VTK_Learning_图形进阶_vtkPolyData数据生成与显示,再次理解vtkPolyData

1.VTK图像处理引言

图像数据的应用非常广泛,最贴近日常生活的应用是3D游戏,其中每个角色的模型、场景等都是图形数据。当然,游戏仅仅是图像数据的一个应用点。图形在CAD(计算机辅助设计)、影视、医学、地质、气象数据建模等领域中均有着广泛的应用。vtkPolyData是VTK中常用的数据结构之一,可以表示小到一个点、一条线,达到一个模型、一个场景等。
 

 2.vtkPolyData数据生成与显示

之前也曾说过,在这里只是简单的回顾,更重要滴在于深入地理解。
VTKPolyData主要由几何结构数据、拓扑结构数据、属性数据组成。
几何结构数据:组成模型的点集;
拓扑结构数据:这些点根据一定的连接关系组成的单元数据;表明集合点集之间的拓扑关系
属性数据:与几何结构数据和拓扑结构数据相关联,属性数据可以是标量、向量或者张量。
例如,可以为其中的每个点定义曲率属性数据,也可以为其中的每一个单元定义一个法向量属性数据。在VTKPolyData可视化中会利用这些属性数据直接或者间接计算单元或点的颜色。
实例如下:
 

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
 
#include <vtkSmartPointer.h>
#include <vtkConeSource.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
 
int main()
{
	vtkSmartPointer<vtkConeSource> coneSource =
		vtkSmartPointer<vtkConeSource>::New();
	coneSource->Update();
 
	vtkSmartPointer<vtkPolyData> polyData =
		vtkSmartPointer<vtkPolyData>::New();
	polyData = coneSource->GetOutput();
	int nPoints = polyData->GetNumberOfPoints();
	int nCells = polyData->GetNumberOfCells();
	std::cout << "几何数据(点数):" << nPoints << std::endl;
	std::cout << "拓扑数据(单元):" << nCells << std::endl;
 
	vtkSmartPointer<vtkPolyDataMapper> mapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputData(polyData);
 
	vtkSmartPointer<vtkActor>  actor =
		vtkSmartPointer<vtkActor>::New();
	actor->SetMapper(mapper);
 
	vtkSmartPointer<vtkRenderer> render =
		vtkSmartPointer<vtkRenderer>::New();
	render->AddActor(actor);
	render->SetBackground(10, 0, 0);
 
	vtkSmartPointer<vtkRenderWindow> rw =
		vtkSmartPointer<vtkRenderWindow>::New();
	rw->AddRenderer(render);
	rw->SetSize(640, 480);
	rw->SetWindowName("PolyData Structure Learning");
	rw->Render();
 
	vtkSmartPointer<vtkRenderWindowInteractor> rwi =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	rwi->SetRenderWindow(rw);
	rwi->Initialize();
	rwi->Start();
 
	return 0;
}

上述代码中,
VTKConeSource类定义了一个锥形图形数据,其输出为VTKPolyData类型数据。VTKPolyData的成员函数GetNumberOfPoints()和GetNumberOfCells()分别用来获取图形数据的点数和单元数目。
接下来是定义一个图形数据的渲染管线,包括VTKPolyDataMapper()、vtkActor()、VTKRender()、vtkRenderWindow()和vtkRenderWindowInteractor()。这个渲染流程和图像渲染管线基本一致。需要注意的是,对于VTKPolyData类型数据的渲染管线,需要定义vtkPolyDataMapper对象,用于接受VTKPolyData图形数据以实现图像数据到渲染图元的转换。
程序的显示结果如下所示:

从结果可以看出,该椎体是由7个空间点构成了7个单元(7个面)的数据组成。这里也仅仅定义了一个空间的椎体,并未给点或者单元数据设置属性信息。

 

3.vtkPolyData再次理解

几何结构:点

拓扑机构:顶点、线、面,表示点的链接方式。

(1)设置顶点拓扑结构

//创建点坐标
	int X[3] = {1.0,0.0,0.0};
	int Y[3] = {0.0,0.0,0.0};
	int Z[3] = {0.0,1.0,0.0};
 
	//创建点数据&创建使每一个点加入类似顶点类型的Cell
	vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
	vtkSmartPointer<vtkCellArray> vertics = vtkSmartPointer<vtkCellArray>::New();
	for (unsigned int i=0; i<3; i++)
	{
		//定义用来存储点索引的中间变量,vtkIdType相当int long等类型
		vtkIdType pId[1];
		//把点坐标加入VTKPoints中,InserNextPoint()返回加入点的索引;
		//使用这个索引号创建定点类型Cell
		pId[0] = points->InsertNextPoint(X[i],Y[i],Z[i]);
		
		//每个坐标点都需要创建一个顶点Cell
		vertics->InsertNextCell(1,pId);
	}
	//创建VTKPolyData对象
	vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
	//将几何结构 & 拓扑结构加入到数据集中
	polydata->SetPoints(points);
	polydata->SetVerts(vertics);

vertics->InsertNextCell(1,pId);第一个参数为点的数目,第二个参数为id数组,第一个参数决定了数组的长度。

以此类推,

如果是线,则pId[2]={id1,id2};    InsertNextCell(2,pId); 

如果是三角形,则pId[2]={id1,id2,id3};    InsertNextCell(3,pId); 

(2)设置线拓扑结构

setId(0,1);表示索引为0的点到索引为1的点的连线

vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
	points->InsertNextPoint(1.0,0.0,0.0); // ID=0;
	points->InsertNextPoint(0.0,0.0,0.0); // ID=1;
	points->InsertNextPoint(0.0,1.0,0.0); // ID=2;
	//每两个点之间用直线连接
	//SetId(para1,para2);para1:出发端点的ID;para2:连接端点的ID
	vtkSmartPointer<vtkLine> line0 = vtkSmartPointer<vtkLine>::New();
	line0->GetPointIds()->SetId(0,0);
	line0->GetPointIds()->SetId(1,1);
 
	vtkSmartPointer<vtkLine> line1 = vtkSmartPointer<vtkLine>::New();
	line1->GetPointIds()->SetId(0,1);
	line1->GetPointIds()->SetId(1,2);
 
	vtkSmartPointer<vtkLine> line2 = vtkSmartPointer<vtkLine>::New();
	line2->GetPointIds()->SetId(0,2);
	line2->GetPointIds()->SetId(1,0);
	//创建Cell,存储拓扑特征:线段
	vtkSmartPointer<vtkCellArray> LineCell = vtkSmartPointer<vtkCellArray>::New();
	LineCell->InsertNextCell(line0);
	LineCell->InsertNextCell(line1);
	LineCell->InsertNextCell(line2);
	
	//创建数据集,并转入拓扑结构和几何结构
	vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
	polydata->SetPoints(points);
	polydata->SetLines(LineCell);

InsertNextCell(line); 直接插入线,推测线应该是,pId[2]={id1,id2};    InsertNextCell(2,pId); 

(3)设置多边形,三角形拓扑结构

总结:

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);
 


 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值