[Bf-blender-cvs] [d3bf08f924e] temp-vert-normals-cleanup: Fix: Failing mesh line test

Hans Goudey noreply at git.blender.org
Fri Nov 5 05:34:07 CET 2021


Commit: d3bf08f924ec5689ab425094fa192fb656e74bab
Author: Hans Goudey
Date:   Thu Nov 4 23:34:00 2021 -0500
Branches: temp-vert-normals-cleanup
https://developer.blender.org/rBd3bf08f924ec5689ab425094fa192fb656e74bab

Fix: Failing mesh line test

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

M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/blenkernel/intern/mesh_normals.cc
M	source/blender/blenkernel/intern/mesh_validate.c

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

diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 4b7ad4f3fa4..a0378554259 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -283,6 +283,7 @@ void BKE_mesh_calc_normals_poly(const struct MVert *mvert,
                                 int mpoly_len,
                                 float (*r_poly_normals)[3]);
 void BKE_mesh_calc_normals(struct Mesh *me);
+void BKE_mesh_assert_normals_dirty_or_calculated(const struct Mesh *mesh);
 float (*BKE_mesh_vertex_normals_for_write(struct Mesh *mesh))[3];
 float (*BKE_mesh_face_normals_for_write(struct Mesh *mesh))[3];
 const float (*BKE_mesh_ensure_vertex_normals(const struct Mesh *mesh))[3];
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index 52d1af64d20..ae56841589a 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -796,26 +796,6 @@ static void add_orco_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orc
   }
 }
 
-static void assert_normals_dirty_or_calculated(const Mesh &mesh)
-{
-  if (!(mesh.runtime.cd_dirty_vert & CD_MASK_NORMAL)) {
-    if (!CustomData_has_layer(&mesh.vdata, CD_NORMAL)) {
-      Mesh *me = const_cast<Mesh *>(&mesh);
-      MEM_freeN(me);
-      MEM_freeN(me);
-    }
-    BLI_assert(CustomData_has_layer(&mesh.vdata, CD_NORMAL));
-  }
-  if (!(mesh.runtime.cd_dirty_poly & CD_MASK_NORMAL)) {
-    if (!CustomData_has_layer(&mesh.pdata, CD_NORMAL)) {
-      Mesh *me = const_cast<Mesh *>(&mesh);
-      MEM_freeN(me);
-      MEM_freeN(me);
-    }
-    BLI_assert(CustomData_has_layer(&mesh.vdata, CD_NORMAL));
-  }
-}
-
 static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
                                              const CustomData_MeshMasks *final_datamask,
                                              const bool sculpt_dyntopo,
@@ -950,7 +930,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
    * constructive modifier is executed, or a deform modifier needs normals
    * or certain data layers. */
   Mesh *mesh_input = (Mesh *)ob->data;
-  assert_normals_dirty_or_calculated(*mesh_input);
+  BKE_mesh_assert_normals_dirty_or_calculated(mesh_input);
   Mesh *mesh_final = nullptr;
   Mesh *mesh_deform = nullptr;
   /* This geometry set contains the non-mesh data that might be generated by modifiers. */
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 5836c63d272..d25c4e0e1cc 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -162,6 +162,8 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
     /* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */
     mesh_dst->key->from = &mesh_dst->id;
   }
+
+  BKE_mesh_assert_normals_dirty_or_calculated(mesh_dst);
 }
 
 static void mesh_free_data(ID *id)
@@ -331,6 +333,15 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
       BLI_endian_switch_uint32_array(tf->col, 4);
     }
   }
+
+  /* TODO: Decide whether to store normal layers in files. If we decide not to,
+   * we should always tag normals dirty when reading mesh data. */
+  if (!CustomData_has_layer(&mesh->vdata, CD_NORMAL) ||
+      !CustomData_has_layer(&mesh->pdata, CD_NORMAL)) {
+    BKE_mesh_normals_tag_dirty(mesh);
+  }
+
+  BKE_mesh_assert_normals_dirty_or_calculated(mesh);
 }
 
 static void mesh_blend_read_lib(BlendLibReader *reader, ID *id)
@@ -1046,6 +1057,8 @@ void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
 
   BKE_mesh_copy_parameters(me_dst, me_src);
 
+  BKE_mesh_assert_normals_dirty_or_calculated(me_dst);
+
   /* Copy vertex group names. */
   BLI_assert(BLI_listbase_is_empty(&me_dst->vertex_group_names));
   BKE_defgroup_copy_list(&me_dst->vertex_group_names, &me_src->vertex_group_names);
diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc
index b6ea02f8d12..08e1b985038 100644
--- a/source/blender/blenkernel/intern/mesh_normals.cc
+++ b/source/blender/blenkernel/intern/mesh_normals.cc
@@ -376,6 +376,30 @@ void BKE_mesh_calc_normals(Mesh *mesh)
 #endif
 }
 
+void BKE_mesh_assert_normals_dirty_or_calculated(const Mesh *mesh)
+{
+  if (!(mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL)) {
+    /* Meshes with non-dirty normals should always have a normal custom data layer. */
+    if (!CustomData_has_layer(&mesh->vdata, CD_NORMAL)) {
+      Mesh *me = const_cast<Mesh *>(mesh);
+      MEM_freeN(me);
+      /* Cause a use after free, to quickly tell where the offending mesh was allocated. */
+      MEM_freeN(me);
+    }
+    BLI_assert(CustomData_has_layer(&mesh->vdata, CD_NORMAL));
+  }
+  if (!(mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL)) {
+    /* Meshes with non-dirty normals should always have a normal custom data layer. */
+    if (!CustomData_has_layer(&mesh->pdata, CD_NORMAL)) {
+      Mesh *me = const_cast<Mesh *>(mesh);
+      MEM_freeN(me);
+      /* Cause a use after free, to quickly tell where the offending mesh was allocated. */
+      MEM_freeN(me);
+    }
+    BLI_assert(CustomData_has_layer(&mesh->vdata, CD_NORMAL));
+  }
+}
+
 void BKE_mesh_calc_normals_looptri(MVert *mverts,
                                    int numVerts,
                                    const MLoop *mloop,
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 029e0a92c09..aeaaff8cc48 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -1130,6 +1130,8 @@ bool BKE_mesh_is_valid(Mesh *me)
   bool is_valid = true;
   bool changed = true;
 
+  BKE_mesh_assert_normals_dirty_or_calculated(me);
+
   is_valid &= BKE_mesh_validate_all_customdata(
       &me->vdata,
       me->totvert,



More information about the Bf-blender-cvs mailing list