如何修改vtkPolydata中单元格中的点?

时间:2018-03-26 12:27:45

标签: c++ vtk

我正在尝试编辑vtkPolyData内的一个点。

我尝试了两种方法:

  • 使用GetPointSetPoint方法直接修改点(这可行)
  • 使用GetCell访问一个单元格,然后使用GetPoint访问这些单元格,并使用SetPoint进行修改(这不会按预期工作)

以下是示例代码:

#include <iostream>
#include <vtkCell.h>
#include <vtkCellArray.h>
#include <vtkFloatArray.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolygon.h>
#include <vtkSmartPointer.h>

using std::cout;
using std::endl;

int main(int, char *[])
{
  // Points
  static float x[8][3] = { {0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 1}, {0, 1, 1}};
  // Faces
  static vtkIdType pts[6][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {0, 1, 5, 4}, {1, 2, 6, 5}, {2, 3, 7, 6}, {3, 0, 4, 7}};

  // We'll create the building blocks of polydata including data attributes.
  vtkPolyData *cube = vtkPolyData::New();
  vtkPoints *points = vtkPoints::New();
  vtkCellArray *polys = vtkCellArray::New();

  // Load the point, cell, and data attributes.
  for (int i = 0; i < 8; i++)
    points->InsertPoint(i, x[i]);
  for (int i = 0; i < 6; i++)
    polys->InsertNextCell(4, pts[i]);

  // We now assign the pieces to the vtkPolyData.
  cube->SetPoints(points);
  points->Delete();
  cube->SetPolys(polys);
  polys->Delete();

  double db[3] = {0, 0, 0};

  vtkSmartPointer<vtkPoints> cube_pts_1 = vtkSmartPointer<vtkPoints>::New();
  cube_pts_1 = cube->GetPoints();
  cout << "cube_pts_1 number of points = " << cube_pts_1->GetNumberOfPoints() << endl;

  // Access and modify third point in the polydata
  vtkIdType id_1(3);
  cube->GetPoint(id_1, db);
  cout << "Point (ID = " << id_1 << ") = " << db[0] << " " << db[1] << " " << db[2] << endl;

  // Modify third point in the polydata
  db[0] = 0;
  db[1] = 2;
  db[2] = 0;
  cube_pts_1->SetPoint(id_1, db);
  cout << "Point (ID = " << id_1 << ") = " << cube_pts_1->GetPoint(id_1)[0] << " " << cube_pts_1->GetPoint(id_1)[1]
      << " " << cube_pts_1->GetPoint(id_1)[2] << endl;

  // Access face 0 of polydata
  vtkSmartPointer<vtkPoints> cube_pts_2 = vtkSmartPointer<vtkPoints>::New();
  cube_pts_2 = cube->GetCell(0)->GetPoints();
  cout << "cube_pts_2 (cell 0) number of points = " << cube_pts_2->GetNumberOfPoints() << endl;

  // Access point 3 of face 0 in polydata (= point 3 in the polydata)
  vtkIdType id_2(3);
  cube->GetCell(0)->GetPoints()->GetPoint(id_2, db);
  cout << "Point (ID = " << id_2 << ") = " << db[0] << " " << db[1] << " " << db[2] << endl;

  // Modify point 3 of face 0 in polydata
  db[0] = 0;
  db[1] = 3;
  db[2] = 0;
  cube_pts_2->SetPoint(cube->GetCell(0)->GetPointId(id_2), db);

  cout << "Point (ID = " << id_2 << ") = " << cube->GetCell(0)->GetPoints()->GetPoint(id_2)[0] << " "
      << cube->GetCell(0)->GetPoints()->GetPoint(id_2)[1] << " " << cube->GetCell(0)->GetPoints()->GetPoint(id_2)[2]
      << endl;

  return EXIT_SUCCESS;
}

如何在访问单元格时修改vtkPolyData中的某个点?

1 个答案:

答案 0 :(得分:2)

单元格的Points数组与多边形数据分开 - 它只包含单元格中的点的副本,并且绝不与多边形数组相关联 - 修改它大部分时间都没有做任何有用的事情。我相信最初的意图是能够让细胞不属于任何网格,但是当它们存在时,不应该使用Points数组,只有PointsIds应该使用,对于给定的单元格中的点包含父网格中的索引(例如vtkPolyData)点。

您几乎总是想要修改polydata的点,因为这是所有过滤器,渲染管道等所使用的点。这将在您的代码中完成:

cube_pts_1->SetPoint(cube->GetCell(0)->GetPointId(id_2), db);

请注意,您编写的内容(cube_pts_2->...)实际上会在大多数情况下导致崩溃 - 它适用于您的情况,因为您正在测试单元格0,其中单元格ID为0,1,2,3 ,但是如果您使用例如单元格1,...GetCell(1)->GetPointId(id_2)调用将返回6(第二个单元格的第三个点的ID),这将超过cube_pts_2数组的大小范围( == 4)。