8
$\begingroup$

I tried to access a custom Attribute from a geometry node setup in Python API after evaluation of the modifiers. But I only can find the vertex data. In this example I want to access the attribute "test" as seen in the spreadsheet.

Python code is as follows:

import bpy

dgEv = bpy.context.evaluated_depsgraph_get()

for obj in bpy.context.selected_objects:
    object_eval = obj.evaluated_get(dgEv)

print(object_eval.data.vertices[0].co)

Result in system console:

<Vector (0.5000, 0.5000, 0.5000)>

enter image description here

My Blender version is: 2.93.0 (Debian 11 Linux)

Can anyone help me?

Thanks.

$\endgroup$

3 Answers 3

9
$\begingroup$

foreach_get

For a quick way to fill a list with attribute values, without iterating in python

Python : Custom Attribute for Vertices

>>> ob = C.object.evaluated_get(C.evaluated_depsgraph_get())
>>> me = ob.data
>>> n = len(me.attributes['test'].data)
>>> vals = [0.] * n

>>> me.attributes['test'].data.foreach_get("value", vals)
>>> vals
[10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0]

>>> 

Similarly to get the coordinates, as shown in How to get the base dimensions of an object (ignoring all of it's modifiers)?

>>> import numpy as np
>>> coords = np.empty(3 * len(me.vertices))
>>> x, y, z = coords.reshape((-1, 3)).T
>>> x
array([ 1.,  1.,  1.,  1., -1., -1., -1., -1.])

>>> y
array([ 1.,  1., -1., -1.,  1.,  1., -1., -1.])

>>> z
array([ 1., -1.,  1., -1.,  1., -1.,  1., -1.])

With bmesh

The attribute layers are also available via bmesh.

>>> bm = bmesh.new()
>>> bm.from_object(C.object, C.evaluated_depsgraph_get())
>>> test = bm.verts.layers.float['test']
>>> for v in bm.verts:
...     v[test]
...     
10.0
10.0
10.0
10.0
10.0
10.0
10.0
10.0

Note: Results above for only geometry node modifier as in question, without sub'd. With level 2 sub'd would be 98 verts

$\endgroup$
3
$\begingroup$

You can access it like this:

object_eval.data.attributes[0].data[0].value or
print (object_eval.data.attributes["attributeName"].data[0].value)

to get the first value.

object_eval.data.attributes[0].data[1].value 

-> 2nd value

object_eval.data.attributes[1].data[0].value

-> first value of 2nd attribute

$\endgroup$
1
$\begingroup$

You make me playing around for the first time with blender scripting. So far I was only able to get the field name using (found via autocomplete):

>>>print(object_eval.data.attributes[0])
<bpy_struct, FloatAttribute("test") at 0x7facac45e400>

Now all you need is find a way to access the value of the attribute.

$\endgroup$

You must log in to answer this question.

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