[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17491] branches/projection-paint/source/ blender: Added option to use another UV layer as a clone source, to paint from one uv layer's image and UVs into the active layer.

Campbell Barton ideasman42 at gmail.com
Tue Nov 18 04:28:51 CET 2008


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

Log Message:
-----------
Added option to use another UV layer as a clone source, to paint from one uv layer's image and UVs into the active layer.

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-18 01:53:52 UTC (rev 17490)
+++ branches/projection-paint/source/blender/makesdna/DNA_scene_types.h	2008-11-18 03:28:50 UTC (rev 17491)
@@ -348,6 +348,7 @@
 	
 	/* for projection painting only - todo - use flags */
 	float seam_bleed;
+	int clone_layer, pad;
 } ImagePaintSettings;
 
 typedef struct ParticleBrushData {
@@ -805,6 +806,7 @@
 #define IMAGEPAINT_PROJECT_XRAY	8
 #define IMAGEPAINT_PROJECT_BACKFACE	16
 #define IMAGEPAINT_PROJECT_IGNORE_SEAMS	32
+#define IMAGEPAINT_PROJECT_CLONE_LAYER	64
 
 /* 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-18 01:53:52 UTC (rev 17490)
+++ branches/projection-paint/source/blender/src/buttons_editing.c	2008-11-18 03:28:50 UTC (rev 17491)
@@ -6392,11 +6392,42 @@
 
 			yco -= 110;
 
-			uiBlockSetCol(block, TH_BUT_SETTING2);
-			id= (mtex)? (ID*)mtex->tex: NULL;
-			xco= std_libbuttons(block, 0, yco, 0, NULL, B_BTEXBROWSE, ID_TE, 0, id, NULL, &(G.buts->menunr), 0, 0, B_BTEXDELETE, 0, 0);
-			/*uiDefButBitS(block, TOG|BIT, BRUSH_FIXED_TEX, B_BRUSHCHANGE, "Fixed",	xco+5,yco,butw,19, &brush->flag, 0, 0, 0, 0, "Keep texture origin in fixed position");*/
-			uiBlockSetCol(block, TH_AUTO);
+			if (settings->imapaint.tool == PAINT_TOOL_CLONE) {
+				Object *ob = OBACT;
+				if (ob) {
+					Mesh *me = ob->data;
+					int layercount = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+					if (layercount>1 && layercount < 12) { /* could allow any number but limit of 11 means no malloc needed */
+						
+						butw = 80;
+						uiBlockBeginAlign(block);
+						uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_CLONE_LAYER, B_REDR, "Clone Layer",	0,yco,butw,20, &settings->imapaint.flag, 0, 0, 0, 0, "Use another UV layer as clone source, otherwise use 3D the cursor as the source");
+						
+						if (settings->imapaint.flag & IMAGEPAINT_PROJECT_CLONE_LAYER) {
+							char str_menu[384], *str_pt; /*384 allows for 11 layers */
+							
+							if (settings->imapaint.clone_layer >= layercount) {
+								settings->imapaint.clone_layer = 0;
+							}
+							
+	
+							
+							/*str_pt = (char *)MEM_mallocN(layercount*40 , "uvmenu"); str[0]='\0';*/
+							str_pt = str_menu;
+							str_pt[0]='\0';
+							mesh_layers_menu_concat(&me->fdata, CD_MTFACE, str_pt);
+							uiDefButI(block, MENU, B_NOP, str_menu ,butw,yco,(180-butw) + 20,20, &settings->imapaint.clone_layer, 0, 0, 0, 0, "Active UV Layer for editing");
+						}
+						uiBlockEndAlign(block);
+					}
+				}
+			} else {
+				uiBlockSetCol(block, TH_BUT_SETTING2);
+				id= (mtex)? (ID*)mtex->tex: NULL;
+				xco= std_libbuttons(block, 0, yco, 0, NULL, B_BTEXBROWSE, ID_TE, 0, id, NULL, &(G.buts->menunr), 0, 0, B_BTEXDELETE, 0, 0);
+				/*uiDefButBitS(block, TOG|BIT, BRUSH_FIXED_TEX, B_BRUSHCHANGE, "Fixed",	xco+5,yco,butw,19, &brush->flag, 0, 0, 0, 0, "Keep texture origin in fixed position");*/
+				uiBlockSetCol(block, TH_AUTO);
+			}
 		}
 	}
 }

Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c	2008-11-18 01:53:52 UTC (rev 17490)
+++ branches/projection-paint/source/blender/src/imagepaint.c	2008-11-18 03:28:50 UTC (rev 17491)
@@ -209,6 +209,7 @@
 	MVert 		   *dm_mvert;
 	MFace 		   *dm_mface;
 	MTFace 		   *dm_mtface;
