[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17821] trunk/blender/source/blender/src/ imagepaint.c: projection paint cleanup (nothing to see here)

Campbell Barton ideasman42 at gmail.com
Sat Dec 13 17:11:52 CET 2008


Revision: 17821
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17821
Author:   campbellbarton
Date:     2008-12-13 17:11:52 +0100 (Sat, 13 Dec 2008)

Log Message:
-----------
projection paint cleanup (nothing to see here)
* BarycentricWeightsPersp2f was calling BarycentricWeights2f, and re-weighting. Changed so the re-weighting isnt needed.
* replaced tri_depth_2d with VecZDepthOrtho and VecZDepthPersp
* project_paint_occlude_ptv_clip now calls project_paint_occlude_ptv to remove duplicate code.

Modified Paths:
--------------
    trunk/blender/source/blender/src/imagepaint.c

Modified: trunk/blender/source/blender/src/imagepaint.c
===================================================================
--- trunk/blender/source/blender/src/imagepaint.c	2008-12-13 11:34:03 UTC (rev 17820)
+++ trunk/blender/source/blender/src/imagepaint.c	2008-12-13 16:11:52 UTC (rev 17821)
@@ -539,47 +539,45 @@
 (v1[1]-v2[1])*(v3[0]-v2[0])));
 }
 
