Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046
00047
00048 #ifndef OGDF_ORTHO_REP_H
00049 #define OGDF_ORTHO_REP_H
00050
00051
00052 #include <ogdf/basic/GraphCopy.h>
00053 #include <ogdf/basic/FaceArray.h>
00054 #include <ogdf/basic/tuples.h>
00055 #include <ogdf/basic/Stack.h>
00056
00057
00058 namespace ogdf {
00059
00060 class OGDF_EXPORT PlanRep;
00061 class OGDF_EXPORT PlanRepUML;
00062
00063
00064
00065 enum BendType { convexBend = '0', reflexBend = '1' };
00066
00067
00068
00069
00070 enum OrthoDir {
00071 odNorth = 0,
00072 odEast = 1,
00073 odSouth = 2,
00074 odWest = 3,
00075 odUndefined = 4
00076 };
00077
00078
00079
00080
00081
00082
00083
00084 class OGDF_EXPORT BendString
00085 {
00086 public:
00087
00088 BendString() {
00089 m_pBend = 0;
00090 m_len = 0;
00091 }
00092
00093
00094
00095 BendString(const char *str) {
00096 init(str);
00097 }
00098
00099
00100
00101 BendString(char c, size_t n) {
00102 init(c,n);
00103 }
00104
00105
00106 BendString(const BendString &bs) {
00107 init(bs);
00108 }
00109
00110
00111
00112 ~BendString() {
00113 delete [] m_pBend;
00114 }
00115
00116
00117
00118 char operator[](size_t i) const {
00119
00120 OGDF_ASSERT(i < m_len);
00121 return m_pBend[i];
00122 }
00123
00124 char &operator[](size_t i) {
00125
00126 OGDF_ASSERT(i < m_len);
00127 return m_pBend[i];
00128 }
00129
00130
00131 size_t size() const {
00132 return m_len;
00133 }
00134
00135
00136
00137 const char *toString() const {
00138 return m_pBend;
00139 }
00140
00141
00142
00143 void set(const char *str) {
00144 delete [] m_pBend;
00145 init(str);
00146 }
00147
00148
00149
00150 void set(char c, size_t n) {
00151 delete [] m_pBend;
00152 init(c,n);
00153 }
00154
00155
00156
00157 void set() {
00158 delete [] m_pBend;
00159 m_pBend = 0;
00160 m_len = 0;
00161 }
00162
00163
00164
00165 BendString &operator=(const BendString &bs) {
00166 delete [] m_pBend;
00167 init(bs);
00168 return *this;
00169 }
00170
00171 BendString &operator+=(const BendString &bs) {
00172 char* temp = new char[m_len+bs.m_len+1];
00173
00174 m_len = m_len + bs.m_len;
00175
00176 if (m_len == 0)
00177 {
00178 *temp = 0;
00179 }
00180 else
00181 {
00182 char *p = temp;
00183 if (m_pBend != 0)
00184 {
00185 const char *str = m_pBend;
00186 while ((*p++ = *str++) != 0) ;
00187 }
00188 else {*p = '0'; p++;}
00189 if (bs.m_len > 0)
00190 {
00191 p--;
00192 const char *str1 = bs.m_pBend;
00193 while ((*p++ = *str1++) != 0) ;
00194 }
00195 }
00196
00197 delete[] m_pBend;
00198 m_pBend = temp;
00199
00200 return *this;
00201 }
00202
00203
00204
00205 friend ostream &operator<<(ostream &os, const BendString &bs) {
00206 if (bs.size() == 0)
00207 os << "\"\"";
00208 else
00209 os << "\"" << bs.m_pBend << "\"";
00210 return os;
00211 }
00212
00213 private:
00214 void init(const char *str);
00215 void init(char c, size_t n);
00216 void init(const BendString &bs);
00217
00218
00219
00220 char *m_pBend;
00221
00222 size_t m_len;
00223 };
00224
00225
00226
00227
00228
00229
00230
00231 class OGDF_EXPORT OrthoRep
00232 {
00233 public:
00234
00235
00236
00237
00238 struct SideInfoUML {
00239
00240
00241 adjEntry m_adjGen;
00242
00243
00244
00245
00246 int m_nAttached[2];
00247
00248
00249 SideInfoUML() {
00250 m_adjGen = 0;
00251 m_nAttached[0] = m_nAttached[1] = 0;
00252 }
00253
00254
00255 int totalAttached() const {
00256 int nGen = (m_adjGen == 0) ? 0 : 1;
00257 return nGen + m_nAttached[0] + m_nAttached[1];
00258 }
00259
00260
00261
00262 friend ostream &operator<<(ostream &os, const SideInfoUML &si)
00263 {
00264 os << "{ " << si.m_nAttached[0] <<
00265 ", " << si.m_adjGen <<
00266 ", " << si.m_nAttached[1] << " }";
00267 return os;
00268 }
00269 };
00270
00271
00272 adjEntry externalAdjEntry() const {return m_adjExternal;}
00273 adjEntry alignAdjEntry() const {return m_adjAlign;}
00274
00275
00276
00277
00278
00279 struct VertexInfoUML {
00280
00281
00282 SideInfoUML m_side[4];
00283
00284
00285 adjEntry m_corner[4];
00286
00287
00288 VertexInfoUML() {
00289 #ifdef OGDF_DEBUG
00290 m_corner[0] = m_corner[1] = m_corner[2] = m_corner[3] = 0;
00291 #endif
00292 }
00293 OGDF_NEW_DELETE
00294 };
00295
00296
00297
00298
00299
00300 OrthoRep() { m_pE = 0; }
00301
00302 OrthoRep(CombinatorialEmbedding &E);
00303
00304
00305 ~OrthoRep() {
00306 freeCageInfoUML();
00307 }
00308
00309
00310 void init(CombinatorialEmbedding &E);
00311
00312
00313
00314
00315
00316
00317
00318 operator const CombinatorialEmbedding &() const {
00319 return *m_pE;
00320 }
00321
00322
00323 operator const Graph &() const {
00324 return *m_pE;
00325 }
00326
00327
00328
00329 int angle(adjEntry adj) const {
00330 return m_angle[adj];
00331 }
00332
00333 int &angle(adjEntry adj) {
00334 return m_angle[adj];
00335 }
00336
00337
00338
00339 const BendString &bend(adjEntry adj) const {
00340 return m_bends[adj];
00341 }
00342
00343 BendString &bend(adjEntry adj) {
00344 return m_bends[adj];
00345 }
00346
00347
00348 OrthoDir direction(adjEntry adj) const {
00349 return m_dir[adj];
00350 }
00351
00352
00353
00354 const VertexInfoUML *cageInfo(node v) const {
00355 return m_umlCageInfo[v];
00356 }
00357
00358
00359 VertexInfoUML *cageInfo(node v) {
00360 return m_umlCageInfo[v];
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 void normalize();
00372
00373
00374 bool isNormalized() const;
00375
00376
00377
00378
00379
00380
00381 void dissect();
00382
00383 void dissect2(PlanRepUML* PG = 0);
00384
00385
00386 void undissect(bool align = false);
00387
00388
00389
00390 void orientate();
00391
00392
00393
00394 void orientate(const PlanRep &PG, OrthoDir preferedDir);
00395
00396
00397
00398 void orientate(adjEntry adj, OrthoDir dir);
00399
00400
00401
00402
00403 bool isOrientated() const {
00404 return m_dir.valid();
00405 }
00406
00407
00408
00409 void rotate(int r);
00410
00411
00412
00413 void computeCageInfoUML(const PlanRep &PG);
00414
00415
00416
00417
00418
00419
00420 bool check(String &error);
00421
00422
00423
00424
00425
00426
00427
00428 static char flip(char c) {
00429 return (c == '0') ? '1' : '0';
00430 }
00431
00432 static OrthoDir oppDir(OrthoDir d) {
00433 return OrthoDir((d + 2) & 3);
00434 }
00435
00436 static OrthoDir nextDir(OrthoDir d) {
00437 return OrthoDir((d + 1) & 3);
00438 }
00439
00440 static OrthoDir prevDir(OrthoDir d) {
00441 return OrthoDir((d + 3) & 3);
00442 }
00443
00444 friend ostream &operator<<(ostream &os, const OrthoRep &op) {
00445 edge e;
00446 const Graph& E = op;
00447 forall_edges(e, E)
00448 {
00449 os << e <<": src angle "<<op.angle(e->adjSource())<<" bend "<<op.bend(e->adjSource())
00450 <<"\n"<<" tgt angle "<<op.angle(e->adjTarget())<<" bend "<<op.bend(e->adjTarget())
00451
00452 <<"\n";
00453 }
00454 return os;
00455 }
00456
00457
00458
00459 private:
00460 void orientateFace(adjEntry adj, OrthoDir dir);
00461 void freeCageInfoUML();
00462
00463
00464 CombinatorialEmbedding *m_pE;
00465
00466
00467 AdjEntryArray<int> m_angle;
00468
00469 AdjEntryArray<BendString> m_bends;
00470
00471 AdjEntryArray<OrthoDir> m_dir;
00472
00473
00474
00475 NodeArray<VertexInfoUML *> m_umlCageInfo;
00476
00477
00478 EdgeArray<bool> m_dissectionEdge;
00479
00480 EdgeArray<bool> m_alignmentEdge;
00481
00482
00483 StackPure<node> m_splitNodes;
00484
00485 adjEntry m_adjExternal;
00486
00487 adjEntry m_adjAlign;
00488
00489 bool m_preprocess;
00490
00491 bool m_pattern2;
00492 };
00493
00494
00495 }
00496
00497
00498 #endif