6 * $Date: 2012-07-07 00:03:48 +0200 (Sa, 07. Jul 2012) $
7 ***************************************************************/
10 * \brief Declaration of ClusterPlanRep class, allowing cluster
11 * boundary insertion and shortest path edge insertion
13 * \author Karsten Klein
16 * This file is part of the Open Graph Drawing Framework (OGDF).
20 * See README.txt in the root directory of the OGDF installation for details.
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
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.
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 ***************************************************************/
48 #ifndef OGDF_CLUSTER_PLAN_REP_H
49 #define OGDF_CLUSTER_PLAN_REP_H
53 #include <ogdf/planarity/PlanRepUML.h>
54 #include <ogdf/cluster/ClusterGraphAttributes.h>
55 #include <ogdf/cluster/ClusterGraph.h>
56 #include <ogdf/cluster/ClusterArray.h>
58 #include <ogdf/basic/HashArray.h>
64 class OGDF_EXPORT ClusterPlanRep
: public PlanRep
70 const ClusterGraphAttributes
&acGraph
,
71 const ClusterGraph
&clusterGraph
);
73 virtual ~ClusterPlanRep() { }
77 //edge on the cluster boundary, adjSource
78 void setClusterBoundary(edge e
) {
79 setEdgeTypeOf(e
, edgeTypeOf(e
) | clusterPattern());
81 bool isClusterBoundary(edge e
) {
82 return ((edgeTypeOf(e
) & clusterPattern()) == clusterPattern());
84 const ClusterGraph
&getClusterGraph() const {
85 return *m_pClusterGraph
;
88 /** re-inserts edge eOrig by "crossing" the edges in crossedEdges;
89 * splits each edge in crossedEdges
90 * Precond.: eOrig is an edge in the original graph,
91 * the edges in crossedEdges are in this graph,
92 * cluster boundaries are modelled as edge paths
93 * \param eOrig: Original edge to be inserted
94 * \param crossedEdges: Edges that are crossed by this insertion
95 * \param E: The embedding in which the edge is inserted
97 void insertEdgePathEmbedded(
99 CombinatorialEmbedding
&E
,
100 const SList
<adjEntry
> &crossedEdges
);
102 void ModelBoundaries();
104 //rootadj is set by ModelBoundaries
105 adjEntry
externalAdj() { return m_rootAdj
; }
108 //*************************************************************************
109 //structural alterations
111 // Expands nodes with degree > 4 and merge nodes for generalizations
112 virtual void expand(bool lowDegreeExpand
= false);
114 virtual void expandLowDegreeVertices(OrthoRep
&OR
);
116 //splits edge e, updates clustercage lists if necessary and returns new edge
117 virtual edge
split(edge e
)
119 edge eNew
= PlanRep::split(e
);
121 //update edge to cluster info
122 m_edgeClusterID
[eNew
] = m_edgeClusterID
[e
];
123 m_nodeClusterID
[eNew
->source()] = m_edgeClusterID
[e
];
129 //returns cluster of edge e
130 //edges only have unique numbers if clusters are already modelled
131 //we derive the edge cluster from the endnode cluster information
132 cluster
clusterOfEdge(edge e
)
135 OGDF_ASSERT(m_clusterOfIndex
.isDefined(ClusterID(e
->source())))
136 OGDF_ASSERT(m_clusterOfIndex
.isDefined(ClusterID(e
->target())))
139 (ClusterID(e
->source()) == ClusterID(e
->target())) ||
140 (clusterOfIndex(ClusterID(e
->source())) ==
141 clusterOfIndex(ClusterID(e
->target()))->parent()) ||
142 (clusterOfIndex(ClusterID(e
->target())) ==
143 clusterOfIndex(ClusterID(e
->source()))->parent()) ||
144 (clusterOfIndex(ClusterID(e
->target()))->parent() ==
145 clusterOfIndex(ClusterID(e
->source()))->parent())
148 if (ClusterID(e
->source()) == ClusterID(e
->target()))
149 return clusterOfIndex(ClusterID(e
->target()));
150 if (clusterOfIndex(ClusterID(e
->source())) ==
151 clusterOfIndex(ClusterID(e
->target()))->parent())
152 return clusterOfIndex(ClusterID(e
->source()));
153 if (clusterOfIndex(ClusterID(e
->target())) ==
154 clusterOfIndex(ClusterID(e
->source()))->parent())
155 return clusterOfIndex(ClusterID(e
->target()));
156 if (clusterOfIndex(ClusterID(e
->target()))->parent() ==
157 clusterOfIndex(ClusterID(e
->source()))->parent())
158 return clusterOfIndex(ClusterID(e
->source()))->parent();
160 OGDF_THROW(AlgorithmFailureException
);
164 inline int ClusterID(node v
) const {return m_nodeClusterID
[v
];}
165 inline int ClusterID(edge e
) const {return m_edgeClusterID
[e
];}
166 cluster
clusterOfIndex(int i
) {return m_clusterOfIndex
[i
];}
168 inline cluster
clusterOfDummy(node v
)
170 OGDF_ASSERT(!original(v
))
171 OGDF_ASSERT(ClusterID(v
) != -1)
172 return clusterOfIndex(ClusterID(v
));
176 void writeGML(const char *fileName
, const Layout
&drawing
);
177 void writeGML(const char *fileName
);
178 void writeGML(ostream
&os
, const Layout
&drawing
);
183 //insert boundaries for all given clusters
184 void convertClusterGraph(cluster act
,
185 AdjEntryArray
<edge
>& currentEdge
,
186 AdjEntryArray
<int>& outEdge
);
188 //insert edges to represent the cluster boundary
189 void insertBoundary(cluster C
,
190 AdjEntryArray
<edge
>& currentEdge
,
191 AdjEntryArray
<int>& outEdge
,
194 //reinsert edges to planarize the graph after convertClusterGraph
195 void reinsertEdge(edge e
);
199 const ClusterGraph
*m_pClusterGraph
;
201 edgeType
clusterPattern() { return etcSecCluster
<< etoSecondary
; }
203 adjEntry m_rootAdj
; //connects cluster on highest level with non cluster or
208 EdgeArray
<int> m_edgeClusterID
;
209 NodeArray
<int> m_nodeClusterID
;
210 //we maintain an array of index to cluster mappings (CG is const)
211 //cluster numbers don't need to be consecutive
212 HashArray
<int, cluster
> m_clusterOfIndex
;