pfe/src/analysis/aspect_ratio_filter.cc

82 lines
2.7 KiB
C++

#include "aspect_ratio_filter.h"
#include "vtkDataObject.h"
#include <vtkUnstructuredGrid.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkDoubleArray.h>
#include <vtkCellIterator.h>
#include <vtkInformation.h>
#include <vtkInformationVector.h>
vtkStandardNewMacro(AspectRatioFilter);
// Ensure there is an "angles", 12 floats tuple array in the DataCell.
int AspectRatioFilter::FillInputPortInformation(int port, vtkInformation *info) {
vtkUnstructuredGridAlgorithm::FillInputPortInformation(port, info);
vtkNew<vtkInformation> anglesField;
anglesField->Set(vtkDataObject::FIELD_ASSOCIATION(), vtkDataObject::FIELD_ASSOCIATION_CELLS);
anglesField->Set(vtkDataObject::FIELD_NAME(), "angles");
anglesField->Set(vtkDataObject::FIELD_NUMBER_OF_COMPONENTS(), 12);
anglesField->Set(vtkDataObject::FIELD_ARRAY_TYPE(), VTK_DOUBLE);
vtkNew<vtkInformationVector> fields;
fields->Append(anglesField);
info->Set(vtkAlgorithm::INPUT_REQUIRED_FIELDS(), fields);
return 1;
}
vtkTypeBool AspectRatioFilter::RequestData(
vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector) {
(void) request;
vtkUnstructuredGrid* input =
vtkUnstructuredGrid::GetData(inputVector[0]);
vtkUnstructuredGrid* output =
vtkUnstructuredGrid::GetData(outputVector);
/* Pass the input structure and point data unmodified. */
output->CopyStructure(input);
output->GetPointData()->PassData(input->GetPointData());
/* Pass the existing cell data unmodified. */
vtkCellData *cellData = output->GetCellData();
cellData->PassData(input->GetCellData());
/* Then add an array to it. */
vtkNew<vtkDoubleArray> aspectRatios;
aspectRatios->SetName("aspect_ratio");
aspectRatios->SetNumberOfComponents(1);
aspectRatios->SetNumberOfTuples(input->GetNumberOfCells());
auto *angles = vtkDoubleArray::SafeDownCast(input->GetCellData()->GetArray("angles"));
double cellAngles[12];
double triangleRatios[4];
for (vtkIdType cellId = 0; cellId < input->GetNumberOfCells(); cellId++) {
if (input->GetCellType(cellId) != VTK_TETRA) continue;
angles->GetTuple(cellId, cellAngles);
for (vtkIdType angleId = 0;
angleId < angles->GetNumberOfComponents();
angleId += 3) {
double minAngle = std::min(
std::min(cellAngles[angleId], cellAngles[angleId + 1]),
cellAngles[angleId + 2]);
double maxAngle = std::max(
std::max(cellAngles[angleId], cellAngles[angleId + 1]),
cellAngles[angleId + 2]);
triangleRatios[angleId / 3] = minAngle / maxAngle;
}
double worst = std::min(
std::min(triangleRatios[0], triangleRatios[1]),
std::min(triangleRatios[2], triangleRatios[3]));
aspectRatios->SetTuple1(cellId, worst);
}
cellData->AddArray((vtkAbstractArray *) aspectRatios);
return true;
}