static void connCallback(void *ptr) { Avoid::ConnRef *connRef = (Avoid::ConnRef *) ptr; printf("Connector %u needs rerouting!\n", connRef->id()); const Avoid::PolyLine& route = connRef->route(); printf("New path: "); for (size_t i = 0; i < route.ps.size(); ++i) { printf("%s(%f, %f)", (i > 0) ? "-" : "", route.ps[i].x, route.ps[i].y); } printf("\n"); }
/* * Make feasible: * - remove overlaps between rectangular boundaries of nodes/clusters * (respecting structural constraints) * - perform routing (preserve previous topology using rubber banding) */ void makeFeasible(vpsc::Rectangles& rs, vector<cola::Edge>& edges, std::vector<topology::Edge*>& routes, std::vector<topology::Node*>& topologyNodes, double defaultEdgeLength) { printf("Removing overlaps...\n"); removeoverlaps(rs,false); printf("done.\n"); printf("Running libavoid to compute routes...\n"); clock_t libavoidstarttime=clock(); // find feasible routes for edges Avoid::Router *router = new Avoid::Router(Avoid::PolyLineRouting); // Use rotational sweep for point visibility router->UseLeesAlgorithm = true; // Don't use invisibility graph. router->InvisibilityGrph = false; double g=0; // make shape that libavoid sees slightly smaller for(unsigned i=0;i<rs.size();++i) { vpsc::Rectangle* r=rs[i]; double x=r->getMinX()+g; double X=r->getMaxX()-g; double y=r->getMinY()+g; double Y=r->getMaxY()-g; // Create the ShapeRef: Avoid::Polygon shapePoly(4); // AntiClockwise! shapePoly.ps[0] = Avoid::Point(X,y); shapePoly.ps[1] = Avoid::Point(X,Y); shapePoly.ps[2] = Avoid::Point(x,Y); shapePoly.ps[3] = Avoid::Point(x,y); //if(i==4||i==13||i==9) { //printf("rect[%d]:{%f,%f,%f,%f}\n",i,x,y,X,Y); //} unsigned int shapeID = i + 1; Avoid::ShapeRef *shapeRef = new Avoid::ShapeRef(router, shapePoly, shapeID); // ShapeRef constructor makes a copy of polygon so we can free it: //router->addShape(shapeRef); // FIXME } for(unsigned i=0;i<edges.size();++i) { cola::Edge e=edges[i]; Avoid::ConnRef *connRef; unsigned int connID = i + rs.size() + 1; Rectangle* r0=rs[e.first], *r1=rs[e.second]; Avoid::Point srcPt(r0->getCentreX(),r0->getCentreY()); Avoid::Point dstPt(r1->getCentreX(),r1->getCentreY()); connRef = new Avoid::ConnRef(router, srcPt, dstPt, connID); router->processTransaction(); const Avoid::Polygon& route = connRef->route(); vector<topology::EdgePoint*> eps; eps.push_back( new topology::EdgePoint( topologyNodes[e.first], topology::EdgePoint::CENTRE)); for(size_t j=1;j+1<route.size();j++) { const Avoid::Point& p = route.ps[j]; const unsigned nodeID=p.id-1; topology::Node* node=topologyNodes[nodeID]; topology::EdgePoint::RectIntersect ri; switch(p.vn) { case 0: ri=topology::EdgePoint::BR; break; case 1: ri=topology::EdgePoint::TR; break; case 2: ri=topology::EdgePoint::TL; break; case 3: ri=topology::EdgePoint::BL; break; default: ri=topology::EdgePoint::CENTRE; } eps.push_back(new topology::EdgePoint(node,ri)); } eps.push_back(new topology::EdgePoint(topologyNodes[e.second], topology::EdgePoint::CENTRE)); topology::Edge* edgeRoute=new topology::Edge(i,defaultEdgeLength, eps); edgeRoute->assertConvexBends(); routes.push_back(edgeRoute); } writeFile(topologyNodes,routes,"beautify0.svg"); assert(topology::assertNoSegmentRectIntersection(topologyNodes,routes)); double libavoidtime=double(clock()-libavoidstarttime)/double(CLOCKS_PER_SEC); cout << "done. Libavoid ran in " << libavoidtime << " seconds" << endl; delete router; }
/** * Method called when a connector of type Avoid::ConnRef needs to be redrawn. */ static void conn_callback(void *ptr) { Avoid::ConnRef *connRef = (Avoid::ConnRef *) ptr; connRef->route(); }