Commit dcd22bc2 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit Committed by David C. Lonie
Browse files

Refactoring to remove iterators.

vtkGenericDataArray no longer uses an iterator. We instead steer users
towards using what we're calling the vtkGenericDataArray concept methods
e.g. Set/GetValue, Set/GetTupleValue, Set/GetComponentValue.
parent 2a43674b
......@@ -258,7 +258,6 @@ set(${vtk-module}_HDRS
vtkGenericDataArray.h
vtkGenericDataArrayLookupHelper.h
vtkGenericDataArrayMacros.h
vtkGenericDataArrayTupleIterator.h
vtkGenericDataArray.txx
vtkIOStream.h
vtkIOStreamFwd.h
......
......@@ -22,11 +22,11 @@ void Test()
array->SetNumberOfComponents(3);
array->SetNumberOfTuples(100);
vtkWriteableGenericDataArrayMacro(array,
for (ARRAY_TYPE::TupleIteratorType iter = ARRAY->Begin(), max = ARRAY->End(); iter != max; ++iter)
for (vtkIdType tupleIdx=0, max=ARRAY->GetNumberOfTuples(); tupleIdx < max; ++tupleIdx)
{
iter[0] = 1;
iter[1] = 2;
iter[2] = 3;
ARRAY->SetComponentValue(tupleIdx, 0, 1);
ARRAY->SetComponentValue(tupleIdx, 1, 2);
ARRAY->SetComponentValue(tupleIdx, 2, 3);
}
);
array->Print(cout);
......@@ -37,5 +37,5 @@ int TestGenericDataArray(int, char**)
{
Test<vtkSoADataArrayTemplate<float> >();
Test<vtkAoSDataArrayTemplate<float> >();
return 1;
return EXIT_SUCCESS;
}
......@@ -29,17 +29,14 @@ template <class ScalarTypeT>
class vtkAoSDataArrayTemplate :
public vtkTypeTemplate<
vtkAoSDataArrayTemplate<ScalarTypeT>,
vtkGenericDataArray<vtkAoSDataArrayTemplate<ScalarTypeT>, ScalarTypeT, std::vector<ScalarTypeT> >
vtkGenericDataArray<vtkAoSDataArrayTemplate<ScalarTypeT>, ScalarTypeT>
>
{
public:
typedef vtkGenericDataArray<vtkAoSDataArrayTemplate<ScalarTypeT>,
ScalarTypeT,
std::vector<ScalarTypeT> > GenericDataArrayType;
typedef vtkGenericDataArray<vtkAoSDataArrayTemplate<ScalarTypeT>, ScalarTypeT > GenericDataArrayType;
typedef GenericDataArrayType Superclass;
typedef vtkAoSDataArrayTemplate<ScalarTypeT> SelfType;
typedef typename Superclass::ScalarType ScalarType;
typedef typename Superclass::TupleType TupleType;
typedef typename Superclass::ScalarReturnType ScalarReturnType;
typedef typename Superclass::ScalarType ValueType; // to match vtkDataArrayTemplate.
......@@ -49,19 +46,40 @@ public:
// Methods that are needed to be implemented by every vtkGenericDataArray
// subclass.
// **************************************************************************
inline ScalarReturnType GetComponentFast(vtkIdType index, int comp) const
inline ScalarReturnType GetValue(vtkIdType valueIdx) const
{
return this->Buffer.GetBuffer()[valueIdx];
}
inline void GetTupleValue(vtkIdType tupleIdx, ScalarType* tuple) const
{
const vtkIdType valueIdx = tupleIdx * this->NumberOfComponents;
std::copy(this->Buffer.GetBuffer() + valueIdx,
this->Buffer.GetBuffer() + valueIdx + this->NumberOfComponents,
tuple);
}
inline ScalarReturnType GetComponentValue(vtkIdType index, int comp) const
{
return this->Buffer.GetBuffer()[this->NumberOfComponents*index + comp];
}
inline TupleType GetTupleFast(vtkIdType index) const
inline void SetValue(vtkIdType valueIdx, ScalarType value)
{
TupleType tuple (this->NumberOfComponents>0? this->NumberOfComponents : 1);
std::copy(this->Buffer.GetBuffer() + (this->NumberOfComponents*index), this->NumberOfComponents, &tuple[0]);
return tuple;
this->Buffer.GetBuffer()[valueIdx] = value;
this->DataChanged();
}
inline void SetTupleValue(vtkIdType tupleIdx, ScalarType* tuple)
{
const vtkIdType valueIdx = tupleIdx * this->NumberOfComponents;
std::copy(tuple, tuple + this->NumberOfComponents,
this->Buffer.GetBuffer() + valueIdx);
this->DataChanged();
}
inline void SetComponentValue(vtkIdType tupleIdx, int comp, ScalarType value)
{
const vtkIdType valueIdx = tupleIdx * this->NumberOfComponents + comp;
this->SetValue(valueIdx, value);
}
// **************************************************************************
// **************************************************************************
// Description:
// Get the address of a particular data index. Make sure data is allocated
// for the number of items requested. Set MaxId according to the number of
......@@ -130,7 +148,7 @@ protected:
private:
vtkAoSDataArrayTemplate(const vtkAoSDataArrayTemplate&); // Not implemented.
void operator=(const vtkAoSDataArrayTemplate&); // Not implemented.
friend class vtkGenericDataArray<vtkAoSDataArrayTemplate<ScalarTypeT>, ScalarTypeT, std::vector<ScalarTypeT> >;
friend class vtkGenericDataArray<vtkAoSDataArrayTemplate<ScalarTypeT>, ScalarTypeT>;
//ETX
};
......
......@@ -24,31 +24,49 @@
#include "vtkTypeTraits.h"
#include "vtkGenericDataArrayLookupHelper.h"
#include "vtkGenericDataArrayHelper.h"
#include "vtkGenericDataArrayTupleIterator.h"
#include <cassert>
template<class DerivedT,
class ScalarTypeT,
class TupleTypeT,
class TupleIteratorTypeT=vtkGenericDataArrayTupleIterator<DerivedT>,
class ScalarReturnTypeT=ScalarTypeT&>
class vtkGenericDataArray : public vtkTypeTemplate<
vtkGenericDataArray<DerivedT, ScalarTypeT, TupleTypeT, TupleIteratorTypeT, ScalarReturnTypeT>,
vtkGenericDataArray<DerivedT, ScalarTypeT, ScalarReturnTypeT>,
vtkDataArray>
{
typedef
vtkGenericDataArray<DerivedT, ScalarTypeT, TupleTypeT, TupleIteratorTypeT, ScalarReturnTypeT> SelfType;
vtkGenericDataArray<DerivedT, ScalarTypeT, ScalarReturnTypeT> SelfType;
public:
typedef ScalarTypeT ScalarType;
typedef ScalarReturnTypeT ScalarReturnType;
typedef TupleTypeT TupleType;
typedef TupleIteratorTypeT TupleIteratorType;
inline TupleIteratorType Begin(vtkIdType pos=0) const
{ return TupleIteratorType(*static_cast<const DerivedT*>(this), pos); }
inline TupleIteratorType End() const
{ return this->Begin(const_cast<SelfType*>(this)->GetNumberOfTuples()); }
//----------------------------------------------------------------------------
// Methods that must be defined by the subclasses.
// Let's call these GenericDataArray concept methods.
inline ScalarReturnType GetValue(vtkIdType valueIdx) const
{
return static_cast<const DerivedT*>(this)->GetValue(valueIdx);
}
inline void GetTupleValue(vtkIdType tupleIdx, ScalarType* tuple) const
{
static_cast<const DerivedT*>(this)->GetTupleValue(tupleIdx, tuple);
}
inline ScalarReturnType GetComponentValue(vtkIdType tupleIdx, int comp) const
{
return static_cast<const DerivedT*>(this)->GetComponentValue(tupleIdx, comp);
}
inline void SetValue(vtkIdType valueIdx, ScalarType value)
{
static_cast<DerivedT*>(this)->SetValue(valueIdx, value);
}
inline void SetTupleValue(vtkIdType tupleIdx, ScalarType* tuple)
{
static_cast<DerivedT*>(this)->SetTupleValue(tupleIdx, tuple);
}
inline void SetComponentValue(vtkIdType tupleIdx, int comp, ScalarType value)
{
static_cast<DerivedT*>(this)->SetComponentValue(tupleIdx, comp, value);
}
// Provide implementations for pure virtual methods in vtkDataArray.
......@@ -174,6 +192,12 @@ public:
return 1;
}
virtual void SetNumberOfComponents(int num)
{
this->vtkDataArray::SetNumberOfComponents(num);
this->LegacyTuple.resize(num);
}
virtual void SetNumberOfTuples(vtkIdType number)
{
if (this->Allocate(number*this->NumberOfComponents, 0))
......@@ -181,6 +205,7 @@ public:
this->MaxId = this->Size - 1;
}
}
virtual void Initialize()
{
this->Resize(0);
......@@ -243,13 +268,12 @@ public:
//----------------------------------------------------------------------------
// Description:
// Removes a tuple at the given index. Default implementation uses
// TupleIteratorType to iterate over tuples to move elements. Subclasses are
// 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.
virtual void RemoveTuple(vtkIdType id);
//----------------------------------------------------------------------------
// Set Value methods. Note the index for all these methods is a "value" index
// or component index assuming traditional VTK style memory layout for tuples
......@@ -275,24 +299,14 @@ public:
}
//----------------------------------------------------------------------------
// vtkArrayIterator API. This provides the generic vtkArrayIterator. Code
// using vtkDataArray should stick to using the TupleIteratorType based
// API when iterating over tuples as that is typically faster.
// vtkArrayIterator API. This provides the generic vtkArrayIterator.
// TODO:
virtual vtkArrayIterator* NewIterator() { return NULL;}
//----------------------------------------------------------------------------
// API provided by vtkDataArrayTemplate/vtkTypedDataArray. These methods used
// to be virtual. They are no longer virtual and use TupleIterator mechanism
// to access values.
// Description:
// Get the data at a particular index. Index is value/component index assuming
// traditional VTK memory layout (array-of-structures).
ScalarType GetValue(vtkIdType idx)
{
return this->GetValueReference(idx);
}
// to be virtual. They are no longer virtual and the vtkGenericDataArray
// concept methods defined above.
// Description:
// Get a reference to the scalar value at a particular index.
......@@ -300,48 +314,9 @@ public:
// traditional VTK memory layout (array-of-structures).
ScalarReturnType GetValueReference(vtkIdType idx)
{
vtkIdType tuple = idx / this->NumberOfComponents;
int comp = static_cast<int>(idx % this->NumberOfComponents);
return this->Begin(tuple)[comp];
return this->GetValue(idx);
}
// Description:
// Set the data at a particular index. Does not do range checking. Make sure
// you use the method SetNumberOfValues() before inserting data.
// Index is value/component index assuming
// traditional VTK memory layout (array-of-structures).
void SetValue(vtkIdType idx, ScalarType value)
{
vtkIdType tuple = idx / this->NumberOfComponents;
int comp = static_cast<int>(idx % this->NumberOfComponents);
this->Begin(tuple)[comp] = value;
this->DataChanged();
}
// Description:
// Copy the tuple value into a user-provided array.
void GetTupleValue(vtkIdType tupleIdx, ScalarType *t)
{
TupleIteratorType iter = this->Begin(tupleIdx);
for (int cc=0; cc < this->NumberOfComponents; ++cc)
{
t[cc] = iter[cc];
}
}
// Description:
// Set the tuple value at the ith location in the array.
void SetTupleValue(vtkIdType tupleIdx, const ScalarType *t)
{
TupleIteratorType iter = this->Begin(tupleIdx);
for (int cc=0; cc < this->NumberOfComponents; ++cc)
{
iter[cc] = t[cc];
}
this->DataChanged();
}
// Description:
// Insert data at the end of the array. Return its location in the array.
vtkIdType InsertNextValue(ScalarType v)
......@@ -384,13 +359,20 @@ public:
// Description:
// Insert (memory allocation performed) the tuple onto the end of the array.
virtual vtkIdType InsertNextTupleValue(const ScalarType *t)
vtkIdType InsertNextTupleValue(const ScalarType *t)
{
vtkIdType nextTuple = this->GetNumberOfTuples();
this->InsertTupleValue(nextTuple, t);
return nextTuple;
}
// Description:
// Returns the number of values i.e.
// (this->NumberOfComponents*this->NumberOfTuples)
inline vtkIdType GetNumberOfValues()
{
return (this->MaxId + 1);
}
protected:
vtkGenericDataArray()
: Lookup(*this)
......
......@@ -21,8 +21,8 @@
#include "vtkVariantCast.h"
#define vtkGenericDataArrayT(returnType) \
template <class D, class S, class T, class TI, class SR> \
returnType vtkGenericDataArray<D, S, T, TI, SR>
template <class D, class S, class SR> \
returnType vtkGenericDataArray<D, S, SR>
//-----------------------------------------------------------------------------
vtkGenericDataArrayT(void)::InsertTuples(
......@@ -122,7 +122,6 @@ vtkGenericDataArrayT(void)::InsertTuples(vtkIdType dstStart, vtkIdType n,
vtkGenericDataArrayT(double *)::GetTuple(vtkIdType i)
{
// XXX Should these be implemented in vtkDataArray?
this->LegacyTuple.resize(this->GetNumberOfComponents());
vtkGenericDataArrayHelper::GetTuple(this, i, &this->LegacyTuple[0]);
return &this->LegacyTuple[0];
}
......@@ -148,7 +147,7 @@ vtkGenericDataArrayT(void)::SetTuple(vtkIdType i, const float *source)
// XXX Should these be implemented in vtkDataArray?
for (int cc=0, max=this->GetNumberOfComponents(); cc < max; ++cc)
{
this->Begin(i)[cc] = static_cast<ScalarType>(source[cc]);
this->SetComponentValue(i, cc, static_cast<ScalarType>(source[cc]));
}
this->DataChanged();
}
......@@ -159,7 +158,7 @@ vtkGenericDataArrayT(void)::SetTuple(vtkIdType i, const double *source)
// XXX Should these be implemented in vtkDataArray?
for (int cc=0, max=this->GetNumberOfComponents(); cc < max; ++cc)
{
this->Begin(i)[cc] = static_cast<ScalarType>(source[cc]);
this->SetComponentValue(i, cc, static_cast<ScalarType>(source[cc]));
}
this->DataChanged();
}
......@@ -185,14 +184,14 @@ vtkGenericDataArrayT(void)::RemoveTuple(vtkIdType id)
assert(len > 0);
int numComps = this->GetNumberOfComponents();
TupleIteratorType from = this->Begin(id+1);
TupleIteratorType to = this->Begin(id);
TupleIteratorType end = this->End();
for (; from != end; ++to, ++from)
vtkIdType fromTuple = id + 1;
vtkIdType toTuple = id;
vtkIdType endTuple = this->GetNumberOfTuples();
for (; fromTuple != endTuple; ++toTuple, ++fromTuple)
{
for (int cc=0; cc < numComps; ++cc)
for (int comp=0; comp < numComps; ++comp)
{
to[cc] = from[cc];
this->SetComponentValue(toTuple, comp, this->GetComponentValue(fromTuple, comp));
}
}
this->SetNumberOfTuples(this->GetNumberOfTuples() - 1);
......@@ -257,15 +256,13 @@ vtkGenericDataArrayT(void)::LookupTypedValue(ScalarType value, vtkIdList* ids)
}
//-----------------------------------------------------------------------------
vtkGenericDataArrayT(void)::SetVariantValue(vtkIdType idx, vtkVariant valueVariant)
vtkGenericDataArrayT(void)::SetVariantValue(vtkIdType valueIdx, vtkVariant valueVariant)
{
bool valid = true;
ScalarType value = vtkVariantCast<ScalarType>(valueVariant, &valid);
if (valid)
{
vtkIdType tupleIndex = static_cast<vtkIdType>(idx / this->NumberOfComponents);
int comp = static_cast<int>(idx % this->NumberOfComponents);
this->Begin(tupleIndex)[comp] = value;
this->SetValue(valueIdx, value);
}
}
......
......@@ -28,8 +28,8 @@ namespace
{
for (int cc=0, max=dest->GetNumberOfComponents(); cc < max; ++cc)
{
dest->Begin(destTuple)[cc] =
static_cast<typename ArrayDestType::ScalarType>(source->Begin(sourceTuple)[cc]);
dest->SetComponentValue(destTuple, cc,
static_cast<typename ArrayDestType::ScalarType>(source->GetComponentValue(sourceTuple, cc)));
}
}
......@@ -39,10 +39,9 @@ namespace
{
for (int cc=0, max=source->GetNumberOfComponents(); cc < max; ++cc)
{
buffer[cc] = static_cast<double>(source->Begin(tuple)[cc]);
buffer[cc] = static_cast<double>(source->GetComponentValue(tuple, cc));
}
}
}
//============================================================================
......
......@@ -35,7 +35,6 @@ class vtkGenericDataArrayLookupHelper
public:
typedef ArrayTypeT ArrayType;
typedef typename ArrayType::ScalarType ScalarType;
typedef typename ArrayType::TupleIteratorType TupleIteratorType;
// Constructor.
vtkGenericDataArrayLookupHelper(ArrayType& associatedArray)
......@@ -114,15 +113,11 @@ private:
if (this->SortedArraySize == 0) { return; }
this->SortedArray = reinterpret_cast<ValueWithIndex*>(malloc(this->SortedArraySize * sizeof(ValueWithIndex)));
for (TupleIteratorType iter = this->AssociatedArray.Begin(); iter != this->AssociatedArray.End(); ++iter)
for (vtkIdType cc=0, max=this->AssociatedArray.GetNumberOfValues(); cc < max; ++cc)
{
for (int cc=0; cc < numComps; ++cc)
{
ValueWithIndex& item = this->SortedArray[iter.GetIndex()*numComps+cc];
item.Value = iter[cc];
item.Index = iter.GetIndex();
// not preserving component index for now.
}
ValueWithIndex& item = this->SortedArray[cc];
item.Value = this->AssociatedArray.GetValue(cc);
item.Index = cc;
}
std::sort(this->SortedArray, this->SortedArray + this->SortedArraySize);
}
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkGenericDataArrayTupleIterator.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.
=========================================================================*/
// .NAME vtkGenericDataArrayTupleIterator
// .SECTION Description
#ifndef vtkGenericDataArrayTupleIterator_h
#define vtkGenericDataArrayTupleIterator_h
#include "vtkObject.h"
template <class ArrayTypeT>
class vtkGenericDataArrayTupleIterator
{
public:
typedef vtkGenericDataArrayTupleIterator<ArrayTypeT> SelfType;
typedef ArrayTypeT ArrayType;
typedef typename ArrayType::ScalarType ScalarType;
typedef typename ArrayType::ScalarReturnType ScalarReturnType;
typedef typename ArrayType::TupleType TupleType;
vtkGenericDataArrayTupleIterator(const ArrayType& associatedArray, const vtkIdType& index=0) :
AssociatedArray(associatedArray), Index(index)
{
}
vtkGenericDataArrayTupleIterator(const SelfType& other) :
AssociatedArray(other.AssociatedArray), Index(other.Index)
{
}
inline const vtkIdType& GetIndex() const { return this->Index; }
inline void operator++() { ++this->Index; }
inline void operator++(int) { this->Index++; }
inline bool operator==(const SelfType& other) const
{
return (this->Index == other.Index);
}
inline bool operator!=(const SelfType& other) const
{
return (this->Index != other.Index);
}
inline ScalarReturnType operator[](int component) const
{
return this->AssociatedArray.GetComponentFast(this->Index, component);
}
inline TupleType operator*() const
{
return this->AssociatedArray.GetTupleFast(this->Index);
}
private:
const ArrayType& AssociatedArray;
vtkIdType Index;
};
#endif
......@@ -21,21 +21,17 @@
#include "vtkGenericDataArray.h"
#include "vtkBuffer.h"
#include <vector>
template <class ScalarTypeT>
class vtkSoADataArrayTemplate : public vtkTypeTemplate<
vtkSoADataArrayTemplate<ScalarTypeT>,
vtkGenericDataArray<vtkSoADataArrayTemplate<ScalarTypeT>, ScalarTypeT, std::vector<ScalarTypeT> >
vtkGenericDataArray<vtkSoADataArrayTemplate<ScalarTypeT>, ScalarTypeT>
>
{
typedef vtkGenericDataArray<vtkSoADataArrayTemplate<ScalarTypeT>,
ScalarTypeT,
std::vector<ScalarTypeT> > GenericDataArrayType;
typedef vtkGenericDataArray<vtkSoADataArrayTemplate<ScalarTypeT>, ScalarTypeT> GenericDataArrayType;
public:
typedef vtkSoADataArrayTemplate<ScalarTypeT> SelfType;
typedef typename GenericDataArrayType::ScalarType ScalarType;
typedef typename GenericDataArrayType::TupleType TupleType;
typedef typename GenericDataArrayType::ScalarReturnType ScalarReturnType;
static vtkSoADataArrayTemplate* New();
......@@ -44,19 +40,43 @@ public:
// Methods that are needed to be implemented by every vtkGenericDataArray
// subclass.
// **************************************************************************
inline ScalarReturnType GetComponentFast(vtkIdType index, int comp) const
inline ScalarReturnType GetValue(vtkIdType valueIdx) const
{
return this->Data[comp].GetBuffer()[index];
vtkIdType tupleIdx;
int comp;
this->GetTupleIndexFromValueIndex(valueIdx, tupleIdx, comp);
return this->GetComponentValue(tupleIdx, comp);
}
inline TupleType GetTupleFast(vtkIdType index) const
inline void GetTupleValue(vtkIdType tupleIdx, ScalarType* tuple) const
{
for (int cc=0; cc < this->NumberOfComponents; cc++)
{
tuple[cc] = this->Data[cc].GetBuffer()[tupleIdx];
}
}
inline ScalarReturnType GetComponentValue(vtkIdType tupleIdx, int comp) const
{
return this->Data[comp].GetBuffer()[tupleIdx];
}
inline void SetValue(vtkIdType valueIdx, ScalarType value)
{
vtkIdType tupleIdx;
int comp;
this->GetTupleIndexFromValueIndex(valueIdx, tupleIdx, comp);
this->SetComponentValue(tupleIdx, comp, value);
}
inline void SetTupleValue(vtkIdType tupleIdx, ScalarType* tuple)
{
TupleType tuple (this->NumberOfComponents>0? this->NumberOfComponents : 1);
for (int cc=0; cc < this->NumberOfComponents; ++cc)
{
tuple[cc] = this->Data[cc].GetBuffer()[index];
this->Data[cc].GetBuffer()[tupleIdx] = tuple[cc];
}
return tuple;
}
inline void SetComponentValue(vtkIdType tupleIdx, int comp, ScalarType value)
{
this->Data[comp].GetBuffer()[tupleIdx] = value;
}
// **************************************************************************
enum DeleteMethod
......@@ -106,11 +126,19 @@ protected:
std::vector<vtkBuffer<ScalarType> > Data;
bool Resizeable;
double NumberOfComponentsReciprocal;
private:
vtkSoADataArrayTemplate(const vtkSoADataArrayTemplate&); // Not implemented.
void operator=(const vtkSoADataArrayTemplate&); // Not implemented.
friend class vtkGenericDataArray<vtkSoADataArrayTemplate<ScalarTypeT>, ScalarTypeT, std::vector<ScalarTypeT> >;
inline void GetTupleIndexFromValueIndex(vtkIdType valueIdx, vtkIdType& tupleIdx, int& comp) const
{
tupleIdx = static_cast<vtkIdType>(valueIdx * this->NumberOfComponentsReciprocal);
comp = valueIdx - (tupleIdx * this->NumberOfComponents);
}
friend class vtkGenericDataArray<vtkSoADataArrayTemplate<ScalarTypeT>, ScalarTypeT>;
};
#include "vtkSoADataArrayTemplate.txx"
......
......@@ -25,7 +25,8 @@ vtkSoADataArrayTemplate<ScalarType>::New()
//-----------------------------------------------------------------------------
template<class ScalarType>
vtkSoADataArrayTemplate<ScalarType>::vtkSoADataArrayTemplate()
: Resizeable(true)
: Resizeable(true),
NumberOfComponentsReciprocal(1.0)
{
}
......@@ -52,6 +53,7 @@ void vtkSoADataArrayTemplate<ScalarType>::SetNumberOfComponents(int val)
this->Data.pop_back();
}
this->Data.resize(numComps);
this->NumberOfComponentsReciprocal = 1.0 / this->NumberOfComponents;