Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

415 lines
9.7 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkSplitField.cxx,v $
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 "vtkSplitField.h"
#include "vtkCellData.h"
#include "vtkDataSet.h"
#include "vtkDataSetAttributes.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
vtkCxxRevisionMacro(vtkSplitField, "$Revision: 1.18 $");
vtkStandardNewMacro(vtkSplitField);
char vtkSplitField::FieldLocationNames[3][12]
= { "DATA_OBJECT",
"POINT_DATA",
"CELL_DATA" };
char vtkSplitField::AttributeNames[vtkDataSetAttributes::NUM_ATTRIBUTES][10]
= { "SCALARS",
"VECTORS",
"NORMALS",
"TCOORDS",
"TENSORS" };
typedef vtkSplitField::Component Component;
vtkSplitField::vtkSplitField()
{
this->FieldName = 0;
this->FieldLocation = -1;
this->AttributeType = -1;
this->FieldType = -1;
this->Head = 0;
this->Tail = 0;
}
vtkSplitField::~vtkSplitField()
{
delete[] this->FieldName;
this->FieldName = 0;
this->DeleteAllComponents();
}
void vtkSplitField::SetInputField(const char* name, int fieldLoc)
{
if (!name)
{
return;
}
if ( (fieldLoc != vtkSplitField::DATA_OBJECT) &&
(fieldLoc != vtkSplitField::POINT_DATA) &&
(fieldLoc != vtkSplitField::CELL_DATA) )
{
vtkErrorMacro("The source for the field is wrong.");
return;
}
this->Modified();
this->FieldLocation = fieldLoc;
this->FieldType = vtkSplitField::NAME;
delete[] this->FieldName;
this->FieldName = new char[strlen(name)+1];
strcpy(this->FieldName, name);
}
void vtkSplitField::SetInputField(int attributeType, int fieldLoc)
{
if ( (fieldLoc != vtkSplitField::POINT_DATA) &&
(fieldLoc != vtkSplitField::CELL_DATA) )
{
vtkErrorMacro("The source for the field is wrong.");
return;
}
this->Modified();
this->FieldLocation = fieldLoc;
this->FieldType = vtkSplitField::ATTRIBUTE;
this->AttributeType = attributeType;
}
void vtkSplitField::SetInputField(const char* name,
const char* fieldLoc)
{
if ( !name || !fieldLoc)
{
return;
}
int numAttr = vtkDataSetAttributes::NUM_ATTRIBUTES;
int numFieldLocs = 3;
int i;
// Convert strings to ints and call the appropriate SetInputField()
int attrType=-1;
for(i=0; i<numAttr; i++)
{
if (!strcmp(name, AttributeNames[i]))
{
attrType = i;
break;
}
}
int loc=-1;
for(i=0; i<numFieldLocs; i++)
{
if (!strcmp(fieldLoc, FieldLocationNames[i]))
{
loc = i;
break;
}
}
if (loc == -1)
{
vtkErrorMacro("Location for the field is invalid.");
return;
}
if (attrType == -1)
{
this->SetInputField(name, loc);
}
else
{
this->SetInputField(attrType, loc);
}
}
void vtkSplitField::Split(int component, const char* arrayName)
{
if (!arrayName)
{
return;
}
this->Modified();
Component* comp = this->FindComponent(component);
// If component is already there, just reset the information
if ( comp )
{
comp->SetName(arrayName);
}
// otherwise add a new one
else
{
comp = new Component;
comp->SetName(arrayName);
comp->Index = component;
this->AddComponent(comp);
}
}
int vtkSplitField::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
// get the info objects
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
vtkInformation *outInfo = outputVector->GetInformationObject(0);
// get the input and ouptut
vtkDataSet *input = vtkDataSet::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkDataSet *output = vtkDataSet::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
// This has to be here because it initialized all field datas.
output->CopyStructure( input );
// Pass all. (data object's field data is passed by the
// superclass after this method)
output->GetPointData()->PassData( input->GetPointData() );
output->GetCellData()->PassData( input->GetCellData() );
vtkDataArray* outputArray;
vtkDataArray* inputArray = 0;
vtkFieldData* fd = 0;
vtkFieldData* outputFD = 0;
Component* cur = this->GetFirst();
Component* before;
if (!cur) { return 1; }
// find the input and output field data
if ( this->FieldLocation == vtkSplitField::DATA_OBJECT)
{
fd = input->GetFieldData();
outputFD = output->GetFieldData();
if (!fd || !outputFD)
{
vtkErrorMacro("No field data in vtkDataObject.");
return 1;
}
}
else if ( this->FieldLocation == vtkSplitField::POINT_DATA )
{
fd = input->GetPointData();
outputFD = output->GetPointData();
}
else if ( this->FieldLocation == vtkSplitField::CELL_DATA )
{
fd = input->GetCellData();
outputFD = output->GetCellData();
}
if ( this->FieldType == vtkSplitField::NAME )
{
inputArray = fd->GetArray(this->FieldName);
}
else if ( this->FieldType == vtkSplitField::ATTRIBUTE )
{
// If we are working with attributes, we also need to have
// access to vtkDataSetAttributes methods.
vtkDataSetAttributes* dsa=vtkDataSetAttributes::SafeDownCast(fd);
if (!dsa)
{
vtkErrorMacro("Sanity check failed, returning.");
return 1;
}
inputArray = dsa->GetAttribute(this->AttributeType);
}
if (!inputArray)
{
vtkErrorMacro("Sanity check failed, returning.");
return 1;
}
// iterate over all components in the linked list and
// generate them
do
{
before = cur;
cur = cur->Next;
if (before->FieldName)
{
outputArray = this->SplitArray(inputArray, before->Index);
if (outputArray)
{
outputArray->SetName(before->FieldName);
outputFD->AddArray(outputArray);
outputArray->UnRegister(this);
}
}
}
while (cur);
return 1;
}
// fast pointer copy
template <class T>
void vtkSplitFieldCopyTuples(T* input, T* output, vtkIdType numTuples,
int numComp, int component)
{
for (int i=0; i<numTuples; i++)
{
output[i] = input[numComp*i+component];
}
}
vtkDataArray* vtkSplitField::SplitArray(vtkDataArray* da, int component)
{
if ( (component < 0) || (component > da->GetNumberOfComponents()) )
{
vtkErrorMacro("Invalid component. Can not split");
return 0;
}
vtkDataArray* output = da->NewInstance();
output->SetNumberOfComponents(1);
int numTuples = da->GetNumberOfTuples();
output->SetNumberOfTuples(numTuples);
if ( numTuples > 0 )
{
switch (output->GetDataType())
{
vtkTemplateMacro(
vtkSplitFieldCopyTuples((VTK_TT *)da->GetVoidPointer(0),
(VTK_TT *)output->GetVoidPointer(0),
numTuples,
da->GetNumberOfComponents(),
component));
// This is not supported by the template macro.
// Switch to using the float interface.
case VTK_BIT:
{
for(int i=0; i<numTuples; i++)
{
output->SetComponent(i, 0, da->GetComponent(i, component));
}
}
break;
default:
vtkErrorMacro(<<"Sanity check failed: Unsupported data type.");
return 0;
}
}
return output;
}
// Linked list methods
void vtkSplitField::AddComponent(Component* op)
{
op->Next = 0;
if (!this->Head)
{
this->Head = op;
this->Tail = op;
return;
}
this->Tail->Next = op;
this->Tail = op;
}
Component* vtkSplitField::FindComponent(int index)
{
Component* cur = this->GetFirst();
if (!cur) { return 0; }
if (cur->Index == index) { return cur; }
while (cur->Next)
{
if (cur->Next->Index == index)
{
return cur->Next;
}
cur = cur->Next;
}
return 0;
}
void vtkSplitField::DeleteAllComponents()
{
Component* cur = this->GetFirst();
if (!cur) {return;}
Component* before;
do
{
before = cur;
cur = cur->Next;
delete before;
}
while (cur);
this->Head = 0;
this->Tail = 0;
}
void vtkSplitField::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Field name: ";
if (this->FieldName)
{
os << this->FieldName << endl;
}
else
{
os << "(none)" << endl;
}
os << indent << "Field type: " << this->FieldType << endl;
os << indent << "Attribute type: " << this->AttributeType << endl;
os << indent << "Field location: " << this->FieldLocation << endl;
os << indent << "Linked list head: " << this->Head << endl;
os << indent << "Linked list tail: " << this->Tail << endl;
os << indent << "Components: " << endl;
this->PrintAllComponents(os, indent.GetNextIndent());
}
void vtkSplitField::PrintComponent(Component* op, ostream& os,
vtkIndent indent)
{
os << indent << "Field name: " << op->FieldName << endl;
os << indent << "Component index: " << op->Index << endl;
}
void vtkSplitField::PrintAllComponents(ostream& os, vtkIndent indent)
{
Component* cur = this->GetFirst();
if (!cur) { return; }
Component* before;
do
{
before = cur;
cur = cur->Next;
os << endl;
this->PrintComponent(before, os, indent);
}
while (cur);
}