diff --git a/pipelines/Combo-EBSD-osc_r0c0.d3dpipeline b/pipelines/Combo-EBSD-osc_r0c0.d3dpipeline index 61c5fe7671..3a5d20213b 100644 --- a/pipelines/Combo-EBSD-osc_r0c0.d3dpipeline +++ b/pipelines/Combo-EBSD-osc_r0c0.d3dpipeline @@ -66,7 +66,7 @@ }, { "args": { - "cell_euler_angles_array_path": "DataContainer/CellData/EulerAngles", + "euler_angles_array_path": "DataContainer/CellData/EulerAngles", "rotation_axis": [ 0.0, 0.0, diff --git a/src/Plugins/ComplexCore/docs/RemoveFlaggedFeaturesFilter.md b/src/Plugins/ComplexCore/docs/RemoveFlaggedFeaturesFilter.md index 77b70277a9..19be24adac 100644 --- a/src/Plugins/ComplexCore/docs/RemoveFlaggedFeaturesFilter.md +++ b/src/Plugins/ComplexCore/docs/RemoveFlaggedFeaturesFilter.md @@ -1,4 +1,4 @@ -# Remove Flagged Features +# Remove/Extract Flagged Features ## Group (Subgroup) @@ -6,7 +6,11 @@ Processing (Cleanup) ## Description -This **Filter** will remove **Features** that have been flagged by another **Filter** from the structure. The **Filter** requires that the user point to a boolean array at the **Feature** level that tells the **Filter** whether the **Feature** should remain in the structure. If the boolean array is *false* for a **Feature**, then all **Cells** that belong to that **Feature** are temporarily *unassigned* and after all *undesired* **Features** are removed, the remaining **Features** are isotropically coarsened to fill in the gaps left by the removed **Features**. +This **Filter** will remove **Features** that have been flagged by another **Filter** from the structure. The **Filter** +requires that the user point to a boolean array at the **Feature** level that tells the **Filter** whether the **Feature** +should remain in the structure. If the boolean array is *false* for a **Feature**, then all **Cells** that belong to that +**Feature** are temporarily *unassigned*. Optionally, after all *undesired* **Features** are removed, the remaining **Features** are +isotropically coarsened to fill in the gaps left by the removed **Features**. % Auto generated parameter table will be inserted here diff --git a/src/Plugins/ComplexCore/docs/RemoveFlaggedVertices.md b/src/Plugins/ComplexCore/docs/RemoveFlaggedVertices.md index cb3d1b17bf..83d0a0d2b0 100644 --- a/src/Plugins/ComplexCore/docs/RemoveFlaggedVertices.md +++ b/src/Plugins/ComplexCore/docs/RemoveFlaggedVertices.md @@ -6,14 +6,14 @@ DREAM3D Review (Geometry) ## Description -This **Filter** removes **Vertices** from the supplied **Vertex Geometry** that are flagged by a boolean mask array. -Specifically, **Vertices** flagged as *true* are removed from the **Geometry**. A new reduced **Vertex Geometry** is +This **Filter** removes **Vertices** from the supplied **Vertex Geometry** that are flagged as **TRUE** by a boolean mask array. +A new reduced **Vertex Geometry** is created that contains all the remaining **Vertices**. It is unknown until run time how many **Vertices** will be removed from the **Geometry**. Therefore, this **Filter** requires that a new **Data Container** be created to contain the -reduced **Vertex Geometry**. This new **Data Container** will contain copies of any **Feature** or **Ensemble** * -*Attribute Matrices** from the original **Data Container**. Additionally, all **Vertex** data will be copied, with -tuples *removed* for any **Vertices** removed by the **Filter**. The user must supply a name for the reduced **Data -Container**, but all other copied objects (**Attribute Matrices** and **Attribute Arrays**) will retain the same names +reduced **Vertex Geometry**. This new **Vertex Geometry** will contain copies of any **Feature** or **Ensemble** +**Attribute Matrices** from the original **Data Container**. Additionally, all **Vertex** data will be copied, with +tuples *removed* for any **Vertices** removed by the **Filter**. The user must supply a name for the reduced **Vertex Geometry**, +but all other copied objects (**Attribute Matrices** and **Attribute Arrays**) will retain the same names as the original source. *Note:* Since it cannot be known before run time how many **Vertices** will be removed, the new **Vertex Geometry** and diff --git a/src/Plugins/ComplexCore/docs/ReplaceElementAttributesWithNeighborValuesFilter.md b/src/Plugins/ComplexCore/docs/ReplaceElementAttributesWithNeighborValuesFilter.md index dfd47c773a..d137f992a2 100644 --- a/src/Plugins/ComplexCore/docs/ReplaceElementAttributesWithNeighborValuesFilter.md +++ b/src/Plugins/ComplexCore/docs/ReplaceElementAttributesWithNeighborValuesFilter.md @@ -12,8 +12,8 @@ maximum or minimum value. The attributes of the neighbor with the maximum/minimu reference **Cell**. *Note:* By default, the **Filter** will run only one iteration of the cleanup. If the user selects the *Loop Until Gone* -option, then the **Filter** will run iteratively until no **Cells** exist that meet the users criteria. So, if a **Cell -** meets the threshold and so are all of its neighbors, then that **Cell** will not be changed during that iteration and +option, then the **Filter** will run iteratively until no **Cells** exist that meet the users criteria. So, if a **Cell** +meets the threshold and so are all of its neighbors, then that **Cell** will not be changed during that iteration and will remain unchanged until one of its neighbors gets changed by a **Cell** further away. ## Examples diff --git a/src/Plugins/ComplexCore/pipelines/ReplaceElementAttributesWithNeighbor.d3dpipeline b/src/Plugins/ComplexCore/pipelines/ReplaceElementAttributesWithNeighbor.d3dpipeline index b42001f010..6c809c20b8 100644 --- a/src/Plugins/ComplexCore/pipelines/ReplaceElementAttributesWithNeighbor.d3dpipeline +++ b/src/Plugins/ComplexCore/pipelines/ReplaceElementAttributesWithNeighbor.d3dpipeline @@ -104,7 +104,7 @@ }, { "args": { - "cell_euler_angles_array_path": "DataContainer/Cell Data/EulerAngles", + "euler_angles_array_path": "DataContainer/Cell Data/EulerAngles", "rotation_axis": [ 0.0, 0.0, @@ -192,7 +192,7 @@ }, { "args": { - "confidence_index_array_path": "DataContainer/Cell Data/Confidence Index", + "comparison_data_path": "DataContainer/Cell Data/Confidence Index", "loop": true, "min_confidence": 0.10000000149011612, "selected_comparison": 0, diff --git a/src/Plugins/ComplexCore/pipelines/VtkRectilinearGridWriter.d3dpipeline b/src/Plugins/ComplexCore/pipelines/VtkRectilinearGridWriter.d3dpipeline index b38bef16d5..bde9946d37 100644 --- a/src/Plugins/ComplexCore/pipelines/VtkRectilinearGridWriter.d3dpipeline +++ b/src/Plugins/ComplexCore/pipelines/VtkRectilinearGridWriter.d3dpipeline @@ -192,7 +192,7 @@ { "args": { "cell_phases_array_path": "DataContainer/CellData/Phases", - "confidence_index_array_path": "DataContainer/CellData/Confidence Index", + "correlation_array_path": "DataContainer/CellData/Confidence Index", "crystal_structures_array_path": "DataContainer/CellEnsembleData/CrystalStructures", "ignored_data_array_paths": [], "image_geometry_path": "DataContainer", diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/AlignSectionsFeatureCentroidFilter.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/AlignSectionsFeatureCentroidFilter.cpp index 9cb48443f2..142ba80de0 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/AlignSectionsFeatureCentroidFilter.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/AlignSectionsFeatureCentroidFilter.cpp @@ -9,6 +9,7 @@ #include "complex/Parameters/FileSystemPathParameter.hpp" #include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" +#include "complex/Utilities/FilterUtilities.hpp" #include @@ -132,6 +133,10 @@ IFilter::PreflightResult AlignSectionsFeatureCentroidFilter::preflightImpl(const return {MakeErrorResult(-3425, "Write Alignment Shifts is TRUE but the output file path is empty. Please ensure the file path is set for the alignment file.")}; } + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, cellDataGroupPath, {}); + // Return both the resultOutputActions and the preflightUpdatedValues via std::move() return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/AlignSectionsListFilter.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/AlignSectionsListFilter.cpp index fe50fdad7c..2fdd558691 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/AlignSectionsListFilter.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/AlignSectionsListFilter.cpp @@ -8,6 +8,7 @@ #include "complex/Parameters/BoolParameter.hpp" #include "complex/Parameters/FileSystemPathParameter.hpp" #include "complex/Parameters/GeometrySelectionParameter.hpp" +#include "complex/Utilities/FilterUtilities.hpp" #include @@ -92,6 +93,10 @@ IFilter::PreflightResult AlignSectionsListFilter::preflightImpl(const DataStruct imageGeom.getNumYCells(), imageGeom.getNumZCells()))}; } + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, imageGeom.getCellDataPath(), {}); + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ErodeDilateBadDataFilter.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ErodeDilateBadDataFilter.cpp index e171cd79e9..4138d62baa 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ErodeDilateBadDataFilter.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ErodeDilateBadDataFilter.cpp @@ -10,6 +10,8 @@ #include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/MultiArraySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" +#include "complex/Utilities/DataGroupUtilities.hpp" +#include "complex/Utilities/FilterUtilities.hpp" using namespace complex; @@ -102,6 +104,10 @@ IFilter::PreflightResult ErodeDilateBadDataFilter::preflightImpl(const DataStruc MakeErrorResult(-16700, fmt::format("Operation Selection must be 0 (Dilate) or 1 (Erode). {} was passed into the filter. ", pOperationValue)); } + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, pFeatureIdsArrayPathValue.getParent(), pIgnoredDataArrayPathsValue); + // Return both the resultOutputActions and the preflightUpdatedValues via std::move() return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/MinNeighbors.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/MinNeighbors.cpp index 034d4e18ae..b1ae5529cc 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/MinNeighbors.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/MinNeighbors.cpp @@ -9,6 +9,7 @@ #include "complex/Parameters/MultiArraySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" #include "complex/Utilities/DataGroupUtilities.hpp" +#include "complex/Utilities/FilterUtilities.hpp" namespace complex { @@ -304,7 +305,7 @@ std::string MinNeighbors::humanName() const //------------------------------------------------------------------------------ std::vector MinNeighbors::defaultTags() const { - return {className(), "Minimum", "Neighbors", "Memory Management", "Cleanup"}; + return {className(), "Minimum", "Neighbors", "Memory Management", "Cleanup", "Remove Features"}; } //------------------------------------------------------------------------------ @@ -359,6 +360,10 @@ IFilter::PreflightResult MinNeighbors::preflightImpl(const DataStructure& dataSt auto numNeighborsPath = args.value(k_NumNeighbors_Key); auto minNumNeighbors = args.value(k_MinNumNeighbors_Key); + complex::Result resultOutputActions; + + std::vector preflightUpdatedValues; + std::vector dataArrayPaths; std::vector cDims = {1}; @@ -386,8 +391,14 @@ IFilter::PreflightResult MinNeighbors::preflightImpl(const DataStructure& dataSt fmt::format("The following DataArrays all must have equal number of tuples but this was not satisfied.\n{}", tupleValidityCheck.error()))}; } - OutputActions actions; - return {std::move(actions)}; + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, featureIdsPath.getParent(), {}); + // Feature Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, numNeighborsPath.getParent(), {}); + + // Return both the resultOutputActions and the preflightUpdatedValues via std::move() + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } //------------------------------------------------------------------------------ @@ -400,7 +411,7 @@ Result<> MinNeighbors::executeImpl(DataStructure& data, const Arguments& args, c // If running on a single phase, validate that the user has not entered a phase number // that is not in the system ; the filter would not crash otherwise, but the user should // be notified of unanticipated behavior ; this cannot be done in the dataCheck since - // we don't have acces to the data yet + // we don't have access to the data yet if(applyToSinglePhase) { auto& featurePhasesArray = data.getDataRefAs(featurePhasesPath); @@ -453,7 +464,7 @@ Result<> MinNeighbors::executeImpl(DataStructure& data, const Arguments& args, c int32 count = 0; for(const auto& value : activeObjects) { - value == true ? count++ : count = count; + value ? count++ : count = count; } std::string message = fmt::format("Feature Count Changed: Previous: {} New: {}", currentFeatureCount, count); messageHandler(complex::IFilter::Message{complex::IFilter::Message::Type::Info, message}); diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/RemoveFlaggedFeaturesFilter.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/RemoveFlaggedFeaturesFilter.cpp index 1f1c1b61d8..1512ecbf36 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/RemoveFlaggedFeaturesFilter.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/RemoveFlaggedFeaturesFilter.cpp @@ -14,6 +14,7 @@ #include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/MultiArraySelectionParameter.hpp" #include "complex/Parameters/StringParameter.hpp" +#include "complex/Utilities/FilterUtilities.hpp" using namespace complex; @@ -45,13 +46,13 @@ Uuid RemoveFlaggedFeaturesFilter::uuid() const //------------------------------------------------------------------------------ std::string RemoveFlaggedFeaturesFilter::humanName() const { - return "Extract/Remove Flagged Features"; + return "Remove/Extract Flagged Features"; } //------------------------------------------------------------------------------ std::vector RemoveFlaggedFeaturesFilter::defaultTags() const { - return {className(), "Processing", "Cleanup"}; + return {className(), "Processing", "Cleanup", "Remove Features"}; } //------------------------------------------------------------------------------ @@ -60,9 +61,9 @@ Parameters RemoveFlaggedFeaturesFilter::parameters() const Parameters params; params.insertSeparator(Parameters::Separator{"Input Parameters"}); - params.insertLinkableParameter(std::make_unique(k_Functionality_Key, "Selected Operation", "Whether to extract features into new geometry or remove or extract then remove", - to_underlying(Functionality::Remove), - ChoicesParameter::Choices{"Remove", "Extract", "Extract then Remove"})); // sequence dependent DO NOT REORDER + params.insertLinkableParameter( + std::make_unique(k_Functionality_Key, "Selected Operation", "Whether to [0] remove features, [1] extract features into new geometry or [2] extract and then remove", + to_underlying(Functionality::Remove), ChoicesParameter::Choices{"Remove", "Extract", "Extract then Remove"})); // sequence dependent DO NOT REORDER params.insert(std::make_unique(k_FillRemovedFeatures_Key, "Fill-in Removed Features", "Whether or not to fill in the gaps left by the removed Features", false)); params.insertSeparator(Parameters::Separator{"Geometry"}); @@ -76,7 +77,7 @@ Parameters RemoveFlaggedFeaturesFilter::parameters() const "The prefix name for each of new cropped (extracted) geometry \n\nNOTE: a '-' will automatically be added between the prefix and number", "Extracted_Feature")); - params.insertSeparator(Parameters::Separator{"Required Input Cell Feature Data"}); + params.insertSeparator(Parameters::Separator{"Required Input Feature Data"}); params.insert(std::make_unique(k_FlaggedFeaturesArrayPath_Key, "Flagged Features", "Specifies whether the Feature will remain in the structure or not", DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::boolean, DataType::uint8}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.insert(std::make_unique(k_IgnoredDataArrayPaths_Key, "Attribute Arrays to Ignore", "The list of arrays to ignore when removing flagged features", @@ -108,13 +109,15 @@ IFilter::PreflightResult RemoveFlaggedFeaturesFilter::preflightImpl(const DataSt { auto pFeatureIdsArrayPathValue = filterArgs.value(k_CellFeatureIdsArrayPath_Key); auto pFlaggedFeaturesArrayPathValue = filterArgs.value(k_FlaggedFeaturesArrayPath_Key); + auto operationType = filterArgs.value(k_Functionality_Key); + auto fillGaps = filterArgs.value(k_FillRemovedFeatures_Key); PreflightResult preflightResult; complex::Result resultOutputActions; std::vector preflightUpdatedValues; - auto* featureIds = dataStructure.getDataAs(pFeatureIdsArrayPathValue); - if(featureIds == nullptr) + auto* featureIdsPtr = dataStructure.getDataAs(pFeatureIdsArrayPathValue); + if(featureIdsPtr == nullptr) { return {nonstd::make_unexpected(std::vector{Error{-9890, fmt::format("Could not find selected Feature Ids Data Array at path '{}'", pFeatureIdsArrayPathValue.toString())}})}; } @@ -124,20 +127,20 @@ IFilter::PreflightResult RemoveFlaggedFeaturesFilter::preflightImpl(const DataSt return {nonstd::make_unexpected(std::vector{Error{-9891, fmt::format("Could not find selected Flagged Features Data Array at path '{}'", pFlaggedFeaturesArrayPathValue.toString())}})}; } - DataPath cellFeatureAttributeMatrixPath = pFlaggedFeaturesArrayPathValue.getParent(); - const auto* cellFeatureAM = dataStructure.getDataAs(cellFeatureAttributeMatrixPath); - if(cellFeatureAM == nullptr) + DataPath const cellFeatureAttributeMatrixPath = pFlaggedFeaturesArrayPathValue.getParent(); + const auto* cellFeatureAmPtr = dataStructure.getDataAs(cellFeatureAttributeMatrixPath); + if(cellFeatureAmPtr == nullptr) { return {nonstd::make_unexpected(std::vector{ Error{-9892, fmt::format("Could not find the parent Attribute Matrix for the selected Flagged Features Data Array at path '{}'", pFlaggedFeaturesArrayPathValue.toString())}})}; } - std::string warningMsg = ""; - for(const auto& [identifier, object] : *cellFeatureAM) + std::string warningMsg; + for(const auto& [identifier, object] : *cellFeatureAmPtr) { - if(const auto* srcNeighborListArray = dynamic_cast(object.get()); srcNeighborListArray != nullptr) + if(const auto* srcNeighborListArrayPtr = dynamic_cast(object.get()); srcNeighborListArrayPtr != nullptr) { - warningMsg += "\n" + cellFeatureAttributeMatrixPath.toString() + "/" + srcNeighborListArray->getName(); + warningMsg += "\n" + cellFeatureAttributeMatrixPath.toString() + "/" + srcNeighborListArrayPtr->getName(); } } if(!warningMsg.empty()) @@ -149,13 +152,24 @@ IFilter::PreflightResult RemoveFlaggedFeaturesFilter::preflightImpl(const DataSt auto pFunctionality = filterArgs.value(k_Functionality_Key); if(pFunctionality != to_underlying(Functionality::Remove)) { - DataPath tempPath = pFlaggedFeaturesArrayPathValue.getParent().createChildPath(k_boundsName); - auto action = std::make_unique(DataType::uint32, std::vector{featureIds->getNumberOfTuples()}, std::vector{featureIds->getNumberOfComponents() * 6}, tempPath); + DataPath const tempPath = pFlaggedFeaturesArrayPathValue.getParent().createChildPath(k_boundsName); + auto action = + std::make_unique(DataType::uint32, std::vector{featureIdsPtr->getNumberOfTuples()}, std::vector{featureIdsPtr->getNumberOfComponents() * 6}, tempPath); // After the execute function has been done, delete the temp array resultOutputActions.value().appendDeferredAction(std::make_unique(tempPath)); } + // If we are in any way removing features, inform the user + if(operationType == 0 || operationType == 2) + { + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, pFeatureIdsArrayPathValue.getParent(), {}); + // Feature Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, pFlaggedFeaturesArrayPathValue.getParent(), {}); + } + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/RemoveMinimumSizeFeaturesFilter.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/RemoveMinimumSizeFeaturesFilter.cpp index 19b3279b35..c4eeed904b 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/RemoveMinimumSizeFeaturesFilter.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/RemoveMinimumSizeFeaturesFilter.cpp @@ -6,8 +6,10 @@ #include "complex/Parameters/ArraySelectionParameter.hpp" #include "complex/Parameters/BoolParameter.hpp" #include "complex/Parameters/DataPathSelectionParameter.hpp" +#include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" #include "complex/Utilities/DataGroupUtilities.hpp" +#include "complex/Utilities/FilterUtilities.hpp" #include #include @@ -277,7 +279,7 @@ std::string RemoveMinimumSizeFeaturesFilter::humanName() const //------------------------------------------------------------------------------ std::vector RemoveMinimumSizeFeaturesFilter::defaultTags() const { - return {className(), "Processing", "Cleanup", "MinSize"}; + return {className(), "Processing", "Cleanup", "MinSize", "Feature Removal"}; } Parameters RemoveMinimumSizeFeaturesFilter::parameters() const @@ -291,7 +293,8 @@ Parameters RemoveMinimumSizeFeaturesFilter::parameters() const params.insert(std::make_unique>(k_PhaseNumber_Key, "Phase Index", "Target phase to remove", 0)); params.insertSeparator(Parameters::Separator{"Required Input Cell Data"}); - params.insert(std::make_unique(k_ImageGeomPath_Key, "Image Geometry", "DataPath to Image Geometry", DataPath{})); + params.insert(std::make_unique(k_ImageGeomPath_Key, "Input Image Geometry", "The input image geometry (cell)", DataPath{}, + GeometrySelectionParameter::AllowedTypes{IGeometry::Type::Image})); params.insert(std::make_unique(k_FeatureIdsPath_Key, "FeatureIds Array", "DataPath to FeatureIds DataArray", DataPath({"FeatureIds"}), ArraySelectionParameter::AllowedTypes{DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{{1}})); @@ -363,10 +366,8 @@ IFilter::PreflightResult RemoveMinimumSizeFeaturesFilter::preflightImpl(const Da } // Create the preflightResult object - IFilter::PreflightResult preflightResult; - - // Create our OutputActions Object - OutputActions outputActions; + complex::Result resultOutputActions; + std::vector preflightUpdatedValues; // Throw a warning to inform the user that the neighbor list arrays could be deleted by this filter std::string ss = fmt::format("If this filter modifies the Cell Level Array '{}', all arrays of type NeighborList will be deleted from the feature data group '{}'. These arrays are:\n", @@ -383,12 +384,17 @@ IFilter::PreflightResult RemoveMinimumSizeFeaturesFilter::preflightImpl(const Da { ss.append(" " + featureNeighborList.toString() + "\n"); auto action = std::make_unique(featureNeighborList); - outputActions.appendAction(std::move(action)); + resultOutputActions.value().actions.emplace_back(std::move(action)); } - preflightResult.outputActions.warnings().push_back(Warning{k_NeighborListRemoval, ss}); + // Inform users that the following arrays are going to be modified in place + // Feature Data is going to be modified + complex::AppendDataObjectModifications(data, resultOutputActions.value().modifiedActions, featureGroupDataPath, {}); + + resultOutputActions.warnings().push_back(Warning{k_NeighborListRemoval, ss}); - return preflightResult; + // Return both the resultOutputActions and the preflightUpdatedValues via std::move() + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } // ----------------------------------------------------------------------------- diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ReplaceElementAttributesWithNeighborValuesFilter.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ReplaceElementAttributesWithNeighborValuesFilter.cpp index 143d13c845..ac9494043b 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ReplaceElementAttributesWithNeighborValuesFilter.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ReplaceElementAttributesWithNeighborValuesFilter.cpp @@ -9,6 +9,7 @@ #include "complex/Parameters/ChoicesParameter.hpp" #include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" +#include "complex/Utilities/FilterUtilities.hpp" using namespace complex; @@ -41,7 +42,7 @@ std::string ReplaceElementAttributesWithNeighborValuesFilter::humanName() const //------------------------------------------------------------------------------ std::vector ReplaceElementAttributesWithNeighborValuesFilter::defaultTags() const { - return {className(), "Processing", "Cleanup"}; + return {className(), "Processing", "Cleanup", "Replace Values"}; } //------------------------------------------------------------------------------ @@ -58,7 +59,7 @@ Parameters ReplaceElementAttributesWithNeighborValuesFilter::parameters() const params.insertSeparator(Parameters::Separator{"Required Input Cell Data"}); params.insert(std::make_unique(k_SelectedImageGeometry_Key, "Selected Image Geometry", "The target geometry", DataPath{}, GeometrySelectionParameter::AllowedTypes{IGeometry::Type::Image})); - params.insert(std::make_unique(k_ConfidenceIndexArrayPath_Key, "Input Comparison Array", "The DataPath to the input array to use for comparison", DataPath{}, + params.insert(std::make_unique(k_ComparisonDataPath, "Input Comparison Array", "The DataPath to the input array to use for comparison", DataPath{}, complex::GetAllDataTypes(), ArraySelectionParameter::AllowedComponentShapes{{1}})); return params; @@ -74,12 +75,16 @@ IFilter::UniquePointer ReplaceElementAttributesWithNeighborValuesFilter::clone() IFilter::PreflightResult ReplaceElementAttributesWithNeighborValuesFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler, const std::atomic_bool& shouldCancel) const { - auto pConfidenceIndexArrayPathValue = filterArgs.value(k_ConfidenceIndexArrayPath_Key); + auto pComparisonDataPath = filterArgs.value(k_ComparisonDataPath); complex::Result resultOutputActions; std::vector preflightUpdatedValues; + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, pComparisonDataPath.getParent(), {}); + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } @@ -93,7 +98,7 @@ Result<> ReplaceElementAttributesWithNeighborValuesFilter::executeImpl(DataStruc inputValues.MinConfidence = filterArgs.value(k_MinConfidence_Key); inputValues.SelectedComparison = filterArgs.value(k_SelectedComparison_Key); inputValues.Loop = filterArgs.value(k_Loop_Key); - inputValues.InputArrayPath = filterArgs.value(k_ConfidenceIndexArrayPath_Key); + inputValues.InputArrayPath = filterArgs.value(k_ComparisonDataPath); inputValues.SelectedImageGeometryPath = filterArgs.value(k_SelectedImageGeometry_Key); return ReplaceElementAttributesWithNeighborValues(dataStructure, messageHandler, shouldCancel, &inputValues)(); diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ReplaceElementAttributesWithNeighborValuesFilter.hpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ReplaceElementAttributesWithNeighborValuesFilter.hpp index 6780b60bb3..b13c8f3aea 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ReplaceElementAttributesWithNeighborValuesFilter.hpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ReplaceElementAttributesWithNeighborValuesFilter.hpp @@ -28,7 +28,7 @@ class COMPLEXCORE_EXPORT ReplaceElementAttributesWithNeighborValuesFilter : publ static inline constexpr StringLiteral k_MinConfidence_Key = "min_confidence"; static inline constexpr StringLiteral k_SelectedComparison_Key = "selected_comparison"; static inline constexpr StringLiteral k_Loop_Key = "loop"; - static inline constexpr StringLiteral k_ConfidenceIndexArrayPath_Key = "confidence_index_array_path"; + static inline constexpr StringLiteral k_ComparisonDataPath = "comparison_data_path"; static inline constexpr StringLiteral k_SelectedImageGeometry_Key = "selected_image_geometry"; /** diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ResampleImageGeomFilter.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ResampleImageGeomFilter.cpp index 8f6698ca55..85d8e13f99 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ResampleImageGeomFilter.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ResampleImageGeomFilter.cpp @@ -19,6 +19,7 @@ #include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/VectorParameter.hpp" #include "complex/Utilities/DataGroupUtilities.hpp" +#include "complex/Utilities/FilterUtilities.hpp" #include "complex/Utilities/GeometryHelpers.hpp" #include "complex/Utilities/StringUtilities.hpp" @@ -77,7 +78,8 @@ Parameters ResampleImageGeomFilter::parameters() const // Create the parameter descriptors that are needed for this filter params.insertSeparator(Parameters::Separator{"Input Parameters"}); - params.insertLinkableParameter(std::make_unique(k_ResamplingMode_Key, "Resampling Mode", "Mode can be 'Spacing (0)' or 'Scaling (1)'", k_SpacingModeIndex, ::k_Choices)); + params.insertLinkableParameter( + std::make_unique(k_ResamplingMode_Key, "Resampling Mode", "Mode can be [0] Spacing, [1] Scaling as Percent, [2] Exact Dimensions as voxels", k_SpacingModeIndex, ::k_Choices)); params.insert(std::make_unique(k_Spacing_Key, "New Spacing", "The new spacing values (dx, dy, dz). Larger spacing will cause less voxels, smaller spacing will cause more voxels.", @@ -86,7 +88,7 @@ Parameters ResampleImageGeomFilter::parameters() const params.insert( std::make_unique(k_Scaling_Key, "Scale Factor (percentages)", "The scale factor values (dx, dy, dz) to resample the geometry, in percentages. Larger percentages will cause more voxels, smaller percentages " - "will cause less voxels. A percentage of 100 in any dimension will not resample the geometry in that dimension. Percentages must be larger than 0.", + "will cause less voxels. A percentage of 100 in any dimension will not resample the geometry in that dimension. Percentages must be larger than 0.", std::vector{100.0F, 100.0F, 100.0F}, std::vector{"X%", "Y%", "Z%"})); params.insert(std::make_unique(k_ExactDimensions_Key, "Exact Dimensions (pixels)", "The exact dimension size values (dx, dy, dz) to resample the geometry, in pixels.", @@ -98,14 +100,14 @@ Parameters ResampleImageGeomFilter::parameters() const params.insert(std::make_unique(k_SelectedImageGeometry_Key, "Selected Image Geometry", "The target geometry to resample", DataPath{}, GeometrySelectionParameter::AllowedTypes{IGeometry::Type::Image})); - params.insertSeparator(Parameters::Separator{"Renumber Features Input Parameters"}); + params.insertSeparator(Parameters::Separator{"Renumber Features (Optional)"}); params.insertLinkableParameter(std::make_unique(k_RenumberFeatures_Key, "Renumber Features", "Specifies if the feature IDs should be renumbered", false)); params.insert(std::make_unique(k_CellFeatureIdsArrayPath_Key, "Feature IDs", "DataPath to Cell Feature IDs array", DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.insert( std::make_unique(k_FeatureAttributeMatrix_Key, "Cell Feature Attribute Matrix", "DataPath to the feature Attribute Matrix", DataPath({"CellFeatureData"}))); - params.insertSeparator({"Output Image Geometry"}); + params.insertSeparator({"Created Image Geometry"}); params.insert(std::make_unique(k_CreatedImageGeometry_Key, "Created Image Geometry", "The location of the resampled geometry", DataPath())); // Associate the Linkable Parameter(s) to the children parameters that they control @@ -327,6 +329,10 @@ IFilter::PreflightResult ResampleImageGeomFilter::preflightImpl(const DataStruct if(pRemoveOriginalGeometry) { resultOutputActions.value().appendDeferredAction(std::make_unique(destImagePath, srcImagePath.getTargetName())); + + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, srcImageGeom->getCellDataPath(), {}); } // Return both the resultOutputActions and the preflightUpdatedValues via std::move() diff --git a/src/Plugins/ComplexCore/test/ReplaceElementAttributesWithNeighborValuesTest.cpp b/src/Plugins/ComplexCore/test/ReplaceElementAttributesWithNeighborValuesTest.cpp index 2765f2c4a6..aa083764c9 100644 --- a/src/Plugins/ComplexCore/test/ReplaceElementAttributesWithNeighborValuesTest.cpp +++ b/src/Plugins/ComplexCore/test/ReplaceElementAttributesWithNeighborValuesTest.cpp @@ -42,7 +42,7 @@ TEST_CASE("OrientationAnalysis::ReplaceElementAttributesWithNeighborValuesFilter args.insertOrAssign(ReplaceElementAttributesWithNeighborValuesFilter::k_MinConfidence_Key, std::make_any(0.1F)); args.insertOrAssign(ReplaceElementAttributesWithNeighborValuesFilter::k_SelectedComparison_Key, std::make_any(0)); args.insertOrAssign(ReplaceElementAttributesWithNeighborValuesFilter::k_Loop_Key, std::make_any(true)); - args.insertOrAssign(ReplaceElementAttributesWithNeighborValuesFilter::k_ConfidenceIndexArrayPath_Key, std::make_any(k_ConfidenceIndexPath)); + args.insertOrAssign(ReplaceElementAttributesWithNeighborValuesFilter::k_ComparisonDataPath, std::make_any(k_ConfidenceIndexPath)); args.insertOrAssign(ReplaceElementAttributesWithNeighborValuesFilter::k_SelectedImageGeometry_Key, std::make_any(k_DataContainerPath)); // Preflight the filter and check result diff --git a/src/Plugins/OrientationAnalysis/pipelines/CI_Histogram.d3dpipeline b/src/Plugins/OrientationAnalysis/pipelines/CI_Histogram.d3dpipeline index 8e7203108a..e7cf60215b 100644 --- a/src/Plugins/OrientationAnalysis/pipelines/CI_Histogram.d3dpipeline +++ b/src/Plugins/OrientationAnalysis/pipelines/CI_Histogram.d3dpipeline @@ -19,7 +19,7 @@ }, { "args": { - "cell_euler_angles_array_path": "DataContainer/Cell Data/EulerAngles", + "euler_angles_array_path": "DataContainer/Cell Data/EulerAngles", "rotation_axis": [ 0.0, 0.0, diff --git a/src/Plugins/OrientationAnalysis/pipelines/EBSD Reconstruction/(08) Small IN100 Full Reconstruction.d3dpipeline b/src/Plugins/OrientationAnalysis/pipelines/EBSD Reconstruction/(08) Small IN100 Full Reconstruction.d3dpipeline index 8e234261e3..61c8108a69 100644 --- a/src/Plugins/OrientationAnalysis/pipelines/EBSD Reconstruction/(08) Small IN100 Full Reconstruction.d3dpipeline +++ b/src/Plugins/OrientationAnalysis/pipelines/EBSD Reconstruction/(08) Small IN100 Full Reconstruction.d3dpipeline @@ -150,7 +150,7 @@ { "args": { "cell_phases_array_path": "DataContainer/CellData/Phases", - "confidence_index_array_path": "DataContainer/CellData/Confidence Index", + "correlation_array_path": "DataContainer/CellData/Confidence Index", "crystal_structures_array_path": "DataContainer/CellEnsembleData/CrystalStructures", "ignored_data_array_paths": [], "image_geometry_path": "DataContainer", diff --git a/src/Plugins/OrientationAnalysis/pipelines/EBSD Statistics/(05) Small IN100 Crystallographic Statistics.d3dpipeline b/src/Plugins/OrientationAnalysis/pipelines/EBSD Statistics/(05) Small IN100 Crystallographic Statistics.d3dpipeline index d4ba3a51eb..173b8d39d3 100644 --- a/src/Plugins/OrientationAnalysis/pipelines/EBSD Statistics/(05) Small IN100 Crystallographic Statistics.d3dpipeline +++ b/src/Plugins/OrientationAnalysis/pipelines/EBSD Statistics/(05) Small IN100 Crystallographic Statistics.d3dpipeline @@ -237,7 +237,7 @@ { "args": { "cell_phases_array_path": "DataContainer/CellData/Phases", - "confidence_index_array_path": "DataContainer/CellData/Confidence Index", + "correlation_array_path": "DataContainer/CellData/Confidence Index", "crystal_structures_array_path": "DataContainer/CellEnsembleData/CrystalStructures", "ignored_data_array_paths": [], "image_geometry_path": "DataContainer", diff --git a/src/Plugins/OrientationAnalysis/pipelines/Edax_IPF_Colors.d3dpipeline b/src/Plugins/OrientationAnalysis/pipelines/Edax_IPF_Colors.d3dpipeline index 74291ec3dd..08cd2272a0 100644 --- a/src/Plugins/OrientationAnalysis/pipelines/Edax_IPF_Colors.d3dpipeline +++ b/src/Plugins/OrientationAnalysis/pipelines/Edax_IPF_Colors.d3dpipeline @@ -19,7 +19,7 @@ }, { "args": { - "cell_euler_angles_array_path": "DataContainer/Cell Data/EulerAngles", + "euler_angles_array_path": "DataContainer/Cell Data/EulerAngles", "rotation_axis": [ 0.0, 0.0, diff --git a/src/Plugins/OrientationAnalysis/pipelines/FindGBCD-GBPDMetricBased.d3dpipeline b/src/Plugins/OrientationAnalysis/pipelines/FindGBCD-GBPDMetricBased.d3dpipeline index 0f0d68caec..21aae0488a 100644 --- a/src/Plugins/OrientationAnalysis/pipelines/FindGBCD-GBPDMetricBased.d3dpipeline +++ b/src/Plugins/OrientationAnalysis/pipelines/FindGBCD-GBPDMetricBased.d3dpipeline @@ -493,7 +493,7 @@ { "args": { "cell_phases_array_path": "DataContainer/CellData/Phases", - "confidence_index_array_path": "DataContainer/CellData/Confidence Index", + "correlation_array_path": "DataContainer/CellData/Confidence Index", "crystal_structures_array_path": "DataContainer/CellEnsembleData/CrystalStructures", "ignored_data_array_paths": [], "image_geometry_path": "DataContainer", diff --git a/src/Plugins/OrientationAnalysis/pipelines/ImportEdaxOIMData.d3dpipeline b/src/Plugins/OrientationAnalysis/pipelines/ImportEdaxOIMData.d3dpipeline index 56c5a96610..28da332c68 100644 --- a/src/Plugins/OrientationAnalysis/pipelines/ImportEdaxOIMData.d3dpipeline +++ b/src/Plugins/OrientationAnalysis/pipelines/ImportEdaxOIMData.d3dpipeline @@ -39,7 +39,7 @@ }, { "args": { - "cell_euler_angles_array_path": "ImageGeom/Cell Data/EulerAngles", + "euler_angles_array_path": "ImageGeom/Cell Data/EulerAngles", "rotation_axis": [ 0.0, 0.0, diff --git a/src/Plugins/OrientationAnalysis/pipelines/ReadAng.d3dpipeline b/src/Plugins/OrientationAnalysis/pipelines/ReadAng.d3dpipeline index c0f5f27661..2456008ab5 100644 --- a/src/Plugins/OrientationAnalysis/pipelines/ReadAng.d3dpipeline +++ b/src/Plugins/OrientationAnalysis/pipelines/ReadAng.d3dpipeline @@ -18,7 +18,7 @@ }, { "args": { - "cell_euler_angles_array_path": "DataContainer/Cell Data/EulerAngles", + "euler_angles_array_path": "DataContainer/Cell Data/EulerAngles", "rotation_axis": [ 0.0, 0.0, diff --git a/src/Plugins/OrientationAnalysis/pipelines/aptr12_Analysis.d3dpipeline b/src/Plugins/OrientationAnalysis/pipelines/aptr12_Analysis.d3dpipeline index 97682ac221..e8979dd70d 100644 --- a/src/Plugins/OrientationAnalysis/pipelines/aptr12_Analysis.d3dpipeline +++ b/src/Plugins/OrientationAnalysis/pipelines/aptr12_Analysis.d3dpipeline @@ -108,7 +108,7 @@ }, { "args": { - "confidence_index_array_path": "fw-ar-IF1-aptr12-corr/Cell Data/Error", + "comparison_data_path": "fw-ar-IF1-aptr12-corr/Cell Data/Error", "loop": true, "min_confidence": 0.0, "selected_comparison": 0, diff --git a/src/Plugins/OrientationAnalysis/pipelines/avtr12_Analysis.d3dpipeline b/src/Plugins/OrientationAnalysis/pipelines/avtr12_Analysis.d3dpipeline index 825293006c..b5fa667cfa 100644 --- a/src/Plugins/OrientationAnalysis/pipelines/avtr12_Analysis.d3dpipeline +++ b/src/Plugins/OrientationAnalysis/pipelines/avtr12_Analysis.d3dpipeline @@ -108,7 +108,7 @@ }, { "args": { - "confidence_index_array_path": "fw-ar-IF1-avtr12-corr/Cell Data/Error", + "comparison_data_path": "fw-ar-IF1-avtr12-corr/Cell Data/Error", "loop": true, "min_confidence": 0.0, "selected_comparison": 0, diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ReadH5Ebsd.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ReadH5Ebsd.cpp index 0792ec5d87..2a1e9b2705 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ReadH5Ebsd.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ReadH5Ebsd.cpp @@ -365,7 +365,7 @@ Result<> ReadH5Ebsd::operator()() std::make_any(std::vector{eulerTransAxis[0], eulerTransAxis[1], eulerTransAxis[2], eulerTransAngle})); complex::DataPath eulerDataPath = m_InputValues->cellAttributeMatrixPath.createChildPath(EbsdLib::CellData::EulerAngles); // get the Euler data from the DataStructure - args.insertOrAssign(RotateEulerRefFrameFilter::k_CellEulerAnglesArrayPath_Key, std::make_any(eulerDataPath)); + args.insertOrAssign(RotateEulerRefFrameFilter::k_EulerAnglesArrayPath_Key, std::make_any(eulerDataPath)); // Preflight the filter and check result auto preflightResult = rotEuler.preflight(m_DataStructure, args); if(preflightResult.outputActions.invalid()) diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMisorientationFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMisorientationFilter.cpp index 597bf11dc0..49fa025e2f 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMisorientationFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMisorientationFilter.cpp @@ -10,6 +10,7 @@ #include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" #include "complex/Utilities/DataArrayUtilities.hpp" +#include "complex/Utilities/FilterUtilities.hpp" #include @@ -168,6 +169,10 @@ IFilter::PreflightResult AlignSectionsMisorientationFilter::preflightImpl(const return {MakeErrorResult(k_OutputFilePathEmpty, "Write Alignment Shifts is TRUE but the output file path is empty. Please ensure the file path is set for the alignment file.")}; } + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, pQuatsArrayPath.getParent(), {}); + // Return both the resultOutputActions and the preflightUpdatedValues via std::move() return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMutualInformationFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMutualInformationFilter.cpp index cdbd374f2f..b2b8efd59c 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMutualInformationFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/AlignSectionsMutualInformationFilter.cpp @@ -10,6 +10,7 @@ #include "complex/Parameters/FileSystemPathParameter.hpp" #include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" +#include "complex/Utilities/FilterUtilities.hpp" #include namespace fs = std::filesystem; @@ -131,6 +132,10 @@ IFilter::PreflightResult AlignSectionsMutualInformationFilter::preflightImpl(con return {MakeErrorResult(-3542, fmt::format("The following DataArrays all must have equal number of tuples but this was not satisfied.\n{}", tupleValidityCheck.error()))}; } + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, pQuatsArrayPathValue.getParent(), {}); + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/BadDataNeighborOrientationCheckFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/BadDataNeighborOrientationCheckFilter.cpp index 45309154b3..58b4cf21f3 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/BadDataNeighborOrientationCheckFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/BadDataNeighborOrientationCheckFilter.cpp @@ -7,6 +7,7 @@ #include "complex/Parameters/ArraySelectionParameter.hpp" #include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" +#include "complex/Utilities/FilterUtilities.hpp" using namespace complex; @@ -97,6 +98,10 @@ IFilter::PreflightResult BadDataNeighborOrientationCheckFilter::preflightImpl(co auto pCellPhasesArrayPathValue = filterArgs.value(k_CellPhasesArrayPath_Key); auto pCrystalStructuresArrayPathValue = filterArgs.value(k_CrystalStructuresArrayPath_Key); + complex::Result resultOutputActions; + + std::vector preflightUpdatedValues; + std::vector dataArrayPaths; auto* imageGeomPtr = dataStructure.getDataAs(pImageGeomPathValue); @@ -184,7 +189,11 @@ IFilter::PreflightResult BadDataNeighborOrientationCheckFilter::preflightImpl(co fmt::format("The following DataArrays all must have equal number of tuples but this was not satisfied.\n{}", tupleValidityCheck.error()))}; } - return {}; + resultOutputActions.value().modifiedActions.emplace_back( + DataObjectModification{pGoodVoxelsArrayPathValue, DataObjectModification::ModifiedType::Modified, dataStructure.getData(pGoodVoxelsArrayPathValue)->getDataObjectType()}); + + // Return both the resultOutputActions and the preflightUpdatedValues via std::move() + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } //------------------------------------------------------------------------------ diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateFZQuaternions.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateFZQuaternions.cpp index 798ea2d03f..3c8292649a 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateFZQuaternions.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateFZQuaternions.cpp @@ -136,7 +136,7 @@ std::string GenerateFZQuaternions::humanName() const //------------------------------------------------------------------------------ std::vector GenerateFZQuaternions::defaultTags() const { - return {className(), "Processing", "OrientationAnalysis"}; + return {className(), "Processing", "OrientationAnalysis", "Quaternion"}; } //------------------------------------------------------------------------------ diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateQuaternionConjugateFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateQuaternionConjugateFilter.cpp index bd2c35d7b4..715ac72f9d 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateQuaternionConjugateFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/GenerateQuaternionConjugateFilter.cpp @@ -47,7 +47,7 @@ std::string GenerateQuaternionConjugateFilter::humanName() const //------------------------------------------------------------------------------ std::vector GenerateQuaternionConjugateFilter::defaultTags() const { - return {className(), "Processing", "Crystallography"}; + return {className(), "Processing", "Crystallography", "Orientation", "Quaternion"}; } //------------------------------------------------------------------------------ @@ -60,8 +60,9 @@ Parameters GenerateQuaternionConjugateFilter::parameters() const params.insertSeparator(Parameters::Separator{"Input Data"}); params.insert(std::make_unique(k_CellQuatsArrayPath_Key, "Quaternions", "Specifies the quaternions to convert", DataPath({"CellData", "Quats"}), ArraySelectionParameter::AllowedTypes{DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{4}})); - params.insertSeparator(Parameters::Separator{"Output Data"}); - params.insert(std::make_unique(k_OutputDataArrayPath_Key, "Output Data Array Path", "The name of the generated output DataArray", "Quaternions [Conjugate]")); + params.insertSeparator(Parameters::Separator{"Created Data"}); + params.insert( + std::make_unique(k_OutputDataArrayPath_Key, "Created Quaternion Conjugate", "The name of the generated quaternion conjugate array", "Quaternions [Conjugate]")); return params; } diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/NeighborOrientationCorrelationFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/NeighborOrientationCorrelationFilter.cpp index 2e133bf5dd..bb0dddea07 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/NeighborOrientationCorrelationFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/NeighborOrientationCorrelationFilter.cpp @@ -7,6 +7,7 @@ #include "complex/Parameters/GeometrySelectionParameter.hpp" #include "complex/Parameters/MultiArraySelectionParameter.hpp" #include "complex/Parameters/NumberParameter.hpp" +#include "complex/Utilities/FilterUtilities.hpp" using namespace complex; @@ -63,7 +64,7 @@ Parameters NeighborOrientationCorrelationFilter::parameters() const params.insertSeparator(Parameters::Separator{"Cell Data"}); params.insert(std::make_unique(k_ImageGeometryPath_Key, "Image Geometry", "Path to the target geometry", DataPath{}, GeometrySelectionParameter::AllowedTypes{IGeometry::Type::Image})); - params.insert(std::make_unique(k_ConfidenceIndexArrayPath_Key, "Confidence Index", "Specifies the confidence in the orientation of the Cell (TSL data)", DataPath{}, + params.insert(std::make_unique(k_CorrelationArrayPath_Key, "Confidence Index", "Specifies the confidence in the orientation of the Cell (TSL data)", DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{1}})); params.insert(std::make_unique(k_CellPhasesArrayPath_Key, "Cell Phases", "Specifies to which Ensemble each Cell belongs", DataPath({"Phases"}), ArraySelectionParameter::AllowedTypes{DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{{1}})); @@ -93,7 +94,7 @@ IFilter::PreflightResult NeighborOrientationCorrelationFilter::preflightImpl(con auto pMinConfidenceValue = filterArgs.value(k_MinConfidence_Key); auto pMisorientationToleranceValue = filterArgs.value(k_MisorientationTolerance_Key); auto pLevelValue = filterArgs.value(k_Level_Key); - auto pConfidenceIndexArrayPathValue = filterArgs.value(k_ConfidenceIndexArrayPath_Key); + auto pConfidenceIndexArrayPathValue = filterArgs.value(k_CorrelationArrayPath_Key); auto pCellPhasesArrayPathValue = filterArgs.value(k_CellPhasesArrayPath_Key); auto pQuatsArrayPathValue = filterArgs.value(k_QuatsArrayPath_Key); auto pCrystalStructuresArrayPathValue = filterArgs.value(k_CrystalStructuresArrayPath_Key); @@ -219,6 +220,10 @@ IFilter::PreflightResult NeighborOrientationCorrelationFilter::preflightImpl(con MakeErrorResult(k_InvalidNumTuples, fmt::format("The following DataArrays all must have equal number of tuples but this was not satisfied.\n{}", tupleValidityCheck.error()))}; } + // Inform users that the following arrays are going to be modified in place + // Cell Data is going to be modified + complex::AppendDataObjectModifications(dataStructure, resultOutputActions.value().modifiedActions, pConfidenceIndexArrayPathValue.getParent(), {}); + return {}; } @@ -232,7 +237,7 @@ Result<> NeighborOrientationCorrelationFilter::executeImpl(DataStructure& dataSt inputValues.MinConfidence = filterArgs.value(k_MinConfidence_Key); inputValues.MisorientationTolerance = filterArgs.value(k_MisorientationTolerance_Key); inputValues.Level = filterArgs.value(k_Level_Key); - inputValues.ConfidenceIndexArrayPath = filterArgs.value(k_ConfidenceIndexArrayPath_Key); + inputValues.ConfidenceIndexArrayPath = filterArgs.value(k_CorrelationArrayPath_Key); inputValues.CellPhasesArrayPath = filterArgs.value(k_CellPhasesArrayPath_Key); inputValues.QuatsArrayPath = filterArgs.value(k_QuatsArrayPath_Key); inputValues.CrystalStructuresArrayPath = filterArgs.value(k_CrystalStructuresArrayPath_Key); diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/NeighborOrientationCorrelationFilter.hpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/NeighborOrientationCorrelationFilter.hpp index 692c7909ab..97b8d57445 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/NeighborOrientationCorrelationFilter.hpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/NeighborOrientationCorrelationFilter.hpp @@ -28,7 +28,7 @@ class ORIENTATIONANALYSIS_EXPORT NeighborOrientationCorrelationFilter : public I static inline constexpr StringLiteral k_MinConfidence_Key = "min_confidence"; static inline constexpr StringLiteral k_MisorientationTolerance_Key = "misorientation_tolerance"; static inline constexpr StringLiteral k_Level_Key = "level"; - static inline constexpr StringLiteral k_ConfidenceIndexArrayPath_Key = "confidence_index_array_path"; + static inline constexpr StringLiteral k_CorrelationArrayPath_Key = "correlation_array_path"; static inline constexpr StringLiteral k_CellPhasesArrayPath_Key = "cell_phases_array_path"; static inline constexpr StringLiteral k_QuatsArrayPath_Key = "quats_array_path"; static inline constexpr StringLiteral k_CrystalStructuresArrayPath_Key = "crystal_structures_array_path"; diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/RotateEulerRefFrameFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/RotateEulerRefFrameFilter.cpp index 2d7ef43dec..a625bf8118 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/RotateEulerRefFrameFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/RotateEulerRefFrameFilter.cpp @@ -51,7 +51,7 @@ Parameters RotateEulerRefFrameFilter::parameters() const VectorFloat32Parameter::ValueType{0.0f, 0.0f, 0.0f, 90.0F}, std::vector{"i", "j", "k", "w (Deg)"})); params.insertSeparator(Parameters::Separator{"Input Data"}); - params.insert(std::make_unique(k_CellEulerAnglesArrayPath_Key, "Euler Angles", "Three angles defining the orientation of the Cell in Bunge convention (Z-X-Z)", DataPath{}, + params.insert(std::make_unique(k_EulerAnglesArrayPath_Key, "Input Euler Angles", "Three angles defining the orientation of the Cell in Bunge convention (Z-X-Z)", DataPath{}, ArraySelectionParameter::AllowedTypes{DataType::float32}, ArraySelectionParameter::AllowedComponentShapes{{3}})); return params; @@ -68,12 +68,15 @@ IFilter::PreflightResult RotateEulerRefFrameFilter::preflightImpl(const DataStru const std::atomic_bool& shouldCancel) const { auto pRotationAxisAngleValue = filterArgs.value(k_RotationAxisAngle_Key); - auto pCellEulerAnglesArrayPathValue = filterArgs.value(k_CellEulerAnglesArrayPath_Key); + auto pCellEulerAnglesArrayPathValue = filterArgs.value(k_EulerAnglesArrayPath_Key); complex::Result resultOutputActions; std::vector preflightUpdatedValues; + resultOutputActions.value().modifiedActions.emplace_back( + DataObjectModification{pCellEulerAnglesArrayPathValue, DataObjectModification::ModifiedType::Modified, dataStructure.getData(pCellEulerAnglesArrayPathValue)->getDataObjectType()}); + // Return both the resultOutputActions and the preflightUpdatedValues via std::move() return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; } @@ -84,7 +87,7 @@ Result<> RotateEulerRefFrameFilter::executeImpl(DataStructure& dataStructure, co { complex::RotateEulerRefFrameInputValues inputValues; - inputValues.eulerAngleDataPath = filterArgs.value(k_CellEulerAnglesArrayPath_Key); + inputValues.eulerAngleDataPath = filterArgs.value(k_EulerAnglesArrayPath_Key); inputValues.rotationAxis = filterArgs.value(k_RotationAxisAngle_Key); // Let the Algorithm instance do the work diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/RotateEulerRefFrameFilter.hpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/RotateEulerRefFrameFilter.hpp index df4fa4ce75..54a34b9f69 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/RotateEulerRefFrameFilter.hpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/RotateEulerRefFrameFilter.hpp @@ -25,7 +25,7 @@ class ORIENTATIONANALYSIS_EXPORT RotateEulerRefFrameFilter : public IFilter // Parameter Keys static inline constexpr StringLiteral k_RotationAxisAngle_Key = "rotation_axis"; - static inline constexpr StringLiteral k_CellEulerAnglesArrayPath_Key = "cell_euler_angles_array_path"; + static inline constexpr StringLiteral k_EulerAnglesArrayPath_Key = "euler_angles_array_path"; /** * @brief Returns the name of the filter. diff --git a/src/Plugins/OrientationAnalysis/test/NeighborOrientationCorrelationTest.cpp b/src/Plugins/OrientationAnalysis/test/NeighborOrientationCorrelationTest.cpp index 1ea686d43c..fb7c9600f6 100644 --- a/src/Plugins/OrientationAnalysis/test/NeighborOrientationCorrelationTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/NeighborOrientationCorrelationTest.cpp @@ -83,7 +83,7 @@ TEST_CASE("OrientationAnalysis::NeighborOrientationCorrelationFilter: Small IN10 args.insertOrAssign(NeighborOrientationCorrelationFilter::k_MinConfidence_Key, std::make_any(0.2f)); args.insertOrAssign(NeighborOrientationCorrelationFilter::k_MisorientationTolerance_Key, std::make_any(5.0f)); args.insertOrAssign(NeighborOrientationCorrelationFilter::k_Level_Key, std::make_any(2)); - args.insertOrAssign(NeighborOrientationCorrelationFilter::k_ConfidenceIndexArrayPath_Key, std::make_any(k_ConfidenceIndexArrayPath)); + args.insertOrAssign(NeighborOrientationCorrelationFilter::k_CorrelationArrayPath_Key, std::make_any(k_ConfidenceIndexArrayPath)); args.insertOrAssign(NeighborOrientationCorrelationFilter::k_CellPhasesArrayPath_Key, std::make_any(k_PhasesArrayPath)); args.insertOrAssign(NeighborOrientationCorrelationFilter::k_QuatsArrayPath_Key, std::make_any(k_QuatsArrayPath)); args.insertOrAssign(NeighborOrientationCorrelationFilter::k_CrystalStructuresArrayPath_Key, std::make_any(k_CrystalStructuresArrayPath)); diff --git a/src/Plugins/OrientationAnalysis/test/OrientationAnalysisTestUtils.hpp b/src/Plugins/OrientationAnalysis/test/OrientationAnalysisTestUtils.hpp index 6a94b2b96c..53dcb42839 100644 --- a/src/Plugins/OrientationAnalysis/test/OrientationAnalysisTestUtils.hpp +++ b/src/Plugins/OrientationAnalysis/test/OrientationAnalysisTestUtils.hpp @@ -301,7 +301,7 @@ inline void ExecuteNeighborOrientationCorrelation(DataStructure& dataStructure, constexpr StringLiteral k_MinConfidence_Key = "min_confidence"; constexpr StringLiteral k_MisorientationTolerance_Key = "misorientation_tolerance"; constexpr StringLiteral k_Level_Key = "level"; - constexpr StringLiteral k_ConfidenceIndexArrayPath_Key = "confidence_index_array_path"; + constexpr StringLiteral k_CorrelationArrayPath_Key = "correlation_array_path"; constexpr StringLiteral k_CellPhasesArrayPath_Key = "cell_phases_array_path"; constexpr StringLiteral k_QuatsArrayPath_Key = "quats_array_path"; constexpr StringLiteral k_CrystalStructuresArrayPath_Key = "crystal_structures_array_path"; @@ -313,7 +313,7 @@ inline void ExecuteNeighborOrientationCorrelation(DataStructure& dataStructure, args.insertOrAssign(k_MinConfidence_Key, std::make_any(0.2f)); args.insertOrAssign(k_MisorientationTolerance_Key, std::make_any(5.0f)); args.insertOrAssign(k_Level_Key, std::make_any(2)); - args.insertOrAssign(k_ConfidenceIndexArrayPath_Key, std::make_any(Constants::k_ConfidenceIndexArrayPath)); + args.insertOrAssign(k_CorrelationArrayPath_Key, std::make_any(Constants::k_ConfidenceIndexArrayPath)); args.insertOrAssign(k_CellPhasesArrayPath_Key, std::make_any(Constants::k_PhasesArrayPath)); args.insertOrAssign(k_QuatsArrayPath_Key, std::make_any(Constants::k_QuatsArrayPath)); args.insertOrAssign(k_CrystalStructuresArrayPath_Key, std::make_any(Constants::k_CrystalStructuresArrayPath)); diff --git a/src/Plugins/OrientationAnalysis/test/RotateEulerRefFrameTest.cpp b/src/Plugins/OrientationAnalysis/test/RotateEulerRefFrameTest.cpp index 2d2b0724a9..b05141a138 100644 --- a/src/Plugins/OrientationAnalysis/test/RotateEulerRefFrameTest.cpp +++ b/src/Plugins/OrientationAnalysis/test/RotateEulerRefFrameTest.cpp @@ -107,7 +107,7 @@ TEST_CASE("OrientationAnalysis::RotateEulerRefFrame", "[OrientationAnalysis]") // Create default Parameters for the filter. args.insertOrAssign(RotateEulerRefFrameFilter::k_RotationAxisAngle_Key, std::make_any(std::vector{1.0F, 1.0F, 1.0F, 30.0F})); - args.insertOrAssign(RotateEulerRefFrameFilter::k_CellEulerAnglesArrayPath_Key, std::make_any(k_EulerAnglesDataPath)); + args.insertOrAssign(RotateEulerRefFrameFilter::k_EulerAnglesArrayPath_Key, std::make_any(k_EulerAnglesDataPath)); // Preflight the filter and check result auto preflightResult = filter.preflight(dataStructure, args); diff --git a/src/complex/Filter/Output.hpp b/src/complex/Filter/Output.hpp index 9d82067dc4..25e1df639f 100644 --- a/src/complex/Filter/Output.hpp +++ b/src/complex/Filter/Output.hpp @@ -107,6 +107,24 @@ class COMPLEX_EXPORT IDataCreationAction : public IDataAction DataPath m_CreatedPath; }; +/** + * @brief + */ +struct COMPLEX_EXPORT DataObjectModification +{ + + enum class ModifiedType : uint64 + { + Modified = 0, + PossiblyDeleted = 1, + Unknown = 2, + }; + + DataPath modifiedPath; + ModifiedType modifiedType = ModifiedType::Unknown; + DataObject::Type dataObjectType = DataObject::Type::Unknown; +}; + /** * @brief Container for IDataActions */ @@ -114,6 +132,7 @@ struct COMPLEX_EXPORT OutputActions { std::vector actions = {}; std::vector deferredActions = {}; + std::vector modifiedActions = {}; OutputActions() = default; @@ -139,6 +158,11 @@ struct COMPLEX_EXPORT OutputActions deferredActions.emplace_back(std::move(action)); } + void appendDataObjectModificationNotification(const DataPath& dataPath, DataObjectModification::ModifiedType modifiedType) + { + modifiedActions.push_back(DataObjectModification{dataPath, modifiedType}); + } + static Result<> ApplyActions(nonstd::span actions, DataStructure& dataStructure, IDataAction::Mode mode); Result<> applyRegular(DataStructure& dataStructure, IDataAction::Mode mode) const; diff --git a/src/complex/Pipeline/PipelineFilter.cpp b/src/complex/Pipeline/PipelineFilter.cpp index 93cf16fdf6..9e5c402cc2 100644 --- a/src/complex/Pipeline/PipelineFilter.cpp +++ b/src/complex/Pipeline/PipelineFilter.cpp @@ -140,25 +140,28 @@ bool PipelineFilter::preflight(DataStructure& data, RenamedPaths& renamedPaths, } std::vector newCreatedPaths; + std::vector newModifiedPaths; for(const auto& action : result.outputActions.value().actions) { - if(const auto* creationAction = dynamic_cast(action.get()); creationAction != nullptr) + if(const auto* creationActionPtr = dynamic_cast(action.get()); creationActionPtr != nullptr) { - auto allCreatedPaths = creationAction->getAllCreatedPaths(); + auto allCreatedPaths = creationActionPtr->getAllCreatedPaths(); newCreatedPaths.insert(newCreatedPaths.end(), allCreatedPaths.begin(), allCreatedPaths.end()); } } + for(const auto& action : result.outputActions.value().deferredActions) { - if(const auto* creationAction = dynamic_cast(action.get()); creationAction != nullptr) + if(const auto* creationActionPtr = dynamic_cast(action.get()); creationActionPtr != nullptr) { - auto allCreatedPaths = creationAction->getAllCreatedPaths(); + auto allCreatedPaths = creationActionPtr->getAllCreatedPaths(); newCreatedPaths.insert(newCreatedPaths.end(), allCreatedPaths.begin(), allCreatedPaths.end()); } } // Do not clear the created paths unless the preflight succeeded m_CreatedPaths = newCreatedPaths; + m_DataModifiedActions = result.outputActions.value().modifiedActions; setPreflightStructure(data); sendFilterFaultMessage(m_Index, getFaultState()); @@ -219,6 +222,11 @@ std::vector PipelineFilter::getCreatedPaths() const return m_CreatedPaths; } +std::vector PipelineFilter::getDataObjectModificationNotifications() const +{ + return m_DataModifiedActions; +} + namespace { /** diff --git a/src/complex/Pipeline/PipelineFilter.hpp b/src/complex/Pipeline/PipelineFilter.hpp index 0eee2d285e..0428e39af3 100644 --- a/src/complex/Pipeline/PipelineFilter.hpp +++ b/src/complex/Pipeline/PipelineFilter.hpp @@ -146,6 +146,12 @@ class COMPLEX_EXPORT PipelineFilter : public AbstractPipelineNode */ std::vector getCreatedPaths() const; + /** + * @brief Returns a vector of DataPaths that would be modified when executing the node + * @return std::vector + */ + std::vector getDataObjectModificationNotifications() const; + /** * @brief Returns a collection of warnings returned by the target filter. * This collection is cleared when the node is preflighted or executed. @@ -220,5 +226,6 @@ class COMPLEX_EXPORT PipelineFilter : public AbstractPipelineNode std::vector m_Errors; std::vector m_PreflightValues; std::vector m_CreatedPaths; + std::vector m_DataModifiedActions; }; } // namespace complex diff --git a/src/complex/Utilities/FilterUtilities.cpp b/src/complex/Utilities/FilterUtilities.cpp index 59e2168f2d..5365fb2d21 100644 --- a/src/complex/Utilities/FilterUtilities.cpp +++ b/src/complex/Utilities/FilterUtilities.cpp @@ -23,4 +23,20 @@ Result<> CreateOutputDirectories(const fs::path& outputPath) } return {}; } + +// ----------------------------------------------------------------------------- +void AppendDataObjectModifications(const DataStructure& dataStructure, std::vector& modifiedActions, const DataPath& parentPath, const std::vector& ignoredDataPaths) +{ + std::optional> result = complex::GetAllChildArrayDataPaths(dataStructure, parentPath, ignoredDataPaths); + if(!result) + { + return; + } + + for(const auto& child : result.value()) + { + modifiedActions.push_back(DataObjectModification{child, DataObjectModification::ModifiedType::Modified, dataStructure.getDataRef(child).getDataObjectType()}); + } +} + } // namespace complex diff --git a/src/complex/Utilities/FilterUtilities.hpp b/src/complex/Utilities/FilterUtilities.hpp index b2dc1bd9c8..a0b1bee341 100644 --- a/src/complex/Utilities/FilterUtilities.hpp +++ b/src/complex/Utilities/FilterUtilities.hpp @@ -4,6 +4,8 @@ #include "complex/Common/Result.hpp" #include "complex/Common/Types.hpp" #include "complex/complex_export.hpp" +#include +#include #include #include @@ -195,4 +197,13 @@ COMPLEX_EXPORT Result<> CreateOutputDirectories(const fs::path& outputPath); */ COMPLEX_EXPORT std::vector CreateDelimitersVector(bool tabAsDelimiter, bool semicolonAsDelimiter, bool commaAsDelimiter, bool spaceAsDelimiter); +/** + * @brief This will create DataModifiedActions for each child of the parent path given + * @param dataStructure The DataStructure object + * @param modifiedActions The std::vector<> of DataModifiedAction + * @param parentPath The parent path + * @param ignoredDataPaths And specific DataPath to ignore. + */ +COMPLEX_EXPORT void AppendDataObjectModifications(const DataStructure& dataStructure, std::vector& modifiedActions, const DataPath& parentPath, + const std::vector& ignoredDataPaths); } // namespace complex