soc-2008-mxcurioni: first version of lib3ds code. It does NOT work yet and has to...
[blender.git] / source / blender / freestyle / intern / winged_edge / WEdge.h
1 //
2 //  Filename         : WEdge.h
3 //  Author(s)        : Stephane Grabli
4 //  Purpose          : Classes to define a Winged Edge data structure.
5 //  Date of creation : 18/02/2002
6 //
7 ///////////////////////////////////////////////////////////////////////////////
8
9
10 //
11 //  Copyright (C) : Please refer to the COPYRIGHT file distributed 
12 //   with this source distribution. 
13 //
14 //  This program is free software; you can redistribute it and/or
15 //  modify it under the terms of the GNU General Public License
16 //  as published by the Free Software Foundation; either version 2
17 //  of the License, or (at your option) any later version.
18 //
19 //  This program is distributed in the hope that it will be useful,
20 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //  GNU General Public License for more details.
23 //
24 //  You should have received a copy of the GNU General Public License
25 //  along with this program; if not, write to the Free Software
26 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27 //
28 ///////////////////////////////////////////////////////////////////////////////
29
30 #ifndef  WEDGE_H
31 # define WEDGE_H
32
33 # include <vector>
34 # include <iterator>
35 # include "../system/FreestyleConfig.h"
36 # include "../geometry/Geom.h"
37 # include "../scene_graph/FrsMaterial.h"
38
39 using namespace std;
40 using namespace Geometry;
41
42
43                   /**********************************/
44                   /*                                */
45                   /*                                */
46                   /*             WVertex            */
47                   /*                                */
48                   /*                                */
49                   /**********************************/
50
51
52 class WOEdge;
53 class WEdge;
54 class WShape;
55 class WFace;
56 class LIB_WINGED_EDGE_EXPORT WVertex
57 {
58 protected:
59   int _Id;                    // an identificator
60   Vec3r _Vertex;
61   vector<WEdge*> _EdgeList;
62   WShape * _Shape; // the shape to which the vertex belongs
63   bool _Smooth; // flag to indicate whether the Vertex belongs to a smooth edge or not
64   int _Border; // 1 -> border, 0 -> no border, -1 -> not set
65   
66 public:
67   void * userdata; // designed to store specific user data
68   inline WVertex(const Vec3r &v) {_Id = 0; _Vertex = v; userdata = NULL; _Shape = NULL;_Smooth=true;_Border=-1;}
69   /*! Copy constructor */
70   WVertex(WVertex& iBrother);
71   virtual WVertex * duplicate(); 
72   virtual ~WVertex() {}
73
74   /*! accessors */
75   inline Vec3r& GetVertex() {return _Vertex;}
76   inline vector<WEdge*>& GetEdges() {return _EdgeList;}
77   inline int GetId() {return _Id;}
78   inline WShape * shape() const {return _Shape;}
79   inline bool isSmooth() const {return _Smooth;}
80   bool isBoundary();
81   
82   /*! modifiers */
83   inline void setVertex(const Vec3r& v) {_Vertex = v;}
84   inline void setEdges(const vector<WEdge *>& iEdgeList) {_EdgeList = iEdgeList;}
85   inline void setId(int id) {_Id = id;}
86   inline void setShape(WShape *iShape) {_Shape = iShape;}
87   inline void setSmooth(bool b) {_Smooth = b;}
88   inline void setBorder(bool b) {if(b) _Border= 1; else _Border = 0;}
89   
90   /*! Adds an edge to the edges list */
91   void AddEdge(WEdge *iEdge) ;
92
93   virtual void ResetUserData() {userdata = 0;}
94
95
96
97 public:
98
99   
100
101   /*! Iterator to iterate over a vertex incoming edges in the CCW order*/
102 # if defined(__GNUC__) && (__GNUC__ < 3)
103   class incoming_edge_iterator : public input_iterator<WOEdge*,ptrdiff_t>
104 # else
105   class LIB_WINGED_EDGE_EXPORT incoming_edge_iterator : public iterator<input_iterator_tag, WOEdge*,ptrdiff_t>
106 # endif
107   {
108   private:
109     WVertex *_vertex;
110     // 
111     WOEdge *_begin;
112     WOEdge *_current;
113
114     public:
115 # if defined(__GNUC__) && (__GNUC__ < 3)
116     inline incoming_edge_iterator() : input_iterator<WOEdge*,ptrdiff_t>() {}
117 # else
118     inline incoming_edge_iterator() : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>() {}
119 # endif
120         virtual ~incoming_edge_iterator() {}; //soc
121
122   protected:
123     friend class WVertex;
124     inline incoming_edge_iterator(
125                          WVertex *iVertex,
126                          WOEdge * iBegin,
127                          WOEdge * iCurrent)
128 # if defined(__GNUC__) && (__GNUC__ < 3)
129       : input_iterator<WOEdge*,ptrdiff_t>()
130 # else
131       : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>()
132 # endif
133     {
134       _vertex = iVertex;
135       _begin = iBegin;
136       _current = iCurrent;
137     }
138
139   public:
140     inline incoming_edge_iterator(const incoming_edge_iterator& iBrother)
141 # if defined(__GNUC__) && (__GNUC__ < 3)
142       : input_iterator<WOEdge*,ptrdiff_t>(iBrother)
143 # else
144       : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>(iBrother)
145 # endif
146     {
147       _vertex = iBrother._vertex;
148       _begin = iBrother._begin;
149       _current = iBrother._current;
150     }
151
152   public:
153     // operators
154     virtual incoming_edge_iterator& operator++()  // operator corresponding to ++i
155     { 
156       increment();
157       return *this;
158     }
159     virtual incoming_edge_iterator operator++(int)  // opérateur correspondant à i++ 
160     {                                  // c.a.d qui renvoie la valeur *puis* incrémente.
161       incoming_edge_iterator tmp = *this;        // C'est pour cela qu'on stocke la valeur
162       increment();                    // dans un temporaire. 
163       return tmp;
164     } 
165   
166     // comparibility
167     virtual bool operator!=(const incoming_edge_iterator& b) const
168     {
169       return ((_current) != (b._current));
170     }
171
172     virtual bool operator==(const incoming_edge_iterator& b) const
173     {
174       return ((_current)== (b._current));
175     }
176
177     // dereferencing
178     virtual WOEdge* operator*();
179     //virtual WOEdge** operator->();
180   protected:
181     virtual void increment();
182   };
183
184
185     /*! Iterator to iterate over a vertex faces in the CCW order */
186 # if defined(__GNUC__) && (__GNUC__ < 3)
187   class face_iterator : public input_iterator<WFace*,ptrdiff_t>
188 # else
189   class LIB_WINGED_EDGE_EXPORT face_iterator : public iterator<input_iterator_tag, WFace*,ptrdiff_t>
190 # endif
191   {
192   private:
193     incoming_edge_iterator _edge_it;
194
195     public:
196 # if defined(__GNUC__) && (__GNUC__ < 3)
197     inline face_iterator() : input_iterator<WFace*,ptrdiff_t>() {}
198 # else
199     inline face_iterator() : iterator<input_iterator_tag, WFace*,ptrdiff_t>() {}
200 # endif
201         virtual ~face_iterator() {}; //soc
202
203   protected:
204     friend class WVertex;
205     inline face_iterator(
206                          incoming_edge_iterator it)
207 # if defined(__GNUC__) && (__GNUC__ < 3)
208       : input_iterator<WFace*,ptrdiff_t>()
209 # else
210       : iterator<input_iterator_tag, WFace*,ptrdiff_t>()
211 # endif
212     {
213       _edge_it = it;
214     }
215
216   public:
217     inline face_iterator(const face_iterator& iBrother)
218 # if defined(__GNUC__) && (__GNUC__ < 3)
219       : input_iterator<WFace*,ptrdiff_t>(iBrother)
220 # else
221       : iterator<input_iterator_tag, WFace*,ptrdiff_t>(iBrother)
222 # endif
223     {
224       _edge_it = iBrother._edge_it;
225     }
226
227   public:
228     // operators
229     virtual face_iterator& operator++()  // operator corresponding to ++i
230     { 
231       increment();
232       return *this;
233     }
234     virtual face_iterator operator++(int)  // opérateur correspondant à i++ 
235     {                                  // c.a.d qui renvoie la valeur *puis* incrémente.
236       face_iterator tmp = *this;        // C'est pour cela qu'on stocke la valeur
237       increment();                    // dans un temporaire. 
238       return tmp;
239     } 
240   
241     // comparibility
242     virtual bool operator!=(const face_iterator& b) const
243     {
244       return ((_edge_it) != (b._edge_it));
245     }
246
247     virtual bool operator==(const face_iterator& b) const
248     {
249       return ((_edge_it)== (b._edge_it));
250     }
251
252     // dereferencing
253     virtual WFace* operator*();
254     //virtual WOEdge** operator->();
255   protected:
256     inline void increment(){
257       ++_edge_it;
258     }
259   };
260
261 public:
262   /*! iterators access */
263   virtual incoming_edge_iterator incoming_edges_begin();
264   virtual incoming_edge_iterator incoming_edges_end() ; 
265  
266   virtual face_iterator faces_begin() {
267     return face_iterator(incoming_edges_begin());
268   }
269   virtual face_iterator faces_end()   {
270     return face_iterator(incoming_edges_end());
271   }
272 };
273
274
275                   /**********************************/
276                   /*                                */
277                   /*                                */
278                   /*             WOEdge             */
279                   /*                                */
280                   /*                                */
281                   /**********************************/
282 class WFace;
283 class WEdge;
284
285 class LIB_WINGED_EDGE_EXPORT WOEdge
286 {
287 protected:
288   //  WOEdge *_paCWEdge;     // edge reached when traveling clockwise on aFace from the edge
289   //  WOEdge *_pbCWEdge;     // edge reached when traveling clockwise on bFace from the edge
290   //  WOEdge *_paCCWEdge;    // edge reached when traveling counterclockwise on aFace from the edge
291   //  WOEdge *_pbCCWEdge;    // edge reached when traveling counterclockwise on bFace from the edge
292   WVertex *_paVertex;   // starting vertex
293   WVertex *_pbVertex;   // ending vertex
294   WFace   *_paFace;     // when following the edge, face on the right
295   WFace   *_pbFace;     // when following the edge, face on the left
296   WEdge *_pOwner;       // Edge 
297
298 public:
299   void *userdata;
300   inline WOEdge()
301   {
302     //    _paCWEdge = NULL;
303     //    _pbCWEdge = NULL;
304     //    _paCCWEdge = NULL;
305     //    _pbCCWEdge = NULL;
306     _paVertex = NULL;
307     _pbVertex = NULL;
308     _paFace = NULL;
309     _pbFace = NULL;
310     _pOwner = NULL;
311     userdata = NULL;
312   }
313   virtual ~WOEdge() {}; //soc
314
315   /*! copy constructor */
316   WOEdge(WOEdge& iBrother);
317   virtual WOEdge * duplicate();
318
319   /*! accessors */
320   //  inline WOEdge *GetaCWEdge() {return _paCWEdge;}
321   //  inline WOEdge *GetbCWEdge() {return _pbCWEdge;}
322   //  inline WOEdge *GetaCCWEdge() {return _paCCWEdge;}
323   //  inline WOEdge *GetbCCWEdge() {return _pbCCWEdge;}
324   inline WVertex *GetaVertex() {return _paVertex;}
325   inline WVertex *GetbVertex() {return _pbVertex;}
326   inline WFace *GetaFace() {return _paFace;}
327   inline WFace *GetbFace() {return _pbFace;}
328   inline WEdge *GetOwner() {return _pOwner;}
329   
330
331   /*! modifiers */
332   //  inline void SetaCWEdge(WOEdge *pe) {_paCWEdge = pe;}
333   //  inline void SetbCWEdge(WOEdge *pe) {_pbCWEdge = pe;}
334   //  inline void SetaCCWEdge(WOEdge *pe) {_paCCWEdge = pe;}
335   //  inline void SetbCCCWEdge(WOEdge *pe) {_pbCCWEdge = pe;}
336   inline void setaVertex(WVertex *pv) {_paVertex = pv;}
337   inline void setbVertex(WVertex *pv) {_pbVertex = pv;}
338   inline void setaFace(WFace *pf) {_paFace = pf;}
339   inline void setbFace(WFace *pf) {_pbFace = pf;}
340   inline void setOwner(WEdge *pe) {_pOwner = pe;}
341
342   /*! Retrieves the list of edges in CW order */
343   inline void RetrieveCWOrderedEdges(vector<WEdge*>& oEdges);
344   /*! returns the vector between the two vertices */
345   Vec3r getVec3r (); 
346   WOEdge * twin (); 
347   WOEdge * getPrevOnFace();
348   virtual void ResetUserData() {userdata = 0;}
349 };
350
351
352                   /**********************************/
353                   /*                                */
354                   /*                                */
355                   /*             WEdge              */
356                   /*                                */
357                   /*                                */
358                   /**********************************/
359
360 class LIB_WINGED_EDGE_EXPORT WEdge
361 {
362 protected:
363   WOEdge *_paOEdge; // first oriented edge
364   WOEdge *_pbOEdge; // second oriented edge
365   int _nOEdges;     // number of oriented edges associated with this edge. (1 means border edge)
366   int    _Id;       // Identifier for the edge
367   
368 public:
369   void * userdata; // designed to store specific user data
370   inline WEdge()
371   {
372     _paOEdge = NULL;
373     _pbOEdge = NULL;
374     _nOEdges = 0;
375     userdata = NULL;
376   }
377
378   inline WEdge(WOEdge *iOEdge)
379   {
380     _paOEdge = iOEdge;
381     _pbOEdge = NULL;
382     _nOEdges = 1;
383     userdata = NULL;
384   }
385
386   inline WEdge(WOEdge *iaOEdge, WOEdge *ibOEdge)
387   {
388     _paOEdge = iaOEdge;
389     _pbOEdge = ibOEdge;
390     _nOEdges = 2;
391     userdata = NULL;
392   }
393
394   /*! Copy constructor */
395   WEdge(WEdge& iBrother);
396   virtual WEdge * duplicate();
397
398   virtual ~WEdge()
399   {
400     if(NULL != _paOEdge)
401     {
402       delete _paOEdge;
403       _paOEdge = NULL;
404     }
405
406     if(NULL != _pbOEdge)
407     {
408       delete _pbOEdge;
409       _pbOEdge = NULL;
410     }
411   }
412
413   /*! checks whether two WEdge have a common vertex.
414    *  Returns a pointer on the common vertex if it exists, 
415    *  NULL otherwise.
416    */
417   static inline WVertex* CommonVertex(WEdge *iEdge1, WEdge* iEdge2)
418   {
419     if((NULL == iEdge1) || (NULL == iEdge2))
420       return NULL;
421
422     WVertex *wv1 = iEdge1->GetaOEdge()->GetaVertex();
423     WVertex *wv2 = iEdge1->GetaOEdge()->GetbVertex();
424     WVertex *wv3 = iEdge2->GetaOEdge()->GetaVertex();
425     WVertex *wv4 = iEdge2->GetaOEdge()->GetbVertex();
426
427     if((wv1 == wv3) || (wv1 == wv4))
428     {
429       return wv1;
430     }
431     else if((wv2 == wv3) || (wv2 == wv4))
432     {
433       return wv2;
434     }
435
436     return NULL;
437   }
438   /*! accessors */
439   inline WOEdge * GetaOEdge() {return _paOEdge;}
440   inline WOEdge * GetbOEdge() {return _pbOEdge;}
441   inline int GetNumberOfOEdges() {return _nOEdges;}
442   inline int    GetId()    {return _Id;}
443   inline WVertex * GetaVertex() {return _paOEdge->GetaVertex();}
444   inline WVertex * GetbVertex() {return _paOEdge->GetbVertex();}
445   inline WFace * GetaFace() {return _paOEdge->GetaFace();}
446   inline WFace * GetbFace() {return _paOEdge->GetbFace();}
447   inline WOEdge* GetOtherOEdge(WOEdge* iOEdge)
448   {
449     if(iOEdge == _paOEdge)
450       return _pbOEdge;
451     else
452       return _paOEdge;
453   }
454
455   /*! modifiers */
456   inline void setaOEdge(WOEdge *iEdge) {_paOEdge = iEdge;}
457   inline void setbOEdge(WOEdge *iEdge) {_pbOEdge = iEdge;}
458   inline void AddOEdge(WOEdge *iEdge) 
459   {
460     if(NULL == _paOEdge)
461     {
462       _paOEdge = iEdge;
463       _nOEdges++;
464       return;
465     }
466     if(NULL == _pbOEdge)
467     {
468       _pbOEdge = iEdge;
469       _nOEdges++;
470       return;
471     }
472   }
473   inline void setNumberOfOEdges(int n) {_nOEdges = n;}
474   inline void setId(int id) {_Id = id;}
475   virtual void ResetUserData() {userdata = 0;}
476 };
477
478                   /**********************************/
479                   /*                                */
480                   /*                                */
481                   /*             WFace              */
482                   /*                                */
483                   /*                                */
484                   /**********************************/
485
486
487 class LIB_WINGED_EDGE_EXPORT WFace
488 {
489 protected:
490   vector<WOEdge *> _OEdgeList; // list of oriented edges of bording the face
491   Vec3r _Normal;              // normal to the face
492   vector<Vec3r> _VerticesNormals; // in case there is a normal per vertex.
493                                   // The normal number i corresponds to the 
494                                   // aVertex of the oedge number i, for that face
495   vector<Vec2r> _VerticesTexCoords;
496
497   int   _Id;
498   unsigned _FrsMaterialIndex;
499
500 public:
501   void *userdata;
502   inline WFace() {userdata = NULL;_FrsMaterialIndex = 0;}
503   /*! copy constructor */
504   WFace(WFace& iBrother);
505   virtual WFace * duplicate();
506   virtual ~WFace() {}
507
508   /*! accessors */
509   inline const vector<WOEdge*>& getEdgeList() {return _OEdgeList;}
510   inline WOEdge * GetOEdge(int i) {return _OEdgeList[i];}
511   inline Vec3r& GetNormal() {return _Normal;}
512   inline int    GetId()     {return _Id;}
513   inline unsigned frs_materialIndex() const {return _FrsMaterialIndex;}
514   const FrsMaterial& frs_material()  ;
515
516   /*! The vertex of index i corresponds to the a vertex 
517    *  of the edge of index i
518    */
519   inline WVertex* GetVertex(unsigned int index)
520   {
521     //    if(index >= _OEdgeList.size())
522     //      return NULL;
523     return _OEdgeList[index]->GetaVertex();
524   }
525   /*! returns the index at which iVertex is stored in the 
526    * array.
527    * returns -1 if iVertex doesn't belong to the face.
528    */
529   inline int GetIndex(WVertex *iVertex){
530     int index = 0;
531     for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end();
532     woe!=woend;
533     woe++){
534       if((*woe)->GetaVertex() == iVertex)
535         return index;
536       ++index;
537     } 
538     return -1;
539   }
540   inline void RetrieveVertexList(vector<WVertex*>& oVertices)
541   {
542     for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end();
543         woe!=woend;
544         woe++)
545       {
546         oVertices.push_back((*woe)->GetaVertex());
547       }
548   }
549   inline void  RetrieveBorderFaces(vector<const WFace*>& oWFaces)
550   {
551     for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end();
552     woe!=woend;
553     woe++)
554     {
555       WFace *af;
556       if(NULL != (af = (*woe)->GetaFace()))
557       oWFaces.push_back(af);
558     }
559   }
560   inline WFace * GetBordingFace(int index)
561   {
562     //    if(index >= _OEdgeList.size())
563     //      return 0;
564     return _OEdgeList[index]->GetaFace();
565   }
566   inline WFace * GetBordingFace(WOEdge *iOEdge)
567   {
568     return iOEdge->GetaFace();
569   }
570   inline vector<Vec3r>& GetPerVertexNormals()
571   {
572     return _VerticesNormals;
573   }
574   inline vector<Vec2r>& GetPerVertexTexCoords()
575   {
576       return _VerticesTexCoords;
577   }
578   /*! Returns the normal of the vertex of index index */
579   inline Vec3r& GetVertexNormal(int index)
580   {
581       return _VerticesNormals[index];
582   }
583   /*! Returns the tex coords of the vertex of index index */
584   inline Vec2r& GetVertexTexCoords(int index)
585   {
586     return _VerticesTexCoords[index];
587   }
588   /*! Returns the normal of the vertex iVertex for that face */
589   inline Vec3r& GetVertexNormal(WVertex *iVertex)
590   {
591     int i = 0;
592     int index = 0;
593     for(vector<WOEdge*>::const_iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end();
594         woe!=woend;
595         woe++)
596       {
597         if((*woe)->GetaVertex() == iVertex)
598         {
599           index = i;
600           break;
601         }
602         ++i;
603       }
604
605     return _VerticesNormals[index];
606   }
607   inline WOEdge* GetNextOEdge(WOEdge* iOEdge)
608   {
609     bool found = false;
610     vector<WOEdge*>::iterator woe,woend, woefirst;
611     woefirst = _OEdgeList.begin();
612     for(woe=woefirst,woend=_OEdgeList.end();
613         woe!=woend;
614         woe++)
615       {
616         if(true == found)
617           return (*woe);
618         
619         if((*woe) == iOEdge)
620           {
621             found = true;
622           }
623       }
624     
625     // We left the loop. That means that the first
626     // OEdge was the good one:
627     if(found)
628       return (*woefirst);
629
630     return NULL;
631   }
632   WOEdge* GetPrevOEdge(WOEdge* iOEdge);
633  
634   inline int numberOfEdges() const { return _OEdgeList.size();}
635   inline int numberOfVertices() const { return _OEdgeList.size();}
636   /*! Returns true if the face has one ot its edge which is a border 
637    *  edge
638    */
639   inline bool isBorder() const 
640   {
641     for(vector<WOEdge*>::const_iterator woe=_OEdgeList.begin(), woeend=_OEdgeList.end();
642     woe!=woeend;
643     ++woe)
644     {
645       if((*woe)->GetOwner()->GetbOEdge() == 0)
646         return true;
647     }
648     return false;
649   }
650   /*! modifiers */
651   inline void setEdgeList(const vector<WOEdge*>& iEdgeList) {_OEdgeList = iEdgeList;}
652   inline void setNormal(const Vec3r& iNormal) {_Normal = iNormal;}
653   inline void setNormalList(const vector<Vec3r>& iNormalsList) {_VerticesNormals = iNormalsList;}
654   inline void setTexCoordsList(const vector<Vec2r>& iTexCoordsList) {_VerticesTexCoords = iTexCoordsList;}
655   inline void setId(int id) {_Id = id;}
656   inline void setFrsMaterialIndex(unsigned iMaterialIndex) {_FrsMaterialIndex = iMaterialIndex;}
657
658   /*! designed to build a specialized WEdge 
659    *  for use in MakeEdge
660    */
661   virtual WEdge * instanciateEdge() const {return new WEdge;}
662
663   /*! Builds an oriented edge
664    *  Returns the built edge.
665    *    v1, v2
666    *      Vertices at the edge's extremities
667    *      The edge is oriented from v1 to v2.
668    */
669   virtual WOEdge * MakeEdge(WVertex *v1, WVertex *v2);
670
671   /*! Adds an edge to the edges list */
672   inline void AddEdge(WOEdge *iEdge) {_OEdgeList.push_back(iEdge);}
673
674   /*! For triangles, returns the edge opposite to the vertex in e. 
675       returns flase if the face is not a triangle or if the vertex is not found*/
676   bool getOppositeEdge (const WVertex *v, WOEdge* &e); 
677
678   /*! compute the area of the face */
679   real getArea ();
680
681   WShape * getShape() ;
682   virtual void ResetUserData() {userdata = 0;}
683 };
684
685
686                   /**********************************/
687                   /*                                */
688                   /*                                */
689                   /*             WShape             */
690                   /*                                */
691                   /*                                */
692                   /**********************************/
693
694
695 class LIB_WINGED_EDGE_EXPORT WShape
696 {
697 protected:
698   vector<WVertex*> _VertexList;
699   vector<WEdge*>   _EdgeList;
700   vector<WFace*>   _FaceList;
701   int _Id; 
702   static unsigned _SceneCurrentId;
703   Vec3r _min;
704   Vec3r _max;
705   vector<FrsMaterial> _FrsMaterials;
706   real _meanEdgeSize;
707
708 public:
709   inline WShape() {_meanEdgeSize = 0;_Id = _SceneCurrentId; _SceneCurrentId++;}
710   /*! copy constructor */
711   WShape(WShape& iBrother);
712   virtual WShape * duplicate();
713   virtual ~WShape()
714   {
715     if(_EdgeList.size() != 0)
716     {
717       vector<WEdge *>::iterator e;
718       for(e=_EdgeList.begin(); e!=_EdgeList.end(); e++)
719       {
720         delete (*e);
721       }
722       _EdgeList.clear();
723     }
724
725     if(_VertexList.size() != 0)
726     {
727       vector<WVertex *>::iterator v;
728       for(v=_VertexList.begin(); v!=_VertexList.end(); v++)
729       {
730         delete (*v);
731       }
732       _VertexList.clear();
733     }
734
735     if(_FaceList.size() != 0)
736     {
737       vector<WFace *>::iterator f;
738       for(f=_FaceList.begin(); f!=_FaceList.end(); f++)
739       {
740         delete (*f);
741       }
742       _FaceList.clear();
743     }
744   }
745
746   /*! accessors */
747   inline vector<WEdge *>& getEdgeList() {return _EdgeList;}
748   inline vector<WVertex*>& getVertexList() {return _VertexList;}
749   inline vector<WFace*>& GetFaceList() {return _FaceList;}
750   inline unsigned GetId() {return _Id;}
751   inline void bbox(Vec3r& min, Vec3r& max) {min=_min; max=_max;}
752   inline const FrsMaterial& frs_material(unsigned i) const  {return _FrsMaterials[i];}
753   inline const vector<FrsMaterial>& frs_materials() const {return _FrsMaterials;}
754   inline const real getMeanEdgeSize() const {return _meanEdgeSize;}
755   /*! modifiers */
756   static inline void setCurrentId(const unsigned id) { _SceneCurrentId = id; }
757   inline void setEdgeList(const vector<WEdge*>& iEdgeList) {_EdgeList = iEdgeList;}
758   inline void setVertexList(const vector<WVertex*>& iVertexList) {_VertexList = iVertexList;}
759   inline void setFaceList(const vector<WFace*>& iFaceList) {_FaceList = iFaceList;}
760   inline void setId(int id) {_Id = id;}
761   inline void setBBox(const Vec3r& min, const Vec3r& max) {_min = min; _max=max;}
762   inline void setFrsMaterial(const FrsMaterial& frs_material, unsigned i) {_FrsMaterials[i]=frs_material;}
763   inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials) {_FrsMaterials = iMaterials;}
764
765   /*! designed to build a specialized WFace 
766    *  for use in MakeFace
767    */
768   virtual WFace * instanciateFace() const {return new WFace;}
769
770   /*! adds a new face to the shape 
771    *  returns the built face.
772    *   iVertexList 
773    *      List of face's vertices. These vertices are 
774    *      not added to the WShape vertex list; they are 
775    *      supposed to be already stored when calling MakeFace.
776    *      The order in which the vertices are stored in the list 
777    *      determines the face's edges orientation and (so) the 
778    *      face orientation.
779    *   iMaterialIndex
780    *      The material index for this face 
781    */
782   virtual WFace * MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex);
783
784   /*! adds a new face to the shape. The difference with 
785    *  the previous method is that this one is designed 
786    *  to build a WingedEdge structure for which there are 
787    *  per vertex normals, opposed to per face normals.
788    *  returns the built face.
789    *   iVertexList 
790    *      List of face's vertices. These vertices are 
791    *      not added to the WShape vertex list; they are 
792    *      supposed to be already stored when calling MakeFace.
793    *      The order in which the vertices are stored in the list 
794    *      determines the face's edges orientation and (so) the 
795    *      face orientation.
796    *   iMaterialIndex
797    *      The materialIndex for this face
798    *   iNormalsList
799    *     The list of normals, iNormalsList[i] corresponding to the 
800    *     normal of the vertex iVertexList[i] for that face.
801    *   iTexCoordsList
802    *     The list of tex coords, iTexCoordsList[i] corresponding to the 
803    *     normal of the vertex iVertexList[i] for that face.
804    */
805   virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterialIndex);
806
807   inline void AddEdge(WEdge *iEdge) {_EdgeList.push_back(iEdge);}
808   inline void AddFace(WFace* iFace) {_FaceList.push_back(iFace);}
809   inline void AddVertex(WVertex *iVertex) {iVertex->setShape(this); _VertexList.push_back(iVertex);}
810
811   inline void ResetUserData()
812   {
813     for(vector<WVertex*>::iterator v=_VertexList.begin(),vend=_VertexList.end();
814         v!=vend;
815         v++)
816       {
817         (*v)->ResetUserData();
818       }
819
820     for(vector<WEdge*>::iterator e=_EdgeList.begin(),eend=_EdgeList.end();
821         e!=eend;
822         e++)
823       {
824         (*e)->ResetUserData();
825         // manages WOEdge:
826         WOEdge *oe = (*e)->GetaOEdge();
827         if(oe != NULL)
828           oe->ResetUserData();
829         oe = (*e)->GetbOEdge();
830         if(oe != NULL)
831           oe->ResetUserData();
832       }
833
834     for(vector<WFace*>::iterator f=_FaceList.begin(),fend=_FaceList.end();
835         f!=fend;
836         f++)
837       {
838         (*f)->ResetUserData();
839       }
840     
841   }
842
843   inline void ComputeBBox()
844   {
845     _min = _VertexList[0]->GetVertex();
846     _max = _VertexList[0]->GetVertex();
847
848     Vec3r v;
849     for(vector<WVertex*>::iterator wv=_VertexList.begin(), wvend=_VertexList.end();
850     wv!=wvend;
851     wv++)
852     {
853       for(unsigned int i=0; i<3; i++)
854       {
855         v = (*wv)->GetVertex();
856         if(v[i] < _min[i])
857           _min[i] = v[i];
858         if(v[i] > _max[i])
859           _max[i] = v[i];
860       }
861     }
862   }
863
864   inline real ComputeMeanEdgeSize(){
865     _meanEdgeSize = _meanEdgeSize/(_EdgeList.size());
866     return _meanEdgeSize;
867   }
868
869 protected:
870   /*! Builds the face passed as argument (which as already been allocated)
871    *    iVertexList
872    *      List of face's vertices. These vertices are 
873    *      not added to the WShape vertex list; they are 
874    *      supposed to be already stored when calling MakeFace.
875    *      The order in which the vertices are stored in the list 
876    *      determines the face's edges orientation and (so) the 
877    *      face orientation.
878    *    iMaterialIndex
879    *      The material index for this face
880    *    face
881    *      The Face that is filled in
882    */
883   virtual WFace * MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex, WFace *face);
884 };
885
886
887                   /**********************************/
888                   /*                                */
889                   /*                                */
890                   /*          WingedEdge            */
891                   /*                                */
892                   /*                                */
893                   /**********************************/
894
895 class WingedEdge {
896
897  public:
898
899   WingedEdge() {}
900
901   ~WingedEdge() {
902     clear();
903   }
904
905   void clear() {
906     for (vector<WShape*>::iterator it = _wshapes.begin();
907          it != _wshapes.end();
908          it++)
909       delete *it;
910     _wshapes.clear();
911   }
912
913   void addWShape(WShape* wshape) {
914     _wshapes.push_back(wshape);
915   }
916
917   vector<WShape*>& getWShapes() {
918     return _wshapes;
919   }
920
921  private:
922
923   vector<WShape*>       _wshapes;
924 };
925
926
927
928 /*
929   
930   #############################################
931   #############################################
932   #############################################
933   ######                                 ######
934   ######   I M P L E M E N T A T I O N   ######
935   ######                                 ######
936   #############################################
937   #############################################
938   #############################################
939   
940 */
941 /* for inline functions */
942 void WOEdge::RetrieveCWOrderedEdges(vector<WEdge*>& oEdges)
943 {
944     
945     WOEdge *currentOEdge = this;
946     do
947       {
948         WOEdge* nextOEdge = currentOEdge->GetbFace()->GetNextOEdge(currentOEdge);
949         oEdges.push_back(nextOEdge->GetOwner());
950         currentOEdge = nextOEdge->GetOwner()->GetOtherOEdge(nextOEdge);
951         
952       } while((currentOEdge != NULL) && (currentOEdge->GetOwner() != GetOwner()));
953 }
954
955 #endif // WEDGE_H