Skip to content

Commit 0ca7950

Browse files
committed
Add addLink method in Binding_Base to create links dynamically
1 parent 6d1bd9f commit 0ca7950

File tree

6 files changed

+54
-1
lines changed

6 files changed

+54
-1
lines changed

Plugin/src/SofaPython3/DataHelper.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ along with sofaqtquick. If not, see <http://www.gnu.org/licenses/>.
3535
#include <SofaPython3/DataCache.h>
3636
#include <SofaPython3/PythonFactory.h>
3737

38+
using sofa::core::objectmodel::BaseLink;
39+
3840
namespace sofapython3
3941
{
4042

@@ -597,5 +599,30 @@ BaseData* addData(py::object py_self, const std::string& name, py::object value,
597599
return data;
598600
}
599601

602+
BaseLink* addLink(py::object py_self, const std::string& name, py::object value, const std::string& help)
603+
{
604+
Base* self = py::cast<Base*>(py_self);
605+
if (isProtectedKeyword(name))
606+
throw py::value_error("addLink: Cannot call addLink with name " + name + ": Protected keyword");
607+
608+
checkAmbiguousCreation(py_self, name, "link");
609+
610+
BaseLink::InitLink<Base> initlink(self, name, help);
600611

612+
BaseLink* link = new sofa::core::objectmodel::SingleLink<Base, Base, BaseLink::FLAG_MULTILINK>(initlink);
613+
if (py::isinstance<std::string>(value))
614+
{
615+
auto linkpath = py::cast<std::string>(value);
616+
if (linkpath[0] != '@')
617+
linkpath = "@" + linkpath;
618+
if (!link->read(linkpath))
619+
throw py::value_error("addLink: Cannot read link path " + linkpath + ": is link valid?");
620+
}
621+
else
622+
link->setLinkedBase(py::cast<Base*>(value));
623+
624+
// self->addLink(link);
625+
return link;
601626
}
627+
628+
} // namespace sofapython3

Plugin/src/SofaPython3/DataHelper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ namespace py { using namespace pybind11; }
5959

6060
using sofa::core::objectmodel::Base;
6161
using sofa::core::objectmodel::BaseData;
62+
using sofa::core::objectmodel::BaseLink;
6263
using sofa::core::objectmodel::BaseNode;
6364
using sofa::core::objectmodel::BaseObject;
6465
using sofa::defaulttype::AbstractTypeInfo;
@@ -189,6 +190,7 @@ class scoped_writeonly_access
189190
};
190191

191192
SOFAPYTHON3_API 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 = "");
193+
SOFAPYTHON3_API BaseLink* addLink(py::object py_self, const std::string& name, py::object value, const std::string& help);
192194
SOFAPYTHON3_API bool isProtectedKeyword(const std::string& name);
193195

194196
} // namespace sofapython3

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,11 @@ BaseData* BindingBase::addData(py::object py_self, const std::string& name, py::
311311
return sofapython3::addData(py_self, name, value, defaultValue, help, group, type);
312312
}
313313

314+
BaseLink* BindingBase::addLink(py::object py_self, const std::string& name, py::object value, const std::string& help)
315+
{
316+
return sofapython3::addLink(py_self, name, value, help);
317+
}
318+
314319
BaseData* BindingBase::addDataFromData(Base* self, py::object d)
315320
{
316321
BaseData* data = py::cast<BaseData*>(d);
@@ -420,6 +425,7 @@ void moduleAddBase(py::module &m)
420425
base.def("getLinks", &BindingBase::getLinks, pybind11::return_value_policy::reference, sofapython3::doc::base::getLinks);
421426
base.def("addData", &BindingBase::addData, "name"_a, "value"_a = py::none(), "default"_a = py::none(), "help"_a = "", "group"_a = "", "type"_a = "", sofapython3::doc::base::addData);
422427
base.def("addData", &BindingBase::addDataFromData, sofapython3::doc::base::addDataInitialized);
428+
base.def("addLink", &BindingBase::addLink, "name"_a, "value"_a, "help"_a = "", sofapython3::doc::base::addLink);
423429
base.def("__getattr__", &BindingBase::__getattr__);
424430
base.def("__setattr__", &BindingBase::__setattr__);
425431
base.def("getData", &BindingBase::getData, sofapython3::doc::base::getData);

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ namespace py {
5151
using namespace pybind11::literals;
5252
using sofa::core::objectmodel::Base;
5353
using sofa::core::objectmodel::BaseData;
54+
using sofa::core::objectmodel::BaseLink;
5455
using sofa::core::sptr;
5556

5657
class BindingBase
@@ -70,6 +71,7 @@ class BindingBase
7071
static py::list getLinks(Base& self);
7172
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 = "");
7273
static BaseData* addDataFromData(Base* self, py::object d);
74+
static BaseLink* addLink(py::object py_self, const std::string& name, py::object value, const std::string& help);
7375
static py::list __dir__(Base* self);
7476
static py::object __getattr__(py::object self, const std::string& s);
7577
static void __setattr__(py::object self, const std::string& s, py::object value);

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_BaseLink.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ void moduleAddBaseLink(py::module& m)
8787

8888
link.def("getLinkedData", &BaseLink::getLinkedData, sofapython3::doc::baseLink::getLinkedData);
8989
link.def("getLinkedBase", getLinkedBase, "index"_a = 0, sofapython3::doc::baseLink::getLinkedBase);
90+
link.def("setLinkedBase", &BaseLink::setLinkedBase, sofapython3::doc::baseLink::getLinkedBase);
91+
9092

9193
link.def("getLinkedPath", &BaseLink::getLinkedPath, "index"_a = 0, sofapython3::doc::baseLink::getLinkedPath);
9294
link.def("read", &BaseLink::read, sofapython3::doc::baseLink::read);

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base_doc.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,24 @@ static auto addData =
123123
:type name: string
124124
:type value: object
125125
:type help: string
126-
:type groupe: string
126+
:type group: string
127127
:type type: string
128128
)";
129129

130+
static auto addLink =
131+
R"(
132+
Create a Link to a SOFA component and adds it to the base.
133+
Note that this method should only be called if the field was not initialized with the initLink method
134+
:param self: the base itself
135+
:param name: the name of the link to be added
136+
:param value: the value from which the data can be created (either a pathname or a SofaBase)
137+
:param help: help message that describes the link to be created
138+
:type self: object
139+
:type name: string
140+
:type value: object
141+
:type help: string
142+
)";
143+
130144
static auto addDataInitialized =
131145
R"(
132146
Add a data field.

0 commit comments

Comments
 (0)