VTK基础教程(1)- vtkPolyData 介绍

目录

VTK的编译与环境搭建

VTK一般渲染流程

VTK数据类型-vtkPolyData

使用vtk自带的多边形数据

 使用自己创建的数据

添加顶点颜色

添加面颜色


VTK的编译与环境搭建

这部分目前已经有了大佬做了成熟的傻瓜式配置,大家可以参考这篇文章:VTK+VS2019(或其他版本均可) 傻瓜式一站式 配置_Nancy_fairy的博客-优快云博客_vs2019 vtk

VTK一般渲染流程

这部分的介绍也很多,大家可以参考这篇文章:VTK笔记-了解VTK_黑山老妖的博客-优快云博客_vtk应用领域最近,重新学习了VTK相关内容,网上资料质量参差不齐,自己从多处搜集资料,整理记录之;VTK简介Vtk,(visualization toolkit)是一个开源的免费软件系统,主要用于三维计算机图形学、图像处理和可视化。Vtk是在面向对象原理的基础上设计和实现的,它的内核是用C++构建的,包含有大约250,000行代码,2000多个类,还包含有几个转换界面,因此也可以自由的通过Java,Tcl/Tk和Python各种语言使用vtk。视觉化工具函式库(VTK,Visualization Toolkit)https://blog.youkuaiyun.com/liushao1031177/article/details/115503446

VTK数据类型-vtkPolyData

多边形数据集主要由顶点、多顶点、线、折线和三角形地带等单元组成。
顶点、线和多边形构成了用来表达0、1和2维几何图形的基本要素的最小集合。特别是三角形带,表达N个三角形仅需N+2个点,且大多数图形渲染三角形带速度极快。


使用vtk自带的多边形数据

vtk自带很多的成熟的多边形数据,包括圆柱,球体,锥体等。我们仅需设置几个属性就可以使用现成的数据创建模型并显示。以下为创建显示锥体的代码

void SimpleVtk()
{
	vtkConeSource* source = vtkConeSource::New();
	source->SetHeight(13);
	source->SetRadius(5);

	vtkPolyDataMapper* coneMapper = vtkPolyDataMapper::New();
	coneMapper->SetInputConnection(source->GetOutputPort());

	vtkActor* coneActor = vtkActor::New();
	coneActor->SetMapper(coneMapper);

	vtkRenderer* render = vtkRenderer::New();
	vtkRenderWindow* renwin = vtkRenderWindow::New();
	vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();

	render->AddActor(coneActor);
	render->SetBackground(0.8, 0.4, 0.4);

	renwin->AddRenderer(render);

	iren->SetRenderWindow(renwin);
	iren->Initialize();
	iren->Start();

	source->Delete();
	coneMapper->Delete();
	coneActor->Delete();
	render->Delete();
	renwin->Delete();
	iren->Delete();
}

首先创建锥体资源,并设置其属性,紧接着将其传递给映射器,映射器将结果传递给渲染组件进行渲染显示。以下为运行的结果:

 使用自己创建的数据

当然有时候默认的模型会不够用,我们想要自己创建模型。以下为创建一个四面体的代码:

void makePolyData()
{
	vtkPoints* points = vtkPoints::New();
	points->InsertNextPoint(0.0, 0.0, 0.0);
	points->InsertNextPoint(1.0, 0.0, 0.0);
	points->InsertNextPoint(0.0, 1.0, 0.0);
	points->InsertNextPoint(0.0, 0.0, 1.0);

	vtkTriangle* tran1 = vtkTriangle::New();
	tran1->GetPointIds()->SetId(0, 0);
	tran1->GetPointIds()->SetId(1, 1);
	tran1->GetPointIds()->SetId(2, 2);
	
	vtkTriangle* tran2 = vtkTriangle::New();
	tran2->GetPointIds()->SetId(0, 0);
	tran2->GetPointIds()->SetId(1, 1);
	tran2->GetPointIds()->SetId(2, 3);

	vtkTriangle* tran3 = vtkTriangle::New();
	tran3->GetPointIds()->SetId(0, 0);
	tran3->GetPointIds()->SetId(1, 2);
	tran3->GetPointIds()->SetId(2, 3);

	vtkTriangle* tran4 = vtkTriangle::New();
	tran4->GetPointIds()->SetId(0, 1);
	tran4->GetPointIds()->SetId(1, 2);
	tran4->GetPointIds()->SetId(2, 3);

	vtkCellArray* cells = vtkCellArray::New();
	cells->InsertNextCell(tran1);
	cells->InsertNextCell(tran2);
	cells->InsertNextCell(tran3);
	cells->InsertNextCell(tran4);

	vtkPolyData* source = vtkPolyData::New();
	source->SetPoints(points);
	source->SetPolys(cells);

	vtkPolyDataMapper* coneMapper = vtkPolyDataMapper::New();
	coneMapper->SetInputData(source);

	vtkActor* coneActor = vtkActor::New();
	coneActor->SetMapper(coneMapper);

	vtkRenderer* render = vtkRenderer::New();
	vtkRenderWindow* renwin = vtkRenderWindow::New();
	vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();

	render->AddActor(coneActor);
	render->SetBackground(0.8, 0.4, 0.4);

	renwin->AddRenderer(render);

	iren->SetRenderWindow(renwin);
	iren->Initialize();
	iren->Start();

	points->Delete();
	tran1->Delete();
	tran2->Delete();
	tran3->Delete();
	tran4->Delete();
	cells->Delete();
	source->Delete();
	coneMapper->Delete();
	coneActor->Delete();
	render->Delete();
	renwin->Delete();
	iren->Delete();
}

