[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17318] branches/projection-paint/source/ blender/src/imagepaint.c: perspective mode now works with seam bleeding.

Campbell Barton ideasman42 at gmail.com
Tue Nov 4 11:17:43 CET 2008


Revision: 17318
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17318
Author:   campbellbarton
Date:     2008-11-04 11:17:43 +0100 (Tue, 04 Nov 2008)

Log Message:
-----------
perspective mode now works with seam bleeding.

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-04 09:21:27 UTC (rev 17317)
+++ branches/projection-paint/source/blender/src/imagepaint.c	2008-11-04 10:17:43 UTC (rev 17318)
@@ -421,7 +421,7 @@
 
 
 /* check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison */
-static int project_bucket_point_occluded(ProjectPaintState *ps, int bucket_index, int orig_face, float pixelScreenCo[3])
+static int project_bucket_point_occluded(ProjectPaintState *ps, int bucket_index, int orig_face, float pixelScreenCo[4])
 {
 	LinkNode *node = ps->projectFaces[bucket_index];
 	MFace *mf;
@@ -833,45 +833,62 @@
 	return(Inp2f(u,h)/Inp2f(u,u));
 }
 
+static screen_px_from_ortho(
+		ProjectPaintState *ps, float *uv,
+		float *v1co, float *v2co, float *v3co, /* Screenspace coords */
+		float *uv1co, float *uv2co, float *uv3co,
+		float *pixelScreenCo )
+{
+	float w1, w2, w3, wtot; /* weights for converting the pixel into 3d screenspace coords */
+	w1 = AreaF2Dfl(uv2co, uv3co, uv);
+	w2 = AreaF2Dfl(uv3co, uv1co, uv);
+	w3 = AreaF2Dfl(uv1co, uv2co, uv);
+	
+	wtot = w1 + w2 + w3;
+	w1 /= wtot; w2 /= wtot; w3 /= wtot;
+	
+	pixelScreenCo[0] = v1co[0]*w1 + v2co[0]*w2 + v3co[0]*w3;
+	pixelScreenCo[1] = v1co[1]*w1 + v2co[1]*w2 + v3co[1]*w3;
+	pixelScreenCo[2] = v1co[2]*w1 + v2co[2]*w2 + v3co[2]*w3;	
+}
 
