Skip to content

Commit cfe3ebc

Browse files
committed
[Bindings] Add MultiVecId bindings
Signed-off-by: Jean-Nicolas Brunet <[email protected]>
1 parent d05cd30 commit cfe3ebc

File tree

6 files changed

+196
-0
lines changed

6 files changed

+196
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
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: [email protected] *
19+
******************************************************************************/
20+
21+
#include <SofaPython3/Sofa/Core/Binding_MultiVecId.h>
22+
#include <sofa/core/MultiVecId.h>
23+
#include <sofa/core/BaseState.h>
24+
25+
namespace py { using namespace pybind11; }
26+
using namespace sofa::core;
27+
28+
namespace sofapython3 {
29+
30+
template <VecType vtype, VecAccess vaccess>
31+
void bindMultiVecId(py::module& m, const std::string & name) {
32+
using MultiVecId = TMultiVecId<vtype, vaccess>;
33+
py::class_<MultiVecId> c (m, name.c_str());
34+
35+
// Constructors
36+
c.def(py::init());
37+
38+
// Read-only can be constructed from both read-only and read-write multi vectors
39+
if constexpr (vaccess == V_READ) {
40+
41+
c.def(py::init<const TVecId<vtype, V_WRITE> &>());
42+
py::implicitly_convertible<TVecId<vtype, V_WRITE>, TMultiVecId<vtype, vaccess>>();
43+
44+
c.def(py::init<const TMultiVecId<vtype, V_WRITE> &>());
45+
py::implicitly_convertible<TMultiVecId<vtype, V_WRITE>, TMultiVecId<vtype, vaccess>>();
46+
47+
if constexpr(vtype != V_ALL) {
48+
c.def(py::init<const TMultiVecId<V_ALL, V_WRITE> &>());
49+
py::implicitly_convertible<TMultiVecId<V_ALL, V_WRITE>, TMultiVecId<vtype, vaccess>>();
50+
} else {
51+
c.def(py::init<const TMultiVecId<V_COORD, V_WRITE> &>());
52+
py::implicitly_convertible<TMultiVecId<V_COORD, V_WRITE>, TMultiVecId<vtype, vaccess>>();
53+
54+
c.def(py::init<const TMultiVecId<V_DERIV, V_WRITE> &>());
55+
py::implicitly_convertible<TMultiVecId<V_DERIV, V_WRITE>, TMultiVecId<vtype, vaccess>>();
56+
57+
c.def(py::init<const TMultiVecId<V_MATDERIV, V_WRITE> &>());
58+
py::implicitly_convertible<TMultiVecId<V_MATDERIV, V_WRITE>, TMultiVecId<vtype, vaccess>>();
59+
60+
c.def(py::init<const TVecId<V_COORD, V_WRITE> &>());
61+
py::implicitly_convertible<TVecId<V_COORD, V_WRITE>, TMultiVecId<vtype, vaccess>>();
62+
63+
c.def(py::init<const TVecId<V_DERIV, V_WRITE> &>());
64+
py::implicitly_convertible<TVecId<V_DERIV, V_WRITE>, TMultiVecId<vtype, vaccess>>();
65+
66+
c.def(py::init<const TVecId<V_MATDERIV, V_WRITE> &>());
67+
py::implicitly_convertible<TVecId<V_MATDERIV, V_WRITE>, TMultiVecId<vtype, vaccess>>();
68+
}
69+
}
70+
71+
// Construct from the same access type
72+
c.def(py::init<const TVecId<vtype, vaccess>&>());
73+
py::implicitly_convertible<TVecId<vtype, vaccess>, TMultiVecId<vtype, vaccess>>();
74+
75+
c.def(py::init<const TMultiVecId<vtype, vaccess>&>());
76+
77+
// Construct from a ALL vector type
78+
if constexpr(vtype != V_ALL) {
79+
c.def(py::init<const TMultiVecId<V_ALL, vaccess> &>());
80+
py::implicitly_convertible<TMultiVecId<V_ALL, vaccess>, TMultiVecId<vtype, vaccess>>();
81+
} else {
82+
c.def(py::init<const TVecId<V_COORD, vaccess> &>());
83+
py::implicitly_convertible<TVecId<V_COORD, vaccess>, TMultiVecId<vtype, vaccess>>();
84+
85+
c.def(py::init<const TMultiVecId<V_COORD, vaccess> &>());
86+
py::implicitly_convertible<TMultiVecId<V_COORD, vaccess>, TMultiVecId<vtype, vaccess>>();
87+
88+
c.def(py::init<const TVecId<V_DERIV, vaccess> &>());
89+
py::implicitly_convertible<TVecId<V_DERIV, vaccess>, TMultiVecId<vtype, vaccess>>();
90+
91+
c.def(py::init<const TMultiVecId<V_DERIV, vaccess> &>());
92+
py::implicitly_convertible<TMultiVecId<V_DERIV, vaccess>, TMultiVecId<vtype, vaccess>>();
93+
94+
c.def(py::init<const TVecId<V_MATDERIV, vaccess> &>());
95+
py::implicitly_convertible<TVecId<V_MATDERIV, vaccess>, TMultiVecId<vtype, vaccess>>();
96+
97+
c.def(py::init<const TMultiVecId<V_MATDERIV, vaccess> &>());
98+
py::implicitly_convertible<TMultiVecId<V_MATDERIV, vaccess>, TMultiVecId<vtype, vaccess>>();
99+
}
100+
101+
// Public methods/properties
102+
c.def_property_readonly("defaultId", &MultiVecId::getDefaultId);
103+
c.def("getDefaultId", &MultiVecId::getDefaultId);
104+
105+
c.def("getName", &MultiVecId::getName);
106+
c.def("isNull", &MultiVecId::isNull);
107+
c.def("__str__", &MultiVecId::getName);
108+
c.def("getId", &MultiVecId::getId, py::arg("state"));
109+
110+
// Static methods/properties
111+
c.def_static("null", &MultiVecId::null);
112+
}
113+
114+
void moduleAddMultiVecId(py::module& m) {
115+
bindMultiVecId<V_ALL, V_READ> (m, "ConstMultiVecId");
116+
bindMultiVecId<V_ALL, V_WRITE> (m, "MultiVecId");
117+
bindMultiVecId<V_COORD, V_READ> (m, "ConstMultiVecCoordId");
118+
bindMultiVecId<V_COORD, V_WRITE> (m, "MultiVecCoordId");
119+
bindMultiVecId<V_DERIV, V_READ> (m, "ConstMultiVecDerivId");
120+
bindMultiVecId<V_DERIV, V_WRITE> (m, "MultiVecDerivId");
121+
bindMultiVecId<V_MATDERIV, V_READ> (m, "ConstMultiMatrixDerivId");
122+
bindMultiVecId<V_MATDERIV, V_WRITE> (m, "MultiMatrixDerivId");
123+
}
124+
125+
} // namespace sofapython3
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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: [email protected] *
19+
******************************************************************************/
20+
21+
#pragma once
22+
#include <pybind11/pybind11.h>
23+
24+
namespace sofapython3 {
25+
26+
void moduleAddMultiVecId(pybind11::module &m);
27+
28+
} /// namespace sofapython3

