Revision: 56405
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56405
Author:   blendix
Date:     2013-04-30 06:07:42 +0000 (Tue, 30 Apr 2013)
Log Message:
-----------
More image painting fixes:

* 2D image painting support for masking to limit the max contribution of a 
stroke
  to a pixel, to get it working compatible with projection painting. Not 
strictly
  a bugfix, but the inconsistency here was annoying.

* Fix python errors in Texture Mask panel in image editor, was missing overlay
  options.

* Clamp paint mask to 0..1 in case some texture exceeds it, this could give 
black
  pixels due to integer overflow.

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_image.py
    trunk/blender/source/blender/blenkernel/BKE_brush.h
    trunk/blender/source/blender/blenkernel/intern/brush.c
    trunk/blender/source/blender/blenlib/intern/math_color_blend_inline.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_intern.h
    trunk/blender/source/blender/imbuf/IMB_imbuf.h
    trunk/blender/source/blender/imbuf/intern/rectop.c
    trunk/blender/source/gameengine/VideoTexture/ImageBuff.cpp

Modified: trunk/blender/release/scripts/startup/bl_ui/space_image.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_image.py  2013-04-30 
06:03:17 UTC (rev 56404)
+++ trunk/blender/release/scripts/startup/bl_ui/space_image.py  2013-04-30 
06:07:42 UTC (rev 56405)
@@ -763,6 +763,12 @@
         col.template_ID_preview(brush, "mask_texture", new="texture.new", 
rows=3, cols=8)
 
         brush_mask_texture_settings(col, brush)
+
+        col = layout.column(align=True)
+        col.active = brush.brush_capabilities.has_overlay
+        col.label(text="Overlay:")
+
+        row = col.row()
         if tex_slot_alpha.map_mode != 'STENCIL':
             if brush.use_secondary_overlay:
                 row.prop(brush, "use_secondary_overlay", toggle=True, text="", 
icon='RESTRICT_VIEW_OFF')

Modified: trunk/blender/source/blender/blenkernel/BKE_brush.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_brush.h 2013-04-30 06:03:17 UTC 
(rev 56404)
+++ trunk/blender/source/blender/blenkernel/BKE_brush.h 2013-04-30 06:07:42 UTC 
(rev 56405)
@@ -82,7 +82,7 @@
 float BKE_brush_sample_masktex(const Scene *scene, struct Brush *br, const 
float point[3],
                                const int thread, struct ImagePool *pool);
 void BKE_brush_imbuf_new(const struct Scene *scene, struct Brush *brush, short 
flt, short texfalloff, int size,
-                         struct ImBuf **imbuf, int use_color_correction);
+                         struct ImBuf **imbuf, bool use_color_correction, bool 
use_brush_alpha);
 
 /* texture */
 unsigned int *BKE_brush_gen_texture_cache(struct Brush *br, int half_side);

Modified: trunk/blender/source/blender/blenkernel/intern/brush.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/brush.c      2013-04-30 
06:03:17 UTC (rev 56404)
+++ trunk/blender/source/blender/blenkernel/intern/brush.c      2013-04-30 
06:07:42 UTC (rev 56405)
@@ -828,14 +828,15 @@
 
 /* TODO, use define for 'texfall' arg
  * NOTE: only used for 2d brushes currently! */
