vtk中通过vtkDataArray进行数据的存储,通过vtkDataObject进行可视化数据的表达,在vtkDataObject内部有一个vtkFieldData的实例,负责对数据的表达:
vtkFieldData存储数据的属性数据,该数据是对拓扑结构和几何结构信息的补充。属性数据可以是某个空间点的温度或某个单元的质量等。在vtk中与数据集的点数据相关联的属性数据用vtkPointData表达,与单元数据相关联的属性数据用vtkCellData表达。
其属性内容都用vtkDataArray来存储,如<vtkDoubleArray>来存储某个空间点或者几何结构的某个属性。
例子1,几何结构点point对象的属性设置:
- 实例化一个 vtkUnstructuredGrid 对象
unStructGrid
- 设置节点序列信息
cells
和单元序列信息points
- 需要渲染节点属性信息时,通过预先设置好的节点属性信息
Scalars
进行赋值,并且通过SetScalarModeToUsePointData()
方法设置 mapper 只显示节点属性
unStructGrid->GetPointData()->SetScalars(Scalars);
ugridMapper->SetScalarModeToUsePointData();
例子2,拓扑结构cell对象的属性设置:
需要渲染单元属性信息时,通过事先设置好的单元属性信息Scalars
进行赋值,并且通过 SetScalarModeToUseCellData()
方法设置 mapper 只显示单元属性
unStructGrid->GetCellData()->SetScalars(Scalars);
ugridMapper->SetScalarModeToUseCellData();
例子3,这里说明了如何创造并将数据写入一个属性数组scalars:
// 创建一个属性数组scalars,存放点的属性
vtkSmartPointer<vtkDoubleArray> scalars = vtkSmartPointer<vtkDoubleArray>::New();
// 填充点云数据(示例数据)
double point[3] = { 0.0, 0.0, 0.0 };
double pixel;
for (int k = 0; k < dims[2]; k++)// dims[2]; k++)
{
for (int j = 0; j < dims[1]; j++)//dims[1]; j++)
{
for (int i = 0; i < dims[0]; i++)
{
pixel = imageData->GetScalarComponentAsDouble(i, j, k, 0);//获取组分作为属性数据
if (pixel > 0)
{
point[0] = i; //X轴横坐标
point[1] = j; //Y轴纵坐标
point[2] = pixel; //Z轴高度
vtkIdType pId[1]; //定义用来存储点的坐标的中间变量,vtkIdType相当int long等类型
points->InsertNextPoint(point); //把点坐标加入VTKPoints中,InserNextPoint()返回加入这些point点依次在VTKPoints中的索引;
pId[0] = points->InsertNextPoint(point); //获取要插入cell的pint点的坐标数据。
vertics->InsertNextCell(1, pId); //将VTKPoints的内容加入拓扑结构cell中,这里每将point点加入VTKPoints一次,就将这个VTKPoints加入cell一次。
vtkCellArray::InsertNextCell ( vtkIdType npts, vtkIdType * pts )的第一个参数值标是这个cell中点的个数,第二个参数指向那些点的坐标数据。
vtkIdType *pts,存储的是所包括点在points中的顺序信息,其个数当然应该和前面的npts一致。这里,2点可以连成一条线,三点可以得到一个面。
//也就是说:vtk中关于点、线、面的那些信息都是存放在cellarray中,应用时也是直接对cellarray指针进行处理,数据的写入和读取在vtkCellArray类完成。
scalars->InsertNextValue(pixel); //属性数组scalars,用来存放点属性
polydata->SetPoints(points);//加入三维点
polydata->SetVerts(vertics);//加入三维点的点索引
//还是需要标量scalars来表示高度,并用这个标量进行映射
//
// scalars->InsertTuple1(i, pixel);//这个格式好像不对
// //polydata->GetPointData()->SetScalars(scalars);//加入点属性
//cout << "高度scalars=" << scalars << endl;
}
}
}
}
——————————————
数据属性是简单的vtkDataArray类型,它可以是标量scalar,向量vector,张量tensor,法向normal,纹理坐标texture coordinate,全局id (global id,如标识大量元素),或者pedigreeids(用来追踪管线中的元素历史)。
vtkDataSet中的一个点或者单元都有独立的属性数据。数据属性可以关联vtkDataSet中的点或者单元。与vtkDataSet关联的vtkDataArray都是vtkDataArray的一个具体子类,例如vtkFloatArray或者vtkIntArray。这些数据数组可以看做连续的、线性的内存块。在内存块中,数据数组可以看作由子数组或者“元组”(Tuple)组成。创建属性数据即是根据类型实例化数组内存,制定元组大小,插入数据并与数据集关联:
这里创建了三种类型的属性数据,float,double和int。第一个数组scalars实例化后,默认的元组大小为1。
InsertTuple1()方法用来向数组中插入数据(所有Insert___()方法负责分配足够的内存来保存数据)。
下一个数组vectors的元组数为3,因此vectors定义为含有三个分量,InsertTuple3用来向数组中添加数据。
最后创建的是元组数为2的数组,通过SetNumberOfTuples()分配内存。
接着通过SetTuple2()添加数据;该方法使用的前提是内存已经分配,因此速度要明显快于Insert__()方法。
当将属性数据关联到点数据或者单元数据时,注意区别设置类型的方法(SetScalars()和SetVectors())。注意点属性个数必须与数据结构中的点个数一致,单元属性与数据结构的单元个数一致。
————————
采用如下方法访问属性数据:
set scalars [[polyData GetPointData] GetScalars]
set vectors [[polyData GetCellData] GetVectors]
许多的Filter需要专门的属性数据进行工作。例如,vtkElevationFilter依赖于相应的高度数据产生标量值。其他的Filter只依赖于结构数据,并忽略传来的属性数据。还有一些Filter需要结构数据和属性数据来工作,如vtkMarchingCubes。它利用输入的标量属性数据和结构数据来产生轮廓结构。其他类型的属性数据,例如向量,在计算轮廓时进行差值计算并输出。
——————————————————
颜色映射(ColorMapping)
最常用的可视化技术可能是通过标量值或者颜色映射来对物体着色。着色技术的思想比较简单,将标量值映射到一个颜色查找表来获取颜色,然后在渲染时使用颜色来改变点或者单元的外观。在阅读本节前,请先理解怎样控制Actor的颜色(详见54页“Actor颜色”一节)。
VTK中颜色映射主要由用户生成或者数据文件中的标量数据和vtkMapper实例执行颜色映射使用的颜色查询表来控制。也可以使用任意的数据数组通过ColorByArrayComponent()方法来控制。如果没有指明,Mapper会生成一个默认的颜色查询表,你也可以自己创建(下例摘自VTK/Examples/Rendering/Tcl/Rainbow.tcl,运行结果如图5-1所示):
如该例所示,操作查询表有两种方式。一是指定一个HSVA范围然后在HSVA空间中插值计算颜色表中颜色(实际由build()函数计算颜色)。第二种方法是在根据颜色表的位置人为指定颜色。注意颜色表中的颜色数目可以设置。本例中利用HSVA范围生成颜色表,然后利用SetTableValue()函数替换掉相应的颜色。
Mapper的SetScalarRange()函数控制标量值与颜色表的映射方式。大于最大值的所有标量值都被映射为最大值,小于最小值的所有标量值都映射为最小值。标量范围设置,可以通过在某一数据范围内映射更多的颜色来达到“扩展”的目的。
很多情况下标量数据就是颜色值,这样就不需要通过颜色查找表进行映射。
——————————————————————————————————
在 VTK中,数据集的几何数据表示为Points (点集),拓扑关系表示为Cell(单元),属性数据包括Scalar(标量)、Vector(向量)、Normal(法线)、Texture(纹理)等。
在VTK中数据集的类型主要按构成数据集的几何数据和单元来划分,主要的数据集类型包括:Structured Points(结构化点集)【vtkStructuredPoints 的父类是vtkImageData】、Unstructured Points (非结构化点集)、Poly Data(多边形数据集)、Structured Grid(结构化网格数据集)、Unstructured Grid(非结构化网格数据集)、Rectilinear Grid(线性网格数据集)等几大类,各类的表现形式如下图所示。
(1) Structured Points
按规则排列的点的集合。点的排列和坐标轴平行,形成方形的点阵。vtkStructuredPoints 的父类是vtkImageData,vtkImageData是vtkDataSet的子类。
(2) Unstructured Points
不规则地分布在空间的点集。非结构化点集具有不规则的几何结构,但不具有拓扑结构,用离散点来表达,通常,这类数据没有固定的结构,是由一些可视化程序识别和创建的。
(3) Poly Data
在VTK中多边形数据集是由顶点、多顶点、线、多线、多边形各三角带构成,多边形数据是非结构化的,并且多边形数据集的单元在拓扑维度上有多种变化,顶点、线和多边形构成了用来表达0、1和2维几何图形的基本要素的最小集合,同时用多顶点、多线和三角形带单元来提高效率和性能,特别是用一个三角形带表达N个三角形只需要用N+2个点,但是用传统的表达方法需要用3N个点。vtkPolyData的父类是vtkPointSet,vtkPointSet是vtkDataSet的子类。
(4) Structured Grid
具有规则的拓扑结构和不规则的几何结构,但是单元没有重叠或交叉。vtkStructuredGrid的父类是vtkPointSet。
(5) Unstructured Grid
非结构化网格集是最常见的数据集类型,它的拓扑结构和几何结构都是非结构化的,在此数据集中所有单元类型都可以组成任意组合,所以单元的拓扑结构从零维延伸至三维,在 VTK中任一类型的数据集都可用非结构化网格来表达。vtkUnstructuredGrid的父类是vtkPointSet。
(6) Rectilinear Grid
是排列在矩形方格中的点和单元的集合,线性网格的拓扑结构是规则的,但其几何结构只有一部分是规则的,也就是说,它的点是沿着坐标轴排列的,但是两点间的间隔可能不同。vtkRectilinearGrid的父类是vtkDataSet。
3.可视化数据集部分的 VTK类列表