若该文为原创文章,转载请注明出处
本文章博客地址: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