Don't import ogdf namespace
[TortoiseGit.git] / ext / OGDF / ogdf / planarity / PlanRep.h
blob89586989a4d89c2db66de994c15deb41c41402a5
1 /*
2 * $Revision: 2583 $
4 * last checkin:
5 * $Author: gutwenger $
6 * $Date: 2012-07-12 01:02:21 +0200 (Do, 12. Jul 2012) $
7 ***************************************************************/
9 /** \file
10 * \brief Declaration of a base class for planar representations
11 * of graphs and cluster graphs.
13 * \author Karsten Klein
15 * \par License:
16 * This file is part of the Open Graph Drawing Framework (OGDF).
18 * \par
19 * Copyright (C)<br>
20 * See README.txt in the root directory of the OGDF installation for details.
22 * \par
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * Version 2 or 3 as published by the Free Software Foundation;
26 * see the file LICENSE.txt included in the packaging of this file
27 * for details.
29 * \par
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * \par
36 * You should have received a copy of the GNU General Public
37 * License along with this program; if not, write to the Free
38 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
39 * Boston, MA 02110-1301, USA.
41 * \see http://www.gnu.org/copyleft/gpl.html
42 ***************************************************************/
45 //PlanRep should not know about generalizations and association,
46 //but we already set types in Attributedgraph, therefore set them
47 //in PlanRep, too
49 #ifdef _MSC_VER
50 #pragma once
51 #endif
53 #ifndef OGDF_PLANREP_H
54 #define OGDF_PLANREP_H
57 #include <ogdf/basic/GraphCopy.h>
58 #include <ogdf/planarity/EdgeTypePatterns.h>
59 #include <ogdf/planarity/NodeTypePatterns.h>
60 #include <ogdf/basic/Layout.h>
61 #include <ogdf/orthogonal/OrthoRep.h>
62 #include <ogdf/basic/GraphAttributes.h>
65 namespace ogdf {
68 /**
69 * \brief Planarized representations (of a connected component) of a graph.
71 * Maintains types of edges (generalization, association) and nodes,
72 * and the connected components of the graph.
74 class OGDF_EXPORT PlanRep : public GraphCopy
76 public:
77 //! Information for restoring degree-1 nodes.
78 struct Deg1RestoreInfo
80 Deg1RestoreInfo() : m_eOriginal(0), m_deg1Original(0), m_adjRef(0) { }
81 Deg1RestoreInfo(edge eOrig, node deg1Orig, adjEntry adjRef)
82 : m_eOriginal(eOrig), m_deg1Original(deg1Orig), m_adjRef(adjRef) { }
84 edge m_eOriginal; //!< the original edge leading to the deg-1 node
85 node m_deg1Original; //!< the original deg-1 node
86 adjEntry m_adjRef; //!< the reference adjacency entry for restoring the edge
90 /* @{
91 * \brief Creates a planarized representation of graph \a G.
93 PlanRep(const Graph& G);
95 /**
96 * \brief Creates a planarized representation of graph \a AG.
98 PlanRep(const GraphAttributes& AG);
100 virtual ~PlanRep() {}
103 //@}
105 * @name Processing connected components
106 * Planarized representations provide a mechanism for always representing
107 * a copy of a single component of the original graph.
109 //@{
112 * \brief Returns the number of connected components in the original graph.
114 int numberOfCCs() const {
115 return m_nodesInCC.size();
119 * \brief Returns the index of the current connected component (-1 if not yet initialized).
121 int currentCC() const {
122 return m_currentCC;
126 * \brief Returns the list of (original) nodes in connected component \a i.
128 * Note that connected components are numbered 0,1,...
130 const List<node> &nodesInCC(int i) const {
131 return m_nodesInCC[i];
135 * \brief Returns the list of (original) nodes in the current connected component.
137 const List<node> &nodesInCC() const {
138 return m_nodesInCC[m_currentCC];
142 * \brief Initializes the planarized representation for connected component \a i.
144 * This initialization is always required. After performing this initialization,
145 * the planarized representation represents a copy of the <i>i</i>-th connected
146 * component of the original graph, where connected components are numbered
147 * 0,1,2,...
149 void initCC(int i);
152 //@}
154 * @name Node expansion
156 //@{
159 * \brief Returns the adjacency entry of a node of an expanded face.
161 * If no such entry is stored at node \a v, 0 is returned.
163 adjEntry expandAdj(node v) const {
164 return m_expandAdj[v];
167 adjEntry& expandAdj(node v) {
168 return m_expandAdj[v];
171 //@}
173 * @name Clique boundary
175 //@{
178 * Returns the adjacency entry of the first edge of the inserted boundary
179 * at a center node (original) of a clique, 0 if no boundary exists
181 adjEntry boundaryAdj(node v) const {
182 return m_boundaryAdj[v];
186 * Returns a reference to the adjacency entry of the first edge of the inserted boundary
187 * at a center node (original) of a clique, 0 if no boundary exists
189 adjEntry& boundaryAdj(node v){
190 return m_boundaryAdj[v];
193 //edge on the clique boundary, adjSource
194 void setCliqueBoundary(edge e) {
195 setEdgeTypeOf(e, edgeTypeOf(e) | cliquePattern());
197 bool isCliqueBoundary(edge e) {
198 return ((edgeTypeOf(e) & cliquePattern()) == cliquePattern());
202 //@}
204 * @name Node types
206 //@{
209 * \brief Returns the type of node \a v.
210 * @param v is a node in the planarized representation.
212 Graph::NodeType typeOf(node v) const {
213 return m_vType[v];
217 * \brief Returns a reference to the type of node \a v.
218 * @param v is a node in the planarized representation.
220 Graph::NodeType& typeOf(node v) {
221 return m_vType[v];
225 * \brief Returns true if the node represents a "real" object in the original graph.
227 * \todo It is necessary to check for several different possible types.
228 * This should be solved by combining representation types (vertex, dummy,...)
229 * with semantic types (class, interface,...) within GraphAttributes;
230 * we then can return to vertex only.
232 inline bool isVertex(node v)
234 return ( (typeOf(v) == Graph::vertex) ||
235 (typeOf(v) == Graph::associationClass));
239 * \brief Returns the extended node type of \a v.
240 * @param v is a node in the planarized representation.
242 nodeType nodeTypeOf(node v)
244 return m_nodeTypes[v];
248 * \brief Classifies node \a v as a crossing.
249 * @param v is a node in the planarized representation.
251 void setCrossingType(node v)
253 m_nodeTypes[v] |= ntTerCrossing << ntoTertiary;
257 * \brief Returns true iff node \a v is classified as a crossing.
258 * @param v is a node in the planarized representation.
260 bool isCrossingType(node v)
262 return (m_nodeTypes[v] &= (ntTerCrossing << ntoTertiary)) != 0;
265 //@}
267 * @name Edge types
269 //@{
272 * \brief Returns the type of edge \a e.
273 * @param e is an edge in the planarized representation.
275 EdgeType typeOf(edge e) const {
276 return m_eType[e];
280 * \brief Returns a reference to the type of edge \a e.
281 * @param e is an edge in the planarized representation.
283 EdgeType& typeOf(edge e) {
284 return m_eType[e];
288 * \brief Returns a reference to the type of original edge \a e.
289 * @param e is an edge in the original graph.
291 edgeType& oriEdgeTypes(edge e)
293 return m_oriEdgeTypes[e];
297 * \brief Returns the new type field of \a e.
298 * @param e is an edge in the planarized representation.
300 edgeType edgeTypeOf(edge e)
302 return m_edgeTypes[e];
306 * \brief Returns a reference to the new type field of \a e.
307 * @param e is an edge in the planarized representation.
309 edgeType& edgeTypes(edge e)
311 return m_edgeTypes[e];
315 * \brief Sets the new type field of edge \a e to \a et.
316 * @param e is an edge in the planarized representation.
317 * @param et is the type assigned to \a e.
319 void setEdgeTypeOf(edge e, edgeType et)
321 m_edgeTypes[e] = et;
325 * \brief Set both type values of \a e at once.
327 * This is a temporary solution that sets both type values; this way, all
328 * additional edge types in the new field are lost.
329 * @param e is an edge in the planarized representation.
330 * @param et is the type assigned to \a e.
332 void setType(edge e, EdgeType et)
334 m_eType[e] = et;
335 switch (et)
337 case Graph::association: m_edgeTypes[e] = etcPrimAssociation;break;
338 case Graph::generalization: m_edgeTypes[e] = etcPrimGeneralization;
339 break;
340 case Graph::dependency: m_edgeTypes[e] = etcPrimDependency; break;
341 default: break;
345 //-------------------------------------------------------------------------
346 //new edge types
347 //to set or check edge types use the pattern function in the private section
349 //-------------------
350 //primary level types
352 //! Returns true iff edge \a e is classified as generalization.
353 bool isGeneralization(edge e) {
354 bool check = (((m_edgeTypes[e] & etpPrimary) & etcPrimGeneralization) == etcPrimGeneralization);
355 return check;
358 //! Classifies edge \a e as generalization (primary type).
359 void setGeneralization(edge e) {
360 setPrimaryType(e, etcPrimGeneralization);
362 //preliminary set old array too
363 m_eType[e] = generalization; //can be removed if edgetypes work properly
366 //! Returns true iff edge \a e is classified as dependency.
367 bool isDependency(edge e) {
368 bool check = (((m_edgeTypes[e] & etpPrimary) & etcPrimDependency) == etcPrimDependency);
369 return check;
372 //! Classifies edge \a e as dependency (primary type).
373 void setDependency(edge e) {
374 setPrimaryType(e, etcPrimDependency);
376 //preliminary set old array too
377 m_eType[e] = dependency; //can be removed if edgetypes work properly
380 //! Classifies edge \a e as association (primary type).
381 void setAssociation(edge e) {
382 setPrimaryType(e, etcPrimAssociation);
384 //preliminary set old array too
385 m_eType[e] = association; //can be removed if edgetypes work properly
388 //------------------
389 //second level types
391 //in contrast to setsecondarytype: do not delete old value
393 //! Classifies edge \a e as expansion edge (secondary type).
394 void setExpansion(edge e) {
395 m_edgeTypes[e] |= expansionPattern();
397 //preliminary set old array too
398 m_expansionEdge[e] = 1;//can be removed if edgetypes work properly
401 //! Returns true iff edge \a e is classified as expansion edge.
402 bool isExpansion(edge e) {
403 return ((m_edgeTypes[e] & expansionPattern()) == expansionPattern());
406 //should add things like cluster and clique boundaries that need rectangle shape
408 //! Returns true iff edge \a e is a clique boundary.
409 bool isBoundary(edge e) {
410 return isCliqueBoundary(e); }
412 //--------------
413 //tertiary types
415 //! Classifies edge \a e as connection at an association class (tertiary type).
416 void setAssClass(edge e)
418 m_edgeTypes[e] |= assClassPattern();
421 //! Returns true iff edge \a e is classified as connection at an association class.
422 bool isAssClass(edge e)
424 return ((m_edgeTypes[e] & assClassPattern()) == assClassPattern());
428 //------------------
429 //fourth level types
431 //! Classifies edge \a e as connection between hierarchy neighbours (fourth level type).
432 void setBrother(edge e) {
433 m_edgeTypes[e] |= brotherPattern();
436 //! Classifies edge \a e as connection between ... (fourth level type).
437 void setHalfBrother(edge e) {
438 m_edgeTypes[e] |= halfBrotherPattern();
441 //! Returns true if edge \a e is classified as brother.
442 bool isBrother(edge e) {
443 return ( (((m_edgeTypes[e] & etpFourth) & brotherPattern())>> etoFourth) == etcBrother);
446 //! Returns true if edge \a e is classified as half-brother.
447 bool isHalfBrother(edge e) {
448 return ( (((m_edgeTypes[e] & etpFourth) & halfBrotherPattern())>> etoFourth) == etcHalfBrother);
451 //-----------------
452 //set generic types
454 edgeType edgeTypeAND(edge e, edgeType et) {m_edgeTypes[e] &= et; return m_edgeTypes[e];}
456 edgeType edgeTypeOR(edge e, edgeType et) {m_edgeTypes[e] |= et; return m_edgeTypes[e];}
458 //set primary edge type of edge e to primary edge type in et
459 //deletes old primary value
460 void setPrimaryType(edge e, edgeType et) {
461 m_edgeTypes[e] &= 0xfffffff0;
462 m_edgeTypes[e] |= (etpPrimary & et);
465 void setSecondaryType(edge e, edgeType et) {
466 m_edgeTypes[e] &= 0xffffff0f;
467 m_edgeTypes[e] |= (etpSecondary & ( et << etoSecondary));
470 //sets primary type to bitwise AND of et's primary value and old value
471 edgeType edgeTypePrimaryAND(edge e, edgeType et) {m_edgeTypes[e] &= (etpAll & et); return m_edgeTypes[e];}
473 //sets primary type to bitwise OR of et's primary value and old value
474 edgeType edgeTypePrimaryOR(edge e, edgeType et) {m_edgeTypes[e] |= et; return m_edgeTypes[e];}
476 //set user defined type locally
477 void setUserType(edge e, edgeType et)
479 OGDF_ASSERT( et < 147);
480 m_edgeTypes[e] |= (et << etoUser);
483 bool isUserType(edge e, edgeType et)
485 OGDF_ASSERT( et < 147);
486 return ( (m_edgeTypes[e] & (et << etoUser)) == (et << etoUser));
489 //---------------
491 // old edge types
493 //this is pure nonsense, cause we have uml-edgetype and m_etype, and should be able to
494 //use them with different types, but as long as they arent used correctly (switch instead of xor),
495 //use this function to return if e is expansionedge
496 //if it is implemented correctly later, delete the array and return m_etype == Graph::expand
497 //(the whole function then is obsolete, cause you can check it directly, but for convenience...)
498 //should use genexpand, nodeexpand, dissect instead of bool
499 void setExpansionEdge(edge e, int expType) {
500 m_expansionEdge[e] = expType;
503 bool isExpansionEdge(edge e) const {
504 return (m_expansionEdge[e] > 0);
507 int expansionType(edge e) const { return m_expansionEdge[e]; }
509 //precondition normalized
510 bool isDegreeExpansionEdge(edge e) const {
511 //return (m_eType[e] == Graph::expand);
512 return ( m_expansionEdge[e] == 2);
516 //@}
518 * @name Access to attributes in original graph
519 * These methods provide easy access to attributes of original nodes and
520 * edges.
522 //@{
525 //! Gives access to the node array of the widths of original nodes.
526 const NodeArray<double> &widthOrig() const {
527 return m_pGraphAttributes->width();
530 //! Returns the width of original node \a v.
531 double widthOrig(node v) const {
532 return m_pGraphAttributes->width(v);
535 //! Gives access to the node array of the heights of original nodes.
536 const NodeArray<double> &heightOrig() const {
537 return m_pGraphAttributes->height();
540 //! Returns the height of original node \a v.
541 double heightOrig(node v) const {
542 return m_pGraphAttributes->height(v);
545 //! Returns the type of original edge \a e.
546 EdgeType typeOrig(edge e) const {
547 return m_pGraphAttributes->type(e);
550 //! Returns the graph attributes of the original graph (the pointer may be 0).
551 const GraphAttributes &getGraphAttributes() const {
552 return *m_pGraphAttributes;
555 //@}
557 * @name Structural alterations
559 //@{
561 // Expands nodes with degree > 4 and merge nodes for generalizations
562 void expand(bool lowDegreeExpand = false);
564 void expandLowDegreeVertices(OrthoRep &OR);
566 void collapseVertices(const OrthoRep &OR, Layout &drawing);
568 void removeCrossing(node v); //removes the crossing at node v
570 //model a boundary around a star subgraph centered at center
571 //and keep external face information (outside the clique
572 void insertBoundary(node center, adjEntry& adjExternal);
575 //@}
577 * @name Extension of methods defined by GraphCopys
579 //@{
581 //! Splits edge \a e.
582 virtual edge split(edge e);
585 //returns node which was expanded using v
586 node expandedNode(node v) const { return m_expandedNode[v]; }
588 void setExpandedNode(node v, node w) { m_expandedNode[v] = w; }
591 //@}
593 * @name Creation of new nodes and edges
595 //@{
598 * \brief Creates a new node with node type \a vType in the planarized representation.
599 * @param vOrig becomes the original node of the new node.
600 * @param vType becomes the type of the new node.
602 node newCopy(node vOrig, Graph::NodeType vType);
605 * \brief Creates a new edge in the planarized representation.
606 * @param v is the source node of the new edge.
607 * @param adjAfter is the adjacency entry at the target node, after which the
608 * new edge is inserted.
609 * @param eOrig becomes the original edge of the new edge.
611 edge newCopy(node v, adjEntry adjAfter, edge eOrig);
614 * \brief Creates a new edge in the planarized representation while updating the embedding \a E.
615 * @param v is the source node of the new edge.
616 * @param adjAfter is the adjacency entry at the target node, after which the
617 * new edge is inserted.
618 * @param eOrig becomes the original edge of the new edge.
619 * @param E is an embedding of the planarized representation.
621 edge newCopy(node v, adjEntry adjAfter, edge eOrig, CombinatorialEmbedding &E);
624 //@}
626 * @name Crossings
628 //@{
630 // embeds current copy
631 bool embed();
633 // removes all crossing nodes which are actually only two "touching" edges
634 void removePseudoCrossings();
636 // re-inserts edge eOrig by "crossing" the edges in crossedEdges;
637 // splits each edge in crossedEdges
638 // Precond.: eOrig is an edge in the original graph,
639 // the edges in crossedEdges are in this graph
640 void insertEdgePath(edge eOrig, const SList<adjEntry> &crossedEdges);
642 // same as insertEdgePath, but assumes that the graph is embedded
643 void insertEdgePathEmbedded(
644 edge eOrig,
645 CombinatorialEmbedding &E,
646 const SList<adjEntry> &crossedEdges);
648 // removes the complete edge path for edge eOrig
649 // Precond.: eOrig s an edge in the original graph
650 void removeEdgePathEmbedded(CombinatorialEmbedding &E,
651 edge eOrig,
652 FaceSetPure &newFaces) {
653 GraphCopy::removeEdgePathEmbedded(E,eOrig,newFaces);
656 //! Inserts crossings between two copy edges.
658 * This method is used in TopologyModule.
660 * Let \a crossingEdge = (\a a, \a b) and \a crossedEdge = (\a v, \a w).
661 * Then \a crossedEdge is split creating two edges \a crossedEdge = (\a v, \a u)
662 * and (\a u, \a w), \a crossingEdge is removed and replaced by two new edges
663 * \a e1 = (\a a, \a u) and \a e1 = (\a u, \a b).
664 * Finally it sets \a crossingEdge to \a e2 and returns (\a u, \a w).
666 * @param crossingEdge is the edge that gets split.
667 * @param crossedEdge is the edge that is replaced by two new edges.
668 * @param topDown is used as follows: If set to true, \a crossingEdge will cross
669 * \a crossedEdge from right to left, otherwise from left to right.
671 edge insertCrossing(
672 edge &crossingEdge,
673 edge crossedEdge,
674 bool topDown);
676 //@}
678 * @name Degree-1 nodes
679 * These methods realize a mechanism for temporarily removing degree-1 nodes.
681 //@{
684 * \brief Removes all marked degree-1 nodes from the graph copy and stores restore information in \a S.
685 * @param S returns the restore information required by restoreDeg1Nodes().
686 * @param mark defines which nodes are marked for removal; all nodes \a v with
687 * <I>mark</I>[<I>v</I>]=<B>true</B> are removed.
688 * \pre Only nodes with degree 1 may be marked.
690 void removeDeg1Nodes(Stack<Deg1RestoreInfo> &S, const NodeArray<bool> &mark);
693 * \brief Restores degree-1 nodes previously removed with removeDeg1Nodes().
694 * @param S contains the restore information.
695 * @param deg1s returns the list of newly created nodes in the copy.
697 void restoreDeg1Nodes(Stack<Deg1RestoreInfo> &S, List<node> &deg1s);
699 //@}
701 protected:
703 int m_currentCC; //!< The index of the current component.
704 int m_numCC; //!< The number of components in the original graph.
706 Array<List<node> > m_nodesInCC; //!< The list of original nodes in each component.
708 const GraphAttributes* m_pGraphAttributes; //!< Pointer to graph attributes of original graph.
710 //------------
711 //object types
713 //set the type of eCopy according to the type of eOrig
714 //should be virtual if PlanRepUML gets its own
715 void setCopyType(edge eCopy, edge eOrig);
717 //helper to cope with the edge types, shifting to the right place
718 edgeType generalizationPattern() {return etcPrimGeneralization;}
719 edgeType associationPattern() {return etcPrimAssociation;}
720 edgeType expansionPattern() {return etcSecExpansion << etoSecondary;}
721 edgeType assClassPattern() {return etcAssClass << etoTertiary;}
722 edgeType brotherPattern() {return etcBrother << etoFourth;}
723 edgeType halfBrotherPattern() {return etcHalfBrother << etoFourth;}
724 edgeType cliquePattern() {return etcSecClique << etoSecondary;} //boundary
727 void removeUnnecessaryCrossing(
728 adjEntry adjA1,
729 adjEntry adjA2,
730 adjEntry adjB1,
731 adjEntry adjB2);
733 //--------------------------------------------------------------------------
735 NodeArray<NodeType> m_vType; //!< Simple node types.
737 NodeArray<nodeType> m_nodeTypes; //!< Node types for extended semantic information.
739 NodeArray<node> m_expandedNode; //!< For all expansion nodes, save expanded node.
740 NodeArray<adjEntry> m_expandAdj;
742 //clique handling: We save an adjEntry of the first edge of an inserted
743 //boundary around a clique at its center v
744 NodeArray<adjEntry> m_boundaryAdj;
746 //zusammenlegbare Typen
747 EdgeArray<int> m_expansionEdge; //1 genmerge, 2 degree (2 highdegree, 3 lowdegree)
748 EdgeArray<EdgeType> m_eType;
750 //m_edgeTypes stores semantic edge type information on several levels:
751 //primary type: generalization, association,...
752 //secondary type: merger,...
753 //tertiary type: vertical in hierarchy, inner, outer, ...
754 //fourth type: neighbour relation (brother, cousin in hierarchy)
755 //user types: user defined for local changes
756 EdgeArray<edgeType> m_edgeTypes; //store all type information
758 //workaround fuer typsuche in insertedgepathembed
759 //speichere kopietyp auf originalen
760 //maybe it's enough to set gen/ass without extra array
761 EdgeArray<edgeType> m_oriEdgeTypes;
763 EdgeArray<edge> m_eAuxCopy; // auxiliary (GraphCopy::initByNodes())
765 };//PlanRep
767 } // end namespace ogdf
770 #endif