首先创建点资源,并通过InsertNextPoint方法添加坐标点,其次创建四面体的四个三角形,通过GetPointIds()->SetId()方法设置点的索引,然后再将四个三角形通过InsertNextCell方法添加进多边形单元中。再然后将点资源和多边形单元添加到vtkPolyData中,将Data置入渲染流程即可显示这个四面体。以下为输出的结果:

 很显然这种生成方式略显繁琐,vtk可以添加三角形带进入多边形单元中。一般情况下的3D模型都是由三角形带组成的,且三角形带非常节约资源且渲染速度快。以下为三角形带的代码:

void makePolyData2()
{
	vtkPoints* points = vtkPoints::New();
	points->InsertNextPoint(0.0, 0.0, 0.0);
	points->InsertNextPoint(1.0, 0.0, 0.0);
	points->InsertNextPoint(0.0, 1.0, 0.0);
	points->InsertNextPoint(0.0, 0.0, 1.0);

	vtkCellArray* array = vtkCellArray::New();
	array->InsertNextCell(6);

	array->InsertCellPoint(1);
	array->InsertCellPoint(3);
	array->InsertCellPoint(0);
	array->InsertCellPoint(2);
	array->InsertCellPoint(1);
	array->InsertCellPoint(3);

	vtkPolyData* source = vtkPolyData::New();
	source->SetPoints(points);
	source->SetStrips(array);

	vtkPolyDataMapper* coneMapper = vtkPolyDataMapper::New();
	coneMapper->SetInputData(source);

	vtkActor* coneActor = vtkActor::New();
	coneActor->SetMapper(coneMapper);

	vtkRenderer* render = vtkRenderer::New();
	vtkRenderWindow* renwin = vtkRenderWindow::New();
	vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();

	render->AddActor(coneActor);
	render->SetBackground(0.8, 0.4, 0.4);

	renwin->AddRenderer(render);

	iren->SetRenderWindow(renwin);
	iren->Initialize();
	iren->Start();

	points->Delete();
	array->Delete();
	source->Delete();
	coneMapper->Delete();
	coneActor->Delete();
	render->Delete();
	renwin->Delete();
	iren->Delete();
}

通过InsertCellPoint方法将点的索引添加进三角带中,在资源中使用SetStrips添加三角带。以下为渲染结果:

添加顶点颜色

 既然我们已经成功的生成了四面体,但他是灰色的,显然不是很好看。以下为添加颜色显示的代码,首先是添加顶点颜色:

void makePolyDataAndSetColor()
{
	unsigned char red[3] = { 255, 0, 0 };
	unsigned char green[3] = { 0, 255, 0 };
	unsigned char blue[3] = { 0, 0, 255 };

	vtkPoints* points = vtkPoints::New();
	points->InsertNextPoint(0.0, 0.0, 0.0);
	points->InsertNextPoint(1.0, 0.0, 0.0);
	points->InsertNextPoint(0.0, 1.0, 0.0);
	points->InsertNextPoint(0.0, 0.0, 1.0);

	vtkCellArray* array = vtkCellArray::New();
	array->InsertNextCell(6);

	array->InsertCellPoint(1);
	array->InsertCellPoint(3);
	array->InsertCellPoint(0);
	array->InsertCellPoint(2);
	array->InsertCellPoint(1);
	array->InsertCellPoint(3);

	vtkUnsignedCharArray* pointsColors = vtkUnsignedCharArray::New();
	pointsColors->SetNumberOfComponents(3);
	pointsColors->InsertNextTypedTuple(red);
	pointsColors->InsertNextTypedTuple(green);
	pointsColors->InsertNextTypedTuple(blue);
	pointsColors->InsertNextTypedTuple(red);

	vtkPolyData* source = vtkPolyData::New();
	source->SetPoints(points);
	source->SetStrips(array);
	source->GetPointData()->SetScalars(pointsColors);

	vtkPolyDataMapper* coneMapper = vtkPolyDataMapper::New();
	coneMapper->SetInputData(source);

	vtkActor* coneActor = vtkActor::New();
	coneActor->SetMapper(coneMapper);

	vtkRenderer* render = vtkRenderer::New();
	vtkRenderWindow* renwin = vtkRenderWindow::New();
	vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();

	render->AddActor(coneActor);
	render->SetBackground(0.8, 0.4, 0.4);

	renwin->AddRenderer(render);

	iren->SetRenderWindow(renwin);
	iren->Initialize();
	iren->Start();

	points->Delete();
	array->Delete();
	pointsColors->Delete();
	source->Delete();
	coneMapper->Delete();
	coneActor->Delete();
	render->Delete();
	renwin->Delete();
	iren->Delete();
}

