我正在尝试编辑vtkPolyData
内的一个点。
我尝试了两种方法:
GetPoint
和SetPoint
方法直接修改点(这可行)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
中的某个点?
答案 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)。