Clean up various simplify steps
Adds the option to simplify the output of Clipper ops that remove minor detours from the output lines. These detours are not substantive, so removing them speeds up the rest of the system by removing unimportant vertices. This also prevents the introduction of inadvertant concave points when unioning two, closely-sized rounded shapes
This commit is contained in:
parent
e758391a23
commit
798e13f70d
|
@ -1046,6 +1046,12 @@ public:
|
|||
///< For \a aFastMode meaning, see function booleanOp
|
||||
void Simplify( POLYGON_MODE aFastMode );
|
||||
|
||||
|
||||
///< Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
|
||||
///< @param aMaxError Smooths the output such that points less than aMaxError away from the line through
|
||||
/// the two adjacent points will be removed
|
||||
void Simplify( size_t aMaxError );
|
||||
|
||||
/**
|
||||
* Convert a self-intersecting polygon to one (or more) non self-intersecting polygon(s).
|
||||
*
|
||||
|
@ -1422,10 +1428,10 @@ private:
|
|||
void booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape,
|
||||
const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode );
|
||||
|
||||
void booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SET& aOtherShape );
|
||||
void booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SET& aOtherShape, size_t aMaxError = 0 );
|
||||
|
||||
void booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SET& aShape,
|
||||
const SHAPE_POLY_SET& aOtherShape );
|
||||
const SHAPE_POLY_SET& aOtherShape, size_t aMaxError = 0 );
|
||||
|
||||
/**
|
||||
* Check whether the point \a aP is inside the \a aSubpolyIndex-th polygon of the polyset. If
|
||||
|
|
|
@ -721,14 +721,14 @@ void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET
|
|||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SET& aOtherShape )
|
||||
void SHAPE_POLY_SET::booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SET& aOtherShape, size_t aMaxError )
|
||||
{
|
||||
booleanOp( aType, *this, aOtherShape );
|
||||
booleanOp( aType, *this, aOtherShape, aMaxError );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SET& aShape,
|
||||
const SHAPE_POLY_SET& aOtherShape )
|
||||
const SHAPE_POLY_SET& aOtherShape, size_t aMaxError )
|
||||
{
|
||||
if( ( aShape.OutlineCount() > 1 || aOtherShape.OutlineCount() > 0 )
|
||||
&& ( aShape.ArcCount() > 0 || aOtherShape.ArcCount() > 0 ) )
|
||||
|
@ -765,7 +765,8 @@ void SHAPE_POLY_SET::booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SE
|
|||
c.AddSubject( paths );
|
||||
c.AddClip( clips );
|
||||
|
||||
Clipper2Lib::PolyTree64 solution;
|
||||
Clipper2Lib::Paths64 solution;
|
||||
Clipper2Lib::PolyTree64 tree;
|
||||
|
||||
Clipper2Lib::ZCallback64 callback =
|
||||
[&]( const Clipper2Lib::Point64 & e1bot, const Clipper2Lib::Point64 & e1top,
|
||||
|
@ -828,10 +829,24 @@ void SHAPE_POLY_SET::booleanOp( Clipper2Lib::ClipType aType, const SHAPE_POLY_SE
|
|||
|
||||
c.SetZCallback( callback ); // register callback
|
||||
|
||||
c.Execute( aType, Clipper2Lib::FillRule::NonZero, solution );
|
||||
if( aMaxError > 0 )
|
||||
{
|
||||
c.Execute( aType, Clipper2Lib::FillRule::NonZero, solution );
|
||||
Clipper2Lib::Paths64 output = Clipper2Lib::SimplifyPaths( solution, aMaxError, false );
|
||||
Clipper2Lib::Clipper64 c2;
|
||||
|
||||
importTree( solution, zValues, arcBuffer );
|
||||
solution.Clear(); // Free used memory (not done in dtor)
|
||||
c2.PreserveCollinear = false;
|
||||
c2.ReverseSolution = false;
|
||||
c2.AddSubject( output );
|
||||
c2.Execute( Clipper2Lib::ClipType::Union, Clipper2Lib::FillRule::Positive, tree);
|
||||
}
|
||||
else
|
||||
{
|
||||
c.Execute( aType, Clipper2Lib::FillRule::NonZero, tree );
|
||||
}
|
||||
|
||||
importTree( tree, zValues, arcBuffer );
|
||||
tree.Clear(); // Free used memory (not done in dtor)
|
||||
}
|
||||
|
||||
|
||||
|
@ -1597,6 +1612,17 @@ void SHAPE_POLY_SET::Unfracture( POLYGON_MODE aFastMode )
|
|||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::Simplify( size_t aMaxError )
|
||||
{
|
||||
SHAPE_POLY_SET empty;
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
|
||||
booleanOp( Clipper2Lib::ClipType::Union, empty, aMaxError );
|
||||
else
|
||||
booleanOp( ClipperLib::ctUnion, empty, PM_FAST );
|
||||
}
|
||||
|
||||
|
||||
void SHAPE_POLY_SET::Simplify( POLYGON_MODE aFastMode )
|
||||
{
|
||||
SHAPE_POLY_SET empty;
|
||||
|
|
|
@ -1299,7 +1299,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
|||
}
|
||||
}
|
||||
|
||||
aHoles.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
aHoles.Simplify( m_maxError );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue