Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
OrthoRep.h
Go to the documentation of this file.
1
32#pragma once
33
36#include <ogdf/basic/tuples.h>
37
38namespace ogdf {
39
40class OGDF_EXPORT PlanRep;
41class OGDF_EXPORT PlanRepUML;
42
43
44// type for bends (convex or reflex)
45enum class OrthoBendType : char { convexBend = '0', reflexBend = '1' };
46
47// type of (orthogonal) directions
48// horizontal: East or West
49// vertical: North or South
50enum class OrthoDir { North = 0, East = 1, South = 2, West = 3, Undefined = 4 };
51
52// Option bits for orthogonal layouts, UML alignment, compaction scaling, progressive shape computation
53enum class UMLOpt { OpAlign = 0x0001, OpScale = 0x0002, OpProg = 0x0004 };
54
55inline int operator|(int lhs, UMLOpt rhs) { return lhs | static_cast<int>(rhs); }
56
57inline int operator~(UMLOpt rhs) { return ~static_cast<int>(rhs); }
58
59inline int operator&(int lhs, UMLOpt rhs) { return lhs & static_cast<int>(rhs); }
60
61inline int operator+=(int& lhs, UMLOpt rhs) {
62 lhs += static_cast<int>(rhs);
63 return lhs;
64}
65
68public:
69 // constructs empty bend string
71 m_pBend = nullptr;
72 m_len = 0;
73 }
74
75 // constructs bend string as given by str
76 // Precond.: str is a 0 terminated C++ string consisting of '0's and '1's
77 explicit BendString(const char* str) { init(str); }
78
79 // constructs bend string consisting of n c's
80 // Precond.: c is '0' or '1'
81 BendString(char c, size_t n) { init(c, n); }
82
83 // copy constructor
84 BendString(const BendString& bs) { init(bs); }
85
86 // copy constructor (move semantics)
87 BendString(BendString&& bs) : m_pBend(bs.m_pBend), m_len(bs.m_len) {
88 bs.m_pBend = nullptr;
89 bs.m_len = 0;
90 }
91
92 // destructor
93 ~BendString() { delete[] m_pBend; }
94
95 // returns i'th character in bend string
96 char operator[](size_t i) const {
97 // range check
98 OGDF_ASSERT(i < m_len);
99 return m_pBend[i];
100 }
101
102 char& operator[](size_t i) {
103 // range check
104 OGDF_ASSERT(i < m_len);
105 return m_pBend[i];
106 }
107
108 // returns number of characters in bend string
109 size_t size() const { return m_len; }
110
111 // returns a pointer to the 0 terminated string
112 // or a 0-pointer if empty
113 const char* toString() const { return m_pBend; }
114
115 // sets bend string to the string given by str
116 // Precond.: str is a 0 terminated C++ string consisting of '0's and '1's
117 void set(const char* str) {
118 delete[] m_pBend;
119 init(str);
120 }
121
122 // sets bend string to the string consisting of n c's
123 // Precond.: c is '0' or '1'
124 void set(char c, size_t n) {
125 delete[] m_pBend;
126 init(c, n);
127 }
128
129 void set(OrthoBendType obt, size_t n) {
130 delete[] m_pBend;
131 init(static_cast<int>(obt), n);
132 }
133
134 // sets bend string to the empty bend string
135 void set() {
136 delete[] m_pBend;
137 m_pBend = nullptr;
138 m_len = 0;
139 }
140
141 // assignment operator
143 delete[] m_pBend;
144 init(bs);
145 return *this;
146 }
147
148 // assignment operator (move semantics)
150 if (&bs != this) {
151 delete[] m_pBend;
152 m_pBend = bs.m_pBend;
153 m_len = bs.m_len;
154 bs.m_pBend = nullptr;
155 bs.m_len = 0;
156 }
157 return *this;
158 }
159
160 BendString& operator+=(const char* str) { return this->operator+=(BendString(str)); }
161
163 char* temp = new char[m_len + bs.m_len + 1];
164
165 m_len = m_len + bs.m_len;
166
167 if (m_len == 0) {
168 *temp = 0; //temp = 0;
169 } else {
170 char* p = temp;
171 if (m_pBend != nullptr) {
172 const char* str = m_pBend;
173 while ((*p++ = *str++) != 0) {
174 ;
175 }
176 } else {
177 *p = '0';
178 p++;
179 }
180 if (bs.m_len > 0) {
181 p--;
182 const char* str1 = bs.m_pBend;
183 while ((*p++ = *str1++) != 0) {
184 ;
185 }
186 }
187 }
188
189 delete[] m_pBend;
190 m_pBend = temp;
191
192 return *this;
193 }
194
195 // output operator
196 // example output: "001101001" or ""
197 friend std::ostream& operator<<(std::ostream& os, const BendString& bs) {
198 if (bs.size() == 0) {
199 os << "\"\"";
200 } else {
201 os << "\"" << bs.m_pBend << "\"";
202 }
203 return os;
204 }
205
206private:
207 void init(const char* str);
208 void init(char c, size_t n);
209 void init(const BendString& bs);
210
211
212 // poiner to 0 terminated character string
213 char* m_pBend;
214 // length of string (number of characters without ending 0)
215 size_t m_len;
216};
217
220public:
222 struct SideInfoUML {
223 // adjacency entry of generalization attached at the side
224 // (or 0 if none)
226 // number of attached edges which have corresponding edges in the
227 // original graph to the left (index 0) or right of the
228 // attached generalization. If no generalization is attached,
229 // m_nAttached[0] is the total number of attached edges.
230 int m_nAttached[2];
231
232 // constructor
234 m_adjGen = nullptr;
235 m_nAttached[0] = m_nAttached[1] = 0;
236 }
237
238 // returns the total number of edges attached at this side
239 int totalAttached() const {
240 int nGen = (m_adjGen == nullptr) ? 0 : 1;
241 return nGen + m_nAttached[0] + m_nAttached[1];
242 }
243
244 // output operator for debugging
245 friend std::ostream& operator<<(std::ostream& os, const SideInfoUML& si) {
246 os << "{ " << si.m_nAttached[0] << ", " << si.m_adjGen << ", " << si.m_nAttached[1]
247 << " }";
248 return os;
249 }
250 };
251
252 //only for debugging purposes
253 adjEntry externalAdjEntry() const { return m_adjExternal; }
254
255 adjEntry alignAdjEntry() const { return m_adjAlign; }
256
259 // side information (North, East, South, West corresponds to
260 // left, top, right, bottom)
261 SideInfoUML m_side[4];
262 // m_corner[dir] is adjacency entry in direction dir starting at
263 // a corner
264 adjEntry m_corner[4];
265
266 // constructor
268#ifdef OGDF_DEBUG
269 m_corner[0] = m_corner[1] = m_corner[2] = m_corner[3] = nullptr;
270#endif
271 }
272
274 };
275
276 // construction
277
278 // dummy
279 OrthoRep() { m_pE = nullptr; }
280
281 // associates orthogonal representation with embedding E
283
284 // destruction
285 ~OrthoRep() { freeCageInfoUML(); }
286
287 // reinitialization: associates orthogonal representation with embedding E
289
290 //
291 // access functions
292 //
293
294 // returns associated embedding
295 operator const CombinatorialEmbedding&() const { return *m_pE; }
296
297 // returns associated graph
298 operator const Graph&() const { return *m_pE; }
299
300 // returns angle between adj and its successor
301 // (return value is angle divided by 90 degree)
302 int angle(adjEntry adj) const { return m_angle[adj]; }
303
304 int& angle(adjEntry adj) { return m_angle[adj]; }
305
306 // returns bend string of adjacency entry adj
307 const BendString& bend(adjEntry adj) const { return m_bends[adj]; }
308
309 BendString& bend(adjEntry adj) { return m_bends[adj]; }
310
311 // returns direction of adjacency entry
312 OrthoDir direction(adjEntry adj) const { return m_dir[adj]; }
313
314 // returns cage info
315 const VertexInfoUML* cageInfo(node v) const { return m_umlCageInfo[v]; }
316
317 // returns cage info
318 VertexInfoUML* cageInfo(node v) { return m_umlCageInfo[v]; }
319
320 //
321 // update functions
322 //
323
324 // normalizes the orthogonal representation, i.e., sets an artficial
325 // vertex on each bend
326 void normalize();
327
328 // checks if the orth. repr. is normalized, i.e., each bend string is empty
329 bool isNormalized() const;
330
331 // removes rectangular ears (pattern "100") by splitting edges and faces.
332 // Afterwards, each internal face is a rectangle and the external face
333 // contains no rectangular ear (but is not necessarily the complement of
334 // a rectangle).
335 // Precond.: The orth. repr. is normalized and contains no 0-degree angles
336 void dissect();
337 // same as dissect, attempting to save artificial nodes and allow preprocessing
338 void dissect2(PlanRep* PG = nullptr);
339 // variant for use with simple PlanRep
341 // undoes a previous dissect() by removing dissection edges and unsplitting
342 // vertices
343 void undissect(bool align = false);
344
345
346 // assigns consistent directions to adjacency entries
347 void orientate();
348
349 // assigns consistent directions to adj. entries such that most
350 // generalizations are directed in preferedDir
351 void orientate(const PlanRep& PG, OrthoDir preferedDir);
352
353 // assigns consistent directions to adjacency entries,
354 // assigning dir to adj (fixing all others)
356
357 // returns true iff orientate() has been called before.
358 // If not, direction() may not be called since adj. entry array is not
359 // initialized!
360 bool isOrientated() const { return m_dir.valid(); }
361
362 // rotates all directions of adjacency entries by r
363 void rotate(int r);
364
365
366 // computes further information about cages
367 void computeCageInfoUML(const PlanRep& PG /*, double sep*/);
368
369
370 // checks if the orth. repr. is a legal shape description, i.e., if there
371 // is an orthogonal embedding realizing this shape (if 0-degree angles are
372 // present, the condition is necessary but not sufficient).
373 // If false is returned, error contains a description of the reason.
374 bool check(string& error) const;
375
376 //
377 // static members
378 //
379
380 // exchanges '1'->'0' and vice versa
381 static char flip(char c) { return (c == '0') ? '1' : '0'; }
382
385 return static_cast<OrthoDir>((static_cast<int>(d) + 2) & 3);
386 }
387
390 return static_cast<OrthoDir>((static_cast<int>(d) + 1) & 3);
391 }
392
395 return static_cast<OrthoDir>((static_cast<int>(d) + 3) & 3);
396 }
397
398 friend std::ostream& operator<<(std::ostream& os, const OrthoRep& op) {
399 const Graph& E = op;
400 for (edge e : E.edges) {
401 os << e << ": src angle " << op.angle(e->adjSource()) << " bend "
402 << op.bend(e->adjSource()) << "\n"
403 << " tgt angle " << op.angle(e->adjTarget()) << " bend " << op.bend(e->adjTarget())
404
405 << "\n";
406 }
407 return os;
408 }
409
410
411private:
414
415 // associated combinatorial embedding
417
418 // * 90 deg = angle between e and its successor
420 // bends on edge e
422 // direction of adjacency entries
424
425 // information about cages of original vertices; used for orthogonal
426 // representations of PlanRep's
428
429 // The following members are used for undoing dissection
430 EdgeArray<bool> m_dissectionEdge; // = true iff dissection edge
431 //check if special gener. sons alignment edge
432 EdgeArray<bool> m_alignmentEdge; // = true iff alignment edge
433 // contains all nodes created by splitting non-dissection edges while
434 // dissect()
436 // stores adjacency entry on external face for restoring in undissect()
438 // stores adjacency entry on preliminary external face in alignment case
440 //starts dissection phase for special pattern 1 replacement before standard dissection
442 //special pattern after pattern 1
444};
445
446}
declaration and implementation of FaceArray class
Declaration of graph copy classes.
Class for adjacency list elements.
Definition Graph_d.h:79
Dynamic arrays indexed with adjacency entries.
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition ArrayBuffer.h:56
Represents the bends on an edge e consisting of vertical and horizontal segments.
Definition OrthoRep.h:67
const char * toString() const
Definition OrthoRep.h:113
BendString & operator+=(const BendString &bs)
Definition OrthoRep.h:162
BendString & operator+=(const char *str)
Definition OrthoRep.h:160
BendString & operator=(BendString &&bs)
Definition OrthoRep.h:149
BendString(BendString &&bs)
Definition OrthoRep.h:87
void init(const char *str)
char & operator[](size_t i)
Definition OrthoRep.h:102
char operator[](size_t i) const
Definition OrthoRep.h:96
void set(char c, size_t n)
Definition OrthoRep.h:124
BendString & operator=(const BendString &bs)
Definition OrthoRep.h:142
void init(const BendString &bs)
void set(OrthoBendType obt, size_t n)
Definition OrthoRep.h:129
BendString(char c, size_t n)
Definition OrthoRep.h:81
friend std::ostream & operator<<(std::ostream &os, const BendString &bs)
Definition OrthoRep.h:197
void set(const char *str)
Definition OrthoRep.h:117
BendString(const BendString &bs)
Definition OrthoRep.h:84
BendString(const char *str)
Definition OrthoRep.h:77
void init(char c, size_t n)
size_t size() const
Definition OrthoRep.h:109
Combinatorial embeddings of planar graphs with modification functionality.
Dynamic arrays indexed with edges.
Definition EdgeArray.h:125
Class for the representation of edges.
Definition Graph_d.h:300
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:521
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition Graph_d.h:592
Dynamic arrays indexed with nodes.
Definition NodeArray.h:125
Class for the representation of nodes.
Definition Graph_d.h:177
Orthogonal representation of an embedded graph.
Definition OrthoRep.h:219
static OrthoDir oppDir(OrthoDir d)
Returns the opposite OrthoDir.
Definition OrthoRep.h:384
AdjEntryArray< OrthoDir > m_dir
Definition OrthoRep.h:423
adjEntry alignAdjEntry() const
Definition OrthoRep.h:255
OrthoDir direction(adjEntry adj) const
Definition OrthoRep.h:312
NodeArray< VertexInfoUML * > m_umlCageInfo
Definition OrthoRep.h:427
void undissect(bool align=false)
void freeCageInfoUML()
void dissect2(PlanRep *PG=nullptr)
bool m_preprocess
Definition OrthoRep.h:441
friend std::ostream & operator<<(std::ostream &os, const OrthoRep &op)
Definition OrthoRep.h:398
void orientate(const PlanRep &PG, OrthoDir preferedDir)
bool isOrientated() const
Definition OrthoRep.h:360
void init(CombinatorialEmbedding &E)
BendString & bend(adjEntry adj)
Definition OrthoRep.h:309
EdgeArray< bool > m_alignmentEdge
Definition OrthoRep.h:432
void orientate(adjEntry adj, OrthoDir dir)
bool isNormalized() const
adjEntry externalAdjEntry() const
Definition OrthoRep.h:253
const VertexInfoUML * cageInfo(node v) const
Definition OrthoRep.h:315
bool check(string &error) const
VertexInfoUML * cageInfo(node v)
Definition OrthoRep.h:318
AdjEntryArray< int > m_angle
Definition OrthoRep.h:419
void rotate(int r)
static OrthoDir prevDir(OrthoDir d)
Returns the previous OrthoDir (in a clockwise manner)
Definition OrthoRep.h:394
ArrayBuffer< node > m_splitNodes
Definition OrthoRep.h:435
adjEntry m_adjExternal
Definition OrthoRep.h:437
void gridDissect(PlanRep *PG)
const BendString & bend(adjEntry adj) const
Definition OrthoRep.h:307
int angle(adjEntry adj) const
Definition OrthoRep.h:302
static char flip(char c)
Definition OrthoRep.h:381
OrthoRep(CombinatorialEmbedding &E)
static OrthoDir nextDir(OrthoDir d)
Returns the next OrthoDir (in a clockwise manner)
Definition OrthoRep.h:389
void orientateFace(adjEntry adj, OrthoDir dir)
CombinatorialEmbedding * m_pE
Definition OrthoRep.h:416
EdgeArray< bool > m_dissectionEdge
Definition OrthoRep.h:430
void computeCageInfoUML(const PlanRep &PG)
AdjEntryArray< BendString > m_bends
Definition OrthoRep.h:421
int & angle(adjEntry adj)
Definition OrthoRep.h:304
adjEntry m_adjAlign
Definition OrthoRep.h:439
Planarized representations (of a connected component) of a graph.
Definition PlanRep.h:57
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF DLL.
Definition config.h:101
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
#define OGDF_NEW_DELETE
Makes the class use OGDF's memory allocator.
Definition memory.h:84
int r[]
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.
int operator|(int lhs, UMLOpt rhs)
Definition OrthoRep.h:55
OrthoDir
Definition OrthoRep.h:50
UMLOpt
Definition OrthoRep.h:53
int operator+=(int &lhs, UMLOpt rhs)
Definition OrthoRep.h:61
int operator~(UMLOpt rhs)
Definition OrthoRep.h:57
OrthoBendType
Definition OrthoRep.h:45
int operator&(int lhs, UMLOpt rhs)
Definition OrthoRep.h:59
Information about a side of a vertex in UML diagrams.
Definition OrthoRep.h:222
friend std::ostream & operator<<(std::ostream &os, const SideInfoUML &si)
Definition OrthoRep.h:245
Further information about the cages of vertices in UML diagrams.
Definition OrthoRep.h:258
Declaration and implementation of class Tuple2, Tuple3 and Tuple4.