Skip to content

Commit 539badc

Browse files
committed
Squashed commit of the following:
commit 833bd69 Author: Hugo <hugo.talbot@sofa-framework.org> Date: Fri Feb 27 00:40:59 2026 +0100 [doc] Use sphinx-design in order to fix doc generation (#586) Co-authored-by: hugtalbot <hugo.talbot@inria.fr> commit d982bc8 Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Thu Feb 26 23:11:32 2026 +0100 Remove unappropriate comment (#591) commit ae7e8e1 Author: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Thu Feb 26 18:39:56 2026 +0100 Ignore the meshing scenes (#587) commit 6593f34 Author: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Thu Feb 26 18:38:58 2026 +0100 [RPyC] Add new exposed methods to SOFA server (#570) * Add a way to init the root remotly * Add method to change working dir on remote commit bdbaece Author: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Thu Feb 26 10:29:37 2026 +0100 Add python modules that uses the CGAL binding (#567) * Add python modules that uses the CGAL binding instead of the CGALPlugin to generate mesh from a pointcloud or a surfacic polyhedron * Add a SOFA scene opening and using the generated mesh with CGAL * Sort all files into a meshing repo and add a Gmsh example * Make display optionnal * Fix typo --------- Co-authored-by: hugtalbot <hugo.talbot@inria.fr> Co-authored-by: Themis Skamagkis <70031729+th-skam@users.noreply.github.com> commit 617d506 Author: Hugo <hugo.talbot@sofa-framework.org> Date: Thu Feb 26 10:29:13 2026 +0100 [examples] Add a thermo-elastic example (#204) * [examples] Add a thermo-elastic example * minor comment to remove * Get compatible with #198 and add legend * Remove option of topo changes * Update scene further to recently introduced templates in Mass * avoid using strings * update scene with imgui, linkpath etc --------- Co-authored-by: hugtalbot <hugo.talbot@inria.fr> commit 4fb7e89 Author: leobois67 <leo.bois@inria.fr> Date: Wed Feb 25 18:58:24 2026 +0100 Example of a ForceField implemented with JAX (#557) * Add the example * Igne jax example on main CI * Fix ignoring the jax examples * Fix addKToMatrix() with different options * Apply suggestions from code review --------- Co-authored-by: Paul Baksic <paul.baksic@outlook.fr> Co-authored-by: Hugo <hugo.talbot@sofa-framework.org> commit b3a79c6 Author: Hugo <hugo.talbot@sofa-framework.org> Date: Wed Feb 25 15:50:54 2026 +0100 Fix code block indentation for createScene function (#582) Updated code block formatting for createScene function. This should fix the doc generation commit fc75967 Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Fri Feb 13 03:42:51 2026 +0100 fix wrong parameter order in addDForce and addKToMatrix (#579) * fix wrong parameter order in addDForce * also fix addKToMatrix commit ca2be7c Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Fri Feb 13 03:42:37 2026 +0100 Add bindings for prism and pyramid topology functions (#578) commit 346d298 Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Fri Feb 13 03:42:20 2026 +0100 ordering field is deprecated, use NaturalOrderingMethod instead (#577) commit 959b4cd Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Fri Feb 13 03:42:02 2026 +0100 Redirect SOFA logs to Python's sys.stdout using a custom PythonMessageHandler (#576) * Redirect SOFA logs to Python's sys.stdout using a custom PythonMessageHandler. * cleaning * Redirect SOFA logs to Python's sys.stdout using a custom PythonMessageHandler. commit c0dc30e Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Thu Feb 12 10:43:05 2026 +0100 Clean getRecords in Timer module (#561) * Clean getRecords in Timer module * remove extra /** commit d2ba475 Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Wed Feb 4 23:59:52 2026 +0100 include `sofa/core/fwd.h` instead of the forward declaration (#575) commit c209f3a Author: Frederick Roy <fredroy@users.noreply.github.com> Date: Wed Feb 4 22:50:20 2026 +0900 fix mixed-up quote/doublequote, plus consistent quoting (#574) commit 7760402 Author: Hugo <hugo.talbot@sofa-framework.org> Date: Tue Feb 3 08:05:33 2026 +0100 Generalize use of initRoot (#566) Co-authored-by: hugtalbot <hugo.talbot@inria.fr> commit b29cfe5 Author: Damien Marchal <damien.marchal@univ-lille1.fr> Date: Thu Jan 29 20:19:43 2026 +0100 Remove the implementation of getPathName as it is now in BaseData (#556) See: sofa-framework/sofa#5759 Co-authored-by: Hugo <hugo.talbot@sofa-framework.org> commit c7fb254 Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Thu Jan 29 20:08:22 2026 +0100 Introduce an example of a custom message handler (#569) commit f4e90d4 Author: Hugo <hugo.talbot@sofa-framework.org> Date: Thu Jan 29 09:00:43 2026 +0100 Follow lifecycle v26.06 deprecated header (#571) Co-authored-by: hugtalbot <hugo.talbot@inria.fr> commit 8bf0162 Author: Frederick Roy <fredroy@users.noreply.github.com> Date: Wed Jan 7 06:48:05 2026 +0900 remove import of scipy.misc, which is deprecated (#564) commit 1016b94 Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Thu Dec 18 16:37:52 2025 +0100 Update advanced_timer.py with comments and fix deprecated data (#562) commit 29c4e87 Author: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Tue Dec 16 12:01:32 2025 +0100 Add example scene using CCDTightInclusion (#559) * Add example scene using CCDTightInclusion * Replace ProjectedGaussSeidel with BlockGaussSeidel * Fix scene error commit d38d3c4 Author: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Fri Dec 12 11:53:20 2025 +0100 Apply name changing on code and examples (#560) commit b09d921 Author: Damien Marchal <damien.marchal@univ-lille1.fr> Date: Thu Nov 13 15:28:05 2025 +0100 Add Quaternion to python factory so we can create data field with this type. (#555) commit a66c054 Author: Damien Marchal <damien.marchal@univ-lille1.fr> Date: Thu Nov 13 15:27:48 2025 +0100 Improve error message when the SetDataFromArray does not match (#554) * Improve error message when the SetDataFromArray does not match * Apply suggestions from code review --------- Co-authored-by: Hugo <hugo.talbot@sofa-framework.org> commit 746745c Author: Damien Marchal <damien.marchal@univ-lille1.fr> Date: Thu Nov 13 15:27:28 2025 +0100 Add context manager behavior to Node() (#545) This allows to use with statment to have good looking indentation in sofa scene. eg: with Node("YOLO") as w: w.addObject("YY") commit af98611 Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Thu Nov 13 15:25:55 2025 +0100 Support more types of linear systems (#542) * Support more types of linear systems * add support for BTD commit ae6b330 Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Thu Nov 13 10:35:28 2025 +0100 add missing required plugin in test (#558) commit 6ef05ed Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Tue Nov 11 14:34:26 2025 +0100 Fix binding after #5648 (#528) Co-authored-by: Hugo <hugo.talbot@sofa-framework.org> commit 5029c05 Author: Alex Bilger <alxbilger@users.noreply.github.com> Date: Thu Nov 6 10:24:24 2025 +0100 Add validation for numpy array as return type in AddKToMatrix bindings (#541) * Add validation for numpy array as return type in AddKToMatrix bindings * Refactor AddKToMatrix return type validation and simplify conditional checks commit 8ba1e2c Author: Damien Marchal <damien.marchal@univ-lille1.fr> Date: Thu Oct 30 16:06:25 2025 +0100 Register in the PythonFactory Rigid3::Coord (#544) Because currently only Rigid3::VecCoord was supported. commit 72ed0e6 Author: Damien Marchal <damien.marchal@univ-lille1.fr> Date: Thu Oct 30 16:06:16 2025 +0100 Add proper return value to event overriden in python (#543) Currently the controllers implemented in python cannot report the the event processing system in sofa that there is no need anymore to process the event. The PR allows to do. Every onXXXXXX() that implement an event processor can no return a value. If it is None or False then processing of event use this to continue the propagation If it is True (aka: has been processed/no more further), then the SOFA system will not proposed to other component to process the same event
1 parent ac3ed74 commit 539badc

File tree

67 files changed

+5340
-345
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+5340
-345
lines changed

Plugin/src/SofaPython3/DataHelper.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,7 @@ std::ostream& operator<<(std::ostream& out, const py::buffer_info& p)
9595

9696
std::string getPathTo(Base* b)
9797
{
98-
BaseNode* node = dynamic_cast<BaseNode*>(b);
99-
if(node)
100-
return node->getPathName();
101-
BaseObject* object = dynamic_cast<BaseObject*>(b);
102-
if(object)
103-
return object->getPathName();
104-
105-
assert(true && "Only Base & BaseObject are supported");
106-
return "";
98+
return b->getPathName();
10799
}
108100

109101
const char* getFormat(const AbstractTypeInfo& nfo)

Plugin/src/SofaPython3/PythonEnvironment.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ void PythonEnvironment::Init()
206206

207207
// Workaround: try to import scipy from the main thread this prevents a deadlock when importing
208208
// scipy from a worker thread when we use the SofaScene asynchronous loading
209-
executePython([]{ PyRun_SimpleString("try:\n\tfrom scipy import misc, optimize\nexcept:\n\tpass\n");});
209+
executePython([]{ PyRun_SimpleString("try:\n\tfrom scipy import optimize\nexcept:\n\tpass\n");});
210210

211211
// If the script directory is not available (e.g. if the interpreter is invoked interactively
212212
// or if the script is read from standard input), path[0] is the empty string,

Plugin/src/SofaPython3/PythonFactory.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,17 @@ bool PythonFactory::registerDefaultTypes()
503503
PythonFactory::registerType<sofa::core::topology::Topology::Hexa>("Hexa");
504504
PythonFactory::registerType<sofa::core::topology::Topology::Penta>("Penta");
505505

506-
// State vectors
506+
// Rigid
507+
PythonFactory::registerType<sofa::defaulttype::Rigid3dTypes::Coord>("Rigid3d::Coord");
508+
PythonFactory::registerType<sofa::defaulttype::Rigid3fTypes::Coord>("Rigid3f::Coord");
509+
PythonFactory::registerType<sofa::defaulttype::Rigid3Types::Coord>("Rigid3::Coord");
510+
511+
/// Quaternion
512+
PythonFactory::registerType<sofa::type::Quat<double>>("Quatd");
513+
PythonFactory::registerType<sofa::type::Quat<float>>("Quatf");
514+
PythonFactory::registerType<sofa::type::Quat<SReal>>("Quat");
515+
516+
// Rigid3 vectors
507517
PythonFactory::registerType<sofa::defaulttype::Rigid3dTypes::VecCoord>("Rigid3d::VecCoord");
508518
PythonFactory::registerType<sofa::defaulttype::Rigid3fTypes::VecCoord>("Rigid3f::VecCoord");
509519
PythonFactory::registerType<sofa::defaulttype::Rigid3Types::VecCoord>("Rigid3::VecCoord");

bindings/Modules/src/SofaPython3/SofaConstraintSolver/Binding_ConstraintSolver_doc.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Returns the compliance matrix projected in constraint space, built in the constr
3434
example:
3535
------------
3636
37-
constraint_solver = root.addObject("ProjectedGaussSeidelConstraintSolver", tolerance=1e-9, maxIterations=1000)
37+
constraint_solver = root.addObject("BlockGaussSeidelConstraintSolver", tolerance=1e-9, maxIterations=1000)
3838
matrix = constraint_solver.W()
3939
)";
4040

