VTK学习笔记--4 数据集与数据属性

项目不等人,只能先跳过范例,先看数据集和数据属性这一章了。范例会在空闲时间穿插在笔记中。

第三章 数据集与数据属性

定义:在可视化流水线中,称处理的数据对象为数据集。

数据集是抽象概念,对应的类vtkDataSet也是一个抽象类。所以在程序中使用的数据集是其具体化后的子类。

数据集的组成:

094231_cMdB_2009228.png

3.1 数据集的结构

由上面数据集结构的组成可知:定义一个数据集的结构需要分别对数据集的几何拓扑进行定义,即分别对单元进行定义

下面分别介绍对点和单元的定义进行介绍:

①定义数据集的点

定义数据集的点十分简单。首先将一系列的点坐标插入到vtkPoints对象中,接着调用数据集对象的方法SetPoint(),并将这个vtkPoints对象作为参数传入,这样就定义好了数据集的点,也就是定义好了数据集的几何。插入到vtkPoints对象中点会有一个对应的id号(索引)。之后定义单元时,就是使用这些id号来表示相应点之间的关系的。

举例:

#include"vtkPolyData.h"
#include"vtkPoints.h"

int main()
{
	int i;
	//定义点在三维坐标系中的坐标
	static float x[8][3]={{0,0,0,},{1,0,0},{1,1,0},{0,1,0},{0,0,1},{1,0,1},{1,1,1},{0,1,1}};
	
	vtkPolyData *cube=vtkPolyData::New();//创建数据集对象的实例
	vtkPoints *points=vtkPoints ::New();//创建vtkPoints对象的实例

	for(i=0;i<8;i++)points->InsertPoint(i,x[i]);//将点坐标插入vtkPoints对象中

	cube->SetPoints(points);//为数据集添加点,定义其几何

	return 0;
}

当然上面的例子运行起来后没有结果可以显示。

②定义数据集的单元

单元的定义要复杂一些,原因是单元的类型比较多,或者说是点之间关系的种类比较多。

VTK支持的单元类型如图所示:

103727_7Rik_2009228.png

(a)顶点:基本的零维单元,由一个单一点定义。

(b)多顶点:复合的零维单元,由任意顺序的一系列点定义。

(c)线:基本的一维单元,由两个点定义,其方向为第一个点到第二个点的方向

(d)多线段:复合的一维单元,包含一个或多个连接的线,由有序的n+1个点定义,其中n是多线段中的线的段数。每对点(i,i+1)定义了一段线。

(e)三角形:基本的二维单元,按照顺时针或者逆时针方向排列的三个点定义。

(f)三角形带:复合的而为单元,包含一个或多个三角形,这些三角形不必位于一个平面上。其由有序的n+2个点进行定义,其中n是三角形的个数,点的排列顺序必须满足使任意三个相邻点(i,i+1,i+2)都能定义一个三角形,其中i的取值范围为【0,n-1】。

(g)四边形:基本的二维单元,由位于同一个面上的按照顺时针或者逆时针方向排列的四个点定义。四边形必须是凸的,并且不能相交。

(h)像素:基本的二维单元,由有序的四个点定义。像素单元在拓扑上与四边形等价,只是另外有几何上的限制。像素的每条边与其临边垂直,并且与x-y-z三个坐标轴中的一个平行。因此,发现方向也平行于一个坐标轴。

       定义像素的点的顺序与定义四边形单元的不同。点的顺序是按照坐标轴的正方向来排列的,先是x轴,然后是Y轴,最后是z轴。像素是一种四边形的特例,用于改进计算性能。

注意事项:这里给出的像素定义与通常的像素定义不同。一般像素是指图像中具有常量值得图像元素,而这里给出的定义意味着,四个图像元素形成了像素单元四个角上的点。

(i)多边形:基本的二维单元,由位于同一平面上按照顺时针或者逆时针的三个或更多个点定义。

(j)四面体:基本的三维单元,由四个不同平面的点定义。四面体包含六条边和四个三角面。

(k)六面体:基本的三维单元,包含六个四边形面,十二条边和八个顶点。六面体由有序的8个点定义。面和边不能与其他面和边相交,四边形必须是凸的。

