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

How do I modify a point in a cell in a vtkPolydata?

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

我尝试了两种方法:

这是一个示例代码:

#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 中的点?

单元格的 Points 数组与多数据之一分开 - 它仅包含单元格中的点的副本,并且绝不链接到多数据的数组 - 修改它不会大多数时候做任何有帮助的事情。我相信最初的意图是能够拥有不属于任何网格的单元格,但是当它们存在时,不应使用 Points 数组,而应该只使用 PointsIds,对于给定的单元内的点包含其在父网格(例如 vtkPolyData)点中的索引。

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

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) 调用将 return 6(第二个单元格的第三个点的 ID),这将超过 cube_pts_2 数组 (== 4).