From 99389d413f74fbcb515b7fe880e4de3d9d380bab Mon Sep 17 00:00:00 2001 From: hugtalbot Date: Tue, 22 Jul 2025 15:24:37 +0200 Subject: [PATCH 1/6] Update documentation to explicit the use of ImGui and SOFA in Python --- docs/sphinx/source/content/FirstSteps.rst | 58 +++++++++++++------ docs/sphinx/source/content/UsingThePlugin.rst | 14 +++-- 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/docs/sphinx/source/content/FirstSteps.rst b/docs/sphinx/source/content/FirstSteps.rst index 9efb32fef..49ddd714c 100644 --- a/docs/sphinx/source/content/FirstSteps.rst +++ b/docs/sphinx/source/content/FirstSteps.rst @@ -8,29 +8,35 @@ Executing a simulation With runSofa ^^^^^^^^^^^^ -You can load a python based simulation directly in runSofa by using the command +Making sure the SofaPython3 plugin is loaded, you can load a simulation described by a python script directly in runSofa. +Assuming you want to run a script named "example.py", you can run the following command: .. code-block:: shell - runSofa examples/example1.py + runSofa example1.py -Let's now open ``examples/example1.py`` to have more insight. -The first important thin to notice is that the python script is importing modules called ``Sofa``, this module, and few other are containing -all SOFA specific component. Then the script is defining a ``createScene()`` function. This function is the entry point of your simulation and -is automatically called by the runSofa application when a python file is loaded. - -We will look with more details in this ``createScene()`` but first let's how we can execute the same file without using ``runSofa``. +Let's now see how this script ``example1.py`` should look like. +The first important thing to notice is that to be compatible with SOFA, a python script must define the ``createScene()`` function. This function is the entry point of your simulation and +is automatically called by the runSofa application when a python file is loaded. It is responsible for describing and building the SOFA scene graph. +In the section `Create a new simulation ` below, we will detail how to implement this ``createScene()``. With the python3 interpreter ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Before being able to execute a simulation from a python interpreter (including jupyter notebook) be sure you read the "`Setup your python3 environment `_" section -so your python environment is properly configured and has access to the SOFA specific python modules. +SOFA simulation can also be executed from a python environment (including jupyter notebook). +To do so, the Python environment must be filled in for SOFA python modules. +Located in "site-packages/" repositories, the path to these libraries should be added to the ``PYTHONPATH``. +The section "`Setup your python3 environment `_" section details how to configure it. + +Once your python environment is properly configured, you will be able to import SOFA python modules (e.g. ``import Sofa``). +By running your simulation from a python interpreter, you will be responsible for: +* creating the root node +* before calling the ``createScene()`` function +* and later initializing the graph -When working a python3 interpreter, your simulation requires more than only the ``createScene()`` function. Indeed, the python environment does not pre-generate a root node as the runSofa executable is. -One must therefore create it and then call the ``createScene()`` function: +To be run from a python environment, any python script should therefore look like: .. code-block:: python @@ -67,10 +73,20 @@ One must therefore create it and then call the ``createScene()`` function: main() -By structuring your scripts this way, you get the advantage to have a script loadable from both runSofa and a python3 interpreter. -Note that the ``main()`` function runs 10 time steps without any graphical user interface and the script ends. +The above script can be run as follows: +.. code-block:: shell + + python3 example1.py + +It can be noted that: +* by structuring your scripts this way, you get the advantage to have a script loadable from both runSofa and a python3 interpreter. +* in the above example, the ``main()`` function runs 10 time steps without any graphical user interface and the script ends. + -In case you want to manage the simulation from the runSofa GUI, you can simply change the ``main()`` function as follows: +Using the SOFA GUI from a python environment +"""""""""""""""""""""""""""""""""""""""""""" + +In case you want to manage the simulation from the runSofa GUI, you can call the GUI from the ``main()`` function, as follows: .. code-block:: python @@ -85,10 +101,12 @@ In case you want to manage the simulation from the runSofa GUI, you can simply c Sofa.Simulation.initRoot(root) # Import the GUI package + import SofaRuntime import Sofa.Gui - # Launch the GUI (qt or qglviewer) - Sofa.Gui.GUIManager.Init("myscene", "qglviewer") + # Launch the GUI (imgui is now by default, to use Qt please refer to the example "basic-useQtGui.py") + SofaRuntime.importPlugin("SofaImGui") + Sofa.Gui.GUIManager.Init("myscene", "imgui") Sofa.Gui.GUIManager.createGUI(root, __file__) Sofa.Gui.GUIManager.SetDimension(1080, 800) @@ -345,6 +363,7 @@ Here is the entire code of the scene : .. code-block:: python import Sofa + import SofaRuntime import Sofa.Gui @@ -358,8 +377,9 @@ Here is the entire code of the scene : # Once defined, initialization of the scene graph Sofa.Simulation.initRoot(root) - # Launch the GUI (qt or qglviewer) - Sofa.Gui.GUIManager.Init("myscene", "qglviewer") + # Launch the GUI (imgui is now by default, to use Qt please refer to the example "basic-useQtGui.py") + SofaRuntime.importPlugin("SofaImGui") + Sofa.Gui.GUIManager.Init("myscene", "imgui") Sofa.Gui.GUIManager.createGUI(root, __file__) Sofa.Gui.GUIManager.SetDimension(1080, 800) diff --git a/docs/sphinx/source/content/UsingThePlugin.rst b/docs/sphinx/source/content/UsingThePlugin.rst index 88b95707d..f9ccf1825 100644 --- a/docs/sphinx/source/content/UsingThePlugin.rst +++ b/docs/sphinx/source/content/UsingThePlugin.rst @@ -221,8 +221,10 @@ By structuring your scripts this way, you get the advantage to have a script loa # Once defined, initialization of the scene graph Sofa.Simulation.init(root) - # Launch the GUI (qt or qglviewer) - Sofa.Gui.GUIManager.Init("myscene", "qglviewer") + # Launch the GUI (imgui is now by default, to use Qt please refer to the example "basic-useQtGui.py") + import SofaRuntime + SofaRuntime.importPlugin("SofaImGui") + Sofa.Gui.GUIManager.Init("myscene", "imgui") Sofa.Gui.GUIManager.createGUI(root, __file__) Sofa.Gui.GUIManager.SetDimension(1080, 800) @@ -415,6 +417,7 @@ Here is the entire code of the scene : .. code-block:: python import Sofa + import SofaRuntime import Sofa.Gui @@ -428,8 +431,9 @@ Here is the entire code of the scene : # Once defined, initialization of the scene graph Sofa.Simulation.init(root) - # Launch the GUI (qt or qglviewer) - Sofa.Gui.GUIManager.Init("myscene", "qglviewer") + # Launch the GUI (imgui is now by default, to use Qt please refer to the example "basic-useQtGui.py") + SofaRuntime.importPlugin("SofaImGui") + Sofa.Gui.GUIManager.Init("myscene", "imgui") Sofa.Gui.GUIManager.createGUI(root, __file__) Sofa.Gui.GUIManager.SetDimension(1080, 800) @@ -644,6 +648,6 @@ Do not hesitate to take a look and get inspiration! Get support *********** -To freely get technical assistance from the community, please do not hesitate to join the `SofaPython3 GitHub forum `_ and post there any question related to SofaPython3. +To freely get technical assistance from the community, please do not hesitate to join the `SofaPython3 GitHub forum `_ and post there any question related to SofaPython3. To quickly level up on SOFA, never hesitate to request `SOFA training sessions `_. From 8d288c6e9747cdde8d4ac387aec8876ea871bb95 Mon Sep 17 00:00:00 2001 From: hugtalbot Date: Tue, 22 Jul 2025 15:33:43 +0200 Subject: [PATCH 2/6] add description to use SofaQt --- docs/sphinx/source/content/FirstSteps.rst | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/sphinx/source/content/FirstSteps.rst b/docs/sphinx/source/content/FirstSteps.rst index 49ddd714c..3841ca6a9 100644 --- a/docs/sphinx/source/content/FirstSteps.rst +++ b/docs/sphinx/source/content/FirstSteps.rst @@ -19,14 +19,14 @@ Let's now see how this script ``example1.py`` should look like. The first important thing to notice is that to be compatible with SOFA, a python script must define the ``createScene()`` function. This function is the entry point of your simulation and is automatically called by the runSofa application when a python file is loaded. It is responsible for describing and building the SOFA scene graph. -In the section `Create a new simulation ` below, we will detail how to implement this ``createScene()``. +In the section "`Create a new simulation `_" below, we will detail how to implement this ``createScene()``. With the python3 interpreter ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SOFA simulation can also be executed from a python environment (including jupyter notebook). To do so, the Python environment must be filled in for SOFA python modules. -Located in "site-packages/" repositories, the path to these libraries should be added to the ``PYTHONPATH``. +Located in *site-packages/* repositories, the path to these libraries should be added to the ``PYTHONPATH``. The section "`Setup your python3 environment `_" section details how to configure it. Once your python environment is properly configured, you will be able to import SOFA python modules (e.g. ``import Sofa``). @@ -120,6 +120,19 @@ So far, you can load this python scene, but it doesn't do much. Let's enrich thi A scene in SOFA is an ordered tree of nodes representing objects (example of node: hand), with parent/child relationship (example of hand's child: finger). Each node has one or more components. Every node and component has a name and a few features. The main node at the top of the tree is usually called "rootNode" or "root". More about how to create a simulation scene can be found in the `SOFA online documentation `_ +Using the old Qt GUI +"""""""""""""""""""" + +Since SOFA v25.06, SOFA GUI relies on the ImGui library. The previous Qt-based GUI is still available. To use it, make sure to: + +* add the *lib/* repository in the SOFA binaries to your ``LD_LIBRARY_PATH`` +* add the *lib/python3/site-packages/* repository to your ``PYTHONPATH`` +* make sure your SOFA install path does not include any special character + +An example using the Qt GUI is available: `basic-useQtGUI.py `_ + + + Create a new simulation *********************** From e5f203d83d821ec4aa910ed454b171228ac452bc Mon Sep 17 00:00:00 2001 From: hugtalbot Date: Tue, 22 Jul 2025 15:39:27 +0200 Subject: [PATCH 3/6] clarify and clean the installation section --- docs/sphinx/source/content/Installation.rst | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/docs/sphinx/source/content/Installation.rst b/docs/sphinx/source/content/Installation.rst index f08fda875..9ce3f9ae1 100644 --- a/docs/sphinx/source/content/Installation.rst +++ b/docs/sphinx/source/content/Installation.rst @@ -130,20 +130,10 @@ Before running your simulations, you must make sure to define the following envi After that, all you need to do is open a Console (cmd.exe) and run: ``runSofa -lSofaPython3`` +It must be noted that depending on the plugins you use, you might have to add the *site-packages/* paths associated to these plugins to your ``PYTHONPATH``. +These are usually located in */path_to_plugin/lib/python3/site-packages*. -It is possible to use SOFA in any python3 interpreter. -The following code should cover most basic SOFA elements: - -.. code-block:: python - - # to be able to create SOFA objects you need to first load the plugins that implement them. - # For simplicity you can load the plugin "Sofa.Component" that will load all most - # common sofa objects. - import SofaRuntime - SofaRuntime.importPlugin("Sofa.Component") - - # to create elements like Node or objects - import Sofa.Core +To discover, how to use SOFA in any python3 interpreter, please refer to the associated `FirstSteps section `_ Get support From aca8f2a4104236c66c36725fa811d9fc682d7f08 Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 22 Jul 2025 15:41:39 +0200 Subject: [PATCH 4/6] Rename example1 as example --- docs/sphinx/source/content/FirstSteps.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/source/content/FirstSteps.rst b/docs/sphinx/source/content/FirstSteps.rst index 3841ca6a9..04154c201 100644 --- a/docs/sphinx/source/content/FirstSteps.rst +++ b/docs/sphinx/source/content/FirstSteps.rst @@ -13,9 +13,9 @@ Assuming you want to run a script named "example.py", you can run the following .. code-block:: shell - runSofa example1.py + runSofa example.py -Let's now see how this script ``example1.py`` should look like. +Let's now see how this script ``example.py`` should look like. The first important thing to notice is that to be compatible with SOFA, a python script must define the ``createScene()`` function. This function is the entry point of your simulation and is automatically called by the runSofa application when a python file is loaded. It is responsible for describing and building the SOFA scene graph. @@ -76,7 +76,7 @@ To be run from a python environment, any python script should therefore look lik The above script can be run as follows: .. code-block:: shell - python3 example1.py + python3 example.py It can be noted that: * by structuring your scripts this way, you get the advantage to have a script loadable from both runSofa and a python3 interpreter. From 79507e039ce8020243bb24eb58a01609fa16ec6d Mon Sep 17 00:00:00 2001 From: hugtalbot Date: Thu, 24 Jul 2025 15:52:02 +0200 Subject: [PATCH 5/6] simplify writing for ImGui use --- docs/sphinx/source/content/FirstSteps.rst | 6 ++---- docs/sphinx/source/content/UsingThePlugin.rst | 7 +++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/docs/sphinx/source/content/FirstSteps.rst b/docs/sphinx/source/content/FirstSteps.rst index 04154c201..1fac18c7b 100644 --- a/docs/sphinx/source/content/FirstSteps.rst +++ b/docs/sphinx/source/content/FirstSteps.rst @@ -101,11 +101,10 @@ In case you want to manage the simulation from the runSofa GUI, you can call the Sofa.Simulation.initRoot(root) # Import the GUI package - import SofaRuntime + import SofaImGui import Sofa.Gui # Launch the GUI (imgui is now by default, to use Qt please refer to the example "basic-useQtGui.py") - SofaRuntime.importPlugin("SofaImGui") Sofa.Gui.GUIManager.Init("myscene", "imgui") Sofa.Gui.GUIManager.createGUI(root, __file__) Sofa.Gui.GUIManager.SetDimension(1080, 800) @@ -376,7 +375,7 @@ Here is the entire code of the scene : .. code-block:: python import Sofa - import SofaRuntime + import SofaImGui import Sofa.Gui @@ -391,7 +390,6 @@ Here is the entire code of the scene : Sofa.Simulation.initRoot(root) # Launch the GUI (imgui is now by default, to use Qt please refer to the example "basic-useQtGui.py") - SofaRuntime.importPlugin("SofaImGui") Sofa.Gui.GUIManager.Init("myscene", "imgui") Sofa.Gui.GUIManager.createGUI(root, __file__) Sofa.Gui.GUIManager.SetDimension(1080, 800) diff --git a/docs/sphinx/source/content/UsingThePlugin.rst b/docs/sphinx/source/content/UsingThePlugin.rst index f9ccf1825..45deee6e4 100644 --- a/docs/sphinx/source/content/UsingThePlugin.rst +++ b/docs/sphinx/source/content/UsingThePlugin.rst @@ -222,8 +222,8 @@ By structuring your scripts this way, you get the advantage to have a script loa Sofa.Simulation.init(root) # Launch the GUI (imgui is now by default, to use Qt please refer to the example "basic-useQtGui.py") - import SofaRuntime - SofaRuntime.importPlugin("SofaImGui") + import SofaImGui + import Sofa.Gui Sofa.Gui.GUIManager.Init("myscene", "imgui") Sofa.Gui.GUIManager.createGUI(root, __file__) Sofa.Gui.GUIManager.SetDimension(1080, 800) @@ -417,7 +417,7 @@ Here is the entire code of the scene : .. code-block:: python import Sofa - import SofaRuntime + import SofaImGui import Sofa.Gui @@ -432,7 +432,6 @@ Here is the entire code of the scene : Sofa.Simulation.init(root) # Launch the GUI (imgui is now by default, to use Qt please refer to the example "basic-useQtGui.py") - SofaRuntime.importPlugin("SofaImGui") Sofa.Gui.GUIManager.Init("myscene", "imgui") Sofa.Gui.GUIManager.createGUI(root, __file__) Sofa.Gui.GUIManager.SetDimension(1080, 800) From 01a9693220da6b1a318ce6c3a290aed1e517d48d Mon Sep 17 00:00:00 2001 From: Hugo Date: Thu, 24 Jul 2025 16:40:31 +0200 Subject: [PATCH 6/6] Apply suggestions from code review --- docs/sphinx/source/content/FirstSteps.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/source/content/FirstSteps.rst b/docs/sphinx/source/content/FirstSteps.rst index 1fac18c7b..5697879eb 100644 --- a/docs/sphinx/source/content/FirstSteps.rst +++ b/docs/sphinx/source/content/FirstSteps.rst @@ -8,7 +8,13 @@ Executing a simulation With runSofa ^^^^^^^^^^^^ -Making sure the SofaPython3 plugin is loaded, you can load a simulation described by a python script directly in runSofa. +💡 To make sure runSofa is able to load a scene described by a python, you can either: +* open runSofa without any argument once and then add libSofaPython3 in the plugin manager +* or add -l SofaPython3 in this command line. + +For more information, please refer to the documentation: `What is a plugin > Plugin loading`_ + +Once the SofaPython3 plugin is loaded, you can load a simulation from a python script directly in runSofa. Assuming you want to run a script named "example.py", you can run the following command: .. code-block:: shell @@ -16,8 +22,7 @@ Assuming you want to run a script named "example.py", you can run the following runSofa example.py Let's now see how this script ``example.py`` should look like. -The first important thing to notice is that to be compatible with SOFA, a python script must define the ``createScene()`` function. This function is the entry point of your simulation and -is automatically called by the runSofa application when a python file is loaded. It is responsible for describing and building the SOFA scene graph. +The first important thing to notice is that to be compatible with SOFA, a python script must define the ``createScene(root : Sofa.Core.Node)`` function. This function is the entry point of your simulation and it is automatically called by the runSofa application when a python file is loaded. It is responsible for describing and building the SOFA scene graph. In the section "`Create a new simulation `_" below, we will detail how to implement this ``createScene()``.