void Voronoi::FinishEdge(VParabola * n){ if(n->isLeaf) {delete n; return;} double mx; if(n->edge->direction->x > 0.0){ mx = std::max(width, n->edge->start->x + 10 ); } else { mx = std::min(0.0, n->edge->start->x - 10 ); } //Vec2d * end = new Vec2d(mx, mx * n->edge->f + n->edge->g); Vec2d * end = new Vec2d(); end->set( mx, mx * n->edge->f + n->edge->g ); n->edge->end = end; points.push_back(end); FinishEdge(n->Left() ); FinishEdge(n->Right()); delete n; }
Edges * Voronoi::GetEdges(Vertices * v, double w, double h){ //Edges * Voronoi::GetEdges(){ places = v; width = w; height = h; root = 0; if( !edges ) { edges = new Edges(); }else{ // clear old edges and vertices for(Vertices::iterator i = points.begin(); i != points.end(); ++i) delete (*i); for(Edges::iterator i = edges->begin(); i != edges->end(); ++i) delete (*i); points.clear(); edges->clear(); } for(Vertices::iterator i = places->begin(); i!=places->end(); ++i) { // put all places to event-que queue.push(new VEvent( *i, true)); } VEvent * e; while( !queue.empty() ) { // pop events from que by priority e = queue.top(); queue.pop(); ly = e->point->y; if(deleted.find(e) != deleted.end()) { delete(e); deleted.erase(e); continue;} // ? if(e->pe) InsertParabola(e->point); else RemoveParabola(e); delete(e); } FinishEdge(root); for(Edges::iterator i = edges->begin(); i != edges->end(); ++i) { // ? if( (*i)->neighbour) { (*i)->start = (*i)->neighbour->end; delete (*i)->neighbour; } } return edges; }
void OCC_Connect::FaceCutters::Build(TopoDS_Face const &face, TopoDS_Shape &result, int verbose) { clear(); /* First we create some data structures to access the topology */ TopTools_IndexedMapOfShape vertices; std::vector<std::pair<int,int> > e2v; for(unsigned int i = 0; i < edges.size(); i++) { TopExp::MapShapes(edges[i],TopAbs_VERTEX,vertices); TopoDS_Vertex v1, v2; TopExp::Vertices(edges[i],v1,v2); std::pair<int,int> t(vertices.FindIndex(v1),vertices.FindIndex(v2)); e2v.push_back(t); } std::vector<std::set<int> > v2e; for(unsigned int e = 0; e < e2v.size(); e++) { if(e2v[e].first >= (int)v2e.size()) v2e.resize(e2v[e].first+1); v2e[e2v[e].first].insert(e); if(e2v[e].second >= (int)v2e.size()) v2e.resize(e2v[e].second+1); v2e[e2v[e].second].insert(e); } std::set<int> open, odd; for(unsigned int i = 0; i < v2e.size(); i++) { if(v2e[i].size()==0) continue; else if(v2e[i].size()==1) open.insert(i); else if(v2e[i].size()&1) odd.insert(i); } if(open.size()&1) std::cerr << "Inconsistent open loops\n"; if(odd.size()&1) std::cerr << "Inconsistent odd loops\n"; for(;;) { int open_mode = -1; std::set<int> current_vertices; for(unsigned int start = 0; start < v2e.size(); start++) { if(v2e[start].size()==1) { if(verbose&Cutting) std::cout << "start open at " << start << "\n"; current_vertices.insert(start); open_mode=1; break; } } if(!current_vertices.size()) { for(unsigned int start = 0; start < v2e.size(); start++) { if(v2e[start].size()) { if(verbose&Cutting) std::cout << "start closed at " << start << "\n"; current_vertices.insert(start); open_mode=0; break; } } } if(!current_vertices.size()) break; std::map<int,std::deque<int> > wires; std::set<int> processed_edges; do { std::set<int> next_vertices; for(std::set<int>::iterator v=current_vertices.begin(); v!=current_vertices.end(); v++ ) { for(std::set<int>::iterator e=v2e[*v].begin() ; e!=v2e[*v].end(); e++ ) { if(processed_edges.count(*e)) continue; int other=e2v[*e].first==*v? e2v[*e].second:e2v[*e].first; if(open_mode) { if(v2e[other].size()==1) { // Other is open end too, finish wire. wires[*v].push_back(*e); std::deque<int>::const_iterator p; BRepBuilderAPI_MakeWire wire; if(verbose&Cutting) std::cout << "CUT Open wire:"; for(p=wires[*v].begin(); p!=wires[*v].end(); p++ ) { FinishEdge(*p, v2e, e2v); wire.Add(edges[*p]); if(verbose&Cutting) std::cout << ' ' << (*p)+1; } if(verbose&Cutting) std::cout << "\n"; push_back(wire); goto next_vertex; } } else { if( current_vertices.count(other) || next_vertices.count(other) ) { if(verbose&Cutting) std::cout << "CUT Closed wire:"; wires[*v].push_back(*e); while(wires[other].front() ==wires[*v].front() ) { wires[other].pop_front(); wires[*v].pop_front(); } BRepBuilderAPI_MakeWire wire; std::deque<int>::const_iterator p; for(p=wires[other].begin(); p!=wires[other].end(); p++ ) { FinishEdge(*p, v2e, e2v); wire.Add(edges[*p]); if(verbose&Cutting) std::cout << ' ' << (*p)+1; } std::deque<int>::reverse_iterator rp; for(rp=wires[*v].rbegin(); rp!=wires[*v].rend(); rp++ ) { FinishEdge(*rp, v2e, e2v); wire.Add(edges[*rp]); if(verbose&Cutting) std::cout << ' ' << (*rp)+1; } if(verbose&Cutting) std::cout << "\n"; push_back(wire); goto next_vertex; } } if(current_vertices.count(other)==0) { wires[other]=wires[*v]; wires[other].push_back(*e); processed_edges.insert(*e); next_vertices.insert(other); } } } current_vertices=next_vertices; } while(current_vertices.size()); next_vertex: ; } if(size()>1 && verbose&CuttingIntermediate) { if(verbose&Cutting) std::cout << "Saving multiple cuts\n"; BRep_Builder BB; TopoDS_Compound compound; BB.MakeCompound(compound); for(unsigned int i = 0; i < edges.size(); i++) BB.Add(compound,edges[i]); BRepTools::Write(compound,"cutter.brep"); ofstream out("cutter.dot",ios::trunc|ios::out); dump(e2v,out); } }