-static void BarycentricWeights2f(float v1[2], float v2[2], float v3[2], float pt[2], float w[3])
+static void BarycentricWeights2f(float pt[2], float v1[2], float v2[2], float v3[2], float w[3])
 {
-   float wtot_inv, wtot, wsign[3];
+   float wtot_inv, wtot;
 
-   wsign[0] = AreaSignedF2Dfl(v2, v3, pt);
-   wsign[1] = AreaSignedF2Dfl(v3, v1, pt);
-   wsign[2] = AreaSignedF2Dfl(v1, v2, pt);
-   wtot = wsign[0]+wsign[1]+wsign[2];
+   w[0] = AreaSignedF2Dfl(v2, v3, pt);
+   w[1] = AreaSignedF2Dfl(v3, v1, pt);
+   w[2] = AreaSignedF2Dfl(v1, v2, pt);
+   wtot = w[0]+w[1]+w[2];
 
-   if (fabs(wtot) > 0.0f) {
+   if (wtot != 0.0f) {
        wtot_inv = 1.0f/wtot;
 
-       w[0] = wsign[0]*wtot_inv;
-       w[1] = wsign[1]*wtot_inv;
-       w[2] = wsign[2]*wtot_inv;
+       w[0] = w[0]*wtot_inv;
+       w[1] = w[1]*wtot_inv;
+       w[2] = w[2]*wtot_inv;
    }
    else /* dummy values for zero area face */
        w[0] = w[1] = w[2] = 1.0f/3.0f;
 }
 
 /* still use 2D X,Y space but this works for verts transformed by a perspective matrix, using their 4th component as a weight */
-
-static void BarycentricWeightsPersp2f(float v1[4], float v2[4], float v3[4], float pt[2], float w[3])
+static void BarycentricWeightsPersp2f(float pt[2], float v1[4], float v2[4], float v3[4], float w[3])
 {
-	float persp_tot, persp_tot_inv;
-	BarycentricWeights2f(v1, v2, v3, pt, w);
-	
-	w[0] /= v1[3];
-	w[1] /= v2[3];
-	w[2] /= v3[3];
-	
-	persp_tot = w[0]+w[1]+w[2];
-	if (persp_tot > 0.0f) {
-		persp_tot_inv = 1.0f / persp_tot;
-		w[0] *= persp_tot_inv;
-		w[1] *= persp_tot_inv;
-		w[2] *= persp_tot_inv;
-	}
-	else {
-		w[0] = w[1] = w[2] = 1.0f/3.0f; /* dummy values for zero area face */
-	}
+   float wtot_inv, wtot;
+
+   w[0] = AreaSignedF2Dfl(v2, v3, pt) / v1[3];
+   w[1] = AreaSignedF2Dfl(v3, v1, pt) / v2[3];
+   w[2] = AreaSignedF2Dfl(v1, v2, pt) / v3[3];
+   wtot = w[0]+w[1]+w[2];
+
+   if (wtot != 0.0f) {
+       wtot_inv = 1.0f/wtot;
+
+       w[0] = w[0]*wtot_inv;
+       w[1] = w[1]*wtot_inv;
+       w[2] = w[2]*wtot_inv;
+   }
+   else /* dummy values for zero area face */
+       w[0] = w[1] = w[2] = 1.0f/3.0f;
 }
 
 static void VecWeightf(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
@@ -595,13 +593,19 @@
 	p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
 }
 
-static float tri_depth_2d(float v1[3], float v2[3], float v3[3], float pt[2], float w[3])
+static float VecZDepthOrtho(float pt[2], float v1[3], float v2[3], float v3[3], float w[3])
 {
-	BarycentricWeights2f(v1, v2, v3, pt, w);
+	BarycentricWeights2f(pt, v1, v2, v3, w);
 	return (v1[2]*w[0]) + (v2[2]*w[1]) + (v3[2]*w[2]);
 }
 
+static float VecZDepthPersp(float pt[2], float v1[3], float v2[3], float v3[3], float w[3])
+{
+	BarycentricWeightsPersp2f(pt, v1, v2, v3, w);
+	return (v1[2]*w[0]) + (v2[2]*w[1]) + (v3[2]*w[2]);
+}
 
+
 /* Return the top-most face index that the screen space coord 'pt' touches (or -1) */
 static int project_paint_PickFace(const ProjPaintState *ps, float pt[2], float w[3], int *side)
 {
@@ -633,7 +637,9 @@
 		v3= ps->screenCoords[mf->v3];
 		
 		if (IsectPT2Df(pt, v1, v2, v3)) {
-			z_depth= tri_depth_2d(v1, v2, v3, pt, w_tmp);
+			if (ps->is_ortho)	z_depth= VecZDepthOrtho(pt, v1, v2, v3, w_tmp);
+			else				z_depth= VecZDepthPersp(pt, v1, v2, v3, w_tmp);
+			
 			if (z_depth < z_depth_best) {
 				best_face_index = face_index;
 				best_side = 0;
@@ -645,7 +651,9 @@
 			v4= ps->screenCoords[mf->v4];
 			
 			if (IsectPT2Df(pt, v1, v3, v4)) {
-				z_depth= tri_depth_2d(v1, v3, v4, pt, w_tmp);
+				if (ps->is_ortho)	z_depth= VecZDepthOrtho(pt, v1, v3, v4, w_tmp);
+				else				z_depth= VecZDepthPersp(pt, v1, v3, v4, w_tmp);
+
 				if (z_depth < z_depth_best) {
 					best_face_index = face_index;
 					best_side= 1;
@@ -768,9 +776,10 @@
  * return...
  *  0	: no occlusion
  * -1	: no occlusion but 2D intersection is true (avoid testing the other half of a quad)
- *  1	: occluded */
+ *  1	: occluded
+    2	: occluded with w[3] weights set (need to know in some cases) */
 
-static int project_paint_occlude_ptv(float pt[3], float v1[3], float v2[3], float v3[3])
+static int project_paint_occlude_ptv(float pt[3], float v1[3], float v2[3], float v3[3], float w[3], int is_ortho)
 {
 	/* if all are behind us, return false */
 	if(v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
@@ -787,11 +796,14 @@
 		return 1;
 	}
 	else {
-		float w[3];
 		/* we intersect? - find the exact depth at the point of intersection */
-		if (tri_depth_2d(v1, v2, v3, pt, w) < pt[2]) {
-			return 1; /* This point is occluded by another face */
+		/* Is this point is occluded by another face? */
+		if (is_ortho) {
+			if (VecZDepthOrtho(pt, v1, v2, v3, w) < pt[2]) return 2;
 		}
+		else {
+			if (VecZDepthPersp(pt, v1, v2, v3, w) < pt[2]) return 2;
+		}
 	}
 	return -1;
 }
@@ -803,19 +815,17 @@
 		const int side )
 {
 	float w[3], wco[3];
-	
-	/* if all are behind us, return false */
-	if(v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
-		return 0;
-		
-	/* do a 2D point in try intersection */
-	if (!IsectPT2Df(pt, v1, v2, v3))
-		return 0; /* we know there is  */
-	
-	/* we intersect? - find the exact depth at the point of intersection */
-	if (tri_depth_2d(v1, v2, v3, pt, w) > pt[2])
-		return -1;
-	
+	int ret = project_paint_occlude_ptv(pt, v1, v2, v3, w, ps->is_ortho);
+
+	if (ret <= 0)
+		return ret;
+
+	if (ret==1) { /* weights not calculated */
+		if (ps->is_ortho)	BarycentricWeights2f(pt, v1, v2, v3, w);
+		else				BarycentricWeightsPersp2f(pt, v1, v2, v3, w);
+	}
+
+	/* Test if we're in the clipped area, */
 	if (side)	VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
 	else		VecWeightf(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
 	
@@ -836,47 +846,32 @@
 	MFace *mf;
 	int face_index;
 	int isect_ret;
+	float w[3]; /* not needed when clipping */
 	
 	/* we could return 0 for 1 face buckets, as long as this function assumes
 	 * that the point its testing is only every originated from an existing face */
-	
-	if(G.vd->flag & V3D_CLIPPING) {
-		for (; bucketFace; bucketFace = bucketFace->next) {
-			face_index = (int)bucketFace->link;
-			
-			if (orig_face != face_index) {
-				mf = ps->dm_mface + face_index;
-					isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], 0);
-					
-					/* Note, if isect_ret==-1 then we dont want to test the other side of the quad */
-					if (isect_ret==0 && mf->v4) {
-						isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], 1);
-					}
-				if (isect_ret==1) {
-					/* TODO - we may want to cache the first hit,
-					 * it is not possible to swap the face order in the list anymore */
-					return 1; 
-				}
+
+	for (; bucketFace; bucketFace = bucketFace->next) {
+		face_index = (int)bucketFace->link;
+
+		if (orig_face != face_index) {
+			mf = ps->dm_mface + face_index;
+			if(G.vd->flag & V3D_CLIPPING)
+				isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], 0);
+			else
+				isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], w, ps->is_ortho);
+
+			/* Note, if isect_ret==-1 then we dont want to test the other side of the quad */
+			if (isect_ret==0 && mf->v4) {
+				if(G.vd->flag & V3D_CLIPPING)
+					isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], 1);
+				else
+					isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho);
 			}
-		}
-	}
-	else {
-		for (; bucketFace; bucketFace = bucketFace->next) {
-			face_index = (int)bucketFace->link;
-			
-			if (orig_face != face_index) {
-				mf = ps->dm_mface + face_index;
-					isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3]);
-					
-					/* Note, if isect_ret==-1 then we dont want to test the other side of the quad */
-					if (isect_ret==0 && mf->v4) {
-						isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4]);
-					}
-				if (isect_ret==1) {
-					/* TODO - we may want to cache the first hit,
-					 * it is not possible to swap the face order in the list anymore */
-					return 1; 
-				}
+			if (isect_ret==1) {
+				/* TODO - we may want to cache the first hit,
+				 * it is not possible to swap the face order in the list anymore */
+				return 1;
 			}
 		}
 	}
