[Bf-blender-cvs] [048d512b915] temp-vert-normals-cleanup: Improve usage of the "for_write" functions, add a separate function to clear dirty flags

Hans Goudey noreply at git.blender.org
Wed Dec 29 21:45:39 CET 2021


Commit: 048d512b9153cd8ef314b3c66ab1af4fb41e2997
Author: Hans Goudey
Date:   Wed Dec 29 13:48:31 2021 -0600
Branches: temp-vert-normals-cleanup
https://developer.blender.org/rB048d512b9153cd8ef314b3c66ab1af4fb41e2997

Improve usage of the "for_write" functions, add a separate function to clear dirty flags

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

M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/intern/fluid.c
M	source/blender/blenkernel/intern/mesh.cc
M	source/blender/blenkernel/intern/mesh_normals.cc
M	source/blender/blenkernel/intern/subdiv_mesh.c
M	source/blender/bmesh/intern/bmesh_mesh_convert.c
M	source/blender/editors/mesh/mesh_data.c
M	source/blender/io/alembic/intern/abc_customdata.h
M	source/blender/io/alembic/intern/abc_reader_mesh.cc
M	source/blender/io/alembic/intern/abc_reader_mesh.h
M	source/blender/io/alembic/intern/abc_reader_points.cc
M	source/blender/io/usd/intern/usd_reader_mesh.cc
M	source/blender/modifiers/intern/MOD_array.c
M	source/blender/modifiers/intern/MOD_normal_edit.c
M	source/blender/modifiers/intern/MOD_screw.c
M	source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc

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

diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index c8f5c1fc1ed..199beb3eef2 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -381,6 +381,41 @@ void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop,
  */
 void BKE_mesh_normals_tag_dirty(struct Mesh *mesh);
 
+/**
+ * Check that a mesh with non-dirty normals has vertex and face custom data layers.
+ */
+void BKE_mesh_assert_normals_dirty_or_calculated(const struct Mesh *mesh);
+
+/**
+ * Retrieve write access to the vertex normal layer, ensuring that it exists and that it is not
+ * shared. The provided vertex normals should be the same as if they were calculated automatically.
+ *
+ * \note In order to clear the dirty flag, this function should be followed by a call to
+ * #BKE_mesh_vertex_normals_clear_dirty. This is separate so that normals are still tagged dirty
+ * while they are being assigned.
+ */
+float (*BKE_mesh_vertex_normals_for_write(struct Mesh *mesh))[3];
+
+/**
+ * Retrieve write access to the poly normal layer, ensuring that it exists and that it is not
+ * shared. The provided poly normals should be the same as if they were calculated automatically.
+ *
+ * \note In order to clear the dirty flag, this function should be followed by a call to
+ * #BKE_mesh_poly_normals_clear_dirty. This is separate so that normals are still tagged dirty
+ * while they are being assigned.
+ */
+float (*BKE_mesh_poly_normals_for_write(struct Mesh *mesh))[3];
+
+/**
+ * Mark the mesh's vertex normals non-dirty, for when they are calculated or assigned manually.
+ */
+void BKE_mesh_vertex_normals_clear_dirty(struct Mesh *mesh);
+
+/**
+ * Mark the mesh's poly normals non-dirty, for when they are calculated or assigned manually.
+ */
+void BKE_mesh_poly_normals_clear_dirty(struct Mesh *mesh);
+
 /**
  * Calculate face normals directly into a result array.
  *
@@ -405,29 +440,16 @@ void BKE_mesh_calc_normals_poly(const struct MVert *mvert,
 void BKE_mesh_calc_normals(struct Mesh *me);
 
 /**
- * Check that a mesh with non-dirty normals has vertex and face custom data layers.
- */
-void BKE_mesh_assert_normals_dirty_or_calculated(const struct Mesh *mesh);
-
-/**
- * Make sure the vertex normal data layer exists and return it.
- * Used for manually assigning vertex normals. Clears the dirty flag.
- */
-float (*BKE_mesh_vertex_normals_for_write(struct Mesh *mesh))[3];
-
-/**
- * Make sure the face normal data layer exists and return it.
- * Used for manually assigning face normals. Clears the dirty flag.
- */
-float (*BKE_mesh_poly_normals_for_write(struct Mesh *mesh))[3];
-
-/**
+ * Returns the normals for each vertex, which is defined as the weighted average of the normals
+ * from a vertices surrounding faces, or the normalized position of vertices connected to no faces.
  * \warning May still return null if the mesh is empty.
  */
 const float (*BKE_mesh_vertex_normals_ensure(const struct Mesh *mesh))[3];
 
 /**
- * \warning May still return null if the mesh is empty.
+ * Return the normal direction of every polygon, which is defined by the winding direction of its
+ * corners.
+ * \warning May still return null if the mesh is empty or has no polygons.
  */
 const float (*BKE_mesh_poly_normals_ensure(const struct Mesh *mesh))[3];
 
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 143ce14e3bc..0c9e352da12 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -1052,7 +1052,8 @@ static void obstacles_from_mesh(Object *coll_ob,
       }
     }
 
-    /* Transform mesh vertices to domain grid space for fast lookups */
+    /* Transform mesh vertices to domain grid space for fast lookups.
+     * This is valid because the mesh is copied above. */
     BKE_mesh_vertex_normals_ensure(me);
     float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me);
     for (i = 0; i < numverts; i++) {
@@ -2138,7 +2139,8 @@ static void emit_from_mesh(
       }
     }
 
