[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16371] trunk/blender/source/blender: * corrective UV transformation - only works with UV edge slide right now.

Campbell Barton ideasman42 at gmail.com
Fri Sep 5 02:28:17 CEST 2008


Revision: 16371
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16371
Author:   campbellbarton
Date:     2008-09-05 02:28:17 +0200 (Fri, 05 Sep 2008)

Log Message:
-----------
* corrective UV transformation - only works with UV edge slide right now. but should be extended so transforming dosnt distort UV's
* smooth respects mirror option (will move mirrored vert too)

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_action.h
    trunk/blender/source/blender/blenkernel/intern/action.c
    trunk/blender/source/blender/makesdna/DNA_scene_types.h
    trunk/blender/source/blender/src/buttons_editing.c
    trunk/blender/source/blender/src/editmesh_mods.c
    trunk/blender/source/blender/src/editmesh_tools.c

Modified: trunk/blender/source/blender/blenkernel/BKE_action.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_action.h	2008-09-05 00:12:01 UTC (rev 16370)
+++ trunk/blender/source/blender/blenkernel/BKE_action.h	2008-09-05 00:28:17 UTC (rev 16371)
@@ -159,7 +159,7 @@
 /* map strip time to global time (frame nr)  */
 float get_action_frame_inv(struct Object *ob, float cframe);
 /* builds a list of NlaIpoChannel with ipo values to write in datablock */
-void extract_ipochannels_from_action(ListBase *lb, struct ID *id, struct bAction *act, char *name, float ctime);
+void extract_ipochannels_from_action(ListBase *lb, struct ID *id, struct bAction *act, const char *name, float ctime);
 /* write values returned by extract_ipochannels_from_action, returns the number of value written */
 int execute_ipochannels(ListBase *lb);
 

Modified: trunk/blender/source/blender/blenkernel/intern/action.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/action.c	2008-09-05 00:12:01 UTC (rev 16370)
+++ trunk/blender/source/blender/blenkernel/intern/action.c	2008-09-05 00:28:17 UTC (rev 16371)
@@ -862,7 +862,7 @@
 	int type;
 } NlaIpoChannel;
 
