VTK交互式拾点——鼠标和按键

        利用点击鼠标左键来对三维网格模型进行拾点,是很简单方便的,但鼠标左键的功能不只是用来拾点的,很多交互式操作都需要鼠标点击。所以,可以加入按键事件,但我按一下键盘上的某个按键时,此时鼠标左键才进行拾点,代码如下:

        程序描述:

                任务:交互式拾取两个点,点1和点2

                操作:按键盘1键,此时用鼠标左键点击拾取点1

                           按键盘2键,此时用鼠标左键点击拾取点2

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.AddObserver('KeyPressEvent', self.key_press_event)  # 按键消息
        self.renderer = renderer
        self.sphereActor1 = vtkActor()  # 定义一个球形,用来标记第一个拾取点
        self.sphereActor2 = vtkActor()  # 定义一个球形,用来标记第二个拾取点
        self.mode = 0  # mode=0的时候表示不选点, mode=1的时候表示选第一个点, mode=2的选第二个点
        MarkWithSphere(self.sphereActor1, color=[1, 1, 0], renderer=self.renderer, bVis=False)
        MarkWithSphere(self.sphereActor2, color=[0, 1, 0], renderer=self.renderer, bVis=False)

    def leftButtonPressEvent(self, obj, event):

        if self.mode != 0:
            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)

        if self.mode == 1:
            self.sphereActor1.VisibilityOn()  # 显示球型
            self.sphereActor1.SetPosition(world_position)  # 将球型的中心设为拾取点的坐标
            self.mode = 0
        elif self.mode == 2:
            self.sphereActor2.VisibilityOn()  # 显示球型
            self.sphereActor2.SetPosition(world_position)  # 将球型的中心设为拾取点的坐标
            self.mode = 0

        self.OnLeftButtonDown()
        return

    def key_press_event(self, obj, event):
        key = self.GetInteractor().GetKeySym()
        # if key.lower() == "1" and self.mode == 0:   # 指定第一个点
        if key.lower() == "1":
            self.mode = 1
        elif key.lower() == "2":
            self.mode = 2
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()

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值