本文最后更新于 30 天前,其中的信息可能已经有所发展或是发生改变。
在VTK (Visualization Toolkit)中,如果需要创建二维文字标签可以使用vtkTextActor
很方便的实现,但是二维文字标签使用窗口上相对的二维坐标,是独立于显示三维模型窗口的。
那么想要同三维模型一起显示在窗口内,共同使用三维坐标系,就要考虑使用三维文字标签,VTK提供了几种方式来实现三维场景中的文字标签功能。
1. vtkVectorText + vtkFollower / vtkActor
利用vtkVectorText
创建向量文本,使用vtkActor
加载到窗口上,如果需要始终面向镜头,就可以使用vtkFollower
类很方便的实现。
很多情况都是需要将三维文字标签始终面向相机,以方便操作者观察的,因此vtkVectorText
+ vtkFollower
是很为常用的方法。、
优点:
- 文字标签会被转换为真正的3D几何体,支持碰撞等三维操作,也可以很方便地应用所有标准的3D变换
- 兼容性高,适用于VTK旧版本
- 使用
vtkFollower
可以让文字始终面向相机
缺点:
- 性能较低,文本转换为多边形数据后,顶点数较多,渲染开销较二维的更大
- 仅支持ASCII字符
- 字体样式较为单一
// 创建文字几何
vtkNew<vtkVectorText> textSource;
textSource->SetText("Hello VTK!");
// 创建映射器
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(textSource->GetOutputPort());
// 创建actor
vtkNew<vtkActor> textActor;
textActor->SetMapper(mapper);
textActor->GetProperty()->SetColor(1, 0, 0); // 设置颜色
// 如果需要文字始终面向相机,使用vtkFollower代替vtkActor
vtkNew<vtkFollower> follower;
follower->SetMapper(mapper);
follower->SetCamera(renderer->GetActiveCamera());
2. vtkTextActor3D
VTK 7.1及以上版本提供了专门的3D文本Actor,是vtkTextActor
三维版本,轻便快捷,性能更好,但不易设置面向镜头。
优点:
- 简单易用,适合快速的静态标注
- 支持复杂字体和Unicode,支持更多语言和符号
- 支持更丰富的文本属性设置
- 渲染效率高,是基于GPU加速的2D文本渲染,渲染起来更轻量
缺点:
- 不支持3D几何交互,文本是作为2D图层叠加在3D场景上,无法直接参与物理模拟
- 面朝方向固定,不易设置面向镜头
vtkNew<vtkTextActor3D> textActor;
textActor->SetInput("Hello VTK 3D!");
textActor->GetTextProperty()->SetColor(1, 0, 0);
textActor->GetTextProperty()->SetFontSize(24);
textActor->SetPosition(10, 20, 30);
renderer->AddActor(textActor);
3. vtkBillboardTextActor3D
vtkBillboardTextActor3D
同样可以让文字标签始终面向相机,但其只能保持固定大小,不随距离缩放,不符合三维模型的物理效果。
vtkNew<vtkBillboardTextActor3D> textActor;
textActor->SetInput("Fixed Size Text");
textActor->GetTextProperty()->SetColor(0, 1, 0);
textActor->SetPosition(50, 50, 50);
renderer->AddActor(textActor);
4. vtkOpenGLTextActor
对于最新版本的VTK,存在使用OpenGL2后端的vtkOpenGLTextActor
vtkNew<vtkOpenGLTextActor> textActor;
textActor->SetInput("OpenGL2 Text");
textActor->GetTextProperty()->SetColor(0, 0, 1);
textActor->SetDisplayPosition(100, 100);
renderer->AddActor2D(textActor);