1 /** \file
2  * \brief Declaration of a base class for planar representations
3  *        of graphs and cluster graphs.
4  *
5  * \author Karsten Klein, Carsten Gutwenger
6  *
7  * \par License:
8  * This file is part of the Open Graph Drawing Framework (OGDF).
9  *
10  * \par
11  * Copyright (C)<br>
12  * See README.md in the OGDF root directory for details.
13  *
14  * \par
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * Version 2 or 3 as published by the Free Software Foundation;
18  * see the file LICENSE.txt included in the packaging of this file
19  * for details.
20  *
21  * \par
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * \par
28  * You should have received a copy of the GNU General Public
29  * License along with this program; if not, see
30  * http://www.gnu.org/copyleft/gpl.html
31  */
32 
33 
34 // PlanRep should not know about generalizations and association,
35 // but we already set types in Attributedgraph, therefore set them
36 // in PlanRep, too
37 
38 #pragma once
39 
40 #include <ogdf/basic/GraphCopy.h>
41 #include <ogdf/planarity/EdgeTypePatterns.h>
42 #include <ogdf/planarity/NodeTypePatterns.h>
43 #include <ogdf/basic/Layout.h>
44 #include <ogdf/basic/GridLayout.h>
45 
46 
47 namespace ogdf {
48 
49 class OrthoRep;
50 
51 
52 //! Planarized representations (of a connected component) of a graph.
53 /**
54  * @ingroup plan-rep
55  *
56  * Maintains types of edges (generalization, association) and nodes,
57  * and the connected components of the graph.
58  */
59 class OGDF_EXPORT PlanRep : public GraphCopy
60 {
61 public:
62 	//! Information for restoring degree-1 nodes.
63 	struct Deg1RestoreInfo
64 	{
Deg1RestoreInfoDeg1RestoreInfo65 		Deg1RestoreInfo() : m_eOriginal(nullptr), m_deg1Original(nullptr), m_adjRef(nullptr) { }
Deg1RestoreInfoDeg1RestoreInfo66 		Deg1RestoreInfo(edge eOrig, node deg1Orig, adjEntry adjRef)
67 			: m_eOriginal(eOrig), m_deg1Original(deg1Orig), m_adjRef(adjRef) { }
68 
69 		edge m_eOriginal;    //!< the original edge leading to the deg-1 node
70 		node m_deg1Original; //!< the original deg-1 node
71 		adjEntry m_adjRef;   //!< the reference adjacency entry for restoring the edge
72 	};
73 
74 
75 	//@{
76 	//! Creates a planarized representation of graph \p G.
77 	explicit PlanRep(const Graph& G);
78 
79 	//! Creates a planarized representation of graph \p AG.
80 	explicit PlanRep(const GraphAttributes& AG);
81 
~PlanRep()82 	virtual ~PlanRep() { }
83 
84 	//@}
85 
86 	/**
87 	 * @name Processing connected components
88 	 * Planarized representations provide a mechanism for always representing
89 	 * a copy of a single component of the original graph.
90 	 */
91 	//@{
92 
93 	//! Returns the number of connected components in the original graph.
numberOfCCs()94 	int numberOfCCs() const {
95 		return m_ccInfo.numberOfCCs();
96 	}
97 
98 	//! Returns the index of the current connected component (-1 if not yet initialized).
currentCC()99 	int currentCC() const {
100 		return m_currentCC;
101 	}
102 
103 	//! Returns the connected components info structure.
ccInfo()104 	const CCsInfo &ccInfo() const { return m_ccInfo; }
105 
106 	//! Returns the number of nodes in the current connected component.
numberOfNodesInCC()107 	int numberOfNodesInCC() const { return numberOfNodesInCC(m_currentCC); }
108 
109 	//! Returns the number of nodes in connected component \p cc.
numberOfNodesInCC(int cc)110 	int numberOfNodesInCC(int cc) const {
111 		return stopNode(cc) - startNode(cc);
112 	}
113 
114 	//! Returns node \p i in the list of all original nodes.
v(int i)115 	node v(int i) const { return m_ccInfo.v(i); }
116 
117 	//! Returns edge \p i in the list of all original edges.
e(int i)118 	edge e(int i) const { return m_ccInfo.e(i); }
119 
120 	//! Returns the index of the first node in this connected component.
startNode()121 	int startNode() const { return m_ccInfo.startNode(m_currentCC); }
122 
123 	//! Returns the index of the first node in connected component \p cc.
startNode(int cc)124 	int startNode(int cc) const { return m_ccInfo.startNode(cc); }
125 
126 	//! Returns the index of (one past) the last node in this connected component.
stopNode()127 	int stopNode() const { return m_ccInfo.stopNode(m_currentCC); }
128 
129 	//! Returns the index of (one past) the last node in connected component \p cc.
stopNode(int cc)130 	int stopNode(int cc) const { return m_ccInfo.stopNode(cc); }
131 
132 	//! Returns the index of the first edge in this connected component.
startEdge()133 	int startEdge() const { return m_ccInfo.startEdge(m_currentCC); }
134 
135 	//! Returns the index of (one past) the last edge in this connected component.
stopEdge()136 	int stopEdge() const { return m_ccInfo.stopEdge(m_currentCC); }
137 
138 	//! Initializes the planarized representation for connected component \p cc.
139 	/**
140 	 * This initialization is always required. After performing this initialization,
141 	 * the planarized representation represents a copy of the connected
142 	 * component \p cc of the original graph, where connected components are numbered
143 	 * 0,1,2,...
144 	 */
145 	void initCC(int cc);
146 
147 	//@}
148 
149 	/**
150 	 * @name Node expansion
151 	 */
152 	//@{
153 
154 	/**
155 	 * \brief Returns the adjacency entry of a node of an expanded face.
156 	 *
157 	 * If no such entry is stored at node \p v, 0 is returned.
158 	 */
expandAdj(node v)159 	adjEntry expandAdj(node v) const {
160 		return m_expandAdj[v];
161 	}
162 
expandAdj(node v)163 	adjEntry& expandAdj(node v) {
164 		return m_expandAdj[v];
165 	}
166 
167 	//@}
168 	/**
169 	 * @name Clique boundary
170 	 */
171 	//@{
172 
173 	/**
174 	 * Returns the adjacency entry of the first edge of the inserted boundary
175 	 * at a center node (original) of a clique, 0 if no boundary exists
176 	 */
boundaryAdj(node v)177 	adjEntry boundaryAdj(node v) const {
178 		return m_boundaryAdj[v];
179 	}
180 
181 	/**
182 	 * Returns a reference to the adjacency entry of the first edge of the inserted boundary
183 	 * at a center node (original) of a clique, 0 if no boundary exists
184 	 */
boundaryAdj(node v)185 	adjEntry& boundaryAdj(node v){
186 		return m_boundaryAdj[v];
187 	}
188 
189 	//edge on the clique boundary, adjSource
setCliqueBoundary(edge e)190 	void setCliqueBoundary(edge e) {
191 		setEdgeTypeOf(e, edgeTypeOf(e) | cliquePattern());
192 	}
isCliqueBoundary(edge e)193 	bool isCliqueBoundary(edge e) const {
194 		return (edgeTypeOf(e) & cliquePattern()) == cliquePattern();
195 	}
196 
197 
198 	//@}
199 	/**
200 	 * @name Node types
201 	 */
202 	//@{
203 
204 	/**
205 	 * \brief Returns the type of node \p v.
206 	 * @param v is a node in the planarized representation.
207 	 */
typeOf(node v)208 	Graph::NodeType typeOf(node v) const {
209 		return m_vType[v];
210 	}
211 
212 	/**
213 	 * \brief Returns a reference to the type of node \p v.
214 	 * @param v is a node in the planarized representation.
215 	 */
typeOf(node v)216 	Graph::NodeType& typeOf(node v) {
217 		return m_vType[v];
218 	}
219 
220 	/**
221 	 * \brief Returns true if the node represents a "real" object in the original graph.
222 	 *
223 	 * \todo It is necessary to check for several different possible types.
224 	 * This should be solved by combining representation types (vertex, dummy,...)
225 	 * with semantic types (class, interface,...) within GraphAttributes;
226 	 * we then can return to vertex only.
227 	 */
isVertex(node v)228 	inline bool isVertex(node v) const
229 	{
230 		return typeOf(v) == Graph::NodeType::vertex
231 		    || typeOf(v) == Graph::NodeType::associationClass;
232 	}
233 
234 	/**
235 	 * \brief Returns the extended node type of \p v.
236 	 * @param v is a node in the planarized representation.
237 	 */
nodeTypeOf(node v)238 	nodeType nodeTypeOf(node v)
239 	{
240 		return m_nodeTypes[v];
241 	}
242 
243 	/**
244 	 * \brief Classifies node \p v as a crossing.
245 	 * @param v is a node in the planarized representation.
246 	 */
setCrossingType(node v)247 	void setCrossingType(node v)
248 	{
249 		m_nodeTypes[v] |= UMLNodeTypeConstants::TerCrossing << UMLNodeTypeOffsets::Tertiary;
250 	}
251 
252 	/**
253 	 * \brief Returns true iff node \p v is classified as a crossing.
254 	 * @param v is a node in the planarized representation.
255 	 */
isCrossingType(node v)256 	bool isCrossingType(node v) const
257 	{
258 		return (m_nodeTypes[v] & (UMLNodeTypeConstants::TerCrossing << UMLNodeTypeOffsets::Tertiary)) != 0;
259 	}
260 
261 	//@}
262 	/**
263 	 * @name Edge types
264 	 */
265 	//@{
266 
267 	/**
268 	 * \brief Returns the type of edge \p e.
269 	 * @param e is an edge in the planarized representation.
270 	 */
typeOf(edge e)271 	EdgeType typeOf(edge e) const {
272 		return m_eType[e];
273 	}
274 
275 	/**
276 	 * \brief Returns a reference to the type of edge \p e.
277 	 * @param e is an edge in the planarized representation.
278 	 */
typeOf(edge e)279 	EdgeType& typeOf(edge e) {
280 		return m_eType[e];
281 	}
282 
283 	/**
284 	 * \brief Returns a reference to the type of original edge \p e.
285 	 * @param e is an edge in the original graph.
286 	 */
oriEdgeTypes(edge e)287 	edgeType& oriEdgeTypes(edge e)
288 	{
289 		return m_oriEdgeTypes[e];
290 	}
291 
292 	/**
293 	 * \brief Returns the new type field of \p e.
294 	 * @param e is an edge in the planarized representation.
295 	 */
edgeTypeOf(edge e)296 	edgeType edgeTypeOf(edge e) const
297 	{
298 		return m_edgeTypes[e];
299 	}
300 
301 	/**
302 	 * \brief Returns a reference to the new type field of \p e.
303 	 * @param e is an edge in the planarized representation.
304 	 */
edgeTypes(edge e)305 	edgeType& edgeTypes(edge e)
306 	{
307 		return m_edgeTypes[e];
308 	}
309 
310 	/**
311 	 * \brief Sets the new type field of edge \p e to \p et.
312 	 * @param e is an edge in the planarized representation.
313 	 * @param et is the type assigned to \p e.
314 	 */
setEdgeTypeOf(edge e,edgeType et)315 	void setEdgeTypeOf(edge e, edgeType et)
316 	{
317 		m_edgeTypes[e] = et;
318 	}
319 
320 	/**
321 	 * \brief Set both type values of \p e at once.
322 	 *
323 	 * This is a temporary solution that sets both type values; this way, all
324 	 * additional edge types in the new field are lost.
325 	 * @param e is an edge in the planarized representation.
326 	 * @param et is the type assigned to \p e.
327 	 */
setType(edge e,EdgeType et)328 	void setType(edge e, EdgeType et)
329 	{
330 		m_eType[e] = et;
331 		switch (et)
332 		{
333 			case Graph::EdgeType::association: m_edgeTypes[e] = static_cast<edgeType>(UMLEdgeTypeConstants::PrimAssociation);break;
334 			case Graph::EdgeType::generalization: m_edgeTypes[e] = static_cast<edgeType>(UMLEdgeTypeConstants::PrimGeneralization);
335 				break;
336 			case Graph::EdgeType::dependency: m_edgeTypes[e] = static_cast<edgeType>(UMLEdgeTypeConstants::PrimDependency); break;
337 			default: break;
338 		}
339 	}
340 
341 	// new edge types
342 	// to set or check edge types use the pattern function in the private section
343 
344 	// primary level types
345 
346 	//! Returns true iff edge \p e is classified as generalization.
isGeneralization(edge e)347 	bool isGeneralization(edge e) const {
348 		bool check = (((m_edgeTypes[e] & UMLEdgeTypePatterns::Primary) & UMLEdgeTypeConstants::PrimGeneralization) == UMLEdgeTypeConstants::PrimGeneralization);
349 		return check;
350 	}
351 
352 	//! Classifies edge \p e as generalization (primary type).
setGeneralization(edge e)353 	void setGeneralization(edge e) {
354 		setPrimaryType(e, UMLEdgeTypeConstants::PrimGeneralization);
355 
356 		//preliminary set old array too
357 		m_eType[e] = EdgeType::generalization; //can be removed if edgetypes work properly
358 	}
359 
360 	//! Returns true iff edge \p e is classified as dependency.
isDependency(edge e)361 	bool isDependency(edge e) const {
362 		bool check = (((m_edgeTypes[e] & UMLEdgeTypePatterns::Primary) & UMLEdgeTypeConstants::PrimDependency) == UMLEdgeTypeConstants::PrimDependency);
363 		return check;
364 	}
365 
366 	//! Classifies edge \p e as dependency (primary type).
setDependency(edge e)367 	void setDependency(edge e) {
368 		setPrimaryType(e, UMLEdgeTypeConstants::PrimDependency);
369 
370 		//preliminary set old array too
371 		m_eType[e] = EdgeType::dependency; //can be removed if edgetypes work properly
372 	}
373 
374 	//! Classifies edge \p e as association (primary type).
setAssociation(edge e)375 	void setAssociation(edge e) {
376 		setPrimaryType(e, UMLEdgeTypeConstants::PrimAssociation);
377 
378 		//preliminary set old array too
379 		m_eType[e] = EdgeType::association; //can be removed if edgetypes work properly
380 	}
381 
382 	//second level types
383 
384 	//in contrast to setsecondarytype: do not delete old value
385 
386 	//! Classifies edge \p e as expansion edge (secondary type).
setExpansion(edge e)387 	void setExpansion(edge e) {
388 		m_edgeTypes[e] |= expansionPattern();
389 
390 		//preliminary set old array too
391 		m_expansionEdge[e] = 1;//can be removed if edgetypes work properly
392 	}
393 
394 	//! Returns true iff edge \p e is classified as expansion edge.
isExpansion(edge e)395 	bool isExpansion(edge e) const {
396 		return (m_edgeTypes[e] & expansionPattern()) == expansionPattern();
397 	}
398 
399 	//should add things like cluster and clique boundaries that need rectangle shape
400 
401 	//! Returns true iff edge \p e is a clique boundary.
isBoundary(edge e)402 	bool isBoundary(edge e) const {
403 		return isCliqueBoundary(e);
404 	}
405 
406 	//tertiary types
407 
408 	//! Classifies edge \p e as connection at an association class (tertiary type).
setAssClass(edge e)409 	void setAssClass(edge e)
410 	{
411 		m_edgeTypes[e] |= assClassPattern();
412 	}
413 
414 	//! Returns true iff edge \p e is classified as connection at an association class.
isAssClass(edge e)415 	bool isAssClass(edge e) const
416 	{
417 		return (m_edgeTypes[e] & assClassPattern()) == assClassPattern();
418 	}
419 
420 	//fourth level types
421 
422 	//! Classifies edge \p e as connection between hierarchy neighbours (fourth level type).
setBrother(edge e)423 	void setBrother(edge e) {
424 		m_edgeTypes[e] |= brotherPattern();
425 	}
426 
427 	//! Classifies edge \p e as connection between ...  (fourth level type).
setHalfBrother(edge e)428 	void setHalfBrother(edge e) {
429 		m_edgeTypes[e] |= halfBrotherPattern();
430 	}
431 
432 	//! Returns true if edge \p e is classified as brother.
isBrother(edge e)433 	bool isBrother(edge e) const {
434 		return ( (m_edgeTypes[e] & UMLEdgeTypePatterns::Fourth & brotherPattern()) >> UMLEdgeTypeOffsets::Fourth) == UMLEdgeTypeConstants::Brother;
435 	}
436 
437 	//! Returns true if edge \p e is classified as half-brother.
isHalfBrother(edge e)438 	bool isHalfBrother(edge e) const {
439 		return ( (m_edgeTypes[e] & UMLEdgeTypePatterns::Fourth & halfBrotherPattern()) >> UMLEdgeTypeOffsets::Fourth) == UMLEdgeTypeConstants::HalfBrother;
440 	}
441 
442 	//set generic types
443 
444 	//! Sets type of edge \p e to current type (bitwise) AND \p et.
edgeTypeAND(edge e,edgeType et)445 	edgeType edgeTypeAND(edge e, edgeType et) {m_edgeTypes[e] &= et; return m_edgeTypes[e];}
446 
447 	//! Sets type of edge \p e to current type (bitwise) OR \p et.
edgeTypeOR(edge e,edgeType et)448 	edgeType edgeTypeOR(edge e, edgeType et) {m_edgeTypes[e] |= et; return m_edgeTypes[e];}
449 
450 	//! Sets primary edge type of edge \p e to primary edge type in \p et (deletes old primary value).
setPrimaryType(edge e,edgeType et)451 	void setPrimaryType(edge e, edgeType et) {
452 		m_edgeTypes[e] &= 0xfffffff0;
453 		m_edgeTypes[e] |= (UMLEdgeTypePatterns::Primary & et);
454 	}
455 
456 	//! Sets primary edge type of edge \p e to primary edge type in \p et (deletes old primary value).
setPrimaryType(edge e,UMLEdgeTypeConstants et)457 	void setPrimaryType(edge e, UMLEdgeTypeConstants et) {
458 		setPrimaryType(e, static_cast<edgeType>(et));
459 	}
460 
461 	//! Sets secondary edge type of edge \p e to primary edge type in \p et.
setSecondaryType(edge e,edgeType et)462 	void setSecondaryType(edge e, edgeType et) {
463 		m_edgeTypes[e] &= 0xffffff0f;
464 		m_edgeTypes[e] |= (UMLEdgeTypePatterns::Secondary & ( et << UMLEdgeTypeOffsets::Secondary));
465 	}
466 
467 	//! Sets primary type of \p e to bitwise AND of \p et's primary value and old value.
edgeTypePrimaryAND(edge e,edgeType et)468 	edgeType edgeTypePrimaryAND(edge e, edgeType et) {m_edgeTypes[e] &= (UMLEdgeTypePatterns::All & et); return m_edgeTypes[e];}
469 
470 	//! Sets primary type of \p e to bitwise OR of \p et's primary value and old value.
edgeTypePrimaryOR(edge e,edgeType et)471 	edgeType edgeTypePrimaryOR(edge e, edgeType et) {m_edgeTypes[e] |= et; return m_edgeTypes[e];}
472 
473 	//! Sets user defined type locally.
setUserType(edge e,edgeType et)474 	void setUserType(edge e, edgeType et)
475 	{
476 		OGDF_ASSERT( et < 147);
477 		m_edgeTypes[e] |= (et << UMLEdgeTypeOffsets::User);
478 	}
479 
480 	//! Returns user defined type.
isUserType(edge e,edgeType et)481 	bool isUserType(edge e, edgeType et) const
482 	{
483 		OGDF_ASSERT( et < 147);
484 		return (m_edgeTypes[e] & (et << UMLEdgeTypeOffsets::User)) == (et << UMLEdgeTypeOffsets::User);
485 	}
486 
487 	// old edge types
488 
489 	//this is pure nonsense, cause we have uml-edgetype and m_etype, and should be able to
490 	//use them with different types, but as long as they arent used correctly (switch instead of xor),
491 	//use this function to return if e is expansionedge
492 	//if it is implemented correctly later, delete the array and return m_etype == Graph::expand
493 	//(the whole function then is obsolete, cause you can check it directly, but for convenience...)
494 	//should use genexpand, nodeexpand, dissect instead of bool
495 
496 	//! Sets the expansion edge type of \p e to \p expType.
setExpansionEdge(edge e,int expType)497 	void setExpansionEdge(edge e, int expType) {
498 		m_expansionEdge[e] = expType;
499 	}
500 
501 	//! Returns if \p e is an expansion edge.
isExpansionEdge(edge e)502 	bool isExpansionEdge(edge e) const {
503 		return m_expansionEdge[e] > 0;
504 	}
505 
506 	//! Returns the expansion edge type of \p e.
expansionType(edge e)507 	int expansionType(edge e) const { return m_expansionEdge[e]; }
508 
509 	//precondition normalized
510 	//! Returns if \p e is a degree expansion edge.
isDegreeExpansionEdge(edge e)511 	bool isDegreeExpansionEdge(edge e) const {
512 #if 0
513 		return (m_eType[e] == Graph::expand);
514 #else
515 		return m_expansionEdge[e]  == 2;
516 #endif
517 	}
518 
519 
520 	//@}
521 	/**
522 	 * @name Access to attributes in original graph
523 	 * These methods provide easy access to attributes of original nodes and
524 	 * edges.
525 	 */
526 	//@{
527 
528 
529 	//! Gives access to the node array of the widths of original nodes.
widthOrig()530 	const NodeArray<double> &widthOrig() const {
531 		OGDF_ASSERT(m_pGraphAttributes != nullptr);
532 		return m_pGraphAttributes->width();
533 	}
534 
535 	//! Returns the width of original node \p v.
widthOrig(node v)536 	double widthOrig(node v) const {
537 		OGDF_ASSERT(m_pGraphAttributes != nullptr);
538 		return m_pGraphAttributes->width(v);
539 	}
540 
541 	//! Gives access to the node array of the heights of original nodes.
heightOrig()542 	const NodeArray<double> &heightOrig() const {
543 		OGDF_ASSERT(m_pGraphAttributes != nullptr);
544 		return m_pGraphAttributes->height();
545 	}
546 
547 	//! Returns the height of original node \p v.
heightOrig(node v)548 	double heightOrig(node v) const {
549 		OGDF_ASSERT(m_pGraphAttributes != nullptr);
550 		return m_pGraphAttributes->height(v);
551 	}
552 
553 	//! Returns the type of original edge \p e.
typeOrig(edge e)554 	EdgeType typeOrig(edge e) const {
555 		OGDF_ASSERT(m_pGraphAttributes != nullptr);
556 		return m_pGraphAttributes->type(e);
557 	}
558 
559 	//! Returns the graph attributes of the original graph (the pointer may be 0).
getGraphAttributes()560 	const GraphAttributes &getGraphAttributes() const {
561 		OGDF_ASSERT(m_pGraphAttributes != nullptr);
562 		return *m_pGraphAttributes;
563 	}
564 
565 	//@}
566 	/**
567 	 * @name Structural alterations
568 	 */
569 	//@{
570 
571 	// Expands nodes with degree > 4 and merge nodes for generalizations
572 	virtual void expand(bool lowDegreeExpand = false);
573 
574 	void expandLowDegreeVertices(OrthoRep &OR);
575 
576 	void collapseVertices(const OrthoRep &OR, Layout &drawing);
577 	void collapseVertices(const OrthoRep &OR, GridLayout &drawing);
578 
579 	void removeCrossing(node v); //removes the crossing at node v
580 
581 	//model a boundary around a star subgraph centered at center
582 	//and keep external face information (outside the clique
583 	void insertBoundary(node center, adjEntry& adjExternal);
584 
585 
586 	//@}
587 	/**
588 	 * @name Extension of methods defined by GraphCopys
589 	 */
590 	//@{
591 
592 	//! Splits edge \p e.
593 	virtual edge split(edge e) override;
594 
595 
596 	//returns node which was expanded using v
expandedNode(node v)597 	node expandedNode(node v) const { return m_expandedNode[v]; }
598 
setExpandedNode(node v,node w)599 	void setExpandedNode(node v, node w) { m_expandedNode[v] = w; }
600 
601 
602 	//@}
603 	/**
604 	 * @name Creation of new nodes and edges
605 	 */
606 	//@{
607 
608 	/**
609 	 * \brief Creates a new node with node type \p vType in the planarized representation.
610 	 * @param vOrig becomes the original node of the new node.
611 	 * @param vType becomes the type of the new node.
612 	 */
613 	node newCopy(node vOrig, Graph::NodeType vType);
614 
615 	/**
616 	 * \brief Creates a new edge in the planarized representation.
617 	 * @param v is the source node of the new edge.
618 	 * @param adjAfter is the adjacency entry at the target node, after which the
619 	 *        new edge is inserted.
620 	 * @param eOrig becomes the original edge of the new edge.
621 	 */
622 	edge newCopy(node v, adjEntry adjAfter, edge eOrig);
623 
624 	/**
625 	 * \brief Creates a new edge in the planarized representation while updating the embedding \p E.
626 	 * @param v is the source node of the new edge.
627 	 * @param adjAfter is the adjacency entry at the target node, after which the
628 	 *        new edge is inserted.
629 	 * @param eOrig becomes the original edge of the new edge.
630 	 * @param E is an embedding of the planarized representation.
631 	 */
632 	edge newCopy(node v, adjEntry adjAfter, edge eOrig, CombinatorialEmbedding &E);
633 
634 
635 	//@}
636 	/**
637 	 * @name Crossings
638 	 */
639 	//@{
640 
641 	//! Re-inserts edge \p eOrig by "crossing" the edges in \p crossedEdges.
642 	/**
643 	 * Splits each edge in crossedEdges.
644 	 *
645 	 * \pre \p eOrig is an edge in the original graph and the edges in \p crossedEdges are in this graph.
646 	 */
647 	void insertEdgePath(edge eOrig, const SList<adjEntry> &crossedEdges);
648 
649 	//! Same as insertEdgePath, but for embedded graphs.
650 	void insertEdgePathEmbedded(
651 		edge eOrig,
652 		CombinatorialEmbedding &E,
653 		const SList<adjEntry> &crossedEdges);
654 
655 	//! Removes the complete edge path for edge \p eOrig while preserving the embedding.
656 	/**
657 	 * \pre \p eOrig s an edge in the original graph.
658 	 */
removeEdgePathEmbedded(CombinatorialEmbedding & E,edge eOrig,FaceSet<false> & newFaces)659 	void removeEdgePathEmbedded(CombinatorialEmbedding &E,
660 		edge eOrig,
661 		FaceSet<false> &newFaces) {
662 		GraphCopy::removeEdgePathEmbedded(E,eOrig,newFaces);
663 	}
664 
665 	//! Inserts crossings between two copy edges.
666 	/**
667 	 * This method is used in TopologyModule.
668 	 *
669 	 * Let \p crossingEdge = (\a a, \a b) and \p crossedEdge = (\a v, \a w).
670 	 * Then \p crossedEdge is split creating two edges \p crossedEdge = (\a v, \a u)
671 	 * and (\a u, \a w), \p crossingEdge is removed and replaced by two new edges
672 	 * \a e1  = (\a a, \a u) and \a e1 = (\a u, \a b).
673 	 * Finally it sets \p crossingEdge to \a e2 and returns (\a u, \a w).
674 	 *
675 	 * @param crossingEdge is the edge that gets split.
676 	 * @param crossedEdge is the edge that is replaced by two new edges.
677 	 * @param topDown is used as follows: If set to true, \p crossingEdge will cross
678 	 *        \p crossedEdge from right to left, otherwise from left to right.
679 	*/
680 	edge insertCrossing(
681 		edge &crossingEdge,
682 		edge crossedEdge,
683 		bool topDown);
684 
685 	//@}
686 	/**
687 	 * @name Degree-1 nodes
688 	 * These methods realize a mechanism for temporarily removing degree-1 nodes.
689 	 */
690 	//@{
691 
692 	/**
693 	 * \brief Removes all marked degree-1 nodes from the graph copy and stores restore information in \p S.
694 	 * @param S returns the restore information required by restoreDeg1Nodes().
695 	 * @param mark defines which nodes are marked for removal; all nodes \a v with
696 	 *        <I>mark</I>[<I>a</I>]=<B>true</B> are removed.
697 	 * \pre Only nodes with degree 1 may be marked.
698 	 */
699 	void removeDeg1Nodes(ArrayBuffer<Deg1RestoreInfo> &S, const NodeArray<bool> &mark);
700 
701 	/**
702 	 * \brief Restores degree-1 nodes previously removed with removeDeg1Nodes().
703 	 * @param S contains the restore information.
704 	 * @param deg1s returns the list of newly created nodes in the copy.
705 	 */
706 	void restoreDeg1Nodes(ArrayBuffer<Deg1RestoreInfo> &S, List<node> &deg1s);
707 
708 	//@}
709 	void writeGML(const char *fileName, const OrthoRep &OR, const GridLayout &drawing);
710 	void writeGML(std::ostream &os, const OrthoRep &OR, const GridLayout &drawing);
711 
712 protected:
713 
714 	int m_currentCC; //!< The index of the current component.
715 	Graph::CCsInfo m_ccInfo;
716 	//int m_numCC;     //!< The number of components in the original graph.
717 
718 	//Array<List<node> >  m_nodesInCC; //!< The list of original nodes in each component.
719 
720 	const GraphAttributes* m_pGraphAttributes; //!< Pointer to graph attributes of original graph.
721 
722 	// object types
723 
724 	//set the type of eCopy according to the type of eOrig
725 	//should be virtual if PlanRepUML gets its own
726 	void setCopyType(edge eCopy, edge eOrig);
727 
728 	//helper to cope with the edge types, shifting to the right place
generalizationPattern()729 	edgeType generalizationPattern() const {return static_cast<edgeType>(UMLEdgeTypeConstants::PrimGeneralization);}
associationPattern()730 	edgeType associationPattern() const    {return static_cast<edgeType>(UMLEdgeTypeConstants::PrimAssociation);}
expansionPattern()731 	edgeType expansionPattern() const      {return UMLEdgeTypeConstants::SecExpansion << UMLEdgeTypeOffsets::Secondary;}
assClassPattern()732 	edgeType assClassPattern() const       {return UMLEdgeTypeConstants::AssClass << UMLEdgeTypeOffsets::Tertiary;}
brotherPattern()733 	edgeType brotherPattern() const        {return UMLEdgeTypeConstants::Brother << UMLEdgeTypeOffsets::Fourth;}
halfBrotherPattern()734 	edgeType halfBrotherPattern() const    {return UMLEdgeTypeConstants::HalfBrother << UMLEdgeTypeOffsets::Fourth;}
cliquePattern()735 	edgeType cliquePattern() const         {return UMLEdgeTypeConstants::SecClique << UMLEdgeTypeOffsets::Secondary;} //boundary
736 
737 	NodeArray<NodeType> m_vType; //!< Simple node types.
738 
739 	NodeArray<nodeType> m_nodeTypes; //!< Node types for extended semantic information.
740 
741 	NodeArray<node>     m_expandedNode; //!< For all expansion nodes, save expanded node.
742 	NodeArray<adjEntry> m_expandAdj;
743 
744 	//clique handling: We save an adjEntry of the first edge of an inserted
745 	//boundary around a clique at its center v
746 	NodeArray<adjEntry> m_boundaryAdj;
747 
748 	//zusammenlegbare Typen
749 	EdgeArray<int>      m_expansionEdge; //1 genmerge, 2 degree (2 highdegree, 3 lowdegree)
750 	EdgeArray<EdgeType> m_eType;
751 
752 	//m_edgeTypes stores semantic edge type information on several levels:
753 	//primary type: generalization, association,...
754 	//secondary type: merger,...
755 	//tertiary type: vertical in hierarchy, inner, outer, ...
756 	//fourth type: neighbour relation (brother, cousin in hierarchy)
757 	//user types: user defined for local changes
758 	EdgeArray<edgeType> m_edgeTypes; //store all type information
759 
760 	//workaround fuer typsuche in insertedgepathembed
761 	//speichere kopietyp auf originalen
762 	//maybe it's enough to set gen/ass without extra array
763 	EdgeArray<edgeType> m_oriEdgeTypes;
764 
765 	EdgeArray<edge>     m_eAuxCopy; // auxiliary (GraphCopy::initByNodes())
766 };
767 
768 }
769