1

I must be misunderstanding something. I really need a sanity check.

I'm trying to duplicate the active object, then delete all the material slots from it without affecting the original.

==== EDIT====== Thanks for the answers, it looks like I only have this problem when the code is part of an operator:

def invoke(self, context, event) :
    def deleteMatsFromDuplicate():

        scene = context.scene

        # Duplicate the model
        obj = context.active_object
        obj.select = False
        obj_copy = obj.copy()
        obj_copy.location += Vector((1, 1, 1))
        mesh_copy = obj.data.copy()
        obj_copy.data = mesh_copy
        scene.objects.link(obj_copy)
        scene.objects.active = obj_copy
        obj_copy.select = True
        obj_copy.name = "copy"

        #loop thru and remove all
        for ms in obj_copy.material_slots:
            bpy.ops.object.material_slot_remove()
    # end deleteMatsFromDuplicate

    deleteMatsFromDuplicate()

    return {"FINISHED"}
#end invoke
batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • Any Help would be appreciated! – Robert Cornwall Jul 13 '16 at 04:27
  • Is the script you've posted part of an operator? If you just run these lines from a text editor, this should work, but from within an operator there is a potential catch to it. In case it is an operator, please post the rest of the code too if possible. – aliasguru Jul 13 '16 at 06:39
  • This code worked for me (Blender 2.77a) after I added import bpy to the start. – MattMS Jul 13 '16 at 05:35
  • Test code using simple operator template, http://www.pasteall.org/71940/python are you invoking the operator or calling form script, in which case you need to bpy.ops.some_op('INVOKE_DEFAULT') See http://blender.stackexchange.com/a/19431/15543 – batFINGER Jul 14 '16 at 05:59

1 Answers1

3

I'm assuming by the behaviour of question code (pre edit) that the material_slot link is 'OBJECT' rather than 'DATA'. Code below should work on either. Used copy() method of object and mesh to create a copy, added (1,1,1) to the location, linked to scene, made active, and removed all material slots.

import bpy
from mathutils import Vector
context = bpy.context
scene = context.scene

obj = context.active_object
obj.select = False
obj_copy = obj.copy()
obj_copy.location += Vector((1, 1, 1))
mesh_copy = obj.data.copy()
obj_copy.data = mesh_copy
scene.objects.link(obj_copy)
scene.objects.active = obj_copy
obj_copy.select = True
#loop thru and remove all
for ms in obj_copy.material_slots:
    bpy.ops.object.material_slot_remove()
batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • Works great! Just out of interest: I ever thought when linking an object to the scene like link(obj_copy) we need to update the scene via scene.update(). Do you know why this is not relevant here? – p2or Jul 13 '16 at 11:04
  • 1
    @poor My guess is scene.objects.link(o) may force a scene update, as does scene.frame_set(f) would have to look at code to be certain. – batFINGER Jul 13 '16 at 17:29
  • It works like a charm :) Except, if I put the code in 'invoke' or 'execute' then I get the same problem I had before. Why is that? – Robert Cornwall Jul 13 '16 at 20:54