vtk学习之路—第一章

基本学习目标:

因为实验室需要所以必须用到vtk,加上个人对于数据可视化和三维建模感兴趣,所以有必要整理一份vtk的学习资料,以备之后的学习和巩固。

vtk是什么:

vtk 全称visualization Toolkit 即可视化工具包,他是一个开源的,跨平台的,可自由获取的支持并行处理的图形应用函数库
对于vtk的一些基础组成比如图模型子系统和可视化管道子系统,以及其中的绘制窗口绘制器,交互器,道具,映射器,和特性等概念下面这个文档介绍的还行:https://wenku.baidu.com/view/e14ab3d033d4b14e852468c1.html

第一个vtk程序:

#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学习之路—第一章_第1张图片

程序学习:

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 类:负责管理场景的渲染过程。
组成场景的对象包括:

  1. Prop
  2. 照相机vtkCamera
  3. 光照vtkLight
    这些都被整合到一个vtkRenderer对象当中,一个vtkRendererWindow中可以有多个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学习之路—第一章_第2张图片

总结:

这是接触vtk的第一步,后序还需要加深各个类的理解。

你可能感兴趣的:(vtk)