diff options
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 47 | ||||
-rw-r--r-- | source/blender/render/intern/bake.c | 6 |
2 files changed, 24 insertions, 29 deletions
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 59530a6d6a6..796ed4f8316 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -653,38 +653,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; @@ -717,17 +708,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 9b56e18bb26..d9f7f9fa0af 100644 --- a/source/blender/render/intern/bake.c +++ b/source/blender/render/intern/bake.c @@ -747,6 +747,7 @@ void RE_bake_pixels_populate(Mesh *me, BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); const int *material_indices = BKE_mesh_material_indices(me); + const int materials_num = targets->materials_num; for (int i = 0; i < tottri; i++) { const MLoopTri *lt = &looptri[i]; @@ -754,7 +755,10 @@ void RE_bake_pixels_populate(Mesh *me, bd.primitive_id = i; /* Find images matching this material. */ - Image *image = targets->material_to_image[material_indices ? material_indices[lt->poly] : 0]; + const int material_index = (material_indices && materials_num) ? + clamp_i(material_indices[lt->poly], 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) { |