Open
Graph Drawing
Framework

 v.2010.10
 

CombinatorialEmbedding.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 2047 $
00003  * 
00004  * last checkin:
00005  *   $Author: klein $ 
00006  *   $Date: 2010-10-13 17:12:21 +0200 (Wed, 13 Oct 2010) $ 
00007  ***************************************************************/
00008  
00054 #ifdef _MSC_VER
00055 #pragma once
00056 #endif
00057 
00058 #ifndef OGDF_COMBINATORIAL_EMBEDDING_H
00059 #define OGDF_COMBINATORIAL_EMBEDDING_H
00060 
00061 
00062 #include <ogdf/basic/AdjEntryArray.h>
00063 
00064 
00065 namespace ogdf {
00066 
00067 class OGDF_EXPORT ConstCombinatorialEmbedding;
00068 
00069 typedef FaceElement *face;
00070 
00074 class OGDF_EXPORT FaceElement : private GraphElement
00075 {
00076     friend class ConstCombinatorialEmbedding;
00077     friend class CombinatorialEmbedding;
00078     friend class GraphList<FaceElement>;
00079 
00080     adjEntry m_adjFirst; 
00081     int m_id;   
00082     int m_size; 
00083 
00084 #ifdef OGDF_DEBUG
00085     const ConstCombinatorialEmbedding *m_pEmbedding;
00086 #endif
00087 
00088     // constructor
00089 #ifdef OGDF_DEBUG
00090     FaceElement(const ConstCombinatorialEmbedding *pEmbedding,
00091         adjEntry adjFirst,
00092         int id) :
00093         m_adjFirst(adjFirst), m_id(id), m_size(0), m_pEmbedding(pEmbedding) { }
00094 #else
00095 
00096     FaceElement(adjEntry adjFirst, int id) :
00097         m_adjFirst(adjFirst), m_id(id), m_size(0) { }
00098 #endif
00099 
00100 public:
00102     int index() const { return m_id; }
00103 
00105     adjEntry firstAdj() const { return m_adjFirst; }
00106 
00108     int size() const { return m_size; }
00109 
00111     face succ() const { return (face)m_next; }
00112 
00114     face pred() const { return (face)m_prev; }
00115 
00117     adjEntry nextFaceEdge(adjEntry adj) const {
00118         adj = adj->faceCycleSucc();
00119         return (adj != m_adjFirst) ? adj : 0;
00120     }
00121 
00122 #ifdef OGDF_DEBUG
00123     const ConstCombinatorialEmbedding *embeddingOf() const { return m_pEmbedding; }
00124 #endif
00125 
00126     OGDF_NEW_DELETE
00127 }; // class FaceElement
00128 
00129 
00130 class FaceArrayBase;
00131 template<class T>class FaceArray;
00132 
00133 
00149 class OGDF_EXPORT ConstCombinatorialEmbedding
00150 {
00151 protected:
00152     const Graph *m_cpGraph; 
00153 
00154     GraphList<FaceElement> m_faces; 
00155     int m_nFaces; 
00156     int m_faceIdCount; 
00157     int m_faceArrayTableSize; 
00158 
00159     AdjEntryArray<face> m_rightFace; 
00160     face m_externalFace; 
00161 
00162     mutable ListPure<FaceArrayBase*> m_regFaceArrays; 
00163 
00164 public:
00168     ConstCombinatorialEmbedding();
00169 
00176     explicit ConstCombinatorialEmbedding(const Graph &G);
00177 
00178 
00180     ConstCombinatorialEmbedding(const ConstCombinatorialEmbedding &C);
00181 
00183     ConstCombinatorialEmbedding &operator=(const ConstCombinatorialEmbedding &C);
00184 
00188     const Graph &getGraph() const { return *m_cpGraph; }
00189 
00191     operator const Graph &() const { return *m_cpGraph; }
00192 
00196     face firstFace() const { return m_faces.begin(); }
00197 
00199     face lastFace() const { return m_faces.rbegin(); }
00200 
00202     int numberOfFaces() const { return m_nFaces; }
00203 
00208     face rightFace(adjEntry adj) const { return m_rightFace[adj]; }
00209 
00214     face leftFace(adjEntry adj) const { return m_rightFace[adj->twin()]; }
00215 
00219     int maxFaceIndex() const { return m_faceIdCount-1; }
00220 
00222     int faceArrayTableSize() const { return m_faceArrayTableSize; }
00223 
00227     face chooseFace() const;
00228 
00230     face maximalFace() const;
00231 
00235     face externalFace() const {
00236         return m_externalFace;
00237     }
00238 
00243     void setExternalFace(face f) {
00244         OGDF_ASSERT(f->embeddingOf() == this);
00245         m_externalFace = f;
00246     }
00247 
00248     bool isBridge(edge e) const {
00249         return m_rightFace[e->adjSource()] == m_rightFace[e->adjTarget()];
00250     }
00251 
00258     void init(const Graph &G);
00259 
00261     void computeFaces();
00262     
00263 
00267     bool consistencyCheck();
00268 
00269 
00275     ListIterator<FaceArrayBase*> registerArray(FaceArrayBase *pFaceArray) const;
00276 
00282     void unregisterArray(ListIterator<FaceArrayBase*> it) const;
00283 
00286 protected:
00288     face createFaceElement(adjEntry adjFirst);
00289 
00291     void reinitArrays();
00292 
00293 }; // class ConstCombinatorialEmbedding
00294 
00295 
00296 
00303 class OGDF_EXPORT CombinatorialEmbedding : public ConstCombinatorialEmbedding
00304 {
00305     Graph *m_pGraph; 
00306 
00307     // the following methods are private in order to make them unusable
00308     // It is not clear which meaning copying of a comb. embedding should
00309     // have since we only store a pointer to the topology (Graph)
00310     CombinatorialEmbedding(const CombinatorialEmbedding &) : ConstCombinatorialEmbedding() { }
00311     CombinatorialEmbedding &operator=(const CombinatorialEmbedding &) {
00312         return *this;
00313     }
00314 
00315 public:
00319     CombinatorialEmbedding() : ConstCombinatorialEmbedding() {
00320         m_pGraph = 0;
00321     }
00322 
00329     explicit CombinatorialEmbedding(Graph &G) : ConstCombinatorialEmbedding(G) {
00330         m_pGraph = &G;
00331     }
00332 
00334 
00338 
00342     const Graph &getGraph() const { return *m_cpGraph; }
00343     
00344     Graph &getGraph() { return *m_pGraph; }
00345 
00346     operator const Graph &() const { return *m_cpGraph; }
00347 
00348     operator Graph &() { return *m_pGraph; }
00349 
00350 
00352 
00356 
00363     void init(Graph &G) {
00364         ConstCombinatorialEmbedding::init(G);
00365         m_pGraph = &G;
00366     }
00367 
00371     void clear();
00372 
00373 
00375 
00379 
00385     edge split(edge e);
00386 
00392     void unsplit(edge eIn, edge eOut);
00393 
00412     node splitNode(adjEntry adjStartLeft, adjEntry adjStartRight);
00413 
00419     node contract(edge e);
00420 
00429     edge splitFace(adjEntry adjSrc, adjEntry adjTgt);
00430 
00431     // incremental stuff
00432 
00433     //special version of the above function doing a pushback of the new edge
00434     //on the adjacency list of v making it possible to insert new degree 0
00435     //nodes into a face
00436     edge splitFace(node v, adjEntry adjTgt);
00437     edge splitFace(adjEntry adjSrc, node v);
00438 
00444     face joinFaces(edge e);
00445 
00447     void reverseEdge(edge e);
00448 
00449     void moveBridge(adjEntry adjBridge, adjEntry adjBefore);
00450 
00451     void removeDeg1(node v);
00452 
00454     void updateMerger(edge e, face fRight, face fLeft);
00455 
00456 
00459 }; // class CombinatorialEmbedding
00460 
00461 
00462 //---------------------------------------------------------
00463 // iteration macros
00464 //---------------------------------------------------------
00465 
00467 #define forall_faces(f,E) for((f)=(E).firstFace(); (f); (f)=(f)->succ())
00468 
00469 
00471 #define forall_rev_faces(f,E) for((f)=(E).lastFace(); (f); (f)=(f)->pred())
00472 
00485 #define forall_face_adj(adj,f) for((adj)=(f)->firstAdj(); (adj); (adj)=(f)->nextFaceEdge(adj))
00486 
00487 
00488 } // end namespace ogdf
00489 
00490 
00491 #endif