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

Silhouette.h

00001 //
00002 //  Filename         : Silhouette.h
00003 //  Author(s)        : Stephane Grabli
00004 //  Purpose          : Classes to define a silhouette structure
00005 //  Date of creation : 25/03/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  SILHOUETTE_H
00031 # define SILHOUETTE_H
00032 
00033 # include <iostream>
00034 # include <string>
00035 # include <vector>
00036 # include <set>
00037 # include <float.h>
00038 # include "../system/FreestyleConfig.h"
00039 # include "../geometry/Geom.h"
00040 # include "../geometry/BBox.h"
00041 # include "../scene_graph/Material.h"
00042 # include "../geometry/Polygon.h"
00043 # include "../system/Exception.h"
00044 # include "Interface0D.h"
00045 # include "Interface1D.h"
00046 # include "../winged_edge/Curvature.h"
00047 
00048 using namespace std;
00049 using namespace Geometry;
00050 
00051 class ViewShape;
00052 typedef vector<ViewShape*> occluder_container;
00053 
00054                   /**********************************/
00055                   /*                                */
00056                   /*                                */
00057                   /*             SVertex            */
00058                   /*                                */
00059                   /*                                */
00060                   /**********************************/
00061 
00062 class FEdge;
00063 class ViewVertex;
00064 class SShape;
00065 
00067 class LIB_VIEW_MAP_EXPORT SVertex : public Interface0D
00068 {
00069 public: // Implementation of Interface0D
00070 
00072   virtual string getExactTypeName() const {
00073     return "SVertex";
00074   }
00075 
00076   // Data access methods
00077 
00079   virtual real getX() const {
00080     return _Point3D.x();
00081   }
00082 
00084   virtual real getY() const {
00085     return _Point3D.y();
00086   }
00087 
00089   virtual real getZ() const {
00090     return _Point3D.z();
00091   }
00092 
00094   virtual Vec3f getPoint3D() const {
00095     return _Point3D;
00096   }
00097 
00099   virtual real getProjectedX() const {
00100     return _Point2D.x();
00101   }
00102 
00104   virtual real getProjectedY() const {
00105     return _Point2D.y();
00106   }
00107 
00109   virtual real getProjectedZ() const {
00110     return _Point2D.z();
00111   }
00112 
00114   virtual Vec2f getPoint2D() const {
00115     return Vec2f((float)_Point2D.x(),(float)_Point2D.y());
00116   }
00117 
00120   virtual FEdge* getFEdge(Interface0D&);
00121 
00123   virtual Id getId() const {
00124     return _Id;
00125   }
00126 
00128   virtual Nature::VertexNature getNature() const;
00129 
00131   virtual SVertex * castToSVertex();
00132 
00134   virtual ViewVertex * castToViewVertex();
00135 
00137   virtual NonTVertex * castToNonTVertex();
00138 
00140   virtual TVertex * castToTVertex();
00141 
00142 public:
00143 
00144   typedef vector<FEdge*> fedges_container;
00145 
00146 private:
00147 
00148   Id _Id;
00149   Vec3r _Point3D;
00150   Vec3r _Point2D;
00151   set<Vec3r> _Normals; 
00152   vector<FEdge*> _FEdges; // the edges containing this vertex
00153   SShape *_Shape;  // the shape to which belongs the vertex
00154   ViewVertex *_pViewVertex; // The associated viewvertex, in case there is one.
00155   real _curvatureFredo;
00156   Vec2r _directionFredo;
00157   CurvatureInfo* _curvature_info;
00158 
00159 public:
00160 
00164   void *userdata;
00165 
00167   inline SVertex() {
00168     _Id = 0;
00169     userdata = NULL;
00170     _Shape = NULL;
00171     _pViewVertex = 0;
00172     _curvature_info = 0;
00173   }
00174 
00176   inline SVertex(const Vec3r &iPoint3D, const Id& id) {
00177     _Point3D = iPoint3D;
00178     _Id=id;
00179     userdata = NULL;
00180     _Shape = NULL;
00181     _pViewVertex=0;
00182     _curvature_info = 0;
00183   }
00184 
00186   inline SVertex(SVertex& iBrother) {
00187     _Id = iBrother._Id;
00188     _Point3D =  iBrother.point3D();
00189     _Point2D = iBrother.point2D();
00190     _Normals = iBrother._Normals;
00191     _FEdges = iBrother.fedges();
00192     _Shape = iBrother.shape();
00193     _pViewVertex = iBrother._pViewVertex;
00194     if (!(iBrother._curvature_info))
00195       _curvature_info = 0;
00196     else
00197       _curvature_info = new CurvatureInfo(*(iBrother._curvature_info));
00198     iBrother.userdata = this;
00199     userdata = 0;
00200   }
00201 
00203   virtual ~SVertex() {
00204     if (_curvature_info)
00205       delete _curvature_info;
00206   }
00207 
00209   virtual SVertex * dupplicate() {
00210     SVertex *clone = new SVertex(*this);
00211     return clone;
00212   }
00213 
00215   virtual bool operator==(const SVertex& iBrother) {
00216     return ((_Point2D == iBrother._Point2D) &&
00217             (_Point3D == iBrother._Point3D));
00218   }
00219 
00220   /* accessors */
00221   inline const Vec3r& point3D() const {return _Point3D;}
00222   inline const Vec3r& point2D() const {return _Point2D;}
00227   inline set<Vec3r> normals() {return _Normals;}
00229   inline unsigned normalsSize() const {return _Normals.size();}
00230   inline const vector<FEdge*>& fedges() {return _FEdges;}
00231   inline fedges_container::iterator fedges_begin() {return _FEdges.begin();}
00232   inline fedges_container::iterator fedges_end() {return _FEdges.end();}
00233   inline SShape * shape() {return _Shape;}
00234   inline real z() const {return _Point2D[2];}
00239   inline ViewVertex * viewvertex() {return _pViewVertex;}
00240 
00243   inline void SetPoint3D(const Vec3r &iPoint3D) {_Point3D = iPoint3D;}
00245   inline void SetPoint2D(const Vec3r &iPoint2D) {_Point2D = iPoint2D;}
00249   inline void AddNormal(const Vec3r& iNormal) 
00250   {
00251     _Normals.insert(iNormal); // if iNormal in the set already exists, nothing is done
00252   }
00253 
00254   void setCurvatureInfo(CurvatureInfo* ci) {
00255     _curvature_info = ci;
00256   }
00257 
00258   const CurvatureInfo* getCurvatureInfo() const {
00259     return _curvature_info;
00260   }
00261 
00262   /* Fredo's normal and curvature*/
00263   void setCurvatureFredo(real c) {_curvatureFredo=c;}
00264   void setDirectionFredo(Vec2r d) {_directionFredo=d;}
00265   real curvatureFredo () {return _curvatureFredo;}
00266   const Vec2r directionFredo () {return _directionFredo;}
00267 
00269   inline void SetId(const Id& id) {_Id = id;}
00270   inline void SetFEdges(const vector<FEdge*>& iFEdges) {_FEdges = iFEdges;}
00271   inline void SetShape(SShape *iShape) {_Shape = iShape;}
00272   inline void SetViewVertex(ViewVertex *iViewVertex) {_pViewVertex = iViewVertex;}
00274   inline void AddFEdge(FEdge* iFEdge) {_FEdges.push_back(iFEdge);}
00275   /* replaces edge 1 by edge 2 in the list of edges */
00276   inline void Replace(FEdge *e1, FEdge *e2)
00277   {
00278     vector<FEdge*>::iterator insertedfe;
00279     for(vector<FEdge*>::iterator fe=_FEdges.begin(),fend=_FEdges.end();
00280         fe!=fend;
00281         fe++)
00282       {
00283         if((*fe) == e1)
00284           {
00285             insertedfe = _FEdges.insert(fe, e2);// inserts e2 before fe.
00286                                                 // returns an iterator pointing toward e2. fe is invalidated.
00287             // we want to remove e1, but we can't use fe anymore:
00288             insertedfe++; // insertedfe points now to e1
00289             _FEdges.erase(insertedfe);
00290             return;
00291           }
00292       }
00293   }
00294 
00295 public:
00296 
00297   /* Information access interface */
00298 
00299   FEdge *fedge() ; // for non T vertex
00300   inline const Vec3r& point2d() const {return point2D();}
00301   inline const Vec3r& point3d() const {return point3D();}
00302   inline Vec3r normal() const {if(_Normals.size() == 1) return (*(_Normals.begin())); Exception::raiseException(); return *(_Normals.begin());}
00303   //Material material() const ;
00304   Id shape_id() const ;
00305   const SShape* shape() const ;
00306   float shape_importance() const ;
00307   
00308   const int qi() const ;
00309   occluder_container::const_iterator occluders_begin() const ;
00310   occluder_container::const_iterator occluders_end() const ;
00311   bool occluders_empty() const ;
00312   int occluders_size() const ;
00313   const Polygon3r& occludee() const ;
00314   const SShape * occluded_shape() const ;
00315   const bool  occludee_empty() const ;
00316   real z_discontinuity() const ;
00317   //inline float local_average_depth() const ;
00318   //  inline float local_depth_variance() const ;
00319   //  inline real local_average_density(float sigma = 2.3f) const ;
00320   //inline Vec3r shaded_color() const ;
00321   //  inline Vec3r orientation2d() const ; 
00322   //  inline Vec3r orientation3d() const ;
00323   //  inline Vec3r curvature2d_as_vector() const ;
00325   //  inline real curvature2d_as_angle() const ;
00326   
00327 };
00328 
00329                   /**********************************/
00330                   /*                                */
00331                   /*                                */
00332                   /*             FEdge              */
00333                   /*                                */
00334                   /*                                */
00335                   /**********************************/
00336 
00337 
00338 class ViewEdge;
00353 class LIB_VIEW_MAP_EXPORT FEdge : public Interface1D
00354 {
00355 public: // Implementation of Interface0D
00356 
00358   virtual string getExactTypeName() const {
00359     return "FEdge";
00360   }
00361 
00362   // Data access methods
00363 
00365   virtual real getLength2D() const {
00366     if (!_VertexA || !_VertexB)
00367       return 0;
00368     return (_VertexB->getPoint2D() - _VertexA->getPoint2D()).norm();
00369   }
00370 
00372   virtual Id getId() const {
00373     return _Id;
00374   }
00375 
00376 public:
00377 
00378   // An edge can only be of one kind (SILHOUETTE or BORDER, etc...)
00379   // For an multi-nature edge there must be several different FEdge.
00380    // DEBUG:
00381   //  Vec3r A;
00382   //  Vec3r u;
00383   //  vector<Polygon3r> _Occludees;
00384   //  Vec3r intersection;
00385   //  vector<Vec3i> _Cells;
00386 
00387 protected:
00388   SVertex *_VertexA;
00389   SVertex *_VertexB;
00390   Id _Id;
00391   Nature::EdgeNature _Nature;
00392   //vector<Polygon3r> _Occluders; // visibility // NON GERE PAR LE COPY CONSTRUCTOR!!
00393   
00394   FEdge *_NextEdge; // next edge on the chain
00395   FEdge *_PreviousEdge;
00396   ViewEdge *_ViewEdge;
00397   // Sometimes we need to deport the visibility computation onto another 
00398   // edge. For example the exact edges use edges of the mesh to 
00399   // compute their visibility
00400   
00401   Polygon3r _aFace; // The occluded face which lies on the right of a silhouette edge
00402   Vec3r _occludeeIntersection;
00403   bool _occludeeEmpty;
00404 
00405   bool _isSmooth;
00406 
00407 public:
00411   void *userdata;
00413   inline FEdge() {
00414     userdata = NULL;
00415     _Nature = Nature::NO_FEATURE;
00416     _NextEdge = NULL;
00417     _PreviousEdge = NULL;
00418     _ViewEdge = NULL;
00419     //_hasVisibilityPoint=false;
00420     _occludeeEmpty = true;
00421     _isSmooth = false;
00422   }
00424   inline FEdge(SVertex *vA, SVertex *vB) {
00425     userdata = NULL;
00426     _VertexA = vA;
00427     _VertexB = vB;
00428     _Nature = Nature::NO_FEATURE;
00429     _NextEdge=NULL;
00430     _PreviousEdge=NULL;
00431     _ViewEdge = NULL;
00432     //_hasVisibilityPoint=false;
00433     _occludeeEmpty = true;
00434     _isSmooth = false;
00435   }
00437   inline FEdge(FEdge& iBrother)
00438   {
00439     _VertexA = iBrother.vertexA();
00440     _VertexB = iBrother.vertexB();
00441     _NextEdge = iBrother.nextEdge();
00442     _PreviousEdge = iBrother._PreviousEdge;
00443     _Nature = iBrother.getNature();
00444     _Id = iBrother._Id;
00445     _ViewEdge = iBrother._ViewEdge;
00446     //_hasVisibilityPoint = iBrother._hasVisibilityPoint;
00447     //_VisibilityPointA = iBrother._VisibilityPointA;
00448     //_VisibilityPointB = iBrother._VisibilityPointB;
00449     _aFace = iBrother._aFace;
00450     _occludeeEmpty = iBrother._occludeeEmpty;
00451     _isSmooth = iBrother._isSmooth;
00452     iBrother.userdata = this;
00453     userdata = 0;
00454   }
00456   virtual ~FEdge() {}
00458   virtual FEdge* dupplicate()
00459   {
00460     FEdge *clone = new FEdge(*this);
00461     return clone;
00462   }
00463   /* accessors */
00465   inline SVertex* vertexA() {return _VertexA;}
00467   inline SVertex* vertexB() {return _VertexB;}
00470   inline SVertex* operator[](const unsigned short int& i) const{ 
00471       return i%2==0 ? _VertexA : _VertexB;
00472   }
00474   inline Nature::EdgeNature getNature() const {return _Nature;}
00478   inline FEdge * nextEdge() {return _NextEdge;}
00482   inline FEdge * previousEdge() {return _PreviousEdge;}
00483   inline SShape * shape() {return _VertexA->shape();}
00484   //inline int invisibility() const {return _Occluders.size();}
00485   int invisibility() const ;
00486   //inline const vector<Polygon3r>& occluders() const {return _Occluders;}
00488   inline ViewEdge * viewedge() const {return _ViewEdge;}
00489   inline Vec3r center3d() {return Vec3r((_VertexA->point3D()+_VertexB->point3D())/2.0);}
00490   inline Vec3r center2d() {return Vec3r((_VertexA->point2D()+_VertexB->point2D())/2.0);}
00491   //  inline bool hasVisibilityPoint() const {return _hasVisibilityPoint;}
00492   //  inline Vec3r visibilityPointA() const {return _VisibilityPointA;}
00493   //  inline Vec3r visibilityPointB() const {return _VisibilityPointB;}
00494   inline const Polygon3r& aFace() const {return _aFace;}
00495   inline const Vec3r& getOccludeeIntersection() { return _occludeeIntersection; }
00496   inline bool getOccludeeEmpty() { return _occludeeEmpty; }
00498   inline bool isSmooth() const {return _isSmooth;}
00499 
00500   /* modifiers */
00502   inline void SetVertexA(SVertex *vA) {_VertexA = vA;}
00504   inline void SetVertexB(SVertex *vB) {_VertexB = vB;}
00506   inline void SetId(const Id& id) {_Id = id;}
00508   inline void SetNextEdge(FEdge* iEdge) {_NextEdge = iEdge;}
00510   inline void SetPreviousEdge(FEdge *iEdge) {_PreviousEdge = iEdge;}
00512   inline void SetNature(Nature::EdgeNature iNature) {_Nature = iNature;}
00513   //inline void AddOccluder(Polygon3r& iPolygon) {_Occluders.push_back(iPolygon);}
00515   inline void SetViewEdge(ViewEdge *iViewEdge) {_ViewEdge = iViewEdge;}
00516   //  inline void SetHasVisibilityPoint(bool iBool) {_hasVisibilityPoint = iBool;}
00517   //  inline void SetVisibilityPointA(const Vec3r& iPoint) {_VisibilityPointA = iPoint;}
00518   //  inline void SetVisibilityPointB(const Vec3r& iPoint) {_VisibilityPointB = iPoint;}
00519   inline void SetaFace(Polygon3r& iFace) {_aFace = iFace;}
00520   inline void SetOccludeeIntersection(const Vec3r& iPoint) {_occludeeIntersection = iPoint;}
00521   inline void SetOccludeeEmpty(bool iempty) {_occludeeEmpty = iempty;}
00525   inline void SetSmooth(bool iFlag) {_isSmooth = iFlag;}
00526   
00527   /* checks whether two FEdge have a common vertex.
00528    *  Returns a pointer on the common vertex if it exists, 
00529    *  NULL otherwise.
00530    */
00531   static inline SVertex* CommonVertex(FEdge *iEdge1, FEdge* iEdge2)
00532   {
00533     if((NULL == iEdge1) || (NULL == iEdge2))
00534       return NULL;
00535 
00536     SVertex *sv1 = iEdge1->vertexA();
00537     SVertex *sv2 = iEdge1->vertexB();
00538     SVertex *sv3 = iEdge2->vertexA();
00539     SVertex *sv4 = iEdge2->vertexB();
00540 
00541     if((sv1 == sv3) || (sv1 == sv4))
00542     {
00543       return sv1;
00544     }
00545     else if((sv2 == sv3) || (sv2 == sv4))
00546     {
00547       return sv2;
00548     }
00549 
00550     return NULL;
00551   }
00552 
00553   inline const SVertex* min2d() const 
00554   {
00555     if(_VertexA->point2D() < _VertexB->point2D())
00556       return _VertexA;
00557     else
00558       return _VertexB;
00559   }
00560   inline const SVertex* max2d() const 
00561   {
00562     if(_VertexA->point2D() < _VertexB->point2D())
00563       return _VertexB;
00564     else
00565       return _VertexA;
00566   }
00567  
00568   /* Information access interface */
00569   /* Information access interface */
00570  
00571   //Material material() const ;
00572   Id shape_id() const ;
00573   const SShape * shape() const ;
00574   float shape_importance() const ;
00575   inline const int qi() const {return invisibility();}
00576   occluder_container::const_iterator occluders_begin() const ;
00577   occluder_container::const_iterator occluders_end() const ;
00578   bool occluders_empty() const ;
00579   int occluders_size() const ;
00580   inline const Polygon3r& occludee() const {return aFace();}
00581   const SShape * occluded_shape() const ;
00582   //inline const bool  occludee_empty() const {return _occludeeEmpty;}
00583   const bool  occludee_empty() const ;
00584   real z_discontinuity() const ;
00585   //  inline float local_average_depth(int iCombination = 0) const ;
00586   //  inline float local_depth_variance(int iCombination = 0) const ;
00587   //  inline real local_average_density(float sigma = 2.3f, int iCombination = 0) const ;
00588   //inline Vec3r shaded_color(int iCombination = 0) const {}
00589   int viewedge_nature() const ;
00590   //float viewedge_length() const ;
00591   inline Vec3r orientation2d() const {return Vec3r(_VertexB->point2d()-_VertexA->point2d());}
00592   inline Vec3r orientation3d() const {return Vec3r(_VertexB->point3d()-_VertexA->point3d());}
00593   //  //inline real curvature2d() const {return viewedge()->curvature2d((_VertexA->point2d()+_VertexB->point2d())/2.0);}
00594   //  inline Vec3r curvature2d_as_vector(int iCombination = 0) const ;
00595   //  /* angle in degrees*/
00596   //  inline real curvature2d_as_angle(int iCombination = 0) const ;  
00597 
00598 
00599   // Iterator access (Interface1D)
00602   virtual inline Interface0DIterator verticesBegin();
00605   virtual inline Interface0DIterator verticesEnd();
00606 
00616   virtual inline Interface0DIterator pointsBegin(float t=0.f);
00626   virtual inline Interface0DIterator pointsEnd(float t=0.f);
00627 };
00628 
00629 //
00630 // SVertexIterator
00631 //
00633 
00634 namespace FEdgeInternal {
00635 
00636   class SVertexIterator : public Interface0DIteratorNested
00637   {
00638   public:
00639 
00640     SVertexIterator() {
00641       _vertex = NULL;
00642       _edge = NULL;
00643     }
00644 
00645     SVertexIterator(const SVertexIterator& vi) {
00646       _vertex = vi._vertex;
00647       _edge = vi._edge;
00648     }
00649 
00650     SVertexIterator(SVertex* v, FEdge* edge) {
00651       _vertex = v;
00652       _edge = edge;
00653     }
00654 
00655     SVertexIterator& operator=(const SVertexIterator& vi) {
00656       _vertex = vi._vertex;
00657       _edge = vi._edge;
00658       return *this;
00659     }
00660 
00661     virtual string getExactTypeName() const {
00662       return "SVertexIterator";
00663     }
00664 
00665     virtual SVertex& operator*() {
00666       return *_vertex;
00667     }
00668 
00669     virtual SVertex* operator->() {
00670       return &(operator*());
00671     }
00672 
00673     virtual SVertexIterator& operator++() {
00674       increment();
00675       return *this;
00676     }
00677 
00678     virtual SVertexIterator operator++(int) {
00679       SVertexIterator ret(*this);
00680       increment();
00681       return ret;
00682     }
00683 
00684     virtual SVertexIterator& operator--() {
00685       decrement();
00686       return *this;
00687     }
00688 
00689     virtual SVertexIterator operator--(int) {
00690       SVertexIterator ret(*this);
00691       decrement();
00692       return ret;
00693     }
00694 
00695     virtual void increment() {
00696       if (_vertex == _edge->vertexB()) {
00697         _vertex = 0;
00698         return;
00699       }
00700 
00701       _vertex = _edge->vertexB();
00702     }
00703 
00704     virtual void decrement() {
00705       if (_vertex == _edge->vertexA()) {
00706         _vertex = 0;
00707         return;
00708       }
00709       _vertex = _edge->vertexA();
00710     }
00711 
00712     virtual bool isBegin() const {
00713       return _vertex == _edge->vertexA();
00714     }
00715 
00716     virtual bool isEnd() const {
00717       return _vertex == _edge->vertexB();
00718     }
00719 
00720     virtual bool operator==(const Interface0DIteratorNested& it) const {
00721       const SVertexIterator* it_exact = dynamic_cast<const SVertexIterator*>(&it);
00722       if (!it_exact)
00723         return false;
00724       return ((_vertex == it_exact->_vertex) &&
00725               (_edge == it_exact->_edge));
00726     }
00727 
00728     virtual float t() const{
00729       if(_vertex == _edge->vertexA()){
00730         return 0;
00731       }
00732       return ((float)_edge->getLength2D());
00733     }
00734     virtual float u() const{
00735       if(_vertex == _edge->vertexA()){
00736         return 0;
00737       }
00738       return 1.0;
00739     }
00740     virtual SVertexIterator* copy() const {
00741       return new SVertexIterator(*this);
00742     }
00743 
00744   private:
00745 
00746     SVertex*    _vertex;
00747     FEdge*      _edge;
00748   };
00749 
00750 } // end of namespace FEdgeInternal
00751 
00752 // Iterator access (implementation)
00753 
00754 Interface0DIterator FEdge::verticesBegin() {
00755   Interface0DIterator ret(new FEdgeInternal::SVertexIterator(_VertexA, this));
00756   return ret;
00757 }
00758 
00759 Interface0DIterator FEdge::verticesEnd() {
00760   Interface0DIterator ret(new FEdgeInternal::SVertexIterator(0, this));
00761   return ret;
00762 }
00763 
00764 Interface0DIterator FEdge::pointsBegin(float t) {
00765   return verticesBegin();
00766 }
00767 
00768 Interface0DIterator FEdge::pointsEnd(float t) {
00769   return verticesEnd();
00770 }
00771 
00781 class LIB_VIEW_MAP_EXPORT FEdgeSharp : public FEdge
00782 {
00783 protected:
00784   Vec3r _aNormal; // When following the edge, normal of the right face
00785   Vec3r _bNormal; // When following the edge, normal of the left face
00786   unsigned _aMaterialIndex;
00787   unsigned _bMaterialIndex;
00788   
00789 public:
00791   inline FEdgeSharp() : FEdge(){
00792     _aMaterialIndex = _bMaterialIndex = 0;
00793   }
00795   inline FEdgeSharp(SVertex *vA, SVertex *vB) : FEdge(vA, vB){
00796     _aMaterialIndex = _bMaterialIndex = 0;
00797   }
00799   inline FEdgeSharp(FEdgeSharp& iBrother) : FEdge(iBrother){
00800     _aNormal = iBrother._aNormal;
00801     _bNormal = iBrother._bNormal;
00802     _aMaterialIndex = iBrother._aMaterialIndex;
00803     _bMaterialIndex = iBrother._bMaterialIndex;
00804   }
00806   virtual ~FEdgeSharp() {}
00808   virtual FEdge* dupplicate(){
00809     FEdge *clone = new FEdgeSharp(*this);
00810     return clone;
00811   }
00816   inline const Vec3r& normalA() {return _aNormal;}
00820   inline const Vec3r& normalB() {return _bNormal;}
00825   inline unsigned aMaterialIndex() const {return _aMaterialIndex;}
00830   const Material& aMaterial() const ;
00834   inline unsigned bMaterialIndex() const {return _bMaterialIndex;}
00838   const Material& bMaterial() const ;
00839 
00841   inline void SetNormalA(const Vec3r& iNormal) {_aNormal = iNormal;}
00843   inline void SetNormalB(const Vec3r& iNormal) {_bNormal = iNormal;}
00845   inline void SetaMaterialIndex(unsigned i) {_aMaterialIndex = i;}
00847   inline void SetbMaterialIndex(unsigned i) {_bMaterialIndex = i;}
00848   
00849 };
00850 
00855 class LIB_VIEW_MAP_EXPORT FEdgeSmooth : public FEdge
00856 {
00857 protected:
00858   Vec3r _Normal;
00859   unsigned _MaterialIndex;
00860   //  bool _hasVisibilityPoint;
00861   //  Vec3r _VisibilityPointA;  // The edge on which the visibility will be computed represented 
00862   //  Vec3r _VisibilityPointB;  // using its 2 extremity points A and B
00863   void * _Face; // In case of exact silhouette, Face is the WFace crossed by Fedge 
00864                // NON GERE PAR LE COPY CONSTRUCTEUR
00865 public:
00867   inline FEdgeSmooth() : FEdge(){
00868     _Face=0;
00869     _MaterialIndex = 0;
00870     _isSmooth = true;
00871   }
00873   inline FEdgeSmooth(SVertex *vA, SVertex *vB) : FEdge(vA, vB){
00874     _Face=0;
00875     _MaterialIndex = 0;
00876     _isSmooth = true;
00877 
00878   }
00880   inline FEdgeSmooth(FEdgeSmooth& iBrother) : FEdge(iBrother){
00881     _Normal = iBrother._Normal;
00882     _Face = iBrother._Face;
00883     _MaterialIndex = iBrother._MaterialIndex;
00884     _isSmooth = true;
00885   }
00887   virtual ~FEdgeSmooth() {}
00889   virtual FEdge* dupplicate(){
00890     FEdge *clone = new FEdgeSmooth(*this);
00891     return clone;
00892   }
00893 
00894   inline void * face() const {return _Face;}
00896   inline const Vec3r& normal() {return _Normal;}
00898   inline unsigned materialIndex() const {return _MaterialIndex;}
00900   const Material& material() const ;
00901 
00902   inline void SetFace(void * iFace) {_Face = iFace;}
00904   inline void SetNormal(const Vec3r& iNormal) {_Normal = iNormal;}
00906   inline void SetMaterialIndex(unsigned i) {_MaterialIndex = i;}
00907 };
00908                   /**********************************/
00909                   /*                                */
00910                   /*                                */
00911                   /*             SShape             */
00912                   /*                                */
00913                   /*                                */
00914                   /**********************************/
00915 
00916 
00920 class LIB_VIEW_MAP_EXPORT SShape
00921 {
00922 private:
00923   vector<FEdge*> _chains;          // list of fedges that are chains starting points.
00924   vector<SVertex*> _verticesList;  // list of all vertices
00925   vector<FEdge*>   _edgesList;     // list of all edges
00926   Id _Id;
00927   BBox<Vec3r> _BBox;
00928   vector<Material> _Materials;  
00929 
00930   float _importance;
00931 
00932   ViewShape *_ViewShape;
00933 
00934 public:
00938   void* userdata; // added by E.T.
00940   inline SShape()
00941   {
00942     userdata = 0;
00943 
00944     _importance = 0.f;
00945     _ViewShape = 0;
00946   }
00948   inline SShape(SShape& iBrother)
00949   {
00950     userdata = 0;
00951     _Id = iBrother._Id;
00952     _BBox = iBrother.bbox();
00953     _Materials = iBrother._Materials;
00954 
00955     _importance = iBrother._importance;
00956 
00957     _ViewShape = iBrother._ViewShape;
00958 
00959      
00960     //---------
00961     // vertices
00962     //---------
00963     vector<SVertex*>::iterator sv,svend;
00964     vector<SVertex*>& verticesList = iBrother.GetVertexList();
00965     for(sv=verticesList.begin(), svend=verticesList.end();
00966         sv!=svend;
00967         sv++)
00968       {
00969         SVertex *newv = new SVertex(*(*sv));
00970         newv->SetShape(this);
00971         _verticesList.push_back(newv);
00972       }
00973     
00974     //------
00975     // edges
00976     //------
00977     vector<FEdge*>::iterator e,eend;
00978     vector<FEdge*>& edgesList = iBrother.GetEdgeList();
00979     for(e=edgesList.begin(),eend=edgesList.end();
00980         e!=eend;
00981         e++)
00982       {
00983         FEdge *newe = (*e)->dupplicate();
00984         _edgesList.push_back(newe);
00985       } 
00986 
00987         //-------------------------
00988         // starting chain edges
00989         //-------------------------
00990         vector<FEdge*>::iterator fe,fend;
00991         vector<FEdge*>& fedges = iBrother.GetChains();
00992         for(fe=fedges.begin(),fend=fedges.end();
00993         fe!=fend;
00994         fe++)
00995         {
00996           _chains.push_back((FEdge*)((*fe)->userdata));
00997         }
00998         
00999     
01000     //-------------------------
01001     // remap edges in vertices:
01002     //-------------------------
01003     for(sv=_verticesList.begin(),svend=_verticesList.end();
01004         sv!=svend;
01005         sv++)
01006       {
01007         const vector<FEdge*>& fedgeList = (*sv)->fedges();
01008         vector<FEdge*> newfedgelist;
01009         for(vector<FEdge*>::const_iterator fed=fedgeList.begin(),fedend=fedgeList.end();
01010             fed!=fedend;
01011             fed++)
01012           {
01013             FEdge *current = *fed;
01014             newfedgelist.push_back((FEdge*)current->userdata);
01015           }
01016         (*sv)->SetFEdges(newfedgelist); 
01017       }
01018     
01019     //-------------------------------------
01020     // remap vertices and nextedge in edges:
01021     //-------------------------------------
01022     for(e=_edgesList.begin(),eend=_edgesList.end();
01023         e!=eend;
01024         e++)
01025       {
01026         (*e)->SetVertexA((SVertex*)((*e)->vertexA()->userdata));
01027         (*e)->SetVertexB((SVertex*)((*e)->vertexB()->userdata));
01028         (*e)->SetNextEdge((FEdge*)((*e)->nextEdge()->userdata));
01029         (*e)->SetPreviousEdge((FEdge*)((*e)->previousEdge()->userdata));
01030       }
01031     
01032 
01033     // reset all brothers userdata to NULL:
01034     //-------------------------------------
01035     //---------
01036     // vertices
01037     //---------
01038     for(sv=_verticesList.begin(),svend=_verticesList.end();
01039         sv!=svend;
01040         sv++)
01041       {
01042         (*sv)->userdata = NULL;
01043       }
01044 
01045     //------
01046     // edges
01047     //------
01048     for(e=_edgesList.begin(),eend=_edgesList.end();
01049         e!=eend;
01050         e++)
01051       {
01052         (*e)->userdata = NULL;
01053       }  
01054   }
01056   virtual SShape * dupplicate()
01057   {
01058     SShape *clone = new SShape(*this);
01059     return clone;
01060   }
01062   virtual inline ~SShape()
01063   {
01064     vector<SVertex*>::iterator sv,svend;
01065     vector<FEdge*>::iterator e,eend;
01066     if(0 != _verticesList.size())
01067       {
01068         for(sv=_verticesList.begin(),svend=_verticesList.end();
01069             sv!=svend;
01070             sv++)
01071           {
01072             delete (*sv);
01073           }
01074         _verticesList.clear();
01075       }
01076 
01077     if(0 != _edgesList.size())
01078       {
01079         for(e=_edgesList.begin(),eend=_edgesList.end();
01080             e!=eend;
01081             e++)
01082           {
01083             delete (*e);
01084           }
01085         _edgesList.clear();
01086       }
01087 
01089     //-----------------------
01090     if(0 != _chains.size())
01091       {
01092         _chains.clear();
01093       }
01094   }
01095 
01097   inline void AddEdge(FEdge *iEdge)
01098     {
01099       _edgesList.push_back(iEdge);
01100     }
01101 
01105   inline void AddNewVertex(SVertex* iv) {iv->SetShape(this);_verticesList.push_back(iv);}
01106   inline void AddChain(FEdge *iEdge){
01107     _chains.push_back(iEdge);
01108   }
01109 
01110   inline SVertex * CreateSVertex(const Vec3r& P3D, const Vec3r& P2D, const Id& id)
01111   {
01112     SVertex *Ia = new SVertex(P3D, id);
01113     Ia->SetPoint2D(P2D);
01114     AddNewVertex(Ia);
01115     return Ia;
01116   }
01117   /* splits an edge into several edges. 
01118    *  The edge's vertices are passed rather than 
01119    *  the edge itself. This way, all feature edges (SILHOUETTE,
01120    *  CREASE, BORDER) are splitted in the same time.
01121    *  The processed edges are flagged as done (using the userdata
01122    *  flag).One single new vertex is created whereas 
01123    *  several splitted edges might created for the different 
01124    *  kinds of edges. These new elements are added to the lists
01125    *  maintained by the shape.
01126    *  new chains are also created.
01127    *    ioA
01128    *      The first vertex for the edge that gets splitted
01129    *    ioB
01130    *      The second vertex for the edge that gets splitted
01131    *    iParameters
01132    *      A vector containing 2D real vectors indicating the parameters
01133    *      giving the intersections coordinates in 3D and in 2D.
01134    *      These intersections points must be sorted from B to A.
01135    *      Each parameter defines the intersection point I as I=A+T*AB.
01136    *      T<0 and T>1 are then incorrect insofar as they give intersections
01137    *      points that lie outside the segment.
01138    *    ioNewEdges
01139    *      The edges that are newly created (the initial edges are not 
01140    *      included) are added to this list.
01141    */
01142   inline void SplitEdge(FEdge *fe, const vector<Vec2r>& iParameters, vector<FEdge*>& ioNewEdges)
01143     {
01144     
01145     SVertex *ioA = fe->vertexA();
01146     SVertex *ioB = fe->vertexB();
01147     Vec3r A = ioA->point3D();
01148     Vec3r B = ioB->point3D();
01149     Vec3r a = ioA->point2D();
01150     Vec3r b = ioB->point2D();
01151     SVertex *svA, *svB;
01152 
01153     Vec3r newpoint3d,newpoint2d;
01154     vector<SVertex*> intersections;
01155     real t,T;
01156     for(vector<Vec2r>::const_iterator p=iParameters.begin(),pend=iParameters.end();
01157     p!=pend;
01158     p++)
01159     {
01160       T=(*p)[0];
01161       t=(*p)[1];
01162 
01163       if((t < 0) || (t > 1))
01164         cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - " << ioB->getId() << endl;
01165     
01166       // compute the 3D and 2D coordinates for the intersections points:
01167       newpoint3d = Vec3r(A + T*(B-A));
01168       newpoint2d = Vec3r(a + t*(b-a));
01169 
01170       // create new SVertex:
01171       // (we keep B's id)
01172       SVertex* newVertex = new SVertex(newpoint3d, ioB->getId());
01173       newVertex->SetPoint2D(newpoint2d);
01174       
01175       // Add this vertex to the intersections list:
01176       intersections.push_back(newVertex);
01177 
01178       // Add this vertex to this sshape:
01179       AddNewVertex(newVertex);
01180     }
01181     
01182     for(vector<SVertex*>::iterator sv=intersections.begin(),svend=intersections.end();
01183     sv!=svend;
01184     sv++)
01185     {
01186       svA = fe->vertexA();
01187       svB = fe->vertexB();
01188         
01189       // We split edge AB into AA' and A'B. A' and A'B are created.
01190       // AB becomes (address speaking) AA'. B is updated.
01191       //--------------------------------------------------
01192       // The edge AB becomes edge AA'.
01193       (fe)->SetVertexB((*sv));
01194       // a new edge, A'B is created.
01195       FEdge *newEdge;
01196       if(fe->isSmooth()){
01197         newEdge = new FEdgeSmooth((*sv), svB);
01198         FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge);
01199         FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe);
01200         se->SetMaterialIndex(fes->materialIndex());
01201       }else{
01202         newEdge = new FEdgeSharp((*sv), svB);
01203         FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge);
01204         FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(fe);
01205         se->SetaMaterialIndex(fes->aMaterialIndex());
01206         se->SetbMaterialIndex(fes->bMaterialIndex());
01207       }
01208         
01209       newEdge->SetNature((fe)->getNature());
01210       
01211 
01212       // to build a new chain:
01213       AddChain(newEdge);
01214       // add the new edge to the sshape edges list.
01215       AddEdge(newEdge);
01216       // add new edge to the list of new edges passed as argument:
01217       ioNewEdges.push_back(newEdge);
01218 
01219       // update edge A'B for the next pointing edge
01220       newEdge->SetNextEdge((fe)->nextEdge());
01221       fe->nextEdge()->SetPreviousEdge(newEdge);
01222       Id id(fe->getId().getFirst(), fe->getId().getSecond()+1);
01223       newEdge->SetId(fe->getId());
01224       fe->SetId(id);
01225 
01226       // update edge AA' for the next pointing edge
01227       //ioEdge->SetNextEdge(newEdge);
01228       (fe)->SetNextEdge(NULL);
01229 
01230       // update vertex pointing edges list:
01231       // -- vertex B --
01232       svB->Replace((fe), newEdge);
01233       // -- vertex A' --
01234       (*sv)->AddFEdge((fe));
01235       (*sv)->AddFEdge(newEdge);
01236     }
01237           
01238     }
01239 
01240   /* splits an edge into 2 edges. The new vertex and edge are added
01241    *  to the sshape list of vertices and edges
01242    *  a new chain is also created.
01243    *  returns the new edge.
01244    *    ioEdge
01245    *      The edge that gets splitted
01246    *    newpoint
01247    *      x,y,z coordinates of the new point.
01248    */
01249   inline FEdge* SplitEdgeIn2(FEdge* ioEdge, SVertex * ioNewVertex)
01250     {
01251       SVertex *A = ioEdge->vertexA();
01252       SVertex *B = ioEdge->vertexB();
01253 
01254       
01255       // We split edge AB into AA' and A'B. A' and A'B are created.
01256       // AB becomes (address speaking) AA'. B is updated.
01257       //--------------------------------------------------
01258       
01259       // a new edge, A'B is created.
01260       FEdge *newEdge;
01261       if(ioEdge->isSmooth()){
01262         newEdge = new FEdgeSmooth(ioNewVertex, B);
01263         FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge);
01264         FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(ioEdge);
01265         se->SetMaterialIndex(fes->materialIndex());
01266       }else{
01267         newEdge = new FEdgeSharp(ioNewVertex, B);
01268         FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge);
01269         FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(ioEdge);
01270         se->SetaMaterialIndex(fes->aMaterialIndex());
01271         se->SetbMaterialIndex(fes->bMaterialIndex());
01272       }
01273       newEdge->SetNature(ioEdge->getNature());
01274       
01275       
01276       if(ioEdge->nextEdge() != 0)
01277         ioEdge->nextEdge()->SetPreviousEdge(newEdge);
01278 
01279       // update edge A'B for the next pointing edge
01280       newEdge->SetNextEdge(ioEdge->nextEdge());
01281       // update edge A'B for the previous pointing edge
01282       newEdge->SetPreviousEdge(0); // because it is now a TVertex
01283       Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond()+1);
01284       newEdge->SetId(ioEdge->getId());
01285       ioEdge->SetId(id);
01286    
01287       // update edge AA' for the next pointing edge
01288       ioEdge->SetNextEdge(0); // because it is now a TVertex
01289 
01290       // update vertex pointing edges list:
01291       // -- vertex B --
01292       B->Replace(ioEdge, newEdge);
01293       // -- vertex A' --
01294       ioNewVertex->AddFEdge(ioEdge);
01295       ioNewVertex->AddFEdge(newEdge);
01296 
01297       // to build a new chain:
01298       AddChain(newEdge);
01299       AddEdge(newEdge); // FIXME ??
01300       
01301       // The edge AB becomes edge AA'.
01302       ioEdge->SetVertexB(ioNewVertex);
01303       
01304       if(ioEdge->isSmooth()){
01305         ((FEdgeSmooth*)newEdge)->SetFace(((FEdgeSmooth*)ioEdge)->face());
01306       }
01307       
01308       return newEdge;
01309     }
01310 
01312   inline void SetBBox(const BBox<Vec3r>& iBBox) {_BBox = iBBox;}
01313 
01315   inline void ComputeBBox()
01316   {
01317     if(0 == _verticesList.size())
01318       return;
01319 
01320     Vec3r firstVertex = _verticesList[0]->point3D();
01321     real XMax = firstVertex[0];
01322     real YMax = firstVertex[1];
01323     real ZMax = firstVertex[2];
01324 
01325     real XMin = firstVertex[0];
01326     real YMin = firstVertex[1];
01327     real ZMin = firstVertex[2];
01328 
01329     vector<SVertex*>::iterator v,vend;
01330     // parse all the coordinates to find 
01331     // the Xmax, YMax, ZMax
01332     for(v=_verticesList.begin(),vend=_verticesList.end();
01333         v!=vend;
01334         v++)
01335       {
01336         Vec3r vertex = (*v)->point3D();
01337         // X
01338         real x = vertex[0];
01339         if(x > XMax)
01340           XMax = x;
01341         if(x < XMin)
01342           XMin = x;
01343         
01344         // Y
01345         real y = vertex[1];
01346         if(y > YMax)
01347           YMax = y;
01348         if(y < YMin)
01349           YMin = y;
01350         
01351         // Z
01352         real z = vertex[2];
01353         if(z > ZMax)
01354           ZMax = z;
01355         if(z < ZMin)
01356           ZMin = z;
01357       }
01358     
01359     
01360     SetBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax)));
01361   }
01362 
01363   inline void RemoveEdgeFromChain(FEdge *iEdge)
01364   {
01365     for(vector<FEdge*>::iterator fe=_chains.begin(), feend=_chains.end();
01366     fe!=feend;
01367     fe++)
01368     {
01369       if(iEdge == (*fe))
01370       {
01371         _chains.erase(fe);
01372         break;
01373       }
01374     }
01375   }
01376 
01377   inline void RemoveEdge(FEdge *iEdge)
01378   {
01379     for(vector<FEdge*>::iterator fe=_edgesList.begin(), feend=_edgesList.end();
01380     fe!=feend;
01381     fe++)
01382     {
01383       if(iEdge == (*fe))
01384       {
01385         _edgesList.erase(fe);
01386         break;
01387       }
01388     }
01389   }
01390 
01391   /* accessors */
01393   inline vector<SVertex*>& GetVertexList() {return _verticesList;} // Get vertices list
01395   inline vector<FEdge*>& GetEdgeList() {return _edgesList;} // Get edges list
01396   inline vector<FEdge*>& GetChains() {return _chains;}
01398   inline const BBox<Vec3r>& bbox() {return _BBox;}
01400   inline const Material& material(unsigned i) const {return _Materials[i];}
01402   inline const vector<Material>& materials() const {return _Materials;}
01403   inline ViewShape * viewShape() {return _ViewShape;}
01404   inline float importance() const {return _importance;}
01406   inline Id getId() const { return _Id; }
01407   
01408   /* Modififers */
01410   inline void SetId(Id id) {_Id = id;}
01412   inline void SetMaterials(const vector<Material>& iMaterials) {_Materials = iMaterials;}
01413   inline void SetViewShape(ViewShape *iShape) {_ViewShape = iShape;}
01414   inline void SetImportance(float importance){_importance = importance;}
01415 };
01416 
01417 #endif // SILHOUETTE_H