0
$\begingroup$

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
$\endgroup$
  • $\begingroup$ Any Help would be appreciated! $\endgroup$ – Robert Cornwall Jul 13 '16 at 4:27
  • $\begingroup$ This code worked for me (Blender 2.77a) after I added import bpy to the start. $\endgroup$ – MattMS Jul 13 '16 at 5:35
  • $\begingroup$ 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. $\endgroup$ – aliasguru Jul 13 '16 at 6:39
  • $\begingroup$ Test code using simple operator template, 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 blender.stackexchange.com/a/19431/15543 $\endgroup$ – batFINGER Jul 14 '16 at 5:59
2
$\begingroup$

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()
| improve this answer | |
$\endgroup$
  • $\begingroup$ 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? $\endgroup$ – p2or Jul 13 '16 at 11:04
  • 1
    $\begingroup$ @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. $\endgroup$ – batFINGER Jul 13 '16 at 17:29
  • $\begingroup$ 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? $\endgroup$ – Robert Cornwall Jul 13 '16 at 20:54

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.