Skip to content

Commit 0d8abef

Browse files
psomers3psomers3
andauthored
* fixed visualization examples to work with OglModel surfaces (#111)
Co-authored-by: psomers3 <[email protected]>
1 parent 8151cfe commit 0d8abef

File tree

2 files changed

+102
-106
lines changed

2 files changed

+102
-106
lines changed

examples/additional-examples/pygame_example.py

Lines changed: 85 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,25 @@
99
from OpenGL.GL import *
1010
from OpenGL.GLU import *
1111

12-
13-
pygame.display.init()
1412
display_size = (800, 600)
15-
pygame.display.set_mode(display_size, pygame.DOUBLEBUF | pygame.OPENGL)
1613

17-
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
18-
glEnable(GL_LIGHTING)
19-
glEnable(GL_DEPTH_TEST)
20-
Sofa.SofaGL.glewInit()
21-
glMatrixMode(GL_PROJECTION)
22-
glLoadIdentity()
23-
gluPerspective(45, (display_size[0] / display_size[1]), 0.1, 50.0)
2414

25-
glMatrixMode(GL_MODELVIEW)
26-
glLoadIdentity()
15+
def init_display(node):
16+
pygame.display.init()
17+
pygame.display.set_mode(display_size, pygame.DOUBLEBUF | pygame.OPENGL)
18+
19+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
20+
glEnable(GL_LIGHTING)
21+
glEnable(GL_DEPTH_TEST)
22+
Sofa.SofaGL.glewInit()
23+
Sofa.Simulation.initVisual(node)
24+
Sofa.Simulation.initTextures(node)
25+
glMatrixMode(GL_PROJECTION)
26+
glLoadIdentity()
27+
gluPerspective(45, (display_size[0] / display_size[1]), 0.1, 50.0)
28+
29+
glMatrixMode(GL_MODELVIEW)
30+
glLoadIdentity()
2731

2832
def simple_render(rootNode):
2933
"""
@@ -38,98 +42,83 @@ def simple_render(rootNode):
3842
glMatrixMode(GL_MODELVIEW)
3943
glLoadIdentity()
4044

41-
cameraMVM = rootNode.visuals.camera.getOpenGLModelViewMatrix()
45+
cameraMVM = rootNode.camera.getOpenGLModelViewMatrix()
4246
glMultMatrixd(cameraMVM)
43-
44-
Sofa.SofaGL.draw(rootNode.visuals)
47+
Sofa.SofaGL.draw(rootNode)
4548

4649
pygame.display.get_surface().fill((0,0,0))
4750
pygame.display.flip()
4851

4952

50-
class scene_interface:
51-
"""Scene_interface provides step and reset methods"""
52-
53-
def __init__(self, max_steps=1000):
54-
# max_steps, how long the simulator should run. Total length: dt*max_steps
55-
self.max_steps = max_steps
56-
57-
# the current step in the simulation
58-
self.current_step = 0
59-
# Register all the common component in the factory.
60-
SofaRuntime.PluginRepository.addFirstPath(os.path.join(sofa_directory, 'plugins'))
61-
SofaRuntime.importPlugin('SofaOpenglVisual')
62-
SofaRuntime.importPlugin("SofaComponentAll")
63-
SofaRuntime.importPlugin("SofaGeneralLoader")
64-
SofaRuntime.importPlugin("SofaImplicitOdeSolver")
65-
SofaRuntime.importPlugin("SofaLoader")
66-
SofaRuntime.importPlugin("SofaSimpleFem")
67-
SofaRuntime.importPlugin("SofaBoundaryCondition")
68-
SofaRuntime.importPlugin("SofaMiscForceField")
69-
70-
self.root = Sofa.Core.Node("myroot")
71-
72-
### create some objects to observe
73-
self.place_objects_in_scene(self.root)
74-
75-
# place light and a camera
76-
self.visuals = self.root.addChild('visuals')
77-
self.visuals.addObject("LightManager")
78-
self.visuals.addObject("SpotLight", position=[0,10,0], direction=[0,-1,0])
79-
self.visuals.addObject("InteractiveCamera", name="camera", position=[0,10, 0],
53+
def createScene(root):
54+
# Register all the common component in the factory.
55+
SofaRuntime.PluginRepository.addFirstPath(os.path.join(sofa_directory, 'bin'))
56+
root.addObject("RequiredPlugin", name="SofaOpenglVisual") # visual stuff
57+
root.addObject("RequiredPlugin", name="SofaLoader") # geometry loaders
58+
root.addObject("RequiredPlugin", name="SofaSimpleFem") # diffusion fem
59+
root.addObject("RequiredPlugin", name="SofaBoundaryCondition") # constraints
60+
root.addObject("RequiredPlugin", name="SofaEngine") # Box Roi
61+
root.addObject("RequiredPlugin", name="SofaImplicitOdeSolver") # implicit solver
62+
root.addObject("RequiredPlugin", name="SofaMiscForceField") # meshmatrix
63+
root.addObject("RequiredPlugin", name="SofaGeneralEngine") # TextureInterpolation
64+
root.addObject("RequiredPlugin", name="CImgPlugin") # for loading a bmp image for texture
65+
root.addObject("RequiredPlugin", name="SofaBaseLinearSolver")
66+
root.addObject("RequiredPlugin", name="SofaGeneralVisual")
67+
root.addObject("RequiredPlugin", name="SofaTopologyMapping")
68+
root.addObject("RequiredPlugin", name="SofaGeneralTopology")
69+
root.addObject("RequiredPlugin", name="SofaGeneralLoader")
70+
71+
### these are just some things that stay still and move around
72+
# so you know the animation is actually happening
73+
root.gravity = [0, -1., 0]
74+
root.addObject("VisualStyle", displayFlags="showAll")
75+
root.addObject("MeshGmshLoader", name="meshLoaderCoarse",
76+
filename="mesh/liver.msh")
77+
root.addObject("MeshObjLoader", name="meshLoaderFine",
78+
filename="mesh/liver-smooth.obj")
79+
80+
root.addObject("EulerImplicitSolver")
81+
root.addObject("CGLinearSolver", iterations="200",
82+
tolerance="1e-09", threshold="1e-09")
83+
84+
liver = root.addChild("liver")
85+
86+
liver.addObject("TetrahedronSetTopologyContainer",
87+
name="topo", src="@../meshLoaderCoarse")
88+
liver.addObject("TetrahedronSetGeometryAlgorithms",
89+
template="Vec3d", name="GeomAlgo")
90+
liver.addObject("MechanicalObject",
91+
template="Vec3d",
92+
name="MechanicalModel", showObject="1", showObjectScale="3")
93+
94+
liver.addObject("TetrahedronFEMForceField", name="fem", youngModulus="1000",
95+
poissonRatio="0.4", method="large")
96+
97+
liver.addObject("MeshMatrixMass", massDensity="1")
98+
liver.addObject("FixedConstraint", indices="2 3 50")
99+
visual = liver.addChild("visual")
100+
visual.addObject('MeshObjLoader', name="meshLoader_0", filename="mesh/liver-smooth.obj", handleSeams="1")
101+
visual.addObject('OglModel', name="VisualModel", src="@meshLoader_0", color='red')
102+
visual.addObject('BarycentricMapping', input="@..", output="@VisualModel", name="visual mapping")
103+
104+
# place light and a camera
105+
root.addObject("LightManager")
106+
root.addObject("DirectionalLight", direction=[0,1,0])
107+
root.addObject("InteractiveCamera", name="camera", position=[0,15, 0],
80108
lookAt=[0,0,0], distance=37,
81109
fieldOfView=45, zNear=0.63, zFar=55.69)
82110

83-
# start the simulator
84-
Sofa.Simulation.init(self.root)
85-
86-
def place_objects_in_scene(self, root):
87-
### these are just some things that stay still and move around
88-
# so you know the animation is actually happening
89-
root.gravity = [0, -1., 0]
90-
root.addObject("VisualStyle", displayFlags="showBehaviorModels showAll")
91-
root.addObject("MeshGmshLoader", name="meshLoaderCoarse",
92-
filename="mesh/liver.msh")
93-
root.addObject("MeshObjLoader", name="meshLoaderFine",
94-
filename="mesh/liver-smooth.obj")
95-
96-
root.addObject("EulerImplicitSolver")
97-
root.addObject("CGLinearSolver", iterations="200",
98-
tolerance="1e-09", threshold="1e-09")
99-
100-
liver = root.addChild("liver")
101-
102-
liver.addObject("TetrahedronSetTopologyContainer",
103-
name="topo", src="@../meshLoaderCoarse" )
104-
liver.addObject("TetrahedronSetGeometryAlgorithms",
105-
template="Vec3d", name="GeomAlgo")
106-
liver.addObject("MechanicalObject",
107-
template="Vec3d",
108-
name="MechanicalModel", showObject="1", showObjectScale="3")
109-
110-
liver.addObject("TetrahedronFEMForceField", name="fem", youngModulus="1000",
111-
poissonRatio="0.4", method="large")
112-
113-
liver.addObject("MeshMatrixMass", massDensity="1")
114-
liver.addObject("FixedConstraint", indices="2 3 50")
115-
116-
def step(self):
117-
# this steps the simulation
118-
Sofa.Simulation.animate(self.root, self.root.getDt())
119-
self.visuals.camera.position = self.visuals.camera.position + [-0.002, 0, 0]
120-
simple_render(self.root)
121-
122-
# just to keep track of where we are
123-
self.current_step += 1
124-
125-
# return true if done
126-
return self.current_step >= self.max_steps
127-
128111

129112
if __name__ == '__main__':
130-
a = scene_interface()
131-
done = False
132-
while not done:
133-
factor = a.current_step
134-
done = a.step()
135-
time.sleep(a.root.getDt())
113+
root = Sofa.Core.Node("myroot")
114+
createScene(root)
115+
Sofa.Simulation.init(root)
116+
init_display(root)
117+
try:
118+
while True:
119+
Sofa.Simulation.animate(root, root.getDt())
120+
Sofa.Simulation.updateVisual(root)
121+
simple_render(root)
122+
time.sleep(root.getDt())
123+
except KeyboardInterrupt:
124+
pass

examples/additional-examples/pyqt_example.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from qtpy.QtCore import *
22
from qtpy.QtWidgets import *
33
from qtpy.QtOpenGL import *
4-
import Sofa.SofaGL as SGL
4+
import Sofa.SofaGL
55
import Sofa
66
import SofaRuntime
77
import Sofa.Simulation as sim
@@ -12,7 +12,6 @@
1212
import numpy as np
1313
from PIL import Image
1414

15-
1615
"""
1716
With something like this setup, we can use Sofa with our own GUI and not have to give over control of the main thread.
1817
Simple pyqt signals can be added to manually rotate the view with the mouse (could be a tedious task to get it to
@@ -56,7 +55,9 @@ def initializeGL(self):
5655
glEnable(GL_LIGHTING)
5756
glEnable(GL_DEPTH_TEST)
5857
glDepthFunc(GL_LESS)
59-
SGL.glewInit()
58+
Sofa.SofaGL.glewInit()
59+
Sofa.Simulation.initVisual(self.visuals_node)
60+
Sofa.Simulation.initTextures(self.visuals_node)
6061
glMatrixMode(GL_PROJECTION)
6162
glLoadIdentity()
6263
gluPerspective(45, (self.width() / self.height()), 0.1, 50.0)
@@ -75,7 +76,7 @@ def paintGL(self):
7576
cameraMVM = self.visuals_node.camera.getOpenGLModelViewMatrix()
7677
glMultMatrixd(cameraMVM)
7778

78-
SGL.draw(self.visuals_node)
79+
Sofa.SofaGL.draw(self.visuals_node)
7980

8081
def get_depth_image(self):
8182
_, _, width, height = glGetIntegerv(GL_VIEWPORT)
@@ -94,7 +95,7 @@ def get_depth_image(self):
9495
class SofaSim():
9596
def __init__(self):
9697
# Register all the common component in the factory.
97-
SofaRuntime.PluginRepository.addFirstPath(os.path.join(sofa_directory, 'plugins'))
98+
SofaRuntime.PluginRepository.addFirstPath(os.path.join(sofa_directory, 'bin'))
9899
SofaRuntime.importPlugin('SofaOpenglVisual')
99100
SofaRuntime.importPlugin("SofaComponentAll")
100101
SofaRuntime.importPlugin("SofaGeneralLoader")
@@ -132,11 +133,16 @@ def __init__(self):
132133
liver.addObject("MeshMatrixMass", massDensity="1")
133134
liver.addObject("FixedConstraint", indices="2 3 50")
134135

136+
visual = liver.addChild("visual")
137+
visual.addObject('MeshObjLoader', name="meshLoader_0", filename="mesh/liver-smooth.obj", handleSeams="1")
138+
visual.addObject('OglModel', name="VisualModel", src="@meshLoader_0", color='red')
139+
visual.addObject('BarycentricMapping', input="@..", output="@VisualModel", name="visual mapping")
140+
135141
# place light and a camera
136142
self.visuals = root.addChild('visuals')
137-
self.visuals.addObject("LightManager")
138-
self.visuals.addObject("SpotLight", position=[0, 10, 0], direction=[0, -1, 0])
139-
self.visuals.addObject("InteractiveCamera", name="camera", position=[0, 10, 0],
143+
root.addObject("LightManager")
144+
root.addObject("DirectionalLight", direction=[0, 1, 0])
145+
self.visuals.addObject("InteractiveCamera", name="camera", position=[0, 15, 0],
140146
lookAt=[0, 0, 0], distance=37,
141147
fieldOfView=45, zNear=0.63, zFar=55.69)
142148

@@ -146,11 +152,12 @@ def init_sim(self):
146152

147153
def step_sim(self):
148154
self.visuals.camera.position = self.visuals.camera.position + [-0.0002, 0, 0]
149-
Sofa.Simulation.animate(self.root, self.root.getDt())
155+
Sofa.Simulation.animate(self.root, self.root.getDt()) # uncomment to animated sim
156+
Sofa.Simulation.updateVisual(self.root)
150157

151158

152159
if __name__ == '__main__':
153160
app = QApplication(['Yo'])
154161
window = MainWindow()
155162
window.show()
156-
app.exec_()
163+
app.exec_()

0 commit comments

Comments
 (0)