1
$\begingroup$

I get polygons instances with a simple python list but it's really interesting how I could get these instances with Numpy as it should be faster.

poly_indices = [tuple(poly.vertices) for poly in bpy.context.active_object.data.polygons]

To be clear I got this: https://docs.blender.org/api/current/bpy.types.MeshPolygon.html?highlight=vertices#bpy.types.MeshPolygon.vertices

The main problem for Numpy Array is that a length of the polygon's tuple can be differen. For a tringle the tuple length is 3. For a quad the tuple length is 4. For an NGon the tuple length is from 5 to N.

$\endgroup$
2
  • $\begingroup$ Ok but what exactly is your question? $\endgroup$
    – Jakemoyo
    Jun 12, 2022 at 20:50
  • $\begingroup$ How to do this with numpy. I want numpyarray. $\endgroup$
    – mifth
    Jun 13, 2022 at 21:03

2 Answers 2

2
$\begingroup$

by design you can't have a numpy array with variable dimension length. If you really need the array format the best option would probably be to create one Nx3 array with all the triangles, one Mx4 with all the quads etc.

Edit: You can get all vertices directly as a numpy array using the following:

vertices = np.ones(len(mesh.vertices)*3)
mesh.vertices.foreach_get("co", vertices)
vertices = vertices.reshape(-1, 3)

this will give you a Nx3 array with the vertices and when I tried it with 1 million points I got a roughly 30x speedup compared to the for loop version (3s with for loop vs 0.1s with foreach_get).

For polygons I'm not sure if you can do it this way since you don't know how many polygon-vertices there are before reading the data (unless it's available through the API somehow), so python for loop is probably the best option

$\endgroup$
2
  • $\begingroup$ I wonder... You could capture an attribute on the loops, using geonodes, where the attribute would be the face index (weird that there's vertex and edge indices, but not face). Then you can use foreach_get to read the attribute and get loop to face mapping (and also loop to vertex mapping). Then you can use numpy to further transform this to your needs. Should be faster than python... $\endgroup$ Jun 20, 2022 at 14:13
  • $\begingroup$ interesting, might try to make it work at some point. However best would be if foreach_get directly returned a numpy array instead of requiring the user to pre-compute the length :D maybe one day.. $\endgroup$
    – Linus
    Jun 20, 2022 at 14:36
1
$\begingroup$

You just need to specify dtype="object" when declaring the numpy array.

import numpy as np 
from bpy import context as C

obj = C.active_object 

npa = np.array([tuple(polygon.vertices) for polygon in obj.data.polygons[:]], dtype="object")
$\endgroup$
2
  • $\begingroup$ The OP mentions he wants it because of the speed of numpy... The thing is, numpy is faster because you can assign entire array in C. Here you first iterate over the collection to figure out the size of the array, and then you assign it with C... To add salt to the injury, as a side effect of reserving the memory for the array you already populate it with the data that the numpy is supposed to obtain. So if you need to make some calculations involving numpy on the indices (can you show how to do it with dtype="object"?), it makes sense, otherwise it doesn't. $\endgroup$ Jun 20, 2022 at 14:08
  • $\begingroup$ As far as I could tell the OP seemed to be asking how to convert a ragged array to a np.array. I wasn't array that he was asking whether or not they already had implemented some kind of integrated np.array attribute of the mesh. Which I did not believe was the case. $\endgroup$
    – Jakemoyo
    Jun 20, 2022 at 17:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .