// // Filename : ViewMap.h // Author(s) : Stephane Grabli // Purpose : Classes to define a View Map (ViewVertex, ViewEdge, etc.) // Date of creation : 03/09/2002 // /////////////////////////////////////////////////////////////////////////////// // // Copyright (C) : Please refer to the COPYRIGHT file distributed // with this source distribution. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // /////////////////////////////////////////////////////////////////////////////// #ifndef VIEWMAP_H # define VIEWMAP_H # include "../system/BaseIterator.h" # include "../system/FreestyleConfig.h" # include "../geometry/GeomUtils.h" # include "Interface0D.h" # include "Interface1D.h" # include "Silhouette.h" // defines the embedding # include /**********************************/ /* */ /* */ /* ViewMap */ /* */ /* */ /**********************************/ /* Density Mean area depth value distance to a point */ class ViewVertex; class ViewEdge; class ViewShape; class TVertex; /*! Class defining the ViewMap.*/ class LIB_VIEW_MAP_EXPORT ViewMap { public: typedef vector viewedges_container; typedef vector viewvertices_container; typedef vector viewshapes_container; typedef vector svertices_container; typedef vector fedges_container; typedef map id_to_index_map; private: static ViewMap *_pInstance; viewshapes_container _VShapes; // view shapes viewedges_container _VEdges; // view edges viewvertices_container _VVertices; // view vertices fedges_container _FEdges; // feature edges (embedded edges) svertices_container _SVertices; // embedded vertices BBox _scene3DBBox; id_to_index_map _shapeIdToIndex; // Mapping between the WShape or VShape id to the VShape index in the // _VShapes vector. Used in the method viewShape(int id) to access a shape from its id. public: /*! A field that can be used by the user to store any data. * This field must be reseted afterwards using ResetUserData(). */ void* userdata; /*! Default constructor. */ ViewMap() { _pInstance = this; userdata = 0; } /*! Destructor. */ virtual ~ViewMap(); /*! Gets the viewedge the nearest to the * 2D position specified as argument */ const ViewEdge * GetClosestViewEdge(real x, real y) const ; /*! Gets the Fedge the nearest to the * 2D position specified as argument */ const FEdge * GetClosestFEdge(real x, real y) const ; /* accessors */ /*! The ViewMap is a singleton class. This static method * returns the instance of the ViewMap. */ static inline ViewMap * getInstance() {return _pInstance;} /* Returns the list of ViewShapes of the scene. */ inline viewshapes_container& ViewShapes() {return _VShapes;} /* Returns the list of ViewEdges of the scene. */ inline viewedges_container& ViewEdges() {return _VEdges;} /* Returns the list of ViewVertices of the scene. */ inline viewvertices_container& ViewVertices() {return _VVertices;} /* Returns the list of FEdges of the scene. */ inline fedges_container& FEdges() {return _FEdges;} /* Returns the list of SVertices of the scene. */ inline svertices_container& SVertices() {return _SVertices;} /* Returns an iterator pointing onto the first ViewEdge of the list. */ inline viewedges_container::iterator viewedges_begin() {return _VEdges.begin();} inline viewedges_container::iterator viewedges_end() {return _VEdges.end();} inline int viewedges_size() {return _VEdges.size();} ViewShape * viewShape(unsigned index); id_to_index_map& shapeIdToIndexMap() {return _shapeIdToIndex;} /*! Returns the scene 3D bounding box. */ inline BBox getScene3dBBox() const {return _scene3DBBox;} /* modifiers */ void AddViewShape(ViewShape *iVShape); inline void AddViewEdge(ViewEdge *iVEdge) {_VEdges.push_back(iVEdge);} inline void AddViewVertex(ViewVertex *iVVertex) {_VVertices.push_back(iVVertex);} inline void AddFEdge(FEdge *iFEdge) {_FEdges.push_back(iFEdge);} inline void AddSVertex(SVertex *iSVertex) {_SVertices.push_back(iSVertex);} /*! Sets the scene 3D bounding box. */ inline void setScene3dBBox(const BBox& bbox) {_scene3DBBox=bbox;} /* Creates a T vertex in the view map. * A T vertex is the intersection between 2 * FEdges (before these ones are splitted). * The TVertex is a 2D intersection but it * corresponds to a 3D point on each of the 2 FEdges. * iA3D * The 3D coordinates of the point corresponding * to the intersection on the first edge. * iA2D * The x,y,z 2D coordinates of the projection * of iA3D * iFEdgeA * The first FEdge * iB3D * The 3D coordinates of the point corresponding * to the intersection on the second edge. * iB2D * The x,y,z 2D coordinates of the projection * of iB3D * iFEdgeB * The second FEdge * id * The id that must be given to that TVertex */ TVertex* CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFEdgeA, const Vec3r& iB3D, const Vec3r& iB2D, FEdge *iFEdgeB, const Id& id); /* Updates the structures to take into account the fact * that a SVertex must now be considered as a ViewVertex * iVertex * The SVertex on top of which the ViewVertex is built (it is necessarily * a NonTVertex because it is a SVertex) * newViewEdges * The new ViewEdges that must be add to the ViewMap */ ViewVertex * InsertViewVertex(SVertex *iVertex, vector& newViewEdges); /* connects a FEdge to the graph trough a SVertex */ //FEdge * Connect(FEdge *ioEdge, SVertex *ioVertex); }; /**********************************/ /* */ /* */ /* ViewVertex */ /* */ /* */ /**********************************/ class ViewEdge; class SShape; namespace ViewVertexInternal { class edge_const_traits; class edge_nonconst_traits; template class edge_iterator_base ; class orientedViewEdgeIterator; } // end of namespace ViewEdgeInternal /*! Class to define a view vertex * A view vertex is a feature vertex corresponding * to a point of the image graph, where the characteristics of an * edge might change (nature, visibility, ...). * A ViewVertex can be of two kinds: a TVertex when * it corresponds to the intersection between two * ViewEdges or a NonTVertex when it corresponds to a * vertex of the initial input mesh (it is the case * for vertices such as corners for example). * Thus, this class can be specialized into two classes, * the TVertex class and the NonTVertex class. */ class LIB_VIEW_MAP_EXPORT ViewVertex : public Interface0D { public: // Implementation of Interface0D /*! Returns the string "ViewVertex" .*/ virtual string getExactTypeName() const { return "ViewVertex"; } public: friend class ViewShape; typedef pair directedViewEdge; // if bool = true, the ViewEdge is incoming typedef vector edges_container; typedef ViewVertexInternal::edge_iterator_base edge_iterator; typedef ViewVertexInternal::edge_iterator_base const_edge_iterator; private: Nature::VertexNature _Nature; public: /*! A field that can be used by the user to store any data. * This field must be reseted afterwards using ResetUserData(). */ void * userdata; /*! Default constructor.*/ inline ViewVertex() {userdata = 0;_Nature = Nature::VIEW_VERTEX; } inline ViewVertex(Nature::VertexNature nature) { userdata = 0; _Nature = Nature::VIEW_VERTEX | nature; } protected: /*! Copy constructor. */ inline ViewVertex(ViewVertex& iBrother) { _Nature = iBrother._Nature; iBrother.userdata = this; userdata = 0; } /*! Cloning method. */ virtual ViewVertex * duplicate() = 0; public: /*! Destructor. */ virtual ~ViewVertex() {} /* accessors */ /*! Returns the nature of the vertex .*/ virtual Nature::VertexNature getNature() const { return _Nature; } /* modifiers */ /*! Sets the nature of the vertex. */ inline void setNature(Nature::VertexNature iNature) {_Nature = iNature;} /* Replaces old edge by new edge */ virtual void Replace(ViewEdge *, ViewEdge *) {} public: /* iterators access */ // allows iteration on the edges that comes from/goes to // this vertex in CCW order (order defined in 2D in the image plan) virtual edge_iterator edges_begin() = 0; virtual const_edge_iterator edges_begin() const = 0; virtual edge_iterator edges_end() = 0; virtual const_edge_iterator edges_end() const = 0; virtual edge_iterator edges_iterator(ViewEdge *iEdge) = 0; virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const = 0; // Iterator access /*! Returns an iterator over the ViewEdges that goes to or comes from * this ViewVertex pointing to the first ViewEdge of the list. * The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges * and to get the orientation for each ViewEdge (incoming/outgoing). */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() = 0; /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, * pointing after the last ViewEdge. */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() = 0; /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge * given as argument. */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) = 0; }; /**********************************/ /* */ /* */ /* TVertex */ /* */ /* */ /**********************************/ /*! class to define a T vertex, i.e. an intersection between * two edges. * It points towards 2 SVertex and 4 View edges. * Among these ViewEdges, 2 are front and 2 are back. * Basically the front edge hides part of the back edge. * So, among the back edges, 1 is of invisibility n * and the other of visibility n+1 */ class LIB_VIEW_MAP_EXPORT TVertex : public ViewVertex { public: typedef vector edge_pointers_container; public: // Implementation of Interface0D /*! Returns the string "TVertex" .*/ virtual string getExactTypeName() const { return "TVertex"; } // Data access methods /* Returns the 3D x coordinate of the vertex . * Ambiguous in this case. */ virtual real getX() const { cerr << "Warning: getX() undefined for this point" << endl; return _FrontSVertex->point3D().x(); } virtual real getY() const { cerr << "Warning: getX() undefined for this point" << endl; return _FrontSVertex->point3D().y(); } virtual real getZ() const { cerr << "Warning: getX() undefined for this point" << endl; return _FrontSVertex->point3D().z(); } /*! Returns the 3D point. */ virtual Vec3f getPoint3D() const { cerr << "Warning: getPoint3D() undefined for this point" << endl; return _FrontSVertex->getPoint3D(); } /*! Returns the projected 3D x coordinate of the vertex .*/ virtual real getProjectedX() const { return _FrontSVertex->point2D().x(); } /*! Returns the projected 3D y coordinate of the vertex .*/ virtual real getProjectedY() const { return _FrontSVertex->point2D().y(); } virtual real getProjectedZ() const { return _FrontSVertex->point2D().z(); } /*! Returns the 2D point. */ virtual Vec2f getPoint2D() const { return _FrontSVertex->getPoint2D(); } /*! Returns the Id of the TVertex .*/ virtual Id getId() const { return _Id; } /*! Cast the Interface0D in SVertex if it can be. */ // it can't /*! Cast the Interface0D in ViewVertex if it can be. */ virtual ViewVertex * castToViewVertex(){ return this; } /*! Cast the Interface0D in TVertex if it can be. */ virtual TVertex * castToTVertex(){ return this; } private: SVertex *_FrontSVertex; SVertex *_BackSVertex; directedViewEdge _FrontEdgeA; directedViewEdge _FrontEdgeB; directedViewEdge _BackEdgeA; directedViewEdge _BackEdgeB; Id _Id; // id to identify t vertices . these id will be negative in order not to be mixed with NonTVertex ids. edge_pointers_container _sortedEdges; // the list of the four ViewEdges, ordered in CCW order (in the image plan) public: /*! Default constructor.*/ inline TVertex() : ViewVertex(Nature::T_VERTEX) { _FrontSVertex = 0; _BackSVertex = 0; _FrontEdgeA.first = 0; _FrontEdgeB.first = 0; _BackEdgeA.first = 0; _BackEdgeB.first = 0; } inline TVertex(SVertex *svFront, SVertex *svBack) : ViewVertex(Nature::T_VERTEX) { _FrontSVertex = svFront; _BackSVertex = svBack; _FrontEdgeA.first = 0; _FrontEdgeB.first = 0; _BackEdgeA.first = 0; _BackEdgeB.first = 0; svFront->SetViewVertex(this); svBack->SetViewVertex(this); } protected: /*! Copy constructor. */ inline TVertex(TVertex& iBrother) : ViewVertex(iBrother) { _FrontSVertex = iBrother._FrontSVertex; _BackSVertex = iBrother._BackSVertex; _FrontEdgeA = iBrother._FrontEdgeA; _FrontEdgeB = iBrother._FrontEdgeB; _BackEdgeA = iBrother._BackEdgeA; _BackEdgeB = iBrother._BackEdgeB; _sortedEdges = iBrother._sortedEdges; } /*! Cloning method. */ virtual ViewVertex * duplicate() { TVertex *clone = new TVertex(*this); return clone; } public: /* accessors */ /*! Returns the SVertex that is closer to the viewpoint. */ inline SVertex *frontSVertex() {return _FrontSVertex;} /*! Returns the SVertex that is further away from the viewpoint. */ inline SVertex *backSVertex() {return _BackSVertex;} inline directedViewEdge& frontEdgeA() {return _FrontEdgeA;} inline directedViewEdge& frontEdgeB() {return _FrontEdgeB;} inline directedViewEdge& backEdgeA() {return _BackEdgeA;} inline directedViewEdge& backEdgeB() {return _BackEdgeB;} /* modifiers */ /*! Sets the SVertex that is closer to the viewpoint. */ inline void SetFrontVertex(SVertex *iFrontSVertex) {_FrontSVertex = iFrontSVertex;_FrontSVertex->SetViewVertex(this);} /*! Sets the SVertex that is further away from the viewpoint. */ inline void SetBackSVertex(SVertex *iBackSVertex) {_BackSVertex = iBackSVertex;_BackSVertex->SetViewVertex(this);} void SetFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming=true); void SetFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming=true) ; void SetBackEdgeA(ViewEdge *iBackEdgeA, bool incoming=true); void SetBackEdgeB(ViewEdge *iBackEdgeB, bool incoming=true) ; /*! Sets the Id. */ inline void SetId(const Id& iId) {_Id = iId;} /*! Returns the SVertex (among the 2) belonging to the FEdge iFEdge */ inline SVertex * GetSVertex(FEdge *iFEdge) { const vector& vfEdges = _FrontSVertex->fedges(); vector::const_iterator fe,fend; for(fe=vfEdges.begin(),fend=vfEdges.end(); fe!=fend; fe++) { if((*fe) == iFEdge) return _FrontSVertex; } const vector& vbEdges = _BackSVertex->fedges(); for(fe=vbEdges.begin(),fend=vbEdges.end(); fe!=fend; fe++) { if((*fe) == iFEdge) return _BackSVertex; } return 0; } virtual void Replace(ViewEdge *iOld, ViewEdge *iNew); /*! returns the mate edge of iEdgeA. * For example, if iEdgeA is frontEdgeA, * then frontEdgeB is returned. If iEdgeA is * frontEdgeB then frontEdgeA is returned. * Same for back edges */ virtual ViewEdge * mate(ViewEdge* iEdgeA) { if(iEdgeA == _FrontEdgeA.first) return _FrontEdgeB.first; if(iEdgeA == _FrontEdgeB.first) return _FrontEdgeA.first; if(iEdgeA == _BackEdgeA.first) return _BackEdgeB.first; if(iEdgeA == _BackEdgeB.first) return _BackEdgeA.first; return 0; } /* iterators access */ virtual edge_iterator edges_begin(); virtual const_edge_iterator edges_begin() const; virtual edge_iterator edges_end(); virtual const_edge_iterator edges_end() const; virtual edge_iterator edges_iterator(ViewEdge *iEdge); virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const; /*! Returns an iterator over the ViewEdges that goes to or comes from * this ViewVertex pointing to the first ViewEdge of the list. * The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges * and to get the orientation for each ViewEdge (incoming/outgoing). */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() ; /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, * pointing after the last ViewEdge. */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() ; /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge * given as argument. */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) ; }; /**********************************/ /* */ /* */ /* NonTVertex */ /* */ /* */ /**********************************/ // (non T vertex) /*! View vertex for corners, cusps, etc... * Associated to a single SVertex. * Can be associated to 2 or several view edges */ class LIB_VIEW_MAP_EXPORT NonTVertex : public ViewVertex { public: typedef vector edges_container; public: // Implementation of Interface0D /*! Returns the string "ViewVertex" .*/ virtual string getExactTypeName() const { return "NonTVertex"; } // Data access methods /*! Returns the 3D x coordinate of the vertex .*/ virtual real getX() const { return _SVertex->point3D().x(); } /*! Returns the 3D y coordinate of the vertex .*/ virtual real getY() const { return _SVertex->point3D().y(); } /*! Returns the 3D z coordinate of the vertex .*/ virtual real getZ() const { return _SVertex->point3D().z(); } /*! Returns the 3D point. */ virtual Vec3f getPoint3D() const { return _SVertex->getPoint3D(); } /*! Returns the projected 3D x coordinate of the vertex .*/ virtual real getProjectedX() const { return _SVertex->point2D().x(); } /*! Returns the projected 3D y coordinate of the vertex .*/ virtual real getProjectedY() const { return _SVertex->point2D().y(); } /*! Returns the projected 3D z coordinate of the vertex .*/ virtual real getProjectedZ() const { return _SVertex->point2D().z(); } /*! Returns the 2D point. */ virtual Vec2f getPoint2D() const { return _SVertex->getPoint2D(); } /*! Returns the Id of the vertex .*/ virtual Id getId() const { return _SVertex->getId(); } /*! Cast the Interface0D in SVertex if it can be. */ virtual SVertex * castToSVertex(){ return _SVertex; } /*! Cast the Interface0D in ViewVertex if it can be. */ virtual ViewVertex * castToViewVertex(){ return this; } /*! Cast the Interface0D in NonTVertex if it can be. */ virtual NonTVertex * castToNonTVertex(){ return this; } private: SVertex *_SVertex; edges_container _ViewEdges; public: /*! Default constructor.*/ inline NonTVertex() : ViewVertex(Nature::NON_T_VERTEX) { _SVertex = 0; } /*! Builds a NonTVertex from a SVertex. */ inline NonTVertex(SVertex* iSVertex) : ViewVertex(Nature::NON_T_VERTEX) { _SVertex = iSVertex; _SVertex->SetViewVertex(this); } protected: /*! Copy constructor. */ inline NonTVertex(NonTVertex& iBrother) : ViewVertex(iBrother) { _SVertex = iBrother._SVertex; _SVertex->SetViewVertex(this); _ViewEdges = iBrother._ViewEdges; } /*! Cloning method. */ virtual ViewVertex * duplicate() { NonTVertex *clone = new NonTVertex(*this); return clone; } public: /*! destructor. */ virtual ~NonTVertex() {} /* accessors */ /*! Returns the SVertex on top of which this NonTVertex is built. */ inline SVertex * svertex() {return _SVertex;} inline edges_container& viewedges() {return _ViewEdges;} /* modifiers */ /*! Sets the SVertex on top of which this NonTVertex is built. */ inline void SetSVertex(SVertex *iSVertex) {_SVertex = iSVertex;_SVertex->SetViewVertex(this);} inline void SetViewEdges(const vector& iViewEdges) {_ViewEdges = iViewEdges;} void AddIncomingViewEdge(ViewEdge * iVEdge) ; void AddOutgoingViewEdge(ViewEdge * iVEdge) ; inline void AddViewEdge(ViewEdge * iVEdge, bool incoming=true) { if(incoming) AddIncomingViewEdge(iVEdge); else AddOutgoingViewEdge(iVEdge); } /* Replaces old edge by new edge */ virtual void Replace(ViewEdge *iOld, ViewEdge *iNew) { edges_container::iterator insertedve; for(edges_container::iterator ve=_ViewEdges.begin(),vend=_ViewEdges.end(); ve!=vend; ve++) { if((ve)->first == iOld) { insertedve = _ViewEdges.insert(ve, directedViewEdge(iNew, ve->second));// inserts e2 before ve. // returns an iterator pointing toward e2. ve is invalidated. // we want to remove e1, but we can't use ve anymore: insertedve++; // insertedve points now to e1 _ViewEdges.erase(insertedve); return; } } } /* iterators access */ virtual edge_iterator edges_begin(); virtual const_edge_iterator edges_begin() const; virtual edge_iterator edges_end(); virtual const_edge_iterator edges_end() const; virtual edge_iterator edges_iterator(ViewEdge *iEdge); virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const; /*! Returns an iterator over the ViewEdges that goes to or comes from * this ViewVertex pointing to the first ViewEdge of the list. * The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges * and to get the orientation for each ViewEdge (incoming/outgoing). */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() ; /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, * pointing after the last ViewEdge. */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() ; /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge * given as argument. */ virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) ; }; /**********************************/ /* */ /* */ /* ViewEdge */ /* */ /* */ /**********************************/ /* Geometry(normals...) Nature of edges 2D spaces (1or2, material, z...) Parent Shape 3D Shading, material Importance Occluders */ class ViewShape; namespace ViewEdgeInternal { template class edge_iterator_base ; template class fedge_iterator_base ; template class vertex_iterator_base ; } // end of namespace ViewEdgeInternal /*! Class defining a ViewEdge. A ViewEdge in an edge * of the image graph. it connnects two ViewVertex. * It is made by connecting a set of FEdges. */ class LIB_VIEW_MAP_EXPORT ViewEdge : public Interface1D { public: // Implementation of Interface0D /*! Returns the string "ViewEdge" .*/ virtual string getExactTypeName() const { return "ViewEdge"; } // Data access methods /*! Returns the Id of the vertex .*/ virtual Id getId() const { return _Id; } /*! Returns the nature of the ViewEdge. */ virtual Nature::EdgeNature getNature() const { return _Nature; } public: typedef SVertex vertex_type; friend class ViewShape; // for ViewEdge iterator typedef ViewEdgeInternal::edge_iterator_base > edge_iterator; typedef ViewEdgeInternal::edge_iterator_base > const_edge_iterator; // for fedge iterator typedef ViewEdgeInternal::fedge_iterator_base > fedge_iterator; typedef ViewEdgeInternal::fedge_iterator_base > const_fedge_iterator; // for svertex iterator typedef ViewEdgeInternal::vertex_iterator_base > vertex_iterator; typedef ViewEdgeInternal::vertex_iterator_base > const_vertex_iterator; private: ViewVertex * __A; // edge starting vertex ViewVertex * __B; // edge ending vertex Nature::EdgeNature _Nature; // nature of view edge ViewShape *_Shape; // shape to which the view edge belongs FEdge * _FEdgeA; // first edge of the embedded fedges chain FEdge * _FEdgeB; // last edge of the embedded fedges chain Id _Id; unsigned _ChainingTimeStamp; ViewShape *_aShape; // The silhouette view edge separates 2 2D spaces. The one on the left is // necessarly the Shape _Shape (the one to which this edge belongs to) // and _aShape is the one on its right // NON GERE PAR LE COPY CONSTRUCTEUR int _qi; vector _Occluders; // tmp Id * _splittingId; public: /*! A field that can be used by the user to store any data. * This field must be reseted afterwards using ResetUserData(). */ void * userdata; /*! Default constructor.*/ inline ViewEdge() { __A=0; __B=0; _FEdgeA = 0; _FEdgeB = 0; _ChainingTimeStamp = 0; _qi = 0; _aShape=0; userdata = 0; _splittingId = 0; } inline ViewEdge(ViewVertex* iA, ViewVertex *iB) { __A = iA; __B = iB; _FEdgeA = 0; _FEdgeB = 0; _Shape = 0; _ChainingTimeStamp = 0; _aShape = 0; _qi = 0; userdata = 0; _splittingId = 0; } inline ViewEdge(ViewVertex* iA, ViewVertex *iB, FEdge *iFEdgeA) { __A = iA; __B = iB; _FEdgeA = iFEdgeA; _FEdgeB = 0; _Shape = 0; _ChainingTimeStamp = 0; _aShape = 0; _qi = 0; userdata = 0; _splittingId = 0; } inline ViewEdge(ViewVertex* iA, ViewVertex *iB, FEdge *iFEdgeA, FEdge *iFEdgeB, ViewShape *iShape) { __A = iA; __B = iB; _FEdgeA = iFEdgeA; _FEdgeB = iFEdgeB; _Shape = iShape; _ChainingTimeStamp = 0; _aShape = 0; _qi = 0; userdata = 0; _splittingId = 0; UpdateFEdges(); // tells every FEdge between iFEdgeA and iFEdgeB that this is theit ViewEdge } protected: /*! Copy constructor. */ inline ViewEdge(ViewEdge& iBrother) { __A = iBrother.__A; __B = iBrother.__B; _FEdgeA = iBrother._FEdgeA; _FEdgeB = iBrother._FEdgeB; _Nature = iBrother._Nature; _Shape = 0; _Id = iBrother._Id; _ChainingTimeStamp = iBrother._ChainingTimeStamp; _aShape = iBrother._aShape; _qi = iBrother._qi; _splittingId = 0; iBrother.userdata = this; userdata = 0; } /*! Cloning method. */ virtual ViewEdge * duplicate() { ViewEdge *clone = new ViewEdge(*this); return clone; } public: /*! Destructor. */ virtual ~ViewEdge() { // if(0 != _aFace) // { // delete _aFace; // _aFace = 0; // } // only the last splitted deletes this id if(_splittingId){ if(*_splittingId == _Id) delete _splittingId; } } /* accessors */ /*! Returns the first ViewVertex. */ inline ViewVertex* A() {return __A;} /*! Returns the second ViewVertex. */ inline ViewVertex* B() {return __B;} /*! Returns the first FEdge that constitues this ViewEdge. */ inline FEdge* fedgeA() {return _FEdgeA;} /*! Returns the last FEdge that constitues this ViewEdge. */ inline FEdge* fedgeB() {return _FEdgeB;} /*! Returns the ViewShape to which this ViewEdge belongs to .*/ inline ViewShape * viewShape() {return _Shape;} /*! Returns the shape that is occluded by the ViewShape * to which this ViewEdge belongs to. If no object is occluded, * 0 is returned. * \return The occluded ViewShape. */ inline ViewShape * aShape() {return _aShape;} /*! Tells whether this ViewEdge forms a closed loop * or not. */ inline bool isClosed() { if(__B == 0) return true; return false; } /*! Returns the time stamp of this ViewEdge. */ inline unsigned getChainingTimeStamp() {return _ChainingTimeStamp;} inline const ViewShape * aShape() const {return _aShape;} inline const ViewShape * bShape() const {return _Shape;} inline vector& occluders() {return _Occluders;} inline Id * splittingId() {return _splittingId;} /* modifiers */ /*! Sets the first ViewVertex of the ViewEdge. */ inline void SetA(ViewVertex* iA) { __A = iA; } /*! Sets the last ViewVertex of the ViewEdge. */ inline void SetB(ViewVertex* iB) { __B = iB; } /*! Sets the nature of the ViewEdge. */ inline void SetNature(Nature::EdgeNature iNature) { _Nature = iNature; } /*! Sets the first FEdge of the ViewEdge. */ inline void SetFEdgeA(FEdge* iFEdge) { _FEdgeA = iFEdge; } /*! Sets the last FEdge of the ViewEdge. */ inline void SetFEdgeB(FEdge* iFEdge) { _FEdgeB = iFEdge; } /*! Sets the ViewShape to which this ViewEdge belongs to.*/ inline void SetShape(ViewShape *iVShape) { _Shape = iVShape; } /*! Sets the ViewEdge id. */ inline void SetId(const Id& id) {_Id = id;} /*! Sets Viewedge to this for all embedded fedges */ void UpdateFEdges(); /*! Sets the occluded ViewShape */ inline void SetaShape(ViewShape * iShape) {_aShape = iShape;} /*! Sets the quantitative invisibility value. */ inline void SetQI(int qi) {_qi = qi;} /*! Sets the time stamp value. */ inline void setChainingTimeStamp(unsigned ts) {_ChainingTimeStamp = ts;} inline void AddOccluder(ViewShape *iShape) {_Occluders.push_back(iShape);} inline void setSplittingId(Id * id) {_splittingId = id;} /* stroke interface definition */ inline bool intersect_2d_area(const Vec2r& iMin, const Vec2r& iMax) const { // parse edges to check if one of them is intersection the region: FEdge * current = _FEdgeA; do { if(GeomUtils::intersect2dSeg2dArea(iMin,iMax, Vec2r(current->vertexA()->point2D()[0],current->vertexA()->point2D()[1]), Vec2r(current->vertexB()->point2D()[0],current->vertexB()->point2D()[1]))) return true; current = current->nextEdge(); }while((current != 0) && (current != _FEdgeA)); return false; } inline bool include_in_2d_area(const Vec2r& iMin, const Vec2r& iMax) const { // parse edges to check if all of them are intersection the region: FEdge * current = _FEdgeA; do { if(!GeomUtils::include2dSeg2dArea(iMin,iMax, Vec2r(current->vertexA()->point2D()[0],current->vertexA()->point2D()[1]), Vec2r(current->vertexB()->point2D()[0],current->vertexB()->point2D()[1]))) return false; current = current->nextEdge(); }while((current != 0) && (current != _FEdgeA)); return true; } /* Information access interface */ //inline Nature::EdgeNature viewedge_nature() const {return getNature();} //float viewedge_length() const ; /*! Returns the 2D length of the Viewedge. */ real getLength2D() const; //inline Material material() const {return _FEdgeA->vertexA()->shape()->material();} inline int qi() const {return _qi;} inline occluder_container::const_iterator occluders_begin() const {return _Occluders.begin();} inline occluder_container::const_iterator occluders_end() const {return _Occluders.end();} inline int occluders_size() const {return _Occluders.size();} inline bool occluders_empty() const {return _Occluders.empty();} inline const Polygon3r& occludee() const {return (_FEdgeA->aFace());} inline const SShape * occluded_shape() const ; inline const bool occludee_empty() const {if(_aShape == 0) return true; return false;} //inline real z_discontinuity(int iCombination = 0) const ; inline Id shape_id() const {return _FEdgeA->vertexA()->shape()->getId();} inline const SShape * shape() const {return _FEdgeA->vertexA()->shape();} inline float shape_importance() const {return _FEdgeA->shape_importance();} /* iterators access */ // view edge iterator edge_iterator ViewEdge_iterator(); const_edge_iterator ViewEdge_iterator() const; // feature edge iterator fedge_iterator fedge_iterator_begin(); const_fedge_iterator fedge_iterator_begin() const; fedge_iterator fedge_iterator_last(); const_fedge_iterator fedge_iterator_last() const; fedge_iterator fedge_iterator_end(); const_fedge_iterator fedge_iterator_end() const; // embedding vertex iterator const_vertex_iterator vertices_begin() const; vertex_iterator vertices_begin(); const_vertex_iterator vertices_last() const; vertex_iterator vertices_last(); const_vertex_iterator vertices_end() const; vertex_iterator vertices_end(); // Iterator access (Interface1D) /*! Returns an Interface0DIterator to iterate over * the SVertex constituing the embedding of this ViewEdge. * The returned Interface0DIterator points to the first * SVertex of the ViewEdge. */ virtual Interface0DIterator verticesBegin(); /*! Returns an Interface0DIterator to iterate over * the SVertex constituing the embedding of this ViewEdge. * The returned Interface0DIterator points after the last * SVertex of the ViewEdge. */ virtual Interface0DIterator verticesEnd(); /*! Returns an Interface0DIterator to iterate over * the points of this ViewEdge at a given resolution. * The returned Interface0DIterator points on the first * Point of the ViewEdge. * \param t * the sampling value. */ virtual Interface0DIterator pointsBegin(float t=0.f); /*! Returns an Interface0DIterator to iterate over * the points of this ViewEdge at a given resolution. * The returned Interface0DIterator points after the last * Point of the ViewEdge. * \param t * the sampling value. */ virtual Interface0DIterator pointsEnd(float t=0.f); }; /**********************************/ /* */ /* */ /* ViewShape */ /* */ /* */ /**********************************/ /*! Class gathering the elements of the ViewMap (ViewVertex, ViewEdge) * that are issued from the same input shape. */ class LIB_VIEW_MAP_EXPORT ViewShape { private: vector _Vertices; vector _Edges; SShape * _SShape; public: /*! A field that can be used by the user to store any data. * This field must be reseted afterwards using ResetUserData(). */ void* userdata; /*! Default constructor.*/ inline ViewShape() { userdata = 0; _SShape = 0;} /*! Builds a ViewShape from a SShape. */ inline ViewShape(SShape *iSShape) {userdata = 0; _SShape = iSShape;}//_SShape->SetViewShape(this);} /*! Copy constructor. */ inline ViewShape(ViewShape& iBrother) { userdata = 0; vector::iterator vv,vvend; vector::iterator ve, veend; _SShape = iBrother._SShape; vector& vvertices = iBrother.vertices(); // duplicate vertices for(vv=vvertices.begin(), vvend=vvertices.end(); vv!=vvend; vv++) { ViewVertex * newVertex = (*vv)->duplicate(); AddVertex(newVertex); } vector& vvedges = iBrother.edges(); // duplicate edges for(ve=vvedges.begin(), veend=vvedges.end(); ve!=veend; ve++) { ViewEdge * newEdge = (*ve)->duplicate(); AddEdge(newEdge); // here the shape is set as the edge's shape } //------------------------- // remap edges in vertices: //------------------------- for(vv=_Vertices.begin(), vvend=_Vertices.end(); vv!=vvend; vv++) { switch((*vv)->getNature()) { case Nature::T_VERTEX: { TVertex *v = (TVertex*)(*vv); ViewEdge *veFrontA = (ViewEdge*)(v)->frontEdgeA().first->userdata; ViewEdge *veFrontB = (ViewEdge*)(v)->frontEdgeB().first->userdata; ViewEdge *veBackA = (ViewEdge*)(v)->backEdgeA().first->userdata; ViewEdge *veBackB = (ViewEdge*)(v)->backEdgeB().first->userdata; v->SetFrontEdgeA(veFrontA, v->frontEdgeA().second); v->SetFrontEdgeB(veFrontB, v->frontEdgeB().second); v->SetBackEdgeA(veBackA, v->backEdgeA().second); v->SetBackEdgeB(veBackB, v->backEdgeB().second); } break; case Nature::NON_T_VERTEX: { NonTVertex * v = (NonTVertex*)(*vv); vector& vedges = (v)->viewedges(); vector newEdges; for(vector::iterator ve=vedges.begin(), veend=vedges.end(); ve!=veend; ve++) { ViewEdge *current = (ViewEdge*)((ve)->first)->userdata; newEdges.push_back(ViewVertex::directedViewEdge(current, ve->second)); } (v)->SetViewEdges(newEdges); } break; default: ; } } //------------------------------------- // remap vertices in edges: //------------------------------------- for(ve=_Edges.begin(),veend=_Edges.end(); ve!=veend; ve++) { (*ve)->SetA((ViewVertex*)((*ve)->A()->userdata)); (*ve)->SetB((ViewVertex*)((*ve)->B()->userdata)); //--------------------------------------- // Update all embedded FEdges //--------------------------------------- (*ve)->UpdateFEdges(); } // reset all brothers userdata to NULL: //------------------------------------- //--------- // vertices //--------- for(vv=vvertices.begin(),vvend=vvertices.end(); vv!=vvend; vv++) { (*vv)->userdata = NULL; } //------ // edges //------ for(ve=vvedges.begin(),veend=vvedges.end(); ve!=veend; ve++) { (*ve)->userdata = NULL; } } /*! Cloning method. */ virtual ViewShape * duplicate() { ViewShape *clone = new ViewShape(*this); return clone; } /*! Destructor. */ virtual ~ViewShape(); /* splits a view edge into several view edges. * fe * The FEdge that gets splitted * iViewVertices * The view vertices corresponding to the different intersections for the edge fe. * This list need to be sorted such as the first view vertex is the * farther away from fe->vertexA. * ioNewEdges * The feature edges that are newly created (the initial edges are not * included) are added to this list. * ioNewViewEdges * The view edges that are newly created (the initial edges are not * included) are added to this list. */ inline void SplitEdge(FEdge *fe, const vector& iViewVertices, vector& ioNewEdges, vector& ioNewViewEdges); /* accessors */ /*! Returns the SShape on top of which this ViewShape is built. */ inline SShape * sshape() {return _SShape;} /*! Returns the SShape on top of which this ViewShape is built. */ inline const SShape * sshape() const {return _SShape;} /*! Returns the list of ViewVertex contained in this ViewShape. */ inline vector& vertices() {return _Vertices;} /*! Returns the list of ViewEdge contained in this ViewShape. */ inline vector& edges() {return _Edges;} /*! Returns the ViewShape id. */ inline Id getId() const {return _SShape->getId();} /* modifiers */ /*! Sets the SShape on top of which the ViewShape is built. */ inline void SetSShape(SShape* iSShape) {_SShape = iSShape;} /*! Sets the list of ViewVertex contained in this ViewShape. */ inline void SetVertices(const vector& iVertices) {_Vertices = iVertices;} /*! Sets the list of ViewEdge contained in this ViewShape. */ inline void SetEdges(const vector& iEdges) {_Edges = iEdges;} /*! Adds a ViewVertex to the list. */ inline void AddVertex(ViewVertex *iVertex) { _Vertices.push_back(iVertex); //_SShape->AddNewVertex(iVertex->svertex()); } /*! Adds a ViewEdge to the list */ inline void AddEdge(ViewEdge *iEdge) { _Edges.push_back(iEdge); iEdge->SetShape(this); //_SShape->AddNewEdge(iEdge->fedge()); } /* removes the view edge iViewEdge in the * View Shape and the associated FEdge chain entry * in the underlying SShape */ void RemoveEdge(ViewEdge * iViewEdge); /* removes the view vertex iViewVertex in the * View Shape. */ void RemoveVertex(ViewVertex * iViewVertex); }; /* ############################################# ############################################# ############################################# ###### ###### ###### I M P L E M E N T A T I O N ###### ###### ###### ############################################# ############################################# ############################################# */ /* for inline functions */ void ViewShape::SplitEdge(FEdge *fe, const vector& iViewVertices, vector& ioNewEdges, vector& ioNewViewEdges) { ViewEdge *vEdge = fe->viewedge(); // We first need to sort the view vertices from farther to closer to fe->vertexA SVertex *sv, *sv2; ViewVertex *vva, *vvb; vector::const_iterator vv, vvend; for(vv=iViewVertices.begin(), vvend = iViewVertices.end(); vv!=vvend; vv++) { // Add the viewvertices to the ViewShape AddVertex((*vv)); // retrieve the correct SVertex from the view vertex //-------------------------------------------------- sv = (*vv)->frontSVertex(); sv2 = (*vv)->backSVertex(); if(sv->shape() != sv2->shape()) { if(sv->shape() != _SShape) sv = sv2; } else { // if the shape is the same we can safely differ // the two vertices using their ids: if(sv->getId() != fe->vertexA()->getId()) sv = sv2; } vva = vEdge->A(); vvb = vEdge->B(); // We split Fedge AB into AA' and A'B. A' and A'B are created. // AB becomes (address speaking) AA'. B is updated. //-------------------------------------------------- SShape * shape = fe->shape(); // a new edge, A'B is created. FEdge *newEdge = shape->SplitEdgeIn2(fe, sv); ioNewEdges.push_back(newEdge); ViewEdge *newVEdge; if((vva == 0) || (vvb == 0)) // that means we're dealing with a closed viewedge (loop) { // remove the chain that was starting by the fedge A of vEdge (which is different from fe !!!!) shape->RemoveEdgeFromChain(vEdge->fedgeA()); // we set vEdge->SetA(*vv); vEdge->SetB(*vv); vEdge->SetFEdgeA(newEdge); //FEdge *previousEdge = newEdge->previousEdge(); vEdge->SetFEdgeB(fe); newVEdge = vEdge; vEdge->fedgeA()->SetViewEdge(newVEdge); } else { // while we create the view edge, it updates the "ViewEdge" pointer // of every underlying FEdges to this. newVEdge = new ViewEdge((*vv),vvb);//, newEdge, vEdge->fedgeB()); newVEdge->SetNature((fe)->getNature()); newVEdge->SetFEdgeA(newEdge); //newVEdge->SetFEdgeB(fe); // If our original viewedge is made of one FEdge, // then if((vEdge->fedgeA() == vEdge->fedgeB()) || (fe == vEdge->fedgeB())) newVEdge->SetFEdgeB(newEdge); else newVEdge->SetFEdgeB(vEdge->fedgeB()); //MODIF Id * newId = vEdge->splittingId(); if(newId == 0){ newId = new Id(vEdge->getId()); vEdge->setSplittingId(newId); } newId->setSecond(newId->getSecond()+1); newVEdge->SetId(*newId); newVEdge->setSplittingId(newId); // Id id(vEdge->getId().getFirst(), vEdge->getId().getSecond()+1); // newVEdge->SetId(vEdge->getId()); // vEdge->SetId(id); AddEdge(newVEdge); // here this shape is set as the edge's shape // add new edge to the list of new edges passed as argument: ioNewViewEdges.push_back(newVEdge); if(0 != vvb) vvb->Replace((vEdge), newVEdge); // we split the view edge: vEdge->SetB((*vv)); vEdge->SetFEdgeB(fe); //MODIF // Update fedges so that they point to the new viewedge: newVEdge->UpdateFEdges(); } // check whether this vertex is a front vertex or a back // one if(sv == (*vv)->frontSVertex()) { // -- View Vertex A' -- (*vv)->SetFrontEdgeA(vEdge, true); (*vv)->SetFrontEdgeB(newVEdge, false); } else { // -- View Vertex A' -- (*vv)->SetBackEdgeA(vEdge, true); (*vv)->SetBackEdgeB(newVEdge, false); } } } /**********************************/ /* */ /* */ /* ViewEdge */ /* */ /* */ /**********************************/ // inline Vec3r ViewEdge::orientation2d(int iCombination) const // { // return edge_orientation2d_function(*this, iCombination); // } // inline Vec3r ViewEdge::orientation3d(int iCombination) const // { // return edge_orientation3d_function(*this, iCombination); // } // inline real ViewEdge::z_discontinuity(int iCombination) const // { // return z_discontinuity_edge_function(*this, iCombination); // } // inline float ViewEdge::local_average_depth(int iCombination ) const // { // return local_average_depth_edge_function(*this, iCombination); // } // inline float ViewEdge::local_depth_variance(int iCombination) const // { // return local_depth_variance_edge_function(*this, iCombination); // } // inline real ViewEdge::local_average_density(float sigma, int iCombination) const // { // return density_edge_function(*this, iCombination); // } inline const SShape * ViewEdge::occluded_shape() const { if(0 == _aShape) return 0; return _aShape->sshape(); } // inline Vec3r ViewEdge::curvature2d_as_vector(int iCombination) const // { // return curvature2d_as_vector_edge_function(*this, iCombination); // } // inline real ViewEdge::curvature2d_as_angle(int iCombination) const // { // return curvature2d_as_angle_edge_function(*this, iCombination); // } #endif // VIEWMAP_H