[Bf-blender-cvs] [3efa760] cycles-ptex-49: First pass at fixing Ptex texpaint resolution undo/redo
Nicholas Bishop
noreply at git.blender.org
Thu Feb 12 19:46:42 CET 2015
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);
+}
More information about the Bf-blender-cvs
mailing list