Add tests for UpdateCrypto
[TortoiseGit.git] / ext / OGDF / ogdf / orthogonal / OrthoRep.h
blob679e06b66b467f758d796f3a84d39988f3597e89
1 /*
2 * $Revision: 2564 $
4 * last checkin:
5 * $Author: gutwenger $
6 * $Date: 2012-07-07 00:03:48 +0200 (Sa, 07. Jul 2012) $
7 ***************************************************************/
9 /** \file
10 * \brief Declaration of orthogonal representation of planar graphs.
12 * \author Carsten Gutwenger
14 * \par License:
15 * This file is part of the Open Graph Drawing Framework (OGDF).
17 * \par
18 * Copyright (C)<br>
19 * See README.txt in the root directory of the OGDF installation for details.
21 * \par
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
26 * for details.
28 * \par
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
34 * \par
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
44 #ifdef _MSC_VER
45 #pragma once
46 #endif
49 #ifndef OGDF_ORTHO_REP_H
50 #define OGDF_ORTHO_REP_H
53 #include <ogdf/basic/GraphCopy.h>
54 #include <ogdf/basic/FaceArray.h>
55 #include <ogdf/basic/tuples.h>
56 #include <ogdf/basic/Stack.h>
59 namespace ogdf {
61 class OGDF_EXPORT PlanRep;
62 class OGDF_EXPORT PlanRepUML;
65 // type for bends (convex or reflex)
66 enum BendType { convexBend = '0', reflexBend = '1' };
68 // type of (orthogonal) directions
69 // horizontal: odEast or odWest
70 // vertical: odNorth or odSouth
71 enum OrthoDir {
72 odNorth = 0,
73 odEast = 1,
74 odSouth = 2,
75 odWest = 3,
76 odUndefined = 4
80 //---------------------------------------------------------
81 // BendString
82 // represents the bends on an edge e consisting of vertical
83 // and horizontal segments
84 //---------------------------------------------------------
85 class OGDF_EXPORT BendString
87 public:
88 // constructs empty bend string
89 BendString() {
90 m_pBend = 0;
91 m_len = 0;
94 // constructs bend string as given by str
95 // Precond.: str is a 0 terminated C++ string consisting of '0's and '1's
96 BendString(const char *str) {
97 init(str);
100 // constructs bend string consisting of n c's
101 // Precond.: c is '0' or '1'
102 BendString(char c, size_t n) {
103 init(c,n);
106 // copy constructor
107 BendString(const BendString &bs) {
108 init(bs);
112 // destructor
113 ~BendString() {
114 delete [] m_pBend;
118 // returns i'th character in bend string
119 char operator[](size_t i) const {
120 // range check
121 OGDF_ASSERT(i < m_len);
122 return m_pBend[i];
125 char &operator[](size_t i) {
126 // range check
127 OGDF_ASSERT(i < m_len);
128 return m_pBend[i];
131 // returns number of characters in bend string
132 size_t size() const {
133 return m_len;
136 // returns a pointer to the 0 terminated string
137 // or a 0-pointer if empty
138 const char *toString() const {
139 return m_pBend;
142 // sets bend string to the string given by str
143 // Precond.: str is a 0 terminated C++ string consisting of '0's and '1's
144 void set(const char *str) {
145 delete [] m_pBend;
146 init(str);
149 // sets bend string to the string consisting of n c's
150 // Precond.: c is '0' or '1'
151 void set(char c, size_t n) {
152 delete [] m_pBend;
153 init(c,n);
157 // sets bend string to the empty bend string
158 void set() {
159 delete [] m_pBend;
160 m_pBend = 0;
161 m_len = 0;
165 // assignment operator
166 BendString &operator=(const BendString &bs) {
167 delete [] m_pBend;
168 init(bs);
169 return *this;
172 BendString &operator+=(const BendString &bs) {
173 char* temp = new char[m_len+bs.m_len+1];
175 m_len = m_len + bs.m_len;
177 if (m_len == 0)
179 *temp = 0;//temp = 0;
181 else
183 char *p = temp;
184 if (m_pBend != 0)
186 const char *str = m_pBend;
187 while ((*p++ = *str++) != 0) ;
189 else {*p = '0'; p++;}
190 if (bs.m_len > 0)
192 p--;
193 const char *str1 = bs.m_pBend;
194 while ((*p++ = *str1++) != 0) ;
198 delete[] m_pBend;
199 m_pBend = temp;
201 return *this;
204 // output operator
205 // example output: "001101001" or ""
206 friend ostream &operator<<(ostream &os, const BendString &bs) {
207 if (bs.size() == 0)
208 os << "\"\"";
209 else
210 os << "\"" << bs.m_pBend << "\"";
211 return os;
214 private:
215 void init(const char *str);
216 void init(char c, size_t n);
217 void init(const BendString &bs);
220 // poiner to 0 terminated character string
221 char *m_pBend;
222 // length of string (number of characters without ending 0)
223 size_t m_len;
228 //---------------------------------------------------------
229 // OrthoRep
230 // orthogonal representation of an embedded graph
231 //---------------------------------------------------------
232 class OGDF_EXPORT OrthoRep
234 public:
236 //---------------------------------------------------------
237 // information about a side of a vertex in UML diagrams
238 //---------------------------------------------------------
239 struct SideInfoUML {
240 // adjacency entry of generalization attached at the side
241 // (or 0 if none)
242 adjEntry m_adjGen;
243 // number of attached edges which have corresponding edges in the
244 // original graph to the left (index 0) or right of the
245 // attached generalization. If no generalization is attached,
246 // m_nAttached[0] is the total number of attached edges.
247 int m_nAttached[2];
249 // constructor
250 SideInfoUML() {
251 m_adjGen = 0;
252 m_nAttached[0] = m_nAttached[1] = 0;
255 // returns the total number of edges attached at this side
256 int totalAttached() const {
257 int nGen = (m_adjGen == 0) ? 0 : 1;
258 return nGen + m_nAttached[0] + m_nAttached[1];
262 // output operator for debugging
263 friend ostream &operator<<(ostream &os, const SideInfoUML &si)
265 os << "{ " << si.m_nAttached[0] <<
266 ", " << si.m_adjGen <<
267 ", " << si.m_nAttached[1] << " }";
268 return os;
272 //only for debugging purposes
273 adjEntry externalAdjEntry() const {return m_adjExternal;}
274 adjEntry alignAdjEntry() const {return m_adjAlign;}
277 //---------------------------------------------------------
278 // further information about the cages of vertices in UML diagrams
279 //---------------------------------------------------------
280 struct VertexInfoUML {
281 // side information (odNorth, odEast, odSouth, odWest corresponds to
282 // left, top, right, bottom)
283 SideInfoUML m_side[4];
284 // m_corner[dir] is adjacency entry in direction dir starting at
285 // a corner
286 adjEntry m_corner[4];
288 // constructor
289 VertexInfoUML() {
290 #ifdef OGDF_DEBUG
291 m_corner[0] = m_corner[1] = m_corner[2] = m_corner[3] = 0;
292 #endif
294 OGDF_NEW_DELETE
298 // construction
300 // dummy
301 OrthoRep() { m_pE = 0; }
302 // associates orthogonal representation with embedding E
303 OrthoRep(CombinatorialEmbedding &E);
305 // destruction
306 ~OrthoRep() {
307 freeCageInfoUML();
310 // reinitialization: associates orthogonal representation with embedding E
311 void init(CombinatorialEmbedding &E);
315 // access functions
318 // returns associated embedding
319 operator const CombinatorialEmbedding &() const {
320 return *m_pE;
323 // returns associated graph
324 operator const Graph &() const {
325 return *m_pE;
328 // returns angle between adj and its successor
329 // (return value is angle divided by 90 degree)
330 int angle(adjEntry adj) const {
331 return m_angle[adj];
334 int &angle(adjEntry adj) {
335 return m_angle[adj];
339 // returns bend string of adjacency entry adj
340 const BendString &bend(adjEntry adj) const {
341 return m_bends[adj];
344 BendString &bend(adjEntry adj) {
345 return m_bends[adj];
348 // returns direction of adjacency entry
349 OrthoDir direction(adjEntry adj) const {
350 return m_dir[adj];
354 // returns cage info
355 const VertexInfoUML *cageInfo(node v) const {
356 return m_umlCageInfo[v];
359 // returns cage info
360 VertexInfoUML *cageInfo(node v) {
361 return m_umlCageInfo[v];
367 // update functions
370 // normalizes the orthogonal representation, i.e., sets an artficial
371 // vertex on each bend
372 void normalize();
374 // checks if the orth. repr. is normalized, i.e., each bend string is empty
375 bool isNormalized() const;
377 // removes rectangular ears (pattern "100") by splitting edges and faces.
378 // Afterwards, each internal face is a rectangle and the external face
379 // contains no rectangular ear (but is not necessarily the complement of
380 // a rectangle).
381 // Precond.: The orth. repr. is normalized and contains no 0-degree angles
382 void dissect();
383 // same as dissect, attempting to save artificial nodes and allow preprocessing
384 void dissect2(PlanRepUML* PG = 0);
385 // undoes a previous dissect() by removing dissection edges and unsplitting
386 // vertices
387 void undissect(bool align = false);
390 // assigns consistent directions to adjacency entries
391 void orientate();
393 // assigns consistent directions to adj. entries such that most
394 // generalizations are directed in preferedDir
395 void orientate(const PlanRep &PG, OrthoDir preferedDir);
397 // assigns consistent directions to adjacency entries,
398 // assigning dir to adj (fixing all others)
399 void orientate(adjEntry adj, OrthoDir dir);
401 // returns true iff orientate() has been called before.
402 // If not, direction() may not be called since adj. entry array is not
403 // initialized!
404 bool isOrientated() const {
405 return m_dir.valid();
409 // rotates all directions of adjacency entries by r
410 void rotate(int r);
413 // computes further information about cages
414 void computeCageInfoUML(const PlanRep &PG/*, double sep*/);
417 // checks if the orth. repr. is a legal shape description, i.e., if there
418 // is an orthogonal embedding realizing this shape (if 0-degree angles are
419 // present, the condition is necessary but not sufficient).
420 // If false is returned, error contains a description of the reason.
421 bool check(String &error);
425 // static members
428 // exchanges '1'->'0' and vice versa
429 static char flip(char c) {
430 return (c == '0') ? '1' : '0';
433 static OrthoDir oppDir(OrthoDir d) {
434 return OrthoDir((d + 2) & 3);
437 static OrthoDir nextDir(OrthoDir d) {
438 return OrthoDir((d + 1) & 3);
441 static OrthoDir prevDir(OrthoDir d) {
442 return OrthoDir((d + 3) & 3);
445 friend ostream &operator<<(ostream &os, const OrthoRep &op) {
446 edge e;
447 const Graph& E = op;
448 forall_edges(e, E)
450 os << e <<": src angle "<<op.angle(e->adjSource())<<" bend "<<op.bend(e->adjSource())
451 <<"\n"<<" tgt angle "<<op.angle(e->adjTarget())<<" bend "<<op.bend(e->adjTarget())
453 <<"\n";
455 return os;
460 private:
461 void orientateFace(adjEntry adj, OrthoDir dir);
462 void freeCageInfoUML();
464 // associated combinatorial embedding
465 CombinatorialEmbedding *m_pE;
467 // * 90 deg = angle between e and its successor
468 AdjEntryArray<int> m_angle;
469 // bends on edge e
470 AdjEntryArray<BendString> m_bends;
471 // direction of adjacency entries
472 AdjEntryArray<OrthoDir> m_dir;
474 // information about cages of original vertices; used for orthogonal
475 // representations of PlanRep's
476 NodeArray<VertexInfoUML *> m_umlCageInfo;
478 // The following members are used for undoing dissection
479 EdgeArray<bool> m_dissectionEdge; // = true iff dissection edge
480 //check if special gener. sons alignment edge
481 EdgeArray<bool> m_alignmentEdge; // = true iff alignment edge
482 // contains all nodes created by splitting non-dissection edges while
483 // dissect()
484 StackPure<node> m_splitNodes;
485 // stores adjacency entry on external face for restoring in undissect()
486 adjEntry m_adjExternal;
487 // stores adjacency entry on preliminary external face in alignment case
488 adjEntry m_adjAlign;
489 //starts dissection phase for special pattern 1 replacement before standard dissection
490 bool m_preprocess;
491 //special pattern after pattern 1
492 bool m_pattern2;
496 } // end namespace ogdf
499 #endif