diff options
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.cc | 19 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_wrapper.cc | 19 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_mesh_types.h | 4 |
3 files changed, 37 insertions, 5 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); } diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 1f8ff182510..0d57afe4225 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -126,7 +126,9 @@ typedef struct Mesh_Runtime { * set in the modifier when GPU subdivision can be performed. */ SessionUUID subsurf_session_uuid; - int subsurf_resolution; + char subsurf_resolution; + char subsurf_do_loop_normals; + char _pad3[2]; char subsurf_apply_render; char subsurf_use_optimal_display; |