/*========================================================================= Program: Visualization Toolkit Module: vtkFixedPointVolumeRayCastMapper.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 vtkVolumeRayCastSpaceLeapingImageFilter * @brief Builds the space leaping data structure. * * This is an optimized multi-threaded imaging filter that builds the space * leaping datastructure, used by vtkFixedPointVolumeRayCastMapper. Empty * space leaping is used to skip large empty regions in the scalar * opacity and/or the gradient opacity transfer functions. Depending on * the various options set by vtkFixedPointVolumeRayCastMapper, the class * will internally invoke one of the many optimized routines to compute the * min/max/gradient-max values within a fixed block size, trying to * compute everything in a single multi-threaded pass through the data * * The block size may be changed at compile time. Its ifdef'ed to 4 in the CXX * file. */ #ifndef vtkVolumeRayCastSpaceLeapingImageFilter_h #define vtkVolumeRayCastSpaceLeapingImageFilter_h #include "vtkRenderingVolumeModule.h" // For export macro #include "vtkThreadedImageAlgorithm.h" class vtkDataArray; class VTKRENDERINGVOLUME_EXPORT vtkVolumeRayCastSpaceLeapingImageFilter : public vtkThreadedImageAlgorithm { public: vtkTypeMacro(vtkVolumeRayCastSpaceLeapingImageFilter,vtkThreadedImageAlgorithm); void PrintSelf(ostream& os, vtkIndent indent) override; static vtkVolumeRayCastSpaceLeapingImageFilter *New(); //@{ /** * Set the scalars. */ virtual void SetCurrentScalars( vtkDataArray * ); vtkGetObjectMacro( CurrentScalars, vtkDataArray ); //@} //@{ /** * Do we use independent components, or dependent components ? */ vtkSetMacro( IndependentComponents, int ); vtkGetMacro( IndependentComponents, int ); //@} //@{ /** * Compute gradient opacity ? */ vtkSetMacro( ComputeGradientOpacity, vtkTypeBool ); vtkGetMacro( ComputeGradientOpacity, vtkTypeBool ); vtkBooleanMacro( ComputeGradientOpacity, vtkTypeBool ); //@} //@{ /** * Compute the min max structure ?. */ vtkSetMacro( ComputeMinMax, vtkTypeBool ); vtkGetMacro( ComputeMinMax, vtkTypeBool ); vtkBooleanMacro( ComputeMinMax, vtkTypeBool ); //@} //@{ /** * Update the gradient opacity flags. (The scalar opacity flags are always * updated upon execution of this filter.) */ vtkSetMacro( UpdateGradientOpacityFlags, vtkTypeBool ); vtkGetMacro( UpdateGradientOpacityFlags, vtkTypeBool ); vtkBooleanMacro( UpdateGradientOpacityFlags, vtkTypeBool ); //@} /** * Get the last execution time. This is updated every * time the scalars or the gradient opacity values are computed */ vtkMTimeType GetLastMinMaxBuildTime() { return LastMinMaxBuildTime.GetMTime(); } /** * Get the last execution time. This is updated every time the flags bits * are re-computed. */ vtkMTimeType GetLastMinMaxFlagTime() { return LastMinMaxFlagTime.GetMTime(); } //@{ /** * Is the difference between max and min of the data less than 32768? If so, * and if the data is not of float/double type, use a simple offset mapping. * If the difference between max and min is 32768 or greater, or the data * is of type float or double, we must use an offset / scaling mapping. * In this case, the array size will be 32768 - we need to figure out the * offset and scale factor. */ vtkSetVector4Macro( TableShift, float ); vtkGetVector4Macro( TableShift, float ); vtkSetVector4Macro( TableScale, float ); vtkGetVector4Macro( TableScale, float ); vtkSetVector4Macro( TableSize, int ); vtkGetVector4Macro( TableSize, int ); //@} /** * Get the number of independent components for which we need to keep track * of min/max */ int GetNumberOfIndependentComponents(); /** * Get the raw pointer to the final computed space leaping datastructure. * The result is only valid after Update() has been called on the filter. * Note that this filter holds onto its memory. The dimensions of the min- * max volume are in dims. The 4th value in the array indicates the number * of independent components, (also queried via * GetNumberOfIndependentComponents()) */ unsigned short * GetMinMaxVolume( int dims[4] ); /** * INTERNAL - Do not use * Set the last cached min-max volume, as used by * vtkFixedPointVolumeRayCastMapper. */ virtual void SetCache(vtkImageData * imageCache); /** * Compute the extents and dimensions of the input that's required to * generate an output min-max structure given by outExt. * INTERNAL - Do not use */ static void ComputeInputExtentsForOutput( int inExt[6], int inDim[3], int outExt[6], vtkImageData *inData ); //@{ /** * Get the first non-zero scalar opacity and gradient opacity indices for * each independent component * INTERNAL - Do not use. */ unsigned short * GetMinNonZeroScalarIndex(); unsigned char * GetMinNonZeroGradientMagnitudeIndex(); //@} //@{ /** * Pointer to the pre-computed gradient magnitude structure. This is pre- * computed by the vtkFixedPointVolumeRayCastMapper class. This should be * set if one has the ComputeGradientOpacity flag enabled. */ void SetGradientMagnitude( unsigned char ** gradientMagnitude ); unsigned char **GetGradientMagnitude(); //@} //@{ /** * Set the scalar opacity and gradient opacity tables computed for each * component by the vtkFixedPointVolumeRayCastMapper */ void SetScalarOpacityTable( int c, unsigned short * t); void SetGradientOpacityTable( int c, unsigned short * t ); //@} /** * INTERNAL - Do not use * Compute the offset within an image of whole extents wholeExt, to access * the data starting at extents ext. */ vtkIdType ComputeOffset(const int ext[6], const int wholeExt[6], int nComponents); // This method helps debug. It writes out a specific component of the // computed min-max-volume structure //static void WriteMinMaxVolume( int component, unsigned short *minMaxVolume, // int minMaxVolumeSize[4], const char *filename ); protected: vtkVolumeRayCastSpaceLeapingImageFilter(); ~vtkVolumeRayCastSpaceLeapingImageFilter() override; int IndependentComponents; vtkTimeStamp LastMinMaxBuildTime; vtkTimeStamp LastMinMaxFlagTime; vtkDataArray * CurrentScalars; float TableShift[4]; float TableScale[4]; int TableSize[4]; vtkTypeBool ComputeGradientOpacity; vtkTypeBool ComputeMinMax; vtkTypeBool UpdateGradientOpacityFlags; unsigned short * MinNonZeroScalarIndex; unsigned char * MinNonZeroGradientMagnitudeIndex; unsigned char ** GradientMagnitude; unsigned short * ScalarOpacityTable[4]; unsigned short * GradientOpacityTable[4]; vtkImageData * Cache; void InternalRequestUpdateExtent(int *, int*); //@{ /** * See superclass for details */ int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override; void ThreadedRequestData( vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector, vtkImageData ***inData, vtkImageData **outData, int outExt[6], int id) override; int RequestData( vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector) override; int RequestInformation( vtkInformation *, vtkInformationVector**, vtkInformationVector *) override; //@} /** * Compute the first non-zero scalar opacity and gradient opacity values * that are encountered when marching from the beginning of the transfer * function tables. */ void ComputeFirstNonZeroOpacityIndices(); /** * Fill the flags after processing the min/max/gradient structure. This * optimized version is invoked when only scalar opacity table is needed. */ void FillScalarOpacityFlags( vtkImageData *minMaxVolume, int outExt[6] ); /** * Fill the flags after processing the min/max/gradient structure. This * optimized version is invoked when both scalar and gradient opacity * tables need to be visited. */ void FillScalarAndGradientOpacityFlags( vtkImageData *minMaxVolume, int outExt[6] ); //@{ /** * Allocate the output data. If we have a cache with the same metadata as * the output we are going to generate, re-use the cache as we may not be * updating all data in the min-max structure. */ void AllocateOutputData(vtkImageData *out, vtkInformation* outInfo, int *uExtent) override; vtkImageData *AllocateOutputData(vtkDataObject *out, vtkInformation *outInfo) override; //@} private: vtkVolumeRayCastSpaceLeapingImageFilter(const vtkVolumeRayCastSpaceLeapingImageFilter&) = delete; void operator=(const vtkVolumeRayCastSpaceLeapingImageFilter&) = delete; }; #endif