1.从图形着色说起

前一个实验显示结果中的图像是白色的,而图形颜色与vtkPolyData属性数据息息相关。由于并未指定任何颜色和属性数据,因此在显示时默认以白色显示。
属性数据包括点属性和单元属性。可以为vtkPolyData的点数据和单元数据分别指定属性数据。
属性数据可以是标量,如点的曲率;可以是向量,如点或者单元的法向量;也可以是张量,主要在流场中较为常见。
颜色可以直接作为一种标量属性数据,设置到相应的点或者单元数据中,这也是最直接的一种图形着色方式。
下面的实例代码仅是对上例图形进行着色:
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkPolygon.h>
#include <vtkTriangle.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkUnsignedCharArray.h> //Attribution
#include <vtkPointData.h>
#include <vtkCellData.h>
///
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>int main()
{//几何结构数据:点集vtkSmartPointer<vtkPoints> pts =vtkSmartPointer<vtkPoints>::New();pts->InsertNextPoint(0.0, 0.0, 0.0);pts->InsertNextPoint(1.0, 0.0, 0.0);pts->InsertNextPoint(1.0, 1.0, 0.0);pts->InsertNextPoint(0.0, 1.0, 0.0);pts->InsertNextPoint(2.0, 0.0, 0.0);//拓扑结构数据:正四边形vtkSmartPointer<vtkPolygon> polygon =vtkSmartPointer<vtkPolygon>::New();polygon->GetPointIds()->SetNumberOfIds(4);polygon->GetPointIds()->SetId(0, 0);polygon->GetPointIds()->SetId(1, 1);polygon->GetPointIds()->SetId(2, 2);polygon->GetPointIds()->SetId(3, 3);//拓扑结构数据:三角形vtkSmartPointer<vtkTriangle> triangle =vtkSmartPointer<vtkTriangle>::New();triangle->GetPointIds()->SetId(0, 1);triangle->GetPointIds()->SetId(1, 2);triangle->GetPointIds()->SetId(2, 4);//构成拓扑结构集合vtkSmartPointer<vtkCellArray> cells =vtkSmartPointer<vtkCellArray>::New();cells->InsertNextCell(polygon);cells->InsertNextCell(triangle);//合成几何拓扑结构用于显示vtkSmartPointer<vtkPolyData> polygonPolyData =vtkSmartPointer<vtkPolyData>::New();polygonPolyData->SetPoints(pts);polygonPolyData->SetPolys(cells);//添加属性结构unsigned char red[3] = { 255, 0, 0 };unsigned char green[3] = { 0, 255, 0 };unsigned char blue[3] = { 0, 0, 255 };vtkSmartPointer<vtkUnsignedCharArray> ptColor =vtkSmartPointer<vtkUnsignedCharArray>::New();ptColor->SetNumberOfComponents(3);ptColor->InsertNextTupleValue(red);ptColor->InsertNextTupleValue(green);ptColor->InsertNextTupleValue(blue);ptColor->InsertNextTupleValue(red);ptColor->InsertNextTupleValue(green);polygonPolyData->GetPointData()->SetScalars(ptColor);vtkSmartPointer<vtkUnsignedCharArray> cellColor =vtkSmartPointer<vtkUnsignedCharArray>::New();cellColor->SetNumberOfComponents(3);cellColor->InsertNextTupleValue(blue);cellColor->InsertNextTupleValue(red);polygonPolyData->GetCellData()->SetScalars(cellColor);vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputData(polygonPolyData);vtkSmartPointer<vtkActor> actor =vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);vtkSmartPointer<vtkRenderer> render =vtkSmartPointer<vtkRenderer>::New();render->AddActor(actor);render->SetBackground(0.0, 0.0, 0.0);vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(render);rw->SetSize(320, 240);rw->SetWindowName("Creating PolyData Structure");vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);rwi->Render();rwi->Start();return 0;
}

该示例代码继承了上一节中的vtkPolyData数据。定义了两个vtkUnsignedCharArray对象ptColor和cellColor,分别为点和单元设置颜色数据。vtkUnsignedCharArray对象实际上为一个Unsigned char类型的数组。SetNumberOfComponents()函数指定了该数组中每个元组的大小。由于每个颜色是由RGB三个颜色分量组成。因此设置元组大小为3。InsertNextTupleValue()函数可以顺序插入元组数据。

