用 pygtk + vtk 实现三维数据可视化(二)
vtk 源码包中 Wrapping/Python 目录下的 CMakeLists.txt 文件中没有考虑到基于 gtkglext 的 pygtk 与 vtk 的对接实现,对应代码如下:
SET(VTK_PYTHON_FILES
${VTK_PYTHON_FILES}
vtk/gtk/GtkVTKRenderWindow
vtk/gtk/__init__
vtk/gtk/GtkVTKRenderWindowInteractor
)
GtkVTKRenderWindow 与 GtkVTKRenderWindowInteractor 的实现是基于 gtkglarea 的,在本主题第一篇文档中已经说过,gtkglarea 项目已经死掉了,所以这里再使用 GtkVTKRenderWindow 与 GtkVTKRenderWindowInteractor 来实现 pygtk 与 vtk 的对接,就有点不合时宜了。
在 Ubuntu 7.10 系统中,如果是从系统软件仓库中安装 vtk, 那么它就继承了上述错误,无法实现在 pygtk 程序中显示 vtk 图形。解决方法可以手动将 GtkVTKRenderWindow.py 与 GtkVTKRenderWindowInteractor.py 文件复制到 python 对应模块目录下。
真正应该使用的是 GtkGLExtVTKRenderWindow 与 GtkGLExtVTKRenderWindowInteractor,它们是基于 pygtk、pygtkglext 以及 vtk 的 python wrapping 实现的。所以应当将上述代码修改为:
SET(VTK_PYTHON_FILES
${VTK_PYTHON_FILES}
vtk/gtk/GtkGLExtVTKRenderWindow
vtk/gtk/__init__
vtk/gtk/GtkGLExtVTKRenderWindowInteractor
)
在 Getentoo 中,从官方 portage 中获得的编译环境配置,安装 vtk 后,在 /usr/lib/python/sitepackage/vtk/gtk 目录中可以得到 GtkGLExtVTKRenderWindow.py 与 GtkGLExtVTKRenderWindowInteractor.py 文件,在程序中导入这两个文件的任何一个,都可以实现 在 pygtk 程序中显示 vtk 图形,区别是后者提供了更多的 vtk 渲染环境的交互方式。
如果 python sys.path/vtk/gtk 目录中存在 GtkGLExtVTKRenderWindow.py 与 GtkGLExtVTKRenderWindowInteractor.py 文件,那么可以采用下面的一个小程序 cube.py 测试一下是否可用:
# -*- coding:utf-8 -*-
# filename: cube.py
import vtk
import gtk
from vtk.gtk.GtkGLExtVTKRenderWindowInteractor \
import GtkGLExtVTKRenderWindowInteractor
mbr = vtk.vtkCubeSource()
mbr.SetBounds (0, 2, 0, 2, 0, 2)
mbrMapper = vtk.vtkPolyDataMapper()
mbrMapper.SetInputConnection(mbr.GetOutputPort())
mbrActor = vtk.vtkActor ()
mbrActor.SetMapper(mbrMapper)
ren = vtk.vtkRenderer()
ren.AddActor(mbrActor)
ren.SetBackground(0.1, 0.2, 0.4)
window = gtk.Window (gtk.WINDOW_TOPLEVEL)
window.set_title ("pygtk + vtk 演示")
window.connect ("destroy", gtk.main_quit)
window.connect ("delete_event", gtk.main_quit)
window.set_border_width (4)
vbox = gtk.VBox (spacing = 2)
window.add (vbox)
vbox.show ()
gvtk = GtkGLExtVTKRenderWindowInteractor ()
gvtk.set_size_request(300, 200)
vbox.pack_start(gvtk)
gvtk.show()
gvtk.Initialize()
gvtk.Start()
gvtk.AddObserver("ExitEvent", lambda o,e,x=None: x)
gvtk.GetRenderWindow ().AddRenderer (ren)
quit = gtk.Button ("退出")
quit.connect ("clicked", gtk.main_quit)
vbox.pack_start (quit)
quit.show ()
window.show ()
gtk.main ()
应当显示类似下图所示的 vtk 图形渲染窗口:
在执行 cube.py 脚本时,也许会在终端中得到以下警告:
self.set_double_buffered(gtk.FALSE)
./display.py:45: GtkDeprecationWarning: gtk.TRUE is deprecated, use True instead
window.show ()
./display.py:46: GtkDeprecationWarning: gtk.TRUE is deprecated, use True instead
gtk.main ()
这是由于 GtkGLExtVTKRenderWindowInteractor.py 的实现没有跟进 pygtk 版本的变化。我现在的 pygtk 版本为 2.12.1, GtkGLExtVTKRenderWindowInteractor.py 中所使用的 gtk.TRUE、gtk.FALSE 在较新版本的 pygtk 中被替代为 True 与 False,所以要消除上述警告,可自行对 GtkGLExtVTKRenderWindow.py 与 GtkGLExtVTKRenderWindowInteractor.py 进行适应修改。