/*========================================================================= Program: Visualization Toolkit Module: vtkTransferAttributes.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. =========================================================================*/ /*------------------------------------------------------------------------- Copyright 2008 Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. -------------------------------------------------------------------------*/ #include "vtkTransferAttributes.h" #include "vtkCellArray.h" #include "vtkCellData.h" #include "vtkDataObject.h" #include "vtkDataSet.h" #include "vtkEdgeListIterator.h" #include "vtkFloatArray.h" #include "vtkGraph.h" #include "vtkIdTypeArray.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkIntArray.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkSmartPointer.h" #include "vtkStdString.h" #include "vtkTable.h" #include "vtkTree.h" #include "vtkVariantArray.h" #include //------------------------------------------------------------------------------ template vtkVariant vtkGetValue(T* arr, vtkIdType index) { return vtkVariant(arr[index]); } //------------------------------------------------------------------------------ static vtkVariant vtkGetVariantValue(vtkAbstractArray* arr, vtkIdType i) { vtkVariant val; switch (arr->GetDataType()) { vtkExtraExtendedTemplateMacro( val = vtkGetValue(static_cast(arr->GetVoidPointer(0)), i)); } return val; } vtkStandardNewMacro(vtkTransferAttributes); vtkTransferAttributes::vtkTransferAttributes() { this->SetNumberOfInputPorts(2); this->DirectMapping = false; this->DefaultValue = 1; this->SourceArrayName = nullptr; this->TargetArrayName = nullptr; this->SourceFieldType = vtkDataObject::FIELD_ASSOCIATION_POINTS; this->TargetFieldType = vtkDataObject::FIELD_ASSOCIATION_POINTS; } vtkTransferAttributes::~vtkTransferAttributes() { this->SetSourceArrayName(nullptr); this->SetTargetArrayName(nullptr); } int vtkTransferAttributes::FillInputPortInformation(int port, vtkInformation* info) { if (port == 0) { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataObject"); return 1; } else if (port == 1) { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataObject"); return 1; } return 0; } int vtkTransferAttributes::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector) { // get the info objects vtkInformation* targetInfo = inputVector[0]->GetInformationObject(0); vtkInformation* sourceInfo = inputVector[1]->GetInformationObject(0); vtkInformation* outInfo = outputVector->GetInformationObject(0); vtkDataObject* sourceInput = sourceInfo->Get(vtkDataObject::DATA_OBJECT()); vtkDataObject* targetInput = targetInfo->Get(vtkDataObject::DATA_OBJECT()); vtkDataObject* output = outInfo->Get(vtkDataObject::DATA_OBJECT()); output->ShallowCopy(targetInput); // get the input and output int item_count_source = 0; vtkDataSetAttributes* dsa_source = nullptr; if (vtkDataSet::SafeDownCast(sourceInput) && this->SourceFieldType == vtkDataObject::FIELD_ASSOCIATION_POINTS) { dsa_source = vtkDataSet::SafeDownCast(sourceInput)->GetPointData(); item_count_source = vtkDataSet::SafeDownCast(sourceInput)->GetNumberOfPoints(); } else if (vtkDataSet::SafeDownCast(sourceInput) && this->SourceFieldType == vtkDataObject::FIELD_ASSOCIATION_CELLS) { dsa_source = vtkDataSet::SafeDownCast(sourceInput)->GetCellData(); item_count_source = vtkDataSet::SafeDownCast(sourceInput)->GetNumberOfCells(); } else if (vtkGraph::SafeDownCast(sourceInput) && this->SourceFieldType == vtkDataObject::FIELD_ASSOCIATION_VERTICES) { dsa_source = vtkGraph::SafeDownCast(sourceInput)->GetVertexData(); item_count_source = vtkGraph::SafeDownCast(sourceInput)->GetNumberOfVertices(); } else if (vtkGraph::SafeDownCast(sourceInput) && this->SourceFieldType == vtkDataObject::FIELD_ASSOCIATION_EDGES) { dsa_source = vtkGraph::SafeDownCast(sourceInput)->GetEdgeData(); item_count_source = vtkGraph::SafeDownCast(sourceInput)->GetNumberOfEdges(); } else if (vtkTable::SafeDownCast(sourceInput) && this->SourceFieldType == vtkDataObject::FIELD_ASSOCIATION_ROWS) { dsa_source = vtkTable::SafeDownCast(sourceInput)->GetRowData(); item_count_source = vtkTable::SafeDownCast(sourceInput)->GetNumberOfRows(); } else { // ERROR vtkErrorMacro("Input type must be specified as a dataset, graph or table."); return 0; } vtkDataSetAttributes* dsa_target = nullptr; vtkDataSetAttributes* dsa_out = nullptr; int item_count_target = 0; if (vtkDataSet::SafeDownCast(targetInput) && this->TargetFieldType == vtkDataObject::FIELD_ASSOCIATION_POINTS) { dsa_target = vtkDataSet::SafeDownCast(targetInput)->GetPointData(); dsa_out = vtkDataSet::SafeDownCast(output)->GetPointData(); item_count_target = vtkDataSet::SafeDownCast(targetInput)->GetNumberOfPoints(); } else if (vtkDataSet::SafeDownCast(targetInput) && this->TargetFieldType == vtkDataObject::FIELD_ASSOCIATION_CELLS) { dsa_target = vtkDataSet::SafeDownCast(targetInput)->GetCellData(); dsa_out = vtkDataSet::SafeDownCast(output)->GetCellData(); item_count_target = vtkDataSet::SafeDownCast(targetInput)->GetNumberOfCells(); } else if (vtkGraph::SafeDownCast(targetInput) && this->TargetFieldType == vtkDataObject::FIELD_ASSOCIATION_VERTICES) { dsa_target = vtkGraph::SafeDownCast(targetInput)->GetVertexData(); dsa_out = vtkGraph::SafeDownCast(output)->GetVertexData(); item_count_target = vtkGraph::SafeDownCast(targetInput)->GetNumberOfVertices(); } else if (vtkGraph::SafeDownCast(targetInput) && this->TargetFieldType == vtkDataObject::FIELD_ASSOCIATION_EDGES) { dsa_target = vtkGraph::SafeDownCast(targetInput)->GetEdgeData(); dsa_out = vtkGraph::SafeDownCast(output)->GetEdgeData(); item_count_target = vtkGraph::SafeDownCast(targetInput)->GetNumberOfEdges(); } else if (vtkTable::SafeDownCast(targetInput) && this->TargetFieldType == vtkDataObject::FIELD_ASSOCIATION_ROWS) { dsa_target = vtkTable::SafeDownCast(targetInput)->GetRowData(); dsa_out = vtkTable::SafeDownCast(output)->GetRowData(); item_count_target = vtkTable::SafeDownCast(targetInput)->GetNumberOfRows(); } else { // ERROR vtkErrorMacro("Input type must be specified as a dataset, graph or table."); return 0; } if (this->SourceArrayName == nullptr || this->TargetArrayName == nullptr) { vtkErrorMacro("Must specify source and target array names for the transfer."); return 0; } vtkAbstractArray* sourceIdArray = dsa_source->GetPedigreeIds(); vtkAbstractArray* targetIdArray = dsa_target->GetPedigreeIds(); // Check for valid pedigree id arrays. if (!sourceIdArray) { vtkErrorMacro("SourceInput pedigree id array not found."); return 0; } if (!targetIdArray) { vtkErrorMacro("TargetInput pedigree id array not found."); return 0; } if (item_count_source != sourceIdArray->GetNumberOfTuples()) { vtkErrorMacro( "The number of pedigree ids must be equal to the number of items in the source data object."); return 0; } if (item_count_target != targetIdArray->GetNumberOfTuples()) { vtkErrorMacro( "The number of pedigree ids must be equal to the number of items in the target data object."); return 0; } // Create a map from sourceInput indices to targetInput indices // If we are using DirectMapping this is trivial // we just create an identity map int i; std::map sourceIndexToTargetIndex; if (this->DirectMapping) { if (sourceIdArray->GetNumberOfTuples() > targetIdArray->GetNumberOfTuples()) { vtkErrorMacro( "Cannot have more sourceInput tuples than targetInput values using direct mapping."); return 0; } // Create identity map. for (i = 0; i < sourceIdArray->GetNumberOfTuples(); i++) { sourceIndexToTargetIndex[i] = i; } } // Okay if we do not have direct mapping then we need // to do some templated madness to go from an arbitrary // type to a nice vtkIdType to vtkIdType mapping if (!this->DirectMapping) { std::map sourceInputIdMap; // Create a map from sourceInput id to sourceInput index for (i = 0; i < sourceIdArray->GetNumberOfTuples(); i++) { sourceInputIdMap[vtkGetVariantValue(sourceIdArray, i)] = i; } // Now create the map from sourceInput index to targetInput index for (i = 0; i < targetIdArray->GetNumberOfTuples(); i++) { vtkVariant id = vtkGetVariantValue(targetIdArray, i); if (sourceInputIdMap.count(id)) { sourceIndexToTargetIndex[sourceInputIdMap[id]] = i; } } } vtkAbstractArray* sourceArray = dsa_source->GetAbstractArray(this->SourceArrayName); vtkAbstractArray* targetArray = vtkAbstractArray::CreateArray(sourceArray->GetDataType()); targetArray->SetName(this->TargetArrayName); targetArray->SetNumberOfComponents(sourceArray->GetNumberOfComponents()); targetArray->SetNumberOfTuples(targetIdArray->GetNumberOfTuples()); for (i = 0; i < targetArray->GetNumberOfTuples(); i++) { targetArray->InsertVariantValue(i, this->DefaultValue); } for (i = 0; i < sourceArray->GetNumberOfTuples(); i++) { if (sourceArray->GetVariantValue(i) < 0) { cout << sourceIndexToTargetIndex[i] << " " << sourceArray->GetVariantValue(i).ToString() << " " << sourceArray->GetNumberOfTuples() << " " << sourceIdArray->GetNumberOfTuples() << " " << i << endl; vtkErrorMacro("Bad value..."); continue; } targetArray->SetTuple(sourceIndexToTargetIndex[i], i, sourceArray); } dsa_out->AddArray(targetArray); targetArray->Delete(); return 1; } vtkVariant vtkTransferAttributes::GetDefaultValue() { return this->DefaultValue; } void vtkTransferAttributes::SetDefaultValue(vtkVariant value) { this->DefaultValue = value; } void vtkTransferAttributes::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "DirectMapping: " << this->DirectMapping << endl; os << indent << "DefaultValue: " << this->DefaultValue.ToString() << endl; os << indent << "SourceArrayName: " << (this->SourceArrayName ? this->SourceArrayName : "(none)") << endl; os << indent << "TargetArrayName: " << (this->TargetArrayName ? this->TargetArrayName : "(none)") << endl; os << indent << "SourceFieldType: " << this->SourceFieldType << endl; os << indent << "TargetFieldType: " << this->TargetFieldType << endl; }