Modifiers: every modifier now copies mesh settings, fixing texture space issues
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Mon, 16 Sep 2019 08:45:49 +0000 (10:45 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Mon, 23 Sep 2019 14:27:23 +0000 (16:27 +0200)
Modifier stack evaluation would copy mesh settings other than mesh topology
automatically, outside of the individual modifier evaluation. This leads to hard
to understand code, and makes it unclear which settings are available in following
modifiers, and which only after the entire stack is evaluated.

Now every modifier is responsible to ensure the mesh it outputs preserves materials,
texture space and other settings, or alters them as needed.

Fixes T64739: incorrect texture space for various modifiers

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

20 files changed:
source/blender/alembic/intern/abc_mesh.cc
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/crazyspace.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/smoke.c
source/blender/editors/mesh/editmesh_mask_extract.c
source/blender/modifiers/intern/MOD_bevel.c
source/blender/modifiers/intern/MOD_boolean.c
source/blender/modifiers/intern/MOD_decimate.c
source/blender/modifiers/intern/MOD_edgesplit.c
source/blender/modifiers/intern/MOD_fluidsim_util.c
source/blender/modifiers/intern/MOD_mirror.c
source/blender/modifiers/intern/MOD_ocean.c
source/blender/modifiers/intern/MOD_particlesystem.c
source/blender/modifiers/intern/MOD_remesh.c
source/blender/modifiers/intern/MOD_skin.c
source/blender/modifiers/intern/MOD_triangulate.c
source/blender/modifiers/intern/MOD_util.c
source/blender/modifiers/intern/MOD_wireframe.c

index 5d336c599f4555c36871222e65ed61d3408322cb..12c59964a8c21e512f9f38a06b07893caa498715 100644 (file)
@@ -561,7 +561,7 @@ Mesh *AbcGenericMeshWriter::getFinalMesh(bool &r_needsfree)
 
     BM_mesh_triangulate(bm, quad_method, ngon_method, 4, tag_only, NULL, NULL, NULL);
 
-    Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+    Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
     BM_mesh_free(bm);
 
     if (r_needsfree) {
@@ -1192,8 +1192,6 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
         existing_mesh, positions->size(), 0, 0, face_indices->size(), face_counts->size());
 
     settings.read_flag |= MOD_MESHSEQ_READ_ALL;
-    /* XXX fixme after 2.80; mesh->flag isn't copied by BKE_mesh_new_nomain_from_template() */
-    new_mesh->flag |= (existing_mesh->flag & ME_AUTOSMOOTH);
   }
   else {
     /* If the face count changed (e.g. by triangulation), only read points.
index 76e67065329bddcc590ab86fef9e101c17216e82..90afec54561a8312a33c14ee7d78f5c3fb7a8a8b 100644 (file)
@@ -78,12 +78,18 @@ struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me,
                                 const bool add_key_index,
                                 const struct BMeshCreateParams *params);
 
-struct Mesh *BKE_mesh_from_bmesh_nomain(struct BMesh *bm, const struct BMeshToMeshParams *params);
+struct Mesh *BKE_mesh_from_bmesh_nomain(struct BMesh *bm,
+                                        const struct BMeshToMeshParams *params,
+                                        const struct Mesh *me_settings);
 struct Mesh *BKE_mesh_from_bmesh_for_eval_nomain(struct BMesh *bm,
-                                                 const struct CustomData_MeshMasks *cd_mask_extra);
+                                                 const struct CustomData_MeshMasks *cd_mask_extra,
+                                                 const struct Mesh *me_settings);
 
 struct Mesh *BKE_mesh_from_editmesh_with_coords_thin_wrap(
-    struct BMEditMesh *em, const struct CustomData_MeshMasks *data_mask, float (*vertexCos)[3]);
+    struct BMEditMesh *em,
+    const struct CustomData_MeshMasks *data_mask,
+    float (*vertexCos)[3],
+    const struct Mesh *me_settings);
 
 int poly_find_loop_from_vert(const struct MPoly *poly,
                              const struct MLoop *loopstart,
@@ -107,6 +113,7 @@ void BKE_mesh_copy_data(struct Main *bmain,
                         const struct Mesh *me_src,
                         const int flag);
 struct Mesh *BKE_mesh_copy(struct Main *bmain, const struct Mesh *me);
+void BKE_mesh_copy_settings(struct Mesh *me_dst, const struct Mesh *me_src);
 void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd);
 void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
 
index 010e162f49d84caadda6d4da15ec0ae5dd2724b3..4849d63149378297050d22c46c1bd07eea008fc3 100644 (file)
@@ -729,7 +729,7 @@ static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer)
   int free;
 
   if (em) {
-    mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
+    mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL, me);
   }
   else {
     mesh = BKE_mesh_copy_for_eval(me, true);
@@ -797,14 +797,6 @@ static void editmesh_update_statvis_color(const Scene *scene, Object *ob)
   BKE_editmesh_statvis_calc(em, me->runtime.edit_data, &scene->toolsettings->statvis);
 }
 
-static void mesh_copy_autosmooth(Mesh *me, Mesh *me_orig)
-{
-  if (me_orig->flag & ME_AUTOSMOOTH) {
-    me->flag |= ME_AUTOSMOOTH;
-    me->smoothresh = me_orig->smoothresh;
-  }
-}
-
 static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
                                              const CustomData_MeshMasks *final_datamask,
                                              const bool sculpt_dyntopo,
@@ -881,18 +873,8 @@ static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval)
   /* Make sure the name is the same. This is because mesh allocation from template does not
    * take care of naming. */
   BLI_strncpy(mesh_eval->id.name, mesh_input->id.name, sizeof(mesh_eval->id.name));
-  /* Make sure materials are preserved from the input. */
-  if (mesh_eval->mat != NULL) {
-    MEM_freeN(mesh_eval->mat);
-  }
-  mesh_eval->mat = MEM_dupallocN(mesh_input->mat);
-  mesh_eval->totcol = mesh_input->totcol;
   /* Make evaluated mesh to share same edit mesh pointer as original and copied meshes. */
   mesh_eval->edit_mesh = mesh_input->edit_mesh;
-  /* Copy auth-smooth settings which are also not taken care about by mesh allocation from a
-   * template. */
-  mesh_eval->flag |= (mesh_input->flag & ME_AUTOSMOOTH);
-  mesh_eval->smoothresh = mesh_input->smoothresh;
 }
 
 static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
