Commit: cc4defac041f3d9d2ff6ed38171ade38d9149b96
Author: Lukas Stockner
Date:   Mon Jun 11 23:07:34 2018 +0200
Branches: temp-udim-images
https://developer.blender.org/rBcc4defac041f3d9d2ff6ed38171ade38d9149b96

Support 2D painting onto tiled images

Currently, a limitation is that strokes can not cross between tiles, only the 
tile in which the stroke started will be affected.

===================================================================

M       source/blender/blenkernel/BKE_image.h
M       source/blender/blenkernel/intern/image.c
M       source/blender/editors/sculpt_paint/paint_image.c
M       source/blender/editors/sculpt_paint/paint_image_2d.c
M       source/blender/editors/sculpt_paint/paint_intern.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_image.h 
b/source/blender/blenkernel/BKE_image.h
index 9a39ddd1de7..f795b53e818 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -283,6 +283,8 @@ void BKE_image_set_bindcode(struct Image *ima, int tile, 
int type, unsigned int
 struct GPUTexture *BKE_image_get_gpu_texture(struct Image *ima, int tile, int 
type);
 void BKE_image_set_gpu_texture(struct Image *ima, int tile, int type, struct 
GPUTexture *tex);
 
+int BKE_image_get_tile_from_pos(struct Image *ima, float uv[2], float 
new_uv[2], float ofs[2]);
+
 void BKE_image_set_num_tiles(struct Image *ima, int num_tiles);
 
 void BKE_image_get_size(struct Image *image, struct ImageUser *iuser, int 
*width, int *height);
diff --git a/source/blender/blenkernel/intern/image.c 
b/source/blender/blenkernel/intern/image.c
index e822d0db469..4edf89fc036 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -556,6 +556,29 @@ bool BKE_image_has_bindcode(Image *ima)
        return has_bindcode;
 }
 
+int BKE_image_get_tile_from_pos(struct Image *ima, float uv[2], float 
new_uv[2], float ofs[2])
+{
+       copy_v2_v2(new_uv, uv);
+       zero_v2(ofs);
+
+       if ((ima->source != IMA_SRC_TILED) || uv[0] < 0.0f || uv[1] < 0.0f || 
uv[0] >= 10.0f) {
+               return 0;
+       }
+
+       int ix = (int) uv[0];
+       int iy = (int) uv[1];
+       int tile = 10*iy + ix;
+
+       if (tile >= ima->num_tiles) {
+               return 0;
+       }
+
+       ofs[0] = ix;
+       ofs[1] = iy;
+       sub_v2_v2(new_uv, ofs);
+       return tile;
+}
+
 static void image_init_color_management(Image *ima)
 {
        ImBuf *ibuf;
diff --git a/source/blender/editors/sculpt_paint/paint_image.c 
b/source/blender/editors/sculpt_paint/paint_image.c
index 93fa3aac0d7..52d4802fd19 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -472,7 +472,7 @@ static PaintOperation *texture_paint_init(bContext *C, 
wmOperator *op, const flo
        }
        else {
                pop->mode = PAINT_MODE_2D;
-               pop->custom_paint = paint_2d_new_stroke(C, op, mode);
+               pop->custom_paint = paint_2d_new_stroke(C, op, mouse, mode);
        }
 
        if (!pop->custom_paint) {
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c 
b/source/blender/editors/sculpt_paint/paint_image_2d.c
index a75d6344849..4e76d9efc84 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -145,6 +145,9 @@ typedef struct ImagePaintState {
 
        bool need_redraw;
 
+       int tile;
+       float uv_ofs[2];
+
        BlurKernel *blurkernel;
 } ImagePaintState;
 
@@ -1189,6 +1192,9 @@ static int paint_2d_op(void *state, ImBuf *ibufb, 
unsigned short *curveb, unsign
 
 static int paint_2d_canvas_set(ImagePaintState *s, Image *ima)
 {
+       if (s->sima) {
+               s->sima->iuser.tile = s->tile;
+       }
        ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : 
NULL, NULL);
 
        /* verify that we can paint and set canvas */
@@ -1212,6 +1218,9 @@ static int paint_2d_canvas_set(ImagePaintState *s, Image 
*ima)
        /* set clone canvas */
        if (s->tool == PAINT_TOOL_CLONE) {
                ima = s->brush->clone.image;
+               if (s->sima) {
+                       s->sima->iuser.tile = s->tile;
+               }
                ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : 
NULL, NULL);
 
                if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
@@ -1249,11 +1258,20 @@ static void paint_2d_canvas_free(ImagePaintState *s)
        image_undo_remove_masks();
 }
 
+static void paint_2d_transform_mouse(ImagePaintState *s, const float in[2], 
float out[2])
+{
+       UI_view2d_region_to_view(s->v2d, in[0], in[1], &out[0], &out[1]);
+       sub_v2_v2(out, s->uv_ofs);
+}
+
 void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], 
const bool eraser, float pressure, float distance, float size)
 {
        float newuv[2], olduv[2];
        ImagePaintState *s = ps;
        BrushPainter *painter = s->painter;
+       if (s->sima) {
+               s->sima->iuser.tile = s->tile;
+       }
        ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? 
&s->sima->iuser : NULL, NULL);
        const bool is_data = (ibuf && ibuf->colormanage_flag & 
IMB_COLORMANAGE_IS_DATA);
 
