[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56699] trunk/blender/source: Image paint: 2D painting now supports texture masks and does masking more

Brecht Van Lommel brechtvanlommel at pandora.be
Sun May 12 11:14:13 CEST 2013


Revision: 56699
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56699
Author:   blendix
Date:     2013-05-12 09:14:13 +0000 (Sun, 12 May 2013)
Log Message:
-----------
Image paint: 2D painting now supports texture masks and does masking more
consistent with projection painting.

Also did some refactoring of this code, moving the brush image creation code
out of brush.c and making it consistent with image updating code.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_brush.h
    trunk/blender/source/blender/blenkernel/intern/brush.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/imbuf/IMB_imbuf.h
    trunk/blender/source/blender/imbuf/intern/rectop.c
    trunk/blender/source/gameengine/VideoTexture/ImageBuff.cpp

Modified: trunk/blender/source/blender/blenkernel/BKE_brush.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_brush.h	2013-05-12 09:14:07 UTC (rev 56698)
+++ trunk/blender/source/blender/blenkernel/BKE_brush.h	2013-05-12 09:14:13 UTC (rev 56699)
@@ -81,12 +81,6 @@
 float BKE_brush_sample_masktex(const Scene *scene, struct Brush *br, const float point[3],
                                const int thread, struct ImagePool *pool);
 
-enum BrushImBufFill { BRUSH_IMBUF_MASK, BRUSH_IMBUF_TEX, BRUSH_IMBUF_TEX_MASK };
-void BKE_brush_imbuf_new(const struct Scene *scene, struct Brush *brush, bool use_float,
-                         enum BrushImBufFill fill, int size, struct ImBuf **imbuf,
-                         bool use_color_correction, bool use_brush_alpha,
-                         struct ImagePool *pool, struct rctf *mapping);
-
 /* 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-05-12 09:14:07 UTC (rev 56698)
+++ trunk/blender/source/blender/blenkernel/intern/brush.c	2013-05-12 09:14:13 UTC (rev 56699)
@@ -758,122 +758,6 @@
 	return intensity;
 }
 
-static void brush_imbuf_tex_co(rctf *mapping, int x, int y, float texco[3])
-{
-	texco[0] = mapping->xmin + x * mapping->xmax;
-	texco[1] = mapping->ymin + y * mapping->ymax;
-	texco[2] = 0.0f;
-}
-
-/* NOTE: only used for 2d brushes currently! and needs to stay in sync
- * with brush_painter_2d_do_partial */
-void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, bool use_float,
-                         enum BrushImBufFill fill, int bufsize,
-                         ImBuf **outbuf, bool use_color_correction, bool use_brush_alpha,
-                         struct ImagePool *pool, rctf *mapping)
-{
-	ImBuf *ibuf;
-	float xy[2], texco[3], 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 = (use_brush_alpha)? BKE_brush_alpha_get(scene, brush): 1.0f;
-	float brush_rgb[3] = {1.0f, 1.0f, 1.0f};
-	int thread = 0;
-
-	imbflag = (use_float) ? IB_rectfloat : IB_rect;
-	xoff = -bufsize / 2.0f + 0.5f;
-	yoff = -bufsize / 2.0f + 0.5f;
-	rowbytes = bufsize * 4;
-
-	if (*outbuf)
-		ibuf = *outbuf;
-	else
-		ibuf = IMB_allocImBuf(bufsize, bufsize, 32, imbflag);
-
-	if (use_float) {
-		if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
-			copy_v3_v3(brush_rgb, brush->rgb);
-			if (use_color_correction) {
-				srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
-			}
-		}
-
-		for (y = 0; y < ibuf->y; y++) {
-			dstf = ibuf->rect_float + y * rowbytes;
-
-			for (x = 0; x < ibuf->x; x++, dstf += 4) {
-				xy[0] = x + xoff;
-				xy[1] = y + yoff;
-
-				if (fill == BRUSH_IMBUF_MASK) {
-					copy_v3_v3(dstf, brush_rgb);
-					dstf[3] = alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
-				}
-				else if (fill == BRUSH_IMBUF_TEX) {
-					brush_imbuf_tex_co(mapping, x, y, texco);
-					BKE_brush_sample_tex_3D(scene, brush, texco, dstf, thread, pool);
-				}
-				else { /* if (fill == BRUSH_IMBUF_TEX_MASK) */
-					brush_imbuf_tex_co(mapping, x, y, texco);
-					BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
-
-					mul_v3_v3v3(dstf, rgba, brush_rgb);
-					dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
-				}
-
-				/* output premultiplied alpha image */
-				dstf[0] *= dstf[3];
-				dstf[1] *= dstf[3];
-				dstf[2] *= dstf[3];
-			}
-		}
-	}
-	else {
-		float alpha_f; /* final float alpha to convert to char */
-
-		if (brush->imagepaint_tool == PAINT_TOOL_DRAW)
-			copy_v3_v3(brush_rgb, brush->rgb);
-
-		rgb_float_to_uchar(crgb, brush->rgb);
-
-		for (y = 0; y < ibuf->y; y++) {
-			dst = (unsigned char *)ibuf->rect + y * rowbytes;
-
-			for (x = 0; x < ibuf->x; x++, dst += 4) {
-				xy[0] = x + xoff;
-				xy[1] = y + yoff;
-
-				if (fill == BRUSH_IMBUF_MASK) {
-					alpha_f = alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
-
-					dst[0] = crgb[0];
-					dst[1] = crgb[1];
-					dst[2] = crgb[2];
-					dst[3] = FTOCHAR(alpha_f);
-				}
-				else if (fill == BRUSH_IMBUF_TEX) {
-					brush_imbuf_tex_co(mapping, x, y, texco);
-					BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
-					rgba_float_to_uchar(dst, rgba);
-				}
-				else { /* if (fill == BRUSH_IMBUF_TEX_MASK) */
-					brush_imbuf_tex_co(mapping, x, y, texco);
-					BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
-
-					mul_v3_v3(rgba, brush_rgb);
-					alpha_f = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
-
-					rgb_float_to_uchar(dst, rgba);
-					dst[3] = FTOCHAR(alpha_f);
-				}
-			}
-		}
-	}
-
-	*outbuf = ibuf;
-}
-
 /* Unified Size and Strength */
 
 /* XXX: be careful about setting size and unprojected radius

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c	2013-05-12 09:14:07 UTC (rev 56698)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c	2013-05-12 09:14:13 UTC (rev 56699)
@@ -88,17 +88,24 @@
 #define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
 
 typedef struct BrushPainterCache {
-	int size;           /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
-	short flt;          /* need float imbuf? */
+	int size;                    /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
 
