1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
19 /** \file
20  * \ingroup freestyle
21  * \brief Classes to define a View Map (ViewVertex, ViewEdge, etc.)
22  */
23 
24 #include <map>
25 
26 #include "Interface0D.h"
27 #include "Interface1D.h"
28 #include "Silhouette.h"  // defines the embedding
29 
30 #include "../geometry/GeomUtils.h"
31 
32 #include "../system/BaseIterator.h"
33 #include "../system/FreestyleConfig.h"
34 
35 #ifdef WITH_CXX_GUARDEDALLOC
36 #  include "MEM_guardedalloc.h"
37 #endif
38 
39 namespace Freestyle {
40 
41 /**********************************/
42 /*                                */
43 /*                                */
44 /*             ViewMap            */
45 /*                                */
46 /*                                */
47 /**********************************/
48 
49 /* Density
50  * Mean area depth value
51  * distance to a point
52  */
53 
54 class ViewVertex;
55 class ViewEdge;
56 class ViewShape;
57 class TVertex;
58 
59 /*! Class defining the ViewMap.*/
60 class ViewMap {
61  public:
62   typedef vector<ViewEdge *> viewedges_container;
63   typedef vector<ViewVertex *> viewvertices_container;
64   typedef vector<ViewShape *> viewshapes_container;
65   typedef vector<SVertex *> svertices_container;
66   typedef vector<FEdge *> fedges_container;
67   typedef map<int, int> id_to_index_map;
68 
69  private:
70   static ViewMap *_pInstance;
71   viewshapes_container _VShapes;      // view shapes
72   viewedges_container _VEdges;        // view edges
73   viewvertices_container _VVertices;  // view vertices
74   fedges_container _FEdges;           // feature edges (embedded edges)
75   svertices_container _SVertices;     // embedded vertices
76   BBox<Vec3r> _scene3DBBox;
77   // Mapping between the WShape or VShape id to the VShape index in the _VShapes vector. Used in
78   // the method viewShape(int id) to access a shape from its id.
79   id_to_index_map _shapeIdToIndex;
80 
81  public:
82   /*! A field that can be used by the user to store any data.
83    *  This field must be reset afterwards using ResetUserData().
84    */
85   void *userdata;
86 
87   /*! Default constructor. */
ViewMap()88   ViewMap()
89   {
90     _pInstance = this;
91     userdata = NULL;
92   }
93 
94   /*! Destructor. */
95   virtual ~ViewMap();
96 
97   /*! Gets the viewedge the nearest to the 2D position specified as argument */
98   const ViewEdge *getClosestViewEdge(real x, real y) const;
99 
100   /*! Gets the Fedge the nearest to the 2D position specified as argument */
101   const FEdge *getClosestFEdge(real x, real y) const;
102 
103   /* accessors */
104   /*! The ViewMap is a singleton class. This static method returns the instance of the ViewMap. */
getInstance()105   static inline ViewMap *getInstance()
106   {
107     return _pInstance;
108   }
109 
110   /* Returns the list of ViewShapes of the scene. */
ViewShapes()111   inline viewshapes_container &ViewShapes()
112   {
113     return _VShapes;
114   }
115 
116   /* Returns the list of ViewEdges of the scene. */
ViewEdges()117   inline viewedges_container &ViewEdges()
118   {
119     return _VEdges;
120   }
121 
122   /* Returns the list of ViewVertices of the scene. */
ViewVertices()123   inline viewvertices_container &ViewVertices()
124   {
125     return _VVertices;
126   }
127 
128   /* Returns the list of FEdges of the scene. */
FEdges()129   inline fedges_container &FEdges()
130   {
131     return _FEdges;
132   }
133 
134   /* Returns the list of SVertices of the scene. */
SVertices()135   inline svertices_container &SVertices()
136   {
137     return _SVertices;
138   }
139 
140   /* Returns an iterator pointing onto the first ViewEdge of the list. */
viewedges_begin()141   inline viewedges_container::iterator viewedges_begin()
142   {
143     return _VEdges.begin();
144   }
145 
viewedges_end()146   inline viewedges_container::iterator viewedges_end()
147   {
148     return _VEdges.end();
149   }
150 
viewedges_size()151   inline int viewedges_size()
152   {
153     return _VEdges.size();
154   }
155 
156   ViewShape *viewShape(unsigned id);
157 
shapeIdToIndexMap()158   id_to_index_map &shapeIdToIndexMap()
159   {
160     return _shapeIdToIndex;
161   }
162 
163   /*! Returns the scene 3D bounding box. */
getScene3dBBox()164   inline BBox<Vec3r> getScene3dBBox() const
165   {
166     return _scene3DBBox;
167   }
168 
169   /* modifiers */
170   void AddViewShape(ViewShape *iVShape);
171 
AddViewEdge(ViewEdge * iVEdge)172   inline void AddViewEdge(ViewEdge *iVEdge)
173   {
174     _VEdges.push_back(iVEdge);
175   }
176 
AddViewVertex(ViewVertex * iVVertex)177   inline void AddViewVertex(ViewVertex *iVVertex)
178   {
179     _VVertices.push_back(iVVertex);
180   }
181 
AddFEdge(FEdge * iFEdge)182   inline void AddFEdge(FEdge *iFEdge)
183   {
184     _FEdges.push_back(iFEdge);
185   }
186 
AddSVertex(SVertex * iSVertex)187   inline void AddSVertex(SVertex *iSVertex)
188   {
189     _SVertices.push_back(iSVertex);
190   }
191 
192   /*! Sets the scene 3D bounding box. */
setScene3dBBox(const BBox<Vec3r> & bbox)193   inline void setScene3dBBox(const BBox<Vec3r> &bbox)
194   {
195     _scene3DBBox = bbox;
196   }
197 
198   /* Creates a T vertex in the view map.
199    *  A T vertex is the intersection between 2 FEdges (before these ones are splitted).
200    *  The TVertex is a 2D intersection but it corresponds to a 3D point on each of the 2 FEdges.
201    *    iA3D
202    *      The 3D coordinates of the point corresponding to the intersection on the first edge.
203    *    iA2D
204    *      The x,y,z 2D coordinates of the projection of iA3D
205    *    iFEdgeA
206    *      The first FEdge
207    *    iB3D
208    *      The 3D coordinates of the point corresponding to the intersection on the second edge.
209    *    iB2D
210    *      The x,y,z 2D coordinates of the projection of iB3D
211    *    iFEdgeB
212    *      The second FEdge
213    *    id
214    *      The id that must be given to that TVertex
215    */
216   TVertex *CreateTVertex(const Vec3r &iA3D,
217                          const Vec3r &iA2D,
218                          FEdge *iFEdgeA,
219                          const Vec3r &iB3D,
220                          const Vec3r &iB2D,
221                          FEdge *iFEdgeB,
222                          const Id &id);
223 
224   /* Updates the structures to take into account the fact that a SVertex must now be considered as
225    * a ViewVertex iVertex The SVertex on top of which the ViewVertex is built (it is necessarily a
226    * NonTVertex because it is a SVertex) newViewEdges The new ViewEdges that must be add to the
227    * ViewMap
228    */
229   ViewVertex *InsertViewVertex(SVertex *iVertex, vector<ViewEdge *> &newViewEdges);
230 
231   /* connects a FEdge to the graph trough a SVertex */
232   // FEdge *Connect(FEdge *ioEdge, SVertex *ioVertex);
233 
234   /* Clean temporary FEdges created by chaining */
235   virtual void Clean();
236 
237 #ifdef WITH_CXX_GUARDEDALLOC
238   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMap")
239 #endif
240 };
241 
242 /**********************************/
243 /*                                */
244 /*                                */
245 /*             ViewVertex         */
246 /*                                */
247 /*                                */
248 /**********************************/
249 
250 class ViewEdge;
251 class SShape;
252 
253 namespace ViewVertexInternal {
254 
255 class edge_const_traits;
256 class edge_nonconst_traits;
257 template<class Traits> class edge_iterator_base;
258 class orientedViewEdgeIterator;
259 
260 }  // namespace ViewVertexInternal
261 
262 /*! Class to define a view vertex.
263  *  A view vertex is a feature vertex corresponding to a point of the image graph, where the
264  * characteristics of an edge might change (nature, visibility, ...). A ViewVertex can be of two
265  * kinds: a TVertex when it corresponds to the intersection between two ViewEdges or a NonTVertex
266  * when it corresponds to a vertex of the initial input mesh (it is the case for vertices such as
267  * corners for example). Thus, this class can be specialized into two classes, the TVertex class
268  * and the NonTVertex class.
269  */
270 class ViewVertex : public Interface0D {
271  public:  // Implementation of Interface0D
272   /*! Returns the string "ViewVertex". */
getExactTypeName()273   virtual string getExactTypeName() const
274   {
275     return "ViewVertex";
276   }
277 
278  public:
279   friend class ViewShape;
280   typedef pair<ViewEdge *, bool> directedViewEdge;  // if bool = true, the ViewEdge is incoming
281 
282   typedef vector<directedViewEdge> edges_container;
283 
284   typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_nonconst_traits>
285       edge_iterator;
286   typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_const_traits>
287       const_edge_iterator;
288 
289  private:
290   Nature::VertexNature _Nature;
291 
292  public:
293   /*! A field that can be used by the user to store any data.
294    *  This field must be reset afterwards using ResetUserData().
295    */
296   void *userdata;
297 
298   /*! Default constructor.*/
ViewVertex()299   inline ViewVertex()
300   {
301     userdata = NULL;
302     _Nature = Nature::VIEW_VERTEX;
303   }
304 
ViewVertex(Nature::VertexNature nature)305   inline ViewVertex(Nature::VertexNature nature)
306   {
307     userdata = NULL;
308     _Nature = Nature::VIEW_VERTEX | nature;
309   }
310 
311  protected:
312   /*! Copy constructor. */
ViewVertex(ViewVertex & iBrother)313   inline ViewVertex(ViewVertex &iBrother)
314   {
315     _Nature = iBrother._Nature;
316     iBrother.userdata = this;
317     userdata = NULL;
318   }
319 
320   /*! Cloning method. */
321   virtual ViewVertex *duplicate() = 0;
322 
323  public:
324   /*! Destructor. */
~ViewVertex()325   virtual ~ViewVertex()
326   {
327   }
328 
329   /* accessors */
330   /*! Returns the nature of the vertex .*/
getNature()331   virtual Nature::VertexNature getNature() const
332   {
333     return _Nature;
334   }
335 
336   /* modifiers */
337   /*! Sets the nature of the vertex. */
setNature(Nature::VertexNature iNature)338   inline void setNature(Nature::VertexNature iNature)
339   {
340     _Nature = iNature;
341   }
342 
343   /* Replaces old edge by new edge */
Replace(ViewEdge *,ViewEdge *)344   virtual void Replace(ViewEdge *, ViewEdge *)
345   {
346   }
347 
348  public:
349   /* iterators access */
350   // allows iteration on the edges that comes from/goes to this vertex in CCW order (order defined
351   // in 2D in the image plan)
352   virtual edge_iterator edges_begin() = 0;
353   virtual const_edge_iterator edges_begin() const = 0;
354   virtual edge_iterator edges_end() = 0;
355   virtual const_edge_iterator edges_end() const = 0;
356   virtual edge_iterator edges_iterator(ViewEdge *iEdge) = 0;
357   virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const = 0;
358 
359   // Iterator access
360   /*! Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to
361    * the first ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order
362    * over these ViewEdges and to get the orientation for each ViewEdge (incoming/outgoing).
363    */
364   virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() = 0;
365 
366   /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after
367    * the last ViewEdge.
368    */
369   virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() = 0;
370 
371   /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
372   virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) = 0;
373 
374 #ifdef WITH_CXX_GUARDEDALLOC
375   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewVertex")
376 #endif
377 };
378 
379 /**********************************/
380 /*                                */
381 /*                                */
382 /*             TVertex            */
383 /*                                */
384 /*                                */
385 /**********************************/
386 
387 /*! class to define a T vertex, i.e. an intersection between two edges.
388  *  It points towards 2 SVertex and 4 View edges.
389  *  Among these ViewEdges, 2 are front and 2 are back.
390  *  Basically the front edge hides part of the back edge.
391  *  So, among the back edges, 1 is of invisibility n and the other of visibility n+1
392  */
393 class TVertex : public ViewVertex {
394  public:
395   typedef vector<directedViewEdge *> edge_pointers_container;
396 
397  public:  // Implementation of Interface0D
398   /*! Returns the string "TVertex". */
getExactTypeName()399   virtual string getExactTypeName() const
400   {
401     return "TVertex";
402   }
403 
404   // Data access methods
405   /* Returns the 3D x coordinate of the vertex. Ambiguous in this case. */
getX()406   virtual real getX() const
407   {
408     cerr << "Warning: getX() undefined for this point" << endl;
409     return _FrontSVertex->point3D().x();
410   }
411 
getY()412   virtual real getY() const
413   {
414     cerr << "Warning: getX() undefined for this point" << endl;
415     return _FrontSVertex->point3D().y();
416   }
417 
getZ()418   virtual real getZ() const
419   {
420     cerr << "Warning: getX() undefined for this point" << endl;
421     return _FrontSVertex->point3D().z();
422   }
423 
424   /*! Returns the 3D point. */
getPoint3D()425   virtual Vec3r getPoint3D() const
426   {
427     cerr << "Warning: getPoint3D() undefined for this point" << endl;
428     return _FrontSVertex->getPoint3D();
429   }
430 
431   /*! Returns the projected 3D  x coordinate of the vertex. */
getProjectedX()432   virtual real getProjectedX() const
433   {
434     return _FrontSVertex->point2D().x();
435   }
436 
437   /*! Returns the projected 3D  y coordinate of the vertex. */
getProjectedY()438   virtual real getProjectedY() const
439   {
440     return _FrontSVertex->point2D().y();
441   }
442 
getProjectedZ()443   virtual real getProjectedZ() const
444   {
445     return _FrontSVertex->point2D().z();
446   }
447 
448   /*! Returns the 2D point. */
getPoint2D()449   virtual Vec2r getPoint2D() const
450   {
451     return _FrontSVertex->getPoint2D();
452   }
453 
454   /*! Returns the Id of the TVertex. */
getId()455   virtual Id getId() const
456   {
457     return _Id;
458   }
459 
460   /*! Cast the Interface0D in SVertex if it can be. */
461   // it can't
castToViewVertex()462   virtual ViewVertex *castToViewVertex()
463   {
464     return this;
465   }
466 
467   /*! Cast the Interface0D in TVertex if it can be. */
castToTVertex()468   virtual TVertex *castToTVertex()
469   {
470     return this;
471   }
472 
473  private:
474   SVertex *_FrontSVertex;
475   SVertex *_BackSVertex;
476   directedViewEdge _FrontEdgeA;
477   directedViewEdge _FrontEdgeB;
478   directedViewEdge _BackEdgeA;
479   directedViewEdge _BackEdgeB;
480   Id _Id;  // id to identify t vertices . these id will be negative in order not to be mixed with
481            // NonTVertex ids.
482   edge_pointers_container
483       _sortedEdges;  // the list of the four ViewEdges, ordered in CCW order (in the image plan)
484 
485  public:
486   /*! Default constructor.*/
TVertex()487   inline TVertex() : ViewVertex(Nature::T_VERTEX)
488   {
489     _FrontSVertex = NULL;
490     _BackSVertex = NULL;
491     _FrontEdgeA.first = 0;
492     _FrontEdgeB.first = 0;
493     _BackEdgeA.first = 0;
494     _BackEdgeB.first = 0;
495   }
496 
TVertex(SVertex * svFront,SVertex * svBack)497   inline TVertex(SVertex *svFront, SVertex *svBack) : ViewVertex(Nature::T_VERTEX)
498   {
499     _FrontSVertex = svFront;
500     _BackSVertex = svBack;
501     _FrontEdgeA.first = 0;
502     _FrontEdgeB.first = 0;
503     _BackEdgeA.first = 0;
504     _BackEdgeB.first = 0;
505     svFront->setViewVertex(this);
506     svBack->setViewVertex(this);
507   }
508 
509  protected:
510   /*! Copy constructor. */
TVertex(TVertex & iBrother)511   inline TVertex(TVertex &iBrother) : ViewVertex(iBrother)
512   {
513     _FrontSVertex = iBrother._FrontSVertex;
514     _BackSVertex = iBrother._BackSVertex;
515     _FrontEdgeA = iBrother._FrontEdgeA;
516     _FrontEdgeB = iBrother._FrontEdgeB;
517     _BackEdgeA = iBrother._BackEdgeA;
518     _BackEdgeB = iBrother._BackEdgeB;
519     _sortedEdges = iBrother._sortedEdges;
520   }
521 
522   /*! Cloning method. */
duplicate()523   virtual ViewVertex *duplicate()
524   {
525     TVertex *clone = new TVertex(*this);
526     return clone;
527   }
528 
529  public:
530   /* accessors */
531   /*! Returns the SVertex that is closer to the viewpoint. */
frontSVertex()532   inline SVertex *frontSVertex()
533   {
534     return _FrontSVertex;
535   }
536 
537   /*! Returns the SVertex that is further away from the viewpoint. */
backSVertex()538   inline SVertex *backSVertex()
539   {
540     return _BackSVertex;
541   }
542 
frontEdgeA()543   inline directedViewEdge &frontEdgeA()
544   {
545     return _FrontEdgeA;
546   }
547 
frontEdgeB()548   inline directedViewEdge &frontEdgeB()
549   {
550     return _FrontEdgeB;
551   }
552 
backEdgeA()553   inline directedViewEdge &backEdgeA()
554   {
555     return _BackEdgeA;
556   }
557 
backEdgeB()558   inline directedViewEdge &backEdgeB()
559   {
560     return _BackEdgeB;
561   }
562 
563   /* modifiers */
564   /*! Sets the SVertex that is closer to the viewpoint. */
setFrontSVertex(SVertex * iFrontSVertex)565   inline void setFrontSVertex(SVertex *iFrontSVertex)
566   {
567     _FrontSVertex = iFrontSVertex;
568     _FrontSVertex->setViewVertex(this);
569   }
570 
571   /*! Sets the SVertex that is further away from the viewpoint. */
setBackSVertex(SVertex * iBackSVertex)572   inline void setBackSVertex(SVertex *iBackSVertex)
573   {
574     _BackSVertex = iBackSVertex;
575     _BackSVertex->setViewVertex(this);
576   }
577 
578   void setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming = true);
579   void setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming = true);
580   void setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming = true);
581   void setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming = true);
582 
583   /*! Sets the Id. */
setId(const Id & iId)584   inline void setId(const Id &iId)
585   {
586     _Id = iId;
587   }
588 
589   /*! Returns the SVertex (among the 2) belonging to the FEdge iFEdge */
getSVertex(FEdge * iFEdge)590   inline SVertex *getSVertex(FEdge *iFEdge)
591   {
592     const vector<FEdge *> &vfEdges = _FrontSVertex->fedges();
593     vector<FEdge *>::const_iterator fe, fend;
594     for (fe = vfEdges.begin(), fend = vfEdges.end(); fe != fend; fe++) {
595       if ((*fe) == iFEdge) {
596         return _FrontSVertex;
597       }
598     }
599 
600     const vector<FEdge *> &vbEdges = _BackSVertex->fedges();
601     for (fe = vbEdges.begin(), fend = vbEdges.end(); fe != fend; fe++) {
602       if ((*fe) == iFEdge) {
603         return _BackSVertex;
604       }
605     }
606     return NULL;
607   }
608 
609   virtual void Replace(ViewEdge *iOld, ViewEdge *iNew);
610 
611   /*! returns the mate edge of iEdgeA.
612    *  For example, if iEdgeA is frontEdgeA, then frontEdgeB is returned. If iEdgeA is frontEdgeB
613    * then frontEdgeA is returned. Same for back edges
614    */
mate(ViewEdge * iEdgeA)615   virtual ViewEdge *mate(ViewEdge *iEdgeA)
616   {
617     if (iEdgeA == _FrontEdgeA.first) {
618       return _FrontEdgeB.first;
619     }
620     if (iEdgeA == _FrontEdgeB.first) {
621       return _FrontEdgeA.first;
622     }
623     if (iEdgeA == _BackEdgeA.first) {
624       return _BackEdgeB.first;
625     }
626     if (iEdgeA == _BackEdgeB.first) {
627       return _BackEdgeA.first;
628     }
629     return NULL;
630   }
631 
632   /* iterators access */
633   virtual edge_iterator edges_begin();
634   virtual const_edge_iterator edges_begin() const;
635   virtual edge_iterator edges_end();
636   virtual const_edge_iterator edges_end() const;
637   virtual edge_iterator edges_iterator(ViewEdge *iEdge);
638   virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const;
639 
640   /*! Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to
641    * the first ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order
642    * over these ViewEdges and to get the orientation for each ViewEdge (incoming/outgoing).
643    */
644   virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin();
645 
646   /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after
647    * the last ViewEdge.
648    */
649   virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd();
650 
651   /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
652   virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge);
653 
654 #ifdef WITH_CXX_GUARDEDALLOC
655   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TVertex")
656 #endif
657 };
658 
659 /**********************************/
660 /*                                */
661 /*                                */
662 /*             NonTVertex         */
663 /*                                */
664 /*                                */
665 /**********************************/
666 
667 // (non T vertex)
668 /*! View vertex for corners, cusps, etc...
669  *  Associated to a single SVertex.
670  *  Can be associated to 2 or several view edges
671  */
672 class NonTVertex : public ViewVertex {
673  public:
674   typedef vector<directedViewEdge> edges_container;
675 
676  public:  // Implementation of Interface0D
677   /*! Returns the string "ViewVertex". */
getExactTypeName()678   virtual string getExactTypeName() const
679   {
680     return "NonTVertex";
681   }
682 
683   // Data access methods
684   /*! Returns the 3D x coordinate of the vertex. */
getX()685   virtual real getX() const
686   {
687     return _SVertex->point3D().x();
688   }
689 
690   /*! Returns the 3D y coordinate of the vertex. */
getY()691   virtual real getY() const
692   {
693     return _SVertex->point3D().y();
694   }
695 
696   /*! Returns the 3D z coordinate of the vertex. */
getZ()697   virtual real getZ() const
698   {
699     return _SVertex->point3D().z();
700   }
701 
702   /*!  Returns the 3D point. */
getPoint3D()703   virtual Vec3r getPoint3D() const
704   {
705     return _SVertex->getPoint3D();
706   }
707 
708   /*! Returns the projected 3D  x coordinate of the vertex. */
getProjectedX()709   virtual real getProjectedX() const
710   {
711     return _SVertex->point2D().x();
712   }
713 
714   /*! Returns the projected 3D  y coordinate of the vertex. */
getProjectedY()715   virtual real getProjectedY() const
716   {
717     return _SVertex->point2D().y();
718   }
719 
720   /*! Returns the projected 3D  z coordinate of the vertex. */
getProjectedZ()721   virtual real getProjectedZ() const
722   {
723     return _SVertex->point2D().z();
724   }
725 
726   /*! Returns the 2D point. */
getPoint2D()727   virtual Vec2r getPoint2D() const
728   {
729     return _SVertex->getPoint2D();
730   }
731 
732   /*! Returns the Id of the vertex. */
getId()733   virtual Id getId() const
734   {
735     return _SVertex->getId();
736   }
737 
738   /*! Cast the Interface0D in SVertex if it can be. */
castToSVertex()739   virtual SVertex *castToSVertex()
740   {
741     return _SVertex;
742   }
743 
744   /*! Cast the Interface0D in ViewVertex if it can be. */
castToViewVertex()745   virtual ViewVertex *castToViewVertex()
746   {
747     return this;
748   }
749 
750   /*! Cast the Interface0D in NonTVertex if it can be. */
castToNonTVertex()751   virtual NonTVertex *castToNonTVertex()
752   {
753     return this;
754   }
755 
756  private:
757   SVertex *_SVertex;
758   edges_container _ViewEdges;
759 
760  public:
761   /*! Default constructor.*/
NonTVertex()762   inline NonTVertex() : ViewVertex(Nature::NON_T_VERTEX)
763   {
764     _SVertex = NULL;
765   }
766 
767   /*! Builds a NonTVertex from a SVertex. */
NonTVertex(SVertex * iSVertex)768   inline NonTVertex(SVertex *iSVertex) : ViewVertex(Nature::NON_T_VERTEX)
769   {
770     _SVertex = iSVertex;
771     _SVertex->setViewVertex(this);
772   }
773 
774  protected:
775   /*! Copy constructor. */
NonTVertex(NonTVertex & iBrother)776   inline NonTVertex(NonTVertex &iBrother) : ViewVertex(iBrother)
777   {
778     _SVertex = iBrother._SVertex;
779     _SVertex->setViewVertex(this);
780     _ViewEdges = iBrother._ViewEdges;
781   }
782 
783   /*! Cloning method. */
duplicate()784   virtual ViewVertex *duplicate()
785   {
786     NonTVertex *clone = new NonTVertex(*this);
787     return clone;
788   }
789 
790  public:
791   /*! destructor. */
~NonTVertex()792   virtual ~NonTVertex()
793   {
794   }
795 
796   /* accessors */
797   /*! Returns the SVertex on top of which this NonTVertex is built. */
svertex()798   inline SVertex *svertex()
799   {
800     return _SVertex;
801   }
802 
viewedges()803   inline edges_container &viewedges()
804   {
805     return _ViewEdges;
806   }
807 
808   /* modifiers */
809   /*! Sets the SVertex on top of which this NonTVertex is built. */
setSVertex(SVertex * iSVertex)810   inline void setSVertex(SVertex *iSVertex)
811   {
812     _SVertex = iSVertex;
813     _SVertex->setViewVertex(this);
814   }
815 
setViewEdges(const vector<directedViewEdge> & iViewEdges)816   inline void setViewEdges(const vector<directedViewEdge> &iViewEdges)
817   {
818     _ViewEdges = iViewEdges;
819   }
820 
821   void AddIncomingViewEdge(ViewEdge *iVEdge);
822   void AddOutgoingViewEdge(ViewEdge *iVEdge);
823 
824   inline void AddViewEdge(ViewEdge *iVEdge, bool incoming = true)
825   {
826     if (incoming) {
827       AddIncomingViewEdge(iVEdge);
828     }
829     else {
830       AddOutgoingViewEdge(iVEdge);
831     }
832   }
833 
834   /* Replaces old edge by new edge */
Replace(ViewEdge * iOld,ViewEdge * iNew)835   virtual void Replace(ViewEdge *iOld, ViewEdge *iNew)
836   {
837     edges_container::iterator insertedve;
838     for (edges_container::iterator ve = _ViewEdges.begin(), vend = _ViewEdges.end(); ve != vend;
839          ve++) {
840       if ((ve)->first == iOld) {
841         insertedve = _ViewEdges.insert(
842             ve, directedViewEdge(iNew, ve->second));  // inserts e2 before ve.
843         // returns an iterator pointing toward e2. ve is invalidated.
844         // we want to remove e1, but we can't use ve anymore:
845         insertedve++;  // insertedve points now to e1
846         _ViewEdges.erase(insertedve);
847         return;
848       }
849     }
850   }
851 
852   /* iterators access */
853   virtual edge_iterator edges_begin();
854   virtual const_edge_iterator edges_begin() const;
855   virtual edge_iterator edges_end();
856   virtual const_edge_iterator edges_end() const;
857   virtual edge_iterator edges_iterator(ViewEdge *iEdge);
858   virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const;
859 
860   /*! Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to
861    * the first ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order
862    * over these ViewEdges and to get the orientation for each ViewEdge (incoming/outgoing).
863    */
864   virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin();
865 
866   /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after
867    * the last ViewEdge.
868    */
869   virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd();
870 
871   /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
872   virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge);
873 
874 #ifdef WITH_CXX_GUARDEDALLOC
875   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NonTVertex")
876 #endif
877 };
878 
879 /**********************************/
880 /*                                */
881 /*                                */
882 /*             ViewEdge           */
883 /*                                */
884 /*                                */
885 /**********************************/
886 
887 /* Geometry(normals...)
888  * Nature of edges
889  * 2D spaces (1or2, material, z...)
890  * Parent Shape
891  * 3D Shading, material
892  * Importance
893  * Occluders
894  */
895 class ViewShape;
896 
897 namespace ViewEdgeInternal {
898 
899 template<class Traits> class edge_iterator_base;
900 template<class Traits> class fedge_iterator_base;
901 template<class Traits> class vertex_iterator_base;
902 
903 }  // end of namespace ViewEdgeInternal
904 
905 /*! Class defining a ViewEdge. A ViewEdge in an edge of the image graph. it connects two
906  * ViewVertex. It is made by connecting a set of FEdges.
907  */
908 class ViewEdge : public Interface1D {
909  public:  // Implementation of Interface0D
910   /*! Returns the string "ViewEdge". */
getExactTypeName()911   virtual string getExactTypeName() const
912   {
913     return "ViewEdge";
914   }
915 
916   // Data access methods
917   /*! Returns the Id of the vertex. */
getId()918   virtual Id getId() const
919   {
920     return _Id;
921   }
922 
923   /*! Returns the nature of the ViewEdge. */
getNature()924   virtual Nature::EdgeNature getNature() const
925   {
926     return _Nature;
927   }
928 
929  public:
930   typedef SVertex vertex_type;
931   friend class ViewShape;
932   // for ViewEdge iterator
933   typedef ViewEdgeInternal::edge_iterator_base<Nonconst_traits<ViewEdge *>> edge_iterator;
934   typedef ViewEdgeInternal::edge_iterator_base<Const_traits<ViewEdge *>> const_edge_iterator;
935   // for fedge iterator
936   typedef ViewEdgeInternal::fedge_iterator_base<Nonconst_traits<FEdge *>> fedge_iterator;
937   typedef ViewEdgeInternal::fedge_iterator_base<Const_traits<FEdge *>> const_fedge_iterator;
938   // for svertex iterator
939   typedef ViewEdgeInternal::vertex_iterator_base<Nonconst_traits<SVertex *>> vertex_iterator;
940   typedef ViewEdgeInternal::vertex_iterator_base<Const_traits<SVertex *>> const_vertex_iterator;
941 
942  private:
943   ViewVertex *__A;             // edge starting vertex
944   ViewVertex *__B;             // edge ending vertex
945   Nature::EdgeNature _Nature;  // nature of view edge
946   ViewShape *_Shape;           // shape to which the view edge belongs
947   FEdge *_FEdgeA;              // first edge of the embedded fedges chain
948   FEdge *_FEdgeB;              // last edge of the embedded fedges chain
949   Id _Id;
950   unsigned _ChainingTimeStamp;
951   // The silhouette view edge separates 2 2D spaces. The one on the left is necessarly the Shape
952   // _Shape (the one to which this edge belongs to) and _aShape is the one on its right NOT HANDLED
953   // BY THE COPY CONSTRUCTOR
954   ViewShape *_aShape;
955   int _qi;
956   vector<ViewShape *> _Occluders;
957   bool _isInImage;
958 
959   // tmp
960   Id *_splittingId;
961 
962  public:
963   /*! A field that can be used by the user to store any data.
964    *  This field must be reset afterwards using ResetUserData().
965    */
966   void *userdata;
967 
968   /*! Default constructor. */
ViewEdge()969   inline ViewEdge()
970   {
971     __A = NULL;
972     __B = NULL;
973     _FEdgeA = NULL;
974     _FEdgeB = NULL;
975     _ChainingTimeStamp = 0;
976     _qi = 0;
977     _aShape = NULL;
978     userdata = NULL;
979     _splittingId = NULL;
980     _isInImage = true;
981   }
982 
ViewEdge(ViewVertex * iA,ViewVertex * iB)983   inline ViewEdge(ViewVertex *iA, ViewVertex *iB)
984   {
985     __A = iA;
986     __B = iB;
987     _FEdgeA = NULL;
988     _FEdgeB = NULL;
989     _Shape = 0;
990     _ChainingTimeStamp = 0;
991     _qi = 0;
992     _aShape = NULL;
993     userdata = NULL;
994     _splittingId = NULL;
995     _isInImage = true;
996   }
997 
ViewEdge(ViewVertex * iA,ViewVertex * iB,FEdge * iFEdgeA)998   inline ViewEdge(ViewVertex *iA, ViewVertex *iB, FEdge *iFEdgeA)
999   {
1000     __A = iA;
1001     __B = iB;
1002     _FEdgeA = iFEdgeA;
1003     _FEdgeB = NULL;
1004     _Shape = NULL;
1005     _ChainingTimeStamp = 0;
1006     _qi = 0;
1007     _aShape = NULL;
1008     userdata = NULL;
1009     _splittingId = NULL;
1010     _isInImage = true;
1011   }
1012 
ViewEdge(ViewVertex * iA,ViewVertex * iB,FEdge * iFEdgeA,FEdge * iFEdgeB,ViewShape * iShape)1013   inline ViewEdge(
1014       ViewVertex *iA, ViewVertex *iB, FEdge *iFEdgeA, FEdge *iFEdgeB, ViewShape *iShape)
1015   {
1016     __A = iA;
1017     __B = iB;
1018     _FEdgeA = iFEdgeA;
1019     _FEdgeB = iFEdgeB;
1020     _Shape = iShape;
1021     _ChainingTimeStamp = 0;
1022     _qi = 0;
1023     _aShape = NULL;
1024     userdata = NULL;
1025     _splittingId = NULL;
1026     _isInImage = true;
1027     UpdateFEdges();  // tells every FEdge between iFEdgeA and iFEdgeB that this is theit ViewEdge
1028   }
1029 
1030   // soc protected:
1031   /*! Copy constructor. */
ViewEdge(ViewEdge & iBrother)1032   inline ViewEdge(ViewEdge &iBrother)
1033   {
1034     __A = iBrother.__A;
1035     __B = iBrother.__B;
1036     _FEdgeA = iBrother._FEdgeA;
1037     _FEdgeB = iBrother._FEdgeB;
1038     _Nature = iBrother._Nature;
1039     _Shape = NULL;
1040     _Id = iBrother._Id;
1041     _ChainingTimeStamp = iBrother._ChainingTimeStamp;
1042     _aShape = iBrother._aShape;
1043     _qi = iBrother._qi;
1044     _splittingId = NULL;
1045     _isInImage = iBrother._isInImage;
1046     iBrother.userdata = this;
1047     userdata = NULL;
1048   }
1049 
1050   /*! Cloning method. */
duplicate()1051   virtual ViewEdge *duplicate()
1052   {
1053     ViewEdge *clone = new ViewEdge(*this);
1054     return clone;
1055   }
1056 
1057  public:
1058   /*! Destructor. */
~ViewEdge()1059   virtual ~ViewEdge()
1060   {
1061 #if 0
1062     if (_aFace) {
1063       delete _aFace;
1064       _aFace = NULL;
1065     }
1066 #endif
1067     // only the last splitted deletes this id
1068     if (_splittingId) {
1069       if (*_splittingId == _Id) {
1070         delete _splittingId;
1071       }
1072     }
1073   }
1074 
1075   /* accessors */
1076   /*! Returns the first ViewVertex. */
A()1077   inline ViewVertex *A()
1078   {
1079     return __A;
1080   }
1081 
1082   /*! Returns the second ViewVertex. */
B()1083   inline ViewVertex *B()
1084   {
1085     return __B;
1086   }
1087 
1088   /*! Returns the first FEdge that constitues this ViewEdge. */
fedgeA()1089   inline FEdge *fedgeA()
1090   {
1091     return _FEdgeA;
1092   }
1093 
1094   /*! Returns the last FEdge that constitues this ViewEdge. */
fedgeB()1095   inline FEdge *fedgeB()
1096   {
1097     return _FEdgeB;
1098   }
1099 
1100   /*! Returns the ViewShape to which this ViewEdge belongs to .*/
viewShape()1101   inline ViewShape *viewShape()
1102   {
1103     return _Shape;
1104   }
1105 
1106   /*! Returns the shape that is occluded by the ViewShape to which this ViewEdge belongs to. If no
1107    * object is occluded, NULL is returned. \return The occluded ViewShape.
1108    */
aShape()1109   inline ViewShape *aShape()
1110   {
1111     return _aShape;
1112   }
1113 
1114   /*! Tells whether this ViewEdge forms a closed loop or not. */
isClosed()1115   inline bool isClosed()
1116   {
1117     if (!__B) {
1118       return true;
1119     }
1120     return false;
1121   }
1122 
1123   /*! Returns the time stamp of this ViewEdge. */
getChainingTimeStamp()1124   inline unsigned getChainingTimeStamp()
1125   {
1126     return _ChainingTimeStamp;
1127   }
1128 
aShape()1129   inline const ViewShape *aShape() const
1130   {
1131     return _aShape;
1132   }
1133 
bShape()1134   inline const ViewShape *bShape() const
1135   {
1136     return _Shape;
1137   }
1138 
occluders()1139   inline vector<ViewShape *> &occluders()
1140   {
1141     return _Occluders;
1142   }
1143 
splittingId()1144   inline Id *splittingId()
1145   {
1146     return _splittingId;
1147   }
1148 
isInImage()1149   inline bool isInImage() const
1150   {
1151     return _isInImage;
1152   }
1153 
1154   /* modifiers */
1155   /*! Sets the first ViewVertex of the ViewEdge. */
setA(ViewVertex * iA)1156   inline void setA(ViewVertex *iA)
1157   {
1158     __A = iA;
1159   }
1160 
1161   /*! Sets the last ViewVertex of the ViewEdge. */
setB(ViewVertex * iB)1162   inline void setB(ViewVertex *iB)
1163   {
1164     __B = iB;
1165   }
1166 
1167   /*! Sets the nature of the ViewEdge. */
setNature(Nature::EdgeNature iNature)1168   inline void setNature(Nature::EdgeNature iNature)
1169   {
1170     _Nature = iNature;
1171   }
1172 
1173   /*! Sets the first FEdge of the ViewEdge. */
setFEdgeA(FEdge * iFEdge)1174   inline void setFEdgeA(FEdge *iFEdge)
1175   {
1176     _FEdgeA = iFEdge;
1177   }
1178 
1179   /*! Sets the last FEdge of the ViewEdge. */
setFEdgeB(FEdge * iFEdge)1180   inline void setFEdgeB(FEdge *iFEdge)
1181   {
1182     _FEdgeB = iFEdge;
1183   }
1184 
1185   /*! Sets the ViewShape to which this ViewEdge belongs to.*/
setShape(ViewShape * iVShape)1186   inline void setShape(ViewShape *iVShape)
1187   {
1188     _Shape = iVShape;
1189   }
1190 
1191   /*! Sets the ViewEdge id. */
setId(const Id & id)1192   inline void setId(const Id &id)
1193   {
1194     _Id = id;
1195   }
1196 
1197   /*! Sets Viewedge to this for all embedded fedges */
1198   void UpdateFEdges();
1199 
1200   /*! Sets the occluded ViewShape */
setaShape(ViewShape * iShape)1201   inline void setaShape(ViewShape *iShape)
1202   {
1203     _aShape = iShape;
1204   }
1205 
1206   /*! Sets the quantitative invisibility value. */
setQI(int qi)1207   inline void setQI(int qi)
1208   {
1209     _qi = qi;
1210   }
1211 
1212   /*! Sets the time stamp value. */
setChainingTimeStamp(unsigned ts)1213   inline void setChainingTimeStamp(unsigned ts)
1214   {
1215     _ChainingTimeStamp = ts;
1216   }
1217 
AddOccluder(ViewShape * iShape)1218   inline void AddOccluder(ViewShape *iShape)
1219   {
1220     _Occluders.push_back(iShape);
1221   }
1222 
setSplittingId(Id * id)1223   inline void setSplittingId(Id *id)
1224   {
1225     _splittingId = id;
1226   }
1227 
setIsInImage(bool iFlag)1228   inline void setIsInImage(bool iFlag)
1229   {
1230     _isInImage = iFlag;
1231   }
1232 
1233   /* stroke interface definition */
intersect_2d_area(const Vec2r & iMin,const Vec2r & iMax)1234   inline bool intersect_2d_area(const Vec2r &iMin, const Vec2r &iMax) const
1235   {
1236     // parse edges to check if one of them is intersection the region:
1237     FEdge *current = _FEdgeA;
1238     do {
1239       if (GeomUtils::intersect2dSeg2dArea(
1240               iMin,
1241               iMax,
1242               Vec2r(current->vertexA()->point2D()[0], current->vertexA()->point2D()[1]),
1243               Vec2r(current->vertexB()->point2D()[0], current->vertexB()->point2D()[1]))) {
1244         return true;
1245       }
1246       current = current->nextEdge();
1247     } while ((current != 0) && (current != _FEdgeA));
1248 
1249     return false;
1250   }
1251 
include_in_2d_area(const Vec2r & iMin,const Vec2r & iMax)1252   inline bool include_in_2d_area(const Vec2r &iMin, const Vec2r &iMax) const
1253   {
1254     // parse edges to check if all of them are intersection the region:
1255     FEdge *current = _FEdgeA;
1256 
1257     do {
1258       if (!GeomUtils::include2dSeg2dArea(
1259               iMin,
1260               iMax,
1261               Vec2r(current->vertexA()->point2D()[0], current->vertexA()->point2D()[1]),
1262               Vec2r(current->vertexB()->point2D()[0], current->vertexB()->point2D()[1]))) {
1263         return false;
1264       }
1265       current = current->nextEdge();
1266     } while ((current != 0) && (current != _FEdgeA));
1267 
1268     return true;
1269   }
1270 
1271   /* Information access interface */
1272 
1273 #if 0
1274   inline Nature::EdgeNature viewedge_nature() const
1275   {
1276     return getNature();
1277   }
1278 
1279   float viewedge_length() const;
1280 #endif
1281 
1282   /*! Returns the 2D length of the Viewedge. */
1283   real getLength2D() const;
1284 
1285 #if 0
1286   inline Material material() const
1287   {
1288     return _FEdgeA->vertexA()->shape()->material();
1289   }
1290 #endif
1291 
qi()1292   inline int qi() const
1293   {
1294     return _qi;
1295   }
1296 
occluders_begin()1297   inline occluder_container::const_iterator occluders_begin() const
1298   {
1299     return _Occluders.begin();
1300   }
1301 
occluders_end()1302   inline occluder_container::const_iterator occluders_end() const
1303   {
1304     return _Occluders.end();
1305   }
1306 
occluders_size()1307   inline int occluders_size() const
1308   {
1309     return _Occluders.size();
1310   }
1311 
occluders_empty()1312   inline bool occluders_empty() const
1313   {
1314     return _Occluders.empty();
1315   }
1316 
occludee()1317   inline const Polygon3r &occludee() const
1318   {
1319     return (_FEdgeA->aFace());
1320   }
1321 
1322   inline const SShape *occluded_shape() const;
1323 
occludee_empty()1324   inline const bool occludee_empty() const
1325   {
1326     if (_aShape == 0) {
1327       return true;
1328     }
1329     return false;
1330   }
1331 
1332   // inline real z_discontinuity(int iCombination = 0) const;
1333 
shape_id()1334   inline Id shape_id() const
1335   {
1336     return _FEdgeA->vertexA()->shape()->getId();
1337   }
1338 
shape()1339   inline const SShape *shape() const
1340   {
1341     return _FEdgeA->vertexA()->shape();
1342   }
1343 
shape_importance()1344   inline float shape_importance() const
1345   {
1346     return _FEdgeA->shape_importance();
1347   }
1348 
1349   /* iterators access */
1350   // view edge iterator
1351   edge_iterator ViewEdge_iterator();
1352   const_edge_iterator ViewEdge_iterator() const;
1353   // feature edge iterator
1354   fedge_iterator fedge_iterator_begin();
1355   const_fedge_iterator fedge_iterator_begin() const;
1356   fedge_iterator fedge_iterator_last();
1357   const_fedge_iterator fedge_iterator_last() const;
1358   fedge_iterator fedge_iterator_end();
1359   const_fedge_iterator fedge_iterator_end() const;
1360   // embedding vertex iterator
1361   const_vertex_iterator vertices_begin() const;
1362   vertex_iterator vertices_begin();
1363   const_vertex_iterator vertices_last() const;
1364   vertex_iterator vertices_last();
1365   const_vertex_iterator vertices_end() const;
1366   vertex_iterator vertices_end();
1367 
1368   // Iterator access (Interface1D)
1369   /*! Returns an Interface0DIterator to iterate over the SVertex constituting the embedding of this
1370    * ViewEdge. The returned Interface0DIterator points to the first SVertex of the ViewEdge.
1371    */
1372   virtual Interface0DIterator verticesBegin();
1373 
1374   /*! Returns an Interface0DIterator to iterate over the SVertex constituting the embedding of this
1375    * ViewEdge. The returned Interface0DIterator points after the last SVertex of the ViewEdge.
1376    */
1377   virtual Interface0DIterator verticesEnd();
1378 
1379   /*! Returns an Interface0DIterator to iterate over the points of this ViewEdge at a given
1380    * resolution. The returned Interface0DIterator points on the first Point of the ViewEdge.
1381    *  \param t:
1382    *    the sampling value.
1383    */
1384   virtual Interface0DIterator pointsBegin(float t = 0.0f);
1385 
1386   /*! Returns an Interface0DIterator to iterate over the points of this ViewEdge at a given
1387    * resolution. The returned Interface0DIterator points after the last Point of the ViewEdge.
1388    *  \param t:
1389    *    the sampling value.
1390    */
1391   virtual Interface0DIterator pointsEnd(float t = 0.0f);
1392 
1393 #ifdef WITH_CXX_GUARDEDALLOC
1394   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdge")
1395 #endif
1396 };
1397 
1398 /**********************************/
1399 /*                                */
1400 /*                                */
1401 /*             ViewShape          */
1402 /*                                */
1403 /*                                */
1404 /**********************************/
1405 
1406 /*! Class gathering the elements of the ViewMap (ViewVertex, ViewEdge) that are issued from the
1407  * same input shape. */
1408 class ViewShape {
1409  private:
1410   vector<ViewVertex *> _Vertices;
1411   vector<ViewEdge *> _Edges;
1412   SShape *_SShape;
1413 
1414  public:
1415   /*! A field that can be used by the user to store any data.
1416    *  This field must be reset afterwards using ResetUserData().
1417    */
1418   void *userdata;
1419 
1420   /*! Default constructor.*/
ViewShape()1421   inline ViewShape()
1422   {
1423     userdata = NULL;
1424     _SShape = NULL;
1425   }
1426 
1427   /*! Builds a ViewShape from a SShape. */
ViewShape(SShape * iSShape)1428   inline ViewShape(SShape *iSShape)
1429   {
1430     userdata = NULL;
1431     _SShape = iSShape;
1432     //_SShape->setViewShape(this);
1433   }
1434 
1435   /*! Copy constructor. */
ViewShape(ViewShape & iBrother)1436   inline ViewShape(ViewShape &iBrother)
1437   {
1438     userdata = NULL;
1439     vector<ViewVertex *>::iterator vv, vvend;
1440     vector<ViewEdge *>::iterator ve, veend;
1441 
1442     _SShape = iBrother._SShape;
1443 
1444     vector<ViewVertex *> &vvertices = iBrother.vertices();
1445     // duplicate vertices
1446     for (vv = vvertices.begin(), vvend = vvertices.end(); vv != vvend; vv++) {
1447       ViewVertex *newVertex = (*vv)->duplicate();
1448       AddVertex(newVertex);
1449     }
1450 
1451     vector<ViewEdge *> &vvedges = iBrother.edges();
1452     // duplicate edges
1453     for (ve = vvedges.begin(), veend = vvedges.end(); ve != veend; ve++) {
1454       ViewEdge *newEdge = (*ve)->duplicate();
1455       AddEdge(newEdge);  // here the shape is set as the edge's shape
1456     }
1457 
1458     //-------------------------
1459     // remap edges in vertices:
1460     //-------------------------
1461     for (vv = _Vertices.begin(), vvend = _Vertices.end(); vv != vvend; vv++) {
1462       switch ((*vv)->getNature()) {
1463         case Nature::T_VERTEX: {
1464           TVertex *v = (TVertex *)(*vv);
1465           ViewEdge *veFrontA = (ViewEdge *)(v)->frontEdgeA().first->userdata;
1466           ViewEdge *veFrontB = (ViewEdge *)(v)->frontEdgeB().first->userdata;
1467           ViewEdge *veBackA = (ViewEdge *)(v)->backEdgeA().first->userdata;
1468           ViewEdge *veBackB = (ViewEdge *)(v)->backEdgeB().first->userdata;
1469 
1470           v->setFrontEdgeA(veFrontA, v->frontEdgeA().second);
1471           v->setFrontEdgeB(veFrontB, v->frontEdgeB().second);
1472           v->setBackEdgeA(veBackA, v->backEdgeA().second);
1473           v->setBackEdgeB(veBackB, v->backEdgeB().second);
1474         } break;
1475         case Nature::NON_T_VERTEX: {
1476           NonTVertex *v = (NonTVertex *)(*vv);
1477           vector<ViewVertex::directedViewEdge> &vedges = (v)->viewedges();
1478           vector<ViewVertex::directedViewEdge> newEdges;
1479           for (vector<ViewVertex::directedViewEdge>::iterator ve = vedges.begin(),
1480                                                               veend = vedges.end();
1481                ve != veend;
1482                ve++) {
1483             ViewEdge *current = (ViewEdge *)((ve)->first)->userdata;
1484             newEdges.push_back(ViewVertex::directedViewEdge(current, ve->second));
1485           }
1486           (v)->setViewEdges(newEdges);
1487         } break;
1488         default:
1489           break;
1490       }
1491     }
1492 
1493     //-------------------------------------
1494     // remap vertices in edges:
1495     //-------------------------------------
1496     for (ve = _Edges.begin(), veend = _Edges.end(); ve != veend; ve++) {
1497       (*ve)->setA((ViewVertex *)((*ve)->A()->userdata));
1498       (*ve)->setB((ViewVertex *)((*ve)->B()->userdata));
1499       //---------------------------------------
1500       // Update all embedded FEdges
1501       //---------------------------------------
1502       (*ve)->UpdateFEdges();
1503     }
1504 
1505     // reset all brothers userdata to NULL:
1506     //-------------------------------------
1507     //---------
1508     // vertices
1509     //---------
1510     for (vv = vvertices.begin(), vvend = vvertices.end(); vv != vvend; vv++) {
1511       (*vv)->userdata = NULL;
1512     }
1513 
1514     //------
1515     // edges
1516     //------
1517     for (ve = vvedges.begin(), veend = vvedges.end(); ve != veend; ve++) {
1518       (*ve)->userdata = NULL;
1519     }
1520   }
1521 
1522   /*! Cloning method. */
duplicate()1523   virtual ViewShape *duplicate()
1524   {
1525     ViewShape *clone = new ViewShape(*this);
1526     return clone;
1527   }
1528 
1529   /*! Destructor. */
1530   virtual ~ViewShape();
1531 
1532   /* splits a view edge into several view edges.
1533    *    fe
1534    *      The FEdge that gets splitted
1535    *    iViewVertices
1536    *      The view vertices corresponding to the different intersections for the edge fe.
1537    *      This list need to be sorted such as the first view vertex is the farther away from
1538    * fe->vertexA. ioNewEdges The feature edges that are newly created (the initial edges are not
1539    * included) are added to this list. ioNewViewEdges The view edges that are newly created (the
1540    * initial edges are not included) are added to this list.
1541    */
1542   inline void SplitEdge(FEdge *fe,
1543                         const vector<TVertex *> &iViewVertices,
1544                         vector<FEdge *> &ioNewEdges,
1545                         vector<ViewEdge *> &ioNewViewEdges);
1546 
1547   /* accessors */
1548   /*! Returns the SShape on top of which this ViewShape is built. */
sshape()1549   inline SShape *sshape()
1550   {
1551     return _SShape;
1552   }
1553 
1554   /*! Returns the SShape on top of which this ViewShape is built. */
sshape()1555   inline const SShape *sshape() const
1556   {
1557     return _SShape;
1558   }
1559 
1560   /*! Returns the list of ViewVertex contained in this ViewShape. */
vertices()1561   inline vector<ViewVertex *> &vertices()
1562   {
1563     return _Vertices;
1564   }
1565 
1566   /*! Returns the list of ViewEdge contained in this ViewShape. */
edges()1567   inline vector<ViewEdge *> &edges()
1568   {
1569     return _Edges;
1570   }
1571 
1572   /*! Returns the ViewShape id. */
getId()1573   inline Id getId() const
1574   {
1575     return _SShape->getId();
1576   }
1577 
1578   /*! Returns the ViewShape name. */
getName()1579   inline const string &getName() const
1580   {
1581     return _SShape->getName();
1582   }
1583 
1584   /*! Returns the ViewShape library path. */
getLibraryPath()1585   inline const string &getLibraryPath() const
1586   {
1587     return _SShape->getLibraryPath();
1588   }
1589 
1590   /* modifiers */
1591   /*! Sets the SShape on top of which the ViewShape is built. */
setSShape(SShape * iSShape)1592   inline void setSShape(SShape *iSShape)
1593   {
1594     _SShape = iSShape;
1595   }
1596 
1597   /*! Sets the list of ViewVertex contained in this ViewShape. */
setVertices(const vector<ViewVertex * > & iVertices)1598   inline void setVertices(const vector<ViewVertex *> &iVertices)
1599   {
1600     _Vertices = iVertices;
1601   }
1602 
1603   /*! Sets the list of ViewEdge contained in this ViewShape. */
setEdges(const vector<ViewEdge * > & iEdges)1604   inline void setEdges(const vector<ViewEdge *> &iEdges)
1605   {
1606     _Edges = iEdges;
1607   }
1608 
1609   /*! Adds a ViewVertex to the list. */
AddVertex(ViewVertex * iVertex)1610   inline void AddVertex(ViewVertex *iVertex)
1611   {
1612     _Vertices.push_back(iVertex);
1613     //_SShape->AddNewVertex(iVertex->svertex());
1614   }
1615 
1616   /*! Adds a ViewEdge to the list */
AddEdge(ViewEdge * iEdge)1617   inline void AddEdge(ViewEdge *iEdge)
1618   {
1619     _Edges.push_back(iEdge);
1620     iEdge->setShape(this);
1621     //_SShape->AddNewEdge(iEdge->fedge());
1622   }
1623 
1624   /* removes the view edge iViewEdge in the View Shape and the associated FEdge chain entry in the
1625    * underlying SShape
1626    */
1627   void RemoveEdge(ViewEdge *iViewEdge);
1628 
1629   /* removes the view vertex iViewVertex in the View Shape. */
1630   void RemoveVertex(ViewVertex *iViewVertex);
1631 
1632 #ifdef WITH_CXX_GUARDEDALLOC
1633   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewShape")
1634 #endif
1635 };
1636 
1637 /*
1638  * #############################################
1639  * #############################################
1640  * #############################################
1641  * ######                                 ######
1642  * ######   I M P L E M E N T A T I O N   ######
1643  * ######                                 ######
1644  * #############################################
1645  * #############################################
1646  * #############################################
1647  */
1648 /* for inline functions */
1649 
SplitEdge(FEdge * fe,const vector<TVertex * > & iViewVertices,vector<FEdge * > & ioNewEdges,vector<ViewEdge * > & ioNewViewEdges)1650 void ViewShape::SplitEdge(FEdge *fe,
1651                           const vector<TVertex *> &iViewVertices,
1652                           vector<FEdge *> &ioNewEdges,
1653                           vector<ViewEdge *> &ioNewViewEdges)
1654 {
1655   ViewEdge *vEdge = fe->viewedge();
1656 
1657   // We first need to sort the view vertices from farther to closer to fe->vertexA
1658   SVertex *sv, *sv2;
1659   ViewVertex *vva, *vvb;
1660   vector<TVertex *>::const_iterator vv, vvend;
1661   for (vv = iViewVertices.begin(), vvend = iViewVertices.end(); vv != vvend; vv++) {
1662     // Add the viewvertices to the ViewShape
1663     AddVertex((*vv));
1664 
1665     // retrieve the correct SVertex from the view vertex
1666     //--------------------------------------------------
1667     sv = (*vv)->frontSVertex();
1668     sv2 = (*vv)->backSVertex();
1669 
1670     if (sv->shape() != sv2->shape()) {
1671       if (sv->shape() != _SShape) {
1672         sv = sv2;
1673       }
1674     }
1675     else {
1676       // if the shape is the same we can safely differ the two vertices using their ids:
1677       if (sv->getId() != fe->vertexA()->getId()) {
1678         sv = sv2;
1679       }
1680     }
1681 
1682     vva = vEdge->A();
1683     vvb = vEdge->B();
1684 
1685     // We split Fedge AB into AA' and A'B. A' and A'B are created.
1686     // AB becomes (address speaking) AA'. B is updated.
1687     //--------------------------------------------------
1688     SShape *shape = fe->shape();
1689 
1690     // a new edge, A'B is created.
1691     FEdge *newEdge = shape->SplitEdgeIn2(fe, sv);
1692     /* One of the two FEdges (fe and newEdge) may have a 2D length less than M_EPSILON.
1693      * (22 Feb 2011, T.K.)
1694      */
1695 
1696     ioNewEdges.push_back(newEdge);
1697     ViewEdge *newVEdge;
1698 
1699     if ((vva == 0) || (vvb == 0)) {  // that means we're dealing with a closed viewedge (loop)
1700       // remove the chain that was starting by the fedge A of vEdge (which is different from fe
1701       // !!!!)
1702       shape->RemoveEdgeFromChain(vEdge->fedgeA());
1703       // we set
1704       vEdge->setA(*vv);
1705       vEdge->setB(*vv);
1706       vEdge->setFEdgeA(newEdge);
1707       // FEdge *previousEdge = newEdge->previousEdge();
1708       vEdge->setFEdgeB(fe);
1709       newVEdge = vEdge;
1710       vEdge->fedgeA()->setViewEdge(newVEdge);
1711     }
1712     else {
1713       // while we create the view edge, it updates the "ViewEdge" pointer of every underlying
1714       // FEdges to this.
1715       newVEdge = new ViewEdge((*vv), vvb);  //, newEdge, vEdge->fedgeB());
1716       newVEdge->setNature((fe)->getNature());
1717       newVEdge->setFEdgeA(newEdge);
1718       // newVEdge->setFEdgeB(fe);
1719       // If our original viewedge is made of one FEdge, then
1720       if ((vEdge->fedgeA() == vEdge->fedgeB()) || (fe == vEdge->fedgeB())) {
1721         newVEdge->setFEdgeB(newEdge);
1722       }
1723       else {
1724         newVEdge->setFEdgeB(vEdge->fedgeB());  // MODIF
1725       }
1726 
1727       Id *newId = vEdge->splittingId();
1728       if (newId == 0) {
1729         newId = new Id(vEdge->getId());
1730         vEdge->setSplittingId(newId);
1731       }
1732       newId->setSecond(newId->getSecond() + 1);
1733       newVEdge->setId(*newId);
1734       newVEdge->setSplittingId(newId);
1735 #if 0
1736       Id id(vEdge->getId().getFirst(), vEdge->getId().getSecond() + 1);
1737       newVEdge->setId(vEdge->getId());
1738       vEdge->setId(id);
1739 #endif
1740 
1741       AddEdge(newVEdge);  // here this shape is set as the edge's shape
1742 
1743       // add new edge to the list of new edges passed as argument:
1744       ioNewViewEdges.push_back(newVEdge);
1745 
1746       if (0 != vvb) {
1747         vvb->Replace((vEdge), newVEdge);
1748       }
1749 
1750       // we split the view edge:
1751       vEdge->setB((*vv));
1752       vEdge->setFEdgeB(fe);  // MODIF
1753 
1754       // Update fedges so that they point to the new viewedge:
1755       newVEdge->UpdateFEdges();
1756     }
1757     // check whether this vertex is a front vertex or a back one
1758     if (sv == (*vv)->frontSVertex()) {
1759       // -- View Vertex A' --
1760       (*vv)->setFrontEdgeA(vEdge, true);
1761       (*vv)->setFrontEdgeB(newVEdge, false);
1762     }
1763     else {
1764       // -- View Vertex A' --
1765       (*vv)->setBackEdgeA(vEdge, true);
1766       (*vv)->setBackEdgeB(newVEdge, false);
1767     }
1768   }
1769 }
1770 
1771 /**********************************/
1772 /*                                */
1773 /*                                */
1774 /*             ViewEdge           */
1775 /*                                */
1776 /*                                */
1777 /**********************************/
1778 
1779 #if 0
1780 inline Vec3r ViewEdge::orientation2d(int iCombination) const
1781 {
1782   return edge_orientation2d_function<ViewEdge>(*this, iCombination);
1783 }
1784 
1785 inline Vec3r ViewEdge::orientation3d(int iCombination) const
1786 {
1787   return edge_orientation3d_function<ViewEdge>(*this, iCombination);
1788 }
1789 
1790 inline real ViewEdge::z_discontinuity(int iCombination) const
1791 {
1792   return z_discontinuity_edge_function<ViewEdge>(*this, iCombination);
1793 }
1794 
1795 inline float ViewEdge::local_average_depth(int iCombination) const
1796 {
1797   return local_average_depth_edge_function<ViewEdge>(*this, iCombination);
1798 }
1799 
1800 inline float ViewEdge::local_depth_variance(int iCombination) const
1801 {
1802   return local_depth_variance_edge_function<ViewEdge>(*this, iCombination);
1803 }
1804 
1805 inline real ViewEdge::local_average_density(float sigma, int iCombination) const
1806 {
1807   return density_edge_function<ViewEdge>(*this, iCombination);
1808 }
1809 #endif
1810 
occluded_shape()1811 inline const SShape *ViewEdge::occluded_shape() const
1812 {
1813   if (0 == _aShape) {
1814     return 0;
1815   }
1816   return _aShape->sshape();
1817 }
1818 
1819 #if 0
1820 inline Vec3r ViewEdge::curvature2d_as_vector(int iCombination) const
1821 {
1822   return curvature2d_as_vector_edge_function<ViewEdge>(*this, iCombination);
1823 }
1824 
1825 inline real ViewEdge::curvature2d_as_angle(int iCombination) const
1826 {
1827   return curvature2d_as_angle_edge_function<ViewEdge>(*this, iCombination);
1828 }
1829 #endif
1830 
1831 } /* namespace Freestyle */
1832