// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-FileCopyrightText: Copyright 2007 Sandia Corporation // SPDX-License-Identifier: LicenseRef-BSD-3-Clause-Sandia-USGov #include "vtkGenerateIndexArray.h" #include "vtkCellData.h" #include "vtkDataSet.h" #include "vtkDataSetAttributes.h" #include "vtkDemandDrivenPipeline.h" #include "vtkGraph.h" #include "vtkIdTypeArray.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkTable.h" #include VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkGenerateIndexArray); vtkGenerateIndexArray::vtkGenerateIndexArray() : ArrayName(nullptr) , FieldType(ROW_DATA) , ReferenceArrayName(nullptr) , PedigreeID(false) { this->SetArrayName("index"); } vtkGenerateIndexArray::~vtkGenerateIndexArray() { this->SetArrayName(nullptr); this->SetReferenceArrayName(nullptr); } void vtkGenerateIndexArray::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << "ArrayName: " << (this->ArrayName ? this->ArrayName : "(none)") << endl; os << "FieldType: " << this->FieldType << endl; os << "ReferenceArrayName: " << (this->ReferenceArrayName ? this->ReferenceArrayName : "(none)") << endl; os << "PedigreeID: " << this->PedigreeID << endl; } vtkTypeBool vtkGenerateIndexArray::ProcessRequest( vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector) { if (request->Has(vtkDemandDrivenPipeline::REQUEST_DATA_OBJECT())) { return this->RequestDataObject(request, inputVector, outputVector); } return this->Superclass::ProcessRequest(request, inputVector, outputVector); } int vtkGenerateIndexArray::RequestDataObject( vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector* outputVector) { vtkInformation* inInfo = inputVector[0]->GetInformationObject(0); if (!inInfo) { return 0; } vtkDataObject* input = inInfo->Get(vtkDataObject::DATA_OBJECT()); if (input) { // for each output for (int i = 0; i < this->GetNumberOfOutputPorts(); ++i) { vtkInformation* info = outputVector->GetInformationObject(i); vtkDataObject* output = info->Get(vtkDataObject::DATA_OBJECT()); if (!output || !output->IsA(input->GetClassName())) { vtkDataObject* newOutput = input->NewInstance(); info->Set(vtkDataObject::DATA_OBJECT(), newOutput); newOutput->Delete(); } } return 1; } return 0; } int vtkGenerateIndexArray::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector) { // An output array name is required ... if (!(this->ArrayName && strlen(this->ArrayName))) { vtkErrorMacro(<< "No array name defined."); return 0; } // Make a shallow-copy of our input ... vtkDataObject* const input = vtkDataObject::GetData(inputVector[0]); vtkDataObject* const output = vtkDataObject::GetData(outputVector); output->ShallowCopy(input); // Figure-out where we'll be reading/writing data ... vtkDataSetAttributes* output_attributes = nullptr; vtkIdType output_count = 0; switch (this->FieldType) { case ROW_DATA: { vtkTable* const table = vtkTable::SafeDownCast(output); output_attributes = table ? table->GetRowData() : nullptr; output_count = table ? table->GetNumberOfRows() : 0; break; } case POINT_DATA: { vtkDataSet* const data_set = vtkDataSet::SafeDownCast(output); output_attributes = data_set ? data_set->GetPointData() : nullptr; output_count = data_set ? data_set->GetNumberOfPoints() : 0; break; } case CELL_DATA: { vtkDataSet* const data_set = vtkDataSet::SafeDownCast(output); output_attributes = data_set ? data_set->GetCellData() : nullptr; output_count = data_set ? data_set->GetNumberOfCells() : 0; break; } case VERTEX_DATA: { vtkGraph* const graph = vtkGraph::SafeDownCast(output); output_attributes = graph ? graph->GetVertexData() : nullptr; output_count = graph ? graph->GetNumberOfVertices() : 0; break; } case EDGE_DATA: { vtkGraph* const graph = vtkGraph::SafeDownCast(output); output_attributes = graph ? graph->GetEdgeData() : nullptr; output_count = graph ? graph->GetNumberOfEdges() : 0; break; } } if (!output_attributes) { vtkErrorMacro(<< "Invalid field type for this data object."); return 0; } // Create our output array ... vtkIdTypeArray* const output_array = vtkIdTypeArray::New(); output_array->SetName(this->ArrayName); output_array->SetNumberOfTuples(output_count); output_attributes->AddArray(output_array); output_array->Delete(); if (this->PedigreeID) output_attributes->SetPedigreeIds(output_array); // Generate indices based on the reference array ... if (this->ReferenceArrayName && strlen(this->ReferenceArrayName)) { int reference_array_index = -1; vtkAbstractArray* const reference_array = output_attributes->GetAbstractArray(this->ReferenceArrayName, reference_array_index); if (!reference_array) { vtkErrorMacro(<< "No reference array " << this->ReferenceArrayName); return 0; } typedef std::map index_map_t; index_map_t index_map; for (vtkIdType i = 0; i != output_count; ++i) { if (!index_map.count(reference_array->GetVariantValue(i))) { #ifdef _RWSTD_NO_MEMBER_TEMPLATES // Deal with Sun Studio old libCstd. // http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html index_map.insert( std::pair(reference_array->GetVariantValue(i), 0)); #else index_map.insert(std::make_pair(reference_array->GetVariantValue(i), 0)); #endif } } vtkIdType index = 0; for (index_map_t::iterator i = index_map.begin(); i != index_map.end(); ++i, ++index) i->second = index; for (vtkIdType i = 0; i != output_count; ++i) output_array->SetValue(i, index_map[reference_array->GetVariantValue(i)]); } // Otherwise, generate a trivial index array ... else { for (vtkIdType i = 0; i != output_count; ++i) output_array->SetValue(i, i); } return 1; } VTK_ABI_NAMESPACE_END