+	MTFace 		   *dm_mtface_clone;	/* other UV layer, use for cloning between layers */
 	
 	/* projection painting only */
 	MemArena *arena;			/* use for alocating many pixel structs and link-lists */
@@ -239,8 +240,8 @@
 #endif
 	/* clone vars */
 	float clone_offset[2];
+	int clone_layer;			/* -1 when not in use */
 	
-	
 	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  */
@@ -1208,9 +1209,9 @@
 		ProjectPaintState *ps, float uv[2],
 		float v1co[3], float v2co[3], float v3co[3], /* Screenspace coords */
 		float uv1co[2], float uv2co[2], float uv3co[2],
-		float pixelScreenCo[4] )
+		float pixelScreenCo[4],
+		float w[3])
 {
-	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];
@@ -1223,9 +1224,10 @@
 		ProjectPaintState *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 pixelScreenCo[4],
+		float w[3])
 {
-	float w[3], wtot;
+	float wtot;
 	BarycentricWeightsSimple2f(uv1co,uv2co,uv3co,uv,w);
 	
 	/* re-weight from the 4th coord of each screen vert */
@@ -1251,7 +1253,7 @@
 
 /* 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(ProjectPaintState *ps, int thread_index, ImBuf *ibuf, short x, short y, int bucket_index, int face_index, int image_index, float pixelScreenCo[4])
+static void project_paint_uvpixel_init(ProjectPaintState *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])
 {
 	ProjectPixel *projPixel;
 	short size;
@@ -1309,21 +1311,63 @@
 		
 		/* done with view3d_project_float inline */
 		if (ps->tool==PAINT_TOOL_CLONE) {
-			float co[2];
-			
-			/* Initialize clone pixels - note that this is a bit of a waste since some of these are being indirectly initialized :/ */
-			/* TODO - possibly only run this for directly ativated buckets when cloning */
-			Vec2Subf(co, projPixel->projCo2D, ps->clone_offset);
-			
-			/* no need to initialize the bucket, we're only checking buckets faces and for this
-			 * the faces are alredy initialized in project_paint_delayed_face_init(...) */
-			if (ibuf->rect_float) {
-				if (!project_paint_PickColor(ps, co, ((ProjectPixelCloneFloat *)projPixel)->clonepx, NULL, 1)) {
-					((ProjectPixelCloneFloat *)projPixel)->clonepx[3] = 0; /* zero alpha - ignore */
+			if (ps->dm_mtface_clone) {
+				/* TODO - float buffer */
+				ImBuf *ibuf_other;
+				MTFace *tf_other = ps->dm_mtface_clone + face_index;
+				float *uvCo1, *uvCo2, *uvCo3; 
+				if (side==1) {
+					uvCo1 =  tf_other->uv[0];
+					uvCo2 =  tf_other->uv[2];
+					uvCo3 =  tf_other->uv[3];
+				} else {
+					uvCo1 =  tf_other->uv[0];
+					uvCo2 =  tf_other->uv[1];
+					uvCo3 =  tf_other->uv[2];
 				}
+				
+				((ProjectPixelClone *)projPixel)->clonepx[3] = 0;
+				
+				if (tf_other->tpage && ( ibuf_other = BKE_image_get_ibuf((Image *)tf_other->tpage, NULL) )) {
+					/* BKE_image_get_ibuf - TODO - this may be slow */
+						
+					float uv_other[2], x, y;
+					
+					uv_other[0] = w[0]*uvCo1[0] + w[1]*uvCo2[0] + w[2]*uvCo3[0];
+					uv_other[1] = w[0]*uvCo1[1] + w[1]*uvCo2[1] + w[2]*uvCo3[1];
+					
+					/* use */
+					x = (float)fmod(uv_other[0], 1.0);
+					y = (float)fmod(uv_other[1], 1.0);
+					
+					if (x < 0.0) x += 1.0;
+					if (y < 0.0) y += 1.0;
+					
+					x = x * ibuf_other->x - 0.5;
+					y = y * ibuf_other->y - 0.5;
+					
+					bicubic_interpolation_px(ibuf_other, x, y, NULL, ((ProjectPixelClone *)projPixel)->clonepx);
+				} else {
+					((ProjectPixelClone *)projPixel)->clonepx[3] = 0;
+				}
+				
 			} else {
-				if (!project_paint_PickColor(ps, co, NULL, ((ProjectPixelClone *)projPixel)->clonepx, 1)) {
-					((ProjectPixelClone *)projPixel)->clonepx[3] = 0; /* zero alpha - ignore */
+				float co[2];
+				
+				/* Initialize clone pixels - note that this is a bit of a waste since some of these are being indirectly initialized :/ */
+				/* TODO - possibly only run this for directly ativated buckets when cloning */
+				Vec2Subf(co, projPixel->projCo2D, ps->clone_offset);
+				
+				/* no need to initialize the bucket, we're only checking buckets faces and for this
+				 * the faces are alredy initialized in project_paint_delayed_face_init(...) */
+				if (ibuf->rect_float) {
+					if (!project_paint_PickColor(ps, co, ((ProjectPixelCloneFloat *)projPixel)->clonepx, NULL, 1)) {
+						((ProjectPixelCloneFloat *)projPixel)->clonepx[3] = 0; /* zero alpha - ignore */
+					}
+				} else {
+					if (!project_paint_PickColor(ps, co, NULL, ((ProjectPixelClone *)projPixel)->clonepx, 1)) {
+						((ProjectPixelClone *)projPixel)->clonepx[3] = 0; /* zero alpha - ignore */
+					}
 				}
 			}
 		}
@@ -1544,6 +1588,8 @@
 	
 	float *vCo[4]; /* vertex screenspace coords */
 	
+	float w[3];
+	
 	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];
 	int i;
@@ -1632,12 +1678,12 @@
 							IsectPT2Df(uv, uv1co, uv2co, uv3co) ) {
 						
 						if (ps->is_ortho) {
-							screen_px_from_ortho(ps, uv, v1coSS,v2coSS,v3coSS, uv1co,uv2co,uv3co, pixelScreenCo);
+							screen_px_from_ortho(ps, uv, v1coSS,v2coSS,v3coSS, uv1co,uv2co,uv3co, pixelScreenCo, w);
 						} else {
-							screen_px_from_persp(ps, uv, v1coSS,v2coSS,v3coSS, uv1co,uv2co,uv3co, pixelScreenCo);
+							screen_px_from_persp(ps, uv, v1coSS,v2coSS,v3coSS, uv1co,uv2co,uv3co, pixelScreenCo, w);
 						}
 						
-						project_paint_uvpixel_init(ps, thread_index, ibuf, x, y, bucket_index, face_index, image_index, pixelScreenCo);
+						project_paint_uvpixel_init(ps, thread_index, ibuf, x, y, bucket_index, face_index, image_index, pixelScreenCo, i, w);
 						
 						has_x_isect = has_isect = 1;
 					} else if (has_x_isect) {
@@ -1692,6 +1738,7 @@
 			float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */
 			float edge_verts_inset_clip[2][3];
 			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 */
+			int side;
 			
 			float seam_subsection[4][2];
 			float fac1, fac2, ftot;
@@ -1731,6 +1778,9 @@
 					
 					if (ftot > 0.0) { /* avoid div by zero */
 						

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list