Commit: 3efa7605720b5ecf26afb08c384ca7b4ed5cd530
Author: Nicholas Bishop
Date:   Thu Feb 12 19:45:39 2015 +0100
Branches: cycles-ptex-49
https://developer.blender.org/rB3efa7605720b5ecf26afb08c384ca7b4ed5cd530

First pass at fixing Ptex texpaint resolution undo/redo

Seems to work OK, but need to clean up the API to make it work
better. Want to make sure there are no unexpected issues first though.

===================================================================

M       source/blender/editors/include/ED_paint.h
M       source/blender/editors/mesh/mesh_data.c
M       source/blender/editors/sculpt_paint/paint_image.c

===================================================================

diff --git a/source/blender/editors/include/ED_paint.h 
b/source/blender/editors/include/ED_paint.h
index decd79f..6501dee 100644
--- a/source/blender/editors/include/ED_paint.h
+++ b/source/blender/editors/include/ED_paint.h
@@ -62,4 +62,8 @@ 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);
 void ED_imapaint_bucket_fill(struct bContext *C, float color[3], struct 
wmOperator *op);
 
+void ED_ptex_res_change_undo_begin(struct Object *ob, const char *layer_name,
+                                                                  const struct 
wmOperator *op);
+void ED_ptex_res_change_undo_end(void);
+
 #endif /* __ED_PAINT_H__ */
diff --git a/source/blender/editors/mesh/mesh_data.c 
b/source/blender/editors/mesh/mesh_data.c
index 424b30c..fd16b63 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -58,6 +58,7 @@
 #include "WM_types.h"
 
 #include "ED_mesh.h"
+#include "ED_paint.h"
 #include "ED_object.h"
 #include "ED_screen.h"
 #include "ED_uvedit.h"
@@ -878,11 +879,16 @@ static int mesh_ptex_res_change_exec(bContext *C, 
wmOperator *op)
        Mesh *me = ob->data;
        const int layer_offset = CustomData_get_active_layer(&me->ldata,
                                                                                
                                 CD_LOOP_PTEX);
+       const char *layer_name = CustomData_get_layer_name(&me->ldata,
+                                                                               
                           CD_LOOP_PTEX,
+                                                                               
                           layer_offset);
        MLoopPtex *loop_ptex = CustomData_get_layer_n(&me->ldata, CD_LOOP_PTEX,
                                                                                
                  layer_offset);
        const PtexResChangeMode mode = RNA_enum_get(op->ptr, "mode");
        int i;
 
+       ED_ptex_res_change_undo_begin(ob, layer_name, op);
+
        for (i = 0; i < me->totpoly; i++) {
                const MPoly *poly = &me->mpoly[i];
                int j;
@@ -903,7 +909,9 @@ static int mesh_ptex_res_change_exec(bContext *C, 
wmOperator *op)
                }
        }
 
+       /* Force refresh */
        BKE_ptex_image_mark_for_update(me, layer_offset);
+       BKE_ptex_mesh_image_get(ob, layer_name);
 
        DAG_id_tag_update(&me->id, 0);
        WM_main_add_notifier(NC_GEOM | ND_DATA, me);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c 
b/source/blender/editors/sculpt_paint/paint_image.c
index 5cfbd16..a2dcec6 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -62,6 +62,7 @@
 #include "BKE_material.h"
 #include "BKE_node.h"
 #include "BKE_paint.h"
+#include "BKE_ptex.h"
 #include "BKE_texture.h"
 
 #include "UI_view2d.h"
@@ -88,6 +89,14 @@
 
 #include "paint_intern.h"
 
+/* TODO(nicholasbishop): testing this out as a solution for Ptex
+ * resolution changes */
+typedef struct {
+       BPXRect *rects;
+       int ibuf_dim[2];
+       int num_bytes;
+} UndoImagePtex;
+
 typedef struct UndoImageTile {
        struct UndoImageTile *next, *prev;
 
@@ -108,6 +117,8 @@ typedef struct UndoImageTile {
        short source, use_float;
        char gen_type;
        bool valid;
+
+       UndoImagePtex *ptex;
 } UndoImageTile;
 
 /* this is a static resource for non-globality,
@@ -222,6 +233,9 @@ void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf 
**tmpibuf, int x_tile,
        int allocsize;
        short use_float = ibuf->rect_float ? 1 : 0;
        void *data;
+       /* TODO(nicholasbishop): temporarily abusing x_tile to test undo
+        * for Ptex resolution changes */
+       const bool full_ptex = (x_tile == -1);
 
        /* check if tile is already pushed */
 
@@ -232,7 +246,7 @@ void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf 
**tmpibuf, int x_tile,
                        return data;
        }
 
-       if (*tmpibuf == NULL)
+       if (!full_ptex && *tmpibuf == NULL)
                *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, 
IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect);
        
        tile = MEM_callocN(sizeof(UndoImageTile), "UndoImageTile");
@@ -246,6 +260,9 @@ void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf 
**tmpibuf, int x_tile,
                                         "UndoImageTile.mask");
 
        allocsize = IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE * 4;
+       if (full_ptex) {
+               allocsize = ibuf->x * ibuf->y * 4;
+       }
        allocsize *= (ibuf->rect_float) ? sizeof(float) : sizeof(char);
        tile->rect.pt = MEM_mapallocN(allocsize, "UndeImageTile.rect");
 
@@ -260,7 +277,18 @@ void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf 
**tmpibuf, int x_tile,
        if (valid)
                *valid = &tile->valid;
 
-       undo_copy_tile(tile, *tmpibuf, ibuf, COPY);
+       if (full_ptex) {
+               tile->ptex = MEM_callocN(sizeof(*tile->ptex), "tile->ptex");
+               tile->ptex->rects = MEM_dupallocN(ibuf->ptex_regions);
+               tile->ptex->ibuf_dim[0] = ibuf->x;
+               tile->ptex->ibuf_dim[1] = ibuf->y;
+               tile->ptex->num_bytes = allocsize;
+
+               memcpy(tile->rect.uint, ibuf->rect, allocsize);
+       }
+       else {
+               undo_copy_tile(tile, *tmpibuf, ibuf, COPY);
+       }
 
        if (proj)
                BLI_spin_lock(&undolock);
@@ -314,6 +342,21 @@ static void image_undo_restore_runtime(ListBase *lb)
        IMB_freeImBuf(tmpibuf);
 }
 
+static void image_undo_ptex_swap(UndoImageTile *tile, ImBuf *ibuf)
+{
+       UndoImagePtex *ptex = tile->ptex;
+
+       BLI_assert(!tile->prev && !tile->next);
+       BLI_assert(ptex->rects);
+       BLI_assert(ibuf->ptex_regions);
+
+       SWAP(BPXRect *, ptex->rects, ibuf->ptex_regions);
+       SWAP(unsigned int *, tile->rect.uint, ibuf->rect);
+
+       SWAP(int, ptex->ibuf_dim[0], ibuf->x);
+       SWAP(int, ptex->ibuf_dim[1], ibuf->y);
+}
+
 void ED_image_undo_restore(bContext *C, ListBase *lb)
 {
        Main *bmain = CTX_data_main(C);
@@ -358,6 +401,10 @@ void ED_image_undo_restore(bContext *C, ListBase *lb)
                        continue;
                }
 
+               if (tile->ptex) {
+                       image_undo_ptex_swap(tile, ibuf);
+               }
+
                use_float = ibuf->rect_float ? 1 : 0;
 
                if (use_float != tile->use_float) {
@@ -365,7 +412,9 @@ void ED_image_undo_restore(bContext *C, ListBase *lb)
                        continue;
                }
 
-               undo_copy_tile(tile, tmpibuf, ibuf, RESTORE_COPY);
+               if (!tile->ptex) {
+                       undo_copy_tile(tile, tmpibuf, ibuf, RESTORE_COPY);
+               }
 
                GPU_free_image(ima); /* force OpenGL reload */
                if (ibuf->rect_float)
@@ -386,8 +435,15 @@ void ED_image_undo_free(ListBase *lb)
 {
        UndoImageTile *tile;
 
-       for (tile = lb->first; tile; tile = tile->next)
+       for (tile = lb->first; tile; tile = tile->next) {
                MEM_freeN(tile->rect.pt);
+               if (tile->ptex) {
+                       if (tile->ptex->rects) {
+                               MEM_freeN(tile->ptex->rects);
+                       }
+                       MEM_freeN(tile->ptex);
+               }
+       }
 }
 
 static void image_undo_end(void)
@@ -1534,3 +1590,28 @@ int mask_paint_poll(bContext *C)
        return BKE_paint_select_elem_test(CTX_data_active_object(C));
 }
 
+void ED_ptex_res_change_undo_begin(Object *ob, const char *layer_name,
+                                                                  const 
wmOperator *op)
+{
+       Image *image;
+       ImBuf *ibuf;
+
+       image = BKE_ptex_mesh_image_get(ob, layer_name);
+       BLI_assert(image);
+       ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
+       BLI_assert(ibuf);
+
+       ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
+                                                        ED_image_undo_restore, 
ED_image_undo_free,
+                                                        NULL);
+
+       ED_imapaint_clear_partial_redraw();
+       image_undo_push_tile(image, ibuf, NULL, -1, -1, NULL, NULL, false);
+
+       BKE_image_release_ibuf(image, ibuf, NULL);
+}
+
+void ED_ptex_res_change_undo_end(void)
+{
+       ED_undo_paint_push_end(UNDO_PAINT_IMAGE);
+}

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to