@@ -1220,8 +1202,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
           MEM_freeN(deformed_verts);
           deformed_verts = NULL;
         }
-
-        mesh_copy_autosmooth(mesh_final, mesh_input);
       }
 
       /* create an orco mesh in parallel */
@@ -1533,8 +1513,8 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
   /* Evaluate modifiers up to certain index to get the mesh cage. */
   int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
   if (r_cage && cageIndex == -1) {
-    mesh_cage = BKE_mesh_from_editmesh_with_coords_thin_wrap(em_input, &final_datamask, NULL);
-    mesh_copy_autosmooth(mesh_cage, mesh_input);
+    mesh_cage = BKE_mesh_from_editmesh_with_coords_thin_wrap(
+        em_input, &final_datamask, NULL, mesh_input);
   }
 
   /* Clear errors before evaluation. */
@@ -1574,9 +1554,8 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
       }
       else if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
         if (mesh_final == NULL) {
-          mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, NULL);
+          mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, NULL, mesh_input);
           ASSERT_IS_VALID_MESH(mesh_final);
-          mesh_copy_autosmooth(mesh_final, mesh_input);
         }
         BLI_assert(deformed_verts != NULL);
         BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
@@ -1607,11 +1586,9 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
         }
       }
       else {
-        mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, NULL);
+        mesh_final = BKE_mesh_from_bmesh_for_eval_nomain(em_input->bm, NULL, mesh_input);
         ASSERT_IS_VALID_MESH(mesh_final);
 
