1 /* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License 4 * as published by the Free Software Foundation; either version 2 5 * of the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software Foundation, 14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 */ 16 17 #pragma once 18 19 /** \file 20 * \ingroup freestyle 21 * \brief Detects/flags/builds extended features edges on the WXEdge structure 22 */ 23 24 #include <vector> 25 26 #include "../geometry/Geom.h" 27 28 #include "../system/FreestyleConfig.h" 29 #include "../system/ProgressBar.h" 30 #include "../system/RenderMonitor.h" 31 32 #include "../winged_edge/Curvature.h" 33 #include "../winged_edge/WXEdge.h" 34 35 #include "BLI_math.h" 36 37 #ifdef WITH_CXX_GUARDEDALLOC 38 # include "MEM_guardedalloc.h" 39 #endif 40 41 namespace Freestyle { 42 43 using namespace Geometry; 44 45 /*! This class takes as input a WXEdge structure and fills it */ 46 class FEdgeXDetector { 47 public: FEdgeXDetector()48 FEdgeXDetector() 49 { 50 _pProgressBar = NULL; 51 _pRenderMonitor = NULL; 52 _computeViewIndependent = true; 53 #if 0 54 _bbox_diagonal = 1.0; 55 #endif 56 _meanEdgeSize = 0; 57 _computeRidgesAndValleys = true; 58 _computeSuggestiveContours = true; 59 _computeMaterialBoundaries = true; 60 _sphereRadius = 1.0; 61 _orthographicProjection = false; 62 _faceSmoothness = false; 63 _changes = false; 64 _kr_derivative_epsilon = 0.0; 65 _creaseAngle = 0.7; // angle of 134.43 degrees 66 } 67 ~FEdgeXDetector()68 virtual ~FEdgeXDetector() 69 { 70 } 71 72 /*! Process shapes from a WingedEdge containing a list of WShapes */ 73 virtual void processShapes(WingedEdge &); 74 75 // GENERAL STUFF 76 virtual void preProcessShape(WXShape *iWShape); 77 virtual void preProcessFace(WXFace *iFace); 78 virtual void computeCurvatures(WXVertex *iVertex); 79 80 // SILHOUETTE 81 virtual void processSilhouetteShape(WXShape *iWShape); 82 virtual void ProcessSilhouetteFace(WXFace *iFace); 83 virtual void ProcessSilhouetteEdge(WXEdge *iEdge); 84 85 // CREASE 86 virtual void processCreaseShape(WXShape *iWShape); 87 virtual void ProcessCreaseEdge(WXEdge *iEdge); 88 89 /*! Sets the minimum angle for detecting crease edges 90 * \param angle: 91 * The angular threshold in degrees (between 0 and 180) for detecting crease edges. An edge is 92 * considered a crease edge if the angle between two faces sharing the edge is smaller than the 93 * given threshold. 94 */ 95 // XXX angle should be in radian... setCreaseAngle(float angle)96 inline void setCreaseAngle(float angle) 97 { 98 if (angle < 0.0) { 99 angle = 0.0; 100 } 101 else if (angle > 180.0) { 102 angle = 180.0; 103 } 104 angle = cos(M_PI * (180.0 - angle) / 180.0); 105 if (angle != _creaseAngle) { 106 _creaseAngle = angle; 107 _changes = true; 108 } 109 } 110 111 // BORDER 112 virtual void processBorderShape(WXShape *iWShape); 113 virtual void ProcessBorderEdge(WXEdge *iEdge); 114 115 // RIDGES AND VALLEYS 116 virtual void processRidgesAndValleysShape(WXShape *iWShape); 117 virtual void ProcessRidgeFace(WXFace *iFace); 118 119 // SUGGESTIVE CONTOURS 120 virtual void processSuggestiveContourShape(WXShape *iWShape); 121 virtual void ProcessSuggestiveContourFace(WXFace *iFace); 122 virtual void postProcessSuggestiveContourShape(WXShape *iShape); 123 virtual void postProcessSuggestiveContourFace(WXFace *iFace); 124 /*! Sets the minimal derivative of the radial curvature for suggestive contours 125 * \param dkr: 126 * The minimal derivative of the radial curvature 127 */ setSuggestiveContourKrDerivativeEpsilon(float dkr)128 inline void setSuggestiveContourKrDerivativeEpsilon(float dkr) 129 { 130 if (dkr != _kr_derivative_epsilon) { 131 _kr_derivative_epsilon = dkr; 132 _changes = true; 133 } 134 } 135 136 // MATERIAL BOUNDARY 137 virtual void processMaterialBoundaryShape(WXShape *iWShape); 138 virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge); 139 140 // EDGE MARKS 141 virtual void processEdgeMarksShape(WXShape *iShape); 142 virtual void ProcessEdgeMarks(WXEdge *iEdge); 143 144 // EVERYBODY 145 virtual void buildSmoothEdges(WXShape *iShape); 146 147 /*! Sets the current viewpoint */ setViewpoint(const Vec3f & ivp)148 inline void setViewpoint(const Vec3f &ivp) 149 { 150 _Viewpoint = ivp; 151 } 152 enableOrthographicProjection(bool b)153 inline void enableOrthographicProjection(bool b) 154 { 155 _orthographicProjection = b; 156 } 157 enableRidgesAndValleysFlag(bool b)158 inline void enableRidgesAndValleysFlag(bool b) 159 { 160 _computeRidgesAndValleys = b; 161 } 162 enableSuggestiveContours(bool b)163 inline void enableSuggestiveContours(bool b) 164 { 165 _computeSuggestiveContours = b; 166 } 167 enableMaterialBoundaries(bool b)168 inline void enableMaterialBoundaries(bool b) 169 { 170 _computeMaterialBoundaries = b; 171 } 172 enableFaceSmoothness(bool b)173 inline void enableFaceSmoothness(bool b) 174 { 175 if (b != _faceSmoothness) { 176 _faceSmoothness = b; 177 _changes = true; 178 } 179 } 180 enableFaceMarks(bool b)181 inline void enableFaceMarks(bool b) 182 { 183 if (b != _faceMarks) { 184 _faceMarks = b; 185 _changes = true; 186 } 187 } 188 189 /*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation) 190 * \param r: 191 * The radius of the sphere expressed as a ratio of the mean edge size 192 */ setSphereRadius(float r)193 inline void setSphereRadius(float r) 194 { 195 if (r != _sphereRadius) { 196 _sphereRadius = r; 197 _changes = true; 198 } 199 } 200 setProgressBar(ProgressBar * iProgressBar)201 inline void setProgressBar(ProgressBar *iProgressBar) 202 { 203 _pProgressBar = iProgressBar; 204 } 205 setRenderMonitor(RenderMonitor * iRenderMonitor)206 inline void setRenderMonitor(RenderMonitor *iRenderMonitor) 207 { 208 _pRenderMonitor = iRenderMonitor; 209 } 210 211 protected: 212 Vec3f _Viewpoint; 213 #if 0 214 real _bbox_diagonal; // diagonal of the current processed shape bbox 215 #endif 216 // oldtmp values 217 bool _computeViewIndependent; 218 real _meanK1; 219 real _meanKr; 220 real _minK1; 221 real _minKr; 222 real _maxK1; 223 real _maxKr; 224 unsigned _nPoints; 225 real _meanEdgeSize; 226 bool _orthographicProjection; 227 228 bool _computeRidgesAndValleys; 229 bool _computeSuggestiveContours; 230 bool _computeMaterialBoundaries; 231 bool _faceSmoothness; 232 bool _faceMarks; 233 float _sphereRadius; // expressed as a ratio of the mean edge size 234 float _creaseAngle; // [-1, 1] compared with the inner product of face normals 235 bool _changes; 236 237 float _kr_derivative_epsilon; 238 239 ProgressBar *_pProgressBar; 240 RenderMonitor *_pRenderMonitor; 241 242 #ifdef WITH_CXX_GUARDEDALLOC 243 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeXDetector") 244 #endif 245 }; 246 247 } /* namespace Freestyle */ 248