Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

916 lines
34 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkFixedPointVolumeRayCastCompositeGOHelper.cxx,v $
Language: C++
Date: $Date: 2005/08/19 19:24:59 $
Version: $Revision: 1.5 $
Copyright (c) 1993-2002 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 "vtkFixedPointVolumeRayCastCompositeGOHelper.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 <math.h>
vtkCxxRevisionMacro(vtkFixedPointVolumeRayCastCompositeGOHelper, "$Revision: 1.5 $");
vtkStandardNewMacro(vtkFixedPointVolumeRayCastCompositeGOHelper);
// Construct a new vtkFixedPointVolumeRayCastCompositeGOHelper with default values
vtkFixedPointVolumeRayCastCompositeGOHelper::vtkFixedPointVolumeRayCastCompositeGOHelper()
{
}
// Destruct a vtkFixedPointVolumeRayCastCompositeGOHelper - clean up any memory used
vtkFixedPointVolumeRayCastCompositeGOHelper::~vtkFixedPointVolumeRayCastCompositeGOHelper()
{
}
// This method is used when the interpolation type is nearest neighbor and
// the data has one component and scale == 1.0 and shift == 0.0. In the inner
// loop we get the data value as an unsigned short, and use this index to
// lookup a color and opacity for this sample. 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).
// Finally we move on to the next sample along the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageOneSimpleNN( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializationAndLoopStartGONN();
VTKKWRCHelper_InitializeCompositeOneNN();
VTKKWRCHelper_InitializeCompositeGONN();
VTKKWRCHelper_SpaceLeapSetup();
for ( k = 0; k < numSteps; k++ )
{
if ( k )
{
VTKKWRCHelper_MoveToNextSampleGONN();
}
VTKKWRCHelper_SpaceLeapCheck();
VTKKWRCHelper_CroppingCheckNN( pos );
unsigned short val = static_cast<unsigned short>(((*dptr)));
unsigned char mag = *magPtr;
VTKKWRCHelper_LookupColorGOUS( colorTable[0], scalarOpacityTable[0],
gradientOpacityTable[0], val, mag, tmp );
if ( tmp[3] )
{
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
VTKKWRCHelper_IncrementAndLoopEnd();
}
// This method is used when the interpolation type is nearest neighbor and
// the data has one component. In the inner loop we get the data value as
// an unsigned short using the scale/shift, and use this index to lookup
// a color and opacity for this sample. 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).
// Finally we move on to the next sample along the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageOneNN( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializationAndLoopStartGONN();
VTKKWRCHelper_InitializeCompositeOneNN();
VTKKWRCHelper_InitializeCompositeGONN();
VTKKWRCHelper_SpaceLeapSetup();
for ( k = 0; k < numSteps; k++ )
{
if ( k )
{
VTKKWRCHelper_MoveToNextSampleGONN();
}
VTKKWRCHelper_SpaceLeapCheck();
VTKKWRCHelper_CroppingCheckNN( pos );
unsigned short val = static_cast<unsigned short>(((*dptr) + shift[0])*scale[0]);
unsigned char mag = *magPtr;
VTKKWRCHelper_LookupColorGOUS( colorTable[0], scalarOpacityTable[0],
gradientOpacityTable[0], val, mag, tmp );
if ( tmp[3] )
{
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
VTKKWRCHelper_IncrementAndLoopEnd();
}
// This method is used when the interpolation type is nearest neighbor and
// the data has two components which are not considered independent. In the
// inner loop we compute the two unsigned short index values from the data
// values (using the scale/shift). We use the first index to lookup a color,
// and we use the second index to look up the opacity. We then composite
// the color into the color computed so far along this ray, and check to
// see if we can terminate here (if the opacity accumulated exceed some
// threshold). Finally we move to the next sample along the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageTwoDependentNN( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializationAndLoopStartGONN();
VTKKWRCHelper_InitializeCompositeOneNN();
VTKKWRCHelper_InitializeCompositeGONN();
VTKKWRCHelper_SpaceLeapSetup();
for ( k = 0; k < numSteps; k++ )
{
if ( k )
{
VTKKWRCHelper_MoveToNextSampleGONN();
}
VTKKWRCHelper_SpaceLeapCheck();
VTKKWRCHelper_CroppingCheckNN( pos );
unsigned short val[2];
val[0] = static_cast<unsigned short>(((*(dptr )) + shift[0])*scale[0]);
val[1] = static_cast<unsigned short>(((*(dptr+1)) + shift[1])*scale[1]);
unsigned char mag = *magPtr;
tmp[3] = (scalarOpacityTable[0][val[1]] * gradientOpacityTable[0][mag] + 0x3fff)>>(VTKKW_FP_SHIFT);
if ( !tmp[3] )
{
continue;
}
tmp[0] = static_cast<unsigned short>
((colorTable[0][3*val[0] ]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
tmp[1] = static_cast<unsigned short>
((colorTable[0][3*val[0]+1]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
tmp[2] = static_cast<unsigned short>
((colorTable[0][3*val[0]+2]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
VTKKWRCHelper_IncrementAndLoopEnd();
}
// This method is used when the interpolation type is nearest neighbor and
// the data has four components which are not considered independent . This
// means that the first three components directly represent color, and this
// data must be of unsigned char type. In the inner loop we directly access
// the four data values (no scale/shift is needed). The first three are the
// color of this sample and the fourth is used to look up an opacity in the
// scalar opacity transfer function. We then composite this color into the
// color we have accumulated so far along the ray, and check if we can
// terminate here (if our accumulated opacity has exceed some threshold).
// Finally we move onto the next sample along the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageFourDependentNN( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializationAndLoopStartGONN();
VTKKWRCHelper_InitializeCompositeOneNN();
VTKKWRCHelper_InitializeCompositeGONN();
VTKKWRCHelper_SpaceLeapSetup();
for ( k = 0; k < numSteps; k++ )
{
if ( k )
{
VTKKWRCHelper_MoveToNextSampleGONN();
}
VTKKWRCHelper_SpaceLeapCheck();
VTKKWRCHelper_CroppingCheckNN( pos );
unsigned short val[4];
val[0] = *(dptr );
val[1] = *(dptr+1);
val[2] = *(dptr+2);
val[3] = *(dptr+3);
unsigned char mag = *magPtr;
tmp[3] = (scalarOpacityTable[0][val[3]] * gradientOpacityTable[0][mag] + 0x3fff)>>(VTKKW_FP_SHIFT);
if ( !tmp[3] )
{
continue;
}
tmp[0] = (val[0]*tmp[3]+0x7f)>>(8);
tmp[1] = (val[1]*tmp[3]+0x7f)>>(8);
tmp[2] = (val[2]*tmp[3]+0x7f)>>(8);
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
VTKKWRCHelper_IncrementAndLoopEnd();
}
// This method is used when the interpolation type is nearest neighbor and
// the data has more than one component and the components are considered to
// be independent. In the inner loop we access each component value, using
// the scale/shift to turn the data value into an unsigned short index. We
// then lookup the color/opacity for each component and combine them according
// to the weighting value for each component. We composite this resulting
// color into the color already accumulated for this ray, and we check
// wether we can terminate here (if the accumulated opacity exceeds some
// threshold). Finally we increment to the next sample on the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageIndependentNN( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializeWeights();
VTKKWRCHelper_InitializationAndLoopStartGONN();
VTKKWRCHelper_InitializeCompositeMultiNN();
VTKKWRCHelper_InitializeCompositeGONN();
for ( k = 0; k < numSteps; k++ )
{
if ( k )
{
VTKKWRCHelper_MoveToNextSampleGONN();
}
VTKKWRCHelper_CroppingCheckNN( pos );
unsigned char mag[4];
for ( c = 0; c < components; c++ )
{
val[c] = static_cast<unsigned short>(((*(dptr+c)) + shift[c])*scale[c]);
mag[c] = static_cast<unsigned short>(*(magPtr+c));
}
VTKKWRCHelper_LookupAndCombineIndependentColorsGOUS( colorTable, scalarOpacityTable,
gradientOpacityTable,
val, mag, weights, components, tmp );
if ( tmp[3] )
{
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
VTKKWRCHelper_IncrementAndLoopEnd();
}
// This method is used when the interpolation type is linear and the data
// has one component and scale = 1.0 and shift = 0.0. In the inner loop we
// get the data value for the eight cell corners (if we have changed cells)
// as an unsigned short (the range must be right and we don't need the
// scale/shift). We compute our weights within the cell according to our
// fractional position within the cell, apply trilinear interpolation to
// compute the index, and use this index to lookup a color and opacity for
// this sample. 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). Finally we move on to the next
// sample along the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageOneSimpleTrilin( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializationAndLoopStartGOTrilin();
VTKKWRCHelper_InitializeCompositeOneTrilin();
VTKKWRCHelper_InitializeCompositeOneGOTrilin();
VTKKWRCHelper_SpaceLeapSetup();
int needToSampleGO = 0;
for ( k = 0; k < numSteps; k++ )
{
if ( k )
{
mapper->FixedPointIncrement( pos, dir );
}
VTKKWRCHelper_SpaceLeapCheck();
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 = data + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
VTKKWRCHelper_GetCellScalarValuesSimple( dptr );
magPtrABCD = gradientMag[spos[2] ] + spos[0]*mInc[0] + spos[1]*mInc[1];
magPtrEFGH = gradientMag[spos[2]+1] + spos[0]*mInc[0] + spos[1]*mInc[1];
needToSampleGO = 1;
}
VTKKWRCHelper_ComputeWeights(pos);
VTKKWRCHelper_InterpolateScalar(val);
tmp[3] = scalarOpacityTable[0][val];
if ( !tmp[3] )
{
continue;
}
if ( needToSampleGO )
{
VTKKWRCHelper_GetCellMagnitudeValues( magPtrABCD, magPtrEFGH );
needToSampleGO = 0;
}
VTKKWRCHelper_InterpolateMagnitude(mag);
tmp[3] = (tmp[3] * gradientOpacityTable[0][mag] + 0x7fff)>>VTKKW_FP_SHIFT;
if ( !tmp[3] )
{
continue;
}
tmp[0] = static_cast<unsigned short>
((colorTable[0][3*val ]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
tmp[1] = static_cast<unsigned short>
((colorTable[0][3*val+1]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
tmp[2] = static_cast<unsigned short>
((colorTable[0][3*val+2]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
VTKKWRCHelper_IncrementAndLoopEnd();
}
// This method is used when the interpolation type is linear and the data
// has one component and scale != 1.0 or shift != 0.0. In the inner loop we
// get the data value for the eight cell corners (if we have changed cells)
// as an unsigned short (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, apply trilinear interpolation to compute the index, and use
// this index to lookup a color and opacity for this sample. 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). Finally we move on to the next sample along the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageOneTrilin( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializationAndLoopStartGOTrilin();
VTKKWRCHelper_InitializeCompositeOneTrilin();
VTKKWRCHelper_InitializeCompositeOneGOTrilin();
VTKKWRCHelper_SpaceLeapSetup();
int needToSampleGO = 0;
for ( k = 0; k < numSteps; k++ )
{
if ( k )
{
mapper->FixedPointIncrement( pos, dir );
}
VTKKWRCHelper_SpaceLeapCheck();
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 = data + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
VTKKWRCHelper_GetCellScalarValues( dptr, scale[0], shift[0] );
magPtrABCD = gradientMag[spos[2] ] + spos[0]*mInc[0] + spos[1]*mInc[1];
magPtrEFGH = gradientMag[spos[2]+1] + spos[0]*mInc[0] + spos[1]*mInc[1];
needToSampleGO = 1;
}
VTKKWRCHelper_ComputeWeights(pos);
VTKKWRCHelper_InterpolateScalar(val);
tmp[3] = scalarOpacityTable[0][val];
if ( !tmp[3] )
{
continue;
}
if ( needToSampleGO )
{
VTKKWRCHelper_GetCellMagnitudeValues( magPtrABCD, magPtrEFGH );
needToSampleGO = 0;
}
VTKKWRCHelper_InterpolateMagnitude(mag);
tmp[3] = (tmp[3] * gradientOpacityTable[0][mag] + 0x7fff)>>VTKKW_FP_SHIFT;
if ( !tmp[3] )
{
continue;
}
tmp[0] = static_cast<unsigned short>
((colorTable[0][3*val ]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
tmp[1] = static_cast<unsigned short>
((colorTable[0][3*val+1]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
tmp[2] = static_cast<unsigned short>
((colorTable[0][3*val+2]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
VTKKWRCHelper_IncrementAndLoopEnd();
}
// This method is used when the interpolation type is linear, the data has
// two components and the components are not considered independent. In the
// inner loop we get the data value for the eight cell corners (if we have
// changed cells) for both components as an 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 two index value. We use the first
// index to lookup a color and the second to look up an opacity for this sample.
// 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). Finally we move on to the next sample along
// the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageTwoDependentTrilin( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializationAndLoopStartGOTrilin();
VTKKWRCHelper_InitializeCompositeMultiTrilin();
VTKKWRCHelper_InitializeCompositeOneGOTrilin();
VTKKWRCHelper_SpaceLeapSetup();
int needToSampleGO = 0;
for ( k = 0; k < numSteps; k++ )
{
if ( k )
{
mapper->FixedPointIncrement( pos, dir );
}
VTKKWRCHelper_SpaceLeapCheck();
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 = data + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 0, scale[0], shift[0] );
dptr++;
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 1, scale[1], shift[1] );
magPtrABCD = gradientMag[spos[2] ] + spos[0]*mInc[0] + spos[1]*mInc[1];
magPtrEFGH = gradientMag[spos[2]+1] + spos[0]*mInc[0] + spos[1]*mInc[1];
needToSampleGO = 1;
}
VTKKWRCHelper_ComputeWeights(pos);
VTKKWRCHelper_InterpolateScalarComponent( val, c, 2 );
tmp[3] = scalarOpacityTable[0][val[1]];
if ( !tmp[3] )
{
continue;
}
if ( needToSampleGO )
{
VTKKWRCHelper_GetCellMagnitudeValues( magPtrABCD, magPtrEFGH );
needToSampleGO = 0;
}
VTKKWRCHelper_InterpolateMagnitude(mag);
tmp[3] = (tmp[3] * gradientOpacityTable[0][mag] + 0x7fff)>>VTKKW_FP_SHIFT;
if ( !tmp[3] )
{
continue;
}
tmp[0] = static_cast<unsigned short>
((colorTable[0][3*val[0] ]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
tmp[1] = static_cast<unsigned short>
((colorTable[0][3*val[0]+1]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
tmp[2] = static_cast<unsigned short>
((colorTable[0][3*val[0]+2]*tmp[3] + 0x7fff)>>(VTKKW_FP_SHIFT));
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
VTKKWRCHelper_IncrementAndLoopEnd();
}
// This method is used when the interpolation type is linear, the data has
// four components and the components are not 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 don't have to
// use the scale/shift because only unsigned char data is supported for four
// component data when the components are not independent). 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
// use the first three directly as the color of the sample, and the fourth is
// used to look up an opacity for this sample. 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). Finally we
// move on to the next sample along the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageFourDependentTrilin( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializationAndLoopStartGOTrilin();
VTKKWRCHelper_InitializeCompositeMultiTrilin();
VTKKWRCHelper_InitializeCompositeOneGOTrilin();
VTKKWRCHelper_SpaceLeapSetup();
int needToSampleGO = 0;
for ( k = 0; k < numSteps; k++ )
{
if ( k )
{
mapper->FixedPointIncrement( pos, dir );
}
VTKKWRCHelper_SpaceLeapCheck();
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 = data + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 0, scale[0], shift[0] );
dptr++;
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 1, scale[1], shift[1] );
dptr++;
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 2, scale[2], shift[2] );
dptr++;
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 3, scale[3], shift[3] );
magPtrABCD = gradientMag[spos[2] ] + spos[0]*mInc[0] + spos[1]*mInc[1];
magPtrEFGH = gradientMag[spos[2]+1] + spos[0]*mInc[0] + spos[1]*mInc[1];
needToSampleGO = 1;
}
VTKKWRCHelper_ComputeWeights(pos);
VTKKWRCHelper_InterpolateScalarComponent( val, c, 4 );
tmp[3] = scalarOpacityTable[0][val[3]];
if ( !tmp[3] )
{
continue;
}
if ( needToSampleGO )
{
VTKKWRCHelper_GetCellMagnitudeValues( magPtrABCD, magPtrEFGH );
needToSampleGO = 0;
}
VTKKWRCHelper_InterpolateMagnitude(mag);
tmp[3] = (tmp[3] * gradientOpacityTable[0][mag] + 0x7fff)>>VTKKW_FP_SHIFT;
if ( !tmp[3] )
{
continue;
}
tmp[0] = (val[0]*tmp[3]+0x7f)>>8;
tmp[1] = (val[1]*tmp[3]+0x7f)>>8;
tmp[2] = (val[2]*tmp[3]+0x7f)>>8;
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
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
// look up a color/opacity for each component and blend them according to the
// component weights. We then composite this resulting color 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). Finally we
// move on to the next sample along the ray.
template <class T>
void vtkFixedPointCompositeGOHelperGenerateImageIndependentTrilin( T *data,
int threadID,
int threadCount,
vtkFixedPointVolumeRayCastMapper *mapper,
vtkVolume *vol)
{
VTKKWRCHelper_InitializeWeights();
VTKKWRCHelper_InitializationAndLoopStartGOTrilin();
VTKKWRCHelper_InitializeCompositeMultiTrilin();
VTKKWRCHelper_InitializeCompositeMultiGOTrilin();
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];
dptr = data + spos[0]*inc[0] + spos[1]*inc[1] + spos[2]*inc[2];
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 0, scale[0], shift[0] );
dptr++;
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 1, scale[1], shift[1] );
if ( components > 2 )
{
dptr++;
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 2, scale[2], shift[2] );
if ( components > 3 )
{
dptr++;
VTKKWRCHelper_GetCellComponentScalarValues( dptr, 3, scale[3], shift[3] );
}
}
magPtrABCD = gradientMag[spos[2] ] + spos[0]*mInc[0] + spos[1]*mInc[1];
magPtrEFGH = gradientMag[spos[2]+1] + spos[0]*mInc[0] + spos[1]*mInc[1];
VTKKWRCHelper_GetCellComponentMagnitudeValues( magPtrABCD, magPtrEFGH, 0 );
magPtrABCD++;
magPtrEFGH++;
VTKKWRCHelper_GetCellComponentMagnitudeValues( magPtrABCD, magPtrEFGH, 1 );
if ( components > 2 )
{
magPtrABCD++;
magPtrEFGH++;
VTKKWRCHelper_GetCellComponentMagnitudeValues( magPtrABCD, magPtrEFGH, 2 );
if ( components > 3 )
{
magPtrABCD++;
magPtrEFGH++;
VTKKWRCHelper_GetCellComponentMagnitudeValues( magPtrABCD, magPtrEFGH, 3 );
}
}
}
VTKKWRCHelper_ComputeWeights(pos);
VTKKWRCHelper_InterpolateScalarComponent( val, c, components );
VTKKWRCHelper_InterpolateMagnitudeComponent( mag, c, components );
VTKKWRCHelper_LookupAndCombineIndependentColorsGOUS( colorTable, scalarOpacityTable,
gradientOpacityTable, val, mag,
weights, components, tmp );
VTKKWRCHelper_CompositeColorAndCheckEarlyTermination( color, tmp, remainingOpacity );
}
VTKKWRCHelper_SetPixelColor( imagePtr, color, remainingOpacity );
VTKKWRCHelper_IncrementAndLoopEnd();
}
void vtkFixedPointVolumeRayCastCompositeGOHelper::GenerateImage( int threadID,
int threadCount,
vtkVolume *vol,
vtkFixedPointVolumeRayCastMapper *mapper )
{
void *data = mapper->GetInput()->GetScalarPointer();
int scalarType = mapper->GetInput()->GetScalarType();
// Nearest Neighbor interpolate
if ( mapper->ShouldUseNearestNeighborInterpolation( vol ) )
{
// One component data
if ( mapper->GetInput()->GetNumberOfScalarComponents() == 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(
vtkFixedPointCompositeGOHelperGenerateImageOneSimpleNN(
(VTK_TT *)(data),
threadID, threadCount, mapper, vol) );
}
}
else
{
switch ( scalarType )
{
vtkTemplateMacro(
vtkFixedPointCompositeGOHelperGenerateImageOneNN(
(VTK_TT *)(data),
threadID, threadCount, mapper, vol) );
}
}
}
// More that one independent components
else if ( vol->GetProperty()->GetIndependentComponents() )
{
switch ( scalarType )
{
vtkTemplateMacro(
vtkFixedPointCompositeGOHelperGenerateImageIndependentNN(
(VTK_TT *)(data),
threadID, threadCount, mapper, vol) );
}
}
// Dependent (color) components
else
{
// Two components - the first specifies color (through a lookup table) and
// the second specified opacity (through a lookup table)
if ( mapper->GetInput()->GetNumberOfScalarComponents() == 2 )
{
switch ( scalarType )
{
vtkTemplateMacro(
vtkFixedPointCompositeGOHelperGenerateImageTwoDependentNN(
(VTK_TT *)(data),
threadID, threadCount, mapper, vol) );
}
}
// Four components - they must be unsigned char, the first three directly
// specify color and the fourth specifies opacity (through a lookup table)
else
{
if ( scalarType == VTK_UNSIGNED_CHAR )
{
vtkFixedPointCompositeGOHelperGenerateImageFourDependentNN(
static_cast<unsigned char *>(data), threadID, threadCount, mapper, vol );
}
else
{
vtkErrorMacro("Four component dependent must be unsigned char!");
}
}
}
}
// Trilinear Interpolation
else
{
// One component
if ( mapper->GetInput()->GetNumberOfScalarComponents() == 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(
vtkFixedPointCompositeGOHelperGenerateImageOneSimpleTrilin(
(VTK_TT *)(data),
threadID, threadCount, mapper, vol) );
}
}
// Scale != 1.0 or shift != 0.0 - must apply scale/shift in inner loop
else
{
switch ( scalarType )
{
vtkTemplateMacro(
vtkFixedPointCompositeGOHelperGenerateImageOneTrilin(
(VTK_TT *)(data),
threadID, threadCount, mapper, vol) );
}
}
}
// Indepedent components (more than one)
else if ( vol->GetProperty()->GetIndependentComponents() )
{
switch ( scalarType )
{
vtkTemplateMacro(
vtkFixedPointCompositeGOHelperGenerateImageIndependentTrilin(
(VTK_TT *)(data),
threadID, threadCount, mapper, vol) );
}
}
// Dependent components
else
{
// Two components - the first specifies color (through a lookup table) and
// the second specified opacity (through a lookup table)
if ( mapper->GetInput()->GetNumberOfScalarComponents() == 2 )
{
switch ( scalarType )
{
vtkTemplateMacro(
vtkFixedPointCompositeGOHelperGenerateImageTwoDependentTrilin(
(VTK_TT *)(data),
threadID, threadCount, mapper, vol) );
}
}
// Four components - they must be unsigned char, the first three directly
// specify color and the fourth specifies opacity (through a lookup table)
else
{
if ( scalarType == VTK_UNSIGNED_CHAR )
{
vtkFixedPointCompositeGOHelperGenerateImageFourDependentTrilin(
static_cast<unsigned char *>(data), threadID, threadCount, mapper, vol );
}
else
{
vtkErrorMacro("Four component dependent must be unsigned char!");
}
}
}
}
}
// Print method for vtkFixedPointVolumeRayCastCompositeGOHelper
void vtkFixedPointVolumeRayCastCompositeGOHelper::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
}