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()
99 #ifdef WITH_CXX_GUARDEDALLOC
100 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXVertex")
105 /**********************************
111 **********************************/
113 class WXEdge : public WEdge
116 // flag to indicate whether the edge is a silhouette edge or not
118 // 0: the order doesn't matter. 1: the order is the orginal one. -1: the order is not good
120 // A front facing edge is an edge for which the bording face which is the nearest from the viewpoint is front.
121 // A back facing edge is the opposite.
125 inline WXEdge() : WEdge()
127 _nature = Nature::NO_FEATURE;
132 inline WXEdge(WOEdge *iOEdge) : WEdge(iOEdge)
134 _nature = Nature::NO_FEATURE;
139 inline WXEdge(WOEdge *iaOEdge, WOEdge *ibOEdge) : WEdge(iaOEdge, ibOEdge)
141 _nature = Nature::NO_FEATURE;
146 /*! Copy constructor */
147 inline WXEdge(WXEdge& iBrother) : WEdge(iBrother)
149 _nature = iBrother.nature();
150 _front = iBrother._front;
151 _order = iBrother._order;
154 virtual WEdge *duplicate()
156 WXEdge *clone = new WXEdge(*this);
164 _nature = _nature & ~Nature::SILHOUETTE;
165 _nature = _nature & ~Nature::SUGGESTIVE_CONTOUR;
169 inline WXNature nature()
179 inline short order() const
185 inline void setFront(bool iFront)
190 inline void setNature(WXNature iNature)
195 inline void AddNature(WXNature iNature)
197 _nature = _nature | iNature;
200 inline void setOrder(int i)
205 #ifdef WITH_CXX_GUARDEDALLOC
206 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXEdge")
210 /**********************************
216 **********************************/
218 /*! Class to store a smooth edge (i.e Hertzman & Zorin smooth silhouette edges) */
222 typedef unsigned short Configuration;
223 static const Configuration EDGE_EDGE = 1;
224 static const Configuration VERTEX_EDGE = 2;
225 static const Configuration EDGE_VERTEX = 3;
227 WOEdge *_woea; // Oriented edge from which the silhouette edge starts
228 WOEdge *_woeb; // Oriented edge where the silhouette edge ends
229 real _ta; // The silhouette starting point's coordinates are : _woea[0]+ta*(_woea[1]-_woea[0])
230 real _tb; // The silhouette ending point's coordinates are : _woeb[0]+ta*(_woeb[1]-_woeb[0])
232 Configuration _config;
244 WXSmoothEdge(const WXSmoothEdge& iBrother)
246 _woea = iBrother._woea;
247 _woeb = iBrother._woeb;
250 _config = iBrother._config;
251 _front = iBrother._front;
256 inline WOEdge *woea()
261 inline WOEdge *woeb()
266 inline real ta() const
271 inline real tb() const
276 inline bool front() const
281 inline Configuration configuration() const
287 inline void setWOeA(WOEdge *iwoea)
292 inline void setWOeB(WOEdge *iwoeb)
297 inline void setTa(real ta)
302 inline void setTb(real tb)
307 inline void setFront(bool iFront)
312 inline void setConfiguration(Configuration iConf)
317 #ifdef WITH_CXX_GUARDEDALLOC
318 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXSmoothEdge")
322 /* Class to store a value per vertex and a smooth edge.
323 * The WXFace stores a list of these
332 // in case of silhouette: the values obtained when computing the normal-view direction dot product. _DotP[i] is
333 // this value for the vertex i for that face.
335 WXSmoothEdge *_pSmoothEdge;
339 // count the number of positive dot products for vertices.
340 // if this number is != 0 and !=_DotP.size() -> it is a silhouette fac
343 unsigned _nNullDotP; // count the number of null dot products for vertices.
344 unsigned _ClosestPointIndex;
347 WXFaceLayer(WXFace *iFace, WXNature iNature, bool viewDependant)
354 _viewDependant = viewDependant;
358 WXFaceLayer(const WXFaceLayer& iBrother)
360 _pWXFace = iBrother._pWXFace;
362 _DotP = iBrother._DotP;
363 _nPosDotP = iBrother._nPosDotP;
364 _nNullDotP = iBrother._nNullDotP;
365 _Nature = iBrother._Nature;
366 if (iBrother._pSmoothEdge) { // XXX ? It's set to null a few lines above!
367 _pSmoothEdge = new WXSmoothEdge(*(iBrother._pSmoothEdge));
369 _viewDependant = iBrother._viewDependant;
373 virtual ~WXFaceLayer()
383 inline const real dotP(int i) const
388 inline unsigned nPosDotP() const
393 inline unsigned nNullDotP() const
398 inline int closestPointIndex() const
400 return _ClosestPointIndex;
403 inline WXNature nature() const
408 inline bool hasSmoothEdge() const
415 inline WXFace *getFace()
420 inline WXSmoothEdge *getSmoothEdge()
425 inline bool isViewDependant() const
427 return _viewDependant;
430 inline void setClosestPointIndex(int iIndex)
432 _ClosestPointIndex = iIndex;
435 inline void removeSmoothEdge()
445 /*! If one of the face layer vertex has a DotP equal to 0, this method returns the vertex where it happens */
446 unsigned int Get0VertexIndex() const;
448 /*! In case one of the edge of the triangle is a smooth edge, this method allows to retrieve the concerned edge */
449 unsigned int GetSmoothEdgeIndex() const;
451 /*! retrieves the edges of the triangle for which the signs are different (a null value is not considered) for
452 * the dotp values at each edge extrimity
454 void RetrieveCuspEdgesIndices(vector<int>& oCuspEdges);
456 WXSmoothEdge *BuildSmoothEdge();
458 inline void setDotP(const vector<real>& iDotP)
463 inline void PushDotP(real iDotP)
465 _DotP.push_back(iDotP);
472 inline void ReplaceDotP(unsigned int index, real newDotP)
474 _DotP[index] = newDotP;
478 inline void updateDotPInfos()
482 for (vector<real>::iterator d = _DotP.begin(), dend = _DotP.end(); d != dend; ++d) {
490 #ifdef WITH_CXX_GUARDEDALLOC
491 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXFaceLayer")
495 class WXFace : public WFace
498 Vec3r _center; // center of the face
499 real _Z; // distance from viewpoint to the center of the face
500 bool _front; // flag to tell whether the face is front facing or back facing
501 real _dotp; // value obtained when computing the normal-viewpoint dot product
503 vector<WXFaceLayer *> _SmoothLayers; // The data needed to store one or several smooth edges that traverse the face
506 inline WXFace() : WFace()
512 /*! Copy constructor */
513 WXFace(WXFace& iBrother) : WFace(iBrother)
515 _center = iBrother.center();
517 _front = iBrother.front();
518 for (vector<WXFaceLayer*>::iterator wxf = iBrother._SmoothLayers.begin(), wxfend = iBrother._SmoothLayers.end();
522 _SmoothLayers.push_back(new WXFaceLayer(**wxf));
526 virtual WFace *duplicate()
528 WXFace *clone = new WXFace(*this);
534 if (!_SmoothLayers.empty()) {
535 for (vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
541 _SmoothLayers.clear();
545 /*! designed to build a specialized WEdge for use in MakeEdge */
546 virtual WEdge *instanciateEdge() const
552 inline Vec3r& center()
572 inline bool hasSmoothEdges() const
574 for (vector<WXFaceLayer*>::const_iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
578 if ((*wxf)->hasSmoothEdge()) {
585 vector<WXFaceLayer*>& getSmoothLayers()
587 return _SmoothLayers;
590 /*! retrieve the smooth edges that match the Nature given as argument */
591 void retrieveSmoothEdges(WXNature iNature, vector<WXSmoothEdge *>& oSmoothEdges)
593 for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
597 if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) {
598 oSmoothEdges.push_back((*wxf)->_pSmoothEdge);
603 void retrieveSmoothEdgesLayers(WXNature iNature, vector<WXFaceLayer *>& oSmoothEdgesLayers)
605 for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
609 if ((*wxf)->hasSmoothEdge() && ((*wxf)->_Nature & iNature)) {
610 oSmoothEdgesLayers.push_back((*wxf));
615 void retrieveSmoothLayers(WXNature iNature, vector<WXFaceLayer *>& oSmoothLayers)
617 for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
621 if ((*wxf)->_Nature & iNature) {
622 oSmoothLayers.push_back(*wxf);
628 inline void setCenter(const Vec3r& iCenter)
633 void ComputeCenter();
635 inline void setZ(real z)
640 inline void setFront(bool iFront)
645 inline void setDotP(real iDotP)
654 inline void AddSmoothLayer(WXFaceLayer *iLayer)
656 _SmoothLayers.push_back(iLayer);
661 vector<WXFaceLayer *> layersToKeep;
662 for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
666 if ((*wxf)->isViewDependant())
669 layersToKeep.push_back(*wxf);
671 _SmoothLayers = layersToKeep;
674 /*! Clears everything */
677 for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
683 _SmoothLayers.clear();
686 virtual void ResetUserData()
688 WFace::ResetUserData();
689 for (vector<WXFaceLayer *>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end();
693 (*wxf)->userdata = NULL;
697 #ifdef WITH_CXX_GUARDEDALLOC
698 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXFace")
703 /**********************************
709 **********************************/
711 class WXShape : public WShape
714 typedef WXShape type_name;
717 bool _computeViewIndependent; // flag to indicate whether the view independent stuff must be computed or not
720 inline WXShape() : WShape()
722 _computeViewIndependent = true;
725 /*! copy constructor */
726 inline WXShape(WXShape& iBrother) : WShape(iBrother)
728 _computeViewIndependent = iBrother._computeViewIndependent;
731 virtual WShape *duplicate()
733 WXShape *clone = new WXShape(*this);
737 virtual ~WXShape() {}
739 inline bool getComputeViewIndependentFlag() const
741 return _computeViewIndependent;
744 inline void setComputeViewIndependentFlag(bool iFlag)
746 _computeViewIndependent = iFlag;
749 /*! designed to build a specialized WFace for use in MakeFace */
750 virtual WFace *instanciateFace() const
755 /*! adds a new face to the shape returns the built face.
757 * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed
758 * to be already stored when calling MakeFace. The order in which the vertices are stored in the list
759 * determines the face's edges orientation and (so) the face orientation.
761 virtual WFace *MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
763 /*! adds a new face to the shape. The difference with the previous method is that this one is designed to build
764 * a WingedEdge structure for which there are per vertex normals, opposed to per face normals.
765 * returns the built face.
767 * List of face's vertices. These vertices are not added to the WShape vertex list; they are supposed to be
768 * already stored when calling MakeFace.
769 * The order in which the vertices are stored in the list determines the face's edges orientation and (so) the
772 * The list of normals, iNormalsList[i] corresponding to the normal of the vertex iVertexList[i] for that face.
774 * The list of tex coords, iTexCoordsList[i] corresponding to the normal of the vertex iVertexList[i] for
777 virtual WFace *MakeFace(vector<WVertex *>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList,
778 vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex);
780 /*! Reset all edges and vertices flags (which might have been set up on a previous pass) */
784 vector<WEdge *>& wedges = getEdgeList();
785 for (vector<WEdge *>::iterator we = wedges.begin(), weend = wedges.end(); we != weend; ++we) {
786 ((WXEdge *)(*we))->Reset();
790 vector<WFace *>& wfaces = GetFaceList();
791 for (vector<WFace *>::iterator wf = wfaces.begin(), wfend = wfaces.end(); wf != wfend; ++wf) {
792 ((WXFace *)(*wf))->Reset();
797 #ifdef WITH_CXX_GUARDEDALLOC
798 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXShape")
804 #############################################
805 #############################################
806 #############################################
808 ###### I M P L E M E N T A T I O N ######
810 #############################################
811 #############################################
812 #############################################
815 /* for inline functions */
817 bool WXVertex::isFeature()
820 vector<WEdge *>& vedges = GetEdges();
821 for (vector<WEdge *>::iterator ve = vedges.begin(), vend = vedges.end(); ve != vend; ++ve) {
822 if (((WXEdge *)(*ve))->nature() != Nature::NO_FEATURE)
826 if ((counter == 1) || (counter > 2))
831 } /* namespace Freestyle */
833 #endif // __FREESTYLE_WX_EDGE_H__