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

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

最佳答案

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

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

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

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

关于c++ - 如何修改 vtkPolydata 中单元格中的点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49491500/

相关文章:

c++ - fwrite 对大量小写的效率

c++ - 为什么我需要 std::endl 来重现我用 getline() 得到的输入行?

c++ - 裁剪非结构化网格并保留数组数据

c++ - vtk 使用越来越多的内存并且变得很慢。

c++ - 简单的 C++ 递归不能正常工作——我只是不明白为什么

c++ - 不能在简单的余弦波上应用 FFT

c++ - SOCKET 没有命名类型

python - 使用 VTK Python API,将多个标量添加到非结构化网格单元

c++ - 使用 VTK 检查点是否在内部和对象

c++ - ItkVtkGlue 的问题