22
33#include " simplnx/Common/Constants.hpp"
44#include " simplnx/DataStructure/DataArray.hpp"
5- #include " simplnx/DataStructure/DataGroup.hpp"
65#include " simplnx/DataStructure/NeighborList.hpp"
76#include " simplnx/Utilities/Math/GeometryMath.hpp"
87#include " simplnx/Utilities/Math/MatrixMath.hpp"
8+ #include " simplnx/Utilities/MessageHelper.hpp"
99
1010#include " EbsdLib/LaueOps/LaueOps.h"
1111
@@ -81,35 +81,38 @@ bool GroupMicroTextureRegions::growGrouping(int32_t referenceFeature, int32_t ne
8181// -----------------------------------------------------------------------------
8282void GroupMicroTextureRegions::execute ()
8383{
84- NeighborList<int32>& neighborlist = m_DataStructure.getDataRefAs <NeighborList<int32>>(m_InputValues->ContiguousNeighborListArrayPath );
84+ MessageHelper messageHelper (m_MessageHandler);
85+ ThrottledMessenger throttledMessenger = messageHelper.createThrottledMessenger ();
86+
87+ NeighborList<int32>& featureNeighborListRef = m_DataStructure.getDataRefAs <NeighborList<int32>>(m_InputValues->ContiguousNeighborListArrayPath );
8588 NeighborList<int32>* nonContigNeighList = nullptr ;
8689 if (m_InputValues->UseNonContiguousNeighbors )
8790 {
8891 nonContigNeighList = m_DataStructure.getDataAs <NeighborList<int32>>(m_InputValues->NonContiguousNeighborListArrayPath );
8992 }
9093
91- std::vector<int32> grouplist ;
94+ std::vector<int32> groupList ;
9295
93- int32 parentcount = 0 ;
94- int32 seed = 0 ;
95- int32 list1size = 0 , list2size = 0 , listsize = 0 ;
96+ int32 parentCount = 0 ;
97+ int32 featureSeed = 0 ;
98+ int32 list1size = 0 , list2size = 0 , listSize = 0 ;
9699 int32 neigh = 0 ;
97100 bool patchGrouping = false ;
98101
99- while (seed >= 0 )
102+ while (featureSeed >= 0 )
100103 {
101- parentcount ++;
102- seed = getSeed (parentcount );
103- if (seed >= 0 )
104+ parentCount ++;
105+ featureSeed = getSeed (parentCount );
106+ if (featureSeed >= 0 )
104107 {
105- grouplist .push_back (seed );
106- for (std::vector<int32>::size_type j = 0 ; j < grouplist .size (); j++)
108+ groupList .push_back (featureSeed );
109+ for (std::vector<int32>::size_type j = 0 ; j < groupList .size (); j++)
107110 {
108- int32 firstfeature = grouplist [j];
109- list1size = int32 (neighborlist[firstfeature ].size ());
111+ int32 firstFeature = groupList [j];
112+ list1size = static_cast < int32>(featureNeighborListRef[firstFeature ].size ());
110113 if (m_InputValues->UseNonContiguousNeighbors )
111114 {
112- list2size = nonContigNeighList->getListSize (firstfeature );
115+ list2size = nonContigNeighList->getListSize (firstFeature );
113116 }
114117 for (int32 k = 0 ; k < 2 ; k++)
115118 {
@@ -119,30 +122,30 @@ void GroupMicroTextureRegions::execute()
119122 }
120123 if (k == 0 )
121124 {
122- listsize = list1size;
125+ listSize = list1size;
123126 }
124127 else if (k == 1 )
125128 {
126- listsize = list2size;
129+ listSize = list2size;
127130 }
128- for (int32 l = 0 ; l < listsize ; l++)
131+ for (int32 l = 0 ; l < listSize ; l++)
129132 {
130133 if (k == 0 )
131134 {
132- neigh = neighborlist[firstfeature ][l];
135+ neigh = featureNeighborListRef[firstFeature ][l];
133136 }
134137 else if (k == 1 )
135138 {
136139 bool ok = false ;
137- neigh = nonContigNeighList->getValue (firstfeature , l, ok);
140+ neigh = nonContigNeighList->getValue (firstFeature , l, ok);
138141 }
139- if (neigh != firstfeature )
142+ if (neigh != firstFeature )
140143 {
141- if (determineGrouping (firstfeature , neigh, parentcount ))
144+ if (determineGrouping (firstFeature , neigh, parentCount ))
142145 {
143146 if (!patchGrouping)
144147 {
145- grouplist .push_back (neigh);
148+ groupList .push_back (neigh);
146149 }
147150 }
148151 }
@@ -151,35 +154,39 @@ void GroupMicroTextureRegions::execute()
151154 }
152155 if (patchGrouping)
153156 {
154- if (growPatch (parentcount ))
157+ if (growPatch (parentCount ))
155158 {
156- for (std::vector<int32_t >::size_type j = 0 ; j < grouplist .size (); j++)
159+ for (std::vector<int32_t >::size_type j = 0 ; j < groupList .size (); j++)
157160 {
158- int32_t firstfeature = grouplist [j];
159- listsize = int32_t (neighborlist[firstfeature ].size ());
160- for (int32_t l = 0 ; l < listsize ; l++)
161+ int32_t firstFeature = groupList [j];
162+ listSize = static_cast < int32_t >(featureNeighborListRef[firstFeature ].size ());
163+ for (int32_t l = 0 ; l < listSize ; l++)
161164 {
162- neigh = neighborlist[firstfeature ][l];
163- if (neigh != firstfeature )
165+ neigh = featureNeighborListRef[firstFeature ][l];
166+ if (neigh != firstFeature )
164167 {
165- if (growGrouping (firstfeature , neigh, parentcount ))
168+ if (growGrouping (firstFeature , neigh, parentCount ))
166169 {
167- grouplist .push_back (neigh);
170+ groupList .push_back (neigh);
168171 }
169172 }
170173 }
171174 }
172175 }
173176 }
177+
178+ throttledMessenger.sendThrottledMessage ([&]() { return fmt::format (" Parent Count: {}" , parentCount); });
174179 }
175- grouplist .clear ();
180+ groupList .clear ();
176181 }
177182}
178183
179184// -----------------------------------------------------------------------------
180185Result<> GroupMicroTextureRegions::operator ()()
181186{
182- m_Generator = std::mt19937_64 (m_InputValues->SeedValue );
187+ MessageHelper messageHelper (m_MessageHandler);
188+
189+ m_Generator = std::mt19937_64 (std::mt19937::default_seed);
183190 m_Distribution = std::uniform_real_distribution<float32>(0 .0f , 1 .0f );
184191
185192 m_AvgCAxes[0 ] = 0 .0f ;
@@ -188,6 +195,9 @@ Result<> GroupMicroTextureRegions::operator()()
188195 auto & featureParentIds = m_DataStructure.getDataRefAs <Int32Array>(m_InputValues->FeatureParentIdsArrayName );
189196 featureParentIds.fill (-1 );
190197
198+ // Execute the main grouping algorithm
199+ messageHelper.sendMessage (fmt::format (" Starting Grouping....." ));
200+
191201 execute ();
192202
193203 // handle active array resize
@@ -206,8 +216,8 @@ Result<> GroupMicroTextureRegions::operator()()
206216 }
207217
208218 // By default we randomize grains !!! COMMENT OUT FOR DEMONSTRATION !!!
209- m_MessageHandler (IFilter::Message::Type::Info, " Randomizing Parent Ids" );
210- RandomizeFeatureIds (totalPoints, m_NumTuples, cellParentIds, featureParentIds, featureIds, m_InputValues->SeedValue );
219+ // m_MessageHandler(IFilter::Message::Type::Info, "Randomizing Parent Ids");
220+ // RandomizeFeatureIds(totalPoints, m_NumTuples, cellParentIds, featureParentIds, featureIds, m_InputValues->SeedValue);
211221
212222 return {};
213223}
@@ -220,24 +230,32 @@ int GroupMicroTextureRegions::getSeed(int32 newFid)
220230
221231 usize numFeatures = featurePhases.getNumberOfTuples ();
222232
223- float32 g1[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
224- float32 g1t[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
225- int32 voxelSeed = -1 ;
233+ float32 g1[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }, { 0 . 0f , 0 . 0f , 0 . 0f } };
234+ float32 g1t[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }, { 0 . 0f , 0 . 0f , 0 . 0f } };
235+ int32 featureIdSeed = -1 ;
226236
227237 // Precalculate some constants
228- int32 totalFMinus1 = numFeatures - 1 ;
238+ const int32 totalFMinus1 = static_cast <int32>( numFeatures) - 1 ;
229239
230240 usize counter = 0 ;
241+ // This section finds a feature id that has not been grouped yet. It starts by
242+ // randomly selecting a feature id between 0 and numFeatures-1. We then start
243+ // looping. If the initial random value is valid then we exit the loop after
244+ // a single iteration. If that feature has already been grouped, then we add one
245+ // to the `randFeature` value and try again. If we get to the end of the range of
246+ // featureIds then the algorithm will loop back to featureId = 0 and start incrementing
247+ // from there. This is reasonably efficient as we only generate random numbers
248+ // as needed.
231249 auto randFeature = static_cast <int32>(m_Distribution (m_Generator) * static_cast <float32>(totalFMinus1));
232- while (voxelSeed == -1 && counter < numFeatures)
250+ while (featureIdSeed == -1 && counter < numFeatures)
233251 {
234252 if (randFeature > totalFMinus1)
235253 {
236254 randFeature = randFeature - numFeatures;
237255 }
238256 if (featureParentIds[randFeature] == -1 )
239257 {
240- voxelSeed = randFeature;
258+ featureIdSeed = randFeature;
241259 }
242260 randFeature++;
243261 counter++;
@@ -251,17 +269,17 @@ int GroupMicroTextureRegions::getSeed(int32 newFid)
251269 // fout << fmt::format("Feature Parent Id: {} | X: {}, Y: {}\n", voxelSeed, centroids.getComponent(voxelSeed, 0), centroids.getComponent(voxelSeed, 1));
252270 // }
253271
254- if (voxelSeed >= 0 )
272+ if (featureIdSeed >= 0 )
255273 {
256- featureParentIds[voxelSeed ] = newFid;
274+ featureParentIds[featureIdSeed ] = newFid;
257275 m_NumTuples = newFid + 1 ;
258276
259277 if (m_InputValues->UseRunningAverage )
260278 {
261279 auto & volumes = m_DataStructure.getDataRefAs <Float32Array>(m_InputValues->VolumesArrayPath );
262280 auto & avgQuats = m_DataStructure.getDataRefAs <Float32Array>(m_InputValues->AvgQuatsArrayPath );
263281
264- usize index = voxelSeed * 4 ;
282+ usize index = featureIdSeed * 4 ;
265283 OrientationTransformation::qu2om<QuatF, OrientationF>({avgQuats[index + 0 ], avgQuats[index + 1 ], avgQuats[index + 2 ], avgQuats[index + 3 ]}).toGMatrix (g1);
266284
267285 std::array<float32, 3 > c1 = {0 .0f , 0 .0f , 0 .0f };
@@ -274,21 +292,34 @@ int GroupMicroTextureRegions::getSeed(int32 newFid)
274292 // dividing by the magnitudes (they would be 1)
275293 MatrixMath::Normalize3x1 (c1.data ());
276294 MatrixMath::Copy3x1 (c1.data (), m_AvgCAxes.data ());
277- MatrixMath::Multiply3x1withConstant (m_AvgCAxes.data (), volumes.getValue (voxelSeed ));
295+ MatrixMath::Multiply3x1withConstant (m_AvgCAxes.data (), volumes.getValue (featureIdSeed ));
278296 }
279297 }
280298
281- return voxelSeed ;
299+ return featureIdSeed ;
282300}
283301
284302// -----------------------------------------------------------------------------
285303bool GroupMicroTextureRegions::determineGrouping (int32 referenceFeature, int32 neighborFeature, int32 newFid)
286304{
287305 uint32 phase1 = 0 ;
288- float32 g1[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
289- float32 g2[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
290- float32 g1t[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
291- float32 g2t[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
306+ /* *
307+ * referenceFeature is Cubic Phase
308+ * neighborFeature is Hex Phase
309+ * m_InputValues->UseRunningAverage = TRUE
310+ * First `if` check is passed
311+ * Second `if` check is passed, `phase1` stays at HEX
312+ * Third `if` check will pass because the 2nd phase is HEX
313+ * Probably should not be happening?
314+ * Solution: Properly initialize the `phase` outside of all checks or just before the `phase2` initialization
315+ * Bug introduced JAN 30, 2014 by J. Tucker commit `7e49e52f362005e44ea9bf21b7a717277b2af04e` in Original DREAM3D repository
316+
317+ */
318+
319+ float32 g1[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
320+ float32 g2[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
321+ float32 g1t[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
322+ float32 g2t[3 ][3 ] = {{0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }};
292323 std::array<float32, 3 > c1 = {0 .0f , 0 .0f , 0 .0f };
293324 std::array<float32, 3 > caxis = {0 .0f , 0 .0f , 1 .0f };
294325
@@ -301,7 +332,6 @@ bool GroupMicroTextureRegions::determineGrouping(int32 referenceFeature, int32 n
301332 if (!m_InputValues->UseRunningAverage )
302333 {
303334 usize index = referenceFeature * 4 ;
304- phase1 = crystalStructures[featurePhases[referenceFeature]];
305335 OrientationTransformation::qu2om<QuatF, Orientation<float32>>({avgQuats[index + 0 ], avgQuats[index + 1 ], avgQuats[index + 2 ], avgQuats[index + 3 ]}).toGMatrix (g1);
306336
307337 // transpose the g matrix so when c-axis is multiplied by it,
@@ -312,6 +342,7 @@ bool GroupMicroTextureRegions::determineGrouping(int32 referenceFeature, int32 n
312342 // dividing by the magnitudes (they would be 1)
313343 MatrixMath::Normalize3x1 (c1.data ());
314344 }
345+ phase1 = crystalStructures[featurePhases[referenceFeature]];
315346 uint32 phase2 = crystalStructures[featurePhases[neighborFeature]];
316347 if (phase1 == phase2 && (phase1 == EbsdLib::CrystalStructure::Hexagonal_High))
317348 {
0 commit comments