Open
Graph Drawing
Framework

 v.2012.07
 

ClusterOrthoShaper.h
Go to the documentation of this file.
1 /*
2  * $Revision: 2564 $
3  *
4  * last checkin:
5  * $Author: gutwenger $
6  * $Date: 2012-07-07 00:03:48 +0200 (Sa, 07. Jul 2012) $
7  ***************************************************************/
8 
45 #ifdef _MSC_VER
46 #pragma once
47 #endif
48 
49 
50 #ifndef OGDF_CLUSTER_ORTHO_SHAPER_H
51 #define OGDF_CLUSTER_ORTHO_SHAPER_H
52 
53 
56 
57 
58 namespace ogdf {
59 
60 
62 {
63 
64 public:
65 
66  enum BendCost { defaultCost, topDownCost, bottomUpCost };
67  enum n_type { low, high, inner, outer }; //types of network nodes:
68  //nodes and faces
69 
71  m_distributeEdges = true; //try to distribute edges to all node sides
72  m_fourPlanar = true; //do not allow zero degree angles at high degree
73  m_allowLowZero = false; //do allow zero degree at low degree nodes
74  m_multiAlign = true; //true; //start/end side of multi edges match
75  m_traditional = true; //true; //prefer 3/1 flow at degree 2 (false: 2/2)
76  m_deg4free = false; //allow free angle assignment at degree four
77  m_align = false; //align nodes on same hierarchy level
78  m_topToBottom = defaultCost; //bend costs depend on edges cluster depth
79  };
80 
82 
83  // Given a planar representation for a UML graph and its planar
84  // combinatorial embedding, call() produces an orthogonal
85  // representation using Tamassias bend minimization algorithm
86  // with a flow network where every flow unit defines 90 degree angle
87  // in traditional mode.
88  // A maximum number of bends per edge can be specified in
89  // startBoundBendsPerEdge. If the algorithm is not successful in
90  // producing a bend minimal representation subject to
91  // startBoundBendsPerEdge, it successively enhances the bound by
92  // one trying to compute an orthogonal representation.
93  //
94  // Using startBoundBendsPerEdge may not produce a bend minimal
95  // representation in general.
96  void call(ClusterPlanRep &PG,
98  OrthoRep &OR,
99  int startBoundBendsPerEdge = 0,
100  bool fourPlanar = true);
101 
102 
103  // returns option distributeEdges
104  bool distributeEdges() { return m_distributeEdges; }
105  // sets option distributeEdges to b
106  void distributeEdges(bool b) { m_distributeEdges = b; }
107 
108  // returns option multiAlign
109  bool multiAlign() { return m_multiAlign; }
110  // sets option multiAlign to b
111  void multiAlign(bool b) { m_multiAlign = b; }
112 
113  // returns option traditional
114  bool traditional() { return m_traditional; }
115  // sets option traditional to b
116  void traditional(bool b) { m_traditional = b; }
117 
118  //returns option deg4free
119  bool fixDegreeFourAngles() { return m_deg4free; }
120  //sets option deg4free
121  void fixDegreeFourAngles(bool b) { m_deg4free = b; }
122 
123  //alignment of brothers in hierarchies
124  void align(bool al) { m_align = al; }
125  bool align() { return m_align; }
126 
127  void bendCostTopDown(BendCost i) { m_topToBottom = i; }
128 
129  //return cluster dependant bend cost for standard cost pbc
130  int clusterProgBendCost(int clDepth, int treeDepth, int pbc)
131  {
132  int cost = 1;
133  switch (m_topToBottom)
134  {
135  case topDownCost:
136  cost = pbc*(clDepth+1); //safeInt
137  break;
138  case bottomUpCost:
139  cost = pbc*(treeDepth - clDepth + 1); //safeInt
140  break;
141  default: //defaultCost
142  cost = pbc;
143  break;
144  }
145 
146 // cout<<" Cost/pbc: "<<cost<<"/"<<pbc<<"\n";
147 
148  return cost;
149  }
150 
151  //this is a try: I dont know why this was never implemented for traditional,
152  //maybe because of the unit cost for traditional bends vs. the highbound
153  //cost for progressive bends
154  //return cluster dependant bend cost for standard cost pbc
155  //preliminary same as progressive
156  int clusterTradBendCost(int clDepth, int treeDepth, int pbc)
157  {
158  int cost = 1;
159  switch (m_topToBottom)
160  {
161  case topDownCost:
162  cost = pbc*(clDepth+1); //safeInt
163  break;
164  case bottomUpCost:
165  cost = pbc*(treeDepth - clDepth + 1); //safeInt
166  break;
167  default: //defaultCost
168  cost = pbc;
169  break;
170  }
171 
172  return cost;
173  }//clusterTradBendCost
174 
175 
176 
177 private:
178  bool m_distributeEdges; // distribute edges among all sides if degree > 4
179  bool m_fourPlanar; // should the input graph be four planar
180  // (no zero degree)
181  bool m_allowLowZero; // allow low degree nodes zero degree
182  // (to low for zero...)
183  bool m_multiAlign; // multi edges aligned on the same side
184  bool m_deg4free; // allow degree four nodes free angle assignment
185  bool m_traditional; // do not prefer 180 degree angles,
186  // traditional is not tamassia,
187  // traditional is a kandinsky - ILP - like network with node supply 4,
188  // not traditional interprets angle flow zero as 180 degree, "flow
189  // through the node"
190  bool m_align; //try to achieve an alignment in hierarchy levels
191 
192  BendCost m_topToBottom; //change bend costs on cluster hierarchy levels
193 
194  //set angle boundary
195  //warning: sets upper AND lower bounds, therefore may interfere with existing bounds
196  void setAngleBound(
197  edge netArc,
198  int angle,
199  EdgeArray<int>& lowB,
200  EdgeArray<int>& upB,
201  EdgeArray<edge>& aTwin,
202  bool maxBound = true)
203  {
204  //vorlaeufig
205  OGDF_ASSERT(!m_traditional);
206  if (m_traditional)
207  {
208  switch (angle)
209  {
210  case 0:
211  case 90:
212  case 180:
213  break;
215  }//switch
216  }//trad
217  else
218  {
219  switch (angle)
220  {
221  case 0:
222  if (maxBound)
223  {
224  upB[netArc] = lowB[netArc] = 2;
225  edge e2 = aTwin[netArc];
226  if (e2)
227  {
228  upB[e2] = lowB[e2] = 0;
229  }
230  }
231  else
232  {
233  upB[netArc] = 2; lowB[netArc] = 0;
234  edge e2 = aTwin[netArc];
235  if (e2)
236  {
237  upB[e2] = 2;
238  lowB[e2] = 0;
239  }
240 
241  }
242  break;
243  case 90:
244  if (maxBound)
245  {
246  lowB[netArc] = 1;
247  upB[netArc] = 2;
248  edge e2 = aTwin[netArc];
249  if (e2)
250  {
251  upB[e2] = lowB[e2] = 0;
252  }
253  }
254  else
255  {
256  upB[netArc] = 1;
257  lowB[netArc] = 0;
258  edge e2 = aTwin[netArc];
259  if (e2)
260  {
261  upB[e2] = 2;
262  lowB[e2] = 0;
263  }
264 
265  }
266  break;
267  case 180:
268  if (maxBound)
269  {
270  lowB[netArc] = 0;
271  upB[netArc] = 2;
272  edge e2 = aTwin[netArc];
273  if (e2)
274  {
275  upB[e2] = lowB[e2] = 0;
276  }
277  }
278  else
279  {
280  upB[netArc] = 0;
281  lowB[netArc] = 0;
282  edge e2 = aTwin[netArc];
283  if (e2)
284  {
285  upB[e2] = 2;
286  lowB[e2] = 0;
287  }
288 
289  }
290  break;
292  }//switch
293  }//progressive
294 
295  }//setAngle
296 };
297 
298 
299 } // end namespace ogdf
300 
301 
302 #endif