void CombinatorialEmbedding::moveBridge(adjEntry adjBridge, adjEntry adjBefore) { OGDF_ASSERT(m_rightFace[adjBridge] == m_rightFace[adjBridge->twin()]); OGDF_ASSERT(m_rightFace[adjBridge] != m_rightFace[adjBefore]); face fOld = m_rightFace[adjBridge]; face fNew = m_rightFace[adjBefore]; adjEntry adjCand = adjBridge->faceCycleSucc(); int sz = 0; adjEntry adj; for(adj = adjBridge->twin(); adj != adjCand; adj = adj->faceCycleSucc()) { if (fOld->entries.m_adjFirst == adj) fOld->entries.m_adjFirst = adjCand; m_rightFace[adj] = fNew; ++sz; } fOld->m_size -= sz; fNew->m_size += sz; edge e = adjBridge->theEdge(); if(e->source() == adjBridge->twinNode()) m_pGraph->moveSource(e, adjBefore, after); else m_pGraph->moveTarget(e, adjBefore, after); OGDF_ASSERT_IF(dlConsistencyChecks, consistencyCheck()); }
// creates a virtual vertex of vertex father and embeds it as // root in the biconnected child component containing of one edge void BoyerMyrvoldInit::createVirtualVertex(const adjEntry father) { // check that adjEntry is valid OGDF_ASSERT(father != nullptr); // create new virtual Vertex and copy properties from non-virtual node const node virt = m_g.newNode(); m_realVertex[virt] = father->theNode(); m_dfi[virt] = -m_dfi[father->twinNode()]; m_nodeFromDFI[m_dfi[virt]] = virt; // set links for traversal of bicomps m_link[CW][virt] = father->twin(); m_link[CCW][virt] = father->twin(); // move edge to new virtual Vertex edge e = father->theEdge(); if (e->source() == father->theNode()) { // e is outgoing edge m_g.moveSource(e,virt); } else { // e is ingoing edge m_g.moveTarget(e,virt); } }
void FixEdgeInserterUMLCore::insertEdgesIntoDual(const CombinatorialEmbedding &E, adjEntry adjSrc) { face f = E.rightFace(adjSrc); node vRight = m_nodeOf[f]; adjEntry adj1 = f->firstAdj(), adj = adj1; do { node vLeft = m_nodeOf[E.leftFace(adj)]; edge eLR = m_dual.newEdge(vLeft,vRight); m_primalAdj[eLR] = adj; edge eRL = m_dual.newEdge(vRight,vLeft); m_primalAdj[eRL] = adj->twin(); if(m_pr.typeOf(adj->theEdge()) == Graph::generalization) m_primalIsGen[eLR] = m_primalIsGen[eRL] = true; } while((adj = adj->faceCycleSucc()) != adj1); // the other face adjacent to *itEdge ... f = E.rightFace(adjSrc->twin()); vRight = m_nodeOf[f]; adj1 = f->firstAdj(); adj = adj1; do { node vLeft = m_nodeOf[E.leftFace(adj)]; edge eLR = m_dual.newEdge(vLeft,vRight); m_primalAdj[eLR] = adj; edge eRL = m_dual.newEdge(vRight,vLeft); m_primalAdj[eRL] = adj->twin(); if(m_pr.typeOf(adj->theEdge()) == Graph::generalization) m_primalIsGen[eLR] = m_primalIsGen[eRL] = true; } while((adj = adj->faceCycleSucc()) != adj1); }
void FixEdgeInserterCore::insertEdgesIntoDual(const CombinatorialEmbedding &E, adjEntry adjSrc) { face f = E.rightFace(adjSrc); node vRight = m_nodeOf[f]; adjEntry adj1 = f->firstAdj(), adj = adj1; do { if(m_pForbidden && (*m_pForbidden)[m_pr.original(adj->theEdge())] == true) continue; node vLeft = m_nodeOf[E.leftFace(adj)]; edge eLR = m_dual.newEdge(vLeft,vRight); m_primalAdj[eLR] = adj; edge eRL = m_dual.newEdge(vRight,vLeft); m_primalAdj[eRL] = adj->twin(); } while((adj = adj->faceCycleSucc()) != adj1); // the other face adjacent to *itEdge ... f = E.rightFace(adjSrc->twin()); vRight = m_nodeOf[f]; adj1 = f->firstAdj(); adj = adj1; do { if(m_pForbidden && (*m_pForbidden)[m_pr.original(adj->theEdge())] == true) continue; node vLeft = m_nodeOf[E.leftFace(adj)]; edge eLR = m_dual.newEdge(vLeft,vRight); m_primalAdj[eLR] = adj; edge eRL = m_dual.newEdge(vRight,vLeft); m_primalAdj[eRL] = adj->twin(); } while((adj = adj->faceCycleSucc()) != adj1); }
void FPPLayout::computeOrder( const GraphCopy &G, NodeArray<int> &num, NodeArray<adjEntry> &e_wp, NodeArray<adjEntry> &e_wq, adjEntry e_12, adjEntry e_2n, adjEntry e_n1) { NodeArray<int> num_diag(G, 0); // number of chords // link[v] = Iterator in possible, that points to v (if diag[v] = 0 and outer[v] = TRUE) NodeArray<ListIterator<node> > link(G, 0); // outer[v] = TRUE <=> v is a node of the actual outer face NodeArray<bool> outer(G, false); // List of all nodes v with outer[v] = TRUE and diag[v] = 0 List<node> possible; // nodes of the outer triangle (v_1,v_2,v_n) node v_1 = e_12->theNode(); node v_2 = e_2n->theNode(); node v_n = e_n1->theNode(); node v_k, wp, wq, u; adjEntry e, e2; int k; // initialization: beginn with outer face (v_1,v_2,v_n) // v_n is the only possible node num[v_1] = 1; num[v_2] = 2; outer[v_1] = true; outer[v_2] = true; outer[v_n] = true; link[v_n] = possible.pushBack(v_n); e_wq[v_1] = e_n1->twin(); e_wp[v_2] = e_2n; e_wq[v_n] = e_2n->twin(); e_wp[v_n] = e_n1; // select next v_k and delete it for (k = G.numberOfNodes(); k >= 3; k--) { v_k = possible.popFrontRet(); // select arbitrary node from possible as v_k num[v_k] = k; // predecessor wp and successor wq from vk in C_k (actual outer face) wq = (e_wq [v_k])->twinNode(); wp = (e_wp [v_k])->twinNode(); // v_k not in C_k-1 anymore outer[v_k] = false; // shortfall of a chord? if (e_wq[wp]->cyclicSucc()->twinNode() == wq) { // wp, wq is the only successor of vk in G_k // wp, wq loose a chord if (--num_diag[wp] == 0) { link[wp] = possible.pushBack(wp); } if (--num_diag[wq] == 0) { link[wq] = possible.pushBack(wq); } } // update or initialize e_wq, e_wp e_wq[wp] = e_wq[wp]->cyclicSucc(); e_wp[wq] = e_wp[wq]->cyclicPred(); e = e_wq[wp]; for (u = e->twinNode(); u != wq; u = e->twinNode()) { outer[u] = true; e_wp[u] = e->twin(); e = e_wq[u] = e_wp[u]->cyclicSucc()->cyclicSucc(); // search for new chords for (e2 = e_wp[u]->cyclicPred(); e2 != e_wq[u]; e2 = e2->cyclicPred()) { node w = e2->twinNode(); if (outer[w] == true) { ++num_diag[u]; if (w != v_1 && w != v_2) if (++num_diag[w] == 1) possible.del(link[w]); } } if (num_diag[u] == 0) { link[u] = possible.pushBack(u); } } } }