Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2022-04-27 15:03:03 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2022-04-27 15:03:03 +0300
commit08731d70bf667a7179a3ea4c29aa9d81b019d4ee (patch)
treec8b166bec21960c43bde5c3530c8a7bea1145dc8 /source/blender/blenkernel
parentc5a4159beeb287a152e998f506a0041613c6f9d3 (diff)
Fix T96327: data transfer crash with GPU subdivision
The crash is caused as the subdivision wrapper does not have loop normals, which are generally computed at the end of the modifier stack evaluation via `mesh_calc_modifier_final_normals`. (Note that they are initially computed, but deleted by the subdivision wrapper creation.) This records in the mesh runtime whether loop normals should have been computed and computes them alongside the subdivision wrapper. Differential Revision: https://developer.blender.org/D14489
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.cc19
-rw-r--r--source/blender/blenkernel/intern/mesh_wrapper.cc19
2 files changed, 34 insertions, 4 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index 8a0ad4b724b..a0ec99b1593 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -628,9 +628,15 @@ static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
const bool do_loop_normals = ((mesh_input->flag & ME_AUTOSMOOTH) != 0 ||
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
+ /* Needed as `final_datamask` is not preserved outside modifier stack evaluation. */
+ mesh_final->runtime.subsurf_do_loop_normals = do_loop_normals;
+
if (do_loop_normals) {
- /* Compute loop normals (NOTE: will compute poly and vert normals as well, if needed!). */
- BKE_mesh_calc_normals_split(mesh_final);
+ /* Compute loop normals (NOTE: will compute poly and vert normals as well, if needed!). In case
+ * of deferred CPU subdivision, this will be computed when the wrapper is generated. */
+ if (mesh_final->runtime.subsurf_resolution != 0) {
+ BKE_mesh_calc_normals_split(mesh_final);
+ }
}
else {
if (sculpt_dyntopo == false) {
@@ -1274,9 +1280,14 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
const bool do_loop_normals = ((mesh_final->flag & ME_AUTOSMOOTH) != 0 ||
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
+ mesh_final->runtime.subsurf_do_loop_normals = do_loop_normals;
+
if (do_loop_normals) {
- /* Compute loop normals */
- BKE_mesh_calc_normals_split(mesh_final);
+ /* Compute loop normals. In case of deferred CPU subdivision, this will be computed when the
+ * wrapper is generated. */
+ if (mesh_final->runtime.subsurf_resolution != 0) {
+ BKE_mesh_calc_normals_split(mesh_final);
+ }
}
else {
/* Same as mesh_calc_modifiers. If using loop normals, poly nors have already been computed. */
diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc
index 8291765c2ef..c505a74724b 100644
--- a/source/blender/blenkernel/intern/mesh_wrapper.cc
+++ b/source/blender/blenkernel/intern/mesh_wrapper.cc
@@ -340,9 +340,28 @@ static Mesh *mesh_wrapper_ensure_subdivision(const Object *ob, Mesh *me)
/* Happens on bad topology, but also on empty input mesh. */
return me;
}
+ const bool use_clnors = BKE_subsurf_modifier_use_custom_loop_normals(smd, me);
+ if (use_clnors) {
+ /* If custom normals are present and the option is turned on calculate the split
+ * normals and clear flag so the normals get interpolated to the result mesh. */
+ BKE_mesh_calc_normals_split(me);
+ CustomData_clear_layer_flag(&me->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
Mesh *subdiv_mesh = BKE_subdiv_to_mesh(subdiv, &mesh_settings, me);
+ if (use_clnors) {
+ float(*lnors)[3] = static_cast<float(*)[3]>(
+ CustomData_get_layer(&subdiv_mesh->ldata, CD_NORMAL));
+ BLI_assert(lnors != NULL);
+ BKE_mesh_set_custom_normals(subdiv_mesh, lnors);
+ CustomData_set_layer_flag(&me->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ CustomData_set_layer_flag(&subdiv_mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+ else if (me->runtime.subsurf_do_loop_normals) {
+ BKE_mesh_calc_normals_split(subdiv_mesh);
+ }
+
if (subdiv != runtime_data->subdiv) {
BKE_subdiv_free(subdiv);
}