3
$\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$
6
$\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$
2
$\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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.