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;
}
Example #3
0
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);
    }
}