2
$\begingroup$

I have a number of different objects with similar armatures that I reuse regularly in animation.

Each contains multiple bones with various constraints and drivers that have to reference other objects in the scene to work. The reference objects change based on the scene and so I'm looking for a way to streamline this process.

Simplified example: I have a cube with an armature with two bones. Each bone has a constraint and each a driver. The constraints and drivers all need to reference the same object. Currently I'd have to do each one manually.

Multiple Target Objects

I'd like to know how one might go about setting all four references at once. By having three all reference one or by having all four reference something else (a custom "Set Target Object" panel in the UI somewhere??). I assume this can only be done via addon or a script but any way of speeding this up is greatly appreciated.

Thanks for your assistance.

$\endgroup$
  • $\begingroup$ Anybody who wants to use this code should note an armature needs to be present & pose selected in the scene for it to become visible in the properties object panel. $\endgroup$ – MarioS Jun 2 at 6:53
2
$\begingroup$

Something like this:

import bpy
from bpy.props import StringProperty

def apply_target(self, context):
    arm = context.active_object
    pbones = arm.pose.bones
    #update drivers
    for driver in arm.animation_data.drivers:
        for v in driver.driver.variables:
            for target in v.targets:
                target.id = bpy.data.objects[arm.my_target]
    #update contraints
    for bone in pbones:
        for constraint in bone.constraints:
            constraint.target = bpy.data.objects[arm.my_target]

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None and context.active_object.type == "ARMATURE"

    def draw(self, context):
        layout = self.layout

        arm = context.active_object
        scene = context.scene

        row = layout.row()
        row.prop_search(arm, 'my_target', scene, 'objects')


def register():
    bpy.utils.register_module(__name__)
    bpy.types.Object.my_target = StringProperty(update=apply_target)


def unregister():
    bpy.utils.unregister_module(__name__)
    del bpy.types.Object.my_target

if __name__ == "__main__":
    register()
$\endgroup$

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.