2
* ***** BEGIN GPL LICENSE BLOCK *****
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software Foundation,
16
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
* ***** END GPL LICENSE BLOCK *****
21
#ifndef __FREESTYLE_SILHOUETTE_H__
22
#define __FREESTYLE_SILHOUETTE_H__
24
/** \file blender/freestyle/intern/view_map/Silhouette.h
26
* \brief Classes to define a silhouette structure
27
* \author Stephane Grabli
37
#include "Interface0D.h"
38
#include "Interface1D.h"
40
#include "../geometry/BBox.h"
41
#include "../geometry/Geom.h"
42
#include "../geometry/Polygon.h"
44
#include "../scene_graph/FrsMaterial.h"
46
#include "../system/Exception.h"
47
#include "../system/FreestyleConfig.h"
49
#include "../winged_edge/Curvature.h"
51
#ifdef WITH_CXX_GUARDEDALLOC
52
#include "MEM_guardedalloc.h"
59
using namespace Geometry;
62
typedef vector<ViewShape*> occluder_container;
64
/**********************************/
70
/**********************************/
76
/*! Class to define a vertex of the embedding. */
77
class LIB_VIEW_MAP_EXPORT SVertex : public Interface0D
79
public: // Implementation of Interface0D
80
/*! Returns the string "SVertex" .*/
81
virtual string getExactTypeName() const
86
// Data access methods
87
/*! Returns the 3D x coordinate of the vertex .*/
88
virtual real getX() const
93
/*! Returns the 3D y coordinate of the vertex .*/
94
virtual real getY() const
99
/*! Returns the 3D z coordinate of the vertex .*/
100
virtual real getZ() const
105
/*! Returns the 3D point. */
106
virtual Vec3f getPoint3D() const
111
/*! Returns the projected 3D x coordinate of the vertex .*/
112
virtual real getProjectedX() const
117
/*! Returns the projected 3D y coordinate of the vertex .*/
118
virtual real getProjectedY() const
123
/*! Returns the projected 3D z coordinate of the vertex .*/
124
virtual real getProjectedZ() const
129
/*! Returns the 2D point. */
130
virtual Vec2f getPoint2D() const
132
return Vec2f((float)_Point2D.x(), (float)_Point2D.y());
135
/*! Returns the FEdge that lies between this Svertex and the Interface0D given as argument. */
136
virtual FEdge *getFEdge(Interface0D&);
138
/*! Returns the Id of the vertex .*/
139
virtual Id getId() const
144
/*! Returns the nature of the vertex .*/
145
virtual Nature::VertexNature getNature() const;
147
/*! Cast the Interface0D in SVertex if it can be. */
148
virtual SVertex *castToSVertex();
150
/*! Cast the Interface0D in ViewVertex if it can be. */
151
virtual ViewVertex *castToViewVertex();
153
/*! Cast the Interface0D in NonTVertex if it can be. */
154
virtual NonTVertex *castToNonTVertex();
156
/*! Cast the Interface0D in TVertex if it can be. */
157
virtual TVertex *castToTVertex();
160
typedef vector<FEdge*> fedges_container;
167
vector<FEdge*> _FEdges; // the edges containing this vertex
168
SShape *_Shape; // the shape to which belongs the vertex
169
ViewVertex *_pViewVertex; // The associated viewvertex, in case there is one.
170
real _curvatureFredo;
171
Vec2r _directionFredo;
172
CurvatureInfo *_curvature_info;
175
/*! A field that can be used by the user to store any data.
176
* This field must be reseted afterwards using ResetUserData().
180
/*! Default constructor.*/
190
/*! Builds a SVertex from 3D coordinates and an Id. */
191
inline SVertex(const Vec3r &iPoint3D, const Id& id)
201
/*! Copy constructor. */
202
inline SVertex(SVertex& iBrother)
205
_Point3D = iBrother.point3D();
206
_Point2D = iBrother.point2D();
207
_Normals = iBrother._Normals;
208
_FEdges = iBrother.fedges();
209
_Shape = iBrother.shape();
210
_pViewVertex = iBrother._pViewVertex;
211
if (!(iBrother._curvature_info))
214
_curvature_info = new CurvatureInfo(*(iBrother._curvature_info));
215
iBrother.userdata = this;
223
delete _curvature_info;
226
/*! Cloning method. */
227
virtual SVertex *duplicate()
229
SVertex *clone = new SVertex(*this);
234
virtual bool operator==(const SVertex& iBrother)
236
return ((_Point2D == iBrother._Point2D) && (_Point3D == iBrother._Point3D));
240
inline const Vec3r& point3D() const
245
inline const Vec3r& point2D() const
250
/*! Returns the set of normals for this Vertex.
251
* In a smooth surface, a vertex has exactly one normal.
252
* In a sharp surface, a vertex can have any number of normals.
254
inline set<Vec3r> normals()
259
/*! Returns the number of different normals for this vertex. */
260
inline unsigned normalsSize() const
262
return _Normals.size();
265
inline const vector<FEdge*>& fedges()
270
inline fedges_container::iterator fedges_begin()
272
return _FEdges.begin();
275
inline fedges_container::iterator fedges_end()
277
return _FEdges.end();
280
inline SShape *shape()
285
inline real z() const
290
/*! If this SVertex is also a ViewVertex, this method returns a pointer onto this ViewVertex.
291
* 0 is returned otherwise.
293
inline ViewVertex *viewvertex()
299
/*! Sets the 3D coordinates of the SVertex. */
300
inline void setPoint3D(const Vec3r &iPoint3D)
305
/*! Sets the 3D projected coordinates of the SVertex. */
306
inline void setPoint2D(const Vec3r &iPoint2D)
311
/*! Adds a normal to the Svertex's set of normals. If the same normal is already in the set, nothing changes. */
312
inline void AddNormal(const Vec3r& iNormal)
314
_Normals.insert(iNormal); // if iNormal in the set already exists, nothing is done
317
void setCurvatureInfo(CurvatureInfo *ci)
319
if (_curvature_info) // Q. is this an error condition? (T.K. 02-May-2011)
320
delete _curvature_info;
321
_curvature_info = ci;
324
const CurvatureInfo *getCurvatureInfo() const
326
return _curvature_info;
329
/* Fredo's normal and curvature*/
330
void setCurvatureFredo(real c)
335
void setDirectionFredo(Vec2r d)
340
real curvatureFredo ()
342
return _curvatureFredo;
345
const Vec2r directionFredo ()
347
return _directionFredo;
351
inline void setId(const Id& id)
356
inline void setFEdges(const vector<FEdge*>& iFEdges)
361
inline void setShape(SShape *iShape)
366
inline void setViewVertex(ViewVertex *iViewVertex)
368
_pViewVertex = iViewVertex;
371
/*! Add an FEdge to the list of edges emanating from this SVertex. */
372
inline void AddFEdge(FEdge *iFEdge)
374
_FEdges.push_back(iFEdge);
377
/* replaces edge 1 by edge 2 in the list of edges */
378
inline void Replace(FEdge *e1, FEdge *e2)
380
vector<FEdge *>::iterator insertedfe;
381
for (vector<FEdge *>::iterator fe = _FEdges.begin(), fend = _FEdges.end(); fe != fend; fe++) {
383
insertedfe = _FEdges.insert(fe, e2);// inserts e2 before fe.
384
// returns an iterator pointing toward e2. fe is invalidated.
385
// we want to remove e1, but we can't use fe anymore:
386
++insertedfe; // insertedfe points now to e1
387
_FEdges.erase(insertedfe);
394
/* Information access interface */
395
FEdge *fedge(); // for non T vertex
397
inline const Vec3r& point2d() const
402
inline const Vec3r& point3d() const
407
inline Vec3r normal() const
409
if (_Normals.size() == 1)
410
return (*(_Normals.begin()));
411
Exception::raiseException();
412
return *(_Normals.begin());
415
//Material material() const ;
417
const SShape *shape() const;
418
float shape_importance() const;
420
const int qi() const;
421
occluder_container::const_iterator occluders_begin() const;
422
occluder_container::const_iterator occluders_end() const;
423
bool occluders_empty() const;
424
int occluders_size() const;
425
const Polygon3r& occludee() const;
426
const SShape *occluded_shape() const;
427
const bool occludee_empty() const;
428
real z_discontinuity() const;
430
inline float local_average_depth() const;
431
inline float local_depth_variance() const;
432
inline real local_average_density(float sigma = 2.3f) const;
433
inline Vec3r shaded_color() const;
434
inline Vec3r orientation2d() const;
435
inline Vec3r orientation3d() const;
436
inline Vec3r curvature2d_as_vector() const;
437
/*! angle in radians */
438
inline real curvature2d_as_angle() const;
442
/**********************************/
448
/**********************************/
452
/*! Base Class for feature edges.
453
* This FEdge can represent a silhouette, a crease, a ridge/valley, a border or a suggestive contour.
454
* For silhouettes, the FEdge is oriented such as, the visible face lies on the left of the edge.
455
* For borders, the FEdge is oriented such as, the face lies on the left of the edge.
456
* An FEdge can represent an initial edge of the mesh or runs accross a face of the initial mesh depending
457
* on the smoothness or sharpness of the mesh.
458
* This class is specialized into a smooth and a sharp version since their properties slightly vary from
461
class LIB_VIEW_MAP_EXPORT FEdge : public Interface1D
463
public: // Implementation of Interface0D
464
/*! Returns the string "FEdge". */
465
virtual string getExactTypeName() const
470
// Data access methods
472
/*! Returns the 2D length of the FEdge. */
473
virtual real getLength2D() const
475
if (!_VertexA || !_VertexB)
477
return (_VertexB->getPoint2D() - _VertexA->getPoint2D()).norm();
480
/*! Returns the Id of the FEdge. */
481
virtual Id getId() const
487
// An edge can only be of one kind (SILHOUETTE or BORDER, etc...)
488
// For an multi-nature edge there must be several different FEdge.
492
// vector<Polygon3r> _Occludees;
493
// Vec3r intersection;
494
// vector<Vec3i> _Cells;
500
Nature::EdgeNature _Nature;
501
//vector<Polygon3r> _Occluders; // visibility // NOT HANDLED BY THE COPY CONSTRUCTOR!!
503
FEdge *_NextEdge; // next edge on the chain
504
FEdge *_PreviousEdge;
506
// Sometimes we need to deport the visibility computation onto another edge. For example the exact edges use
507
// edges of the mesh to compute their visibility
509
Polygon3r _aFace; // The occluded face which lies on the right of a silhouette edge
510
Vec3r _occludeeIntersection;
518
/*! A field that can be used by the user to store any data.
519
* This field must be reseted afterwards using ResetUserData().
523
/*! Default constructor */
529
_Nature = Nature::NO_FEATURE;
531
_PreviousEdge = NULL;
533
//_hasVisibilityPoint = false;
534
_occludeeEmpty = true;
539
/*! Builds an FEdge going from vA to vB. */
540
inline FEdge(SVertex *vA, SVertex *vB)
545
_Nature = Nature::NO_FEATURE;
547
_PreviousEdge = NULL;
549
//_hasVisibilityPoint = false;
550
_occludeeEmpty = true;
555
/*! Copy constructor */
556
inline FEdge(FEdge& iBrother)
558
_VertexA = iBrother.vertexA();
559
_VertexB = iBrother.vertexB();
560
_NextEdge = iBrother.nextEdge();
561
_PreviousEdge = iBrother._PreviousEdge;
562
_Nature = iBrother.getNature();
564
_ViewEdge = iBrother._ViewEdge;
565
//_hasVisibilityPoint = iBrother._hasVisibilityPoint;
566
//_VisibilityPointA = iBrother._VisibilityPointA;
567
//_VisibilityPointB = iBrother._VisibilityPointB;
568
_aFace = iBrother._aFace;
569
_occludeeEmpty = iBrother._occludeeEmpty;
570
_isSmooth = iBrother._isSmooth;
571
_isInImage = iBrother._isInImage;
572
iBrother.userdata = this;
579
/*! Cloning method. */
580
virtual FEdge *duplicate()
582
FEdge *clone = new FEdge(*this);
587
/*! Returns the first SVertex. */
588
inline SVertex *vertexA()
593
/*! Returns the second SVertex. */
594
inline SVertex *vertexB()
599
/*! Returns the first SVertex if i=0, the seccond SVertex if i=1. */
600
inline SVertex *operator[](const unsigned short int& i) const
602
return (i % 2 == 0) ? _VertexA : _VertexB;
605
/*! Returns the nature of the FEdge. */
606
inline Nature::EdgeNature getNature() const
611
/*! Returns the FEdge following this one in the ViewEdge.
612
* If this FEdge is the last of the ViewEdge, 0 is returned.
614
inline FEdge *nextEdge()
619
/*! Returns the Edge preceding this one in the ViewEdge.
620
* If this FEdge is the first one of the ViewEdge, 0 is returned.
622
inline FEdge *previousEdge()
624
return _PreviousEdge;
627
inline SShape *shape()
629
return _VertexA->shape();
633
inline int invisibility() const
635
return _Occluders.size();
639
int invisibility() const;
642
inline const vector<Polygon3r>& occluders() const
648
/*! Returns a pointer to the ViewEdge to which this FEdge belongs to. */
649
inline ViewEdge *viewedge() const
654
inline Vec3r center3d()
656
return Vec3r((_VertexA->point3D() + _VertexB->point3D()) / 2.0);
659
inline Vec3r center2d()
661
return Vec3r((_VertexA->point2D() + _VertexB->point2D()) / 2.0);
665
inline bool hasVisibilityPoint() const
667
return _hasVisibilityPoint;
670
inline Vec3r visibilityPointA() const
672
return _VisibilityPointA;
675
inline Vec3r visibilityPointB() const
677
return _VisibilityPointB;
681
inline const Polygon3r& aFace() const
686
inline const Vec3r& getOccludeeIntersection()
688
return _occludeeIntersection;
691
inline bool getOccludeeEmpty()
693
return _occludeeEmpty;
696
/*! Returns true if this FEdge is a smooth FEdge. */
697
inline bool isSmooth() const
702
inline bool isInImage () const
708
/*! Sets the first SVertex. */
709
inline void setVertexA(SVertex *vA)
714
/*! Sets the second SVertex. */
715
inline void setVertexB(SVertex *vB)
720
/*! Sets the FEdge Id . */
721
inline void setId(const Id& id)
726
/*! Sets the pointer to the next FEdge. */
727
inline void setNextEdge(FEdge *iEdge)
732
/*! Sets the pointer to the previous FEdge. */
733
inline void setPreviousEdge(FEdge *iEdge)
735
_PreviousEdge = iEdge;
738
/*! Sets the nature of this FEdge. */
739
inline void setNature(Nature::EdgeNature iNature)
745
inline void AddOccluder(Polygon3r& iPolygon)
747
_Occluders.push_back(iPolygon);
751
/*! Sets the ViewEdge to which this FEdge belongs to. */
752
inline void setViewEdge(ViewEdge *iViewEdge)
754
_ViewEdge = iViewEdge;
758
inline void setHasVisibilityPoint(bool iBool)
760
_hasVisibilityPoint = iBool;
763
inline void setVisibilityPointA(const Vec3r& iPoint)
765
_VisibilityPointA = iPoint;
768
inline void setVisibilityPointB(const Vec3r& iPoint)
770
_VisibilityPointB = iPoint;
774
inline void setaFace(Polygon3r& iFace)
779
inline void setOccludeeIntersection(const Vec3r& iPoint)
781
_occludeeIntersection = iPoint;
784
inline void setOccludeeEmpty(bool iempty)
786
_occludeeEmpty = iempty;
789
/*! Sets the flag telling whether this FEdge is smooth or sharp.
790
* true for Smooth, false for Sharp.
792
inline void setSmooth(bool iFlag)
797
inline void setIsInImage (bool iFlag)
802
/* checks whether two FEdge have a common vertex.
803
* Returns a pointer on the common vertex if it exists, NULL otherwise.
805
static inline SVertex *CommonVertex(FEdge *iEdge1, FEdge *iEdge2)
807
if ((NULL == iEdge1) || (NULL == iEdge2))
810
SVertex *sv1 = iEdge1->vertexA();
811
SVertex *sv2 = iEdge1->vertexB();
812
SVertex *sv3 = iEdge2->vertexA();
813
SVertex *sv4 = iEdge2->vertexB();
815
if ((sv1 == sv3) || (sv1 == sv4)) {
818
else if ((sv2 == sv3) || (sv2 == sv4)) {
825
inline const SVertex *min2d() const
827
if (_VertexA->point2D() < _VertexB->point2D())
833
inline const SVertex *max2d() const
835
if (_VertexA->point2D() < _VertexB->point2D())
841
/* Information access interface */
843
//Material material() const;
845
const SShape *shape() const;
846
float shape_importance() const;
848
inline const int qi() const
850
return invisibility();
853
occluder_container::const_iterator occluders_begin() const;
854
occluder_container::const_iterator occluders_end() const;
855
bool occluders_empty() const;
856
int occluders_size() const;
858
inline const Polygon3r& occludee() const
863
const SShape *occluded_shape() const;
866
inline const bool occludee_empty() const
868
return _occludeeEmpty;
872
const bool occludee_empty() const;
873
real z_discontinuity() const;
876
inline float local_average_depth(int iCombination = 0) const;
877
inline float local_depth_variance(int iCombination = 0) const;
878
inline real local_average_density(float sigma = 2.3f, int iCombination = 0) const;
879
inline Vec3r shaded_color(int iCombination = 0) const {}
882
int viewedge_nature() const;
884
//float viewedge_length() const;
886
inline Vec3r orientation2d() const
888
return Vec3r(_VertexB->point2d() - _VertexA->point2d());
891
inline Vec3r orientation3d() const
893
return Vec3r(_VertexB->point3d() - _VertexA->point3d());
897
inline real curvature2d() const
899
return viewedge()->curvature2d((_VertexA->point2d() + _VertexB->point2d()) / 2.0);
902
inline Vec3r curvature2d_as_vector(int iCombination = 0) const;
904
/* angle in degrees*/
905
inline real curvature2d_as_angle(int iCombination = 0) const;
908
// Iterator access (Interface1D)
909
/*! Returns an iterator over the 2 (!) SVertex pointing to the first SVertex. */
910
virtual inline Interface0DIterator verticesBegin();
912
/*! Returns an iterator over the 2 (!) SVertex pointing after the last SVertex. */
913
virtual inline Interface0DIterator verticesEnd();
915
/*! Returns an iterator over the FEdge points, pointing to the first point. The difference with verticesBegin()
916
* is that here we can iterate over points of the FEdge at a any given sampling.
917
* Indeed, for each iteration, a virtual point is created.
919
* The sampling with which we want to iterate over points of this FEdge.
921
virtual inline Interface0DIterator pointsBegin(float t = 0.0f);
923
/*! Returns an iterator over the FEdge points, pointing after the last point. The difference with verticesEnd()
924
* is that here we can iterate over points of the FEdge at a any given sampling.
925
* Indeed, for each iteration, a virtual point is created.
927
* The sampling with which we want to iterate over points of this FEdge.
929
virtual inline Interface0DIterator pointsEnd(float t = 0.0f);
935
/////////////////////////////////////////////////
937
namespace FEdgeInternal {
939
class SVertexIterator : public Interface0DIteratorNested
948
SVertexIterator(const SVertexIterator& vi)
950
_vertex = vi._vertex;
954
SVertexIterator(SVertex *v, FEdge *edge)
960
SVertexIterator& operator=(const SVertexIterator& vi)
962
_vertex = vi._vertex;
967
virtual string getExactTypeName() const
969
return "SVertexIterator";
972
virtual SVertex& operator*()
977
virtual SVertex *operator->()
979
return &(operator*());
982
virtual SVertexIterator& operator++()
988
virtual SVertexIterator operator++(int)
990
SVertexIterator ret(*this);
995
virtual SVertexIterator& operator--()
1001
virtual SVertexIterator operator--(int)
1003
SVertexIterator ret(*this);
1008
virtual int increment()
1010
if (_vertex == _edge->vertexB()) {
1014
_vertex = _edge->vertexB();
1018
virtual int decrement()
1020
if (_vertex == _edge->vertexA()) {
1024
_vertex = _edge->vertexA();
1028
virtual bool isBegin() const
1030
return _vertex == _edge->vertexA();
1033
virtual bool isEnd() const
1035
return _vertex == _edge->vertexB();
1038
virtual bool operator==(const Interface0DIteratorNested& it) const
1040
const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator*>(&it);
1043
return ((_vertex == it_exact->_vertex) && (_edge == it_exact->_edge));
1046
virtual float t() const
1048
if (_vertex == _edge->vertexA()) {
1051
return ((float)_edge->getLength2D());
1053
virtual float u() const
1055
if (_vertex == _edge->vertexA()) {
1061
virtual SVertexIterator *copy() const
1063
return new SVertexIterator(*this);
1071
} // end of namespace FEdgeInternal
1073
// Iterator access (implementation)
1075
Interface0DIterator FEdge::verticesBegin()
1077
Interface0DIterator ret(new FEdgeInternal::SVertexIterator(_VertexA, this));
1081
Interface0DIterator FEdge::verticesEnd()
1083
Interface0DIterator ret(new FEdgeInternal::SVertexIterator(0, this));
1087
Interface0DIterator FEdge::pointsBegin(float t)
1089
return verticesBegin();
1092
Interface0DIterator FEdge::pointsEnd(float t)
1094
return verticesEnd();
1097
/*! Class defining a sharp FEdge. A Sharp FEdge corresponds to an initial edge of the input mesh.
1098
* It can be a silhouette, a crease or a border. If it is a crease edge, then it is borded
1099
* by two faces of the mesh. Face a lies on its right whereas Face b lies on its left.
1100
* If it is a border edge, then it doesn't have any face on its right, and thus Face a = 0.
1102
class LIB_VIEW_MAP_EXPORT FEdgeSharp : public FEdge
1105
Vec3r _aNormal; // When following the edge, normal of the right face
1106
Vec3r _bNormal; // When following the edge, normal of the left face
1107
unsigned _aFrsMaterialIndex;
1108
unsigned _bFrsMaterialIndex;
1113
/*! Returns the string "FEdgeSharp" . */
1114
virtual string getExactTypeName() const
1116
return "FEdgeSharp";
1119
/*! Default constructor. */
1120
inline FEdgeSharp() : FEdge()
1122
_aFrsMaterialIndex = _bFrsMaterialIndex = 0;
1123
_aFaceMark = _bFaceMark = false;
1126
/*! Builds an FEdgeSharp going from vA to vB. */
1127
inline FEdgeSharp(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
1129
_aFrsMaterialIndex = _bFrsMaterialIndex = 0;
1130
_aFaceMark = _bFaceMark = false;
1133
/*! Copy constructor. */
1134
inline FEdgeSharp(FEdgeSharp& iBrother) : FEdge(iBrother)
1136
_aNormal = iBrother._aNormal;
1137
_bNormal = iBrother._bNormal;
1138
_aFrsMaterialIndex = iBrother._aFrsMaterialIndex;
1139
_bFrsMaterialIndex = iBrother._bFrsMaterialIndex;
1140
_aFaceMark = iBrother._aFaceMark;
1141
_bFaceMark = iBrother._bFaceMark;
1145
virtual ~FEdgeSharp() {}
1147
/*! Cloning method. */
1148
virtual FEdge *duplicate()
1150
FEdge *clone = new FEdgeSharp(*this);
1154
/*! Returns the normal to the face lying on the right of the FEdge. If this FEdge is a border,
1155
* it has no Face on its right and therefore, no normal.
1157
inline const Vec3r& normalA()
1162
/*! Returns the normal to the face lying on the left of the FEdge. */
1163
inline const Vec3r& normalB()
1168
/*! Returns the index of the material of the face lying on the
1169
* right of the FEdge. If this FEdge is a border,
1170
* it has no Face on its right and therefore, no material.
1172
inline unsigned aFrsMaterialIndex() const
1174
return _aFrsMaterialIndex;
1177
/*! Returns the material of the face lying on the right of the FEdge. If this FEdge is a border,
1178
* it has no Face on its right and therefore, no material.
1180
const FrsMaterial& aFrsMaterial() const;
1182
/*! Returns the index of the material of the face lying on the left of the FEdge. */
1183
inline unsigned bFrsMaterialIndex() const
1185
return _bFrsMaterialIndex;
1188
/*! Returns the material of the face lying on the left of the FEdge. */
1189
const FrsMaterial& bFrsMaterial() const;
1191
/*! Returns the face mark of the face lying on the right of the FEdge.
1192
* If this FEdge is a border, it has no Face on its right and thus false is returned.
1194
inline bool aFaceMark() const
1199
/*! Returns the face mark of the face lying on the left of the FEdge. */
1200
inline bool bFaceMark() const
1205
/*! Sets the normal to the face lying on the right of the FEdge. */
1206
inline void setNormalA(const Vec3r& iNormal)
1211
/*! Sets the normal to the face lying on the left of the FEdge. */
1212
inline void setNormalB(const Vec3r& iNormal)
1217
/*! Sets the index of the material lying on the right of the FEdge.*/
1218
inline void setaFrsMaterialIndex(unsigned i)
1220
_aFrsMaterialIndex = i;
1223
/*! Sets the index of the material lying on the left of the FEdge.*/
1224
inline void setbFrsMaterialIndex(unsigned i)
1226
_bFrsMaterialIndex = i;
1229
/*! Sets the face mark of the face lying on the right of the FEdge. */
1230
inline void setaFaceMark(bool iFaceMark)
1232
_aFaceMark = iFaceMark;
1235
/*! Sets the face mark of the face lying on the left of the FEdge. */
1236
inline void setbFaceMark(bool iFaceMark)
1238
_bFaceMark = iFaceMark;
1242
/*! Class defining a smooth edge. This kind of edge typically runs across a face of the input mesh. It can be
1243
* a silhouette, a ridge or valley, a suggestive contour.
1245
class LIB_VIEW_MAP_EXPORT FEdgeSmooth : public FEdge
1249
unsigned _FrsMaterialIndex;
1251
bool _hasVisibilityPoint;
1252
Vec3r _VisibilityPointA; // The edge on which the visibility will be computed represented
1253
Vec3r _VisibilityPointB; // using its 2 extremity points A and B
1255
void *_Face; // In case of exact silhouette, Face is the WFace crossed by Fedge
1256
// NOT HANDLED BY THE COPY CONSTRUCTEUR
1260
/*! Returns the string "FEdgeSmooth" . */
1261
virtual string getExactTypeName() const
1263
return "FEdgeSmooth";
1266
/*! Default constructor. */
1267
inline FEdgeSmooth() : FEdge()
1271
_FrsMaterialIndex = 0;
1275
/*! Builds an FEdgeSmooth going from vA to vB. */
1276
inline FEdgeSmooth(SVertex *vA, SVertex *vB) : FEdge(vA, vB)
1280
_FrsMaterialIndex = 0;
1284
/*! Copy constructor. */
1285
inline FEdgeSmooth(FEdgeSmooth& iBrother) : FEdge(iBrother)
1287
_Normal = iBrother._Normal;
1288
_Face = iBrother._Face;
1289
_FaceMark = iBrother._FaceMark;
1290
_FrsMaterialIndex = iBrother._FrsMaterialIndex;
1295
virtual ~FEdgeSmooth() {}
1297
/*! Cloning method. */
1298
virtual FEdge *duplicate()
1300
FEdge *clone = new FEdgeSmooth(*this);
1304
inline void *face() const
1309
/*! Returns the face mark of the face it is running across. */
1310
inline bool faceMark() const
1315
/*! Returns the normal to the Face it is running accross. */
1316
inline const Vec3r& normal()
1321
/*! Returns the index of the material of the face it is running accross. */
1322
inline unsigned frs_materialIndex() const
1324
return _FrsMaterialIndex;
1327
/*! Returns the material of the face it is running accross. */
1328
const FrsMaterial& frs_material() const;
1330
inline void setFace(void *iFace)
1335
/*! Sets the face mark of the face it is running across. */
1336
inline void setFaceMark(bool iFaceMark)
1338
_FaceMark = iFaceMark;
1341
/*! Sets the normal to the Face it is running accross. */
1342
inline void setNormal(const Vec3r& iNormal)
1347
/*! Sets the index of the material of the face it is running accross. */
1348
inline void setFrsMaterialIndex(unsigned i)
1350
_FrsMaterialIndex = i;
1355
/**********************************/
1361
/**********************************/
1364
/*! Class to define a feature shape. It is the gathering of feature elements from an identified input shape */
1365
class LIB_VIEW_MAP_EXPORT SShape
1368
vector<FEdge*> _chains; // list of fedges that are chains starting points.
1369
vector<SVertex*> _verticesList; // list of all vertices
1370
vector<FEdge*> _edgesList; // list of all edges
1374
vector<FrsMaterial> _FrsMaterials;
1378
ViewShape *_ViewShape;
1381
/*! A field that can be used by the user to store any data.
1382
* This field must be reseted afterwards using ResetUserData().
1384
void *userdata; // added by E.T.
1386
/*! Default constructor */
1394
/*! Copy constructor */
1395
inline SShape(SShape& iBrother)
1399
_Name = iBrother._Name;
1400
_BBox = iBrother.bbox();
1401
_FrsMaterials = iBrother._FrsMaterials;
1402
_importance = iBrother._importance;
1403
_ViewShape = iBrother._ViewShape;
1408
vector<SVertex*>::iterator sv, svend;
1409
vector<SVertex*>& verticesList = iBrother.getVertexList();
1410
for (sv = verticesList.begin(), svend = verticesList.end(); sv != svend; sv++) {
1411
SVertex *newv = new SVertex(*(*sv));
1412
newv->setShape(this);
1413
_verticesList.push_back(newv);
1419
vector<FEdge*>::iterator e, eend;
1420
vector<FEdge*>& edgesList = iBrother.getEdgeList();
1421
for (e = edgesList.begin(), eend = edgesList.end(); e != eend; e++) {
1422
FEdge *newe = (*e)->duplicate();
1423
_edgesList.push_back(newe);
1426
//-------------------------
1427
// starting chain edges
1428
//-------------------------
1429
vector<FEdge*>::iterator fe, fend;
1430
vector<FEdge*>& fedges = iBrother.getChains();
1431
for (fe = fedges.begin(), fend = fedges.end(); fe != fend; fe++) {
1432
_chains.push_back((FEdge *)((*fe)->userdata));
1435
//-------------------------
1436
// remap edges in vertices:
1437
//-------------------------
1438
for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
1439
const vector<FEdge*>& fedgeList = (*sv)->fedges();
1440
vector<FEdge*> newfedgelist;
1441
for (vector<FEdge*>::const_iterator fed = fedgeList.begin(), fedend = fedgeList.end();
1445
FEdge *current = *fed;
1446
newfedgelist.push_back((FEdge *)current->userdata);
1448
(*sv)->setFEdges(newfedgelist);
1451
//-------------------------------------
1452
// remap vertices and nextedge in edges:
1453
//-------------------------------------
1454
for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
1455
(*e)->setVertexA((SVertex *)((*e)->vertexA()->userdata));
1456
(*e)->setVertexB((SVertex *)((*e)->vertexB()->userdata));
1457
(*e)->setNextEdge((FEdge *)((*e)->nextEdge()->userdata));
1458
(*e)->setPreviousEdge((FEdge *)((*e)->previousEdge()->userdata));
1461
// reset all brothers userdata to NULL:
1462
//-------------------------------------
1466
for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
1467
(*sv)->userdata = NULL;
1473
for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
1474
(*e)->userdata = NULL;
1478
/*! Cloning method. */
1479
virtual SShape *duplicate()
1481
SShape *clone = new SShape(*this);
1486
virtual inline ~SShape()
1488
vector<SVertex*>::iterator sv, svend;
1489
vector<FEdge*>::iterator e, eend;
1490
if (0 != _verticesList.size()) {
1491
for (sv = _verticesList.begin(), svend = _verticesList.end(); sv != svend; sv++) {
1494
_verticesList.clear();
1497
if (0 != _edgesList.size()) {
1498
for (e = _edgesList.begin(), eend = _edgesList.end(); e != eend; e++) {
1504
//! Clear the chains list
1505
//-----------------------
1506
if (0 != _chains.size()) {
1511
/*! Adds a FEdge to the list of FEdges. */
1512
inline void AddEdge(FEdge *iEdge)
1514
_edgesList.push_back(iEdge);
1517
/*! Adds a SVertex to the list of SVertex of this Shape.
1518
* The SShape attribute of the SVertex is also set to 'this'.
1520
inline void AddNewVertex(SVertex *iv)
1523
_verticesList.push_back(iv);
1526
inline void AddChain(FEdge *iEdge)
1528
_chains.push_back(iEdge);
1531
inline SVertex *CreateSVertex(const Vec3r& P3D, const Vec3r& P2D, const Id& id)
1533
SVertex *Ia = new SVertex(P3D, id);
1534
Ia->setPoint2D(P2D);
1539
/*! Splits an edge into several edges.
1540
* The edge's vertices are passed rather than the edge itself. This way, all feature edges (SILHOUETTE,
1541
* CREASE, BORDER) are splitted in the same time.
1542
* The processed edges are flagged as done (using the userdata flag).One single new vertex is created whereas
1543
* several splitted edges might created for the different kinds of edges. These new elements are added to the lists
1544
* maintained by the shape.
1545
* New chains are also created.
1547
* The first vertex for the edge that gets splitted
1549
* The second vertex for the edge that gets splitted
1551
* A vector containing 2D real vectors indicating the parameters giving the intersections coordinates in
1552
* 3D and in 2D. These intersections points must be sorted from B to A.
1553
* Each parameter defines the intersection point I as I=A+T*AB. T<0 and T>1 are then incorrect insofar as
1554
* they give intersections points that lie outside the segment.
1556
* The edges that are newly created (the initial edges are not included) are added to this list.
1558
inline void SplitEdge(FEdge *fe, const vector<Vec2r>& iParameters, vector<FEdge*>& ioNewEdges)
1560
SVertex *ioA = fe->vertexA();
1561
SVertex *ioB = fe->vertexB();
1562
Vec3r A = ioA->point3D();
1563
Vec3r B = ioB->point3D();
1564
Vec3r a = ioA->point2D();
1565
Vec3r b = ioB->point2D();
1567
Vec3r newpoint3d, newpoint2d;
1568
vector<SVertex*> intersections;
1570
for (vector<Vec2r>::const_iterator p = iParameters.begin(), pend = iParameters.end(); p != pend; p++) {
1574
if ((t < 0) || (t > 1))
1575
cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - " << ioB->getId() << endl;
1577
// compute the 3D and 2D coordinates for the intersections points:
1578
newpoint3d = Vec3r(A + T * (B - A));
1579
newpoint2d = Vec3r(a + t * (b - a));
1581
// create new SVertex:
1583
SVertex *newVertex = new SVertex(newpoint3d, ioB->getId());
1584
newVertex->setPoint2D(newpoint2d);
1586
// Add this vertex to the intersections list:
1587
intersections.push_back(newVertex);
1589
// Add this vertex to this sshape:
1590
AddNewVertex(newVertex);
1593
for (vector<SVertex*>::iterator sv = intersections.begin(), svend = intersections.end(); sv != svend; sv++) {
1594
//SVertex *svA = fe->vertexA();
1595
SVertex *svB = fe->vertexB();
1597
// We split edge AB into AA' and A'B. A' and A'B are created.
1598
// AB becomes (address speaking) AA'. B is updated.
1599
//--------------------------------------------------
1600
// The edge AB becomes edge AA'.
1601
(fe)->setVertexB((*sv));
1602
// a new edge, A'B is created.
1604
if (fe->isSmooth()) {
1605
newEdge = new FEdgeSmooth((*sv), svB);
1606
FEdgeSmooth *se = dynamic_cast<FEdgeSmooth*>(newEdge);
1607
FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(fe);
1608
se->setFrsMaterialIndex(fes->frs_materialIndex());
1611
newEdge = new FEdgeSharp((*sv), svB);
1612
FEdgeSharp *se = dynamic_cast<FEdgeSharp*>(newEdge);
1613
FEdgeSharp *fes = dynamic_cast<FEdgeSharp*>(fe);
1614
se->setaFrsMaterialIndex(fes->aFrsMaterialIndex());
1615
se->setbFrsMaterialIndex(fes->bFrsMaterialIndex());
1618
newEdge->setNature((fe)->getNature());
1620
// to build a new chain:
1622
// add the new edge to the sshape edges list.
1624
// add new edge to the list of new edges passed as argument:
1625
ioNewEdges.push_back(newEdge);
1627
// update edge A'B for the next pointing edge
1628
newEdge->setNextEdge((fe)->nextEdge());
1629
fe->nextEdge()->setPreviousEdge(newEdge);
1630
Id id(fe->getId().getFirst(), fe->getId().getSecond() + 1);
1631
newEdge->setId(fe->getId());
1634
// update edge AA' for the next pointing edge
1635
//ioEdge->setNextEdge(newEdge);
1636
(fe)->setNextEdge(NULL);
1638
// update vertex pointing edges list:
1640
svB->Replace((fe), newEdge);
1642
(*sv)->AddFEdge((fe));
1643
(*sv)->AddFEdge(newEdge);
1647
/* splits an edge into 2 edges. The new vertex and edge are added to the sshape list of vertices and edges
1648
* a new chain is also created.
1649
* returns the new edge.
1651
* The edge that gets splitted
1653
* x,y,z coordinates of the new point.
1655
inline FEdge *SplitEdgeIn2(FEdge *ioEdge, SVertex *ioNewVertex)
1657
//soc unused - SVertex *A = ioEdge->vertexA();
1658
SVertex *B = ioEdge->vertexB();
1660
// We split edge AB into AA' and A'B. A' and A'B are created.
1661
// AB becomes (address speaking) AA'. B is updated.
1662
//--------------------------------------------------
1663
// a new edge, A'B is created.
1665
if (ioEdge->isSmooth()) {
1666
newEdge = new FEdgeSmooth(ioNewVertex, B);
1667
FEdgeSmooth *se = dynamic_cast<FEdgeSmooth*>(newEdge);
1668
FEdgeSmooth *fes = dynamic_cast<FEdgeSmooth*>(ioEdge);
1669
se->setNormal(fes->normal());
1670
se->setFrsMaterialIndex(fes->frs_materialIndex());
1671
se->setFaceMark(fes->faceMark());
1674
newEdge = new FEdgeSharp(ioNewVertex, B);
1675
FEdgeSharp *se = dynamic_cast<FEdgeSharp*>(newEdge);
1676
FEdgeSharp *fes = dynamic_cast<FEdgeSharp*>(ioEdge);
1677
se->setNormalA(fes->normalA());
1678
se->setNormalB(fes->normalB());
1679
se->setaFrsMaterialIndex(fes->aFrsMaterialIndex());
1680
se->setbFrsMaterialIndex(fes->bFrsMaterialIndex());
1681
se->setaFaceMark(fes->aFaceMark());
1682
se->setbFaceMark(fes->bFaceMark());
1684
newEdge->setNature(ioEdge->getNature());
1686
if (ioEdge->nextEdge() != 0)
1687
ioEdge->nextEdge()->setPreviousEdge(newEdge);
1689
// update edge A'B for the next pointing edge
1690
newEdge->setNextEdge(ioEdge->nextEdge());
1691
// update edge A'B for the previous pointing edge
1692
newEdge->setPreviousEdge(0); // because it is now a TVertex
1693
Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1);
1694
newEdge->setId(ioEdge->getId());
1697
// update edge AA' for the next pointing edge
1698
ioEdge->setNextEdge(0); // because it is now a TVertex
1700
// update vertex pointing edges list:
1702
B->Replace(ioEdge, newEdge);
1704
ioNewVertex->AddFEdge(ioEdge);
1705
ioNewVertex->AddFEdge(newEdge);
1707
// to build a new chain:
1709
AddEdge(newEdge); // FIXME ??
1711
// The edge AB becomes edge AA'.
1712
ioEdge->setVertexB(ioNewVertex);
1714
if (ioEdge->isSmooth()) {
1715
((FEdgeSmooth *)newEdge)->setFace(((FEdgeSmooth *)ioEdge)->face());
1721
/*! Sets the Bounding Box of the Shape */
1722
inline void setBBox(const BBox<Vec3r>& iBBox)
1727
/*! Compute the bbox of the sshape */
1728
inline void ComputeBBox()
1730
if (0 == _verticesList.size())
1733
Vec3r firstVertex = _verticesList[0]->point3D();
1734
real XMax = firstVertex[0];
1735
real YMax = firstVertex[1];
1736
real ZMax = firstVertex[2];
1738
real XMin = firstVertex[0];
1739
real YMin = firstVertex[1];
1740
real ZMin = firstVertex[2];
1742
vector<SVertex*>::iterator v, vend;
1743
// parse all the coordinates to find the Xmax, YMax, ZMax
1744
for (v = _verticesList.begin(), vend = _verticesList.end(); v != vend; v++) {
1745
Vec3r vertex = (*v)->point3D();
1768
setBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax)));
1771
inline void RemoveEdgeFromChain(FEdge *iEdge)
1773
for (vector<FEdge*>::iterator fe = _chains.begin(), feend = _chains.end(); fe != feend; fe++) {
1774
if (iEdge == (*fe)) {
1781
inline void RemoveEdge(FEdge *iEdge)
1783
for (vector<FEdge*>::iterator fe = _edgesList.begin(), feend = _edgesList.end(); fe != feend; fe++) {
1784
if (iEdge == (*fe)) {
1785
_edgesList.erase(fe);
1792
/*! Returns the list of SVertex of the Shape. */
1793
inline vector<SVertex*>& getVertexList()
1795
return _verticesList;
1798
/*! Returns the list of FEdges of the Shape. */
1799
inline vector<FEdge*>& getEdgeList()
1804
inline vector<FEdge*>& getChains()
1809
/*! Returns the bounding box of the shape. */
1810
inline const BBox<Vec3r>& bbox()
1815
/*! Returns the ith material of the shape. */
1816
inline const FrsMaterial& frs_material(unsigned i) const
1818
return _FrsMaterials[i];
1821
/*! Returns the list of materials of the Shape. */
1822
inline const vector<FrsMaterial>& frs_materials() const
1824
return _FrsMaterials;
1827
inline ViewShape *viewShape()
1832
inline float importance() const
1837
/*! Returns the Id of the Shape. */
1838
inline Id getId() const
1843
/*! Returns the name of the Shape. */
1844
inline const string& getName() const
1850
/*! Sets the Id of the shape.*/
1851
inline void setId(Id id)
1856
/*! Sets the name of the shape.*/
1857
inline void setName(const string& name)
1862
/*! Sets the list of materials for the shape */
1863
inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials)
1865
_FrsMaterials = iMaterials;
1868
inline void setViewShape(ViewShape *iShape)
1870
_ViewShape = iShape;
1873
inline void setImportance(float importance)
1875
_importance = importance;
1878
#ifdef WITH_CXX_GUARDEDALLOC
1879
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SShape")
1883
} /* namespace Freestyle */
1885
#endif // __FREESTYLE_SILHOUETTE_H__