13        tinyxml2::XMLDocument doc;
 
   14        if (doc.LoadFile(filename.c_str()))
 
   25        std::shared_ptr<SceneGraph> scn = std::make_shared<SceneGraph>();
 
   27        tinyxml2::XMLElement* root = doc.RootElement();
 
   29        scn->setUpperBound(
decodeVec3f(root->Attribute(
"UpperBound")));
 
   30        scn->setLowerBound(
decodeVec3f(root->Attribute(
"LowerBound")));
 
   32        std::vector<std::shared_ptr<Node>> nodes;
 
   33        tinyxml2::XMLElement* nodeXML = root->FirstChildElement(
"Node");
 
   35        std::map<std::shared_ptr<Node>, tinyxml2::XMLElement*> node2xml;
 
   42                nodes.push_back(node);
 
   44            node2xml[node] = nodeXML;
 
   46            nodeXML = nodeXML->NextSiblingElement(
"Node");
 
   49        std::map<ObjectId, std::shared_ptr<Node>> objID2Node;
 
   50        std::map<uint, ObjectId> index2ObjectId;
 
   53        for (
auto it : nodes) {
 
   55            objID2Node[it->objectId()] = it;
 
   56            index2ObjectId[radix] = it->objectId();
 
   60        for (
auto it : node2xml)
 
   68            for (
size_t j = 0; j < connections.size(); j++)
 
   70                auto info = connections[j];
 
   72                auto expNode = nodes[info.src];
 
   73                auto inpNode = nodes[info.dst];
 
   75                auto& outFields = expNode->getOutputFields();
 
   76                auto& FieldsSrc = expNode->getAllFields();
 
   78                auto& inPorts = inpNode->getImportNodes();
 
   79                auto& inFields = inpNode->getInputFields();
 
   81                if (info.srcModuleId != -1) 
 
   83                    std::shared_ptr<Pipeline> pipline;
 
   84                    switch (info.srcModulePipline)
 
   87                        pipline = expNode->animationPipeline();
 
   90                        pipline = expNode->graphicsPipeline();
 
   93                        pipline = expNode->resetPipeline();
 
   98                    auto& activemodules = pipline->activeModules();
 
   99                    std::vector<std::shared_ptr<Module>> modules;
 
  100                    for (
const auto& elem : activemodules) {
 
  101                        modules.push_back(elem);
 
  103                    FBase* fout = modules[info.srcModuleId]->getAllFields()[info.id0];
 
  104                    FBase* fin = inpNode->getAllFields()[info.id1];
 
  108                        pipline->promoteOutputToNode(fout);
 
  114                        expNode->connect(inPorts[info.id1]);
 
  118                        FieldsSrc[info.id0]->connect(inpNode->getAllFields()[info.id1]);
 
  125        scn->markQueueUpdateRequired();
 
 
  132        tinyxml2::XMLDocument doc;
 
  137        tinyxml2::XMLElement* root = doc.NewElement(
"SceneGraph");
 
  139        root->SetAttribute(
"LowerBound", 
encodeVec3f(scn->getLowerBound()).c_str());
 
  140        root->SetAttribute(
"UpperBound", 
encodeVec3f(scn->getUpperBound()).c_str());
 
  142        doc.InsertEndChild(root);
 
  145        tinyxml2::XMLElement* version = doc.NewElement(
"Version");
 
  146        version->SetText(
TOSTRING(PERIDYNO_VERSION));
 
  147        root->InsertEndChild(version);
 
  152        std::map<ObjectId, uint> indices;
 
  154        for (; itor != scn->end(); itor++) {
 
  155            auto node = itor.
get();
 
  156            indices[node->objectId()] = radix;
 
  160        for (itor = scn->begin(); itor != scn->end(); itor++)
 
  162            auto node = itor.
get();
 
  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());
 
  173            root->InsertEndChild(nodeXml);
 
  175            tinyxml2::XMLElement* varsXml = doc.NewElement(
"Variables");
 
  176            nodeXml->InsertEndChild(varsXml);
 
  179            auto& params = node->getParameters();
 
  180            for (
auto var : params)
 
  182                tinyxml2::XMLElement* field = doc.NewElement(
"Field");
 
  183                field->SetAttribute(
"Name", var->getObjectName().c_str());
 
  185                tinyxml2::XMLText* val = doc.NewText(var->serialize().c_str());
 
  186                field->InsertEndChild(val);
 
  188                varsXml->InsertEndChild(field);
 
  192            tinyxml2::XMLElement* nodeConnectionsXml = doc.NewElement(
"Connections");
 
  193            nodeXml->InsertEndChild(nodeConnectionsXml);
 
  195            auto ports = node->getImportNodes();
 
  197            for (
int i = 0; i < ports.size(); i++)
 
  199                auto NodesSrc = ports[i]->getNodes();
 
  200                bool fieldFound = 
false;
 
  201                Node* nSrcPar = 
nullptr;
 
  202                for (
auto nSrc : NodesSrc)
 
  204                    auto nSrcExports = nSrc->getExportNodes();
 
  205                    for (
auto x : nSrcExports)
 
  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);
 
  223            auto fieldInp = node->getInputFields();
 
  225            for (
int i = 0; i < fieldInp.size(); i++)
 
  228                auto InNodeFields = node->getAllFields();
 
  229                for (ToIndex = 0; ToIndex < InNodeFields.size(); ToIndex++)
 
  231                    if (fieldInp[i] == InNodeFields[ToIndex])
 
  235                switch (fieldInp[i]->inputPolicy())
 
  239                    auto manySrc = fieldInp[i]->getSources();
 
  240                    for (
size_t j = 0; j < manySrc.size(); j++)
 
  242                        auto fieldSrc = manySrc[j];
 
  244                        if (fieldSrc != 
nullptr) 
 
  253                    auto fieldSrc = fieldInp[i]->getSource();
 
  254                    if (fieldSrc != 
nullptr) 
 
  266            for (
auto s : node->getOutputFields())
 
  268                auto fieldSrc = s->getSource();
 
  269                if (fieldSrc != 
nullptr)
 
  271                    auto parSrc = fieldSrc->parent();
 
  273                    auto fields = node->getAllFields();
 
  274                    for (
size_t i = 0; i < fields.size(); i++)
 
  283                    Node* nodeSrc = 
dynamic_cast<Node*
>(parSrc);
 
  284                    if (nodeSrc != 
nullptr)
 
  288                        bool fieldFound = 
false;
 
  291                        for (FromIndex = 0; FromIndex < fieldsSrc.size(); FromIndex++)
 
  293                            if (fieldsSrc[FromIndex] == fieldSrc)
 
  302                            tinyxml2::XMLElement* connection = doc.NewElement(
"Connection");
 
  303                            connection->SetAttribute(
"SourceId", indices[parSrc->objectId()]);
 
  305                            connection->SetAttribute(
"TargetId", indices[node->objectId()]);
 
  306                            connection->SetAttribute(
"To", ToIndex);
 
  307                            connection->SetAttribute(
"From", FromIndex);
 
  308                            nodeConnectionsXml->InsertEndChild(connection);
 
  314                    if (moduleSrc != 
nullptr)
 
  316                        std::map<ObjectId, uint> ModuleIndices;
 
  317                        auto getModuleData = [&](
Module* module, 
int& index, 
int& channel)
 
  323                                auto& animModules = 
module->getParentNode()->animationPipeline()->activeModules();
 
  324                                for (
auto m : animModules) {
 
  325                                    if (module == m.get())
 
  335                                auto& renderModules = 
module->getParentNode()->graphicsPipeline()->activeModules();
 
  336                                for (
auto m : renderModules) {
 
  337                                    if (module == m.get())
 
  347                                auto& resetModules = 
module->getParentNode()->resetPipeline()->activeModules();
 
  348                                for (
auto m : resetModules) {
 
  349                                    if (module == m.get())
 
  365                        bool fieldFound = 
false;
 
  366                        for (
auto f : moduleFieldsSrc)
 
  379                            tinyxml2::XMLElement* connection = doc.NewElement(
"Connection");
 
  383                            int moduleIndex = -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);
 
  399            auto savePipeline = [&](std::shared_ptr<Pipeline> pipeline, 
const char* tag) {
 
  400                tinyxml2::XMLElement* pipelineXml = doc.NewElement(tag);
 
  401                nodeXml->InsertEndChild(pipelineXml);
 
  403                std::map<ObjectId, uint> ModuleIndices;
 
  404                std::map<ObjectId, std::shared_ptr<Module>> moduleMap;
 
  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);
 
  414                    tinyxml2::XMLElement* varsModuleXml = doc.NewElement(
"Variables");
 
  415                    moduleXml->InsertEndChild(varsModuleXml);
 
  418                    auto& params = m->getParameters();
 
  419                    for (
auto var : params)
 
  421                        tinyxml2::XMLElement* field = doc.NewElement(
"Field");
 
  422                        field->SetAttribute(
"Name", var->getObjectName().c_str());
 
  424                        tinyxml2::XMLText* val = doc.NewText(var->serialize().c_str());
 
  425                        field->InsertEndChild(val);
 
  427                        varsModuleXml->InsertEndChild(field);
 
  430                    ModuleIndices[m->objectId()] = radix;
 
  431                    moduleMap[m->objectId()] = m;
 
  435                tinyxml2::XMLElement* moduleConnectionsXml = doc.NewElement(
"Connections");
 
  436                pipelineXml->InsertEndChild(moduleConnectionsXml);
 
  438                for (
auto m : activeModules)
 
  441                        auto& ports = m->getImportModules();
 
  443                        for (
int i = 0; i < ports.size(); i++)
 
  445                            auto ModuleSrc = ports[i]->getModules();
 
  446                            for (
auto mSrc : ModuleSrc)
 
  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);
 
  459                    auto& fieldIn = m->getInputFields();
 
  460                    for (
int i = 0; i < fieldIn.size(); i++)
 
  462                        auto fieldSrc = fieldIn[i]->getSource();
 
  463                        if (fieldSrc != 
nullptr) {
 
  464                            auto parSrc = fieldSrc->parent();
 
  465                            if (parSrc != 
nullptr)
 
  467                                uint inFieldIndex = 0;
 
  468                                bool infieldFound = 
false;
 
  470                                auto infields = m->getAllFields();
 
  471                                for (
auto f : infields)
 
  487                                    uint outFieldIndex = 0;
 
  488                                    bool fieldFound = 
false;
 
  489                                    for (
auto f : srcfields)
 
  499                                    if (fieldFound && moduleMap.find(outId) != moduleMap.end())
 
  501                                        auto outBlock = moduleMap[outId];
 
  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);
 
  512                                    Node* src = 
dynamic_cast<Node*
>(parSrc);
 
  516                                        bool fieldFound = 
false;
 
  520                                        int nodeExportIndex = 0;
 
  521                                        for (
auto f : fields)
 
  526                                                type = f->getFieldType();
 
  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);
 
  540                                            moduleConnectionsXml->InsertEndChild(moduleConnectionXml);
 
  549                ModuleIndices.clear();
 
  552            savePipeline(node->animationPipeline(), 
"Simulation");
 
  554            savePipeline(node->graphicsPipeline(), 
"Rendering");
 
  559        doc.SaveFile(filename.c_str());
 
 
  568        const char* name = nodeXML->Attribute(
"Class");
 
  575            std::cout << name << 
" does not exist! " << std::endl;
 
  579        const char* coordStr = nodeXML->Attribute(
"Coordinate");
 
  583        node->setBlockCoord(coord.x, coord.y);
 
  585        const char* dtStr = nodeXML->Attribute(
"Dt");
 
  586        node->setDt(std::stod(dtStr));
 
  588        const char* syncStr = nodeXML->Attribute(
"AutoSync");
 
  589        node->setAutoSync(std::string(syncStr) == 
"false" ? 
false : 
true);
 
  591        const char* hiddenStr = nodeXML->Attribute(
"AutoHidden");
 
  592        node->setAutoHidden(std::string(hiddenStr) == 
"false" ? 
false : 
true);
 
  594        const char* activeStr = nodeXML->Attribute(
"PhysicsEnabled");
 
  595        node->setActive(std::string(activeStr) == 
"false" ? 
false : 
true);
 
  597        const char* visibleStr = nodeXML->Attribute(
"RenderingEnabled");
 
  598        node->setVisible(std::string(visibleStr) == 
"false" ? 
false : 
true);
 
  600        const char* nodeName = nodeXML->Attribute(
"Name");
 
  602            node->setName(nodeName);
 
  604        std::map<std::string, FBase*> str2Field;
 
  605        auto& params = node->getParameters();
 
  606        for (
auto var : params) {
 
  607            str2Field[var->getObjectName()] = var;
 
  609        tinyxml2::XMLElement* varsXmls = nodeXML->FirstChildElement(
"Variables");
 
  610        tinyxml2::XMLElement* fieldXml = varsXmls->FirstChildElement(
"Field");
 
  613            std::string name = fieldXml->Attribute(
"Name");
 
  614            std::string str = fieldXml->GetText() == 
nullptr ? 
"" : fieldXml->GetText();
 
  615            str2Field[name]->deserialize(str);
 
  617            fieldXml = fieldXml->NextSiblingElement(
"Field");
 
  621        std::vector<ConnectionInfo> infoVec;
 
  626        tinyxml2::XMLElement* cnnXmls = nodeXML->FirstChildElement(
"Connections");
 
  627        tinyxml2::XMLElement* connectionXml = cnnXmls->FirstChildElement(
"Connection");
 
  629        while (connectionXml)
 
  633            info.
src = atoi(connectionXml->Attribute(
"SourceId"));
 
  634            info.
dst = atoi(connectionXml->Attribute(
"TargetId"));
 
  636            info.
id0 = atoi(connectionXml->Attribute(
"From"));
 
  637            info.
id1 = atoi(connectionXml->Attribute(
"To"));
 
  639            auto sourceModuleId = connectionXml->Attribute(
"SourceModuleId");
 
  640            auto sourceModulePiplineId = connectionXml->Attribute(
"SourceModulePipline");
 
  641            if (sourceModuleId != 
nullptr && sourceModulePiplineId != 
nullptr)
 
  643                info.
srcModuleId = atoi(connectionXml->Attribute(
"SourceModuleId"));
 
  644                info.
srcModulePipline = atoi(connectionXml->Attribute(
"SourceModulePipline"));
 
  648            infoVec.push_back(info);
 
  650            connectionXml = connectionXml->NextSiblingElement(
"Connection");
 
  657        auto& fields = node->getAllFields();
 
 
  723        tinyxml2::XMLDocument& doc, 
 
  724        std::map<ObjectId, uint> indices, 
 
  725        std::shared_ptr<Node> node,
 
  727        tinyxml2::XMLElement* nodeConnectionsXml
 
  730        auto parSrc = fieldSrc->
parent();
 
  731        if (parSrc != 
nullptr)
 
  733            Node* nodeSrc = 
dynamic_cast<Node*
>(parSrc);
 
  734            if (nodeSrc != 
nullptr)
 
  738                bool fieldFound = 
false;
 
  741                for (FromIndex = 0; FromIndex < fieldsSrc.size(); FromIndex++)
 
  743                    if (fieldsSrc[FromIndex] == fieldSrc)
 
  752                    tinyxml2::XMLElement* connection = doc.NewElement(
"Connection");
 
  753                    connection->SetAttribute(
"SourceId", indices[parSrc->objectId()]);
 
  755                    connection->SetAttribute(
"TargetId", indices[node->objectId()]);
 
  756                    connection->SetAttribute(
"To", ToIndex);
 
  757                    connection->SetAttribute(
"From", FromIndex);
 
  758                    nodeConnectionsXml->InsertEndChild(connection);
 
  764            if (moduleSrc != 
nullptr)
 
  766                std::map<ObjectId, uint> ModuleIndices;
 
  767                auto getModuleData = [&](
Module* module, 
int& index, 
int& channel)
 
  772                        auto& animModules = 
module->getParentNode()->animationPipeline()->activeModules();
 
  773                        for (
auto m : animModules) {
 
  774                            if (module == m.get())
 
  784                        auto& renderModules = 
module->getParentNode()->graphicsPipeline()->activeModules();
 
  785                        for (
auto m : renderModules) {
 
  786                            if (module == m.get())
 
  796                        auto& resetModules = 
module->getParentNode()->resetPipeline()->activeModules();
 
  797                        for (
auto m : resetModules) {
 
  798                            if (module == m.get())
 
  814                bool fieldFound = 
false;
 
  815                for (
auto f : moduleFieldsSrc)
 
  828                    tinyxml2::XMLElement* connection = doc.NewElement(
"Connection");
 
  832                    int moduleIndex = -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);