Open
Graph Drawing
Framework

 v.2010.10
 

ClusterOrthoShaper.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 2027 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2010-09-01 11:55:17 +0200 (Wed, 01 Sep 2010) $ 
00007  ***************************************************************/
00008  
00054 #ifdef _MSC_VER
00055 #pragma once
00056 #endif
00057 
00058 
00059 #ifndef OGDF_CLUSTER_ORTHO_FORMER_H
00060 #define OGDF_CLUSTER_ORTHO_FORMER_H
00061 
00062 
00063 #include <ogdf/orthogonal/OrthoRep.h>
00064 #include <ogdf/cluster/ClusterPlanRep.h>
00065 
00066 
00067 namespace ogdf {
00068 
00069 const bool angleMaxBound = true;
00070 const bool angleMinBound = false;
00071 
00072 enum bendCost {defaultCost, topDownCost, bottomUpCost};
00073 
00074 class OGDF_EXPORT ClusterOrthoShaper
00075 {
00076 
00077 public:
00078 
00079     enum n_type {low, high, inner, outer}; //types of network nodes: 
00080                                            //nodes and faces
00081 
00082     ClusterOrthoShaper() {
00083         m_distributeEdges = true; // true;  //try to distribute edges to all node sides
00084         m_fourPlanar      = true;  //do not allow zero degree angles at high degree
00085         m_allowLowZero    = false; //do allow zero degree at low degree nodes
00086         m_multiAlign      = true;//true;  //start/end side of multi edges match
00087         m_traditional     = true;//true;  //prefer 3/1 flow at degree 2 (false: 2/2)
00088         m_deg4free        = false; //allow free angle assignment at degree four
00089         m_align           = false; //align nodes on same hierarchy level
00090         m_topToBottom     = 0;     //bend costs depend on edges cluster depth
00091     };
00092 
00093     ~ClusterOrthoShaper() {};
00094 
00095     // Given a planar representation for a UML graph and its planar 
00096     // combinatorial embedding, call() produces an orthogonal 
00097     // representation using Tamassias bend minimization algorithm
00098     // with a flow network where every flow unit defines 90 degree angle
00099     // in traditional mode.
00100     // A maximum number of bends per edge can be specified in 
00101     // startBoundBendsPerEdge. If the algorithm is not successful in 
00102     // producing a bend minimal representation subject to 
00103     // startBoundBendsPerEdge, it successively enhances the bound by 
00104     // one trying to compute an orthogonal representation.
00105     //
00106     // Using startBoundBendsPerEdge may not produce a bend minimal
00107     // representation in general.
00108     void call(ClusterPlanRep &PG,
00109         CombinatorialEmbedding &E,
00110         OrthoRep &OR,
00111         int startBoundBendsPerEdge = 0,
00112         bool fourPlanar = true) throw(AlgorithmFailureException);
00113 
00114 
00115     // returns option distributeEdges
00116     bool distributeEdges() { return m_distributeEdges; }
00117     // sets option distributeEdges to b
00118     void distributeEdges(bool b) { m_distributeEdges = b; }
00119 
00120     // returns option multiAlign
00121     bool multiAlign() { return m_multiAlign; }
00122     // sets option multiAlign to b
00123     void multiAlign(bool b) { m_multiAlign = b; }
00124 
00125     // returns option traditional
00126     bool traditional() { return m_traditional; }
00127     // sets option traditional to b
00128     void traditional(bool b) { m_traditional = b; }
00129 
00130     //returns option deg4free
00131     bool fixDegreeFourAngles() { return m_deg4free; }
00132     //sets option deg4free
00133     void fixDegreeFourAngles(bool b) { m_deg4free = b; }
00134 
00135     //alignment of brothers in hierarchies
00136     void align(bool al) {m_align = al;}
00137     bool align() {return m_align;}
00138 
00139     void bendCostTopDown(int i) {m_topToBottom = i;}
00140 
00141     //return cluster dependant bend cost for standard cost pbc
00142     int clusterProgBendCost(int clDepth, int treeDepth, int pbc)
00143     {
00144         int cost = 1;
00145         switch (m_topToBottom)
00146         {
00147             case 1: //topDownCost
00148                         cost = pbc*(clDepth+1); //safeInt
00149                         break;
00150             case 2: //bottomUpCOst
00151                         cost = pbc*(treeDepth - clDepth + 1); //safeInt
00152                         break;
00153             default: //defaultCost
00154                         cost = pbc;
00155                         break;
00156         }
00157 
00158 //      cout<<"   Cost/pbc: "<<cost<<"/"<<pbc<<"\n";
00159 
00160         return cost;
00161     }
00162 
00163     //this is a try: I dont know why this was never implemented for traditional,
00164     //maybe because of the unit cost for traditional bends vs. the highbound
00165     //cost for progressive bends
00166     //return cluster dependant bend cost for standard cost pbc
00167     //preliminary same as progressive
00168     int clusterTradBendCost(int clDepth, int treeDepth, int pbc)
00169     {
00170         int cost = 1;
00171         switch (m_topToBottom)
00172         {
00173             case 1: //topDownCost
00174                         cost = pbc*(clDepth+1); //safeInt
00175                         break;
00176             case 2: //bottomUpCOst
00177                         cost = pbc*(treeDepth - clDepth + 1); //safeInt
00178                         break;
00179             default: //defaultCost
00180                         cost = pbc;
00181                         break;
00182         }
00183 
00184         return cost;
00185     }//clusterTradBendCost
00186 
00187 
00188 
00189 private:
00190     bool m_distributeEdges; // distribute edges among all sides if degree > 4
00191     bool m_fourPlanar;      // should the input graph be four planar 
00192                             // (no zero degree)
00193     bool m_allowLowZero;    // allow low degree nodes zero degree
00194                             // (to low for zero...)
00195     bool m_multiAlign;      // multi edges aligned on the same side
00196     bool m_deg4free;        // allow degree four nodes free angle assignment
00197     bool m_traditional;     // do not prefer 180 degree angles,
00198                             // traditional is not tamassia,
00199     // traditional is a kandinsky - ILP - like network with node supply 4,
00200     // not traditional interprets angle flow zero as 180 degree, "flow
00201     // through the node"
00202     bool m_align;           //try to achieve an alignment in hierarchy levels
00203 
00204     int m_topToBottom;      //change bend costs on cluster hierarchy levels
00205     //set angle boundary
00206     //warning: sets upper AND lower bounds, therefore may interfere with existing bounds
00207     void setAngleBound(edge netArc, int angle, EdgeArray<int>& lowB,
00208                   EdgeArray<int>& upB, EdgeArray<edge>& aTwin, bool maxBound = true)
00209     {
00210         //vorlaeufig
00211         OGDF_ASSERT(!m_traditional);
00212         if (m_traditional)
00213         {
00214             switch (angle)
00215             {
00216                 case 0:
00217                 case 90:
00218                 case 180:
00219                         break;
00220                 OGDF_NODEFAULT
00221             }//switch
00222         }//trad
00223         else
00224         {
00225             switch (angle)
00226             {
00227                 case 0: if (maxBound)
00228                         {
00229                             upB[netArc] = lowB[netArc] = 2;
00230                             edge e2 = aTwin[netArc];
00231                             if (e2) 
00232                             {
00233                                 upB[e2] = lowB[e2] = 0;
00234                             }
00235                         }
00236                         else
00237                         {
00238                             upB[netArc] = 2; lowB[netArc] = 0;
00239                             edge e2 = aTwin[netArc];
00240                             if (e2) 
00241                             {
00242                                 upB[e2] = 2;
00243                                 lowB[e2] = 0;
00244                             }
00245 
00246                         }
00247                        break;
00248                 case 90:
00249                         if (maxBound)
00250                         {
00251                             lowB[netArc] = 1;
00252                             upB[netArc] = 2;
00253                             edge e2 = aTwin[netArc];
00254                             if (e2) 
00255                             {
00256                                 upB[e2] = lowB[e2] = 0;
00257                             }
00258                         }
00259                         else
00260                         {
00261                             upB[netArc] = 1; 
00262                             lowB[netArc] = 0;
00263                             edge e2 = aTwin[netArc];
00264                             if (e2) 
00265                             {
00266                                 upB[e2] = 2;
00267                                 lowB[e2] = 0;
00268                             }
00269 
00270                         }
00271                         break;
00272                 case 180:
00273                         if (maxBound)
00274                         {
00275                             lowB[netArc] = 0;
00276                             upB[netArc] = 2;
00277                             edge e2 = aTwin[netArc];
00278                             if (e2) 
00279                             {
00280                                 upB[e2] = lowB[e2] = 0;
00281                             }
00282                         }
00283                         else
00284                         {
00285                             upB[netArc] = 0; 
00286                             lowB[netArc] = 0;
00287                             edge e2 = aTwin[netArc];
00288                             if (e2) 
00289                             {
00290                                 upB[e2] = 2;
00291                                 lowB[e2] = 0;
00292                             }
00293 
00294                         }
00295                         break;
00296                 OGDF_NODEFAULT
00297             }//switch       
00298         }//progressive
00299 
00300     }//setAngle
00301 };
00302 
00303 
00304 } // end namespace ogdf
00305 
00306 
00307 #endif