[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