-void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short 
texfall, int bufsize, ImBuf **outbuf, int use_color_correction)
+void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short 
texfall, int bufsize,
+                         ImBuf **outbuf, bool use_color_correction, bool 
use_brush_alpha)
 {
        ImBuf *ibuf;
        float xy[2], rgba[4], *dstf;
        int x, y, rowbytes, xoff, yoff, imbflag;
        const int radius = BKE_brush_size_get(scene, brush);
        unsigned char *dst, crgb[3];
-       const float alpha = BKE_brush_alpha_get(scene, brush);
+       const float alpha = (use_brush_alpha)? BKE_brush_alpha_get(scene, 
brush): 1.0f;
        float brush_rgb[3];
 
        imbflag = (flt) ? IB_rectfloat : IB_rect;

Modified: trunk/blender/source/blender/blenlib/intern/math_color_blend_inline.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_color_blend_inline.c       
2013-04-30 06:03:17 UTC (rev 56404)
+++ trunk/blender/source/blender/blenlib/intern/math_color_blend_inline.c       
2013-04-30 06:07:42 UTC (rev 56405)
@@ -372,12 +372,17 @@
 {
        if (src2[3] != 0.0f && src1[3] > 0.0f) {
                /* subtract alpha and remap RGB channels to match */
-               const float alpha = max_ff(src1[3] - src2[3], 0.0f);
-               const float map_alpha = alpha / src1[3];
+               float alpha = max_ff(src1[3] - src2[3], 0.0f);
+               float map_alpha;
 
-               dst[0] *= map_alpha;
-               dst[1] *= map_alpha;
-               dst[2] *= map_alpha;
+               if (alpha <= 0.0005f)
+                       alpha = 0.0f;
+
+               map_alpha = alpha / src1[3];
+
+               dst[0] = src1[0] * map_alpha;
+               dst[1] = src1[1] * map_alpha;
+               dst[2] = src1[2] * map_alpha;
                dst[3] = alpha;
        }
        else {
@@ -393,12 +398,17 @@
 {
        if (src2[3] != 0.0f && src1[3] < 1.0f) {
                /* add alpha and remap RGB channels to match */
-               const float alpha = min_ff(src1[3] + src2[3], 1.0f);
-               const float map_alpha = (src1[3] > 0.0f) ? alpha / src1[3] : 
1.0f;
+               float alpha = min_ff(src1[3] + src2[3], 1.0f);
+               float map_alpha;
 
-               dst[0] *= map_alpha;
-               dst[1] *= map_alpha;
-               dst[2] *= map_alpha;
+               if (alpha >= 1.0f - 0.0005f)
+                       alpha = 1.0f;
+
+               map_alpha = (src1[3] > 0.0f) ? alpha / src1[3] : 1.0f;
+
+               dst[0] = src1[0] * map_alpha;
+               dst[1] = src1[1] * map_alpha;
+               dst[2] = src1[2] * map_alpha;
                dst[3] = alpha;
        }
        else {

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image.c     
2013-04-30 06:03:17 UTC (rev 56404)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image.c     
2013-04-30 06:07:42 UTC (rev 56405)
@@ -101,9 +101,6 @@
 
 #include "paint_intern.h"
 
-#define IMAPAINT_TILE_BITS          6
-#define IMAPAINT_TILE_SIZE          (1 << IMAPAINT_TILE_BITS)
-
 typedef struct UndoImageTile {
        struct UndoImageTile *next, *prev;
 
@@ -115,6 +112,9 @@
                unsigned int *uint;
                void         *pt;
        } rect;
+
+       unsigned short *mask;
+
        int x, y;
 
        short source, use_float;
@@ -156,18 +156,45 @@
                            tile->y * IMAPAINT_TILE_SIZE, 0, 0, 
IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
 }
 
+void *image_undo_find_tile(Image *ima, ImBuf *ibuf, int x_tile, int y_tile, 
unsigned short **mask)
+{
+       ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
+       UndoImageTile *tile;
+       short use_float = ibuf->rect_float ? 1 : 0;
+
+       for (tile = lb->first; tile; tile = tile->next) {
+               if (tile->x == x_tile && tile->y == y_tile && ima->gen_type == 
tile->gen_type && ima->source == tile->source) {
+                       if (tile->use_float == use_float) {
+                               if (strcmp(tile->idname, ima->id.name) == 0 && 
strcmp(tile->ibufname, ibuf->name) == 0) {
+                                       if (mask) {
+                                               /* allocate mask if requested */
+                                               if (!tile->mask)
+                                                       tile->mask = 
MEM_callocN(sizeof(unsigned short)*IMAPAINT_TILE_SIZE*IMAPAINT_TILE_SIZE, 
"UndoImageTile.mask");
+
+                                               *mask = tile->mask;
+                                       }
+
+                                       return tile->rect.pt;
+                               }
+                       }
+               }
+       }
+       
+       return NULL;
+}
+
 void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int 
x_tile, int y_tile)
 {
        ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
        UndoImageTile *tile;
        int allocsize;
        short use_float = ibuf->rect_float ? 1 : 0;
+       void *data;
 
-       for (tile = lb->first; tile; tile = tile->next)
-               if (tile->x == x_tile && tile->y == y_tile && ima->gen_type == 
tile->gen_type && ima->source == tile->source)
-                       if (tile->use_float == use_float)
-                               if (strcmp(tile->idname, ima->id.name) == 0 && 
strcmp(tile->ibufname, ibuf->name) == 0)
-                                       return tile->rect.pt;
+       /* check if tile is already pushed */
+       data = image_undo_find_tile(ima, ibuf, x_tile, y_tile, NULL);
+       if (data)
+               return data;
        
        if (*tmpibuf == NULL)
                *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, 
IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect);
@@ -195,6 +222,19 @@
        return tile->rect.pt;
 }
 
+void image_undo_remove_masks(void)
+{
+       ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
+       UndoImageTile *tile;
+
+       for (tile = lb->first; tile; tile = tile->next) {
+               if (tile->mask) {
+                       MEM_freeN(tile->mask);
+                       tile->mask = NULL;
+               }
+       }
+}
+
 void image_undo_restore(bContext *C, ListBase *lb)
 {
        Main *bmain = CTX_data_main(C);
@@ -276,10 +316,23 @@
        memset(&imapaintpartial, 0, sizeof(imapaintpartial));
 }
 
+void imapaint_region_tiles(ImBuf *ibuf, int x, int y, int w, int h, int *tx, 
int *ty, int *tw, int *th)
+{
+       int srcx = 0, srcy = 0;
+
+       IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
+
+       *tw = ((x + w - 1) >> IMAPAINT_TILE_BITS);
+       *th = ((y + h - 1) >> IMAPAINT_TILE_BITS);
+       *tx = (x >> IMAPAINT_TILE_BITS);
+       *ty = (y >> IMAPAINT_TILE_BITS);
+}
+
 void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
 {
        ImBuf *tmpibuf = NULL;
-       int srcx = 0, srcy = 0, origx;
+       int tilex, tiley, tilew, tileh, tx, ty;
+       int srcx = 0, srcy = 0;
 
        IMB_rectclip(ibuf, NULL, &x, &y, &srcx, &srcy, &w, &h);
 
@@ -300,15 +353,12 @@
                imapaintpartial.y2 = max_ii(imapaintpartial.y2, y + h);
        }
 
-       w = ((x + w - 1) >> IMAPAINT_TILE_BITS);
-       h = ((y + h - 1) >> IMAPAINT_TILE_BITS);
-       origx = (x >> IMAPAINT_TILE_BITS);
-       y = (y >> IMAPAINT_TILE_BITS);
-       
-       for (; y <= h; y++)
-               for (x = origx; x <= w; x++)
-                       image_undo_push_tile(ima, ibuf, &tmpibuf, x, y);
+       imapaint_region_tiles(ibuf, x, y, w, h, &tilex, &tiley, &tilew, &tileh);
 
+       for (ty = tiley; ty <= tileh; ty++)
+               for (tx = tilex; tx <= tilew; tx++)
+                       image_undo_push_tile(ima, ibuf, &tmpibuf, tx, ty);
+
        ibuf->userflags |= IB_BITMAPDIRTY;
        
        if (tmpibuf)

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c  
2013-04-30 06:03:17 UTC (rev 56404)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c  
2013-04-30 06:07:42 UTC (rev 56405)
@@ -133,6 +133,8 @@
        char *warnpackedfile;
        char *warnmultifile;
 
+       bool do_masking;
+
        /* viewport texture paint only, but _not_ project paint */
        Object *ob;
        int faceindex;
@@ -327,7 +329,7 @@
                brush_painter_2d_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 
0, 0, pos);
 }
 
