/** * Function NormalizeAreaOutlines * Convert a self-intersecting polygon to one (or more) non self-intersecting polygon(s) * @param aNewPolygonList = a std::vector<CPolyLine*> reference where to store new CPolyLine * needed by the normalization * @return the polygon count (always >= 1, because there is at least one polygon) * There are new polygons only if the polygon count is > 1 */ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList ) { SHAPE_POLY_SET polySet = ConvertPolyListToPolySet( m_CornersList ); // We are expecting only one main outline, but this main outline can have holes // if holes: combine holes and remove them from the main outline. // Note also we are using SHAPE_POLY_SET::PM_STRICTLY_SIMPLE in polygon // calculations, but it is not mandatory. It is used mainly // because there is usually only very few vertices in area outlines SHAPE_POLY_SET::POLYGON& outline = polySet.Polygon( 0 ); SHAPE_POLY_SET holesBuffer; // Move holes stored in outline to holesBuffer: // The first SHAPE_LINE_CHAIN is the main outline, others are holes while( outline.size() > 1 ) { holesBuffer.AddOutline( outline.back() ); outline.pop_back(); } polySet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE); // If any hole, substract it to main outline if( holesBuffer.OutlineCount() ) { holesBuffer.Simplify( SHAPE_POLY_SET::PM_FAST); polySet.BooleanSubtract( holesBuffer, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); } RemoveAllContours(); // Note: we can have more than outline, because a self intersecting outline will be // broken to non intersecting polygons, and removing holes can also create a few polygons for( int ii = 0; ii < polySet.OutlineCount(); ii++ ) { CPolyLine* polyline = this; if( ii > 0 ) { polyline = new CPolyLine; polyline->ImportSettings( this ); aNewPolygonList->push_back( polyline ); } SHAPE_POLY_SET pnew; pnew.NewOutline(); pnew.Polygon( 0 ) = polySet.CPolygon( ii ); polyline->m_CornersList = ConvertPolySetToPolyList( pnew ); } return polySet.OutlineCount(); }