VTK知识学习(20)- 数据的存储与表达

1、数据的存储

1)、vtkDataArray

VTK中的内存分配采用连续内存,可以快速地创建、删除和遍历,称之为数据数组(DataArray),用类 vtkDataArray 实现。数组数据的访问是基于索引的,从零开始计数。

以 vtkFloatArray 类来说明如何在 VTK 中实现连续内存的数据数组。

如图所示,变量 Aray 是一个指向浮点型数组的指针,数组的长度由变量 Size 指定,由于数组的长度是动态地增加的,所以当存储数据的数组长度超出指定的长度时,会自动触发 ResizeO)操作来调整数组的长度,使数组的长度变成原来的两倍,MaxId是一个整型的偏移量,用来定义最后个被插入的数据的索引。如果没有数据插入,MaxId等于-1,否则,Maxld的值介于0和 Size之间,即0≤MaxId<Size。
连续数组的实现

此外,许多可视化数据是由多个数据分量组成的,如RGB颜色数据由红、绿、蓝三个分量组成,为了在连续数组中表达这一类数据,引入了元组(Tuple)的概念。元组是数据数组的子数组,用于存储数据类型相同的分量数据,图所示的NumberOfComponents,表示的就是数据数组里元组的组分个数。元组的组分个数称为元组的大小,在给定后不会改变,图 所示的数据数组由N个元组组成,每个元组由三个组分组成。

2)、vtkDataArray 及其子类是建立 VTK 数据对象的基础

以 vtkPolyData 为例,该类由几何数据(vtkPoints)、拓扑数据(vtkCellArray)和属性数据(vtkPointData、vtkCellData 和vtkFieldData)组成,而这些数据都是通过数据数组(vkDataArray)的形式存储。

vtkDataArray可以存储标量数据,也可以存储向量数据。

因此使用 vtkDataAray 时需要指定元组的大小。

例如,点、矢量和法向量等属性数据,元组的大小是3,而张量属性数据的元组大小是9(即3x3的矩阵),标量属性数据对元组的大小则没有任何要求。

对于处理标量属性数据的算法,通常都是只处理标量每一个元组数据的第一个组分。

VTK提供了将多组分的数据数组分离成单一组分的数据数组的类 vtkSplitField,以及将单一组分的数据数组合并成多组分的数据数组的类vtkMergeFields.

3)、示例
cs 复制代码
 private void  UseDataArray()
        {
            vtkFloatArray array = vtkFloatArray.New();
            array.SetNumberOfComponents(1);
            array.SetNumberOfTuples(10);
            array.SetComponent(5, 0, 10.0);
            array.SetTuple1(6, 9.0);
            double b = array.GetComponent(5, 0);

            Console.WriteLine(" array.GetComponent:" + b);
        }

示意如何创建固定长度的数据数组,首先是设置元组的组分个数为1以及总的元组个数为10。、方法SetComponent()和 GetComponent()分别用于设置及获取元组的值。

SetComponent(vtkIdType i, int j,double c):指定第i个元组的第j个组分的值为c。

GetComponet(vtkIdType i,intj):获取第i个元组的第j个组分的值,由函数返回值返回。

除了可以创建固定长度的数据数组,vtkDataArray也提供了动态创建数据数组的方法,代码如下所示:

cs 复制代码
  vtkFloatArray array2 = vtkFloatArray.New();
            array2.SetNumberOfComponents(1);
            array2.InsertNextTuple1(5);
            array2.InsertNextTuple1(10);
            double bb = array2.GetComponent(1, 0);

            Console.WriteLine(" array.GetComponent:" + bb);

代码首先设置每个元组的组分个数为1,方法InsertNextTuple1()用于插入一个单组分的元组,连续调用两次即为插入两个元组,其值分别为5和10,类似的方法还有

InsertNextTuple2(),InsertNextTuple3(),InsertNextTuple4(),InsertNextTuple9()等。

4)、各种数据类型

可视化数据有各种各样的类型,如简单的浮点型、整型、字节型和双精度型等,复杂的特征字符串和多维标识符等。既然有这么多种数据类型,那么数据数组是如何操作和表达这些数据的呢?

VTK通过抽象数据对象(AbstractData Obiect)提供运行时解决方案以及使用C++编译时动态绑定的方法来解决这个问题。如图 3-15 所示,vtkDataAray 是一个抽象基类,其子类实现特定类型的数据数组及相关操作。
数据数组对象

2、数据对象的表达

VTK 里的数据对象是作为vtkDataArray的数组(即数据数组的数组)实现的。vtkDataObiect 是一种通用的可视化数据的表达,可视化算法基本都没有直接处理vtkDataObject 类型的数据,在处理某一类数据时,一般都要求数据内部具有某种组织结构。vtkDataObject 内部封装了与可视化管线的执行相关的变量和方法,包括表达数据。在vtkDataObiect 内部有一个 vtkFieldData(场数据)的实例,负责对数据的表达。如图A所示,场数据可以看作数据数组的数组,数组里的每一个元素都是一个数组,数组的类型、长度、元组的大小和名称等都可以各不相同。
图A vtkDataObject数据对象的表达

图 B是类 vtkFieldData的继承图,从类的名字能够推断出,vtkFieldData 存储的数据是与数据对象的属性数据相关的。以vtkPolyData为例,vtkPolyData内部存储了三种类型的数据,分别是 vtkPointData、vtkCellData和 vtkFieldData。vtkPointData 是与每一个点相关联的数据,如某点上的温度值;vtkCellData是与每一个单元相关联的数据,如某个三角形单元的面积:除点和单元数据以外的数据,应该使用vtkFieldData,如 vtkPolyData 模型的质心等。
图B vtkFieldData类的继承图

3、小结

vtkDataArray 采用连续内存,可以快速地创建、删除和遍历。

vtkDataObject是一种通用的可视化数据的表达,可视化算法基本都没有直接处理这个类型的数据,在处理某一类数据时,一般都要求数据内部具有某种组织结构。

内部封装了与可视化管线的执行相关的变量和方法,包括表达数据。。

内部有一个vtkFieldData(场数据)的实例,负责对数据的表达。

场数据可以看作数据数组的数组,数组里的每一个元素都是一个数组,数组的类型、长度、元组的大小和名称等都可以各不相同。

相关推荐
PP东2 小时前
ES6学习Generator 函数(生成器)(八)
javascript·学习·es6
小屁不止是运维4 小时前
麒麟操作系统服务架构保姆级教程(二)ssh远程连接
linux·运维·服务器·学习·架构·ssh
follycat5 小时前
bestphp‘s revenge
学习·web安全
职业考试资料墙5 小时前
二级建造师考试题库及答案
学习·考试·题库
Aughts6 小时前
基础电路的学习
学习
岳不谢8 小时前
华为DHCP高级配置学习笔记
网络·笔记·网络协议·学习·华为
爱吃西瓜的小菜鸡9 小时前
【C语言】抽空洗澡
c语言·开发语言·学习·算法
lover_putter11 小时前
ai学习报告:训练
人工智能·学习
123yhy传奇11 小时前
【学习总结|DAY020】Java FIle、字符集、IO流
java·开发语言·学习
eddieHoo13 小时前
关于生活的事
学习