当前位置:   article > 正文

VTK图形图像开发进阶-03VTK基本数据结构_vtk图形图像开发 csdn

vtk图形图像开发 csdn

3.1 可视化数据的基本特点

1.离散性

       为了让计算机能够获取、处理和分析数据,必须对无限、连续的空间体进行采样,生成有限的采样数据点,这些数据以离散点的形式存储,采样的过程是一个离散化的过程。由于可视化数据的离散性特点,在某些离散点上有精确的值存在,但点与点之间的值则是不可知的,要得到采样点之外的其他点的值,只有通过插值(Interpolation) 的方法获取。常用的插值方法是线性插值,要得到更精确的数值可以采用非线性插值。

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

        规则结构数据点之间有固定的关联关系,可以通过这些关联确定每个点的坐标,不规则结构数据之间没有固定的关联关系。对于规则结构的数据,在储时不必存储所有数据点,只需存储起始点,相邻两点之 间的间隔以及点的总数就可以保存完整的数据信息。对于不规则结构的数据,虽然不可以像规则结构的数据那样存储,但它也有自身的优势,即在数据变化频繁的区域可以密集表示,而数据变化不频繁的区域则稀疏表示。规则结构的数据可以在存储及计算时占优势,不规则结构的数据虽然在存储和计算时不能像规则结构那样高效,但它在数据表达方面相对而言更加自由、细致、灵活。

3.数据具有维度

        可视化数据的第三个特点是拓扑维度(Topological Dimension)。可视化数据具有零维、一维、二维、三维等任意维度,例如,零维数据表现为点,- -维数据表现为曲线。 二维数据表现为曲面、三维数据表现为体等。数据的维度决定了数据可视化的方法。

3.2数据对象和数据集

3.2.1 vtkDataObject

1.数据一般以数据对象(类vtkDataObject)的形式表现,数据对象是数据的基合,数据对象表现的数据是可以被可视化管线处理的数据,只有当数据对象被组织成一种结构后,才能被VTK提供的可视化算法所处理。

3.3.2 vtkDataSet

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

2.vtkDataSet由两个部分组成,即组织结构和与组织结构相关联的属性数据。

3.组织结构包括拓扑结构和几何结构

拓扑结构描述了对象的构成形式——点数据的连接形式形成单元数据,有单元数据形成了数据集的拓扑结构

几何结构描述了对象的空间位置关系——点数据所定义的一些列坐标构成了vtkDataset数据集的几何结构

4.属性数据是对拓扑结构和结合结构信息的补充,属性数据可以是每个空间点的温度值,也可以看作某个单元的质量等。

5.示例——如何将几何结构和拓扑结构加入数据集中

(1)将几何结构加入数据集

        先创建一个点数据(vtkPoints),里面含有三个点,再创建一个具体数据集(vtkPolyData)然后将创建的点加入数据集,最后把vtkPolyData的数据用类vtkPolyDataWriter写入triangle.vtk文件,保存路径为工程的当前目录。

        可以利用ParaView软件打开.vtk文件。

  1. #include <vtkSmartPointer.h>
  2. #include <vtkPoints.h>
  3. #include <vtkPolyData.h>
  4. #include <vtkPolyDataWriter.h>
  5. int main(int argc, char* argv[])
  6. {
  7. // 创建点数据
  8. vtkSmartPointer<vtkPoints> points =
  9. vtkSmartPointer<vtkPoints>::New();
  10. points->InsertNextPoint(1.0, 0.0, 0.0);
  11. points->InsertNextPoint(0.0, 0.0, 0.0);
  12. points->InsertNextPoint(0.0, 1.0, 0.0);
  13. // 创建vtkPolyData类型数据,vtkPolyData派生自vtkPointSet
  14. // vtkPointSet是vtkDataSet子类,即vtkPolyData是一种数据集
  15. vtkSmartPointer<vtkPolyData> polyData =
  16. vtkSmartPointer<vtkPolyData>::New();
  17. // 将创建的点数据加入到vtkPolyData数据里
  18. polyData->SetPoints(points);
  19. //将vtkPolyData类型的数据写入到一个vtk文件,保存位置是工程当前目录
  20. vtkSmartPointer<vtkPolyDataWriter> writer =
  21. vtkSmartPointer<vtkPolyDataWriter>::New();
  22. writer->SetFileName("triangle.vtk");
  23. writer->SetInputData(polyData);
  24. writer->Write();
  25. return 0;
  26. }

