[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15151] branches/apricot/source/blender: Option to correct for UV distortion when edge sliding when the surrounding faces share the same UV location (else uv interpolation is ignored for that vert).

Campbell Barton ideasman42 at gmail.com
Sat Jun 7 19:48:44 CEST 2008


Revision: 15151
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15151
Author:   campbellbarton
Date:     2008-06-07 19:48:35 +0200 (Sat, 07 Jun 2008)

Log Message:
-----------
Option to correct for UV distortion when edge sliding when the surrounding faces share the same UV location (else uv interpolation is ignored for that vert).
Enable this from the UV Calculation panel, "Transform Correction" button.
This also means deleting edge loops keeps uvs where possible (even when Transform Correction isnt enabled).
Works for multiple UV layers.

Modified Paths:
--------------
    branches/apricot/source/blender/blenkernel/intern/customdata.c
    branches/apricot/source/blender/blenlib/BLI_arithb.h
    branches/apricot/source/blender/blenlib/intern/arithb.c
    branches/apricot/source/blender/makesdna/DNA_scene_types.h
    branches/apricot/source/blender/src/buttons_editing.c
    branches/apricot/source/blender/src/editmesh_tools.c

Modified: branches/apricot/source/blender/blenkernel/intern/customdata.c
===================================================================
--- branches/apricot/source/blender/blenkernel/intern/customdata.c	2008-06-07 17:39:01 UTC (rev 15150)
+++ branches/apricot/source/blender/blenkernel/intern/customdata.c	2008-06-07 17:48:35 UTC (rev 15151)
@@ -1279,7 +1279,7 @@
 	int layer_index;
 	
 	/* get the layer index of the first layer of type */
-	layer_index = CustomData_get_active_layer_index(data, type);
+	layer_index = CustomData_get_layer_index(data, type);
 	if(layer_index < 0) return NULL;
 
 	return (char *)block + data->layers[layer_index+n].offset;

Modified: branches/apricot/source/blender/blenlib/BLI_arithb.h
===================================================================
--- branches/apricot/source/blender/blenlib/BLI_arithb.h	2008-06-07 17:39:01 UTC (rev 15150)
+++ branches/apricot/source/blender/blenlib/BLI_arithb.h	2008-06-07 17:48:35 UTC (rev 15151)
@@ -247,6 +247,7 @@
 void VecAddf(float *v, float *v1, float *v2);
 void VecSubf(float *v, float *v1, float *v2);
 void VecLerpf(float *target, float *a, float *b, float t);
+void VecLerpf2D(float *target, float *a, float *b, float t);
 void VecMidf(float *v, float *v1, float *v2);
 
 void VecOrthoBasisf(float *v, float *v1, float *v2);

Modified: branches/apricot/source/blender/blenlib/intern/arithb.c
===================================================================
--- branches/apricot/source/blender/blenlib/intern/arithb.c	2008-06-07 17:39:01 UTC (rev 15150)
+++ branches/apricot/source/blender/blenlib/intern/arithb.c	2008-06-07 17:48:35 UTC (rev 15151)
@@ -2112,6 +2112,14 @@
 	target[2]= s*a[2] + t*b[2];
 }
 
