[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17372] branches/projection-paint/source/ blender/src/imagepaint.c: mistake made initializing seam UV's fail

Campbell Barton ideasman42 at gmail.com
Sun Nov 9 04:34:23 CET 2008


Revision: 17372
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17372
Author:   campbellbarton
Date:     2008-11-09 04:34:22 +0100 (Sun, 09 Nov 2008)

Log Message:
-----------
mistake made initializing seam UV's fail

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-09 02:47:30 UTC (rev 17371)
+++ branches/projection-paint/source/blender/src/imagepaint.c	2008-11-09 03:34:22 UTC (rev 17372)
@@ -134,6 +134,7 @@
 #define PROJ_BUCKET_DIV 128 /* TODO - test other values, this is a guess, seems ok */
 
 //#define PROJ_DEBUG_PAINT 1
+#define PROJ_DEBUG_NOSCANLINE 1
 //#define PROJ_DEBUG_NOSEAMBLEED 1
 
 /* projectFaceSeamFlags options */
@@ -213,6 +214,11 @@
 	float viewHeight;
 } ProjectPaintState;
 
+typedef struct ProjectScanline {
+	int v[3]; /* verts for this scanline, 0,1,2 or 0,2,3 */
+	float x_limits[2]; /* UV min|max for this scanline */
+} ProjectScanline;
+
 typedef struct ProjectPixel {
 	float projCo2D[2]; /* the floating point screen projection of this pixel */
 	char *pixel;
@@ -700,6 +706,101 @@
 	}
 }
 