@@ -1285,7 +1280,7 @@
 		float pixelScreenCo[4],
 		float w[3])
 {
-	BarycentricWeights2f(uv1co, uv2co, uv3co, uv, w);
+	BarycentricWeights2f(uv, uv1co, uv2co, uv3co, w);
 	VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
 }
 
@@ -1300,7 +1295,7 @@
 {
 
 	float wtot_inv, wtot;
-	BarycentricWeights2f(uv1co, uv2co, uv3co, uv, w);
+	BarycentricWeights2f(uv, uv1co, uv2co, uv3co, w);
 	
 	/* re-weight from the 4th coord of each screen vert */
 	w[0] *= v1co[3];
@@ -1360,7 +1355,7 @@
 		const int side,
 		const float w[3])
 {
-	float mask, mask_angle;
+	float mask;
 	
 	/* Image Mask */
 	if (ps->do_layer_mask) {
@@ -1872,22 +1867,22 @@
 	/* get the UV space bounding box */
 	uv[0] = bucket_bounds->xmax;
 	uv[1] = bucket_bounds->ymin;
-	BarycentricWeights2f(v1coSS, v2coSS, v3coSS, uv, w);	
+	BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
 	Vec2Weightf(bucket_bounds_uv[flip?3:0], uv1co, uv2co, uv3co, w);
 
 	//uv[0] = bucket_bounds->xmax; // set above
 	uv[1] = bucket_bounds->ymax;
-	BarycentricWeights2f(v1coSS, v2coSS, v3coSS, uv, w);
+	BarycentricWeights2f(uv, v1coSS, v2coSS, v3coSS, w);
 	Vec2Weightf(bucket_bounds_uv[flip?2:1], uv1co, uv2co, uv3co, w);
 
 	uv[0] = bucket_bounds->xmin;
 	//uv[1] = bucket_bounds->ymax; // set above
-	BarycentricWeights2f(v1coSS, v2coSS, v3coSS, uv, w);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list