[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24321] branches/sculpt25/source/blender/ editors: Sculpt: split generic part of image paint undo system into separate
Brecht Van Lommel
brecht at blender.org
Wed Nov 4 21:19:41 CET 2009
Revision: 24321
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24321
Author: blendix
Date: 2009-11-04 21:19:41 +0100 (Wed, 04 Nov 2009)
Log Message:
-----------
Sculpt: split generic part of image paint undo system into separate
paint_undo.c file, to be reused for sculpt.
Modified Paths:
--------------
branches/sculpt25/source/blender/editors/include/ED_sculpt.h
branches/sculpt25/source/blender/editors/sculpt_paint/paint_image.c
branches/sculpt25/source/blender/editors/sculpt_paint/paint_intern.h
branches/sculpt25/source/blender/editors/space_view3d/view3d_header.c
branches/sculpt25/source/blender/editors/util/ed_util.c
branches/sculpt25/source/blender/editors/util/undo.c
Added Paths:
-----------
branches/sculpt25/source/blender/editors/sculpt_paint/paint_undo.c
Modified: branches/sculpt25/source/blender/editors/include/ED_sculpt.h
===================================================================
--- branches/sculpt25/source/blender/editors/include/ED_sculpt.h 2009-11-04 20:15:17 UTC (rev 24320)
+++ branches/sculpt25/source/blender/editors/include/ED_sculpt.h 2009-11-04 20:19:41 UTC (rev 24321)
@@ -45,8 +45,11 @@
void ED_operatortypes_paint(void);
void ED_keymap_paint(struct wmKeyConfig *keyconf);
-/* paint_image.c */
-void undo_imagepaint_step(int step);
-void undo_imagepaint_clear(void);
+/* paint_undo.c */
+#define UNDO_PAINT_IMAGE 0
+#define UNDO_PAINT_MESH 1
+void ED_undo_paint_step(struct bContext *C, int type, int step);
+void ED_undo_paint_free(void);
+
#endif
Modified: branches/sculpt25/source/blender/editors/sculpt_paint/paint_image.c
===================================================================
--- branches/sculpt25/source/blender/editors/sculpt_paint/paint_image.c 2009-11-04 20:15:17 UTC (rev 24320)
+++ branches/sculpt25/source/blender/editors/sculpt_paint/paint_image.c 2009-11-04 20:19:41 UTC (rev 24321)
@@ -86,6 +86,7 @@
#include "ED_image.h"
#include "ED_object.h"
#include "ED_screen.h"
+#include "ED_sculpt.h"
#include "ED_view3d.h"
#include "WM_api.h"
@@ -113,8 +114,6 @@
#define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS)
#define IMAPAINT_TILE_NUMBER(size) (((size)+IMAPAINT_TILE_SIZE-1) >> IMAPAINT_TILE_BITS)
-#define MAXUNDONAME 64
-
static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint);
@@ -204,7 +203,7 @@
Image *ima;
ImBuf *ibuf;
ImagePaintPartialRedraw *partRedrawRect;
- struct UndoTile **undoRect; /* only used to build undo tiles after painting */
+ void **undoRect; /* only used to build undo tiles after painting */
int touch;
} ProjPaintImage;
@@ -332,32 +331,20 @@
/* Finish projection painting structs */
+typedef struct UndoImageTile {
+ struct UndoImageTile *next, *prev;
-typedef struct UndoTile {
- struct UndoTile *next, *prev;
- ID id;
+ char idname[MAX_ID_NAME]; /* name instead of pointer*/
+
void *rect;
int x, y;
-} UndoTile;
+} UndoImageTile;
-typedef struct UndoElem {
- struct UndoElem *next, *prev;
- char name[MAXUNDONAME];
- uintptr_t undosize;
-
- ImBuf *ibuf;
- ListBase tiles;
-} UndoElem;
-
-static ListBase undobase = {NULL, NULL};
-static UndoElem *curundo = NULL;
static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
/* UNDO */
-/* internal functions */
-
-static void undo_copy_tile(UndoTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, int restore)
+static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, int restore)
{
/* copy or swap contents of tile->rect and region in ibuf->rect */
IMB_rectcpy(tmpibuf, ibuf, 0, 0, tile->x*IMAPAINT_TILE_SIZE,
@@ -374,49 +361,52 @@
tile->y*IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
}
-static UndoTile *undo_init_tile(ID *id, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile)
+static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile)
{
- UndoTile *tile;
+ ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_IMAGE);
+ UndoImageTile *tile;
int allocsize;
+
+ for(tile=lb->first; tile; tile=tile->next)
+ if(tile->x == x_tile && tile->y == y_tile && strcmp(tile->idname, ima->id.name)==0)
+ return tile->rect;
if (*tmpibuf==NULL)
*tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat|IB_rect, 0);
- tile= MEM_callocN(sizeof(UndoTile), "ImaUndoTile");
- tile->id= *id;
+ tile= MEM_callocN(sizeof(UndoImageTile), "UndoImageTile");
+ strcpy(tile->idname, ima->id.name);
tile->x= x_tile;
tile->y= y_tile;
allocsize= IMAPAINT_TILE_SIZE*IMAPAINT_TILE_SIZE*4;
allocsize *= (ibuf->rect_float)? sizeof(float): sizeof(char);
- tile->rect= MEM_mapallocN(allocsize, "ImaUndoRect");
+ tile->rect= MEM_mapallocN(allocsize, "UndeImageTile.rect");
undo_copy_tile(tile, *tmpibuf, ibuf, 0);
- curundo->undosize += allocsize;
+ undo_paint_push_count_alloc(UNDO_PAINT_IMAGE, allocsize);
- BLI_addtail(&curundo->tiles, tile);
+ BLI_addtail(lb, tile);
- return tile;
+ return tile->rect;
}
-static void undo_restore(UndoElem *undo)
+static void image_undo_restore(bContext *C, ListBase *lb)
{
+ Main *bmain= CTX_data_main(C);
Image *ima = NULL;
ImBuf *ibuf, *tmpibuf;
- UndoTile *tile;
+ UndoImageTile *tile;
- if(!undo)
- return;
-
tmpibuf= IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32,
IB_rectfloat|IB_rect, 0);
- for(tile=undo->tiles.first; tile; tile=tile->next) {
+ for(tile=lb->first; tile; tile=tile->next) {
/* find image based on name, pointer becomes invalid with global undo */
- if(ima && strcmp(tile->id.name, ima->id.name)==0);
+ if(ima && strcmp(tile->idname, ima->id.name)==0);
else {
- for(ima=G.main->image.first; ima; ima=ima->id.next)
- if(strcmp(tile->id.name, ima->id.name)==0)
+ for(ima=bmain->image.first; ima; ima=ima->id.next)
+ if(strcmp(tile->idname, ima->id.name)==0)
break;
}
@@ -435,119 +425,14 @@
IMB_freeImBuf(tmpibuf);
}
-static void undo_free(UndoElem *undo)
+static void image_undo_free(ListBase *lb)
{
- UndoTile *tile;
+ UndoImageTile *tile;
- for(tile=undo->tiles.first; tile; tile=tile->next)
+ for(tile=lb->first; tile; tile=tile->next)
MEM_freeN(tile->rect);
- BLI_freelistN(&undo->tiles);
}
-static void undo_imagepaint_push_begin(char *name)
-{
- UndoElem *uel;
- int nr;
-
- /* Undo push is split up in begin and end, the reason is that as painting
- * happens more tiles are added to the list, and at the very end we know
- * how much memory the undo used to remove old undo elements */
-
- /* remove all undos after (also when curundo==NULL) */
- while(undobase.last != curundo) {
- uel= undobase.last;
- undo_free(uel);
- BLI_freelinkN(&undobase, uel);
- }
-
- /* make new */
- curundo= uel= MEM_callocN(sizeof(UndoElem), "undo file");
- BLI_addtail(&undobase, uel);
-
- /* name can be a dynamic string */
- strncpy(uel->name, name, MAXUNDONAME-1);
-
- /* limit amount to the maximum amount*/
- nr= 0;
- uel= undobase.last;
- while(uel) {
- nr++;
- if(nr==U.undosteps) break;
- uel= uel->prev;
- }
- if(uel) {
- while(undobase.first!=uel) {
- UndoElem *first= undobase.first;
- undo_free(first);
- BLI_freelinkN(&undobase, first);
- }
- }
-}
-
-static void undo_imagepaint_push_end()
-{
- UndoElem *uel;
- uintptr_t totmem, maxmem;
-
- if(U.undomemory != 0) {
- /* limit to maximum memory (afterwards, we can't know in advance) */
- totmem= 0;
- maxmem= ((uintptr_t)U.undomemory)*1024*1024;
-
- uel= undobase.last;
- while(uel) {
- totmem+= uel->undosize;
- if(totmem>maxmem) break;
- uel= uel->prev;
- }
-
- if(uel) {
- while(undobase.first!=uel) {
- UndoElem *first= undobase.first;
- undo_free(first);
- BLI_freelinkN(&undobase, first);
- }
- }
- }
-}
-
-void undo_imagepaint_step(int step)
-{
- UndoElem *undo;
-
- if(step==1) {
- if(curundo==NULL);
- else {
- if(G.f & G_DEBUG) printf("undo %s\n", curundo->name);
- undo_restore(curundo);
- curundo= curundo->prev;
- }
- }
- else if(step==-1) {
- if((curundo!=NULL && curundo->next==NULL) || undobase.first==NULL);
- else {
- undo= (curundo && curundo->next)? curundo->next: undobase.first;
- undo_restore(undo);
- curundo= undo;
- if(G.f & G_DEBUG) printf("redo %s\n", undo->name);
- }
- }
-}
-
-void undo_imagepaint_clear(void)
-{
- UndoElem *uel;
-
- uel= undobase.first;
- while(uel) {
- undo_free(uel);
- uel= uel->next;
- }
-
- BLI_freelistN(&undobase);
- curundo= NULL;
-}
-
/* fast projection bucket array lookup, use the safe version for bound checking */
static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
{
@@ -3316,7 +3201,7 @@
ProjPixel *projPixel;
ImBuf *tmpibuf = NULL, *tmpibuf_float = NULL;
LinkNode *pixel_node;
- UndoTile *tile;
+ void *tilerect;
MemArena *arena = ps->arena_mt[0]; /* threaded arena re-used for non threaded case */
int bucket_tot = (ps->buckets_x * ps->buckets_y); /* we could get an X/Y but easier to loop through all possible buckets */
@@ -3332,8 +3217,8 @@
int last_tile_width=0;
for(a=0, last_projIma=ps->projImages; a < ps->image_tot; a++, last_projIma++) {
- int size = sizeof(UndoTile **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y);
- last_projIma->undoRect = (UndoTile **) BLI_memarena_alloc(arena, size);
+ int size = sizeof(void **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y);
+ last_projIma->undoRect = (void **) BLI_memarena_alloc(arena, size);
memset(last_projIma->undoRect, 0, size);
last_projIma->ibuf->userflags |= IB_BITMAPDIRTY;
}
@@ -3373,21 +3258,21 @@
if (last_projIma->undoRect[tile_index]==NULL) {
/* add the undo tile from the modified image, then write the original colors back into it */
- tile = last_projIma->undoRect[tile_index] = undo_init_tile(&last_projIma->ima->id, last_projIma->ibuf, is_float ? (&tmpibuf_float):(&tmpibuf) , x_tile, y_tile);
+ tilerect = last_projIma->undoRect[tile_index] = image_undo_push_tile(last_projIma->ima, last_projIma->ibuf, is_float ? (&tmpibuf_float):(&tmpibuf) , x_tile, y_tile);
}
else {
- tile = last_projIma->undoRect[tile_index];
+ tilerect = last_projIma->undoRect[tile_index];
}
/* This is a BIT ODD, but overwrite the undo tiles image info with this pixels original color
* because allocating the tiles allong the way slows down painting */
if (is_float) {
- float *rgba_fp = (float *)tile->rect + (((projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE)) * 4;
+ float *rgba_fp = (float *)tilerect + (((projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE)) * 4;
QUATCOPY(rgba_fp, projPixel->origColor.f);
}
else {
- ((unsigned int *)tile->rect)[ (projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE ] = projPixel->origColor.uint;
+ ((unsigned int *)tilerect)[ (projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE ] = projPixel->origColor.uint;
}
}
}
@@ -3958,7 +3843,6 @@
static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
{
ImBuf *tmpibuf = NULL;
- UndoTile *tile;
int srcx= 0, srcy= 0, origx;
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list