Revision: 17460
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17460
Author:   campbellbarton
Date:     2008-11-14 18:30:55 +0100 (Fri, 14 Nov 2008)

Log Message:
-----------
tile based undo's now works while projection painting.
TODO - float buffer support & for some reason painting on multiple images at 
once dosnt restore the tiles to the right image then undoing.

Modified Paths:
--------------
    branches/projection-paint/source/blender/src/imagepaint.c

Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c   2008-11-14 
17:05:25 UTC (rev 17459)
+++ branches/projection-paint/source/blender/src/imagepaint.c   2008-11-14 
17:30:55 UTC (rev 17460)
@@ -244,6 +244,7 @@
 
 typedef struct ProjectPixel {
        float projCo2D[2]; /* the floating point screen projection of this 
pixel */
+       char origColor[4];
        short x_px, y_px;
        void *pixel;
        short image_index; /* if anyone wants to paint onto more then 32000 
images they can bite me */
@@ -301,6 +302,31 @@
                        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)
+{
+       UndoTile *tile;
+       int allocsize;
+       
+       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->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");
+
+       undo_copy_tile(tile, *tmpibuf, ibuf, 0);
+       curundo->undosize += allocsize;
+
+       BLI_addtail(&curundo->tiles, tile);
+       
+       return tile;
+}
+
 static void undo_restore(UndoElem *undo)
 {
        Image *ima = NULL;
@@ -1327,8 +1353,10 @@
                
                if (ibuf->rect_float) {
                        projPixel->pixel = (void *) ((( float * ) 
ibuf->rect_float) + (( x + y * ibuf->x ) * pixel_size));
+                       /* TODO float support for origColor */
                } else {
                        projPixel->pixel = (void *) ((( char * ) ibuf->rect) + 
(( x + y * ibuf->x ) * pixel_size));
+                       *((unsigned int *)projPixel->origColor) = *((unsigned 
int *)projPixel->pixel);
                }
                
                VECCOPY2D(projPixel->projCo2D, pixelScreenCo);
@@ -2258,16 +2286,16 @@
        ps->projectImBufs = BLI_memarena_alloc( ps->projectArena, sizeof(ImBuf 
*) * ps->projectImageTotal);
        *(ps->projectPartialRedraws) = BLI_memarena_alloc( ps->projectArena, 
sizeof(ImagePaintPartialRedraw) * ps->projectImageTotal * 
PROJ_BOUNDBOX_SQUARED);
        
-       for (a=1; a< ps->projectImageTotal; a++) {
-               ps->projectPartialRedraws[a] = *(ps->projectPartialRedraws) + 
(a * PROJ_BOUNDBOX_SQUARED);
-       }
-       // calloced - memset(ps->projectPartialRedraws, 0, 
sizeof(ImagePaintPartialRedraw) * ps->projectImageTotal);
-       
        for (node= image_LinkList, i=0; node; node= node->next, i++) {
                ps->projectImages[i] = node->link;
                ps->projectImages[i]->id.flag &= ~LIB_DOIT;
                ps->projectImBufs[i] = BKE_image_get_ibuf(ps->projectImages[i], 
NULL);
+               
+               ps->projectPartialRedraws[i] = *(ps->projectPartialRedraws) + 
(i * PROJ_BOUNDBOX_SQUARED);
        }
+       
+       // calloced - memset(ps->projectPartialRedraws, 0, 
sizeof(ImagePaintPartialRedraw) * ps->projectImageTotal);
+       
        /* we have built the array, discard the linked list */
        BLI_linklist_free(image_LinkList, NULL);
 }
