New loopcut version. much praise goes to Johnny Matthews who implemented precision cutting.

new features:

- after choosing a loop to cut you go into a second mode that lets you choose where exactly on the edge you want to cut.
the placement is in percentages, so 0% is one side of the edge, and 100% is the other side.

- holding CTRL snaps the placement to whole percentages. 1.00 instead of the standard 0.01 of a percentage.

- Pressing S while you place the cut turns on Smooth-subdivide for the cut (or as I like to call it: Loopcutsubdividesmooth :)

- the percentages and the ON/OFF for smooth cut can be seen in the view3D header.

fixes:

- loop takes into account hidden vertices, this solves bug #895.
- Cutpreviews are drawn correctly for triangular faces.
- renamed the function from loop -> loopoperations. I'm sure someone has a problem with the new name too, but BLAH! :D
- the parameters for the function are defines. loopoperations(LOOP_CUT) cuts, and loopoperation(LOOP_SELECT) selects (duh). this is changes in all the places the function gets called.

if people find new bugs, feel free to yell! :)

Roel
This commit is contained in:
2004-01-21 21:45:38 +00:00
parent 83fc1730e6
commit 220e2f0c25
4 changed files with 589 additions and 136 deletions

View File

@@ -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);

View File

@@ -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]<distance[0]){
distance[0]=distance[1];
closest=eed; /*save the current closest edge*/
}
} else {
distance[0]=distance[1];
closest=eed;
found=1;
}
}
}
eed= eed->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;i<ect;i++)
{
tagged[i] = NULL;
taggedsrch[i] = NULL;
}
ect = 0;
for(eed=G.eded.first; eed; eed = eed->next){
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;j<ect;j++){ /*Look through the list of tagged verts for connected edges*/
int addededge = 0;
if(taggedsrch[i]->f & 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;k<ect;k++) {
if(taggedsrch[k] == NULL) /*go to empty part of search list without finding*/
break;
if(tagged[j] == taggedsrch[k]){ /*We found a match already in the list*/
skip = 1;
break;
}
}
if(skip)
continue;
nextpos = 0;
if(findedgelist(look,tagged[j]->v2)){
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(j<ect)*/
timesthrough++;
} /*end while timesthrough */
percentcut = 0.50;
searching = 1;
cut = 1;
smooth = 0;
close = NULL;
/* Count the Number of Faces in the selected loop*/
percentfaces = 0;
for(evl= G.edvl.first; evl ;evl=evl->next){
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;i<percentfaces;i++){
evl = percentfacesloop[i];
for(eed = G.eded.first; eed; eed=eed->next){
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);

View File

@@ -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();

View File

@@ -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');