text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    vtkPointDensityFilter.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   vtkPointDensityFilter
   * @brief   produce density field from input point cloud
   *
   * vtkPointDensityFilter is a filter that generates a density field on a
   * volume from a point cloud. Basically the density is computed as number of
   * points in a local neighborhood per unit volume; or optionally, the number
   * of points in a local neighborhood surrounding each voxel. The local
   * neighborhood is specified as a radius around each sample position (i.e.,
   * each voxel) which can be of fixed value; or the radius can be relative to
   * the voxel size. The density computation may be further weighted by a
   * scalar value which is simply multiplied by each point's presumed density
   * of 1.0.
   *
   * To use this filter, specify an input of type vtkPointSet (i.e., has an
   * explicit representation of points). Optionally a scalar weighting function
   * can be provided (part of the input to the filter). Then specify how the
   * local spherical neighborhood is to be defined, either by a fixed radius or
   * a radius relative to the voxel size. Finally, specify how the density is
   * specified, either as a points/volume, or as number of points. (The
   * weighting scalar array will affect both of these results if provided and
   * enabled.)
   *
   * An optional capability of the filter is to compute the gradients of the
   * resulting density function (a 3-component vector), which also includes the
   * gradient magnitude (single component scalar) and classification (regions
   * of zero function, a scalar with single unsigned char value per voxel).
  
   * @warning
   * A point locator is used to speed up searches. By default a fast
   * vtkStaticPointLocator is used; however the user may specify an alternative
   * locator. In some situations adaptive locators may run faster depending on
   * the relative variation in point cloud density.
   *
   * @warning
   * Note that the volume calculation can be affected by the boundary. The
   * local spherical neighborhood around a "near volume boundary" voxel may
   * extend beyond the volume extent, meaning that density computation may be
   * reduced. To counter this effect, the volume may be increased in size
   * and/or resolution so that the point cloud fits well within the volume.
   *
   * @warning
   * While this class is very similar to many other of VTK's the point
   * splatting and interpolation classes, the algorithm density computation is
   * specialized to generate the density computation over a volume, does not
   * require (scalar weighting) data attributes to run, and does not require
   * multiple inputs. As an interesting side note: using the
   * vtkPointInterpolation class with a vtkLinearKernel, a (scalar) weighting
   * point attribute, a point cloud source, and an input volume produces the
   * same result as this filter does (assuming that the input volume is the
   * same).
   *
   * @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.
   *
   * @sa
   * vtkCheckerboardSplatter vtkShepardMethod vtkGaussianSplatter
   * vtkPointInterpolator vtkSPHInterpolator
  */
  
  #ifndef vtkPointDensityFilter_h
  #define vtkPointDensityFilter_h
  
  #include "vtkFiltersPointsModule.h" // For export macro
  #include "vtkImageAlgorithm.h"
  
  #define VTK_DENSITY_ESTIMATE_FIXED_RADIUS 0
  #define VTK_DENSITY_ESTIMATE_RELATIVE_RADIUS 1
  
  #define VTK_DENSITY_FORM_VOLUME_NORM 0
  #define VTK_DENSITY_FORM_NPTS 1
  
  class vtkAbstractPointLocator;
  
  class VTKFILTERSPOINTS_EXPORT vtkPointDensityFilter : public vtkImageAlgorithm
  {
  public:
    //@{
    /**
     * Standard methods for instantiating, obtaining type information, and
     * printing information.
     */
    static vtkPointDensityFilter *New();
    vtkTypeMacro(vtkPointDensityFilter,vtkImageAlgorithm);
    void PrintSelf(ostream& os, vtkIndent indent) VTK_OVERRIDE;
    //@}
  
    //@{
    /**
     * Set / get the dimensions of the sampling volume. Higher values generally
     * produce better results but may be much slower. Note however that too
     * high a resolution can generate excessive noise; too low and data can be
     * excessively smoothed.
     */
    void SetSampleDimensions(int i, int j, int k);
    void SetSampleDimensions(int dim[3]);
    vtkGetVectorMacro(SampleDimensions,int,3);
    //@}
  
    //@{
    /**
     * Set / get the (xmin,xmax, ymin,ymax, zmin,zmax) bounding box in which
     * the sampling is performed. If any of the (min,max) bounds values are
     * min >= max, then the bounds will be computed automatically from the input
     * data. Otherwise, the user-specified bounds will be used.
     */
    vtkSetVector6Macro(ModelBounds,double);
    vtkGetVectorMacro(ModelBounds,double,6);
    //@}
  
    //@{
    /**
     * Set / get the relative amount to pad the model bounds if automatic
     * computation is performed. The padding is the fraction to scale
     * the model bounds in each of the x-y-z directions. By default the
     * padding is 0.10 (i.e., 10% larger in each direction).
     */
    vtkSetClampMacro(AdjustDistance,double,-1.0,1.0);
    vtkGetMacro(AdjustDistance,double);
    //@}
  
    //@{
    /**
     * Specify the method to estimate point density. The density can be
     * calculated using a fixed sphere radius; or a sphere radius that is
     * relative to voxel size.
     */
    vtkSetClampMacro(DensityEstimate,int, VTK_DENSITY_ESTIMATE_FIXED_RADIUS,
                     VTK_DENSITY_ESTIMATE_RELATIVE_RADIUS);
    vtkGetMacro(DensityEstimate,int);
    void SetDensityEstimateToFixedRadius()
      {this->SetDensityEstimate(VTK_DENSITY_ESTIMATE_FIXED_RADIUS);}
    void SetDensityEstimateToRelativeRadius()
      {this->SetDensityEstimate(VTK_DENSITY_ESTIMATE_RELATIVE_RADIUS);}
    const char *GetDensityEstimateAsString();
    //@}
  
    //@{
    /**
     * Specify the form by which the density is expressed. Either the density is
     * expressed as (number of points/local sphere volume), or as simply the
     * (number of points) within the local sphere.
     */
    vtkSetClampMacro(DensityForm,int, VTK_DENSITY_FORM_VOLUME_NORM,
                     VTK_DENSITY_FORM_NPTS);
    vtkGetMacro(DensityForm,int);
    void SetDensityFormToVolumeNormalized()
      {this->SetDensityForm(VTK_DENSITY_FORM_VOLUME_NORM);}
    void SetDensityFormToNumberOfPoints()
      {this->SetDensityForm(VTK_DENSITY_FORM_NPTS);}
    const char *GetDensityFormAsString();
    //@}
  
    //@{
    /**
     * Set / get the radius variable defining the local sphere used to estimate
     * the density function. The Radius is used when the density estimate is
     ^ set to a fixed radius (i.e., the radius doesn't change).
     */
    vtkSetClampMacro(Radius,double,0.0,VTK_DOUBLE_MAX);
    vtkGetMacro(Radius,double);
    //@}
  
    //@{
    /**
     * Set / get the relative radius factor defining the local sphere used to
     * estimate the density function. The relative sphere radius is equal to
     * the diagonal length of a voxel times the radius factor. The RelativeRadius
     * is used when the density estimate is set to relative radius (i.e.,
     * relative to voxel size).
     */
    vtkSetClampMacro(RelativeRadius,double,0.0,VTK_DOUBLE_MAX);
    vtkGetMacro(RelativeRadius,double);
    //@}
  
    //@{
    /**
     * Turn on/off the weighting of point density by a scalar array. By default
     * scalar weighting is off.
     */
    vtkSetMacro(ScalarWeighting,bool);
    vtkGetMacro(ScalarWeighting,bool);
    vtkBooleanMacro(ScalarWeighting,bool);
    //@}
  
    //@{
    /**
     * Turn on/off the generation of the gradient vector, gradient magnitude
     * scalar, and function classification scalar. By default this is off. Note
     * that this will increase execution time and the size of the output. (The
     * names of these point data arrays are: "Gradient", "Gradient Magnitude",
     * and "Classification".)
     */
    vtkSetMacro(ComputeGradient,bool);
    vtkGetMacro(ComputeGradient,bool);
    vtkBooleanMacro(ComputeGradient,bool);
    //@}
  
    //@{
    /**
     * Specify a point locator. By default a vtkStaticPointLocator is
     * used. The locator performs efficient searches to locate near a
     * specified interpolation position.
     */
    void SetLocator(vtkAbstractPointLocator *locator);
    vtkGetObjectMacro(Locator,vtkAbstractPointLocator);
    //@}
  
    /**
     * This enum is used to classify the behavior of the function gradient. Regions
     * where all density values used in the calculation of the gradient are zero
     * are referred to as ZERO regions. Otherwise NON_ZERO. This can be used to
     * differentiate between regions where data is available and where it is not.
     */
    enum FunctionClass
    {
      ZERO=0,
      NON_ZERO=1
    };
  
  protected:
    vtkPointDensityFilter();
    ~vtkPointDensityFilter() VTK_OVERRIDE;
  
    int SampleDimensions[3]; // dimensions of volume over which to estimate density
    double ModelBounds[6]; // bounding box of splatting dimensions
    double AdjustDistance; // how much to pad the model bounds if automatically computed
    double Origin[3], Spacing[3]; // output geometry
    int DensityEstimate; // how to compute the density
    int DensityForm; // how to represent density value
    double RelativeRadius; // Radius factor for estimating density
    double Radius; // Actually radius used
    bool ScalarWeighting; // Are point densities weighted or not?
    bool ComputeGradient; // Compute the gradient vector and magnitude
    vtkAbstractPointLocator *Locator; //accelerate point searches
  
    int FillInputPortInformation(int port, vtkInformation* info) VTK_OVERRIDE;
    int RequestInformation (vtkInformation *,
                                    vtkInformationVector **,
                                    vtkInformationVector *) VTK_OVERRIDE;
    int RequestData(vtkInformation *,
                            vtkInformationVector **,
                            vtkInformationVector *) VTK_OVERRIDE;
  
    void ComputeModelBounds(vtkDataSet *input, vtkImageData *output,
                            vtkInformation *outInfo);
  
  private:
    vtkPointDensityFilter(const vtkPointDensityFilter&) VTK_DELETE_FUNCTION;
    void operator=(const vtkPointDensityFilter&) VTK_DELETE_FUNCTION;
  };
  
  #endif
  