From b50a5250762f204ee5476a05da618b0ff9e3e3ae Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Jul 2025 14:50:23 +1000 Subject: [PATCH] Fix #141336: Modeling: Don't assume gizmo available in polybuild tool Check the polybuild gizmo is drawn before using it, also account for it being empty (the cause of the crash), although this shouldn't happen in practice. --- .../editors/mesh/editmesh_polybuild.cc | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/blender/editors/mesh/editmesh_polybuild.cc b/source/blender/editors/mesh/editmesh_polybuild.cc index 9040bb16434..cc9ad38a393 100644 --- a/source/blender/editors/mesh/editmesh_polybuild.cc +++ b/source/blender/editors/mesh/editmesh_polybuild.cc @@ -19,6 +19,7 @@ #include "BKE_object_types.hh" #include "BKE_screen.hh" +#include "BLI_listbase.h" #include "BLI_math_geom.h" #include "BLI_math_matrix.h" #include "BLI_math_vector.h" @@ -82,6 +83,25 @@ static bool edbm_preselect_or_active(bContext *C, const View3D *v3d, Base **r_ba wmGizmoMap *gzmap = show_gizmo ? region->runtime->gizmo_map : nullptr; wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, "VIEW3D_GGT_mesh_preselect_elem") : nullptr; + + if (gzgroup != nullptr) { + /* Check the gizmo can draw, if not the state may be stale + * or if the gizmo group has never drawn the list may even be empty, see: #141336. + * + * NOTE(ideasman42): we could also fail with an error in this case, + * however that would be quite disruptive, so fallback to the active element. */ + if (!WM_gizmo_context_check_drawstep(C, WM_GIZMOMAP_DRAWSTEP_3D)) { + /* Typically only reached when attempting to use the tool during animation playback. */ + gzgroup = nullptr; + } + else if (BLI_listbase_is_empty(&gzgroup->gizmos)) { + /* If the gizmo group is drawing it *should* never be empty. + * Even so, avoid crashing if it is - investigate if this is ever reached. */ + BLI_assert(false); + gzgroup = nullptr; + } + } + if (gzgroup != nullptr) { wmGizmo *gz = static_cast(gzgroup->gizmos.first); ED_view3d_gizmo_mesh_preselect_get_active(C, gz, r_base, r_ele);