diff --git a/src/Plugins/SimplnxCore/CMakeLists.txt b/src/Plugins/SimplnxCore/CMakeLists.txt index 2dae27cb3b..0f0e589ec2 100644 --- a/src/Plugins/SimplnxCore/CMakeLists.txt +++ b/src/Plugins/SimplnxCore/CMakeLists.txt @@ -155,6 +155,7 @@ set(AlgorithmList ExecuteProcess ExtractComponentAsArray ExtractVertexGeometry + FeatureFaceCurvature FillBadData FindArrayStatistics FindBiasedFeatures diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.cpp index c8dae5ea9d..8938c9c0ef 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.cpp @@ -46,12 +46,13 @@ namespace nx::core { // ----------------------------------------------------------------------------- -CalculateTriangleGroupCurvatures::CalculateTriangleGroupCurvatures(int64_t nring, std::vector triangleIds, bool useNormalsForCurveFitting, Float64Array* principleCurvature1, - Float64Array* principleCurvature2, Float64Array* principleDirection1, Float64Array* principleDirection2, - Float64Array* gaussianCurvature, Float64Array* meanCurvature, Float64Array* weingartenMatrix, TriangleGeom* trianglesGeom, - Int32Array* surfaceMeshFaceLabels, Float64Array* surfaceMeshFaceNormals, Float64Array* surfaceMeshTriangleCentroids, - const IFilter::MessageHandler& messageHandler, const std::atomic_bool& shouldCancel) -: m_NRing(nring) +CalculateTriangleGroupCurvatures::CalculateTriangleGroupCurvatures(FeatureFaceCurvature* filter, int64_t nring, std::vector triangleIds, bool useNormalsForCurveFitting, + Float64Array* principleCurvature1, Float64Array* principleCurvature2, Float64Array* principleDirection1, + Float64Array* principleDirection2, Float64Array* gaussianCurvature, Float64Array* meanCurvature, Float64Array* weingartenMatrix, + TriangleGeom* trianglesGeom, Int32Array* surfaceMeshFaceLabels, Float64Array* surfaceMeshFaceNormals, + Float64Array* surfaceMeshTriangleCentroids, const IFilter::MessageHandler& messageHandler, const std::atomic_bool& shouldCancel) +: m_Filter(filter) +, m_NRing(nring) , m_TriangleIds(triangleIds) , m_UseNormalsForCurveFitting(useNormalsForCurveFitting) , m_PrincipleCurvature1(principleCurvature1) @@ -327,7 +328,7 @@ void CalculateTriangleGroupCurvatures::operator()() const } // End Loop over this triangle // Send some feedback - m_MessageHandler(fmt::format("Progress: {} / {}", m_TriangleIds.size(), tCount)); + m_Filter->sendThreadSafeProgressMessage(1); } // ----------------------------------------------------------------------------- diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.hpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.hpp index 45c3d6dfbd..4ff73f0c34 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.hpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.hpp @@ -41,10 +41,9 @@ #include "simplnx/DataStructure/Geometry/TriangleGeom.hpp" #include "simplnx/Filter/IFilter.hpp" +#include "SimplnxCore/Filters/Algorithms/FeatureFaceCurvature.hpp" #include "SimplnxCore/SimplnxCore_export.hpp" -class FeatureFaceCurvatureFilter; - namespace nx::core { /** @@ -55,10 +54,10 @@ namespace nx::core class SIMPLNXCORE_EXPORT CalculateTriangleGroupCurvatures { public: - CalculateTriangleGroupCurvatures(int64_t nring, std::vector triangleIds, bool useNormalsForCurveFitting, Float64Array* principleCurvature1, Float64Array* principleCurvature2, - Float64Array* principleDirection1, Float64Array* principleDirection2, Float64Array* gaussianCurvature, Float64Array* meanCurvature, Float64Array* weingartenMatrix, - TriangleGeom* trianglesGeom, Int32Array* surfaceMeshFaceLabels, Float64Array* surfaceMeshFaceNormals, Float64Array* surfaceMeshTriangleCentroids, - const IFilter::MessageHandler& messageHandler, const std::atomic_bool& shouldCancel); + CalculateTriangleGroupCurvatures(FeatureFaceCurvature* filter, int64_t nring, std::vector triangleIds, bool useNormalsForCurveFitting, Float64Array* principleCurvature1, + Float64Array* principleCurvature2, Float64Array* principleDirection1, Float64Array* principleDirection2, Float64Array* gaussianCurvature, + Float64Array* meanCurvature, Float64Array* weingartenMatrix, TriangleGeom* trianglesGeom, Int32Array* surfaceMeshFaceLabels, Float64Array* surfaceMeshFaceNormals, + Float64Array* surfaceMeshTriangleCentroids, const IFilter::MessageHandler& messageHandler, const std::atomic_bool& shouldCancel); virtual ~CalculateTriangleGroupCurvatures(); @@ -77,6 +76,7 @@ class SIMPLNXCORE_EXPORT CalculateTriangleGroupCurvatures std::shared_ptr extractPatchData(int64_t triId, UniqueFaceIds_t& triPatch, Float64AbstractDataStore& data) const; private: + FeatureFaceCurvature* m_Filter = nullptr; int64_t m_NRing; std::vector m_TriangleIds; bool m_UseNormalsForCurveFitting; diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/FeatureFaceCurvature.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/FeatureFaceCurvature.cpp new file mode 100644 index 0000000000..dc4bef877e --- /dev/null +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/FeatureFaceCurvature.cpp @@ -0,0 +1,158 @@ +#include "FeatureFaceCurvature.hpp" + +#include "SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.hpp" +#include "SimplnxCore/Filters/Algorithms/FindNRingNeighbors.hpp" + +#include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/Utilities/ParallelTaskAlgorithm.hpp" + +#include "fmt/format.h" + +using namespace nx::core; + +using FaceIds_t = std::vector; +using SharedFeatureFaces_t = std::map; + +// ----------------------------------------------------------------------------- +FeatureFaceCurvature::FeatureFaceCurvature(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, FeatureFaceCurvatureInputValues* inputValues) +: m_DataStructure(dataStructure) +, m_InputValues(inputValues) +, m_ShouldCancel(shouldCancel) +, m_MessageHandler(mesgHandler) +{ +} + +// ----------------------------------------------------------------------------- +FeatureFaceCurvature::~FeatureFaceCurvature() noexcept = default; + +// ----------------------------------------------------------------------------- +const std::atomic_bool& FeatureFaceCurvature::getCancel() +{ + return m_ShouldCancel; +} + +// ----------------------------------------------------------------------------- +Result<> FeatureFaceCurvature::operator()() +{ + + // Get DataObjects + auto* surfaceMeshPrincipalCurvature1sArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshPrincipalCurvature1sPath); + auto* surfaceMeshPrincipalCurvature2sArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshPrincipalCurvature2sPath); + auto* surfaceMeshPrincipalDirection1sArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshPrincipalDirection1sPath); + auto* surfaceMeshPrincipalDirection2sArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshPrincipalDirection2sPath); + auto* surfaceMeshMeanCurvaturesArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshMeanCurvaturesPath); + auto* surfaceMeshGaussianCurvaturesArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshGaussianCurvaturesPath); + auto* surfaceMeshFaceLabelsArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshFaceLabelsPath); + auto* surfaceMeshFaceNormalsArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshFaceNormalsPath); + auto* surfaceMeshTriangleCentroidsArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshTriangleCentroidsPath); + auto* surfaceMeshWeingartenMatrixArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshWeingartenMatrixPath); + + auto* triangleGeomPtr = m_DataStructure.getDataAs(m_InputValues->triangleGeomPath); + auto* surfaceMeshFeatureFaceIdsArrayPtr = m_DataStructure.getDataAs(m_InputValues->surfaceMeshFeatureFaceIdsPath); + auto& surfaceMeshFeatureFaceIds = surfaceMeshFeatureFaceIdsArrayPtr->getDataStoreRef(); + + // Just to double-check we have everything. + auto numTriangles = static_cast(triangleGeomPtr->getNumberOfFaces()); + + // Make sure the Face Connectivity is created because the FindNRing algorithm needs this and will + // assert if the data is NOT in the SurfaceMesh Data Container + const IGeometry::ElementDynamicList* vertLinks = triangleGeomPtr->getElementsContainingVert(); + if(nullptr == vertLinks) + { + triangleGeomPtr->findElementsContainingVert(); + } + + int32_t maxFaceId = 0; + for(int64_t t = 0; t < numTriangles; ++t) + { + if(surfaceMeshFeatureFaceIds[t] > maxFaceId) + { + maxFaceId = surfaceMeshFeatureFaceIds[t]; + } + } + + std::vector faceSizes(maxFaceId + 1, 0); + // Loop through all the Triangles and assign each one to a unique Feature Face Id. + for(int64_t t = 0; t < numTriangles; ++t) + { + faceSizes[surfaceMeshFeatureFaceIds[t]]++; + } + + SharedFeatureFaces_t sharedFeatureFaces; + // Allocate all the vectors that we need + for(size_t iter = 0; iter < faceSizes.size(); ++iter) + { + FaceIds_t v; + v.reserve(faceSizes[iter]); + sharedFeatureFaces[static_cast(iter)] = v; + } + + // Loop through all the Triangles and assign each one to a unique Feature Face Id. + for(int64_t t = 0; t < numTriangles; ++t) + { + sharedFeatureFaces[surfaceMeshFeatureFaceIds[t]].push_back(t); + } + +/********************************* + * We are going to specifically invoke TBB directly instead of using ParallelTaskAlgorithm since we can just queue up all + * the tasks while the first tasks start up. TBB will then grab a new task from it's own queue to work on it up to the + * number of hardware limit of the machine. If we use ParallelTaskAlgorithm then at most we can only work on the number + * of tasks that equal the number of cores on the machine. We spend a lot of overhead spinning up new threads to do each + * task. This takes much longer (3x longer) in some cases. + */ +#ifdef SIMPLNX_ENABLE_MULTICORE + std::shared_ptr g(new tbb::task_group); + m_MessageHandler(fmt::format("Adding {} Feature Faces to the work queue....", maxFaceId)); +#else + +#endif + m_TotalElements = sharedFeatureFaces.size(); + + for(auto& sharedFeatureFace : sharedFeatureFaces) + { + FaceIds_t& triangleIds = sharedFeatureFace.second; + + CalculateTriangleGroupCurvatures func(this, m_InputValues->NRingCount, triangleIds, m_InputValues->useNormalsForCurveFitting, surfaceMeshPrincipalCurvature1sArrayPtr, + surfaceMeshPrincipalCurvature2sArrayPtr, surfaceMeshPrincipalDirection1sArrayPtr, surfaceMeshPrincipalDirection2sArrayPtr, + surfaceMeshGaussianCurvaturesArrayPtr, surfaceMeshMeanCurvaturesArrayPtr, surfaceMeshWeingartenMatrixArrayPtr, triangleGeomPtr, surfaceMeshFaceLabelsArrayPtr, + surfaceMeshFaceNormalsArrayPtr, surfaceMeshTriangleCentroidsArrayPtr, m_MessageHandler, m_ShouldCancel); + +#ifdef SIMPLNX_ENABLE_MULTICORE + { + g->run(func); + } +#else + m_MessageHandler(fmt::format("Working on Face Id {}/{}", std::to_string((sharedFeatureFace).first), std::to_string(maxFaceId))); + { + func(); + } +#endif + } + +#ifdef SIMPLNX_ENABLE_MULTICORE + m_MessageHandler(fmt::format("Waiting on computations to complete.")); + g->wait(); // Wait for all the threads to complete before moving on. +#endif + + return {}; +} + +// ----------------------------------------------------------------------------- +void FeatureFaceCurvature::sendThreadSafeProgressMessage(usize counter) +{ + std::lock_guard guard(m_ProgressMessage_Mutex); + + m_ProgressCounter += counter; + auto now = std::chrono::steady_clock::now(); + if(std::chrono::duration_cast(now - m_InitialPoint).count() < 1000) + { + return; + } + + auto progressInt = static_cast((static_cast(m_ProgressCounter) / static_cast(m_TotalElements)) * 100.0f); + std::string ss = fmt::format("{}/{}", m_ProgressCounter, m_TotalElements); + m_MessageHandler(IFilter::Message::Type::Info, ss); + + m_LastProgressInt = progressInt; + m_InitialPoint = std::chrono::steady_clock::now(); +} diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/FeatureFaceCurvature.hpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/FeatureFaceCurvature.hpp new file mode 100644 index 0000000000..c1777de66b --- /dev/null +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/FeatureFaceCurvature.hpp @@ -0,0 +1,69 @@ + +#pragma once + +#include "SimplnxCore/SimplnxCore_export.hpp" + +#include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" +#include "simplnx/Filter/IFilter.hpp" + +namespace nx::core +{ + +struct SIMPLNXCORE_EXPORT FeatureFaceCurvatureInputValues +{ + int64 NRingCount = 0; + DataPath triangleGeomPath; + DataPath surfaceMeshPrincipalCurvature1Path; + DataPath surfaceMeshFeatureFaceIdsPath; + DataPath surfaceMeshFaceLabelsPath; + DataPath surfaceMeshFaceNormalsPath; + DataPath surfaceMeshTriangleCentroidsPath; + + bool useNormalsForCurveFitting; + DataPath surfaceMeshPrincipalCurvature1sPath; + DataPath surfaceMeshPrincipalCurvature2sPath; + DataPath surfaceMeshPrincipalDirection1sPath; + DataPath surfaceMeshPrincipalDirection2sPath; + DataPath surfaceMeshMeanCurvaturesPath; + DataPath surfaceMeshGaussianCurvaturesPath; + DataPath surfaceMeshWeingartenMatrixPath; +}; + +/** + * @class FillBadData + * @brief This filter replaces values in the target array with a user specified value + * where a bool mask array specifies. + */ +class SIMPLNXCORE_EXPORT FeatureFaceCurvature +{ +public: + FeatureFaceCurvature(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, FeatureFaceCurvatureInputValues* inputValues); + ~FeatureFaceCurvature() noexcept; + + FeatureFaceCurvature(const FeatureFaceCurvature&) = delete; + FeatureFaceCurvature(FeatureFaceCurvature&&) noexcept = delete; + FeatureFaceCurvature& operator=(const FeatureFaceCurvature&) = delete; + FeatureFaceCurvature& operator=(FeatureFaceCurvature&&) noexcept = delete; + + Result<> operator()(); + + const std::atomic_bool& getCancel(); + + void sendThreadSafeProgressMessage(usize counter); + +private: + DataStructure& m_DataStructure; + const FeatureFaceCurvatureInputValues* m_InputValues = nullptr; + const std::atomic_bool& m_ShouldCancel; + const IFilter::MessageHandler& m_MessageHandler; + + // Thread safe Progress Message + std::chrono::steady_clock::time_point m_InitialPoint = std::chrono::steady_clock::now(); + mutable std::mutex m_ProgressMessage_Mutex; + size_t m_TotalElements = 0; + size_t m_ProgressCounter = 0; + size_t m_LastProgressInt = 0; +}; + +} // namespace nx::core diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/FeatureFaceCurvatureFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/FeatureFaceCurvatureFilter.cpp index ee74a730b6..e3ca7326e4 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/FeatureFaceCurvatureFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/FeatureFaceCurvatureFilter.cpp @@ -1,7 +1,6 @@ #include "FeatureFaceCurvatureFilter.hpp" -#include "SimplnxCore/Filters/Algorithms/CalculateTriangleGroupCurvatures.hpp" -#include "SimplnxCore/Filters/Algorithms/FindNRingNeighbors.hpp" +#include "SimplnxCore/Filters/Algorithms/FeatureFaceCurvature.hpp" #include "simplnx/DataStructure/AttributeMatrix.hpp" #include "simplnx/DataStructure/DataPath.hpp" @@ -13,9 +12,6 @@ #include "simplnx/Parameters/BoolParameter.hpp" #include "simplnx/Parameters/GeometrySelectionParameter.hpp" #include "simplnx/Parameters/NumberParameter.hpp" -#include "simplnx/Utilities/ParallelTaskAlgorithm.hpp" - -#include "fmt/format.h" using namespace nx::core; @@ -207,139 +203,26 @@ IFilter::PreflightResult FeatureFaceCurvatureFilter::preflightImpl(const DataStr Result<> FeatureFaceCurvatureFilter::executeImpl(DataStructure& dataStructure, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler, const std::atomic_bool& shouldCancel) const { - int64 nRingCount = filterArgs.value(k_NeighborhoodRing_Key); - auto triangleGeomPath = filterArgs.value(k_TriangleGeom_Key); - auto surfaceMeshPrincipalCurvature1Path = filterArgs.value(k_PrincipalCurvature1_Key); - auto surfaceMeshFeatureFaceIdsPath = filterArgs.value(k_FeatureFaceIds_Key); - auto surfaceMeshFaceLabelsPath = filterArgs.value(k_FaceLabels_Key); - auto surfaceMeshFaceNormalsPath = filterArgs.value(k_FaceNormals_Key); - auto surfaceMeshTriangleCentroidsPath = filterArgs.value(k_FaceCentroids_Key); - - auto useNormalsForCurveFitting = filterArgs.value(k_UseFaceNormals_Key); - auto surfaceMeshPrincipalCurvature1sPath = filterArgs.value(k_PrincipalCurvature1_Key); - auto surfaceMeshPrincipalCurvature2sPath = filterArgs.value(k_PrincipalCurvature2_Key); - auto surfaceMeshPrincipalDirection1sPath = filterArgs.value(k_PrincipalDirection1_Key); - auto surfaceMeshPrincipalDirection2sPath = filterArgs.value(k_PrincipalDirection2_Key); - auto surfaceMeshMeanCurvaturesPath = filterArgs.value(k_MeanCurvature_Key); - auto surfaceMeshGaussianCurvaturesPath = filterArgs.value(k_GaussianCurvature_Key); - auto surfaceMeshWeingartenMatrixPath = filterArgs.value(k_WeingartenMatrix_Key); - - // Get DataObjects - auto* surfaceMeshPrincipalCurvature1sArray = dataStructure.getDataAs(surfaceMeshPrincipalCurvature1sPath); - auto* surfaceMeshPrincipalCurvature2sArray = dataStructure.getDataAs(surfaceMeshPrincipalCurvature2sPath); - auto* surfaceMeshPrincipalDirection1sArray = dataStructure.getDataAs(surfaceMeshPrincipalDirection1sPath); - auto* surfaceMeshPrincipalDirection2sArray = dataStructure.getDataAs(surfaceMeshPrincipalDirection2sPath); - auto* surfaceMeshMeanCurvaturesArray = dataStructure.getDataAs(surfaceMeshMeanCurvaturesPath); - auto* surfaceMeshGaussianCurvaturesArray = dataStructure.getDataAs(surfaceMeshGaussianCurvaturesPath); - auto* surfaceMeshFaceLabelsArray = dataStructure.getDataAs(surfaceMeshFaceLabelsPath); - auto* surfaceMeshFaceNormalsArray = dataStructure.getDataAs(surfaceMeshFaceNormalsPath); - auto* surfaceMeshTriangleCentroidsArray = dataStructure.getDataAs(surfaceMeshTriangleCentroidsPath); - auto* surfaceMeshWeingartenMatrixArray = dataStructure.getDataAs(surfaceMeshWeingartenMatrixPath); - - TriangleGeom* triangleGeom = dataStructure.getDataAs(triangleGeomPath); - Int32Array* surfaceMeshFeatureFaceIdsArray = dataStructure.getDataAs(surfaceMeshFeatureFaceIdsPath); - auto& surfaceMeshFeatureFaceIds = surfaceMeshFeatureFaceIdsArray->getDataStoreRef(); - - // Algorithm - int32 totalFeatureFaces = -1; - int32 completedFeatureFaces = -1; - - // Just to double check we have everything. - int64 numTriangles = triangleGeom->getNumberOfFaces(); - int32 totalTriangles = numTriangles; - - // Make sure the Face Connectivity is created because the FindNRing algorithm needs this and will - // assert if the data is NOT in the SurfaceMesh Data Container - const IGeometry::ElementDynamicList* vertLinks = triangleGeom->getElementsContainingVert(); - if(nullptr == vertLinks) - { - triangleGeom->findElementsContainingVert(); - } - - // get the QMap from the SharedFeatureFaces filter - SharedFeatureFaces_t sharedFeatureFaces; - - int32_t maxFaceId = 0; - for(int64_t t = 0; t < numTriangles; ++t) - { - if(surfaceMeshFeatureFaceIds[t] > maxFaceId) - { - maxFaceId = surfaceMeshFeatureFaceIds[t]; - } - } - - std::vector faceSizes(maxFaceId + 1, 0); - // Loop through all the Triangles and assign each one to a unique Feature Face Id. - for(int64_t t = 0; t < numTriangles; ++t) - { - faceSizes[surfaceMeshFeatureFaceIds[t]]++; - } - - // Allocate all the vectors that we need - for(size_t iter = 0; iter < faceSizes.size(); ++iter) - { - FaceIds_t v; - v.reserve(faceSizes[iter]); - sharedFeatureFaces[iter] = v; - } - - // Loop through all the Triangles and assign each one to a unique Feature Face Id. - for(int64_t t = 0; t < numTriangles; ++t) - { - sharedFeatureFaces[surfaceMeshFeatureFaceIds[t]].push_back(t); - } - - totalFeatureFaces = sharedFeatureFaces.size(); - completedFeatureFaces = 0; - totalTriangles = numTriangles; - std::string ss; - -/********************************* - * We are going to specfically invoke TBB directly instead of using ParallelTaskAlgorithm since we can just queue up all - * the tasks while the first tasks start up. TBB will then grab a new task from it's own queue to work on it up to the - * number of hardware limit of the machine. If we use ParallelTaskAlgorithm then at most we can only work on the number - * of tasks that equal the number of cores on the machine. We spend a lot of overhead spinning up new threads to do each - * task. This takes much longer (3x longer) in some cases - */ -#ifdef SIMPLNX_ENABLE_MULTICORE - std::shared_ptr g(new tbb::task_group); - ss = fmt::format("Adding {} Feature Faces to the work queue....", maxFaceId); - messageHandler(ss); -#else - -#endif - - // typedef here for conveneince - typedef SharedFeatureFaces_t::iterator SharedFeatureFaceIterator_t; - for(SharedFeatureFaceIterator_t iter = sharedFeatureFaces.begin(); iter != sharedFeatureFaces.end(); ++iter) - { - FaceIds_t& triangleIds = (*iter).second; - - CalculateTriangleGroupCurvatures func(nRingCount, triangleIds, useNormalsForCurveFitting, surfaceMeshPrincipalCurvature1sArray, surfaceMeshPrincipalCurvature2sArray, - surfaceMeshPrincipalDirection1sArray, surfaceMeshPrincipalDirection2sArray, surfaceMeshGaussianCurvaturesArray, surfaceMeshMeanCurvaturesArray, - surfaceMeshWeingartenMatrixArray, triangleGeom, surfaceMeshFaceLabelsArray, surfaceMeshFaceNormalsArray, surfaceMeshTriangleCentroidsArray, messageHandler, - shouldCancel); - -#ifdef SIMPLNX_ENABLE_MULTICORE - { - g->run(func); - } -#else - ss = fmt::format("Working on Face Id {}/{}", std::to_string((*iter).first), std::to_string(maxFaceId)); - messageHandler(ss); - { - func(); - } -#endif - } - -#ifdef SIMPLNX_ENABLE_MULTICORE - ss = fmt::format("Waiting on computations to complete."); - messageHandler(ss); - g->wait(); // Wait for all the threads to complete before moving on. -#endif - // return FillBadData(dataStructure, messageHandler, shouldCancel, &inputValues)(); - return {}; + FeatureFaceCurvatureInputValues inputValues; + + inputValues.NRingCount = filterArgs.value(k_NeighborhoodRing_Key); + inputValues.triangleGeomPath = filterArgs.value(k_TriangleGeom_Key); + inputValues.surfaceMeshPrincipalCurvature1Path = filterArgs.value(k_PrincipalCurvature1_Key); + inputValues.surfaceMeshFeatureFaceIdsPath = filterArgs.value(k_FeatureFaceIds_Key); + inputValues.surfaceMeshFaceLabelsPath = filterArgs.value(k_FaceLabels_Key); + inputValues.surfaceMeshFaceNormalsPath = filterArgs.value(k_FaceNormals_Key); + inputValues.surfaceMeshTriangleCentroidsPath = filterArgs.value(k_FaceCentroids_Key); + + inputValues.useNormalsForCurveFitting = filterArgs.value(k_UseFaceNormals_Key); + inputValues.surfaceMeshPrincipalCurvature1sPath = filterArgs.value(k_PrincipalCurvature1_Key); + inputValues.surfaceMeshPrincipalCurvature2sPath = filterArgs.value(k_PrincipalCurvature2_Key); + inputValues.surfaceMeshPrincipalDirection1sPath = filterArgs.value(k_PrincipalDirection1_Key); + inputValues.surfaceMeshPrincipalDirection2sPath = filterArgs.value(k_PrincipalDirection2_Key); + inputValues.surfaceMeshMeanCurvaturesPath = filterArgs.value(k_MeanCurvature_Key); + inputValues.surfaceMeshGaussianCurvaturesPath = filterArgs.value(k_GaussianCurvature_Key); + inputValues.surfaceMeshWeingartenMatrixPath = filterArgs.value(k_WeingartenMatrix_Key); + + return FeatureFaceCurvature(dataStructure, messageHandler, shouldCancel, &inputValues)(); } } // namespace nx::core diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/FeatureFaceCurvatureFilter.hpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/FeatureFaceCurvatureFilter.hpp index 621b791a7b..131c8fdc74 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/FeatureFaceCurvatureFilter.hpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/FeatureFaceCurvatureFilter.hpp @@ -15,9 +15,6 @@ namespace nx::core class SIMPLNXCORE_EXPORT FeatureFaceCurvatureFilter : public IFilter { public: - using FaceIds_t = std::vector; - using SharedFeatureFaces_t = std::map; - FeatureFaceCurvatureFilter() = default; ~FeatureFaceCurvatureFilter() noexcept override = default;