(l)体素:基本的三维单元。体素在拓扑上与六面体等价,只是另外带有几何上的限制。体素每个面与x-y-z三个坐标轴中的一个垂直。点的定义顺序是按照坐标轴的正方向来排列的。体素是六面体的一个特例,用于改进计算性能。

与像素一样,这里的体素的定义与常规意义上的体素不同。一般,体素是指具有长两只的体积元素。根据这里体素单元的定义,8个体积元素形成了体素单元8个角上的点。

定义单元举例:

#include"vtkPolyData.h"
#include"vtkPoints.h"
#include"vtkCellArray.h"
int main()
{
	int i;
	//定义点在三维坐标系中的坐标
	static float x[8][3]={{0,0,0,},{1,0,0},{1,1,0},{0,1,0},{0,0,1},{1,0,1},{1,1,1},{0,1,1}};
	//定义单元(通过点的索引来表达点之间的关系,所以采用vtkIdType)
	static vtkIdType pts[6][4]={{0,1,2,3},{4,5,6,7},{0,1,5,4},{1,2,6,5},{2,3,7,6},{3,0,4,7}};

	vtkPolyData *cube=vtkPolyData::New();//创建数据集对象的实例
	vtkPoints *points=vtkPoints ::New();//创建vtkPoints对象的实例
	vtkCellArray *polys=vtkCellArray::New();

	for(i=0;i<8;i++)points->InsertPoint(i,x[i]);//将点坐标插入vtkPoints对象中
	for(i=0;i<6;i++)polys->InsertNextCell(4,pts[i]);//

	cube->SetPoints(points);//为数据集添加点,定义其几何
	points->Delete();
	cube->SetPolys(polys);//为数据集添加单元,定义其拓扑
	polys->Delete();
	return 0;
}

3.2 数据集的属性

      数据集的属性(属性数据)是与数据集结构相关联的。而数据集又是建立在点和单元的基础上,所以数据属性很自然地是与点和单元相关联。即每个点每个单元都有与其对应的数据属性。

      数据属性的值称为属性数据。属性数据一般设置为一些有实际意义的值,如在某点处的温度(用一个数值表示),或在某点处所受的力(用三个数值表示)等。点或单元的属性数据是以数据数组(vtkDataArray)的形式进行存储的,根据数据值类型的不同,具体是存储 在vtkDataArray的子类中,如vtkFloatArray或vtkIntArray等。数组的每个元素称为元组,对应着但个点或单元的属性数据。每个元组可以有多个分量(Component),例如速度值就有分别沿着x,y,z轴的三个分量。数组的长度必须与点或单元的个数相同,这样才能保证与点或单元一一对应。如下是创建数组的方法:

vtkFloatArray *scalars=vtkFloatArray::New();

scalars->InsertTuple1(0,0.0);

scalars->InsertTuple1(0,1.0);

……

vtkDoubleArray *vectors=vtkDoubleArray::New();

vectors->SetNumberOfComponents(3);//设置分量个数,默认为1

vectors->SetNumberOfTuples(10);//设置元组个数,必须等于点的个数

vectors->SetTuple3(0,0.0,0.5,1.0);//设置Id为0的点的属性数据

vectors->SetTuple3(1,0.0,1.5,1.0);//设置Id为1的点的属性数据

……

vtkIntArray *anArray=vtkIntArray::New();

anArray->SetNumberOfComponents(2);

anArray->SetName("Velocity");

anArray->SetTuple2(0,1,3);

anArray->SetTuple2(1,2,4);

从代码可以看出,在插入各个数据前,元组的个数可以不指定。这样的话,就必须调用名字前缀为Insert的方法插入数据(注意最终插入的元组个数必须等于点或单元的个数)。如果制定了元组个数的话,就可以调用名字前缀为Set的方法,该方法相对较快些。方法名后缀的数字表示的是元组中分量的个数,该数字与SetNumberOfComponents()参数一致,默认分量个数为1.设定每个元组数据时,需提供若干个参数,第一个是点ID号,之后是元组各个分量的值。设置元组数据还有很多种方法可供选择。

  数据数组可作为特殊或一般的属性数据添加进数据集中。若是作为一般属性数据的话,那么在创建数据数组的时候,可以用方法SetName()给数组设置一个名字,如上面代码中:anArray->SetName("Velocity"),之后就可以通过这个名字来使用该数据数组。下面以多边形数据集为例,说明使用两种不同形式添加数据数组的过程:

