diff options
Diffstat (limited to 'source/blender/editors/render/render_shading.c')
-rw-r--r-- | source/blender/editors/render/render_shading.c | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index f7a1d7187f1..01740c13c9d 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -310,7 +310,7 @@ static int material_slot_de_select(bContext *C, bool select) } else { /* Find the first matching material. - * Note: there may be multiple but thats not a common use case. */ + * Note: there may be multiple but that's not a common use case. */ for (short i = 0; i < ob->totcol; i++) { const Material *mat = give_current_material(ob, i + 1); if (mat_active == mat) { @@ -549,6 +549,73 @@ void OBJECT_OT_material_slot_move(wmOperatorType *ot) "Direction to move the active material towards"); } +static int material_slot_remove_unused_exec(bContext *C, wmOperator *op) +{ + Object *ob = CTX_data_active_object(C); + + if (!ob) { + return OPERATOR_CANCELLED; + } + + /* Removing material slots in edit mode screws things up, see bug #21822.*/ + if (ob == CTX_data_edit_object(C)) { + BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode"); + return OPERATOR_CANCELLED; + } + + int actcol = ob->actcol; + + int removed = 0; + for (int slot = 1; slot <= ob->totcol; slot++) { + while (slot <= ob->totcol && !BKE_object_material_slot_used(ob->data, slot)) { + ob->actcol = slot; + BKE_object_material_slot_remove(CTX_data_main(C), ob); + + if (actcol >= slot) { + actcol--; + } + + removed++; + } + } + + ob->actcol = actcol; + + if (!removed) { + return OPERATOR_CANCELLED; + } + + BKE_reportf(op->reports, RPT_INFO, "Removed %d slots", removed); + + if (ob->mode & OB_MODE_TEXTURE_PAINT) { + Scene *scene = CTX_data_scene(C); + BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); + } + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_material_slot_remove_unused(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Unused Slots"; + ot->idname = "OBJECT_OT_material_slot_remove_unused"; + ot->description = "Remove unused material slots"; + + /* api callbacks */ + ot->exec = material_slot_remove_unused_exec; + ot->poll = ED_operator_object_active_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /********************** new material operator *********************/ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) @@ -859,7 +926,7 @@ static int light_cache_bake_exec(bContext *C, wmOperator *op) EEVEE_lightbake_job_data_free(rj); // no redraw needed, we leave state as we entered it - ED_update_for_newframe(bmain, CTX_data_depsgraph(C)); + ED_update_for_newframe(bmain, CTX_data_depsgraph_pointer(C)); WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene); |