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