+static int project_face_scanline(ProjectScanline *sc, float y_level, float v1[2], float v2[2], float v3[2], float v4[2])
+{	
+	/* Create a scanlines for the face at this Y level 
+	 * triangles will only ever have 1 scanline, quads may have 2 */
+	int totscanlines = 0;
+	short i1=0,i2=0,i3=0;
+	
+	if (v4) { /* This is a quad?*/
+		int i4=0, i_mid=0;
+		float xi1, xi2, xi3, xi4, xi_mid;
+				
+		i1 = line_isect_y(v1, v2, y_level, &xi1);
+		if (i1 != ISECT_TRUE_P2) /* rare cases we could be on the line, in these cases we dont want to intersect with the same point twice */
+			i2 = line_isect_y(v2, v3, y_level, &xi2);
+		
+		if (i1 && i2) { /* both the first 2 edges intersect, this means the second half of the quad wont intersect */
+			sc->v[0] = 0;
+			sc->v[1] = 1;
+			sc->v[2] = 2;
+			sc->x_limits[0] = MIN2(xi1, xi2);
+			sc->x_limits[1] = MAX2(xi1, xi2);
+			totscanlines = 1;
+		} else {
+			if (i2 != ISECT_TRUE_P2) 
+				i3 = line_isect_y(v3, v4, y_level, &xi3);
+			if (i1 != ISECT_TRUE_P1 && i3 != ISECT_TRUE_P2) 
+				i4 = line_isect_y(v4, v1, y_level, &xi4);
+			
+			if (i3 && i4) { /* second 2 edges only intersect, same as above */
+				sc->v[0] = 0;
+				sc->v[1] = 2;
+				sc->v[2] = 3;
+				sc->x_limits[0] = MIN2(xi3, xi4);
+				sc->x_limits[1] = MAX2(xi3, xi4);
+				totscanlines = 1;
+			} else {
+				/* OK - we have a not-so-simple case, both sides of the quad intersect.
+				 * Will need to have 2 scanlines */
+				if ((i1||i2) && (i3||i4)) {
+					i_mid = line_isect_y(v1, v3, y_level, &xi_mid);
+					/* it would be very rare this would be false, but possible */
+					sc->v[0] = 0;
+					sc->v[1] = 1;
+					sc->v[2] = 2;
+					sc->x_limits[0] = MIN2((i1?xi1:xi2), xi_mid);
+					sc->x_limits[1] = MAX2((i1?xi1:xi2), xi_mid);
+					
+					sc++;
+					sc->v[0] = 0;
+					sc->v[1] = 2;
+					sc->v[2] = 3;
+					sc->x_limits[0] = MIN2((i3?xi3:xi4), xi_mid);
+					sc->x_limits[1] = MAX2((i3?xi3:xi4), xi_mid);
+					
+					totscanlines = 2;
+				}
+			}
+		}
+	} else { /* triangle */
+		int i = 0;
+		
+		i1 = line_isect_y(v1, v2, y_level, &sc->x_limits[0]);
+		if (i1) i++;
+		
+		if (i1 != ISECT_TRUE_P2) {
+			i2 = line_isect_y(v2, v3, y_level, &sc->x_limits[i]);
+			if (i2) i++;
+		}
+		
+		/* if the triangle intersects then the first 2 lines must */
+		if (i!=0) {
+			if (i!=2) {
+				/* if we are here then this really should not fail since 2 edges MUST intersect  */
+				if (i1 != ISECT_TRUE_P1 && i2 != ISECT_TRUE_P2) {
+					i3 = line_isect_y(v3, v1, y_level, &sc->x_limits[i]);
+					if (i3) i++;
+					
+				}
+			}
+			
+			if (i==2) {
+				if (sc->x_limits[0] > sc->x_limits[1]) {
+					SWAP(float, sc->x_limits[0], sc->x_limits[1]);
+				}
+				sc->v[0] = 0;
+				sc->v[1] = 1;
+				sc->v[2] = 2;
+				totscanlines = 1;
+			}
+		}
+	}
+	/* done setting up scanlines */
+	return totscanlines;
+}
+
 static int cmp_uv(float vec2a[2], float vec2b[2])
 {
 	return ((fabs(vec2a[0]-vec2b[0]) < 0.0001) && (fabs(vec2a[1]-vec2b[1]) < 0.0001)) ? 1:0;
@@ -1238,6 +1339,12 @@
 	float w[3];
 	int i1,i2,i3;
 	
+	/* scanlines since quads can have 2 triangles intersecting the same vertical location */
+#ifndef PROJ_DEBUG_NOSCANLINE 
+	ProjectScanline scanlines[2];
+	ProjectScanline *sc;
+	int totscanlines; /* can only be 1 or 2, oh well */
+#endif
 	i = mf->v4 ? 1:0;
 	do {
 		if (i==1) {
@@ -1340,26 +1447,22 @@
 			/* Now create new UV's for the seam face */
 			float (*outset_uv)[2];
 			float insetCos[4][3]; /* expanded UV's */
+			float cent[3];
 			float *uv_seam_quads[4][4];
 			float *edge_verts_inset[4][2];
 			float *edge_verts[4][2];
+			float fac;
 			float *vCoSS[4]; /* vertex screenspace coords */
 			
 			float bucket_clip_edges[4][2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */
 			int totuvseamquads = 0;
 			int fidx1, fidx2; /* face edge pairs - loop throuh these ((0,1), (1,2), (2,3), (3,0)) or ((0,1), (1,2), (2,0)) for a tri */
 			
-			/* seam subsection is a quad subsection of the seam that intersects the bucket */
-			float seam_subsection[4][2];
-			float fac1, fac2, ftot; /* factors for converting the distance along an edge from screenspace to uvspace */
-			float edge_verts_inset_clip[2][3]; /* inset clipped line */
+			outset_uv = ps->projectFaceSeamUVs[face_index];
 			
-			outset_uv = ps->projectFaceSeamUVs[face_index];
-			if (outset_uv[0][0]==MAXFLOAT) {
+			if (outset_uv[0][0]==MAXFLOAT) /* first time initialize */
 				uv_image_outset(tf->uv, outset_uv, ps->projectSeamBleed, ibuf->x, ibuf->y, mf->v4);
-			}
 			
-			
 			vCoSS[0] = ps->projectVertScreenCos[ mf->v1 ];
 			vCoSS[1] = ps->projectVertScreenCos[ mf->v2 ];
 			vCoSS[2] = ps->projectVertScreenCos[ mf->v3 ];
@@ -1391,7 +1494,13 @@
 			
 			
 			for (i=0; i< totuvseamquads; i++) { /* loop over our seams */
+				
+			
 				/* make a quad spanning the subsection of the face the bucket intersects with */
+				float seam_subsection[4][2];
+				float fac1, fac2, ftot;
+				float edge_verts_inset_clip[2][3];
+
 				ftot = Vec2Lenf(edge_verts[i][0], edge_verts[i][1]);
 				fac1 = Vec2Lenf(edge_verts[i][0], bucket_clip_edges[i][0]) / ftot;
 				fac2 = Vec2Lenf(edge_verts[i][0], bucket_clip_edges[i][1]) / ftot;
@@ -1429,15 +1538,15 @@
 								else					screen_px_from_persp(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCo);
 								*/
 								
-								/* Since this is a seam we need to work out the closest point on the UV edge this pixel is */
-								fac1 = lambda_cp_line2(uv, seam_subsection[0], seam_subsection[1]); /* these 2 points in the seam_subsection happen to run along the inside */
-								
-								if (fac1 < 0.0) {
+								/* Since this is a seam we need to work out where on the line this pixel is */
+								//fac = lambda_cp_line2(uv, uv_seam_quads[i][0], uv_seam_quads[i][1]);
+								fac = lambda_cp_line2(uv, seam_subsection[0], seam_subsection[1]);
+								if (fac<0.0) {
 									VECCOPY(pixelScreenCo, edge_verts_inset_clip[0]);
-								} else if (fac1 > 1.0) {
+								} else if (fac>1.0) {
 									VECCOPY(pixelScreenCo, edge_verts_inset_clip[1]);
 								} else {
-									VecLerpf(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac1);
+									VecLerpf(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac);
 								}
 								
 								if (!ps->projectIsOrtho) {
@@ -1644,9 +1753,11 @@
 		}
 	}
 	
-	if (!mf->v4 && ps->projectSeamBleed > 0.0) {
-		ps->projectFaceSeamFlags[face_index] |= PROJ_FACE_NOSEAM4; /* so this wont show up as an untagged egde */
-		ps->projectFaceSeamUVs[face_index][0][0] = MAXFLOAT; /* set as uninitialized */
+	if (ps->projectSeamBleed > 0.0) {
+		if (!mf->v4) {
+			ps->projectFaceSeamFlags[face_index] |= PROJ_FACE_NOSEAM4; /* so this wont show up as an untagged egde */
+		}
+		**ps->projectFaceSeamUVs[face_index] = MAXFLOAT; /* set as uninitialized */
 	}
 }
 
@@ -1744,7 +1855,7 @@
 	if (ps->projectSeamBleed > 0.0) {
 		ps->projectVertFaces= (LinkNode **)BLI_memarena_alloc( ps->projectArena, tot_bucketVertFacesMem);
 		ps->projectFaceSeamFlags = (char *)BLI_memarena_alloc( ps->projectArena, tot_faceSeamFlagMem);
-		ps->projectFaceSeamUVs=  BLI_memarena_alloc( ps->projectArena, tot_faceSeamUVMem);
+		ps->projectFaceSeamUVs= BLI_memarena_alloc( ps->projectArena, tot_faceSeamUVMem);
 	}
 #endif
 	





More information about the Bf-blender-cvs mailing list