diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ComputeTriangleGeomShapes.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ComputeTriangleGeomShapes.cpp index 082b9a8a07..7486104452 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ComputeTriangleGeomShapes.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ComputeTriangleGeomShapes.cpp @@ -400,4 +400,3 @@ void ComputeTriangleGeomShapes::findAxisEulers() axisEulerAngles[3 * i + 2] = euler[2]; } } - diff --git a/src/Plugins/OrientationAnalysis/test/CMakeLists.txt b/src/Plugins/OrientationAnalysis/test/CMakeLists.txt index aa13c0a38d..8729c9ee5d 100644 --- a/src/Plugins/OrientationAnalysis/test/CMakeLists.txt +++ b/src/Plugins/OrientationAnalysis/test/CMakeLists.txt @@ -31,7 +31,7 @@ set(${PLUGIN_NAME}UnitTest_SRCS ComputeSchmidsTest.cpp ComputeShapesFilterTest.cpp ComputeSlipTransmissionMetricsTest.cpp - # ComputeTriangleGeomShapesTest.cpp + ComputeTriangleGeomShapesTest.cpp ConvertHexGridToSquareGridTest.cpp ConvertOrientationsTest.cpp ConvertQuaternionTest.cpp diff --git a/src/Plugins/OrientationAnalysis/test/ComputeTriangleGeomShapesTest.cpp b/src/Plugins/OrientationAnalysis/test/ComputeTriangleGeomShapesTest.cpp index 473efe0c44..776e6659df 100644 --- a/src/Plugins/OrientationAnalysis/test/ComputeTriangleGeomShapesTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/ComputeTriangleGeomShapesTest.cpp @@ -8,15 +8,22 @@ #include +#include +#include +#include + +namespace fs = std::filesystem; + using namespace nx::core; using namespace nx::core::UnitTest; +#define SIMPLNX_WRITE_TEST_OUTPUT + namespace ComputeTriangleGeomShapesFilterTest { -const std::string k_TriangleGeometryName = "TriangleDataContainer"; -const std::string k_FaceLabelsName = "FaceLabels"; -const std::string k_FaceFeatureName = "FaceFeatureData"; -const std::string k_FaceDataName = "FaceData"; +const std::string k_FaceLabelsName = "Face Labels"; +const std::string k_FaceFeatureName = "Face Feature Data"; +const std::string k_FaceDataName = "Face Data"; const std::string k_CentroidsArrayName = "Centroids"; const std::string k_VolumesArrayName = "Volumes"; @@ -25,11 +32,31 @@ const std::string k_AxisLengthsArrayName = "AxisLengths [NX Computed]"; const std::string k_AxisEulerAnglesArrayName = "AxisEulerAngles [NX Computed]"; const std::string k_AspectRatiosArrayName = "AspectRatios [NX Computed]"; -const DataPath k_GeometryPath = DataPath({k_TriangleGeometryName}); -const DataPath k_FaceFeatureAttributeMatrixPath = k_GeometryPath.createChildPath(k_FaceFeatureName); -const DataPath k_FaceLabelsPath = k_GeometryPath.createChildPath(k_FaceDataName).createChildPath(k_FaceLabelsName); -const DataPath k_FaceFeatureCentroidsPath = k_FaceFeatureAttributeMatrixPath.createChildPath(k_CentroidsArrayName); -const DataPath k_FaceFeatureVolumesPath = k_FaceFeatureAttributeMatrixPath.createChildPath(k_VolumesArrayName); +// const DataPath k_FaceFeatureAttributeMatrixPath = k_GeometryPath.createChildPath(k_FaceFeatureName); +// const DataPath k_FaceLabelsPath = k_GeometryPath.createChildPath(k_FaceDataName).createChildPath(k_FaceLabelsName); +// const DataPath k_FaceFeatureCentroidsPath = k_FaceFeatureAttributeMatrixPath.createChildPath(k_CentroidsArrayName); +// const DataPath k_FaceFeatureVolumesPath = k_FaceFeatureAttributeMatrixPath.createChildPath(k_VolumesArrayName); + +constexpr float32 k_Sphere_Omega_3 = 2193.245f; // 1.00000 + +constexpr float32 k_Tetrahedron_Omega_3 = 888.889f / k_Sphere_Omega_3; +constexpr float32 k_Cube_Omega_3 = 1728.0f / k_Sphere_Omega_3; // 0.787873675763538 +constexpr float32 k_Octahedron_Omega_3 = 1777.778f / k_Sphere_Omega_3; // 0.810569726592332 +constexpr float32 k_Dodecahedron_Omega_3 = 2096.873f / k_Sphere_Omega_3; // 0.956059628541271 +constexpr float32 k_Icosahedron_Omega_3 = 2122.033f / k_Sphere_Omega_3; // 0.967531215162921 +constexpr float32 k_TriangularPyramid_Omega_3 = 888.889f / k_Sphere_Omega_3; // 0.405284863296166 +constexpr float32 k_Rectangular_Prism_Omega_3 = 1728.0f / k_Sphere_Omega_3; // 0.787873675763538 +constexpr float32 k_Circular_Cylinder_Omega_3 = 1894.964f / k_Sphere_Omega_3; // 0.864000145902533 +constexpr float32 k_Ellipsoid_Omega_3 = 2193.245f / k_Sphere_Omega_3; // 1.000 + +const std::string k_TestFileDirName = "7_Triangle_Shapes_Files/stl_exemplar"; +std::vector k_TestFileNames = {"10_octahedron", "11_pyramid_elongated", "20_sphere", "21_ellipsoid", "40_rounded_cube", "41_rounded_cube_elongated", + "50_cube", "51_rectangular_prism", "60_Cylinder", "70_Dodecahedron", "80_Icosahedron", "90_tetrahedron"}; + +std::vector k_Theoretical_Omega_3_Values = { + k_Octahedron_Omega_3, k_Octahedron_Omega_3, 1.0f, k_Ellipsoid_Omega_3, 0.907957, 0.907945, k_Cube_Omega_3, k_Rectangular_Prism_Omega_3, k_Circular_Cylinder_Omega_3, k_Dodecahedron_Omega_3, + k_Icosahedron_Omega_3, k_Tetrahedron_Omega_3}; + } // namespace ComputeTriangleGeomShapesFilterTest using namespace ComputeTriangleGeomShapesFilterTest; @@ -37,54 +64,54 @@ using namespace ComputeTriangleGeomShapesFilterTest; TEST_CASE("OrientationAnalysis::ComputeTriangleGeomShapes", "[OrientationAnalysis][ComputeTriangleGeomShapes]") { Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); - - const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "12_IN625_GBCD.tar.gz", "12_IN625_GBCD"); - - // Read Exemplar DREAM3D File Filter - auto exemplarFilePath = fs::path(fmt::format("{}/12_IN625_GBCD/12_IN625_GBCD.dream3d", unit_test::k_TestFilesDir)); - DataStructure dataStructure = LoadDataStructure(exemplarFilePath); - + const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "7_Triangle_Shapes_Files.tar.gz", "7_Triangle_Shapes_Files"); + usize index = 0; + for(const auto& fileName : k_TestFileNames) { - // Instantiate the filter and an Arguments Object - ComputeTriangleGeomShapesFilter filter; - Arguments args; - - // Create default Parameters for the filter. - args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_TriGeometryDataPath_Key, std::make_any(k_GeometryPath)); - args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_FaceLabelsArrayPath_Key, std::make_any(k_FaceLabelsPath)); - - args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_FeatureAttributeMatrixPath_Key, std::make_any(k_FaceFeatureAttributeMatrixPath)); - args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_CentroidsArrayPath_Key, std::make_any(k_FaceFeatureCentroidsPath)); - args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_VolumesArrayPath_Key, std::make_any(k_FaceFeatureVolumesPath)); - // Output Vars - args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_Omega3sArrayName_Key, std::make_any(k_Omega3SArrayName)); - args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_AxisLengthsArrayName_Key, std::make_any(k_AxisLengthsArrayName)); - args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_AxisEulerAnglesArrayName_Key, std::make_any(k_AxisEulerAnglesArrayName)); - args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_AspectRatiosArrayName_Key, std::make_any(k_AspectRatiosArrayName)); - - // Preflight the filter and check result - auto preflightResult = filter.preflight(dataStructure, args); - SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); - - // Execute the filter and check the result - auto executeResult = filter.execute(dataStructure, args); - SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result); - } - - std::vector outputArrayNames = {k_Omega3SArrayName, k_AxisLengthsArrayName, k_AxisEulerAnglesArrayName, k_AspectRatiosArrayName}; - std::vector exemplarArrayNames = {"Omega3s", "AxisLengths", "AxisEulerAngles", "AspectRatios"}; - for(usize i = 0; i < 4; i++) - { - const DataPath kExemplarArrayPath = k_FaceFeatureAttributeMatrixPath.createChildPath(exemplarArrayNames[i]); - const DataPath kNxArrayPath = k_FaceFeatureAttributeMatrixPath.createChildPath(outputArrayNames[i]); - - const auto& kExemplarsArray = dataStructure.getDataRefAs(kExemplarArrayPath); - const auto& kNxArray = dataStructure.getDataRefAs(kNxArrayPath); - - UnitTest::CompareDataArrays(kExemplarsArray, kNxArray); - } + // Read Exemplar DREAM3D File Filter + auto exemplarFilePath = fs::path(fmt::format("{}/{}/{}.dream3d", nx::core::unit_test::k_TestFilesDir, k_TestFileDirName, fileName)); + // std::cout << "Loading File: " << exemplarFilePath.string() << "\n"; + DataStructure dataStructure = UnitTest::LoadDataStructure(exemplarFilePath); + + DataPath geometryPath({fileName}); + DataPath faceDataPath = geometryPath.createChildPath(k_FaceDataName); + DataPath faceFeatureDataPath = geometryPath.createChildPath(k_FaceFeatureName); + + { + // Instantiate the filter and an Arguments Object + ComputeTriangleGeomShapesFilter filter; + Arguments args; + + // Create default Parameters for the filter. + args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_TriGeometryDataPath_Key, std::make_any(geometryPath)); + args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_FaceLabelsArrayPath_Key, std::make_any(faceDataPath.createChildPath(k_FaceLabelsName))); + + args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_FeatureAttributeMatrixPath_Key, std::make_any(faceFeatureDataPath)); + args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_CentroidsArrayPath_Key, std::make_any(faceFeatureDataPath.createChildPath(k_CentroidsArrayName))); + args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_VolumesArrayPath_Key, std::make_any(faceFeatureDataPath.createChildPath(k_VolumesArrayName))); + // Output Vars + args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_Omega3sArrayName_Key, std::make_any(k_Omega3SArrayName)); + args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_AxisLengthsArrayName_Key, std::make_any(k_AxisLengthsArrayName)); + args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_AxisEulerAnglesArrayName_Key, std::make_any(k_AxisEulerAnglesArrayName)); + args.insertOrAssign(ComputeTriangleGeomShapesFilter::k_AspectRatiosArrayName_Key, std::make_any(k_AspectRatiosArrayName)); + + // Preflight the filter and check result + auto preflightResult = filter.preflight(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(preflightResult.outputActions); + + // Execute the filter and check the result + auto executeResult = filter.execute(dataStructure, args); + SIMPLNX_RESULT_REQUIRE_VALID(executeResult.result); + } #ifdef SIMPLNX_WRITE_TEST_OUTPUT - WriteTestDataStructure(dataStructure, fs::path(fmt::format("{}/find_triangle_geom_shapes.dream3d", unit_test::k_BinaryTestOutputDir))); + WriteTestDataStructure(dataStructure, fs::path(fmt::format("{}/{}.dream3d", unit_test::k_BinaryTestOutputDir, fileName))); #endif + + const auto& computedOmega3 = dataStructure.getDataRefAs(faceFeatureDataPath.createChildPath(k_Omega3SArrayName)); + float32 diff = std::abs(computedOmega3[1] - k_Theoretical_Omega_3_Values[index]); + // std::cout << fileName << ": Omega-3 Computed: " << computedOmega3[1] << " Theoretical Value: " << k_Theoretical_Omega_3_Values[index] << " Diff: " << diff << "\n"; + REQUIRE(diff < 1.0E-4); + index++; + } } diff --git a/src/Plugins/OrientationAnalysis/test/MergeTwinsTest.cpp b/src/Plugins/OrientationAnalysis/test/MergeTwinsTest.cpp index fd0baea0b5..1b78b0bf7a 100644 --- a/src/Plugins/OrientationAnalysis/test/MergeTwinsTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/MergeTwinsTest.cpp @@ -23,8 +23,6 @@ TEST_CASE("Reconstruction::MergeTwinsFilter: Valid Execution", "[Reconstruction] const nx::core::UnitTest::TestFileSentinel testDataSentinel(nx::core::unit_test::k_CMakeExecutable, nx::core::unit_test::k_TestFilesDir, "neighbor_orientation_correlation.tar.gz", "neighbor_orientation_correlation.dream3d"); - - Application::GetOrCreateInstance()->loadPlugins(unit_test::k_BuildDir.view(), true); auto* filterList = Application::Instance()->getFilterList(); // Make sure we can load the needed filters from the plugins