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:
authorBastien Montagne <bastien@blender.org>2020-07-28 19:26:56 +0300
committerBastien Montagne <bastien@blender.org>2020-07-28 19:31:51 +0300
commit9c1da81a4c173437c1e556afde7b32eef4b0a47d (patch)
tree7675a89fde25907989722666b14289e5b2598cbc /source
parent5d88f8eba2e2a303c7777af0aa60aec875071596 (diff)
Fix T54544: "Copy Materials to Selected" only works when materials are defined on the mesh.
Build a temp matarray storing materials from obdata and source object (depending on slots 'allocation' of source object), and assign those to targets. Also remove limitation of 'using same obdata is forbidden', just never edit obdata materials in that case... Certainly not perfect, but already much better than existing code.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_material.h3
-rw-r--r--source/blender/blenkernel/intern/material.c13
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c6
-rw-r--r--source/blender/editors/render/render_shading.c22
4 files changed, 34 insertions, 10 deletions
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 225d966a51a..cae79326dda 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -84,7 +84,8 @@ void BKE_object_material_assign(
void BKE_object_material_array_assign(struct Main *bmain,
struct Object *ob,
struct Material ***matar,
- short totcol);
+ int totcol,
+ const bool to_object_only);
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);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 0e2d8fcf4c7..34835fd1e35 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -955,7 +955,8 @@ void BKE_object_material_remap_calc(Object *ob_dst, Object *ob_src, short *remap
void BKE_object_material_array_assign(Main *bmain,
struct Object *ob,
struct Material ***matar,
- short totcol)
+ int totcol,
+ const bool to_object_only)
{
int actcol_orig = ob->actcol;
short i;
@@ -966,7 +967,15 @@ void BKE_object_material_array_assign(Main *bmain,
/* now we have the right number of slots */
for (i = 0; i < totcol; i++) {
- BKE_object_material_assign(bmain, ob, (*matar)[i], i + 1, BKE_MAT_ASSIGN_USERPREF);
+ if (to_object_only && ob->matbits[i] == 0) {
+ /* If we only assign to object, and that slot uses obdata material, do nothing. */
+ continue;
+ }
+ BKE_object_material_assign(bmain,
+ ob,
+ (*matar)[i],
+ i + 1,
+ to_object_only ? BKE_MAT_ASSIGN_OBJECT : BKE_MAT_ASSIGN_USERPREF);
}
if (actcol_orig > ob->totcol) {
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 5dc4ffcad18..d699d761709 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -4172,7 +4172,8 @@ static Base *mesh_separate_tagged(
BKE_object_material_array_assign(bmain,
base_new->object,
BKE_object_material_array_p(obedit),
- *BKE_object_material_len_p(obedit));
+ *BKE_object_material_len_p(obedit),
+ false);
ED_object_base_select(base_new, BA_SELECT);
@@ -4244,7 +4245,8 @@ static Base *mesh_separate_arrays(Main *bmain,
BKE_object_material_array_assign(bmain,
base_new->object,
BKE_object_material_array_p(obedit),
- *BKE_object_material_len_p(obedit));
+ *BKE_object_material_len_p(obedit),
+ false);
ED_object_base_select(base_new, BA_SELECT);
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 149bae718a0..536252f5003 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -465,17 +465,27 @@ static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
Object *ob = ED_object_context(C);
- Material ***matar;
+ Material ***matar_obdata;
- if (!ob || !(matar = BKE_object_material_array_p(ob))) {
+ if (!ob || !(matar_obdata = BKE_object_material_array_p(ob))) {
return OPERATOR_CANCELLED;
}
+ BLI_assert(ob->totcol == *BKE_object_material_len_p(ob));
+
+ Material ***matar_object = &ob->mat;
+
+ Material **matar = MEM_callocN(sizeof(*matar) * (size_t)ob->totcol, __func__);
+ for (int i = ob->totcol; i--;) {
+ matar[i] = ob->matbits[i] ? (*matar_object)[i] : (*matar_obdata)[i];
+ }
+
CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
if (ob != ob_iter && BKE_object_material_array_p(ob_iter)) {
- if (ob->data != ob_iter->data) {
- BKE_object_material_array_assign(bmain, ob_iter, matar, ob->totcol);
- }
+ /* If we are using the same obdata, we only assign slots in ob_iter that are using object
+ * materials, and not obdata ones. */
+ const bool is_same_obdata = ob->data == ob_iter->data;
+ BKE_object_material_array_assign(bmain, ob_iter, &matar, ob->totcol, is_same_obdata);
if (ob_iter->totcol == ob->totcol) {
ob_iter->actcol = ob->actcol;
@@ -486,6 +496,8 @@ static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
}
CTX_DATA_END;
+ MEM_freeN(matar);
+
return OPERATOR_FINISHED;
}