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; }
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; 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 }
void fitSVG(const POLYGON& _polygon, gex::io::SVG& _svg) { using namespace gex; auto& _bounds = _polygon.bounds(); auto&& _center = _bounds.center(); auto&& _max = (_bounds.size()(X) + _bounds.size()(Y)) / 2.0; Vec2 _m(_max,_max); _svg.buffer().fit(Bounds2(_center - _m,_center + _m)); }
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); } } }
// extended methods int SIMPLEPOLY::SetValues( const POLYGON& aPolygon ) { if( x ) delete [] x; if( y ) delete [] y; if( z ) delete [] z; x = y = z = NULL; nv = 0; valid = false; int np; double* px, * py, * pz; px = py = pz = NULL; np = aPolygon.GetVertices( &px, &py, &pz ); if( np < 3 ) return 0; // polygons must have 3 or more vertices if( (!px) || (!py) || (!pz) ) { ERRBLURB; cerr << "invalid pointer to coordinate\n"; return -1; } x = new (nothrow) double[np]; if( x == NULL ) { ERRBLURB; cerr << "could not allocate memory for vertices\n"; return -1; } y = new (nothrow) double[np]; if( y == NULL ) { ERRBLURB; cerr << "could not allocate memory for vertices\n"; delete [] x; return -1; } z = new (nothrow) double[np]; if( z == NULL ) { ERRBLURB; cerr << "could not allocate memory for vertices\n"; delete [] x; delete [] y; return -1; } int i; for( i = 0; i < np; ++i ) { x[i] = px[i]; y[i] = py[i]; z[i] = pz[i]; } valid = true; nv = np; return 0; }
int POLYGON::Stitch( bool isCCW, POLYGON& aPolygon, TRANSFORM& aTransform, VRMLMAT& aMaterial, bool reuseMaterial, std::ofstream& aVRMLFile, int aTabDepth ) { int i, j, k; if( !valid ) { ERRBLURB; cerr << "invoked without prior invocation of Calc()\n"; return -1; } if( nv < 3 ) { ERRBLURB; cerr << "invalid number of vertices (" << nv << "); range is 3 .. 360\n"; return -1; } double* r2x = NULL; double* r2y = NULL; double* r2z = NULL; int rv = aPolygon.GetVertices( &r2x, &r2y, &r2z ); if( rv != nv ) { ERRBLURB; cerr << "points in second ring (" << rv << ") do not match points in this ring (" << nv << ")\n"; return -1; } if( aTabDepth < 0 ) aTabDepth = 0; if( aTabDepth > 4 ) aTabDepth = 4; double* lx; double* ly; double* lz; // allocate memory lx = new double[nv * 2]; if( lx == NULL ) { ERRBLURB; cerr << "could not allocate points for intermediate calculations\n"; return -1; } ly = new double[nv * 2]; if( ly == NULL ) { ERRBLURB; cerr << "could not allocate points for intermediate calculations\n"; delete [] lx; return -1; } lz = new double[nv * 2]; if( lz == NULL ) { ERRBLURB; cerr << "could not allocate points for intermediate calculations\n"; delete [] lx; delete [] ly; return -1; } for( i = 0; i < nv; ++i ) { lx[i] = x[i]; ly[i] = y[i]; lz[i] = z[i]; lx[i + nv] = r2x[i]; ly[i + nv] = r2y[i]; lz[i + nv] = r2z[i]; } // perform transforms aTransform.Transform( lx, ly, lz, nv * 2 ); // set up VRML Shape SetupShape( aMaterial, reuseMaterial, aVRMLFile, aTabDepth ); // enumerate vertices WriteCoord( lx, ly, lz, nv * 2, aVRMLFile, aTabDepth + 1 ); // enumerate facets SetupCoordIndex( aVRMLFile, aTabDepth + 1 ); string fmt( (aTabDepth + 1) * 4, ' ' ); aVRMLFile << fmt << " "; if( isCCW ) k = 1; else k = -1; for( i = 0; i < nv - 1; ++i ) { j = i + k; if( j >= nv ) j -= nv; if( j < 0 ) j += nv; aVRMLFile << " " << i << "," << j << "," << j + nv << "," << i + nv << ",-1,"; if( !( (i + 1) % 4 ) ) aVRMLFile << "\n" << fmt << " "; } j = i + k; if( j >= nv ) j -= nv; if( j < 0 ) j += nv; aVRMLFile << " " << i << "," << j << "," << j + nv << "," << i + nv << ",-1\n"; CloseCoordIndex( aVRMLFile, aTabDepth + 1 ); delete [] lx; delete [] ly; delete [] lz; return CloseShape( aVRMLFile, aTabDepth ); }
return gb; } } void hp_inter(const list<LINE>& Lin, list<rat_polygon>& Lout) { if (Lin.size() < 1) return; int HP_NUMB=Lin.size(),i; array<LINE> L(HP_NUMB); LINE lakt; i=0; forall(lakt,Lin) { L[i]=lakt; i++; } POLYGON GP = halfplane_intersection(L,0,HP_NUMB-1); Lout = GP.polygons(); } POINT get_dual(const LINE& l) { POINT p1 = l.point1(); POINT p2 = l.point2(); POINT swp; if (p1.xcoord() > p2.xcoord()) { swp=p1; p1=p2; p2=swp; } NUMBER2 a,b,x1,x2,y1,y2; x1=p1.xcoord(); y1=p1.ycoord(); x2=p2.xcoord(); y2=p2.ycoord();
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 ); }