@@ -1264,8 +1282,8 @@ void paint_2d_stroke(void *ps, const float prev_mval[2], 
const float mval[2], co
        if (eraser)
                s->blend = IMB_BLEND_ERASE_ALPHA;
 
-       UI_view2d_region_to_view(s->v2d, mval[0], mval[1], &newuv[0], 
&newuv[1]);
-       UI_view2d_region_to_view(s->v2d, prev_mval[0], prev_mval[1], &olduv[0], 
&olduv[1]);
+       paint_2d_transform_mouse(s, mval, newuv);
+       paint_2d_transform_mouse(s, prev_mval, olduv);
 
        newuv[0] *= ibuf->x;
        newuv[1] *= ibuf->y;
@@ -1276,7 +1294,8 @@ void paint_2d_stroke(void *ps, const float prev_mval[2], 
const float mval[2], co
        if (painter->firsttouch) {
                float startuv[2];
 
-               UI_view2d_region_to_view(s->v2d, 0, 0, &startuv[0], 
&startuv[1]);
+               zero_v2(startuv);
+               paint_2d_transform_mouse(s, startuv, startuv);
 
                /* paint exactly once on first touch */
                painter->startpaintpos[0] = startuv[0] * ibuf->x;
@@ -1302,7 +1321,7 @@ void paint_2d_stroke(void *ps, const float prev_mval[2], 
const float mval[2], co
        BKE_image_release_ibuf(s->image, ibuf, NULL);
 }
 
-void *paint_2d_new_stroke(bContext *C, wmOperator *op, int mode)
+void *paint_2d_new_stroke(bContext *C, wmOperator *op, const float mouse[2], 
int mode)
 {
        Scene *scene = CTX_data_scene(C);
        ToolSettings *settings = scene->toolsettings;
@@ -1322,6 +1341,11 @@ void *paint_2d_new_stroke(bContext *C, wmOperator *op, 
int mode)
        s->image = s->sima->image;
        s->symmetry = settings->imapaint.paint.symmetry_flags;
 
+       float uv[2];
+       paint_2d_transform_mouse(s, mouse, uv);
+       s->tile = BKE_image_get_tile_from_pos(s->image, uv, uv, s->uv_ofs);
+       //negate_v2(s->uv_ofs);
+
        if (!paint_2d_canvas_set(s, s->image)) {
                if (s->warnmultifile)
                        BKE_report(op->reports, RPT_WARNING, "Image requires 4 
color channels to paint");
@@ -1349,6 +1373,9 @@ void paint_2d_redraw(const bContext *C, void *ps, bool 
final)
        ImagePaintState *s = ps;
 
        if (s->need_redraw) {
+               if (s->sima) {
+                       s->sima->iuser.tile = s->tile;
+               }
                ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? 
&s->sima->iuser : NULL, NULL);
 
                imapaint_image_update(s->sima, s->image, ibuf, false);
@@ -1453,6 +1480,7 @@ void paint_2d_bucket_fill(
        if (!ima)
                return;
 
+       sima->iuser.tile = s->tile;
        ibuf = BKE_image_acquire_ibuf(ima, &sima->iuser, NULL);
 
        if (!ibuf)
@@ -1505,7 +1533,7 @@ void paint_2d_bucket_fill(
                /* We are comparing to sum of three squared values (assumed in 
range [0,1]), so need to multiply... */
                float threshold_sq = br->fill_threshold * br->fill_threshold * 
3;
 
-               UI_view2d_region_to_view(s->v2d, mouse_init[0], mouse_init[1], 
&image_init[0], &image_init[1]);
+               paint_2d_transform_mouse(s, mouse_init, image_init);
 
                x_px = image_init[0] * ibuf->x;
                y_px = image_init[1] * ibuf->y;
@@ -1631,13 +1659,14 @@ void paint_2d_gradient_fill(
        if (!ima)
                return;
 
+       sima->iuser.tile = s->tile;
        ibuf = BKE_image_acquire_ibuf(ima, &sima->iuser, NULL);
 
        if (!ibuf)
                return;
 
-       UI_view2d_region_to_view(s->v2d, mouse_final[0], mouse_final[1], 
&image_final[0], &image_final[1]);
-       UI_view2d_region_to_view(s->v2d, mouse_init[0], mouse_init[1], 
&image_init[0], &image_init[1]);
+       paint_2d_transform_mouse(s, mouse_final, image_final);
+       paint_2d_transform_mouse(s, mouse_init, image_init);
 
        image_final[0] *= ibuf->x;
        image_final[1] *= ibuf->y;
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h 
b/source/blender/editors/sculpt_paint/paint_intern.h
index 8d94978f5c6..6f9e5eeb751 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -185,7 +185,7 @@ struct ImagePaintPartialRedraw *get_imapaintpartial(void);
 void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr);
 void imapaint_region_tiles(struct ImBuf *ibuf, int x, int y, int w, int h, int 
*tx, int *ty, int *tw, int *th);
 int get_imapaint_zoom(struct bContext *C, float *zoomx, float *zoomy);
-void *paint_2d_new_stroke(struct bContext *, struct wmOperator *, int mode);
+void *paint_2d_new_stroke(struct bContext *, struct wmOperator *, const float 
mouse[2], int mode);
 void paint_2d_redraw(const struct bContext *C, void *ps, bool final);
 void paint_2d_stroke_done(void *ps);
 void paint_2d_stroke(

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to