VTK开发笔记(八):示例Cone5,交互器的实现方式,在Qt窗口中详解复现对应的Demo

若该文为原创文章,转载请注明出处

本文章博客地址:https://hpzwl.blog.csdn.net/article/details/154077570

长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...

OSG、VTK、OSGEARTH三维开发专栏(点击传送门)

上一篇:《VTK开发笔记(七):示例Cone4,一数据源多演员模式,在Qt窗口中详解复现对应的Demo

下一篇:敬请期待...

前言

本篇详细解析Cone5.exe,了解预定义的交互器操作。

Demo

交互器

概述

VTK(Visualization Toolkit)中的交互器(Interactor)是连接用户操作与可视化场景的核心组件,它负责处理鼠标、键盘等输入事件,并将这些事件转化为对场景中对象的操作(如旋转、缩放、平移等)。

在 VTK 中,交互器的核心作用是事件监听与响应,它连接了用户输入设备(鼠标、键盘)和可视化场景(如vtkRenderer渲染的图像)。其核心组成包括:

  • 交互器对象(如vtkRenderWindowInteractor):负责监听输入事件(如鼠标点击、移动、滚轮,键盘按键)。
  • 交互样式(vtkInteractorStyle及其子类):定义事件的响应逻辑(如鼠标左键拖动是旋转还是平移)。
  • 渲染窗口(vtkRenderWindow):交互器需要绑定到渲染窗口,以获取渲染的图像并处理用户输入。

工作流程

  • 初始化交互器:将交互器绑定到渲染窗口(SetRenderWindow()),并设置交互样式(SetInteractorStyle())。
  • 启动事件循环:通过Start()方法启动交互器的事件循环,开始监听用户输入。
  • 事件触发与处理
      用户操作(如鼠标拖动)被交互器捕获,转化为特定事件(如LeftButtonPressEvent、MouseMoveEvent)。
    交互样式(vtkInteractorStyle)中定义的对应事件处理函数被调用(如OnLeftButtonDown())。
    处理函数更新场景状态(如旋转相机vtkCamera的角度),并触发渲染窗口重绘(Render())。
  • 场景更新:渲染窗口根据新的状态重新绘制图像,用户看到交互后的效果。

常用交互器与交互样式

查看VTKMananger.h的枚举定义说明:

cpp 复制代码
/** 预定义的交互器类型
 *     操作对象(摄像机 vs 演员);交互连续性(平滑 Trackball vs 步进 Joystick);场景类型(图像、地形、通用 3D 等)。
 *     实际使用时,可根据具体场景选择合适的样式,或基于 vtkInteractorStyleUser 扩展自定义交互逻辑。 */
