Page MenuHome

PyDriver variables as Objects
AbandonedPublic

Authored by Campbell Barton (campbellbarton) on Feb 18 2016, 4:10 PM.

Details

Summary

Support for Driver Variables that don't resolve into numbers, avoiding having to use bpy.data in py-driver expressions.

Motivation: the reason for this patch is to allow people to reference objects, bones, curves... etc from py-drivers.

A patch submitted recently used a property where a function would be more correct Curve.calc_length(), the main reason to do this is that driver-variables can't reference function calls. (See D1810)

Without this Python expressions can use an absolute path, eg bpy.data.curves["SomeCurve"].splines[0].calc_length(), however this won't setup the correct dependencies.

Also its a hassle to always type in the full path and renaming the curve will break the driver.

So this patch allows a driver variable to reference a curve directly, then the expression can read... driver_var.splines[0].calc_length().

Diff Detail

Repository
rB Blender
Branch
arcpatch-D1812

Event Timeline

  • Description for use_object option.

Seems that the message "Invalid Python expression" doesn't go away unless you revalidate the expression, if you check "As Object" after having set the path. Don't know if that can (and has to) be made better.

Functionality
I guess this is ok. I'd been thinking of doing something similar that would allow for the use of strings here, that would have functioned in a similar manner.

Two minor potential issues that may arise (not blocking issues, but I think they should be noted here for future reference):

  • I'm slightly worried about riggers getting lazy and just adding a single var for the object/bone, then grabbing the transforms off that (problematic because they'll not be grabbing the final transforms that way). Then again, they can do similar things already with the single prop anyway.
  • If we do end up implementing a simpler Py-subset-expression-evaluator for use with driver expressions, "obj.prop" constructions in the expressions would necessarily need to be viewed as suspicious. This is because the goal of having that subset-evaluation engine is to bypass the need for autoexec protections to block the execution of the most common set of "simple" driver expressions (e.g. things like "var", or "var * 2", or "var * 10 + 1", vs "use_my_crazy_potentially_evil_callback("rm", "-rf")). The issue here with the functionality proposed here is that there may be some user confusion about why some driver vars passed in work, and others don't. However, at this stage, this system doesn't exist, so it's probably just a hypothetical concern that we don't need to care about too much now.

Implementation

  • IIRC, when using driver types other than expressions (e.g. Averaged Values), we will still end up looping over all the vars, calling driver_get_variable_value() on them. In that case, these variables would get flagged as being invalid.
  • Is the "As Object" toggle really needed? Couldn't we do something like check on the type of the RNA prop, and use Py Objects otherwise?

    On second thought, maybe it's ok - it does simplify checking for this case, and it would also allow bools to be represented in their native form instead of as floats).
Campbell Barton (campbellbarton) planned changes to this revision.EditedFeb 23 2016, 8:45 PM

Functionality
I guess this is ok. I'd been thinking of doing something similar that would allow for the use of strings here, that would have functioned in a similar manner.

Two minor potential issues that may arise (not blocking issues, but I think they should be noted here for future reference):

  • I'm slightly worried about riggers getting lazy and just adding a single var for the object/bone, then grabbing the transforms off that (problematic because they'll not be grabbing the final transforms that way). Then again, they can do similar things already with the single prop anyway.

Valid point, but think guys who need to access this are already using workarounds, so not sure it changes much.

  • If we do end up implementing a simpler Py-subset-expression-evaluator for use with driver expressions, "obj.prop" constructions in the expressions would necessarily need to be viewed as suspicious. This is because the goal of having that subset-evaluation engine is to bypass the need for autoexec protections to block the execution of the most common set of "simple" driver expressions (e.g. things like "var", or "var * 2", or "var * 10 + 1", vs "use_my_crazy_potentially_evil_callback("rm", "-rf")). The issue here with the functionality proposed here is that there may be some user confusion about why some driver vars passed in work, and others don't. However, at this stage, this system doesn't exist, so it's probably just a hypothetical concern that we don't need to care about too much now.

Am quite skeptical of auto-detection being used to validate strings. If we have some *safe* evaluate one day, likely this will only work for very basic expressions, non-trivial drivers will likely need to be updated.

Implementation

  • IIRC, when using driver types other than expressions (e.g. Averaged Values), we will still end up looping over all the vars, calling driver_get_variable_value() on them. In that case, these variables would get flagged as being invalid.

This can only work with Python expression, so average values or anything are incompatible.

  • Is the "As Object" toggle really needed? Couldn't we do something like check on the type of the RNA prop, and use Py Objects otherwise?

    On second thought, maybe it's ok - it does simplify checking for this case, and it would also allow bools to be represented in their native form instead of as floats).

Think its worth checking on making this default. With Python3 its _very_ unlikely people rely on a float in a way that breaks scripts, since Python coerces bools and ints into floats as needed.
So think its worth considering, if this works on a handful of complex rigs (rigify, blendrig, glasshalf... perhaps others on the cloud)... think its reasonable to make this change.


(Note that for making this default I'll need to add array index lookup support, will update patch).

Support for index lookups for py-drivers

  • Support for index lookups for py-drivers
  • Minor/corrections

Use Python Objects by default (no longer optional)


Tested this patch with: glass_half_export/pro/shots/05/05_anim.blend and the eyes don't open after this patch is applied. That needs to be fixed of course.
Otherwise this patch can still be reviewed.

Fix for accessing the wrong 'ptr' when resolving the path.

Remove externs, use own source file mixing drivers+rna

Use own source file since I'd rather keep RNA API out of bpy_drivers.c.

@Joshua Leung (aligorith), aside from more testing, think this is ready for master.

Tested with glasshalf and rigs and its giving same results as master.