[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17346] branches/projection-paint/source/ blender/src/imagepaint.c: WIP commit before some optimizations,

Campbell Barton ideasman42 at gmail.com
Thu Nov 6 09:01:16 CET 2008


Revision: 17346
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17346
Author:   campbellbarton
Date:     2008-11-06 09:01:11 +0100 (Thu, 06 Nov 2008)

Log Message:
-----------
WIP commit before some optimizations,
fix for possible divide by zero.
added BarryCentricWeights2f(), returns weights for points outside the triangle.

Modified Paths:
--------------
    branches/projection-paint/source/blender/src/imagepaint.c

Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c	2008-11-06 03:31:25 UTC (rev 17345)
+++ branches/projection-paint/source/blender/src/imagepaint.c	2008-11-06 08:01:11 UTC (rev 17346)
@@ -135,6 +135,7 @@
 
 // #define PROJ_DEBUG_PAINT 1
 // #define PROJ_DEBUG_NOSCANLINE 1
+//#define PROJ_DEBUG_NOSEAMBLEED 1
 
 /* projectFaceFlags options */
 #define PROJ_FACE_IGNORE	1<<0	/* When the face is hidden, backfacing or occluded */
@@ -144,7 +145,6 @@
 #define PROJ_FACE_SEAM3	1<<4
 #define PROJ_FACE_SEAM4	1<<5
 
-
 #define PROJ_BUCKET_NULL		0
 #define PROJ_BUCKET_INIT		1<<0
 // #define PROJ_BUCKET_CLONE_INIT	1<<1
@@ -191,8 +191,9 @@
 	short projectIsOcclude;		/* Use raytraced occlusion? - ortherwise will paint right through to the back*/
 	short projectIsBackfaceCull;	/* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
 	short projectIsOrtho;
+#ifndef PROJ_DEBUG_NOSEAMBLEED
 	float projectSeamBleed;
-	
+#endif
 	/* clone vars */
 	float cloneOfs[2];
 	
@@ -411,21 +412,48 @@
 	}
 }
 
-/* assume they intersect */
-static void BarryCentricWeights2f(float v1[2], float v2[2], float v3[2], float pt[2], float w[3]) {
+/* The point must be inside the triangle */
+static void BaryCentricWeightsSimple2f(float v1[2], float v2[2], float v3[2], float pt[2], float w[3]) {
 	float wtot;
 	w[0] = AreaF2Dfl(v2, v3, pt);
 	w[1] = AreaF2Dfl(v3, v1, pt);
 	w[2] = AreaF2Dfl(v1, v2, pt);
 	wtot = w[0]+w[1]+w[2];
-	w[0]/=wtot;
-	w[1]/=wtot;
-	w[2]/=wtot;
+	if (wtot > 0.0) { /* just incase */
+		w[0]/=wtot;
+		w[1]/=wtot;
+		w[2]/=wtot;
+	} else {
+		w[0] = w[1] = w[2] = 1.0/3.0; /* dummy values for zero area face */
+	}
 }
 
+/* also works for points outside the triangle */
+#define SIDE_OF_LINE(pa,pb,pp)	((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
+static void BaryCentricWeights2f(float v1[2], float v2[2], float v3[2], float pt[2], float w[3]) {
+	float wtot = AreaF2Dfl(v1, v2, v3);
+	if (wtot > 0.0) {
+		w[0] = AreaF2Dfl(v2, v3, pt);
+		w[1] = AreaF2Dfl(v3, v1, pt);
+		w[2] = AreaF2Dfl(v1, v2, pt);
+		
+		/* negate weights when 'pt' is on the outer side of the the triangles edge */
+		if ((SIDE_OF_LINE(v2,v3, pt)>0.0) != (SIDE_OF_LINE(v2,v3, v1)>0.0))	w[0]/= -wtot;
+		else																w[0]/=  wtot;
+
+		if ((SIDE_OF_LINE(v3,v1, pt)>0.0) != (SIDE_OF_LINE(v3,v1, v2)>0.0))	w[1]/= -wtot;
+		else																w[1]/=  wtot;
+
+		if ((SIDE_OF_LINE(v1,v2, pt)>0.0) != (SIDE_OF_LINE(v1,v2, v3)>0.0))	w[2]/= -wtot;
+		else																w[2]/=  wtot;
+	} else {
+		w[0] = w[1] = w[2] = 1.0/3.0; /* dummy values for zero area face */
+	}
+}
+
 static float tri_depth_2d(float v1[3], float v2[3], float v3[3], float pt[2], float w[3])
 {
-	BarryCentricWeights2f(v1,v2,v3,pt,w);
+	BaryCentricWeightsSimple2f(v1,v2,v3,pt,w);
 	return (v1[2]*w[0]) + (v2[2]*w[1]) + (v3[2]*w[2]);
 }
 
@@ -749,6 +777,7 @@
 }
 	
 
+#ifndef PROJ_DEBUG_NOSEAMBLEED
 static int check_seam(ProjectPaintState *ps, int orig_face, int orig_i1_fidx, int orig_i2_fidx)
 {
 	LinkNode *node;
@@ -825,6 +854,7 @@
 			(check_seam(ps, face_index, 2,0) ? PROJ_FACE_SEAM3 : 0);
 	}
 }
