Fix #28780: Undo while painting image sequences issue
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 3 Oct 2011 11:04:05 +0000 (11:04 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 3 Oct 2011 11:04:05 +0000 (11:04 +0000)
- Store imbuf file path in UndoImageTile structure, so imbuf can be verified
  before applying titles on it.
- If current image's imbuf file path isn't equal to file path stored in
  undo block, search for imbuf in ima->ibufs.

  Probably it can be optimized, but storing all settings which defines
  needed imbuf (image source type, offset, image file name, current
  scene frame and so messes up undo code and requires deeper changes
  which probably better not to start on bcon4).

source/blender/editors/sculpt_paint/paint_image.c

index add269c087700d1fa396f1f84fed2d1711de12da..43969f3c19e8b70046503c82d115e42433f6e4c4 100644 (file)
@@ -356,6 +356,7 @@ typedef struct UndoImageTile {
        struct UndoImageTile *next, *prev;
 
        char idname[MAX_ID_NAME];       /* name instead of pointer*/
+       char ibufname[IB_FILENAME_SIZE];
 
        void *rect;
        int x, y;
@@ -389,7 +390,7 @@ static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int
        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)
+               if(tile->x == x_tile && tile->y == y_tile && strcmp(tile->idname, ima->id.name)==0 && strcmp(tile->ibufname, ibuf->name)==0)
                        return tile->rect;
        
        if (*tmpibuf==NULL)
@@ -404,6 +405,8 @@ static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int
        allocsize *= (ibuf->rect_float)? sizeof(float): sizeof(char);
        tile->rect= MEM_mapallocN(allocsize, "UndeImageTile.rect");
 
+       strcpy(tile->ibufname, ibuf->name);
+
        undo_copy_tile(tile, *tmpibuf, ibuf, 0);
        undo_paint_push_count_alloc(UNDO_PAINT_IMAGE, allocsize);
 
@@ -433,6 +436,21 @@ static void image_undo_restore(bContext *C, ListBase *lb)
 
                ibuf= BKE_image_get_ibuf(ima, NULL);
 
+               if(ima && strcmp(tile->ibufname, ibuf->name)!=0) {
+                       /* current ImBuf filename was changed, probably current frame
+                          was changed when paiting on image sequence, rather than storing
+                          full image user (which isn't so obvious, btw) try to find ImBuf with
+                          matched file name in list of already loaded images */
+
+                       ibuf= ima->ibufs.first;
+                       while(ibuf) {
+                               if(strcmp(tile->ibufname, ibuf->name)==0)
+                                       break;
+
+                               ibuf= ibuf->next;
+                       }
+               }
+
                if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
                        continue;