diff options
Diffstat (limited to 'source/blender/src/editipo.c')
-rw-r--r-- | source/blender/src/editipo.c | 5212 |
1 files changed, 5212 insertions, 0 deletions
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c new file mode 100644 index 00000000000..163bf0132c8 --- /dev/null +++ b/source/blender/src/editipo.c @@ -0,0 +1,5212 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" +#include "PIL_time.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_constraint_types.h" +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" +#include "DNA_lamp_types.h" +#include "DNA_sequence_types.h" +#include "DNA_sound_types.h" +#include "DNA_camera_types.h" +#include "DNA_material_types.h" +#include "DNA_key_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_ipo_types.h" +#include "DNA_curve_types.h" +#include "DNA_space_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view3d_types.h" +#include "DNA_group_types.h" +#include "DNA_ika_types.h" + +#include "BKE_utildefines.h" +#include "BKE_action.h" +#include "BKE_anim.h" +#include "BKE_material.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_ika.h" +#include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_group.h" + +#include "BIF_buttons.h" +#include "BIF_editkey.h" +#include "BIF_editseq.h" +#include "BIF_editview.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_poseobject.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" +#include "BIF_poseobject.h" + +#include "BDR_drawobject.h" +#include "BDR_editobject.h" + +#include "BSE_trans_types.h" +#include "BSE_editipo_types.h" +#include "BSE_drawipo.h" +#include "BSE_editipo.h" +#include "BSE_editaction.h" +#include "BSE_edit.h" +#include "BSE_drawview.h" +#include "BSE_headerbuttons.h" + +#include "blendef.h" +#include "mydevice.h" +#include "interface.h" +#include "render.h" + +/* forwards */ +#define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1)) + +#define IPOTHRESH 0.9 +#define ISPOIN(a, b, c) ( (a->b) && (a->c) ) +#define ISPOIN3(a, b, c, d) ( (a->b) && (a->c) && (a->d) ) +#define ISPOIN4(a, b, c, d, e) ( (a->b) && (a->c) && (a->d) && (a->e) ) + +extern int ob_ar[]; +extern int ma_ar[]; +extern int seq_ar[]; +extern int cu_ar[]; +extern int key_ar[]; +extern int wo_ar[]; +extern int la_ar[]; +extern int cam_ar[]; +extern int snd_ar[]; +extern int ac_ar[]; +extern int co_ar[]; + +void getname_ac_ei(int nr, char *str) +{ + switch(nr) { + case AC_LOC_X: + strcpy(str, "LocX"); break; + case AC_LOC_Y: + strcpy(str, "LocY"); break; + case AC_LOC_Z: + strcpy(str, "LocZ"); break; + case AC_SIZE_X: + strcpy(str, "SizeX"); break; + case AC_SIZE_Y: + strcpy(str, "SizeY"); break; + case AC_SIZE_Z: + strcpy(str, "SizeZ"); break; + case AC_QUAT_X: + strcpy(str, "QuatX"); break; + case AC_QUAT_Y: + strcpy(str, "QuatY"); break; + case AC_QUAT_Z: + strcpy(str, "QuatZ"); break; + case AC_QUAT_W: + strcpy(str, "QuatW"); break; + default: + str[0]= 0; + } +} + +void getname_co_ei(int nr, char *str) +{ + switch(nr){ + case CO_ENFORCE: + strcpy(str, "Inf"); break; + } +} + +void getname_ob_ei(int nr, char *str, int colipo) +{ + switch(nr) { + case OB_LOC_X: + strcpy(str, "LocX"); break; + case OB_LOC_Y: + strcpy(str, "LocY"); break; + case OB_LOC_Z: + strcpy(str, "LocZ"); break; + case OB_DLOC_X: + strcpy(str, "dLocX"); break; + case OB_DLOC_Y: + strcpy(str, "dLocY"); break; + case OB_DLOC_Z: + strcpy(str, "dLocZ"); break; + + case OB_ROT_X: + strcpy(str, "RotX"); break; + case OB_ROT_Y: + strcpy(str, "RotY"); break; + case OB_ROT_Z: + strcpy(str, "RotZ"); break; + case OB_DROT_X: + strcpy(str, "dRotX"); break; + case OB_DROT_Y: + strcpy(str, "dRotY"); break; + case OB_DROT_Z: + strcpy(str, "dRotZ"); break; + + case OB_SIZE_X: + strcpy(str, "SizeX"); break; + case OB_SIZE_Y: + strcpy(str, "SizeY"); break; + case OB_SIZE_Z: + strcpy(str, "SizeZ"); break; + case OB_DSIZE_X: + strcpy(str, "dSizeX"); break; + case OB_DSIZE_Y: + strcpy(str, "dSizeY"); break; + case OB_DSIZE_Z: + strcpy(str, "dSizeZ"); break; + + case OB_LAY: + strcpy(str, "Layer"); break; + + case OB_TIME: + strcpy(str, "Time"); break; + case OB_EFF_X: + if(colipo) strcpy(str, "ColR"); + else strcpy(str, "EffX"); + break; + case OB_EFF_Y: + if(colipo) strcpy(str, "ColG"); + else strcpy(str, "EffY"); + break; + case OB_EFF_Z: + if(colipo) strcpy(str, "ColB"); + else strcpy(str, "EffZ"); + break; + case OB_COL_A: + strcpy(str, "ColA"); + break; + default: + str[0]= 0; + } +} + +void getname_tex_ei(int nr, char *str) +{ + switch(nr) { + case MAP_OFS_X: + strcpy(str, "OfsX"); break; + case MAP_OFS_Y: + strcpy(str, "OfsY"); break; + case MAP_OFS_Z: + strcpy(str, "OfsZ"); break; + case MAP_SIZE_X: + strcpy(str, "SizeX"); break; + case MAP_SIZE_Y: + strcpy(str, "SizeY"); break; + case MAP_SIZE_Z: + strcpy(str, "SizeZ"); break; + case MAP_R: + strcpy(str, "texR"); break; + case MAP_G: + strcpy(str, "texG"); break; + case MAP_B: + strcpy(str, "texB"); break; + case MAP_DVAR: + strcpy(str, "DefVar"); break; + case MAP_COLF: + strcpy(str, "Col"); break; + case MAP_NORF: + strcpy(str, "Nor"); break; + case MAP_VARF: + strcpy(str, "Var"); break; + default: + str[0]= 0; + } +} + +void getname_mat_ei(int nr, char *str) +{ + if(nr>=MA_MAP1) getname_tex_ei((nr & (MA_MAP1-1)), str); + else { + switch(nr) { + case MA_COL_R: + strcpy(str, "R"); break; + case MA_COL_G: + strcpy(str, "G"); break; + case MA_COL_B: + strcpy(str, "B"); break; + case MA_SPEC_R: + strcpy(str, "SpecR"); break; + case MA_SPEC_G: + strcpy(str, "SpecG"); break; + case MA_SPEC_B: + strcpy(str, "SpecB"); break; + case MA_MIR_R: + strcpy(str, "MirR"); break; + case MA_MIR_G: + strcpy(str, "MirG"); break; + case MA_MIR_B: + strcpy(str, "MirB"); break; + case MA_REF: + strcpy(str, "Ref"); break; + case MA_ALPHA: + strcpy(str, "Alpha"); break; + case MA_EMIT: + strcpy(str, "Emit"); break; + case MA_AMB: + strcpy(str, "Amb"); break; + case MA_SPEC: + strcpy(str, "Spec"); break; + case MA_HARD: + strcpy(str, "Hard"); break; + case MA_SPTR: + strcpy(str, "SpTra"); break; + case MA_ANG: + strcpy(str, "Ang"); break; + case MA_MODE: + strcpy(str, "Mode"); break; + case MA_HASIZE: + strcpy(str, "HaSize"); break; + default: + str[0]= 0; + } + } +} + +void getname_world_ei(int nr, char *str) +{ + if(nr>=MA_MAP1) getname_tex_ei((nr & (MA_MAP1-1)), str); + else { + switch(nr) { + case WO_HOR_R: + strcpy(str, "HorR"); break; + case WO_HOR_G: + strcpy(str, "HorG"); break; + case WO_HOR_B: + strcpy(str, "HorB"); break; + case WO_ZEN_R: + strcpy(str, "ZenR"); break; + case WO_ZEN_G: + strcpy(str, "ZenG"); break; + case WO_ZEN_B: + strcpy(str, "ZenB"); break; + + case WO_EXPOS: + strcpy(str, "Expos"); break; + + case WO_MISI: + strcpy(str, "Misi"); break; + case WO_MISTDI: + strcpy(str, "MisDi"); break; + case WO_MISTSTA: + strcpy(str, "MisSta"); break; + case WO_MISTHI: + strcpy(str, "MisHi"); break; + + case WO_STAR_R: + strcpy(str, "StarR"); break; + case WO_STAR_G: + strcpy(str, "StarB"); break; + case WO_STAR_B: + strcpy(str, "StarG"); break; + + case WO_STARDIST: + strcpy(str, "StarDi"); break; + case WO_STARSIZE: + strcpy(str, "StarSi"); break; + default: + str[0]= 0; + } + } +} + +void getname_seq_ei(int nr, char *str) +{ + switch(nr) { + case SEQ_FAC1: + strcpy(str, "Fac"); break; + default: + str[0]= 0; + } +} + +void getname_cu_ei(int nr, char *str) +{ + + switch(nr) { + case CU_SPEED: + strcpy(str, "Speed"); break; + default: + str[0]= 0; + } +} + +void getname_key_ei(int nr, char *str) +{ + if(nr==KEY_SPEED) strcpy(str, "Speed"); + else sprintf(str, "Key %d", nr); +} + +void getname_la_ei(int nr, char *str) +{ + if(nr>=MA_MAP1) getname_tex_ei((nr & (MA_MAP1-1)), str); + else { + switch(nr) { + case LA_ENERGY: + strcpy(str, "Energ"); break; + case LA_COL_R: + strcpy(str, "R"); break; + case LA_COL_G: + strcpy(str, "G"); break; + case LA_COL_B: + strcpy(str, "B"); break; + case LA_DIST: + strcpy(str, "Dist"); break; + case LA_SPOTSI: + strcpy(str, "SpoSi"); break; + case LA_SPOTBL: + strcpy(str, "SpoBl"); break; + case LA_QUAD1: + strcpy(str, "Quad1"); break; + case LA_QUAD2: + strcpy(str, "Quad2"); break; + case LA_HALOINT: + strcpy(str, "HaInt"); break; + default: + str[0]= 0; + } + } +} + +void getname_cam_ei(int nr, char *str) +{ + switch(nr) { + case CAM_LENS: + strcpy(str, "Lens"); break; + case CAM_STA: + strcpy(str, "ClSta"); break; + case CAM_END: + strcpy(str, "ClEnd"); break; + default: + str[0]= 0; + } +} + +void getname_snd_ei(int nr, char *str) +{ + switch(nr) { + case SND_VOLUME: + strcpy(str, "Vol"); break; + case SND_PITCH: + strcpy(str, "Pitch"); break; + case SND_PANNING: + strcpy(str, "Pan"); break; + case SND_ATTEN: + strcpy(str, "Atten"); break; + default: + str[0]= 0; + } +} + + +IpoCurve *find_ipocurve(Ipo *ipo, int adrcode) +{ + if(ipo) { + IpoCurve *icu= ipo->curve.first; + while(icu) { + if(icu->adrcode==adrcode) return icu; + icu= icu->next; + } + } + return NULL; +} + +void boundbox_ipocurve(IpoCurve *icu) +{ + BezTriple *bezt; + float vec[3]={0.0,0.0,0.0}; + float min[3], max[3]; + int a; + + if(icu->totvert) { + INIT_MINMAX(min, max); + + if(icu->bezt ) { + a= icu->totvert; + bezt= icu->bezt; + while(a--) { + if(icu->vartype & IPO_BITS) { + vec[0]= bezt->vec[1][0]; + vec[1]= 0.0; + DO_MINMAX(vec, min, max); + + vec[1]= 16.0; + DO_MINMAX(vec, min, max); + } + else { + if(icu->ipo==IPO_BEZ && a!=icu->totvert-1) { + DO_MINMAX(bezt->vec[0], min, max); + } + DO_MINMAX(bezt->vec[1], min, max); + if(icu->ipo==IPO_BEZ && a!=0) { + DO_MINMAX(bezt->vec[2], min, max); + } + } + + bezt++; + } + } + if(min[0]==max[0]) max[0]= (float)(min[0]+1.0); + if(min[1]==max[1]) max[1]= (float)(min[1]+0.1); + + icu->totrct.xmin= min[0]; + icu->totrct.ymin= min[1]; + icu->totrct.xmax= max[0]; + icu->totrct.ymax= max[1]; + } + else { + icu->totrct.xmin= icu->totrct.ymin= 0.0; + icu->totrct.xmax= EFRA; + icu->totrct.ymax= 1.0; + } +} + +void boundbox_ipo(Ipo *ipo, rctf *bb) +{ + IpoCurve *icu; + int first= 1; + + icu= ipo->curve.first; + while(icu) { + + boundbox_ipocurve(icu); + + if(first) { + *bb= icu->totrct; + first= 0; + } + else BLI_union_rctf(bb, &(icu->totrct)); + + icu= icu->next; + } +} + + + +void editipo_changed(SpaceIpo *si, int doredraw) +{ + EditIpo *ei; + View2D *v2d; + Key *key; + KeyBlock *kb; + int a, first=1; + + + ei= si->editipo; + if(ei==0) + return; + + for(a=0; a<si->totipo; a++, ei++) { + + if(ei->icu) { + + /* 2 keer i.v.m. ittereren nieuwe autohandle */ + calchandles_ipocurve(ei->icu); + calchandles_ipocurve(ei->icu); + + if(ei->flag & IPO_VISIBLE) { + + boundbox_ipocurve(ei->icu); + sort_time_ipocurve(ei->icu); + if(first) { + si->v2d.tot= ei->icu->totrct; + first= 0; + } + else BLI_union_rctf(&(si->v2d.tot), &(ei->icu->totrct)); + } + } + } + + v2d= &(si->v2d); +// v2d = &G.v2d; + + /* keylijnen? */ + if(si->blocktype==ID_KE) { + key= (Key *)si->from; + if(key && key->block.first) { + kb= key->block.first; + if(kb->pos < v2d->tot.ymin) v2d->tot.ymin= kb->pos; + kb= key->block.last; + if(kb->pos > v2d->tot.ymax) v2d->tot.ymax= kb->pos; + } + } + + + /* is er geen curve? */ + if(first) { + v2d->tot.xmin= 0.0; + v2d->tot.xmax= EFRA; + v2d->tot.ymin= (float)-0.1; + v2d->tot.ymax= (float)1.1; + + if(si->blocktype==ID_SEQ) { + v2d->tot.xmin= -5.0; + v2d->tot.xmax= 105.0; + v2d->tot.ymin= (float)-0.1; + v2d->tot.ymax= (float)1.1; + } + } + + si->tot= v2d->tot; + + if(doredraw) { + /* als do_ipo altijd wordt aangeroepen: problemen met insertkey, bijvoorbeeld + * als alleen een 'loc' wordt ge-insert wordt de 'ob->rot' veranderd. + */ + + + if(si->blocktype==ID_OB) { + /* clear delta loc,rot,size (bij ipo vrijgeven/deleten) */ + clear_delta_obipo(si->ipo); + + } + + do_ipo(si->ipo); + + allqueue(REDRAWIPO, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWBUTSANIM, 0); + + if(si->blocktype==ID_OB) { + Object *ob= (Object *)si->from; + if(ob && ob->type==OB_IKA) itterate_ika(ob); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWNLA, 0); + } + + else if(si->blocktype==ID_MA) allqueue(REDRAWBUTSMAT, 0); + else if(si->blocktype==ID_WO) allqueue(REDRAWBUTSWORLD, 0); + else if(si->blocktype==ID_LA) allqueue(REDRAWBUTSLAMP, 0); + else if(si->blocktype==ID_SO) allqueue(REDRAWBUTSSOUND, 0); + else if(si->blocktype==ID_CA) { + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + } + else if(si->blocktype==ID_SEQ) clear_last_seq(); + else if(si->blocktype==ID_AC){ + do_all_actions(); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + else if(si->blocktype==ID_KE) { + do_spec_key((Key *)si->from); + allqueue(REDRAWVIEW3D, 0); + } + else if(si->blocktype==ID_CU) { + calc_curvepath(OBACT); + allqueue(REDRAWVIEW3D, 0); + } + } + + if(si->showkey) make_ipokey(); +} + +void scale_editipo() +{ + /* komt uit buttons, scale met G.sipo->tot rect */ + + EditIpo *ei; + BezTriple *bezt; + float facx, facy; + int a, b; + + facx= (G.sipo->tot.xmax-G.sipo->tot.xmin)/(G.sipo->v2d.tot.xmax-G.sipo->v2d.tot.xmin); + facy= (G.sipo->tot.ymax-G.sipo->tot.ymin)/(G.sipo->v2d.tot.ymax-G.sipo->v2d.tot.ymin); + + ei= G.sipo->editipo; + if(ei==0) return; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + + bezt->vec[0][0]= facx*(bezt->vec[0][0] - G.sipo->v2d.tot.xmin) + G.sipo->tot.xmin; + bezt->vec[1][0]= facx*(bezt->vec[1][0] - G.sipo->v2d.tot.xmin) + G.sipo->tot.xmin; + bezt->vec[2][0]= facx*(bezt->vec[2][0] - G.sipo->v2d.tot.xmin) + G.sipo->tot.xmin; + + bezt->vec[0][1]= facy*(bezt->vec[0][1] - G.sipo->v2d.tot.ymin) + G.sipo->tot.ymin; + bezt->vec[1][1]= facy*(bezt->vec[1][1] - G.sipo->v2d.tot.ymin) + G.sipo->tot.ymin; + bezt->vec[2][1]= facy*(bezt->vec[2][1] - G.sipo->v2d.tot.ymin) + G.sipo->tot.ymin; + + bezt++; + } + } + } + editipo_changed(G.sipo, 1); + allqueue(REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); +} + + +Ipo *get_ipo_to_edit(ID **from) +{ + Object *ob= OBACT; + + *from= 0; + + + if (G.sipo->pin) { + *from = G.sipo->from; + return G.sipo->ipo; + } + + if(G.sipo->blocktype==ID_SEQ) { + extern Sequence *last_seq; + + *from= (ID *)last_seq; + if(last_seq) return last_seq->ipo; + } + else if(G.sipo->blocktype==IPO_CO){ + if (ob && ob->activecon){ + *from= (ID*) ob; + return ob->activecon->ipo; + } + } + else if(G.sipo->blocktype==ID_AC) { + bActionChannel *chan; + if (ob && ob->action){ + *from= (ID *) ob->action; + chan= get_hilighted_action_channel(ob->action); + if (chan) + return chan->ipo; + else{ + *from = NULL; + return NULL; + } + } + + } + else if(G.sipo->blocktype==ID_WO) { + World *wo= G.scene->world; + *from= (ID *)wo; + if(wo) return wo->ipo; + } + else if(G.sipo->blocktype==ID_OB) { + if(ob) { + *from= (ID *)ob; + return ob->ipo; + } + } + else if(G.sipo->blocktype==ID_MA) { + if(ob) { + Material *ma= give_current_material(ob, ob->actcol); + *from= (ID *)ma; + if(ma) return ma->ipo; + } + } + else if(G.sipo->blocktype==ID_KE) { + if(ob) { + Key *key= give_current_key(ob); + *from= (ID *)key; + if(key) return key->ipo; + } + } + else if(G.sipo->blocktype==ID_CU) { + if(ob && ob->type==OB_CURVE) { + Curve *cu= ob->data; + *from= (ID *)cu; + return cu->ipo; + } + } + else if(G.sipo->blocktype==ID_LA) { + if(ob && ob->type==OB_LAMP) { + Lamp *la= ob->data; + *from= (ID *)la; + return la->ipo; + } + } + else if(G.sipo->blocktype==ID_CA) { + if(ob && ob->type==OB_CAMERA) { + Camera *ca= ob->data; + *from= (ID *)ca; + if(ca) return ca->ipo; + } + } + else if(G.sipo->blocktype==ID_SO) { + + if (G.buts && G.buts->mainb == BUTS_SOUND) { + + bSound *sound = G.buts->lockpoin; + + *from= (ID *)sound; + + if(sound) return sound->ipo; + + } + } + + return NULL; +} + +unsigned int ipo_rainbow(int cur, int tot) +{ + float dfac, fac, sat; + + dfac= (float)(1.0/( (float)tot+1.0)); + + /* deze berekening zorgt voor twee verschillende cycles regenboogkleuren */ + if(cur< tot/2) fac= (float)(cur*2.0*dfac); + else fac= (float)((cur-tot/2)*2.0*dfac +dfac); + + if(fac>0.5 && fac<0.8) sat= (float)0.4; + else sat= 0.5; + + return hsv_to_cpack(fac, sat, 1.0); +} + +void make_ob_editipo(Object *ob, SpaceIpo *si) +{ + EditIpo *ei; + int a, len, colipo=0; + + if(ob->type==OB_MESH) colipo= 1; + + ei= si->editipo= MEM_callocN(OB_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= OB_TOTIPO; + + for(a=0; a<OB_TOTIPO; a++) { + getname_ob_ei(ob_ar[a], ei->name, colipo); + ei->adrcode= ob_ar[a]; + + if ELEM6(ei->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z) ei->disptype= IPO_DISPDEGR; + else if(ei->adrcode==OB_LAY) ei->disptype= IPO_DISPBITS; + else if(ei->adrcode==OB_TIME) ei->disptype= IPO_DISPTIME; + + ei->col= ipo_rainbow(a, OB_TOTIPO); + + if(colipo) { + len= strlen(ei->name); + if(len) { + if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF; + else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50; + else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050; + } + } + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + + +void make_seq_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(SEQ_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= SEQ_TOTIPO; + + + for(a=0; a<SEQ_TOTIPO; a++) { + getname_seq_ei(seq_ar[a], ei->name); + ei->adrcode= seq_ar[a]; + + ei->col= ipo_rainbow(a, SEQ_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + else ei->flag |= IPO_VISIBLE; + + ei++; + } +} + +void make_cu_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(CU_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= CU_TOTIPO; + + + for(a=0; a<CU_TOTIPO; a++) { + getname_cu_ei(cu_ar[a], ei->name); + ei->adrcode= cu_ar[a]; + + ei->col= ipo_rainbow(a, CU_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + else ei->flag |= IPO_VISIBLE; + + ei++; + } +} + +void make_key_editipo(SpaceIpo *si) +{ + Key *key; + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(KEY_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= KEY_TOTIPO; + + for(a=0; a<KEY_TOTIPO; a++) { + getname_key_ei(key_ar[a], ei->name); + ei->adrcode= key_ar[a]; + + ei->col= ipo_rainbow(a, KEY_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + else if(a==0) ei->flag |= IPO_VISIBLE; + + ei++; + } + + ei= si->editipo; + key= (Key *)G.sipo->from; + if(key && key->type==KEY_RELATIVE) { + strcpy(ei->name, "----"); + } + else { + ei->flag |= IPO_VISIBLE; + } +} + +int texchannel_to_adrcode(int channel) +{ + switch(channel) { + case 0: return MA_MAP1; + case 1: return MA_MAP2; + case 2: return MA_MAP3; + case 3: return MA_MAP4; + case 4: return MA_MAP5; + case 5: return MA_MAP6; + case 6: return MA_MAP7; + case 7: return MA_MAP8; + default: return 0; + } +} + +void make_mat_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a, len; + + if(si->from==0) return; + + ei= si->editipo= MEM_callocN(MA_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= MA_TOTIPO; + + for(a=0; a<MA_TOTIPO; a++) { + getname_mat_ei(ma_ar[a], ei->name); + ei->adrcode= ma_ar[a]; + + if(ei->adrcode & MA_MAP1) { + ei->adrcode-= MA_MAP1; + ei->adrcode |= texchannel_to_adrcode(si->channel); + } + else { + /* dit was weggecommentaard. Waarom? */ + if(ei->adrcode==MA_MODE) ei->disptype= IPO_DISPBITS; + } + + ei->col= ipo_rainbow(a, WO_TOTIPO); + + len= strlen(ei->name); + if(len) { + if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF; + else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50; + else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050; + } + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +void make_world_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a, len; + + if(si->from==0) return; + + ei= si->editipo= MEM_callocN(WO_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= WO_TOTIPO; + + for(a=0; a<WO_TOTIPO; a++) { + getname_world_ei(wo_ar[a], ei->name); + ei->adrcode= wo_ar[a]; + + if(ei->adrcode & MA_MAP1) { + ei->adrcode-= MA_MAP1; + ei->adrcode |= texchannel_to_adrcode(si->channel); + } + else { + if(ei->adrcode==MA_MODE) ei->disptype= IPO_DISPBITS; + } + + ei->col= ipo_rainbow(a, MA_TOTIPO); + + len= strlen(ei->name); + if(len) { + if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF; + else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50; + else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050; + } + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +void make_lamp_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(LA_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= LA_TOTIPO; + + + for(a=0; a<LA_TOTIPO; a++) { + getname_la_ei(la_ar[a], ei->name); + ei->adrcode= la_ar[a]; + + if(ei->adrcode & MA_MAP1) { + ei->adrcode-= MA_MAP1; + ei->adrcode |= texchannel_to_adrcode(si->channel); + } + + ei->col= ipo_rainbow(a, LA_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +void make_camera_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(CAM_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= CAM_TOTIPO; + + + for(a=0; a<CAM_TOTIPO; a++) { + getname_cam_ei(cam_ar[a], ei->name); + ei->adrcode= cam_ar[a]; + + ei->col= ipo_rainbow(a, CAM_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +int make_constraint_editipo(Ipo *ipo, EditIpo **si) +{ + EditIpo *ei; + int a; + + ei= *si= MEM_callocN(CO_TOTIPO*sizeof(EditIpo), "editipo"); + + for(a=0; a<CO_TOTIPO; a++) { + getname_co_ei(co_ar[a], ei->name); + ei->adrcode= co_ar[a]; + + ei->col= ipo_rainbow(a, CO_TOTIPO); + + ei->icu= find_ipocurve(ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } + + return CO_TOTIPO; +} +int make_action_editipo(Ipo *ipo, EditIpo **si) +{ + EditIpo *ei; + int a; + + ei= *si= MEM_callocN(AC_TOTIPO*sizeof(EditIpo), "editipo"); + + for(a=0; a<AC_TOTIPO; a++) { + getname_ac_ei(ac_ar[a], ei->name); + ei->adrcode= ac_ar[a]; + + ei->col= ipo_rainbow(a, AC_TOTIPO); + + ei->icu= find_ipocurve(ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } + + return AC_TOTIPO; +} + +void make_sound_editipo(SpaceIpo *si) +{ + EditIpo *ei; + int a; + + ei= si->editipo= MEM_callocN(SND_TOTIPO*sizeof(EditIpo), "editipo"); + + si->totipo= SND_TOTIPO; + + + for(a=0; a<SND_TOTIPO; a++) { + getname_snd_ei(snd_ar[a], ei->name); + ei->adrcode= snd_ar[a]; + + ei->col= ipo_rainbow(a, SND_TOTIPO); + + ei->icu= find_ipocurve(si->ipo, ei->adrcode); + if(ei->icu) { + ei->flag= ei->icu->flag; + } + + ei++; + } +} + +void make_editipo() +{ + EditIpo *ei; + Object *ob; + ID *from; + rctf *rf; + int a; + + if(G.sipo->editipo) + MEM_freeN(G.sipo->editipo); + G.sipo->editipo= 0; + G.sipo->totipo= 0; + ob= OBACT; + + G.sipo->ipo= get_ipo_to_edit(&from); + G.sipo->from= from; + + if(G.sipo->ipo) G.sipo->showkey= G.sipo->ipo->showkey; + + if(G.sipo->blocktype==ID_SEQ) { + make_seq_editipo(G.sipo); + } + else if(G.sipo->blocktype==ID_WO) { + make_world_editipo(G.sipo); + } + else if(G.sipo->blocktype==ID_OB) { + if (ob) { + ob->ipowin= ID_OB; + make_ob_editipo(ob, G.sipo); + } + } + else if(G.sipo->blocktype==ID_MA) { + if (ob) { + ob->ipowin= ID_MA; + make_mat_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_CU) { + if (ob) { + ob->ipowin= ID_CU; + make_cu_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_KE) { + if (ob) { + ob->ipowin= ID_KE; + make_key_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_LA) { + if (ob) { + ob->ipowin= ID_LA; + make_lamp_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_CA) { + if (ob) { + ob->ipowin= ID_CA; + make_camera_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==ID_SO) { + if (ob) { + ob->ipowin= ID_SO; + make_sound_editipo(G.sipo); + } + } + else if(G.sipo->blocktype==IPO_CO){ + G.sipo->totipo = make_constraint_editipo(G.sipo->ipo, (EditIpo**)&G.sipo->editipo); + if (ob) { + ob->ipowin= IPO_CO; + } + } + else if(G.sipo->blocktype==ID_AC) { + + G.sipo->totipo = make_action_editipo(G.sipo->ipo, (EditIpo**)&G.sipo->editipo); + if (ob) { + ob->ipowin= ID_AC; + } + } + + if(G.sipo->editipo==0) return; + + /* rowbut voor VISIBLE select */ + G.sipo->rowbut= 0; + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if(ei->flag & IPO_VISIBLE) G.sipo->rowbut |= (1<<a); + + if(ei->icu) ei->icu->flag= ei->flag; + } + editipo_changed(G.sipo, 0); + + if(G.sipo->ipo) { + + if (G.sipo->pin) + rf= &(G.sipo->v2d.cur); + else + rf= &(G.sipo->ipo->cur); + + if(rf->xmin<rf->xmax && rf->ymin<rf->ymax) G.v2d->cur= *rf; + + } + else { + if(G.sipo->blocktype==ID_OB) { + G.v2d->cur.xmin= 0.0; + G.v2d->cur.xmax= EFRA; + G.v2d->cur.ymin= -5.0; + G.v2d->cur.ymax= +5.0; + } + else if(G.sipo->blocktype==ID_CA) { + G.v2d->cur.xmin= 0.0; + G.v2d->cur.xmax= EFRA; + G.v2d->cur.ymin= 0.0; + G.v2d->cur.ymax= 100.0; + } + else if ELEM5(G.sipo->blocktype, ID_MA, ID_CU, ID_WO, ID_LA, IPO_CO) { + G.v2d->cur.xmin= (float)-0.1; + G.v2d->cur.xmax= EFRA; + G.v2d->cur.ymin= (float)-0.1; + G.v2d->cur.ymax= (float)+1.1; + } + else if(G.sipo->blocktype==ID_SEQ) { + G.v2d->cur.xmin= -5.0; + G.v2d->cur.xmax= 105.0; + G.v2d->cur.ymin= (float)-0.1; + G.v2d->cur.ymax= (float)+1.1; + } + else if(G.sipo->blocktype==ID_KE) { + G.v2d->cur.xmin= (float)-0.1; + G.v2d->cur.xmax= EFRA; + G.v2d->cur.ymin= (float)-0.1; + G.v2d->cur.ymax= (float)+2.1; + } + + } +} + + +void test_editipo() +{ + Ipo *ipo; + ID *from; + + if(G.sipo->editipo==0){ + make_editipo(); + } + else { + ipo= get_ipo_to_edit(&from); + + if(G.sipo->ipo != ipo || G.sipo->from!=from) + make_editipo(); + + } + + if (G.sipo->pin) + return; + + + if(G.sipo->ipo) + G.sipo->ipo->cur = G.v2d->cur; + +} + +/* ****************************************** */ + +int totipo_edit, totipo_sel, totipo_vis, totipo_vert, totipo_vertsel, totipo_key, totipo_keysel; + +void get_status_editipo() +{ + EditIpo *ei; + IpoKey *ik; + BezTriple *bezt; + int a, b; + + totipo_vis= 0; + totipo_sel= 0; + totipo_edit= 0; + totipo_vert= 0; + totipo_vertsel= 0; + totipo_key= 0; + totipo_keysel= 0; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + ei= G.sipo->editipo; + if(ei==0) return; + for(a=0; a<G.sipo->totipo; a++) { + if( ei->flag & IPO_VISIBLE ) { + totipo_vis++; + if(ei->flag & IPO_SELECT) totipo_sel++; + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + + /* als showkey: wel de vertices tellen (voor grab) */ + if(G.sipo->showkey==0) totipo_edit++; + + if(ei->icu) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(ei->icu->ipo==IPO_BEZ) { + if(bezt->f1 & 1) totipo_vertsel++; + if(bezt->f3 & 1) totipo_vertsel++; + totipo_vert+= 2; + } + if(bezt->f2 & 1) totipo_vertsel++; + + totipo_vert++; + bezt++; + } + } + } + } + } + ei++; + } + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + totipo_key++; + if(ik->flag & 1) totipo_keysel++; + ik= ik->next; + } + } +} + + + +void update_editipo_flags() +{ + EditIpo *ei; + IpoKey *ik; + unsigned int flag; + int a; + + ei= G.sipo->editipo; + if(ei) { + for(a=0; a<G.sipo->totipo; a++, ei++) { + ei->flag &= ~IPO_VISIBLE; + flag= (1<<a); + if( G.sipo->rowbut & flag ) ei->flag |= IPO_VISIBLE; + + if(ei->icu) ei->icu->flag= ei->flag; + + } + } + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + if(ik->flag & 1) { + ik->data[a]->f1 |= 1; + ik->data[a]->f2 |= 1; + ik->data[a]->f3 |= 1; + } + else { + ik->data[a]->f1 &= ~1; + ik->data[a]->f2 &= ~1; + ik->data[a]->f3 &= ~1; + } + } + } + ik= ik->next; + } + } +} + +void set_editflag_editipo() +{ + EditIpo *ei; + int a; /* , tot= 0, ok= 0; */ + + /* van showkey direkt door naar editen geselecteerde punten */ + if(G.sipo->showkey) { + G.sipo->showkey= 0; + if(G.sipo->ipo) G.sipo->ipo->showkey= 0; + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) ei->flag |= IPO_SELECT; + scrarea_queue_headredraw(curarea); + allqueue(REDRAWVIEW3D, 0); + } + + get_status_editipo(); + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if(ei->icu) { + if(ei->flag & IPO_VISIBLE) { + + if(totipo_edit==0 && (ei->flag & IPO_SELECT)) { + ei->flag |= IPO_EDIT; + ei->icu->flag= ei->flag; + } + else if(totipo_edit && (ei->flag & IPO_EDIT)) { + ei->flag -= IPO_EDIT; + ei->icu->flag= ei->flag; + } + else if(totipo_vis==1) { + if(ei->flag & IPO_EDIT) ei->flag -= IPO_EDIT; + else ei->flag |= IPO_EDIT; + ei->icu->flag= ei->flag; + } + } + } + } + + scrarea_queue_winredraw(curarea); +} + +void swap_selectall_editipo() +{ + Object *ob; + EditIpo *ei; + IpoKey *ik; + BezTriple *bezt; + int a, b; /* , sel=0; */ + + + deselectall_key(); + + get_status_editipo(); + + + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + if(totipo_vertsel) ik->flag &= ~1; + else ik->flag |= 1; + ik= ik->next; + } + update_editipo_flags(); + + if(G.sipo->showkey && G.sipo->blocktype==ID_OB ) { + ob= OBACT; + if(ob && (ob->ipoflag & OB_DRAWKEY)) draw_object_ext(BASACT); + } + } + else if(totipo_edit==0) { + ei= G.sipo->editipo; + if (ei){ + for(a=0; a<G.sipo->totipo; a++) { + if( ei->flag & IPO_VISIBLE ) { + if(totipo_sel) ei->flag &= ~IPO_SELECT; + else ei->flag |= IPO_SELECT; + } + ei++; + } + update_editipo_flags(); + } + } + else { + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu ) { + bezt= ei->icu->bezt; + if(bezt) { + b= ei->icu->totvert; + while(b--) { + if(totipo_vertsel) { + bezt->f1= bezt->f2= bezt->f3= 0; + } + else { + bezt->f1= bezt->f2= bezt->f3= 1; + } + bezt++; + } + } + } + ei++; + } + + } + + scrarea_queue_winredraw(curarea); + +} + +void swap_visible_editipo() +{ + EditIpo *ei; + Object *ob; + int a; /* , sel=0; */ + + get_status_editipo(); + + G.sipo->rowbut= 0; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if(totipo_vis==0) { + if(ei->icu) { + ei->flag |= IPO_VISIBLE; + G.sipo->rowbut |= (1<<a); + } + } + else ei->flag &= ~IPO_VISIBLE; + ei++; + } + + update_editipo_flags(); + + if(G.sipo->showkey) { + + make_ipokey(); + + ob= OBACT; + if(ob && (ob->ipoflag & OB_DRAWKEY)) allqueue(REDRAWVIEW3D, 0); + } + + scrarea_queue_winredraw(curarea); + +} + +void deselectall_editipo() +{ + EditIpo *ei; + IpoKey *ik; + BezTriple *bezt; + int a, b; /* , sel=0; */ + + deselectall_key(); + + get_status_editipo(); + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + ik->flag &= ~1; + ik= ik->next; + } + update_editipo_flags(); + + } + else if(totipo_edit==0) { + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if( ei->flag & IPO_VISIBLE ) { + ei->flag &= ~IPO_SELECT; + } + ei++; + } + update_editipo_flags(); + } + else { + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu ) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + bezt->f1= bezt->f2= bezt->f3= 0; + bezt++; + } + } + } + ei++; + } + } + + scrarea_queue_winredraw(curarea); +} + +short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt) +{ + /* selected krijgen een nadeel */ + /* in icu en (bezt of bp) wordt nearest weggeschreven */ + /* return 0 1 2: handlepunt */ + EditIpo *ei; + BezTriple *bezt1; + int a, b; + short dist= 100, temp, mval[2], hpoint=0; + + *icu= 0; + *bezt= 0; + + getmouseco_areawin(mval); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu) { + + if(ei->icu->bezt) { + bezt1= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + + ipoco_to_areaco_noclip(G.v2d, bezt1->vec[0], bezt1->s[0]); + ipoco_to_areaco_noclip(G.v2d, bezt1->vec[1], bezt1->s[1]); + ipoco_to_areaco_noclip(G.v2d, bezt1->vec[2], bezt1->s[2]); + + if(ei->disptype==IPO_DISPBITS) { + temp= abs(mval[0]- bezt1->s[1][0]); + } + else temp= abs(mval[0]- bezt1->s[1][0])+ abs(mval[1]- bezt1->s[1][1]); + + if( bezt1->f2 & 1) temp+=5; + if(temp<dist) { + hpoint= 1; + *bezt= bezt1; + dist= temp; + *icu= ei->icu; + } + + if(ei->disptype!=IPO_DISPBITS && ei->icu->ipo==IPO_BEZ) { + /* middelste punten een klein voordeel */ + temp= -3+abs(mval[0]- bezt1->s[0][0])+ abs(mval[1]- bezt1->s[0][1]); + if( bezt1->f1 & 1) temp+=5; + if(temp<dist) { + hpoint= 0; + *bezt= bezt1; + dist= temp; + *icu= ei->icu; + } + + temp= abs(mval[0]- bezt1->s[2][0])+ abs(mval[1]- bezt1->s[2][1]); + if( bezt1->f3 & 1) temp+=5; + if(temp<dist) { + hpoint= 2; + *bezt=bezt1; + dist= temp; + *icu= ei->icu; + } + } + bezt1++; + } + } + } + } + + return hpoint; +} + + +void move_to_frame() +{ + EditIpo *ei; + BezTriple *bezt; + ID *id; + float cfra; + int a, b; + + if(G.sipo->editipo==0) return; + + ei= G.sipo->editipo; + + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + + if(ei->icu->bezt) { + + b= ei->icu->totvert; + bezt= ei->icu->bezt; + while(b--) { + if(BEZSELECTED(bezt)) { + + cfra= bezt->vec[1][0]/G.scene->r.framelen; + + id= G.sipo->from; + if(id && GS(id->name)==ID_OB ) { + Object *ob= (Object *)id; + if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) { + cfra+= ob->sf/G.scene->r.framelen; + } + } + CFRA= (short)floor(cfra+0.5); + + if(CFRA < 1) CFRA= 1; + update_for_newframe(); + + break; + } + bezt++; + } + } + } + } + } +} + +/* *********************************** */ + +void do_ipowin_buts(short event) +{ + if((G.qual & LR_SHIFTKEY)==0) { + G.sipo->rowbut= (1<<event); + } + scrarea_queue_winredraw(curarea); + + update_editipo_flags(); + + if(G.sipo->showkey) { + make_ipokey(); + if(G.sipo->blocktype==ID_OB) allqueue(REDRAWVIEW3D, 0); + } + +} + +void do_ipo_selectbuttons() +{ + EditIpo *ei, *ei1; + int a, nr; + short mval[2]; + + if(G.sipo->showkey) return; + + /* geen editipo toestaan: editipo's naar selected omzetten */ + get_status_editipo(); + if(totipo_edit) { + set_editflag_editipo(); + } + + /* welke */ + getmouseco_areawin(mval); + + nr= -(mval[1]-curarea->winy+30-G.sipo->butofs-IPOBUTY)/IPOBUTY; + if(nr>=0 && nr<G.sipo->totipo) { + ei= G.sipo->editipo; + ei+= nr; + + if(ei->icu) { + if((ei->flag & IPO_VISIBLE)==0) { + ei->flag |= IPO_VISIBLE; + G.sipo->rowbut |= (1<<nr); + } + + if((G.qual & LR_SHIFTKEY)==0) { + ei1= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + ei1->flag &= ~IPO_SELECT; + ei1++; + } + } + + if(ei->flag & IPO_SELECT) { + ei->flag &= ~IPO_SELECT; + } + else { + ei->flag |= IPO_SELECT; + } + + update_editipo_flags(); + scrarea_queue_winredraw(curarea); + } + } +} + +/* ******************************************* */ + +EditIpo *get_editipo() +{ + EditIpo *ei; + int a; /* , sel=0; */ + + get_status_editipo(); + + if(totipo_edit>1) { + error("Too many editipo's"); + return 0; + } + if(G.sipo->editipo==0) return 0; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if(ei->flag & IPO_VISIBLE) { + if( ei->flag & IPO_EDIT ) return ei; + else if(totipo_vis==1) return ei; + + if(ei->flag & IPO_SELECT) { + if(totipo_sel==1) return ei; + } + } + ei++; + } + return 0; +} + + +static Ipo *get_ipo(ID *from, short type, int make) +{ + Object *ob; + Material *ma; + Curve *cu; + Sequence *seq; + Key *key; + World *wo; + Lamp *la; + Camera *ca; + Ipo *ipo= 0; + bAction *act; + + if( type==ID_OB) { + ob= (Object *)from; + if(ob->id.lib) return 0; + + ipo= ob->ipo; + if(make && ipo==0) ipo= ob->ipo= add_ipo("ObIpo", ID_OB); + } + else if( type==IPO_CO){ + ob= (Object *)from; + if(ob->id.lib) return 0; + + if (ob->activecon){ + ipo= ob->activecon->ipo; + if(make && ipo==0) ipo= ob->activecon->ipo= add_ipo("CoIpo", IPO_CO); + } + } + else if( type==ID_AC) { + act= (bAction *)from; + if (!act->achan) return 0; + if (act->id.lib) return 0; + ipo= act->achan->ipo; + + /* This should never happen */ + if(make && ipo==0) ipo= act->achan->ipo= add_ipo("AcIpo", ID_AC); + } + else if( type==ID_MA) { + ma= (Material *)from; + if(ma->id.lib) return 0; + ipo= ma->ipo; + + if(make && ipo==0) ipo= ma->ipo= add_ipo("MatIpo", ID_MA); + } + + else if( type==ID_SEQ) { + seq= (Sequence *)from; + + if(seq->type & SEQ_EFFECT) { + ipo= seq->ipo; + if(make && ipo==0) ipo= seq->ipo= add_ipo("SeqIpo", ID_SEQ); + } + else return 0; + } + else if( type==ID_CU) { + cu= (Curve *)from; + if(cu->id.lib) return 0; + ipo= cu->ipo; + + if(make && ipo==0) ipo= cu->ipo= add_ipo("CuIpo", ID_CU); + } + else if( type==ID_KE) { + key= (Key *)from; + if(key->id.lib) return 0; + ipo= key->ipo; + + if(make && ipo==0) ipo= key->ipo= add_ipo("KeyIpo", ID_KE); + } + else if( type==ID_WO) { + wo= (World *)from; + if(wo->id.lib) return 0; + ipo= wo->ipo; + + if(make && ipo==0) ipo= wo->ipo= add_ipo("WoIpo", ID_WO); + } + else if( type==ID_LA) { + la= (Lamp *)from; + if(la->id.lib) return 0; + ipo= la->ipo; + + if(make && ipo==0) ipo= la->ipo= add_ipo("LaIpo", ID_LA); + } + else if( type==ID_CA) { + ca= (Camera *)from; + if(ca->id.lib) return 0; + ipo= ca->ipo; + + if(make && ipo==0) ipo= ca->ipo= add_ipo("CaIpo", ID_CA); + } + else if( type==ID_SO) { + bSound *snd= (bSound *)from; + if(snd->id.lib) return 0; + ipo= snd->ipo; + + if(make && ipo==0) ipo= snd->ipo= add_ipo("SndIpo", ID_SO); + } + else return 0; + + return ipo; +} + + +// this function should not have the G.sipo in it... + +IpoCurve *get_ipocurve(ID *from, short type, int adrcode, Ipo *useipo) +{ + Ipo *ipo= 0; + IpoCurve *icu=0; + + /* return 0 als lib */ + /* ook testen of ipo en ipocurve bestaan */ + + if (useipo==NULL) { + + if (G.sipo==NULL || G.sipo->pin==0){ + ipo= get_ipo(from, type, 1); /* 1= make */ + } + else + ipo = G.sipo->ipo; + + + if(G.sipo) { + if (G.sipo->pin==0) G.sipo->ipo= ipo; + } + } + else + ipo= useipo; + + + if(ipo && ipo->id.lib==0) { + + icu= ipo->curve.first; + while(icu) { + if(icu->adrcode==adrcode) break; + icu= icu->next; + } + if(icu==0) { + icu= MEM_callocN(sizeof(IpoCurve), "ipocurve"); + + icu->flag |= IPO_VISIBLE; + + if (!useipo && G.sipo && G.sipo->pin) + icu->blocktype = G.sipo->blocktype; + else + icu->blocktype= type; + icu->adrcode= adrcode; + + set_icu_vars(icu); + + BLI_addtail( &(ipo->curve), icu); + } + } + return icu; +} + +void insert_vert_ipo(IpoCurve *icu, float x, float y) +{ + BezTriple *bezt, beztr, *newbezt; + int a = 0, h1, h2; + + memset(&beztr, 0, sizeof(BezTriple)); + beztr.vec[1][0]= x; + beztr.vec[1][1]= y; + beztr.hide= IPO_BEZ; + beztr.f1= beztr.f2= beztr.f3= SELECT; + beztr.h1= beztr.h2= HD_AUTO; + + bezt= icu->bezt; + + if(bezt==0) { + icu->bezt= MEM_callocN( sizeof(BezTriple), "beztriple"); + *(icu->bezt)= beztr; + icu->totvert= 1; + } + else { + /* alle vertices deselect */ + for(a=0; a<icu->totvert; a++, bezt++) { + bezt->f1= bezt->f2= bezt->f3= 0; + } + + bezt= icu->bezt; + for(a=0; a<=icu->totvert; a++, bezt++) { + + /* geen dubbele punten */ + if(a<icu->totvert && (bezt->vec[1][0]>x-IPOTHRESH && bezt->vec[1][0]<x+IPOTHRESH)) { + *(bezt)= beztr; + break; + } + if(a==icu->totvert || bezt->vec[1][0] > x) { + newbezt= MEM_callocN( (icu->totvert+1)*sizeof(BezTriple), "beztriple"); + + if(a>0) memcpy(newbezt, icu->bezt, a*sizeof(BezTriple)); + + bezt= newbezt+a; + *(bezt)= beztr; + + if(a<icu->totvert) memcpy(newbezt+a+1, icu->bezt+a, (icu->totvert-a)*sizeof(BezTriple)); + + MEM_freeN(icu->bezt); + icu->bezt= newbezt; + + icu->totvert++; + break; + } + } + } + + + calchandles_ipocurve(icu); + + /* handletype goedzetten */ + if(icu->totvert>2) { + h1= h2= HD_AUTO; + if(a>0) h1= (bezt-1)->h2; + if(a<icu->totvert-1) h2= (bezt+1)->h1; + bezt->h1= h1; + bezt->h2= h2; + + calchandles_ipocurve(icu); + } +} + +void add_vert_ipo() +{ + EditIpo *ei; + float x, y; + int val; + short mval[2]; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + if(G.sipo->showkey) { + G.sipo->showkey= 0; + free_ipokey(&G.sipo->ipokey); + } + + getmouseco_areawin(mval); + + if(mval[0]>G.v2d->mask.xmax) return; + + ei= get_editipo(); + if(ei==0) return; + + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + + if(ei->icu==0) { + if(G.sipo->from) + ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0); + } + if(ei->icu==0) return; + + if(ei->disptype==IPO_DISPBITS) { + ei->icu->vartype= IPO_BITS; + val= (int)floor(y-0.5); + if(val<0) val= 0; + y= (float)(1 << val); + } + + insert_vert_ipo(ei->icu, x, y); + + /* voor zekerheid: als icu 0 was, of maar 1 curve visible */ + ei->flag |= IPO_SELECT; + ei->icu->flag= ei->flag; + + editipo_changed(G.sipo, 1); +} + +void add_duplicate_editipo() +{ + Object *ob; + EditIpo *ei; + IpoCurve *icu; + BezTriple *bezt, *beztn, *newb; + int tot, a, b; + + get_status_editipo(); + if(totipo_vertsel==0) return; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + icu= ei->icu; + + /* hoeveel punten */ + tot= 0; + b= icu->totvert; + bezt= icu->bezt; + while(b--) { + if(bezt->f2 & 1) tot++; + bezt++; + } + + if(tot) { + icu->totvert+= tot; + newb= beztn= MEM_mallocN(icu->totvert*sizeof(BezTriple), "bezt"); + bezt= icu->bezt; + b= icu->totvert-tot; + while(b--) { + *beztn= *bezt; + if(bezt->f2 & 1) { + beztn->f1= beztn->f2= beztn->f3= 0; + beztn++; + *beztn= *bezt; + } + beztn++; + bezt++; + } + MEM_freeN(icu->bezt); + icu->bezt= newb; + + calchandles_ipocurve(icu); + } + } + } + } + + if(G.sipo->showkey) { + make_ipokey(); + if(G.sipo->blocktype==ID_OB) { + ob= OBACT; + if(ob && (ob->ipoflag & OB_DRAWKEY)) allqueue(REDRAWVIEW3D, 0); + } + } + transform_ipo('g'); +} + +void remove_doubles_ipo() +{ + EditIpo *ei; + IpoKey *ik, *ikn; + BezTriple *bezt, *newb, *new1; + float val; + int mode, a, b; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + + /* OF de curve is selected OF in editmode OF in keymode */ + mode= 0; + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) mode= 1; + else if(ei->flag & IPO_SELECT) mode= 2; + + if(mode) { + bezt= ei->icu->bezt; + newb= new1= MEM_mallocN(ei->icu->totvert*sizeof(BezTriple), "newbezt"); + *newb= *bezt; + b= ei->icu->totvert-1; + bezt++; + while(b--) { + + /* mag er verwijderd worden? */ + if(mode==2 || (bezt->f2 & 1)) { + + /* verschillen de punten? */ + if( fabs( bezt->vec[1][0]-newb->vec[1][0] ) > 0.9 ) { + newb++; + *newb= *bezt; + } + else { + /* gemiddelde */ + VecMidf(newb->vec[0], newb->vec[0], bezt->vec[0]); + VecMidf(newb->vec[1], newb->vec[1], bezt->vec[1]); + VecMidf(newb->vec[2], newb->vec[2], bezt->vec[2]); + + newb->h1= newb->h2= HD_FREE; + + ei->icu->totvert--; + } + + } + else { + newb++; + *newb= *bezt; + } + bezt++; + } + + MEM_freeN(ei->icu->bezt); + ei->icu->bezt= new1; + + calchandles_ipocurve(ei->icu); + } + } + } + + editipo_changed(G.sipo, 1); /* maakt ook ipokeys opnieuw! */ + + /* dubbele keys weg */ + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + ikn= ik->next; + + while(ik && ikn) { + if( (ik->flag & 1) && (ikn->flag & 1) ) { + if( fabs(ik->val-ikn->val) < 0.9 ) { + val= (float)((ik->val + ikn->val)/2.0); + + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) ik->data[a]->vec[1][0]= val; + if(ikn->data[a]) ikn->data[a]->vec[1][0]= val; + } + } + } + ik= ikn; + ikn= ikn->next; + + } + + editipo_changed(G.sipo, 1); /* maakt ook ipokeys opnieuw! */ + + } + deselectall_editipo(); +} + +void join_ipo() +{ + EditIpo *ei; + IpoKey *ik; + IpoCurve *icu; + BezTriple *bezt, *beztn, *newb; + float val; + int mode, tot, a, b; + + get_status_editipo(); + + mode= pupmenu("Join %t|All Selected %x1|Selected doubles %x2"); + if( mode==2 ) { + remove_doubles_ipo(); + return; + } + else if(mode!=1) return; + + /* eerst: meerdere geselecteerde verts in 1 curve */ + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + icu= ei->icu; + + /* hoeveel punten */ + tot= 0; + b= icu->totvert; + bezt= icu->bezt; + while(b--) { + if(bezt->f2 & 1) tot++; + bezt++; + } + + if(tot>1) { + tot--; + icu->totvert-= tot; + + newb= MEM_mallocN(icu->totvert*sizeof(BezTriple), "bezt"); + /* het eerste punt wordt het nieuwe punt */ + beztn= newb+1; + tot= 0; + + bezt= icu->bezt; + b= icu->totvert+tot+1; + while(b--) { + + if(bezt->f2 & 1) { + if(tot==0) *newb= *bezt; + else { + VecAddf(newb->vec[0], newb->vec[0], bezt->vec[0]); + VecAddf(newb->vec[1], newb->vec[1], bezt->vec[1]); + VecAddf(newb->vec[2], newb->vec[2], bezt->vec[2]); + } + tot++; + } + else { + *beztn= *bezt; + beztn++; + } + bezt++; + } + + VecMulf(newb->vec[0], (float)(1.0/((float)tot))); + VecMulf(newb->vec[1], (float)(1.0/((float)tot))); + VecMulf(newb->vec[2], (float)(1.0/((float)tot))); + + MEM_freeN(icu->bezt); + icu->bezt= newb; + + sort_time_ipocurve(icu); + calchandles_ipocurve(icu); + } + } + } + } + + /* dan: in keymode: meerdere geselecteerde keys samenvoegen */ + + editipo_changed(G.sipo, 1); /* maakt ook ipokeys opnieuw! */ + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + val= 0.0; + tot= 0; + while(ik) { + if(ik->flag & 1) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + val+= ik->data[a]->vec[1][0]; + break; + } + } + tot++; + } + ik= ik->next; + } + if(tot>1) { + val/= (float)tot; + + ik= G.sipo->ipokey.first; + while(ik) { + if(ik->flag & 1) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + ik->data[a]->vec[1][0]= val; + } + } + } + ik= ik->next; + } + editipo_changed(G.sipo, 0); + } + } + deselectall_editipo(); +} + +void ipo_snapmenu() +{ + EditIpo *ei; + BezTriple *bezt; + float dx = 0.0; + int a, b; + short event, ok, ok2; + + event= pupmenu("Snap %t|Horizontal %x1|To next %x2|To frame %x3|To current frame%x4"); + if(event < 1) return; + + get_status_editipo(); + + ei= G.sipo->editipo; + for(b=0; b<G.sipo->totipo; b++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) { + + ok2= 0; + if(G.sipo->showkey) ok2= 1; + else if(totipo_vert && (ei->flag & IPO_EDIT)) ok2= 2; + else if(totipo_vert==0 && (ei->flag & IPO_SELECT)) ok2= 3; + + if(ok2) { + bezt= ei->icu->bezt; + a= ei->icu->totvert; + while(a--) { + ok= 0; + if(totipo_vert) { + if(bezt->f2 & 1) ok= 1; + } + else ok= 1; + + if(ok) { + if(event==1) { + bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1]; + if(bezt->h1==HD_AUTO || bezt->h1==HD_VECT) bezt->h1= HD_ALIGN; + if(bezt->h2==HD_AUTO || bezt->h2==HD_VECT) bezt->h2= HD_ALIGN; + } + else if(event==2) { + if(a) { + bezt->vec[0][1]= bezt->vec[1][1]= bezt->vec[2][1]= (bezt+1)->vec[1][1]; + if(bezt->h1==HD_AUTO || bezt->h1==HD_VECT) bezt->h1= HD_ALIGN; + if(bezt->h2==HD_AUTO || bezt->h2==HD_VECT) bezt->h2= HD_ALIGN; + } + } + else if(event==3) { + bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5)); + } + else if(event==4) { /* to current frame */ + + if(ok2==1 || ok2==2) { + + if(G.sipo->blocktype==ID_SEQ) { + Sequence *seq; + + seq= (Sequence *)G.sipo->from; + if(seq) { + dx= (float)(CFRA-seq->startdisp); + dx= (float)(100.0*dx/((float)(seq->enddisp-seq->startdisp))); + + dx-= bezt->vec[1][0]; + } + } + else dx= G.scene->r.framelen*CFRA - bezt->vec[1][0]; + + bezt->vec[0][0]+= dx; + bezt->vec[1][0]+= dx; + bezt->vec[2][0]+= dx; + } + } + } + + bezt++; + } + calchandles_ipocurve(ei->icu); + } + } + } + editipo_changed(G.sipo, 1); +} + + + +void mouse_select_ipo() +{ + Object *ob; + EditIpo *ei, *actei= 0; + IpoCurve *icu; + IpoKey *ik, *actik; + BezTriple *bezt; + Key *key; + KeyBlock *kb, *actkb=0; + float x, y, dist, mindist; + int a, oldflag = 0, hand, ok; + short mval[2], xo, yo; + + if(G.sipo->editipo==0) return; + + get_status_editipo(); + + if(G.sipo->showkey) { + getmouseco_areawin(mval); + + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + actik= 0; + mindist= 1000.0; + ik= G.sipo->ipokey.first; + while(ik) { + dist= (float)(fabs(ik->val-x)); + if(ik->flag & 1) dist+= 1.0; + if(dist < mindist) { + actik= ik; + mindist= dist; + } + ik= ik->next; + } + if(actik) { + oldflag= actik->flag; + + if(G.qual & LR_SHIFTKEY); + else deselectall_editipo(); + + if(G.qual & LR_SHIFTKEY) { + if(oldflag & 1) actik->flag &= ~1; + else actik->flag |= 1; + } + else { + actik->flag |= 1; + } + } + } + else if(totipo_edit) { + + hand= findnearest_ipovert(&icu, &bezt); + + if(G.qual & LR_SHIFTKEY) { + if(bezt) { + if(hand==1) { + if(BEZSELECTED(bezt)) { + bezt->f1= bezt->f2= bezt->f3= 0; + } + else { + bezt->f1= bezt->f2= bezt->f3= 1; + } + } + else if(hand==0) { + if(bezt->f1 & 1) bezt->f1= 0; + else bezt->f1= 1; + } + else { + if(bezt->f3 & 1) bezt->f3= 0; + else bezt->f3= 1; + } + } + } + else { + deselectall_editipo(); + + if(bezt) { + if(hand==1) { + bezt->f1|= 1; bezt->f2|= 1; bezt->f3|= 1; + } + else if(hand==0) bezt->f1|= 1; + else bezt->f3|= 1; + } + } + } + else { + + /* vertex keys ? */ + + if(G.sipo->blocktype==ID_KE && G.sipo->from) { + key= (Key *)G.sipo->from; + + ei= G.sipo->editipo; + if(key->type==KEY_NORMAL || (ei->flag & IPO_VISIBLE)) { + getmouseco_areawin(mval); + + areamouseco_to_ipoco(G.v2d, mval, &x, &y); + /* hoeveel is 20 pixels? */ + mindist= (float)(20.0*(G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)curarea->winy); + + kb= key->block.first; + while(kb) { + dist= (float)(fabs(kb->pos-y)); + if(kb->flag & SELECT) dist+= (float)0.01; + if(dist < mindist) { + actkb= kb; + mindist= dist; + } + kb= kb->next; + } + if(actkb) { + ok= TRUE; + if(G.obedit && (actkb->flag & 1)==0) { + ok= okee("Copy Key after leaving EditMode"); + } + if(ok) { + /* doet ook alle keypos */ + deselectall_editipo(); + + /* oldflag= actkb->flag; */ + + /* if(G.qual & LR_SHIFTKEY); */ + /* else { */ + /* deselectall_key(); */ + /* } */ + + /* if(G.qual & LR_SHIFTKEY) { */ + /* if(oldflag & 1) actkb->flag &= ~1; */ + /* else actkb->flag |= 1; */ + /* } */ + /* else { */ + actkb->flag |= 1; + /* } */ + + /* bereken keypos */ + showkeypos((Key *)G.sipo->from, actkb); + } + } + } + } + + /* select curve */ + if(actkb==0) { + if(totipo_vis==1) { + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if(ei->icu) { + if(ei->flag & IPO_VISIBLE) actei= ei; + } + } + } + else if(totipo_vis>1) { + actei= select_proj_ipo(0, 0); + } + + if(actei) oldflag= actei->flag; + + if(G.qual & LR_SHIFTKEY); + else deselectall_editipo(); + + if(actei) { + if(G.qual & LR_SHIFTKEY) { + if(oldflag & IPO_SELECT) actei->flag &= ~IPO_SELECT; + else actei->flag |= IPO_SELECT; + } + else { + actei->flag |= IPO_SELECT; + } + } + } + } + + update_editipo_flags(); + + force_draw(); + + if(G.sipo->showkey && G.sipo->blocktype==ID_OB) { + ob= OBACT; + if(ob && (ob->ipoflag & OB_DRAWKEY)) draw_object_ext(BASACT); + } + + getmouseco_areawin(mval); + xo= mval[0]; + yo= mval[1]; + + while(get_mbut()&R_MOUSE) { + getmouseco_areawin(mval); + if(abs(mval[0]-xo)+abs(mval[1]-yo) > 4) { + + if(actkb) move_keys(); + else transform_ipo('g'); + + return; + } + BIF_wait_for_statechange(); + } +} + +void sethandles_ipo(int code) +{ + /* code==1: set autohandle */ + /* code==2: set vectorhandle */ + /* als code==3 (HD_ALIGN) toggelt het, vectorhandles worden HD_FREE */ + EditIpo *ei; + BezTriple *bezt; + int a, b, ok=0; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + if(code==1 || code==2) { + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(bezt->f1 || bezt->f3) { + if(bezt->f1) bezt->h1= code; + if(bezt->f3) bezt->h2= code; + + if(bezt->h1!=bezt->h2) { + if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE; + if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE; + } + } + bezt++; + } + calchandles_ipocurve(ei->icu); + } + } + } + else { + /* is er 1 handle NIET vrij: alles vrijmaken, else ALIGNED maken */ + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(bezt->f1 && bezt->h1) ok= 1; + if(bezt->f3 && bezt->h2) ok= 1; + if(ok) break; + bezt++; + } + } + } + if(ok) ok= HD_FREE; + else ok= HD_ALIGN; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(bezt->f1) bezt->h1= ok; + if(bezt->f3 ) bezt->h2= ok; + + bezt++; + } + calchandles_ipocurve(ei->icu); + } + } + } + editipo_changed(G.sipo, 1); +} + +void set_ipotype() +{ + EditIpo *ei; + Key *key; + KeyBlock *kb; + int a; + short event; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + if(G.sipo->showkey) return; + get_status_editipo(); + + if(G.sipo->blocktype==ID_KE && totipo_edit==0 && totipo_sel==0) { + key= (Key *)G.sipo->from; + if(key==0) return; + + event= pupmenu("Key Type %t|Linear %x1|Cardinal %x2|B spline %x3"); + if(event < 1) return; + + kb= key->block.first; + while(kb) { + if(kb->flag & SELECT) { + kb->type= 0; + if(event==1) kb->type= KEY_LINEAR; + if(event==2) kb->type= KEY_CARDINAL; + if(event==3) kb->type= KEY_BSPLINE; + } + kb= kb->next; + } + } + else { + event= pupmenu("Ipo Type %t|Constant %x1|Linear %x2|Bezier %x3"); + if(event < 1) return; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) { + if(event==1) ei->icu->ipo= IPO_CONST; + else if(event==2) ei->icu->ipo= IPO_LIN; + else ei->icu->ipo= IPO_BEZ; + } + } + } + scrarea_queue_winredraw(curarea); +} + +void borderselect_ipo() +{ + EditIpo *ei; + IpoKey *ik; + BezTriple *bezt; + rcti rect; + rctf rectf; + int a, b, val; + short mval[2]; + + get_status_editipo(); + + val= get_border(&rect, 3); + + if(val) { + mval[0]= rect.xmin; + mval[1]= rect.ymin; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + if(G.sipo->showkey) { + ik= G.sipo->ipokey.first; + while(ik) { + if(rectf.xmin<ik->val && rectf.xmax>ik->val) { + if(val==LEFTMOUSE) ik->flag |= 1; + else ik->flag &= ~1; + } + ik= ik->next; + } + update_editipo_flags(); + } + else if(totipo_edit==0) { + if(rect.xmin<rect.xmax && rect.ymin<rect.ymax) + select_proj_ipo(&rectf, val); + } + else { + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu) { + if(ei->icu->bezt) { + b= ei->icu->totvert; + bezt= ei->icu->bezt; + while(b--) { + int bit= (val==LEFTMOUSE); + + if(BLI_in_rctf(&rectf, bezt->vec[0][0], bezt->vec[0][1])) + bezt->f1 = (bezt->f1&~1) | bit; + if(BLI_in_rctf(&rectf, bezt->vec[1][0], bezt->vec[1][1])) + bezt->f2 = (bezt->f2&~1) | bit; + if(BLI_in_rctf(&rectf, bezt->vec[2][0], bezt->vec[2][1])) + bezt->f3 = (bezt->f3&~1) | bit; + + bezt++; + } + } + } + } + } + scrarea_queue_winredraw(curarea); + } +} + + + + +void del_ipo() +{ + EditIpo *ei; + BezTriple *bezt, *bezt1; + int a, b; + int del, event; + + get_status_editipo(); + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + if(totipo_edit==0 && totipo_sel==0 && totipo_vertsel==0) { + delete_key(); + return; + } + + if( okee("Erase selected")==0 ) return; + + // eerste doorloop, kunnen hele stukken weg? + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + del= 0; + + if(G.sipo->showkey==0 && totipo_edit==0) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) { + del= 1; + } + } + else { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + if(b) { + while(b) { + if( BEZSELECTED(bezt) ); + else break; + b--; + bezt++; + } + if(b==0) del= 1; + } + } + } + } + } + + if(del) { + BLI_remlink( &(G.sipo->ipo->curve), ei->icu); + if(ei->icu->bezt) MEM_freeN(ei->icu->bezt); + MEM_freeN(ei->icu); + ei->flag &= ~IPO_SELECT; + ei->flag &= ~IPO_EDIT; + ei->icu= 0; + } + } + + // tweede doorloop, kleine stukken weg: alleen curves + ei= G.sipo->editipo; + for(b=0; b<G.sipo->totipo; b++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { + + event= 0; + if(ei->icu->bezt) { + + bezt= ei->icu->bezt; + for(a=0; a<ei->icu->totvert; a++) { + if( BEZSELECTED(bezt) ) { + memcpy(bezt, bezt+1, (ei->icu->totvert-a-1)*sizeof(BezTriple)); + ei->icu->totvert--; + a--; + event= 1; + } + else bezt++; + } + if(event) { + bezt1 = (BezTriple*) MEM_mallocN(ei->icu->totvert * sizeof(BezTriple), "delNurb"); + memcpy(bezt1, ei->icu->bezt, (ei->icu->totvert)*sizeof(BezTriple) ); + MEM_freeN(ei->icu->bezt); + ei->icu->bezt= bezt1; + } + } + } + } + } + + allqueue(REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); +} + +ListBase ipocopybuf={0, 0}; +int totipocopybuf=0; + +void free_ipocopybuf() +{ + IpoCurve *icu; + + while( (icu= ipocopybuf.first) ) { + if(icu->bezt) MEM_freeN(icu->bezt); + BLI_remlink(&ipocopybuf, icu); + MEM_freeN(icu); + } + totipocopybuf= 0; +} + +void copy_editipo() +{ + EditIpo *ei; + IpoCurve *icu; + int a; + + if(G.sipo->showkey) { + error("cannot copy\n"); + return; + } + + free_ipocopybuf(); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || (ei->flag & IPO_SELECT) ) { + icu= MEM_callocN(sizeof(IpoCurve), "ipocopybuf"); + *icu= *(ei->icu); + BLI_addtail(&ipocopybuf, icu); + if(icu->bezt) { + icu->bezt= MEM_mallocN(icu->totvert*sizeof(BezTriple), "ipocopybuf"); + memcpy(icu->bezt, ei->icu->bezt, icu->totvert*sizeof(BezTriple)); + } + totipocopybuf++; + } + } + } + + if(totipocopybuf==0) error("Copybuf is empty"); +} + +void paste_editipo() +{ + EditIpo *ei; + IpoCurve *icu; + int a, ok; + + if(G.sipo->showkey) return; + + if(totipocopybuf==0) return; + if(G.sipo->ipo==0) return; + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + get_status_editipo(); + + if(totipo_vis==0) { + error("No visible splines"); + } + else if(totipo_vis!=totipocopybuf && totipo_sel!=totipocopybuf) { + error("Incompatible paste"); + } + else { + /* problemen voorkomen: andere splines visible dan select */ + if(totipo_vis==totipo_sel) totipo_vis= 0; + + icu= ipocopybuf.first; + if(icu==0) return; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if(ei->flag & IPO_VISIBLE) { + ok= 0; + if(totipo_vis==totipocopybuf) ok= 1; + if(totipo_sel==totipocopybuf && (ei->flag & IPO_SELECT)) ok= 1; + + if(ok) { + + ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0); + if(ei->icu==0) return; + + if(ei->icu->bezt) MEM_freeN(ei->icu->bezt); + ei->icu->bezt= 0; + + ei->icu->totvert= icu->totvert; + ei->icu->flag= ei->flag= icu->flag; + ei->icu->extrap= icu->extrap; + ei->icu->ipo= icu->ipo; + + if(icu->bezt) { + ei->icu->bezt= MEM_mallocN(icu->totvert*sizeof(BezTriple), "ipocopybuf"); + memcpy(ei->icu->bezt, icu->bezt, icu->totvert*sizeof(BezTriple)); + } + + icu= icu->next; + + } + } + } + editipo_changed(G.sipo, 1); + } +} + +void set_exprap_ipo(int mode) +{ + EditIpo *ei; + int a; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + /* in geval van keys: altijd ok */ + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || (ei->flag & IPO_SELECT) || (G.sipo->showkey) ) { + ei->icu->extrap= mode; + } + } + } + editipo_changed(G.sipo, 1); +} + +int find_other_handles(EditIpo *eicur, float ctime, BezTriple **beztar) +{ + EditIpo *ei; + BezTriple *bezt; + int a, b, c= 1, totvert; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if(ei!=eicur && ei->icu && (ei->flag & IPO_VISIBLE)) { + + bezt= ei->icu->bezt; + totvert= ei->icu->totvert; + + for(b=0; b<totvert; b++, bezt++) { + if( bezt->vec[1][0] < ctime+IPOTHRESH && bezt->vec[1][0] > ctime-IPOTHRESH) { + if(c>2) return 0; + beztar[c]= bezt; + c++; + } + } + } + } + + if(c==3) return 1; + return 0; +} + +void set_speed_editipo(float speed) +{ + EditIpo *ei; + BezTriple *bezt, *beztar[3]; + float vec1[3], vec2[3]; + int a, b, totvert, didit=0; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + + /* uitgaande van 1 visible curve, selected punt, bijhorende punten: lencorr! */ + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + bezt= ei->icu->bezt; + totvert= ei->icu->totvert; + + for(b=0; b<totvert; b++, bezt++) { + if(BEZSELECTED(bezt)) { + + beztar[0]= bezt; + + if( find_other_handles(ei, bezt->vec[1][0], beztar) ) { + beztar[0]->h1= beztar[0]->h2= HD_ALIGN; + beztar[1]->h1= beztar[1]->h2= HD_ALIGN; + beztar[2]->h1= beztar[2]->h2= HD_ALIGN; + + vec1[0]= (beztar[0]->vec[1][1] - beztar[0]->vec[0][1]) / (beztar[0]->vec[1][0] - beztar[0]->vec[0][0]) ; + vec2[0]= (beztar[0]->vec[1][1] - beztar[0]->vec[2][1]) / (beztar[0]->vec[2][0] - beztar[0]->vec[1][0]) ; + + vec1[1]= (beztar[1]->vec[1][1] - beztar[1]->vec[0][1]) / (beztar[1]->vec[1][0] - beztar[1]->vec[0][0]) ; + vec2[1]= (beztar[1]->vec[1][1] - beztar[1]->vec[2][1]) / (beztar[1]->vec[2][0] - beztar[1]->vec[1][0]) ; + + vec1[2]= (beztar[2]->vec[1][1] - beztar[2]->vec[0][1]) / (beztar[2]->vec[1][0] - beztar[2]->vec[0][0]) ; + vec2[2]= (beztar[2]->vec[1][1] - beztar[2]->vec[2][1]) / (beztar[2]->vec[2][0] - beztar[2]->vec[1][0]) ; + + Normalise(vec1); + Normalise(vec2); + + VecMulf(vec1, speed); + VecMulf(vec2, speed); + + beztar[0]->vec[0][1]= beztar[0]->vec[1][1] - vec1[0]*(beztar[0]->vec[1][0] - beztar[0]->vec[0][0]) ; + beztar[0]->vec[2][1]= beztar[0]->vec[1][1] - vec2[0]*(beztar[0]->vec[2][0] - beztar[0]->vec[1][0]) ; + + beztar[1]->vec[0][1]= beztar[1]->vec[1][1] - vec1[1]*(beztar[1]->vec[1][0] - beztar[1]->vec[0][0]) ; + beztar[1]->vec[2][1]= beztar[1]->vec[1][1] - vec2[1]*(beztar[1]->vec[2][0] - beztar[1]->vec[1][0]) ; + + beztar[2]->vec[0][1]= beztar[2]->vec[1][1] - vec1[2]*(beztar[2]->vec[1][0] - beztar[2]->vec[0][0]) ; + beztar[2]->vec[2][1]= beztar[2]->vec[1][1] - vec2[2]*(beztar[2]->vec[2][0] - beztar[2]->vec[1][0]) ; + + didit= 1; + } + else { + error("Cannot set speed"); + } + } + } + break; + } + } + + if(didit==0) error("Did not set speed"); + + editipo_changed(G.sipo, 1); + allqueue(REDRAWNLA, 0); + allqueue (REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + +} + + +void insertkey(ID *id, int adrcode) +{ + IpoCurve *icu; + Ipo *ipo; + Object *ob; + void *poin; + float curval, cfra; + int type; + + if(id) { + + // this call here, otherwise get_ipo_curve gives it from the pinned ipo + ipo= get_ipo(id, GS(id->name), 1); // 1=make + + icu= get_ipocurve(id, GS(id->name), adrcode, ipo); + + if(icu) { + poin= get_ipo_poin(id, icu, &type); + if(poin) { + curval= read_ipo_poin(poin, type); + + cfra= frame_to_float(CFRA); + + if( GS(id->name)==ID_OB ) { + ob= (Object *)id; + if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) { + /* eigenlijk frametofloat overniew berekenen! daarvoor CFRA als float door kunnen geven */ + cfra-= ob->sf*G.scene->r.framelen; + } + } + + insert_vert_ipo(icu, cfra, curval); + } + } + } +} + +void insertkey_editipo() +{ + EditIpo *ei; + IpoKey *ik; + ID *id; + float *fp, cfra, *insertvals; + int a, nr, ok, tot; + short event; + + if(G.sipo->showkey) + event= pupmenu("Insert KeyVertices %t|Current frame %x1|Selected Keys %x2"); + else + event= pupmenu("Insert KeyVertices %t|Current frame %x1"); + + if(event<1) return; + + ei= G.sipo->editipo; + for(nr=0; nr<G.sipo->totipo; nr++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + + ok= 0; + if(G.sipo->showkey) ok= 1; + else if(ei->flag & IPO_SELECT) ok= 1; + + if(ok) { + /* aantal tellen */ + if(event==1) tot= 1; + else { + ik= G.sipo->ipokey.first; + tot= 0; + while(ik) { + if(ik->flag & 1) tot++; + ik= ik->next; + } + } + if(tot) { + + /* correctie voor ob timeoffs */ + cfra= frame_to_float(CFRA); + id= G.sipo->from; + if(id && GS(id->name)==ID_OB ) { + Object *ob= (Object *)id; + if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) { + cfra-= ob->sf*G.scene->r.framelen; + } + } + else if(id && GS(id->name)==ID_SEQ) { + extern Sequence *last_seq; /* editsequence.c */ + + if(last_seq) { + cfra= (float)(100.0*(cfra-last_seq->startdisp)/((float)(last_seq->enddisp-last_seq->startdisp))); + } + } + + insertvals= MEM_mallocN(sizeof(float)*2*tot, "insertkey_editipo"); + /* zeker zijn dat icu->curval klopt */ + calc_ipo(G.sipo->ipo, cfra); + + if(event==1) { + insertvals[0]= cfra; + + insertvals[1]= ei->icu->curval; + } + else { + fp= insertvals; + ik= G.sipo->ipokey.first; + while(ik) { + if(ik->flag & 1) { + calc_ipo(G.sipo->ipo, ik->val); + + fp[0]= ik->val; + fp[1]= ei->icu->curval; + fp+= 2; + } + ik= ik->next; + } + } + fp= insertvals; + for(a=0; a<tot; a++, fp+=2) { + insert_vert_ipo(ei->icu, fp[0], fp[1]); + } + + MEM_freeN(insertvals); + calc_ipo(G.sipo->ipo, (float)CFRA); + } + } + } + } + allqueue (REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); +} + + +void common_insertkey() +{ + Base *base; + Object *ob; + Material *ma; + ID *id; + IpoCurve *icu; + World *wo; + Lamp *la; + int tlay, map, event; + char menustr[256]; + + if(curarea->spacetype==SPACE_IPO) { + insertkey_editipo(); + } + else if(curarea->spacetype==SPACE_BUTS) { + + if(G.buts->mainb==BUTS_MAT) { + id= G.buts->lockpoin; + ma= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|RGB%x0|Alpha%x1|HaSize%x2|Mode %x3|All Color%x10|Ofs%x12|Size%x13|All Mapping%x11"); + if(event== -1) return; + + map= texchannel_to_adrcode(ma->texact); + + if(event==0 || event==10) { + insertkey(id, MA_COL_R); + insertkey(id, MA_COL_G); + insertkey(id, MA_COL_B); + } + if(event==1 || event==10) { + insertkey(id, MA_ALPHA); + } + if(event==2 || event==10) { + insertkey(id, MA_HASIZE); + } + if(event==3 || event==10) { + insertkey(id, MA_MODE); + } + if(event==10) { + insertkey(id, MA_SPEC_R); + insertkey(id, MA_SPEC_G); + insertkey(id, MA_SPEC_B); + insertkey(id, MA_REF); + insertkey(id, MA_EMIT); + insertkey(id, MA_AMB); + insertkey(id, MA_SPEC); + insertkey(id, MA_HARD); + insertkey(id, MA_MODE); + } + if(event==12 || event==11) { + insertkey(id, map+MAP_OFS_X); + insertkey(id, map+MAP_OFS_Y); + insertkey(id, map+MAP_OFS_Z); + } + if(event==13 || event==11) { + insertkey(id, map+MAP_SIZE_X); + insertkey(id, map+MAP_SIZE_Y); + insertkey(id, map+MAP_SIZE_Z); + } + if(event==11) { + insertkey(id, map+MAP_R); + insertkey(id, map+MAP_G); + insertkey(id, map+MAP_B); + insertkey(id, map+MAP_DVAR); + insertkey(id, map+MAP_COLF); + insertkey(id, map+MAP_NORF); + insertkey(id, map+MAP_VARF); + } + } + } + else if(G.buts->mainb==BUTS_WORLD) { + id= G.buts->lockpoin; + wo= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|ZenRGB%x0|HorRGB%x1|Mist%x2|stars %x3|Ofs%x12|Size%x13"); + if(event== -1) return; + + map= texchannel_to_adrcode(wo->texact); + + if(event==0) { + insertkey(id, WO_ZEN_R); + insertkey(id, WO_ZEN_G); + insertkey(id, WO_ZEN_B); + } + if(event==1) { + insertkey(id, WO_HOR_R); + insertkey(id, WO_HOR_G); + insertkey(id, WO_HOR_B); + } + if(event==2) { + insertkey(id, WO_MISI); + insertkey(id, WO_MISTDI); + insertkey(id, WO_MISTSTA); + insertkey(id, WO_MISTHI); + } + if(event==3) { + insertkey(id, WO_STAR_R); + insertkey(id, WO_STAR_G); + insertkey(id, WO_STAR_B); + insertkey(id, WO_STARDIST); + insertkey(id, WO_STARSIZE); + } + if(event==12) { + insertkey(id, map+MAP_OFS_X); + insertkey(id, map+MAP_OFS_Y); + insertkey(id, map+MAP_OFS_Z); + } + if(event==13) { + insertkey(id, map+MAP_SIZE_X); + insertkey(id, map+MAP_SIZE_Y); + insertkey(id, map+MAP_SIZE_Z); + } + } + } + else if(G.buts->mainb==BUTS_LAMP) { + id= G.buts->lockpoin; + la= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|RGB%x0|Energy%x1|Spotsi%x2|Ofs%x12|Size%x13"); + if(event== -1) return; + + map= texchannel_to_adrcode(la->texact); + + if(event==0) { + insertkey(id, LA_COL_R); + insertkey(id, LA_COL_G); + insertkey(id, LA_COL_B); + } + if(event==1) { + insertkey(id, LA_ENERGY); + } + if(event==2) { + insertkey(id, LA_SPOTSI); + } + if(event==12) { + insertkey(id, map+MAP_OFS_X); + insertkey(id, map+MAP_OFS_Y); + insertkey(id, map+MAP_OFS_Z); + } + if(event==13) { + insertkey(id, map+MAP_SIZE_X); + insertkey(id, map+MAP_SIZE_Y); + insertkey(id, map+MAP_SIZE_Z); + } + + } + } + else if(G.buts->mainb==BUTS_EDIT) { + ob= OBACT; + if(ob && ob->type==OB_CAMERA) { + id= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|Lens%x0|Clipping%x1"); + if(event== -1) return; + + if(event==0) { + insertkey(id, CAM_LENS); + } + if(event==1) { + insertkey(id, CAM_STA); + insertkey(id, CAM_END); + } + } + } + } + else if(G.buts->mainb==BUTS_SOUND) { + if(G.ssound) { + id= G.buts->lockpoin; + if(id) { + event= pupmenu("Insert Key %t|Volume%x0|Pitch%x1|Panning%x2|Attennuation%x3"); + if(event== -1) return; + + if(event==0) { + insertkey(id, SND_VOLUME); + } + if(event==1) { + insertkey(id, SND_PITCH); + } + if(event==2) { + insertkey(id, SND_PANNING); + } + if(event==3) { + insertkey(id, SND_ATTEN); + } + } + } + } + + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + + } + else if(curarea->spacetype==SPACE_VIEW3D) { + + + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) break; + base= base->next; + } + if(base==0) return; + + if (G.obpose) + strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Avail%x9"); + else + strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Layer%x5|Avail%x9"); + + + if( (ob = OBACT)) { + if(ob->type==OB_MESH) strcat(menustr, "| %x6|Mesh%x7"); + else if(ob->type==OB_LATTICE) strcat(menustr, "| %x6|Lattice%x7"); + else if(ob->type==OB_CURVE) strcat(menustr, "| %x6|Curve%x7"); + else if(ob->type==OB_SURF) strcat(menustr, "| %x6|Surface%x7"); + else if(ob->type==OB_IKA) strcat(menustr, "| %x6|Effector%x8"); + if(ob->flag & OB_FROMGROUP) strcat(menustr, "| %x6|Entire Group%x10"); + } + + event= pupmenu(menustr); + if(event== -1) return; + + if(event==7) { + if(ob->type==OB_MESH) insert_meshkey(ob->data); + else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(ob->data); + else if(ob->type==OB_LATTICE) insert_lattkey(ob->data); + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWBUTSANIM, 0); + return; + } + + if(event==10) { + Group *group= find_group(ob); + if(group) { + add_group_key(group); + allqueue(REDRAWBUTSANIM, 0); + } + } + + base= FIRSTBASE; + if (G.obpose){ + bAction *act; + bPose *pose; + bPoseChannel *chan; + bActionChannel *achan; + + ob = G.obpose; + + /* Get action & pose from object */ + act=ob->action; + pose=ob->pose; + + collect_pose_garbage(ob); + + if (!act){ + act=G.obpose->action=add_empty_action(); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + if (!pose){ + error ("No pose!"); /* Should never happen */ + } + + if (act->id.lib) + { + error ("Can't key libactions"); + return; + } + filter_pose_keys (); + for (chan=pose->chanbase.first; chan; chan=chan->next) + { + if (chan->flag & POSE_KEY){ + // set_action_key(act, chan); + if(event==0 || event==3 ||event==4) { + set_action_key(act, chan, AC_LOC_X, 1); + set_action_key(act, chan, AC_LOC_Y, 1); + set_action_key(act, chan, AC_LOC_Z, 1); + } + if(event==1 || event==3 ||event==4) { + set_action_key(act, chan, AC_QUAT_X, 1); + set_action_key(act, chan, AC_QUAT_Y, 1); + set_action_key(act, chan, AC_QUAT_Z, 1); + set_action_key(act, chan, AC_QUAT_W, 1); + } + if(event==2 || event==4) { + set_action_key(act, chan, AC_SIZE_X, 1); + set_action_key(act, chan, AC_SIZE_Y, 1); + set_action_key(act, chan, AC_SIZE_Z, 1); + } + if (event==9){ + for (achan = act->chanbase.first; achan; achan=achan->next){ + if (achan->ipo && !strcmp (achan->name, chan->name)){ + for (icu = achan->ipo->curve.first; icu; icu=icu->next){ + set_action_key(act, chan, icu->adrcode, 0); + } + break; + } + } + } + } + + remake_action_ipos(act); + } + allqueue(REDRAWIPO, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + + } + else + { + while(base) { + if TESTBASELIB(base) { + id= (ID *)(base->object); + + /* alle curves in ipo deselect */ + if(base->object->ipo) { + icu= base->object->ipo->curve.first; + while(icu) { + icu->flag &= ~IPO_SELECT; + if(event==9) insertkey(id, icu->adrcode); + icu= icu->next; + } + } + + if(event==0 || event==3 ||event==4) { + insertkey(id, OB_LOC_X); + insertkey(id, OB_LOC_Y); + insertkey(id, OB_LOC_Z); + } + if(event==1 || event==3 ||event==4) { + insertkey(id, OB_ROT_X); + insertkey(id, OB_ROT_Y); + insertkey(id, OB_ROT_Z); + } + if(event==2 || event==4) { + insertkey(id, OB_SIZE_X); + insertkey(id, OB_SIZE_Y); + insertkey(id, OB_SIZE_Z); + } + if(event==5) { + /* localview weghalen */ + tlay= base->object->lay; + base->object->lay &= 0xFFFFFF; + insertkey(id, OB_LAY); + base->object->lay= tlay; + } + if(event==8) { + /* deze patch moet omdat duplicators de positie van effg veranderen */ + Ika *ika= ob->data; + VecMat4MulVecfl(ika->effg, ob->obmat, ika->effn); + + insertkey(id, OB_EFF_X); + insertkey(id, OB_EFF_Y); + insertkey(id, OB_EFF_Z); + } + } + base= base->next; + } + } + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + +} + + +/* **************************************************** */ + +/* IPOKEY: + * + * er zijn drie manieren om hiermee om te gaan: + * 1. hieronder: voor tekenen en editen in Ipo window + * 2. voor tekenen keys in View3D (zie ipo.c en drawobject.c) + * 3. voor editen keys in View3D (hieronder en editobject.c) + * + */ + + +void free_ipokey(ListBase *lb) +{ + IpoKey *ik; + + ik= lb->first; + while(ik) { + if(ik->data) MEM_freeN(ik->data); + ik= ik->next; + } + BLI_freelistN(lb); +} + + +void add_to_ipokey(ListBase *lb, BezTriple *bezt, int nr, int len) +{ + IpoKey *ik, *ikn; + + ik= lb->first; + while(ik) { + + if( ik->val==bezt->vec[1][0] ) { + if(ik->data[nr]==0) { /* dubbele punten! */ + ik->data[nr]= bezt; + if(bezt->f2 & 1) ik->flag= 1; + return; + } + } + else if(ik->val > bezt->vec[1][0]) break; + + ik= ik->next; + } + + ikn= MEM_callocN(sizeof(IpoKey), "add_to_ipokey"); + if(ik) BLI_insertlinkbefore(lb, ik, ikn); + else BLI_addtail(lb, ikn); + + ikn->data= MEM_callocN(sizeof(float *)*len, "add_to_ipokey"); + ikn->data[nr]= bezt; + ikn->val= bezt->vec[1][0]; + + if(bezt->f2 & 1) ikn->flag= 1; +} + +void make_ipokey(void) +{ + EditIpo *ei; + IpoKey *ik; + ListBase *lb; + BezTriple *bezt; + int a, b, sel, desel, totvert; + + lb= &G.sipo->ipokey; + free_ipokey(lb); + + ei= G.sipo->editipo; + if(ei==0) return; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + bezt= ei->icu->bezt; + totvert= ei->icu->totvert; + + for(b=0; b<totvert; b++, bezt++) { + add_to_ipokey(lb, bezt, a, G.sipo->totipo); + } + + ei->flag &= ~IPO_SELECT; + ei->flag &= ~IPO_EDIT; + ei->icu->flag= ei->flag; + } + } + + /* selectflags testen */ + ik= lb->first; + while(ik) { + sel= desel= 0; + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + bezt= ik->data[a]; + if(bezt->f2 & 1) sel++; + else desel++; + } + } + if(sel && desel) sel= 0; + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + bezt= ik->data[a]; + if(sel) { + bezt->f1 |= 1; + bezt->f2 |= 1; + bezt->f3 |= 1; + } + else { + bezt->f1 &= ~1; + bezt->f2 &= ~1; + bezt->f3 &= ~1; + } + } + } + if(sel) ik->flag = 1; + else ik->flag= 0; + + ik= ik->next; + } + get_status_editipo(); +} + +void make_ipokey_transform(Object *ob, ListBase *lb, int sel) +{ + IpoCurve *icu; + BezTriple *bezt; + int a, adrcode = 0, ok, dloc=0, drot=0, dsize=0; + + if(ob->ipo==0) return; + if(ob->ipo->showkey==0) return; + + /* testen: zijn er delta curves? */ + icu= ob->ipo->curve.first; + while(icu) { + if(icu->flag & IPO_VISIBLE) { + switch(icu->adrcode) { + case OB_DLOC_X: + case OB_DLOC_Y: + case OB_DLOC_Z: + dloc= 1; + break; + case OB_DROT_X: + case OB_DROT_Y: + case OB_DROT_Z: + drot= 1; + break; + case OB_DSIZE_X: + case OB_DSIZE_Y: + case OB_DSIZE_Z: + dsize= 1; + break; + } + } + icu= icu->next; + } + + icu= ob->ipo->curve.first; + while(icu) { + if(icu->flag & IPO_VISIBLE) { + ok= 0; + + switch(icu->adrcode) { + case OB_DLOC_X: + case OB_DLOC_Y: + case OB_DLOC_Z: + case OB_DROT_X: + case OB_DROT_Y: + case OB_DROT_Z: + case OB_DSIZE_X: + case OB_DSIZE_Y: + case OB_DSIZE_Z: + ok= 1; + break; + + case OB_LOC_X: + case OB_LOC_Y: + case OB_LOC_Z: + if(dloc==0) ok= 1; + break; + case OB_ROT_X: + case OB_ROT_Y: + case OB_ROT_Z: + if(drot==0) ok= 1; + break; + case OB_SIZE_X: + case OB_SIZE_Y: + case OB_SIZE_Z: + if(dsize==0) ok= 1; + break; + } + if(ok) { + for(a=0; a<OB_TOTIPO; a++) { + if(icu->adrcode==ob_ar[a]) { + adrcode= a; + break; + } + } + + bezt= icu->bezt; + a= icu->totvert; + while(a--) { + if(sel==0 || (bezt->f2 & 1)) { + add_to_ipokey(lb, bezt, adrcode, OB_TOTIPO); + } + bezt++; + } + } + } + icu= icu->next; + } +} + +void update_ipokey_val() /* na verplaatsen vertices */ +{ + IpoKey *ik; + int a; + + ik= G.sipo->ipokey.first; + while(ik) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) { + ik->val= ik->data[a]->vec[1][0]; + break; + } + } + ik= ik->next; + } +} + +void set_tob_old(float *old, float *poin) +{ + old[0]= *(poin); + old[3]= *(poin-3); + old[6]= *(poin+3); +} + +void set_ipo_pointers_transob(IpoKey *ik, TransOb *tob) +{ + BezTriple *bezt; + int a, delta= 0; + + tob->locx= tob->locy= tob->locz= 0; + tob->rotx= tob->roty= tob->rotz= 0; + tob->sizex= tob->sizey= tob->sizez= 0; + + for(a=0; a<OB_TOTIPO; a++) { + if(ik->data[a]) { + bezt= ik->data[a]; + + switch( ob_ar[a] ) { + case OB_LOC_X: + case OB_DLOC_X: + tob->locx= &(bezt->vec[1][1]); break; + case OB_LOC_Y: + case OB_DLOC_Y: + tob->locy= &(bezt->vec[1][1]); break; + case OB_LOC_Z: + case OB_DLOC_Z: + tob->locz= &(bezt->vec[1][1]); break; + + case OB_DROT_X: + delta= 1; + case OB_ROT_X: + tob->rotx= &(bezt->vec[1][1]); break; + case OB_DROT_Y: + delta= 1; + case OB_ROT_Y: + tob->roty= &(bezt->vec[1][1]); break; + case OB_DROT_Z: + delta= 1; + case OB_ROT_Z: + tob->rotz= &(bezt->vec[1][1]); break; + + case OB_SIZE_X: + case OB_DSIZE_X: + tob->sizex= &(bezt->vec[1][1]); break; + case OB_SIZE_Y: + case OB_DSIZE_Y: + tob->sizey= &(bezt->vec[1][1]); break; + case OB_SIZE_Z: + case OB_DSIZE_Z: + tob->sizez= &(bezt->vec[1][1]); break; + } + } + } + + /* oldvals voor o.a. undo */ + if(tob->locx) set_tob_old(tob->oldloc, tob->locx); + if(tob->locy) set_tob_old(tob->oldloc+1, tob->locy); + if(tob->locz) set_tob_old(tob->oldloc+2, tob->locz); + + /* bewaar de eerste oldrot, ivm mapping curves ('1'=10 graden) en correcte berekening */ + if(tob->rotx) set_tob_old(tob->oldrot+3, tob->rotx); + if(tob->roty) set_tob_old(tob->oldrot+4, tob->roty); + if(tob->rotz) set_tob_old(tob->oldrot+5, tob->rotz); + + /* bewaar de eerste oldsize, dit mag niet de dsize zijn! */ + if(tob->sizex) set_tob_old(tob->oldsize+3, tob->sizex); + if(tob->sizey) set_tob_old(tob->oldsize+4, tob->sizey); + if(tob->sizez) set_tob_old(tob->oldsize+5, tob->sizez); + + tob->flag= TOB_IPO; + if(delta) tob->flag |= TOB_IPODROT; +} + + + +void nextkey(ListBase *elems, int dir) +{ + IpoKey *ik, *previk; + int totsel; + + if(dir==1) ik= elems->last; + else ik= elems->first; + previk= 0; + totsel= 0; + + while(ik) { + + if(ik->flag) totsel++; + + if(previk) { + if(G.qual & LR_SHIFTKEY) { + if(ik->flag) previk->flag= 1; + } + else previk->flag= ik->flag; + } + + previk= ik; + if(dir==1) ik= ik->prev; + else ik= ik->next; + + if(G.qual & LR_SHIFTKEY); + else if(ik==0) previk->flag= 0; + } + + /* als geen een key select: */ + if(totsel==0) { + if(dir==1) ik= elems->first; + else ik= elems->last; + + if(ik) ik->flag= 1; + } +} + +static int float_to_frame (float frame) +{ + int to= (int) frame; + + if (frame-to>0.5) to++; + + return to; +} + +void movekey_ipo(int dir) /* alleen extern aanroepen vanuit view3d queue */ +{ + IpoKey *ik; + float toframe = 0.0; + int a; + + if(G.sipo->showkey==0) return; + + ik= G.sipo->ipokey.first; + if (dir==-1) { + while (ik && float_to_frame(ik->val)<CFRA) { + toframe= ik->val; + ik= ik->next; + } + } else { + while (ik && float_to_frame(ik->val)<=CFRA) { + ik= ik->next; + } + if (ik) toframe= ik->val; + } + + a= float_to_frame(toframe); + + if (a!=CFRA && a>0) { + CFRA= a; + + update_for_newframe(); + } + + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + +} + +void movekey_obipo(int dir) /* alleen extern aanroepen vanuit view3d queue */ +{ + Base *base; + Object *ob; + ListBase elems; + IpoKey *ik; + int a; + float toframe= CFRA; + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + ob= base->object; + if(ob->ipo && ob->ipo->showkey) { + elems.first= elems.last= 0; + make_ipokey_transform(ob, &elems, 0); + + if(elems.first) { + ik= elems.first; + if (dir==-1) { + while (ik && float_to_frame(ik->val)<CFRA) { + toframe= ik->val; + ik= ik->next; + } + } else { + while (ik && float_to_frame(ik->val)<=CFRA) { + ik= ik->next; + } + if (ik) toframe= ik->val; + } + + free_ipokey(&elems); + } + } + } + + base= base->next; + } + + a= float_to_frame(toframe); + + if (a!=CFRA && a>0) { + CFRA= a; + + update_for_newframe(); + } + + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + +} + +void nextkey_ipo(int dir) /* aanroepen vanuit ipo queue */ +{ + IpoKey *ik; + int a; + + if(G.sipo->showkey==0) return; + + nextkey(&G.sipo->ipokey, dir); + + /* kopieeren naar beziers */ + ik= G.sipo->ipokey.first; + while(ik) { + for(a=0; a<G.sipo->totipo; a++) { + if(ik->data[a]) ik->data[a]->f1= ik->data[a]->f2= ik->data[a]->f3= ik->flag; + } + ik= ik->next; + } + + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + if(G.sipo->blocktype == ID_OB) allqueue(REDRAWVIEW3D, 0); +} + +void nextkey_obipo(int dir) /* alleen extern aanroepen vanuit view3d queue */ +{ + Base *base; + Object *ob; + ListBase elems; + IpoKey *ik; + int a; + + /* problem: this doesnt work when you mix dLoc keys with Loc keys */ + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + ob= base->object; + if( (ob->ipoflag & OB_DRAWKEY) && ob->ipo && ob->ipo->showkey) { + elems.first= elems.last= 0; + make_ipokey_transform(ob, &elems, 0); + + if(elems.first) { + + nextkey(&elems, dir); + + /* kopieeren naar beziers */ + ik= elems.first; + while(ik) { + for(a=0; a<OB_TOTIPO; a++) { + if(ik->data[a]) ik->data[a]->f1= ik->data[a]->f2= ik->data[a]->f3= ik->flag; + } + ik= ik->next; + } + + free_ipokey(&elems); + } + } + } + + base= base->next; + } + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWVIEW3D, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); +} + + +/* **************************************************** */ + + +void remake_ipo_transverts(TransVert *transmain, float *dvec, int tot) +{ + EditIpo *ei; + TransVert *tv; + BezTriple *bezt; + int a, b; + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + + if(ei->icu->bezt) { + sort_time_ipocurve(ei->icu); + } + } + } + + ei= G.sipo->editipo; + tv= transmain; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(ei->icu->ipo==IPO_BEZ) { + if(bezt->f1 & 1) { + tv->loc= bezt->vec[0]; + tv++; + } + if(bezt->f3 & 1) { + tv->loc= bezt->vec[2]; + tv++; + } + } + if(bezt->f2 & 1) { + tv->loc= bezt->vec[1]; + tv++; + } + + bezt++; + } + testhandles_ipocurve(ei->icu); + } + } + } + } + + if(G.sipo->showkey) make_ipokey(); + + if(dvec==0) return; + + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->oldloc[0]= tv->loc[0]-dvec[0]; + tv->oldloc[1]= tv->loc[1]-dvec[1]; + } +} + +void transform_ipo(int mode) +{ + EditIpo *ei; + BezTriple *bezt; + TransVert *transmain = NULL, *tv; + float xref=1.0, yref=1.0, dx, dy, dvec[2], min[3], max[3], vec[2], div, cent[2], size[2], sizefac; + int tot=0, a, b, firsttime=1, afbreek=0, midtog= 0, dosort, proj = 0; + unsigned short event = 0; + short mval[2], val, xo, yo, xn, yn, xc, yc; + char str[32]; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + if(G.sipo->editipo==0) return; + if(mode=='r') return; /* vanuit gesture */ + + INIT_MINMAX(min, max); + + /* welke vertices doen mee */ + get_status_editipo(); + if(totipo_vertsel) { + tot= totipo_vertsel; + tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain"); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + + + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(ei->icu->ipo==IPO_BEZ) { + if(bezt->f1 & 1) { + tv->loc= bezt->vec[0]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + + /* let op: we nemen middelste vertex */ + DO_MINMAX2(bezt->vec[1], min, max); + + tv++; + } + if(bezt->f3 & 1) { + tv->loc= bezt->vec[2]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + + /* let op: we nemen middelste vertex */ + DO_MINMAX2(bezt->vec[1], min, max); + + tv++; + } + } + if(bezt->f2 & 1) { + tv->loc= bezt->vec[1]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + DO_MINMAX2(bezt->vec[1], min, max); + tv++; + } + bezt++; + } + } + } + } + } + + } + else if(totipo_edit==0 && totipo_sel!=0) { + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) { + if(ei->icu->bezt && ei->icu->ipo==IPO_BEZ) tot+= 3*ei->icu->totvert; + else tot+= ei->icu->totvert; + } + } + if(tot==0) return; + + tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain"); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) { + if(ei->icu->bezt) { + + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(ei->icu->ipo==IPO_BEZ) { + tv->loc= bezt->vec[0]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + tv++; + + tv->loc= bezt->vec[2]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + tv++; + } + tv->loc= bezt->vec[1]; + VECCOPY(tv->oldloc, tv->loc); + if(ei->disptype==IPO_DISPBITS) tv->flag= 1; + + DO_MINMAX2(bezt->vec[1], min, max); + + tv++; + + bezt++; + } + } + } + } + + } + + if(tot==0) { + if(totipo_edit==0) move_keys(); + return; + } + + cent[0]= (float)((min[0]+max[0])/2.0); + cent[1]= (float)((min[1]+max[1])/2.0); + + if(G.sipo->showkey) { + midtog= 1; + proj= 1; + } + + ipoco_to_areaco(G.v2d, cent, mval); + xc= mval[0]; + yc= mval[1]; + + getmouseco_areawin(mval); + xo= xn= mval[0]; + yo= yn= mval[1]; + dvec[0]= dvec[1]= 0.0; + + sizefac= (float)(sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) )); + if(sizefac<2.0) sizefac= 2.0; + + while(afbreek==0) { + getmouseco_areawin(mval); + if(mval[0]!=xo || mval[1]!=yo || firsttime) { + + if(mode=='g') { + + dx= (float)(mval[0]- xo); + dy= (float)(mval[1]- yo); + + div= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin); + dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div; + + div= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div; + + if(midtog) dvec[proj]= 0.0; + + /* vec wordt verderop nog gebruikt: remake_ipo_transverts */ + vec[0]= dvec[0]; + vec[1]= dvec[1]; + + apply_keyb_grid(vec, 0.0, (float)1.0, (float)0.1, U.flag & AUTOGRABGRID); + apply_keyb_grid(vec+1, 0.0, (float)1.0, (float)0.1, 0); + + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= tv->oldloc[0]+vec[0]; + + if(tv->flag==0) tv->loc[1]= tv->oldloc[1]+vec[1]; + } + + sprintf(str, "X: %.3f Y: %.3f ", vec[0], vec[1]); + headerprint(str); + } + else if(mode=='s') { + + size[0]=size[1]=(float)( (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac); + + if(midtog) size[proj]= 1.0; + size[0]*= xref; + size[1]*= yref; + + apply_keyb_grid(size, 0.0, (float)0.2, (float)0.1, U.flag & AUTOSIZEGRID); + apply_keyb_grid(size+1, 0.0, (float)0.2, (float)0.1, U.flag & AUTOSIZEGRID); + + tv= transmain; + + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= size[0]*(tv->oldloc[0]-cent[0])+ cent[0]; + if(tv->flag==0) tv->loc[1]= size[1]*(tv->oldloc[1]-cent[1])+ cent[1]; + } + + sprintf(str, "sizeX: %.3f sizeY: %.3f ", size[0], size[1]); + headerprint(str); + + } + + xo= mval[0]; + yo= mval[1]; + + dosort= 0; + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + + /* let op: als de tijd verkeerd is: niet de handles corrigeren */ + if (test_time_ipocurve(ei->icu) ) dosort++; + else testhandles_ipocurve(ei->icu); + } + } + + if(dosort) { + if(mode=='g') remake_ipo_transverts(transmain, vec, tot); + else remake_ipo_transverts(transmain, 0, tot); + } + if(G.sipo->showkey) update_ipokey_val(); + + calc_ipo(G.sipo->ipo, (float)CFRA); + + /* update realtime */ + if(G.sipo->lock) { + if(G.sipo->blocktype==ID_MA) { + force_draw_plus(SPACE_BUTS); + } + else if(G.sipo->blocktype==ID_KE) { + do_ob_key(OBACT); + makeDispList(OBACT); + force_draw_plus(SPACE_VIEW3D); + } + else if(G.sipo->blocktype==ID_AC) { + do_all_actions(); + force_draw_all(); + } + else if(G.sipo->blocktype==ID_OB) { + Base *base= FIRSTBASE; + + while(base) { + if(base->object->ipo==G.sipo->ipo) do_ob_ipo(base->object); + base= base->next; + } + force_draw_plus(SPACE_VIEW3D); + } + else force_draw(); + } + else { + force_draw(); + } + firsttime= 0; + } + else BIF_wait_for_statechange(); + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case ESCKEY: + case LEFTMOUSE: + case RIGHTMOUSE: + case SPACEKEY: + case RETKEY: + afbreek= 1; + break; + case MIDDLEMOUSE: + if(G.sipo->showkey==0) { + midtog= ~midtog; + if(midtog) { + if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1; + else proj= 0; + firsttime= 1; + } + } + break; + case XKEY: + case YKEY: + if(event==XKEY) xref= -xref; + else if(G.sipo->showkey==0) yref= -yref; + firsttime= 1; + break; + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + firsttime= 1; + break; + default: + if(mode=='g') { + if(G.qual & LR_CTRLKEY) { + if(event==LEFTARROWKEY) {dvec[0]-= 1.0; firsttime= 1;} + else if(event==RIGHTARROWKEY) {dvec[0]+= 1.0; firsttime= 1;} + else if(event==UPARROWKEY) {dvec[1]+= 1.0; firsttime= 1;} + else if(event==DOWNARROWKEY) {dvec[1]-= 1.0; firsttime= 1;} + } + else arrows_move_cursor(event); + } + else arrows_move_cursor(event); + } + } + if(afbreek) break; + } + } + + if(event==ESCKEY || event==RIGHTMOUSE) { + tv= transmain; + for(a=0; a<tot; a++, tv++) { + tv->loc[0]= tv->oldloc[0]; + tv->loc[1]= tv->oldloc[1]; + } + + dosort= 0; + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + if( test_time_ipocurve(ei->icu)) { + dosort= 1; + break; + } + } + } + } + + if(dosort) remake_ipo_transverts(transmain, 0, tot); + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + testhandles_ipocurve(ei->icu); + } + } + } + calc_ipo(G.sipo->ipo, (float)CFRA); + } + + editipo_changed(G.sipo, 1); + + MEM_freeN(transmain); +} + +void clever_numbuts_ipo() +{ + BezTriple *bezt=0, *bezt1; + Key *key; + KeyBlock *kb; + EditIpo *ei; + float far, delta[3], old[3]; + int a, b, scale10=0, totbut=2; + + if(G.sipo->ipo && G.sipo->ipo->id.lib) return; + if(G.sipo->editipo==0) return; + + /* welke vertices doen mee */ + get_status_editipo(); + + if(G.qual & LR_SHIFTKEY) totbut= 1; + + if(G.vd==0) far= 10000.0; + else far= (float)(MAX2(G.vd->far, 10000.0)); + + if(totipo_vertsel) { + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + + if(ei->icu->bezt) { + bezt1= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(BEZSELECTED(bezt1)) { + bezt= bezt1; + break; + } + bezt1++; + } + + } + } + } + if(bezt) break; + } + + if(bezt==0) return; + + if(bezt->f2 & 1) { + + VECCOPY(old, bezt->vec[1]); + + if(totipo_vis==1 && G.sipo->blocktype==ID_OB) { + if ELEM4(ei->icu->adrcode, OB_TIME, OB_ROT_X, OB_ROT_Y, OB_ROT_Z) scale10= 1; + if ELEM3(ei->icu->adrcode, OB_DROT_X, OB_DROT_Y, OB_DROT_Z) scale10= 1; + } + if(scale10) bezt->vec[1][1]*= 10.0; + + add_numbut(0, NUM|FLO, "LocX:", -1000, 10000, bezt->vec[1], 0); + if(totbut==2) add_numbut(1, NUM|FLO, "LocY:", -far, far, bezt->vec[1]+1, 0); + do_clever_numbuts("Active BezierPoint", totbut, REDRAW); + + if(scale10) bezt->vec[1][1]/= 10.0; + + VecSubf(delta, bezt->vec[1], old); + VECCOPY(bezt->vec[1], old); + + /* apply */ + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + if( (ei->flag & IPO_EDIT) || G.sipo->showkey) { + if(ei->icu->bezt) { + bezt= ei->icu->bezt; + b= ei->icu->totvert; + while(b--) { + if(bezt->f2 & 1) { + bezt->vec[0][0]+= delta[0]; + bezt->vec[1][0]+= delta[0]; + bezt->vec[2][0]+= delta[0]; + + bezt->vec[0][1]+= delta[1]; + bezt->vec[1][1]+= delta[1]; + bezt->vec[2][1]+= delta[1]; + } + bezt++; + } + } + } + } + } + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { + sort_time_ipocurve(ei->icu); + testhandles_ipocurve(ei->icu); + } + } + + } + else if(bezt->f1 & 1) { + add_numbut(0, NUM|FLO, "LocX:", -1000, 10000, bezt->vec[0], 0); + if(totbut==2) add_numbut(1, NUM|FLO, "LocY:", -far, far, bezt->vec[0]+1, 0); + + do_clever_numbuts("Active HandlePoint", totbut, REDRAW); + } + else if(bezt->f3 & 1) { + add_numbut(0, NUM|FLO, "LocX:", -1000, 10000, bezt->vec[0], 0); + if(totbut==2) add_numbut(1, NUM|FLO, "LocY:", -far, far, bezt->vec[2]+1, 0); + + do_clever_numbuts("Active HandlePoint", totbut, REDRAW); + } + + editipo_changed(G.sipo, 1); + } + else { + + if(G.sipo->blocktype==ID_KE) { + key= (Key *)G.sipo->from; + + if(key==0) return; + + kb= key->block.first; + while(kb) { + if(kb->flag & SELECT) break; + kb= kb->next; + } + if(kb && G.sipo->rowbut&1) { + add_numbut(0, NUM|FLO, "Pos:", -100, 100, &kb->pos, 0); + do_clever_numbuts("Active Key", 1, REDRAW); + sort_keys(key); + } + } + } +} + +void filter_sampledata(float *data, int sfra, int efra) +{ + float *da; + int a; + + da= data+1; + for(a=sfra+1; a<efra; a++, da++) { + da[0]=(float)( 0.25*da[-1] + 0.5*da[0] + 0.25*da[1]); + } + +} + +void sampledata_to_ipocurve(float *data, int sfra, int efra, IpoCurve *icu) +{ + BezTriple *bezt; + float *da; + int a, tot; + + filter_sampledata(data, sfra, efra); + filter_sampledata(data, sfra, efra); + + icu->ipo= IPO_LIN; + + if(icu->bezt) MEM_freeN(icu->bezt); + icu->bezt= 0; + + tot= 1; /* eerste punt */ + da= data+1; + for(a=sfra+1; a<efra; a++, da++) { + if( IS_EQ(da[0], da[1])==0 && IS_EQ(da[1], da[2])==0 ) tot++; + } + + icu->totvert= tot; + bezt= icu->bezt= MEM_callocN(tot*sizeof(BezTriple), "samplebezt"); + bezt->vec[1][0]= (float)sfra; + bezt->vec[1][1]= data[0]; + bezt++; + da= data+1; + for(a=sfra+1; a<efra; a++, da++) { + if( IS_EQ(da[0], da[1])==0 && IS_EQ(da[1], da[2])==0 ) { + bezt->vec[1][0]= (float)a; + bezt->vec[1][1]= da[0]; + bezt++; + } + } +} + +void ipo_record() +{ + /* 1 of 2 aktieve curves + * kopie maken (ESC) + * + * nulpunt is de huidige stand (of 0) + * dx (dy identiek) is de hoogteverhouding + * CTRL start record + */ + extern double tottime; + EditIpo *ei, *ei1=0, *ei2=0; + ScrArea *sa, *oldarea; + Ipo *ipo; + void *poin; + double swaptime; + float or1, or2 = 0.0, fac, *data1, *data2; + int type, a, afbreek=0, firsttime=1, cfrao, cfra, sfra, efra; + unsigned short event = 0; + short anim, val, xn, yn, mvalo[2], mval[2]; + char str[128]; + + if(G.sipo->from==0) return; + if(SFRA>=EFRA) return; + + anim= pupmenu("Record Mouse %t|Still %x1|Play anim %x2"); + if(anim < 1) return; + if(anim!=2) anim= 0; + + ipo= get_ipo(G.sipo->from, G.sipo->blocktype, 1); /* 1= make */ + if(G.sipo) G.sipo->ipo= ipo; + + /* find the curves... */ + + ei= G.sipo->editipo; + for(a=0; a<G.sipo->totipo; a++) { + if(ei->flag & IPO_VISIBLE) { + + if(ei1==0) ei1= ei; + else if(ei2==0) ei2= ei; + else { + error("Max 2 visible curves"); + return; + } + } + ei++; + } + + if(ei1==0) { + error("Select 1 or 2 channels"); + return; + } + + /* curves gereedmaken, startwaardes */ + if(ei1->icu==0) ei1->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei1->adrcode, 0); + if(ei1->icu==0) return; + poin= get_ipo_poin(G.sipo->from, ei1->icu, &type); + if(poin) ei1->icu->curval= read_ipo_poin(poin, type); + or1= ei1->icu->curval; + ei1->icu->flag |= IPO_LOCK; + + if(ei2) { + if(ei2->icu==0) ei2->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei2->adrcode, 0); + if(ei2->icu==0) return; + poin= get_ipo_poin(G.sipo->from, ei2->icu, &type); + if(poin) ei2->icu->curval= read_ipo_poin(poin, type); + or2= ei2->icu->curval; + ei2->icu->flag |= IPO_LOCK; + } + + fac= G.v2d->cur.ymax - G.v2d->cur.ymin; + fac/= (float)curarea->winy; + + /* welke area */ + oldarea= curarea; + sa= G.curscreen->areabase.first; + while(sa) { + if(sa->win) { + if(G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_LA) { + if(sa->spacetype==SPACE_BUTS) break; + } + else { + if(sa->spacetype==SPACE_VIEW3D) break; + } + } + sa= sa->next; + } + if(sa) areawinset(sa->win); + + /* kandie? */ + while(get_mbut()&L_MOUSE) BIF_wait_for_statechange(); + data1= MEM_callocN(sizeof(float)*(EFRA-SFRA+1), "data1"); + data2= MEM_callocN(sizeof(float)*(EFRA-SFRA+1), "data2"); + + getmouseco_areawin(mvalo); + xn= mvalo[0]; yn= mvalo[1]; + waitcursor(1); + + tottime= 0.0; + swaptime= speed_to_swaptime(G.animspeed); + cfrao= CFRA; + cfra=efra= SFRA; + sfra= EFRA; + + while(afbreek==0) { + + getmouseco_areawin(mval); + + if(mval[0]!= mvalo[0] || mval[1]!=mvalo[1] || firsttime || (G.qual & LR_CTRLKEY)) { + if(anim) CFRA= cfra; + else firsttime= 0; + + set_timecursor(cfra); + + /* ipo doen: eerst alles daarna de specifieke */ + if(anim==2) { + do_all_ipos(); + do_all_keys(); + } + + ei1->icu->curval= or1 + fac*(mval[0]-xn); + if(ei2) ei2->icu->curval= or2 + fac*(mval[1]-yn); + + do_ipo_nocalc(G.sipo->ipo); + do_all_visible_ikas(); + + if(G.qual & LR_CTRLKEY) { + sprintf(str, "Recording... %d\n", cfra); + data1[ cfra-SFRA ]= ei1->icu->curval; + if(ei2) data2[ cfra-SFRA ]= ei2->icu->curval; + + sfra= MIN2(sfra, cfra); + efra= MAX2(efra, cfra); + } + else sprintf(str, "Mouse Recording. Use CTRL to start. LeftMouse or Space to end"); + + do_ob_key(OBACT); + + headerprint(str); + + if(sa) scrarea_do_windraw(sa); + + /* minimaal swaptime laten voorbijgaan */ + tottime -= swaptime; + while (update_time()) PIL_sleep_ms(1); + + screen_swapbuffers(); + + tottime= 0.0; + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + if(anim || (G.qual & LR_CTRLKEY)) { + cfra++; + if(cfra>EFRA) cfra= SFRA; + } + } + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case LEFTMOUSE: case ESCKEY: case SPACEKEY: case RETKEY: + afbreek= 1; + break; + } + } + if(afbreek) break; + } + } + + if(event!=ESCKEY) { + sampledata_to_ipocurve(data1+sfra-SFRA, sfra, efra, ei1->icu); + if(ei2) sampledata_to_ipocurve(data2+sfra-SFRA, sfra, efra, ei2->icu); + + /* vervelend als dat aanstaat */ + if(G.sipo->showkey) { + G.sipo->showkey= 0; + free_ipokey(&G.sipo->ipokey); + } + } + else { + /* undo: startwaardes */ + poin= get_ipo_poin(G.sipo->from, ei1->icu, &type); + if(poin) write_ipo_poin(poin, type, or1); + if(ei1->icu->bezt==0) { + BLI_remlink( &(G.sipo->ipo->curve), ei1->icu); + MEM_freeN(ei1->icu); + ei1->icu= 0; + } + if(ei2) { + poin= get_ipo_poin(G.sipo->from, ei2->icu, &type); + if(poin) write_ipo_poin(poin, type, or2); + if(ei2->icu->bezt==0) { + BLI_remlink( &(G.sipo->ipo->curve), ei2->icu); + MEM_freeN(ei2->icu); + ei2->icu= 0; + } + } + } + + if(ei1->icu) ei1->icu->flag &= ~IPO_LOCK; + if(ei2 && ei2->icu) ei2->icu->flag &= ~IPO_LOCK; + + editipo_changed(G.sipo, 0); + do_ipo(G.sipo->ipo); + waitcursor(0); + allqueue(REDRAWVIEW3D, 0); + if(sa) scrarea_queue_headredraw(sa); /* headerprint */ + scrarea_queue_redraw(oldarea); + CFRA= cfrao; + + /* vooropig? */ + update_for_newframe(); + + MEM_freeN(data1); + MEM_freeN(data2); +} + + + +void remake_object_ipos(Object *ob) +{ + IpoCurve *icu; + + if (!ob) + return; + if (!ob->ipo) + return; + + for (icu = ob->ipo->curve.first; icu; icu=icu->next){ + sort_time_ipocurve(icu); + testhandles_ipocurve(icu); + } +} + + +int is_ipo_key_selected(Ipo *ipo) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return 0; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++) + if (BEZSELECTED(&icu->bezt[i])) + return 1; + } + + return 0; +} + + +void set_ipo_key_selection(Ipo *ipo, int sel) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (sel){ + icu->bezt[i].f1|=1; + icu->bezt[i].f2|=1; + icu->bezt[i].f3|=1; + } + else{ + icu->bezt[i].f1&=~1; + icu->bezt[i].f2&=~1; + icu->bezt[i].f3&=~1; + } + } + } +} + +void delete_ipo_keys(Ipo *ipo) +{ + IpoCurve *icu, *next; + int i; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=next){ + next = icu->next; + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].f2 & 1){ + // Delete the item + memcpy (&icu->bezt[i], &icu->bezt[i+1], sizeof (BezTriple)*(icu->totvert-i-1)); + icu->totvert--; + i--; + } + } + if (!icu->totvert){ + /* Delete the curve */ + BLI_remlink( &(ipo->curve), icu); + if(icu->bezt) MEM_freeN(icu->bezt); + MEM_freeN(icu); + } + } +} + +int fullselect_ipo_keys(Ipo *ipo) +{ + int i; + IpoCurve *icu; + int tvtot = 0; + + if (!ipo) + return tvtot; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].f2 & 1){ + tvtot+=3; + icu->bezt[i].f1 |= 1; + icu->bezt[i].f3 |= 1; + } + } + } + + return tvtot; +} + +int add_trans_ipo_keys(Ipo *ipo, TransVert *tv, int tvtot) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return tvtot; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].f2 & 1){ + tv[tvtot+0].loc=icu->bezt[i].vec[0]; + tv[tvtot+1].loc=icu->bezt[i].vec[1]; + tv[tvtot+2].loc=icu->bezt[i].vec[2]; + + memcpy (&tv[tvtot+0].oldloc, icu->bezt[i].vec[0], sizeof (float)*3); + memcpy (&tv[tvtot+1].oldloc, icu->bezt[i].vec[1], sizeof (float)*3); + memcpy (&tv[tvtot+2].oldloc, icu->bezt[i].vec[2], sizeof (float)*3); + tvtot+=3; + } + } + } + + return tvtot; +} + +void duplicate_ipo_keys(Ipo *ipo) +{ + IpoCurve *icu; + int i; + BezTriple *newbezt; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + /* If a key is selected */ + if (icu->bezt[i].f2 & 1){ + /* Expand the list */ + newbezt = MEM_callocN(sizeof(BezTriple) * (icu->totvert+1), "beztriple"); + memcpy (newbezt, icu->bezt, sizeof(BezTriple) * (i+1)); + memcpy (newbezt+i+1, icu->bezt+i, sizeof(BezTriple)); + memcpy (newbezt+i+2, icu->bezt+i+1, sizeof (BezTriple) *(icu->totvert-(i+1))); + icu->totvert++; + MEM_freeN (icu->bezt); + icu->bezt=newbezt; + /* Unselect the current key*/ + icu->bezt[i].f1 &= ~ 1; + icu->bezt[i].f2 &= ~ 1; + icu->bezt[i].f3 &= ~ 1; + i++; + /* Select the copied key */ + icu->bezt[i].f1 |= 1; + icu->bezt[i].f2 |= 1; + icu->bezt[i].f3 |= 1; + + } + } + } +} + +void borderselect_ipo_key(Ipo *ipo, float xmin, float xmax, int val) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0] > xmin && icu->bezt[i].vec[1][0] < xmax ){ + if (val==1){ + icu->bezt[i].f1 |= 1; + icu->bezt[i].f2 |= 1; + icu->bezt[i].f3 |= 1; + } + else{ + icu->bezt[i].f1 &= ~1; + icu->bezt[i].f2 &= ~1; + icu->bezt[i].f3 &= ~1; + } + } + } + } +} + +void select_ipo_key(Ipo *ipo, float selx, int sel) +{ + int i; + IpoCurve *icu; + + if (!ipo) + return; + + for (icu=ipo->curve.first; icu; icu=icu->next){ + for (i=0; i<icu->totvert; i++){ + if (icu->bezt[i].vec[1][0]==selx){ + if (sel) { + icu->bezt[i].f1 &= ~1; + icu->bezt[i].f2 &= ~1; + icu->bezt[i].f3 &= ~1; + } + else { + icu->bezt[i].f1 |= 1; + icu->bezt[i].f2 |= 1; + icu->bezt[i].f3 |= 1; + } + } + } + } +}
\ No newline at end of file |