[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17526] branches/projection-paint/source/ blender: * added option "Normal", same as the vpaint option, gives more natural looking brush strokes.

Campbell Barton ideasman42 at gmail.com
Fri Nov 21 04:09:51 CET 2008


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

Log Message:
-----------
* added option "Normal", same as the vpaint option, gives more natural looking brush strokes.
* faces that were ignored were also not taken into acount when checking UV seams - causng bleed not to work properly in some cases.
* commented early pixel filling loop exit that fails in some cases.

Modified Paths:
--------------
    branches/projection-paint/source/blender/makesdna/DNA_scene_types.h
    branches/projection-paint/source/blender/src/buttons_editing.c
    branches/projection-paint/source/blender/src/imagepaint.c

Modified: branches/projection-paint/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- branches/projection-paint/source/blender/makesdna/DNA_scene_types.h	2008-11-21 02:23:46 UTC (rev 17525)
+++ branches/projection-paint/source/blender/makesdna/DNA_scene_types.h	2008-11-21 03:09:48 UTC (rev 17526)
@@ -803,10 +803,11 @@
 #define IMAGEPAINT_DRAW_TOOL_DRAWING	4
 
 /* projection painting only */
-#define IMAGEPAINT_PROJECT_XRAY	8
-#define IMAGEPAINT_PROJECT_BACKFACE	16
+#define IMAGEPAINT_PROJECT_XRAY			8
+#define IMAGEPAINT_PROJECT_BACKFACE		16
 #define IMAGEPAINT_PROJECT_IGNORE_SEAMS	32
 #define IMAGEPAINT_PROJECT_CLONE_LAYER	64
+#define IMAGEPAINT_PROJECT_FLAT			128
 
 /* toolsettings->uvcalc_flag */
 #define UVCALC_FILLHOLES			1

Modified: branches/projection-paint/source/blender/src/buttons_editing.c
===================================================================
--- branches/projection-paint/source/blender/src/buttons_editing.c	2008-11-21 02:23:46 UTC (rev 17525)
+++ branches/projection-paint/source/blender/src/buttons_editing.c	2008-11-21 03:09:48 UTC (rev 17526)
@@ -6373,7 +6373,9 @@
 			/* Projection Painting */
 			uiBlockBeginAlign(block);
 			uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_XRAY, B_NOP, "Occlude",	xco+10,yco-70,butw,19, &settings->imapaint.flag, 0, 0, 0, 0, "Only paint onto the faces directly under the brush (slower)");
-			uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_BACKFACE, B_NOP, "Backface Cull",	xco+10,yco-90,butw,19, &settings->imapaint.flag, 0, 0, 0, 0, "Ignore faces pointing away from the view (faster)");
+			uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_BACKFACE, B_NOP, "Cull",	xco+10,yco-90,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Ignore faces pointing away from the view (faster)");
+			uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_FLAT, B_NOP, "Normal",	xco+10+butw/2,yco-90,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Ignore faces pointing away from the view (faster)");
+			
 			uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_IGNORE_SEAMS, B_NOP, "Bleed",	xco+10,yco-110,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)");
 			uiDefButF(block, NUM, B_NOP, "", xco+10 + (butw/2),yco-110,butw/2,19, &settings->imapaint.seam_bleed, 2.0, 8.0, 0, 0, "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)");
 			uiBlockEndAlign(block);

Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c	2008-11-21 02:23:46 UTC (rev 17525)
+++ branches/projection-paint/source/blender/src/imagepaint.c	2008-11-21 03:09:48 UTC (rev 17526)
@@ -178,6 +178,9 @@
 #define PROJ_BUCKET_INIT		1<<0
 // #define PROJ_BUCKET_CLONE_INIT	1<<1
 
+/* vert flags */
+#define PROJ_VERT_CULL 1
+
 /* only for readability */
 #define PROJ_BUCKET_LEFT	0
 #define PROJ_BUCKET_RIGHT	1
@@ -221,6 +224,7 @@
 	char *faceSeamFlags;				/* store info about faces, if they are initialized etc*/
 	float (*faceSeamUVs)[4][2];			/* expanded UVs for faces to use as seams */
 	LinkNode **vertFaces;				/* Only needed for when seam_bleed_px is enabled, use to find UV seams */
+	char *vertFlags;					/* store options per vert, now only store if the vert is pointing away from the view */
 #endif
 	int buckets_x;						/* The size of the bucket grid, the grid span's screen_min/screen_max so you can paint outsize the screen or with 2 brushes at once */
 	int buckets_y;
@@ -235,6 +239,7 @@
 	short do_occlude;			/* Use raytraced occlusion? - ortherwise will paint right through to the back*/
 	short do_backfacecull;	/* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
 	short is_ortho;
+	short do_mask_normal;			/* mask out pixels based on their normals */
 #ifndef PROJ_DEBUG_NOSEAMBLEED
 	float seam_bleed_px;
 #endif
@@ -245,6 +250,7 @@
 	float projectMat[4][4];		/* Projection matrix, use for getting screen coords */
 	float viewMat[4][4];
 	float viewDir[3];			/* View vector, use for do_backfacecull and for ray casting with an ortho viewport  */
+	float viewPos[3];			/* View location in object relative 3D space, so can compare to verts  */
 	
 	float screen_min[2];			/* 2D bounds for mesh verts on the screen's plane (screenspace) */
 	float screen_max[2]; 
@@ -278,8 +284,10 @@
 	PixelStore origColor;
 	PixelPointer pixel;
 	
