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