pfe/src/analysis/dihedral_angles_filter.cc

83 lines
2.9 KiB
C++

#include "dihedral_angles_filter.h"
#include <algorithm>
#include <limits>
#include <vtkUnstructuredGrid.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkDoubleArray.h>
#include <vtkCellIterator.h>
#include <vtkTriangle.h>
vtkStandardNewMacro(DihedralAnglesFilter);
vtkTypeBool DihedralAnglesFilter::RequestData(
vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector) {
(void) request;
vtkUnstructuredGrid* input =
vtkUnstructuredGrid::GetData(inputVector[0]);
vtkUnstructuredGrid* output =
vtkUnstructuredGrid::GetData(outputVector);
output->CopyStructure(input);
output->GetPointData()->PassData(input->GetPointData());
vtkCellData *cellData = output->GetCellData();
cellData->PassData(input->GetCellData());
vtkNew<vtkDoubleArray> dihedralAnglesArray;
dihedralAnglesArray->SetName("dihedral_angles");
dihedralAnglesArray->SetNumberOfComponents(6);
dihedralAnglesArray->SetNumberOfTuples(input->GetNumberOfCells());
double *dihedralAnglesBase = dihedralAnglesArray->GetPointer(0);
vtkNew<vtkDoubleArray> minDihedralAngleArray;
minDihedralAngleArray->SetName("min_dihedral_angle");
minDihedralAngleArray->SetNumberOfTuples(input->GetNumberOfCells());
double *minDihedralAngleBase = minDihedralAngleArray->GetPointer(0);
AverageMinDegrees = 0;
MinMinDegrees = std::numeric_limits<double>::infinity();
size_t i = 0;
vtkCellIterator *it = input->NewCellIterator();
for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextCell()) {
double a[3], b[3], c[3], d[3];
vtkPoints *points = it->GetPoints();
points->GetPoint(0, a);
points->GetPoint(1, b);
points->GetPoint(2, c);
points->GetPoint(3, d);
double nacb[3], nadc[3], nabd[3], nbdc[3];
vtkTriangle::ComputeNormal(a, c, b, nacb);
vtkTriangle::ComputeNormal(a, d, c, nadc);
vtkTriangle::ComputeNormal(a, b, d, nabd);
vtkTriangle::ComputeNormal(b, d, c, nbdc);
dihedralAnglesBase[i+0] = vtkMath::AngleBetweenVectors(nacb, nadc);
dihedralAnglesBase[i+1] = vtkMath::AngleBetweenVectors(nadc, nabd);
dihedralAnglesBase[i+2] = vtkMath::AngleBetweenVectors(nabd, nacb);
dihedralAnglesBase[i+3] = vtkMath::AngleBetweenVectors(nbdc, nacb);
dihedralAnglesBase[i+4] = vtkMath::AngleBetweenVectors(nbdc, nadc);
dihedralAnglesBase[i+5] = vtkMath::AngleBetweenVectors(nbdc, nabd);
minDihedralAngleBase[i / 6] =
*std::min_element(dihedralAnglesBase + i,
dihedralAnglesBase + i + 6);
AverageMinDegrees += minDihedralAngleBase[i / 6];
MinMinDegrees = std::min(MinMinDegrees, minDihedralAngleBase[i / 6]);
i += 6;
}
it->Delete();
AverageMinDegrees /= input->GetNumberOfCells();
AverageMinDegrees = AverageMinDegrees * 180. / 3.141592653589793;
MinMinDegrees = MinMinDegrees * 180. / 3.141592653589793;
cellData->AddArray((vtkAbstractArray *) dihedralAnglesArray);
cellData->AddArray((vtkAbstractArray *) minDihedralAngleArray);
return true;
}