第04章 02 VTK管道的执行过程与类型
在VTK(Visualization Toolkit)中,可视化管道的执行过程是实现数据可视化的核心。VTK的管道系统通过一系列数据处理模块(称为算法)和数据对象组成,这些模块通过输入和输出端口连接,形成一个有向非循环图(DAG)。管道的执行方式包括显式执行、隐式执行和条件执行。以下将详细论述这三种执行方式及其特点,并通过示例说明。
1. 显式执行
1.1. 概述
显式执行是指用户在代码中明确调用某个管道节点的Update()
方法,强制该节点及其下游节点执行数据处理。显式执行通常用于调试或需要精确控制管道执行顺序的场景。
1.2. 执行过程
- 用户调用某个算法模块(如过滤器、映射器)的
Update()
方法。 - 该模块及其下游模块依次执行数据处理。
- 数据从输入端流入,经过处理后依次传递到下游模块。
1.3. 示例
假设有一个简单的VTK管道,包含数据源、过滤器和映射器:
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
int main() {
// 创建数据源
vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetRadius(5.0);
// 显式执行数据源
sphereSource->Update();
// 创建映射器
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
// 创建Actor
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// 创建渲染器和窗口
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
// 添加Actor到渲染器
renderer->AddActor(actor);
// 启动渲染窗口
renderWindow->Render();
interactor->Start();
return 0;
}
在这个例子中,sphereSource->Update()
是显式执行的调用。调用后,sphereSource
生成球体数据并传递给映射器。
2. 隐式执行
2.1. 概述
隐式执行是指在管道的某个节点需要数据时,VTK自动触发其上游节点的执行。隐式执行是VTK管道的默认行为,通常用于效率优化和简化代码。
2.2. 执行过程
- 当某个节点需要数据时(如渲染器需要映射器的数据),它会检查输入数据是否是最新的。
- 如果输入数据不是最新的,则自动触发上游节点的
Update()
方法。 - 数据从上游节点依次向下游节点传递。
2.3. 示例
在隐式执行的情况下,用户不需要显式调用Update()
,VTK会自动完成管道的执行。以下是上一个例子的简化版本:
int main() {
// 创建数据源
vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetRadius(5.0);
// 创建映射器
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
// 创建Actor
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// 创建渲染器和窗口
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
// 添加Actor到渲染器
renderer->AddActor(actor);
// 启动渲染窗口
renderWindow->Render();
interactor->Start();
return 0;
}
在这个例子中,sphereSource->Update()
未显式调用,但当渲染器需要映射器的数据时,VTK会自动触发sphereSource
的执行。
3. 条件执行
3.1. 概述
条件执行是指管道的某个节点是否执行取决于某些条件(如数据的修改、用户设置的阈值等)。VTK支持通过条件判断来控制管道的执行,以实现动态更新或优化计算。
3.2. 执行过程
- 在某个节点中定义执行条件(如参数变化、数据变化)。
- 如果条件满足,则执行该节点及其下游节点。
- 如果条件不满足,则跳过该节点的执行。
3.3. 示例
假设有一个带有阈值条件的过滤器,只有在用户设置的阈值发生变化时才执行:
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkThreshold.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
int main() {
// 创建数据源
vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetRadius(5.0);
// 创建阈值过滤器
vtkSmartPointer<vtkThreshold> thresholdFilter = vtkSmartPointer<vtkThreshold>::New();
thresholdFilter->SetInputConnection(sphereSource->GetOutputPort());
thresholdFilter->SetLowerThreshold(0.5); // 设置阈值
// 创建映射器
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(thresholdFilter->GetOutputPort());
// 创建Actor
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// 创建渲染器和窗口
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
// 添加Actor到渲染器
renderer->AddActor(actor);
// 启动渲染窗口
renderWindow->Render();
interactor->Start();
return 0;
}
在这个例子中,vtkThreshold
过滤器是否执行取决于用户设置的阈值。如果阈值未发生变化,则过滤器不会重新执行。
4. 总结
VTK的管道执行方式包括显式执行、隐式执行和条件执行,分别适用于不同的场景:
- 显式执行:用于调试或精确控制管道的执行顺序。
- 隐式执行:VTK默认的执行方式,自动触发管道的执行,简化代码。
- 条件执行:根据特定条件决定是否执行某个节点,动态更新或优化计算。
通过灵活的执行方式,VTK的管道系统能够高效地处理复杂的数据可视化任务。