[Script] Simple Script To Retarget Drivers

I have often the case where I have a mesh with shape keys which are driven by drivers which target the bones of an armature, from importing Daz figures to blender. I wanted a way to be able to copy a mesh from one armature to another. Doing that is easy, but all the many drivers are now targeted at the old armature (the one it’s copied from) not the one it has been copied to. I tried to find something to retarget them all but couldn’t find anything, though that might be just bad Googling. So I have written this simple script which will do it. It assumes that the target armature has the same bones in it as the source armature, and just retargets the object.

I thought this might be useful for other people, but it’s also likely I’ve reinvented the wheel, so rather than refine it further I thought it would make sense to “release” it and see if I get laughed at for doing that because something much better already exists, or whether it’s worth more work to make a bit more professional. Currently, you need to run it from the Python script window. You just select the mesh with the drivers, select the armature you want it retargeted TO, run the script and it should do it.

Please let me know if anyone has any interest in this script being further developed or if it’s a waste of time. You can indicate the latter by ridicule or silence, I’m easy.

import bpy
import re

myScene = bpy.context.scene
myLayer = bpy.context.view_layer
myObjects = bpy.context.scene.objects

def main():

sel_obs=bpy.context.selected_objects
for ob in sel_obs:
    print("Selected:",ob.name)
    
if len(sel_obs) != 2:
    print("Need 2 objects selected")
    return
        
obAct= myLayer.objects.active
print("Active:", obAct)
obSrc= sel_obs[0]
obDest=sel_obs[1]

if obAct == sel_obs[0]:
    obSrc=sel_obs[1]
    obDest=sel_obs[0]

if not obSrc.data: return
if not obSrc.type=='MESH': return
if not obDest.type=="ARMATURE": return

obSrc_mesh=obSrc.data

obDest_id = obDest.data
print("Destination:",obDest_id)

if obSrc_mesh.shape_keys:
    obSK=obSrc_mesh.shape_keys
    obSrc_SKblocks=obSrc_mesh.shape_keys.key_blocks
    obSrc_drivers = obSK.animation_data.drivers.items()
    
    for drv in obSrc_drivers:
        drvIt2= drv[1]
        drvDrv = drvIt2.driver
        drvVars = drvDrv.variables
        for vv in drvVars:
            drvTargs = vv.targets
            for tt in drvTargs:
                print(tt.id, tt.bone_target)    #bone target is the bone driving the driver
                tt.id = obDest
                
        drvDrv.expression += " "
        drvDrv.expression = drvDrv.expression[:-1]
                
return

main()

Health And Safety Notice: save your work before trying it.

2 Likes

For some reason the “main()” at the end has been separated from the rest of the script. It is part of it and it won’t work without it. :slight_smile:

1 Like