代码改变世界

详细介绍:VTK开发笔记(九):示例Cone6,使用3D交互控件,在Qt窗口中详解复现对应的Demo

2026-01-01 08:17  tlnshuju  阅读(1)  评论(0)    收藏  举报

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

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

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

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