• VTK删除vtkPolyData中的顶点和面片


      应用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<int> delPIds)
    {
      vtkPoints
    *pPoints = vtkPoints::New();   vtkCellArray *PCell = vtkCellArray::New();   vtkIdType *newIds = nullptr;   vtkIdType *pIds;   vtkIdType nId;   std::map<Vertex, int> 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); }

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

  • 相关阅读:
    BZOJ2809: [Apio2012]dispatching
    BZOJ1455: 罗马游戏
    可并堆试水--BZOJ1367: [Baltic2004]sequence
    可并堆模板
    Codeforces870F. Paths
    Codeforces913F. Strongly Connected Tournament
    一练Splay之维修数列第一次
    Codeforces913E. Logical Expression
    Codeforces700C. Break Up
    可持久化KMP
  • 原文地址:https://www.cnblogs.com/xuhui24/p/6555685.html
Copyright © 2020-2023  润新知