第一个 VTK Demo

认识 VTK 中的基本类型,使用 VTK 渲染一个圆锥

1. 认识 VTK 渲染管线

先了解几个VTK中的常用模板类型

模板类型 功能
vtkNew 在堆内存中分配 VTK object,是 vtkSmartPointer 的替代品。
vtkNamedColors 封装了VTK内置的命名颜色集合,提供RGB颜色定义,常用于可视化场景中的颜色配置。
vtkConeSource VTK可视化管线中的一个节点,它负责产生数据(输出类型为 vtkPolyData),供后续过滤器处理。
vtkPolyDataMapper 该类将 vtkPolyData 数据转换为几何图元,方便使用底层接口渲染,如 OpenGL。
需要将 vtkPolyData 的 output 连接到 vtkPolyDataMapper 的 input
vtkActor 演员” 是场景中所有可渲染对象的基类。
负责:绑定几何数据(通过 SetMapper)、管理外观属性(颜色、光照、纹理等)、应用变换矩阵(平移、旋转、缩放)
vtkRenderer VTK 渲染器,管理舞台(渲染场景)中的渲染操作,一个渲染器可以管理多个 Actor。
vtkRenderWindow 渲染窗口是最终的输出载体,负责:
管理一个或多个渲染器(通过 AddRenderer())、
控制窗口大小和位置、
处理操作系统级的窗口事件、
触发实际的渲染操作。
vtkCamera 可以理解为观察着的眼睛
vtkProp 一个基类,所有可以在渲染场景中存在的类型的基类。
vtkActor2D 继承自vtkProp,用于在渲染场景中显示二维对象。
vtkProp3D 继承自vtkProp,表示一个用于放置在渲染场景中的3D对象。
vtkActor 继承自vtkProp3D,表示渲染场景中的一个对象(几何形状和属性),支持矩阵变换。
vtkTextActor 用于实现文本的 actor。
vtkRenderWindowInteractor 继承自vtkObject,负责窗口交互,将鼠标/键盘/定时器消息路由至 vtkInteractorObserver 及其子类。
同时,vtkRenderWindowInteractor 还提供了对象拾取、渲染帧率控制以及头灯光源管理等交互功能。
vtkOrientationMarkerWidget 用于操控标记道具的2D控件
vtkInteractorObserver vtkInteractorObserver 是一个抽象基类,其子类用于观察由 vtkRenderWindowInteractor 触发的事件。这些子类通常是诸如 3D 控件之类的对象——它们能够与场景中的角色(actors)进行交互,或以交互方式探查场景信息。
vtkInteractorStyleTrackballCamera vtkInteractorStyleTrackballCamera 允许用户以交互方式操控(旋转、平移等)场景的视点——即相机。在轨迹球交互模式下,鼠标移动的幅度与特定鼠标绑定触发的相机运动成正比。例如,小幅度的左键移动会使相机围绕其焦点产生小幅旋转。对于三键鼠标:左键用于旋转,右键用于缩放,中键用于平移,Ctrl+左键用于自转,Shift+右键用于环境旋转(若鼠标按键较少,则Ctrl+Shift+左键用于缩放,Shift+左键用于平移)。

1.1. 使用 C++ API 渲染圆锥体

我们看一个简单的Demo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkConeSource.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>


