Commit: e142387b2fb3ec1f6a01b043dbc421abef2e5584
Author: Hans Goudey
Date: Thu Jul 7 17:09:47 2022 -0500
Branches: temp-deform-curves-on-surface
https://developer.blender.org/rBe142387b2fb3ec1f6a01b043dbc421abef2e5584
Threadsafe access to face corner normals
===================================================================
M source/blender/blenkernel/BKE_mesh.h
M source/blender/blenkernel/intern/mesh.cc
M
source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_mesh.h
b/source/blender/blenkernel/BKE_mesh.h
index 66e0ff8e81a..847fb05fb92 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -710,7 +710,8 @@ void BKE_mesh_calc_normals_split(struct Mesh *mesh);
* to split geometry along sharp edges.
*/
void BKE_mesh_calc_normals_split_ex(struct Mesh *mesh,
- struct MLoopNorSpaceArray
*r_lnors_spacearr);
+ struct MLoopNorSpaceArray
*r_lnors_spacearr,
+ float (*r_corner_normals)[3]);
/**
* Higher level functions hiding most of the code needed around call to
diff --git a/source/blender/blenkernel/intern/mesh.cc
b/source/blender/blenkernel/intern/mesh.cc
index ffbd824712a..9d02ae2d0fa 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -1922,9 +1922,25 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh,
BKE_mesh_tag_coords_changed(mesh);
}
-void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray
*r_lnors_spacearr)
+static float (*ensure_corner_normal_layer(Mesh &mesh))[3]
{
float(*r_loopnors)[3];
+ if (CustomData_has_layer(&mesh.ldata, CD_NORMAL)) {
+ r_loopnors = (float(*)[3])CustomData_get_layer(&mesh.ldata, CD_NORMAL);
+ memset(r_loopnors, 0, sizeof(float[3]) * mesh.totloop);
+ }
+ else {
+ r_loopnors = (float(*)[3])CustomData_add_layer(
+ &mesh.ldata, CD_NORMAL, CD_CALLOC, nullptr, mesh.totloop);
+ CustomData_set_layer_flag(&mesh.ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+ return r_loopnors;
+}
+
+void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
+ MLoopNorSpaceArray *r_lnors_spacearr,
+ float (*r_corner_normals)[3])
+{
short(*clnors)[2] = nullptr;
/* Note that we enforce computing clnors when the clnor space array is
requested by caller here.
@@ -1934,16 +1950,6 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
MLoopNorSpaceArray *r_lnors_spac
((mesh->flag & ME_AUTOSMOOTH) != 0);
const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ?
mesh->smoothresh : (float)M_PI;
- if (CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
- r_loopnors = (float(*)[3])CustomData_get_layer(&mesh->ldata, CD_NORMAL);
- memset(r_loopnors, 0, sizeof(float[3]) * mesh->totloop);
- }
- else {
- r_loopnors = (float(*)[3])CustomData_add_layer(
- &mesh->ldata, CD_NORMAL, CD_CALLOC, nullptr, mesh->totloop);
- CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
- }
-
/* may be nullptr */
clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata,
CD_CUSTOMLOOPNORMAL);
@@ -1953,7 +1959,7 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
MLoopNorSpaceArray *r_lnors_spac
mesh->medge,
mesh->totedge,
mesh->mloop,
- r_loopnors,
+ r_corner_normals,
mesh->totloop,
mesh->mpoly,
BKE_mesh_poly_normals_ensure(mesh),
@@ -1969,7 +1975,7 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
MLoopNorSpaceArray *r_lnors_spac
void BKE_mesh_calc_normals_split(Mesh *mesh)
{
- BKE_mesh_calc_normals_split_ex(mesh, nullptr);
+ BKE_mesh_calc_normals_split_ex(mesh, nullptr,
ensure_corner_normal_layer(*mesh));
}
/* Split faces helper functions. */
@@ -2188,7 +2194,8 @@ void BKE_mesh_split_faces(Mesh *mesh, bool
free_loop_normals)
MLoopNorSpaceArray lnors_spacearr = {nullptr};
/* Compute loop normals and loop normal spaces (a.k.a. smooth fans of faces
around vertices). */
- BKE_mesh_calc_normals_split_ex(mesh, &lnors_spacearr);
+
+ BKE_mesh_calc_normals_split_ex(mesh, &lnors_spacearr,
ensure_corner_normal_layer(*mesh));
/* Stealing memarena from loop normals space array. */
MemArena *memarena = lnors_spacearr.mem;
diff --git
a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc
b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc
index 00866bca48f..7557023aef7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc
@@ -266,19 +266,16 @@ static void node_geo_exec(GeoNodeExecParams params)
const ReverseUVSampler reverse_uv_sampler_orig{uv_map_orig, looptris_orig};
const ReverseUVSampler reverse_uv_sampler_eval{uv_map_eval, looptris_eval};
- /* TODO: Figure out how to get this data in a thread-safe way. */
- if (!CustomData_has_layer(&surface_mesh_orig.ldata, CD_NORMAL)) {
- BKE_mesh_calc_normals_split(&surface_mesh_orig);
- }
- if (!CustomData_has_layer(&surface_mesh_eval->ldata, CD_NORMAL)) {
- BKE_mesh_calc_normals_split(surface_mesh_eval);
- }
- const Span<float3> corner_normals_orig = {
- reinterpret_cast<const float3
*>(CustomData_get_layer(&surface_mesh_orig.ldata, CD_NORMAL)),
- surface_mesh_orig.totloop};
- const Span<float3> corner_normals_eval = {
- reinterpret_cast<const float3
*>(CustomData_get_layer(&surface_mesh_eval->ldata, CD_NORMAL)),
- surface_mesh_eval->totloop};
+ /* Retrieve face corner normals from each mesh. It's necessary to use face
corner normals
+ * because face normals or vertex normals may lose information (custom
normals, auto smooth) in
+ * some cases. It isn't yet possible to retrieve lazily calculated face
corner normals from a
+ * const mesh, so they are calculated here every time. */
+ Array<float3> corner_normals_orig(surface_mesh_orig.totloop);
+ Array<float3> corner_normals_eval(surface_mesh_eval->totloop);
+ BKE_mesh_calc_normals_split_ex(
+ &surface_mesh_orig, nullptr,
reinterpret_cast<float(*)[3]>(corner_normals_orig.data()));
+ BKE_mesh_calc_normals_split_ex(
+ surface_mesh_eval, nullptr,
reinterpret_cast<float(*)[3]>(corner_normals_eval.data()));
std::atomic<int> invalid_uv_count = 0;
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs