Ejemplo n.º 1
0
void DynamicSPQRForest::createSPQR (node vB) const
{
	Graph GC;
	NodeArray<node> origNode(GC,0);
	EdgeArray<edge> origEdge(GC,0);
	SListConstIterator<edge> iH;

	for (iH=m_bNode_hEdges[vB].begin(); iH.valid(); ++iH)
		m_htogc[(*iH)->source()] = m_htogc[(*iH)->target()] = 0;

	for (iH=m_bNode_hEdges[vB].begin(); iH.valid(); ++iH) {
		edge eH = *iH;
		node sH = eH->source();
		node tH = eH->target();
		node& sGC = m_htogc[sH];
		node& tGC = m_htogc[tH];
		if (!sGC) { sGC = GC.newNode(); origNode[sGC] = sH; }
		if (!tGC) { tGC = GC.newNode(); origNode[tGC] = tH; }
		origEdge[GC.newEdge(sGC,tGC)] = eH;
	}

	TricComp tricComp(GC);

	const GraphCopySimple& GCC = *tricComp.m_pGC;

	EdgeArray<node> partnerNode(GCC,0);
	EdgeArray<edge> partnerEdge(GCC,0);

	for (int i=0; i<tricComp.m_numComp; ++i) {
		const TricComp::CompStruct &C = tricComp.m_component[i];

		if (C.m_edges.empty()) continue;

		node vT = m_T.newNode();
		m_tNode_owner[vT] = vT;

		switch(C.m_type) {
			case TricComp::bond:
				m_tNode_type[vT] = PComp;
				m_bNode_numP[vB]++;
				break;
			case TricComp::polygon:
				m_tNode_type[vT] = SComp;
				m_bNode_numS[vB]++;
				break;
			case TricComp::triconnected:
				m_tNode_type[vT] = RComp;
				m_bNode_numR[vB]++;
				break;
		}

		for (ListConstIterator<edge> iGCC=C.m_edges.begin(); iGCC.valid(); ++iGCC) {
			edge eGCC = *iGCC;
			edge eH = GCC.original(eGCC);
			if (eH) eH = origEdge[eH];
			else {
				node uH = origNode[GCC.original(eGCC->source())];
				node vH = origNode[GCC.original(eGCC->target())];
				eH = m_H.newEdge(uH,vH);

				if (!partnerNode[eGCC]) {
					partnerNode[eGCC] = vT;
					partnerEdge[eGCC] = eH;
				}
				else {
					m_T.newEdge(partnerNode[eGCC],vT);
					m_hEdge_twinEdge[eH] = partnerEdge[eGCC];
					m_hEdge_twinEdge[partnerEdge[eGCC]] = eH;
				}
			}
			m_hEdge_position[eH] = m_tNode_hEdges[vT].pushBack(eH);
			m_hEdge_tNode[eH] = vT;
		}
	}

	m_bNode_SPQR[vB] = m_hEdge_tNode[origEdge[GC.firstEdge()]];
	m_tNode_hRefEdge[m_bNode_SPQR[vB]] = 0;

	SList<node> lT;
	lT.pushBack(m_bNode_SPQR[vB]);
	lT.pushBack(0);
	while (!lT.empty()) {
		node vT = lT.popFrontRet();
		node wT = lT.popFrontRet();
		for (ListConstIterator<edge> iH=m_tNode_hEdges[vT].begin(); iH.valid(); ++iH) {
			edge eH = *iH;
			edge fH = m_hEdge_twinEdge[eH];
			if (!fH) continue;
			node uT = m_hEdge_tNode[fH];
			if (uT==wT) m_tNode_hRefEdge[vT] = eH;
			else {
				lT.pushBack(uT);
				lT.pushBack(vT);
			}
		}
	}
}
Ejemplo n.º 2
0
void StaticSPQRTree::init(edge eRef, TricComp &tricComp)
{
	m_cpV = nullptr;
	const GraphCopySimple &GC = *tricComp.m_pGC;

	m_type.init(m_tree,SNode);
	m_sk.init(m_tree,nullptr);

	m_skEdgeSrc.init(m_tree,nullptr);
	m_skEdgeTgt.init(m_tree,nullptr);

	NodeArray<node> mapV(GC,nullptr);
	BoundedStack<node> inMapV(GC.numberOfNodes());

	EdgeArray<node> partnerNode(GC,nullptr);
	EdgeArray<edge> partnerEdge(GC,nullptr);

	m_numS = m_numP = m_numR = 0;

	for (int i = 0; i < tricComp.m_numComp; i++) {
		const TricComp::CompStruct &C = tricComp.m_component[i];

		if (C.m_edges.empty()) continue;

		node vT = m_tree.newNode();

		switch(C.m_type) {
		case TricComp::bond:
			m_type[vT] = PNode;
			m_numP++; break;

		case TricComp::polygon:
			m_type[vT] = SNode;
			m_numS++; break;

		case TricComp::triconnected:
			m_type[vT] = RNode;
			m_numR++; break;
		}

		m_sk[vT] = OGDF_NEW StaticSkeleton(this,vT);
		StaticSkeleton &S = *m_sk[vT];

		for(edge e : C.m_edges)
		{
			edge eG  = GC.original(e);

			node uGC = e->source(), vGC = e->target();
			node uM = mapV[uGC], vM = mapV[vGC];

			if (uM == nullptr) {
				uM = mapV[uGC] = S.m_M.newNode();
				inMapV.push(uGC);
				S.m_orig[uM] = GC.original(uGC);
			}
			if (vM == nullptr) {
				vM = mapV[vGC] = S.m_M.newNode();
				inMapV.push(vGC);
				S.m_orig[vM] = GC.original(vGC);
			}

			// normalize direction of virtual edges
			if(eG == nullptr && GC.original(vGC) < GC.original(uGC))
				swap(uM,vM);

			edge eM  = S.m_M.newEdge(uM,vM);

			if (eG == nullptr) {
				if (partnerNode[e] == nullptr) {
					partnerNode[e] = vT;
					partnerEdge[e] = eM;

				} else {
					edge eT = m_tree.newEdge(partnerNode[e],vT);
					StaticSkeleton &pS = *m_sk[partnerNode[e]];
					pS.m_treeEdge[partnerEdge[e]] = S.m_treeEdge[eM] = eT;
					m_skEdgeSrc[eT] = partnerEdge[e];
					m_skEdgeTgt[eT] = eM;
				}

			} else {
				S.m_real[eM] = eG;
				m_copyOf[eG] = eM;
				if (eG->source() != S.original(eM->source()))
					S.m_M.reverseEdge(eM);
				m_skOf  [eG] = &S;
			}
		}

		while(!inMapV.empty())
			mapV[inMapV.pop()] = nullptr;
	}

	rootTreeAt(eRef);
}