enum INTERACTOR_STYLE {
    // 基础交互器样式
    INTERACTOR_STYLE_TRACKBALL_CAMERA = 0x00,   //  摄像机       鼠标左键旋转、中键平移、右键 / 滚轮缩放,交互平滑连续(类似 "轨迹球" 效果),通用 3D 场景浏览,操作摄像机以改变观察视角。
    INTERACTOR_STYLE_TRACKBALL_ACTOR,           //  选中的演员    先点击选中演员,再通过鼠标左键旋转、中键平移、右键缩放该演员。仅修改单个对象的姿态,不改变摄像机位置。
    // 遥感式交互器样式
    INTERACTOR_STYLE_JOYSTICK_CAMERA,           //  摄像机       类似TrackballCamera,但交互是 "步进式"(拖动鼠标后松开才执行操作),而非连续平滑,需要精确控制交互幅度的场景。
    INTERACTOR_STYLE_JOYSTICK_ACTOR,            //  选中的演员    步进式操作单个演员,与 JoystickCamera 逻辑类似,但针对演员而非摄像机。
    // 图像与切片交互器样式
    INTERACTOR_STYLE_IMAGE,                     //  专为 2D/3D 图像(如 CT、MRI 切片)设计。交互方式:左键平移图像、右键缩放、键盘 / 下键切换切片层,默认禁用摄像机旋转(保持正交视角)。扩展功能:支持图像窗宽窗位调整(通过键盘或鼠标)。
    // 选择与区域操作样式
    INTERACTOR_STYLE_RUBBER_BAND_ZOOM,          //  核心功能:支持 "框选缩放"------ 拖动鼠标绘制矩形区域,场景自动缩放至该区域。适用场景:快速聚焦到局部区域(如病灶、细节)。
    INTERACTOR_STYLE_RUBBER_BAND_PICK,          //  支持框选区域内的对象(如演员、点集),配合拾取器(Picker)使用。
    INTERACTOR_STYLE_DRAW_POLYGON,              //  支持用鼠标绘制多边形区域,用于复杂区域的选择或裁剪。
    // 特殊场景与特殊场景样式
    INTERACTOR_STYLE_TERRAIN,                   //  专为地形数据(如高程图、地形模型)设计。交互方式:模拟 "在地形上行走",支持前后移动、左右转向,避免摄像机穿入地形。
    INTERACTOR_STYLE_FLIGHT,                    //  模拟 "飞行" 视角,通过鼠标控制飞行方向和速度,适合大规模场景(如城市、地形)浏览。
    INTERACTOR_STYLE_UNICAM,                    //  基于 "单摄像机" 模型,优化了 3D 交互的直观性,减少操作歧义。
    // 扩展与集成样式
    INTERACTOR_STYLE_USER,                      //  用于自定义交互逻辑的基类,可通过重写事件回调函数实现个性化操作。
    INTERACTOR_STYLE_SWITCH,                    //  支持动态切换多种交互器样式(如在 Trackball 和 Image 样式间切换)。
};

事件与自定义交互

VTK允许通过自定义交互样式或绑定回调函数,实现个性化的事件响应逻辑。

常用的事件类型

交互器支持的事件可分为鼠标事件、键盘事件、窗口事件等,例如:

  • 鼠标事件:LeftButtonPressEvent(左键按下)、MouseMoveEvent(鼠标移动)、MouseWheelForwardEvent(滚轮向前)。
  • 键盘事件:KeyPressEvent(按键按下)、KeyReleaseEvent(按键释放)。
  • 窗口事件:ConfigureEvent(窗口大小改变)、ExitEvent(退出事件循环)。

自定义交互的两种方式

继承vtkInteractorStyle并重写事件处理函数通过子类化交互样式,重写特定事件的处理方法(如OnLeftButtonDown、OnKeyPress),实现自定义逻辑。

自定义鼠标左键点击时输出坐标。

通过观察者模式绑定回调函数

使用AddObserver(eventName, callback)直接为交互器或交互样式绑定事件回调,无需子类化。

交互器与camera/actor 的联动

交互的本质是通过事件处理函数修改场景中的对象状态,最常见的是操作相机(改变视角)或 actor(改变位置 / 姿态):

  • 操作相机:通过vtkCamera的Azimuth()(水平旋转)、Elevation()(垂直旋转)、Dolly()(缩放)等方法实现。
  • 操作actor :通过vtkActor的SetPosition()、SetOrientation()等方法修改位置或旋转角度
      VTK交互器是用户与可视化场景交互的桥梁,其核心是交互器对象(监听事件)与交互样式(处理事件)的配合。通过预定义的交互样式可快速实现旋转、缩放等基础操作,而自定义交互则能满足复杂场景需求(如医学图像测量、特定对象选择等)。

高级交互功能

拾取

通过交互事件获取场景中被点击的对象(Actor、Cell、Point等),常用类:vtkCellPicker、vtkPointPicker。

cpp 复制代码
vtkSmartPointer<vtkCellPicker> pCellPicker = vtkSmartPointer<vtkCellPicker>::New();
// 将拾取器与交互器关联
pRenderWindowInteractor->SetPicker(pCellPicker); 

