Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2005-04-23 05:36:08 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2005-04-23 05:36:08 +0400
commitc333ba8dfaa8e92483d29f3cf77988ce0e1beb3a (patch)
treeb2a7ea6a784d0376f2c9fc4e77b5fbddd7f9e373 /source/blender/src/editsima.c
parent375cf60462cadb8625b13f9b256f69df15831336 (diff)
Merging over some uv editor tweaks from tuhopuu:
- Moved Weld/Align out of transform code, now it's a menu. - Removed confirmation popups for LSCM unwrapping in the uv editor, didn't make sense anymore now we have undo. - Extended select linked, to work more like it does in edit mode: - L: select linked uvs/faces under the mouse - Shift+L: select/deselect linked uvs/faces under the mouse (like shift+click for selecting single uvs/faces) - Ctrl+L: how L worked before - More accurate uv selection: when selecting one uv from a group of uvs that are in the same position, it now selects the uv belonging to the face the mouse is over, instead of a random uv. - 'View Selected' (numpad .-key) for both faceselect mode and the uv editor.
Diffstat (limited to 'source/blender/src/editsima.c')
-rw-r--r--source/blender/src/editsima.c759
1 files changed, 425 insertions, 334 deletions
diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c
index 4de8824cb6c..8a869afc759 100644
--- a/source/blender/src/editsima.c
+++ b/source/blender/src/editsima.c
@@ -85,10 +85,9 @@
#include "mydevice.h"
struct uvvertsort {
- unsigned int v;
+ unsigned int v, f;
unsigned char tf_sel;
char flag;
- TFace *tface;
};
/* local prototypes */
@@ -125,18 +124,17 @@ int is_uv_tface_editing_allowed(void)
return is_uv_tface_editing_allowed_silent();
}
-static void setLinkedLimit(float *limit)
+void get_connected_limit_tface_uv(float *limit)
{
if(G.sima->image && G.sima->image->ibuf && G.sima->image->ibuf->x > 0 &&
G.sima->image->ibuf->y > 0) {
- limit[0]= 0.5/(float)G.sima->image->ibuf->x;
- limit[1]= 0.5/(float)G.sima->image->ibuf->y;
+ limit[0]= 0.05/(float)G.sima->image->ibuf->x;
+ limit[1]= 0.05/(float)G.sima->image->ibuf->y;
}
else
- limit[0]= limit[1]= 0.5/256.0;
+ limit[0]= limit[1]= 0.05/256.0;
}
-
void clever_numbuts_sima(void)
{
float ocent[2], cent[2]= {0.0, 0.0};
@@ -268,7 +266,9 @@ static void be_square_tface_uv(Mesh *me)
int a;
/* if 1 vertex selected: doit (with the selected vertex) */
- for(a=me->totface, mface= me->mface, tface= me->tface; a>0; a--, tface++, mface++) {
+ mface= (MFace*)me->mface;
+ tface= (TFace*)me->tface;
+ for(a=me->totface; a>0; a--, tface++, mface++) {
if(mface->v4) {
if(tface->flag & TF_SELECT) {
if(tface->flag & TF_SEL1) {
@@ -353,7 +353,7 @@ void transform_tface_uv(int mode)
float size[2], sizefac;
float dx, dy, dvec2[2], dvec[2], div, cent[2];
float x, y, min[2], max[2], vec[2], xtra[2], ivec[2];
- int xim, yim, tot=0, a, b, firsttime=1, afbreek=0, align= 0;
+ int xim, yim, tot=0, a, b, firsttime=1, afbreek=0;
int propmode= 0, proptot= 0, midtog= 0, proj= 0, prop_recalc= 1;
unsigned short event = 0;
short mval[2], val, xo, yo, xn, yn, xc, yc;
@@ -467,7 +467,7 @@ void transform_tface_uv(int mode)
while(afbreek==0) {
getmouseco_areawin(mval);
- if(((mval[0]!=xo || mval[1]!=yo) && !(mode=='w')) || firsttime) {
+ if((mval[0]!=xo || mval[1]!=yo) || firsttime) {
if(propmode && prop_recalc && transmain) {
a= tot;
tv= transmain;
@@ -660,42 +660,11 @@ void transform_tface_uv(int mode)
sprintf(str, "sizeX: %.3f sizeY: %.3f", size[0], size[1]);
headerprint(str);
}
- else if(mode=='w') { /* weld / align */
- tv= transmain;
- for(a=0; a<tot; a++, tv++) {
- x= tv->oldloc[0];
- y= tv->oldloc[1];
- if(align==0) {
- x= cent[0];
- y= cent[1];
- }
- else if(align==1) y= cent[1];
- else if(align==2) x= cent[0];
-
- tv->loc[0]= x;
- tv->loc[1]= y;
-
- if(G.sima->flag & SI_CLIP_UV) {
- if(tv->loc[0]<0.0) tv->loc[0]= 0.0;
- else if(tv->loc[0]>1.0) tv->loc[0]= 1.0;
- if(tv->loc[1]<0.0) tv->loc[1]= 0.0;
- else if(tv->loc[1]>1.0) tv->loc[1]= 1.0;
- }
- }
-
- if(align==0)
- sprintf(str, "Weld (X: Align along X, Y: Align along Y)");
- else if(align==1)
- sprintf(str, "X Axis Align (W: Weld, Y: Align along Y)");
- else if(align==2)
- sprintf(str, "Y Axis Align (W: Weld, X: Align along X)");
- headerprint(str);
- }
-
+
xo= mval[0];
yo= mval[1];
- if(G.sima->lock || mode=='w') force_draw_plus(SPACE_VIEW3D, 0);
+ if(G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0);
else force_draw(0);
firsttime= 0;
@@ -741,31 +710,24 @@ void transform_tface_uv(int mode)
case WKEY:
case XKEY:
case YKEY:
- if(mode=='w') {
- if(event==WKEY) align= 0;
- else if(event==XKEY) align= 1;
- else align= 2;
+ if(midtog) {
+ if(event==XKEY) {
+ if(proj==1) midtog= ~midtog;
+ else if(proj==0) proj= 1;
+ }
+ else if(event==YKEY) {
+ if(proj==0) midtog= ~midtog;
+ else if(proj==1) proj= 0;
+ }
}
else {
- if(midtog) {
- if(event==XKEY) {
- if(proj==1) midtog= ~midtog;
- else if(proj==0) proj= 1;
- }
- else if(event==YKEY) {
- if(proj==0) midtog= ~midtog;
- else if(proj==1) proj= 0;
- }
+ if(event==XKEY) {
+ midtog= ~midtog;
+ proj= 1;
}
- else {
- if(event==XKEY) {
- midtog= ~midtog;
- proj= 1;
- }
- else if(event==YKEY) {
- midtog= ~midtog;
- proj= 0;
- }
+ else if(event==YKEY) {
+ midtog= ~midtog;
+ proj= 0;
}
}
firsttime= 1;
@@ -804,7 +766,7 @@ void transform_tface_uv(int mode)
scrarea_queue_winredraw(curarea);
}
-static void mirror_tface_uv(char mirroraxis)
+void mirror_tface_uv(char mirroraxis)
{
MFace *mface;
TFace *tface;
@@ -815,24 +777,11 @@ static void mirror_tface_uv(char mirroraxis)
if( is_uv_tface_editing_allowed()==0 ) return;
me= get_mesh(OBACT);
- min[0]= min[1]= 10000.0;
- max[0]= max[1]= -10000.0;
-
- tface= me->tface;
- mface= me->mface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(tface->flag & TF_SELECT) {
- if(tface->flag & TF_SEL1) { DO_MINMAX2(tface->uv[0], min, max); }
- if(tface->flag & TF_SEL2) { DO_MINMAX2(tface->uv[1], min, max); }
- if(tface->flag & TF_SEL3) { DO_MINMAX2(tface->uv[2], min, max); }
- if(mface->v4 && (tface->flag & TF_SEL4)) {
- DO_MINMAX2(tface->uv[3], min, max);
- }
- }
- }
+ if (!minmax_tface_uv(min, max))
+ return;
- cent[0]= (min[0]+max[0])/2.0;
- cent[1]= (min[1]+max[1])/2.0;
+ cent[0]= min[0]+max[0];
+ cent[1]= min[1]+max[1];
if(mirroraxis=='x') axis= 0;
else axis= 1;
@@ -842,13 +791,13 @@ static void mirror_tface_uv(char mirroraxis)
for(a=me->totface; a>0; a--, tface++, mface++) {
if(tface->flag & TF_SELECT) {
if(tface->flag & TF_SEL1)
- tface->uv[0][axis]= 2*cent[axis] - tface->uv[0][axis];
+ tface->uv[0][axis]= cent[axis] - tface->uv[0][axis];
if(tface->flag & TF_SEL2)
- tface->uv[1][axis]= 2*cent[axis] - tface->uv[1][axis];
+ tface->uv[1][axis]= cent[axis] - tface->uv[1][axis];
if(tface->flag & TF_SEL3)
- tface->uv[2][axis]= 2*cent[axis] - tface->uv[2][axis];
+ tface->uv[2][axis]= cent[axis] - tface->uv[2][axis];
if(mface->v4 && (tface->flag & TF_SEL4))
- tface->uv[3][axis]= 2*cent[axis] - tface->uv[3][axis];
+ tface->uv[3][axis]= cent[axis] - tface->uv[3][axis];
}
}
@@ -872,7 +821,78 @@ void mirrormenu_tface_uv(void)
BIF_undo_push("Mirror UV");
}
+void weld_align_tface_uv(char tool)
+{
+ MFace *mface;
+ TFace *tface;
+ Mesh *me;
+ float min[2], max[2], cent[2];
+ int a;
+
+ if( is_uv_tface_editing_allowed()==0 ) return;
+ me= get_mesh(OBACT);
+
+ if (!minmax_tface_uv(min, max))
+ return;
+
+ cent[0]= (min[0]+max[0])/2.0;
+ cent[1]= (min[1]+max[1])/2.0;
+
+ if(tool == 'x' || tool == 'w') {
+ tface= me->tface;
+ mface= me->mface;
+ for(a=me->totface; a>0; a--, tface++, mface++) {
+ if(tface->flag & TF_SELECT) {
+ if(tface->flag & TF_SEL1)
+ tface->uv[0][0]= cent[0];
+ if(tface->flag & TF_SEL2)
+ tface->uv[1][0]= cent[0];
+ if(tface->flag & TF_SEL3)
+ tface->uv[2][0]= cent[0];
+ if(mface->v4 && (tface->flag & TF_SEL4))
+ tface->uv[3][0]= cent[0];
+ }
+ }
+ }
+
+ if(tool == 'y' || tool == 'w') {
+ tface= me->tface;
+ mface= me->mface;
+ for(a=me->totface; a>0; a--, tface++, mface++) {
+ if(tface->flag & TF_SELECT) {
+ if(tface->flag & TF_SEL1)
+ tface->uv[0][1]= cent[1];
+ if(tface->flag & TF_SEL2)
+ tface->uv[1][1]= cent[1];
+ if(tface->flag & TF_SEL3)
+ tface->uv[2][1]= cent[1];
+ if(mface->v4 && (tface->flag & TF_SEL4))
+ tface->uv[3][1]= cent[1];
+ }
+ }
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWIMAGE, 0);
+}
+
+void weld_align_menu_tface_uv(void)
+{
+ short mode= 0;
+
+ if( is_uv_tface_editing_allowed()==0 ) return;
+
+ mode= pupmenu("Weld/Align%t|Weld%x1|Align X%x2|Align Y%x3|");
+
+ if(mode==-1) return;
+
+ if(mode==1) weld_align_tface_uv('w');
+ else if(mode==2) weld_align_tface_uv('x');
+ else if(mode==3) weld_align_tface_uv('y');
+ if(mode==1) BIF_undo_push("Weld UV");
+ else if(mode==2 || mode==3) BIF_undo_push("Align UV");
+}
void select_swap_tface_uv(void)
{
Mesh *me;
@@ -926,191 +946,232 @@ static int msel_hit(float *limit, unsigned int *hitarray, unsigned int vertexid,
return 0;
}
+void find_nearest_tface(TFace **nearesttf, MFace **nearestmf)
+{
+ Mesh *me;
+ TFace *tf;
+ MFace *mf;
+ int a, i, nverts, mindist, dist, fcenter[2];
+ short mval[2], uval[2];
+
+ getmouseco_areawin(mval);
+
+ mindist= 0x7FFFFFF;
+ *nearesttf= NULL;
+ *nearestmf= NULL;
+
+ me= get_mesh(OBACT);
+ mf= (MFace*)me->mface;
+ tf= (TFace*)me->tface;
+
+ for(a=me->totface; a>0; a--, tf++, mf++) {
+ if(tf->flag & TF_SELECT && mf->v3) {
+
+ fcenter[0]= fcenter[1]= 0;
+ nverts= mf->v4? 4: 3;
+ for(i=0; i<nverts; i++) {
+ uvco_to_areaco_noclip(tf->uv[i], uval);
+ fcenter[0] += uval[0];
+ fcenter[1] += uval[1];
+ }
+
+ fcenter[0] /= nverts;
+ fcenter[1] /= nverts;
+
+ dist= abs(mval[0]- fcenter[0])+ abs(mval[1]- fcenter[1]);
+ if (dist < mindist) {
+ *nearesttf= tf;
+ *nearestmf= mf;
+ mindist= dist;
+ }
+ }
+ }
+}
+
+int nearest_uv_between(TFace *tf, int nverts, int id, short *mval, short *uval)
+{
+ float m[3], v1[3], v2[3], c1, c2;
+ int id1, id2;
+
+ id1= (id+nverts-1)%nverts;
+ id2= (id+nverts+1)%nverts;
+
+ m[0] = (float)(mval[0]-uval[0]);
+ m[1] = (float)(mval[1]-uval[1]);
+ Vec2Subf(v1, tf->uv[id1], tf->uv[id]);
+ Vec2Subf(v2, tf->uv[id2], tf->uv[id]);
+
+ /* m and v2 on same side of v-v1? */
+ c1= v1[0]*m[1] - v1[1]*m[0];
+ c2= v1[0]*v2[1] - v1[1]*v2[0];
+
+ if (c1*c2 < 0.0f)
+ return 0;
+
+ /* m and v1 on same side of v-v2? */
+ c1= v2[0]*m[1] - v2[1]*m[0];
+ c2= v2[0]*v1[1] - v2[1]*v1[0];
+
+ return (c1*c2 >= 0.0f);
+}
+
+void find_nearest_uv(TFace **nearesttf, unsigned int *nearestv, int *nearestuv)
+{
+ Mesh *me;
+ TFace *tf;
+ MFace *mf;
+ int a, i, nverts, mindist, dist;
+ short mval[2], uval[2];
+
+ getmouseco_areawin(mval);
+
+ mindist= 0x7FFFFFF;
+ *nearesttf= NULL;
+
+ me= get_mesh(OBACT);
+ mf= (MFace*)me->mface;
+ tf= (TFace*)me->tface;
+
+ for(a=me->totface; a>0; a--, tf++, mf++) {
+ if(tf->flag & TF_SELECT && mf->v3) {
+
+ nverts= mf->v4? 4: 3;
+ for(i=0; i<nverts; i++) {
+ uvco_to_areaco_noclip(tf->uv[i], uval);
+ dist= abs(mval[0]-uval[0]) + abs(mval[1]-uval[1]);
+
+ if(tf->flag & TF_SEL_MASK(i))
+ dist += 5;
+
+ if(dist<=mindist) {
+ if(dist==mindist)
+ if (!nearest_uv_between(tf, nverts, i, mval, uval))
+ continue;
+
+ mindist= dist;
+
+ *nearesttf= tf;
+ *nearestuv= i;
+
+ if (i==0) *nearestv= mf->v1;
+ else if (i==1) *nearestv= mf->v2;
+ else if (i==2) *nearestv= mf->v3;
+ else *nearestv= mf->v4;
+ }
+ }
+ }
+ }
+}
+
void mouse_select_sima(void)
{
Mesh *me;
- TFace *tface, *closesttface= NULL;
- MFace *mface, *closestmface= NULL;
- int a, redraw= 0, uvcent[2], selectsticky= 0, sticky, actface;
- int temp, dist= 0x7FFFFFF, fdist= 0x7FFFFFF, fdistmin= 0x7FFFFFF;
- short mval[2], uval[2], val= 0;
- char *flagpoin= 0;
- unsigned int hitvert[4]= {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+ TFace *tf, *nearesttf;
+ MFace *mf, *nearestmf;
+ int a, selectsticky, sticky, actface, nearestuv, i;
+ unsigned int hitv[4], nearestv;
float *hituv[4], limit[2];
if( is_uv_tface_editing_allowed()==0 ) return;
me= get_mesh(OBACT);
- getmouseco_areawin(mval);
- setLinkedLimit(limit);
+ get_connected_limit_tface_uv(limit);
actface= (G.qual & LR_ALTKEY || G.sima->flag & SI_SELACTFACE);
sticky= (G.qual & LR_CTRLKEY || G.sima->flag & SI_STICKYUVS ||
G.sima->flag & SI_LOCALSTICKY);
- /* go for one run through all faces. collect all information needed */
- mface= me->mface;
- tface= me->tface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(tface->flag & TF_SELECT && mface->v3) {
-
- uvco_to_areaco_noclip(tface->uv[0], uval);
- uvcent[0]= uval[0];
- uvcent[1]= uval[1];
- temp= abs(mval[0]-uval[0]) + abs(mval[1]-uval[1]);
- if(tface->flag & TF_SEL1) temp += 5;
- if(temp<dist) {
- flagpoin= &tface->flag;
- dist= temp;
- val= TF_SEL1;
- hitvert[1]= hitvert[2]= hitvert[3]= 0xFFFFFFFF;
- hitvert[0]= mface->v1;
- hituv[0]= tface->uv[0];
- }
-
- uvco_to_areaco_noclip(tface->uv[1], uval);
- temp= abs(mval[0]-uval[0]) + abs(mval[1]-uval[1]);
- uvcent[0] += uval[0];
- uvcent[1] += uval[1];
- if(tface->flag & TF_SEL2) temp += 5;
- if(temp<dist) {
- flagpoin= &tface->flag;
- dist= temp;
- val= TF_SEL2;
- hitvert[0]= hitvert[2]= hitvert[3]= 0xFFFFFFFF;
- hitvert[1]= mface->v2;
- hituv[1]= tface->uv[1];
- }
-
- uvco_to_areaco_noclip(tface->uv[2], uval);
- temp= abs(mval[0]-uval[0]) + abs(mval[1]-uval[1]);
- uvcent[0] += uval[0];
- uvcent[1] += uval[1];
- if(tface->flag & TF_SEL3) temp += 5;
- if(temp<dist) {
- flagpoin= &tface->flag;
- dist= temp;
- val= TF_SEL3;
- hitvert[0]= hitvert[1]= hitvert[3]= 0xFFFFFFFF;
- hitvert[2]= mface->v3;
- hituv[2]= tface->uv[2];
- }
-
- if(mface->v4) {
- uvco_to_areaco_noclip(tface->uv[3], uval);
- uvcent[0] += uval[0];
- uvcent[1] += uval[1];
- temp= abs(mval[0]-uval[0]) + abs(mval[1]-uval[1]);
- if(tface->flag & TF_SEL4) temp += 5;
- if(temp<dist) {
- flagpoin= &tface->flag;
- dist= temp;
- val= TF_SEL4;
- hitvert[0]= hitvert[1]= hitvert[2]= 0xFFFFFFFF;
- hitvert[3] = mface->v4;
- hituv[3]= tface->uv[3];
- }
- uvcent[0] /= 4;
- uvcent[1] /= 4;
- }
- else {
- uvcent[0] /= 3;
- uvcent[1] /= 3;
- }
-
- /* find face closest to mouse */
- if(actface) {
- fdist= abs(mval[0]- uvcent[0])+ abs(mval[1]- uvcent[1]);
- if (fdist < fdistmin){
- closesttface= tface;
- closestmface= mface;
- fdistmin= fdist;
- }
- }
- }
+ if(actface) {
+ find_nearest_tface(&nearesttf, &nearestmf);
+ if(nearesttf==NULL)
+ return;
+
+ nearesttf->flag |= TF_ACTIVE;
+
+ for (i=0; i<4; i++)
+ hituv[i]= nearesttf->uv[i];
+
+ hitv[0]= nearestmf->v1;
+ hitv[1]= nearestmf->v2;
+ hitv[2]= nearestmf->v3;
+ hitv[3]= nearestmf->v4? nearestmf->v4: 0xFFFFFFFF;
}
-
- if(!flagpoin)
- return;
+ else {
+ find_nearest_uv(&nearesttf, &nearestv, &nearestuv);
+ if(nearesttf==NULL)
+ return;
- if(actface && closesttface) {
- closesttface->flag |= TF_ACTIVE;
- hitvert[0]= closestmface->v1;
- hituv[0]= closesttface->uv[0];
- hitvert[1]= closestmface->v2;
- hituv[1]= closesttface->uv[1];
- hitvert[2]= closestmface->v3;
- hituv[2]= closesttface->uv[2];
- if(closestmface->v4) {
- hitvert[3]= closestmface->v4;
- hituv[3]= closesttface->uv[3];
+ if(sticky) {
+ for(i=0; i<4; i++)
+ hitv[i]= 0xFFFFFFFF;
+ hitv[nearestuv]= nearestv;
+ hituv[nearestuv]= nearesttf->uv[nearestuv];
}
}
if(G.qual & LR_SHIFTKEY) {
/* (de)select face */
if(actface) {
- if(!(~closesttface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
- && (!closestmface->v4 || closesttface->flag & TF_SEL4)) {
- closesttface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ if(!(~nearesttf->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
+ && (!nearestmf->v4 || nearesttf->flag & TF_SEL4)) {
+ nearesttf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
selectsticky= 0;
}
else {
- closesttface->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4;
+ nearesttf->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4;
selectsticky= 1;
}
}
/* (de)select uv node */
else {
- if(*flagpoin & val) {
- *flagpoin &= ~val;
+ if(nearesttf->flag & TF_SEL_MASK(nearestuv)) {
+ nearesttf->flag &= ~TF_SEL_MASK(nearestuv);
selectsticky= 0;
}
else {
- *flagpoin |= val;
+ nearesttf->flag |= TF_SEL_MASK(nearestuv);
selectsticky= 1;
}
}
/* (de)select sticky uv nodes */
if(sticky || actface) {
- mface= me->mface;
- tface= me->tface;
+ mf= (MFace*)me->mface;
+ tf= (TFace*)me->tface;
/* deselect */
if(selectsticky==0) {
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(!(tface->flag & TF_SELECT && mface->v3)) continue;
- if(closesttface && tface!=closesttface)
- tface->flag &=~ TF_ACTIVE;
+ for(a=me->totface; a>0; a--, tf++, mf++) {
+ if(!(tf->flag & TF_SELECT && mf->v3)) continue;
+ if(nearesttf && tf!=nearesttf) tf->flag &=~ TF_ACTIVE;
if (!sticky) continue;
- if(msel_hit(limit,hitvert,mface->v1,hituv,tface->uv[0]))
- tface->flag &= ~TF_SEL1;
- if(msel_hit(limit,hitvert,mface->v2,hituv,tface->uv[1]))
- tface->flag &= ~TF_SEL2;
- if(msel_hit(limit,hitvert,mface->v3,hituv,tface->uv[2]))
- tface->flag &= ~TF_SEL3;
- if (mface->v4)
- if(msel_hit(limit,hitvert,mface->v4,hituv,tface->uv[3]))
- tface->flag &= ~TF_SEL4;
+ if(msel_hit(limit, hitv, mf->v1, hituv, tf->uv[0]))
+ tf->flag &= ~TF_SEL1;
+ if(msel_hit(limit, hitv, mf->v2, hituv, tf->uv[1]))
+ tf->flag &= ~TF_SEL2;
+ if(msel_hit(limit, hitv, mf->v3, hituv, tf->uv[2]))
+ tf->flag &= ~TF_SEL3;
+ if (mf->v4)
+ if(msel_hit(limit, hitv, mf->v4, hituv, tf->uv[3]))
+ tf->flag &= ~TF_SEL4;
}
}
/* select */
else {
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(!(tface->flag & TF_SELECT && mface->v3)) continue;
- if(closesttface && tface!=closesttface)
- tface->flag &=~ TF_ACTIVE;
+ for(a=me->totface; a>0; a--, tf++, mf++) {
+ if(!(tf->flag & TF_SELECT && mf->v3)) continue;
+ if(nearesttf && tf!=nearesttf)
+ tf->flag &=~ TF_ACTIVE;
if (!sticky) continue;
- if(msel_hit(limit,hitvert,mface->v1,hituv,tface->uv[0]))
- tface->flag |= TF_SEL1;
- if(msel_hit(limit,hitvert,mface->v2,hituv,tface->uv[1]))
- tface->flag |= TF_SEL2;
- if(msel_hit(limit,hitvert,mface->v3,hituv,tface->uv[2]))
- tface->flag |= TF_SEL3;
- if (mface->v4)
- if(msel_hit(limit,hitvert,mface->v4,hituv,tface->uv[3]))
- tface->flag |= TF_SEL4;
+ if(msel_hit(limit, hitv, mf->v1, hituv, tf->uv[0]))
+ tf->flag |= TF_SEL1;
+ if(msel_hit(limit, hitv, mf->v2, hituv, tf->uv[1]))
+ tf->flag |= TF_SEL2;
+ if(msel_hit(limit, hitv, mf->v3, hituv, tf->uv[2]))
+ tf->flag |= TF_SEL3;
+ if (mf->v4)
+ if(msel_hit(limit, hitv, mf->v4, hituv, tf->uv[3]))
+ tf->flag |= TF_SEL4;
}
}
}
@@ -1118,40 +1179,39 @@ void mouse_select_sima(void)
else {
/* select face and deselect other faces */
if(actface) {
- mface= me->mface;
- tface= me->tface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
- if(closesttface && tface!=closesttface)
- tface->flag &=~ TF_ACTIVE;
+ mf= (MFace*)me->mface;
+ tf= (TFace*)me->tface;
+ for(a=me->totface; a>0; a--, tf++, mf++) {
+ tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ if(nearesttf && tf!=nearesttf)
+ tf->flag &= ~TF_ACTIVE;
}
- if(closesttface)
- closesttface->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
- redraw= 1;
+ if(nearesttf)
+ nearesttf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
}
/* deselect uvs, and select sticky uvs */
- mface= me->mface;
- tface= me->tface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(tface->flag & TF_SELECT && mface->v3) {
- if(!actface) tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ mf= (MFace*)me->mface;
+ tf= (TFace*)me->tface;
+ for(a=me->totface; a>0; a--, tf++, mf++) {
+ if(tf->flag & TF_SELECT && mf->v3) {
+ if(!actface) tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
if(!sticky) continue;
- if(msel_hit(limit,hitvert,mface->v1,hituv,tface->uv[0]))
- tface->flag |=TF_SEL1;
- if(msel_hit(limit,hitvert,mface->v2,hituv,tface->uv[1]))
- tface->flag |=TF_SEL2;
- if(msel_hit(limit,hitvert,mface->v3,hituv,tface->uv[2]))
- tface->flag |=TF_SEL3;
- if(mface->v4)
- if(msel_hit(limit,hitvert,mface->v4,hituv,tface->uv[3]))
- tface->flag |=TF_SEL4;
+ if(msel_hit(limit, hitv, mf->v1, hituv, tf->uv[0]))
+ tf->flag |= TF_SEL1;
+ if(msel_hit(limit, hitv, mf->v2, hituv, tf->uv[1]))
+ tf->flag |= TF_SEL2;
+ if(msel_hit(limit, hitv, mf->v3, hituv, tf->uv[2]))
+ tf->flag |= TF_SEL3;
+ if(mf->v4)
+ if(msel_hit(limit, hitv, mf->v4, hituv, tf->uv[3]))
+ tf->flag |= TF_SEL4;
}
}
if(!actface)
- *flagpoin |= val;
+ nearesttf->flag |= TF_SEL_MASK(nearestuv);
}
force_draw(1);
@@ -1411,8 +1471,8 @@ void reveal_tface_uv(void)
void stitch_uv_tface(int mode)
{
- MFace *mface;
- TFace *tface;
+ MFace *mf;
+ TFace *tf, *tface;
Mesh *me;
unsigned int a, b, c, vtot, vtot2, tot;
float newuv[2], limit[2], *uv, *uv1;
@@ -1436,45 +1496,48 @@ void stitch_uv_tface(int mode)
limit[0]= limit[1]= limit[0]/256.0;
me= get_mesh(OBACT);
+ tface= (TFace*)me->tface;
tot= 0;
- mface= me->mface;
- for(a=me->totface, tface=me->tface; a>0; a--, tface++, mface++) {
- if((tface->flag & TF_SELECT) && mface->v3) {
- if(tface->flag & TF_SEL1) tot++;
- if(tface->flag & TF_SEL2) tot++;
- if(tface->flag & TF_SEL3) tot++;
- if(mface->v4 && tface->flag & TF_SEL4) tot++;
+ mf= (MFace*)me->mface;
+ tf= (TFace*)me->tface;
+ for(a=me->totface; a>0; a--, tf++, mf++) {
+ if((tf->flag & TF_SELECT) && mf->v3) {
+ if(tf->flag & TF_SEL1) tot++;
+ if(tf->flag & TF_SEL2) tot++;
+ if(tf->flag & TF_SEL3) tot++;
+ if(mf->v4 && tf->flag & TF_SEL4) tot++;
}
}
if(tot==0) return;
sb= sortblock= MEM_callocN(sizeof(struct uvvertsort)*tot,"sortstitchuv");
- mface= me->mface;
- for(a=me->totface, tface=me->tface; a>0; a--, tface++, mface++) {
- if((tface->flag & TF_SELECT) && mface->v3) {
- if(tface->flag & TF_SEL1) {
- sb->v= mface->v1;
- sb->tface= tface;
+ mf= (MFace*)me->mface;
+ tf= (TFace*)me->tface;
+ for(a=0; a<me->totface; a++, tf++, mf++) {
+ if((tf->flag & TF_SELECT) && mf->v3) {
+ if(tf->flag & TF_SEL1) {
+ sb->v= mf->v1;
+ sb->f= a;
sb->tf_sel= 0;
sb++;
}
- if(tface->flag & TF_SEL2) {
- sb->v= mface->v2;
- sb->tface= tface;
+ if(tf->flag & TF_SEL2) {
+ sb->v= mf->v2;
+ sb->f= a;
sb->tf_sel= 1;
sb++;
}
- if(tface->flag & TF_SEL3) {
- sb->v= mface->v3;
- sb->tface= tface;
+ if(tf->flag & TF_SEL3) {
+ sb->v= mf->v3;
+ sb->f= a;
sb->tf_sel= 2;
sb++;
}
- if(mface->v4 && tface->flag & TF_SEL4) {
- sb->v= mface->v4;
- sb->tface = tface;
+ if(mf->v4 && tf->flag & TF_SEL4) {
+ sb->v= mf->v4;
+ sb->f= a;
sb->tf_sel= 3;
sb++;
}
@@ -1490,16 +1553,16 @@ void stitch_uv_tface(int mode)
vtot= 0;
for (b=a, sb1=sb; b<tot && sb1->v==sb->v; b++, sb1++) {
- newuv[0] += sb1->tface->uv[sb1->tf_sel][0];
- newuv[1] += sb1->tface->uv[sb1->tf_sel][1];
+ newuv[0] += tface[sb1->f].uv[sb1->tf_sel][0];
+ newuv[1] += tface[sb1->f].uv[sb1->tf_sel][1];
vtot++;
}
newuv[0] /= vtot; newuv[1] /= vtot;
for (b=a, sb1=sb; b<a+vtot; b++, sb1++) {
- sb1->tface->uv[sb1->tf_sel][0]= newuv[0];
- sb1->tface->uv[sb1->tf_sel][1]= newuv[1];
+ tface[sb1->f].uv[sb1->tf_sel][0]= newuv[0];
+ tface[sb1->f].uv[sb1->tf_sel][1]= newuv[1];
}
}
} else if(mode==1) {
@@ -1515,8 +1578,8 @@ void stitch_uv_tface(int mode)
vtot2 = 0;
for (c=b, sb2=sb1; c<a+vtot; c++, sb2++) {
- uv = sb2->tface->uv[sb2->tf_sel];
- uv1 = sb1->tface->uv[sb1->tf_sel];
+ uv = tface[sb2->f].uv[sb2->tf_sel];
+ uv1 = tface[sb1->f].uv[sb1->tf_sel];
if (fabs(uv[0]-uv1[0]) < limit[0] &&
fabs(uv[1]-uv1[1]) < limit[1]) {
newuv[0] += uv[0];
@@ -1531,8 +1594,8 @@ void stitch_uv_tface(int mode)
for (c=b, sb2=sb1; c<a+vtot; c++, sb2++) {
if(sb2->flag & 4) {
- sb2->tface->uv[sb2->tf_sel][0]= newuv[0];
- sb2->tface->uv[sb2->tf_sel][1]= newuv[1];
+ tface[sb2->f].uv[sb2->tf_sel][0]= newuv[0];
+ tface[sb2->f].uv[sb2->tf_sel][1]= newuv[1];
sb2->flag &= ~4;
}
}
@@ -1549,65 +1612,74 @@ void stitch_uv_tface(int mode)
scrarea_queue_winredraw(curarea);
}
-void select_linked_tface_uv(void)
+void select_linked_tface_uv(int mode)
{
- MFace *mface;
- TFace *tface;
+ MFace *mf;
+ TFace *tface, *tf, *nearesttf=NULL;
Mesh *me;
- char sel;
- unsigned int a, b, c, vtot, tot;
+ char sel, *linkflag;
+ int nearestuv, i, nverts;
+ unsigned int a, b, c, vtot, tot, nearestv;
float limit[2], *uv, *uv1;
struct uvvertsort *sortblock, *sb, *sb1, *sb2;
if( is_uv_tface_editing_allowed()==0 ) return;
me= get_mesh(OBACT);
-
- setLinkedLimit(limit);
+ get_connected_limit_tface_uv(limit);
tot= 0;
- mface= me->mface;
- for(a=me->totface, tface=me->tface; a>0; a--, tface++, mface++) {
- if((tface->flag & TF_SELECT) && mface->v3) {
- tot += 3;
- if(mface->v4) tot++;
- }
- }
+ mf= (MFace*)me->mface;
+ tf= (TFace*)me->tface;
+ for(a=me->totface; a>0; a--, tf++, mf++)
+ if((tf->flag & TF_SELECT) && mf->v3)
+ tot += mf->v4? 4: 3;
+
if(tot==0) return;
- sb= sortblock= MEM_callocN(sizeof(struct uvvertsort)*tot,"sortsellinkuv");
+ if (mode!=2) {
+ find_nearest_uv(&nearesttf, &nearestv, &nearestuv);
- mface= me->mface;
- for(a=me->totface, tface=me->tface; a>0; a--, tface++, mface++) {
- if((tface->flag & TF_SELECT) && mface->v3) {
- if(tface->flag & TF_SEL1) sb->flag |= 1;
- sb->v= mface->v1;
- sb->tface= tface;
- sb->tf_sel= 0;
- sb++;
- if(tface->flag & TF_SEL2) sb->flag |= 1;
- sb->v= mface->v2;
- sb->tface= tface;
- sb->tf_sel= 1;
- sb++;
- if(tface->flag & TF_SEL3) sb->flag |= 1;
- sb->v= mface->v3;
- sb->tface= tface;
- sb->tf_sel= 2;
- sb++;
- if(mface->v4) {
- if(tface->flag & TF_SEL4) sb->flag |= 1;
- sb->v= mface->v4;
- sb->tface= tface;
- sb->tf_sel= 3;
+ if(nearesttf==NULL)
+ return;
+ }
+ else {
+ nearesttf= NULL;
+ nearestuv= 0;
+ }
+
+ sb= sortblock= MEM_callocN(sizeof(struct uvvertsort)*tot, "sortsellinkuv");
+ linkflag= MEM_callocN(sizeof(char)*me->totface, "linkflaguv");
+
+ mf= (MFace*)me->mface;
+ tf= (TFace*)me->tface;
+ for(a=0; a<me->totface; a++, tf++, mf++) {
+ if(!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT) && mf->v3) {
+ sel= 0;
+ sb1= sb;
+ nverts= mf->v4? 4: 3;
+ for(i=0; i<nverts; i++) {
+ if(tf->flag & TF_SEL_MASK(i))
+ sel= 1;
+ sb->f= a;
+ sb->tf_sel= i;
sb++;
}
+
+ if(nearesttf==tf || ((sel && mode==2)))
+ linkflag[a] = 1;
+
+ (sb1)->v= mf->v1;
+ (sb1+1)->v= mf->v2;
+ (sb1+2)->v= mf->v3;
+ if(mf->v4) (sb1+3)->v= mf->v4;
}
}
/* sort by vertex */
qsort(sortblock, tot, sizeof(struct uvvertsort), compuvvert);
+ tface= (TFace*)me->tface;
sel= 1;
while(sel) {
sel= 0;
@@ -1618,38 +1690,57 @@ void select_linked_tface_uv(void)
for (b=a, sb1=sb; b<tot && sb1->v==sb->v; b++, sb1++)
vtot++;
for (b=a, sb1=sb; b<a+vtot; b++, sb1++) {
- if(sb1->flag & 1) continue;
+ if(linkflag[sb1->f]) continue;
for (c=a, sb2=sb; c<a+vtot; c++, sb2++) {
- if(!(sb2->flag & 1)) continue;
- uv = sb2->tface->uv[sb2->tf_sel];
- uv1 = sb1->tface->uv[sb1->tf_sel];
+ if(!(linkflag[sb2->f])) continue;
+
+ uv = tface[sb2->f].uv[sb2->tf_sel];
+ uv1 = tface[sb1->f].uv[sb1->tf_sel];
if (fabs(uv[0]-uv1[0]) < limit[0] &&
fabs(uv[1]-uv1[1]) < limit[1]) {
- sb1->flag |= 1;
+ linkflag[sb1->f] = 1;
sel= 1;
break;
}
}
}
}
+ }
- /* if one tex vert is selected, select the whole tface */
- for (a=0, sb=sortblock; a<tot; a++, sb++) {
- if(sb->flag & 1) {
- sb->tface->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ if(mode==0 || mode==2) {
+ for(a=0, tf=tface; a<me->totface; a++, tf++)
+ if(linkflag[a])
+ tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ else
+ tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ }
+ else if(mode==1) {
+ for(a=0, tf=tface; a<me->totface; a++, tf++) {
+ if(linkflag[a]) {
+ if (mf->v4) {
+ if((tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)))
+ break;
+ }
+ else if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
+ break;
}
}
- /* sync the flags, one bitflag check is enough */
- for (a=0, sb=sortblock; a<tot; a++, sb++) {
- if(sb->tface->flag & TF_SEL1 && !(sb->flag & 1)) {
- sb->flag |= 1;
- sel= 1;
- }
+ if (a<me->totface) {
+ for(a=0, tf=tface; a<me->totface; a++, tf++)
+ if(linkflag[a])
+ tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ }
+ else {
+ for(a=0, tf=tface; a<me->totface; a++, tf++)
+ if(linkflag[a])
+ tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
}
}
+
MEM_freeN(sortblock);
+ MEM_freeN(linkflag);
BIF_undo_push("Select linked UV");
scrarea_queue_winredraw(curarea);