From 4879dbcdb215e15c56819c7f0cfacc1fb8d71523 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Mon, 22 Dec 2025 16:39:09 +0100 Subject: [PATCH 01/60] SaveSnapshotv1 --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 3853848ecc..677f6c1543 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -80,6 +80,13 @@ #include #include +#include +using sofa::core::objectmodel::SnapshotType; + +#include +using sofa::simulation::SnapshotVisitor; + + #include @@ -431,7 +438,35 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) sofa::simulation::node::initRoot(baseGUI->getRootNode().get()); return; } + + ImGui::Separator(); + + if (ImGui::MenuItem(ICON_FA_FOLDER_CLOSED " Save Snapshot")) + { + // sofa::core::objectmodel::Base* b; + + auto JSONSnapCont = createSnapshot(SnapshotType::JSON); + auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); + groot->execute(visitor); + JSONSnapCont->exportToJSON(); + return; + + // Node* root = c.root.get() ; + // auto JSONSnapCont = createSnapshot(SnapshotType::JSON); + // auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); + // root->execute(visitor); + // JSONSnapCont->exportToJSON(); + // sofa::simulation::node::animate(groot.get(), groot->getDt()); + // sofa::simulation::node::updateVisual(groot.get()); + } + + if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) + { + return; + } + ImGui::Separator(); + if (ImGui::MenuItem("Exit")) { this->terminate(); From 724af0fc125229e15fc00853791db8e300dec371 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 23 Dec 2025 15:34:24 +0100 Subject: [PATCH 02/60] Save Snapshot - choose filename --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 37 ++++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 677f6c1543..ea71d09fd6 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -443,21 +443,38 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem(ICON_FA_FOLDER_CLOSED " Save Snapshot")) { - // sofa::core::objectmodel::Base* b; + auto JSONSnapCont = createSnapshot(SnapshotType::JSON); auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); groot->execute(visitor); - JSONSnapCont->exportToJSON(); - return; + NFD_Init(); + + nfdchar_t* savePath; - // Node* root = c.root.get() ; - // auto JSONSnapCont = createSnapshot(SnapshotType::JSON); - // auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); - // root->execute(visitor); - // JSONSnapCont->exportToJSON(); - // sofa::simulation::node::animate(groot.get(), groot->getDt()); - // sofa::simulation::node::updateVisual(groot.get()); + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + + + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) { + puts("Success!"); + puts(savePath); + + std::string path(savePath); + + JSONSnapCont->exportToJSON(path); + // remember to free the memory (since NFD_OKAY is returned) + NFD_FreePath(savePath); + } else if (result == NFD_CANCEL) { + puts("User pressed cancel."); + } else { + printf("Error: %s\n", NFD_GetError()); + } + + // Quit NFD + NFD_Quit(); + + return; } if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) From 06f2410cb4162d515c24d1089acffb378a10c47c Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 6 Jan 2026 16:15:59 +0100 Subject: [PATCH 03/60] new feature : select type of snapshot (only JSON) --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 102 ++++++++++++++------- 1 file changed, 69 insertions(+), 33 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index ea71d09fd6..3e13d33152 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -402,6 +402,15 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool animate; animate = groot->animate_.getValue(); + enum class SaveStep + { + None, + ChooseType, + OpenFileDialog + }; + + static SaveStep saveStep = SaveStep::None; + /*************************************** * Main menu bar **************************************/ @@ -442,39 +451,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Separator(); if (ImGui::MenuItem(ICON_FA_FOLDER_CLOSED " Save Snapshot")) - { - - - auto JSONSnapCont = createSnapshot(SnapshotType::JSON); - auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); - groot->execute(visitor); - NFD_Init(); - - nfdchar_t* savePath; - - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - - - nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) { - puts("Success!"); - puts(savePath); - - std::string path(savePath); - - JSONSnapCont->exportToJSON(path); - // remember to free the memory (since NFD_OKAY is returned) - NFD_FreePath(savePath); - } else if (result == NFD_CANCEL) { - puts("User pressed cancel."); - } else { - printf("Error: %s\n", NFD_GetError()); - } - - // Quit NFD - NFD_Quit(); - - return; + { + saveStep = SaveStep::ChooseType; } if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) @@ -685,6 +663,62 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::EndMainMenuBar(); } + if (saveStep == SaveStep::ChooseType) + { + ImGui::OpenPopup("SnapshotTypeChoice"); + } + + if ( ImGui::BeginPopupModal("SnapshotTypeChoice", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("Choose type of snapshot"); + ImGui::Separator(); + if (ImGui::Button("JSON")) + { + saveStep = SaveStep::OpenFileDialog; + + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("nothing")) + { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + + if(saveStep == SaveStep::OpenFileDialog) + { + + auto SnapCont = createSnapshot(SnapshotType::JSON); + auto visitor = SnapshotVisitor(nullptr,*SnapCont); + groot->execute(visitor); + + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) { + puts("Save Snapshot success!"); + puts(savePath); + + std::string path(savePath); + + SnapCont->exportToJSON(path); // Problem : i want to change this (avoid JSON) + // remember to free the memory (since NFD_OKAY is returned) + NFD_FreePath(savePath); + } else { + printf("Error: %s\n", NFD_GetError()); + } + + // Quit NFD + NFD_Quit(); + saveStep = SaveStep::None; + } + if (m_imguiNeedViewReset) { resetView(dockspace_id, windowNameSceneGraph, windowNameSelectionDescription, windowNameLog, windowNameViewport); @@ -1054,4 +1088,6 @@ type::Vec2i ImGuiGUIEngine::getFrameBufferPixels(std::vector& pixels) return {viewport[2], viewport[3]}; } + + } //namespace sofaimgui From 03b1950b64b0312e00ca24c9849b739db90db297 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 13 Jan 2026 09:22:08 +0100 Subject: [PATCH 04/60] fix tree structure SaveSnapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 3e13d33152..57b03b0590 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -410,7 +410,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) }; static SaveStep saveStep = SaveStep::None; - + static SnapshotType chosenType = SnapshotType::Print; /*************************************** * Main menu bar **************************************/ @@ -675,6 +675,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Separator(); if (ImGui::Button("JSON")) { + chosenType = SnapshotType::JSON; saveStep = SaveStep::OpenFileDialog; ImGui::CloseCurrentPopup(); @@ -690,7 +691,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(saveStep == SaveStep::OpenFileDialog) { - auto SnapCont = createSnapshot(SnapshotType::JSON); + // auto SnapCont = createSnapshot(SnapshotType::JSON); + auto SnapCont = createSnapshot(chosenType); auto visitor = SnapshotVisitor(nullptr,*SnapCont); groot->execute(visitor); @@ -707,7 +709,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) std::string path(savePath); - SnapCont->exportToJSON(path); // Problem : i want to change this (avoid JSON) + SnapCont->exportTo(path); // remember to free the memory (since NFD_OKAY is returned) NFD_FreePath(savePath); } else { From 82f7b8af63aa72310c329443defc2357b7e4fc2b Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Mon, 26 Jan 2026 11:17:52 +0100 Subject: [PATCH 05/60] update Snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 97 +++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 57b03b0590..a38f560687 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -410,6 +410,16 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) }; static SaveStep saveStep = SaveStep::None; + + enum class LoadStep + { + None, + ChooseType, + OpenFileDialog + }; + + static LoadStep loadStep = LoadStep::None; + static SnapshotType chosenType = SnapshotType::Print; /*************************************** * Main menu bar @@ -457,7 +467,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) { - return; + loadStep = LoadStep::ChooseType; + } ImGui::Separator(); @@ -668,6 +679,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::OpenPopup("SnapshotTypeChoice"); } + if (loadStep == LoadStep::ChooseType) + { + ImGui::OpenPopup("LoadSnapshotTypeChoice"); + } + if ( ImGui::BeginPopupModal("SnapshotTypeChoice", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { @@ -688,14 +704,57 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::EndPopup(); } + if ( ImGui::BeginPopupModal("LoadSnapshotTypeChoice", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("Choose type of snapshot"); + ImGui::Separator(); + if (ImGui::Button("JSON")) + { + chosenType = SnapshotType::JSON; + loadStep = LoadStep::OpenFileDialog; + + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("nothing")) + { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if(saveStep == SaveStep::OpenFileDialog) { // auto SnapCont = createSnapshot(SnapshotType::JSON); auto SnapCont = createSnapshot(chosenType); - auto visitor = SnapshotVisitor(nullptr,*SnapCont); + auto rootSnapNode = std::make_shared(); + rootSnapNode->name = "root"; + // SnapNode_.nodeName = "root"; + std::cout << "IMGUI " << std::endl; + auto visitor = SnapshotVisitor(nullptr,*SnapCont, *rootSnapNode); groot->execute(visitor); + std::ofstream file("dumpStateTest.txt"); + sofa::simulation::node::dumpState(groot.get(),file); + file.close(); + + for(auto element : rootSnapNode->componentList) + { + std::cout <<"dans rootSnapNode : " << element.name << std::endl; + } + + std::cout << "######" << std::endl; + + for(auto element : rootSnapNode->childNode) + { + std::cout <<"dans rootSnapNode : " << element->name << std::endl; + for(auto compelement : element->componentList) + { + std::cout << "components: " << compelement.name << std::endl; + } + } NFD_Init(); nfdchar_t* savePath; @@ -721,6 +780,40 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) saveStep = SaveStep::None; } + if(loadStep == LoadStep::OpenFileDialog) + { + auto SnapCont = createSnapshot(chosenType); + + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); + // nfdresult_t result = NFD_OpenDialog(&outPath, nfd_filters.data(), nfd_filters.size(), NULL); + if ( result == NFD_OKAY ) + { + puts("Success!"); + puts(outPath); + + if (helper::system::FileSystem::exists(outPath)) + { + //loadFile(baseGUI, groot, outPath, false); + SnapCont->importSnapshot(outPath); + + } + free(outPath); + } + else if ( result == NFD_CANCEL ) + { + puts("User pressed cancel."); + } + else + { + printf("Error: %s\n", NFD_GetError() ); + } + NFD_Quit(); + loadStep = LoadStep::None; + // call loadSnapshot ? to transfer data/link into their fields + } + if (m_imguiNeedViewReset) { resetView(dockspace_id, windowNameSceneGraph, windowNameSelectionDescription, windowNameLog, windowNameViewport); From cfbc57f389c1554294eb304c00ff55b59ebd30c4 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 27 Jan 2026 17:58:07 +0100 Subject: [PATCH 06/60] [Snapshot] ADD codes for load a snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 106 ++++++++++++++------- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 2 + 2 files changed, 73 insertions(+), 35 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index a38f560687..5cb42ff2ad 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -86,6 +86,9 @@ using sofa::core::objectmodel::SnapshotType; #include using sofa::simulation::SnapshotVisitor; +#include +using sofa::simulation::LoadSnapshotVisitor; + #include @@ -406,7 +409,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { None, ChooseType, - OpenFileDialog + OpenFileDialog, + MemorySave }; static SaveStep saveStep = SaveStep::None; @@ -415,7 +419,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { None, ChooseType, - OpenFileDialog + OpenFileDialog, + MemorySave }; static LoadStep loadStep = LoadStep::None; @@ -700,8 +705,17 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::Button("nothing")) { ImGui::CloseCurrentPopup(); + saveStep = SaveStep::None; + } + ImGui::SameLine(); + if (ImGui::Button("Memory")) + { + chosenType = SnapshotType::Memory; + saveStep = SaveStep::MemorySave; + ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); + } if ( ImGui::BeginPopupModal("LoadSnapshotTypeChoice", nullptr, @@ -720,41 +734,27 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::Button("nothing")) { ImGui::CloseCurrentPopup(); + loadStep = LoadStep::None; + } + ImGui::SameLine(); + if (ImGui::Button("Memory")) + { + chosenType = SnapshotType::Memory; + loadStep = LoadStep::MemorySave; + ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); + } if(saveStep == SaveStep::OpenFileDialog) { + //auto SnapCont = createSnapshot(chosenType); + //SnapCont->printSnapshot(); + m_baseSnapshot = createSnapshot(chosenType); + m_baseSnapshot->printSnapshot(); + // auto visitor = SnapshotVisitor(nullptr,*SnapCont); - // auto SnapCont = createSnapshot(SnapshotType::JSON); - auto SnapCont = createSnapshot(chosenType); - auto rootSnapNode = std::make_shared(); - rootSnapNode->name = "root"; - // SnapNode_.nodeName = "root"; - std::cout << "IMGUI " << std::endl; - auto visitor = SnapshotVisitor(nullptr,*SnapCont, *rootSnapNode); - groot->execute(visitor); - - std::ofstream file("dumpStateTest.txt"); - sofa::simulation::node::dumpState(groot.get(),file); - file.close(); - - for(auto element : rootSnapNode->componentList) - { - std::cout <<"dans rootSnapNode : " << element.name << std::endl; - } - - std::cout << "######" << std::endl; - - for(auto element : rootSnapNode->childNode) - { - std::cout <<"dans rootSnapNode : " << element->name << std::endl; - for(auto compelement : element->componentList) - { - std::cout << "components: " << compelement.name << std::endl; - } - } NFD_Init(); nfdchar_t* savePath; @@ -767,8 +767,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) puts(savePath); std::string path(savePath); - - SnapCont->exportTo(path); + auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + // SnapCont->exportTo(path); + m_baseSnapshot->exportTo(path); // remember to free the memory (since NFD_OKAY is returned) NFD_FreePath(savePath); } else { @@ -777,12 +779,29 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) // Quit NFD NFD_Quit(); + // SnapCont->printSnapshot(); + m_baseSnapshot->printSnapshot(); + saveStep = SaveStep::None; + } + + if (saveStep == SaveStep::MemorySave) + { + std::cout << "MemorySave begin : " << std::endl; + m_baseSnapshot = createSnapshot(chosenType); + m_baseSnapshot->printSnapshot(); + auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } if(loadStep == LoadStep::OpenFileDialog) { - auto SnapCont = createSnapshot(chosenType); + if(!m_baseSnapshot) + { + m_baseSnapshot = createSnapshot(chosenType); + } + nfdchar_t *outPath = NULL; nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; @@ -796,8 +815,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { //loadFile(baseGUI, groot, outPath, false); - SnapCont->importSnapshot(outPath); - + m_baseSnapshot->importFrom(outPath); + //m_baseSnapshot->printSnapshot(); + //auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + //groot->execute(visitor); } free(outPath); } @@ -810,10 +831,25 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) printf("Error: %s\n", NFD_GetError() ); } NFD_Quit(); + + + loadStep = LoadStep::None; // call loadSnapshot ? to transfer data/link into their fields } + if (loadStep == LoadStep::MemorySave) + { + if(!m_baseSnapshot) + { + m_baseSnapshot = createSnapshot(chosenType); + } + + m_baseSnapshot->printSnapshot(); + + loadStep = LoadStep::None; + } + if (m_imguiNeedViewReset) { resetView(dockspace_id, windowNameSceneGraph, windowNameSelectionDescription, windowNameLog, windowNameViewport); diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index 73cb3ccd8e..01e52db4c9 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -116,6 +116,8 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine static inline constexpr int s_NB_PBOS = 2; GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; + + std::shared_ptr m_baseSnapshot; }; } // namespace sofaimgui From eac5dfd056560bfd672eac1494d78d012ff3b264 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Wed, 28 Jan 2026 09:32:02 +0100 Subject: [PATCH 07/60] clean some comments --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 5cb42ff2ad..31d7b0340c 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -748,12 +748,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } if(saveStep == SaveStep::OpenFileDialog) - { - //auto SnapCont = createSnapshot(chosenType); - //SnapCont->printSnapshot(); + { m_baseSnapshot = createSnapshot(chosenType); m_baseSnapshot->printSnapshot(); - // auto visitor = SnapshotVisitor(nullptr,*SnapCont); NFD_Init(); @@ -769,7 +766,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) std::string path(savePath); auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); - // SnapCont->exportTo(path); + m_baseSnapshot->exportTo(path); // remember to free the memory (since NFD_OKAY is returned) NFD_FreePath(savePath); @@ -779,7 +776,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) // Quit NFD NFD_Quit(); - // SnapCont->printSnapshot(); m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } @@ -802,11 +798,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) m_baseSnapshot = createSnapshot(chosenType); } - nfdchar_t *outPath = NULL; nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); - // nfdresult_t result = NFD_OpenDialog(&outPath, nfd_filters.data(), nfd_filters.size(), NULL); + if ( result == NFD_OKAY ) { puts("Success!"); @@ -832,10 +827,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } NFD_Quit(); - - loadStep = LoadStep::None; - // call loadSnapshot ? to transfer data/link into their fields + } if (loadStep == LoadStep::MemorySave) From f6d1d0e76bfd004ac62aa29472e1aa42ee8a67e7 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 3 Feb 2026 09:29:00 +0100 Subject: [PATCH 08/60] [SNAPSHOT] FIX save and load snapshotAPI --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 31d7b0340c..33761508f6 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -750,7 +750,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(saveStep == SaveStep::OpenFileDialog) { m_baseSnapshot = createSnapshot(chosenType); - m_baseSnapshot->printSnapshot(); + // m_baseSnapshot->printSnapshot(); NFD_Init(); @@ -776,18 +776,16 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) // Quit NFD NFD_Quit(); - m_baseSnapshot->printSnapshot(); + // m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } if (saveStep == SaveStep::MemorySave) { - std::cout << "MemorySave begin : " << std::endl; + std::cout << "MemorySave !" << std::endl; m_baseSnapshot = createSnapshot(chosenType); - m_baseSnapshot->printSnapshot(); auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); - m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } @@ -811,7 +809,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { //loadFile(baseGUI, groot, outPath, false); m_baseSnapshot->importFrom(outPath); - //m_baseSnapshot->printSnapshot(); + // //m_baseSnapshot->printSnapshot(); //auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); //groot->execute(visitor); } @@ -833,13 +831,17 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (loadStep == LoadStep::MemorySave) { + std::cout << "MemoryLoad !" << std::endl; if(!m_baseSnapshot) { + std::cout << "Nothing to load..." << std::endl; m_baseSnapshot = createSnapshot(chosenType); } + else + { + m_baseSnapshot->importSnapshot("test"); + } - m_baseSnapshot->printSnapshot(); - loadStep = LoadStep::None; } From 53dfb58dc1aa78f49f9f00a084b3066707c39a34 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Mon, 9 Feb 2026 09:43:54 +0100 Subject: [PATCH 09/60] Update laodSnapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 33761508f6..ee93aeb9e1 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -839,7 +839,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } else { - m_baseSnapshot->importSnapshot("test"); + m_baseSnapshot->importSnapshot("none"); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); } loadStep = LoadStep::None; From 0a97a3543215ca4bf533cea38f694d815abb921d Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Wed, 25 Feb 2026 11:44:32 +0100 Subject: [PATCH 10/60] [Snapshot] Fix LoadSnapshot for JSON --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index ee93aeb9e1..0bc965410a 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -750,8 +750,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(saveStep == SaveStep::OpenFileDialog) { m_baseSnapshot = createSnapshot(chosenType); - // m_baseSnapshot->printSnapshot(); - + NFD_Init(); nfdchar_t* savePath; @@ -759,24 +758,22 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) { + if (result == NFD_OKAY) + { puts("Save Snapshot success!"); puts(savePath); - std::string path(savePath); auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); - m_baseSnapshot->exportTo(path); - // remember to free the memory (since NFD_OKAY is returned) NFD_FreePath(savePath); - } else { + } + else + { printf("Error: %s\n", NFD_GetError()); } - // Quit NFD NFD_Quit(); - // m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } @@ -807,11 +804,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { - //loadFile(baseGUI, groot, outPath, false); m_baseSnapshot->importFrom(outPath); - // //m_baseSnapshot->printSnapshot(); - //auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); - //groot->execute(visitor); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } free(outPath); } From c59fd04e8fbd197a3146f356bc953076de87a490 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Thu, 26 Feb 2026 11:39:06 +0100 Subject: [PATCH 11/60] modify API for save/load snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 386 +++++++++++---------- 1 file changed, 197 insertions(+), 189 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 0bc965410a..34b728d405 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -339,6 +339,29 @@ void ImGuiGUIEngine::saveScreenshot(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } +void AddRecentFile(const std::string& path, std::vector& recentFiles, int maxFiles = 10) +{ + recentFiles.erase( + std::remove(recentFiles.begin(), recentFiles.end(), path), + recentFiles.end() + ); + //recentFiles.insert(recentFiles.begin(), path); + recentFiles.push_back(path); + if (recentFiles.size() > maxFiles) + recentFiles.resize(maxFiles); +} + +void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) +{ + static int index = 0; + recentSnapshots["Memory_Snapshot " + std::to_string(index++) + " at " + std::to_string(snapshotTime)] = snapshot; + if (recentSnapshots.size() > maxSnapshots) + recentSnapshots.erase(recentSnapshots.begin()); +} + +std::vector recentSnapshotFiles; +std::map> recentSnapshots; + void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_localeBackup = std::setlocale(LC_NUMERIC, nullptr); @@ -399,33 +422,19 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool showFPSInMenuBar = true; static bool showTime = true; + static bool showMemorySnapshot = true; ImVec2 mainMenuBarSize; static bool animate; animate = groot->animate_.getValue(); - enum class SaveStep - { - None, - ChooseType, - OpenFileDialog, - MemorySave - }; - - static SaveStep saveStep = SaveStep::None; - - enum class LoadStep - { - None, - ChooseType, - OpenFileDialog, - MemorySave - }; + static SnapshotType chosenType = SnapshotType::Print; - static LoadStep loadStep = LoadStep::None; + + const int MAX_RECENT_FILES = 10; - static SnapshotType chosenType = SnapshotType::Print; + /*************************************** * Main menu bar **************************************/ @@ -465,15 +474,166 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Separator(); - if (ImGui::MenuItem(ICON_FA_FOLDER_CLOSED " Save Snapshot")) - { - saveStep = SaveStep::ChooseType; + if (ImGui::BeginMenu("Save Snapshot")) + { + if(ImGui::MenuItem("Memory")) + { + chosenType = SnapshotType::Memory; + std::cout << "MemorySave !" << std::endl; + m_baseSnapshot = createSnapshot(chosenType); + auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + std::string memorySnapshotName = "Memory Snapshot"; + if(!recentSnapshotFiles.empty()) + { + memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); + + } + + auto snapshotTime = groot->getTime(); + AddRecentSnapshot(recentSnapshots, m_baseSnapshot, snapshotTime); + } + if (ImGui::MenuItem("JSON")) + { + chosenType = SnapshotType::JSON; + m_baseSnapshot = createSnapshot(chosenType); + + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + std::string filepath = "null"; + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) + { + puts("Save Snapshot success!"); + puts(savePath); + std::string path(savePath); + auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + m_baseSnapshot->exportTo(path); + std::cout << "filepath : " << filepath << std::endl; + std::cout << "savePath : " << savePath << std::endl; + filepath = savePath; + std::cout << "filepath after : " << filepath << std::endl; + NFD_FreePath(savePath); + } + else + { + + printf("Error: %s\n", NFD_GetError()); + } + + NFD_Quit(); + AddRecentFile(filepath, recentSnapshotFiles); + } + + ImGui::EndMenu(); } - if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) + if (ImGui::BeginMenu("Load Snapshot")) { - loadStep = LoadStep::ChooseType; - + if (ImGui::MenuItem("Memory (recent)")) + { + std::cout << "MemoryLoad !" << std::endl; + if(!m_baseSnapshot) + { + std::cout << "Nothing to load..." << std::endl; + m_baseSnapshot = createSnapshot(SnapshotType::Memory); + } + else + { + m_baseSnapshot = recentSnapshots.rbegin()->second; + m_baseSnapshot->importSnapshot("none"); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } + } + + if (ImGui::MenuItem("JSON")) + { + if(!m_baseSnapshot) + { + m_baseSnapshot = createSnapshot(SnapshotType::JSON); + } + + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); + std::string filepath = "null"; + if ( result == NFD_OKAY ) + { + puts("Success!"); + puts(outPath); + + if (helper::system::FileSystem::exists(outPath)) + { + m_baseSnapshot->importFrom(outPath); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + + } + filepath = outPath; + free(outPath); + } + else if ( result == NFD_CANCEL ) + { + puts("User pressed cancel."); + } + else + { + printf("Error: %s\n", NFD_GetError() ); + } + NFD_Quit(); + AddRecentFile(filepath, recentSnapshotFiles); + } + + if(ImGui::BeginMenu("Recent Files")) + { + if (recentSnapshotFiles.empty() && recentSnapshots.empty()) + { + ImGui::MenuItem("(No recent files)", nullptr, false, false); + } + else + { + for (auto file : recentSnapshotFiles) + { + if (ImGui::MenuItem(file.c_str())) + { + if(file.ends_with(".json")) + { + m_baseSnapshot = createSnapshot(SnapshotType::JSON); + std::cout << "file de MenuItem : " << file << std::endl; + m_baseSnapshot->importFrom(file); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } + else + { + m_baseSnapshot = createSnapshot(SnapshotType::Memory); + std::cout << "file de MenuItem : " << file << std::endl; + m_baseSnapshot->importFrom(file); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } + } + } + for (auto [name, file] : recentSnapshots) + { + if(ImGui::MenuItem(name.c_str())) + { + m_baseSnapshot = file; + std::cout << "file de MenuItem : " << name << std::endl; + m_baseSnapshot->importFrom("none"); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } + } + } + ImGui::EndMenu(); + } + ImGui::EndMenu(); } ImGui::Separator(); @@ -675,174 +835,22 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Text("Time: %.3f", groot->getTime()); ImGui::SetCursorPosX(posX); } + if (showMemorySnapshot) + { + auto position = ImGui::GetCursorPosX() + ImGui::GetColumnWidth() - ImGui::CalcTextSize("Snapshot in memory : 00 items ").x + - 2 * ImGui::GetStyle().ItemSpacing.x; + if (showFPSInMenuBar) + position -= ImGui::CalcTextSize("1000.0 FPS ").x; + if (showTime) + position -= ImGui::CalcTextSize("Time: 000.000 ").x; + ImGui::SetCursorPosX(position); + ImGui::Text("Snapshot in memory : %d items ", static_cast(recentSnapshots.size())); + ImGui::SetCursorPosX(posX); + } mainMenuBarSize = ImGui::GetWindowSize(); ImGui::EndMainMenuBar(); } - if (saveStep == SaveStep::ChooseType) - { - ImGui::OpenPopup("SnapshotTypeChoice"); - } - - if (loadStep == LoadStep::ChooseType) - { - ImGui::OpenPopup("LoadSnapshotTypeChoice"); - } - - if ( ImGui::BeginPopupModal("SnapshotTypeChoice", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) - { - ImGui::Text("Choose type of snapshot"); - ImGui::Separator(); - if (ImGui::Button("JSON")) - { - chosenType = SnapshotType::JSON; - saveStep = SaveStep::OpenFileDialog; - - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("nothing")) - { - ImGui::CloseCurrentPopup(); - saveStep = SaveStep::None; - } - ImGui::SameLine(); - if (ImGui::Button("Memory")) - { - chosenType = SnapshotType::Memory; - saveStep = SaveStep::MemorySave; - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - - } - - if ( ImGui::BeginPopupModal("LoadSnapshotTypeChoice", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) - { - ImGui::Text("Choose type of snapshot"); - ImGui::Separator(); - if (ImGui::Button("JSON")) - { - chosenType = SnapshotType::JSON; - loadStep = LoadStep::OpenFileDialog; - - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("nothing")) - { - ImGui::CloseCurrentPopup(); - loadStep = LoadStep::None; - } - ImGui::SameLine(); - if (ImGui::Button("Memory")) - { - chosenType = SnapshotType::Memory; - loadStep = LoadStep::MemorySave; - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - - } - - if(saveStep == SaveStep::OpenFileDialog) - { - m_baseSnapshot = createSnapshot(chosenType); - - NFD_Init(); - - nfdchar_t* savePath; - - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - - nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) - { - puts("Save Snapshot success!"); - puts(savePath); - std::string path(savePath); - auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); - groot->execute(visitor); - m_baseSnapshot->exportTo(path); - NFD_FreePath(savePath); - } - else - { - printf("Error: %s\n", NFD_GetError()); - } - - NFD_Quit(); - saveStep = SaveStep::None; - } - - if (saveStep == SaveStep::MemorySave) - { - std::cout << "MemorySave !" << std::endl; - m_baseSnapshot = createSnapshot(chosenType); - auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); - groot->execute(visitor); - saveStep = SaveStep::None; - } - - if(loadStep == LoadStep::OpenFileDialog) - { - if(!m_baseSnapshot) - { - m_baseSnapshot = createSnapshot(chosenType); - } - - nfdchar_t *outPath = NULL; - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); - - if ( result == NFD_OKAY ) - { - puts("Success!"); - puts(outPath); - - if (helper::system::FileSystem::exists(outPath)) - { - m_baseSnapshot->importFrom(outPath); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); - groot->execute(visitor); - - } - free(outPath); - } - else if ( result == NFD_CANCEL ) - { - puts("User pressed cancel."); - } - else - { - printf("Error: %s\n", NFD_GetError() ); - } - NFD_Quit(); - - loadStep = LoadStep::None; - - } - - if (loadStep == LoadStep::MemorySave) - { - std::cout << "MemoryLoad !" << std::endl; - if(!m_baseSnapshot) - { - std::cout << "Nothing to load..." << std::endl; - m_baseSnapshot = createSnapshot(chosenType); - } - else - { - m_baseSnapshot->importSnapshot("none"); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); - groot->execute(visitor); - } - - loadStep = LoadStep::None; - } - if (m_imguiNeedViewReset) { resetView(dockspace_id, windowNameSceneGraph, windowNameSelectionDescription, windowNameLog, windowNameViewport); From f93eb39aa11e6c435cbe1ec9b4dfd69b4e64cca1 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Fri, 27 Feb 2026 18:11:12 +0100 Subject: [PATCH 12/60] clean 27/02 --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 34b728d405..2e145024fa 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -604,7 +604,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(file.ends_with(".json")) { m_baseSnapshot = createSnapshot(SnapshotType::JSON); - std::cout << "file de MenuItem : " << file << std::endl; m_baseSnapshot->importFrom(file); auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); @@ -612,7 +611,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) else { m_baseSnapshot = createSnapshot(SnapshotType::Memory); - std::cout << "file de MenuItem : " << file << std::endl; m_baseSnapshot->importFrom(file); auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); @@ -624,7 +622,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(ImGui::MenuItem(name.c_str())) { m_baseSnapshot = file; - std::cout << "file de MenuItem : " << name << std::endl; m_baseSnapshot->importFrom("none"); auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); From 2ffba4cebf1840c0b07db9060719aad90f763ee5 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 3 Mar 2026 16:44:55 +0100 Subject: [PATCH 13/60] Renaming SnapshotVisitor to SaveSnapshotVisitor --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 2e145024fa..543992c37f 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -83,8 +83,8 @@ #include using sofa::core::objectmodel::SnapshotType; -#include -using sofa::simulation::SnapshotVisitor; +#include +using sofa::simulation::SaveSnapshotVisitor; #include using sofa::simulation::LoadSnapshotVisitor; @@ -481,7 +481,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) chosenType = SnapshotType::Memory; std::cout << "MemorySave !" << std::endl; m_baseSnapshot = createSnapshot(chosenType); - auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; if(!recentSnapshotFiles.empty()) @@ -510,7 +510,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) puts("Save Snapshot success!"); puts(savePath); std::string path(savePath); - auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); m_baseSnapshot->exportTo(path); std::cout << "filepath : " << filepath << std::endl; From 3201b1b2fdfdba46041b034361cda3a38d6909c3 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Wed, 11 Mar 2026 14:49:53 +0100 Subject: [PATCH 14/60] (draft) split data and link visitor for loading --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 28 +++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 543992c37f..c54ac2273d 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -86,8 +86,11 @@ using sofa::core::objectmodel::SnapshotType; #include using sofa::simulation::SaveSnapshotVisitor; -#include -using sofa::simulation::LoadSnapshotVisitor; +#include +using sofa::simulation::LoadDataSnapshotVisitor; + +#include +using sofa::simulation::LoadLinkSnapshotVisitor; #include @@ -544,10 +547,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } else { - m_baseSnapshot = recentSnapshots.rbegin()->second; - m_baseSnapshot->importSnapshot("none"); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + m_baseSnapshot = recentSnapshots.rbegin()->second; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); } } @@ -570,8 +574,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { m_baseSnapshot->importFrom(outPath); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); } filepath = outPath; @@ -605,15 +611,19 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_baseSnapshot = createSnapshot(SnapshotType::JSON); m_baseSnapshot->importFrom(file); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); } else { m_baseSnapshot = createSnapshot(SnapshotType::Memory); m_baseSnapshot->importFrom(file); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); } } } @@ -623,7 +633,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_baseSnapshot = file; m_baseSnapshot->importFrom("none"); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); } } From f3de55fe4145ca1d817549daec7d73217717820d Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Thu, 19 Mar 2026 17:21:27 +0100 Subject: [PATCH 15/60] update 19/03 --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index c54ac2273d..16a4a058f1 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -68,6 +68,7 @@ #include #include //imgui_internal.h is included in order to use the DockspaceBuilder API (which is still in development) #include +#include #include #include #include @@ -592,7 +593,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) printf("Error: %s\n", NFD_GetError() ); } NFD_Quit(); + std::cout << "JSON file loaded !" << std::endl; AddRecentFile(filepath, recentSnapshotFiles); + } if(ImGui::BeginMenu("Recent Files")) From e93a9c0046ccbc63b5183fb0a237f048572b20b2 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Thu, 19 Mar 2026 17:40:02 +0100 Subject: [PATCH 16/60] rename BaseSnapshot to Snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 58 +++++++++++----------- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 16a4a058f1..0fc88f890d 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -355,7 +355,7 @@ void AddRecentFile(const std::string& path, std::vector& recentFile recentFiles.resize(maxFiles); } -void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) +void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) { static int index = 0; recentSnapshots["Memory_Snapshot " + std::to_string(index++) + " at " + std::to_string(snapshotTime)] = snapshot; @@ -364,7 +364,7 @@ void AddRecentSnapshot(std::map recentSnapshotFiles; -std::map> recentSnapshots; +std::map> recentSnapshots; void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { @@ -484,8 +484,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { chosenType = SnapshotType::Memory; std::cout << "MemorySave !" << std::endl; - m_baseSnapshot = createSnapshot(chosenType); - auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = createSnapshot(chosenType); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; if(!recentSnapshotFiles.empty()) @@ -495,12 +495,12 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } auto snapshotTime = groot->getTime(); - AddRecentSnapshot(recentSnapshots, m_baseSnapshot, snapshotTime); + AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); } if (ImGui::MenuItem("JSON")) { chosenType = SnapshotType::JSON; - m_baseSnapshot = createSnapshot(chosenType); + m_snapshot = createSnapshot(chosenType); NFD_Init(); @@ -514,9 +514,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) puts("Save Snapshot success!"); puts(savePath); std::string path(savePath); - auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - m_baseSnapshot->exportTo(path); + m_snapshot->exportTo(path); std::cout << "filepath : " << filepath << std::endl; std::cout << "savePath : " << savePath << std::endl; filepath = savePath; @@ -541,26 +541,26 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem("Memory (recent)")) { std::cout << "MemoryLoad !" << std::endl; - if(!m_baseSnapshot) + if(!m_snapshot) { std::cout << "Nothing to load..." << std::endl; - m_baseSnapshot = createSnapshot(SnapshotType::Memory); + m_snapshot = createSnapshot(SnapshotType::Memory); } else { - m_baseSnapshot = recentSnapshots.rbegin()->second; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = recentSnapshots.rbegin()->second; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } } if (ImGui::MenuItem("JSON")) { - if(!m_baseSnapshot) + if(!m_snapshot) { - m_baseSnapshot = createSnapshot(SnapshotType::JSON); + m_snapshot = createSnapshot(SnapshotType::JSON); } nfdchar_t *outPath = NULL; @@ -574,10 +574,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { - m_baseSnapshot->importFrom(outPath); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot->importFrom(outPath); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } @@ -612,20 +612,20 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(file.ends_with(".json")) { - m_baseSnapshot = createSnapshot(SnapshotType::JSON); - m_baseSnapshot->importFrom(file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = createSnapshot(SnapshotType::JSON); + m_snapshot->importFrom(file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } else { - m_baseSnapshot = createSnapshot(SnapshotType::Memory); - m_baseSnapshot->importFrom(file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = createSnapshot(SnapshotType::Memory); + m_snapshot->importFrom(file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } } @@ -634,9 +634,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(ImGui::MenuItem(name.c_str())) { - m_baseSnapshot = file; - m_baseSnapshot->importFrom("none"); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = file; + m_snapshot->importFrom("none"); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); } } diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index 01e52db4c9..d2e6a80b98 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -117,7 +117,7 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; - std::shared_ptr m_baseSnapshot; + std::shared_ptr m_snapshot; }; } // namespace sofaimgui From 6f9a080726b0ea2cf30e840b1986b1152f80aa6b Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Fri, 20 Mar 2026 11:39:24 +0100 Subject: [PATCH 17/60] Refactoring the API of snapshot (Snapshot, SnapshotJSONExporter and SnapshotManager) --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 46 ++++++---------------- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 2 +- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 0fc88f890d..057ed1a3e9 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -81,10 +81,11 @@ #include #include -#include -using sofa::core::objectmodel::SnapshotType; +#include #include + +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" using sofa::simulation::SaveSnapshotVisitor; #include @@ -433,7 +434,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool animate; animate = groot->animate_.getValue(); - static SnapshotType chosenType = SnapshotType::Print; + //static SnapshotType chosenType = SnapshotType::Print; const int MAX_RECENT_FILES = 10; @@ -482,16 +483,14 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(ImGui::MenuItem("Memory")) { - chosenType = SnapshotType::Memory; std::cout << "MemorySave !" << std::endl; - m_snapshot = createSnapshot(chosenType); + auto m_snapshot = std::make_shared(); auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; if(!recentSnapshotFiles.empty()) { memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); - } auto snapshotTime = groot->getTime(); @@ -499,9 +498,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } if (ImGui::MenuItem("JSON")) { - chosenType = SnapshotType::JSON; - m_snapshot = createSnapshot(chosenType); - + auto m_snapshot = std::make_shared(); NFD_Init(); nfdchar_t* savePath; @@ -516,16 +513,12 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) std::string path(savePath); auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - m_snapshot->exportTo(path); - std::cout << "filepath : " << filepath << std::endl; - std::cout << "savePath : " << savePath << std::endl; + exportTo(*m_snapshot,path); filepath = savePath; - std::cout << "filepath after : " << filepath << std::endl; NFD_FreePath(savePath); } else { - printf("Error: %s\n", NFD_GetError()); } @@ -540,11 +533,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if (ImGui::MenuItem("Memory (recent)")) { + auto m_snapshot = std::make_shared(); std::cout << "MemoryLoad !" << std::endl; if(!m_snapshot) { std::cout << "Nothing to load..." << std::endl; - m_snapshot = createSnapshot(SnapshotType::Memory); } else { @@ -558,11 +551,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem("JSON")) { - if(!m_snapshot) - { - m_snapshot = createSnapshot(SnapshotType::JSON); - } - + auto m_snapshot = std::make_shared(); nfdchar_t *outPath = NULL; nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); @@ -574,7 +563,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { - m_snapshot->importFrom(outPath); + importFrom(*m_snapshot,outPath); auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); @@ -612,17 +601,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(file.ends_with(".json")) { - m_snapshot = createSnapshot(SnapshotType::JSON); - m_snapshot->importFrom(file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } - else - { - m_snapshot = createSnapshot(SnapshotType::Memory); - m_snapshot->importFrom(file); + auto m_snapshot = std::make_shared(); + importFrom(*m_snapshot,file); auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); @@ -634,8 +614,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(ImGui::MenuItem(name.c_str())) { + auto m_snapshot = std::make_shared(); m_snapshot = file; - m_snapshot->importFrom("none"); auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); } diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index d2e6a80b98..f30ccf63c3 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -117,7 +117,7 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; - std::shared_ptr m_snapshot; + // std::shared_ptr m_snapshot; }; } // namespace sofaimgui From 1079e40c2d929df67151d02e99e03977327f94c0 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Mon, 23 Mar 2026 17:12:44 +0100 Subject: [PATCH 18/60] Fix loadDataSnapshot and update SnapshotManager --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 53 ++++++++-------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 057ed1a3e9..633f7d2a64 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -82,10 +82,14 @@ #include #include +#include +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/Base.h" +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotManager.h" +using sofa::core::objectmodel::SnapshotManager; #include -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" +// #include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" using sofa::simulation::SaveSnapshotVisitor; #include @@ -344,28 +348,7 @@ void ImGuiGUIEngine::saveScreenshot(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } -void AddRecentFile(const std::string& path, std::vector& recentFiles, int maxFiles = 10) -{ - recentFiles.erase( - std::remove(recentFiles.begin(), recentFiles.end(), path), - recentFiles.end() - ); - //recentFiles.insert(recentFiles.begin(), path); - recentFiles.push_back(path); - if (recentFiles.size() > maxFiles) - recentFiles.resize(maxFiles); -} - -void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) -{ - static int index = 0; - recentSnapshots["Memory_Snapshot " + std::to_string(index++) + " at " + std::to_string(snapshotTime)] = snapshot; - if (recentSnapshots.size() > maxSnapshots) - recentSnapshots.erase(recentSnapshots.begin()); -} - -std::vector recentSnapshotFiles; -std::map> recentSnapshots; +SnapshotManager snapshot_manager; void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { @@ -484,17 +467,21 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(ImGui::MenuItem("Memory")) { std::cout << "MemorySave !" << std::endl; + auto m_snapshot = std::make_shared(); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; - if(!recentSnapshotFiles.empty()) + if(!snapshot_manager.recentSnapshotFiles.empty()) { - memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); + memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); } auto snapshotTime = groot->getTime(); - AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); + + // SnapshotManager::AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); + SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); } if (ImGui::MenuItem("JSON")) { @@ -523,7 +510,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } NFD_Quit(); - AddRecentFile(filepath, recentSnapshotFiles); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); } ImGui::EndMenu(); @@ -541,7 +528,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } else { - m_snapshot = recentSnapshots.rbegin()->second; + m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); @@ -583,19 +570,19 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } NFD_Quit(); std::cout << "JSON file loaded !" << std::endl; - AddRecentFile(filepath, recentSnapshotFiles); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); } if(ImGui::BeginMenu("Recent Files")) { - if (recentSnapshotFiles.empty() && recentSnapshots.empty()) + if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) { ImGui::MenuItem("(No recent files)", nullptr, false, false); } else { - for (auto file : recentSnapshotFiles) + for (auto file : snapshot_manager.recentSnapshotFiles) { if (ImGui::MenuItem(file.c_str())) { @@ -610,7 +597,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } } - for (auto [name, file] : recentSnapshots) + for (auto [name, file] : snapshot_manager.recentSnapshots) { if(ImGui::MenuItem(name.c_str())) { @@ -834,7 +821,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (showTime) position -= ImGui::CalcTextSize("Time: 000.000 ").x; ImGui::SetCursorPosX(position); - ImGui::Text("Snapshot in memory : %d items ", static_cast(recentSnapshots.size())); + ImGui::Text("Snapshot in memory : %d items ", static_cast(snapshot_manager.recentSnapshots.size())); ImGui::SetCursorPosX(posX); } mainMenuBarSize = ImGui::GetWindowSize(); From 158d1c4d5a484290c920fc4a79efcc7246210884 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Tue, 5 May 2026 09:20:06 +0200 Subject: [PATCH 19/60] update snapshot API --- SofaImGui/CMakeLists.txt | 2 + SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 203 +------------ SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 2 +- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 304 +++++++++++++++++++ SofaImGui/src/SofaImGui/windows/Snapshot.h | 42 +++ 5 files changed, 359 insertions(+), 194 deletions(-) create mode 100644 SofaImGui/src/SofaImGui/windows/Snapshot.cpp create mode 100644 SofaImGui/src/SofaImGui/windows/Snapshot.h diff --git a/SofaImGui/CMakeLists.txt b/SofaImGui/CMakeLists.txt index 5d4fcaaa9f..d3df91e727 100644 --- a/SofaImGui/CMakeLists.txt +++ b/SofaImGui/CMakeLists.txt @@ -120,6 +120,7 @@ set(HEADER_FILES ${SOFAIMGUI_SOURCE_DIR}/windows/DisplayFlags.h ${SOFAIMGUI_SOURCE_DIR}/windows/Plugins.h ${SOFAIMGUI_SOURCE_DIR}/windows/Components.h + ${SOFAIMGUI_SOURCE_DIR}/windows/Snapshot.h ${SOFAIMGUI_SOURCE_DIR}/AppIniFile.h ${SOFAIMGUI_SOURCE_DIR}/windows/WindowState.h ${SOFAIMGUI_SOURCE_DIR}/guis/BaseAdditionalGUI.h @@ -145,6 +146,7 @@ set(SOURCE_FILES ${SOFAIMGUI_SOURCE_DIR}/windows/DisplayFlags.cpp ${SOFAIMGUI_SOURCE_DIR}/windows/Plugins.cpp ${SOFAIMGUI_SOURCE_DIR}/windows/Components.cpp + ${SOFAIMGUI_SOURCE_DIR}/windows/Snapshot.cpp ${SOFAIMGUI_SOURCE_DIR}/windows/Settings.cpp ${SOFAIMGUI_SOURCE_DIR}/windows/ViewPort.cpp ${SOFAIMGUI_SOURCE_DIR}/AppIniFile.cpp diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 633f7d2a64..6df3523245 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -46,6 +46,7 @@ #include "windows/DisplayFlags.h" #include "windows/Log.h" #include "windows/MouseManager.h" +#include "windows/Snapshot.h" #include "windows/Performances.h" #include "windows/Plugins.h" #include "windows/Profiler.h" @@ -81,27 +82,8 @@ #include #include -#include -#include - -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/Base.h" -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotManager.h" -using sofa::core::objectmodel::SnapshotManager; -#include - -// #include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" -using sofa::simulation::SaveSnapshotVisitor; - -#include -using sofa::simulation::LoadDataSnapshotVisitor; - -#include -using sofa::simulation::LoadLinkSnapshotVisitor; - - #include - using namespace sofa; namespace sofaimgui @@ -122,6 +104,7 @@ ImGuiGUIEngine::ImGuiGUIEngine() , winManagerComponents(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("components.txt"))) , winManagerLog(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("log.txt"))) , winManagerMouse(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("mouse.txt"))) + , winManagerSnapshot(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("snapshot.txt"))) , winManagerSettings(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("settings.txt"))) , winManagerViewPort(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("viewport.txt"))) , firstRunState(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("firstrun.txt"))) @@ -348,8 +331,6 @@ void ImGuiGUIEngine::saveScreenshot(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } -SnapshotManager snapshot_manager; - void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_localeBackup = std::setlocale(LC_NUMERIC, nullptr); @@ -397,6 +378,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static constexpr auto windowNameComponents = ICON_FA_LIST " Components"; static constexpr auto windowNameLog = ICON_FA_TERMINAL " Log"; static constexpr auto windowNameMouse = ICON_FA_COMPUTER_MOUSE " Mouse Manager"; + static constexpr auto windowNameSnapshot = ICON_FA_FLOPPY_DISK " Snapshot"; static constexpr auto windowNameSettings = ICON_FA_SLIDERS " Settings"; if (!*firstRunState.getStatePtr()) @@ -410,19 +392,12 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool showFPSInMenuBar = true; static bool showTime = true; - static bool showMemorySnapshot = true; ImVec2 mainMenuBarSize; static bool animate; animate = groot->animate_.getValue(); - //static SnapshotType chosenType = SnapshotType::Print; - - - const int MAX_RECENT_FILES = 10; - - /*************************************** * Main menu bar **************************************/ @@ -462,159 +437,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Separator(); - if (ImGui::BeginMenu("Save Snapshot")) - { - if(ImGui::MenuItem("Memory")) - { - std::cout << "MemorySave !" << std::endl; - - auto m_snapshot = std::make_shared(); - - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - std::string memorySnapshotName = "Memory Snapshot"; - if(!snapshot_manager.recentSnapshotFiles.empty()) - { - memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); - } - - auto snapshotTime = groot->getTime(); - - // SnapshotManager::AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); - SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); - } - if (ImGui::MenuItem("JSON")) - { - auto m_snapshot = std::make_shared(); - NFD_Init(); - - nfdchar_t* savePath; - - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - std::string filepath = "null"; - nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) - { - puts("Save Snapshot success!"); - puts(savePath); - std::string path(savePath); - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - exportTo(*m_snapshot,path); - filepath = savePath; - NFD_FreePath(savePath); - } - else - { - printf("Error: %s\n", NFD_GetError()); - } - - NFD_Quit(); - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); - } - - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Load Snapshot")) - { - if (ImGui::MenuItem("Memory (recent)")) - { - auto m_snapshot = std::make_shared(); - std::cout << "MemoryLoad !" << std::endl; - if(!m_snapshot) - { - std::cout << "Nothing to load..." << std::endl; - } - else - { - m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } - } - - if (ImGui::MenuItem("JSON")) - { - auto m_snapshot = std::make_shared(); - nfdchar_t *outPath = NULL; - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); - std::string filepath = "null"; - if ( result == NFD_OKAY ) - { - puts("Success!"); - puts(outPath); - - if (helper::system::FileSystem::exists(outPath)) - { - importFrom(*m_snapshot,outPath); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - - } - filepath = outPath; - free(outPath); - } - else if ( result == NFD_CANCEL ) - { - puts("User pressed cancel."); - } - else - { - printf("Error: %s\n", NFD_GetError() ); - } - NFD_Quit(); - std::cout << "JSON file loaded !" << std::endl; - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); - - } - - if(ImGui::BeginMenu("Recent Files")) - { - if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) - { - ImGui::MenuItem("(No recent files)", nullptr, false, false); - } - else - { - for (auto file : snapshot_manager.recentSnapshotFiles) - { - if (ImGui::MenuItem(file.c_str())) - { - if(file.ends_with(".json")) - { - auto m_snapshot = std::make_shared(); - importFrom(*m_snapshot,file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } - } - } - for (auto [name, file] : snapshot_manager.recentSnapshots) - { - if(ImGui::MenuItem(name.c_str())) - { - auto m_snapshot = std::make_shared(); - m_snapshot = file; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - } - } - } - ImGui::EndMenu(); - } - ImGui::EndMenu(); - } - - ImGui::Separator(); - if (ImGui::MenuItem("Exit")) { this->terminate(); @@ -707,6 +529,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Checkbox(windowNameMouse, winManagerMouse.getStatePtr()); + ImGui::Checkbox(windowNameSnapshot, winManagerSnapshot.getStatePtr()); + if (guis::MainAdditionGUIRegistry::getAllGUIs().empty() == false) { ImGui::Separator(); @@ -812,18 +636,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Text("Time: %.3f", groot->getTime()); ImGui::SetCursorPosX(posX); } - if (showMemorySnapshot) - { - auto position = ImGui::GetCursorPosX() + ImGui::GetColumnWidth() - ImGui::CalcTextSize("Snapshot in memory : 00 items ").x - - 2 * ImGui::GetStyle().ItemSpacing.x; - if (showFPSInMenuBar) - position -= ImGui::CalcTextSize("1000.0 FPS ").x; - if (showTime) - position -= ImGui::CalcTextSize("Time: 000.000 ").x; - ImGui::SetCursorPosX(position); - ImGui::Text("Snapshot in memory : %d items ", static_cast(snapshot_manager.recentSnapshots.size())); - ImGui::SetCursorPosX(posX); - } mainMenuBarSize = ImGui::GetWindowSize(); ImGui::EndMainMenuBar(); } @@ -903,6 +715,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) **************************************/ windows::showManagerMouseWindow(windowNameMouse, winManagerMouse, baseGUI); + /*************************************** + * Snapshot window + **************************************/ + windows::showSnapshot(windowNameSnapshot, winManagerSnapshot, groot); + /*************************************** * Additional GUIs **************************************/ diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index f30ccf63c3..ee49ab4fe5 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -101,6 +101,7 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine windows::WindowState winManagerComponents; windows::WindowState winManagerLog; windows::WindowState winManagerMouse; + windows::WindowState winManagerSnapshot; windows::WindowState winManagerSettings; windows::WindowState winManagerViewPort; std::map winManagerAdditionalGUIs; @@ -117,7 +118,6 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; - // std::shared_ptr m_snapshot; }; } // namespace sofaimgui diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp new file mode 100644 index 0000000000..e5d7917abc --- /dev/null +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -0,0 +1,304 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation; either version 2 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using sofa::core::objectmodel::SnapshotManager; +#include +using sofa::simulation::SaveSnapshotVisitor; + +#include +using sofa::simulation::LoadDataSnapshotVisitor; + +#include +using sofa::simulation::LoadLinkSnapshotVisitor; + +#include "Snapshot.h" + +namespace windows +{ + SnapshotManager snapshot_manager; + + void showSnapshot(const char* const& windowNameSnapshot, + WindowState& winManagerSnapshot, sofa::core::sptr& groot) { + + if (*winManagerSnapshot.getStatePtr()) + { + if (ImGui::Begin(windowNameSnapshot, winManagerSnapshot.getStatePtr())) + { + static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_Sortable; + if(ImGui::BeginTable("MainTable",2,flags, ImVec2(0.f, 400.f))) + { + ImGui::TableSetupColumn("Save/Load"); + ImGui::TableSetupColumn("Snapshot in memory"); + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); + + ImGui::TableSetColumnIndex(0); + float totalHeight = ImGui::GetContentRegionAvail().y; + float halfHeight = totalHeight * 0.5f - 4.0f; + + ImGui::BeginChild("Save Snapshot", ImVec2(0, halfHeight), true); + ImGui::Text("Save Snapshot"); + ImGui::Separator(); + if (ImGui::Button("Memory")) + { + std::cout << "MemorySave !" << std::endl; + + auto m_snapshot = std::make_shared(); + + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + std::string memorySnapshotName = "Memory Snapshot"; + if(!snapshot_manager.recentSnapshotFiles.empty()) + { + memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); + } + + auto snapshotTime = groot->getTime(); + + SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); + } + if (ImGui::Button("JSON")) + { + auto m_snapshot = std::make_shared(); + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + std::string filepath = "null"; + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) + { + puts("Save Snapshot success!"); + puts(savePath); + std::string path(savePath); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + exportTo(*m_snapshot,path); + filepath = savePath; + NFD_FreePath(savePath); + } + else + { + printf("Error: %s\n", NFD_GetError()); + } + + NFD_Quit(); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); + } + if (ImGui::Button("Groups")) + { + if (!snapshot_manager.recentSnapshots.empty()) + { + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + std::string filepath = "null"; + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) + { + puts(savePath); + std::string path(savePath); + exportTo(snapshot_manager.recentSnapshots, path); + filepath = savePath; + NFD_FreePath(savePath); + } + else + { + printf("Error: %s\n", NFD_GetError()); + } + + } + else + std::cout << "No snapshot" << std::endl; + + } + + + ImGui::EndChild(); + + ImGui::BeginChild("Load Snapshot", ImVec2(0, halfHeight), true); + ImGui::Text("Load Snapshot"); + ImGui::Separator(); + if (ImGui::Button("Memory (recent)")) + { + auto m_snapshot = std::make_shared(); + std::cout << "MemoryLoad !" << std::endl; + if(!m_snapshot) + { + std::cout << "Nothing to load..." << std::endl; + } + else + { + m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(linkvisitor); + } + } + if (ImGui::Button("JSON")) + { + auto m_snapshot = std::make_shared(); + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); + std::string filepath = "null"; + if ( result == NFD_OKAY ) + { + puts("Success!"); + puts(outPath); + + if (sofa::helper::system::FileSystem::exists(outPath)) + { + importFrom(*m_snapshot,outPath); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(linkvisitor); + + } + filepath = outPath; + free(outPath); + } + else if ( result == NFD_CANCEL ) + { + puts("User pressed cancel."); + } + else + { + printf("Error: %s\n", NFD_GetError() ); + } + NFD_Quit(); + std::cout << "JSON file loaded !" << std::endl; + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); + + } + + if (ImGui::Button("Groups")) + { + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); + std::string filepath = "null"; + if ( result == NFD_OKAY ) + { + puts("Success!"); + puts(outPath); + + if (sofa::helper::system::FileSystem::exists(outPath)) + { + sofa::core::objectmodel::separateSnapshots(outPath, snapshot_manager); + } + filepath = outPath; + free(outPath); + } + else if ( result == NFD_CANCEL ) + { + puts("User pressed cancel."); + } + else + { + printf("Error: %s\n", NFD_GetError() ); + } + NFD_Quit(); + } + ImGui::EndChild(); + + ImGui::TableSetColumnIndex(1); + + float listHeight = ImGui::GetContentRegionAvail().y - 8.0f; + + + + ImGui::BeginChild("Recents", ImVec2(0, listHeight), true); + + + + if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) + { + ImGui::TextDisabled("(No recent files)"); + } + else + { + for (auto file : snapshot_manager.recentSnapshotFiles) + { + if (ImGui::Selectable(file.c_str())) + { + if(file.ends_with(".json")) + { + auto m_snapshot = std::make_shared(); + importFrom(*m_snapshot,file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(linkvisitor); + } + } + } + for (auto [name, file] : snapshot_manager.recentSnapshots) + { + if(ImGui::Selectable(name.c_str())) + { + auto m_snapshot = std::make_shared(); + m_snapshot = file; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + } + } + } + ImGui::EndChild(); + } + ImGui::EndTable(); + } + ImGui::End(); + } + } + + + +} diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.h b/SofaImGui/src/SofaImGui/windows/Snapshot.h new file mode 100644 index 0000000000..1b16d64824 --- /dev/null +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.h @@ -0,0 +1,42 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation; either version 2 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include "WindowState.h" + + + +namespace windows +{ + /** + * @brief Shows the Components window. + * + * This function displays a window listing all available components along with their categories. It allows users to select a component to view its details, including name, description, templates, aliases, namespaces, parents, targets, and data properties. + * + * @param windowNameComponents The name of the Components window. + * @param isComponentsWindowOpen A reference to a boolean flag indicating if the Components window is open. + */ + void showSnapshot(const char* const& windowNameSnapshot, + WindowState& winManagerSnapshot,sofa::core::sptr& groot); + +} // namespace sofaimgui From f1a48a390ff09a6f18122f716c9de31fdb8003fa Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Mon, 11 May 2026 10:57:39 +0200 Subject: [PATCH 20/60] update GUI with snapshot --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 27 ++++++++++++-------- SofaImGui/src/SofaImGui/windows/Snapshot.h | 6 ++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index e5d7917abc..ebdac0bdc7 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -47,6 +47,9 @@ using sofa::core::objectmodel::SnapshotManager; #include using sofa::simulation::SaveSnapshotVisitor; +#include +using sofa::simulation::LoadSnapshotVisitor; + #include using sofa::simulation::LoadDataSnapshotVisitor; @@ -175,10 +178,11 @@ namespace windows else { m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); + // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + // groot->execute(linkvisitor); } } if (ImGui::Button("JSON")) @@ -196,10 +200,11 @@ namespace windows if (sofa::helper::system::FileSystem::exists(outPath)) { importFrom(*m_snapshot,outPath); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); + // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + // groot->execute(linkvisitor); } filepath = outPath; @@ -273,10 +278,11 @@ namespace windows { auto m_snapshot = std::make_shared(); importFrom(*m_snapshot,file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); + // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + // groot->execute(linkvisitor); } } } @@ -286,7 +292,8 @@ namespace windows { auto m_snapshot = std::make_shared(); m_snapshot = file; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); } } diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.h b/SofaImGui/src/SofaImGui/windows/Snapshot.h index 1b16d64824..54a183d705 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.h +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.h @@ -29,12 +29,10 @@ namespace windows { /** - * @brief Shows the Components window. + * @brief Shows the Snapshot window. * - * This function displays a window listing all available components along with their categories. It allows users to select a component to view its details, including name, description, templates, aliases, namespaces, parents, targets, and data properties. + * This function displays a window which user can save and load snapshots. * - * @param windowNameComponents The name of the Components window. - * @param isComponentsWindowOpen A reference to a boolean flag indicating if the Components window is open. */ void showSnapshot(const char* const& windowNameSnapshot, WindowState& winManagerSnapshot,sofa::core::sptr& groot); From 72d173969c06711389906450adf9a8974c9a3931 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Mon, 22 Dec 2025 16:39:09 +0100 Subject: [PATCH 21/60] SaveSnapshotv1 --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 0694fd9f63..e2f721f85e 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -80,6 +80,13 @@ #include #include +#include +using sofa::core::objectmodel::SnapshotType; + +#include +using sofa::simulation::SnapshotVisitor; + + #include @@ -214,7 +221,7 @@ void ImGuiGUIEngine::loadFile(sofaglfw::SofaGLFWBaseGUI* baseGUI, sofa::core::sp sofa::simulation::node::unload(groot); groot = sofa::simulation::node::load(filePathName.c_str()); - + if( !groot ) groot = sofa::simulation::getSimulation()->createNewGraph(""); From 4355f6ff034c12d4aef72d95b6e7913417bfd6e3 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 27 Jan 2026 17:58:07 +0100 Subject: [PATCH 22/60] [Snapshot] ADD codes for load a snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index 73cb3ccd8e..01e52db4c9 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -116,6 +116,8 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine static inline constexpr int s_NB_PBOS = 2; GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; + + std::shared_ptr m_baseSnapshot; }; } // namespace sofaimgui From 25a67bbbb43909b69f3c07723a1048d3ff6bee6a Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Wed, 11 Mar 2026 14:49:53 +0100 Subject: [PATCH 23/60] (draft) split data and link visitor for loading --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 183 +++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index e2f721f85e..bf07b490f2 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -83,6 +83,14 @@ #include using sofa::core::objectmodel::SnapshotType; +#include +using sofa::simulation::SaveSnapshotVisitor; + +#include +using sofa::simulation::LoadDataSnapshotVisitor; + +#include +using sofa::simulation::LoadLinkSnapshotVisitor; #include using sofa::simulation::SnapshotVisitor; @@ -448,6 +456,181 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem(ICON_FA_CIRCLE_XMARK " Close Simulation")) doCloseSimulation = true; + { + sofa::simulation::node::unload(groot); + baseGUI->setSimulationIsRunning(false); + sofa::simulation::node::initRoot(baseGUI->getRootNode().get()); + return; + } + + ImGui::Separator(); + + if (ImGui::BeginMenu("Save Snapshot")) + { + if(ImGui::MenuItem("Memory")) + { + chosenType = SnapshotType::Memory; + std::cout << "MemorySave !" << std::endl; + m_baseSnapshot = createSnapshot(chosenType); + auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + std::string memorySnapshotName = "Memory Snapshot"; + if(!recentSnapshotFiles.empty()) + { + memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); + + } + + auto snapshotTime = groot->getTime(); + AddRecentSnapshot(recentSnapshots, m_baseSnapshot, snapshotTime); + } + if (ImGui::MenuItem("JSON")) + { + chosenType = SnapshotType::JSON; + m_baseSnapshot = createSnapshot(chosenType); + + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + std::string filepath = "null"; + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) + { + puts("Save Snapshot success!"); + puts(savePath); + std::string path(savePath); + auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + m_baseSnapshot->exportTo(path); + std::cout << "filepath : " << filepath << std::endl; + std::cout << "savePath : " << savePath << std::endl; + filepath = savePath; + std::cout << "filepath after : " << filepath << std::endl; + NFD_FreePath(savePath); + } + else + { + + printf("Error: %s\n", NFD_GetError()); + } + + NFD_Quit(); + AddRecentFile(filepath, recentSnapshotFiles); + } + + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Load Snapshot")) + { + if (ImGui::MenuItem("Memory (recent)")) + { + std::cout << "MemoryLoad !" << std::endl; + if(!m_baseSnapshot) + { + std::cout << "Nothing to load..." << std::endl; + m_baseSnapshot = createSnapshot(SnapshotType::Memory); + } + else + { + m_baseSnapshot = recentSnapshots.rbegin()->second; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); + } + } + + if (ImGui::MenuItem("JSON")) + { + if(!m_baseSnapshot) + { + m_baseSnapshot = createSnapshot(SnapshotType::JSON); + } + + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); + std::string filepath = "null"; + if ( result == NFD_OKAY ) + { + puts("Success!"); + puts(outPath); + + if (helper::system::FileSystem::exists(outPath)) + { + m_baseSnapshot->importFrom(outPath); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); + + } + filepath = outPath; + free(outPath); + } + else if ( result == NFD_CANCEL ) + { + puts("User pressed cancel."); + } + else + { + printf("Error: %s\n", NFD_GetError() ); + } + NFD_Quit(); + AddRecentFile(filepath, recentSnapshotFiles); + } + + if(ImGui::BeginMenu("Recent Files")) + { + if (recentSnapshotFiles.empty() && recentSnapshots.empty()) + { + ImGui::MenuItem("(No recent files)", nullptr, false, false); + } + else + { + for (auto file : recentSnapshotFiles) + { + if (ImGui::MenuItem(file.c_str())) + { + if(file.ends_with(".json")) + { + m_baseSnapshot = createSnapshot(SnapshotType::JSON); + m_baseSnapshot->importFrom(file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); + } + else + { + m_baseSnapshot = createSnapshot(SnapshotType::Memory); + m_baseSnapshot->importFrom(file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); + } + } + } + for (auto [name, file] : recentSnapshots) + { + if(ImGui::MenuItem(name.c_str())) + { + m_baseSnapshot = file; + m_baseSnapshot->importFrom("none"); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } + } + } + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + ImGui::Separator(); if (ImGui::MenuItem("Exit")) { From 651fea568010eb83409491cac326975e6808158b Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Thu, 19 Mar 2026 17:21:27 +0100 Subject: [PATCH 24/60] update 19/03 --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index bf07b490f2..b3097f283a 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -68,6 +68,7 @@ #include #include //imgui_internal.h is included in order to use the DockspaceBuilder API (which is still in development) #include +#include #include #include #include @@ -580,7 +581,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) printf("Error: %s\n", NFD_GetError() ); } NFD_Quit(); + std::cout << "JSON file loaded !" << std::endl; AddRecentFile(filepath, recentSnapshotFiles); + } if(ImGui::BeginMenu("Recent Files")) From b9192a8178e30f5f5699f313d08f59dfe317bbb5 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Thu, 19 Mar 2026 17:40:02 +0100 Subject: [PATCH 25/60] rename BaseSnapshot to Snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 77 ++++++++++++++-------- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 2 +- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index b3097f283a..17985f909b 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -359,6 +359,29 @@ void ImGuiGUIEngine::saveScreenshot(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } +void AddRecentFile(const std::string& path, std::vector& recentFiles, int maxFiles = 10) +{ + recentFiles.erase( + std::remove(recentFiles.begin(), recentFiles.end(), path), + recentFiles.end() + ); + //recentFiles.insert(recentFiles.begin(), path); + recentFiles.push_back(path); + if (recentFiles.size() > maxFiles) + recentFiles.resize(maxFiles); +} + +void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) +{ + static int index = 0; + recentSnapshots["Memory_Snapshot " + std::to_string(index++) + " at " + std::to_string(snapshotTime)] = snapshot; + if (recentSnapshots.size() > maxSnapshots) + recentSnapshots.erase(recentSnapshots.begin()); +} + +std::vector recentSnapshotFiles; +std::map> recentSnapshots; + void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_localeBackup = std::setlocale(LC_NUMERIC, nullptr); @@ -472,8 +495,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { chosenType = SnapshotType::Memory; std::cout << "MemorySave !" << std::endl; - m_baseSnapshot = createSnapshot(chosenType); - auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = createSnapshot(chosenType); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; if(!recentSnapshotFiles.empty()) @@ -483,12 +506,12 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } auto snapshotTime = groot->getTime(); - AddRecentSnapshot(recentSnapshots, m_baseSnapshot, snapshotTime); + AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); } if (ImGui::MenuItem("JSON")) { chosenType = SnapshotType::JSON; - m_baseSnapshot = createSnapshot(chosenType); + m_snapshot = createSnapshot(chosenType); NFD_Init(); @@ -502,9 +525,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) puts("Save Snapshot success!"); puts(savePath); std::string path(savePath); - auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - m_baseSnapshot->exportTo(path); + m_snapshot->exportTo(path); std::cout << "filepath : " << filepath << std::endl; std::cout << "savePath : " << savePath << std::endl; filepath = savePath; @@ -529,26 +552,26 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem("Memory (recent)")) { std::cout << "MemoryLoad !" << std::endl; - if(!m_baseSnapshot) + if(!m_snapshot) { std::cout << "Nothing to load..." << std::endl; - m_baseSnapshot = createSnapshot(SnapshotType::Memory); + m_snapshot = createSnapshot(SnapshotType::Memory); } else { - m_baseSnapshot = recentSnapshots.rbegin()->second; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = recentSnapshots.rbegin()->second; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } } if (ImGui::MenuItem("JSON")) { - if(!m_baseSnapshot) + if(!m_snapshot) { - m_baseSnapshot = createSnapshot(SnapshotType::JSON); + m_snapshot = createSnapshot(SnapshotType::JSON); } nfdchar_t *outPath = NULL; @@ -562,10 +585,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { - m_baseSnapshot->importFrom(outPath); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot->importFrom(outPath); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } @@ -600,20 +623,20 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(file.ends_with(".json")) { - m_baseSnapshot = createSnapshot(SnapshotType::JSON); - m_baseSnapshot->importFrom(file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = createSnapshot(SnapshotType::JSON); + m_snapshot->importFrom(file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } else { - m_baseSnapshot = createSnapshot(SnapshotType::Memory); - m_baseSnapshot->importFrom(file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = createSnapshot(SnapshotType::Memory); + m_snapshot->importFrom(file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } } @@ -622,9 +645,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(ImGui::MenuItem(name.c_str())) { - m_baseSnapshot = file; - m_baseSnapshot->importFrom("none"); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = file; + m_snapshot->importFrom("none"); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); } } diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index 01e52db4c9..d2e6a80b98 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -117,7 +117,7 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; - std::shared_ptr m_baseSnapshot; + std::shared_ptr m_snapshot; }; } // namespace sofaimgui From fdea4478d8dc3a99521d9acbf026c989426e80df Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Fri, 20 Mar 2026 11:39:24 +0100 Subject: [PATCH 26/60] Refactoring the API of snapshot (Snapshot, SnapshotJSONExporter and SnapshotManager) --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 49 ++++++++-------------- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 2 +- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 17985f909b..97311456e0 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -81,10 +81,11 @@ #include #include -#include -using sofa::core::objectmodel::SnapshotType; +#include #include + +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" using sofa::simulation::SaveSnapshotVisitor; #include @@ -449,6 +450,12 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool animate; animate = groot->animate_.getValue(); + //static SnapshotType chosenType = SnapshotType::Print; + + + const int MAX_RECENT_FILES = 10; + + /*************************************** * Main menu bar **************************************/ @@ -493,16 +500,14 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(ImGui::MenuItem("Memory")) { - chosenType = SnapshotType::Memory; std::cout << "MemorySave !" << std::endl; - m_snapshot = createSnapshot(chosenType); + auto m_snapshot = std::make_shared(); auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; if(!recentSnapshotFiles.empty()) { memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); - } auto snapshotTime = groot->getTime(); @@ -510,9 +515,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } if (ImGui::MenuItem("JSON")) { - chosenType = SnapshotType::JSON; - m_snapshot = createSnapshot(chosenType); - + auto m_snapshot = std::make_shared(); NFD_Init(); nfdchar_t* savePath; @@ -527,11 +530,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) std::string path(savePath); auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - m_snapshot->exportTo(path); - std::cout << "filepath : " << filepath << std::endl; - std::cout << "savePath : " << savePath << std::endl; + exportTo(*m_snapshot,path); filepath = savePath; - std::cout << "filepath after : " << filepath << std::endl; NFD_FreePath(savePath); } else @@ -551,11 +551,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if (ImGui::MenuItem("Memory (recent)")) { + auto m_snapshot = std::make_shared(); std::cout << "MemoryLoad !" << std::endl; if(!m_snapshot) { std::cout << "Nothing to load..." << std::endl; - m_snapshot = createSnapshot(SnapshotType::Memory); } else { @@ -569,11 +569,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem("JSON")) { - if(!m_snapshot) - { - m_snapshot = createSnapshot(SnapshotType::JSON); - } - + auto m_snapshot = std::make_shared(); nfdchar_t *outPath = NULL; nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); @@ -585,7 +581,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { - m_snapshot->importFrom(outPath); + importFrom(*m_snapshot,outPath); auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); @@ -623,17 +619,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(file.ends_with(".json")) { - m_snapshot = createSnapshot(SnapshotType::JSON); - m_snapshot->importFrom(file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } - else - { - m_snapshot = createSnapshot(SnapshotType::Memory); - m_snapshot->importFrom(file); + auto m_snapshot = std::make_shared(); + importFrom(*m_snapshot,file); auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); @@ -645,8 +632,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(ImGui::MenuItem(name.c_str())) { + auto m_snapshot = std::make_shared(); m_snapshot = file; - m_snapshot->importFrom("none"); auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); } diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index d2e6a80b98..f30ccf63c3 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -117,7 +117,7 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; - std::shared_ptr m_snapshot; + // std::shared_ptr m_snapshot; }; } // namespace sofaimgui From b61f319ad4098e85ade19565a0fa5f2ee4324ac8 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Mon, 23 Mar 2026 17:12:44 +0100 Subject: [PATCH 27/60] Fix loadDataSnapshot and update SnapshotManager --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 65 +++++++++++----------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 97311456e0..40bb37b0f8 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -82,10 +82,14 @@ #include #include +#include +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/Base.h" +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotManager.h" +using sofa::core::objectmodel::SnapshotManager; #include -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" +// #include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" using sofa::simulation::SaveSnapshotVisitor; #include @@ -93,8 +97,6 @@ using sofa::simulation::LoadDataSnapshotVisitor; #include using sofa::simulation::LoadLinkSnapshotVisitor; -#include -using sofa::simulation::SnapshotVisitor; #include @@ -360,28 +362,7 @@ void ImGuiGUIEngine::saveScreenshot(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } -void AddRecentFile(const std::string& path, std::vector& recentFiles, int maxFiles = 10) -{ - recentFiles.erase( - std::remove(recentFiles.begin(), recentFiles.end(), path), - recentFiles.end() - ); - //recentFiles.insert(recentFiles.begin(), path); - recentFiles.push_back(path); - if (recentFiles.size() > maxFiles) - recentFiles.resize(maxFiles); -} - -void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) -{ - static int index = 0; - recentSnapshots["Memory_Snapshot " + std::to_string(index++) + " at " + std::to_string(snapshotTime)] = snapshot; - if (recentSnapshots.size() > maxSnapshots) - recentSnapshots.erase(recentSnapshots.begin()); -} - -std::vector recentSnapshotFiles; -std::map> recentSnapshots; +SnapshotManager snapshot_manager; void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { @@ -501,17 +482,21 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(ImGui::MenuItem("Memory")) { std::cout << "MemorySave !" << std::endl; + auto m_snapshot = std::make_shared(); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; - if(!recentSnapshotFiles.empty()) + if(!snapshot_manager.recentSnapshotFiles.empty()) { - memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); + memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); } auto snapshotTime = groot->getTime(); - AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); + + // SnapshotManager::AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); + SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); } if (ImGui::MenuItem("JSON")) { @@ -541,7 +526,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } NFD_Quit(); - AddRecentFile(filepath, recentSnapshotFiles); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); } ImGui::EndMenu(); @@ -559,7 +544,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } else { - m_snapshot = recentSnapshots.rbegin()->second; + m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); @@ -601,19 +586,19 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } NFD_Quit(); std::cout << "JSON file loaded !" << std::endl; - AddRecentFile(filepath, recentSnapshotFiles); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); } if(ImGui::BeginMenu("Recent Files")) { - if (recentSnapshotFiles.empty() && recentSnapshots.empty()) + if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) { ImGui::MenuItem("(No recent files)", nullptr, false, false); } else { - for (auto file : recentSnapshotFiles) + for (auto file : snapshot_manager.recentSnapshotFiles) { if (ImGui::MenuItem(file.c_str())) { @@ -628,7 +613,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } } - for (auto [name, file] : recentSnapshots) + for (auto [name, file] : snapshot_manager.recentSnapshots) { if(ImGui::MenuItem(name.c_str())) { @@ -842,6 +827,18 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Text("Time: %.3f", groot->getTime()); ImGui::SetCursorPosX(posX); } + if (showMemorySnapshot) + { + auto position = ImGui::GetCursorPosX() + ImGui::GetColumnWidth() - ImGui::CalcTextSize("Snapshot in memory : 00 items ").x + - 2 * ImGui::GetStyle().ItemSpacing.x; + if (showFPSInMenuBar) + position -= ImGui::CalcTextSize("1000.0 FPS ").x; + if (showTime) + position -= ImGui::CalcTextSize("Time: 000.000 ").x; + ImGui::SetCursorPosX(position); + ImGui::Text("Snapshot in memory : %d items ", static_cast(snapshot_manager.recentSnapshots.size())); + ImGui::SetCursorPosX(posX); + } mainMenuBarSize = ImGui::GetWindowSize(); ImGui::EndMainMenuBar(); } From 88253ffc2c648b04b305dad712739bca427cddff Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Tue, 5 May 2026 09:20:06 +0200 Subject: [PATCH 28/60] update snapshot API --- SofaImGui/CMakeLists.txt | 2 + SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 49 +-- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 2 +- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 304 +++++++++++++++++++ SofaImGui/src/SofaImGui/windows/Snapshot.h | 42 +++ 5 files changed, 359 insertions(+), 40 deletions(-) create mode 100644 SofaImGui/src/SofaImGui/windows/Snapshot.cpp create mode 100644 SofaImGui/src/SofaImGui/windows/Snapshot.h diff --git a/SofaImGui/CMakeLists.txt b/SofaImGui/CMakeLists.txt index 5d4fcaaa9f..d3df91e727 100644 --- a/SofaImGui/CMakeLists.txt +++ b/SofaImGui/CMakeLists.txt @@ -120,6 +120,7 @@ set(HEADER_FILES ${SOFAIMGUI_SOURCE_DIR}/windows/DisplayFlags.h ${SOFAIMGUI_SOURCE_DIR}/windows/Plugins.h ${SOFAIMGUI_SOURCE_DIR}/windows/Components.h + ${SOFAIMGUI_SOURCE_DIR}/windows/Snapshot.h ${SOFAIMGUI_SOURCE_DIR}/AppIniFile.h ${SOFAIMGUI_SOURCE_DIR}/windows/WindowState.h ${SOFAIMGUI_SOURCE_DIR}/guis/BaseAdditionalGUI.h @@ -145,6 +146,7 @@ set(SOURCE_FILES ${SOFAIMGUI_SOURCE_DIR}/windows/DisplayFlags.cpp ${SOFAIMGUI_SOURCE_DIR}/windows/Plugins.cpp ${SOFAIMGUI_SOURCE_DIR}/windows/Components.cpp + ${SOFAIMGUI_SOURCE_DIR}/windows/Snapshot.cpp ${SOFAIMGUI_SOURCE_DIR}/windows/Settings.cpp ${SOFAIMGUI_SOURCE_DIR}/windows/ViewPort.cpp ${SOFAIMGUI_SOURCE_DIR}/AppIniFile.cpp diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 40bb37b0f8..d5192def7d 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -46,6 +46,7 @@ #include "windows/DisplayFlags.h" #include "windows/Log.h" #include "windows/MouseManager.h" +#include "windows/Snapshot.h" #include "windows/Performances.h" #include "windows/Plugins.h" #include "windows/Profiler.h" @@ -81,27 +82,8 @@ #include #include -#include -#include - -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/Base.h" -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotManager.h" -using sofa::core::objectmodel::SnapshotManager; -#include - -// #include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" -using sofa::simulation::SaveSnapshotVisitor; - -#include -using sofa::simulation::LoadDataSnapshotVisitor; - -#include -using sofa::simulation::LoadLinkSnapshotVisitor; - - #include - using namespace sofa; namespace sofaimgui @@ -122,6 +104,7 @@ ImGuiGUIEngine::ImGuiGUIEngine() , winManagerComponents(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("components.txt"))) , winManagerLog(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("log.txt"))) , winManagerMouse(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("mouse.txt"))) + , winManagerSnapshot(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("snapshot.txt"))) , winManagerSettings(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("settings.txt"))) , winManagerViewPort(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("viewport.txt"))) , firstRunState(helper::system::FileSystem::append(sofaimgui::getConfigurationFolderPath(), std::string("firstrun.txt"))) @@ -362,8 +345,6 @@ void ImGuiGUIEngine::saveScreenshot(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } -SnapshotManager snapshot_manager; - void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_localeBackup = std::setlocale(LC_NUMERIC, nullptr); @@ -411,6 +392,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static constexpr auto windowNameComponents = ICON_FA_LIST " Components"; static constexpr auto windowNameLog = ICON_FA_TERMINAL " Log"; static constexpr auto windowNameMouse = ICON_FA_COMPUTER_MOUSE " Mouse Manager"; + static constexpr auto windowNameSnapshot = ICON_FA_FLOPPY_DISK " Snapshot"; static constexpr auto windowNameSettings = ICON_FA_SLIDERS " Settings"; if (!*firstRunState.getStatePtr()) @@ -431,12 +413,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool animate; animate = groot->animate_.getValue(); - //static SnapshotType chosenType = SnapshotType::Print; - - - const int MAX_RECENT_FILES = 10; - - /*************************************** * Main menu bar **************************************/ @@ -722,6 +698,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Checkbox(windowNameMouse, winManagerMouse.getStatePtr()); + ImGui::Checkbox(windowNameSnapshot, winManagerSnapshot.getStatePtr()); + if (guis::MainAdditionGUIRegistry::getAllGUIs().empty() == false) { ImGui::Separator(); @@ -827,18 +805,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Text("Time: %.3f", groot->getTime()); ImGui::SetCursorPosX(posX); } - if (showMemorySnapshot) - { - auto position = ImGui::GetCursorPosX() + ImGui::GetColumnWidth() - ImGui::CalcTextSize("Snapshot in memory : 00 items ").x - - 2 * ImGui::GetStyle().ItemSpacing.x; - if (showFPSInMenuBar) - position -= ImGui::CalcTextSize("1000.0 FPS ").x; - if (showTime) - position -= ImGui::CalcTextSize("Time: 000.000 ").x; - ImGui::SetCursorPosX(position); - ImGui::Text("Snapshot in memory : %d items ", static_cast(snapshot_manager.recentSnapshots.size())); - ImGui::SetCursorPosX(posX); - } mainMenuBarSize = ImGui::GetWindowSize(); ImGui::EndMainMenuBar(); } @@ -926,6 +892,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) **************************************/ windows::showManagerMouseWindow(windowNameMouse, winManagerMouse, baseGUI); + /*************************************** + * Snapshot window + **************************************/ + windows::showSnapshot(windowNameSnapshot, winManagerSnapshot, groot); + /*************************************** * Additional GUIs **************************************/ diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index f30ccf63c3..ee49ab4fe5 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -101,6 +101,7 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine windows::WindowState winManagerComponents; windows::WindowState winManagerLog; windows::WindowState winManagerMouse; + windows::WindowState winManagerSnapshot; windows::WindowState winManagerSettings; windows::WindowState winManagerViewPort; std::map winManagerAdditionalGUIs; @@ -117,7 +118,6 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; - // std::shared_ptr m_snapshot; }; } // namespace sofaimgui diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp new file mode 100644 index 0000000000..e5d7917abc --- /dev/null +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -0,0 +1,304 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation; either version 2 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using sofa::core::objectmodel::SnapshotManager; +#include +using sofa::simulation::SaveSnapshotVisitor; + +#include +using sofa::simulation::LoadDataSnapshotVisitor; + +#include +using sofa::simulation::LoadLinkSnapshotVisitor; + +#include "Snapshot.h" + +namespace windows +{ + SnapshotManager snapshot_manager; + + void showSnapshot(const char* const& windowNameSnapshot, + WindowState& winManagerSnapshot, sofa::core::sptr& groot) { + + if (*winManagerSnapshot.getStatePtr()) + { + if (ImGui::Begin(windowNameSnapshot, winManagerSnapshot.getStatePtr())) + { + static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_Sortable; + if(ImGui::BeginTable("MainTable",2,flags, ImVec2(0.f, 400.f))) + { + ImGui::TableSetupColumn("Save/Load"); + ImGui::TableSetupColumn("Snapshot in memory"); + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); + + ImGui::TableSetColumnIndex(0); + float totalHeight = ImGui::GetContentRegionAvail().y; + float halfHeight = totalHeight * 0.5f - 4.0f; + + ImGui::BeginChild("Save Snapshot", ImVec2(0, halfHeight), true); + ImGui::Text("Save Snapshot"); + ImGui::Separator(); + if (ImGui::Button("Memory")) + { + std::cout << "MemorySave !" << std::endl; + + auto m_snapshot = std::make_shared(); + + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + std::string memorySnapshotName = "Memory Snapshot"; + if(!snapshot_manager.recentSnapshotFiles.empty()) + { + memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); + } + + auto snapshotTime = groot->getTime(); + + SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); + } + if (ImGui::Button("JSON")) + { + auto m_snapshot = std::make_shared(); + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + std::string filepath = "null"; + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) + { + puts("Save Snapshot success!"); + puts(savePath); + std::string path(savePath); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + exportTo(*m_snapshot,path); + filepath = savePath; + NFD_FreePath(savePath); + } + else + { + printf("Error: %s\n", NFD_GetError()); + } + + NFD_Quit(); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); + } + if (ImGui::Button("Groups")) + { + if (!snapshot_manager.recentSnapshots.empty()) + { + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + std::string filepath = "null"; + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) + { + puts(savePath); + std::string path(savePath); + exportTo(snapshot_manager.recentSnapshots, path); + filepath = savePath; + NFD_FreePath(savePath); + } + else + { + printf("Error: %s\n", NFD_GetError()); + } + + } + else + std::cout << "No snapshot" << std::endl; + + } + + + ImGui::EndChild(); + + ImGui::BeginChild("Load Snapshot", ImVec2(0, halfHeight), true); + ImGui::Text("Load Snapshot"); + ImGui::Separator(); + if (ImGui::Button("Memory (recent)")) + { + auto m_snapshot = std::make_shared(); + std::cout << "MemoryLoad !" << std::endl; + if(!m_snapshot) + { + std::cout << "Nothing to load..." << std::endl; + } + else + { + m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(linkvisitor); + } + } + if (ImGui::Button("JSON")) + { + auto m_snapshot = std::make_shared(); + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); + std::string filepath = "null"; + if ( result == NFD_OKAY ) + { + puts("Success!"); + puts(outPath); + + if (sofa::helper::system::FileSystem::exists(outPath)) + { + importFrom(*m_snapshot,outPath); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(linkvisitor); + + } + filepath = outPath; + free(outPath); + } + else if ( result == NFD_CANCEL ) + { + puts("User pressed cancel."); + } + else + { + printf("Error: %s\n", NFD_GetError() ); + } + NFD_Quit(); + std::cout << "JSON file loaded !" << std::endl; + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); + + } + + if (ImGui::Button("Groups")) + { + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); + std::string filepath = "null"; + if ( result == NFD_OKAY ) + { + puts("Success!"); + puts(outPath); + + if (sofa::helper::system::FileSystem::exists(outPath)) + { + sofa::core::objectmodel::separateSnapshots(outPath, snapshot_manager); + } + filepath = outPath; + free(outPath); + } + else if ( result == NFD_CANCEL ) + { + puts("User pressed cancel."); + } + else + { + printf("Error: %s\n", NFD_GetError() ); + } + NFD_Quit(); + } + ImGui::EndChild(); + + ImGui::TableSetColumnIndex(1); + + float listHeight = ImGui::GetContentRegionAvail().y - 8.0f; + + + + ImGui::BeginChild("Recents", ImVec2(0, listHeight), true); + + + + if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) + { + ImGui::TextDisabled("(No recent files)"); + } + else + { + for (auto file : snapshot_manager.recentSnapshotFiles) + { + if (ImGui::Selectable(file.c_str())) + { + if(file.ends_with(".json")) + { + auto m_snapshot = std::make_shared(); + importFrom(*m_snapshot,file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(linkvisitor); + } + } + } + for (auto [name, file] : snapshot_manager.recentSnapshots) + { + if(ImGui::Selectable(name.c_str())) + { + auto m_snapshot = std::make_shared(); + m_snapshot = file; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + } + } + } + ImGui::EndChild(); + } + ImGui::EndTable(); + } + ImGui::End(); + } + } + + + +} diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.h b/SofaImGui/src/SofaImGui/windows/Snapshot.h new file mode 100644 index 0000000000..1b16d64824 --- /dev/null +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.h @@ -0,0 +1,42 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation; either version 2 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include "WindowState.h" + + + +namespace windows +{ + /** + * @brief Shows the Components window. + * + * This function displays a window listing all available components along with their categories. It allows users to select a component to view its details, including name, description, templates, aliases, namespaces, parents, targets, and data properties. + * + * @param windowNameComponents The name of the Components window. + * @param isComponentsWindowOpen A reference to a boolean flag indicating if the Components window is open. + */ + void showSnapshot(const char* const& windowNameSnapshot, + WindowState& winManagerSnapshot,sofa::core::sptr& groot); + +} // namespace sofaimgui From 1be3685464abd1e24a44819d015d02edad7a0e58 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Mon, 11 May 2026 10:57:39 +0200 Subject: [PATCH 29/60] update GUI with snapshot --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 27 ++++++++++++-------- SofaImGui/src/SofaImGui/windows/Snapshot.h | 6 ++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index e5d7917abc..ebdac0bdc7 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -47,6 +47,9 @@ using sofa::core::objectmodel::SnapshotManager; #include using sofa::simulation::SaveSnapshotVisitor; +#include +using sofa::simulation::LoadSnapshotVisitor; + #include using sofa::simulation::LoadDataSnapshotVisitor; @@ -175,10 +178,11 @@ namespace windows else { m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); + // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + // groot->execute(linkvisitor); } } if (ImGui::Button("JSON")) @@ -196,10 +200,11 @@ namespace windows if (sofa::helper::system::FileSystem::exists(outPath)) { importFrom(*m_snapshot,outPath); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); + // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + // groot->execute(linkvisitor); } filepath = outPath; @@ -273,10 +278,11 @@ namespace windows { auto m_snapshot = std::make_shared(); importFrom(*m_snapshot,file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); + // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + // groot->execute(linkvisitor); } } } @@ -286,7 +292,8 @@ namespace windows { auto m_snapshot = std::make_shared(); m_snapshot = file; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); + auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); } } diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.h b/SofaImGui/src/SofaImGui/windows/Snapshot.h index 1b16d64824..54a183d705 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.h +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.h @@ -29,12 +29,10 @@ namespace windows { /** - * @brief Shows the Components window. + * @brief Shows the Snapshot window. * - * This function displays a window listing all available components along with their categories. It allows users to select a component to view its details, including name, description, templates, aliases, namespaces, parents, targets, and data properties. + * This function displays a window which user can save and load snapshots. * - * @param windowNameComponents The name of the Components window. - * @param isComponentsWindowOpen A reference to a boolean flag indicating if the Components window is open. */ void showSnapshot(const char* const& windowNameSnapshot, WindowState& winManagerSnapshot,sofa::core::sptr& groot); From 163e903ff6fc3c633742d429354b9b3f894ffc09 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Mon, 11 May 2026 14:10:19 +0200 Subject: [PATCH 30/60] fix snapshot menu --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 163 --------------------- 1 file changed, 163 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 963fa8683b..75109a08ec 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -444,170 +444,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem(ICON_FA_CIRCLE_XMARK " Close Simulation")) doCloseSimulation = true; - { - sofa::simulation::node::unload(groot); - baseGUI->setSimulationIsRunning(false); - sofa::simulation::node::initRoot(baseGUI->getRootNode().get()); - return; - } - - ImGui::Separator(); - - if (ImGui::BeginMenu("Save Snapshot")) - { - if(ImGui::MenuItem("Memory")) - { - std::cout << "MemorySave !" << std::endl; - - auto m_snapshot = std::make_shared(); - - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - std::string memorySnapshotName = "Memory Snapshot"; - if(!snapshot_manager.recentSnapshotFiles.empty()) - { - memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); - } - - auto snapshotTime = groot->getTime(); - - // SnapshotManager::AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); - SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); - } - if (ImGui::MenuItem("JSON")) - { - auto m_snapshot = std::make_shared(); - NFD_Init(); - - nfdchar_t* savePath; - - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - std::string filepath = "null"; - nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) - { - puts("Save Snapshot success!"); - puts(savePath); - std::string path(savePath); - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - exportTo(*m_snapshot,path); - filepath = savePath; - NFD_FreePath(savePath); - } - else - { - - printf("Error: %s\n", NFD_GetError()); - } - - NFD_Quit(); - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); - } - - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Load Snapshot")) - { - if (ImGui::MenuItem("Memory (recent)")) - { - auto m_snapshot = std::make_shared(); - std::cout << "MemoryLoad !" << std::endl; - if(!m_snapshot) - { - std::cout << "Nothing to load..." << std::endl; - } - else - { - m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } - } - - if (ImGui::MenuItem("JSON")) - { - auto m_snapshot = std::make_shared(); - nfdchar_t *outPath = NULL; - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); - std::string filepath = "null"; - if ( result == NFD_OKAY ) - { - puts("Success!"); - puts(outPath); - - if (helper::system::FileSystem::exists(outPath)) - { - importFrom(*m_snapshot,outPath); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - - } - filepath = outPath; - free(outPath); - } - else if ( result == NFD_CANCEL ) - { - puts("User pressed cancel."); - } - else - { - printf("Error: %s\n", NFD_GetError() ); - } - NFD_Quit(); - std::cout << "JSON file loaded !" << std::endl; - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); - - } - - if(ImGui::BeginMenu("Recent Files")) - { - if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) - { - ImGui::MenuItem("(No recent files)", nullptr, false, false); - } - else - { - for (auto file : snapshot_manager.recentSnapshotFiles) - { - if (ImGui::MenuItem(file.c_str())) - { - if(file.ends_with(".json")) - { - auto m_snapshot = std::make_shared(); - importFrom(*m_snapshot,file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } - } - } - for (auto [name, file] : snapshot_manager.recentSnapshots) - { - if(ImGui::MenuItem(name.c_str())) - { - auto m_snapshot = std::make_shared(); - m_snapshot = file; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - } - } - } - ImGui::EndMenu(); - } - ImGui::EndMenu(); - } - - ImGui::Separator(); - if (ImGui::MenuItem("Exit")) { this->terminate(); From b0f77018b69f6b7c3d436cf0515d8fa9a1b16d64 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Mon, 22 Dec 2025 16:39:09 +0100 Subject: [PATCH 31/60] SaveSnapshotv1 --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 75109a08ec..9ff2d2238d 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -82,6 +82,13 @@ #include #include +#include +using sofa::core::objectmodel::SnapshotType; + +#include +using sofa::simulation::SnapshotVisitor; + + #include using namespace sofa; @@ -443,8 +450,42 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } if (ImGui::MenuItem(ICON_FA_CIRCLE_XMARK " Close Simulation")) + { + sofa::simulation::node::unload(groot); + baseGUI->setSimulationIsRunning(false); + sofa::simulation::node::initRoot(baseGUI->getRootNode().get()); + return; + } + + ImGui::Separator(); + + if (ImGui::MenuItem(ICON_FA_FOLDER_CLOSED " Save Snapshot")) + { + // sofa::core::objectmodel::Base* b; + + auto JSONSnapCont = createSnapshot(SnapshotType::JSON); + auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); + groot->execute(visitor); + JSONSnapCont->exportToJSON(); + return; + + // Node* root = c.root.get() ; + // auto JSONSnapCont = createSnapshot(SnapshotType::JSON); + // auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); + // root->execute(visitor); + // JSONSnapCont->exportToJSON(); + // sofa::simulation::node::animate(groot.get(), groot->getDt()); + // sofa::simulation::node::updateVisual(groot.get()); + } + + if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) + { + return; + } + doCloseSimulation = true; ImGui::Separator(); + if (ImGui::MenuItem("Exit")) { this->terminate(); From 2e70e9ac0c74aa48d75fd08165b144854a97633c Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 23 Dec 2025 15:34:24 +0100 Subject: [PATCH 32/60] Save Snapshot - choose filename --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 37 ++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 9ff2d2238d..d48900a2c3 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -463,19 +463,38 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { // sofa::core::objectmodel::Base* b; + + auto JSONSnapCont = createSnapshot(SnapshotType::JSON); auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); groot->execute(visitor); - JSONSnapCont->exportToJSON(); - return; + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + - // Node* root = c.root.get() ; - // auto JSONSnapCont = createSnapshot(SnapshotType::JSON); - // auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); - // root->execute(visitor); - // JSONSnapCont->exportToJSON(); - // sofa::simulation::node::animate(groot.get(), groot->getDt()); - // sofa::simulation::node::updateVisual(groot.get()); + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) { + puts("Success!"); + puts(savePath); + + std::string path(savePath); + + JSONSnapCont->exportToJSON(path); + // remember to free the memory (since NFD_OKAY is returned) + NFD_FreePath(savePath); + } else if (result == NFD_CANCEL) { + puts("User pressed cancel."); + } else { + printf("Error: %s\n", NFD_GetError()); + } + + // Quit NFD + NFD_Quit(); + + return; } if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) From 978ec7f780dec8dc0d50b133837d5b92ea3a7caa Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 6 Jan 2026 16:15:59 +0100 Subject: [PATCH 33/60] new feature : select type of snapshot (only JSON) --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index d48900a2c3..8fe7e02f4b 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -420,6 +420,15 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool animate; animate = groot->animate_.getValue(); + enum class SaveStep + { + None, + ChooseType, + OpenFileDialog + }; + + static SaveStep saveStep = SaveStep::None; + /*************************************** * Main menu bar **************************************/ @@ -460,6 +469,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Separator(); if (ImGui::MenuItem(ICON_FA_FOLDER_CLOSED " Save Snapshot")) + { + saveStep = SaveStep::ChooseType; { // sofa::core::objectmodel::Base* b; @@ -716,6 +727,62 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) return; } + if (saveStep == SaveStep::ChooseType) + { + ImGui::OpenPopup("SnapshotTypeChoice"); + } + + if ( ImGui::BeginPopupModal("SnapshotTypeChoice", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("Choose type of snapshot"); + ImGui::Separator(); + if (ImGui::Button("JSON")) + { + saveStep = SaveStep::OpenFileDialog; + + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("nothing")) + { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + + if(saveStep == SaveStep::OpenFileDialog) + { + + auto SnapCont = createSnapshot(SnapshotType::JSON); + auto visitor = SnapshotVisitor(nullptr,*SnapCont); + groot->execute(visitor); + + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) { + puts("Save Snapshot success!"); + puts(savePath); + + std::string path(savePath); + + SnapCont->exportToJSON(path); // Problem : i want to change this (avoid JSON) + // remember to free the memory (since NFD_OKAY is returned) + NFD_FreePath(savePath); + } else { + printf("Error: %s\n", NFD_GetError()); + } + + // Quit NFD + NFD_Quit(); + saveStep = SaveStep::None; + } + if (m_imguiNeedViewReset) { resetView(dockspace_id, windowNameSceneGraph, windowNameSelectionDescription, windowNameLog, windowNameViewport); From 7abea116c6e91ad993879a9982d133225ee5c98f Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 13 Jan 2026 09:22:08 +0100 Subject: [PATCH 34/60] fix tree structure SaveSnapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 8fe7e02f4b..70dabaa9f3 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -428,7 +428,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) }; static SaveStep saveStep = SaveStep::None; - + static SnapshotType chosenType = SnapshotType::Print; /*************************************** * Main menu bar **************************************/ @@ -739,6 +739,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Separator(); if (ImGui::Button("JSON")) { + chosenType = SnapshotType::JSON; saveStep = SaveStep::OpenFileDialog; ImGui::CloseCurrentPopup(); @@ -755,6 +756,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { auto SnapCont = createSnapshot(SnapshotType::JSON); + + // auto SnapCont = createSnapshot(SnapshotType::JSON); + auto SnapCont = createSnapshot(chosenType); auto visitor = SnapshotVisitor(nullptr,*SnapCont); groot->execute(visitor); @@ -771,7 +775,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) std::string path(savePath); - SnapCont->exportToJSON(path); // Problem : i want to change this (avoid JSON) + SnapCont->exportTo(path); // remember to free the memory (since NFD_OKAY is returned) NFD_FreePath(savePath); } else { From f10335e4f959128e1ce92a1f0ac2c70e56f74a94 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Mon, 26 Jan 2026 11:17:52 +0100 Subject: [PATCH 35/60] update Snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 97 +++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 70dabaa9f3..45fea5ae8a 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -428,6 +428,16 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) }; static SaveStep saveStep = SaveStep::None; + + enum class LoadStep + { + None, + ChooseType, + OpenFileDialog + }; + + static LoadStep loadStep = LoadStep::None; + static SnapshotType chosenType = SnapshotType::Print; /*************************************** * Main menu bar @@ -510,7 +520,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) { - return; + loadStep = LoadStep::ChooseType; + } doCloseSimulation = true; @@ -732,6 +743,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::OpenPopup("SnapshotTypeChoice"); } + if (loadStep == LoadStep::ChooseType) + { + ImGui::OpenPopup("LoadSnapshotTypeChoice"); + } + if ( ImGui::BeginPopupModal("SnapshotTypeChoice", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { @@ -752,6 +768,26 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::EndPopup(); } + if ( ImGui::BeginPopupModal("LoadSnapshotTypeChoice", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("Choose type of snapshot"); + ImGui::Separator(); + if (ImGui::Button("JSON")) + { + chosenType = SnapshotType::JSON; + loadStep = LoadStep::OpenFileDialog; + + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("nothing")) + { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if(saveStep == SaveStep::OpenFileDialog) { @@ -759,9 +795,32 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) // auto SnapCont = createSnapshot(SnapshotType::JSON); auto SnapCont = createSnapshot(chosenType); - auto visitor = SnapshotVisitor(nullptr,*SnapCont); + auto rootSnapNode = std::make_shared(); + rootSnapNode->name = "root"; + // SnapNode_.nodeName = "root"; + std::cout << "IMGUI " << std::endl; + auto visitor = SnapshotVisitor(nullptr,*SnapCont, *rootSnapNode); groot->execute(visitor); + std::ofstream file("dumpStateTest.txt"); + sofa::simulation::node::dumpState(groot.get(),file); + file.close(); + + for(auto element : rootSnapNode->componentList) + { + std::cout <<"dans rootSnapNode : " << element.name << std::endl; + } + + std::cout << "######" << std::endl; + + for(auto element : rootSnapNode->childNode) + { + std::cout <<"dans rootSnapNode : " << element->name << std::endl; + for(auto compelement : element->componentList) + { + std::cout << "components: " << compelement.name << std::endl; + } + } NFD_Init(); nfdchar_t* savePath; @@ -787,6 +846,40 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) saveStep = SaveStep::None; } + if(loadStep == LoadStep::OpenFileDialog) + { + auto SnapCont = createSnapshot(chosenType); + + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); + // nfdresult_t result = NFD_OpenDialog(&outPath, nfd_filters.data(), nfd_filters.size(), NULL); + if ( result == NFD_OKAY ) + { + puts("Success!"); + puts(outPath); + + if (helper::system::FileSystem::exists(outPath)) + { + //loadFile(baseGUI, groot, outPath, false); + SnapCont->importSnapshot(outPath); + + } + free(outPath); + } + else if ( result == NFD_CANCEL ) + { + puts("User pressed cancel."); + } + else + { + printf("Error: %s\n", NFD_GetError() ); + } + NFD_Quit(); + loadStep = LoadStep::None; + // call loadSnapshot ? to transfer data/link into their fields + } + if (m_imguiNeedViewReset) { resetView(dockspace_id, windowNameSceneGraph, windowNameSelectionDescription, windowNameLog, windowNameViewport); From f145ee57bfd24a57d603e58d021bb3aee52b0679 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 27 Jan 2026 17:58:07 +0100 Subject: [PATCH 36/60] [Snapshot] ADD codes for load a snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 79 ++++++++++++++++++++-- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 2 + 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 45fea5ae8a..78e29995b3 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -88,6 +88,9 @@ using sofa::core::objectmodel::SnapshotType; #include using sofa::simulation::SnapshotVisitor; +#include +using sofa::simulation::LoadSnapshotVisitor; + #include @@ -424,7 +427,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { None, ChooseType, - OpenFileDialog + OpenFileDialog, + MemorySave }; static SaveStep saveStep = SaveStep::None; @@ -433,7 +437,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { None, ChooseType, - OpenFileDialog + OpenFileDialog, + MemorySave }; static LoadStep loadStep = LoadStep::None; @@ -764,8 +769,17 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::Button("nothing")) { ImGui::CloseCurrentPopup(); + saveStep = SaveStep::None; + } + ImGui::SameLine(); + if (ImGui::Button("Memory")) + { + chosenType = SnapshotType::Memory; + saveStep = SaveStep::MemorySave; + ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); + } if ( ImGui::BeginPopupModal("LoadSnapshotTypeChoice", nullptr, @@ -784,8 +798,17 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::Button("nothing")) { ImGui::CloseCurrentPopup(); + loadStep = LoadStep::None; + } + ImGui::SameLine(); + if (ImGui::Button("Memory")) + { + chosenType = SnapshotType::Memory; + loadStep = LoadStep::MemorySave; + ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); + } if(saveStep == SaveStep::OpenFileDialog) @@ -821,6 +844,12 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) std::cout << "components: " << compelement.name << std::endl; } } + //auto SnapCont = createSnapshot(chosenType); + //SnapCont->printSnapshot(); + m_baseSnapshot = createSnapshot(chosenType); + m_baseSnapshot->printSnapshot(); + // auto visitor = SnapshotVisitor(nullptr,*SnapCont); + NFD_Init(); nfdchar_t* savePath; @@ -833,8 +862,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) puts(savePath); std::string path(savePath); - - SnapCont->exportTo(path); + auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + // SnapCont->exportTo(path); + m_baseSnapshot->exportTo(path); // remember to free the memory (since NFD_OKAY is returned) NFD_FreePath(savePath); } else { @@ -843,12 +874,29 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) // Quit NFD NFD_Quit(); + // SnapCont->printSnapshot(); + m_baseSnapshot->printSnapshot(); + saveStep = SaveStep::None; + } + + if (saveStep == SaveStep::MemorySave) + { + std::cout << "MemorySave begin : " << std::endl; + m_baseSnapshot = createSnapshot(chosenType); + m_baseSnapshot->printSnapshot(); + auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } if(loadStep == LoadStep::OpenFileDialog) { - auto SnapCont = createSnapshot(chosenType); + if(!m_baseSnapshot) + { + m_baseSnapshot = createSnapshot(chosenType); + } + nfdchar_t *outPath = NULL; nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; @@ -862,8 +910,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { //loadFile(baseGUI, groot, outPath, false); - SnapCont->importSnapshot(outPath); - + m_baseSnapshot->importFrom(outPath); + //m_baseSnapshot->printSnapshot(); + //auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + //groot->execute(visitor); } free(outPath); } @@ -876,10 +926,25 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) printf("Error: %s\n", NFD_GetError() ); } NFD_Quit(); + + + loadStep = LoadStep::None; // call loadSnapshot ? to transfer data/link into their fields } + if (loadStep == LoadStep::MemorySave) + { + if(!m_baseSnapshot) + { + m_baseSnapshot = createSnapshot(chosenType); + } + + m_baseSnapshot->printSnapshot(); + + loadStep = LoadStep::None; + } + if (m_imguiNeedViewReset) { resetView(dockspace_id, windowNameSceneGraph, windowNameSelectionDescription, windowNameLog, windowNameViewport); diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index ee49ab4fe5..d9db5d7cc4 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -118,6 +118,8 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; + + std::shared_ptr m_baseSnapshot; }; } // namespace sofaimgui From 5c909cda231fec49978255e80e7d469f782195d1 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Wed, 28 Jan 2026 09:32:02 +0100 Subject: [PATCH 37/60] clean some comments --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 78e29995b3..85f99131cc 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -846,8 +846,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } //auto SnapCont = createSnapshot(chosenType); //SnapCont->printSnapshot(); + { m_baseSnapshot = createSnapshot(chosenType); m_baseSnapshot->printSnapshot(); + // auto visitor = SnapshotVisitor(nullptr,*SnapCont); NFD_Init(); @@ -864,7 +866,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) std::string path(savePath); auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); - // SnapCont->exportTo(path); + m_baseSnapshot->exportTo(path); // remember to free the memory (since NFD_OKAY is returned) NFD_FreePath(savePath); @@ -874,7 +876,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) // Quit NFD NFD_Quit(); - // SnapCont->printSnapshot(); m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } @@ -898,10 +899,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } + nfdchar_t *outPath = NULL; nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); - // nfdresult_t result = NFD_OpenDialog(&outPath, nfd_filters.data(), nfd_filters.size(), NULL); + if ( result == NFD_OKAY ) { puts("Success!"); @@ -930,7 +932,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) loadStep = LoadStep::None; - // call loadSnapshot ? to transfer data/link into their fields + } if (loadStep == LoadStep::MemorySave) From e35af876d6dac7b3ee87f56571e4c885333a82cf Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 3 Feb 2026 09:29:00 +0100 Subject: [PATCH 38/60] [SNAPSHOT] FIX save and load snapshotAPI --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 85f99131cc..6fef96f047 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -852,6 +852,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) // auto visitor = SnapshotVisitor(nullptr,*SnapCont); + // m_baseSnapshot->printSnapshot(); + NFD_Init(); nfdchar_t* savePath; @@ -876,18 +878,16 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) // Quit NFD NFD_Quit(); - m_baseSnapshot->printSnapshot(); + // m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } if (saveStep == SaveStep::MemorySave) { - std::cout << "MemorySave begin : " << std::endl; + std::cout << "MemorySave !" << std::endl; m_baseSnapshot = createSnapshot(chosenType); - m_baseSnapshot->printSnapshot(); auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); - m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } @@ -913,7 +913,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { //loadFile(baseGUI, groot, outPath, false); m_baseSnapshot->importFrom(outPath); - //m_baseSnapshot->printSnapshot(); + // //m_baseSnapshot->printSnapshot(); //auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); //groot->execute(visitor); } @@ -937,10 +937,16 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (loadStep == LoadStep::MemorySave) { + std::cout << "MemoryLoad !" << std::endl; if(!m_baseSnapshot) { + std::cout << "Nothing to load..." << std::endl; m_baseSnapshot = createSnapshot(chosenType); } + else + { + m_baseSnapshot->importSnapshot("test"); + } m_baseSnapshot->printSnapshot(); From 0a09581ff1ab05fe7894e62af7fe4f926c7dfbf7 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Mon, 9 Feb 2026 09:43:54 +0100 Subject: [PATCH 39/60] Update laodSnapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 6fef96f047..bc243f335e 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -945,7 +945,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } else { - m_baseSnapshot->importSnapshot("test"); + m_baseSnapshot->importSnapshot("none"); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); } m_baseSnapshot->printSnapshot(); From fc58501f91515ac00f142c63d6501d1077ccedd9 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Wed, 25 Feb 2026 11:44:32 +0100 Subject: [PATCH 40/60] [Snapshot] Fix LoadSnapshot for JSON --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index bc243f335e..860185f3d6 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -854,6 +854,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) // m_baseSnapshot->printSnapshot(); + NFD_Init(); nfdchar_t* savePath; @@ -861,24 +862,23 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) { + if (result == NFD_OKAY) + { puts("Save Snapshot success!"); puts(savePath); - std::string path(savePath); auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); m_baseSnapshot->exportTo(path); - // remember to free the memory (since NFD_OKAY is returned) NFD_FreePath(savePath); - } else { + } + else + { printf("Error: %s\n", NFD_GetError()); } - // Quit NFD NFD_Quit(); - // m_baseSnapshot->printSnapshot(); saveStep = SaveStep::None; } @@ -911,11 +911,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { - //loadFile(baseGUI, groot, outPath, false); m_baseSnapshot->importFrom(outPath); - // //m_baseSnapshot->printSnapshot(); - //auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); - //groot->execute(visitor); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } free(outPath); } From 56480f631899235a371f949fb41875af5896b8df Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Thu, 26 Feb 2026 11:39:06 +0100 Subject: [PATCH 41/60] modify API for save/load snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 221 +++++++++++++++++++-- 1 file changed, 201 insertions(+), 20 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 860185f3d6..215a9a819c 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -355,6 +355,29 @@ void ImGuiGUIEngine::saveScreenshot(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } +void AddRecentFile(const std::string& path, std::vector& recentFiles, int maxFiles = 10) +{ + recentFiles.erase( + std::remove(recentFiles.begin(), recentFiles.end(), path), + recentFiles.end() + ); + //recentFiles.insert(recentFiles.begin(), path); + recentFiles.push_back(path); + if (recentFiles.size() > maxFiles) + recentFiles.resize(maxFiles); +} + +void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) +{ + static int index = 0; + recentSnapshots["Memory_Snapshot " + std::to_string(index++) + " at " + std::to_string(snapshotTime)] = snapshot; + if (recentSnapshots.size() > maxSnapshots) + recentSnapshots.erase(recentSnapshots.begin()); +} + +std::vector recentSnapshotFiles; +std::map> recentSnapshots; + void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_localeBackup = std::setlocale(LC_NUMERIC, nullptr); @@ -416,6 +439,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool showFPSInMenuBar = true; static bool showTime = true; + static bool showMemorySnapshot = true; ImVec2 mainMenuBarSize; bool doCloseSimulation = false; @@ -423,27 +447,12 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool animate; animate = groot->animate_.getValue(); - enum class SaveStep - { - None, - ChooseType, - OpenFileDialog, - MemorySave - }; + static SnapshotType chosenType = SnapshotType::Print; - static SaveStep saveStep = SaveStep::None; - enum class LoadStep - { - None, - ChooseType, - OpenFileDialog, - MemorySave - }; + const int MAX_RECENT_FILES = 10; - static LoadStep loadStep = LoadStep::None; - static SnapshotType chosenType = SnapshotType::Print; /*************************************** * Main menu bar **************************************/ @@ -527,6 +536,166 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { loadStep = LoadStep::ChooseType; + if (ImGui::BeginMenu("Save Snapshot")) + { + if(ImGui::MenuItem("Memory")) + { + chosenType = SnapshotType::Memory; + std::cout << "MemorySave !" << std::endl; + m_baseSnapshot = createSnapshot(chosenType); + auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + std::string memorySnapshotName = "Memory Snapshot"; + if(!recentSnapshotFiles.empty()) + { + memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); + + } + + auto snapshotTime = groot->getTime(); + AddRecentSnapshot(recentSnapshots, m_baseSnapshot, snapshotTime); + } + if (ImGui::MenuItem("JSON")) + { + chosenType = SnapshotType::JSON; + m_baseSnapshot = createSnapshot(chosenType); + + NFD_Init(); + + nfdchar_t* savePath; + + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + std::string filepath = "null"; + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); + if (result == NFD_OKAY) + { + puts("Save Snapshot success!"); + puts(savePath); + std::string path(savePath); + auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + m_baseSnapshot->exportTo(path); + std::cout << "filepath : " << filepath << std::endl; + std::cout << "savePath : " << savePath << std::endl; + filepath = savePath; + std::cout << "filepath after : " << filepath << std::endl; + NFD_FreePath(savePath); + } + else + { + + printf("Error: %s\n", NFD_GetError()); + } + + NFD_Quit(); + AddRecentFile(filepath, recentSnapshotFiles); + } + + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Load Snapshot")) + { + if (ImGui::MenuItem("Memory (recent)")) + { + std::cout << "MemoryLoad !" << std::endl; + if(!m_baseSnapshot) + { + std::cout << "Nothing to load..." << std::endl; + m_baseSnapshot = createSnapshot(SnapshotType::Memory); + } + else + { + m_baseSnapshot = recentSnapshots.rbegin()->second; + m_baseSnapshot->importSnapshot("none"); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } + } + + if (ImGui::MenuItem("JSON")) + { + if(!m_baseSnapshot) + { + m_baseSnapshot = createSnapshot(SnapshotType::JSON); + } + + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); + std::string filepath = "null"; + if ( result == NFD_OKAY ) + { + puts("Success!"); + puts(outPath); + + if (helper::system::FileSystem::exists(outPath)) + { + m_baseSnapshot->importFrom(outPath); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + + } + filepath = outPath; + free(outPath); + } + else if ( result == NFD_CANCEL ) + { + puts("User pressed cancel."); + } + else + { + printf("Error: %s\n", NFD_GetError() ); + } + NFD_Quit(); + AddRecentFile(filepath, recentSnapshotFiles); + } + + if(ImGui::BeginMenu("Recent Files")) + { + if (recentSnapshotFiles.empty() && recentSnapshots.empty()) + { + ImGui::MenuItem("(No recent files)", nullptr, false, false); + } + else + { + for (auto file : recentSnapshotFiles) + { + if (ImGui::MenuItem(file.c_str())) + { + if(file.ends_with(".json")) + { + m_baseSnapshot = createSnapshot(SnapshotType::JSON); + std::cout << "file de MenuItem : " << file << std::endl; + m_baseSnapshot->importFrom(file); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } + else + { + m_baseSnapshot = createSnapshot(SnapshotType::Memory); + std::cout << "file de MenuItem : " << file << std::endl; + m_baseSnapshot->importFrom(file); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } + } + } + for (auto [name, file] : recentSnapshots) + { + if(ImGui::MenuItem(name.c_str())) + { + m_baseSnapshot = file; + std::cout << "file de MenuItem : " << name << std::endl; + m_baseSnapshot->importFrom("none"); + auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(visitor); + } + } + } + ImGui::EndMenu(); + } + ImGui::EndMenu(); } doCloseSimulation = true; @@ -731,6 +900,18 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Text("Time: %.3f", groot->getTime()); ImGui::SetCursorPosX(posX); } + if (showMemorySnapshot) + { + auto position = ImGui::GetCursorPosX() + ImGui::GetColumnWidth() - ImGui::CalcTextSize("Snapshot in memory : 00 items ").x + - 2 * ImGui::GetStyle().ItemSpacing.x; + if (showFPSInMenuBar) + position -= ImGui::CalcTextSize("1000.0 FPS ").x; + if (showTime) + position -= ImGui::CalcTextSize("Time: 000.000 ").x; + ImGui::SetCursorPosX(position); + ImGui::Text("Snapshot in memory : %d items ", static_cast(recentSnapshots.size())); + ImGui::SetCursorPosX(posX); + } mainMenuBarSize = ImGui::GetWindowSize(); ImGui::EndMainMenuBar(); } @@ -791,7 +972,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { chosenType = SnapshotType::JSON; loadStep = LoadStep::OpenFileDialog; - + ImGui::CloseCurrentPopup(); } ImGui::SameLine(); @@ -908,7 +1089,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { puts("Success!"); puts(outPath); - + if (helper::system::FileSystem::exists(outPath)) { m_baseSnapshot->importFrom(outPath); @@ -922,7 +1103,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { puts("User pressed cancel."); } - else + else { printf("Error: %s\n", NFD_GetError() ); } From b57bc89d28c8efd2e19df35c5cfaf9571f6682c7 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Fri, 27 Feb 2026 18:11:12 +0100 Subject: [PATCH 42/60] clean 27/02 --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 215a9a819c..6a5cac27e6 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -666,7 +666,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(file.ends_with(".json")) { m_baseSnapshot = createSnapshot(SnapshotType::JSON); - std::cout << "file de MenuItem : " << file << std::endl; m_baseSnapshot->importFrom(file); auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); @@ -674,7 +673,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) else { m_baseSnapshot = createSnapshot(SnapshotType::Memory); - std::cout << "file de MenuItem : " << file << std::endl; m_baseSnapshot->importFrom(file); auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); @@ -686,7 +684,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(ImGui::MenuItem(name.c_str())) { m_baseSnapshot = file; - std::cout << "file de MenuItem : " << name << std::endl; m_baseSnapshot->importFrom("none"); auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); From 9f477c6d892b95846e05796d20c80e8402bf8c76 Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Tue, 3 Mar 2026 16:44:55 +0100 Subject: [PATCH 43/60] Renaming SnapshotVisitor to SaveSnapshotVisitor --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 6a5cac27e6..bef3502ec8 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -85,8 +85,8 @@ #include using sofa::core::objectmodel::SnapshotType; -#include -using sofa::simulation::SnapshotVisitor; +#include +using sofa::simulation::SaveSnapshotVisitor; #include using sofa::simulation::LoadSnapshotVisitor; @@ -543,7 +543,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) chosenType = SnapshotType::Memory; std::cout << "MemorySave !" << std::endl; m_baseSnapshot = createSnapshot(chosenType); - auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; if(!recentSnapshotFiles.empty()) @@ -572,7 +572,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) puts("Save Snapshot success!"); puts(savePath); std::string path(savePath); - auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); m_baseSnapshot->exportTo(path); std::cout << "filepath : " << filepath << std::endl; From 22ba5a9f5e2566ac0ea5a6608dd235019d9286aa Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Wed, 11 Mar 2026 14:49:53 +0100 Subject: [PATCH 44/60] (draft) split data and link visitor for loading --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 27 ++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index bef3502ec8..e8e08b9ef2 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -88,8 +88,11 @@ using sofa::core::objectmodel::SnapshotType; #include using sofa::simulation::SaveSnapshotVisitor; -#include -using sofa::simulation::LoadSnapshotVisitor; +#include +using sofa::simulation::LoadDataSnapshotVisitor; + +#include +using sofa::simulation::LoadLinkSnapshotVisitor; #include @@ -535,7 +538,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) { loadStep = LoadStep::ChooseType; - + if (ImGui::BeginMenu("Save Snapshot")) { if(ImGui::MenuItem("Memory")) @@ -609,7 +612,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) m_baseSnapshot = recentSnapshots.rbegin()->second; m_baseSnapshot->importSnapshot("none"); auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + m_baseSnapshot = recentSnapshots.rbegin()->second; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); } } @@ -632,8 +639,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { m_baseSnapshot->importFrom(outPath); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); } filepath = outPath; @@ -667,15 +676,19 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_baseSnapshot = createSnapshot(SnapshotType::JSON); m_baseSnapshot->importFrom(file); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); } else { m_baseSnapshot = createSnapshot(SnapshotType::Memory); m_baseSnapshot->importFrom(file); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + groot->execute(linkvisitor); } } } @@ -685,7 +698,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_baseSnapshot = file; m_baseSnapshot->importFrom("none"); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); groot->execute(visitor); } } From 28b7c7b387f48b1eb2ca57857f63a1c22194502d Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Thu, 19 Mar 2026 17:21:27 +0100 Subject: [PATCH 45/60] update 19/03 --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index e8e08b9ef2..112d8dce3d 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -657,7 +657,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) printf("Error: %s\n", NFD_GetError() ); } NFD_Quit(); + std::cout << "JSON file loaded !" << std::endl; AddRecentFile(filepath, recentSnapshotFiles); + } if(ImGui::BeginMenu("Recent Files")) From 290881fe17f0dcdd637cf59c84e356823d48df2e Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Thu, 19 Mar 2026 17:40:02 +0100 Subject: [PATCH 46/60] rename BaseSnapshot to Snapshot --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 56 +++++++++++----------- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 1 + 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 112d8dce3d..4ae2eaec2f 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -370,7 +370,7 @@ void AddRecentFile(const std::string& path, std::vector& recentFile recentFiles.resize(maxFiles); } -void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) +void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) { static int index = 0; recentSnapshots["Memory_Snapshot " + std::to_string(index++) + " at " + std::to_string(snapshotTime)] = snapshot; @@ -379,7 +379,7 @@ void AddRecentSnapshot(std::map recentSnapshotFiles; -std::map> recentSnapshots; +std::map> recentSnapshots; void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { @@ -545,8 +545,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { chosenType = SnapshotType::Memory; std::cout << "MemorySave !" << std::endl; - m_baseSnapshot = createSnapshot(chosenType); - auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = createSnapshot(chosenType); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; if(!recentSnapshotFiles.empty()) @@ -556,12 +556,12 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } auto snapshotTime = groot->getTime(); - AddRecentSnapshot(recentSnapshots, m_baseSnapshot, snapshotTime); + AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); } if (ImGui::MenuItem("JSON")) { chosenType = SnapshotType::JSON; - m_baseSnapshot = createSnapshot(chosenType); + m_snapshot = createSnapshot(chosenType); NFD_Init(); @@ -575,9 +575,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) puts("Save Snapshot success!"); puts(savePath); std::string path(savePath); - auto visitor = SaveSnapshotVisitor(nullptr,*m_baseSnapshot); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - m_baseSnapshot->exportTo(path); + m_snapshot->exportTo(path); std::cout << "filepath : " << filepath << std::endl; std::cout << "savePath : " << savePath << std::endl; filepath = savePath; @@ -602,10 +602,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem("Memory (recent)")) { std::cout << "MemoryLoad !" << std::endl; - if(!m_baseSnapshot) + if(!m_snapshot) { std::cout << "Nothing to load..." << std::endl; - m_baseSnapshot = createSnapshot(SnapshotType::Memory); + m_snapshot = createSnapshot(SnapshotType::Memory); } else { @@ -614,17 +614,19 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); m_baseSnapshot = recentSnapshots.rbegin()->second; auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = recentSnapshots.rbegin()->second; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } } if (ImGui::MenuItem("JSON")) { - if(!m_baseSnapshot) + if(!m_snapshot) { - m_baseSnapshot = createSnapshot(SnapshotType::JSON); + m_snapshot = createSnapshot(SnapshotType::JSON); } nfdchar_t *outPath = NULL; @@ -638,10 +640,10 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { - m_baseSnapshot->importFrom(outPath); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot->importFrom(outPath); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } @@ -676,20 +678,20 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(file.ends_with(".json")) { - m_baseSnapshot = createSnapshot(SnapshotType::JSON); - m_baseSnapshot->importFrom(file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = createSnapshot(SnapshotType::JSON); + m_snapshot->importFrom(file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } else { - m_baseSnapshot = createSnapshot(SnapshotType::Memory); - m_baseSnapshot->importFrom(file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = createSnapshot(SnapshotType::Memory); + m_snapshot->importFrom(file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_baseSnapshot); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } } @@ -698,9 +700,9 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(ImGui::MenuItem(name.c_str())) { - m_baseSnapshot = file; - m_baseSnapshot->importFrom("none"); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); + m_snapshot = file; + m_snapshot->importFrom("none"); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); } } diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index d9db5d7cc4..56346c9813 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -118,6 +118,7 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; + std::shared_ptr m_snapshot; std::shared_ptr m_baseSnapshot; }; From f3929df2b54977b1b2a92be4a51f0b2ededbb979 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Fri, 20 Mar 2026 11:39:24 +0100 Subject: [PATCH 47/60] Refactoring the API of snapshot (Snapshot, SnapshotJSONExporter and SnapshotManager) --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 40 +++++++--------------- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 1 + 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 4ae2eaec2f..361dc44a63 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -82,10 +82,11 @@ #include #include -#include -using sofa::core::objectmodel::SnapshotType; +#include #include + +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" using sofa::simulation::SaveSnapshotVisitor; #include @@ -450,7 +451,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool animate; animate = groot->animate_.getValue(); - static SnapshotType chosenType = SnapshotType::Print; + //static SnapshotType chosenType = SnapshotType::Print; const int MAX_RECENT_FILES = 10; @@ -543,16 +544,14 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(ImGui::MenuItem("Memory")) { - chosenType = SnapshotType::Memory; std::cout << "MemorySave !" << std::endl; - m_snapshot = createSnapshot(chosenType); + auto m_snapshot = std::make_shared(); auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; if(!recentSnapshotFiles.empty()) { memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); - } auto snapshotTime = groot->getTime(); @@ -560,9 +559,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } if (ImGui::MenuItem("JSON")) { - chosenType = SnapshotType::JSON; - m_snapshot = createSnapshot(chosenType); - + auto m_snapshot = std::make_shared(); NFD_Init(); nfdchar_t* savePath; @@ -577,11 +574,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) std::string path(savePath); auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - m_snapshot->exportTo(path); - std::cout << "filepath : " << filepath << std::endl; - std::cout << "savePath : " << savePath << std::endl; + exportTo(*m_snapshot,path); filepath = savePath; - std::cout << "filepath after : " << filepath << std::endl; NFD_FreePath(savePath); } else @@ -601,11 +595,11 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if (ImGui::MenuItem("Memory (recent)")) { + auto m_snapshot = std::make_shared(); std::cout << "MemoryLoad !" << std::endl; if(!m_snapshot) { std::cout << "Nothing to load..." << std::endl; - m_snapshot = createSnapshot(SnapshotType::Memory); } else { @@ -624,6 +618,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (ImGui::MenuItem("JSON")) { + auto m_snapshot = std::make_shared(); if(!m_snapshot) { m_snapshot = createSnapshot(SnapshotType::JSON); @@ -640,7 +635,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (helper::system::FileSystem::exists(outPath)) { - m_snapshot->importFrom(outPath); + importFrom(*m_snapshot,outPath); auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); @@ -678,17 +673,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(file.ends_with(".json")) { - m_snapshot = createSnapshot(SnapshotType::JSON); - m_snapshot->importFrom(file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } - else - { - m_snapshot = createSnapshot(SnapshotType::Memory); - m_snapshot->importFrom(file); + auto m_snapshot = std::make_shared(); + importFrom(*m_snapshot,file); auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); @@ -700,8 +686,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { if(ImGui::MenuItem(name.c_str())) { + auto m_snapshot = std::make_shared(); m_snapshot = file; - m_snapshot->importFrom("none"); auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); } diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index 56346c9813..c6b514fc21 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -121,6 +121,7 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine std::shared_ptr m_snapshot; std::shared_ptr m_baseSnapshot; + // std::shared_ptr m_snapshot; }; } // namespace sofaimgui From a9e97f30b13459626c32712bef479e7c2cf6a94a Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Mon, 23 Mar 2026 17:12:44 +0100 Subject: [PATCH 48/60] Fix loadDataSnapshot and update SnapshotManager --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 52 +++++++++------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index 361dc44a63..a87c5431a8 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -83,10 +83,14 @@ #include #include +#include +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/Base.h" +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotManager.h" +using sofa::core::objectmodel::SnapshotManager; #include -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" +// #include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" using sofa::simulation::SaveSnapshotVisitor; #include @@ -359,28 +363,7 @@ void ImGuiGUIEngine::saveScreenshot(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } -void AddRecentFile(const std::string& path, std::vector& recentFiles, int maxFiles = 10) -{ - recentFiles.erase( - std::remove(recentFiles.begin(), recentFiles.end(), path), - recentFiles.end() - ); - //recentFiles.insert(recentFiles.begin(), path); - recentFiles.push_back(path); - if (recentFiles.size() > maxFiles) - recentFiles.resize(maxFiles); -} - -void AddRecentSnapshot(std::map>& recentSnapshots, std::shared_ptr snapshot, double snapshotTime, int maxSnapshots = 10) -{ - static int index = 0; - recentSnapshots["Memory_Snapshot " + std::to_string(index++) + " at " + std::to_string(snapshotTime)] = snapshot; - if (recentSnapshots.size() > maxSnapshots) - recentSnapshots.erase(recentSnapshots.begin()); -} - -std::vector recentSnapshotFiles; -std::map> recentSnapshots; +SnapshotManager snapshot_manager; void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { @@ -545,17 +528,21 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if(ImGui::MenuItem("Memory")) { std::cout << "MemorySave !" << std::endl; + auto m_snapshot = std::make_shared(); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; - if(!recentSnapshotFiles.empty()) + if(!snapshot_manager.recentSnapshotFiles.empty()) { - memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); + memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); } auto snapshotTime = groot->getTime(); - AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); + + // SnapshotManager::AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); + SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); } if (ImGui::MenuItem("JSON")) { @@ -585,7 +572,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } NFD_Quit(); - AddRecentFile(filepath, recentSnapshotFiles); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); } ImGui::EndMenu(); @@ -609,6 +596,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) m_baseSnapshot = recentSnapshots.rbegin()->second; auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); m_snapshot = recentSnapshots.rbegin()->second; + m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); @@ -655,19 +643,19 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } NFD_Quit(); std::cout << "JSON file loaded !" << std::endl; - AddRecentFile(filepath, recentSnapshotFiles); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); } if(ImGui::BeginMenu("Recent Files")) { - if (recentSnapshotFiles.empty() && recentSnapshots.empty()) + if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) { ImGui::MenuItem("(No recent files)", nullptr, false, false); } else { - for (auto file : recentSnapshotFiles) + for (auto file : snapshot_manager.recentSnapshotFiles) { if (ImGui::MenuItem(file.c_str())) { @@ -682,7 +670,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } } - for (auto [name, file] : recentSnapshots) + for (auto [name, file] : snapshot_manager.recentSnapshots) { if(ImGui::MenuItem(name.c_str())) { @@ -909,7 +897,7 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) if (showTime) position -= ImGui::CalcTextSize("Time: 000.000 ").x; ImGui::SetCursorPosX(position); - ImGui::Text("Snapshot in memory : %d items ", static_cast(recentSnapshots.size())); + ImGui::Text("Snapshot in memory : %d items ", static_cast(snapshot_manager.recentSnapshots.size())); ImGui::SetCursorPosX(posX); } mainMenuBarSize = ImGui::GetWindowSize(); From 6b5e623e59a0f36ff0be52974396b5c9c8ad8b3e Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Tue, 5 May 2026 09:20:06 +0200 Subject: [PATCH 49/60] bindings snapshot + python scripts --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 21 -------------------- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 10 ++++++++++ 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index a87c5431a8..f40dbb0793 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -82,24 +82,6 @@ #include #include -#include -#include - -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/Base.h" -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotManager.h" -using sofa::core::objectmodel::SnapshotManager; -#include - -// #include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" -using sofa::simulation::SaveSnapshotVisitor; - -#include -using sofa::simulation::LoadDataSnapshotVisitor; - -#include -using sofa::simulation::LoadLinkSnapshotVisitor; - - #include using namespace sofa; @@ -363,8 +345,6 @@ void ImGuiGUIEngine::saveScreenshot(sofaglfw::SofaGLFWBaseGUI* baseGUI) } } -SnapshotManager snapshot_manager; - void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) { m_localeBackup = std::setlocale(LC_NUMERIC, nullptr); @@ -426,7 +406,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool showFPSInMenuBar = true; static bool showTime = true; - static bool showMemorySnapshot = true; ImVec2 mainMenuBarSize; bool doCloseSimulation = false; diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index ebdac0bdc7..b399ab6833 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -180,9 +180,12 @@ namespace windows m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); // groot->execute(linkvisitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(linkvisitor); } } if (ImGui::Button("JSON")) @@ -200,9 +203,12 @@ namespace windows if (sofa::helper::system::FileSystem::exists(outPath)) { importFrom(*m_snapshot,outPath); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(linkvisitor); // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); // groot->execute(linkvisitor); @@ -278,9 +284,12 @@ namespace windows { auto m_snapshot = std::make_shared(); importFrom(*m_snapshot,file); + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); + auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(linkvisitor); // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); // groot->execute(linkvisitor); } @@ -292,6 +301,7 @@ namespace windows { auto m_snapshot = std::make_shared(); m_snapshot = file; + auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); From 7313b4a9b42a60c0e6ce7bac249d836a1360531d Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Fri, 20 Mar 2026 11:39:24 +0100 Subject: [PATCH 50/60] bindings snapshot + python scripts --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index f40dbb0793..fe8d3c157b 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -82,6 +82,20 @@ #include #include +#include + +#include + +#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" +using sofa::simulation::SaveSnapshotVisitor; + +#include +using sofa::simulation::LoadDataSnapshotVisitor; + +#include +using sofa::simulation::LoadLinkSnapshotVisitor; + + #include using namespace sofa; @@ -510,12 +524,14 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) auto m_snapshot = std::make_shared(); + auto m_snapshot = std::make_shared(); auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); std::string memorySnapshotName = "Memory Snapshot"; if(!snapshot_manager.recentSnapshotFiles.empty()) { memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); + memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); } auto snapshotTime = groot->getTime(); From 543ec1ea50ca55ea0b6d87f5fb5ba0debe78d543 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Tue, 12 May 2026 11:06:50 +0200 Subject: [PATCH 51/60] clean --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 436 --------------------- SofaImGui/src/SofaImGui/ImGuiGUIEngine.h | 5 - 2 files changed, 441 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index fe8d3c157b..f5e0e2ba7b 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -427,12 +427,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) static bool animate; animate = groot->animate_.getValue(); - //static SnapshotType chosenType = SnapshotType::Print; - - - const int MAX_RECENT_FILES = 10; - - /*************************************** * Main menu bar **************************************/ @@ -463,227 +457,8 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) } if (ImGui::MenuItem(ICON_FA_CIRCLE_XMARK " Close Simulation")) - { - sofa::simulation::node::unload(groot); - baseGUI->setSimulationIsRunning(false); - sofa::simulation::node::initRoot(baseGUI->getRootNode().get()); - return; - } - - ImGui::Separator(); - - if (ImGui::MenuItem(ICON_FA_FOLDER_CLOSED " Save Snapshot")) - { - saveStep = SaveStep::ChooseType; - { - // sofa::core::objectmodel::Base* b; - - - - auto JSONSnapCont = createSnapshot(SnapshotType::JSON); - auto visitor = SnapshotVisitor(nullptr,*JSONSnapCont); - groot->execute(visitor); - NFD_Init(); - - nfdchar_t* savePath; - - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - - - nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) { - puts("Success!"); - puts(savePath); - - std::string path(savePath); - - JSONSnapCont->exportToJSON(path); - // remember to free the memory (since NFD_OKAY is returned) - NFD_FreePath(savePath); - } else if (result == NFD_CANCEL) { - puts("User pressed cancel."); - } else { - printf("Error: %s\n", NFD_GetError()); - } - - // Quit NFD - NFD_Quit(); - - return; - } - - if (ImGui::MenuItem(ICON_FA_FOLDER_OPEN " Load Snapshot")) - { - loadStep = LoadStep::ChooseType; - - if (ImGui::BeginMenu("Save Snapshot")) - { - if(ImGui::MenuItem("Memory")) - { - std::cout << "MemorySave !" << std::endl; - - auto m_snapshot = std::make_shared(); - - auto m_snapshot = std::make_shared(); - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - std::string memorySnapshotName = "Memory Snapshot"; - if(!snapshot_manager.recentSnapshotFiles.empty()) - { - memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); - memorySnapshotName += " " + std::to_string(recentSnapshotFiles.size()); - } - - auto snapshotTime = groot->getTime(); - - // SnapshotManager::AddRecentSnapshot(recentSnapshots, m_snapshot, snapshotTime); - SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); - } - if (ImGui::MenuItem("JSON")) - { - auto m_snapshot = std::make_shared(); - NFD_Init(); - - nfdchar_t* savePath; - - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - std::string filepath = "null"; - nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) - { - puts("Save Snapshot success!"); - puts(savePath); - std::string path(savePath); - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - exportTo(*m_snapshot,path); - filepath = savePath; - NFD_FreePath(savePath); - } - else - { - - printf("Error: %s\n", NFD_GetError()); - } - - NFD_Quit(); - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); - } - - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Load Snapshot")) - { - if (ImGui::MenuItem("Memory (recent)")) - { - auto m_snapshot = std::make_shared(); - std::cout << "MemoryLoad !" << std::endl; - if(!m_snapshot) - { - std::cout << "Nothing to load..." << std::endl; - } - else - { - m_baseSnapshot = recentSnapshots.rbegin()->second; - m_baseSnapshot->importSnapshot("none"); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); - m_baseSnapshot = recentSnapshots.rbegin()->second; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_baseSnapshot); - m_snapshot = recentSnapshots.rbegin()->second; - m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } - } - - if (ImGui::MenuItem("JSON")) - { - auto m_snapshot = std::make_shared(); - if(!m_snapshot) - { - m_snapshot = createSnapshot(SnapshotType::JSON); - } - - nfdchar_t *outPath = NULL; - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); - std::string filepath = "null"; - if ( result == NFD_OKAY ) - { - puts("Success!"); - puts(outPath); - - if (helper::system::FileSystem::exists(outPath)) - { - importFrom(*m_snapshot,outPath); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - - } - filepath = outPath; - free(outPath); - } - else if ( result == NFD_CANCEL ) - { - puts("User pressed cancel."); - } - else - { - printf("Error: %s\n", NFD_GetError() ); - } - NFD_Quit(); - std::cout << "JSON file loaded !" << std::endl; - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); - - } - - if(ImGui::BeginMenu("Recent Files")) - { - if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) - { - ImGui::MenuItem("(No recent files)", nullptr, false, false); - } - else - { - for (auto file : snapshot_manager.recentSnapshotFiles) - { - if (ImGui::MenuItem(file.c_str())) - { - if(file.ends_with(".json")) - { - auto m_snapshot = std::make_shared(); - importFrom(*m_snapshot,file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } - } - } - for (auto [name, file] : snapshot_manager.recentSnapshots) - { - if(ImGui::MenuItem(name.c_str())) - { - auto m_snapshot = std::make_shared(); - m_snapshot = file; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - } - } - } - ImGui::EndMenu(); - } - ImGui::EndMenu(); - } - doCloseSimulation = true; ImGui::Separator(); - if (ImGui::MenuItem("Exit")) { this->terminate(); @@ -907,217 +682,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) return; } - if (saveStep == SaveStep::ChooseType) - { - ImGui::OpenPopup("SnapshotTypeChoice"); - } - - if (loadStep == LoadStep::ChooseType) - { - ImGui::OpenPopup("LoadSnapshotTypeChoice"); - } - - if ( ImGui::BeginPopupModal("SnapshotTypeChoice", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) - { - ImGui::Text("Choose type of snapshot"); - ImGui::Separator(); - if (ImGui::Button("JSON")) - { - chosenType = SnapshotType::JSON; - saveStep = SaveStep::OpenFileDialog; - - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("nothing")) - { - ImGui::CloseCurrentPopup(); - saveStep = SaveStep::None; - } - ImGui::SameLine(); - if (ImGui::Button("Memory")) - { - chosenType = SnapshotType::Memory; - saveStep = SaveStep::MemorySave; - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - - } - - if ( ImGui::BeginPopupModal("LoadSnapshotTypeChoice", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) - { - ImGui::Text("Choose type of snapshot"); - ImGui::Separator(); - if (ImGui::Button("JSON")) - { - chosenType = SnapshotType::JSON; - loadStep = LoadStep::OpenFileDialog; - - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("nothing")) - { - ImGui::CloseCurrentPopup(); - loadStep = LoadStep::None; - } - ImGui::SameLine(); - if (ImGui::Button("Memory")) - { - chosenType = SnapshotType::Memory; - loadStep = LoadStep::MemorySave; - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - - } - - if(saveStep == SaveStep::OpenFileDialog) - { - - auto SnapCont = createSnapshot(SnapshotType::JSON); - - // auto SnapCont = createSnapshot(SnapshotType::JSON); - auto SnapCont = createSnapshot(chosenType); - auto rootSnapNode = std::make_shared(); - rootSnapNode->name = "root"; - // SnapNode_.nodeName = "root"; - std::cout << "IMGUI " << std::endl; - auto visitor = SnapshotVisitor(nullptr,*SnapCont, *rootSnapNode); - groot->execute(visitor); - - std::ofstream file("dumpStateTest.txt"); - sofa::simulation::node::dumpState(groot.get(),file); - file.close(); - - for(auto element : rootSnapNode->componentList) - { - std::cout <<"dans rootSnapNode : " << element.name << std::endl; - } - - std::cout << "######" << std::endl; - - for(auto element : rootSnapNode->childNode) - { - std::cout <<"dans rootSnapNode : " << element->name << std::endl; - for(auto compelement : element->componentList) - { - std::cout << "components: " << compelement.name << std::endl; - } - } - //auto SnapCont = createSnapshot(chosenType); - //SnapCont->printSnapshot(); - { - m_baseSnapshot = createSnapshot(chosenType); - m_baseSnapshot->printSnapshot(); - - // auto visitor = SnapshotVisitor(nullptr,*SnapCont); - - // m_baseSnapshot->printSnapshot(); - - - NFD_Init(); - - nfdchar_t* savePath; - - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - - nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) - { - puts("Save Snapshot success!"); - puts(savePath); - std::string path(savePath); - auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); - groot->execute(visitor); - - m_baseSnapshot->exportTo(path); - NFD_FreePath(savePath); - } - else - { - printf("Error: %s\n", NFD_GetError()); - } - - NFD_Quit(); - saveStep = SaveStep::None; - } - - if (saveStep == SaveStep::MemorySave) - { - std::cout << "MemorySave !" << std::endl; - m_baseSnapshot = createSnapshot(chosenType); - auto visitor = SnapshotVisitor(nullptr,*m_baseSnapshot); - groot->execute(visitor); - saveStep = SaveStep::None; - } - - if(loadStep == LoadStep::OpenFileDialog) - { - if(!m_baseSnapshot) - { - m_baseSnapshot = createSnapshot(chosenType); - } - - - - nfdchar_t *outPath = NULL; - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); - - if ( result == NFD_OKAY ) - { - puts("Success!"); - puts(outPath); - - if (helper::system::FileSystem::exists(outPath)) - { - m_baseSnapshot->importFrom(outPath); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); - groot->execute(visitor); - - } - free(outPath); - } - else if ( result == NFD_CANCEL ) - { - puts("User pressed cancel."); - } - else - { - printf("Error: %s\n", NFD_GetError() ); - } - NFD_Quit(); - - - - loadStep = LoadStep::None; - - } - - if (loadStep == LoadStep::MemorySave) - { - std::cout << "MemoryLoad !" << std::endl; - if(!m_baseSnapshot) - { - std::cout << "Nothing to load..." << std::endl; - m_baseSnapshot = createSnapshot(chosenType); - } - else - { - m_baseSnapshot->importSnapshot("none"); - auto visitor = LoadSnapshotVisitor(nullptr,*m_baseSnapshot); - groot->execute(visitor); - } - - m_baseSnapshot->printSnapshot(); - - loadStep = LoadStep::None; - } - if (m_imguiNeedViewReset) { resetView(dockspace_id, windowNameSceneGraph, windowNameSelectionDescription, windowNameLog, windowNameViewport); diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h index c6b514fc21..519b4d1560 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.h @@ -117,11 +117,6 @@ class ImGuiGUIEngine : public sofaglfw::BaseGUIEngine static inline constexpr int s_NB_PBOS = 2; GLuint m_pbos[s_NB_PBOS]; sofa::type::Vec2i m_pboSize; - - std::shared_ptr m_snapshot; - - std::shared_ptr m_baseSnapshot; - // std::shared_ptr m_snapshot; }; } // namespace sofaimgui From bedf5395f1642ed003040b8b0488c4c7b6d3780d Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Tue, 12 May 2026 11:11:25 +0200 Subject: [PATCH 52/60] clean --- SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp | 26 -------------------- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 19 -------------- 2 files changed, 45 deletions(-) diff --git a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp index f5e0e2ba7b..75109a08ec 100644 --- a/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp +++ b/SofaImGui/src/SofaImGui/ImGuiGUIEngine.cpp @@ -82,20 +82,6 @@ #include #include -#include - -#include - -#include "../../../../../src/Sofa/framework/Core/src/sofa/core/objectmodel/SnapshotJSONExporter.h" -using sofa::simulation::SaveSnapshotVisitor; - -#include -using sofa::simulation::LoadDataSnapshotVisitor; - -#include -using sofa::simulation::LoadLinkSnapshotVisitor; - - #include using namespace sofa; @@ -658,18 +644,6 @@ void ImGuiGUIEngine::startFrame(sofaglfw::SofaGLFWBaseGUI* baseGUI) ImGui::Text("Time: %.3f", groot->getTime()); ImGui::SetCursorPosX(posX); } - if (showMemorySnapshot) - { - auto position = ImGui::GetCursorPosX() + ImGui::GetColumnWidth() - ImGui::CalcTextSize("Snapshot in memory : 00 items ").x - - 2 * ImGui::GetStyle().ItemSpacing.x; - if (showFPSInMenuBar) - position -= ImGui::CalcTextSize("1000.0 FPS ").x; - if (showTime) - position -= ImGui::CalcTextSize("Time: 000.000 ").x; - ImGui::SetCursorPosX(position); - ImGui::Text("Snapshot in memory : %d items ", static_cast(snapshot_manager.recentSnapshots.size())); - ImGui::SetCursorPosX(posX); - } mainMenuBarSize = ImGui::GetWindowSize(); ImGui::EndMainMenuBar(); } diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index b399ab6833..05b1e2e6d9 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -178,12 +178,8 @@ namespace windows else { m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; - // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - // groot->execute(linkvisitor); auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); groot->execute(linkvisitor); } @@ -203,15 +199,8 @@ namespace windows if (sofa::helper::system::FileSystem::exists(outPath)) { importFrom(*m_snapshot,outPath); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - // groot->execute(linkvisitor); - } filepath = outPath; free(outPath); @@ -284,14 +273,8 @@ namespace windows { auto m_snapshot = std::make_shared(); importFrom(*m_snapshot,file); - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - // auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - // groot->execute(linkvisitor); } } } @@ -301,8 +284,6 @@ namespace windows { auto m_snapshot = std::make_shared(); m_snapshot = file; - auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); - // auto visitor = LoadDataSnapshotVisitor(nullptr,*m_snapshot); auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); } From eea703579b2ca6aa14d0b0f934025d88661665db Mon Sep 17 00:00:00 2001 From: Lucas Burel Date: Mon, 15 Jun 2026 10:07:55 +0200 Subject: [PATCH 53/60] update 15/06 --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 62 ++++++++++---------- SofaImGui/src/SofaImGui/windows/Snapshot.h | 5 +- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index 05b1e2e6d9..be59441546 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -62,8 +62,10 @@ namespace windows { SnapshotManager snapshot_manager; + /// TODO : Refactoring/Cleaning void showSnapshot(const char* const& windowNameSnapshot, - WindowState& winManagerSnapshot, sofa::core::sptr& groot) { + WindowState& winManagerSnapshot, sofa::core::sptr& groot) + { if (*winManagerSnapshot.getStatePtr()) { @@ -86,21 +88,7 @@ namespace windows ImGui::Separator(); if (ImGui::Button("Memory")) { - std::cout << "MemorySave !" << std::endl; - - auto m_snapshot = std::make_shared(); - - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - std::string memorySnapshotName = "Memory Snapshot"; - if(!snapshot_manager.recentSnapshotFiles.empty()) - { - memorySnapshotName += " " + std::to_string(snapshot_manager.recentSnapshotFiles.size()); - } - - auto snapshotTime = groot->getTime(); - - SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); + doMemorySave(groot); } if (ImGui::Button("JSON")) { @@ -114,8 +102,7 @@ namespace windows nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); if (result == NFD_OKAY) { - puts("Save Snapshot success!"); - puts(savePath); + msg_info("SaveSnapshot") << "Snapshot " << savePath << " saved"; std::string path(savePath); auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); @@ -169,20 +156,7 @@ namespace windows ImGui::Separator(); if (ImGui::Button("Memory (recent)")) { - auto m_snapshot = std::make_shared(); - std::cout << "MemoryLoad !" << std::endl; - if(!m_snapshot) - { - std::cout << "Nothing to load..." << std::endl; - } - else - { - m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; - auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto linkvisitor = LoadLinkSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(linkvisitor); - } + doMemoryLoad(groot); } if (ImGui::Button("JSON")) { @@ -298,5 +272,29 @@ namespace windows } + void doMemorySave(sofa::core::sptr& groot) + { + auto m_snapshot = std::make_shared(); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + auto snapshotTime = groot->getTime(); + SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); + } + + void doMemoryLoad(sofa::core::sptr& groot) + { + auto m_snapshot = std::make_shared(); + if(snapshot_manager.recentSnapshots.size() > 0) + { + m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; + auto visitor = LoadSnapshotVisitor(nullptr, *m_snapshot); + groot->execute(visitor); + } + else + { + msg_warning("MemoryLoad") << "No Snapshot in memory"; + } + + } } diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.h b/SofaImGui/src/SofaImGui/windows/Snapshot.h index 54a183d705..276c12f472 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.h +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.h @@ -34,7 +34,10 @@ namespace windows * This function displays a window which user can save and load snapshots. * */ - void showSnapshot(const char* const& windowNameSnapshot, + void showSnapshot(const char* const& windowNameSnapshot, WindowState& winManagerSnapshot,sofa::core::sptr& groot); + void doMemorySave(sofa::core::sptr& groot); + void doMemoryLoad(sofa::core::sptr& groot); + } // namespace sofaimgui From 76909c4048f27805a03353eae03fe79cf34cceb5 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Mon, 15 Jun 2026 15:50:41 +0200 Subject: [PATCH 54/60] clean Snapshot API --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 206 +++++++++---------- SofaImGui/src/SofaImGui/windows/Snapshot.h | 2 + 2 files changed, 98 insertions(+), 110 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index be59441546..81656a3478 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -40,9 +40,13 @@ #include #include + +#include "../../../../../../src/Sofa/framework/Helper/src/sofa/helper/logging/Messaging.h" +using sofa::helper::system::FileSystem; #include #include + using sofa::core::objectmodel::SnapshotManager; #include using sofa::simulation::SaveSnapshotVisitor; @@ -62,7 +66,6 @@ namespace windows { SnapshotManager snapshot_manager; - /// TODO : Refactoring/Cleaning void showSnapshot(const char* const& windowNameSnapshot, WindowState& winManagerSnapshot, sofa::core::sptr& groot) { @@ -90,65 +93,20 @@ namespace windows { doMemorySave(groot); } - if (ImGui::Button("JSON")) + if (ImGui::Button("File")) { - auto m_snapshot = std::make_shared(); - NFD_Init(); - - nfdchar_t* savePath; - - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - std::string filepath = "null"; - nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) - { - msg_info("SaveSnapshot") << "Snapshot " << savePath << " saved"; - std::string path(savePath); - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - exportTo(*m_snapshot,path); - filepath = savePath; - NFD_FreePath(savePath); - } - else - { - printf("Error: %s\n", NFD_GetError()); - } - - NFD_Quit(); - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); + doFileSave(groot, false); } if (ImGui::Button("Groups")) { if (!snapshot_manager.recentSnapshots.empty()) { - NFD_Init(); - - nfdchar_t* savePath; - - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - std::string filepath = "null"; - nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 2, NULL, "Untitled.json"); - if (result == NFD_OKAY) - { - puts(savePath); - std::string path(savePath); - exportTo(snapshot_manager.recentSnapshots, path); - filepath = savePath; - NFD_FreePath(savePath); - } - else - { - printf("Error: %s\n", NFD_GetError()); - } - + doFileSave(groot, true); } else std::cout << "No snapshot" << std::endl; } - - ImGui::EndChild(); ImGui::BeginChild("Load Snapshot", ImVec2(0, halfHeight), true); @@ -158,68 +116,14 @@ namespace windows { doMemoryLoad(groot); } - if (ImGui::Button("JSON")) + if (ImGui::Button("File")) { - auto m_snapshot = std::make_shared(); - nfdchar_t *outPath = NULL; - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); - std::string filepath = "null"; - if ( result == NFD_OKAY ) - { - puts("Success!"); - puts(outPath); - - if (sofa::helper::system::FileSystem::exists(outPath)) - { - importFrom(*m_snapshot,outPath); - auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - } - filepath = outPath; - free(outPath); - } - else if ( result == NFD_CANCEL ) - { - puts("User pressed cancel."); - } - else - { - printf("Error: %s\n", NFD_GetError() ); - } - NFD_Quit(); - std::cout << "JSON file loaded !" << std::endl; - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); - + doFileLoad(groot, false); } if (ImGui::Button("Groups")) { - nfdchar_t *outPath = NULL; - nfdfilteritem_t filterItem[2] = {{"Snapshot code", "json,txt"}, {"Scene file", "py,xml"}}; - nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL); - std::string filepath = "null"; - if ( result == NFD_OKAY ) - { - puts("Success!"); - puts(outPath); - - if (sofa::helper::system::FileSystem::exists(outPath)) - { - sofa::core::objectmodel::separateSnapshots(outPath, snapshot_manager); - } - filepath = outPath; - free(outPath); - } - else if ( result == NFD_CANCEL ) - { - puts("User pressed cancel."); - } - else - { - printf("Error: %s\n", NFD_GetError() ); - } - NFD_Quit(); + doFileLoad(groot, true); } ImGui::EndChild(); @@ -227,12 +131,8 @@ namespace windows float listHeight = ImGui::GetContentRegionAvail().y - 8.0f; - - ImGui::BeginChild("Recents", ImVec2(0, listHeight), true); - - if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) { ImGui::TextDisabled("(No recent files)"); @@ -297,4 +197,90 @@ namespace windows } + void doSaveTo(sofa::core::sptr& groot, nfdchar_t* savePath, std::string filepath, bool isGroup) + { + auto m_snapshot = std::make_shared(); + + std::string path(savePath); + auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + + std::string FileExtension = FileSystem::getExtension(path); + if (FileExtension == "json" && !isGroup) + exportToJSON(*m_snapshot,path); + else if (FileExtension == "json" && isGroup) + exportToJSON(snapshot_manager.recentSnapshots,path); + else + msg_error("SaveSnapshot") << "Snapshot " << filepath << " not supported"; + + filepath = savePath; + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); + msg_info("SaveSnapshot") << "Snapshot " << savePath << " saved"; + NFD_FreePath(savePath); + } + + + void doFileSave(sofa::core::sptr& groot, bool isGroup) + { + NFD_Init(); + nfdchar_t* savePath; + nfdfilteritem_t filterItem[1] = {{"Snapshot code", "json,txt"}}; + std::string filepath = "null"; + nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 1, NULL, "Untitled.json"); + if (result == NFD_OKAY) + { + doSaveTo(groot,savePath,filepath, isGroup); + } + else + { + msg_error("SaveSnapshot") << "Error of saving snapshot" ; + } + NFD_Quit(); + } + + void doLoadTo(sofa::core::sptr& groot, nfdchar_t* outPath, std::string filepath) + { + + auto m_snapshot = std::make_shared(); + if (sofa::helper::system::FileSystem::exists(outPath)) + { + importFrom(*m_snapshot,outPath); + auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); + groot->execute(visitor); + } + filepath = outPath; + SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); + msg_info("LoadSnapshot") << "Snapshot " << filepath << " loaded"; + NFD_FreePath(outPath); + } + + void doLoadToGroup(nfdchar_t* outPath, SnapshotManager& snapshot_manager) + { + if (sofa::helper::system::FileSystem::exists(outPath)) + { + sofa::core::objectmodel::separateSnapshots(outPath, snapshot_manager); + } + msg_info("LoadSnapshot") << "Snapshot " << outPath << " loaded"; + NFD_FreePath(outPath); + } + + void doFileLoad(sofa::core::sptr& groot, bool isGroup) + { + nfdchar_t *outPath = NULL; + nfdfilteritem_t filterItem[1] = {{"Snapshot code", "json"}}; + nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 1, NULL); + std::string filepath = "null"; + if ( result == NFD_OKAY && !isGroup) + { + doLoadTo(groot,outPath,filepath); + } + else if (result == NFD_OKAY && isGroup) + doLoadToGroup(outPath,snapshot_manager); + else + { + msg_error("LoadSnapshot") << "Error of loading snapshot" ; + } + NFD_Quit(); + } + } diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.h b/SofaImGui/src/SofaImGui/windows/Snapshot.h index 276c12f472..369bd39474 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.h +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.h @@ -39,5 +39,7 @@ namespace windows void doMemorySave(sofa::core::sptr& groot); void doMemoryLoad(sofa::core::sptr& groot); + void doFileSave(sofa::core::sptr& groot, bool isGroup); + void doFileLoad(sofa::core::sptr& groot, bool isGroup); } // namespace sofaimgui From 27771407e84b4b841fe3767e7702ca30c2f272d9 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Thu, 2 Jul 2026 16:33:30 +0200 Subject: [PATCH 55/60] remove LoadDataSnapshotVisitor and LoadLinkSnapshotVisitor --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index 81656a3478..62c8ec5a83 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -54,11 +54,6 @@ using sofa::simulation::SaveSnapshotVisitor; #include using sofa::simulation::LoadSnapshotVisitor; -#include -using sofa::simulation::LoadDataSnapshotVisitor; - -#include -using sofa::simulation::LoadLinkSnapshotVisitor; #include "Snapshot.h" From 2a9eb0a216245b395767d6d47f0fe66b94038719 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Fri, 3 Jul 2026 16:44:22 +0200 Subject: [PATCH 56/60] fix & clean --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index 62c8ec5a83..df37c14f18 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -94,7 +94,7 @@ namespace windows } if (ImGui::Button("Groups")) { - if (!snapshot_manager.recentSnapshots.empty()) + if (!snapshot_manager.m_recentSnapshots.empty()) { doFileSave(groot, true); } @@ -128,13 +128,13 @@ namespace windows ImGui::BeginChild("Recents", ImVec2(0, listHeight), true); - if (snapshot_manager.recentSnapshotFiles.empty() && snapshot_manager.recentSnapshots.empty()) + if (snapshot_manager.m_recentSnapshotFiles.empty() && snapshot_manager.m_recentSnapshots.empty()) { ImGui::TextDisabled("(No recent files)"); } else { - for (auto file : snapshot_manager.recentSnapshotFiles) + for (auto file : snapshot_manager.m_recentSnapshotFiles) { if (ImGui::Selectable(file.c_str())) { @@ -147,7 +147,7 @@ namespace windows } } } - for (auto [name, file] : snapshot_manager.recentSnapshots) + for (auto [name, file] : snapshot_manager.m_recentSnapshots) { if(ImGui::Selectable(name.c_str())) { @@ -173,15 +173,15 @@ namespace windows auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); groot->execute(visitor); auto snapshotTime = groot->getTime(); - SnapshotManager::AddRecentSnapshot(snapshot_manager.recentSnapshots, m_snapshot, snapshotTime); + SnapshotManager::AddRecentSnapshot(snapshot_manager.m_recentSnapshots, m_snapshot, snapshotTime); } void doMemoryLoad(sofa::core::sptr& groot) { auto m_snapshot = std::make_shared(); - if(snapshot_manager.recentSnapshots.size() > 0) + if(snapshot_manager.m_recentSnapshots.size() > 0) { - m_snapshot = snapshot_manager.recentSnapshots.rbegin()->second; + m_snapshot = snapshot_manager.m_recentSnapshots.rbegin()->second; auto visitor = LoadSnapshotVisitor(nullptr, *m_snapshot); groot->execute(visitor); } @@ -204,12 +204,12 @@ namespace windows if (FileExtension == "json" && !isGroup) exportToJSON(*m_snapshot,path); else if (FileExtension == "json" && isGroup) - exportToJSON(snapshot_manager.recentSnapshots,path); + exportToJSON(snapshot_manager.m_recentSnapshots,path); else msg_error("SaveSnapshot") << "Snapshot " << filepath << " not supported"; filepath = savePath; - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.m_recentSnapshotFiles); msg_info("SaveSnapshot") << "Snapshot " << savePath << " saved"; NFD_FreePath(savePath); } @@ -244,7 +244,7 @@ namespace windows groot->execute(visitor); } filepath = outPath; - SnapshotManager::AddRecentFile(filepath, snapshot_manager.recentSnapshotFiles); + SnapshotManager::AddRecentFile(filepath, snapshot_manager.m_recentSnapshotFiles); msg_info("LoadSnapshot") << "Snapshot " << filepath << " loaded"; NFD_FreePath(outPath); } From 0c7e9c5d1cd367e131b51be68f7debabc002d6eb Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Tue, 7 Jul 2026 17:08:32 +0200 Subject: [PATCH 57/60] Modifications to SnapshotManager class --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 104 +++---------------- SofaImGui/src/SofaImGui/windows/Snapshot.h | 2 - 2 files changed, 16 insertions(+), 90 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index df37c14f18..7d962d2900 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -41,13 +41,11 @@ #include -#include "../../../../../../src/Sofa/framework/Helper/src/sofa/helper/logging/Messaging.h" using sofa::helper::system::FileSystem; +#include #include -#include - -using sofa::core::objectmodel::SnapshotManager; +using sofa::simulation::SnapshotManager; #include using sofa::simulation::SaveSnapshotVisitor; @@ -86,7 +84,7 @@ namespace windows ImGui::Separator(); if (ImGui::Button("Memory")) { - doMemorySave(groot); + snapshot_manager.doMemorySave(groot); } if (ImGui::Button("File")) { @@ -94,7 +92,7 @@ namespace windows } if (ImGui::Button("Groups")) { - if (!snapshot_manager.m_recentSnapshots.empty()) + if (!snapshot_manager.m_recentSnapshotsFromMemory.empty()) { doFileSave(groot, true); } @@ -109,7 +107,7 @@ namespace windows ImGui::Separator(); if (ImGui::Button("Memory (recent)")) { - doMemoryLoad(groot); + snapshot_manager.doMemoryLoad(groot); } if (ImGui::Button("File")) { @@ -128,13 +126,13 @@ namespace windows ImGui::BeginChild("Recents", ImVec2(0, listHeight), true); - if (snapshot_manager.m_recentSnapshotFiles.empty() && snapshot_manager.m_recentSnapshots.empty()) + if (snapshot_manager.m_recentSnapshotsFromFiles.empty() && snapshot_manager.m_recentSnapshotsFromMemory.empty()) { ImGui::TextDisabled("(No recent files)"); } else { - for (auto file : snapshot_manager.m_recentSnapshotFiles) + for (auto file : snapshot_manager.m_recentSnapshotsFromFiles) { if (ImGui::Selectable(file.c_str())) { @@ -147,7 +145,7 @@ namespace windows } } } - for (auto [name, file] : snapshot_manager.m_recentSnapshots) + for (auto [name, file] : snapshot_manager.m_recentSnapshotsFromMemory) { if(ImGui::Selectable(name.c_str())) { @@ -166,55 +164,6 @@ namespace windows } } - - void doMemorySave(sofa::core::sptr& groot) - { - auto m_snapshot = std::make_shared(); - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - auto snapshotTime = groot->getTime(); - SnapshotManager::AddRecentSnapshot(snapshot_manager.m_recentSnapshots, m_snapshot, snapshotTime); - } - - void doMemoryLoad(sofa::core::sptr& groot) - { - auto m_snapshot = std::make_shared(); - if(snapshot_manager.m_recentSnapshots.size() > 0) - { - m_snapshot = snapshot_manager.m_recentSnapshots.rbegin()->second; - auto visitor = LoadSnapshotVisitor(nullptr, *m_snapshot); - groot->execute(visitor); - } - else - { - msg_warning("MemoryLoad") << "No Snapshot in memory"; - } - - } - - void doSaveTo(sofa::core::sptr& groot, nfdchar_t* savePath, std::string filepath, bool isGroup) - { - auto m_snapshot = std::make_shared(); - - std::string path(savePath); - auto visitor = SaveSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - - std::string FileExtension = FileSystem::getExtension(path); - if (FileExtension == "json" && !isGroup) - exportToJSON(*m_snapshot,path); - else if (FileExtension == "json" && isGroup) - exportToJSON(snapshot_manager.m_recentSnapshots,path); - else - msg_error("SaveSnapshot") << "Snapshot " << filepath << " not supported"; - - filepath = savePath; - SnapshotManager::AddRecentFile(filepath, snapshot_manager.m_recentSnapshotFiles); - msg_info("SaveSnapshot") << "Snapshot " << savePath << " saved"; - NFD_FreePath(savePath); - } - - void doFileSave(sofa::core::sptr& groot, bool isGroup) { NFD_Init(); @@ -224,7 +173,8 @@ namespace windows nfdresult_t result = NFD_SaveDialog(&savePath, filterItem, 1, NULL, "Untitled.json"); if (result == NFD_OKAY) { - doSaveTo(groot,savePath,filepath, isGroup); + std::string path(savePath); + snapshot_manager.doSaveTo(groot,path,isGroup); } else { @@ -233,32 +183,6 @@ namespace windows NFD_Quit(); } - void doLoadTo(sofa::core::sptr& groot, nfdchar_t* outPath, std::string filepath) - { - - auto m_snapshot = std::make_shared(); - if (sofa::helper::system::FileSystem::exists(outPath)) - { - importFrom(*m_snapshot,outPath); - auto visitor = LoadSnapshotVisitor(nullptr,*m_snapshot); - groot->execute(visitor); - } - filepath = outPath; - SnapshotManager::AddRecentFile(filepath, snapshot_manager.m_recentSnapshotFiles); - msg_info("LoadSnapshot") << "Snapshot " << filepath << " loaded"; - NFD_FreePath(outPath); - } - - void doLoadToGroup(nfdchar_t* outPath, SnapshotManager& snapshot_manager) - { - if (sofa::helper::system::FileSystem::exists(outPath)) - { - sofa::core::objectmodel::separateSnapshots(outPath, snapshot_manager); - } - msg_info("LoadSnapshot") << "Snapshot " << outPath << " loaded"; - NFD_FreePath(outPath); - } - void doFileLoad(sofa::core::sptr& groot, bool isGroup) { nfdchar_t *outPath = NULL; @@ -267,10 +191,14 @@ namespace windows std::string filepath = "null"; if ( result == NFD_OKAY && !isGroup) { - doLoadTo(groot,outPath,filepath); + std::string path(outPath); + snapshot_manager.doLoadTo(groot,path); } else if (result == NFD_OKAY && isGroup) - doLoadToGroup(outPath,snapshot_manager); + { + std::string path(outPath); + snapshot_manager.doLoadToGroup(path); + } else { msg_error("LoadSnapshot") << "Error of loading snapshot" ; diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.h b/SofaImGui/src/SofaImGui/windows/Snapshot.h index 369bd39474..a7919588ce 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.h +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.h @@ -37,8 +37,6 @@ namespace windows void showSnapshot(const char* const& windowNameSnapshot, WindowState& winManagerSnapshot,sofa::core::sptr& groot); - void doMemorySave(sofa::core::sptr& groot); - void doMemoryLoad(sofa::core::sptr& groot); void doFileSave(sofa::core::sptr& groot, bool isGroup); void doFileLoad(sofa::core::sptr& groot, bool isGroup); From 308330f1c44c638642f3e63258e389761754aaf8 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Wed, 8 Jul 2026 13:39:08 +0200 Subject: [PATCH 58/60] cleaning --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index 7d962d2900..75d5570d9c 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -92,7 +92,7 @@ namespace windows } if (ImGui::Button("Groups")) { - if (!snapshot_manager.m_recentSnapshotsFromMemory.empty()) + if (!snapshot_manager.m_snapshotsFromMemory.empty()) { doFileSave(groot, true); } @@ -126,13 +126,13 @@ namespace windows ImGui::BeginChild("Recents", ImVec2(0, listHeight), true); - if (snapshot_manager.m_recentSnapshotsFromFiles.empty() && snapshot_manager.m_recentSnapshotsFromMemory.empty()) + if (snapshot_manager.m_snapshotsFromFiles.empty() && snapshot_manager.m_snapshotsFromMemory.empty()) { ImGui::TextDisabled("(No recent files)"); } else { - for (auto file : snapshot_manager.m_recentSnapshotsFromFiles) + for (auto file : snapshot_manager.m_snapshotsFromFiles) { if (ImGui::Selectable(file.c_str())) { @@ -145,7 +145,7 @@ namespace windows } } } - for (auto [name, file] : snapshot_manager.m_recentSnapshotsFromMemory) + for (auto [name, file] : snapshot_manager.m_snapshotsFromMemory) { if(ImGui::Selectable(name.c_str())) { From f9590ebe7129a9dfdae328ca8a7ba9405ce7cbd4 Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Fri, 10 Jul 2026 10:28:43 +0200 Subject: [PATCH 59/60] cleaning --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 11 +++++------ SofaImGui/src/SofaImGui/windows/Snapshot.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index 75d5570d9c..aea5c2448f 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -67,9 +67,8 @@ namespace windows { if (ImGui::Begin(windowNameSnapshot, winManagerSnapshot.getStatePtr())) { - static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_Sortable; - if(ImGui::BeginTable("MainTable",2,flags, ImVec2(0.f, 400.f))) - { + static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders| ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg; + if(ImGui::BeginTable("MainTable", 2, flags, ImVec2(0.f, 400.f))) { ImGui::TableSetupColumn("Save/Load"); ImGui::TableSetupColumn("Snapshot in memory"); ImGui::TableHeadersRow(); @@ -79,7 +78,7 @@ namespace windows float totalHeight = ImGui::GetContentRegionAvail().y; float halfHeight = totalHeight * 0.5f - 4.0f; - ImGui::BeginChild("Save Snapshot", ImVec2(0, halfHeight), true); + ImGui::BeginChild("Save Snapshot", ImVec2(0, halfHeight), ImGuiChildFlags_Borders); ImGui::Text("Save Snapshot"); ImGui::Separator(); if (ImGui::Button("Memory")) @@ -102,7 +101,7 @@ namespace windows } ImGui::EndChild(); - ImGui::BeginChild("Load Snapshot", ImVec2(0, halfHeight), true); + ImGui::BeginChild("Load Snapshot", ImVec2(0, halfHeight), ImGuiChildFlags_Borders); ImGui::Text("Load Snapshot"); ImGui::Separator(); if (ImGui::Button("Memory (recent)")) @@ -157,8 +156,8 @@ namespace windows } } ImGui::EndChild(); + ImGui::EndTable(); } - ImGui::EndTable(); } ImGui::End(); } diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.h b/SofaImGui/src/SofaImGui/windows/Snapshot.h index a7919588ce..b4ce52a18e 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.h +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.h @@ -31,7 +31,7 @@ namespace windows /** * @brief Shows the Snapshot window. * - * This function displays a window which user can save and load snapshots. + * This function displays a window which user can use Snapshot's features. * */ void showSnapshot(const char* const& windowNameSnapshot, From d1c94c7275c5c937228491cff3141254b88899bf Mon Sep 17 00:00:00 2001 From: Lucas-TJ Date: Fri, 10 Jul 2026 16:04:42 +0200 Subject: [PATCH 60/60] cleaning --- SofaImGui/src/SofaImGui/windows/Snapshot.cpp | 31 +++++--------------- SofaImGui/src/SofaImGui/windows/Snapshot.h | 11 +++++-- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp index aea5c2448f..1ff8701f1c 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.cpp +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.cpp @@ -39,20 +39,6 @@ #include #include -#include - -using sofa::helper::system::FileSystem; -#include -#include - -using sofa::simulation::SnapshotManager; -#include -using sofa::simulation::SaveSnapshotVisitor; - -#include -using sofa::simulation::LoadSnapshotVisitor; - - #include "Snapshot.h" namespace windows @@ -89,7 +75,7 @@ namespace windows { doFileSave(groot, false); } - if (ImGui::Button("Groups")) + if (ImGui::Button("Set of Snapshots")) { if (!snapshot_manager.m_snapshotsFromMemory.empty()) { @@ -113,7 +99,7 @@ namespace windows doFileLoad(groot, false); } - if (ImGui::Button("Groups")) + if (ImGui::Button("Set of Snapshots")) { doFileLoad(groot, true); } @@ -163,7 +149,7 @@ namespace windows } } - void doFileSave(sofa::core::sptr& groot, bool isGroup) + void doFileSave(sofa::core::sptr& groot, bool isSet) { NFD_Init(); nfdchar_t* savePath; @@ -173,7 +159,7 @@ namespace windows if (result == NFD_OKAY) { std::string path(savePath); - snapshot_manager.doSaveTo(groot,path,isGroup); + snapshot_manager.doSaveTo(groot,path,isSet); } else { @@ -182,21 +168,21 @@ namespace windows NFD_Quit(); } - void doFileLoad(sofa::core::sptr& groot, bool isGroup) + void doFileLoad(sofa::core::sptr& groot, bool isSet) { nfdchar_t *outPath = NULL; nfdfilteritem_t filterItem[1] = {{"Snapshot code", "json"}}; nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 1, NULL); std::string filepath = "null"; - if ( result == NFD_OKAY && !isGroup) + if ( result == NFD_OKAY && !isSet) { std::string path(outPath); snapshot_manager.doLoadTo(groot,path); } - else if (result == NFD_OKAY && isGroup) + else if (result == NFD_OKAY && isSet) { std::string path(outPath); - snapshot_manager.doLoadToGroup(path); + snapshot_manager.doLoadToSet(path); } else { @@ -204,5 +190,4 @@ namespace windows } NFD_Quit(); } - } diff --git a/SofaImGui/src/SofaImGui/windows/Snapshot.h b/SofaImGui/src/SofaImGui/windows/Snapshot.h index b4ce52a18e..7e0f1baeb1 100644 --- a/SofaImGui/src/SofaImGui/windows/Snapshot.h +++ b/SofaImGui/src/SofaImGui/windows/Snapshot.h @@ -24,6 +24,13 @@ #include #include "WindowState.h" +#include +using sofa::helper::system::FileSystem; +#include +#include +using sofa::simulation::SnapshotManager; +#include +using sofa::simulation::LoadSnapshotVisitor; namespace windows @@ -37,7 +44,7 @@ namespace windows void showSnapshot(const char* const& windowNameSnapshot, WindowState& winManagerSnapshot,sofa::core::sptr& groot); - void doFileSave(sofa::core::sptr& groot, bool isGroup); - void doFileLoad(sofa::core::sptr& groot, bool isGroup); + void doFileSave(sofa::core::sptr& groot, bool isSet); + void doFileLoad(sofa::core::sptr& groot, bool isSet); } // namespace sofaimgui