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/FaceArray.h>
35 #include <ogdf/basic/GraphCopy.h>
36 #include <ogdf/basic/tuples.h>
37 
38 namespace ogdf {
39 
40 class OGDF_EXPORT PlanRep;
41 class OGDF_EXPORT PlanRepUML;
42 
43 
44 // type for bends (convex or reflex)
45 enum class OrthoBendType : char { convexBend = '0', reflexBend = '1' };
46 
47 // type of (orthogonal) directions
48 // horizontal: East or West
49 // vertical: North or South
50 enum 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
53 enum class UMLOpt { OpAlign = 0x0001, OpScale = 0x0002, OpProg = 0x0004 };
54 
55 inline int operator|(int lhs, UMLOpt rhs) { return lhs | static_cast<int>(rhs); }
56 
57 inline int operator~(UMLOpt rhs) { return ~static_cast<int>(rhs); }
58 
59 inline int operator&(int lhs, UMLOpt rhs) { return lhs & static_cast<int>(rhs); }
60 
61 inline int operator+=(int& lhs, UMLOpt rhs) {
62  lhs += static_cast<int>(rhs);
63  return lhs;
64 }
65 
68 public:
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 
206 private:
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 
220 public:
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 
258  struct VertexInfoUML {
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
282  explicit OrthoRep(CombinatorialEmbedding& E);
283 
284  // destruction
285  ~OrthoRep() { freeCageInfoUML(); }
286 
287  // reinitialization: associates orthogonal representation with embedding E
288  void init(CombinatorialEmbedding& 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
340  void gridDissect(PlanRep* PG);
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)
355  void orientate(adjEntry adj, OrthoDir dir);
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 
411 private:
412  void orientateFace(adjEntry adj, OrthoDir dir);
413  void freeCageInfoUML();
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 }
ogdf::ArrayBuffer
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition: Array.h:46
ogdf::OrthoRep::m_adjAlign
adjEntry m_adjAlign
Definition: OrthoRep.h:439
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::BendString::BendString
BendString(const BendString &bs)
Definition: OrthoRep.h:84
ogdf::OrthoRep::m_dir
AdjEntryArray< OrthoDir > m_dir
Definition: OrthoRep.h:423
ogdf::OrthoRep::m_umlCageInfo
NodeArray< VertexInfoUML * > m_umlCageInfo
Definition: OrthoRep.h:427
ogdf::PlanRep
Planarized representations (of a connected component) of a graph.
Definition: PlanRep.h:57
ogdf::OrthoRep::angle
int & angle(adjEntry adj)
Definition: OrthoRep.h:304
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::BendString::BendString
BendString()
Definition: OrthoRep.h:70
ogdf::OrthoRep::VertexInfoUML
Further information about the cages of vertices in UML diagrams.
Definition: OrthoRep.h:258
ogdf::OrthoRep::angle
int angle(adjEntry adj) const
Definition: OrthoRep.h:302
ogdf::OrthoDir
OrthoDir
Definition: OrthoRep.h:50
ogdf::operator+=
int operator+=(int &lhs, UMLOpt rhs)
Definition: OrthoRep.h:61
ogdf::OrthoRep::cageInfo
VertexInfoUML * cageInfo(node v)
Definition: OrthoRep.h:318
ogdf::BendString::BendString
BendString(const char *str)
Definition: OrthoRep.h:77
ogdf::BendString::m_pBend
char * m_pBend
Definition: OrthoRep.h:213
ogdf::OrthoDir::West
@ West
ogdf::OrthoRep::SideInfoUML::m_adjGen
adjEntry m_adjGen
Definition: OrthoRep.h:225
ogdf::BendString
Represents the bends on an edge e consisting of vertical and horizontal segments.
Definition: OrthoRep.h:67
ogdf::BendString::operator=
BendString & operator=(const BendString &bs)
Definition: OrthoRep.h:142
ogdf::OrthoRep::m_alignmentEdge
EdgeArray< bool > m_alignmentEdge
Definition: OrthoRep.h:432
ogdf::OrthoRep::SideInfoUML
Information about a side of a vertex in UML diagrams.
Definition: OrthoRep.h:222
ogdf::BendString::size
size_t size() const
Definition: OrthoRep.h:109
ogdf::OrthoDir::South
@ South
ogdf::OrthoBendType::convexBend
@ convexBend
ogdf::operator&
int operator&(int lhs, UMLOpt rhs)
Definition: OrthoRep.h:59
ogdf::OrthoRep::m_pE
CombinatorialEmbedding * m_pE
Definition: OrthoRep.h:416
ogdf::BendString::operator+=
BendString & operator+=(const char *str)
Definition: OrthoRep.h:160
ogdf::OrthoRep::m_dissectionEdge
EdgeArray< bool > m_dissectionEdge
Definition: OrthoRep.h:430
FaceArray.h
declaration and implementation of FaceArray class
OGDF_NEW_DELETE
#define OGDF_NEW_DELETE
Makes the class use OGDF's memory allocator.
Definition: memory.h:84
ogdf::OrthoDir::Undefined
@ Undefined
ogdf::operator~
int operator~(UMLOpt rhs)
Definition: OrthoRep.h:57
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:135
ogdf::BendString::set
void set()
Definition: OrthoRep.h:135
ogdf::BendString::set
void set(const char *str)
Definition: OrthoRep.h:117
ogdf::BendString::operator+=
BendString & operator+=(const BendString &bs)
Definition: OrthoRep.h:162
ogdf::BendString::operator[]
char & operator[](size_t i)
Definition: OrthoRep.h:102
ogdf::BendString::set
void set(OrthoBendType obt, size_t n)
Definition: OrthoRep.h:129
ogdf::OrthoRep::flip
static char flip(char c)
Definition: OrthoRep.h:381
ogdf::BendString::~BendString
~BendString()
Definition: OrthoRep.h:93
r
int r[]
Definition: hierarchical-ranking.cpp:8
ogdf::OrthoBendType::reflexBend
@ reflexBend
ogdf::OrthoRep::m_splitNodes
ArrayBuffer< node > m_splitNodes
Definition: OrthoRep.h:435
ogdf::OrthoRep
Orthogonal representation of an embedded graph.
Definition: OrthoRep.h:219
ogdf::OrthoRep::SideInfoUML::SideInfoUML
SideInfoUML()
Definition: OrthoRep.h:233
ogdf::UMLOpt::OpAlign
@ OpAlign
ogdf::OrthoRep::m_bends
AdjEntryArray< BendString > m_bends
Definition: OrthoRep.h:421
ogdf::OrthoBendType
OrthoBendType
Definition: OrthoRep.h:45
ogdf::OrthoRep::nextDir
static OrthoDir nextDir(OrthoDir d)
Returns the next OrthoDir (in a clockwise manner)
Definition: OrthoRep.h:389
ogdf::OrthoRep::cageInfo
const VertexInfoUML * cageInfo(node v) const
Definition: OrthoRep.h:315
GraphCopy.h
Declaration of graph copy classes.
ogdf::OrthoRep::SideInfoUML::m_nAttached
int m_nAttached[2]
Definition: OrthoRep.h:230
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:651
ogdf::EdgeElement::adjSource
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
Definition: Graph_d.h:400
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:862
ogdf::OrthoRep::alignAdjEntry
adjEntry alignAdjEntry() const
Definition: OrthoRep.h:255
ogdf::BendString::BendString
BendString(char c, size_t n)
Definition: OrthoRep.h:81
ogdf::OrthoRep::m_pattern2
bool m_pattern2
Definition: OrthoRep.h:443
ogdf::OrthoRep::bend
BendString & bend(adjEntry adj)
Definition: OrthoRep.h:309
ogdf::OrthoRep::oppDir
static OrthoDir oppDir(OrthoDir d)
Returns the opposite OrthoDir.
Definition: OrthoRep.h:384
ogdf::BendString::operator[]
char operator[](size_t i) const
Definition: OrthoRep.h:96
ogdf::OrthoRep::~OrthoRep
~OrthoRep()
Definition: OrthoRep.h:285
ogdf::BendString::toString
const char * toString() const
Definition: OrthoRep.h:113
ogdf::EdgeElement::adjTarget
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
Definition: Graph_d.h:403
ogdf::OrthoRep::VertexInfoUML::VertexInfoUML
VertexInfoUML()
Definition: OrthoRep.h:267
ogdf::OrthoRep::SideInfoUML::totalAttached
int totalAttached() const
Definition: OrthoRep.h:239
ogdf::graphics::init
void init()
Definition: graphics.h:446
ogdf::OrthoRep::m_angle
AdjEntryArray< int > m_angle
Definition: OrthoRep.h:419
ogdf::OrthoRep::SideInfoUML::operator<<
friend std::ostream & operator<<(std::ostream &os, const SideInfoUML &si)
Definition: OrthoRep.h:245
ogdf::Graph::edges
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition: Graph_d.h:927
ogdf::OrthoRep::m_preprocess
bool m_preprocess
Definition: OrthoRep.h:441
ogdf::UMLOpt
UMLOpt
Definition: OrthoRep.h:53
ogdf::BendString::operator<<
friend std::ostream & operator<<(std::ostream &os, const BendString &bs)
Definition: OrthoRep.h:197
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:253
ogdf::CombinatorialEmbedding
Combinatorial embeddings of planar graphs with modification functionality.
Definition: CombinatorialEmbedding.h:397
ogdf::OrthoDir::East
@ East
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
ogdf::OrthoRep::operator<<
friend std::ostream & operator<<(std::ostream &os, const OrthoRep &op)
Definition: OrthoRep.h:398
ogdf::BendString::BendString
BendString(BendString &&bs)
Definition: OrthoRep.h:87
ogdf::OrthoRep::isOrientated
bool isOrientated() const
Definition: OrthoRep.h:360
ogdf::OrthoRep::bend
const BendString & bend(adjEntry adj) const
Definition: OrthoRep.h:307
ogdf::BendString::m_len
size_t m_len
Definition: OrthoRep.h:215
ogdf::OrthoRep::m_adjExternal
adjEntry m_adjExternal
Definition: OrthoRep.h:437
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:394
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
tuples.h
Declaration and implementation of class Tuple2, Tuple3 and Tuple4.
ogdf::UMLOpt::OpProg
@ OpProg
ogdf::operator|
int operator|(int lhs, UMLOpt rhs)
Definition: OrthoRep.h:55
ogdf::OrthoRep::direction
OrthoDir direction(adjEntry adj) const
Definition: OrthoRep.h:312
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:709
ogdf::OrthoRep::OrthoRep
OrthoRep()
Definition: OrthoRep.h:279
ogdf::BendString::set
void set(char c, size_t n)
Definition: OrthoRep.h:124
ogdf::BendString::operator=
BendString & operator=(BendString &&bs)
Definition: OrthoRep.h:149