vtkPolyData

转自优快云博主「JayneYJ」的原创文章
原文链接:https://blog.youkuaiyun.com/kateyabc/article/details/83868359

VTK图像处理引言

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

vtkpolydata介绍

vtkpolydata用来表示顶点、线、多边形、三角形带在内的几何结构,即三维实体。
setpoints:通过函数setpoints设置点信息:
setpolys:通过设置单元排列(cell array)来定义多边形,单元排列(cell array)用来定义多边形的表示(多边形按点顺序进行定义)。
setstrips:通过设置单元排列(cell array)来定义三角形带strip,setverts:设置顶点,等。
vtkpoints:用来操作vtk中的点,可以调用setpoint或insertpoint来设置点的vtkidtype(类似id的值)和三维坐标,2个函数的功能相同,区别在于insertpoint先要完成点的范围检查和内存分配工作,所以速度较慢。注:这2个函数的实质是调用settuple或inserttuple在数组的第i个位置赋值。适用于bit、char、double、float等所有array类型。以vtkfloatarray为例函数void vtkfloatarray::settuple( const vtkidtype i,const float *tuple ) [virtual] 的第一个参数是位置内容,第二个参数是数据指针。实际操作的时候只需要考虑vtkpoints的指针就可以了,只是在点操作的时候才需要调用上述函数。
vtkcellarray:用来操作cell单元,调用insertnextcell函数逐步添加新的cell,例如函数vtkcellarray::insertnextcell ( vtkidtype npts, vtkidtype * pts ) [inline] 的第一个参数值标是cell中点的个数,第二个参数指向那些点的坐标数据。(说明:vtkidtype * pts 存储的是所包括点在points中的顺序信息,其个数当然应该和前面的npts一致。),2点可以连成一条线,三点可以得到一个面。也就是说:vtk中关于点、线、面的那些信息都是存放在cellarray中,应用时也是直接对cellarray指针进行处理,数据的写入和读取在vtkcellarray类完成。
然后定义vtkpolydatamapper,通过setinput输入vtkpolydata信息,再定义vtkactor,调用setmapper 导入vtkpolydatamapper,接下来vtkrenderer,调用addactor,然后 vtkrenderwindow调用render,再加上其他辅助的函数,就可以完整的完成输出了。
自己理解的就是通过vtkpoints和vtkcellarray两个类来获取点和cell单元的数据,然后vtkpoints通过setpoints函数将点集与vtkploydadta连接,vtkcellarray通过setploys将cell单元与vtkploydata连接

例子:
int i;
static float x[4][3]={{0,0,0}, {1,0,0}, {0,1,0},{0,0,1}}; 
static vtkidtype pts[4][3]={{0,1,2},{0,1,3},{0,2,3},{1,2,3}};
//这里说明了每个pts[i]由哪几个点构成,如第一个由{0,0,0}, {1,0,0}, {0,1,0}组成。
//实际上就是定义一个面 
vtkpolydata *polydata = vtkpolydata::New(); 
vtkpoints *points = vtkpoints::New();
vtkcellarray *polys = vtkcellarray::New(); 
for (i=0; i<4; i++) points->insertpoint(i,x[i]);//输入各点
for (i=0; i<4; i++) polys->insertnextcell(3,pts[i]);//输入各cell信息
//给vtkpolydata设置点面信息
polydata->setpoints(points);//设置点的位置 
points->delete(); 
polydata->setpolys(polys);//设置cell(面)的信息
polys->delete(); 
//映射 
vtkpolydatamapper *polydatamapper = vtkpolydatamapper::new(); 
polydatamapper->setinput(tetrahedron);

————————————————————
例子:

