Skip to content

Commit ffb9f67

Browse files
joeykleingersimikejackson
authored andcommitted
FILT: ComputeEquivalentDiameterCirclesFilter
Signed-off-by: Joey Kleingers <joey.kleingers@bluequartz.net>
1 parent 4e58118 commit ffb9f67

6 files changed

Lines changed: 417 additions & 0 deletions

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set(${PLUGIN_NAME}_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
2727
# These are all the filters in the plugin. All filters should be kept in the
2828
# SimplnxReview/src/SimplnxReview/Filters/ directory.
2929
set(FilterList
30+
ComputeEquivalentDiameterCirclesFilter
3031
ComputeGroupingDensityFilter
3132
ComputeLocalAverageCAxisMisalignmentsFilter
3233
ComputeMicroTextureRegionsFilter
@@ -44,6 +45,7 @@ set(ActionList
4445
# This should be integrated with the `create_simplnx_plugin` function call
4546
# ------------------------------------------------------------------------------
4647
set(AlgorithmList
48+
ComputeEquivalentDiameterCircles
4749
ComputeGroupingDensity
4850
ComputeLocalAverageCAxisMisalignments
4951
ComputeMicroTextureRegions
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Compute Equivalent Diameter Circles
2+
3+
**THIS FILTER IS UNTESTED, UNVERIFIED AND UNVALIDATED. IT IS AN EXPERIMENTAL FILTER THAT IS UNDERGOING LONG TERM DEVELOPMENT
4+
AND TESTING. USE AT YOUR OWN RISK**
5+
6+
## Group (Subgroup)
7+
8+
Visualization Helpers
9+
10+
## Description
11+
12+
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.
13+
14+
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.
15+
16+
% Auto generated parameter table will be inserted here
17+
18+
## References
19+
20+
## Example Pipelines
21+
22+
## License & Copyright
23+
24+
Please see the description file distributed with this **Plugin**
25+
26+
## DREAM3D-NX Help
27+
28+
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.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include "ComputeEquivalentDiameterCircles.hpp"
2+
3+
#include "simplnx/DataStructure/DataArray.hpp"
4+
#include "simplnx/DataStructure/Geometry/EdgeGeom.hpp"
5+
#include "simplnx/Common/Constants.hpp"
6+
7+
#include <cmath>
8+
9+
using namespace nx::core;
10+
11+
// -----------------------------------------------------------------------------
12+
ComputeEquivalentDiameterCircles::ComputeEquivalentDiameterCircles(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel,
13+
ComputeEquivalentDiameterCirclesInputValues* inputValues)
14+
: m_DataStructure(dataStructure)
15+
, m_InputValues(inputValues)
16+
, m_ShouldCancel(shouldCancel)
17+
, m_MessageHandler(mesgHandler)
18+
{
19+
}
20+
21+
// -----------------------------------------------------------------------------
22+
const std::atomic_bool& ComputeEquivalentDiameterCircles::getCancel()
23+
{
24+
return m_ShouldCancel;
25+
}
26+
27+
// -----------------------------------------------------------------------------
28+
Result<> ComputeEquivalentDiameterCircles::operator()()
29+
{
30+
auto& centroidsArray = m_DataStructure.getDataRefAs<Float32Array>(m_InputValues->CentroidsArrayPath);
31+
auto& equivalentDiametersArray = m_DataStructure.getDataRefAs<Float32Array>(m_InputValues->EquivalentDiametersArrayPath);
32+
DataPath featureIdsPath = m_InputValues->OutputEdgeGeometryPath.createChildPath(m_InputValues->EdgeAttributeMatrixName).createChildPath(m_InputValues->FeatureIdsArrayName);
33+
auto& featureIdsArray = m_DataStructure.getDataRefAs<Int32Array>(featureIdsPath);
34+
auto& outputEdgeGeom = m_DataStructure.getDataRefAs<EdgeGeom>(m_InputValues->OutputEdgeGeometryPath);
35+
Float32Array& verticesArray = outputEdgeGeom.getVerticesRef();
36+
UInt64Array& edgesArray = outputEdgeGeom.getEdgesRef();
37+
38+
usize circleResolution = m_InputValues->CircleResolution;
39+
usize verticesPerCircle = circleResolution + 1;
40+
usize edgeIdx = 0;
41+
42+
for(usize i = 1; i < centroidsArray.getNumberOfTuples(); ++i)
43+
{
44+
float32 r = equivalentDiametersArray[i] / 2.0f;
45+
float32 cx = centroidsArray.getComponent(i, 0);
46+
float32 cy = centroidsArray.getComponent(i, 1);
47+
48+
usize circleVertexStart = (i - 1) * verticesPerCircle;
49+
50+
for(usize v = 0; v < verticesPerCircle; ++v)
51+
{
52+
usize vertexIdx = circleVertexStart + v;
53+
54+
float32 theta = 2.0f * nx::core::Constants::k_PiF * static_cast<float32>(v) / static_cast<float32>(circleResolution);
55+
56+
float32 x = cx + r * std::cos(theta);
57+
float32 y = cy + r * std::sin(theta);
58+
59+
verticesArray.setComponent(vertexIdx, 0, x);
60+
verticesArray.setComponent(vertexIdx, 1, y);
61+
verticesArray.setComponent(vertexIdx, 2, static_cast<float32>(m_InputValues->ZPlane));
62+
}
63+
64+
for(usize e = 0; e < circleResolution; ++e)
65+
{
66+
usize v0 = circleVertexStart + e;
67+
usize v1 = circleVertexStart + e + 1;
68+
69+
featureIdsArray.setValue(edgeIdx, static_cast<int32>(i));
70+
71+
edgesArray.setComponent(edgeIdx, 0, v0);
72+
edgesArray.setComponent(edgeIdx, 1, v1);
73+
edgeIdx++;
74+
}
75+
}
76+
77+
return {};
78+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#pragma once
2+
3+
#include "SimplnxReview/SimplnxReview_export.hpp"
4+
5+
#include "simplnx/DataStructure/DataPath.hpp"
6+
#include "simplnx/DataStructure/DataStructure.hpp"
7+
#include "simplnx/Filter/IFilter.hpp"
8+
9+
namespace nx::core
10+
{
11+
12+
struct SIMPLNXREVIEW_EXPORT ComputeEquivalentDiameterCirclesInputValues
13+
{
14+
DataPath CentroidsArrayPath;
15+
DataPath EquivalentDiametersArrayPath;
16+
uint64 CircleResolution;
17+
int64 ZPlane;
18+
DataPath OutputEdgeGeometryPath;
19+
std::string EdgeAttributeMatrixName;
20+
std::string FeatureIdsArrayName;
21+
};
22+
23+
/**
24+
* @class ComputeEquivalentDiameterCircles
25+
* @brief This filter determines the average C-axis location of each Feature.
26+
*/
27+
28+
class SIMPLNXREVIEW_EXPORT ComputeEquivalentDiameterCircles
29+
{
30+
public:
31+
ComputeEquivalentDiameterCircles(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel,
32+
ComputeEquivalentDiameterCirclesInputValues* inputValues);
33+
~ComputeEquivalentDiameterCircles() noexcept = default;
34+
35+
ComputeEquivalentDiameterCircles(const ComputeEquivalentDiameterCircles&) = delete;
36+
ComputeEquivalentDiameterCircles(ComputeEquivalentDiameterCircles&&) noexcept = delete;
37+
ComputeEquivalentDiameterCircles& operator=(const ComputeEquivalentDiameterCircles&) = delete;
38+
ComputeEquivalentDiameterCircles& operator=(ComputeEquivalentDiameterCircles&&) noexcept = delete;
39+
40+
Result<> operator()();
41+
42+
const std::atomic_bool& getCancel();
43+
44+
private:
45+
DataStructure& m_DataStructure;
46+
const ComputeEquivalentDiameterCirclesInputValues* m_InputValues = nullptr;
47+
const std::atomic_bool& m_ShouldCancel;
48+
const IFilter::MessageHandler& m_MessageHandler;
49+
};
50+
51+
} // namespace nx::core
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#include "ComputeEquivalentDiameterCirclesFilter.hpp"
2+
3+
#include "SimplnxReview/Filters/Algorithms/ComputeEquivalentDiameterCircles.hpp"
4+
5+
#include "simplnx/DataStructure/DataArray.hpp"
6+
#include "simplnx/Filter/Actions/CreateArrayAction.hpp"
7+
#include "simplnx/Filter/Actions/CreateGeometry1DAction.hpp"
8+
#include "simplnx/Parameters/ArraySelectionParameter.hpp"
9+
#include "simplnx/Parameters/DataGroupCreationParameter.hpp"
10+
#include "simplnx/Parameters/DataObjectNameParameter.hpp"
11+
#include "simplnx/Parameters/NumberParameter.hpp"
12+
13+
using namespace nx::core;
14+
15+
namespace nx::core
16+
{
17+
//------------------------------------------------------------------------------
18+
std::string ComputeEquivalentDiameterCirclesFilter::name() const
19+
{
20+
return FilterTraits<ComputeEquivalentDiameterCirclesFilter>::name.str();
21+
}
22+
23+
//------------------------------------------------------------------------------
24+
std::string ComputeEquivalentDiameterCirclesFilter::className() const
25+
{
26+
return FilterTraits<ComputeEquivalentDiameterCirclesFilter>::className;
27+
}
28+
29+
//------------------------------------------------------------------------------
30+
Uuid ComputeEquivalentDiameterCirclesFilter::uuid() const
31+
{
32+
return FilterTraits<ComputeEquivalentDiameterCirclesFilter>::uuid;
33+
}
34+
35+
//------------------------------------------------------------------------------
36+
std::string ComputeEquivalentDiameterCirclesFilter::humanName() const
37+
{
38+
return "Compute Equivalent Diameter Circles";
39+
}
40+
41+
//------------------------------------------------------------------------------
42+
std::vector<std::string> ComputeEquivalentDiameterCirclesFilter::defaultTags() const
43+
{
44+
return {className()};
45+
}
46+
47+
//------------------------------------------------------------------------------
48+
Parameters ComputeEquivalentDiameterCirclesFilter::parameters() const
49+
{
50+
Parameters params;
51+
// Create the parameter descriptors that are needed for this filter
52+
params.insertSeparator(Parameters::Separator{"Input Parameter(s)"});
53+
params.insert(std::make_unique<ArraySelectionParameter>(k_CentroidsArrayPath_Key, "Feature Centroids", "X, Y, Z coordinates of Feature center of mass", DataPath{},
54+
ArraySelectionParameter::AllowedTypes{DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{3}}));
55+
params.insert(std::make_unique<ArraySelectionParameter>(k_EquivalentDiametersArrayPath_Key, "Equivalent Diameters", "Input feature based Equivalent Diameters", DataPath{},
56+
ArraySelectionParameter::AllowedTypes{DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{1}}));
57+
params.insert(std::make_unique<NumberParameter<uint64>>(k_CircleResolution_Key, "Circle Resolution", "The number of edges that each circle will have", 100));
58+
params.insert(std::make_unique<NumberParameter<int64>>(k_ZPlane_Key, "Z Plane", "The Z plane that the circles will be calculated on.", 0));
59+
60+
params.insertSeparator(Parameters::Separator{"Output Edge Geometry"});
61+
params.insert(std::make_unique<DataGroupCreationParameter>(k_OutputEdgeGeometryPath_Key, "Created Edge Geometry", "The name of the created Edge Geometry", DataPath({"Circles"})));
62+
params.insert(std::make_unique<DataObjectNameParameter>(k_EdgeAttributeMatrixName_Key, "Edge Attribute Matrix", "Attribute Matrix to store information about the created edges", "Edge Data"));
63+
params.insert(std::make_unique<DataObjectNameParameter>(k_CreatedFeatureIdsArrayName_Key, "Edge Feature Ids", "Identifies the Feature Id to which each edge belongs", "Feature Ids"));
64+
65+
return params;
66+
}
67+
68+
//------------------------------------------------------------------------------
69+
IFilter::UniquePointer ComputeEquivalentDiameterCirclesFilter::clone() const
70+
{
71+
return std::make_unique<ComputeEquivalentDiameterCirclesFilter>();
72+
}
73+
74+
//------------------------------------------------------------------------------
75+
IFilter::VersionType ComputeEquivalentDiameterCirclesFilter::parametersVersion() const
76+
{
77+
return 1;
78+
}
79+
80+
//------------------------------------------------------------------------------
81+
IFilter::PreflightResult ComputeEquivalentDiameterCirclesFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler,
82+
const std::atomic_bool& shouldCancel, const ExecutionContext& executionContext) const
83+
{
84+
auto pCentroidsArrayPath = filterArgs.value<DataPath>(k_CentroidsArrayPath_Key);
85+
auto pEquivalentDiametersArrayPath = filterArgs.value<DataPath>(k_EquivalentDiametersArrayPath_Key);
86+
auto pCircleResolution = filterArgs.value<uint64>(k_CircleResolution_Key);
87+
auto pOutputEdgeGeometryPath = filterArgs.value<DataGroupCreationParameter::ValueType>(k_OutputEdgeGeometryPath_Key);
88+
auto pEdgeAttributeMatrixName = filterArgs.value<DataObjectNameParameter::ValueType>(k_EdgeAttributeMatrixName_Key);
89+
auto pFeatureIdsArrayName = filterArgs.value<DataObjectNameParameter::ValueType>(k_CreatedFeatureIdsArrayName_Key);
90+
91+
Result<OutputActions> resultOutputActions;
92+
std::vector<PreflightValue> preflightUpdatedValues;
93+
94+
auto& centroidsArray = dataStructure.getDataRefAs<Float32Array>(pCentroidsArrayPath);
95+
auto& equivalentDiametersArray = dataStructure.getDataRefAs<Float32Array>(pEquivalentDiametersArrayPath);
96+
usize numberOfCentroids = centroidsArray.getNumberOfTuples();
97+
if(numberOfCentroids != equivalentDiametersArray.getNumberOfTuples())
98+
{
99+
return MakePreflightErrorResult(-13860, fmt::format("Centroids array has {} centroids, and the equivalent diameters array has {} diameters. These must be equal.", numberOfCentroids,
100+
equivalentDiametersArray.getNumberOfTuples()));
101+
}
102+
103+
auto createGeometryAction =
104+
std::make_unique<CreateEdgeGeometryAction>(pOutputEdgeGeometryPath, pCircleResolution * (numberOfCentroids - 1), (pCircleResolution + 1) * (numberOfCentroids - 1),
105+
INodeGeometry0D::k_VertexAttributeMatrixName, pEdgeAttributeMatrixName, EdgeGeom::k_SharedVertexListName, EdgeGeom::k_SharedEdgeListName);
106+
resultOutputActions.value().appendAction(std::move(createGeometryAction));
107+
108+
DataPath path = pOutputEdgeGeometryPath.createChildPath(pEdgeAttributeMatrixName).createChildPath(pFeatureIdsArrayName);
109+
auto createArray = std::make_unique<CreateArrayAction>(DataType::int32, std::vector<usize>{pCircleResolution * (numberOfCentroids - 1)}, std::vector<usize>{1}, path);
110+
resultOutputActions.value().appendAction(std::move(createArray));
111+
112+
preflightUpdatedValues.push_back({"WARNING: This filter is experimental in nature and has not had any testing, validation or verification. Use at your own risk"});
113+
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"});
114+
115+
return {std::move(resultOutputActions), std::move(preflightUpdatedValues)};
116+
}
117+
118+
//------------------------------------------------------------------------------
119+
Result<> ComputeEquivalentDiameterCirclesFilter::executeImpl(DataStructure& dataStructure, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler,
120+
const std::atomic_bool& shouldCancel, const ExecutionContext& executionContext) const
121+
{
122+
ComputeEquivalentDiameterCirclesInputValues inputValues;
123+
124+
inputValues.CentroidsArrayPath = filterArgs.value<DataPath>(k_CentroidsArrayPath_Key);
125+
inputValues.EquivalentDiametersArrayPath = filterArgs.value<DataPath>(k_EquivalentDiametersArrayPath_Key);
126+
inputValues.CircleResolution = filterArgs.value<uint64>(k_CircleResolution_Key);
127+
inputValues.ZPlane = filterArgs.value<int64>(k_ZPlane_Key);
128+
inputValues.OutputEdgeGeometryPath = filterArgs.value<DataGroupCreationParameter::ValueType>(k_OutputEdgeGeometryPath_Key);
129+
inputValues.EdgeAttributeMatrixName = filterArgs.value<DataObjectNameParameter::ValueType>(k_EdgeAttributeMatrixName_Key);
130+
inputValues.FeatureIdsArrayName = filterArgs.value<DataObjectNameParameter::ValueType>(k_CreatedFeatureIdsArrayName_Key);
131+
132+
return ComputeEquivalentDiameterCircles(dataStructure, messageHandler, shouldCancel, &inputValues)();
133+
}
134+
} // namespace nx::core

0 commit comments

Comments
 (0)