int SHAPE_POLY_SET::NewOutline() { SHAPE_LINE_CHAIN empty_path; POLYGON poly; poly.push_back( empty_path ); m_polys.push_back( poly ); return m_polys.size() - 1; }
void SHAPE_POLY_SET::importTree( PolyTree* tree) { m_polys.clear(); for( PolyNode* n = tree->GetFirst(); n; n = n->GetNext() ) { if( !n->IsHole() ) { POLYGON paths; paths.push_back( convertFromClipper( n->Contour ) ); for( unsigned int i = 0; i < n->Childs.size(); i++ ) paths.push_back( convertFromClipper( n->Childs[i]->Contour ) ); m_polys.push_back(paths); } } }
bool SHAPE_POLY_SET::Parse( std::stringstream& aStream ) { std::string tmp; aStream >> tmp; if( tmp != "polyset" ) return false; aStream >> tmp; int n_polys = atoi( tmp.c_str() ); if( n_polys < 0 ) return false; for( int i = 0; i < n_polys; i++ ) { POLYGON paths; aStream >> tmp; if( tmp != "poly" ) return false; aStream >> tmp; int n_outlines = atoi( tmp.c_str() ); if( n_outlines < 0 ) return false; for( int j = 0; j < n_outlines; j++ ) { SHAPE_LINE_CHAIN outline; outline.SetClosed( true ); aStream >> tmp; int n_vertices = atoi( tmp.c_str() ); for( int v = 0; v < n_vertices; v++ ) { VECTOR2I p; aStream >> tmp; p.x = atoi( tmp.c_str() ); aStream >> tmp; p.y = atoi( tmp.c_str() ); outline.Append( p ); } paths.push_back( outline ); } m_polys.push_back( paths ); } return true; }
int SHAPE_POLY_SET::AddOutline( const SHAPE_LINE_CHAIN& aOutline ) { assert( aOutline.IsClosed() ); POLYGON poly; poly.push_back( aOutline ); m_polys.push_back( poly ); return m_polys.size() - 1; }
void SHAPE_POLY_SET::fractureSingle( POLYGON& paths ) { FractureEdgeSet edges; FractureEdgeSet border_edges; FractureEdge* root = NULL; bool first = true; if( paths.size() == 1 ) return; int num_unconnected = 0; for( SHAPE_LINE_CHAIN& path : paths ) { int index = 0; FractureEdge *prev = NULL, *first_edge = NULL; int x_min = std::numeric_limits<int>::max(); for( int i = 0; i < path.PointCount(); i++ ) { const VECTOR2I& p = path.CPoint( i ); if( p.x < x_min ) x_min = p.x; } for( int i = 0; i < path.PointCount(); i++ ) { FractureEdge* fe = new FractureEdge( first, &path, index++ ); if( !root ) root = fe; if( !first_edge ) first_edge = fe; if( prev ) prev->m_next = fe; if( i == path.PointCount() - 1 ) fe->m_next = first_edge; prev = fe; edges.push_back( fe ); if( !first ) { if( fe->m_p1.x == x_min ) border_edges.push_back( fe ); } if( !fe->m_connected ) num_unconnected++; } first = false; // first path is always the outline } // keep connecting holes to the main outline, until there's no holes left... while( num_unconnected > 0 ) { int x_min = std::numeric_limits<int>::max(); FractureEdge* smallestX = NULL; // find the left-most hole edge and merge with the outline for( FractureEdgeSet::iterator i = border_edges.begin(); i != border_edges.end(); ++i ) { int xt = (*i)->m_p1.x; if( ( xt < x_min ) && ! (*i)->m_connected ) { x_min = xt; smallestX = *i; } } num_unconnected -= processEdge( edges, smallestX ); } paths.clear(); SHAPE_LINE_CHAIN newPath; newPath.SetClosed( true ); FractureEdge* e; for( e = root; e->m_next != root; e = e->m_next ) newPath.Append( e->m_p1 ); newPath.Append( e->m_p1 ); for( FractureEdgeSet::iterator i = edges.begin(); i != edges.end(); ++i ) delete *i; paths.push_back( newPath ); }