UV EditMode

-lasso tool now respects sticky selection setting when used 
with face 
mode
-use constants for sticky value.
This commit is contained in:
Campbell Barton 2007-10-03 10:36:04 +00:00
parent ba1f2248d0
commit d3382b8d1f
9 changed files with 185 additions and 18 deletions

@ -39,11 +39,14 @@ struct Render;
struct Image; struct Image;
struct ImBuf; struct ImBuf;
struct uiBlock; struct uiBlock;
struct MTFace;
void do_imagebuts(unsigned short event); void do_imagebuts(unsigned short event);
void calc_image_view(struct SpaceImage *sima, char mode); void calc_image_view(struct SpaceImage *sima, char mode);
void drawimagespace(struct ScrArea *sa, void *spacedata); void drawimagespace(struct ScrArea *sa, void *spacedata);
void image_changed(struct SpaceImage *sima, struct Image *image); void image_changed(struct SpaceImage *sima, struct Image *image);
int draw_uvs_face_check(void);
void tface_center(struct MTFace *tf, float cent[2], void * isquad);
void draw_uvs_sima(void); void draw_uvs_sima(void);
void image_set_tile(struct SpaceImage *sima, int dotile); void image_set_tile(struct SpaceImage *sima, int dotile);
void image_home(void); void image_home(void);

