From 0e11a6c72d3128826acd1770e9f45219cf597193 Mon Sep 17 00:00:00 2001 From: Damien Marchal Date: Mon, 23 Sep 2024 12:24:18 +0200 Subject: [PATCH 1/4] Remove Sofa.Components. I suspect this code to have been integrated in the SofaPython3 by mistake and to have never worked. By looking at it it may be an experiment to allow syntax like this import Sofa.Components Sofa.Components.MechanicalObject() ... --- bindings/Sofa/CMakeLists.txt | 1 - bindings/Sofa/package/__init__.py | 1 - .../Sofa/Components/CMakeLists.txt | 21 --- .../Sofa/Components/Submodule_Components.cpp | 142 ------------------ .../Sofa/Components/Submodule_Components.h | 30 ---- 5 files changed, 195 deletions(-) delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Components/CMakeLists.txt delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.cpp delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.h diff --git a/bindings/Sofa/CMakeLists.txt b/bindings/Sofa/CMakeLists.txt index 9bfab5b51..63227a2b9 100644 --- a/bindings/Sofa/CMakeLists.txt +++ b/bindings/Sofa/CMakeLists.txt @@ -1,7 +1,6 @@ project(Bindings.Sofa) set(SOFABINDINGS_MODULE_LIST - Components Core Helper Simulation diff --git a/bindings/Sofa/package/__init__.py b/bindings/Sofa/package/__init__.py index 5d77db2c5..8b4a62b2d 100644 --- a/bindings/Sofa/package/__init__.py +++ b/bindings/Sofa/package/__init__.py @@ -161,7 +161,6 @@ import Sofa.Core import Sofa.Simulation import Sofa.Types -import Sofa.Components import SofaTypes from .prefab import * diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Components/CMakeLists.txt b/bindings/Sofa/src/SofaPython3/Sofa/Components/CMakeLists.txt deleted file mode 100644 index 67c1e21b9..000000000 --- a/bindings/Sofa/src/SofaPython3/Sofa/Components/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -project(Bindings.Sofa.Components) - -set(HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Components.h -) - -set(SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Components.cpp -) - -sofa_find_package(Sofa.Simulation.Core REQUIRED) - -SP3_add_python_module( - TARGET ${PROJECT_NAME} - PACKAGE Bindings.Sofa - MODULE Components - DESTINATION Sofa - SOURCES ${SOURCE_FILES} - HEADERS ${HEADER_FILES} - DEPENDS Sofa.Simulation.Core SofaPython3::Plugin -) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.cpp deleted file mode 100644 index 639ea6d2b..000000000 --- a/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/****************************************************************************** -* SOFA, Simulation Open-Framework Architecture * -* (c) 2021 INRIA, USTL, UJF, CNRS, MGH * -* * -* 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 -using sofa::core::objectmodel::BaseObjectDescription; -using sofa::core::ObjectFactory; - -#include -using sofa::helper::logging::Message; - -#include -using sofa::simulation::Node; - -#include -#include -#include - -#include -#include -#include - -namespace py = pybind11; -using namespace py::literals; - -namespace sofapython3 -{ - -class FCreator -{ -public: - FCreator(const std::string& n) - { - name = n; - } - std::string name; -}; - -PYBIND11_MODULE(Components, m) -{ - // These are needed to force the dynamic loading of module dependencies (found in CMakeLists.txt) - sofa::core::init(); - sofa::helper::init(); - sofa::simulation::core::init(); - - py::class_ mm(m, "Creator"); - mm.def("__call__", [](FCreator& s, const py::args& args, const py::kwargs& kwargs){ - if(args.size() != 1) - { - throw py::type_error("Invalid number of arguments. Only 1 argument of type 'Node' is allowed."); - } - - py::object pynode = args[0]; - if(!py::isinstance(pynode)) - { - throw py::type_error(std::string("Invalid first argument. Expecting 'Node' but got ") + py::cast(py::str(pynode))); - } - - auto node = py::cast>(pynode); - - /// Prepare the description to hold the different python attributes as data field's - /// arguments then create the object. - BaseObjectDescription desc {s.name.c_str(), s.name.c_str()}; - fillBaseObjectdescription(desc, kwargs); - auto object = py_shared_ptr(ObjectFactory::getInstance()->createObject(node.get(), &desc)); - - /// After calling createObject the returned value can be either a nullptr - /// or non-null but with error message or non-null. - /// Let's first handle the case when the returned pointer is null. - if(!object) - { - std::stringstream tmp ; - for(auto& s : desc.getErrors()) - tmp << s << msgendl ; - throw py::value_error(tmp.str()); - } - - //checkParamUsage(object.get(), desc); - - /// Convert the logged messages in the object's internal logging into python exception. - /// this is not a very fast way to do that...but well...python is slow anyway. And serious - /// error management has a very high priority. If performance becomes an issue we will fix it - /// when needed. - if(object->countLoggedMessages({Message::Error})) - { - throw py::value_error(object->getLoggedMessagesAsString({Message::Error})); - } - - return py::cast(object); - }); - - m.def("__getattr__", [](const std::string& name) -> py::object - { - return py::cast(new FCreator(name)); - }); - - // THIS PART IS NOT WORKING... - //todo(dmarchal 04/07/2019): do it or delete it in one year. -// py::list names; -// std::vector entries ; -// ObjectFactory::getInstance()->getAllEntries(entries) ; - -// for(auto& entry : entries) -// { -// names.append(entry->className); -// } - -// simulation.def("__dir__", []() -> py::object -// { -// py::list names; -// std::vector entries ; -// ObjectFactory::getInstance()->getAllEntries(entries) ; - -// for(auto& entry : entries) -// { -// names.append(entry->className); -// } -// return names; //std::move(names); -// }); - -} - -} /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.h b/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.h deleted file mode 100644 index 8c22387f9..000000000 --- a/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** -* SOFA, Simulation Open-Framework Architecture * -* (c) 2021 INRIA, USTL, UJF, CNRS, MGH * -* * -* 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 -{ -namespace py { using namespace pybind11; } - -} ///namespace sofapython3 - From ddead4d85aaba2b642ce7530511827722d77bbf8 Mon Sep 17 00:00:00 2001 From: Damien Marchal Date: Mon, 23 Sep 2024 14:58:13 +0200 Subject: [PATCH 2/4] Example on how to fix pybind11 type forward declaration so stubgens knows about them. The problem: Depending on the definition order of the binded classes, there may have incorrect types if Base is useing BaseData... but BaseData is only binded after Base. The PR propose a solution for that using a decidcated "forward" registration patter. --- .../src/SofaPython3/Sofa/Core/Binding_Base.cpp | 5 +++++ .../SofaPython3/Sofa/Core/Binding_BaseData.cpp | 16 +++++++++++++++- .../src/SofaPython3/Sofa/Core/Binding_BaseData.h | 1 + .../SofaPython3/Sofa/Core/Binding_BaseLink.cpp | 14 +++++++++++++- .../src/SofaPython3/Sofa/Core/Binding_BaseLink.h | 1 + .../Sofa/Core/Binding_ObjectFactory.cpp | 6 ++++-- 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp index 88f3a6df4..6aa8d7631 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp @@ -34,6 +34,8 @@ using sofa::helper::WriteOnlyAccessor; #include +#include +#include #include #include #include @@ -449,6 +451,9 @@ py::object BindingBase::setDataValues(Base& self, py::kwargs kwargs) void moduleAddBase(py::module &m) { + moduleForwardAddBaseData(m); + moduleForwardAddBaseLink(m); + py::class_> base(m, "Base", py::dynamic_attr(), doc::base::BaseClass); /// set & get the name as string. The alternative is to access the data field using /// obj.name.value = "aName" diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp index f70de7c9c..ecc837503 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp @@ -192,10 +192,24 @@ std::string getValueTypeString(BaseData* data) return data->getValueTypeInfo()->name(); } +auto getPythonClassForBaseData(py::module& m) +{ + /// Register the BaseData binding into the pybind11 system. + static py::class_> data(m, "Data", sofapython3::doc::baseData::BaseDataClass); + return data; +} + +void moduleForwardAddBaseData(py::module& m) +{ + getPythonClassForBaseData(m); +} + void moduleAddBaseData(py::module& m) { /// Register the BaseData binding into the pybind11 system. - py::class_> data(m, "Data", sofapython3::doc::baseData::BaseDataClass); + //py::class_> data(m, "Data", sofapython3::doc::baseData::BaseDataClass); + + auto data =getPythonClassForBaseData(m); data.def("getName", [](BaseData& b){ return b.getName(); }, sofapython3::doc::baseData::getName); data.def("setName", [](BaseData& b, const std::string& s){ b.setName(s); }, sofapython3::doc::baseData::setName); data.def("getCounter", [](BaseData& self) { return self.getCounter(); }, sofapython3::doc::baseData::getCounter); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h index 6a747d1d7..badd65220 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h @@ -24,6 +24,7 @@ namespace sofapython3 { + void moduleForwardAddBaseData(pybind11::module& m); void moduleAddBaseData(pybind11::module& m); } /// sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.cpp index 101b88f88..c658eaec7 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.cpp @@ -91,9 +91,21 @@ void __setattr__(py::object self, const std::string& s, py::object value) } } +auto getPythonClassForBaseLink(py::module& m) +{ + /// Register the BaseData binding into the pybind11 system. + static py::class_ link(m, "Link", sofapython3::doc::baseLink::baseLinkClass); + return link; +} + +void moduleForwardAddBaseLink(py::module& m) +{ + getPythonClassForBaseLink(m); +} + void moduleAddBaseLink(py::module& m) { - py::class_ link(m, "Link", sofapython3::doc::baseLink::baseLinkClass); + auto link = getPythonClassForBaseLink(m); link.def("getName", &BaseLink::getName, sofapython3::doc::baseLink::getName); link.def("setName", &BaseLink::setName, sofapython3::doc::baseLink::setName); link.def("isMultiLink", &BaseLink::isMultiLink, sofapython3::doc::baseLink::isMultiLink); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h index 6f03d5af6..1cf5df4ae 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h @@ -24,6 +24,7 @@ namespace sofapython3 { + void moduleForwardAddBaseLink(pybind11::module& m); void moduleAddBaseLink(pybind11::module& m); } /// sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.cpp index 2be5a3574..71dbfe451 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.cpp @@ -169,9 +169,11 @@ py::dict dataAlias(const ObjectFactory::ClassEntry &self) void moduleAddObjectFactory(py::module &m) { - py::class_ factory (m, "ObjectFactory", sofapython3::doc::objectmodel::ObjectFactoryClass); + py::class_ factory (m, "ObjectFactory", + sofapython3::doc::objectmodel::ObjectFactoryClass); - py::class_ entry(m, sofapython3::doc::objectmodel::ClassEntryClass); + py::class_ entry(m, "ClassEntry", + sofapython3::doc::objectmodel::ClassEntryClass); entry.def_property_readonly("className", &className); entry.def_property_readonly("aliases", &aliases); entry.def_property_readonly("description", &description); From 8446233cb3cd3c4804cb5c1ade20e96fb4ae63b1 Mon Sep 17 00:00:00 2001 From: Damien Marchal Date: Fri, 11 Oct 2024 17:00:49 +0200 Subject: [PATCH 3/4] Update tests to take into account removal of Sofa.Components. --- .../tests/SofaConstraintSolver/matrix_access.py | 1 - .../Modules/tests/SofaLinearSolver/matrix_access.py | 1 - bindings/Sofa/Bindings.SofaConfig.cmake.in | 2 +- bindings/Sofa/tests/CMakeLists.txt | 1 - bindings/Sofa/tests/Components/Components.py | 13 ------------- 5 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 bindings/Sofa/tests/Components/Components.py diff --git a/bindings/Modules/tests/SofaConstraintSolver/matrix_access.py b/bindings/Modules/tests/SofaConstraintSolver/matrix_access.py index 1a8dacdcd..d4a7f2894 100644 --- a/bindings/Modules/tests/SofaConstraintSolver/matrix_access.py +++ b/bindings/Modules/tests/SofaConstraintSolver/matrix_access.py @@ -1,6 +1,5 @@ import unittest import Sofa.Core -import Sofa.Components from Sofa import SofaConstraintSolver class Test(unittest.TestCase): diff --git a/bindings/Modules/tests/SofaLinearSolver/matrix_access.py b/bindings/Modules/tests/SofaLinearSolver/matrix_access.py index 0bb0618cb..09698bd29 100644 --- a/bindings/Modules/tests/SofaLinearSolver/matrix_access.py +++ b/bindings/Modules/tests/SofaLinearSolver/matrix_access.py @@ -1,6 +1,5 @@ import unittest import Sofa.Core -import Sofa.Components from Sofa import SofaLinearSolver class Test(unittest.TestCase): diff --git a/bindings/Sofa/Bindings.SofaConfig.cmake.in b/bindings/Sofa/Bindings.SofaConfig.cmake.in index c9f25fd66..864892140 100644 --- a/bindings/Sofa/Bindings.SofaConfig.cmake.in +++ b/bindings/Sofa/Bindings.SofaConfig.cmake.in @@ -8,7 +8,7 @@ find_package(SofaPython3 QUIET REQUIRED COMPONENTS Plugin) # Required by Bindings.Sofa.Helper, Bindings.Sofa.Types find_package(Sofa.Core QUIET REQUIRED) -# Required by Bindings.Sofa.Core, Bindings.Sofa.Components +# Required by Bindings.Sofa.Core find_package(Sofa.Simulation.Core QUIET REQUIRED) # Required by Bindings.Sofa.Core diff --git a/bindings/Sofa/tests/CMakeLists.txt b/bindings/Sofa/tests/CMakeLists.txt index 36d74080d..2e30bd5d6 100644 --- a/bindings/Sofa/tests/CMakeLists.txt +++ b/bindings/Sofa/tests/CMakeLists.txt @@ -10,7 +10,6 @@ set(SOURCE_FILES ) set(PYTHON_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/Components/Components.py ${CMAKE_CURRENT_SOURCE_DIR}/Core/Base.py ${CMAKE_CURRENT_SOURCE_DIR}/Core/BaseData.py ${CMAKE_CURRENT_SOURCE_DIR}/Core/BaseLink.py diff --git a/bindings/Sofa/tests/Components/Components.py b/bindings/Sofa/tests/Components/Components.py deleted file mode 100644 index d51891d4c..000000000 --- a/bindings/Sofa/tests/Components/Components.py +++ /dev/null @@ -1,13 +0,0 @@ -# coding: utf8 - -import Sofa.Core -import Sofa.Components -import unittest - -class Test(unittest.TestCase): - def test_component_creation(self): - root = Sofa.Core.Node("rootNode") - root.addObject('RequiredPlugin', name='Sofa.Component.StateContainer') - - c = Sofa.Components.MechanicalObject(root, name="dofs") - self.assertTrue(c.name.value == "dofs") From cb781a47c6bb6552993abae7976fe1095291cd48 Mon Sep 17 00:00:00 2001 From: Damien Marchal Date: Mon, 14 Oct 2024 15:47:26 +0200 Subject: [PATCH 4/4] FIXUP --- bindings/Sofa/tests/CMakeLists.txt | 1 - bindings/Sofa/tests/PythonModule_Sofa_test.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/bindings/Sofa/tests/CMakeLists.txt b/bindings/Sofa/tests/CMakeLists.txt index 2e30bd5d6..038c1cf0f 100644 --- a/bindings/Sofa/tests/CMakeLists.txt +++ b/bindings/Sofa/tests/CMakeLists.txt @@ -50,7 +50,6 @@ sofa_auto_set_target_rpath( add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) set(DIR_BINDING_LIST - Components Core Helper Simulation diff --git a/bindings/Sofa/tests/PythonModule_Sofa_test.cpp b/bindings/Sofa/tests/PythonModule_Sofa_test.cpp index 4ddc5bf37..9d80485e5 100644 --- a/bindings/Sofa/tests/PythonModule_Sofa_test.cpp +++ b/bindings/Sofa/tests/PythonModule_Sofa_test.cpp @@ -58,7 +58,6 @@ static struct PythonModule_Sofa_tests : public PythonTestExtractor addTestDirectory(executable_directory+"/Bindings.Sofa.Tests.d/Helper", "Sofa_Helper_"); addTestDirectory(executable_directory+"/Bindings.Sofa.Tests.d/Simulation", "Sofa_Simulation_"); addTestDirectory(executable_directory+"/Bindings.Sofa.Tests.d/Types", "Sofa_Types_"); - addTestDirectory(executable_directory+"/Bindings.Sofa.Tests.d/Components", "Sofa_Components_"); } } python_tests;