1. 程式人生 > >6.1.2 vtkPolyData資料來源討論與資料建立

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