From 6cdb023ca58055b4647b1db782e5b303bdb5940a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 24 Nov 2024 12:18:05 -0500 Subject: [PATCH] BUG: Fixes issue where any component shape was allowed for ComputeTriangleGeometrySizes (#1134) * BUG: Fixes issue where any component shape were allowed for ComputeTriangleGeometrySizes.cpp * Fix all instances of "Face Labels" are only allowed to use 2 component input arrays * ComputeTriangleGeomVolumes - fix possible walking off the end of the array. A negative value for the face label when used as an index will cast into an unsigned value and bad things are going to happen. * BUG: Fixes negative volumes produced from calculations --------- Signed-off-by: Michael Jackson --- .../Filters/ComputeTriangleAreasFilter.cpp | 58 ++++++++++++++++++- .../Filters/TriangleNormalFilter.cpp | 58 ++++++++++++++++++- src/simplnx/Utilities/GeometryUtilities.cpp | 1 - 3 files changed, 111 insertions(+), 6 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeTriangleAreasFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeTriangleAreasFilter.cpp index 8a67e51eee..e2c962c486 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeTriangleAreasFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/ComputeTriangleAreasFilter.cpp @@ -8,17 +8,64 @@ #include "simplnx/Parameters/DataGroupSelectionParameter.hpp" #include "simplnx/Parameters/DataObjectNameParameter.hpp" #include "simplnx/Parameters/GeometrySelectionParameter.hpp" -#include "simplnx/Utilities/GeometryUtilities.hpp" #include "simplnx/Utilities/Math/MatrixMath.hpp" -#include "simplnx/Utilities/ParallelDataAlgorithm.hpp" + #include "simplnx/Utilities/SIMPLConversion.hpp" +#include "simplnx/Utilities/ParallelDataAlgorithm.hpp" + using namespace nx::core; namespace { constexpr nx::core::int32 k_MissingFeatureAttributeMatrix = -75769; +/** + * @brief The CalculateAreasImpl class implements a threaded algorithm that computes the area of each + * triangle for a set of triangles + */ +class CalculateAreasImpl +{ +public: + CalculateAreasImpl(const TriangleGeom* triangleGeom, Float64AbstractDataStore& areas, const std::atomic_bool& shouldCancel) + : m_TriangleGeom(triangleGeom) + , m_Areas(areas) + , m_ShouldCancel(shouldCancel) + { + } + virtual ~CalculateAreasImpl() = default; + + void convert(size_t start, size_t end) const + { + std::array cross = {0.0f, 0.0f, 0.0f}; + for(size_t triangleIndex = start; triangleIndex < end; triangleIndex++) + { + if(m_ShouldCancel) + { + break; + } + std::array vertCoords; + m_TriangleGeom->getFaceCoordinates(triangleIndex, vertCoords); + + auto vecA = (vertCoords[0] - vertCoords[1]).toArray(); + auto vecB = (vertCoords[0] - vertCoords[2]).toArray(); + + MatrixMath::CrossProduct(vecA.data(), vecB.data(), cross.data()); + + m_Areas[triangleIndex] = 0.5F * MatrixMath::Magnitude3x1(cross.data()); + } + } + + void operator()(const Range& range) const + { + convert(range.min(), range.max()); + } + +private: + const TriangleGeom* m_TriangleGeom = nullptr; + Float64AbstractDataStore& m_Areas; + const std::atomic_bool& m_ShouldCancel; +}; } // namespace namespace nx::core @@ -126,7 +173,12 @@ Result<> ComputeTriangleAreasFilter::executeImpl(DataStructure& dataStructure, c DataPath pCalculatedAreasDataPath = pTriangleGeometryDataPath.createChildPath(faceAttributeMatrix->getName()).createChildPath(pCalculatedAreasName); auto& faceAreas = dataStructure.getDataAs(pCalculatedAreasDataPath)->getDataStoreRef(); - return nx::core::GeometryUtilities::ComputeTriangleAreas(triangleGeom, faceAreas, shouldCancel); + // Parallel algorithm to find duplicate nodes + ParallelDataAlgorithm dataAlg; + dataAlg.setRange(0ULL, static_cast(triangleGeom->getNumberOfFaces())); + dataAlg.execute(CalculateAreasImpl(triangleGeom, faceAreas, shouldCancel)); + + return {}; } namespace diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/TriangleNormalFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/TriangleNormalFilter.cpp index 7f2e5061e2..336bd8f20f 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/TriangleNormalFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/TriangleNormalFilter.cpp @@ -7,7 +7,6 @@ #include "simplnx/Parameters/DataGroupSelectionParameter.hpp" #include "simplnx/Parameters/DataObjectNameParameter.hpp" #include "simplnx/Parameters/GeometrySelectionParameter.hpp" -#include "simplnx/Utilities/GeometryUtilities.hpp" #include "simplnx/Utilities/Math/MatrixMath.hpp" #include "simplnx/Utilities/ParallelDataAlgorithm.hpp" #include "simplnx/Utilities/SIMPLConversion.hpp" @@ -19,6 +18,56 @@ namespace constexpr nx::core::int32 k_MissingFeatureAttributeMatrix = -75969; +/** + * @brief The CalculateAreasImpl class implements a threaded algorithm that computes the normal of each + * triangle for a set of triangles + */ +class CalculateNormalsImpl +{ +public: + CalculateNormalsImpl(const TriangleGeom* triangleGeom, Float64AbstractDataStore& normals, const std::atomic_bool& shouldCancel) + : m_TriangleGeom(triangleGeom) + , m_Normals(normals) + , m_ShouldCancel(shouldCancel) + { + } + virtual ~CalculateNormalsImpl() = default; + + void generate(size_t start, size_t end) const + { + std::array normal = {0.0f, 0.0f, 0.0f}; + for(size_t triangleIndex = start; triangleIndex < end; triangleIndex++) + { + + if(m_ShouldCancel) + { + break; + } + std::array vertCoords; + m_TriangleGeom->getFaceCoordinates(triangleIndex, vertCoords); + + auto vecA = (vertCoords[1] - vertCoords[0]).toArray(); + auto vecB = (vertCoords[2] - vertCoords[0]).toArray(); + + MatrixMath::CrossProduct(vecA.data(), vecB.data(), normal.data()); + MatrixMath::Normalize3x1(normal.data()); + + m_Normals[triangleIndex * 3] = static_cast(normal[0]); + m_Normals[triangleIndex * 3 + 1] = static_cast(normal[1]); + m_Normals[triangleIndex * 3 + 2] = static_cast(normal[2]); + } + } + + void operator()(const Range& range) const + { + generate(range.min(), range.max()); + } + +private: + const TriangleGeom* m_TriangleGeom = nullptr; + Float64AbstractDataStore& m_Normals; + const std::atomic_bool& m_ShouldCancel; +}; } // namespace namespace nx::core @@ -123,7 +172,12 @@ Result<> TriangleNormalFilter::executeImpl(DataStructure& dataStructure, const A DataPath pNormalsArrayPath = pTriangleGeometryDataPath.createChildPath(faceAttributeMatrix->getName()).createChildPath(pNormalsName); auto& normals = dataStructure.getDataAs(pNormalsArrayPath)->getDataStoreRef(); - return nx::core::GeometryUtilities::ComputeTriangleNormals(triangleGeom, normals, shouldCancel); + // Parallel algorithm to find duplicate nodes + ParallelDataAlgorithm dataAlg; + dataAlg.setRange(0ULL, static_cast(triangleGeom->getNumberOfFaces())); + dataAlg.execute(CalculateNormalsImpl(triangleGeom, normals, shouldCancel)); + + return {}; } namespace diff --git a/src/simplnx/Utilities/GeometryUtilities.cpp b/src/simplnx/Utilities/GeometryUtilities.cpp index 74ef30b406..af8a90c25c 100644 --- a/src/simplnx/Utilities/GeometryUtilities.cpp +++ b/src/simplnx/Utilities/GeometryUtilities.cpp @@ -2,7 +2,6 @@ #include "simplnx/Common/Array.hpp" #include "simplnx/Common/Result.hpp" -#include "simplnx/Utilities/Math/MatrixMath.hpp" using namespace nx::core;