若该文为原创文章,转载请注明出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/155466101
长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...
OSG、VTK、OSGEARTH三维开发专栏(点击传送门)
上一篇:《VTK开发笔记(八):示例Cone5,交互器的实现方式,在Qt窗口中详解复现对应的Demo》
下一篇:敬请期待...
前言
本篇详细解析Cone6.exe,了解预定义的交互器操作。
Demo

VTK的3D交互控件
概述
VTK(Visualization Toolkit)提供了丰富的3D交互控件,用于实现对 3D 场景的旋转、平移、缩放等操作,以及自定义交互逻辑。这些控件是构建交互式可视化应用的核心组件。
常用交互样式和功能
vtkInteractorStyleTrackballCamera(默认样式)
- 功能:通过操作相机(Camera)来改变视图,适用于观察整个场景。
- 交互方式:左键拖拽:旋转相机(场景绕视角中心旋转)。中键/滚轮:缩放(相机靠近/远离场景)。右键拖拽:平移相机(场景整体平移)。
vtkInteractorStyleTrackballActor
- 功能:直接操作场景中的演员(Actor),而非相机,适用于编辑单个对象的位置和姿态。
- 交互方式:左键拖拽:旋转选中的Actor。中键/滚轮:缩放选中的Actor(改变其大小)。右键拖拽:平移选中的Actor。
- 注意:需要先通过SetCurrentActor()指定要操作的Actor。
vtkInteractorStyleJoystickCamera与vtkInteractorStyleJoystickActor
- 功能:与Trackball 系列类似,但交互方式更接近"摇杆"逻辑------鼠标移动的方向和距离直接映射为旋转/平移的增量,而非持续拖拽。
- 适用场景:需要更精准控制的交互(如医疗影像中的精细调整)。
vtkInteractorStyleFlight
- 功能:模拟飞行视角,通过鼠标和键盘控制相机的移动方向和速度,适用于漫游大型场景(如地形、城市模型)。
- 交互方式:左键拖拽:改变飞行方向。键盘W/S:加速/减速。键盘A/D:左右平移。
vtkInteractorStyleImage
- 功能:专为2D图像(如切片数据)设计,支持切片的平移、缩放和层切换(适用于CT/MRI等医学影像的断层浏览)。
- 交互方式:左键拖拽:平移图像。中键/ 滚轮:缩放图像。 右键拖拽:切换切片(沿 Z 轴方向)。
vtkBoxWidget交互控件
概述
创建一个可交互的立方体框(6个面、12条边、8个顶点)。通过拖拽顶点、边或面来调整立方体的大小和姿态。实时获取立方体的变换矩阵,用于控制关联对象的位置、旋转和缩放。框选场景中的部分对象进行操作。对体数据或网格模型进行立方体裁剪。交互式调整对象的包围盒(Bounding Box)。作为变换工具,控制模型的缩放、旋转和平移。
交互操作
vtkBoxWidget提供了丰富的交互操作,通过鼠标拖拽不同组件实现:
- 拖拽顶点:调整立方体的角点位置,改变局部大小。
- 拖拽边:沿边的方向拉伸或压缩立方体。
- 拖拽面:沿面的法线方向移动整个面,改变立方体的整体尺寸。
- Ctrl + 拖拽面/边/顶点:保持立方体的比例缩放。
- Shift + 拖拽:仅平移立方体(不改变大小和方向)。
- 右键点击:弹出上下文菜单,支持重置、对齐轴等操作(需开启默认 Representation)。
关键参数与方法

Demo实现步骤
步骤一:创建圆锥数据源


步骤二:创建多边形映射


步骤三:创建演员


步骤四:创建渲染器


步骤五:设置渲染器到渲染窗口

步骤六(关键):设置boxWidget交互器