由于要为点集设置颜色,因此颜色数目要与点数保持一致。对于单元的颜色数据设置同样需要注意,有多少个单元,就要设置多少个颜色。
设置点的颜色时,需要通过GetPointData()函数获取vtkPointData类型的点数据指针,然后通过SetScalar()函数设置颜色数据。
显示结果如下所示,从图中可以看出,在进行颜色渲染时,使用的是点的颜色,而不是单元的颜色!
根据之前的内容,我们知道:点数据和单元的属性数据是分别存储在VTKPointData和VTKCellData中的。
在这里,我们还是要着重区分一下标量属性数据和向量属性数据的区别
向量数据具有方向和模;而标量数据不具有。如果一个数据(可以是单组分、也可以是多组分)经过一个几何变换后保持不变,那么该数据是一个标量,例如我们说的颜色属性。然而,对于法向量,该数据同样有三个组分,却是一个矢量属性,因为法向量经过几何变换后(如图像旋转)会发生改变。因此不能简单滴通过组分的个数来区分标量数据或者矢量数据。在对属性数据进行赋值时,也要分清标量数据还是矢量数据,不能将两者混淆,例如将颜色数据设置为矢量数据,那么在对图像数据进行几何变换后,颜色数据会发生改变。

2. 单元的标量属性和矢量属性数据设置

默认情况下,vtkPolyDataMapper会使用一个unsigned char类型的三元数组作为颜色值进行渲染。但是在很多情况下,模型颜色是通过属性数据获取的,比如根据标量数据在颜色查找表中获取相应的颜色。
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);#include <vtkSmartPointer.h>
#include <vtkPlaneSource.h>
#include <vtkPolyData.h>
#include <vtkFloatArray.h>
#include <vtkCellData.h>
#include <vtkLookupTable.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>int main()
{vtkSmartPointer<vtkPlaneSource> gridSource =vtkSmartPointer<vtkPlaneSource>::New();gridSource->SetXResolution(3);gridSource->SetYResolution(3);gridSource->Update();vtkSmartPointer<vtkPolyData> grid = gridSource->GetOutput();//标量属性vtkSmartPointer<vtkFloatArray> cellScalars =vtkSmartPointer<vtkFloatArray>::New();//矢量属性vtkSmartPointer<vtkFloatArray> cellVector =vtkSmartPointer<vtkFloatArray>::New();cellVector->SetNumberOfComponents(3);//设置属性for (int i = 0; i < 9; i++){cellScalars->InsertNextValue(i + 1); //九个索引cellVector->InsertNextTuple3(0.0, 0.0, 1.0);}grid->GetCellData()->SetScalars(cellScalars);grid->GetCellData()->SetVectors(cellVector);vtkSmartPointer<vtkLookupTable> lut =vtkSmartPointer<vtkLookupTable>::New();lut->SetNumberOfTableValues(10);lut->Build();lut->SetTableValue(0, 0, 0, 0, 1);lut->SetTableValue(1, 0.8900, 0.8100, 0.3400, 1);lut->SetTableValue(2, 1.0000, 0.3882, 0.2784, 1);lut->SetTableValue(3, 0.9608, 0.8706, 0.7020, 1);lut->SetTableValue(4, 0.9020, 0.9020, 0.9804, 1);lut->SetTableValue(5, 1.0000, 0.4900, 0.2500, 1);lut->SetTableValue(6, 0.5300, 0.1500, 0.3400, 1);lut->SetTableValue(7, 0.9804, 0.5020, 0.4471, 1);lut->SetTableValue(8, 0.7400, 0.9900, 0.7900, 1);lut->SetTableValue(9, 0.2000, 0.6300, 0.7900, 1);//vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputData(grid);mapper->SetScalarRange(0, 9);mapper->SetLookupTable(lut);//vtkSmartPointer<vtkActor> actor =vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);vtkSmartPointer<vtkRenderer> render =vtkSmartPointer<vtkRenderer>::New();render->AddActor(actor);render->SetBackground(0.0, 0.0, 0.0);vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(render);rw->SetSize(320, 320);rw->SetWindowName("Setting Attribution of Vectors and Scalars");vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);rwi->Start();return 0;
}

这个实例主要演示了怎样添加单元的标量属性数据和向量属性数据。

VTKPlaneSource定义了一个3*3的网格数据。cellScalars定义了vtkFloatArray类型的标量属性数据,默认情况下其元组大小为1,因此不需要显示指定其大小;cellVectors则定义了vtkFloatArray类型的矢量属性数组,通过SetNumberOfComponents()指定向量维数为3,并通过InsertNextTuple3()可以方便地插入向量数据。
定义完毕后,vtkPolyData的单元数据(VTKCellData)通过调用函数SetScalars()和SetVectors()设置相应的属性数据和标量数据。
为了进一步演示利用标量数据进行颜色映射,定义了一个具有10个颜色的颜色映射表。利用vtkPolyDataMapper类的SetLookupTable()函数设置定义的颜色映射表。另外,需要注意的是,SetScalarRange()指定了颜色映射范围的最小值和最大值,当标量值大于最大值时,按定义最大值获取颜色;当小鱼最小值时,按照指定的最小值获取颜色。这样做的一个好处是,可以在一个小的标量范围内显示更多的颜色!!!
该例的输出结果为:

3.参看资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

