From f7c5296f1d918b94255f50a15a984978c46bf81e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 18 Sep 2020 14:17:17 +1000 Subject: Fix T80885: Texture paint camera project crashes after undo/redo Unmatched ED_image_undo_push_{begin/end}, add doc-strings noting why this is needed. Thanks to @Baardaap for the initial fix. --- .../editors/sculpt_paint/paint_image_proj.c | 25 +++++++++++----------- source/blender/editors/space_image/image_undo.c | 12 +++++++++++ 2 files changed, 25 insertions(+), 12 deletions(-) (limited to 'source') diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index af84cb2d15b..92ca082311a 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -6140,8 +6140,6 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) scene->toolsettings->imapaint.flag |= IMAGEPAINT_DRAWING; - ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_3D); - /* allocate and initialize spatial data structures */ project_paint_begin(C, &ps, false, 0); @@ -6150,23 +6148,26 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Could not get valid evaluated mesh"); return OPERATOR_CANCELLED; } - else { - float pos[2] = {0.0, 0.0}; - float lastpos[2] = {0.0, 0.0}; - int a; - project_paint_op(&ps, lastpos, pos); + ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_3D); + + const float pos[2] = {0.0, 0.0}; + const float lastpos[2] = {0.0, 0.0}; + int a; - project_image_refresh_tagged(&ps); + project_paint_op(&ps, lastpos, pos); - for (a = 0; a < ps.image_tot; a++) { - GPU_free_image(ps.projImages[a].ima); - WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima); - } + project_image_refresh_tagged(&ps); + + for (a = 0; a < ps.image_tot; a++) { + GPU_free_image(ps.projImages[a].ima); + WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima); } project_paint_end(&ps); + ED_image_undo_push_end(); + scene->toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING; BKE_brush_size_set(scene, ps.brush, orig_brush_size); diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c index eb1c46240cb..f45e415e604 100644 --- a/source/blender/editors/space_image/image_undo.c +++ b/source/blender/editors/space_image/image_undo.c @@ -1005,6 +1005,14 @@ void ED_image_undosys_type(UndoType *ut) /* -------------------------------------------------------------------- */ /** \name Utilities + * + * \note image undo exposes #ED_image_undo_push_begin, #ED_image_undo_push_end + * which must be called by the operator directly. + * + * Unlike most other undo stacks this is needed: + * - So we can always access the state before the image was painted onto, + * which is needed if previous undo states aren't image-type. + * - So operators can access the pixel-data before the stroke was applied, at run-time. * \{ */ ListBase *ED_image_paint_tile_list_get(void) @@ -1042,6 +1050,10 @@ static ImageUndoStep *image_undo_push_begin(const char *name, int paint_mode) return us; } +/** + * The caller is responsible for running #ED_image_undo_push_end, + * failure to do so causes an invalid state for the undo system. + */ void ED_image_undo_push_begin(const char *name, int paint_mode) { image_undo_push_begin(name, paint_mode); -- cgit v1.2.3