Commit fad86463 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

ENH:

* vtkDataArray now has a new superclass-vtkAbstractArray.vtkAbstractArray
provides type-agnostic API to access array elements. vtkDataArray provides
a double API to access values -- such an API is deliberately missing from
vtkAbstractArray, since arrays like string arrays are not castable to doubles.

* vtkAbstractArray has the notion of components/tuples, but does not make
any assumptions about the arragment of these. It's up to the concrete
subclasses how the data is represented in memory.

* vtkFieldData used to provide tuple API to get/set values from data arrays
contained in it. However, now that FieldData can have arrays that are not
vtkDataArrays, this API is not longer valid.
The following are the methods that are no longer available:
double* GetTuple(const vtkIdType);
void SetTuple(const vtkIdType i, const double* tuple);
void GetTuple(const vtkIdType i, double* tuple);
void InsertTuple(const vtkIdType i, const double* tuple);
void InsertNextTuple(cons double*);
double GetComponent(const vtkIdType i, const int j);
void SetComponent(const vtkIdType i, const int j, const double c);
void InsertComponent(const vtkIdType i, const int j, const double c);
However, new API is provided to copy tuples arround from one field data to
another using:
void SetTuple(const vtkIdType i, const vtkIdType j, vtkFieldData* source);
void InsertTuple(const vtkIdType i, const vtkIdType j, vtkFieldData* source);
vtkIdType InsertNextTuple(const vtkIdType j, vtkFieldData* source);

* vtkFieldData provide a vtkDataArray* GetArray(int index) to retrieve arrays
in the field data. This function can will now return a NULL if the array
at the given index is not a data array. It provides
vtkAbstractArray* GetAbstractArray(int index);
to retrieve an array even if it isn't a vtkDataArray.

* Since vtkFieldData can contain arrays that aren't subclasses of
vtkDataArray, so can vtkDataSetAttributes. However, an attribute can only be
a vtkDataArray subclass i.e. one cannot set a vtkStringArray as the SCALARS
array for a Point Data, for example.

* String Array IO is only supported in XML file formats. If deemed important,
support may be added for lecacy file formats.