(2)将拓扑结构加入数据集

        以下示例实例化了一个vtkCellArray对象,其中vtkCellArray类型中的vertices就是指定数据集polydata的拓扑结构,points定义几何结构。

        该示例中定义的数据集的拓扑结构为零维的点,单元类型为vertices

  1. #include <vtkSmartPointer.h>
  2. #include <vtkPoints.h>
  3. #include <vtkCellArray.h>
  4. #include <vtkPolyData.h>
  5. #include <vtkPolyDataWriter.h>
  6. int main(int argc, char* argv[])
  7. {
  8. // 创建点坐标
  9. double X[3] = { 1.0, 0.0, 0.0 };
  10. double Y[3] = { 0.0, 0.0, 0.0 };
  11. double Z[3] = { 0.0, 1.0, 0.0 };
  12. // 创建点数据以及在每个点坐标上加入顶点(Vertex)类型的单元
  13. // vtkPointSet是vtkDataSet子类,即vtkPolyData是一种数据集
  14. vtkSmartPointer<vtkPoints> points =
  15. vtkSmartPointer<vtkPoints>::New();
  16. vtkSmartPointer<vtkCellArray> vertices =
  17. vtkSmartPointer<vtkCellArray>::New();
  18. for (unsigned int i = 0; i < 3; ++i)
  19. {
  20. // 定义用于存储点索引的中间变量,vtkIdType就相当于int long等类型
  21. vtkIdType pid[1];
  22. // 把每个点坐标加入vtkPoints中,InsertNextPoints()返回加入的点的索引号
  23. // 下面需要使用这个索引号来创建顶点类型的单元
  24. pid[0] = points->InsertNextPoint(X[i], Y[i], Z[i]);
  25. // 在每个坐标点上分别创建一个顶点,顶点是单元(Cell)里的一种类型
  26. vertices->InsertNextCell(1, pid);
  27. }
  28. // 创建vtkPolyData对象
  29. vtkSmartPointer<vtkPolyData> polyData =
  30. vtkSmartPointer<vtkPolyData>::New();
  31. // 指定数据集的几何结构(由points指定)以及数据集的拓扑结构(由vertices指定)
  32. polyData->SetPoints(points);
  33. polyData->SetVerts(vertices);
  34. //将生成的数据集写入到TriangleVerts.vtk文件,保存位置是工程当前目录
  35. vtkSmartPointer<vtkPolyDataWriter> writer =
  36. vtkSmartPointer<vtkPolyDataWriter>::New();
  37. writer->SetFileName("TriangleVerts.vtk");
  38. writer->SetInputData(polyData);
  39. writer->Write();
  40. return 0;
  41. }

        该示例定义的是一维拓扑结构。 

  1. #include <vtkSmartPointer.h>
  2. #include <vtkPoints.h>
  3. #include <vtkLine.h>
  4. #include <vtkPolyData.h>
  5. #include <vtkPolyDataWriter.h>
  6. int main(int argc, char* argv[])
  7. {
  8. // 创建三个坐标点
  9. vtkSmartPointer<vtkPoints> points =
  10. vtkSmartPointer<vtkPoints>::New();
  11. points->InsertNextPoint(1.0, 0.0, 0.0); // 返回第一个点的ID:0
  12. points->InsertNextPoint(0.0, 0.0, 0.0); // 返回第一个点的ID:1
  13. points->InsertNextPoint(0.0, 1.0, 0.0); // 返回第一个点的ID:2
  14. // 每两个坐标点之间分别创建一条线
  15. // SetId()的第一个参数是线段的端点ID,第二个参数是连接的点ID
  16. vtkSmartPointer<vtkLine> line0 =
  17. vtkSmartPointer<vtkLine>::New();
  18. line0->GetPointIds()->SetId(0, 0);
  19. line0->GetPointIds()->SetId(1,1);
  20. vtkSmartPointer<vtkLine> line1 =
  21. vtkSmartPointer<vtkLine>::New();
  22. line1->GetPointIds()->SetId(0, 1);
  23. line1->GetPointIds()->SetId(1, 2);
  24. vtkSmartPointer<vtkLine> line2 =
  25. vtkSmartPointer<vtkLine>::New();
  26. line2->GetPointIds()->SetId(0, 2);
  27. line2->GetPointIds()->SetId(1, 0);
  28. // 创建单元数组,用于存储以上创建的线段
  29. vtkSmartPointer<vtkCellArray> lines =
  30. vtkSmartPointer<vtkCellArray>::New();
  31. lines->InsertNextCell(line0);
  32. lines->InsertNextCell(line1);
  33. lines->InsertNextCell(line2);
  34. // 创建vtkPolyData对象
  35. vtkSmartPointer<vtkPolyData> polyData =
  36. vtkSmartPointer<vtkPolyData>::New();
  37. // 指定数据集的几何结构(由points指定)以及数据集的拓扑结构(由lines指定)
  38. polyData->SetPoints(points);
  39. polyData->SetVerts(lines);
  40. //将生成的数据集写入到TriangleVerts.vtk文件,保存位置是工程当前目录
  41. vtkSmartPointer<vtkPolyDataWriter> writer =
  42. vtkSmartPointer<vtkPolyDataWriter>::New();
  43. writer->SetFileName("TriangleLines.vtk");
  44. writer->SetInputData(polyData);
  45. writer->Write();
  46. return 0;
  47. }

