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

多视口
概述
VTK(Visualization Toolkit)中的多视口(Multi-Viewport)是一种在单个渲染窗口中同时显示多个独立视图的技术,广泛用于对比数据、展示不同视角或多维度分析结果。
- 视口(Viewport):渲染窗口中用于绘制图像的矩形区域,通过标准化坐标(范围[0,1])定义位置和大小,例如(xmin, ymin, xmax, ymax)。
- 多视口:在一个vtkRenderWindow中划分多个不重叠或部分重叠的视口,每个视口对应一个vtkRenderer(渲染器),可独立渲染不同数据、视角或样式。
核心组件及关系
实现多视口需以下关键类,其关系如下:
- vtkRenderWindow:顶级窗口容器,负责管理显示设备(如屏幕),可包含多个vtkRenderer。
- vtkRenderer:每个渲染器对应一个视口,定义渲染区域(SetViewport()),并包含待渲染的vtkActor(演员)、vtkCamera(相机)等。
- vtkActor:关联几何数据(vtkPolyData)和属性(vtkProperty),定义渲染对象的外观。
- vtkRenderWindowInteractor:处理用户交互(如旋转、缩放),需与vtkRenderWindow绑定。
vtkRenderWindow → 包含多个 vtkRenderer(每个设置独立视口)→ 每个vtkRenderer包含 vtkActor + vtkCamera 等。
视口重叠与层级
若视口坐标重叠,后添加到vtkRenderWindow的vtkRenderer会覆盖先添加的(可通过SetLayer()设置层级,层数高的在上)。
联动交互
通过回调函数(vtkCommand)实现多视口相机联动,例如旋转一个视口的模型时,其他视口同步更新视角:
class CameraCallback
: public vtkCommand {
public:
static CameraCallback* New() {
return new CameraCallback;
}
void Execute(vtkObject* caller, unsigned long eventId, void* callData) override {
vtkRenderer* ren = static_cast<vtkRenderer*>
(caller);
vtkCamera* cam = ren->
GetActiveCamera();
// 同步其他渲染器的相机
ren2->
SetActiveCamera(cam);
ren3->
SetActiveCamera(cam);
renWin->
Render();
}
};
// 绑定到渲染器的相机更新事件
ren1->
AddObserver(vtkCommand::ModifiedEvent, cameraCallback);
动态调整视口
可通过vtkRenderer::SetViewport()实时修改视口大小和位置(需调用renWin->Render()刷新)。
多数据对比
在不同视口渲染同一数据的不同处理结果(如原始图像与滤波后图像、CT 的不同断层),辅助分析。
多视口的实现步骤
步骤一:创建渲染器添加渲染和数据
定义了2个视口:

步骤二:设置背景色和视口范围

步骤三:将视口设置到渲染窗口上即可

Demo源码
VTKWidget.cpp
void VTKWidget::test_demo5_createCone()
{
// 步骤一:创建圆锥体数据源
vtkSmartPointer<vtkConeSource> pConeSource =
VTKManager::createConeSource(0, 0, 0, 10, 30, 10);
// 步骤二:创建多边形映射器
#if 0
vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper =
VTKManager::createPolyDataMapper(pConeSource);
#else
vtkSmartPointer<vtkPolyDataMapper> pPolyDataMapper =
VTKManager::createPolyDataMapper(pConeSource->
GetOutputPort());
#endif
// 步骤三:创建演员
vtkSmartPointer<vtkActor> pActor =
VTKManager::createActor(pPolyDataMapper);
// 步骤四:创建渲染器1,2
vtkSmartPointer<vtkRenderer> pRenderer =
VTKManager::createRenderer(pActor,
0.1, 0.2, 0.4,
0, 0, 0.5, 1.0);
vtkSmartPointer<vtkRenderer> pRenderer2 =
VTKManager::createRenderer(pActor,
0.2, 0.2, 0.4,
0.5, 0, 1.0, 1.0);
// 步骤五:渲染器添加到QVTKWidget渲染
_pQVTKWidget->
GetRenderWindow()->
AddRenderer(pRenderer);
_pQVTKWidget->
GetRenderWindow()->
AddRenderer(pRenderer2);
// 步骤六:过程循环的方式实现旋转
QElapsedTimer elapsedTimer;
for(int index = 0; index <
360; index++)
{
LOG << index;
if(!isVisible())
{
continue;
}
// 渲染一次
_pQVTKWidget->
GetRenderWindow()->
Render();
elapsedTimer.start();
while(elapsedTimer.elapsed() <
10)
{
qApp->
processEvents();
}
if(!isVisible())
{
continue;
}
// 渲染器相机绕焦点旋转
VTKManager::rotateAzimuth(pRenderer, 1);
// 渲染器相机绕焦点旋转
VTKManager::rotateAzimuth(pRenderer2, 2);
}
}
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)
{
// 步骤一:智能指针定义
vtkSmartPointer<vtkActor> pActor;
// 步骤二:智能指针实例化
pActor = vtkSmartPointer<vtkActor>
::New();
// 步骤三:设置映射器
pActor->
SetMapper(pPolyDataMapper);
return pActor;
}
vtkSmartPointer<vtkRenderer>
VTKManager::createRenderer(vtkActor *pActor, double r, double g, double b, double x1, double y1, double x2, double y2)
{
// 步骤一:智能指针定义
vtkSmartPointer<vtkRenderer> pRenderer;
// 步骤二:智能指针实例化
pRenderer = vtkSmartPointer<vtkRenderer>
::New();
// 步骤三:设置映射器
pRenderer->
AddActor(pActor);
// 步骤四:设置背景色
pRenderer->
SetBackground(r, g, b);
// 步骤五:设置视口范围(注意三维视口范围[0,1]
pRenderer->
SetViewport(x1, y1, x2, y2);
return pRenderer;
}
void VTKManager::rotateAzimuth(vtkRenderer *pRenderer, double angle)
{
pRenderer->
GetActiveCamera()->
Azimuth(angle);
}
工程模板v1.4.0

上一篇:《VTK开发笔记(五):示例Cone2,熟悉观察者模式,在Qt窗口中详解复现对应的Demo》
下一篇:敬请期待…
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/151959697
浙公网安备 33010602011771号