Open
Graph Drawing
Framework

 v.2010.10
 

PlanarizationLayout.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  
00053 #ifdef _MSC_VER
00054 #pragma once
00055 #endif
00056 
00057 #ifndef OGDF_UML_PLANARIZATION_LAYOUT_H
00058 #define OGDF_UML_PLANARIZATION_LAYOUT_H
00059 
00060 
00061 
00062 #include <ogdf/module/UMLLayoutModule.h>
00063 #include <ogdf/module/PlanarSubgraphModule.h>
00064 #include <ogdf/module/EdgeInsertionModule.h>
00065 #include <ogdf/module/LayoutPlanRepModule.h>
00066 #include <ogdf/module/CCLayoutPackModule.h>
00067 #include <ogdf/basic/ModuleOption.h>
00068 #include <ogdf/module/EmbedderModule.h>
00069 #include <ogdf/basic/HashArray.h>
00070 
00071 
00072 
00073 namespace ogdf {
00074 
00075 
00151 class OGDF_EXPORT PlanarizationLayout : public UMLLayoutModule
00152 {
00153 public:
00155     PlanarizationLayout();
00156 
00157     // destructor
00158     virtual ~PlanarizationLayout() { }
00159 
00170     void call(GraphAttributes &GA) {
00171         doSimpleCall(&GA, 0);
00172     }
00173 
00179     virtual void call(UMLGraph &umlGraph);
00180 
00182     void simpleCall(UMLGraph &umlGraph) {
00183         doSimpleCall(&umlGraph, &umlGraph);
00184     }
00185 
00187     virtual void callSimDraw(UMLGraph &umlGraph);
00188 
00196     virtual void callFixEmbed(UMLGraph &umlGraph);
00197 
00198     //call with information about objects that should be
00199     //fixed as much as possible in the old/new drawing
00200     //for incremental drawing: takes a fixed part of the input
00201     //graph (indicated by fixedNodes(Edges)==true), embeds it using
00202     //the input layout, then inserts the remaining part into this embedding
00203     virtual void callIncremental(UMLGraph &umlgraph,
00204         NodeArray<bool> &fixedNodes, const EdgeArray<bool> &fixedEdges);
00205 
00206 
00218     double pageRatio() const {
00219         return m_pageRatio;
00220     }
00221 
00223     void pageRatio(double ratio) {
00224         m_pageRatio = ratio;
00225     }
00226 
00236     bool preprocessCliques() const {
00237         return m_processCliques;
00238     }
00239 
00241     void preprocessCliques(bool b) {
00242         m_processCliques = b;
00243     }
00244 
00251     int minCliqueSize() const {
00252         return m_cliqueSize;
00253     }
00254 
00256     void minCliqueSize(int i) {
00257         m_cliqueSize = max(i, 3);
00258     }
00259 
00260     //set the option field for the orthogonal layouter
00261     void setLayouterOptions(int ops)
00262     {m_planarLayouter.get().setOptions(ops);}
00263 
00264     //draw hierarchy nodes corresponding to their level
00265     void alignSons(bool b) 
00266     {
00267         int opts = m_planarLayouter.get().getOptions();
00268 
00269         if (b) m_planarLayouter.get().setOptions(opts | umlOpAlign); 
00270         else  m_planarLayouter.get().setOptions(opts & ~umlOpAlign);
00271     }
00272 
00273 
00285     void setSubgraph(PlanarSubgraphModule *pSubgraph) {
00286         m_subgraph.set(pSubgraph);
00287     }
00288 
00297     void setInserter(EdgeInsertionModule *pInserter) {
00298         m_inserter.set(pInserter);
00299     }
00300 
00308     void setEmbedder(EmbedderModule *pEmbedder) {
00309         m_embedder.set(pEmbedder);
00310     }
00311 
00322     void setPlanarLayouter(LayoutPlanRepModule *pPlanarLayouter) {
00323         m_planarLayouter.set(pPlanarLayouter);
00324     }
00325 
00333     void setPacker(CCLayoutPackModule *pPacker) {
00334         m_packer.set(pPacker);
00335     }
00336 
00342 
00343     int numberOfCrossings() const {
00344         return m_nCrossings;
00345     }
00346 
00348     void assureDrawability(UMLGraph& umlGraph);
00349 
00351 
00352 protected:
00353     void doSimpleCall(GraphAttributes *pGA, UMLGraph *pUmlGraph);
00354 
00355     //sorts the additional nodes for piecewise insertion
00356     void sortIncrementalNodes(List<node> &addNodes, const NodeArray<bool> &fixedNodes);
00357     void getFixationDistance(node startNode, HashArray<int, int> &distance,
00358         const NodeArray<bool> &fixedNodes);
00359     //reembeds already planarized PG in case of errors
00360     void reembed(PlanRepUML &PG, int ccNumber, bool l_align = false, 
00361         bool l_gensExist = false);
00362 
00363     virtual void preProcess(UMLGraph &UG);
00364     virtual void postProcess(UMLGraph& UG); //redo changes at original
00365 
00366     //collect and store nodes around center in correct order
00367     void fillAdjNodes(List<node>& adjNodes, PlanRepUML& PG, node centerNode, 
00368         NodeArray<bool>& isClique, Layout& drawing);
00369 
00370     void arrangeCCs(PlanRep &PG, GraphAttributes &GA, Array<DPoint> &boundingBox);
00371 
00372 private:
00374     ModuleOption<PlanarSubgraphModule> m_subgraph;
00375 
00377     ModuleOption<EdgeInsertionModule>  m_inserter;
00378 
00380     ModuleOption<EmbedderModule>       m_embedder;
00381 
00383     ModuleOption<LayoutPlanRepModule>  m_planarLayouter;
00384 
00386     ModuleOption<CCLayoutPackModule>   m_packer;
00387 
00388     double m_pageRatio;    
00389     int m_nCrossings;      
00390     bool m_arrangeLabels;  
00391     bool m_processCliques; 
00392     int m_cliqueSize;      
00393 
00394     // temporary changes to avoid errors
00395     List<edge> m_fakedGens; // made to associations
00396     bool m_fakeTree;
00397 
00398     face findBestExternalFace(
00399         const PlanRep &PG,
00400         const CombinatorialEmbedding &E);
00401 };
00402 
00403 
00404 //--------------------------------------------------------
00405 //incremental part
00406 
00408 class AddNodeComparer
00409 {
00410     HashArray<int, int> *m_indToDeg;
00411 
00412 public:
00413     AddNodeComparer(HashArray<int, int> &ha) : m_indToDeg(&ha) { }
00414 
00415     int compare(const node &v1, const node &v2) const {
00416         if ((*m_indToDeg)[v1->index()] < (*m_indToDeg)[v2->index()])
00417             return 1;
00418         else if ((*m_indToDeg)[v1->index()] > (*m_indToDeg)[v2->index()])
00419             return -1;
00420         else
00421             return 0;
00422     }
00423     
00424     OGDF_AUGMENT_COMPARER(node)
00425 };
00426 
00427 
00428 } // end namespace ogdf
00429 
00430 
00431 #endif