-        mesh_copy_autosmooth(mesh_final, mesh_input);
-
         if (deformed_verts) {
           BKE_mesh_vert_coords_apply(mesh_final, deformed_verts);
         }
@@ -1674,8 +1651,6 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
           MEM_freeN(deformed_verts);
           deformed_verts = NULL;
         }
-
-        mesh_copy_autosmooth(mesh_final, mesh_input);
       }
       mesh_final->runtime.deformed_only = false;
     }
@@ -1695,8 +1670,10 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
           me_orig->runtime.edit_data->vertexCos = MEM_dupallocN(deformed_verts);
         }
         mesh_cage = BKE_mesh_from_editmesh_with_coords_thin_wrap(
-            em_input, &final_datamask, deformed_verts ? MEM_dupallocN(deformed_verts) : NULL);
-        mesh_copy_autosmooth(mesh_cage, mesh_input);
+            em_input,
+            &final_datamask,
+            deformed_verts ? MEM_dupallocN(deformed_verts) : NULL,
+            mesh_input);
       }
     }
 
@@ -1730,11 +1707,9 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
   else {
     /* this is just a copy of the editmesh, no need to calc normals */
     mesh_final = BKE_mesh_from_editmesh_with_coords_thin_wrap(
-        em_input, &final_datamask, deformed_verts);
+        em_input, &final_datamask, deformed_verts, mesh_input);
     deformed_verts = NULL;
 
-    mesh_copy_autosmooth(mesh_final, mesh_input);
-
     /* In this case, we should never have weight-modifying modifiers in stack... */
     if (do_init_statvis) {
       editmesh_update_statvis_color(scene, ob);
@@ -1854,11 +1829,6 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
                       &ob->runtime.mesh_eval);
 
   BKE_object_boundbox_calc_from_mesh(ob, ob->runtime.mesh_eval);
-  /* Only copy texspace from orig mesh if some modifier (hint: smoke sim, see T58492)
-   * did not re-enable that flag (which always get disabled for eval mesh as a start). */
-  if (!(ob->runtime.mesh_eval->texflag & ME_AUTOSPACE)) {
-    BKE_mesh_texspace_copy_from_object(ob->runtime.mesh_eval, ob);
-  }
 
   assign_object_mesh_eval(ob);
 