#include "stdafx.h"
#include "vtkCellArray.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIntArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
int _tmain(int argc, _TCHAR* argv[])
{
int i;
//创建一个浮点型数组存储"点"
vtkFloatArray *pcoords = vtkFloatArray::New();
//设置维度,点->3
pcoords->SetNumberOfComponents( 3 );
//设置数组个数
pcoords->SetNumberOfTuples( 4 );
//指定每一个数组,具体的点坐标
float pts[4][3] = { { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 },
       { 1.0, 0.0, 0.0 }, { 1.0, 1.0, 0.0}} ;
for( i=0; i<4; i++ )
{
   //设置数组中的点
   pcoords->SetTuple( i, pts[i] );
}
vtkPoints *points = vtkPoints::New();
//获得四个点
points->SetData( pcoords );
//创建网格数组
vtkCellArray *strips = vtkCellArray::New();
//设置单元由几个点组成
/* strips->InsertNextCell( 4 );
strips->InsertCellPoint( 0 );
strips->InsertCellPoint( 1 );
strips->InsertCellPoint( 2 );
strips->InsertCellPoint( 3 );*/
strips->InsertNextCell( 3 );
strips->InsertCellPoint( 0 );
strips->InsertCellPoint( 1 );
strips->InsertCellPoint( 2 );
//strips->InsertCellPoint( 3 );
//创建整形数组
vtkIntArray *temperature = vtkIntArray::New();
temperature->SetName( "Temperature" );
temperature->InsertNextValue( 60 );
temperature->InsertNextValue( 70 );
temperature->InsertNextValue( 80 );
// temperature->InsertNextValue( 90 );
/* //创建双精度型数组
vtkDoubleArray *vorticity = vtkDoubleArray::New();
vorticity->SetName( "Vorticity" );
vorticity->InsertNextValue( 2.7 );
vorticity->InsertNextValue( 4.1 );
vorticity->InsertNextValue( 5.3 );
vorticity->InsertNextValue( 3.4 );*/
//创建数据集
vtkPolyData *polydata = vtkPolyData::New();
//指定点和网格
polydata->SetPoints( points );
polydata->SetStrips( strips );
//指定标量
polydata->GetPointData()->SetScalars( temperature );
//polydata->GetPointData()->AddArray( vorticity ); 
vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
mapper->SetInput( polydata );
mapper->SetScalarRange( 0, 40 );
// Create an actor.
vtkActor* actor = vtkActor::New();
actor->SetMapper(mapper);
// Create the rendering objects.
vtkRenderer* ren = vtkRenderer::New();
ren->AddActor(actor);
vtkRenderWindow* renWin = vtkRenderWindow::New();
renWin->AddRenderer(ren);
vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
iren->Initialize();
iren->Start();
return 0;
}

————————————————————
使用python 调用vtk展示自己定义的数据模型,并进行颜色映射。

import vtk
 
x=[[0,0,0],[4,0,0],[4,4,0],[0,4,0],[1,1,1],[3,1,1],[3,3,1],[1,3,1]]
y=[[0,1,2,3],[4,5,6,7],[0,1,5,4],[1,2,6,5],[2,3,7,6],[3,0,4,7]]
 
#把点添加到数据结构中
points = vtk.vtkPoints()
for i in range(8):
    points.InsertPoint(i,x[i])
 
#把面添加到数据结构中
ploys = vtk.vtkCellArray()
for i in range(6):
    ploys.InsertNextCell(4,y[i])
 
#为每一个点设置一个标量(用来进行颜色映射)
scalars = vtk.vtkFloatArray()
for i in range(8):
    scalars.InsertTuple1(i,i)
 
#创建一个多边形结构体,并把数据填充进去
cube = vtk.vtkPolyData()
cube.SetPoints(points)
cube.SetPolys(ploys)
cube.GetPointData().SetScalars(scalars)
 
#创建一个颜色映射表,若是不自己定义,系统会使用默认的
pColorTable = vtk.vtkLookupTable()
pColorTable.SetNumberOfColors(6)
pColorTable.SetTableValue(0,1.0,0.0,1.0,1.0)
pColorTable.SetTableValue(1,0.0,1.0,1.0,1.0)
pColorTable.SetTableValue(2,1.0,1.0,1.0,1.0)
pColorTable.SetTableValue(3,1.0,0.0,1.0,1.0)
pColorTable.SetTableValue(4,0.0,0.0,1.0,1.0)
pColorTable.SetTableValue(5,1.0,1.0,0.0,1.0)
#上面是颜色手动定义6种,下面是自己定义生成的,使用一种就可以
# pColorTable.SetNumberOfColor(256)
# pColorTable.SetHueRange(1.0,0.0)
pColorTable.Build()
 
#创建一个舞台和演员(类比理解哈~)
mapper = vtk.vtkPolyDataMapper()
if vtk.VTK_MAJOR_VERSION <= 5:
    mapper.SetInput(cube)
else:
    mapper.SetInputData(cube)
#0指最小值,8指最大值。每个点都有自己的标量,根据标量在哪个范围然后映射到颜色表上
mapper.SetScalarRange(0,8)
mapper.SetLookupTable(pColorTable)
actor = vtk.vtkActor()
actor.SetMapper(mapper)
 
#定义相机
camera = vtk.vtkCamera()
camera.SetPosition(1,1,1)
camera.SetFocalPoint(0,0,0)
 
#定义渲染等
render = vtk.vtkRenderer()
render.AddActor(actor)
render.SetActiveCamera(camera)
render.ResetCamera()
render.SetBackground(1,1,1)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(render)
 
#展示
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
renWin.Render()
iren.Start()
 
————————————————
版权声明:本文为优快云博主「california94」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/california94/article/details/84497404

————————————————————

vtkPolyData数据生成与显示

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

例子:

#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); //vtkPolyDataMapper用于接受VTKPolyData图形数据以实现图像数据到渲染图元的转换
 
	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;
}

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

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

————————————————
转自优快云博主「JayneYJ」的原创文章
原文链接:https://blog.youkuaiyun.com/kateyabc/article/details/83868359

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值