VTK-vtkPolyData解读

很高兴在雪易的CSDN遇见你 ,给你糖糖

欢迎大家加入雪易社区-CSDN社区云 


前言

本文分享vtkPolyData接口及常用的方法实现原理,vtkPolyData作为VTK中的重要接口,掌握了vtkPolyData的数据结构及相关方法才能有助于更好的理解VTK,希望对各位小伙伴有所帮助!

感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!

你的点赞就是我的动力(^U^)ノ~YO

我将收获到的:

        1. 了解vtkPolyData的介绍

        2. 掌握vtkPolyData构建方法

        3. vtkPolyData的常用方法

目录

前言

1. vtkPolyData介绍

 2. vtkPolyData构建方法

3. 涉及的方法

1)GetCellNeighbors-获取指定Cell,指定点的相邻Cell

2)获取PolyData的全部内容

3) vtkPolyData->vtkUnstructuredGrid

4)重新构建输入vtkPolyData数据的Mesh数据

结论:


1. vtkPolyData介绍

vtkPolyData是一系列的数据集包括vertices,lines,polygons,triangle strips。

vtkPolyData是vtkDataSet的具体实现,代表了一系列的几何结构,包括vertices,lines,polygons,triangle strips,以及Point和Cell属性结构。

vtkPolyData支持的Cell类型为vtkVertex, vtkPolyVertex, vtkLine, vtkPolyLine, vtkTriangle, vtkQuad, vtkPolygon, and vtkTriangleStrip。

 

 

 注意:

1. vtkPolyData实现了代表0D的vertices,1D的Lines,2D的Polygons和TriangleStrips;因此vtkPolyData可以创建由混合单元格类型组成的vtkPolyData实例。由于接口的设计特性,vtkPolyData在插值时必须按顺序进行处理:按顶点(vtkVertex和vtkPolyVertex)的顺序,线(vtkLine和vtkPolyLine),多边形(vtkTriangle,vtkQuad,vtkPolygon) 和 三角带(vtkTriangleStrip)。小伙伴可以参考vtkClipClosedSurface的具体实现来学习具体过程,附上相关博文链接:VTK中Clip/Trim总结_雪易的博客-CSDN博客

2. 在Filter的具体实现中,可能会将vtkTriangleStrip转换为vtkTriangles进行处理(vtkClipClosedSurface就是这么操作的);也可能会将vtkDecimatePro转换为vtkTriangles或vtkTriangleStrip;

 2. vtkPolyData构建方法

        vtkPolyData数据的构建流程包括:定义点数据,定义Cell数据结构。

        示例如下:

#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkNamedColors.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolygon.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>

int main(int, char *[])
{
  vtkSmartPointer<vtkNamedColors> colors =
    vtkSmartPointer<vtkNamedColors>::New();

  // Setup four points
  vtkSmartPointer<vtkPoints> points =
    vtkSmartPointer<vtkPoints>::New();
  points->InsertNextPoint(0.0, 0.0, 0.0);
  points->InsertNextPoint(1.0, 0.0, 0.0);
  points->InsertNextPoint(1.0, 1.0, 0.0);
  points->InsertNextPoint(0.0, 1.0, 0.0);
  
  // Create the polygon
  vtkSmartPointer<vtkPolygon> polygon =
    vtkSmartPointer<vtkPolygon>::New();
  polygon->GetPointIds()->SetNumberOfIds(4); //make a quad
  polygon->GetPointIds()->SetId(0, 0);
  polygon->GetPointIds()->SetId(1, 1);
  polygon->GetPointIds()->SetId(2, 2);
  polygon->GetPointIds()->SetId(3, 3);
  
  // Add the polygon to a list of polygons
  vtkSmartPointer<vtkCellArray> polygons =
    vtkSmartPointer<vtkCellArray>::New();
  polygons->InsertNextCell(polygon);

  // Create a PolyData
  vtkSmartPointer<vtkPolyData> polygonPolyData =
    vtkSmartPointer<vtkPolyData>::New();
  polygonPolyData->SetPoints(points);
  polygonPolyData->SetPolys(polygons);

  // Create a mapper and actor
  vtkSmartPointer<vtkPolyDataMapper> mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputData(polygonPolyData);

  vtkSmartPointer<vtkActor> actor =
    vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(
    colors->GetColor3d("Silver").GetData());

  // Visualize
  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->SetWindowName("Polygon");
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderer->SetBackground(colors->GetColor3d("Salmon").GetData());
  renderWindow->Render();
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

3. 涉及的方法

1)GetCellNeighbors-获取指定Cell,指定点的相邻Cell

   /**
   * Get the neighbors at an edge. More efficient than the general
   * GetCellNeighbors(). Assumes links have been built (with BuildLinks()),
   * and looks specifically for edge neighbors.
   */
  void GetCellEdgeNeighbors(vtkIdType cellId, vtkIdType p1, vtkIdType p2, vtkIdList* cellIds);

