File: TopologyModule.h

package info (click to toggle)
tulip 4.6.0dfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 139,284 kB
  • ctags: 35,942
  • sloc: cpp: 289,758; ansic: 27,264; python: 1,256; sh: 923; yacc: 522; xml: 337; makefile: 258; php: 66; lex: 55
file content (232 lines) | stat: -rw-r--r-- 7,670 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
 * $Revision: 2564 $
 *
 * last checkin:
 *   $Author: gutwenger $
 *   $Date: 2012-07-07 00:03:48 +0200 (Sa, 07. Jul 2012) $
 ***************************************************************/

/** \file
 * \brief Declaration of class TopologyModule.
 *
 * The TopologyModule transports the layout information from
 * GraphAttributes to PlanRep on that Graph, i.e., it computes a
 * combinatorial embedding for the input.
 *
 * \author Karsten Klein
 *
 * \par License:
 * This file is part of the Open Graph Drawing Framework (OGDF).
 *
 * \par
 * Copyright (C)<br>
 * See README.txt in the root directory of the OGDF installation for details.
 *
 * \par
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * Version 2 or 3 as published by the Free Software Foundation;
 * see the file LICENSE.txt included in the packaging of this file
 * for details.
 *
 * \par
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * \par
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * \see  http://www.gnu.org/copyleft/gpl.html
 ***************************************************************/


#ifdef _MSC_VER
#pragma once
#endif


#ifndef OGDF_TOPOLOGYMODULE_H
#define OGDF_TOPOLOGYMODULE_H



#include <ogdf/planarity/PlanRep.h>
#include <ogdf/basic/GraphAttributes.h>
#include <ogdf/basic/EdgeComparer.h>

namespace ogdf {

class EdgeLeg;

//===============================================
//main function(s):
//		setEmbeddingFromGraph(PlanRep&, GraphAttributes&)
//	    assumes that PG(AG) without bend nodes in PG
//
//		sortEdgesFromLayout(GraphAttributes &AG)
//      sort the edges in AG, no crossing insertion
//===============================================

class OGDF_EXPORT TopologyModule
{
public:
	TopologyModule() : m_options(opDegOneCrossings | opGenToAss |
		opCrossFlip | opLoop | opFlipUML) {}
	virtual ~TopologyModule() {}

	//the (pre/post)processing options
	//opCrossFlip increases running time by const*n,
	//opLoop increases running time by const*m
	enum Options {
		opDegOneCrossings = 0x0001, //should degree one node's edge be crossed
		opGenToAss        = 0x0002, //should generalizations be turned into associations
		opCrossFlip       = 0x0004, //if there is a crossing (first ~) between two edges with
									//same start or end point, should there position
									//at the node be flipped and the crossing be skipped?
									//(postprocessing)
		opFlipUML         = 0x0010, //only flip if same edge type
		opLoop            = 0x0008  //should loops between crossings (consecutive on both
									//crossing edges) be deleted (we dont check for enclosed
									//CC's. Therefore it is safe to remove the crossing
	};

	void setOptions(int i) {m_options = i;}
	void addOption(TopologyModule::Options o)  {m_options = (m_options | o);}
	//use AG layout to determine an embedding for PG.
	//non-constness of AG in the following methods is only
	//used when resolving problems, e.g. setting edge types
	//if two generalizations cross in the input layout

	//Parameter setExternal: run over faces to compute external face
	//Parameter reuseAGEmbedding: If true, the call only
	//checks for a correct embedding of PG and tries to insert
	//crossings detected in the given layout otherwise.
	//this allows to assign already sorted UMLGraphs
	//NOTE: if the sorting of the edges does not correspond
	//to the layout given in AG, this cannot work correctly
	//returns false if planarization fails
	bool setEmbeddingFromGraph(
		PlanRep &PG,
		GraphAttributes &AG,
		adjEntry &adjExternal,
		bool setExternal = true,
		bool reuseAGEmbedding = false);

