|
Open Graph Drawing Framework |
v. 2023.09 (Elderberry)
|
|
|
Go to the documentation of this file.
42 #include <type_traits>
46 template<
bool isConst>
60 template<
bool isConst>
68 const Graph& primalGraph = CE.getGraph();
70 Graph& dualGraph = getGraph();
73 m_dualEdge.init(primalGraph);
74 m_dualFace.init(primalGraph);
76 m_primalNode.init(*
this,
nullptr);
78 m_primalNode.init(*
this);
80 m_primalFace.init(dualGraph);
81 m_primalEdge.init(dualGraph);
84 for (
face f : CE.faces) {
86 m_dualNode[f] = vDual;
87 m_primalFace[vDual] = f;
93 node vDualSource = m_dualNode[CE.rightFace(aE)];
94 node vDualTarget = m_dualNode[CE.leftFace(aE)];
95 edge eDual = dualGraph.
newEdge(vDualSource, vDualTarget);
96 m_primalEdge[eDual] = e;
97 m_dualEdge[e] = eDual;
101 for (
face f : CE.faces) {
102 node vDual = m_dualNode[f];
107 edge eDual = m_dualEdge[e];
113 dualGraph.
sort(vDual, newOrder);
121 edge eDual = m_dualEdge[ePrimal];
123 if (ePrimal->
source() == v) {
129 m_dualFace[v] = fDual;
130 m_primalNode[fDual] = v;
198 edge oldDualEdge {m_dualEdge[e]};
202 face oldDualFace {rightFace(oldDualEdge->adjSource())};
206 edge newPrimalEdge {m_primalEmbedding.split(e)};
207 node newPrimalNode {newPrimalEdge->source()};
211 oldDualEdge->adjSource()->faceCycleSucc())};
212 face newDualFace {leftFace(newDualEdge->adjSource())};
215 m_dualEdge[newPrimalEdge] = newDualEdge;
216 m_primalEdge[newDualEdge] = newPrimalEdge;
218 m_dualFace[newPrimalNode] = newDualFace;
219 m_primalNode[newDualFace] = newPrimalNode;
221 OGDF_ASSERT(m_dualFace[oldPrimalNode] == oldDualFace);
222 OGDF_ASSERT(m_primalNode[oldDualFace] == oldPrimalNode);
224 #ifdef OGDF_HEAVY_DEBUG
228 return newPrimalEdge;
236 m_primalEmbedding.unsplit(eIn, eOut);
240 m_dualFace[oldPrimalNode] = oldDualFace;
241 m_primalNode[oldDualFace] = oldPrimalNode;
244 #ifdef OGDF_HEAVY_DEBUG
253 face oldDualFace {m_dualFace[oldPrimalNode]};
256 node newPrimalNode {m_primalEmbedding.splitNode(adjStartLeft, adjStartRight)};
260 adjEntry dualAdjLeft {dualAdj(adjStartLeft,
true)};
261 adjEntry dualAdjRight {dualAdj(adjStartRight,
true)};
262 OGDF_ASSERT(dualAdjLeft->theNode() == m_dualNode[m_primalEmbedding.leftFace(adjStartLeft)]);
263 OGDF_ASSERT(dualAdjRight->theNode() == m_dualNode[m_primalEmbedding.leftFace(adjStartRight)]);
265 face newDualFace {leftFace(newDualEdge->adjSource())};
268 m_dualEdge[newPrimalEdge] = newDualEdge;
269 m_primalEdge[newDualEdge] = newPrimalEdge;
271 m_dualFace[newPrimalNode] = oldDualFace;
272 m_primalNode[oldDualFace] = newPrimalNode;
274 m_dualFace[oldPrimalNode] = newDualFace;
275 m_primalNode[newDualFace] = oldPrimalNode;
277 #ifdef OGDF_HEAVY_DEBUG
281 return newPrimalNode;
287 edge dualEdge {m_dualEdge[e]};
292 node newPrimalNode {m_primalEmbedding.contract(e, keepSelfLoops)};
296 m_dualFace[newPrimalNode] = newDualFace;
297 m_primalNode[newDualFace] = newPrimalNode;
299 #ifdef OGDF_HEAVY_DEBUG
303 return newPrimalNode;
310 face oldPrimalFace {m_primalEmbedding.rightFace(adjSrc)};
311 node oldDualNode {m_dualNode[oldPrimalFace]};
315 edge newPrimalEdge {m_primalEmbedding.splitFace(adjSrc, adjTgt, sourceAfter)};
316 face newPrimalFace {m_primalEmbedding.leftFace(newPrimalEdge->adjSource())};
320 adjEntry rightAdj {dualAdj(adjSrc)};
325 edge newDualEdge {leftAdj->cyclicPred()->theEdge()};
328 m_dualEdge[newPrimalEdge] = newDualEdge;
329 m_primalEdge[newDualEdge] = newPrimalEdge;
331 m_dualNode[newPrimalFace] = newDualNode;
332 m_primalFace[newDualNode] = newPrimalFace;
334 OGDF_ASSERT(m_dualNode[oldPrimalFace] == oldDualNode);
335 OGDF_ASSERT(m_primalFace[oldDualNode] == oldPrimalFace);
337 #ifdef OGDF_HEAVY_DEBUG
341 return newPrimalEdge;
347 return addEdgeToIsolatedNodePrimal(adjTgt, v,
false);
353 return addEdgeToIsolatedNodePrimal(adjSrc, v,
true);
359 edge eDual {m_dualEdge[e]};
362 face oldPrimalFace {m_primalEmbedding.joinFaces(e)};
365 m_primalFace[oldDualNode] = oldPrimalFace;
366 m_dualNode[oldPrimalFace] = oldDualNode;
368 #ifdef OGDF_HEAVY_DEBUG
372 return oldPrimalFace;
381 edge dualEdge {m_dualEdge[primalEdge]};
383 node otherPrimalNode {primalEdge->opposite(v)};
386 m_primalEmbedding.removeDeg1(v);
392 OGDF_ASSERT(m_dualFace[otherPrimalNode] == newDualFace);
393 OGDF_ASSERT(m_primalNode[newDualFace] == otherPrimalNode);
395 #ifdef OGDF_HEAVY_DEBUG
403 m_primalEmbedding.reverseEdge(e);
406 #ifdef OGDF_HEAVY_DEBUG
412 void consistencyCheck()
const {
414 Embedding::consistencyCheck();
416 const Graph& primalGraph {m_primalEmbedding.getGraph()};
417 const Graph& dualGraph {getGraph()};
418 OGDF_ASSERT(primalGraph.numberOfNodes() == numberOfFaces());
419 OGDF_ASSERT(primalGraph.numberOfEdges() == dualGraph.numberOfEdges());
420 OGDF_ASSERT(m_primalEmbedding.numberOfFaces() == dualGraph.numberOfNodes());
422 for (
node vDual : dualGraph.nodes) {
423 OGDF_ASSERT(m_dualNode[m_primalFace[vDual]] == vDual);
425 for (
edge eDual : dualGraph.edges) {
426 OGDF_ASSERT(m_dualEdge[m_primalEdge[eDual]] == eDual);
429 OGDF_ASSERT(leftFace(eDual->adjSource()) == m_dualFace[m_primalEdge[eDual]->source()]);
430 OGDF_ASSERT(rightFace(eDual->adjSource()) == m_dualFace[m_primalEdge[eDual]->target()]);
432 for (
face fDual : Embedding::faces) {
433 OGDF_ASSERT(m_dualFace[m_primalNode[fDual]] == fDual);
452 face oldPrimalFace {m_primalEmbedding.rightFace(adj)};
453 node oldDualNode {m_dualNode[oldPrimalFace]};
456 face oldDualFace {m_dualFace[oldPrimalNode]};
459 edge newPrimalEdge {adjSrc ? m_primalEmbedding.addEdgeToIsolatedNode(adj, v)
460 : m_primalEmbedding.addEdgeToIsolatedNode(v, adj)};
463 adjEntry dualAdjEntry {dualAdj(primalAdj)};
464 OGDF_ASSERT(dualAdjEntry->theNode() == oldDualNode);
466 face newDualFace {leftFace(newDualEdge->adjSource())};
469 m_dualEdge[newPrimalEdge] = newDualEdge;
470 m_primalEdge[newDualEdge] = newPrimalEdge;
473 m_primalNode[oldDualFace] = v;
474 m_dualFace[v] = oldDualFace;
476 m_primalNode[newDualFace] = oldPrimalNode;
477 m_dualFace[oldPrimalNode] = newDualFace;
479 m_primalNode[newDualFace] = v;
480 m_dualFace[v] = newDualFace;
482 OGDF_ASSERT(m_primalNode[oldDualFace] == oldPrimalNode);
483 OGDF_ASSERT(m_dualFace[oldPrimalNode] == oldDualFace);
486 #ifdef OGDF_HEAVY_DEBUG
490 return newPrimalEdge;
497 : m_dualEdge[primalAdj->
theEdge()]->adjTarget();
edge addEdgeToIsolatedNodePrimal(node v, adjEntry adjTgt)
Inserts a new edge similarly to #splitFace without having to call #computeFaces again.
The namespace for all OGDF objects.
NodeArray< face > m_dualFace
The corresponding face in embedding of the dual graph.
void removeDeg1Primal(node v)
Removes degree-1 node v.
Includes declaration of graph class.
const node & primalNode(face f) const
Returns the node in the primal graph corresponding to f.
void sort(node v, const ADJ_ENTRY_LIST &newOrder)
Sorts the adjacency list of node v according to newOrder.
typename std::conditional< isConst, const ConstCombinatorialEmbedding, CombinatorialEmbedding >::type Embedding
void reverseEdgePrimal(edge e)
Reverses edges e and updates embedding.
const face & primalFace(node v) const
Returns the face in the embedding of the primal graph corresponding to v.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Embedding & m_primalEmbedding
The embedding of the primal graph.
node theNode() const
Returns the node whose adjacency list contains this element.
EdgeArray< edge > m_primalEdge
The corresponding edge in the primal graph.
A dual graph including its combinatorial embedding of an embedded graph.
adjEntry cyclicPred() const
Returns the cyclic predecessor in the adjacency list.
NodeArray< face > m_primalFace
The corresponding facee in the embedding of the primal graph.
internal::FaceAdjContainer entries
Container maintaining the adjacency entries in the face.
void unsplitPrimal(edge eIn, edge eOut)
Undoes a split operation.
~DualGraphBase()
Destructor.
face joinFaces(edge e)
Removes edge e and joins the two faces adjacent to e.
edge splitFace(adjEntry adjSrc, adjEntry adjTgt, bool sourceAfter=false)
Splits a face by inserting a new edge.
node splitNode(adjEntry adjStartLeft, adjEntry adjStartRight)
Splits a node while preserving the order of adjacency entries.
adjEntry faceCyclePred() const
Returns the cyclic predecessor in face.
Class for adjacency list elements.
Reverse< T > reverse(T &container)
Provides iterators for container to make it easily iterable in reverse.
bool isSource() const
Returns true iff this is the source adjacency entry of the corresponding edge.
EdgeElement * edge
The type of edges.
edge theEdge() const
Returns the edge associated with this adjacency entry.
edge splitPrimal(edge e)
Splits edge e=(v,w) into e=(v,u) and e'=(u,w) creating a new node u.
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
int degree() const
Returns the degree of the node (indegree + outdegree).
adjEntry dualAdj(adjEntry primalAdj, bool reverse=false)
Returns the corresponding adjEntry of the dual edge of primalAdj (or the opposite adjEntry of the dua...
Decralation of GraphElement and GraphList classes.
EdgeArray< edge > m_dualEdge
The corresponding edge in the dual graph.
edge addEdgeToIsolatedNodePrimal(adjEntry adj, node v, bool adjSrc)
Inserts a new edge similarly to #splitFace without having to call #computeFaces again.
node source() const
Returns the source node of the edge.
NodeElement * node
The type of nodes.
const Graph & getPrimalGraph() const
Returns a reference to the primal graph.
Doubly linked lists (maintaining the length of the list).
RegisteredArray for nodes, edges and adjEntries of a graph.
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
Data type for general directed graphs (adjacency list representation).
RegisteredArray for labeling the faces of a CombinatorialEmbedding.
void reverseEdge(edge e)
Reverses edges e and updates embedding.
node contract(edge e, bool keepSelfLoops=false)
Contracts edge e while preserving the order of adjacency entries.
FaceArray< node > m_dualNode
The corresponding node in the dual graph.
Decralation of graph iterators.
face joinFacesPrimal(edge e)
Removes edge e and joins the two faces adjacent to e.
edge splitFacePrimal(adjEntry adjSrc, adjEntry adjTgt, bool sourceAfter=false)
Splits a face by inserting a new edge.
Combinatorial embeddings of planar graphs.
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Embedding & getPrimalEmbedding() const
Returns a reference to the combinatorial embedding of the primal graph.
node contractPrimal(edge e, bool keepSelfLoops=false)
Contracts edge e while preserving the order of adjacency entries.
const edge & dualEdge(edge e) const
Returns the edge in the dual graph corresponding to e.
FaceArray< node > m_primalNode
The corresponding node in the primal graph.
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Basic declarations, included by all source files.
Declaration of CombinatorialEmbedding and face.
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF DLL.
const edge & primalEdge(edge e) const
Returns the edge in the primal graph corresponding to e.
node newNode(int index=-1)
Creates a new node and returns it.
Combinatorial embeddings of planar graphs with modification functionality.
adjEntry firstAdj() const
Returns the first entry in the adjaceny list.
Class for the representation of edges.
Declaration of doubly linked lists and iterators.
node target() const
Returns the target node of the edge.
edge newEdge(node v, node w, int index=-1)
Creates a new edge (v,w) and returns it.
const node & dualNode(face f) const
Returns the node in the dual graph corresponding to f.
Class for the representation of nodes.
edge addEdgeToIsolatedNodePrimal(adjEntry adjSrc, node v)
Inserts a new edge similarly to #splitFace without having to call #computeFaces again.
node splitNodePrimal(adjEntry adjStartLeft, adjEntry adjStartRight)
Splits a node while preserving the order of adjacency entries.
const face & dualFace(node v) const
Returns the face in the embedding of the dual graph corresponding to v.
iterator pushBack(const E &x)
Adds element x at the end of the list.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
DualGraphBase(Embedding &CE)
Constructor; creates dual graph and its combinatorial embedding.
Faces in a combinatorial embedding.