[Bf-blender-cvs] [b9f5d00] temp-material-remap: Material slot reorder https://developer.blender.org/T43235 (WIP)

Gaia Clary noreply at git.blender.org
Mon Apr 27 22:25:13 CEST 2015


Commit: b9f5d00c31ed418b0235f4a62b976b25a3f8ace5
Author: Gaia Clary
Date:   Tue Apr 28 05:51:38 2015 +1000
Branches: temp-material-remap
https://developer.blender.org/rBb9f5d00c31ed418b0235f4a62b976b25a3f8ace5

Material slot reorder https://developer.blender.org/T43235 (WIP)

This Diff implements the Material Slot reorder.
This Diff is a WIP and it probably needs a lot of rework, however i'd like to get some feedback
before i continue on it.

Note: I started with Severin's initial patch P193
There i added support for Materials assigned to Objects and materials assigned to Data
Then finally i added the material assignment swapping for Mesh, Nurbs and Fonts.

I tested the Diff for Mesh objects and there it seems to work nicely.
So for Mesh objects now changing the material order will preserve the material assignments.

Any feedback appreciated.
thanks

Reviewers: Severin, campbellbarton

Subscribers: campbellbarton

Maniphest Tasks: T43235

Differential Revision: https://developer.blender.org/D1262

===================================================================

M	release/scripts/startup/bl_ui/properties_material.py
M	source/blender/blenkernel/BKE_material.h
M	source/blender/blenkernel/intern/material.c
M	source/blender/editors/render/render_intern.h
M	source/blender/editors/render/render_ops.c
M	source/blender/editors/render/render_shading.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index cea0c9a..4f15d6f 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -123,11 +123,16 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
         ob = context.object
         slot = context.material_slot
         space = context.space_data
+        is_sortable = len(ob.material_slots) > 1
 
         if ob:
+            rows = 1
+            if (is_sortable):
+                rows = 4
+
             row = layout.row()
 
-            row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=1)
+            row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
 
             col = row.column(align=True)
             col.operator("object.material_slot_add", icon='ZOOMIN', text="")
@@ -135,6 +140,12 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
 
             col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
 
+            if is_sortable:
+                col.separator()
+
+                col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP'
+                col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
+
             if ob.mode == 'EDIT':
                 row = layout.row(align=True)
                 row.operator("object.material_slot_assign", text="Assign")
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 5639372..f8c658a 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -50,6 +50,7 @@ void BKE_material_free_ex(struct Material *ma, bool do_id_user);
 void test_object_materials(struct Main *bmain, struct ID *id);
 void BKE_material_resize_object(struct Object *ob, const short totcol, bool do_id_user);
 void init_material(struct Material *ma);
+void BKE_material_id_remap(struct Object *ob, unsigned int remap[]);
 struct Material *BKE_material_add(struct Main *bmain, const char *name);
 struct Material *BKE_material_copy(struct Material *ma);
 struct Material *localize_material(struct Material *ma);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index c7e6b3b..c50d52f 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -53,6 +53,7 @@
 #include "BLI_listbase.h"		
 #include "BLI_utildefines.h"
 #include "BLI_string.h"
+#include "BLI_array_utils.h"
 
 #include "BKE_animsys.h"
 #include "BKE_displist.h"
@@ -66,6 +67,8 @@
 #include "BKE_scene.h"
 #include "BKE_node.h"
 #include "BKE_curve.h"
+#include "BKE_editmesh.h"
+#include "BKE_font.h"
 
 #include "GPU_material.h"
 
@@ -922,6 +925,62 @@ void assign_material(Object *ob, Material *ma, short act, int assign_type)
 	test_object_materials(G.main, ob->data);
 }
 