3.3 单元类型

1.数据集由一个或多个单元组成。一系列有序的点按指定类型连接所定义的结构就是单元。

2.单元是由单元的类型和构成的定点列表(由点的检索号表示)两部分构成。

3.3.1 线性单元

(a)VTK_VERTEX。顶点,零维的基本类型。

(b)VTK_POLY_VERTEX。多顶点,多个顶点组成,零维的基本类型。

(c)VTK_LINE。直线,一维的基本类型,方向由第一个点指向第二个点。

(d)VTK_POLY_LINE。折线

(e)VTK_TRIANGLE 三角形,三个点逆时针防线连接

(f)VTK_TRIANGLE_STRIP 三角形条带

(g)VTK_QUAD。四边形,二维的基本类型,非自交的凸多边形

(h)VTK_PIXEL。二维的基本类型

(i)VTK_POLYGON。多边形,二维的基本类型,逆时针方向顺序定义,可以是非凸的

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

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

(l)VTK_VOXEL。三维的基本类型

(m)VTK_WEDGE。楔形,三维的基本类型

(n)VTK_PYRAMID 。角椎体

(o)VTK_PENTAGONAL_PRISM 。五棱柱

(p)VTK_HEXAGONAL_PRISM。六角柱

3.3.2 非线性单元

        非线性单元常见的处理方式是将非线性单元细分成线性单元,再把细分结果当作线性单元处理,采用固定细分的方法。

3.4 属性数据

        属性数据主要用于描述数据集的属性特征,对数据集的可视化实质上就是对属性数据的可视化。在VTK中,用vtkPointData类和vtkCellDta类表达数据集属性,他们是类vtkDataSetAttributes(vtkDataSetAttributes派生自vtkFieldData)的子类,构成数据集的每个点(或单元)和属性数据之间存在一对一的关系。

