VTK图形图像开发进阶-学习笔记 03 VTK的基本数据结构

3.1可视化数据的基本特点

(1)离散性

(2)数据具有规则或者不规则的结构(结构化与非结构化)

(3)数据具有维度

3.2 数据对象和数据集

3.2.1 vtkDataObject

VTK中,数据一般以数据对象(Data Object,类vtkDataObjiect)的形式表现,这是VTK里可视化数据最常用的表达形式。数据对象是数据的集合,数据对象表现的数据是可以被可视化管线处理的数据,只有当数据对象被组织成一种结构后,才能被VTK提供的可视化算法所处理。

3.2.2 vtkDataSet

将数据对象组织成一种结构并且赋予相应的属性值,就形成了数据集(Dataset)

vtkDataSet由两部分组成,即组织结构以及与组织结构相关联的属性数据

vtkDataSet的组织结构由拓扑结构和集合结构两部分组成。拓扑结构描述了对象的构成形式,几何结构描述了对象的空间位置关系。

点数据所定义的一系列座标点构成了vtkDataSet数据集的几何结构;点数据的连接形成单元数据,由单元数据形成了数据集的拓扑结构。

/****************************************************/
/*  Examples/Chap03/3.2_TrianglePoints.cpp     */
/****************************************************/

#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataWriter.h>

int main(int argc, char* argv[])
{

	// 创建点数据
	vtkSmartPointer<vtkPoints> points =
				vtkSmartPointer<vtkPoints>::New();
	points->InsertNextPoint(1.0, 0.0, 0.0);
	points->InsertNextPoint(0.0, 0.0, 0.0);
	points->InsertNextPoint(0.0, 1.0, 0.0);

	// 创建vtkPolyData类型数据,vtkPolyData派生自vtkPointSet
	// vtkPointSet是vtkDataSet子类,即vtkPolyData是一种数据集
	vtkSmartPointer<vtkPolyData> polyData =
		vtkSmartPointer<vtkPolyData>::New();

	// 将创建的点数据加入到vtkPolyData数据里
	polyData->SetPoints(points);

	//将vtkPolyData类型的数据写入到一个vtk文件,保存位置是工程当前目录
	vtkSmartPointer<vtkPolyDataWriter> writer =
		vtkSmartPointer<vtkPolyDataWriter>::New();
	writer->SetFileName("triangle.vtk");
	writer->SetInputData(polyData);
	writer->Write();

	return 0;

}

/****************************************************/
/*  Examples/Chap03/3.2_TriangleVertices.cpp     */
/****************************************************/

#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataWriter.h>

int main(int argc, char* argv[])
{

	// 创建点座标
	double X[3] = { 1.0, 0.0, 0.0 };
	double Y[3] = { 0.0, 0.0, 0.0 };
	double Z[3] = { 0.0, 1.0, 0.0 };

	// 创建点数据以及在每个点座标上加入顶点(Vertex)类型的单元
	// vtkPointSet是vtkDataSet子类,即vtkPolyData是一种数据集
	vtkSmartPointer<vtkPoints> points =
						vtkSmartPointer<vtkPoints>::New();
	vtkSmartPointer<vtkCellArray> vertices =
		vtkSmartPointer<vtkCellArray>::New();

	for (unsigned int i = 0; i < 3; ++i)
	{
		// 定义用于存储点索引的中间变量,vtkIdType就相当于int long等类型
		vtkIdType pid[1];

		// 把每个点座标加入vtkPoints中,InsertNextPoints()返回加入的点的索引号
		// 下面需要使用这个索引号来创建顶点类型的单元
		pid[0] = points->InsertNextPoint(X[i], Y[i], Z[i]);

		// 在每个座标点上分别创建一个顶点,顶点是单元(Cell)里的一种类型
		vertices->InsertNextCell(1, pid);

	}
	// 创建vtkPolyData对象
	vtkSmartPointer<vtkPolyData> polyData =
		vtkSmartPointer<vtkPolyData>::New();

	// 指定数据集的几何结构(由points指定)以及数据集的拓扑结构(由vertices指定)
	polyData->SetPoints(points);
	polyData->SetVerts(vertices);

	//将生成的数据集写入到TriangleVerts.vtk文件,保存位置是工程当前目录
	vtkSmartPointer<vtkPolyDataWriter> writer =
		vtkSmartPointer<vtkPolyDataWriter>::New();
	writer->SetFileName("TriangleVerts.vtk");
	writer->SetInputData(polyData);
	writer->Write();

	return 0;

}