+void VecLerpf2D(float *target, float *a, float *b, float t)
+{
+	float s = 1.0f-t;
+
+	target[0]= s*a[0] + t*b[0];
+	target[1]= s*a[1] + t*b[1];
+}
+
 void VecMidf(float *v, float *v1, float *v2)
 {
 	v[0]= 0.5f*(v1[0]+ v2[0]);

Modified: branches/apricot/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- branches/apricot/source/blender/makesdna/DNA_scene_types.h	2008-06-07 17:39:01 UTC (rev 15150)
+++ branches/apricot/source/blender/makesdna/DNA_scene_types.h	2008-06-07 17:48:35 UTC (rev 15151)
@@ -790,6 +790,7 @@
 /* toolsettings->uvcalc_flag */
 #define UVCALC_FILLHOLES			1
 #define UVCALC_NO_ASPECT_CORRECT	2	/* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
+#define UVCALC_NO_TRANSFORM_CORRECT	4	/* adjust UV's while transforming to avoid distortion */
 
 /* toolsettings->edge_mode */
 #define EDGE_MODE_SELECT				0

Modified: branches/apricot/source/blender/src/buttons_editing.c
===================================================================
--- branches/apricot/source/blender/src/buttons_editing.c	2008-06-07 17:39:01 UTC (rev 15150)
+++ branches/apricot/source/blender/src/buttons_editing.c	2008-06-07 17:48:35 UTC (rev 15151)
@@ -6272,6 +6272,11 @@
 	row= 180;
 
 	uiDefButBitS(block, TOGN, UVCALC_NO_ASPECT_CORRECT, B_NOP, "Image Aspect",100,row,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0,  "Scale the UV Unwrapping to correct for the current images aspect ratio");
+
+	row-= butHB+butS;	
+		uiDefButBitS(block, TOG, UVCALC_NO_TRANSFORM_CORRECT, B_NOP, "Transform Correction",100,row,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0,  "Correct for UV distortion while transforming, (only works with edge slide now)");
+
+	row= 180;
 	
 	uiBlockBeginAlign(block);
 	uiDefButF(block, NUM,B_UVAUTO_CUBESIZE ,"Cube Size:",315,row,200,butH, &G.scene->toolsettings->uvcalc_cubesize, 0.0001, 100.0, 10, 3, "Defines the cubemap size for cube mapping");

Modified: branches/apricot/source/blender/src/editmesh_tools.c
===================================================================
--- branches/apricot/source/blender/src/editmesh_tools.c	2008-06-07 17:39:01 UTC (rev 15150)
+++ branches/apricot/source/blender/src/editmesh_tools.c	2008-06-07 17:48:35 UTC (rev 15151)
@@ -4646,6 +4646,11 @@
 }
 
 /* *********** END BEVEL *********/
+typedef struct SlideUv {
+	float origuv[2];
+	float *uv_up, *uv_down;
+	float *fuv[4];
+} SlideUv;
 
 typedef struct SlideVert {
 	EditEdge *up,*down;
@@ -4653,9 +4658,19 @@
 } SlideVert;
 
 int EdgeLoopDelete(void) {
+	
+	/* temporal flag setting so we keep UVs when deleting edge loops,
+	 * this is a bit of a hack but it works how you would want in almost all cases */
+	short uvcalc_flag_orig = G.scene->toolsettings->uvcalc_flag; 
+	G.scene->toolsettings->uvcalc_flag |= UVCALC_NO_TRANSFORM_CORRECT;
+	
 	if(!EdgeSlide(1, 1)) {
 		return 0;
 	}
+	
+	/* restore uvcalc flag */
+	G.scene->toolsettings->uvcalc_flag = uvcalc_flag_orig;
+	
 	EM_select_more();
 	removedoublesflag(1,0, 0.001);
 	EM_select_flush();
@@ -4671,11 +4686,19 @@
 	EditVert *ev, *nearest;
 	LinkNode *edgelist = NULL, *vertlist=NULL, *look;
 	GHash *vertgh;
+
 	SlideVert *tempsv;
 	float perc = 0, percp = 0,vertdist, projectMat[4][4], viewMat[4][4];
 	float shiftlabda= 0.0f,len = 0.0f;
 	int i = 0,j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
 	int wasshift = 0;
+	
+	/* UV correction vars */
+	GHash **uvarray;
+	int  uvlay_tot= CustomData_number_of_layers(&G.editMesh->fdata, CD_MTFACE);
+	int uvlay_idx;
+	SlideUv *slideuvs, *suv, *suv_last;	
+	
 	short event, draw=1;
 	short mval[2], mvalo[2];
 	char str[128]; 
@@ -4980,6 +5003,111 @@
 		
 		look = look->next;   
 	}	   
