PeriDyno 1.2.1
Loading...
Searching...
No Matches
SceneLoaderXML.cpp
Go to the documentation of this file.
1#include "SceneLoaderXML.h"
2#include <algorithm>
3
4#include <stdlib.h>
5#include <sstream>
6
7namespace dyno
8{
9 using LoadResult = std::variant<std::shared_ptr<SceneGraph>, std::string>;
10
11 LoadResult SceneLoaderXML::load(const std::string filename)
12 {
13 tinyxml2::XMLDocument doc;
14 if (doc.LoadFile(filename.c_str()))
15 {
16 doc.PrintError();
17 return "Error Load";
18 }
19
20 for (size_t i = 0; i < mConnectionInfo.size(); i++) {
21 mConnectionInfo[i].clear();
22 }
23 mConnectionInfo.clear();
24
25 std::shared_ptr<SceneGraph> scn = std::make_shared<SceneGraph>();
26
27 tinyxml2::XMLElement* root = doc.RootElement();
28
29 scn->setUpperBound(decodeVec3f(root->Attribute("UpperBound")));
30 scn->setLowerBound(decodeVec3f(root->Attribute("LowerBound")));
31
32 std::vector<std::shared_ptr<Node>> nodes;
33 tinyxml2::XMLElement* nodeXML = root->FirstChildElement("Node");
34
35 std::map<std::shared_ptr<Node>, tinyxml2::XMLElement*> node2xml;
36
37 while (nodeXML)
38 {
39 auto node = processNode(nodeXML);
40 if (node) {
41 scn->addNode(node);
42 nodes.push_back(node);
43 }
44 node2xml[node] = nodeXML;
45
46 nodeXML = nodeXML->NextSiblingElement("Node");
47 }
48
49 std::map<ObjectId, std::shared_ptr<Node>> objID2Node;
50 std::map<uint, ObjectId> index2ObjectId;
51 int radix = 0;
52
53 for (auto it : nodes) {
54
55 objID2Node[it->objectId()] = it;
56 index2ObjectId[radix] = it->objectId();
57 radix++;
58 }
59
60 for (auto it : node2xml)
61 {
62 ConstructNodePipeline(it.first,it.second, nodes);
63 }
64
65 for (size_t i = 0; i < mConnectionInfo.size(); i++)
66 {
67 auto& connections = mConnectionInfo[i];
68 for (size_t j = 0; j < connections.size(); j++)
69 {
70 auto info = connections[j];
71
72 auto expNode = nodes[info.src];
73 auto inpNode = nodes[info.dst];
74
75 auto& outFields = expNode->getOutputFields();
76 auto& FieldsSrc = expNode->getAllFields();
77
78 auto& inPorts = inpNode->getImportNodes();
79 auto& inFields = inpNode->getInputFields();
80
81 if (info.srcModuleId != -1) //from module;
82 {
83 std::shared_ptr<Pipeline> pipline;
84 switch (info.srcModulePipline)
85 {
86 case 0:
87 pipline = expNode->animationPipeline();
88 break;
89 case 1:
90 pipline = expNode->graphicsPipeline();
91 break;
92 case 2:
93 pipline = expNode->resetPipeline();
94 break;
95 default:
96 break;
97 }
98 auto& activemodules = pipline->activeModules();
99 std::vector<std::shared_ptr<Module>> modules;
100 for (const auto& elem : activemodules) {
101 modules.push_back(elem);
102 }
103 FBase* fout = modules[info.srcModuleId]->getAllFields()[info.id0];
104 FBase* fin = inpNode->getAllFields()[info.id1];
105
106 fout->connect(fin);
107 if (fin->getFieldType() != FieldTypeEnum::Out)
108 pipline->promoteOutputToNode(fout);
109 }
110 else
111 {
112 if (info.id0 <= 0)
113 {
114 expNode->connect(inPorts[info.id1]);
115 }
116 else
117 {
118 FieldsSrc[info.id0]->connect(inpNode->getAllFields()[info.id1]);
119 }
120 }
121
122 }
123 }
124
125 scn->markQueueUpdateRequired();
126
127 return scn;
128 }
129
130 bool SceneLoaderXML::save(std::shared_ptr<SceneGraph> scn, const std::string filename)
131 {
132 tinyxml2::XMLDocument doc;
133
134 // const char* declaration = "<?xml version=\"0.6.0\" encoding=\"UTF-8\">";
135 // doc.Parse(declaration);
136
137 tinyxml2::XMLElement* root = doc.NewElement("SceneGraph");
138
139 root->SetAttribute("LowerBound", encodeVec3f(scn->getLowerBound()).c_str());
140 root->SetAttribute("UpperBound", encodeVec3f(scn->getUpperBound()).c_str());
141
142 doc.InsertEndChild(root);
143
144 // version
145 tinyxml2::XMLElement* version = doc.NewElement("Version");
146 version->SetText(TOSTRING(PERIDYNO_VERSION));
147 root->InsertEndChild(version);
148
149
150 SceneGraph::Iterator itor = scn->begin();
151
152 std::map<ObjectId, uint> indices;
153 int radix = 0;
154 for (; itor != scn->end(); itor++) {
155 auto node = itor.get();
156 indices[node->objectId()] = radix;
157
158 radix++;
159 }
160 for (itor = scn->begin(); itor != scn->end(); itor++)
161 {
162 auto node = itor.get();
163
164 tinyxml2::XMLElement* nodeXml = doc.NewElement("Node");
165 nodeXml->SetAttribute("Class", node->getClassInfo()->getClassName().c_str());
166 nodeXml->SetAttribute("Coordinate", encodeVec2f(Vec2f(node->bx(), node->by())).c_str());
167 nodeXml->SetAttribute("Dt",node->getDt());
168 nodeXml->SetAttribute("AutoSync", node->isAutoSync());
169 nodeXml->SetAttribute("AutoHidden", node->isAutoHidden());
170 nodeXml->SetAttribute("PhysicsEnabled", node->isActive());
171 nodeXml->SetAttribute("RenderingEnabled", node->isVisible());
172
173 root->InsertEndChild(nodeXml);
174
175 tinyxml2::XMLElement* varsXml = doc.NewElement("Variables");
176 nodeXml->InsertEndChild(varsXml);
177
178 //write control variables
179 auto& params = node->getParameters();
180 for (auto var : params)
181 {
182 tinyxml2::XMLElement* field = doc.NewElement("Field");
183 field->SetAttribute("Name", var->getObjectName().c_str());
184
185 tinyxml2::XMLText* val = doc.NewText(var->serialize().c_str());
186 field->InsertEndChild(val);
187
188 varsXml->InsertEndChild(field);
189 }
190
191 //write connections
192 tinyxml2::XMLElement* nodeConnectionsXml = doc.NewElement("Connections");
193 nodeXml->InsertEndChild(nodeConnectionsXml);
194
195 auto ports = node->getImportNodes();
196
197 for (int i = 0; i < ports.size(); i++)
198 {
199 auto NodesSrc = ports[i]->getNodes();
200 bool fieldFound = false;
201 Node* nSrcPar = nullptr;
202 for (auto nSrc : NodesSrc)
203 {
204 auto nSrcExports = nSrc->getExportNodes();
205 for (auto x : nSrcExports)
206 {
207 if (x == ports[i])
208 {
209 fieldFound = true;
210 nSrcPar = nSrc;
211
212 tinyxml2::XMLElement* connection = doc.NewElement("Connection");
213 connection->SetAttribute("SourceId", indices[nSrcPar->objectId()]);
214 connection->SetAttribute("From", 0);
215 connection->SetAttribute("TargetId", indices[node->objectId()]);
216 connection->SetAttribute("To", uint(i));
217 nodeConnectionsXml->InsertEndChild(connection);
218 }
219 }
220 }
221 }
222
223 auto fieldInp = node->getInputFields();
224
225 for (int i = 0; i < fieldInp.size(); i++)
226 {
227 uint ToIndex = 0;
228 auto InNodeFields = node->getAllFields();
229 for (ToIndex = 0; ToIndex < InNodeFields.size(); ToIndex++)
230 {
231 if (fieldInp[i] == InNodeFields[ToIndex])
232 break;
233 }
234
235 switch (fieldInp[i]->inputPolicy())
236 {
238 {
239 auto manySrc = fieldInp[i]->getSources();
240 for (size_t j = 0; j < manySrc.size(); j++)
241 {
242 auto fieldSrc = manySrc[j];
243
244 if (fieldSrc != nullptr)
245 {
246 NodeFieldInputConnection(fieldSrc, doc, indices, node, ToIndex, nodeConnectionsXml);
247 }
248 }
249 break;
250 }
252 {
253 auto fieldSrc = fieldInp[i]->getSource();
254 if (fieldSrc != nullptr)
255 {
256 NodeFieldInputConnection(fieldSrc, doc,indices,node,ToIndex,nodeConnectionsXml);
257 }
258 break;
259 }
260 default:
261 break;
262 };
263
264 }
265
266 for (auto s : node->getOutputFields())
267 {
268 auto fieldSrc = s->getSource();
269 if (fieldSrc != nullptr)
270 {
271 auto parSrc = fieldSrc->parent();
272 int ToIndex = -1;
273 auto fields = node->getAllFields();
274 for (size_t i = 0; i < fields.size(); i++)
275 {
276 auto t = fields[i];
277 if (t == s)
278 {
279 ToIndex = i;
280 break;
281 }
282 }
283 Node* nodeSrc = dynamic_cast<Node*>(parSrc);// [node->field] - [node->field]
284 if (nodeSrc != nullptr)
285 {
286 auto fieldsSrc = nodeSrc->getAllFields();
287
288 bool fieldFound = false;
289
290 uint FromIndex = 0;
291 for (FromIndex = 0; FromIndex < fieldsSrc.size(); FromIndex++)
292 {
293 if (fieldsSrc[FromIndex] == fieldSrc)
294 {
295 fieldFound = true;
296 break;
297 }
298 }
299
300
301 if (fieldFound) {
302 tinyxml2::XMLElement* connection = doc.NewElement("Connection");
303 connection->SetAttribute("SourceId", indices[parSrc->objectId()]);
304
305 connection->SetAttribute("TargetId", indices[node->objectId()]);
306 connection->SetAttribute("To", ToIndex);
307 connection->SetAttribute("From", FromIndex);
308 nodeConnectionsXml->InsertEndChild(connection);
309 }
310 }
311
312
313 Module* moduleSrc = dynamic_cast<Module*>(parSrc);// [ANode->Module->field] - [BNode->field]
314 if (moduleSrc != nullptr)
315 {
316 std::map<ObjectId, uint> ModuleIndices;
317 auto getModuleData = [&](Module* module, int& index, int& channel)
318 {
319
320 {
321 uint radix = 0;
322
323 auto& animModules = module->getParentNode()->animationPipeline()->activeModules();
324 for (auto m : animModules) {
325 if (module == m.get())
326 {
327 channel = 0;
328 index = radix;
329 return;
330 }
331 radix++;
332 }
333
334 radix = 0;
335 auto& renderModules = module->getParentNode()->graphicsPipeline()->activeModules();
336 for (auto m : renderModules) {
337 if (module == m.get())
338 {
339 channel = 1;
340 index = radix;
341 return;
342 }
343 radix++;
344 }
345
346 radix = 0;
347 auto& resetModules = module->getParentNode()->resetPipeline()->activeModules();
348 for (auto m : resetModules) {
349 if (module == m.get())
350 {
351 channel = 2;
352 index = radix;
353 return;
354 }
355 radix++;
356 }
357 }
358 };
359
360
361 auto outId = moduleSrc->objectId();
362 auto moduleFieldsSrc = moduleSrc->getAllFields();
363
364 uint Index = 0;
365 bool fieldFound = false;
366 for (auto f : moduleFieldsSrc)
367 {
368 if (f == fieldSrc)
369 {
370 fieldFound = true;
371 break;
372 }
373 Index++;
374 }
375
376
377
378 if (fieldFound) {
379 tinyxml2::XMLElement* connection = doc.NewElement("Connection");
380
381 connection->SetAttribute("SourceId", indices[moduleSrc->getParentNode()->objectId()]);
382
383 int moduleIndex = -1;
384 int pipline = -1;
385 getModuleData(moduleSrc, moduleIndex, pipline);
386 connection->SetAttribute("SourceModuleId", moduleIndex);
387 connection->SetAttribute("SourceModulePipline", pipline);
388 connection->SetAttribute("TargetId", indices[node->objectId()]);
389 connection->SetAttribute("To", ToIndex);
390 connection->SetAttribute("From", Index);
391 nodeConnectionsXml->InsertEndChild(connection);
392 }
393 }
394
395 }
396 }
397 /**/
398 //Save pipeline
399 auto savePipeline = [&](std::shared_ptr<Pipeline> pipeline, const char* tag) {
400 tinyxml2::XMLElement* pipelineXml = doc.NewElement(tag);
401 nodeXml->InsertEndChild(pipelineXml);
402
403 std::map<ObjectId, uint> ModuleIndices;
404 std::map<ObjectId, std::shared_ptr<Module>> moduleMap;
405 uint radix = 0;
406
407 auto& activeModules = pipeline->activeModules();
408 for (auto m : activeModules) {
409 tinyxml2::XMLElement* moduleXml = doc.NewElement("Module");
410 moduleXml->SetAttribute("Class", m->getClassInfo()->getClassName().c_str());
411 moduleXml->SetAttribute("Coordinate", encodeVec2f(Vec2f(m->bx(), m->by())).c_str());
412 pipelineXml->InsertEndChild(moduleXml);
413
414 tinyxml2::XMLElement* varsModuleXml = doc.NewElement("Variables");
415 moduleXml->InsertEndChild(varsModuleXml);
416
417 //write control variables
418 auto& params = m->getParameters();
419 for (auto var : params)
420 {
421 tinyxml2::XMLElement* field = doc.NewElement("Field");
422 field->SetAttribute("Name", var->getObjectName().c_str());
423
424 tinyxml2::XMLText* val = doc.NewText(var->serialize().c_str());
425 field->InsertEndChild(val);
426
427 varsModuleXml->InsertEndChild(field);
428 }
429
430 ModuleIndices[m->objectId()] = radix;
431 moduleMap[m->objectId()] = m;
432 radix++;
433 }
434 //write connections
435 tinyxml2::XMLElement* moduleConnectionsXml = doc.NewElement("Connections");
436 pipelineXml->InsertEndChild(moduleConnectionsXml);
437
438 for (auto m : activeModules)
439 {
440 {//Try
441 auto& ports = m->getImportModules();
442
443 for (int i = 0; i < ports.size(); i++)
444 {
445 auto ModuleSrc = ports[i]->getModules();
446 for (auto mSrc : ModuleSrc)
447 {
448
449 tinyxml2::XMLElement* moduleConnectionXml = doc.NewElement("Connection");
450 moduleConnectionXml->SetAttribute("SourceModulePortId", ModuleIndices[mSrc->objectId()]);
451 moduleConnectionXml->SetAttribute("TargetModulePortId", ModuleIndices[m->objectId()]);
452 moduleConnectionsXml->InsertEndChild(moduleConnectionXml);
453
454 }
455 }
456 }
457
458
459 auto& fieldIn = m->getInputFields();
460 for (int i = 0; i < fieldIn.size(); i++)
461 {
462 auto fieldSrc = fieldIn[i]->getSource();
463 if (fieldSrc != nullptr) {
464 auto parSrc = fieldSrc->parent();
465 if (parSrc != nullptr)
466 {
467 uint inFieldIndex = 0;
468 bool infieldFound = false;
469
470 auto infields = m->getAllFields();
471 for (auto f : infields)
472 {
473 if (f == fieldIn[i])
474 {
475 infieldFound = true;
476 break;
477 }
478 inFieldIndex++;
479 }
480
481 Module* src = dynamic_cast<Module*>(parSrc);
482 if (src != nullptr)
483 {
484 auto outId = src->objectId();
485 auto srcfields = src->getAllFields();
486
487 uint outFieldIndex = 0;
488 bool fieldFound = false;
489 for (auto f : srcfields)
490 {
491 if (f == fieldSrc)
492 {
493 fieldFound = true;
494 break;
495 }
496 outFieldIndex++;
497 }
498
499 if (fieldFound && moduleMap.find(outId) != moduleMap.end())
500 {
501 auto outBlock = moduleMap[outId];
502
503 tinyxml2::XMLElement* moduleConnectionXml = doc.NewElement("Connection");
504 moduleConnectionXml->SetAttribute("SourceId", ModuleIndices[outBlock->objectId()]);
505 moduleConnectionXml->SetAttribute("From", outFieldIndex);
506 moduleConnectionXml->SetAttribute("TargetId", ModuleIndices[m->objectId()]);
507 moduleConnectionXml->SetAttribute("To", inFieldIndex);
508 moduleConnectionsXml->InsertEndChild(moduleConnectionXml);
509 }
510 }
511 else {
512 Node* src = dynamic_cast<Node*>(parSrc);
513
514 if (src != nullptr)
515 {
516 bool fieldFound = false;
517 auto n = src->getModuleList().size();
518 FieldTypeEnum type;
519 auto fields = src->getAllFields();
520 int nodeExportIndex = 0;
521 for (auto f : fields)
522 {
523 if (f == fieldSrc)
524 {
525 fieldFound = true;
526 type = f->getFieldType();
527 break;
528 }
529 nodeExportIndex++;
530 }
531
532 if (fieldFound)
533 {
534 tinyxml2::XMLElement* moduleConnectionXml = doc.NewElement("Connection");
535 moduleConnectionXml->SetAttribute("SourceId", -1 * int((indices[src->objectId()]) + 1));
536 moduleConnectionXml->SetAttribute("From", nodeExportIndex);
537 moduleConnectionXml->SetAttribute("TargetId", ModuleIndices[m->objectId()]);
538 moduleConnectionXml->SetAttribute("To", inFieldIndex);
539
540 moduleConnectionsXml->InsertEndChild(moduleConnectionXml);
541 }
542 }
543 }
544 }
545 }
546 }
547 }
548
549 ModuleIndices.clear();
550 };
551
552 savePipeline(node->animationPipeline(), "Simulation");
553
554 savePipeline(node->graphicsPipeline(), "Rendering");
555
556
557 }
558
559 doc.SaveFile(filename.c_str());
560
561 indices.clear();
562
563 return true;
564 }
565
566 std::shared_ptr<Node> SceneLoaderXML::processNode(tinyxml2::XMLElement* nodeXML)
567 {
568 const char* name = nodeXML->Attribute("Class");
569 if (!name)
570 return nullptr;
571
572 std::shared_ptr<Node> node(dynamic_cast<Node*>(Object::createObject(name)));
573 if (node == nullptr)
574 {
575 std::cout << name << " does not exist! " << std::endl;
576 return nullptr;
577 }
578
579 const char* coordStr = nodeXML->Attribute("Coordinate");
580
581 Vec2f coord = decodeVec2f(std::string(coordStr));
582
583 node->setBlockCoord(coord.x, coord.y);
584
585 const char* dtStr = nodeXML->Attribute("Dt");
586 node->setDt(std::stod(dtStr));
587
588 const char* syncStr = nodeXML->Attribute("AutoSync");
589 node->setAutoSync(std::string(syncStr) == "false" ? false : true);
590
591 const char* hiddenStr = nodeXML->Attribute("AutoHidden");
592 node->setAutoHidden(std::string(hiddenStr) == "false" ? false : true);
593
594 const char* activeStr = nodeXML->Attribute("PhysicsEnabled");
595 node->setActive(std::string(activeStr) == "false" ? false : true);
596
597 const char* visibleStr = nodeXML->Attribute("RenderingEnabled");
598 node->setVisible(std::string(visibleStr) == "false" ? false : true);
599
600 const char* nodeName = nodeXML->Attribute("Name");
601 if (nodeName)
602 node->setName(nodeName);
603
604 std::map<std::string, FBase*> str2Field;
605 auto& params = node->getParameters();
606 for (auto var : params) {
607 str2Field[var->getObjectName()] = var;
608 }
609 tinyxml2::XMLElement* varsXmls = nodeXML->FirstChildElement("Variables");
610 tinyxml2::XMLElement* fieldXml = varsXmls->FirstChildElement("Field");
611 while (fieldXml)
612 {
613 std::string name = fieldXml->Attribute("Name");
614 std::string str = fieldXml->GetText() == nullptr ? "" : fieldXml->GetText();
615 str2Field[name]->deserialize(str);
616
617 fieldXml = fieldXml->NextSiblingElement("Field");
618 }
619 str2Field.clear();
620
621 std::vector<ConnectionInfo> infoVec;
622
626 tinyxml2::XMLElement* cnnXmls = nodeXML->FirstChildElement("Connections");
627 tinyxml2::XMLElement* connectionXml = cnnXmls->FirstChildElement("Connection");
628
629 while (connectionXml)
630 {
631 ConnectionInfo info;
632
633 info.src = atoi(connectionXml->Attribute("SourceId"));
634 info.dst = atoi(connectionXml->Attribute("TargetId"));
635
636 info.id0 = atoi(connectionXml->Attribute("From"));
637 info.id1 = atoi(connectionXml->Attribute("To"));
638
639 auto sourceModuleId = connectionXml->Attribute("SourceModuleId");
640 auto sourceModulePiplineId = connectionXml->Attribute("SourceModulePipline");
641 if (sourceModuleId != nullptr && sourceModulePiplineId != nullptr)
642 {
643 info.srcModuleId = atoi(connectionXml->Attribute("SourceModuleId"));
644 info.srcModulePipline = atoi(connectionXml->Attribute("SourceModulePipline"));
645
646 }
647
648 infoVec.push_back(info);
649
650 connectionXml = connectionXml->NextSiblingElement("Connection");
651 }
652
653 mConnectionInfo.push_back(infoVec);
654
655 infoVec.clear();
656
657 auto& fields = node->getAllFields();
658
659
660
661 return node;
662 }
663
664
666 {
667 std::stringstream ss;
668
669 ss << v.x << " " << v.y << " " << v.z;
670
671 return ss.str();
672 }
673
675 {
676 std::stringstream ss;
677
678 ss << v.x << " " << v.y;
679
680 return ss.str();
681 }
682
683 Vec3f SceneLoaderXML::decodeVec3f(const std::string str)
684 {
685 std::stringstream ss(str);
686 std::string substr;
687
688 ss >> substr;
689 float x = std::stof(substr.c_str());
690
691 ss >> substr;
692 float y = std::stof(substr.c_str());
693
694 ss >> substr;
695 float z = std::stof(substr.c_str());
696
697 return Vec3f(x, y, z);
698 }
699
700 Vec2f SceneLoaderXML::decodeVec2f(const std::string str)
701 {
702 std::stringstream ss(str);
703 std::string substr;
704
705 ss >> substr;
706 float x = std::stof(substr.c_str());
707
708 ss >> substr;
709 float y = std::stof(substr.c_str());
710
711 return Vec2f(x, y);
712 }
713
714 bool SceneLoaderXML::canLoadFileByExtension(const std::string extension)
715 {
716 std::string str = extension;
717 std::transform(str.begin(), str.end(), str.begin(), ::tolower);
718 return (extension == "xml");
719 }
720
722 FBase* fieldSrc,
723 tinyxml2::XMLDocument& doc,
724 std::map<ObjectId, uint> indices,
725 std::shared_ptr<Node> node,
726 uint ToIndex,
727 tinyxml2::XMLElement* nodeConnectionsXml
728 )
729 {
730 auto parSrc = fieldSrc->parent();
731 if (parSrc != nullptr)
732 {
733 Node* nodeSrc = dynamic_cast<Node*>(parSrc);// [node->field] - [node->field]
734 if (nodeSrc != nullptr)
735 {
736 auto fieldsSrc = nodeSrc->getAllFields();
737
738 bool fieldFound = false;
739
740 uint FromIndex = 0;
741 for (FromIndex = 0; FromIndex < fieldsSrc.size(); FromIndex++)
742 {
743 if (fieldsSrc[FromIndex] == fieldSrc)
744 {
745 fieldFound = true;
746 break;
747 }
748 }
749
750
751 if (fieldFound) {
752 tinyxml2::XMLElement* connection = doc.NewElement("Connection");
753 connection->SetAttribute("SourceId", indices[parSrc->objectId()]);
754
755 connection->SetAttribute("TargetId", indices[node->objectId()]);
756 connection->SetAttribute("To", ToIndex);
757 connection->SetAttribute("From", FromIndex);
758 nodeConnectionsXml->InsertEndChild(connection);
759 }
760 }
761
762
763 Module* moduleSrc = dynamic_cast<Module*>(parSrc);// [node->Module->field] - [node->field]
764 if (moduleSrc != nullptr)
765 {
766 std::map<ObjectId, uint> ModuleIndices;
767 auto getModuleData = [&](Module* module, int& index, int& channel)
768 {
769 {
770 uint radix = 0;
771
772 auto& animModules = module->getParentNode()->animationPipeline()->activeModules();
773 for (auto m : animModules) {
774 if (module == m.get())
775 {
776 channel = 0;
777 index = radix;
778 return;
779 }
780 radix++;
781 }
782
783 radix = 0;
784 auto& renderModules = module->getParentNode()->graphicsPipeline()->activeModules();
785 for (auto m : renderModules) {
786 if (module == m.get())
787 {
788 channel = 1;
789 index = radix;
790 return;
791 }
792 radix++;
793 }
794
795 radix = 0;
796 auto& resetModules = module->getParentNode()->resetPipeline()->activeModules();
797 for (auto m : resetModules) {
798 if (module == m.get())
799 {
800 channel = 2;
801 index = radix;
802 return;
803 }
804 radix++;
805 }
806 }
807 };
808
809
810 auto outId = moduleSrc->objectId();
811 auto moduleFieldsSrc = moduleSrc->getAllFields();
812
813 uint Index = 0;
814 bool fieldFound = false;
815 for (auto f : moduleFieldsSrc)
816 {
817 if (f == fieldSrc)
818 {
819 fieldFound = true;
820 break;
821 }
822 Index++;
823 }
824
825
826
827 if (fieldFound) {
828 tinyxml2::XMLElement* connection = doc.NewElement("Connection");
829
830 connection->SetAttribute("SourceId", indices[moduleSrc->getParentNode()->objectId()]);
831
832 int moduleIndex = -1;
833 int pipline = -1;
834 getModuleData(moduleSrc, moduleIndex, pipline);
835 connection->SetAttribute("SourceModuleId", moduleIndex);
836 connection->SetAttribute("SourceModulePipline", pipline);
837 connection->SetAttribute("TargetId", indices[node->objectId()]);
838 connection->SetAttribute("To", ToIndex);
839 connection->SetAttribute("From", Index);
840 nodeConnectionsXml->InsertEndChild(connection);
841 }
842 }
843 }
844
845 }
846
847 bool SceneLoaderXML::ConstructNodePipeline(std::shared_ptr<Node> node, tinyxml2::XMLElement* nodeXML, std::vector<std::shared_ptr<Node>> nodes)
848 {
849 bool anim = ConstructPipeline(node, node->animationPipeline(), nodeXML, nodes);
850 bool graphic = ConstructPipeline(node, node->graphicsPipeline(), nodeXML, nodes);
851
852 return anim && graphic;
853 }
854
855 bool SceneLoaderXML::ConstructPipeline(std::shared_ptr<Node> node, std::shared_ptr<Pipeline> pipeline, tinyxml2::XMLElement* nodeXML, std::vector<std::shared_ptr<Node>> nodes)
856 {
857 std::string pipelineName;
858
859 if (dynamic_cast<AnimationPipeline*>(pipeline.get()))
860 pipelineName = "Simulation";
861 else if (dynamic_cast<GraphicsPipeline*>(pipeline.get()))
862 pipelineName = "Rendering";
863 else
864 return false;
865
866
867 std::vector<Module*> pipelineModules;
868 pipeline->clear();
869 tinyxml2::XMLElement* PipelineXml = nodeXML->FirstChildElement(pipelineName.c_str());
870 tinyxml2::XMLElement* ModuleXml = PipelineXml->FirstChildElement("Module");
871
872
873
874 while (ModuleXml)
875 {
876 processModule(ModuleXml, pipeline, pipelineModules);
877
878
879 ModuleXml = ModuleXml->NextSiblingElement("Module");
880 }
881 tinyxml2::XMLElement* ConnectionsXml = PipelineXml->FirstChildElement("Connections");
882 tinyxml2::XMLElement* ConnectXml = ConnectionsXml->FirstChildElement("Connection");
883 while (ConnectXml)
884 {
885 bool isFlowConnection = ConnectXml->Attribute("SourceModulePortId");
886
887
888 if(isFlowConnection)
889 {
891 int src = atoi(ConnectXml->Attribute("SourceModulePortId"));
892 int target = atoi(ConnectXml->Attribute("TargetModulePortId"));
893
894 pipelineModules[src]->connect(pipelineModules[target]->importModules());
895 }
896 else
897 {
898 //Data Connection
899 int src = atoi(ConnectXml->Attribute("SourceId"));
900 int dst = atoi(ConnectXml->Attribute("TargetId"));
901
902 int id0 = atoi(ConnectXml->Attribute("From"));
903 int id1 = atoi(ConnectXml->Attribute("To"));
904 FBase* fout;
905 if (src < 0)
906 {
907 auto& fields = nodes[std::abs(src) - 1]->getAllFields();
908 fout = fields[id0];
909 }
910 else
911 {
912 fout = pipelineModules[src]->getAllFields()[id0];
913 }
914
915 FBase* fin = pipelineModules[dst]->getAllFields()[id1];
916
917 fout->connect(fin);
918 }
919
920
921 ConnectXml = ConnectXml->NextSiblingElement("Connection");
922 }
923 pipelineModules.clear();
924 return true;
925 }
926
927 void SceneLoaderXML::processModule(tinyxml2::XMLElement* moduleXml, std::shared_ptr<Pipeline> pipeline, std::vector<Module*>& modules)
928 {
929 const char* name = moduleXml->Attribute("Class");
930 if (name) {
931 std::shared_ptr<Module> module(dynamic_cast<Module*>(Object::createObject(name)));
932 if (module != nullptr) {
933 pipeline->pushModule(module);
934 modules.push_back(module.get());
935
936 std::map<std::string, FBase*> str2Field;
937 auto& params = module->getParameters();
938 for (auto var : params) {
939 str2Field[var->getObjectName()] = var;
940 }
941
942 tinyxml2::XMLElement* varsXml = moduleXml->FirstChildElement("Variables");
943 tinyxml2::XMLElement* varXml = varsXml->FirstChildElement("Field");
944
945 while (varXml)
946 {
947 std::string name = varXml->Attribute("Name");
948 std::string str = varXml->GetText();
949 str2Field[name]->deserialize(str);
950
951 varXml = varXml->NextSiblingElement("Field");
952 }
953
954 str2Field.clear();
955 }
956 }
957 }
958
959}
#define TOSTRING(x)
FieldTypeEnum getFieldType()
Definition FBase.cpp:388
OBase * parent()
Definition FBase.cpp:41
virtual bool connect(FBase *dst)=0
Node * getParentNode()
Definition Module.cpp:246
std::list< std::shared_ptr< Module > > & getModuleList()
Definition Node.h:149
std::shared_ptr< Node > get() const
std::vector< FBase * > & getAllFields()
Definition OBase.cpp:202
static Object * createObject(std::string name)
Definition Object.cpp:33
ObjectId objectId()
Definition Object.h:129
NodeIterator Iterator
Definition SceneGraph.h:34
std::variant< std::shared_ptr< SceneGraph >, std::string > LoadResult
bool ConstructNodePipeline(std::shared_ptr< Node > node, tinyxml2::XMLElement *nodeXML, std::vector< std::shared_ptr< Node > > nodes)
Vec3f decodeVec3f(const std::string str)
std::string encodeVec2f(const Vec2f v)
virtual bool canLoadFileByExtension(const std::string extension)
bool ConstructPipeline(std::shared_ptr< Node > node, std::shared_ptr< Pipeline > pipeline, tinyxml2::XMLElement *nodeXML, std::vector< std::shared_ptr< Node > > nodes)
void processModule(tinyxml2::XMLElement *moduleXml, std::shared_ptr< Pipeline > pipeline, std::vector< Module * > &modules)
std::shared_ptr< Node > processNode(tinyxml2::XMLElement *nodeXML)
LoadResult load(const std::string filename) override
void NodeFieldInputConnection(FBase *fieldSrc, tinyxml2::XMLDocument &doc, std::map< ObjectId, uint > indices, std::shared_ptr< Node > node, uint ToIndex, tinyxml2::XMLElement *nodeConnectionsXml)
Vec2f decodeVec2f(const std::string str)
std::string encodeVec3f(const Vec3f v)
bool save(std::shared_ptr< SceneGraph > scn, const std::string filename) override
std::vector< std::vector< ConnectionInfo > > mConnectionInfo
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
Vector< float, 2 > Vec2f
Definition Vector2D.h:81
std::variant< std::shared_ptr< SceneGraph >, std::string > LoadResult
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
FieldTypeEnum
Definition FBase.h:30
@ Out
Definition FBase.h:32
unsigned int uint
Definition VkProgram.h:14