List all drivers in a blend file.

Any ideas how to do this without some brute strength search everything code? would be most appreciated.

there is a ‘Dependency Relations’ operator you can find through spacebar menu
it just prints to console but could be useful…?

Dang… got my hopes up. All I get on a sample file with lots of drivers is the 4 scene objects being dependant on the scene. The code I have to find these drivers is so long winded and bloated it seems ridiculous… makes me think I’m missing something obvious.

is this of any help?


for oObj in bpy.data.objects:
    if oObj.animation_data is not None:
        for oDrv in oObj.animation_data.drivers:
            print ('%s.%s is driven to %s' % (oObj.name, oDrv.data_path, oDrv.driver.expression) )

Thanks for that. Looking at bpy.data collections in the end was the key.


import bpy
from mathutils import Vector, Color

if "Drivers in File" in bpy.data.texts:
    text = bpy.data.texts["Drivers in File"]
else:
    text = bpy.data.texts["Drivers in File"]
text.clear()


collections = ["scenes","objects","meshes","materials","textures","speakers","worlds","curves","armatures","particles","lattices","shape_keys","lamps","cameras"]
text.write("-"*70 + "
")
text.write("DRIVERS IN %s
" % bpy.data.filepath)
text.write("-"*70 + "
")
for col in collections:
    collection = eval("bpy.data.%s"%col)
    for ob in collection:
        if ob.animation_data is not None:
            for driver in ob.animation_data.drivers:
                dp = driver.data_path
                pp = dp
                if dp.find("[") != 0:pp = ".%s"%dp
                resolved = False
                try:
                    dob = ob.path_resolve(dp)
                    resolved = True
                except:
                    dob = None
                    
                if not resolved:
                    try:
                        dob = eval('bpy.data.%s["%s"]%s' % (col,ob.name,pp))
                        resolved = True
                    except:
                        dob = None
                    
                idx = driver.array_index
                if dob is not None and (isinstance(dob,Vector) or isinstance(dob,Color)):
                    pp = "%s[%d]"%(pp,idx)
                text.write('bpy.data.%s["%s"]%s  (%s)
' % (col,ob.name, pp, driver.driver.expression) )
text.write("-"*70 + "
")

On a sample file this gives output


----------------------------------------------------------------------
DRIVERS IN F:\blender\BAFSamples\st_sample1.blend
----------------------------------------------------------------------
bpy.data.scenes["Scene"].render.filter_size  (1.000)
bpy.data.scenes["Scene"].gravity[0]  (0.000)
bpy.data.objects["Cube"].modifiers["Softbody"].settings.mass  (1.000)
bpy.data.objects["Cube"].modifiers["Shrinkwrap"].offset  (0.000)
bpy.data.objects["Cube"].location[0]  (0.258)
bpy.data.objects["Cube"].location[1]  (0.571)
bpy.data.objects["Cube"].location[2]  (0.403)
bpy.data.objects["Cube"].material_slots["Material.001"].material.diffuse_color[2]  (0.800)
bpy.data.objects["Cube"].material_slots["Material.001"].material.specular_color[1]  (1.000)
bpy.data.objects["Cube"].material_slots["Material.001"].material.texture_slots["Texture"].texture.noise_scale  (0.250)
bpy.data.objects["Cube"].material_slots["Material.001"].material.translucency  (0.000)
bpy.data.objects["Cube.001"].modifiers["Softbody"].settings.mass  (1.000)
bpy.data.objects["Cube.001"].modifiers["Shrinkwrap"].offset  (0.000)
bpy.data.objects["Cube.001"].material_slots["Material.001"].material.diffuse_color[0]  (0.800)
<b>bpy.data.materials["Material.001"].diffuse_intensity  (0.800)</b>
bpy.data.speakers["Speaker"]["Driver0"]  (2 + SoundDrive(Channel7,amp=3))
bpy.data.speakers["Speaker"].volume  (1.000)
bpy.data.speakers["Speaker"].pitch  (1.000)
bpy.data.worlds["World"].exposure  (0.000)
bpy.data.particles["ParticleSettings"].normal_factor  (1.000)
bpy.data.shape_keys["Key"].key_blocks["Key 1"].value  (0.000)
bpy.data.shape_keys["Key.001"].key_blocks["Key 1"].value  (0.000)
bpy.data.lamps["Lamp"].distance  (30.000)
----------------------------------------------------------------------

Running thru the data collections seems to be the key. For instance the particle system can also be found by


&gt;&gt;&gt;C.object.particle_systems['ParticleSystem'].settings.animation_data.drivers

So the driver could be added at the object level with a data_path similar to the way the Softbody modifier drivers are. Having them on the data is prob more useful tho as they remain and become broken if the mod is removed, whereas if the particle system is removed so is the driver.

What I also noticed is that material and texture drivers added via the UI get object context whereas if you add a keyframe it gets material / texture context for the action. I added the diffuse material driver (bold) in the sample file via the console.

This is a nice example and it does seem odd, the entry you have in BOLD.

I was messing around with animation_data interrogation for RE:Lay just the other day. I did not realize that object and data actions were still so separate. Seems kind of 2.49 ish to me.

I added the one in bold using the console.


&gt;&gt;&gt; bpy.data.materials['Material.001'].driver_add('diffuse_intensity')

This way I have a driven material for whatever object it is assigned to… which in this case was what I was after. Seems a little inconsistent to me that adding a keyframe adds an action to the material animation_data whereas adding a driver to the same property box adds the driver at object level.