VTK修炼之道45:图形进阶_vtkPolyData属性数据相关推荐

  1. VTK修炼之道46:图形基本操作进阶_三角网格体积、表面积、测地距离、包围盒

    1.基本图形操作意义 图形处理,比如图形平滑.多分辨率分析.特征提取等都离不开一些基本的图形操作.掌握这些基本的图形操作有助于理解和深入学习图形处理和分析方法. VTK中提供了多种图形的基本操作,其中 ...

  2. VTK修炼之道44:图形进阶_vtkPolyData数据源讨论与数据创建

    1.VTKPolyData源数据总结 1之前的实例中,我们利用VTKConeSource源数据创建了一个棱锥.实际上VTK内部提供可以写数据源类来快速获取简单的图形数据.下面给出了最常见的几种VTKP ...

  3. VTK修炼之道54:图形基本操作进阶_表面重建技术(三角剖分)

    1.表面重建 通过三维扫描仪所获取的实际物体的空间点云数据仅仅表示物体的几何形状,而无法表达其内部的拓扑结构.拓扑结构对于实际图形处理以及可视化具有更重要的意义.因此,这就需要利用表面重建技术奖点云数 ...

  4. VTK修炼之道59:图形基本操作进阶_纹理映射

    1.纹理映射 纹理映射是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程.纹理生成过程实质上是将所定义的纹理映射为某种三维物体表面的属性,并参与后续的光照计算.在三维图形中,纹理映射运用的十分广泛, ...

  5. VTK修炼之道58:图形基本操作进阶_点云配准技术(迭代最近点ICP算法)

    1.Iterative Closest Points算法 点云数据配准最经典的方法是迭代最近点算法(Iterative Closest Points,ICP).ICP算法是一个迭代的过程,每次迭代中对 ...

  6. VTK修炼之道57:图形基本操作进阶_点云配准技术(LandMark标记点算法和坐标系显示方法)

    1.点云配准 在计算机逆向工程中,通过三维扫描等实物数字化技术可以获取各种点云数据.但是受到测量环境和设备的影响,再一次测量的情况下,难以获取实物整体的点云数据,因此需要多次从不同角度进行测量.但不同 ...

  7. VTK修炼之道56:图形基本操作进阶_表面重建技术(三维点云曲面重建)

    1.点云重建 虽然Delaunay三角剖分算法可以实现网格曲面重建,但是其应用主要在二维剖分,在三维空间网格生成中遇到了问题.因为在三维点云曲面重建中,Delaunay条件不在满足,不仅基于最大最小角 ...

  8. VTK修炼之道55:图形基本操作进阶_表面重建技术(等值面提取)

    1.等值面提取 等值面(线)提取是一种常用的可视化技术,常应用于医学.地质.气象等领域.例如,在医学图像处理中,由于CT.MRI等图像分辨率越来越高,虽然体绘制技术可以清晰地对数据内部结构进行可视化, ...

  9. VTK修炼之道53:图形基本操作进阶_多分辨率策略(模型细化的三种方法)

    1.模型细化 vtk中实现网格细化的累有vtkLinearSubdivisionFilter.vtkLoopsubdivisionFilter.vtkButterflySubdivisionFilte ...

最新文章

  1. linux进程下的线程数,Linux下查看进程线程数的方法
  2. MyEclipse配置Tomcat 6
  3. QML笔记-对QML中信号与槽的进一步认识
  4. Mysql 导出 sql的执行结果到 csv文件
  5. 特征提取与检测(三) --- ORB算法
  6. mac电脑如何查看ip地址
  7. 支付宝架构师的总结:为什么他们能抗住万亿级流量的高并发?
  8. 深度学习:卷积神经网络之移动网络(MobileNet)
  9. Machine Learning A-Z学习笔记16-Thompson抽样算法
  10. 对《骨骼运动变换的数学计算过程详解》一文的理解
  11. ie浏览器js不刷新和乱码问题
  12. 汇正财经推荐股票靠谱吗?说说自己的经历
  13. file_get_contents failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request
  14. 如何用python爬取新浪财经
  15. 机器学习之PQ量化算法
  16. seq2seq模型_具有注意力机制的seq2seq模型
  17. 2017蓝桥杯java本科模拟赛
  18. linux安装过程中遇到了“kernel panic : no working init found“的解决措施
  19. 淘宝数据包转ECSHOP数据包的操作步骤
  20. nonlinear transformation

热门文章

  1. 敏捷团队如何进行绩效考核?
  2. NET许可证及License
  3. NYOJ 5177 疯牛(最大化最小值 二分搜索)
  4. Colorful Lecture Note(栈的模拟)
  5. hdu-4539 郑厂长系列故事――排兵布阵(状态压缩)
  6. nyoj - 947(Max Xor)字典树
  7. NYOJ 558 一二三
  8. 蜗牛慢慢爬 LeetCode 6. ZigZag Conversion [Difficulty: Medium]
  9. 8080处理器计算机启动
  10. [RM HA 1] Cloudera CDH5 RM HA功能验证