11
$\begingroup$

I need some help in removing all material slots in one go using a python script. I am able to use this, would prefer to ave all removed.

bpy.context.object.active_material_index = 0
bpy.ops.object.material_slot_remove()
bpy.context.object.active_material_index = 1
bpy.ops.object.material_slot_remove()
bpy.context.object.active_material_index = 2
bpy.ops.object.material_slot_remove()
$\endgroup$
1
  • $\begingroup$ You'll find some good answers here $\endgroup$
    – Robin Betts
    Commented Jul 29, 2019 at 17:07

3 Answers 3

4
$\begingroup$

You can also remove all material slots without calling the operator at all, so you don't have to bother with indexes:

bpy.context.object.data.materials.clear()

In general, I would always try to avoid calling operators unless they do something very specific that is difficult to achieve via calling usual API functions.

$\endgroup$
3
  • $\begingroup$ That would remove the materials, not the slots. $\endgroup$ Commented Jun 15, 2022 at 12:31
  • $\begingroup$ Sort of. All materials get removed from the data-block by removing all material slots as well. Afterwards the materials do still exist, but they are no longer linked to the object. Unfortunately the Blender API is not very specific here. $\endgroup$
    – Febulix
    Commented Jun 15, 2022 at 15:24
  • $\begingroup$ Wonder if calling object.data.materials.clear() then calling object.material_slot_remove_unused() is a safe idea - if it works, could be a better solution I guess $\endgroup$
    – jupiterbjy
    Commented May 28, 2023 at 21:28
12
$\begingroup$

You can set the index of the list to 0, iterate through all slots and override the context of material_slot_remove().

Blender 3.2+

import bpy
from bpy import context

for obj in context.selected_editable_objects:
    obj.active_material_index = 0
    for i in range(len(obj.material_slots)):
        with context.temp_override(object=obj):
            bpy.ops.object.material_slot_remove()

Blender 2.8+

import bpy

for obj in bpy.context.selected_editable_objects:
    obj.active_material_index = 0
    for i in range(len(obj.material_slots)):
        bpy.ops.object.material_slot_remove({'object': obj})
$\endgroup$
2
  • $\begingroup$ Can you elaborate the part of overwriting the context? $\endgroup$
    – Mike W
    Commented Apr 19, 2020 at 17:09
  • 1
    $\begingroup$ Further reading: poll() failed, context incorrect? @MikeW $\endgroup$
    – brockmann
    Commented Apr 19, 2020 at 18:40
6
$\begingroup$
import bpy #import the blender python library
for x in bpy.context.object.material_slots: #For all of the materials in the selected object:
    bpy.context.object.active_material_index = 0 #select the top material
    bpy.ops.object.material_slot_remove() #delete it
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .