Open
Graph Drawing
Framework

 v.2012.05
 

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