Blender  V3.3
Silhouette.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
10 #include <float.h>
11 #include <iostream>
12 #include <set>
13 #include <string>
14 #include <vector>
15 
16 #include "Interface0D.h"
17 #include "Interface1D.h"
18 
19 #include "../geometry/BBox.h"
20 #include "../geometry/Geom.h"
21 #include "../geometry/Polygon.h"
22 
23 #include "../scene_graph/FrsMaterial.h"
24 
25 #include "../system/Exception.h"
26 #include "../system/FreestyleConfig.h"
27 
28 #include "../winged_edge/Curvature.h"
29 
30 #ifdef WITH_CXX_GUARDEDALLOC
31 # include "MEM_guardedalloc.h"
32 #endif
33 
34 using namespace std;
35 
36 namespace Freestyle {
37 
38 using namespace Geometry;
39 
40 class ViewShape;
41 typedef vector<ViewShape *> occluder_container;
42 
43 /**********************************/
44 /* */
45 /* */
46 /* SVertex */
47 /* */
48 /* */
49 /**********************************/
50 
51 class FEdge;
52 class ViewVertex;
53 class SShape;
54 
56 class SVertex : public Interface0D {
57  public: // Implementation of Interface0D
59  virtual string getExactTypeName() const
60  {
61  return "SVertex";
62  }
63 
64  // Data access methods
66  virtual real getX() const
67  {
68  return _Point3D.x();
69  }
70 
72  virtual real getY() const
73  {
74  return _Point3D.y();
75  }
76 
78  virtual real getZ() const
79  {
80  return _Point3D.z();
81  }
82 
84  virtual Vec3r getPoint3D() const
85  {
86  return _Point3D;
87  }
88 
90  virtual real getProjectedX() const
91  {
92  return _Point2D.x();
93  }
94 
96  virtual real getProjectedY() const
97  {
98  return _Point2D.y();
99  }
100 
102  virtual real getProjectedZ() const
103  {
104  return _Point2D.z();
105  }
106 
108  virtual Vec2r getPoint2D() const
109  {
110  return Vec2r(_Point2D.x(), _Point2D.y());
111  }
112 
114  virtual FEdge *getFEdge(Interface0D &);
115 
117  virtual Id getId() const
118  {
119  return _Id;
120  }
121 
123  virtual Nature::VertexNature getNature() const;
124 
126  virtual SVertex *castToSVertex();
127 
129  virtual ViewVertex *castToViewVertex();
130 
132  virtual NonTVertex *castToNonTVertex();
133 
135  virtual TVertex *castToTVertex();
136 
137  public:
138  typedef vector<FEdge *> fedges_container;
139 
140  private:
141  Id _Id;
142  Vec3r _Point3D;
143  Vec3r _Point2D;
144  set<Vec3r> _Normals;
145  vector<FEdge *> _FEdges; // the edges containing this vertex
146  SShape *_Shape; // the shape to which belongs the vertex
147  ViewVertex *_pViewVertex; // The associated viewvertex, in case there is one.
148 #if 0
149  real _curvatureFredo;
150  Vec2r _directionFredo;
151 #endif
152  CurvatureInfo *_curvature_info;
153 
154  public:
158  void *userdata;
159 
161  inline SVertex()
162  {
163  _Id = 0;
164  userdata = NULL;
165  _Shape = NULL;
166  _pViewVertex = 0;
167  _curvature_info = 0;
168  }
169 
171  inline SVertex(const Vec3r &iPoint3D, const Id &id)
172  {
173  _Point3D = iPoint3D;
174  _Id = id;
175  userdata = NULL;
176  _Shape = NULL;
177  _pViewVertex = 0;
178  _curvature_info = 0;
179  }
180 
182  inline SVertex(SVertex &iBrother)
183  {
184  _Id = iBrother._Id;
185  _Point3D = iBrother.point3D();
186  _Point2D = iBrother.point2D();
187  _Normals = iBrother._Normals;
188  _FEdges = iBrother.fedges();
189  _Shape = iBrother.shape();
190  _pViewVertex = iBrother._pViewVertex;
191  if (!(iBrother._curvature_info)) {
192  _curvature_info = 0;
193  }
194  else {
195  _curvature_info = new CurvatureInfo(*(iBrother._curvature_info));
196  }
197  iBrother.userdata = this;
198  userdata = 0;
199  }
200 
202  virtual ~SVertex()
203  {
204  if (_curvature_info) {
205  delete _curvature_info;
206  }
207  }
208 
210  virtual SVertex *duplicate()
211  {
212  SVertex *clone = new SVertex(*this);
213  return clone;
214  }
215 
217  virtual bool operator==(const SVertex &iBrother)
218  {
219  return ((_Point2D == iBrother._Point2D) && (_Point3D == iBrother._Point3D));
220  }
221 
222  /* accessors */
223  inline const Vec3r &point3D() const
224  {
225  return _Point3D;
226  }
227 
228  inline const Vec3r &point2D() const
229  {
230  return _Point2D;
231  }
232 
237  inline set<Vec3r> normals()
238  {
239  return _Normals;
240  }
241 
243  inline unsigned normalsSize() const
244  {
245  return _Normals.size();
246  }
247 
248  inline const vector<FEdge *> &fedges()
249  {
250  return _FEdges;
251  }
252 
253  inline fedges_container::iterator fedges_begin()
254  {
255  return _FEdges.begin();
256  }
257 
258  inline fedges_container::iterator fedges_end()
259  {
260  return _FEdges.end();
261  }
262 
263  inline SShape *shape()
264  {
265  return _Shape;
266  }
267 
268  inline real z() const
269  {
270  return _Point2D[2];
271  }
272 
277  {
278  return _pViewVertex;
279  }
280 
283  inline void setPoint3D(const Vec3r &iPoint3D)
284  {
285  _Point3D = iPoint3D;
286  }
287 
289  inline void setPoint2D(const Vec3r &iPoint2D)
290  {
291  _Point2D = iPoint2D;
292  }
293 
296  inline void AddNormal(const Vec3r &iNormal)
297  {
298  _Normals.insert(iNormal); // if iNormal in the set already exists, nothing is done
299  }
300 
302  {
303  if (_curvature_info) { // Q. is this an error condition? (T.K. 02-May-2011)
304  delete _curvature_info;
305  }
306  _curvature_info = ci;
307  }
308 
310  {
311  return _curvature_info;
312  }
313 
314 #if 0
315  /* Fredo's normal and curvature. */
316  void setCurvatureFredo(real c)
317  {
318  _curvatureFredo = c;
319  }
320 
321  void setDirectionFredo(Vec2r d)
322  {
323  _directionFredo = d;
324  }
325 
326  real curvatureFredo()
327  {
328  return _curvatureFredo;
329  }
330 
331  const Vec2r directionFredo()
332  {
333  return _directionFredo;
334  }
335 #endif
336 
338  inline void setId(const Id &id)
339  {
340  _Id = id;
341  }
342 
343  inline void setFEdges(const vector<FEdge *> &iFEdges)
344  {
345  _FEdges = iFEdges;
346  }
347 
348  inline void setShape(SShape *iShape)
349  {
350  _Shape = iShape;
351  }
352 
353  inline void setViewVertex(ViewVertex *iViewVertex)
354  {
355  _pViewVertex = iViewVertex;
356  }
357 
359  inline void AddFEdge(FEdge *iFEdge)
360  {
361  _FEdges.push_back(iFEdge);
362  }
363 
365  inline void RemoveFEdge(FEdge *iFEdge)
366  {
367  for (vector<FEdge *>::iterator fe = _FEdges.begin(), fend = _FEdges.end(); fe != fend; fe++) {
368  if (iFEdge == (*fe)) {
369  _FEdges.erase(fe);
370  break;
371  }
372  }
373  }
374 
375  /* replaces edge 1 by edge 2 in the list of edges */
376  inline void Replace(FEdge *e1, FEdge *e2)
377  {
378  vector<FEdge *>::iterator insertedfe;
379  for (vector<FEdge *>::iterator fe = _FEdges.begin(), fend = _FEdges.end(); fe != fend; fe++) {
380  if ((*fe) == e1) {
381  insertedfe = _FEdges.insert(fe, e2); // inserts e2 before fe.
382  // returns an iterator pointing toward e2. fe is invalidated.
383  // we want to remove e1, but we can't use fe anymore:
384  ++insertedfe; // insertedfe points now to e1
385  _FEdges.erase(insertedfe);
386  return;
387  }
388  }
389  }
390 
391  public:
392  /* Information access interface */
393  FEdge *fedge(); // for non T vertex
394 
395  inline const Vec3r &point2d() const
396  {
397  return point2D();
398  }
399 
400  inline const Vec3r &point3d() const
401  {
402  return point3D();
403  }
404 
405  inline Vec3r normal() const
406  {
407  if (_Normals.size() == 1) {
408  return (*(_Normals.begin()));
409  }
410  Exception::raiseException();
411  return *(_Normals.begin());
412  }
413 
414  // Material material() const ;
415  Id shape_id() const;
416  const SShape *shape() const;
417  float shape_importance() const;
418 
419  int qi() const;
420  occluder_container::const_iterator occluders_begin() const;
421  occluder_container::const_iterator occluders_end() const;
422  bool occluders_empty() const;
423  int occluders_size() const;
424  const Polygon3r &occludee() const;
425  const SShape *occluded_shape() const;
426  bool occludee_empty() const;
427  real z_discontinuity() const;
428 #if 0
429  inline float local_average_depth() const;
430  inline float local_depth_variance() const;
431  inline real local_average_density(float sigma = 2.3f) const;
432  inline Vec3r shaded_color() const;
433  inline Vec3r orientation2d() const;
434  inline Vec3r orientation3d() const;
435  inline Vec3r curvature2d_as_vector() const;
437  inline real curvature2d_as_angle() const;
438 #endif
439 
440 #ifdef WITH_CXX_GUARDEDALLOC
441  MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SVertex")
442 #endif
443 };
444 
445 /**********************************/
446 /* */
447 /* */
448 /* FEdge */
449 /* */
450 /* */
451 /**********************************/
452 
453 class ViewEdge;
454 
463 class FEdge : public Interface1D {
464  public: // Implementation of Interface0D
466  virtual string getExactTypeName() const
467  {
468  return "FEdge";
469  }
470 
471  // Data access methods
472 
474  virtual real getLength2D() const
475  {
476  if (!_VertexA || !_VertexB) {
477  return 0;
478  }
479  return (_VertexB->getPoint2D() - _VertexA->getPoint2D()).norm();
480  }
481 
483  virtual Id getId() const
484  {
485  return _Id;
486  }
487 
488  public:
489  // An edge can only be of one kind (SILHOUETTE or BORDER, etc...)
490  // For an multi-nature edge there must be several different FEdge.
491  // DEBUG:
492  // Vec3r A;
493  // Vec3r u;
494  // vector<Polygon3r> _Occludees;
495  // Vec3r intersection;
496  // vector<Vec3i> _Cells;
497 
498  protected:
503  // vector<Polygon3r> _Occluders; // visibility // NOT HANDLED BY THE COPY CONSTRUCTOR!!
504 
505  FEdge *_NextEdge; // next edge on the chain
508  // Sometimes we need to deport the visibility computation onto another edge. For example the
509  // exact edges use edges of the mesh to compute their visibility
510 
511  Polygon3r _aFace; // The occluded face which lies on the right of a silhouette edge
514 
515  bool _isSmooth;
516 
518 
520 
521  public:
525  void *userdata;
526 
528  inline FEdge()
529  {
530  userdata = NULL;
531  _VertexA = NULL;
532  _VertexB = NULL;
533  _Nature = Nature::NO_FEATURE;
534  _NextEdge = NULL;
535  _PreviousEdge = NULL;
536  _ViewEdge = NULL;
537  //_hasVisibilityPoint = false;
538  _occludeeEmpty = true;
539  _isSmooth = false;
540  _isInImage = true;
541  _isTemporary = false;
542  }
543 
545  inline FEdge(SVertex *vA, SVertex *vB)
546  {
547  userdata = NULL;
548  _VertexA = vA;
549  _VertexB = vB;
550  _Nature = Nature::NO_FEATURE;
551  _NextEdge = NULL;
552  _PreviousEdge = NULL;
553  _ViewEdge = NULL;
554  //_hasVisibilityPoint = false;
555  _occludeeEmpty = true;
556  _isSmooth = false;
557  _isInImage = true;
558  _isTemporary = false;
559  }
560 
562  inline FEdge(FEdge &iBrother)
563  {
564  _VertexA = iBrother.vertexA();
565  _VertexB = iBrother.vertexB();
566  _NextEdge = iBrother.nextEdge();
567  _PreviousEdge = iBrother._PreviousEdge;
568  _Nature = iBrother.getNature();
569  _Id = iBrother._Id;
570  _ViewEdge = iBrother._ViewEdge;
571  //_hasVisibilityPoint = iBrother._hasVisibilityPoint;
572  //_VisibilityPointA = iBrother._VisibilityPointA;
573  //_VisibilityPointB = iBrother._VisibilityPointB;
574  _aFace = iBrother._aFace;
575  _occludeeEmpty = iBrother._occludeeEmpty;
576  _isSmooth = iBrother._isSmooth;
577  _isInImage = iBrother._isInImage;
578  _isTemporary = iBrother._isTemporary;
579  iBrother.userdata = this;
580  userdata = 0;
581  }
582 
584  virtual ~FEdge()
585  {
586  }
587 
589  virtual FEdge *duplicate()
590  {
591  FEdge *clone = new FEdge(*this);
592  return clone;
593  }
594 
595  /* accessors */
597  inline SVertex *vertexA()
598  {
599  return _VertexA;
600  }
601 
603  inline SVertex *vertexB()
604  {
605  return _VertexB;
606  }
607 
609  inline SVertex *operator[](const unsigned short int &i) const
610  {
611  return (i % 2 == 0) ? _VertexA : _VertexB;
612  }
613 
616  {
617  return _Nature;
618  }
619 
623  inline FEdge *nextEdge()
624  {
625  return _NextEdge;
626  }
627 
631  inline FEdge *previousEdge()
632  {
633  return _PreviousEdge;
634  }
635 
636  inline SShape *shape()
637  {
638  return _VertexA->shape();
639  }
640 
641 #if 0
642  inline int invisibility() const
643  {
644  return _Occluders.size();
645  }
646 #endif
647 
648  int invisibility() const;
649 
650 #if 0
651  inline const vector<Polygon3r> &occluders() const
652  {
653  return _Occluders;
654  }
655 #endif
656 
658  inline ViewEdge *viewedge() const
659  {
660  return _ViewEdge;
661  }
662 
663  inline Vec3r center3d()
664  {
665  return Vec3r((_VertexA->point3D() + _VertexB->point3D()) / 2.0);
666  }
667 
668  inline Vec3r center2d()
669  {
670  return Vec3r((_VertexA->point2D() + _VertexB->point2D()) / 2.0);
671  }
672 
673 #if 0
674  inline bool hasVisibilityPoint() const
675  {
676  return _hasVisibilityPoint;
677  }
678 
679  inline Vec3r visibilityPointA() const
680  {
681  return _VisibilityPointA;
682  }
683 
684  inline Vec3r visibilityPointB() const
685  {
686  return _VisibilityPointB;
687  }
688 #endif
689 
690  inline const Polygon3r &aFace() const
691  {
692  return _aFace;
693  }
694 
696  {
697  return _occludeeIntersection;
698  }
699 
700  inline bool getOccludeeEmpty()
701  {
702  return _occludeeEmpty;
703  }
704 
706  inline bool isSmooth() const
707  {
708  return _isSmooth;
709  }
710 
711  inline bool isInImage() const
712  {
713  return _isInImage;
714  }
715 
716  inline bool isTemporary() const
717  {
718  return _isTemporary;
719  }
720 
721  /* modifiers */
723  inline void setVertexA(SVertex *vA)
724  {
725  _VertexA = vA;
726  }
727 
729  inline void setVertexB(SVertex *vB)
730  {
731  _VertexB = vB;
732  }
733 
735  inline void setId(const Id &id)
736  {
737  _Id = id;
738  }
739 
741  inline void setNextEdge(FEdge *iEdge)
742  {
743  _NextEdge = iEdge;
744  }
745 
747  inline void setPreviousEdge(FEdge *iEdge)
748  {
749  _PreviousEdge = iEdge;
750  }
751 
753  inline void setNature(Nature::EdgeNature iNature)
754  {
755  _Nature = iNature;
756  }
757 
758 #if 0
759  inline void AddOccluder(Polygon3r &iPolygon)
760  {
761  _Occluders.push_back(iPolygon);
762  }
763 #endif
764 
766  inline void setViewEdge(ViewEdge *iViewEdge)
767  {
768  _ViewEdge = iViewEdge;
769  }
770 
771 #if 0
772  inline void setHasVisibilityPoint(bool iBool)
773  {
774  _hasVisibilityPoint = iBool;
775  }
776 
777  inline void setVisibilityPointA(const Vec3r &iPoint)
778  {
779  _VisibilityPointA = iPoint;
780  }
781 
782  inline void setVisibilityPointB(const Vec3r &iPoint)
783  {
784  _VisibilityPointB = iPoint;
785  }
786 #endif
787 
788  inline void setaFace(Polygon3r &iFace)
789  {
790  _aFace = iFace;
791  }
792 
793  inline void setOccludeeIntersection(const Vec3r &iPoint)
794  {
795  _occludeeIntersection = iPoint;
796  }
797 
798  inline void setOccludeeEmpty(bool iempty)
799  {
800  _occludeeEmpty = iempty;
801  }
802 
806  inline void setSmooth(bool iFlag)
807  {
808  _isSmooth = iFlag;
809  }
810 
811  inline void setIsInImage(bool iFlag)
812  {
813  _isInImage = iFlag;
814  }
815 
816  inline void setTemporary(bool iFlag)
817  {
818  _isTemporary = iFlag;
819  }
820 
821  /* checks whether two FEdge have a common vertex.
822  * Returns a pointer on the common vertex if it exists, NULL otherwise.
823  */
824  static inline SVertex *CommonVertex(FEdge *iEdge1, FEdge *iEdge2)
825  {
826  if ((NULL == iEdge1) || (NULL == iEdge2)) {
827  return NULL;
828  }
829 
830  SVertex *sv1 = iEdge1->vertexA();
831  SVertex *sv2 = iEdge1->vertexB();
832  SVertex *sv3 = iEdge2->vertexA();
833  SVertex *sv4 = iEdge2->vertexB();
834 
835  if ((sv1 == sv3) || (sv1 == sv4)) {
836  return sv1;
837  }
838  else if ((sv2 == sv3) || (sv2 == sv4)) {
839  return sv2;
840  }
841 
842  return NULL;
843  }
844 
845  inline const SVertex *min2d() const
846  {
847  if (_VertexA->point2D() < _VertexB->point2D()) {
848  return _VertexA;
849  }
850  else {
851  return _VertexB;
852  }
853  }
854 
855  inline const SVertex *max2d() const
856  {
857  if (_VertexA->point2D() < _VertexB->point2D()) {
858  return _VertexB;
859  }
860  else {
861  return _VertexA;
862  }
863  }
864 
865  /* Information access interface */
866 
867  // Material material() const;
868  Id shape_id() const;
869  const SShape *shape() const;
870  float shape_importance() const;
871 
872  inline const int qi() const
873  {
874  return invisibility();
875  }
876 
877  occluder_container::const_iterator occluders_begin() const;
878  occluder_container::const_iterator occluders_end() const;
879  bool occluders_empty() const;
880  int occluders_size() const;
881 
882  inline const Polygon3r &occludee() const
883  {
884  return aFace();
885  }
886 
887  const SShape *occluded_shape() const;
888 
889 #if 0
890  inline const bool occludee_empty() const
891  {
892  return _occludeeEmpty;
893  }
894 #endif
895 
896  bool occludee_empty() const;
897  real z_discontinuity() const;
898 
899 #if 0
900  inline float local_average_depth(int iCombination = 0) const;
901  inline float local_depth_variance(int iCombination = 0) const;
902  inline real local_average_density(float sigma = 2.3f, int iCombination = 0) const;
903  inline Vec3r shaded_color(int iCombination = 0) const
904  {
905  }
906 #endif
907 
908  int viewedge_nature() const;
909 
910  // float viewedge_length() const;
911 
912  inline Vec3r orientation2d() const
913  {
914  return Vec3r(_VertexB->point2d() - _VertexA->point2d());
915  }
916 
917  inline Vec3r orientation3d() const
918  {
919  return Vec3r(_VertexB->point3d() - _VertexA->point3d());
920  }
921 
922 #if 0
923  inline real curvature2d() const
924  {
925  return viewedge()->curvature2d((_VertexA->point2d() + _VertexB->point2d()) / 2.0);
926  }
927 
928  inline Vec3r curvature2d_as_vector(int iCombination = 0) const;
929 
930  /* Angle in degrees. */
931  inline real curvature2d_as_angle(int iCombination = 0) const;
932 #endif
933 
934  // Iterator access (Interface1D)
936  virtual inline Interface0DIterator verticesBegin();
937 
939  virtual inline Interface0DIterator verticesEnd();
940 
947  virtual inline Interface0DIterator pointsBegin(float t = 0.0f);
948 
955  virtual inline Interface0DIterator pointsEnd(float t = 0.0f);
956 
957 #ifdef WITH_CXX_GUARDEDALLOC
958  MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdge")
959 #endif
960 };
961 
962 //
963 // SVertexIterator
964 //
966 
967 namespace FEdgeInternal {
968 
970  public:
972  {
973  _vertex = NULL;
974  _edge = NULL;
975  }
976 
978  {
979  _vertex = vi._vertex;
980  _edge = vi._edge;
981  }
982 
984  {
985  _vertex = v;
986  _edge = edge;
987  }
988 
990  {
991  _vertex = vi._vertex;
992  _edge = vi._edge;
993  return *this;
994  }
995 
996  virtual string getExactTypeName() const
997  {
998  return "SVertexIterator";
999  }
1000 
1001  virtual SVertex &operator*()
1002  {
1003  return *_vertex;
1004  }
1005 
1006  virtual SVertex *operator->()
1007  {
1008  return &(operator*());
1009  }
1010 
1012  {
1013  increment();
1014  return *this;
1015  }
1016 
1018  {
1019  SVertexIterator ret(*this);
1020  increment();
1021  return ret;
1022  }
1023 
1025  {
1026  decrement();
1027  return *this;
1028  }
1029 
1031  {
1032  SVertexIterator ret(*this);
1033  decrement();
1034  return ret;
1035  }
1036 
1037  virtual int increment()
1038  {
1039  if (_vertex == _edge->vertexB()) {
1040  _vertex = 0;
1041  return 0;
1042  }
1043  _vertex = _edge->vertexB();
1044  return 0;
1045  }
1046 
1047  virtual int decrement()
1048  {
1049  if (_vertex == _edge->vertexA()) {
1050  _vertex = 0;
1051  return 0;
1052  }
1053  _vertex = _edge->vertexA();
1054  return 0;
1055  }
1056 
1057  virtual bool isBegin() const
1058  {
1059  return _vertex == _edge->vertexA();
1060  }
1061 
1062  virtual bool isEnd() const
1063  {
1064  return _vertex == _edge->vertexB();
1065  }
1066 
1067  virtual bool operator==(const Interface0DIteratorNested &it) const
1068  {
1069  const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator *>(&it);
1070  if (!it_exact) {
1071  return false;
1072  }
1073  return ((_vertex == it_exact->_vertex) && (_edge == it_exact->_edge));
1074  }
1075 
1076  virtual float t() const
1077  {
1078  if (_vertex == _edge->vertexA()) {
1079  return 0.0f;
1080  }
1081  return ((float)_edge->getLength2D());
1082  }
1083  virtual float u() const
1084  {
1085  if (_vertex == _edge->vertexA()) {
1086  return 0.0f;
1087  }
1088  return 1.0f;
1089  }
1090 
1091  virtual SVertexIterator *copy() const
1092  {
1093  return new SVertexIterator(*this);
1094  }
1095 
1096  private:
1097  SVertex *_vertex;
1098  FEdge *_edge;
1099 };
1100 
1101 } // end of namespace FEdgeInternal
1102 
1103 // Iterator access (implementation)
1104 
1105 Interface0DIterator FEdge::verticesBegin()
1106 {
1108  return ret;
1109 }
1110 
1111 Interface0DIterator FEdge::verticesEnd()
1112 {
1114  return ret;
1115 }
1116 
1117 Interface0DIterator FEdge::pointsBegin(float /*t*/)
1118 {
1119  return verticesBegin();
1120 }
1121 
1122 Interface0DIterator FEdge::pointsEnd(float /*t*/)
1123 {
1124  return verticesEnd();
1125 }
1126 
1132 class FEdgeSharp : public FEdge {
1133  protected:
1134  Vec3r _aNormal; // When following the edge, normal of the right face
1135  Vec3r _bNormal; // When following the edge, normal of the left face
1140 
1141  public:
1143  virtual string getExactTypeName() const
1144  {
1145  return "FEdgeSharp";
1146  }
1147 
1149  inline FEdgeSharp() : FEdge()
1150  {
1151  _aFrsMaterialIndex = _bFrsMaterialIndex = 0;
1152  _aFaceMark = _bFaceMark = false;
1153  }
1154 
1156  inline FEdgeSharp(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
1157  {
1158  _aFrsMaterialIndex = _bFrsMaterialIndex = 0;
1159  _aFaceMark = _bFaceMark = false;
1160  }
1161 
1163  inline FEdgeSharp(FEdgeSharp &iBrother) : FEdge(iBrother)
1164  {
1165  _aNormal = iBrother._aNormal;
1166  _bNormal = iBrother._bNormal;
1167  _aFrsMaterialIndex = iBrother._aFrsMaterialIndex;
1168  _bFrsMaterialIndex = iBrother._bFrsMaterialIndex;
1169  _aFaceMark = iBrother._aFaceMark;
1170  _bFaceMark = iBrother._bFaceMark;
1171  }
1172 
1174  virtual ~FEdgeSharp()
1175  {
1176  }
1177 
1179  virtual FEdge *duplicate()
1180  {
1181  FEdge *clone = new FEdgeSharp(*this);
1182  return clone;
1183  }
1184 
1188  inline const Vec3r &normalA()
1189  {
1190  return _aNormal;
1191  }
1192 
1194  inline const Vec3r &normalB()
1195  {
1196  return _bNormal;
1197  }
1198 
1203  inline unsigned aFrsMaterialIndex() const
1204  {
1205  return _aFrsMaterialIndex;
1206  }
1207 
1211  const FrsMaterial &aFrsMaterial() const;
1212 
1214  inline unsigned bFrsMaterialIndex() const
1215  {
1216  return _bFrsMaterialIndex;
1217  }
1218 
1220  const FrsMaterial &bFrsMaterial() const;
1221 
1225  inline bool aFaceMark() const
1226  {
1227  return _aFaceMark;
1228  }
1229 
1231  inline bool bFaceMark() const
1232  {
1233  return _bFaceMark;
1234  }
1235 
1237  inline void setNormalA(const Vec3r &iNormal)
1238  {
1239  _aNormal = iNormal;
1240  }
1241 
1243  inline void setNormalB(const Vec3r &iNormal)
1244  {
1245  _bNormal = iNormal;
1246  }
1247 
1249  inline void setaFrsMaterialIndex(unsigned i)
1250  {
1251  _aFrsMaterialIndex = i;
1252  }
1253 
1255  inline void setbFrsMaterialIndex(unsigned i)
1256  {
1257  _bFrsMaterialIndex = i;
1258  }
1259 
1261  inline void setaFaceMark(bool iFaceMark)
1262  {
1263  _aFaceMark = iFaceMark;
1264  }
1265 
1267  inline void setbFaceMark(bool iFaceMark)
1268  {
1269  _bFaceMark = iFaceMark;
1270  }
1271 
1272 #ifdef WITH_CXX_GUARDEDALLOC
1273  MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeSharp")
1274 #endif
1275 };
1276 
1280 class FEdgeSmooth : public FEdge {
1281  protected:
1284 #if 0
1285  bool _hasVisibilityPoint;
1286  Vec3r _VisibilityPointA; // The edge on which the visibility will be computed represented
1287  Vec3r _VisibilityPointB; // using its 2 extremity points A and B
1288 #endif
1289  void *_Face; // In case of exact silhouette, Face is the WFace crossed by Fedge
1290  // NOT HANDLED BY THE COPY CONSTRUCTEUR
1292 
1293  public:
1295  virtual string getExactTypeName() const
1296  {
1297  return "FEdgeSmooth";
1298  }
1299 
1301  inline FEdgeSmooth() : FEdge()
1302  {
1303  _Face = NULL;
1304  _FaceMark = false;
1305  _FrsMaterialIndex = 0;
1306  _isSmooth = true;
1307  }
1308 
1310  inline FEdgeSmooth(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
1311  {
1312  _Face = NULL;
1313  _FaceMark = false;
1314  _FrsMaterialIndex = 0;
1315  _isSmooth = true;
1316  }
1317 
1319  inline FEdgeSmooth(FEdgeSmooth &iBrother) : FEdge(iBrother)
1320  {
1321  _Normal = iBrother._Normal;
1322  _Face = iBrother._Face;
1323  _FaceMark = iBrother._FaceMark;
1324  _FrsMaterialIndex = iBrother._FrsMaterialIndex;
1325  _isSmooth = true;
1326  }
1327 
1329  virtual ~FEdgeSmooth()
1330  {
1331  }
1332 
1334  virtual FEdge *duplicate()
1335  {
1336  FEdge *clone = new FEdgeSmooth(*this);
1337  return clone;
1338  }
1339 
1340  inline void *face() const
1341  {
1342  return _Face;
1343  }
1344 
1346  inline bool faceMark() const
1347  {
1348  return _FaceMark;
1349  }
1350 
1352  inline const Vec3r &normal()
1353  {
1354  return _Normal;
1355  }
1356 
1358  inline unsigned frs_materialIndex() const
1359  {
1360  return _FrsMaterialIndex;
1361  }
1362 
1364  const FrsMaterial &frs_material() const;
1365 
1366  inline void setFace(void *iFace)
1367  {
1368  _Face = iFace;
1369  }
1370 
1372  inline void setFaceMark(bool iFaceMark)
1373  {
1374  _FaceMark = iFaceMark;
1375  }
1376 
1378  inline void setNormal(const Vec3r &iNormal)
1379  {
1380  _Normal = iNormal;
1381  }
1382 
1384  inline void setFrsMaterialIndex(unsigned i)
1385  {
1386  _FrsMaterialIndex = i;
1387  }
1388 
1389 #ifdef WITH_CXX_GUARDEDALLOC
1390  MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeSmooth")
1391 #endif
1392 };
1393 
1394 /**********************************/
1395 /* */
1396 /* */
1397 /* SShape */
1398 /* */
1399 /* */
1400 /**********************************/
1401 
1404 class SShape {
1405  private:
1406  vector<FEdge *> _chains; // list of fedges that are chains starting points.
1407  vector<SVertex *> _verticesList; // list of all vertices
1408  vector<FEdge *> _edgesList; // list of all edges
1409  Id _Id;
1410  string _Name;
1411  string _LibraryPath;
1412  BBox<Vec3r> _BBox;
1413  vector<FrsMaterial> _FrsMaterials;
1414 
1415  float _importance;
1416 
1417  ViewShape *_ViewShape;
1418 
1419  public:
1423  void *userdata; // added by E.T.
1424 
1426  inline SShape()
1427  {
1428  userdata = NULL;
1429  _importance = 0.0f;
1430  _ViewShape = NULL;
1431  }
1432 
1434  inline SShape(SShape &iBrother)
1435  {
1436  userdata = NULL;
1437  _Id = iBrother._Id;
1438  _Name = iBrother._Name;
1439  _LibraryPath = iBrother._LibraryPath;
1440  _BBox = iBrother.bbox();
1441  _FrsMaterials = iBrother._FrsMaterials;
1442  _importance = iBrother._importance;
1443  _ViewShape = iBrother._ViewShape;
1444 
1445  //---------
1446  // vertices
1447  //---------
1448  vector<SVertex *>::iterator sv, svend;
1449  vector<SVertex *> &verticesList = iBrother.getVertexList();
1450  for (sv = verticesList.begin(), svend = verticesList.end(); sv != svend; sv++) {
1451  SVertex *newv = new SVertex(*(*sv));
1452  newv->setShape(this);
1453  _verticesList.push_back(newv);
1454  }
1455 
1456  //------
1457  // edges
1458  //------
1459  vector<FEdge *>::iterator e, eend;
1460  vector<FEdge *> &edgesList = iBrother.getEdgeList();
1461  for (e = edgesList.begin(), eend = edgesList.end(); e != eend; e++) {
1462  FEdge *newe = (*e)->duplicate();
1463  _edgesList.push_back(newe);
1464  }
1465 
1466  //-------------------------
1467  // starting chain edges
1468  //-------------------------
1469  vector<FEdge *>::iterator fe, fend;
1470  vector<FEdge *> &fedges = iBrother.getChains();
1471  for (fe = fedges.begin(), fend = fedges.end(); fe != fend; fe++) {
1472  _chains.push_back((FEdge *)((*fe)->userdata));
1473  }
1474 
1475  //-------------------------
1476  // remap edges in vertices:
1477  //-------------------------
1478  for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
1479  const vector<FEdge *> &fedgeList = (*sv)->fedges();
1480  vector<FEdge *> newfedgelist;
1481  for (vector<FEdge *>::const_iterator fed = fedgeList.begin(), fedend = fedgeList.end();
1482  fed != fedend;
1483  fed++) {
1484  FEdge *current = *fed;
1485  newfedgelist.push_back((FEdge *)current->userdata);
1486  }
1487  (*sv)->setFEdges(newfedgelist);
1488  }
1489 
1490  //-------------------------------------
1491  // remap vertices and nextedge in edges:
1492  //-------------------------------------
1493  for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
1494  (*e)->setVertexA((SVertex *)((*e)->vertexA()->userdata));
1495  (*e)->setVertexB((SVertex *)((*e)->vertexB()->userdata));
1496  (*e)->setNextEdge((FEdge *)((*e)->nextEdge()->userdata));
1497  (*e)->setPreviousEdge((FEdge *)((*e)->previousEdge()->userdata));
1498  }
1499 
1500  // reset all brothers userdata to NULL:
1501  //-------------------------------------
1502  //---------
1503  // vertices
1504  //---------
1505  for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
1506  (*sv)->userdata = NULL;
1507  }
1508 
1509  //------
1510  // edges
1511  //------
1512  for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
1513  (*e)->userdata = NULL;
1514  }
1515  }
1516 
1518  virtual SShape *duplicate()
1519  {
1520  SShape *clone = new SShape(*this);
1521  return clone;
1522  }
1523 
1525  virtual inline ~SShape()
1526  {
1527  vector<SVertex *>::iterator sv, svend;
1528  vector<FEdge *>::iterator e, eend;
1529  if (0 != _verticesList.size()) {
1530  for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
1531  delete (*sv);
1532  }
1533  _verticesList.clear();
1534  }
1535 
1536  if (0 != _edgesList.size()) {
1537  for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
1538  delete (*e);
1539  }
1540  _edgesList.clear();
1541  }
1542 
1544  //-----------------------
1545  if (0 != _chains.size()) {
1546  _chains.clear();
1547  }
1548  }
1549 
1551  inline void AddEdge(FEdge *iEdge)
1552  {
1553  _edgesList.push_back(iEdge);
1554  }
1555 
1559  inline void AddNewVertex(SVertex *iv)
1560  {
1561  iv->setShape(this);
1562  _verticesList.push_back(iv);
1563  }
1564 
1565  inline void AddChain(FEdge *iEdge)
1566  {
1567  _chains.push_back(iEdge);
1568  }
1569 
1570  inline SVertex *CreateSVertex(const Vec3r &P3D, const Vec3r &P2D, const Id &id)
1571  {
1572  SVertex *Ia = new SVertex(P3D, id);
1573  Ia->setPoint2D(P2D);
1574  AddNewVertex(Ia);
1575  return Ia;
1576  }
1577 
1596  inline void SplitEdge(FEdge *fe, const vector<Vec2r> &iParameters, vector<FEdge *> &ioNewEdges)
1597  {
1598  SVertex *ioA = fe->vertexA();
1599  SVertex *ioB = fe->vertexB();
1600  Vec3r A = ioA->point3D();
1601  Vec3r B = ioB->point3D();
1602  Vec3r a = ioA->point2D();
1603  Vec3r b = ioB->point2D();
1604 
1605  Vec3r newpoint3d, newpoint2d;
1606  vector<SVertex *> intersections;
1607  real t, T;
1608  for (vector<Vec2r>::const_iterator p = iParameters.begin(), pend = iParameters.end();
1609  p != pend;
1610  p++) {
1611  T = (*p)[0];
1612  t = (*p)[1];
1613 
1614  if ((t < 0) || (t > 1)) {
1615  cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - "
1616  << ioB->getId() << endl;
1617  }
1618 
1619  // compute the 3D and 2D coordinates for the intersections points:
1620  newpoint3d = Vec3r(A + T * (B - A));
1621  newpoint2d = Vec3r(a + t * (b - a));
1622 
1623  // create new SVertex:
1624  // (we keep B's id)
1625  SVertex *newVertex = new SVertex(newpoint3d, ioB->getId());
1626  newVertex->setPoint2D(newpoint2d);
1627 
1628  // Add this vertex to the intersections list:
1629  intersections.push_back(newVertex);
1630 
1631  // Add this vertex to this sshape:
1632  AddNewVertex(newVertex);
1633  }
1634 
1635  for (vector<SVertex *>::iterator sv = intersections.begin(), svend = intersections.end();
1636  sv != svend;
1637  sv++) {
1638  // SVertex *svA = fe->vertexA();
1639  SVertex *svB = fe->vertexB();
1640 
1641  // We split edge AB into AA' and A'B. A' and A'B are created.
1642  // AB becomes (address speaking) AA'. B is updated.
1643  //--------------------------------------------------
1644  // The edge AB becomes edge AA'.
1645  (fe)->setVertexB((*sv));
1646  // a new edge, A'B is created.
1647  FEdge *newEdge;
1648  if (fe->isSmooth()) {
1649  newEdge = new FEdgeSmooth((*sv), svB);
1650  FEdgeSmooth *se = dynamic_cast<FEdgeSmooth *>(newEdge);
1651  FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(fe);
1653  }
1654  else {
1655  newEdge = new FEdgeSharp((*sv), svB);
1656  FEdgeSharp *se = dynamic_cast<FEdgeSharp *>(newEdge);
1657  FEdgeSharp *fes = dynamic_cast<FEdgeSharp *>(fe);
1660  }
1661 
1662  newEdge->setNature((fe)->getNature());
1663 
1664  // to build a new chain:
1665  AddChain(newEdge);
1666  // add the new edge to the sshape edges list.
1667  AddEdge(newEdge);
1668  // add new edge to the list of new edges passed as argument:
1669  ioNewEdges.push_back(newEdge);
1670 
1671  // update edge A'B for the next pointing edge
1672  newEdge->setNextEdge((fe)->nextEdge());
1673  fe->nextEdge()->setPreviousEdge(newEdge);
1674  Id id(fe->getId().getFirst(), fe->getId().getSecond() + 1);
1675  newEdge->setId(fe->getId());
1676  fe->setId(id);
1677 
1678  // update edge AA' for the next pointing edge
1679  // ioEdge->setNextEdge(newEdge);
1680  (fe)->setNextEdge(NULL);
1681 
1682  // update vertex pointing edges list:
1683  // -- vertex B --
1684  svB->Replace((fe), newEdge);
1685  // -- vertex A' --
1686  (*sv)->AddFEdge((fe));
1687  (*sv)->AddFEdge(newEdge);
1688  }
1689  }
1690 
1691  /* splits an edge into 2 edges. The new vertex and edge are added to the sshape list of vertices
1692  * and edges a new chain is also created. returns the new edge. ioEdge The edge that gets
1693  * splitted newpoint x,y,z coordinates of the new point.
1694  */
1695  inline FEdge *SplitEdgeIn2(FEdge *ioEdge, SVertex *ioNewVertex)
1696  {
1697  // soc unused - SVertex *A = ioEdge->vertexA();
1698  SVertex *B = ioEdge->vertexB();
1699 
1700  // We split edge AB into AA' and A'B. A' and A'B are created.
1701  // AB becomes (address speaking) AA'. B is updated.
1702  //--------------------------------------------------
1703  // a new edge, A'B is created.
1704  FEdge *newEdge;
1705  if (ioEdge->isSmooth()) {
1706  newEdge = new FEdgeSmooth(ioNewVertex, B);
1707  FEdgeSmooth *se = dynamic_cast<FEdgeSmooth *>(newEdge);
1708  FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth *>(ioEdge);
1709  se->setNormal(fes->normal());
1711  se->setFaceMark(fes->faceMark());
1712  }
1713  else {
1714  newEdge = new FEdgeSharp(ioNewVertex, B);
1715  FEdgeSharp *se = dynamic_cast<FEdgeSharp *>(newEdge);
1716  FEdgeSharp *fes = dynamic_cast<FEdgeSharp *>(ioEdge);
1717  se->setNormalA(fes->normalA());
1718  se->setNormalB(fes->normalB());
1721  se->setaFaceMark(fes->aFaceMark());
1722  se->setbFaceMark(fes->bFaceMark());
1723  }
1724  newEdge->setNature(ioEdge->getNature());
1725 
1726  if (ioEdge->nextEdge() != 0) {
1727  ioEdge->nextEdge()->setPreviousEdge(newEdge);
1728  }
1729 
1730  // update edge A'B for the next pointing edge
1731  newEdge->setNextEdge(ioEdge->nextEdge());
1732  // update edge A'B for the previous pointing edge
1733  newEdge->setPreviousEdge(0); // because it is now a TVertex
1734  Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1);
1735  newEdge->setId(ioEdge->getId());
1736  ioEdge->setId(id);
1737 
1738  // update edge AA' for the next pointing edge
1739  ioEdge->setNextEdge(0); // because it is now a TVertex
1740 
1741  // update vertex pointing edges list:
1742  // -- vertex B --
1743  B->Replace(ioEdge, newEdge);
1744  // -- vertex A' --
1745  ioNewVertex->AddFEdge(ioEdge);
1746  ioNewVertex->AddFEdge(newEdge);
1747 
1748  // to build a new chain:
1749  AddChain(newEdge);
1750  AddEdge(newEdge); // FIXME ??
1751 
1752  // The edge AB becomes edge AA'.
1753  ioEdge->setVertexB(ioNewVertex);
1754 
1755  if (ioEdge->isSmooth()) {
1756  ((FEdgeSmooth *)newEdge)->setFace(((FEdgeSmooth *)ioEdge)->face());
1757  }
1758 
1759  return newEdge;
1760  }
1761 
1763  inline void setBBox(const BBox<Vec3r> &iBBox)
1764  {
1765  _BBox = iBBox;
1766  }
1767 
1769  inline void ComputeBBox()
1770  {
1771  if (0 == _verticesList.size()) {
1772  return;
1773  }
1774 
1775  Vec3r firstVertex = _verticesList[0]->point3D();
1776  real XMax = firstVertex[0];
1777  real YMax = firstVertex[1];
1778  real ZMax = firstVertex[2];
1779 
1780  real XMin = firstVertex[0];
1781  real YMin = firstVertex[1];
1782  real ZMin = firstVertex[2];
1783 
1784  vector<SVertex *>::iterator v, vend;
1785  // parse all the coordinates to find the Xmax, YMax, ZMax
1786  for (v = _verticesList.begin(), vend = _verticesList.end(); v != vend; v++) {
1787  Vec3r vertex = (*v)->point3D();
1788  // X
1789  real x = vertex[0];
1790  if (x > XMax) {
1791  XMax = x;
1792  }
1793  else if (x < XMin) {
1794  XMin = x;
1795  }
1796 
1797  // Y
1798  real y = vertex[1];
1799  if (y > YMax) {
1800  YMax = y;
1801  }
1802  else if (y < YMin) {
1803  YMin = y;
1804  }
1805 
1806  // Z
1807  real z = vertex[2];
1808  if (z > ZMax) {
1809  ZMax = z;
1810  }
1811  else if (z < ZMin) {
1812  ZMin = z;
1813  }
1814  }
1815 
1816  setBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax)));
1817  }
1818 
1819  inline void RemoveEdgeFromChain(FEdge *iEdge)
1820  {
1821  for (vector<FEdge *>::iterator fe = _chains.begin(), feend = _chains.end(); fe != feend;
1822  fe++) {
1823  if (iEdge == (*fe)) {
1824  _chains.erase(fe);
1825  break;
1826  }
1827  }
1828  }
1829 
1830  inline void RemoveEdge(FEdge *iEdge)
1831  {
1832  for (vector<FEdge *>::iterator fe = _edgesList.begin(), feend = _edgesList.end(); fe != feend;
1833  fe++) {
1834  if (iEdge == (*fe)) {
1835  _edgesList.erase(fe);
1836  break;
1837  }
1838  }
1839  }
1840 
1841  /* accessors */
1843  inline vector<SVertex *> &getVertexList()
1844  {
1845  return _verticesList;
1846  }
1847 
1849  inline vector<FEdge *> &getEdgeList()
1850  {
1851  return _edgesList;
1852  }
1853 
1854  inline vector<FEdge *> &getChains()
1855  {
1856  return _chains;
1857  }
1858 
1860  inline const BBox<Vec3r> &bbox()
1861  {
1862  return _BBox;
1863  }
1864 
1866  inline const FrsMaterial &frs_material(unsigned i) const
1867  {
1868  return _FrsMaterials[i];
1869  }
1870 
1872  inline const vector<FrsMaterial> &frs_materials() const
1873  {
1874  return _FrsMaterials;
1875  }
1876 
1878  {
1879  return _ViewShape;
1880  }
1881 
1882  inline float importance() const
1883  {
1884  return _importance;
1885  }
1886 
1888  inline Id getId() const
1889  {
1890  return _Id;
1891  }
1892 
1894  inline const string &getName() const
1895  {
1896  return _Name;
1897  }
1898 
1900  inline const string &getLibraryPath() const
1901  {
1902  return _LibraryPath;
1903  }
1904 
1905  /* Modifiers */
1907  inline void setId(Id id)
1908  {
1909  _Id = id;
1910  }
1911 
1913  inline void setName(const string &name)
1914  {
1915  _Name = name;
1916  }
1917 
1919  inline void setLibraryPath(const string &path)
1920  {
1921  _LibraryPath = path;
1922  }
1923 
1925  inline void setFrsMaterials(const vector<FrsMaterial> &iMaterials)
1926  {
1927  _FrsMaterials = iMaterials;
1928  }
1929 
1930  inline void setViewShape(ViewShape *iShape)
1931  {
1932  _ViewShape = iShape;
1933  }
1934 
1935  inline void setImportance(float importance)
1936  {
1937  _importance = importance;
1938  }
1939 
1940 #ifdef WITH_CXX_GUARDEDALLOC
1941  MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SShape")
1942 #endif
1943 };
1944 
1945 } /* namespace Freestyle */
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Interface to 0D elts.
Interface 1D and related tools definitions.
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
virtual SVertexIterator & operator++()
Definition: Silhouette.h:1011
virtual bool operator==(const Interface0DIteratorNested &it) const
Definition: Silhouette.h:1067
virtual string getExactTypeName() const
Definition: Silhouette.h:996
virtual SVertexIterator & operator--()
Definition: Silhouette.h:1024
SVertexIterator(const SVertexIterator &vi)
Definition: Silhouette.h:977
SVertexIterator & operator=(const SVertexIterator &vi)
Definition: Silhouette.h:989
virtual SVertexIterator * copy() const
Definition: Silhouette.h:1091
virtual SVertexIterator operator--(int)
Definition: Silhouette.h:1030
SVertexIterator(SVertex *v, FEdge *edge)
Definition: Silhouette.h:983
virtual SVertexIterator operator++(int)
Definition: Silhouette.h:1017
unsigned aFrsMaterialIndex() const
Definition: Silhouette.h:1203
void setbFrsMaterialIndex(unsigned i)
Definition: Silhouette.h:1255
void setaFaceMark(bool iFaceMark)
Definition: Silhouette.h:1261
virtual string getExactTypeName() const
Definition: Silhouette.h:1143
unsigned bFrsMaterialIndex() const
Definition: Silhouette.h:1214
virtual FEdge * duplicate()
Definition: Silhouette.h:1179
unsigned _aFrsMaterialIndex
Definition: Silhouette.h:1136
bool bFaceMark() const
Definition: Silhouette.h:1231
FEdgeSharp(FEdgeSharp &iBrother)
Definition: Silhouette.h:1163
void setNormalB(const Vec3r &iNormal)
Definition: Silhouette.h:1243
void setaFrsMaterialIndex(unsigned i)
Definition: Silhouette.h:1249
bool aFaceMark() const
Definition: Silhouette.h:1225
FEdgeSharp(SVertex *vA, SVertex *vB)
Definition: Silhouette.h:1156
void setbFaceMark(bool iFaceMark)
Definition: Silhouette.h:1267
const Vec3r & normalA()
Definition: Silhouette.h:1188
const Vec3r & normalB()
Definition: Silhouette.h:1194
void setNormalA(const Vec3r &iNormal)
Definition: Silhouette.h:1237
unsigned _bFrsMaterialIndex
Definition: Silhouette.h:1137
virtual string getExactTypeName() const
Definition: Silhouette.h:1295
unsigned frs_materialIndex() const
Definition: Silhouette.h:1358
bool faceMark() const
Definition: Silhouette.h:1346
void setNormal(const Vec3r &iNormal)
Definition: Silhouette.h:1378
virtual FEdge * duplicate()
Definition: Silhouette.h:1334
void * face() const
Definition: Silhouette.h:1340
FEdgeSmooth(FEdgeSmooth &iBrother)
Definition: Silhouette.h:1319
FEdgeSmooth(SVertex *vA, SVertex *vB)
Definition: Silhouette.h:1310
void setFaceMark(bool iFaceMark)
Definition: Silhouette.h:1372
const Vec3r & normal()
Definition: Silhouette.h:1352
void setFrsMaterialIndex(unsigned i)
Definition: Silhouette.h:1384
void setFace(void *iFace)
Definition: Silhouette.h:1366
virtual Id getId() const
Definition: Silhouette.h:483
bool getOccludeeEmpty()
Definition: Silhouette.h:700
void setOccludeeEmpty(bool iempty)
Definition: Silhouette.h:798
Vec3r center2d()
Definition: Silhouette.h:668
void setTemporary(bool iFlag)
Definition: Silhouette.h:816
const Vec3r & getOccludeeIntersection()
Definition: Silhouette.h:695
const int qi() const
Definition: Silhouette.h:872
const Polygon3r & aFace() const
Definition: Silhouette.h:690
void setVertexB(SVertex *vB)
Definition: Silhouette.h:729
static SVertex * CommonVertex(FEdge *iEdge1, FEdge *iEdge2)
Definition: Silhouette.h:824
SVertex * _VertexB
Definition: Silhouette.h:500
SVertex * operator[](const unsigned short int &i) const
Definition: Silhouette.h:609
const SVertex * max2d() const
Definition: Silhouette.h:855
virtual FEdge * duplicate()
Definition: Silhouette.h:589
ViewEdge * _ViewEdge
Definition: Silhouette.h:507
FEdge * _NextEdge
Definition: Silhouette.h:505
void setId(const Id &id)
Definition: Silhouette.h:735
SVertex * vertexA()
Definition: Silhouette.h:597
ViewEdge * viewedge() const
Definition: Silhouette.h:658
FEdge * previousEdge()
Definition: Silhouette.h:631
SVertex * _VertexA
Definition: Silhouette.h:499
Vec3r orientation2d() const
Definition: Silhouette.h:912
const SVertex * min2d() const
Definition: Silhouette.h:845
bool isInImage() const
Definition: Silhouette.h:711
bool isTemporary() const
Definition: Silhouette.h:716
void setViewEdge(ViewEdge *iViewEdge)
Definition: Silhouette.h:766
void setNextEdge(FEdge *iEdge)
Definition: Silhouette.h:741
FEdge(SVertex *vA, SVertex *vB)
Definition: Silhouette.h:545
SVertex * vertexB()
Definition: Silhouette.h:603
SShape * shape()
Definition: Silhouette.h:636
virtual real getLength2D() const
Definition: Silhouette.h:474
void setNature(Nature::EdgeNature iNature)
Definition: Silhouette.h:753
Vec3r _occludeeIntersection
Definition: Silhouette.h:512
Vec3r center3d()
Definition: Silhouette.h:663
const Polygon3r & occludee() const
Definition: Silhouette.h:882
void setSmooth(bool iFlag)
Definition: Silhouette.h:806
void setPreviousEdge(FEdge *iEdge)
Definition: Silhouette.h:747
void setIsInImage(bool iFlag)
Definition: Silhouette.h:811
virtual string getExactTypeName() const
Definition: Silhouette.h:466
bool isSmooth() const
Definition: Silhouette.h:706
void setaFace(Polygon3r &iFace)
Definition: Silhouette.h:788
FEdge * nextEdge()
Definition: Silhouette.h:623
Vec3r orientation3d() const
Definition: Silhouette.h:917
void setVertexA(SVertex *vA)
Definition: Silhouette.h:723
virtual ~FEdge()
Definition: Silhouette.h:584
Polygon3r _aFace
Definition: Silhouette.h:511
Nature::EdgeNature getNature() const
Definition: Silhouette.h:615
void setOccludeeIntersection(const Vec3r &iPoint)
Definition: Silhouette.h:793
FEdge * _PreviousEdge
Definition: Silhouette.h:506
Nature::EdgeNature _Nature
Definition: Silhouette.h:502
FEdge(FEdge &iBrother)
Definition: Silhouette.h:562
id_type getFirst() const
Definition: Id.h:62
id_type getSecond() const
Definition: Id.h:68
void RemoveEdgeFromChain(FEdge *iEdge)
Definition: Silhouette.h:1819
vector< SVertex * > & getVertexList()
Definition: Silhouette.h:1843
void setId(Id id)
Definition: Silhouette.h:1907
const string & getName() const
Definition: Silhouette.h:1894
virtual SShape * duplicate()
Definition: Silhouette.h:1518
ViewShape * viewShape()
Definition: Silhouette.h:1877
SVertex * CreateSVertex(const Vec3r &P3D, const Vec3r &P2D, const Id &id)
Definition: Silhouette.h:1570
void AddChain(FEdge *iEdge)
Definition: Silhouette.h:1565
const vector< FrsMaterial > & frs_materials() const
Definition: Silhouette.h:1872
void setFrsMaterials(const vector< FrsMaterial > &iMaterials)
Definition: Silhouette.h:1925
void setImportance(float importance)
Definition: Silhouette.h:1935
void setViewShape(ViewShape *iShape)
Definition: Silhouette.h:1930
float importance() const
Definition: Silhouette.h:1882
virtual ~SShape()
Definition: Silhouette.h:1525
const BBox< Vec3r > & bbox()
Definition: Silhouette.h:1860
vector< FEdge * > & getEdgeList()
Definition: Silhouette.h:1849
FEdge * SplitEdgeIn2(FEdge *ioEdge, SVertex *ioNewVertex)
Definition: Silhouette.h:1695
void setLibraryPath(const string &path)
Definition: Silhouette.h:1919
void SplitEdge(FEdge *fe, const vector< Vec2r > &iParameters, vector< FEdge * > &ioNewEdges)
Definition: Silhouette.h:1596
const string & getLibraryPath() const
Definition: Silhouette.h:1900
void RemoveEdge(FEdge *iEdge)
Definition: Silhouette.h:1830
void setBBox(const BBox< Vec3r > &iBBox)
Definition: Silhouette.h:1763
const FrsMaterial & frs_material(unsigned i) const
Definition: Silhouette.h:1866
SShape(SShape &iBrother)
Definition: Silhouette.h:1434
void AddNewVertex(SVertex *iv)
Definition: Silhouette.h:1559
Id getId() const
Definition: Silhouette.h:1888
void setName(const string &name)
Definition: Silhouette.h:1913
vector< FEdge * > & getChains()
Definition: Silhouette.h:1854
void AddEdge(FEdge *iEdge)
Definition: Silhouette.h:1551
const vector< FEdge * > & fedges()
Definition: Silhouette.h:248
virtual bool operator==(const SVertex &iBrother)
Definition: Silhouette.h:217
ViewVertex * viewvertex()
Definition: Silhouette.h:276
SShape * shape()
Definition: Silhouette.h:263
const Vec3r & point2d() const
Definition: Silhouette.h:395
virtual real getY() const
Definition: Silhouette.h:72
void setPoint2D(const Vec3r &iPoint2D)
Definition: Silhouette.h:289
void setViewVertex(ViewVertex *iViewVertex)
Definition: Silhouette.h:353
virtual ~SVertex()
Definition: Silhouette.h:202
void setShape(SShape *iShape)
Definition: Silhouette.h:348
Vec3r normal() const
Definition: Silhouette.h:405
fedges_container::iterator fedges_begin()
Definition: Silhouette.h:253
virtual Vec3r getPoint3D() const
Definition: Silhouette.h:84
void setCurvatureInfo(CurvatureInfo *ci)
Definition: Silhouette.h:301
real z() const
Definition: Silhouette.h:268
virtual real getX() const
Definition: Silhouette.h:66
fedges_container::iterator fedges_end()
Definition: Silhouette.h:258
set< Vec3r > normals()
Definition: Silhouette.h:237
void AddNormal(const Vec3r &iNormal)
Definition: Silhouette.h:296
virtual Vec2r getPoint2D() const
Definition: Silhouette.h:108
virtual string getExactTypeName() const
Definition: Silhouette.h:59
const Vec3r & point3D() const
Definition: Silhouette.h:223
void setPoint3D(const Vec3r &iPoint3D)
Definition: Silhouette.h:283
const CurvatureInfo * getCurvatureInfo() const
Definition: Silhouette.h:309
void AddFEdge(FEdge *iFEdge)
Definition: Silhouette.h:359
virtual real getProjectedZ() const
Definition: Silhouette.h:102
unsigned normalsSize() const
Definition: Silhouette.h:243
virtual real getZ() const
Definition: Silhouette.h:78
virtual Id getId() const
Definition: Silhouette.h:117
const Vec3r & point2D() const
Definition: Silhouette.h:228
const Vec3r & point3d() const
Definition: Silhouette.h:400
void RemoveFEdge(FEdge *iFEdge)
Definition: Silhouette.h:365
virtual real getProjectedY() const
Definition: Silhouette.h:96
void setId(const Id &id)
Definition: Silhouette.h:338
vector< FEdge * > fedges_container
Definition: Silhouette.h:138
SVertex(const Vec3r &iPoint3D, const Id &id)
Definition: Silhouette.h:171
void setFEdges(const vector< FEdge * > &iFEdges)
Definition: Silhouette.h:343
virtual real getProjectedX() const
Definition: Silhouette.h:90
virtual SVertex * duplicate()
Definition: Silhouette.h:210
SVertex(SVertex &iBrother)
Definition: Silhouette.h:182
void Replace(FEdge *e1, FEdge *e2)
Definition: Silhouette.h:376
#define T
#define B
FEdge * getFEdge(Interface0D &it1, Interface0D &it2)
Definition: Functions0D.cpp:18
VecMat::Vec2< real > Vec2r
Definition: Geom.h:22
VecMat::Vec3< real > Vec3r
Definition: Geom.h:28
static const EdgeNature NO_FEATURE
Definition: Nature.h:34
unsigned short VertexNature
Definition: Nature.h:18
unsigned short EdgeNature
Definition: Nature.h:32
Vec< T, N > operator*(const typename Vec< T, N >::value_type r, const Vec< T, N > &v)
Definition: VecMat.h:844
inherits from class Rep
Definition: AppCanvas.cpp:18
vector< ViewShape * > occluder_container
Definition: Silhouette.h:40
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
double real
Definition: Precision.h:12
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
return ret