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.
752 lines
24 KiB
C++
752 lines
24 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkFixedPointVolumeRayCastMIPHelper.cxx
|
|
|
|
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.
|
|
|
|
=========================================================================*/
|
|
#include "vtkFixedPointVolumeRayCastMIPHelper.h"
|
|
|
|
#include "vtkImageData.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkFixedPointVolumeRayCastMapper.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkRenderWindow.h"
|
|
#include "vtkVolume.h"
|
|
#include "vtkVolumeProperty.h"
|
|
#include "vtkFixedPointRayCastImage.h"
|
|
#include "vtkDataArray.h"
|
|
|
|
#include <cmath>
|
|
|
|
vtkStandardNewMacro(vtkFixedPointVolumeRayCastMIPHelper);
|
|
|
|
// Construct a new vtkFixedPointVolumeRayCastMIPHelper with default values
|
|
vtkFixedPointVolumeRayCastMIPHelper::vtkFixedPointVolumeRayCastMIPHelper()
|
|
{
|
|
}
|
|
|
|
// Destruct a vtkFixedPointVolumeRayCastMIPHelper - clean up any memory used
|
|
vtkFixedPointVolumeRayCastMIPHelper::~vtkFixedPointVolumeRayCastMIPHelper()
|
|
{
|
|
}
|
|
|
|
// This method is called when the interpolation type is nearest neighbor and
|
|
// the data contains one component. In the inner loop we will compute the
|
|
// maximum value (in native type). After we have a maximum value for the ray
|
|
// we will convert it to unsigned short using the scale/shift, then use this
|
|
// index to lookup the final color/opacity.
|
|
template <class T>
|
|
void vtkFixedPointMIPHelperGenerateImageOneNN( T *data,
|
|
int threadID,
|
|
int threadCount,
|
|
vtkFixedPointVolumeRayCastMapper *mapper,
|
|
vtkVolume *vtkNotUsed(vol))
|
|
{
|
|
VTKKWRCHelper_InitializationAndLoopStartNN();
|
|
VTKKWRCHelper_InitializeMIPOneNN();
|
|
VTKKWRCHelper_SpaceLeapSetup();
|
|
|
|
if ( cropping )
|
|
{
|
|
int maxValueDefined = 0;
|
|
unsigned short maxIdx = 0;
|
|
|
|
for ( k = 0; k < numSteps; k++ )
|
|
{
|
|
if ( k )
|
|
{
|
|
mapper->FixedPointIncrement( pos, dir );
|
|
}
|
|
|
|
VTKKWRCHelper_MIPSpaceLeapCheck( maxIdx, maxValueDefined, mapper->GetFlipMIPComparison() );
|
|
|
|
if ( !mapper->CheckIfCropped( pos ) )
|
|
{
|
|
mapper->ShiftVectorDown( pos, spos );
|
|
dptr = data + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
|
|
if ( !maxValueDefined ||
|
|
( (mapper->GetFlipMIPComparison() && *dptr < maxValue) ||
|
|
(!mapper->GetFlipMIPComparison() && *dptr > maxValue) ) )
|
|
{
|
|
maxValue = *dptr;
|
|
maxIdx = static_cast<unsigned short>((maxValue + shift[0])*scale[0]);
|
|
maxValueDefined = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( maxValueDefined )
|
|
{
|
|
VTKKWRCHelper_LookupColorMax( colorTable[0], scalarOpacityTable[0], maxIdx, imagePtr );
|
|
}
|
|
else
|
|
{
|
|
imagePtr[0] = imagePtr[1] = imagePtr[2] = imagePtr[3] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
unsigned short maxIdx =
|
|
static_cast<unsigned short>((maxValue + shift[0])*scale[0]);
|
|
|
|
for ( k = 0; k < numSteps; k++ )
|
|
{
|
|
if ( k )
|
|
{
|
|
mapper->FixedPointIncrement( pos, dir );
|
|
}
|
|
|
|
VTKKWRCHelper_MIPSpaceLeapCheck( maxIdx, 1, mapper->GetFlipMIPComparison() );
|
|
|
|
mapper->ShiftVectorDown( pos, spos );
|
|
dptr = data + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
|
|
if ( mapper->GetFlipMIPComparison() )
|
|
{
|
|
maxValue = ( *dptr < maxValue )?(*dptr):(maxValue);
|
|
}
|
|
else
|
|
{
|
|
maxValue = ( *dptr > maxValue )?(*dptr):(maxValue);
|
|
}
|
|
|
|
maxIdx = static_cast<unsigned short>((maxValue + shift[0])*scale[0]);
|
|
}
|
|
|
|
VTKKWRCHelper_LookupColorMax( colorTable[0], scalarOpacityTable[0], maxIdx, imagePtr );
|
|
}
|
|
|
|
VTKKWRCHelper_IncrementAndLoopEnd();
|
|
|
|
}
|
|
|
|
// This method is called when the interpolation type is nearest neighbor and
|
|
// the data has two or four dependent components. If it is four, they must be
|
|
// unsigned char components. Compute max of last components in native type,
|
|
// then use first component to look up a color (2 component data) or first three
|
|
// as the color directly (four component data). Lookup alpha off the last component.
|
|
template <class T>
|
|
void vtkFixedPointMIPHelperGenerateImageDependentNN(
|
|
T *data,
|
|
int threadID,
|
|
int threadCount,
|
|
vtkFixedPointVolumeRayCastMapper *mapper,
|
|
vtkVolume *vtkNotUsed(vol))
|
|
{
|
|
VTKKWRCHelper_InitializationAndLoopStartNN();
|
|
VTKKWRCHelper_InitializeMIPMultiNN();
|
|
VTKKWRCHelper_SpaceLeapSetup();
|
|
|
|
int maxValueDefined = 0;
|
|
unsigned short maxIdxS = 0;
|
|
|
|
for ( k = 0; k < numSteps; k++ )
|
|
{
|
|
if ( k )
|
|
{
|
|
mapper->FixedPointIncrement( pos, dir );
|
|
}
|
|
|
|
VTKKWRCHelper_MIPSpaceLeapCheck( maxIdxS, maxValueDefined,
|
|
mapper->GetFlipMIPComparison() );
|
|
VTKKWRCHelper_CroppingCheckNN( pos );
|
|
|
|
mapper->ShiftVectorDown( pos, spos );
|
|
dptr = data + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
|
|
if ( !maxValueDefined ||
|
|
( ( mapper->GetFlipMIPComparison() && *(dptr + components - 1) < maxValue[components-1] ) ||
|
|
( !mapper->GetFlipMIPComparison() && *(dptr + components - 1) > maxValue[components-1] ) ) )
|
|
{
|
|
for ( c = 0; c < components; c++ )
|
|
{
|
|
maxValue[c] = *(dptr+c);
|
|
}
|
|
maxIdxS =
|
|
static_cast<unsigned short>((maxValue[components-1] +
|
|
shift[components-1])*scale[components-1]);
|
|
maxValueDefined = 1;
|
|
}
|
|
}
|
|
|
|
if ( maxValueDefined )
|
|
{
|
|
unsigned short maxIdx[4]={0,0,0,0};
|
|
if ( components == 2 )
|
|
{
|
|
maxIdx[0] = static_cast<unsigned short>((maxValue[0] +
|
|
shift[0])*scale[0]);
|
|
maxIdx[1] = static_cast<unsigned short>((maxValue[1] +
|
|
shift[1])*scale[1]);
|
|
}
|
|
else
|
|
{
|
|
maxIdx[0] = static_cast<unsigned short>(maxValue[0]);
|
|
maxIdx[1] = static_cast<unsigned short>(maxValue[1]);
|
|
maxIdx[2] = static_cast<unsigned short>(maxValue[2]);
|
|
maxIdx[3] = static_cast<unsigned short>((maxValue[3] +
|
|
shift[3])*scale[3]);
|
|
}
|
|
|
|
for ( c = 0; c < components; c++ )
|
|
{
|
|
}
|
|
VTKKWRCHelper_LookupDependentColorUS( colorTable[0], scalarOpacityTable[0],
|
|
maxIdx, components, imagePtr );
|
|
}
|
|
else
|
|
{
|
|
imagePtr[0] = imagePtr[1] = imagePtr[2] = imagePtr[3] = 0;
|
|
}
|
|
|
|
VTKKWRCHelper_IncrementAndLoopEnd();
|
|
}
|
|
|
|
// This method is called when the interpolation type is nearest neighbor and
|
|
// the data has more than one independent components. We compute the max of
|
|
// each component along the ray in native type, then use the scale/shift to
|
|
// convert this into an unsigned short index value. We use the index values
|
|
// to lookup the color/opacity per component, then use the component weights to
|
|
// blend these into one final color.
|
|
template <class T>
|
|
void vtkFixedPointMIPHelperGenerateImageIndependentNN(
|
|
T *data,
|
|
int threadID,
|
|
int threadCount,
|
|
vtkFixedPointVolumeRayCastMapper *mapper,
|
|
vtkVolume *vol)
|
|
{
|
|
VTKKWRCHelper_InitializeWeights();
|
|
VTKKWRCHelper_InitializationAndLoopStartNN();
|
|
VTKKWRCHelper_InitializeMIPMultiNN();
|
|
VTKKWRCHelper_SpaceLeapSetupMulti();
|
|
|
|
int maxValueDefined = 0;
|
|
unsigned short maxIdx[4] = {0, 0, 0, 0};
|
|
|
|
for ( k = 0; k < numSteps; k++ )
|
|
{
|
|
if ( k )
|
|
{
|
|
mapper->FixedPointIncrement( pos, dir );
|
|
}
|
|
VTKKWRCHelper_CroppingCheckNN( pos );
|
|
VTKKWRCHelper_MIPSpaceLeapPopulateMulti( maxIdx,
|
|
mapper->GetFlipMIPComparison() )
|
|
|
|
mapper->ShiftVectorDown( pos, spos );
|
|
dptr = data + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
|
|
|
|
if ( !maxValueDefined )
|
|
{
|
|
for ( c = 0; c < components; c++ )
|
|
{
|
|
maxValue[c] = *(dptr+c);
|
|
maxIdx[c] = static_cast<unsigned short>((maxValue[c] +
|
|
shift[c])*scale[c]);
|
|
}
|
|
maxValueDefined = 1;
|
|
}
|
|
else
|
|
{
|
|
for ( c = 0; c < components; c++ )
|
|
{
|
|
if ( VTKKWRCHelper_MIPSpaceLeapCheckMulti( c, mapper->GetFlipMIPComparison() ) &&
|
|
((mapper->GetFlipMIPComparison() && *(dptr + c) < maxValue[c] ) ||
|
|
(!mapper->GetFlipMIPComparison() && *(dptr + c) > maxValue[c] )) )
|
|
{
|
|
maxValue[c] = *(dptr+c);
|
|
maxIdx[c] = static_cast<unsigned short>((maxValue[c] +
|
|
shift[c])*scale[c]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
imagePtr[0] = imagePtr[1] = imagePtr[2] = imagePtr[3] = 0;
|
|
if ( maxValueDefined )
|
|
{
|
|
VTKKWRCHelper_LookupAndCombineIndependentColorsMax(colorTable,
|
|
scalarOpacityTable,
|
|
maxIdx, weights,
|
|
components, imagePtr );
|
|
}
|
|
|
|
VTKKWRCHelper_IncrementAndLoopEnd();
|
|
}
|
|
|
|
// This method is called when the interpolation type is linear, the
|
|
// data contains one component and scale = 1.0 and shift = 0.0. This is
|
|
// the simple case were we do not need to apply scale/shift in the
|
|
// inner loop. In the inner loop we compute the eight cell vertex values
|
|
// (if we have changed cells). We compute our weights within the cell
|
|
// according to our fractional position within the cell, and apply trilinear
|
|
// interpolation to compute the index. We find the maximum index along
|
|
// the ray, and then use this to look up a final color.
|
|
template <class T>
|
|
void vtkFixedPointMIPHelperGenerateImageOneSimpleTrilin(
|
|
T *dataPtr,
|
|
int threadID,
|
|
int threadCount,
|
|
vtkFixedPointVolumeRayCastMapper *mapper,
|
|
vtkVolume *vtkNotUsed(vol))
|
|
{
|
|
VTKKWRCHelper_InitializationAndLoopStartTrilin();
|
|
VTKKWRCHelper_InitializeMIPOneTrilin();
|
|
VTKKWRCHelper_SpaceLeapSetup();
|
|
|
|
int maxValueDefined = 0;
|
|
unsigned short maxIdx=0;
|
|
unsigned int maxScalar = 0;
|
|
|
|
for ( k = 0; k < numSteps; k++ )
|
|
{
|
|
if ( k )
|
|
{
|
|
mapper->FixedPointIncrement( pos, dir );
|
|
}
|
|
|
|
VTKKWRCHelper_MIPSpaceLeapCheck( maxIdx, maxValueDefined,
|
|
mapper->GetFlipMIPComparison() );
|
|
VTKKWRCHelper_CroppingCheckTrilin( pos );
|
|
|
|
mapper->ShiftVectorDown( pos, spos );
|
|
if ( spos[0] != oldSPos[0] ||
|
|
spos[1] != oldSPos[1] ||
|
|
spos[2] != oldSPos[2] )
|
|
{
|
|
oldSPos[0] = spos[0];
|
|
oldSPos[1] = spos[1];
|
|
oldSPos[2] = spos[2];
|
|
|
|
dptr = dataPtr + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
|
|
VTKKWRCHelper_GetCellScalarValuesSimple( dptr );
|
|
if ( mapper->GetFlipMIPComparison() )
|
|
{
|
|
maxScalar = (A<B)?(A):(B);
|
|
maxScalar = (C<maxScalar)?(C):(maxScalar);
|
|
maxScalar = (D<maxScalar)?(D):(maxScalar);
|
|
maxScalar = (E<maxScalar)?(E):(maxScalar);
|
|
maxScalar = (F<maxScalar)?(F):(maxScalar);
|
|
maxScalar = (G<maxScalar)?(G):(maxScalar);
|
|
maxScalar = (H<maxScalar)?(H):(maxScalar);
|
|
}
|
|
else
|
|
{
|
|
maxScalar = (A>B)?(A):(B);
|
|
maxScalar = (C>maxScalar)?(C):(maxScalar);
|
|
maxScalar = (D>maxScalar)?(D):(maxScalar);
|
|
maxScalar = (E>maxScalar)?(E):(maxScalar);
|
|
maxScalar = (F>maxScalar)?(F):(maxScalar);
|
|
maxScalar = (G>maxScalar)?(G):(maxScalar);
|
|
maxScalar = (H>maxScalar)?(H):(maxScalar);
|
|
}
|
|
|
|
}
|
|
|
|
if ( !maxValueDefined ||
|
|
((mapper->GetFlipMIPComparison() && maxScalar < static_cast<unsigned int>(maxValue) ) ||
|
|
(!mapper->GetFlipMIPComparison() && maxScalar > static_cast<unsigned int>(maxValue) )) )
|
|
{
|
|
VTKKWRCHelper_ComputeWeights(pos);
|
|
VTKKWRCHelper_InterpolateScalar(val);
|
|
|
|
if ( !maxValueDefined ||
|
|
((mapper->GetFlipMIPComparison() && val < maxValue ) ||
|
|
(!mapper->GetFlipMIPComparison() && val > maxValue )) )
|
|
{
|
|
maxValue = val;
|
|
maxIdx = static_cast<unsigned short>(maxValue);
|
|
maxValueDefined = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( maxValueDefined )
|
|
{
|
|
VTKKWRCHelper_LookupColorMax( colorTable[0], scalarOpacityTable[0], maxIdx, imagePtr );
|
|
}
|
|
else
|
|
{
|
|
imagePtr[0] = imagePtr[1] = imagePtr[2] = imagePtr[3] = 0;
|
|
}
|
|
|
|
VTKKWRCHelper_IncrementAndLoopEnd();
|
|
}
|
|
|
|
|
|
// This method is called when the interpolation type is linear, the
|
|
// data contains one component and scale != 1.0 or shift != 0.0. This
|
|
// means that we need to apply scale/shift in the inner loop to compute
|
|
// an unsigned short index value. In the inner loop we compute the eight cell
|
|
// vertex values (as unsigned short indices, if we have changed cells). We
|
|
// compute our weights within the cell according to our fractional position
|
|
// within the cell, and apply trilinear interpolation to compute the index.
|
|
// We find the maximum index along the ray, and then use this to look up a
|
|
// final color.
|
|
template <class T>
|
|
void vtkFixedPointMIPHelperGenerateImageOneTrilin(
|
|
T *dataPtr,
|
|
int threadID,
|
|
int threadCount,
|
|
vtkFixedPointVolumeRayCastMapper *mapper,
|
|
vtkVolume *vtkNotUsed(vol))
|
|
{
|
|
VTKKWRCHelper_InitializationAndLoopStartTrilin();
|
|
VTKKWRCHelper_InitializeMIPOneTrilin();
|
|
VTKKWRCHelper_SpaceLeapSetup();
|
|
|
|
int maxValueDefined = 0;
|
|
unsigned short maxIdx = 0;
|
|
for ( k = 0; k < numSteps; k++ )
|
|
{
|
|
if ( k )
|
|
{
|
|
mapper->FixedPointIncrement( pos, dir );
|
|
}
|
|
|
|
VTKKWRCHelper_CroppingCheckTrilin( pos );
|
|
VTKKWRCHelper_MIPSpaceLeapCheck( maxIdx, maxValueDefined,
|
|
mapper->GetFlipMIPComparison() );
|
|
|
|
mapper->ShiftVectorDown( pos, spos );
|
|
if ( spos[0] != oldSPos[0] ||
|
|
spos[1] != oldSPos[1] ||
|
|
spos[2] != oldSPos[2] )
|
|
{
|
|
oldSPos[0] = spos[0];
|
|
oldSPos[1] = spos[1];
|
|
oldSPos[2] = spos[2];
|
|
|
|
|
|
dptr = dataPtr + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
|
|
VTKKWRCHelper_GetCellScalarValues( dptr, scale[0], shift[0] );
|
|
}
|
|
|
|
VTKKWRCHelper_ComputeWeights(pos);
|
|
VTKKWRCHelper_InterpolateScalar(val);
|
|
|
|
if ( !maxValueDefined ||
|
|
((mapper->GetFlipMIPComparison() && val < maxValue ) ||
|
|
(!mapper->GetFlipMIPComparison() && val > maxValue )) )
|
|
{
|
|
maxValue = val;
|
|
maxIdx = static_cast<unsigned short>(maxValue);
|
|
maxValueDefined = 1;
|
|
}
|
|
}
|
|
|
|
if ( maxValueDefined )
|
|
{
|
|
VTKKWRCHelper_LookupColorMax( colorTable[0], scalarOpacityTable[0],
|
|
maxIdx, imagePtr );
|
|
}
|
|
else
|
|
{
|
|
imagePtr[0] = imagePtr[1] = imagePtr[2] = imagePtr[3] = 0;
|
|
}
|
|
|
|
VTKKWRCHelper_IncrementAndLoopEnd();
|
|
}
|
|
|
|
// This method is used when the interpolation type is linear, the data has
|
|
// two or four components and the components are not considered independent.
|
|
// For four component d>>(VTKKW_FP_SHIFT - 8));ata, the data must be unsigned char in type. In the
|
|
// inner loop we get the data value for the eight cell corners (if we have
|
|
// changed cells) for all components as unsigned shorts (we use the
|
|
// scale/shift to ensure the correct range). We compute our weights within
|
|
// the cell according to our fractional position within the cell, and apply
|
|
// trilinear interpolation to compute the index values. For two component data,
|
|
// We use the first index to lookup a color and the second to look up an opacity
|
|
// for this sample. For four component data we use the first three components
|
|
// directly as a color, then we look up the opacity using the fourth component.
|
|
// We then composite this into the color computed so far along the ray, and
|
|
// check if we can terminate at this point (if the accumulated opacity is
|
|
// higher than some threshold).
|
|
template <class T>
|
|
void vtkFixedPointMIPHelperGenerateImageDependentTrilin(
|
|
T *dataPtr,
|
|
int threadID,
|
|
int threadCount,
|
|
vtkFixedPointVolumeRayCastMapper *mapper,
|
|
vtkVolume *vtkNotUsed(vol))
|
|
{
|
|
VTKKWRCHelper_InitializationAndLoopStartTrilin();
|
|
VTKKWRCHelper_InitializeMIPMultiTrilin();
|
|
VTKKWRCHelper_SpaceLeapSetup();
|
|
|
|
int maxValueDefined = 0;
|
|
unsigned short maxIdx = 0;
|
|
for ( k = 0; k < numSteps; k++ )
|
|
{
|
|
if ( k )
|
|
{
|
|
mapper->FixedPointIncrement( pos, dir );
|
|
}
|
|
|
|
VTKKWRCHelper_CroppingCheckTrilin( pos );
|
|
VTKKWRCHelper_MIPSpaceLeapCheck( maxIdx, maxValueDefined,
|
|
mapper->GetFlipMIPComparison() );
|
|
|
|
mapper->ShiftVectorDown( pos, spos );
|
|
if ( spos[0] != oldSPos[0] ||
|
|
spos[1] != oldSPos[1] ||
|
|
spos[2] != oldSPos[2] )
|
|
{
|
|
oldSPos[0] = spos[0];
|
|
oldSPos[1] = spos[1];
|
|
oldSPos[2] = spos[2];
|
|
|
|
if ( components == 2 )
|
|
{
|
|
for ( c= 0; c < components; c++ )
|
|
{
|
|
dptr = dataPtr + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2]+ c;
|
|
VTKKWRCHelper_GetCellComponentScalarValues( dptr, c, scale[c],
|
|
shift[c] );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( c= 0; c < 3; c++ )
|
|
{
|
|
dptr = dataPtr + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2]+ c;
|
|
VTKKWRCHelper_GetCellComponentRawScalarValues( dptr, c );
|
|
}
|
|
dptr = dataPtr + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2] + c;
|
|
VTKKWRCHelper_GetCellComponentScalarValues( dptr,3,scale[3],shift[3] );
|
|
}
|
|
|
|
}
|
|
|
|
VTKKWRCHelper_ComputeWeights(pos);
|
|
VTKKWRCHelper_InterpolateScalarComponent( val, c, components );
|
|
|
|
if ( !maxValueDefined ||
|
|
((mapper->GetFlipMIPComparison() && (val[components-1] < maxValue[components-1]) ) ||
|
|
(!mapper->GetFlipMIPComparison() && (val[components-1] > maxValue[components-1]) )) )
|
|
{
|
|
for ( c= 0; c < components; c++ )
|
|
{
|
|
maxValue[c] = val[c];
|
|
}
|
|
maxIdx = static_cast<unsigned short>((maxValue[components-1] +
|
|
shift[components-1])*scale[components-1]);
|
|
maxValueDefined = 1;
|
|
}
|
|
}
|
|
|
|
if ( maxValueDefined )
|
|
{
|
|
VTKKWRCHelper_LookupDependentColorUS( colorTable[0],
|
|
scalarOpacityTable[0],
|
|
maxValue, components, imagePtr );
|
|
}
|
|
else
|
|
{
|
|
imagePtr[0] = imagePtr[1] = imagePtr[2] = imagePtr[3] = 0;
|
|
}
|
|
|
|
VTKKWRCHelper_IncrementAndLoopEnd();
|
|
}
|
|
|
|
// This method is used when the interpolation type is linear, the data has
|
|
// more than one component and the components are considered independent. In
|
|
// the inner loop we get the data value for the eight cell corners (if we have
|
|
// changed cells) for all components as an unsigned shorts (we have to use the
|
|
// scale/shift to ensure that we obtained unsigned short indices) We compute
|
|
// our weights within the cell according to our fractional position within the
|
|
// cell, and apply trilinear interpolation to compute a value for each
|
|
// component. We do this for each sample along the ray to find a maximum value
|
|
// per component, then we look up a color/opacity for each component and blend
|
|
// them according to the component weights.
|
|
template <class T>
|
|
void vtkFixedPointMIPHelperGenerateImageIndependentTrilin(
|
|
T *dataPtr,
|
|
int threadID,
|
|
int threadCount,
|
|
vtkFixedPointVolumeRayCastMapper *mapper,
|
|
vtkVolume *vol)
|
|
{
|
|
VTKKWRCHelper_InitializeWeights();
|
|
VTKKWRCHelper_InitializationAndLoopStartTrilin();
|
|
VTKKWRCHelper_InitializeMIPMultiTrilin();
|
|
|
|
int maxValueDefined = 0;
|
|
for ( k = 0; k < numSteps; k++ )
|
|
{
|
|
if ( k )
|
|
{
|
|
mapper->FixedPointIncrement( pos, dir );
|
|
}
|
|
|
|
VTKKWRCHelper_CroppingCheckTrilin( pos );
|
|
|
|
mapper->ShiftVectorDown( pos, spos );
|
|
if ( spos[0] != oldSPos[0] ||
|
|
spos[1] != oldSPos[1] ||
|
|
spos[2] != oldSPos[2] )
|
|
{
|
|
oldSPos[0] = spos[0];
|
|
oldSPos[1] = spos[1];
|
|
oldSPos[2] = spos[2];
|
|
|
|
for ( c= 0; c < components; c++ )
|
|
{
|
|
dptr = dataPtr + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2] + c;
|
|
VTKKWRCHelper_GetCellComponentScalarValues( dptr, c, scale[c],
|
|
shift[c] );
|
|
}
|
|
}
|
|
|
|
VTKKWRCHelper_ComputeWeights(pos);
|
|
VTKKWRCHelper_InterpolateScalarComponent( val, c, components );
|
|
|
|
if ( !maxValueDefined )
|
|
{
|
|
for ( c= 0; c < components; c++ )
|
|
{
|
|
maxValue[c] = val[c];
|
|
}
|
|
maxValueDefined = 1;
|
|
}
|
|
else
|
|
{
|
|
for ( c= 0; c < components; c++ )
|
|
{
|
|
if ( ( mapper->GetFlipMIPComparison() && val[c] < maxValue[c] ) ||
|
|
( !mapper->GetFlipMIPComparison() && val[c] > maxValue[c] ) )
|
|
{
|
|
maxValue[c] = val[c];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
imagePtr[0] = imagePtr[1] = imagePtr[2] = imagePtr[3] = 0;
|
|
if ( maxValueDefined )
|
|
{
|
|
VTKKWRCHelper_LookupAndCombineIndependentColorsMax( colorTable,
|
|
scalarOpacityTable,
|
|
maxValue, weights,
|
|
components, imagePtr );
|
|
}
|
|
|
|
VTKKWRCHelper_IncrementAndLoopEnd();
|
|
}
|
|
|
|
void vtkFixedPointVolumeRayCastMIPHelper::GenerateImage(
|
|
int threadID,
|
|
int threadCount,
|
|
vtkVolume *vol,
|
|
vtkFixedPointVolumeRayCastMapper *mapper )
|
|
{
|
|
void *dataPtr = mapper->GetCurrentScalars()->GetVoidPointer(0);
|
|
int scalarType = mapper->GetCurrentScalars()->GetDataType();
|
|
|
|
// Nearest Neighbor interpolate
|
|
if ( mapper->ShouldUseNearestNeighborInterpolation( vol ) )
|
|
{
|
|
// One component data
|
|
if ( mapper->GetCurrentScalars()->GetNumberOfComponents() == 1 )
|
|
{
|
|
switch ( scalarType )
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkFixedPointMIPHelperGenerateImageOneNN(
|
|
static_cast<VTK_TT *>(dataPtr),
|
|
threadID, threadCount, mapper, vol) );
|
|
}
|
|
}
|
|
// More that one independent components
|
|
else if ( vol->GetProperty()->GetIndependentComponents() )
|
|
{
|
|
switch ( scalarType )
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkFixedPointMIPHelperGenerateImageIndependentNN(
|
|
static_cast<VTK_TT *>(dataPtr),
|
|
threadID, threadCount, mapper, vol) );
|
|
}
|
|
}
|
|
// Dependent (color) components
|
|
else
|
|
{
|
|
switch ( scalarType )
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkFixedPointMIPHelperGenerateImageDependentNN(
|
|
static_cast<VTK_TT *>(dataPtr),
|
|
threadID, threadCount, mapper, vol) );
|
|
}
|
|
}
|
|
}
|
|
// Trilinear Interpolation
|
|
else
|
|
{
|
|
// One component
|
|
if ( mapper->GetCurrentScalars()->GetNumberOfComponents() == 1 )
|
|
{
|
|
// Scale == 1.0 and shift == 0.0 - simple case (faster)
|
|
if ( mapper->GetTableScale()[0] == 1.0 &&
|
|
mapper->GetTableShift()[0] == 0.0 )
|
|
{
|
|
switch ( scalarType )
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkFixedPointMIPHelperGenerateImageOneSimpleTrilin(
|
|
static_cast<VTK_TT *>(dataPtr),
|
|
threadID, threadCount, mapper, vol) );
|
|
}
|
|
}
|
|
// Scale != 1.0 or shift != 0.0 - must apply scale/shift in inner loop
|
|
else
|
|
{
|
|
switch ( scalarType )
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkFixedPointMIPHelperGenerateImageOneTrilin(
|
|
static_cast<VTK_TT *>(dataPtr),
|
|
threadID, threadCount, mapper, vol) );
|
|
}
|
|
}
|
|
}
|
|
// Indepedent components (more than one)
|
|
else if ( vol->GetProperty()->GetIndependentComponents() )
|
|
{
|
|
switch ( scalarType )
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkFixedPointMIPHelperGenerateImageIndependentTrilin(
|
|
static_cast<VTK_TT *>(dataPtr),
|
|
threadID, threadCount, mapper, vol) );
|
|
}
|
|
}
|
|
// Dependent components
|
|
else
|
|
{
|
|
switch ( scalarType )
|
|
{
|
|
vtkTemplateMacro(
|
|
vtkFixedPointMIPHelperGenerateImageDependentTrilin(
|
|
static_cast<VTK_TT *>(dataPtr),
|
|
threadID, threadCount, mapper, vol) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Print method for vtkFixedPointVolumeRayCastMIPHelper
|
|
void vtkFixedPointVolumeRayCastMIPHelper::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
}
|
|
|
|
|