[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