在事件响应中获取拾取结果

cpp 复制代码
// 获取鼠标位置
int* pos = pRenderWindowInteractor->GetEventPosition();
// 执行拾取
picker->Pick(pos[0], pos[1], 0, renderer); 
// 获取被拾取的Actor
vtkActor* pActor = picker->GetActor();

手势交互

VTK 支持触屏设备的手势事件(如捏合缩放、旋转),需使用vtkInteractorStyleMultiTouchCamera等样式。

Demo源码

VTKWidget.cpp

cpp 复制代码
void VTKWidget::test_demo7_createCone(VTKManager::INTERACTOR_STYLE interactorStyle)
{
    // 步骤一:创建圆锥体数据源
    vtkSmartPointer<vtkConeSource> pConeSource =
            VTKManager::createConeSource(0, 0, 0, 8, 30, 100);
    // 步骤二:创建多边形映射器
    vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper =
            VTKManager::createPolyDataMapper(pConeSource->GetOutputPort());
    // 步骤三:创建演员
    vtkSmartPointer<vtkActor> pActor =
            VTKManager::createActor(pPolyDataMapper, 1.0, 0.3882, 0.2784, 1.0);
    // 步骤四:创建渲染器
    vtkSmartPointer<vtkRenderer> pRenderer =
            VTKManager::createRenderer(pActor, 0.1, 0.2, 0.4);
    // 步骤五:渲染器添加到QVTKWidget渲染
    _pQVTKWidget->GetRenderWindow()->AddRenderer(pRenderer);

    // 步骤六:设置交互器
    vtkSmartPointer<vtkRenderWindowInteractor> pRenderWindowInteractor =
            VTKManager::createRenderWindowInteractor(_pQVTKWidget->GetRenderWindow(), interactorStyle);
}

VTKManager.h

cpp 复制代码
public:
    /** 预定义的交互器类型
     *     操作对象(摄像机 vs 演员);交互连续性(平滑 Trackball vs 步进 Joystick);场景类型(图像、地形、通用 3D 等)。
     *     实际使用时,可根据具体场景选择合适的样式,或基于 vtkInteractorStyleUser 扩展自定义交互逻辑。 */
    enum INTERACTOR_STYLE {
        // 基础交互器样式
        INTERACTOR_STYLE_TRACKBALL_CAMERA = 0x00,   //  摄像机       鼠标左键旋转、中键平移、右键 / 滚轮缩放,交互平滑连续(类似 "轨迹球" 效果),通用 3D 场景浏览,操作摄像机以改变观察视角。
        INTERACTOR_STYLE_TRACKBALL_ACTOR,           //  选中的演员    先点击选中演员,再通过鼠标左键旋转、中键平移、右键缩放该演员。仅修改单个对象的姿态,不改变摄像机位置。
        // 遥感式交互器样式
        INTERACTOR_STYLE_JOYSTICK_CAMERA,           //  摄像机       类似TrackballCamera,但交互是 "步进式"(拖动鼠标后松开才执行操作),而非连续平滑,需要精确控制交互幅度的场景。
        INTERACTOR_STYLE_JOYSTICK_ACTOR,            //  选中的演员    步进式操作单个演员,与 JoystickCamera 逻辑类似,但针对演员而非摄像机。
        // 图像与切片交互器样式
        INTERACTOR_STYLE_IMAGE,                     //  专为 2D/3D 图像(如 CT、MRI 切片)设计。交互方式:左键平移图像、右键缩放、键盘 / 下键切换切片层,默认禁用摄像机旋转(保持正交视角)。扩展功能:支持图像窗宽窗位调整(通过键盘或鼠标)。
        // 选择与区域操作样式
        INTERACTOR_STYLE_RUBBER_BAND_ZOOM,          //  核心功能:支持 "框选缩放"------ 拖动鼠标绘制矩形区域,场景自动缩放至该区域。适用场景:快速聚焦到局部区域(如病灶、细节)。
        INTERACTOR_STYLE_RUBBER_BAND_PICK,          //  支持框选区域内的对象(如演员、点集),配合拾取器(Picker)使用。
        INTERACTOR_STYLE_DRAW_POLYGON,              //  支持用鼠标绘制多边形区域,用于复杂区域的选择或裁剪。
        // 特殊场景与特殊场景样式
        INTERACTOR_STYLE_TERRAIN,                   //  专为地形数据(如高程图、地形模型)设计。交互方式:模拟 "在地形上行走",支持前后移动、左右转向,避免摄像机穿入地形。
        INTERACTOR_STYLE_FLIGHT,                    //  模拟 "飞行" 视角,通过鼠标控制飞行方向和速度,适合大规模场景(如城市、地形)浏览。
        INTERACTOR_STYLE_UNICAM,                    //  基于 "单摄像机" 模型,优化了 3D 交互的直观性,减少操作歧义。
        // 扩展与集成样式
        INTERACTOR_STYLE_USER,                      //  用于自定义交互逻辑的基类,可通过重写事件回调函数实现个性化操作。
        INTERACTOR_STYLE_SWITCH,                    //  支持动态切换多种交互器样式(如在 Trackball 和 Image 样式间切换)。
    };

