From da1ed32f7681071ecae24a8aab191ba31aa2fd5c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 12 Jan 2024 11:13:41 +0100 Subject: [PATCH] Fix #116734: Measure Tool Undo crash. The ruler code would add new (GP) ID and link it to current scene outside of any depsgraph tagging and/or undo step writing. Now always add this 'util' GP data earlier, in a context where there is a clear undo step written. Also fixes the missing tagging and relations updates. Pull Request: https://projects.blender.org/blender/blender/pulls/116751 --- .../space_view3d/view3d_gizmo_ruler.cc | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc b/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc index 47dff752790..ec741ded491 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc @@ -515,11 +515,25 @@ static RulerItem *gzgroup_ruler_item_first_get(wmGizmoGroup *gzgroup) } #define RULER_ID "RulerData3D" -static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup) + +/* GP data creation has to happen before the undo step is stored. + * See also #116734. */ +static void view3d_ruler_gpencil_ensure(bContext *C) { // RulerInfo *ruler_info = gzgroup->customdata; Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + if (scene->gpd == nullptr) { + scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations"); + DEG_id_tag_update_ex(bmain, &scene->id, ID_RECALC_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + } +} + +static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup) +{ + // RulerInfo *ruler_info = gzgroup->customdata; + Scene *scene = CTX_data_scene(C); bGPdata *gpd; bGPDlayer *gpl; @@ -529,9 +543,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup) const char *ruler_name = RULER_ID; bool changed = false; - if (scene->gpd == nullptr) { - scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations"); - } + BLI_assert(scene->gpd != nullptr); gpd = scene->gpd; gpl = view3d_ruler_layer_get(gpd); @@ -1191,6 +1203,9 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event) ruler_info->item_active = ruler_item_pick; + /* Ensures there is a valid GPencil data in current scene. */ + view3d_ruler_gpencil_ensure(C); + return OPERATOR_RUNNING_MODAL; } @@ -1419,6 +1434,7 @@ static int view3d_ruler_remove_invoke(bContext *C, wmOperator *op, const wmEvent } /* Update the annotation layer. */ + view3d_ruler_gpencil_ensure(C); view3d_ruler_to_gpencil(C, gzgroup); ED_region_tag_redraw_editor_overlays(region);