新建一个unsignedchar数组作为颜色资源,将颜色通过InsertNextTypedTuple()方法加入到颜色资源中。然后将顶点颜色资源通过GetPointData()->SetScalars()方法加入到polyData中。以下为渲染结果:

添加面颜色

当然我们也可以给每个面添加纯色:

void makePolyDataAndSetColor2()
{
	unsigned char red[3] = { 255, 0, 0 };
	unsigned char green[3] = { 0, 255, 0 };
	unsigned char blue[3] = { 0, 0, 255 };

	vtkPoints* points = vtkPoints::New();
	points->InsertNextPoint(0.0, 0.0, 0.0);
	points->InsertNextPoint(1.0, 0.0, 0.0);
	points->InsertNextPoint(0.0, 1.0, 0.0);
	points->InsertNextPoint(0.0, 0.0, 1.0);

	vtkTriangle* tran1 = vtkTriangle::New();
	tran1->GetPointIds()->SetId(0, 0);
	tran1->GetPointIds()->SetId(1, 1);
	tran1->GetPointIds()->SetId(2, 2);

	vtkTriangle* tran2 = vtkTriangle::New();
	tran2->GetPointIds()->SetId(0, 0);
	tran2->GetPointIds()->SetId(1, 1);
	tran2->GetPointIds()->SetId(2, 3);

	vtkTriangle* tran3 = vtkTriangle::New();
	tran3->GetPointIds()->SetId(0, 0);
	tran3->GetPointIds()->SetId(1, 2);
	tran3->GetPointIds()->SetId(2, 3);

	vtkTriangle* tran4 = vtkTriangle::New();
	tran4->GetPointIds()->SetId(0, 1);
	tran4->GetPointIds()->SetId(1, 2);
	tran4->GetPointIds()->SetId(2, 3);

	vtkCellArray* cells = vtkCellArray::New();
	cells->InsertNextCell(tran1);
	cells->InsertNextCell(tran2);
	cells->InsertNextCell(tran3);
	cells->InsertNextCell(tran4);

	vtkUnsignedCharArray* cellColors = vtkUnsignedCharArray::New();
	cellColors->SetNumberOfComponents(3);
	cellColors->InsertNextTypedTuple(red);
	cellColors->InsertNextTypedTuple(green);
	cellColors->InsertNextTypedTuple(blue);
	cellColors->InsertNextTypedTuple(red);

	vtkPolyData* source = vtkPolyData::New();
	source->SetPoints(points);
	source->SetPolys(cells);
	source->GetCellData()->SetScalars(cellColors);

	vtkPolyDataMapper* coneMapper = vtkPolyDataMapper::New();
	coneMapper->SetInputData(source);

	vtkActor* coneActor = vtkActor::New();
	coneActor->SetMapper(coneMapper);

	vtkRenderer* render = vtkRenderer::New();
	vtkRenderWindow* renwin = vtkRenderWindow::New();
	vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();

	render->AddActor(coneActor);
	render->SetBackground(0.8, 0.4, 0.4);

	renwin->AddRenderer(render);

	iren->SetRenderWindow(renwin);
	iren->Initialize();
	iren->Start();

	points->Delete();
	cellColors->Delete();
	tran1->Delete();
	tran2->Delete();
	tran3->Delete();
	tran4->Delete();
	cells->Delete();
	source->Delete();
	coneMapper->Delete();
	coneActor->Delete();
	render->Delete();
	renwin->Delete();
	iren->Delete();
}

 这次用的是GetCellData()->SetScalars()方法将面颜色传递给各个面。渲染结果如下:

 大家也可以试试同时添加顶点颜色和面颜色是什么效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值