3.4.1 标量数据

        标量数据是数据集里的每个位置具有单值的数据,它只表示数据的大小。例如温度、压力、密度、高度等。

  1. #include <vtkSmartPointer.h>
  2. #include <vtkPoints.h>
  3. #include <vtkDoubleArray.h>
  4. #include <vtkPolyData.h>
  5. int main(int , char* [])
  6. {
  7. // 创建点集数据:包含两个坐标点
  8. vtkSmartPointer<vtkPoints> points =
  9. vtkSmartPointer<vtkPoints>::New();
  10. points->InsertNextPoint(0, 0, 0); // 返回第一个点的ID:0
  11. points->InsertNextPoint(1, 0, 0); // 返回第一个点的ID:1
  12. // 创建多边形数据
  13. vtkSmartPointer<vtkPolyData> polyData =
  14. vtkSmartPointer<vtkPolyData>::New();
  15. polyData->SetPoints(points);
  16. // 准备加入点数据的标量值,两个标量值分别为1和2
  17. vtkSmartPointer<vtkDoubleArray> weights =
  18. vtkSmartPointer<vtkDoubleArray>::New();
  19. weights->SetNumberOfValues(2);
  20. weights->SetValue(0, 1);
  21. weights->SetValue(1, 2);
  22. // 先获取多边形数据的点数据指针,然后设置该点数据的标量属性值
  23. polyData->GetPointData->SetScalars(weights);
  24. // 输出索引号为0的点标量值
  25. double weight = vtkDoubleArray::SafeDownCast(
  26. polyData->GetPointData->GetScalars())->GetValue(0);
  27. std::cout << "double weight:" << weight << std::endl;
  28. return 0;
  29. }

        要给数据集里的点数据或单元数据设置标量属性数据,只有先获得该数据集对应的点数据或单元数据,然后设置标量属性数据即可。

GetPointData->SetScalars();

3.4.2 矢量数据

        与物理学的矢量概念一样,VTK的矢量数据也是指既有大小也有方向的量,三维方向上用三元组(Triple)表示为(u, v, w),如速度、应力、位移等。

       除了矢量数据用三元组表示,颜色等标量数据也会用类似三元组的结构表示。比如,从2.2.3节可知,颜色可以用RGB三个分量表示,RGB分量是构成颜色标量数据的三个组分,尽管颜色vtkColor也是使用vtkVector 容器,但它与矢量数据是有本质区别的。

         标量数据在数据集的几何变换过程中具有不变性。比如,假设有一个矢量数据存储在某个vtkDataSet 数据集里,当使用vtkTransformFilter对该数据集做变换时,希望的结果是该矢量数据也随着数据集的变换而变换;而对于RGB系统的颜色,假如把该颜色的RGB三个分量当成矢量方向的三个方向,对该数据集做变换时,颜色值也会随着变化,对于某一点的颜色,显然需要的结果是变换前后它的值应该保持不变。法向量是指大小恒为1的方向向量,也是一种常用的矢量数据,通常用于计算投影、光照等。当对数据集做变换时,法向量是会随之发生改变的。

3.4.3 纹理坐标

        为了使物体看起来更加真实,计算机图形学通常对显示的三维物体采用纹理映射。纹理坐标可以将点从笛卡儿坐标空间映射到一维、二维或三维的纹理空间中。

3.4.4 张量数据

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

3.5 不同类型的数据集

(a)vtkImageData

        vtkImageData类型的数据是按规则排列在矩形方格中的点和单元的集合。如果数据集的点和单元排列在平面(二维)上,则称此数据集为像素映射、位图或图像;如果排列在层叠面(三维)上,则称为体。

(b)vtkRectilinearGrid

        vtkRectilinearGrid类型的数据是排列在矩形方格中的点和单元的集合。线性网格的拓扑结构是规则的,但其几何结构只有部分是规则的。

(c)vtkStructuredGrid

        vtkStructuredGrid是结构化网格数据,是具有规则的拓扑结构和不规则的几何结构。

(d)vtkUnstructuredPoints

        vtkUnstructuredPoints 为非结构化点集,是指不规则地分布在空间的点集。非结构化点集具有不规则的几何结构,不具有拓扑结构,非结构化点集用离散点来表达。

(e)vtkPolyData

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

(f)vtkUnstructuredGrid

        vtkUnstructuredPoints为非结构化点集,是指不规则地分布在空间的点集。非结构化点集具有不规则的几何结构,不具有拓扑结构,非结构化点集用离散点来表达。

3.6 数据的存储与表达

3.6.1  vtkDataArray

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

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

3.元组是数据数组的子数组,用于存储数据类型相同的分量数据,元组的组分成为元组的大小。

3.6.2  数据对象的表达

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/996068
推荐阅读
相关标签
  

闽ICP备14008679号