Skip to content

Commit 4eb8faa

Browse files
committed
FILT: Compute Direction Vectors filter has been added.
No unit test has been created.
1 parent 363e4a8 commit 4eb8faa

6 files changed

Lines changed: 593 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ set(${PLUGIN_NAME}_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
3030
# These are all the filters in the plugin. All filters should be kept in the
3131
# SimplnxReview/src/SimplnxReview/Filters/ directory.
3232
set(FilterList
33+
ComputeDirectionVectorsFilter
34+
ComputeGroupingDensityFilter
3335
ComputeLocalAverageCAxisMisalignmentsFilter
3436
ComputeMicroTextureRegionsFilter
3537
ComputeSaltykovSizesFilter
@@ -46,6 +48,8 @@ set(ActionList
4648
# This should be integrated with the `create_simplnx_plugin` function call
4749
# ------------------------------------------------------------------------------
4850
set(AlgorithmList
51+
ComputeDirectionVectors
52+
ComputeGroupingDensity
4953
ComputeLocalAverageCAxisMisalignments
5054
ComputeMicroTextureRegions
5155
ComputeSaltykovSizes
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Compute Direction Vectors
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** computes the crystallographic Z Axis in a cartesian coordinate system.
13+
14+
This results from this filter can then be used in various visualization applications to visually inspect the crystallographic system.
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: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
#include "ComputeDirectionVectors.hpp"
2+
3+
#include "EbsdLib/Core/Orientation.hpp"
4+
#include "EbsdLib/Orientation/AxisAngle.hpp"
5+
#include "EbsdLib/Orientation/Euler.hpp"
6+
#include "EbsdLib/Orientation/OrientationMatrix.hpp"
7+
#include "EbsdLib/Orientation/Quaternion.hpp"
8+
#include "EbsdLib/Orientation/Rodrigues.hpp"
9+
10+
#include <Eigen/Core>
11+
12+
#include "simplnx/Common/Constants.hpp"
13+
#include "simplnx/DataStructure/DataArray.hpp"
14+
#include "simplnx/Utilities/DataArrayUtilities.hpp"
15+
#include "simplnx/Utilities/ParallelTaskAlgorithm.hpp"
16+
17+
using namespace nx::core;
18+
19+
namespace
20+
{
21+
/**
22+
*
23+
* @param latticeParameters The lattice Parameters in the order, a, b, c, alpha, beta, gamma. Note that alpha, beta, gamma are all stored as degrees.
24+
* @return
25+
*/
26+
template <typename T>
27+
ebsdlib::Matrix3X3<T> DirectStructureMatrix(const Vec3<float32>& latticeParametersLengths, const Vec3<float32>& latticeParametersAngles)
28+
{
29+
/* This code is taken from EMsoftOO/mod_crystallography.f90 - computeMatrices() function */
30+
31+
T a = latticeParametersLengths[0];
32+
T b = latticeParametersLengths[1];
33+
T c = latticeParametersLengths[2];
34+
T alpha = latticeParametersAngles[0];
35+
T beta = latticeParametersAngles[1];
36+
T gamma = latticeParametersAngles[2];
37+
38+
// auxiliary variables for the various tensors
39+
T pirad = Constants::k_PiOver180F;
40+
T ca = std::cos(pirad * alpha);
41+
T cb = std::cos(pirad * beta);
42+
T cg = std::cos(pirad * gamma);
43+
T sg = std::sin(pirad * gamma);
44+
45+
// cell volume via the determinant of dmt
46+
T det = (a * b * c) * (a * b * c) * (1.0f - ca * ca - cb * cb - cg * cg + 1.0f * ca * cb * cg);
47+
T vol = std::sqrt(det);
48+
49+
ebsdlib::Matrix3X3<T> dsm;
50+
dsm[0] = a;
51+
dsm[1] = b * cg;
52+
dsm[2] = c * cb;
53+
dsm[3] = 0.0;
54+
dsm[4] = b * sg;
55+
dsm[5] = -c * (cb * cg - ca) / sg;
56+
dsm[6] = 0.0;
57+
dsm[7] = 0.0;
58+
dsm[8] = vol / (a * b * sg);
59+
return dsm;
60+
}
61+
62+
template <typename T>
63+
class ComputeDirectionVectorsImpl
64+
{
65+
public:
66+
ComputeDirectionVectorsImpl(const DataArray<T>& inputOrientationsArray, ebsdlib::orientations::Type inputRepType, const ebsdlib::Matrix3X1<T>& cartesian, Float32Array& outputArray,
67+
const std::atomic_bool& shouldCancel)
68+
: m_InputOrientationsArray(inputOrientationsArray)
69+
, m_InputRepType(inputRepType)
70+
, m_Cartesian(cartesian)
71+
, m_OutputArray(outputArray)
72+
, m_ShouldCancel(shouldCancel)
73+
{
74+
}
75+
~ComputeDirectionVectorsImpl() = default;
76+
77+
ComputeDirectionVectorsImpl(const ComputeDirectionVectorsImpl&) = default;
78+
ComputeDirectionVectorsImpl(ComputeDirectionVectorsImpl&&) noexcept = default;
79+
ComputeDirectionVectorsImpl& operator=(const ComputeDirectionVectorsImpl&) = delete;
80+
ComputeDirectionVectorsImpl& operator=(ComputeDirectionVectorsImpl&&) noexcept = delete;
81+
82+
void convert(usize start, usize end) const
83+
{
84+
// For each orientation matrix, convert to gmatrix, transpose, and multiply by the cartesian point.
85+
// The result is the direction vector that will be stored in the output array.
86+
87+
const auto& inputOrientationsDataStore = m_InputOrientationsArray.template getIDataStoreRefAs<AbstractDataStore<T>>();
88+
auto& outputDataStore = m_OutputArray.template getIDataStoreRefAs<AbstractDataStore<float32>>();
89+
ebsdlib::OrientationMatrix<T> om;
90+
for(usize i = start; i < end; i++)
91+
{
92+
if(m_ShouldCancel)
93+
{
94+
return;
95+
}
96+
97+
switch(m_InputRepType)
98+
{
99+
case ebsdlib::orientations::Type::Euler: {
100+
// Euler has 3 components
101+
om = ebsdlib::Euler<T>(inputOrientationsDataStore.getValue(i * 3), inputOrientationsDataStore.getValue(i * 3 + 1), inputOrientationsDataStore.getValue(i * 3 + 2)).toOrientationMatrix();
102+
break;
103+
}
104+
case ebsdlib::orientations::Type::OrientationMatrix: {
105+
// OrientationMatrix has 9 components
106+
om = ebsdlib::OrientationMatrix<T>(inputOrientationsDataStore.getValue(i * 3), inputOrientationsDataStore.getValue(i * 3 + 1), inputOrientationsDataStore.getValue(i * 3 + 2),
107+
inputOrientationsDataStore.getValue(i * 3 + 3), inputOrientationsDataStore.getValue(i * 3 + 4), inputOrientationsDataStore.getValue(i * 3 + 5),
108+
inputOrientationsDataStore.getValue(i * 3 + 6), inputOrientationsDataStore.getValue(i * 3 + 7), inputOrientationsDataStore.getValue(i * 3 + 8));
109+
break;
110+
}
111+
case ebsdlib::orientations::Type::Rodrigues: {
112+
// Rodrigues has 4 components
113+
om = ebsdlib::Rodrigues<T>(inputOrientationsDataStore.getValue(i * 3), inputOrientationsDataStore.getValue(i * 3 + 1), inputOrientationsDataStore.getValue(i * 3 + 2),
114+
inputOrientationsDataStore.getValue(i * 3 + 3))
115+
.toOrientationMatrix();
116+
break;
117+
}
118+
case ebsdlib::orientations::Type::Quaternion: {
119+
// Quaternion has 4 components
120+
om = ebsdlib::Quaternion<T>(inputOrientationsDataStore.getValue(i * 3), inputOrientationsDataStore.getValue(i * 3 + 1), inputOrientationsDataStore.getValue(i * 3 + 2),
121+
inputOrientationsDataStore.getValue(i * 3 + 3))
122+
.toOrientationMatrix();
123+
break;
124+
}
125+
case ebsdlib::orientations::Type::AxisAngle: {
126+
// AxisAngle has 4 components
127+
om = ebsdlib::AxisAngle<T>(inputOrientationsDataStore.getValue(i * 3), inputOrientationsDataStore.getValue(i * 3 + 1), inputOrientationsDataStore.getValue(i * 3 + 2),
128+
inputOrientationsDataStore.getValue(i * 3 + 3))
129+
.toOrientationMatrix();
130+
break;
131+
}
132+
case ebsdlib::orientations::Type::Homochoric: {
133+
// Homochoric has 3 components
134+
om = ebsdlib::Homochoric<T>(inputOrientationsDataStore.getValue(i * 3), inputOrientationsDataStore.getValue(i * 3 + 1), inputOrientationsDataStore.getValue(i * 3 + 2)).toOrientationMatrix();
135+
break;
136+
}
137+
case ebsdlib::orientations::Type::Cubochoric: {
138+
// Cubochoric has 3 components
139+
om = ebsdlib::Cubochoric<T>(inputOrientationsDataStore.getValue(i * 3), inputOrientationsDataStore.getValue(i * 3 + 1), inputOrientationsDataStore.getValue(i * 3 + 2)).toOrientationMatrix();
140+
break;
141+
}
142+
case ebsdlib::orientations::Type::Stereographic: {
143+
// Stereographic has 3 components
144+
om =
145+
ebsdlib::Stereographic<T>(inputOrientationsDataStore.getValue(i * 3), inputOrientationsDataStore.getValue(i * 3 + 1), inputOrientationsDataStore.getValue(i * 3 + 2)).toOrientationMatrix();
146+
break;
147+
}
148+
case ebsdlib::orientations::Type::Unknown: {
149+
throw std::runtime_error("Unknown Orientation Representation Type. This should not happen, contact the developers.");
150+
}
151+
}
152+
153+
ebsdlib::Matrix3X1<T> point = om.toGMatrix().transpose() * m_Cartesian;
154+
std::copy(point.data(), point.data() + 3, outputDataStore.begin() + i * outputDataStore.getNumberOfComponents());
155+
156+
// std::cout << fmt::format("Cartesian: ({}, {}, {})", m_Cartesian[0], m_Cartesian[1], m_Cartesian[2]) << std::endl;
157+
// std::cout << fmt::format("Point: ({}, {}, {})", point[0], point[1], point[2]) << std::endl;
158+
}
159+
}
160+
161+
void operator()() const
162+
{
163+
convert(0, m_InputOrientationsArray.getNumberOfTuples());
164+
}
165+
166+
private:
167+
const DataArray<T>& m_InputOrientationsArray;
168+
Float32Array& m_OutputArray;
169+
const ebsdlib::Matrix3X1<T>& m_Cartesian;
170+
ebsdlib::orientations::Type m_InputRepType;
171+
const std::atomic_bool& m_ShouldCancel;
172+
};
173+
174+
template <typename T, typename = std::enable_if_t<std::is_same_v<T, float32> || std::is_same_v<T, float64>>>
175+
Result<> ExecuteComputeDirectionVectors(DataStructure& dataStructure, const DataPath& inputOrientationsArrayPath, const DataPath& outputArrayPath, ebsdlib::orientations::Type inputRepType,
176+
const Vec3<float32>& latticeParametersLengths, const Vec3<float32>& latticeParametersAngles, const IFilter::MessageHandler& msgHandler,
177+
const std::atomic_bool& shouldCancel)
178+
{
179+
msgHandler("Computing Direction Vectors...");
180+
181+
// Convert the lattice parameters to a direct structure matrix, and calculate the cartesian point
182+
ebsdlib::Matrix3X3<T> dsm = DirectStructureMatrix<T>(latticeParametersLengths, latticeParametersAngles);
183+
ebsdlib::Matrix3X1<T> latticePoint(0.0f, 0.0f, 1.0f);
184+
auto cartesian = dsm * latticePoint;
185+
186+
// Parallelize the implementation method
187+
ParallelTaskAlgorithm taskRunner;
188+
auto& inputOrientationsArray = dataStructure.getDataRefAs<DataArray<T>>(inputOrientationsArrayPath);
189+
auto& outputArray = dataStructure.getDataRefAs<Float32Array>(outputArrayPath);
190+
taskRunner.template execute<>(ComputeDirectionVectorsImpl<T>(inputOrientationsArray, inputRepType, cartesian, outputArray, shouldCancel));
191+
192+
return {};
193+
}
194+
} // namespace
195+
196+
// -----------------------------------------------------------------------------
197+
ComputeDirectionVectors::ComputeDirectionVectors(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel,
198+
ComputeDirectionVectorsInputValues* inputValues)
199+
: m_DataStructure(dataStructure)
200+
, m_InputValues(inputValues)
201+
, m_ShouldCancel(shouldCancel)
202+
, m_MessageHandler(mesgHandler)
203+
{
204+
}
205+
206+
// -----------------------------------------------------------------------------
207+
ComputeDirectionVectors::~ComputeDirectionVectors() noexcept = default;
208+
209+
// -----------------------------------------------------------------------------
210+
Result<> ComputeDirectionVectors::operator()()
211+
{
212+
Vec3<float32> latticeParametersLengths;
213+
Vec3<float32> latticeParametersAngles;
214+
switch(m_InputValues->LatticeConstantsInputType)
215+
{
216+
case LatticeConstantsInputType::DataArrayPath: {
217+
auto& latticeConstantsArray = m_DataStructure.getDataRefAs<Float32Array>(m_InputValues->LatticeConstantsArrayPath);
218+
latticeParametersLengths[0] = latticeConstantsArray[0];
219+
latticeParametersLengths[1] = latticeConstantsArray[1];
220+
latticeParametersLengths[2] = latticeConstantsArray[2];
221+
latticeParametersAngles[0] = latticeConstantsArray[3];
222+
latticeParametersAngles[1] = latticeConstantsArray[4];
223+
latticeParametersAngles[2] = latticeConstantsArray[5];
224+
break;
225+
}
226+
case LatticeConstantsInputType::Manual: {
227+
latticeParametersLengths = m_InputValues->ManualLatticeConstantsLengths;
228+
latticeParametersAngles = m_InputValues->ManualLatticeConstantsAngles;
229+
break;
230+
}
231+
}
232+
233+
DataPath orientationsParentPath = m_InputValues->InputOrientationsArrayPath.getParent();
234+
DataPath outputDirectionVectorsPath = orientationsParentPath.createChildPath(m_InputValues->OutputDirectionVectorsArrayName);
235+
236+
auto& inputOrientationsArray = m_DataStructure.getDataRefAs<IDataArray>(m_InputValues->InputOrientationsArrayPath);
237+
DataType inputDataType = inputOrientationsArray.getDataType();
238+
switch(inputDataType)
239+
{
240+
case DataType::float32: {
241+
return ExecuteComputeDirectionVectors<float32>(m_DataStructure, m_InputValues->InputOrientationsArrayPath, outputDirectionVectorsPath, m_InputValues->InputRepType, latticeParametersLengths,
242+
latticeParametersAngles, m_MessageHandler, m_ShouldCancel);
243+
}
244+
case DataType::float64: {
245+
return ExecuteComputeDirectionVectors<float64>(m_DataStructure, m_InputValues->InputOrientationsArrayPath, outputDirectionVectorsPath, m_InputValues->InputRepType, latticeParametersLengths,
246+
latticeParametersAngles, m_MessageHandler, m_ShouldCancel);
247+
}
248+
default: {
249+
return MakeErrorResult(
250+
-2300, fmt::format("Input Orientations array has incompatible data type: the data type is {} but this filter only supports float32 and float64 data types.", DataTypeToString(inputDataType)));
251+
}
252+
}
253+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#pragma once
2+
3+
#include "SimplnxReview/SimplnxReview_export.hpp"
4+
5+
#include "EbsdLib/Orientation/OrientationFwd.hpp"
6+
7+
#include "simplnx/Common/Array.hpp"
8+
#include "simplnx/DataStructure/DataPath.hpp"
9+
#include "simplnx/Filter/IFilter.hpp"
10+
#include "simplnx/Parameters/ChoicesParameter.hpp"
11+
12+
namespace nx::core
13+
{
14+
enum LatticeConstantsInputType : uint8
15+
{
16+
DataArrayPath = 0,
17+
Manual = 1
18+
};
19+
20+
struct SIMPLNXREVIEW_EXPORT ComputeDirectionVectorsInputValues
21+
{
22+
ebsdlib::orientations::Type InputRepType;
23+
DataPath InputOrientationsArrayPath;
24+
LatticeConstantsInputType LatticeConstantsInputType;
25+
DataPath LatticeConstantsArrayPath;
26+
FloatVec3 ManualLatticeConstantsLengths;
27+
FloatVec3 ManualLatticeConstantsAngles;
28+
std::string OutputDirectionVectorsArrayName;
29+
};
30+
31+
/**
32+
* @class
33+
*/
34+
class SIMPLNXREVIEW_EXPORT ComputeDirectionVectors
35+
{
36+
public:
37+
ComputeDirectionVectors(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ComputeDirectionVectorsInputValues* inputValues);
38+
~ComputeDirectionVectors() noexcept;
39+
40+
ComputeDirectionVectors(const ComputeDirectionVectors&) = delete;
41+
ComputeDirectionVectors(ComputeDirectionVectors&&) noexcept = delete;
42+
ComputeDirectionVectors& operator=(const ComputeDirectionVectors&) = delete;
43+
ComputeDirectionVectors& operator=(ComputeDirectionVectors&&) noexcept = delete;
44+
45+
Result<> operator()();
46+
47+
private:
48+
DataStructure& m_DataStructure;
49+
const ComputeDirectionVectorsInputValues* m_InputValues = nullptr;
50+
const std::atomic_bool& m_ShouldCancel;
51+
const IFilter::MessageHandler& m_MessageHandler;
52+
};
53+
} // namespace nx::core

0 commit comments

Comments
 (0)