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/vtkGenericDataArray.h

356 lines
14 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkGenericDataArray.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 vtkGenericDataArray
* @brief Base interface for all typed vtkDataArray
* subclasses.
*
*
*
* A more detailed description of this class and related tools can be found
* \ref VTK-7-1-ArrayDispatch "here".
*
* The vtkGenericDataArray class provides a generic implementation of the
* vtkDataArray API. It relies on subclasses providing access to data
* via 8 "concept methods", which should be implemented as non-virtual
* methods of the subclass. These methods are:
*
* - ValueType GetValue(vtkIdType valueIdx) const
* - [public] void SetValue(vtkIdType valueIdx, ValueType value)
* - [public] void GetTypedTuple(vtkIdType tupleIdx, ValueType* tuple) const
* - [public] void SetTypedTuple(vtkIdType tupleIdx, const ValueType* tuple)
* - [public] ValueType GetTypedComponent(vtkIdType tupleIdx, int compIdx) const
* - [public] void SetTypedComponent(vtkIdType tupleIdx, int compIdx,
* ValueType value)
* - [protected] bool AllocateTuples(vtkIdType numTuples)
* - [protected] bool ReallocateTuples(vtkIdType numTuples)
*
* Note that these methods use the CRTP idiom, which provides static binding to
* avoid virtual calls. This allows the compiler to optimize away layers of
* indirection when these methods are used. Well-designed implementations
* of these methods will reduce to raw memory accesses, providing efficient
* performance comparable to working with the pointer data.
*
* See vtkAOSDataArrayTemplate and vtkSOADataArrayTemplate for example
* implementations.
*
* In practice, code should not be written to use vtkGenericDataArray objects.
* Doing so is rather unweildy due to the CRTP pattern requiring the derived
* class be provided as a template argument. Instead, the vtkArrayDispatch
* framework can be used to detect a vtkDataArray's implementation type and
* instantiate appropriate templated worker code.
*
* vtkArrayDispatch is also intended to replace code that currently relies on
* the encapsulation-breaking GetVoidPointer method. Not all subclasses of
* vtkDataArray use the memory layout assumed by GetVoidPointer; calling this
* method on, e.g. a vtkSOADataArrayTemplate will trigger a deep copy of the
* array data into an AOS buffer. This is very inefficient and should be
* avoided.
*
* @sa
* vtkArrayDispatcher vtkDataArrayAccessor
*/
#ifndef vtkGenericDataArray_h
#define vtkGenericDataArray_h
#include "vtkDataArray.h"
#include "vtkSmartPointer.h"
#include "vtkTypeTraits.h"
#include "vtkGenericDataArrayLookupHelper.h"
#include <cassert>
template<class DerivedT, class ValueTypeT>
class vtkGenericDataArray : public vtkDataArray
{
typedef vtkGenericDataArray<DerivedT, ValueTypeT> SelfType;
public:
typedef ValueTypeT ValueType;
vtkTemplateTypeMacro(SelfType, vtkDataArray)
/**
* Compile time access to the VTK type identifier.
*/
enum { VTK_DATA_TYPE = vtkTypeTraits<ValueType>::VTK_TYPE_ID };
/// @defgroup vtkGDAConceptMethods vtkGenericDataArray Concept Methods
/// These signatures must be reimplemented in subclasses as public,
/// non-virtual methods. Ideally, they should be inlined and as efficient as
/// possible to ensure the best performance possible.
/**
* Get the value at @a valueIdx. @a valueIdx assumes AOS ordering.
* @note GetTypedComponent is preferred over this method. It is faster for
* SOA arrays, and shows equivalent performance for AOS arrays when
* NumberOfComponents is known to the compiler (See vtkAssume.h).
* @ingroup vtkGDAConceptMethods
*/
inline ValueType GetValue(vtkIdType valueIdx) const
{
return static_cast<const DerivedT*>(this)->GetValue(valueIdx);
}
/**
* Set the value at @a valueIdx to @a value. @a valueIdx assumes AOS ordering.
* @note SetTypedComponent is preferred over this method. It is faster for
* SOA arrays, and shows equivalent performance for AOS arrays when
* NumberOfComponents is known to the compiler (See vtkAssume.h).
* @ingroup vtkGDAConceptMethods
*/
inline void SetValue(vtkIdType valueIdx, ValueType value)
{
static_cast<DerivedT*>(this)->SetValue(valueIdx, value);
}
/**
* Copy the tuple at @a tupleIdx into @a tuple.
* @note GetTypedComponent is preferred over this method. The overhead of
* copying the tuple is significant compared to the more performant
* component-wise access methods, which typically optimize to raw memory
* access.
* @ingroup vtkGDAConceptMethods
*/
inline void GetTypedTuple(vtkIdType tupleIdx, ValueType* tuple) const
{
static_cast<const DerivedT*>(this)->GetTypedTuple(tupleIdx, tuple);
}
/**
* Set this array's tuple at @a tupleIdx to the values in @a tuple.
* @note SetTypedComponent is preferred over this method. The overhead of
* copying the tuple is significant compared to the more performant
* component-wise access methods, which typically optimize to raw memory
* access.
* @ingroup vtkGDAConceptMethods
*/
inline void SetTypedTuple(vtkIdType tupleIdx, const ValueType* tuple)
{
static_cast<DerivedT*>(this)->SetTypedTuple(tupleIdx, tuple);
}
/**
* Get component @a compIdx of the tuple at @a tupleIdx. This is typically
* the fastest way to access array data.
* @ingroup vtkGDAConceptMethods
*/
inline ValueType GetTypedComponent(vtkIdType tupleIdx, int compIdx) const
{
return static_cast<const DerivedT*>(this)->GetTypedComponent(tupleIdx,
compIdx);
}
/**
* Set component @a compIdx of the tuple at @a tupleIdx to @a value. This is
* typically the fastest way to set array data.
* @ingroup vtkGDAConceptMethods
*/
inline void SetTypedComponent(vtkIdType tupleIdx, int compIdx,
ValueType value)
{
static_cast<DerivedT*>(this)->SetTypedComponent(tupleIdx, compIdx, value);
}
//@{
/**
* Default implementation raises a runtime error. If subclasses keep on
* supporting this API, they should override this method.
*/
void *GetVoidPointer(vtkIdType valueIdx) VTK_OVERRIDE;
ValueType* GetPointer(vtkIdType valueIdx);
void SetVoidArray(void*, vtkIdType, int) VTK_OVERRIDE;
void SetVoidArray(void*, vtkIdType, int, int) VTK_OVERRIDE;
void* WriteVoidPointer(vtkIdType valueIdx, vtkIdType numValues) VTK_OVERRIDE;
ValueType* WritePointer(vtkIdType valueIdx, vtkIdType numValues);
//@}
/**
* Removes a tuple at the given index. Default implementation
* iterates over tuples to move elements. Subclasses are
* encouraged to reimplemented this method to support faster implementations,
* if needed.
*/
void RemoveTuple(vtkIdType tupleIdx) VTK_OVERRIDE;
/**
* Insert data at the end of the array. Return its location in the array.
*/
vtkIdType InsertNextValue(ValueType value);
/**
* Insert data at a specified position in the array.
*/
void InsertValue(vtkIdType valueIdx, ValueType value);
/**
* Insert (memory allocation performed) the tuple t at tupleIdx.
*/
void InsertTypedTuple(vtkIdType tupleIdx, const ValueType *t);
/**
* Insert (memory allocation performed) the tuple onto the end of the array.
*/
vtkIdType InsertNextTypedTuple(const ValueType *t);
/**
* Insert (memory allocation performed) the value at the specified tuple and
* component location.
*/
void InsertTypedComponent(vtkIdType tupleIdx, int compIdx, ValueType val);
//@{
/**
* Get the range of array values for the given component in the
* native data type.
*/
void GetValueRange(ValueType range[2], int comp);
ValueType *GetValueRange(int comp);
//@}
/**
* Get the range of array values for the 0th component in the
* native data type.
*/
ValueType *GetValueRange() { return this->GetValueRange(0); }
void GetValueRange(ValueType range[2]) { this->GetValueRange(range, 0); }
/**
* Return the capacity in typeof T units of the current array.
* TODO Leftover from vtkDataArrayTemplate, redundant with GetSize. Deprecate?
*/
vtkIdType Capacity() { return this->Size; }
int GetDataType() VTK_OVERRIDE;
int GetDataTypeSize() VTK_OVERRIDE;
bool HasStandardMemoryLayout() VTK_OVERRIDE;
int Allocate(vtkIdType size, vtkIdType ext = 1000) VTK_OVERRIDE;
int Resize(vtkIdType numTuples) VTK_OVERRIDE;
void SetNumberOfComponents(int num) VTK_OVERRIDE;
void SetNumberOfTuples(vtkIdType number) VTK_OVERRIDE;
void Initialize() VTK_OVERRIDE;
void Squeeze() VTK_OVERRIDE;
void SetTuple(vtkIdType dstTupleIdx, vtkIdType srcTupleIdx,
vtkAbstractArray* source) VTK_OVERRIDE;
// MSVC doesn't like 'using' here (error C2487). Just forward instead:
// using Superclass::SetTuple;
void SetTuple(vtkIdType tupleIdx, const float *tuple) VTK_OVERRIDE
{ this->Superclass::SetTuple(tupleIdx, tuple); }
void SetTuple(vtkIdType tupleIdx, const double *tuple) VTK_OVERRIDE
{ this->Superclass::SetTuple(tupleIdx, tuple); }
void InsertTuples(vtkIdList *dstIds, vtkIdList *srcIds,
vtkAbstractArray *source) VTK_OVERRIDE;
// MSVC doesn't like 'using' here (error C2487). Just forward instead:
// using Superclass::InsertTuples;
void InsertTuples(vtkIdType dstStart, vtkIdType n, vtkIdType srcStart,
vtkAbstractArray* source) VTK_OVERRIDE
{ this->Superclass::InsertTuples(dstStart, n, srcStart, source); }
void InsertTuple(vtkIdType dstTupleIdx, vtkIdType srcTupleIdx,
vtkAbstractArray *source) VTK_OVERRIDE;
void InsertTuple(vtkIdType tupleIdx, const float *source) VTK_OVERRIDE;
void InsertTuple(vtkIdType tupleIdx, const double *source) VTK_OVERRIDE;
void InsertComponent(vtkIdType tupleIdx, int compIdx,
double value) VTK_OVERRIDE;
vtkIdType InsertNextTuple(vtkIdType srcTupleIdx,
vtkAbstractArray *source) VTK_OVERRIDE;
vtkIdType InsertNextTuple(const float *tuple) VTK_OVERRIDE;
vtkIdType InsertNextTuple(const double *tuple) VTK_OVERRIDE;
void GetTuples(vtkIdList *tupleIds,
vtkAbstractArray *output) VTK_OVERRIDE;
void GetTuples(vtkIdType p1, vtkIdType p2,
vtkAbstractArray *output) VTK_OVERRIDE;
double *GetTuple(vtkIdType tupleIdx) VTK_OVERRIDE;
void GetTuple(vtkIdType tupleIdx, double * tuple) VTK_OVERRIDE;
void InterpolateTuple(vtkIdType dstTupleIdx, vtkIdList *ptIndices,
vtkAbstractArray* source,
double* weights) VTK_OVERRIDE;
void InterpolateTuple(vtkIdType dstTupleIdx,
vtkIdType srcTupleIdx1, vtkAbstractArray* source1,
vtkIdType srcTupleIdx2, vtkAbstractArray* source2, double t) VTK_OVERRIDE;
void SetComponent(vtkIdType tupleIdx, int compIdx, double value) VTK_OVERRIDE;
double GetComponent(vtkIdType tupleIdx, int compIdx) VTK_OVERRIDE;
void SetVariantValue(vtkIdType valueIdx, vtkVariant value) VTK_OVERRIDE;
vtkVariant GetVariantValue(vtkIdType valueIdx) VTK_OVERRIDE;
void InsertVariantValue(vtkIdType valueIdx, vtkVariant value) VTK_OVERRIDE;
vtkIdType LookupValue(vtkVariant value) VTK_OVERRIDE;
virtual vtkIdType LookupTypedValue(ValueType value);
void LookupValue(vtkVariant value, vtkIdList* valueIds) VTK_OVERRIDE;
virtual void LookupTypedValue(ValueType value, vtkIdList* valueIds);
void ClearLookup() VTK_OVERRIDE;
void DataChanged() VTK_OVERRIDE;
VTK_NEWINSTANCE vtkArrayIterator* NewIterator() VTK_OVERRIDE;
protected:
vtkGenericDataArray();
~vtkGenericDataArray() VTK_OVERRIDE;
/**
* Allocate space for numTuples. Old data is not preserved. If numTuples == 0,
* all data is freed.
* @ingroup vtkGDAConceptMethods
*/
inline bool AllocateTuples(vtkIdType numTuples)
{
return static_cast<DerivedT*>(this)->AllocateTuples(numTuples);
}
/**
* Allocate space for numTuples. Old data is preserved. If numTuples == 0,
* all data is freed.
* @ingroup vtkGDAConceptMethods
*/
inline bool ReallocateTuples(vtkIdType numTuples)
{
return static_cast<DerivedT*>(this)->ReallocateTuples(numTuples);
}
// This method resizes the array if needed so that the given tuple index is
// valid/accessible.
bool EnsureAccessToTuple(vtkIdType tupleIdx);
vtkGenericDataArrayLookupHelper<SelfType> Lookup;
private:
vtkGenericDataArray(const vtkGenericDataArray&) VTK_DELETE_FUNCTION;
void operator=(const vtkGenericDataArray&) VTK_DELETE_FUNCTION;
std::vector<double> LegacyTuple;
std::vector<ValueType> LegacyValueRange;
};
#include "vtkGenericDataArray.txx"
// Adds an implementation of NewInstanceInternal() that returns an AoS
// (unmapped) VTK array, if possible. This allows the pipeline to copy and
// propagate the array when the array data is not modifiable. Use this in
// combination with vtkAbstractTypeMacro or vtkAbstractTemplateTypeMacro
// (instead of vtkTypeMacro) to avoid adding the default NewInstance
// implementation.
#define vtkAOSArrayNewInstanceMacro(thisClass) \
protected: \
vtkObjectBase *NewInstanceInternal() const VTK_OVERRIDE \
{ \
if (vtkDataArray *da = \
vtkDataArray::CreateDataArray(thisClass::VTK_DATA_TYPE)) \
{ \
return da; \
} \
return thisClass::New(); \
} \
public:
#endif
// VTK-HeaderTest-Exclude: vtkGenericDataArray.h