From f3a0267016cba54873b9b60d857798a13460425d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 20 May 2021 12:15:57 +0200 Subject: Materials: support materials when applying modifier This fixes the `Apply Modifier` and `Visual Geometry to Mesh` operator when a modifier changed materials on the evaluated geometry. This is necessary since rB1a81d268a19f2f1402f408ad1dadf92c7a399607. Differential Revision: https://developer.blender.org/D11303 --- source/blender/blenkernel/BKE_material.h | 3 ++ source/blender/blenkernel/intern/material.c | 37 +++++++++++++++++++++++++ source/blender/editors/object/object_add.c | 1 + source/blender/editors/object/object_modifier.c | 3 ++ 4 files changed, 44 insertions(+) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index ef1de891bfe..dc471fcb62f 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -51,6 +51,9 @@ void BKE_object_material_remap(struct Object *ob, const unsigned int *remap); void BKE_object_material_remap_calc(struct Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst); +void BKE_object_material_from_eval_data(struct Main *bmain, + struct Object *ob_orig, + struct ID *data_eval); struct Material *BKE_material_add(struct Main *bmain, const char *name); struct Material *BKE_gpencil_material_add(struct Main *bmain, const char *name); void BKE_gpencil_material_attr_init(struct Material *ma); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 73a7a69f5a5..73b64e6efb3 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1121,6 +1121,43 @@ void BKE_object_material_remap_calc(Object *ob_dst, Object *ob_src, short *remap BLI_ghash_free(gh_mat_map, NULL, NULL); } +/** + * Copy materials from evaluated geometry to the original geometry of an object. + */ +void BKE_object_material_from_eval_data(Main *bmain, Object *ob_orig, ID *data_eval) +{ + ID *data_orig = ob_orig->data; + + short *orig_totcol = BKE_id_material_len_p(data_orig); + Material ***orig_mat = BKE_id_material_array_p(data_orig); + + short *eval_totcol = BKE_id_material_len_p(data_eval); + Material ***eval_mat = BKE_id_material_array_p(data_eval); + + if (ELEM(NULL, orig_totcol, orig_mat, eval_totcol, eval_mat)) { + return; + } + + /* Remove old materials from original geometry. */ + for (int i = 0; i < *orig_totcol; i++) { + id_us_min(&(*orig_mat)[i]->id); + } + MEM_SAFE_FREE(*orig_mat); + + /* Create new material slots based on materials on evaluated geometry. */ + *orig_totcol = *eval_totcol; + *orig_mat = MEM_callocN(sizeof(void *) * (*eval_totcol), __func__); + for (int i = 0; i < *eval_totcol; i++) { + Material *material_eval = (*eval_mat)[i]; + if (material_eval != NULL) { + Material *material_orig = (Material *)DEG_get_original_id(&material_eval->id); + (*orig_mat)[i] = material_orig; + id_us_plus(&material_orig->id); + } + } + BKE_object_materials_test(bmain, ob_orig, data_orig); +} + /* XXX - this calls many more update calls per object then are needed, could be optimized */ void BKE_object_material_array_assign(Main *bmain, struct Object *ob, diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index c722a0c00ee..8cf7d60e6c4 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -2899,6 +2899,7 @@ static int object_convert_exec(bContext *C, wmOperator *op) me_eval = BKE_mesh_copy_for_eval(me_eval, false); /* Full (edge-angle based) draw calculation should ideally be performed. */ BKE_mesh_edges_set_draw_render(me_eval); + BKE_object_material_from_eval_data(bmain, newob, &me_eval->id); BKE_mesh_nomain_to_mesh(me_eval, newob->data, newob, &CD_MASK_MESH, true); BKE_object_free_modifiers(newob, 0); /* after derivedmesh calls! */ } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index e71b66b1a72..e14e5cbd44b 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -63,6 +63,7 @@ #include "BKE_lattice.h" #include "BKE_lib_id.h" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" #include "BKE_mesh_runtime.h" @@ -772,6 +773,8 @@ static bool modifier_apply_obdata( return false; } + Main *bmain = DEG_get_bmain(depsgraph); + BKE_object_material_from_eval_data(bmain, ob, &mesh_applied->id); BKE_mesh_nomain_to_mesh(mesh_applied, me, ob, &CD_MASK_MESH, true); if (md_eval->type == eModifierType_Multires) { -- cgit v1.2.3