init
This commit is contained in:
+311
@@ -0,0 +1,311 @@
|
||||
"""
|
||||
Description:
|
||||
|
||||
Provides a pyGtk vtkRenderWindowInteractor widget. This embeds a
|
||||
vtkRenderWindow inside a GTK widget and uses the
|
||||
vtkGenericRenderWindowInteractor for the event handling. This is
|
||||
similar to GtkVTKRenderWindowInteractor.py.
|
||||
|
||||
The extensions here allow the use of gtkglext rather than gtkgl and
|
||||
pygtk-2 rather than pygtk-0. It requires pygtk-2.0.0 or later.
|
||||
|
||||
There is a working example at the bottom.
|
||||
|
||||
Credits:
|
||||
|
||||
John Hunter <jdhunter@ace.bsd.uchicago.edu> developed and tested
|
||||
this code based on VTK's GtkVTKRenderWindow.py and extended it to
|
||||
work with pygtk-2.0.0.
|
||||
|
||||
License:
|
||||
|
||||
VTK license.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk
|
||||
from gtk import gdk
|
||||
import gtk.gtkgl
|
||||
from vtkmodules.vtkRenderingCore import vtkRenderWindow
|
||||
from vtkmodules.vtkRenderingUI import vtkGenericRenderWindowInteractor
|
||||
|
||||
class GtkGLExtVTKRenderWindowInteractor(gtk.gtkgl.DrawingArea):
|
||||
|
||||
""" Embeds a vtkRenderWindow into a pyGTK widget and uses
|
||||
vtkGenericRenderWindowInteractor for the event handling. This
|
||||
class embeds the RenderWindow correctly. A __getattr__ hook is
|
||||
provided that makes the class behave like a
|
||||
vtkGenericRenderWindowInteractor."""
|
||||
|
||||
def __init__(self, *args):
|
||||
gtk.gtkgl.DrawingArea.__init__(self)
|
||||
|
||||
self.set_double_buffered(gtk.FALSE)
|
||||
|
||||
self._RenderWindow = vtkRenderWindow()
|
||||
|
||||
# private attributes
|
||||
self.__Created = 0
|
||||
self._ActiveButton = 0
|
||||
|
||||
self._Iren = vtkGenericRenderWindowInteractor()
|
||||
self._Iren.SetRenderWindow(self._RenderWindow)
|
||||
self._Iren.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
|
||||
self._Iren.AddObserver('CreateTimerEvent', self.CreateTimer)
|
||||
self._Iren.AddObserver('DestroyTimerEvent', self.DestroyTimer)
|
||||
self.ConnectSignals()
|
||||
|
||||
# need this to be able to handle key_press events.
|
||||
self.set_flags(gtk.CAN_FOCUS)
|
||||
|
||||
def set_size_request(self, w, h):
|
||||
gtk.gtkgl.DrawingArea.set_size_request(self, w, h)
|
||||
self._RenderWindow.SetSize(w, h)
|
||||
self._Iren.SetSize(w, h)
|
||||
self._Iren.ConfigureEvent()
|
||||
|
||||
def ConnectSignals(self):
|
||||
self.connect("realize", self.OnRealize)
|
||||
self.connect("expose_event", self.OnExpose)
|
||||
self.connect("configure_event", self.OnConfigure)
|
||||
self.connect("button_press_event", self.OnButtonDown)
|
||||
self.connect("button_release_event", self.OnButtonUp)
|
||||
self.connect("motion_notify_event", self.OnMouseMove)
|
||||
self.connect("enter_notify_event", self.OnEnter)
|
||||
self.connect("leave_notify_event", self.OnLeave)
|
||||
self.connect("key_press_event", self.OnKeyPress)
|
||||
self.connect("delete_event", self.OnDestroy)
|
||||
self.add_events(gdk.EXPOSURE_MASK| gdk.BUTTON_PRESS_MASK |
|
||||
gdk.BUTTON_RELEASE_MASK |
|
||||
gdk.KEY_PRESS_MASK |
|
||||
gdk.POINTER_MOTION_MASK |
|
||||
gdk.POINTER_MOTION_HINT_MASK |
|
||||
gdk.ENTER_NOTIFY_MASK | gdk.LEAVE_NOTIFY_MASK)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"""Makes the object behave like a
|
||||
vtkGenericRenderWindowInteractor"""
|
||||
if attr == '__vtk__':
|
||||
return lambda t=self._Iren: t
|
||||
elif hasattr(self._Iren, attr):
|
||||
return getattr(self._Iren, attr)
|
||||
else:
|
||||
raise AttributeError(self.__class__.__name__ +
|
||||
" has no attribute named " + attr)
|
||||
|
||||
def CreateTimer(self, obj, event):
|
||||
gtk.timeout_add(10, self._Iren.TimerEvent)
|
||||
|
||||
def DestroyTimer(self, obj, event):
|
||||
"""The timer is a one shot timer so will expire automatically."""
|
||||
return 1
|
||||
|
||||
def GetRenderWindow(self):
|
||||
return self._RenderWindow
|
||||
|
||||
def Render(self):
|
||||
if self.__Created:
|
||||
self._RenderWindow.Render()
|
||||
|
||||
def OnRealize(self, *args):
|
||||
if self.__Created == 0:
|
||||
# you can't get the xid without the window being realized.
|
||||
self.realize()
|
||||
if sys.platform=='win32':
|
||||
win_id = str(self.widget.window.handle)
|
||||
else:
|
||||
win_id = str(self.widget.window.xid)
|
||||
|
||||
self._RenderWindow.SetWindowInfo(win_id)
|
||||
#self._Iren.Initialize()
|
||||
self.__Created = 1
|
||||
return gtk.TRUE
|
||||
|
||||
def OnConfigure(self, widget, event):
|
||||
self.widget=widget
|
||||
self._Iren.SetSize(event.width, event.height)
|
||||
self._Iren.ConfigureEvent()
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnExpose(self, *args):
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnDestroy(self, event=None):
|
||||
self.hide()
|
||||
del self._RenderWindow
|
||||
self.destroy()
|
||||
return gtk.TRUE
|
||||
|
||||
def _GetCtrlShift(self, event):
|
||||
ctrl, shift = 0, 0
|
||||
if ((event.state & gdk.CONTROL_MASK) == gdk.CONTROL_MASK):
|
||||
ctrl = 1
|
||||
if ((event.state & gdk.SHIFT_MASK) == gdk.SHIFT_MASK):
|
||||
shift = 1
|
||||
return ctrl, shift
|
||||
|
||||
def OnButtonDown(self, wid, event):
|
||||
"""Mouse button pressed."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
button = event.button
|
||||
if button == 3:
|
||||
self._Iren.RightButtonPressEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 1:
|
||||
self._Iren.LeftButtonPressEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 2:
|
||||
self._Iren.MiddleButtonPressEvent()
|
||||
return gtk.TRUE
|
||||
else:
|
||||
return gtk.FALSE
|
||||
|
||||
def OnButtonUp(self, wid, event):
|
||||
"""Mouse button released."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
button = event.button
|
||||
if button == 3:
|
||||
self._Iren.RightButtonReleaseEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 1:
|
||||
self._Iren.LeftButtonReleaseEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 2:
|
||||
self._Iren.MiddleButtonReleaseEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
return gtk.FALSE
|
||||
|
||||
def OnMouseMove(self, wid, event):
|
||||
"""Mouse has moved."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.MouseMoveEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnEnter(self, wid, event):
|
||||
"""Entering the vtkRenderWindow."""
|
||||
self.grab_focus()
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.EnterEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnLeave(self, wid, event):
|
||||
"""Leaving the vtkRenderWindow."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.LeaveEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyPress(self, wid, event):
|
||||
"""Key pressed."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
keycode, keysym = event.keyval, event.string
|
||||
key = chr(0)
|
||||
if keycode < 256:
|
||||
key = chr(keycode)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
key, 0, keysym)
|
||||
self._Iren.KeyPressEvent()
|
||||
self._Iren.CharEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyRelease(self, wid, event):
|
||||
"Key released."
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
keycode, keysym = event.keyval, event.string
|
||||
key = chr(0)
|
||||
if keycode < 256:
|
||||
key = chr(keycode)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
key, 0, keysym)
|
||||
self._Iren.KeyReleaseEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def Initialize(self):
|
||||
if self.__Created:
|
||||
self._Iren.Initialize()
|
||||
|
||||
def SetPicker(self, picker):
|
||||
self._Iren.SetPicker(picker)
|
||||
|
||||
def GetPicker(self, picker):
|
||||
return self._Iren.GetPicker()
|
||||
|
||||
|
||||
def main():
|
||||
from vtkmodules.vtkFiltersSources import vtkConeSource
|
||||
from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer
|
||||
# load implementations for rendering and interaction factory classes
|
||||
import vtkmodules.vtkRenderingOpenGL2
|
||||
import vtkmodules.vtkInteractionStyle
|
||||
|
||||
# The main window
|
||||
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||
window.set_title("A GtkVTKRenderWindow Demo!")
|
||||
window.connect("destroy", gtk.mainquit)
|
||||
window.connect("delete_event", gtk.mainquit)
|
||||
window.set_border_width(10)
|
||||
|
||||
# A VBox into which widgets are packed.
|
||||
vbox = gtk.VBox(spacing=3)
|
||||
window.add(vbox)
|
||||
vbox.show()
|
||||
|
||||
# The GtkVTKRenderWindow
|
||||
gvtk = GtkGLExtVTKRenderWindowInteractor()
|
||||
#gvtk.SetDesiredUpdateRate(1000)
|
||||
gvtk.set_size_request(400, 400)
|
||||
vbox.pack_start(gvtk)
|
||||
gvtk.show()
|
||||
gvtk.Initialize()
|
||||
gvtk.Start()
|
||||
# prevents 'q' from exiting the app.
|
||||
gvtk.AddObserver("ExitEvent", lambda o,e,x=None: x)
|
||||
|
||||
# The VTK stuff.
|
||||
cone = vtkConeSource()
|
||||
cone.SetResolution(80)
|
||||
coneMapper = vtkPolyDataMapper()
|
||||
coneMapper.SetInputConnection(cone.GetOutputPort())
|
||||
#coneActor = vtkLODActor()
|
||||
coneActor = vtkActor()
|
||||
coneActor.SetMapper(coneMapper)
|
||||
coneActor.GetProperty().SetColor(0.5, 0.5, 1.0)
|
||||
ren = vtkRenderer()
|
||||
gvtk.GetRenderWindow().AddRenderer(ren)
|
||||
ren.AddActor(coneActor)
|
||||
|
||||
# A simple quit button
|
||||
quit = gtk.Button("Quit!")
|
||||
quit.connect("clicked", gtk.mainquit)
|
||||
vbox.pack_start(quit)
|
||||
quit.show()
|
||||
|
||||
# show the main window and start event processing.
|
||||
window.show()
|
||||
gtk.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user