Small automated script I need your help for a small script, because my python skills are very low.

I would like to automate on my selected objects:


Duplicate object "linked"
Constrain duplicate to original object with "Transforms"
Set all material_slots of duplicate to "object"
Override all empty materials with custom material. A black one for example
Move duplicate with black materials to specific layer


It would be nice if this would work on a hierarchy so it would be possible to do this with rigs.

This is what I have done so far, the biggest problem is to set a material to the empty slots.

import bpy

for ob in bpy.context.selected_objects:
    bpy.ops.object.select_all(action='DESELECT')
    ob.select = True

    bpy.ops.object.duplicate_move_linked(OBJECT_OT_duplicate={"linked":True, "mode":'TRANSLATION'}, TRANSFORM_OT_translate={"value":(0,   0, 0), "constraint_axis":(False, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED',       "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0),     "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False})

    ob.select = True

    bpy.context.scene.objects.active = bpy.context.selected_objects[0]

    bpy.ops.object.constraint_add_with_targets(type='COPY_TRANSFORMS')

    mat = bpy.data.materials.get("#BLACK")

    new = bpy.context.selected_objects[1]

    for matslot in new.material_slots:
        i = ob.material_slots.find(matslot.name)

        matslot.link = 'OBJECT'
The result without calling operators.

import bpy

from bpy import context
# all mesh objects
meshobs = [o for o in context.selected_objects if o.type == 'MESH']
# black material (or None)
black = bpy.data.materials.get('BLACK')
# copy layer
copy_layer = 19
copy_layers = [i == copy_layer for i in range(20)] 
if black is None:
    print("WARNING: no black material")

scene = context.scene

for o in meshobs:
    # linked copy
    copy = o.copy()
    # new copy transforms constraint
    ct = copy.constraints.new('COPY_TRANSFORMS')
    # set target to original
    ct.target = o
    # loop thru material slots
    for slot in copy.material_slots:
        # object link
        slot.link = 'OBJECT'
        # set to black material
        if slot.material is None:
            slot.material = black

    # link to scene
    scene.objects.link(copy)
    # move to copy_layer (after linking to scene)
    copy.layers = copy_layers


It only sets existing slots with empty (slot.material is None) material to black.