// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkInterpolateDataSetAttributes.h" #include "vtkCellData.h" #include "vtkDataSetCollection.h" #include "vtkExecutive.h" #include "vtkGarbageCollector.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkPolyData.h" #include "vtkRectilinearGrid.h" #include "vtkStructuredGrid.h" #include "vtkStructuredPoints.h" #include "vtkUnstructuredGrid.h" VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkInterpolateDataSetAttributes); // Create object with no input or output. vtkInterpolateDataSetAttributes::vtkInterpolateDataSetAttributes() { this->InputList = vtkDataSetCollection::New(); this->T = 0.0; } vtkInterpolateDataSetAttributes::~vtkInterpolateDataSetAttributes() { if (this->InputList) { this->InputList->Delete(); this->InputList = nullptr; } } vtkDataSetCollection* vtkInterpolateDataSetAttributes::GetInputList() { int i; this->InputList->RemoveAllItems(); for (i = 0; i < this->GetNumberOfInputConnections(0); i++) { this->InputList->AddItem(static_cast(this->GetExecutive()->GetInputData(0, i))); } return this->InputList; } // Interpolate the data int vtkInterpolateDataSetAttributes::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector) { // get the info object vtkInformation* outInfo = outputVector->GetInformationObject(0); // get the output vtkDataSet* output = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); vtkIdType numPts, numCells, i; int numInputs = this->GetNumberOfInputConnections(0); int lowDS, highDS; vtkDataSet *ds, *ds2; vtkPointData* outputPD = output->GetPointData(); vtkCellData* outputCD = output->GetCellData(); vtkPointData *inputPD, *input2PD; vtkCellData *inputCD, *input2CD; double t; if (numInputs < 2) { vtkErrorMacro(<< "Need at least two inputs to interpolate!"); return 1; } vtkDebugMacro(<< "Interpolating data..."); // Check input and determine between which data sets the interpolation // is to occur. if (this->T > static_cast(numInputs)) { vtkErrorMacro(<< "Bad interpolation parameter"); return 1; } lowDS = static_cast(this->T); if (lowDS >= (numInputs - 1)) { lowDS = numInputs - 2; } highDS = lowDS + 1; t = this->T - static_cast(lowDS); t = std::min(t, 1.0); vtkInformation* dsInfo = inputVector[0]->GetInformationObject(lowDS); vtkInformation* ds2Info = inputVector[0]->GetInformationObject(highDS); ds = vtkDataSet::SafeDownCast(dsInfo->Get(vtkDataObject::DATA_OBJECT())); ds2 = vtkDataSet::SafeDownCast(ds2Info->Get(vtkDataObject::DATA_OBJECT())); numPts = ds->GetNumberOfPoints(); numCells = ds->GetNumberOfCells(); if (numPts != ds2->GetNumberOfPoints() || numCells != ds2->GetNumberOfCells()) { vtkErrorMacro(<< "Data sets not consistent!"); return 1; } output->CopyStructure(ds); inputPD = ds->GetPointData(); inputCD = ds->GetCellData(); input2PD = ds2->GetPointData(); input2CD = ds2->GetCellData(); // Allocate the data set attributes outputPD->CopyAllOff(); if (inputPD->GetScalars() && input2PD->GetScalars()) { outputPD->CopyScalarsOn(); } if (inputPD->GetVectors() && input2PD->GetVectors()) { outputPD->CopyVectorsOn(); } if (inputPD->GetNormals() && input2PD->GetNormals()) { outputPD->CopyNormalsOn(); } if (inputPD->GetTCoords() && input2PD->GetTCoords()) { outputPD->CopyTCoordsOn(); } if (inputPD->GetTensors() && input2PD->GetTensors()) { outputPD->CopyTensorsOn(); } // *TODO* Fix // if ( inputPD->GetFieldData() && input2PD->GetFieldData() ) //{ // outputPD->CopyFieldDataOn(); //} outputPD->InterpolateAllocate(inputPD); outputCD->CopyAllOff(); if (inputCD->GetScalars() && input2CD->GetScalars()) { outputCD->CopyScalarsOn(); } if (inputCD->GetVectors() && input2CD->GetVectors()) { outputCD->CopyVectorsOn(); } if (inputCD->GetNormals() && input2CD->GetNormals()) { outputCD->CopyNormalsOn(); } if (inputCD->GetTCoords() && input2CD->GetTCoords()) { outputCD->CopyTCoordsOn(); } if (inputCD->GetTensors() && input2CD->GetTensors()) { outputCD->CopyTensorsOn(); } // *TODO* Fix // if ( inputCD->GetFieldData() && input2CD->GetFieldData() ) //{ // outputCD->CopyFieldDataOn(); // } outputCD->InterpolateAllocate(inputCD); // Interpolate point data. We'll assume that it takes 50% of the time for (i = 0; i < numPts; i++) { if (!(i % 10000)) { this->UpdateProgress(static_cast(i) / numPts * 0.50); if (this->CheckAbort()) { break; } } outputPD->InterpolateTime(inputPD, input2PD, i, t); } // Interpolate cell data. We'll assume that it takes 50% of the time for (i = 0; i < numCells; i++) { if (!(i % 10000)) { this->UpdateProgress(0.5 + static_cast(i) / numCells * 0.50); if (this->CheckAbort()) { break; } } outputCD->InterpolateTime(inputCD, input2CD, i, t); } return 1; } int vtkInterpolateDataSetAttributes::FillInputPortInformation(int port, vtkInformation* info) { if (!this->Superclass::FillInputPortInformation(port, info)) { return 0; } info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1); return 1; } void vtkInterpolateDataSetAttributes::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "T: " << this->T << endl; } //------------------------------------------------------------------------------ void vtkInterpolateDataSetAttributes ::ReportReferences(vtkGarbageCollector* collector) { this->Superclass::ReportReferences(collector); vtkGarbageCollectorReport(collector, this->InputList, "InputList"); } VTK_ABI_NAMESPACE_END