6.1.2 vtkPolyData数据源讨论与数据创建

1.VTKPolyData源数据总结

1之前的实例中,我们利用VTKConeSource源数据创建了一个棱锥。实际上VTK内部提供可以写数据源类来快速获取简单的图形数据。下面给出了最常见的几种VTKPolyData数据源类:

6.1.2 vtkPolyData数据源讨论与数据创建_第1张图片

2.vtkPolyData数据的创建


前面多采用图像或者VTK合成源数据进行讨论。在这里,我们希望深入底层,显示地定义一个点集合和一个单元集合。
点集合定义了VTKPolyData的几何数据;单元集合定义了点的拓扑结构。每个单元由点的索引而非坐标来定义。这样能够减少数据的存储空间。
单元的类型可以是点、三角形、矩形、多边形等基本图元(注意:只有定义了单元数据才能显示该图形数据)。这需要根据实际情况来定义相应的图元。
下面的实例演示了一个简单的VTKPolyData数据的创建过程:

#include"vtkSmartPointer.h"
#include"vtkPoints.h"
#include"vtkPolygon.h"
#include"vtkTriangle.h"
#include"vtkCellArray.h"
#include"vtkPolyData.h"
#include"vtkPolyDataMapper.h"
#include"vtkActor.h"
#include"vtkRenderer.h"
#include"vtkRenderWindow.h"
#include"vtkRenderWindowInteractor.h"

int main(){

	vtkSmartPointer pts = vtkSmartPointer::New();//顺序地添加点
	pts->InsertNextPoint(0.0, 0.0, 0.0);
	pts->InsertNextPoint(1.0, 0.0, 0.0);
	pts->InsertNextPoint(1.0, 1.0, 0.0);
	pts->InsertNextPoint(0.0, 1.0, 0.0);
	pts->InsertNextPoint(2.0, 0.0, 0.0);
	//利用定义的5个坐标点定义一个多边形单元,vtkPolygon继承自vtkCell类,表示一个多边形单元
	vtkSmartPointerpolygon = vtkSmartPointer::New();
	polygon->GetPointIds()->SetNumberOfIds(4);//设置点数
	polygon->GetPointIds()->SetId(0, 0);//此索引必须在vtkPoints中的点索引
	polygon->GetPointIds()->SetId(1, 1);//setId为指定的点设置索引
	polygon->GetPointIds()->SetId(2, 2);
	polygon->GetPointIds()->SetId(3, 3);
	polygon->GetPointIds()->SetId(4, 4);

	vtkSmartPointertriangle = vtkSmartPointer::New();//三角形的点数是固定的不需要设置
	triangle->GetPointIds()->SetId(0, 1);
	triangle->GetPointIds()->SetId(1, 2);
	triangle->GetPointIds()->SetId(2, 4);

	vtkSmartPointer cells = vtkSmartPointer::New();
	cells->InsertNextCell(polygon);
	cells->InsertNextCell(triangle); //设置拓扑结构
	//合成数据
	vtkSmartPointer polygonPolyData = vtkSmartPointer::New();
	polygonPolyData->SetPoints(pts);
	polygonPolyData->SetPolys(cells);

	vtkSmartPointer mapper = vtkSmartPointer::New();
	mapper->SetInputData(polygonPolyData);

	vtkSmartPointer actor = vtkSmartPointer::New();
	actor->SetMapper(mapper);

	vtkSmartPointerrender = vtkSmartPointer::New();
	render->AddActor(actor);
	render->SetBackground(0.0, 0.0, 0.0);

	vtkSmartPointer rw = vtkSmartPointer::New();
	rw->AddRenderer(render);
	rw->SetSize(320, 240);
	rw->SetWindowName("creating polydata structure");

	vtkSmartPointer rwi = vtkSmartPointer::New();
	rwi->SetRenderWindow(rw);
	rwi->Render();
	rwi->Start();

	return 0;
}

运行结果如下:

6.1.2 vtkPolyData数据源讨论与数据创建_第2张图片

vtkPoints用于存储点集合。通过InserNextPoint()函数可以顺序地为其添加点,并返回点的索引,索引从0开始。另外,还可以通过函数SetNumberofPoints()来指定其点的个数,然后调用SetPoint()函数为对应索引点设置坐标。代码中含有5个坐标点。
利用定义的5个坐标点的索引定义一个VTKPolygon多边形单元。vtkPolygon继承自vtkCell类,表示一个多边形单元。定义vtkPolygon单元时,需要指定组成改单元的点数(这里指定了四个点,所以定义的是四边形)。vtkPolygon内部定义了一个vtkIdList对象,该对象存储了点索引集合。通过调用vtkList类的SetNumberOfIds()函数可以设置点数,SetId则可以为指定的点设置索引,注意该索引必须是vtkPoints中的点索引。在该示例代码中利用四个点构成了一个四边形,利用三个点构成了一个三角形。
VTK中定义了大量的单元类,这些类都继承自vtkCell,需要根据实际情况选择使用。这里面,我只对单元类型为三角形和多边形的图形进行了分析,这通常也被称为网格(Mesh)。在一个多边形网格模型中,连接网格点的称为边,每个单元由一系列的边顺序连接而成,也被称为面片。
vtkCellArray用于存储所有的单元数据,InsertNextCell()函数一次插入定义的单元。只有点数据和单元数据都定义完毕才能通过下面的函数添加到vtkPolyData中:

void SetPoints(vtkPoints*);
void SetPolys(vtkCellArray*p);

需要注意的是,SetPolys()接受的是多边形单元数组,如果单元类型为顶点、线段或者三角形带的话,则需要调用如下函数:

void SetVerts(vtkCellArray* v);
void SetLines(vtkCellArray* l);
void SetStrips(vtkCellArray* s);

参考资料:

1.《The Visualization Toolkit – AnObject-Oriented Approach To 3D Graphics (4th Edition)》
2. 张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

所用软件:vtk7.0+visual studio 2013
注:此文知识学习笔记,仅记录完整程序和实现结果,具体原理参见:

https://blog.csdn.net/www_doling_net/article/details/8541534

https://blog.csdn.net/shenziheng1/article/category/6114053/4

你可能感兴趣的:(VTK)