	//sorts the edges around all nodes of AG corresponding to the
	//layout given in AG
	//there is no check of the embedding afterwards because this
	//method could be used as a first step of a planarization
	void sortEdgesFromLayout(Graph &G, GraphAttributes &AG);

	face getExternalFace(PlanRep &PG, const GraphAttributes &AG);

	double faceSum(PlanRep &PG, const GraphAttributes &AG, face f);

protected:
	//compute a planarization, i.e. insert crossing vertices,
	//corresponding to the AG layout
	void planarizeFromLayout(PlanRep &PG,
							 GraphAttributes &AG);
	//compute crossing point and return if existing
	bool hasCrossing(EdgeLeg* legA, EdgeLeg* legB, DPoint& xp);
	//check if node v is a crossing of two edges with a common
	//endpoint adjacent to v, crossing is removed if flip is set
	bool checkFlipCrossing(PlanRep &PG,node v, bool flip = true);

	void postProcess(PlanRep &PG);
	void handleImprecision(PlanRep &PG);
	bool skipable(EdgeLeg* legA, EdgeLeg* legB);

private:
	//compare vectors for sorting
	int compare_vectors(const double& x1, const double& y1,
						const double& x2, const double& y2);
	//compute and return the angle defined by p-q,p-r
	double angle(DPoint p, DPoint q, DPoint r);
	//we have to save the position of the inserted crossing vertices
	//in order to compute the external face
	NodeArray<DPoint> m_crossPosition;

	//we save a list of EdgeLegs for all original edges in
	//AG
	EdgeArray< List<EdgeLeg*> > m_eLegs;


	//option settings as bits
	int m_options;

};//TopologyModule


//sorts EdgeLegs according to their xp distance to a reference point
class PointComparer {
public:
	PointComparer(DPoint refPoint) : m_refPoint(refPoint) {}
	//compares the crossing points stored in the EdgeLeg
	int compare(const ListIterator<EdgeLeg*> &ep1,
		const ListIterator<EdgeLeg*> &ep2) const;
	OGDF_AUGMENT_COMPARER(ListIterator<EdgeLeg*>)

	// undefined methods to avoid automatic creation
	PointComparer &operator=(const PointComparer &);

private:
	const DPoint m_refPoint;
};//PointComparer

//helper class for the computation of crossings
//represents a part of the edge between two consecutive
//bends (in the layout, there are no bends allowed in
//the representation) or crossings
//there can be multiple EdgeLegs associated to one copy
//edge in the PlanRep because of bends
class EdgeLeg
{
public:
	EdgeLeg() : m_topDown(false)
		{m_copyEdge = 0; m_xp = DPoint(0.0, 0.0);}
	EdgeLeg(edge e, int number, DPoint p1, DPoint p2) :
		m_xp(DPoint(0.0,0.0)), m_topDown(false),
		m_copyEdge(e), m_p1(p1), m_p2(p2), m_number(number)
		{}

	DPoint& start() {return m_p1;}
	DPoint& end()   {return m_p2;}
	int& number()    {return m_number;}
	edge& copyEdge() { return m_copyEdge;}

	//to avoid sorting both edgelegs and crossing points,
	//do not store a pair of them, but allow the xp to be
	//stored in the edgeleg
	DPoint m_xp;
	//we store the direction of the crossed EdgeLeg, too
	//if crossingEdgeLeg is horizontally left to right
	bool m_topDown;

	//each edgeLeg holds an entry with a ListIterator pointing to
	//its entry in a <edgeLeg*> List for an original edge
	ListIterator< EdgeLeg* > m_eIterator;

private:
	edge m_copyEdge; //the edge in the PlanRep copy corresponding to the EdgeLeg
	DPoint m_p1, m_p2;  //"Starting" and "End" point of the EdgeLeg
	int    m_number;    //the order nuumber on the edge, starting at 0

};//edgeleg


/*
EdgeArray<ListIterator<edge> > m_eIterator; // position of copy edge in chain

	NodeArray<node> m_vCopy; // corresponding node in graph copy
	EdgeArray<List<edge> > m_eCopy; // corresponding chain of edges in graph copy

*/
} // end namespace ogdf

#endif