std::string getNodeLabel(const MachineBasicBlock *Node, const MachineFunction *Graph) { if (isSimple () && Node->getBasicBlock() && !Node->getBasicBlock()->getName().empty()) return Node->getBasicBlock()->getNameStr() + ":"; std::string OutStr; { raw_string_ostream OSS(OutStr); if (isSimple()) OSS << Node->getNumber() << ':'; else Node->print(OSS); } if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); // Process string output to make it nicer... for (unsigned i = 0; i != OutStr.length(); ++i) if (OutStr[i] == '\n') { // Left justify OutStr[i] = '\\'; OutStr.insert(OutStr.begin()+i+1, 'l'); } return OutStr; }
void LCA::dfs(const Graph &G, node root) { OGDF_ASSERT(isSimple(G)); OGDF_ASSERT(isArborescence(G)); List< std::pair<node,int> > todo; List< adjEntry > adjStack; int dfscounter = 0; todo.pushBack(std::pair<node,int>(root, 0)); adjStack.pushBack(root->firstAdj()); while (!todo.empty()) { const node u = todo.back().first; const int level = todo.back().second; adjEntry adj = adjStack.popBackRet(); m_euler[dfscounter] = u; m_level[dfscounter] = level; m_representative[u] = dfscounter; while (adj && adj->theEdge()->source() != u) { adj = adj->succ(); } if (adj) { node v = adj->twinNode(); adjStack.pushBack(adj->succ()); todo.pushBack(std::pair<node,int>(v, level + 1)); adjStack.pushBack(v->firstAdj()); } else { todo.popBack(); } ++dfscounter; } }
std::string getNodeLabel(const SILBasicBlock *Node, const SILFunction *Graph) { if (isSimple()) return getSimpleNodeLabel(Node, Graph); else return getCompleteNodeLabel(Node, Graph); }
UpwardPlanRep::UpwardPlanRep(const CombinatorialEmbedding &Gamma) : GraphCopy(Gamma.getGraph()), isAugmented(false), t_hat(nullptr), extFaceHandle(nullptr), crossings(0) { OGDF_ASSERT(Gamma.externalFace() != nullptr); OGDF_ASSERT(hasSingleSource(*this)); OGDF_ASSERT(isSimple(*this)); m_isSourceArc.init(*this, false); m_isSinkArc.init(*this, false); hasSingleSource(*this, s_hat); m_Gamma.init(*this); //compute the ext. face; adjEntry adj; node v = this->original(s_hat); adj = getAdjEntry(Gamma, v, Gamma.externalFace()); adj = this->copy(adj->theEdge())->adjSource(); m_Gamma.setExternalFace(m_Gamma.rightFace(adj)); //outputFaces(Gamma); computeSinkSwitches(); }
void Matrix4::mapRect(Rect& r) const { if (isIdentity()) return; if (isSimple()) { MUL_ADD_STORE(r.left, data[kScaleX], data[kTranslateX]); MUL_ADD_STORE(r.right, data[kScaleX], data[kTranslateX]); MUL_ADD_STORE(r.top, data[kScaleY], data[kTranslateY]); MUL_ADD_STORE(r.bottom, data[kScaleY], data[kTranslateY]); if (r.left > r.right) { float x = r.left; r.left = r.right; r.right = x; } if (r.top > r.bottom) { float y = r.top; r.top = r.bottom; r.bottom = y; } return; } float vertices[] = { r.left, r.top, r.right, r.top, r.right, r.bottom, r.left, r.bottom }; float x, y, z; for (int i = 0; i < 8; i+= 2) { float px = vertices[i]; float py = vertices[i + 1]; x = px * data[kScaleX] + py * data[kSkewX] + data[kTranslateX]; y = px * data[kSkewY] + py * data[kScaleY] + data[kTranslateY]; z = px * data[kPerspective0] + py * data[kPerspective1] + data[kPerspective2]; if (z) z = 1.0f / z; vertices[i] = x * z; vertices[i + 1] = y * z; } r.left = r.right = vertices[0]; r.top = r.bottom = vertices[1]; for (int i = 2; i < 8; i += 2) { x = vertices[i]; y = vertices[i + 1]; if (x < r.left) r.left = x; else if (x > r.right) r.right = x; if (y < r.top) r.top = y; else if (y > r.bottom) r.bottom = y; } }
void Matrix4::dump() const { ALOGD("Matrix4[simple=%d, type=0x%x", isSimple(), getType()); ALOGD(" %f %f %f %f", data[kScaleX], data[kSkewX], data[8], data[kTranslateX]); ALOGD(" %f %f %f %f", data[kSkewY], data[kScaleY], data[9], data[kTranslateY]); ALOGD(" %f %f %f %f", data[2], data[6], data[kScaleZ], data[kTranslateZ]); ALOGD(" %f %f %f %f", data[kPerspective0], data[kPerspective1], data[11], data[kPerspective2]); ALOGD("]"); }
bool noCompoundArgs(Obj expr) { if (noArgs(expr)) return true; else { List* list = GETLIST(expr); return isSimple(list->car) && noCompoundArgs(LISTOBJ(list->cdr)); } }
std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) { if (!Node->isSubRegion()) { BasicBlock *BB = Node->getNodeAs<BasicBlock>(); if (isSimple()) return DOTGraphTraits<const Function *>::getSimpleNodeLabel( BB, BB->getParent()); else return DOTGraphTraits<const Function *>::getCompleteNodeLabel( BB, BB->getParent()); } return "Not implemented"; }
void Matrix4::mapPoint(float& x, float& y) const { if (isSimple()) { MUL_ADD_STORE(x, data[kScaleX], data[kTranslateX]); MUL_ADD_STORE(y, data[kScaleY], data[kTranslateY]); return; } float dx = x * data[kScaleX] + y * data[kSkewX] + data[kTranslateX]; float dy = x * data[kSkewY] + y * data[kScaleY] + data[kTranslateY]; float dz = x * data[kPerspective0] + y * data[kPerspective1] + data[kPerspective2]; if (dz) dz = 1.0f / dz; x = dx * dz; y = dy * dz; }
std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) { BasicBlock *BB = Node->getBlock(); if (!BB) return "Post dominance root node"; if (isSimple()) return DOTGraphTraits<const Function*> ::getSimpleNodeLabel(BB, BB->getParent()); else return DOTGraphTraits<const Function*> ::getCompleteNodeLabel(BB, BB->getParent()); }
void SchnyderLayout::doCall( const Graph &G, adjEntry adjExternal, GridLayout &gridLayout, IPoint &boundingBox, bool fixEmbedding) { // check for double edges & self loops OGDF_ASSERT(isSimple(G)); // handle special case of graphs with less than 3 nodes if (G.numberOfNodes() < 3) { node v1, v2; switch (G.numberOfNodes()) { case 0: boundingBox = IPoint(0, 0); return; case 1: v1 = G.firstNode(); gridLayout.x(v1) = gridLayout.y(v1) = 0; boundingBox = IPoint(0, 0); return; case 2: v1 = G.firstNode(); v2 = G.lastNode(); gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0; gridLayout.x(v2) = 1; boundingBox = IPoint(1, 0); return; } } // make a copy for triangulation GraphCopy GC(G); // embed if (!fixEmbedding) { if (planarEmbed(GC) == false) { OGDF_THROW_PARAM(PreconditionViolatedException, pvcPlanar); } } triangulate(GC); schnyderEmbedding(GC, gridLayout, adjExternal); }
std::string getNodeLabel(const MachineBasicBlock *Node, const MachineBlockFrequencyInfo *Graph) { int layout_order = -1; // Attach additional ordering information if 'isSimple' is false. if (!isSimple()) { const MachineFunction *F = Node->getParent(); if (!CurFunc || F != CurFunc) { if (CurFunc) LayoutOrderMap.clear(); CurFunc = F; int O = 0; for (auto MBI = F->begin(); MBI != F->end(); ++MBI, ++O) { LayoutOrderMap[&*MBI] = O; } } layout_order = LayoutOrderMap[Node]; } return MBFIDOTGraphTraitsBase::getNodeLabel(Node, Graph, getGVDT(), layout_order); }
void FPPLayout::doCall( const Graph &G, adjEntry adjExternal, GridLayout &gridLayout, IPoint &boundingBox, bool fixEmbedding) { // check for double edges & self loops OGDF_ASSERT(isSimple(G)); // handle special case of graphs with less than 3 nodes if (G.numberOfNodes() < 3) { node v1, v2; switch (G.numberOfNodes()) { case 0: boundingBox = IPoint(0, 0); return; case 1: v1 = G.firstNode(); gridLayout.x(v1) = gridLayout.y(v1) = 0; boundingBox = IPoint(0, 0); return; case 2: v1 = G.firstNode(); v2 = G.lastNode(); gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0; gridLayout.x(v2) = 1; boundingBox = IPoint(1, 0); return; } } // make a copy for triangulation GraphCopy GC(G); // embed if (!fixEmbedding) { if (planarEmbed(GC) == false) { OGDF_THROW_PARAM(PreconditionViolatedException, pvcPlanar); } } triangulate(GC); // get edges for outer face (triangle) adjEntry e_12; if (adjExternal != 0) { edge eG = adjExternal->theEdge(); edge eGC = GC.copy(eG); e_12 = (adjExternal == eG->adjSource()) ? eGC->adjSource() : eGC->adjTarget(); } else { e_12 = GC.firstEdge()->adjSource(); } adjEntry e_2n = e_12->faceCycleSucc(); NodeArray<int> num(GC); NodeArray<adjEntry> e_wp(GC); // List of predecessors on circle C_k NodeArray<adjEntry> e_wq(GC); // List of successors on circle C_k computeOrder(GC, num , e_wp, e_wq, e_12, e_2n, e_2n->faceCycleSucc()); computeCoordinates(GC, boundingBox, gridLayout, num, e_wp, e_wq); }
Module::ReturnType OutputUpwardEdgeInserter::insertAll(UpwardPlanRep &UPR, List<edge> &toInsert, EdgeArray<int> &costOrig) { if (toInsert.empty()) return Module::retFeasible; List<edge> l; int size_new = toInsert.size(); int size_old = 0; while (size_old != size_new) { size_old = size_new; while (!toInsert.empty()) { edge e_orig = toInsert.popFrontRet(); SList<adjEntry> path; /* //debug cout << endl; cout << " insertion path for e_orig :" << e_orig << "; e_UPR: (" << UPR.copy(e_orig->source()) << "," << UPR.copy(e_orig->target()) << ")" << endl; */ minFIP(UPR, toInsert, costOrig, e_orig, path); /* //--------------------------------------debug forall_slistiterators(adjEntry, it, path) { cout << (*it)->theEdge() << "; node: " << (*it)->theNode() << endl; } //--------------------------------------end debug */ List<edge> lEdges = toInsert, lTmp = l; lEdges.conc(lTmp); bool ok = isConstraintFeasible(UPR, lEdges, e_orig, path); if (ok) { UPR.insertEdgePathEmbedded(e_orig, path, costOrig); OGDF_ASSERT(isUpwardPlanar(UPR)); OGDF_ASSERT(isSimple(UPR)); OGDF_ASSERT(isConnected(UPR)); OGDF_ASSERT(hasSingleSource(UPR)); } else l.pushBack(e_orig); /* if (false) { //---------------------------------------------------debug //UPR.outputFaces(UPR.getEmbedding()); //UPR.writeGML("c:/temp/bug5.gml"); LayerBasedUPRLayout uprLayout; Graph GTmp( (const Graph &) UPR); CombinatorialEmbedding embTmp(GTmp); node tTmp = 0; //GTmp.writeGML("c:/temp/bug4.gml"); hasSingleSink(GTmp, tTmp); OGDF_ASSERT(tTmp != 0); embTmp.setExternalFace(embTmp.rightFace(tTmp->firstAdj())); //adjEntry adjTmp = GCTmp.copy(UPR.extFaceHandle->theEdge())->adjTarget(); UpwardPlanRep upr_bug(embTmp); adjEntry adj_bug = upr_bug.getAdjEntry(upr_bug.getEmbedding(), upr_bug.getSuperSource(), upr_bug.getEmbedding().externalFace()); node s_upr_bug = upr_bug.newNode(); upr_bug.getEmbedding().splitFace(s_upr_bug, adj_bug); upr_bug.m_isSourceArc.init(upr_bug, false); upr_bug.m_isSourceArc[s_upr_bug->firstAdj()->theEdge()] = true; upr_bug.s_hat = s_upr_bug; upr_bug.augment(); GraphAttributes GA_UPR_tmp(GTmp, GraphAttributes::nodeGraphics| GraphAttributes::edgeGraphics| GraphAttributes::nodeColor| GraphAttributes::edgeColor| GraphAttributes::nodeLabel| GraphAttributes::edgeLabel ); GA_UPR_tmp.setAllHeight(30.0); GA_UPR_tmp.setAllWidth(30.0); uprLayout.call(upr_bug, GA_UPR_tmp); // label the nodes with their index node z; forall_nodes(z, GA_UPR_tmp.constGraph()) { char str[255]; sprintf_s(str, 255, "%d", z->index()); // convert to string GA_UPR_tmp.labelNode(z) = str; GA_UPR_tmp.y(z)=-GA_UPR_tmp.y(z); GA_UPR_tmp.x(z)=-GA_UPR_tmp.x(z); } edge eee; forall_edges(eee, GA_UPR_tmp.constGraph()) { DPolyline &line = GA_UPR_tmp.bends(eee); ListIterator<DPoint> it; for(it = line.begin(); it.valid(); it++) { (*it).m_y = -(*it).m_y; (*it).m_x = -(*it).m_x; } } GA_UPR_tmp.writeGML("c:/temp/UPR_int.gml"); //cout << "face of UPR_int :" << endl; //upr_bug.outputFaces(upr_bug.getEmbedding()); //end -----------------------------------------------debug } */ } size_new = l.size(); toInsert = l; l.clear(); } /* * some edges cannot be inserted, so use heuristic insertion methods */ if (!toInsert.empty()) { //cout << endl << "\a\a\a\a\aheuristical call!! " << endl; edge e_orig = toInsert.popFrontRet(); /* cout << endl; cout << "heuristical insertion path for e_orig :" << e_orig << "; e_UPR: (" << UPR.copy(e_orig->source()) << "," << UPR.copy(e_orig->target()) << ")" << endl; */ /* if (false) { //---------------------------------------------------debug //UPR.outputFaces(UPR.getEmbedding()); //UPR.writeGML("c:/temp/bug5.gml"); LayerBasedUPRLayout uprLayout; Graph GTmp( (const Graph &) UPR); CombinatorialEmbedding embTmp(GTmp); node tTmp = 0; //GTmp.writeGML("c:/temp/bug4.gml"); hasSingleSink(GTmp, tTmp); OGDF_ASSERT(tTmp != 0); embTmp.setExternalFace(embTmp.rightFace(tTmp->firstAdj())); //adjEntry adjTmp = GCTmp.copy(UPR.extFaceHandle->theEdge())->adjTarget(); UpwardPlanRep upr_bug(embTmp); adjEntry adj_bug = upr_bug.getAdjEntry(upr_bug.getEmbedding(), upr_bug.getSuperSource(), upr_bug.getEmbedding().externalFace()); node s_upr_bug = upr_bug.newNode(); upr_bug.getEmbedding().splitFace(s_upr_bug, adj_bug); upr_bug.m_isSourceArc.init(upr_bug, false); upr_bug.m_isSourceArc[s_upr_bug->firstAdj()->theEdge()] = true; upr_bug.s_hat = s_upr_bug; upr_bug.augment(); GraphAttributes GA_UPR_tmp(GTmp, GraphAttributes::nodeGraphics| GraphAttributes::edgeGraphics| GraphAttributes::nodeColor| GraphAttributes::edgeColor| GraphAttributes::nodeLabel| GraphAttributes::edgeLabel ); GA_UPR_tmp.setAllHeight(30.0); GA_UPR_tmp.setAllWidth(30.0); uprLayout.call(upr_bug, GA_UPR_tmp); // label the nodes with their index node z; forall_nodes(z, GA_UPR_tmp.constGraph()) { char str[255]; sprintf_s(str, 255, "%d", z->index()); // convert to string GA_UPR_tmp.labelNode(z) = str; GA_UPR_tmp.y(z)=-GA_UPR_tmp.y(z); GA_UPR_tmp.x(z)=-GA_UPR_tmp.x(z); } edge eee; forall_edges(eee, GA_UPR_tmp.constGraph()) { DPolyline &line = GA_UPR_tmp.bends(eee); ListIterator<DPoint> it; for(it = line.begin(); it.valid(); it++) { (*it).m_y = -(*it).m_y; (*it).m_x = -(*it).m_x; } } GA_UPR_tmp.writeGML("c:/temp/UPR_int.gml"); //cout << "face of UPR_int :" << endl; //upr_bug.outputFaces(upr_bug.getEmbedding()); //end -----------------------------------------------debug } */ SList<adjEntry> path; constraintFIP(UPR, toInsert, costOrig, e_orig, path); /* //--------------------------------------debug forall_slistiterators(adjEntry, it, path) { cout << (*it)->theEdge() << "; node: " << (*it)->theNode() << endl;; } //--------------------------------------end debug */ UPR.insertEdgePathEmbedded(e_orig, path, costOrig); OGDF_ASSERT(isUpwardPlanar(UPR)); return insertAll(UPR, toInsert, costOrig); } return Module::retFeasible; }
void PlanarDrawLayout::doCall( const Graph &G, adjEntry adjExternal, GridLayout &gridLayout, IPoint &boundingBox, bool fixEmbedding) { // require to have a planar graph without multi-edges and self-loops; // planarity is checked below OGDF_ASSERT(isSimple(G) && isLoopFree(G)); // handle special case of graphs with less than 3 nodes if(G.numberOfNodes() < 3) { node v1, v2; switch(G.numberOfNodes()) { case 0: boundingBox = IPoint(0,0); return; case 1: v1 = G.firstNode(); gridLayout.x(v1) = gridLayout.y(v1) = 0; boundingBox = IPoint(0,0); return; case 2: v1 = G.firstNode(); v2 = G.lastNode (); gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0; gridLayout.x(v2) = 1; boundingBox = IPoint(1,0); return; } } // we make a copy of G since we use planar biconnected augmentation GraphCopySimple GC(G); if(fixEmbedding) { PlanarAugmentationFix augmenter; augmenter.call(GC); } else { // augment graph planar biconnected m_augmenter.get().call(GC); // embed augmented graph PlanarModule pm; bool isPlanar = pm.planarEmbed(GC); if(isPlanar == false) OGDF_THROW_PARAM(PreconditionViolatedException, pvcPlanar); } // compute shelling order m_computeOrder.get().baseRatio(m_baseRatio); ShellingOrder order; m_computeOrder.get().call(GC,order,adjExternal); // compute grid coordinates for GC NodeArray<int> x(GC), y(GC); computeCoordinates(GC,order,x,y); boundingBox.m_x = x[order(1,order.len(1))]; boundingBox.m_y = 0; node v; forall_nodes(v,GC) if(y[v] > boundingBox.m_y) boundingBox.m_y = y[v]; // copy coordinates from GC to G forall_nodes(v,G) { node vCopy = GC.copy(v); gridLayout.x(v) = x[vCopy]; gridLayout.y(v) = y[vCopy]; }
CBORValue::SimpleValue CBORValue::getSimpleValue() const { ASSERT(isSimple()); return m_simpleValue; }
void PlanarStraightLayout::doCall( const Graph &G, adjEntry adjExternal, GridLayout &gridLayout, IPoint &boundingBox, bool fixEmbedding) { // require to have a planar graph without multi-edges and self-loops; // planarity is checked below OGDF_ASSERT(isSimple(G) && isLoopFree(G)); // handle special case of graphs with less than 3 nodes if(G.numberOfNodes() < 3) { node v1, v2; switch(G.numberOfNodes()) { case 0: boundingBox = IPoint(0,0); return; case 1: v1 = G.firstNode(); gridLayout.x(v1) = gridLayout.y(v1) = 0; boundingBox = IPoint(0,0); return; case 2: v1 = G.firstNode(); v2 = G.lastNode (); gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0; gridLayout.x(v2) = 1; boundingBox = IPoint(1,0); return; } } // we make a copy of G since we use planar biconnected augmentation GraphCopySimple GC(G); if(fixEmbedding) { // determine adjacency entry on external face of GC (if required) if(adjExternal != 0) { edge eG = adjExternal->theEdge(); edge eGC = GC.copy(eG); adjExternal = (adjExternal == eG->adjSource()) ? eGC->adjSource() : eGC->adjTarget(); } PlanarAugmentationFix augmenter; augmenter.call(GC); } else { adjExternal = 0; // augment graph planar biconnected m_augmenter.get().call(GC); // embed augmented graph m_embedder.get().call(GC,adjExternal); } // compute shelling order with shelling order module m_computeOrder.get().baseRatio(m_baseRatio); ShellingOrder order; m_computeOrder.get().callLeftmost(GC,order,adjExternal); // compute grid coordinates for GC NodeArray<int> x(GC), y(GC); computeCoordinates(GC,order,x,y); boundingBox.m_x = x[order(1,order.len(1))]; boundingBox.m_y = 0; node v; forall_nodes(v,GC) if(y[v] > boundingBox.m_y) boundingBox.m_y = y[v]; // copy coordinates from GC to G forall_nodes(v,G) { node vCopy = GC.copy(v); gridLayout.x(v) = x[vCopy]; gridLayout.y(v) = y[vCopy]; }
void UpwardPlanRep::augment() { if (isAugmented) return; OGDF_ASSERT(hasSingleSource(*this)); List<adjEntry> switches; hasSingleSource(*this, s_hat); OGDF_ASSERT(this == &m_Gamma.getGraph()); for(adjEntry adj : s_hat->adjEntries) m_isSourceArc[adj->theEdge()] = true; FaceSinkGraph fsg(m_Gamma, s_hat); List<adjEntry> dummyList; FaceArray< List<adjEntry> > sinkSwitches(m_Gamma, dummyList); fsg.sinkSwitches(sinkSwitches); m_sinkSwitchOf.init(*this, nullptr); List<Tuple2<adjEntry, adjEntry>> list; for(face f : m_Gamma.faces) { adjEntry adj_top; switches = sinkSwitches[f]; if (switches.empty() || f == m_Gamma.externalFace()) continue; else adj_top = switches.popFrontRet(); // first switch in the list is a top sink switch while (!switches.empty()) { adjEntry adj = switches.popFrontRet(); Tuple2<adjEntry, adjEntry> pair(adj, adj_top); list.pushBack(pair); } } // construct sink arcs // for the ext. face extFaceHandle = getAdjEntry(m_Gamma, s_hat, m_Gamma.externalFace()); node t = this->newNode(); switches = sinkSwitches[m_Gamma.externalFace()]; OGDF_ASSERT(!switches.empty()); while (!switches.empty()) { adjEntry adj = switches.popFrontRet(); edge e_new; if (t->degree() == 0) { e_new = m_Gamma.addEdgeToIsolatedNode(adj, t); } else { adjEntry adjTgt = getAdjEntry(m_Gamma, t, m_Gamma.rightFace(adj)); e_new = m_Gamma.splitFace(adj, adjTgt); } m_isSinkArc[e_new] = true; m_Gamma.setExternalFace(m_Gamma.rightFace(extFaceHandle)); } /* * set ext. face handle * we add a additional node t_hat and an addtional edge e=(t, t_hat) * e will never been crossed. we use e as the ext. face handle */ t_hat = this->newNode(); adjEntry adjSource = getAdjEntry(m_Gamma, t, m_Gamma.externalFace()); extFaceHandle = m_Gamma.addEdgeToIsolatedNode(adjSource, t_hat)->adjTarget(); m_isSinkArc[extFaceHandle->theEdge()] = true; // not really a sink arc !! TODO?? m_Gamma.setExternalFace(m_Gamma.rightFace(extFaceHandle)); //for int. faces while (!list.empty()) { Tuple2<adjEntry, adjEntry> pair = list.popFrontRet(); edge e_new = nullptr; if (pair.x2()->theNode()->degree() == 0 ) { e_new = m_Gamma.addEdgeToIsolatedNode(pair.x1(), pair.x2()->theNode()); } else { adjEntry adjTgt = getAdjEntry(m_Gamma, pair.x2()->theNode(), m_Gamma.rightFace(pair.x1())); if(!m_Gamma.getGraph().searchEdge(pair.x1()->theNode(),adjTgt->theNode())) // post-hoi-ming bugfix: prohibit the same edge twice... e_new = m_Gamma.splitFace(pair.x1(), adjTgt); } if(e_new!=nullptr) m_isSinkArc[e_new] = true; } isAugmented = true; OGDF_ASSERT(isSimple(*this)); computeSinkSwitches(); }
bool LineString::isRing() const { return isClosed() && isSimple(); }
Module::ReturnType SubgraphUpwardPlanarizer::doCall(UpwardPlanRep &UPR, const EdgeArray<int> &cost, const EdgeArray<bool> &forbid) { const Graph &G = UPR.original(); GraphCopy GC(G); //reverse some edges in order to obtain a DAG List<edge> feedBackArcSet; m_acyclicMod.get().call(GC, feedBackArcSet); for(edge e : feedBackArcSet) { GC.reverseEdge(e); } OGDF_ASSERT(isSimple(G)); //mapping cost EdgeArray<int> cost_GC(GC); for(edge e : GC.edges) { if (forbid[GC.original(e)]) cost_GC[e] = numeric_limits<int>::max(); else cost_GC[e] = cost[GC.original(e)]; } // tranform to single source graph by adding a super source s_hat and connect it with the other sources EdgeArray<bool> sourceArcs(GC, false); node s_hat = GC.newNode(); for(node v : GC.nodes) { if (v->indeg() == 0 && v != s_hat) { edge e_tmp = GC.newEdge(s_hat, v); cost_GC[e_tmp] = 0; // crossings source arcs cause not cost sourceArcs[e_tmp] = true; } } /* //------------------------------------------------debug GraphAttributes AG_GC(GC, GraphAttributes::nodeGraphics| GraphAttributes::edgeGraphics| GraphAttributes::nodeColor| GraphAttributes::edgeColor| GraphAttributes::nodeLabel| GraphAttributes::edgeLabel ); AG_GC.setAllHeight(30.0); AG_GC.setAllWidth(30.0); for(node z : AG_GC.constGraph().nodes) { AG_GC.label(z) = to_string(z->index()); } AG_GC.writeGML("c:/temp/GC.gml"); // --------------------------------------------end debug */ BCTree BC(GC); const Graph &bcTree = BC.bcTree(); GraphCopy G_dummy; G_dummy.createEmpty(G); NodeArray<GraphCopy> biComps(bcTree, G_dummy); // bicomps of G; init with an empty graph UpwardPlanRep UPR_dummy; UPR_dummy.createEmpty(G); NodeArray<UpwardPlanRep> uprs(bcTree, UPR_dummy); // the upward planarized representation of the bicomps; init with an empty UpwarPlanRep constructComponentGraphs(BC, biComps); for(node v : bcTree.nodes) { if (BC.typeOfBNode(v) == BCTree::CComp) continue; GraphCopy &block = biComps[v]; OGDF_ASSERT(m_subgraph.valid()); // construct a super source for this block node s, s_block; hasSingleSource(block, s); s_block = block.newNode(); block.newEdge(s_block, s); //connect s UpwardPlanRep bestUPR; //upward planarize if not upward planar if (!UpwardPlanarity::upwardPlanarEmbed_singleSource(block)) { for (int i = 0; i < m_runs; i++) {// i multistarts UpwardPlanRep UPR_tmp; UPR_tmp.createEmpty(block); List<edge> delEdges; m_subgraph.get().call(UPR_tmp, delEdges); OGDF_ASSERT( isSimple(UPR_tmp) ); UPR_tmp.augment(); //mark the source arcs of block UPR_tmp.m_isSourceArc[UPR_tmp.copy(s_block->firstAdj()->theEdge())] = true; for (adjEntry adj_tmp : UPR_tmp.copy(s_block->firstAdj()->theEdge()->target())->adjEntries) { edge e_tmp = UPR_tmp.original(adj_tmp->theEdge()); if (e_tmp != nullptr && block.original(e_tmp) != nullptr && sourceArcs[block.original(e_tmp)]) UPR_tmp.m_isSourceArc[adj_tmp->theEdge()] = true; } //assign "crossing cost" EdgeArray<int> cost_Block(block); for (edge e : block.edges) { if (block.original(e) == nullptr || GC.original(block.original(e)) == nullptr) cost_Block[e] = 0; else cost_Block[e] = cost_GC[block.original(e)]; } /* if (false) { //---------------------------------------------------debug LayerBasedUPRLayout uprLayout; UpwardPlanRep upr_bug(UPR_tmp.getEmbedding()); adjEntry adj_bug = upr_bug.getAdjEntry(upr_bug.getEmbedding(), upr_bug.getSuperSource(), upr_bug.getEmbedding().externalFace()); node s_upr_bug = upr_bug.newNode(); upr_bug.getEmbedding().splitFace(s_upr_bug, adj_bug); upr_bug.m_isSourceArc.init(upr_bug, false); upr_bug.m_isSourceArc[s_upr_bug->firstAdj()->theEdge()] = true; upr_bug.s_hat = s_upr_bug; upr_bug.augment(); GraphAttributes GA_UPR_tmp(UPR_tmp, GraphAttributes::nodeGraphics| GraphAttributes::edgeGraphics| GraphAttributes::nodeColor| GraphAttributes::edgeColor| GraphAttributes::nodeLabel| GraphAttributes::edgeLabel ); GA_UPR_tmp.setAllHeight(30.0); GA_UPR_tmp.setAllWidth(30.0); uprLayout.call(upr_bug, GA_UPR_tmp); // label the nodes with their index for(node z : GA_UPR_tmp.constGraph().nodes) { GA_UPR_tmp.label(z) = to_string(z->index()); GA_UPR_tmp.y(z)=-GA_UPR_tmp.y(z); GA_UPR_tmp.x(z)=-GA_UPR_tmp.x(z); } for(edge eee : GA_UPR_tmp.constGraph().edges) { DPolyline &line = GA_UPR_tmp.bends(eee); ListIterator<DPoint> it; for(it = line.begin(); it.valid(); it++) { (*it).m_y = -(*it).m_y; (*it).m_x = -(*it).m_x; } } GA_UPR_tmp.writeGML("c:/temp/UPR_tmp_fups.gml"); cout << "UPR_tmp/fups faces:"; UPR_tmp.outputFaces(UPR_tmp.getEmbedding()); //end -----------------------------------------------debug } */ delEdges.permute(); m_inserter.get().call(UPR_tmp, cost_Block, delEdges); if (i != 0) { if (UPR_tmp.numberOfCrossings() < bestUPR.numberOfCrossings()) { //cout << endl << "new cr_nr:" << UPR_tmp.numberOfCrossings() << " old cr_nr : " << bestUPR.numberOfCrossings() << endl; bestUPR = UPR_tmp; } } else bestUPR = UPR_tmp; }//for } else { //block is upward planar CombinatorialEmbedding Gamma(block); FaceSinkGraph fsg((const CombinatorialEmbedding &) Gamma, s_block); SList<face> faceList; fsg.possibleExternalFaces(faceList); Gamma.setExternalFace(faceList.front()); UpwardPlanRep UPR_tmp(Gamma); UPR_tmp.augment(); //mark the source arcs of block UPR_tmp.m_isSourceArc[UPR_tmp.copy(s->firstAdj()->theEdge())] = true; for (adjEntry adj_tmp : UPR_tmp.copy(s->firstAdj()->theEdge()->target())->adjEntries) { edge e_tmp = UPR_tmp.original(adj_tmp->theEdge()); if (e_tmp != nullptr && block.original(e_tmp) != nullptr && sourceArcs[block.original(e_tmp)]) UPR_tmp.m_isSourceArc[adj_tmp->theEdge()] = true; } bestUPR = UPR_tmp; /* //debug //---------------------------------------------------debug GraphAttributes GA_UPR_tmp(UPR_tmp, GraphAttributes::nodeGraphics| GraphAttributes::edgeGraphics| GraphAttributes::nodeColor| GraphAttributes::edgeColor| GraphAttributes::nodeLabel| GraphAttributes::edgeLabel ); GA_UPR_tmp.setAllHeight(30.0); GA_UPR_tmp.setAllWidth(30.0); // label the nodes with their index for(node z : GA_UPR_tmp.constGraph().nodes) { GA_UPR_tmp.label(z) = to_string(z->index()); GA_UPR_tmp.y(z)=-GA_UPR_tmp.y(z); GA_UPR_tmp.x(z)=-GA_UPR_tmp.x(z); } for(edge eee : GA_UPR_tmp.constGraph().edges) { DPolyline &line = GA_UPR_tmp.bends(eee); ListIterator<DPoint> it; for(it = line.begin(); it.valid(); it++) { (*it).m_y = -(*it).m_y; (*it).m_x = -(*it).m_x; } } GA_UPR_tmp.writeGML("c:/temp/UPR_tmp_fups.gml"); cout << "UPR_tmp/fups faces:"; UPR_tmp.outputFaces(UPR_tmp.getEmbedding()); //end -----------------------------------------------debug */ } uprs[v] = bestUPR; } // compute the number of crossings int nr_cr = 0; for(node v : bcTree.nodes) { if (BC.typeOfBNode(v) != BCTree::CComp) nr_cr = nr_cr + uprs[v].numberOfCrossings(); } //merge all component to a graph node parent_BC = BC.bcproper(s_hat); NodeArray<bool> nodesDone(bcTree, false); dfsMerge(GC, BC, biComps, uprs, UPR, nullptr, parent_BC, nodesDone); // start with the component which contains the super source s_hat //augment to single sink graph UPR.augment(); //set crossings UPR.crossings = nr_cr; //------------------------------------------------debug /* LayerBasedUPRLayout uprLayout; UpwardPlanRep upr_bug(UPR.getEmbedding()); adjEntry adj_bug = upr_bug.getAdjEntry(upr_bug.getEmbedding(), upr_bug.getSuperSource(), upr_bug.getEmbedding().externalFace()); node s_upr_bug = upr_bug.newNode(); upr_bug.getEmbedding().splitFace(s_upr_bug, adj_bug); upr_bug.m_isSourceArc.init(upr_bug, false); upr_bug.m_isSourceArc[s_upr_bug->firstAdj()->theEdge()] = true; upr_bug.s_hat = s_upr_bug; upr_bug.augment(); GraphAttributes AG(UPR, GraphAttributes::nodeGraphics| GraphAttributes::edgeGraphics| GraphAttributes::nodeColor| GraphAttributes::edgeColor| GraphAttributes::nodeLabel| GraphAttributes::edgeLabel ); AG.setAllHeight(30.0); AG.setAllWidth(30.0); uprLayout.call(upr_bug, AG); for(node v : AG.constGraph().nodes) { int idx; idx = v->index(); if (UPR.original(v) != 0) idx = UPR.original(v)->index(); AG.label(v) = to_string(idx); if (UPR.isDummy(v)) AG.fillColor(v) = "#ff0000"; AG.y(v)=-AG.y(v); } // label the edges with their index for(edge e : AG.constGraph().edges) { AG.label(e) = to_string(e->index()); if (UPR.isSourceArc(e)) AG.strokeColor(e) = "#00ff00"; if (UPR.isSinkArc(e)) AG.strokeColor(e) = "#ff0000"; DPolyline &line = AG.bends(e); ListIterator<DPoint> it; for(it = line.begin(); it.valid(); it++) { (*it).m_y = -(*it).m_y; } } AG.writeGML("c:/temp/upr_res.gml"); //cout << "UPR_RES"; //UPR.outputFaces(UPR.getEmbedding()); //cout << "Mapping :" << endl; //for(node v : UPR.nodes) { // if (UPR.original(v) != 0) { // cout << "node UPR " << v << " node G " << UPR.original(v) << endl; // } //} // --------------------------------------------end debug */ OGDF_ASSERT(hasSingleSource(UPR)); OGDF_ASSERT(isSimple(UPR)); OGDF_ASSERT(isAcyclic(UPR)); OGDF_ASSERT(UpwardPlanarity::isUpwardPlanar_singleSource(UPR)); /* for(edge eee : UPR.original().edges) { if (UPR.isReversed(eee)) cout << endl << eee << endl; } */ return Module::retFeasible; }