-#define pixel_size 4
-static void project_paint_uvpixel_init(
-		ProjectPaintState *ps, ProjectScanline *sc, ImBuf *ibuf, float *uv,
-		float *v1co, float *v2co, float *v3co,
+static screen_px_from_persp(
+		ProjectPaintState *ps, float *uv,
+		float *v1co, float *v2co, float *v3co, /* Worldspace coords */
 		float *uv1co, float *uv2co, float *uv3co,
-		int x, int y, int face_index,
-		float *pixelScreenCo /* can provide own own coords, use for seams when we want to bleed our from the original location */
-) {
-	float pixelScreenCo_own[3]; /* for testing occlusion we need the depth too, but not for saving into ProjectPixel */
-	int bucket_index;
+		float *pixelScreenCo )
+{
+	float w1, w2, w3, wtot; /* weights for converting the pixel into 3d screenspace coords */
+	w1 = AreaF2Dfl(uv2co, uv3co, uv);
+	w2 = AreaF2Dfl(uv3co, uv1co, uv);
+	w3 = AreaF2Dfl(uv1co, uv2co, uv);
 	
-	ProjectPixel *projPixel;
+	wtot = w1 + w2 + w3;
+	w1 /= wtot; w2 /= wtot; w3 /= wtot;
 	
+	pixelScreenCo[0] = v1co[0]*w1 + v2co[0]*w2 + v3co[0]*w3;
+	pixelScreenCo[1] = v1co[1]*w1 + v2co[1]*w2 + v3co[1]*w3;
+	pixelScreenCo[2] = v1co[2]*w1 + v2co[2]*w2 + v3co[2]*w3;	
+	pixelScreenCo[3] = 1.0;
 	
-	/* pixelScreenCo not provided? - calculate our own */
-	if (pixelScreenCo==NULL) {
-		float w1, w2, w3, wtot; /* weights for converting the pixel into 3d worldspace coords */
+	Mat4MulVec4fl(ps->projectMat, pixelScreenCo);
+	
+	// if( pixelScreenCo[3] > 0.001 ) { ??? TODO
+	/* screen space, not clamped */
+	pixelScreenCo[0] = (float)(curarea->winx/2.0)+(curarea->winx/2.0)*pixelScreenCo[0]/pixelScreenCo[3];	
+	pixelScreenCo[1] = (float)(curarea->winy/2.0)+(curarea->winy/2.0)*pixelScreenCo[1]/pixelScreenCo[3];
+	pixelScreenCo[2] = pixelScreenCo[2]/pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
+}
 
-		pixelScreenCo = pixelScreenCo_own;
-		/* Get the world coord for the point in uv space */
-		if (ps->projectIsOrtho) {
-			w1 = AreaF2Dfl(uv2co, uv3co, uv);
-			w2 = AreaF2Dfl(uv3co, uv1co, uv);
-			w3 = AreaF2Dfl(uv1co, uv2co, uv);
-		} else { /* prespective mode needs an interpolation */
-			w1 = AreaF2Dfl(uv2co, uv3co, uv) / v1co[2];
-			w2 = AreaF2Dfl(uv3co, uv1co, uv) / v2co[2];
-			w3 = AreaF2Dfl(uv1co, uv2co, uv) / v3co[2];
-		}
-		
-		wtot = w1 + w2 + w3;
-		w1 /= wtot; w2 /= wtot; w3 /= wtot;
-		
-		pixelScreenCo[0] = v1co[0]*w1 + v2co[0]*w2 + v3co[0]*w3;
-		pixelScreenCo[1] = v1co[1]*w1 + v2co[1]*w2 + v3co[1]*w3;
-		pixelScreenCo[2] = v1co[2]*w1 + v2co[2]*w2 + v3co[2]*w3;
-	}
+/* can provide own own coords, use for seams when we want to bleed our from the original location */
+
+#define pixel_size 4
+static void project_paint_uvpixel_init(ProjectPaintState *ps, ProjectScanline *sc, ImBuf *ibuf, float *uv,	int x, int y, int face_index, float *pixelScreenCo)
+{
+	int bucket_index;
 	
+	ProjectPixel *projPixel;
+	
 	bucket_index = project_paint_BucketOffset(ps, pixelScreenCo);
 	
 	/* even though it should be clamped, in some cases it can still run over */
@@ -919,6 +936,7 @@
 	int min_px[2], max_px[2]; /* UV Bounds converted to int's for pixel */
 	float *v1co, *v2co, *v3co; /* for convenience only, these will be assigned to mf->v1,2,3 or mf->v1,3,4 */
 	float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
+	float pixelScreenCo[4], pixelScreenCoXMin[4], pixelScreenCoXMax[4];
 	int i, j;
 	
 	/* scanlines since quads can have 2 triangles intersecting the same vertical location */
@@ -946,25 +964,75 @@
 			CLAMP(min_px[0], 0, ibuf->x);
 			CLAMP(max_px[0], 0, ibuf->x);
 			
-			v1co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[0])) ];
-			v2co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[1])) ];
-			v3co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[2])) ];
-			
 			uv1co = tf->uv[sc->v[0]];
 			uv2co = tf->uv[sc->v[1]];
 			uv3co = tf->uv[sc->v[2]];
 			
-			for (x = min_px[0]; x < max_px[0]; x++) {
+			if (ps->projectIsOrtho) {
+				v1co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[0])) ];
+				v2co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[1])) ];
+				v3co = ps->projectVertScreenCos[ (*(&mf->v1 + sc->v[2])) ];
+				
+				for (x = min_px[0]; x < max_px[0]; x++) {
+					uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+					screen_px_from_ortho(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCo);
+					project_paint_uvpixel_init(ps, sc, ibuf, uv, x,y,face_index, pixelScreenCo);
+				}
+				
+				/* interpolation is faster - no workies :( */
+				/*
+				x = min_px[0];
 				uv[0] = (((float)x)+0.5) / (float)ibuf->x;
-				project_paint_uvpixel_init(ps, sc, ibuf, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, x,y,face_index, NULL);
+				screen_px_from_ortho(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCoXMin);
+				
+				x = max_px[0]-1;
+				uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+				screen_px_from_ortho(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCoXMax);
+				
+				for (x = min_px[0]; x < max_px[0]; x++) {
+					uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+					VecLerpf(pixelScreenCo, pixelScreenCoXMin, pixelScreenCoXMax, ((float)x) / ((float)(max_px[0]-min_px[0])) );
+					project_paint_uvpixel_init(ps, sc, ibuf, uv, x,y, face_index, pixelScreenCo);
+				}
+				*/
+				
+			} else {
+				v1co = ps->dm_mvert[ (*(&mf->v1 + sc->v[0])) ].co;
+				v2co = ps->dm_mvert[ (*(&mf->v1 + sc->v[1])) ].co;
+				v3co = ps->dm_mvert[ (*(&mf->v1 + sc->v[2])) ].co;
+				
+				for (x = min_px[0]; x < max_px[0]; x++) {
+					uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+					screen_px_from_persp(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCo);
+					project_paint_uvpixel_init(ps, sc, ibuf, uv, x,y,face_index, pixelScreenCo);
+				}
+				
+				
+				/* interpolation is faster */
+				/*
+				x = min_px[0];
+				uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+				screen_px_from_persp(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCoXMin);
+				
+				x = max_px[0]-1;
+				uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+				screen_px_from_persp(ps, uv, v1co,v2co,v3co, uv1co,uv2co,uv3co, pixelScreenCoXMax);
+				
+				for (x = min_px[0]; x < max_px[0]; x++) {
+					uv[0] = (((float)x)+0.5) / (float)ibuf->x;
+					VecLerpf(pixelScreenCo, pixelScreenCoXMin, pixelScreenCoXMax, ((float)x) / ((float)(max_px[0]-min_px[0])) );
+					project_paint_uvpixel_init(ps, sc, ibuf, uv, x,y, face_index, pixelScreenCo);
+				}
+				*/
 			}
