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