Convert vtkArray -> vtkPoints?

It seems (to me) that the data in vtkArray should be similar to vtkPoints. If I read in data, as a numpy array, and convert it to vtk format like:

pd = vtk.vtkPolyData()
g = numpy_to_vtk(my_nice_array)
pd.SetPoints(g)

This doesn’t work. I can use something like:

...
pts = vtk.vtkPoints()
for x, y, z in my_nice_array:
    pts.InsertNextPoint(x, y, z)

But I was wondering if I could somehow convert the output of numpy_to_vtk to vtkPoints?

Hello,

Can you, please, be more specific? “Does’t work” can mean a lot of different unexpected results when it comes to computer graphics.

regards,

Paulo

I guess you can do

pd.GetPoints().SetData(numpy_to_vtk(my_nice_array))

First, thanks for the replies.

@Paulo_Carvalho, here is the error that I got:

TypeError: SetPoints argument 1: method requires a vtkPoints, a vtkTypeFloat64Array was provided.

@marcomusy, this is the error that statement generates:

AttributeError: 'NoneType' object has no attribute 'SetData'

Here is the code I ran to get that last error:

import vtk
import numpy as np
from vtk.util.numpy_support import numpy_to_vtk
pd = vtk.vtkPolyData()
g = numpy_to_vtk(np.zeros(5))
pd.GetPoints().SetData(g)

What do you get when you run

pd = vtk.vtkPolyData()
g = numpy_to_vtk(my_nice_array)
pd.SetPoints(g)

?

When you create a vtkPolyData, it is empty, so it has no points:

>>> pd = vtk.vtkPolyData()
>>> pd.GetPoints()
None

And you can’t call SetPoints() with a vtkDataArray, since they’re different types. So what you have to do is create a vtkPoints object from the vtkDataArray, and then call SetPoints().

>>> pd = vtk.vtkPolyData()
>>> points = vtk.vtkPoints()
>>> points.SetData(numpy_to_vtk(my_nice_array))
>>> pd.SetPoints(points)

Also note that the vtkDataArray must have 3 components or else this will fail. So make sure the array has the correct shape.

i think the problem is that your polydata is still empty, this works:

import vedo
msh = vedo.Mesh("https://vedo.embl.es/examples/data/apple.ply")
pd = msh.polydata()
pts = msh.points()

import vtk
import numpy as np
from vtk.util.numpy_support import numpy_to_vtk
#pd = vtk.vtkPolyData()
g = numpy_to_vtk(np.zeros_like(pts)+pts*2) # whatever..
pd.GetPoints().SetData(g)

#vedo.show(pd)

you need to set it with a vtkPoints object.

I agree with you guys, that the “points” was empty - it just seemed to me like the vtkPoints is conceptually just an array, I was wondering if there was some way to use the vtk.util function numpy_to_vtk to directly load points instead of having to iterate over the rows in the array to add the coordinates … but it looks like the only way to do it is to iterate over the rows.

No, it’s not necessary to iterate over the rows. Both my answer and Marco’s answer demonstrate how to create vtkPoints from a numpy array. It just takes two steps.

Ok - sorry, I see that now, thanks!

I like to wrap the polydata object first

import numpy as np
from vtkmodules.numpy_interface import dataset_adapter as dsa

polydata = dsa.WrapDataObject(vtk.vtkPolyData())
polydata.Points = np.random.random(30).reshape(-1,3)
1 Like