博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
VTK删除vtkPolyData中的顶点和面片
阅读量:4608 次
发布时间:2019-06-09

本文共 2781 字,大约阅读时间需要 9 分钟。

  应用VTK处理网格数据,基本都要用到vtkPolyData,包括点数据信息和拓扑结构进行。点信息数据存储在vtkPoints数据结构中,拓扑结构信息可以包括顶点(verts),线(lines),多边形(polys)和三角面片(strips)。拓扑结构信息的数据类型是vtkCharArray,只存储顶点信息的索引值,本文以polys为例。

  vtkPolyData提供便利数据添加功能,添加point和添加polys示例如下:

// 添加点double p0[3] = {
1.0,0.0,0.0};double p1[3] = {
0.0,1.0,0.0};double p2[3] = {
0.0,0.0,1.0};vtkPoints *pPoint = vtkPoints::New();pPoint->InsertNextPoint(p0);pPoint->InsertNextPoint(p1);pPoint->InsertNextPoint(p2);//添加多边形vtkIdType pIds[3] = {
0,1,2};vtkCellArray *pPolys = vtkCellArray::New();pPolys->InsertNextCell(pIds);vtkPolyData *pData = vtkPolyData::New();pData->SetPoints(pPoint);pData->SetPolys(pPolys);

  但是,vtkPolyData删除点或者拓扑信息就没有这么简单了,应为拓扑结构中存储的是点的索引信息,删除点必然会影响点的索引值,这时就要特别注意。

  最近查了一些资料,总结了一下安全删除vtkPolyData数据中点和拓扑信息

  (1)vtkPolyData提供一个DeletePoint()的接口,可以使用这个接口删除点,但是不能真正的删除点数据。因为DeletePoint()实际操作的是vtkPolyData内部定义的数据vtkCellLinks,这个数据结构是一个辅助类,使用前必须要调用BuildLinks()函数,如果只是可视化使用,这个函数是可以用的。但是如果要删除vtkPoints里面的数据,就没有这么简单了。

  (2)vtkPolyData删除拓扑结构信息比较简单,因为拓扑信息只包括点的索引值,删除后不会影响其他数据,可以使用DeleteCell()方法。

  本文将将给出三个实例来表示vtkPolyData中数据的删除操作,其中包括一个删除拓扑信息的实例,两个删除点的实例。

实例1:删除拓扑结构

vtkIdType cellId = 200;// 要删除的面片的索引值pData->BuildCells();pData->DeleteCell(cellId);  // 标记要删除的cell结构,不会真正的删除pData->RemoveDeleteCells(); // 实际删除cell结构pData->Modified();

实例2:删除点数据,不能真正的删除点

vtkIdType pId = 100; // 要删除的顶点的索引值
pData->BuildLinks();pData->DeletePoint(pId);pData->DeleteLinks();
pData->Modified();

实例3:真正的删除点数据,同时恢复拓扑结构中点的索引值

// 辅助类struct Vertex{  double p[3];  inline bool operator==(const Vertex &v ) const {   return (p[0] == v.p[0])&&( p[1] == v.p[1])&&(p[2] == v.p[2]); } inline bool operator != (const Vertex &v) const {   return (p[0] != v.p[0])&&( p[1] != v.p[1])&&(p[2] != v.p[2]); }      }/** pData 要处理的网格数据* delPIds 要删除的点的索引值,可以是多个点,用vector表示*/void RealDeletePoint(vtkPolyData *pData, std::vector
delPIds){
  vtkPoints *pPoints = vtkPoints::New();  vtkCellArray *PCell = vtkCellArray::New();  vtkIdType *newIds = nullptr;  vtkIdType *pIds;  vtkIdType nId;  std::map
pointMap;  for(int i = 0; i < pData->GetNumberOfCells(); i++)  {    pData->GetCellPoints(i,nId,pIds);    newIds = new vtkIdType[nId];    for(int j = 0; j < nId; j++)    {      double *p = pData->GetPoint(pIds[j]);      Vertex tmpv;      tmpv[0] = p[0];      tmpv[1] = p[1];      tmpv[2] = p[2];      auto it = pointMap.find(tmpv);      if(it != pointMap.end())      {        newIds[j] = it->second;      }      else      {        pPoints->InsertNextPoint(p);        newIds[j] = pPoints->GetNumberOfPoints()-1;      }    }    pCell->InsertNextCell(nId, newIds);    delete []newIds;    newIds = nullptr;  }  pData->SetPoints(pPoints);  pData->SetPolys(pCell);}

本方法效率不高,但是能够满足删除点的要求,目前没有其他更有效的方法。

 

转载于:https://www.cnblogs.com/xuhui24/p/6555685.html

你可能感兴趣的文章
CSS——水平/垂直居中
查看>>
Eclipse连接mysql数据库jdbc下载(图文)
查看>>
快速入门
查看>>
Mybatis通过ID查询 && 通过name模糊查询
查看>>
发送邮件
查看>>
VirtulBox虚拟机搭建Linux Centos系统
查看>>
创建型模式(二):AbstractFactory ( 抽象工厂 )
查看>>
PHP获取当日或本月时间戳范围
查看>>
一款由jQuery实现的手风琴式相册图片展开效果
查看>>
基于jQuery仿淘宝产品图片放大镜代码
查看>>
Python中Selenium的使用方法
查看>>
python ord()与chr()用法以及区别
查看>>
三月23日测试Fiddler
查看>>
20171013_数据库新环境后期操作
查看>>
poj 1654 && poj 1675
查看>>
运维派 企业面试题1 监控MySQL主从同步是否异常
查看>>
Docker 版本
查看>>
poj 1753 Flip Game
查看>>
在深信服实习是怎样的体验(研发测试岗)
查看>>
Linux免密码登陆
查看>>