VTKManager.cpp

cpp 复制代码
vtkSmartPointer<vtkRenderWindowInteractor> VTKManager::createRenderWindowInteractor(vtkRenderWindow *pRenderWindow, VTKManager::INTERACTOR_STYLE interactorStyle)
{
    // 步骤一:智能指针定义
    vtkSmartPointer<vtkRenderWindowInteractor> pRenderWindowInteractor;
    // 步骤二:智能指针实例化
    pRenderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    // 步骤三:智能指针定义
    vtkSmartPointer<vtkInteractorObserver> pInteractorObserver;
    // 步骤四:智能指针实例化
    switch (interactorStyle)
    {
    // 基础交互器样式
    case INTERACTOR_STYLE_TRACKBALL_CAMERA: //  摄像机       鼠标左键旋转、中键平移、右键 / 滚轮缩放,交互平滑连续(类似 "轨迹球" 效果),通用 3D 场景浏览,操作摄像机以改变观察视角。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
        break;
    case INTERACTOR_STYLE_TRACKBALL_ACTOR:  //  选中的演员    先点击选中演员,再通过鼠标左键旋转、中键平移、右键缩放该演员。仅修改单个对象的姿态,不改变摄像机位置。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleTrackballActor>::New();
        break;
    // 遥感式交互器样式
    case INTERACTOR_STYLE_JOYSTICK_CAMERA:  //  摄像机       类似TrackballCamera,但交互是 "步进式"(拖动鼠标后松开才执行操作),而非连续平滑,需要精确控制交互幅度的场景。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleJoystickCamera>::New();
        break;
    case INTERACTOR_STYLE_JOYSTICK_ACTOR:   //  选中的演员    步进式操作单个演员,与 JoystickCamera 逻辑类似,但针对演员而非摄像机。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleJoystickActor>::New();
        break;
    // 图像与切片交互器样式
    case INTERACTOR_STYLE_IMAGE:            //  专为 2D/3D 图像(如 CT、MRI 切片)设计。交互方式:左键平移图像、右键缩放、键盘 / 下键切换切片层,默认禁用摄像机旋转(保持正交视角)。扩展功能:支持图像窗宽窗位调整(通过键盘或鼠标)。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleImage>::New();
        break;
    // 选择与区域操作样式
    case INTERACTOR_STYLE_RUBBER_BAND_ZOOM: //  核心功能:支持 "框选缩放"------ 拖动鼠标绘制矩形区域,场景自动缩放至该区域。适用场景:快速聚焦到局部区域(如病灶、细节)。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleRubberBandZoom>::New();
        break;
    case INTERACTOR_STYLE_RUBBER_BAND_PICK: //  支持框选区域内的对象(如演员、点集),配合拾取器(Picker)使用。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleRubberBandPick>::New();
        break;
    case INTERACTOR_STYLE_DRAW_POLYGON:     //  支持用鼠标绘制多边形区域,用于复杂区域的选择或裁剪。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleDrawPolygon>::New();
        break;
    // 特殊场景与特殊场景样式
    case INTERACTOR_STYLE_TERRAIN:          //  专为地形数据(如高程图、地形模型)设计。交互方式:模拟 "在地形上行走",支持前后移动、左右转向,避免摄像机穿入地形。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleTerrain>::New();
        break;
    case INTERACTOR_STYLE_FLIGHT:           //  模拟 "飞行" 视角,通过鼠标控制飞行方向和速度,适合大规模场景(如城市、地形)浏览。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleFlight>::New();
        break;
    case INTERACTOR_STYLE_UNICAM:           //  基于 "单摄像机" 模型,优化了 3D 交互的直观性,减少操作歧义。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleUnicam>::New();
        break;
    // 扩展与集成样式
    case INTERACTOR_STYLE_USER:              //  用于自定义交互逻辑的基类,可通过重写事件回调函数实现个性化操作。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleUser>::New();
        break;
    case INTERACTOR_STYLE_SWITCH:           //  支持动态切换多种交互器样式(如在 Trackball 和 Image 样式间切换)。
        pInteractorObserver = vtkSmartPointer<vtkInteractorStyleSwitch>::New();
        break;
    default:
        break;
    }
    // 步骤五:设置交换器
    pRenderWindowInteractor->SetInteractorStyle(pInteractorObserver);
    // 步骤六:设置处理的渲染窗口
    pRenderWindowInteractor->SetRenderWindow(pRenderWindow);
    // 步骤七:初始化
    pRenderWindowInteractor->Initialize();
    // 步骤八:开始
    pRenderWindowInteractor->Start();

    return pRenderWindowInteractor;
}

