Source code for openalea.oalab.scene.view3d

# -*- python -*-
#
#       3D scene viewer for OALab Scene
# 
#       OpenAlea.OALab: Multi-Paradigm GUI
#
#       Copyright 2013 INRIA - CIRAD - INRA
#
#       File author(s): Julien Coste <julien.coste@inria.fr>
#
#       File contributor(s):
#
#       Distributed under the Cecill-C License.
#       See accompanying file LICENSE.txt or copy at
#           http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
#       OpenAlea WebSite : http://openalea.gforge.inria.fr
#
###############################################################################
__revision__ = ""

from openalea.vpltk.qt import QtGui, QtCore
from openalea.plantgl.all import Scene, Sphere, Discretizer, GLRenderer, BoundingBox
from openalea.core.observer import AbstractListener

from PyQGLViewer import QGLViewer, Vec
import sys


[docs]class view3D(QGLViewer): """ This class is used to create and manipulate a 3 dimensions scene. This scene is based on QGLViewer. For the moment, we have only one view of this scene. """ def __init__(self, parent=None, scene=None, statefilename='.temp_scene.xml', shareWidget=None): QGLViewer.__init__(self, parent, shareWidget) # set the scene if scene == None: scene = self.defaultScene() self.scene = scene # set some parameters self.setAxisIsDrawn(False) # show axis self.setGridIsDrawn(True) # show grid position = Vec(0.0, -1.0, 0.1) self.camera().setPosition(position) # set camera self.camera().lookAt(self.sceneCenter()) self.camera().setSceneRadius(1) #Size of vectors x,y,z self.camera().showEntireScene() # connection self.connect(self, QtCore.SIGNAL("drawNeeded()"), self.draw) self.orientation_initiale = self.camera().orientation() self.position_initiale = self.camera().position() # Block "*.xml" save self.setStateFileName("") # Disable Quit in clicking on 'Escape' # Set "show_axis" instead of "kill_application" self.setShortcut(0, QtCore.Qt.Key_Escape) # Method for lpy.registerPlotter to "animate"
[docs] def plot(self, scene): scenedict = {"new": scene} self.setScene(scenedict) self.updateGL() # Method for lpy.registerPlotter to "animate"
[docs] def selection(self): return super(view3D, self).selection # Method for lpy.registerPlotter to "animate"
[docs] def waitSelection(self, txt): return super(view3D, self).waitSelection(txt) # Method for lpy.registerPlotter to "animate"
[docs] def save(self, fname, format): super(view3D, self).frameGL.saveImage(fname, format)
[docs] def setScene(self, scenes): """ Set the scene (erase old scene if necessary) :param scene: dict with every sub-scenes to add """ self.scene.clear() for s in scenes: self.scene += scenes[s] self.draw()
[docs] def getScene(self): """ :return: the scene (orderedDict) """ return self.scene
[docs] def addToScene(self, obj): """ Add a new object in existing scene :param obj: object to add in the scene """ scene = self.getScene() scene += obj self.setScene(scene)
[docs] def draw(self): """ Draw the scene """ d = Discretizer() gl = GLRenderer(d) self.scene.apply(gl)
[docs] def start(self): self.show()
[docs] def defaultScene(self): """ Create a default scene. Here she is empty. :return: the scene """ scene = Scene() return scene
[docs] def update_radius(self): """ Set the scene radius to 110% of the max size in the scene """ try: bBox = BoundingBox(self.scene) xmax = bBox.getXMax() ymax = bBox.getYMax() zmax = bBox.getZMax() xmin = bBox.getXMin() ymin = bBox.getYMin() zmin = bBox.getZMin() x = max(abs(xmin), abs(xmax)) y = max(abs(ymin), abs(ymax)) z = max(abs(zmin), abs(zmax)) radius = max(x, y, z) self.camera().setSceneRadius(radius * 1.1) self.show_entire_scene() except: pass
[docs]class Viewer(AbstractListener, view3D): """ Widget of 3D Viewer to show the scene. """ def __init__(self, session, controller, parent=None): # super(Viewer, self).__init__() AbstractListener.__init__(self) view3D.__init__(self, parent=parent) self.setAccessibleName("3DViewer") self.setMinimumSize(100, 100) self.autofocus = True self._fps = False self.axis = False self.grid = True actionResetZoom = QtGui.QAction(QtGui.QIcon(":/images/resources/resetzoom.png"), "Reset Zoom", self) actionZoomOut = QtGui.QAction(QtGui.QIcon(":/images/resources/zoomout.png"), "Zoom Out", self) actionZoomIn = QtGui.QAction(QtGui.QIcon(":/images/resources/zoomin.png"), "Zoom In", self) actionShowAxis = QtGui.QAction(QtGui.QIcon(":/images/resources/axis.png"), "Show Axis", self) actionShowGrid = QtGui.QAction(QtGui.QIcon(":/images/resources/grid.png"), "Show Grid", self) actionRadius = QtGui.QAction(QtGui.QIcon(":/images/resources/growth2.png"), "Focus", self) actionShowFps = QtGui.QAction(QtGui.QIcon(":/images/resources/fps.png"), "Show FPS", self) actionShowAxis.setShortcut( QtGui.QApplication.translate("MainWindow", "Ctrl+A", None, QtGui.QApplication.UnicodeUTF8)) actionShowGrid.setShortcut( QtGui.QApplication.translate("MainWindow", "Ctrl+G", None, QtGui.QApplication.UnicodeUTF8)) actionRadius.setShortcut( QtGui.QApplication.translate("MainWindow", "Ctrl+F", None, QtGui.QApplication.UnicodeUTF8)) QtCore.QObject.connect(actionResetZoom, QtCore.SIGNAL('triggered(bool)'), self.resetzoom) QtCore.QObject.connect(actionZoomOut, QtCore.SIGNAL('triggered(bool)'), self.zoomout) QtCore.QObject.connect(actionZoomIn, QtCore.SIGNAL('triggered(bool)'), self.zoomin) QtCore.QObject.connect(actionShowAxis, QtCore.SIGNAL('triggered(bool)'), self.show_hide_axis) QtCore.QObject.connect(actionShowGrid, QtCore.SIGNAL('triggered(bool)'), self.show_hide_grid) QtCore.QObject.connect(actionRadius, QtCore.SIGNAL('triggered(bool)'), self.update_radius) QtCore.QObject.connect(actionShowFps, QtCore.SIGNAL('triggered(bool)'), self.show_fps) session.scene.register_listener(self) # QtCore.QObject.connect(session.scene.signaler, QtCore.SIGNAL('SceneChanged'), self.setScene) # QtCore.QObject.connect(session.scene.signaler, QtCore.SIGNAL('SceneChanged'), self.updateGL) self._actions = [["3D Viewer", "Zoom", actionResetZoom, 0], ["3D Viewer", "Zoom", actionZoomOut, 0], ["3D Viewer", "Zoom", actionZoomIn, 0], ["3D Viewer", "Camera", actionShowAxis, 1], ["3D Viewer", "Camera", actionShowGrid, 1], ["3D Viewer", "Camera", actionRadius, 1], ["3D Viewer", "Informations", actionShowFps, 1]]
[docs] def notify(self, sender, event=None): signal, scene = event self.setScene(scene) self.updateGL()
[docs] def actions(self): return self._actions
[docs] def resetzoom(self): self.camera().setOrientation(self.orientation_initiale) self.camera().setPosition(self.position_initiale) self.updateGL()
[docs] def zoomout(self): cam = self.camera() new_position = (cam.position() - cam.sceneCenter()) * 2 cam.setPosition(new_position) self.updateGL()
[docs] def zoomin(self): cam = self.camera() new_position = (cam.position() - cam.sceneCenter()) / 2 cam.setPosition(new_position) self.updateGL()
[docs] def show_fps(self): self._fps = not self._fps self.setFPSIsDisplayed(self._fps)
[docs] def mainMenu(self): """ :return: Name of menu tab to automatically set current when current widget begin current. """ return "3D Viewer"
[docs] def show_hide_axis(self): if self.axis: self.setAxisIsDrawn(False) # hide axis self.axis = False else: self.setAxisIsDrawn(True) # show axis self.axis = True
[docs] def show_hide_grid(self): if self.grid: self.setGridIsDrawn(False) # hide grid self.grid = False else: self.setGridIsDrawn(True) # show grid self.grid = True
[docs] def show_entire_scene(self): self.camera().showEntireScene() self.updateGL()
[docs] def setScene(self, scenes): """ Set the scene (erase old scene if necessary) Class overloaded to use an autofocus if you add a first object in the scene :param scene: dict with every sub-scenes to add """ super(Viewer, self).setScene(scenes) if self.autofocus: self.update_radius() self.autofocus = False
[docs]def main(): app = QtGui.QApplication(sys.argv) view = view3D() view.addToScene(Sphere()) view.start() app.exec_()
if ( __name__ == "__main__"): main()