-	short image_index; /* if anyone wants to paint onto more then 32000 images they can bite me */
-	short bb_cell_index;
+	float mask;			/* for various reasons we may want to mask out painting onto this pixel */
+	
+	short image_index; /* if anyone wants to paint onto more then 32768 images they can bite me */
+	unsigned char bb_cell_index;
 } ProjPixel;
 
 typedef struct ProjPixelClone {
@@ -583,6 +591,19 @@
 	}
 }
 
+static VecWeightf(float p[3], float v1[3], float v2[3], float v3[3], float w[3])
+{
+	p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
+	p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2];
+	p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2];
+}
+
+static Vec2Weightf(float p[3], float v1[3], float v2[3], float v3[3], float w[3])
+{
+	p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2];
+	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])
 {
 	BarycentricWeightsSimple2f(v1,v2,v3,pt,w);
@@ -666,12 +687,10 @@
 	
 	tf = ps->dm_mtface + face_index;
 	
-	if (side==0) {
-		uv[0] = tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[2][0]*w[2];
-		uv[1] = tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[2][1]*w[2];
+	if (side == 0) {
+		Vec2Weightf(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
 	} else { /* QUAD */
-		uv[0] = tf->uv[0][0]*w[0] + tf->uv[2][0]*w[1] + tf->uv[3][0]*w[2];
-		uv[1] = tf->uv[0][1]*w[0] + tf->uv[2][1]*w[1] + tf->uv[3][1]*w[2];
+		Vec2Weightf(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
 	}
 	
 	ibuf = BKE_image_get_ibuf((Image *)tf->tpage, NULL); /* TODO - this may be slow */
@@ -774,9 +793,8 @@
 /* Check if a screenspace location is occluded by any other faces
  * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
  * and dosn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
-static int project_bucket_point_occluded(ProjPaintState *ps, int bucket_index, int orig_face, float pixelScreenCo[4])
+static int project_bucket_point_occluded(ProjPaintState *ps, LinkNode *bucketFace, int orig_face, float pixelScreenCo[4])
 {
-	LinkNode *node = ps->bucketFaces[bucket_index];
 	MFace *mf;
 	int face_index;
 	int isect_ret;
@@ -784,8 +802,8 @@
 	/* 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 */
 	
-	while (node) {
-		face_index = (int)node->link;
+	while (bucketFace) {
+		face_index = (int)bucketFace->link;
 		
 		if (orig_face != face_index) {
 			
@@ -812,7 +830,7 @@
 				return 1; 
 			}
 		}
-		node = node->next;
+		bucketFace = bucketFace->next;
 	}
 	
 	return 0;
@@ -1151,20 +1169,19 @@
 		float w[3])
 {
 	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];	
+	VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
 }
 
 /* same as screen_px_from_ortho except we need to take into account
  * the perspective W coord for each vert */
 static void screen_px_from_persp(
 		ProjPaintState *ps, float uv[2],
-		float v1co[3], float v2co[3], float v3co[3], /* Worldspace coords */
+		float v1co[3], float v2co[3], float v3co[3], /* screenspace coords */
 		float uv1co[2], float uv2co[2], float uv3co[2],
 		float pixelScreenCo[4],
 		float w[3])
 {
+
 	float wtot_inv, wtot;
 	BarycentricWeightsSimple2f(uv1co,uv2co,uv3co,uv,w);
 	
@@ -1185,149 +1202,230 @@
 	}
 	/* done re-weighting */
 	
+	VecWeightf(pixelScreenCo, v1co, v2co, v3co, w);
+}
+
+#if 0
+static void screen_px_from_persp(
+		ProjPaintState *ps, float uv[2],
+		float v1co[3], float v2co[3], float v3co[3], /* Worldspace coords */
+		float uv1co[2], float uv2co[2], float uv3co[2],
+		float pixelScreenCo[4],
+		float w[3])
+{
+	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];	
+	pixelScreenCo[2] = v1co[2]*w[0] + v2co[2]*w[1] + v3co[2]*w[2];
+	pixelScreenCo[3] = 1.0;
+	
+	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 */
 }
+#endif
 
 
 /* Only run this function once for new ProjPixelClone's */
 #define IMA_CHAR_PX_SIZE 4
 
-/* run this function when we know a bucket's, face's pixel can be initialized,
- * adding to the LinkList 'ps->bucketRect' */
-static void project_paint_uvpixel_init(ProjPaintState *ps, int thread_index, ImBuf *ibuf, short x, short y, int bucket_index, int face_index, int image_index, float pixelScreenCo[4], int side, float w[3])
-{
-	ProjPixel *projPixel;
-	short size;
-	
-	// printf("adding px (%d %d), (%f %f)\n", x,y,uv[0],uv[1]);
-	
-	
-	/* Use screen_min to make (0,0) the bottom left of the bounds 
-	 * Then this can be used to index the bucket array */
-	
-	/* Is this UV visible from the view? - raytrace */
-	/* project_paint_PickFace is less complex, use for testing */
-	//if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == face_index) {
-	if (ps->do_occlude==0 || !project_bucket_point_occluded(ps, bucket_index, face_index, pixelScreenCo)) {
+
+/* run this outside project_paint_uvpixel_init since pixels with mask 0 dont need init */
+float project_paint_uvpixel_mask(
+		ProjPaintState *ps,
+		int face_index,
+		int side,
+		float w[3]
+) {
+	float mask;
+	/* calculate mask */
+	if (ps->do_mask_normal) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list