index af4bd5d2ebd0356931152531b6347e39700d7195..6740fc985e9027af596c2f90c1f60607f5b962b6 100644 (file)
@@ -261,7 +261,8 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
                                                        float (**deformcos)[3])
 {
   ModifierData *md;
-  Mesh *me;
+  Mesh *me_input = ob->data;
+  Mesh *me = NULL;
   int i, a, numleft = 0, numVerts = 0;
   int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
   float(*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
@@ -270,7 +271,6 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
 
   modifiers_clearErrors(ob);
 
-  me = NULL;
   md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
 
   /* compute the deformation matrices and coordinates for the first
@@ -292,7 +292,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
         data_mask = datamasks->mask;
         BLI_linklist_free((LinkNode *)datamasks, NULL);
 
-        me = BKE_mesh_from_editmesh_with_coords_thin_wrap(em, &data_mask, NULL);
+        me = BKE_mesh_from_editmesh_with_coords_thin_wrap(em, &data_mask, NULL, me_input);
         deformedVerts = editbmesh_vert_coords_alloc(em, &numVerts);
         defmats = MEM_mallocN(sizeof(*defmats) * numVerts, "defmats");
 
index a98fc414f31e8c5cbc8fd5a2e312ffadabe57970..05d6f2c5ddf3a4ab28ae52bb0af7a8c50aaf28de 100644 (file)
@@ -657,6 +657,30 @@ Mesh *BKE_mesh_new_nomain(
   return mesh;
 }
 
+/* Copy user editable settings that we want to preserve through the modifier stack
+ * or operations where a mesh with new topology is created based on another mesh. */
+void BKE_mesh_copy_settings(Mesh *me_dst, const Mesh *me_src)
+{
+  /* Copy general settings. */
+  me_dst->editflag = me_src->editflag;
+  me_dst->flag = me_src->flag;
+  me_dst->smoothresh = me_src->smoothresh;
+  me_dst->remesh_voxel_size = me_src->remesh_voxel_size;
+  me_dst->remesh_mode = me_src->remesh_mode;
+
+  /* Copy texture space. */
+  me_dst->texflag = me_src->texflag;
+  copy_v3_v3(me_dst->loc, me_src->loc);
+  copy_v3_v3(me_dst->size, me_src->size);
+
+  /* Copy materials. */
+  if (me_dst->mat != NULL) {
+    MEM_freeN(me_dst->mat);
+  }
+  me_dst->mat = MEM_dupallocN(me_src->mat);
+  me_dst->totcol = me_src->totcol;
+}
+
 Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
                                            int verts_len,
                                            int edges_len,
@@ -670,7 +694,6 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
 
   Mesh *me_dst = BKE_id_new_nomain(ID_ME, NULL);
 
-  me_dst->mat = MEM_dupallocN(me_src->mat);
   me_dst->mselect = MEM_dupallocN(me_dst->mselect);
 
   me_dst->totvert = verts_len;
@@ -680,8 +703,7 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
   me_dst->totpoly = polys_len;
 
   me_dst->cd_flag = me_src->cd_flag;
-  me_dst->editflag = me_src->editflag;
-  me_dst->texflag = me_src->texflag;
+  BKE_mesh_copy_settings(me_dst, me_src);
 
   CustomData_copy(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_CALLOC, verts_len);
   CustomData_copy(&me_src->edata, &me_dst->edata, mask.emask, CD_CALLOC, edges_len);
@@ -770,18 +792,24 @@ BMesh *BKE_mesh_to_bmesh(Mesh *me,
                               });
 }
 
-Mesh *BKE_mesh_from_bmesh_nomain(BMesh *bm, const struct BMeshToMeshParams *params)
+Mesh *BKE_mesh_from_bmesh_nomain(BMesh *bm,
+                                 const struct BMeshToMeshParams *params,
+                                 const Mesh *me_settings)
 {
   BLI_assert(params->calc_object_remap == false);
   Mesh *mesh = BKE_id_new_nomain(ID_ME, NULL);
   BM_mesh_bm_to_me(NULL, bm, mesh, params);
+  BKE_mesh_copy_settings(mesh, me_settings);
   return mesh;
 }
 
-Mesh *BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra)
+Mesh *BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm,
+                                          const CustomData_MeshMasks *cd_mask_extra,
+                                          const Mesh *me_settings)
 {
   Mesh *mesh = BKE_id_new_nomain(ID_ME, NULL);
   BM_mesh_bm_to_me_for_eval(bm, mesh, cd_mask_extra);
+  BKE_mesh_copy_settings(mesh, me_settings);
   return mesh;
 }
 
