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