From 210d0f1b801fb23c7edabb35b67224eab671e363 Mon Sep 17 00:00:00 2001 From: Jesse Yurkovich Date: Tue, 17 May 2022 00:27:23 -0700 Subject: Fix T96414: Stencil mapping is incorrect for UDIMs When texture painting, brush textures and brush texture masks were not transformed to account for UDIM tiles. Differential Revision: https://developer.blender.org/D14671 --- .../blender/editors/sculpt_paint/paint_image_2d.c | 55 +++++++++------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index d30aa4dfab1..fae2e6863fa 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -621,39 +621,38 @@ static void brush_painter_imbuf_partial_update(BrushPainter *painter, } static void brush_painter_2d_tex_mapping(ImagePaintState *s, - ImBuf *canvas, + ImagePaintTile *tile, const int diameter, - const float startpos[2], const float pos[2], const float mouse[2], int mapmode, rctf *mapping) { - float invw = 1.0f / (float)canvas->x; - float invh = 1.0f / (float)canvas->y; - int xmin, ymin, xmax, ymax; - int ipos[2]; + float invw = 1.0f / (float)tile->canvas->x; + float invh = 1.0f / (float)tile->canvas->y; + float start[2]; /* find start coordinate of brush in canvas */ - ipos[0] = (int)floorf((pos[0] - diameter / 2) + 1.0f); - ipos[1] = (int)floorf((pos[1] - diameter / 2) + 1.0f); + start[0] = pos[0] - diameter / 2.0f; + start[1] = pos[1] - diameter / 2.0f; if (mapmode == MTEX_MAP_MODE_STENCIL) { /* map from view coordinates of brush to region coordinates */ - UI_view2d_view_to_region(s->v2d, ipos[0] * invw, ipos[1] * invh, &xmin, &ymin); - UI_view2d_view_to_region( - s->v2d, (ipos[0] + diameter) * invw, (ipos[1] + diameter) * invh, &xmax, &ymax); + float xmin, ymin, xmax, ymax; + UI_view2d_view_to_region_fl(s->v2d, start[0] * invw, start[1] * invh, &xmin, &ymin); + UI_view2d_view_to_region_fl( + s->v2d, (start[0] + diameter) * invw, (start[1] + diameter) * invh, &xmax, &ymax); /* output mapping from brush ibuf x/y to region coordinates */ - mapping->xmin = xmin; - mapping->ymin = ymin; mapping->xmax = (xmax - xmin) / (float)diameter; mapping->ymax = (ymax - ymin) / (float)diameter; + mapping->xmin = xmin + (tile->uv_origin[0] * tile->size[0] * mapping->xmax); + mapping->ymin = ymin + (tile->uv_origin[1] * tile->size[1] * mapping->ymax); } else if (mapmode == MTEX_MAP_MODE_3D) { /* 3D mapping, just mapping to canvas 0..1. */ - mapping->xmin = 2.0f * (ipos[0] * invw - 0.5f); - mapping->ymin = 2.0f * (ipos[1] * invh - 0.5f); + mapping->xmin = 2.0f * (start[0] * invw - 0.5f); + mapping->ymin = 2.0f * (start[1] * invh - 0.5f); mapping->xmax = 2.0f * invw; mapping->ymax = 2.0f * invh; } @@ -665,8 +664,10 @@ static void brush_painter_2d_tex_mapping(ImagePaintState *s, mapping->ymax = 1.0f; } else /* if (mapmode == MTEX_MAP_MODE_TILED) */ { - mapping->xmin = (int)(-diameter * 0.5) + (int)floorf(pos[0]) - (int)floorf(startpos[0]); - mapping->ymin = (int)(-diameter * 0.5) + (int)floorf(pos[1]) - (int)floorf(startpos[1]); + mapping->xmin = (int)(-diameter * 0.5) + (int)floorf(pos[0]) - + (int)floorf(tile->start_paintpos[0]); + mapping->ymin = (int)(-diameter * 0.5) + (int)floorf(pos[1]) - + (int)floorf(tile->start_paintpos[1]); mapping->xmax = 1.0f; mapping->ymax = 1.0f; } @@ -711,14 +712,8 @@ static void brush_painter_2d_refresh_cache(ImagePaintState *s, do_partial_update = true; } - brush_painter_2d_tex_mapping(s, - tile->canvas, - diameter, - tile->start_paintpos, - pos, - mouse, - brush->mtex.brush_map_mode, - &painter->tex_mapping); + brush_painter_2d_tex_mapping( + s, tile, diameter, pos, mouse, brush->mtex.brush_map_mode, &painter->tex_mapping); } if (cache->is_maskbrush) { @@ -745,14 +740,8 @@ static void brush_painter_2d_refresh_cache(ImagePaintState *s, renew_maxmask) { MEM_SAFE_FREE(cache->tex_mask); - brush_painter_2d_tex_mapping(s, - tile->canvas, - diameter, - tile->start_paintpos, - pos, - mouse, - brush->mask_mtex.brush_map_mode, - &painter->mask_mapping); + brush_painter_2d_tex_mapping( + s, tile, diameter, pos, mouse, brush->mask_mtex.brush_map_mode, &painter->mask_mapping); if (do_partial_update_mask) { brush_painter_mask_imbuf_partial_update(painter, tile, pos, diameter); -- cgit v1.2.3