Open
Graph Drawing
Framework

 v.2012.05
 

PlanRep.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 //PlanRep should not know about generalizations and association,
00045 //but we already set types in Attributedgraph, therefore set them 
00046 //in PlanRep, too
00047 
00048 #ifdef _MSC_VER
00049 #pragma once
00050 #endif
00051 
00052 #ifndef OGDF_PLANREP_H
00053 #define OGDF_PLANREP_H
00054 
00055 
00056 #include <ogdf/basic/GraphCopy.h>
00057 #include <ogdf/planarity/EdgeTypePatterns.h>
00058 #include <ogdf/planarity/NodeTypePatterns.h>
00059 #include <ogdf/basic/Layout.h>
00060 #include <ogdf/orthogonal/OrthoRep.h>
00061 #include <ogdf/basic/GraphAttributes.h>
00062 
00063 
00064 namespace ogdf {
00065 
00066 
00073 class OGDF_EXPORT PlanRep : public GraphCopy
00074 {
00075 public:
00077     struct Deg1RestoreInfo
00078     {
00079         Deg1RestoreInfo() : m_eOriginal(0), m_deg1Original(0), m_adjRef(0) { }
00080         Deg1RestoreInfo(edge eOrig, node deg1Orig, adjEntry adjRef)
00081             : m_eOriginal(eOrig), m_deg1Original(deg1Orig), m_adjRef(adjRef) { }
00082 
00083         edge m_eOriginal;    
00084         node m_deg1Original; 
00085         adjEntry m_adjRef;   
00086     };
00087 
00088 
00089     /* @{
00090      * \brief Creates a planarized representation of graph \a G.
00091      */
00092     PlanRep(const Graph& G);
00093 
00097     PlanRep(const GraphAttributes& AG);
00098 
00099     virtual ~PlanRep() {}
00100 
00101 
00103 
00109 
00113     int numberOfCCs() const {
00114         return m_nodesInCC.size();
00115     }
00116 
00120     int currentCC() const {
00121         return m_currentCC;
00122     }
00123 
00129     const List<node> &nodesInCC(int i) const {
00130         return m_nodesInCC[i];
00131     }
00132 
00136     const List<node> &nodesInCC() const {
00137         return m_nodesInCC[m_currentCC];
00138     }
00139 
00148     void initCC(int i);
00149 
00150 
00152 
00156 
00162     adjEntry expandAdj(node v) const {
00163         return m_expandAdj[v];
00164     }
00165 
00166     adjEntry& expandAdj(node v) {
00167         return m_expandAdj[v];
00168     }
00169 
00171 
00175 
00180     adjEntry boundaryAdj(node v) const {
00181         return m_boundaryAdj[v];
00182     }
00183 
00188     adjEntry& boundaryAdj(node v){
00189         return m_boundaryAdj[v];
00190     }
00191 
00192     //edge on the clique boundary, adjSource
00193     void setCliqueBoundary(edge e) {
00194         setEdgeTypeOf(e, edgeTypeOf(e) | cliquePattern());
00195     }
00196     bool isCliqueBoundary(edge e) {
00197         return ((edgeTypeOf(e) & cliquePattern()) == cliquePattern());
00198     }
00199 
00200 
00202 
00206 
00211     Graph::NodeType typeOf(node v) const {
00212         return m_vType[v];
00213     }
00214 
00219    Graph::NodeType& typeOf(node v) {
00220         return m_vType[v];
00221     }
00222 
00231     inline bool isVertex(node v)
00232     {
00233         return ( (typeOf(v) == Graph::vertex) ||
00234             (typeOf(v) == Graph::associationClass));
00235     }
00236 
00241     nodeType nodeTypeOf(node v)
00242     {
00243         return m_nodeTypes[v];
00244     }
00245 
00250     void setCrossingType(node v)
00251     {
00252         m_nodeTypes[v] |= ntTerCrossing << ntoTertiary;
00253     }
00254 
00259     bool isCrossingType(node v)
00260     {
00261         return (m_nodeTypes[v] &= (ntTerCrossing << ntoTertiary)) != 0;
00262     }
00263 
00265 
00269 
00274     EdgeType typeOf(edge e) const {
00275         return m_eType[e];
00276     }
00277 
00282     EdgeType& typeOf(edge e) {
00283         return m_eType[e];
00284     }
00285 
00290     edgeType& oriEdgeTypes(edge e)
00291     {
00292         return m_oriEdgeTypes[e];
00293     }
00294 
00299     edgeType edgeTypeOf(edge e) 
00300     {
00301         return m_edgeTypes[e];
00302     }
00303 
00308     edgeType& edgeTypes(edge e)
00309     {
00310         return m_edgeTypes[e];
00311     }
00312 
00318     void setEdgeTypeOf(edge e, edgeType et) 
00319     {
00320         m_edgeTypes[e] = et;
00321     }
00322 
00331     void setType(edge e, EdgeType et)
00332     {
00333         m_eType[e] = et;
00334         switch (et)
00335         {
00336             case Graph::association: m_edgeTypes[e] = etcPrimAssociation;break;
00337             case Graph::generalization: m_edgeTypes[e] = etcPrimGeneralization; 
00338                 break;
00339             case Graph::dependency: m_edgeTypes[e] = etcPrimDependency; break;
00340             default: break;
00341         }
00342     }
00343 
00344     //-------------------------------------------------------------------------
00345     //new edge types
00346     //to set or check edge types use the pattern function in the private section
00347 
00348     //-------------------
00349     //primary level types
00350 
00352     bool isGeneralization(edge e) {
00353         bool check = (((m_edgeTypes[e] & etpPrimary) & etcPrimGeneralization) == etcPrimGeneralization);
00354         return check;
00355     }
00356 
00358     void setGeneralization(edge e) {
00359         setPrimaryType(e, etcPrimGeneralization);
00360 
00361         //preliminary set old array too
00362         m_eType[e] = generalization; //can be removed if edgetypes work properly
00363     }
00364 
00366     bool isDependency(edge e) {
00367         bool check = (((m_edgeTypes[e] & etpPrimary) & etcPrimDependency) == etcPrimDependency);
00368         return check;
00369     }
00370 
00372     void setDependency(edge e) {
00373         setPrimaryType(e, etcPrimDependency);
00374 
00375         //preliminary set old array too
00376         m_eType[e] = dependency; //can be removed if edgetypes work properly
00377     }
00378 
00380     void setAssociation(edge e) {
00381         setPrimaryType(e, etcPrimAssociation);
00382 
00383         //preliminary set old array too
00384         m_eType[e] = association; //can be removed if edgetypes work properly
00385     }
00386 
00387     //------------------
00388     //second level types
00389 
00390     //in contrast to setsecondarytype: do not delete old value
00391 
00393     void setExpansion(edge e) {
00394         m_edgeTypes[e] |= expansionPattern();
00395 
00396         //preliminary set old array too
00397         m_expansionEdge[e] = 1;//can be removed if edgetypes work properly
00398     }
00399 
00401     bool isExpansion(edge e) {
00402         return ((m_edgeTypes[e] & expansionPattern()) == expansionPattern());
00403     }
00404 
00405     //should add things like cluster and clique boundaries that need rectangle shape
00406 
00408     bool isBoundary(edge e) {
00409         return isCliqueBoundary(e); }
00410 
00411     //--------------
00412     //tertiary types
00413 
00415     void setAssClass(edge e)
00416     {
00417         m_edgeTypes[e] |= assClassPattern();
00418     }
00419 
00421     bool isAssClass(edge e)
00422     {
00423         return ((m_edgeTypes[e] & assClassPattern()) == assClassPattern());
00424     }
00425 
00426 
00427     //------------------
00428     //fourth level types
00429 
00431     void setBrother(edge e) {
00432         m_edgeTypes[e] |= brotherPattern();
00433     }
00434 
00436     void setHalfBrother(edge e) {
00437         m_edgeTypes[e] |= halfBrotherPattern();
00438     }
00439 
00441     bool isBrother(edge e) {
00442         return ( (((m_edgeTypes[e] & etpFourth) & brotherPattern())>> etoFourth) == etcBrother);
00443     }
00444 
00446     bool isHalfBrother(edge e) {
00447         return ( (((m_edgeTypes[e] & etpFourth) & halfBrotherPattern())>> etoFourth) == etcHalfBrother);
00448     }
00449 
00450     //-----------------
00451     //set generic types
00452 
00453     edgeType edgeTypeAND(edge e, edgeType et) {m_edgeTypes[e] &= et; return m_edgeTypes[e];}
00454 
00455     edgeType edgeTypeOR(edge e, edgeType et) {m_edgeTypes[e] |= et; return m_edgeTypes[e];}
00456 
00457     //set primary edge type of edge e to primary edge type in et
00458     //deletes old primary value
00459     void setPrimaryType(edge e, edgeType et) {m_edgeTypes[e] &= 0xfffffff0; 
00460                                               m_edgeTypes[e] |= (etpPrimary & et); } 
00461 
00462     void setSecondaryType(edge e, edgeType et) {m_edgeTypes[e] &= 0xffffff0f; 
00463                                                 m_edgeTypes[e] |= (etpSecondary & ( et << etoSecondary)); }
00464 
00465     //sets primary type to bitwise AND of et's primary value and old value
00466     edgeType edgeTypePrimaryAND(edge e, edgeType et) {m_edgeTypes[e] &= (etpAll & et); return m_edgeTypes[e];}    
00467 
00468     //sets primary type to bitwise OR of et's primary value and old value
00469     edgeType edgeTypePrimaryOR(edge e, edgeType et) {m_edgeTypes[e] |= et; return m_edgeTypes[e];}
00470 
00471     //set user defined type locally
00472     void setUserType(edge e, edgeType et)
00473     {   
00474         OGDF_ASSERT( et < 147);
00475         m_edgeTypes[e] |= (et << etoUser);
00476     }
00477 
00478     bool isUserType(edge e, edgeType et)
00479     {
00480         OGDF_ASSERT( et < 147);
00481         return ( (m_edgeTypes[e] & (et << etoUser)) == (et << etoUser));
00482     }
00483 
00484     //---------------
00485     //
00486     // old edge types
00487 
00488     //this is pure nonsense, cause we have uml-edgetype and m_etype, and should be able to 
00489     //use them with different types, but as long as they arent used correctly (switch instead of xor),
00490     //use this function to return if e is expansionedge
00491     //if it is implemented correctly later, delete the array and return m_etype == Graph::expand
00492     //(the whole function then is obsolete, cause you can check it directly, but for convenience...)
00493     //should use genexpand, nodeexpand, dissect instead of bool
00494     void setExpansionEdge(edge e, int expType) {
00495         m_expansionEdge[e] = expType;
00496         }
00497 
00498     bool isExpansionEdge(edge e) const {
00499         return (m_expansionEdge[e] > 0);
00500     }
00501 
00502     int expansionType(edge e) const { return m_expansionEdge[e]; }
00503 
00504     //precondition normalized
00505     bool isDegreeExpansionEdge(edge e) const {
00506         //return (m_eType[e] == Graph::expand);
00507         return ( m_expansionEdge[e]  == 2);
00508     }
00509 
00510 
00512 
00518 
00519 
00521     const NodeArray<double> &widthOrig() const {
00522         return m_pGraphAttributes->width();
00523     }
00524 
00526     double widthOrig(node v) const {
00527         return m_pGraphAttributes->width(v);
00528     }
00529 
00531     const NodeArray<double> &heightOrig() const {
00532         return m_pGraphAttributes->height();
00533     }
00534 
00536     double heightOrig(node v) const {
00537         return m_pGraphAttributes->height(v);
00538     }
00539 
00541     EdgeType typeOrig(edge e) const {
00542         return m_pGraphAttributes->type(e);
00543     }
00544 
00546     const GraphAttributes &getGraphAttributes() const {
00547         return *m_pGraphAttributes;
00548     }
00549 
00551 
00555 
00556     // Expands nodes with degree > 4 and merge nodes for generalizations
00557     void expand(bool lowDegreeExpand = false);
00558 
00559     void expandLowDegreeVertices(OrthoRep &OR);
00560 
00561     void collapseVertices(const OrthoRep &OR, Layout &drawing);
00562 
00563     void removeCrossing(node v); //removes the crossing at node v
00564 
00565     //model a boundary around a star subgraph centered at center
00566     //and keep external face information (outside the clique
00567     void insertBoundary(node center, adjEntry& adjExternal);
00568 
00569 
00571 
00575 
00577     virtual edge split(edge e);
00578 
00579 
00580     //returns node which was expanded using v
00581     node expandedNode(node v) const { return m_expandedNode[v]; }
00582 
00583     void setExpandedNode(node v, node w) { m_expandedNode[v] = w; }
00584 
00585 
00587 
00591 
00597     node newCopy(node vOrig, Graph::NodeType vType);
00598 
00606     edge newCopy(node v, adjEntry adjAfter, edge eOrig);
00607 
00616     edge newCopy(node v, adjEntry adjAfter, edge eOrig, CombinatorialEmbedding &E);
00617 
00618 
00620 
00624 
00625     // embeds current copy
00626     bool embed();
00627 
00628     // removes all crossing nodes which are actually only two "touching" edges
00629     void removePseudoCrossings();
00630 
00631     // re-inserts edge eOrig by "crossing" the edges in crossedEdges;
00632     // splits each edge in crossedEdges
00633     // Precond.: eOrig is an edge in the original graph,
00634     //           the edges in crossedEdges are in this graph
00635     void insertEdgePath(edge eOrig, const SList<adjEntry> &crossedEdges);
00636 
00637     // same as insertEdgePath, but assumes that the graph is embedded
00638     void insertEdgePathEmbedded(
00639         edge eOrig,
00640         CombinatorialEmbedding &E,
00641         const SList<adjEntry> &crossedEdges);
00642 
00643     // removes the complete edge path for edge eOrig
00644     // Precond.: eOrig s an edge in the original graph
00645     void removeEdgePathEmbedded(CombinatorialEmbedding &E,
00646         edge eOrig,
00647         FaceSetPure &newFaces) {
00648         GraphCopy::removeEdgePathEmbedded(E,eOrig,newFaces);
00649     }
00650 
00651     //inserts crossings between two copy edges (used in TopologyModule)
00652     //replaces crossingedge by first crossingedge part and returns second.
00653     //the parameter topDown describes he following:
00654     // if the crossingEdge is running horizontally from left to right,
00655     // is the crossedEdge direction top->down?
00656     edge insertCrossing(edge& crossingEdge,
00657                         const edge crossedEdge,
00658                         bool topDown);
00659 
00661 
00666 
00674     void removeDeg1Nodes(Stack<Deg1RestoreInfo> &S, const NodeArray<bool> &mark);
00675 
00681     void restoreDeg1Nodes(Stack<Deg1RestoreInfo> &S, List<node> &deg1s);
00682 
00684 
00685 protected:
00686 
00687     int m_currentCC; 
00688     int m_numCC;     
00689 
00690     Array<List<node> >  m_nodesInCC; 
00691     
00692     const GraphAttributes* m_pGraphAttributes; 
00693 
00694     //------------
00695     //object types
00696 
00697     //set the type of eCopy according to the type of eOrig
00698     //should be virtual if PlanRepUML gets its own
00699     void setCopyType(edge eCopy, edge eOrig);
00700 
00701     //helper to cope with the edge types, shifting to the right place
00702     edgeType generalizationPattern() {return etcPrimGeneralization;}
00703     edgeType associationPattern()    {return etcPrimAssociation;}
00704     edgeType expansionPattern()      {return etcSecExpansion << etoSecondary;}
00705     edgeType assClassPattern()       {return etcAssClass << etoTertiary;}
00706     edgeType brotherPattern()        {return etcBrother   << etoFourth;}
00707     edgeType halfBrotherPattern()    {return etcHalfBrother   << etoFourth;}
00708     edgeType cliquePattern()         {return etcSecClique << etoSecondary;} //boundary
00709     
00710     
00711     void removeUnnecessaryCrossing(
00712         adjEntry adjA1,
00713         adjEntry adjA2,
00714         adjEntry adjB1,
00715         adjEntry adjB2);
00716 
00717 //--------------------------------------------------------------------------
00718 
00719     NodeArray<NodeType> m_vType; 
00720 
00721     NodeArray<nodeType> m_nodeTypes; 
00722 
00723     NodeArray<node>     m_expandedNode; 
00724     NodeArray<adjEntry> m_expandAdj;
00725 
00726     //clique handling: We save an adjEntry of the first edge of an inserted
00727     //boundary around a clique at its center v
00728     NodeArray<adjEntry> m_boundaryAdj;
00729 
00730     //zusammenlegbare Typen
00731     EdgeArray<int>      m_expansionEdge; //1 genmerge, 2 degree (2 highdegree, 3 lowdegree)
00732     EdgeArray<EdgeType> m_eType;
00733     
00734     //m_edgeTypes stores semantic edge type information on several levels: 
00735     //primary type: generalization, association,...
00736     //secondary type: merger,...
00737     //tertiary type: vertical in hierarchy, inner, outer, ...
00738     //fourth type: neighbour relation (brother, cousin in hierarchy)
00739     //user types: user defined for local changes
00740     EdgeArray<edgeType> m_edgeTypes; //store all type information
00741 
00742     //workaround fuer typsuche in insertedgepathembed
00743     //speichere kopietyp auf originalen
00744     //maybe it's enough to set gen/ass without extra array
00745     EdgeArray<edgeType> m_oriEdgeTypes;
00746 
00747     EdgeArray<edge>     m_eAuxCopy; // auxiliary (GraphCopy::initByNodes())
00748 
00749 };//PlanRep
00750 
00751 } // end namespace ogdf
00752 
00753 
00754 #endif