Commit 30acb904 authored by Sean McBride's avatar Sean McBride
Browse files

Improved performance of vtkLookupTable a bit

Did a few things to speed things up:
- eliminated some double<->integer conversions.
- repeated the last colour in the lut as a 4th "special" colour, eliminating need for a test in very hot function. Improved shift & scale calculations against pathological cases.
- use memcpy() (with fixed size) instead of manual copying byte by byte. Modern compilers optimize this well, as verified with godbolt.

Did some other cleanup while investigating my performance issues: added more const safety, fixed comments, etc.
parent 63f0faa8
......@@ -24,10 +24,11 @@
#include <cassert>
const vtkIdType vtkLookupTable::BELOW_RANGE_COLOR_INDEX = 0;
const vtkIdType vtkLookupTable::ABOVE_RANGE_COLOR_INDEX = 1;
const vtkIdType vtkLookupTable::NAN_COLOR_INDEX = 2;
const vtkIdType vtkLookupTable::NUMBER_OF_SPECIAL_COLORS = NAN_COLOR_INDEX+1;
const vtkIdType vtkLookupTable::REPEATED_LAST_COLOR_INDEX = 0;
const vtkIdType vtkLookupTable::BELOW_RANGE_COLOR_INDEX = 1;
const vtkIdType vtkLookupTable::ABOVE_RANGE_COLOR_INDEX = 2;
const vtkIdType vtkLookupTable::NAN_COLOR_INDEX = 3;
const vtkIdType vtkLookupTable::NUMBER_OF_SPECIAL_COLORS = NAN_COLOR_INDEX+1;
vtkStandardNewMacro(vtkLookupTable);
......@@ -201,7 +202,7 @@ void vtkLookupTable::ForceBuild()
vtkIdType maxIndex = this->NumberOfColors - 1;
if( maxIndex )
if( maxIndex > 0 )
{
hinc = (this->HueRange[1] - this->HueRange[0])/maxIndex;
sinc = (this->SaturationRange[1] - this->SaturationRange[0])/maxIndex;
......@@ -297,15 +298,42 @@ void vtkLookupTable::Build()
//----------------------------------------------------------------------------
void vtkLookupTable::BuildSpecialColors()
{
// Add "special" colors (NaN, below range, above range) to table here.
// Append 4 "special" colors (repeated last, below range, above range, NaN) to table here.
vtkIdType numberOfColors = this->GetTable()->GetNumberOfTuples();
this->ResizeTableForSpecialColors();
unsigned char *table = this->GetTable()->GetPointer(0);
unsigned char *tptr = table + 4*(numberOfColors + vtkLookupTable::BELOW_RANGE_COLOR_INDEX);
unsigned char color[4];
// Repeat the last color. This is done to improve performance later on.
// Floating point math in vtkLinearIndexLookupMain may result in an off-by-one,
// and having an extra copy of the last color lets us avoid a test in that very hot function.
unsigned char *tptr = table + 4*(numberOfColors + vtkLookupTable::REPEATED_LAST_COLOR_INDEX);
if (numberOfColors > 0)
{
// Duplicate the last color in the table.
tptr[0] = table[4*(numberOfColors-1) + 0];
tptr[1] = table[4*(numberOfColors-1) + 1];
tptr[2] = table[4*(numberOfColors-1) + 2];
tptr[3] = table[4*(numberOfColors-1) + 3];
}
else if (this->GetUseAboveRangeColor())
{
vtkLookupTable::GetColorAsUnsignedChars(this->GetAboveRangeColor(), color);
tptr[0] = color[0];
tptr[1] = color[1];
tptr[2] = color[2];
tptr[3] = color[3];
}
else
{
tptr[0] = 0;
tptr[1] = 0;
tptr[2] = 0;
tptr[3] = 0;
}
// Below range color
tptr = table + 4*(numberOfColors + vtkLookupTable::BELOW_RANGE_COLOR_INDEX);
if (this->GetUseBelowRangeColor() || numberOfColors == 0)
{
vtkLookupTable::GetColorAsUnsignedChars(this->GetBelowRangeColor(), color);
......@@ -495,9 +523,9 @@ inline double vtkApplyLogScale(double v, const double range[2],
}
//----------------------------------------------------------------------------
// Data structure for passing data around various internal functions
// Private structure for passing data between various internal functions
struct TableParameters {
double MaxIndex;
vtkIdType NumColors;
double Range[2];
double Shift;
double Scale;
......@@ -507,81 +535,86 @@ struct TableParameters {
// Apply shift/scale to the scalar value v and return the index.
inline vtkIdType vtkLinearIndexLookupMain(double v, const TableParameters & p)
{
double dIndex;
vtkIdType index;
// This is a very hot function.
// Be very careful changing it, as it affects performance greatly.
if (v < p.Range[0])
{
dIndex = p.MaxIndex + vtkLookupTable::BELOW_RANGE_COLOR_INDEX + 1.5;
index = p.NumColors + vtkLookupTable::BELOW_RANGE_COLOR_INDEX;
}
else if (v > p.Range[1])
{
dIndex = p.MaxIndex + vtkLookupTable::ABOVE_RANGE_COLOR_INDEX + 1.5;
index = p.NumColors + vtkLookupTable::ABOVE_RANGE_COLOR_INDEX;
}
else
{
dIndex = (v + p.Shift)*p.Scale;
// This conditional is needed because when v is very close to
// p.Range[1], it may map above p.MaxIndex in the linear mapping
// above.
dIndex = (dIndex < p.MaxIndex ? dIndex : p.MaxIndex);
double dIndex = (v + p.Shift) * p.Scale;
// When v is very close to p.Range[1], the floating point calculation giving
// dIndex may map above the highest value in the lut (at index p.NumColors-1)
// in the linear mapping above. This is why we keep an extra copy of the last
// lut value, to avoid extra work in this very hot function.
// It should never be more than 1 off, assert to be sure.
assert(dIndex > -1.0 && dIndex <= (double)p.NumColors && std::isfinite(dIndex));
index = static_cast<vtkIdType>(dIndex);
}
return static_cast<vtkIdType>(dIndex);
}
//----------------------------------------------------------------------------
// Get index and do the table lookup.
inline const unsigned char *vtkLinearLookupMain(double v,
unsigned char *table,
const TableParameters & p)
{
vtkIdType index = vtkLinearIndexLookupMain(v, p);
return &table[4*index];
return index;
}
//----------------------------------------------------------------------------
// integer variant
template<class T>
const unsigned char *vtkLinearLookup(T v, unsigned char *table, const TableParameters & p)
inline vtkIdType vtkLinearLookup(T v, const TableParameters & p)
{
return vtkLinearLookupMain(v, table, p);
// First convert from integer to double.
double dv = static_cast<double>(v);
return vtkLinearIndexLookupMain(dv, p);
}
//----------------------------------------------------------------------------
// Check for not-a-number when mapping double or float
inline const unsigned char *vtkLinearLookup(
double v, unsigned char *table, const TableParameters & p)
// double variant
inline vtkIdType vtkLinearLookup(double v, const TableParameters & p)
{
// If Nan, use the special NaN color.
if (vtkMath::IsNan(v))
{
vtkIdType maxIndex = static_cast<vtkIdType>(p.MaxIndex + 0.5) + 1;
return table + 4*(maxIndex + vtkLookupTable::NAN_COLOR_INDEX);
vtkIdType maxIndex = p.NumColors + vtkLookupTable::NAN_COLOR_INDEX;
return maxIndex;
}
return vtkLinearLookupMain(v, table, p);
return vtkLinearIndexLookupMain(v, p);
}
//----------------------------------------------------------------------------
inline const unsigned char *vtkLinearLookup(
float v, unsigned char *table, const TableParameters & p)
// float variant
inline vtkIdType vtkLinearLookup(float v, const TableParameters & p)
{
return vtkLinearLookup(static_cast<double>(v), table, p);
// Convert from float to double, then call the double variant.
double dv = static_cast<double>(v);
return vtkLinearLookup(dv, p);
}
//----------------------------------------------------------------------------
inline void vtkLookupShiftAndScale(double range[2],
double maxIndex,
inline void vtkLookupShiftAndScale(const double range[2],
double numColors,
double& shift, double& scale)
{
shift = -range[0];
if (range[1] <= range[0])
double rangeDelta = range[1] - range[0];
if (rangeDelta < VTK_DBL_MIN)
{
scale = VTK_DOUBLE_MAX;
// if the range is tiny, anything within the range will map to the bottom
// of the color scale.
scale = 0.0;
}
else
{
scale = (maxIndex + 1)/(range[1] - range[0]);
scale = numColors / rangeDelta;
}
assert(scale >= 0.0);
}
} // end anonymous namespace
......@@ -609,20 +642,20 @@ vtkIdType vtkLookupTable::GetIndex(double v)
}
TableParameters p;
p.MaxIndex = this->NumberOfColors - 1;
p.NumColors = this->NumberOfColors;
if (this->Scale == VTK_SCALE_LOG10)
{ // handle logarithmic scale
double logRange[2];
vtkLookupTableLogRange(this->TableRange, logRange);
vtkLookupShiftAndScale(logRange, p.MaxIndex, p.Shift, p.Scale);
vtkLookupShiftAndScale(logRange, p.NumColors, p.Shift, p.Scale);
v = vtkApplyLogScale(v, this->TableRange, logRange);
p.Range[0] = logRange[0];
p.Range[1] = logRange[1];
}
else
{ // plain old linear
vtkLookupShiftAndScale(this->TableRange, p.MaxIndex, p.Shift, p.Scale);
vtkLookupShiftAndScale(this->TableRange, p.NumColors, p.Shift, p.Scale);
p.Range[0] = this->TableRange[0];
p.Range[1] = this->TableRange[1];
}
......@@ -643,7 +676,8 @@ vtkIdType vtkLookupTable::GetIndex(double v)
{
index = 0;
}
else if (index == this->NumberOfColors + ABOVE_RANGE_COLOR_INDEX)
else if ((index == this->NumberOfColors + REPEATED_LAST_COLOR_INDEX) ||
(index == this->NumberOfColors + ABOVE_RANGE_COLOR_INDEX))
{
index = this->NumberOfColors - 1;
}
......@@ -746,7 +780,7 @@ void vtkLookupTableMapData(vtkLookupTable *self,
int inIncr, int outFormat, TableParameters & p)
{
int i = length;
double *range = self->GetTableRange();
const double *range = self->GetTableRange();
const unsigned char *cptr;
double alpha;
......@@ -757,7 +791,7 @@ void vtkLookupTableMapData(vtkLookupTable *self,
vtkUnsignedCharArray* lookupTable = self->GetTable();
unsigned char* table = lookupTable->GetPointer(0);
const unsigned char* table = lookupTable->GetPointer(0);
if ( (alpha=self->GetAlpha()) >= 1.0 ) //no blending required
{
......@@ -766,7 +800,7 @@ void vtkLookupTableMapData(vtkLookupTable *self,
double val;
double logRange[2];
vtkLookupTableLogRange(range, logRange);
vtkLookupShiftAndScale(logRange, p.MaxIndex, p.Shift, p.Scale);
vtkLookupShiftAndScale(logRange, p.NumColors, p.Shift, p.Scale);
p.Range[0] = logRange[0];
p.Range[1] = logRange[1];
......@@ -775,11 +809,9 @@ void vtkLookupTableMapData(vtkLookupTable *self,
while (--i >= 0)
{
val = vtkApplyLogScale(*input, range, logRange);
cptr = vtkLinearLookup(val, table, p);
output[0] = cptr[0];
output[1] = cptr[1];
output[2] = cptr[2];
output[3] = cptr[3];
vtkIdType idx = vtkLinearLookup(val, p);
cptr = table + 4*idx;
memcpy(output, cptr, 4);
input += inIncr;
output += 4;
}
......@@ -789,10 +821,9 @@ void vtkLookupTableMapData(vtkLookupTable *self,
while (--i >= 0)
{
val = vtkApplyLogScale(*input, range, logRange);
cptr = vtkLinearLookup(val, table, p);
output[0] = cptr[0];
output[1] = cptr[1];
output[2] = cptr[2];
vtkIdType idx = vtkLinearLookup(val, p);
cptr = table + 4*idx;
memcpy(output, cptr, 3);
input += inIncr;
output += 3;
}
......@@ -802,7 +833,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
while (--i >= 0)
{
val = vtkApplyLogScale(*input, range, logRange);
cptr = vtkLinearLookup(val, table, p);
vtkIdType idx = vtkLinearLookup(val, p);
cptr = table + 4*idx;
output[0] = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
cptr[2]*0.11 + 0.5);
output[1] = cptr[3];
......@@ -815,7 +847,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
while (--i >= 0)
{
val = vtkApplyLogScale(*input, range, logRange);
cptr = vtkLinearLookup(val, table, p);
vtkIdType idx = vtkLinearLookup(val, p);
cptr = table + 4*idx;
*output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
cptr[2]*0.11 + 0.5);
input += inIncr;
......@@ -825,18 +858,16 @@ void vtkLookupTableMapData(vtkLookupTable *self,
else //not log scale
{
vtkLookupShiftAndScale(range, p.MaxIndex, p.Shift, p.Scale);
vtkLookupShiftAndScale(range, p.NumColors, p.Shift, p.Scale);
p.Range[0] = range[0];
p.Range[1] = range[1];
if (outFormat == VTK_RGBA)
{
while (--i >= 0)
{
cptr = vtkLinearLookup(*input, table, p);
output[0] = cptr[0];
output[1] = cptr[1];
output[2] = cptr[2];
output[3] = cptr[3];
vtkIdType idx = vtkLinearLookup(*input, p);
cptr = table + 4*idx;
memcpy(output, cptr, 4);
input += inIncr;
output += 4;
}
......@@ -845,10 +876,9 @@ void vtkLookupTableMapData(vtkLookupTable *self,
{
while (--i >= 0)
{
cptr = vtkLinearLookup(*input, table, p);
output[0] = cptr[0];
output[1] = cptr[1];
output[2] = cptr[2];
vtkIdType idx = vtkLinearLookup(*input, p);
cptr = table + 4*idx;
memcpy(output, cptr, 3);
input += inIncr;
output += 3;
}
......@@ -857,7 +887,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
{
while (--i >= 0)
{
cptr = vtkLinearLookup(*input, table, p);
vtkIdType idx = vtkLinearLookup(*input, p);
cptr = table + 4*idx;
output[0] = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
cptr[2]*0.11 + 0.5);
output[1] = cptr[3];
......@@ -869,7 +900,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
{
while (--i >= 0)
{
cptr = vtkLinearLookup(*input, table, p);
vtkIdType idx = vtkLinearLookup(*input, p);
cptr = table + 4*idx;
*output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
cptr[2]*0.11 + 0.5);
input += inIncr;
......@@ -885,7 +917,7 @@ void vtkLookupTableMapData(vtkLookupTable *self,
double val;
double logRange[2];
vtkLookupTableLogRange(range, logRange);
vtkLookupShiftAndScale(logRange, p.MaxIndex, p.Shift, p.Scale);
vtkLookupShiftAndScale(logRange, p.NumColors, p.Shift, p.Scale);
p.Range[0] = logRange[0];
p.Range[1] = logRange[1];
......@@ -894,7 +926,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
while (--i >= 0)
{
val = vtkApplyLogScale(*input, range, logRange);
cptr = vtkLinearLookup(val, table, p);
vtkIdType idx = vtkLinearLookup(val, p);
cptr = table + 4*idx;
output[0] = cptr[0];
output[1] = cptr[1];
output[2] = cptr[2];
......@@ -908,10 +941,9 @@ void vtkLookupTableMapData(vtkLookupTable *self,
while (--i >= 0)
{
val = vtkApplyLogScale(*input, range, logRange);
cptr = vtkLinearLookup(val, table, p);
output[0] = cptr[0];
output[1] = cptr[1];
output[2] = cptr[2];
vtkIdType idx = vtkLinearLookup(val, p);
cptr = table + 4*idx;
memcpy(output, cptr, 3);
input += inIncr;
output += 3;
}
......@@ -921,7 +953,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
while (--i >= 0)
{
val = vtkApplyLogScale(*input, range, logRange);
cptr = vtkLinearLookup(val, table, p);
vtkIdType idx = vtkLinearLookup(val, p);
cptr = table + 4*idx;
output[0] = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
cptr[2]*0.11 + 0.5);
output[1] = static_cast<unsigned char>(alpha*cptr[3] + 0.5);
......@@ -934,7 +967,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
while (--i >= 0)
{
val = vtkApplyLogScale(*input, range, logRange);
cptr = vtkLinearLookup(val, table, p);
vtkIdType idx = vtkLinearLookup(val, p);
cptr = table + 4*idx;
*output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
cptr[2]*0.11 + 0.5);
input += inIncr;
......@@ -944,7 +978,7 @@ void vtkLookupTableMapData(vtkLookupTable *self,
else //no log scale with blending
{
vtkLookupShiftAndScale(range, p.MaxIndex, p.Shift, p.Scale);
vtkLookupShiftAndScale(range, p.NumColors, p.Shift, p.Scale);
p.Range[0] = range[0];
p.Range[1] = range[1];
......@@ -952,7 +986,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
{
while (--i >= 0)
{
cptr = vtkLinearLookup(*input, table, p);
vtkIdType idx = vtkLinearLookup(*input, p);
cptr = table + 4*idx;
output[0] = cptr[0];
output[1] = cptr[1];
output[2] = cptr[2];
......@@ -965,10 +1000,9 @@ void vtkLookupTableMapData(vtkLookupTable *self,
{
while (--i >= 0)
{
cptr = vtkLinearLookup(*input, table, p);
output[0] = cptr[0];
output[1] = cptr[1];
output[2] = cptr[2];
vtkIdType idx = vtkLinearLookup(*input, p);
cptr = table + 4*idx;
memcpy(output, cptr, 3);
input += inIncr;
output += 3;
}
......@@ -977,7 +1011,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
{
while (--i >= 0)
{
cptr = vtkLinearLookup(*input, table, p);
vtkIdType idx = vtkLinearLookup(*input, p);
cptr = table + 4*idx;
output[0] = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
cptr[2]*0.11 + 0.5);
output[1] = static_cast<unsigned char>(cptr[3]*alpha + 0.5);
......@@ -989,7 +1024,8 @@ void vtkLookupTableMapData(vtkLookupTable *self,
{
while (--i >= 0)
{
cptr = vtkLinearLookup(*input, table, p);
vtkIdType idx = vtkLinearLookup(*input, p);
cptr = table + 4*idx;
*output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
cptr[2]*0.11 + 0.5);
input += inIncr;
......@@ -1187,7 +1223,7 @@ void vtkLookupTable::MapScalarsThroughTable2(void *input,
else
{
TableParameters p;
p.MaxIndex = this->GetNumberOfColors() - 1;
p.NumColors = this->GetNumberOfColors();
switch (inputDataType)
{
......
......@@ -73,6 +73,7 @@ public:
* Constants for offsets of special colors (e.g., NanColor, BelowRangeColor,
* AboveRangeColor) from the maximum index in the lookup table.
*/
static const vtkIdType REPEATED_LAST_COLOR_INDEX;
static const vtkIdType BELOW_RANGE_COLOR_INDEX;
static const vtkIdType ABOVE_RANGE_COLOR_INDEX;
static const vtkIdType NAN_COLOR_INDEX;
......@@ -249,7 +250,7 @@ public:
//@{
/**
* Set whether the below range color should be used.
* Set whether the above range color should be used.
*/
vtkSetMacro(UseAboveRangeColor, int);
vtkGetMacro(UseAboveRangeColor, int);
......
......@@ -354,7 +354,7 @@ int vtkThreadedImageAlgorithm::SplitExtent(int splitExt[6],
// The old way to thread an image filter, before vtkSMPTools existed:
// this mess is really a simple function. All it does is call
// the ThreadedExecute method after setting the correct
// extent for this thread. Its just a pain to calculate
// extent for this thread. It's just a pain to calculate
// the correct extent.
static VTK_THREAD_RETURN_TYPE vtkThreadedImageAlgorithmThreadedExecute( void *arg )
{
......
......@@ -17,7 +17,7 @@
* @brief Generic filter that has one input.
*
* vtkThreadedImageAlgorithm is a filter superclass that hides much of the
* pipeline complexity. It handles breaking the pipeline execution
* pipeline complexity. It handles breaking the pipeline execution
* into smaller extents so that the vtkImageData limits are observed. It
* also provides support for multithreading. If you don't need any of this
* functionality, consider using vtkSimpleImageToImageAlgorithm instead.
......
......@@ -75,7 +75,7 @@ const char *HelpText =
" --runs N The number of runs to perform\n"
" --threads N (or N-M or N,M,O) Request a certain number of threads\n"
" --split-mode slab|beam|block Use the specified splitting mode\n"
" --enable-smp on|off Use vtkSMPTools vs. vtkMultiThreader\n"
" --enable-smp on|off Use vtkSMPTools (on) vs. vtkMultiThreader (off)\n"
" --clear-cache MBytes Attempt to clear CPU cache between runs\n"
" --bytes-per-piece N Ask for N bytes per piece [65536]\n"
" --min-piece-size XxYxZ Minimum dimensions per piece [16x1x1]\n"
......
......@@ -347,8 +347,3 @@ void vtkImageMapToColors::PrintSelf(ostream& os, vtkIndent indent)
os << "(none)\n";
}
}
......@@ -1648,7 +1648,7 @@ void vtkGetCompositeFunc(
//--------------------------------------------------------------------------
// Check pointer memory alignment with 4-byte words
inline int vtkImageReslicePointerAlignment(void *ptr, int n)
inline bool vtkImageReslicePointerAlignment(void *ptr, int n)
{
return ((reinterpret_cast<uintptr_t>(ptr) % n) == 0);
}
......@@ -1979,13 +1979,13 @@ void vtkImageResliceExecute(vtkImageReslice *self,
}
// extra scalar info for nearest-neighbor optimization
void *inPtr = scalars->GetVoidPointer(0);
const void *inPtr = scalars->GetVoidPointer(0);
int inputScalarSize = scalars->GetDataTypeSize();
int inputScalarType = scalars->GetDataType();
int inComponents = interpolator->GetNumberOfComponents();
int componentOffset = interpolator->GetComponentOffset();
int borderMode = interpolator->GetBorderMode();
int *inExt = interpolator->GetExtent();
const int *inExt = interpolator->GetExtent();
vtkIdType inInc[3];
inInc[0] = scalars->GetNumberOfComponents();
inInc[1] = inInc[0]*(inExt[1] - inExt[0] + 1);
......@@ -1995,7 +1995,7 @@ void vtkImageResliceExecute(vtkImageReslice *self,
fullSize *= (inExt[5] - inExt[4] + 1);
if (componentOffset > 0 && componentOffset + inComponents < inInc[0])
{
inPtr = static_cast<char *>(inPtr) + inputScalarSize*componentOffset;
inPtr = static_cast<const char *>(inPtr) + inputScalarSize*componentOffset;
}
int interpolationMode = VTK_INT_MAX;
......@@ -2108,7 +2108,7 @@ void vtkImageResliceExecute(vtkImageReslice *self,
idY = outExt[2] - 1;
}
// if Y index increased, then advance position along Z axis
// if Y index increased, then advance position along Y axis
if (outIndex[1] > idY)
{
idY = outIndex[1];
......@@ -2372,23 +2372,23 @@ struct vtkImageResliceRowInterpolate
{
static void Nearest(
void *&outPtr0, int idX, int idY, int idZ, int, int n,
vtkInterpolationWeights *weights);
const vtkInterpolationWeights *weights);
static void Nearest1(
void *&outPtr0, int idX, int idY, int idZ, int, int n,
vtkInterpolationWeights *weights);
const vtkInterpolationWeights *weights);
static void Nearest2(
void *&outPtr0, int idX, int idY, int idZ, int, int n,
vtkInterpolationWeights *weights);
const vtkInterpolationWeights *weights);
static void Nearest3(
void *&outPtr0, int idX, int idY, int idZ, int, int n,
vtkInterpolationWeights *weights);
const vtkInterpolationWeights *weights);
static void Nearest4(
void *&outPtr0, int idX, int idY, int idZ, int, int n,
vtkInterpolationWeights *weights);
const vtkInterpolationWeights *weights);
};