/****************************************************/
/*  Examples/Chap03/3.2_TriangleGeometryLines.cpp     */
/****************************************************/

#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkLine.h>
#include <vtkPolyData.h>
#include <vtkPolyDataWriter.h>

int main(int argc, char* argv[])
{

	// 创建三个座标点
	vtkSmartPointer<vtkPoints> points =
		vtkSmartPointer<vtkPoints>::New();
	points->InsertNextPoint(1.0, 0.0, 0.0); // 返回第一个点的ID:0
	points->InsertNextPoint(0.0, 0.0, 0.0); // 返回第一个点的ID:1
	points->InsertNextPoint(0.0, 1.0, 0.0); // 返回第一个点的ID:2
	
	// 每两个座标点之间分别创建一条线
	// SetId()的第一个参数是线段的端点ID,第二个参数是连接的点ID
	vtkSmartPointer<vtkLine> line0 =
		vtkSmartPointer<vtkLine>::New();
	line0->GetPointIds()->SetId(0, 0);
	line0->GetPointIds()->SetId(1,1);

	vtkSmartPointer<vtkLine> line1 =
		vtkSmartPointer<vtkLine>::New();
	line1->GetPointIds()->SetId(0, 1);
	line1->GetPointIds()->SetId(1, 2);

	vtkSmartPointer<vtkLine> line2 =
		vtkSmartPointer<vtkLine>::New();
	line2->GetPointIds()->SetId(0, 2);
	line2->GetPointIds()->SetId(1, 0);

	// 创建单元数组,用于存储以上创建的线段
	vtkSmartPointer<vtkCellArray> lines =
		vtkSmartPointer<vtkCellArray>::New();
	lines->InsertNextCell(line0);
	lines->InsertNextCell(line1);
	lines->InsertNextCell(line2);

	// 创建vtkPolyData对象
	vtkSmartPointer<vtkPolyData> polyData =
		vtkSmartPointer<vtkPolyData>::New();

	// 指定数据集的几何结构(由points指定)以及数据集的拓扑结构(由lines指定)
	polyData->SetPoints(points);
	polyData->SetVerts(lines);

	//将生成的数据集写入到TriangleVerts.vtk文件,保存位置是工程当前目录
	vtkSmartPointer<vtkPolyDataWriter> writer =
		vtkSmartPointer<vtkPolyDataWriter>::New();
	writer->SetFileName("TriangleLines.vtk");
	writer->SetInputData(polyData);
	writer->Write();

	return 0;

}

3.3 单元类型

数据集由一个或多个单元组成,VTK支持线性和非线性类型的单元。一系列有序的点按指定类型连接所定义的结构就是单元,单元是VTK可视化系统的基础。

这些顺序连接的点定义了单元的拓扑结构,而点的座标定义了单元的几何结构。

单元是由单元的类型(如六面体)和构成单元的顶点列表两部分构成的

3.3.1 线性单元

单元类型的线性与非线性的划分主要是以插值函数为依据的,对于线性单元,采用的是线性或者常量插值函数。

VTK单元的类型定义在vtkCellType.h文件里,线性单元类型如下:

1)VTK_VERTEX。顶点

2)VTK_POLY_VERTEX。多顶点

3)VTK_LINE。直线

4)VTK_POLY_LINE。折线

5)VTK_TRIANGLE 三角形

5)VTK_TRIANGLE_STRIP 三角形条带

7)VTK_QUAD。四边形,二维的基本类型

8)VTK_PIXEL。二维的基本类型

9)VTK_POLYGON。多边形,二维的基本类型

10)VTK_TETRA。四面体,三维的基本类型

11)VTK_HEXAHEDRON。六面体,三维的基本类型

