1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkSmoothPolyDataFilter.h 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 /** 16 * @class vtkSmoothPolyDataFilter 17 * @brief adjust point positions using Laplacian smoothing 18 * 19 * vtkSmoothPolyDataFilter is a filter that adjusts point coordinates using 20 * Laplacian smoothing. The effect is to "relax" the mesh, making the cells 21 * better shaped and the vertices more evenly distributed. Note that this 22 * filter operates on the lines, polygons, and triangle strips composing an 23 * instance of vtkPolyData. Vertex or poly-vertex cells are never modified. 24 * 25 * The algorithm proceeds as follows. For each vertex v, a topological and 26 * geometric analysis is performed to determine which vertices are connected 27 * to v, and which cells are connected to v. Then, a connectivity array is 28 * constructed for each vertex. (The connectivity array is a list of lists 29 * of vertices that directly attach to each vertex.) Next, an iteration 30 * phase begins over all vertices. For each vertex v, the coordinates of v 31 * are modified according to an average of the connected vertices. (A 32 * relaxation factor is available to control the amount of displacement of 33 * v). The process repeats for each vertex. This pass over the list of 34 * vertices is a single iteration. Many iterations (generally around 20 or 35 * so) are repeated until the desired result is obtained. 36 * 37 * There are some special instance variables used to control the execution 38 * of this filter. (These ivars basically control what vertices can be 39 * smoothed, and the creation of the connectivity array.) The 40 * BoundarySmoothing ivar enables/disables the smoothing operation on 41 * vertices that are on the "boundary" of the mesh. A boundary vertex is one 42 * that is surrounded by a semi-cycle of polygons (or used by a single 43 * line). 44 * 45 * Another important ivar is FeatureEdgeSmoothing. If this ivar is 46 * enabled, then interior vertices are classified as either "simple", 47 * "interior edge", or "fixed", and smoothed differently. (Interior 48 * vertices are manifold vertices surrounded by a cycle of polygons; or used 49 * by two line cells.) The classification is based on the number of feature 50 * edges attached to v. A feature edge occurs when the angle between the two 51 * surface normals of a polygon sharing an edge is greater than the 52 * FeatureAngle ivar. Then, vertices used by no feature edges are classified 53 * "simple", vertices used by exactly two feature edges are classified 54 * "interior edge", and all others are "fixed" vertices. 55 * 56 * Once the classification is known, the vertices are smoothed 57 * differently. Corner (i.e., fixed) vertices are not smoothed at all. 58 * Simple vertices are smoothed as before (i.e., average of connected 59 * vertex coordinates). Interior edge vertices are smoothed only along 60 * their two connected edges, and only if the angle between the edges 61 * is less than the EdgeAngle ivar. 62 * 63 * The total smoothing can be controlled by using two ivars. The 64 * NumberOfIterations is a cap on the maximum number of smoothing passes. 65 * The Convergence ivar is a limit on the maximum point motion. If the 66 * maximum motion during an iteration is less than Convergence, then the 67 * smoothing process terminates. (Convergence is expressed as a fraction of 68 * the diagonal of the bounding box.) 69 * 70 * There are two instance variables that control the generation of error 71 * data. If the ivar GenerateErrorScalars is on, then a scalar value indicating 72 * the distance of each vertex from its original position is computed. If the 73 * ivar GenerateErrorVectors is on, then a vector representing change in 74 * position is computed. 75 * 76 * Optionally you can further control the smoothing process by defining a 77 * second input: the Source. If defined, the input mesh is constrained to 78 * lie on the surface defined by the Source ivar. 79 * 80 * 81 * @warning 82 * The Laplacian operation reduces high frequency information in the geometry 83 * of the mesh. With excessive smoothing important details may be lost, and 84 * the surface may shrink towards the centroid. Enabling FeatureEdgeSmoothing 85 * helps reduce this effect, but cannot entirely eliminate it. You may also 86 * wish to try vtkWindowedSincPolyDataFilter. It does a better job of 87 * minimizing shrinkage. 88 * 89 * @sa 90 * vtkWindowedSincPolyDataFilter vtkDecimate vtkDecimatePro 91 */ 92 93 #ifndef vtkSmoothPolyDataFilter_h 94 #define vtkSmoothPolyDataFilter_h 95 96 #include "vtkFiltersCoreModule.h" // For export macro 97 #include "vtkPolyDataAlgorithm.h" 98 99 class vtkSmoothPoints; 100 101 class VTKFILTERSCORE_EXPORT vtkSmoothPolyDataFilter : public vtkPolyDataAlgorithm 102 { 103 public: 104 vtkTypeMacro(vtkSmoothPolyDataFilter, vtkPolyDataAlgorithm); 105 void PrintSelf(ostream& os, vtkIndent indent) override; 106 107 /** 108 * Construct object with number of iterations 20; relaxation factor .01; 109 * feature edge smoothing turned off; feature 110 * angle 45 degrees; edge angle 15 degrees; and boundary smoothing turned 111 * on. Error scalars and vectors are not generated (by default). The 112 * convergence criterion is 0.0 of the bounding box diagonal. 113 */ 114 static vtkSmoothPolyDataFilter* New(); 115 116 ///@{ 117 /** 118 * Specify a convergence criterion for the iteration 119 * process. Smaller numbers result in more smoothing iterations. 120 */ 121 vtkSetClampMacro(Convergence, double, 0.0, 1.0); 122 vtkGetMacro(Convergence, double); 123 ///@} 124 125 ///@{ 126 /** 127 * Specify the number of iterations for Laplacian smoothing, 128 */ 129 vtkSetClampMacro(NumberOfIterations, int, 0, VTK_INT_MAX); 130 vtkGetMacro(NumberOfIterations, int); 131 ///@} 132 133 ///@{ 134 /** 135 * Specify the relaxation factor for Laplacian smoothing. As in all 136 * iterative methods, the stability of the process is sensitive to 137 * this parameter. In general, small relaxation factors and large 138 * numbers of iterations are more stable than larger relaxation 139 * factors and smaller numbers of iterations. 140 */ 141 vtkSetMacro(RelaxationFactor, double); 142 vtkGetMacro(RelaxationFactor, double); 143 ///@} 144 145 ///@{ 146 /** 147 * Turn on/off smoothing along sharp interior edges. 148 */ 149 vtkSetMacro(FeatureEdgeSmoothing, vtkTypeBool); 150 vtkGetMacro(FeatureEdgeSmoothing, vtkTypeBool); 151 vtkBooleanMacro(FeatureEdgeSmoothing, vtkTypeBool); 152 ///@} 153 154 ///@{ 155 /** 156 * Specify the feature angle for sharp edge identification. 157 */ 158 vtkSetClampMacro(FeatureAngle, double, 0.0, 180.0); 159 vtkGetMacro(FeatureAngle, double); 160 ///@} 161 162 ///@{ 163 /** 164 * Specify the edge angle to control smoothing along edges (either interior 165 * or boundary). 166 */ 167 vtkSetClampMacro(EdgeAngle, double, 0.0, 180.0); 168 vtkGetMacro(EdgeAngle, double); 169 ///@} 170 171 ///@{ 172 /** 173 * Turn on/off the smoothing of vertices on the boundary of the mesh. 174 */ 175 vtkSetMacro(BoundarySmoothing, vtkTypeBool); 176 vtkGetMacro(BoundarySmoothing, vtkTypeBool); 177 vtkBooleanMacro(BoundarySmoothing, vtkTypeBool); 178 ///@} 179 180 ///@{ 181 /** 182 * Turn on/off the generation of scalar distance values. 183 */ 184 vtkSetMacro(GenerateErrorScalars, vtkTypeBool); 185 vtkGetMacro(GenerateErrorScalars, vtkTypeBool); 186 vtkBooleanMacro(GenerateErrorScalars, vtkTypeBool); 187 ///@} 188 189 ///@{ 190 /** 191 * Turn on/off the generation of error vectors. 192 */ 193 vtkSetMacro(GenerateErrorVectors, vtkTypeBool); 194 vtkGetMacro(GenerateErrorVectors, vtkTypeBool); 195 vtkBooleanMacro(GenerateErrorVectors, vtkTypeBool); 196 ///@} 197 198 ///@{ 199 /** 200 * Specify the source object which is used to constrain smoothing. The 201 * source defines a surface that the input (as it is smoothed) is 202 * constrained to lie upon. 203 */ 204 void SetSourceData(vtkPolyData* source); 205 vtkPolyData* GetSource(); 206 ///@} 207 208 ///@{ 209 /** 210 * Set/get the desired precision for the output types. See the documentation 211 * for the vtkAlgorithm::DesiredOutputPrecision enum for an explanation of 212 * the available precision settings. 213 */ 214 vtkSetMacro(OutputPointsPrecision, int); 215 vtkGetMacro(OutputPointsPrecision, int); 216 ///@} 217 218 protected: 219 vtkSmoothPolyDataFilter(); 220 ~vtkSmoothPolyDataFilter() override = default; 221 222 int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; 223 int FillInputPortInformation(int port, vtkInformation* info) override; 224 225 double Convergence; 226 int NumberOfIterations; 227 double RelaxationFactor; 228 vtkTypeBool FeatureEdgeSmoothing; 229 double FeatureAngle; 230 double EdgeAngle; 231 vtkTypeBool BoundarySmoothing; 232 vtkTypeBool GenerateErrorScalars; 233 vtkTypeBool GenerateErrorVectors; 234 int OutputPointsPrecision; 235 236 vtkSmoothPoints* SmoothPoints; 237 238 private: 239 vtkSmoothPolyDataFilter(const vtkSmoothPolyDataFilter&) = delete; 240 void operator=(const vtkSmoothPolyDataFilter&) = delete; 241 }; 242 243 #endif 244