2
$\begingroup$

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'
$\endgroup$
1
$\begingroup$

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.

$\endgroup$
0
$\begingroup$

i think i got it, works well so far. Now i have two buttons, one with black material and one without material.

The goal was to have a second viewport as an alpha mask to key the orignial viewport in realtime over a hardware picture mixer. I think there is a much more elegant way to do this, but im a beginner Biggest problem was to select and deselect the objects in the script.

Cheers Daniel

bl_info = {
    "name": "Alpha",
    "author": "DanielPaul",
    "version": (1, 0),
    "blender": (2, 78, 0),
    "location": "View3D > Tool Shelf > My Tab",
    "description": "Makes_object_to_alpha",
    "warning": "",
    "wiki_url": "",
    "category": "Duplicate",
    }

import bpy


def main(context):
    #get selected objects
    for ob in bpy.context.selected_objects:

        #deselect all
        bpy.ops.object.select_all(action='DESELECT')
        #select only ob
        ob.select = True

        #dublicate linked    
        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})

        #select new linked dublicate    
        ob.select = True
        #set original as active
        bpy.context.scene.objects.active = bpy.context.selected_objects[0]
        #constraint "transform"
        bpy.ops.object.constraint_add_with_targets(type='COPY_TRANSFORMS')

        #select linked dublicate
        new = bpy.context.selected_objects[1]

        #change "data" in material slot to "object"    
        for matslot in new.material_slots:

            matslot.link = 'OBJECT'

        bpy.ops.object.select_all(action='DESELECT')
        new.select = True
        bpy.ops.object.move_to_layer(layers=(False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True))

def second(context):
    #get selected objects
    for ob in bpy.context.selected_objects:

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

        if mat is None:
            # create material
            mat = bpy.data.materials.new(name="#BLACK")
            mat.diffuse_color = (0,0,0)
            mat.specular_color = (0,0,0)


        #deselect all
        bpy.ops.object.select_all(action='DESELECT')
        #select only ob
        ob.select = True

        #dublicate linked    
        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})

        #select new linked dublicate    
        ob.select = True
        #set original as active
        bpy.context.scene.objects.active = bpy.context.selected_objects[0]
        #constraint "transform"
        bpy.ops.object.constraint_add_with_targets(type='COPY_TRANSFORMS')

        #select linked dublicate
        new = bpy.context.selected_objects[1]

        #change "data" in material slot to "object"    
        for matslot in new.material_slots:

            matslot.link = 'OBJECT'


                #set black mat to empty mat slots in dublicate
        for i in range(len(new.material_slots)):
            new.material_slots[i].material = mat

        bpy.ops.object.select_all(action='DESELECT')
        new.select = True
        bpy.ops.object.move_to_layer(layers=(False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True))

class WhiteAlphaDublicate(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "myops.white_alphadublicate"
    bl_label = "White alpha"


    def execute(self, context):
        main(context)
        return {'FINISHED'}

class BlackAlphaDublicate(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "myops.black_alphadublicate"
    bl_label = "Black alpha"


    def execute(self, context):
        second(context)
        return {'FINISHED'}

class AlphaDublicatePanel(bpy.types.Panel):
    """Creates a Panel in the Tool Shelf"""
    bl_label = "Alpha dublicate"
    bl_idname = "OBJECT_PT_alpha"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_category = "Studio_tools"

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

        row = layout.row()
        row.operator("myops.white_alphadublicate")
        row.operator("myops.black_alphadublicate")

def register():
    bpy.utils.register_class(WhiteAlphaDublicate)
    bpy.utils.register_class(BlackAlphaDublicate)
    bpy.utils.register_class(AlphaDublicatePanel)

def unregister():
    bpy.utils.unregister_class(WhiteAlphaDublicate)
    bpy.utils.unregister_class(BlackAlphaDublicate)
    bpy.utils.unregister_class(AlphaDublicatePanel)

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.