// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkProbePolyhedron.h" #include "vtkCellArray.h" #include "vtkCellData.h" #include "vtkDoubleArray.h" #include "vtkFloatArray.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkMeanValueCoordinatesInterpolator.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkPolyData.h" #include "vtkStreamingDemandDrivenPipeline.h" VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkProbePolyhedron); //------------------------------------------------------------------------------ vtkProbePolyhedron::vtkProbePolyhedron() { this->ProbePointData = 1; this->ProbeCellData = 0; this->SetNumberOfInputPorts(2); } //------------------------------------------------------------------------------ vtkProbePolyhedron::~vtkProbePolyhedron() = default; //------------------------------------------------------------------------------ void vtkProbePolyhedron::SetSourceConnection(vtkAlgorithmOutput* algOutput) { this->SetInputConnection(1, algOutput); } //------------------------------------------------------------------------------ void vtkProbePolyhedron::SetSourceData(vtkPolyData* input) { this->SetInputData(1, input); } //------------------------------------------------------------------------------ vtkPolyData* vtkProbePolyhedron::GetSource() { if (this->GetNumberOfInputConnections(1) < 1) { return nullptr; } return vtkPolyData::SafeDownCast(this->GetExecutive()->GetInputData(1, 0)); } //------------------------------------------------------------------------------ int vtkProbePolyhedron::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())); vtkPolyData* source = vtkPolyData::SafeDownCast(sourceInfo->Get(vtkDataObject::DATA_OBJECT())); vtkDataSet* output = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); if (!source) { return 0; } // Make sure that the mesh consists of triangles. Bail out if not. vtkIdType numPolys = source->GetNumberOfPolys(); vtkCellArray* srcPolys = source->GetPolys(); if (!numPolys || !srcPolys) { vtkErrorMacro("Probe polyhedron filter requires a non-empty mesh"); return 0; } // Set up attribute interpolation. The input structure is passed to the // output. vtkIdType numInputPts = input->GetNumberOfPoints(); vtkIdType numSrcPts = source->GetNumberOfPoints(); vtkIdType numInputCells = input->GetNumberOfCells(); output->CopyStructure(input); vtkPointData* outPD = output->GetPointData(); vtkCellData* outCD = output->GetCellData(); vtkPointData* srcPD = source->GetPointData(); outPD->InterpolateAllocate(srcPD, numInputPts, 1); outCD->InterpolateAllocate(srcPD, numInputCells, 1); // Okay probe the polyhedral mesh. Have to loop over all points and compute // each points interpolation weights. These weights are used to perform the // interpolation. vtkPoints* srcPts = source->GetPoints(); vtkDoubleArray* weights = vtkDoubleArray::New(); weights->SetNumberOfComponents(1); weights->SetNumberOfTuples(numSrcPts); double* wPtr = weights->GetPointer(0); // InterpolatePoint requires knowing which points to interpolate from. vtkIdType ptId, cellId; vtkIdList* srcIds = vtkIdList::New(); srcIds->SetNumberOfIds(numSrcPts); for (ptId = 0; ptId < numSrcPts; ++ptId) { srcIds->SetId(ptId, ptId); } // Interpolate the point data (if requested) double x[3]; bool abort = false; vtkIdType idx = 0, progressInterval = (numInputCells + numInputPts) / 10 + 1; if (this->ProbePointData) { for (ptId = 0; ptId < numInputPts && !abort; ++ptId, ++idx) { if (!(idx % progressInterval)) { vtkDebugMacro(<< "Processing #" << idx); this->UpdateProgress(static_cast(idx) / (numInputCells + numInputPts)); abort = this->CheckAbort(); } input->GetPoint(ptId, x); vtkMeanValueCoordinatesInterpolator::ComputeInterpolationWeights(x, srcPts, srcPolys, wPtr); outPD->InterpolatePoint(srcPD, ptId, srcIds, wPtr); } } // Interpolate the cell data (if requested) // Compute point value at the cell's parametric center. if (this->ProbeCellData) { vtkCell* cell; int subId; double pcoords[3]; x[0] = x[1] = x[2] = 0.0; for (cellId = 0; cellId < numInputCells && !abort; ++cellId, ++idx) { if (!(idx % progressInterval)) { vtkDebugMacro(<< "Processing #" << idx); this->UpdateProgress(static_cast(idx) / (numInputCells + numInputPts)); abort = this->CheckAbort(); } cell = input->GetCell(cellId); if (cell->GetCellType() != VTK_EMPTY_CELL) { subId = cell->GetParametricCenter(pcoords); cell->EvaluateLocation(subId, pcoords, x, wPtr); } vtkMeanValueCoordinatesInterpolator::ComputeInterpolationWeights(x, srcPts, srcPolys, wPtr); outCD->InterpolatePoint(srcPD, cellId, srcIds, wPtr); } } // clean up srcIds->Delete(); weights->Delete(); return 1; } //------------------------------------------------------------------------------ int vtkProbePolyhedron::RequestInformation(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); outInfo->CopyEntry(sourceInfo, vtkStreamingDemandDrivenPipeline::TIME_STEPS()); outInfo->CopyEntry(sourceInfo, vtkStreamingDemandDrivenPipeline::TIME_RANGE()); outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()), 6); return 1; } //------------------------------------------------------------------------------ int vtkProbePolyhedron::RequestUpdateExtent(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector) { // get the info objects vtkInformation* inInfo = inputVector[0]->GetInformationObject(0); vtkInformation* outInfo = outputVector->GetInformationObject(0); int usePiece = 0; // What ever happened to CopyUpdateExtent in vtkDataObject? // Copying both piece and extent could be bad. Setting the piece // of a structured data set will affect the extent. vtkDataObject* output = outInfo->Get(vtkDataObject::DATA_OBJECT()); if (output && (!strcmp(output->GetClassName(), "vtkUnstructuredGrid") || !strcmp(output->GetClassName(), "vtkPolyData"))) { usePiece = 1; } inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1); if (usePiece) { inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER())); inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(), outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES())); inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(), outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS())); } else { inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT()), 6); } return 1; } //------------------------------------------------------------------------------ void vtkProbePolyhedron::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); vtkDataObject* source = this->GetSource(); os << indent << "Source: " << source << "\n"; os << indent << "Probe Point Data: " << (this->ProbePointData ? "true" : "false") << "\n"; os << indent << "Probe Cell Data: " << (this->ProbeCellData ? "true" : "false") << "\n"; } VTK_ABI_NAMESPACE_END