From 61f4f1ca9de080e4e06c89816e71e83af9829fec Mon Sep 17 00:00:00 2001 From: Mario Luzeiro Date: Mon, 24 Aug 2015 09:55:22 -0400 Subject: [PATCH] Add hole count function and other minor improvements to SHAPE_POLY_SET. --- common/geometry/shape_poly_set.cpp | 54 ++++++++++++++++++++++++++++++ include/geometry/shape_poly_set.h | 36 ++++++++++++++++---- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/common/geometry/shape_poly_set.cpp b/common/geometry/shape_poly_set.cpp index 4348b2ec51..4c84630ba2 100644 --- a/common/geometry/shape_poly_set.cpp +++ b/common/geometry/shape_poly_set.cpp @@ -234,6 +234,36 @@ void SHAPE_POLY_SET::booleanOp( ClipType aType, const SHAPE_POLY_SET& aOtherShap } +void SHAPE_POLY_SET::booleanOp( ClipperLib::ClipType aType, + const SHAPE_POLY_SET& aShape, + const SHAPE_POLY_SET& aOtherShape, + bool aFastMode ) +{ + Clipper c; + + if( !aFastMode ) + c.StrictlySimple( true ); + + BOOST_FOREACH( const POLYGON& poly, aShape.m_polys ) + { + for( unsigned int i = 0; i < poly.size(); i++ ) + c.AddPath( convertToClipper( poly[i], i > 0 ? false : true ), ptSubject, true ); + } + + BOOST_FOREACH( const POLYGON& poly, aOtherShape.m_polys ) + { + for( unsigned int i = 0; i < poly.size(); i++ ) + c.AddPath( convertToClipper( poly[i], i > 0 ? false : true ), ptClip, true ); + } + + PolyTree solution; + + c.Execute( aType, solution, pftNonZero, pftNonZero ); + + importTree( &solution ); +} + + void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& b, bool aFastMode ) { booleanOp( ctUnion, b, aFastMode ); @@ -246,6 +276,30 @@ void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& b, bool aFastMode ) } +void SHAPE_POLY_SET::BooleanIntersection( const SHAPE_POLY_SET& b, bool aFastMode ) +{ + booleanOp( ctIntersection, b, aFastMode ); +} + + +void SHAPE_POLY_SET::BooleanAdd( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b, bool aFastMode ) +{ + booleanOp( ctUnion, a, b, aFastMode ); +} + + +void SHAPE_POLY_SET::BooleanSubtract( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b, bool aFastMode ) +{ + booleanOp( ctDifference, a, b, aFastMode ); +} + + +void SHAPE_POLY_SET::BooleanIntersection( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b, bool aFastMode ) +{ + booleanOp( ctIntersection, a, b, aFastMode ); +} + + void SHAPE_POLY_SET::Inflate( int aFactor, int aCircleSegmentsCount ) { ClipperOffset c; diff --git a/include/geometry/shape_poly_set.h b/include/geometry/shape_poly_set.h index 37c181df30..24c4a91935 100644 --- a/include/geometry/shape_poly_set.h +++ b/include/geometry/shape_poly_set.h @@ -162,7 +162,12 @@ class SHAPE_POLY_SET : public SHAPE int VertexCount( int aOutline = -1, int aHole = -1 ) const; ///> Returns the number of holes in a given outline - int HoleCount( int aOutline ) const; + int HoleCount( int aOutline ) const + { + if( (aOutline > (int)m_polys.size()) || (m_polys[aOutline].size() < 2) ) + return 0; + return m_polys[aOutline].size() - 1; + } ///> Returns the reference to aIndex-th outline in the set SHAPE_LINE_CHAIN& Outline( int aIndex ) @@ -247,20 +252,35 @@ class SHAPE_POLY_SET : public SHAPE ///> Performs boolean polyset union ///> For aFastMode meaning, see function booleanOp - void BooleanAdd( const SHAPE_POLY_SET& b, bool aFastMode = false ); ///> Performs boolean polyset difference ///> For aFastMode meaning, see function booleanOp void BooleanSubtract( const SHAPE_POLY_SET& b, bool aFastMode = false ); + ///> Performs boolean polyset intersection + ///> For aFastMode meaning, see function booleanOp + void BooleanIntersection( const SHAPE_POLY_SET& b, bool aFastMode = false ); + + ///> Performs boolean polyset union between a and b, store the result in it self + ///> For aFastMode meaning, see function booleanOp + void BooleanAdd( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b, bool aFastMode = false ); + + ///> Performs boolean polyset difference between a and b, store the result in it self + ///> For aFastMode meaning, see function booleanOp + void BooleanSubtract( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b, bool aFastMode = false ); + + ///> Performs boolean polyset intersection between a and b, store the result in it self + ///> For aFastMode meaning, see function booleanOp + void BooleanIntersection( const SHAPE_POLY_SET& a, const SHAPE_POLY_SET& b, bool aFastMode = false ); + ///> Performs outline inflation/deflation, using round corners. void Inflate( int aFactor, int aCircleSegmentsCount ); ///> Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the outer ring ///> to the inner holes ///> For aFastMode meaning, see function booleanOp - void Fracture( bool aFastMode = false); + void Fracture( bool aFastMode = false ); ///> Converts a set of slitted polygons to a set of polygons with holes void Unfracture(); @@ -330,13 +350,17 @@ class SHAPE_POLY_SET : public SHAPE * @param aOtherShape is the SHAPE_LINE_CHAIN to combine with me. * @param aFastMode is an option to choos if the result is a weak polygon * or a stricty simple polygon. - * if aFastMode is true (default) the result can be a weak polygon - * if aFastMode is true (default) the result is (theorically) a strictly - * simple polygon, but calculations can be really significantly time consuming + * if aFastMode is true the result can be a weak polygon + * if aFastMode is false (default) the result is (theorically) a strictly + * simple polygon, but calculations can be really significantly time consuming */ void booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aOtherShape, bool aFastMode = false ); + void booleanOp( ClipperLib::ClipType aType, + const SHAPE_POLY_SET& aShape, + const SHAPE_POLY_SET& aOtherShape, bool aFastMode = false ); + bool pointInPolygon( const VECTOR2I& aP, const SHAPE_LINE_CHAIN& aPath ) const; const ClipperLib::Path convertToClipper( const SHAPE_LINE_CHAIN& aPath, bool aRequiredOrientation );