From 8ec1d44da3ccb037811bf65120a3135a15a5dad1 Mon Sep 17 00:00:00 2001 From: Thomas Galland <thomas.galland@kitware.com> Date: Thu, 14 Nov 2024 09:47:05 +0100 Subject: [PATCH] vtkHyperTreeGridAxisCut: add test with coincident plane --- Filters/HyperTree/Testing/CMakeLists.txt | 1 + Filters/HyperTree/Testing/Cxx/CMakeLists.txt | 1 + ...tHyperTreeGrid3DAxisCutCoincidentPlane.cxx | 148 ++++++++++++++++++ ...reeGrid3DAxisCutCoincidentPlane.png.sha512 | 1 + .../HTG/htg_for_axis_aligned_cut.htg.sha512 | 1 + 5 files changed, 152 insertions(+) create mode 100644 Filters/HyperTree/Testing/Cxx/TestHyperTreeGrid3DAxisCutCoincidentPlane.cxx create mode 100644 Filters/HyperTree/Testing/Data/Baseline/TestHyperTreeGrid3DAxisCutCoincidentPlane.png.sha512 create mode 100644 Testing/Data/HTG/htg_for_axis_aligned_cut.htg.sha512 diff --git a/Filters/HyperTree/Testing/CMakeLists.txt b/Filters/HyperTree/Testing/CMakeLists.txt index c9fccd33c7c..317b82a6a72 100644 --- a/Filters/HyperTree/Testing/CMakeLists.txt +++ b/Filters/HyperTree/Testing/CMakeLists.txt @@ -5,6 +5,7 @@ vtk_module_test_data( Data/HTG/binary_3D_333_mask.htg Data/HTG/donut_XZ_shift_2d.htg Data/HTG/ghost.htg + Data/HTG/htg_for_axis_aligned_cut.htg Data/HTG/shell_3d.htg Data/HTG/single_cell_3d.htg Data/HTG/three_cells_3d.htg diff --git a/Filters/HyperTree/Testing/Cxx/CMakeLists.txt b/Filters/HyperTree/Testing/Cxx/CMakeLists.txt index 6e8a41d9d8e..f4ec43c05ab 100644 --- a/Filters/HyperTree/Testing/Cxx/CMakeLists.txt +++ b/Filters/HyperTree/Testing/Cxx/CMakeLists.txt @@ -11,6 +11,7 @@ set(test_sources TestHyperTreeGrid2DInterfaceShift.cxx + TestHyperTreeGrid3DAxisCutCoincidentPlane.cxx TestHyperTreeGrid3DIntercepts.cxx TestHyperTreeGrid3DInterface.cxx TestHyperTreeGrid3DSimpleInterface.cxx diff --git a/Filters/HyperTree/Testing/Cxx/TestHyperTreeGrid3DAxisCutCoincidentPlane.cxx b/Filters/HyperTree/Testing/Cxx/TestHyperTreeGrid3DAxisCutCoincidentPlane.cxx new file mode 100644 index 00000000000..654d2d4d6c6 --- /dev/null +++ b/Filters/HyperTree/Testing/Cxx/TestHyperTreeGrid3DAxisCutCoincidentPlane.cxx @@ -0,0 +1,148 @@ +// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen +// SPDX-License-Identifier: BSD-3-Clause + +#include "vtkCamera.h" +#include "vtkDataSetMapper.h" +#include "vtkHyperTreeGrid.h" +#include "vtkHyperTreeGridAxisCut.h" +#include "vtkHyperTreeGridGeometry.h" +#include "vtkNew.h" +#include "vtkOutlineSource.h" +#include "vtkProperty.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkRenderer.h" +#include "vtkTestUtilities.h" +#include "vtkXMLHyperTreeGridReader.h" + +#include <limits> + +/** + * Test the behavior of vtkHyperTreeGridAxisCut when the cutting plane is coincident with some faces + * of the HTG cells geometry. In such cases, the plan should be considered as "inside" if it is + * coincident with the oposite faces of the cell origin. + */ +int TestHyperTreeGrid3DAxisCutCoincidentPlane(int argc, char* argv[]) +{ + // Read HTG test data + std::string filename = + vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/HTG/htg_for_axis_aligned_cut.htg"); + vtkNew<vtkXMLHyperTreeGridReader> htgReader; + htgReader->SetFileName(filename.c_str()); + htgReader->Update(); + + // Compute HTG bounds + vtkHyperTreeGrid* htg = htgReader->GetOutput(); + if (!htg) + { + cerr << "Unable to read input HTG (" + filename + ")"; + return EXIT_FAILURE; + } + std::array<double, 6> bounds; + htg->GetBounds(bounds.data()); + + // Define test plane positions + std::array<double, 4> planePositions = { + 0.014799999999999994, // Coincident, inside the HTG + bounds[1] + std::numeric_limits<double>::epsilon() * 0.5, // Coincident, htg boundary + bounds[1] + std::numeric_limits<double>::epsilon(), // Outside + bounds[0], // Outside + }; + + std::array<double, 4> expectedNbOfCutCells = { 110, 11, 0, 0 }; + std::array<vtkSmartPointer<vtkHyperTreeGrid>, 4> cuts; + + vtkNew<vtkHyperTreeGridAxisCut> cutter; + cutter->SetInputData(htg); + cutter->SetPlaneNormalAxis(0); // X + + // Test cut results + for (unsigned int i = 0; i < 4; i++) + { + cutter->SetPlanePosition(planePositions[i]); + cutter->Update(); + + vtkHyperTreeGrid* cut = cutter->GetHyperTreeGridOutput(); + if (!cut) + { + std::cerr << "Unable to retrieve the HTG cut " << i << "." << endl; + return EXIT_FAILURE; + } + if (cut->GetNumberOfCells() != expectedNbOfCutCells[i]) + { + cerr << "Wrong number of cells in the HTG slice. Expected 110, got " + << cut->GetNumberOfCells() << endl; + return EXIT_FAILURE; + } + + // Store cut + cuts[i] = vtkSmartPointer<vtkHyperTreeGrid>::New(); + cuts[i]->DeepCopy(cut); + } + + // Geometry + vtkNew<vtkOutlineSource> htgOutline; + htgOutline->SetBounds(bounds.data()); + vtkNew<vtkHyperTreeGridGeometry> geometryCutIn; + geometryCutIn->SetInputData(cuts[0]); + vtkNew<vtkHyperTreeGridGeometry> geometryCutOut; + geometryCutOut->SetInputData(cuts[1]); + + // Mappers + vtkMapper::SetResolveCoincidentTopologyToPolygonOffset(); + vtkNew<vtkDataSetMapper> mapperCutIn; + mapperCutIn->SetInputConnection(geometryCutIn->GetOutputPort()); + vtkNew<vtkDataSetMapper> mapperCutBound; + mapperCutBound->SetInputConnection(geometryCutOut->GetOutputPort()); + vtkNew<vtkDataSetMapper> mapperHTG; + mapperHTG->SetInputConnection(htgOutline->GetOutputPort()); + + // Actors + vtkNew<vtkActor> actorCutIn; + actorCutIn->SetMapper(mapperCutIn); + actorCutIn->GetProperty()->SetRepresentationToSurface(); + actorCutIn->GetProperty()->SetEdgeVisibility(true); + vtkNew<vtkActor> actorCutBound; + actorCutBound->SetMapper(mapperCutBound); + actorCutBound->GetProperty()->SetRepresentationToSurface(); + actorCutBound->GetProperty()->SetEdgeVisibility(true); + vtkNew<vtkActor> actorHTG; + actorHTG->SetMapper(mapperHTG); + + // Camera + vtkNew<vtkCamera> camera; + camera->SetPosition(.5, .5, 0.); + + // Renderer + vtkNew<vtkRenderer> renderer; + renderer->SetActiveCamera(camera); + renderer->AddActor(actorCutIn); + renderer->AddActor(actorCutBound); + renderer->AddActor(actorHTG); + renderer->ResetCamera(); + + // Render window + vtkNew<vtkRenderWindow> renWin; + renWin->AddRenderer(renderer); + renWin->SetSize(400, 400); + renWin->SetMultiSamples(0); + + // Interactor + vtkNew<vtkRenderWindowInteractor> iren; + iren->SetRenderWindow(renWin); + + // Render and test against baseline + renWin->Render(); + int retVal = vtkRegressionTestImageThreshold(renWin, 0.05); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + iren->Start(); + } + else if (retVal == vtkRegressionTester::FAILED) + { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/Filters/HyperTree/Testing/Data/Baseline/TestHyperTreeGrid3DAxisCutCoincidentPlane.png.sha512 b/Filters/HyperTree/Testing/Data/Baseline/TestHyperTreeGrid3DAxisCutCoincidentPlane.png.sha512 new file mode 100644 index 00000000000..e33016a2571 --- /dev/null +++ b/Filters/HyperTree/Testing/Data/Baseline/TestHyperTreeGrid3DAxisCutCoincidentPlane.png.sha512 @@ -0,0 +1 @@ +dcbb8448789801e79ea8dbf9ad4c7c908dc1f3d85d8512ea18041d6c32cf94a85aa74778f75b26eaca8a4691ee71413420228352ae6118591842a9cebba72370 diff --git a/Testing/Data/HTG/htg_for_axis_aligned_cut.htg.sha512 b/Testing/Data/HTG/htg_for_axis_aligned_cut.htg.sha512 new file mode 100644 index 00000000000..cff670cbf12 --- /dev/null +++ b/Testing/Data/HTG/htg_for_axis_aligned_cut.htg.sha512 @@ -0,0 +1 @@ +c56d68404de41e13ccc4f063cb24ca94ab78195394ce1fac6cccf5ae005efdbc88001ebaac030a7cf7bdc2a5a8800f16e2910ce79d0bbe7e82d2d99a7659bd15 -- GitLab