Accessing custom attributes created in Geometry Nodes

With Geometry Nodes in Blender is easy to create additional custom attributes for objects and transfer the necessary data to them.  However, there is no direct access to such created attributes.

If we try to read the object’s attribute created in Geometry Nodes by name:

Blender will throw an error:

KeyError: ‘bpy_prop_collection [key]: key “_attribute_name_” not found’

This occurs because Geometry Nodes works like a modifier appended to an object. Modifiers do not affect the object’s source, overlaying changes above.

Like other modifiers, all the results of the Geometry Nodes, including the attributes created in them, can be obtained from the evaluated object.

Let’s add a cube to the scene and assign the Geometry Nodes modifier to it.

Add an Attribute Convert node (shift+a – Attributes – Attribute Convert) to the Geometry Nodes node tree. In the “Attribute” field set the “position” attribute. In the “Result” field type any name for the new attribute, for example, “my_pos”. As a result, Geometry Nodes will create a new attribute with this name and will translate the current position of the object to it.

If we try to access this attribute right now:

Blender will throw the same error informing that the specified attribute is missing for this object.

We can check that the object has no attributes by printing the list of its attributes.

To access the Geometry Nodes attributes, we first need to evaluate the object – get its final evaluated copy.

The “obj” object now contains a fully evaluated copy of the active object with all changes made by modifiers and Geometry Nodes.

The required attribute already exists in the evaluated object:

Now we can get all the data we need from the attribute by its name.

For example, the position of the first vertex of the mesh:

or a list of positions of all mesh vertices:


*.blend file with the code example for my Patreon subscribers

5 1 vote
Article Rating
Subscribe
Notify of
guest

11 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Ignacio
Ignacio
2 years ago

Hi there! Thanks so much, this is really useful. I was wondering if there is a similar process for getting “Instances” data from the Spreadsheet. I found that something like :

depsgraph = bpy.context.evaluated_depsgraph_get()

obj = branch

bm = bmesh.new()

bm.from_object( obj, depsgraph )

for object_instance in depsgraph.object_instances:

print(object_instance.matrix_world)

Could at least read position, scale… of the instances, but I can’t read other attributes that might be stored on the instances plus it feels that your way is much cleaner and efficient.
Thanks

Nikita
Editor
2 years ago
Reply to  Ignacio

Hi!
I think this is the same way to do the same thing. Your way with bmesh is good too.

Chris
Chris
2 years ago

This is great, thanks. How can I then put this into a driver?
I’m trying to use a float value (from an index of a point along a curve) to drive the frame number of an image sequence.
thanks!

Nikita
Editor
2 years ago
Reply to  Chris

Try to set the attrubute value to a driver input field
For example:
bpy.context.object.data.attributes[_attr_name_].data[0].vector

senya
senya
2 years ago

Where’s attribute convert node? I can only see capture, transfer and statistic attribute nodes… 3.0 release

Nikita
Editor
2 years ago
Reply to  senya

It was removed in the last builds of 3.0. You don’t need to use it to create attributes now. In the last version use fields – just connect the required node output to the Group Output node and name the created attribute in the modifier panel.
All the code to access the attribute in the last version stays the same.

lynchon
lynchon
3 years ago

Nice! very usefull info, thank you.

What if I wanted to edit (set) an attribute of a single vertex (selected vertex)? How could it be done via python?

lynchon
lynchon
3 years ago
Reply to  Nikita

what if I’ve already created this layer using bmesh, set its vertex values and pass it back to the mesh data? can I then recover those values and edit them again?

lynchon
lynchon
3 years ago
Reply to  Nikita

Yes, it works. I just tried. Thanks