[Bf-blender-cvs] [282e8499b10] master: Fix T73871: improve assignement of material to selection in multi object editmode

Philipp Oeser noreply at git.blender.org
Thu Feb 20 14:08:36 CET 2020


Commit: 282e8499b1092f57394711c638011af61dd29456
Author: Philipp Oeser
Date:   Mon Feb 17 10:29:08 2020 +0100
Branches: master
https://developer.blender.org/rB282e8499b1092f57394711c638011af61dd29456

Fix T73871: improve assignement of material to selection in multi object
editmode

This was already supported in "Select" & "Deselect" but not in "Assign".
So similar to rB6b39dc7672eb, we now check if the material corresponding
to the currently selected material slot is found in other objects
materials and assign this (instead of always assigning their 'own'
actcol).

Maniphest Tasks: T73871

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

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

M	source/blender/editors/render/render_shading.c

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

diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 95bc90c8e5f..8ecaeefbd5f 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -217,13 +217,38 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
   View3D *v3d = CTX_wm_view3d(C);
   bool changed_multi = false;
 
+  Object *obact = CTX_data_active_object(C);
+  const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : NULL;
+
   uint objects_len = 0;
   Object **objects = object_array_for_shading(C, &objects_len);
   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
     Object *ob = objects[ob_index];
-    if (ob->actcol <= 0) {
+    short mat_nr_active = -1;
+
+    if (ob->totcol == 0) {
       continue;
     }
+    if (obact && (mat_active == BKE_object_material_get(ob, obact->actcol))) {
+      /* Avoid searching since there may be multiple slots with the same material.
+       * For the active object or duplicates: match the material slot index first. */
+      mat_nr_active = obact->actcol - 1;
+    }
+    else {
+      /* Find the first matching material.
+       * Note: there may be multiple but that's not a common use case. */
+      for (short i = 0; i < ob->totcol; i++) {
+        const Material *mat = BKE_object_material_get(ob, i + 1);
+        if (mat_active == mat) {
+          mat_nr_active = i;
+          break;
+        }
+      }
+      if (mat_nr_active == -1) {
+        continue;
+      }
+    }
+
     bool changed = false;
     if (ob->type == OB_MESH) {
       BMEditMesh *em = BKE_editmesh_from_object(ob);
@@ -234,7 +259,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
         BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
           if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
             changed = true;
-            efa->mat_nr = ob->actcol - 1;
+            efa->mat_nr = mat_nr_active;
           }
         }
       }
@@ -247,7 +272,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
         for (nu = nurbs->first; nu; nu = nu->next) {
           if (ED_curve_nurb_select_check(v3d, nu)) {
             changed = true;
-            nu->mat_nr = ob->actcol - 1;
+            nu->mat_nr = mat_nr_active;
           }
         }
       }
@@ -259,7 +284,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
       if (ef && BKE_vfont_select_get(ob, &selstart, &selend)) {
         for (i = selstart; i <= selend; i++) {
           changed = true;
-          ef->textbufinfo[i].mat_nr = ob->actcol;
+          ef->textbufinfo[i].mat_nr = mat_nr_active + 1;
         }
       }
     }



More information about the Bf-blender-cvs mailing list