From 9d68a346bb9ffc86661a253896687489b7e8116e Mon Sep 17 00:00:00 2001 From: Johnny Matthews Date: Mon, 8 Mar 2004 02:49:50 +0000 Subject: Initial commit for vertexloop select. I altered the version that is in tuhopuu to not take into consideration hidden verts. This commit: selection code, loop cursor and menu option for 3d header committed. Still to come will be activation code (perhaps shift-B rotation) after more discussion. --- source/blender/include/BIF_cursors.h | 2 +- source/blender/src/cursors.c | 77 ++++++++++++ source/blender/src/editmesh.c | 230 +++++++++++++++++++++++++++++++++++ source/blender/src/header_view3d.c | 4 + 4 files changed, 312 insertions(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/include/BIF_cursors.h b/source/blender/include/BIF_cursors.h index c078d2589a7..c68c9b607c8 100644 --- a/source/blender/include/BIF_cursors.h +++ b/source/blender/include/BIF_cursors.h @@ -74,7 +74,7 @@ enum { BC_EDITCROSSCURSOR, BC_BOXSELCURSOR, BC_KNIFECURSOR, - + BC_VLOOPCURSOR, /* --- ALWAYS LAST ----- */ BC_NUMCURSORS, }; diff --git a/source/blender/src/cursors.c b/source/blender/src/cursors.c index ad512e407c3..1991f54c881 100644 --- a/source/blender/src/cursors.c +++ b/source/blender/src/cursors.c @@ -510,6 +510,83 @@ BEGIN_CURSOR_BLOCK BlenderCursor[BC_KNIFECURSOR]=&KnifeCursor; END_CURSOR_BLOCK + + /********************** Loop Select Cursor ***********************/ +BEGIN_CURSOR_BLOCK + +static char vloop_sbm[]={ + 0x00, 0x00, 0x7e, 0x00, 0x3e, 0x00, 0x1e, 0x00, + 0x0e, 0x00, 0x66, 0x60, 0x62, 0x6f, 0x00, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x60, 0x60, 0x60, 0x6f, 0x00, 0x00, +}; + +static char vloop_smsk[]={ + 0xff, 0x01, 0xff, 0x00, 0x7f, 0x00, 0x3f, 0x00, + 0xff, 0xf0, 0xff, 0xff, 0xf7, 0xff, 0xf3, 0xf0, + 0x61, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, + 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xff, 0xf0, 0xf0, +}; + + + +static char vloop_lbm[]={ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0x3f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, + 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, + 0xfc, 0x03, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, + 0x3c, 0x3c, 0x00, 0x3c, 0x3c, 0x3c, 0x00, 0x3c, + 0x0c, 0x3c, 0xff, 0x3c, 0x0c, 0x3c, 0xff, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, + 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, + 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, + 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, + 0x00, 0x3c, 0xff, 0x3c, 0x00, 0x3c, 0xff, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static char vloop_lmsk[]={ + 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xff, 0x3f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, + 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x3f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, + 0x0f, 0xff, 0x00, 0xff, 0x0f, 0xff, 0x00, 0xff, + 0x03, 0x3c, 0x00, 0x3c, 0x03, 0x3c, 0x00, 0x3c, + 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, + 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, + 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, +}; + + + + static BCursor VLoopCursor = { + /*small*/ + vloop_sbm, vloop_smsk, + 16, 16, + 0, 0, + /*big*/ + vloop_lbm, vloop_lmsk, + 32,32, + 0, 0, + /*color*/ + BC_BLACK, BC_WHITE + }; + + BlenderCursor[BC_VLOOPCURSOR]=&VLoopCursor; + +END_CURSOR_BLOCK + /********************** Put the cursors in the array ***********************/ } diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 1d7d9033e39..c30d5e75b23 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -9206,3 +9206,233 @@ void selectrandom_mesh(void) /* randomly selects a user-set % of vertices */ allqueue(REDRAWVIEW3D, 0); } } + +/* this utility function checks to see if 2 edit edges share a face, + returns 1 if they do + returns 0 if they do not, or if the function is passed the same edge 2 times +*/ +short sharesFace(EditEdge* e1, EditEdge* e2) +{ + EditVlak *search=NULL; + search = G.edvl.first; + if (e1 == e2){ + return 0 ; + } + while(search){ + if( + ((search->e1 == e1 || search->e2 == e1) || (search->e3 == e1 || search->e4 == e1)) && + ((search->e1 == e2 || search->e2 == e2) || (search->e3 == e2 || search->e4 == e2)) + ) { + return 1; + } + search = search->next; + } + return 0; +} +/* This function selects a vertex loop based on a each succesive edge having a valance of 4 + and not sharing a face with the previous edge */ +void vertex_loop_select() +{ + EditVert *v1=NULL,*v2=NULL,*curVert=NULL; + EditEdge *search=NULL,*startEdge=NULL,*valSearch = NULL,*nearest,*compEdge; + EditEdge *EdgeVal[5] = {NULL,NULL,NULL,NULL,NULL}; + short numEdges=0,curEdge = 0,looking = 1,edgeValCount = 0,i=0,looped = 0,choosing = 1,event,noloop=0,cancel=0; + + short mvalo[2] = {0,0}, mval[2], val; + + undo_push_mesh("Vertex Loop Select"); + SetBlenderCursor(BC_VLOOPCURSOR); + for(search=G.eded.first;search;search=search->next) + numEdges++; + + /* start with v1 and go in one direction. */ + while(choosing){ + + getmouseco_areawin(mval); + if (mval[0] != mvalo[0] || mval[1] != mvalo[1]) { + + mvalo[0] = mval[0]; + mvalo[1] = mval[1]; + + scrarea_do_windraw(curarea); + nearest = findnearestedge(); + if (nearest) { + for(search = G.eded.first;search;search=search->next) + search->f &= ~32; + + compEdge = startEdge = nearest; + nearest->f |= 32; + curEdge = 0; + v1 = startEdge->v1; + v2 = startEdge->v2; + looking = 1; + while(looking){ + /*Find Edges that have v1*/ + edgeValCount = -1; + EdgeVal[0] = EdgeVal[1] = EdgeVal[2] = NULL; + + for(valSearch = G.eded.first;valSearch;valSearch = valSearch->next){ + if(valSearch->v1 == v1 || valSearch->v2 == v1){ + if(valSearch != compEdge){ + if((valSearch->v1->h == 0) && (valSearch->v2->h == 0)){ + edgeValCount++; + EdgeVal[edgeValCount] = valSearch; + } + } + } + if(edgeValCount == 3)break; + } + /* Check that there was a valance of 4*/ + if(edgeValCount != 2){ + noloop = 1; + looking = 0; + break; + } + else{ + /* There were 3 edges, so find the one that does not share the previous edge */ + for(i=0;i<3;i++){ + if(sharesFace(compEdge,EdgeVal[i]) == 0){ + /* We went all the way around the loop */ + if(EdgeVal[i] == nearest){ + looking = 0; + looped = 1; + break; + } + else{ + /* we are still in the loop, so add the next edge*/ + curEdge++; + EdgeVal[i]->f |= 32; + compEdge = EdgeVal[i]; + if(compEdge->v1 == v1) + v1 = compEdge->v2; + else + v1 = compEdge->v1; + } + } + } + } + } + compEdge = nearest; + looking = 1; + while(looking/* && !looped*/){ + /*Find Edges that have v1*/ + edgeValCount = -1; + EdgeVal[0] = EdgeVal[1] = EdgeVal[2] = NULL; + + for(valSearch = G.eded.first;valSearch;valSearch = valSearch->next){ + if(valSearch->v1 == v2 || valSearch->v2 == v2){ + if(valSearch != compEdge){ + if((valSearch->v1->h == 0) && (valSearch->v2->h == 0)){ + edgeValCount++; + EdgeVal[edgeValCount] = valSearch; + } + } + } + if(edgeValCount == 3)break; + } + /* Check that there was a valance of 4*/ + if(edgeValCount != 2){ + noloop = 1; + looking = 0; + break; + } + else{ + /* There were 3 edges, so find the one that does not share the previous edge */ + for(i=0;i<3;i++){ + if(sharesFace(compEdge,EdgeVal[i]) == 0){ + /* We went all the way around the loop */ + if(EdgeVal[i] == nearest){ + looking = 0; + looped = 1; + break; + } + else{ + /* we are still in the loop, so add the next edge*/ + curEdge++; + EdgeVal[i]->f |= 32; + compEdge = EdgeVal[i]; + if(compEdge->v1 == v2) + v2 = compEdge->v2; + else + v2 = compEdge->v1; + } + } + } + } + } + /* set up for opengl drawing in the 3d window */ + persp(PERSP_VIEW); + glPushMatrix(); + mymultmatrix(G.obedit->obmat); + glColor3ub(0, 255, 255); + for(search = G.eded.first;search;search= search->next){ + if(search->f & 32){ + glBegin(GL_LINES); + glVertex3f(search->v1->co[0],search->v1->co[1],search->v1->co[2]); + glVertex3f(search->v2->co[0],search->v2->co[1],search->v2->co[2]); + glEnd(); + } + } + + glPopMatrix(); + } + } + + screen_swapbuffers(); + + + while(qtest()) + { + unsigned short val=0; + event= extern_qread(&val); + if(val && ((event==LEFTMOUSE || event==RETKEY) || event == MIDDLEMOUSE)) + { + if (nearest==NULL) + cancel = 1; + choosing=0; + break; + } + if(val && (event==ESCKEY || event==RIGHTMOUSE )) + { + choosing=0; + cancel = 1; + break; + } + } + } + if(!cancel){ + /* If this is a unmodified select, clear the selection */ + if(!(G.qual & LR_SHIFTKEY) && !(G.qual & LR_ALTKEY)){ + for(search = G.eded.first;search;search= search->next){ + search->v1->f &= !1; + search->v2->f &= !1; + } + } + /* Alt was not pressed, so add to the selection */ + if(!(G.qual & LR_ALTKEY)){ + for(search = G.eded.first;search;search= search->next){ + if(search->f & 32){ + search->v1->f |= 1; + search->v2->f |= 1; + } + search->f &= ~32; + } + } + /* alt was pressed, so subtract from the selection */ + else + { + for(search = G.eded.first;search;search= search->next){ + if(search->f & 32){ + search->v1->f &= !1; + search->v2->f &= !1; + } + search->f &= ~32; + } + } + } + else + undo_pop_mesh(1); + addqueue(curarea->win, REDRAW, 1); + SetBlenderCursor(SYSCURSOR); + return; +} \ No newline at end of file diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 5e27ef3edd3..46e1953a25a 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -731,6 +731,9 @@ void do_view3d_select_meshmenu(void *arg, int event) case 9: /* select less */ select_non_manifold(); break; + case 10: /* select vertexloop */ + vertex_loop_select(); + break; } allqueue(REDRAWVIEW3D, 0); } @@ -771,6 +774,7 @@ static uiBlock *view3d_select_meshmenu(void *arg_unused) menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Face Loop...|Shift R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Vertex Loop", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linked Vertices|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); if(curarea->headertype==HEADERTOP) { -- cgit v1.2.3