Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

OrthoRep.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/ArrayBuffer.h>
36 #include <ogdf/basic/Graph.h>
37 #include <ogdf/basic/GraphList.h>
38 #include <ogdf/basic/basic.h>
39 #include <ogdf/basic/memory.h>
40 
41 #include <cstddef>
42 #include <ostream>
43 #include <string>
44 
45 namespace ogdf {
46 
47 class OGDF_EXPORT PlanRep;
48 
49 
50 // type for bends (convex or reflex)
51 enum class OrthoBendType : char { convexBend = '0', reflexBend = '1' };
52 
53 // type of (orthogonal) directions
54 // horizontal: East or West
55 // vertical: North or South
56 enum 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
59 enum class UMLOpt { OpAlign = 0x0001, OpScale = 0x0002, OpProg = 0x0004 };
60 
61 inline int operator|(int lhs, UMLOpt rhs) { return lhs | static_cast<int>(rhs); }
62 
63 inline int operator~(UMLOpt rhs) { return ~static_cast<int>(rhs); }
64 
65 inline int operator&(int lhs, UMLOpt rhs) { return lhs & static_cast<int>(rhs); }
66 
67 inline int operator+=(int& lhs, UMLOpt rhs) {
68  lhs += static_cast<int>(rhs);
69  return lhs;
70 }
71 
74 public:
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 
212 private:
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 
226 public:
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 
264  struct VertexInfoUML {
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
288  explicit OrthoRep(CombinatorialEmbedding& E);
289 
290  // destruction
291  ~OrthoRep() { freeCageInfoUML(); }
292 
293  // reinitialization: associates orthogonal representation with embedding E
294  void init(CombinatorialEmbedding& 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
346  void gridDissect(PlanRep* PG);
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)
361  void orientate(adjEntry adj, OrthoDir dir);
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 
417 private:
418  void orientateFace(adjEntry adj, OrthoDir dir);
419  void freeCageInfoUML();
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 }
ogdf::ArrayBuffer
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition: Array.h:53
ogdf::OrthoRep::m_adjAlign
adjEntry m_adjAlign
Definition: OrthoRep.h:445
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ArrayBuffer.h
Declaration and implementation of ArrayBuffer class.
Graph.h
Includes declaration of graph class.
ogdf::BendString::BendString
BendString(const BendString &bs)
Definition: OrthoRep.h:90
ogdf::OrthoRep::m_dir
AdjEntryArray< OrthoDir > m_dir
Definition: OrthoRep.h:429
ogdf::OrthoRep::m_umlCageInfo
NodeArray< VertexInfoUML * > m_umlCageInfo
Definition: OrthoRep.h:433
ogdf::PlanRep
Planarized representations (of a connected component) of a graph.
Definition: PlanRep.h:69
ogdf::OrthoRep::angle
int & angle(adjEntry adj)
Definition: OrthoRep.h:310
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::BendString::BendString
BendString()
Definition: OrthoRep.h:76
ogdf::OrthoRep::VertexInfoUML
Further information about the cages of vertices in UML diagrams.
Definition: OrthoRep.h:264
ogdf::OrthoRep::angle
int angle(adjEntry adj) const
Definition: OrthoRep.h:308
ogdf::OrthoDir
OrthoDir
Definition: OrthoRep.h:56
ogdf::operator+=
int operator+=(int &lhs, UMLOpt rhs)
Definition: OrthoRep.h:67
ogdf::OrthoRep::cageInfo
VertexInfoUML * cageInfo(node v)
Definition: OrthoRep.h:324
ogdf::BendString::BendString
BendString(const char *str)
Definition: OrthoRep.h:83
ogdf::BendString::m_pBend
char * m_pBend
Definition: OrthoRep.h:219
ogdf::OrthoDir::West
@ West
ogdf::OrthoRep::SideInfoUML::m_adjGen
adjEntry m_adjGen
Definition: OrthoRep.h:231
ogdf::BendString
Represents the bends on an edge e consisting of vertical and horizontal segments.
Definition: OrthoRep.h:73
ogdf::BendString::operator=
BendString & operator=(const BendString &bs)
Definition: OrthoRep.h:148
ogdf::OrthoRep::m_alignmentEdge
EdgeArray< bool > m_alignmentEdge
Definition: OrthoRep.h:438
ogdf::OrthoRep::SideInfoUML
Information about a side of a vertex in UML diagrams.
Definition: OrthoRep.h:228
ogdf::BendString::size
size_t size() const
Definition: OrthoRep.h:115
ogdf::OrthoDir::South
@ South
ogdf::OrthoBendType::convexBend
@ convexBend
ogdf::operator&
int operator&(int lhs, UMLOpt rhs)
Definition: OrthoRep.h:65
ogdf::OrthoRep::m_pE
CombinatorialEmbedding * m_pE
Definition: OrthoRep.h:422
ogdf::BendString::operator+=
BendString & operator+=(const char *str)
Definition: OrthoRep.h:166
ogdf::OrthoRep::m_dissectionEdge
EdgeArray< bool > m_dissectionEdge
Definition: OrthoRep.h:436
OGDF_NEW_DELETE
#define OGDF_NEW_DELETE
Makes the class use OGDF's memory allocator.
Definition: memory.h:85
ogdf::OrthoDir::Undefined
@ Undefined
ogdf::operator~
int operator~(UMLOpt rhs)
Definition: OrthoRep.h:63
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:142
ogdf::BendString::set
void set()
Definition: OrthoRep.h:141
ogdf::BendString::set
void set(const char *str)
Definition: OrthoRep.h:123
ogdf::BendString::operator+=
BendString & operator+=(const BendString &bs)
Definition: OrthoRep.h:168
ogdf::BendString::operator[]
char & operator[](size_t i)
Definition: OrthoRep.h:108
ogdf::BendString::set
void set(OrthoBendType obt, size_t n)
Definition: OrthoRep.h:135
ogdf::OrthoRep::flip
static char flip(char c)
Definition: OrthoRep.h:387
ogdf::BendString::~BendString
~BendString()
Definition: OrthoRep.h:99
r
int r[]
Definition: hierarchical-ranking.cpp:13
ogdf::OrthoBendType::reflexBend
@ reflexBend
ogdf::OrthoRep::m_splitNodes
ArrayBuffer< node > m_splitNodes
Definition: OrthoRep.h:441
ogdf::OrthoRep
Orthogonal representation of an embedded graph.
Definition: OrthoRep.h:225
ogdf::OrthoRep::SideInfoUML::SideInfoUML
SideInfoUML()
Definition: OrthoRep.h:239
GraphList.h
Decralation of GraphElement and GraphList classes.
ogdf::UMLOpt::OpAlign
@ OpAlign
ogdf::OrthoRep::m_bends
AdjEntryArray< BendString > m_bends
Definition: OrthoRep.h:427
ogdf::OrthoBendType
OrthoBendType
Definition: OrthoRep.h:51
ogdf::OrthoRep::nextDir
static OrthoDir nextDir(OrthoDir d)
Returns the next OrthoDir (in a clockwise manner)
Definition: OrthoRep.h:395
ogdf::OrthoRep::cageInfo
const VertexInfoUML * cageInfo(node v) const
Definition: OrthoRep.h:321
ogdf::OrthoRep::SideInfoUML::m_nAttached
int m_nAttached[2]
Definition: OrthoRep.h:236
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:658
ogdf::EdgeElement::adjSource
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
Definition: Graph_d.h:407
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:869
ogdf::OrthoRep::alignAdjEntry
adjEntry alignAdjEntry() const
Definition: OrthoRep.h:261
ogdf::BendString::BendString
BendString(char c, size_t n)
Definition: OrthoRep.h:87
ogdf::OrthoRep::m_pattern2
bool m_pattern2
Definition: OrthoRep.h:449
ogdf::OrthoRep::bend
BendString & bend(adjEntry adj)
Definition: OrthoRep.h:315
ogdf::OrthoRep::oppDir
static OrthoDir oppDir(OrthoDir d)
Returns the opposite OrthoDir.
Definition: OrthoRep.h:390
ogdf::BendString::operator[]
char operator[](size_t i) const
Definition: OrthoRep.h:102
ogdf::OrthoRep::~OrthoRep
~OrthoRep()
Definition: OrthoRep.h:291
ogdf::BendString::toString
const char * toString() const
Definition: OrthoRep.h:119
ogdf::EdgeElement::adjTarget
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Definition: Graph_d.h:410
ogdf::OrthoRep::VertexInfoUML::VertexInfoUML
VertexInfoUML()
Definition: OrthoRep.h:273
ogdf::OrthoRep::SideInfoUML::totalAttached
int totalAttached() const
Definition: OrthoRep.h:245
ogdf::graphics::init
void init()
Definition: graphics.h:450
ogdf::OrthoRep::m_angle
AdjEntryArray< int > m_angle
Definition: OrthoRep.h:425
ogdf::OrthoRep::SideInfoUML::operator<<
friend std::ostream & operator<<(std::ostream &os, const SideInfoUML &si)
Definition: OrthoRep.h:251
ogdf::Graph::edges
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition: Graph_d.h:935
ogdf::OrthoRep::m_preprocess
bool m_preprocess
Definition: OrthoRep.h:447
ogdf::UMLOpt
UMLOpt
Definition: OrthoRep.h:59
ogdf::BendString::operator<<
friend std::ostream & operator<<(std::ostream &os, const BendString &bs)
Definition: OrthoRep.h:203
basic.h
Basic declarations, included by all source files.
CombinatorialEmbedding.h
Declaration of CombinatorialEmbedding and face.
OGDF_EXPORT
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF DLL.
Definition: config.h:101
ogdf::OrthoRep::externalAdjEntry
adjEntry externalAdjEntry() const
Definition: OrthoRep.h:259
ogdf::CombinatorialEmbedding
Combinatorial embeddings of planar graphs with modification functionality.
Definition: CombinatorialEmbedding.h:406
ogdf::OrthoDir::East
@ East
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
ogdf::OrthoRep::operator<<
friend std::ostream & operator<<(std::ostream &os, const OrthoRep &op)
Definition: OrthoRep.h:404
ogdf::BendString::BendString
BendString(BendString &&bs)
Definition: OrthoRep.h:93
ogdf::OrthoRep::isOrientated
bool isOrientated() const
Definition: OrthoRep.h:366
ogdf::OrthoRep::bend
const BendString & bend(adjEntry adj) const
Definition: OrthoRep.h:313
ogdf::BendString::m_len
size_t m_len
Definition: OrthoRep.h:221
ogdf::OrthoRep::m_adjExternal
adjEntry m_adjExternal
Definition: OrthoRep.h:443
ogdf::UMLOpt::OpScale
@ OpScale
ogdf::OrthoDir::North
@ North
ogdf::OrthoRep::prevDir
static OrthoDir prevDir(OrthoDir d)
Returns the previous OrthoDir (in a clockwise manner)
Definition: OrthoRep.h:400
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240
ogdf::UMLOpt::OpProg
@ OpProg
ogdf::operator|
int operator|(int lhs, UMLOpt rhs)
Definition: OrthoRep.h:61
memory.h
Declaration of memory manager for allocating small pieces of memory.
ogdf::OrthoRep::direction
OrthoDir direction(adjEntry adj) const
Definition: OrthoRep.h:318
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:716
ogdf::OrthoRep::OrthoRep
OrthoRep()
Definition: OrthoRep.h:285
ogdf::BendString::set
void set(char c, size_t n)
Definition: OrthoRep.h:130
ogdf::BendString::operator=
BendString & operator=(BendString &&bs)
Definition: OrthoRep.h:155