/*========================================================================= 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; iSetInputField(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 void vtkSplitFieldCopyTuples(T* input, T* output, vtkIdType numTuples, int numComp, int component) { for (int i=0; i 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; iSetComponent(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); }