6
$\begingroup$

I have read the answers to this question, so see you can access Geometry Nodes-generated attributes on an evaluated object using Python.

I'm attempting to access a mesh-wide vector-attribute in a driver. For testing purposes, a fixed vector value is plugged straight into the output node of a Geometry Nodes tree.

However, if I attempt to run v_attr(), a driver-namespace function, as defined below..

import bpy def v_attr(obj_name, attr_name): C = bpy.context ob = bpy.data.objects [obj_name] ev_dg = C.evaluated_depsgraph_get() ev_me = ob.evaluated_get(ev_dg).data return ev_me.attributes[attr_name].data[0].vector bpy.app.driver_namespace['v_attr'] = v_attr #print(v_attr('Plane', 'v_test').y) 

.. inside a driver, Blender 3.0b freezes.

Run from the Python console, v_attr() returns correct values, as a vector, or its components. Permission to auto-run scripts has been granted in Preferences.

I apologise if this is a premature question on a beta-bug, but I doubt that it is.. it's much more likely to be me, maybe misunderstanding the depsgraph altogether? Or permissions?

If there are better ways to store a mesh-wide attribute than duplicated on every point, that would be good...

$\endgroup$
10
  • $\begingroup$ may i ask where you added your driver to ? $\endgroup$ Commented Nov 3, 2021 at 3:55
  • $\begingroup$ All the mesh attributes store the same value ? Because then you can use a custom property instead like you would on a regular object $\endgroup$ Commented Nov 3, 2021 at 7:19
  • $\begingroup$ @chris I tried using v_attr('Plane', 'v_test').y in a scripted expression, to drive the Z location of an Empty. The result, for me, was a hang of (Linux) Blender 3.0b, requiring a kill of the Blender process. $\endgroup$ Commented Nov 3, 2021 at 8:02
  • $\begingroup$ @Gorgious I was just wondering if there was such a thing as a declared 'Whole Object' domain for an attribute, from within GN, which would save duplicating a value as a layer across all elements of a geometry domain. If I use, say, an Attribute Statistic result as an output, that may have to be stored only once, for the mesh. $\endgroup$ Commented Nov 3, 2021 at 8:10
  • $\begingroup$ @Gorgious sorry, that should be a 'Geometry' level domain: 1 attribute per hunk of geometry. $\endgroup$ Commented Nov 3, 2021 at 8:25

1 Answer 1

2
$\begingroup$

Not a full solution, but since Blender 2.90 you can use the depsgraph variable in drivers to retrieve the current dependency graph, which helps you avoid using bpy.context:

import bpy def v_attr(ev_dg, obj_name, attr_name): ob = bpy.data.objects[obj_name] ev_me = ob.evaluated_get(ev_dg).data return ev_me.attributes[attr_name].data[0].vector bpy.app.driver_namespace['v_attr'] = v_attr 

Then in your driver function call, just add an argument depsgraph at the start.

However, even then, there is no depsgraph relation built between the mesh, which is why there is no automatic update (you must click on "Update Dependencies" on the driver to see changes).

Alternative implementation, without extending the driver namespace: bpy.data.objects["Plane"].evaluated_get(depsgraph).data.attributes["v_test"].data[0].vector.y. This warns about use of bpy.data, but there sadly is no way to retrieve an evaluated mesh through the driver variables.

$\endgroup$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.