bindings/Sofa/src/SofaPython3/Sofa/Core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(HEADER_FILES
2424
${CMAKE_CURRENT_SOURCE_DIR}/Binding_ObjectFactory_doc.h
2525
${CMAKE_CURRENT_SOURCE_DIR}/Binding_MechanicalParams.h
2626
${CMAKE_CURRENT_SOURCE_DIR}/Binding_MechanicalParams_doc.h
27+
${CMAKE_CURRENT_SOURCE_DIR}/Binding_MultiVecId.h
2728
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Node.h
2829
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Node_doc.h
2930
${CMAKE_CURRENT_SOURCE_DIR}/Binding_NodeIterator.h
@@ -65,6 +66,7 @@ set(SOURCE_FILES
6566
${CMAKE_CURRENT_SOURCE_DIR}/Binding_ForceField.cpp
6667
${CMAKE_CURRENT_SOURCE_DIR}/Binding_ObjectFactory.cpp
6768
${CMAKE_CURRENT_SOURCE_DIR}/Binding_MechanicalParams.cpp
69+
${CMAKE_CURRENT_SOURCE_DIR}/Binding_MultiVecId.cpp
6870
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Node.cpp
6971
${CMAKE_CURRENT_SOURCE_DIR}/Binding_NodeIterator.cpp
7072
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Prefab.cpp

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ using sofa::helper::logging::Message;
3636
#include <SofaPython3/Sofa/Core/Binding_DataEngine.h>
3737
#include <SofaPython3/Sofa/Core/Binding_ObjectFactory.h>
3838
#include <SofaPython3/Sofa/Core/Binding_MechanicalParams.h>
39+
#include <SofaPython3/Sofa/Core/Binding_MultiVecId.h>
3940
#include <SofaPython3/Sofa/Core/Binding_Node.h>
4041
#include <SofaPython3/Sofa/Core/Binding_NodeIterator.h>
4142
#include <SofaPython3/Sofa/Core/Binding_Prefab.h>
@@ -137,6 +138,7 @@ PYBIND11_MODULE(Core, core)
137138
moduleAddForceField(core);
138139
moduleAddObjectFactory(core);
139140
moduleAddMechanicalParams(core);
141+
moduleAddMultiVecId(core);
140142
moduleAddNode(core);
141143
moduleAddNodeIterator(core);
142144
moduleAddPrefab(core);

bindings/Sofa/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ set(PYTHON_FILES
1919
${CMAKE_CURRENT_SOURCE_DIR}/Core/DataEngine.py
2020
${CMAKE_CURRENT_SOURCE_DIR}/Core/MyRestShapeForceField.py
2121
${CMAKE_CURRENT_SOURCE_DIR}/Core/MechanicalParams.py
22+
${CMAKE_CURRENT_SOURCE_DIR}/Core/MultiVecId.py
2223
${CMAKE_CURRENT_SOURCE_DIR}/Core/PythonRestShapeForceField.py
2324
${CMAKE_CURRENT_SOURCE_DIR}/Core/BaseLink.py
2425
${CMAKE_CURRENT_SOURCE_DIR}/Core/VecId.py
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import Sofa
2+
import unittest
3+
4+
5+
class MultiVecId(unittest.TestCase):
6+
"""
7+
Test the creation of MultiVecId
8+
9+
Note that this test case will not test the allocation inside mechanical object. This is instead tested inside
10+
the vector operations (Sofa.SimulationCore.VectorOperations) test case.
11+
"""
12+
def test_coord(self):
13+
# Const Coord
14+
vec = Sofa.Core.ConstMultiVecCoordId()
15+
self.assertEqual(vec.defaultId.index, 0)
16+
self.assertEqual(vec.getDefaultId().getIndex(), 0)
17+
self.assertEqual(vec.defaultId.type, Sofa.Core.VecType.V_COORD)
18+
19+
vec = Sofa.Core.ConstMultiVecCoordId(Sofa.Core.ConstVecCoordId(15))
20+
self.assertEqual(vec.defaultId.index, 15)
21+
self.assertEqual(vec.getDefaultId().getIndex(), 15)
22+
self.assertEqual(vec.defaultId.type, Sofa.Core.VecType.V_COORD)
23+
24+
vec = Sofa.Core.ConstMultiVecCoordId(Sofa.Core.VecCoordId(15))
25+
self.assertEqual(vec.defaultId.index, 15)
26+
self.assertEqual(vec.getDefaultId().getIndex(), 15)
27+
self.assertEqual(vec.defaultId.type, Sofa.Core.VecType.V_COORD)
28+
29+
# Coord
30+
vec = Sofa.Core.MultiVecCoordId()
31+
self.assertEqual(vec.defaultId.index, 0)
32+
self.assertEqual(vec.getDefaultId().getIndex(), 0)
33+
self.assertEqual(vec.defaultId.type, Sofa.Core.VecType.V_COORD)
34+
35+
vec = Sofa.Core.MultiVecCoordId(Sofa.Core.VecCoordId(15))
36+
self.assertEqual(vec.defaultId.index, 15)
37+
self.assertEqual(vec.getDefaultId().getIndex(), 15)
38+
self.assertEqual(vec.defaultId.type, Sofa.Core.VecType.V_COORD)

0 commit comments

Comments
 (0)