diff --git a/libs/kimath/include/geometry/shape_poly_set.h b/libs/kimath/include/geometry/shape_poly_set.h index f49261d4d9..86957eefad 100644 --- a/libs/kimath/include/geometry/shape_poly_set.h +++ b/libs/kimath/include/geometry/shape_poly_set.h @@ -550,6 +550,9 @@ public: ///< Return the area of this poly set double Area(); + ///< Appends all the arcs in this polyset to \a aArcBuffer + void GetArcs( std::vector& aArcBuffer ) const; + ///< 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 @@ -1358,6 +1361,16 @@ private: void booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape, const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode ); + /** + * Detect arcs in a polyset and convert them from segments to true arcs by adding an arc + * and associated references. The original segment points are not changed. + * + * @param aArcs List of possible arcs that might be in this polyset + * @param aMargin Maximum acceptable deviation from the found points to the arc (defaults + * to ARC_HIGH_DEF) + */ + void detectArcs( const std::vector& aArcs, int aMargin = PCB_IU_PER_MM * 0.005 ); + /** * Check whether the point \a aP is inside the \a aSubpolyIndex-th polygon of the polyset. If * the points lies on an edge, the polygon is considered to contain it. diff --git a/libs/kimath/src/geometry/shape_poly_set.cpp b/libs/kimath/src/geometry/shape_poly_set.cpp index 625ab32de1..72420d401e 100644 --- a/libs/kimath/src/geometry/shape_poly_set.cpp +++ b/libs/kimath/src/geometry/shape_poly_set.cpp @@ -489,6 +489,19 @@ double SHAPE_POLY_SET::Area() } +void SHAPE_POLY_SET::GetArcs( std::vector& aArcBuffer ) const +{ + for( const POLYGON& poly : m_polys ) + { + for( size_t i = 0; i < poly.size(); i++ ) + { + for( SHAPE_ARC arc : poly[i].m_arcs ) + aArcBuffer.push_back( arc ); + } + } +} + + void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode ) { @@ -503,6 +516,12 @@ void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET c.StrictlySimple( aFastMode == PM_STRICTLY_SIMPLE ); + // All possible arcs in the resulting shape of the booleanop + std::vector possibleArcs; + + aShape.GetArcs( possibleArcs ); + aOtherShape.GetArcs( possibleArcs ); + for( const POLYGON& poly : aShape.m_polys ) { for( size_t i = 0 ; i < poly.size(); i++ ) @@ -520,6 +539,20 @@ void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET c.Execute( aType, solution, ClipperLib::pftNonZero, ClipperLib::pftNonZero ); importTree( &solution ); + + detectArcs( possibleArcs ); +} + + +void SHAPE_POLY_SET::detectArcs( const std::vector& aArcs, int aMargin ) +{ + for( POLYGON& poly : m_polys ) + { + for( size_t i = 0; i < poly.size(); i++ ) + { + poly[i].DetectArcs( aArcs, aMargin ); + } + } }