Compare commits

...

2 Commits

Author SHA1 Message Date
340cdbd7ed add aspect ratio computation 2022-02-17 17:30:04 +01:00
df1d96e686 angles are now stored in per-triangle order 2022-02-17 17:29:30 +01:00
5 changed files with 132 additions and 35 deletions

View File

@ -11,7 +11,9 @@ target_compile_features(pfe PRIVATE cxx_std_17)
target_sources(pfe PRIVATE target_sources(pfe PRIVATE
src/main.cc src/main.cc
src/angles_filter.cc src/angles_filter.cc
src/angles_filter.h) src/angles_filter.h
src/aspect_ratio_filter.cc
src/aspect_ratio_filter.h)
target_link_libraries(pfe PRIVATE target_link_libraries(pfe PRIVATE
VTK::CommonCore VTK::CommonCore

View File

@ -73,15 +73,15 @@ void cellAngles(vtkDataSet *dataSet, vtkIdList *idList, double *angles) {
vtkMath::Subtract(b, d, db); vtkMath::Subtract(b, d, db);
vtkMath::Subtract(c, d, dc); vtkMath::Subtract(c, d, dc);
angles[0] = vtkMath::AngleBetweenVectors(ab, ac); angles[0] = vtkMath::AngleBetweenVectors(ab, ac);
angles[1] = vtkMath::AngleBetweenVectors(ac, ad); angles[1] = vtkMath::AngleBetweenVectors(ca, cb);
angles[2] = vtkMath::AngleBetweenVectors(ad, ab); angles[2] = vtkMath::AngleBetweenVectors(ba, bc);
angles[3] = vtkMath::AngleBetweenVectors(ba, bc); angles[3] = vtkMath::AngleBetweenVectors(ac, ad);
angles[4] = vtkMath::AngleBetweenVectors(bc, bd); angles[4] = vtkMath::AngleBetweenVectors(dc, da);
angles[5] = vtkMath::AngleBetweenVectors(bd, ba); angles[5] = vtkMath::AngleBetweenVectors(cd, ca);
angles[6] = vtkMath::AngleBetweenVectors(ca, cb); angles[6] = vtkMath::AngleBetweenVectors(ad, ab);
angles[7] = vtkMath::AngleBetweenVectors(cb, cd); angles[7] = vtkMath::AngleBetweenVectors(bd, ba);
angles[8] = vtkMath::AngleBetweenVectors(cd, ca); angles[8] = vtkMath::AngleBetweenVectors(da, db);
angles[9] = vtkMath::AngleBetweenVectors(da, db); angles[9] = vtkMath::AngleBetweenVectors(bc, bd);
angles[10] = vtkMath::AngleBetweenVectors(db, dc); angles[10] = vtkMath::AngleBetweenVectors(cb, cd);
angles[11] = vtkMath::AngleBetweenVectors(dc, da); angles[11] = vtkMath::AngleBetweenVectors(db, dc);
} }

View File

@ -0,0 +1,69 @@
#include "aspect_ratio_filter.h"
#include <vtkUnstructuredGrid.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkDoubleArray.h>
#include <vtkCellIterator.h>
vtkStandardNewMacro(AspectRatioFilter);
int AspectRatioFilter::FillInputPortInformation(int port, vtkInformation *info) {
vtkUnstructuredGridAlgorithm::FillInputPortInformation(port, info);
// Ensure there is an "angles" array in the DataCell.
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;
}

23
src/aspect_ratio_filter.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef ASPECT_RATIO_FILTER_H
#define ASPECT_RATIO_FILTER_H
#include <vtkUnstructuredGridAlgorithm.h>
#include <vtkIdList.h>
class AspectRatioFilter : public vtkUnstructuredGridAlgorithm {
public:
static AspectRatioFilter *New();
vtkTypeMacro(AspectRatioFilter, vtkUnstructuredGridAlgorithm);
int FillInputPortInformation(int, vtkInformation *info) override;
vtkTypeBool RequestData(vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector) override;
protected:
~AspectRatioFilter() override = default;
};
#endif

View File

@ -1,4 +1,5 @@
#include "angles_filter.h" #include "angles_filter.h"
#include "aspect_ratio_filter.h"
#include <vtkCellData.h> #include <vtkCellData.h>
#include <vtkUnstructuredGrid.h> #include <vtkUnstructuredGrid.h>
@ -47,17 +48,16 @@ int main(int argc, char **argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
vtkNew<vtkNamedColors> colors; /* Reader */
std::array<unsigned char, 4> bkg{{26, 51, 102, 255}};
colors->SetColor("BkgColor", bkg.data());
// vtkNew<vtkXMLPolyDataReader> reader;
vtkNew<vtkUnstructuredGridReader> reader; vtkNew<vtkUnstructuredGridReader> reader;
reader->SetFileName(argv[1]); reader->SetFileName(argv[1]);
// reader->Update();
/* Angle filter */
vtkNew<AnglesFilter> anglesFilter; vtkNew<AnglesFilter> anglesFilter;
anglesFilter->SetInputConnection(reader->GetOutputPort()); anglesFilter->SetInputConnection(reader->GetOutputPort());
/* Display angles in console. */
anglesFilter->Update(); anglesFilter->Update();
vtkUnstructuredGrid *grid = anglesFilter->GetOutput(); vtkUnstructuredGrid *grid = anglesFilter->GetOutput();
auto *angles = vtkDoubleArray::SafeDownCast(grid->GetCellData()->GetArray("angles")); auto *angles = vtkDoubleArray::SafeDownCast(grid->GetCellData()->GetArray("angles"));
@ -68,16 +68,23 @@ int main(int argc, char **argv) {
} }
std::cout << "\b\b \n"; std::cout << "\b\b \n";
} }
// std::cout << "avg: " << average(angles)
// << ", stddev: " << standard_deviation(angles)
// << ", min: " << *std::min_element(angles.begin(), angles.end())
// << ", max: " << *std::max_element(angles.begin(), angles.end()) << std::endl;
/* Aspect ratio */
vtkNew<AspectRatioFilter> aspectRatioFilter;
aspectRatioFilter->SetInputConnection(anglesFilter->GetOutputPort());
/* Display aspect ratios in console. */
aspectRatioFilter->Update();
grid = aspectRatioFilter->GetOutput();
auto *aspectRatios = vtkDoubleArray::SafeDownCast(grid->GetCellData()->GetArray("aspect_ratio"));
for (ssize_t i = 0; i < aspectRatios->GetNumberOfTuples(); i++) {
std::cout << "cell " << i << ": "
<< aspectRatios->GetTuple1(i) << "\n";
}
/* Volume rendering properties */
vtkNew<vtkOpenGLProjectedTetrahedraMapper> volumeMapper; vtkNew<vtkOpenGLProjectedTetrahedraMapper> volumeMapper;
volumeMapper->SetInputConnection(anglesFilter->GetOutputPort()); volumeMapper->SetInputConnection(aspectRatioFilter->GetOutputPort());
// vtkNew<vtkPolyDataMapper> mapper;
// mapper->SetInputConnection(reader->GetOutputPort());
vtkNew<vtkVolume> volume; vtkNew<vtkVolume> volume;
volume->SetMapper(volumeMapper); volume->SetMapper(volumeMapper);
vtkNew<vtkPiecewiseFunction> transferFunction; vtkNew<vtkPiecewiseFunction> transferFunction;
@ -85,16 +92,12 @@ int main(int argc, char **argv) {
transferFunction->AddPoint(1, 1); transferFunction->AddPoint(1, 1);
volume->GetProperty()->SetScalarOpacity(transferFunction); volume->GetProperty()->SetScalarOpacity(transferFunction);
volume->GetProperty()->SetColor(transferFunction); volume->GetProperty()->SetColor(transferFunction);
// vtkNew<vtkActor> actor;
// actor->SetMapper(mapper);
// actor->GetProperty()->SetColor(
// colors->GetColor4d("Tomato").GetData());
// actor->RotateX(30.0);
// actor->RotateY(-45.0);
/* Renderer */
vtkNew<vtkNamedColors> colors;
std::array<unsigned char, 4> bkg{{26, 51, 102, 255}};
colors->SetColor("BkgColor", bkg.data());
vtkNew<vtkRenderer> renderer; vtkNew<vtkRenderer> renderer;
// renderer->AddActor(actor);
renderer->AddVolume(volume); renderer->AddVolume(volume);
renderer->SetBackground(colors->GetColor3d("BkgColor").GetData()); renderer->SetBackground(colors->GetColor3d("BkgColor").GetData());
renderer->ResetCamera(); renderer->ResetCamera();