6.1.2 vtkPolyData資料來源討論與資料建立
1.VTKPolyData源資料總結
1之前的例項中,我們利用VTKConeSource源資料建立了一個稜錐。實際上VTK內部提供可以寫資料來源類來快速獲取簡單的圖形資料。下面給出了最常見的幾種VTKPolyData資料來源類:
2.vtkPolyData資料的建立
前面多采用影象或者VTK合成源資料進行討論。在這裡,我們希望深入底層,顯示地定義一個點集合和一個單元集合。
點集合定義了VTKPolyData的幾何資料;單元集合定義了點的拓撲結構。每個單元由點的索引而非座標來定義。這樣能夠減少資料的儲存空間。
單元的型別可以是點、三角形、矩形、多邊形等基本圖元(注意:只有定義了單元資料才能顯示該圖形資料
下面的例項演示了一個簡單的VTKPolyData資料的建立過程:
#include"vtkSmartPointer.h" #include"vtkPoints.h" #include"vtkPolygon.h" #include"vtkTriangle.h" #include"vtkCellArray.h" #include"vtkPolyData.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);//此索引必須在vtkPoints中的點索引 polygon->GetPointIds()->SetId(1, 1);//setId為指定的點設定索引 polygon->GetPointIds()->SetId(2, 2); polygon->GetPointIds()->SetId(3, 3); polygon->GetPointIds()->SetId(4, 4); 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); 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; }
執行結果如下:
vtkPoints用於儲存點集合。通過InserNextPoint()函式可以順序地為其新增點,並返回點的索引,索引從0開始。另外,還可以通過函式SetNumberofPoints()來指定其點的個數,然後呼叫SetPoint()函式為對應索引點設定座標。程式碼中含有5個座標點。
利用定義的5個座標點的索引定義一個VTKPolygon多邊形單元。vtkPolygon繼承自vtkCell類,表示一個多邊形單元。定義vtkPolygon單元時,需要指定組成改單元的點數(這裡指定了四個點,所以定義的是四邊形)。vtkPolygon內部定義了一個vtkIdList物件,該物件儲存了點索引集合。通過呼叫vtkList類的SetNumberOfIds()函式可以設定點數,SetId則可以為指定的點設定索引,注意該索引必須是vtkPoints中的點索引
VTK中定義了大量的單元類,這些類都繼承自vtkCell,需要根據實際情況選擇使用。這裡面,我只對單元型別為三角形和多邊形的圖形進行了分析,這通常也被稱為網格(Mesh)。在一個多邊形網格模型中,連線網格點的稱為邊,每個單元由一系列的邊順序連線而成,也被稱為面片。
vtkCellArray用於儲存所有的單元資料,InsertNextCell()函式一次插入定義的單元。只有點資料和單元資料都定義完畢才能通過下面的函式新增到vtkPolyData中:
void SetPoints(vtkPoints*);
void SetPolys(vtkCellArray*p);
需要注意的是,SetPolys()接受的是多邊形單元陣列,如果單元型別為頂點、線段或者三角形帶的話,則需要呼叫如下函式:
void SetVerts(vtkCellArray* v);
void SetLines(vtkCellArray* l);
void SetStrips(vtkCellArray* s);
參考資料:
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