diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-04-27 15:03:03 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-04-27 15:03:03 +0300 |
commit | 08731d70bf667a7179a3ea4c29aa9d81b019d4ee (patch) | |
tree | c8b166bec21960c43bde5c3530c8a7bea1145dc8 /source/blender/blenkernel/intern/mesh_wrapper.cc | |
parent | c5a4159beeb287a152e998f506a0041613c6f9d3 (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/intern/mesh_wrapper.cc')
-rw-r--r-- | source/blender/blenkernel/intern/mesh_wrapper.cc | 19 |
1 files changed, 19 insertions, 0 deletions
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); } |