vtk9/Rendering/Volume/vtkVolumeRayCastSpaceLeapin...

266 lines
9.0 KiB
C++

/*=========================================================================
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