1 /*
2  * This file is part of libSavitar
3  *
4  * Copyright (C) 2017 Ultimaker b.v. <j.vankessel@ultimaker.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "ThreeMFParser.h"
20 #include "Namespace.h"
21 #include "Scene.h"
22 #include <iostream>
23 #include <sstream>
24 #include <locale.h>
25 
26 using namespace Savitar;
27 
ThreeMFParser()28 ThreeMFParser::ThreeMFParser()
29 {
30     setlocale(LC_ALL, "C");
31 }
32 
~ThreeMFParser()33 ThreeMFParser::~ThreeMFParser()
34 {
35 
36 }
37 
parse(std::string xml_string)38 Scene ThreeMFParser::parse(std::string xml_string)
39 {
40     pugi::xml_document document;
41     pugi::xml_parse_result result = document.load_string(xml_string.c_str());
42 
43     Scene scene;
44 
45     scene.fillByXMLNode(document.child("model"));
46 
47 
48     return scene;
49 }
50 
sceneToString(Scene scene)51 std::string ThreeMFParser::sceneToString(Scene scene)
52 {
53     pugi::xml_document document;
54     pugi::xml_node model_node = document.append_child("model");
55     pugi::xml_node resources_node = model_node.append_child("resources");
56     pugi::xml_node build_node = model_node.append_child("build");
57 
58     model_node.append_attribute("unit") = scene.getUnit().c_str();
59     model_node.append_attribute("xmlns") = xml_namespace::getCuraUri().c_str();
60     model_node.append_attribute("xmlns:cura") = xml_namespace::getDefaultUri().c_str();
61     model_node.append_attribute("xml:lang") ="en-US";
62 
63     for(int i = 0; i < scene.getAllSceneNodes().size(); i++)
64     {
65         SceneNode* scene_node = scene.getAllSceneNodes().at(i);
66         scene_node->setId(std::to_string(i + 1));
67     }
68 
69     for(SceneNode* scene_node: scene.getAllSceneNodes())
70     {
71         // Create item
72         pugi::xml_node object = resources_node.append_child("object");
73         object.append_attribute("id") = scene_node->getId().c_str();
74         object.append_attribute("type") = "model";
75 
76         if(scene_node->getMeshData().getVertices().size() != 0)
77         {
78             pugi::xml_node mesh = object.append_child("mesh");
79             scene_node->getMeshData().toXmlNode(mesh);
80         }
81 
82         std::map<std::string, std::string> per_object_settings = scene_node->getSettings();
83         if(!per_object_settings.empty())
84         {
85             pugi::xml_node settings = object.append_child("metadatagroup");
86             for(const std::pair<std::string, std::string> setting_pair: per_object_settings)
87             {
88                 pugi::xml_node setting = settings.append_child("metadata");
89                 setting.append_attribute("name") = (std::string("cura:") + setting_pair.first).c_str();
90                 setting.text().set(setting_pair.second.c_str());
91                 setting.append_attribute("preserve") = "true";
92                 setting.append_attribute("type") = "xs:string";
93             }
94         }
95 
96         if(scene_node->getChildren().size() != 0)
97         {
98             pugi::xml_node components = object.append_child("components");
99             for(SceneNode* child_scene_node: scene_node->getChildren())
100             {
101                 pugi::xml_node component = components.append_child("component");
102                 component.append_attribute("objectid") = child_scene_node->getId().c_str();
103                 component.append_attribute("transform") = child_scene_node->getTransformation().c_str();
104             }
105         }
106     }
107 
108     for(SceneNode* scene_node: scene.getSceneNodes())
109     {
110         pugi::xml_node item = build_node.append_child("item");
111         item.append_attribute("objectid") = scene_node->getId().c_str();
112         item.append_attribute("transform") = scene_node->getTransformation().c_str();
113     }
114 
115     std::stringstream ss;
116     document.save(ss);
117     return ss.str();
118 }
119