From ae027413f4b3b4aa9e606f03f1d301b3c7cdc035 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 13 Apr 2022 13:37:16 +0200 Subject: Rebuild pixels when image resolution/uvmap changes. --- source/blender/blenkernel/BKE_paint.h | 5 ++++ source/blender/blenkernel/BKE_pbvh.h | 2 +- source/blender/blenkernel/intern/paint.c | 23 ++++++++++++++++++ source/blender/blenkernel/intern/pbvh.c | 4 ++-- source/blender/editors/include/ED_paint.h | 5 ++++ .../blender/editors/sculpt_paint/paint_canvas.cc | 28 ++++++++++++++++++++++ 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 1b296277b8f..ca9c88d771d 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -649,6 +649,11 @@ typedef struct SculptSession { */ bool sticky_shading_color; + /** + * Last used painting canvas key. + */ + char *last_paint_canvas_key; + } SculptSession; void BKE_sculptsession_free(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 7c5ff94f188..cee3b7246a6 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -307,7 +307,7 @@ bool BKE_pbvh_node_fully_masked_get(PBVHNode *node); void BKE_pbvh_node_fully_unmasked_set(PBVHNode *node, int fully_masked); bool BKE_pbvh_node_fully_unmasked_get(PBVHNode *node); -void BKE_pbvh_mark_update_pixels(PBVH *pbvh); +void BKE_pbvh_mark_rebuild_pixels(PBVH *pbvh); void BKE_pbvh_pixels_free_brush_test(PBVH *pbvh); void BKE_pbvh_vert_mark_update(PBVH *pbvh, int index); diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index eb3f47760fc..f75c5c58709 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -59,6 +59,9 @@ #include "RNA_enum_types.h" +/* TODO(jbakker) Bad include/call. Move paint_canvas to BKE_paint but in master directly. */ +#include "../../editors/include/ED_paint.h" + #include "BLO_read_write.h" #include "bmesh.h" @@ -1511,6 +1514,8 @@ void BKE_sculptsession_free(Object *ob) BKE_sculptsession_free_vwpaint_data(ob->sculpt); + MEM_SAFE_FREE(ss->last_paint_canvas_key); + MEM_freeN(ss); ob->sculpt = NULL; @@ -1771,6 +1776,24 @@ static void sculpt_update_object(Depsgraph *depsgraph, } } + /* + * We should rebuild the PBVH_pixels when painting canvas changes. + * + * The relevant changes are stored/encoded in the paint canvas key. + * These include the active uv map, and resolutions. + */ + if (U.experimental.use_sculpt_texture_paint && ss->pbvh) { + char *paint_canvas_key = ED_paint_canvas_key_get(&scene->toolsettings->paint_mode, ob); + if (ss->last_paint_canvas_key == NULL || !STREQ(paint_canvas_key, ss->last_paint_canvas_key)) { + MEM_SAFE_FREE(ss->last_paint_canvas_key); + ss->last_paint_canvas_key = paint_canvas_key; + BKE_pbvh_mark_rebuild_pixels(ss->pbvh); + } + else { + MEM_freeN(paint_canvas_key); + } + } + /* We could be more precise when we have access to the active tool. */ const bool use_paint_slots = (ob->mode & OB_MODE_SCULPT) != 0; if (use_paint_slots) { diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 08dcd8f34b6..637c5fb5c2e 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1781,7 +1781,7 @@ BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh) void BKE_pbvh_node_mark_update(PBVHNode *node) { node->flag |= PBVH_UpdateNormals | PBVH_UpdateBB | PBVH_UpdateOriginalBB | - PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; + PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw | PBVH_RebuildPixels; } void BKE_pbvh_node_mark_update_mask(PBVHNode *node) @@ -1794,7 +1794,7 @@ void BKE_pbvh_node_mark_update_color(PBVHNode *node) node->flag |= PBVH_UpdateColor | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; } -void BKE_pbvh_mark_update_pixels(PBVH *pbvh) +void BKE_pbvh_mark_rebuild_pixels(PBVH *pbvh) { for (int n = 0; n < pbvh->totnode; n++) { PBVHNode *node = &pbvh->nodes[n]; diff --git a/source/blender/editors/include/ED_paint.h b/source/blender/editors/include/ED_paint.h index 557891f78f1..252b24eacf0 100644 --- a/source/blender/editors/include/ED_paint.h +++ b/source/blender/editors/include/ED_paint.h @@ -120,6 +120,11 @@ bool ED_paint_canvas_image_get(struct PaintModeSettings *paint_mode_settings, struct ImageUser **r_image_user); int ED_paint_canvas_uvmap_layer_index_get(const struct PaintModeSettings *settings, struct Object *ob); +/** + * Create a key that can be used to compare with previous ones to identify changes. + * The resulting 'string' is owned by the caller. + */ +char *ED_paint_canvas_key_get(struct PaintModeSettings *settings, struct Object *ob); /** Color type of an object can be overridden in sculpt/paint mode. */ eV3DShadingColorType ED_paint_shading_color_override(struct bContext *C, diff --git a/source/blender/editors/sculpt_paint/paint_canvas.cc b/source/blender/editors/sculpt_paint/paint_canvas.cc index 9c0f16636d7..bb52b442ee2 100644 --- a/source/blender/editors/sculpt_paint/paint_canvas.cc +++ b/source/blender/editors/sculpt_paint/paint_canvas.cc @@ -9,10 +9,13 @@ #include "BKE_context.h" #include "BKE_customdata.h" +#include "BKE_image.h" #include "BKE_material.h" #include "BKE_paint.h" #include "BKE_pbvh.h" +#include "IMB_imbuf_types.h" + #include "DEG_depsgraph.h" #include "NOD_shader.h" @@ -215,4 +218,29 @@ int ED_paint_canvas_uvmap_layer_index_get(const struct PaintModeSettings *settin } return -1; } + +char *ED_paint_canvas_key_get(struct PaintModeSettings *settings, struct Object *ob) +{ + std::stringstream ss; + int active_uv_map_layer_index = ED_paint_canvas_uvmap_layer_index_get(settings, ob); + ss << "UV_MAP:" << active_uv_map_layer_index; + + Image *image; + ImageUser *image_user; + if (ED_paint_canvas_image_get(settings, ob, &image, &image_user)) { + ImageUser tile_user = *image_user; + LISTBASE_FOREACH (ImageTile *, image_tile, &image->tiles) { + tile_user.tile = image_tile->tile_number; + ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &tile_user, nullptr); + if (!image_buffer) { + continue; + } + ss << ",TILE_" << image_tile->tile_number; + ss << "(" << image_buffer->x << "," << image_buffer->y << ")"; + BKE_image_release_ibuf(image, image_buffer, nullptr); + } + } + + return BLI_strdup(ss.str().c_str()); +} } -- cgit v1.2.3