注意:若vtkPolyData数据为拷贝而来,但未进行Link时,调用GetCellEdgeNeighbors会出错。同样的针对GetPointCells, GetCellNeighbors等方法均会出错。

例如:

vtkPolyData* pd = vtkPolyData::New();

pd->DeepCopy((vtkPolyData*)obj);

...

pd->GetCellNeighbor(...); 调用此函数将会出错。 

2)获取PolyData的全部内容

vtkPolyData* pd = ...

//获取pd中的点
vtkPoints* inPts = pd->GetPoints();
vtkIdType numPts = pd->GetNumberOfPoints();

//获取pd中所有的Cells,包括vertex,line,poly,strip
vtkCellArray* vertexs = pd->GetVerts();
vtkCellArray* lines = pd->GetLines();
vtkCellArray* polys = pd->GetPolys();
vtkCellArray* strips = pd->GetStrips();
vtkIdType numVertexs = pd->GetNumberOfVerts();
vtkIdType numLines = pd->GetNumberOfLines();
vtkIdType numPolys = pd->GetNumberOfPolys();
vtkIdType numStrips = pd->GetNumberOfStrips();

//numcells = numVertexs+numLines+numPolys+numStrips
vtkIdType numCells = pd->GetNumberOfCells();
vtkPolyData* pd = ...
vtkIdType cellId;
vtkIdType numCells = pd->GetNumberOfCells();
vtkGenericCell* cell;
vtkPoints* cellPts;
vtkIdList* cellIds;
for (cellId = 0; cellId < numCells; cellId++)
{
  pd->GetCell(cellId, cell);
  cellPts = cell->GetPoints();
  cellIds = cell->GetPointIds();
}

3) vtkPolyData->vtkUnstructuredGrid

vtkUnstructuredGrid* uGrid = vtkUnstructuredGrid::New();
uGrid->SetPoints(inPts);

const vtkIdType* pts = nullptr;
vtkIdType npts;
for (vtkIdType id = 0; id < numCells; id++)
{
	pd->GetCellPoints(id, npts, pts);
	uGrid->InsertNextCell(pd->GetCellType(id), npts, pts);
}

        vtkUnstructuredGrid -> vtkPolyData转换:VTK-数据集vtkUnstructuredGrid_雪易的博客-CSDN博客

4)重新构建输入vtkPolyData数据的Mesh数据

        将Polys和Strips合并为Polys输出为Mesh数据

vtkPolyData* Mesh = vtkPolyData::New();
Mesh->SetPoints(inPts);
vtkCellArray *newPolys, *inPolys = input->GetPolys();
if (numStrips > 0)
{
  newPolys = vtkCellArray::New();
  if (numPolys > 0)
  {
    newPolys->DeepCopy(inPolys);
  }
  else
  {
    newPolys->AllocateEstimate(numStrips, 5);
  }
  vtkCellArray* inStrips = input->GetStrips();
  for (inStrips->InitTraversal(); inStrips->GetNextCell(npts, pts);)
  {
    vtkTriangleStrip::DecomposeStrip(npts, pts, newPolys);
  }
  Mesh->SetPolys(newPolys);
  newPolys->Delete();
}
else
{
  newPolys = inPolys;
  Mesh->SetPolys(newPolys);
}
Mesh->BuildLinks();

注意:若直接在vtkPolyData数据上进行处理会发生内存占用导致异常退出;因此通常会将待处理的数据重新构建为Mesh数据,这样可避免此类问题。

如:vtkFillHolesFilter等常见的过滤器。 

 

结论:

        本文主要介绍vtkPolyData的描述、数据构建方法及vtkPolyData常见的使用方法。

若小伙伴有想了解的,但未在本文展示的也可以联系我哟!

感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!

你的赞赏是我的最最最最大的动力(^U^)ノ~YO

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪易

给我来点鼓励吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值