欢迎访问宙启技术站
智能推送

使用vtkRenderWindowInteractor()实现鼠标绘制模型轮廓

发布时间:2023-12-26 06:51:55

VTK(Visualization Toolkit)是一个开源的、跨平台的图像处理和可视化库,可以用于创建交互式的3D图形应用程序。vtkRenderWindowInteractor是VTK中提供的一个用户交互窗口,可以响应用户的鼠标和键盘输入事件。

下面是一个使用vtkRenderWindowInteractor实现鼠标绘制模型轮廓的例子:

import vtk

class MouseInteractorStyle(vtk.vtkInteractorStyleTrackballCamera):
    def __init__(self, parent=None):
        self.AddObserver("LeftButtonPressEvent", self.on_left_button_press)
        self.AddObserver("LeftButtonReleaseEvent", self.on_left_button_release)
        self.AddObserver("MouseMoveEvent", self.on_mouse_move)
        self.painting = False

    def on_left_button_press(self, obj, event):
        self.OnLeftButtonDown()
        self.painting = True

    def on_left_button_release(self, obj, event):
        self.OnLeftButtonUp()
        self.painting = False

    def on_mouse_move(self, obj, event):
        if self.painting:
            self.GetInteractor().GetRenderWindow().SetDesiredUpdateRate(10)

            # 获取鼠标当前位置
            mouse_pos = self.GetInteractor().GetEventPosition()

            # 获取渲染窗口和相机
            render_window = self.GetInteractor().GetRenderWindow()
            renderer = render_window.GetRenderers().GetFirstRenderer()
            camera = renderer.GetActiveCamera()

            # 通过渲染器像素空间转换为世界坐标系空间
            picker = vtk.vtkWorldPointPicker()
            picker.Pick(mouse_pos[0], mouse_pos[1], 0, renderer)
            world_pos = picker.GetPickPosition()

            # 创建一个小球作为绘制轮廓
            sphere = vtk.vtkSphereSource()
            sphere.SetRadius(0.2)
            sphere.SetCenter(world_pos[0], world_pos[1], world_pos[2])

            # 创建一个mapper
            mapper = vtk.vtkPolyDataMapper()
            mapper.SetInputConnection(sphere.GetOutputPort())

            # 创建一个actor
            actor = vtk.vtkActor()
            actor.SetMapper(mapper)
            actor.GetProperty().SetColor(1, 0, 0)  # 设置小球颜色

            # 将actor添加到渲染器中
            renderer.AddActor(actor)
            render_window.Render()

            # 更新显示
            self.GetInteractor().GetRenderWindow().SetDesiredUpdateRate(0.001)

def main():
    # 加载模型
    reader = vtk.vtkSTLReader()
    reader.SetFileName("model.stl")

    # 创建mapper
    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputConnection(reader.GetOutputPort())

    # 创建actor
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)

    # 创建渲染器
    renderer = vtk.vtkRenderer()
    renderer.AddActor(actor)

    # 创建渲染窗口
    render_window = vtk.vtkRenderWindow()
    render_window.AddRenderer(renderer)

    # 创建交互器
    interactor = vtk.vtkRenderWindowInteractor()
    interactor.SetRenderWindow(render_window)

    # 设置交互器样式
    style = MouseInteractorStyle()
    interactor.SetInteractorStyle(style)

    # 启动交互器
    interactor.Initialize()
    interactor.Start()

if __name__ == '__main__':
    main()

在这个例子中,我们首先加载了一个模型(model.stl),然后创建了一个vtkRenderWindowInteractor对象作为用户交互窗口。我们还自定义了一个MouseInteractorStyle类继承自vtkInteractorStyleTrackballCamera,并重写了鼠标事件处理函数。

在on_left_button_press函数中,我们启用了绘制模式,并在on_left_button_release函数中禁用了绘制模式。当鼠标移动时,如果处于绘制模式,我们会获取当前鼠标位置,并通过vtkWorldPointPicker将其转换为世界坐标系空间。然后,我们创建了一个小球作为绘制轮廓,并将其添加到渲染器中。最后,我们更新显示并将渲染器附加到交互器中。

启动程序后,你可以使用鼠标左键在模型上绘制轮廓。每次按下鼠标左键并移动时,会在当前鼠标位置绘制一个小球,颜色为红色。