6 * $Date: 2012-07-07 00:03:48 +0200 (Sa, 07. Jul 2012) $
7 ***************************************************************/
10 * \brief Declaration of orthogonal representation of planar graphs.
12 * \author Carsten Gutwenger
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
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
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.
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 ***************************************************************/
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>
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
80 //---------------------------------------------------------
82 // represents the bends on an edge e consisting of vertical
83 // and horizontal segments
84 //---------------------------------------------------------
85 class OGDF_EXPORT BendString
88 // constructs empty bend string
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
) {
100 // constructs bend string consisting of n c's
101 // Precond.: c is '0' or '1'
102 BendString(char c
, size_t n
) {
107 BendString(const BendString
&bs
) {
118 // returns i'th character in bend string
119 char operator[](size_t i
) const {
121 OGDF_ASSERT(i
< m_len
);
125 char &operator[](size_t i
) {
127 OGDF_ASSERT(i
< m_len
);
131 // returns number of characters in bend string
132 size_t size() const {
136 // returns a pointer to the 0 terminated string
137 // or a 0-pointer if empty
138 const char *toString() const {
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
) {
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
) {
157 // sets bend string to the empty bend string
165 // assignment operator
166 BendString
&operator=(const BendString
&bs
) {
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
;
179 *temp
= 0;//temp = 0;
186 const char *str
= m_pBend
;
187 while ((*p
++ = *str
++) != 0) ;
189 else {*p
= '0'; p
++;}
193 const char *str1
= bs
.m_pBend
;
194 while ((*p
++ = *str1
++) != 0) ;
205 // example output: "001101001" or ""
206 friend ostream
&operator<<(ostream
&os
, const BendString
&bs
) {
210 os
<< "\"" << bs
.m_pBend
<< "\"";
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
222 // length of string (number of characters without ending 0)
228 //---------------------------------------------------------
230 // orthogonal representation of an embedded graph
231 //---------------------------------------------------------
232 class OGDF_EXPORT OrthoRep
236 //---------------------------------------------------------
237 // information about a side of a vertex in UML diagrams
238 //---------------------------------------------------------
240 // adjacency entry of generalization attached at the side
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.
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] << " }";
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
286 adjEntry m_corner
[4];
291 m_corner
[0] = m_corner
[1] = m_corner
[2] = m_corner
[3] = 0;
301 OrthoRep() { m_pE
= 0; }
302 // associates orthogonal representation with embedding E
303 OrthoRep(CombinatorialEmbedding
&E
);
310 // reinitialization: associates orthogonal representation with embedding E
311 void init(CombinatorialEmbedding
&E
);
318 // returns associated embedding
319 operator const CombinatorialEmbedding
&() const {
323 // returns associated graph
324 operator const Graph
&() const {
328 // returns angle between adj and its successor
329 // (return value is angle divided by 90 degree)
330 int angle(adjEntry adj
) const {
334 int &angle(adjEntry adj
) {
339 // returns bend string of adjacency entry adj
340 const BendString
&bend(adjEntry adj
) const {
344 BendString
&bend(adjEntry adj
) {
348 // returns direction of adjacency entry
349 OrthoDir
direction(adjEntry adj
) const {
355 const VertexInfoUML
*cageInfo(node v
) const {
356 return m_umlCageInfo
[v
];
360 VertexInfoUML
*cageInfo(node v
) {
361 return m_umlCageInfo
[v
];
370 // normalizes the orthogonal representation, i.e., sets an artficial
371 // vertex on each bend
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
381 // Precond.: The orth. repr. is normalized and contains no 0-degree angles
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
387 void undissect(bool align
= false);
390 // assigns consistent directions to adjacency entries
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
404 bool isOrientated() const {
405 return m_dir
.valid();
409 // rotates all directions of adjacency entries by 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
);
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
) {
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())
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
;
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
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
489 //starts dissection phase for special pattern 1 replacement before standard dissection
491 //special pattern after pattern 1
496 } // end namespace ogdf