6.6 数据集的存储与表达
可视化数据自身的特点决定了数据对象内存的分配与管理必须谨慎处理才有可能创建出高效的可视化系统。VTK中对绝大多数的数据对象的内存分配采用连续内存,连续内存的结构可被快速地创建、删除和遍历,称为Data Array (数据数组),用类vtkDataArray实现。
6.6.1 vtkDataArray
数据数组的访问是基于索引的,从零开始计数。我们以vtkFloatArray类来说明如何在VTK中实现连续内存的数据数组。如图6.13所示,变量Array是一个指向浮点型数组的指针,数组的长度由变量Size指定,由于数组的长度是动态地增加的,所以当存储数据的数组长度超出指定的长度时,会自动触发Resize()操作来调整数组的长度,使数组的长度变成原来的两倍,MaxId是一个整型的偏移量,用来定义最后一个插入的数据的索引。如果没有数据插入,MaxId等于-1,否则,MaxId的值介于0到Size之间,即0≤MaxId<Size。
图6.13连续数组的实现
6.6.2 Tuple(元组)的概念
许多可视化数据是由多个数据分量组成的,如RGB颜色数据由红、绿、蓝三个分量组成,为了在连续数组中表达这一类数据,VTK引入了元组(Tuple)的概念。元组是数据数组的子数组,用于存储数据类型相同的分量数据,图6.13所示的NumberOfComponents,表示的就是数据数组里元组的个数。元组的大小在给定后不会改变,图6.14所示的数据数组由n个元组组成,每个元组存储三个分量数据。
图6.14数据数组结构
vtkDataArray存储的是数值数据,如属性数据(Attribute Data)和点数据(Point)等。有些属性数据,如点、矢量、法向量和张量等,在定义时就需要指定元组的大小。例如,点、矢量和法向量等属性数据,元组的大小是3,而张量属性数据的元组大小是9 (即3×3的矩阵),标量属性数据对于元组的大小则没有任何要求,对于处理标量属性数据的算法,通常都是只处理标量每一个元组数据的第一个分量。VTK提供了将多分量的数据数组分离成单一分量的数据数组,以及将单一分量的数据数组合并成多分量的数据数组的类,即vtkSplitField和vtkMergeFields。
下列代码演示了如何创建固定长度及动态的数据数组,以加深对Data Array及Tuple概念的理解:
/**************************************************************************
固定长度的数据数组(DataArray)。下列代码创建了容量为20个元组(Tuple)的数据数组,
每个元组的分量个数为1,通过方法SetComponent()和GetComponent()设置及获取相应
的元组的值。
**************************************************************************/