automatically adding vertex cells

Hello, I am building a PolyData including just vertex cells, i.e. isolated points. I have the point coordinates so I easily create the points, but I cannot find an example (possibly in Python) explaining how to add one vertex cell for each point automatically.

My code is (having coords as a points_number x 3 array)

points = vtk.vtkPoints()
cells = vtk.vtkCellArray()
poly = vtk.vtkPolyData()

for i in range(points_number):
    points.InsertPoint(i, coords[i, 0], coords[i, 1], coords[i, 2])

poly.SetPoints(points)

for pid in range(poly.GetNumberOfPoints()):
    cells.InsertNextCell(0, pid)

poly.SetVerts(cells)

When I check the PolyData (i.e. with print) I have the right number of points and vertex cells (same number), but the bounds are messed up (they show high values around 1e+299 and 1e-299), and this results in a completely messed up zoom level when I try to plot in a 3D view.

However the point coordinates are correct, so I guess that there is some problem with the topology.

Thanks very much in advance!

A quick glance suggests that “cells.InsertNextCell(0, pid)” is inserting a bunch of cells with no 0 points…

Thanks! In fact I was wondering what is the right way to reference points for Vertex cells, particularly when you already have all the points. Do you know of any valid example?

Thanks!

I was referring to issue #750 where it suggests to use this C++ code:

auto vertexes = vtkSmartPointer<vtkCellArray>::New();
for (int i = 0; i < data->GetNumberOfPoints(); i++) {
    vtkIdType pid[1];
    pid[0] = i;
    vertexes->InsertNextCell(1, pid);
}
dataPoints->SetPoints(points);
dataPoints->SetVerts(vertexes);

However it is not clear to me how to translate in Python the “pid” lines.

I also found this on an older post, but it rises many errors.

num = model.GetNumberOfPoints()
ids = vtk.vtkIdList()
ids.SetNumberOfIds(num);
model.Allocate(1,1)

for i in range(0, num):
    ids.SetId(i, i)
    model.InsertNextCell(vtk.VTK_VERTEX, ids)

In the end, I understand that the error is with the “pid” index, that must be a vtkIdType, but I cannot get it correct in Python.

Thanks!

Hello, I just figured out how it should be done. This is the working code:

points = vtk.vtkPoints()
cells = vtk.vtkCellArray()
poly = vtk.vtkPolyData()

for i in range(points_number):
    points.InsertPoint(i, coords[i, 0], coords[i, 1], coords[i, 2])

poly.SetPoints(points)

for pid in range(poly.GetNumberOfPoints()):
    vertex = vtk.vtkVertex()
    vertex.GetPointIds().SetId(0, pid)
    curr_obj_cells.InsertNextCell(vertex)

poly.SetVerts(cells)

So it looks like the examples cited above were quite misleading!

Let me know if there is a better way.

Thanks!

There are usually several ways to do the same thing in VTK :slight_smile: Partially due to a flexible API, partially backward compatibility, partially emerging data models, partially performance related (i.e., threading), etc.

I would do it like this: (you can also grep on testing or other code to finds lots of similar examples, say for example
VTK/Filters/General/Testing/PythonTestRemovePolyData2.py) :

#!/usr/bin/env python
import vtk

numPts = 100
npts = 1
cellIds = [0]

points = vtk.vtkPoints()
cells = vtk.vtkCellArray()
poly = vtk.vtkPolyData()

for i in range(numPts):
    points.InsertPoint(i, i, i, i)

poly.SetPoints(points)

for pid in range(numPts):
    cellIds[0] = pid
    cells.InsertNextCell(npts,cellIds)

poly.SetVerts(cells)

print(poly)

So cellIds are a one-element list, where the element is an integer with the point index. Correct?

But I would rather call them pntIds because they are the index of the point in the cell.

This was the problem!

And I start seeing why it is a one-element list: in fact the vertex cell contains a single point, but the syntax is general and for instance to build a triangle you can do

pntIds[0] = pid_0
pntIds[1] = pid_1
pntIds[2] = pid_2`Preformatted text`
cells.InsertNextCell(3,pntIds)

Thanks very much!