Driver Editor can provide convenience macros such as currentobject and currentdatablock
Currently there is no way to refer the currentobject and currentdatablock in the driver editor. This can be provided as a special macro for convenience.
The advantage is to create generic animation drivers. That way we can reuse the drivers for other objects without changing the object details in the driver.
7 Comments
"Currently there is no way to refer the currentobject" What?
The option for "use self" is even right there in the screenshot.
Here's an example of a generic driver like what you describe:
(int(self.name[-3:]) != frame) * 10This driver was nice for easily making a bunch of duplicated mask meshes swap in and out on a given frame that corresponds to their name.
Thanks for the comment and an example. It helps me understand your thought process for a downvote. And i learnt a couple of things from your example.
I agree with you on the use of self. But the self is limited to the scope of the target driver. For example, if my target field is at the datablock level such as power of a light object, i am unable to use the self to access the object level properties such as location using self. For now, i use "Copy as new driver"-"Paste Driver" options. But maybe you know better.
So i thought providing this convenience macro can help us cross reference from a datablock to an object scope and vice versa.
Indeed - it's limited to the scope of Blender's Python API, just like every other driver. Almost anything you can do in an addon or the text editor - within one 255 character line and evaluable - you can do in a driver*. Very similar to what you can do in Blender's value inputs, too. Quite... Limiting...
self.data.energyself.location[0],self.location[1],self.location[2]Here's one I cooked up - this driver sums the number of keyframes your object has with the number of times there's "var" in any of its drivers (which it doesn't contain) and the number of objects in the file:
("".join([c for s in [d.driver.expression for d in self.animation_data.drivers] for c in s]).count("va"+"r"))+(0 if self.animation_data.action is None else sum([len(f.keyframe_points) for f in self.animation_data.action.fcurves]))+len(bpy.data.objects)selfis basicallybpy.data.objects["Your object here"]. That's the datablock. That's the object. It does what you're asking for.*can't use exec either, and probably can't use other big python fuckery. But at that point, you should use a handler instead.
("".join([c for s in [d.driver.expression for d in self.animation_data.drivers] for c in s]).count("va"+"r"))+(0 if self.animation_data.action is None else sum([len(f.keyframe_points) for f in self.animation_data.action.fcurves]))+len(bpy.data.objects)
All i can say is "WOW"... infact it took me a while to get my head around it... thanks
What i am trying is a much, much simple driver compared to yours.. I am trying to create a driver on the energy of a light that increases when the location of the object is moved further from the origin in the Z direction with hardcoding the object name in it
Well in the case of putting a driver in the light, your problem is that a light and an object are 2 very separate things. The driver's self evaluates to the light's datablock, not the object's. Like an object's mesh and the object itself, you can link lights too for different light objects, so you can end up with multiple instances of the same light in completely different locations, or none at all! Blender can't know which one you want, especially in the case of there being none.
Here's a piece of code that will fetch the first object that uses the datablock:
[o for o in bpy.data.objects if o.data.name==self.name][0].location[2]Of course, in this case, "first" is very arbitrary and I believe should mean whichever got added to the blend file first.
Another worse solution - if you can promise yourself to have all your light objects be called the same thing as their light datablock with the driver (or at least that such an object exists), you can do this very hacky thing:
abs(bpy.data.objects[self.name].location.z)If you haven't touched any light objects' names and light datablocks' names, both of them should be the same. Or you can rename both to be the same.both of these are superb ideas.. Thanks a lot.
I was assuming that Blender must be tracking this reference of a datablock to its current object in some C/C++ layer. Hence i spawned this proposal. But maybe my assumption is wrong.
It seems you are talking about the Expression input, while the OP explicitly marked the Object input field.
Sadly it seems you can NOT reference the currentobject in the Object input.