/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 1997 by Ton Roosendaal, Frank van Beek and Joeri Kassenaar. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ /* edit.c */ /* bindkey -r f1,'make\n' bindkey -r f2,'/usr/people/trace/traces\n' muiscursor() deselectall() deselectall_ex(b) clearbase(mode) muisselect() copymenu() snapmenu() maketrack() makeparent() movetolayer() selector() recalcnormals() apply() initprintoverdraw() grabber() roteer() sizing() */ #include #include #include #include #include "/usr/people/include/Trace.h" #define PARENT(base) ( (base)->p || (base)->pkey ) extern short backbufok; extern ListBase editNurb; extern ListBase bpbase; extern void VecMulf(float *v1, float f); long *getbasekeyadr(); void muiscursor_oud() { float fx,fy,fz,dx,dy,fw, vec4[4]; long *t; Device mdev[2]; short mval[2], mx, my; t= view0.muis; winset(G.winar[0]); mdev[0] = MOUSEX; mdev[1] = MOUSEY; while(getbutton(LEFTMOUSE)) { getdev(2, mdev, mval); mval[1]-= S.vys; if(mval[0]!=view0.mx || mval[1]!=view0.my) { pnti(t[0], t[1], t[2]); getgpos(&fx,&fy,&fz,&fw); mx= view0.mx; my= view0.my; /* als mx==3200: toch even proberen de schermco te berekenen */ if(view0.mx==3200) { VECCOPY(vec4, view0.muis); vec4[3]= 1.0; Mat4MulVec4fl(G.persmat, vec4); if( vec4[3]!=0 ) { fx= 640.0+640.0*vec4[0]/vec4[3]; if( fabs(fx)<30000) { fy= 400.0+400.0*vec4[1]/vec4[3]; if(fabs(fy)<30000) { mx= fx; my= fy; } } } } if(mx!=3200) { dx= (mx-mval[0])*fw/640.0; dy= (my-mval[1])*fw/400.0; t[0]-= (G.persinv[0][0]*dx + G.persinv[1][0]*dy); t[1]-= (G.persinv[0][1]*dx + G.persinv[1][1]*dy); t[2]-= (G.persinv[0][2]*dx + G.persinv[1][2]*dy); } else { dx= ((float)(mval[0]-640))*fw/640.0; dy= ((float)(mval[1]-400))*fw/400.0; fz= fz/fw; t[0]= (G.persinv[0][0]*dx + G.persinv[1][0]*dy+ G.persinv[2][0]*fz)-view0.ofs[0]; t[1]= (G.persinv[0][1]*dx + G.persinv[1][1]*dy+ G.persinv[2][1]*fz)-view0.ofs[1]; t[2]= (G.persinv[0][2]*dx + G.persinv[1][2]*dy+ G.persinv[2][2]*fz)-view0.ofs[2]; } berekenschermco(t,&view0.mx); tekenoverdraw(0); } if(getbutton(RIGHTMOUSE)!=0 && G.ebase!=0) { if(G.ebase->soort==1) addvert_ebase(); else if ELEM(G.ebase->soort, 5, 11) addvert_Nurb(); break; } } } #define MOVES 50 #define DONT_KNOW 0 #define GRAB 1 #define ROTATE 2 #define SIZE 3 long interpret_move(float mouse[][2], long count) { long i, j, dist, dir = 0; float x1, x2, y1, y2, d1, d2, md, d, inp, sq; if (count <= 10) return (GRAB); /* filteren */ /*printf("count %d\n", count);*/ for( j = 3 ; j > 0; j--){ x1 = mouse[1][0]; y1 = mouse[1][1]; for (i = 2; i < count; i++){ x2 = mouse[i-1][0]; y2 = mouse[i-1][1]; mouse[i-1][0] = ((x1 + mouse[i][0]) /4.0) + (x2 / 2.0); mouse[i-1][1] = ((y1 + mouse[i][1]) /4.0) + (y2 / 2.0); x1 = x2; y1 = y2; } } /* cpack(0xff); bgnline(); for (i = 0; i < count; i++){ v2f(mouse[i]); } endline(); */ /* maak directions overzicht */ for (i = 0; i <= count - 2; i++){ x1 = mouse[i][0] - mouse[i + 1][0]; y1 = mouse[i][1] - mouse[i + 1][1]; if (x1 < -0.5){ if (y1 < -0.5) dir |= 32; else if (y1 > 0.5) dir |= 128; else dir |= 64; } else if (x1 > 0.5){ if (y1 < -0.5) dir |= 8; else if (y1 > 0.5) dir |= 2; else dir |= 4; } else{ if (y1 < -0.5) dir |= 16; else if (y1 > 0.5) dir |= 1; else dir |= 0; } } /* for (i = 7; i >= 0; i--){ if (dir & (1 << i)) printf("X"); else printf("."); } printf("\n"); */ /* alle kruisjes naar rechts halen */ for (i = 7; i>=0 ; i--){ if (dir & 128) dir = (dir << 1) + 1; else break; } dir &= 255; for (i = 7; i>=0 ; i--){ if ((dir & 1) == 0) dir >>= 1; else break; } /* for (i = 7; i >= 0; i--){ if (dir & (1 << i)) printf("X"); else printf("."); } printf("\n"); */ /* theorie zegt: 1 richting: rechte lijn * meer aaneengesloten richtingen: cirkel * onderbroken en minstens 1 bit gezet in hoogste 4 bits: size */ switch(dir){ case 1: return (GRAB); break; case 3: case 7: x1 = mouse[0][0] - mouse[count >> 1][0]; y1 = mouse[0][1] - mouse[count >> 1][1]; x2 = mouse[count >> 1][0] - mouse[count - 1][0]; y2 = mouse[count >> 1][1] - mouse[count - 1][1]; d1 = (x1 * x1) + (y1 * y1); d2 = (x2 * x2) + (y2 * y2); sq = sqrtf(d1); x1 /= sq; y1 /= sq; sq = sqrtf(d2); x2 /= sq; y2 /= sq; inp = (x1 * x2) + (y1 * y2); /*printf("%f\n", inp);*/ if (inp > 0.9) return (GRAB); else return (ROTATE); break; case 15: case 31: case 63: case 127: case 255: return (ROTATE); break; default: /* bij size moeten minstens een van de hogere bits gezet zijn */ if (dir < 16) return (ROTATE); else return (SIZE); } return (DONT_KNOW); } void muiscursor() { float fx,fy,fz,dx,dy,fw, vec4[4]; long *t, i = 1, ofsx, ofsy, event, mousex, mousey; Device mdev[2]; short mval[2], mx, my, val; float mcords[MOVES][2]; void grabber(), sizing(), roteer(); t= view0.muis; winset(G.winar[0]); mdev[0] = MOUSEX; mdev[1] = MOUSEY; if(G.qual==0) { qdevice(MOUSEX); qdevice(MOUSEY); getorigin(&ofsx, &ofsy); getdev(2, mdev, mval); mcords[0][0] = mousex = mval[0] - ofsx; mcords[0][1] = mousey = mval[1] - ofsy; drawmode(OVERDRAW); persp(0); color(3); bgnline(); while(getbutton(LEFTMOUSE)) { switch (traces_qread(&val)){ case MOUSEY: mousey = val - ofsy; if (mousex != mcords[i-1][0] || mousey != mcords[i-1][1]) { mcords[i][0] = mousex; mcords[i][1] = mousey; v2f(mcords[i]); i++; } break; case MOUSEX: mousex = val - ofsx; break; case LEFTMOUSE: break; default: i = -1; break; } if (i == MOVES || i == -1) break; } /* je hebt de neiging om de muis los te laten voordat de beweging afgemaakt is, dus even door lezen */ if (qtest() == 0) sginap(3); while (event = qtest() && i < MOVES){ if (event != MOUSEX && event != MOUSEY) break; /*printf("adding\n");*/ event = traces_qread(&val); if (event == MOUSEY){ mousey = val - ofsy; if (mousex != mcords[i-1][0] || mousey != mcords[i-1][1]) { mcords[i][0] = mousex; mcords[i][1] = mousey; v2f(mcords[i]); i++; } } else mousex = val - ofsx; if (i == MOVES) break; if (qtest() == 0) sginap(3); } endline(); persp(1); drawmode(NORMALDRAW); unqdevice(MOUSEX); unqdevice(MOUSEY); if (i > 5){ i = interpret_move(mcords, i); switch (i){ case GRAB: grabber(); break; case ROTATE: roteer(); break; case SIZE: sizing(); break; } drawmode(OVERDRAW); color(0); clear(); drawmode(NORMALDRAW); tekenoverdraw(0); return; } } getdev(2, mdev, mval); mval[1]-= S.vys; if(mval[0]!=view0.mx || mval[1]!=view0.my) { pnti(t[0], t[1], t[2]); getgpos(&fx,&fy,&fz,&fw); mx= view0.mx; my= view0.my; /* als mx==3200: toch even proberen de schermco te berekenen */ if(view0.mx==3200) { VECCOPY(vec4, view0.muis); vec4[3]= 1.0; Mat4MulVec4fl(G.persmat, vec4); if( vec4[3]!=0 ) { fx= (S.vxw/2)+(S.vxw/2)*vec4[0]/vec4[3]; if( fabs(fx)<30000) { fy= (S.vyw/2)+(S.vyw/2)*vec4[1]/vec4[3]; if(fabs(fy)<30000) { mx= fx; my= fy; } } } } if(mx!=3200) { dx= (mx-mval[0])*fw/(S.vxw/2); dy= (my-mval[1])*fw/(S.vyw/2); t[0]-= (G.persinv[0][0]*dx + G.persinv[1][0]*dy); t[1]-= (G.persinv[0][1]*dx + G.persinv[1][1]*dy); t[2]-= (G.persinv[0][2]*dx + G.persinv[1][2]*dy); } else { dx= ((float)(mval[0]-(S.vxw/2)))*fw/(S.vxw/2); dy= ((float)(mval[1]-(S.vyw/2)))*fw/(S.vyw/2); fz= fz/fw; t[0]= (G.persinv[0][0]*dx + G.persinv[1][0]*dy+ G.persinv[2][0]*fz)-view0.ofs[0]; t[1]= (G.persinv[0][1]*dx + G.persinv[1][1]*dy+ G.persinv[2][1]*fz)-view0.ofs[1]; t[2]= (G.persinv[0][2]*dx + G.persinv[1][2]*dy+ G.persinv[2][2]*fz)-view0.ofs[2]; } berekenschermco(t,&view0.mx); tekenoverdraw(0); } if(G.ebase!=0 && (getbutton(RIGHTMOUSE)!=0 || (G.qual & 48) ) ) { if(G.ebase->soort==1) addvert_ebase(); else if ELEM3(G.ebase->soort, 5, 11, -2) addvert_Nurb(); } } void deselectall() /* is toggle */ { struct Base *base; struct Nurb *nu; struct BezTriple *bezt; struct BPoint *bp; struct EditVert *eve; struct BodyPoint *bop; long a, b; short xs,ys; winset(G.winar[0]); if(G.ebase && G.ebase->soort==1) { if(G.ebase->lay & view0.lay) { a= 0; eve= (struct EditVert *)G.edve.first; while(eve) { if(eve->f & 1) { a= 1; break; } eve= eve->next; } eve= (struct EditVert *)G.edve.first; while(eve) { if(eve->h==0) { if(a) eve->f&= -2; else eve->f|= 1; } eve= eve->next; } tekenvertices_ext(); } } else if(G.ebase && ELEM3(G.ebase->soort, 5, 11, -2) ) { if(G.ebase->lay & view0.lay) { a= 0; nu= editNurb.first; while(nu) { if((nu->type & 7)==1) { b= nu->pntsu; bezt= nu->bezt; while(b--) { if(bezt->hide==0) { if(bezt->f1 & 1) { a=1; break; } if(bezt->f2 & 1) { a=1; break; } if(bezt->f3 & 1) { a=1; break; } } bezt++; } } else { b= nu->pntsu*nu->pntsv; bp= nu->bp; while(b--) { if(bp->hide==0) { if(bp->f1 & 1) { a=1; break; } } bp++; } } if(a) break; nu= nu->next; } nu= editNurb.first; while(nu) { if((nu->type & 7)==1) { b= nu->pntsu; bezt= nu->bezt; while(b--) { if(bezt->hide==0) { if(a) { bezt->f1 &= ~1; bezt->f2 &= ~1; bezt->f3 &= ~1; } else { bezt->f1 |= 1; bezt->f2 |= 1; bezt->f3 |= 1; } } bezt++; } } else { b= nu->pntsu*nu->pntsv; bp= nu->bp; while(b--) { if(bp->hide==0) { if(a) bp->f1 &= ~ 1; else bp->f1 |= 1; } bp++; } } nu= nu->next; } projektie(); } } else if(G.ebase && G.ebase->soort== -4) { if(G.ebase->lay & view0.lay) { a= 0; bop= bpbase.first; while(bop) { if(bop->f & 1) { a= 1; break; } bop= bop->next; } bop= bpbase.first; while(bop) { if(a) bop->f= 0; else bop->f= 1; bop= bop->next; } projektie(); } } else if(G.ebase); else { a= 0; base=G.firstbase; while(base) { if(TESTBASE(base)) { a= 1; break; } base= base->next; } base=G.firstbase; while(base) { if(base->lay & view0.lay) { if(a) base->f&= -2; else base->f|= 1; } base= base->next; } projektie(); } countall(); tekenoverdraw(0); } void deselectall_ex(b) /* alles deselect behalve b */ struct Base *b; { struct Base *base; base=G.firstbase; while(base) { if(base->f & 1) { if(base->lay & view0.lay) { if(b!=base) { base->f -=1; tekenbase_ext(base); } } } base= base->next; } } short setparentflags(lay,flag) short lay,flag; { /* alle bases met kinderen (lay en flag) krijgen base->f2 & 16 */ /* als dit voorkomt, return 1 */ struct Base *base; short ret=0; base= G.firstbase; while(base) { base->f2&= ~16; base= base->next; } base= G.firstbase; while(base) { if(base->lay & lay) { if(base->f & flag) { if(base->p) { if(base->p->lay & lay) { if(base->p->f & flag) { base->p->f2|=16; ret= 1; } } } } } base= base->next; } return ret; } void clearbase(mode) short mode; { struct Base *base; struct ObData *ob; float *af,tmat[4][4],omat[3][3]; long *ai; short parentlus; switch(mode) { case 1: if((mode= pupmenu("OK ? %t|Clear Parent %x1|and keep transform %x6"))== -1) return; parentlus=setparentflags(view0.lay,1); if(G.f & 4) { if(mode==6) makeduplibase_real(); } break; case 2: if(okee("Clear Track")==0) return; break; case 3: if(okee("Clear Matrix")==0) return; break; case 4: if(okee("Clear Origin")==0) return; break; case 5: if(okee("Clear Quaternion")==0) return; break; case 7: /* pas op 6 is in gebruik */ break; } base=G.firstbase; while(base) { if(TESTBASE(base)) { switch(mode){ case 1: case 6: /* bij mode 6: alleen parent wissen als base geen ouder is */ if(mode==1) base->p=0; else if(base->p) { if((base->f2 & 16)==0) { parentbase(base,tmat,omat); Mat3CpyMat4(base->m,tmat); VECCOPY(base->v,tmat[3]); base->q[0]= 1.0; base->q[1]=base->q[2]=base->q[3]= 0.0; base->p=0; } } if(base->p==0) { base->skelnr= 0; base->rodnr= 0; } if(base->soort & 1) { ob= (struct ObData *)base->d; if(ob->floatverts) freeN(ob->floatverts); ob->floatverts= 0; } break; case 2: base->t=0; break; case 3: ai= getbasekeyadr(base,3); Mat3One(ai); if(base->key==0) base->f= (base->f | 8); break; case 4: ai= getbasekeyadr(base,1); ai[0]=ai[1]=ai[2]=0; break; case 5: af= (float *)getbasekeyadr(base,2); af[0]=1.0; af[1]=af[2]=af[3]=0.0; if(base->key==0) base->f= (base->f | 4); break; } } base= base->next; if(mode==6 && base==0) { if(parentlus) base= G.firstbase; parentlus= setparentflags(view0.lay,1); } } projektie(); } void convertmenu() { struct ObData *ob,*obact; struct PerfSph *ps; struct ColBlck *col,*ocol; struct Base *base,*tbase; struct Key *key, *keyn, *prevk; long len; short event,colt,ocolt,min,type; char menustr[160]; if(G.ebase) return; type= 0; base= G.firstbase; while(base) { if(TESTBASE(base)) { if(type==0) type= base->soort; else if(type!=base->soort) { type= 0; break; } } base= base->next; } if(type==0 || type==1 || type==2) { error("Can't convert"); return; } menustr[0]= 0; if(type== -2) { strcpy(menustr, "Convert Move Base to %t|"); strcat(menustr, "Curve%x11"); } else if(type==5) { strcpy(menustr, "Convert Nurbs Object to %t|"); strcat(menustr, "Triface%x1"); } else if(type==9) { strcpy(menustr, "Convert Text Object to %t|"); strcat(menustr, "Nurbs%x5|Curve%x11"); } else if(type==11) { strcpy(menustr, "Convert Curve Object to %t|"); strcat(menustr, "Triface%x1|Move%x102|Nurbs%x11"); } event= pupmenu(menustr); if(event== -1) return; base= G.firstbase; while(base) { if(TESTBASE(base)) { switch(type) { case 102: if(event==11) move_to_curve(base); break; case 5: if(event==1) nurbs_to_triface(base); break; case 9: if(event==11) text_to_curve(base); break; case 11: if(event==1) nurbs_to_triface(base); else if(event==102) curve_to_move(base); break; } } base= base->next; } if(G.mainb==5) tekenobjbuts(1); else if(G.mainb==9) tekeneditbuts(0); projektie(); } void ebase_copymenu() { extern struct Nurb *lastnu; extern short isNurbsel(); struct Nurb *nu; short event; char str[140]; if ELEM3(G.ebase->soort, 5, 11, -2) { if(lastnu==0) return; strcpy(str, "COPY %t|Resolution %x1|Order %x2"); event= pupmenu(str); if(event>0) { nu= editNurb.first; while(nu) { if(nu!=lastnu && isNurbsel(nu) ) { if(event==1) { nu->resolu= lastnu->resolu; nu->resolv= lastnu->resolv; } else if(event==2) { nu->orderu= lastnu->orderu; nu->orderv= lastnu->orderv; } } nu= nu->next; } makeDispList(G.ebase); } } } void copymenu() { struct ObData *ob,*obact; struct IkaData *ika; struct PerfSph *ps; struct Nurb *nu, *newnu, *duplicateNurb(); struct ColBlck *col,*ocol; struct Base *base,*tbase, *dbase; struct Key *key, *keyn, *prevk; struct Bezier *bez; struct VV *vv; long *ai; long len; short event,colt,ocolt,min,type; char str[140]; if(G.basact==0) return; if(G.ebase) { ebase_copymenu(); return; } G.moving=1; tekenbase_ext(G.basact); strcpy(str, "COPY %t|Color%x1|Matrix%x2|Quat%x3|Origin%x4|Drawtype%x5|Len%x9|Startframe%x10|BaseKeys%x7"); if(G.basact->soort==1) strcat(str, "|Verts+Faces%x6"); else if(G.basact->soort==2) strcat(str, "|LampSettings%x8"); else if(G.basact->soort==4) strcat(str, "|CameraNoise%x8"); else if(G.basact->soort==5) strcat(str, "|Nurbs%x6"); else if(G.basact->soort==9) strcat(str, "|Text%x6|FontSettings%x8"); else if(G.basact->soort==11) strcat(str, "|Curves%x6|BevelSettings%x8"); event= pupmenu(str); G.moving= 0; if(event== -1) { projektie(); return; } else if(event==1) { if(G.basact->soort & 1) { if(G.basact->soort==3) { ps=(struct PerfSph *)G.basact->d; ocol= &ps->c; ocolt=1; } else { ob=(struct ObData *)G.basact->d; ocol=(struct ColBlck *)(ob+1); ocolt=ob->c; } } else { projektie(); return; } } else if(event==6) { if(G.basact->soort & 1) { obact= (struct ObData *)G.basact->d; ocol=(struct ColBlck *)(obact+1); } } else if(event==5) { if ELEM5(G.basact->soort, 1, 5, 7, 9, 11) { ob= (struct ObData *)G.basact->d; type= ob->dt; } else if(G.basact->soort== -4) { ika= (struct IkaData *)G.basact->d; type= ika->dt; } else type=1; } tbase= G.basact; base=G.firstbase; while(base) { if(base!=G.basact) { if(TESTBASE(base)) { if(event==1) { if(base->soort & 1) { if(base->soort==3) { ps=(struct PerfSph *)base->d; col= &ps->c; colt=1; } else { ob=(struct ObData *)base->d; col=(struct ColBlck *)(ob+1); colt=ob->c; } min=ocolt; if(ocolt>colt) min=colt; memcpy(col,ocol,min*sizeof(struct ColBlck)); } } else if(event==2) { /* mat */ G.basact= base; /* anders geeft getbasekeyadr geen key terug */ ai= getbasekeyadr(base,3); memcpy(ai,tbase->m,36); G.basact= tbase; base->f&= ~8; } else if(event==3) { /* quat */ G.basact= base; /* anders geeft getbasekeyadr geen key terug */ ai= getbasekeyadr(base,2); memcpy(ai,tbase->q,16); G.basact= tbase; base->f&= ~4; } else if(event==4) { /* or */ G.basact= base; /* anders geeft getbasekeyadr geen key terug */ ai= getbasekeyadr(base,1); memcpy(ai,tbase->o,12); G.basact= tbase; } else if(event==5) { /* drawt */ if ELEM5(base->soort, 1, 5, 7, 9, 11) { ob= (struct ObData *)base->d; ob->dt= type; makeDispList(base); } else if(base->soort== -4) { ika= (struct IkaData *)G.basact->d; ika->dt= type; } } else if(event==9) { /* len */ base->len= G.basact->len; } else if(event==10) { /* sf */ base->sf= G.basact->sf; } else if(event==6) { /* specific basedata */ ob=(struct ObData *)base->d; if(G.basact->soort==1) { /* verts & faces */ if(base->soort==1) { ob->vv->us--; if(ob->vv->us<1) freeN(ob->vv); ob->vv= obact->vv; ob->vv->us++; if(ob->cc) { ai= (long *)mallocN(sizeof(struct ObData)+ obact->c*sizeof(struct ColBlck),"copymenu"); base->d= ai; freelistN(&ob->disp); memcpy(ai, ob, sizeof(struct ObData)); freeN(ob); ob= (struct ObData *)ai; ob->c= obact->c; memcpy(ob+1,ocol,ob->c*sizeof(struct ColBlck)); } /* displisten van alle users, ook deze base */ vv= ob->vv; dbase= G.firstbase; while(dbase) { if(dbase!=G.basact && dbase->soort==1 && dbase->lay & view0.lay) { ob= (struct ObData *)dbase->d; if(ob->vv == vv) makeDispList(dbase); } dbase= dbase->next; } } } else if ELEM(G.basact->soort, 5, 11) { /* Nurbs, curve */ if(base->soort==G.basact->soort) { freeNurblist(&(ob->cu->curve)); nu= obact->cu->curve.first; while(nu) { newnu= duplicateNurb(nu); addtail(&(ob->cu->curve), newnu); nu= nu->next; } ob->cu->ws= obact->cu->ws; if(obact->cu->key) { if(ob->cu->key) freekeys(ob->cu->key); key= obact->cu->key; prevk= 0; len= sizeof(struct Key) +4 +12*obact->cu->keyverts; while(key) { keyn= (struct Key *)mallocN(len, "copymenuKey"); memcpy(keyn, key, len); if(prevk==0) ob->cu->key= keyn; else prevk->next= keyn; prevk= keyn; key= key->next; } ob->cu->keyverts= obact->cu->keyverts; } if(base->soort==11) { makeBevelList(base); } makeDispList(base); if(ob->cc) { ai= (long *)mallocN(sizeof(struct ObData)+ obact->c*sizeof(struct ColBlck),"copymenu"); base->d= ai; memcpy(ai,ob,sizeof(struct ObData)); freeN(ob); ob= (struct ObData *)ai; ob->c= obact->c; memcpy(ob+1,ocol,ob->c*sizeof(struct ColBlck)); } } } else if(G.basact->soort==9) { /* text */ if(base->soort==9) { len= strlen(obact->fo->str); if(len) { if(ob->fo->str) freeN(ob->fo->str); ob->fo->str= mallocN(len+2, "copymenu"); strcpy(ob->fo->str, obact->fo->str); ob->fo->len= len; makepolytext(base); extrudepoly(base); } } } } else if(event==7) { /* BaseKeys */ if(base->key) freekeys(base->key); base->key= 0; if(G.basact->key) { key= G.basact->key; prevk= 0; len= sizeof(struct Key) +19*4; while(key) { keyn= (struct Key *)mallocN(len, "copymenuKey"); memcpy(keyn, key, len); if(prevk==0) base->key= keyn; else prevk->next= keyn; prevk= keyn; key= key->next; } } if(base->ipokey) freeN(base->ipokey); base->ipokey= 0; if(G.basact->ipokey) { bez= G.basact->ipokey; len= sizeof(struct Bezier)+ 36*bez->cp; base->ipokey= (struct Bezier *)mallocN(len, "copymenuIpokey"); memcpy(base->ipokey, bez, len); } } else if(event==8) { /* settings */ if(G.basact->soort==2) { if(base->soort==2) { /* lamp */ memcpy(base->d, G.basact->d, sizeof(struct LaData)); } } else if(G.basact->soort==4) { /* camera */ base->noise= G.basact->noise; base->noisefreq= G.basact->noisefreq; base->nvecint= G.basact->nvecint; base->nrotint= G.basact->nrotint; if(base->iponoise) freeN(base->iponoise); if(G.basact->iponoise) { bez= G.basact->iponoise; len= sizeof(struct Bezier)+bez->cp*36; base->iponoise= (struct Bezier *)mallocN(len,"addupbaseii"); memcpy(base->iponoise, G.basact->iponoise, len); } } else if(G.basact->soort==9) { /* font */ if(base->soort==9) { ob= (struct ObData *)base->d; obact= (struct ObData *)G.basact->d; freevfont(ob->fo->vf); obact->fo->vf->us++; ob->fo->vf= obact->fo->vf; memcpy(ob->fo->set, obact->fo->set, 12); memcpy( &(ob->po->f), &(obact->po->f), 10); ob->po->depth= obact->po->depth; makepolytext(base); extrudepoly(base); } } else if(G.basact->soort==11) { /* curve */ if(base->soort==11) { ob= (struct ObData *)base->d; obact= (struct ObData *)G.basact->d; ob->cu->bevbase= obact->cu->bevbase; memcpy( &(ob->cu->flag), &(obact->cu->flag), 14); makeBevelList(base); makeDispList(base); } } } } } base=base->next; } projektie(); } void snapmenu() { struct Base *base; struct ObData *ob; struct EditVert *eve; float gridf,tmat[4][4],imat[3][3],bmat[3][3],vec[3], min[3], max[3]; short event; long count; event= pupmenu("SNAP %t|Sel -> Grid%x1|Sel -> Curs%x2|Curs-> Grid%x3|Curs-> Sel%x4"); gridf= view0.grid; if(event== 1 || event==2) { /* sel->grid sel->curs */ if(G.ebase) { if ELEM4(G.ebase->soort, 5, 11, -2, -4) bgnVedit(); parentbase(G.ebase,tmat,bmat); Mat3CpyMat4(bmat,tmat); if(G.ebase->soort==1) { ob= (struct ObData *)G.ebase->d; Mat3MulFloat(bmat,ob->vv->ws); } else if ELEM(G.ebase->soort, 5, 11) { ob= (struct ObData *)G.ebase->d; Mat3MulFloat(bmat,ob->cu->ws); } Mat3Inv(imat,bmat); eve= (struct EditVert *)G.edve.first; while(eve) { if(eve->f & 1) { if(event==2) { vec[0]= view0.muis[0]-tmat[3][0]; vec[1]= view0.muis[1]-tmat[3][1]; vec[2]= view0.muis[2]-tmat[3][2]; } else { VECCOPY(vec,eve->co); Mat3MulVecfl(bmat,vec); VecAddf(vec,vec,tmat[3]); vec[0]= view0.grid*ffloor(.5+ vec[0]/gridf); vec[1]= view0.grid*ffloor(.5+ vec[1]/gridf); vec[2]= view0.grid*ffloor(.5+ vec[2]/gridf); VecSubf(vec,vec,tmat[3]); } Mat3MulVecfl(imat,vec); VECCOPY(eve->co,vec); } eve= eve->next; } if ELEM4(G.ebase->soort, 5, 11, -2, -4) { copyVedit(); endVedit(); } projektie(); return; } base= G.firstbase; while(base) { if(TESTBASE(base)) { if(event==2) { vec[0]= -base->r[0]+view0.muis[0]; vec[1]= -base->r[1]+view0.muis[1]; vec[2]= -base->r[2]+view0.muis[2]; } else { vec[0]= -base->r[0]+view0.grid*ffloor(.5+ base->r[0]/gridf); vec[1]= -base->r[1]+view0.grid*ffloor(.5+ base->r[1]/gridf); vec[2]= -base->r[2]+view0.grid*ffloor(.5+ base->r[2]/gridf); } if(base->p!=0 && G.hie) { parentbase(base,tmat,bmat); Mat3Inv(imat,bmat); Mat3MulVecfl(imat,vec); base->o[0]+= vec[0]; base->o[1]+= vec[1]; base->o[2]+= vec[2]; } else { base->v[0]+= vec[0]; base->v[1]+= vec[1]; base->v[2]+= vec[2]; } } base= base->next; if(G.ebase) base= 0; } projektie(); } else if(event==3) { /* curs to grid */ view0.muis[0]= view0.grid*ffloor(.5+view0.muis[0]/gridf); view0.muis[1]= view0.grid*ffloor(.5+view0.muis[1]/gridf); view0.muis[2]= view0.grid*ffloor(.5+view0.muis[2]/gridf); berekenschermco(view0.muis,&view0.mx); tekenoverdraw(0); } else if(event==4) { /* curs to sel */ count= 0; min[0]= min[1]= min[2]= 1.0e20; max[0]= max[1]= max[2]= -1.0e20; if(G.ebase) { if ELEM4(G.ebase->soort, 5, 11, -2, -4) bgnVedit(); parentbase(G.ebase,tmat,bmat); Mat3CpyMat4(bmat,tmat); if(G.ebase->soort==1) { ob= (struct ObData *)G.ebase->d; Mat3MulFloat(bmat,ob->vv->ws); } else if ELEM(G.ebase->soort, 5, 11) { ob= (struct ObData *)G.ebase->d; Mat3MulFloat(bmat,ob->cu->ws); } eve= (struct EditVert *)G.edve.first; while(eve) { if(eve->f & 1) { VECCOPY(vec,eve->co); Mat3MulVecfl(bmat,vec); VecAddf(vec,vec,tmat[3]); MinMax3(min, max, vec); count++; } eve= eve->next; } if(count) { view0.muis[0]= (min[0]+max[0])/2; view0.muis[1]= (min[1]+max[1])/2; view0.muis[2]= (min[2]+max[2])/2; } if ELEM4(G.ebase->soort, 5, 11, -2, -4) endVedit(); } else { base= G.firstbase; while(base) { if(TESTBASE(base)) { VECCOPY(vec, base->r); MinMax3(min, max, vec); count++; } base= base->next; } if(count) { view0.muis[0]= (min[0]+max[0])/2; view0.muis[1]= (min[1]+max[1])/2; view0.muis[2]= (min[2]+max[2])/2; } } berekenschermco(view0.muis,&view0.mx); tekenoverdraw(0); } } void enter_ebasemode(base) struct Base *base; { struct IkaData *ika; struct MoData *mo; struct ObData *ob; if(base==0) return; if((base->lay & view0.lay)==0) return; if(base->soort== -4) { ika= (struct IkaData *)base->d; countkeys(); if(ika->key) { if( (G.ipomode!=22) || (G.actkey==0) ) { error("Must have active key"); return; } } G.ebase= base; make_ebaseIka(); } else if(base->soort== -2) { mo= (struct MoData *)base->d; countkeys(); if(mo->key) { if( (G.ipomode!=22) || (G.actkey==0) ) { error("Must have active key"); return; } } G.ebase= base; make_ebaseNurb(); } else if(base->soort==1) { ob= (struct ObData *)base->d; countkeys(); if(ob->vv->key) { if( (G.ipomode!=22) || (G.actkey==0) ) { error("Must have active key"); return; } } G.ebase= base; make_ebasedata(); } else if(base->soort==9) { G.ebase= base; textedit(); } else if(base->soort==5 || base->soort==11) { ob= (struct ObData *)base->d; countkeys(); if(ob->cu->key) { if( (G.ipomode!=22) || (G.actkey==0) ) { error("Must have active key"); return; } } G.ebase= base; make_ebaseNurb(); } if(G.ebase) G.ebase->f&= ~1; /* wel testen vanwege soort==9 */ countall(); projektie(); } void exit_ebasemode() { struct Base *base, *tbase; struct ObData *ob; struct MoData *mo; struct IkaData *ika; struct VV *vv; if(G.ebase==0) return; if(G.ebase->soort==1) { ob= (struct ObData *)G.ebase->d; vv= ob->vv; if(vv->key) { if(G.totvert!= vv->vert) { if(okee("Different # vertices: copy to all keys")==0) return; } } load_ebasedata(); if(G.edve.first) freelist(&G.edve.first); if(G.eded.first) freelist(&G.eded.first); if(G.edvl.first) freelist(&G.edvl.first); free_hashedgetab(); } else if ELEM(G.ebase->soort, 5, 11) { ob= (struct ObData *)G.ebase->d; if(G.ipomode==22 && ob->cu->key && G.actkey) { if(G.totvert!= ob->cu->keyverts) { if(okee("Different # vertices: copy to all keys")==0) return; } } load_ebaseNurb(); freeNurblist(&editNurb); } else if(G.ebase->soort== -2) { mo= (struct MoData *)G.ebase->d; if(G.ipomode==22 && mo->key && G.actkey) { if(G.totvert!= mo->keyverts) { if(okee("Different # vertices: copy to all keys")==0) return; } } load_ebaseNurb(); freeNurblist(&editNurb); } else if(G.ebase->soort== -4) { ika= (struct IkaData *)G.ebase->d; if(G.ipomode==22 && ika->key && G.actkey) { if(G.totvert!= ika->keyverts) { if(okee("Different # vertices: copy to all keys")==0) return; } } load_ebaseIka(); } G.ebase->f|=1; /* weer select maken */ base= G.ebase; G.ebase=0; makeDispList(base); /* ebase moet 0 zijn voor curve-extrude */ countall(); loadkeypos(base, base); /* voor vv key */ /* heeft dit nog invloed op andere bases? */ if(base->soort==11) { /* test of base als bevelcurve wordt gebruikt */ tbase= G.firstbase; while(tbase) { if(tbase->soort==11) { ob= (struct ObData *)tbase->d; if(ob->cu->bevbase==base) { makeDispList(tbase); } } tbase= tbase->next; } } projektie(); } ulong samplerect(buf, size, dontdo) ulong *buf; long size; ulong dontdo; { ulong *bufmin,*bufmax; long a,b,rc,tel,aantal,dirvec[4][2],maxob; ulong retval=0; maxob= G.totobj+G.totlamp+G.totmove+G.totpoly; maxob= ((maxob & 0xF00)<<12) + ((maxob & 0xF0)<<8) + ((maxob & 0xF)<<4); aantal= (size-1)/2; rc= 0; dirvec[0][0]= 1; dirvec[0][1]= 0; dirvec[1][0]= 0; dirvec[1][1]= -size; dirvec[2][0]= -1; dirvec[2][1]= 0; dirvec[3][0]= 0; dirvec[3][1]= size; bufmin= buf; bufmax= buf+ size*size; buf+= aantal*size+ aantal; for(tel=1;tel<=size;tel++) { for(a=0;a<2;a++) { for(b=0;b=bufmax) return retval; } rc++; rc &= 3; } } return retval; } #define SELECTSIZE 51 void muisselect() { void grabber(); struct MoData *mo; struct Base *base, *b=0, *startbase=0,*oldbase; float *p,mat[4][4],omat[3][3]; ulong rect[SELECTSIZE*SELECTSIZE],*dr,kleur=0; Device mdev[2]; short hits, buffer[2000], dist=100, mval[2], temp,a,sco[2],x,y; winset(G.winar[0]); if(G.ebase) { if(G.ebase->soort==1) muis_ebase(); else if ELEM3(G.ebase->soort, 5, 11, -2) muis_Nurb(); else if(G.ebase->soort== -4) muis_ika(); return; } mdev[0] = MOUSEX; mdev[1] = MOUSEY; getdev(2, mdev, mval); mval[1]-= S.vys; if( (G.qual & 32) ) { /* iedere keer baselijst starten vanuit basact */ if(G.basact) startbase=G.basact->next; if(startbase==0) startbase=G.firstbase; base=startbase; while(base) { if(base->lay & view0.lay) { temp=abs(base->sx -mval[0]) + abs(base->sy -mval[1]); if(base==G.basact) temp+=10; if(tempnext; if(base==0) base=G.firstbase; if(base==startbase) break; } } else if(G.machine==ENTRY) { hits= selectprojektie(buffer, 0, 0, 0, 0); if(hits>0) { if(G.basact) startbase=G.basact->next; if(startbase==0) startbase=G.firstbase; base=startbase; while(base) { if(base->lay & view0.lay) { for(a=0; aselcol==buffer[2*a+1]) b= base; } } if(b) break; base= base->next; if(base==0) base=G.firstbase; if(base==startbase) break; } } } else { /* met rectread testen */ if(!backbufok) { backbufprojektie(0); } countall(); a= SELECTSIZE*SELECTSIZE; dr= rect; while(a--) *(dr++)= 0; a= (SELECTSIZE-1)/2; lrectread(mval[0]-a,mval[1]-a,mval[0]+a,mval[1]+a,rect); dr= rect; for(y= mval[1]-a; y<=mval[1]+a; y++) { for(x=mval[0]-a; x<=mval[0]+a; x++) { if(x<0 || y<0) *dr= 0; else if(x>=S.x || y>=S.vyw) *dr= 0; else *dr&= 0xF0F0F0; dr++; } } if(G.basact && TESTBASE(G.basact) ) { /* niet 2 x de zelfde */ kleur= samplerect(rect, SELECTSIZE, G.basact->selcol); } else { kleur= samplerect(rect, SELECTSIZE, 0); } if(kleur==0) return; else { b= G.firstbase; while(b) { if(b->lay & view0.lay) { if(b->selcol==kleur) break; } b= b->next; } } } if(b) { oldbase= G.basact; /* even onthouden, oa voor mainb==9 */ G.basact= b; if((G.qual & 3)==0) { deselectall_ex(b); b->f |= 1; } else { if(b->f & 1) b->f--; else b->f++; } if(G.mainb==7) if(oldbase) oldbase->lastipo= G.ipomode; if(oldbase!=G.basact) { tekenbase_ext(b); if(G.mainb==4) if(b->soort==2) { tekenlampbuts(1); } if(G.mainb==5) if(b->soort & 1) { tekenobjbuts(1); } if(G.mainb==7) { a= 1; if(oldbase) { if(oldbase->soort== -2 && G.basact->soort!= -2) a= 0; if(oldbase->soort!= -2 && G.basact->soort== -2) a= 0; } G.ipomode= G.basact->lastipo; if(G.basact->soort!= -2 && G.ipomode<20) G.ipomode= 20; /* patch */ tekenmovebuts(a); } if(G.mainb==9) { a= 0; /* wel complete redraw */ if(oldbase) if(oldbase->soort==b->soort) a=1; tekeneditbuts(a); } } else { tekenbase_ext(b); } } countall(); tekenoverdraw(0); getmouseco(mval); x= mval[0]; y= mval[1]; while(getbutton(RIGHTMOUSE)) { gsync(); getmouseco(mval); if(abs(mval[0]-x)+abs(mval[1]-y) > 14) { grabber(); while(getbutton(RIGHTMOUSE)) gsync(); } } } void minmaxbase(base, min, max) struct Base *base; float *min, *max; { struct ObData *ob; struct VV *vv; struct VertOb *adrve; struct CurveData *cu; struct Nurb *nu; struct BezTriple *bezt; struct BPoint *bp; struct MoData *mo; struct IkaData *ika; struct BodyPoint *bop; struct PolyData *po; float *fp, mat[4][4], omat[3][3], vec[3]; long a, b, tot; short *p; if(base->soort & 1) { ob= (struct ObData *)base->d; } VECCOPY(vec, base->r); MinMax3(min, max, vec); parentbase(base, mat, omat); if(base->soort==1) { vv= ob->vv; Mat4MulFloat3(mat, vv->ws); tot= vv->vert; adrve= (struct VertOb *)(vv+1); while(tot--) { VECCOPY(vec, adrve->c); Mat4MulVecfl(mat, vec); MinMax3(min, max, vec); adrve++; } } else if ELEM3(base->soort, 5, 11, -2) { if(base->soort== -2) { mo= (struct MoData *)base->d; nu= mo->curve.first; } else { cu= ob->cu; Mat4MulFloat3(mat, cu->ws); nu= cu->curve.first; } while(nu) { if((nu->type & 7)==1) { bezt= nu->bezt; tot= nu->pntsu; while(tot--) { VECCOPY(vec, bezt->vec[0]); Mat4MulVecfl(mat, vec); MinMax3(min, max, vec); VECCOPY(vec, bezt->vec[1]); Mat4MulVecfl(mat, vec); MinMax3(min, max, vec); VECCOPY(vec, bezt->vec[2]); Mat4MulVecfl(mat, vec); MinMax3(min, max, vec); bezt++; } } else { bp= nu->bp; tot= nu->pntsu*nu->pntsv; while(tot--) { VECCOPY(vec, bp->vec); Mat4MulVecfl(mat, vec); MinMax3(min, max, vec); bp++; } } nu= nu->next; } } else if(base->soort==9) { po= ob->po; Mat4MulFloat3(mat, po->ws); p=(short *)(po+1); for(a=0;apoly;a++) { tot= *p; p++; for(b=0; bsoort== -4) { ika= (struct IkaData *)(base->d); bop= ika->bpbase.first; while(bop) { VECCOPY(vec, bop->r); Mat4MulVecfl(mat, vec); MinMax3(min, max, vec); bop= bop->next; } } } void maakbol() { struct ObData *ob; struct VV *vv; struct VertOb *adrve; float x1,y1,r,r1,fac; long a,tot; if(G.basact==0 || okee("Maak bol")==0) return; if(G.basact->soort!=1) return; ob=(struct ObData *)G.basact->d; vv= ob->vv; tot= vv->vert; adrve= (struct VertOb *)(vv+1); fac= 1.0/32767.0; for(a=0;ac[0]; y1= fac*adrve->c[2]; r= x1*x1+y1*y1; r1= fsqrt( fabs(1-r)); if(r<1.0) adrve->c[1]= -32767*r1; else adrve->c[1]=0; adrve++; } } void wordruimtekleiner() { struct ObData *ob; struct VV *vv; struct VertOb *adrve; float x1,y1,r,r1,fac; long a,tot; if(G.basact==0 || okee("wordruimte .05 kleiner")==0) return; if(G.basact->soort!=1) return; ob=(struct ObData *)G.basact->d; vv= ob->vv; tot= vv->vert; adrve= (struct VertOb *)(vv+1); fac= .95; vv->ws= vv->ws/fac; for(a=0;ac[0]*=fac; adrve->c[1]*=fac; adrve->c[2]*=fac; adrve++; } } void makeparent() { struct Base *base, *b; struct Key *key; float imat[3][3], mat[4][4], oldmat[4][4], omat[3][3]; long vec[3], *l0; short a=0, vert[2], vert1[2], transf= 1, rodnr= 0, button(), mode, skelnr= 0; if(G.ebase) return; if(G.basact==0) return; G.moving=1; tekenbase_ext(G.basact); G.moving=0; vert1[0]=G.basact->sx; vert1[1]=G.basact->sy; base=G.firstbase; setlinestyle(1); cpack(0); frontbuffer(1); backbuffer(0); while(base) { if(base->lay & view0.lay) { if(base->f & 1) { if(base!=G.basact) { a=1; bgnline(); v3i(G.basact->r); v3i(base->r); endline(); } } } base=base->next; } setlinestyle(0); frontbuffer(0); backbuffer(1); if(a==0) { tekenbase_ext(G.basact); return; } if(G.basact->soort== -4) { if(G.qual & 3) { if((mode= pupmenu("Make Parent without transform %t|Use Rod %x1|Use Skeleton %x2"))== -1) return; transf= 0; } else if((mode= pupmenu("Make Parent %t|Use Rod %x1|Use Skeleton %x2"))== -1) return; a= 1; if(mode==1) tekenrodnummers(G.basact); else tekenskelnummers(G.basact); } else { if(G.qual & 3) { a= okee("Make Parent without transform"); transf= 0; } else a= okee("Make Parent"); } if(a) { if(G.basact->soort== -4) { if(mode==1) { if(button(&rodnr, 0, 99, "Rod: ")==0) a= 0; } else { if(button(&skelnr, 0, 99, "Skeleton: ")==0) a= 0; } } } if(a) { base=G.firstbase; while(base) { if(base->lay & view0.lay) { if(base->f & 1) { if(base!=G.basact) { parentbase(base, oldmat, omat); base->p= G.basact; if(G.basact->soort== -4) { base->rodnr= rodnr; base->skelnr= skelnr; } else { base->rodnr= G.basact->rodnr; /* ivm *childbase in parentbase() */ base->skelnr= 0; } b=base; while(b) { b=b->p; if(b==base) break; } if(b==base) { base->p=0; error("Loop in parents"); base->skelnr= base->rodnr= 0; } else { if(transf) { base->o[0]=base->o[1]=base->o[2]=0; base->q[1]=base->q[2]=base->q[3]= 0.0; base->q[0]= 1.0; Mat3One(base->m); parentbase(base, mat, omat); Mat3Inv(imat, omat); vec[0]= base->r[0]-base->v[0]; vec[1]= base->r[1]-base->v[1]; vec[2]= base->r[2]-base->v[2]; Mat3MulVec(imat, vec); base->o[0]= -vec[0]; base->o[1]= -vec[1]; base->o[2]= -vec[2]; /* nieuwe matrix: oudemat x inverse nieuwe */ Mat3CpyMat4(omat, mat); Mat3Inv(imat, omat); Mat3CpyMat4(omat, oldmat); Mat3MulMat3(base->m, imat, omat); base->f &= ~8; } if(base->skelnr) calc_deform(base); if(base->key!=0 && okee("Change origin in keys")) { key= base->key; while(key) { l0=(long *)(key+1); l0[3]= l0[4]= l0[5]= 0; key= key->next; } loadkeypos(base, base); /* staat verkeerd */ parentbase(base, mat, omat); Mat3Inv(imat, omat); key= base->key; while(key) { l0=(long *)(key+1); vec[0]= base->r[0]-l0[0]; vec[1]= base->r[1]-l0[1]; vec[2]= base->r[2]-l0[2]; Mat3MulVec(imat, vec); l0[3]= -vec[0]; l0[4]= -vec[1]; l0[5]= -vec[2]; key=key->next; } loadkeypos(base, base); /* staat-ie weer goed */ } } } } } base=base->next; } } projektie(); } void maketrack() { struct Base *base, *b; short a=0,vert[2],vert1[2]; if(G.basact==0) return; if(G.basact->sx==3200) return; G.moving=1; tekenbase_ext(G.basact); G.moving=0; if(okee("Track to")) { base=G.firstbase; while(base) { if(base->lay & view0.lay) { if(base->f & 1) { if(base!=G.basact) { base->q[0]= 1.0; base->q[1]= base->q[2]= base->q[3]= 0.0; base->t= G.basact; } } } base=base->next; } } projektie(); } void join() { struct Base *base, *first, *next, *lbase, *par; struct ObData *ob, *obn; struct VV *vv, *vvn; struct ColBlck *col, *testcol[16]; struct VlakOb *adrvl, *adrvl1; struct VertOb *adrve, *adrve1; float fac, min[3], max[3], *vertdata, *vd, bmat[4][4], omat[3][3], cent[3]; long len, ok, a, b, vertofs, soort= 0, totvlak, totvert, totcol, setnewcol; char newcol[16]; if(G.ebase) return; if(okee("Join selected bases")==0) return; ok= 1; base= G.firstbase; while(base) { if(TESTBASE(base)) { if(base->soort>0 && (base->soort & 1)) { if(soort==0) soort= base->soort; else if(soort!=base->soort) { soort= 0; ok= 0; break; } } } base= base->next; } if(soort==0) { if(ok==0) error("Can't join mixed base types"); return; } if(soort==1) { totvlak= totvert= totcol= 0; first= 0; ok= 0; base= G.firstbase; while(base) { if(TESTBASE(base)) { if(base->soort==1) { if(first==0) { first= base; par= base->p; } else { ok= 1; if(base->p != par) par= 0; } ob= (struct ObData *)base->d; if(ob->vv->key) { ok= 0; error("Can't join with vertexkeys"); break; } totvert+= ob->vv->vert; totvlak+= ob->vv->vlak; if(totcol) { setnewcol= 0; col= (struct ColBlck *)(ob+1); for(a=0; ac; a++) { /* mapping maken */ newcol[a]= 16; for(b=0; bvv->us>1) { ob->vv->us--; len= sizeof(struct VV)+ob->vv->vert*sizeof(struct VertOb)+ ob->vv->vlak*sizeof(struct VlakOb); vvn= mallocN(len, "join4"); memcpy(vvn, ob->vv, len); vvn->us= 1; ob->vv= vvn; } adrve= (struct VertOb *)(ob->vv+1); adrvl= (struct VlakOb *)(adrve+ob->vv->vert); for(a=0; avv->vlak; a++) { b= (adrvl->ec & ~15); adrvl->ec= b+ newcol[adrvl->ec & 15]; adrvl++; } } } else { col= (struct ColBlck *)(ob+1); for(a=0; ac; a++) { testcol[a]= col; col++; } totcol= ob->c; } } } base= base->next; } if(ok==0) return; /* maar 1 base */ ob= (struct ObData *)first->d; if(totcol!= ob->c) { obn= mallocN(sizeof(struct ObData)+totcol*sizeof(struct ColBlck), "join3"); memcpy(obn, ob, sizeof(struct ObData)); obn->c= totcol; col= (struct ColBlck *)(obn+1); for(a=0; ad= (long *)obn; ob= obn; } freelistN(&ob->disp); vvn= mallocN(sizeof(struct VV)+totvert*sizeof(struct VertOb)+totvlak*sizeof(struct VlakOb), "join"); memcpy(vvn, ob->vv, sizeof(struct VV)); vvn->vert= totvert; vvn->vlak= totvlak; vvn->us= 1; min[0]= min[1]= min[2]= 1.0e10; max[0]= max[1]= max[2]= -1.0e10; vd=vertdata= mallocN(totvert*12, "join2"); vertofs= 0; adrve= (struct VertOb *)(vvn+1); adrvl= (struct VlakOb *)(adrve+vvn->vert); base= G.firstbase; lbase= 0; while(base) { next= base->next; if(TESTBASE(base)) { parentbase(base, bmat, omat); ob= (struct ObData *)base->d; vv= ob->vv; Mat4MulFloat3(bmat,vv->ws); adrve1= (struct VertOb *)(vv+1); for(a=0; avert; a++) { VECCOPY(vd, adrve1->c); Mat4MulVecfl(bmat, vd); for(b=0; b<3; b++) { min[b]= MIN2(min[b], vd[b]); max[b]= MAX2(max[b], vd[b]); } adrve1++; vd+=3; } adrvl1= (struct VlakOb *)(adrve1); for(a=0; avlak; a++) { adrvl->v1= adrvl1->v1+ vertofs; adrvl->v2= adrvl1->v2+ vertofs; adrvl->v3= adrvl1->v3+ vertofs; memcpy(adrvl->n, adrvl1->n, 10); adrvl++; adrvl1++; } vertofs+= vv->vert; if(base!=first) delbase(base, lbase); else lbase= base; } else lbase= base; base= next; } ob= (struct ObData *)first->d; if(ob->vv->us==1) { if(ob->vv->key) freekeys(ob->vv->key); freeN(ob->vv); } else ob->vv->us--; ob->vv= vvn; cent[0]= (max[0]+ min[0])/2; cent[1]= (max[1]+ min[1])/2; cent[2]= (max[2]+ min[2])/2; max[0]= (max[0]-min[0])/2; max[1]= (max[1]-min[1])/2; max[2]= (max[2]-min[2])/2; fac= 1.0+MAX3(max[0], max[1], max[2]); fac= 32767.0/fac; vvn->ws= 1.0/fac; Mat3One(first->m); first->q[0]= 1.0; first->q[1]= first->q[2]= first->q[3]= 0.0; first->o[0]= first->o[1]= first->o[2]= 0; first->f |= 12; VECCOPY(first->v, cent); first->p= par; first->t= 0; if(first->key) freekeys(first->key); if(first->pkey) freekeys(first->pkey); first->key= first->pkey= 0; adrve= (struct VertOb *)(vvn+1); vd= vertdata; for(a=0; ac[0]= fac*(vd[0]-cent[0]); adrve->c[1]= fac*(vd[1]-cent[1]); adrve->c[2]= fac*(vd[2]-cent[2]); adrve++; vd+=3; } freeN(vertdata); G.basact= first; makeDispList(G.basact); /* adrve= (struct VertOb *)(vvn+1); */ /* adrvl= (struct VlakOb *)(adrve+vvn->vert); */ } else if (soort == 11){ struct CurveData * cu1, * cu2; struct Link * link; first = 0; lbase = 0; base= G.firstbase; while(base) { if(TESTBASE(base)) { if(base->soort==11) { if (first == 0) { G.basact= first = base; /* parentbase(base, bmat, omat); */ ob = (struct ObData *)base->d; cu1 = ob->cu; } else { ob = (struct ObData *)base->d; cu2 = ob->cu; while(cu2->curve.first) { link = cu2->curve.first; remlink(&cu2->curve, link); addtail(&cu1->curve, link); } base = lbase; delbase(base->next, lbase); } } } lbase = base; base= base->next; } makeBevelList(G.basact); makeDispList(G.basact); } tekenmainbuts(2); projektie(); } void movetolayer() { struct Base *base; short button(),lay, shade= 0; lay=G.layact; if(button(&lay,0,12,"MoveToLayer: ")) { if(lay==0) lay= -1; else lay= 1<<(lay-1); base=G.firstbase; while(base) { if(base->f & 1) { if(base->lay & view0.lay) { base->lay =lay; if(base->soort==2) shade= 1; } } base=base->next; } countall(); testDispLists(); if(shade) reshadeall(); projektie(); } } #define MAXLASSO 1024 int testlasso_pixel(xs, ys) int xs, ys; { ulong pix; if(xs>= 0 && xs0 && ys5 || abs(mousey-mcords[i-1][1])>5 ) { mcords[i][0] = mousex; mcords[i][1] = mousey; v2s(mcords[i]); i++; } } break; case MOUSEX: mousex = val - ofsx; break; case LEFTMOUSE: if(val==0) ok= 0; else start= 1; break; case RIGHTMOUSE: if(val==0) ok= 0; else start= 1; break; case ESCKEY: ok= 0; break; } if (i == MAXLASSO) { if(getbutton(RIGHTMOUSE)) event= RIGHTMOUSE; else event= LEFTMOUSE; break; } } endline(); color(0); clear(); drawmode(NORMALDRAW); if(i>2 && ok==0 && (event==LEFTMOUSE || event==RIGHTMOUSE)) { cpack(0); clear(); cpack(0xF0F0F0); backbufok= 0; /* poly tekenen in backbuf, incr zetten */ if(G.zbuf) zbuffer(0); incr= 1; if(i>256) incr= 2; if(i>512) incr= 3; if(i>768) incr= 4; concave(TRUE); bgnpolygon(); for(val=0; valh==0) { if( testlasso_pixel(eve->xs, eve->ys)) { if(sel) eve->f|= 1; else eve->f&= 254; } } eve= eve->next; } tekenvertices_ext(); countall(); tekenoverdraw(0); } else if ELEM3(G.ebase->soort, 5, 11, -2) { nu= editNurb.first; while(nu) { if((nu->type & 7)==1) { bezt= nu->bezt; a= nu->pntsu; while(a--) { if(bezt->hide==0) { if( testlasso_pixel(bezt->s[0][0], bezt->s[0][1])) { if(sel) bezt->f1|= 1; else bezt->f1 &= ~1; } if( testlasso_pixel(bezt->s[1][0], bezt->s[1][1])) { if(sel) bezt->f2|= 1; else bezt->f2 &= ~1; } if( testlasso_pixel(bezt->s[2][0], bezt->s[2][1])) { if(sel) bezt->f3|= 1; else bezt->f3 &= ~1; } } bezt++; } } else { bp= nu->bp; a= nu->pntsu*nu->pntsv; while(a--) { if(bp->hide==0) { if( testlasso_pixel(bp->s[0], bp->s[1])) { if(sel) bp->f1|= 1; else bp->f1 &= ~1; } } bp++; } } nu= nu->next; } countall(); projektie(); /* geen tekenvertices: edges ook */ } else if(G.ebase->soort== -4) { bop= bpbase.first; while(bop) { if( testlasso_pixel(bop->sx, bop->sy) ) { if(sel) bop->f |= 1; else bop->f &= ~1; } bop= bop->next; } projektie(); } } else { /* bases alleen met centrum */ base= G.firstbase; while(base) { if(base->lay & view0.lay) { if( testlasso_pixel(base->sx, base->sy)) { if(sel) base->f|= 1; else base->f&= 254; } } base= base->next; } countall(); projektie(); } } else persp(1); unqdevice(MOUSEY); unqdevice(MOUSEX); } void selector(mode) short mode; { extern float obsviewXfac,obsviewYfac; struct Base *base; struct EditVert *eve; struct Nurb *nu; struct BezTriple *bezt; struct BPoint *bp; struct BodyPoint *bop; float fac, xx2, yy2; long a, x2, y2; Device mdev[2]; short event, mval[2],xo,yo,x1,y1,xs,ys,sel=0,dum; char string[100]; if(mode && view0.persp!=2) return; winset(G.winar[0]); mdev[0]=MOUSEX; mdev[1]=MOUSEY; persp(0); drawmode(OVERDRAW); color(0); clear(); color(3-mode); getdev(2,mdev,mval); xo=mval[0]; yo=mval[1]-S.vys; sboxs(0, yo, S.x, yo); sboxs(xo, 0, xo, S.y); while( TRUE ) { getdev(2,mdev,mval); mval[1]-= S.vys; if(mval[0]!=xo || mval[1]!=yo) { color(0); sboxs(0,yo,S.x,yo); sboxs(xo,0,xo,S.y); xo= mval[0]; yo= mval[1]; color(3-mode); sboxs(0,yo,S.x,yo); sboxs(xo,0,xo,S.y); } if (qtest()) { event= traces_qread(&dum); if(event==LEFTMOUSE || event==RIGHTMOUSE) { if(dum) break; } else if (event == ESCKEY) { color(0); clear(); drawmode(NORMALDRAW); persp(1); return; } else if(mode==0 && event==BKEY && dum==1) { selectlasso(); return; } } sginap(2); } color(0); sboxs(0,yo,S.x,yo); sboxs(xo,0,xo,S.y); x1=xo; y1=yo; while( TRUE ) { getdev(2,mdev,mval); mval[1]-= S.vys; if(mval[0]!=xo || mval[1]!=yo) { color(0); sboxs(x1,y1,xo,yo); rectfi(0,0,400,50); xo=mval[0]; yo=mval[1]; color(3-mode); sboxs(x1,y1,xo,yo); x2= abs(x1-xo); y2= abs(y1-yo); if(view0.persp==0) { xx2= x2*50*view0.dproj; yy2= y2*50*view0.dproj; sprintf(string,"x:%d y:%d d:%d ",(long)xx2,(long)yy2,(long)fsqrt(xx2*xx2+yy2*yy2)); } else { if(view0.persp>=2) { x2/= obsviewXfac; y2/= obsviewYfac; } sprintf(string,"x:%d y:%d d:%.2f ",x2,y2,fsqrt(x2*x2+y2*y2)); } cmov2i(10,10); charstr(string); } if (qtest()){ event== traces_qread(&dum); if ( event== ESCKEY ) { color(0); clear(); drawmode(NORMALDRAW); persp(1); return; } else if(event==LEFTMOUSE || event==RIGHTMOUSE) break; } sginap(2); } if(event==LEFTMOUSE) sel=1; color(0); clear(); drawmode(NORMALDRAW); persp(1); if(x1h==0 && eve->xs>xo && eve->xsys>yo && eve->ysf|= 1; else eve->f&= 254; } } eve= eve->next; } tekenvertices_ext(); } else if ELEM3(G.ebase->soort, 5, 11, -2) { nu= editNurb.first; while(nu) { if((nu->type & 7)==1) { bezt= nu->bezt; a= nu->pntsu; while(a--) { if(bezt->hide==0) { if(bezt->s[0][0]>xo && bezt->s[0][0]s[0][1]>yo && bezt->s[0][1]f1|= 1; else bezt->f1 &= ~1; } } if(bezt->s[1][0]>xo && bezt->s[1][0]s[1][1]>yo && bezt->s[1][1]f2|= 1; else bezt->f2 &= ~1; } } if(bezt->s[2][0]>xo && bezt->s[2][0]s[2][1]>yo && bezt->s[2][1]f3|= 1; else bezt->f3 &= ~1; } } } bezt++; } } else { bp= nu->bp; a= nu->pntsu*nu->pntsv; while(a--) { if(bp->hide==0) { if(bp->s[0]>xo && bp->s[0]s[1]>yo && bp->s[1]f1|= 1; else bp->f1 &= ~1; } } } bp++; } } nu= nu->next; } projektie(); } else if(G.ebase->soort== -4) { bop= bpbase.first; while(bop) { if(bop->sx>xo && bop->sxsy>yo && bop->syf |= 1; else bop->f &= ~1; } } bop= bop->next; } vars_for_buttons(); /* editika.c */ projektie(); } } else { short hits, buffer[2000]; base=G.firstbase; hits= selectprojektie(buffer, xo, yo, x1, y1); while(base) { if(base->lay & view0.lay) { for(a=0; aselcol== buffer[2*a+1]) { if(sel) base->f|= 1; else base->f&= 254; tekenbase_ext(base); break; } } } base=base->next; } if(G.machine!=ENTRY) { /* i.v.m. backbufprojektie */ base= G.firstbase; while(base) { if(base->lay & view0.lay) { base->selcol= ((base->selcol & 0xF00)<<12) + ((base->selcol & 0xF0)<<8) + ((base->selcol & 0xF)<<4); } base= base->next; } } } while( getbutton(LEFTMOUSE) || getbutton(RIGHTMOUSE) ); while(qtest()) { if(traces_qread(&sel)==INPUTCHANGE) { if(sel) G.winakt=sel; } } if(mode==0) countall(); if(mode && view0.persp==2) projektie(); else tekenoverdraw(0); } void recalcnormals() { struct Base *base; struct ObData *ob; struct VV *vv; struct VertOb *adrve,*adrve1, *adrve2, *adrve3; struct VlakOb *adrvl; int len; short a,col=1; if( okee("Recalc normals")==0 ) { if( okee("Vertices->normals")==0 ) return; if( button(&col,1,15,"colblnr:")==0) return; col--; base=G.basact; if(base) { if(base->soort==1) { ob=(struct ObData *)base->d; vv=ob->vv; adrve=(struct VertOb *)(vv+1); adrvl=(struct VlakOb *)(adrve+vv->vert); for(a=0;avlak;a++,adrvl++) { if( (adrvl->ec & 15)==col) { adrve1= adrve+adrvl->v1; VECCOPY(adrve1->n,adrve1->c); adrve2= adrve+adrvl->v2; VECCOPY(adrve2->n,adrve2->c); adrve3= adrve+adrvl->v3; VECCOPY(adrve3->n,adrve3->c); adrvl->f=0; len=adrvl->n[0]*adrve1->n[0]+adrvl->n[1]*adrve1->n[1]+adrvl->n[2]*adrve1->n[2]; if(len<0) adrvl->f=1; len=adrvl->n[0]*adrve2->n[0]+adrvl->n[1]*adrve2->n[1]+adrvl->n[2]*adrve2->n[2]; if(len<0) adrvl->f+=2; len=adrvl->n[0]*adrve3->n[0]+adrvl->n[1]*adrve3->n[1]+adrvl->n[2]*adrve3->n[2]; if(len<0) adrvl->f+=4; } } } } return; } if(G.ebase) { righthandfaces(); /* zet normalen rechtsdraaiend */ projektie(); return; } base=G.firstbase; while(base) { if(TESTBASE(base)) { if(base->soort==1) { ob=(struct ObData *)base->d; vv=ob->vv; adrve=(struct VertOb *)(vv+1); adrvl=(struct VlakOb *)(adrve+vv->vert); normalen(adrve,adrvl,vv->vert,vv->vlak); } } base=base->next; } } void docentre(base, mode) struct Base *base; int mode; /* 0= origin zelfde, 1: vertices blijven op zelfde plek */ { struct Base *par; struct ObData *ob; struct VV *vv; struct VertOb *adrve; struct VlakOb *adrvl; struct MoData *mo; struct BezTriple *bezt; struct BPoint *bp; struct Nurb *nu, *nu1; struct EditVert *eve; float *fp, fac, cent[3], min[3], max[3], mat[4][4], omat[3][3]; float wspace; int c,a; min[0]=min[1]=min[2]= 1.0e10; max[0]=max[1]=max[2]= -1.0e10; if(G.ebase && mode) { error("Not in editbase mode"); return; } if(G.ebase==base && base->soort==1) { eve= (struct EditVert *)G.edve.first; while(eve) { for(c=0;c<3;c++) { if(eve->co[c]>max[c]) max[c]= eve->co[c]; if(eve->co[c]co[c]; } eve= eve->next; } cent[0]= (min[0]+max[0])/2.0; cent[1]= (min[1]+max[1])/2.0; cent[2]= (min[2]+max[2])/2.0; eve= (struct EditVert *)G.edve.first; while(eve) { for(c=0;c<3;c++) { eve->co[c]-= cent[c]; } eve= eve->next; } } else if(base->soort==1) { ob=(struct ObData *)base->d; vv=ob->vv; adrve=(struct VertOb *)(vv+1); adrvl=(struct VlakOb *)(adrve+vv->vert); for(a=0;avert;a++,adrve++) { for(c=0;c<3;c++) { min[c]= MIN2(min[c],adrve->c[c]); max[c]= MAX2(max[c],adrve->c[c]); } } fac= 0.5*MAX3(max[0]-min[0],max[1]-min[1],max[2]-min[2]); cent[0]= (min[0]+max[0])/2.0; cent[1]= (min[1]+max[1])/2.0; cent[2]= (min[2]+max[2])/2.0; max[0]= (max[0]-min[0]+1)/2.0; max[1]= (max[1]-min[1]+1)/2.0; max[2]= (max[2]-min[2]+1)/2.0; if(fac<.001) fac= 1.0; else { fac/= 32767.0; vv->ws*= fac; } vv->afm[0]= vv->ws*max[0]; vv->afm[1]= vv->ws*max[1]; vv->afm[2]= vv->ws*max[2]; adrve=(struct VertOb *)(vv+1); for(a=0;avert;a++,adrve++) { for(c=0;c<3;c++) adrve->c[c]= (adrve->c[c]-cent[c])/fac; } if(mode) { VecMulf(cent, vv->ws/fac); parentbase(base, mat, omat); Mat3CpyMat4(omat, mat); Mat3MulVecfl(omat, cent); base->v[0]+= cent[0]; base->v[1]+= cent[1]; base->v[2]+= cent[2]; } /* displisten van alle users, ook deze base */ base= G.firstbase; while(base) { if(base->soort==1 && base->lay & view0.lay) { ob= (struct ObData *)base->d; if(ob->vv == vv) makeDispList(base); } base= base->next; } } else if ELEM3(base->soort, 5, 11, -2) { fp= 0; if(base==G.ebase) { nu1= editNurb.first; } else if(base->soort== -2) { mo= (struct MoData *)base->d; nu1= mo->curve.first; } else { ob=(struct ObData *)base->d; nu1= ob->cu->curve.first; fp= &(ob->cu->ws); } if(nu1==0) return; nu= nu1; while(nu) { minmaxNurb(nu, min, max); nu= nu->next; } fac= 0.5*MAX3(max[0]-min[0],max[1]-min[1],max[2]-min[2]); cent[0]= (min[0]+max[0])/2.0; cent[1]= (min[1]+max[1])/2.0; cent[2]= (min[2]+max[2])/2.0; if(base->soort==5) wspace= 32767.0; else wspace= 16384.0; if(fp==0) { fac= 1.0; } else { if(fac<.001) fac= 1.0; fac/= wspace; (*fp) *= fac; fac= 1.0/fac; } nu= nu1; while(nu) { if( (nu->type & 7)==1) { a= nu->pntsu; bezt= nu->bezt; while(a--) { VecSubf(bezt->vec[0], bezt->vec[0], cent); VecMulf(bezt->vec[0], fac); VecSubf(bezt->vec[1], bezt->vec[1], cent); VecMulf(bezt->vec[1], fac); VecSubf(bezt->vec[2], bezt->vec[2], cent); VecMulf(bezt->vec[2], fac); bezt++; } } else { a= nu->pntsu*nu->pntsv; bp= nu->bp; while(a--) { VecSubf(bp->vec, bp->vec, cent); VecMulf(bp->vec, fac); bp++; } } nu= nu->next; } fac= 1.0/fac; if(mode && fp) { VecMulf(cent, (*fp)/fac); parentbase(base, mat, omat); Mat3CpyMat4(omat, mat); Mat3MulVecfl(omat, cent); base->v[0]+= cent[0]; base->v[1]+= cent[1]; base->v[2]+= cent[2]; } if(G.ebase== 0 && base->soort==11) makeBevelList(base); makeDispList(base); } projektie(); } void fitinWspace() { struct Base *base; struct ObData *ob; struct CurveData *cu; struct Nurb *nu; struct BezTriple *bezt; struct BPoint *bp; struct VV *vv; struct VertOb *adrve; struct VlakOb *adrvl; float *f,facx, facy, facz, cent[3],min[3],max[3], tmat[3][3], mat[3][3]; float wspace; int c, a, ret=0; if(okee("Fit in Wspace")==0) return; base= G.firstbase; while(base) { if(TESTBASE(base) ) { if(base->soort==1) { ob=(struct ObData *)base->d; vv=ob->vv; if(vv->us>1) { error("Can't fit in a duplicate"); ret= 1; } if(vv->key) { error("Can't fit in a key"); ret= 1; } if(ret) return; min[0]=min[1]=min[2]= 1.0e10; max[0]=max[1]=max[2]= -1.0e10; adrve=(struct VertOb *)(vv+1); adrvl=(struct VlakOb *)(adrve+vv->vert); for(a=0;avert;a++,adrve++) { for(c=0;c<3;c++) { min[c]= MIN2(min[c],adrve->c[c]); max[c]= MAX2(max[c],adrve->c[c]); } } facx= 0.5*(max[0]-min[0]); if(facx<=1.0) facx= 32767.0; facy= 0.5*(max[1]-min[1]); if(facy<=1.0) facy= 32767.0; facz= 0.5*(max[2]-min[2]); if(facz<=1.0) facz= 32767.0; cent[0]= (min[0]+max[0])/2.0; cent[1]= (min[1]+max[1])/2.0; cent[2]= (min[2]+max[2])/2.0; max[0]= (max[0]-min[0]+1)/2.0; max[1]= (max[1]-min[1]+1)/2.0; max[2]= (max[2]-min[2]+1)/2.0; facx/= 32767.0; facy/= 32767.0; facz/= 32767.0; Mat3One(mat); mat[0][0]= facx; mat[1][1]= facy; mat[2][2]= facz; Mat3CpyMat3(tmat, base->m); Mat3MulMat3(base->m, mat, tmat); base->f &= ~8; adrve=(struct VertOb *)(vv+1); for(a=0;avert;a++,adrve++) { adrve->c[0]= (adrve->c[0]-cent[0])/facx; adrve->c[1]= (adrve->c[1]-cent[1])/facy; adrve->c[2]= (adrve->c[2]-cent[2])/facz; } } else if(base->soort==5) { ob= (struct ObData *)base->d; cu= ob->cu; if(cu->key) { error("Can't fit in a key"); ret= 1; } if(ret) return; min[0]=min[1]=min[2]= 1.0e10; max[0]=max[1]=max[2]= -1.0e10; nu= cu->curve.first; while(nu) { a= nu->pntsu*nu->pntsv; bp= nu->bp; while(a--) { for(c=0;c<3;c++) { min[c]= MIN2(min[c],bp->vec[c]); max[c]= MAX2(max[c],bp->vec[c]); } bp++; } nu= nu->next; } facx= 0.5*(max[0]-min[0]); if(facx<=1.0) facx= 32767.0; facy= 0.5*(max[1]-min[1]); if(facy<=1.0) facy= 32767.0; facz= 0.5*(max[2]-min[2]); if(facz<=1.0) facz= 32767.0; cent[0]= (min[0]+max[0])/2.0; cent[1]= (min[1]+max[1])/2.0; cent[2]= (min[2]+max[2])/2.0; max[0]= (max[0]-min[0]+1)/2.0; max[1]= (max[1]-min[1]+1)/2.0; max[2]= (max[2]-min[2]+1)/2.0; facx/= 32767.0; facy/= 32767.0; facz/= 32767.0; Mat3One(mat); mat[0][0]= facx; mat[1][1]= facy; mat[2][2]= facz; Mat3CpyMat3(tmat, base->m); Mat3MulMat3(base->m, mat, tmat); base->f &= ~8; nu= cu->curve.first; while(nu) { a= nu->pntsu*nu->pntsv; bp= nu->bp; while(a--) { bp->vec[0]= (bp->vec[0]-cent[0])/facx; bp->vec[1]= (bp->vec[1]-cent[1])/facy; bp->vec[2]= (bp->vec[2]-cent[2])/facz; bp++; } nu= nu->next; } makeDispList(base); } else error("Can't fit in"); } base= base->next; } projektie(); } void testWspace(struct Base *base) { struct ObData *ob; struct Nurb *nu; struct BezTriple *bezt; struct BPoint *bp; float fac, min[3], max[3], wspace; int a, b; fac= 1.0; min[0]= min[1]= min[2]= 1.0e20; max[0]= max[1]= max[2]= -1.0e20; if(base->soort==1) { } else if ELEM(base->soort, 5, 11) { if(base->soort==5) wspace= 32767.0; else wspace= 16384.0; ob= (struct ObData *)base->d; if(base==G.ebase) nu= editNurb.first; else nu= ob->cu->curve.first; if(nu) { while(nu) { minmaxNurb(nu, min, max); nu= nu->next; } min[0]= MAX3(fabs(min[0]), fabs(min[1]), fabs(min[2])); max[0]= MAX3(fabs(max[0]), fabs(max[1]), fabs(max[2])); fac= MAX2( min[0], max[0] ); fac= wspace/fac; ob->cu->ws/= fac; } if(base==G.ebase) nu= editNurb.first; else nu= ob->cu->curve.first; while(nu) { if( (nu->type & 7)==1 ) { bezt= nu->bezt; a= nu->pntsu; while(a--) { for(b=0; b<3; b++) { VecMulf(bezt->vec[b], fac); } bezt++; } } else { bp= nu->bp; a= nu->pntsu*nu->pntsv; while(a--) { VecMulf(bp->vec, fac); bp++; } } nu= nu->next; } } } void apply() { struct Base *base,*par; struct ObData *ob; struct VV *vv; struct VertOb *adrve; struct VlakOb *adrvl; struct MoData *mo; struct BezTriple *bezt; struct BPoint *bp; struct Nurb *nu; float *f,fac,vec[3],tmat[4][4],mat[3][3],min[3],max[3]; int c,a; if(okee("Apply mat/quat")==0) return; base= G.firstbase; while(base) { if(TESTBASE(base)) { par= base->p; base->p= 0; parentbase(base,tmat,mat); base->p= par; Mat3CpyMat4(mat,tmat); if ELEM3(base->soort, 5, 11, -2) { if(base->soort== -2) { mo= (struct MoData *)base->d; nu= mo->curve.first; } else { ob= (struct ObData *)base->d; nu= ob->cu->curve.first; } if(nu) { while(nu) { if(nu->bezt) { a= nu->pntsu; bezt= nu->bezt; while(a--) { Mat3MulVecfl(mat, bezt->vec[0]); Mat3MulVecfl(mat, bezt->vec[1]); Mat3MulVecfl(mat, bezt->vec[2]); bezt++; } } else if(nu->bp) { a= nu->pntsu*nu->pntsv; bp= nu->bp; while(a--) { Mat3MulVecfl(mat, bp->vec); bp++; } } nu= nu->next; } Mat3One(base->m); base->q[0]= 1.0; base->q[1]=base->q[2]=base->q[3]= 0.0; makeDispList(base); testWspace(base); } } else if(base->soort==1) { ob=(struct ObData *)base->d; vv=ob->vv; if(vv->us>1) { error("Don't apply a duplicate"); return; } if(vv->key) { error("Don't apply a key"); return; } min[0]=min[1]=min[2]= 1.0e20; max[0]=max[1]=max[2]= -1.0e20; Mat3MulFloat(mat,vv->ws); adrve=(struct VertOb *)(vv+1); adrvl=(struct VlakOb *)(adrve+vv->vert); for(a=0;avert;a++,adrve++) { VECCOPY(vec,adrve->c); Mat3MulVecfl(mat,vec); f= (float *)adrve->c; VECCOPY(f,vec); for(c=0;c<3;c++) { min[c]= MIN2(min[c],vec[c]); max[c]= MAX2(max[c],vec[c]); } } max[0]= MAX2(fabs(min[0]),fabs(max[0])); max[1]= MAX2(fabs(min[1]),fabs(max[1])); max[2]= MAX2(fabs(min[2]),fabs(max[2])); fac= MAX3(max[0],max[1],max[2]); fac= 32767.0/fac; vv->ws= 1.0/fac; VECCOPY(vv->afm,max); adrve=(struct VertOb *)(vv+1); for(a=0;avert;a++,adrve++) { f= (float *)adrve->c; VECCOPY(vec,f); vec[0]*=fac; vec[1]*=fac; vec[2]*=fac; VECCOPY(adrve->c,vec); } Mat3One(base->m); base->q[0]= 1.0; base->q[1]=base->q[2]=base->q[3]= 0.0; adrve=(struct VertOb *)(vv+1); normalen(adrve,adrvl,vv->vert,vv->vlak); } } base= base->next; } projektie(); } void fasterdraw() { struct Base *base; struct ObData *ob; struct VV *vv; struct VertOb *adrve; struct VlakOb *adrvl; long toggle, a, ec; base= G.firstbase; while(base) { if(TESTBASE(base) && (base->soort==1)) { ob= (struct ObData *)base->d; vv= ob->vv; vv->f1 &= ~1; } base= base->next; } base= G.firstbase; while(base) { if(TESTBASE(base) && (base->soort==1)) { ob= (struct ObData *)base->d; vv= ob->vv; if((vv->f1 & 1)==0) { vv->f1 |= 1; adrve= (struct VertOb *)(vv+1); adrvl= (struct VlakOb *)(adrve+vv->vert); toggle= 1; for(a=0; avlak; a++) { if( (adrvl->ec & 32)==0 ) { toggle++; if(toggle & 1) adrvl->ec += 32; } if( (adrvl->ec & 64)==0 ) { toggle++; if(toggle & 1) adrvl->ec += 64; } if( (adrvl->ec & 128)==0 ) { toggle++; if(toggle & 1) adrvl->ec += 128; } adrvl++; } } } base= base->next; } /* belangrijk: vlaggen weer resetten */ base= G.firstbase; while(base) { if(TESTBASE(base) && (base->soort==1)) { ob= (struct ObData *)base->d; vv= ob->vv; vv->f1 &= ~1; } base= base->next; } projektie(); } void clearworkbase() { G.workbase->f= 9; G.workbase->f1= 2+8+16+64; G.workbase->f2= 0; G.workbase->q[0]= 1.0; G.workbase->q[1]= 0.0; G.workbase->q[2]= 0.0; G.workbase->q[3]= 0.0; Mat3One(G.workbase->m); G.workbase->t= 0; G.workbase->p= 0; G.workbase->v[0]= G.workbase->v[1]= G.workbase->v[2]= 0; G.workbase->o[0]= G.workbase->o[1]= G.workbase->o[2]= 0; G.workbase->sf= 1; G.workbase->rodnr= G.workbase->skelnr= 0; } /* *************************************** */ void arrowsmovecursor(event) short event; { Device mdev[2]; short mval[2],a=0; mdev[0]=MOUSEX; mdev[1]=MOUSEY; getdev(2,mdev,mval); if(event==UPARROWKEY) { a=1; mval[1]++; } if(event==DOWNARROWKEY) { a=1; mval[1]--; } if(event==LEFTARROWKEY) { a=1; mval[0]--; } if(event==RIGHTARROWKEY) { a=1; mval[0]++; } if(a) { if(mval[0]<0) mval[0]=0; if(mval[1]<0) mval[1]=0; if(mval[0]>S.x) mval[0]=S.x; if(mval[1]>S.y) mval[1]=S.y; setvaluator(MOUSEX,mval[0],0,S.x-1); setvaluator(MOUSEY,mval[1],0,S.y-1); } } short testproj(xn,yn,mval) short xn,yn,*mval; { float x,y,z; /* welke beweging is het grootst? die wordt het */ xn= (xn-mval[0]); yn= (yn-mval[1]); x = fabs(G.persinv[0][0]*xn + G.persinv[1][0]*yn); y = fabs(G.persinv[0][1]*xn + G.persinv[1][1]*yn); z = fabs(G.persinv[0][2]*xn + G.persinv[1][2]*yn); if(x>=y && x>=z) return 0; else if(y>=x && y>=z) return 1; else return 2; } void initprintoverdraw() { winset(G.winar[1]); drawmode(OVERDRAW); color(1); sboxfs(0,200,1279,220); /* ortho doet dit goed! */ color(3); sboxs(0,200,1279,220); } void clearprintoverdraw() { winset(G.winar[1]); drawmode(OVERDRAW); color(0); sboxfs(0,200,1279,220); drawmode(NORMALDRAW); } void endprintoverdraw() { drawmode(NORMALDRAW); winset(G.winar[0]); } void setbaseflags_for_editing() { /* als hie==1: als base selected en heeft parent selected: base->f=2, base->f2= 32, als base niet selected en parent selected: base->f=2 Verder: test op Duplibase (G.f & 4) */ struct Base *base,*b; struct MoData *mo; struct Key *key; short parsel, dupli=0; if(G.hie) { base= G.firstbase; while(base) { base->f&= ~2; if(base->soort== -2 && base->p==0) { mo= (struct MoData *)base->d; if(mo->f & 4) dupli= 1; } if(base->dupli) dupli= 1; if(base->lay & view0.lay) { parsel= 0; b= base->p; while(b) { if(TESTBASE(b)) { parsel= 1; break; } b= b->p; } if(base->pkey) { key= base->pkey; while(key) { b= (struct Base *) *( (long *)(key+1) ); if(b && b!=base && TESTBASE(b)) { parsel= 1; break; } key= key->next; } } if(parsel) { if(base->f & 1) { base->f2|= 32; base->f|= 2; base->f-= 1; } else base->f|=2; } b= base->t; if(b) if(TESTBASE(b)) if((base->f & 1)==0) base->f|=2; } base= base->next; } } if(dupli) G.f |= 4; else G.f &= ~4; } void clearbaseflags_for_editing() /* doet ook shade */ { struct Base *base; struct ObData *ob; short shadeall= 0; if(G.zbuf) { /* is er een lamp verplaatst? */ base= G.firstbase; while(base) { if(TESTBASE(base)) { if(base->soort==2) { shadeall= 1; break; } } base= base->next; } /* test de bases */ base= G.firstbase; while(base) { if(base->soort & 1) { if(base->lay & view0.lay) { ob= (struct ObData *)base->d; if(shadeall) { if(ob->dt==2) shadeDispList(base); } else if(base->f & 3) { if(ob->dt==2) shadeDispList(base); } } } base= base->next; } } base= G.firstbase; while(base) { if(base->lay & view0.lay) { if(base->f2 & 32) { base->f|= 1; base->f2-= 32; } } base->f&= ~2; base= base->next; } } void addstartframe() { struct Base *base; short addval=0; if(button(&addval, -1000, 1000, "Add Sf: ")==0) return; base= G.firstbase; while(base) { if(TESTBASE(base)) { base->sf+= addval; } base= base->next; } projektie(); } void helpline(vec) long *vec; { short mval[2], mval1[2]; getmouseco(mval); berekenschermco_noclip(vec, mval1); persp(0); frontbuffer(1); cpack(0); setlinestyle(1); bgnline(); v2s(mval); v2s(mval1); endline(); setlinestyle(0); persp(1); frontbuffer(0); } void grabber() { struct Base *base,*b; struct Key *key; float dx,dy,z=0,mat[3][3],cmat[3][3],tmat[4][4]; long *adror,*a,**adrin,*ai,dvec[3],vec[3]; short teller=0,a1, val,mval[2],xn,yn,xm,ym,toets,proj,midtog=0, cambase=0; Device mdev[2]; char s[40]; if(G.firstbase==0) return; if(G.ebase) { vertgrabber(); return; } G.moving=1; setbaseflags_for_editing(); base=G.firstbase; while(base) { /* aantal tellen en alvast tekenen */ if(view0.lay & base->lay) { if(base->f & 1) { if(teller==0) z= initgrabz(base->v[0],base->v[1],base->v[2]); teller++; } if(base->f & 3) { tekenbase_ext(base); } } base= base->next; } if(teller) { /* het opslaan in temp blok */ base=G.firstbase; adror=(long *)callocN(12*teller,"grabber0"); adrin=(long **)callocN(4*teller,"grabber1"); a=adror; teller=0; while(base) { if(view0.lay & base->lay) { if(base->f & 1) { if(G.hie && PARENT(base)) ai= getbasekeyadr(base,1); else ai= getbasekeyadr(base,0); adrin[teller++]=ai; VECCOPY(a,ai); a+=3; } } base=base->next; } mdev[0] = MOUSEX; mdev[1] = MOUSEY; getdev(2, mdev, mval); mval[1]-= S.vys; xn=xm=mval[0]; yn=ym=mval[1]; dvec[0]=dvec[1]=dvec[2]=0; initprintoverdraw(); sprintf(s,"Dx: %d",dvec[0]); cmov2i(10,204); charstr(s); sprintf(s,"Dy: %d",dvec[1]); cmov2i(160,204); charstr(s); sprintf(s,"Dz: %d",dvec[2]); cmov2i(310,204); charstr(s); endprintoverdraw(); if(teller==1 && view0.cambase && view0.persp>=2) { if(TESTBASE(view0.cambase)) { cambase= 1; z= view0.grid; } } while(TRUE) { getdev(2, mdev, mval); mval[1]-= S.vys; if(mval[0]!=xm || mval[1]!=ym) { xm=mval[0]; ym=mval[1]; dx= 2.0*(xn-xm)*z/S.vxw; dy= 2.0*(yn-ym)*z/S.vyw; if(cambase) { dvec[0]+= dy*G.persinv[2][0]; dvec[1]+= dy*G.persinv[2][1]; dvec[2]+= dy*G.persinv[2][2]; xm--; /* blijft ie lopen */ } else { dvec[0] = (G.persinv[0][0]*dx + G.persinv[1][0]*dy); dvec[1] = (G.persinv[0][1]*dx + G.persinv[1][1]*dy); dvec[2] = (G.persinv[0][2]*dx + G.persinv[1][2]*dy); } base=G.firstbase; if(G.move2==1) dvec[1]=dvec[2]=0; if(G.move2==2) dvec[0]=dvec[2]=0; if(G.move2==3) dvec[0]=dvec[1]=0; if(midtog) { if(proj==0) dvec[1]=dvec[2]=0; if(proj==1) dvec[0]=dvec[2]=0; if(proj==2) dvec[0]=dvec[1]=0; } if(G.qual & (48+3) ) { dy= view0.grid; if(G.qual & 3) dy/= 10.0; dx= dvec[0]/dy; dx= ffloor(dx+.5); dvec[0]= dx*dy; dx= dvec[1]/dy; dx= ffloor(dx+.5); dvec[1]= dx*dy; dx= dvec[2]/dy; dx= ffloor(dx+.5); dvec[2]= dx*dy; } a= adror; teller=0; while(base) { if(view0.lay & base->lay) { if(base->f & 1) { ai=adrin[teller++]; if( PARENT(base) && G.hie!=0) { parentbase(base,tmat,mat); Mat3Inv(cmat,mat); VECCOPY(vec,dvec); Mat3MulVec(cmat,vec); ai[0]= *(a++)-vec[0]; ai[1]= *(a++)-vec[1]; ai[2]= *(a++)-vec[2]; } else { ai[0]= *(a++)-dvec[0]; ai[1]= *(a++)-dvec[1]; ai[2]= *(a++)-dvec[2]; } } } base=base->next; } projektie(); initprintoverdraw(); sprintf(s,"Dx: %d",-dvec[0]); cmov2i(10,204); charstr(s); sprintf(s,"Dy: %d",-dvec[1]); cmov2i(160,204); charstr(s); sprintf(s,"Dz: %d",-dvec[2]); cmov2i(310,204); charstr(s); endprintoverdraw(); } else sginap(2); if( qtest() ) { toets= traces_qread(&val); if(val) { if(toets==ESCKEY || toets==LEFTMOUSE || toets==SPACEKEY) break; if(toets==MIDDLEMOUSE) { midtog= ~midtog; if(midtog) proj= testproj(xn,yn,mval); } arrowsmovecursor(toets); } if(toets==INPUTCHANGE) G.winakt= val; toets=0; xm= -10; /* dan doetie projektie */ } } if(toets==ESCKEY) { base=G.firstbase; a=adror; teller=0; while(base) { if(view0.lay & base->lay) { if(base->f & 1) { ai=adrin[teller++]; VECCOPY(ai,a); a+=3; if(base->skelnr) calc_deform(base); } } base=base->next; } } freeN(adror); freeN(adrin); G.moving=0; clearprintoverdraw(); clearbaseflags_for_editing(); projektie(); } G.moving=0; } void roteer() { struct Base *base,*b; struct MoData *mo; struct Key *key; float dx,dy,mat[4][4],omat[3][3],imat[3][3],tmat[3][3],n[3],rotn[3], rotn1[3]; float pmat[3][3], bmat[3][3], qtot[4], qpar[4]; float *adror,*a,hoek=0,hoeko=0,deler,choek,dhoek,si,co; float **adrin,*ai,hoek1=0,hoek2=0; float q1[4],q2[4],q3[4], q5[4]; long *adrve,*v,vec[3],vec1[3]; short teller=0,teller2,a1,val,mval[2],toets,midtog=0,proj; short cambase=0, xc=0,yc=0,xn,yn,dx1,dy1,dx2,dy2, filt; Device mdev[2]; char s[40]; if(G.firstbase==0) return; if(G.ebase) { vertroteer(); return; } G.moving=1; vec[0]=vec[1]=vec[2]=0; q1[0]=q1[1]=q1[2]=0; /* tijdelijk voor rotatie middelpunt */ setbaseflags_for_editing(); base=G.firstbase; while(base) { /* aantal tellen en alvast tekenen en centrum */ if(view0.lay & base->lay) { if(base->f & 1) { q1[0]+= base->r[0]; q1[1]+= base->r[1]; q1[2]+= base->r[2]; teller++; } if(base->f & 3) { tekenbase_ext(base); base->f&= ~4; /* quateenheid flag wissen */ } } base= base->next; } if(teller) { if(G.move2) { n[0]=n[1]=n[2]=0; if(G.move2==1) n[0]=1; if(G.move2==2) n[1]=1; if(G.move2==3) n[2]=1; } else { n[0]= -G.persinv[2][0]; n[1]= -G.persinv[2][1]; n[2]= -G.persinv[2][2]; Normalise(n); } base=G.firstbase; /* het opslaan in temp blok */ adror=(float *)callocN(16*teller,"roteer1"); adrve=(long *)callocN(24*teller,"roteer2"); adrin=(float **)mallocN(4*teller,"roteer3"); a=adror; v=adrve; teller2=0; while(base) { if(view0.lay & base->lay) { if(base->f & 1) { ai= (float *)getbasekeyadr(base,2); adrin[teller2++]=ai; QUATCOPY(a,ai); a+=4; if(PARENT(base)) { VECCOPY(v,base->r); } else { VECCOPY(v,base->v); } v+=3; VECCOPY(v,base->o); v+=3; } } base=base->next; } if(G.move1==1) { berekenschermco_noclip(view0.muis,mval); xc= mval[0]; yc= mval[1]; VECCOPY(vec,view0.muis); teller=2; } else { vec[0]=q1[0]/teller; vec[1]=q1[1]/teller; vec[2]= q1[2]/teller; berekenschermco_noclip(vec,mval); xc= mval[0]; yc= mval[1]; if(G.move1==2) teller=0; /* rond eigen centrum */ } if(teller==1 && view0.cambase && (view0.cambase->f & 1) && view0.persp>=2) { xc= 640; yc= 400; cambase= 1; } mdev[0] = MOUSEX; mdev[1] = MOUSEY; getdev(2, mdev, mval); mval[1]-= S.vys; dx1=xc-mval[0]; dy1=yc-mval[1]; xn= mval[0]; yn= mval[1]; /* voor midtog */ initprintoverdraw(); sprintf(s,"Rotate: %3.3f\n",hoek); cmov2i(10,204); charstr(s); endprintoverdraw(); if(teller>1) helpline(vec); VECCOPY(rotn,(G.persinv[0])); /* op deze plek vanwege cambase rot */ Normalise(rotn); VECCOPY(rotn1,(G.persinv[1])); Normalise(rotn1); while(TRUE) { getdev(2, mdev, mval); mval[1]-= S.vys; if(midtog) { dx2= -xn+mval[0]; dy2= yn-mval[1]; hoek1+= .2*(float)(dy2-dy1); if(G.qual & 32) hoek1= 5*ffloor(hoek1/5.0 +.5); choek= PI*hoek1/180.0; si= fsin(choek); co= fcos(choek); q2[0]= co; q2[1]= si*rotn[0]; q2[2]= si*rotn[1]; q2[3]= si*rotn[2]; hoek2+= .2*(float)(dx2-dx1); if(G.qual & 32) hoek2= 5*ffloor(hoek2/5.0 +.5); choek= PI*hoek2/180.0; si= fsin(choek); co= fcos(choek); q3[0]= co; q3[1]= si*rotn1[0]; q3[2]= si*rotn1[1]; q3[3]= si*rotn1[2]; QuatMul(q1,q2,q3); if( q1[0]!=hoeko ) { dx1=dx2; dy1=dy2; } } else { dx2=xc-mval[0]; dy2=yc-mval[1]; deler=fsqrt( (float)(dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2)); if(deler>1) { choek=(dx1*dx2+dy1*dy2)/deler; dhoek= 180.0*facos(choek)/PI; if( (dx1*dy2-dx2*dy1)<0 ) dhoek= -dhoek; if(G.qual & 3) hoek+= dhoek/30.0; else hoek+=dhoek; /* if(hoek>=360) hoek-=360; */ /* else if(hoek<-360) hoek+=360; */ if(G.qual & 32) if(G.qual & 3) hoek=ffloor(hoek+.5); else hoek= 5*ffloor(hoek/5.0 +.5); /* if(hoek>=360) hoek-=360; */ /* else if(hoek<-360) hoek+=360; */ choek=PI*hoek/360.0; si= fsin(choek); co= fcos(choek); q1[0]= co; q1[1]= si*n[0]; q1[2]= si*n[1]; q1[3]= si*n[2]; if( q1[0]!=hoeko ) { dx1=dx2; dy1=dy2; } } } if( q1[0]!=hoeko ) { hoeko= q1[0]; QuatToMat3(q1, tmat); a=adror; v=adrve; teller2=0; base=G.firstbase; while(base) { if(TESTBASE(base)) { QUATCOPY(q5, a); /* de te veranderen quat */ ai=adrin[teller2++]; QUATCOPY(ai, q5); if(base->p || base->t) { /* voor qpar: met workbase, voor o.a. qfillparent */ clearworkbase(); VECCOPY(G.workbase->v, base->v); /* voor track! */ VECCOPY(G.workbase->o, base->o); /* voor track! */ G.workbase->tflag= base->tflag; G.workbase->upflag= base->upflag; G.workbase->p= base->p; G.workbase->t= base->t; G.workbase->f= base->f; G.workbase->f1= base->f1; G.workbase->f2= base->f2; G.workbase->sf= base->sf; G.workbase->rodnr= base->rodnr; G.workbase->skelnr= base->skelnr; parentbase(G.workbase, mat, omat); clearworkbase(); Mat4ToQuat(mat, qpar); /* bepaal de qtot: totale quat incl eigen basequat */ /* let op volgorde QuatMul(), andersom geeft pas fouten onder complexe omstandigheden */ QuatMul(qtot, qpar, q5); /* totale eindrotatie */ QuatMul(q2, q1, qtot); /* deze met inverse qpar terugroteren */ qpar[1]= -qpar[1]; qpar[2]= -qpar[2]; qpar[3]= -qpar[3]; QuatMul(q2, qpar, q2); } else { QuatMul(q2, q1, q5); } QUATCOPY(ai, q2); if(teller>1) { if( PARENT(base) && G.hie) { VECCOPY(vec1,v); vec1[0]-= vec[0]; vec1[1]-= vec[1]; vec1[2]-= vec[2]; Mat3MulVec(tmat,vec1); vec1[0]+= vec[0]-v[0]; vec1[1]+= vec[1]-v[1]; vec1[2]+= vec[2]-v[2]; Mat3Inv(imat,omat); Mat3MulVec(imat,vec1); base->o[0]= v[3]+vec1[0]; base->o[1]= v[4]+vec1[1]; base->o[2]= v[5]+vec1[2]; } else { vec1[0]= v[0]-vec[0]; vec1[1]= v[1]-vec[1]; vec1[2]= v[2]-vec[2]; Mat3MulVec(tmat,vec1); base->v[0]= vec1[0]+vec[0]; base->v[1]= vec1[1]+vec[1]; base->v[2]= vec1[2]+vec[2]; } } a+=4; v+=6; } base=base->next; } projektie(); if(teller>1) helpline(vec); initprintoverdraw(); if(midtog) { sprintf(s,"Rotate: %3.3f %3.3f\n",hoek1,hoek2); cmov2i(10,204); charstr(s); } else { sprintf(s,"Rotate: %3.3f\n",hoek); cmov2i(10,204); charstr(s); } endprintoverdraw(); } else sginap(2); if( qtest() ) { toets= traces_qread(&val); if(val) { if(toets==ESCKEY || toets==LEFTMOUSE || toets==SPACEKEY) break; if(toets==MIDDLEMOUSE) { midtog= ~midtog; hoeko-=1.0; if(midtog) { getdev(2, mdev, mval); mval[1]-= S.vys; xn=mval[0]; yn=mval[1]; hoeko= q1[0]-1.0; dx1= 0; dy1= 0; } else { dx1=xc-mval[0]; dy1=yc-mval[1]; } } arrowsmovecursor(toets); } if(toets==INPUTCHANGE) G.winakt= val; toets=0; } } base=G.firstbase; a=adror; v=adrve; teller2=0; G.moving=0; while(base) { if(view0.lay & base->lay) { if(base->f & 1) { ai=adrin[teller2++]; if(toets==ESCKEY) { if( PARENT(base) ) { VECCOPY(base->o,v+3); } else { VECCOPY(base->v,v); } QUATCOPY(ai,a); } v+=6; a+=4; if(base->skelnr) calc_deform(base); } } base=base->next; } freeN(adror); freeN(adrve); freeN(adrin); clearprintoverdraw(); clearbaseflags_for_editing(); projektie(); } G.moving=0; } void sizing() { struct Base *base,*b; struct Key *key; float *adror,*a,**adrin,*ai,mat[4][4],bmat[3][3],pmat[3][3],imat[3][3],cmat[3][3],omat[3][3]; float vmat[3][3]; float xref, yref, sizex,sizey,sizez,sizexo,sizeyo,sizezo,fac; float persmat[3][3],persinv[3][3]; long *adrve,*v,dvec[3],vec[3],vec1[3],xc=0,yc=0; short teller=0,teller2,a1, val,mval[2],xm,ym,xn,yn,toets; short eenheidsmat(),midtog=0,proj; Device mdev[2]; char s[20]; if(G.firstbase==0) return; if(G.ebase) { vertsizing(); return; } G.moving=1; dvec[0]=dvec[1]=dvec[2]=0; xref= yref= 1.0; setbaseflags_for_editing(); base=G.firstbase; while(base) { /* aantal tellen en alvast tekenen */ if(view0.lay & base->lay) { if(base->f & 1) { xc+= base->sx; yc+= base->sy; dvec[0]+= base->r[0]; dvec[1]+= base->r[1]; dvec[2]+= base->r[2]; teller++; } if(base->f & 3) { tekenbase_ext(base); base->f&= ~8; /* mateenheid flag wissen */ } } base= base->next; } if(teller) { base=G.firstbase; /* het opslaan in temp blok */ adror=(float *)callocN(36*teller,"sizing1"); adrin=(float **)callocN(4*teller,"sizing1"); adrve=(long *)callocN(24*teller,"sizing2"); a=adror; v=adrve; teller2=0; while(base) { if(view0.lay & base->lay) { if(base->f & 1) { ai=(float *)getbasekeyadr(base,3); adrin[teller2++]=ai; if( PARENT(base) ) { VECCOPY(v,base->r); } else { VECCOPY(v,base->v); } v+=3; VECCOPY(v,base->o); Mat3CpyMat3(a,ai); v+=3; a+=9; } } base=base->next; } if(G.move1==1) { berekenschermco_noclip(view0.muis,mval); xc= mval[0]; yc= mval[1]; VECCOPY(vec,view0.muis); teller=2; } else { /* if(teller>1 && G.move1==0) { */ vec[0]=dvec[0]/teller; vec[1]=dvec[1]/teller; vec[2]= dvec[2]/teller; berekenschermco_noclip(vec, mval); xc= mval[0]; yc= mval[1]; /* } */ /* else teller=0; */ if(G.move1==2) teller=0; } Mat3CpyMat4(persmat,G.persmat); Mat3CpyMat4(persinv,G.persinv); mdev[0] = MOUSEX; mdev[1] = MOUSEY; getdev(2, mdev, mval); mval[1]-= S.vys; xm=mval[0]; ym=mval[1]; sizexo=sizeyo=sizezo=1.0; fac= fsqrt( (float)((yc-ym)*(yc-ym)+(xm-xc)*(xm-xc)) ); if(fac<2.0) fac= 2.0; initprintoverdraw(); sprintf(s,"Size X: %3.3f",sizexo); cmov2i(10,204); charstr(s); sprintf(s,"Size Y: %3.3f",sizeyo); cmov2i(160,204); charstr(s); sprintf(s,"Size Z: %3.3f",sizezo); cmov2i(310,204); charstr(s); if(G.move2==4) { sprintf(s,"SizeView"); cmov2i(460,204); charstr(s); } else if(G.move2==5) { sprintf(s,"Shear"); cmov2i(460,204); charstr(s); } endprintoverdraw(); while(TRUE) { getdev(2, mdev, mval); mval[1]-= S.vys; xn=mval[0]; yn=mval[1]; if(G.move2>=4) { sizex= 1.0-(float)(xm-xn)*0.005; if(G.move2==4) sizey= 1.0+(float)(ym-yn)*0.005; else sizey= 1.0; sizez= 1.0; } else { sizex=sizey=sizez= (fsqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) ))/fac; if(G.move2==1) sizey=sizez=1; if(G.move2==2) sizex=sizez=1; if(G.move2==3) sizey=sizex=1; } if(midtog) { if(proj==0) sizey=sizez=1; if(proj==1) sizex=sizez=1; if(proj==2) sizey=sizex=1; } if(G.qual & 32) { if (G.qual & 3) { sizex= (ffloor(100.0*sizex))/100.0; sizey= (ffloor(100.0*sizey))/100.0; sizez= (ffloor(100.0*sizez))/100.0; if(sizex==0.0) sizex== 0.01; if(sizey==0.0) sizey== 0.01; if(sizez==0.0) sizez== 0.01; } else { sizex= (ffloor(10.0*sizex))/10.0; sizey= (ffloor(10.0*sizey))/10.0; sizez= (ffloor(10.0*sizez))/10.0; if(sizex==0.0) sizex== 0.1; if(sizey==0.0) sizey== 0.1; if(sizez==0.0) sizez== 0.1; } } else if (G.qual & 3) { sizex = ((sizex - 1.0) / 10.0) + 1.0; sizey = ((sizey - 1.0) / 10.0) + 1.0; sizez = ((sizez - 1.0) / 10.0) + 1.0; } /* x flip */ val= testproj(mval[0]+10, mval[1], mval); if(val==0) sizex*= xref; else if(val==1) sizey*= xref; else sizez*=xref; /* y flip */ val= testproj(mval[0], mval[1]+10, mval); if(val==0) sizex*= yref; else if(val==1) sizey*= yref; else sizez*=yref; if(sizex==0.0) sizex== 0.001; if(sizey==0.0) sizey== 0.001; if(sizez==0.0) sizez== 0.001; if(sizex!=sizexo || sizey!=sizeyo || sizez!=sizezo) { base=G.firstbase; a=adror; v=adrve; teller2=0; while(base) { if(view0.lay & base->lay) { if(base->f & 1) { ai=adrin[teller2++]; Mat3CpyMat3(ai,a); parentbase(base,mat,omat); Mat3CpyMat4(bmat,mat); Mat3Inv(imat,bmat); Mat3One(cmat); cmat[0][0]= sizex; cmat[1][1]= sizey; cmat[2][2]= sizez; if(G.move2>=4) { if(G.move2==5) { cmat[0][0]= cmat[2][2]= cmat[1][1]= 1.0; cmat[1][0]=sizex-1.0; } /* eerst voor de basevecs: */ Mat3MulSerie(vmat, persmat, cmat, persinv, 0); Mat3MulSerie(pmat, bmat, persmat, cmat, persinv, imat, 0); Mat3CpyMat3(cmat, pmat); } else { /* eerst voor de basevecs: */ Mat3CpyMat3(vmat,cmat); Mat3MulMat3(pmat,cmat,bmat); Mat3MulMat3(cmat,imat,pmat); } Mat3MulMat3(ai,a,cmat); if(teller>1) { if( PARENT(base) && G.hie) { VECCOPY(vec1,v); vec1[0]= sizex*(vec1[0]-vec[0])+vec[0]-v[0]; vec1[1]= sizey*(vec1[1]-vec[1])+vec[1]-v[1]; vec1[2]= sizez*(vec1[2]-vec[2])+vec[2]-v[2]; Mat3Inv(imat,omat); Mat3MulVec(imat,vec1); base->o[0]= v[3]+vec1[0]; base->o[1]= v[4]+vec1[1]; base->o[2]= v[5]+vec1[2]; } else { base->v[0]= v[0]-vec[0]; base->v[1]= v[1]-vec[1]; base->v[2]= v[2]-vec[2]; Mat3MulVec(vmat,base->v); base->v[0]+= vec[0]; base->v[1]+= vec[1]; base->v[2]+= vec[2]; /* base->v[0]= sizex*(v[0]-vec[0])+vec[0]; */ /* base->v[1]= sizey*(v[1]-vec[1])+vec[1]; */ /* base->v[2]= sizez*(v[2]-vec[2])+vec[2]; */ } } a+=9; v+=6; } } base=base->next; } projektie(); if(teller>1) helpline(vec); initprintoverdraw(); sprintf(s,"Size X: %3.3f",sizex); cmov2i(10,204); charstr(s); sprintf(s,"Size Y: %3.3f",sizey); cmov2i(160,204); charstr(s); sprintf(s,"Size Z: %3.3f",sizez); cmov2i(310,204); charstr(s); if(G.move2==4) { sprintf(s,"SizeView"); cmov2i(460,204); charstr(s); } else if(G.move2==5) { sprintf(s,"Shear"); cmov2i(460,204); charstr(s); } endprintoverdraw(); } else sginap(2); sizexo=sizex; sizeyo=sizey; sizezo=sizez; if( qtest() ) { toets= traces_qread(&val); if(val) { if(toets==ESCKEY || toets==LEFTMOUSE || toets==SPACEKEY) break; else if(toets==MIDDLEMOUSE) { midtog= ~midtog; if(midtog) proj= testproj(xm,ym,mval); } else if(toets==XKEY) xref= -xref; else if(toets==YKEY) yref= -yref; arrowsmovecursor(toets); } if(toets==INPUTCHANGE) G.winakt= val; toets=0; sizexo-= 1.0; } } if(toets==ESCKEY) { base=G.firstbase; a=adror; v=adrve; teller2=0; while(base) { if(view0.lay & base->lay) { if(base->f & 1) { ai=adrin[teller2++]; if( PARENT(base) ) { VECCOPY(base->o,v+3); } else { VECCOPY(base->v,v); } Mat3CpyMat3(ai,a); a+=9; v+=6; if(base->skelnr) calc_deform(base); } } base=base->next; } } freeN(adror); freeN(adrve); freeN(adrin); G.moving=0; clearprintoverdraw(); clearbaseflags_for_editing(); projektie(); } G.moving=0; } void basebend() { ; /* wordt vanuit toets.c aangeroepen */ } void ipomouse(anim) long anim; { /* neemt huidige ipo en zet deze op de muiseco (l-r) */ /* bezier pointer wordt vervangen door rechte lijn */ struct Bezier *new, *orig, **origpp=0; double *mousedata, *md; /* GGems wil doubles */ float fac, *data, minx, maxx, sizex, sizey; long a, count=0, maxcount=5000, record=0, len, temp1, temp2, onceround=0; short mval[2], toets, val, oldval[2]; char s[50]; if(G.mainb!=7) return; if(anim) { temp1=G.cfra; G.cfra= G.sfra; temp2=G.hie; G.hie=2; swapinterval(2); } if(G.basact && G.ebase==0) { G.f |= 128; give_curipo_pp(&origpp); if(origpp) { new= callocN(sizeof(struct Bezier)+36*2, "ipomouse"); new->cp= 2; orig= *origpp; *origpp= new; data= (float *)(new+1); data[3]= IPOMINX; data[5]= 0.0; data[6]= data[3]; data[8]= 0.0; data[12]= IPOMAXX; data[14]= 0.0; data[9]= data[12]; data[11]= 0.0; oldval[0]= oldval[1]= 10000; md=mousedata= mallocN(2*8*maxcount, "ipomouse2"); while(TRUE) { getmouseco(mval); if(record || oldval[0]!=mval[0] || oldval[1]!=mval[1]) { fac= mval[0]/(float)S.vxw; data[4]= data[7]= data[10]= data[13]= IPOMINY+ fac*(IPOMAXY-IPOMINY); initprintoverdraw(); if(record) { if(anim) sprintf(s,"Ipo Mouse: %.3f Record: %d Frame: %d", fac, count, G.cfra); else sprintf(s,"Ipo Mouse: %.3f Record: %d", fac, count); } else { if(anim) sprintf(s,"Ipo Mouse: %.3f Frame: %d", fac, G.cfra); else sprintf(s,"Ipo Mouse: %.3f", fac); } cmov2i(10,204); charstr(s); endprintoverdraw(); if(anim) loadkeyposall(); else loadkeypostype(G.ipomode, G.basact, G.basact); makeDispList(G.basact); /* ook berekenpad */ projektie(); oldval[0]= mval[0]; oldval[1]= mval[1]; if(record) { md[0]= count; md[1]= mval[0]; md+= 2; if(anim) { G.cfra++; if(G.cfra>G.efra) { G.cfra= G.sfra; count= 0; md= mousedata; onceround= 1; } else count++; } else { count++; } if(count>=maxcount) count--; } } else sginap(2); if( qtest() ) { toets= traces_qread(&val); if(val) { if(toets==ESCKEY || toets==LEFTMOUSE || toets==SPACEKEY) break; } if(toets==LEFTCTRLKEY || toets==RIGHTCTRLKEY) record= val; } if(record) { /* af en toe raakt event verloren */ if( getbutton(LEFTCTRLKEY) || getbutton(RIGHTCTRLKEY) ); else record= 0; } } clearprintoverdraw(); freeN(new); if(anim && onceround) { count= G.efra-G.sfra+1; } if(count>1) { /* normaliseren x (tijd) coordinaten */ minx= 1.0e10; maxx= -1.0e10; md= mousedata; for(a=0; amd[0]) minx= md[0]; if(maxx