From 3c9b44aec13ae7df583805e5c64e867615cda071 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Wed, 22 Apr 2026 08:06:47 -0400 Subject: [PATCH 01/16] Refactored WriteDREAM3D filter algorithm * Refactored into multiple functions for easier readability and added error value constant. --- .../Filters/Algorithms/WriteDREAM3D.cpp | 93 +++++++++++++++---- .../Filters/WriteDREAM3DFilter.cpp | 1 + 2 files changed, 76 insertions(+), 18 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp index 20cd13fa3b..44577ebb84 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp @@ -15,7 +15,8 @@ using namespace nx::core; namespace { -constexpr int32 k_FailedFindPipelineError = -15; +constexpr nx::core::int32 k_NoExportPathError = -1; +constexpr nx::core::int32 k_FailedFindPipelineError = -15; } // namespace // ----------------------------------------------------------------------------- @@ -30,6 +31,71 @@ WriteDREAM3D::WriteDREAM3D(DataStructure& dataStructure, const IFilter::MessageH // ----------------------------------------------------------------------------- WriteDREAM3D::~WriteDREAM3D() noexcept = default; +/** + * @brief Extracts the preceding Pipeline from the PipelineFilter. + * This method returns an empty Pipeline if the PipelineFilter is null. + * @param pipelineNode The PipelineFilter to extract the Pipeline from. + * @return Result The target Pipeline or an error message if the process failed to complete. + */ +Result ExtractPipeline(const PipelineFilter* pipelineNode) +{ + Pipeline pipeline; + if(pipelineNode != nullptr) + { + auto pipelinePtr = pipelineNode->getPrecedingPipeline(); + if(pipelinePtr == nullptr) + { + return MakeErrorResult(k_FailedFindPipelineError, "Failed to retrieve pipeline."); + } + + pipeline = *pipelinePtr; + } + return {pipeline}; +} + +/** + * @brief Writes the DREAM3D file to the temp file, commits changes, and then writes the XDMF file if requested. + * @param atomicFile Temp file for writing the DREAM3D file + * @param dataStructure DataStructure to be written to file. + * @param pipeline Pipeline to write to file. + * @param writeXdmfFile + * @return Result<> + */ +Result<> WriteDREAM3DFile(AtomicFile& atomicFile, const DataStructure& dataStructure, const Pipeline& pipeline, bool writeXdmfFile) +{ + auto exportFilePath = atomicFile.tempFilePath(); + + auto results = DREAM3D::WriteFile(exportFilePath, dataStructure, pipeline, writeXdmfFile); + if(results.invalid()) + { + return results; + } + + // Commit changes to the temp file. Return an invalid Result if errors occured. + if(auto commitResult = atomicFile.commit(); commitResult.invalid()) + { + return commitResult; + } + + // Write the XDMF file if specified + if(writeXdmfFile) + { + // TODO: Double check this + fs::path xdmfFilePath = exportFilePath.replace_extension(".xdmf"); + std::error_code errorCode; + fs::rename(xdmfFilePath, fs::path(exportFilePath).replace_extension(".xdmf"), errorCode); + + // If the XDMF file failed to be renamed, return an invalid Result + if(errorCode) + { + std::string ss = fmt::format("Failed to rename xdmf file with error: '{}'", errorCode.message()); + return MakeErrorResult(errorCode.value(), ss); + } + } + + return {}; +} + // ----------------------------------------------------------------------------- Result<> WriteDREAM3D::operator()() { @@ -61,22 +127,13 @@ Result<> WriteDREAM3D::operator()() auto results = DREAM3D::WriteFile(exportFilePath, m_DataStructure, pipeline, writeXdmf, writeOptions); if(results.valid()) { - Result<> commitResult = atomicFile.commit(); - if(commitResult.invalid()) - { - return commitResult; - } - if(writeXdmf) - { - fs::path xdmfFilePath = exportFilePath.replace_extension(".xdmf"); - std::error_code errorCode; - fs::rename(xdmfFilePath, m_InputValues->ExportFilePath.parent_path() / m_InputValues->ExportFilePath.stem().concat(".xdmf"), errorCode); - if(errorCode) - { - std::string ss = fmt::format("Failed to rename xdmf file with error: '{}'", errorCode.message()); - return MakeErrorResult(errorCode.value(), ss); - } - } + return ConvertResult(std::move(result)); + } + else + { + pipeline = std::move(result.value()); } - return results; + + // Write DREAM.3D file + return WriteDREAM3DFile(atomicFile, m_DataStructure, pipeline, m_InputValues->WriteXdmfFile); } diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteDREAM3DFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteDREAM3DFilter.cpp index 79c14387e5..3add11fc5d 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteDREAM3DFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteDREAM3DFilter.cpp @@ -6,6 +6,7 @@ #include "simplnx/Parameters/FileSystemPathParameter.hpp" #include "simplnx/Parameters/NumberParameter.hpp" #include "simplnx/Utilities/SIMPLConversion.hpp" +#include "SimplnxCore/Filters/Algorithms/WriteDREAM3D.hpp" #include From 63c4084188f7e181e6e2aa887cd5608a936da2c5 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Tue, 12 May 2026 12:53:45 -0400 Subject: [PATCH 02/16] WIP: Updating metadata for expandable IO types * Updating Metadata class for reading and writing DataObject metadata while preserving the data's type information. * Added abstract metadata value class for reading and writing metadata of a specific type with assignment and casting operators. * Adding collection of metadata types for creating the appropriate class object for a given json string --- CMakeLists.txt | 16 ++++ src/simplnx/Core/Application.cpp | 6 ++ src/simplnx/Core/Application.hpp | 8 ++ src/simplnx/DataStructure/Metadata.cpp | 30 ++++++-- src/simplnx/DataStructure/Metadata.hpp | 10 ++- .../Metadata/AbstractMetadataValue.cpp | 0 .../Metadata/AbstractMetadataValue.hpp | 73 +++++++++++++++++++ .../Metadata/BaseMetadataValue.cpp | 19 +++++ .../Metadata/BaseMetadataValue.hpp | 31 ++++++++ .../Metadata/BoolMetadataValue.cpp | 43 +++++++++++ .../Metadata/BoolMetadataValue.hpp | 47 ++++++++++++ .../Metadata/DoubleMetadataValue.cpp | 43 +++++++++++ .../Metadata/DoubleMetadataValue.hpp | 47 ++++++++++++ .../Metadata/IntMetadataValue.cpp | 43 +++++++++++ .../Metadata/IntMetadataValue.hpp | 47 ++++++++++++ .../DataStructure/Metadata/MetaDataList.cpp | 57 +++++++++++++++ .../DataStructure/Metadata/MetaDataList.hpp | 36 +++++++++ .../Metadata/StringMetadataValue.cpp | 48 ++++++++++++ .../Metadata/StringMetadataValue.hpp | 52 +++++++++++++ .../Metadata/VectorMetadataValue.cpp | 0 .../Metadata/VectorMetadataValue.hpp | 72 ++++++++++++++++++ 21 files changed, 721 insertions(+), 7 deletions(-) create mode 100644 src/simplnx/DataStructure/Metadata/AbstractMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/BaseMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/BoolMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/MetaDataList.cpp create mode 100644 src/simplnx/DataStructure/Metadata/MetaDataList.hpp create mode 100644 src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/VectorMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/VectorMetadataValue.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8383529a38..321732363f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -439,6 +439,15 @@ set(SIMPLNX_HDRS ${SIMPLNX_SOURCE_DIR}/DataStructure/Geometry/INodeGeometry2D.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Geometry/INodeGeometry3D.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BaseMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/AbstractMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/MetaDataList.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/VectorMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/DynamicListArray.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/EmptyDataStore.hpp @@ -684,6 +693,13 @@ set(SIMPLNX_SRCS ${SIMPLNX_SOURCE_DIR}/DataStructure/Geometry/TriangleGeom.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Geometry/VertexGeom.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BaseMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/MetaDataList.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Montage/AbstractMontage.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Montage/AbstractTileIndex.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Montage/GridMontage.cpp diff --git a/src/simplnx/Core/Application.cpp b/src/simplnx/Core/Application.cpp index ebd49eab85..b15a08cbd5 100644 --- a/src/simplnx/Core/Application.cpp +++ b/src/simplnx/Core/Application.cpp @@ -120,6 +120,7 @@ Result<> Application::initialize() m_CurrentPath = pathResult.value(); initDefaultDataTypes(); + m_MetaDataList = std::make_unique(); return combinedResult; } @@ -414,3 +415,8 @@ std::vector Application::getDataStoreFormats() const { return m_DataIOCollection->getFormatNames(); } + +nx::core::MetaDataList* Application::getMetaDataList() const +{ + return m_MetaDataList.get(); +} diff --git a/src/simplnx/Core/Application.hpp b/src/simplnx/Core/Application.hpp index 7f9d727b0f..6347f4eb6e 100644 --- a/src/simplnx/Core/Application.hpp +++ b/src/simplnx/Core/Application.hpp @@ -3,6 +3,7 @@ #include "simplnx/Common/Result.hpp" #include "simplnx/Core/Preferences.hpp" #include "simplnx/DataStructure/DataObject.hpp" +#include "simplnx/DataStructure/Metadata/MetaDataList.hpp" #include "simplnx/Filter/FilterList.hpp" #include "simplnx/Plugin/AbstractPlugin.hpp" #include "simplnx/simplnx_export.hpp" @@ -190,6 +191,12 @@ class SIMPLNX_EXPORT Application */ std::vector getDataStoreFormats() const; + /** + * @brief Returns a list of known MetaData formats for reading and writing DataObject metadata. + * @return Known metadata formats + */ + nx::core::MetaDataList* getMetaDataList() const; + protected: /** * @brief Constructs an Application using default values and replaces the @@ -234,6 +241,7 @@ class SIMPLNX_EXPORT Application //////////// // Variables std::unique_ptr m_FilterList; + std::unique_ptr m_MetaDataList; std::filesystem::path m_CurrentPath = ""; std::vector m_Simpl_Uuids; // no duplicates; index must match m_Simplnx_Uuids std::vector m_Simplnx_Uuids; // duplicate allowed conditionally; index must match m_Simpl_Uuids diff --git a/src/simplnx/DataStructure/Metadata.cpp b/src/simplnx/DataStructure/Metadata.cpp index 78c5f80c5c..0bc60a7c83 100644 --- a/src/simplnx/DataStructure/Metadata.cpp +++ b/src/simplnx/DataStructure/Metadata.cpp @@ -1,9 +1,9 @@ #include "Metadata.hpp" +#include "nlohmann/json.hpp" + using namespace nx::core; -namespace nx::core -{ Metadata::Metadata() = default; Metadata::Metadata(const Metadata& rhs) = default; @@ -21,14 +21,15 @@ bool Metadata::contains(const KeyType& key) const return m_Map.find(key) != m_Map.end(); } -Metadata::ValueType Metadata::getData(const KeyType& key) const +const Metadata::ValueType& Metadata::getData(const KeyType& key) const { return m_Map.at(key); } void Metadata::setData(const KeyType& key, const ValueType& value) { - m_Map[key] = value; + //m_Map.insert(key, value); + //m_Map[key] = std::move(value); } void Metadata::remove(const KeyType& key) @@ -65,4 +66,23 @@ Metadata::ConstIterator Metadata::end() const { return m_Map.end(); } -} // namespace nx::core + +std::string Metadata::toJson() const +{ + nlohmann::json json; + for(const auto& [key, value] : m_Map) + { + json[key] = value.toJson(); + } + + return json; +} + +void Metadata::fromJson(const std::string& jsonStr) +{ + nlohmann::json json(jsonStr); + for(auto& [key, value] : json.items()) + { + // m_Map[key] = valueFromJson(value); + } +} \ No newline at end of file diff --git a/src/simplnx/DataStructure/Metadata.hpp b/src/simplnx/DataStructure/Metadata.hpp index 8d51fec279..0320765f9b 100644 --- a/src/simplnx/DataStructure/Metadata.hpp +++ b/src/simplnx/DataStructure/Metadata.hpp @@ -1,5 +1,7 @@ #pragma once +#include "simplnx/DataStructure/Metadata/BaseMetadataValue.hpp" + #include "simplnx/simplnx_export.hpp" #include @@ -21,7 +23,7 @@ class SIMPLNX_EXPORT Metadata { public: using KeyType = std::string; - using ValueType = std::any; + using ValueType = BaseMetadataValue; using Iterator = std::map::iterator; using ConstIterator = std::map::const_iterator; @@ -74,7 +76,7 @@ class SIMPLNX_EXPORT Metadata * @param key The key to retrieve data for * @return ValueType containing the metadata value, or empty std::any if key doesn't exist */ - ValueType getData(const KeyType& key) const; + const ValueType& getData(const KeyType& key) const; /** * @brief Adds or assigns the specified value for the target key. @@ -127,6 +129,10 @@ class SIMPLNX_EXPORT Metadata */ ConstIterator end() const; + std::string toJson() const; + + void fromJson(const std::string& json); + private: std::map m_Map; }; diff --git a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp new file mode 100644 index 0000000000..06093bf01c --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include "BaseMetadataValue.hpp" + +#include "simplnx/Common/StringLiteral.hpp" + +#include + +namespace nx::core +{ +/** + * @brief Abstract typed meta data value class. Derived classes implement the + * specifics for reading and writing the target value, but the AbstractMetaData + * class allows reading and assigning the appropriate data type. + */ +template +class AbstractMetadataValue : public BaseMetadataValue +{ +public: + using ValueType = T; + + ~AbstractMetadataValue() noexcept = default; + + /** + * @brief Default cast to the type in question + * @return metadata value + */ + virtual operator ValueType() const = 0; + + /** + * @brief Assignment operator + * @param rhs + */ + virtual AbstractMetadataValue& operator=(const ValueType& rhs) = 0; + + virtual std::string getTypeName() const = 0; + + /** + * @brief Returns a json string representation for the meta data. + * @return json string + */ + std::string toJson() const override + { + return toJsonImpl(); + } + + /** + * @brief Reads and updates the meta data value based on the provided json string + * @param jsonStr json string value + */ + void fromJson(const std::string& jsonStr) override + { + return fromJsonImpl(jsonStr); + } + +protected: + AbstractMetadataValue() = default; + AbstractMetadataValue(const AbstractMetadataValue& other) = default; + AbstractMetadataValue(AbstractMetadataValue&& other) = default; + + /** + * @brief Abstract method for derived classes to specify the appropriate json string. + * @return json string + */ + virtual std::string toJsonImpl() const = 0; + + /** + * @brief Abstract method for reading data from a json string. + * @param jsonStr json string + */ + virtual void fromJsonImpl(const std::string& jsonStr) = 0; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/BaseMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.cpp new file mode 100644 index 0000000000..d5e28749ab --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.cpp @@ -0,0 +1,19 @@ +#include "BaseMetadataValue.hpp" + +#include "nlohmann/json.hpp" + +namespace nx::core +{ +std::string BaseMetadataValue::toJson() const +{ + nlohmann::json json; + json[k_ValueTypeKey] = "Error"; + json[k_ValueKey] = ""; + return ""; +} + +void BaseMetadataValue::fromJson(const std::string& json) +{ + throw std::runtime_error("BaseMetadataValue::fromJson not implemented"); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp new file mode 100644 index 0000000000..31496fb48c --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "BaseMetadataValue.hpp" + +#include "simplnx/Common/StringLiteral.hpp" + +#include + +namespace nx::core +{ +/** +* @brief Base class for meta data values. +*/ +class BaseMetadataValue +{ +public: + static constexpr StringLiteral k_ValueTypeKey = "type"; + static constexpr StringLiteral k_ValueKey = "value"; + + BaseMetadataValue(const BaseMetadataValue& other) = default; + BaseMetadataValue(BaseMetadataValue&& other) = default; + ~BaseMetadataValue() noexcept = default; + + virtual std::string toJson() const; + + virtual void fromJson(const std::string& json); + +protected: + BaseMetadataValue() = default; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/BoolMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.cpp new file mode 100644 index 0000000000..73986b0523 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.cpp @@ -0,0 +1,43 @@ +#include "BoolMetadataValue.hpp" + +#include "nlohmann/json.hpp" + +namespace nx::core +{ +BoolMetadataValue::BoolMetadataValue(bool value) +: ParentType() +, m_Value(value) +{ +} + +BoolMetadataValue::operator ValueType() const +{ + return m_Value; +} + +BoolMetadataValue::ParentType& BoolMetadataValue::operator=(const ValueType& rhs) +{ + m_Value = rhs; + return *this; +} + +std::string BoolMetadataValue::getTypeName() const +{ + return k_TypeName; +} + +std::string BoolMetadataValue::toJsonImpl() const +{ + nlohmann::json json; + json[k_ValueTypeKey] = "bool"; + json[k_ValueKey] = m_Value; + + return json; +} + +void BoolMetadataValue::fromJsonImpl(const std::string& jsonStr) +{ + nlohmann::json json(jsonStr); + m_Value = json[k_ValueKey].get(); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp new file mode 100644 index 0000000000..400638e870 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include "AbstractMetadataValue.hpp" + +#include "simplnx/simplnx_export.hpp" + +namespace nx::core +{ +/** + * @brief Metadata class implementation for reading and writing boolean metadata. + */ +class SIMPLNX_EXPORT BoolMetadataValue : public AbstractMetadataValue +{ +public: + using ParentType = AbstractMetadataValue; + using ValueType = ParentType::ValueType; + + static constexpr StringLiteral k_TypeName = "bool"; + + BoolMetadataValue(ValueType value = false); + BoolMetadataValue(const BoolMetadataValue& other) = default; + BoolMetadataValue(BoolMetadataValue&& other) = default; + ~BoolMetadataValue() = default; + + /** + * @brief Default cast to the type in question + * @return metadata value + */ + operator ValueType() const override; + + /** + * @brief Assignment operator + * @param rhs + */ + ParentType& operator=(const ValueType& rhs) override; + + std::string getTypeName() const override; + +protected: + std::string toJsonImpl() const override; + + void fromJsonImpl(const std::string& json) override; + +private: + bool m_Value; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp new file mode 100644 index 0000000000..406c1fddc1 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp @@ -0,0 +1,43 @@ +#include "DoubleMetadataValue.hpp" + +#include "nlohmann/json.hpp" + +namespace nx::core +{ +DoubleMetadataValue::DoubleMetadataValue(ValueType value) +: ParentType() +, m_Value(value) +{ +} + +DoubleMetadataValue::operator ValueType() const +{ + return m_Value; +} + +DoubleMetadataValue::ParentType& DoubleMetadataValue::operator=(const ValueType& rhs) +{ + m_Value = rhs; + return *this; +} + +std::string DoubleMetadataValue::getTypeName() const +{ + return k_TypeName; +} + +std::string DoubleMetadataValue::toJsonImpl() const +{ + nlohmann::json json; + json[k_ValueTypeKey] = k_TypeName; + json[k_ValueKey] = m_Value; + + return json; +} + +void DoubleMetadataValue::fromJsonImpl(const std::string& jsonStr) +{ + nlohmann::json json(jsonStr); + m_Value = json[k_ValueKey].get(); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp new file mode 100644 index 0000000000..b603a10e2c --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include "AbstractMetadataValue.hpp" + +#include "simplnx/simplnx_export.hpp" + +namespace nx::core +{ +/** + * @brief Metadata class implementation for reading and writing floating-point metadata. + */ +class SIMPLNX_EXPORT DoubleMetadataValue : public AbstractMetadataValue +{ +public: + using ParentType = AbstractMetadataValue; + using ValueType = ParentType::ValueType; + + static constexpr StringLiteral k_TypeName = "double"; + + DoubleMetadataValue(ValueType value = 0); + DoubleMetadataValue(const DoubleMetadataValue& other) = default; + DoubleMetadataValue(DoubleMetadataValue&& other) = default; + ~DoubleMetadataValue() = default; + + /** + * @brief Default cast to the type in question + * @return metadata value + */ + operator ValueType() const override; + + /** + * @brief Assignment operator + * @param rhs + */ + ParentType& operator=(const ValueType& rhs) override; + + std::string getTypeName() const override; + +protected: + std::string toJsonImpl() const override; + + void fromJsonImpl(const std::string& json) override; + +private: + ValueType m_Value; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp new file mode 100644 index 0000000000..10dd4ce49f --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp @@ -0,0 +1,43 @@ +#include "IntMetadataValue.hpp" + +#include "nlohmann/json.hpp" + +namespace nx::core +{ +IntMetadataValue::IntMetadataValue(int32 value) +: AbstractMetadataValue() +, m_Value(value) +{ +} + +IntMetadataValue::operator int32() const +{ + return m_Value; +} + +IntMetadataValue::ParentType& IntMetadataValue::operator=(const int32& rhs) +{ + m_Value = rhs; + return *this; +} + +std::string IntMetadataValue::getTypeName() const +{ + return k_TypeName; +} + +std::string IntMetadataValue::toJsonImpl() const +{ + nlohmann::json json; + json[k_ValueTypeKey] = k_TypeName; + json[k_ValueKey] = m_Value; + + return json; +} + +void IntMetadataValue::fromJsonImpl(const std::string& jsonStr) +{ + nlohmann::json json(jsonStr); + m_Value = json[k_ValueKey].get(); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp new file mode 100644 index 0000000000..bfee1f5124 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include "AbstractMetadataValue.hpp" + +#include "simplnx/simplnx_export.hpp" + +namespace nx::core +{ +/** + * @brief Metadata class implementation for reading and writing integer metadata. + */ +class SIMPLNX_EXPORT IntMetadataValue : public AbstractMetadataValue +{ +public: + using ParentType = AbstractMetadataValue; + using ValueType = ParentType::ValueType; + + static constexpr StringLiteral k_TypeName = "int32"; + + IntMetadataValue(ValueType value); + IntMetadataValue(const IntMetadataValue& other) = default; + IntMetadataValue(IntMetadataValue&& other) = default; + ~IntMetadataValue() = default; + + /** + * @brief Default cast to the type in question + * @return metadata value + */ + operator ValueType() const override; + + /** + * @brief Assignment operator + * @param rhs + */ + ParentType& operator=(const ValueType& rhs) override; + + std::string getTypeName() const override; + +protected: + std::string toJsonImpl() const override; + + void fromJsonImpl(const std::string& json) override; + +private: + int32 m_Value; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/MetaDataList.cpp b/src/simplnx/DataStructure/Metadata/MetaDataList.cpp new file mode 100644 index 0000000000..642adf98a1 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/MetaDataList.cpp @@ -0,0 +1,57 @@ +#include "MetaDataList.hpp" + +#include "simplnx/DataStructure/Metadata/BoolMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/IntMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/StringMetadataValue.hpp" + +#include "nlohmann/json.hpp" + +namespace nx::core +{ +MetaDataList::MetaDataList() +{ + addDefaultTypes(); +} + +void MetaDataList::addDefaultTypes() +{ + // Boolean Metadata + addMetaDataType(BoolMetadataValue::k_TypeName, [](const std::string& json) { + auto metaData = std::make_unique(); + metaData->fromJson(json); + return metaData; + }); + // Double Metadata + addMetaDataType(DoubleMetadataValue::k_TypeName, [](const std::string& json) { + auto metaData = std::make_unique(); + metaData->fromJson(json); + return metaData; + }); + // Integer Metadata + addMetaDataType(IntMetadataValue::k_TypeName, [](const std::string& json) { + auto metaData = std::make_unique(); + metaData->fromJson(json); + return metaData; + }); + // String Metadata + addMetaDataType(StringMetadataValue::k_TypeName, [](const std::string& json) { + auto metaData = std::make_unique(); + metaData->fromJson(json); + return metaData; + }); +} + +void MetaDataList::addMetaDataType(const KeyType& name, MetaDataCreationFnc constructorFnc) +{ + m_CreationMap[name] = constructorFnc; +} + +std::unique_ptr MetaDataList::createValueFromJson(const std::string& jsonStr) const +{ + nlohmann::json json(jsonStr); + std::string type = json[BaseMetadataValue::k_ValueTypeKey].get(); + + return m_CreationMap.at(type)(json); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/MetaDataList.hpp b/src/simplnx/DataStructure/Metadata/MetaDataList.hpp new file mode 100644 index 0000000000..7d57ae6f4f --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/MetaDataList.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "simplnx/DataStructure/Metadata/BaseMetadataValue.hpp" + +#include "simplnx/simplnx_export.hpp" + +#include +#include +#include + +namespace nx::core +{ +class SIMPLNX_EXPORT MetaDataList +{ +public: + using KeyType = std::string; + using CreatedValueType = std::unique_ptr; + using MetaDataCreationFnc = std::function; + using ContainerType = std::map; + + MetaDataList(); + MetaDataList(const MetaDataList& other) = default; + MetaDataList(MetaDataList&& other) = default; + ~MetaDataList() = default; + + void addMetaDataType(const KeyType& name, MetaDataCreationFnc constructorFnc); + + std::unique_ptr createValueFromJson(const std::string& jsonStr) const; + +protected: + void addDefaultTypes(); + +private: + ContainerType m_CreationMap; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp new file mode 100644 index 0000000000..6f6e51f95a --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp @@ -0,0 +1,48 @@ +#include "StringMetadataValue.hpp" + +#include "nlohmann/json.hpp" + +namespace nx::core +{ +StringMetadataValue::StringMetadataValue() +: AbstractMetadataValue() +{ +} + +StringMetadataValue::StringMetadataValue(const std::string& value) +: AbstractMetadataValue() +, m_Value(value) +{ +} + +StringMetadataValue::operator std::string() const +{ + return m_Value; +} + +StringMetadataValue::ParentType& StringMetadataValue::operator=(const std::string& rhs) +{ + m_Value = rhs; + return *this; +} + +std::string StringMetadataValue::getTypeName() const +{ + return k_TypeName; +} + +std::string StringMetadataValue::toJsonImpl() const +{ + nlohmann::json json; + json[k_ValueTypeKey] = k_TypeName; + json[k_ValueKey] = m_Value; + + return json; +} + +void StringMetadataValue::fromJsonImpl(const std::string& jsonStr) +{ + nlohmann::json json(jsonStr); + m_Value = json[k_ValueKey].get(); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp new file mode 100644 index 0000000000..2471739788 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include "AbstractMetadataValue.hpp" + +#include "simplnx/simplnx_export.hpp" + +namespace nx::core +{ +/** + * @brief String metadata class implementation for reading and writing string-based metadata. + */ +class SIMPLNX_EXPORT StringMetadataValue : public AbstractMetadataValue +{ +public: + using ParentType = AbstractMetadataValue; + using ValueType = ParentType::ValueType; + + static constexpr StringLiteral k_TypeName = "string"; + + StringMetadataValue(); + StringMetadataValue(const ValueType& value); + StringMetadataValue(const StringMetadataValue& other) = default; + StringMetadataValue(StringMetadataValue&& other) = default; + ~StringMetadataValue() = default; + + /** + * @brief Default cast to the type in question + * @return metadata value + */ + operator ValueType() const override; + + /** + * @brief Assignment operator + * @param rhs + */ + ParentType& operator=(const ValueType& rhs) override; + + /** + * @brief Returns the typename for the StringMetadata + * @return typename string + */ + std::string getTypeName() const override; + +protected: + std::string toJsonImpl() const override; + + void fromJsonImpl(const std::string& json) override; + +private: + std::string m_Value; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/VectorMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/VectorMetadataValue.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/simplnx/DataStructure/Metadata/VectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/VectorMetadataValue.hpp new file mode 100644 index 0000000000..077e09963a --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/VectorMetadataValue.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include "AbstractMetadataValue.hpp" + +#include "simplnx/simplnx_export.hpp" + +namespace nx::core +{ +template +class SIMPLNX_EXPORT VectorMetadataValue : public AbstractMetadataValue> +{ +public: + using ParentType = AbstractMetadataValue>; + using ValueType = ParentType::ValueType; + + static constexpr StringLiteral k_TypeName = "array"; + + VectorMetadataValue(const ValueType& value) + : ParentType() + , m_Value(value) + { + } + + VectorMetadataValue(const VectorMetadataValue& other) = default; + VectorMetadataValue(VectorMetadataValue&& other) = default; + + ~VectorMetadataValue() = default; + + /** + * @brief Default cast to the type in question + * @return metadata value + */ + operator ValueType() const override + { + return m_Value; + } + + /** + * @brief Assignment operator + * @param rhs + */ + ParentType& operator=(const ValueType& rhs) override + { + m_Value = rhs; + return *this; + } + + std::string getTypeName() const + { + return k_TypeName; + } + +protected: + std::string toJsonImpl() const override + { + nlohmann::json json; + json[k_ValueTypeKey] = k_TypeName; + json[k_ValueKey] = m_Value; + + return json; + } + + void fromJsonImpl(const std::string& jsonStr) override + { + nlohmann::json json(jsonStr); + m_Value = json[k_ValueKey].get(); + } + +private: + std::vector m_Value; +}; +} // namespace nx::core From 09db07d2e72f3894aa07db11ff608b3466e6d1cb Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Wed, 22 Apr 2026 08:06:47 -0400 Subject: [PATCH 03/16] Refactored WriteDREAM3D filter algorithm * Refactored into multiple functions for easier readability and added error value constant. --- .../Filters/Algorithms/WriteDREAM3D.cpp | 67 ++++++++++++++++--- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp index 44577ebb84..cf5269c972 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp @@ -99,28 +99,73 @@ Result<> WriteDREAM3DFile(AtomicFile& atomicFile, const DataStructure& dataStruc // ----------------------------------------------------------------------------- Result<> WriteDREAM3D::operator()() { - auto atomicFileResult = AtomicFile::Create(m_InputValues->ExportFilePath); - if(atomicFileResult.invalid()) + Pipeline pipeline; + if(pipelineNode != nullptr) { - return ConvertResult(std::move(atomicFileResult)); + auto pipelinePtr = pipelineNode->getPrecedingPipeline(); + if(pipelinePtr == nullptr) + { + return MakeErrorResult(k_FailedFindPipelineError, "Failed to retrieve pipeline."); + } + + pipeline = *pipelinePtr; } - AtomicFile atomicFile = std::move(atomicFileResult.value()); + return {pipeline}; +} +/** + * @brief Writes the DREAM3D file to the temp file, commits changes, and then writes the XDMF file if requested. + * @param atomicFile Temp file for writing the DREAM3D file + * @param dataStructure DataStructure to be written to file. + * @param pipeline Pipeline to write to file. + * @param writeXdmfFile + * @return Result<> + */ +Result<> WriteDREAM3DFile(AtomicFile& atomicFile, const DataStructure& dataStructure, const Pipeline& pipeline, bool writeXdmfFile) +{ auto exportFilePath = atomicFile.tempFilePath(); - auto writeXdmf = m_InputValues->WriteXdmfFile; - Pipeline pipeline; + auto results = DREAM3D::WriteFile(exportFilePath, dataStructure, pipeline, writeXdmfFile); + if(results.invalid()) + { + return results; + } - if(m_InputValues->PipelineNode != nullptr) + // Commit changes to the temp file. Return an invalid Result if errors occured. + if(auto commitResult = atomicFile.commit(); commitResult.invalid()) { - auto pipelinePtr = m_InputValues->PipelineNode->getPrecedingPipeline(); - if(pipelinePtr == nullptr) + return commitResult; + } + + // Write the XDMF file if specified + if(writeXdmfFile) + { + // TODO: Double check this + fs::path xdmfFilePath = exportFilePath.replace_extension(".xdmf"); + std::error_code errorCode; + fs::rename(xdmfFilePath, fs::path(exportFilePath).replace_extension(".xdmf"), errorCode); + + // If the XDMF file failed to be renamed, return an invalid Result + if(errorCode) { - return MakeErrorResult(k_FailedFindPipelineError, "Failed to retrieve pipeline."); + std::string ss = fmt::format("Failed to rename xdmf file with error: '{}'", errorCode.message()); + return MakeErrorResult(errorCode.value(), ss); } + } - pipeline = *pipelinePtr; + return {}; +} + +// ----------------------------------------------------------------------------- +Result<> WriteDREAM3D::operator()() +{ + // Create AtomicFile to write. + auto atomicFileResult = AtomicFile::Create(m_InputValues->ExportFilePath); + if(atomicFileResult.invalid()) + { + return ConvertResult(std::move(atomicFileResult)); } + AtomicFile atomicFile = std::move(atomicFileResult.value()); nx::core::HDF5::DataStructureWriter::WriteOptions writeOptions; writeOptions.compressionLevel = m_InputValues->UseCompression ? m_InputValues->CompressionLevel : 0; From 41421de20dd328bc39964d1395384228a05d2b30 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Fri, 15 May 2026 14:30:18 -0400 Subject: [PATCH 04/16] Added DataObject meta data to DataObject hdf5 IO * Added unit tests for bool, int, double, and string metadata types across round-trip .dream3dnx file IO. * Updated BaseMetadataValue API for reading and writing json. * Added MetaDataList for creating an expandable list of metadata value types from json. * Added a metadata value type for unknown value types to preserve the value even if the type is not known when reading data. --- CMakeLists.txt | 2 + .../SimplnxCore/test/DREAM3DFileTest.cpp | 100 ++++++++++++++++++ src/simplnx/DataStructure/DataStructure.hpp | 1 + .../IO/HDF5/DataStructureReader.cpp | 6 ++ src/simplnx/DataStructure/IO/HDF5/IDataIO.cpp | 52 +++++++++ src/simplnx/DataStructure/IO/HDF5/IDataIO.hpp | 4 + src/simplnx/DataStructure/Metadata.cpp | 38 ++++--- src/simplnx/DataStructure/Metadata.hpp | 74 ++++++++++--- .../Metadata/AbstractMetadataValue.hpp | 50 ++++++--- .../Metadata/BaseMetadataValue.cpp | 11 +- .../Metadata/BaseMetadataValue.hpp | 32 ++++-- .../Metadata/BoolMetadataValue.cpp | 29 +++-- .../Metadata/BoolMetadataValue.hpp | 29 +++-- .../Metadata/DoubleMetadataValue.cpp | 29 +++-- .../Metadata/DoubleMetadataValue.hpp | 31 ++++-- .../Metadata/IntMetadataValue.cpp | 29 +++-- .../Metadata/IntMetadataValue.hpp | 31 ++++-- .../DataStructure/Metadata/MetaDataList.cpp | 19 ++-- .../DataStructure/Metadata/MetaDataList.hpp | 17 ++- .../Metadata/StringMetadataValue.cpp | 29 +++-- .../Metadata/StringMetadataValue.hpp | 29 +++-- .../Metadata/UnknownMetadataValue.cpp | 24 +++++ .../Metadata/UnknownMetadataValue.hpp | 49 +++++++++ 23 files changed, 595 insertions(+), 120 deletions(-) create mode 100644 src/simplnx/DataStructure/Metadata/UnknownMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/UnknownMetadataValue.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 321732363f..1d3c3b5c41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -446,6 +446,7 @@ set(SIMPLNX_HDRS ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/MetaDataList.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/UnknownMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/VectorMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/DynamicListArray.hpp @@ -699,6 +700,7 @@ set(SIMPLNX_SRCS ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/MetaDataList.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/UnknownMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Montage/AbstractMontage.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Montage/AbstractTileIndex.cpp diff --git a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp index 1e51c94f05..f2ab84c1e5 100644 --- a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp +++ b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp @@ -10,6 +10,10 @@ #include "simplnx/DataStructure/DataGroup.hpp" #include "simplnx/DataStructure/DataStore.hpp" #include "simplnx/DataStructure/DataStructure.hpp" +#include "simplnx/DataStructure/Metadata/BoolMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/IntMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/StringMetadataValue.hpp" #include "simplnx/Filter/Arguments.hpp" #include "simplnx/Filter/FilterHandle.hpp" #include "simplnx/Parameters/Dream3dImportParameter.hpp" @@ -82,6 +86,17 @@ fs::path GetIODataPath() return GetDataDir(*app) / Constants::k_Dream3dFilename; } +fs::path GetMetaDataPath() +{ + auto app = Application::Instance(); + if(app == nullptr) + { + throw std::runtime_error("nx::core::Application instance not found"); + } + + return GetDataDir(*app) / "MetaDataTest.dream3d"; +} + fs::path GetExportDataPath() { auto app = Application::Instance(); @@ -886,3 +901,88 @@ TEST_CASE("WriteDREAM3DFilter: Compression_Preflight_RejectsOutOfRangeLevel", "[ REQUIRE(filter.preflight(ds, args).outputActions.valid()); } } + +TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM3DFilter][MetaData]") +{ + UnitTest::LoadPlugins(); + + const std::string groupName = "meta test"; + const std::string intDataName = "int"; + const std::string doubleDataName = "double"; + const std::string stringDataName = "string"; + + constexpr int intValue = 5; + constexpr double doubleValue = 8.6; + const std::string stringValue = "test string"; + + DataStructure dataStructure; + auto* metaObject = DataGroup::Create(dataStructure, groupName); + auto& metadata = metaObject->getMetadata(); + + // Int metadata + { + auto intDataPtr = std::make_shared(); + metadata.setDataPtr(intDataName, intDataPtr); + *intDataPtr.get() = intValue; + } + + // Double metadata + { + auto doubleDataPtr = std::make_shared(); + metadata.setDataPtr(doubleDataName, doubleDataPtr); + *doubleDataPtr.get() = doubleValue; + } + + // String metadata + { + auto stringDataPtr = std::make_shared(); + metadata.setDataPtr(stringDataName, stringDataPtr); + *stringDataPtr.get() = stringValue; + } + + { + std::lock_guard lock(m_DataMutex); + std::filesystem::path metadataPath = GetMetaDataPath(); + // Write .dream3d file + { + auto writeResult = DREAM3D::WriteFile(metadataPath, dataStructure); + SIMPLNX_RESULT_REQUIRE_VALID(writeResult); + } + + // Read .dream3d file + { + auto fileReader = HDF5::FileIO::ReadFile(metadataPath); + auto fileResult = DREAM3D::ReadFile(fileReader); + SIMPLNX_RESULT_REQUIRE_VALID(fileResult); + + auto [pipeline, dataStructureRead] = fileResult.value(); + + // Get MetaData + const auto& metaObjectRead = dataStructureRead.getDataRefAs(DataPath({groupName})); + const auto& metaDataRead = metaObjectRead.getMetadata(); + + auto intDataReadPtr = metaDataRead.getDataPtr(intDataName); + auto doubleDataReadPtr = metaDataRead.getDataPtr(doubleDataName); + auto stringDataReadPtr = metaDataRead.getDataPtr(stringDataName); + + // Require metadata exists + REQUIRE(intDataReadPtr != nullptr); + REQUIRE(doubleDataReadPtr != nullptr); + REQUIRE(stringDataReadPtr != nullptr); + + // Require metadata preserves typename + REQUIRE(intDataReadPtr->getTypeName() == IntMetadataValue::k_TypeName); + REQUIRE(doubleDataReadPtr->getTypeName() == DoubleMetadataValue::k_TypeName); + REQUIRE(stringDataReadPtr->getTypeName() == StringMetadataValue::k_TypeName); + + // Require metadata preserves values + auto intDataReadRef = metaDataRead.getDataRefAs(intDataName); + auto doubleDataReadRef = metaDataRead.getDataRefAs(doubleDataName); + auto stringDataReadRef = metaDataRead.getDataRefAs(stringDataName); + + REQUIRE(intDataReadRef == intValue); + REQUIRE(doubleDataReadRef == doubleValue); + REQUIRE(stringDataReadRef == stringValue); + } + } +} diff --git a/src/simplnx/DataStructure/DataStructure.hpp b/src/simplnx/DataStructure/DataStructure.hpp index 9f0fed78a8..3709f186fe 100644 --- a/src/simplnx/DataStructure/DataStructure.hpp +++ b/src/simplnx/DataStructure/DataStructure.hpp @@ -31,6 +31,7 @@ inline const std::string k_DataStructureTag = "DataStructure"; inline const std::string k_ObjectIdTag = "ObjectId"; inline const std::string k_NextIdTag = "NextObjectId"; inline const std::string k_ImportableTag = "Importable"; +inline const std::string k_ObjectMetaTag = "MetaData"; } // namespace Constants /** diff --git a/src/simplnx/DataStructure/IO/HDF5/DataStructureReader.cpp b/src/simplnx/DataStructure/IO/HDF5/DataStructureReader.cpp index 73b93b0990..34e20715bc 100644 --- a/src/simplnx/DataStructure/IO/HDF5/DataStructureReader.cpp +++ b/src/simplnx/DataStructure/IO/HDF5/DataStructureReader.cpp @@ -238,6 +238,12 @@ Result<> DataStructureReader::readObjectFromGroup(const nx::core::HDF5::GroupIO& { return errorCode; } + + auto metaDataResult = IDataIO::ReadMetaData(*this, parentGroup, objectName, objectId); + if(metaDataResult.invalid()) + { + return metaDataResult; + } } return {}; diff --git a/src/simplnx/DataStructure/IO/HDF5/IDataIO.cpp b/src/simplnx/DataStructure/IO/HDF5/IDataIO.cpp index 28f9347957..13b8548efe 100644 --- a/src/simplnx/DataStructure/IO/HDF5/IDataIO.cpp +++ b/src/simplnx/DataStructure/IO/HDF5/IDataIO.cpp @@ -1,6 +1,7 @@ #include "IDataIO.hpp" #include "simplnx/DataStructure/DataStructure.hpp" +#include "simplnx/DataStructure/IO/HDF5/DataStructureReader.hpp" #include "simplnx/DataStructure/IO/HDF5/DataStructureWriter.hpp" #include "simplnx/Utilities/Parsing/HDF5/IO/DatasetIO.hpp" #include "simplnx/Utilities/Parsing/HDF5/IO/GroupIO.hpp" @@ -49,12 +50,63 @@ Result<> IDataIO::WriteObjectAttributes(DataStructureWriter& dataStructureWriter int32 value = (importable ? 1 : 0); objectWriter.writeScalarAttribute(Constants::k_ImportableTag, value); + // Metadata + if(!dataObject.getMetadata().isEmpty()) + { + Result<> metaDataResult = objectWriter.writeStringAttribute(Constants::k_ObjectMetaTag, dataObject.getMetadata().toJson().dump()); + if(metaDataResult.invalid()) + { + return metaDataResult; + } + } + // Add to DataStructureWriter for use in linking dataStructureWriter.addWriter(objectWriter, dataObject.getId()); return {}; } +Result<> IDataIO::ReadMetaData(DataStructureReader& dataStructureReader, const DataObject::IdType& objectId, const object_reader_type& objectReader) +{ + if(!objectReader.hasAttribute(Constants::k_ObjectMetaTag)) + { + return {}; + } + + DataStructure& dataStructure = dataStructureReader.getDataStructure(); + if(!dataStructure.containsData(objectId)) + { + auto errorStr = fmt::format("DataStructure does not contain DataObject with ID '{}'", objectId); + return MakeErrorResult(-9700, errorStr); + } + + auto& dataObject = dataStructure.getDataRef(objectId); + + Result jsonResult = objectReader.readStringAttribute(Constants::k_ObjectMetaTag); + if(jsonResult.invalid()) + { + return ConvertResult(std::move(jsonResult)); + } + + dataObject.getMetadata().fromJson(jsonResult.value()); + + return {}; +} + +Result<> IDataIO::ReadMetaData(DataStructureReader& dataStructureReader, const group_reader_type& parentReader, const std::string& objectName, const DataObject::IdType& objectId) +{ + if(parentReader.isGroup(objectName)) + { + const auto& group = parentReader.openGroup(objectName); + return ReadMetaData(dataStructureReader, objectId, group); + } + else + { + const auto& dataset = parentReader.openDataset(objectName); + return ReadMetaData(dataStructureReader, objectId, dataset); + } +} + Result<> IDataIO::finishImportingData(DataStructure& dataStructure, const DataPath& dataPath, const group_reader_type& dataStructureGroup) const { return {}; diff --git a/src/simplnx/DataStructure/IO/HDF5/IDataIO.hpp b/src/simplnx/DataStructure/IO/HDF5/IDataIO.hpp index daf3abd1a0..ef7d07261b 100644 --- a/src/simplnx/DataStructure/IO/HDF5/IDataIO.hpp +++ b/src/simplnx/DataStructure/IO/HDF5/IDataIO.hpp @@ -26,6 +26,8 @@ class SIMPLNX_EXPORT IDataIO : public nx::core::IDataFactory ~IDataIO() noexcept override; + static Result<> ReadMetaData(DataStructureReader& dataStructureReader, const group_reader_type& parentReader, const std::string& objectName, const DataObject::IdType& objectId); + /** * @brief Attempts to read the DataObject from HDF5. * Returns a Result<> with any errors or warnings encountered during the process. @@ -93,6 +95,8 @@ class SIMPLNX_EXPORT IDataIO : public nx::core::IDataFactory */ static Result<> WriteObjectAttributes(DataStructureWriter& dataStructureWriter, const DataObject& dataObject, object_writer_type& objectWriter, bool importable); + static Result<> ReadMetaData(DataStructureReader& dataStructureReader, const DataObject::IdType& objectId, const object_reader_type& objectReader); + /** * @brief Protected constructor. */ diff --git a/src/simplnx/DataStructure/Metadata.cpp b/src/simplnx/DataStructure/Metadata.cpp index 0bc60a7c83..206dc3e6b0 100644 --- a/src/simplnx/DataStructure/Metadata.cpp +++ b/src/simplnx/DataStructure/Metadata.cpp @@ -1,5 +1,8 @@ #include "Metadata.hpp" +#include "simplnx/Core/Application.hpp" +#include "simplnx/DataStructure/Metadata/MetaDataList.hpp" + #include "nlohmann/json.hpp" using namespace nx::core; @@ -16,20 +19,30 @@ Metadata& Metadata::operator=(Metadata&& rhs) noexcept = default; Metadata::~Metadata() noexcept = default; +bool Metadata::isEmpty() const +{ + return m_Map.empty(); +} + bool Metadata::contains(const KeyType& key) const { return m_Map.find(key) != m_Map.end(); } -const Metadata::ValueType& Metadata::getData(const KeyType& key) const +const Metadata::ValuePtr& Metadata::getDataPtr(const KeyType& key) const { + if(!contains(key)) + { + return nullptr; + } + return m_Map.at(key); } -void Metadata::setData(const KeyType& key, const ValueType& value) +void Metadata::setDataPtr(const KeyType& key, const ValuePtr& value) { - //m_Map.insert(key, value); - //m_Map[key] = std::move(value); + // m_Map.insert(key, value); + m_Map[key] = std::move(value); } void Metadata::remove(const KeyType& key) @@ -42,11 +55,6 @@ void Metadata::clear() m_Map.clear(); } -Metadata::ValueType& Metadata::operator[](const KeyType& key) -{ - return m_Map[key]; -} - Metadata::Iterator Metadata::begin() { return m_Map.begin(); @@ -67,12 +75,12 @@ Metadata::ConstIterator Metadata::end() const return m_Map.end(); } -std::string Metadata::toJson() const +nlohmann::json Metadata::toJson() const { - nlohmann::json json; + nlohmann::json json = nlohmann::json::object(); for(const auto& [key, value] : m_Map) { - json[key] = value.toJson(); + json[key] = value->toJson(); } return json; @@ -80,9 +88,11 @@ std::string Metadata::toJson() const void Metadata::fromJson(const std::string& jsonStr) { - nlohmann::json json(jsonStr); + MetaDataList* metaDataList = Application::Instance()->getMetaDataList(); + + nlohmann::json json = nlohmann::json::parse(jsonStr); for(auto& [key, value] : json.items()) { - // m_Map[key] = valueFromJson(value); + m_Map[key] = metaDataList->createValueFromJson(value); } } \ No newline at end of file diff --git a/src/simplnx/DataStructure/Metadata.hpp b/src/simplnx/DataStructure/Metadata.hpp index 0320765f9b..187be4f308 100644 --- a/src/simplnx/DataStructure/Metadata.hpp +++ b/src/simplnx/DataStructure/Metadata.hpp @@ -4,8 +4,12 @@ #include "simplnx/simplnx_export.hpp" +#include +#include + #include #include +#include #include namespace nx::core @@ -24,8 +28,9 @@ class SIMPLNX_EXPORT Metadata public: using KeyType = std::string; using ValueType = BaseMetadataValue; - using Iterator = std::map::iterator; - using ConstIterator = std::map::const_iterator; + using ValuePtr = std::shared_ptr; + using Iterator = std::map::iterator; + using ConstIterator = std::map::const_iterator; /** * @brief Default constructor. @@ -63,6 +68,13 @@ class SIMPLNX_EXPORT Metadata */ ~Metadata() noexcept; + /** + * @brief Returns true if there are no metadata values stored. + * Returns false otherwise + * @return bool is empty + */ + bool isEmpty() const; + /** * @brief Checks if metadata exists for the specified key. * @param key The key to check for @@ -71,19 +83,57 @@ class SIMPLNX_EXPORT Metadata bool contains(const KeyType& key) const; /** - * @brief Returns the ValueType for the target key. Returns an empty std::any + * @brief Returns the ValuePtr for the target key. Returns nullptr * if the key does not exist in the Metadata. * @param key The key to retrieve data for - * @return ValueType containing the metadata value, or empty std::any if key doesn't exist + * @return ValuePtr containing the metadata value, or nullptr if key doesn't exist */ - const ValueType& getData(const KeyType& key) const; + const ValuePtr& getDataPtr(const KeyType& key) const; + + /** + * @brief Returns the metadata value for the target key. + * Throws if the key does not exist in the Metadata. + * @param key The key to retrieve data for + * @return metadata value for key of type T + */ + template + const T& getDataRefAs(const KeyType& key) const + { + const auto dataPtr = getDataPtr(key); + if(const auto typedDataPtr = std::static_pointer_cast(dataPtr); typedDataPtr != nullptr) + { + return *typedDataPtr.get(); + } + + std::string errorStr = fmt::format("Metadata '{}' does not exist or cannot be cast to type '{}'", key, typeid(T).name()); + throw std::runtime_error(errorStr); + } + + /** + * @brief Returns the metadata value for the target key. + * Throws if the key does not exist in the Metadata. + * @param key The key to retrieve data for + * @return metadata value for key of type T + */ + template + T& getDataRefAs(const KeyType& key) + { + auto dataPtr = getDataPtr(key); + if(auto typedDataPtr = std::static_pointer_cast(dataPtr); typedDataPtr != nullptr) + { + return *typedDataPtr.get(); + } + + std::string errorStr = fmt::format("Metadata '{}' does not exist or cannot be cast to type '{}'", key, typeid(T).name()); + throw std::runtime_error(errorStr); + } /** * @brief Adds or assigns the specified value for the target key. * @param key The key to set data for * @param value The value to associate with the key */ - void setData(const KeyType& key, const ValueType& value); + void setDataPtr(const KeyType& key, const ValuePtr& value); /** * @brief Clears the metadata with the specified key. Does nothing if the key @@ -97,14 +147,6 @@ class SIMPLNX_EXPORT Metadata */ void clear(); - /** - * @brief Returns a reference to the data with the target key. - * Returns and adds an empty std::any if no data exists with the key value. - * @param key The key to retrieve or create - * @return Reference to the ValueType at the specified key - */ - ValueType& operator[](const KeyType& key); - /** * @brief Returns an iterator to the beginning of the Metadata collection. * @return Iterator to the beginning @@ -129,11 +171,11 @@ class SIMPLNX_EXPORT Metadata */ ConstIterator end() const; - std::string toJson() const; + nlohmann::json toJson() const; void fromJson(const std::string& json); private: - std::map m_Map; + std::map m_Map; }; } // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp index 06093bf01c..1d615a4921 100644 --- a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp @@ -4,6 +4,8 @@ #include "simplnx/Common/StringLiteral.hpp" +#include + #include namespace nx::core @@ -27,30 +29,52 @@ class AbstractMetadataValue : public BaseMetadataValue */ virtual operator ValueType() const = 0; + /** + * @brief Returns the stored value. + * @return metadata value + */ + virtual ValueType getValue() const = 0; + + /** + * @brief Sets the stored value. + * @param value + */ + virtual void setValue(const ValueType& value) = 0; + /** * @brief Assignment operator * @param rhs */ virtual AbstractMetadataValue& operator=(const ValueType& rhs) = 0; - virtual std::string getTypeName() const = 0; + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + virtual bool operator==(const ValueType& rhs) const = 0; + + std::string getTypeName() const + { + return getTypeNameImpl(); + } /** * @brief Returns a json string representation for the meta data. - * @return json string + * @return json */ - std::string toJson() const override + nlohmann::json toJson() const override { return toJsonImpl(); } /** * @brief Reads and updates the meta data value based on the provided json string - * @param jsonStr json string value + * @param json */ - void fromJson(const std::string& jsonStr) override + void fromJson(const nlohmann::json& json) override { - return fromJsonImpl(jsonStr); + return fromJsonImpl(json); } protected: @@ -58,16 +82,18 @@ class AbstractMetadataValue : public BaseMetadataValue AbstractMetadataValue(const AbstractMetadataValue& other) = default; AbstractMetadataValue(AbstractMetadataValue&& other) = default; + virtual std::string getTypeNameImpl() const = 0; + /** - * @brief Abstract method for derived classes to specify the appropriate json string. - * @return json string + * @brief Abstract method for derived classes to specify the appropriate json. + * @return json */ - virtual std::string toJsonImpl() const = 0; + virtual nlohmann::json toJsonImpl() const = 0; /** - * @brief Abstract method for reading data from a json string. - * @param jsonStr json string + * @brief Abstract method for reading data from a json. + * @param jsonStr json */ - virtual void fromJsonImpl(const std::string& jsonStr) = 0; + virtual void fromJsonImpl(const nlohmann::json& json) = 0; }; } // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/BaseMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.cpp index d5e28749ab..dc092d8fac 100644 --- a/src/simplnx/DataStructure/Metadata/BaseMetadataValue.cpp +++ b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.cpp @@ -4,15 +4,20 @@ namespace nx::core { -std::string BaseMetadataValue::toJson() const +std::string BaseMetadataValue::getTypeName() const +{ + return "[Not Implemented]"; +} + +nlohmann::json BaseMetadataValue::toJson() const { nlohmann::json json; json[k_ValueTypeKey] = "Error"; json[k_ValueKey] = ""; - return ""; + return json; } -void BaseMetadataValue::fromJson(const std::string& json) +void BaseMetadataValue::fromJson(const nlohmann::json& json) { throw std::runtime_error("BaseMetadataValue::fromJson not implemented"); } diff --git a/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp index 31496fb48c..6bb7970156 100644 --- a/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp @@ -1,17 +1,19 @@ #pragma once -#include "BaseMetadataValue.hpp" - #include "simplnx/Common/StringLiteral.hpp" +#include "simplnx/simplnx_export.hpp" + +#include + #include namespace nx::core { /** -* @brief Base class for meta data values. -*/ -class BaseMetadataValue + * @brief Base class for meta data values. + */ +class SIMPLNX_EXPORT BaseMetadataValue { public: static constexpr StringLiteral k_ValueTypeKey = "type"; @@ -21,9 +23,23 @@ class BaseMetadataValue BaseMetadataValue(BaseMetadataValue&& other) = default; ~BaseMetadataValue() noexcept = default; - virtual std::string toJson() const; - - virtual void fromJson(const std::string& json); + /** + * @brief Returns the metadata type name. + * @return std::string + */ + virtual std::string getTypeName() const; + + /** + * @brief Returns the metadata's json representation. + * @return json + */ + virtual nlohmann::json toJson() const; + + /** + * @brief Updates the metadata from the provided json value. + * @param json metadata json representation + */ + virtual void fromJson(const nlohmann::json& json); protected: BaseMetadataValue() = default; diff --git a/src/simplnx/DataStructure/Metadata/BoolMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.cpp index 73986b0523..4bd0ce7106 100644 --- a/src/simplnx/DataStructure/Metadata/BoolMetadataValue.cpp +++ b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.cpp @@ -15,29 +15,42 @@ BoolMetadataValue::operator ValueType() const return m_Value; } +BoolMetadataValue::ValueType BoolMetadataValue::getValue() const +{ + return m_Value; +} + +void BoolMetadataValue::setValue(const ValueType& value) +{ + m_Value = value; +} + +bool BoolMetadataValue::operator==(const ValueType& rhs) const +{ + return m_Value == rhs; +} + BoolMetadataValue::ParentType& BoolMetadataValue::operator=(const ValueType& rhs) { m_Value = rhs; return *this; } -std::string BoolMetadataValue::getTypeName() const +std::string BoolMetadataValue::getTypeNameImpl() const { return k_TypeName; } -std::string BoolMetadataValue::toJsonImpl() const +nlohmann::json BoolMetadataValue::toJsonImpl() const { nlohmann::json json; - json[k_ValueTypeKey] = "bool"; - json[k_ValueKey] = m_Value; - + json[k_ValueTypeKey.str()] = k_TypeName; + json[k_ValueKey.str()] = m_Value; return json; } -void BoolMetadataValue::fromJsonImpl(const std::string& jsonStr) +void BoolMetadataValue::fromJsonImpl(const nlohmann::json& json) { - nlohmann::json json(jsonStr); - m_Value = json[k_ValueKey].get(); + m_Value = json[k_ValueKey.str()].get(); } } // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp index 400638e870..bb80200f3d 100644 --- a/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp @@ -2,8 +2,6 @@ #include "AbstractMetadataValue.hpp" -#include "simplnx/simplnx_export.hpp" - namespace nx::core { /** @@ -28,18 +26,37 @@ class SIMPLNX_EXPORT BoolMetadataValue : public AbstractMetadataValue */ operator ValueType() const override; + /** + * @brief Returns the stored value. + * @return metadata value + */ + ValueType getValue() const override; + + /** + * @brief Sets the stored value. + * @param value + */ + void setValue(const ValueType& value) override; + + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + bool operator==(const ValueType& rhs) const override; + /** * @brief Assignment operator * @param rhs */ ParentType& operator=(const ValueType& rhs) override; - std::string getTypeName() const override; - protected: - std::string toJsonImpl() const override; + std::string getTypeNameImpl() const override; + + nlohmann::json toJsonImpl() const override; - void fromJsonImpl(const std::string& json) override; + void fromJsonImpl(const nlohmann::json& json) override; private: bool m_Value; diff --git a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp index 406c1fddc1..e717df81a6 100644 --- a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp +++ b/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp @@ -15,29 +15,42 @@ DoubleMetadataValue::operator ValueType() const return m_Value; } +DoubleMetadataValue::ValueType DoubleMetadataValue::getValue() const +{ + return m_Value; +} + +void DoubleMetadataValue::setValue(const ValueType& value) +{ + m_Value = value; +} + +bool DoubleMetadataValue::operator==(const ValueType& rhs) const +{ + return m_Value == rhs; +} + DoubleMetadataValue::ParentType& DoubleMetadataValue::operator=(const ValueType& rhs) { m_Value = rhs; return *this; } -std::string DoubleMetadataValue::getTypeName() const +std::string DoubleMetadataValue::getTypeNameImpl() const { return k_TypeName; } -std::string DoubleMetadataValue::toJsonImpl() const +nlohmann::json DoubleMetadataValue::toJsonImpl() const { nlohmann::json json; - json[k_ValueTypeKey] = k_TypeName; - json[k_ValueKey] = m_Value; - + json[k_ValueTypeKey.str()] = k_TypeName; + json[k_ValueKey.str()] = m_Value; return json; } -void DoubleMetadataValue::fromJsonImpl(const std::string& jsonStr) +void DoubleMetadataValue::fromJsonImpl(const nlohmann::json& json) { - nlohmann::json json(jsonStr); - m_Value = json[k_ValueKey].get(); + m_Value = json[k_ValueKey.str()].get(); } } // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp index b603a10e2c..75863747ea 100644 --- a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp @@ -2,8 +2,6 @@ #include "AbstractMetadataValue.hpp" -#include "simplnx/simplnx_export.hpp" - namespace nx::core { /** @@ -17,7 +15,7 @@ class SIMPLNX_EXPORT DoubleMetadataValue : public AbstractMetadataValue static constexpr StringLiteral k_TypeName = "double"; - DoubleMetadataValue(ValueType value = 0); + DoubleMetadataValue(ValueType value = 0.0); DoubleMetadataValue(const DoubleMetadataValue& other) = default; DoubleMetadataValue(DoubleMetadataValue&& other) = default; ~DoubleMetadataValue() = default; @@ -28,18 +26,37 @@ class SIMPLNX_EXPORT DoubleMetadataValue : public AbstractMetadataValue */ operator ValueType() const override; + /** + * @brief Returns the stored value. + * @return metadata value + */ + ValueType getValue() const override; + + /** + * @brief Sets the stored value. + * @param value + */ + void setValue(const ValueType& value) override; + + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + bool operator==(const ValueType& rhs) const override; + /** * @brief Assignment operator * @param rhs */ ParentType& operator=(const ValueType& rhs) override; - std::string getTypeName() const override; - protected: - std::string toJsonImpl() const override; + std::string getTypeNameImpl() const override; + + nlohmann::json toJsonImpl() const override; - void fromJsonImpl(const std::string& json) override; + void fromJsonImpl(const nlohmann::json& json) override; private: ValueType m_Value; diff --git a/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp index 10dd4ce49f..aa5e7187b9 100644 --- a/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp +++ b/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp @@ -15,29 +15,42 @@ IntMetadataValue::operator int32() const return m_Value; } +IntMetadataValue::ValueType IntMetadataValue::getValue() const +{ + return m_Value; +} + +void IntMetadataValue::setValue(const ValueType& value) +{ + m_Value = value; +} + +bool IntMetadataValue::operator==(const ValueType& rhs) const +{ + return m_Value == rhs; +} + IntMetadataValue::ParentType& IntMetadataValue::operator=(const int32& rhs) { m_Value = rhs; return *this; } -std::string IntMetadataValue::getTypeName() const +std::string IntMetadataValue::getTypeNameImpl() const { return k_TypeName; } -std::string IntMetadataValue::toJsonImpl() const +nlohmann::json IntMetadataValue::toJsonImpl() const { nlohmann::json json; - json[k_ValueTypeKey] = k_TypeName; - json[k_ValueKey] = m_Value; - + json[k_ValueTypeKey.str()] = k_TypeName; + json[k_ValueKey.str()] = m_Value; return json; } -void IntMetadataValue::fromJsonImpl(const std::string& jsonStr) +void IntMetadataValue::fromJsonImpl(const nlohmann::json& json) { - nlohmann::json json(jsonStr); - m_Value = json[k_ValueKey].get(); + m_Value = json[k_ValueKey.str()].get(); } } // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp index bfee1f5124..5e50fac9a6 100644 --- a/src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp @@ -2,8 +2,6 @@ #include "AbstractMetadataValue.hpp" -#include "simplnx/simplnx_export.hpp" - namespace nx::core { /** @@ -17,7 +15,7 @@ class SIMPLNX_EXPORT IntMetadataValue : public AbstractMetadataValue static constexpr StringLiteral k_TypeName = "int32"; - IntMetadataValue(ValueType value); + IntMetadataValue(ValueType value = 0); IntMetadataValue(const IntMetadataValue& other) = default; IntMetadataValue(IntMetadataValue&& other) = default; ~IntMetadataValue() = default; @@ -28,18 +26,37 @@ class SIMPLNX_EXPORT IntMetadataValue : public AbstractMetadataValue */ operator ValueType() const override; + /** + * @brief Returns the stored value. + * @return metadata value + */ + ValueType getValue() const override; + + /** + * @brief Sets the stored value. + * @param value + */ + void setValue(const ValueType& value) override; + + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + bool operator==(const ValueType& rhs) const override; + /** * @brief Assignment operator * @param rhs */ ParentType& operator=(const ValueType& rhs) override; - std::string getTypeName() const override; - protected: - std::string toJsonImpl() const override; + std::string getTypeNameImpl() const override; + + nlohmann::json toJsonImpl() const override; - void fromJsonImpl(const std::string& json) override; + void fromJsonImpl(const nlohmann::json& json) override; private: int32 m_Value; diff --git a/src/simplnx/DataStructure/Metadata/MetaDataList.cpp b/src/simplnx/DataStructure/Metadata/MetaDataList.cpp index 642adf98a1..1ddbfbca51 100644 --- a/src/simplnx/DataStructure/Metadata/MetaDataList.cpp +++ b/src/simplnx/DataStructure/Metadata/MetaDataList.cpp @@ -4,6 +4,7 @@ #include "simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/IntMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/StringMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/UnknownMetadataValue.hpp" #include "nlohmann/json.hpp" @@ -17,25 +18,25 @@ MetaDataList::MetaDataList() void MetaDataList::addDefaultTypes() { // Boolean Metadata - addMetaDataType(BoolMetadataValue::k_TypeName, [](const std::string& json) { + addMetaDataType(BoolMetadataValue::k_TypeName, [](const nlohmann::json& json) { auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; }); // Double Metadata - addMetaDataType(DoubleMetadataValue::k_TypeName, [](const std::string& json) { + addMetaDataType(DoubleMetadataValue::k_TypeName, [](const nlohmann::json& json) { auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; }); // Integer Metadata - addMetaDataType(IntMetadataValue::k_TypeName, [](const std::string& json) { + addMetaDataType(IntMetadataValue::k_TypeName, [](const nlohmann::json& json) { auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; }); // String Metadata - addMetaDataType(StringMetadataValue::k_TypeName, [](const std::string& json) { + addMetaDataType(StringMetadataValue::k_TypeName, [](const nlohmann::json& json) { auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; @@ -47,10 +48,14 @@ void MetaDataList::addMetaDataType(const KeyType& name, MetaDataCreationFnc cons m_CreationMap[name] = constructorFnc; } -std::unique_ptr MetaDataList::createValueFromJson(const std::string& jsonStr) const +std::unique_ptr MetaDataList::createValueFromJson(const nlohmann::json& json) const { - nlohmann::json json(jsonStr); - std::string type = json[BaseMetadataValue::k_ValueTypeKey].get(); + std::string type = json[BaseMetadataValue::k_ValueTypeKey.str()].get(); + + if(!m_CreationMap.contains(type)) + { + return std::make_unique(json); + } return m_CreationMap.at(type)(json); } diff --git a/src/simplnx/DataStructure/Metadata/MetaDataList.hpp b/src/simplnx/DataStructure/Metadata/MetaDataList.hpp index 7d57ae6f4f..40a52ed4db 100644 --- a/src/simplnx/DataStructure/Metadata/MetaDataList.hpp +++ b/src/simplnx/DataStructure/Metadata/MetaDataList.hpp @@ -15,7 +15,7 @@ class SIMPLNX_EXPORT MetaDataList public: using KeyType = std::string; using CreatedValueType = std::unique_ptr; - using MetaDataCreationFnc = std::function; + using MetaDataCreationFnc = std::function; using ContainerType = std::map; MetaDataList(); @@ -23,11 +23,24 @@ class SIMPLNX_EXPORT MetaDataList MetaDataList(MetaDataList&& other) = default; ~MetaDataList() = default; + /** + * @brief Add a meta data value type for creation from json. + * @param name Metadata type name + * @param constructorFnc Function to create and return a metadata value pointer. + */ void addMetaDataType(const KeyType& name, MetaDataCreationFnc constructorFnc); - std::unique_ptr createValueFromJson(const std::string& jsonStr) const; + /** + * @brief Creates and returns a metadata value from the provided json. + * @param json + * @return std::unique_ptr + */ + std::unique_ptr createValueFromJson(const nlohmann::json& json) const; protected: + /** + * @brief Adds default simplnx metadata value types. + */ void addDefaultTypes(); private: diff --git a/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp index 6f6e51f95a..dc5ff54e42 100644 --- a/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp +++ b/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp @@ -20,29 +20,42 @@ StringMetadataValue::operator std::string() const return m_Value; } +StringMetadataValue::ValueType StringMetadataValue::getValue() const +{ + return m_Value; +} + +void StringMetadataValue::setValue(const ValueType& value) +{ + m_Value = value; +} + +bool StringMetadataValue::operator==(const ValueType& rhs) const +{ + return m_Value == rhs; +} + StringMetadataValue::ParentType& StringMetadataValue::operator=(const std::string& rhs) { m_Value = rhs; return *this; } -std::string StringMetadataValue::getTypeName() const +std::string StringMetadataValue::getTypeNameImpl() const { return k_TypeName; } -std::string StringMetadataValue::toJsonImpl() const +nlohmann::json StringMetadataValue::toJsonImpl() const { nlohmann::json json; - json[k_ValueTypeKey] = k_TypeName; - json[k_ValueKey] = m_Value; - + json[k_ValueTypeKey.str()] = k_TypeName; + json[k_ValueKey.str()] = m_Value; return json; } -void StringMetadataValue::fromJsonImpl(const std::string& jsonStr) +void StringMetadataValue::fromJsonImpl(const nlohmann::json& json) { - nlohmann::json json(jsonStr); - m_Value = json[k_ValueKey].get(); + m_Value = json[k_ValueKey.str()].get(); } } // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp index 2471739788..842b770a40 100644 --- a/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp @@ -2,8 +2,6 @@ #include "AbstractMetadataValue.hpp" -#include "simplnx/simplnx_export.hpp" - namespace nx::core { /** @@ -29,22 +27,41 @@ class SIMPLNX_EXPORT StringMetadataValue : public AbstractMetadataValue Date: Sat, 16 May 2026 04:24:22 -0400 Subject: [PATCH 05/16] Added vector metadata support * Added bool, int, double, and string vector metadata types. * Added unit tests for new metadata types. * Added missing bool metadata testing --- CMakeLists.txt | 10 +- .../SimplnxCore/test/DREAM3DFileTest.cpp | 74 +++++++++++- src/simplnx/DataStructure/Metadata.cpp | 2 +- src/simplnx/DataStructure/Metadata.hpp | 8 ++ .../Metadata/AbstractMetadataValue.hpp | 2 +- .../Metadata/AbstractVectorMetadataValue.hpp | 108 ++++++++++++++++++ .../Metadata/BaseMetadataValue.hpp | 2 +- .../Metadata/BoolVectorMetadataValue.cpp | 44 +++++++ .../Metadata/BoolVectorMetadataValue.hpp | 40 +++++++ .../Metadata/DoubleVectorMetadataValue.cpp | 33 ++++++ .../Metadata/DoubleVectorMetadataValue.hpp | 40 +++++++ .../Metadata/IntVectorMetadataValue.cpp | 33 ++++++ .../Metadata/IntVectorMetadataValue.hpp | 40 +++++++ .../DataStructure/Metadata/MetaDataList.cpp | 28 +++++ .../Metadata/StringVectorMetadataValue.cpp | 33 ++++++ .../Metadata/StringVectorMetadataValue.hpp | 40 +++++++ .../Metadata/VectorMetadataValue.hpp | 72 ------------ 17 files changed, 531 insertions(+), 78 deletions(-) create mode 100644 src/simplnx/DataStructure/Metadata/AbstractVectorMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp delete mode 100644 src/simplnx/DataStructure/Metadata/VectorMetadataValue.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d3c3b5c41..4cdc0ce147 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -441,13 +441,17 @@ set(SIMPLNX_HDRS ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BaseMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/AbstractMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/AbstractVectorMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolVectorMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleVectorMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntVectorMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/MetaDataList.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringVectorMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/UnknownMetadataValue.hpp - ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/VectorMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/DynamicListArray.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/EmptyDataStore.hpp @@ -696,10 +700,14 @@ set(SIMPLNX_SRCS ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BaseMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolVectorMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleVectorMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntVectorMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/MetaDataList.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringVectorMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/UnknownMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Montage/AbstractMontage.cpp diff --git a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp index f2ab84c1e5..6ac50840d1 100644 --- a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp +++ b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp @@ -11,9 +11,13 @@ #include "simplnx/DataStructure/DataStore.hpp" #include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/Metadata/BoolMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/IntMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/StringMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp" #include "simplnx/Filter/Arguments.hpp" #include "simplnx/Filter/FilterHandle.hpp" #include "simplnx/Parameters/Dream3dImportParameter.hpp" @@ -907,24 +911,53 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM UnitTest::LoadPlugins(); const std::string groupName = "meta test"; + const std::string boolDataName = "bool"; + const std::string boolVecDataName = "bool-vec"; const std::string intDataName = "int"; + const std::string intVecDataName = "int-vec"; const std::string doubleDataName = "double"; + const std::string doubleVecDataName = "double-vec"; const std::string stringDataName = "string"; + const std::string stringVecDataName = "string-vec"; - constexpr int intValue = 5; - constexpr double doubleValue = 8.6; + constexpr bool boolValue = true; + constexpr int32 intValue = 5; + constexpr float64 doubleValue = 8.6; const std::string stringValue = "test string"; + const std::vector boolVecValue = {true, false, true}; + const std::vector intVecValue = {5, 6, 7}; + const std::vector doubleVecValue = {8.6, 1.2}; + const std::vector stringVecValue = {"test string"}; DataStructure dataStructure; auto* metaObject = DataGroup::Create(dataStructure, groupName); auto& metadata = metaObject->getMetadata(); + // Bool metadata + { + auto boolDataPtr = std::make_shared(); + metadata.setDataPtr(boolDataName, boolDataPtr); + *boolDataPtr.get() = boolValue; + } + { + auto dataPtr = std::make_shared(); + metadata.setDataPtr(boolVecDataName, dataPtr); + BoolVectorMetadataValue& dataRef = *dataPtr.get(); + dataRef = boolVecValue; + } + // Int metadata { auto intDataPtr = std::make_shared(); metadata.setDataPtr(intDataName, intDataPtr); *intDataPtr.get() = intValue; } + { + auto dataPtr = std::make_shared(); + metadata.setDataPtr(intVecDataName, dataPtr); + Int32VectorMetadataValue& dataRef = *dataPtr.get(); + dataRef = intVecValue; + } // Double metadata { @@ -932,6 +965,12 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM metadata.setDataPtr(doubleDataName, doubleDataPtr); *doubleDataPtr.get() = doubleValue; } + { + auto dataPtr = std::make_shared(); + metadata.setDataPtr(doubleVecDataName, dataPtr); + DoubleVectorMetadataValue& dataRef = *dataPtr.get(); + dataRef = doubleVecValue; + } // String metadata { @@ -939,6 +978,12 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM metadata.setDataPtr(stringDataName, stringDataPtr); *stringDataPtr.get() = stringValue; } + { + auto dataPtr = std::make_shared(); + metadata.setDataPtr(stringVecDataName, dataPtr); + StringVectorMetadataValue& dataRef = *dataPtr.get(); + dataRef = stringVecValue; + } { std::lock_guard lock(m_DataMutex); @@ -961,28 +1006,53 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM const auto& metaObjectRead = dataStructureRead.getDataRefAs(DataPath({groupName})); const auto& metaDataRead = metaObjectRead.getMetadata(); + auto boolDataReadPtr = metaDataRead.getDataPtr(boolDataName); + auto boolVecDataReadPtr = metaDataRead.getDataPtr(boolVecDataName); auto intDataReadPtr = metaDataRead.getDataPtr(intDataName); + auto intVecDataReadPtr = metaDataRead.getDataPtr(intVecDataName); auto doubleDataReadPtr = metaDataRead.getDataPtr(doubleDataName); + auto doubleVecDataReadPtr = metaDataRead.getDataPtr(doubleVecDataName); auto stringDataReadPtr = metaDataRead.getDataPtr(stringDataName); + auto stringVecDataReadPtr = metaDataRead.getDataPtr(stringVecDataName); // Require metadata exists + REQUIRE(boolDataReadPtr != nullptr); + REQUIRE(boolVecDataReadPtr != nullptr); REQUIRE(intDataReadPtr != nullptr); + REQUIRE(intVecDataReadPtr != nullptr); REQUIRE(doubleDataReadPtr != nullptr); + REQUIRE(doubleVecDataReadPtr != nullptr); REQUIRE(stringDataReadPtr != nullptr); + REQUIRE(stringVecDataReadPtr != nullptr); // Require metadata preserves typename + REQUIRE(boolDataReadPtr->getTypeName() == BoolMetadataValue::k_TypeName); + REQUIRE(boolVecDataReadPtr->getTypeName() == BoolVectorMetadataValue::k_TypeName); REQUIRE(intDataReadPtr->getTypeName() == IntMetadataValue::k_TypeName); + REQUIRE(intVecDataReadPtr->getTypeName() == Int32VectorMetadataValue::k_TypeName); REQUIRE(doubleDataReadPtr->getTypeName() == DoubleMetadataValue::k_TypeName); + REQUIRE(doubleVecDataReadPtr->getTypeName() == DoubleVectorMetadataValue::k_TypeName); REQUIRE(stringDataReadPtr->getTypeName() == StringMetadataValue::k_TypeName); + REQUIRE(stringVecDataReadPtr->getTypeName() == StringVectorMetadataValue::k_TypeName); // Require metadata preserves values + auto boolDataReadRef = metaDataRead.getDataRefAs(boolDataName); + auto boolVecDataReadRef = metaDataRead.getDataRefAs(boolVecDataName); auto intDataReadRef = metaDataRead.getDataRefAs(intDataName); + auto intVecDataReadRef = metaDataRead.getDataRefAs(intVecDataName); auto doubleDataReadRef = metaDataRead.getDataRefAs(doubleDataName); + auto doubleVecDataReadRef = metaDataRead.getDataRefAs(doubleVecDataName); auto stringDataReadRef = metaDataRead.getDataRefAs(stringDataName); + auto stringVecDataReadRef = metaDataRead.getDataRefAs(stringVecDataName); + REQUIRE(boolDataReadRef == boolValue); + REQUIRE(boolVecDataReadRef == boolVecValue); REQUIRE(intDataReadRef == intValue); + REQUIRE(intVecDataReadRef == intVecValue); REQUIRE(doubleDataReadRef == doubleValue); + REQUIRE(doubleVecDataReadRef == doubleVecValue); REQUIRE(stringDataReadRef == stringValue); + REQUIRE(stringVecDataReadRef == stringVecValue); } } } diff --git a/src/simplnx/DataStructure/Metadata.cpp b/src/simplnx/DataStructure/Metadata.cpp index 206dc3e6b0..2e021cb976 100644 --- a/src/simplnx/DataStructure/Metadata.cpp +++ b/src/simplnx/DataStructure/Metadata.cpp @@ -95,4 +95,4 @@ void Metadata::fromJson(const std::string& jsonStr) { m_Map[key] = metaDataList->createValueFromJson(value); } -} \ No newline at end of file +} diff --git a/src/simplnx/DataStructure/Metadata.hpp b/src/simplnx/DataStructure/Metadata.hpp index 187be4f308..7a8aa7f7ff 100644 --- a/src/simplnx/DataStructure/Metadata.hpp +++ b/src/simplnx/DataStructure/Metadata.hpp @@ -135,6 +135,14 @@ class SIMPLNX_EXPORT Metadata */ void setDataPtr(const KeyType& key, const ValuePtr& value); + template + void setData(const KeyType& key, const T::ValueType& value) + { + auto dataPtr = std::make_shared(); + *dataPtr.get() = value; + setDataPtr(key, dataPtr); + } + /** * @brief Clears the metadata with the specified key. Does nothing if the key * has no data assigned to it. diff --git a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp index 1d615a4921..17425055d4 100644 --- a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp @@ -80,7 +80,7 @@ class AbstractMetadataValue : public BaseMetadataValue protected: AbstractMetadataValue() = default; AbstractMetadataValue(const AbstractMetadataValue& other) = default; - AbstractMetadataValue(AbstractMetadataValue&& other) = default; + AbstractMetadataValue(AbstractMetadataValue&& other) noexcept = default; virtual std::string getTypeNameImpl() const = 0; diff --git a/src/simplnx/DataStructure/Metadata/AbstractVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/AbstractVectorMetadataValue.hpp new file mode 100644 index 0000000000..a08e19369d --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/AbstractVectorMetadataValue.hpp @@ -0,0 +1,108 @@ +#pragma once + +#include "AbstractMetadataValue.hpp" + +namespace nx::core +{ +template +class AbstractVectorMetadataValue : public AbstractMetadataValue> +{ +public: + using ParentType = AbstractMetadataValue>; + using ValueType = ParentType::ValueType; + using AssignmentReturnType = ParentType; + + AbstractVectorMetadataValue(const AbstractVectorMetadataValue& other) + : ParentType(other) + , m_Value(other.m_Value) + { + } + AbstractVectorMetadataValue(AbstractVectorMetadataValue&& other) noexcept + : ParentType(other) + , m_Value(std::move(other.m_Value)) + { + } + + ~AbstractVectorMetadataValue() noexcept = default; + + /** + * @brief Default cast to the type in question + * @return metadata value + */ + operator ValueType() const override + { + return m_Value; + } + + /** + * @brief Returns the stored value. + * @return metadata value + */ + ValueType getValue() const override + { + return m_Value; + } + + /** + * @brief Sets the stored value. + * @param value + */ + void setValue(const ValueType& value) override + { + m_Value = value; + } + + /** + * @brief Assignment operator + * @param rhs + */ + ParentType& operator=(const ValueType& rhs) override + { + m_Value = rhs; + return *this; + } + + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + bool operator==(const ValueType& rhs) const override + { + return m_Value == rhs; + } + +protected: + AbstractVectorMetadataValue() + : ParentType() + { + } + + AbstractVectorMetadataValue& operator=(const AbstractVectorMetadataValue& rhs) + { + m_Value = rhs.m_Value; + return *this; + } + AbstractVectorMetadataValue& operator=(AbstractVectorMetadataValue&& rhs) noexcept + { + m_Value = std::move(rhs.m_Value); + return *this; + } + + nlohmann::json toJsonImpl() const override + { + nlohmann::json json; + json[ParentType::k_ValueTypeKey] = ParentType::getTypeName(); + json[ParentType::k_ValueKey] = m_Value; + return json; + } + + void fromJsonImpl(const nlohmann::json& json) override + { + m_Value = json[ParentType::k_ValueKey].get(); + } + +private: + std::vector m_Value; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp index 6bb7970156..3d14e54a4d 100644 --- a/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/BaseMetadataValue.hpp @@ -20,7 +20,7 @@ class SIMPLNX_EXPORT BaseMetadataValue static constexpr StringLiteral k_ValueKey = "value"; BaseMetadataValue(const BaseMetadataValue& other) = default; - BaseMetadataValue(BaseMetadataValue&& other) = default; + BaseMetadataValue(BaseMetadataValue&& other) noexcept = default; ~BaseMetadataValue() noexcept = default; /** diff --git a/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.cpp new file mode 100644 index 0000000000..c294f1e523 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.cpp @@ -0,0 +1,44 @@ +#include "BoolVectorMetadataValue.hpp" + +namespace nx::core +{ +BoolVectorMetadataValue::BoolVectorMetadataValue() +: ParentType() +{ +} + +BoolVectorMetadataValue::BoolVectorMetadataValue(const BoolVectorMetadataValue& rhs) +: ParentType(rhs) +{ +} +BoolVectorMetadataValue::BoolVectorMetadataValue(BoolVectorMetadataValue&& rhs) noexcept +: ParentType(rhs) +{ +} + +BoolVectorMetadataValue& BoolVectorMetadataValue::operator=(const BoolVectorMetadataValue& rhs) +{ + setValue(rhs.getValue()); + return *this; +} +BoolVectorMetadataValue& BoolVectorMetadataValue::operator=(BoolVectorMetadataValue&& rhs) noexcept +{ + ParentType::operator=(rhs); + return *this; +} + +std::string BoolVectorMetadataValue::getTypeNameImpl() const +{ + return k_TypeName; +} + +BoolVectorMetadataValue::AssignmentReturnType& BoolVectorMetadataValue::operator=(const ValueType& rhs) +{ + return ParentType::operator=(rhs); +} + +bool BoolVectorMetadataValue::operator==(const ValueType& rhs) const +{ + return ParentType::operator==(rhs); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp new file mode 100644 index 0000000000..3ed5a4e9c9 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "AbstractVectorMetadataValue.hpp" + +namespace nx::core +{ +class SIMPLNX_EXPORT BoolVectorMetadataValue : public AbstractVectorMetadataValue +{ +public: + using ParentType = AbstractVectorMetadataValue; + using ValueType = ParentType::ValueType; + using AssignmentReturnType = ParentType::AssignmentReturnType; + + static constexpr StringLiteral k_TypeName = "vec"; + + BoolVectorMetadataValue(); + BoolVectorMetadataValue(const BoolVectorMetadataValue& rhs); + BoolVectorMetadataValue(BoolVectorMetadataValue&& rhs) noexcept; + ~BoolVectorMetadataValue() noexcept = default; + + BoolVectorMetadataValue& operator=(const BoolVectorMetadataValue& rhs); + BoolVectorMetadataValue& operator=(BoolVectorMetadataValue&& rhs) noexcept; + + /** + * @brief Assignment operator + * @param rhs + */ + AssignmentReturnType& operator=(const ValueType& rhs) override; + + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + bool operator==(const ValueType& rhs) const override; + +protected: + std::string getTypeNameImpl() const override; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.cpp new file mode 100644 index 0000000000..92dcd3ac7b --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.cpp @@ -0,0 +1,33 @@ +#include "DoubleVectorMetadataValue.hpp" + +namespace nx::core +{ +DoubleVectorMetadataValue::DoubleVectorMetadataValue() +: ParentType() +{ +} + +DoubleVectorMetadataValue::DoubleVectorMetadataValue(const DoubleVectorMetadataValue& rhs) +: ParentType(rhs) +{ +} +DoubleVectorMetadataValue::DoubleVectorMetadataValue(DoubleVectorMetadataValue&& rhs) noexcept +: ParentType(rhs) +{ +} + +std::string DoubleVectorMetadataValue::getTypeNameImpl() const +{ + return k_TypeName; +} + +DoubleVectorMetadataValue::AssignmentReturnType& DoubleVectorMetadataValue::operator=(const ValueType& rhs) +{ + return ParentType::operator=(rhs); +} + +bool DoubleVectorMetadataValue::operator==(const ValueType& rhs) const +{ + return ParentType::operator==(rhs); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp new file mode 100644 index 0000000000..571a040a1b --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "AbstractVectorMetadataValue.hpp" + +namespace nx::core +{ +class SIMPLNX_EXPORT DoubleVectorMetadataValue : public AbstractVectorMetadataValue +{ +public: + using ParentType = AbstractVectorMetadataValue; + using ValueType = ParentType::ValueType; + using AssignmentReturnType = ParentType::AssignmentReturnType; + + static constexpr StringLiteral k_TypeName = "vec"; + + DoubleVectorMetadataValue(); + DoubleVectorMetadataValue(const DoubleVectorMetadataValue& rhs); + DoubleVectorMetadataValue(DoubleVectorMetadataValue&& rhs) noexcept; + ~DoubleVectorMetadataValue() noexcept = default; + + DoubleVectorMetadataValue& operator=(const DoubleVectorMetadataValue& rhs) = default; + DoubleVectorMetadataValue& operator=(DoubleVectorMetadataValue&& rhs) noexcept = default; + + /** + * @brief Assignment operator + * @param rhs + */ + AssignmentReturnType& operator=(const ValueType& rhs) override; + + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + bool operator==(const ValueType& rhs) const override; + +protected: + std::string getTypeNameImpl() const override; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.cpp new file mode 100644 index 0000000000..bd68701c03 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.cpp @@ -0,0 +1,33 @@ +#include "IntVectorMetadataValue.hpp" + +namespace nx::core +{ +Int32VectorMetadataValue::Int32VectorMetadataValue() +: ParentType() +{ +} + +Int32VectorMetadataValue::Int32VectorMetadataValue(const Int32VectorMetadataValue& rhs) +: ParentType(rhs) +{ +} +Int32VectorMetadataValue::Int32VectorMetadataValue(Int32VectorMetadataValue&& rhs) noexcept +: ParentType(rhs) +{ +} + +std::string Int32VectorMetadataValue::getTypeNameImpl() const +{ + return k_TypeName; +} + +Int32VectorMetadataValue::AssignmentReturnType& Int32VectorMetadataValue::operator=(const ValueType& rhs) +{ + return ParentType::operator=(rhs); +} + +bool Int32VectorMetadataValue::operator==(const ValueType& rhs) const +{ + return ParentType::operator==(rhs); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp new file mode 100644 index 0000000000..231507948f --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "AbstractVectorMetadataValue.hpp" + +namespace nx::core +{ +class SIMPLNX_EXPORT Int32VectorMetadataValue : public AbstractVectorMetadataValue +{ +public: + using ParentType = AbstractVectorMetadataValue; + using ValueType = ParentType::ValueType; + using AssignmentReturnType = ParentType::AssignmentReturnType; + + static constexpr StringLiteral k_TypeName = "vec"; + + Int32VectorMetadataValue(); + Int32VectorMetadataValue(const Int32VectorMetadataValue& rhs); + Int32VectorMetadataValue(Int32VectorMetadataValue&& rhs) noexcept; + ~Int32VectorMetadataValue() noexcept = default; + + Int32VectorMetadataValue& operator=(const Int32VectorMetadataValue& rhs) = default; + Int32VectorMetadataValue& operator=(Int32VectorMetadataValue&& rhs) noexcept = default; + + /** + * @brief Assignment operator + * @param rhs + */ + AssignmentReturnType& operator=(const ValueType& rhs) override; + + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + bool operator==(const ValueType& rhs) const override; + +protected: + std::string getTypeNameImpl() const override; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/MetaDataList.cpp b/src/simplnx/DataStructure/Metadata/MetaDataList.cpp index 1ddbfbca51..3c90f2cef1 100644 --- a/src/simplnx/DataStructure/Metadata/MetaDataList.cpp +++ b/src/simplnx/DataStructure/Metadata/MetaDataList.cpp @@ -1,9 +1,13 @@ #include "MetaDataList.hpp" #include "simplnx/DataStructure/Metadata/BoolMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/IntMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/StringMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/UnknownMetadataValue.hpp" #include "nlohmann/json.hpp" @@ -23,24 +27,48 @@ void MetaDataList::addDefaultTypes() metaData->fromJson(json); return metaData; }); + // Boolean Vector Metadata + addMetaDataType(BoolVectorMetadataValue::k_TypeName, [](const nlohmann::json& json) { + auto metaData = std::make_unique(); + metaData->fromJson(json); + return metaData; + }); // Double Metadata addMetaDataType(DoubleMetadataValue::k_TypeName, [](const nlohmann::json& json) { auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; }); + // Double Vector Metadata + addMetaDataType(DoubleVectorMetadataValue::k_TypeName, [](const nlohmann::json& json) { + auto metaData = std::make_unique(); + metaData->fromJson(json); + return metaData; + }); // Integer Metadata addMetaDataType(IntMetadataValue::k_TypeName, [](const nlohmann::json& json) { auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; }); + // Integer Vector Metadata + addMetaDataType(Int32VectorMetadataValue::k_TypeName, [](const nlohmann::json& json) { + auto metaData = std::make_unique(); + metaData->fromJson(json); + return metaData; + }); // String Metadata addMetaDataType(StringMetadataValue::k_TypeName, [](const nlohmann::json& json) { auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; }); + // String Vector Metadata + addMetaDataType(StringVectorMetadataValue::k_TypeName, [](const nlohmann::json& json) { + auto metaData = std::make_unique(); + metaData->fromJson(json); + return metaData; + }); } void MetaDataList::addMetaDataType(const KeyType& name, MetaDataCreationFnc constructorFnc) diff --git a/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.cpp new file mode 100644 index 0000000000..1c92dbbbe2 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.cpp @@ -0,0 +1,33 @@ +#include "StringVectorMetadataValue.hpp" + +namespace nx::core +{ +StringVectorMetadataValue::StringVectorMetadataValue() +: ParentType() +{ +} + +StringVectorMetadataValue::StringVectorMetadataValue(const StringVectorMetadataValue& rhs) +: ParentType(rhs) +{ +} +StringVectorMetadataValue::StringVectorMetadataValue(StringVectorMetadataValue&& rhs) noexcept +: ParentType(rhs) +{ +} + +std::string StringVectorMetadataValue::getTypeNameImpl() const +{ + return k_TypeName; +} + +StringVectorMetadataValue::AssignmentReturnType& StringVectorMetadataValue::operator=(const ValueType& rhs) +{ + return ParentType::operator=(rhs); +} + +bool StringVectorMetadataValue::operator==(const ValueType& rhs) const +{ + return ParentType::operator==(rhs); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp new file mode 100644 index 0000000000..add86b2d82 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "AbstractVectorMetadataValue.hpp" + +namespace nx::core +{ +class SIMPLNX_EXPORT StringVectorMetadataValue : public AbstractVectorMetadataValue +{ +public: + using ParentType = AbstractVectorMetadataValue; + using ValueType = ParentType::ValueType; + using AssignmentReturnType = ParentType::AssignmentReturnType; + + static constexpr StringLiteral k_TypeName = "vec"; + + StringVectorMetadataValue(); + StringVectorMetadataValue(const StringVectorMetadataValue& rhs); + StringVectorMetadataValue(StringVectorMetadataValue&& rhs) noexcept; + ~StringVectorMetadataValue() noexcept = default; + + StringVectorMetadataValue& operator=(const StringVectorMetadataValue& rhs) = default; + StringVectorMetadataValue& operator=(StringVectorMetadataValue&& rhs) noexcept = default; + + /** + * @brief Assignment operator + * @param rhs + */ + AssignmentReturnType& operator=(const ValueType& rhs) override; + + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + bool operator==(const ValueType& rhs) const override; + +protected: + std::string getTypeNameImpl() const override; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/VectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/VectorMetadataValue.hpp deleted file mode 100644 index 077e09963a..0000000000 --- a/src/simplnx/DataStructure/Metadata/VectorMetadataValue.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include "AbstractMetadataValue.hpp" - -#include "simplnx/simplnx_export.hpp" - -namespace nx::core -{ -template -class SIMPLNX_EXPORT VectorMetadataValue : public AbstractMetadataValue> -{ -public: - using ParentType = AbstractMetadataValue>; - using ValueType = ParentType::ValueType; - - static constexpr StringLiteral k_TypeName = "array"; - - VectorMetadataValue(const ValueType& value) - : ParentType() - , m_Value(value) - { - } - - VectorMetadataValue(const VectorMetadataValue& other) = default; - VectorMetadataValue(VectorMetadataValue&& other) = default; - - ~VectorMetadataValue() = default; - - /** - * @brief Default cast to the type in question - * @return metadata value - */ - operator ValueType() const override - { - return m_Value; - } - - /** - * @brief Assignment operator - * @param rhs - */ - ParentType& operator=(const ValueType& rhs) override - { - m_Value = rhs; - return *this; - } - - std::string getTypeName() const - { - return k_TypeName; - } - -protected: - std::string toJsonImpl() const override - { - nlohmann::json json; - json[k_ValueTypeKey] = k_TypeName; - json[k_ValueKey] = m_Value; - - return json; - } - - void fromJsonImpl(const std::string& jsonStr) override - { - nlohmann::json json(jsonStr); - m_Value = json[k_ValueKey].get(); - } - -private: - std::vector m_Value; -}; -} // namespace nx::core From 5849d07fbad0aaecbdb3c0f0f7e5a56e1a3566df Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Sat, 16 May 2026 23:58:35 -0400 Subject: [PATCH 06/16] Simplified MetaData API * Simplified MetaData API for setting and retrieving stored values. * Updated unit test to use the shortened setters and added additional checks against shortened getters. --- .../SimplnxCore/test/DREAM3DFileTest.cpp | 101 +++++++----------- src/simplnx/DataStructure/Metadata.cpp | 4 +- src/simplnx/DataStructure/Metadata.hpp | 52 +++++---- .../Metadata/AbstractMetadataValue.hpp | 6 +- 4 files changed, 69 insertions(+), 94 deletions(-) diff --git a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp index 6ac50840d1..49453a753d 100644 --- a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp +++ b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp @@ -933,56 +933,22 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM auto* metaObject = DataGroup::Create(dataStructure, groupName); auto& metadata = metaObject->getMetadata(); - // Bool metadata { - auto boolDataPtr = std::make_shared(); - metadata.setDataPtr(boolDataName, boolDataPtr); - *boolDataPtr.get() = boolValue; - } - { - auto dataPtr = std::make_shared(); - metadata.setDataPtr(boolVecDataName, dataPtr); - BoolVectorMetadataValue& dataRef = *dataPtr.get(); - dataRef = boolVecValue; - } + // Bool metadata + metadata.setData(boolDataName, boolValue); + metadata.setData(boolVecDataName, boolVecValue); - // Int metadata - { - auto intDataPtr = std::make_shared(); - metadata.setDataPtr(intDataName, intDataPtr); - *intDataPtr.get() = intValue; - } - { - auto dataPtr = std::make_shared(); - metadata.setDataPtr(intVecDataName, dataPtr); - Int32VectorMetadataValue& dataRef = *dataPtr.get(); - dataRef = intVecValue; - } + // Int metadata + metadata.setData(intDataName, intValue); + metadata.setData(intVecDataName, intVecValue); - // Double metadata - { - auto doubleDataPtr = std::make_shared(); - metadata.setDataPtr(doubleDataName, doubleDataPtr); - *doubleDataPtr.get() = doubleValue; - } - { - auto dataPtr = std::make_shared(); - metadata.setDataPtr(doubleVecDataName, dataPtr); - DoubleVectorMetadataValue& dataRef = *dataPtr.get(); - dataRef = doubleVecValue; - } + // Double metadata + metadata.setData(doubleDataName, doubleValue); + metadata.setData(doubleVecDataName, doubleVecValue); - // String metadata - { - auto stringDataPtr = std::make_shared(); - metadata.setDataPtr(stringDataName, stringDataPtr); - *stringDataPtr.get() = stringValue; - } - { - auto dataPtr = std::make_shared(); - metadata.setDataPtr(stringVecDataName, dataPtr); - StringVectorMetadataValue& dataRef = *dataPtr.get(); - dataRef = stringVecValue; + // String metadata + metadata.setData(stringDataName, stringValue); + metadata.setData(stringVecDataName, stringVecValue); } { @@ -1006,14 +972,14 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM const auto& metaObjectRead = dataStructureRead.getDataRefAs(DataPath({groupName})); const auto& metaDataRead = metaObjectRead.getMetadata(); - auto boolDataReadPtr = metaDataRead.getDataPtr(boolDataName); - auto boolVecDataReadPtr = metaDataRead.getDataPtr(boolVecDataName); - auto intDataReadPtr = metaDataRead.getDataPtr(intDataName); - auto intVecDataReadPtr = metaDataRead.getDataPtr(intVecDataName); - auto doubleDataReadPtr = metaDataRead.getDataPtr(doubleDataName); - auto doubleVecDataReadPtr = metaDataRead.getDataPtr(doubleVecDataName); - auto stringDataReadPtr = metaDataRead.getDataPtr(stringDataName); - auto stringVecDataReadPtr = metaDataRead.getDataPtr(stringVecDataName); + auto boolDataReadPtr = metaDataRead.getDataValuePtr(boolDataName); + auto boolVecDataReadPtr = metaDataRead.getDataValuePtr(boolVecDataName); + auto intDataReadPtr = metaDataRead.getDataValuePtr(intDataName); + auto intVecDataReadPtr = metaDataRead.getDataValuePtr(intVecDataName); + auto doubleDataReadPtr = metaDataRead.getDataValuePtr(doubleDataName); + auto doubleVecDataReadPtr = metaDataRead.getDataValuePtr(doubleVecDataName); + auto stringDataReadPtr = metaDataRead.getDataValuePtr(stringDataName); + auto stringVecDataReadPtr = metaDataRead.getDataValuePtr(stringVecDataName); // Require metadata exists REQUIRE(boolDataReadPtr != nullptr); @@ -1036,14 +1002,14 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM REQUIRE(stringVecDataReadPtr->getTypeName() == StringVectorMetadataValue::k_TypeName); // Require metadata preserves values - auto boolDataReadRef = metaDataRead.getDataRefAs(boolDataName); - auto boolVecDataReadRef = metaDataRead.getDataRefAs(boolVecDataName); - auto intDataReadRef = metaDataRead.getDataRefAs(intDataName); - auto intVecDataReadRef = metaDataRead.getDataRefAs(intVecDataName); - auto doubleDataReadRef = metaDataRead.getDataRefAs(doubleDataName); - auto doubleVecDataReadRef = metaDataRead.getDataRefAs(doubleVecDataName); - auto stringDataReadRef = metaDataRead.getDataRefAs(stringDataName); - auto stringVecDataReadRef = metaDataRead.getDataRefAs(stringVecDataName); + auto& boolDataReadRef = *metaDataRead.getDataValuePtrAs(boolDataName).get(); + auto& boolVecDataReadRef = *metaDataRead.getDataValuePtrAs(boolVecDataName).get(); + auto& intDataReadRef = *metaDataRead.getDataValuePtrAs(intDataName).get(); + auto& intVecDataReadRef = *metaDataRead.getDataValuePtrAs(intVecDataName).get(); + auto& doubleDataReadRef = *metaDataRead.getDataValuePtrAs(doubleDataName).get(); + auto& doubleVecDataReadRef = *metaDataRead.getDataValuePtrAs(doubleVecDataName).get(); + auto& stringDataReadRef = *metaDataRead.getDataValuePtrAs(stringDataName).get(); + auto& stringVecDataReadRef = *metaDataRead.getDataValuePtrAs(stringVecDataName).get(); REQUIRE(boolDataReadRef == boolValue); REQUIRE(boolVecDataReadRef == boolVecValue); @@ -1053,6 +1019,17 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM REQUIRE(doubleVecDataReadRef == doubleVecValue); REQUIRE(stringDataReadRef == stringValue); REQUIRE(stringVecDataReadRef == stringVecValue); + + // Simplified MetaData API + REQUIRE(metaDataRead.getDataAs(boolDataName) == boolValue); + REQUIRE(metaDataRead.getDataAs(intDataName) == intValue); + REQUIRE(metaDataRead.getDataAs(doubleDataName) == doubleValue); + REQUIRE(metaDataRead.getDataAs(stringDataName) == stringValue); + // vector data + REQUIRE(metaDataRead.getDataAs>(boolVecDataName) == boolVecValue); + REQUIRE(metaDataRead.getDataAs>(intVecDataName) == intVecValue); + REQUIRE(metaDataRead.getDataAs>(doubleVecDataName) == doubleVecValue); + REQUIRE(metaDataRead.getDataAs>(stringVecDataName) == stringVecValue); } } } diff --git a/src/simplnx/DataStructure/Metadata.cpp b/src/simplnx/DataStructure/Metadata.cpp index 2e021cb976..963dd27928 100644 --- a/src/simplnx/DataStructure/Metadata.cpp +++ b/src/simplnx/DataStructure/Metadata.cpp @@ -29,7 +29,7 @@ bool Metadata::contains(const KeyType& key) const return m_Map.find(key) != m_Map.end(); } -const Metadata::ValuePtr& Metadata::getDataPtr(const KeyType& key) const +const Metadata::ValuePtr& Metadata::getDataValuePtr(const KeyType& key) const { if(!contains(key)) { @@ -39,7 +39,7 @@ const Metadata::ValuePtr& Metadata::getDataPtr(const KeyType& key) const return m_Map.at(key); } -void Metadata::setDataPtr(const KeyType& key, const ValuePtr& value) +void Metadata::setDataValuePtr(const KeyType& key, const ValuePtr& value) { // m_Map.insert(key, value); m_Map[key] = std::move(value); diff --git a/src/simplnx/DataStructure/Metadata.hpp b/src/simplnx/DataStructure/Metadata.hpp index 7a8aa7f7ff..c7de49a525 100644 --- a/src/simplnx/DataStructure/Metadata.hpp +++ b/src/simplnx/DataStructure/Metadata.hpp @@ -1,6 +1,6 @@ #pragma once -#include "simplnx/DataStructure/Metadata/BaseMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp" #include "simplnx/simplnx_export.hpp" @@ -88,7 +88,7 @@ class SIMPLNX_EXPORT Metadata * @param key The key to retrieve data for * @return ValuePtr containing the metadata value, or nullptr if key doesn't exist */ - const ValuePtr& getDataPtr(const KeyType& key) const; + const ValuePtr& getDataValuePtr(const KeyType& key) const; /** * @brief Returns the metadata value for the target key. @@ -97,31 +97,12 @@ class SIMPLNX_EXPORT Metadata * @return metadata value for key of type T */ template - const T& getDataRefAs(const KeyType& key) const + std::shared_ptr getDataValuePtrAs(const KeyType& key) const { - const auto dataPtr = getDataPtr(key); - if(const auto typedDataPtr = std::static_pointer_cast(dataPtr); typedDataPtr != nullptr) + ValuePtr dataPtr = getDataValuePtr(key); + if(const auto typedDataPtr = std::static_pointer_cast(dataPtr); typedDataPtr != nullptr) { - return *typedDataPtr.get(); - } - - std::string errorStr = fmt::format("Metadata '{}' does not exist or cannot be cast to type '{}'", key, typeid(T).name()); - throw std::runtime_error(errorStr); - } - - /** - * @brief Returns the metadata value for the target key. - * Throws if the key does not exist in the Metadata. - * @param key The key to retrieve data for - * @return metadata value for key of type T - */ - template - T& getDataRefAs(const KeyType& key) - { - auto dataPtr = getDataPtr(key); - if(auto typedDataPtr = std::static_pointer_cast(dataPtr); typedDataPtr != nullptr) - { - return *typedDataPtr.get(); + return typedDataPtr; } std::string errorStr = fmt::format("Metadata '{}' does not exist or cannot be cast to type '{}'", key, typeid(T).name()); @@ -133,14 +114,31 @@ class SIMPLNX_EXPORT Metadata * @param key The key to set data for * @param value The value to associate with the key */ - void setDataPtr(const KeyType& key, const ValuePtr& value); + void setDataValuePtr(const KeyType& key, const ValuePtr& value); + /** + * @brief Sets or creates a value with the specified key. + * @param key Name of the stored value. + * @param value Value to store + */ template void setData(const KeyType& key, const T::ValueType& value) { auto dataPtr = std::make_shared(); *dataPtr.get() = value; - setDataPtr(key, dataPtr); + setDataValuePtr(key, dataPtr); + } + + /** + * @brief Returns the value stored in the metadata value specified by the given key. + * @param key Name of the stored value to lookup. + * @return T Stored value + */ + template + T getDataAs(const KeyType& key) const + { + const auto& dataValue = getDataValuePtrAs>(key); + return dataValue->getValue(); } /** diff --git a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp index 17425055d4..cb819f5b90 100644 --- a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp @@ -21,6 +21,8 @@ class AbstractMetadataValue : public BaseMetadataValue public: using ValueType = T; + AbstractMetadataValue(const AbstractMetadataValue& other) = default; + AbstractMetadataValue(AbstractMetadataValue&& other) noexcept = default; ~AbstractMetadataValue() noexcept = default; /** @@ -79,9 +81,7 @@ class AbstractMetadataValue : public BaseMetadataValue protected: AbstractMetadataValue() = default; - AbstractMetadataValue(const AbstractMetadataValue& other) = default; - AbstractMetadataValue(AbstractMetadataValue&& other) noexcept = default; - + virtual std::string getTypeNameImpl() const = 0; /** From 97a856a2912d0999eae7a20db9df9ef76d48f2eb Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Tue, 26 May 2026 12:34:32 -0400 Subject: [PATCH 07/16] Add DataStructure comparison functions --- .../SimplnxCore/test/DREAM3DFileTest.cpp | 342 ++++++++++++++++++ .../Metadata/StringMetadataValue.cpp | 2 +- .../Metadata/StringMetadataValue.hpp | 4 + 3 files changed, 347 insertions(+), 1 deletion(-) diff --git a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp index 49453a753d..19e6c71087 100644 --- a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp +++ b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp @@ -286,6 +286,348 @@ DREAM3D::FileData CreateFileData() return {CreateExportPipeline(), CreateTestDataStructure()}; } +void CompareBaseGroups(const BaseGroup* group1, const BaseGroup* group2) +{ + REQUIRE(group1 != nullptr); + REQUIRE(group2 != nullptr); + + REQUIRE(group1->getSize() == group2->getSize()); +} + +void CompareStringArrays(const DataObject* object1, const DataObject* object2) +{ + const auto* array1 = dynamic_cast(object1); + const auto* array2 = dynamic_cast(object2); + + REQUIRE(array1 != nullptr); + REQUIRE(array2 != nullptr); + + REQUIRE(array1->getSize() == array2->getSize()); + REQUIRE(array1->values() == array2->values()); +} + +template +void CompareNeighborLists(const DataObject* object1, const DataObject* object2) +{ + const auto* array1 = dynamic_cast*>(object1); + const auto* array2 = dynamic_cast*>(object2); + + const auto numLists = array1->getNumberOfLists(); + for (usize i = 0; i < numLists; i++) + { + REQUIRE(array1->getList(i) == array2->getList(i)); + } +} + +void CompareINeighborLists(const DataObject* object1, const DataObject* object2) +{ + const auto* array1 = dynamic_cast(object1); + const auto* array2 = dynamic_cast(object2); + + REQUIRE(array1 != nullptr); + REQUIRE(array2 != nullptr); + + REQUIRE(array1->getDataType() == array2->getDataType()); + switch (array1->getDataType()) + { + case DataType::int8: + CompareNeighborLists(object1, object2); + break; + case DataType::int16: + CompareNeighborLists(object1, object2); + break; + case DataType::int32: + CompareNeighborLists(object1, object2); + break; + case DataType::int64: + CompareNeighborLists(object1, object2); + break; + case DataType::uint8: + CompareNeighborLists(object1, object2); + break; + case DataType::uint16: + CompareNeighborLists(object1, object2); + break; + case DataType::uint32: + CompareNeighborLists(object1, object2); + break; + case DataType::uint64: + CompareNeighborLists(object1, object2); + break; + case DataType::float32: + CompareNeighborLists(object1, object2); + break; + case DataType::float64: + CompareNeighborLists(object1, object2); + break; + } +} + +template +void CompareDataArrays(const IDataArray* object1, const IDataArray* object2) +{ + const auto* array1 = dynamic_cast*>(object1); + const auto* array2 = dynamic_cast*>(object2); + + REQUIRE(array1->getTupleShape() == array2->getTupleShape()); + REQUIRE(array1->getComponentShape() == array2->getComponentShape()); + + auto& store1 = array1->getDataStoreRef(); + auto& store2 = array2->getDataStoreRef(); + + const auto size = store1.getSize(); + for(usize i = 0; i < size; i++) + { + REQUIRE(store1[i] == store2[i]); + } +} + +void CompareIDataArrays(const DataObject* object1, const DataObject* object2) +{ + const auto* array1 = dynamic_cast(object1); + const auto* array2 = dynamic_cast(object2); + + REQUIRE(array1 != nullptr); + REQUIRE(array2 != nullptr); + + REQUIRE(array1->getArrayType() == array2->getArrayType()); + REQUIRE(array1->getDataType() == array2->getDataType()); + + switch(array1->getDataType()) + { + case DataType::int8: + CompareDataArrays(array1, array2); + return; + case DataType::int16: + CompareDataArrays(array1, array2); + return; + case DataType::int32: + CompareDataArrays(array1, array2); + return; + case DataType::int64: + CompareDataArrays(array1, array2); + return; + case DataType::uint8: + CompareDataArrays(array1, array2); + return; + case DataType::uint16: + CompareDataArrays(array1, array2); + return; + case DataType::uint32: + CompareDataArrays(array1, array2); + return; + case DataType::uint64: + CompareDataArrays(array1, array2); + return; + case DataType::float32: + CompareDataArrays(array1, array2); + return; + case DataType::float64: + CompareDataArrays(array1, array2); + return; + case DataType::boolean: + CompareDataArrays(array1, array2); + return; + } +} + +void CompareNodeGeom0D(const INodeGeometry0D* geom1, const INodeGeometry0D* geom2) +{ + REQUIRE(geom1 != nullptr); + REQUIRE(geom2 != nullptr); + + CompareIDataArrays(geom1->getVertices(), geom2->getVertices()); +} + +void CompareNodeGeom1D(const INodeGeometry1D* geom1, const INodeGeometry1D* geom2) +{ + REQUIRE(geom1 != nullptr); + REQUIRE(geom2 != nullptr); + + CompareNodeGeom0D(geom1, geom2); + + CompareIDataArrays(geom1->getEdges(), geom2->getEdges()); +} + +void CompareNodeGeom2D(const INodeGeometry2D* geom1, const INodeGeometry2D* geom2) +{ + REQUIRE(geom1 != nullptr); + REQUIRE(geom2 != nullptr); + + CompareNodeGeom1D(geom1, geom2); + + CompareIDataArrays(geom1->getFaces(), geom2->getFaces()); +} + +void CompareNodeGeom3D(const INodeGeometry3D* geom1, const INodeGeometry3D* geom2) +{ + REQUIRE(geom1 != nullptr); + REQUIRE(geom2 != nullptr); + + CompareNodeGeom2D(geom1, geom2); + + CompareIDataArrays(geom1->getPolyhedra(), geom2->getPolyhedra()); +} + +void CompareEdgeGeom(const DataObject* object1, const DataObject* object2) +{ + const auto* geom1 = dynamic_cast(object1); + const auto* geom2 = dynamic_cast(object2); + + CompareBaseGroups(geom1, geom2); + CompareNodeGeom1D(geom1, geom2); +} + +void CompareHexahedralGeom(const DataObject* object1, const DataObject* object2) +{ + const auto* geom1 = dynamic_cast(object1); + const auto* geom2 = dynamic_cast(object2); + + CompareBaseGroups(geom1, geom2); + CompareNodeGeom3D(geom1, geom2); +} + +void CompareImageGeom(const DataObject* object1, const DataObject* object2) +{ + const auto* geom1 = dynamic_cast(object1); + const auto* geom2 = dynamic_cast(object2); + + CompareBaseGroups(geom1, geom2); + + REQUIRE(geom1->getSpacing() == geom2->getSpacing()); + REQUIRE(geom1->getOrigin() == geom2->getOrigin()); + REQUIRE(geom1->getDimensions() == geom2->getDimensions()); +} + +void CompareQuadGeom(const DataObject* object1, const DataObject* object2) +{ + const auto* geom1 = dynamic_cast(object1); + const auto* geom2 = dynamic_cast(object2); + + CompareBaseGroups(geom1, geom2); + CompareNodeGeom2D(geom1, geom2); +} + +void CompareRectGridGeom(const DataObject* object1, const DataObject* object2) +{ + const auto* geom1 = dynamic_cast(object1); + const auto* geom2 = dynamic_cast(object2); + + CompareBaseGroups(geom1, geom2); + CompareIDataArrays(geom1->getXBounds(), geom2->getXBounds()); + CompareIDataArrays(geom1->getYBounds(), geom2->getYBounds()); + CompareIDataArrays(geom1->getZBounds(), geom2->getZBounds()); +} + +void CompareTetrahedralGeom(const DataObject* object1, const DataObject* object2) +{ + const auto* geom1 = dynamic_cast(object1); + const auto* geom2 = dynamic_cast(object2); + + CompareBaseGroups(geom1, geom2); + CompareNodeGeom3D(geom1, geom2); +} + +void CompareTriangleGeom(const DataObject* object1, const DataObject* object2) +{ + const auto* geom1 = dynamic_cast(object1); + const auto* geom2 = dynamic_cast(object2); + + CompareBaseGroups(geom1, geom2); + CompareNodeGeom2D(geom1, geom2); +} + +void CompareVertexGeom(const DataObject* object1, const DataObject* object2) +{ + const auto* geom1 = dynamic_cast(object1); + const auto* geom2 = dynamic_cast(object2); + + CompareBaseGroups(geom1, geom2); + CompareNodeGeom0D(geom1, geom2); +} + +void CompareAttributeMatrices(const DataObject* object1, const DataObject* object2) +{ + const auto* group1 = dynamic_cast(object1); + const auto* group2 = dynamic_cast(object2); + + CompareBaseGroups(group1, group2); + + REQUIRE(group1->getNumberOfTuples() == group2->getNumberOfTuples()); + REQUIRE(group1->getShape() == group2->getShape()); +} + +void CompareDataGroups(const DataObject* object1, const DataObject* object2) +{ + const auto* group1 = dynamic_cast(object1); + const auto* group2 = dynamic_cast(object2); + + CompareBaseGroups(group1, group2); +} + +void CompareMetaData(const Metadata& metaData1, const Metadata& metaData2) +{ + for(const auto& [key, valuePtr] : metaData1) + { + auto& valueRef1 = *valuePtr.get(); + auto& valueRef2 = *metaData2.getDataValuePtr(key).get(); + + REQUIRE(valueRef1.toJson().dump() == valueRef2.toJson().dump()); + } +} + +void CompareDataObjects(const DataStructure& dataStruct1, const DataStructure& dataStruct2, const DataPath& dataPath) +{ + const auto* object1 = dataStruct1.getData(dataPath); + const auto* object2 = dataStruct2.getData(dataPath); + + if(object1 == nullptr) + { + if(object2 == nullptr) + { + return; + } + else + { + FAIL(); + } + } + + // Compare names + REQUIRE(object1->getName() == object2->getName()); + + // Compare MetaData + CompareMetaData(object1->getMetadata(), object2->getMetadata()); + + switch(object1->getDataObjectType()) + { + case DataObject::Type::AttributeMatrix: + CompareAttributeMatrices(object1, object2); + break; + case DataObject::Type::DataArray: + CompareIDataArrays(object1, object2); + break; + case DataObject::Type::DataGroup: + CompareDataGroups(object1, object2); + break; + } +} + +void CompareDataStructures(const DataStructure& dataStruct1, const DataStructure& dataStruct2) +{ + auto dataPaths1 = dataStruct1.getAllDataPaths(); + auto dataPaths2 = dataStruct2.getAllDataPaths(); + + REQUIRE(dataPaths1.size() == dataPaths2.size()); + for(const auto& dataPath : dataPaths1) + { + auto iter = std::find(dataPaths2.begin(), dataPaths2.end(), dataPath); + REQUIRE(iter != dataPaths2.end()); + + CompareDataObjects(dataStruct1, dataStruct2, dataPath); + } +} + } // End Namespace TEST_CASE("DREAM3DFileTest:DREAM3D File IO Test", "[WriteDREAM3DFilter]") diff --git a/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp index dc5ff54e42..6ca52e5921 100644 --- a/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp +++ b/src/simplnx/DataStructure/Metadata/StringMetadataValue.cpp @@ -15,7 +15,7 @@ StringMetadataValue::StringMetadataValue(const std::string& value) { } -StringMetadataValue::operator std::string() const +StringMetadataValue::operator StringMetadataValue::ValueType() const { return m_Value; } diff --git a/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp index 842b770a40..9572a0bf7f 100644 --- a/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp @@ -2,6 +2,10 @@ #include "AbstractMetadataValue.hpp" +#include "simplnx/simplnx_export.hpp" + +#include + namespace nx::core { /** From edb59d9e16ada6db750ef4f8f7e2437d80b394e3 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Tue, 26 May 2026 12:42:27 -0400 Subject: [PATCH 08/16] Expand test DataStructure with geometries --- .../SimplnxCore/test/DREAM3DFileTest.cpp | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp index 19e6c71087..b369f336bb 100644 --- a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp +++ b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp @@ -58,6 +58,15 @@ std::mutex m_DataMutex; namespace DataNames { +constexpr StringLiteral k_EdgeGeomName = "EdgeGeom"; +constexpr StringLiteral k_QuadGeomName = "QuadGeom"; +constexpr StringLiteral k_RectGridGeomName = "RectGridGeom"; +constexpr StringLiteral k_TetrahedralGeomName = "TetrahedralGeom"; +constexpr StringLiteral k_TriangleGeomName = "TriangleGeom"; +constexpr StringLiteral k_VertexGeomName = "VertexGeom"; + +constexpr StringLiteral k_VertexListName = "Vertex List"; + constexpr StringLiteral k_Group1Name = "Top-Level"; constexpr StringLiteral k_Group2Name = "Second-Level"; constexpr StringLiteral k_Group3Name = "Third-Level"; @@ -156,9 +165,85 @@ fs::path GetReMultiExportDataPath() return GetDataDir(*app) / Constants::k_MultiExportFilename3; } +void SetupNodeGeom0D(DataStructure& dataStructure, INodeGeometry0D* geom, const ShapeType& tupleShape) +{ + auto vertexStore = DataStoreUtilities::CreateDataStore(tupleShape, {3}, IDataAction::Mode::Execute); + auto* vertexList = DataArray::Create(dataStructure, DataNames::k_VertexListName, vertexStore, geom->getId()); + geom->setVertices(*vertexList); +} + +void SetupNodeGeom1D(DataStructure& dataStructure, INodeGeometry1D* geom, const ShapeType& tupleShape) +{ + auto edgeStore = DataStoreUtilities::CreateDataStore(tupleShape, {3}, IDataAction::Mode::Execute); + auto* edgeList = DataArray::Create(dataStructure, DataNames::k_VertexListName, edgeStore, geom->getId()); + geom->setEdgeList(*edgeList); +} + +void SetupNodeGeom2D(DataStructure& dataStructure, INodeGeometry2D* geom, const ShapeType& tupleShape) +{ + auto faceStore = DataStoreUtilities::CreateDataStore(tupleShape, {3}, IDataAction::Mode::Execute); + auto* faceList = DataArray::Create(dataStructure, DataNames::k_VertexListName, faceStore, geom->getId()); + geom->setFaceList(*faceList); +} + +void SetupNodeGeom3D(DataStructure& dataStructure, INodeGeometry3D* geom, const ShapeType& tupleShape) +{ + auto polyhedraStore = DataStoreUtilities::CreateDataStore(tupleShape, {3}, IDataAction::Mode::Execute); + auto* polyhedraList = DataArray::Create(dataStructure, DataNames::k_VertexListName, polyhedraStore, geom->getId()); + geom->setPolyhedraList(*polyhedraList); +} + +void CreateEdgeGeom(DataStructure& dataStructure) +{ + auto* geom = EdgeGeom::Create(dataStructure, DataNames::k_EdgeGeomName); + SetupNodeGeom1D(dataStructure, geom); +} + +void CreateQuadGeom(DataStructure& dataStructure) +{ + auto* geom = QuadGeom::Create(dataStructure, DataNames::k_QuadGeomName); + SetupNodeGeom3D(dataStructure, geom); +} + +void CreateRectGridGeom(DataStructure& dataStructure) +{ + auto* geom = RectGridGeom::Create(dataStructure, DataNames::k_RectGridGeomName); +} + +void CreateTetrahedralGeom(DataStructure& dataStructure) +{ + auto* geom = TetrahedralGeom::Create(dataStructure, DataNames::k_TetrahedralGeomName); + SetupNodeGeom3D(dataStructure, geom); +} + +void CreateTriangleGeom(DataStructure& dataStructure) +{ + auto* geom = TriangleGeom::Create(dataStructure, DataNames::k_TriangleGeomName); + SetupNodeGeom2D(dataStructure, geom); +} + +void CreateVertexGeom(DataStructure& dataStructure) +{ + auto* geom = VertexGeom::Create(dataStructure, DataNames::k_VertexGeomName); + SetupNodeGeom0D(dataStructure, geom); +} + +void CreateGeometries(DataStructure& dataStructure) +{ + CreateEdgeGeom(dataStructure); + CreateQuadGeom(dataStructure); + CreateRectGridGeom(dataStructure); + CreateTetrahedralGeom(dataStructure); + CreateTriangleGeom(dataStructure); + CreateVertexGeom(dataStructure); +} + DataStructure CreateTestDataStructure() { DataStructure dataStructure; + + CreateGeometries(dataStructure); + auto group1 = DataGroup::Create(dataStructure, DataNames::k_Group1Name); auto group2 = DataGroup::Create(dataStructure, DataNames::k_Group2Name, group1->getId()); auto group3 = DataGroup::Create(dataStructure, DataNames::k_Group3Name, group2->getId()); From 2dbdad2776dad70cfd0094e2f98ff8f0f014cb46 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Tue, 26 May 2026 13:01:48 -0400 Subject: [PATCH 09/16] Fix missing parameters --- .../SimplnxCore/test/DREAM3DFileTest.cpp | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp index b369f336bb..efaa6ad8ee 100644 --- a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp +++ b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp @@ -52,6 +52,8 @@ const fs::path k_ExportFilename2 = "export2.dream3d"; const fs::path k_MultiExportFilename1 = "multi_export1.dream3d"; const fs::path k_MultiExportFilename2 = "multi_export2.dream3d"; const fs::path k_MultiExportFilename3 = "multi_export3.dream3d"; + +const ShapeType k_TestDataShape = {2, 3}; } // namespace Constants std::mutex m_DataMutex; @@ -196,13 +198,13 @@ void SetupNodeGeom3D(DataStructure& dataStructure, INodeGeometry3D* geom, const void CreateEdgeGeom(DataStructure& dataStructure) { auto* geom = EdgeGeom::Create(dataStructure, DataNames::k_EdgeGeomName); - SetupNodeGeom1D(dataStructure, geom); + SetupNodeGeom1D(dataStructure, geom, Constants::k_TestDataShape); } void CreateQuadGeom(DataStructure& dataStructure) { auto* geom = QuadGeom::Create(dataStructure, DataNames::k_QuadGeomName); - SetupNodeGeom3D(dataStructure, geom); + SetupNodeGeom2D(dataStructure, geom, Constants::k_TestDataShape); } void CreateRectGridGeom(DataStructure& dataStructure) @@ -213,19 +215,19 @@ void CreateRectGridGeom(DataStructure& dataStructure) void CreateTetrahedralGeom(DataStructure& dataStructure) { auto* geom = TetrahedralGeom::Create(dataStructure, DataNames::k_TetrahedralGeomName); - SetupNodeGeom3D(dataStructure, geom); + SetupNodeGeom3D(dataStructure, geom, Constants::k_TestDataShape); } void CreateTriangleGeom(DataStructure& dataStructure) { auto* geom = TriangleGeom::Create(dataStructure, DataNames::k_TriangleGeomName); - SetupNodeGeom2D(dataStructure, geom); + SetupNodeGeom2D(dataStructure, geom, Constants::k_TestDataShape); } void CreateVertexGeom(DataStructure& dataStructure) { auto* geom = VertexGeom::Create(dataStructure, DataNames::k_VertexGeomName); - SetupNodeGeom0D(dataStructure, geom); + SetupNodeGeom0D(dataStructure, geom, Constants::k_TestDataShape); } void CreateGeometries(DataStructure& dataStructure) @@ -827,6 +829,33 @@ TEST_CASE("DREAM3DFileTest:Import/Export DREAM3D Filter Test", "[ReadDREAM3DFilt } } +TEST_CASE("DREAM3DFileTest:Import/Export DREAM3D Filter Test: Expanded DataStructure", "[ReadDREAM3DFilter][WriteDREAM3DFilter]") +{ + auto app = Application::GetOrCreateInstance(); + + fs::path path = GetDataDir(*app) / "ExpandedDataStructureTestData.dream3d"; + + DataStructure exportDataStructure = CreateTestDataStructure(); + + WriteDREAM3DFilter writeDream3dFilter; + Arguments writeArgs; + writeArgs.insertOrAssign(WriteDREAM3DFilter::k_ExportFilePath, path); + writeArgs.insertOrAssign(WriteDREAM3DFilter::k_WriteXdmf, false); + Result<> writeResult = writeDream3dFilter.execute(exportDataStructure, writeArgs).result; + SIMPLNX_RESULT_REQUIRE_VALID(writeResult); + + DataStructure importDataStructure; + + ReadDREAM3DFilter readDream3dFilter; + Arguments readArgs; + Dream3dImportParameter::ImportData importData(path); + readArgs.insertOrAssign(ReadDREAM3DFilter::k_ImportFileData, importData); + Result<> readResult = readDream3dFilter.execute(importDataStructure, readArgs).result; + SIMPLNX_RESULT_REQUIRE_VALID(readResult); + + CompareDataStructures(exportDataStructure, importDataStructure); +} + TEST_CASE("DREAM3DFileTest:Import/Export Multi-DREAM3D Filter Test", "[ReadDREAM3DFilter][WriteDREAM3DFilter]") { UnitTest::LoadPlugins(); From 229c8fb045e680711e2f0ee2b58a3a01fba76e32 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Fri, 29 May 2026 08:11:29 -0400 Subject: [PATCH 10/16] Rename metadata value types --- CMakeLists.txt | 16 +++--- .../Metadata/DoubleMetadataValue.cpp | 56 ------------------- .../Metadata/DoubleVectorMetadataValue.cpp | 33 ----------- .../Metadata/DoubleVectorMetadataValue.hpp | 40 ------------- .../Metadata/Float64MetadataValue.cpp | 56 +++++++++++++++++++ ...dataValue.hpp => Float64MetadataValue.hpp} | 14 ++--- .../Metadata/Float64VectorMetadataValue.cpp | 33 +++++++++++ .../Metadata/Float64VectorMetadataValue.hpp | 40 +++++++++++++ .../Metadata/Int32MetadataValue.cpp | 56 +++++++++++++++++++ ...tadataValue.hpp => Int32MetadataValue.hpp} | 14 ++--- ...Value.cpp => Int32VectorMetadataValue.cpp} | 2 +- ...Value.hpp => Int32VectorMetadataValue.hpp} | 4 +- .../Metadata/IntMetadataValue.cpp | 56 ------------------- 13 files changed, 210 insertions(+), 210 deletions(-) delete mode 100644 src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp delete mode 100644 src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.cpp delete mode 100644 src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/Float64MetadataValue.cpp rename src/simplnx/DataStructure/Metadata/{DoubleMetadataValue.hpp => Float64MetadataValue.hpp} (73%) create mode 100644 src/simplnx/DataStructure/Metadata/Float64VectorMetadataValue.cpp create mode 100644 src/simplnx/DataStructure/Metadata/Float64VectorMetadataValue.hpp create mode 100644 src/simplnx/DataStructure/Metadata/Int32MetadataValue.cpp rename src/simplnx/DataStructure/Metadata/{IntMetadataValue.hpp => Int32MetadataValue.hpp} (73%) rename src/simplnx/DataStructure/Metadata/{IntVectorMetadataValue.cpp => Int32VectorMetadataValue.cpp} (94%) rename src/simplnx/DataStructure/Metadata/{IntVectorMetadataValue.hpp => Int32VectorMetadataValue.hpp} (89%) delete mode 100644 src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cdc0ce147..21d572b1f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -444,10 +444,10 @@ set(SIMPLNX_HDRS ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/AbstractVectorMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolVectorMetadataValue.hpp - ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleMetadataValue.hpp - ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleVectorMetadataValue.hpp - ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntMetadataValue.hpp - ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntVectorMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/Float64MetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/Float64VectorMetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/Int32MetadataValue.hpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/Int32VectorMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/MetaDataList.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringMetadataValue.hpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringVectorMetadataValue.hpp @@ -701,10 +701,10 @@ set(SIMPLNX_SRCS ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BaseMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/BoolVectorMetadataValue.cpp - ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleMetadataValue.cpp - ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/DoubleVectorMetadataValue.cpp - ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntMetadataValue.cpp - ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/IntVectorMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/Float64MetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/Float64VectorMetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/Int32MetadataValue.cpp + ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/Int32VectorMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/MetaDataList.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringMetadataValue.cpp ${SIMPLNX_SOURCE_DIR}/DataStructure/Metadata/StringVectorMetadataValue.cpp diff --git a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp deleted file mode 100644 index e717df81a6..0000000000 --- a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "DoubleMetadataValue.hpp" - -#include "nlohmann/json.hpp" - -namespace nx::core -{ -DoubleMetadataValue::DoubleMetadataValue(ValueType value) -: ParentType() -, m_Value(value) -{ -} - -DoubleMetadataValue::operator ValueType() const -{ - return m_Value; -} - -DoubleMetadataValue::ValueType DoubleMetadataValue::getValue() const -{ - return m_Value; -} - -void DoubleMetadataValue::setValue(const ValueType& value) -{ - m_Value = value; -} - -bool DoubleMetadataValue::operator==(const ValueType& rhs) const -{ - return m_Value == rhs; -} - -DoubleMetadataValue::ParentType& DoubleMetadataValue::operator=(const ValueType& rhs) -{ - m_Value = rhs; - return *this; -} - -std::string DoubleMetadataValue::getTypeNameImpl() const -{ - return k_TypeName; -} - -nlohmann::json DoubleMetadataValue::toJsonImpl() const -{ - nlohmann::json json; - json[k_ValueTypeKey.str()] = k_TypeName; - json[k_ValueKey.str()] = m_Value; - return json; -} - -void DoubleMetadataValue::fromJsonImpl(const nlohmann::json& json) -{ - m_Value = json[k_ValueKey.str()].get(); -} -} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.cpp deleted file mode 100644 index 92dcd3ac7b..0000000000 --- a/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "DoubleVectorMetadataValue.hpp" - -namespace nx::core -{ -DoubleVectorMetadataValue::DoubleVectorMetadataValue() -: ParentType() -{ -} - -DoubleVectorMetadataValue::DoubleVectorMetadataValue(const DoubleVectorMetadataValue& rhs) -: ParentType(rhs) -{ -} -DoubleVectorMetadataValue::DoubleVectorMetadataValue(DoubleVectorMetadataValue&& rhs) noexcept -: ParentType(rhs) -{ -} - -std::string DoubleVectorMetadataValue::getTypeNameImpl() const -{ - return k_TypeName; -} - -DoubleVectorMetadataValue::AssignmentReturnType& DoubleVectorMetadataValue::operator=(const ValueType& rhs) -{ - return ParentType::operator=(rhs); -} - -bool DoubleVectorMetadataValue::operator==(const ValueType& rhs) const -{ - return ParentType::operator==(rhs); -} -} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp deleted file mode 100644 index 571a040a1b..0000000000 --- a/src/simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "AbstractVectorMetadataValue.hpp" - -namespace nx::core -{ -class SIMPLNX_EXPORT DoubleVectorMetadataValue : public AbstractVectorMetadataValue -{ -public: - using ParentType = AbstractVectorMetadataValue; - using ValueType = ParentType::ValueType; - using AssignmentReturnType = ParentType::AssignmentReturnType; - - static constexpr StringLiteral k_TypeName = "vec"; - - DoubleVectorMetadataValue(); - DoubleVectorMetadataValue(const DoubleVectorMetadataValue& rhs); - DoubleVectorMetadataValue(DoubleVectorMetadataValue&& rhs) noexcept; - ~DoubleVectorMetadataValue() noexcept = default; - - DoubleVectorMetadataValue& operator=(const DoubleVectorMetadataValue& rhs) = default; - DoubleVectorMetadataValue& operator=(DoubleVectorMetadataValue&& rhs) noexcept = default; - - /** - * @brief Assignment operator - * @param rhs - */ - AssignmentReturnType& operator=(const ValueType& rhs) override; - - /** - * @brief Default equality operator - * @param rhs value to compare against - * @return is equal - */ - bool operator==(const ValueType& rhs) const override; - -protected: - std::string getTypeNameImpl() const override; -}; -} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/Float64MetadataValue.cpp b/src/simplnx/DataStructure/Metadata/Float64MetadataValue.cpp new file mode 100644 index 0000000000..3991be7f8b --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/Float64MetadataValue.cpp @@ -0,0 +1,56 @@ +#include "Float64MetadataValue.hpp" + +#include "nlohmann/json.hpp" + +namespace nx::core +{ +Float64MetadataValue::Float64MetadataValue(ValueType value) +: ParentType() +, m_Value(value) +{ +} + +Float64MetadataValue::operator ValueType() const +{ + return m_Value; +} + +Float64MetadataValue::ValueType Float64MetadataValue::getValue() const +{ + return m_Value; +} + +void Float64MetadataValue::setValue(const ValueType& value) +{ + m_Value = value; +} + +bool Float64MetadataValue::operator==(const ValueType& rhs) const +{ + return m_Value == rhs; +} + +Float64MetadataValue::ParentType& Float64MetadataValue::operator=(const ValueType& rhs) +{ + m_Value = rhs; + return *this; +} + +std::string Float64MetadataValue::getTypeNameImpl() const +{ + return k_TypeName; +} + +nlohmann::json Float64MetadataValue::toJsonImpl() const +{ + nlohmann::json json; + json[k_ValueTypeKey.str()] = k_TypeName; + json[k_ValueKey.str()] = m_Value; + return json; +} + +void Float64MetadataValue::fromJsonImpl(const nlohmann::json& json) +{ + m_Value = json[k_ValueKey.str()].get(); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/Float64MetadataValue.hpp similarity index 73% rename from src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp rename to src/simplnx/DataStructure/Metadata/Float64MetadataValue.hpp index 75863747ea..9acba1e49e 100644 --- a/src/simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/Float64MetadataValue.hpp @@ -7,18 +7,18 @@ namespace nx::core /** * @brief Metadata class implementation for reading and writing floating-point metadata. */ -class SIMPLNX_EXPORT DoubleMetadataValue : public AbstractMetadataValue +class SIMPLNX_EXPORT Float64MetadataValue : public AbstractMetadataValue { public: using ParentType = AbstractMetadataValue; - using ValueType = ParentType::ValueType; + using ValueType = typename ParentType::ValueType; - static constexpr StringLiteral k_TypeName = "double"; + static constexpr StringLiteral k_TypeName = "float64"; - DoubleMetadataValue(ValueType value = 0.0); - DoubleMetadataValue(const DoubleMetadataValue& other) = default; - DoubleMetadataValue(DoubleMetadataValue&& other) = default; - ~DoubleMetadataValue() = default; + Float64MetadataValue(ValueType value = 0.0); + Float64MetadataValue(const Float64MetadataValue& other) = default; + Float64MetadataValue(Float64MetadataValue&& other) = default; + ~Float64MetadataValue() = default; /** * @brief Default cast to the type in question diff --git a/src/simplnx/DataStructure/Metadata/Float64VectorMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/Float64VectorMetadataValue.cpp new file mode 100644 index 0000000000..fd1c05a04d --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/Float64VectorMetadataValue.cpp @@ -0,0 +1,33 @@ +#include "Float64VectorMetadataValue.hpp" + +namespace nx::core +{ +Float64VectorMetadataValue::Float64VectorMetadataValue() +: ParentType() +{ +} + +Float64VectorMetadataValue::Float64VectorMetadataValue(const Float64VectorMetadataValue& rhs) +: ParentType(rhs) +{ +} +Float64VectorMetadataValue::Float64VectorMetadataValue(Float64VectorMetadataValue&& rhs) noexcept +: ParentType(rhs) +{ +} + +std::string Float64VectorMetadataValue::getTypeNameImpl() const +{ + return k_TypeName; +} + +Float64VectorMetadataValue::AssignmentReturnType& Float64VectorMetadataValue::operator=(const ValueType& rhs) +{ + return ParentType::operator=(rhs); +} + +bool Float64VectorMetadataValue::operator==(const ValueType& rhs) const +{ + return ParentType::operator==(rhs); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/Float64VectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/Float64VectorMetadataValue.hpp new file mode 100644 index 0000000000..06a3abdb93 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/Float64VectorMetadataValue.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "AbstractVectorMetadataValue.hpp" + +namespace nx::core +{ +class SIMPLNX_EXPORT Float64VectorMetadataValue : public AbstractVectorMetadataValue +{ +public: + using ParentType = AbstractVectorMetadataValue; + using ValueType = typename ParentType::ValueType; + using AssignmentReturnType = typename ParentType::AssignmentReturnType; + + static constexpr StringLiteral k_TypeName = "vec"; + + Float64VectorMetadataValue(); + Float64VectorMetadataValue(const Float64VectorMetadataValue& rhs); + Float64VectorMetadataValue(Float64VectorMetadataValue&& rhs) noexcept; + ~Float64VectorMetadataValue() noexcept = default; + + Float64VectorMetadataValue& operator=(const Float64VectorMetadataValue& rhs) = default; + Float64VectorMetadataValue& operator=(Float64VectorMetadataValue&& rhs) noexcept = default; + + /** + * @brief Assignment operator + * @param rhs + */ + AssignmentReturnType& operator=(const ValueType& rhs) override; + + /** + * @brief Default equality operator + * @param rhs value to compare against + * @return is equal + */ + bool operator==(const ValueType& rhs) const override; + +protected: + std::string getTypeNameImpl() const override; +}; +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/Int32MetadataValue.cpp b/src/simplnx/DataStructure/Metadata/Int32MetadataValue.cpp new file mode 100644 index 0000000000..58bb5d4eb8 --- /dev/null +++ b/src/simplnx/DataStructure/Metadata/Int32MetadataValue.cpp @@ -0,0 +1,56 @@ +#include "Int32MetadataValue.hpp" + +#include "nlohmann/json.hpp" + +namespace nx::core +{ +Int32MetadataValue::Int32MetadataValue(int32 value) +: AbstractMetadataValue() +, m_Value(value) +{ +} + +Int32MetadataValue::operator int32() const +{ + return m_Value; +} + +Int32MetadataValue::ValueType Int32MetadataValue::getValue() const +{ + return m_Value; +} + +void Int32MetadataValue::setValue(const ValueType& value) +{ + m_Value = value; +} + +bool Int32MetadataValue::operator==(const ValueType& rhs) const +{ + return m_Value == rhs; +} + +Int32MetadataValue::ParentType& Int32MetadataValue::operator=(const int32& rhs) +{ + m_Value = rhs; + return *this; +} + +std::string Int32MetadataValue::getTypeNameImpl() const +{ + return k_TypeName; +} + +nlohmann::json Int32MetadataValue::toJsonImpl() const +{ + nlohmann::json json; + json[k_ValueTypeKey.str()] = k_TypeName; + json[k_ValueKey.str()] = m_Value; + return json; +} + +void Int32MetadataValue::fromJsonImpl(const nlohmann::json& json) +{ + m_Value = json[k_ValueKey.str()].get(); +} +} // namespace nx::core diff --git a/src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/Int32MetadataValue.hpp similarity index 73% rename from src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp rename to src/simplnx/DataStructure/Metadata/Int32MetadataValue.hpp index 5e50fac9a6..7ef21e7555 100644 --- a/src/simplnx/DataStructure/Metadata/IntMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/Int32MetadataValue.hpp @@ -7,18 +7,18 @@ namespace nx::core /** * @brief Metadata class implementation for reading and writing integer metadata. */ -class SIMPLNX_EXPORT IntMetadataValue : public AbstractMetadataValue +class SIMPLNX_EXPORT Int32MetadataValue : public AbstractMetadataValue { public: - using ParentType = AbstractMetadataValue; - using ValueType = ParentType::ValueType; + using ParentType = typename AbstractMetadataValue; + using ValueType = typename ParentType::ValueType; static constexpr StringLiteral k_TypeName = "int32"; - IntMetadataValue(ValueType value = 0); - IntMetadataValue(const IntMetadataValue& other) = default; - IntMetadataValue(IntMetadataValue&& other) = default; - ~IntMetadataValue() = default; + Int32MetadataValue(ValueType value = 0); + Int32MetadataValue(const Int32MetadataValue& other) = default; + Int32MetadataValue(Int32MetadataValue&& other) = default; + ~Int32MetadataValue() = default; /** * @brief Default cast to the type in question diff --git a/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/Int32VectorMetadataValue.cpp similarity index 94% rename from src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.cpp rename to src/simplnx/DataStructure/Metadata/Int32VectorMetadataValue.cpp index bd68701c03..0fe259da5d 100644 --- a/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.cpp +++ b/src/simplnx/DataStructure/Metadata/Int32VectorMetadataValue.cpp @@ -1,4 +1,4 @@ -#include "IntVectorMetadataValue.hpp" +#include "Int32VectorMetadataValue.hpp" namespace nx::core { diff --git a/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/Int32VectorMetadataValue.hpp similarity index 89% rename from src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp rename to src/simplnx/DataStructure/Metadata/Int32VectorMetadataValue.hpp index 231507948f..ed177874cb 100644 --- a/src/simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/Int32VectorMetadataValue.hpp @@ -8,8 +8,8 @@ class SIMPLNX_EXPORT Int32VectorMetadataValue : public AbstractVectorMetadataVal { public: using ParentType = AbstractVectorMetadataValue; - using ValueType = ParentType::ValueType; - using AssignmentReturnType = ParentType::AssignmentReturnType; + using ValueType = typename ParentType::ValueType; + using AssignmentReturnType = typename ParentType::AssignmentReturnType; static constexpr StringLiteral k_TypeName = "vec"; diff --git a/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp b/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp deleted file mode 100644 index aa5e7187b9..0000000000 --- a/src/simplnx/DataStructure/Metadata/IntMetadataValue.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "IntMetadataValue.hpp" - -#include "nlohmann/json.hpp" - -namespace nx::core -{ -IntMetadataValue::IntMetadataValue(int32 value) -: AbstractMetadataValue() -, m_Value(value) -{ -} - -IntMetadataValue::operator int32() const -{ - return m_Value; -} - -IntMetadataValue::ValueType IntMetadataValue::getValue() const -{ - return m_Value; -} - -void IntMetadataValue::setValue(const ValueType& value) -{ - m_Value = value; -} - -bool IntMetadataValue::operator==(const ValueType& rhs) const -{ - return m_Value == rhs; -} - -IntMetadataValue::ParentType& IntMetadataValue::operator=(const int32& rhs) -{ - m_Value = rhs; - return *this; -} - -std::string IntMetadataValue::getTypeNameImpl() const -{ - return k_TypeName; -} - -nlohmann::json IntMetadataValue::toJsonImpl() const -{ - nlohmann::json json; - json[k_ValueTypeKey.str()] = k_TypeName; - json[k_ValueKey.str()] = m_Value; - return json; -} - -void IntMetadataValue::fromJsonImpl(const nlohmann::json& json) -{ - m_Value = json[k_ValueKey.str()].get(); -} -} // namespace nx::core From 0c68140a2e15f6e44ade10e63561e8d3adb028f6 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Fri, 29 May 2026 08:12:37 -0400 Subject: [PATCH 11/16] Fix PR issues * Fixed Linux build errors. * Fixed rebase errors * Clang-format files --- .../Filters/Algorithms/WriteDREAM3D.cpp | 67 +------------------ .../SimplnxCore/test/DREAM3DFileTest.cpp | 30 ++++----- .../Metadata/AbstractMetadataValue.hpp | 2 +- .../Metadata/AbstractVectorMetadataValue.hpp | 8 +-- .../Metadata/BoolMetadataValue.hpp | 2 +- .../Metadata/BoolVectorMetadataValue.hpp | 4 +- .../DataStructure/Metadata/MetaDataList.cpp | 20 +++--- .../Metadata/StringMetadataValue.hpp | 2 +- .../Metadata/StringVectorMetadataValue.hpp | 4 +- 9 files changed, 39 insertions(+), 100 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp index cf5269c972..dd361d3943 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp @@ -84,67 +84,7 @@ Result<> WriteDREAM3DFile(AtomicFile& atomicFile, const DataStructure& dataStruc fs::path xdmfFilePath = exportFilePath.replace_extension(".xdmf"); std::error_code errorCode; fs::rename(xdmfFilePath, fs::path(exportFilePath).replace_extension(".xdmf"), errorCode); - - // If the XDMF file failed to be renamed, return an invalid Result - if(errorCode) - { - std::string ss = fmt::format("Failed to rename xdmf file with error: '{}'", errorCode.message()); - return MakeErrorResult(errorCode.value(), ss); - } - } - - return {}; -} - -// ----------------------------------------------------------------------------- -Result<> WriteDREAM3D::operator()() -{ - Pipeline pipeline; - if(pipelineNode != nullptr) - { - auto pipelinePtr = pipelineNode->getPrecedingPipeline(); - if(pipelinePtr == nullptr) - { - return MakeErrorResult(k_FailedFindPipelineError, "Failed to retrieve pipeline."); - } - pipeline = *pipelinePtr; - } - return {pipeline}; -} - -/** - * @brief Writes the DREAM3D file to the temp file, commits changes, and then writes the XDMF file if requested. - * @param atomicFile Temp file for writing the DREAM3D file - * @param dataStructure DataStructure to be written to file. - * @param pipeline Pipeline to write to file. - * @param writeXdmfFile - * @return Result<> - */ -Result<> WriteDREAM3DFile(AtomicFile& atomicFile, const DataStructure& dataStructure, const Pipeline& pipeline, bool writeXdmfFile) -{ - auto exportFilePath = atomicFile.tempFilePath(); - - auto results = DREAM3D::WriteFile(exportFilePath, dataStructure, pipeline, writeXdmfFile); - if(results.invalid()) - { - return results; - } - - // Commit changes to the temp file. Return an invalid Result if errors occured. - if(auto commitResult = atomicFile.commit(); commitResult.invalid()) - { - return commitResult; - } - - // Write the XDMF file if specified - if(writeXdmfFile) - { - // TODO: Double check this - fs::path xdmfFilePath = exportFilePath.replace_extension(".xdmf"); - std::error_code errorCode; - fs::rename(xdmfFilePath, fs::path(exportFilePath).replace_extension(".xdmf"), errorCode); - // If the XDMF file failed to be renamed, return an invalid Result if(errorCode) { @@ -167,10 +107,9 @@ Result<> WriteDREAM3D::operator()() } AtomicFile atomicFile = std::move(atomicFileResult.value()); - nx::core::HDF5::DataStructureWriter::WriteOptions writeOptions; - writeOptions.compressionLevel = m_InputValues->UseCompression ? m_InputValues->CompressionLevel : 0; - auto results = DREAM3D::WriteFile(exportFilePath, m_DataStructure, pipeline, writeXdmf, writeOptions); - if(results.valid()) + // Extract Preceding Pipeline + Pipeline pipeline; + if(auto result = ExtractPipeline(m_InputValues->PipelineNode); result.invalid()) { return ConvertResult(std::move(result)); } diff --git a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp index efaa6ad8ee..0adbe85986 100644 --- a/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp +++ b/src/Plugins/SimplnxCore/test/DREAM3DFileTest.cpp @@ -12,10 +12,10 @@ #include "simplnx/DataStructure/DataStructure.hpp" #include "simplnx/DataStructure/Metadata/BoolMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp" -#include "simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp" -#include "simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp" -#include "simplnx/DataStructure/Metadata/IntMetadataValue.hpp" -#include "simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/Float64MetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/Float64VectorMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/Int32MetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/Int32VectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/StringMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp" #include "simplnx/Filter/Arguments.hpp" @@ -400,7 +400,7 @@ void CompareNeighborLists(const DataObject* object1, const DataObject* object2) const auto* array2 = dynamic_cast*>(object2); const auto numLists = array1->getNumberOfLists(); - for (usize i = 0; i < numLists; i++) + for(usize i = 0; i < numLists; i++) { REQUIRE(array1->getList(i) == array2->getList(i)); } @@ -415,7 +415,7 @@ void CompareINeighborLists(const DataObject* object1, const DataObject* object2) REQUIRE(array2 != nullptr); REQUIRE(array1->getDataType() == array2->getDataType()); - switch (array1->getDataType()) + switch(array1->getDataType()) { case DataType::int8: CompareNeighborLists(object1, object2); @@ -1395,12 +1395,12 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM metadata.setData(boolVecDataName, boolVecValue); // Int metadata - metadata.setData(intDataName, intValue); + metadata.setData(intDataName, intValue); metadata.setData(intVecDataName, intVecValue); // Double metadata - metadata.setData(doubleDataName, doubleValue); - metadata.setData(doubleVecDataName, doubleVecValue); + metadata.setData(doubleDataName, doubleValue); + metadata.setData(doubleVecDataName, doubleVecValue); // String metadata metadata.setData(stringDataName, stringValue); @@ -1450,20 +1450,20 @@ TEST_CASE("SimplnxCore::WriteDREAM3DFilter: MetaData", "[SimplnxCore][WriteDREAM // Require metadata preserves typename REQUIRE(boolDataReadPtr->getTypeName() == BoolMetadataValue::k_TypeName); REQUIRE(boolVecDataReadPtr->getTypeName() == BoolVectorMetadataValue::k_TypeName); - REQUIRE(intDataReadPtr->getTypeName() == IntMetadataValue::k_TypeName); + REQUIRE(intDataReadPtr->getTypeName() == Int32MetadataValue::k_TypeName); REQUIRE(intVecDataReadPtr->getTypeName() == Int32VectorMetadataValue::k_TypeName); - REQUIRE(doubleDataReadPtr->getTypeName() == DoubleMetadataValue::k_TypeName); - REQUIRE(doubleVecDataReadPtr->getTypeName() == DoubleVectorMetadataValue::k_TypeName); + REQUIRE(doubleDataReadPtr->getTypeName() == Float64MetadataValue::k_TypeName); + REQUIRE(doubleVecDataReadPtr->getTypeName() == Float64VectorMetadataValue::k_TypeName); REQUIRE(stringDataReadPtr->getTypeName() == StringMetadataValue::k_TypeName); REQUIRE(stringVecDataReadPtr->getTypeName() == StringVectorMetadataValue::k_TypeName); // Require metadata preserves values auto& boolDataReadRef = *metaDataRead.getDataValuePtrAs(boolDataName).get(); auto& boolVecDataReadRef = *metaDataRead.getDataValuePtrAs(boolVecDataName).get(); - auto& intDataReadRef = *metaDataRead.getDataValuePtrAs(intDataName).get(); + auto& intDataReadRef = *metaDataRead.getDataValuePtrAs(intDataName).get(); auto& intVecDataReadRef = *metaDataRead.getDataValuePtrAs(intVecDataName).get(); - auto& doubleDataReadRef = *metaDataRead.getDataValuePtrAs(doubleDataName).get(); - auto& doubleVecDataReadRef = *metaDataRead.getDataValuePtrAs(doubleVecDataName).get(); + auto& doubleDataReadRef = *metaDataRead.getDataValuePtrAs(doubleDataName).get(); + auto& doubleVecDataReadRef = *metaDataRead.getDataValuePtrAs(doubleVecDataName).get(); auto& stringDataReadRef = *metaDataRead.getDataValuePtrAs(stringDataName).get(); auto& stringVecDataReadRef = *metaDataRead.getDataValuePtrAs(stringVecDataName).get(); diff --git a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp index cb819f5b90..e205166c84 100644 --- a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp @@ -81,7 +81,7 @@ class AbstractMetadataValue : public BaseMetadataValue protected: AbstractMetadataValue() = default; - + virtual std::string getTypeNameImpl() const = 0; /** diff --git a/src/simplnx/DataStructure/Metadata/AbstractVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/AbstractVectorMetadataValue.hpp index a08e19369d..2f8bc0896e 100644 --- a/src/simplnx/DataStructure/Metadata/AbstractVectorMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/AbstractVectorMetadataValue.hpp @@ -8,9 +8,9 @@ template class AbstractVectorMetadataValue : public AbstractMetadataValue> { public: - using ParentType = AbstractMetadataValue>; - using ValueType = ParentType::ValueType; - using AssignmentReturnType = ParentType; + using ParentType = typename AbstractMetadataValue>; + using ValueType = typename ParentType::ValueType; + using AssignmentReturnType = typename ParentType; AbstractVectorMetadataValue(const AbstractVectorMetadataValue& other) : ParentType(other) @@ -85,7 +85,7 @@ class AbstractVectorMetadataValue : public AbstractMetadataValue> } AbstractVectorMetadataValue& operator=(AbstractVectorMetadataValue&& rhs) noexcept { - m_Value = std::move(rhs.m_Value); + m_Value = std::move(rhs.m_Value); return *this; } diff --git a/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp index bb80200f3d..9d5f482349 100644 --- a/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/BoolMetadataValue.hpp @@ -11,7 +11,7 @@ class SIMPLNX_EXPORT BoolMetadataValue : public AbstractMetadataValue { public: using ParentType = AbstractMetadataValue; - using ValueType = ParentType::ValueType; + using ValueType = typename ParentType::ValueType; static constexpr StringLiteral k_TypeName = "bool"; diff --git a/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp index 3ed5a4e9c9..55d4c85584 100644 --- a/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp @@ -8,8 +8,8 @@ class SIMPLNX_EXPORT BoolVectorMetadataValue : public AbstractVectorMetadataValu { public: using ParentType = AbstractVectorMetadataValue; - using ValueType = ParentType::ValueType; - using AssignmentReturnType = ParentType::AssignmentReturnType; + using ValueType = typename ParentType::ValueType; + using AssignmentReturnType = typename ParentType::AssignmentReturnType; static constexpr StringLiteral k_TypeName = "vec"; diff --git a/src/simplnx/DataStructure/Metadata/MetaDataList.cpp b/src/simplnx/DataStructure/Metadata/MetaDataList.cpp index 3c90f2cef1..39e4549acc 100644 --- a/src/simplnx/DataStructure/Metadata/MetaDataList.cpp +++ b/src/simplnx/DataStructure/Metadata/MetaDataList.cpp @@ -2,10 +2,10 @@ #include "simplnx/DataStructure/Metadata/BoolMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/BoolVectorMetadataValue.hpp" -#include "simplnx/DataStructure/Metadata/DoubleMetadataValue.hpp" -#include "simplnx/DataStructure/Metadata/DoubleVectorMetadataValue.hpp" -#include "simplnx/DataStructure/Metadata/IntMetadataValue.hpp" -#include "simplnx/DataStructure/Metadata/IntVectorMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/Float64MetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/Float64VectorMetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/Int32MetadataValue.hpp" +#include "simplnx/DataStructure/Metadata/Int32VectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/StringMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp" #include "simplnx/DataStructure/Metadata/UnknownMetadataValue.hpp" @@ -34,20 +34,20 @@ void MetaDataList::addDefaultTypes() return metaData; }); // Double Metadata - addMetaDataType(DoubleMetadataValue::k_TypeName, [](const nlohmann::json& json) { - auto metaData = std::make_unique(); + addMetaDataType(Float64MetadataValue::k_TypeName, [](const nlohmann::json& json) { + auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; }); // Double Vector Metadata - addMetaDataType(DoubleVectorMetadataValue::k_TypeName, [](const nlohmann::json& json) { - auto metaData = std::make_unique(); + addMetaDataType(Float64VectorMetadataValue::k_TypeName, [](const nlohmann::json& json) { + auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; }); // Integer Metadata - addMetaDataType(IntMetadataValue::k_TypeName, [](const nlohmann::json& json) { - auto metaData = std::make_unique(); + addMetaDataType(Int32MetadataValue::k_TypeName, [](const nlohmann::json& json) { + auto metaData = std::make_unique(); metaData->fromJson(json); return metaData; }); diff --git a/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp index 9572a0bf7f..e89241db7a 100644 --- a/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/StringMetadataValue.hpp @@ -15,7 +15,7 @@ class SIMPLNX_EXPORT StringMetadataValue : public AbstractMetadataValue; - using ValueType = ParentType::ValueType; + using ValueType = typename ParentType::ValueType; static constexpr StringLiteral k_TypeName = "string"; diff --git a/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp index add86b2d82..0bd341c074 100644 --- a/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/StringVectorMetadataValue.hpp @@ -8,8 +8,8 @@ class SIMPLNX_EXPORT StringVectorMetadataValue : public AbstractVectorMetadataVa { public: using ParentType = AbstractVectorMetadataValue; - using ValueType = ParentType::ValueType; - using AssignmentReturnType = ParentType::AssignmentReturnType; + using ValueType = typename ParentType::ValueType; + using AssignmentReturnType = typename ParentType::AssignmentReturnType; static constexpr StringLiteral k_TypeName = "vec"; From 8b1cc39e809a853443e01d9deebbb6fff822b7c9 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Fri, 29 May 2026 08:26:55 -0400 Subject: [PATCH 12/16] Clang-format filter --- .../SimplnxCore/src/SimplnxCore/Filters/WriteDREAM3DFilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteDREAM3DFilter.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteDREAM3DFilter.cpp index 3add11fc5d..16b4515fe4 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteDREAM3DFilter.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/WriteDREAM3DFilter.cpp @@ -2,11 +2,11 @@ #include "SimplnxCore/Filters/Algorithms/WriteDREAM3D.hpp" +#include "SimplnxCore/Filters/Algorithms/WriteDREAM3D.hpp" #include "simplnx/Parameters/BoolParameter.hpp" #include "simplnx/Parameters/FileSystemPathParameter.hpp" #include "simplnx/Parameters/NumberParameter.hpp" #include "simplnx/Utilities/SIMPLConversion.hpp" -#include "SimplnxCore/Filters/Algorithms/WriteDREAM3D.hpp" #include From 4a243b924ab25883696b3e8b1b3d9cd11b11a8fa Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Fri, 29 May 2026 08:36:55 -0400 Subject: [PATCH 13/16] Fix Linux compile errors * Add missing typename to Metadata type alias --- src/simplnx/DataStructure/Metadata.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simplnx/DataStructure/Metadata.hpp b/src/simplnx/DataStructure/Metadata.hpp index c7de49a525..5f3221b149 100644 --- a/src/simplnx/DataStructure/Metadata.hpp +++ b/src/simplnx/DataStructure/Metadata.hpp @@ -29,7 +29,7 @@ class SIMPLNX_EXPORT Metadata using KeyType = std::string; using ValueType = BaseMetadataValue; using ValuePtr = std::shared_ptr; - using Iterator = std::map::iterator; + using Iterator = typename std::map::iterator; using ConstIterator = std::map::const_iterator; /** @@ -122,7 +122,7 @@ class SIMPLNX_EXPORT Metadata * @param value Value to store */ template - void setData(const KeyType& key, const T::ValueType& value) + void setData(const KeyType& key, const typename T::ValueType& value) { auto dataPtr = std::make_shared(); *dataPtr.get() = value; From 96fe5096ec3d0db6d7097a66cc4d0e97be455e1c Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Fri, 29 May 2026 08:42:33 -0400 Subject: [PATCH 14/16] Fix missing WriteOptions in WriteDREAM3D operator --- .../src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp index dd361d3943..f9fa5067b1 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp @@ -61,11 +61,11 @@ Result ExtractPipeline(const PipelineFilter* pipelineNode) * @param writeXdmfFile * @return Result<> */ -Result<> WriteDREAM3DFile(AtomicFile& atomicFile, const DataStructure& dataStructure, const Pipeline& pipeline, bool writeXdmfFile) +Result<> WriteDREAM3DFile(AtomicFile& atomicFile, const DataStructure& dataStructure, const Pipeline& pipeline, bool writeXdmfFile, const nx::core::HDF5::DataStructureWriter::WriteOptions& writeOptions) { auto exportFilePath = atomicFile.tempFilePath(); - auto results = DREAM3D::WriteFile(exportFilePath, dataStructure, pipeline, writeXdmfFile); + auto results = DREAM3D::WriteFile(exportFilePath, dataStructure, pipeline, writeXdmfFile, writeOptions); if(results.invalid()) { return results; @@ -119,5 +119,7 @@ Result<> WriteDREAM3D::operator()() } // Write DREAM.3D file - return WriteDREAM3DFile(atomicFile, m_DataStructure, pipeline, m_InputValues->WriteXdmfFile); + nx::core::HDF5::DataStructureWriter::WriteOptions writeOptions; + writeOptions.compressionLevel = m_InputValues->UseCompression ? m_InputValues->CompressionLevel : 0; + return WriteDREAM3DFile(atomicFile, m_DataStructure, pipeline, m_InputValues->WriteXdmfFile, writeOptions); } From a27a204d6738547d2f31242c26019105c5fcecb0 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Fri, 29 May 2026 08:44:14 -0400 Subject: [PATCH 15/16] Clang-format --- .../src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp index f9fa5067b1..9e6e4c655b 100644 --- a/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp +++ b/src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/WriteDREAM3D.cpp @@ -61,7 +61,8 @@ Result ExtractPipeline(const PipelineFilter* pipelineNode) * @param writeXdmfFile * @return Result<> */ -Result<> WriteDREAM3DFile(AtomicFile& atomicFile, const DataStructure& dataStructure, const Pipeline& pipeline, bool writeXdmfFile, const nx::core::HDF5::DataStructureWriter::WriteOptions& writeOptions) +Result<> WriteDREAM3DFile(AtomicFile& atomicFile, const DataStructure& dataStructure, const Pipeline& pipeline, bool writeXdmfFile, + const nx::core::HDF5::DataStructureWriter::WriteOptions& writeOptions) { auto exportFilePath = atomicFile.tempFilePath(); From f8290db44d5e38727ee0b7ef836ee7272cd0bd60 Mon Sep 17 00:00:00 2001 From: Matthew Marine Date: Fri, 29 May 2026 13:24:46 -0400 Subject: [PATCH 16/16] Fix Linux compile error * Add missing override --- src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp index e205166c84..7ab108808c 100644 --- a/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp +++ b/src/simplnx/DataStructure/Metadata/AbstractMetadataValue.hpp @@ -56,7 +56,7 @@ class AbstractMetadataValue : public BaseMetadataValue */ virtual bool operator==(const ValueType& rhs) const = 0; - std::string getTypeName() const + std::string getTypeName() const override { return getTypeNameImpl(); }