Fix T37326 inversion of image channels did not do an undo push. Now only do an undo...
authorAntony Riakiotakis <kalast@gmail.com>
Thu, 5 Dec 2013 20:28:14 +0000 (22:28 +0200)
committerAntony Riakiotakis <kalast@gmail.com>
Sat, 7 Dec 2013 22:29:13 +0000 (00:29 +0200)
source/blender/editors/include/ED_sculpt.h
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_image_2d.c
source/blender/editors/sculpt_paint/paint_image_proj.c
source/blender/editors/sculpt_paint/paint_intern.h
source/blender/editors/sculpt_paint/paint_undo.c
source/blender/editors/sculpt_paint/sculpt_undo.c
source/blender/editors/space_image/CMakeLists.txt
source/blender/editors/space_image/SConscript
source/blender/editors/space_image/image_ops.c

index e85f11e5b78c70af0bf0e2acf24742994c64d9e7..ed7415e6c26dd289fbbe0bc95d856658dbf4ae3e 100644 (file)
@@ -65,8 +65,20 @@ void ED_keymap_paint(struct wmKeyConfig *keyconf);
 #define UNDO_PAINT_IMAGE    0
 #define UNDO_PAINT_MESH     1
 
+typedef void (*UndoRestoreCb)(struct bContext *C, struct ListBase *lb);
+typedef void (*UndoFreeCb)(struct ListBase *lb);
+
 int ED_undo_paint_step(struct bContext *C, int type, int step, const char *name);
 void ED_undo_paint_free(void);
 int ED_undo_paint_valid(int type, const char *name);
+void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free);
+void ED_undo_paint_push_end(int type);
+
+/* image painting specific undo */
+void ED_image_undo_restore(struct bContext *C, struct ListBase *lb);
+void ED_image_undo_free(struct ListBase *lb);
+void ED_imapaint_clear_partial_redraw(void);
+void ED_imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h);
+
 
 #endif
index 003db8a9c4310dc4a2eb226533c53422f33b1a5a..6ffa54c556902e68942db901f6f3e312d9d72b43 100644 (file)
@@ -238,7 +238,7 @@ void image_undo_remove_masks(void)
        }
 }
 
-void image_undo_restore(bContext *C, ListBase *lb)
+void ED_image_undo_restore(bContext *C, ListBase *lb)
 {
        Main *bmain = CTX_data_main(C);
        Image *ima = NULL;
@@ -304,7 +304,7 @@ void image_undo_restore(bContext *C, ListBase *lb)
        IMB_freeImBuf(tmpibuf);
 }
 
-void image_undo_free(ListBase *lb)
+void ED_image_undo_free(ListBase *lb)
 {
        UndoImageTile *tile;
 
@@ -314,7 +314,7 @@ void image_undo_free(ListBase *lb)
 
 /* Imagepaint Partial Redraw & Dirty Region */
 
-void imapaint_clear_partial_redraw(void)
+void ED_imapaint_clear_partial_redraw(void)
 {
        memset(&imapaintpartial, 0, sizeof(imapaintpartial));
 }
@@ -331,7 +331,7 @@ void imapaint_region_tiles(ImBuf *ibuf, int x, int y, int w, int h, int *tx, int
        *ty = (y >> IMAPAINT_TILE_BITS);
 }
 
-void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
+void ED_imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
 {
        ImBuf *tmpibuf = NULL;
        int tilex, tiley, tilew, tileh, tx, ty;
@@ -506,8 +506,8 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, float mou
        }
 
        settings->imapaint.flag |= IMAGEPAINT_DRAWING;
-       undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
-                             image_undo_restore, image_undo_free);
+       ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
+                             ED_image_undo_restore, ED_image_undo_free);
 
        {
                UnifiedPaintSettings *ups = &settings->unified_paint_settings;
@@ -582,7 +582,7 @@ static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke)
                paint_2d_stroke_done(pop->custom_paint);
        }
 
-       undo_paint_push_end(UNDO_PAINT_IMAGE);
+       ED_undo_paint_push_end(UNDO_PAINT_IMAGE);
 
        /* duplicate warning, see texpaint_init */
 #if 0