@@ -45,7 +45,7 @@ Returns the force resulting from the constraints
4545
example:
4646
------------
4747
48-
constraint_solver = root.addObject("ProjectedGaussSeidelConstraintSolver", tolerance=1e-9, maxIterations=1000)
48+
constraint_solver = root.addObject("BlockGaussSeidelConstraintSolver", tolerance=1e-9, maxIterations=1000)
4949
lambda = constraint_solver.lambda_force()
5050
)";
5151

@@ -56,7 +56,7 @@ Returns the displacement computed without any constraint
5656
example:
5757
------------
5858
59-
constraint_solver = root.addObject("ProjectedGaussSeidelConstraintSolver", tolerance=1e-9, maxIterations=1000)
59+
constraint_solver = root.addObject("BlockGaussSeidelConstraintSolver", tolerance=1e-9, maxIterations=1000)
6060
dfree = constraint_solver.dfree()
6161
)";
6262

bindings/Modules/src/SofaPython3/SofaLinearSolver/Binding_LinearSolver.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void bindLinearSolvers(py::module &m)
6767

6868
c.def("A", [](CRSLinearSolver& self) -> EigenSparseMatrix
6969
{
70-
if (CRS* matrix = self.getSystemMatrix())
70+
if (CRS* matrix = self.l_linearSystem->getSystemMatrix())
7171
{
7272
return toEigen(*matrix);
7373
}
@@ -76,7 +76,7 @@ void bindLinearSolvers(py::module &m)
7676

7777
c.def("b", [](CRSLinearSolver& self) -> Vector
7878
{
79-
if (auto* vector = self.getSystemRHVector())
79+
if (auto* vector = self.l_linearSystem->getRHSVector())
8080
{
8181
return EigenVectorMap(vector->ptr(), vector->size());
8282
}
@@ -85,7 +85,7 @@ void bindLinearSolvers(py::module &m)
8585

8686
c.def("x", [](CRSLinearSolver& self) -> Vector
8787
{
88-
if (auto* vector = self.getSystemLHVector())
88+
if (auto* vector = self.l_linearSystem->getSolutionVector())
8989
{
9090
return EigenVectorMap(vector->ptr(), vector->size());
9191
}

bindings/Modules/src/SofaPython3/SofaLinearSystem/Binding_LinearSystem.cpp

Lines changed: 88 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,12 @@
1717
*******************************************************************************
1818
* Contact information: contact@sofa-framework.org *
1919
******************************************************************************/
20-
#include <SofaPython3/SofaLinearSystem/Binding_LinearSystem.h>
21-
#include <SofaPython3/SofaLinearSystem/Binding_LinearSystem_doc.h>
22-
#include <pybind11/pybind11.h>
20+
#include <SofaPython3/SofaLinearSystem/Binding_LinearSystem.inl>
2321

24-
#include <SofaPython3/Sofa/Core/Binding_Base.h>
25-
#include <SofaPython3/PythonFactory.h>
2622

27-
#include <sofa/component/linearsystem/TypedMatrixLinearSystem.h>
2823
#include <pybind11/eigen.h>
24+
#include <sofa/linearalgebra/BTDMatrix.h>
25+
#include <sofa/linearalgebra/BlockVector.h>
2926
#include <sofa/linearalgebra/CompressedRowSparseMatrix.h>
3027

3128

@@ -39,12 +36,6 @@ using EigenSparseMatrix = Eigen::SparseMatrix<Real, Eigen::RowMajor>;
3936
template<class Real>
4037
using EigenMatrixMap = Eigen::Map<Eigen::SparseMatrix<Real, Eigen::RowMajor> >;
4138

42-
template<class Real>
43-
using Vector = Eigen::Matrix<Real,Eigen::Dynamic, 1>;
44-
45-
template<class Real>
46-
using EigenVectorMap = Eigen::Map<Vector<Real>>;
47-
4839
template<class TBlock>
4940
EigenSparseMatrix<typename sofa::linearalgebra::CompressedRowSparseMatrix<TBlock>::Real>
5041
toEigen(sofa::linearalgebra::CompressedRowSparseMatrix<TBlock>& matrix)
@@ -70,62 +61,104 @@ toEigen(sofa::linearalgebra::CompressedRowSparseMatrix<TBlock>& matrix)
7061
}
7162
}
7263

73-
template<class TBlock>
74-
void bindLinearSystems(py::module &m)
64+
template<class TMatrix, class TVector>
65+
void bindMatrixAccessCRS(LinearSystemClass<TMatrix, TVector>& c)
7566
{
76-
using CRS = sofa::linearalgebra::CompressedRowSparseMatrix<TBlock>;
77-
using Real = typename CRS::Real;
78-
using CRSLinearSystem = sofa::component::linearsystem::TypedMatrixLinearSystem<CRS, sofa::linearalgebra::FullVector<Real> >;
67+
using Real = typename TMatrix::Real;
68+
using CRSLinearSystem = sofa::component::linearsystem::TypedMatrixLinearSystem<TMatrix, TVector>;
7969

80-
const std::string typeName = CRSLinearSystem::GetClass()->className + CRSLinearSystem::GetCustomTemplateName();
81-
82-
py::class_<CRSLinearSystem,
83-
sofa::core::objectmodel::BaseObject,
84-
sofapython3::py_shared_ptr<CRSLinearSystem> > c(m, typeName.c_str(), sofapython3::doc::linearsystem::linearSystemClass);
85-
86-
c.def("A", [](CRSLinearSystem& self) -> EigenSparseMatrix<Real>
87-
{
88-
if (CRS* matrix = self.getSystemMatrix())
70+
const auto matrixAccess =
71+
[](CRSLinearSystem& self) -> EigenSparseMatrix<Real>
8972
{
90-
if (matrix->colsValue.empty()) //null matrix: contains no entries
73+
if (TMatrix* matrix = self.getSystemMatrix())
9174
{
92-
return EigenSparseMatrix<Real>{matrix->rows(), matrix->cols()};
75+
if (matrix->colsValue.empty()) //null matrix: contains no entries
76+
{
77+
return EigenSparseMatrix<Real>{matrix->rows(), matrix->cols()};
78+
}
79+
return toEigen(*matrix);
9380
}
94-
return toEigen(*matrix);
95-
}
96-
return {};
97-
}, sofapython3::doc::linearsystem::linearSystem_A);
81+
return {};
82+
};
9883

99-
c.def("b", [](CRSLinearSystem& self) -> Vector<Real>
100-
{
101-
if (auto* vector = self.getRHSVector())
102-
{
103-
return EigenVectorMap<Real>(vector->ptr(), vector->size());
104-
}
105-
return {};
106-
}, sofapython3::doc::linearsystem::linearSystem_b);
84+
c.def("A", matrixAccess, sofapython3::doc::linearsystem::linearSystem_CRS_A);
85+
c.def("get_system_matrix", matrixAccess, sofapython3::doc::linearsystem::linearSystem_CRS_get_system_matrix);
86+
}
10787

108-
c.def("x", [](CRSLinearSystem& self) -> Vector<Real>
109-
{
110-
if (auto* vector = self.getSolutionVector())
111-
{
112-
return EigenVectorMap<Real>(vector->ptr(), vector->size());
113-
}
114-
return {};
115-
}, sofapython3::doc::linearsystem::linearSystem_x);
88+
template<>
89+
void bindMatrixAccess(LinearSystemClass<sofa::linearalgebra::CompressedRowSparseMatrix<SReal>, sofa::linearalgebra::FullVector<SReal>>& c)
90+
{
91+
bindMatrixAccessCRS(c);
92+
}
11693

94+
template<>
95+
void bindMatrixAccess(LinearSystemClass<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<2,2,SReal>>, sofa::linearalgebra::FullVector<SReal>>& c)
96+
{
97+
bindMatrixAccessCRS(c);
98+
}
11799

118-
/// register the binding in the downcasting subsystem
119-
PythonFactory::registerType<CRSLinearSystem>([](sofa::core::objectmodel::Base* object)
120-
{
121-
return py::cast(dynamic_cast<CRSLinearSystem*>(object));
122-
});
100+
template<>
101+
void bindMatrixAccess(LinearSystemClass<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<3,3,SReal>>, sofa::linearalgebra::FullVector<SReal>>& c)
102+
{
103+
bindMatrixAccessCRS(c);
104+
}
105+
106+
template<>
107+
void bindMatrixAccess(LinearSystemClass<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<4,4,SReal>>, sofa::linearalgebra::FullVector<SReal>>& c)
108+
{
109+
bindMatrixAccessCRS(c);
110+
}
111+
112+
template<>
113+
void bindMatrixAccess(LinearSystemClass<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<6,6,SReal>>, sofa::linearalgebra::FullVector<SReal>>& c)
114+
{
115+
bindMatrixAccessCRS(c);
116+
}
117+
118+
template<>
119+
void bindMatrixAccess(LinearSystemClass<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<8,8,SReal>>, sofa::linearalgebra::FullVector<SReal>>& c)
120+
{
121+
bindMatrixAccessCRS(c);
122+
}
123+
124+
template<class Real>
125+
using DenseMatrix = Eigen::Matrix<Real,Eigen::Dynamic, Eigen::Dynamic>;
126+
127+
template<class Real>
128+
using EigenDenseMatrixMap = Eigen::Map<DenseMatrix<Real>>;
129+
130+
template<>
131+
void bindMatrixAccess(LinearSystemClass<sofa::linearalgebra::FullMatrix<SReal>, sofa::linearalgebra::FullVector<SReal>>& c)
132+
{
133+
using CRSLinearSystem = sofa::component::linearsystem::TypedMatrixLinearSystem<sofa::linearalgebra::FullMatrix<SReal>, sofa::linearalgebra::FullVector<SReal>>;
134+
135+
const auto matrixAccess =
136+
[](CRSLinearSystem& self) -> EigenDenseMatrixMap<SReal>
137+
{
138+
sofa::linearalgebra::FullMatrix<SReal>* matrix = self.getSystemMatrix();
139+
const auto row = matrix ? matrix->rows() : 0;
140+
const auto col = matrix ? matrix->cols() : 0;
141+
return EigenDenseMatrixMap<SReal>(matrix ? matrix->ptr() : nullptr, row, col);
142+
};
143+
c.def("A", matrixAccess, sofapython3::doc::linearsystem::linearSystem_FullMatrix_A);
144+
c.def("get_system_matrix", matrixAccess, sofapython3::doc::linearsystem::linearSystem_FullMatrix_get_system_matrix);
123145
}
124146

125147
void moduleAddLinearSystem(py::module &m)
126148
{
127-
bindLinearSystems<SReal>(m);
128-
bindLinearSystems<sofa::type::Mat<3, 3, SReal> >(m);
149+
bindLinearSystems<sofa::linearalgebra::FullMatrix<SReal>, sofa::linearalgebra::FullVector<SReal> >(m);
150+
bindLinearSystems<sofa::linearalgebra::SparseMatrix<SReal>, sofa::linearalgebra::FullVector<SReal> >(m);
151+
bindLinearSystems<sofa::linearalgebra::CompressedRowSparseMatrix<SReal>, sofa::linearalgebra::FullVector<SReal> >(m);
152+
bindLinearSystems<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<2,2,SReal> >, sofa::linearalgebra::FullVector<SReal> >(m);
153+
bindLinearSystems<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<3,3,SReal> >, sofa::linearalgebra::FullVector<SReal> >(m);
154+
bindLinearSystems<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<4,4,SReal> >, sofa::linearalgebra::FullVector<SReal> >(m);
155+
bindLinearSystems<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<6,6,SReal> >, sofa::linearalgebra::FullVector<SReal> >(m);
156+
bindLinearSystems<sofa::linearalgebra::CompressedRowSparseMatrix<sofa::type::Mat<8,8,SReal> >, sofa::linearalgebra::FullVector<SReal> >(m);
157+
bindLinearSystems<sofa::linearalgebra::DiagonalMatrix<SReal>, sofa::linearalgebra::FullVector<SReal> >(m);
158+
bindLinearSystems<sofa::linearalgebra::BlockDiagonalMatrix<3,SReal>, sofa::linearalgebra::FullVector<SReal> >(m);
159+
bindLinearSystems<sofa::linearalgebra::RotationMatrix<SReal>, sofa::linearalgebra::FullVector<SReal> >(m);
160+
161+
bindLinearSystems<sofa::linearalgebra::BTDMatrix<6, SReal>, sofa::linearalgebra::BlockVector<6, SReal> >(m);
129162
}
130163

131164
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/******************************************************************************
2+
* SofaPython3 plugin *
3+
* (c) 2021 CNRS, University of Lille, INRIA *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify it *
6+
* under the terms of the GNU Lesser General Public License as published by *
7+
* the Free Software Foundation; either version 2.1 of the License, or (at *
8+
* your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, but WITHOUT *
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13+
* for more details. *
14+
* *
15+
* You should have received a copy of the GNU Lesser General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*******************************************************************************
18+
* Contact information: contact@sofa-framework.org *
19+
******************************************************************************/
20+
#pragma once
21+
#include <SofaPython3/SofaLinearSystem/Binding_LinearSystem.h>
22+
#include <SofaPython3/SofaLinearSystem/Binding_LinearSystem_doc.h>
23+
#include <sofa/component/linearsystem/TypedMatrixLinearSystem.h>
24+
#include <pybind11/pybind11.h>
25+
26+
#include <SofaPython3/PythonFactory.h>
27+
#include <SofaPython3/Sofa/Core/Binding_Base.h>
28+
#include <sofa/linearalgebra/EigenSparseMatrix.h>
29+
30+
namespace py { using namespace pybind11; }
31+
32+
namespace sofapython3
33+
{
34+
35+
template<class Real>
36+
using Vector = Eigen::Matrix<Real,Eigen::Dynamic, 1>;
37+
38+
template<class Real>
39+
using EigenVectorMap = Eigen::Map<Vector<Real>>;
40+
41+
template<class TVector>
42+
Vector<typename TVector::Real>
43+
getVector(TVector* vector)
44+
{
45+
using Real = typename TVector::Real;
46+
if (vector)
47+
{
48+
return EigenVectorMap<Real>(vector->ptr(), vector->size());
49+
}
50+
return {};
51+
}
52+
53+
template<class TMatrix, class TVector>
54+
Vector<typename TVector::Real> getRHSVector(sofa::component::linearsystem::TypedMatrixLinearSystem<TMatrix, TVector>& linearSystem)
55+
{
56+
return getVector(linearSystem.getRHSVector());
57+
}
58+
59+
template<class TMatrix, class TVector>
60+
Vector<typename TVector::Real> getSolutionVector(sofa::component::linearsystem::TypedMatrixLinearSystem<TMatrix, TVector>& linearSystem)
61+
{
62+
return getVector(linearSystem.getSolutionVector());
63+
}
64+
65+
template<class TMatrix, class TVector>
66+
using LinearSystemClass =
67+
py::class_<sofa::component::linearsystem::TypedMatrixLinearSystem<TMatrix, TVector>,
68+
sofa::core::objectmodel::BaseObject,
69+
sofapython3::py_shared_ptr<sofa::component::linearsystem::TypedMatrixLinearSystem<TMatrix, TVector>> >;
70+
71+
template<class TMatrix, class TVector>
72+
void bindMatrixAccess(LinearSystemClass<TMatrix, TVector>& c)
73+
{}
74+
75+
template<class TMatrix, class TVector>
76+
void bindLinearSystems(py::module &m)
77+
{
78+
using LinearSystem = sofa::component::linearsystem::TypedMatrixLinearSystem<TMatrix, TVector>;
79+
80+
const std::string typeName =
81+
LinearSystem::GetClass()->className
82+
+ LinearSystem::GetCustomTemplateName();
83+
84+
LinearSystemClass<TMatrix, TVector> c(m, typeName.c_str(), sofapython3::doc::linearsystem::linearSystemClass);
85+
86+
c.def("b", getRHSVector<TMatrix, TVector>, sofapython3::doc::linearsystem::linearSystem_b);
87+
c.def("get_rhs_vector", getRHSVector<TMatrix, TVector>, sofapython3::doc::linearsystem::linearSystem_b);
88+
89+
c.def("x", getSolutionVector<TMatrix, TVector>, sofapython3::doc::linearsystem::linearSystem_x);
90+
c.def("get_solution_vector", getSolutionVector<TMatrix, TVector>, sofapython3::doc::linearsystem::linearSystem_x);
91+
92+
bindMatrixAccess<TMatrix, TVector>(c);
93+
94+
/// register the binding in the downcasting subsystem
95+
PythonFactory::registerType<LinearSystem>([](sofa::core::objectmodel::Base* object)
96+
{
97+
return py::cast(dynamic_cast<LinearSystem*>(object));
98+
});
99+
}
100+
101+
}

0 commit comments

Comments
 (0)