Open
Graph Drawing
Framework

 v.2012.05
 

TopologyModule.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  
00047 #ifdef _MSC_VER
00048 #pragma once
00049 #endif
00050 
00051 
00052 #ifndef OGDF_TOPOLOGYMODULE_H
00053 #define OGDF_TOPOLOGYMODULE_H
00054 
00055 
00056 
00057 #include <ogdf/planarity/PlanRep.h>
00058 #include <ogdf/basic/GraphAttributes.h>
00059 #include <ogdf/basic/EdgeComparer.h>
00060 
00061 namespace ogdf {
00062 
00063 class EdgeLeg;
00064 
00065 //===============================================
00066 //main function(s):
00067 //      setEmbeddingFromGraph(PlanRep&, GraphAttributes&)
00068 //      assumes that PG(AG) without bend nodes in PG
00069 //
00070 //      sortEdgesFromLayout(GraphAttributes &AG)
00071 //      sort the edges in AG, no crossing insertion
00072 //===============================================
00073 
00074 class OGDF_EXPORT TopologyModule 
00075 {
00076 public:
00077     TopologyModule() : m_options(opDegOneCrossings | opGenToAss | 
00078         opCrossFlip | opLoop | opFlipUML) {}
00079     virtual ~TopologyModule() {}
00080 
00081     //the (pre/post)processing options
00082     //opCrossFlip increases running time by const*n,
00083     //opLoop increases running time by const*m
00084     enum Options {
00085         opDegOneCrossings = 0x0001, //should degree one node's edge be crossed
00086         opGenToAss        = 0x0002, //should generalizations be turned into associations
00087         opCrossFlip       = 0x0004,//if there is a crossing (first ~) between two edges with
00088                                     //same start or end point, should there position
00089                                     //at the node be flipped and the crossing be skipped?
00090                                     //(postprocessing)
00091         opFlipUML         = 0x0010, //only flip if same edge type
00092         opLoop            = 0x0008  //should loops between crossings (consecutive on both 
00093                                     //crossing edges) be deleted (we dont check for enclosed
00094                                     //CC's. Therefore it is safe to remove the crossing
00095     };
00096 
00097     void setOptions(int i) {m_options = i;}
00098     void addOption(TopologyModule::Options o)  {m_options = (m_options | o);}
00099     //use AG layout to determine an embedding for PG.
00100     //non-constness of AG in the following methods is only
00101     //used when resolving problems, e.g. setting edge types
00102     //if two generalizations cross in the input layout
00103 
00104     //Parameter setExternal: run over faces to compute external face
00105     //Parameter reuseAGEmbedding: If true, the call only 
00106     //checks for a correct embedding of PG and tries to insert
00107     //crossings detected in the given layout otherwise.
00108     //this allows to assign already sorted UMLGraphs 
00109     //NOTE: if the sorting of the edges does not correspond
00110     //to the layout given in AG, this cannot work correctly
00111     //returns false if planarization fails
00112     bool setEmbeddingFromGraph(PlanRep &PG, 
00113                                GraphAttributes &AG,
00114                                adjEntry &adjExternal,
00115                                bool setExternal = true,
00116                                bool reuseAGEmbedding = false);
00117 
00118     //sorts the edges around all nodes of AG corresponding to the
00119     //layout given in AG
00120     //there is no check of the embedding afterwards because this
00121     //method could be used as a first step of a planarization
00122     void sortEdgesFromLayout(Graph &G, GraphAttributes &AG);
00123 
00124     face getExternalFace(PlanRep &PG, const GraphAttributes &AG);
00125 
00126     double faceSum(PlanRep &PG, const GraphAttributes &AG, face f);
00127 
00128 protected:
00129     //compute a planarization, i.e. insert crossing vertices,
00130     //corresponding to the AG layout 
00131     void planarizeFromLayout(PlanRep &PG,
00132                              GraphAttributes &AG);
00133     //compute crossing point and return if existing
00134     bool hasCrossing(EdgeLeg* legA, EdgeLeg* legB, DPoint& xp);
00135     //check if node v is a crossing of two edges with a common
00136     //endpoint adjacent to v, crossing is removed if flip is set
00137     bool checkFlipCrossing(PlanRep &PG,node v, bool flip = true);
00138 
00139     void postProcess(PlanRep &PG);
00140     void handleImprecision(PlanRep &PG);
00141     bool skipable(EdgeLeg* legA, EdgeLeg* legB);
00142 
00143 private:
00144     //compare vectors for sorting
00145     int compare_vectors(const double& x1, const double& y1, 
00146                         const double& x2, const double& y2);
00147     //compute and return the angle defined by p-q,p-r
00148     double angle(DPoint p, DPoint q, DPoint r);
00149     //we have to save the position of the inserted crossing vertices
00150     //in order to compute the external face
00151     NodeArray<DPoint> m_crossPosition;
00152 
00153     //we save a list of EdgeLegs for all original edges in 
00154     //AG
00155     EdgeArray< List<EdgeLeg*> > m_eLegs;
00156 
00157 
00158     //option settings as bits
00159     int m_options;
00160 
00161 };//TopologyModule
00162 
00163 
00164 //sorts EdgeLegs according to their xp distance to a reference point
00165 class PointComparer {
00166 public: 
00167     PointComparer(DPoint refPoint) : m_refPoint(refPoint) {}
00168     //compares the crossing points stored in the EdgeLeg
00169     int compare(const ListIterator<EdgeLeg*> &ep1, 
00170         const ListIterator<EdgeLeg*> &ep2) const;
00171     OGDF_AUGMENT_COMPARER(ListIterator<EdgeLeg*>)
00172 
00173     // undefined methods to avoid automatic creation
00174     PointComparer &operator=(const PointComparer &);
00175 
00176 private:
00177     const DPoint m_refPoint;
00178 };//PointComparer
00179 
00180 //helper class for the computation of crossings
00181 //represents a part of the edge between two consecutive
00182 //bends (in the layout, there are no bends allowed in
00183 //the representation) or crossings
00184 //there can be multiple EdgeLegs associated to one copy
00185 //edge in the PlanRep because of bends
00186 class EdgeLeg 
00187 {
00188 public:
00189     EdgeLeg() : m_topDown(false)
00190         {m_copyEdge = 0; m_xp = DPoint(0.0, 0.0);}
00191     EdgeLeg(edge e, int number, DPoint p1, DPoint p2) :
00192         m_xp(DPoint(0.0,0.0)), m_topDown(false),
00193         m_copyEdge(e), m_p1(p1), m_p2(p2), m_number(number)
00194         {}
00195 
00196     DPoint& start() {return m_p1;}
00197     DPoint& end()   {return m_p2;}
00198     int& number()    {return m_number;}
00199     edge& copyEdge() { return m_copyEdge;} 
00200 
00201     //to avoid sorting both edgelegs and crossing points,
00202     //do not store a pair of them, but allow the xp to be
00203     //stored in the edgeleg
00204     DPoint m_xp;
00205     //we store the direction of the crossed EdgeLeg, too
00206     //if crossingEdgeLeg is horizontally left to right
00207     bool m_topDown;
00208 
00209     //each edgeLeg holds an entry with a ListIterator pointing to
00210     //its entry in a <edgeLeg*> List for an original edge
00211     ListIterator< EdgeLeg* > m_eIterator;
00212 
00213 private:
00214     edge m_copyEdge; //the edge in the PlanRep copy corresponding
00215                      //to the EdgeLeg
00216     DPoint m_p1, m_p2;  //"Starting" and "End" point of the EdgeLeg
00217     int    m_number;    //the order nuumber on the edge, starting at 0
00218 
00219 };//edgeleg
00220 
00221 
00222 /*
00223 EdgeArray<ListIterator<edge> > m_eIterator; // position of copy edge in chain
00224 
00225     NodeArray<node> m_vCopy; // corresponding node in graph copy
00226     EdgeArray<List<edge> > m_eCopy; // corresponding chain of edges in graph copy
00227 
00228 */
00229 } // end namespace ogdf
00230 
00231 #endif