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; BOOST_FOREACH( 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 }
bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttribute<typename PFP::VEC3>& position, CellMarker<EDGE>& polygons, CellMarker<FACE>& polygonsFaces) { typedef typename PFP::VEC3 VEC3; typedef std::vector<VEC3 > POLYGON; xmlDocPtr doc = xmlReadFile(filename.c_str(), NULL, 0); xmlNodePtr map_node = xmlDocGetRootElement(doc); if (!checkXmlNode(map_node,"svg")) { CGoGNerr << "Wrong xml format: Root node != svg"<< CGoGNendl; return false; } std::vector<POLYGON> allPoly; std::vector<POLYGON> allBrokenLines; std::vector<float> allBrokenLinesWidth; bool closedPoly; for (xmlNode* cur_node = map_node->children; cur_node; cur_node = cur_node->next) { // for each layer if (checkXmlNode(cur_node, "g")) { // CGoGNout << "----load layer----"<< CGoGNendl; for (xmlNode* cur_path = cur_node->children ; cur_path; cur_path = cur_path->next) { if (checkXmlNode(cur_path, "path")) { POLYGON curPoly; // CGoGNout << "--load a path--"<< CGoGNendl; xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "d"); std::string allcoords((reinterpret_cast<const char*>(prop))); getPolygonFromSVG(allcoords,curPoly,closedPoly); //check orientation : set in CCW if(curPoly.size()>2) { VEC3 v1(curPoly[1]-curPoly[0]); VEC3 v2(curPoly[2]-curPoly[1]); if((v1^v2)[2]>0) { std::reverse(curPoly.begin(), curPoly.end()); } } if(closedPoly) allPoly.push_back(curPoly); else { allBrokenLines.push_back(curPoly); xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "style"); std::string allstyle((reinterpret_cast<const char*>(prop))); std::stringstream is(allstyle); std::string style; while ( std::getline( is, style, ';' ) ) { if(style.find("stroke-width:")!=std::string::npos) { std::stringstream isSize(style); std::getline( isSize, style, ':' ); float sizeOfLine; isSize >> sizeOfLine; allBrokenLinesWidth.push_back(sizeOfLine); } } } } } }
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 ); }