Commit 3632f9ac authored by Robert Maynard's avatar Robert Maynard
Browse files

ENH: vtkAbstractArray and all children now have the ability to have named...

ENH: vtkAbstractArray and all children now have the ability to have named components. Also added support for these custom component names to the Calculator, ColorBar and PV XML datasets.
parent b1a84e34
......@@ -12,6 +12,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx
TestConditionVariable.cxx
TestGarbageCollector.cxx
TestDataArray.cxx
TestDataArrayComponentNames.cxx
TestDirectory.cxx
TestFastNumericConversion.cxx
TestMath.cxx
......
#include "vtkIntArray.h"
#include "vtkDoubleArray.h"
int TestDataArrayComponentNames(int,char *[])
{
vtkIntArray* array = vtkIntArray::New();
array->SetNumberOfComponents( 2 );
array->SetComponentName(0, "x" );
array->SetComponentName(1, "y" );
if ( strcmp(array->GetComponentName(0),"x") != 0 || strcmp(array->GetComponentName(1),"y") != 0 )
{
cerr
<< "Unable to store component names correctly";
array->Delete();
return 1;
}
if ( array->GetComponentName(-1) != NULL || array->GetComponentName(3) != NULL )
{
cerr
<< " Unable to return NULL when asking for a component name outside the the valid range";
array->Delete();
return 1;
}
//rename to a different string length
array->SetComponentName(0, "a really long component name" );
if ( strcmp(array->GetComponentName(0),"a really long component name") != 0 )
{
cerr
<< "Unable to rename the component name to a string of a different length";
array->Delete();
return 1;
}
array->Delete();
vtkDoubleArray* farray = vtkDoubleArray::New();
farray->SetComponentName(2,"z");
farray->SetComponentName(1,"y");
farray->SetComponentName(0,"x");
farray->SetNumberOfComponents(3);
for ( int i = 0; i < 10; i ++ )
{
farray->InsertNextTuple3( i + 0.1, i + 0.2, i + 0.3);
}
if ( strcmp(farray->GetComponentName(0),"x") != 0 ||
strcmp(farray->GetComponentName(1),"y") != 0 ||
strcmp(farray->GetComponentName(2),"z") != 0 )
{
cerr
<< "Unable to store component names correctly";
farray->Delete();
return 1;
}
//rename the components
farray->SetComponentName(0,"a");
farray->SetComponentName(1,"b");
farray->SetComponentName(2,"c");
if ( strcmp(farray->GetComponentName(0),"a") != 0 ||
strcmp(farray->GetComponentName(1),"b") != 0 ||
strcmp(farray->GetComponentName(2),"c") != 0 )
{
cerr
<< "Unable to rename component names correctly";
farray->Delete();
return 1;
}
//test edge cases
farray->SetComponentName(-1, "invalid" );
//Test Down cast
vtkDoubleArray *downcast = vtkDoubleArray::SafeDownCast( farray );
if ( strcmp(downcast->GetComponentName(0),"a") != 0||
strcmp(downcast->GetComponentName(1),"b") != 0||
strcmp(downcast->GetComponentName(2),"c") != 0)
{
cerr
<< "Unable to safe down cast";
farray->Delete();
return 1;
}
//DeepCopy
vtkDoubleArray *deepCopy = vtkDoubleArray::New();
deepCopy->SetComponentName(3,"s1");
deepCopy->SetComponentName(2,"z");
deepCopy->SetComponentName(1,"y");
deepCopy->SetComponentName(0,"x");
deepCopy->DeepCopy( farray );
if ( strcmp(deepCopy->GetComponentName(0),"a") != 0||
strcmp(deepCopy->GetComponentName(1),"b") != 0||
strcmp(deepCopy->GetComponentName(2),"c") != 0)
{
cerr
<< "Deep Copy failed to overwrite old component names";
deepCopy->Delete();
downcast->Delete();
return 1;
}
if ( deepCopy->GetComponentName(3) != NULL )
{
cerr
<< "Deep Copy failed to return null for a invalid component name";
deepCopy->Delete();
downcast->Delete();
return 1;
}
downcast->Delete();
//test to make sure that the deep copy still has valid strings
if ( strcmp(deepCopy->GetComponentName(0),"a") != 0||
strcmp(deepCopy->GetComponentName(1),"b") != 0||
strcmp(deepCopy->GetComponentName(2),"c") != 0)
{
cerr
<< "Deep copy failed to copy component names, instead it made shallow copies";
deepCopy->Delete();
return 1;
}
deepCopy->Delete();
//DeepCopy test 2 with NULL values
farray = vtkDoubleArray::New();
farray->SetNumberOfComponents(20);
deepCopy = vtkDoubleArray::New();
deepCopy->DeepCopy( farray );
if ( deepCopy->GetComponentName(0) != NULL )
{
cerr
<< "Failed to deep copy with no names on the components";
return 1;
}
deepCopy->Delete();
farray->Delete();
return 0;
}
......@@ -45,7 +45,10 @@
# endif
#endif
vtkCxxRevisionMacro(vtkAbstractArray, "1.17");
typedef vtkstd::vector< vtkStdString* > vtkComponentNameBase;
class vtkComponentNames : public vtkComponentNameBase {};
vtkCxxRevisionMacro(vtkAbstractArray, "1.18");
//----------------------------------------------------------------------------
// Construct object with sane defaults.
......@@ -53,18 +56,83 @@ vtkAbstractArray::vtkAbstractArray(vtkIdType vtkNotUsed(numComp))
{
this->Size = 0;
this->MaxId = -1;
this->NumberOfComponents = 1;
this->NumberOfComponents = 1;
this->Name = NULL;
this->Information = NULL;
this->ComponentNames = NULL;
}
//----------------------------------------------------------------------------
vtkAbstractArray::~vtkAbstractArray()
{
if ( this->ComponentNames )
{
this->ComponentNames->clear();
delete this->ComponentNames;
this->ComponentNames = NULL;
}
this->SetName(NULL);
this->SetInformation(NULL);
}
//----------------------------------------------------------------------------
void vtkAbstractArray::SetComponentName( int component, const char *name )
{
if ( component < 0 || name == NULL )
{
return;
}
if ( this->ComponentNames == NULL )
{
//delayed allocate
this->ComponentNames = new vtkComponentNames();
}
if ( component == this->ComponentNames->size() )
{
//the array isn't large enough, so we will resize
this->ComponentNames->push_back( new vtkStdString(name) );
return;
}
else if ( component > this->ComponentNames->size() )
{
this->ComponentNames->resize( component+1, NULL );
}
//replace an exisiting element
vtkStdString *compName = this->ComponentNames->at(component);
if ( !compName )
{
compName = new vtkStdString(name);
this->ComponentNames->at(component) = compName;
}
else
{
compName->assign( name );
}
}
//----------------------------------------------------------------------------
const char* vtkAbstractArray::GetComponentName( int component )
{
if ( !this->ComponentNames || component < 0 ||
component >= this->ComponentNames->size() )
{
//make sure we have valid vector
return NULL;
}
vtkStdString *compName = this->ComponentNames->at( component );
return ( compName ) ? compName->c_str() : NULL;
}
//----------------------------------------------------------------------------
bool vtkAbstractArray::HasAComponentName()
{
return (this->ComponentNames) ? ( this->ComponentNames->size() > 0 ) : 0;
}
//----------------------------------------------------------------------------
void vtkAbstractArray::SetInformation(vtkInformation *args)
{
......@@ -127,6 +195,28 @@ void vtkAbstractArray::DeepCopy( vtkAbstractArray* da )
{
this->CopyInformation(da->GetInformation(),/*deep=*/1);
}
if ( da && da != this && da->ComponentNames )
{
//clear the vector of the all data
if ( this->ComponentNames )
{
this->ComponentNames->clear();
delete this->ComponentNames;
}
//copy the passed in components
this->ComponentNames = new vtkComponentNames();
this->ComponentNames->reserve( da->ComponentNames->size() );
const char *name;
for ( vtkIdType i = 0; i < da->ComponentNames->size(); ++i )
{
name = da->GetComponentName(i);
if ( name )
{
this->SetComponentName(i, name);
}
}
}
}
//----------------------------------------------------------------------------
......@@ -307,6 +397,15 @@ void vtkAbstractArray::PrintSelf(ostream& os, vtkIndent indent)
os << indent << "Size: " << this->Size << "\n";
os << indent << "MaxId: " << this->MaxId << "\n";
os << indent << "NumberOfComponents: " << this->NumberOfComponents << endl;
if ( this->ComponentNames )
{
os << indent << "ComponentNames: " << endl;
vtkIndent nextIndent = indent.GetNextIndent();
for ( int i=0; i < this->ComponentNames->size(); ++i )
{
os << nextIndent << i << " : " << this->ComponentNames->at(i) << endl;
}
}
os << indent << "Information: " << this->Information << endl;
if ( this->Information )
{
......
......@@ -49,6 +49,7 @@ class vtkDataArray;
class vtkIdList;
class vtkIdTypeArray;
class vtkInformation;
class vtkComponentNames;
class VTK_COMMON_EXPORT vtkAbstractArray : public vtkObject
{
......@@ -91,6 +92,19 @@ public:
vtkSetClampMacro(NumberOfComponents, int, 1, VTK_LARGE_INTEGER);
int GetNumberOfComponents() { return this->NumberOfComponents; }
// Description:
// Set the name for a component. Must be >= 1.
void SetComponentName( int component, const char *name );
//Description:
// Get the component name for a given component.
// Note: will return the actual string that is stored
const char* GetComponentName( int component );
// Description:
// Returns if any component has had a name assigned
bool HasAComponentName();
// Description:
// Set the number of tuples (a component group) in the array. Note that
// this may allocate space depending on the number of components.
......@@ -339,6 +353,8 @@ protected:
vtkInformation* Information;
vtkComponentNames* ComponentNames; //names for each component
private:
vtkAbstractArray(const vtkAbstractArray&); // Not implemented.
void operator=(const vtkAbstractArray&); // Not implemented.
......
......@@ -18,9 +18,9 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx
TestInterpolationDerivs.cxx
TestImageIterator.cxx
TestGenericCell.cxx
TestHigherOrderCell.cxx
TestHigherOrderCell.cxx
TestPointLocators.cxx
TestPolyDataRemoveCell.cxx
TestPolyDataRemoveCell.cxx
TestTriangle.cxx
TestPolygon.cxx
EXTRA_INCLUDE vtkTestDriver.h
......
......@@ -33,7 +33,10 @@
#include <vtkstd/vector>
vtkCxxRevisionMacro(vtkDataSetAttributes, "1.34");
typedef vtkstd::vector< vtkStdString* > vtkComponentNameBase;
class vtkComponentNames : public vtkComponentNameBase {};
vtkCxxRevisionMacro(vtkDataSetAttributes, "1.35");
vtkStandardNewMacro(vtkDataSetAttributes);
//--------------------------------------------------------------------------
......@@ -619,6 +622,19 @@ void vtkDataSetAttributes::InternalCopyAllocate(vtkDataSetAttributes* pd,
{
newAA = aa->NewInstance();
newAA->SetNumberOfComponents(aa->GetNumberOfComponents());
//set the component names
if ( aa->HasAComponentName() )
{
const char *name;
for ( vtkIdType i = 0; i < newAA->GetNumberOfComponents(); ++i)
{
name = aa->GetComponentName(i);
if ( name )
{
newAA->SetComponentName(i, name );
}
}
}
newAA->SetName(aa->GetName());
if (aa->HasInformation())
{
......@@ -1477,7 +1493,8 @@ void vtkDataSetAttributes::InternalCopyAllocate(
{
vtkAbstractArray* newAA=0;
vtkDataArray* newDA=0;
int i;
vtkStdString *compName;
int i,j;
// Allocate attributes if any
for (i=0; i < list.NumberOfFields; i++)
......@@ -1487,6 +1504,18 @@ void vtkDataSetAttributes::InternalCopyAllocate(
newAA = vtkAbstractArray::CreateArray(list.FieldTypes[i]);
newAA->SetName(list.Fields[i]);
newAA->SetNumberOfComponents(list.FieldComponents[i]);
if ( list.FieldComponentsNames[i] )
{
for ( j=0; j < list.FieldComponentsNames[i]->size(); ++j)
{
compName = list.FieldComponentsNames[i]->at(j);
if ( compName )
{
newAA->SetComponentName( j, compName->c_str() );
}
}
}
if (list.FieldInformation[i])
{
newAA->CopyInformation(list.FieldInformation[i],/*deep=*/1);
......@@ -1615,6 +1644,7 @@ vtkDataSetAttributes::FieldList::FieldList(int numInputs)
this->Fields = 0;
this->FieldTypes = 0;
this->FieldComponents = 0;
this->FieldComponentsNames = 0;
this->FieldIndices = 0;
this->NumberOfFields = 0;
this->LUT = 0;
......@@ -1656,6 +1686,7 @@ void vtkDataSetAttributes::FieldList::InitializeFieldList(
this->Fields = new char*[this->NumberOfFields];
this->FieldTypes = new int [this->NumberOfFields];
this->FieldComponents = new int [this->NumberOfFields];
this->FieldComponentsNames = new vtkComponentNames*[ this->NumberOfFields ];
this->FieldIndices = new int [this->NumberOfFields];
this->LUT = new vtkLookupTable* [this->NumberOfFields];
this->FieldInformation = new vtkInformation* [this->NumberOfFields];
......@@ -1664,6 +1695,7 @@ void vtkDataSetAttributes::FieldList::InitializeFieldList(
this->Fields[i] = 0;
this->FieldTypes[i] = -1;
this->FieldComponents[i] = 0;
this->FieldComponentsNames[i] = 0;
this->FieldIndices[i] = -1;
this->LUT[i] = 0;
this->FieldInformation[i] = 0;
......@@ -1739,6 +1771,7 @@ void vtkDataSetAttributes::FieldList::UnionFieldList(vtkDataSetAttributes* dsa)
this->Fields[offset+NUM_ATTRIBUTES] = this->Fields[i];
this->FieldTypes[offset+NUM_ATTRIBUTES] = this->FieldTypes[i];
this->FieldComponents[offset+NUM_ATTRIBUTES] = this->FieldComponents[i];
this->FieldComponentsNames[offset+NUM_ATTRIBUTES] = this->FieldComponentsNames[i];
this->LUT[offset+NUM_ATTRIBUTES] = this->LUT[i];
this->FieldInformation[offset+NUM_ATTRIBUTES] = this->FieldInformation[i];
......@@ -1746,6 +1779,7 @@ void vtkDataSetAttributes::FieldList::UnionFieldList(vtkDataSetAttributes* dsa)
this->Fields[i] = NULL;
this->FieldTypes[i] = -1;
this->FieldComponents[i] = 0;
this->FieldComponentsNames[i] = NULL;
this->LUT[i] = NULL;
this->FieldInformation[i] = NULL;
......@@ -1832,6 +1866,7 @@ void vtkDataSetAttributes::FieldList::GrowBy(unsigned int delta)
char** newFields = new char*[new_size];
int* newFieldTypes = new int[new_size];
int* newFieldComponents = new int [new_size];
vtkComponentNames** newFieldComponentsNames = new vtkComponentNames* [ new_size ];
int* newFieldIndices = new int [new_size];
vtkLookupTable** newLUT = new vtkLookupTable* [new_size];
vtkInformation** newFieldInformation = new vtkInformation* [new_size];
......@@ -1847,6 +1882,17 @@ void vtkDataSetAttributes::FieldList::GrowBy(unsigned int delta)
{
newFields[i] = NULL;
}
if ( this->FieldComponentsNames[i] )
{
for ( int j=0; j < this->FieldComponentsNames[i]->size(); ++j )
{
*newFieldComponentsNames[i]->at(j) = *this->FieldComponentsNames[i]->at(j);
}
}
else
{
this->FieldComponentsNames[i] = NULL;
}
}
memcpy(newFieldTypes, this->FieldTypes, sizeof(int)*old_size);
memcpy(newFieldComponents, this->FieldComponents, sizeof(int)*old_size);
......@@ -1895,6 +1941,7 @@ void vtkDataSetAttributes::FieldList::GrowBy(unsigned int delta)
this->Fields = newFields;
this->FieldTypes = newFieldTypes;
this->FieldComponents = newFieldComponents;
this->FieldComponentsNames = newFieldComponentsNames;
this->FieldIndices = newFieldIndices;
this->LUT = newLUT;
this->FieldInformation = newFieldInformation;
......@@ -2005,6 +2052,20 @@ void vtkDataSetAttributes::FieldList::ClearFields()
delete [] this->FieldComponents;
this->FieldComponents = 0;
if ( this->FieldComponentsNames )
{
for ( i=0; i < this->NumberOfFields; ++i )
{
if ( this->FieldComponentsNames[i] )
{
this->FieldComponentsNames[i]->clear();
delete this->FieldComponentsNames[i];
}
this->FieldComponentsNames[i] = 0;
}
this->FieldComponentsNames=0;
}
delete [] this->FieldIndices;
this->FieldIndices = 0;
......@@ -2035,8 +2096,36 @@ void vtkDataSetAttributes::FieldList::SetField(
}
// Store the data type
this->FieldTypes[index] = aa->GetDataType();
//we unallocate the names before we update the field components
//so we unallocate correctly
if ( !this->FieldComponentsNames[index] )
{
this->FieldComponentsNames[index] = new vtkComponentNames();
}
//delete the array of component names
this->FieldComponentsNames[index]->clear();
//store the components names
int numberOfComponents = aa->GetNumberOfComponents();
if ( aa->HasAComponentName() )
{
this->FieldComponentsNames[index]->resize( numberOfComponents, NULL );
const char *name;
for ( vtkIdType i=0; i < numberOfComponents; ++i)
{
name = aa->GetComponentName(i);
if ( name )
{
this->FieldComponentsNames[index]->at(i) = new vtkStdString(name);
}
}
}
// Store the components
this->FieldComponents[index] = aa->GetNumberOfComponents();
this->FieldComponents[index] = numberOfComponents;
// Store the lookup table
this->LUT[index]=0;
if (vtkDataArray::SafeDownCast(aa))
......@@ -2066,8 +2155,13 @@ void vtkDataSetAttributes::FieldList::RemoveField(const char *name)
{
delete [] this->Fields[i];
this->Fields[i] = 0;
this->FieldTypes[i] = -1;
this->FieldTypes[i] = -1;
this->FieldComponents[i] = 0;
this->FieldComponentsNames[i]->clear();
delete this->FieldComponentsNames[i];
this->FieldComponentsNames = 0;
this->FieldIndices[i] = -1;
this->LUT[i] = 0;
this->FieldInformation[i] = 0;
......
......@@ -642,11 +642,12 @@ public:
int NumberOfFields; //the number of fields (including five named attributes)
// These keep track of what is common across datasets. The first
// five items are always named attributes.
// six items are always named attributes.
char** Fields; // the names of the fields
int *FieldTypes; // the types of the fields
int *FieldComponents; // the number of components in field
int *FieldComponents; // the number of components in field
int *FieldIndices; // output data array index
vtkComponentNames **FieldComponentsNames; // the name for each component in the field
vtkLookupTable **LUT; // luts associated with each array
vtkInformation **FieldInformation; // Information map associated with each array
......@@ -660,6 +661,7 @@ public:
int **DSAIndices;
int NumberOfDSAIndices;
int CurrentInput;
};
//ETX
......
......@@ -25,6 +25,7 @@ IF (VTK_USE_RENDERING AND VTK_USE_DISPLAY)
TestHyperOctreeDual.cxx
TestHyperOctreeSurfaceFilter.cxx
TestHyperOctreeToUniformGrid.cxx
TestNamedComponents.cxx
TestPolyDataPointSampler.cxx
TestSelectEnclosedPoints.cxx
TestTessellatedBoxSource.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestNamedComponents.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 "vtkCellData.h"
#include "vtkIdTypeArray.h"
#include "vtkIntArray.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkSmartPointer.h"
#include "vtkThreshold.h"
#include "vtkUnstructuredGrid.h"