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 #ifndef OGDF_UML_GRAPH_H
00048 #define OGDF_UML_GRAPH_H
00049
00050
00051 #include <ogdf/basic/GraphAttributes.h>
00052 #include <ogdf/basic/AdjEntryArray.h>
00053 #include <ogdf/basic/SList.h>
00054
00055
00056 namespace ogdf {
00057
00058 class OGDF_EXPORT UMLGraph : public GraphAttributes
00059 {
00060 public:
00061
00062
00063
00064 UMLGraph() : GraphAttributes(), m_pG(0) { }
00065
00066
00067 explicit UMLGraph(Graph &G, long initAttributes = 0);
00068
00069
00070 virtual ~UMLGraph();
00071
00072
00073 virtual void init(Graph &G, long initAttr)
00074 {
00075 m_pG = &G;
00076 GraphAttributes::init(G, initAttr);
00077 m_hierarchyParent.init(constGraph(), 0);
00078 m_upwardEdge.init(constGraph(), false);
00079 }
00080
00081 operator const Graph &() const { return *m_pGraph; }
00082
00083
00084
00085
00086 void insertGenMergers();
00087
00088 node doInsertMergers(node v, SList<edge> &inGens);
00089 void undoGenMergers();
00090
00091
00092
00093
00094
00095 void replaceByStar(List< List<node> > &cliques);
00096
00097
00098 void undoStars();
00099
00100 void undoStar(node center, bool restoreAllEdges);
00101
00102
00103 DRect cliqueRect(node v)
00104 {
00105 return m_cliqueCircleSize[v];
00106 }
00107 DPoint cliquePos(node v)
00108 {
00109 return m_cliqueCirclePos[v];
00110 }
00111
00112
00113
00114
00115
00116
00117 void computeCliquePosition(node center, double rectMin);
00118
00119
00120
00121 void computeCliquePosition(List<node> &adjNodes, node center, double rectMin = -1.0);
00122
00123
00124 Graph& pureGraph() const {return *m_pG;}
00125
00126
00127
00128
00129 void setUpwards(adjEntry a, bool b) {m_upwardEdge[a] = b;}
00130 bool upwards(adjEntry a) const {return m_upwardEdge[a];}
00131
00132
00133 void writeGML(const char *fileName);
00134
00135
00136 void writeGML(ostream &os);
00137
00138
00139
00140
00141 void adjustHierarchyParents();
00142
00143
00144
00145
00146 void sortEdgesFromLayout();
00147
00148
00149
00150
00151
00152
00153 bool isReplacement(edge e)
00154 {
00155 return m_replacementEdge[e];
00156 }
00157
00158 const SListPure<node> ¢erNodes() {return m_centerNodes;}
00159
00160
00161 void setDefaultCliqueCenterSize(double i) {m_cliqueCenterSize = max(i, 1.0);}
00162 double getDefaultCliqueCenterSize() {return m_cliqueCenterSize;}
00163
00164
00165
00166 class AssociationClass {
00167 public:
00168 AssociationClass(edge e, double width = 1.0, double height = 1.0,
00169 double x = 0.0, double y = 0.0)
00170 : m_width(width), m_height(height), m_x(x), m_y(y), m_edge(e), m_node(0)
00171 {
00172
00173 }
00174 double m_width;
00175 double m_height;
00176 double m_x;
00177 double m_y;
00178 edge m_edge;
00179 node m_node;
00180 };
00181 const SListPure<AssociationClass*> &assClassList() const {return m_assClassList;}
00182
00183 const AssociationClass* assClass(edge e) const {return m_assClass[e];}
00184
00185
00186
00187 node createAssociationClass(edge e, double width = 1.0, double height = 1.0)
00188 {
00189 AssociationClass* ac = new AssociationClass(e, width, height);
00190 m_assClass[e] = ac;
00191 m_assClassList.pushBack(ac);
00192
00193
00194
00195 node v = m_pG->newNode();
00196 m_height[v] = ac->m_height;
00197 m_width[v] = ac->m_width;
00198 m_associationClassModel[ac->m_edge] = v;
00199 ac->m_node = v;
00200
00201 if (m_attributes & GraphAttributes::nodeType)
00202 {
00203 m_vType[v] = Graph::associationClass;
00204 }
00205 return v;
00206
00207 }
00208
00209
00210
00211 void modelAssociationClasses()
00212 {
00213 SListIterator<UMLGraph::AssociationClass*> it = m_assClassList.begin();
00214 while (it.valid())
00215 {
00216 modelAssociationClass((*it));
00217 it++;
00218 }
00219 }
00220 node modelAssociationClass(AssociationClass* ac)
00221 {
00222 node dummy = m_pG->split(ac->m_edge)->source();
00223
00224 m_height[dummy] = 1;
00225 m_width[dummy] = 1;
00226 OGDF_ASSERT(ac->m_node)
00227 m_pG->newEdge(ac->m_node, dummy);
00228
00229 return dummy;
00230 }
00231
00232 void undoAssociationClasses()
00233 {
00234 SListIterator<UMLGraph::AssociationClass*> it = m_assClassList.begin();
00235 while (it.valid())
00236 {
00237 undoAssociationClass((*it));
00238 it++;
00239 }
00240 }
00241
00242 void undoAssociationClass(AssociationClass* ac)
00243 {
00244 node v = m_associationClassModel[ac->m_edge];
00245 OGDF_ASSERT(v)
00246 OGDF_ASSERT(v->degree() == 1)
00247 if (v->degree() != 1) throw AlgorithmFailureException(afcLabel);
00248
00249 ac->m_x = x(v);
00250 ac->m_y = y(v);
00251
00252
00253
00254
00255 adjEntry outAdj = v->firstAdj();
00256 adjEntry dummyAdj = outAdj->twin();
00257
00258 node dummy = dummyAdj->theNode();
00259 OGDF_ASSERT(dummy->degree() == 3)
00260
00261
00262
00263 m_pG->delEdge(v->firstAdj()->theEdge());
00264 OGDF_ASSERT(v->degree() == 0)
00265
00266 m_pG->unsplit(dummy);
00267 }
00268
00269
00270
00271 protected:
00272
00273 node replaceByStar(List<node> &clique, NodeArray<int> &cliqueNum);
00274 DRect circularBound(node center);
00275
00276 private:
00277
00278 Graph *m_pG;
00279
00280
00281 class CliqueInfo {
00282 public:
00283 CliqueInfo(node v, int i) : m_target(v), m_edgeIndex(i) {}
00284 node m_target;
00285 int m_edgeIndex;
00286 };
00287 double m_cliqueCenterSize;
00288
00289 SListPure<edge> m_mergeEdges;
00290 SListPure<node> m_centerNodes;
00291 EdgeArray<bool> m_replacementEdge;
00292
00293 NodeArray<DRect> m_cliqueCircleSize;
00294
00295 NodeArray<DPoint> m_cliqueCirclePos;
00296
00297
00298
00299
00300 SListPure<AssociationClass*> m_assClassList;
00301 EdgeArray<AssociationClass*> m_assClass;
00302 EdgeArray<node> m_associationClassModel;
00303
00304
00305
00306
00307
00308 AdjEntryArray<bool> m_upwardEdge;
00309
00310
00311
00312
00313 NodeArray<node> m_hierarchyParent;
00314
00315 };
00316
00317
00318 }
00319
00320 #endif