diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/MergeColonies.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/MergeColonies.cpp index c27efe3c43..4051ff7d9a 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/MergeColonies.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/MergeColonies.cpp @@ -12,7 +12,6 @@ #include "EbsdLib/Core/Orientation.hpp" #include "EbsdLib/Core/OrientationTransformation.hpp" #include "EbsdLib/Core/Quaternion.hpp" -#include "EbsdLib/LaueOps/LaueOps.h" using namespace complex; using LaueOpsShPtrType = std::shared_ptr; @@ -49,327 +48,96 @@ float64 crystalDirections[12][3][3] = {{{unit111, unit112_1, unit110}, {-unit111 {{-unit111, unit112_2, 0}, {unit111, unit112_1, unit110}, {unit111, unit112_1, -unit110}}}; -class MergeColoniesAlg +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +bool check_for_burgers(const QuatD& betaQuat, const QuatD& alphaQuat, float64 angleTolerance) { -public: - MergeColoniesAlg(Int32Array& featureParentIds, AttributeMatrix& cellFeatureAM, Int32Array& featurePhases, float64 axisToleranceRad, float64 angleTolerance) - : - , m_OrientationOps(LaueOps::GetAllOrientationOps()) - { - } - ~MergeColoniesAlg() = default; - - void execute() - { - Int32NeighborList& neighborlist = *(m_ContiguousNeighborList.lock()); - Int32NeighborList& nonContigNeighList = m_NonContiguousNeighborList.lock().get(); - - std::vector grouplist; - - int32 parentcount = 0; - int32 seed = 0; - int32 list1size = 0, list2size = 0, listsize = 0; - int32 neigh = 0; - - while(seed >= 0) - { - parentcount++; - seed = getSeed(parentcount); - if(seed >= 0) - { - grouplist.push_back(seed); - for(std::vector::size_type j = 0; j < grouplist.size(); j++) - { - int32 firstfeature = grouplist[j]; - list1size = int32(neighborlist[firstfeature].size()); - if(m_UseNonContiguousNeighbors) - { - list2size = nonContigNeighList.getListSize(firstfeature); - } - for(int32 k = 0; k < 2; k++) - { - if(m_PatchGrouping) - { - k = 1; - } - if(k == 0) - { - listsize = list1size; - } - else if(k == 1) - { - listsize = list2size; - } - for(int32 l = 0; l < listsize; l++) - { - if(k == 0) - { - neigh = neighborlist[firstfeature][l]; - } - else if(k == 1) - { - neigh = nonContigNeighList.getListReference(firstfeature)[l]; - } - if(neigh != firstfeature) - { - if(determineGrouping(firstfeature, neigh, parentcount)) - { - if(!m_PatchGrouping) - { - grouplist.push_back(neigh); - } - } - } - } - } - } - if(m_PatchGrouping) - { - if(growPatch(parentcount)) - { - for(std::vector::size_type j = 0; j < grouplist.size(); j++) - { - int32 firstfeature = grouplist[j]; - listsize = int32(neighborlist[firstfeature].size()); - for(int32 l = 0; l < listsize; l++) - { - neigh = neighborlist[firstfeature][l]; - if(neigh != firstfeature) - { - if(growGrouping(firstfeature, neigh, parentcount)) - { - grouplist.push_back(neigh); - } - } - } - } - } - } - } - grouplist.clear(); - } - } - -private: - LaueOpsContainer m_OrientationOps; - Int32Array& m_FeatureParentIds; - AttributeMatrix& m_CellFeatureAM; - Int32Array& m_FeaturePhases; - Float32Array& m_AvgQuats; - const UInt32Array& m_CrystalStructures; - float64 m_AxisToleranceRad = 0.0; - float64 m_AngleTolerance = 1.0; - - // ----------------------------------------------------------------------------- - // - // ----------------------------------------------------------------------------- - int32 getSeed(int32 newFid) + float64 dP = 0.0; + float64 angle = 0.0; + float64 radToDeg = 180.0 / Constants::k_PiD; + + float64 gBeta[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; + float64 gBetaT[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; + OrientationTransformation::qu2om(betaQuat).toGMatrix(gBeta); + // transpose gBeta so the sample direction is the output when + // gBeta is multiplied by the crystal directions below + MatrixMath::Transpose3x3(gBeta, gBetaT); + + float64 gAlpha[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; + float64 gAlphaT[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; + OrientationTransformation::qu2om(alphaQuat).toGMatrix(gAlpha); + // transpose gBeta so the sample direction is the output when + // gBeta is multiplied by the crystal directions below + MatrixMath::Transpose3x3(gAlpha, gAlphaT); + + float64 mat[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; + for(int32 i = 0; i < 12; i++) { - usize numFeatures = m_FeaturePhases.getNumberOfTuples(); - - SIMPL_RANDOMNG_NEW(); - int32 seed = -1; - int32 randFeature = 0; - - // Precalculate some constants - usize totalFMinus1 = numFeatures - 1; - - usize counter = 0; - randFeature = int32(float32(rg.genrand_res53()) * float32(totalFMinus1)); - while(seed == -1 && counter < numFeatures) + MatrixMath::Multiply3x3with3x3(gBetaT, crystalDirections[i], mat); + Point3Dd a = Point3Dd(mat[0][2], mat[1][2], mat[2][2]); + Point3Dd b = Point3Dd(gAlphaT[0][2], gAlphaT[1][2], gAlphaT[2][2]); + dP = GeometryMath::CosThetaBetweenVectors(a, b); + angle = std::acos(dP); + if((angle * radToDeg) < angleTolerance || (180.0f - (angle * radToDeg)) < angleTolerance) { - if(randFeature > totalFMinus1) + a[0] = mat[0][0]; + a[1] = mat[1][0]; + a[2] = mat[2][0]; + b[0] = gAlphaT[0][0]; + b[1] = gAlphaT[1][0]; + b[2] = gAlphaT[2][0]; + dP = GeometryMath::CosThetaBetweenVectors(a, b); + angle = std::acos(dP); + if((angle * radToDeg) < angleTolerance) { - randFeature = randFeature - numFeatures; + return true; } - if(m_FeatureParentIds[randFeature] == -1) + if((180.0 - (angle * radToDeg)) < angleTolerance) { - seed = randFeature; + return true; } - randFeature++; - counter++; - } - if(seed >= 0) - { - m_FeatureParentIds[seed] = newFid; - std::vector tDims(1, newFid + 1); - m_CellFeatureAM.resizeTuples(tDims); - } - return seed; - } - - // ----------------------------------------------------------------------------- - // - // ----------------------------------------------------------------------------- - bool check_for_burgers(const QuatD& betaQuat, const QuatD& alphaQuat) - { - float64 dP = 0.0; - float64 angle = 0.0; - float64 radToDeg = 180.0 / Constants::k_PiD; - - float64 gBeta[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; - float64 gBetaT[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; - OrientationTransformation::qu2om(betaQuat).toGMatrix(gBeta); - // transpose gBeta so the sample direction is the output when - // gBeta is multiplied by the crystal directions below - MatrixMath::Transpose3x3(gBeta, gBetaT); - - float64 gAlpha[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; - float64 gAlphaT[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; - OrientationTransformation::qu2om(alphaQuat).toGMatrix(gAlpha); - // transpose gBeta so the sample direction is the output when - // gBeta is multiplied by the crystal directions below - MatrixMath::Transpose3x3(gAlpha, gAlphaT); - - float64 mat[3][3] = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; - for(int32 i = 0; i < 12; i++) - { - MatrixMath::Multiply3x3with3x3(gBetaT, crystalDirections[i], mat); - Point3Dd a = Point3Dd(mat[0][2], mat[1][2], mat[2][2]); - Point3Dd b = Point3Dd(gAlphaT[0][2], gAlphaT[1][2], gAlphaT[2][2]); + b[0] = -0.5 * gAlphaT[0][0] + 0.866025 * gAlphaT[0][1]; + b[1] = -0.5 * gAlphaT[1][0] + 0.866025 * gAlphaT[1][1]; + b[2] = -0.5 * gAlphaT[2][0] + 0.866025 * gAlphaT[2][1]; dP = GeometryMath::CosThetaBetweenVectors(a, b); angle = std::acos(dP); - if((angle * radToDeg) < m_AngleTolerance || (180.0f - (angle * radToDeg)) < m_AngleTolerance) + if((angle * radToDeg) < angleTolerance) { - a[0] = mat[0][0]; - a[1] = mat[1][0]; - a[2] = mat[2][0]; - b[0] = gAlphaT[0][0]; - b[1] = gAlphaT[1][0]; - b[2] = gAlphaT[2][0]; - dP = GeometryMath::CosThetaBetweenVectors(a, b); - angle = std::acos(dP); - if((angle * radToDeg) < m_AngleTolerance) - { - return true; - } - if((180.0 - (angle * radToDeg)) < m_AngleTolerance) - { - return true; - } - b[0] = -0.5 * gAlphaT[0][0] + 0.866025 * gAlphaT[0][1]; - b[1] = -0.5 * gAlphaT[1][0] + 0.866025 * gAlphaT[1][1]; - b[2] = -0.5 * gAlphaT[2][0] + 0.866025 * gAlphaT[2][1]; - dP = GeometryMath::CosThetaBetweenVectors(a, b); - angle = std::acos(dP); - if((angle * radToDeg) < m_AngleTolerance) - { - return true; - } - if((180.0 - (angle * radToDeg)) < m_AngleTolerance) - { - return true; - } - b[0] = -0.5 * gAlphaT[0][0] - 0.866025 * gAlphaT[0][1]; - b[1] = -0.5 * gAlphaT[1][0] - 0.866025 * gAlphaT[1][1]; - b[2] = -0.5 * gAlphaT[2][0] - 0.866025 * gAlphaT[2][1]; - dP = GeometryMath::CosThetaBetweenVectors(a, b); - angle = std::acos(dP); - if((angle * radToDeg) < m_AngleTolerance) - { - return true; - } - if((180.0 - (angle * radToDeg)) < m_AngleTolerance) - { - return true; - } + return true; } - } - return false; - } - - // ----------------------------------------------------------------------------- - // - // ----------------------------------------------------------------------------- - bool determineGrouping(int32 referenceFeature, int32 neighborFeature, int32 newFid) - { - float64 w = std::numeric_limits::max(); - bool colony = false; - - if(m_FeatureParentIds[neighborFeature] == -1 && m_FeaturePhases[referenceFeature] > 0 && m_FeaturePhases[neighborFeature] > 0) - { - usize avgQuatIdx = referenceFeature * 4; - QuatD q1(m_AvgQuats[avgQuatIdx], m_AvgQuats[avgQuatIdx + 1], m_AvgQuats[avgQuatIdx + 2], m_AvgQuats[avgQuatIdx + 3]); - avgQuatIdx = neighborFeature * 4; - QuatD q2(m_AvgQuats[avgQuatIdx], m_AvgQuats[avgQuatIdx + 1], m_AvgQuats[avgQuatIdx + 2], m_AvgQuats[avgQuatIdx + 3]); - - uint32 phase1 = m_CrystalStructures[m_FeaturePhases[referenceFeature]]; - uint32 phase2 = m_CrystalStructures[m_FeaturePhases[neighborFeature]]; - if(phase1 == phase2 && (phase1 == EbsdLib::CrystalStructure::Hexagonal_High)) + if((180.0 - (angle * radToDeg)) < angleTolerance) { - OrientationD ax = m_OrientationOps[phase1]->calculateMisorientation(q1, q2); - - auto rod = OrientationTransformation::ax2ro(ax); - rod = m_OrientationOps[phase1]->getMDFFZRod(rod); - ax = OrientationTransformation::ro2ax(rod); - - w = ax[3] * (Constants::k_180OverPiD); - float angdiff1 = std::fabs(w - 10.53f); - float axisdiff1 = std::acos(/*std::fabs(n1) * 0.0000f + std::fabs(n2) * 0.0000f +*/ std::fabs(ax[2]) /* * 1.0000f */); - if(angdiff1 < m_AngleTolerance && axisdiff1 < m_AxisToleranceRad) - { - colony = true; - } - float angdiff2 = std::fabs(w - 90.00f); - float axisdiff2 = std::acos(std::fabs(ax[0]) * 0.9958f + std::fabs(ax[1]) * 0.0917f /* + std::fabs(n3) * 0.0000f */); - if(angdiff2 < m_AngleTolerance && axisdiff2 < m_AxisToleranceRad) - { - colony = true; - } - float angdiff3 = std::fabs(w - 60.00f); - float axisdiff3 = std::acos(std::fabs(ax[0]) /* * 1.0000f + std::fabs(n2) * 0.0000f + std::fabs(n3) * 0.0000f*/); - if(angdiff3 < m_AngleTolerance && axisdiff3 < m_AxisToleranceRad) - { - colony = true; - } - float angdiff4 = std::fabs(w - 60.83f); - float axisdiff4 = std::acos(std::fabs(ax[0]) * 0.9834f + std::fabs(ax[1]) * 0.0905f + std::fabs(ax[2]) * 0.1570f); - if(angdiff4 < m_AngleTolerance && axisdiff4 < m_AxisToleranceRad) - { - colony = true; - } - float angdiff5 = std::fabs(w - 63.26f); - float axisdiff5 = std::acos(std::fabs(ax[0]) * 0.9549f /* + std::fabs(n2) * 0.0000f */ + std::fabs(ax[2]) * 0.2969f); - if(angdiff5 < m_AngleTolerance && axisdiff5 < m_AxisToleranceRad) - { - colony = true; - } - if(colony) - { - m_FeatureParentIds[neighborFeature] = newFid; - return true; - } + return true; } - else if(EbsdLib::CrystalStructure::Cubic_High == phase2 && EbsdLib::CrystalStructure::Hexagonal_High == phase1) + b[0] = -0.5 * gAlphaT[0][0] - 0.866025 * gAlphaT[0][1]; + b[1] = -0.5 * gAlphaT[1][0] - 0.866025 * gAlphaT[1][1]; + b[2] = -0.5 * gAlphaT[2][0] - 0.866025 * gAlphaT[2][1]; + dP = GeometryMath::CosThetaBetweenVectors(a, b); + angle = std::acos(dP); + if((angle * radToDeg) < angleTolerance) { - colony = check_for_burgers(q2, q1); - if(colony) - { - m_FeatureParentIds[neighborFeature] = newFid; - return true; - } + return true; } - else if(EbsdLib::CrystalStructure::Cubic_High == phase1 && EbsdLib::CrystalStructure::Hexagonal_High == phase2) + if((180.0 - (angle * radToDeg)) < angleTolerance) { - colony = check_for_burgers(q1, q2); - if(colony) - { - m_FeatureParentIds[neighborFeature] = newFid; - return true; - } + return true; } } - return false; } -}; + return false; +} } // namespace // ----------------------------------------------------------------------------- -MergeColonies::MergeColonies(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, MergeColoniesInputValues* inputValues) -: m_DataStructure(dataStructure) +MergeColonies::MergeColonies(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, MergeColoniesInputValues* inputValues, + GroupFeaturesInputValues* groupInputValues) +: GroupFeatures(dataStructure, mesgHandler, shouldCancel, groupInputValues) +, m_DataStructure(dataStructure) , m_InputValues(inputValues) , m_ShouldCancel(shouldCancel) , m_MessageHandler(mesgHandler) +, m_OrientationOps(LaueOps::GetAllOrientationOps()) { } @@ -385,20 +153,33 @@ const std::atomic_bool& MergeColonies::getCancel() // ----------------------------------------------------------------------------- Result<> MergeColonies::operator()() { - m_AxisToleranceRad = m_AxisTolerance * Constants::k_PiD / 180.0f; + m_FeatureParentIds = m_DataStructure.getDataRefAs(m_InputValues->FeatureParentIdsPath); + m_FeaturePhases = m_DataStructure.getDataRefAs(m_InputValues->FeaturePhasesPath); + m_AvgQuats = m_DataStructure.getDataRefAs(m_InputValues->AvgQuatsPath); + m_CrystalStructures = m_DataStructure.getDataRefAs(m_InputValues->CrystalStructuresPath); + + m_AxisToleranceRad = m_InputValues->AxisTolerance * Constants::k_PiF / 180.0f; + m_AngleTolerance = m_InputValues->AngleTolerance; + + GroupFeatures::execute(); + + auto active = m_DataStructure.getDataRefAs(m_InputValues->ActivePath); - usize totalFeatures = m_ActivePtr.lock()->getNumberOfTuples(); + usize totalFeatures = active.getNumberOfTuples(); if(totalFeatures < 2) { return MakeErrorResult(-87000, "The number of Grouped Features was 0 or 1 which means no grouped Features were detected. A grouping value may be set too high"); } + auto featureIds = m_DataStructure.getDataRefAs(m_InputValues->FeatureIdsPath); + auto cellParentIds = m_DataStructure.getDataRefAs(m_InputValues->CellParentIdsPath); + int32 numParents = 0; - usize totalPoints = m_FeatureIdsPtr.lock()->getNumberOfTuples(); + usize totalPoints = featureIds.getNumberOfTuples(); for(usize k = 0; k < totalPoints; k++) { - int32 featurename = m_FeatureIds[k]; - m_CellParentIds[k] = m_FeatureParentIds[featurename]; + int32 featurename = featureIds[k]; + cellParentIds[k] = m_FeatureParentIds[featurename]; if(m_FeatureParentIds[featurename] > numParents) { numParents = m_FeatureParentIds[featurename]; @@ -406,8 +187,9 @@ Result<> MergeColonies::operator()() } numParents += 1; - if(m_RandomizeParentIds) + if(m_InputValues->RandomizeParentIds) { + m_MessageHandler({IFilter::Message::Type::Info, "Randomizing Parent Ids...."}); // Generate all the numbers up front const int32 rangeMin = 1; const int32 rangeMax = numParents - 1; @@ -417,7 +199,7 @@ Result<> MergeColonies::operator()() std::vector pid(numParents); pid.push_back(0); - QSet parentIdSet; + std::set parentIdSet; parentIdSet.insert(0); for(int32 i = 1; i < numParents; ++i) { @@ -428,6 +210,7 @@ Result<> MergeColonies::operator()() int32 r = 0; int32 temp = 0; + m_MessageHandler({IFilter::Message::Type::Info, "Shuffle elements ...."}); //--- Shuffle elements by randomly exchanging each with one other. for(int32 i = 1; i < numParents; i++) { @@ -441,13 +224,134 @@ Result<> MergeColonies::operator()() pid[r] = temp; } + m_MessageHandler({IFilter::Message::Type::Info, "Adjusting Feature Ids Array...."}); // Now adjust all the Feature Id values for each Voxel for(usize i = 0; i < totalPoints; ++i) { - m_CellParentIds[i] = pid[m_CellParentIds[i]]; - m_FeatureParentIds[m_FeatureIds[i]] = m_CellParentIds[i]; + cellParentIds[i] = pid[cellParentIds[i]]; + m_FeatureParentIds[featureIds[i]] = cellParentIds[i]; } } return {}; } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +int32 MergeColonies::getSeed(int32 newFid) +{ + usize numFeatures = m_FeaturePhases.getNumberOfTuples(); + + SIMPL_RANDOMNG_NEW(); + int32 seed = -1; + int32 randFeature = 0; + + // Precalculate some constants + usize totalFMinus1 = numFeatures - 1; + + usize counter = 0; + randFeature = int32(float32(rg.genrand_res53()) * float32(totalFMinus1)); + while(seed == -1 && counter < numFeatures) + { + if(randFeature > totalFMinus1) + { + randFeature = randFeature - numFeatures; + } + if(m_FeatureParentIds[randFeature] == -1) + { + seed = randFeature; + } + randFeature++; + counter++; + } + if(seed >= 0) + { + m_FeatureParentIds[seed] = newFid; + std::vector tDims(1, newFid + 1); + m_DataStructure.getDataRefAs(m_InputValues->CellFeatureAMPath).resizeTuples(tDims); + } + return seed; +} + +// ----------------------------------------------------------------------------- +bool MergeColonies::determineGrouping(int32 referenceFeature, int32 neighborFeature, int32 newFid) +{ + float64 w = std::numeric_limits::max(); + bool colony = false; + + if(m_FeatureParentIds[neighborFeature] == -1 && m_FeaturePhases[referenceFeature] > 0 && m_FeaturePhases[neighborFeature] > 0) + { + usize avgQuatIdx = referenceFeature * 4; + QuatD q1(m_AvgQuats[avgQuatIdx], m_AvgQuats[avgQuatIdx + 1], m_AvgQuats[avgQuatIdx + 2], m_AvgQuats[avgQuatIdx + 3]); + avgQuatIdx = neighborFeature * 4; + QuatD q2(m_AvgQuats[avgQuatIdx], m_AvgQuats[avgQuatIdx + 1], m_AvgQuats[avgQuatIdx + 2], m_AvgQuats[avgQuatIdx + 3]); + + uint32 phase1 = m_CrystalStructures[m_FeaturePhases[referenceFeature]]; + uint32 phase2 = m_CrystalStructures[m_FeaturePhases[neighborFeature]]; + if(phase1 == phase2 && (phase1 == EbsdLib::CrystalStructure::Hexagonal_High)) + { + OrientationD ax = m_OrientationOps[phase1]->calculateMisorientation(q1, q2); + + auto rod = OrientationTransformation::ax2ro(ax); + rod = m_OrientationOps[phase1]->getMDFFZRod(rod); + ax = OrientationTransformation::ro2ax(rod); + + w = ax[3] * (Constants::k_180OverPiD); + float angdiff1 = std::fabs(w - 10.53f); + float axisdiff1 = std::acos(/*std::fabs(n1) * 0.0000f + std::fabs(n2) * 0.0000f +*/ std::fabs(ax[2]) /* * 1.0000f */); + if(angdiff1 < m_AngleTolerance && axisdiff1 < m_AxisToleranceRad) + { + colony = true; + } + float angdiff2 = std::fabs(w - 90.00f); + float axisdiff2 = std::acos(std::fabs(ax[0]) * 0.9958f + std::fabs(ax[1]) * 0.0917f /* + std::fabs(n3) * 0.0000f */); + if(angdiff2 < m_AngleTolerance && axisdiff2 < m_AxisToleranceRad) + { + colony = true; + } + float angdiff3 = std::fabs(w - 60.00f); + float axisdiff3 = std::acos(std::fabs(ax[0]) /* * 1.0000f + std::fabs(n2) * 0.0000f + std::fabs(n3) * 0.0000f*/); + if(angdiff3 < m_AngleTolerance && axisdiff3 < m_AxisToleranceRad) + { + colony = true; + } + float angdiff4 = std::fabs(w - 60.83f); + float axisdiff4 = std::acos(std::fabs(ax[0]) * 0.9834f + std::fabs(ax[1]) * 0.0905f + std::fabs(ax[2]) * 0.1570f); + if(angdiff4 < m_AngleTolerance && axisdiff4 < m_AxisToleranceRad) + { + colony = true; + } + float angdiff5 = std::fabs(w - 63.26f); + float axisdiff5 = std::acos(std::fabs(ax[0]) * 0.9549f /* + std::fabs(n2) * 0.0000f */ + std::fabs(ax[2]) * 0.2969f); + if(angdiff5 < m_AngleTolerance && axisdiff5 < m_AxisToleranceRad) + { + colony = true; + } + if(colony) + { + m_FeatureParentIds[neighborFeature] = newFid; + return true; + } + } + else if(EbsdLib::CrystalStructure::Cubic_High == phase2 && EbsdLib::CrystalStructure::Hexagonal_High == phase1) + { + colony = check_for_burgers(q2, q1, m_AngleTolerance); + if(colony) + { + m_FeatureParentIds[neighborFeature] = newFid; + return true; + } + } + else if(EbsdLib::CrystalStructure::Cubic_High == phase1 && EbsdLib::CrystalStructure::Hexagonal_High == phase2) + { + colony = check_for_burgers(q1, q2, m_AngleTolerance); + if(colony) + { + m_FeatureParentIds[neighborFeature] = newFid; + return true; + } + } + } + return false; +} diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/MergeColonies.hpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/MergeColonies.hpp index d41b3ca8bc..113129bac2 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/MergeColonies.hpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/MergeColonies.hpp @@ -3,6 +3,8 @@ #include "OrientationAnalysis/Filters/Algorithms/GroupFeatures.hpp" #include "OrientationAnalysis/OrientationAnalysis_export.hpp" +#include "complex/DataStructure/AttributeMatrix.hpp" +#include "complex/DataStructure/DataArray.hpp" #include "complex/DataStructure/DataPath.hpp" #include "complex/DataStructure/DataStructure.hpp" #include "complex/Filter/IFilter.hpp" @@ -10,25 +12,27 @@ #include "complex/Parameters/ArraySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" +#include "EbsdLib/LaueOps/LaueOps.h" + namespace complex { - struct ORIENTATIONANALYSIS_EXPORT MergeColoniesInputValues { bool UseNonContiguousNeighbors; - DataPath NonContiguousNeighborListArrayPath; - DataPath ContiguousNeighborListArrayPath; + DataPath NonContiguousNLPath; + DataPath ContiguousNLPath; float32 AxisTolerance; float32 AngleTolerance; - DataPath FeaturePhasesArrayPath; - DataPath AvgQuatsArrayPath; - DataPath FeatureIdsArrayPath; - DataPath CellPhasesArrayPath; - DataPath CrystalStructuresArrayPath; - DataPath CellParentIdsArrayName; - DataPath NewCellFeatureAttributeMatrixName; - DataPath FeatureParentIdsArrayName; - DataPath ActiveArrayName; + DataPath FeaturePhasesPath; + DataPath AvgQuatsPath; + DataPath FeatureIdsPath; + DataPath CellPhasesPath; + DataPath CrystalStructuresPath; + DataPath CellParentIdsPath; + DataPath CellFeatureAMPath; + DataPath FeatureParentIdsPath; + DataPath ActivePath; + bool RandomizeParentIds = true; }; /** @@ -39,6 +43,9 @@ struct ORIENTATIONANALYSIS_EXPORT MergeColoniesInputValues class ORIENTATIONANALYSIS_EXPORT MergeColonies : public GroupFeatures { + using LaueOpsShPtrType = std::shared_ptr; + using LaueOpsContainer = std::vector; + public: MergeColonies(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, MergeColoniesInputValues* inputValues); ~MergeColonies() noexcept; @@ -52,11 +59,20 @@ class ORIENTATIONANALYSIS_EXPORT MergeColonies : public GroupFeatures const std::atomic_bool& getCancel(); + int getSeed(int32 newFid) override; + bool determineGrouping(int32 referenceFeature, int32 neighborFeature, int32 newFid) override; + private: DataStructure& m_DataStructure; const MergeColoniesInputValues* m_InputValues = nullptr; const std::atomic_bool& m_ShouldCancel; const IFilter::MessageHandler& m_MessageHandler; + LaueOpsContainer m_OrientationOps; + Int32Array& m_FeatureParentIds; + Int32Array& m_FeaturePhases; + Float32Array& m_AvgQuats; + UInt32Array& m_CrystalStructures; + float32 m_AxisToleranceRad = 0.0; + float32 m_AngleTolerance = 1.0; }; - } // namespace complex diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/MergeColoniesFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/MergeColoniesFilter.cpp index 65adfeefbd..9575b35242 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/MergeColoniesFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/MergeColoniesFilter.cpp @@ -1,6 +1,6 @@ #include "MergeColoniesFilter.hpp" -#include "ComplexCore/Filters/Algorithms/MergeColonies.hpp" +#include "OrientationAnalysis/Filters/Algorithms/MergeColonies.hpp" #include "complex/DataStructure/DataPath.hpp" #include "complex/Filter/Actions/EmptyAction.hpp"