-static void brush_painter_2d_refresh_cache(BrushPainter *painter, const float 
pos[2], int use_color_correction)
+static void brush_painter_2d_refresh_cache(BrushPainter *painter, const float 
pos[2], bool use_color_correction, bool use_brush_alpha)
 {
        const Scene *scene = painter->scene;
        UnifiedPaintSettings *ups = 
&scene->toolsettings->unified_paint_settings;
@@ -347,7 +349,7 @@
        }
 
        if (diameter != cache->lastsize ||
-           alpha != cache->lastalpha ||
+           (use_brush_alpha && alpha != cache->lastalpha) ||
            brush->jitter != cache->lastjitter ||
            rotation != cache->last_rotation ||
            do_random)
@@ -365,11 +367,13 @@
                size = (cache->size) ? cache->size : diameter;
 
                if (do_tiled) {
-                       BKE_brush_imbuf_new(scene, brush, flt, 3, size, 
&cache->maskibuf, use_color_correction);
+                       BKE_brush_imbuf_new(scene, brush, flt, 3, size, 
&cache->maskibuf,
+                                           use_color_correction, 
use_brush_alpha);
                        brush_painter_2d_tiled_tex_partial_update(painter, pos);
                }
                else
-                       BKE_brush_imbuf_new(scene, brush, flt, 2, size, 
&cache->ibuf, use_color_correction);

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to