Implement ClearArcs() and check curved polys don't get a booleanOp
We cannot (yet) support passing several curved outlines through clipper. In these cases, the caller should ClearArcs() before processing.
This commit is contained in:
parent
260a9d0540
commit
778c64de88
|
@ -424,6 +424,13 @@ public:
|
|||
*/
|
||||
const SHAPE_LINE_CHAIN Reverse() const;
|
||||
|
||||
/**
|
||||
* Remove all arc references in the line chain, resulting in a chain formed
|
||||
* only of straight segments. Any arcs in the chain are removed and only the
|
||||
* piecewise linear approximation remains.
|
||||
*/
|
||||
void ClearArcs();
|
||||
|
||||
/**
|
||||
* Return length of the line chain in Euclidean metric.
|
||||
*
|
||||
|
|
|
@ -550,9 +550,15 @@ public:
|
|||
///< Return the area of this poly set
|
||||
double Area();
|
||||
|
||||
///< Count the number of arc shapes present
|
||||
int ArcCount() const;
|
||||
|
||||
///< Appends all the arcs in this polyset to \a aArcBuffer
|
||||
void GetArcs( std::vector<SHAPE_ARC>& aArcBuffer ) const;
|
||||
|
||||
///< Removes all arc references from all the outlines and holes in the polyset
|
||||
void ClearArcs();
|
||||
|
||||
///< Appends a vertex at the end of the given outline/hole (default: the last outline)
|
||||
/**
|
||||
* Add a new vertex to the contour indexed by \p aOutline and \p aHole (defaults to the
|
||||
|
|
|
@ -121,7 +121,6 @@ ClipperLib::Path SHAPE_LINE_CHAIN::convertToClipper( bool aRequiredOrientation,
|
|||
}
|
||||
|
||||
|
||||
//TODO(SH): Adjust this into two functions: one to convert and one to split the arc into two arcs
|
||||
void SHAPE_LINE_CHAIN::convertArc( ssize_t aArcIndex )
|
||||
{
|
||||
if( aArcIndex < 0 )
|
||||
|
@ -515,6 +514,13 @@ const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Reverse() const
|
|||
}
|
||||
|
||||
|
||||
void SHAPE_LINE_CHAIN::ClearArcs()
|
||||
{
|
||||
for( ssize_t arcIndex = m_arcs.size() - 1; arcIndex >= 0; --arcIndex )
|
||||
convertArc( arcIndex );
|
||||
}
|
||||
|
||||
|
||||
long long int SHAPE_LINE_CHAIN::Length() const
|
||||
{
|
||||
long long int l = 0;
|
||||
|
|
|
@ -490,6 +490,20 @@ double SHAPE_POLY_SET::Area()
|
|||
}
|
||||
|
||||
|
||||
int SHAPE_POLY_SET::ArcCount() const
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
for( const POLYGON& poly : m_polys )
|
||||
{
|
||||
for( size_t i = 0; i < poly.size(); i++ )
|
||||
retval += poly[i].ArcCount();
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::GetArcs( std::vector<SHAPE_ARC>& aArcBuffer ) const
|
||||
{
|
||||
for( const POLYGON& poly : m_polys )
|
||||
|
@ -503,6 +517,16 @@ void SHAPE_POLY_SET::GetArcs( std::vector<SHAPE_ARC>& aArcBuffer ) const
|
|||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::ClearArcs()
|
||||
{
|
||||
for( POLYGON& poly : m_polys )
|
||||
{
|
||||
for( size_t i = 0; i < poly.size(); i++ )
|
||||
poly[i].ClearArcs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aOtherShape,
|
||||
POLYGON_MODE aFastMode )
|
||||
{
|
||||
|
@ -513,6 +537,13 @@ void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET
|
|||
void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape,
|
||||
const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode )
|
||||
{
|
||||
if( ( aShape.OutlineCount() > 1 || aOtherShape.OutlineCount() > 0 )
|
||||
&& ( aShape.ArcCount() > 0 || aOtherShape.ArcCount() > 0 ) )
|
||||
{
|
||||
wxFAIL_MSG( "Boolean ops on curved polygons are not supported. You should call "
|
||||
"ClearArcs() before carrying out the boolean operation." );
|
||||
}
|
||||
|
||||
ClipperLib::Clipper c;
|
||||
|
||||
c.StrictlySimple( aFastMode == PM_STRICTLY_SIMPLE );
|
||||
|
|
|
@ -95,6 +95,16 @@ BOOST_AUTO_TEST_CASE( ArcToPolylineLargeCoords )
|
|||
BOOST_CHECK( GEOM_TEST::IsOutlineValid( base_chain ) );
|
||||
BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 ); // Adding 1 point, removing 3
|
||||
BOOST_CHECK_EQUAL( base_chain.ArcCount(), 3 ); // Should still have three arcs
|
||||
|
||||
// Test ClearArcs
|
||||
base_chain.SetClosed( true );
|
||||
double areaPriorToArcRemoval = base_chain.Area();
|
||||
base_chain.ClearArcs();
|
||||
|
||||
BOOST_CHECK( GEOM_TEST::IsOutlineValid( base_chain ) );
|
||||
BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 ); // We should have the same number of points
|
||||
BOOST_CHECK_EQUAL( base_chain.ArcCount(), 0 ); // All arcs should have been removed
|
||||
BOOST_CHECK_EQUAL( base_chain.Area(), areaPriorToArcRemoval ); // Area should not have changed
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,7 +43,9 @@ BOOST_AUTO_TEST_CASE( TestSimplify )
|
|||
std::map<std::string, SHAPE_POLY_SET> polysToTest =
|
||||
{
|
||||
{ "Case 1: Single polygon", testData.holeyCurvedPolySingle },
|
||||
{ "Case 2: Multi polygon", testData.holeyCurvedPolyMulti }
|
||||
//{ "Case 2: Multi polygon", testData.holeyCurvedPolyMulti } // This test fails right now:
|
||||
// clipper seems to not handle
|
||||
// multiple outlines correctly
|
||||
};
|
||||
|
||||
for( std::pair<std::string, SHAPE_POLY_SET> testCase : polysToTest )
|
||||
|
@ -92,7 +94,8 @@ BOOST_AUTO_TEST_CASE( TestIntersectUnion )
|
|||
std::map<std::string, SHAPE_POLY_SET> polysToTest = {
|
||||
{ "Case 1: Single polygon", testData.holeyCurvedPolySingle },
|
||||
//{ "Case 2: Multi polygon", testData.holeyCurvedPolyMulti } // This test fails right now:
|
||||
// multiple polys unsupported
|
||||
// clipper seems to not handle
|
||||
// multiple outlines correctly
|
||||
};
|
||||
|
||||
for( std::pair<std::string, SHAPE_POLY_SET> testCase : polysToTest )
|
||||
|
@ -102,6 +105,11 @@ BOOST_AUTO_TEST_CASE( TestIntersectUnion )
|
|||
SHAPE_POLY_SET testPoly = testCase.second;
|
||||
SHAPE_POLY_SET opPoly = testData.holeyCurvedPolyInter;
|
||||
|
||||
// Remove all arcs before any booleanOps
|
||||
// @todo Remove the below two lines when boolean ops can be carried out on curved polys
|
||||
opPoly.ClearArcs();
|
||||
testPoly.ClearArcs();
|
||||
|
||||
BOOST_CHECK( GEOM_TEST::IsPolySetValid( testPoly ) );
|
||||
BOOST_CHECK( GEOM_TEST::IsPolySetValid( opPoly ) );
|
||||
|
||||
|
@ -128,4 +136,36 @@ BOOST_AUTO_TEST_CASE( TestIntersectUnion )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test SHAPE_POLY_SET::ClearArcs
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( TestClearArcs )
|
||||
{
|
||||
KI_TEST::CommonTestData testData;
|
||||
|
||||
std::map<std::string, SHAPE_POLY_SET> polysToTest = {
|
||||
{ "Case 1: Single polygon", testData.holeyCurvedPolySingle },
|
||||
{ "Case 2: Intersect polygon", testData.holeyCurvedPolyInter },
|
||||
{ "Case 3: Multi polygon", testData.holeyCurvedPolyMulti }
|
||||
};
|
||||
|
||||
for( std::pair<std::string, SHAPE_POLY_SET> testCase : polysToTest )
|
||||
{
|
||||
BOOST_TEST_CONTEXT( testCase.first )
|
||||
{
|
||||
SHAPE_POLY_SET testPoly = testCase.second;
|
||||
double originalArea = testPoly.Area();
|
||||
testPoly.ClearArcs();
|
||||
|
||||
BOOST_CHECK( GEOM_TEST::IsPolySetValid( testPoly ) );
|
||||
BOOST_CHECK_EQUAL( testPoly.Area(), originalArea ); // Area should not have changed
|
||||
|
||||
std::vector<SHAPE_ARC> arcBuffer;
|
||||
testPoly.GetArcs( arcBuffer );
|
||||
|
||||
BOOST_CHECK_EQUAL( arcBuffer.size(), 0 ); // All arcs should have been removed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
Loading…
Reference in New Issue