From 40642343b692ec63e0ddf740148f2c8460f93c75 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 19 May 2025 11:50:00 +0200 Subject: [PATCH] Fix #138978: Modifier cage option not working when GPU subdivision is off Need an equivalent of DRW_object_get_data_for_drawing for the cage mesh, to ensure proper comparison between meshes. Pull Request: https://projects.blender.org/blender/blender/pulls/138987 --- source/blender/blenkernel/BKE_mesh_wrapper.hh | 1 + source/blender/blenkernel/intern/mesh_wrapper.cc | 7 +++++++ source/blender/draw/intern/DRW_render.hh | 6 ++++++ .../intern/draw_cache_extract_mesh_render_data.cc | 4 +++- .../blender/draw/intern/draw_cache_impl_mesh.cc | 2 +- source/blender/draw/intern/draw_context.cc | 15 +++++++++++++++ 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_wrapper.hh b/source/blender/blenkernel/BKE_mesh_wrapper.hh index eefa751bf25..23e6fde94c7 100644 --- a/source/blender/blenkernel/BKE_mesh_wrapper.hh +++ b/source/blender/blenkernel/BKE_mesh_wrapper.hh @@ -48,3 +48,4 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *mesh, const float mat[4][4]); Mesh *BKE_mesh_wrapper_ensure_subdivision(Mesh *mesh); +const Mesh *BKE_mesh_wrapper_ensure_subdivision(const Mesh *mesh); diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 73dedc3a6f3..b9a4ba45907 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -395,4 +395,11 @@ Mesh *BKE_mesh_wrapper_ensure_subdivision(Mesh *mesh) return result; } +const Mesh *BKE_mesh_wrapper_ensure_subdivision(const Mesh *mesh) +{ + /* This modifies the mesh, but it's lazy initialization protected by mutex lock + * so still read-only access in a sense. */ + return BKE_mesh_wrapper_ensure_subdivision(const_cast(mesh)); +} + /** \} */ diff --git a/source/blender/draw/intern/DRW_render.hh b/source/blender/draw/intern/DRW_render.hh index 0c78ab40375..730e9facac4 100644 --- a/source/blender/draw/intern/DRW_render.hh +++ b/source/blender/draw/intern/DRW_render.hh @@ -217,6 +217,12 @@ template T &DRW_object_get_data_for_drawing(const Object &object) template<> Mesh &DRW_object_get_data_for_drawing(const Object &object); +/** + * Same as DRW_object_get_data_for_drawing, but for the editmesh cage, + * if it exists. + */ +const Mesh *DRW_object_get_editmesh_cage_for_drawing(const Object &object); + /* Draw State. */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index a5267475526..18877bfd202 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -24,6 +24,8 @@ #include "ED_mesh.hh" +#include "DRW_render.hh" + #include "mesh_extractors/extract_mesh.hh" /* ---------------------------------------------------------------------- */ @@ -555,7 +557,7 @@ MeshRenderData mesh_render_data_create(Object &object, const Mesh *editmesh_orig = BKE_object_get_pre_modified_mesh(&object); if (is_editmode && editmesh_orig && editmesh_orig->runtime->edit_mesh) { - const Mesh *eval_cage = BKE_object_get_editmesh_eval_cage(&object); + const Mesh *eval_cage = DRW_object_get_editmesh_cage_for_drawing(object); mr.bm = editmesh_orig->runtime->edit_mesh->bm; mr.edit_bmesh = editmesh_orig->runtime->edit_mesh.get(); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index 7d983c16667..140a5cfa258 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -1262,7 +1262,7 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, bool do_cage = false; const Mesh *edit_data_mesh = nullptr; if (is_editmode) { - const Mesh *eval_cage = BKE_object_get_editmesh_eval_cage(&ob); + const Mesh *eval_cage = DRW_object_get_editmesh_cage_for_drawing(ob); if (eval_cage && eval_cage != &mesh) { /* Extract "cage" data separately when it exists and it's not just the same mesh as the * regular evaluated mesh. Otherwise edit data will be extracted from the final evaluated diff --git a/source/blender/draw/intern/draw_context.cc b/source/blender/draw/intern/draw_context.cc index 7050d4dfe13..51b16eb8b84 100644 --- a/source/blender/draw/intern/draw_context.cc +++ b/source/blender/draw/intern/draw_context.cc @@ -382,6 +382,21 @@ template<> Mesh &DRW_object_get_data_for_drawing(const Object &object) return *BKE_mesh_wrapper_ensure_subdivision(&mesh); } +const Mesh *DRW_object_get_editmesh_cage_for_drawing(const Object &object) +{ + /* Same as DRW_object_get_data_for_drawing, but for the cage mesh. */ + BLI_assert(object.type == OB_MESH); + const Mesh *cage_mesh = BKE_object_get_editmesh_eval_cage(&object); + if (cage_mesh == nullptr) { + return nullptr; + } + + if (BKE_subsurf_modifier_has_gpu_subdiv(cage_mesh)) { + return cage_mesh; + } + return BKE_mesh_wrapper_ensure_subdivision(cage_mesh); +} + /** \} */ /* -------------------------------------------------------------------- */