Fix T46560: 2D paint smear and soften brushes not working with alpha.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 20 Jul 2017 22:16:59 +0000 (00:16 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 20 Jul 2017 22:47:43 +0000 (00:47 +0200)
Interpolate rather than do alpha over mix, matching projection paint.

source/blender/editors/sculpt_paint/paint_image_2d.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/rectop.c

index 4f93c12385d97cb74b4b1beaa538c5e22c9f556e..09b0847b3064c067939d8ba4f8435caed3b872fc 100644 (file)
@@ -797,6 +797,7 @@ static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const bool is_torus
                float map_alpha = (rgb[3] == 0.0f) ? rrgbf[3] : rrgbf[3] / rgb[3];
 
                mul_v3_v3fl(rrgbf, rgb, map_alpha);
+               rrgbf[3] = rgb[3];
        }
        else {
                unsigned char straight[4];
@@ -806,6 +807,7 @@ static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const bool is_torus
                rrgb[0] = straight[0];
                rrgb[1] = straight[1];
                rrgb[2] = straight[2];
+               rrgb[3] = straight[3];
        }
 }
 
@@ -995,7 +997,7 @@ static void paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos, short tile)
                IMB_rectblend(ibufb, ibufb, ibuf, NULL, NULL, NULL, 0, region[a].destx, region[a].desty,
                              region[a].destx, region[a].desty,
                              region[a].srcx, region[a].srcy,
-                             region[a].width, region[a].height, IMB_BLEND_COPY_RGB, false);
+                             region[a].width, region[a].height, IMB_BLEND_COPY, false);
 }
 
 static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
@@ -1096,6 +1098,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
        /* lift from canvas */
        if (s->tool == PAINT_TOOL_SOFTEN) {
                paint_2d_lift_soften(s, s->canvas, ibufb, bpos, tile);
+               blend = IMB_BLEND_INTERPOLATE;
        }
        else if (s->tool == PAINT_TOOL_SMEAR) {
                if (lastpos[0] == pos[0] && lastpos[1] == pos[1])
@@ -1103,6 +1106,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
 
                paint_2d_convert_brushco(ibufb, lastpos, blastpos);
                paint_2d_lift_smear(s->canvas, ibufb, blastpos, tile);
+               blend = IMB_BLEND_INTERPOLATE;
        }
        else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
                liftpos[0] = pos[0] - offset[0] * s->canvas->x;
index e7abfdc7d67b3d2592b62859622b509cd46d6889..f1f36351e79479006d5c4d3bad487b0acb0d492e 100644 (file)
@@ -205,6 +205,7 @@ typedef enum IMB_BlendMode {
        IMB_BLEND_SATURATION = 21,
        IMB_BLEND_LUMINOSITY = 22,
        IMB_BLEND_COLOR = 23,
+       IMB_BLEND_INTERPOLATE = 24,
 
        IMB_BLEND_COPY = 1000,
        IMB_BLEND_COPY_RGB = 1001,
index 3360fd7548e90dd19836f69ca317d7efd4205b0f..086599a37467f1c7c7bcc1306b22b078f732515e 100644 (file)
@@ -424,6 +424,7 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
        else {
                switch (mode) {
                        case IMB_BLEND_MIX:
+                       case IMB_BLEND_INTERPOLATE:
                                func = blend_color_mix_byte;
                                func_float = blend_color_mix_float;
                                break;
@@ -563,9 +564,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
                                                                        mask_src[0] = src[0];
                                                                        mask_src[1] = src[1];
                                                                        mask_src[2] = src[2];
-                                                                       mask_src[3] = divide_round_i(src[3] * mask, 65535);
 
-                                                                       func((unsigned char *)dr, (unsigned char *)or, mask_src);
+                                                                       if (mode == IMB_BLEND_INTERPOLATE) {
+                                                                               mask_src[3] = src[3];
+                                                                               blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f);
+                                                                       }
+                                                                       else {
+                                                                               mask_src[3] = divide_round_i(src[3] * mask, 65535);
+                                                                               func((unsigned char *)dr, (unsigned char *)or, mask_src);
+                                                                       }
                                                                }
                                                        }
                                                }
@@ -588,9 +595,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
                                                                mask_src[0] = src[0];
                                                                mask_src[1] = src[1];
                                                                mask_src[2] = src[2];
-                                                               mask_src[3] = divide_round_i(src[3] * mask, 65535);
 
-                                                               func((unsigned char *)dr, (unsigned char *)or, mask_src);
+                                                               if (mode == IMB_BLEND_INTERPOLATE) {
+                                                                       mask_src[3] = src[3];
+                                                                       blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f);
+                                                               }
+                                                               else {
+                                                                       mask_src[3] = divide_round_i(src[3] * mask, 65535);
+                                                                       func((unsigned char *)dr, (unsigned char *)or, mask_src);
+                                                               }
                                                        }
                                                }
                                        }
@@ -642,12 +655,16 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
                                                                mask = min_ff(mask, 65535.0);
 
                                                                if (mask > *dmr) {
-                                                                       float mask_srf[4];
-
                                                                        *dmr = mask;
-                                                                       mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
 
-                                                                       func_float(drf, orf, mask_srf);
+                                                                       if (mode == IMB_BLEND_INTERPOLATE) {
+                                                                               blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
+                                                                       }
+                                                                       else {
+                                                                               float mask_srf[4];
+                                                                               mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
+                                                                               func_float(drf, orf, mask_srf);
+                                                                       }
                                                                }
                                                        }
                                                }
@@ -664,11 +681,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
                                                        mask = min_ff(mask, 65535.0);
 
                                                        if (srf[3] && (mask > 0.0f)) {
-                                                               float mask_srf[4];
-
-                                                               mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
+                                                               if (mode == IMB_BLEND_INTERPOLATE) {
+                                                                       blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
+                                                               }
+                                                               else {
+                                                                       float mask_srf[4];
+                                                                       mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
+                                                                       func_float(drf, orf, mask_srf);
+                                                               }
 
-                                                               func_float(drf, orf, mask_srf);
                                                        }
                                                }
                                        }