@@ -2275,6 +2303,85 @@
 static void project_paint_end( ProjectPaintState *ps )
 {
        int a;
+       
+       /* build undo data from original pixel colors */
+       if(U.uiflag & USER_GLOBALUNDO) {
+               ProjectPixel *projPixel;
+               ImBuf *ibuf, *tmpibuf = NULL;
+               LinkNode *pixel_node;
+               UndoTile *tile;
+               UndoTile ***image_undo_tiles = (UndoTile 
***)BLI_memarena_alloc( ps->projectArena, sizeof(UndoTile ***) * 
ps->projectImageTotal);
+               int bucket_index = (ps->bucketsX * ps->bucketsY) - 1; /* we 
could get an X/Y but easier to loop through all possible buckets */
+               int tile_index;
+               int x_round, y_round;
+               int x_tile, y_tile;
+               
+               /* context */
+               int last_image_index = -1;
+               int last_tile_width;
+               ImBuf *last_ibuf;
+               Image *last_ima;
+               UndoTile **last_undo_grid = NULL;
+               
+               
+               for(a=0; a < ps->projectImageTotal; a++) {
+                       ibuf = ps->projectImBufs[a];
+                       image_undo_tiles[a] = (UndoTile **)BLI_memarena_alloc(
+                                                       ps->projectArena,
+                                                       sizeof(UndoTile **) * 
IMAPAINT_TILE_NUMBER(ibuf->x) * IMAPAINT_TILE_NUMBER(ibuf->y) );
+               }
+               
+               do {
+                       if ((pixel_node = ps->projectBuckets[bucket_index])) {
+                               
+                               /* loop through all pixels */
+                               while (pixel_node) {
+                                       /* ok we have a pixel, was it modified? 
*/
+                                       projPixel = (ProjectPixel 
*)pixel_node->link;
+                                       
+                                       /* TODO - support float */
+                                       if (*((unsigned int 
*)projPixel->origColor) != *((unsigned int *)projPixel->pixel)) {
+                                               
+                                               if (last_image_index != 
projPixel->image_index) {
+                                                       /* set the context */
+                                                       last_image_index =      
projPixel->image_index;
+                                                       last_ima =              
        ps->projectImages[last_image_index];
+                                                       last_ibuf =             
        ps->projectImBufs[last_image_index];
+                                                       last_tile_width =       
IMAPAINT_TILE_NUMBER(last_ibuf->x);
+                                                       last_undo_grid =        
image_undo_tiles[last_image_index];
+                                               }
+                                               
+                                               x_tile =  projPixel->x_px >> 
IMAPAINT_TILE_BITS;
+                                               y_tile =  projPixel->y_px >> 
IMAPAINT_TILE_BITS;
+                                               
+                                               x_round = x_tile * 
IMAPAINT_TILE_SIZE;
+                                               y_round = y_tile * 
IMAPAINT_TILE_SIZE;
+                                               
+                                               tile_index = x_tile + y_tile * 
last_tile_width;
+                                               
+                                               if 
(last_undo_grid[tile_index]==NULL) {
+                                                       /* add the undo tile 
from the modified image, then write the original colors back into it */
+                                                       tile = 
last_undo_grid[tile_index] = undo_init_tile(&last_ima->id, ibuf, &tmpibuf, 
x_tile, y_tile);
+                                               } else {
+                                                       tile = 
last_undo_grid[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 */
+                                               /* TODO float buffer */
+                                               ((unsigned int *)tile->rect)[ 
(projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE 
] = *((unsigned int *)projPixel->origColor);                                    
           
+                                       }
+                                       
+                                       pixel_node = pixel_node->next;
+                               }
+                       }
+               } while(bucket_index--);
+               
+               if (tmpibuf)
+                       IMB_freeImBuf(tmpibuf);
+       }
+       /* done calculating undo data */
+       
        BLI_memarena_free(ps->projectArena);
        
        for (a=0; a<ps->thread_tot; a++) {
@@ -2339,7 +2446,7 @@
 {
        ImBuf *tmpibuf = NULL;
        UndoTile *tile;
-       int srcx= 0, srcy= 0, origx, allocsize;
+       int srcx= 0, srcy= 0, origx;
 
        IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
 
@@ -2372,22 +2479,7 @@
                                        break;
 
                        if(!tile) {
-                               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= ima->id;
-                               tile->x= x;
-                               tile->y= y;
-
-                               allocsize= 
IMAPAINT_TILE_SIZE*IMAPAINT_TILE_SIZE*4;
-                               allocsize *= (ibuf->rect_float)? sizeof(float): 
sizeof(char);
-                               tile->rect= MEM_mapallocN(allocsize, 
"ImaUndoRect");
-
-                               undo_copy_tile(tile, tmpibuf, ibuf, 0);
-                               curundo->undosize += allocsize;
-
-                               BLI_addtail(&curundo->tiles, tile);
+                               undo_init_tile(&ima->id, ibuf, &tmpibuf, x, y);
                        }
                }
        }


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to