diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp index 6aa8d763..81365ecf 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp @@ -449,12 +449,21 @@ py::object BindingBase::setDataValues(Base& self, py::kwargs kwargs) return py::none(); } +auto getBaseBinding(py::module& m) +{ + static py::class_> base(m, "Base", py::dynamic_attr(), doc::base::BaseClass); + return base; +} + +void moduleForwardAddBase(py::module& m) +{ + getBaseBinding(m); +} + void moduleAddBase(py::module &m) { - moduleForwardAddBaseData(m); - moduleForwardAddBaseLink(m); + auto base = getBaseBinding(m); - py::class_> base(m, "Base", py::dynamic_attr(), doc::base::BaseClass); /// set & get the name as string. The alternative is to access the data field using /// obj.name.value = "aName" 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 670ce54b..06a98e59 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h @@ -68,7 +68,9 @@ class BindingBase static std::string getLinkPath(sofa::core::objectmodel::Base& self); }; - +/// Forward declaration in pybind11. +/// more details in: https://github.com/sofa-framework/SofaPython3/pull/457 +void moduleForwardAddBase(pybind11::module& m); void moduleAddBase(pybind11::module& m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseClass.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseClass.cpp new file mode 100644 index 00000000..7fbbc0dd --- /dev/null +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseClass.cpp @@ -0,0 +1,48 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2021 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Contact information: contact@sofa-framework.org * +******************************************************************************/ + +#include +#include +#include + +namespace sofapython3 +{ +using namespace sofa::core::objectmodel; + +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + +auto getBaseClassBinding(py::module& m) +{ + static py::class_> base(m, "BaseClass", doc::baseclass::classdocstring); + return base; +} + +void moduleForwardAddBaseClass(py::module& m) +{ + getBaseClassBinding(m); +} + +void moduleAddBaseClass(py::module &m) +{ + // adds here the BaseClass's binded function (if any). +} + +} /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseClass.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseClass.h new file mode 100644 index 00000000..6ae2c6b7 --- /dev/null +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseClass.h @@ -0,0 +1,32 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2021 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Contact information: contact@sofa-framework.org * +******************************************************************************/ + +#pragma once + +#include + +namespace sofapython3 { + +/// Forward declaration in pybind11. +/// more details in: https://github.com/sofa-framework/SofaPython3/pull/457 +void moduleForwardAddBaseClass(pybind11::module& m); +void moduleAddBaseClass(pybind11::module& m); + +} /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseClass_doc.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseClass_doc.h new file mode 100644 index 00000000..2ed3d7d3 --- /dev/null +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseClass_doc.h @@ -0,0 +1,31 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2021 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Contact information: contact@sofa-framework.org * +******************************************************************************/ + +#pragma once + +namespace sofapython3::doc::baseclass { + +static auto classdocstring = + R"(Class hierarchy reflection base class +This class provides information on the class and parent classes of components. +It is created by using the SOFA_CLASS macro on each new class declaration. +All classes deriving from Base should use the SOFA_CLASS macro within their declaration.)"; + +} diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp index ecc83750..d00341e6 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.cpp @@ -207,8 +207,6 @@ void moduleForwardAddBaseData(py::module& m) void moduleAddBaseData(py::module& m) { /// Register the BaseData binding into the pybind11 system. - //py::class_> data(m, "Data", sofapython3::doc::baseData::BaseDataClass); - auto data =getPythonClassForBaseData(m); data.def("getName", [](BaseData& b){ return b.getName(); }, sofapython3::doc::baseData::getName); data.def("setName", [](BaseData& b, const std::string& s){ b.setName(s); }, sofapython3::doc::baseData::setName); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h index badd6522..54be7010 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseData.h @@ -24,6 +24,8 @@ namespace sofapython3 { + /// Forward declaration in pybind11. + /// more details in: https://github.com/sofa-framework/SofaPython3/pull/457 void moduleForwardAddBaseData(pybind11::module& m); void moduleAddBaseData(pybind11::module& m); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h index 1cf5df4a..7beca2fa 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.h @@ -24,6 +24,8 @@ namespace sofapython3 { + /// Forward declaration in pybind11. + /// more details in: https://github.com/sofa-framework/SofaPython3/pull/457 void moduleForwardAddBaseLink(pybind11::module& m); void moduleAddBaseLink(pybind11::module& m); diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseMeshTopology.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseMeshTopology.cpp index 2759c530..886179b0 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseMeshTopology.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseMeshTopology.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -36,8 +37,21 @@ using namespace sofa::core::topology; namespace sofapython3 { + +auto getPythonClassForBaseMeshTopology(py::module& m) +{ + /// Register the BaseData binding into the pybind11 system. + static py::class_> basemesh(m, "BaseMeshTopology"); + return basemesh; +} + +void moduleForwardAddBaseMeshTopology(py::module& m) +{ + getPythonClassForBaseMeshTopology(m); +} + void moduleAddBaseMeshTopology(py::module& m) { - py::class_> c (m, "BaseMeshTopology"); + auto c = getPythonClassForBaseMeshTopology(m); /// register the BaseMeshTopology binding in the downcasting subsystem PythonFactory::registerType([](sofa::core::objectmodel::Base* object) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseMeshTopology.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseMeshTopology.h index db28451e..7f8dd115 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseMeshTopology.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseMeshTopology.h @@ -24,6 +24,9 @@ namespace sofapython3 { +/// Forward declaration in pybind11. +/// more details in: https://github.com/sofa-framework/SofaPython3/pull/457 +void moduleForwardAddBaseMeshTopology(pybind11::module &m); void moduleAddBaseMeshTopology(pybind11::module &m); } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.cpp index 7f9a476c..06fe77b6 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.cpp @@ -188,10 +188,21 @@ py::object __getitem__(BaseObject &self, std::string s) return getItem(self, s); } -void moduleAddBaseObject(py::module& m) +auto getBaseObjectBinding(py::module& m) { /// Register the BaseObject binding into the pybind11 typing system - py::class_>p(m, "Object", sofapython3::doc::baseObject::Class); + static py::class_>p(m, "Object", sofapython3::doc::baseObject::Class); + return p; +} + +void moduleForwardAddBaseObject(py::module& m) +{ + getBaseObjectBinding(m); +} + +void moduleAddBaseObject(py::module& m) +{ + auto p = getBaseObjectBinding(m); /// Register the BaseObject binding into the downcasting subsystem PythonFactory::registerType( diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.h index 3e40176d..b85eed1f 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseObject.h @@ -29,6 +29,8 @@ class BaseObject; namespace sofapython3 { pybind11::object getItem(const sofa::core::objectmodel::BaseObject & self, const std::string& path); + +void moduleForwardAddBaseObject(pybind11::module &m); void moduleAddBaseObject(pybind11::module &m); } /// namespace sofapython diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Mass.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Mass.cpp index 75af4211..268b7a0d 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Mass.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Mass.cpp @@ -94,4 +94,10 @@ void moduleAddMass(py::module &m) { declare_mass(m); } +void moduleForwardAddBaseMass(py::module& m) +{ + static py::class_> basemass(m, "BaseMass"); +} + } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Mass.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Mass.h index 826b78da..7316b6ab 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Mass.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Mass.h @@ -24,6 +24,9 @@ namespace sofapython3 { +/// Forward declaration in pybind11. +/// more details in: https://github.com/sofa-framework/SofaPython3/pull/457 +void moduleForwardAddBaseMass(pybind11::module &m); void moduleAddMass(pybind11::module &m); } /// namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Topology.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Topology.cpp index ed57ba11..63c182c5 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Topology.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Topology.cpp @@ -35,8 +35,17 @@ using namespace sofa::core::topology; namespace sofapython3 { +auto getTopologyClass(py::module& m){ + static py::class_> c (m, "Topology"); + return c; +} + +void moduleForwardAddTopology(py::module& m) { + getTopologyClass(m); +} + void moduleAddTopology(py::module& m) { - py::class_> c (m, "Topology"); + getTopologyClass(m); } } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Topology.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Topology.h index 5f89f0e1..4bd7d4d1 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Topology.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Topology.h @@ -24,6 +24,9 @@ namespace sofapython3 { +/// Forward declaration in pybind11. +/// more details in: https://github.com/sofa-framework/SofaPython3/pull/457 +void moduleForwardAddTopology(pybind11::module &m); void moduleAddTopology(pybind11::module &m); } // namespace sofapython3 diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt b/bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt index 6dad5fea..d7ff4fd7 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt @@ -3,6 +3,8 @@ project(Bindings.Sofa.Core) set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Base.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Base_doc.h + ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseClass.h + ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseClass_doc.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_DataDict.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_DataDict_doc.h ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseData.h @@ -51,6 +53,7 @@ set(HEADER_FILES set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Base.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseClass.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseData.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_DataDict.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseObject.cpp @@ -72,12 +75,12 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/Binding_NodeIterator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_PointSetTopologyModifier.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Prefab.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Core.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_PythonScriptEvent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseLink.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_Topology.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseMeshTopology.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Binding_TaskScheduler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Submodule_Core.cpp ) if (NOT TARGET SofaPython3::Plugin) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.cpp index 546bb435..462d220c 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Submodule_Core.cpp @@ -23,6 +23,7 @@ using sofa::helper::logging::Message; #include +#include #include #include #include @@ -44,6 +45,7 @@ using sofa::helper::logging::Message; #include #include #include +#include #include #include @@ -103,6 +105,27 @@ PYBIND11_MODULE(Core, core) #Sofa.Core.WriteAccessor )doc"; + + + /// Forward declaration of a class in pybind11. + /// The general idea is that to avoid typeing errors in pybind11 because of -yet- to + /// define classes it is needed to register binded class before any use (including use + /// in function signature inferance) + /// more details in: https://github.com/sofa-framework/SofaPython3/pull/457 + moduleForwardAddBaseClass(core); + moduleForwardAddBase(core); + moduleForwardAddBaseObject(core); + moduleForwardAddBaseData(core); + moduleForwardAddBaseLink(core); + moduleForwardAddTopology(core); + moduleForwardAddBaseMeshTopology(core); + moduleForwardAddBaseMass(core); + + py::class_> basems(core, "BaseMechanicalState"); + + /// When all forward declarations in pybind11 are done we can actually fully + /// define the full binding. moduleAddPythonScriptEvent(); moduleAddDataDict(core); moduleAddDataDictIterator(core); @@ -143,7 +166,6 @@ PYBIND11_MODULE(Core, core) msg_info("SofaPython3.Core") << "Sofa.Core unload()"; })); - } } ///namespace sofapython3