SHAPE_POLY_SET: polysets can now be built from a bunch of arbitraily ordered oriented outlines. Used by the SVG hole support

This commit is contained in:
Tomasz Wlostowski 2021-12-30 03:45:53 +01:00
parent 68f6db7213
commit 78968f75c0
2 changed files with 62 additions and 0 deletions

View File

@ -1350,6 +1350,16 @@ public:
*/
bool IsVertexInHole( int aGlobalIdx );
/**
* Build a SHAPE_POLY_SET from a bunch of outlines in provided in random order.
*
* @param aPath set of closed outlines forming the polygon. Positive orientation = outline, negative = hole
* @param aReverseOrientation inverts the sign of the orientation of aPaths (so negative = outline)
* @param aEvenOdd forces the even-off fill rule (default is non zero)
* @return the constructed poly set
*/
static const SHAPE_POLY_SET BuildPolysetFromOrientedPaths( const std::vector<SHAPE_LINE_CHAIN>& aPaths, bool aReverseOrientation = false, bool aEvenOdd = false );
private:
void fractureSingle( POLYGON& paths );
void unfractureSingle ( POLYGON& path );

View File

@ -2524,3 +2524,55 @@ SHAPE_POLY_SET::TRIANGULATED_POLYGON::TRIANGULATED_POLYGON()
SHAPE_POLY_SET::TRIANGULATED_POLYGON::~TRIANGULATED_POLYGON()
{
}
const SHAPE_POLY_SET
SHAPE_POLY_SET::BuildPolysetFromOrientedPaths( const std::vector<SHAPE_LINE_CHAIN>& aPaths,
bool aReverseOrientation, bool aEvenOdd )
{
ClipperLib::Clipper clipper;
ClipperLib::PolyTree tree;
// fixme: do we need aReverseOrientation?
for( const SHAPE_LINE_CHAIN& path : aPaths )
{
ClipperLib::Path lc;
for( int i = 0; i < path.PointCount(); i++ )
{
lc.emplace_back( path.CPoint( i ).x, path.CPoint( i ).y );
}
clipper.AddPath( lc, ClipperLib::ptSubject, true );
}
clipper.StrictlySimple( true );
clipper.Execute( ClipperLib::ctUnion, tree,
aEvenOdd ? ClipperLib::pftEvenOdd : ClipperLib::pftNonZero,
ClipperLib::pftNonZero );
SHAPE_POLY_SET result;
for( ClipperLib::PolyNode* n = tree.GetFirst(); n; n = n->GetNext() )
{
if( !n->IsHole() )
{
int outl = result.NewOutline();
for( unsigned int i = 0; i < n->Contour.size(); i++ )
result.Outline( outl ).Append( n->Contour[i].X, n->Contour[i].Y );
for( unsigned int i = 0; i < n->Childs.size(); i++ )
{
int outh = result.NewHole( outl );
for( unsigned int j = 0; j < n->Childs[i]->Contour.size(); j++ )
{
result.Hole( outl, outh )
.Append( n->Childs[i]->Contour[j].X, n->Childs[i]->Contour[j].Y );
}
}
}
}
return result;
}