From 1ee446186c66025b3d564854c6101a559b693a28 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Fri, 17 Oct 2025 16:03:28 +0200 Subject: [PATCH 1/2] Add validation for numpy array as return type in AddKToMatrix bindings --- .../Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp index 85f2461a7..0986d02ad 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp @@ -177,6 +177,10 @@ namespace sofapython3 throw py::type_error("Can't read return value of AddKToMatrix. The method should return either a plain 2D matrix or a vector of tuples (i, j, val)"); } } + else + { + throw py::type_error("Can't read return value of AddKToMatrix. A numpy array is expected"); + } } From 10df94aedaaa959ad0a87dc2892506d76a8c19ca Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 30 Oct 2025 09:28:46 +0100 Subject: [PATCH 2/2] Refactor AddKToMatrix return type validation and simplify conditional checks --- .../Sofa/Core/Binding_ForceField.cpp | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp index 0986d02ad..e58068f07 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_ForceField.cpp @@ -147,40 +147,39 @@ namespace sofapython3 py::object ret = _addKToMatrix(mparams, nNodes, nDofs); + if(!py::isinstance(ret)) + { + throw py::type_error("Can't read return value of AddKToMatrix. A numpy array is expected"); + } + // if ret is numpy array - if(py::isinstance(ret)) + auto r = py::cast(ret); + if (r.ndim() == 3 && r.shape(2) == 1) { - auto r = py::cast(ret); - if (r.ndim() == 3 && r.shape(2) == 1) + // read K as a plain 2D matrix + auto kMatrix = r.unchecked(); + for (size_t x = 0 ; x < size_t(kMatrix.shape(0)) ; ++x) { - // read K as a plain 2D matrix - auto kMatrix = r.unchecked(); - for (size_t x = 0 ; x < size_t(kMatrix.shape(0)) ; ++x) + for (size_t y = 0 ; y < size_t(kMatrix.shape(1)) ; ++y) { - for (size_t y = 0 ; y < size_t(kMatrix.shape(1)) ; ++y) - { - mat->add(int(offset + x), int(offset + y), kMatrix(x,y, 0)); - } + mat->add(int(offset + x), int(offset + y), kMatrix(x,y, 0)); } } - else if (r.ndim() == 2 && r.shape(1) == 3) - { - // consider ret to be a list of tuples [(i,j,[val])] - auto kMatrix = r.unchecked(); - for (auto x = 0 ; x < kMatrix.shape(0) ; ++x) - { - mat->add(int(offset + size_t(kMatrix(x,0))), int(offset + size_t(kMatrix(x,1))), kMatrix(x,2)); - } - } - else + } + else if (r.ndim() == 2 && r.shape(1) == 3) + { + // consider ret to be a list of tuples [(i,j,[val])] + auto kMatrix = r.unchecked(); + for (auto x = 0 ; x < kMatrix.shape(0) ; ++x) { - throw py::type_error("Can't read return value of AddKToMatrix. The method should return either a plain 2D matrix or a vector of tuples (i, j, val)"); + mat->add(int(offset + size_t(kMatrix(x,0))), int(offset + size_t(kMatrix(x,1))), kMatrix(x,2)); } } else { - throw py::type_error("Can't read return value of AddKToMatrix. A numpy array is expected"); + throw py::type_error("Can't read return value of AddKToMatrix. The method should return either a plain 2D matrix or a vector of tuples (i, j, val)"); } + }