VTK在wxpython中的显示
推荐官方的学习网站,绝大部分内容都可以在网站上找到。
一 前言
目标是让VTK的画布显示在wx的panel上。
首先要了解VTK的工作模式。具体的内容可以查相关资料。我在这里简单说一下。
要想让VTK显示东西,首先要有① Data,不管是自己创建还是导入文件的,都要有vtkPolyData。然后要将Data绑定到一个②Mapper上,对应的是vtkPolyDataMapper。接着要将Mapper绑定到③Actor上,对应vtkActor。最后将Actor添加到④Render上,对应vtkRenderer。
要想画出现实的东西,要处理以上①②③④四个对象。
最后一个Render就是最后呈现的画面,这个画面要绑定到RenderWindow上Interactor,这里要在wx中的panel空间上显示,所以不能直接创建RenderWindow。
这里wx和vtk提供了一个接口,wxVTKRenderWindowInteractor,这个可以直接理解为创建了一个可以在wx中操作的Interactor,把render添加到这个Interactor中就可以显示了。
二 开始
直接上代码,其实非常简单。有过wxpython开发经验的话,应该很容易明白。
需要注意的是,一定要把wxVTKRenderWindowInteractor放到一个sizer里,否则不能随窗口改变大小。
wxVTKRenderWindowInteractor里面内置了绑定了很多事件,这一点很便于新手学习,当然也可以自己绑定事件。
class WxVTKScene(wx.Panel):
def __init__(self, parent, *args, **kwargs):
wx.Panel.__init__(self, parent, *args, **kwargs)
self.size = self.GetClientSize() # 获取父窗体尺寸
self.vtk_widget = wxVTKRenderWindowInteractor(self, -1, size=(self.size.width,self.size.height), flag=wx.EXPAND) # 创建VTK窗口
self.vtk_widget .SetPosition((0,0)) # 设置VTK位置
self.vtk_widget .Enable(1) # 启用VTK窗口
Sizer = wx.BoxSizer(wx.VERTICAL)
Sizer.Add(self.vtk_widget , 1, wx.EXPAND, 0)
self.SetSizer(Sizer)
Sizer.Fit(self)
self.Layout()
self.vtk_widget.Bind(wx.EVT_CHAR, self.onKeyDown) # 绑定键盘事件
self.Render()
def Render(self):
self.render.SetBackground(1.0, 1.0, 1.0) # 设置页面底部颜色值
self.render.SetBackground2(0.1, 0.2, 0.4) # 设置页面顶部颜色值
self.render.SetGradientBackground(1) # 开启渐变色背景设置
self.render_window = self.vtk_widget.GetRenderWindow()
self.iren = self.render_window.GetInteractor()
self.render_window.AddRenderer(self.render)
style = vtkInteractorStyleTrackballCamera()
self.iren.SetInteractorStyle(style)
camera = self.render.GetActiveCamera()
camera.ParallelProjectionOn()
self.render.ResetCamera()
Render() 函数是用来设置显示区域的,包括背景色和相机的相关设置。
三 显示图形
在前言里介绍了如何显示,接下来介绍一个自定义cube的例子,直接上代码。p是cube八个点的坐标,index是cube六个面对应点的索引。
def DrawCube(self):
p = [
[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 1, 0],
[0, 0, -1],
[1, 0, -1],
[0, 1, -1],
[1, 1, -1]
]
index = [
[0, 1, 3, 2],
[1, 5, 7, 3],
[5, 4, 6, 7],
[4, 0, 2, 6],
[4, 5, 1, 0],
[2, 3, 7, 6]
]
cube = vtk.vtkPolyData()
polys = vtk.vtkCellArray()
points = vtk.vtkPoints()
for i in range(8):
points.InsertPoint(i,p[i])
for i in range(6):
polys.InsertNextCell(4)
for j in range(4):
polys.InsertCellPoint(index[i][j])
cube.SetPoints(points)
cube.SetPolys(polys)
cubeMapper = vtkPolyDataMapper()
cubeMapper.SetInputData(cube)
cubeActor = vtkActor()
cubeActor.SetMapper(cubeMapper)
self.Render.AddActor(cubeActor)
直接调用上面的函数,就可以得到下面的画面。