Demo源码
VTKWidget.cpp
cpp
void VTKWidget::test_demo8_createCone(VTKManager::INTERACTOR_STYLE interactorStyle)
{
// 步骤一:创建圆锥体数据源
vtkSmartPointer<vtkConeSource> pConeSource =
VTKManager::createConeSource(0, 0, 0, 10, 30, 100);
// 步骤二:创建多边形映射器
vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper =
VTKManager::createPolyDataMapper(pConeSource->GetOutputPort());
// 步骤三:创建演员
vtkSmartPointer<vtkActor> pActor =
VTKManager::createActor(pPolyDataMapper, 0.5, 0.3, 0.2);
// 步骤四:创建渲染器
vtkSmartPointer<vtkRenderer> pRenderer =
VTKManager::createRenderer(pActor, 0.1, 0.1, 0.1);
// 步骤五:设置渲染器到QVTKWidget渲染窗口
_pQVTKWidget->GetRenderWindow()->AddRenderer(pRenderer);
// 步骤六:设置交互器
VTKManager::createRenderWindowInteractorBoxWidget(_pQVTKWidget->GetRenderWindow(),
pActor,
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<vtkConeSource> VTKManager::createConeSource(double x, double y, double z, double r, int h, int n)
{
// 步骤一:智能指针定义
vtkSmartPointer<vtkConeSource> pConeSource;
// 步骤二:智能指针实例化
pConeSource = vtkSmartPointer<vtkConeSource>::New();
// 步骤三:设置中心坐标
pConeSource->SetCenter(x, y, z);
// 步骤三:设置半径
pConeSource->SetRadius(r);
// 步骤四:设置圆锥的高度
pConeSource->SetHeight(h);
// 步骤五:设置圆锥球体的经度分辨率,即横向的切片数量(横向/水平精细度)
pConeSource->SetResolution(n);
return pConeSource;
}
vtkSmartPointer<vtkPolyDataMapper> VTKManager::createPolyDataMapper(vtkAlgorithmOutput *pAlgorithmOutput)
{
// 步骤一:智能指针定义
vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper;
// 步骤二:智能指针实例化
pPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
// 步骤三:设置
pPolyDataMapper->SetInputConnection(pAlgorithmOutput);
return pPolyDataMapper;
}
vtkSmartPointer<vtkActor> VTKManager::createActor(vtkPolyDataMapper *pPolyDataMapper, double r, double g, double b)
{
// 步骤一:智能指针定义
vtkSmartPointer<vtkActor> pActor;
// 步骤二:智能指针实例化
pActor = vtkSmartPointer<vtkActor>::New();
// 步骤三:设置映射器
pActor->SetMapper(pPolyDataMapper);
// 步骤四:设置颜色
pActor->GetProperty()->SetColor(r, g, b);
return pActor;
}
vtkSmartPointer<vtkRenderer> VTKManager::createRenderer(std::vector<vtkActor *> vectorPActor, double r, double g, double b)
{
// 步骤一:智能指针定义
vtkSmartPointer<vtkRenderer> pRenderer;
// 步骤二:智能指针实例化
pRenderer = vtkSmartPointer<vtkRenderer>::New();
// 步骤三:设置映射器
for(int index = 0; index < vectorPActor.size(); index++)
{
pRenderer->AddActor(vectorPActor.at(index));
}
// 步骤四:设置背景色
pRenderer->SetBackground(r, g, b);
return pRenderer;
}
vtkSmartPointer<vtkRenderWindowInteractor> VTKManager::createRenderWindowInteractorBoxWidget(vtkRenderWindow *pRenderWindow, vtkActor *pActor, VTKManager::INTERACTOR_STYLE interactorStyle)
{
// 步骤一:智能指针定义、实例化
vtkSmartPointer<vtkRenderWindowInteractor> 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);
// 步骤五:智能指针定义、实例化
vtkSmartPointer<vtkBoxWidget> pBoxWidget =
vtkSmartPointer<vtkBoxWidget>::New();
// 步骤六:设置boxWidget的交互器
pBoxWidget->SetInteractor(pRenderWindowInteractor);
// 步骤七:设置位置因子,位置因子控制小部件相对于小部件输入边界框的初始大小。
pBoxWidget->SetPlaceFactor(1.25);
// 步骤八:box添加控制的演员
pBoxWidget->SetProp3D(pActor);
// 步骤九:
pBoxWidget->PlaceWidget();
// 步骤十:定义观察者回调处理类、智能指针定义、实例化
class vtkMyCallback : public vtkCommand
{
public:
static vtkMyCallback *New() {
return new vtkMyCallback;
}
void Execute(vtkObject *caller, unsigned long, void*) override
{
// 变换矩阵
vtkTransform *pTransform = vtkTransform::New();
// 获取被观察(这里是对BoxWidget添加观察者,所以BoxWidget是被观察者)
vtkBoxWidget *pBoxWidget = reinterpret_cast<vtkBoxWidget*>(caller);
// 获取被观察者的举证
pBoxWidget->GetTransform(pTransform);
// 讲BoxWidget下的3D模型都设置为其变换的矩阵
pBoxWidget->GetProp3D()->SetUserTransform(pTransform);
// 删除
pTransform->Delete();
}
};
vtkSmartPointer<vtkMyCallback> pMyCallback = vtkSmartPointer<vtkMyCallback>::New();
// 步骤十一:添加时间观察回调
pBoxWidget->AddObserver(vtkCommand::InteractionEvent, pMyCallback);
// 步骤十二:启用BoxWidget
pBoxWidget->On();
// 步骤十三:初始化交互器
pRenderWindowInteractor->Initialize();
// 步骤十四:开始进入交互器时间循环
pRenderWindowInteractor->Start();
return pRenderWindowInteractor;
}
工程模板v1.7.0

上一篇:《VTK开发笔记(八):示例Cone5,交互器的实现方式,在Qt窗口中详解复现对应的Demo》
下一篇:敬请期待...
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/155466101