Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorLukas Stockner <lukas.stockner@freenet.de>2019-07-31 22:04:52 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2019-07-31 22:08:18 +0300
commita2f357edc2afb8f3ded60bc0e48c4015d6ad8f40 (patch)
tree4643a09b8fec9d4c40309ae9d279a2b47636633d /source
parentfeed46c4ae480ccd3f1b1ee6bb61adaf308f85c3 (diff)
Add operator for removing unused material slots
Reviewers: campbellbarton, brecht Reviewed By: brecht Subscribers: brecht Differential Revision: https://developer.blender.org/D4991
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_curve.h1
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h1
-rw-r--r--source/blender/blenkernel/BKE_material.h1
-rw-r--r--source/blender/blenkernel/BKE_mesh.h1
-rw-r--r--source/blender/blenkernel/intern/curve.c26
-rw-r--r--source/blender/blenkernel/intern/gpencil.c16
-rw-r--r--source/blender/blenkernel/intern/material.c20
-rw-r--r--source/blender/blenkernel/intern/mesh.c21
-rw-r--r--source/blender/editors/render/render_intern.h1
-rw-r--r--source/blender/editors/render/render_ops.c1
-rw-r--r--source/blender/editors/render/render_shading.c67
11 files changed, 156 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index df1e7a7baea..51ff4673aba 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -109,6 +109,7 @@ void BKE_curve_transform(struct Curve *cu,
const bool do_props);
void BKE_curve_translate(struct Curve *cu, float offset[3], const bool do_keys);
void BKE_curve_material_index_remove(struct Curve *cu, int index);
+bool BKE_curve_material_index_used(struct Curve *cu, int index);
void BKE_curve_material_index_clear(struct Curve *cu);
bool BKE_curve_material_index_validate(struct Curve *cu);
void BKE_curve_material_remap(struct Curve *cu, const unsigned int *remap, unsigned int remap_len);
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index ae1000d1b99..60e9e6b91d3 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -87,6 +87,7 @@ void BKE_gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe
/* materials */
void BKE_gpencil_material_index_reassign(struct bGPdata *gpd, int totcol, int index);
+bool BKE_gpencil_material_index_used(struct bGPdata *gpd, int index);
void BKE_gpencil_material_remap(struct bGPdata *gpd,
const unsigned int *remap,
unsigned int remap_len);
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 268cf831456..b1200c7e608 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -90,6 +90,7 @@ void assign_matarar(struct Main *bmain, struct Object *ob, struct Material ***ma
short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma);
bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob);
bool BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob);
+bool BKE_object_material_slot_used(struct ID *id, short actcol);
struct MaterialGPencilStyle *BKE_material_gpencil_settings_get(struct Object *ob, short act);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 3b7fe208bb6..59812df246f 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -182,6 +182,7 @@ void BKE_mesh_to_curve(struct Main *bmain,
struct Scene *scene,
struct Object *ob);
void BKE_mesh_material_index_remove(struct Mesh *me, short index);
+bool BKE_mesh_material_index_used(struct Mesh *me, short index);
void BKE_mesh_material_index_clear(struct Mesh *me);
void BKE_mesh_material_remap(struct Mesh *me, const unsigned int *remap, unsigned int remap_len);
void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 931c0ed73d3..efdfa2c19bb 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -5313,6 +5313,32 @@ void BKE_curve_material_index_remove(Curve *cu, int index)
}
}
+bool BKE_curve_material_index_used(Curve *cu, int index)
+{
+ const int curvetype = BKE_curve_type_get(cu);
+
+ if (curvetype == OB_FONT) {
+ struct CharInfo *info = cu->strinfo;
+ int i;
+ for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ if (info->mat_nr == index) {
+ return true;
+ }
+ }
+ }
+ else {
+ Nurb *nu;
+
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
+ if (nu->mat_nr == index) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
void BKE_curve_material_index_clear(Curve *cu)
{
const int curvetype = BKE_curve_type_get(cu);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 058c0d10b8e..7d732235f7e 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1662,6 +1662,22 @@ void BKE_gpencil_material_index_reassign(bGPdata *gpd, int totcol, int index)
}
}
+/* remove strokes using a material */
+bool BKE_gpencil_material_index_used(bGPdata *gpd, int index)
+{
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ if (gps->mat_nr == index) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
void BKE_gpencil_material_remap(struct bGPdata *gpd,
const unsigned int *remap,
unsigned int remap_len)
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 391af8b96ab..1382b863637 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -366,6 +366,26 @@ static void material_data_index_remove_id(ID *id, short index)
}
}
+bool BKE_object_material_slot_used(ID *id, short actcol)
+{
+ /* ensure we don't try get materials from non-obdata */
+ BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
+
+ switch (GS(id->name)) {
+ case ID_ME:
+ return BKE_mesh_material_index_used((Mesh *)id, actcol - 1);
+ case ID_CU:
+ return BKE_curve_material_index_used((Curve *)id, actcol - 1);
+ case ID_MB:
+ /* meta-elems don't have materials atm */
+ return false;
+ case ID_GD:
+ return BKE_gpencil_material_index_used((bGPdata *)id, actcol - 1);
+ default:
+ return false;
+ }
+}
+
static void material_data_index_clear_id(ID *id)
{
/* ensure we don't try get materials from non-obdata */
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index f38161546e2..7e755e54eaa 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1206,6 +1206,27 @@ void BKE_mesh_material_index_remove(Mesh *me, short index)
}
}
+bool BKE_mesh_material_index_used(Mesh *me, short index)
+{
+ MPoly *mp;
+ MFace *mf;
+ int i;
+
+ for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) {
+ if (mp->mat_nr == index) {
+ return true;
+ }
+ }
+
+ for (mf = me->mface, i = 0; i < me->totface; i++, mf++) {
+ if (mf->mat_nr == index) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void BKE_mesh_material_index_clear(Mesh *me)
{
MPoly *mp;
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index 1e03d986e3e..50f0b53c037 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -37,6 +37,7 @@ void OBJECT_OT_material_slot_select(struct wmOperatorType *ot);
void OBJECT_OT_material_slot_deselect(struct wmOperatorType *ot);
void OBJECT_OT_material_slot_copy(struct wmOperatorType *ot);
void OBJECT_OT_material_slot_move(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_remove_unused(struct wmOperatorType *ot);
void MATERIAL_OT_new(struct wmOperatorType *ot);
void TEXTURE_OT_new(struct wmOperatorType *ot);
diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c
index b77f5c2bbad..8156f48343f 100644
--- a/source/blender/editors/render/render_ops.c
+++ b/source/blender/editors/render/render_ops.c
@@ -42,6 +42,7 @@ void ED_operatortypes_render(void)
WM_operatortype_append(OBJECT_OT_material_slot_deselect);
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(MATERIAL_OT_new);
WM_operatortype_append(TEXTURE_OT_new);
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 5c305f45fb2..36531b2806c 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -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))