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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to