python vtk 关于STL图像的旋转与缩放及事件监听
Vtk,(visualization toolkit)是一个开源的免费软件系统,主要用于三维计算机图形学、图像处理和可视化。Vtk是在面向对象原理的基础上设计和实现的,它的内核是用C++构建的,包含有大约250,000行代码,2000多个类,还包含有几个转换界面,因此也可以自由的通过Java,Tcl/Tk和Python各种语言使用vtk。以下介绍VTK对于STL图像的基本操作
基础概念
数据源 resource: cone = vtk.vtkConeSource()
映射器 mapper:coneMapper = vtk.vtkPolyDataMapper()
映射器添加数据源: coneMapper.SetInput( cone.GetOutput() )
演员 actor: coneActor = vtk.vtkActor()
演员添加映射器:coneActor.SetMapper( coneMapper )
绘制器 renderer: vtk.vtkRenderer()
绘制器添加演员:renderer.AddActor( coneActor )
绘制窗口 win:vtk.vtkRenderWindow()
绘制窗口添加绘制器:renWin.AddRenderer( renderer )
窗口读取绘制器生成的图形: renWin.Render()
极简示例
import vtk
# 箭头源
arrow_source = vtk.vtkArrowSource()
# 映射器
mapper = vtk.vtkPolyDataMapper()
# 映射器添加数据源
mapper.SetInputConnection(arrow_source.GetOutputPort())
# 演员
actor = vtk.vtkActor()
# 演员添加映射器
actor.SetMapper(mapper)
# 绘制器
ren = vtk.vtkRenderer()
# 绘制器添加演员
ren.AddActor(actor)
# 绘制窗口
renWin = vtk.vtkRenderWindow()
# 绘制窗口添加绘制器
renWin.AddRenderer(ren)
# 创建窗口交互器
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.Initialize()
# 窗口读取绘制器生成的图形
renWin.Render()
iren.Start()
结果
读取文件
文件类型 | 读取方法 |
STL | vtkSTLReader() |
SLC | vtkSLCReader() |
VTP | vtkXMLPolyDataReader() |
UnstructuredGrid | vtkNamedColors() |
ExodusData | vtkExodusIIReader() |
示例
def read_data(file_name):
reader = vtk.vtkSTLReader()
reader.SetFileName(file_name)
return reader
图像旋转
绕()轴旋转 | 方法 |
X | actor.RotateX(angle) |
Y | actor.RotateY(angle) |
Z | actor.RotateZ(angle) |
整体旋转
transform.RotateWXYZ(angle, x, y, z)
x,y,z旋转(0,1)表示是否旋转
import vtk
arrow_source = vtk.vtkArrowSource()
mapper = vtk.vtkPolyDataMapper()
transform = vtk.vtkTransform()
transform.RotateWXYZ(90, 0, 0, 1)
transformFilter = vtk.vtkTransformPolyDataFilter()
transformFilter.SetTransform(transform)
transformFilter.SetInputConnection(arrow_source.GetOutputPort())
transformFilter.Update()
mapper.SetInputConnection(transformFilter.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
ren = vtk.vtkRenderer()
ren.AddActor(actor)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
renWin.Render()
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.Initialize()
renWin.Render()
iren.Start()
结果
设置演员初始方向
def set_origin(actor, x, y, z):
actor.SetOrientation(x, y, z)
缩放
def set_scale(x, y, z):
actor.SetScale(x, y, z)
平移
def add_position(x, y, z):
actor.AddPosition(x, y, z)
平面切割
def cut(file_name):
reader = read_data(file_name)
# 定义切割平面
clipPlane = vtk.vtkPlane()
clipPlane.SetNormal(1.0, -1.0, -1.0)
clipPlane.SetOrigin(0.0, 0.0, 0.0)
# 平面切割三维数据
clipper = vtk.vtkClipPolyData()
clipper.SetInputConnection(reader.GetOutputPort())
clipper.SetClipFunction(clipPlane)
clipper.InsideOutOn() # ?
# 定义mapper和actor
superMapper = vtk.vtkPolyDataMapper()
superMapper.SetInputConnection(clipper.GetOutputPort())
superActor = vtk.vtkActor()
# 设置偏转角度
set_origin(superActor, -50, -75, 120)
superActor.SetMapper(superMapper)
superActor.GetProperty().SetColor(colors.GetColor3d("Cyan"))
only_show(superActor)
原始图片
平面切割后图片
鼠标事件监听
# 监听事件
class MyEvent(vtk.vtkInteractorStyleTrackballCamera):
def __init__(self, parent=None):
self.AddObserver("MiddleButtonPressEvent", self.middle_button_press_event)
self.AddObserver("MiddleButtonReleaseEvent", self.middle_button_release_event)
self.AddObserver("LeftButtonPressEvent", self.left_button_press_event)
self.AddObserver("LeftButtonReleaseEvent", self.left_button_release_event)
self.AddObserver("RightButtonPressEvent", self.right_button_press_event)
self.AddObserver("RightButtonReleaseEvent", self.right_button_release_event)
def middle_button_press_event(self, obj, event):
print("Middle Button pressed")
self.OnMiddleButtonDown()
return
def middle_button_release_event(self, obj, event):
print("Middle Button released")
self.OnMiddleButtonUp()
return
def left_button_press_event(self, obj, event):
print("Left Button pressed")
self.OnLeftButtonDown()
return
def left_button_release_event(self, obj, event):
print("Left Button released")
self.OnLeftButtonUp()
return
def right_button_press_event(self, obj, event):
print("right Button pressed")
self.OnRightButtonDown()
return
def right_button_release_event(self, obj, event):
print("right Button released")
self.OnLeftButtonUp()
return
# 引入上一段代码调用
iren.SetInteractorStyle(MyEvent())
结果