1. 程式人生 > >6.1.3 vtkPolyData 屬性資料

6.1.3 vtkPolyData 屬性資料

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