-void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, char *name, float ctime)
+void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, const char *name, float ctime)
 {
 	bActionChannel *achan= get_action_channel(act, name);
 	IpoCurve *icu;

Modified: trunk/blender/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_scene_types.h	2008-09-05 00:12:01 UTC (rev 16370)
+++ trunk/blender/source/blender/makesdna/DNA_scene_types.h	2008-09-05 00:28:17 UTC (rev 16371)
@@ -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_TRANSFORM_CORRECT	4	/* adjust UV's while transforming to avoid distortion */
 
 /* toolsettings->edge_mode */
 #define EDGE_MODE_SELECT				0

Modified: trunk/blender/source/blender/src/buttons_editing.c
===================================================================
--- trunk/blender/source/blender/src/buttons_editing.c	2008-09-05 00:12:01 UTC (rev 16370)
+++ trunk/blender/source/blender/src/buttons_editing.c	2008-09-05 00:28:17 UTC (rev 16371)
@@ -6277,6 +6277,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_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: trunk/blender/source/blender/src/editmesh_mods.c
===================================================================
--- trunk/blender/source/blender/src/editmesh_mods.c	2008-09-05 00:12:01 UTC (rev 16370)
+++ trunk/blender/source/blender/src/editmesh_mods.c	2008-09-05 00:28:17 UTC (rev 16371)
@@ -4202,7 +4202,7 @@
 void vertexsmooth(void)
 {
 	EditMesh *em = G.editMesh;
-	EditVert *eve;
+	EditVert *eve, *eve_mir = NULL;
 	EditEdge *eed;
 	float *adror, *adr, fac;
 	float fvec[3];
@@ -4285,13 +4285,19 @@
 	while(eve) {
 		if(eve->f & SELECT) {
 			if(eve->f1) {
+				
+				if (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR) {
+					eve_mir= editmesh_get_x_mirror_vert(G.obedit, eve->co);
+				}
+				
 				adr = eve->tmp.p;
 				fac= 0.5/(float)eve->f1;
 				
 				eve->co[0]= 0.5*eve->co[0]+fac*adr[0];
 				eve->co[1]= 0.5*eve->co[1]+fac*adr[1];
 				eve->co[2]= 0.5*eve->co[2]+fac*adr[2];
-
+				
+				
 				/* clip if needed by mirror modifier */
 				if (eve->f2) {
 					if (eve->f2 & 1) {
@@ -4304,6 +4310,13 @@
 						eve->co[2]= 0.0f;
 					}
 				}
+				
+				if (eve_mir) {
+					eve_mir->co[0]=-eve->co[0];
+					eve_mir->co[1]= eve->co[1];
+					eve_mir->co[2]= eve->co[2];
+				}
+				
 			}
 			eve->tmp.p= NULL;
 		}

Modified: trunk/blender/source/blender/src/editmesh_tools.c
===================================================================
--- trunk/blender/source/blender/src/editmesh_tools.c	2008-09-05 00:12:01 UTC (rev 16370)
+++ trunk/blender/source/blender/src/editmesh_tools.c	2008-09-05 00:28:17 UTC (rev 16371)
@@ -4648,6 +4648,12 @@
 }
 
 /* *********** END BEVEL *********/
+typedef struct SlideUv {
+	float origuv[2];
+	float *uv_up, *uv_down;
+	//float *fuv[4];
+	LinkNode *fuv_list;
+} SlideUv;
 
 typedef struct SlideVert {
 	EditEdge *up,*down;
@@ -4655,9 +4661,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_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();
@@ -4674,11 +4690,21 @@
 	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;	
+	float uv_tmp[2];
+	LinkNode *fuv_link;
+	
 	short event, draw=1;
 	short mval[2], mvalo[2];
 	char str[128]; 
@@ -4985,6 +5011,99 @@
 		
 		look = look->next;   
 	}	   
+	
+	
+	if (uvlay_tot && (G.scene->toolsettings->uvcalc_flag & UVCALC_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);
+							EditVert *ev_up, *ev_down;
+							
+							uv_new = tf->uv[k];
+				
+							if (ev->tmp.l) {
+								if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001 || fabs(suv->origuv[1]-uv_new[1])) {
+									ev->tmp.l = -1; /* Tag as invalid */
+									BLI_linklist_free(suv->fuv_list,NULL);
+									suv->fuv_list = NULL;
+									BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL);
+									suv = NULL;
+									break;
+								}
+							} else {
+								ev->tmp.l = 1;
+								suv = suv_last;
+
+								suv->fuv_list = NULL;
+								suv->uv_up = suv->uv_down = NULL;
+								suv->origuv[0] = uv_new[0];
+								suv->origuv[1] = uv_new[1];
+								
+								BLI_linklist_prepend(&suv->fuv_list, uv_new);
+								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 */
+								BLI_linklist_prepend(&suv->fuv_list, uv_new);
+							}
+						}
+					}
+				}
+				look = look->next;
+			}
+		} /* end uv layer loop */
+	} /* end uvlay_tot */
+	
+	
+	
 	// we should have enough info now to slide
 
 	len = 0.0f; 
@@ -5089,7 +5208,21 @@
 					
 					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_TRANSFORM_CORRECT) {
+						for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+							suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
+							if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
+								Vec2Lerpf(uv_tmp, suv->origuv,  (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc));
+								fuv_link = suv->fuv_list;
+								while (fuv_link) {
+									VECCOPY2D(((float *)fuv_link->link), uv_tmp);
+									fuv_link = fuv_link->next;
+								}
+							}
+						}
+					}
+					
 					look = look->next;	 
 				}
 			}
@@ -5105,8 +5238,37 @@
 					if(newlen < 0.0) {newlen = 0.0;}
 					if(flip == 0) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list