/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkGaussianSplatter.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 vtkGaussianSplatter - splat points into a volume with an elliptical, Gaussian distribution // .SECTION Description // vtkGaussianSplatter is a filter that injects input points into a // structured points (volume) dataset. As each point is injected, it "splats" // or distributes values to nearby voxels. Data is distributed using an // elliptical, Gaussian distribution function. The distribution function is // modified using scalar values (expands distribution) or normals // (creates ellipsoidal distribution rather than spherical). // // In general, the Gaussian distribution function f(x) around a given // splat point p is given by // // f(x) = ScaleFactor * exp( ExponentFactor*((r/Radius)**2) ) // // where x is the current voxel sample point; r is the distance |x-p| // ExponentFactor <= 0.0, and ScaleFactor can be multiplied by the scalar // value of the point p that is currently being splatted. // // If points normals are present (and NormalWarping is on), then the splat // function becomes elliptical (as compared to the spherical one described // by the previous equation). The Gaussian distribution function then // becomes: // // f(x) = ScaleFactor * // exp( ExponentFactor*( ((rxy/E)**2 + z**2)/R**2) ) // // where 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 normal N; and rxy is the distance of x in the direction // prependicular to N. // // This class is typically used to convert point-valued distributions into // a volume representation. The volume is then usually iso-surfaced or // volume rendered to generate a visualization. It can be used to create // surfaces from point distributions, or to create structure (i.e., // topology) when none exists. // .SECTION Caveats // The input to this filter is any dataset type. This filter can be used // to resample any form of data, i.e., the input data need not be // unstructured. // // Some voxels may never receive a contribution during the splatting process. // The final value of these points can be specified with the "NullValue" // instance variable. // .SECTION See Also // vtkShepardMethod #ifndef __vtkGaussianSplatter_h #define __vtkGaussianSplatter_h #include "vtkImageAlgorithm.h" #define VTK_ACCUMULATION_MODE_MIN 0 #define VTK_ACCUMULATION_MODE_MAX 1 #define VTK_ACCUMULATION_MODE_SUM 2 class vtkDoubleArray; class VTK_IMAGING_EXPORT vtkGaussianSplatter : public vtkImageAlgorithm { public: vtkTypeRevisionMacro(vtkGaussianSplatter,vtkImageAlgorithm); void PrintSelf(ostream& os, vtkIndent indent); // Description: // Construct object with dimensions=(50,50,50); automatic computation of // bounds; a splat radius of 0.1; an exponent factor of -5; and normal and // scalar warping turned on. static vtkGaussianSplatter *New(); // Description: // Set / get the dimensions of the sampling structured point set. Higher // values produce better results but are much slower. void SetSampleDimensions(int i, int j, int k); void SetSampleDimensions(int dim[3]); vtkGetVectorMacro(SampleDimensions,int,3); // Description: // 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); // Description: // Set / get the radius of propagation of the splat. This value is expressed // as a percentage of the length of the longest side of the sampling // volume. Smaller numbers greatly reduce execution time. vtkSetClampMacro(Radius,double,0.0,1.0); vtkGetMacro(Radius,double); // Description: // Multiply Gaussian splat distribution by this value. If ScalarWarping // is on, 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); // Description: // Set / get the sharpness of decay of the splats. This is the // exponent constant in the Gaussian equation. Normally this is // a negative value. vtkSetMacro(ExponentFactor,double); vtkGetMacro(ExponentFactor,double); // Description: // Turn on/off the generation of elliptical splats. If normal warping is // on, then the input normals affect the distribution of the splat. This // boolean is used in combination with the Eccentricity ivar. vtkSetMacro(NormalWarping,int); vtkGetMacro(NormalWarping,int); vtkBooleanMacro(NormalWarping,int); // Description: // Control the shape of elliptical splatting. Eccentricity is the ratio // of the major axis (aligned along normal) to the minor (axes) aligned // along other two axes. So Eccentricity > 1 creates needles with the // long axis in the direction of the normal; Eccentricity<1 creates // pancakes perpendicular to the normal vector. vtkSetClampMacro(Eccentricity,double,0.001,VTK_DOUBLE_MAX); vtkGetMacro(Eccentricity,double); // Description: // Turn on/off the scaling of splats by scalar value. vtkSetMacro(ScalarWarping,int); vtkGetMacro(ScalarWarping,int); vtkBooleanMacro(ScalarWarping,int); // Description: // Turn on/off the capping of the outer boundary of the volume // to a specified cap value. This can be used to close surfaces // (after iso-surfacing) and create other effects. vtkSetMacro(Capping,int); vtkGetMacro(Capping,int); vtkBooleanMacro(Capping,int); // Description: // Specify the cap value to use. (This instance variable only has effect // if the ivar Capping is on.) vtkSetMacro(CapValue,double); vtkGetMacro(CapValue,double); // Description: // Specify the scalar accumulation mode. This mode expresses how scalar // values are combined when splats are overlapped. The Max mode acts // like a set union operation and is the most commonly used; the Min // mode acts like a set intersection, and the sum is just weird. vtkSetClampMacro(AccumulationMode,int, VTK_ACCUMULATION_MODE_MIN,VTK_ACCUMULATION_MODE_SUM); vtkGetMacro(AccumulationMode,int); void SetAccumulationModeToMin() {this->SetAccumulationMode(VTK_ACCUMULATION_MODE_MIN);} void SetAccumulationModeToMax() {this->SetAccumulationMode(VTK_ACCUMULATION_MODE_MAX);} void SetAccumulationModeToSum() {this->SetAccumulationMode(VTK_ACCUMULATION_MODE_SUM);} const char *GetAccumulationModeAsString(); // Description: // Set the Null value for output points not receiving a contribution from the // input points. (This is the initial value of the voxel samples.) vtkSetMacro(NullValue,double); vtkGetMacro(NullValue,double); // Description: // Compute the size of the sample bounding box automatically from the // input data. This is an internal helper function. void ComputeModelBounds(vtkDataSet *input, vtkImageData *output, vtkInformation *outInfo); protected: vtkGaussianSplatter(); ~vtkGaussianSplatter() {}; virtual int FillInputPortInformation(int port, vtkInformation* info); virtual int RequestInformation (vtkInformation *, vtkInformationVector **, vtkInformationVector *); virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); void Cap(vtkDoubleArray *s); int SampleDimensions[3]; // dimensions of volume to splat into double Radius; // maximum distance splat propagates (as fraction 0->1) double ExponentFactor; // scale exponent of gaussian function double ModelBounds[6]; // bounding box of splatting dimensions int NormalWarping; // on/off warping of splat via normal double Eccentricity;// elliptic distortion due to normals int ScalarWarping; // on/off warping of splat via scalar double ScaleFactor; // splat size influenced by scale factor int Capping; // Cap side of volume to close surfaces double CapValue; // value to use for capping int AccumulationMode; // how to combine scalar values double Gaussian(double x[3]); double EccentricGaussian(double x[3]); double ScalarSampling(double s) {return this->ScaleFactor * s;} double PositionSampling(double) {return this->ScaleFactor;} void SetScalar(int idx, double dist2, vtkDoubleArray *newScalars); //BTX private: double Radius2; double (vtkGaussianSplatter::*Sample)(double x[3]); double (vtkGaussianSplatter::*SampleFactor)(double s); char *Visited; double Eccentricity2; double *P; double *N; double S; double Origin[3]; double Spacing[3]; double SplatDistance[3]; double NullValue; //ETX private: vtkGaussianSplatter(const vtkGaussianSplatter&); // Not implemented. void operator=(const vtkGaussianSplatter&); // Not implemented. }; #endif