From b6b169cd01443a04752af9b9866266456dd75a88 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Mon, 14 Dec 2020 10:59:12 +0100 Subject: [PATCH 1/2] Fix windows compilation and install in user directory --- CMakeLists.txt | 17 +++- Plugin/src/SofaPython3/DataHelper.h | 10 +-- .../Sofa/Core/Binding_Controller.cpp | 77 +++++-------------- .../Sofa/Core/Binding_Controller.h | 31 +++++--- 4 files changed, 61 insertions(+), 74 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24529cf0..5e2f8370 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,9 @@ if(MSVC) # With C++17 (/std:c++17), to get MSVC to behave, you need /permissive- # see https://github.com/pybind/pybind11/issues/1616 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-") + + # use M_PI in cmath.h + add_definitions("-D_USE_MATH_DEFINES") endif() set(CMAKE_CXX_STANDARD 17) @@ -172,13 +175,23 @@ if (SP3_LINK_TO_USER_SITE AND SP3_PYTHON_PACKAGES_LINK_DIRECTORY) install(DIRECTORY DESTINATION ${SP3_PYTHON_PACKAGES_LINK_DIRECTORY}) foreach(directory ${directories}) if(IS_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SP3_PYTHON_PACKAGES_DIRECTORY}/${directory}) - install(CODE "\ + if(WIN32) + install(CODE "\ execute_process( \ - COMMAND ${CMAKE_COMMAND} -E create_symlink \ + COMMAND ${CMAKE_COMMAND} -E copy_directory \ ${CMAKE_INSTALL_PREFIX}/${LIBRARY_OUTPUT_DIRECTORY}/${SP3_PYTHON_PACKAGES_DIRECTORY}/${directory}/ \ ${SP3_PYTHON_PACKAGES_LINK_DIRECTORY}/${directory} \ )" ) + else() + install(CODE "\ + execute_process( \ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${CMAKE_INSTALL_PREFIX}/${LIBRARY_OUTPUT_DIRECTORY}/${SP3_PYTHON_PACKAGES_DIRECTORY}/${directory}/ \ + ${SP3_PYTHON_PACKAGES_LINK_DIRECTORY}/${directory} \ + )" + ) + endif() endif() endforeach() endif() diff --git a/Plugin/src/SofaPython3/DataHelper.h b/Plugin/src/SofaPython3/DataHelper.h index 6a46f0a1..75cd2a7b 100644 --- a/Plugin/src/SofaPython3/DataHelper.h +++ b/Plugin/src/SofaPython3/DataHelper.h @@ -205,12 +205,10 @@ class SOFAPYTHON3_API PythonTrampoline template class py_shared_ptr : public sofa::core::sptr { public: - py_shared_ptr(T *ptr) : sofa::core::sptr(ptr) - { - auto nptr = dynamic_cast(ptr); - if(nptr) - nptr->setInstance( py::cast(ptr) ) ; - } + using Base = typename sofa::core::sptr; + using Base::Base; + py_shared_ptr(const py_shared_ptr& other, T* ptr) : sofa::core::sptr(ptr) {} + py_shared_ptr(T* ptr) : sofa::core::sptr(ptr) {} }; SOFAPYTHON3_API void setItem2D(py::array a, py::slice slice, py::object o); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.cpp index a49dedae..f57669cf 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.cpp @@ -26,6 +26,7 @@ along with sofaqtquick. If not, see . ********************************************************************/ #include +#include #include "Binding_Controller.h" #include "Binding_Controller_doc.h" @@ -42,39 +43,6 @@ namespace sofapython3 { using sofa::core::objectmodel::Event; - void Controller::init() { - } - - void Controller::reinit() { - } - - Controller::Controller() { - } - - Controller::~Controller() { - } - - class Controller_Trampoline : public Controller, public PythonTrampoline - { - public: - Controller_Trampoline() = default; - - ~Controller_Trampoline() override = default; - - std::string getClassName() const override - { - return pyobject->ob_type->tp_name; - } - - void init() override ; - void reinit() override ; - void handleEvent(Event* event) override ; - - private: - void callScriptMethod(const py::object& self, Event* event, - const std::string & methodName); - }; - void Controller_Trampoline::init() { PythonEnvironment::gil acquire {"Controller_init"}; @@ -120,39 +88,36 @@ namespace sofapython3 callScriptMethod(self, event, "onEvent"); } - - void moduleAddController(py::module &m) { py::class_> f(m, "Controller", py::dynamic_attr(), - py::multiple_inheritance(), sofapython3::doc::controller::Controller); f.def(py::init([](py::args& /*args*/, py::kwargs& kwargs) { - auto c = new Controller_Trampoline(); - c->f_listening.setValue(true); - - for(auto kv : kwargs) - { - std::string key = py::cast(kv.first); - py::object value = py::reinterpret_borrow(kv.second); - - if( key == "name") - c->setName(py::cast(kv.second)); - try { - BindingBase::SetAttr(*c, key, value); - } catch (py::attribute_error& /*e*/) { - /// kwargs are used to set datafields to their initial values, - /// but they can also be used as simple python attributes, unrelated to SOFA. - /// thus we catch & ignore the py::attribute_error thrown by SetAttr - } - } - return c; - })); + auto c = new Controller_Trampoline(); + c->f_listening.setValue(true); + + for(auto kv : kwargs) + { + std::string key = py::cast(kv.first); + py::object value = py::reinterpret_borrow(kv.second); + + if( key == "name") + c->setName(py::cast(kv.second)); + try { + BindingBase::SetAttr(*c, key, value); + } catch (py::attribute_error& /*e*/) { + /// kwargs are used to set datafields to their initial values, + /// but they can also be used as simple python attributes, unrelated to SOFA. + /// thus we catch & ignore the py::attribute_error thrown by SetAttr + } + } + return c; + })); f.def("init", &Controller::init); f.def("reinit", &Controller::reinit); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.h index 6edc7a6e..bd1acdaa 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.h @@ -26,16 +26,11 @@ along with sofaqtquick. If not, see . ********************************************************************/ #pragma once - #include "Binding_BaseObject.h" +#include #include -template class pybind11::class_>; - - namespace sofapython3 { using sofa::core::behavior::BaseController; @@ -44,14 +39,30 @@ class Controller : public BaseController { public: SOFA_CLASS(Controller, BaseController); - void init() override ; - void reinit() override; + void init() override {}; + void reinit() override {}; - Controller(); - ~Controller() override; + Controller() {}; + ~Controller() override {}; }; void moduleAddController(py::module &m); +class Controller_Trampoline : public Controller +{ +public: + Controller_Trampoline() = default; + + ~Controller_Trampoline() override = default; + + void init() override; + void reinit() override; + void handleEvent(sofa::core::objectmodel::Event* event) override; + +private: + void callScriptMethod(const py::object& self, sofa::core::objectmodel::Event* event, + const std::string& methodName); +}; + } /// namespace sofapython3 From cba740890a413776cb7ac7b4c750d9ac07c78aa0 Mon Sep 17 00:00:00 2001 From: Jean-Nicolas Brunet Date: Fri, 18 Dec 2020 16:38:43 +0100 Subject: [PATCH 2/2] Redesign holder types and fix corrupted memory with virtual inheritance This commit make use of a custom py_shared_ptr holder type that will hold the virtual pointers to SOFA objects (inheriting from Base). The holder also keeps an internal copy of the initial python object to avoid slicing when the latter gets deleted by python before the C++ wrapper. This commit also brings several cleanup to the overall source code of the bindings. --- .github/workflows/macos.yml | 15 +- .github/workflows/ubuntu.yml | 4 +- CMake/SofaPython3Tools.cmake | 3 +- Plugin/CMakeLists.txt | 1 - Plugin/src/SofaPython3/DataHelper.cpp | 15 -- Plugin/src/SofaPython3/DataHelper.h | 61 ++---- Plugin/src/SofaPython3/Prefab.cpp | 6 +- Plugin/src/SofaPython3/Prefab.h | 2 +- Plugin/src/SofaPython3/PythonEnvironment.cpp | 4 +- Plugin/src/SofaPython3/PythonEnvironment.h | 5 +- Plugin/src/SofaPython3/PythonFactory.cpp | 9 +- Plugin/src/SofaPython3/PythonFactory.h | 21 +- Plugin/src/SofaPython3/PythonTest.h | 2 +- .../Sofa/Components/Submodule_Components.cpp | 11 +- .../SofaPython3/Sofa/Core/Binding_Base.cpp | 28 ++- .../src/SofaPython3/Sofa/Core/Binding_Base.h | 202 ++++++++++++++---- .../Sofa/Core/Binding_BaseCamera.cpp | 19 +- .../Sofa/Core/Binding_BaseCamera.h | 12 +- .../Sofa/Core/Binding_BaseContext.cpp | 7 +- .../Sofa/Core/Binding_BaseContext.h | 13 +- .../Sofa/Core/Binding_BaseData.cpp | 24 ++- .../SofaPython3/Sofa/Core/Binding_BaseData.h | 10 +- .../Sofa/Core/Binding_BaseLink.cpp | 16 +- .../SofaPython3/Sofa/Core/Binding_BaseLink.h | 9 +- .../Sofa/Core/Binding_BaseObject.cpp | 20 +- .../Sofa/Core/Binding_BaseObject.h | 17 +- .../SofaPython3/Sofa/Core/Binding_Context.cpp | 10 +- .../SofaPython3/Sofa/Core/Binding_Context.h | 12 +- .../Sofa/Core/Binding_Controller.cpp | 16 +- .../Sofa/Core/Binding_Controller.h | 29 ++- .../Sofa/Core/Binding_DataDict.cpp | 13 +- .../SofaPython3/Sofa/Core/Binding_DataDict.h | 21 +- .../Sofa/Core/Binding_DataEngine.cpp | 56 ++--- .../Sofa/Core/Binding_DataEngine.h | 20 +- .../Sofa/Core/Binding_ForceField.cpp | 158 +++++++------- .../Sofa/Core/Binding_ForceField.h | 16 +- .../SofaPython3/Sofa/Core/Binding_Node.cpp | 55 +++-- .../src/SofaPython3/Sofa/Core/Binding_Node.h | 12 +- .../Sofa/Core/Binding_NodeIterator.cpp | 16 +- .../Sofa/Core/Binding_NodeIterator.h | 25 +-- .../Sofa/Core/Binding_ObjectFactory.cpp | 5 +- .../Sofa/Core/Binding_ObjectFactory.h | 1 - .../SofaPython3/Sofa/Core/Binding_Prefab.cpp | 40 ++-- .../SofaPython3/Sofa/Core/Binding_Prefab.h | 17 +- .../Sofa/Core/Binding_PythonScriptEvent.cpp | 6 +- .../Sofa/Core/Binding_PythonScriptEvent.h | 8 +- .../SofaPython3/Sofa/Core/Binding_Visitor.cpp | 27 --- .../SofaPython3/Sofa/Core/Binding_Visitor.h | 27 --- .../Sofa/Core/Binding_Visitor_doc.h | 36 ---- .../src/SofaPython3/Sofa/Core/CMakeLists.txt | 4 - .../SofaPython3/Sofa/Core/Submodule_Core.cpp | 44 ++-- .../SofaPython3/Sofa/Core/Submodule_Core.h | 38 ---- .../Sofa/Helper/Binding_MessageHandler.cpp | 42 +--- .../Sofa/Helper/Binding_MessageHandler.h | 30 +-- .../Sofa/Helper/Binding_MessageHandler_doc.h | 0 .../SofaPython3/Sofa/Helper/Binding_Vector.h | 8 +- .../SofaPython3/Sofa/Helper/CMakeLists.txt | 1 - .../Sofa/Helper/Submodule_Helper.cpp | 13 +- .../Sofa/Helper/Submodule_Helper.h | 37 ---- .../Helper/System/Binding_FileRepository.cpp | 5 +- .../Helper/System/Binding_FileRepository.h | 8 +- .../Sofa/Helper/System/Submodule_System.cpp | 12 +- .../Sofa/Helper/System/Submodule_System.h | 6 +- .../Sofa/Simulation/CMakeLists.txt | 3 +- .../Sofa/Simulation/Submodule_Simulation.cpp | 4 +- .../Sofa/Types/Binding_BoundingBox.cpp | 14 +- .../Sofa/Types/Binding_BoundingBox.h | 6 +- .../src/SofaPython3/Sofa/Types/CMakeLists.txt | 1 - .../Sofa/Types/Submodule_Types.cpp | 6 +- .../SofaPython3/Sofa/Types/Submodule_Types.h | 37 ---- bindings/Sofa/tests/Core/ForceField.py | 1 + .../SofaGui/Binding_GUIManager.cpp | 5 +- .../SofaPython3/SofaGui/Binding_GUIManager.h | 10 +- 73 files changed, 619 insertions(+), 878 deletions(-) delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor.cpp delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor.h delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor_doc.h delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.h delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler_doc.h delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.h delete mode 100644 bindings/Sofa/src/SofaPython3/Sofa/Types/Submodule_Types.h diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7f5c7c8f..04ec88ba 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -69,6 +69,7 @@ jobs: -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_PREFIX_PATH=$SOFA_ROOT/lib/cmake + -DCMAKE_BUILD_TYPE=Release . && ninja && ninja install && echo ${CCACHE_BASEDIR} @@ -125,24 +126,22 @@ jobs: - name: Binding.Sofa.Tests if: ${{ always() }} run: | - export DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib:$DYLD_LIBRARY_PATH - export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/python3/site-packages:$PYTHONPATH - export SOFA_PLUGIN_PATH=$SOFA_ROOT/plugins + export DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib + export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/python3/site-packages chmod +x SofaPython3/bin/Bindings.Sofa.Tests ./SofaPython3/bin/Bindings.Sofa.Tests - name: Bindings.SofaRuntime.Tests if: ${{ always() }} run: | - export DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib:$DYLD_LIBRARY_PATH - export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/python3/site-packages:$PYTHONPATH - export SOFA_PLUGIN_PATH=$SOFA_ROOT/plugins + export DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib + export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/python3/site-packages chmod +x SofaPython3/bin/Bindings.SofaRuntime.Tests ./SofaPython3/bin/Bindings.SofaRuntime.Tests - name: Bindings.SofaTypes.Tests if: ${{ always() }} run: | - export DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib:$DYLD_LIBRARY_PATH - export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/python3/site-packages:$PYTHONPATH + export DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib + export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/python3/site-packages chmod +x SofaPython3/bin/Bindings.SofaTypes.Tests ./SofaPython3/bin/Bindings.SofaTypes.Tests diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index e14c5e2d..2dd64f7b 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -85,6 +85,7 @@ jobs: -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_PREFIX_PATH=$SOFA_ROOT/lib/cmake + -DCMAKE_BUILD_TYPE=Release . && ninja && ninja install && echo ${CCACHE_BASEDIR} @@ -143,7 +144,6 @@ jobs: run: | export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib:$LD_LIBRARY_PATH export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/python3/site-packages:$PYTHONPATH - export SOFA_PLUGIN_PATH=$SOFA_ROOT/plugins chmod +x SofaPython3/bin/Bindings.Sofa.Tests ./SofaPython3/bin/Bindings.Sofa.Tests - name: Bindings.SofaRuntime.Tests @@ -151,7 +151,6 @@ jobs: run: | export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib:$LD_LIBRARY_PATH export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/python3/site-packages:$PYTHONPATH - export SOFA_PLUGIN_PATH=$SOFA_ROOT/plugins chmod +x SofaPython3/bin/Bindings.SofaRuntime.Tests ./SofaPython3/bin/Bindings.SofaRuntime.Tests - name: Bindings.SofaTypes.Tests @@ -159,7 +158,6 @@ jobs: run: | export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/SofaPython3/lib:$SOFA_ROOT/lib:$LD_LIBRARY_PATH export PYTHONPATH=$GITHUB_WORKSPACE/SofaPython3/lib/python3/site-packages:$PYTHONPATH - export SOFA_PLUGIN_PATH=$SOFA_ROOT/plugins chmod +x SofaPython3/bin/Bindings.SofaTypes.Tests ./SofaPython3/bin/Bindings.SofaTypes.Tests diff --git a/CMake/SofaPython3Tools.cmake b/CMake/SofaPython3Tools.cmake index e6493c8f..8e784ddf 100644 --- a/CMake/SofaPython3Tools.cmake +++ b/CMake/SofaPython3Tools.cmake @@ -125,12 +125,13 @@ function(SP3_add_python_module) PUBLIC $ ) - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang or AppleCLang target_compile_options(${A_TARGET} PUBLIC -fsized-deallocation) endif() if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") target_compile_options(${A_TARGET} PRIVATE -Dregister=) + target_compile_options(${A_TARGET} PRIVATE -fvisibility=hidden) endif() target_link_libraries(${A_TARGET} PUBLIC pybind11::module) diff --git a/Plugin/CMakeLists.txt b/Plugin/CMakeLists.txt index 52038e49..15adcc15 100644 --- a/Plugin/CMakeLists.txt +++ b/Plugin/CMakeLists.txt @@ -37,7 +37,6 @@ endif(SP3_BUILD_TEST) find_package(pybind11 CONFIG REQUIRED) find_package(SofaFramework REQUIRED) find_package(SofaSimulation REQUIRED) -find_package(SofaGeneral REQUIRED) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) add_library(SofaPython3::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) diff --git a/Plugin/src/SofaPython3/DataHelper.cpp b/Plugin/src/SofaPython3/DataHelper.cpp index 3e73f0db..f434ae16 100644 --- a/Plugin/src/SofaPython3/DataHelper.cpp +++ b/Plugin/src/SofaPython3/DataHelper.cpp @@ -66,21 +66,6 @@ void fillBaseObjectdescription(sofa::core::objectmodel::BaseObjectDescription& d } } -PythonTrampoline::~PythonTrampoline(){} -void PythonTrampoline::setInstance(py::object s) -{ - s.inc_ref(); - - // TODO(bruno-marques) ici ça crash dans SOFA. - //--ref_counter; - - pyobject = std::shared_ptr( s.ptr(), [](PyObject* ob) - { - // runSofa Sofa/tests/pyfiles/ScriptController.py => CRASH - // Py_DECREF(ob); -}); -} - std::ostream& operator<<(std::ostream& out, const py::buffer_info& p) { out << "buffer{"<< p.format << ", " << p.ndim << ", " << p.shape[0]; diff --git a/Plugin/src/SofaPython3/DataHelper.h b/Plugin/src/SofaPython3/DataHelper.h index 75cd2a7b..a5d7bdca 100644 --- a/Plugin/src/SofaPython3/DataHelper.h +++ b/Plugin/src/SofaPython3/DataHelper.h @@ -37,8 +37,7 @@ along with sofaqtquick. If not, see . #include #include #include - -#include "config.h" +#include ////////////////////////// FORWARD DECLARATION /////////////////////////// namespace sofa { @@ -183,7 +182,6 @@ namespace sofa { /////////////////////////////// DECLARATION ////////////////////////////// namespace sofapython3 { -namespace py { using namespace pybind11; } using sofa::core::objectmodel::Base; using sofa::core::objectmodel::BaseData; @@ -192,59 +190,40 @@ using sofa::core::objectmodel::BaseNode; using sofa::core::objectmodel::BaseObject; using sofa::defaulttype::AbstractTypeInfo; +SOFAPYTHON3_API void setItem2D(pybind11::array a, pybind11::slice slice, pybind11::object o); +SOFAPYTHON3_API void setItem2D(pybind11::array a, const pybind11::slice& slice, + const pybind11::slice& slice1, pybind11::object o); +SOFAPYTHON3_API void setItem1D(pybind11::array a, pybind11::slice slice, pybind11::object o); +SOFAPYTHON3_API void setItem(pybind11::array a, pybind11::slice slice, pybind11::object value); -class SOFAPYTHON3_API PythonTrampoline -{ -protected: - std::shared_ptr pyobject; -public: - virtual ~PythonTrampoline(); - virtual void setInstance(py::object s); -}; - -template class py_shared_ptr : public sofa::core::sptr -{ -public: - using Base = typename sofa::core::sptr; - using Base::Base; - py_shared_ptr(const py_shared_ptr& other, T* ptr) : sofa::core::sptr(ptr) {} - py_shared_ptr(T* ptr) : sofa::core::sptr(ptr) {} -}; - -SOFAPYTHON3_API void setItem2D(py::array a, py::slice slice, py::object o); -SOFAPYTHON3_API void setItem2D(py::array a, const py::slice& slice, - const py::slice& slice1, py::object o); -SOFAPYTHON3_API void setItem1D(py::array a, py::slice slice, py::object o); -SOFAPYTHON3_API void setItem(py::array a, py::slice slice, py::object value); - -SOFAPYTHON3_API py::slice toSlice(const py::object& o); +SOFAPYTHON3_API pybind11::slice toSlice(const pybind11::object& o); SOFAPYTHON3_API std::string getPathTo(Base* b); SOFAPYTHON3_API const char* getFormat(const AbstractTypeInfo& nfo); -SOFAPYTHON3_API std::map& getObjectCache(); +SOFAPYTHON3_API std::map& getObjectCache(); SOFAPYTHON3_API void trimCache(); SOFAPYTHON3_API bool hasArrayFor(BaseData* d); -SOFAPYTHON3_API py::array resetArrayFor(BaseData* d); -SOFAPYTHON3_API py::array getPythonArrayFor(BaseData* d); +SOFAPYTHON3_API pybind11::array resetArrayFor(BaseData* d); +SOFAPYTHON3_API pybind11::array getPythonArrayFor(BaseData* d); -py::buffer_info SOFAPYTHON3_API toBufferInfo(BaseData& m); -py::object SOFAPYTHON3_API convertToPython(BaseData* d); +pybind11::buffer_info SOFAPYTHON3_API toBufferInfo(BaseData& m); +pybind11::object SOFAPYTHON3_API convertToPython(BaseData* d); -void SOFAPYTHON3_API copyFromListScalar(BaseData& d, const AbstractTypeInfo& nfo, const py::list& l); +void SOFAPYTHON3_API copyFromListScalar(BaseData& d, const AbstractTypeInfo& nfo, const pybind11::list& l); -std::string SOFAPYTHON3_API toSofaParsableString(const py::handle& p); +std::string SOFAPYTHON3_API toSofaParsableString(const pybind11::handle& p); -//py::object SOFAPYTHON3_API dataToPython(BaseData* d); +//pybind11::object SOFAPYTHON3_API dataToPython(BaseData* d); /// RVO optimized function. Don't care about copy on the return code. void SOFAPYTHON3_API fillBaseObjectdescription(sofa::core::objectmodel::BaseObjectDescription& desc, - const py::dict& dict); + const pybind11::dict& dict); template -void copyScalar(BaseData* a, const AbstractTypeInfo& nfo, py::array_t src) +void copyScalar(BaseData* a, const AbstractTypeInfo& nfo, pybind11::array_t src) { void* ptr = a->beginEditVoidPtr(); @@ -269,7 +248,7 @@ size_t SOFAPYTHON3_API getNDim(BaseData* self); /// https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.size.html#numpy.ndarray.size size_t SOFAPYTHON3_API getSize(BaseData* self); -SOFAPYTHON3_API std::ostream& operator<<(std::ostream& out, const py::buffer_info& p); +SOFAPYTHON3_API std::ostream& operator<<(std::ostream& out, const pybind11::buffer_info& p); // TODO: move this somewhere else as we will probably need it in several other places. template class raw_ptr @@ -315,8 +294,8 @@ class scoped_writeonly_access ~scoped_writeonly_access(){ data->endEditVoidPtr(); } }; -SOFAPYTHON3_API BaseData* addData(py::object py_self, const std::string& name, py::object value = py::none(), py::object defaultValue = py::none(), const std::string& help = "", const std::string& group = "Property", std::string type = ""); -SOFAPYTHON3_API BaseLink* addLink(py::object py_self, const std::string& name, py::object value, const std::string& help); +SOFAPYTHON3_API BaseData* addData(pybind11::object py_self, const std::string& name, pybind11::object value = pybind11::none(), pybind11::object defaultValue = pybind11::none(), const std::string& help = "", const std::string& group = "Property", std::string type = ""); +SOFAPYTHON3_API BaseLink* addLink(pybind11::object py_self, const std::string& name, pybind11::object value, const std::string& help); SOFAPYTHON3_API bool isProtectedKeyword(const std::string& name); } // namespace sofapython3 diff --git a/Plugin/src/SofaPython3/Prefab.cpp b/Plugin/src/SofaPython3/Prefab.cpp index eefe6cb5..96197efb 100644 --- a/Plugin/src/SofaPython3/Prefab.cpp +++ b/Plugin/src/SofaPython3/Prefab.cpp @@ -1,5 +1,4 @@ -#include "Prefab.h" - +#include #include #include #include @@ -15,6 +14,9 @@ using sofa::simulation::VisualInitVisitor; #include using sofa::simulation::Simulation; +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + namespace sofapython3 { using sofa::core::objectmodel::Event; diff --git a/Plugin/src/SofaPython3/Prefab.h b/Plugin/src/SofaPython3/Prefab.h index 2044348b..9966d0b1 100644 --- a/Plugin/src/SofaPython3/Prefab.h +++ b/Plugin/src/SofaPython3/Prefab.h @@ -39,7 +39,7 @@ class SOFAPYTHON3_API Prefab : public BasePrefab void reinit(); virtual void doReInit() ; - void addPrefabParameter(const std::string& name, const std::string& help, const std::string& type, pybind11::object defaultValue = py::none()); + void addPrefabParameter(const std::string& name, const std::string& help, const std::string& type, pybind11::object defaultValue = pybind11::none()); void setSourceTracking(const std::string& filename); void breakPrefab(); diff --git a/Plugin/src/SofaPython3/PythonEnvironment.cpp b/Plugin/src/SofaPython3/PythonEnvironment.cpp index 93778a1d..d2460457 100644 --- a/Plugin/src/SofaPython3/PythonEnvironment.cpp +++ b/Plugin/src/SofaPython3/PythonEnvironment.cpp @@ -76,7 +76,9 @@ using sofa::simulation::SceneLoaderFactory; #include #include -namespace py = pybind11; + +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } #include "SceneLoaderPY3.h" using sofapython3::SceneLoaderPY3; diff --git a/Plugin/src/SofaPython3/PythonEnvironment.h b/Plugin/src/SofaPython3/PythonEnvironment.h index bbd04dc8..27a2e8de 100644 --- a/Plugin/src/SofaPython3/PythonEnvironment.h +++ b/Plugin/src/SofaPython3/PythonEnvironment.h @@ -70,7 +70,6 @@ along with sofaqtquick. If not, see . namespace sofapython3 { -namespace py { using namespace pybind11; } using sofa::simulation::SceneLoader ; /// Forward definition @@ -82,9 +81,9 @@ class SOFAPYTHON3_API PythonEnvironment static void Init(); static void Release(); - static py::module importFromFile(const std::string& module, + static pybind11::module importFromFile(const std::string& module, const std::string& path, - py::object* globals = nullptr); + pybind11::object* globals = nullptr); /// Add a path to sys.path, the list of search path for Python modules. static void addPythonModulePath(const std::string& path); diff --git a/Plugin/src/SofaPython3/PythonFactory.cpp b/Plugin/src/SofaPython3/PythonFactory.cpp index 02cad7c3..4ad7143f 100644 --- a/Plugin/src/SofaPython3/PythonFactory.cpp +++ b/Plugin/src/SofaPython3/PythonFactory.cpp @@ -26,8 +26,8 @@ along with sofaqtquick. If not, see . ********************************************************************/ #include -#include "PythonFactory.h" -#include "DataHelper.h" +#include +#include #include @@ -60,6 +60,11 @@ using sofa::core::objectmodel::Event; #include +/// Bind the python's attribute error +namespace pybind11 { PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) } +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + namespace sofapython3 { using namespace pybind11::literals; diff --git a/Plugin/src/SofaPython3/PythonFactory.h b/Plugin/src/SofaPython3/PythonFactory.h index d18d4265..bbf653a8 100644 --- a/Plugin/src/SofaPython3/PythonFactory.h +++ b/Plugin/src/SofaPython3/PythonFactory.h @@ -37,12 +37,9 @@ along with sofaqtquick. If not, see . /////////////////////////////// DECLARATION ////////////////////////////// namespace sofapython3 { - /// Makes an alias for the pybind11 namespace to increase readability. - namespace py { using namespace pybind11; } - - typedef std::function componentDowncastingFunction; - typedef std::function dataDowncastingFunction; - typedef std::function eventDowncastingFunction; + typedef std::function componentDowncastingFunction; + typedef std::function dataDowncastingFunction; + typedef std::function eventDowncastingFunction; typedef std::function dataCreatorFunction; typedef sofa::helper::Factory< std::string, sofa::core::objectmodel::BaseData> DataFactory; @@ -50,12 +47,12 @@ namespace sofapython3 class SOFAPYTHON3_API PythonFactory { public: - static py::object toPython(sofa::core::objectmodel::Base* object); - static py::object toPython(const sofa::core::objectmodel::BaseData* data); - static py::object toPython(sofa::core::objectmodel::BaseData* data); - static py::object valueToPython_ro(sofa::core::objectmodel::BaseData* data); - static void fromPython(sofa::core::objectmodel::BaseData* data, const py::object& value); - static py::object toPython(sofa::core::objectmodel::Event* event); + static pybind11::object toPython(sofa::core::objectmodel::Base* object); + static pybind11::object toPython(const sofa::core::objectmodel::BaseData* data); + static pybind11::object toPython(sofa::core::objectmodel::BaseData* data); + static pybind11::object valueToPython_ro(sofa::core::objectmodel::BaseData* data); + static void fromPython(sofa::core::objectmodel::BaseData* data, const pybind11::object& value); + static pybind11::object toPython(sofa::core::objectmodel::Event* event); static sofa::core::objectmodel::BaseData* createInstance(const std::string& typeName); static void registerType(const std::string& typeName, componentDowncastingFunction fct); diff --git a/Plugin/src/SofaPython3/PythonTest.h b/Plugin/src/SofaPython3/PythonTest.h index d686a686..84d4bf46 100644 --- a/Plugin/src/SofaPython3/PythonTest.h +++ b/Plugin/src/SofaPython3/PythonTest.h @@ -28,7 +28,7 @@ along with sofaqtquick. If not, see . #pragma once #include -#include "config.h" +#include #include #include diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.cpp index 3b7c3292..7fcc9a31 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Components/Submodule_Components.cpp @@ -27,7 +27,6 @@ along with sofaqtquick. If not, see . #include -#include #include #include @@ -37,10 +36,12 @@ using sofa::core::ObjectFactory; #include using sofa::helper::logging::Message; +#include +using sofa::simulation::Node; + #include +#include #include -#include -#include "Submodule_Components.h" namespace py = pybind11; using namespace py::literals; @@ -76,13 +77,13 @@ PYBIND11_MODULE(Components, m) throw py::type_error(std::string("Invalid first argument. Expecting 'Node' but got ") + py::cast(py::str(pynode))); } - auto node = py::cast(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 = ObjectFactory::getInstance()->createObject(node, &desc); + 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. diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp index 61ed5764..e84b52cb 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp @@ -39,28 +39,26 @@ using sofa::core::objectmodel::BaseLink; using sofa::helper::WriteOnlyAccessor; #include -//#include -#include "Binding_Base.h" -#include "Binding_Base_doc.h" - - -#include "Binding_DataDict.h" -#include "Binding_BaseData.h" +#include +#include +#include #include "Data/Binding_DataContainer.h" #include using sofa::simulation::Node; -#include -using sofa::core::objectmodel::BaseObject; -#include -using sofa::core::objectmodel::BaseNode; -#include -using sofa::core::objectmodel::BaseContext; - #include +/// Bind the python's attribute error +namespace pybind11 { PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) } + +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + +/// Bring pybind11 literals +using namespace pybind11::literals; + namespace sofapython3 { @@ -420,7 +418,7 @@ py::object BindingBase::setDataValues(Base& self, py::kwargs kwargs) void moduleAddBase(py::module &m) { - py::class_ base(m, "Base", py::dynamic_attr(), doc::base::BaseClass); + 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" base.def("getName", [](Base& b){ return b.getName(); }, sofapython3::doc::base::getName); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h index 37cf7ed4..ccfdf2e0 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h @@ -32,59 +32,181 @@ along with sofaqtquick. If not, see . #include #include -/// More info about smart pointer in -/// /pybind11.readthedocs.io/en/stable/advanced/smart_ptrs.html -PYBIND11_DECLARE_HOLDER_TYPE(Base, sofa::core::sptr, true) +namespace sofapython3 { + +/** + * This is the main pybind11 type holder that will manage the underlying reference counter of the SOFA C++ objects. It + * should be used when creating bindings for a C++ class that inherits sofa::core::objectmodel::Base. + * + * \note There is a problem in pybind11 which sometime does a kind of slicing between the python object and its bound + * C++ object. This usually happens when instantiating a virtual (trampoline) class in python that then calls the + * new operator in the pybind11::init() and return the newly created object. Python will sometime destroy the + * initial object before the C++ one is created. We go around this by keeping here a reference to the initial + * python object, hence incrementing its reference counter by one. + * + * See https://github.com/pybind/pybind11/issues/1546 for more details. + * @tparam T + */ + +template +struct py_shared_ptr : public sofa::core::sptr { + using Base = sofa::core::sptr; + using Base::Base; + + py_shared_ptr(const sofa::core::sptr & sptr) : Base(sptr) {} + + py_shared_ptr(const sofa::core::sptr & sptr, T * ptr) : Base(ptr) {} + + py_shared_ptr(const py_shared_ptr & py_ptr) : Base(py_ptr) { + p_object = py_ptr.p_object; + } + + py_shared_ptr(py_shared_ptr & py_ptr) : Base(py_ptr) { + p_object = py_ptr.p_object; + } + + void set_object(const pybind11::object & o) { + p_object = o; + } + +private: + pybind11::object p_object; +}; -template class pybind11::class_; +} // namespace sofapython3 + +// Type caster for SP3 and SOFA holders +namespace pybind11::detail { +/** + * This is an alias type caster that converts sofa::core::sptr to sofapython3::py_shared_ptr. + * It is needed for when bound C++ function returns sofa::core::sptr instead of py_shared_ptr while the holder + * type was set to the latter. + * @tparam T + */ +template +class type_caster> { + +PYBIND11_TYPE_CASTER (sofa::core::sptr , _("sofa::core::sptr")); + + using BaseCaster = copyable_holder_caster>; + + bool load (pybind11::handle src, bool b) + { + // First make sure the py::object is an instanced of sofapython3::py_shared_ptr + BaseCaster bc; + bool success = bc.load (src, b); + if (!success) { + return false; + } + + // Convert the holder_caster to a sofapython3::py_shared_ptr instance + auto base_ptr = static_cast> (bc); + + // Take ownership of the py::object + auto h = BaseCaster::cast(base_ptr, return_value_policy(), handle()); + auto py_obj = reinterpret_borrow(h); + + // Save a copy into the holder so that it doesn't get deleted and thereby creating slicing + base_ptr.set_object(py_obj); + + // Set the value to the ptr + value = sofa::core::sptr (base_ptr); + return true; + } + + static handle cast (sofa::core::sptr sp, + return_value_policy rvp, + handle h) + { + return BaseCaster::cast (sp, rvp, h); + } +}; -namespace sofapython3 -{ -/// Makes an alias for the pybind11 namespace to increase readability. -namespace py { using namespace pybind11; } -// @TODO: Remove with pybind11 > 2.2.4 -namespace py { - PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) +template +struct always_construct_holder> : always_construct_holder { }; + +/** + * Main type caster that converts python objects to C++ sofapython3::py_shared_ptr objects, and the inverse. + * To avoid slicing (see sofapython3::py_shared_ptr), it will preserve the initial python object when the initial + * python -> C++ conversion happens. + * @tparam T + */ +template +class type_caster> { + +PYBIND11_TYPE_CASTER (sofapython3::py_shared_ptr , _("sofapython3::py_shared_ptr")); + + using BaseCaster = copyable_holder_caster>; + + bool load (pybind11::handle src, bool b) + { + // First make sure the py::object is an instanced of sofapython3::py_shared_ptr + BaseCaster bc; + bool success = bc.load (src, b); + if (!success) { + return false; + } + + // Convert the holder_caster to a sofapython3::py_shared_ptr instance + auto base_ptr = static_cast> (bc); + + // Take ownership of the py::object + auto h = BaseCaster::cast(base_ptr, return_value_policy(), handle()); + auto py_obj = reinterpret_borrow(h); + + // Save a copy into the holder so that it doesn't get deleted and thereby creating slicing + base_ptr.set_object(py_obj); + + // Set the value to the ptr + value = base_ptr; + return true; + } + + static handle cast (sofapython3::py_shared_ptr sp, + return_value_policy rvp, + handle h) + { + return BaseCaster::cast (sp, rvp, h); + } +}; + +template +struct is_holder_type> : std::true_type {}; } -using namespace pybind11::literals; -using sofa::core::objectmodel::Base; -using sofa::core::objectmodel::BaseData; -using sofa::core::objectmodel::BaseLink; -using sofa::core::sptr; +namespace sofapython3 { class BindingBase { public: - static void SetAttr(Base& self, const std::string& s, py::object value); + static void SetAttr(sofa::core::objectmodel::Base& self, const std::string& s, pybind11::object value); - static void SetAttr(py::object self, const std::string& s, pybind11::object value); - static py::object GetAttr(Base* self, const std::string& s, bool doThrowException=true); - static void SetAttrFromArray(py::object self, const std::string& s, const pybind11::array &value); + static void SetAttr(pybind11::object self, const std::string& s, pybind11::object value); + static pybind11::object GetAttr(sofa::core::objectmodel::Base* self, const std::string& s, bool doThrowException=true); + static void SetAttrFromArray(pybind11::object self, const std::string& s, const pybind11::array &value); /// Set the data field value from the array. - static void SetDataFromArray(BaseData* data, const py::array& value); - static bool SetData(BaseData* data, pybind11::object value); - static py::object setDataValues(Base& self, py::kwargs kwargs); - - static py::list getDataFields(Base& self); - static py::list getLinks(Base& self); - static BaseData* addData(py::object py_self, const std::string& name, py::object value = py::object(), py::object defaultValue = py::object(), const std::string& help = "", const std::string& group = "Property", std::string type = ""); - static BaseData* addDataFromData(Base* self, py::object d); - static BaseLink* addLink(py::object py_self, const std::string& name, py::object value, const std::string& help); - static py::list __dir__(Base* self); - static py::object __getattr__(py::object self, const std::string& s); - static void __setattr__(py::object self, const std::string& s, py::object value); - static py::object getData(Base& self, const std::string&); - - static py::object getLoggedMessagesAsString(Base& self); - static py::object countLoggedMessages(Base& self); - static py::object clearLoggedMessages(Base& self); - static std::string getPathName(Base& self); + static void SetDataFromArray(sofa::core::objectmodel::BaseData* data, const pybind11::array& value); + static bool SetData(sofa::core::objectmodel::BaseData* data, pybind11::object value); + static pybind11::object setDataValues(sofa::core::objectmodel::Base& self, pybind11::kwargs kwargs); + + static pybind11::list getDataFields(sofa::core::objectmodel::Base& self); + static pybind11::list getLinks(sofa::core::objectmodel::Base& self); + static sofa::core::objectmodel::BaseData* addData(pybind11::object py_self, const std::string& name, pybind11::object value = pybind11::object(), pybind11::object defaultValue = pybind11::object(), const std::string& help = "", const std::string& group = "Property", std::string type = ""); + static sofa::core::objectmodel::BaseData* addDataFromData(sofa::core::objectmodel::Base* self, pybind11::object d); + static sofa::core::objectmodel::BaseLink* addLink(pybind11::object py_self, const std::string& name, pybind11::object value, const std::string& help); + static pybind11::list __dir__(sofa::core::objectmodel::Base* self); + static pybind11::object __getattr__(pybind11::object self, const std::string& s); + static void __setattr__(pybind11::object self, const std::string& s, pybind11::object value); + static pybind11::object getData(sofa::core::objectmodel::Base& self, const std::string&); + + static pybind11::object getLoggedMessagesAsString(sofa::core::objectmodel::Base& self); + static pybind11::object countLoggedMessages(sofa::core::objectmodel::Base& self); + static pybind11::object clearLoggedMessages(sofa::core::objectmodel::Base& self); + static std::string getPathName(sofa::core::objectmodel::Base& self); }; -void moduleAddBase(py::module& m); +void moduleAddBase(pybind11::module& m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseCamera.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseCamera.cpp index 14db8124..ac613071 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseCamera.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseCamera.cpp @@ -27,17 +27,20 @@ along with sofaqtquick. If not, see . #include #include -#include -#include "Binding_Base.h" -#include "Binding_BaseObject.h" -#include "Binding_BaseCamera.h" +#include +#include + +#include +#include #include -#include "Binding_BaseCamera_doc.h" -namespace sofapython3 -{ +namespace py { using namespace pybind11; } +using sofa::core::objectmodel::BaseObject; +using sofa::component::visualmodel::BaseCamera; + +namespace sofapython3 { std::vector getProjectionMatrix(BaseCamera* self) { @@ -78,7 +81,7 @@ void moduleAddBaseCamera(py::module &m) /// register the BaseCamera binding in the pybind11 typeing sytem py::class_> c(m, "Camera", sofapython3::doc::baseCamera::baseCameraClass); + py_shared_ptr> c(m, "Camera", sofapython3::doc::baseCamera::baseCameraClass); /// register the BaseCamera binding in the downcasting subsystem PythonFactory::registerType([](sofa::core::objectmodel::Base* object) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseCamera.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseCamera.h index 959a8c53..b9e52665 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseCamera.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseCamera.h @@ -27,17 +27,11 @@ along with sofaqtquick. If not, see . #pragma once -#include "Binding_BaseObject.h" -#include +#include -template class pybind11::class_>; +namespace sofapython3 { -namespace sofapython3 -{ +void moduleAddBaseCamera(pybind11::module &m); -using sofa::component::visualmodel::BaseCamera; -void moduleAddBaseCamera(py::module &m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseContext.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseContext.cpp index 03973fd0..324e1bff 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseContext.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseContext.cpp @@ -25,7 +25,8 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ -#include "Binding_BaseContext.h" +#include +#include #include #include #include @@ -33,11 +34,13 @@ along with sofaqtquick. If not, see . #include #include +namespace py { using namespace pybind11; } + using namespace sofa::core::objectmodel; namespace sofapython3 { void moduleAddBaseContext(py::module& m) { - py::class_ c (m, "BaseContext"); + py::class_> c (m, "BaseContext"); py::enum_(c, "SearchDirection") .value("SearchUp", BaseContext::SearchDirection::SearchUp) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseContext.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseContext.h index 5008e841..6d639aa8 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseContext.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseContext.h @@ -29,19 +29,8 @@ along with sofaqtquick. If not, see . #include -#include "Binding_Base.h" - -#include - -template class pybind11::class_>; - - namespace sofapython3 { -namespace py { using namespace pybind11; } - -void moduleAddBaseContext(py::module &m); +void moduleAddBaseContext(pybind11::module &m); } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp index 254d71e0..901cce4a 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp @@ -29,23 +29,25 @@ along with sofaqtquick. If not, see . #include #include -using sofa::defaulttype::AbstractTypeInfo; #include -using sofa::core::objectmodel::BaseData; - #include -using sofa::core::objectmodel::BaseObject; -#include -using sofa::core::objectmodel::BaseNode; - -#include "Binding_Base.h" -#include "Binding_BaseData.h" -#include "Data/Binding_DataContainer.h" +#include +#include +#include +#include #include #include -#include "Binding_BaseData_doc.h" + +/// Bind the python's attribute error +namespace pybind11 { PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) } +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + +using namespace sofa::core::objectmodel; +using sofa::defaulttype::AbstractTypeInfo; + namespace sofapython3 { diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h index 0f76f6a7..304e862d 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h @@ -27,10 +27,10 @@ along with sofaqtquick. If not, see . #pragma once -#include -#include +#include + +namespace sofapython3 { + + void moduleAddBaseData(pybind11::module& m); -namespace sofapython3 -{ - void moduleAddBaseData(py::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 e24da003..61cac759 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.cpp @@ -25,7 +25,6 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ - #include using sofa::core::objectmodel::BaseLink; @@ -33,14 +32,17 @@ using sofa::core::objectmodel::BaseLink; using sofa::core::objectmodel::BaseObject; #include -using sofa::core::objectmodel::BaseNode; -#include "Binding_Base.h" -#include "Binding_BaseLink.h" -#include "Binding_BaseLink_doc.h" -#include +#include +#include #include +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + +// To bring in the `_a` literal +using namespace pybind11::literals; + namespace sofapython3 { @@ -74,7 +76,7 @@ std::string getPathName(BaseLink& self) void moduleAddBaseLink(py::module& m) { - py::class_> link(m, "Link", sofapython3::doc::baseLink::baseLinkClass); + py::class_ link(m, "Link", sofapython3::doc::baseLink::baseLinkClass); 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 00745176..2002444b 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h @@ -27,11 +27,10 @@ along with sofaqtquick. If not, see . #pragma once -#include -#include +#include -namespace sofapython3 -{ - void moduleAddBaseLink(py::module& m); +namespace sofapython3 { + + void moduleAddBaseLink(pybind11::module& m); } /// sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.cpp index b461b6ce..7125d738 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.cpp @@ -25,12 +25,13 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ -#include "Binding_BaseObject.h" -#include "Binding_Controller.h" -#include -#include "Binding_BaseObject_doc.h" +#include +#include +#include +#include #include +#include // Imports for getCategories #include @@ -57,6 +58,13 @@ along with sofaqtquick. If not, see . #include #include +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + +using sofa::core::objectmodel::BaseData; +using sofa::core::objectmodel::Base; +using sofa::core::objectmodel::BaseObject; + namespace sofapython3 { py::object getItem(const BaseObject& self, const std::string& path) @@ -244,13 +252,13 @@ py::object __getitem__(BaseObject &self, std::string s) void moduleAddBaseObject(py::module& m) { /// Register the BaseObject binding into the pybind11 typing system - py::class_p(m, "Object", sofapython3::doc::baseObject::Class); + py::class_>p(m, "Object", sofapython3::doc::baseObject::Class); /// Register the BaseObject binding into the downcasting subsystem PythonFactory::registerType( [](sofa::core::objectmodel::Base* object) { - return py::cast(object->toBaseObject()); + return py::cast(py_shared_ptr(object->toBaseObject())); }); p.def("init", &BaseObject::init, sofapython3::doc::baseObject::init); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.h index dae1e942..7b116a92 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.h @@ -29,20 +29,15 @@ along with sofaqtquick. If not, see . #include -#include +namespace sofa::core::objectmodel { +class BaseObject; +} -#include "Binding_Base.h" +namespace sofapython3 { -template class pybind11::class_>; +pybind11::object getItem(const sofa::core::objectmodel::BaseObject & self, const std::string& path); +void moduleAddBaseObject(pybind11::module &m); -namespace sofapython3 -{ - - using sofa::core::objectmodel::BaseObject; - py::object getItem(const BaseObject& self, const std::string& path); - void moduleAddBaseObject(py::module &m); } /// namespace sofapython diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Context.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Context.cpp index 1ac77c1f..594067c3 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Context.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Context.cpp @@ -25,14 +25,18 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ -#include "Binding_BaseContext.h" -#include "Binding_Context.h" +#include +#include +#include +#include using namespace sofa::core::objectmodel; +namespace py { using namespace pybind11; } + namespace sofapython3 { void moduleAddContext(py::module& m) { - py::class_ (m, "Context"); + py::class_> (m, "Context"); } } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Context.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Context.h index d21b88bc..d1272c15 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Context.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Context.h @@ -29,19 +29,9 @@ along with sofaqtquick. If not, see . #include -#include "Binding_Base.h" - -#include - -template class pybind11::class_>; - namespace sofapython3 { -namespace py { using namespace pybind11; } - -void moduleAddContext(py::module &m); +void moduleAddContext(pybind11::module &m); } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.cpp index f57669cf..6411bcd0 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.cpp @@ -28,20 +28,22 @@ along with sofaqtquick. If not, see . #include #include -#include "Binding_Controller.h" -#include "Binding_Controller_doc.h" +#include +#include +#include -#include #include #include -using sofapython3::PythonEnvironment; -PYBIND11_DECLARE_HOLDER_TYPE(Controller, - sofapython3::py_shared_ptr, true) +/// Bind the python's attribute error +namespace pybind11 { PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) } +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } namespace sofapython3 { using sofa::core::objectmodel::Event; + using sofa::core::objectmodel::BaseObject; void Controller_Trampoline::init() { @@ -98,7 +100,7 @@ namespace sofapython3 f.def(py::init([](py::args& /*args*/, py::kwargs& kwargs) { - auto c = new Controller_Trampoline(); + auto c = sofa::core::sptr (new Controller_Trampoline()); c->f_listening.setValue(true); for(auto kv : kwargs) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.h index bd1acdaa..e2651cb6 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Controller.h @@ -26,43 +26,38 @@ along with sofaqtquick. If not, see . ********************************************************************/ #pragma once -#include "Binding_BaseObject.h" -#include +#include #include -namespace sofapython3 -{ -using sofa::core::behavior::BaseController; +namespace sofapython3 { -class Controller : public BaseController -{ +/** + * Empty controller shell that allows pybind11 to bind the init and reinit methods (since BaseController doesn't have + * them) + */ +class Controller : public sofa::core::behavior::BaseController { public: - SOFA_CLASS(Controller, BaseController); + SOFA_CLASS(Controller, sofa::core::behavior::BaseController); void init() override {}; void reinit() override {}; - - Controller() {}; - ~Controller() override {}; }; -void moduleAddController(py::module &m); - class Controller_Trampoline : public Controller { public: - Controller_Trampoline() = default; - - ~Controller_Trampoline() override = default; + SOFA_CLASS(Controller_Trampoline, Controller); void init() override; void reinit() override; void handleEvent(sofa::core::objectmodel::Event* event) override; private: - void callScriptMethod(const py::object& self, sofa::core::objectmodel::Event* event, + void callScriptMethod(const pybind11::object& self, sofa::core::objectmodel::Event* event, const std::string& methodName); }; +void moduleAddController(pybind11::module &m); + } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataDict.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataDict.cpp index ff40e56f..20304b25 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataDict.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataDict.cpp @@ -25,10 +25,17 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ -#include "Binding_DataDict.h" +#include + +using sofa::core::objectmodel::Base; +using sofa::core::objectmodel::BaseData; +using sofa::core::sptr; + +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + +namespace sofapython3 { -namespace sofapython3 -{ void moduleAddDataDict(py::module& m) { //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataDict.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataDict.h index 2b2f43a3..61c9d806 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataDict.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataDict.h @@ -37,30 +37,23 @@ along with sofaqtquick. If not, see . #include "Binding_DataDict_doc.h" -namespace sofapython3 -{ -/// Makes an alias for the pybind11 namespace to increase readability. -namespace py { using namespace pybind11; } +namespace sofapython3 { -using namespace pybind11::literals; -using sofa::core::objectmodel::Base; -using sofa::core::objectmodel::BaseData; -using sofa::core::sptr; class DataDict { public: - sptr owner; - DataDict(sptr b){ owner = b; } + sofa::core::sptr owner; + DataDict(sofa::core::sptr b){ owner = b; } }; class DataDictIterator { public: - Base::SPtr owner; + sofa::core::sptr owner; size_t index=0; bool key; bool value; - DataDictIterator(Base::SPtr owner_, bool withKey, bool withValue) + DataDictIterator(sofa::core::sptr owner_, bool withKey, bool withValue) { owner=owner_; index=0; @@ -69,7 +62,7 @@ class DataDictIterator } }; -void moduleAddDataDict(py::module& m); -void moduleAddDataDictIterator(py::module& m); +void moduleAddDataDict(pybind11::module& m); +void moduleAddDataDictIterator(pybind11::module& m); } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataEngine.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataEngine.cpp index 1307518a..9d9aa36f 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataEngine.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataEngine.cpp @@ -24,19 +24,20 @@ along with sofaqtquick. If not, see . - jean-nicolas.brunet@inria.fr - thierry.gaugry@inria.fr ********************************************************************/ +#include +#include +#include -#include "Binding_DataEngine.h" -#include "Binding_DataEngine_doc.h" - -#include #include #include using sofapython3::PythonEnvironment; #include -PYBIND11_DECLARE_HOLDER_TYPE(PyDataEngine, - sofapython3::py_shared_ptr, true) +/// Bind the python's attribute error +namespace pybind11 { PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) } +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } namespace sofapython3 { @@ -46,41 +47,10 @@ namespace sofapython3 using sofa::core::objectmodel::BaseObject; using sofa::core::objectmodel::DDGNode; - void PyDataEngine::init() { - } - - void PyDataEngine::doUpdate() { - } - - PyDataEngine::PyDataEngine() { - } - - PyDataEngine::~PyDataEngine() { - } - - class DataEngine_Trampoline : public PyDataEngine, public PythonTrampoline - { - public: - DataEngine_Trampoline(); - - ~DataEngine_Trampoline() override; - - std::string getClassName() const override - { - return pyobject->ob_type->tp_name; - } - void init() override ; - void doUpdate() override ; - }; - - DataEngine_Trampoline::DataEngine_Trampoline() = default; - - DataEngine_Trampoline::~DataEngine_Trampoline() = default; - void DataEngine_Trampoline::init() { PythonEnvironment::gil acquire; - PYBIND11_OVERLOAD(void, PyDataEngine, init, ); + PYBIND11_OVERLOAD(void, DataEngine, init, ); } void DataEngine_Trampoline::doUpdate() @@ -101,12 +71,12 @@ namespace sofapython3 void moduleAddDataEngine(pybind11::module &m) { - py::class_> f(m, "DataEngine", + py_shared_ptr> f(m, "DataEngine", py::dynamic_attr(), - py::multiple_inheritance(), sofapython3::doc::dataengine::DataEngine); + sofapython3::doc::dataengine::DataEngine); f.def(py::init([](py::args& /*args*/, py::kwargs& kwargs) { @@ -130,8 +100,8 @@ namespace sofapython3 return c; })); - f.def("addInput", &PyDataEngine::addInput, sofapython3::doc::dataengine::addInput); - f.def("addOutput", &PyDataEngine::addOutput, sofapython3::doc::dataengine::addOutput); + f.def("addInput", &DataEngine::addInput, sofapython3::doc::dataengine::addInput); + f.def("addOutput", &DataEngine::addOutput, sofapython3::doc::dataengine::addOutput); } } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataEngine.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataEngine.h index c26d9280..b6b7f7b7 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataEngine.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DataEngine.h @@ -27,32 +27,18 @@ along with sofaqtquick. If not, see . #pragma once -#include "Binding_BaseObject.h" - #include #include -template class pybind11::class_>; - -namespace sofapython3 -{ -using sofa::core::DataEngine; -using sofa::core::objectmodel::BaseData; -using sofa::core::objectmodel::BaseObject; -using sofa::core::objectmodel::DDGNode; +namespace sofapython3 { -class PyDataEngine : public DataEngine +class DataEngine_Trampoline : public sofa::core::DataEngine { public: - SOFA_CLASS(PyDataEngine, DataEngine); + SOFA_CLASS(DataEngine_Trampoline, sofa::core::DataEngine); void init() override; void doUpdate() override; - PyDataEngine(); - ~PyDataEngine() override; - }; void moduleAddDataEngine(pybind11::module &m); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp index 73628c52..22048fb4 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp @@ -26,27 +26,27 @@ along with sofaqtquick. If not, see . ********************************************************************/ #include -#include -#include "Binding_BaseObject.h" -#include "Binding_ForceField.h" -#include "Binding_ForceField_doc.h" -#include +#include +#include +#include +#include #include #include #include -#include #include #include using sofapython3::PythonEnvironment; -PYBIND11_DECLARE_HOLDER_TYPE(TForceField, - sofapython3::py_shared_ptr, true) - +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } +/// To bring in the `_a` literal +using namespace pybind11::literals; namespace sofapython3 { + using sofa::core::objectmodel::BaseObject; using sofa::core::objectmodel::ComponentState; using sofa::core::behavior::MechanicalState; using sofa::core::MechanicalParams; @@ -77,7 +77,6 @@ namespace sofapython3 PYBIND11_OVERLOAD(void, ForceField, init,); } - template void ForceField_Trampoline::addForce(const MechanicalParams* mparams, DataVecDeriv& f, const DataVecCoord& x, const DataVecDeriv& v) { @@ -170,81 +169,68 @@ namespace sofapython3 } } - template - std::string ForceField_Trampoline::getClassName() const - { - return pyobject->ob_type->tp_name; - } - - void moduleAddForceField(py::module &m) - { - py::class_, - BaseObject, ForceField_Trampoline, - py_shared_ptr>> f(m, "ForceField", - py::dynamic_attr(), - py::multiple_inheritance(), sofapython3::doc::forceField::forceFieldClass); - - f.def(py::init([](py::args& args, py::kwargs& kwargs) - { - auto c = new ForceField_Trampoline(); - c->f_listening.setValue(true); - - if(args.size()==1) c->setName(py::cast(args[0])); - - py::object cc = py::cast(c); - for(auto kv : kwargs) - { - std::string key = py::cast(kv.first); - py::object value = py::reinterpret_borrow(kv.second); - if( key == "name") - { - if( args.size() != 0 ) - { - throw py::type_error("The name is setted twice as a " - "named argument='"+py::cast(value)+"' and as a" - "positional argument='"+py::cast(args[0])+"'."); - } - } - BindingBase::SetAttr(cc, key, value); - } - return c; - })); - - - py::class_, - BaseObject, ForceField_Trampoline, - py_shared_ptr>> f2(m, "ForceFieldRigid3", - py::dynamic_attr(), - py::multiple_inheritance(), sofapython3::doc::forceField::forceFieldClass); - - - f2.def(py::init([](py::args& args, py::kwargs& kwargs) - { - auto c = new ForceField_Trampoline(); - c->f_listening.setValue(true); - - if(args.size()==1) c->setName(py::cast(args[0])); - - py::object cc = py::cast(c); - for(auto kv : kwargs) - { - std::string key = py::cast(kv.first); - py::object value = py::reinterpret_borrow(kv.second); - if( key == "name") - { - if( args.size() != 0 ) - { - throw py::type_error("The name is setted twice as a " - "named argument='"+py::cast(value)+"' and as a" - "positional argument='"+py::cast(args[0])+"'."); - } - } - BindingBase::SetAttr(cc, key, value); - } - return c; - })); - } - - +void moduleAddForceField(py::module &m) { + py::class_, + BaseObject, ForceField_Trampoline, + py_shared_ptr>> f(m, "ForceField", + py::dynamic_attr(), + sofapython3::doc::forceField::forceFieldClass); + + f.def(py::init([](py::args &args, py::kwargs &kwargs) { + auto ff = sofa::core::sptr> (new ForceField_Trampoline()); + + ff->f_listening.setValue(true); + + if (args.size() == 1) ff->setName(py::cast(args[0])); + + py::object cc = py::cast(ff); + for (auto kv : kwargs) { + std::string key = py::cast(kv.first); + py::object value = py::reinterpret_borrow(kv.second); + if (key == "name") { + if (args.size() != 0) { + throw py::type_error("The name is setted twice as a " + "named argument='" + py::cast(value) + "' and as a" + "positional argument='" + + py::cast(args[0]) + "'."); + } + } + BindingBase::SetAttr(cc, key, value); + } + return ff; + })); + + + py::class_, + BaseObject, ForceField_Trampoline, + py_shared_ptr>> f2(m, "ForceFieldRigid3", + py::dynamic_attr(), + py::multiple_inheritance(), + sofapython3::doc::forceField::forceFieldClass); + + + f2.def(py::init([](py::args &args, py::kwargs &kwargs) { + auto c = sofa::core::sptr> (new ForceField_Trampoline()); + c->f_listening.setValue(true); + + if (args.size() == 1) c->setName(py::cast(args[0])); + + py::object cc = py::cast(c); + for (auto kv : kwargs) { + std::string key = py::cast(kv.first); + py::object value = py::reinterpret_borrow(kv.second); + if (key == "name") { + if (args.size() != 0) { + throw py::type_error("The name is setted twice as a " + "named argument='" + py::cast(value) + "' and as a" + "positional argument='" + + py::cast(args[0]) + "'."); + } + } + BindingBase::SetAttr(cc, key, value); + } + return c; + })); +} } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.h index db523728..5aad6ddf 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.h @@ -32,17 +32,12 @@ along with sofaqtquick. If not, see . #include #include -#include "Binding_BaseObject.h" -#include - -namespace sofapython3 -{ +namespace sofapython3 { template -class ForceField_Trampoline : public sofa::core::behavior::ForceField, public PythonTrampoline -{ - +class ForceField_Trampoline : public sofa::core::behavior::ForceField { public: + SOFA_CLASS(ForceField_Trampoline, SOFA_TEMPLATE(sofa::core::behavior::ForceField, TDOFType)); using sofa::core::behavior::ForceField::mstate; using sofa::core::behavior::ForceField::getContext; using typename sofa::core::behavior::ForceField::DataTypes; @@ -58,14 +53,13 @@ class ForceField_Trampoline : public sofa::core::behavior::ForceField void addForce(const sofa::core::MechanicalParams* mparams, DataVecDeriv& f, const DataVecCoord& x, const DataVecDeriv& v) override; void addDForce(const sofa::core::MechanicalParams* mparams, DataVecDeriv& df, const DataVecDeriv& dx ) override; - py::object _addKToMatrix(const sofa::core::MechanicalParams* mparams, int nNodes, int nDofs); + pybind11::object _addKToMatrix(const sofa::core::MechanicalParams* mparams, int nNodes, int nDofs); void addKToMatrix(const sofa::core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* dfId) override; SReal getPotentialEnergy(const sofa::core::MechanicalParams* /*mparams*/, const DataVecCoord& /*x*/) const override { return 0.0; } - std::string getClassName() const override; }; -void moduleAddForceField(py::module &m); +void moduleAddForceField(pybind11::module &m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp index d2a94f03..ac5e1349 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp @@ -39,11 +39,11 @@ namespace simpleapi = sofa::simpleapi; #include using sofa::helper::logging::Message; -#include #include using sofa::core::ExecParams; #include +#include #include #include @@ -52,20 +52,23 @@ using sofa::core::ObjectFactory; #include using sofapython3::PythonFactory; -#include "Binding_Node.h" -#include "Binding_NodeIterator.h" -#include "Binding_Context.h" +#include +#include +#include +#include using sofa::core::objectmodel::BaseObjectDescription; #include #include -#include "Binding_Node_doc.h" -#include "Binding_PythonScriptEvent.h" +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } -namespace sofapython3 -{ + +using sofa::simulation::Node; + +namespace sofapython3 { bool checkParamUsage(BaseObjectDescription& desc) @@ -134,26 +137,36 @@ std::string getLinkPath(Node* node){ -Node::SPtr __init__noname() -{ - return sofa::core::objectmodel::New("unnamed"); +py_shared_ptr __init__noname() { + auto dag_node = sofa::core::objectmodel::New("unnamed"); + return dag_node; } -Node::SPtr __init__(const std::string& name) -{ - return sofa::core::objectmodel::New(name); +py_shared_ptr __init__(const std::string& name) { + auto dag_node = sofa::core::objectmodel::New(name); + return dag_node; } /// Method: init (beware this is not the python __init__, this is sofa's init()) void init(Node& self) { self.init(ExecParams::defaultInstance()); } -py::object addObject(Node& self, BaseObject* object) +py::object addObject(Node& self, const py::object & object) { - if(self.addObject(object)) - return PythonFactory::toPython(object); + try { + auto base_object = py::cast>(object); + if (self.addObject(base_object)) + return object; + } catch (...) { + throw py::type_error("Trying to add an object that isn't derived from sofa::core::objectmodel::BaseObject."); + } return py::none(); } +void removeObject(Node& self, BaseObject* object) +{ + self.removeObject(object); +} + /// Implement the addObject function. py::object addObjectKwargs(Node* self, const std::string& type, const py::kwargs& kwargs) { @@ -453,16 +466,16 @@ void moduleAddNode(py::module &m) { /// typing system. py::class_(m, "BaseNode"); + py_shared_ptr>(m, "BaseNode"); py::class_ + sofa::core::objectmodel::Context, py_shared_ptr> p(m, "Node", sofapython3::doc::sofa::core::Node::Class); PythonFactory::registerType( [](sofa::core::objectmodel::Base* object) { - return py::cast(static_cast(object->toBaseNode())); + return py::cast(dynamic_cast(object->toBaseNode())); }); p.def(py::init(&__init__noname), sofapython3::doc::sofa::core::Node::init); @@ -486,7 +499,7 @@ void moduleAddNode(py::module &m) { p.def_property_readonly("objects", &property_objects, sofapython3::doc::sofa::core::Node::objects); p.def("__getattr__", &__getattr__); p.def("__getitem__", &__getitem__); - p.def("removeObject", &Node::removeObject, sofapython3::doc::sofa::core::Node::removeObject); + p.def("removeObject", &removeObject, sofapython3::doc::sofa::core::Node::removeObject); p.def("getRootPath", &Node::getRootPath, sofapython3::doc::sofa::core::Node::getRootPath); p.def("moveChild", &moveChild, sofapython3::doc::sofa::core::Node::moveChild); p.def("isInitialized", &Node::isInitialized, sofapython3::doc::sofa::core::Node::isInitialized); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.h index 5911f390..9c118361 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.h @@ -26,18 +26,10 @@ along with sofaqtquick. If not, see . ********************************************************************/ #pragma once -#include #include -#include -#include -using sofa::simulation::Node; -using sofa::core::objectmodel::BaseNode; +namespace sofapython3 { -namespace sofapython3 -{ -namespace py { using namespace pybind11; } - -void moduleAddNode(py::module &m); +void moduleAddNode(pybind11::module &m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_NodeIterator.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_NodeIterator.cpp index 36c36d67..f2944cd6 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_NodeIterator.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_NodeIterator.cpp @@ -28,10 +28,14 @@ along with sofaqtquick. If not, see . /// Neede to have automatic conversion from pybind types to stl container. #include #include -#include "Binding_NodeIterator.h" +#include -namespace sofapython3 -{ +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + +using sofa::core::objectmodel::BaseObject; + +namespace sofapython3 { void moduleAddNodeIterator(py::module &m) { @@ -70,11 +74,13 @@ void moduleAddNodeIterator(py::module &m) d.def("at", [](NodeIterator& d, size_t index) -> py::object { - return py::cast(d.get(d.owner.get(), index)); + return PythonFactory::toPython(d.get(d.owner.get(), index).get()); }); d.def("remove_at", [](NodeIterator& d, size_t index) { - BaseNode::SPtr n(dynamic_cast(d.get(d.owner.get(), index).get())); + sofa::core::sptr n( + dynamic_cast(d.get(d.owner.get(), index).get()) + ); d.owner->removeChild(n); }); } diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_NodeIterator.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_NodeIterator.h index 6166833f..fb9c47dd 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_NodeIterator.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_NodeIterator.h @@ -28,28 +28,21 @@ along with sofaqtquick. If not, see . #pragma once #include #include -#include #include -namespace sofapython3 -{ -namespace py { using namespace pybind11; } +namespace sofapython3 { -using sofa::simulation::Node; -using sofa::core::objectmodel::BaseNode; - -class NodeIterator -{ +class NodeIterator { public: - Node::SPtr owner; + sofa::core::sptr owner; size_t index=0; - std::function size ; - std::function get ; + std::function size ; + std::function (sofa::simulation::Node *, size_t)> get ; - NodeIterator(Node::SPtr owner_, - std::function size_, - std::function get_) + NodeIterator(sofa::core::sptr owner_, + std::function size_, + std::function (sofa::simulation::Node *, size_t)> get_) { size = size_; get = get_; @@ -58,6 +51,6 @@ class NodeIterator } }; -void moduleAddNodeIterator(py::module &m); +void moduleAddNodeIterator(pybind11::module &m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.cpp index 95fbaa89..0d0d8c33 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.cpp @@ -25,8 +25,9 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ -#include "Binding_ObjectFactory.h" -#include "Binding_ObjectFactory_doc.h" +#include +#include +#include #include #include #include diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.h index f31308e4..9aa788ba 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ObjectFactory.h @@ -27,7 +27,6 @@ along with sofaqtquick. If not, see . #pragma once -#include #include namespace sofapython3 { diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Prefab.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Prefab.cpp index e17fc85f..6aafb581 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Prefab.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Prefab.cpp @@ -26,42 +26,35 @@ along with sofaqtquick. If not, see . ********************************************************************/ #include -#include - -#include "Binding_Prefab.h" -#include "Binding_Prefab_doc.h" - -#include -#include -#include #include +#include +#include + +#include #include +#include using sofa::core::objectmodel::DataCallback; -PYBIND11_DECLARE_HOLDER_TYPE(Prefab, - sofapython3::py_shared_ptr, true) - #include using sofa::simulation::VisualInitVisitor; #include using sofa::simulation::Simulation; -namespace sofapython3 -{ -class Prefab_Trampoline : public Prefab, public PythonTrampoline -{ -public: - Prefab_Trampoline() = default; +/// Bind the python's attribute error +namespace pybind11 { PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) } +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } +/// To bring in the `_a` literal +using namespace pybind11::literals; - ~Prefab_Trampoline() override = default; +namespace sofapython3 { - std::string getClassName() const override - { - return "Prefab"; /// pyobject->ob_type->tp_name; - } +class Prefab_Trampoline : public Prefab { +public: + SOFA_CLASS(Prefab_Trampoline, Prefab); void doReInit() override ; }; @@ -86,14 +79,13 @@ void Prefab_Trampoline::doReInit() void moduleAddPrefab(py::module &m) { py::class_(m, "BasePrefab"); + py_shared_ptr>(m, "BasePrefab"); py::class_> f(m, "RawPrefab", py::dynamic_attr(), - py::multiple_inheritance(), sofapython3::doc::prefab::Prefab); f.def(py::init([](py::args& /*args*/, py::kwargs& kwargs){ diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Prefab.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Prefab.h index 76b158e8..b88eb945 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Prefab.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Prefab.h @@ -27,22 +27,11 @@ along with sofaqtquick. If not, see . #pragma once -#include "Binding_BaseObject.h" -#include -#include +#include -#include -#include +namespace sofapython3 { - -template class pybind11::class_>; - -namespace sofapython3 -{ - -void moduleAddPrefab(py::module &m); +void moduleAddPrefab(pybind11::module &m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_PythonScriptEvent.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_PythonScriptEvent.cpp index 36ac557b..5dba7d41 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_PythonScriptEvent.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_PythonScriptEvent.cpp @@ -25,11 +25,13 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ -#include "Binding_PythonScriptEvent.h" - +#include #include #include +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + namespace sofapython3 { using namespace pybind11::literals; diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_PythonScriptEvent.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_PythonScriptEvent.h index cd9e6e03..90119176 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_PythonScriptEvent.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_PythonScriptEvent.h @@ -28,26 +28,24 @@ along with sofaqtquick. If not, see . #pragma once #include -#include #include #include namespace sofapython3 { -namespace py { using namespace pybind11; } class PythonScriptEvent : public sofa::core::objectmodel::ScriptEvent { SOFA_EVENT_H(PythonScriptEvent) public: - PythonScriptEvent(sofa::simulation::Node::SPtr sender, const char* eventName, py::object userData=py::none()); + PythonScriptEvent(sofa::simulation::Node::SPtr sender, const char* eventName, pybind11::object userData=pybind11::none()); ~PythonScriptEvent() override; - py::object getUserData() const { return m_userData; } + pybind11::object getUserData() const { return m_userData; } inline static const char* GetClassName() { return "PythonScriptEvent"; } private: - py::object m_userData; + pybind11::object m_userData; }; void moduleAddPythonScriptEvent(); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor.cpp deleted file mode 100644 index 1dabf0c5..00000000 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/********************************************************************* -Copyright 2019, CNRS, University of Lille, INRIA - -This file is part of sofaPython3 - -sofaPython3 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 3 of the License, or -(at your option) any later version. - -sofaPython3 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 sofaqtquick. If not, see . -*********************************************************************/ -/******************************************************************** - Contributors: - - damien.marchal@univ-lille.fr - - bruno.josue.marques@inria.fr - - eve.le-guillou@centrale.centralelille.fr - - jean-nicolas.brunet@inria.fr - - thierry.gaugry@inria.fr -********************************************************************/ - diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor.h deleted file mode 100644 index 1dabf0c5..00000000 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor.h +++ /dev/null @@ -1,27 +0,0 @@ -/********************************************************************* -Copyright 2019, CNRS, University of Lille, INRIA - -This file is part of sofaPython3 - -sofaPython3 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 3 of the License, or -(at your option) any later version. - -sofaPython3 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 sofaqtquick. If not, see . -*********************************************************************/ -/******************************************************************** - Contributors: - - damien.marchal@univ-lille.fr - - bruno.josue.marques@inria.fr - - eve.le-guillou@centrale.centralelille.fr - - jean-nicolas.brunet@inria.fr - - thierry.gaugry@inria.fr -********************************************************************/ - diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor_doc.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor_doc.h deleted file mode 100644 index 6e94e052..00000000 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Visitor_doc.h +++ /dev/null @@ -1,36 +0,0 @@ -/********************************************************************* -Copyright 2019, CNRS, University of Lille, INRIA - -This file is part of sofaPython3 - -sofaPython3 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 3 of the License, or -(at your option) any later version. - -sofaPython3 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 sofaqtquick. If not, see . -*********************************************************************/ -/******************************************************************** - Contributors: - - damien.marchal@univ-lille.fr - - bruno.josue.marques@inria.fr - - eve.le-guillou@centrale.centralelille.fr - - jean-nicolas.brunet@inria.fr - - thierry.gaugry@inria.fr -********************************************************************/ - -#pragma once - -namespace sofapython3::doc::controller -{ -static auto Controller = R"( - An Interface for user interaction on SOFA Components. - Can catch events to trigger actions - )"; -} diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt b/bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt index 9a99102e..06ded287 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt @@ -17,8 +17,6 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Binding_DataEngine_doc.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_ForceField.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_ForceField_doc.h - ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Visitor.h - ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Visitor_doc.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_ObjectFactory.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_ObjectFactory_doc.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Node.h @@ -33,7 +31,6 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Data/Binding_DataString_doc.h ${CMAKE_CURRENT_SOURCE_DIR}/Data/Binding_DataVectorString.h ${CMAKE_CURRENT_SOURCE_DIR}/Data/Binding_DataVectorString_doc.h - ${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Core.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_PythonScriptEvent.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseLink.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseLink_doc.h @@ -56,7 +53,6 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Data/Binding_DataLink.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Data/Binding_DataVectorString.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_ForceField.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Visitor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_ObjectFactory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Node.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_NodeIterator.cpp diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.cpp index a17ee87e..6c98bcb7 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.cpp @@ -29,29 +29,27 @@ along with sofaqtquick. If not, see . #include using sofa::helper::logging::Message; -#include "Binding_Base.h" -#include "Binding_BaseContext.h" -#include "Binding_BaseObject.h" -#include "Binding_DataDict.h" -#include "Binding_BaseData.h" -#include "Binding_BaseCamera.h" -#include "Binding_ForceField.h" -#include "Binding_Context.h" -#include "Binding_Controller.h" -#include "Binding_DataEngine.h" -#include "Binding_ObjectFactory.h" -#include "Binding_Node.h" -#include "Binding_NodeIterator.h" -#include "Binding_Prefab.h" -#include "Binding_BaseLink.h" -#include "Binding_PythonScriptEvent.h" - -#include "Data/Binding_DataString.h" -#include "Data/Binding_DataLink.h" -#include "Data/Binding_DataVectorString.h" -#include "Data/Binding_DataContainer.h" - -#include "Submodule_Core.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include #include #include diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.h deleted file mode 100644 index a0499864..00000000 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.h +++ /dev/null @@ -1,38 +0,0 @@ -/********************************************************************* -Copyright 2019, CNRS, University of Lille, INRIA - -This file is part of sofaPython3 - -sofaPython3 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 3 of the License, or -(at your option) any later version. - -sofaPython3 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 sofaqtquick. If not, see . -*********************************************************************/ -/******************************************************************** - Contributors: - - damien.marchal@univ-lille.fr - - bruno.josue.marques@inria.fr - - eve.le-guillou@centrale.centralelille.fr - - jean-nicolas.brunet@inria.fr - - thierry.gaugry@inria.fr -********************************************************************/ - -#pragma once - -#include - -namespace sofapython3 -{ -namespace py { using namespace pybind11; } - -} /// namespace sofapython3 - - diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler.cpp index 6704cd90..1b46ac4e 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler.cpp @@ -25,43 +25,27 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ -#include "Binding_MessageHandler.h" -#include "Binding_MessageHandler_doc.h" +#include -#include +#include #include -#include -using sofapython3::PythonEnvironment; -#include +#include #include -PYBIND11_DECLARE_HOLDER_TYPE(PyMessageHandler, - sofapython3::py_shared_ptr, true) +using sofapython3::PythonEnvironment; +using sofa::helper::logging::Message; +using sofa::helper::logging::MessageHandler; +using sofa::core::objectmodel::Base; + +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } namespace sofapython3 { using sofa::core::objectmodel::Event; - void PyMessageHandler::process(Message& /*m*/) { - } - - PyMessageHandler::PyMessageHandler() { - } - - PyMessageHandler::~PyMessageHandler() { - } - - class MessageHandler_Trampoline : public PyMessageHandler, public PythonTrampoline - { - public: - MessageHandler_Trampoline() = default; - - ~MessageHandler_Trampoline() override = default; - virtual void process(Message& m) override ; - }; - void MessageHandler_Trampoline::process(Message& m) { PythonEnvironment::gil acquire {"MessageHandler"}; @@ -108,11 +92,7 @@ namespace sofapython3 void moduleAddMessageHandler(py::module &m) { - py::class_> f(m, "MessageHandler", - py::dynamic_attr(), - py::multiple_inheritance()); + py::class_ f(m, "MessageHandler", py::dynamic_attr()); f.def(py::init([]() { diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler.h b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler.h index 874e3769..fce3c7ca 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler.h @@ -31,34 +31,24 @@ along with sofaqtquick. If not, see . #include /// Forward declaration -namespace sofa { - namespace helper { - namespace logging { - class Message; - } - } +namespace sofa::helper::logging { +class Message; } -namespace sofapython3 -{ - -/// Makes an alias for the pybind11 namespace to increase readability. -namespace py { using namespace pybind11; } +namespace sofapython3 { -using namespace pybind11::literals; -using sofa::helper::logging::Message ; -using sofa::helper::logging::MessageHandler ; +class PyMessageHandler: public sofa::helper::logging::MessageHandler { +public: + void process(sofa::helper::logging::Message& m) override {} +}; -class PyMessageHandler: public MessageHandler +class MessageHandler_Trampoline : public PyMessageHandler { public: - virtual void process(Message& m) override ; - - PyMessageHandler(); - ~PyMessageHandler() override; + void process(sofa::helper::logging::Message& m) override ; }; -void moduleAddMessageHandler(py::module &m); +void moduleAddMessageHandler(pybind11::module &m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler_doc.h b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_MessageHandler_doc.h deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Vector.h b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Vector.h index bf13c2e6..246ef21c 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Vector.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Binding_Vector.h @@ -29,12 +29,8 @@ along with sofaqtquick. If not, see . #include -namespace sofapython3 -{ +namespace sofapython3 { -/// Makes an alias for the pybind11 namespace to increase readability. - namespace py { using namespace pybind11; } - - void moduleAddVector(py::module &m); + void moduleAddVector(pybind11::module &m); } ///sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/CMakeLists.txt b/bindings/Sofa/src/SofaPython3/Sofa/Helper/CMakeLists.txt index 78db96ac..ac1bce07 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/CMakeLists.txt +++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/CMakeLists.txt @@ -1,7 +1,6 @@ project(Bindings.Sofa.Helper) set(HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Helper.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Vector.h ${CMAKE_CURRENT_SOURCE_DIR}/System/Submodule_System.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_MessageHandler.h diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.cpp index 64249d4b..a4fb9474 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.cpp @@ -29,12 +29,15 @@ along with sofaqtquick. If not, see . #include #include #include -#include "System/Submodule_System.h" -#include "Binding_MessageHandler.h" -#include "Binding_Vector.h" +#include +#include +#include + +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + +namespace sofapython3 { -namespace sofapython3 -{ using sofa::core::objectmodel::Base; using sofa::helper::logging::ComponentInfo; using sofa::helper::logging::SofaComponentInfo; diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.h b/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.h deleted file mode 100644 index 455da08e..00000000 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/Submodule_Helper.h +++ /dev/null @@ -1,37 +0,0 @@ -/********************************************************************* -Copyright 2019, CNRS, University of Lille, INRIA - -This file is part of sofaPython3 - -sofaPython3 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 3 of the License, or -(at your option) any later version. - -sofaPython3 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 sofaqtquick. If not, see . -*********************************************************************/ -/******************************************************************** - Contributors: - - damien.marchal@univ-lille.fr - - bruno.josue.marques@inria.fr - - eve.le-guillou@centrale.centralelille.fr - - jean-nicolas.brunet@inria.fr - - thierry.gaugry@inria.fr -********************************************************************/ - -#pragma once -#include - -namespace sofapython3 -{ -namespace py { using namespace pybind11; } - -} /// namespace sofapython3 - - diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Binding_FileRepository.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Binding_FileRepository.cpp index d0f450a1..59f6a913 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Binding_FileRepository.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Binding_FileRepository.cpp @@ -26,9 +26,8 @@ along with sofaqtquick. If not, see . ********************************************************************/ #include -#include -#include "Binding_FileRepository.h" -#include "Binding_FileRepository_doc.h" +#include +#include #include namespace py { using namespace pybind11; } diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Binding_FileRepository.h b/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Binding_FileRepository.h index b227e0d1..bf989ad7 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Binding_FileRepository.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Binding_FileRepository.h @@ -28,12 +28,8 @@ along with sofaqtquick. If not, see . #pragma once #include -namespace sofapython3 -{ +namespace sofapython3 { -/// Makes an alias for the pybind11 namespace to increase readability. -namespace py { using namespace pybind11; } - -void moduleAddFileRepository(py::module &m); +void moduleAddFileRepository(pybind11::module &m); } ///sofapython3 \ No newline at end of file diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Submodule_System.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Submodule_System.cpp index f874ab15..c3a1373f 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Submodule_System.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Submodule_System.cpp @@ -25,14 +25,14 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ -#include "Submodule_System.h" -#include "Binding_FileRepository.h" +#include +#include -namespace sofapython3 -{ +namespace py { using namespace pybind11; } -void moduleAddSystem(py::module &m) -{ +namespace sofapython3 { + +void moduleAddSystem(py::module &m) { auto system = m.def_submodule("System"); moduleAddFileRepository(system); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Submodule_System.h b/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Submodule_System.h index 36b89bba..c9d2ad82 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Submodule_System.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Helper/System/Submodule_System.h @@ -28,11 +28,9 @@ along with sofaqtquick. If not, see . #pragma once #include -namespace sofapython3 -{ -namespace py { using namespace pybind11; } +namespace sofapython3 { -void moduleAddSystem(py::module &m); +void moduleAddSystem(pybind11::module &m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Simulation/CMakeLists.txt b/bindings/Sofa/src/SofaPython3/Sofa/Simulation/CMakeLists.txt index d9fde404..ace92e79 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Simulation/CMakeLists.txt +++ b/bindings/Sofa/src/SofaPython3/Sofa/Simulation/CMakeLists.txt @@ -14,7 +14,6 @@ endif() find_package(SofaFramework REQUIRED) find_package(SofaSimulation REQUIRED) -find_package(SofaBase REQUIRED) SP3_add_python_module( TARGET ${PROJECT_NAME} @@ -22,5 +21,5 @@ SP3_add_python_module( MODULE_NAME Simulation SOURCES ${SOURCE_FILES} HEADERS ${HEADER_FILES} - DEPENDS SofaCore SofaSimulationCore SofaSimulationGraph SofaBaseVisual SofaPython3::Plugin + DEPENDS SofaCore SofaSimulationCore SofaSimulationGraph SofaPython3::Plugin ) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Simulation/Submodule_Simulation.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Simulation/Submodule_Simulation.cpp index 85856958..f1767960 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Simulation/Submodule_Simulation.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Simulation/Submodule_Simulation.cpp @@ -40,12 +40,11 @@ using namespace pybind11::literals; using sofa::simulation::Simulation; #include -#include "Submodule_Simulation_doc.h" +#include #include #include #include -#include namespace py = pybind11; @@ -58,7 +57,6 @@ PYBIND11_MODULE(Simulation, simulation) sofa::core::init(); sofa::simulation::core::init(); sofa::simulation::graph::init(); - sofa::component::initBaseVisual(); if(!sofa::simulation::getSimulation()) sofa::simulation::setSimulation(new DAGSimulation()); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Types/Binding_BoundingBox.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Types/Binding_BoundingBox.cpp index c6ed5e9d..6555998a 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Types/Binding_BoundingBox.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Types/Binding_BoundingBox.cpp @@ -25,15 +25,17 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ -#include "Binding_BoundingBox.h" - -#include +#include +#include #include #include #include using sofa::defaulttype::BoundingBox; +using sofa::core::objectmodel::BaseData; + +namespace py { using namespace pybind11; } namespace sofapython3 { @@ -80,7 +82,11 @@ void moduleAddBoundingBox(py::module& m) }, "returns the center of the bbox"); PythonFactory::registerType("BoundingBox", [](BaseData* data) -> py::object { - return py::cast(dynamic_cast*>(data)); + // Weird bug here, using a dynamic_cast will fail to convert the BaseData to a Data on MacOS and + // MSVC, even if the type is good. We therefore use in reinterpret_cast to force it until we understand why + // the initial cast fails. + auto bbox = reinterpret_cast*>(data); + return py::cast(bbox); }); } diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Types/Binding_BoundingBox.h b/bindings/Sofa/src/SofaPython3/Sofa/Types/Binding_BoundingBox.h index 08a2c8e0..03d27ade 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Types/Binding_BoundingBox.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Types/Binding_BoundingBox.h @@ -28,11 +28,9 @@ along with sofaqtquick. If not, see . #pragma once #include -namespace sofapython3 { - -namespace py { using namespace pybind11; } +namespace sofapython3 { -void moduleAddBoundingBox(py::module& m); +void moduleAddBoundingBox(pybind11::module& m); } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Types/CMakeLists.txt b/bindings/Sofa/src/SofaPython3/Sofa/Types/CMakeLists.txt index 11694b73..f6fd02bb 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Types/CMakeLists.txt +++ b/bindings/Sofa/src/SofaPython3/Sofa/Types/CMakeLists.txt @@ -1,7 +1,6 @@ project(Bindings.Sofa.Types) set(HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Types.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BoundingBox.h ) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Types/Submodule_Types.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Types/Submodule_Types.cpp index 39505fae..2d499200 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Types/Submodule_Types.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Types/Submodule_Types.cpp @@ -27,11 +27,9 @@ along with sofaqtquick. If not, see . #include -#include "Submodule_Types.h" -#include "Binding_BoundingBox.h" +#include -namespace sofapython3 -{ +namespace sofapython3 { /// The first parameter must be named the same as the module file to load. PYBIND11_MODULE(Types, types) { diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Types/Submodule_Types.h b/bindings/Sofa/src/SofaPython3/Sofa/Types/Submodule_Types.h deleted file mode 100644 index 3e019dea..00000000 --- a/bindings/Sofa/src/SofaPython3/Sofa/Types/Submodule_Types.h +++ /dev/null @@ -1,37 +0,0 @@ -/********************************************************************* -Copyright 2019, CNRS, University of Lille, INRIA - -This file is part of sofaPython3 - -sofaPython3 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 3 of the License, or -(at your option) any later version. - -sofaPython3 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 sofaqtquick. If not, see . -*********************************************************************/ -/******************************************************************** - Contributors: - - damien.marchal@univ-lille.fr - - bruno.josue.marques@inria.fr - - eve.le-guillou@centrale.centralelille.fr - - jean-nicolas.brunet@inria.fr - - thierry.gaugry@inria.fr -********************************************************************/ - -#pragma once - - -#include - -namespace sofapython3 -{ -namespace py { using namespace pybind11; } - -} /// namespace sofapython3 diff --git a/bindings/Sofa/tests/Core/ForceField.py b/bindings/Sofa/tests/Core/ForceField.py index a8651232..c2d6e67d 100644 --- a/bindings/Sofa/tests/Core/ForceField.py +++ b/bindings/Sofa/tests/Core/ForceField.py @@ -41,6 +41,7 @@ def createParticle(node, node_name, use_implicit_scheme, use_iterative_solver): def rssffScene(use_implicit_scheme=True, use_iterative_solver=True): SofaRuntime.importPlugin("SofaSparseSolver") + SofaRuntime.importPlugin("SofaExplicitOdeSolver") node = Sofa.Core.Node("root") node.gravity = [0, -10, 0] createParticle(node, "particle", use_implicit_scheme, use_iterative_solver) diff --git a/bindings/SofaGui/src/SofaPython3/SofaGui/Binding_GUIManager.cpp b/bindings/SofaGui/src/SofaPython3/SofaGui/Binding_GUIManager.cpp index 49d3d73d..6238c972 100644 --- a/bindings/SofaGui/src/SofaPython3/SofaGui/Binding_GUIManager.cpp +++ b/bindings/SofaGui/src/SofaPython3/SofaGui/Binding_GUIManager.cpp @@ -27,11 +27,12 @@ along with sofaqtquick. If not, see . #include -#include "Binding_GUIManager.h" +#include #include #include -namespace py = pybind11; +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } namespace sofapython3 { diff --git a/bindings/SofaGui/src/SofaPython3/SofaGui/Binding_GUIManager.h b/bindings/SofaGui/src/SofaPython3/SofaGui/Binding_GUIManager.h index 8cd59f6b..affe0e03 100644 --- a/bindings/SofaGui/src/SofaPython3/SofaGui/Binding_GUIManager.h +++ b/bindings/SofaGui/src/SofaPython3/SofaGui/Binding_GUIManager.h @@ -30,13 +30,7 @@ along with sofaqtquick. If not, see . #include namespace sofapython3 { -/// Makes an alias for the pybind11 namespace to increase readability. -namespace py { using namespace pybind11; } -// @TODO: Remove with pybind11 > 2.2.4 -namespace py { -PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) -} - -void moduleAddGuiManager(py::module& m); + +void moduleAddGuiManager(pybind11::module& m); } /// namespace sofapython3 \ No newline at end of file