+
+void BKE_material_id_remap(Object *ob, unsigned int remap[])
+{
+	short mat_nr_max = ob->totcol;
+
+	BLI_array_permute(ob->mat, ob->totcol, remap);
+	if (ob->matbits)
+		BLI_array_permute(ob->matbits, ob->totcol, remap);
+
+	Material ***matarrar = give_matarar(ob);
+	if(matarrar)
+		BLI_array_permute(*matarrar, ob->totcol, remap);
+
+	/* Now reassign the new material order to the affected items in the object*/
+	if (ob->type == OB_MESH) {
+
+		if (ob->mode == OB_MODE_EDIT) {
+			BMEditMesh *em = BKE_editmesh_from_object(ob);
+			BMFace *efa;
+			BMIter iter;
+
+			if (em) {
+				BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) {
+					if (remap[efa->mat_nr] < mat_nr_max)
+						efa->mat_nr = remap[efa->mat_nr];
+				}
+			}
+		}
+		else {
+			Mesh *me = ob->data;
+			for (int index = 0; index < me->totpoly; index++)
+				if (remap[me->mpoly[index].mat_nr] < mat_nr_max)
+					me->mpoly[index].mat_nr = remap[me->mpoly[index].mat_nr];
+		}
+	}
+	else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+		Nurb *nu;
+		ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
+
+		if (nurbs) {
+			for (nu = nurbs->first; nu; nu = nu->next)
+				if (remap[nu->charidx] < mat_nr_max)
+					nu->mat_nr = remap[nu->charidx];
+		}
+	}
+	else if (ob->type == OB_FONT) {
+		EditFont *ef = ((Curve *)ob->data)->editfont;
+		if (ef) {
+			for (int i = 0; i <= ef->len; i++)
+				if (remap[ef->textbufinfo[i].mat_nr] < mat_nr_max)
+					ef->textbufinfo[i].mat_nr = remap[ef->textbufinfo[i].mat_nr];
+		}
+	}
+}
+
+
 /* XXX - this calls many more update calls per object then are needed, could be optimized */
 void assign_matarar(struct Object *ob, struct Material ***matar, short totcol)
 {
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index 5c6744b..54429f9 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -44,6 +44,7 @@ void OBJECT_OT_material_slot_assign(struct wmOperatorType *ot);
 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 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 6aaad98..f98083f 100644
--- a/source/blender/editors/render/render_ops.c
+++ b/source/blender/editors/render/render_ops.c
@@ -47,6 +47,7 @@ void ED_operatortypes_render(void)
 	WM_operatortype_append(OBJECT_OT_material_slot_select);
 	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(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 3de2153..b854664 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -381,6 +381,70 @@ void OBJECT_OT_material_slot_copy(wmOperatorType *ot)
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
 }
 
+
+static int material_slot_move_exec(bContext *C, wmOperator *op)
+{
+	Object *ob = ED_object_context(C);
+
+	unsigned int *slotremap;
+
+	int dir = RNA_enum_get(op->ptr, "direction");
+
+	if (!ob || ob->totcol ==0) {
+		return OPERATOR_CANCELLED;
+	}
+
+	slotremap = MEM_mallocN(sizeof(unsigned int) * ob->totcol, "Temp remap array BKE_material_id_remap");
+	for (int index = 0; index < ob->totcol; index++)
+		slotremap[index] = index;
+
+	/* up */
+	if (dir == 1 && ob->actcol > 1) {
+		slotremap[ob->actcol - 2] = ob->actcol - 1;
+		slotremap[ob->actcol - 1] = ob->actcol - 2;
+		ob->actcol--;
+	}
+	/* down */
+	else if (dir == -1 && ob->actcol < ob->totcol) {
+		slotremap[ob->actcol - 1] = ob->actcol - 0;
+		slotremap[ob->actcol - 0] = ob->actcol - 1;
+		ob->actcol++;
+	}
+	else {
+		MEM_freeN(slotremap);
+		return OPERATOR_CANCELLED;
+	}
+
+	BKE_material_id_remap(ob, slotremap);
+	MEM_freeN(slotremap);
+
+	WM_event_add_notifier(C, NC_OBJECT | ND_DRAW | ND_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_move(wmOperatorType *ot)
+{
+	static EnumPropertyItem material_slot_move[] = {
+		{1, "UP", 0, "Up", ""},
+		{-1, "DOWN", 0, "Down", ""},
+		{0, NULL, 0, NULL, NULL}
+	};
+
+	/* identifiers */
+	ot->name = "Move Material";
+	ot->idname = "OBJECT_OT_material_slot_move";
+	ot->description = "Move the active material up/down in the list";
+
+	/* api callbacks */
+	ot->exec = material_slot_move_exec;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+	RNA_def_enum(ot->srna, "direction", material_slot_move, 0, "Direction", "Direction to move, UP or DOWN");
+}
+
 /********************** new material operator *********************/
 
 static int new_material_exec(bContext *C, wmOperator *UNUSED(op))




More information about the Bf-blender-cvs mailing list