VTK修炼之道45:图形进阶_vtkPolyData属性数据
生活随笔
收集整理的這篇文章主要介紹了
VTK修炼之道45:图形进阶_vtkPolyData属性数据
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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属性数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RIFF格式详解
- 下一篇: 飞鸽传书:服务器开发系列—系统构架