[Bf-blender-cvs] [f3a0267016c] master: Materials: support materials when applying modifier

Jacques Lucke noreply at git.blender.org
Thu May 20 12:16:59 CEST 2021


Commit: f3a0267016cba54873b9b60d857798a13460425d
Author: Jacques Lucke
Date:   Thu May 20 12:15:57 2021 +0200
Branches: master
https://developer.blender.org/rBf3a0267016cba54873b9b60d857798a13460425d

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

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

M	source/blender/blenkernel/BKE_material.h
M	source/blender/blenkernel/intern/material.c
M	source/blender/editors/object/object_add.c
M	source/blender/editors/object/object_modifier.c

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

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) {



More information about the Bf-blender-cvs mailing list