int main(int, char*[])
{
    // 颜色对象。      
    vtkNew<vtkNamedColors> colors;

    // 创建了一个圆锥体数据源并设置其参数。  
    vtkNew<vtkConeSource> cone;  
    cone->SetHeight(3.0);        // 设置圆锥高度为3.0单位
    cone->SetRadius(1.0);        // 设置底面半径为1.0单位
    cone->SetResolution(10);     // 设置圆锥侧面由10个分段构成,应该叫做棱锥

    // 将 vtkPolyData 的 output 连接到 vtkPolyDataMapper 的 input。 
    vtkNew<vtkPolyDataMapper> coneMapper;
    coneMapper->SetInputConnection(cone->GetOutputPort());

    // 创建并配置一个VTK演员(vtkActor)对象。   
    vtkNew<vtkActor> coneActor;
    coneActor->SetMapper(coneMapper);                                              // 绑定几何数据
    coneActor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData()); // 管理外观属性

    // 创建并配置一个VTK渲染器。   
    vtkNew<vtkRenderer> ren1;     // vtkRenderer 实例,用于管理场景中的渲染操作
    ren1->AddActor(coneActor);    // 将之前创建的演员(coneActor)添加到渲染器中,一个渲染器可以管理多个演员
    ren1->SetBackground(colors->GetColor3d("MidnightBlue").GetData()); // 设置渲染器的背景颜色,

    // 创建并配置VTK渲染窗口
    vtkNew<vtkRenderWindow> renWin;    // 最终显示渲染结果的窗口
    renWin->AddRenderer(ren1);         // 将之前创建的渲染器添加到窗口,一个窗口可包含多个渲染器
    renWin->SetSize(300, 300);
    renWin->SetWindowName("Tutorial_Step1");

    // 锥体的连续旋转动画
    for (int i = 0; i < 360; ++i)
    {
      // 触发渲染窗口的渲染操作
      renWin->Render();                    

      // GetActiveCamera() 获取当前渲染器的主相机   
      // Azimuth(1) 表示绕观察点水平旋转 1 度 
      ren1->GetActiveCamera()->Azimuth(1); 
    }

    return EXIT_SUCCESS;
}

这里就讲一下,相机视角的旋转问题:
vtkCamera* GetActiveCamera();获取当前渲染器的活动相机。
void Azimuth(viskores::Float32 angleDegrees);旋转相机水平时视角。
既然有水平视角,那么就有垂直视角旋转,他们的关系如图:

1.2. 使用 Python API 渲染圆锥体

和C++过程一样。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import vtkmodules.vtkInteractionStyle  # 提供交互样式支持(如鼠标/键盘控制)
import vtkmodules.vtkRenderingOpenGL2  # 基于OpenGL 2.0的渲染引擎模块,必须导入的

from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkFiltersSources import vtkConeSource
from vtkmodules.vtkRenderingCore import (
    vtkActor,
    vtkPolyDataMapper,
    vtkRenderWindow,
    vtkRenderer
)

def main(argv):

    colors = vtkNamedColors()

    cone = vtkConeSource()
    cone.SetHeight(3.0)
    cone.SetRadius(1.0)
    cone.SetResolution(10)

    coneMapper = vtkPolyDataMapper()
    coneMapper.SetInputConnection(cone.GetOutputPort())

    coneActor = vtkActor()
    coneActor.SetMapper(coneMapper)
    coneActor.GetProperty().SetColor(colors.GetColor3d('MistyRose'))

    ren1 = vtkRenderer()
    ren1.AddActor(coneActor)
    ren1.SetBackground(colors.GetColor3d('MidnightBlue'))

    renWin = vtkRenderWindow()
    renWin.AddRenderer(ren1)
    renWin.SetSize(300, 300)
    renWin.SetWindowName('Tutorial_Step1')

    for i in range(0, 360):
        renWin.Render()
        ren1.GetActiveCamera().Azimuth(1)

if __name__ == '__main__':
    import sys

    main(sys.argv)

2. 资料链接

VTK官方Demo,循序渐进的示例程序。
Python Demo,Python 示例程序。
VTK接口文档,类型以及函数接口文档。
类文档,带有示例的类文档。

官方网站的下载页面有 6 下载文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
VTK-9.5.1.tar.gz                # 核心源码包

# 测试数据包,解压后就是 `VTK-x.x.x/.ExternalData/`  
VTKData-9.5.1.tar.gz            # 测试数据索引包, 告诉 CMake ExternalData 模块去哪里下载真正的测试输入 & 基准图像。
VTKDataFiles-9.5.1.tar.gz       # 和上面一样,但是包含了完整测试数据集,不用在线下载了。     

# 离线 HTML 文档包
vtkDocHtml-9.5.1.tar.gz         

# 这两个好像是旧版的测试数据包,不需要了
VTKLargeData-9.5.1.tar.gz   
VTKLargeDataFiles-9.5.1.tar.gz 

当然官网也提供了Python扩展包

comments powered by Disqus