Skip to content

Commit 569d86e

Browse files
Merge pull request #259 from alxbilger/springforcefield
Add bindings for all data types supported by SpringForceField + example
2 parents 33070ab + 1aed9bd commit 569d86e

2 files changed

Lines changed: 67 additions & 3 deletions

File tree

bindings/Modules/src/SofaPython3/SofaDeformable/Binding_SpringForceField.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,13 @@ void bindSpringForcefield(py::module& m) {
101101
});
102102
}
103103

104-
void moduleAddSpringForceField(py::module& m) {
105-
bindSpringForcefield<sofa::defaulttype::Vec3dTypes>(m);
106-
bindSpringForcefield<sofa::defaulttype::Vec6dTypes>(m);
104+
void moduleAddSpringForceField(py::module& m)
105+
{
106+
bindSpringForcefield<sofa::defaulttype::Vec3Types>(m);
107+
bindSpringForcefield<sofa::defaulttype::Vec2Types>(m);
108+
bindSpringForcefield<sofa::defaulttype::Vec1Types>(m);
109+
bindSpringForcefield<sofa::defaulttype::Vec6Types>(m);
110+
bindSpringForcefield<sofa::defaulttype::Rigid3Types>(m);
107111
}
112+
108113
} // namespace sofapython3

examples/springForceField.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import Sofa
2+
import SofaRuntime
3+
from Sofa import SofaDeformable
4+
5+
6+
def createScene(root):
7+
root.gravity = [0, -9.81, 0]
8+
9+
root.addObject('DefaultAnimationLoop')
10+
root.addObject('DefaultVisualManagerLoop')
11+
12+
surface_node = root.addChild('Surface')
13+
surface_loader = surface_node.addObject('MeshOBJLoader', name='surface_loader', filename='mesh/ball.obj')
14+
15+
root.addObject('EulerImplicitSolver', name='ODE', rayleighStiffness=0.1, rayleighMass=0.1)
16+
root.addObject('CGLinearSolver', name='linear solver', iterations=25, tolerance=1e-08, threshold=1e-08)
17+
18+
ball_0 = add_ball(root, 'ball_0', (-2, 0, 0), surface_loader)
19+
ball_1 = add_ball(root, 'ball_1', (2, 0, 0), surface_loader)
20+
21+
ball_0.addObject('RestShapeSpringsForceField', name='rest_spring', stiffness=1e1, angularStiffness=1e03)
22+
springs = root.addObject('StiffSpringForceField',
23+
object1=ball_0.dofs.getLinkPath(), object2=ball_1.dofs.getLinkPath(),
24+
indices1=[0], indices2=[0],
25+
length=[4], stiffness=2)
26+
27+
root.addObject(KeyPressedController(name='controller', springs=springs))
28+
29+
floor = root.addChild('Floor')
30+
floor_loader = floor.addObject('MeshOBJLoader', name='surface_loader', filename='mesh/floor.obj',
31+
scale3d=[0.2, 0.1, 0.2], translation=[0, -15, 0])
32+
floor.addObject('OglModel', src=floor_loader.getLinkPath())
33+
34+
35+
def add_ball(root, name, position, obj_loader):
36+
ball_node = root.addChild(name)
37+
38+
initial_position = position + (0, 0, 0, 1)
39+
ball_node.addObject('MechanicalObject', name='dofs', template='Rigid3d', position=initial_position)
40+
ball_node.addObject('UniformMass', name='mass', totalMass=1)
41+
ball_node.addObject('PlaneForceField', normal='0 1 0', d='-15', stiffness='10000')
42+
43+
visual_model = ball_node.addChild('visual')
44+
visual_model.addObject('OglModel', src=obj_loader.getLinkPath())
45+
visual_model.addObject('RigidMapping')
46+
47+
return ball_node
48+
49+
50+
class KeyPressedController(Sofa.Core.Controller):
51+
52+
def __init__(self, *args, **kwargs):
53+
Sofa.Core.Controller.__init__(self, *args, **kwargs)
54+
self.springs = kwargs.get('springs')
55+
56+
def onKeypressedEvent(self, event):
57+
if event['key'] == 'L':
58+
print('Remove spring')
59+
self.springs.removeSpring(0)

0 commit comments

Comments
 (0)