From 7b68d0b9be367182936c016f4e217a393adbc92c Mon Sep 17 00:00:00 2001 From: psomers3 Date: Wed, 10 Feb 2021 18:07:24 +0100 Subject: [PATCH] * fixed visualization examples to work with OglModel surfaces --- .../additional-examples/pygame_example.py | 181 ++++++++---------- examples/additional-examples/pyqt_example.py | 27 ++- 2 files changed, 102 insertions(+), 106 deletions(-) diff --git a/examples/additional-examples/pygame_example.py b/examples/additional-examples/pygame_example.py index d353713d..d19f3fc7 100644 --- a/examples/additional-examples/pygame_example.py +++ b/examples/additional-examples/pygame_example.py @@ -9,21 +9,25 @@ from OpenGL.GL import * from OpenGL.GLU import * - -pygame.display.init() display_size = (800, 600) -pygame.display.set_mode(display_size, pygame.DOUBLEBUF | pygame.OPENGL) -glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) -glEnable(GL_LIGHTING) -glEnable(GL_DEPTH_TEST) -Sofa.SofaGL.glewInit() -glMatrixMode(GL_PROJECTION) -glLoadIdentity() -gluPerspective(45, (display_size[0] / display_size[1]), 0.1, 50.0) -glMatrixMode(GL_MODELVIEW) -glLoadIdentity() +def init_display(node): + pygame.display.init() + pygame.display.set_mode(display_size, pygame.DOUBLEBUF | pygame.OPENGL) + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + glEnable(GL_LIGHTING) + glEnable(GL_DEPTH_TEST) + Sofa.SofaGL.glewInit() + Sofa.Simulation.initVisual(node) + Sofa.Simulation.initTextures(node) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + gluPerspective(45, (display_size[0] / display_size[1]), 0.1, 50.0) + + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() def simple_render(rootNode): """ @@ -38,98 +42,83 @@ def simple_render(rootNode): glMatrixMode(GL_MODELVIEW) glLoadIdentity() - cameraMVM = rootNode.visuals.camera.getOpenGLModelViewMatrix() + cameraMVM = rootNode.camera.getOpenGLModelViewMatrix() glMultMatrixd(cameraMVM) - - Sofa.SofaGL.draw(rootNode.visuals) + Sofa.SofaGL.draw(rootNode) pygame.display.get_surface().fill((0,0,0)) pygame.display.flip() -class scene_interface: - """Scene_interface provides step and reset methods""" - - def __init__(self, max_steps=1000): - # max_steps, how long the simulator should run. Total length: dt*max_steps - self.max_steps = max_steps - - # the current step in the simulation - self.current_step = 0 - # Register all the common component in the factory. - SofaRuntime.PluginRepository.addFirstPath(os.path.join(sofa_directory, 'plugins')) - SofaRuntime.importPlugin('SofaOpenglVisual') - SofaRuntime.importPlugin("SofaComponentAll") - SofaRuntime.importPlugin("SofaGeneralLoader") - SofaRuntime.importPlugin("SofaImplicitOdeSolver") - SofaRuntime.importPlugin("SofaLoader") - SofaRuntime.importPlugin("SofaSimpleFem") - SofaRuntime.importPlugin("SofaBoundaryCondition") - SofaRuntime.importPlugin("SofaMiscForceField") - - self.root = Sofa.Core.Node("myroot") - - ### create some objects to observe - self.place_objects_in_scene(self.root) - - # place light and a camera - self.visuals = self.root.addChild('visuals') - self.visuals.addObject("LightManager") - self.visuals.addObject("SpotLight", position=[0,10,0], direction=[0,-1,0]) - self.visuals.addObject("InteractiveCamera", name="camera", position=[0,10, 0], +def createScene(root): + # Register all the common component in the factory. + SofaRuntime.PluginRepository.addFirstPath(os.path.join(sofa_directory, 'bin')) + root.addObject("RequiredPlugin", name="SofaOpenglVisual") # visual stuff + root.addObject("RequiredPlugin", name="SofaLoader") # geometry loaders + root.addObject("RequiredPlugin", name="SofaSimpleFem") # diffusion fem + root.addObject("RequiredPlugin", name="SofaBoundaryCondition") # constraints + root.addObject("RequiredPlugin", name="SofaEngine") # Box Roi + root.addObject("RequiredPlugin", name="SofaImplicitOdeSolver") # implicit solver + root.addObject("RequiredPlugin", name="SofaMiscForceField") # meshmatrix + root.addObject("RequiredPlugin", name="SofaGeneralEngine") # TextureInterpolation + root.addObject("RequiredPlugin", name="CImgPlugin") # for loading a bmp image for texture + root.addObject("RequiredPlugin", name="SofaBaseLinearSolver") + root.addObject("RequiredPlugin", name="SofaGeneralVisual") + root.addObject("RequiredPlugin", name="SofaTopologyMapping") + root.addObject("RequiredPlugin", name="SofaGeneralTopology") + root.addObject("RequiredPlugin", name="SofaGeneralLoader") + + ### these are just some things that stay still and move around + # so you know the animation is actually happening + root.gravity = [0, -1., 0] + root.addObject("VisualStyle", displayFlags="showAll") + root.addObject("MeshGmshLoader", name="meshLoaderCoarse", + filename="mesh/liver.msh") + root.addObject("MeshObjLoader", name="meshLoaderFine", + filename="mesh/liver-smooth.obj") + + root.addObject("EulerImplicitSolver") + root.addObject("CGLinearSolver", iterations="200", + tolerance="1e-09", threshold="1e-09") + + liver = root.addChild("liver") + + liver.addObject("TetrahedronSetTopologyContainer", + name="topo", src="@../meshLoaderCoarse") + liver.addObject("TetrahedronSetGeometryAlgorithms", + template="Vec3d", name="GeomAlgo") + liver.addObject("MechanicalObject", + template="Vec3d", + name="MechanicalModel", showObject="1", showObjectScale="3") + + liver.addObject("TetrahedronFEMForceField", name="fem", youngModulus="1000", + poissonRatio="0.4", method="large") + + liver.addObject("MeshMatrixMass", massDensity="1") + liver.addObject("FixedConstraint", indices="2 3 50") + visual = liver.addChild("visual") + visual.addObject('MeshObjLoader', name="meshLoader_0", filename="mesh/liver-smooth.obj", handleSeams="1") + visual.addObject('OglModel', name="VisualModel", src="@meshLoader_0", color='red') + visual.addObject('BarycentricMapping', input="@..", output="@VisualModel", name="visual mapping") + + # place light and a camera + root.addObject("LightManager") + root.addObject("DirectionalLight", direction=[0,1,0]) + root.addObject("InteractiveCamera", name="camera", position=[0,15, 0], lookAt=[0,0,0], distance=37, fieldOfView=45, zNear=0.63, zFar=55.69) - # start the simulator - Sofa.Simulation.init(self.root) - - def place_objects_in_scene(self, root): - ### these are just some things that stay still and move around - # so you know the animation is actually happening - root.gravity = [0, -1., 0] - root.addObject("VisualStyle", displayFlags="showBehaviorModels showAll") - root.addObject("MeshGmshLoader", name="meshLoaderCoarse", - filename="mesh/liver.msh") - root.addObject("MeshObjLoader", name="meshLoaderFine", - filename="mesh/liver-smooth.obj") - - root.addObject("EulerImplicitSolver") - root.addObject("CGLinearSolver", iterations="200", - tolerance="1e-09", threshold="1e-09") - - liver = root.addChild("liver") - - liver.addObject("TetrahedronSetTopologyContainer", - name="topo", src="@../meshLoaderCoarse" ) - liver.addObject("TetrahedronSetGeometryAlgorithms", - template="Vec3d", name="GeomAlgo") - liver.addObject("MechanicalObject", - template="Vec3d", - name="MechanicalModel", showObject="1", showObjectScale="3") - - liver.addObject("TetrahedronFEMForceField", name="fem", youngModulus="1000", - poissonRatio="0.4", method="large") - - liver.addObject("MeshMatrixMass", massDensity="1") - liver.addObject("FixedConstraint", indices="2 3 50") - - def step(self): - # this steps the simulation - Sofa.Simulation.animate(self.root, self.root.getDt()) - self.visuals.camera.position = self.visuals.camera.position + [-0.002, 0, 0] - simple_render(self.root) - - # just to keep track of where we are - self.current_step += 1 - - # return true if done - return self.current_step >= self.max_steps - if __name__ == '__main__': - a = scene_interface() - done = False - while not done: - factor = a.current_step - done = a.step() - time.sleep(a.root.getDt()) + root = Sofa.Core.Node("myroot") + createScene(root) + Sofa.Simulation.init(root) + init_display(root) + try: + while True: + Sofa.Simulation.animate(root, root.getDt()) + Sofa.Simulation.updateVisual(root) + simple_render(root) + time.sleep(root.getDt()) + except KeyboardInterrupt: + pass diff --git a/examples/additional-examples/pyqt_example.py b/examples/additional-examples/pyqt_example.py index 5c6d2f2b..8fe84b6a 100644 --- a/examples/additional-examples/pyqt_example.py +++ b/examples/additional-examples/pyqt_example.py @@ -1,7 +1,7 @@ from qtpy.QtCore import * from qtpy.QtWidgets import * from qtpy.QtOpenGL import * -import Sofa.SofaGL as SGL +import Sofa.SofaGL import Sofa import SofaRuntime import Sofa.Simulation as sim @@ -12,7 +12,6 @@ import numpy as np from PIL import Image - """ With something like this setup, we can use Sofa with our own GUI and not have to give over control of the main thread. 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): glEnable(GL_LIGHTING) glEnable(GL_DEPTH_TEST) glDepthFunc(GL_LESS) - SGL.glewInit() + Sofa.SofaGL.glewInit() + Sofa.Simulation.initVisual(self.visuals_node) + Sofa.Simulation.initTextures(self.visuals_node) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45, (self.width() / self.height()), 0.1, 50.0) @@ -75,7 +76,7 @@ def paintGL(self): cameraMVM = self.visuals_node.camera.getOpenGLModelViewMatrix() glMultMatrixd(cameraMVM) - SGL.draw(self.visuals_node) + Sofa.SofaGL.draw(self.visuals_node) def get_depth_image(self): _, _, width, height = glGetIntegerv(GL_VIEWPORT) @@ -94,7 +95,7 @@ def get_depth_image(self): class SofaSim(): def __init__(self): # Register all the common component in the factory. - SofaRuntime.PluginRepository.addFirstPath(os.path.join(sofa_directory, 'plugins')) + SofaRuntime.PluginRepository.addFirstPath(os.path.join(sofa_directory, 'bin')) SofaRuntime.importPlugin('SofaOpenglVisual') SofaRuntime.importPlugin("SofaComponentAll") SofaRuntime.importPlugin("SofaGeneralLoader") @@ -132,11 +133,16 @@ def __init__(self): liver.addObject("MeshMatrixMass", massDensity="1") liver.addObject("FixedConstraint", indices="2 3 50") + visual = liver.addChild("visual") + visual.addObject('MeshObjLoader', name="meshLoader_0", filename="mesh/liver-smooth.obj", handleSeams="1") + visual.addObject('OglModel', name="VisualModel", src="@meshLoader_0", color='red') + visual.addObject('BarycentricMapping', input="@..", output="@VisualModel", name="visual mapping") + # place light and a camera self.visuals = root.addChild('visuals') - self.visuals.addObject("LightManager") - self.visuals.addObject("SpotLight", position=[0, 10, 0], direction=[0, -1, 0]) - self.visuals.addObject("InteractiveCamera", name="camera", position=[0, 10, 0], + root.addObject("LightManager") + root.addObject("DirectionalLight", direction=[0, 1, 0]) + self.visuals.addObject("InteractiveCamera", name="camera", position=[0, 15, 0], lookAt=[0, 0, 0], distance=37, fieldOfView=45, zNear=0.63, zFar=55.69) @@ -146,11 +152,12 @@ def init_sim(self): def step_sim(self): self.visuals.camera.position = self.visuals.camera.position + [-0.0002, 0, 0] - Sofa.Simulation.animate(self.root, self.root.getDt()) + Sofa.Simulation.animate(self.root, self.root.getDt()) # uncomment to animated sim + Sofa.Simulation.updateVisual(self.root) if __name__ == '__main__': app = QApplication(['Yo']) window = MainWindow() window.show() - app.exec_() + app.exec_() \ No newline at end of file