很高兴在雪易的CSDN遇见你 ,给你糖糖
欢迎大家加入雪易社区-CSDN社区云
前言
本文分享vtkPolyData接口及常用的方法实现原理,vtkPolyData作为VTK中的重要接口,掌握了vtkPolyData的数据结构及相关方法才能有助于更好的理解VTK,希望对各位小伙伴有所帮助!
感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!
你的点赞就是我的动力(^U^)ノ~YO
我将收获到的:
1. 了解vtkPolyData的介绍
2. 掌握vtkPolyData构建方法
3. vtkPolyData的常用方法
目录
1)GetCellNeighbors-获取指定Cell,指定点的相邻Cell
3) vtkPolyData->vtkUnstructuredGrid
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