6.1.3 vtkPolyData 属性数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kateyabc/article/details/84430985

1、图形着色

前一个实验显示结果中的图像是白色的,而图形颜色与vtkPolyData属性数据息息相关。由于并未指定任何颜色和属性数据,因此在显示时默认以白色显示。
属性数据包括点属性和单元属性。可以为vtkPolyData的点数据和单元数据分别指定属性数据。
属性数据可以是标量,如点的曲率;可以是向量,如点或者单元的法向量;也可以是张量,主要在流场中较为常见
颜色可以直接作为一种标量属性数据,设置到相应的点或者单元数据中,这也是最直接的一种图形着色方式。
下面的实例代码仅是对上例图形进行着色:


#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);
	//拓扑结构数据:正四边形
	//利用定义的5个坐标点定义一个多边形单元,vtkPolygon继承自vtkCell类,表示一个多边形单元

	vtkSmartPointer<vtkPolygon> polygon =
		vtkSmartPointer<vtkPolygon>::New();
	polygon->GetPointIds()->SetNumberOfIds(4);//设置点数
	polygon->GetPointIds()->SetId(0, 0);//为对应索引的点设置坐标,坐标为vtkpionts中定义的5个坐标点
	polygon->GetPointIds()->SetId(1, 1);
	polygon->GetPointIds()->SetId(2, 2);//setId为指定的点设置索引
	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();//有5个点数据
	ptColor->SetNumberOfComponents(3);//指定每个元组的大小,RGB三色分量组成
	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();//2个单元数据
	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、单元的标量属性和矢量属性数据设置

/******************单元标量属性和矢量属性数据设置*******************************/
//很多情况下,模型颜色是通过属性数据获取的,比如根据标量数据在颜色查找表中获取相应的颜色
#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();//定义3*3的网格数据
	gridSource->SetXResolution(3);
	gridSource->SetYResolution(3);
	gridSource->Update();
    //构成几何拓扑结构数据
	vtkSmartPointer<vtkPolyData> grid = gridSource->GetOutput();
	//标量属性数据,默认情况下,其元组大小为1
	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);//InsertNextTuple3可以方便地插入向量数据
	}
 
	grid->GetCellData()->SetScalars(cellScalars);
	grid->GetCellData()->SetVectors(cellVector);
 
	vtkSmartPointer<vtkLookupTable> lut =
		vtkSmartPointer<vtkLookupTable>::New();
	lut->SetNumberOfTableValues(10);//setLookupTable()函数设置定义的颜色映射表,如果不指定,会使用内部定义的默认颜色表
	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;
}

运行结果:(右图是SetLookupTable()函数不指定时,使用内部定义的默认颜色表)

                   

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

参考资料:

1.《The Visualization Toolkit – AnObject-Oriented Approach To 3D Graphics (4th Edition)》
2. 张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

所用软件:vtk7.0+visual studio 2013
注:此文知识学习笔记,仅记录完整程序和实现结果,具体原理参见:

https://blog.csdn.net/www_doling_net/article/details/8541534

https://blog.csdn.net/shenziheng1/article/category/6114053/4
 

猜你喜欢

转载自blog.csdn.net/kateyabc/article/details/84430985