[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20469] trunk/blender/source/blender: Projection paint, cloning from 1 layer to another would show ugly black lines at the seams because interpolation didnt wrap across the image .

Campbell Barton ideasman42 at gmail.com
Thu May 28 08:13:56 CEST 2009


Revision: 20469
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20469
Author:   campbellbarton
Date:     2009-05-28 08:13:56 +0200 (Thu, 28 May 2009)

Log Message:
-----------
Projection paint, cloning from 1 layer to another would show ugly black lines at the seams because interpolation didnt wrap across the image.
Added bilinear_interpolation_color_wrap to be used instead of bilinear_interpolation_color for painting.

Modified Paths:
--------------
    trunk/blender/source/blender/imbuf/IMB_imbuf.h
    trunk/blender/source/blender/imbuf/intern/imageprocess.c
    trunk/blender/source/blender/src/imagepaint.c

Modified: trunk/blender/source/blender/imbuf/IMB_imbuf.h
===================================================================
--- trunk/blender/source/blender/imbuf/IMB_imbuf.h	2009-05-28 06:10:48 UTC (rev 20468)
+++ trunk/blender/source/blender/imbuf/IMB_imbuf.h	2009-05-28 06:13:56 UTC (rev 20469)
@@ -410,6 +410,7 @@
 void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
 void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
 void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
+void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
 
 /**
  * Change the ordering of the color bytes pointed to by rect from

Modified: trunk/blender/source/blender/imbuf/intern/imageprocess.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/imageprocess.c	2009-05-28 06:10:48 UTC (rev 20468)
+++ trunk/blender/source/blender/imbuf/intern/imageprocess.c	2009-05-28 06:13:56 UTC (rev 20469)
@@ -303,6 +303,73 @@
 	}
 }
 
+/* function assumes out to be zero'ed, only does RGBA */
+/* BILINEAR INTERPOLATION */
+
+/* Note about wrapping, the u/v still needs to be within the image bounds,
+ * just the interpolation is wrapped.
+ * This the same as bilinear_interpolation_color except it wraps rather then using empty and emptyI */
+void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v)
+{
+	float *row1, *row2, *row3, *row4, a, b;
+	unsigned char *row1I, *row2I, *row3I, *row4I;
+	float a_b, ma_b, a_mb, ma_mb;
+	int y1, y2, x1, x2;
+	
+	
+	/* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */
+
+	x1= (int)floor(u);
+	x2= (int)ceil(u);
+	y1= (int)floor(v);
+	y2= (int)ceil(v);
+
+	// sample area entirely outside image? 
+	if (x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1) return;
+	
+	/* wrap interpolation pixels - main difference from bilinear_interpolation_color  */
+	if(x1<0)x1= in->x+x1;
+	if(y1<0)y1= in->y+y1;
+	
+	if(x2>=in->x)x2= x2-in->x;
+	if(y2>=in->y)y2= y2-in->y;
+
+	if (outF) {
+		// sample including outside of edges of image 
+		row1= (float *)in->rect_float + in->x * y1 * 4 + 4*x1;
+		row2= (float *)in->rect_float + in->x * y2 * 4 + 4*x1;
+		row3= (float *)in->rect_float + in->x * y1 * 4 + 4*x2;
+		row4= (float *)in->rect_float + in->x * y2 * 4 + 4*x2;
+		
+		a= u-floor(u);
+		b= v-floor(v);
+		a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b);
+		
+		outF[0]= ma_mb*row1[0] + a_mb*row3[0] + ma_b*row2[0]+ a_b*row4[0];
+		outF[1]= ma_mb*row1[1] + a_mb*row3[1] + ma_b*row2[1]+ a_b*row4[1];
+		outF[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2];
+		outF[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3];
+	}
+	if (outI) {
+		// sample including outside of edges of image 
+		row1I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1;
+		row2I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x1;
+		row3I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x2;
+		row4I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x2;
+		
+		a= u-floor(u);
+		b= v-floor(v);
+		a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b);
+		
+		/* need to add 0.5 to avoid rounding down (causes darken with the smear brush)
+		 * tested with white images and this should not wrap back to zero */
+		outI[0]= (ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0]) + 0.5f;
+		outI[1]= (ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1]) + 0.5f;
+		outI[2]= (ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2]) + 0.5f;
+		outI[3]= (ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3]) + 0.5f;
+	}
+}
+
 void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
 {
 	

Modified: trunk/blender/source/blender/src/imagepaint.c
===================================================================
--- trunk/blender/source/blender/src/imagepaint.c	2009-05-28 06:10:48 UTC (rev 20468)
+++ trunk/blender/source/blender/src/imagepaint.c	2009-05-28 06:13:56 UTC (rev 20469)
@@ -716,21 +716,21 @@
 		
 		if (ibuf->rect_float) {
 			if (rgba_fp) {
-				bilinear_interpolation_color(ibuf, NULL, rgba_fp, x, y);
+				bilinear_interpolation_color_wrap(ibuf, NULL, rgba_fp, x, y);
 			}
 			else {
 				float rgba_tmp_f[4];
-				bilinear_interpolation_color(ibuf, NULL, rgba_tmp_f, x, y);
+				bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y);
 				IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f);
 			}
 		}
 		else {
 			if (rgba) {
-				bilinear_interpolation_color(ibuf, rgba, NULL, x, y);
+				bilinear_interpolation_color_wrap(ibuf, rgba, NULL, x, y);
 			}
 			else {
 				unsigned char rgba_tmp[4];
-				bilinear_interpolation_color(ibuf, rgba_tmp, NULL, x, y);
+				bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y);
 				IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp);
 			}
 		}
@@ -1342,10 +1342,10 @@
 	
 	
 	if (ibuf_other->rect_float) { /* from float to float */
-		bilinear_interpolation_color(ibuf_other, NULL, rgba_f, x, y);
+		bilinear_interpolation_color_wrap(ibuf_other, NULL, rgba_f, x, y);
 	}
 	else { /* from char to float */
-		bilinear_interpolation_color(ibuf_other, rgba_ub, NULL, x, y);
+		bilinear_interpolation_color_wrap(ibuf_other, rgba_ub, NULL, x, y);
 	}
 		
 }





More information about the Bf-blender-cvs mailing list