UI: Add "Remove All Materials" operator

Added a new operator `OBJECT_OT_material_slot_remove_all`
that removes all materials from the material slots of selected objects

This was inspired by a request proposal on RCS.

Pull Request: https://projects.blender.org/blender/blender/pulls/138402
This commit is contained in:
Eitan Traurig
2025-05-07 08:06:52 +02:00
committed by Pratik Borhade
parent 16c87b62e4
commit dd43ea4e9e
6 changed files with 70 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ class MATERIAL_MT_context_menu(Menu):
layout.operator("object.material_slot_copy")
layout.operator("material.paste", icon='PASTEDOWN')
layout.operator("object.material_slot_remove_unused")
layout.operator("object.material_slot_remove_all")
class MATERIAL_UL_matslots(UIList):

View File

@@ -40,6 +40,7 @@ class GPENCIL_MT_material_context_menu(Menu):
).only_active = False
layout.operator("object.material_slot_remove_unused")
layout.operator("object.material_slot_remove_all")
class GPENCIL_UL_matslots(UIList):

View File

@@ -3351,6 +3351,7 @@ class VIEW3D_MT_object_cleanup(Menu):
layout.separator()
layout.operator("object.material_slot_remove_unused", text="Remove Unused Material Slots")
layout.operator("object.material_slot_remove_all", text="Remove All Materials")
class VIEW3D_MT_object_asset(Menu):

View File

@@ -24,6 +24,7 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot);
void OBJECT_OT_material_slot_copy(wmOperatorType *ot);
void OBJECT_OT_material_slot_move(wmOperatorType *ot);
void OBJECT_OT_material_slot_remove_unused(wmOperatorType *ot);
void OBJECT_OT_material_slot_remove_all(wmOperatorType *ot);
void MATERIAL_OT_new(wmOperatorType *ot);
void TEXTURE_OT_new(wmOperatorType *ot);

View File

@@ -26,6 +26,7 @@ void ED_operatortypes_render()
WM_operatortype_append(OBJECT_OT_material_slot_copy);
WM_operatortype_append(OBJECT_OT_material_slot_move);
WM_operatortype_append(OBJECT_OT_material_slot_remove_unused);
WM_operatortype_append(OBJECT_OT_material_slot_remove_all);
WM_operatortype_append(OBJECT_OT_lightprobe_cache_bake);
WM_operatortype_append(OBJECT_OT_lightprobe_cache_free);

View File

@@ -740,6 +740,71 @@ void OBJECT_OT_material_slot_remove_unused(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static wmOperatorStatus material_slot_remove_all_exec(bContext *C, wmOperator *op)
{
/* Removing material slots in edit mode screws things up, see bug #21822. */
Object *ob_active = CTX_data_active_object(C);
if (ob_active && BKE_object_is_in_editmode(ob_active)) {
BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
return OPERATOR_CANCELLED;
}
Main *bmain = CTX_data_main(C);
int removed = 0;
Vector<Object *> objects = object_array_for_shading_edit_mode_disabled(C);
for (Object *ob : objects) {
int actcol = ob->actcol;
for (int slot = 1; slot <= ob->totcol; slot++) {
while (slot <= ob->totcol) {
ob->actcol = slot;
BKE_object_material_slot_remove(bmain, ob);
if (actcol >= slot) {
actcol--;
}
removed++;
}
}
ob->actcol = actcol;
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
if (!removed) {
return OPERATOR_CANCELLED;
}
BKE_reportf(op->reports, RPT_INFO, "Removed %d materials", removed);
if (ob_active->mode == OB_MODE_TEXTURE_PAINT) {
Scene *scene = CTX_data_scene(C);
ED_paint_proj_mesh_data_check(*scene, *ob_active, nullptr, nullptr, nullptr, nullptr);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, nullptr);
}
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_active);
WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob_active);
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob_active);
return OPERATOR_FINISHED;
}
void OBJECT_OT_material_slot_remove_all(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove All Materials";
ot->idname = "OBJECT_OT_material_slot_remove_all";
ot->description = "Remove all materials";
/* api callbacks */
ot->exec = material_slot_remove_all_exec;
ot->poll = object_materials_supported_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
/* -------------------------------------------------------------------- */