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_WX_EDGE_H__
22
#define __FREESTYLE_WX_EDGE_H__
24
/** \file blender/freestyle/intern/winged_edge/WXEdge.h
26
* \brief Classes to define an Extended Winged Edge data structure.
27
* \author Stephane Grabli
31
#include "Curvature.h"
35
#ifdef WITH_CXX_GUARDEDALLOC
36
#include "MEM_guardedalloc.h"
41
typedef Nature::EdgeNature WXNature;
43
/**********************************
49
**********************************/
51
class WXVertex : public WVertex
55
CurvatureInfo *_curvatures;
58
inline WXVertex(const Vec3r &v) : WVertex(v)
63
/*! Copy constructor */
64
WXVertex(WXVertex& iBrother) : WVertex(iBrother)
66
_curvatures = new CurvatureInfo(*iBrother._curvatures);
69
virtual WVertex *duplicate()
71
WXVertex *clone = new WXVertex(*this);
84
_curvatures->Kr = 0.0;
87
inline void setCurvatures(CurvatureInfo *ci)
92
inline bool isFeature();
94
inline CurvatureInfo *curvatures()
101
/**********************************
107
**********************************/
109
class WXEdge : public WEdge
112
// flag to indicate whether the edge is a silhouette edge or not
114
// 0: the order doesn't matter. 1: the order is the orginal one. -1: the order is not good
116
// A front facing edge is an edge for which the bording face which is the nearest from the viewpoint is front.
117
// A back facing edge is the opposite.
121
inline WXEdge() : WEdge()
123
_nature = Nature::NO_FEATURE;
128
inline WXEdge(WOEdge *iOEdge) : WEdge(iOEdge)
130
_nature = Nature::NO_FEATURE;
135
inline WXEdge(WOEdge *iaOEdge, WOEdge *ibOEdge) : WEdge(iaOEdge, ibOEdge)
137
_nature = Nature::NO_FEATURE;
142
/*! Copy constructor */
143
inline WXEdge(WXEdge& iBrother) : WEdge(iBrother)
145
_nature = iBrother.nature();
146
_front = iBrother._front;
147
_order = iBrother._order;
150
virtual WEdge *duplicate()
152
WXEdge *clone = new WXEdge(*this);
160
_nature = _nature & ~Nature::SILHOUETTE;
161
_nature = _nature & ~Nature::SUGGESTIVE_CONTOUR;
165
inline WXNature nature()
175
inline int order() const
181
inline void setFront(bool iFront)
186
inline void setNature(WXNature iNature)
191
inline void AddNature(WXNature iNature)
193
_nature = _nature | iNature;
196
inline void setOrder(int i)
202
/**********************************
208
**********************************/
210
/*! Class to store a smooth edge (i.e Hertzman & Zorin smooth silhouette edges) */
220
WOEdge *_woea; // Oriented edge from which the silhouette edge starts
221
WOEdge *_woeb; // Oriented edge where the silhouette edge ends
222
real _ta; // The silhouette starting point's coordinates are : _woea[0]+ta*(_woea[1]-_woea[0])
223
real _tb; // The silhouette ending point's coordinates are : _woeb[0]+ta*(_woeb[1]-_woeb[0])
225
Configuration _config;
237
WXSmoothEdge(const WXSmoothEdge& iBrother)
239
_woea = iBrother._woea;
240
_woeb = iBrother._woeb;
243
_config = iBrother._config;
244
_front = iBrother._front;
249
inline WOEdge *woea()
254
inline WOEdge *woeb()
259
inline real ta() const
264
inline real tb() const
269
inline bool front() const
274
inline Configuration configuration() const
280
inline void setWOeA(WOEdge *iwoea)
285
inline void setWOeB(WOEdge *iwoeb)
290
inline void setTa(real ta)
295
inline void setTb(real tb)
300
inline void setFront(bool iFront)
305
inline void setConfiguration(Configuration iConf)
310
#ifdef WITH_CXX_GUARDEDALLOC
311
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXSmoothEdge")
315
/* Class to store a value per vertex and a smooth edge.
316
* The WXFace stores a list of these
320
class LIB_WINGED_EDGE_EXPORT WXFaceLayer
325
// in case of silhouette: the values obtained when computing the normal-view direction dot product. _DotP[i] is
326
// this value for the vertex i for that face.
328
WXSmoothEdge *_pSmoothEdge;
332
// count the number of positive dot products for vertices.
333
// if this number is != 0 and !=_DotP.size() -> it is a silhouette fac
336
unsigned _nNullDotP; // count the number of null dot products for vertices.
337
unsigned _ClosestPointIndex;
340
WXFaceLayer(WXFace *iFace, WXNature iNature, bool viewDependant)
347
_viewDependant = viewDependant;
351
WXFaceLayer(const WXFaceLayer& iBrother)
353
_pWXFace = iBrother._pWXFace;
355
_DotP = iBrother._DotP;
356
_nPosDotP = iBrother._nPosDotP;
357
_nNullDotP = iBrother._nNullDotP;
358
_Nature = iBrother._Nature;
359
if (iBrother._pSmoothEdge) { // XXX ? It's set to null a few lines above!
360
_pSmoothEdge = new WXSmoothEdge(*(iBrother._pSmoothEdge));
362
_viewDependant = iBrother._viewDependant;
366
virtual ~WXFaceLayer()
376
inline const real dotP(int i) const
381
inline unsigned nPosDotP() const
386
inline unsigned nNullDotP() const
391
inline int closestPointIndex() const
393
return _ClosestPointIndex;
396
inline Nature::EdgeNature nature() const
401
inline bool hasSmoothEdge() const
408
inline WXFace *getFace()
413
inline WXSmoothEdge *getSmoothEdge()
418
inline bool isViewDependant() const
420
return _viewDependant;
423
inline void setClosestPointIndex(int iIndex)
425
_ClosestPointIndex = iIndex;
428
inline void removeSmoothEdge()
438
/*! If one of the face layer vertex has a DotP equal to 0, this method returns the vertex where it happens */
439
unsigned int Get0VertexIndex() const;
441
/*! In case one of the edge of the triangle is a smooth edge, this method allows to retrieve the concerned edge */
442
unsigned int GetSmoothEdgeIndex() const;
444
/*! retrieves the edges of the triangle for which the signs are different (a null value is not considered) for
445
* the dotp values at each edge extrimity
447
void RetrieveCuspEdgesIndices(vector<int>& oCuspEdges);
449
WXSmoothEdge *BuildSmoothEdge();
451
inline void setDotP(const vector<real>& iDotP)
456
inline void PushDotP(real iDotP)
458
_DotP.push_back(iDotP);
465
inline void ReplaceDotP(unsigned int index, real newDotP)
467
_DotP[index] = newDotP;
471
inline void updateDotPInfos()
475
for (vector<real>::iterator d = _DotP.begin(), dend = _DotP.end(); d != dend; ++d) {
483
#ifdef WITH_CXX_GUARDEDALLOC
484
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXFaceLayer")
488
class WXFace : public WFace
491
Vec3r _center; // center of the face
492
real _Z; // distance from viewpoint to the center of the face
493
bool _front; // flag to tell whether the face is front facing or back facing
494
real _dotp; // value obtained when computing the normal-viewpoint dot product
496
vector<WXFaceLayer *> _SmoothLayers; // The data needed to store one or several smooth edges that traverse the face
499
inline WXFace() : WFace()
505
/*! Copy constructor */
506
WXFace(WXFace& iBrother) : WFace(iBrother)
508
_center = iBrother.center();
510
_front = iBrother.front();
511
for (vector<WXFaceLayer*>::iterator wxf = iBrother._SmoothLayers.begin(), wxfend = iBrother._SmoothLayers.end();
515
_SmoothLayers.push_back(new WXFaceLayer(**wxf));
519
virtual WFace *duplicate()
521
WXFace *clone = new WXFace(*this);
527
if (!_SmoothLayers.empty()) {
528
for (vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
534
_SmoothLayers.clear();
538
/*! designed to build a specialized WEdge for use in MakeEdge */
539
virtual WEdge *instanciateEdge() const
545
inline Vec3r& center()
565
inline bool hasSmoothEdges() const
567
for (vector<WXFaceLayer*>::const_iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
571
if ((*wxf)->hasSmoothEdge()) {
578
vector<WXFaceLayer*>& getSmoothLayers()
580
return _SmoothLayers;
583
/*! retrieve the smooth edges that match the Nature given as argument */
584
void retrieveSmoothEdges(WXNature iNature, vector<WXSmoothEdge *>& oSmoothEdges)
586
for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
590
if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) {
591
oSmoothEdges.push_back((*wxf)->_pSmoothEdge);
596
void retrieveSmoothEdgesLayers(WXNature iNature, vector<WXFaceLayer *>& oSmoothEdgesLayers)
598
for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
602
if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) {
603
oSmoothEdgesLayers.push_back((*wxf));
608
void retrieveSmoothLayers(WXNature iNature, vector<WXFaceLayer *>& oSmoothLayers)
610
for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
614
if ((*wxf)->_Nature & iNature) {
615
oSmoothLayers.push_back(*wxf);
621
inline void setCenter(const Vec3r& iCenter)
626
void ComputeCenter();
628
inline void setZ(real z)
633
inline void setFront(bool iFront)
638
inline void setDotP(real iDotP)
647
inline void AddSmoothLayer(WXFaceLayer *iLayer)
649
_SmoothLayers.push_back(iLayer);
654
vector<WXFaceLayer *> layersToKeep;
655
for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
659
if ((*wxf)->isViewDependant())
662
layersToKeep.push_back(*wxf);
664
_SmoothLayers = layersToKeep;
667
/*! Clears everything */
670
for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
676
_SmoothLayers.clear();
679
virtual void ResetUserData()
681
WFace::ResetUserData();
682
for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
686
(*wxf)->userdata = NULL;
692
/**********************************
698
**********************************/
700
class WXShape : public WShape
703
typedef WXShape type_name;
706
bool _computeViewIndependant; // flag to indicate whether the view independant stuff must be computed or not
709
inline WXShape() : WShape()
711
_computeViewIndependant = true;
714
/*! copy constructor */
715
inline WXShape(WXShape& iBrother) : WShape(iBrother)
717
_computeViewIndependant = iBrother._computeViewIndependant;
720
virtual WShape *duplicate()
722
WXShape *clone = new WXShape(*this);
726
virtual ~WXShape() {}
728
inline bool getComputeViewIndependantFlag() const
730
return _computeViewIndependant;
733
inline void setComputeViewIndependantFlag(bool iFlag)
735
_computeViewIndependant = iFlag;
738
/*! designed to build a specialized WFace for use in MakeFace */
739
virtual WFace *instanciateFace() const
744
/*! adds a new face to the shape returns the built face.
746
* List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed
747
* to be already stored when calling MakeFace. The order in which the vertices are stored in the list
748
* determines the face's edges orientation and (so) the face orientation.
750
virtual WFace *MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
752
/*! adds a new face to the shape. The difference with the previous method is that this one is designed to build
753
* a WingedEdge structure for which there are per vertex normals, opposed to per face normals.
754
* returns the built face.
756
* List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be
757
* already stored when calling MakeFace.
758
* The order in which the vertices are stored in the list determines the face's edges orientation and (so) the
761
* The list of normals, iNormalsList[i] corresponding to the normal of the vertex iVertexList[i] for that face.
763
* The list of tex coords, iTexCoordsList[i] corresponding to the normal of the vertex iVertexList[i] for
766
virtual WFace *MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
767
vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
769
/*! Reset all edges and vertices flags (which might have been set up on a previous pass) */
773
vector<WEdge *>& wedges = getEdgeList();
774
for (vector<WEdge *>::iterator we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
775
((WXEdge *)(*we))->Reset();
779
vector<WFace *>& wfaces = GetFaceList();
780
for (vector<WFace *>::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; ++wf) {
781
((WXFace *)(*wf))->Reset();
789
#############################################
790
#############################################
791
#############################################
793
###### I M P L E M E N T A T I O N ######
795
#############################################
796
#############################################
797
#############################################
800
/* for inline functions */
802
bool WXVertex::isFeature()
805
vector<WEdge *>& vedges = GetEdges();
806
for (vector<WEdge *>::iterator ve = vedges.begin(), vend = vedges.end(); ve != vend; ++ve) {
807
if (((WXEdge *)(*ve))->nature() != Nature::NO_FEATURE)
811
if ((counter == 1) || (counter > 2))
816
} /* namespace Freestyle */
818
#endif // __FREESTYLE_WX_EDGE_H__