diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_image_undo.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image_undo.c | 806 |
1 files changed, 416 insertions, 390 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image_undo.c b/source/blender/editors/sculpt_paint/paint_image_undo.c index 8c4bfe00654..68abdfbf95b 100644 --- a/source/blender/editors/sculpt_paint/paint_image_undo.c +++ b/source/blender/editors/sculpt_paint/paint_image_undo.c @@ -55,26 +55,26 @@ * \{ */ typedef struct UndoImageTile { - struct UndoImageTile *next, *prev; + struct UndoImageTile *next, *prev; - char ibufname[IMB_FILENAME_SIZE]; + char ibufname[IMB_FILENAME_SIZE]; - union { - float *fp; - unsigned int *uint; - void *pt; - } rect; + union { + float *fp; + unsigned int *uint; + void *pt; + } rect; - unsigned short *mask; + unsigned short *mask; - int x, y; + int x, y; - Image *ima; - short source, use_float; - char gen_type; - bool valid; + Image *ima; + short source, use_float; + char gen_type; + bool valid; - size_t undo_size; + size_t undo_size; } UndoImageTile; /* this is a static resource for non-globality, @@ -84,281 +84,305 @@ static SpinLock undolock; void image_undo_init_locks(void) { - BLI_spin_init(&undolock); + BLI_spin_init(&undolock); } void image_undo_end_locks(void) { - BLI_spin_end(&undolock); + BLI_spin_end(&undolock); } /* UNDO */ typedef enum { - COPY = 0, - RESTORE = 1, - RESTORE_COPY = 2, + COPY = 0, + RESTORE = 1, + RESTORE_COPY = 2, } CopyMode; static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, CopyMode mode) { - if (mode == COPY) { - /* copy or swap contents of tile->rect and region in ibuf->rect */ - IMB_rectcpy( - tmpibuf, ibuf, 0, 0, tile->x * IMAPAINT_TILE_SIZE, - tile->y * IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE); - - if (ibuf->rect_float) { - SWAP(float *, tmpibuf->rect_float, tile->rect.fp); - } - else { - SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint); - } - } - else { - if (mode == RESTORE_COPY) { - IMB_rectcpy( - tmpibuf, ibuf, 0, 0, tile->x * IMAPAINT_TILE_SIZE, - tile->y * IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE); - } - /* swap to the tmpbuf for easy copying */ - if (ibuf->rect_float) { - SWAP(float *, tmpibuf->rect_float, tile->rect.fp); - } - else { - SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint); - } - - IMB_rectcpy( - ibuf, tmpibuf, tile->x * IMAPAINT_TILE_SIZE, - tile->y * IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE); - - if (mode == RESTORE) { - if (ibuf->rect_float) { - SWAP(float *, tmpibuf->rect_float, tile->rect.fp); - } - else { - SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint); - } - } - } + if (mode == COPY) { + /* copy or swap contents of tile->rect and region in ibuf->rect */ + IMB_rectcpy(tmpibuf, + ibuf, + 0, + 0, + tile->x * IMAPAINT_TILE_SIZE, + tile->y * IMAPAINT_TILE_SIZE, + IMAPAINT_TILE_SIZE, + IMAPAINT_TILE_SIZE); + + if (ibuf->rect_float) { + SWAP(float *, tmpibuf->rect_float, tile->rect.fp); + } + else { + SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint); + } + } + else { + if (mode == RESTORE_COPY) { + IMB_rectcpy(tmpibuf, + ibuf, + 0, + 0, + tile->x * IMAPAINT_TILE_SIZE, + tile->y * IMAPAINT_TILE_SIZE, + IMAPAINT_TILE_SIZE, + IMAPAINT_TILE_SIZE); + } + /* swap to the tmpbuf for easy copying */ + if (ibuf->rect_float) { + SWAP(float *, tmpibuf->rect_float, tile->rect.fp); + } + else { + SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint); + } + + IMB_rectcpy(ibuf, + tmpibuf, + tile->x * IMAPAINT_TILE_SIZE, + tile->y * IMAPAINT_TILE_SIZE, + 0, + 0, + IMAPAINT_TILE_SIZE, + IMAPAINT_TILE_SIZE); + + if (mode == RESTORE) { + if (ibuf->rect_float) { + SWAP(float *, tmpibuf->rect_float, tile->rect.fp); + } + else { + SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint); + } + } + } } -void *image_undo_find_tile( - ListBase *undo_tiles, - Image *ima, ImBuf *ibuf, int x_tile, int y_tile, unsigned short **mask, bool validate) +void *image_undo_find_tile(ListBase *undo_tiles, + Image *ima, + ImBuf *ibuf, + int x_tile, + int y_tile, + unsigned short **mask, + bool validate) { - UndoImageTile *tile; - short use_float = ibuf->rect_float ? 1 : 0; - - for (tile = undo_tiles->first; tile; tile = tile->next) { - if (tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && ima->source == tile->source) { - if (tile->use_float == use_float) { - if (STREQ(tile->ibufname, ibuf->name)) { - if (mask) { - /* allocate mask if requested */ - if (!tile->mask) { - tile->mask = MEM_callocN( - sizeof(unsigned short) * IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE, - "UndoImageTile.mask"); - } - - *mask = tile->mask; - } - if (validate) { - tile->valid = true; - } - return tile->rect.pt; - } - } - } - } - - return NULL; + UndoImageTile *tile; + short use_float = ibuf->rect_float ? 1 : 0; + + for (tile = undo_tiles->first; tile; tile = tile->next) { + if (tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && + ima->source == tile->source) { + if (tile->use_float == use_float) { + if (STREQ(tile->ibufname, ibuf->name)) { + if (mask) { + /* allocate mask if requested */ + if (!tile->mask) { + tile->mask = MEM_callocN(sizeof(unsigned short) * IMAPAINT_TILE_SIZE * + IMAPAINT_TILE_SIZE, + "UndoImageTile.mask"); + } + + *mask = tile->mask; + } + if (validate) { + tile->valid = true; + } + return tile->rect.pt; + } + } + } + } + + return NULL; } -void *image_undo_push_tile( - ListBase *undo_tiles, - Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile, - unsigned short **mask, bool **valid, bool proj, bool find_prev) +void *image_undo_push_tile(ListBase *undo_tiles, + Image *ima, + ImBuf *ibuf, + ImBuf **tmpibuf, + int x_tile, + int y_tile, + unsigned short **mask, + bool **valid, + bool proj, + bool find_prev) { - UndoImageTile *tile; - int allocsize; - short use_float = ibuf->rect_float ? 1 : 0; - void *data; - - /* check if tile is already pushed */ - - /* in projective painting we keep accounting of tiles, so if we need one pushed, just push! */ - if (find_prev) { - data = image_undo_find_tile(undo_tiles, ima, ibuf, x_tile, y_tile, mask, true); - if (data) { - return data; - } - } - - if (*tmpibuf == NULL) { - *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect); - } - - tile = MEM_callocN(sizeof(UndoImageTile), "UndoImageTile"); - tile->x = x_tile; - tile->y = y_tile; - - /* add mask explicitly here */ - if (mask) { - *mask = tile->mask = MEM_callocN( - sizeof(unsigned short) * IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE, - "UndoImageTile.mask"); - } - allocsize = IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE * 4; - allocsize *= (ibuf->rect_float) ? sizeof(float) : sizeof(char); - tile->rect.pt = MEM_mapallocN(allocsize, "UndeImageTile.rect"); - - BLI_strncpy(tile->ibufname, ibuf->name, sizeof(tile->ibufname)); - - tile->gen_type = ima->gen_type; - tile->source = ima->source; - tile->use_float = use_float; - tile->valid = true; - tile->ima = ima; - - if (valid) { - *valid = &tile->valid; - } - undo_copy_tile(tile, *tmpibuf, ibuf, COPY); - - if (proj) { - BLI_spin_lock(&undolock); - } - BLI_addtail(undo_tiles, tile); - - if (proj) { - BLI_spin_unlock(&undolock); - } - return tile->rect.pt; + UndoImageTile *tile; + int allocsize; + short use_float = ibuf->rect_float ? 1 : 0; + void *data; + + /* check if tile is already pushed */ + + /* in projective painting we keep accounting of tiles, so if we need one pushed, just push! */ + if (find_prev) { + data = image_undo_find_tile(undo_tiles, ima, ibuf, x_tile, y_tile, mask, true); + if (data) { + return data; + } + } + + if (*tmpibuf == NULL) { + *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect); + } + + tile = MEM_callocN(sizeof(UndoImageTile), "UndoImageTile"); + tile->x = x_tile; + tile->y = y_tile; + + /* add mask explicitly here */ + if (mask) { + *mask = tile->mask = MEM_callocN( + sizeof(unsigned short) * IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE, "UndoImageTile.mask"); + } + allocsize = IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE * 4; + allocsize *= (ibuf->rect_float) ? sizeof(float) : sizeof(char); + tile->rect.pt = MEM_mapallocN(allocsize, "UndeImageTile.rect"); + + BLI_strncpy(tile->ibufname, ibuf->name, sizeof(tile->ibufname)); + + tile->gen_type = ima->gen_type; + tile->source = ima->source; + tile->use_float = use_float; + tile->valid = true; + tile->ima = ima; + + if (valid) { + *valid = &tile->valid; + } + undo_copy_tile(tile, *tmpibuf, ibuf, COPY); + + if (proj) { + BLI_spin_lock(&undolock); + } + BLI_addtail(undo_tiles, tile); + + if (proj) { + BLI_spin_unlock(&undolock); + } + return tile->rect.pt; } void image_undo_remove_masks(void) { - ListBase *undo_tiles = ED_image_undo_get_tiles(); - UndoImageTile *tile; - - for (tile = undo_tiles->first; tile; tile = tile->next) { - if (tile->mask) { - MEM_freeN(tile->mask); - tile->mask = NULL; - } - } + ListBase *undo_tiles = ED_image_undo_get_tiles(); + UndoImageTile *tile; + + for (tile = undo_tiles->first; tile; tile = tile->next) { + if (tile->mask) { + MEM_freeN(tile->mask); + tile->mask = NULL; + } + } } static void image_undo_restore_runtime(ListBase *lb) { - ImBuf *ibuf, *tmpibuf; - UndoImageTile *tile; + ImBuf *ibuf, *tmpibuf; + UndoImageTile *tile; - tmpibuf = IMB_allocImBuf( - IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, - IB_rectfloat | IB_rect); + tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect); - for (tile = lb->first; tile; tile = tile->next) { - Image *ima = tile->ima; - ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + for (tile = lb->first; tile; tile = tile->next) { + Image *ima = tile->ima; + ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - undo_copy_tile(tile, tmpibuf, ibuf, RESTORE); + undo_copy_tile(tile, tmpibuf, ibuf, RESTORE); - GPU_free_image(ima); /* force OpenGL reload (maybe partial update will operate better?) */ - if (ibuf->rect_float) { - ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */ - } - if (ibuf->mipmap[0]) { - ibuf->userflags |= IB_MIPMAP_INVALID; /* force mipmap recreatiom */ - } - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + GPU_free_image(ima); /* force OpenGL reload (maybe partial update will operate better?) */ + if (ibuf->rect_float) { + ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */ + } + if (ibuf->mipmap[0]) { + ibuf->userflags |= IB_MIPMAP_INVALID; /* force mipmap recreatiom */ + } + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - BKE_image_release_ibuf(ima, ibuf, NULL); - } + BKE_image_release_ibuf(ima, ibuf, NULL); + } - IMB_freeImBuf(tmpibuf); + IMB_freeImBuf(tmpibuf); } static void image_undo_restore_list(ListBase *lb, struct UndoIDPtrMap *id_map) { - ImBuf *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect); + ImBuf *tmpibuf = IMB_allocImBuf( + IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect); - /* Store last found image. */ - ID *image_prev[2] = {NULL}; + /* Store last found image. */ + ID *image_prev[2] = {NULL}; - for (UndoImageTile *tile = lb->first; tile; tile = tile->next) { - short use_float; + for (UndoImageTile *tile = lb->first; tile; tile = tile->next) { + short use_float; - Image *ima = (Image *)BKE_undosys_ID_map_lookup_with_prev(id_map, &tile->ima->id, image_prev); + Image *ima = (Image *)BKE_undosys_ID_map_lookup_with_prev(id_map, &tile->ima->id, image_prev); - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - if (ima && ibuf && !STREQ(tile->ibufname, ibuf->name)) { - /* current ImBuf filename was changed, probably current frame - * was changed when painting 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 */ + if (ima && ibuf && !STREQ(tile->ibufname, ibuf->name)) { + /* current ImBuf filename was changed, probably current frame + * was changed when painting 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 */ - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_release_ibuf(ima, ibuf, NULL); - ibuf = BKE_image_get_ibuf_with_name(ima, tile->ibufname); - } + ibuf = BKE_image_get_ibuf_with_name(ima, tile->ibufname); + } - if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) { - BKE_image_release_ibuf(ima, ibuf, NULL); - continue; - } + if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) { + BKE_image_release_ibuf(ima, ibuf, NULL); + continue; + } - if (ima->gen_type != tile->gen_type || ima->source != tile->source) { - BKE_image_release_ibuf(ima, ibuf, NULL); - continue; - } + if (ima->gen_type != tile->gen_type || ima->source != tile->source) { + BKE_image_release_ibuf(ima, ibuf, NULL); + continue; + } - use_float = ibuf->rect_float ? 1 : 0; + use_float = ibuf->rect_float ? 1 : 0; - if (use_float != tile->use_float) { - BKE_image_release_ibuf(ima, ibuf, NULL); - continue; - } + if (use_float != tile->use_float) { + BKE_image_release_ibuf(ima, ibuf, NULL); + continue; + } - undo_copy_tile(tile, tmpibuf, ibuf, RESTORE_COPY); + undo_copy_tile(tile, tmpibuf, ibuf, RESTORE_COPY); - GPU_free_image(ima); /* force OpenGL reload */ - if (ibuf->rect_float) { - ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */ - } - if (ibuf->mipmap[0]) { - ibuf->userflags |= IB_MIPMAP_INVALID; /* force mipmap recreatiom */ - } - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + GPU_free_image(ima); /* force OpenGL reload */ + if (ibuf->rect_float) { + ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */ + } + if (ibuf->mipmap[0]) { + ibuf->userflags |= IB_MIPMAP_INVALID; /* force mipmap recreatiom */ + } + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - DEG_id_tag_update(&ima->id, 0); + DEG_id_tag_update(&ima->id, 0); - BKE_image_release_ibuf(ima, ibuf, NULL); - } + BKE_image_release_ibuf(ima, ibuf, NULL); + } - IMB_freeImBuf(tmpibuf); + IMB_freeImBuf(tmpibuf); } static void image_undo_free_list(ListBase *lb) { - for (UndoImageTile *tile = lb->first, *tile_next; tile; tile = tile_next) { - tile_next = tile->next; - MEM_freeN(tile->rect.pt); - MEM_freeN(tile); - } + for (UndoImageTile *tile = lb->first, *tile_next; tile; tile = tile_next) { + tile_next = tile->next; + MEM_freeN(tile->rect.pt); + MEM_freeN(tile); + } } static void image_undo_invalidate(void) { - UndoImageTile *tile; - ListBase *lb = ED_image_undo_get_tiles(); + UndoImageTile *tile; + ListBase *lb = ED_image_undo_get_tiles(); - for (tile = lb->first; tile; tile = tile->next) { - tile->valid = false; - } + for (tile = lb->first; tile; tile = tile->next) { + tile->valid = false; + } } /** \} */ @@ -368,258 +392,260 @@ static void image_undo_invalidate(void) * \{ */ typedef struct ImageUndoStep { - UndoStep step; - ListBase tiles; - bool is_encode_init; - ePaintMode paint_mode; + UndoStep step; + ListBase tiles; + bool is_encode_init; + ePaintMode paint_mode; - /* Use for all ID lookups (can be NULL). */ - struct UndoIDPtrMap *id_map; + /* Use for all ID lookups (can be NULL). */ + struct UndoIDPtrMap *id_map; } ImageUndoStep; static void image_undosys_step_encode_store_ids(ImageUndoStep *us) { - us->id_map = BKE_undosys_ID_map_create(); + us->id_map = BKE_undosys_ID_map_create(); - ID *image_prev = NULL; - for (UndoImageTile *tile = us->tiles.first; tile; tile = tile->next) { - BKE_undosys_ID_map_add_with_prev(us->id_map, &tile->ima->id, &image_prev); - } + ID *image_prev = NULL; + for (UndoImageTile *tile = us->tiles.first; tile; tile = tile->next) { + BKE_undosys_ID_map_add_with_prev(us->id_map, &tile->ima->id, &image_prev); + } } /* Restore at runtime. */ #if 0 static void paint_undosys_step_decode_restore_ids(ImageUndoStep *us) { - ID *image_prev[2] = {NULL}; - for (UndoImageTile *tile = us->tiles.first; tile; tile = tile->next) { - tile->ima = (Image *)BKE_undosys_ID_map_lookup_with_prev(us->id_map, &tile->ima->id, image_prev); - } + ID *image_prev[2] = {NULL}; + for (UndoImageTile *tile = us->tiles.first; tile; tile = tile->next) { + tile->ima = (Image *)BKE_undosys_ID_map_lookup_with_prev(us->id_map, &tile->ima->id, image_prev); + } } #endif static bool image_undosys_poll(bContext *C) { - Object *obact = CTX_data_active_object(C); - - ScrArea *sa = CTX_wm_area(C); - if (sa && (sa->spacetype == SPACE_IMAGE)) { - SpaceImage *sima = (SpaceImage *)sa->spacedata.first; - if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || - (sima->mode == SI_MODE_PAINT)) - { - return true; - } - } - else { - if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) { - return true; - } - } - return false; + Object *obact = CTX_data_active_object(C); + + ScrArea *sa = CTX_wm_area(C); + if (sa && (sa->spacetype == SPACE_IMAGE)) { + SpaceImage *sima = (SpaceImage *)sa->spacedata.first; + if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { + return true; + } + } + else { + if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) { + return true; + } + } + return false; } static void image_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p) { - ImageUndoStep *us = (ImageUndoStep *)us_p; - /* dummy, memory is cleared anyway. */ - us->is_encode_init = true; - BLI_listbase_clear(&us->tiles); + ImageUndoStep *us = (ImageUndoStep *)us_p; + /* dummy, memory is cleared anyway. */ + us->is_encode_init = true; + BLI_listbase_clear(&us->tiles); } -static bool image_undosys_step_encode(struct bContext *C, struct Main *UNUSED(bmain), UndoStep *us_p) +static bool image_undosys_step_encode(struct bContext *C, + struct Main *UNUSED(bmain), + UndoStep *us_p) { - /* dummy, encoding is done along the way by adding tiles - * to the current 'ImageUndoStep' added by encode_init. */ - ImageUndoStep *us = (ImageUndoStep *)us_p; - - BLI_assert(us->step.data_size == 0); - - int allocsize = IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE * 4; - - if (us->is_encode_init) { - /* first dispose of invalid tiles (may happen due to drag dot for instance) */ - for (UndoImageTile *tile = us->tiles.first; tile;) { - if (!tile->valid) { - UndoImageTile *tmp_tile = tile->next; - MEM_freeN(tile->rect.pt); - BLI_freelinkN(&us->tiles, tile); - tile = tmp_tile; - } - else { - us->step.data_size += allocsize * ((tile->use_float) ? sizeof(float) : sizeof(char)); - tile = tile->next; - } - } - } - else { - /* Happens when switching modes. */ - ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C); - BLI_assert(ELEM(paint_mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D)); - us->paint_mode = paint_mode; - } - - image_undosys_step_encode_store_ids(us); - - us_p->is_applied = true; - - return true; + /* dummy, encoding is done along the way by adding tiles + * to the current 'ImageUndoStep' added by encode_init. */ + ImageUndoStep *us = (ImageUndoStep *)us_p; + + BLI_assert(us->step.data_size == 0); + + int allocsize = IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE * 4; + + if (us->is_encode_init) { + /* first dispose of invalid tiles (may happen due to drag dot for instance) */ + for (UndoImageTile *tile = us->tiles.first; tile;) { + if (!tile->valid) { + UndoImageTile *tmp_tile = tile->next; + MEM_freeN(tile->rect.pt); + BLI_freelinkN(&us->tiles, tile); + tile = tmp_tile; + } + else { + us->step.data_size += allocsize * ((tile->use_float) ? sizeof(float) : sizeof(char)); + tile = tile->next; + } + } + } + else { + /* Happens when switching modes. */ + ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C); + BLI_assert(ELEM(paint_mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D)); + us->paint_mode = paint_mode; + } + + image_undosys_step_encode_store_ids(us); + + us_p->is_applied = true; + + return true; } - static void image_undosys_step_decode_undo_impl(ImageUndoStep *us) { - BLI_assert(us->step.is_applied == true); - image_undo_restore_list(&us->tiles, us->id_map); - us->step.is_applied = false; + BLI_assert(us->step.is_applied == true); + image_undo_restore_list(&us->tiles, us->id_map); + us->step.is_applied = false; } static void image_undosys_step_decode_redo_impl(ImageUndoStep *us) { - BLI_assert(us->step.is_applied == false); - image_undo_restore_list(&us->tiles, us->id_map); - us->step.is_applied = true; + BLI_assert(us->step.is_applied == false); + image_undo_restore_list(&us->tiles, us->id_map); + us->step.is_applied = true; } static void image_undosys_step_decode_undo(ImageUndoStep *us) { - ImageUndoStep *us_iter = us; - while (us_iter->step.next && (us_iter->step.next->type == us_iter->step.type)) { - if (us_iter->step.next->is_applied == false) { - break; - } - us_iter = (ImageUndoStep *)us_iter->step.next; - } - while (us_iter != us) { - image_undosys_step_decode_undo_impl(us_iter); - us_iter = (ImageUndoStep *)us_iter->step.prev; - } + ImageUndoStep *us_iter = us; + while (us_iter->step.next && (us_iter->step.next->type == us_iter->step.type)) { + if (us_iter->step.next->is_applied == false) { + break; + } + us_iter = (ImageUndoStep *)us_iter->step.next; + } + while (us_iter != us) { + image_undosys_step_decode_undo_impl(us_iter); + us_iter = (ImageUndoStep *)us_iter->step.prev; + } } static void image_undosys_step_decode_redo(ImageUndoStep *us) { - ImageUndoStep *us_iter = us; - while (us_iter->step.prev && (us_iter->step.prev->type == us_iter->step.type)) { - if (us_iter->step.prev->is_applied == true) { - break; - } - us_iter = (ImageUndoStep *)us_iter->step.prev; - } - while (us_iter && (us_iter->step.is_applied == false)) { - image_undosys_step_decode_redo_impl(us_iter); - if (us_iter == us) { - break; - } - us_iter = (ImageUndoStep *)us_iter->step.next; - } + ImageUndoStep *us_iter = us; + while (us_iter->step.prev && (us_iter->step.prev->type == us_iter->step.type)) { + if (us_iter->step.prev->is_applied == true) { + break; + } + us_iter = (ImageUndoStep *)us_iter->step.prev; + } + while (us_iter && (us_iter->step.is_applied == false)) { + image_undosys_step_decode_redo_impl(us_iter); + if (us_iter == us) { + break; + } + us_iter = (ImageUndoStep *)us_iter->step.next; + } } -static void image_undosys_step_decode(struct bContext *C, struct Main *bmain, UndoStep *us_p, int dir) +static void image_undosys_step_decode(struct bContext *C, + struct Main *bmain, + UndoStep *us_p, + int dir) { - ImageUndoStep *us = (ImageUndoStep *)us_p; + ImageUndoStep *us = (ImageUndoStep *)us_p; #if 0 - paint_undosys_step_decode_restore_ids(us); + paint_undosys_step_decode_restore_ids(us); #endif - if (dir < 0) { - image_undosys_step_decode_undo(us); - } - else { - image_undosys_step_decode_redo(us); - } + if (dir < 0) { + image_undosys_step_decode_undo(us); + } + else { + image_undosys_step_decode_redo(us); + } - if (us->paint_mode == PAINT_MODE_TEXTURE_3D) { - ED_object_mode_set(C, OB_MODE_TEXTURE_PAINT); - } + if (us->paint_mode == PAINT_MODE_TEXTURE_3D) { + ED_object_mode_set(C, OB_MODE_TEXTURE_PAINT); + } - /* Refresh texture slots. */ - ED_editors_init_for_undo(bmain); + /* Refresh texture slots. */ + ED_editors_init_for_undo(bmain); } static void image_undosys_step_free(UndoStep *us_p) { - ImageUndoStep *us = (ImageUndoStep *)us_p; - image_undo_free_list(&us->tiles); - BKE_undosys_ID_map_destroy(us->id_map); + ImageUndoStep *us = (ImageUndoStep *)us_p; + image_undo_free_list(&us->tiles); + BKE_undosys_ID_map_destroy(us->id_map); } -static void image_undosys_foreach_ID_ref( - UndoStep *us_p, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data) +static void image_undosys_foreach_ID_ref(UndoStep *us_p, + UndoTypeForEachIDRefFn foreach_ID_ref_fn, + void *user_data) { - ImageUndoStep *us = (ImageUndoStep *)us_p; - if (us->id_map != NULL) { - BKE_undosys_ID_map_foreach_ID_ref(us->id_map, foreach_ID_ref_fn, user_data); - } + ImageUndoStep *us = (ImageUndoStep *)us_p; + if (us->id_map != NULL) { + BKE_undosys_ID_map_foreach_ID_ref(us->id_map, foreach_ID_ref_fn, user_data); + } } /* Export for ED_undo_sys. */ void ED_image_undosys_type(UndoType *ut) { - ut->name = "Image"; - ut->poll = image_undosys_poll; - ut->step_encode_init = image_undosys_step_encode_init; - ut->step_encode = image_undosys_step_encode; - ut->step_decode = image_undosys_step_decode; - ut->step_free = image_undosys_step_free; + ut->name = "Image"; + ut->poll = image_undosys_poll; + ut->step_encode_init = image_undosys_step_encode_init; + ut->step_encode = image_undosys_step_encode; + ut->step_decode = image_undosys_step_decode; + ut->step_free = image_undosys_step_free; - ut->step_foreach_ID_ref = image_undosys_foreach_ID_ref; + ut->step_foreach_ID_ref = image_undosys_foreach_ID_ref; - ut->use_context = true; + ut->use_context = true; - ut->step_size = sizeof(ImageUndoStep); + ut->step_size = sizeof(ImageUndoStep); } /** \} */ - /* -------------------------------------------------------------------- */ /** \name Utilities * \{ */ ListBase *ED_image_undosys_step_get_tiles(UndoStep *us_p) { - ImageUndoStep *us = (ImageUndoStep *)us_p; - return &us->tiles; + ImageUndoStep *us = (ImageUndoStep *)us_p; + return &us->tiles; } ListBase *ED_image_undo_get_tiles(void) { - UndoStack *ustack = ED_undo_stack_get(); - UndoStep *us_prev = ustack->step_init; - UndoStep *us_p = BKE_undosys_stack_init_or_active_with_type(ustack, BKE_UNDOSYS_TYPE_IMAGE); - ImageUndoStep *us = (ImageUndoStep *)us_p; - /* We should always have an undo push started when accessing tiles, - * not doing this means we won't have paint_mode correctly set. */ - BLI_assert(us_p == us_prev); - if (us_p != us_prev) { - /* Fallback value until we can be sure this never happens. */ - us->paint_mode = PAINT_MODE_TEXTURE_2D; - } - return ED_image_undosys_step_get_tiles(us_p); + UndoStack *ustack = ED_undo_stack_get(); + UndoStep *us_prev = ustack->step_init; + UndoStep *us_p = BKE_undosys_stack_init_or_active_with_type(ustack, BKE_UNDOSYS_TYPE_IMAGE); + ImageUndoStep *us = (ImageUndoStep *)us_p; + /* We should always have an undo push started when accessing tiles, + * not doing this means we won't have paint_mode correctly set. */ + BLI_assert(us_p == us_prev); + if (us_p != us_prev) { + /* Fallback value until we can be sure this never happens. */ + us->paint_mode = PAINT_MODE_TEXTURE_2D; + } + return ED_image_undosys_step_get_tiles(us_p); } /* restore painting image to previous state. Used for anchored and drag-dot style brushes*/ void ED_image_undo_restore(UndoStep *us) { - ListBase *lb = ED_image_undosys_step_get_tiles(us); - image_undo_restore_runtime(lb); - image_undo_invalidate(); + ListBase *lb = ED_image_undosys_step_get_tiles(us); + image_undo_restore_runtime(lb); + image_undo_invalidate(); } void ED_image_undo_push_begin(const char *name, int paint_mode) { - UndoStack *ustack = ED_undo_stack_get(); - bContext *C = NULL; /* special case, we never read from this. */ - UndoStep *us_p = BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_IMAGE); - ImageUndoStep *us = (ImageUndoStep *)us_p; - BLI_assert(ELEM(paint_mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D)); - us->paint_mode = paint_mode; + UndoStack *ustack = ED_undo_stack_get(); + bContext *C = NULL; /* special case, we never read from this. */ + UndoStep *us_p = BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_IMAGE); + ImageUndoStep *us = (ImageUndoStep *)us_p; + BLI_assert(ELEM(paint_mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D)); + us->paint_mode = paint_mode; } void ED_image_undo_push_end(void) { - UndoStack *ustack = ED_undo_stack_get(); - BKE_undosys_step_push(ustack, NULL, NULL); + UndoStack *ustack = ED_undo_stack_get(); + BKE_undosys_step_push(ustack, NULL, NULL); } /** \} */ |