diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_material.py | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_curve.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_material.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 48 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 32 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 30 | ||||
-rw-r--r-- | source/blender/editors/render/render_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/render/render_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/render/render_shading.c | 70 |
10 files changed, 196 insertions, 2 deletions
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index cea0c9aef95..79199400b63 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_curve.h b/source/blender/blenkernel/BKE_curve.h index ec3c0447269..98c85415812 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -90,6 +90,7 @@ 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); void BKE_curve_material_index_clear(struct Curve *cu); int BKE_curve_material_index_validate(struct Curve *cu); +void BKE_curve_material_remap(struct Curve *cu,const unsigned int *remap, unsigned int remap_len); ListBase *BKE_curve_nurbs_get(struct Curve *cu); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 56393727d28..0cfa1aeecb5 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_remap_object(struct Object *ob, const 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/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index c0d8902eb71..ebf4384d5a7 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -108,6 +108,7 @@ void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblis void BKE_mesh_to_curve(struct Scene *scene, struct Object *ob); void BKE_mesh_material_index_remove(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); const char *BKE_mesh_cmp(struct Mesh *me1, struct Mesh *me2, float thresh); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 5fcdc9c2e78..cd59e30a406 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -4492,6 +4492,54 @@ int BKE_curve_material_index_validate(Curve *cu) } } +void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int remap_len) +{ + const int curvetype = BKE_curve_type_get(cu); + const short remap_len_short = (short)remap_len; + +#define MAT_NR_REMAP(n) \ + if (n < remap_len_short) { \ + BLI_assert(n >= 0 && remap[n] < remap_len_short); \ + n = remap[n]; \ + } ((void)0) + + if (curvetype == OB_FONT) { + struct CharInfo *strinfo; + int charinfo_len, i; + + if (cu->editfont) { + EditFont *ef = cu->editfont; + strinfo = ef->textbufinfo; + charinfo_len = ef->len; + } + else { + strinfo = cu->strinfo; + charinfo_len = cu->len_wchar; + } + + for (i = 0; i <= charinfo_len; i++) { + if (strinfo[i].mat_nr > 0) { + strinfo[i].mat_nr -= 1; + MAT_NR_REMAP(strinfo[i].mat_nr); + strinfo[i].mat_nr += 1; + } + } + } + else { + Nurb *nu; + ListBase *nurbs = BKE_curve_editNurbs_get(cu); + + if (nurbs) { + for (nu = nurbs->first; nu; nu = nu->next) { + MAT_NR_REMAP(nu->mat_nr); + } + } + } + +#undef MAT_NR_REMAP + +} + void BKE_curve_rect_from_textbox(const struct Curve *cu, const struct TextBox *tb, struct rctf *r_rect) { r_rect->xmin = cu->xof + tb->x; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index c7e6b3ba1b3..8932ac1f4c6 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,35 @@ void assign_material(Object *ob, Material *ma, short act, int assign_type) test_object_materials(G.main, ob->data); } + +void BKE_material_remap_object(Object *ob, const unsigned int *remap) +{ + Material ***matar = give_matarar(ob); + const short *totcol_p = give_totcolp(ob); + + BLI_array_permute(ob->mat, ob->totcol, remap); + + if (ob->matbits) { + BLI_array_permute(ob->matbits, ob->totcol, remap); + } + + if(matar) { + BLI_array_permute(*matar, *totcol_p, remap); + } + + if (ob->type == OB_MESH) { + BKE_mesh_material_remap(ob->data, remap, ob->totcol); + } + else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { + BKE_curve_material_remap(ob->data, remap, ob->totcol); + } + else { + /* add support for this object data! */ + BLI_assert(matar == NULL); + } +} + + /* 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/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 87325a7ff47..12379bedb36 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1773,6 +1773,36 @@ void BKE_mesh_material_index_clear(Mesh *me) } } +void BKE_mesh_material_remap(Mesh *me, const unsigned int *remap, unsigned int remap_len) +{ + const short remap_len_short = (short)remap_len; + +#define MAT_NR_REMAP(n) \ + if (n < remap_len_short) { \ + BLI_assert(n >= 0 && remap[n] < remap_len_short); \ + n = remap[n]; \ + } ((void)0) + + if (me->edit_btmesh) { + BMEditMesh *em = me->edit_btmesh; + BMIter iter; + BMFace *efa; + + BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) { + MAT_NR_REMAP(efa->mat_nr); + } + } + else { + int i; + for (i = 0; i < me->totpoly; i++) { + MAT_NR_REMAP(me->mpoly[i].mat_nr); + } + } + +#undef MAT_NR_REMAP + +} + void BKE_mesh_smooth_flag_set(Object *meshOb, int enableSmooth) { Mesh *me = meshOb->data; diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index 5c6744b0248..54429f9f066 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 6aaad98f946..f98083f7e74 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 3de21536148..88f522a2615 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -41,8 +41,9 @@ #include "DNA_space_types.h" #include "DNA_world_types.h" -#include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_math_vector.h" #include "BLF_translation.h" @@ -381,6 +382,73 @@ 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 *slot_remap; + int index_pair[2]; + + int dir = RNA_enum_get(op->ptr, "direction"); + + if (!ob || ob->totcol < 2) { + return OPERATOR_CANCELLED; + } + + /* up */ + if (dir == 1 && ob->actcol > 1) { + index_pair[0] = ob->actcol - 2; + index_pair[1] = ob->actcol - 1; + ob->actcol--; + } + /* down */ + else if (dir == -1 && ob->actcol < ob->totcol) { + index_pair[0] = ob->actcol - 1; + index_pair[1] = ob->actcol - 0; + ob->actcol++; + } + else { + return OPERATOR_CANCELLED; + } + + slot_remap = MEM_mallocN(sizeof(unsigned int) * ob->totcol, __func__); + + range_vn_u(slot_remap, ob->totcol, 0); + + slot_remap[index_pair[0]] = index_pair[1]; + slot_remap[index_pair[1]] = index_pair[0]; + + BKE_material_remap_object(ob, slot_remap); + + MEM_freeN(slot_remap); + + 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)) |