因为实验室需要所以必须用到vtk,加上个人对于数据可视化和三维建模感兴趣,所以有必要整理一份vtk的学习资料,以备之后的学习和巩固。
vtk 全称visualization Toolkit 即可视化工具包,他是一个开源的,跨平台的,可自由获取的支持并行处理的图形应用函数库。
对于vtk的一些基础组成比如图模型子系统和可视化管道子系统,以及其中的绘制窗口绘制器,交互器,道具,映射器,和特性等概念下面这个文档介绍的还行:https://wenku.baidu.com/view/e14ab3d033d4b14e852468c1.html
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
int main() {
vtkSmartPointer<vtkCylinderSource> cylinder= vtkSmartPointer<vtkCylinderSource>::New();
cylinder->SetHeight(3.0);
cylinder->SetRadius(1.0);
cylinder->SetResolution(10);
vtkSmartPointer<vtkPolyDataMapper>cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
vtkSmartPointer<vtkActor>cylinderActor = vtkSmartPointer<vtkActor>::New();
cylinderActor->SetMapper(cylinderMapper);
vtkSmartPointer<vtkRenderer>renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(cylinderActor);
renderer->SetBackground(0.1,0.2,0.4);
vtkSmartPointer<vtkRenderWindow>renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(renderer);
renWin->SetSize(300,300);
vtkSmartPointer<vtkRenderWindowInteractor>iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
vtkSmartPointer<vtkInteractorStyleTrackballCamera>style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
iren->SetInteractorStyle(style);
iren->Initialize();
iren->Start();
return 0;
}
vtk的一些规则:vtk对类的命名规则都是小写的vtk开头每个类的关键字首字母大写。
程序中有许多vtkSmartPointer,这是VTK的类实例化对象的基本用法。因为VTK里每个类的构造函数都定义为保护成员,所以常用的C++中定义语句在vtk中是不可取的。
采用以下两种方式构造vtk对象:
vtkSmartPointer<vtkPolyDataMapper>cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
或者:
vtkRenderWindow* renWin = vtkRenderWindow::New();
同时切记:使用New()定义变量时,在其生命周期结束前使用Delete()函数释放内存!
我个人觉得vtk对象的构造方式类似如下的做法:
#include
using namespace std;
class A {
public:
int a;
static A* New(){//采用静态成员函数New()得到该类的实例化对象
return new A;
}
protected:
A(int b=10):a(b){}//构造函数为保护成员
};
int main() {
A* c = A::New();
cout << c->a;
return 0;
}
从语法上来讲,一个函数被声明为protected或者private,那么这个函数就不能从“外部”直接被调用了。
对于protected的函数,子类的“内部”的其他函数可以调用之。
而对于private的函数,只能被本类“内部”的其他函数说调用。
这篇文章对这个问题做了简单的描述:https://www.cnblogs.com/this-543273659/archive/2011/08/02/2125487.html
关于构造函数与析构函数的保护权限可以看这篇文章的介绍:
http://blog.csdn.net/zxjluohe/article/details/42217491
还有一些解释:
1.至于为什么这个类的构造函数设置为保护,是因为有纯虚函数的类都是抽象类,抽象类不能实例化,因此这么写可以提醒程序员不要new。
2.这些类都不能让你直接实例化而是由系统调用所以constructor设成protected。
3.构造函数是保护成员 你就没有办法 new ClassName。
回到代码的学习:
1.vtkSmartPointer类 : 这是vtk里的智能指针类。
使用方式:
vtkSmartPointer<指向对象类型名称> 指针变量名= vtkSmartPointer<指向对象类型名称>::New();
2.vtkRenderWindow类: 是一个或多个绘制器在其上进行绘制的窗口的抽象基类。
vtkSmartPointer<vtkRenderWindow>renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(renderer);//调用AddRenderer()方法添加vtkRenderer类型绘制器
renWin->SetSize(300,300);//调用方法SetSize() 设置窗口的大小,以像素为单位
3.vtkCylinderSource类 : 该类派生自vtkPloyDataAlogrithm (poly是聚的意思)
主要是生成一个中心在渲染场景原点的柱体。这个柱体的数据类型是vtkPloyData。
cylinder->SetHeight(3.0);//设置柱体的高
cylinder->SetRadius(1.0);//设置柱体的横截面半径
cylinder->SetResolution(10);//设置柱体横截面的等多边形边数
4.vtkPolyDataMapper类: 字面意思就是 vtk 聚数据 映射器。
该类用于渲染多边形几何数据(vtkPolyData),该类派生自vtkMapper 将输入数据转换为几何图元(点,线,多边形)进行渲染。Mapper是可视化管线的末端。
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
//这里就是从cylinder得到输出数据再将其输入到cylinderMapper。
SetInputConnection()输入数据接口,GetOutputPort()输出数据接口。
5.vtkActor类: 该类派生自vtkProp类 (prop-支柱)
vtkProp类是所有的2D和3D道具的抽象基类。包含可见性,方向,大小和位置信息。
渲染场景中数据的可视化表达是通过vtkProp的子类负责的。比如渲染这个柱体,柱体的数据是vtkPloyData类型的,数据要在场景中渲染,不是直接把数据加载到渲染场景当中,而是以vtkProp形式存在于场景当中的。
三维空间中渲染对象最常用的vtkProp子类是vtkActor(负责场景中的几何数据) 和vtkVolume(负责场景中的体数据)。
prop依赖于两个对象:一个是Mapper(vtkMapper)对象,负责存放数据和渲染信息,另一个是属性(vtkProperty)对象负责控制颜色,不透明度等参数。
另外,vtkActor 还可以设置纹理(vtkTexture)对象,用于纹理贴图。
vtkSmartPointer<vtkActor>cylinderActor = vtkSmartPointer<vtkActor>::New();
cylinderActor->SetMapper(cylinderMapper);
//将cylinderActor的Mapper(vtkMapper)对象设置为cylinderMapper。
6.vtkRenderer 类:负责管理场景的渲染过程。
组成场景的对象包括:
vtkSmartPointerrenderer = vtkSmartPointer::New();
renderer->AddActor(cylinderActor);//该方法用于将Prop类型对象添加到渲染场景当中
renderer->SetBackground(0.1,0.2,0.4);//用RGB格式设置背景颜色
7.vtkRenderWindowInteractor 类: 提供平台独立的响应鼠标,键盘和时钟事件的交互机制。
通过观察者/命令模式将监听到的事件交由vtkInteractorObserver 或其子类如vtkInteractorStyle 处理。
他们监听这些事件消息,并且完成旋转,拉伸和缩放等运动控制。
vtkSmartPointer<vtkRenderWindowInteractor>iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
//消息是通过渲染窗口捕获的,所以必须给交互器设置渲染窗口。
vtkSmartPointer<vtkInteractorStyleTrackballCamera>style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
iren->SetInteractorStyle(style);
//定义交互器的交互样式。
iren->Initialize();//为处理窗口事件做准备,交互器工作之前必须调用这个方法初始化。
iren->Start();//该方法表示开始进入事件响应循环,交互器处于等待状态,等待用户交互事件发生。必须先调用Initialize()。
8.vtkInteractorStyleTrackballCamera类: 交互器的一种样式。父类为vtkInteractorStyle.
vtkSmartPointer<vtkInteractorStyleTrackballCamera>style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
iren->SetInteractorStyle(style);
VTK与观看舞台剧演出做对比。
整个大剧院<—->vtkRenderWindow的渲染窗口。
剧院中舞台<—->vtkRenderer的渲染场景。
舞台上演员<—->vtkActor的的渲染对象。
表演中互动<—->vtkRenderWindowInteractor的交互。
交互的方式<—->vtkInteractorSyle的交互器样式。
演员的特性<—->vtkActor的不同属性vtkProperty。
观众的视角<—->vtkCamera。
下图加深理解:
这是接触vtk的第一步,后序还需要加深各个类的理解。