Open
Graph Drawing
Framework

 v.2012.05
 

PlanarizationLayout.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  
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046 
00047 #ifndef OGDF_UML_PLANARIZATION_LAYOUT_H
00048 #define OGDF_UML_PLANARIZATION_LAYOUT_H
00049 
00050 
00051 
00052 #include <ogdf/module/UMLLayoutModule.h>
00053 #include <ogdf/module/PlanarSubgraphModule.h>
00054 #include <ogdf/module/EdgeInsertionModule.h>
00055 #include <ogdf/module/LayoutPlanRepModule.h>
00056 #include <ogdf/module/CCLayoutPackModule.h>
00057 #include <ogdf/basic/ModuleOption.h>
00058 #include <ogdf/module/EmbedderModule.h>
00059 #include <ogdf/basic/HashArray.h>
00060 
00061 
00062 
00063 namespace ogdf {
00064 
00065 
00141 class OGDF_EXPORT PlanarizationLayout : public UMLLayoutModule
00142 {
00143 public:
00145     PlanarizationLayout();
00146 
00147     // destructor
00148     virtual ~PlanarizationLayout() { }
00149 
00160     void call(GraphAttributes &GA) {
00161         doSimpleCall(&GA);
00162     }
00163 
00169     virtual void call(UMLGraph &umlGraph);
00170 
00172     void simpleCall(UMLGraph &umlGraph) {
00173         //this simple call method does not care about any special treatments
00174         //of subgraphs, layout informations etc., therefore we save the
00175         //option status and set them back later on
00176         //cliques are only handled for UMLGraphs, so it is save to 
00177         //only set this value here and not in the GraphAtrtibutes interface method.
00178         bool l_saveCliqueHandling = m_processCliques;
00179         m_processCliques = false;
00180 
00181         //---------------------------------------------------
00182         // preprocessing: insert a merger for generalizations
00183         
00184         preProcess(umlGraph);
00185         umlGraph.insertGenMergers();
00186         
00187         doSimpleCall(&umlGraph);
00188 
00189         umlGraph.undoGenMergers();
00190 
00191         umlGraph.removeUnnecessaryBendsHV();
00192 
00193         postProcess(umlGraph);
00194 
00195         m_processCliques = l_saveCliqueHandling;
00196     }
00197 
00198     void simpleCall(GraphAttributes & GA)
00199     {
00200         doSimpleCall(&GA);
00201         GA.removeUnnecessaryBendsHV();
00202     }
00203 
00205     virtual void callSimDraw(UMLGraph &umlGraph);
00206 
00214     virtual void callFixEmbed(UMLGraph &umlGraph);
00215 
00216     //call with information about objects that should be
00217     //fixed as much as possible in the old/new drawing
00218     //for incremental drawing: takes a fixed part of the input
00219     //graph (indicated by fixedNodes(Edges)==true), embeds it using
00220     //the input layout, then inserts the remaining part into this embedding
00221     virtual void callIncremental(UMLGraph &umlgraph,
00222         NodeArray<bool> &fixedNodes, const EdgeArray<bool> &fixedEdges);
00223 
00224 
00236     double pageRatio() const {
00237         return m_pageRatio;
00238     }
00239 
00241     void pageRatio(double ratio) {
00242         m_pageRatio = ratio;
00243     }
00244 
00254     bool preprocessCliques() const {
00255         return m_processCliques;
00256     }
00257 
00259     void preprocessCliques(bool b) {
00260         m_processCliques = b;
00261     }
00262 
00269     int minCliqueSize() const {
00270         return m_cliqueSize;
00271     }
00272 
00274     void minCliqueSize(int i) {
00275         m_cliqueSize = max(i, 3);
00276     }
00277 
00278     //set the option field for the planar layouter
00279     void setLayouterOptions(int ops)
00280     {m_planarLayouter.get().setOptions(ops);}
00281 
00282     //draw hierarchy nodes corresponding to their level
00283     void alignSons(bool b) 
00284     {
00285         int opts = m_planarLayouter.get().getOptions();
00286 
00287         if (b) m_planarLayouter.get().setOptions(opts | umlOpAlign); 
00288         else  m_planarLayouter.get().setOptions(opts & ~umlOpAlign);
00289     }
00290 
00291 
00303     void setSubgraph(PlanarSubgraphModule *pSubgraph) {
00304         m_subgraph.set(pSubgraph);
00305     }
00306 
00315     void setInserter(EdgeInsertionModule *pInserter) {
00316         m_inserter.set(pInserter);
00317     }
00318 
00326     void setEmbedder(EmbedderModule *pEmbedder) {
00327         m_embedder.set(pEmbedder);
00328     }
00329 
00340     void setPlanarLayouter(LayoutPlanRepModule *pPlanarLayouter) {
00341         m_planarLayouter.set(pPlanarLayouter);
00342     }
00343 
00351     void setPacker(CCLayoutPackModule *pPacker) {
00352         m_packer.set(pPacker);
00353     }
00354 
00360 
00361     int numberOfCrossings() const {
00362         return m_nCrossings;
00363     }
00364 
00366     void assureDrawability(UMLGraph& umlGraph);
00367 
00369 
00370 protected:
00371     void doSimpleCall(GraphAttributes *pGA);
00372 
00373     //sorts the additional nodes for piecewise insertion
00374     void sortIncrementalNodes(List<node> &addNodes, const NodeArray<bool> &fixedNodes);
00375     void getFixationDistance(node startNode, HashArray<int, int> &distance,
00376         const NodeArray<bool> &fixedNodes);
00377     //reembeds already planarized PG in case of errors
00378     void reembed(PlanRepUML &PG, int ccNumber, bool l_align = false, 
00379         bool l_gensExist = false);
00380 
00381     virtual void preProcess(UMLGraph &UG);
00382     virtual void postProcess(UMLGraph& UG); //redo changes at original
00383 
00384     //collect and store nodes around center in correct order
00385     void fillAdjNodes(List<node>& adjNodes, PlanRepUML& PG, node centerNode, 
00386         NodeArray<bool>& isClique, Layout& drawing);
00387 
00388     void arrangeCCs(PlanRep &PG, GraphAttributes &GA, Array<DPoint> &boundingBox);
00389 
00390 private:
00392     ModuleOption<PlanarSubgraphModule> m_subgraph;
00393 
00395     ModuleOption<EdgeInsertionModule>  m_inserter;
00396 
00398     ModuleOption<EmbedderModule>       m_embedder;
00399 
00401     ModuleOption<LayoutPlanRepModule>  m_planarLayouter;
00402 
00404     ModuleOption<CCLayoutPackModule>   m_packer;
00405 
00406     double m_pageRatio;    
00407     int m_nCrossings;      
00408     bool m_arrangeLabels;  
00409     bool m_processCliques; 
00410     int m_cliqueSize;      
00411 
00412     // temporary changes to avoid errors
00413     List<edge> m_fakedGens; // made to associations
00414     bool m_fakeTree;
00415 
00416     face findBestExternalFace(
00417         const PlanRep &PG,
00418         const CombinatorialEmbedding &E);
00419 };
00420 
00421 
00422 //--------------------------------------------------------
00423 //incremental part
00424 
00426 class AddNodeComparer
00427 {
00428     HashArray<int, int> *m_indToDeg;
00429 
00430 public:
00431     AddNodeComparer(HashArray<int, int> &ha) : m_indToDeg(&ha) { }
00432 
00433     int compare(const node &v1, const node &v2) const {
00434         if ((*m_indToDeg)[v1->index()] < (*m_indToDeg)[v2->index()])
00435             return 1;
00436         else if ((*m_indToDeg)[v1->index()] > (*m_indToDeg)[v2->index()])
00437             return -1;
00438         else
00439             return 0;
00440     }
00441     
00442     OGDF_AUGMENT_COMPARER(node)
00443 };
00444 
00445 
00446 } // end namespace ogdf
00447 
00448 
00449 #endif