Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ py::object getTarget(BaseComponent *self)
{
if (!self)
return py::none();
sofa::core::ObjectFactory::ClassEntry entry = sofa::core::ObjectFactory::getInstance()->getEntry(self->getClassName());
if (!entry.creatorMap.empty())

sofa::core::objectmodel::BaseObjectDescription arg;
arg.setAttribute("type", self->getClassName());
arg.setAttribute("template", self->getTemplateName());
if (auto component = sofa::core::MainComponentFactory::getInstance()->findComponent(self->getContext(), &arg))
{
sofa::core::ObjectFactory::CreatorMap::iterator it = entry.creatorMap.find(self->getTemplateName());
if (it != entry.creatorMap.end() && *it->second->getTarget())
{
return py::cast(it->second->getTarget()) ;
}
return py::cast(component->componentModule);
}

return py::none() ;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace sofapython3 {

std::string __repr__(const ObjectFactory::ClassEntry & entry) {
std::ostringstream s;
s << "<" << entry.className << " at " << std::hex << &entry << ">";
s << entry;
return s.str();
}

Expand Down
14 changes: 10 additions & 4 deletions bindings/Sofa/tests/Binding_BaseObject_MockComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
******************************************************************************/

#include "Binding_BaseObject_MockComponent.h"
#include <sofa/core/ObjectFactory.h>
#include <sofa/core/ComponentFactory.h>


Binding_BaseObject_MockComponent::Binding_BaseObject_MockComponent():
Expand Down Expand Up @@ -56,7 +56,13 @@ void Binding_BaseObject_MockComponent::reinit(){
d_test.setValue("reinit");
}

bool registerComponent()
{
sofa::core::MainComponentFactory::getInstance()->registerComponent(
sofa::core::CreateComponent<Binding_BaseObject_MockComponent>("Binding_BaseObject_MockComponent")
.withModule("SofaPython3")
.withDescription("This component is used to test several functions of Binding_BaseObject"));
return true;
}


static int Binding_BaseObject_MockComponentClass = sofa::core::RegisterObject("This component is used to test several functions of Binding_BaseObject")
.add< Binding_BaseObject_MockComponent >();
bool b = registerComponent();
38 changes: 32 additions & 6 deletions bindings/SofaTypes/src/SofaPython3/SofaTypes/Binding_Mat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "Binding_Mat.h"
#include <functional>
#include <pybind11/operators.h>
#include <pybind11/eigen.h>

#define BINDING_MAT_MAKE_NAME(R, C) \
std::string(std::string("Mat") + std::to_string(R) + "x" + std::to_string(C))
Expand Down Expand Up @@ -59,6 +60,31 @@ static void addMat(py::module & /*m*/, py::class_<Mat<R, C, double>> &p) {
typedef typename MatClass::Line Row;
p.def(py::init());
p.def(py::init<const MatClass &>());
p.def(py::init([](py::buffer b) {

/* Request a buffer descriptor from Python */
py::buffer_info info = b.request();

/* Some basic validation checks ... */
if (!info.item_type_is_equivalent_to<double>())
throw std::runtime_error(
"Incompatible format: expected a double array!");

if (info.ndim != 2)
throw std::runtime_error("Incompatible buffer dimension!");

return Mat<R, C, double>(static_cast<double*>(info.ptr));
}));
p.def_buffer([](Mat<R, C, double>& self) -> py::buffer_info {
return py::buffer_info(
self.elems.data(), // pointer
sizeof(double), // itemsize
py::format_descriptor<double>::format(), // format
2, // ndim
{static_cast<py::ssize_t>(R), static_cast<py::ssize_t>(C)}, // shape
{sizeof(double) * static_cast<py::ssize_t>(C), sizeof(double)} // strides (row-major)
);
});
p.def_property_readonly("rows", &MatClass::getNbLines);
p.def_property_readonly("cols", &MatClass::getNbCols);
p.def("clear", &MatClass::clear);
Expand Down Expand Up @@ -184,7 +210,7 @@ static void addMatProduct(py::module & /*m*/, py::class_<Mat<R_1, C_1, double>>
template <sofa::Size R, sofa::Size C> struct MATRIX {
static void addMat(py::module &m) {
typedef Mat<R, C, double> MatClass;
py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(R, C).c_str());
py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(R, C).c_str(), py::buffer_protocol());
::addMat(m, p);
}
};
Expand All @@ -203,7 +229,7 @@ template <> struct MATRIX<1, 1> {
// typedef typename MatClass::Line Row;
// typedef typename MatClass::Col Col;

py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(1, 1).c_str());
py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(1, 1).c_str(), py::buffer_protocol());
p.def(py::init([](py::list l) {
MatClass *mat = new MatClass(sofa::type::NOINIT);
if (py::isinstance<py::list>(l[0])) // 2D array
Expand Down Expand Up @@ -233,7 +259,7 @@ template <> struct MATRIX<2, 2> {
typedef typename MatClass::Line Row;
// typedef typename MatClass::Col Col;

py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(2, 2).c_str());
py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(2, 2).c_str(), py::buffer_protocol());
p.def(py::init<Row, Row>());
p.def(py::init([](py::list l) {
MatClass *mat = new MatClass(sofa::type::NOINIT);
Expand Down Expand Up @@ -264,7 +290,7 @@ template <> struct MATRIX<3, 3> {
typedef typename MatClass::Line Row;
// typedef typename MatClass::Col Col;

py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(3, 3).c_str());
py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(3, 3).c_str(), py::buffer_protocol());
p.def(py::init<Row, Row, Row>());
p.def(py::init([](py::list l) {
MatClass *mat = new MatClass(sofa::type::NOINIT);
Expand Down Expand Up @@ -295,7 +321,7 @@ template <> struct MATRIX<4, 4> {
typedef typename MatClass::Line Row;
// typedef typename MatClass::Col Col;

py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(4, 4).c_str());
py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(4, 4).c_str(), py::buffer_protocol());
p.def(py::init<Row, Row, Row, Row>());
p.def(py::init([](py::list l) {
MatClass *mat = new MatClass(sofa::type::NOINIT);
Expand Down Expand Up @@ -326,7 +352,7 @@ template <> struct MATRIX<3, 4> {
typedef typename MatClass::Line Row;
// typedef typename MatClass::Col Col;

py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(3, 4).c_str());
py::class_<MatClass> p(m, BINDING_MAT_MAKE_NAME(3, 4).c_str(), py::buffer_protocol());
p.def(py::init<Row, Row, Row>());
p.def(py::init([](py::list l) {
MatClass *mat = new MatClass(sofa::type::NOINIT);
Expand Down
22 changes: 22 additions & 0 deletions bindings/SofaTypes/tests/pyfiles/mat_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import Sofa
from SofaTypes import Mat1x1, Mat2x2, Mat3x3, Vec2d

import numpy as np

class TestMaterialMatrix(unittest.TestCase):

def test_Constructors(self):
Expand Down Expand Up @@ -62,3 +64,23 @@ def test_Operators(self):
m_test /= 2.0
expected_inplace_div = Mat2x2([[0.5, 1.0], [1.5, 2.0]])
self.assertEqual(m_test, expected_inplace_div)

def test_to_numpy(self):
m1 = Mat2x2([[1.0, 2.0], [3.0, 4.0]])
n1 = np.array(m1, copy = False) #n1 is a view on m1
n1[0, 0] = 9.0
self.assertEqual(m1[0][0], 9.0)

m2 = Mat2x2([[5.0, 6.0], [7.0, 8.0]])
n2 = np.array(m2, copy = False)

prod = n1 @ n2
expected_prod = np.array([[59.0, 70.0], [43.0, 50.0]])
np.testing.assert_array_equal(prod, expected_prod)

m3_prod = Mat2x2(prod)

self.assertEqual(m3_prod[0][0], prod[0,0])
self.assertEqual(m3_prod[0][1], prod[0,1])
self.assertEqual(m3_prod[1][0], prod[1,0])
self.assertEqual(m3_prod[1][1], prod[1,1])
Loading