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.

178 lines
6.4 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkSignedDistance.h
Copyright (c) Kitware, Inc.
All rights reserved.
See LICENSE file 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 vtkSignedDistance
* @brief compute signed distances from an input point cloud
*
* vtkSignedDistance is a filter that computes signed distances over a volume
* from an input point cloud. The input point cloud must have point normals
* defined, as well as an optional weighting function (e.g., probabilities
* that the point measurements are accurate). Once the signed distance
* function is computed, then the output volume may be isocontoured to with
* vtkExtractSurface to extract a approximating surface to the point cloud.
*
* To use this filter, specify the input vtkPolyData (which represents the
* point cloud); define the sampling volume; specify a radius (which limits
* the radius of influence of each point); and set an optional point locator
* (to accelerate proximity operations, a vtkStaticPointLocator is used by
* default). Note that large radius values may have significant impact on
* performance. The volume is defined by specifying dimensions in the x-y-z
* directions, as well as a domain bounds. By default the model bounds are
* defined from the input points, but the user can also manually specify
* them.
*
* This filter has one other unusual capability: it is possible to append
* data in a sequence of operations to generate a single output. This is
* useful when you have multiple point clouds (e.g., possibly from multiple
* acqusition scans) and want to incrementally accumulate all the data.
* However, the user must be careful to either specify the Bounds or
* order the input such that the bounds of the first input completely
* contains all other input data. This is because the geometry and topology
* of the output sampling volume cannot be changed after the initial Append
* operation.
*
* This algorithm loosely follows the most excellent paper by Curless and
* Levoy: "A Volumetric Method for Building Complex Models from Range
* Images." As described in this paper it may produce a signed distance
* volume that may contain the three data states for each voxel: near
* surface, empty, or unseen (see vtkExtractSurface for additional
* information). Note in this implementation the initial values of the volume
* are set to < this->Radius. This indicates that these voxels are
* "empty". Of course voxels with value -this->Radius <= d <= this->Radius
* are "near" the surface. (Voxels with values > this->Radius are "unseen" --
* this filter does not produce such values.)
*
* @warning
* This class has been threaded with vtkSMPTools. Using TBB or other
* non-sequential type (set in the CMake variable
* VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
*
* @warning
* Empty voxel values are set to -this->Radius.
*
* @sa
* vtkExtractSurface vtkImplicitModeller
*/
#ifndef vtkSignedDistance_h
#define vtkSignedDistance_h
#include "vtkFiltersPointsModule.h" // For export macro
#include "vtkImageAlgorithm.h"
class vtkPolyData;
class vtkAbstractPointLocator;
class VTKFILTERSPOINTS_EXPORT vtkSignedDistance : public vtkImageAlgorithm
{
public:
//@{
/**
* Standard methods for instantiating the class, providing type information,
* and printing.
*/
static vtkSignedDistance* New();
vtkTypeMacro(vtkSignedDistance, vtkImageAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@}
//@{
/**
* Set/Get the i-j-k dimensions on which to computer the distance function.
*/
vtkGetVectorMacro(Dimensions, int, 3);
void SetDimensions(int i, int j, int k);
void SetDimensions(const int dim[3]);
//@}
//@{
/**
* Set / get the region in space in which to perform the sampling. If
* not specified, it will be computed automatically.
*/
vtkSetVector6Macro(Bounds, double);
vtkGetVectorMacro(Bounds, double, 6);
//@}
//@{
/**
* Set / get the radius of influence of each point. Smaller values
* generally improve performance markedly. Note that after the signed
* distance function is computed, any voxel taking on the value >= Radius
* is presumed to be "unseen" or uninitialized.
*/
vtkSetClampMacro(Radius, double, 0.0, VTK_FLOAT_MAX);
vtkGetMacro(Radius, double);
//@}
//@{
/**
* Specify a point locator. By default a vtkStaticPointLocator is
* used. The locator performs efficient searches to locate points
* surrounding a voxel (within the specified radius).
*/
void SetLocator(vtkAbstractPointLocator* locator);
vtkGetObjectMacro(Locator, vtkAbstractPointLocator);
//@}
/**
* Initialize the filter for appending data. You must invoke the
* StartAppend() method before doing successive Appends(). It's also a
* good idea to manually specify the model bounds; otherwise the input
* bounds for the data will be used.
*/
void StartAppend();
/**
* Append a data set to the existing output. To use this function,
* you'll have to invoke the StartAppend() method before doing
* successive appends. It's also a good idea to specify the model
* bounds; otherwise the input model bounds is used. When you've
* finished appending, use the EndAppend() method.
*/
void Append(vtkPolyData* input);
/**
* Method completes the append process.
*/
void EndAppend();
// See the vtkAlgorithm for a description of what these do
vtkTypeBool ProcessRequest(
vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
protected:
vtkSignedDistance();
~vtkSignedDistance() override;
int Dimensions[3];
double Bounds[6];
double Radius;
vtkAbstractPointLocator* Locator;
// Flag tracks whether process needs initialization
int Initialized;
int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
int FillInputPortInformation(int, vtkInformation*) override;
private:
vtkSignedDistance(const vtkSignedDistance&) = delete;
void operator=(const vtkSignedDistance&) = delete;
};
#endif