-    /* Transform mesh vertices to domain grid space for fast lookups */
+    /* Transform mesh vertices to domain grid space for fast lookups.
+     * This is valid because the mesh is copied above. */
     BKE_mesh_vertex_normals_ensure(me);
     float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me);
     for (i = 0; i < numverts; i++) {
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index b85b9f9b8f3..633fb4f21f5 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -2147,6 +2147,7 @@ static void split_faces_split_new_verts(Mesh *mesh,
       copy_v3_v3(vert_normals[i], new_verts->vnor);
     }
   }
+  BKE_mesh_vertex_normals_clear_dirty(mesh);
 }
 
 /* Perform actual split of edges. */
diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc
index 353fec38292..f840e404a61 100644
--- a/source/blender/blenkernel/intern/mesh_normals.cc
+++ b/source/blender/blenkernel/intern/mesh_normals.cc
@@ -122,18 +122,40 @@ void BKE_mesh_normals_tag_dirty(Mesh *mesh)
 
 float (*BKE_mesh_vertex_normals_for_write(Mesh *mesh))[3]
 {
-  mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
+  CustomData_duplicate_referenced_layer(&mesh->vdata, CD_NORMAL, mesh->totvert);
   return (float(*)[3])CustomData_add_layer(
       &mesh->vdata, CD_NORMAL, CD_CALLOC, nullptr, mesh->totvert);
 }
 
 float (*BKE_mesh_poly_normals_for_write(Mesh *mesh))[3]
 {
-  mesh->runtime.cd_dirty_poly &= ~CD_MASK_NORMAL;
+  CustomData_duplicate_referenced_layer(&mesh->pdata, CD_NORMAL, mesh->totpoly);
   return (float(*)[3])CustomData_add_layer(
       &mesh->pdata, CD_NORMAL, CD_CALLOC, nullptr, mesh->totpoly);
 }
 
+void BKE_mesh_vertex_normals_clear_dirty(Mesh *mesh)
+{
+  mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
+  BKE_mesh_assert_normals_dirty_or_calculated(mesh);
+}
+
+void BKE_mesh_poly_normals_clear_dirty(Mesh *mesh)
+{
+  mesh->runtime.cd_dirty_poly &= ~CD_MASK_NORMAL;
+  BKE_mesh_assert_normals_dirty_or_calculated(mesh);
+}
+
+void BKE_mesh_assert_normals_dirty_or_calculated(const Mesh *mesh)
+{
+  if (!(mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL)) {
+    BLI_assert(CustomData_has_layer(&mesh->vdata, CD_NORMAL) || mesh->totvert == 0);
+  }
+  if (!(mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL)) {
+    BLI_assert(CustomData_has_layer(&mesh->pdata, CD_NORMAL) || mesh->totpoly == 0);
+  }
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -436,16 +458,6 @@ 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)) {
-    BLI_assert(CustomData_has_layer(&mesh->vdata, CD_NORMAL));
-  }
-  if (!(mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL)) {
-    BLI_assert(CustomData_has_layer(&mesh->pdata, CD_NORMAL));
-  }
-}
-
 void BKE_mesh_calc_normals_looptri(MVert *mverts,
                                    int numVerts,
                                    const MLoop *mloop,
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
index 89543e037a0..2e857608369 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -101,9 +101,10 @@ static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
 
 static void subdiv_mesh_prepare_accumulator(SubdivMeshContext *ctx, int num_vertices)
 {
-  /* TODO: Even though #can_evaluated_normals is false, a buffer for the normals is necessary,
-   * since previously the code was evaluating into Mert.no directly. */
+  /* Even though #can_evaluated_normals is false, a buffer for the normals is necessary,
+   * since previously the code was evaluating into #Mert.no directly. */
   ctx->accumulated_normals = BKE_mesh_vertex_normals_for_write(ctx->subdiv_mesh);
+  BKE_mesh_vertex_normals_clear_dirty(ctx->subdiv_mesh);
   /* TODO(sergey): Technically, this is overallocating, we don't need memory
    * for an inner subdivision vertices. */
   memset(ctx->accumulated_normals, 0, sizeof(float[3]) * num_vertices);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.c b/source/blender/bmesh/intern/bmesh_mesh_convert.c
index f7902bedac4..9d0933b0aa5 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.c
@@ -639,8 +639,8 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
   CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
   CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
   CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
-  float(*face_normals)[3] = BKE_mesh_poly_normals_for_write(me);
-  float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me);
+
+  BKE_mesh_normals_tag_dirty(me);
 
   me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
 
@@ -650,7 +650,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
   i = 0;
   BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
     copy_v3_v3(mvert->co, v->co);
-    copy_v3_v3(vert_normals[i], v->no);
 
     mvert->flag = BM_vert_flag_to_mflag(v);
 
@@ -706,7 +705,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
     mpoly->totloop = f->len;
     mpoly->mat_nr = f->mat_nr;
     mpoly->flag = BM_face_flag_to_mflag(f);
-    copy_v3_v3(face_normals[i], f->no);
 
     l_iter = l_first = BM_FACE_FIRST_LOOP(f);
     do {
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 0d3aaf6278c..0f58752f323 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -1026,7 +1026,7 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator
                                        me->mloop,
                                        me->totloop,
                                        me->mpoly,
-                                   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list