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