[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [57776] trunk/blender/source/blender/ editors/sculpt_paint/paint_image_proj.c: Fix #35365 Texture cloning not behaving correctly in perspective view

Antony Riakiotakis kalast at gmail.com
Wed Jun 26 16:28:39 CEST 2013


Revision: 57776
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=57776
Author:   psy-fi
Date:     2013-06-26 14:28:39 +0000 (Wed, 26 Jun 2013)
Log Message:
-----------
Fix #35365 Texture cloning not behaving correctly in perspective view

This issue was caused by doing pespective interpolation of clone uv
coordinates in perspective view. To fix this we need to use perspective
correction for screen coordinates, but return regular barycentric
weights back for clone layer uv coordinate interpolation.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c	2013-06-26 13:22:25 UTC (rev 57775)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c	2013-06-26 14:28:39 UTC (rev 57776)
@@ -1121,6 +1121,44 @@
 	interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
 }
 
+
+/* same as screen_px_from_persp except we return ortho weights back to the caller.
+ * These weights will be used to determine correct interpolation of uvs in cloned uv layer */
+static void screen_px_from_persp_ortho_weights(
+        float uv[2],
+        float v1co[4], float v2co[4], float v3co[4],  /* screenspace coords */
+        float uv1co[2], float uv2co[2], float uv3co[2],
+        float pixelScreenCo[4],
+        float w[3])
+{
+	float w_int[3];
+	float wtot_inv, wtot;
+	barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
+
+	/* re-weight from the 4th coord of each screen vert */
+	w_int[0] = w[0] * v1co[3];
+	w_int[1] = w[1] * v2co[3];
+	w_int[2] = w[2] * v3co[3];
+
+	wtot = w_int[0] + w_int[1] + w_int[2];
+
+	if (wtot > 0.0f) {
+		wtot_inv = 1.0f / wtot;
+		w_int[0] *= wtot_inv;
+		w_int[1] *= wtot_inv;
+		w_int[2] *= wtot_inv;
+	}
+	else {
+		w[0] = w[1] = w[2] =
+		w_int[0] = w_int[1] = w_int[2] = 1.0f / 3.0f;  /* dummy values for zero area face */
+	}
+	/* done re-weighting */
+
+	/* do interpolation based on projected weight */
+	interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w_int);
+}
+
+
 static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3],
                                int side, unsigned char rgba_ub[4], float rgba_f[4])
 {
@@ -2168,6 +2206,7 @@
 	float uv_clip[8][2];
 	int uv_clip_tot;
 	const short is_ortho = ps->is_ortho;
+	const short is_clone_other = ((ps->brush->imagepaint_tool == PAINT_TOOL_CLONE) && ps->dm_mtface_clone);
 	const short do_backfacecull = ps->do_backfacecull;
 	const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
 
@@ -2191,8 +2230,6 @@
 	 * but since the first thing most people try is painting onto a quad- better make it work.
 	 */
 
-
-
 	tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx;
 	tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx;
 
@@ -2276,8 +2313,9 @@
 
 						has_x_isect = has_isect = 1;
 
-						if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
-						else          screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
+						if (is_clone_other) screen_px_from_persp_ortho_weights(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
+						else if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
+						else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
 
 						/* a pity we need to get the worldspace pixel location here */
 						if (do_clip || do_3d_mapping) {




More information about the Bf-blender-cvs mailing list