@ -466,17 +466,25 @@ typedef struct SpaceImaSel {
#define SI_TEXTURE 0 #define SI_TEXTURE 0
#define SI_SHOW 1 #define SI_SHOW 1
/* SpaceImage->dt_uv */
#define SI_UVDT_DASH 0 #define SI_UVDT_DASH 0
#define SI_UVDT_BLACK 1 #define SI_UVDT_BLACK 1
#define SI_UVDT_WHITE 2 #define SI_UVDT_WHITE 2
#define SI_UVDT_OUTLINE 3 #define SI_UVDT_OUTLINE 3
/* SpaceImage->sticky
* Note DISABLE should be 0, however would also need to re-arrange icon order,
* also, sticky loc is the default mode so this means we dont need to 'do_versons' */
#define SI_STICKY_LOC 0
#define SI_STICKY_DISABLE 1
#define SI_STICKY_VERTEX 2
/* SpaceImage->flag */ /* SpaceImage->flag */
#define SI_BE_SQUARE 1<<0 #define SI_BE_SQUARE 1<<0
#define SI_EDITTILE 1<<1 #define SI_EDITTILE 1<<1
#define SI_CLIP_UV 1<<2 #define SI_CLIP_UV 1<<2
#define SI_DRAWTOOL 1<<3 #define SI_DRAWTOOL 1<<3
#define SI_DEPRECATED1 1<<4 /* stick UVs to others in the same location */ #define SI_DEPRECATED1 1<<4 /* stick UVs to others in the same location */
#define SI_DRAWSHADOW 1<<5 #define SI_DRAWSHADOW 1<<5
#define SI_SELACTFACE 1<<6 #define SI_SELACTFACE 1<<6
#define SI_DEPRECATED2 1<<7 #define SI_DEPRECATED2 1<<7

@ -2580,6 +2580,7 @@ void do_fontbuts(unsigned short event)
} }
} }
#ifdef INTERNATIONAL
static void editing_panel_char_type(Object *ob, Curve *cu) static void editing_panel_char_type(Object *ob, Curve *cu)
{ {
uiBlock *block; uiBlock *block;
@ -2605,6 +2606,7 @@ static void editing_panel_char_type(Object *ob, Curve *cu)
uiDefButI(block, BUT, B_SETUPCHAR, "U", 280, 185, 15, 15, &G.charstart, 0, 0xffff, 0, 0, "Scroll character table up"); uiDefButI(block, BUT, B_SETUPCHAR, "U", 280, 185, 15, 15, &G.charstart, 0, 0xffff, 0, 0, "Scroll character table up");
uiDefButI(block, BUT, B_SETDOWNCHAR, "D", 280, 0, 15, 15, &G.charstart, 0, 0xffff, 0, 0, "Scroll character table down"); uiDefButI(block, BUT, B_SETDOWNCHAR, "D", 280, 0, 15, 15, &G.charstart, 0, 0xffff, 0, 0, "Scroll character table down");
} }
#endif
static void editing_panel_font_type(Object *ob, Curve *cu) static void editing_panel_font_type(Object *ob, Curve *cu)
{ {

@ -446,7 +446,7 @@ static void drawcursor_sima(float xuser_asp, float yuser_asp)
} }
// checks if we are selecting only faces // checks if we are selecting only faces
static int draw_uvs_face_check(void) int draw_uvs_face_check(void)
{ {
if (G.sima==NULL) if (G.sima==NULL)
return 0; return 0;

@ -616,7 +616,7 @@ void find_nearest_uv(MTFace **nearesttf, EditFace **nearestefa, unsigned int *ne
} }
} }
void mouse_select_sima(void) /* TODO - SYNCSEL */ void mouse_select_sima(void)
{ {
EditMesh *em = G.editMesh; EditMesh *em = G.editMesh;
EditFace *efa; EditFace *efa;
@ -646,13 +646,13 @@ void mouse_select_sima(void) /* TODO - SYNCSEL */
actface= (G.qual & LR_ALTKEY || G.sima->flag & SI_SELACTFACE); actface= (G.qual & LR_ALTKEY || G.sima->flag & SI_SELACTFACE);
switch(G.sima->sticky) { switch(G.sima->sticky) {
case 0: case SI_STICKY_LOC:
sticky=2; sticky=2;
break; break;
case 1: case SI_STICKY_DISABLE:
sticky=0; sticky=0;
break; break;
case 2: case SI_STICKY_VERTEX:
if(G.qual & LR_CTRLKEY) { if(G.qual & LR_CTRLKEY) {
sticky=0; sticky=0;
} else { } else {

@ -480,14 +480,50 @@ static void do_lasso_select_mesh_uv(short mcords[][2], short moves, short select
lasso_select_boundbox(&rect, mcords, moves); lasso_select_boundbox(&rect, mcords, moves);
for (efa= em->faces.first; efa; efa= efa->next) { if (draw_uvs_face_check()) { /* Face Center Sel */
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); float cent[2];
if (SIMA_FACEDRAW_CHECK(efa, tf)) {
nverts= efa->v4? 4: 3; /* selecting UV Faces with some modes requires us to change
for(i=0; i<nverts; i++) { * the selection in other faces (depending on the stickt mode)
if ((select) != (SIMA_UVSEL_CHECK(efa, tf, i))) { *
uvco_to_areaco_noclip(tf->uv[i], screenUV); * This only needs to be done when the Mesh is not used for selection
if (BLI_in_rcti(&rect, screenUV[0], screenUV[1]) && lasso_inside(mcords, moves, screenUV[0], screenUV[1])) { * (So for sticky modes - vertex or location based)
* This shoud be a generic function - so Ill make one but it will
* Only be used by this at the moment.
* */
if ((G.sima->flag & SI_SYNC_UVSEL)==0 && G.sima->sticky == SI_STICKY_VERTEX) {
/* tag all verts as untouched,
* then touch the ones that have a face center in the loop
* and select all MTFace UV's that use a touched vert */
EditVert *eve;
for (eve= em->verts.first; eve; eve= eve->next)
eve->tmp.l = 0;
for (efa= em->faces.first; efa; efa= efa->next) {
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if (SIMA_FACEDRAW_CHECK(efa, tf)) {
if ((select) != (SIMA_FACESEL_CHECK(efa, tf))) {
tface_center(tf, cent, (void *)efa->v4);
uvco_to_areaco_noclip(cent, screenUV);
if (BLI_in_rcti(&rect, screenUV[0], screenUV[1]) && lasso_inside(mcords, moves, screenUV[0], screenUV[1])) {
if (efa->v4) {
efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= efa->v4->tmp.l=1;
} else {
efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= 1;
}
}
}
}
}
/* now select tagged verts */
for (efa= em->faces.first; efa; efa= efa->next) {
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
nverts= efa->v4? 4: 3;
for(i=0; i<nverts; i++) {
if ((*(&efa->v1 + i))->tmp.l) {
if (select) { if (select) {
SIMA_UVSEL_SET(efa, tf, i); SIMA_UVSEL_SET(efa, tf, i);
} else { } else {
@ -496,9 +532,120 @@ static void do_lasso_select_mesh_uv(short mcords[][2], short moves, short select
} }
} }
} }
} else if ((G.sima->flag & SI_SYNC_UVSEL)==0 && G.sima->sticky == SI_STICKY_LOC) {
/* This is not that nice!
*
* do a proximity based sticky selecion,
* need to do some odd stuff here
*/
int j, face_count=0, coord_end = 0; /* so we know what the last coord is */
float *coords, limit[2];
get_connected_limit_tface_uv(limit);
/* count and index */
/* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */
for (efa= em->faces.first; efa; efa= efa->next) {
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if (SIMA_FACEDRAW_CHECK(efa, tf)) {
efa->tmp.p = tf;
face_count++;
} else {
efa->tmp.p = NULL;
}
}
/* assumes worst case where all quads are selected */
coords = MEM_mallocN(sizeof(float) * face_count * 8, "lasso sticky coords");
for (efa= em->faces.first; efa; efa= efa->next) {
if ((tf=(MTFace *)efa->tmp.p)) {
if ((select) != (SIMA_FACESEL_CHECK(efa, tf))) {
tface_center(tf, cent, (void *)efa->v4);
uvco_to_areaco_noclip(cent, screenUV);
if (BLI_in_rcti(&rect, screenUV[0], screenUV[1]) && lasso_inside(mcords, moves, screenUV[0], screenUV[1])) {
/* select now so as to avoid a location lookup later on */
if (select) {
SIMA_FACESEL_SET(efa, tf);
} else {
SIMA_FACESEL_UNSET(efa, tf);
}
/* add this face's coords so we can select close coords later on */
nverts= efa->v4? 4: 3;
for(j=0; j<nverts; j++) {
coords[coord_end++] = tf->uv[j][0];
coords[coord_end++] = tf->uv[j][1];
}
}
}
}
}
/* now select verts based on proximity to existing coords */
for (efa= em->faces.first; efa; efa= efa->next) {
if ((tf=(MTFace *)efa->tmp.p)) {
nverts= efa->v4? 4: 3;
for(i=0; i<nverts; i++) {
if ((SIMA_UVSEL_CHECK(efa, tf, i)) != (select) ) {
/* this corner is not selected, check if its next to an adjacent selected uv face */
for (j=0; j<coord_end; j+=2) {
if ( fabs(coords[j ]-tf->uv[i][0]) < limit[0] &&
fabs(coords[j+1]-tf->uv[i][1]) < limit[1] ) {
if (select)
tf->flag |= TF_SEL_MASK(i);
else
tf->flag &= ~TF_SEL_MASK(i);
break;
}
}
}
}
}
}
MEM_freeN(coords);
} else { /* SI_STICKY_DISABLE or G.sima->flag & SI_SYNC_UVSEL */
for (efa= em->faces.first; efa; efa= efa->next) {
if ((tf=(MTFace *)efa->tmp.p)) {
if ((select) != (SIMA_FACESEL_CHECK(efa, tf))) {
tface_center(tf, cent, (void *)efa->v4);
uvco_to_areaco_noclip(cent, screenUV);
if (BLI_in_rcti(&rect, screenUV[0], screenUV[1]) && lasso_inside(mcords, moves, screenUV[0], screenUV[1])) {
if (select) {
SIMA_FACESEL_SET(efa, tf);
} else {
SIMA_FACESEL_UNSET(efa, tf);
}
}
}
}
}
}
} else { /* Vert Sel*/
for (efa= em->faces.first; efa; efa= efa->next) {
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if (SIMA_FACEDRAW_CHECK(efa, tf)) {
nverts= efa->v4? 4: 3;
for(i=0; i<nverts; i++) {
if ((select) != (SIMA_UVSEL_CHECK(efa, tf, i))) {
uvco_to_areaco_noclip(tf->uv[i], screenUV);
if (BLI_in_rcti(&rect, screenUV[0], screenUV[1]) && lasso_inside(mcords, moves, screenUV[0], screenUV[1])) {
if (select) {
SIMA_UVSEL_SET(efa, tf, i);
} else {
SIMA_UVSEL_UNSET(efa, tf, i);
}
}
}
}
}
} }
} }
if (G.sima->flag & SI_SYNC_UVSEL) { if (G.sima->flag & SI_SYNC_UVSEL) {
if (select) EM_select_flush(); if (select) EM_select_flush();
else EM_deselect_flush(); else EM_deselect_flush();

@ -1199,11 +1199,15 @@ void image_buttons(void)
uiDefIconButBitI(block, TOGN, SI_SYNC_UVSEL, B_REDR, ICON_NO_GO_LEFT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Mesh independant selection"); uiDefIconButBitI(block, TOGN, SI_SYNC_UVSEL, B_REDR, ICON_NO_GO_LEFT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Mesh independant selection");
xco+= XIC; xco+= XIC;
if ((G.sima->flag & SI_SYNC_UVSEL)==0) { if ((G.sima->flag & SI_SYNC_UVSEL)==0) {
/* would use these if const's could go in strings
* SI_STICKY_LOC SI_STICKY_DISABLE SI_STICKY_VERTEX */
ubut = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC, ubut = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC,
"Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2", "Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2",
xco,0,XIC+10,YIC, &(G.sima->sticky), 0, 3.0, 0, 0, xco,0,XIC+10,YIC, &(G.sima->sticky), 0, 3.0, 0, 0,
"Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)"); "Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)");
xco+= XIC + 16; xco+= XIC + 16;
} else { } else {
xco+= 6; xco+= 6;
} }

@ -587,7 +587,10 @@ void do_global_buttons(unsigned short event)
ScrArea *sa; ScrArea *sa;
Brush *br; Brush *br;
int nr= 1; int nr= 1;
#ifdef INTERNATIONAL
char buf[FILE_MAX]; char buf[FILE_MAX];
#endif
ob= OBACT; ob= OBACT;

@ -4843,13 +4843,13 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
} else { } else {
/* normal operaton */ /* normal operaton */
if(G.qual==LR_CTRLKEY) { if(G.qual==LR_CTRLKEY) {
G.sima->sticky = 2; G.sima->sticky = SI_STICKY_VERTEX;
scrarea_do_headdraw(curarea); scrarea_do_headdraw(curarea);
} else if(G.qual==LR_SHIFTKEY) { } else if(G.qual==LR_SHIFTKEY) {
G.sima->sticky = 1; G.sima->sticky = SI_STICKY_DISABLE;
scrarea_do_headdraw(curarea); scrarea_do_headdraw(curarea);
} else if(G.qual==LR_ALTKEY) { } else if(G.qual==LR_ALTKEY) {
G.sima->sticky = 0; G.sima->sticky = SI_STICKY_LOC;
scrarea_do_headdraw(curarea); scrarea_do_headdraw(curarea);
} else { } else {
G.sima->flag ^= SI_SELACTFACE; G.sima->flag ^= SI_SELACTFACE;