3
$\begingroup$

I have a function for a driver that expects 2 objects as arguments, and I can't find a way to set the variable as the Object ID, only a single property of that object. Is that possible?

enter image description here

$\endgroup$
3
  • $\begingroup$ Provide a data path. Maybe "location" in that case? $\endgroup$
    – lemon
    Dec 4 '20 at 9:23
  • $\begingroup$ So it's not possible to only reference an object? I can easily work around it by making the function arguments require each object property separately, and create variables of these, but I wanted to make sure there wasn't an cleaner way. $\endgroup$
    – chafouin
    Dec 4 '20 at 17:30
  • $\begingroup$ afaik no. But may be a workaround? you can distance("Camera") without using var. And get the object, bpy.data.objects[param] in the function. Or if you want var, use "name" as datapath $\endgroup$
    – lemon
    Dec 4 '20 at 17:42
3
$\begingroup$

You can set the driver to data path and use "name" as path, at the cost of getting the object from its name.

With this setting, the object can be renamed by the user and the driver won't be broken.

enter image description here

$\endgroup$
5
$\begingroup$

Using the depsgraph

Since the upgrade to 2.8 the depsgraph is a member of the locals of a driver, as are the variables. See answer to

How to use different types of data blocks for driver variables?

re setting up a test driver.

As an example, driver is on "Cube". The object "Lamp" is in scene, and passed as an evaluated object to the driver via the depsgraph. The depsgraph can also be used.

enter image description here

def test(*args, depsgraph=None, **kwargs):
    for arg in args:
        print(arg)
    print(depsgraph)   
    return -1 # a simple val to indicate working

<bpy_struct, Object("Cube") at 0x7f62fcbefa08, evaluated>
<bpy_struct, Object("Lamp") at 0x7f62fcbf0008, evaluated>
<bpy_struct, Depsgraph at 0x7f62faba6c08>

An example to return minimum global z of all other objects in the depsgraph. The method of @lemon can be used for the object names. Other options could be tagging them via custom property or name prefix suffix.

def test(self, *args, depsgraph=None, **kwargs):

    z = min(o.matrix_world.translation.z for o in depsgraph.objects
    if o != self)

    return z  

Pointerproperties.

IMO the best way to associate an object(s) with another is via a pointer property

bpy.types.Object.driver_obj1 = bpy.props.PointerProperty(type=bpy.types.Object)

which can be assigned via script or UI.

context.object.driver_object1 = context.scene.objects.get("Lamp")
$\endgroup$
3
  • $\begingroup$ How does the depsgraph keyword argument get automagically assigned inside your first test() function? Don't you have to look up the **kwargs items through the kwargs dictionary? .. (Sorry, another Python baby- gurgle.. I really have tried to look it up. $\endgroup$ Dec 5 '20 at 12:27
  • $\begingroup$ It's in the locals() of the driver so can be used by name directly. just like any driver variable accessed by its name. $\endgroup$
    – batFINGER
    Dec 5 '20 at 12:30
  • $\begingroup$ OK, got it $\endgroup$ Dec 5 '20 at 14:33

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.