1.VTKPolyData源数据总结
1之前的实例中,我们利用VTKConeSource源数据创建了一个棱锥。实际上VTK内部提供可以写数据源类来快速获取简单的图形数据。下面给出了最常见的几种VTKPolyData数据源类:
2.vtkPolyData数据的创建
前面多采用图像或者VTK合成源数据进行讨论。在这里,我们希望深入底层,显示地定义一个点集合和一个单元集合。点集合定义了VTKPolyData的几何数据;单元集合定义了点的拓扑结构。每个单元由点的索引而非坐标来定义。这样能够减少数据的存储空间。单元的类型可以是点、三角形、矩形、多边形等基本图元(注意:只有定义了单元数据才能显示该图形数据)。这需要根据实际情况来定义相应的图元。下面的实例演示了一个简单的VTKPolyData数据的创建过程:1 #include <vtkAutoInit.h> 2 VTK_MODULE_INIT(vtkRenderingOpenGL); 3 4 #include <vtkSmartPointer.h> 5 #include <vtkPoints.h> 6 #include <vtkPolygon.h> 7 #include <vtkTriangle.h> 8 #include <vtkCellArray.h> 9 #include <vtkPolyData.h> 10 /// 11 #include <vtkPolyDataMapper.h> 12 #include <vtkActor.h> 13 #include <vtkRenderer.h> 14 #include <vtkRenderWindow.h> 15 #include <vtkRenderWindowInteractor.h> 16 17 int main() 18 { 19 vtkSmartPointer<vtkPoints> pts = 20 vtkSmartPointer<vtkPoints>::New(); 21 pts->InsertNextPoint(0.0, 0.0, 0.0); 22 pts->InsertNextPoint(1.0, 0.0, 0.0); 23 pts->InsertNextPoint(1.0, 1.0, 0.0); 24 pts->InsertNextPoint(0.0, 1.0, 0.0); 25 pts->InsertNextPoint(2.0, 0.0, 0.0); 26 //拓扑结构 27 vtkSmartPointer<vtkPolygon> polygon = 28 vtkSmartPointer<vtkPolygon>::New(); 29 polygon->GetPointIds()->SetNumberOfIds(4); 30 polygon->GetPointIds()->SetId(0, 0); 31 polygon->GetPointIds()->SetId(1, 1); 32 polygon->GetPointIds()->SetId(2, 2); 33 polygon->GetPointIds()->SetId(3, 3); 34 polygon->GetPointIds()->SetId(4, 4); 35 36 vtkSmartPointer<vtkTriangle> triangle = 37 vtkSmartPointer<vtkTriangle>::New(); 38 triangle->GetPointIds()->SetId(0, 1); 39 triangle->GetPointIds()->SetId(1, 2); 40 triangle->GetPointIds()->SetId(2, 4); 41 42 vtkSmartPointer<vtkCellArray> cells = 43 vtkSmartPointer<vtkCellArray>::New(); 44 cells->InsertNextCell(polygon); 45 cells->InsertNextCell(triangle); //设置拓扑结构 46 //合成数据 47 vtkSmartPointer<vtkPolyData> polygonPolyData = 48 vtkSmartPointer<vtkPolyData>::New(); 49 polygonPolyData->SetPoints(pts); 50 polygonPolyData->SetPolys(cells); 51 52 vtkSmartPointer<vtkPolyDataMapper> mapper = 53 vtkSmartPointer<vtkPolyDataMapper>::New(); 54 mapper->SetInputData(polygonPolyData); 55 56 vtkSmartPointer<vtkActor> actor = 57 vtkSmartPointer<vtkActor>::New(); 58 actor->SetMapper(mapper); 59 60 vtkSmartPointer<vtkRenderer> render = 61 vtkSmartPointer<vtkRenderer>::New(); 62 render->AddActor(actor); 63 render->SetBackground(0.0, 0.0, 0.0); 64 65 vtkSmartPointer<vtkRenderWindow> rw = 66 vtkSmartPointer<vtkRenderWindow>::New(); 67 rw->AddRenderer(render); 68 rw->SetSize(320, 240); 69 rw->SetWindowName("Creating PolyData Structure"); 70 71 vtkSmartPointer<vtkRenderWindowInteractor> rwi = 72 vtkSmartPointer<vtkRenderWindowInteractor>::New(); 73 rwi->SetRenderWindow(rw); 74 rwi->Render(); 75 rwi->Start(); 76 77 return 0; 78 }
vtkPoints用于存储点集合。通过InserNextPoint()函数可以顺序地为其添加点,并返回点的索引,索引从0开始。另外,还可以通过函数SetNumberofPoints()来指定其点的个数,然后调用SetPoint()函数为对应索引点设置坐标。代码中含有5个坐标点。利用定义的5个坐标点的索引定义一个VTKPolygon多边形单元。vtkPolygon继承自vtkCell类,表示一个多边形单元。定义vtkPolygon单元时,需要指定组成改单元的点数(这里指定了四个点,所以定义的是四边形)。vtkPolygon内部定义了一个vtkIdList对象,该对象存储了点索引集合。通过调用vtkList类的SetNumberOfIds()函数可以设置点数,SetId则可以为指定的点设置索引,注意该索引必须是vtkPoints中的点索引。在该示例代码中利用四个点构成了一个四边形,利用三个点构成了一个三角形。上例的显示结果如下:VTK中定义了大量的单元类,这些类都继承自vtkCell,需要根据实际情况选择使用。这里面,我只对单元类型为三角形和多边形的图形进行了分析,这通常也被称为网格(Mesh)。在一个多边形网格模型总,连接网格点的称为边,每个单元有一系列的边顺序连接而成,也被戏称为面片。vtkCellArray用于存储所有的单元数据,InsertNextCell()函数一次插入定义的单元。只有点数据和单元数据都定义完毕才能通过下面的函数添加到vtkPolyData中:1 void SetPoints(vtkPoints*); 2 void SetPolys(vtkCellArray*p);
需要注意的是,SetPolys()接受的是多边形单元数组,如果单元类型为顶点、线段或者三角形带的话,则需要调用如下函数:
1 void SetVerts(vtkCellArray* v); 2 void SetLines(vtkCellArray* l); 3 void SetStrips(vtkCellArray* s);