+			
 		}
 	}
 	
 	/* 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 */
-		float inset_screen_cos[4][3]; /* expanded UV's */
+		float insetCos[4][3]; /* expanded UV's */
 		float cent[3];
 		float *uv_seam_quads[4][4];
 		float *edge_verts[4][2];
@@ -972,39 +1040,49 @@
 		float fac;
 		int totuvseamquads = 0;
 		
-		VECCOPY2D(inset_screen_cos[0], ps->projectVertScreenCos[ mf->v1 ]);
-		VECCOPY2D(inset_screen_cos[1], ps->projectVertScreenCos[ mf->v2 ]);
-		VECCOPY2D(inset_screen_cos[2], ps->projectVertScreenCos[ mf->v3 ]);
+		if (ps->projectIsOrtho) {
+			VECCOPY(insetCos[0], ps->projectVertScreenCos[ mf->v1 ]);
+			VECCOPY(insetCos[1], ps->projectVertScreenCos[ mf->v2 ]);
+			VECCOPY(insetCos[2], ps->projectVertScreenCos[ mf->v3 ]);
+			if (mf->v4)
+				VECCOPY(insetCos[3], ps->projectVertScreenCos[ mf->v4 ]);
+		} else {
+			VECCOPY(insetCos[0], ps->dm_mvert[ mf->v1 ].co);
+			VECCOPY(insetCos[1], ps->dm_mvert[ mf->v2 ].co);
+			VECCOPY(insetCos[2], ps->dm_mvert[ mf->v3 ].co);
+			if (mf->v4)
+				VECCOPY(insetCos[3], ps->dm_mvert[ mf->v4 ].co);
+		}
+		
+			
 		if (mf->v4) {
-			VECCOPY2D(inset_screen_cos[3], ps->projectVertScreenCos[ mf->v4 ]);
+			cent[0] = (insetCos[0][0] + insetCos[1][0] + insetCos[2][0] + insetCos[3][0]) / 4.0;
+			cent[1] = (insetCos[0][1] + insetCos[1][1] + insetCos[2][1] + insetCos[3][1]) / 4.0;
+			cent[2] = (insetCos[0][2] + insetCos[1][2] + insetCos[2][2] + insetCos[3][2]) / 4.0;
 			
-			cent[0] = (inset_screen_cos[0][0] + inset_screen_cos[1][0] + inset_screen_cos[2][0] + inset_screen_cos[3][0]) / 4.0;
-			cent[1] = (inset_screen_cos[0][1] + inset_screen_cos[1][1] + inset_screen_cos[2][1] + inset_screen_cos[3][1]) / 4.0;
-			cent[2] = (inset_screen_cos[0][2] + inset_screen_cos[1][2] + inset_screen_cos[2][2] + inset_screen_cos[3][2]) / 4.0;
-			
 		} else {
-			cent[0] = (inset_screen_cos[0][0] + inset_screen_cos[1][0] + inset_screen_cos[2][0]) / 3.0;
-			cent[1] = (inset_screen_cos[0][1] + inset_screen_cos[1][1] + inset_screen_cos[2][1]) / 3.0;
-			cent[2] = (inset_screen_cos[0][2] + inset_screen_cos[1][2] + inset_screen_cos[2][2]) / 3.0;
+			cent[0] = (insetCos[0][0] + insetCos[1][0] + insetCos[2][0]) / 3.0;
+			cent[1] = (insetCos[0][1] + insetCos[1][1] + insetCos[2][1]) / 3.0;
+			cent[2] = (insetCos[0][2] + insetCos[1][2] + insetCos[2][2]) / 3.0;
 		}
 		
-		Vec2Subf(inset_screen_cos[0], inset_screen_cos[0], cent);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list