You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
6.7 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkEllipsoidalGaussianKernel.h
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.
=========================================================================*/
/**
* @class vtkEllipsoidalGaussianKernel
* @brief an ellipsoidal Gaussian interpolation kernel
*
*
* vtkEllipsoidalGaussianKernel is an interpolation kernel that returns the
* weights for all points found in the ellipsoid defined by radius R in
* combination with local data (normals and/or scalars). For example, "pancake"
* weightings (the local normal parallel to the minimum ellisoidal axis); or
* "needle" weightings (the local normal parallel to the maximum ellipsoidal
* axis) are possible. (Note that spherical Gaussian weightings are more
* efficiently computed using vtkGaussianKernel.)
*
* The ellipsoidal Gaussian can be described by:
*
* W(x) = S * exp( -( Sharpness^2 * ((rxy/E)**2 + z**2)/R**2) )
*
* where S is the local scalar value; E is a user-defined eccentricity factor
* that controls the elliptical shape of the splat; z is the distance of the
* current voxel sample point along the local normal N; and rxy is the
* distance to neighbor point x in the direction prependicular to N.
*
* @warning
* The weights are normalized so that SUM(Wi) = 1. If a neighbor point p
* precisely lies on the point to be interpolated, then the interpolated
* point takes on the values associated with p.
*
* @sa
* vtkPointInterpolator vtkInterpolationKernel vtkGeneralizedKernel
* vtkGaussianKernel vtkVoronoiKernel vtkSPHKernel vtkShepardKernel
*/
#ifndef vtkEllipsoidalGaussianKernel_h
#define vtkEllipsoidalGaussianKernel_h
#include "vtkFiltersPointsModule.h" // For export macro
#include "vtkGeneralizedKernel.h"
#include "vtkStdString.h" // For vtkStdString ivars
class vtkIdList;
class vtkDataArray;
class vtkDoubleArray;
class VTKFILTERSPOINTS_EXPORT vtkEllipsoidalGaussianKernel : public vtkGeneralizedKernel
{
public:
//@{
/**
* Standard methods for instantiation, obtaining type information, and printing.
*/
static vtkEllipsoidalGaussianKernel* New();
vtkTypeMacro(vtkEllipsoidalGaussianKernel, vtkGeneralizedKernel);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@}
/**
* Initialize the kernel. Overload the superclass to set up scalars and
* vectors.
*/
void Initialize(vtkAbstractPointLocator* loc, vtkDataSet* ds, vtkPointData* pd) override;
// Re-use any superclass signatures that we don't override.
using vtkGeneralizedKernel::ComputeWeights;
/**
* Given a point x, a list of basis points pIds, and a probability
* weighting function prob, compute interpolation weights associated with
* these basis points. Note that basis points list pIds, the probability
* weighting prob, and the weights array are provided by the caller of the
* method, and may be dynamically resized as necessary. The method returns
* the number of weights (pIds may be resized in some cases). Typically
* this method is called after ComputeBasis(), although advanced users can
* invoke ComputeWeights() and provide the interpolation basis points pIds
* directly. The probably weighting prob are numbers 0<=prob<=1 which are
* multiplied against the interpolation weights before normalization. They
* are estimates of local confidence of weights. The prob may be nullptr in
* which all probabilities are considered =1.
*/
vtkIdType ComputeWeights(
double x[3], vtkIdList* pIds, vtkDoubleArray* prob, vtkDoubleArray* weights) override;
//@{
/**
* Specify whether vector values should be used to affect the shape
* of the Gaussian distribution. By default this is on.
*/
vtkSetMacro(UseNormals, bool);
vtkGetMacro(UseNormals, bool);
vtkBooleanMacro(UseNormals, bool);
//@}
//@{
/**
* Specify the normals array name. Used to orient the ellipsoid. Note that
* by default the input normals are used (i.e. the input to
* vtkPointInterpolator). If no input normals are available, then the named
* NormalsArrayName is used.
*/
vtkSetMacro(NormalsArrayName, vtkStdString);
vtkGetMacro(NormalsArrayName, vtkStdString);
//@}
//@{
/**
* Specify whether scalar values should be used to scale the weights.
* By default this is off.
*/
vtkSetMacro(UseScalars, bool);
vtkGetMacro(UseScalars, bool);
vtkBooleanMacro(UseScalars, bool);
//@}
//@{
/**
* Specify the scalars array name. Used to scale the ellipsoid. Note that
* by default the input scalars are used (i.e. the input to
* vtkPointInterpolator). If no input scalars are available, then the named
* ScalarsArrayName is used.
*/
vtkSetMacro(ScalarsArrayName, vtkStdString);
vtkGetMacro(ScalarsArrayName, vtkStdString);
//@}
//@{
/**
* Multiply the Gaussian splat distribution by this value. If UseScalars is
* on and a scalar array is provided, then the scalar value will be
* multiplied by the ScaleFactor times the Gaussian function.
*/
vtkSetClampMacro(ScaleFactor, double, 0.0, VTK_DOUBLE_MAX);
vtkGetMacro(ScaleFactor, double);
//@}
//@{
/**
* Set / Get the sharpness (i.e., falloff) of the Gaussian. By default
* Sharpness=2. As the sharpness increases the effects of distant points
* are reduced.
*/
vtkSetClampMacro(Sharpness, double, 1, VTK_FLOAT_MAX);
vtkGetMacro(Sharpness, double);
//@}
//@{
/**
* Set / Get the eccentricity of the ellipsoidal Gaussian. A value=1.0
* produces a spherical distribution. Values < 1 produce a needle like
* distribution (in the direction of the normal); values > 1 produce a
* pancake like distribution (orthogonal to the normal).
*/
vtkSetClampMacro(Eccentricity, double, 0.000001, VTK_FLOAT_MAX);
vtkGetMacro(Eccentricity, double);
//@}
protected:
vtkEllipsoidalGaussianKernel();
~vtkEllipsoidalGaussianKernel() override;
bool UseNormals;
bool UseScalars;
vtkStdString NormalsArrayName;
vtkStdString ScalarsArrayName;
double ScaleFactor;
double Sharpness;
double Eccentricity;
// Internal structure to reduce computation
double F2, E2;
vtkDataArray* NormalsArray;
vtkDataArray* ScalarsArray;
void FreeStructures() override;
private:
vtkEllipsoidalGaussianKernel(const vtkEllipsoidalGaussianKernel&) = delete;
void operator=(const vtkEllipsoidalGaussianKernel&) = delete;
};
#endif