@@ -790,9 +818,10 @@ Mesh *BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks
  */
 Mesh *BKE_mesh_from_editmesh_with_coords_thin_wrap(BMEditMesh *em,
                                                    const CustomData_MeshMasks *data_mask,
-                                                   float (*vertexCos)[3])
+                                                   float (*vertexCos)[3],
+                                                   const Mesh *me_settings)
 {
-  Mesh *me = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, data_mask);
+  Mesh *me = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, data_mask, me_settings);
   /* Use editmesh directly where possible. */
   me->runtime.is_original = true;
   if (vertexCos) {
@@ -1916,9 +1945,6 @@ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)
 {
   DEG_debug_print_eval(depsgraph, __func__, mesh->id.name, mesh);
   BKE_mesh_texspace_calc(mesh);
-  /* Clear autospace flag in evaluated mesh, so that texspace does not get recomputed when bbox is
-   * (e.g. after modifiers, etc.) */
-  mesh->texflag &= ~ME_AUTOSPACE;
   /* We are here because something did change in the mesh. This means we can not trust the existing
    * evaluated mesh, and we don't know what parts of the mesh did change. So we simply delete the
    * evaluated mesh and let objects to re-create it with updated settings. */
index 74873db179dde1a6cfe5a90280f6ecbae3e21c9a..e6c414b92da2043b322be15d3956b56cc7234cf5 100644 (file)
@@ -3352,14 +3352,16 @@ struct Mesh *smokeModifier_do(
   if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain &&
       smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN && smd->domain->base_res[0]) {
     result = createDomainGeometry(smd->domain, ob);
+    BKE_mesh_copy_settings(result, me);
   }
   else {
     result = BKE_mesh_copy_for_eval(me, false);
   }
-  /* XXX This is really not a nice hack, but until root of the problem is understood,
-   * this should be an acceptable workaround I think.
-   * See T58492 for details on the issue. */
-  result->texflag |= ME_AUTOSPACE;
+
+  /* Smoke simulation needs a texture space relative to the adaptive domain bounds, not the
+   * original mesh. So recompute it at this point in the modifier stack. See T58492. */
+  BKE_mesh_texspace_calc(result);
+
   return result;
 }
 
index 6d51e1d3393edeaac4f53e7be2ac6be4d273f80d..d066e9ecddc8d1842d94377637bb53f1325f8efc 100644 (file)
@@ -179,7 +179,8 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op)
   new_mesh = BKE_mesh_from_bmesh_nomain(bm,
                                         (&(struct BMeshToMeshParams){
                                             .calc_object_remap = false,
-                                        }));
+                                        }),
+                                        mesh);
 
   BM_mesh_free(bm);
 
index a05b7023392ee828f9d8bd9ad53450ef41f5e282..0c00bb572be217ca0f5236fd1864727395ad988d 100644 (file)
@@ -212,7 +212,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
                 spread,
                 mesh->smoothresh);
 
-  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
 
   /* Make sure we never alloc'd these. */
   BLI_assert(bm->vtoolflagpool == NULL && bm->etoolflagpool == NULL && bm->ftoolflagpool == NULL);
index e55eeddbfa5109ed6dce73927ebba0d0d1dcdb7e..9868395c0e8599309be6e053677699fce823fa05 100644 (file)
@@ -316,7 +316,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
         MEM_freeN(looptris);
       }
 
-      result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+      result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
 
       BM_mesh_free(bm);
 
index e0764241f184fdc2c7cf189eecee8368c6a183aa..c113a2767a05d331752b581a87f25e59933652f0 100644 (file)
@@ -199,7 +199,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
 
   updateFaceCount(ctx, dmd, bm->totface);
 
-  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
   /* make sure we never alloc'd these */
   BLI_assert(bm->vtoolflagpool == NULL && bm->etoolflagpool == NULL && bm->ftoolflagpool == NULL);
   BLI_assert(bm->vtable == NULL && bm->etable == NULL && bm->ftable == NULL);
index 59d560b9a4a530a962b6dd19a39ce9c13c9b57aa..69ba4aa27950c91228e4d77bd6ccf1f91c8fdd46 100644 (file)
@@ -97,7 +97,7 @@ static Mesh *doEdgeSplit(Mesh *mesh, EdgeSplitModifierData *emd)
 
   /* BM_mesh_validate(bm); */ /* for troubleshooting */
 
-  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
   BM_mesh_free(bm);
 
   result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
index 587aa108fd1d194db4c03af315465d9ff66d00c1..748bf4db4e26187a536ec5406965bd7844625794 100644 (file)
@@ -513,6 +513,12 @@ static Mesh *fluidsim_read_cache(
     return NULL;
   }
 
