[Bf-blender-cvs] [dd7a10e5a5f] blender-v3.3-release: Fix T102214: inconsistenty between bake and render with invalid material index

Brecht Van Lommel noreply at git.blender.org
Mon Nov 28 17:03:04 CET 2022


Commit: dd7a10e5a5f15fac6d0c06f49dc1f2e59637f7ec
Author: Brecht Van Lommel
Date:   Wed Nov 9 16:59:16 2022 +0100
Branches: blender-v3.3-release
https://developer.blender.org/rBdd7a10e5a5f15fac6d0c06f49dc1f2e59637f7ec

Fix T102214: inconsistenty between bake and render with invalid material index

When the materal slot index on mesh faces exceeds the number of slots, rendering
would use the last material slot while other operations like baking would fall
back to the default material.

Now consistently use the last material slot in such cases, since preserving
backwards compatibility for rendering seems most important. And if there is
one material slot, it's more useful to use that one rather than falling back
to the default material.

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

M	source/blender/blenkernel/intern/material.c
M	source/blender/render/intern/bake.c

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

diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index f899901b54e..df2c48aaac5 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -652,38 +652,29 @@ Material **BKE_object_material_get_p(Object *ob, short act)
 
   /* if object cannot have material, (totcolp == NULL) */
   totcolp = BKE_object_material_len_p(ob);
-  if (totcolp == NULL || ob->totcol == 0) {
+  if (totcolp == NULL || *totcolp == 0) {
     return NULL;
   }
 
-  /* return NULL for invalid 'act', can happen for mesh face indices */
-  if (act > ob->totcol) {
-    return NULL;
-  }
-  if (act <= 0) {
-    if (act < 0) {
-      CLOG_ERROR(&LOG, "Negative material index!");
-    }
-    return NULL;
-  }
+  /* Clamp to number of slots if index is out of range, same convention as used for rendering. */
+  const int slot_index = clamp_i(act - 1, 0, *totcolp - 1);
 
-  if (ob->matbits && ob->matbits[act - 1]) { /* in object */
-    ma_p = &ob->mat[act - 1];
+  /* Fix inconsistency which may happen when library linked data reduces the number of
+   * slots but object was not updated. Ideally should be fixed elsewhere. */
+  if (*totcolp < ob->totcol) {
+    ob->totcol = *totcolp;
   }
-  else { /* in data */
-
-    /* check for inconsistency */
-    if (*totcolp < ob->totcol) {
-      ob->totcol = *totcolp;
-    }
-    if (act > ob->totcol) {
-      act = ob->totcol;
-    }
 
+  if (slot_index < ob->totcol && ob->matbits && ob->matbits[slot_index]) {
+    /* Use object material slot. */
+    ma_p = &ob->mat[slot_index];
+  }
+  else {
+    /* Use data material slot. */
     matarar = BKE_object_material_array_p(ob);
 
     if (matarar && *matarar) {
-      ma_p = &(*matarar)[act - 1];
+      ma_p = &(*matarar)[slot_index];
     }
     else {
       ma_p = NULL;
@@ -716,17 +707,17 @@ static ID *get_evaluated_object_data_with_materials(Object *ob)
 Material *BKE_object_material_get_eval(Object *ob, short act)
 {
   BLI_assert(DEG_is_evaluated_object(ob));
-  const int slot_index = act - 1;
 
-  if (slot_index < 0) {
-    return NULL;
-  }
   ID *data = get_evaluated_object_data_with_materials(ob);
   const short *tot_slots_data_ptr = BKE_id_material_len_p(data);
   const int tot_slots_data = tot_slots_data_ptr ? *tot_slots_data_ptr : 0;
-  if (slot_index >= tot_slots_data) {
+
+  if (tot_slots_data == 0) {
     return NULL;
   }
+
+  /* Clamp to number of slots if index is out of range, same convention as used for rendering. */
+  const int slot_index = clamp_i(act - 1, 0, tot_slots_data - 1);
   const int tot_slots_object = ob->totcol;
 
   Material ***materials_data_ptr = BKE_id_material_array_p(data);
diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c
index 9ffe2879779..095d03b857f 100644
--- a/source/blender/render/intern/bake.c
+++ b/source/blender/render/intern/bake.c
@@ -740,6 +740,7 @@ void RE_bake_pixels_populate(Mesh *me,
   MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
 
   BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
+  const int materials_num = targets->materials_num;
 
   for (int i = 0; i < tottri; i++) {
     const MLoopTri *lt = &looptri[i];
@@ -748,7 +749,11 @@ void RE_bake_pixels_populate(Mesh *me,
     bd.primitive_id = i;
 
     /* Find images matching this material. */
-    Image *image = targets->material_to_image[mp->mat_nr];
+    const int material_index = (materials_num) ? clamp_i(targets->material_to_image[mp->mat_nr],
+                                                         0,
+                                                         materials_num - 1) :
+                                                 0;
+    Image *image = targets->material_to_image[material_index];
     for (int image_id = 0; image_id < targets->images_num; image_id++) {
       BakeImage *bk_image = &targets->images[image_id];
       if (bk_image->image != image) {



More information about the Bf-blender-cvs mailing list