0
$\begingroup$

Main question: I want to access the curve length value from the geometry node setup via the blender python api (see the screenshot). In the pictured node setup, you can see that I have it hooked up to a viewer node, and the instantaneous length of the curve is displayed on the curve points (1.00337). I want to access this value via the python api. I can't apply the modifier stack to the curve via the depsgraph and use calc_length on the spline, because of other modifiers added for visualization. Is it possible to access the value in Geo nodes via python?

Background: I'm working a blender plugin, and one of the functionalities depends on interactively creating poly curves, where the individual points are hooked to specific empties. A curve can have an arbitrary number of empties and corresponding hook modifiers, then the last two modifiers in the stack are always one that adds a profile curve & custom material, and then a bevel modifier. These last two steps are for visualization purposes only (the curve is an abstract representation of a muscle, hence the name in my screenshots).

I have a python script that programmatically moves some of the empties around (thus changing the curve length), and then using the depsgraph, computes the instantaneous curve's length (by applying all the modifiers in the depsgraph evaluation). The curve itself remains unchanged, but I can get the length this way. This works with only hook modifiers, and also other custom node groups that I add to modify the curve's path, but it's more complicated if you add the geometry & bevel nodes add the end for visualization because then the curve gets transformed into a mesh. In geometry nodes, it is possible to access the curve's instantaneous length, and this updates automatically as I move the empties around (see screenshot). Is there some way to access this value outside of geometry nodes? I tried several approaches (accessing the curve length's own output, and hooking the node output to the group output and then trying to access the group output), but these approaches did not seem to work. Any suggestions would be welcome!

Cheers, Pasha

Curve length node example

$\endgroup$
3
  • $\begingroup$ Can you possibly rephrase your question to disinclude the less-relevant background details and to show what it is you're trying to achieve? Reading your whole post it's not made clear what your actual end goal is, we only know that you want to access the curve length with Python but if your actual goal is "move the empties with Python and have the curve always follow" then it's possible there are a number of non-python solutions we could suggest, if we understood the actual end-goal. We won't know if we can't even tell what your actually aiming for. See XY Problem. $\endgroup$ Commented Oct 31, 2024 at 14:59
  • $\begingroup$ Sorry for responding so late, I was quite ill the last couple of days. The goal is to access the curve length parameter from geometry nodes via the python API. I want to perform several calculations that require repeatedly accessing the curve length as the empties are systematically repositioned via a script. I gave the information to outline what I'd already tried (applying the modifiers in the depsgraph and then calling calc_length() on the spline), and why that solution wouldn't work here (the extra geo nodes & bevel modifier that are essential in my plugin). $\endgroup$ Commented Nov 3, 2024 at 17:28
  • $\begingroup$ I've edited my original post, hopefully this helps $\endgroup$ Commented Nov 3, 2024 at 19:23

1 Answer 1

1
$\begingroup$

I found the answer to my own question. In fact, I found two approaches that work, and the second approach is slightly faster (0.05s versus 0.035s when evaluated 10000 times on my laptop which has an i7).

1) The answer to my actual question is a modification of this post. Basically, numbers within geometry nodes are not directly accessible via the blender python api. You have to assign the value to a custom attribute, evaluate the object in the depsgraph, and then find the value of your attribute there. I think this is a strange workaround for something that appears to be available in real time within the node setup, but perhaps there are reasons for this. Here's the code:

import bpy 
C = bpy.context
obj_ev = C.object.evaluated_get(C.evaluated_depsgraph_get()) #assumes the target object is selected.
obj_ev_mesh = obj_ev.to_mesh()
length = obj_ev_mesh.attributes['length'].data[0].value
obj_ev.to_mesh_clear()

This requires the following additional node in the geo node setup:

enter image description here

2) The faster solution to my problem is essentially the solution I already had. Basically, you get a depsgraph copy of the curve with modifiers applied, and then apply 'calc_length()' to the (only) spline. I thought this wouldn't work because of the curve to mesh node in the geometry node, and the bevel node, but apparently these both simply get ignored by the "_.to_curve(depsgraph, apply_modifiers=True" call. Here's the code:

import bpy 
C = bpy.context
obj_ev = C.object.to_curve(C.evaluated_depsgraph_get(),apply_modifiers=True) 
#assumes the target object is selected.
#apparently, geometry nodes and bevel modifiers are ignored
length = obj_ev.splines[0].calc_length()
C.object.to_curve_clear()
$\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.