Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-10-01 18:44:27 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-10-01 18:45:37 +0300
commit7aff48add08a875138d3a65c16811c8cb0e5eae1 (patch)
treee9e77912436bc037413803c559a180c9fa9e47d6 /source/blender/editors/sculpt_paint
parentcc092e9ab0c2e1877fe5d33724c1fdc5fb16b522 (diff)
Cleanup: move image undo into space_image/
This isn't just used for painting.
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt1
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_undo.c1037
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h28
3 files changed, 0 insertions, 1066 deletions
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index c8057686c5e..a5cc262ddcd 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -48,7 +48,6 @@ set(SRC
paint_image.c
paint_image_2d.c
paint_image_proj.c
- paint_image_undo.c
paint_mask.c
paint_ops.c
paint_stroke.c
diff --git a/source/blender/editors/sculpt_paint/paint_image_undo.c b/source/blender/editors/sculpt_paint/paint_image_undo.c
deleted file mode 100644
index 4cc12296e37..00000000000
--- a/source/blender/editors/sculpt_paint/paint_image_undo.c
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup edsculpt
- *
- * Overview
- * ========
- *
- * - Each undo step is a #ImageUndoStep
- * - Each #ImageUndoStep stores a list of #UndoImageHandle
- * - Each #UndoImageHandle stores a list of #UndoImageBuf
- * (this is the undo systems equivalent of an #ImBuf).
- * - Each #UndoImageBuf stores an array of #UndoImageTile
- * The tiles are shared between #UndoImageBuf's to avoid duplication.
- *
- * When the undo system manages an image, there will always be a full copy (as a #UndoImageBuf)
- * each new undo step only stores modified tiles.
- */
-
-#include "CLG_log.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-#include "BLI_threads.h"
-
-#include "DNA_image_types.h"
-#include "DNA_windowmanager_types.h"
-#include "DNA_object_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
-
-#include "BKE_context.h"
-#include "BKE_image.h"
-#include "BKE_paint.h"
-#include "BKE_undo_system.h"
-
-#include "DEG_depsgraph.h"
-
-#include "ED_paint.h"
-#include "ED_undo.h"
-#include "ED_util.h"
-#include "ED_object.h"
-
-#include "GPU_draw.h"
-
-#include "WM_api.h"
-
-#include "paint_intern.h"
-
-static CLG_LogRef LOG = {"ed.image.undo"};
-
-/* -------------------------------------------------------------------- */
-/** \name Thread Locking
- * \{ */
-
-/* this is a static resource for non-globality,
- * Maybe it should be exposed as part of the
- * paint operation, but for now just give a public interface */
-static SpinLock paint_tiles_lock;
-
-void image_undo_init_locks(void)
-{
- BLI_spin_init(&paint_tiles_lock);
-}
-
-void image_undo_end_locks(void)
-{
- BLI_spin_end(&paint_tiles_lock);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Paint Tiles
- *
- * Created on demand while painting,
- * use to access the previous state for some paint operations.
- *
- * These buffers are also used for undo when available.
- *
- * \{ */
-
-static ImBuf *imbuf_alloc_temp_tile(void)
-{
- return IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect);
-}
-
-typedef struct PaintTile {
- struct PaintTile *next, *prev;
- Image *image;
- ImBuf *ibuf;
- union {
- float *fp;
- uint *uint;
- void *pt;
- } rect;
- ushort *mask;
- bool valid;
- bool use_float;
- int x, y;
-} PaintTile;
-
-static void ptile_free(PaintTile *ptile)
-{
- if (ptile->rect.pt) {
- MEM_freeN(ptile->rect.pt);
- }
- MEM_freeN(ptile);
-}
-
-static void ptile_free_list(ListBase *paint_tiles)
-{
- for (PaintTile *ptile = paint_tiles->first, *ptile_next; ptile; ptile = ptile_next) {
- ptile_next = ptile->next;
- ptile_free(ptile);
- }
- BLI_listbase_clear(paint_tiles);
-}
-
-static void ptile_invalidate_list(ListBase *paint_tiles)
-{
- for (PaintTile *ptile = paint_tiles->first; ptile; ptile = ptile->next) {
- ptile->valid = false;
- }
-}
-
-void *image_undo_find_tile(ListBase *paint_tiles,
- Image *image,
- ImBuf *ibuf,
- int x_tile,
- int y_tile,
- ushort **r_mask,
- bool validate)
-{
- for (PaintTile *ptile = paint_tiles->first; ptile; ptile = ptile->next) {
- if (ptile->x == x_tile && ptile->y == y_tile) {
- if (ptile->image == image && ptile->ibuf == ibuf) {
- if (r_mask) {
- /* allocate mask if requested. */
- if (!ptile->mask) {
- ptile->mask = MEM_callocN(sizeof(ushort) * SQUARE(IMAPAINT_TILE_SIZE),
- "UndoImageTile.mask");
- }
- *r_mask = ptile->mask;
- }
- if (validate) {
- ptile->valid = true;
- }
- return ptile->rect.pt;
- }
- }
- }
- return NULL;
-}
-
-void image_undo_remove_masks(void)
-{
- ListBase *paint_tiles = ED_image_undo_get_tiles();
- for (PaintTile *ptile = paint_tiles->first; ptile; ptile = ptile->next) {
- MEM_SAFE_FREE(ptile->mask);
- }
-}
-
-void *image_undo_push_tile(ListBase *paint_tiles,
- Image *image,
- ImBuf *ibuf,
- ImBuf **tmpibuf,
- int x_tile,
- int y_tile,
- ushort **r_mask,
- bool **valid,
- bool proj,
- bool find_prev)
-{
- const bool has_float = (ibuf->rect_float != NULL);
-
- /* 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) {
- void *data = image_undo_find_tile(paint_tiles, image, ibuf, x_tile, y_tile, r_mask, true);
- if (data) {
- return data;
- }
- }
-
- if (*tmpibuf == NULL) {
- *tmpibuf = imbuf_alloc_temp_tile();
- }
-
- PaintTile *ptile = MEM_callocN(sizeof(PaintTile), "PaintTile");
-
- ptile->image = image;
- ptile->ibuf = ibuf;
-
- ptile->x = x_tile;
- ptile->y = y_tile;
-
- /* add mask explicitly here */
- if (r_mask) {
- *r_mask = ptile->mask = MEM_callocN(sizeof(ushort) * SQUARE(IMAPAINT_TILE_SIZE),
- "PaintTile.mask");
- }
-
- ptile->rect.pt = MEM_mapallocN((ibuf->rect_float ? sizeof(float[4]) : sizeof(char[4])) *
- SQUARE(IMAPAINT_TILE_SIZE),
- "PaintTile.rect");
-
- ptile->use_float = has_float;
- ptile->valid = true;
-
- if (valid) {
- *valid = &ptile->valid;
- }
-
- IMB_rectcpy(*tmpibuf,
- ibuf,
- 0,
- 0,
- x_tile * IMAPAINT_TILE_SIZE,
- y_tile * IMAPAINT_TILE_SIZE,
- IMAPAINT_TILE_SIZE,
- IMAPAINT_TILE_SIZE);
-
- if (has_float) {
- SWAP(float *, ptile->rect.fp, (*tmpibuf)->rect_float);
- }
- else {
- SWAP(uint *, ptile->rect.uint, (*tmpibuf)->rect);
- }
-
- if (proj) {
- BLI_spin_lock(&paint_tiles_lock);
- }
- BLI_addtail(paint_tiles, ptile);
-
- if (proj) {
- BLI_spin_unlock(&paint_tiles_lock);
- }
- return ptile->rect.pt;
-}
-
-static void ptile_restore_runtime_list(ListBase *paint_tiles)
-{
- ImBuf *tmpibuf = imbuf_alloc_temp_tile();
-
- for (PaintTile *ptile = paint_tiles->first; ptile; ptile = ptile->next) {
- Image *image = ptile->image;
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
- const bool has_float = (ibuf->rect_float != NULL);
-
- if (has_float) {
- SWAP(float *, ptile->rect.fp, tmpibuf->rect_float);
- }
- else {
- SWAP(uint *, ptile->rect.uint, tmpibuf->rect);
- }
-
- IMB_rectcpy(ibuf, tmpibuf, ptile->x, ptile->y, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
-
- if (has_float) {
- SWAP(float *, ptile->rect.fp, tmpibuf->rect_float);
- }
- else {
- SWAP(uint *, ptile->rect.uint, tmpibuf->rect);
- }
-
- GPU_free_image(image); /* 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 mip-map recreation. */
- }
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
-
- IMB_freeImBuf(tmpibuf);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Image Undo Tile
- * \{ */
-
-static uint index_from_xy(uint tile_x, uint tile_y, const uint tiles_dims[2])
-{
- BLI_assert(tile_x < tiles_dims[0] && tile_y < tiles_dims[1]);
- return (tile_y * tiles_dims[0]) + tile_x;
-}
-
-typedef struct UndoImageTile {
- union {
- float *fp;
- uint *uint;
- void *pt;
- } rect;
- int users;
-} UndoImageTile;
-
-static UndoImageTile *utile_alloc(bool has_float)
-{
- UndoImageTile *utile = MEM_callocN(sizeof(*utile), "ImageUndoTile");
- if (has_float) {
- utile->rect.fp = MEM_mallocN(sizeof(float[4]) * SQUARE(IMAPAINT_TILE_SIZE), __func__);
- }
- else {
- utile->rect.uint = MEM_mallocN(sizeof(uint) * SQUARE(IMAPAINT_TILE_SIZE), __func__);
- }
- return utile;
-}
-
-static void utile_init_from_imbuf(
- UndoImageTile *utile, const uint x, const uint y, const ImBuf *ibuf, ImBuf *tmpibuf)
-{
- const bool has_float = ibuf->rect_float;
-
- if (has_float) {
- SWAP(float *, utile->rect.fp, tmpibuf->rect_float);
- }
- else {
- SWAP(uint *, utile->rect.uint, tmpibuf->rect);
- }
-
- IMB_rectcpy(tmpibuf, ibuf, 0, 0, x, y, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
-
- if (has_float) {
- SWAP(float *, utile->rect.fp, tmpibuf->rect_float);
- }
- else {
- SWAP(uint *, utile->rect.uint, tmpibuf->rect);
- }
-}
-
-static void utile_restore(
- const UndoImageTile *utile, const uint x, const uint y, ImBuf *ibuf, ImBuf *tmpibuf)
-{
- const bool has_float = ibuf->rect_float;
- float *prev_rect_float = tmpibuf->rect_float;
- uint *prev_rect = tmpibuf->rect;
-
- if (has_float) {
- tmpibuf->rect_float = utile->rect.fp;
- }
- else {
- tmpibuf->rect = utile->rect.uint;
- }
-
- IMB_rectcpy(ibuf, tmpibuf, x, y, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
-
- tmpibuf->rect_float = prev_rect_float;
- tmpibuf->rect = prev_rect;
-}
-
-static void utile_decref(UndoImageTile *utile)
-{
- utile->users -= 1;
- BLI_assert(utile->users >= 0);
- if (utile->users == 0) {
- MEM_freeN(utile->rect.pt);
- MEM_freeN(utile);
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Image Undo Buffer
- * \{ */
-
-typedef struct UndoImageBuf {
- struct UndoImageBuf *next, *prev;
-
- /**
- * The buffer after the undo step has executed.
- */
- struct UndoImageBuf *post;
-
- char ibuf_name[IMB_FILENAME_SIZE];
-
- UndoImageTile **tiles;
-
- /** Can calculate these from dims, just for convenience. */
- uint tiles_len;
- uint tiles_dims[2];
-
- uint image_dims[2];
-
- /** Store variables from the image. */
- struct {
- short source;
- bool use_float;
- char gen_type;
- } image_state;
-
-} UndoImageBuf;
-
-static UndoImageBuf *ubuf_from_image_no_tiles(Image *image, const ImBuf *ibuf)
-{
- UndoImageBuf *ubuf = MEM_callocN(sizeof(*ubuf), __func__);
-
- ubuf->image_dims[0] = ibuf->x;
- ubuf->image_dims[1] = ibuf->y;
-
- ubuf->tiles_dims[0] = IMAPAINT_TILE_NUMBER(ubuf->image_dims[0]);
- ubuf->tiles_dims[1] = IMAPAINT_TILE_NUMBER(ubuf->image_dims[1]);
-
- ubuf->tiles_len = ubuf->tiles_dims[0] * ubuf->tiles_dims[1];
- ubuf->tiles = MEM_callocN(sizeof(*ubuf->tiles) * ubuf->tiles_len, __func__);
-
- BLI_strncpy(ubuf->ibuf_name, ibuf->name, sizeof(ubuf->ibuf_name));
- ubuf->image_state.gen_type = image->gen_type;
- ubuf->image_state.source = image->source;
- ubuf->image_state.use_float = ibuf->rect_float != NULL;
-
- return ubuf;
-}
-
-static void ubuf_from_image_all_tiles(UndoImageBuf *ubuf, const ImBuf *ibuf)
-{
- ImBuf *tmpibuf = imbuf_alloc_temp_tile();
-
- const bool has_float = ibuf->rect_float;
- int i = 0;
- for (uint y_tile = 0; y_tile < ubuf->tiles_dims[1]; y_tile += 1) {
- uint y = y_tile << IMAPAINT_TILE_BITS;
- for (uint x_tile = 0; x_tile < ubuf->tiles_dims[0]; x_tile += 1) {
- uint x = x_tile << IMAPAINT_TILE_BITS;
-
- BLI_assert(ubuf->tiles[i] == NULL);
- UndoImageTile *utile = utile_alloc(has_float);
- utile->users = 1;
- utile_init_from_imbuf(utile, x, y, ibuf, tmpibuf);
- ubuf->tiles[i] = utile;
-
- i += 1;
- }
- }
-
- IMB_freeImBuf(tmpibuf);
-}
-
-static void ubuf_free(UndoImageBuf *ubuf)
-{
- UndoImageBuf *ubuf_post = ubuf->post;
- for (uint i = 0; i < ubuf->tiles_len; i++) {
- UndoImageTile *utile = ubuf->tiles[i];
- utile_decref(utile);
- }
- MEM_freeN(ubuf->tiles);
- MEM_freeN(ubuf);
- if (ubuf_post) {
- ubuf_free(ubuf_post);
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Image Undo Handle
- * \{ */
-
-typedef struct UndoImageHandle {
- struct UndoImageHandle *next, *prev;
-
- /** Each undo handle refers to a single image which may have multiple buffers. */
- UndoRefID_Image image_ref;
-
- /**
- * List of #UndoImageBuf's to support multiple buffers per image.
- *
- * \note To properly support multiple buffers per image
- * we would need to store an #ImageUser for each #UndoImageBuf.
- * since when restoring the image we use:
- * `BKE_image_acquire_ibuf(image, NULL, NULL)`.
- */
- ListBase buffers;
-
-} UndoImageHandle;
-
-static void uhandle_restore_list(ListBase *undo_handles, bool use_init)
-{
- ImBuf *tmpibuf = imbuf_alloc_temp_tile();
-
- for (UndoImageHandle *uh = undo_handles->first; uh; uh = uh->next) {
- /* Tiles only added to second set of tiles. */
- Image *image = uh->image_ref.ptr;
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
- if (UNLIKELY(ibuf == NULL)) {
- CLOG_ERROR(&LOG, "Unable to get buffer for image '%s'", image->id.name + 2);
- continue;
- }
- bool changed = false;
- for (UndoImageBuf *ubuf_iter = uh->buffers.first; ubuf_iter; ubuf_iter = ubuf_iter->next) {
- UndoImageBuf *ubuf = use_init ? ubuf_iter : ubuf_iter->post;
- IMB_rect_size_set(ibuf, ubuf->image_dims);
- int i = 0;
- for (uint y_tile = 0; y_tile < ubuf->tiles_dims[1]; y_tile += 1) {
- uint y = y_tile << IMAPAINT_TILE_BITS;
- for (uint x_tile = 0; x_tile < ubuf->tiles_dims[0]; x_tile += 1) {
- uint x = x_tile << IMAPAINT_TILE_BITS;
- utile_restore(ubuf->tiles[i], x, y, ibuf, tmpibuf);
- changed = true;
- i += 1;
- }
- }
- }
-
- if (changed) {
- BKE_image_mark_dirty(image, ibuf);
- GPU_free_image(image); /* 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 mip-map recreation. */
- }
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-
- DEG_id_tag_update(&image->id, 0);
- }
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
-
- IMB_freeImBuf(tmpibuf);
-}
-
-static void uhandle_free_list(ListBase *undo_handles)
-{
- LISTBASE_FOREACH_MUTABLE (UndoImageHandle *, uh, undo_handles) {
- LISTBASE_FOREACH_MUTABLE (UndoImageBuf *, ubuf, &uh->buffers) {
- ubuf_free(ubuf);
- }
- MEM_freeN(uh);
- }
- BLI_listbase_clear(undo_handles);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Image Undo Internal Utilities
- * \{ */
-
-/** #UndoImageHandle utilities */
-
-static UndoImageBuf *uhandle_lookup_ubuf(UndoImageHandle *uh,
- const Image *UNUSED(image),
- const char *ibuf_name)
-{
- for (UndoImageBuf *ubuf = uh->buffers.first; ubuf; ubuf = ubuf->next) {
- if (STREQ(ubuf->ibuf_name, ibuf_name)) {
- return ubuf;
- }
- }
- return NULL;
-}
-
-static UndoImageBuf *uhandle_add_ubuf(UndoImageHandle *uh, Image *image, ImBuf *ibuf)
-{
- BLI_assert(uhandle_lookup_ubuf(uh, image, ibuf->name) == NULL);
- UndoImageBuf *ubuf = ubuf_from_image_no_tiles(image, ibuf);
- BLI_addtail(&uh->buffers, ubuf);
-
- ubuf->post = NULL;
-
- return ubuf;
-}
-
-static UndoImageBuf *uhandle_ensure_ubuf(UndoImageHandle *uh, Image *image, ImBuf *ibuf)
-{
- UndoImageBuf *ubuf = uhandle_lookup_ubuf(uh, image, ibuf->name);
- if (ubuf == NULL) {
- ubuf = uhandle_add_ubuf(uh, image, ibuf);
- }
- return ubuf;
-}
-
-static UndoImageHandle *uhandle_lookup_by_name(ListBase *undo_handles, const Image *image)
-{
- for (UndoImageHandle *uh = undo_handles->first; uh; uh = uh->next) {
- if (STREQ(image->id.name + 2, uh->image_ref.name + 2)) {
- return uh;
- }
- }
- return NULL;
-}
-
-static UndoImageHandle *uhandle_lookup(ListBase *undo_handles, const Image *image)
-{
- for (UndoImageHandle *uh = undo_handles->first; uh; uh = uh->next) {
- if (image == uh->image_ref.ptr) {
- return uh;
- }
- }
- return NULL;
-}
-
-static UndoImageHandle *uhandle_add(ListBase *undo_handles, Image *image)
-{
- BLI_assert(uhandle_lookup(undo_handles, image) == NULL);
- UndoImageHandle *uh = MEM_callocN(sizeof(*uh), __func__);
- uh->image_ref.ptr = image;
- BLI_addtail(undo_handles, uh);
- return uh;
-}
-
-static UndoImageHandle *uhandle_ensure(ListBase *undo_handles, Image *image)
-{
- UndoImageHandle *uh = uhandle_lookup(undo_handles, image);
- if (uh == NULL) {
- uh = uhandle_add(undo_handles, image);
- }
- return uh;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Implements ED Undo System
- * \{ */
-
-typedef struct ImageUndoStep {
- UndoStep step;
-
- /** #UndoImageHandle */
- ListBase handles;
-
- /**
- * #PaintTile
- * Run-time only data (active during a paint stroke).
- */
- ListBase paint_tiles;
-
- bool is_encode_init;
- ePaintMode paint_mode;
-
-} ImageUndoStep;
-
-/**
- * Find the previous undo buffer from this one.
- * \note We could look into undo steps even further back.
- */
-static UndoImageBuf *ubuf_lookup_from_reference(ImageUndoStep *us_prev,
- const Image *image,
- const UndoImageBuf *ubuf)
-{
- /* Use name lookup because because the pointer is cleared for previous steps. */
- UndoImageHandle *uh_prev = uhandle_lookup_by_name(&us_prev->handles, image);
- if (uh_prev != NULL) {
- UndoImageBuf *ubuf_reference = uhandle_lookup_ubuf(uh_prev, image, ubuf->ibuf_name);
- if (ubuf_reference) {
- ubuf_reference = ubuf_reference->post;
- if ((ubuf_reference->image_dims[0] == ubuf->image_dims[0]) &&
- (ubuf_reference->image_dims[1] == ubuf->image_dims[1])) {
- return ubuf_reference;
- }
- }
- }
- return NULL;
-}
-
-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;
-}
-
-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->handles);
- BLI_listbase_clear(&us->paint_tiles);
-}
-
-static bool image_undosys_step_encode(struct bContext *C,
- struct Main *UNUSED(bmain),
- UndoStep *us_p)
-{
- /* Encoding is done along the way by adding tiles
- * to the current 'ImageUndoStep' added by encode_init.
- *
- * This function ensures there are previous and current states of the image in the undo buffer.
- */
- ImageUndoStep *us = (ImageUndoStep *)us_p;
-
- BLI_assert(us->step.data_size == 0);
-
- if (us->is_encode_init) {
-
- ImBuf *tmpibuf = imbuf_alloc_temp_tile();
-
- ImageUndoStep *us_reference = (ImageUndoStep *)ED_undo_stack_get()->step_active;
- while (us_reference && us_reference->step.type != BKE_UNDOSYS_TYPE_IMAGE) {
- us_reference = (ImageUndoStep *)us_reference->step.prev;
- }
-
- /* Initialize undo tiles from ptiles (if they exist). */
- for (PaintTile *ptile = us->paint_tiles.first, *ptile_next; ptile; ptile = ptile_next) {
- if (ptile->valid) {
- UndoImageHandle *uh = uhandle_ensure(&us->handles, ptile->image);
- UndoImageBuf *ubuf_pre = uhandle_ensure_ubuf(uh, ptile->image, ptile->ibuf);
-
- UndoImageTile *utile = MEM_callocN(sizeof(*utile), "UndoImageTile");
- utile->users = 1;
- utile->rect.pt = ptile->rect.pt;
- ptile->rect.pt = NULL;
- const uint tile_index = index_from_xy(ptile->x, ptile->y, ubuf_pre->tiles_dims);
-
- BLI_assert(ubuf_pre->tiles[tile_index] == NULL);
- ubuf_pre->tiles[tile_index] = utile;
- }
- ptile_next = ptile->next;
- ptile_free(ptile);
- }
- BLI_listbase_clear(&us->paint_tiles);
-
- for (UndoImageHandle *uh = us->handles.first; uh; uh = uh->next) {
- for (UndoImageBuf *ubuf_pre = uh->buffers.first; ubuf_pre; ubuf_pre = ubuf_pre->next) {
-
- ImBuf *ibuf = BKE_image_acquire_ibuf(uh->image_ref.ptr, NULL, NULL);
-
- const bool has_float = ibuf->rect_float;
-
- BLI_assert(ubuf_pre->post == NULL);
- ubuf_pre->post = ubuf_from_image_no_tiles(uh->image_ref.ptr, ibuf);
- UndoImageBuf *ubuf_post = ubuf_pre->post;
-
- if (ubuf_pre->image_dims[0] != ubuf_post->image_dims[0] ||
- ubuf_pre->image_dims[1] != ubuf_post->image_dims[1]) {
- ubuf_from_image_all_tiles(ubuf_post, ibuf);
- }
- else {
- /* Search for the previous buffer. */
- UndoImageBuf *ubuf_reference = (us_reference ?
- ubuf_lookup_from_reference(
- us_reference, uh->image_ref.ptr, ubuf_post) :
- NULL);
-
- int i = 0;
- for (uint y_tile = 0; y_tile < ubuf_pre->tiles_dims[1]; y_tile += 1) {
- uint y = y_tile << IMAPAINT_TILE_BITS;
- for (uint x_tile = 0; x_tile < ubuf_pre->tiles_dims[0]; x_tile += 1) {
- uint x = x_tile << IMAPAINT_TILE_BITS;
-
- if ((ubuf_reference != NULL) && ((ubuf_pre->tiles[i] == NULL) ||
- /* In this case the paint stroke as has added a tile
- * which we have a duplicate reference available. */
- (ubuf_pre->tiles[i]->users == 1))) {
- if (ubuf_pre->tiles[i] != NULL) {
- /* If we have a reference, re-use this single use tile for the post state. */
- BLI_assert(ubuf_pre->tiles[i]->users == 1);
- ubuf_post->tiles[i] = ubuf_pre->tiles[i];
- ubuf_pre->tiles[i] = NULL;
- utile_init_from_imbuf(ubuf_post->tiles[i], x, y, ibuf, tmpibuf);
- }
- else {
- BLI_assert(ubuf_post->tiles[i] == NULL);
- ubuf_post->tiles[i] = ubuf_reference->tiles[i];
- ubuf_post->tiles[i]->users += 1;
- }
- BLI_assert(ubuf_pre->tiles[i] == NULL);
- ubuf_pre->tiles[i] = ubuf_reference->tiles[i];
- ubuf_pre->tiles[i]->users += 1;
-
- BLI_assert(ubuf_pre->tiles[i] != NULL);
- BLI_assert(ubuf_post->tiles[i] != NULL);
- }
- else {
- UndoImageTile *utile = utile_alloc(has_float);
- utile_init_from_imbuf(utile, x, y, ibuf, tmpibuf);
-
- if (ubuf_pre->tiles[i] != NULL) {
- ubuf_post->tiles[i] = utile;
- utile->users = 1;
- }
- else {
- ubuf_pre->tiles[i] = utile;
- ubuf_post->tiles[i] = utile;
- utile->users = 2;
- }
- }
- BLI_assert(ubuf_pre->tiles[i] != NULL);
- BLI_assert(ubuf_post->tiles[i] != NULL);
- i += 1;
- }
- }
- }
- BKE_image_release_ibuf(uh->image_ref.ptr, ibuf, NULL);
- }
- }
-
- IMB_freeImBuf(tmpibuf);
-
- /* Useful to debug tiles are stored correctly. */
- if (false) {
- uhandle_restore_list(&us->handles, false);
- }
- }
- 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;
- }
-
- us_p->is_applied = true;
-
- return true;
-}
-
-static void image_undosys_step_decode_undo_impl(ImageUndoStep *us, bool is_final)
-{
- BLI_assert(us->step.is_applied == true);
- uhandle_restore_list(&us->handles, !is_final);
- us->step.is_applied = false;
-}
-
-static void image_undosys_step_decode_redo_impl(ImageUndoStep *us)
-{
- BLI_assert(us->step.is_applied == false);
- uhandle_restore_list(&us->handles, false);
- us->step.is_applied = true;
-}
-
-static void image_undosys_step_decode_undo(ImageUndoStep *us, bool is_final)
-{
- 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 || (!is_final && us_iter == us)) {
-
- image_undosys_step_decode_undo_impl(us_iter, is_final);
- if (us_iter == us) {
- break;
- }
- 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;
- }
-}
-
-static void image_undosys_step_decode(
- struct bContext *C, struct Main *bmain, UndoStep *us_p, int dir, bool is_final)
-{
- ImageUndoStep *us = (ImageUndoStep *)us_p;
- if (dir < 0) {
- image_undosys_step_decode_undo(us, is_final);
- }
- else {
- image_undosys_step_decode_redo(us);
- }
-
- 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);
-}
-
-static void image_undosys_step_free(UndoStep *us_p)
-{
- ImageUndoStep *us = (ImageUndoStep *)us_p;
- uhandle_free_list(&us->handles);
-
- /* Typically this list will have been cleared. */
- ptile_free_list(&us->paint_tiles);
-}
-
-static void image_undosys_foreach_ID_ref(UndoStep *us_p,
- UndoTypeForEachIDRefFn foreach_ID_ref_fn,
- void *user_data)
-{
- ImageUndoStep *us = (ImageUndoStep *)us_p;
- for (UndoImageHandle *uh = us->handles.first; uh; uh = uh->next) {
- foreach_ID_ref_fn(user_data, ((UndoRefID *)&uh->image_ref));
- }
-}
-
-/* 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->step_foreach_ID_ref = image_undosys_foreach_ID_ref;
-
- ut->use_context = true;
-
- ut->step_size = sizeof(ImageUndoStep);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Utilities
- * \{ */
-
-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 &us->paint_tiles;
-}
-
-/* restore painting image to previous state. Used for anchored and drag-dot style brushes*/
-void ED_image_undo_restore(UndoStep *us)
-{
- ListBase *paint_tiles = &((ImageUndoStep *)us)->paint_tiles;
- ptile_restore_runtime_list(paint_tiles);
- ptile_invalidate_list(paint_tiles);
-}
-
-static ImageUndoStep *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;
- return us;
-}
-
-void ED_image_undo_push_begin(const char *name, int paint_mode)
-{
- image_undo_push_begin(name, paint_mode);
-}
-
-void ED_image_undo_push_begin_with_image(const char *name, Image *image, ImBuf *ibuf)
-{
- ImageUndoStep *us = image_undo_push_begin(name, PAINT_MODE_TEXTURE_2D);
-
- UndoImageHandle *uh = uhandle_ensure(&us->handles, image);
- UndoImageBuf *ubuf_pre = uhandle_ensure_ubuf(uh, image, ibuf);
- BLI_assert(ubuf_pre->post == NULL);
-
- ImageUndoStep *us_reference = (ImageUndoStep *)ED_undo_stack_get()->step_active;
- while (us_reference && us_reference->step.type != BKE_UNDOSYS_TYPE_IMAGE) {
- us_reference = (ImageUndoStep *)us_reference->step.prev;
- }
- UndoImageBuf *ubuf_reference = (us_reference ?
- ubuf_lookup_from_reference(us_reference, image, ubuf_pre) :
- NULL);
-
- if (ubuf_reference) {
- memcpy(ubuf_pre->tiles, ubuf_reference->tiles, sizeof(*ubuf_pre->tiles) * ubuf_pre->tiles_len);
- for (uint i = 0; i < ubuf_pre->tiles_len; i++) {
- UndoImageTile *utile = ubuf_pre->tiles[i];
- utile->users += 1;
- }
- }
- else {
- ubuf_from_image_all_tiles(ubuf_pre, ibuf);
- }
-}
-
-void ED_image_undo_push_end(void)
-{
- UndoStack *ustack = ED_undo_stack_get();
- BKE_undosys_step_push(ustack, NULL, NULL);
- WM_file_tag_modified();
-}
-
-/** \} */
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index abfa4331952..69eed84fe2b 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -184,10 +184,6 @@ typedef struct ImagePaintPartialRedraw {
int enabled;
} ImagePaintPartialRedraw;
-#define IMAPAINT_TILE_BITS 6
-#define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS)
-#define IMAPAINT_TILE_NUMBER(size) (((size) + IMAPAINT_TILE_SIZE - 1) >> IMAPAINT_TILE_BITS)
-
bool image_texture_paint_poll(struct bContext *C);
void imapaint_image_update(struct SpaceImage *sima,
struct Image *image,
@@ -252,30 +248,6 @@ void PAINT_OT_add_texture_paint_slot(struct wmOperatorType *ot);
void PAINT_OT_image_paint(struct wmOperatorType *ot);
void PAINT_OT_add_simple_uvs(struct wmOperatorType *ot);
-/* paint_image_undo.c */
-void *image_undo_find_tile(ListBase *undo_tiles,
- struct Image *ima,
- struct ImBuf *ibuf,
- int x_tile,
- int y_tile,
- unsigned short **mask,
- bool validate);
-void *image_undo_push_tile(ListBase *undo_tiles,
- struct Image *ima,
- struct ImBuf *ibuf,
- struct ImBuf **tmpibuf,
- int x_tile,
- int y_tile,
- unsigned short **,
- bool **valid,
- bool proj,
- bool find_prev);
-void image_undo_remove_masks(void);
-void image_undo_init_locks(void);
-void image_undo_end_locks(void);
-
-struct ListBase *ED_image_undo_get_tiles(void);
-
/* sculpt_uv.c */
void SCULPT_OT_uv_sculpt_stroke(struct wmOperatorType *ot);