+	
+	
+	if (uvlay_tot && (G.scene->toolsettings->uvcalc_flag & UVCALC_NO_TRANSFORM_CORRECT)) {
+		int maxnum = 0;
+		uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array");
+		suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(SlideUv), "SlideUVs"); /* uvLayers * verts */
+		suv = NULL;
+		
+		for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+			
+			uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); 
+			
+			for(ev=em->verts.first;ev;ev=ev->next) {
+				ev->tmp.l = 0;
+			}
+			look = vertlist;
+			while(look) {
+				float *uv_new;
+				tempsv  = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
+				
+				ev = look->link;
+				suv = NULL;
+				for(efa = em->faces.first;efa;efa=efa->next) {
+					if (ev->tmp.l != -1) { /* test for self, in this case its invalid */
+						int k=-1; /* face corner */
+					
+						/* Is this vert in the faces corner? */
+						if		(efa->v1==ev)				k=0;
+						else if	(efa->v2==ev)				k=1;
+						else if	(efa->v3==ev)				k=2;
+						else if	(efa->v4 && efa->v4==ev)	k=3;
+						
+						if (k != -1) {
+							MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx);
+							uv_new = tf->uv[k];
+						
+							EditVert *ev_up, *ev_down;
+				
+							if (ev->tmp.l) {
+								if (fabs(suv->fuv[0][0]-uv_new[0]) > 0.0001 || fabs(suv->fuv[0][1]-uv_new[1])) {
+									ev->tmp.l = -1; /* Tag as invalid */
+									suv->fuv[0] = suv->fuv[1] = suv->fuv[2] = suv->fuv[3] = NULL;
+									BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL);
+									suv = NULL;
+									break;
+								}
+							} else {
+								ev->tmp.l = 1;
+								suv = suv_last;
+
+								suv->fuv[0] = suv->fuv[1] = suv->fuv[2] = suv->fuv[3] = NULL;
+								suv->uv_up = suv->uv_down = NULL;
+								
+								BLI_ghash_insert(uvarray[uvlay_idx],ev,suv);
+								
+								suv_last++; /* advance to next slide UV */
+								maxnum++;
+							}
+				
+							/* Now get the uvs along the up or down edge if we can */
+							if (suv) {
+								if (!suv->uv_up) {
+									ev_up = editedge_getOtherVert(tempsv->up,ev);
+									if		(efa->v1==ev_up)				suv->uv_up = tf->uv[0];
+									else if	(efa->v2==ev_up)				suv->uv_up = tf->uv[1];
+									else if	(efa->v3==ev_up)				suv->uv_up = tf->uv[2];
+									else if	(efa->v4 && efa->v4==ev_up)		suv->uv_up = tf->uv[3];
+								}
+								if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */
+									ev_down = editedge_getOtherVert(tempsv->down,ev);
+									if		(efa->v1==ev_down)				suv->uv_down = tf->uv[0];
+									else if	(efa->v2==ev_down)				suv->uv_down = tf->uv[1];
+									else if	(efa->v3==ev_down)				suv->uv_down = tf->uv[2];
+									else if	(efa->v4 && efa->v4==ev_down)	suv->uv_down = tf->uv[3];
+								}
+					
+								/* Copy the pointers to the face UV's */
+								for (k=0; k<4; k++) {
+									if (!suv->fuv[k]) {
+										suv->fuv[k] = uv_new;
+										break;
+									}
+								}
+					
+								if (k==3) { /* Dont look any further since 4 faces gace been found */
+								 	break;
+								}
+							}
+					
+						}
+					}
+				}
+		
+				/* UV SUPPORT */
+				if (suv && suv->fuv[0]) {
+					suv->origuv[0] = suv->fuv[0][0];
+					suv->origuv[1] = suv->fuv[0][1];
+				}
+				look = look->next;
+			}
+		} /* end uv layer loop */
+	} /* end uvlay_tot */
+	
+	
+	
 	// we should have enough info now to slide
 
 	len = 0.0f; 
@@ -5017,7 +5145,19 @@
 					
 					tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev);
 					VecLerpf(ev->co, tempsv->origvert.co, tempev->co, fabs(perc));
-									
+					
+					if (G.scene->toolsettings->uvcalc_flag & UVCALC_NO_TRANSFORM_CORRECT) {
+						for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+							suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
+							if (suv && suv->fuv[0] && suv->uv_up && suv->uv_down) {
+								VecLerpf2D(suv->fuv[0], suv->origuv,  (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc));
+								if (suv->fuv[1]) VECCOPY2D(suv->fuv[1], suv->fuv[0]);
+								if (suv->fuv[2]) VECCOPY2D(suv->fuv[2], suv->fuv[0]);
+								if (suv->fuv[3]) VECCOPY2D(suv->fuv[3], suv->fuv[0]);
+							}
+						}
+					}
+					
 					look = look->next;	 
 				}
 			}
@@ -5033,8 +5173,33 @@
 					if(newlen < 0.0) {newlen = 0.0;}
 					if(flip == 0) {
 						VecLerpf(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen));									
+						if (G.scene->toolsettings->uvcalc_flag & UVCALC_NO_TRANSFORM_CORRECT) {
+							/* dont do anything if no UVs */
+							for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+								suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
+								if (suv && suv->fuv[0] && suv->uv_up && suv->uv_down) {
+									VecLerpf2D(suv->fuv[0], suv->uv_down, suv->uv_up, fabs(newlen));
+									if (suv->fuv[1]) VECCOPY2D(suv->fuv[1], suv->fuv[0]);
+									if (suv->fuv[2]) VECCOPY2D(suv->fuv[2], suv->fuv[0]);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list