70 tinyxml2::XMLDocument doc;
75 tinyxml2::XMLElement* root = doc.NewElement(
"SceneGraph");
77 root->SetAttribute(
"LowerBound",
encodeVec3f(scn->getLowerBound()).c_str());
78 root->SetAttribute(
"UpperBound",
encodeVec3f(scn->getUpperBound()).c_str());
80 doc.InsertEndChild(root);
84 std::map<ObjectId, uint> indices;
86 for (; itor != scn->end(); itor++) {
87 auto node = itor.
get();
88 indices[node->objectId()] = radix;
92 for (itor = scn->begin(); itor != scn->end(); itor++)
94 auto node = itor.
get();
96 tinyxml2::XMLElement* nodeXml = doc.NewElement(
"Node");
97 nodeXml->SetAttribute(
"Class", node->getClassInfo()->getClassName().c_str());
98 nodeXml->SetAttribute(
"Coordinate",
encodeVec2f(
Vec2f(node->bx(), node->by())).c_str());
99 root->InsertEndChild(nodeXml);
101 tinyxml2::XMLElement* varsXml = doc.NewElement(
"Variables");
102 nodeXml->InsertEndChild(varsXml);
105 auto& params = node->getParameters();
106 for (
auto var : params)
108 tinyxml2::XMLElement* field = doc.NewElement(
"Field");
109 field->SetAttribute(
"Name", var->getObjectName().c_str());
111 tinyxml2::XMLText* val = doc.NewText(var->serialize().c_str());
112 field->InsertEndChild(val);
114 varsXml->InsertEndChild(field);
118 tinyxml2::XMLElement* nodeConnectionsXml = doc.NewElement(
"Connections");
119 nodeXml->InsertEndChild(nodeConnectionsXml);
121 auto ports = node->getImportNodes();
123 for (
int i = 0; i < ports.size(); i++)
125 auto NodesSrc = ports[i]->getNodes();
126 bool fieldFound =
false;
127 Node* nSrcPar =
nullptr;
128 for (
auto nSrc : NodesSrc)
130 auto nSrcExports = nSrc->getExportNodes();
131 for (
auto x : nSrcExports)
140 if (fieldFound&&nSrcPar!=
nullptr) {
142 tinyxml2::XMLElement* connection = doc.NewElement(
"Connection");
143 connection->SetAttribute(
"SourceId", indices[nSrcPar->
objectId()]);
144 connection->SetAttribute(
"From", 0);
145 connection->SetAttribute(
"TargetId", indices[node->objectId()]);
146 connection->SetAttribute(
"To",
uint(i));
147 nodeConnectionsXml->InsertEndChild(connection);
152 auto fieldInp = node->getInputFields();
154 for (
int i = 0; i < fieldInp.size(); i++)
156 auto fieldSrc = fieldInp[i]->getSource();
157 if (fieldSrc !=
nullptr) {
158 auto parSrc = fieldSrc->parent();
159 if (parSrc !=
nullptr)
161 Node* nodeSrc =
dynamic_cast<Node*
>(parSrc);
164 uint outFieldIndex = 0;
165 bool fieldFound =
false;
167 for(outFieldIndex=0; outFieldIndex< fieldsOut.size(); outFieldIndex++)
169 if (fieldsOut[outFieldIndex] == fieldSrc)
177 tinyxml2::XMLElement* connection = doc.NewElement(
"Connection");
178 connection->SetAttribute(
"SourceId", indices[parSrc->objectId()]);
179 connection->SetAttribute(
"From", 1 +outFieldIndex);
180 connection->SetAttribute(
"TargetId", indices[node->objectId()]);
181 connection->SetAttribute(
"To",
uint(i + ports.size()));
182 nodeConnectionsXml->InsertEndChild(connection);
189 auto& fields = node->getAllFields();
190 std::vector<FBase*> fieldsOut;
191 for (
auto field : fields)
195 fieldsOut.push_back(field);
199 auto fieldSrc = field->getSource();
200 if (fieldSrc !=
nullptr) {
202 auto parSrc = fieldSrc->parent();
203 if (parSrc !=
nullptr)
208 Node* srcNode =
dynamic_cast<Node*
>(parSrc);
209 if (srcNode !=
nullptr)
211 fieldsOut.push_back(field);
220 auto savePipeline = [&](std::shared_ptr<Pipeline> pipeline,
const char* tag) {
221 tinyxml2::XMLElement* pipelineXml = doc.NewElement(tag);
222 nodeXml->InsertEndChild(pipelineXml);
224 std::map<ObjectId, uint> indices;
225 std::map<ObjectId, std::shared_ptr<Module>> moduleMap;
228 auto& activeModules = pipeline->activeModules();
229 for (
auto m : activeModules){
230 tinyxml2::XMLElement* moduleXml = doc.NewElement(
"Module");
231 moduleXml->SetAttribute(
"Class", m->getClassInfo()->getClassName().c_str());
232 moduleXml->SetAttribute(
"Coordinate",
encodeVec2f(
Vec2f(m->bx(), m->by())).c_str());
233 pipelineXml->InsertEndChild(moduleXml);
235 tinyxml2::XMLElement* varsModuleXml = doc.NewElement(
"Variables");
236 moduleXml->InsertEndChild(varsModuleXml);
239 auto& params = m->getParameters();
240 for (
auto var : params)
242 tinyxml2::XMLElement* field = doc.NewElement(
"Field");
243 field->SetAttribute(
"Name", var->getObjectName().c_str());
245 tinyxml2::XMLText* val = doc.NewText(var->serialize().c_str());
246 field->InsertEndChild(val);
248 varsModuleXml->InsertEndChild(field);
251 indices[m->objectId()] = radix;
252 moduleMap[m->objectId()] = m;
256 tinyxml2::XMLElement* moduleConnectionsXml = doc.NewElement(
"Connections");
257 pipelineXml->InsertEndChild(moduleConnectionsXml);
259 for (
auto m : activeModules)
261 auto& fieldIn = m->getInputFields();
262 for (
int i = 0; i < fieldIn.size(); i++)
264 auto fieldSrc = fieldIn[i]->getSource();
265 if (fieldSrc !=
nullptr) {
266 auto parSrc = fieldSrc->parent();
267 if (parSrc !=
nullptr)
275 uint outFieldIndex = 0;
276 bool fieldFound =
false;
277 for (
auto f : srcfieldsOut)
287 if (fieldFound && moduleMap.find(outId) != moduleMap.end())
289 auto outBlock = moduleMap[outId];
291 tinyxml2::XMLElement* moduleConnectionXml = doc.NewElement(
"Connection");
292 moduleConnectionXml->SetAttribute(
"SourceId", indices[outBlock->objectId()]);
293 moduleConnectionXml->SetAttribute(
"From", outFieldIndex);
294 moduleConnectionXml->SetAttribute(
"TargetId", indices[m->objectId()]);
295 moduleConnectionXml->SetAttribute(
"To",
uint(i));
296 moduleConnectionsXml->InsertEndChild(moduleConnectionXml);
300 Node* src =
dynamic_cast<Node*
>(parSrc);
304 uint outFieldIndex = 0;
305 bool fieldFound =
false;
307 for (
auto f : fieldsOut)
319 tinyxml2::XMLElement* moduleConnectionXml = doc.NewElement(
"Connection");
320 moduleConnectionXml->SetAttribute(
"SourceId", -1);
321 moduleConnectionXml->SetAttribute(
"From", outFieldIndex);
322 moduleConnectionXml->SetAttribute(
"TargetId", indices[m->objectId()]);
323 moduleConnectionXml->SetAttribute(
"To",
uint(i));
324 moduleConnectionsXml->InsertEndChild(moduleConnectionXml);
336 savePipeline(node->animationPipeline(),
"Simulation");
351 savePipeline(node->graphicsPipeline(),
"Rendering");
356 doc.SaveFile(filename.c_str());
365 const char* name = nodeXML->Attribute(
"Class");
372 std::cout << name <<
" does not exist! " << std::endl;
376 const char* coordStr = nodeXML->Attribute(
"Coordinate");
380 node->setBlockCoord(coord.x, coord.y);
382 const char* nodeName = nodeXML->Attribute(
"Name");
384 node->setName(nodeName);
386 std::map<std::string, FBase*> str2Field;
387 auto& params = node->getParameters();
388 for (
auto var : params) {
389 str2Field[var->getObjectName()] = var;
391 tinyxml2::XMLElement* varsXmls = nodeXML->FirstChildElement(
"Variables");
392 tinyxml2::XMLElement* fieldXml = varsXmls->FirstChildElement(
"Field");
395 std::string name = fieldXml->Attribute(
"Name");
396 std::string str = fieldXml->GetText();
397 str2Field[name]->deserialize(str);
399 fieldXml = fieldXml->NextSiblingElement(
"Field");
403 std::vector<ConnectionInfo> infoVec;
408 tinyxml2::XMLElement* cnnXmls = nodeXML->FirstChildElement(
"Connections");
409 tinyxml2::XMLElement* connectionXml = cnnXmls->FirstChildElement(
"Connection");
411 while (connectionXml)
415 info.
src = atoi(connectionXml->Attribute(
"SourceId"));
416 info.
dst = atoi(connectionXml->Attribute(
"TargetId"));
418 info.
id0 = atoi(connectionXml->Attribute(
"From"));
419 info.
id1 = atoi(connectionXml->Attribute(
"To"));
421 infoVec.push_back(info);
424 connectionXml = connectionXml->NextSiblingElement(
"Connection");
431 auto& fields = node->getAllFields();
432 std::vector<FBase*> states;
433 for (
auto field : fields)
437 states.push_back(field);
442 states.push_back(field);
449 std::vector<Module*> animationModules;
450 node->animationPipeline()->clear();
451 tinyxml2::XMLElement* animationPipelineXml = nodeXML->FirstChildElement(
"Simulation");
452 tinyxml2::XMLElement* animationModuleXml = animationPipelineXml->FirstChildElement(
"Module");
454 auto processModule = [&](tinyxml2::XMLElement* moduleXml, std::shared_ptr<Pipeline> pipeline, std::vector<Module*>& modules) {
455 const char* name = moduleXml->Attribute(
"Class");
458 if (module !=
nullptr) {
459 pipeline->pushModule(module);
460 modules.push_back(module.get());
462 std::map<std::string, FBase*> str2Field;
463 auto& params =
module->getParameters();
464 for (
auto var : params) {
465 str2Field[var->getObjectName()] = var;
468 tinyxml2::XMLElement* varsXml = moduleXml->FirstChildElement(
"Variables");
469 tinyxml2::XMLElement* varXml = varsXml->FirstChildElement(
"Field");
473 std::string name = varXml->Attribute(
"Name");
474 std::string str = varXml->GetText();
475 str2Field[name]->deserialize(str);
477 varXml = varXml->NextSiblingElement(
"Field");
485 while (animationModuleXml)
487 processModule(animationModuleXml, node->animationPipeline(), animationModules);
497 animationModuleXml = animationModuleXml->NextSiblingElement(
"Module");
499 tinyxml2::XMLElement* animationConnectionsXml = animationPipelineXml->FirstChildElement(
"Connections");
500 tinyxml2::XMLElement* animationConnectionXml = animationConnectionsXml->FirstChildElement(
"Connection");
501 while (animationConnectionXml)
503 int src = atoi(animationConnectionXml->Attribute(
"SourceId"));
504 int dst = atoi(animationConnectionXml->Attribute(
"TargetId"));
506 int id0 = atoi(animationConnectionXml->Attribute(
"From"));
507 int id1 = atoi(animationConnectionXml->Attribute(
"To"));
509 FBase* fout = src == -1 ? states[id0] : animationModules[src]->getOutputFields()[id0];
510 FBase* fin = animationModules[dst]->getInputFields()[id1];
514 animationConnectionXml = animationConnectionXml->NextSiblingElement(
"Connection");
516 animationModules.clear();
521 std::vector<Module*> renderingModules;
522 node->graphicsPipeline()->clear();
523 tinyxml2::XMLElement* renderingPipelineXml = nodeXML->FirstChildElement(
"Rendering");
524 tinyxml2::XMLElement* renderingModuleXml = renderingPipelineXml->FirstChildElement(
"Module");
525 while (renderingModuleXml)
527 processModule(renderingModuleXml, node->graphicsPipeline(), renderingModules);
537 renderingModuleXml = renderingModuleXml->NextSiblingElement(
"Module");
540 tinyxml2::XMLElement* renderingConnectionsXml = renderingPipelineXml->FirstChildElement(
"Connections");
541 tinyxml2::XMLElement* renderingConnectionXml = renderingConnectionsXml->FirstChildElement(
"Connection");
542 while (renderingConnectionXml)
544 int src = atoi(renderingConnectionXml->Attribute(
"SourceId"));
545 int dst = atoi(renderingConnectionXml->Attribute(
"TargetId"));
547 int id0 = atoi(renderingConnectionXml->Attribute(
"From"));
548 int id1 = atoi(renderingConnectionXml->Attribute(
"To"));
550 if (id0 < states.size())
552 FBase* fout = src == -1 ? states[id0] : renderingModules[src]->getOutputFields()[id0];
553 FBase* fin = renderingModules[dst]->getInputFields()[id1];
559 renderingConnectionXml = renderingConnectionXml->NextSiblingElement(
"Connection");
561 renderingModules.clear();