Skip to content

Commit d05cd30

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

File tree

6 files changed

+289
-0
lines changed

6 files changed

+289
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
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_VecId.h>
22+
#include <sofa/core/VecId.h>
23+
24+
namespace py { using namespace pybind11; }
25+
using namespace sofa::core;
26+
27+
namespace sofapython3 {
28+
29+
template <VecType vtype, VecAccess vaccess>
30+
void bindVecId(py::module& m, const std::string & name) {
31+
32+
using StandardVec = TStandardVec<vtype, vaccess>;
33+
py::class_<StandardVec> s (m, ("Standard"+name).c_str());
34+
if constexpr (vtype == VecType::V_COORD || vtype == VecType::V_ALL) {
35+
s.def_static("position", &StandardVec::position);
36+
s.def_static("restPosition", &StandardVec::restPosition);
37+
s.def_static("freePosition", &StandardVec::freePosition);
38+
s.def_static("resetPosition", &StandardVec::resetPosition);
39+
}
40+
if constexpr (vtype == VecType::V_DERIV || vtype == VecType::V_ALL) {
41+
s.def_static("velocity", &StandardVec::velocity);
42+
s.def_static("resetVelocity", &StandardVec::resetVelocity);
43+
s.def_static("freeVelocity", &StandardVec::freeVelocity);
44+
s.def_static("normal", &StandardVec::normal);
45+
s.def_static("force", &StandardVec::force);
46+
s.def_static("externalForce", &StandardVec::externalForce);
47+
s.def_static("dx", &StandardVec::dx);
48+
s.def_static("dforce", &StandardVec::dforce);
49+
}
50+
if constexpr(vtype == VecType::V_MATDERIV || vtype == VecType::V_ALL) {
51+
s.def_static("constraintJacobian", &StandardVec::constraintJacobian);
52+
s.def_static("mappingJacobian", &StandardVec::mappingJacobian);
53+
}
54+
55+
if constexpr (vtype == VecType::V_ALL) {
56+
s.def_static("getFirstDynamicIndex", &StandardVec::getFirstDynamicIndex, py::arg("t"));
57+
}
58+
59+
using VecId = TVecId<vtype, vaccess>;
60+
py::class_<VecId, StandardVec, BaseVecId> v (m, name.c_str());
61+
v.def(py::init());
62+
if constexpr (vtype != V_ALL) {
63+
py::implicitly_convertible<TVecId<vtype, vaccess>, TVecId<V_ALL, vaccess>>();
64+
v.def(py::init<unsigned int>());
65+
}
66+
v.def("getName", &VecId::getName);
67+
v.def("__str__", &VecId::getName);
68+
}
69+
70+
void moduleAddVecId(py::module& m) {
71+
72+
// VecType
73+
py::enum_<VecType> (m, "VecType")
74+
.value("V_ALL", VecType::V_ALL)
75+
.value("V_COORD", VecType::V_COORD)
76+
.value("V_DERIV", VecType::V_DERIV)
77+
.value("V_MATDERIV", VecType::V_MATDERIV)
78+
.export_values()
79+
;
80+
81+
// VecAccess
82+
py::enum_<VecAccess> (m, "VecAccess")
83+
.value("V_READ", VecAccess::V_READ)
84+
.value("V_WRITE", VecAccess::V_WRITE)
85+
.export_values()
86+
;
87+
88+
// BaseVecId
89+
py::class_<BaseVecId> (m, "BaseVecId")
90+
.def_property_readonly("index", &BaseVecId::getIndex)
91+
.def("getIndex", &BaseVecId::getIndex)
92+
.def_property_readonly("type", &BaseVecId::getType)
93+
.def("getType", &BaseVecId::getType)
94+
;
95+
96+
// VecId
97+
bindVecId<V_ALL, V_READ> (m, "ConstVecId");
98+
bindVecId<V_ALL, V_WRITE> (m, "VecId");
99+
bindVecId<V_COORD, V_READ> (m, "ConstVecCoordId");
100+
bindVecId<V_COORD, V_WRITE>(m, "VecCoordId");
101+
bindVecId<V_DERIV, V_READ> (m, "ConstVecDerivId");
102+
bindVecId<V_DERIV, V_WRITE>(m, "VecDerivId");
103+
bindVecId<V_MATDERIV, V_READ> (m, "ConstMatrixDerivId");
104+
bindVecId<V_MATDERIV, V_WRITE>(m, "MatrixDerivId");
105+
}
106+
107+
} // 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 moduleAddVecId(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
@@ -42,6 +42,7 @@ set(HEADER_FILES
4242
${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseData_doc.h
4343
${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseCamera_doc.h
4444
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Topology.h
45+
${CMAKE_CURRENT_SOURCE_DIR}/Binding_VecId.h
4546
${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseMeshTopology.h
4647
)
4748

@@ -71,6 +72,7 @@ set(SOURCE_FILES
7172
${CMAKE_CURRENT_SOURCE_DIR}/Binding_PythonScriptEvent.cpp
7273
${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseLink.cpp
7374
${CMAKE_CURRENT_SOURCE_DIR}/Binding_Topology.cpp
75+
${CMAKE_CURRENT_SOURCE_DIR}/Binding_VecId.cpp
7476
${CMAKE_CURRENT_SOURCE_DIR}/Binding_BaseMeshTopology.cpp
7577
)
7678

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ using sofa::helper::logging::Message;
4242
#include <SofaPython3/Sofa/Core/Binding_BaseLink.h>
4343
#include <SofaPython3/Sofa/Core/Binding_PythonScriptEvent.h>
4444
#include <SofaPython3/Sofa/Core/Binding_Topology.h>
45+
#include <SofaPython3/Sofa/Core/Binding_VecId.h>
4546
#include <SofaPython3/Sofa/Core/Binding_BaseMeshTopology.h>
4647

4748
#include <SofaPython3/Sofa/Core/Data/Binding_DataString.h>
@@ -141,6 +142,7 @@ PYBIND11_MODULE(Core, core)
141142
moduleAddPrefab(core);
142143
moduleAddBaseLink(core);
143144
moduleAddTopology(core);
145+
moduleAddVecId(core);
144146
moduleAddBaseMeshTopology(core);
145147
}
146148

bindings/Sofa/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ set(PYTHON_FILES
2121
${CMAKE_CURRENT_SOURCE_DIR}/Core/MechanicalParams.py
2222
${CMAKE_CURRENT_SOURCE_DIR}/Core/PythonRestShapeForceField.py
2323
${CMAKE_CURRENT_SOURCE_DIR}/Core/BaseLink.py
24+
${CMAKE_CURRENT_SOURCE_DIR}/Core/VecId.py
2425
${CMAKE_CURRENT_SOURCE_DIR}/Helper/Message.py
2526
${CMAKE_CURRENT_SOURCE_DIR}/Types/RGBAColor.py
2627
${CMAKE_CURRENT_SOURCE_DIR}/Types/Vec3.py

bindings/Sofa/tests/Core/VecId.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import Sofa
2+
import unittest
3+
4+
5+
class VecId(unittest.TestCase):
6+
def test_coord(self):
7+
# Const Coord
8+
vec = Sofa.Core.ConstVecCoordId()
9+
self.assertEqual(vec.index, 0)
10+
self.assertEqual(vec.getIndex(), 0)
11+
self.assertEqual(vec.type, Sofa.Core.VecType.V_COORD)
12+
13+
vec = Sofa.Core.ConstVecCoordId(15)
14+
self.assertEqual(vec.index, 15)
15+
self.assertEqual(vec.getIndex(), 15)
16+
self.assertEqual(vec.type, Sofa.Core.VecType.V_COORD)
17+
18+
# Coord
19+
vec = Sofa.Core.VecCoordId()
20+
self.assertEqual(vec.index, 0)
21+
self.assertEqual(vec.getIndex(), 0)
22+
self.assertEqual(vec.type, Sofa.Core.VecType.V_COORD)
23+
24+
vec = Sofa.Core.VecCoordId(15)
25+
self.assertEqual(vec.index, 15)
26+
self.assertEqual(vec.getIndex(), 15)
27+
self.assertEqual(vec.type, Sofa.Core.VecType.V_COORD)
28+
29+
def test_deriv(self):
30+
# Const Deriv
31+
vec = Sofa.Core.ConstVecDerivId()
32+
self.assertEqual(vec.index, 0)
33+
self.assertEqual(vec.getIndex(), 0)
34+
self.assertEqual(vec.type, Sofa.Core.VecType.V_DERIV)
35+
36+
vec = Sofa.Core.ConstVecDerivId(15)
37+
self.assertEqual(vec.index, 15)
38+
self.assertEqual(vec.getIndex(), 15)
39+
self.assertEqual(vec.type, Sofa.Core.VecType.V_DERIV)
40+
41+
# Deriv
42+
vec = Sofa.Core.VecDerivId()
43+
self.assertEqual(vec.index, 0)
44+
self.assertEqual(vec.getIndex(), 0)
45+
self.assertEqual(vec.type, Sofa.Core.VecType.V_DERIV)
46+
47+
vec = Sofa.Core.VecDerivId(15)
48+
self.assertEqual(vec.index, 15)
49+
self.assertEqual(vec.getIndex(), 15)
50+
self.assertEqual(vec.type, Sofa.Core.VecType.V_DERIV)
51+
52+
def test_default_coord_vectors(self):
53+
# Position
54+
self.assertEqual(Sofa.Core.VecCoordId.position().index, 1)
55+
self.assertEqual(Sofa.Core.VecCoordId.position().getName(), "position(V_COORD)")
56+
self.assertEqual(Sofa.Core.ConstVecCoordId.position().index, 1)
57+
self.assertEqual(Sofa.Core.ConstVecCoordId.position().getName(), "position(V_COORD)")
58+
59+
# restPosition
60+
self.assertEqual(Sofa.Core.VecCoordId.restPosition().index, 2)
61+
self.assertEqual(Sofa.Core.VecCoordId.restPosition().getName(), "restPosition(V_COORD)")
62+
self.assertEqual(Sofa.Core.ConstVecCoordId.restPosition().index, 2)
63+
self.assertEqual(Sofa.Core.ConstVecCoordId.restPosition().getName(), "restPosition(V_COORD)")
64+
65+
# freePosition
66+
self.assertEqual(Sofa.Core.VecCoordId.freePosition().index, 3)
67+
self.assertEqual(Sofa.Core.VecCoordId.freePosition().getName(), "freePosition(V_COORD)")
68+
self.assertEqual(Sofa.Core.ConstVecCoordId.freePosition().index, 3)
69+
self.assertEqual(Sofa.Core.ConstVecCoordId.freePosition().getName(), "freePosition(V_COORD)")
70+
71+
# resetPosition
72+
self.assertEqual(Sofa.Core.VecCoordId.resetPosition().index, 4)
73+
self.assertEqual(Sofa.Core.VecCoordId.resetPosition().getName(), "resetPosition(V_COORD)")
74+
self.assertEqual(Sofa.Core.ConstVecCoordId.resetPosition().index, 4)
75+
self.assertEqual(Sofa.Core.ConstVecCoordId.resetPosition().getName(), "resetPosition(V_COORD)")
76+
77+
# Dynamic offset
78+
self.assertEqual(Sofa.Core.VecId.getFirstDynamicIndex(Sofa.Core.VecType.V_COORD), 5)
79+
self.assertEqual(Sofa.Core.ConstVecId.getFirstDynamicIndex(Sofa.Core.VecType.V_COORD), 5)
80+
81+
def test_default_deriv_vectors(self):
82+
# velocity
83+
self.assertEqual(Sofa.Core.VecDerivId.velocity().index, 1)
84+
self.assertEqual(Sofa.Core.VecDerivId.velocity().getName(), "velocity(V_DERIV)")
85+
self.assertEqual(Sofa.Core.ConstVecDerivId.velocity().index, 1)
86+
self.assertEqual(Sofa.Core.ConstVecDerivId.velocity().getName(), "velocity(V_DERIV)")
87+
88+
# resetVelocity
89+
self.assertEqual(Sofa.Core.VecDerivId.resetVelocity().index, 2)
90+
self.assertEqual(Sofa.Core.VecDerivId.resetVelocity().getName(), "resetVelocity(V_DERIV)")
91+
self.assertEqual(Sofa.Core.ConstVecDerivId.resetVelocity().index, 2)
92+
self.assertEqual(Sofa.Core.ConstVecDerivId.resetVelocity().getName(), "resetVelocity(V_DERIV)")
93+
94+
# freeVelocity
95+
self.assertEqual(Sofa.Core.VecDerivId.freeVelocity().index, 3)
96+
self.assertEqual(Sofa.Core.VecDerivId.freeVelocity().getName(), "freeVelocity(V_DERIV)")
97+
self.assertEqual(Sofa.Core.ConstVecDerivId.freeVelocity().index, 3)
98+
self.assertEqual(Sofa.Core.ConstVecDerivId.freeVelocity().getName(), "freeVelocity(V_DERIV)")
99+
100+
# normal
101+
self.assertEqual(Sofa.Core.VecDerivId.normal().index, 4)
102+
self.assertEqual(Sofa.Core.VecDerivId.normal().getName(), "normal(V_DERIV)")
103+
self.assertEqual(Sofa.Core.ConstVecDerivId.normal().index, 4)
104+
self.assertEqual(Sofa.Core.ConstVecDerivId.normal().getName(), "normal(V_DERIV)")
105+
106+
# force
107+
self.assertEqual(Sofa.Core.VecDerivId.force().index, 5)
108+
self.assertEqual(Sofa.Core.VecDerivId.force().getName(), "force(V_DERIV)")
109+
self.assertEqual(Sofa.Core.ConstVecDerivId.force().index, 5)
110+
self.assertEqual(Sofa.Core.ConstVecDerivId.force().getName(), "force(V_DERIV)")
111+
112+
# externalForce
113+
self.assertEqual(Sofa.Core.VecDerivId.externalForce().index, 6)
114+
self.assertEqual(Sofa.Core.VecDerivId.externalForce().getName(), "externalForce(V_DERIV)")
115+
self.assertEqual(Sofa.Core.ConstVecDerivId.externalForce().index, 6)
116+
self.assertEqual(Sofa.Core.ConstVecDerivId.externalForce().getName(), "externalForce(V_DERIV)")
117+
118+
# dx
119+
self.assertEqual(Sofa.Core.VecDerivId.dx().index, 7)
120+
self.assertEqual(Sofa.Core.VecDerivId.dx().getName(), "dx(V_DERIV)")
121+
self.assertEqual(Sofa.Core.ConstVecDerivId.dx().index, 7)
122+
self.assertEqual(Sofa.Core.ConstVecDerivId.dx().getName(), "dx(V_DERIV)")
123+
124+
# dforce
125+
self.assertEqual(Sofa.Core.VecDerivId.dforce().index, 8)
126+
self.assertEqual(Sofa.Core.VecDerivId.dforce().getName(), "dforce(V_DERIV)")
127+
self.assertEqual(Sofa.Core.ConstVecDerivId.dforce().index, 8)
128+
self.assertEqual(Sofa.Core.ConstVecDerivId.dforce().getName(), "dforce(V_DERIV)")
129+
130+
# Dynamic offset
131+
self.assertEqual(Sofa.Core.VecId.getFirstDynamicIndex(Sofa.Core.VecType.V_DERIV), 9)
132+
self.assertEqual(Sofa.Core.ConstVecId.getFirstDynamicIndex(Sofa.Core.VecType.V_DERIV), 9)
133+
134+
def test_default_matderiv_vectors(self):
135+
# constraintJacobian
136+
self.assertEqual(Sofa.Core.MatrixDerivId.constraintJacobian().index, 1)
137+
self.assertEqual(Sofa.Core.MatrixDerivId.constraintJacobian().getName(), "holonomic(V_MATDERIV)")
138+
self.assertEqual(Sofa.Core.ConstMatrixDerivId.constraintJacobian().index, 1)
139+
self.assertEqual(Sofa.Core.ConstMatrixDerivId.constraintJacobian().getName(), "holonomic(V_MATDERIV)")
140+
141+
# mappingJacobian
142+
self.assertEqual(Sofa.Core.MatrixDerivId.mappingJacobian().index, 2)
143+
self.assertEqual(Sofa.Core.MatrixDerivId.mappingJacobian().getName(), "nonHolonomic(V_MATDERIV)")
144+
self.assertEqual(Sofa.Core.ConstMatrixDerivId.mappingJacobian().index, 2)
145+
self.assertEqual(Sofa.Core.ConstMatrixDerivId.mappingJacobian().getName(), "nonHolonomic(V_MATDERIV)")
146+
147+
# Dynamic offset
148+
self.assertEqual(Sofa.Core.VecId.getFirstDynamicIndex(Sofa.Core.VecType.V_MATDERIV), 3)
149+
self.assertEqual(Sofa.Core.ConstVecId.getFirstDynamicIndex(Sofa.Core.VecType.V_MATDERIV), 3)

0 commit comments

Comments
 (0)