/** * $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 ***** */ /** * $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 ***** */ /* calcika.c juni 93 */ /* aug 94 */ /* */ /* */ #include "/usr/people/include/Trace.h" #include #include #include /* DOEN : * * - als alles rechtopstaat (obj 2) klappert de quaternion om als je er 1 keer aan trekt. * tijdelijk opgelost door y coordinaat van bovenste punt iets te veranderen * * * */ ListBase bpbase={0, 0}, rodbase={0, 0}, jointbase={0, 0}, skelbase={0, 0}; extern short rodedit; struct BodyPoint *addbodypoint() { struct BodyPoint *p1; p1= callocN(sizeof(struct BodyPoint), "addbodypoint"); addtail(&bpbase, p1); return p1; } void freebodypoint(struct BodyPoint *p1) { remlink(&bpbase, p1); freeN(p1); } void freeBPlist(ListBase *lb) { struct BodyPoint *bop, *next; bop= lb->first; while(bop) { next= bop->next; freebodypoint(bop); bop= next; } } struct Rod *addrod() { struct Rod *rod; rod= callocN(sizeof(struct Rod), "addrod"); addtail(&rodbase, rod); rod->drawwidth= 0.1*view0.grid; return rod; } void freerod(struct Rod *rod) { if(rod->rdef) freeN(rod->rdef); remlink(&rodbase, rod); freeN(rod); } void freeRodlist(ListBase *lb) { struct Rod *rod, *next; rod= lb->first; while(rod) { next= rod->next; freerod(rod); rod= next; } } struct Joint *addjoint() { struct Joint *joint; joint= callocN(sizeof(struct Joint), "addjoint"); addtail(&jointbase, joint); return joint; } void freejoint(joint) struct Joint *joint; { remlink(&jointbase, joint); freeN(joint); } void freeJointlist(ListBase *lb) { struct Joint *joint, *next; joint= lb->first; while(joint) { next= joint->next; freejoint(joint); joint= next; } } struct Skeleton *addskeleton(int nr) { struct Skeleton *skel; skel= callocN( sizeof(struct Skeleton)+4*nr, "addskel"); skel->nr= nr; addtail(&skelbase, skel); return skel; } void freeskeleton(struct Skeleton *skel) { remlink(&skelbase, skel); freeN(skel); } void freeSkellist(ListBase *lb) { struct Skeleton *skel, *next; skel= lb->first; while(skel) { next= skel->next; freeskeleton(skel); skel= next; } } void addIka1() { struct BodyPoint *p1, *p2, *p3, *p4; struct Rod *rod; struct Joint *joint; p1= addbodypoint(); p1->r[0]= 0.0; p1->r[1]= -2.0; p1->r[2]= 1.0; p1->m= 1.0; p2= addbodypoint(); p2->r[0]= 0.20*view0.grid; p2->r[1]= 0.0; p2->r[2]= 1.3*view0.grid; p2->m= 1.0; p3= addbodypoint(); p3->r[0]= -1.01*view0.grid; p3->r[1]= -1.0; p3->r[2]= 2.0*view0.grid; p3->m= 1.0; p4= addbodypoint(); p4->r[0]= -2.1*view0.grid; p4->r[1]= 1.0; p4->r[2]= 1.01*view0.grid; p4->m= 1.0; rod= addrod(); rod->p1= p1; rod->p2= p2; init_rod(rod, 0.0); rod= addrod(); rod->p1= p2; rod->p2= p3; init_rod(rod, 0.0); rod= addrod(); rod->p1= p3; rod->p2= p4; init_rod(rod, 0.0); joint= addjoint(); joint->r1= rod->prev->prev; joint->r2= rod->prev; joint->p1= p1; joint->p2= p2; joint->p3= p3; init_joint(joint, 1.0, 1.0, 0.0, 0.0, 0); joint= addjoint(); joint->r1= rod->prev; joint->r2= rod; joint->p1= p2; joint->p2= p3; joint->p3= p4; init_joint(joint, 1.0, 1.0, 0.0, 0.0, 0); } void deselectallpoints() { struct BodyPoint *bop; bop= bpbase.first; while(bop) { bop->f= 0; bop= bop->next; } } struct BodyPoint *nearest_bodypoint(mval) short *mval; { struct BodyPoint *bop, *sel= 0; int mindist= 10000, x, y, test; bop= bpbase.first; while(bop) { x= bop->sx-mval[0]; y= bop->sy-mval[1]; test= x*x+y*y; if(testnext; } return sel; } struct BodyPoint *nearest_sel_bodypoint_ex(mval, bopnot) short *mval; struct BodyPoint *bopnot; { struct BodyPoint *bop, *sel= 0; int mindist= 10000, x, y, test; bop= bpbase.first; while(bop) { if(bopnot!=bop) { if(bop->f & 1) { x= bop->sx-mval[0]; y= bop->sy-mval[1]; test= x*x+y*y; if(testnext; } return sel; } struct Rod *rod_has_bodypoints(p1, p2, p3, p4) struct BodyPoint *p1, *p2, *p3, *p4; { /* return rod die de aangegeven punten heeft. punten mogen '0' zijn */ struct Rod *rod; int nr=0, verg; if(p1) nr++; /* 'nr' moet de score zijn om rod te returnen */ if(p2) nr++; if(p3) nr++; if(p4) nr++; rod= rodbase.first; while(rod) { verg= 0; if(p1) if(rod->p1==p1 || rod->p2==p1 || rod->p3==p1 || rod->p4==p1 ) verg++; if(p2) if(rod->p1==p2 || rod->p2==p2 || rod->p3==p2 || rod->p4==p2 ) verg++; if(p3) if(rod->p1==p3 || rod->p2==p3 || rod->p3==p3 || rod->p4==p3 ) verg++; if(p4) if(rod->p1==p4 || rod->p2==p4 || rod->p3==p4 || rod->p4==p4 ) verg++; if(verg==nr) return rod; rod= rod->next; } return 0; } void setflags_bodypoints(bop, flag) struct BodyPoint *bop; { while(bop) { bop->f= flag; bop= bop->next; } } int is_rod_selected(struct Rod *rod) { if(rod->type==ROD) { if(rod->p1->f &1) if(rod->p2->f &1) return 1; } else if(rod->type==T_ROD) { if(rod->p1->f &1) if(rod->p2->f &1) if(rod->p3->f &1) return 1; } if(rod->type==H_ROD) { if(rod->p1->f &1) if(rod->p2->f &1) if(rod->p3->f &1) if(rod->p4->f &1) return 1; } return 0; } int is_joint_selected(struct Joint *joint) { if( is_rod_selected(joint->r1) && is_rod_selected(joint->r2) ) return 1; return 0; } int is_skel_selected(struct Skeleton *skel) { struct Rod **rod; int nr; nr= skel->nr; rod= (struct Rod **)(skel+1); while(nr--) { if( is_rod_selected(*rod) == 0 ) return 0; rod++; } return 1; } int is_rod_OR_selected(struct Rod *rod) /* min 1 point */ { if(rod->type==ROD) { if(rod->p1->f &1) if(rod->p2->f &1) return 1; } else if(rod->type==T_ROD) { if(rod->p1->f &1) if(rod->p2->f &1) if(rod->p3->f &1) return 1; } if(rod->type==H_ROD) { if(rod->p1->f &1) if(rod->p2->f &1) if(rod->p3->f &1) if(rod->p4->f &1) return 1; } return 0; } void vars_for_buttons() { extern struct BodyPoint *bopsel; extern struct Rod *rodsel; extern struct Joint *jointsel; extern struct Skeleton *skelsel; struct BodyPoint *bop, *b1; struct Rod *rod, *r1; struct Joint *joint, *j1; /* onthoud */ b1= bopsel; r1= rodsel; j1= jointsel; /* is er maar 1 bp selected: ok */ bop= bpbase.first; bopsel= 0; while(bop) { if(bop->f & 1) { if(bopsel) { bopsel= 0; break; } else bopsel= bop; } bop= bop->next; } /* is er maar 1 rod selected: ok */ rod= rodbase.first; rodsel= 0; while(rod) { if(is_rod_selected(rod)) { if(rodsel) { rodsel= 0; break; } else rodsel= rod; } rod= rod->next; } /* is er maar 1 joint selected: ok */ joint= jointbase.first; jointsel= 0; while(joint) { if(is_joint_selected(joint)) { if(jointsel) { jointsel= 0; break; } else jointsel= joint; } joint= joint->next; } skelsel= 0; if(G.mainb==9) { if(b1!=bopsel || r1!=rodsel || j1!=jointsel) { tekeneditbuts(1); } } } void freeAllika() { struct Rod *rod; freeBPlist(&bpbase); freeRodlist(&rodbase); freeJointlist(&jointbase); freeSkellist(&skelbase); } void delete_bodypoints_flag(int flag) { struct Skeleton *skel, *nexts; struct BodyPoint *bop, *nextb; struct Rod *rod, *nextr, **rodpp; struct Joint *joint, *nextj; int a, ok; skel= skelbase.first; while(skel) { nexts= skel->next; /* is er minimaal 1 select? */ ok= 0; a= skel->nr; rodpp= (struct Rod **)(skel+1); while(a--) { if( (*rodpp)->p1->f & flag) ok= 1; else if((*rodpp)->p2->f & flag) ok= 1; else if((*rodpp)->p3 && (*rodpp)->p3->f & flag) ok= 1; else if((*rodpp)->p4 && (*rodpp)->p4->f & flag) ok= 1; if(ok) break; rodpp++; } if(ok) freeskeleton(skel); skel= nexts; } joint= jointbase.first; while(joint) { nextj= joint->next; /* is er minimaal 1 select? */ ok= 0; if(joint->p1->f & flag) ok= 1; else if(joint->p2->f & flag) ok= 1; else if(joint->p3->f & flag) ok= 1; else if(joint->p1a && joint->p1a->f & flag) ok= 1; else if(joint->p2a && joint->p2a->f & flag) ok= 1; else if(joint->p3a && joint->p3a->f & flag) ok= 1; if(ok) freejoint(joint); joint= nextj; } rod= rodbase.first; while(rod) { nextr= rod->next; /* is er minimaal 1 select? */ ok= 0; if(rod->p1->f & flag) ok= 1; else if(rod->p2->f & flag) ok= 1; else if(rod->p3 && rod->p3->f & flag) ok= 1; else if(rod->p4 && rod->p4->f & flag) ok= 1; if(ok) freerod(rod); rod= nextr; } bop= bpbase.first; while(bop) { nextb= bop->next; if(bop->f & flag) freebodypoint(bop); bop= nextb; } } void delete_rods_flag(int flag) { struct BodyPoint *bop, *nextb; struct Rod *rod, *nextr, **rodpp; struct Joint *joint, *nextj; struct Skeleton *skel, *nexts; int a, ok; skel= skelbase.first; while(skel) { nexts= skel->next; a= skel->nr; ok= 0; rodpp= (struct Rod **)(skel+1); while(a--) { if( is_rod_selected(*rodpp) ) { ok= 1; break; } rod++; } if(ok) freeskeleton(skel); skel= nexts; } joint= jointbase.first; while(joint) { nextj= joint->next; if( is_rod_selected(joint->r1) || is_rod_selected(joint->r2) ) freejoint(joint); joint= nextj; } rod= rodbase.first; while(rod) { nextr= rod->next; if( is_rod_selected(rod) ) freerod(rod); rod= nextr; } /* losslingerende punten weg */ rod= rodbase.first; while(rod) { if(rod->p1->f & flag) rod->p1->f &= ~flag; if(rod->p2->f & flag) rod->p2->f &= ~flag; if(rod->p3 && (rod->p3->f & flag)) rod->p3->f &= ~flag; if(rod->p4 && (rod->p4->f & flag)) rod->p4->f &= ~flag; rod= rod->next; } bop= bpbase.first; while(bop) { nextb= bop->next; if(bop->f & flag) freebodypoint(bop); bop= nextb; } } void delete_joints_flag(int flag) { struct Joint *joint, *nextj; joint= jointbase.first; while(joint) { nextj= joint->next; if( is_rod_selected(joint->r1) && is_rod_selected(joint->r2) ) freejoint(joint); joint= nextj; } } void delete_skels_flag(int flag) { struct Skeleton *skel, *nexts; struct Rod **rodpp; int a, sel; skel= skelbase.first; while(skel) { nexts= skel->next; rodpp= (struct Rod **)(skel+1); sel==0; while(a--) { if(is_rod_selected(*rodpp)) sel++; else break; rodpp++; } if(sel==skel->nr) freeskeleton(skel); skel= nexts; } } void default_ika(struct IkaData *ika) { /* om Base te initialiseren, niet in editmode */ addIka1(); calc_ika(); ika->bpbase= bpbase; ika->rodbase= rodbase; ika->jointbase= jointbase; ika->skelbase= skelbase; bpbase.first= bpbase.last= 0; rodbase.first= rodbase.last= 0; jointbase.first= jointbase.last= 0; skelbase.first= skelbase.last= 0; ika->dt= 2; } int dupli_split_mode= 0; /* 2 soorten duplicate! */ void add_dupli_ika(bpnew, rodnew, jointnew, skelnew, bpold, rodold, jointold, skelold) ListBase *bpnew, *rodnew, *jointnew, *skelnew, *bpold, *rodold, *jointold, *skelold; { /* dupliceerst al het geselecteerde */ struct BodyPoint *bop, *lbop; struct Rod *rod, **rodpp, *lrod; struct Joint *joint, *jointn, *ljoint; struct Skeleton *skel, *skeln, *lskel; int a; /* van old pointers op nul */ bop= bpold->first; while(bop) { bop->new= 0; bop->f &= ~2; /* voor temp */ bop= bop->next; } rod= rodold->first; while(rod) { rod->new= 0; rod= rod->next; } /* nieuwe punten */ bop= bpold->first; lbop= bpold->last; while(bop) { if(bop->f & 1) { bop->new= mallocN(sizeof(struct BodyPoint), "duplika"); memcpy(bop->new, bop, sizeof(struct BodyPoint)); bop->new->new= 0; bop->new->f= 2; addtail(bpnew, bop->new); } if(bop==lbop) break; bop= bop->next; } /* nieuwe rods */ rod= rodold->first; lrod= rodold->last; while(rod) { if( is_rod_selected(rod) ) { rod->new= mallocN(sizeof(struct Rod), "duplika"); memcpy(rod->new, rod, sizeof(struct Rod)); rod->new->new= 0; addtail(rodnew, rod->new); rod->new->p1= rod->p1->new; rod->new->p2= rod->p2->new; if(rod->p3) rod->new->p3= rod->p3->new; if(rod->p4) rod->new->p4= rod->p4->new; if(rod->rdef) { rod->new->rdef= mallocN(sizeof(struct RodDeform), "duplika"); memcpy(rod->new->rdef, rod->rdef, sizeof(struct RodDeform)); } } if(rod==lrod) break; rod= rod->next; } /* nieuwe joints */ joint= jointold->first; ljoint= jointold->last; while(joint) { if( is_joint_selected(joint) ) { jointn= mallocN(sizeof(struct Joint), "duplika"); memcpy(jointn, joint, sizeof(struct Joint)); addtail(jointnew, jointn); jointn->r1= joint->r1->new; jointn->r2= joint->r2->new; jointn->p1= joint->p1->new; jointn->p2= joint->p2->new; jointn->p3= joint->p3->new; if(joint->p1a) jointn->p1a= joint->p1a->new; if(joint->p2a) jointn->p2a= joint->p2a->new; if(joint->p3a) jointn->p3a= joint->p3a->new; } if(joint==ljoint) break; joint= joint->next; } /* nieuwe skeletons */ skel= skelold->first; lskel= skelold->last; while(skel) { if( is_skel_selected(skel) ) { skeln= mallocN( sizeof(struct Skeleton)+4*skel->nr, "dupliskel"); memcpy(skeln, skel, sizeof(struct Skeleton)+4*skel->nr); addtail(skelnew, skeln); rodpp= (struct Rod **)(skeln+1); a= skeln->nr; while(a--) { *rodpp= (*rodpp)->new; rodpp++; } } if(skel==lskel) break; skel= skel->next; } /* niet netjes, werkt alleen als listbases op editmode staan */ if(dupli_split_mode) { delete_rods_flag(1); } /* nieuwe selecteren */ bop= bpold->first; while(bop) { if(bop->f & 1) bop->f= 0; if(bop->f == 2) bop->f= 1; bop= bop->next; } if(bpold!=bpnew) { bop= bpnew->first; while(bop) { bop->f= 1; bop= bop->prev; } } } void adduplicateIka() /* extern in editmode, vanuit toets */ { add_dupli_ika(&bpbase, &rodbase, &jointbase, &skelbase, &bpbase, &rodbase, &jointbase, &skelbase); vertgrabber(); } void muis_ika() { struct BodyPoint *bop; short mval[2], xs, ys; /* welk punt wordt geselecteerd */ getmouseco(mval); bop= nearest_bodypoint(mval); if(bop==0) return; if(G.qual & 3) { if(bop->f & 1) bop->f=0; else bop->f= 1; } else { setflags_bodypoints(bpbase.first, 0); bop->f= 1; } projektie(); getmouseco(mval); xs= mval[0]; ys= mval[1]; while(getbutton(RIGHTMOUSE)) { gsync(); getmouseco(mval); if(abs(mval[0]-xs)+abs(mval[1]-ys) > 4) { vertgrabber(); while(getbutton(RIGHTMOUSE)) gsync(); } } vars_for_buttons(); } void make_ebaseIka() { /* kopieer base naar edit data */ struct IkaData *ika; struct Key *key; struct Rod *rod; int a; freeAllika(); /* voor zekerheid en reload! */ ika= (struct IkaData *)G.ebase->d; key= ika->key; if(key && G.ipomode==22 && G.actkey) { a= 1; while(key) { if(a== G.actkey) break; a++; key= key->next; } if(key) { key_to_ika(key, ika); } } setflags_bodypoints(ika->bpbase.first, 1); add_dupli_ika(&bpbase, &rodbase, &jointbase, &skelbase, &ika->bpbase, &ika->rodbase, &ika->jointbase, &ika->skelbase); setflags_bodypoints(bpbase.first, 0); calc_ika(); vars_for_buttons(); } void load_ebaseIka() { /* kopieer edit data naar base */ struct IkaData *ika; struct Base *base; struct Key *key, *newk, *prevk; struct BodyPoint *bop; struct Rod *rod; int a, count, diffvert, len; ika= (struct IkaData *)G.ebase->d; key= ika->key; /* eerst tellen */ count= diffvert= 0; bop= bpbase.first; while(bop) { count++; bop= bop->next; } if(ika->keyverts!=count) diffvert= 1; ika->keyverts= count; count= 0; rod= rodbase.first; while(rod) { count++; rod= rod->next; } if(ika->keyrods!=count) diffvert= 1; ika->keyrods= count; freeBPlist(&ika->bpbase); freeRodlist(&ika->rodbase); freeJointlist(&ika->jointbase); freeSkellist(&ika->skelbase); deselectallpoints(); ika->bpbase= bpbase; ika->rodbase= rodbase; ika->jointbase= jointbase; ika->skelbase= skelbase; if(G.ipomode==22 && key && G.actkey) { if(diffvert) { /* allemaal nieuwe keyblokken maken */ prevk= 0; len= sizeof(struct Key)+4*4*ika->keyverts+4*ika->keyrods; while(key) { newk= (struct Key *)mallocN(len, "loadebaseNurb"); memcpy(newk, key, sizeof(struct Key)); ika_to_key(ika, newk); freeN(key); if(prevk==0) { ika->key= newk; } else prevk->next= newk; prevk= newk; key= newk->next; } } else { a= 1; while(key) { if(a== G.actkey) break; a++; key= key->next; } if(key) { ika_to_key(ika, key); } } /* nu zit waarschijnlijk verkeerde key in ikadata: dus... */ base= G.ebase; G.ebase= 0; loadkeypos(base); G.ebase= base; } bpbase.first= bpbase.last= 0; rodbase.first= rodbase.last= 0; jointbase.first= jointbase.last= 0; skelbase.first= skelbase.last= 0; vars_for_buttons(); } void addprimitiveIka(int prim) { struct BodyPoint *p1, *p2, *p3, *p4; struct Rod *rod; float cent[3], pmat[4][4], tmat[4][4], cmat[3][3], mat[3][3], imat[3][3]; parentbase(G.ebase,tmat,mat); Mat3CpyMat4(mat,tmat); VECCOPY(cent,view0.muis); cent[0]-= tmat[3][0]; cent[1]-= tmat[3][1]; cent[2]-= tmat[3][2]; winset(G.winar[0]); getmatrix(pmat); Mat3CpyMat4(imat,pmat); Mat3MulVecfl(imat, cent); Mat3MulMat3(cmat, imat, mat); Mat3Inv(imat, cmat); setflags_bodypoints(bpbase.first, 0); if(prim==1) { /* rod */ p1= addbodypoint(); VECCOPY(p1->r, cent); p1->r[0]-= 0.5*view0.grid; Mat3MulVecfl(imat, p1->r); p1->m= 1.0; p1->f= 1; p2= addbodypoint(); VECCOPY(p2->r, cent); p2->r[0]+= 0.5*view0.grid; p2->m= 1.0; Mat3MulVecfl(imat, p2->r); p2->f= 1; rod= addrod(); rod->p1= p1; rod->p2= p2; init_rod(rod, 0.0); } else if(prim==2) { /* T rod */ p1= addbodypoint(); VECCOPY(p1->r, cent); p1->r[0]-= 0.5*view0.grid; Mat3MulVecfl(imat, p1->r); p1->m= 1.0; p1->f= 1; p2= addbodypoint(); VECCOPY(p2->r, cent); p2->r[0]+= 0.5*view0.grid; p2->r[1]+= 0.2*view0.grid; p2->m= 1.0; Mat3MulVecfl(imat, p2->r); p2->f= 1; p3= addbodypoint(); VECCOPY(p3->r, cent); p3->r[0]+= 0.5*view0.grid; p3->r[1]-= 0.2*view0.grid; p3->m= 1.0; Mat3MulVecfl(imat, p3->r); p3->f= 1; rod= addrod(); rod->p1= p1; rod->p2= p2; rod->p3= p3; init_rod(rod, 0.0); } else if(prim==3) { /* H rod */ p1= addbodypoint(); VECCOPY(p1->r, cent); p1->r[0]-= 0.5*view0.grid; p1->r[1]+= 0.2*view0.grid; Mat3MulVecfl(imat, p1->r); p1->m= 1.0; p1->f= 1; p2= addbodypoint(); VECCOPY(p2->r, cent); p2->r[0]-= 0.5*view0.grid; p2->r[1]-= 0.2*view0.grid; p2->m= 1.0; Mat3MulVecfl(imat, p2->r); p2->f= 1; p3= addbodypoint(); VECCOPY(p3->r, cent); p3->r[0]+= 0.5*view0.grid; p3->r[1]+= 0.2*view0.grid; p3->m= 1.0; Mat3MulVecfl(imat, p3->r); p3->f= 1; p4= addbodypoint(); VECCOPY(p4->r, cent); p4->r[0]+= 0.5*view0.grid; p4->r[1]-= 0.2*view0.grid; p4->m= 1.0; Mat3MulVecfl(imat, p4->r); p4->f= 1; rod= addrod(); rod->p1= p1; rod->p2= p2; rod->p3= p3; rod->p4= p4; init_rod(rod, 0.0); } else if(prim==4) { /* Q rod */ } else if(prim==5) { /* chain */ } projektie(); vars_for_buttons(); } void delIka() { struct BodyPoint *bop; struct Rod *rod; struct Joint *joint; int event; event= pupmenu("ERASE %t|Points%x1|Rods%x2|Joints%x3|Skeletons%x4|All%x5"); if(event== -1) return; if(event==1) { delete_bodypoints_flag(1); } else if(event==2) { delete_rods_flag(1); } else if(event==3) { delete_joints_flag(1); } else if(event==4) { delete_skels_flag(1); } else if(event==5) { freeAllika(); } projektie(); vars_for_buttons(); } void splitIka() { if(okee(" Split ")==0) return; dupli_split_mode= 1; add_dupli_ika(&bpbase, &rodbase, &jointbase, &skelbase, &bpbase, &rodbase, &jointbase, &skelbase); dupli_split_mode= 0; vars_for_buttons(); } void connect_ika() { struct BodyPoint *bop, *p1=0; struct Rod *rod; struct Joint *joint; if( okee("Connect")==0 ) return; /* pointers op nul */ bop= bpbase.first; while(bop) { bop->new= 0; bop= bop->next; } /* zoek tweetallen punten bij elkaar */ bop= bpbase.first; while(bop) { if(bop->f & 1) { p1= nearest_sel_bodypoint_ex(&(bop->sx), bop); if(p1) { if( rod_has_bodypoints(bop, p1, 0, 0) ); /* beide punten in 1 rod */ else { VecMidf(bop->r, bop->r, p1->r); p1->new= bop; p1->f= 0; } } bop->f= 0; } bop= bop->next; } /* pointers weer goedzetten */ rod= rodbase.first; while(rod) { if(rod->p1->new) rod->p1= rod->p1->new; if(rod->p2->new) rod->p2= rod->p2->new; if(rod->p3 && rod->p3->new) rod->p3= rod->p3->new; if(rod->p4 && rod->p4->new) rod->p4= rod->p4->new; rod= rod->next; } joint= jointbase.first; while(joint) { if(joint->p1->new) joint->p1= joint->p1->new; if(joint->p2->new) joint->p2= joint->p2->new; if(joint->p3->new) joint->p3= joint->p3->new; if(joint->p1a && joint->p1a->new) joint->p1a= joint->p1a->new; if(joint->p2a && joint->p2a->new) joint->p2a= joint->p2a->new; if(joint->p3a && joint->p3a->new) joint->p3a= joint->p3a->new; joint= joint->next; } /* verwijderen */ bop= bpbase.first; while(bop) { p1= bop->next; if(bop->new) freebodypoint(bop); bop= p1; } calc_ika(); if(rodedit==0) { rodedit= 1; calc_ika(); /* interne spanningen op nul */ rodedit= 0; } projektie(); vars_for_buttons(); } void makejoint() { struct Joint *joint; struct Rod *r1=0, *r2=0, *rod; struct BodyPoint *p1=0, *p2=0; /* testen of joint al bestaat */ vars_for_buttons(); if(jointsel) { if( okee("Init Joint")==0 ) return; init_joint(jointsel, 0.0, 0.0, 0.0, 0.0, 0); jointsel= 0; /* forceer buttonredraw */ } else { if( okee("Make Joint")==0 ) return; /* we gaan op zoek naar 2 rods met geselecteerde punten */ rod= rodbase.first; while(rod) { if(is_rod_OR_selected(rod)) { if(r1==0) r1= rod; else if(r2==0) r2= rod; else { error("Indicate 2 connecting rods"); return; } } rod= rod->next; } if(r2==0) { error("Indicate 2 connecting rods"); return; } /* r1 en r2 moeten aansluiten */ if(r1->p1==r2->p1 || r1->p1==r2->p2 || r1->p1==r2->p3 || r1->p1==r2->p4) p1= r1->p1; if(r1->p2==r2->p1 || r1->p2==r2->p2 || r1->p2==r2->p3 || r1->p2==r2->p4) { if(p1) p2= r1->p2; else p1= r1->p2; } if(r1->p3) if(r1->p3==r2->p1 || r1->p3==r2->p2 || r1->p3==r2->p3 || r1->p3==r2->p4) { if(p1) p2= r1->p3; else p1= r1->p3; } if(r1->p4) if(r1->p4==r2->p1 || r1->p4==r2->p2 || r1->p4==r2->p3 || r1->p4==r2->p4) { if(p1) p2= r1->p4; else p1= r1->p4; } if(p1==0) { error("Indicate 2 connecting rods"); return; } joint= addjoint(); joint->r1= r1; joint->r2= r2; joint->p2= p1; joint->p2a= p2; if(p1 && p2) { /* dubbel scharnier, testen op illegale joints */ /* eerst rod 1 */ if(r1->type==T_ROD) { if(r1->p2==p1 || r1->p3==p1) { if(r1->p2==p2 || r1->p3==p2) { joint->p1= r1->p1; } } } else if(r1->type==H_ROD) { if(r1->p1==p1 || r1->p2==p1) { if(r1->p1==p2 || r1->p2==p2) { joint->p1= r1->p3; joint->p1a= r1->p4; } } else if(r1->p3==p1 || r1->p4==p1) { if(r1->p3==p2 || r1->p4==p2) { joint->p1= r1->p1; joint->p1a= r1->p2; } } } /* daarna rod 2 */ if(r2->type==T_ROD) { if(r2->p2==p1 || r2->p3==p1) { if(r2->p2==p2 || r2->p3==p2) { joint->p3= r2->p1; } } } else if(r2->type==H_ROD) { if(r2->p1==p1 || r2->p2==p1) { if(r2->p1==p2 || r2->p2==p2) { joint->p3= r2->p3; joint->p3a= r2->p4; } } else if(r2->p3==p1 || r2->p4==p1) { if(r2->p3==p2 || r2->p4==p2) { joint->p3= r2->p1; joint->p3a= r2->p2; } } } } else { /* enkel scharnier */ /* eerst rod 1 */ if(r1->type==ROD) { if(p1==r1->p1) joint->p1= r1->p2; else joint->p1= r1->p1; } else if(r1->type==T_ROD) { if(p1==r1->p1) { /* aan de staart */ joint->p1= r1->p2; joint->p1a= r1->p3; } else if(p1==r1->p2 || p1==r1->p3) { /* aan de andere zijde */ joint->p1= r1->p1; } } else if(r1->type==H_ROD) { if(p1==r1->p1 || p1==r1->p2) { joint->p1= r1->p3; joint->p1a= r1->p4; } else if(p1==r1->p3 || p1==r1->p4) { joint->p1= r1->p1; joint->p1a= r1->p2; } } /* daarna rod 2 */ if(r2->type==ROD) { if(p1==r2->p1) joint->p3= r2->p2; else joint->p3= r2->p1; } else if(r2->type==T_ROD) { if(p1==r2->p1) { /* aan de staart */ joint->p3= r2->p2; joint->p3a= r2->p3; } else if(p1==r2->p2 || p1==r2->p3) { /* aan de andere zijde */ joint->p3= r2->p1; } } else if(r2->type==H_ROD) { if(p1==r2->p1 || p1==r2->p2) { joint->p3= r2->p3; joint->p3a= r2->p4; } else if(p1==r2->p3 || p1==r2->p4) { joint->p3= r2->p1; joint->p3a= r2->p2; } } } if(joint->p1==0 || joint->p3==0) { error("Illegal joint"); freejoint(joint); return; } init_joint(joint, 0.0, 0.0, 0.0, 0.0, 0); } vars_for_buttons(); projektie(); } void makeskeleton() { struct Rod *rod, **rodpp; struct Skeleton *skel; int nr=0; if( okee("Make Skeleton")==0 ) return; /* tellen welke rods geselecteerd */ rod= rodbase.first; while(rod) { if(is_rod_selected(rod)) nr++; rod= rod->next; } if(nr>1) { skel= addskeleton(nr); rodpp= (struct Rod **)(skel+1); rod= rodbase.first; while(rod) { if(is_rod_selected(rod)) { *rodpp= rod; make_orig_rod(rod); rodpp++; } rod= rod->next; } } else error("Select min 2 rods"); } void re_init_deform() { struct Rod *rod; struct Joint *joint; rod= rodbase.first; while(rod) { if(is_rod_selected(rod)) make_orig_rod(rod); rod= rod->next; } /* zeer tijdelijk: alpha en def alpha */ joint= jointbase.first; while(joint) { if(is_joint_selected(joint)) { joint->rt[1]= joint->rt[0]; } joint= joint->next; } } void revealIka() { struct BodyPoint *bop; bop= bpbase.first; while(bop) { if(bop->h) { bop->h= 0; bop->f= 1; } bop= bop->next; } vars_for_buttons(); projektie(); } void hideIka() { struct BodyPoint *bop; bop= bpbase.first; while(bop) { if(bop->f & 1) { bop->h= 1; } bop= bop->next; } vars_for_buttons(); projektie(); } void selectswapIka() { struct BodyPoint *bop; bop= bpbase.first; while(bop) { if(bop->h==0) { if(bop->f & 1) bop->f= 0; else bop->f= 1; } bop= bop->next; } vars_for_buttons(); projektie(); } void selectconnectedIka() { struct Rod *rod; struct BodyPoint *bop; int cont=1, ok; short mval[2]; /* alle hulpflags resetten */ bop= bpbase.first; while(bop) { bop->f & ~1; bop= bop->next; } getmouseco(mval); bop= nearest_bodypoint(mval); if(bop==0) return; bop->f |= 2; /* floodfill */ while(cont) { cont= 0; rod= rodbase.first; while(rod) { ok= 0; if(rod->p1->f & 2) ok++; if(rod->p2->f & 2) ok++; if(rod->p3 && rod->p3->f & 2) ok++; if(rod->p4 && rod->p4->f & 2) ok++; if(ok) { if( (rod->p1->f & 2)==0) {rod->p1->f |= 2; cont= 1;} if( (rod->p2->f & 2)==0) {rod->p2->f |= 2; cont= 1;} if( rod->p3 && (rod->p3->f & 2)==0) {rod->p3->f |= 2; cont= 1;} if( rod->p4 && (rod->p4->f & 2)==0) {rod->p4->f |= 2; cont= 1;} } rod= rod->next; } } /* flaggen */ bop= bpbase.first; while(bop) { if(bop->f & 2) { bop->f -= 2; if(G.qual & 3) bop->f= 0; else bop->f |= 1; } bop= bop->next; } projektie(); } void setlock_ika(int lock) { struct BodyPoint *bop; bop= bpbase.first; while(bop) { if(bop->f & 1) bop->f1= lock; bop= bop->next; } } void setmass_ika(float mass) { struct BodyPoint *bop; bop= bpbase.first; while(bop) { if(bop->f & 1) bop->m= mass; bop= bop->next; } } void setwidth_ika(short width) { struct Rod *rod; rod= rodbase.first; while(rod) { if(is_rod_selected(rod)) rod->drawwidth= width; rod= rod->next; } projektie(); }