diff --git a/conandata.yml b/conandata.yml index a30e8f2..0644c1a 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1 +1 @@ -version: "5.10.0" +version: "5.11.0-alpha.0" diff --git a/include/Savitar/SceneNode.h b/include/Savitar/SceneNode.h index 9f8f19c..15b0e47 100644 --- a/include/Savitar/SceneNode.h +++ b/include/Savitar/SceneNode.h @@ -36,6 +36,11 @@ class SceneNode */ void fillByXMLNode(pugi::xml_node xml_node); + /** + * Parses the (mesh) data stored in the external component file + */ + void parseComponentData(const std::string& xml_string); + /** * Get the (unique) identifier of the node. */ @@ -69,6 +74,8 @@ class SceneNode [[nodiscard]] SceneNode* getMeshNode(); + [[nodiscard]] std::string getComponentPath() const; + private: std::string transformation_{ "1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0" }; std::vector children_; @@ -77,6 +84,7 @@ class SceneNode std::string id_; std::string name_; std::string type_{ "model" }; + std::string component_path_; // 3MF does not support having an Object that has a mesh and components. // This is solved by the concept of the "mesh" node, which is added as a child. diff --git a/src/SceneNode.cpp b/src/SceneNode.cpp index 99f396d..a4c04ce 100644 --- a/src/SceneNode.cpp +++ b/src/SceneNode.cpp @@ -23,6 +23,11 @@ SceneNode* SceneNode::getMeshNode() return mesh_node_; } +std::string SceneNode::getComponentPath() const +{ + return component_path_; +} + std::vector SceneNode::getChildren() { return children_; @@ -125,6 +130,45 @@ void SceneNode::fillByXMLNode(pugi::xml_node xml_node) setSetting(key, value, type, preserve); } } + + // Read components + const pugi::xml_node components_node = xml_node.child("components"); + if (components_node != nullptr) + { + for (pugi::xml_node component = components_node.child("component"); component != nullptr; component = component.next_sibling("component")) + { + std::string path = component.attribute("p:path").as_string(); + if (! path.empty()) + { + component_path_ = path; + } + + std::string transformation = component.attribute("transform").as_string(); + if (! transformation.empty()) + { + transformation_ = transformation; + } + } + } +} + +void SceneNode::parseComponentData(const std::string& xml_string) +{ + pugi::xml_document document; + document.load_string(xml_string.c_str()); + + pugi::xml_node xml_node = document; + for (const std::string child_name : {"model", "resources", "object", "mesh"}) + { + xml_node = xml_node.child(child_name.c_str()); + if (xml_node == nullptr) + { + return; + } + } + + mesh_data_.clear(); + mesh_data_.fillByXMLNode(xml_node); } std::string SceneNode::getId()