+	bool use_float;              /* need float imbuf? */
+	bool use_color_correction;   /* use color correction for float */
+	bool use_masking;            /* use masking? */
+
+	bool is_texbrush;
+	bool is_maskbrush;
+
 	int lastsize;
 	float lastalpha;
 	float lastjitter;
-	float last_rotation;
+	float last_tex_rotation;
+	float last_mask_rotation;
 
 	ImBuf *ibuf;
 	ImBuf *texibuf;
-	ImBuf *maskibuf;
+	unsigned short *mask;
 } BrushPainterCache;
 
 typedef struct BrushPainter {
@@ -111,7 +118,8 @@
 	short firsttouch;       /* first paint op */
 
 	struct ImagePool *pool;	/* image pool */
-	rctf mapping;			/* texture coordinate mapping */
+	rctf tex_mapping;		/* texture coordinate mapping */
+	rctf mask_mapping;		/* mask texture coordinate mapping */
 
 	BrushPainterCache cache;
 } BrushPainter;
@@ -161,144 +169,314 @@
 }
 
 
-static void brush_painter_2d_require_imbuf(BrushPainter *painter, short flt, int size)
+static void brush_painter_2d_require_imbuf(BrushPainter *painter, bool use_float, bool use_color_correction, bool use_masking)
 {
-	if ((painter->cache.flt != flt) || (painter->cache.size != size)) {
+	Brush *brush = painter->brush;
+
+	if ((painter->cache.use_float != use_float)) {
 		if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
-		if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
-		painter->cache.ibuf = painter->cache.maskibuf = NULL;
+		if (painter->cache.mask) MEM_freeN(painter->cache.mask);
+		painter->cache.ibuf = NULL;
+		painter->cache.mask = NULL;
 		painter->cache.lastsize = -1; /* force ibuf create in refresh */
 	}
 
-	if (painter->cache.flt != flt) {
+	if (painter->cache.use_float != use_float) {
 		if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
 		painter->cache.texibuf = NULL;
 		painter->cache.lastsize = -1; /* force ibuf create in refresh */
 	}
 
-	painter->cache.size = size;
-	painter->cache.flt = flt;
+	painter->cache.use_float = use_float;
+	painter->cache.use_color_correction = use_float && use_color_correction;
+	painter->cache.use_masking = use_masking;
+	painter->cache.is_texbrush = (brush->mtex.tex && brush->imagepaint_tool == PAINT_TOOL_DRAW) ? true : false;
+	painter->cache.is_maskbrush = (brush->mask_mtex.tex) ? true : false;
 }
 
 static void brush_painter_2d_free(BrushPainter *painter)
 {
 	if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
 	if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
-	if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
+	if (painter->cache.mask) MEM_freeN(painter->cache.mask);
 	MEM_freeN(painter);
 }
 
-static void brush_painter_2d_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
-                                     int x, int y, int w, int h, int xt, int yt,
-                                     const float pos[2])
+static void brush_imbuf_tex_co(rctf *mapping, int x, int y, float texco[3])
 {
+	texco[0] = mapping->xmin + x * mapping->xmax;
+	texco[1] = mapping->ymin + y * mapping->ymax;
+	texco[2] = 0.0f;
+}
+
+/* create a mask with the falloff strength and optionally brush alpha */
+static unsigned short *brush_painter_mask_new(BrushPainter *painter, int size)
+{
 	Scene *scene = painter->scene;
 	Brush *brush = painter->brush;
-	ImBuf *ibuf, *maskibuf, *texibuf;
-	float *bf, *mf, *tf, *otf = NULL, texco[3], rgba[4];
-	unsigned char *b, *m, *t, *ot = NULL;
-	int dotexold, origx = x, origy = y;
-	int thread = 0;
-	rctf mapping = painter->mapping;
+	bool use_masking = painter->cache.use_masking;
 
-	if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
-		mapping.xmin += (int)pos[0] - (int)painter->startpaintpos[0];
-		mapping.ymin += (int)pos[1] - (int)painter->startpaintpos[1];
+	float alpha = (use_masking)? 1.0f: BKE_brush_alpha_get(scene, brush);
+	int radius = BKE_brush_size_get(scene, brush);
+	int xoff = -size * 0.5f + 0.5f;
+	int yoff = -size * 0.5f + 0.5f;
+
+	unsigned short *mask, *m;
+	int x, y;
+
+	mask = MEM_callocN(sizeof(unsigned short)*size*size, "brush_painter_mask");
+	m = mask;
+
+	for (y = 0; y < size; y++) {
+		for (x = 0; x < size; x++, m++) {
+			float xy[2] = {x + xoff, y + yoff};
+			float len = len_v2(xy);
+			float strength = alpha;
+
+			strength *= BKE_brush_curve_strength_clamp(brush, len, radius);
+
+			*m = (unsigned short)(65535.0f * strength);
+		}
 	}
 
-	ibuf = painter->cache.ibuf;
-	texibuf = painter->cache.texibuf;
-	maskibuf = painter->cache.maskibuf;
+	return mask;
+}
 
-	dotexold = (oldtexibuf != NULL);
+/* create imbuf with brush color */
+static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size)
+{
+	Scene *scene = painter->scene;
+	Brush *brush = painter->brush;
 
-	/* not sure if it's actually needed or it's a mistake in coords/sizes

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list