// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkGenericProbeFilter.h" #include "vtkCell.h" #include "vtkCellData.h" #include "vtkExecutive.h" #include "vtkGenericAdaptorCell.h" #include "vtkGenericAttribute.h" #include "vtkGenericAttributeCollection.h" #include "vtkGenericCellIterator.h" #include "vtkGenericDataSet.h" #include "vtkIdTypeArray.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkGenericProbeFilter); //------------------------------------------------------------------------------ vtkGenericProbeFilter::vtkGenericProbeFilter() { this->ValidPoints = vtkIdTypeArray::New(); this->SetNumberOfInputPorts(2); } //------------------------------------------------------------------------------ vtkGenericProbeFilter::~vtkGenericProbeFilter() { this->ValidPoints->Delete(); this->ValidPoints = nullptr; } //------------------------------------------------------------------------------ void vtkGenericProbeFilter::SetSourceData(vtkGenericDataSet* input) { this->SetInputData(1, input); } //------------------------------------------------------------------------------ vtkGenericDataSet* vtkGenericProbeFilter::GetSource() { if (this->GetNumberOfInputConnections(1) < 1) { return nullptr; } return vtkGenericDataSet::SafeDownCast(this->GetExecutive()->GetInputData(1, 0)); } //------------------------------------------------------------------------------ int vtkGenericProbeFilter::RequestInformation(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector) { vtkInformation* sourceInfo = inputVector[1]->GetInformationObject(0); vtkInformation* outInfo = outputVector->GetInformationObject(0); // A variation of the bug fix from John Biddiscombe. // Make sure that the scalar type and number of components // are propagated from the source not the input. if (vtkImageData::HasScalarType(sourceInfo)) { vtkImageData::SetScalarType(vtkImageData::GetScalarType(sourceInfo), outInfo); } if (vtkImageData::HasNumberOfScalarComponents(sourceInfo)) { vtkImageData::SetNumberOfScalarComponents( vtkImageData::GetNumberOfScalarComponents(sourceInfo), outInfo); } return 1; } //------------------------------------------------------------------------------ int vtkGenericProbeFilter::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector) { // get the info objects vtkInformation* inInfo = inputVector[0]->GetInformationObject(0); vtkInformation* sourceInfo = inputVector[1]->GetInformationObject(0); vtkInformation* outInfo = outputVector->GetInformationObject(0); // get the input and output vtkDataSet* input = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())); vtkDataSet* output = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); vtkGenericDataSet* source = vtkGenericDataSet::SafeDownCast(sourceInfo->Get(vtkDataObject::DATA_OBJECT())); vtkIdType ptId, numPts; double x[3], tol2; int subId; double pcoords[3]; vtkDebugMacro(<< "Probing data"); if (source == nullptr) { vtkErrorMacro(<< "Source is nullptr."); return 1; } // First, copy the input to the output as a starting point output->CopyStructure(input); numPts = input->GetNumberOfPoints(); this->ValidPoints->Allocate(numPts); vtkPointData* outputPD = output->GetPointData(); vtkCellData* outputCD = output->GetCellData(); // prepare the output attributes vtkGenericAttributeCollection* attributes = source->GetAttributes(); vtkGenericAttribute* attribute; vtkDataArray* attributeArray; int c = attributes->GetNumberOfAttributes(); vtkDataSetAttributes* dsAttributes; int attributeType; double* tuples = new double[attributes->GetMaxNumberOfComponents()]; for (int i = 0; i < c; ++i) { attribute = attributes->GetAttribute(i); attributeType = attribute->GetType(); if (attribute->GetCentering() == vtkPointCentered) { dsAttributes = outputPD; } else // vtkCellCentered { dsAttributes = outputCD; } attributeArray = vtkDataArray::CreateDataArray(attribute->GetComponentType()); attributeArray->SetNumberOfComponents(attribute->GetNumberOfComponents()); attributeArray->SetName(attribute->GetName()); dsAttributes->AddArray(attributeArray); attributeArray->Delete(); if (dsAttributes->GetAttribute(attributeType) == nullptr) { dsAttributes->SetActiveAttribute(dsAttributes->GetNumberOfArrays() - 1, attributeType); } } // Use tolerance as a function of size of source data // tol2 = source->GetLength(); tol2 = tol2 ? tol2 * tol2 / 1000.0 : 0.001; std::cout << "tol2=" << tol2 << "\n"; // Loop over all input points, interpolating source data // bool abort = false; // Need to use source to create a cellIt since this class is virtual vtkGenericCellIterator* cellIt = source->NewCellIterator(); vtkIdType progressInterval = numPts / 20 + 1; for (ptId = 0; ptId < numPts && !abort; ptId++) { if (!(ptId % progressInterval)) { this->UpdateProgress(static_cast(ptId) / numPts); abort = CheckAbort(); } // Get the xyz coordinate of the point in the input dataset input->GetPoint(ptId, x); // Find the cell that contains xyz and get it if (source->FindCell(x, cellIt, tol2, subId, pcoords)) { vtkGenericAdaptorCell* cellProbe = cellIt->GetCell(); // for each cell-centered attribute: copy the value for (int attrib = 0; attrib < c; ++attrib) { if (attributes->GetAttribute(attrib)->GetCentering() == vtkCellCentered) { vtkDataArray* array = outputCD->GetArray(attributes->GetAttribute(attrib)->GetName()); double* values = attributes->GetAttribute(attrib)->GetTuple(cellProbe); array->InsertNextTuple(values); } } // for each point-centered attribute: interpolate the value int j = 0; for (int attribute_idx = 0; attribute_idx < c; ++attribute_idx) { vtkGenericAttribute* a = attributes->GetAttribute(attribute_idx); if (a->GetCentering() == vtkPointCentered) { cellProbe->InterpolateTuple(a, pcoords, tuples); outputPD->GetArray(j)->InsertTuple(ptId, tuples); ++j; } } this->ValidPoints->InsertNextValue(ptId); } else { outputPD->NullData(ptId); } } cellIt->Delete(); delete[] tuples; return 1; } //------------------------------------------------------------------------------ void vtkGenericProbeFilter::PrintSelf(ostream& os, vtkIndent indent) { vtkGenericDataSet* source = this->GetSource(); this->Superclass::PrintSelf(os, indent); os << indent << "Source: " << source << "\n"; os << indent << "ValidPoints: " << this->ValidPoints << "\n"; } //------------------------------------------------------------------------------ int vtkGenericProbeFilter::FillInputPortInformation(int port, vtkInformation* info) { if (!this->Superclass::FillInputPortInformation(port, info)) { return 0; } if (port == 1) { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkGenericDataSet"); } else { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet"); } return 1; } VTK_ABI_NAMESPACE_END