1 /** \file
2  * \brief Declaration of class PlanRepInc.
3  *
4  * The PlanRepInc is especially suited for incremental drawing
5  * modes. It derives from GraphObserver and therefore is always
6  * informed about changes of the underlying graph. Keeps the
7  * m_nodesInCC and m_numCC fields up-to-date.
8  *
9  * \author Karsten Klein
10  *
11  * \par License:
12  * This file is part of the Open Graph Drawing Framework (OGDF).
13  *
14  * \par
15  * Copyright (C)<br>
16  * See README.md in the OGDF root directory for details.
17  *
18  * \par
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * Version 2 or 3 as published by the Free Software Foundation;
22  * see the file LICENSE.txt included in the packaging of this file
23  * for details.
24  *
25  * \par
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  * \par
32  * You should have received a copy of the GNU General Public
33  * License along with this program; if not, see
34  * http://www.gnu.org/copyleft/gpl.html
35  */
36 
37 #pragma once
38 
39 #include <ogdf/planarity/PlanRep.h>
40 #include <ogdf/uml/PlanRepUML.h>
41 #include <ogdf/uml/UMLGraph.h>
42 #include <ogdf/basic/GraphAttributes.h>
43 #include <ogdf/basic/GraphObserver.h>
44 #include <ogdf/basic/Array2D.h>
45 
46 
47 namespace ogdf {
48 
49 /**
50  * This class is only an adaption of PlanRep for the special incremental drawing case.
51  *
52  * As incremental layout only makes sense with a given layout, this PlanRepInc copes
53  * with layout information and embedding.
54  */
55 class OGDF_EXPORT PlanRepInc : public PlanRepUML, public GraphObserver
56 {
57 public:
58 	//! Constructor for interactive updates (parts added step by step)
59 	explicit PlanRepInc(const UMLGraph& UG);
60 
61 	//! Constructor for incremental updates (whole graph already given).
62 	//! The part to stay fixed has fixed value set to true
63 	PlanRepInc(const UMLGraph& UG, const NodeArray<bool> &fixed);
64 
65 	//! Inits a CC only with active elements
66 	void initActiveCC(int i);
67 	//! Inits a CC with at least one active node, makes a node active if necessary
68 	//! and returns it. Returns nullptr otherwise.
69 	node initMinActiveCC(int i);
70 
71 	//! In the case that the underlying incremental structure
72 	//! changes, we update this copy.
73 	//! @{
74 	virtual void nodeDeleted(node v) override;
75 	virtual void nodeAdded(node v) override;
76 	virtual void edgeDeleted(edge e) override;
77 	virtual void edgeAdded(edge e) override;
78 	virtual void reInit() override;
79 	virtual void cleared() override;//Graph cleared
80 	//! @}
81 
82 	//! Sets activity status to true and updates the structures.
83 	//! Node activation activates all adjacent edges.
84 	void activateNode(node v);
85 
86 	//! Sets activity status to true and updates the structures.
87 	void activateEdge(edge e);
88 
89 	// TODO: deactivate, too
90 
91 	//! Handles copies of original CCs that are split into
92 	//! unconnected parts of active nodes by connecting them
93 	//! tree-like, adding necessary edges at "external" nodes
94 	//! of the partial CCs. Note that this only makes sense
95 	//! when the CC parts are already correctly embedded.
96 	bool makeTreeConnected(adjEntry adjExternal);
97 
98 	//! Deletes an edge again
99 	//! @{
100 	void deleteTreeConnection(int i, int j);
101 	void deleteTreeConnection(int i, int j, CombinatorialEmbedding &E);
102 	//! @}
103 
104 	//! Sets a list of adjentries on "external" faces of
105 	//! unconnected active parts of the current CC
106 	void getExtAdjs(List<adjEntry> &extAdjs);
107 	adjEntry getExtAdj(GraphCopy &GC, CombinatorialEmbedding &E);
108 
109 	//! Component number
componentNumber(node v)110 	int& componentNumber(node v) {return m_component[v];}
111 
treeEdge(edge e)112 	bool& treeEdge(edge e) {return m_treeEdge[e];}
113 	//only valid if m_eTreeArray initialized, should be replaced later
treeEdge(int i,int j)114 	edge treeEdge(int i, int j) const
115 	{
116 		if (m_treeInit) {
117 			return m_eTreeArray(i, j);
118 		}
119 		return nullptr;
120 	}
treeInit()121 	bool treeInit() {return m_treeInit;}
122 
123 	//! \name Extension of methods defined by GraphCopy/PlanRep
124 	//! @{
125 
126 	//! Splits edge e, can be removed when edge status in edgetype
127 	//! m_treedge can be removed afterwards
split(edge e)128 	virtual edge split(edge e) override {
129 
130 		edge eNew = PlanRepUML::split(e);
131 		if (m_treeEdge[e]) m_treeEdge[eNew] = true;
132 
133 		return eNew;
134 
135 	}
136 
137 	//debug output
138 #ifdef OGDF_DEBUG
writeGML(const char * fileName)139 	void writeGML(const char *fileName)
140 	{
141 		const GraphAttributes &AG = getUMLGraph();
142 		std::ofstream os(fileName);
143 		writeGML(os, AG);//getUMLGraph());//l);
144 	}
writeGML(const char * fileName,const Layout & drawing)145 	void writeGML(const char *fileName, const Layout &drawing)
146 	{
147 		std::ofstream os(fileName);
148 		writeGML(os, drawing);
149 	}
150 
151 	void writeGML(std::ostream &os, const GraphAttributes &AG);
152 	void writeGML(std::ostream &os, const Layout &drawing, bool colorEmbed = true);
153 
154 	//outputs a drawing if genus != 0
155 	int genusLayout(Layout &drawing) const;
156 #endif
157 
158 	//! @}
159 
160 protected:
161 	void initMembers(const UMLGraph &UG);
162 
163 	//! Initializes CC with active nodes (minNode ? at least one node)
164 	node initActiveCCGen(int i, bool minNode);
165 
166 private:
167 	NodeArray<bool> m_activeNodes; //!< stores the status of the nodes
168 	EdgeArray<bool> m_treeEdge; //!< edge inserted for connnectivity
169 	NodeArray<int> m_component; //!< number of partial component in current CC used for treeConnection
170 	Array2D<edge> m_eTreeArray; //!< used for treeConnection
171 	bool m_treeInit; //!< check if the tree edge Array2D was initialized
172 };
173 
174 }
175