+#endif // PROJ_DEBUG_NOSEAMBLEED
 
 static float angleToLength(float angle)
 {
@@ -1004,7 +1034,7 @@
 		float pixelScreenCo[4] )
 {
 	float w[3];
-	BarryCentricWeights2f(uv1co,uv2co,uv3co,uv,w);
+	BaryCentricWeightsSimple2f(uv1co,uv2co,uv3co,uv,w);
 	pixelScreenCo[0] = v1co[0]*w[0] + v2co[0]*w[1] + v3co[0]*w[2];
 	pixelScreenCo[1] = v1co[1]*w[0] + v2co[1]*w[1] + v3co[1]*w[2];
 	pixelScreenCo[2] = v1co[2]*w[0] + v2co[2]*w[1] + v3co[2]*w[2];	
@@ -1017,7 +1047,7 @@
 		float pixelScreenCo[4])
 {
 	float w[3];
-	BarryCentricWeights2f(uv1co,uv2co,uv3co,uv,w);
+	BaryCentricWeightsSimple2f(uv1co,uv2co,uv3co,uv,w);
 	pixelScreenCo[0] = v1co[0]*w[0] + v2co[0]*w[1] + v3co[0]*w[2];
 	pixelScreenCo[1] = v1co[1]*w[0] + v2co[1]*w[1] + v3co[1]*w[2];
 	pixelScreenCo[2] = v1co[2]*w[0] + v2co[2]*w[1] + v3co[2]*w[2];
@@ -1131,10 +1161,12 @@
 
 	if (!uv_image_rect(tf->uv[0], tf->uv[1], tf->uv[2], tf->uv[3], min_px, max_px, ibuf->x, ibuf->y, mf->v4))
 		return;
-	
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
 	/* detect UV seams so we can bleed */
 	if (ps->projectSeamBleed > 0.0)
 		project_face_seams_init(ps, face_index, mf->v4);
+#endif
 	
 	for (y = min_px[1]; y < max_px[1]; y++) {
 		uv[1] = (((float)y)+0.5) / (float)ibuf->y; /* TODO - this is not pixel aligned correctly */
@@ -1214,7 +1246,8 @@
 	}
 
 	
-#ifndef PROJ_DEBUG_NOSCANLINE 
+#ifndef PROJ_DEBUG_NOSCANLINE
+#ifndef PROJ_DEBUG_NOSEAMBLEED
 	/* Pretty much a copy of above, except fill in seams if we have any */
 	if (ps->projectFaceFlags[face_index] & (PROJ_FACE_SEAM1|PROJ_FACE_SEAM2|PROJ_FACE_SEAM3|PROJ_FACE_SEAM4)) {
 		float outset_uv[4][2]; /* expanded UV's */
@@ -1378,6 +1411,7 @@
 		}
 	}
 #endif
+#endif
 }
 
 
@@ -1544,6 +1578,7 @@
 		
 		DO_MINMAX2(ps->projectVertScreenCos[ a ], min, max);
 		
+#ifndef PROJ_DEBUG_NOSEAMBLEED
 		/* add face user if we have bleed enabled, set the UV seam flags later */
 		if (ps->projectSeamBleed > 0.0) {
 			BLI_linklist_prepend_arena(
@@ -1552,6 +1587,7 @@
 				ps->projectArena
 			);
 		}
+#endif
 	} while (i--);
 	
 	project_paint_rect(ps, min, max, bucket_min, bucket_max);
@@ -1642,9 +1678,10 @@
 	tot_faceListMem =			sizeof(LinkNode *) * ps->bucketsX * ps->bucketsY;
 	tot_faceFlagMem =			sizeof(char) * ps->dm_totface;
 	tot_bucketFlagMem =			sizeof(char) * ps->bucketsX * ps->bucketsY;
+#ifndef PROJ_DEBUG_NOSEAMBLEED
 	if (ps->projectSeamBleed > 0.0) /* UV Seams for bleeding */
 		tot_bucketVertFacesMem =	sizeof(LinkNode *) * ps->dm_totvert;
-	
+#endif
 
 	ps->projectArena =
 		BLI_memarena_new(	tot_bucketMem +
@@ -1656,16 +1693,19 @@
 	ps->projectFaces= (LinkNode **)BLI_memarena_alloc( ps->projectArena, tot_faceListMem);
 	ps->projectFaceFlags = (char *)BLI_memarena_alloc( ps->projectArena, tot_faceFlagMem);
 	ps->projectBucketFlags= (char *)BLI_memarena_alloc( ps->projectArena, tot_bucketFlagMem);
+#ifndef PROJ_DEBUG_NOSEAMBLEED
 	if (ps->projectSeamBleed > 0.0)
 		ps->projectVertFaces= (LinkNode **)BLI_memarena_alloc( ps->projectArena, tot_bucketVertFacesMem);
+#endif
 	
 	memset(ps->projectBuckets,		0, tot_bucketMem);
 	memset(ps->projectFaces,		0, tot_faceListMem);
 	memset(ps->projectFaceFlags,	0, tot_faceFlagMem);
 	memset(ps->projectBucketFlags,	0, tot_bucketFlagMem);
+#ifndef PROJ_DEBUG_NOSEAMBLEED
 	if (ps->projectSeamBleed > 0.0)
 		memset(ps->projectVertFaces,	0, tot_bucketVertFacesMem);
-	
+#endif
 	Mat4Invert(ps->ob->imat, ps->ob->obmat);
 	
 	Mat3CpyMat4(mat, G.vd->viewinv);
@@ -2658,8 +2698,9 @@
 		/* setup projection painting data */
 		ps.projectIsBackfaceCull = 1;
 		ps.projectIsOcclude = 1;
+#ifndef PROJ_DEBUG_NOSEAMBLEED
 		ps.projectSeamBleed = 2.0; /* pixel num to bleed  */
-		
+#endif
 		project_paint_begin(&ps, mval);
 		
 	} else {





More information about the Bf-blender-cvs mailing list