12)VTK_VOXEL。三维的基本类型

13)VTK_WEDGE。契形,三维的基本类型

14)VTK_PYRAMID 。角椎体

15)VTK_PENTAGONAL_PRISM 。五棱柱

16)VTK_HEXAGONAL_PRISM。六角柱


 

 

3.3.2 非线性单元

3.4 属性数据

属性数据是与数据集的组织结构相关联的信息。

组织结构包括几何结构和拓扑结构,几何结构由点数据定义,拓扑结构由单元数据定义。

属性数据通常是与数据集的点数据或者单元数据相关联,但有时属性数据也可能与组成单元的某些成分相关联,如单元数据的某条边或某个面。

属性数据主要用于描述数据集的属性特征,对数据集的可视化实质上就是对属性数据的可视化。

VTK中,用vtkPointData类和vtkCellData类表达数据集属性,他们是类vtkDataSetAttributes(vtkDataSetAttributes派生自vtkFieldData)的子类,构成数据集的每个点(或单元)和属性数据之间存在一对一的关系。

3.4.1 标量数据

/****************************************************/
/*  Examples/Chap03/3.4_VTKConceptScalars.cpp     */
/****************************************************/

#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkDoubleArray.h>
#include <vtkPolyData.h>

int main(int , char* [])
{

	// 创建点集数据:包含两个座标点
	vtkSmartPointer<vtkPoints> points =
		vtkSmartPointer<vtkPoints>::New();
	points->InsertNextPoint(0, 0, 0); // 返回第一个点的ID:0
	points->InsertNextPoint(1, 0, 0); // 返回第一个点的ID:1

	// 创建多边形数据
	vtkSmartPointer<vtkPolyData> polyData =
		vtkSmartPointer<vtkPolyData>::New();
	polyData->SetPoints(points);
	
	// 准备加入点数据的标量值,两个标量值分别为1和2
	vtkSmartPointer<vtkDoubleArray> weights =
		vtkSmartPointer<vtkDoubleArray>::New();
	weights->SetNumberOfValues(2);
	weights->SetValue(0, 1);
	weights->SetValue(1, 2);

	// 先获取多边形数据的点数据指针,然后设置该点数据的标量属性值
	polyData->GetPointData->SetScalars(weights);
		
	// 输出索引号为0的点标量值
	double weight = vtkDoubleArray::SafeDownCast(
					polyData->GetPointData->GetScalars())->GetValue(0);
	std::cout << "double weight:" << weight << std::endl;

	return 0;

}

GetPointData->SetScalars()

3.4.2 矢量数据

与物理学的矢量概念一样,VTK的矢量数据也是指既有大小也有方向的量。

3.4.3 纹理座标

3.4.4 张量数据

3.5  不同类型的数据集

3.5.1 vtkImageData

vtkImageData类型的数据是按规则排列在矩形方格中的点和单元的集合

如果数据集的点和单元排列在平面(二维)上,则称此数据集为像素映射、位图或图像;如果排列在层叠面(三维)上,则称为体。

3.5.2 vtkPolyData

多边形数据集vtkPolyData由顶点、多顶点、线、折线和三角形条带等单元构成,多边形数据是不规则结构的,并且多边形数据集的单元在拓扑维度上有多种类型。

3.5.3 vtkRectilinearGrid

3.5.4 vtkStructuredGrid

3.5.5 vtkUnstructuredGrid

3.5.6 vtkUnstructuredPoints

3.6 数据的存储与表达

3.6.1  vtkDataArray

VTK中的内存分配采用连续内存,可以快速的创建、删除和遍历,称之为数据数组(Data Array),用类vtkDataArray实现。

vtkDataArray及其子类是建立VTK数据对象的基础。以vtkPolyData为例,该类由几何数据(vtkPoints)、拓扑数据(vtkCellArray)和属性数据(vtkPointData、vtkCellData和vtkFieldData)组成,而这些数据是通过数据数组(vtkDataArray)的形式存储。

 

3.6.2  数据对象的表达

VTK里的数据对象是作为vtkDataArray的数组(即数据数组的数组)实现的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章