From 001a2b3f4df52f4dcd36a3550907cfb45aca8185 Mon Sep 17 00:00:00 2001 From: "Jason C. Wenger" Date: Sat, 16 Aug 2025 09:02:41 -0500 Subject: [PATCH] Fix #144383: Limited dissolve creates duplicate faces Use of BM_faces_join_pair can result in an invalid mesh with doubled faces. [0] added an assert to identify when this could occur. This case has been inspected, and allowing the auto-join logic in BM_faces_join_pair() to delete the doubled face does not negatively impact iteration or processing: 1. The eheap and eheap_table used here deal only with edges, not faces. 2. Loop iteration is unchanged. A conversion to use of BM_ITER_MESH_MUTABLE is not applicable because the iteration is done on the edge heap, not the mesh. 3. The recomputation of the face normals of each combined face still works properly. Ref !144653 [0]: 702efd6846790cd820e7ef20b81500eb21d902cd --- source/blender/bmesh/tools/bmesh_decimate_dissolve.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.cc b/source/blender/bmesh/tools/bmesh_decimate_dissolve.cc index 49de18607de..1991bdc88fb 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.cc +++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.cc @@ -348,11 +348,11 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, i = BM_elem_index_get(e); if (BM_edge_is_manifold(e)) { - BMFace *f_double; - f_new = BM_faces_join_pair(bm, e->l, e->l->radial_next, false, &f_double); - /* See #BM_faces_join note on callers asserting when `r_double` is non-null. */ - BLI_assert_msg(f_double == nullptr, - "Doubled face detected at " AT ". Resulting mesh may be corrupt."); + /* The `f_new` may be an existing face, see #144383. + * In this case it's still flagged as output so the selection + * isn't "lost" when dissolving, see: !144653. */ + f_new = BM_faces_join_pair(bm, e->l, e->l->radial_next, false, nullptr); + if (f_new) { BMLoop *l_first, *l_iter;