[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51934] trunk/blender: fix [#33037] Soften brush can't handle seams in texture paint

Campbell Barton ideasman42 at gmail.com
Tue Nov 6 10:19:54 CET 2012


Revision: 51934
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51934
Author:   campbellbarton
Date:     2012-11-06 09:19:51 +0000 (Tue, 06 Nov 2012)
Log Message:
-----------
fix [#33037] Soften brush can't handle seams in texture paint

project paint never worked with soften (blur), support now added.

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py
    trunk/blender/source/blender/editors/sculpt_paint/paint_image.c

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2012-11-06 07:11:17 UTC (rev 51933)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2012-11-06 09:19:51 UTC (rev 51934)
@@ -1048,7 +1048,7 @@
     @classmethod
     def poll(cls, context):
         brush = context.tool_settings.image_paint.brush
-        return (brush and brush.image_tool != 'SOFTEN')
+        return (brush is not None)
 
     def draw_header(self, context):
         ipaint = context.tool_settings.image_paint

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image.c	2012-11-06 07:11:17 UTC (rev 51933)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image.c	2012-11-06 09:19:51 UTC (rev 51934)
@@ -381,6 +381,18 @@
 	PixelStore clonepx;
 } ProjPixelClone;
 
+/* blur, store surrounding colors */
+#define PROJ_PIXEL_SOFTEN_TOT 4
+/* blur picking offset (in screenspace) */
+#define PROJ_PIXEL_SOFTEN_OFS_PX 1.0f
+
+static const float proj_pixel_soften_v2[PROJ_PIXEL_SOFTEN_TOT][2] = {
+	{-PROJ_PIXEL_SOFTEN_OFS_PX,                         0.0f},
+	{ 0.0f,                        -PROJ_PIXEL_SOFTEN_OFS_PX},
+	{ 0.0f,                         PROJ_PIXEL_SOFTEN_OFS_PX},
+	{ PROJ_PIXEL_SOFTEN_OFS_PX,                         0.0f},
+};
+
 /* Finish projection painting structs */
 
 typedef struct UndoImageTile {
@@ -3816,6 +3828,84 @@
 	BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena);
 }
 
+/* do_projectpaint_soften for float & byte
+ */
+static float inv_pow2(float f)
+{
+	f = 1.0f - f;
+	f = f * f;
+	return 1.0f - f;
+}
+
+static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *softenArena, LinkNode **softenPixels)
+{
+	unsigned int accum_tot = 0;
+	unsigned int i;
+
+	float *rgba = projPixel->newColor.f;
+
+	/* sigh, alpha values tend to need to be a _lot_ stronger with blur */
+	mask  = inv_pow2(mask);
+	alpha = inv_pow2(alpha);
+
+	/* rather then painting, accumulate surrounding colors */
+	zero_v4(rgba);
+
+	for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
+		float co_ofs[2];
+		float rgba_tmp[4];
+		sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
+		if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
+			add_v4_v4(rgba, rgba_tmp);
+			accum_tot++;
+		}
+	}
+
+	if (LIKELY(accum_tot != 0)) {
+		mul_v4_fl(rgba, 1.0f / (float)accum_tot);
+		blend_color_mix_float(rgba, projPixel->pixel.f_pt, rgba, alpha);
+		if (mask < 1.0f) blend_color_mix_float(rgba, projPixel->origColor.f, rgba, mask);
+		BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
+	}
+}
+
+static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *softenArena, LinkNode **softenPixels)
+{
+	unsigned int accum_tot = 0;
+	unsigned int i;
+
+	float rgba[4];  /* convert to byte after */
+
+	/* sigh, alpha values tend to need to be a _lot_ stronger with blur */
+	mask  = inv_pow2(mask);
+	alpha = inv_pow2(alpha);
+
+	/* rather then painting, accumulate surrounding colors */
+	zero_v4(rgba);
+
+	for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
+		float co_ofs[2];
+		float rgba_tmp[4];
+		sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
+		if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
+			add_v4_v4(rgba, rgba_tmp);
+			accum_tot++;
+		}
+	}
+
+	if (LIKELY(accum_tot != 0)) {
+		unsigned char *rgba_ub = projPixel->newColor.ch;
+
+		mul_v4_fl(rgba, 1.0f / (float)accum_tot);
+		IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_ub, rgba);
+
+		blend_color_mix(rgba_ub, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * 255));
+		if (mask != 1.0f) blend_color_mix(rgba_ub, projPixel->origColor.ch, rgba_ub, (int)(mask * 255));
+		BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
+	}
+}
+
+
 static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const float rgba[4], float alpha, float mask)
 {
 	unsigned char rgba_ub[4];
@@ -3914,6 +4004,10 @@
 	LinkNode *smearPixels = NULL;
 	LinkNode *smearPixels_f = NULL;
 	MemArena *smearArena = NULL; /* mem arena for this brush projection only */
+
+	LinkNode *softenPixels = NULL;
+	LinkNode *softenPixels_f = NULL;
+	MemArena *softenArena = NULL; /* mem arena for this brush projection only */
 	
 	if (tool == PAINT_TOOL_SMEAR) {
 		pos_ofs[0] = pos[0] - lastpos[0];
@@ -3921,6 +4015,9 @@
 		
 		smearArena = BLI_memarena_new(1 << 16, "paint smear arena");
 	}
+	else if (tool == PAINT_TOOL_SOFTEN) {
+		softenArena = BLI_memarena_new(1 << 16, "paint soften arena");
+	}
 	
 	/* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */
 	
@@ -4060,6 +4157,10 @@
 									if (is_floatbuf) do_projectpaint_smear_f(ps, projPixel, alpha, mask, smearArena, &smearPixels_f, co);
 									else do_projectpaint_smear(ps, projPixel, alpha, mask, smearArena, &smearPixels, co);
 									break;
+								case PAINT_TOOL_SOFTEN:
+									if (is_floatbuf) do_projectpaint_soften_f(ps, projPixel, alpha, mask, softenArena, &softenPixels_f);
+									else do_projectpaint_soften(ps, projPixel, alpha, mask, softenArena, &softenPixels);
+									break;
 								default:
 									if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask, use_color_correction);
 									else do_projectpaint_draw(ps, projPixel, rgba, alpha, mask);
@@ -4094,7 +4195,21 @@
 		
 		BLI_memarena_free(smearArena);
 	}
-	
+	else if (tool == PAINT_TOOL_SOFTEN) {
+
+		for (node = softenPixels; node; node = node->next) { /* this wont run for a float image */
+			projPixel = node->link;
+			*projPixel->pixel.uint_pt = projPixel->newColor.uint;
+		}
+
+		for (node = softenPixels_f; node; node = node->next) {
+			projPixel = node->link;
+			copy_v4_v4(projPixel->pixel.f_pt, projPixel->newColor.f);
+		}
+
+		BLI_memarena_free(softenArena);
+	}
+
 	return NULL;
 }
 
@@ -4913,13 +5028,6 @@
 
 	pop->first = 1;
 	op->customdata = pop;
-	
-	/* XXX: Soften tool does not support projection painting atm, so just disable
-	 *      projection for this brush */
-	if (brush->imagepaint_tool == PAINT_TOOL_SOFTEN) {
-		settings->imapaint.flag |= IMAGEPAINT_PROJECT_DISABLE;
-		pop->restore_projection = 1;
-	}
 
 	/* initialize from context */
 	if (CTX_wm_region_view3d(C)) {




More information about the Bf-blender-cvs mailing list