h o m e d o c u m e n t a t i o n c l a s s h i e r a r c h y

ViewMap.h

00001 //
00002 //  Filename         : ViewMap.h
00003 //  Author(s)        : Stephane Grabli
00004 //  Purpose          : Classes to define a View Map (ViewVertex, ViewEdge, etc.)
00005 //  Date of creation : 03/09/2002
00006 //
00008 
00009 
00010 //
00011 //  Copyright (C) : Please refer to the COPYRIGHT file distributed 
00012 //   with this source distribution. 
00013 //
00014 //  This program is free software; you can redistribute it and/or
00015 //  modify it under the terms of the GNU General Public License
00016 //  as published by the Free Software Foundation; either version 2
00017 //  of the License, or (at your option) any later version.
00018 //
00019 //  This program is distributed in the hope that it will be useful,
00020 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022 //  GNU General Public License for more details.
00023 //
00024 //  You should have received a copy of the GNU General Public License
00025 //  along with this program; if not, write to the Free Software
00026 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 //
00029 
00030 #ifndef  VIEWMAP_H
00031 # define VIEWMAP_H
00032 
00033 # include "../system/BaseIterator.h"
00034 # include "../system/FreestyleConfig.h"
00035 # include "../geometry/GeomUtils.h"
00036 # include "Interface0D.h"
00037 # include "Interface1D.h"
00038 # include "Silhouette.h" // defines the embedding
00039 
00040                   /**********************************/
00041                   /*                                */
00042                   /*                                */
00043                   /*             ViewMap            */
00044                   /*                                */
00045                   /*                                */
00046                   /**********************************/
00047 
00048 
00049 /*  Density
00050     Mean area depth value
00051     distance to a point
00052     */
00053 
00054 class ViewVertex;
00055 class ViewEdge;
00056 class ViewShape;
00057 class TVertex;
00058 
00060 class LIB_VIEW_MAP_EXPORT ViewMap 
00061 {
00062 public:
00063 
00064   typedef vector<ViewEdge*> viewedges_container;
00065   typedef vector<ViewVertex*> viewvertices_container;
00066   typedef vector<ViewShape*> viewshapes_container;
00067   typedef vector<SVertex*> svertices_container;
00068   typedef vector<FEdge*> fedges_container;
00069 
00070 private:
00071 
00072   static ViewMap *_pInstance;
00073   viewshapes_container _VShapes; // view shapes
00074   viewedges_container _VEdges; // view edges
00075   viewvertices_container _VVertices; // view vertices
00076   fedges_container _FEdges; // feature edges (embedded edges)
00077   svertices_container _SVertices; // embedded vertices
00078   BBox<Vec3r> _scene3DBBox;
00079 
00080 public:
00081 
00085   void* userdata;
00086 
00088   ViewMap() {
00089     _pInstance = this;
00090     userdata = 0;
00091   }
00093   virtual ~ViewMap();
00094 
00098   const ViewEdge * GetClosestViewEdge(real x, real y) const ;
00099 
00103   const FEdge * GetClosestFEdge(real x, real y) const ;
00104 
00105   /* accessors */
00109   static inline ViewMap * getInstance() {return _pInstance;}
00110   /* Returns the list of ViewShapes of the scene. */
00111   inline viewshapes_container& ViewShapes() {return _VShapes;}
00112   /* Returns the list of ViewEdges of the scene. */
00113   inline viewedges_container& ViewEdges() {return _VEdges;}
00114   /* Returns the list of ViewVertices of the scene. */
00115   inline viewvertices_container& ViewVertices() {return _VVertices;}
00116   /* Returns the list of FEdges of the scene. */
00117   inline fedges_container& FEdges() {return _FEdges;}
00118   /* Returns the list of SVertices of the scene. */
00119   inline svertices_container& SVertices() {return _SVertices;}
00120   /* Returns an iterator pointing onto the first ViewEdge of the list. */
00121   inline viewedges_container::iterator viewedges_begin() {return _VEdges.begin();}
00122   inline viewedges_container::iterator viewedges_end() {return _VEdges.end();}
00123   inline int viewedges_size() {return _VEdges.size();}
00124   ViewShape * viewShape(unsigned index);
00126   inline BBox<Vec3r> getScene3dBBox() const {return _scene3DBBox;}
00127 
00128   /* modifiers */
00129   inline void AddViewShape(ViewShape *iVShape) {_VShapes.push_back(iVShape);}
00130   inline void AddViewEdge(ViewEdge *iVEdge) {_VEdges.push_back(iVEdge);}
00131   inline void AddViewVertex(ViewVertex *iVVertex) {_VVertices.push_back(iVVertex);}
00132   inline void AddFEdge(FEdge *iFEdge) {_FEdges.push_back(iFEdge);}
00133   inline void AddSVertex(SVertex *iSVertex) {_SVertices.push_back(iSVertex);}
00135   inline void setScene3dBBox(const BBox<Vec3r>& bbox) {_scene3DBBox=bbox;}
00136 
00137   /* Creates a T vertex in the view map.
00138    *  A T vertex is the intersection between 2
00139    *  FEdges (before these ones are splitted).
00140    *  The TVertex is a 2D intersection but it 
00141    *  corresponds to a 3D point on each of the 2 FEdges.
00142    *    iA3D
00143    *      The 3D coordinates of the point corresponding 
00144    *      to the intersection on the first edge.
00145    *    iA2D
00146    *      The x,y,z 2D coordinates of the projection 
00147    *      of iA3D
00148    *    iFEdgeA
00149    *      The first FEdge
00150    *    iB3D
00151    *      The 3D coordinates of the point corresponding 
00152    *      to the intersection on the second edge.
00153    *    iB2D
00154    *      The x,y,z 2D coordinates of the projection 
00155    *      of iB3D
00156    *    iFEdgeB
00157    *      The second FEdge   
00158    *    id
00159    *      The id that must be given to that TVertex
00160    */
00161   TVertex* CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFEdgeA,
00162                          const Vec3r& iB3D, const Vec3r& iB2D, FEdge *iFEdgeB,
00163                          const Id& id);
00164 
00165   /* Updates the structures to take into account the fact 
00166    *  that a SVertex must now be considered as a ViewVertex 
00167    *    iVertex
00168    *      The SVertex on top of which the ViewVertex is built (it is necessarily
00169    *      a NonTVertex because it is a SVertex)
00170    *    newViewEdges
00171    *      The new ViewEdges that must be add to the ViewMap
00172    */
00173   ViewVertex * InsertViewVertex(SVertex *iVertex, vector<ViewEdge*>& newViewEdges);
00174 
00175   /* connects a FEdge to the graph trough a SVertex */
00176   //FEdge * Connect(FEdge *ioEdge, SVertex *ioVertex);
00177 };
00178 
00179                   /**********************************/
00180                   /*                                */
00181                   /*                                */
00182                   /*             ViewVertex         */
00183                   /*                                */
00184                   /*                                */
00185                   /**********************************/
00186 
00187 class ViewEdge;
00188 class SShape;
00189 
00190 namespace ViewVertexInternal {
00191   class edge_const_traits;
00192   class edge_nonconst_traits;
00193   template<class Traits> class edge_iterator_base ;
00194   class orientedViewEdgeIterator;
00195 } // end of namespace ViewEdgeInternal
00208 class LIB_VIEW_MAP_EXPORT ViewVertex : public Interface0D
00209 {
00210 public: // Implementation of Interface0D
00211 
00213   virtual string getExactTypeName() const {
00214     return "ViewVertex";
00215   }
00216 
00217 public:  
00218   friend class ViewShape;
00219   typedef pair<ViewEdge*, bool> directedViewEdge; // if bool = true, the ViewEdge is incoming
00220 
00221   typedef vector<directedViewEdge> edges_container;
00222 
00223   typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_nonconst_traits> edge_iterator;
00224   typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_const_traits> const_edge_iterator;
00225 
00226 private:
00227 
00228   Nature::VertexNature _Nature;
00229 
00230 public:
00234   void * userdata;
00236   inline ViewVertex() {userdata = 0;_Nature = Nature::VIEW_VERTEX; }
00237   inline ViewVertex(Nature::VertexNature nature) {
00238     userdata = 0;
00239     _Nature = Nature::VIEW_VERTEX | nature;
00240   }
00241 
00242 protected:
00244   inline ViewVertex(ViewVertex& iBrother)
00245   {
00246     _Nature = iBrother._Nature;
00247     iBrother.userdata = this;
00248     userdata = 0;
00249   }
00251   virtual ViewVertex * dupplicate() = 0;
00252   
00253 public:
00255   virtual ~ViewVertex() {}
00256 
00257   /* accessors */
00259   virtual Nature::VertexNature getNature() const {
00260     return _Nature;
00261   }
00262 
00263   /* modifiers */
00265   inline void setNature(Nature::VertexNature iNature) {_Nature = iNature;}
00266   
00267   /* Replaces old edge by new edge */
00268   virtual void Replace(ViewEdge *, ViewEdge *) {}
00269 
00270 public:
00271   
00272   /* iterators access */
00273   // allows iteration on the edges that comes from/goes to 
00274   // this vertex in CCW order (order defined in 2D in the image plan)
00275   virtual edge_iterator edges_begin() = 0;
00276   virtual const_edge_iterator edges_begin() const = 0;
00277   virtual edge_iterator edges_end()   = 0;
00278   virtual const_edge_iterator edges_end() const   = 0;
00279   virtual edge_iterator edges_iterator(ViewEdge *iEdge) = 0;
00280   virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const = 0;
00281 
00282   // Iterator access
00288   virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() = 0;
00292   virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() = 0;
00296   virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) = 0;
00297   
00298 };
00299 
00300                   /**********************************/
00301                   /*                                */
00302                   /*                                */
00303                   /*             TVertex            */
00304                   /*                                */
00305                   /*                                */
00306                   /**********************************/
00307 
00316 class LIB_VIEW_MAP_EXPORT TVertex : public ViewVertex
00317 {
00318 public:
00319   typedef vector<directedViewEdge*> edge_pointers_container;
00320 public: // Implementation of Interface0D
00321 
00323   virtual string getExactTypeName() const {
00324     return "TVertex";
00325   }
00326 
00327   // Data access methods
00328   /* Returns the 3D x coordinate of the vertex .
00329    * Ambiguous in this case.
00330    */
00331   virtual real getX() const {
00332     cerr << "Warning: getX() undefined for this point" << endl;
00333     return _FrontSVertex->point3D().x();
00334   }
00335 
00336   virtual real getY() const {
00337     cerr << "Warning: getX() undefined for this point" << endl;
00338     return _FrontSVertex->point3D().y();
00339   }
00340 
00341   virtual real getZ() const {
00342     cerr << "Warning: getX() undefined for this point" << endl;
00343     return _FrontSVertex->point3D().z();
00344   }
00345 
00347   virtual Vec3f getPoint3D() const {
00348     cerr << "Warning: getPoint3D() undefined for this point" << endl;
00349     return _FrontSVertex->getPoint3D();
00350   }
00351 
00353   virtual real getProjectedX() const {
00354     return _FrontSVertex->point2D().x();
00355   }
00356 
00358   virtual real getProjectedY() const {
00359     return _FrontSVertex->point2D().y();
00360   }
00361 
00362   virtual real getProjectedZ() const {
00363     return _FrontSVertex->point2D().z();
00364   }
00365 
00367   virtual Vec2f getPoint2D() const {
00368     return _FrontSVertex->getPoint2D();
00369   }
00370 
00372   virtual Id getId() const {
00373     return _Id;
00374   }
00375 
00377   // it can't
00379   virtual ViewVertex * castToViewVertex(){
00380     return this;
00381   }
00382 
00384   virtual TVertex * castToTVertex(){
00385     return this;
00386   }
00387 
00388 private:
00389   SVertex  *_FrontSVertex;
00390   SVertex  *_BackSVertex;
00391   directedViewEdge _FrontEdgeA;
00392   directedViewEdge _FrontEdgeB;
00393   directedViewEdge _BackEdgeA;
00394   directedViewEdge _BackEdgeB;
00395   Id _Id; // id to identify t vertices . these id will be negative in order not to be mixed with NonTVertex ids.
00396   edge_pointers_container _sortedEdges; // the list of the four ViewEdges, ordered in CCW order (in the image plan)
00397 
00398 
00399 public:
00401   inline TVertex() : ViewVertex(Nature::T_VERTEX) 
00402   {
00403     _FrontSVertex = 0;
00404     _BackSVertex = 0;
00405     _FrontEdgeA.first = 0;
00406     _FrontEdgeB.first = 0;
00407     _BackEdgeA.first = 0;
00408     _BackEdgeB.first = 0;
00409 
00410   }
00411 
00412   inline TVertex(SVertex *svFront, SVertex *svBack)
00413     : ViewVertex(Nature::T_VERTEX)
00414   {
00415     _FrontSVertex = svFront;
00416     _BackSVertex = svBack;
00417     _FrontEdgeA.first = 0;
00418     _FrontEdgeB.first = 0;
00419     _BackEdgeA.first = 0;
00420     _BackEdgeB.first = 0;
00421     svFront->SetViewVertex(this);
00422     svBack->SetViewVertex(this);
00423   }
00424 
00425 protected:
00427   inline TVertex(TVertex& iBrother)
00428     : ViewVertex(iBrother)
00429   {
00430     _FrontSVertex = iBrother._FrontSVertex;
00431     _BackSVertex = iBrother._BackSVertex;
00432     _FrontEdgeA = iBrother._FrontEdgeA;
00433     _FrontEdgeB = iBrother._FrontEdgeB;
00434     _BackEdgeA = iBrother._BackEdgeA;
00435     _BackEdgeB = iBrother._BackEdgeB;
00436     _sortedEdges = iBrother._sortedEdges;
00437   }
00438 
00440   virtual ViewVertex * dupplicate()
00441   {
00442     TVertex *clone = new TVertex(*this);
00443     return clone;
00444   }
00445 
00446 public:
00447   /* accessors */
00449   inline SVertex  *frontSVertex() {return _FrontSVertex;}
00451   inline SVertex  *backSVertex() {return _BackSVertex;}
00452   inline directedViewEdge& frontEdgeA() {return _FrontEdgeA;}
00453   inline directedViewEdge& frontEdgeB() {return _FrontEdgeB;}
00454   inline directedViewEdge& backEdgeA() {return _BackEdgeA;}
00455   inline directedViewEdge& backEdgeB() {return _BackEdgeB;}
00456   
00457   /* modifiers */
00459   inline void SetFrontVertex(SVertex  *iFrontSVertex) {_FrontSVertex = iFrontSVertex;_FrontSVertex->SetViewVertex(this);}
00461   inline void SetBackSVertex(SVertex  *iBackSVertex) {_BackSVertex = iBackSVertex;_BackSVertex->SetViewVertex(this);}
00462   void SetFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming=true);
00463   void SetFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming=true) ;
00464   void SetBackEdgeA(ViewEdge *iBackEdgeA, bool incoming=true);
00465   void SetBackEdgeB(ViewEdge *iBackEdgeB, bool incoming=true) ;
00467   inline void SetId(const Id& iId) {_Id = iId;}
00468   
00470   inline SVertex * GetSVertex(FEdge *iFEdge)
00471   {
00472     const vector<FEdge*>& vfEdges = _FrontSVertex->fedges();
00473     vector<FEdge*>::const_iterator fe,fend;
00474     for(fe=vfEdges.begin(),fend=vfEdges.end();
00475     fe!=fend;
00476     fe++)
00477     {
00478       if((*fe) == iFEdge)
00479         return _FrontSVertex;
00480     }
00481 
00482     const vector<FEdge*>& vbEdges = _BackSVertex->fedges();
00483     for(fe=vbEdges.begin(),fend=vbEdges.end();
00484     fe!=fend;
00485     fe++)
00486     {
00487       if((*fe) == iFEdge)
00488         return _BackSVertex;
00489     }
00490     return 0;
00491   }
00492 
00493   virtual void Replace(ViewEdge *iOld, ViewEdge *iNew);
00494   
00501   virtual ViewEdge * mate(ViewEdge* iEdgeA)
00502   {
00503     if(iEdgeA == _FrontEdgeA.first)
00504       return _FrontEdgeB.first;
00505     if(iEdgeA == _FrontEdgeB.first)
00506       return _FrontEdgeA.first;
00507     if(iEdgeA == _BackEdgeA.first)
00508       return _BackEdgeB.first;
00509     if(iEdgeA == _BackEdgeB.first)
00510       return _BackEdgeA.first;
00511     return 0;
00512   }
00513   
00514   /* iterators access */
00515   virtual edge_iterator edges_begin();
00516   virtual const_edge_iterator edges_begin() const;
00517   virtual edge_iterator edges_end();
00518   virtual const_edge_iterator edges_end() const;
00519   virtual edge_iterator edges_iterator(ViewEdge *iEdge);
00520   virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const;
00521 
00527   virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() ;
00531   virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() ;
00535   virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) ;
00536 };
00537 
00538 
00539                   /**********************************/
00540                   /*                                */
00541                   /*                                */
00542                   /*             NonTVertex         */ 
00543                   /*                                */
00544                   /*                                */
00545                   /**********************************/
00546 
00547 
00548 // (non T vertex)
00553 class LIB_VIEW_MAP_EXPORT NonTVertex : public ViewVertex
00554 {
00555 public:
00556   typedef vector<directedViewEdge> edges_container;
00557 
00558 public: // Implementation of Interface0D
00559 
00561   virtual string getExactTypeName() const {
00562     return "NonTVertex";
00563   }
00564 
00565   // Data access methods
00567   virtual real getX() const {
00568     return _SVertex->point3D().x();
00569   }
00571   virtual real getY() const {
00572     return _SVertex->point3D().y();
00573   }
00574 
00576   virtual real getZ() const {
00577     return _SVertex->point3D().z();
00578   }
00579 
00581   virtual Vec3f getPoint3D() const {
00582     return _SVertex->getPoint3D();
00583   }
00584 
00586   virtual real getProjectedX() const {
00587     return _SVertex->point2D().x();
00588   }
00589 
00591   virtual real getProjectedY() const {
00592     return _SVertex->point2D().y();
00593   }
00594 
00596   virtual real getProjectedZ() const {
00597     return _SVertex->point2D().z();
00598   }
00599 
00601   virtual Vec2f getPoint2D() const {
00602     return _SVertex->getPoint2D();
00603   }
00604 
00606   virtual Id getId() const {
00607     return _SVertex->getId();
00608   }
00609 
00611   virtual SVertex * castToSVertex(){
00612     return _SVertex;
00613   }
00614 
00616   virtual ViewVertex * castToViewVertex(){
00617     return this;
00618   }
00619 
00621   virtual NonTVertex * castToNonTVertex(){
00622     return this;
00623   }
00624 
00625 private:
00626   SVertex *_SVertex;
00627   edges_container _ViewEdges; 
00628 public:
00630   inline NonTVertex() : ViewVertex(Nature::NON_T_VERTEX) { _SVertex = 0; }
00632   inline NonTVertex(SVertex* iSVertex) : ViewVertex(Nature::NON_T_VERTEX)
00633   {
00634     _SVertex = iSVertex;
00635     _SVertex->SetViewVertex(this);
00636   }
00637 protected:
00639   inline NonTVertex(NonTVertex& iBrother)
00640     : ViewVertex(iBrother)
00641   {
00642     _SVertex = iBrother._SVertex;
00643     _SVertex->SetViewVertex(this);
00644     _ViewEdges = iBrother._ViewEdges;
00645   }
00647   virtual ViewVertex * dupplicate()
00648   {
00649     NonTVertex *clone = new NonTVertex(*this);
00650     return clone;
00651   }
00652 public:
00654   virtual ~NonTVertex() {}
00655   
00656   /* accessors */
00658   inline SVertex * svertex() {return _SVertex;}
00659   inline edges_container& viewedges() {return _ViewEdges;}
00660   
00661   /* modifiers */
00663   inline void SetSVertex(SVertex *iSVertex) {_SVertex = iSVertex;_SVertex->SetViewVertex(this);}
00664   inline void SetViewEdges(const vector<directedViewEdge>& iViewEdges) {_ViewEdges = iViewEdges;}
00665   void AddIncomingViewEdge(ViewEdge * iVEdge) ;
00666   void AddOutgoingViewEdge(ViewEdge * iVEdge) ;
00667   inline void AddViewEdge(ViewEdge * iVEdge, bool incoming=true) {
00668     if(incoming)
00669       AddIncomingViewEdge(iVEdge);
00670     else
00671       AddOutgoingViewEdge(iVEdge);
00672   }
00673   /* Replaces old edge by new edge */
00674   virtual void Replace(ViewEdge *iOld, ViewEdge *iNew)
00675   {
00676     
00677       edges_container::iterator insertedve;
00678       for(edges_container::iterator ve=_ViewEdges.begin(),vend=_ViewEdges.end();
00679       ve!=vend;
00680       ve++)
00681       {
00682         if((ve)->first == iOld)
00683         {
00684           insertedve = _ViewEdges.insert(ve, directedViewEdge(iNew, ve->second));// inserts e2 before ve.
00685                                               // returns an iterator pointing toward e2. ve is invalidated.
00686           // we want to remove e1, but we can't use ve anymore:
00687           insertedve++; // insertedve points now to e1
00688           _ViewEdges.erase(insertedve);
00689           return;
00690         }
00691       } 
00692   }    
00693 
00694   
00695   /* iterators access */
00696   virtual edge_iterator edges_begin();
00697   virtual const_edge_iterator edges_begin() const;
00698   virtual edge_iterator edges_end();
00699   virtual const_edge_iterator edges_end() const;
00700   virtual edge_iterator edges_iterator(ViewEdge *iEdge);
00701   virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const;
00702 
00708   virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() ;
00712   virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() ;
00716   virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) ;
00717 };
00718 
00719                   /**********************************/
00720                   /*                                */
00721                   /*                                */
00722                   /*             ViewEdge           */
00723                   /*                                */
00724                   /*                                */
00725                   /**********************************/
00726 
00727 /* Geometry(normals...)
00728   Nature of edges
00729   2D spaces (1or2, material, z...)
00730   Parent Shape
00731   3D Shading, material
00732   Importance
00733   Occluders
00734   */
00735 class ViewShape;
00736 
00737 namespace ViewEdgeInternal {
00738   template<class Traits> class edge_iterator_base ;
00739   template<class Traits> class fedge_iterator_base ;
00740   template<class Traits> class vertex_iterator_base ;
00741 } // end of namespace ViewEdgeInternal
00742 
00747 class LIB_VIEW_MAP_EXPORT ViewEdge : public Interface1D
00748 {
00749 public: // Implementation of Interface0D
00750 
00752   virtual string getExactTypeName() const {
00753     return "ViewEdge";
00754   }
00755 
00756   // Data access methods
00758   virtual Id getId() const {
00759     return _Id;
00760   }
00761 
00763   virtual Nature::EdgeNature getNature() const {
00764     return _Nature;
00765   }
00766 
00767 public:
00768   
00769   typedef SVertex vertex_type;
00770   friend class ViewShape;
00771   // for ViewEdge iterator
00772   typedef ViewEdgeInternal::edge_iterator_base<Nonconst_traits<ViewEdge*> > edge_iterator;
00773   typedef ViewEdgeInternal::edge_iterator_base<Const_traits<ViewEdge*> > const_edge_iterator;
00774   // for fedge iterator
00775   typedef ViewEdgeInternal::fedge_iterator_base<Nonconst_traits<FEdge*> > fedge_iterator;
00776   typedef ViewEdgeInternal::fedge_iterator_base<Const_traits<FEdge*> > const_fedge_iterator;
00777   // for svertex iterator
00778   typedef ViewEdgeInternal::vertex_iterator_base<Nonconst_traits<SVertex*> > vertex_iterator;
00779   typedef ViewEdgeInternal::vertex_iterator_base<Const_traits<SVertex*> > const_vertex_iterator;
00780 private:
00781 
00782   ViewVertex * __A; // edge starting vertex
00783   ViewVertex * __B; // edge ending vertex
00784   Nature::EdgeNature _Nature; // nature of view edge
00785   ViewShape *_Shape; // shape to which the view edge belongs
00786   FEdge * _FEdgeA; // first edge of the embedded fedges chain
00787   FEdge * _FEdgeB; // last edge of the embedded fedges chain
00788   Id _Id;
00789   unsigned _ChainingTimeStamp;
00790   ViewShape *_aShape; // The silhouette view edge separates 2 2D spaces. The one on the left is 
00791   // necessarly the Shape _Shape (the one to which this edge belongs to)
00792   // and _aShape is the one on its right // NON GERE PAR LE COPY CONSTRUCTEUR
00793   int _qi;
00794   vector<ViewShape*> _Occluders;
00795 
00796   // tmp
00797   Id * _splittingId;
00798 
00799 public:
00803   void * userdata;
00805   inline ViewEdge() {
00806     __A=0;
00807     __B=0;
00808     _FEdgeA = 0;
00809     _FEdgeB = 0;
00810     _ChainingTimeStamp = 0;
00811     _qi = 0;
00812     _aShape=0;
00813     userdata = 0;
00814     _splittingId = 0;
00815   }
00816   inline ViewEdge(ViewVertex* iA, ViewVertex *iB)
00817   {
00818     __A = iA;
00819     __B = iB;
00820     _FEdgeA = 0;
00821     _FEdgeB = 0;
00822     _Shape = 0;
00823     _ChainingTimeStamp = 0;
00824     _aShape = 0;
00825     _qi = 0;
00826     userdata = 0;
00827     _splittingId = 0;
00828   }
00829   inline ViewEdge(ViewVertex* iA, ViewVertex *iB, FEdge *iFEdgeA)
00830   {
00831     __A = iA;
00832     __B = iB;
00833     _FEdgeA = iFEdgeA;
00834     _FEdgeB = 0;
00835     _Shape = 0;
00836     _ChainingTimeStamp = 0;
00837     _aShape = 0;
00838     _qi = 0;
00839     userdata = 0;
00840     _splittingId = 0;
00841   }
00842   inline ViewEdge(ViewVertex* iA, ViewVertex *iB, FEdge *iFEdgeA, FEdge *iFEdgeB, ViewShape *iShape)
00843   {
00844     __A = iA;
00845     __B = iB;
00846     _FEdgeA = iFEdgeA;
00847     _FEdgeB = iFEdgeB;
00848     _Shape = iShape;
00849     _ChainingTimeStamp = 0;
00850     _aShape = 0;
00851     _qi = 0;
00852     userdata = 0;
00853     _splittingId = 0;
00854     UpdateFEdges(); // tells every FEdge between iFEdgeA and iFEdgeB that this is theit ViewEdge
00855   }
00856 protected:
00858   inline ViewEdge(ViewEdge& iBrother)
00859   {
00860     __A = iBrother.__A;
00861     __B = iBrother.__B;
00862     _FEdgeA = iBrother._FEdgeA;
00863     _FEdgeB = iBrother._FEdgeB;
00864     _Nature = iBrother._Nature;
00865     _Shape = 0;
00866     _Id = iBrother._Id;
00867     _ChainingTimeStamp = iBrother._ChainingTimeStamp;
00868     _aShape = iBrother._aShape;
00869     _qi = iBrother._qi;
00870     _splittingId = 0;
00871     iBrother.userdata = this;
00872     userdata = 0;
00873   }
00875   virtual ViewEdge * dupplicate()
00876   {
00877     ViewEdge *clone = new ViewEdge(*this);
00878     return clone;
00879   }
00880 
00881 public:
00883   virtual ~ViewEdge()
00884   {
00885     //    if(0 != _aFace)
00886     //    {
00887     //      delete _aFace;
00888     //      _aFace = 0;
00889     //    }
00890     // only the last splitted deletes this id
00891     if(_splittingId){
00892       if(*_splittingId == _Id)
00893         delete _splittingId;
00894     }
00895   }
00896 
00897   /* accessors */
00899   inline  ViewVertex* A()  {return __A;}
00901   inline  ViewVertex* B()  {return __B;}
00903   inline  FEdge* fedgeA()  {return _FEdgeA;}
00905   inline  FEdge* fedgeB()  {return _FEdgeB;}
00907   inline ViewShape * viewShape() {return _Shape;}
00913   inline ViewShape * aShape() {return _aShape;}
00917   inline bool isClosed() 
00918   {
00919     if(__B == 0)
00920       return true;
00921     return false;
00922   }
00924   inline unsigned getChainingTimeStamp() {return _ChainingTimeStamp;}
00925   inline const ViewShape * aShape() const {return _aShape;}
00926   inline const ViewShape * bShape() const {return _Shape;}
00927   inline vector<ViewShape*>& occluders() {return _Occluders;}
00928   inline Id * splittingId() {return _splittingId;}
00929   
00930   /* modifiers */
00932   inline void SetA(ViewVertex* iA) { __A = iA; }
00934   inline void SetB(ViewVertex* iB) { __B = iB; }
00936   inline void SetNature(Nature::EdgeNature iNature) { _Nature = iNature; }
00938   inline void SetFEdgeA(FEdge* iFEdge) { _FEdgeA = iFEdge; }
00940   inline void SetFEdgeB(FEdge* iFEdge) { _FEdgeB = iFEdge; }
00942   inline void SetShape(ViewShape *iVShape) 
00943   {
00944     _Shape = iVShape;
00945   }
00947   inline void SetId(const Id& id) {_Id = id;}
00949   void UpdateFEdges();
00951   inline void SetaShape(ViewShape * iShape) {_aShape = iShape;}
00953   inline void SetQI(int qi) {_qi = qi;}
00955   inline void setChainingTimeStamp(unsigned ts) {_ChainingTimeStamp = ts;}
00956   inline void AddOccluder(ViewShape *iShape) {_Occluders.push_back(iShape);}
00957   inline void setSplittingId(Id * id) {_splittingId = id;}
00958 
00959   /* stroke interface definition */
00960   inline bool intersect_2d_area(const Vec2r& iMin, const Vec2r& iMax) const
00961   {
00962     // parse edges to check if one of them is intersection the region:
00963     FEdge * current = _FEdgeA;
00964     do
00965     {
00966       if(GeomUtils::intersect2dSeg2dArea(iMin,iMax, 
00967                                          Vec2r(current->vertexA()->point2D()[0],current->vertexA()->point2D()[1]),
00968                                          Vec2r(current->vertexB()->point2D()[0],current->vertexB()->point2D()[1])))
00969       
00970         return true;
00971       current = current->nextEdge();
00972     }while((current != 0) && (current != _FEdgeA));
00973 
00974     return false;
00975   }
00976   inline bool include_in_2d_area(const Vec2r& iMin, const Vec2r& iMax) const
00977   {
00978     // parse edges to check if all of them are intersection the region:
00979     FEdge * current = _FEdgeA;
00980     
00981     do
00982     {
00983       if(!GeomUtils::include2dSeg2dArea(iMin,iMax, 
00984                                         Vec2r(current->vertexA()->point2D()[0],current->vertexA()->point2D()[1]),
00985                                         Vec2r(current->vertexB()->point2D()[0],current->vertexB()->point2D()[1])))
00986         return false;
00987       current = current->nextEdge();
00988     }while((current != 0) && (current != _FEdgeA));
00989     
00990     return true;
00991   }
00992 
00993   /* Information access interface */
00994   
00995   //inline Nature::EdgeNature viewedge_nature() const {return getNature();}
00996   //float viewedge_length() const ;
00998   real getLength2D() const;
00999   //inline Material material() const {return _FEdgeA->vertexA()->shape()->material();}
01000   inline int qi() const {return _qi;}
01001   inline occluder_container::const_iterator occluders_begin() const {return _Occluders.begin();}
01002   inline occluder_container::const_iterator occluders_end() const {return _Occluders.end();}
01003   inline int occluders_size() const {return _Occluders.size();}
01004   inline bool occluders_empty() const {return _Occluders.empty();}
01005   inline const Polygon3r& occludee() const {return (_FEdgeA->aFace());}
01006   inline const SShape * occluded_shape() const ;
01007   inline const bool occludee_empty() const {if(_aShape == 0) return true; return false;}
01008   //inline real z_discontinuity(int iCombination = 0) const ;
01009   inline Id shape_id() const {return _FEdgeA->vertexA()->shape()->getId();}
01010   inline const SShape * shape() const {return _FEdgeA->vertexA()->shape();}
01011   inline float shape_importance() const {return _FEdgeA->shape_importance();} 
01012 
01013   /* iterators access */
01014   // view edge iterator
01015   edge_iterator ViewEdge_iterator();
01016   const_edge_iterator ViewEdge_iterator() const;
01017   // feature edge iterator
01018   fedge_iterator fedge_iterator_begin();
01019   const_fedge_iterator fedge_iterator_begin() const;
01020   fedge_iterator fedge_iterator_last();
01021   const_fedge_iterator fedge_iterator_last() const;
01022   fedge_iterator fedge_iterator_end();
01023   const_fedge_iterator fedge_iterator_end() const;
01024   // embedding vertex iterator
01025   const_vertex_iterator vertices_begin() const;
01026   vertex_iterator vertices_begin();
01027   const_vertex_iterator vertices_last() const;
01028   vertex_iterator vertices_last();
01029   const_vertex_iterator vertices_end() const;
01030   vertex_iterator vertices_end();
01031 
01032   // Iterator access (Interface1D)
01038   virtual Interface0DIterator verticesBegin();
01044   virtual Interface0DIterator verticesEnd();
01045 
01053   virtual Interface0DIterator pointsBegin(float t=0.f);
01061   virtual Interface0DIterator pointsEnd(float t=0.f);
01062 };
01063 
01064   
01065 
01066                   /**********************************/
01067                   /*                                */
01068                   /*                                */
01069                   /*             ViewShape          */
01070                   /*                                */
01071                   /*                                */
01072                   /**********************************/
01073 
01077 class LIB_VIEW_MAP_EXPORT ViewShape
01078 {
01079 private:
01080   vector<ViewVertex*> _Vertices;
01081   vector<ViewEdge*> _Edges;
01082   SShape * _SShape;
01083   
01084 
01085 public:
01089   void* userdata;
01091   inline ViewShape() { userdata = 0; _SShape = 0;}
01093   inline ViewShape(SShape *iSShape) {userdata = 0; _SShape = iSShape;}//_SShape->SetViewShape(this);}
01095   inline ViewShape(ViewShape& iBrother)
01096   {
01097     userdata = 0;
01098     vector<ViewVertex*>::iterator vv,vvend;
01099     vector<ViewEdge*>::iterator ve, veend;
01100 
01101     _SShape = iBrother._SShape;
01102 
01103     vector<ViewVertex*>& vvertices = iBrother.vertices();
01104     // dupplicate vertices
01105     for(vv=vvertices.begin(), vvend=vvertices.end();
01106     vv!=vvend;
01107     vv++)
01108     {
01109       ViewVertex * newVertex = (*vv)->dupplicate();
01110       AddVertex(newVertex);
01111     }
01112 
01113     vector<ViewEdge*>& vvedges = iBrother.edges();
01114     // dupplicate edges
01115     for(ve=vvedges.begin(), veend=vvedges.end();
01116     ve!=veend;
01117     ve++)
01118     {
01119       ViewEdge * newEdge = (*ve)->dupplicate();
01120       AddEdge(newEdge); // here the shape is set as the edge's shape
01121     }
01122 
01123     //-------------------------
01124     // remap edges in vertices:
01125     //-------------------------
01126     for(vv=_Vertices.begin(), vvend=_Vertices.end();
01127     vv!=vvend;
01128     vv++)
01129     {
01130       switch((*vv)->getNature())
01131       {  
01132       case Nature::T_VERTEX:
01133         {
01134           TVertex *v = (TVertex*)(*vv);
01135           ViewEdge *veFrontA = (ViewEdge*)(v)->frontEdgeA().first->userdata;
01136           ViewEdge *veFrontB = (ViewEdge*)(v)->frontEdgeB().first->userdata;
01137           ViewEdge *veBackA = (ViewEdge*)(v)->backEdgeA().first->userdata;
01138           ViewEdge *veBackB = (ViewEdge*)(v)->backEdgeB().first->userdata;
01139 
01140           v->SetFrontEdgeA(veFrontA, v->frontEdgeA().second);
01141           v->SetFrontEdgeB(veFrontB, v->frontEdgeB().second);
01142           v->SetBackEdgeA(veBackA, v->backEdgeA().second);
01143           v->SetBackEdgeB(veBackB, v->backEdgeB().second);
01144         }
01145         break;
01146       case Nature::NON_T_VERTEX:
01147         {
01148           NonTVertex * v = (NonTVertex*)(*vv);
01149           vector<ViewVertex::directedViewEdge>& vedges = (v)->viewedges();
01150           vector<ViewVertex::directedViewEdge> newEdges;
01151           for(vector<ViewVertex::directedViewEdge>::iterator ve=vedges.begin(), veend=vedges.end();
01152           ve!=veend;
01153           ve++)
01154           {
01155             ViewEdge *current = (ViewEdge*)((ve)->first)->userdata;
01156             newEdges.push_back(ViewVertex::directedViewEdge(current, ve->second));
01157           }
01158           (v)->SetViewEdges(newEdges);
01159         }
01160         break;
01161       default:
01162         ;
01163       }
01164     }
01165     
01166     //-------------------------------------
01167     // remap vertices in edges:
01168     //-------------------------------------
01169     for(ve=_Edges.begin(),veend=_Edges.end();
01170         ve!=veend;
01171         ve++)
01172       {
01173         (*ve)->SetA((ViewVertex*)((*ve)->A()->userdata));
01174         (*ve)->SetB((ViewVertex*)((*ve)->B()->userdata));
01175         //---------------------------------------
01176         // Update all embedded FEdges
01177         //---------------------------------------
01178         (*ve)->UpdateFEdges();
01179       }
01180     
01181     
01182     // reset all brothers userdata to NULL:
01183     //-------------------------------------
01184     //---------
01185     // vertices
01186     //---------
01187     for(vv=vvertices.begin(),vvend=vvertices.end();
01188         vv!=vvend;
01189         vv++)
01190       {
01191         (*vv)->userdata = NULL;
01192       }
01193 
01194     //------
01195     // edges
01196     //------
01197     for(ve=vvedges.begin(),veend=vvedges.end();
01198         ve!=veend;
01199         ve++)
01200       {
01201         (*ve)->userdata = NULL;
01202       }  
01203   }
01204 
01206   virtual ViewShape * dupplicate()
01207   {
01208     ViewShape *clone = new ViewShape(*this);
01209     return clone;
01210   }
01211 
01213   virtual ~ViewShape();
01214 
01215   /* splits a view edge into several view edges. 
01216    *    fe
01217    *      The FEdge that gets splitted
01218    *    iViewVertices
01219    *      The view vertices corresponding to the different intersections for the edge fe.
01220    *      This list need to be sorted such as the first view vertex is the 
01221    *      farther away from fe->vertexA.
01222    *    ioNewEdges
01223    *      The feature edges that are newly created (the initial edges are not 
01224    *      included) are added to this list.
01225    *    ioNewViewEdges
01226    *      The view edges that are newly created (the initial edges are not 
01227    *      included) are added to this list.  
01228    */
01229   inline void SplitEdge(FEdge *fe, 
01230                         const vector<TVertex*>& iViewVertices, 
01231                         vector<FEdge*>& ioNewEdges,
01232                         vector<ViewEdge*>& ioNewViewEdges);
01233   /* accessors */
01235   inline  SShape * sshape()  {return _SShape;}
01237   inline  const SShape * sshape() const {return _SShape;}
01239   inline  vector<ViewVertex*>& vertices() {return _Vertices;}
01241   inline  vector<ViewEdge*>& edges() {return _Edges;}
01243   inline  Id getId() const {return _SShape->getId();}
01244 
01245   /* modifiers */
01247   inline void SetSShape(SShape* iSShape) {_SShape = iSShape;}
01249   inline void SetVertices(const vector<ViewVertex*>& iVertices) {_Vertices = iVertices;}
01251   inline void SetEdges(const vector<ViewEdge*>& iEdges) {_Edges = iEdges;}
01253   inline void AddVertex(ViewVertex *iVertex) 
01254   {
01255     _Vertices.push_back(iVertex);
01256     //_SShape->AddNewVertex(iVertex->svertex());
01257   }
01259   inline void AddEdge(ViewEdge *iEdge) 
01260   {
01261     _Edges.push_back(iEdge);
01262     iEdge->SetShape(this);
01263     //_SShape->AddNewEdge(iEdge->fedge());
01264   }
01265 
01266   /* removes the view edge iViewEdge in the 
01267    *  View Shape and the associated FEdge chain entry
01268    *  in the underlying SShape 
01269    */
01270   void RemoveEdge(ViewEdge * iViewEdge);
01271 
01272   /* removes the view vertex iViewVertex in the 
01273    *  View Shape.
01274    */
01275   void RemoveVertex(ViewVertex * iViewVertex);
01276 };
01277 
01278 
01279 
01280 /*
01281   
01282   #############################################
01283   #############################################
01284   #############################################
01285   ######                                 ######
01286   ######   I M P L E M E N T A T I O N   ######
01287   ######                                 ######
01288   #############################################
01289   #############################################
01290   #############################################
01291   
01292 */
01293 /* for inline functions */
01294 
01295 void ViewShape::SplitEdge(FEdge *fe, 
01296                         const vector<TVertex*>& iViewVertices, 
01297                         vector<FEdge*>& ioNewEdges,
01298                         vector<ViewEdge*>& ioNewViewEdges)
01299 { 
01300     ViewEdge *vEdge = fe->viewedge();
01301 
01302     
01303     // We first need to sort the view vertices from farther to closer to fe->vertexA
01304     
01305     SVertex *sv, *sv2; 
01306     ViewVertex *vva, *vvb;
01307     vector<TVertex*>::const_iterator vv, vvend;
01308     for(vv=iViewVertices.begin(), vvend = iViewVertices.end();
01309     vv!=vvend;
01310     vv++)
01311     {
01312       // Add the viewvertices to the ViewShape
01313       AddVertex((*vv));
01314       
01315       // retrieve the correct SVertex from the view vertex
01316       //--------------------------------------------------
01317       sv = (*vv)->frontSVertex();
01318       sv2 = (*vv)->backSVertex();
01319 
01320       if(sv->shape() != sv2->shape())
01321       {
01322         if(sv->shape() != _SShape)
01323           sv = sv2;
01324       }
01325       else
01326       {
01327         // if the shape is the same we can safely differ 
01328         // the two vertices using their ids:
01329         if(sv->getId() != fe->vertexA()->getId())
01330           sv = sv2;
01331       }
01332       
01333       vva = vEdge->A();
01334       vvb = vEdge->B();
01335       
01336       // We split Fedge AB into AA' and A'B. A' and A'B are created.
01337       // AB becomes (address speaking) AA'. B is updated.
01338       //--------------------------------------------------
01339       SShape * shape = fe->shape();
01340       
01341       // a new edge, A'B is created.
01342       FEdge *newEdge = shape->SplitEdgeIn2(fe, sv);
01343 
01344       ioNewEdges.push_back(newEdge);
01345       ViewEdge *newVEdge;
01346 
01347       if((vva == 0) || (vvb == 0)) // that means we're dealing with a closed viewedge (loop)
01348       {
01349         // remove the chain that was starting by the fedge A of vEdge (which is different from fe !!!!)
01350         shape->RemoveEdgeFromChain(vEdge->fedgeA());
01351         // we set 
01352         vEdge->SetA(*vv);
01353         vEdge->SetB(*vv);
01354         vEdge->SetFEdgeA(newEdge);
01355         //FEdge *previousEdge = newEdge->previousEdge();  
01356         vEdge->SetFEdgeB(fe);
01357         newVEdge = vEdge;
01358         vEdge->fedgeA()->SetViewEdge(newVEdge);
01359       }
01360       else
01361       {
01362         
01363         // while we create the view edge, it updates the "ViewEdge" pointer 
01364         // of every underlying FEdges to this.
01365         newVEdge = new ViewEdge((*vv),vvb);//, newEdge, vEdge->fedgeB());
01366         newVEdge->SetNature((fe)->getNature());
01367         newVEdge->SetFEdgeA(newEdge);
01368         //newVEdge->SetFEdgeB(fe);
01369         // If our original viewedge is made of one FEdge, 
01370         // then 
01371         if((vEdge->fedgeA() == vEdge->fedgeB()) || (fe == vEdge->fedgeB()))
01372           newVEdge->SetFEdgeB(newEdge);
01373         else
01374           newVEdge->SetFEdgeB(vEdge->fedgeB()); //MODIF
01375 
01376         Id * newId = vEdge->splittingId();
01377         if(newId == 0){
01378           newId = new Id(vEdge->getId());
01379           vEdge->setSplittingId(newId);
01380         }
01381         newId->setSecond(newId->getSecond()+1);
01382         newVEdge->SetId(*newId);
01383         newVEdge->setSplittingId(newId);
01384         //        Id id(vEdge->getId().getFirst(), vEdge->getId().getSecond()+1);
01385         //        newVEdge->SetId(vEdge->getId());
01386         //        vEdge->SetId(id);
01387         
01388         AddEdge(newVEdge); // here this shape is set as the edge's shape
01389       
01390         // add new edge to the list of new edges passed as argument:
01391         ioNewViewEdges.push_back(newVEdge);
01392 
01393       
01394         
01395         if(0 != vvb) 
01396           vvb->Replace((vEdge), newVEdge);
01397 
01398         // we split the view edge:
01399         vEdge->SetB((*vv));
01400         vEdge->SetFEdgeB(fe); //MODIF
01401       
01402         // Update fedges so that they point to the new viewedge:
01403         newVEdge->UpdateFEdges();
01404 
01405       }
01406       // check whether this vertex is a front vertex or a back
01407       // one
01408       
01409       if(sv == (*vv)->frontSVertex())
01410       { 
01411         // -- View Vertex A' --
01412         (*vv)->SetFrontEdgeA(vEdge, true);
01413         (*vv)->SetFrontEdgeB(newVEdge, false);
01414       }
01415       else
01416       {
01417         // -- View Vertex A' --
01418         (*vv)->SetBackEdgeA(vEdge, true);
01419         (*vv)->SetBackEdgeB(newVEdge, false);
01420       }
01421     }
01422 } 
01423     
01424                   /**********************************/
01425                   /*                                */
01426                   /*                                */
01427                   /*             ViewEdge           */
01428                   /*                                */
01429                   /*                                */
01430                   /**********************************/
01431 
01432                   
01433 // inline Vec3r ViewEdge::orientation2d(int iCombination) const
01434 // {
01435 //  return edge_orientation2d_function<ViewEdge>(*this, iCombination);
01436 // }
01437 
01438 // inline Vec3r  ViewEdge::orientation3d(int iCombination) const
01439 // {
01440 //  return edge_orientation3d_function<ViewEdge>(*this, iCombination);
01441 // }
01442 
01443 // inline real ViewEdge::z_discontinuity(int iCombination) const 
01444 // {
01445 //   return z_discontinuity_edge_function<ViewEdge>(*this, iCombination);
01446 // }
01447 
01448 // inline float ViewEdge::local_average_depth(int iCombination ) const
01449 // {
01450 //   return local_average_depth_edge_function<ViewEdge>(*this, iCombination);
01451 // }
01452 
01453 // inline float ViewEdge::local_depth_variance(int iCombination) const 
01454 // {
01455 //   return local_depth_variance_edge_function<ViewEdge>(*this, iCombination);
01456 // }
01457 
01458 // inline real ViewEdge::local_average_density(float sigma, int iCombination) const 
01459 // {
01460 //   return density_edge_function<ViewEdge>(*this, iCombination);
01461 // }
01462 
01463 inline const SShape * ViewEdge::occluded_shape() const 
01464 {
01465   if(0 == _aShape)
01466     return 0;
01467   return _aShape->sshape();
01468 }  
01469 
01470 // inline Vec3r ViewEdge::curvature2d_as_vector(int iCombination) const 
01471 // {
01472 //   return curvature2d_as_vector_edge_function<ViewEdge>(*this, iCombination);
01473 // }
01474 
01475 // inline real ViewEdge::curvature2d_as_angle(int iCombination) const 
01476 // {
01477 //   return curvature2d_as_angle_edge_function<ViewEdge>(*this, iCombination);
01478 // }
01479 
01480 
01481 #endif // VIEWMAP_H