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,
rexthor:
This doesn’t work.
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
marcomusy
(Marco Musy)
February 5, 2023, 3:28pm
3
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)
?
dgobbi
(David Gobbi)
February 6, 2023, 2:45pm
6
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.
marcomusy
(Marco Musy)
February 6, 2023, 2:48pm
7
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.
dgobbi
(David Gobbi)
February 6, 2023, 3:05pm
9
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.
rexthor
February 6, 2023, 3:06pm
10
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