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.
nmWTAI-Platform/3rd/VTK7.1/include/vtkArrayListTemplate.h

313 lines
9.4 KiB
C

/*=========================================================================
Program: Visualization Toolkit
Module: vtkArrayListTemplate.h
Copyright (c) Kitware, Inc.
All rights reserved.
See LICENSE file 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 vtkArrayListTemplate
* @brief thread-safe and efficient data attribute manipulation
*
*
* vtkArrayListTemplate supplements the vtkDataSetAttributes class to provide
* threaded processing of data arrays. It is also more efficient for certain
* interpolation operations. The expectation is that it will be replaced one
* day once vtkPointData, vtkCellData, vtkDataSetAttributes, and vtkFieldData
* properly support multithreading and/or are redesigned. Note that this
* implementation does not support incremental operations (like InsertNext()).
*
* Generally the way this helper class is used is to first invoke
* vtkDataSetAttributes::CopyInterpolate() or InterpolateAllocate() which
* performs the initial magic of constructing input and output arrays. Then
* the input attributes, and output attributes, are passed to initialize the
* internal structures. Essentially these internal structures are pairs of
* arrays of the same type, which can be efficently accessed and
* assigned. The operations on these array pairs (e.g., interpolation) occur
* using a typeless, virtual dispatch base class.
*
* @sa
* vtkFieldData vtkDataSetAttributes vtkPointData vtkCellData
*/
#ifndef vtkArrayListTemplate_h
#define vtkArrayListTemplate_h
#include "vtkDataArray.h"
#include "vtkDataSetAttributes.h"
#include "vtkSmartPointer.h"
#include "vtkStdString.h"
#include <vector>
#include <algorithm>
// Create a generic class supporting virtual dispatch to type-specific
// subclasses.
struct BaseArrayPair
{
vtkIdType Num;
int NumComp;
vtkSmartPointer<vtkDataArray> OutputArray;
BaseArrayPair(vtkIdType num, int numComp, vtkDataArray *outArray) :
Num(num), NumComp(numComp), OutputArray(outArray)
{
}
virtual ~BaseArrayPair()
{
}
virtual void Copy(vtkIdType inId, vtkIdType outId) = 0;
virtual void Interpolate(int numWeights, const vtkIdType *ids,
const double *weights, vtkIdType outId) = 0;
virtual void InterpolateEdge(vtkIdType v0, vtkIdType v1,
double t, vtkIdType outId) = 0;
virtual void AssignNullValue(vtkIdType outId) = 0;
virtual void Realloc(vtkIdType sze) = 0;
};
// Type specific interpolation on a matched pair of data arrays
template <typename T>
struct ArrayPair : public BaseArrayPair
{
T *Input;
T *Output;
T NullValue;
ArrayPair(T *in, T *out, vtkIdType num, int numComp, vtkDataArray *outArray, T null) :
BaseArrayPair(num,numComp,outArray), Input(in), Output(out), NullValue(null)
{
}
~ArrayPair() VTK_OVERRIDE //calm down some finicky compilers
{
}
void Copy(vtkIdType inId, vtkIdType outId) VTK_OVERRIDE
{
for (int j=0; j < this->NumComp; ++j)
{
this->Output[outId*this->NumComp+j] = this->Input[inId*this->NumComp+j];
}
}
void Interpolate(int numWeights, const vtkIdType *ids,
const double *weights, vtkIdType outId) VTK_OVERRIDE
{
for (int j=0; j < this->NumComp; ++j)
{
double v = 0.0;
for (vtkIdType i=0; i < numWeights; ++i)
{
v += weights[i] * static_cast<double>(this->Input[ids[i]*this->NumComp+j]);
}
this->Output[outId*this->NumComp+j] = static_cast<T>(v);
}
}
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) VTK_OVERRIDE
{
double v;
vtkIdType numComp=this->NumComp;
for (int j=0; j < numComp; ++j)
{
v = this->Input[v0*numComp+j] +
t * (this->Input[v1*numComp+j] - this->Input[v0*numComp+j]);
this->Output[outId*numComp+j] = static_cast<T>(v);
}
}
void AssignNullValue(vtkIdType outId) VTK_OVERRIDE
{
for (int j=0; j < this->NumComp; ++j)
{
this->Output[outId*this->NumComp+j] = this->NullValue;
}
}
void Realloc(vtkIdType sze) VTK_OVERRIDE
{
this->OutputArray->WriteVoidPointer(0,sze*this->NumComp);
this->Output = static_cast<T*>(this->OutputArray->GetVoidPointer(0));
}
};
// Type specific interpolation on a pair of data arrays with different types, where the
// output type is expected to be a real type (i.e., float or double).
template <typename TInput, typename TOutput>
struct RealArrayPair : public BaseArrayPair
{
TInput *Input;
TOutput *Output;
TOutput NullValue;
RealArrayPair(TInput *in, TOutput *out, vtkIdType num, int numComp, vtkDataArray *outArray, TOutput null) :
BaseArrayPair(num,numComp,outArray), Input(in), Output(out), NullValue(null)
{
}
~RealArrayPair() VTK_OVERRIDE //calm down some finicky compilers
{
}
void Copy(vtkIdType inId, vtkIdType outId) VTK_OVERRIDE
{
for (int j=0; j < this->NumComp; ++j)
{
this->Output[outId*this->NumComp+j] = static_cast<TOutput>(this->Input[inId*this->NumComp+j]);
}
}
void Interpolate(int numWeights, const vtkIdType *ids,
const double *weights, vtkIdType outId) VTK_OVERRIDE
{
for (int j=0; j < this->NumComp; ++j)
{
double v = 0.0;
for (vtkIdType i=0; i < numWeights; ++i)
{
v += weights[i] * static_cast<double>(this->Input[ids[i]*this->NumComp+j]);
}
this->Output[outId*this->NumComp+j] = static_cast<TOutput>(v);
}
}
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId) VTK_OVERRIDE
{
double v;
vtkIdType numComp=this->NumComp;
for (int j=0; j < numComp; ++j)
{
v = this->Input[v0*numComp+j] +
t * (this->Input[v1*numComp+j] - this->Input[v0*numComp+j]);
this->Output[outId*numComp+j] = static_cast<TOutput>(v);
}
}
void AssignNullValue(vtkIdType outId) VTK_OVERRIDE
{
for (int j=0; j < this->NumComp; ++j)
{
this->Output[outId*this->NumComp+j] = this->NullValue;
}
}
void Realloc(vtkIdType sze) VTK_OVERRIDE
{
this->OutputArray->WriteVoidPointer(0,sze*this->NumComp);
this->Output = static_cast<TOutput*>(this->OutputArray->GetVoidPointer(0));
}
};
// Forward declarations. This makes working with vtkTemplateMacro easier.
struct ArrayList;
template <typename T>
void CreateArrayPair(ArrayList *list, T *inData, T *outData,
vtkIdType numTuples, int numComp, T nullValue);
// A list of the arrays to interpolate, and a method to invoke interpolation on the list
struct ArrayList
{
// The list of arrays, and the arrays not to process
std::vector<BaseArrayPair*> Arrays;
std::vector<vtkDataArray*> ExcludedArrays;
// Add the arrays to interpolate here (from attribute data)
void AddArrays(vtkIdType numOutPts, vtkDataSetAttributes *inPD,
vtkDataSetAttributes *outPD, double nullValue=0.0,
bool promote=true);
// Add a pair of arrays (manual insertion). Returns the output array created,
// if any. No array may be created if \c inArray was previously marked as
// excluded using ExcludeArray().
vtkDataArray* AddArrayPair(vtkIdType numTuples, vtkDataArray *inArray,
vtkStdString &outArrayName, double nullValue, bool promote);
// Any array excluded here is not added by AddArrays() or AddArrayPair, hence not
// processed. Also check whether an array is excluded.
void ExcludeArray(vtkDataArray *da);
bool IsExcluded(vtkDataArray *da);
// Loop over the array pairs and copy data from one to another
void Copy(vtkIdType inId, vtkIdType outId)
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
it != Arrays.end(); ++it)
{
(*it)->Copy(inId, outId);
}
}
// Loop over the arrays and have them interpolate themselves
void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId)
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
it != Arrays.end(); ++it)
{
(*it)->Interpolate(numWeights, ids, weights, outId);
}
}
// Loop over the arrays perform edge interpolation
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId)
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
it != Arrays.end(); ++it)
{
(*it)->InterpolateEdge(v0, v1, t, outId);
}
}
// Loop over the arrays and assign the null value
void AssignNullValue(vtkIdType outId)
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
it != Arrays.end(); ++it)
{
(*it)->AssignNullValue(outId);
}
}
// Extend (realloc) the arrays
void Realloc(vtkIdType sze)
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
it != Arrays.end(); ++it)
{
(*it)->Realloc(sze);
}
}
// Only you can prevent memory leaks!
~ArrayList()
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
it != Arrays.end(); ++it)
{
delete (*it);
}
}
// Return the number of arrays
vtkIdType GetNumberOfArrays()
{
return Arrays.size();
}
};
#include "vtkArrayListTemplate.txx"
#endif
// VTK-HeaderTest-Exclude: vtkArrayListTemplate.h