在VTK中通过程序员手动点击鼠标左键来实现在三维网格模型上的选点,并将该点用球型进行可视化,同时输出该点的三维坐标以及ID
代码:
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonCore import vtkMinimalStandardRandomSequence
from vtkmodules.vtkFiltersSources import vtkSphereSource
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleTrackballCamera
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkPolyDataMapper,
vtkPropPicker,
vtkProperty,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer
)
import vtk
''' 对Actor的属性进行设置 '''
def SetupActor(actor, color=None, opa=None, pos=None, bVis=None, renderer=None):
if color != None: # 设置颜色
actor.GetProperty().SetColor(color[0], color[1], color[2])
if opa != None: # 设置透明度
actor.GetProperty().SetOpacity(opa)
if pos != None: # 设置位置
actor.SetPosition(pos)
if bVis != None: # 设置可见性
actor.SetVisibility(bVis)
if renderer != None: # 加入渲染器
renderer.AddActor(actor)
''' 使用小球对坐标进行可视化 '''
def MarkWithSphere(actor, color=None, opa=None, pos=None, bVis=None, renderer=None):
sphere = vtk.vtkSphereSource()
sphere.Update()
sphereMapper = vtkPolyDataMapper()
sphereMapper.SetInputConnection(sphere.GetOutputPort())
actor.SetMapper(sphereMapper)
SetupActor(actor, color, opa, pos, bVis, renderer)
class MouseInteractorHighLightActor(vtkInteractorStyleTrackballCamera):
def __init__(self, renderer):
self.AddObserver("LeftButtonPressEvent", self.leftButtonPressEvent) # 鼠标左键消息
self.renderer = renderer
self.sphereActor = vtkActor() # 定义一个球形,用来显示拾取点
MarkWithSphere(self.sphereActor, color=[1, 1, 0], renderer=self.renderer, bVis=False)
def leftButtonPressEvent(self, obj, event):
picker = vtk.vtkPointPicker() # 指定拾取器
pos = self.GetInteractor().GetEventPosition() # 获取事件二维屏幕坐标
ren = self.GetDefaultRenderer() # 记得预先通过SetDefaultRenderer指定渲染器
picker.Pick(pos[0], pos[1], 0, ren)
world_position = picker.GetPickPosition() # 获取拾取点的三维坐标
print(world_position)
id = picker.GetPointId()
print(id)
self.sphereActor.VisibilityOn() # 显示球型
self.sphereActor.SetPosition(world_position) # 将球型的中心设为拾取点的坐标
self.OnLeftButtonDown()
return
def main():
colors = vtkNamedColors()
# 渲染和窗口
renderer = vtkRenderer()
renderer.SetBackground(colors.GetColor3d('SteelBlue'))
renwin = vtkRenderWindow()
renwin.AddRenderer(renderer)
renwin.SetSize(640, 480)
renwin.SetWindowName('HighlightPickedActor')
# 交互器
interactor = vtkRenderWindowInteractor()
interactor.SetRenderWindow(renwin)
# add the custom style
style = MouseInteractorHighLightActor(renderer)
style.SetDefaultRenderer(renderer)
interactor.SetInteractorStyle(style)
reader = vtk.vtkOBJReader()
reader.SetFileName("00OMSZGW_upper.obj")
reader.Update()
mesh = reader.GetOutput()
mapper = vtkPolyDataMapper()
mapper.SetInputData(mesh)
actor = vtkActor()
actor.SetMapper(mapper)
renderer.AddActor(actor)
# Start
interactor.Initialize()
renwin.Render()
interactor.Start()
if __name__ == '__main__':
main()
运行结果: