diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h index 15cb9bdeb0f..b89da31103f 100644 --- a/source/blender/include/BIF_editmesh.h +++ b/source/blender/include/BIF_editmesh.h @@ -123,7 +123,10 @@ void separatemenu(void); void separate_mesh(void); void separate_mesh_loose(void); -void loop(int); +void loopoperations(char mode); +#define LOOP_SELECT 1 +#define LOOP_CUT 2 + void edge_select(void); void extrude_repeat_mesh(int steps, float offs); diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 789832d030e..3ac33722c4b 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -2095,6 +2095,64 @@ static EditEdge *findnearestedge() else return 0; } +/* does the same as findnearestedge but both vertices of the edge should be on screen*/ +static EditEdge *findnearestvisibleedge() +{ + EditEdge *closest, *eed; + EditVert *eve; + short foundedge=0, found=0, mval[2]; + float distance[2], v1[2], v2[2], mval2[2]; + + if(G.eded.first==0) return NULL; + else eed=G.eded.first; + + /* reset flags */ + for(eve=G.edve.first; eve; eve=eve->next){ + eve->f &= ~2; + } + calc_meshverts_ext_f2(); /*sets (eve->f & 2) for vertices that aren't visible*/ + + closest=NULL; + getmouseco_areawin(mval); + + mval2[0] = (float)mval[0]; /* cast to float because of the pdist function only taking floats...*/ + mval2[1] = (float)mval[1]; + + eed=G.eded.first; + while(eed) { /* compare the distance to the rest of the edges and find the closest one*/ + if( !((eed->v1->f | eed->v2->f) & 2) && (eed->v1->h==0 && eed->v2->h==0) ){ /* only return edges with both vertices on screen */ + v1[0] = eed->v1->xs; + v1[1] = eed->v1->ys; + v2[0] = eed->v2->xs; + v2[1] = eed->v2->ys; + + distance[1] = PdistVL2Dfl(mval2, v1, v2); + + if(distance[1]<50){ /* TODO: make this maximum selecting distance selectable (the same with vertice select?) */ + if(found) { /*do we have to compare it to other distances? */ + if (distance[1]next; + } + + /* reset flags */ + for(eve=G.edve.first; eve; eve=eve->next){ + eve->f &= ~2; + } + + if(found) return closest; + else return 0; +} + #if 0 /* this is a template function to demonstrate a loop with drawing... it is a temporal mode, so use with wisdom! if you can avoid, always better. (ton) @@ -2158,20 +2216,33 @@ void loop(int mode) /* functionality: various loop functions parameters: mode tells the function what it should do with the loop: - 's' = select - 'c' = cut in half + LOOP_SELECT = select + LOOP_CUT = cut in half */ -void loop(int mode) + +void loopoperations(char mode) { + EditVert* look = NULL; + EditEdge *start, *eed, *opposite,*currente, *oldstart; - EditVlak *evl, *currentvl, *formervl; + EditEdge **tagged = NULL,**taggedsrch = NULL,*close; + + EditVlak *evl,**percentfacesloop = NULL, *currentvl, *formervl; + short lastface=0, foundedge=0, c=0, tri=0, side=1, totface=0, searching=1, event=0, noface=1; - + short skip,nextpos,percentfaces; + + int i=0,ect=0,j=0,k=0,cut,smooth,timesthrough = 0; + + float percentcut, outcut; + + char mesg[100]; + if ((G.obedit==0) || (G.edvl.first==0)) return; - if(mode=='c')undo_push_mesh("Loop Subdivide"); - else if(mode=='s')undo_push_mesh("Faceloop select"); - + if(mode==LOOP_CUT)undo_push_mesh("Faceloop Subdivide"); + else if(mode==LOOP_SELECT)undo_push_mesh("Faceloop Select"); + start=NULL; oldstart=NULL; @@ -2182,10 +2253,9 @@ void loop(int mode) evl=currentvl=formervl=0; side=noface=1; lastface=foundedge=c=tri=totface=0; - - /* Look for an edge close by */ - start=findnearestedge(); - + + start=findnearestvisibleedge(); + /* If the edge doesn't belong to a face, it's not a valid starting edge */ if(start){ start->f |= 16; @@ -2203,7 +2273,7 @@ void loop(int mode) noface=0; evl->e3->f &= ~16; } - else if(evl->e4 && evl->e4->f & 16){ + else if(evl->e4 && (evl->e4->f & 16)){ noface=0; evl->e4->f &= ~16; } @@ -2214,28 +2284,25 @@ void loop(int mode) /* Did we find anything that is selectable? */ if(start && !noface && (oldstart==NULL || start!=oldstart)){ - + + /* If we stay in the neighbourhood of this edge, we don't have to recalculate the loop everytime*/ oldstart=start; - /* Clear flags */ - eed=G.eded.first; - while(eed) { - eed->f &= ~(2|4|8|32); + /* Clear flags */ + for(eed=G.eded.first; eed; eed=eed->next){ + eed->f &= ~(2|4|8|32|64); eed->v1->f &= ~(2|8|16); - eed->v2->f &= ~(2|8|16); - eed= eed->next; + eed->v2->f &= ~(2|8|16); } - evl= G.edvl.first; - while(evl){ + for(evl= G.edvl.first; evl; evl=evl->next){ evl->f &= ~(4|8); - totface++; - evl=evl->next; + totface++; } /* Tag the starting edge */ - start->f |= (2|4|8); + start->f |= (2|4|8|64); start->v1->f |= 2; start->v2->f |= 2; @@ -2252,8 +2319,11 @@ void loop(int mode) if(!(evl->v4)){ /* Exception for triangular faces */ if((evl->e1->f | evl->e2->f | evl->e3->f) & 2){ - tri=1; - currentvl=evl; + if(!(evl->f & 4)){ + tri=1; + currentvl=evl; + if(side==1) evl->f |= 4; + } } } else{ @@ -2264,47 +2334,65 @@ void loop(int mode) if(!(evl->f & 4)){ if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){ - opposite=evl->e1; - foundedge=1; + if(evl->e1->v1->h==0 && evl->e1->v2->h==0){ + opposite=evl->e1; + foundedge=1; + } } else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){ - opposite=evl->e2; - foundedge=1; + if(evl->e2->v1->h==0 && evl->e2->v2->h==0){ + opposite=evl->e2; + foundedge=1; + } } else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){ - opposite=evl->e3; - foundedge=1; + if(evl->e3->v1->h==0 && evl->e3->v2->h==0){ + opposite=evl->e3; + foundedge=1; + } } else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){ - opposite=evl->e4; - foundedge=1; + if(evl->e4->v1->h==0 && evl->e4->v2->h==0){ + opposite=evl->e4; + foundedge=1; + } } - currentvl=evl; - formervl=evl; + if(foundedge){ + currentvl=evl; + formervl=evl; - /* mark this side of the edge so we know in which direction we went */ - if(side==1) evl->f |= 4; + /* mark this side of the edge so we know in which direction we went */ + if(side==1) evl->f |= 4; + } } } else { if(evl!=formervl){ /* prevent going backwards in the loop */ if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){ - opposite=evl->e1; - foundedge=1; + if(evl->e1->v1->h==0 && evl->e1->v2->h==0){ + opposite=evl->e1; + foundedge=1; + } } else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){ - opposite=evl->e2; - foundedge=1; + if(evl->e2->v1->h==0 && evl->e2->v2->h==0){ + opposite=evl->e2; + foundedge=1; + } } else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){ - opposite=evl->e3; - foundedge=1; + if(evl->e3->v1->h==0 && evl->e3->v2->h==0){ + opposite=evl->e3; + foundedge=1; + } } else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){ - opposite=evl->e4; - foundedge=1; + if(evl->e4->v1->h==0 && evl->e4->v2->h==0){ + opposite=evl->e4; + foundedge=1; + } } currentvl=evl; @@ -2353,23 +2441,13 @@ void loop(int mode) currente->f |= 8; currentvl->f |= 8; - /* cheat to correctly split tri's: - * Set eve->f & 16 for the last vertex of the loop - */ - if(tri){ - currentvl->v1->f |= 16; - currentvl->v2->f |= 16; - currentvl->v3->f |= 16; - - currente->v1->f &= ~16; - currente->v2->f &= ~16; - } - + + /* is the the first time we've ran out of possible faces? - * try to start from the beginning but in the opposite direction to select as many - * verts as possible. + * try to start from the beginning but in the opposite direction go as far as possible */ - if(side==1){ + if(side==1){ + if(tri)tri=0; currente=start; currente->f |= 2; currente->v1->f |= 2; @@ -2377,7 +2455,7 @@ void loop(int mode) side++; c=0; } - else lastface=1; + else lastface=1; } /*----------END Decisions-----------------------------*/ @@ -2399,7 +2477,7 @@ void loop(int mode) glColor3ub(255, 255, 0); - if(mode=='s'){ + if(mode==LOOP_SELECT){ evl= G.edvl.first; while(evl){ if(evl->f & 8){ @@ -2438,14 +2516,18 @@ void loop(int mode) } } - if(mode=='c'){ + if(mode==LOOP_CUT){ evl= G.edvl.first; while(evl){ if(evl->f & 8){ float cen[2][3]; - int a=0; - glBegin(GL_LINES); + int a=0; + evl->v1->f &= ~8; + evl->v2->f &= ~8; + evl->v3->f &= ~8; + if(evl->v4)evl->v4->f &= ~8; + if(evl->e1->f & 8){ cen[a][0]= (evl->e1->v1->co[0] + evl->e1->v2->co[0])/2.0; cen[a][1]= (evl->e1->v1->co[1] + evl->e1->v2->co[1])/2.0; @@ -2461,8 +2543,8 @@ void loop(int mode) cen[a][1]= (evl->e2->v1->co[1] + evl->e2->v2->co[1])/2.0; cen[a][2]= (evl->e2->v1->co[2] + evl->e2->v2->co[2])/2.0; - evl->e1->v1->f |= 8; - evl->e1->v2->f |= 8; + evl->e2->v1->f |= 8; + evl->e2->v2->f |= 8; a++; } @@ -2471,8 +2553,8 @@ void loop(int mode) cen[a][1]= (evl->e3->v1->co[1] + evl->e3->v2->co[1])/2.0; cen[a][2]= (evl->e3->v1->co[2] + evl->e3->v2->co[2])/2.0; - evl->e1->v1->f |= 8; - evl->e1->v2->f |= 8; + evl->e3->v1->f |= 8; + evl->e3->v2->f |= 8; a++; } @@ -2483,43 +2565,58 @@ void loop(int mode) cen[a][1]= (evl->e4->v1->co[1] + evl->e4->v2->co[1])/2.0; cen[a][2]= (evl->e4->v1->co[2] + evl->e4->v2->co[2])/2.0; - evl->e1->v1->f |= 8; - evl->e1->v2->f |= 8; + evl->e4->v1->f |= 8; + evl->e4->v2->f |= 8; a++; } } - else{ /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */ - if(a!=2){ - if(evl->v1->f & 16){ + else{ /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */ + if(!(evl->v1->f & 8) && evl->v1->h==0){ cen[a][0]= evl->v1->co[0]; cen[a][1]= evl->v1->co[1]; cen[a][2]= evl->v1->co[2]; - evl->v1->f &= ~16; + a++; } - else if(evl->v2->f & 16){ + else if(!(evl->v2->f & 8) && evl->v2->h==0){ cen[a][0]= evl->v2->co[0]; cen[a][1]= evl->v2->co[1]; - cen[a][2]= evl->v2->co[2]; - evl->v2->f &= ~16; + cen[a][2]= evl->v2->co[2]; + a++; } - else if(evl->v3->f & 16){ + else if(!(evl->v3->f & 8) && evl->v3->h==0){ cen[a][0]= evl->v3->co[0]; cen[a][1]= evl->v3->co[1]; cen[a][2]= evl->v3->co[2]; - evl->v3->f &= ~16; - } - } + a++; + } } + + if(a==2){ + glBegin(GL_LINES); - - glVertex3fv(cen[0]); - glVertex3fv(cen[1]); - - glEnd(); + glVertex3fv(cen[0]); + glVertex3fv(cen[1]); + + glEnd(); + } } evl=evl->next; } + + eed=G.eded.first; + while(eed){ + if(eed->f & 64){ + glBegin(GL_LINES); + glColor3ub(200, 255, 200); + glVertex3fv(eed->v1->co); + glVertex3fv(eed->v2->co); + glEnd(); + eed=0; + }else{ + eed = eed->next; + } + } } /* restore matrix transform */ @@ -2536,10 +2633,10 @@ void loop(int mode) while(qtest()) { unsigned short val=0; - event= extern_qread(&val); // extern_qread stores important events for the mainloop to handle + event= extern_qread(&val); /* extern_qread stores important events for the mainloop to handle */ /* val==0 on key-release event */ - if(val && (event==ESCKEY || event==RIGHTMOUSE || event==LEFTMOUSE || event==RETKEY)){ + if(val && (event==ESCKEY || event==RIGHTMOUSE || event==LEFTMOUSE || event==RETKEY || event == MIDDLEMOUSE)){ searching=0; } } @@ -2547,66 +2644,419 @@ void loop(int mode) }/*while(event!=ESCKEY && event!=RIGHTMOUSE && event!=LEFTMOUSE && event!=RETKEY){*/ /*----------Select Loop------------*/ - if(mode=='s' && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){ + if(mode==LOOP_SELECT && start!=NULL && ((event==LEFTMOUSE || event==RETKEY) || event == MIDDLEMOUSE)){ - evl= G.edvl.first; - while(evl){ - if(evl->f & 8){ - evl->v1->f |= 1; - evl->v2->f |= 1; - evl->v3->f |= 1; - if(evl->v4)evl->v4->f |= 1; - } - evl=evl->next; + /* If this is a unmodified select, clear the selection */ + if(!(G.qual & LR_SHIFTKEY) && !(G.qual & LR_ALTKEY)){ + for(evl= G.edvl.first;evl;evl=evl->next){ + evl->v1->f &= !1; + evl->v2->f &= !1; + evl->v3->f &= !1; + if(evl->v4)evl->v4->f &= !1; + } } + /* Alt was not pressed, so add to the selection */ + if(!(G.qual & LR_ALTKEY)){ + for(evl= G.edvl.first;evl;evl=evl->next){ + if(evl->f & 8){ + evl->v1->f |= 1; + evl->v2->f |= 1; + evl->v3->f |= 1; + if(evl->v4)evl->v4->f |= 1; + } + } + } + /* alt was pressed, so subtract from the selection */ + else + { + for(evl= G.edvl.first;evl;evl=evl->next){ + if(evl->f & 8){ + evl->v1->f &= !1; + evl->v2->f &= !1; + evl->v3->f &= !1; + if(evl->v4)evl->v4->f &= !1; + } + } + } + } /*----------END Select Loop------------*/ /*----------Cut Loop---------------*/ - if(mode=='c' && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){ + if(mode==LOOP_CUT && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){ - /* subdivide works on selected verts... */ - eed=G.eded.first; - while(eed) { - if(eed->f & 8){ - eed->v1->f |= 1; - eed->v2->f |= 1; - } - eed= eed->next; + /* count the number of edges in the loop */ + for(eed=G.eded.first; eed; eed = eed->next){ + if(eed->f & 8) + ect++; + } + + tagged = malloc(ect*sizeof(EditEdge*)); + taggedsrch = malloc(ect*sizeof(EditEdge*)); + for(i=0;inext){ + if(eed->f & 8) + { + if(eed->h==0){ + eed->v1->f |= 1; + eed->v2->f |= 1; + tagged[ect] = eed; + eed->f &= ~(32); + ect++; + } + } + } + taggedsrch[0] = tagged[0]; + + while(timesthrough < 2) + { + i=0; + while(i < ect){/*Look at the members of the search array to line up cuts*/ + if(taggedsrch[i]==NULL)break; + for(j=0;jf & 32) /*If this edgee is marked as flipped, use vert 2*/ + look = taggedsrch[i]->v2; + else /*else use vert 1*/ + look = taggedsrch[i]->v1; + + if(taggedsrch[i] == tagged[j]) + continue; /*If we are looking at the same edge, skip it*/ + + skip = 0; + for(k=0;kv2)){ + while(nextpos < ect){ /*Find the first open spot in the search array*/ + if(taggedsrch[nextpos] == NULL){ + taggedsrch[nextpos] = tagged[j]; /*put tagged[j] in it*/ + taggedsrch[nextpos]->f |= 32; + addededge = 1; + break; + } + else + nextpos++; + } + } /* End else if connected to vert 2*/ + else if(findedgelist(look,tagged[j]->v1)){ /*If our vert is connected to vert 1 */ + while(nextpos < ect){ /*Find the first open spot in the search array */ + if(taggedsrch[nextpos] == NULL){ + taggedsrch[nextpos] = tagged[j]; /*put tagged[j] in it*/ + addededge = 1; + break; + } + else + nextpos++; + } + } + + if(addededge) + { + break; + } + }/* End Outer For (j)*/ + i++; + } /* End while(jnext){ + if(evl->f & 8) + { + percentfaces++; + } } - - subdivideflag(8, 0, B_KNIFE); /* B_KNIFE tells subdivide that edgeflags are already set */ - - eed=G.eded.first; - while(eed) { - if(eed->v1->f & 16) eed->v1->f |= 1; - else eed->v1->f &= ~1; - if(eed->v2->f & 16) eed->v2->f |= 1; - else eed->v2->f &= ~1; + /* create a dynamic array for those face pointers */ + percentfacesloop = malloc(percentfaces*sizeof(EditVlak*)); + + /* put those faces in the array */ + i=0; + for(evl= G.edvl.first; evl ;evl=evl->next){ + if(evl->f & 8) + { + percentfacesloop[i] = evl; + i++; + } + } + + while(searching){ - eed= eed->next; + /* For the % calculation */ + short mval[2]; + float labda, rc[2], len; + float v1[2], v2[2], v3[2]; + + /*------------- Percent Cut Preview Lines--------------- */ + scrarea_do_windraw(curarea); + persp(PERSP_VIEW); + glPushMatrix(); + mymultmatrix(G.obedit->obmat); + glColor3ub(0, 255, 255); + + /*Put the preview lines where they should be for the percentage selected.*/ + + for(i=0;inext){ + if(eed->f & 64){ /* color the starting edge */ + glBegin(GL_LINES); + + glColor3ub(200, 255, 200); + glVertex3fv(eed->v1->co); + glVertex3fv(eed->v2->co); + + glEnd(); + } + } + + glColor3ub(0,255,255); + if(evl->f & 8) + { + float cen[2][3]; + int a=0; + + evl->v1->f &= ~8; + evl->v2->f &= ~8; + evl->v3->f &= ~8; + if(evl->v4)evl->v4->f &= ~8; + + if(evl->e1->f & 8){ + float pct; + if(evl->e1->f & 32) + pct = 1-percentcut; + else + pct = percentcut; + cen[a][0]= evl->e1->v1->co[0] - ((evl->e1->v1->co[0] - evl->e1->v2->co[0]) * (pct)); + cen[a][1]= evl->e1->v1->co[1] - ((evl->e1->v1->co[1] - evl->e1->v2->co[1]) * (pct)); + cen[a][2]= evl->e1->v1->co[2] - ((evl->e1->v1->co[2] - evl->e1->v2->co[2]) * (pct)); + evl->e1->v1->f |= 8; + evl->e1->v2->f |= 8; + a++; + } + if((evl->e2->f & 8) && a!=2) + { + float pct; + if(evl->e2->f & 32) + pct = 1-percentcut; + else + pct = percentcut; + cen[a][0]= evl->e2->v1->co[0] - ((evl->e2->v1->co[0] - evl->e2->v2->co[0]) * (pct)); + cen[a][1]= evl->e2->v1->co[1] - ((evl->e2->v1->co[1] - evl->e2->v2->co[1]) * (pct)); + cen[a][2]= evl->e2->v1->co[2] - ((evl->e2->v1->co[2] - evl->e2->v2->co[2]) * (pct)); + + evl->e2->v1->f |= 8; + evl->e2->v2->f |= 8; + + a++; + } + if((evl->e3->f & 8) && a!=2){ + float pct; + if(evl->e3->f & 32) + pct = 1-percentcut; + else + pct = percentcut; + cen[a][0]= evl->e3->v1->co[0] - ((evl->e3->v1->co[0] - evl->e3->v2->co[0]) * (pct)); + cen[a][1]= evl->e3->v1->co[1] - ((evl->e3->v1->co[1] - evl->e3->v2->co[1]) * (pct)); + cen[a][2]= evl->e3->v1->co[2] - ((evl->e3->v1->co[2] - evl->e3->v2->co[2]) * (pct)); + + evl->e3->v1->f |= 8; + evl->e3->v2->f |= 8; + + a++; + } + + if(evl->e4){ + if((evl->e4->f & 8) && a!=2){ + float pct; + if(evl->e4->f & 32) + pct = 1-percentcut; + else + pct = percentcut; + cen[a][0]= evl->e4->v1->co[0] - ((evl->e4->v1->co[0] - evl->e4->v2->co[0]) * (pct)); + cen[a][1]= evl->e4->v1->co[1] - ((evl->e4->v1->co[1] - evl->e4->v2->co[1]) * (pct)); + cen[a][2]= evl->e4->v1->co[2] - ((evl->e4->v1->co[2] - evl->e4->v2->co[2]) * (pct)); + + evl->e4->v1->f |= 8; + evl->e4->v2->f |= 8; + + a++; + } + } + else { /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */ + if(!(evl->v1->f & 8) && evl->v1->h==0){ + cen[a][0]= evl->v1->co[0]; + cen[a][1]= evl->v1->co[1]; + cen[a][2]= evl->v1->co[2]; + a++; + } + else if(!(evl->v2->f & 8) && evl->v2->h==0){ + cen[a][0]= evl->v2->co[0]; + cen[a][1]= evl->v2->co[1]; + cen[a][2]= evl->v2->co[2]; + a++; + } + else if(!(evl->v3->f & 8) && evl->v3->h==0){ + cen[a][0]= evl->v3->co[0]; + cen[a][1]= evl->v3->co[1]; + cen[a][2]= evl->v3->co[2]; + a++; + } + } + + if(a==2){ + glBegin(GL_LINES); + + glVertex3fv(cen[0]); + glVertex3fv(cen[1]); + + glEnd(); + } + }/* end preview line drawing */ + } + /* restore matrix transform */ + glPopMatrix(); + + /*--------- END Preview Lines------------*/ + while(qtest()) + { + unsigned short val=0; + event= extern_qread(&val); /* extern_qread stores important events for the mainloop to handle */ + /* val==0 on key-release event */ + + + if(val && (event==SKEY)) + { + if(smooth)smooth = 0; + else smooth = 1; + } + + if(val && (event==LEFTMOUSE || event==RETKEY)) + { + searching=0; + } + if(val && (event==ESCKEY || event==RIGHTMOUSE )) + { + searching=0; + cut = 0; + } + + } + + + /* Determine the % on wich the loop should be cut */ + getmouseco_areawin(mval); + v1[0]=(float)mval[0]; + v1[1]=(float)mval[1]; + + v2[0]=(float)start->v1->xs; + v2[1]=(float)start->v1->ys; + + v3[0]=(float)start->v2->xs; + v3[1]=(float)start->v2->ys; + + rc[0]= v3[0]-v2[0]; + rc[1]= v3[1]-v2[1]; + len= rc[0]*rc[0]+ rc[1]*rc[1]; + + labda= ( rc[0]*(v1[0]-v2[0]) + rc[1]*(v1[1]-v2[1]) )/len; + if(labda<=0.0) labda=0.0; + else if(labda>=1.0)labda=1.0; + + percentcut=labda; + + if(start->f & 32) + percentcut = 1.0-percentcut; + + if (G.qual & LR_CTRLKEY) + percentcut = (int)(percentcut*100.0)/100.0; + + outcut = (percentcut*100.0); + if(smooth) + sprintf(mesg,"Cut: %0.2f%%, Smooth (skey): ON",outcut); + else + sprintf(mesg,"Cut: %0.2f%%, Smooth (skey): OFF",outcut); + headerprint(mesg); + screen_swapbuffers(); + + } + + if(cut){ + /* Now that we have selected a cut %, mark the edges for cutting. */ + for(eed = G.eded.first; eed; eed=eed->next){ + if(percentcut == 1.0) + percentcut = 0.9999; + else if(percentcut == 0.0) + percentcut = 0.0001; + if(eed->f & 8){ + if(eed->f & 32) + eed->f1 = 32768*(1.0-percentcut); + else + eed->f1 = 32768*(percentcut); + } + } + /*-------------------------------------*/ + + if(smooth) + subdivideflag(8, 0, B_KNIFE | B_PERCENTSUBD | B_SMOOTH); /* B_KNIFE tells subdivide that edgeflags are already set */ + else + subdivideflag(8, 0, B_KNIFE | B_PERCENTSUBD); /* B_KNIFE tells subdivide that edgeflags are already set */ + + for(eed = G.eded.first; eed; eed=eed->next){ + if(eed->v1->f & 16) eed->v1->f |= 1; + else eed->v1->f &= ~1; + + if(eed->v2->f & 16) eed->v2->f |= 1; + else eed->v2->f &= ~1; + } } } /*----------END Cut Loop-----------------------------*/ + - + /* Clear flags */ - eed=G.eded.first; - while(eed) { - eed->f &= ~(2|4|8|32); + for(eed = G.eded.first; eed; eed=eed->next){ + eed->f &= ~(2|4|8|32|64); eed->v1->f &= ~(2|16); - eed->v2->f &= ~(2|16); - eed= eed->next; + eed->v2->f &= ~(2|16); } - evl= G.edvl.first; - while(evl){ + for(evl= G.edvl.first; evl; evl=evl->next){ evl->f &= ~(4|8); - evl=evl->next; } countall(); + + if(tagged) + free(tagged); + if(taggedsrch) + free(taggedsrch); + if(percentfacesloop) + free(percentfacesloop); + /* send event to redraw this window, does header too */ addqueue(curarea->win, REDRAW, 1); } @@ -7593,10 +8043,10 @@ void LoopMenu(){ /* Called by KKey */ switch (ret){ case 1: - loop('s'); + loopoperations(LOOP_SELECT); break; case 2: - loop('c'); + loopoperations(LOOP_CUT); break; case 3: KnifeSubdivide(KNIFE_EXACT); diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index a6709c47e05..8d04d640bcf 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -716,7 +716,7 @@ void do_view3d_select_meshmenu(void *arg, int event) selectrandom_mesh(); break; case 6: /* select Faceloop */ - loop('s'); + loopoperations(LOOP_SELECT); break; case 7: /* select more */ select_more(); @@ -1657,7 +1657,7 @@ void do_view3d_edit_mesh_edgesmenu(void *arg, int event) KnifeSubdivide(KNIFE_PROMPT); break; case 4: /* Loop subdivide */ - loop('c'); + loopoperations(LOOP_CUT); break; case 5: /* Make Edge/Face */ addedgevlak_mesh(); diff --git a/source/blender/src/space.c b/source/blender/src/space.c index f9937dfaff9..1533273286c 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -1245,11 +1245,11 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if ELEM(G.obedit->type, OB_CURVE, OB_SURF) selectrow_nurb(); else if (G.obedit->type==OB_MESH) - loop('s'); + loopoperations(LOOP_SELECT); } else if(G.qual==LR_CTRLKEY) { if (G.obedit->type==OB_MESH) - loop('c'); + loopoperations(LOOP_CUT); } else if((G.qual==0)) transform('r');