#一、VTK简介及安装
##1.1 VTK介绍
Vtk(visualization toolkit)是一个开源的免费软件系统,主要用于三维计算机图形学、图像处理和可视化。Vtk是在面向对象原理的基础上设计和实现的,它的内核是用C++构建的,包含有大约250,000行代码,2000多个类,还包含有几个转换界面,因此也可以自由的通过Java,Tcl/Tk和Python各种语言使用vtk。
VTK是一个开放源码、自由获取的软件系统,全世界的数以千计的研究人员和开发人员用它来进行3D计算机图形,图像处理,可视化。VTK包含一个c++类库,众多的翻译接口层,包括Tcl/Tk,Java,Python。 Visualization Toolkit 是一个用于可视化应用程序构造与运行的支撑环境,它是在三维函数库OpenGL 的基础上采用面向对象的设计方法发展起来的,它将我们在可视化开发过程中会经常遇到的细节屏蔽起来,并将一些常用的算法封装起来。比如 Visualization Toolkit 将我们在表面重建中比较常见的MarchingCubes 算法封装起来,以类的形式给我们以支持,这样我们在对三维规则点阵数据进行表面重建时就不必再重复编写MarchingCubes 算法的代码,而直接使用Visualization Toolkit 中已经提供的vtkMarchingCubes 类。 Visualization Toolkit 是给从事可视化应用程序开发工作的研究人员提供直接的技术支持的一个强大的可视化开发工具。
##1.2 VTK在Python环境下安装
方法一(未亲手实践)、安装anaconda,使用conda install安装:
注意不同版本的Python对应不同的命令。
1)适用于python3(3.6以下)
install -n envA -c menpo vtk=7 python=3
or if you want to be more specific:
conda install -n envB -c menpo vtk=7 python=3.5
2)适用于python 2 (不过最近好多库都声明不支持python2了)
conda install -n envC vtk python=2
适用于3.6:
conda install -c clinicalgraphics vtk=7.1.0
以上的命令都可以不加版本号
方法二(已经实践):由于国内的镜像里没有vtk,所以直接用conda安装会非常慢,推荐下载whl文件后使用pip 安装。
提供一个下载VTK的whl文件的网址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#vtk
我是win7系统64位下,使用的python3.5,下载的是:
VTK 7.1.1 cp35 cp35m win_amd64.whl
然后进入下载目录,启动cmd或者window power shell,输入命令: pip install VTK-7.1.1-cp36-cp36m-win_amd64.whl完成安装。
安装完成后,检测是否安装成功,在spyder里输入
import vtk
这里提供一个检测的小代码:
1. import vtk
2.
3. cone_a=vtk.vtkConeSource()
4.
5. coneMapper = vtk.vtkPolyDataMapper()
6. coneMapper.SetInputConnection(cone_a.GetOutputPort())
7.
8. coneActor = vtk.vtkActor()
9. coneActor.SetMapper(coneMapper)
10.
11.
12. ren1= vtk.vtkRenderer()
13. ren1.AddActor( coneActor )
14. ren1.SetBackground( 0.1, 0.2, 0.4 )
15.
16. renWin = vtk.vtkRenderWindow()
17. renWin.AddRenderer( ren1 )
18. renWin.SetSize( 300, 300 )
19. renWin.Render()
20.
21. iren=vtk.vtkRenderWindowInteractor()
22. iren.SetRenderWindow(renWin)
23.
24. iren.Initialize()
25. iren.Start()
运行结果如下图:
#二、创建包含三维模型窗口的对话框
- 2.1 创建一个对话框
参考我的另外一篇博客,利用PyQt5创建一个对话框。
- 2.2 对话框中加入渲染窗口及三维模型
当上述对话框搭建好以后,可以输入下面的测试代码进行实验,会得到一个包含渲染窗口的对话框如下,并且可以用鼠标对三维模型进行简单的操作:
PyQt4版本使用以下代码:
#!/usr/bin/env python
import sys
import vtk
from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt4 import Qt
from PyQt4 import QtGui, QtCore
class test(Qt.QMainWindow):
"""Test class"""
def __init__(self, parent=None):
Qt.QMainWindow.__init__(self, parent)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
self.setWindowTitle(self.tr("PyQt4 VTK test"))
self.workspace = Qt.QWorkspace()
self.setCentralWidget(self.workspace)
self.frame = QtGui.QFrame(self.workspace)
self.hbox = QtGui.QHBoxLayout()
# create the widget
self.widget = QVTKRenderWindowInteractor(self.frame)
self.widget.Initialize()
self.widget.Start()
# if you dont want the 'q' key to exit comment this.
self.widget.AddObserver("ExitEvent", lambda o, e, a=app: a.quit())
self.cone = vtk.vtkConeSource()
self.cone.SetResolution(8)
self.coneMapper = vtk.vtkPolyDataMapper()
self.coneMapper.SetInput(self.cone.GetOutput())
self.coneActor = vtk.vtkActor()
self.ren.AddActor(self.coneActor)
self.renWin=self.widget.GetRenderWindow()
self.renWin.AddRenderer(self.ren)
self.hbox.addWidget(self.widget)
self.frame.setLayout(self.hbox)
self.workspace.addWindow(self.frame)
if __name__ == "__main__":
app = Qt.QApplication(sys.argv)
mainwindow = test()
mainwindow.show()
sys.exit(app.exec_())
若是PyQt5版本则使用以下代码(已经经过验证):
import sys
import vtk
from PyQt5 import QtCore, QtGui, QtWidgets
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class myMainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.frame = QtWidgets.QFrame()
self.vl = QtWidgets.QVBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.vl.addWidget(self.vtkWidget)
self.ren = vtk.vtkRenderer()
self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
# Create source
source = vtk.vtkConeSource()
source.SetCenter(0, 0, 0)
source.SetRadius(0.1)
source1 = vtk.vtkSphereSource()
source1.SetCenter(0, 0, 0)
source1.SetRadius(0.5)
# Create a mapper
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(source.GetOutputPort())
mapper1 = vtk.vtkPolyDataMapper()
mapper1.SetInputConnection(source1.GetOutputPort())
# Create an actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor1 = vtk.vtkActor()
actor1.SetMapper(mapper1)
self.ren.AddActor(actor)
self.ren.AddActor(actor1)
self.ren.ResetCamera()
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.show()
self.iren.Initialize()
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
if __name__ == "__main__":
app = QApplication(sys.argv)
window = myMainWindow()
sys.exit(app.exec_())