*** Array Iterators ***
Another addition to the VTK Arrays, is the notion of Array Iterator. A
vtkArrayIterator subclass is be provided for every vtkAbstractArray
subclass. The iterator is a random access iterator. The iterators are not
available in any of the wrapped languages, however, in C++ they can be used to
write templatized code to processes the array values without any implicit type
conversion and consequent loss of precision. vtkArrayIteratorTemplateMacro is
provided to simply switching between different types of the arrays. Examples of
use of this macro and the iterators can be found in
vtkXMLWriter.cxx / vtkXMLDataReader.cxx / vtkXMLStructuredDataReader.cxx.
parent d75ee0a4
......@@ -25,10 +25,12 @@ vtkAbstractTransform.cxx
vtkAmoebaMinimizer.cxx
vtkAnimationCue.cxx
vtkAnimationScene.cxx
vtkArrayIterator.cxx
vtkAssemblyNode.cxx
vtkAssemblyPath.cxx
vtkAssemblyPaths.cxx
vtkBitArray.cxx
vtkBitArrayIterator.cxx
vtkBox.cxx
vtkByteSwap.cxx
vtkCallbackCommand.cxx
......@@ -213,6 +215,8 @@ ENDFOREACH(t)
SET_SOURCE_FILES_PROPERTIES(
# vtkObjectBase is marked ABSTRACT so that instantiators are happy.
vtkAbstractArray
vtkArrayIterator
vtkArrayIteratorTemplate
vtkAbstractTransform
vtkCallbackCommand
vtkCommand
......@@ -238,6 +242,7 @@ ABSTRACT
)
SET_SOURCE_FILES_PROPERTIES(
vtkArrayIteratorTemplate.txx
vtkCallbackCommand.cxx
vtkCommand.cxx
vtkDebugLeaksManager.cxx
......@@ -283,6 +288,7 @@ INCLUDE(${VTK_CMAKE_DIR}/KitCommonBlock.cmake)
IF(NOT VTK_INSTALL_NO_DEVELOPMENT)
INSTALL_FILES(${VTK_INSTALL_INCLUDE_DIR} .h
vtkArrayIteratorTemplate
vtkDataArrayTemplate
vtkIOStream
vtkIOStreamFwd
......@@ -325,6 +331,8 @@ IF(NOT VTK_INSTALL_NO_DEVELOPMENT)
ENDIF(VTK_WRAP_JAVA)
INSTALL_FILES(${VTK_INSTALL_INCLUDE_DIR} .txx
vtkArrayIteratorTemplate
vtkArrayIteratorTemplateImplicit
vtkDataArrayTemplate
vtkDataArrayTemplateImplicit
)
......
......@@ -16,6 +16,7 @@ IF(PYTHON_EXECUTABLE)
vtkAbstractIterator.h
vtkAbstractList.h
vtkAbstractMap.h
vtkArrayIteratorIncludes.h
vtkArrayMap.h
vtkArrayMapIterator.h
vtkAssemblyPaths.h
......
......@@ -65,11 +65,12 @@ int otherFieldData(int,char *[])
int arrayComp;
int a = fd->GetArrayContainingComponent(1, arrayComp);
if (a != 0)
if (a != 1)
{
return 1;
}
/* Obsolete API.
double tuple[10];
// initialize tuple before using it to set something
for (i = 0; i < 10; i++)
......@@ -82,7 +83,7 @@ int otherFieldData(int,char *[])
fd->InsertNextTuple(tuple);
fd->SetComponent(0,0, 1.0);
fd->InsertComponent(0,0, 1.0);
*/
fd2->Reset();
fd->Delete();
......
......@@ -118,7 +118,7 @@ int doStringArrayTest(ostream& strm, int size)
strm << "FAILED" << endl;
}
strm << "\tvtkAbstractArray::GetValues(vtkIdList)...";
strm << "\tvtkAbstractArray::GetTuples(vtkIdList)...";
vtkIdList *indices = vtkIdList::New();
indices->InsertNextId(10);
indices->InsertNextId(20);
......@@ -126,7 +126,7 @@ int doStringArrayTest(ostream& strm, int size)
vtkStringArray *newValues = vtkStringArray::New();
newValues->SetNumberOfValues(3);
ptr->GetValues(indices, newValues);
ptr->GetTuples(indices, newValues);
if (newValues->GetValue(0) == "string entry 10" &&
newValues->GetValue(1) == "string entry 20" &&
......@@ -148,9 +148,9 @@ int doStringArrayTest(ostream& strm, int size)
newValues->Reset();
strm << "\tvtkAbstractArray::GetValues(vtkIdType, vtkIdType)...";
strm << "\tvtkAbstractArray::GetTuples(vtkIdType, vtkIdType)...";
newValues->SetNumberOfValues(3);
ptr->GetValues(30, 32, newValues);
ptr->GetTuples(30, 32, newValues);
if (newValues->GetValue(0) == "string entry 30" &&
newValues->GetValue(1) == "string entry 31" &&
newValues->GetValue(2) == "string entry 32")
......@@ -163,8 +163,8 @@ int doStringArrayTest(ostream& strm, int size)
strm << "FAILED" << endl;
}
strm << "\tvtkAbstractArray::CopyValue...";
ptr->CopyValue(150, 2, newValues);
strm << "\tvtkAbstractArray::InsertTuple...";
ptr->InsertTuple(150, 2, newValues);
if (ptr->GetValue(150) == "string entry 32")
{
strm << "OK" << endl;
......@@ -183,66 +183,6 @@ int doStringArrayTest(ostream& strm, int size)
ptr->Delete();
delete [] strings;
strm << "\tvtkAbstractArray::ConvertToContiguous...";
vtkStringArray *srcArray = vtkStringArray::New();
vtkStringArray *destArray = vtkStringArray::New();
srcArray->InsertNextValue("First");
srcArray->InsertNextValue("Second");
srcArray->InsertNextValue("Third");
vtkDataArray *data;
vtkIdTypeArray *offsets;
srcArray->ConvertToContiguous(&data, &offsets);
char combinedString[] = "FirstSecondThird";
vtkCharArray *charData = vtkCharArray::SafeDownCast(data);
if (charData == NULL)
{
++errors;
strm << "FAILED: couldn't downcast data array" << endl;
}
else
{
for (int i = 0; i < static_cast<int>(strlen(combinedString)); ++i)
{
if (charData->GetValue(i) != combinedString[i])
{
strm << "FAILED: array element " << i << " is wrong. Expected "
<< combinedString[i] << ", got "
<< charData->GetValue(i) << endl;
++errors;
}
}
destArray->ConvertFromContiguous(data, offsets);
if (destArray->GetNumberOfValues() != srcArray->GetNumberOfValues())
{
++errors;
strm << "FAILED: reconstructed lengths don't match" << endl;
}
else
{
for (int i = 0; i < srcArray->GetNumberOfValues(); ++i)
{
if (destArray->GetValue(i) != srcArray->GetValue(i))
{
strm << "FAILED: element " << i << " doesn't match" << endl;
++errors;
}
}
}
}
srcArray->Delete();
destArray->Delete();
data->Delete();
offsets->Delete();
return errors;
}
......
......@@ -13,135 +13,105 @@
=========================================================================*/
#include "vtkAbstractArray.h"
#include "vtkIdList.h"
#include "vtkMath.h"
#include "vtkDataArray.h"
#include "vtkBitArray.h"
#include "vtkCharArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIdList.h"
#include "vtkIntArray.h"
#include "vtkIdTypeArray.h"
#include "vtkLongArray.h"
#include "vtkShortArray.h"
#include "vtkSignedCharArray.h"
#include "vtkStringArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkUnsignedIntArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkUnsignedShortArray.h"
vtkCxxRevisionMacro(vtkAbstractArray, "1.5");
#if defined(VTK_TYPE_USE_LONG_LONG)
# include "vtkLongLongArray.h"
# include "vtkUnsignedLongLongArray.h"
#endif
#if defined(VTK_TYPE_USE___INT64)
# include "vtk__Int64Array.h"
# if defined(VTK_TYPE_CONVERT_UI64_TO_DOUBLE)
# include "vtkUnsigned__Int64Array.h"
# endif
#endif
vtkCxxRevisionMacro(vtkAbstractArray, "1.6");
//----------------------------------------------------------------------------
// Construct object with sane defaults.
vtkAbstractArray::vtkAbstractArray(vtkIdType vtkNotUsed(numComp))
{
this->Size = 0;
this->MaxId = -1;
this->NumberOfComponents = 1;
this->Name = NULL;
this->DataType = -1;
}
//----------------------------------------------------------------------------
vtkAbstractArray::~vtkAbstractArray()
{
if (this->Name != NULL)
{
delete [] this->Name;
}
this->Name = NULL;
this->SetName(NULL);
}
void vtkAbstractArray::SetName(const char* name)
//----------------------------------------------------------------------------
void vtkAbstractArray::GetTuples(vtkIdList* ptIds, vtkAbstractArray* aa)
{
if (this->Name != NULL)
if (aa->GetNumberOfComponents() != this->GetNumberOfComponents())
{
delete[] this->Name;
vtkWarningMacro("Number of components for input and output do not match.");
return;
}
this->Name = NULL;
if (name)
// Here we give the slowest implementation. Subclasses can override
// to use the knowledge about the data.
vtkIdType num = ptIds->GetNumberOfIds();
for (vtkIdType i = 0; i < num; i++)
{
int size = static_cast<int>(strlen(name));
this->Name = new char[size+1];
strcpy(this->Name, name);
aa->SetTuple(i, ptIds->GetId(i), this);
}
}
const char* vtkAbstractArray::GetName()
//----------------------------------------------------------------------------
void vtkAbstractArray::GetTuples(vtkIdType p1, vtkIdType p2,
vtkAbstractArray* aa)
{
return this->Name;
}
void vtkAbstractArray::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
const char* name = this->GetName();
if (name)
if (aa->GetNumberOfComponents() != this->GetNumberOfComponents())
{
os << indent << "Name: " << name << "\n";
vtkWarningMacro("Number of components for input and output do not match.");
return;
}
else
// Here we give the slowest implementation. Subclasses can override
// to use the knowledge about the data.
vtkIdType num = p2 - p1 + 1;
for (vtkIdType i = 0; i < num; i++)
{
os << indent << "Name: (none)\n";
aa->SetTuple(i, (p1+i), this);
}
os << indent << "Data type: " << this->GetDataTypeAsString();
os << indent << "Size: " << this->Size << "\n";
os << indent << "MaxId: " << this->MaxId << "\n";
}
//----------------------------------------------------------------------------
template <class T>
unsigned long vtkAbstractArrayGetDataTypeSize(T*)
{
return sizeof(T);
}
unsigned long vtkAbstractArray::GetDataTypeSize(int type)
{
switch (type)
{
vtkTemplateMacro(
return vtkAbstractArrayGetDataTypeSize(static_cast<VTK_TT*>(0))
);
case VTK_BIT:
return 1;
break;
case VTK_CHAR:
return sizeof(char);
break;
case VTK_UNSIGNED_CHAR:
return sizeof(unsigned char);
break;
case VTK_SHORT:
return sizeof(short);
break;
case VTK_UNSIGNED_SHORT:
return sizeof(unsigned short);
break;
case VTK_INT:
return sizeof(int);
break;
case VTK_UNSIGNED_INT:
return sizeof(unsigned int);
break;
case VTK_LONG:
return sizeof(long);
break;
case VTK_UNSIGNED_LONG:
return sizeof(unsigned long);
break;
case VTK_FLOAT:
return sizeof(float);
break;
case VTK_DOUBLE:
return sizeof(double);
break;
case VTK_ID_TYPE:
return sizeof(vtkIdType);
return 0;
break;
case VTK_STRING:
......@@ -156,8 +126,6 @@ unsigned long vtkAbstractArray::GetDataTypeSize(int type)
}
// ----------------------------------------------------------------------
#if 0
vtkAbstractArray* vtkAbstractArray::CreateArray(int dataType)
{
switch (dataType)
......@@ -168,6 +136,9 @@ vtkAbstractArray* vtkAbstractArray::CreateArray(int dataType)
case VTK_CHAR:
return vtkCharArray::New();
case VTK_SIGNED_CHAR:
return vtkSignedCharArray::New();
case VTK_UNSIGNED_CHAR:
return vtkUnsignedCharArray::New();
......@@ -189,6 +160,26 @@ vtkAbstractArray* vtkAbstractArray::CreateArray(int dataType)
case VTK_UNSIGNED_LONG:
return vtkUnsignedLongArray::New();
#if defined(VTK_TYPE_USE_LONG_LONG)
case VTK_LONG_LONG:
return vtkLongLongArray::New();
case VTK_UNSIGNED_LONG_LONG:
return vtkUnsignedLongLongArray::New();
#endif
#if defined(VTK_TYPE_USE___INT64)
case VTK___INT64:
return vtk__Int64Array::New();
break;
# if defined(VTK_TYPE_CONVERT_UI64_TO_DOUBLE)
case VTK_UNSIGNED___INT64:
return vtkUnsigned__Int64Array::New();
break;
# endif
#endif
case VTK_FLOAT:
return vtkFloatArray::New();
......@@ -197,10 +188,33 @@ vtkAbstractArray* vtkAbstractArray::CreateArray(int dataType)
case VTK_ID_TYPE:
return vtkIdTypeArray::New();
case VTK_STRING:
return vtkStringArray::New();
default:
vtkGenericWarningMacro(<<"Unsupported data type! Setting to VTK_DOUBLE");
vtkGenericWarningMacro("Unsupported data type " << dataType
<< "! Setting to VTK_DOUBLE");
return vtkDoubleArray::New();
}
}
#endif
//----------------------------------------------------------------------------
void vtkAbstractArray::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
const char* name = this->GetName();
if (name)
{
os << indent << "Name: " << name << "\n";
}
else
{
os << indent << "Name: (none)\n";
}
os << indent << "Data type: " << this->GetDataTypeAsString();
os << indent << "Size: " << this->Size << "\n";
os << indent << "MaxId: " << this->MaxId << "\n";
os << indent << "NumberOfComponents: " << this->NumberOfComponents << endl;
}
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkArrayIterator.cxx
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.
=========================================================================*/
#include "vtkArrayIterator.h"
#include "vtkObjectFactory.h"
vtkCxxRevisionMacro(vtkArrayIterator, "1.1");
//-----------------------------------------------------------------------------
vtkArrayIterator::vtkArrayIterator()
{
}
//-----------------------------------------------------------------------------
vtkArrayIterator::~vtkArrayIterator()
{
}
//-----------------------------------------------------------------------------
void vtkArrayIterator::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkArrayIterator.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 vtkArrayIterator - Abstract superclass to iterate over elements in
// an vtkAbstractArray.
// .SECTION Description
//
#ifndef __vtkArrayIterator_h
#define __vtkArrayIterator_h
#include "vtkObject.h"
class vtkAbstractArray;
class VTK_COMMON_EXPORT vtkArrayIterator : public vtkObject
{
public:
vtkTypeRevisionMacro(vtkArrayIterator, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Set the array this iterator will iterate over.
// After Initialize() has been called, the iterator is valid
// so long as the Array has not been modified
// (except using the iterator itself).
// If the array is modified, the iterator must be re-intialized.
virtual void Initialize(vtkAbstractArray* array) = 0;
protected:
vtkArrayIterator();
~vtkArrayIterator();
private:
vtkArrayIterator(const vtkArrayIterator&); // Not implemented.
void operator=(const vtkArrayIterator&); // Not implemented.
};
#endif
/*=========================================================================
Program: Visualization Toolkit
Module: vtkArrayIteratorIncludes.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 vtkArrayIteratorIncludes - centralize array iterator type includes
// required when using the vtkArrayIteratorTemplateMacro.
// .SECTION Description
// A CXX file using vtkArrayIteratorTemplateMacro needs to include the
// header files for all types of iterators supported by the macro.
// As new arrays and new iterators are added, vtkArrayIteratorTemplateMacro
// will also need to be updated to switch to the additional cases. However,
// this would imply any code using the macro will start giving compilation errors
// unless they include the new iterator headers. The vtkArrayIteratorIncludes.h
// will streamline this issue. Every file using the vtkArrayIteratorTemplateMacro
// must include this vtkArrayIteratorIncludes.h. As new iterators are added and the
// vtkArrayIteratorTemplateMacro updated, one needs to update this header file alone.
#ifndef __vtkArrayIteratorIncludes_h
#define __vtkArrayIteratorIncludes_h
// Iterators.
#include "vtkArrayIteratorTemplate.h"
#include "vtkBitArrayIterator.h"
// DataTypes for Iterators.
#include "vtkStdString.h"
#endif
/*=========================================================================
Program: Visualization Toolkit
Module: vtkArrayIteratorTemplate.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 vtkArrayIteratorTemplate - Implementation template for a array iterator.
// .SECTION Description
// This is implementation template for a array iterator. It only works with
// arrays that have a contiguous internal storage of values (as in vtkDataArray,
// vtkStringArray).
#ifndef __vtkArrayIteratorTemplate_h
#define __vtkArrayIteratorTemplate_h
#include "vtkArrayIterator.h"
template <class T>
class VTK_COMMON_EXPORT vtkArrayIteratorTemplate : public vtkArrayIterator
{
public:
static vtkArrayIteratorTemplate<T>* New();
vtkTypeRevisionMacro(vtkArrayIteratorTemplate, vtkArrayIterator);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Set the array this iterator will iterate over.
// After Initialize() has been called, the iterator is valid
// so long as the Array has not been modified
// (except using the iterator itself).
// If the array is modified, the iterator must be re-intialized.
virtual void Initialize(vtkAbstractArray* array);
// Description:
// Get the array.
vtkAbstractArray* GetArray(){ return this->Array; }
// Description:
// Must be called only after Initialize.
T* GetTuple(vtkIdType id);
// Description:
// Must be called only after Initialize.
T& GetValue(vtkIdType id)
{ return this->Pointer[id]; }
// Description:
// Must be called only after Initialize.
vtkIdType GetNumberOfTuples();
// Description:
// Must be called only after Initialize.
vtkIdType GetNumberOfValues();
// Description:
// Must be called only after Initialize.
int GetNumberOfComponents();
// Description:
// Get the data type from the underlying array.
int GetDataType();
// Description:
// Get the data type size from the underlying array.
int GetDataTypeSize();
// Description:
// This is the data type for the value.
typedef T ValueType;
protected:
vtkArrayIteratorTemplate();
~vtkArrayIteratorTemplate();
T* Pointer;
private:
vtkArrayIteratorTemplate(const vtkArrayIteratorTemplate&); // Not implemented.
void operator=(const vtkArrayIteratorTemplate&); // Not implemented.
void SetArray(vtkAbstractArray*);
vtkAbstractArray* Array;
};
#if !defined(VTK_NO_EXPLICIT_TEMPLATE_INSTANTIATION)
# define VTK_ARRAY_ITERATOR_TEMPLATE_INSTANTIATE(T) \
template class VTK_COMMON_EXPORT vtkArrayIteratorTemplate< T >
#else
# include "vtkArrayIteratorTemplateImplicit.txx" // needed for templates.
# define VTK_ARRAY_ITERATOR_TEMPLATE_INSTANTIATE(T)
#endif // !defined(VTK_NO_EXPLICIT_TEMPLATE_INSTANTIATION)
#endif // !defined(__vtkArrayIteratorTemplate_h)
// This portion must be OUTSIDE the include blockers. Each
// vtkArrayIteratorTemplate subclass uses this to give its instantiation of this
// template a DLL interface.
#if defined(VTK_ARRAY_ITERATOR_TEMPLATE_TYPE)
# if defined(VTK_BUILD_SHARED_LIBS) && defined(_MSC_VER)
# pragma warning (push)
# pragma warning (disable: 4091) // warning C4091: 'extern ' :
// ignored on left of 'int' when no variable is declared
# pragma warning (disable: 4231) // Compiler-specific extension warning.
// Use an "extern explicit instantiation" to give the class a DLL
// interface. This is a compiler-specific extension.
extern VTK_ARRAY_ITERATOR_TEMPLATE_INSTANTIATE(VTK_ARRAY_ITERATOR_TEMPLATE_TYPE);
# pragma warning (pop)
# endif
# undef VTK_ARRAY_ITERATOR_TEMPLATE_TYPE
#endif