index 5f4594703ee4c0483221c2a8c47f64f805448f46..b2f429c31a1e7bbfdedd3174dd1e274d28be6684 100644 (file)
@@ -49,6 +49,7 @@
 #include "BKE_report.h"
 
 #include "ED_screen.h"
+#include "ED_sculpt.h"
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
@@ -902,7 +903,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *maskb, const f
        
        /* blend into canvas */
        for (a = 0; a < tot; a++) {
-               imapaint_dirty_region(s->image, s->canvas,
+               ED_imapaint_dirty_region(s->image, s->canvas,
                                      region[a].destx, region[a].desty,
                                      region[a].width, region[a].height);
        
@@ -1111,7 +1112,7 @@ void paint_2d_redraw(const bContext *C, void *ps, bool final)
                ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL);
 
                imapaint_image_update(s->sima, s->image, ibuf, false);
-               imapaint_clear_partial_redraw();
+               ED_imapaint_clear_partial_redraw();
 
                BKE_image_release_ibuf(s->image, ibuf, NULL);
 
index fccd9cf0a19584f7eb1a22f751d2778ad7920153..d6989c082a101ca6575b01a050bba281d02b7872 100644 (file)
@@ -4413,8 +4413,8 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
 
        scene->toolsettings->imapaint.flag |= IMAGEPAINT_DRAWING;
 
-       undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
-                             image_undo_restore, image_undo_free);
+       ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
+                             ED_image_undo_restore, ED_image_undo_free);
 
        /* allocate and initialize spatial data structures */
        project_paint_begin(&ps);
index 5fff02f016b95e884a3648d9baae9b3fa28dcf73..01f5d53594e972ec2cb18c1cca0c69b4a0d15c77 100644 (file)
@@ -146,13 +146,9 @@ int image_texture_paint_poll(struct bContext *C);
 void *image_undo_find_tile(struct Image *ima, struct ImBuf *ibuf, int x_tile, int y_tile, unsigned short **mask);
 void *image_undo_push_tile(struct Image *ima, struct ImBuf *ibuf, struct ImBuf **tmpibuf, int x_tile, int y_tile);
 void image_undo_remove_masks(void);
-void image_undo_restore(struct bContext *C, struct ListBase *lb);
-void image_undo_free(struct ListBase *lb);
 void imapaint_image_update(struct SpaceImage *sima, struct Image *image, struct ImBuf *ibuf, short texpaint);
 struct ImagePaintPartialRedraw *get_imapaintpartial(void);
 void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr);
-void imapaint_clear_partial_redraw(void);
-void imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h);
 void imapaint_region_tiles(struct ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th);
 int get_imapaint_zoom(struct bContext *C, float *zoomx, float *zoomy);
 void *paint_2d_new_stroke(struct bContext *, struct wmOperator *);
@@ -232,13 +228,8 @@ typedef enum BrushStrokeMode {
 } BrushStrokeMode;
 
 /* paint_undo.c */
-typedef void (*UndoRestoreCb)(struct bContext *C, struct ListBase *lb);
-typedef void (*UndoFreeCb)(struct ListBase *lb);
-
-void undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free);
 struct ListBase *undo_paint_push_get_list(int type);
 void undo_paint_push_count_alloc(int type, int size);
-void undo_paint_push_end(int type);
 
 /* paint_hide.c */
 
index 50a79005ee33558e57c217b51a2957b67d912e2a..b4bd46376d3900274947f023e53b083dd6375186 100644 (file)
@@ -223,7 +223,7 @@ static void undo_stack_free(UndoStack *stack)
 
 /* Exported Functions */
 
-void undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free)
+void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free)
 {
        if (type == UNDO_PAINT_IMAGE)
                undo_stack_push_begin(&ImageUndoStack, name, restore, free);
@@ -253,7 +253,7 @@ void undo_paint_push_count_alloc(int type, int size)
                MeshUndoStack.current->undosize += size;
 }
 