工程模板v1.6.0

入坑

入坑一:不出现渲染窗口

问题

不出现渲染窗口

尝试

隐藏之后,会显示渲染窗口,所以设置了交互就不行了。

原因

检查代码,忘记初始化:

解决

上一篇:《VTK开发笔记(七):示例Cone4,一数据源多演员模式,在Qt窗口中详解复现对应的Demo

下一篇:敬请期待...

本文章博客地址:https://hpzwl.blog.csdn.net/article/details/154077570

相关推荐
Predestination王瀞潞7 小时前
WEB前端技术基础(第四章:JavaScript-网页动态交互语言)
前端·javascript·交互
进击ing小白17 小时前
QGraphicsEffect控件添加特效
qt
迷失的walker17 小时前
【Qt C++ QSerialPort】QSerialPort fQSerialPortInfo::availablePorts() 执行报错问题解决方案
数据库·c++·qt
B站计算机毕业设计之家17 小时前
计算机视觉:pyqt5+yoloV5目标检测平台 python实战 torch 目标识别 大数据项目 目标跟踪(建议收藏)✅
深度学习·qt·opencv·yolo·目标检测·计算机视觉·1024程序员节
一个处女座的程序猿21 小时前
LLMs之PE:PromptX(将 AI 智能体从通用助手转变为具备行业/角色能力的交互平台)的简介、安装和使用方法、案例应用之详细攻略
人工智能·交互·agent·promptx
上去我就QWER1 天前
解锁Qt元对象系统:C++编程的超强扩展
c++·qt
莫听穿林打叶声儿1 天前
关于Qt开发UI框架Qt Advanced Docking System测试
开发语言·qt·ui
freedom_1024_1 天前
【c++ qt】QtConcurrent与QFutureWatcher:实现高效异步计算
java·c++·qt
KL41801 天前
【QT】窗口
c++·qt