diff --git a/CMakeLists.txt b/CMakeLists.txt index d887159..bc3e417 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,6 @@ set(${PLUGIN_NAME}_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) # These are all the filters in the plugin. All filters should be kept in the # SimplnxReview/src/SimplnxReview/Filters/ directory. set(FilterList - ComputeGroupingDensityFilter ComputeLocalAverageCAxisMisalignmentsFilter ComputeMicroTextureRegionsFilter ComputeSaltykovSizesFilter @@ -44,7 +43,11 @@ set(ActionList # This should be integrated with the `create_simplnx_plugin` function call # ------------------------------------------------------------------------------ set(AlgorithmList +<<<<<<< HEAD +======= + ComputeEquivalentDiameterCircles ComputeGroupingDensity +>>>>>>> c376c60 (FILT: ComputeEquivalentDiameterCirclesFilter) ComputeLocalAverageCAxisMisalignments ComputeMicroTextureRegions ComputeSaltykovSizes diff --git a/docs/ComputeEquivalentDiameterCirclesFilter.md b/docs/ComputeEquivalentDiameterCirclesFilter.md new file mode 100644 index 0000000..8abfe8f --- /dev/null +++ b/docs/ComputeEquivalentDiameterCirclesFilter.md @@ -0,0 +1,28 @@ +# Compute Equivalent Diameter Circles + +**THIS FILTER IS UNTESTED, UNVERIFIED AND UNVALIDATED. IT IS AN EXPERIMENTAL FILTER THAT IS UNDERGOING LONG TERM DEVELOPMENT +AND TESTING. USE AT YOUR OWN RISK** + +## Group (Subgroup) + +Visualization Helpers + +## Description + +This filter will generate an Edge Geometry that holds N number of circles where each circle is centered at a given centroid and the radius of the circle is based on the Equivalent Spherical Diameter(ESD) values that are also provided by the user. + +This filter was meant to generate 2D circles in the XY plane. This filter will not work well with 3D centroids or centroids that have differing Z Values. + +% Auto generated parameter table will be inserted here + +## References + +## Example Pipelines + +## License & Copyright + +Please see the description file distributed with this **Plugin** + +## DREAM3D-NX Help + +If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions. diff --git a/src/SimplnxReview/Filters/Algorithms/ComputeEquivalentDiameterCircles.cpp b/src/SimplnxReview/Filters/Algorithms/ComputeEquivalentDiameterCircles.cpp new file mode 100644 index 0000000..cb12331 --- /dev/null +++ b/src/SimplnxReview/Filters/Algorithms/ComputeEquivalentDiameterCircles.cpp @@ -0,0 +1,84 @@ +#include "ComputeEquivalentDiameterCircles.hpp" + +#include "simplnx/Common/Constants.hpp" +#include "simplnx/Common/Result.hpp" +#include "simplnx/Common/Types.hpp" +#include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" +#include "simplnx/DataStructure/Geometry/EdgeGeom.hpp" +#include "simplnx/Filter/IFilter.hpp" + +#include +#include + +using namespace nx::core; + +// ----------------------------------------------------------------------------- +ComputeEquivalentDiameterCircles::ComputeEquivalentDiameterCircles(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, + ComputeEquivalentDiameterCirclesInputValues* inputValues) +: m_DataStructure(dataStructure) +, m_InputValues(inputValues) +, m_ShouldCancel(shouldCancel) +, m_MessageHandler(mesgHandler) +{ +} + +// ----------------------------------------------------------------------------- +const std::atomic_bool& ComputeEquivalentDiameterCircles::getCancel() +{ + return m_ShouldCancel; +} + +// ----------------------------------------------------------------------------- +Result<> ComputeEquivalentDiameterCircles::operator()() +{ + auto& centroidsArray = m_DataStructure.getDataRefAs(m_InputValues->CentroidsArrayPath); + auto& equivalentDiametersArray = m_DataStructure.getDataRefAs(m_InputValues->EquivalentDiametersArrayPath); + const DataPath featureIdsPath = m_InputValues->OutputEdgeGeometryPath.createChildPath(m_InputValues->EdgeAttributeMatrixName).createChildPath(m_InputValues->FeatureIdsArrayName); + auto& featureIdsArray = m_DataStructure.getDataRefAs(featureIdsPath); + auto& outputEdgeGeom = m_DataStructure.getDataRefAs(m_InputValues->OutputEdgeGeometryPath); + Float32Array& verticesArray = outputEdgeGeom.getVerticesRef(); + UInt64Array& edgesArray = outputEdgeGeom.getEdgesRef(); + + const usize circleResolution = m_InputValues->CircleResolution; + const usize verticesPerCircle = circleResolution + 1; + usize edgeIdx = 0; + + for(usize i = 1; i < centroidsArray.getNumberOfTuples(); ++i) + { + const float32 r = equivalentDiametersArray[i] / 2.0f; + const float32 cx = centroidsArray.getComponent(i, 0); + const float32 cy = centroidsArray.getComponent(i, 1); + + const usize circleVertexStart = (i - 1) * verticesPerCircle; + + for(usize v = 0; v < verticesPerCircle; ++v) + { + const usize vertexIdx = circleVertexStart + v; + + const float32 theta = 2.0f * nx::core::Constants::k_PiF * static_cast(v) / static_cast(circleResolution); + + const float32 x = cx + r * std::cos(theta); + const float32 y = cy + r * std::sin(theta); + + verticesArray.setComponent(vertexIdx, 0, x); + verticesArray.setComponent(vertexIdx, 1, y); + verticesArray.setComponent(vertexIdx, 2, static_cast(m_InputValues->ZPlane)); + } + + for(usize e = 0; e < circleResolution; ++e) + { + const usize v0 = circleVertexStart + e; + const usize v1 = circleVertexStart + e + 1; + + featureIdsArray.setValue(edgeIdx, static_cast(i)); + + edgesArray.setComponent(edgeIdx, 0, v0); + edgesArray.setComponent(edgeIdx, 1, v1); + edgeIdx++; + } + } + + return {}; +} diff --git a/src/SimplnxReview/Filters/Algorithms/ComputeEquivalentDiameterCircles.hpp b/src/SimplnxReview/Filters/Algorithms/ComputeEquivalentDiameterCircles.hpp new file mode 100644 index 0000000..3da783a --- /dev/null +++ b/src/SimplnxReview/Filters/Algorithms/ComputeEquivalentDiameterCircles.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "SimplnxReview/SimplnxReview_export.hpp" + +#include "simplnx/DataStructure/DataPath.hpp" +#include "simplnx/DataStructure/DataStructure.hpp" +#include "simplnx/Filter/IFilter.hpp" + +namespace nx::core +{ + +struct SIMPLNXREVIEW_EXPORT ComputeEquivalentDiameterCirclesInputValues +{ + DataPath CentroidsArrayPath; + DataPath EquivalentDiametersArrayPath; + uint64 CircleResolution; + int64 ZPlane; + DataPath OutputEdgeGeometryPath; + std::string EdgeAttributeMatrixName; + std::string FeatureIdsArrayName; +}; + +/** + * @class ComputeEquivalentDiameterCircles + * @brief This filter determines the average C-axis location of each Feature. + */ + +class SIMPLNXREVIEW_EXPORT ComputeEquivalentDiameterCircles +{ +public: + ComputeEquivalentDiameterCircles(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, + ComputeEquivalentDiameterCirclesInputValues* inputValues); + ~ComputeEquivalentDiameterCircles() noexcept = default; + + ComputeEquivalentDiameterCircles(const ComputeEquivalentDiameterCircles&) = delete; + ComputeEquivalentDiameterCircles(ComputeEquivalentDiameterCircles&&) noexcept = delete; + ComputeEquivalentDiameterCircles& operator=(const ComputeEquivalentDiameterCircles&) = delete; + ComputeEquivalentDiameterCircles& operator=(ComputeEquivalentDiameterCircles&&) noexcept = delete; + + Result<> operator()(); + + const std::atomic_bool& getCancel(); + +private: + DataStructure& m_DataStructure; + const ComputeEquivalentDiameterCirclesInputValues* m_InputValues = nullptr; + const std::atomic_bool& m_ShouldCancel; + const IFilter::MessageHandler& m_MessageHandler; +}; + +} // namespace nx::core diff --git a/src/SimplnxReview/Filters/Algorithms/ComputeGroupingDensity.cpp b/src/SimplnxReview/Filters/Algorithms/ComputeGroupingDensity.cpp deleted file mode 100644 index 31e20a2..0000000 --- a/src/SimplnxReview/Filters/Algorithms/ComputeGroupingDensity.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include "ComputeGroupingDensity.hpp" - -#include "simplnx/DataStructure/DataArray.hpp" -#include "simplnx/DataStructure/NeighborList.hpp" -#include "simplnx/Utilities/MessageHelper.hpp" - -using namespace nx::core; - -namespace -{ -template -struct FindDensitySpecializations -{ - static inline constexpr bool UsingNonContiguousNeighbors = UseNonContiguousNeighbors; - static inline constexpr bool FindingCheckedFeatures = FindCheckedFeatures; -}; - -template > -class FindDensityGrouping -{ -public: - FindDensityGrouping(const std::atomic_bool& shouldCancel, const IFilter::MessageHandler& mesgHandler, const Int32Array& parentIds, const Float32Array& parentVolumes, const Float32Array& volumes, - const Int32NeighborList& contiguousNL, Float32Array& groupingDensities, Int32NeighborList& nonContiguousNL, Int32Array& checkedFeatures) - : m_ShouldCancel(shouldCancel) - , m_MessageHandler(mesgHandler) - , m_ParentIds(parentIds) - , m_ParentVolumes(parentVolumes) - , m_Volumes(volumes) - , m_ContiguousNL(contiguousNL) - , m_GroupingDensities(groupingDensities) - , m_NonContiguousNL(nonContiguousNL) - , m_CheckedFeatures(checkedFeatures) - { - } - ~FindDensityGrouping() noexcept = default; - - FindDensityGrouping(const FindDensityGrouping&) = delete; // Copy Constructor Default Implemented - FindDensityGrouping(FindDensityGrouping&&) = delete; // Move Constructor Not Implemented - FindDensityGrouping& operator=(const FindDensityGrouping&) = delete; // Copy Assignment Not Implemented - FindDensityGrouping& operator=(FindDensityGrouping&&) = delete; // Move Assignment Not Implemented - - Result<> operator()() - { - const auto& parentIds = m_ParentIds.getDataStoreRef(); - const auto& parentVolumes = m_ParentVolumes.getDataStoreRef(); - const auto& volumes = m_Volumes.getDataStoreRef(); - - auto& checkedFeatures = m_CheckedFeatures.getDataStoreRef(); - auto& groupingDensities = m_GroupingDensities.getDataStoreRef(); - - usize numFeatures = volumes.getNumberOfTuples(); - usize numParents = parentVolumes.getNumberOfTuples(); - - int kMax = 1; - if constexpr(FindDensitySpecializations::UsingNonContiguousNeighbors) - { - kMax = 2; - } - - int32 numNeighbors, numNeighborhoods, numCurNeighborList, neigh; - float32 totalCheckVolume, curParentVolume; - std::set totalCheckList = {}; - - std::vector checkedFeatureVolumes(1, 0.0f); - if constexpr(FindDensitySpecializations::FindingCheckedFeatures) - { - // Default value-initialized to zeroes: https://en.cppreference.com/w/cpp/named_req/DefaultInsertable - checkedFeatureVolumes.resize(numFeatures); - } - MessageHelper messageHelper(m_MessageHandler); - ThrottledMessenger throttledMessenger = messageHelper.createThrottledMessenger(); - - for(usize parentIdx = 1; parentIdx < numParents; parentIdx++) - { - throttledMessenger.sendThrottledMessage([&]() { return fmt::format("[{}%]", CalculatePercentComplete(parentIdx, numParents)); }); - - if(m_ShouldCancel) - { - return {}; - } - for(usize j = 1; j < numFeatures; j++) - { - if(parentIds[j] == parentIdx) - { - if(totalCheckList.find(j) == totalCheckList.end()) - // if(std::find(totalCheckList.begin(), totalCheckList.end(), j) == totalCheckList.end()) - { - totalCheckVolume += m_Volumes[j]; - totalCheckList.insert(static_cast(j)); - if constexpr(FindDensitySpecializations::FindingCheckedFeatures) - { - if(parentVolumes[parentIdx] > checkedFeatureVolumes[j]) - { - checkedFeatureVolumes[j] = parentVolumes[parentIdx]; - checkedFeatures[j] = static_cast(parentIdx); - } - } - } - numNeighbors = m_ContiguousNL.getListSize(static_cast(j)); - if constexpr(FindDensitySpecializations::UsingNonContiguousNeighbors) - { - numNeighborhoods = static_cast(m_NonContiguousNL[j].size()); - } - for(int k = 0; k < kMax; k++) - { - if(k == 0) - { - numCurNeighborList = numNeighbors; - } - if constexpr(FindDensitySpecializations::UsingNonContiguousNeighbors) - { - if(k == 1) - { - numCurNeighborList = numNeighborhoods; - } - } - for(int32_t l = 0; l < numCurNeighborList; l++) - { - if(k == 0) - { - bool ok = false; - neigh = m_ContiguousNL.getValue(static_cast(j), l, ok); - } - else if(k == 1) - { - neigh = m_NonContiguousNL[j][l]; - } - if(totalCheckList.find(neigh) == totalCheckList.end()) - // if(std::find(totalCheckList.begin(), totalCheckList.end(), neigh) == totalCheckList.end()) - { - totalCheckVolume += m_Volumes[neigh]; - totalCheckList.insert(neigh); - if constexpr(FindDensitySpecializations::FindingCheckedFeatures) - { - if(parentVolumes[parentIdx] > checkedFeatureVolumes[neigh]) - { - checkedFeatureVolumes[neigh] = parentVolumes[parentIdx]; - checkedFeatures[neigh] = static_cast(parentIdx); - } - } - } - } - } - } - } - curParentVolume = parentVolumes[parentIdx]; - if(totalCheckVolume == 0.0f) - { - groupingDensities[parentIdx] = -1.0f; - } - else - { - groupingDensities[parentIdx] = (curParentVolume / totalCheckVolume); - } - totalCheckList.clear(); - totalCheckVolume = 0.0f; - } - - return {}; - } - -private: - const std::atomic_bool& m_ShouldCancel; - const IFilter::MessageHandler& m_MessageHandler; - const Int32Array& m_ParentIds; - const Float32Array& m_ParentVolumes; - const Float32Array& m_Volumes; - const Int32NeighborList& m_ContiguousNL; - Float32Array& m_GroupingDensities; - Int32NeighborList& m_NonContiguousNL; - Int32Array& m_CheckedFeatures; -}; -} // namespace - -// ----------------------------------------------------------------------------- -ComputeGroupingDensity::ComputeGroupingDensity(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, - ComputeGroupingDensityInputValues* inputValues) -: m_DataStructure(dataStructure) -, m_InputValues(inputValues) -, m_ShouldCancel(shouldCancel) -, m_MessageHandler(mesgHandler) -{ -} - -// ----------------------------------------------------------------------------- -const std::atomic_bool& ComputeGroupingDensity::getCancel() -{ - return m_ShouldCancel; -} - -// ----------------------------------------------------------------------------- -Result<> ComputeGroupingDensity::operator()() -{ - auto& parentIds = m_DataStructure.getDataRefAs(m_InputValues->ParentIdsPath); - auto& parentVolumes = m_DataStructure.getDataRefAs(m_InputValues->ParentVolumesPath); - auto& volumes = m_DataStructure.getDataRefAs(m_InputValues->VolumesPath); - auto& contiguousNL = m_DataStructure.getDataRefAs>(m_InputValues->ContiguousNLPath); - auto& groupingDensities = m_DataStructure.getDataRefAs(m_InputValues->GroupingDensitiesPath); - - // These may or may not be empty depending on the parameters - auto& nonContiguousNL = m_DataStructure.getDataRefAs>(m_InputValues->NonContiguousNLPath); - auto& checkedFeatures = m_DataStructure.getDataRefAs(m_InputValues->CheckedFeaturesPath); - - if(m_InputValues->UseNonContiguousNeighbors) - { - if(m_InputValues->FindCheckedFeatures) - { - return ::FindDensityGrouping>(getCancel(), m_MessageHandler, parentIds, parentVolumes, volumes, contiguousNL, groupingDensities, nonContiguousNL, - checkedFeatures)(); - } - return ::FindDensityGrouping>(getCancel(), m_MessageHandler, parentIds, parentVolumes, volumes, contiguousNL, groupingDensities, nonContiguousNL, - checkedFeatures)(); - } - else if(m_InputValues->FindCheckedFeatures) - { - return ::FindDensityGrouping>(getCancel(), m_MessageHandler, parentIds, parentVolumes, volumes, contiguousNL, groupingDensities, nonContiguousNL, - checkedFeatures)(); - } - else - { - return ::FindDensityGrouping>(getCancel(), m_MessageHandler, parentIds, parentVolumes, volumes, contiguousNL, groupingDensities, nonContiguousNL, - checkedFeatures)(); - } -} diff --git a/src/SimplnxReview/Filters/Algorithms/ComputeGroupingDensity.hpp b/src/SimplnxReview/Filters/Algorithms/ComputeGroupingDensity.hpp deleted file mode 100644 index 3b2dc60..0000000 --- a/src/SimplnxReview/Filters/Algorithms/ComputeGroupingDensity.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "SimplnxReview/SimplnxReview_export.hpp" - -#include "simplnx/DataStructure/DataPath.hpp" -#include "simplnx/DataStructure/DataStructure.hpp" -#include "simplnx/Filter/IFilter.hpp" - -namespace nx::core -{ - -struct SIMPLNXREVIEW_EXPORT ComputeGroupingDensityInputValues -{ - DataPath VolumesPath; - DataPath ContiguousNLPath; - bool UseNonContiguousNeighbors; - DataPath NonContiguousNLPath; - DataPath ParentIdsPath; - DataPath ParentVolumesPath; - bool FindCheckedFeatures; - DataPath CheckedFeaturesPath; - DataPath GroupingDensitiesPath; -}; - -/** - * @class ComputeGroupingDensity - * @brief This filter determines the average C-axis location of each Feature. - */ - -class SIMPLNXREVIEW_EXPORT ComputeGroupingDensity -{ -public: - ComputeGroupingDensity(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ComputeGroupingDensityInputValues* inputValues); - ~ComputeGroupingDensity() noexcept = default; - - ComputeGroupingDensity(const ComputeGroupingDensity&) = delete; - ComputeGroupingDensity(ComputeGroupingDensity&&) noexcept = delete; - ComputeGroupingDensity& operator=(const ComputeGroupingDensity&) = delete; - ComputeGroupingDensity& operator=(ComputeGroupingDensity&&) noexcept = delete; - - Result<> operator()(); - - const std::atomic_bool& getCancel(); - -private: - DataStructure& m_DataStructure; - const ComputeGroupingDensityInputValues* m_InputValues = nullptr; - const std::atomic_bool& m_ShouldCancel; - const IFilter::MessageHandler& m_MessageHandler; -}; - -} // namespace nx::core diff --git a/src/SimplnxReview/Filters/ComputeEquivalentDiameterCirclesFilter.cpp b/src/SimplnxReview/Filters/ComputeEquivalentDiameterCirclesFilter.cpp new file mode 100644 index 0000000..1286813 --- /dev/null +++ b/src/SimplnxReview/Filters/ComputeEquivalentDiameterCirclesFilter.cpp @@ -0,0 +1,134 @@ +#include "ComputeEquivalentDiameterCirclesFilter.hpp" + +#include "SimplnxReview/Filters/Algorithms/ComputeEquivalentDiameterCircles.hpp" + +#include "simplnx/DataStructure/DataArray.hpp" +#include "simplnx/Filter/Actions/CreateArrayAction.hpp" +#include "simplnx/Filter/Actions/CreateGeometry1DAction.hpp" +#include "simplnx/Parameters/ArraySelectionParameter.hpp" +#include "simplnx/Parameters/DataGroupCreationParameter.hpp" +#include "simplnx/Parameters/DataObjectNameParameter.hpp" +#include "simplnx/Parameters/NumberParameter.hpp" + +using namespace nx::core; + +namespace nx::core +{ +//------------------------------------------------------------------------------ +std::string ComputeEquivalentDiameterCirclesFilter::name() const +{ + return FilterTraits::name.str(); +} + +//------------------------------------------------------------------------------ +std::string ComputeEquivalentDiameterCirclesFilter::className() const +{ + return FilterTraits::className; +} + +//------------------------------------------------------------------------------ +Uuid ComputeEquivalentDiameterCirclesFilter::uuid() const +{ + return FilterTraits::uuid; +} + +//------------------------------------------------------------------------------ +std::string ComputeEquivalentDiameterCirclesFilter::humanName() const +{ + return "Compute Equivalent Diameter Circles"; +} + +//------------------------------------------------------------------------------ +std::vector ComputeEquivalentDiameterCirclesFilter::defaultTags() const +{ + return {className()}; +} + +//------------------------------------------------------------------------------ +Parameters ComputeEquivalentDiameterCirclesFilter::parameters() const +{ + Parameters params; + // Create the parameter descriptors that are needed for this filter + params.insertSeparator(Parameters::Separator{"Input Parameter(s)"}); + params.insert(std::make_unique(k_CentroidsArrayPath_Key, "Feature Centroids", "X, Y, Z coordinates of Feature center of mass", DataPath{}, + ArraySelectionParameter::AllowedTypes{DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{3}})); + params.insert(std::make_unique(k_EquivalentDiametersArrayPath_Key, "Equivalent Diameters", "Input feature based Equivalent Diameters", DataPath{}, + ArraySelectionParameter::AllowedTypes{DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{1}})); + params.insert(std::make_unique>(k_CircleResolution_Key, "Circle Resolution", "The number of edges that each circle will have", 100)); + params.insert(std::make_unique>(k_ZPlane_Key, "Z Plane", "The Z plane that the circles will be calculated on.", 0)); + + params.insertSeparator(Parameters::Separator{"Output Edge Geometry"}); + params.insert(std::make_unique(k_OutputEdgeGeometryPath_Key, "Created Edge Geometry", "The name of the created Edge Geometry", DataPath({"Circles"}))); + params.insert(std::make_unique(k_EdgeAttributeMatrixName_Key, "Edge Attribute Matrix", "Attribute Matrix to store information about the created edges", "Edge Data")); + params.insert(std::make_unique(k_CreatedFeatureIdsArrayName_Key, "Edge Feature Ids", "Identifies the Feature Id to which each edge belongs", "Feature Ids")); + + return params; +} + +//------------------------------------------------------------------------------ +IFilter::UniquePointer ComputeEquivalentDiameterCirclesFilter::clone() const +{ + return std::make_unique(); +} + +//------------------------------------------------------------------------------ +IFilter::VersionType ComputeEquivalentDiameterCirclesFilter::parametersVersion() const +{ + return 1; +} + +//------------------------------------------------------------------------------ +IFilter::PreflightResult ComputeEquivalentDiameterCirclesFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler, + const std::atomic_bool& shouldCancel, const ExecutionContext& executionContext) const +{ + auto pCentroidsArrayPath = filterArgs.value(k_CentroidsArrayPath_Key); + auto pEquivalentDiametersArrayPath = filterArgs.value(k_EquivalentDiametersArrayPath_Key); + auto pCircleResolution = filterArgs.value(k_CircleResolution_Key); + auto pOutputEdgeGeometryPath = filterArgs.value(k_OutputEdgeGeometryPath_Key); + auto pEdgeAttributeMatrixName = filterArgs.value(k_EdgeAttributeMatrixName_Key); + auto pFeatureIdsArrayName = filterArgs.value(k_CreatedFeatureIdsArrayName_Key); + + Result resultOutputActions; + std::vector preflightUpdatedValues; + + auto& centroidsArray = dataStructure.getDataRefAs(pCentroidsArrayPath); + auto& equivalentDiametersArray = dataStructure.getDataRefAs(pEquivalentDiametersArrayPath); + usize numberOfCentroids = centroidsArray.getNumberOfTuples(); + if(numberOfCentroids != equivalentDiametersArray.getNumberOfTuples()) + { + return MakePreflightErrorResult(-13860, fmt::format("Centroids array has {} centroids, and the equivalent diameters array has {} diameters. These must be equal.", numberOfCentroids, + equivalentDiametersArray.getNumberOfTuples())); + } + + auto createGeometryAction = + std::make_unique(pOutputEdgeGeometryPath, pCircleResolution * (numberOfCentroids - 1), (pCircleResolution + 1) * (numberOfCentroids - 1), + INodeGeometry0D::k_VertexAttributeMatrixName, pEdgeAttributeMatrixName, EdgeGeom::k_SharedVertexListName, EdgeGeom::k_SharedEdgeListName); + resultOutputActions.value().appendAction(std::move(createGeometryAction)); + + DataPath path = pOutputEdgeGeometryPath.createChildPath(pEdgeAttributeMatrixName).createChildPath(pFeatureIdsArrayName); + auto createArray = std::make_unique(DataType::int32, std::vector{pCircleResolution * (numberOfCentroids - 1)}, std::vector{1}, path); + resultOutputActions.value().appendAction(std::move(createArray)); + + preflightUpdatedValues.push_back({"WARNING: This filter is experimental in nature and has not had any testing, validation or verification. Use at your own risk"}); + resultOutputActions.warnings().push_back({-65432, "WARNING: This filter is experimental in nature and has not had any testing, validation or verification. Use at your own risk"}); + + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; +} + +//------------------------------------------------------------------------------ +Result<> ComputeEquivalentDiameterCirclesFilter::executeImpl(DataStructure& dataStructure, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler, + const std::atomic_bool& shouldCancel, const ExecutionContext& executionContext) const +{ + ComputeEquivalentDiameterCirclesInputValues inputValues; + + inputValues.CentroidsArrayPath = filterArgs.value(k_CentroidsArrayPath_Key); + inputValues.EquivalentDiametersArrayPath = filterArgs.value(k_EquivalentDiametersArrayPath_Key); + inputValues.CircleResolution = filterArgs.value(k_CircleResolution_Key); + inputValues.ZPlane = filterArgs.value(k_ZPlane_Key); + inputValues.OutputEdgeGeometryPath = filterArgs.value(k_OutputEdgeGeometryPath_Key); + inputValues.EdgeAttributeMatrixName = filterArgs.value(k_EdgeAttributeMatrixName_Key); + inputValues.FeatureIdsArrayName = filterArgs.value(k_CreatedFeatureIdsArrayName_Key); + + return ComputeEquivalentDiameterCircles(dataStructure, messageHandler, shouldCancel, &inputValues)(); +} +} // namespace nx::core diff --git a/src/SimplnxReview/Filters/ComputeGroupingDensityFilter.hpp b/src/SimplnxReview/Filters/ComputeEquivalentDiameterCirclesFilter.hpp similarity index 72% rename from src/SimplnxReview/Filters/ComputeGroupingDensityFilter.hpp rename to src/SimplnxReview/Filters/ComputeEquivalentDiameterCirclesFilter.hpp index 0614178..14d9880 100644 --- a/src/SimplnxReview/Filters/ComputeGroupingDensityFilter.hpp +++ b/src/SimplnxReview/Filters/ComputeEquivalentDiameterCirclesFilter.hpp @@ -8,31 +8,29 @@ namespace nx::core { /** - * @class ComputeGroupingDensityFilter + * @class ComputeEquivalentDiameterCirclesFilter * @brief This filter determines the average C-axis location of each Feature */ -class SIMPLNXREVIEW_EXPORT ComputeGroupingDensityFilter : public IFilter +class SIMPLNXREVIEW_EXPORT ComputeEquivalentDiameterCirclesFilter : public IFilter { public: - ComputeGroupingDensityFilter() = default; - ~ComputeGroupingDensityFilter() noexcept override = default; + ComputeEquivalentDiameterCirclesFilter() = default; + ~ComputeEquivalentDiameterCirclesFilter() noexcept override = default; - ComputeGroupingDensityFilter(const ComputeGroupingDensityFilter&) = delete; - ComputeGroupingDensityFilter(ComputeGroupingDensityFilter&&) noexcept = delete; + ComputeEquivalentDiameterCirclesFilter(const ComputeEquivalentDiameterCirclesFilter&) = delete; + ComputeEquivalentDiameterCirclesFilter(ComputeEquivalentDiameterCirclesFilter&&) noexcept = delete; - ComputeGroupingDensityFilter& operator=(const ComputeGroupingDensityFilter&) = delete; - ComputeGroupingDensityFilter& operator=(ComputeGroupingDensityFilter&&) noexcept = delete; + ComputeEquivalentDiameterCirclesFilter& operator=(const ComputeEquivalentDiameterCirclesFilter&) = delete; + ComputeEquivalentDiameterCirclesFilter& operator=(ComputeEquivalentDiameterCirclesFilter&&) noexcept = delete; // Parameter Keys - static constexpr StringLiteral k_VolumesArrayPath_Key = "volumes_path"; - static constexpr StringLiteral k_ContiguousNeighborListArrayPath_Key = "contiguous_neighbor_list_path"; - static constexpr StringLiteral k_UseNonContiguousNeighbors_Key = "use_non_contiguous_neighbors"; - static constexpr StringLiteral k_NonContiguousNeighborListArrayPath_Key = "non_contiguous_neighbor_list_path"; - static constexpr StringLiteral k_ParentIdsPath_Key = "parent_ids_path"; - static constexpr StringLiteral k_ParentVolumesPath_Key = "parent_volumes_path"; - static constexpr StringLiteral k_FindCheckedFeatures_Key = "find_checked_features"; - static constexpr StringLiteral k_CheckedFeaturesName_Key = "checked_features_name"; - static constexpr StringLiteral k_GroupingDensitiesName_Key = "grouping_densities_name"; + static constexpr StringLiteral k_CentroidsArrayPath_Key = "centroids_array_path"; + static constexpr StringLiteral k_EquivalentDiametersArrayPath_Key = "equivalent_diameters_array_path"; + static constexpr StringLiteral k_CircleResolution_Key = "circle_resolution"; + static constexpr StringLiteral k_ZPlane_Key = "z_plane"; + static constexpr StringLiteral k_OutputEdgeGeometryPath_Key = "output_edge_geometry_path"; + static constexpr StringLiteral k_EdgeAttributeMatrixName_Key = "edge_attribute_matrix_name"; + static constexpr StringLiteral k_CreatedFeatureIdsArrayName_Key = "created_feature_ids_array_name"; /** * @brief Reads SIMPL json and converts it simplnx Arguments. @@ -122,5 +120,5 @@ class SIMPLNXREVIEW_EXPORT ComputeGroupingDensityFilter : public IFilter }; } // namespace nx::core -SIMPLNX_DEF_FILTER_TRAITS(nx::core, ComputeGroupingDensityFilter, "ff46afcf-de32-4f37-98bc-8f0fd4b3c122"); +SIMPLNX_DEF_FILTER_TRAITS(nx::core, ComputeEquivalentDiameterCirclesFilter, "f841b59f-c176-4eca-be2b-8e9bdee012c6"); /* LEGACY UUID FOR THIS FILTER 708be082-8b08-4db2-94be-52781ed4d53d */ diff --git a/src/SimplnxReview/Filters/ComputeGroupingDensityFilter.cpp b/src/SimplnxReview/Filters/ComputeGroupingDensityFilter.cpp deleted file mode 100644 index a2f79ff..0000000 --- a/src/SimplnxReview/Filters/ComputeGroupingDensityFilter.cpp +++ /dev/null @@ -1,254 +0,0 @@ -#include "ComputeGroupingDensityFilter.hpp" - -#include "SimplnxReview/Filters/Algorithms/ComputeGroupingDensity.hpp" - -#include "simplnx/DataStructure/AttributeMatrix.hpp" -#include "simplnx/DataStructure/DataPath.hpp" -#include "simplnx/Filter/Actions/CreateArrayAction.hpp" -#include "simplnx/Filter/Actions/CreateNeighborListAction.hpp" -#include "simplnx/Filter/Actions/DeleteDataAction.hpp" -#include "simplnx/Parameters/ArraySelectionParameter.hpp" -#include "simplnx/Parameters/BoolParameter.hpp" -#include "simplnx/Parameters/DataObjectNameParameter.hpp" -#include "simplnx/Parameters/NeighborListSelectionParameter.hpp" -#include "simplnx/Utilities/SIMPLConversion.hpp" - -using namespace nx::core; - -namespace -{ -const DataPath k_ThrowawayCheckedFeatures = DataPath({"HiddenTempCheckedFeatures"}); -const DataPath k_ThrowawayNonContiguous = DataPath({"HiddenContiguousNL"}); -} // namespace - -namespace nx::core -{ -//------------------------------------------------------------------------------ -std::string ComputeGroupingDensityFilter::name() const -{ - return FilterTraits::name.str(); -} - -//------------------------------------------------------------------------------ -std::string ComputeGroupingDensityFilter::className() const -{ - return FilterTraits::className; -} - -//------------------------------------------------------------------------------ -Uuid ComputeGroupingDensityFilter::uuid() const -{ - return FilterTraits::uuid; -} - -//------------------------------------------------------------------------------ -std::string ComputeGroupingDensityFilter::humanName() const -{ - return "Compute Grouping Densities"; -} - -//------------------------------------------------------------------------------ -std::vector ComputeGroupingDensityFilter::defaultTags() const -{ - return {className(), "Statistics", "Reconstruction"}; -} - -//------------------------------------------------------------------------------ -Parameters ComputeGroupingDensityFilter::parameters() const -{ - Parameters params; - // Create the parameter descriptors that are needed for this filter - params.insertSeparator(Parameters::Separator{"Input Parameter(s)"}); - params.insertLinkableParameter(std::make_unique(k_FindCheckedFeatures_Key, "Find Checked Features", "Find checked features", false)); - - params.insertSeparator(Parameters::Separator{"Non-Contiguous Neighborhood Option"}); - params.insertLinkableParameter(std::make_unique(k_UseNonContiguousNeighbors_Key, "Use Non-Contiguous Neighbors", "Use non-contiguous neighborhoods for computations", false)); - params.insert(std::make_unique(k_NonContiguousNeighborListArrayPath_Key, "Non-Contiguous Neighborhoods", "List of non-contiguous neighbors for each Feature.", - DataPath{}, NeighborListSelectionParameter::AllowedTypes{DataType::int32})); - - params.insertSeparator(Parameters::Separator{"Input Cell Data"}); - params.insert(std::make_unique(k_ParentIdsPath_Key, "Parent Ids", "Input Cell level ParentIds", DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::int32}, - ArraySelectionParameter::AllowedComponentShapes{{1}})); - - params.insertSeparator(Parameters::Separator{"Input Feature Data"}); - params.insert(std::make_unique(k_VolumesArrayPath_Key, "Volumes", "The Feature Volumes Data Array", DataPath{}, - ArraySelectionParameter::AllowedTypes{nx::core::DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{1}})); - - params.insert(std::make_unique(k_ContiguousNeighborListArrayPath_Key, "Contiguous Neighbor List", "List of contiguous neighbors for each Feature.", DataPath{}, - NeighborListSelectionParameter::AllowedTypes{DataType::int32})); - - params.insert(std::make_unique(k_ParentVolumesPath_Key, "Parent Volumes", "Input feature level parent volume data array", DataPath{}, - ArraySelectionParameter::AllowedTypes{DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{1}})); - - params.insertSeparator(Parameters::Separator{"Output Feature Data"}); - - params.insert(std::make_unique(k_CheckedFeaturesName_Key, "Checked Features Name", "Output feature level data array to hold 'Checked Features' values", "Checked Features")); - params.insert( - std::make_unique(k_GroupingDensitiesName_Key, "Grouping Densities Name", "Output feature level data array to hold 'Grouping Densities' values", "Grouping Densities")); - - // Link params - params.linkParameters(k_UseNonContiguousNeighbors_Key, k_NonContiguousNeighborListArrayPath_Key, true); - params.linkParameters(k_FindCheckedFeatures_Key, k_CheckedFeaturesName_Key, true); - - return params; -} - -//------------------------------------------------------------------------------ -IFilter::UniquePointer ComputeGroupingDensityFilter::clone() const -{ - return std::make_unique(); -} - -//------------------------------------------------------------------------------ -IFilter::VersionType ComputeGroupingDensityFilter::parametersVersion() const -{ - return 1; -} - -//------------------------------------------------------------------------------ -IFilter::PreflightResult ComputeGroupingDensityFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler, - const std::atomic_bool& shouldCancel, const ExecutionContext& executionContext) const -{ - auto pParentIdsPath = filterArgs.value(k_ParentIdsPath_Key); - auto pParentVolumesPath = filterArgs.value(k_ParentVolumesPath_Key); - auto pContiguousNLPath = filterArgs.value(k_ContiguousNeighborListArrayPath_Key); - auto pVolumesPath = filterArgs.value(k_VolumesArrayPath_Key); - auto pGroupingDensitiesName = filterArgs.value(k_GroupingDensitiesName_Key); - - auto pUseNonContiguousNeighbors = filterArgs.value(k_UseNonContiguousNeighbors_Key); - auto pNonContiguousNLPath = filterArgs.value(k_NonContiguousNeighborListArrayPath_Key); - auto pFindCheckedFeatures = filterArgs.value(k_FindCheckedFeatures_Key); - auto pCheckedFeaturesName = filterArgs.value(k_CheckedFeaturesName_Key); - - Result resultOutputActions; - std::vector preflightUpdatedValues; - - auto* pParentAM = dataStructure.getDataAs(pParentVolumesPath.getParent()); - if(pParentAM == nullptr) - { - return MakePreflightErrorResult(-15670, fmt::format("Parent Volumes [{}] must be stored in an Attribute Matrix.", pParentVolumesPath.toString())); - } - { - DataPath groupingDataPath = pParentVolumesPath.replaceName(pGroupingDensitiesName); - auto createArrayAction = std::make_unique(nx::core::DataType::float32, pParentAM->getShape(), std::vector{1}, groupingDataPath); - resultOutputActions.value().appendAction(std::move(createArrayAction)); - } - - auto* pFeatureAM = dataStructure.getDataAs(pVolumesPath.getParent()); - if(pFeatureAM == nullptr) - { - return MakePreflightErrorResult(-15671, fmt::format("Feature Volumes [{}] must be stored in an Attribute Matrix.", pVolumesPath.toString())); - } - - if(pFindCheckedFeatures) - { - DataPath checkedFeaturesPath = pVolumesPath.replaceName(pCheckedFeaturesName); - { - auto createArrayAction = std::make_unique(nx::core::DataType::int32, pFeatureAM->getShape(), std::vector{1}, checkedFeaturesPath); - resultOutputActions.value().appendAction(std::move(createArrayAction)); - } - } - else - { - { - auto createArrayAction = std::make_unique(nx::core::DataType::int32, ShapeType{1}, ShapeType{1}, k_ThrowawayCheckedFeatures); - resultOutputActions.value().appendAction(std::move(createArrayAction)); - } - { - auto removeAction = std::make_unique(k_ThrowawayCheckedFeatures); - resultOutputActions.value().appendDeferredAction(std::move(removeAction)); - } - } - - if(!pUseNonContiguousNeighbors) - { - { - auto createArrayAction = std::make_unique(nx::core::DataType::int32, ShapeType{1}, k_ThrowawayNonContiguous); - resultOutputActions.value().appendAction(std::move(createArrayAction)); - } - { - auto removeAction = std::make_unique(k_ThrowawayNonContiguous); - resultOutputActions.value().appendDeferredAction(std::move(removeAction)); - } - } - - preflightUpdatedValues.push_back({"WARNING: This filter is experimental in nature and has not had any testing, validation or verification. Use at your own risk"}); - resultOutputActions.warnings().push_back({-65432, "WARNING: This filter is experimental in nature and has not had any testing, validation or verification. Use at your own risk"}); - - return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; -} - -//------------------------------------------------------------------------------ -Result<> ComputeGroupingDensityFilter::executeImpl(DataStructure& dataStructure, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler, - const std::atomic_bool& shouldCancel, const ExecutionContext& executionContext) const -{ - ComputeGroupingDensityInputValues inputValues; - - inputValues.ParentIdsPath = filterArgs.value(k_ParentIdsPath_Key); - inputValues.ParentVolumesPath = filterArgs.value(k_ParentVolumesPath_Key); - inputValues.ContiguousNLPath = filterArgs.value(k_ContiguousNeighborListArrayPath_Key); - inputValues.VolumesPath = filterArgs.value(k_VolumesArrayPath_Key); - inputValues.GroupingDensitiesPath = inputValues.ParentVolumesPath.replaceName(filterArgs.value(k_GroupingDensitiesName_Key)); - - inputValues.UseNonContiguousNeighbors = filterArgs.value(k_UseNonContiguousNeighbors_Key); - if(inputValues.UseNonContiguousNeighbors) - { - inputValues.NonContiguousNLPath = filterArgs.value(k_NonContiguousNeighborListArrayPath_Key); - } - else - { - inputValues.NonContiguousNLPath = k_ThrowawayNonContiguous; - } - - inputValues.FindCheckedFeatures = filterArgs.value(k_FindCheckedFeatures_Key); - if(inputValues.FindCheckedFeatures) - { - inputValues.CheckedFeaturesPath = inputValues.VolumesPath.replaceName(filterArgs.value(k_CheckedFeaturesName_Key)); - } - else - { - inputValues.CheckedFeaturesPath = k_ThrowawayCheckedFeatures; - } - - return ComputeGroupingDensity(dataStructure, messageHandler, shouldCancel, &inputValues)(); -} - -namespace -{ -namespace SIMPL -{ -constexpr StringLiteral k_CheckedFeaturesArrayNameKey = "CheckedFeaturesArrayName"; -constexpr StringLiteral k_ContiguousNeighborListArrayPathKey = "ContiguousNeighborListArrayPath"; -constexpr StringLiteral k_FindCheckedFeaturesKey = "FindCheckedFeatures"; -constexpr StringLiteral k_NonContiguousNeighborListArrayPathKey = "NonContiguousNeighborListArrayPath"; -constexpr StringLiteral k_ParentDensitiesArrayNameKey = "ParentDensitiesArrayName"; -constexpr StringLiteral k_ParentIdsArrayPathKey = "ParentIdsArrayPath"; -constexpr StringLiteral k_ParentVolumesArrayPathKey = "ParentVolumesArrayPath"; -constexpr StringLiteral k_UseNonContiguousNeighborsKey = "UseNonContiguousNeighbors"; -constexpr StringLiteral k_VolumesArrayPathKey = "VolumesArrayPath"; -} // namespace SIMPL -} // namespace - -Result ComputeGroupingDensityFilter::FromSIMPLJson(const nlohmann::json& json) -{ - Arguments args = ComputeGroupingDensityFilter().getDefaultArguments(); - - std::vector> results; - - results.push_back(SIMPLConversion::ConvertParameter(args, json, SIMPL::k_CheckedFeaturesArrayNameKey, k_CheckedFeaturesName_Key)); - results.push_back( - SIMPLConversion::ConvertParameter(args, json, SIMPL::k_ContiguousNeighborListArrayPathKey, k_ContiguousNeighborListArrayPath_Key)); - results.push_back(SIMPLConversion::ConvertParameter(args, json, SIMPL::k_FindCheckedFeaturesKey, k_FindCheckedFeatures_Key)); - results.push_back(SIMPLConversion::ConvertParameter(args, json, SIMPL::k_NonContiguousNeighborListArrayPathKey, - k_NonContiguousNeighborListArrayPath_Key)); - results.push_back(SIMPLConversion::ConvertParameter(args, json, SIMPL::k_ParentDensitiesArrayNameKey, k_GroupingDensitiesName_Key)); - results.push_back(SIMPLConversion::ConvertParameter(args, json, SIMPL::k_ParentIdsArrayPathKey, k_ParentIdsPath_Key)); - results.push_back(SIMPLConversion::ConvertParameter(args, json, SIMPL::k_ParentVolumesArrayPathKey, k_ParentVolumesPath_Key)); - results.push_back(SIMPLConversion::ConvertParameter(args, json, SIMPL::k_UseNonContiguousNeighborsKey, k_UseNonContiguousNeighbors_Key)); - results.push_back(SIMPLConversion::ConvertParameter(args, json, SIMPL::k_VolumesArrayPathKey, k_VolumesArrayPath_Key)); - - Result<> conversionResult = MergeResults(std::move(results)); - - return ConvertResultTo(std::move(conversionResult), std::move(args)); -} -} // namespace nx::core diff --git a/src/SimplnxReview/SimplnxReviewLegacyUUIDMapping.hpp b/src/SimplnxReview/SimplnxReviewLegacyUUIDMapping.hpp index d56f487..6e8ca58 100644 --- a/src/SimplnxReview/SimplnxReviewLegacyUUIDMapping.hpp +++ b/src/SimplnxReview/SimplnxReviewLegacyUUIDMapping.hpp @@ -10,7 +10,6 @@ #include "SimplnxReview/Filters/ComputeSaltykovSizesFilter.hpp" #include "SimplnxReview/Filters/ComputeMicroTextureRegionsFilter.hpp" #include "SimplnxReview/Filters/ComputeLocalAverageCAxisMisalignmentsFilter.hpp" -#include "SimplnxReview/Filters/ComputeGroupingDensityFilter.hpp" // @@__HEADER__TOKEN__DO__NOT__DELETE__@@ @@ -27,7 +26,6 @@ namespace nx::core {nx::core::Uuid::FromString("cc76cffe-81ad-5ece-be2a-ce127c5fa6d7").value(), {nx::core::FilterTraits::uuid, &ComputeSaltykovSizesFilter::FromSIMPLJson}}, // FindSaltykovSizes {nx::core::Uuid::FromString("90f8e3b1-2460-5862-95a1-a9e06f5ee75e").value(), {nx::core::FilterTraits::uuid, &ComputeMicroTextureRegionsFilter::FromSIMPLJson}}, // FindMicroTextureRegions {nx::core::Uuid::FromString("49b2dd47-bb29-50d4-a051-5bad9b6b9f80").value(), {nx::core::FilterTraits::uuid, &ComputeLocalAverageCAxisMisalignmentsFilter::FromSIMPLJson}}, // FindLocalAverageCAxisMisalignments - {nx::core::Uuid::FromString("708be082-8b08-4db2-94be-52781ed4d53d").value(), {nx::core::FilterTraits::uuid, &ComputeGroupingDensityFilter::FromSIMPLJson}}, // FindGroupingDensity // @@__MAP__UPDATE__TOKEN__DO__NOT__DELETE__@@ };