diff --git a/bindings/Sofa/package/__init__.py b/bindings/Sofa/package/__init__.py
index 8926e8cee..5b73b863a 100644
--- a/bindings/Sofa/package/__init__.py
+++ b/bindings/Sofa/package/__init__.py
@@ -195,6 +195,11 @@ def unloadModules():
for name in toremove:
del(sys.modules[name]) # unload it
+def GetVersion():
+ """Returns the version of SOFA as a string in the format 'vMM.mm', where MM is the major version and mm is the
+ minor version.
+ """
+ return Sofa.Helper.GetVersion()
def formatStackForSofa(o):
""" format the stack trace provided as a parameter into a string like that:
diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Version.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Version.cpp
new file mode 100644
index 000000000..d3973be25
--- /dev/null
+++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Version.cpp
@@ -0,0 +1,57 @@
+/******************************************************************************
+* SofaPython3 plugin *
+* (c) 2021 CNRS, University of Lille, INRIA *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 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 Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+
+/// Makes an alias for the pybind11 namespace to increase readability.
+namespace py { using namespace pybind11; }
+
+namespace sofapython3
+{
+
+void moduleAddVersion(py::module &m)
+{
+ m.def("GetVersion",
+ []()
+ {
+ static const std::string sofaVersion = []() {
+ std::stringstream version;
+ constexpr auto major = SOFA_VERSION / 10000;
+ constexpr auto minor = SOFA_VERSION / 100 % 100;
+ version << 'v'
+ << std::setfill('0') << std::setw(2) << major
+ << "."
+ << std::setfill('0') << std::setw(2) << minor;
+ return version.str();
+ }();
+ return sofaVersion;
+ },
+ "Returns the version of SOFA as a string in the format 'vMM.mm', where MM is the major version and mm is the minor version.");
+}
+
+
+}
diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Version.h b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Version.h
new file mode 100644
index 000000000..178ac422a
--- /dev/null
+++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Version.h
@@ -0,0 +1,30 @@
+/******************************************************************************
+* SofaPython3 plugin *
+* (c) 2021 CNRS, University of Lille, INRIA *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 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 Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+
+#pragma once
+
+#include
+
+namespace sofapython3
+{
+
+void moduleAddVersion(pybind11::module &m);
+
+}
diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/CMakeLists.txt b/bindings/Sofa/src/SofaPython3/Sofa/Helper/CMakeLists.txt
index b65f18044..1283bc540 100644
--- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/CMakeLists.txt
+++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/CMakeLists.txt
@@ -3,6 +3,7 @@ project(Bindings.Sofa.Helper)
set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Utils.h
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Vector.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Version.h
${CMAKE_CURRENT_SOURCE_DIR}/System/Submodule_System.h
${CMAKE_CURRENT_SOURCE_DIR}/Binding_MessageHandler.h
${CMAKE_CURRENT_SOURCE_DIR}/System/Binding_FileRepository.h
@@ -13,6 +14,7 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/Binding_MessageHandler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Vector.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Version.cpp
${CMAKE_CURRENT_SOURCE_DIR}/System/Submodule_System.cpp
${CMAKE_CURRENT_SOURCE_DIR}/System/Binding_FileRepository.cpp
)
diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.cpp
index 4c80cb148..1fb3690fa 100644
--- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.cpp
+++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.cpp
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
/// Makes an alias for the pybind11 namespace to increase readability.
namespace py { using namespace pybind11; }
@@ -153,6 +154,7 @@ PYBIND11_MODULE(Helper, helper)
moduleAddVector(helper);
moduleAddSystem(helper);
moduleAddUtils(helper);
+ moduleAddVersion(helper);
auto atexit = py::module_::import("atexit");
atexit.attr("register")(py::cpp_function([]() {
diff --git a/bindings/Sofa/tests/CMakeLists.txt b/bindings/Sofa/tests/CMakeLists.txt
index 038c1cf0f..f4dde4270 100644
--- a/bindings/Sofa/tests/CMakeLists.txt
+++ b/bindings/Sofa/tests/CMakeLists.txt
@@ -22,6 +22,7 @@ set(PYTHON_FILES
${CMAKE_CURRENT_SOURCE_DIR}/Core/Mass.py
${CMAKE_CURRENT_SOURCE_DIR}/Core/MyRestShapeForceField.py
${CMAKE_CURRENT_SOURCE_DIR}/Helper/Message.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/Helper/Version.py
${CMAKE_CURRENT_SOURCE_DIR}/Simulation/Node.py
${CMAKE_CURRENT_SOURCE_DIR}/Simulation/Simulation.py
${CMAKE_CURRENT_SOURCE_DIR}/Types/BoundingBox.py
diff --git a/bindings/Sofa/tests/Helper/Version.py b/bindings/Sofa/tests/Helper/Version.py
new file mode 100644
index 000000000..dc62c5c34
--- /dev/null
+++ b/bindings/Sofa/tests/Helper/Version.py
@@ -0,0 +1,26 @@
+import Sofa
+import Sofa.Helper
+import unittest
+
+class GetVersionTest(unittest.TestCase):
+ """
+ Contains unit tests for verifying the existence and format of the `GetVersion` method
+ in the `Sofa.Helper.Utils` module.
+
+ Includes tests to assert that the version is correctly formatted and meets the expected
+ structure.
+ """
+ def test_exist(self):
+ self.assertTrue(hasattr(Sofa.Helper, "GetVersion"))
+
+ def test_version_format(self):
+ version = Sofa.Helper.GetVersion()
+ print(f"SOFA Version: {version}")
+ self.assertTrue(version.startswith('v'))
+ version = version.replace('v', '')
+ self.assertTrue(version.count('.') == 1)
+ major, minor = version.split('.')
+ self.assertTrue(major.isdigit())
+ self.assertTrue(minor.isdigit())
+ self.assertEqual(len(major), 2)
+ self.assertEqual(len(minor), 2)