Fix Clipper2 handling of Inflate/Deflate

For unknown reasons, Clipper2 only returns Paths structures from the
ClipperOffset::Execute routine.  Further, the Paths are not properly
ordered (outline->hole in outline, outline2->hole in outline2).
To get proper hierarchy, we need to run an additional pass of the
solution with the paths as Subject in a null union.  This is effectively
a Simplify() call but we keep the data in Clipper format to reduce the
churn/calc time
This commit is contained in:
Seth Hillbrand 2022-10-28 16:57:57 -07:00
parent aca3329469
commit 8e97855557
2 changed files with 19 additions and 8 deletions

View File

@ -1391,7 +1391,7 @@ private:
void importTree( Clipper2Lib::PolyTree64& tree,
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
const std::vector<SHAPE_ARC>& aArcBuffe );
void importTree( Clipper2Lib::Paths64& paths,
void importPaths( Clipper2Lib::Paths64& paths,
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
const std::vector<SHAPE_ARC>& aArcBuffe );
void importPolyPath( Clipper2Lib::PolyPath64* aPolyPath,

View File

@ -1013,11 +1013,12 @@ void SHAPE_POLY_SET::inflate2( int aAmount, int aCircleSegCount, CORNER_STRATEGY
for( const POLYGON& poly : m_polys )
{
Paths64 paths;
for( size_t i = 0; i < poly.size(); i++ )
{
c.AddPath( poly[i].convertToClipper2( i == 0, zValues, arcBuffer ),
joinType, EndType::Polygon );
}
paths.push_back( poly[i].convertToClipper2( i == 0, zValues, arcBuffer ) );
c.AddPaths( paths, joinType, EndType::Polygon );
}
// Calculate the arc tolerance (arc error) from the seg count by circle. The seg count is
@ -1043,9 +1044,19 @@ void SHAPE_POLY_SET::inflate2( int aAmount, int aCircleSegCount, CORNER_STRATEGY
c.ArcTolerance( std::abs( aAmount ) * coeff );
c.MiterLimit( miterLimit );
c.MergeGroups( true );
Paths64 solution = c.Execute( aAmount );
importTree( solution, zValues, arcBuffer );
// We get paths back but we need the tree to assign the holes to the correct
// outlines
Clipper64 c2;
PolyTree64 tree;
c2.PreserveCollinear = false;
c2.ReverseSolution = false;
c2.AddSubject( solution );
c2.Execute(ClipType::Union, FillRule::Positive, tree);
importTree( tree, zValues, arcBuffer );
}
@ -1116,14 +1127,14 @@ void SHAPE_POLY_SET::importTree( Clipper2Lib::PolyTree64& tree,
}
void SHAPE_POLY_SET::importTree( Clipper2Lib::Paths64& tree,
void SHAPE_POLY_SET::importPaths( Clipper2Lib::Paths64& aPath,
const std::vector<CLIPPER_Z_VALUE>& aZValueBuffer,
const std::vector<SHAPE_ARC>& aArcBuffer )
{
m_polys.clear();
POLYGON path;
for( const Clipper2Lib::Path64& n : tree )
for( const Clipper2Lib::Path64& n : aPath )
{
if( Clipper2Lib::Area( n ) > 0 )
{