+  BKE_mesh_copy_settings(newmesh, orgmesh);
+
+  /* Fluid simulation has a texture space that based on the bounds of the fluid mesh.
+   * This does not seem particularly useful, but it's backwards compatible. */
+  BKE_mesh_texspace_calc(newmesh);
+
   /* load vertex velocities, if they exist...
    * TODO? use generate flag as loading flag as well?
    * warning, needs original .bobj.gz mesh loading filename */
index 21ec3505dc932a65514574cb2af31c028e49f576..c91f5d41c5e08ad0f0046c74e3ced5a2a075d5da 100644 (file)
@@ -118,7 +118,7 @@ static Mesh *doBiscetOnMirrorPlane(MirrorModifierData *mmd,
     }
   }
 
-  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
   BM_mesh_free(bm);
 
   return result;
index aff5b8b071b5924d10b394163be7faa09714ace7..97be42367d4242eb3faf1b650c70377a5eff3938 100644 (file)
@@ -268,7 +268,7 @@ static void generate_ocean_geometry_uvs(void *__restrict userdata,
   }
 }
 
-static Mesh *generate_ocean_geometry(OceanModifierData *omd)
+static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig)
 {
   Mesh *result;
 
@@ -296,6 +296,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd)
   gogd.sy /= gogd.ry;
 
   result = BKE_mesh_new_nomain(num_verts, 0, 0, num_polys * 4, num_polys);
+  BKE_mesh_copy_settings(result, mesh_orig);
 
   gogd.mverts = result->mvert;
   gogd.mpolys = result->mpoly;
@@ -377,7 +378,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
   }
 
   if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) {
-    result = generate_ocean_geometry(omd);
+    result = generate_ocean_geometry(omd, mesh);
     BKE_mesh_ensure_normals(result);
   }
   else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
index a7c7c207cd61c0ea7ef6c4eda93a781f307be0da..67a64921bbcaee8a97bb59cbe68ec29d1af6273d 100644 (file)
@@ -168,7 +168,7 @@ static void deformVerts(ModifierData *md,
 
       if (em) {
         /* In edit mode get directly from the edit mesh. */
-        psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
+        psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL, mesh);
       }
       else {
         /* Otherwise get regular mesh. */
index 631401d9d9e3a19af2590299d4cb0f91d34a4fe6..df84f3db55c4d196375908526b9d7086ba220ed4 100644 (file)
@@ -185,6 +185,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(c
     }
   }
 
+  BKE_mesh_copy_settings(result, mesh);
   BKE_mesh_calc_edges(result, true, false);
   result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
   return result;
index 6ba834c69348520a76d86c7b98ef9f832f6dabff..6e7a0b0dbaeddee15e5291fb5c527a87f2015bbb 100644 (file)
@@ -1871,7 +1871,7 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd)
     return NULL;
   }
 
-  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, origmesh);
   BM_mesh_free(bm);
 
   result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
index 1582c27960ea17d25217db5f797005ec6fed2b6c..7fba7e864ae16eb2bf2ef724c21a76996eb0f31f 100644 (file)
@@ -65,7 +65,7 @@ static Mesh *triangulate_mesh(Mesh *mesh,
 
   BM_mesh_triangulate(bm, quad_method, ngon_method, min_vertices, false, NULL, NULL, NULL);
 
-  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cddata_masks);
+  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cddata_masks, mesh);
   BM_mesh_free(bm);
 
   if (keep_clnors) {
index 36e712a1958f9f2c04c152fdc01f43dd407447f2..1e3c747022cd373343766e0a693ee4188a797652 100644 (file)
@@ -182,7 +182,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
   }
   else if (ob->type == OB_MESH) {
     if (em) {
-      mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
+      mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL, ob->data);
     }
     else {
       /* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
index 7af9ef6f5b61ed1d137dbf53bd837ab5d39a18c6..3dd6e00c3a5593ff1513f11fa290a048b1ce1e6f 100644 (file)
@@ -91,7 +91,7 @@ static Mesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, Mesh *
                     MAX2(ob->totcol - 1, 0),
                     false);
 
-  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+  result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
   BM_mesh_free(bm);
 
   result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;