Open
Graph Drawing
Framework

 v.2007.11
 

PlanRep.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 1.14 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2007-11-08 16:10:37 +0100 (Do, 08 Nov 2007) $ 
00007  ***************************************************************/
00008  
00052 //PlanRep should not know about generalizations and association,
00053 //but we already set types in Attributedgraph, therefore set them 
00054 //in PlanRep, too
00055 
00056 #ifdef _MSC_VER
00057 #pragma once
00058 #endif
00059 
00060 #ifndef OGDF_PLANREP_H
00061 #define OGDF_PLANREP_H
00062 
00063 
00064 #include <ogdf/basic/GraphCopy.h>
00065 #include <ogdf/planarity/EdgeTypePatterns.h>
00066 #include <ogdf/planarity/NodeTypePatterns.h>
00067 #include <ogdf/basic/Layout.h>
00068 #include <ogdf/orthogonal/OrthoRep.h>
00069 #include <ogdf/basic/GraphAttributes.h>
00070 
00071 
00072 namespace ogdf {
00073 
00074 
00081 class PlanRep : public GraphCopy
00082 {
00083 public:
00085     struct Deg1RestoreInfo
00086     {
00087         Deg1RestoreInfo() : m_eOriginal(0), m_deg1Original(0), m_adjRef(0) { }
00088         Deg1RestoreInfo(edge eOrig, node deg1Orig, adjEntry adjRef)
00089             : m_eOriginal(eOrig), m_deg1Original(deg1Orig), m_adjRef(adjRef) { }
00090 
00091         edge m_eOriginal;    
00092         node m_deg1Original; 
00093         adjEntry m_adjRef;   
00094     };
00095 
00096 
00097     /* @{
00098      * \brief Creates a planarized representation of graph \a G.
00099      */
00100     PlanRep(const Graph& G);
00101 
00105     PlanRep(const GraphAttributes& AG);
00106 
00107     virtual ~PlanRep() {}
00108 
00109 
00111 
00117 
00121     int numberOfCCs() const {
00122         return m_nodesInCC.size();
00123     }
00124 
00128     int currentCC() const {
00129         return m_currentCC;
00130     }
00131 
00137     const List<node> &nodesInCC(int i) const {
00138         return m_nodesInCC[i];
00139     }
00140 
00144     const List<node> &nodesInCC() const {
00145         return m_nodesInCC[m_currentCC];
00146     }
00147 
00156     void initCC(int i);
00157 
00158 
00160 
00164 
00170     adjEntry expandAdj(node v) const {
00171         return m_expandAdj[v];
00172     }
00173 
00174     adjEntry& expandAdj(node v) {
00175         return m_expandAdj[v];
00176     }
00177 
00179 
00183 
00188     adjEntry boundaryAdj(node v) const {
00189         return m_boundaryAdj[v];
00190     }
00191 
00196     adjEntry& boundaryAdj(node v){
00197         return m_boundaryAdj[v];
00198     }
00199 
00200     //edge on the clique boundary, adjSource
00201     void setCliqueBoundary(edge e) {
00202         setEdgeTypeOf(e, edgeTypeOf(e) | cliquePattern());
00203     }
00204     bool isCliqueBoundary(edge e) {
00205         return ((edgeTypeOf(e) & cliquePattern()) == cliquePattern());
00206     }
00207 
00208 
00210 
00214 
00219     Graph::NodeType typeOf(node v) const {
00220         return m_vType[v];
00221     }
00222 
00227    Graph::NodeType& typeOf(node v) {
00228         return m_vType[v];
00229     }
00230 
00239     inline bool isVertex(node v)
00240     {
00241         return ( (typeOf(v) == Graph::vertex) ||
00242             (typeOf(v) == Graph::associationClass));
00243     }
00244 
00249     nodeType nodeTypeOf(node v)
00250     {
00251         return m_nodeTypes[v];
00252     }
00253 
00258     void setCrossingType(node v)
00259     {
00260         m_nodeTypes[v] |= ntTerCrossing << ntoTertiary;
00261     }
00262 
00267     bool isCrossingType(node v)
00268     {
00269         return (m_nodeTypes[v] &= (ntTerCrossing << ntoTertiary)) != 0;
00270     }
00271 
00273 
00277 
00282     EdgeType typeOf(edge e) const {
00283         return m_eType[e];
00284     }
00285 
00290     EdgeType& typeOf(edge e) {
00291         return m_eType[e];
00292     }
00293 
00298     edgeType& oriEdgeTypes(edge e)
00299     {
00300         return m_oriEdgeTypes[e];
00301     }
00302 
00307     edgeType edgeTypeOf(edge e) 
00308     {
00309         return m_edgeTypes[e];
00310     }
00311 
00316     edgeType& edgeTypes(edge e)
00317     {
00318         return m_edgeTypes[e];
00319     }
00320 
00326     void setEdgeTypeOf(edge e, edgeType et) 
00327     {
00328         m_edgeTypes[e] = et;
00329     }
00330 
00339     void setType(edge e, EdgeType et)
00340     {
00341         m_eType[e] = et;
00342         switch (et)
00343         {
00344             case Graph::association: m_edgeTypes[e] = etcPrimAssociation;break;
00345             case Graph::generalization: m_edgeTypes[e] = etcPrimGeneralization; 
00346                 break;
00347             case Graph::dependency: m_edgeTypes[e] = etcPrimDependency; break;
00348             default: break;
00349         }
00350     }
00351 
00352     //-------------------------------------------------------------------------
00353     //new edge types
00354     //to set or check edge types use the pattern function in the private section
00355 
00356     //-------------------
00357     //primary level types
00358 
00360     bool isGeneralization(edge e) {
00361         bool check = (((m_edgeTypes[e] & etpPrimary) & etcPrimGeneralization) == etcPrimGeneralization);
00362         //bool checkb = (m_eType[e] == Graph::generalization);
00363         //OGDF_ASSERT( (check && checkb) || ((!check && !checkb)));
00364         return check;
00365     }
00366 
00368     void setGeneralization(edge e) {
00369         setPrimaryType(e, etcPrimGeneralization);
00370 
00371         //preliminary set old array too
00372         m_eType[e] = generalization; //can be removed if edgetypes work properly
00373     }
00374 
00376     bool isDependency(edge e) {
00377         bool check = (((m_edgeTypes[e] & etpPrimary) & etcPrimDependency) == etcPrimDependency);
00378         //bool checkb = (m_eType[e] == Graph::dependency);
00379         //OGDF_ASSERT( (check && checkb) || ((!check && !checkb)));
00380         return check;
00381     }
00382 
00384     void setDependency(edge e) {
00385         setPrimaryType(e, etcPrimDependency);
00386 
00387         //preliminary set old array too
00388         m_eType[e] = dependency; //can be removed if edgetypes work properly
00389     }
00390 
00392     void setAssociation(edge e) {
00393         setPrimaryType(e, etcPrimAssociation);
00394 
00395         //preliminary set old array too
00396         m_eType[e] = association; //can be removed if edgetypes work properly
00397     }
00398 
00399     //------------------
00400     //second level types
00401 
00402     //in contrast to setsecondarytype: do not delete old value
00403 
00405     void setExpansion(edge e) {
00406         m_edgeTypes[e] |= expansionPattern();
00407 
00408         //preliminary set old array too
00409         m_expansionEdge[e] = 1;//can be removed if edgetypes work properly
00410     }
00411 
00413     bool isExpansion(edge e) {
00414         return ((m_edgeTypes[e] & expansionPattern()) == expansionPattern());
00415     }
00416 
00417     //should add things like cluster and clique boundaries that need rectangle shape
00418 
00420     bool isBoundary(edge e) {
00421         return isCliqueBoundary(e); }
00422 
00423     //--------------
00424     //tertiary types
00425 
00427     void setAssClass(edge e)
00428     {
00429         m_edgeTypes[e] |= assClassPattern();
00430     }
00431 
00433     bool isAssClass(edge e)
00434     {
00435         return ((m_edgeTypes[e] & assClassPattern()) == assClassPattern());
00436     }
00437 
00438 
00439     //------------------
00440     //fourth level types
00441 
00443     void setBrother(edge e) {
00444         m_edgeTypes[e] |= brotherPattern();
00445     }
00446 
00448     void setHalfBrother(edge e) {
00449         m_edgeTypes[e] |= halfBrotherPattern();
00450     }
00451 
00453     bool isBrother(edge e) {
00454         return ( (((m_edgeTypes[e] & etpFourth) & brotherPattern())>> etoFourth) == etcBrother);
00455     }
00456 
00458     bool isHalfBrother(edge e) {
00459         return ( (((m_edgeTypes[e] & etpFourth) & halfBrotherPattern())>> etoFourth) == etcHalfBrother);
00460     }
00461 
00462     //-----------------
00463     //set generic types
00464 
00465     edgeType edgeTypeAND(edge e, edgeType et) {m_edgeTypes[e] &= et; return m_edgeTypes[e];}
00466 
00467     edgeType edgeTypeOR(edge e, edgeType et) {m_edgeTypes[e] |= et; return m_edgeTypes[e];}
00468 
00469     //set primary edge type of edge e to primary edge type in et
00470     //deletes old primary value
00471     void setPrimaryType(edge e, edgeType et) {m_edgeTypes[e] &= 0xfffffff0; 
00472                                               m_edgeTypes[e] |= (etpPrimary & et); } 
00473 
00474     void setSecondaryType(edge e, edgeType et) {m_edgeTypes[e] &= 0xffffff0f; 
00475                                                 m_edgeTypes[e] |= (etpSecondary & ( et << etoSecondary)); }
00476 
00477     //sets primary type to bitwise AND of et's primary value and old value
00478     edgeType edgeTypePrimaryAND(edge e, edgeType et) {m_edgeTypes[e] &= (etpAll & et); return m_edgeTypes[e];}    
00479 
00480     //sets primary type to bitwise OR of et's primary value and old value
00481     edgeType edgeTypePrimaryOR(edge e, edgeType et) {m_edgeTypes[e] |= et; return m_edgeTypes[e];}
00482 
00483     //set user defined type locally
00484     void setUserType(edge e, edgeType et)
00485     {   
00486         OGDF_ASSERT( et < 147);
00487         m_edgeTypes[e] |= (et << etoUser);
00488     }
00489 
00490     bool isUserType(edge e, edgeType et)
00491     {
00492         OGDF_ASSERT( et < 147);
00493         return ( (m_edgeTypes[e] & (et << etoUser)) == (et << etoUser));
00494     }
00495 
00496     //---------------
00497     //
00498     // old edge types
00499 
00500     //this is pure nonsense, cause we have uml-edgetype and m_etype, and should be able to 
00501     //use them with different types, but as long as they arent used correctly (switch instead of xor),
00502     //use this function to return if e is expansionedge
00503     //if it is implemented correctly later, delete the array and return m_etype == Graph::expand
00504     //(the whole function then is obsolete, cause you can check it directly, but for convenience...)
00505     //should use genexpand, nodeexpand, dissect instead of bool
00506     void setExpansionEdge(edge e, int expType) {
00507         m_expansionEdge[e] = expType;
00508         }
00509 
00510     bool isExpansionEdge(edge e) const {
00511         return (m_expansionEdge[e] > 0);
00512     }
00513 
00514     int expansionType(edge e) const { return m_expansionEdge[e]; }
00515 
00516     //precondition normalized
00517     bool isDegreeExpansionEdge(edge e) const {
00518         //return (m_eType[e] == Graph::expand);
00519         return ( m_expansionEdge[e]  == 2);
00520     }
00521 
00522 
00524 
00530 
00531 
00533     const NodeArray<double> &widthOrig() const {
00534         return m_pGraphAttributes->width();
00535     }
00536 
00538     double widthOrig(node v) const {
00539         return m_pGraphAttributes->width(v);
00540     }
00541 
00543     const NodeArray<double> &heightOrig() const {
00544         return m_pGraphAttributes->height();
00545     }
00546 
00548     double heightOrig(node v) const {
00549         return m_pGraphAttributes->height(v);
00550     }
00551 
00553     EdgeType typeOrig(edge e) const {
00554         return m_pGraphAttributes->type(e);
00555     }
00556 
00558     const GraphAttributes &getGraphAttributes() const {
00559         return *m_pGraphAttributes;
00560     }
00561 
00563 
00567 
00568     // Expands nodes with degree > 4 and merge nodes for generalizations
00569     void expand(bool lowDegreeExpand = false);
00570 
00571     void expandLowDegreeVertices(OrthoRep &OR);
00572 
00573     void collapseVertices(const OrthoRep &OR, Layout &drawing);
00574 
00575     void removeCrossing(node v); //removes the crossing at node v
00576 
00577     //model a boundary around a star subgraph centered at center
00578     //and keep external face information (outside the clique
00579     void insertBoundary(node center, adjEntry& adjExternal);
00580 
00581 
00583 
00587 
00589     virtual edge split(edge e);
00590 
00591 
00592     //returns node which was expanded using v
00593     node expandedNode(node v) const { return m_expandedNode[v]; }
00594 
00595     void setExpandedNode(node v, node w) { m_expandedNode[v] = w; }
00596 
00597 
00599 
00603 
00609     node newCopy(node vOrig, Graph::NodeType vType);
00610 
00618     edge newCopy(node v, adjEntry adjAfter, edge eOrig);
00619 
00628     edge newCopy(node v, adjEntry adjAfter, edge eOrig, CombinatorialEmbedding &E);
00629 
00630 
00632 
00636 
00637     // embeds current copy
00638     bool embed();
00639 
00640     // removes all crossing nodes which are actually only two "touching" edges
00641     void removePseudoCrossings();
00642 
00643     // re-inserts edge eOrig by "crossing" the edges in crossedEdges;
00644     // splits each edge in crossedEdges
00645     // Precond.: eOrig is an edge in the original graph,
00646     //           the edges in crossedEdges are in this graph
00647     void insertEdgePath(edge eOrig, const SList<adjEntry> &crossedEdges);
00648 
00649     // same as insertEdgePath, but assumes that the graph is embedded
00650     void insertEdgePathEmbedded(
00651         edge eOrig,
00652         CombinatorialEmbedding &E,
00653         const SList<adjEntry> &crossedEdges);
00654 
00655     // removes the complete edge path for edge eOrig
00656     // Precond.: eOrig s an edge in the original graph
00657     void removeEdgePathEmbedded(CombinatorialEmbedding &E,
00658         edge eOrig,
00659         FaceSetPure &newFaces) {
00660         GraphCopy::removeEdgePathEmbedded(E,eOrig,newFaces);
00661     }
00662 
00663     //inserts crossings between two copy edges (used in TopologyModule)
00664     //replaces crossingedge by first crossingedge part and returns second.
00665     //the parameter topDown describes he following:
00666     // if the crossingEdge is running horizontally from left to right,
00667     // is the crossedEdge direction top->down?
00668     edge insertCrossing(edge& crossingEdge,
00669                         const edge crossedEdge,
00670                         bool topDown);
00671 
00673 
00678 
00686     void removeDeg1Nodes(Stack<Deg1RestoreInfo> &S, const NodeArray<bool> &mark);
00687 
00693     void restoreDeg1Nodes(Stack<Deg1RestoreInfo> &S, List<node> &deg1s);
00694 
00696 
00697 protected:
00698 
00699     int m_currentCC; 
00700     int m_numCC;     
00701 
00702     Array<List<node> >  m_nodesInCC; 
00703     
00704     const GraphAttributes* m_pGraphAttributes; 
00705 
00706     //------------
00707     //object types
00708 
00709     //set the type of eCopy according to the type of eOrig
00710     //should be virtual if PlanRepUML gets its own
00711     void setCopyType(edge eCopy, edge eOrig);
00712 
00713     //helper to cope with the edge types, shifting to the right place
00714     edgeType generalizationPattern() {return etcPrimGeneralization;}
00715     edgeType associationPattern()    {return etcPrimAssociation;}
00716     edgeType expansionPattern()      {return etcSecExpansion << etoSecondary;}
00717     edgeType assClassPattern()       {return etcAssClass << etoTertiary;}
00718     edgeType brotherPattern()        {return etcBrother   << etoFourth;}
00719     edgeType halfBrotherPattern()    {return etcHalfBrother   << etoFourth;}
00720     edgeType cliquePattern()         {return etcSecClique << etoSecondary;} //boundary
00721     
00722     
00723     void removeUnnecessaryCrossing(
00724         adjEntry adjA1,
00725         adjEntry adjA2,
00726         adjEntry adjB1,
00727         adjEntry adjB2);
00728 
00729 //--------------------------------------------------------------------------
00730 
00731     NodeArray<NodeType> m_vType; 
00732 
00733     NodeArray<nodeType> m_nodeTypes; 
00734 
00735     NodeArray<node>     m_expandedNode; 
00736     NodeArray<adjEntry> m_expandAdj;
00737 
00738     //clique handling: We save an adjEntry of the first edge of an inserted
00739     //boundary around a clique at its center v
00740     NodeArray<adjEntry> m_boundaryAdj;
00741 
00742     //zusammenlegbare Typen
00743     EdgeArray<int>      m_expansionEdge; //1 genmerge, 2 degree (2 highdegree, 3 lowdegree)
00744     EdgeArray<EdgeType> m_eType;
00745     
00746     //m_edgeTypes stores semantic edge type information on several levels: 
00747     //primary type: generalization, association,...
00748     //secondary type: merger,...
00749     //tertiary type: vertical in hierarchy, inner, outer, ...
00750     //fourth type: neighbour relation (brother, cousin in hierarchy)
00751     //user types: user defined for local changes
00752     EdgeArray<edgeType> m_edgeTypes; //store all type information
00753 
00754     //workaround fuer typsuche in insertedgepathembed
00755     //speichere kopietyp auf originalen
00756     //maybe it's enough to set gen/ass without extra array
00757     EdgeArray<edgeType> m_oriEdgeTypes;
00758 
00759     EdgeArray<edge>     m_eAuxCopy; // auxiliary (GraphCopy::initByNodes())
00760 
00761 };//PlanRep
00762 
00763 } // end namespace ogdf
00764 
00765 
00766 #endif


© 1999-2007 by oreas GmbH, © 2005-2007 by University Dortmund and University Cologne.

Generated on Thu Nov 22 19:40:04 2007 by doxygen 1.5.4.