vtkPolyData *polyData = vtkPolyData::New();//创建数据集对象的实例

……

polyData->GetPointData()->SetScalars(scalars);//特殊属性数据

polyData->GetCellData()->SetVectors(vectors);//特殊属性数据

polyData->GetPointData()->AddArray(anArray);//一般属性数据

首先需要调用数据集的方法GetPointData()或者GetCellData()获取点或单元数据,接着调用方法SetScalars()和SetVectors()将数据数组作为特殊属性数据存储。这两个方法分别设置的是标量属性数据和矢量属性数据(其他特殊属性数据还包括法向量属性数据、纹理坐标属性数据和张量属性数据,分别用方法SetNormals()、SetTCoords()和SetTensors()设置)。最后调用AddArray()将数据数组作为一般属性数据添加进数据集中。该方法可以多次调用从而添加多个数据数组。正是由于一般属性数据没有数量上的限制,所以使用字符串名字来进行区分会方便些。

补充:下面资料来自:http://blog.sina.com.cn/s/blog_84181a7901017tsm.html

       属性数据主要用于描述数据集的属性特征,属性数据常常和数据集的几何数据或单元数据相关联,对数据集的可视化实质上是对属性数据的可视化,例如,根据压力监测数据构建一个压力场可视化数据集后,数据集中的每个数据点(几何数据)或单元都必须有对应的属性数据,VTK根据属性数据设置颜色表,用不同的颜色表示不同的压力,通过颜色的变化情况,可以直观的分析出压力的变化趋势。

       属性数据依据数据的性质可分为标量数据、向量数据、张量数据几大类,一般标量数据和向量数据应用的比较多,大部分的例子都以这两种数据为主。

     1、标量数据

      标量数据只表示数据的大小,例如温度、压力、高度等。

84181a7907b18c7861966&690

 

      2、向量数据

      既有大小又有方向的量,如速度、应力、位移等

84181a794cef7cb3577b8&690

     3、张量数据

      张量是矢量和矩阵通过复杂的数学算法得到的,一个k阶的张量可当作一个k维的表格。零阶的张量是标量,一阶的张量是矢量,二阶的张量是纹理坐标,三阶的张量是一个三维阵列。  

84181a794cef7cb3be13f&690

属性数据只能和数据集中的点及单元关联,对于构成单元的基本组成要素,如边和面等不能与数据属性关联,我们称与点关联的数据属性为点属性,与单元关联的数据属性为单元属性。

      在VTK中用vtkPointData类和vtkCellData类表达数据集属性,它们是类vtkFieldData的子类,构成数据集的每个点(或单元)和属性数据之间存在一对一的关系,如一个数据集由N个点(或单元)构成,那么必须有N个属性数据和这N个点(或单元)一一对应,通过点的ID号就可以对该点的属性数据进行访问,例如在数据集aDataSet中访问ID号为129的点的标量值时(假设标量数据已被定义且不为空)使用如下方法: aDataSet->GetPointData()->GetScalars()->GetScalar(129)。

现在前面两节3.1 3.2 已经将数据集的构成讲完了。但是数据集的结合和拓扑有各种各样的可能,所以,还需要从数据集整体上对数据集进行分类。假设以哺乳动物这个类来比喻数据集的话,现在我们已经知道动物是由血肉和骨头组成的了。但是血肉和骨头的组成由很多种,所以在实际生活中我们可能还要将哺乳动物分成各种可数比如猫科、犬科等等。

Σ( ° △ °|||)︴ 我这个比喻好像不恰当。原谅我的想象力吧。后面讲介绍: 各种数据集类型  这是很重要的部分。

转载于:https://my.oschina.net/u/2009228/blog/364413

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值