-void undo_paint_push_end(int type)
+void ED_undo_paint_push_end(int type)
 {
        if (type == UNDO_PAINT_IMAGE)
                undo_stack_push_end(&ImageUndoStack);
index 8861777f3265fee0da4c4ffe85dbd952f231ec19..846801ae85d3332ab51a3ac0b21a2ff6c063b0c4 100644 (file)
@@ -819,7 +819,7 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
 
 void sculpt_undo_push_begin(const char *name)
 {
-       undo_paint_push_begin(UNDO_PAINT_MESH, name,
+       ED_undo_paint_push_begin(UNDO_PAINT_MESH, name,
                              sculpt_undo_restore, sculpt_undo_free);
 }
 
@@ -839,5 +839,5 @@ void sculpt_undo_push_end(void)
                        BKE_pbvh_node_layer_disp_free(unode->node);
        }
 
-       undo_paint_push_end(UNDO_PAINT_MESH);
+       ED_undo_paint_push_end(UNDO_PAINT_MESH);
 }
index 50d8051a73e1c453d3286256b4516e3197dddaea..62ac3c2d985bf75b930d49393c4dbb7db5f58fba 100644 (file)
@@ -30,6 +30,7 @@ set(INC
        ../../render/extern/include
        ../../windowmanager
        ../../../../intern/guardedalloc
+       ../../gpu
 )
 
 set(INC_SYS
index 89def32e70f4534859ed74be5c30ed4c1365cc7a..d878a726b55d975a1034a0533da8648430a43fce 100644 (file)
@@ -42,6 +42,7 @@ incs = [
     '../../makesrna',
     '../../render/extern/include',
     '../../windowmanager',
+    '../../gpu',
     ]
 incs = ' '.join(incs)
 
index 2c2e204b3b34efd479aca865281c6234b980e125..a37b50172cf98d161beeec186aab2c6753b728b7 100644 (file)
@@ -58,6 +58,8 @@
 #include "BKE_report.h"
 #include "BKE_screen.h"
 
+#include "GPU_draw.h"
+
 #include "IMB_colormanagement.h"
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
@@ -85,6 +87,7 @@
 #include "PIL_time.h"
 
 #include "image_intern.h"
+#include "ED_sculpt.h"
 
 /******************** view navigation utilities *********************/
 
@@ -1860,6 +1863,9 @@ static int image_invert_exec(bContext *C, wmOperator *op)
 {
        Image *ima = CTX_data_edit_image(C);
        ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+       SpaceImage *sima = CTX_wm_space_image(C);
+       /* undo is supported only on image paint mode currently */
+       bool support_undo = ((sima != NULL) && (sima->mode == SI_MODE_PAINT));
 
        /* flags indicate if this channel should be inverted */
        const short r = RNA_boolean_get(op->ptr, "invert_r");
@@ -1872,6 +1878,14 @@ static int image_invert_exec(bContext *C, wmOperator *op)
        if (ibuf == NULL)  /* TODO: this should actually never happen, but does for render-results -> cleanup */
                return OPERATOR_CANCELLED;
 
+       if (support_undo) {
+               ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
+                                                         ED_image_undo_restore, ED_image_undo_free);
+               /* not strictly needed, because we only imapaint_dirty_region to invalidate all tiles
+                * but better do this right in case someone copies this for a tool that uses partial redraw better */
+               ED_imapaint_clear_partial_redraw();
+               ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y);
+       }
        /* TODO: make this into an IMB_invert_channels(ibuf,r,g,b,a) method!? */
        if (ibuf->rect_float) {
                
@@ -1903,9 +1917,16 @@ static int image_invert_exec(bContext *C, wmOperator *op)
        }
 
        ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
+
        if (ibuf->mipmap[0])
                ibuf->userflags |= IB_MIPMAP_INVALID;
 
+       if (support_undo)
+               ED_undo_paint_push_end(UNDO_PAINT_IMAGE);
+
+       /* force GPU reupload, all image is invalid */
+       GPU_free_image(ima);
+
        WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
 
        BKE_image_release_ibuf(ima, ibuf, NULL);