You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
11 KiB
241 lines
11 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkWindowedSincPolyDataFilter.h,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
// .NAME vtkWindowedSincPolyDataFilter - adjust point positions using a windowed sinc function interpolation kernel
|
|
// .SECTION Description
|
|
// vtkWindowedSincPolyDataFiler adjust point coordinate using a windowed
|
|
// sinc function interpolation kernel. The effect is to "relax" the mesh,
|
|
// making the cells better shaped and the vertices more evenly distributed.
|
|
// Note that this filter operates the lines, polygons, and triangle strips
|
|
// composing an instance of vtkPolyData. Vertex or poly-vertex cells are
|
|
// never modified.
|
|
//
|
|
// The algorithm proceeds as follows. For each vertex v, a topological and
|
|
// geometric analysis is performed to determine which vertices are connected
|
|
// to v, and which cells are connected to v. Then, a connectivity array is
|
|
// constructed for each vertex. (The connectivity array is a list of lists
|
|
// of vertices that directly attach to each vertex.) Next, an iteration
|
|
// phase begins over all vertices. For each vertex v, the coordinates of v
|
|
// are modified using a windowed sinc function interpolation kernel.
|
|
// Taubin describes this methodology is the IBM tech report RC-20404
|
|
// (#90237, dated 3/12/96) "Optimal Surface Smoothing as Filter Design"
|
|
// G. Taubin, T. Zhang and G. Golub. (Zhang and Golub are at Stanford
|
|
// University).
|
|
//
|
|
// This report discusses using standard signal processing low-pass filters
|
|
// (in particular windowed sinc functions) to smooth polyhedra. The
|
|
// transfer functions of the low-pass filters are approximated by
|
|
// Chebyshev polynomials. This facilitates applying the filters in an
|
|
// iterative diffusion process (as opposed to a kernel convolution). The
|
|
// more smoothing iterations applied, the higher the degree of polynomial
|
|
// approximating the low-pass filter transfer function. Each smoothing
|
|
// iteration, therefore, applies the next higher term of the Chebyshev
|
|
// filter approximation to the polyhedron. This decoupling of the filter
|
|
// into an iteratively applied polynomial is possible since the Chebyshev
|
|
// polynomials are orthogonal, i.e. increasing the order of the
|
|
// approximation to the filter transfer function does not alter the
|
|
// previously calculated coefficients for the low order terms.
|
|
//
|
|
// Note: Care must be taken to avoid smoothing with too few iterations.
|
|
// A Chebyshev approximation with too few terms is an poor approximation.
|
|
// The first few smoothing iterations represent a severe scaling and
|
|
// translation of the data. Subsequent iterations cause the smoothed
|
|
// polyhedron to converge to the true location and scale of the object.
|
|
// We have attempted to protect against this by automatically adjusting
|
|
// the filter, effectively widening the pass band. This adjustment is only
|
|
// possible if the number of iterations is greater than 1. Note that this
|
|
// sacrifices some degree of smoothing for model integrity. For those
|
|
// interested, the filter is adjusted by searching for a value sigma
|
|
// such that the actual pass band is k_pb + sigma and such that the
|
|
// filter transfer function evaluates to unity at k_pb, i.e. f(k_pb) = 1
|
|
//
|
|
// To improve the numerical stability of the solution and minimize the
|
|
// scaling the translation effects, the algorithm can translate and
|
|
// scale the position coordinates to within the unit cube [-1, 1],
|
|
// perform the smoothing, and translate and scale the position
|
|
// coordinates back to the original coordinate frame. This mode is
|
|
// controlled with the NormalizeCoordinatesOn() /
|
|
// NormalizeCoordinatesOff() methods. For legacy reasons, the default
|
|
// is NormalizeCoordinatesOff.
|
|
//
|
|
// This implementation is currently limited to using an interpolation
|
|
// kernel based on Hamming windows. Other windows (such as Hann, Blackman,
|
|
// Kaiser, Lanczos, Gaussian, and exponential windows) could be used
|
|
// instead.
|
|
//
|
|
// There are some special instance variables used to control the execution
|
|
// of this filter. (These ivars basically control what vertices can be
|
|
// smoothed, and the creation of the connectivity array.) The
|
|
// BoundarySmoothing ivar enables/disables the smoothing operation on
|
|
// vertices that are on the "boundary" of the mesh. A boundary vertex is one
|
|
// that is surrounded by a semi-cycle of polygons (or used by a single
|
|
// line).
|
|
//
|
|
// Another important ivar is FeatureEdgeSmoothing. If this ivar is
|
|
// enabled, then interior vertices are classified as either "simple",
|
|
// "interior edge", or "fixed", and smoothed differently. (Interior
|
|
// vertices are manifold vertices surrounded by a cycle of polygons; or used
|
|
// by two line cells.) The classification is based on the number of feature
|
|
// edges attached to v. A feature edge occurs when the angle between the two
|
|
// surface normals of a polygon sharing an edge is greater than the
|
|
// FeatureAngle ivar. Then, vertices used by no feature edges are classified
|
|
// "simple", vertices used by exactly two feature edges are classified
|
|
// "interior edge", and all others are "fixed" vertices.
|
|
//
|
|
// Once the classification is known, the vertices are smoothed
|
|
// differently. Corner (i.e., fixed) vertices are not smoothed at all.
|
|
// Simple vertices are smoothed as before . Interior edge vertices are
|
|
// smoothed only along their two connected edges, and only if the angle
|
|
// between the edges is less than the EdgeAngle ivar.
|
|
//
|
|
// The total smoothing can be controlled by using two ivars. The
|
|
// NumberOfIterations determines the maximum number of smoothing passes.
|
|
// The NumberOfIterations corresponds to the degree of the polynomial that
|
|
// is used to approximate the windowed sinc function. Ten or twenty
|
|
// iterations is all the is usually necessary. Contrast this with
|
|
// vtkSmoothPolyDataFilter which usually requires 100 to 200 smoothing
|
|
// iterations. vtkSmoothPolyDataFilter is also not an approximation to
|
|
// an ideal low-pass filter, which can cause the geometry to shrink as the
|
|
// amount of smoothing increases.
|
|
//
|
|
// The second ivar is the specification of the PassBand for the windowed
|
|
// sinc filter. By design, the PassBand is specified as a doubleing point
|
|
// number between 0 and 2. Lower PassBand values produce more smoothing.
|
|
// A good default value for the PassBand is 0.1 (for those interested, the
|
|
// PassBand (and frequencies) for PolyData are based on the valence of the
|
|
// vertices, this limits all the frequency modes in a polyhedral mesh to
|
|
// between 0 and 2.)
|
|
//
|
|
// There are two instance variables that control the generation of error
|
|
// data. If the ivar GenerateErrorScalars is on, then a scalar value indicating
|
|
// the distance of each vertex from its original position is computed. If the
|
|
// ivar GenerateErrorVectors is on, then a vector representing change in
|
|
// position is computed.
|
|
//
|
|
// .SECTION Caveats
|
|
// The smoothing operation reduces high frequency information in the
|
|
// geometry of the mesh. With excessive smoothing important details may be
|
|
// lost. Enabling FeatureEdgeSmoothing helps reduce this effect, but cannot
|
|
// entirely eliminate it.
|
|
//
|
|
// .SECTION See Also
|
|
// vtkSmoothPolyDataFilter vtkDecimate vtkDecimatePro
|
|
|
|
|
|
#ifndef __vtkWindowedSincPolyDataFilter_h
|
|
#define __vtkWindowedSincPolyDataFilter_h
|
|
|
|
|
|
#include "vtkPolyDataAlgorithm.h"
|
|
|
|
class VTK_GRAPHICS_EXPORT vtkWindowedSincPolyDataFilter : public vtkPolyDataAlgorithm
|
|
{
|
|
public:
|
|
vtkTypeRevisionMacro(vtkWindowedSincPolyDataFilter,vtkPolyDataAlgorithm);
|
|
void PrintSelf(ostream& os, vtkIndent indent);
|
|
|
|
// Description:
|
|
// Construct object with number of iterations 20; passband .1;
|
|
// feature edge smoothing turned off; feature
|
|
// angle 45 degrees; edge angle 15 degrees; and boundary smoothing turned
|
|
// on. Error scalars and vectors are not generated (by default). The
|
|
// convergence criterion is 0.0 of the bounding box diagonal.
|
|
static vtkWindowedSincPolyDataFilter *New();
|
|
|
|
// Description:
|
|
// Specify the number of iterations (or degree of the polynomial
|
|
// approximating the windowed sinc function).
|
|
vtkSetClampMacro(NumberOfIterations,int,0,VTK_LARGE_INTEGER);
|
|
vtkGetMacro(NumberOfIterations,int);
|
|
|
|
// Description:
|
|
// Set the passband value for the windowed sinc filter
|
|
vtkSetClampMacro(PassBand,double, 0.0, 2.0);
|
|
vtkGetMacro(PassBand,double);
|
|
|
|
// Description:
|
|
// Turn on/off coordinate normalization. The positions can be
|
|
// translated and scaled such that they fit within a [-1, 1] prior
|
|
// to the smoothing computation. The default is off. The numerical
|
|
// stability of the solution can be improved by turning
|
|
// normalization on. If normalization is on, the coordinates will
|
|
// be rescaled to the original coordinate system after smoothing has
|
|
// completed.
|
|
vtkSetMacro(NormalizeCoordinates, int);
|
|
vtkGetMacro(NormalizeCoordinates, int);
|
|
vtkBooleanMacro(NormalizeCoordinates, int);
|
|
|
|
// Description:
|
|
// Turn on/off smoothing along sharp interior edges.
|
|
vtkSetMacro(FeatureEdgeSmoothing,int);
|
|
vtkGetMacro(FeatureEdgeSmoothing,int);
|
|
vtkBooleanMacro(FeatureEdgeSmoothing,int);
|
|
|
|
// Description:
|
|
// Specify the feature angle for sharp edge identification.
|
|
vtkSetClampMacro(FeatureAngle,double,0.0,180.0);
|
|
vtkGetMacro(FeatureAngle,double);
|
|
|
|
// Description:
|
|
// Specify the edge angle to control smoothing along edges (either interior
|
|
// or boundary).
|
|
vtkSetClampMacro(EdgeAngle,double,0.0,180.0);
|
|
vtkGetMacro(EdgeAngle,double);
|
|
|
|
// Description:
|
|
// Turn on/off the smoothing of vertices on the boundary of the mesh.
|
|
vtkSetMacro(BoundarySmoothing,int);
|
|
vtkGetMacro(BoundarySmoothing,int);
|
|
vtkBooleanMacro(BoundarySmoothing,int);
|
|
|
|
// Description:
|
|
// Smooth non-manifold vertices.
|
|
vtkSetMacro(NonManifoldSmoothing,int);
|
|
vtkGetMacro(NonManifoldSmoothing,int);
|
|
vtkBooleanMacro(NonManifoldSmoothing,int);
|
|
|
|
// Description:
|
|
// Turn on/off the generation of scalar distance values.
|
|
vtkSetMacro(GenerateErrorScalars,int);
|
|
vtkGetMacro(GenerateErrorScalars,int);
|
|
vtkBooleanMacro(GenerateErrorScalars,int);
|
|
|
|
// Description:
|
|
// Turn on/off the generation of error vectors.
|
|
vtkSetMacro(GenerateErrorVectors,int);
|
|
vtkGetMacro(GenerateErrorVectors,int);
|
|
vtkBooleanMacro(GenerateErrorVectors,int);
|
|
|
|
protected:
|
|
vtkWindowedSincPolyDataFilter();
|
|
~vtkWindowedSincPolyDataFilter() {};
|
|
|
|
int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
|
|
|
|
int NumberOfIterations;
|
|
double PassBand;
|
|
int FeatureEdgeSmoothing;
|
|
double FeatureAngle;
|
|
double EdgeAngle;
|
|
int BoundarySmoothing;
|
|
int NonManifoldSmoothing;
|
|
int GenerateErrorScalars;
|
|
int GenerateErrorVectors;
|
|
int NormalizeCoordinates;
|
|
private:
|
|
vtkWindowedSincPolyDataFilter(const vtkWindowedSincPolyDataFilter&); // Not implemented.
|
|
void operator=(const vtkWindowedSincPolyDataFilter&); // Not implemented.
|
|
};
|
|
|
|
#endif
|
|
|