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 obDest=sel_obs if obAct == sel_obs: obSrc=sel_obs obDest=sel_obs 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 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.