diff options
-rw-r--r-- | source/blender/blenkernel/BKE_ipo.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 39 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 164 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 39 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 7 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 1 | ||||
-rw-r--r-- | source/blender/include/BSE_editipo.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_curve_types.h | 8 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ipo_types.h | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/renderPreAndPost.c | 6 | ||||
-rw-r--r-- | source/blender/src/buttons_shading.c | 2 | ||||
-rw-r--r-- | source/blender/src/drawipo.c | 213 | ||||
-rw-r--r-- | source/blender/src/editipo.c | 429 | ||||
-rw-r--r-- | source/blender/src/editobject.c | 17 | ||||
-rw-r--r-- | source/blender/src/header_ipo.c | 22 | ||||
-rw-r--r-- | source/blender/src/interface.c | 35 |
18 files changed, 766 insertions, 229 deletions
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h index c0a5be27bcf..6acbceb8e3f 100644 --- a/source/blender/blenkernel/BKE_ipo.h +++ b/source/blender/blenkernel/BKE_ipo.h @@ -52,7 +52,10 @@ struct ID; /* struct IPO_Channel; */ float frame_to_float(int cfra); + +void free_ipo_curve(struct IpoCurve *icu); void free_ipo(struct Ipo *ipo); + struct Ipo *add_ipo(char *name, int idcode); struct Ipo *copy_ipo(struct Ipo *ipo); void make_local_obipo(struct Ipo *ipo); @@ -79,11 +82,14 @@ void *give_mtex_poin(struct MTex *mtex, int adrcode ); void *get_ipo_poin(struct ID *id, struct IpoCurve *icu, int *type); void set_icu_vars(struct IpoCurve *icu); void execute_ipo(struct ID *id, struct Ipo *ipo); + void do_ipo_nocalc(struct Ipo *ipo); void do_ipo(struct Ipo *ipo); void do_mat_ipo(struct Material *ma); void do_ob_ipo(struct Object *ob); void do_seq_ipo(struct Sequence *seq); +void do_ob_ipodrivers(struct Object *ob, struct Ipo *ipo); + int has_ipo_code(struct Ipo *ipo, int code); void do_all_data_ipos(void); int calc_ipo_spec(struct Ipo *ipo, int adrcode, float *ctime); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 9c06c2d015d..6fd3cbcfd8b 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -756,7 +756,7 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own if(data->subtarget[0]) { pchan = get_pose_channel(data->tar->pose, data->subtarget); if (pchan) { - float arm_mat[3][3], pose_mat[3][3]; + float arm_mat[3][3], pose_mat[3][3]; /* arm mat should be bone mat! bug... */ Mat3CpyMat4(arm_mat, pchan->bone->arm_mat); Mat3CpyMat4(pose_mat, pchan->pose_mat); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 61a0ea20a2e..45c9d0b874e 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -47,6 +47,7 @@ #include "DNA_ID.h" #include "DNA_effect_types.h" #include "DNA_lattice_types.h" +#include "DNA_key_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" @@ -289,6 +290,23 @@ DagForest * dag_init() return forest; } +static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int isdata) +{ + IpoCurve *icu; + DagNode *node1; + + for(icu= ipo->curve.first; icu; icu= icu->next) { + if(icu->driver && icu->driver->ob) { + node1 = dag_get_node(dag, icu->driver->ob); + if(icu->driver->blocktype==ID_AR) + dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB); + else + dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB); + } + } +} + + struct DagForest *build_dag(struct Scene *sce, short mask) { Base *base; @@ -300,6 +318,7 @@ struct DagForest *build_dag(struct Scene *sce, short mask) DagNode * scenenode; DagForest *dag; DagAdjList *itA; + Key *key; dag = sce->theDag; sce->dagisvalid=1; @@ -324,9 +343,8 @@ struct DagForest *build_dag(struct Scene *sce, short mask) dag_add_relation(dag,node,node2,DAG_RL_DATA); node2->first_ancestor = ob; node2->ancestor_count += 1; - - } + if (ob->type == OB_ARMATURE) { if (ob->pose){ bPoseChannel *pchan; @@ -354,6 +372,23 @@ struct DagForest *build_dag(struct Scene *sce, short mask) } } } + + /* driver dependencies */ + if(ob->ipo) + dag_add_driver_relation(ob->ipo, dag, node, 0); + + key= ob_get_key(ob); + if(key && key->ipo) + dag_add_driver_relation(key->ipo, dag, node, 1); + + if(ob->action) { + bActionChannel *chan; + for (chan = ob->action->chanbase.first; chan; chan=chan->next){ + if(chan->ipo) + dag_add_driver_relation(chan->ipo, dag, node, 1); + } + } + if (ob->modifiers.first) { ModifierData *md; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index ece3e39ae1e..36f461feaf2 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -42,6 +42,7 @@ #include "MEM_guardedalloc.h" #include "DNA_action_types.h" +#include "DNA_armature_types.h" #include "DNA_curve_types.h" #include "DNA_camera_types.h" #include "DNA_lamp_types.h" @@ -184,17 +185,24 @@ float frame_to_float(int cfra) /* see also bsystem_time in object.c */ return ctime; } +/* includes ipo curve itself */ +void free_ipo_curve(IpoCurve *icu) +{ + if(icu->bezt) MEM_freeN(icu->bezt); + if(icu->bp) MEM_freeN(icu->bp); + if(icu->driver) MEM_freeN(icu->driver); + MEM_freeN(icu); +} + /* do not free ipo itself */ void free_ipo(Ipo *ipo) { IpoCurve *icu; - icu= ipo->curve.first; - while(icu) { - if(icu->bezt) MEM_freeN(icu->bezt); - icu= icu->next; + while( (icu= ipo->curve.first) ) { + BLI_remlink(&ipo->curve, icu); + free_ipo_curve(icu); } - BLI_freelistN(&ipo->curve); } Ipo *add_ipo(char *name, int idcode) @@ -212,7 +220,7 @@ Ipo *copy_ipo(Ipo *ipo) Ipo *ipon; IpoCurve *icu; - if(ipo==0) return 0; + if(ipo==NULL) return 0; ipon= copy_libblock(ipo); @@ -221,6 +229,7 @@ Ipo *copy_ipo(Ipo *ipo) icu= ipon->curve.first; while(icu) { icu->bezt= MEM_dupallocN(icu->bezt); + if(icu->driver) icu->driver= MEM_dupallocN(icu->driver); icu= icu->next; } @@ -247,7 +256,7 @@ void make_local_obipo(Ipo *ipo) ob= ob->id.next; } - if(local && lib==0) { + if(local && lib==NULL) { ipo->id.lib= 0; ipo->id.flag= LIB_LOCAL; new_id(0, (ID *)ipo, 0); @@ -260,7 +269,7 @@ void make_local_obipo(Ipo *ipo) while(ob) { if(ob->ipo==ipo) { - if(ob->id.lib==0) { + if(ob->id.lib==NULL) { ob->ipo= ipon; ipon->id.us++; ipo->id.us--; @@ -291,7 +300,7 @@ void make_local_matipo(Ipo *ipo) ma= ma->id.next; } - if(local && lib==0) { + if(local && lib==NULL) { ipo->id.lib= 0; ipo->id.flag= LIB_LOCAL; new_id(0, (ID *)ipo, 0); @@ -304,7 +313,7 @@ void make_local_matipo(Ipo *ipo) while(ma) { if(ma->ipo==ipo) { - if(ma->id.lib==0) { + if(ma->id.lib==NULL) { ma->ipo= ipon; ipon->id.us++; ipo->id.us--; @@ -335,7 +344,7 @@ void make_local_keyipo(Ipo *ipo) key= key->id.next; } - if(local && lib==0) { + if(local && lib==NULL) { ipo->id.lib= 0; ipo->id.flag= LIB_LOCAL; new_id(0, (ID *)ipo, 0); @@ -348,7 +357,7 @@ void make_local_keyipo(Ipo *ipo) while(key) { if(key->ipo==ipo) { - if(key->id.lib==0) { + if(key->id.lib==NULL) { key->ipo= ipon; ipon->id.us++; ipo->id.us--; @@ -363,7 +372,7 @@ void make_local_keyipo(Ipo *ipo) void make_local_ipo(Ipo *ipo) { - if(ipo->id.lib==0) return; + if(ipo->id.lib==NULL) return; if(ipo->id.us==1) { ipo->id.lib= 0; ipo->id.flag= LIB_LOCAL; @@ -443,7 +452,7 @@ void testhandles_ipocurve(IpoCurve *icu) int flag, a; bezt= icu->bezt; - if(bezt==0) return; + if(bezt==NULL) return; a= icu->totvert; while(a--) { @@ -675,6 +684,86 @@ void berekenx(float *f, float *o, int b) } } +static float eval_driver(IpoDriver *driver) +{ + Object *ob= driver->ob; + + if(ob==NULL) return 0.0f; + + if(driver->blocktype==ID_OB) { + switch(driver->adrcode) { + case OB_LOC_X: + return ob->loc[0]; + case OB_LOC_Y: + return ob->loc[1]; + case OB_LOC_Z: + return ob->loc[2]; + case OB_ROT_X: + return ob->rot[0]/(M_PI_2/9.0); + case OB_ROT_Y: + return ob->rot[1]/(M_PI_2/9.0); + case OB_ROT_Z: + return ob->rot[2]/(M_PI_2/9.0); + case OB_SIZE_X: + return ob->size[0]; + case OB_SIZE_Y: + return ob->size[1]; + case OB_SIZE_Z: + return ob->size[2]; + } + } + else { /* ID_AR */ + bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name); + if(pchan && pchan->bone) { + float pose_mat[3][3]; + float diff_mat[3][3], par_mat[3][3], ipar_mat[3][3]; + float eul[3], size[3]; + + /* we need the local transform = current transform - (parent transform + bone transform) */ + + Mat3CpyMat4(pose_mat, pchan->pose_mat); + + if (pchan->parent) { + Mat3CpyMat4(par_mat, pchan->parent->pose_mat); + Mat3MulMat3(diff_mat, par_mat, pchan->bone->bone_mat); + + Mat3Inv(ipar_mat, diff_mat); + } + else { + Mat3Inv(ipar_mat, pchan->bone->bone_mat); + } + + Mat3MulMat3(diff_mat, ipar_mat, pose_mat); + + Mat3ToEul(diff_mat, eul); + Mat3ToSize(diff_mat, size); + + switch(driver->adrcode) { + case OB_LOC_X: + return pchan->loc[0]; + case OB_LOC_Y: + return pchan->loc[1]; + case OB_LOC_Z: + return pchan->loc[2]; + case OB_ROT_X: + return eul[0]/(M_PI_2/9.0); + case OB_ROT_Y: + return eul[1]/(M_PI_2/9.0); + case OB_ROT_Z: + return eul[2]/(M_PI_2/9.0); + case OB_SIZE_X: + return size[0]; + case OB_SIZE_Y: + return size[1]; + case OB_SIZE_Z: + return size[2]; + } + } + } + + return 0.0f; +} + float eval_icu(IpoCurve *icu, float ipotime) { BezTriple *bezt, *prevbezt; @@ -684,6 +773,10 @@ float eval_icu(IpoCurve *icu, float ipotime) cycyofs= 0.0; + if(icu->driver) { + /* ipotime now serves as input for the curve */ + ipotime= cvalue= eval_driver(icu->driver); + } if(icu->bezt) { prevbezt= icu->bezt; bezt= prevbezt+1; @@ -814,10 +907,12 @@ void calc_ipo(Ipo *ipo, float ctime) { IpoCurve *icu; + if(ipo==NULL) return; + icu= ipo->curve.first; while(icu) { - if( (icu->flag & IPO_LOCK)==0) calc_icu(icu, ctime); + if(icu->driver || (icu->flag & IPO_LOCK)==0) calc_icu(icu, ctime); icu= icu->next; } @@ -1186,7 +1281,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type) poin= &(ma->add); break; } - if(poin==0) { + if(poin==NULL) { mtex= 0; if(icu->adrcode & MA_MAP1) mtex= ma->mtex[0]; else if(icu->adrcode & MA_MAP2) mtex= ma->mtex[1]; @@ -1270,7 +1365,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type) poin= &(wo->starsize); break; } - if(poin==0) { + if(poin==NULL) { mtex= 0; if(icu->adrcode & MA_MAP1) mtex= wo->mtex[0]; else if(icu->adrcode & MA_MAP2) mtex= wo->mtex[1]; @@ -1315,7 +1410,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type) poin= &(la->haint); break; } - if(poin==0) { + if(poin==NULL) { mtex= 0; if(icu->adrcode & MA_MAP1) mtex= la->mtex[0]; else if(icu->adrcode & MA_MAP2) mtex= la->mtex[1]; @@ -1650,7 +1745,7 @@ void execute_ipo(ID *id, Ipo *ipo) void *poin; int type; - if(ipo==0) return; + if(ipo==NULL) return; icu= ipo->curve.first; while(icu) { @@ -1673,7 +1768,7 @@ void do_ipo_nocalc(Ipo *ipo) Camera *ca; bSound *snd; - if(ipo==0) return; + if(ipo==NULL) return; switch(ipo->blocktype) { case ID_OB: @@ -1747,7 +1842,7 @@ void do_mat_ipo(Material *ma) { float ctime; - if(ma==0 || ma->ipo==0) return; + if(ma==NULL || ma->ipo==NULL) return; ctime= frame_to_float(G.scene->r.cfra); /* if(ob->ipoflag & OB_OFFS_OB) ctime-= ob->sf; */ @@ -1762,7 +1857,7 @@ void do_ob_ipo(Object *ob) float ctime; unsigned int lay; - if(ob->ipo==0) return; + if(ob->ipo==NULL) return; /* do not set ob->ctime here: for example when parent in invisible layer */ @@ -1785,6 +1880,21 @@ void do_ob_ipo(Object *ob) } } +void do_ob_ipodrivers(Object *ob, Ipo *ipo) +{ + IpoCurve *icu; + void *poin; + int type; + + for(icu= ipo->curve.first; icu; icu= icu->next) { + if(icu->driver) { + icu->curval= eval_icu(icu, 0.0f); + poin= get_ipo_poin((ID *)ob, icu, &type); + if(poin) write_ipo_poin(poin, type, icu->curval); + } + } +} + void do_seq_ipo(Sequence *seq) { float ctime, div; @@ -1794,7 +1904,7 @@ void do_seq_ipo(Sequence *seq) if(seq->ipo) { ctime= frame_to_float(G.scene->r.cfra - seq->startdisp); div= (seq->enddisp - seq->startdisp)/100.0f; - if(div==0) return; + if(div==0.0) return; /* 2nd field */ calc_ipo(seq->ipo, (ctime+0.5f)/div); @@ -1813,7 +1923,7 @@ int has_ipo_code(Ipo *ipo, int code) { IpoCurve *icu; - if(ipo==0) return 0; + if(ipo==NULL) return 0; icu= ipo->curve.first; while(icu) { @@ -1924,7 +2034,7 @@ int calc_ipo_spec(Ipo *ipo, int adrcode, float *ctime) { IpoCurve *icu; - if(ipo==0) return 0; + if(ipo==NULL) return 0; icu= ipo->curve.first; while(icu) { @@ -1948,11 +2058,11 @@ void clear_delta_obipo(Ipo *ipo) { Object *ob; - if(ipo==0) return; + if(ipo==NULL) return; ob= G.main->object.first; while(ob) { - if(ob->id.lib==0) { + if(ob->id.lib==NULL) { if(ob->ipo==ipo) { memset(&ob->dloc, 0, 12); memset(&ob->drot, 0, 12); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index c32874f69c5..d0c0b1f9927 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -935,6 +935,8 @@ static int do_mesh_key(Mesh *me) else { ctime= bsystem_time(0, 0, (float)G.scene->r.cfra, 0.0); + calc_ipo(me->key->ipo, ctime); /* also all relative key positions */ + if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; CLAMP(ctime, 0.0, 1.0); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 29bfff8bc66..aa8efe61565 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -237,6 +237,7 @@ void unlink_object(Object *ob) Scene *sce; Curve *cu; Tex *tex; + Ipo *ipo; Group *group; bConstraint *con; int a; @@ -308,7 +309,7 @@ void unlink_object(Object *ob) for(a=0; a<MAX_MTEX; a++) { if(mat->mtex[a] && ob==mat->mtex[a]->object) { /* actually, test for lib here... to do */ - mat->mtex[a]->object= 0; + mat->mtex[a]->object= NULL; } } @@ -319,7 +320,7 @@ void unlink_object(Object *ob) tex= G.main->tex.first; while(tex) { if(tex->env) { - if(tex->env->object == ob) tex->env->object= 0; + if(tex->env->object == ob) tex->env->object= NULL; } tex= tex->id.next; } @@ -333,10 +334,10 @@ void unlink_object(Object *ob) /* worlds */ wrld= G.main->world.first; while(wrld) { - if(wrld->id.lib==0) { + if(wrld->id.lib==NULL) { for(a=0; a<MAX_MTEX; a++) { if(wrld->mtex[a] && ob==wrld->mtex[a]->object) - wrld->mtex[a]->object =0; + wrld->mtex[a]->object= NULL; } } @@ -346,12 +347,23 @@ void unlink_object(Object *ob) /* scenes */ sce= G.main->scene.first; while(sce) { - if(sce->id.lib==0) { - if(sce->camera==ob) sce->camera= 0; + if(sce->id.lib==NULL) { + if(sce->camera==ob) sce->camera= NULL; } sce= sce->id.next; } - /* keys */ + /* ipos */ + ipo= G.main->ipo.first; + while(ipo) { + if(ipo->id.lib==NULL) { + IpoCurve *icu; + for(icu= ipo->curve.first; icu; icu= icu->next) { + if(icu->driver && icu->driver->ob==ob) + icu->driver->ob= NULL; + } + } + ipo= ipo->id.next; + } /* screens */ sc= G.main->screen.first; @@ -365,11 +377,11 @@ void unlink_object(Object *ob) View3D *v3d= (View3D*) sl; if(v3d->camera==ob) { - v3d->camera= 0; + v3d->camera= NULL; if(v3d->persp>1) v3d->persp= 1; } if(v3d->localvd && v3d->localvd->camera==ob ) { - v3d->localvd->camera= 0; + v3d->localvd->camera= NULL; if(v3d->localvd->persp>1) v3d->localvd->persp= 1; } } @@ -1285,8 +1297,9 @@ void where_is_object_time(Object *ob, float ctime) if(ob==NULL) return; + /* this is needed to be able to grab objects with ipos, otherwise it always freezes them */ stime= bsystem_time(ob, 0, ctime, 0.0); - if( stime != ob->ctime) { + if(stime != ob->ctime) { ob->ctime= stime; if(ob->ipo) { @@ -1296,7 +1309,11 @@ void where_is_object_time(Object *ob, float ctime) /* do constraint ipos ... */ do_constraint_channels(&ob->constraints, &ob->constraintChannels, ctime); } - + else { + /* but, the drivers have to be done */ + if(ob->ipo) do_ob_ipodrivers(ob, ob->ipo); + } + if(ob->parent) { par= ob->parent; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index da342c2f656..54b4e494169 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1707,7 +1707,11 @@ static void lib_link_ipo(FileData *fd, Main *main) ipo= main->ipo.first; while(ipo) { if(ipo->id.flag & LIB_NEEDLINK) { - + IpoCurve *icu; + for(icu= ipo->curve.first; icu; icu= icu->next) { + if(icu->driver) + icu->driver->ob= newlibadr(fd, ipo->id.lib, icu->driver->ob); + } ipo->id.flag -= LIB_NEEDLINK; } ipo= ipo->id.next; @@ -1723,6 +1727,7 @@ static void direct_link_ipo(FileData *fd, Ipo *ipo) while(icu) { icu->bezt= newdataadr(fd, icu->bezt); icu->bp= newdataadr(fd, icu->bp); + icu->driver= newdataadr(fd, icu->driver); icu= icu->next; } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index bce6dceb384..f941b5f77d2 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -770,6 +770,7 @@ static void write_ipos(WriteData *wd, ListBase *idbase) while(icu) { if(icu->bezt) writestruct(wd, DATA, "BezTriple", icu->totvert, icu->bezt); if(icu->bp) writestruct(wd, DATA, "BPoint", icu->totvert, icu->bp); + if(icu->driver) writestruct(wd, DATA, "IpoDriver", 1, icu->driver); icu= icu->next; } } diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h index d96565f95b4..e0036de5eac 100644 --- a/source/blender/include/BSE_editipo.h +++ b/source/blender/include/BSE_editipo.h @@ -59,6 +59,8 @@ char *getname_la_ei(int nr); char *getname_cam_ei(int nr); char *getname_snd_ei(int nr); +struct EditIpo *get_active_editipo(void); + void boundbox_ipocurve(struct IpoCurve *icu); void boundbox_ipo(struct Ipo *ipo, struct rctf *bb); void editipo_changed(struct SpaceIpo *si, int doredraw); diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 5c99671dd54..2078875215f 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -171,6 +171,12 @@ typedef struct Curve { struct CharInfo curinfo; } Curve; +typedef struct IpoDriver { + struct Object *ob; + short blocktype, adrcode, type, flag; + char name[32]; /* bone or constraint(?) name, later we can add python expression here */ +} IpoDriver; + typedef struct IpoCurve { struct IpoCurve *next, *prev; @@ -188,6 +194,8 @@ typedef struct IpoCurve { float curval; + IpoDriver *driver; + } IpoCurve; /* **************** CURVE ********************* */ diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h index c658d40db79..b3cb0c81148 100644 --- a/source/blender/makesdna/DNA_ipo_types.h +++ b/source/blender/makesdna/DNA_ipo_types.h @@ -359,6 +359,7 @@ typedef short IPO_Channel; #define IPO_EDIT 4 #define IPO_LOCK 8 #define IPO_AUTO_HORIZ 16 +#define IPO_ACTIVE 32 #endif diff --git a/source/blender/render/intern/source/renderPreAndPost.c b/source/blender/render/intern/source/renderPreAndPost.c index 0f7a98843ce..defb6b97ff6 100644 --- a/source/blender/render/intern/source/renderPreAndPost.c +++ b/source/blender/render/intern/source/renderPreAndPost.c @@ -70,12 +70,12 @@ void prepareScene() /* RADIO */ if(R.r.mode & R_RADIO) do_radio_render(); - /* ENVIRONMENT MAPS */ - make_envmaps(); - /* octree */ if(R.r.mode & R_RAYTRACE) makeoctree(); + /* ENVIRONMENT MAPS */ + make_envmaps(); + } } diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 1047c46f787..93addb8e20d 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2544,7 +2544,7 @@ void do_matbuts(unsigned short event) /* same for 'xtreme alpha' which is 'only shadow' */ ma= G.buts->lockpoin; if((ma->mode & MA_HALO)==0) { - ma->mode &= ~(MA_STAR|MA_HALO_XALPHA); + ma->mode &= ~(MA_STAR|MA_HALO_XALPHA|MA_ZINV); } BIF_preview_changed(G.buts); allqueue(REDRAWBUTSSHADING, 0); diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c index c18d9aba1c1..f2546d20d39 100644 --- a/source/blender/src/drawipo.c +++ b/source/blender/src/drawipo.c @@ -45,6 +45,7 @@ #endif #include "BMF_Api.h" +#include "MEM_guardedalloc.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -786,8 +787,20 @@ void drawscroll(int disptype) scroll_prstr(fac, 3.0+(float)(hor.ymin), fac2, 'h', disptype); } } - else { - scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype); + else { /* space ipo */ + EditIpo *ei= get_active_editipo(); + + if(ei && ei->icu && ei->icu->driver) { + int adrcode= ei->icu->driver->adrcode; + + if(adrcode==OB_ROT_X || adrcode==OB_ROT_Y || adrcode==OB_ROT_Z) { + scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'v', IPO_DISPDEGR); + } + else + scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype); + } + else + scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype); } fac+= dfac; @@ -910,16 +923,17 @@ static void draw_ipobuts(SpaceIpo *sipo) sel= ei->flag & (IPO_SELECT + IPO_EDIT); uiEmboss((float)(v2d->mask.xmax+8), (float)(y+2), (float)(v2d->mask.xmax+15), (float)(y+IPOBUTY-2), sel); - } - - if(sipo->blocktype==ID_KE) { - Key *key= (Key *)sipo->from; - if(key==NULL || key->type==KEY_NORMAL) break; - if(a==ob->shapenr-1) { + + if(ei->icu->driver) { cpack(0x0); - fdrawbox(v2d->mask.xmax+7, y+1, v2d->mask.xmax+16, y+IPOBUTY-1); + fdrawbox((float)v2d->mask.xmax+11, (float)y+8, (float)v2d->mask.xmax+12.5, (float)y+9.5); } } + + if(ei->flag & IPO_ACTIVE) { + cpack(0x0); + fdrawbox(v2d->mask.xmax+7, y+1, v2d->mask.xmax+16, y+IPOBUTY-1); + } } uiDrawBlock(block); } @@ -1247,7 +1261,9 @@ static void draw_ipocurves(int sel) glVertex2fv(v1); } else { - resol= 3.0*sqrt(bezt->vec[1][0] - prevbezt->vec[1][0]); + /* resol not depending on horizontal resolution anymore, drivers for example... */ + if(icu->driver) resol= 32; + else resol= 3.0*sqrt(bezt->vec[1][0] - prevbezt->vec[1][0]); if(resol<2) { v1[0]= prevbezt->vec[1][0]+cycxofs; @@ -1439,11 +1455,13 @@ static void draw_key(SpaceIpo *sipo, int visible) #define B_MUL_IPO 3402 #define B_TRANS_IPO 3403 #define B_IPO_NONE 3404 +#define B_IPO_DRIVER 3405 +#define B_IPO_REDR 3406 +#define B_IPO_DEPCHANGE 3407 static float hspeed= 0; - -static void boundbox_ipo_visible(SpaceIpo *si) +static void boundbox_ipo_curves(SpaceIpo *si) { EditIpo *ei; Key *key; @@ -1550,20 +1568,21 @@ static void ipo_editvertex_buts(uiBlock *block, SpaceIpo *si, float min, float m VECCOPY(si->median, median); + uiBlockBeginAlign(block); if(tot==1) { if(iskey) uiDefButF(block, NUM, B_TRANS_IPO, "Key Y:", 10, 80, 300, 19, &(si->median[1]), min, max, 10, 0, ""); else { - uiDefButF(block, NUM, B_TRANS_IPO, "Vertex X:", 10, 100, 300, 19, &(si->median[0]), min, max, 100, 0, ""); - uiDefButF(block, NUM, B_TRANS_IPO, "Vertex Y:", 10, 80, 300, 19, &(si->median[1]), min, max, 100, 0, ""); + uiDefButF(block, NUM, B_TRANS_IPO, "Vertex X:", 10, 100, 150, 19, &(si->median[0]), min, max, 100, 0, ""); + uiDefButF(block, NUM, B_TRANS_IPO, "Vertex Y:", 160, 100, 150, 19, &(si->median[1]), min, max, 100, 0, ""); } } else { if(iskey) uiDefButF(block, NUM, B_TRANS_IPO, "Median Key Y:", 10, 80, 300, 19, &(si->median[1]), min, max, 10, 0, ""); else { - uiDefButF(block, NUM, B_TRANS_IPO, "Median X:", 10, 100, 300, 19, &(si->median[0]), min, max, 100, 0, ""); - uiDefButF(block, NUM, B_TRANS_IPO, "Median Y:", 10, 80, 300, 19, &(si->median[1]), min, max, 100, 0, ""); + uiDefButF(block, NUM, B_TRANS_IPO, "Median X:", 10, 100, 150, 19, &(si->median[0]), min, max, 100, 0, ""); + uiDefButF(block, NUM, B_TRANS_IPO, "Median Y:", 160, 100, 150, 19, &(si->median[1]), min, max, 100, 0, ""); } } } @@ -1624,8 +1643,22 @@ static void ipo_editvertex_buts(uiBlock *block, SpaceIpo *si, float min, float m void do_ipobuts(unsigned short event) { Object *ob= OBACT; + EditIpo *ei; switch(event) { + case B_IPO_REDR: + ei= get_active_editipo(); + if(ei) { + if(ei->icu->driver) { + if(G.sipo->blocktype==ID_KE || G.sipo->blocktype==ID_AC) + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + else + DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); + } + } + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + break; case B_SETSPEED: set_speed_editipo(hspeed); break; @@ -1645,28 +1678,167 @@ void do_ipobuts(unsigned short event) allqueue(REDRAWIPO, 0); allqueue(REDRAWBUTSEDIT, 0); break; + case B_IPO_DRIVER: + ei= get_active_editipo(); + if(ei) { + if(ei->icu==NULL) { + ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0); + ei->flag |= IPO_SELECT; + ei->icu->flag= ei->flag; + } + if(ei->icu->driver) { + MEM_freeN(ei->icu->driver); + ei->icu->driver= NULL; + if(ei->icu->bezt==NULL) { + BLI_remlink( &(G.sipo->ipo->curve), ei->icu); + free_ipo_curve(ei->icu); + ei->icu= NULL; + } + } + else { + ei->icu->driver= MEM_callocN(sizeof(IpoDriver), "ipo driver"); + ei->icu->driver->blocktype= ID_OB; + ei->icu->driver->adrcode= OB_LOC_X; + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWBUTSEDIT, 0); + DAG_scene_sort(G.scene); + + BIF_undo_push("Add/Remove Ipo driver"); + } + break; + case B_IPO_DEPCHANGE: + ei= get_active_editipo(); + if(ei) { + if(ei->icu->driver) { + IpoDriver *driver= ei->icu->driver; + + /* check if type is still OK */ + if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR); + else driver->blocktype= ID_OB; + + DAG_scene_sort(G.scene); + + if(G.sipo->blocktype==ID_KE || G.sipo->blocktype==ID_AC) + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + else + DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); + } + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWBUTSEDIT, 0); + break; + } +} + +static char *ipodriver_modeselect_pup(Object *ob) +{ + static char string[265]; + char tmpstr[64]; + char formatstring[64]; + + strcpy(string, "Driver type: %t"); + + strcpy(formatstring, "|%s %%x%d %%i%d"); + + if(ob) { + sprintf(tmpstr,formatstring,"Object",ID_OB, ICON_OBJECT); + strcat(string,tmpstr); } + if(ob && ob->type==OB_ARMATURE) { + sprintf(tmpstr,formatstring,"Pose",ID_AR, ICON_POSE_DEHLT); + strcat(string,tmpstr); + } + + return (string); } +static char *ipodriver_channelselect_pup(void) +{ + static char string[1024]; + char *tmp; + + strcpy(string, "Driver channel: %t"); + tmp= string+strlen(string); + + tmp+= sprintf(tmp, "|Loc X %%x%d", OB_LOC_X); + tmp+= sprintf(tmp, "|Loc Y %%x%d", OB_LOC_Y); + tmp+= sprintf(tmp, "|Loc Z %%x%d", OB_LOC_Z); + tmp+= sprintf(tmp, "|Rot X %%x%d", OB_ROT_X); + tmp+= sprintf(tmp, "|Rot Y %%x%d", OB_ROT_Y); + tmp+= sprintf(tmp, "|Rot Z %%x%d", OB_ROT_Z); + tmp+= sprintf(tmp, "|Size X %%x%d", OB_SIZE_X); + tmp+= sprintf(tmp, "|Size Y %%x%d", OB_SIZE_Y); + tmp+= sprintf(tmp, "|Size Z %%x%d", OB_SIZE_Z); + + return (string); +} static void ipo_panel_properties(short cntrl) // IPO_HANDLER_PROPERTIES { - extern int totipo_vis; // editipo.c + extern int totipo_curve; // editipo.c uiBlock *block; + EditIpo *ei; + char name[48]; block= uiNewBlock(&curarea->uiblocks, "ipo_panel_properties", UI_EMBOSS, UI_HELV, curarea->win); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); uiSetPanelHandler(IPO_HANDLER_PROPERTIES); // for close and esc if(uiNewPanel(curarea, block, "Transform Properties", "Ipo", 10, 230, 318, 204)==0) return; + /* this is new panel height, newpanel doesnt force new size on existing panels */ + uiNewPanelHeight(block, 204); + + /* driver buttons first */ + ei= get_active_editipo(); + if(ei) { + + sprintf(name, "Driven Channel: %s", ei->name); + uiDefBut(block, LABEL, 0, name, 10, 265, 200, 19, NULL, 1.0, 0.0, 0, 0, ""); + + if(ei->icu && ei->icu->driver) { + IpoDriver *driver= ei->icu->driver; + + uiDefBut(block, BUT, B_IPO_DRIVER, "Remove", 210,265,100,19, NULL, 0.0f, 0.0f, 0, 0, "Remove Driver for this Ipo Channel"); + + uiBlockBeginAlign(block); + uiDefIDPoinBut(block, test_obpoin_but, B_IPO_DEPCHANGE, "OB:", 10, 240, 150, 20, &(driver->ob), "Driver Object"); + if(driver->ob) { + int icon=ICON_OBJECT; + + if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR) { + icon = ICON_POSE_DEHLT; + uiDefBut(block, TEX, B_IPO_REDR, "BO:", 10,220,150,20, driver->name, 0, 31, 0, 0, "Bone name"); + } + else driver->blocktype= ID_OB; /* safety when switching object button */ + + uiBlockBeginAlign(block); + uiDefIconTextButS(block, MENU, B_IPO_DEPCHANGE, icon, + ipodriver_modeselect_pup(driver->ob), 165,240,145,20, &(driver->blocktype), 0, 0, 0, 0, "Driver type"); + + uiDefButS(block, MENU, B_IPO_REDR, + ipodriver_channelselect_pup(), 165,220,145,20, &(driver->adrcode), 0, 0, 0, 0, "Driver channel"); + } + uiBlockEndAlign(block); + } + else { + uiDefBut(block, BUT, B_IPO_DRIVER, "Add Driver", 210,265,100,19, NULL, 0.0f, 0.0f, 0, 0, "Create a Driver for this Ipo Channel"); + } + } + else + uiDefBut(block, LABEL, 0, " ", 10, 265, 150, 19, NULL, 1.0, 0.0, 0, 0, ""); - boundbox_ipo_visible(G.sipo); // should not be needed... transform/draw calls should update + boundbox_ipo_curves(G.sipo); // should not be needed... transform/draw calls should update /* note ranges for buttons below are idiot... we need 2 ranges, one for sliding scale, one for real clip */ - if(G.sipo->ipo && G.sipo->ipo->curve.first && totipo_vis) { + if(G.sipo->ipo && G.sipo->ipo->curve.first && totipo_curve) { extern int totipo_vertsel; // editipo.c uiDefBut(block, LABEL, 0, "Visible curves", 10, 200, 150, 19, NULL, 1.0, 0.0, 0, 0, ""); + uiBlockBeginAlign(block); uiDefButF(block, NUM, B_MUL_IPO, "Xmin:", 10, 180, 150, 19, &G.sipo->tot.xmin, G.sipo->tot.xmin-1000.0, MAXFRAMEF, 100, 0, ""); uiDefButF(block, NUM, B_MUL_IPO, "Xmax:", 160, 180, 150, 19, &G.sipo->tot.xmax, G.sipo->tot.ymin-1000.0, MAXFRAMEF, 100, 0, ""); @@ -1675,7 +1847,8 @@ static void ipo_panel_properties(short cntrl) // IPO_HANDLER_PROPERTIES /* SPEED BUTTON */ if(totipo_vertsel) { - uiDefButF(block, NUM, B_IPO_NONE, "Speed:", 10,130,150,19, &hspeed, 0.0, 180.0, 1, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_IPO_NONE, "Speed:", 10,130,150,19, &hspeed, 0.0, 180.0, 1, 0, ""); uiDefBut(block, BUT, B_SETSPEED,"SET", 160,130,50,19, 0, 0, 0, 0, 0, ""); } } diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index 05974e251d0..a3f579db4c5 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -288,6 +288,86 @@ char *getname_snd_ei(int nr) return ic_name_empty[0]; } +/* tests if only one editipo is active */ +static void check_active_editipo(void) +{ + EditIpo *ei, *actei; + int a; + + actei= G.sipo->editipo; + if(actei) { + for(a=0; a<G.sipo->totipo; a++, actei++) { + if(actei->flag & IPO_ACTIVE) + break; + } + if(actei==NULL) { + /* set visible active */ + for(a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) { + if(ei->flag & IPO_VISIBLE) + break; + } + if(ei==NULL) ei=G.sipo->editipo; + ei->flag |= IPO_ACTIVE; + if(ei->icu) ei->icu->flag |= IPO_ACTIVE; + } + else { + /* make sure no others are active */ + for(a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) { + if(ei!=actei) { + ei->flag &= ~IPO_ACTIVE; + if(ei->icu) ei->icu->flag &= ~IPO_ACTIVE; + } + } + } + } +} + +/* sets this ei channel active */ +static void set_active_editipo(EditIpo *actei) +{ + EditIpo *ei; + int a; + + for(a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) { + ei->flag &= ~IPO_ACTIVE; + if(ei->icu) ei->icu->flag &= ~IPO_ACTIVE; + } + actei->flag |= IPO_ACTIVE; + if(actei->icu) actei->icu->flag |= IPO_ACTIVE; +} + +EditIpo *get_active_editipo(void) +{ + EditIpo *ei= G.sipo->editipo; + int a; + + for(a=0; a<G.sipo->totipo; a++, ei++) + if(ei->flag & IPO_ACTIVE) + return ei; + + return NULL; +} + +static void set_active_key(int index) +{ + if(G.sipo->blocktype==ID_KE && G.sipo->from) { + Key *key= (Key *)G.sipo->from; + KeyBlock *curkb; + Object *ob= OBACT; + + curkb= BLI_findlink(&key->block, index-1); + if(curkb) { + ob->shapenr= index; + ob->shapeflag |= OB_SHAPE_TEMPLOCK; + + /* calc keypos */ + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + } + } +} + void boundbox_ipocurve(IpoCurve *icu) { BezTriple *bezt; @@ -484,7 +564,7 @@ void editipo_changed(SpaceIpo *si, int doredraw) if(si->showkey) make_ipokey(); } -void scale_editipo() +void scale_editipo(void) { /* comes from buttons, scale with G.sipo->tot rect */ @@ -786,6 +866,13 @@ void make_key_editipo(SpaceIpo *si) else if(a==0) if(key && key->type==KEY_NORMAL) ei->flag |= IPO_VISIBLE; + + /* active ipo is tied to active shape */ + { + Object *ob= OBACT; + if(a==ob->shapenr-1) + set_active_editipo(ei); + } } ei= si->editipo; @@ -1066,7 +1153,7 @@ void make_sound_editipo(SpaceIpo *si) } } -void make_editipo() +void make_editipo(void) { EditIpo *ei; Object *ob; @@ -1213,12 +1300,12 @@ void make_editipo() } -void test_editipo() +void test_editipo(void) { Ipo *ipo; ID *from; - if(G.sipo->editipo==0){ + if(G.sipo->editipo==NULL){ make_editipo(); } else { @@ -1240,9 +1327,9 @@ void test_editipo() /* ****************************************** */ -int totipo_edit, totipo_sel, totipo_vis, totipo_vert, totipo_vertsel, totipo_key, totipo_keysel; +int totipo_edit, totipo_sel, totipo_curve, totipo_vis, totipo_vert, totipo_vertsel, totipo_key, totipo_keysel; -void get_status_editipo() +void get_status_editipo(void) { EditIpo *ei; IpoKey *ik; @@ -1250,6 +1337,7 @@ void get_status_editipo() int a, b; totipo_vis= 0; + totipo_curve= 0; totipo_sel= 0; totipo_edit= 0; totipo_vert= 0; @@ -1265,6 +1353,7 @@ void get_status_editipo() if( ei->flag & IPO_VISIBLE ) { totipo_vis++; if(ei->flag & IPO_SELECT) totipo_sel++; + if(ei->icu && ei->icu->totvert) totipo_curve++; if(G.sipo->showkey || (ei->flag & IPO_EDIT)) { /* if showkey: do count the vertices (for grab) */ @@ -1302,7 +1391,8 @@ void get_status_editipo() } } -void update_editipo_flags() +/* synchronize editipo flag with icu flag and ipokey flags */ +void update_editipo_flags(void) { EditIpo *ei; IpoKey *ik; @@ -1336,7 +1426,7 @@ void update_editipo_flags() } } -void set_editflag_editipo() +void set_editflag_editipo(void) { EditIpo *ei; int a; /* , tot= 0, ok= 0; */ @@ -1380,7 +1470,8 @@ void set_editflag_editipo() scrarea_queue_winredraw(curarea); } -void ipo_toggle_showkey(void) { +void ipo_toggle_showkey(void) +{ if(G.sipo->showkey) { G.sipo->showkey= 0; swap_selectall_editipo(); /* sel all */ @@ -1392,7 +1483,7 @@ void ipo_toggle_showkey(void) { BIF_undo_push("Toggle show key Ipo"); } -void swap_selectall_editipo() +void swap_selectall_editipo(void) { Object *ob; EditIpo *ei; @@ -1458,7 +1549,7 @@ void swap_selectall_editipo() } -void swap_visible_editipo() +void swap_visible_editipo(void) { EditIpo *ei; Object *ob; @@ -1493,7 +1584,7 @@ void swap_visible_editipo() BIF_undo_push("Swap Visible Ipo"); } -void deselectall_editipo() +void deselectall_editipo(void) { EditIpo *ei; IpoKey *ik; @@ -1614,7 +1705,7 @@ short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt) } -void move_to_frame() +void move_to_frame(void) { EditIpo *ei; BezTriple *bezt; @@ -1667,7 +1758,7 @@ void move_to_frame() /* handling of right-hand channel/curve buttons in ipo window */ void do_ipowin_buts(short event) { - EditIpo *ei = 0; + EditIpo *ei = NULL; int a; /* without shift, all other channels are made invisible */ @@ -1680,9 +1771,17 @@ void do_ipowin_buts(short event) ei++; } } + + /* set active */ + if(event>=0 && event<G.sipo->totipo) { + ei= G.sipo->editipo; // void pointer... + set_active_editipo(ei+event); + set_active_key(event+1); // only if there's a key, of course + } scrarea_queue_winredraw(curarea); update_editipo_flags(); + get_status_editipo(); if(G.sipo->showkey) { make_ipokey(); @@ -1692,7 +1791,7 @@ void do_ipowin_buts(short event) } /* the fake buttons to the left of channel names, for select/deselect curves */ -void do_ipo_selectbuttons() +void do_ipo_selectbuttons(void) { EditIpo *ei, *ei1; int a, nr; @@ -1714,6 +1813,9 @@ void do_ipo_selectbuttons() ei= G.sipo->editipo; ei+= nr; + set_active_editipo(ei); + set_active_key(nr+1); + if(ei->icu) { if((ei->flag & IPO_VISIBLE)==0) { ei->flag |= IPO_VISIBLE|IPO_SELECT; @@ -1743,7 +1845,7 @@ void do_ipo_selectbuttons() /* ******************************************* */ -EditIpo *get_editipo() +EditIpo *get_editipo(void) { EditIpo *ei; int a; /* , sel=0; */ @@ -1889,8 +1991,8 @@ Ipo *get_ipo(ID *from, short type, int make) IpoCurve *get_ipocurve(ID *from, short type, int adrcode, Ipo *useipo) { - Ipo *ipo= 0; - IpoCurve *icu=0; + Ipo *ipo= NULL; + IpoCurve *icu=NULL; /* return 0 if lib */ /* also test if ipo and ipocurve exist */ @@ -1956,7 +2058,7 @@ void insert_vert_ipo(IpoCurve *icu, float x, float y) bezt= icu->bezt; - if(bezt==0) { + if(bezt==NULL) { icu->bezt= MEM_callocN( sizeof(BezTriple), "beztriple"); *(icu->bezt)= beztr; icu->totvert= 1; @@ -2009,7 +2111,7 @@ void insert_vert_ipo(IpoCurve *icu, float x, float y) } } -void add_vert_ipo() +void add_vert_ipo(void) { EditIpo *ei; float x, y; @@ -2034,11 +2136,11 @@ void add_vert_ipo() areamouseco_to_ipoco(G.v2d, mval, &x, &y); - if(ei->icu==0) { + if(ei->icu==NULL) { if(G.sipo->from) ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0); } - if(ei->icu==0) return; + if(ei->icu==NULL) return; if(ei->disptype==IPO_DISPBITS) { ei->icu->vartype= IPO_BITS; @@ -2057,7 +2159,7 @@ void add_vert_ipo() BIF_undo_push("Add Ipo vertex"); } -void add_duplicate_editipo() +void add_duplicate_editipo(void) { Object *ob; EditIpo *ei; @@ -2118,7 +2220,7 @@ void add_duplicate_editipo() transform_ipo('g'); } -void remove_doubles_ipo() +void remove_doubles_ipo(void) { EditIpo *ei; IpoKey *ik, *ikn; @@ -2436,7 +2538,7 @@ void ipo_snap(short event) -void mouse_select_ipo() +void mouse_select_ipo(void) { Object *ob; Key *key; @@ -2555,14 +2657,8 @@ void mouse_select_ipo() if(ok) { /* also does all keypos */ deselectall_editipo(); - - ob->shapenr= index; - ob->shapeflag |= OB_SHAPE_TEMPLOCK; - - /* calc keypos */ - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSEDIT, 0); + set_active_key(index); + set_active_editipo(ei+index-1); } } } @@ -2595,6 +2691,7 @@ void mouse_select_ipo() else { actei->flag |= IPO_SELECT; } + set_active_editipo(actei); } } } @@ -2754,7 +2851,8 @@ static int selected_bezier_loop(int (*looptest)(EditIpo *), return 0; } -int select_bezier_add(BezTriple *bezt) { +int select_bezier_add(BezTriple *bezt) +{ /* Select the bezier triple */ bezt->f1 |= 1; bezt->f2 |= 1; @@ -2762,7 +2860,8 @@ int select_bezier_add(BezTriple *bezt) { return 0; } -int select_bezier_subtract(BezTriple *bezt) { +int select_bezier_subtract(BezTriple *bezt) +{ /* Deselect the bezier triple */ bezt->f1 &= ~1; bezt->f2 &= ~1; @@ -2770,7 +2869,8 @@ int select_bezier_subtract(BezTriple *bezt) { return 0; } -int select_bezier_invert(BezTriple *bezt) { +int select_bezier_invert(BezTriple *bezt) +{ /* Invert the selection for the bezier triple */ bezt->f2 ^= 1; if ( bezt->f2 & 1 ) { @@ -2858,7 +2958,8 @@ static int set_bezier_align(BezTriple *bezt) return 0; } -static int vis_edit_icu_bez(EditIpo *ei) { +static int vis_edit_icu_bez(EditIpo *ei) +{ /* A 4 part test for an EditIpo : * is it a) visible * b) in edit mode @@ -3035,7 +3136,7 @@ void setipotype_ipo(Ipo *ipo, int code) } } -void set_ipotype() +void set_ipotype(void) { EditIpo *ei; int a; @@ -3078,7 +3179,7 @@ void set_ipotype() scrarea_queue_winredraw(curarea); } -void borderselect_ipo() +void borderselect_ipo(void) { EditIpo *ei; IpoKey *ik; @@ -3164,7 +3265,7 @@ void del_ipoCurve ( IpoCurve * icu ) } } -void del_ipo() +void del_ipo(void) { EditIpo *ei; BezTriple *bezt, *bezt1; @@ -3214,12 +3315,21 @@ void del_ipo() } 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; + if(ei->icu->driver==NULL) { + BLI_remlink( &(G.sipo->ipo->curve), ei->icu); + + free_ipo_curve(ei->icu); + + ei->flag &= ~IPO_SELECT; + ei->flag &= ~IPO_EDIT; + ei->icu= NULL; + } + else { + if(ei->icu->bezt) MEM_freeN(ei->icu->bezt); + ei->icu->bezt= NULL; + ei->icu->totvert= 0; + ei->flag &= ~IPO_EDIT; + } } } @@ -3243,16 +3353,25 @@ void del_ipo() 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; + if(ei->icu->totvert) { + 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; + } + else { + MEM_freeN(ei->icu->bezt); + ei->icu->bezt= NULL; + } } } } } } + get_status_editipo(); /* count again */ + check_active_editipo(); + BIF_undo_push("Delete Ipo"); allqueue(REDRAWNLA, 0); allqueue (REDRAWACTION, 0); @@ -3263,19 +3382,18 @@ void del_ipo() ListBase ipocopybuf={0, 0}; int totipocopybuf=0; -void free_ipocopybuf() +void free_ipocopybuf(void) { IpoCurve *icu; while( (icu= ipocopybuf.first) ) { - if(icu->bezt) MEM_freeN(icu->bezt); BLI_remlink(&ipocopybuf, icu); - MEM_freeN(icu); + free_ipo_curve(icu); } totipocopybuf= 0; } -void copy_editipo() +void copy_editipo(void) { EditIpo *ei; IpoCurve *icu; @@ -3295,10 +3413,9 @@ void copy_editipo() 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)); - } + icu->bezt= MEM_dupallocN(icu->bezt); + icu->driver= MEM_dupallocN(icu->driver); + totipocopybuf++; } } @@ -3307,7 +3424,7 @@ void copy_editipo() if(totipocopybuf==0) error("Copy buffer is empty"); } -void paste_editipo() +void paste_editipo(void) { EditIpo *ei; IpoCurve *icu; @@ -3322,7 +3439,7 @@ void paste_editipo() get_status_editipo(); if(totipo_vis==0) { - error("No visible splines"); + error("No visible channels"); } else if(totipo_vis!=totipocopybuf && totipo_sel!=totipocopybuf) { error("Incompatible paste"); @@ -3344,20 +3461,22 @@ void paste_editipo() if(ok) { ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0); - if(ei->icu==0) return; + if(ei->icu==NULL) return; if(ei->icu->bezt) MEM_freeN(ei->icu->bezt); - ei->icu->bezt= 0; + ei->icu->bezt= NULL; + if(ei->icu->driver) MEM_freeN(ei->icu->driver); + ei->icu->driver= NULL; 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)); - } + if(icu->bezt) + ei->icu->bezt= MEM_dupallocN(icu->bezt); + if(icu->driver) + ei->icu->driver= MEM_dupallocN(icu->driver); icu= icu->next; @@ -3501,7 +3620,7 @@ void insertkey(ID *id, int adrcode) if(id) { - // this call here, otherwise get_ipo_curve gives it from the pinned ipo + // this call here, otherwise get_ipocurve 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); @@ -3527,7 +3646,7 @@ void insertkey(ID *id, int adrcode) } } -void insertkey_editipo() +void insertkey_editipo(void) { EditIpo *ei; IpoKey *ik; @@ -3536,81 +3655,110 @@ void insertkey_editipo() int a, nr, ok, tot; short event; - if(G.sipo->showkey) + ei= get_active_editipo(); + if(ei && ei->icu && ei->icu->driver) + event= pupmenu("Insert Curve %t|Default one-to-one mapping %x3"); + else if(G.sipo->showkey) event= pupmenu("Insert Key Vertices %t|Current Frame %x1|Selected Keys %x2"); else event= pupmenu("Insert Key Vertices %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) { + if(event==3) { + IpoDriver *driver= ei->icu->driver; - ok= 0; - if(G.sipo->showkey) ok= 1; - else if(ei->flag & IPO_SELECT) ok= 1; + if(ei->icu->bezt) MEM_freeN(ei->icu->bezt); + ei->icu->totvert= 0; + ei->icu->bezt= NULL; + + insert_vert_ipo(ei->icu, 0.0f, 0.0f); + + if(ELEM3(driver->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) { + if(ei->disptype==IPO_DISPDEGR) + insert_vert_ipo(ei->icu, 18.0f, 18.0f); + else + insert_vert_ipo(ei->icu, 18.0f, 1.0f); + } + else + insert_vert_ipo(ei->icu, 1.0f, 1.0f); + + ei->flag |= IPO_SELECT|IPO_VISIBLE; + ei->icu->flag= ei->flag; + ei->icu->extrap= IPO_DIR; - if(ok) { - /* count amount */ - 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) { - - /* correction for 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))); - } - } + do_ipo_buttons(B_IPOHOME); + } + else { + ei= G.sipo->editipo; + for(nr=0; nr<G.sipo->totipo; nr++, ei++) { + if ISPOIN(ei, flag & IPO_VISIBLE, icu) { - insertvals= MEM_mallocN(sizeof(float)*2*tot, "insertkey_editipo"); - /* make sure icu->curval is correct */ - calc_ipo(G.sipo->ipo, cfra); - - if(event==1) { - insertvals[0]= cfra; - - insertvals[1]= ei->icu->curval; - } + ok= 0; + if(G.sipo->showkey) ok= 1; + else if(ei->flag & IPO_SELECT) ok= 1; + + if(ok) { + /* count amount */ + if(event==1) tot= 1; else { - fp= insertvals; ik= G.sipo->ipokey.first; + tot= 0; while(ik) { - if(ik->flag & 1) { - calc_ipo(G.sipo->ipo, ik->val); - - fp[0]= ik->val; - fp[1]= ei->icu->curval; - fp+= 2; - } + if(ik->flag & 1) tot++; ik= ik->next; } } - fp= insertvals; - for(a=0; a<tot; a++, fp+=2) { - insert_vert_ipo(ei->icu, fp[0], fp[1]); - } + if(tot) { - MEM_freeN(insertvals); - calc_ipo(G.sipo->ipo, (float)CFRA); + /* correction for 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"); + /* make sure icu->curval is correct */ + 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); + } } } } @@ -3623,7 +3771,7 @@ void insertkey_editipo() } -void common_insertkey() +void common_insertkey(void) { Base *base; Object *ob; @@ -4250,7 +4398,7 @@ void make_ipokey_transform(Object *ob, ListBase *lb, int sel) } } -void update_ipokey_val() /* after moving vertices */ +void update_ipokey_val(void) /* after moving vertices */ { IpoKey *ik; int a; @@ -4992,7 +5140,7 @@ void sampledata_to_ipocurve(float *data, int sfra, int efra, IpoCurve *icu) icu->ipo= IPO_LIN; if(icu->bezt) MEM_freeN(icu->bezt); - icu->bezt= 0; + icu->bezt= NULL; tot= 1; /* first point */ da= data+1; @@ -5015,7 +5163,7 @@ void sampledata_to_ipocurve(float *data, int sfra, int efra, IpoCurve *icu) } } -void ipo_record() +void ipo_record(void) { /* only 1 or 2 active curves * make a copy (ESC) @@ -5070,16 +5218,16 @@ void ipo_record() } /* make curves ready, start values */ - if(ei1->icu==0) ei1->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei1->adrcode, 0); - if(ei1->icu==0) return; + if(ei1->icu==NULL) ei1->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei1->adrcode, 0); + if(ei1->icu==NULL) 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; + if(ei2->icu==NULL) ei2->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei2->adrcode, 0); + if(ei2->icu==NULL) 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; @@ -5203,18 +5351,18 @@ void ipo_record() /* undo: start values */ poin= get_ipo_poin(G.sipo->from, ei1->icu, &type); if(poin) write_ipo_poin(poin, type, or1); - if(ei1->icu->bezt==0) { + if(ei1->icu->bezt==NULL) { BLI_remlink( &(G.sipo->ipo->curve), ei1->icu); MEM_freeN(ei1->icu); - ei1->icu= 0; + ei1->icu= NULL; } 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) { + if(ei2->icu->bezt==NULL) { BLI_remlink( &(G.sipo->ipo->curve), ei2->icu); MEM_freeN(ei2->icu); - ei2->icu= 0; + ei2->icu= NULL; } } } @@ -5320,8 +5468,7 @@ void delete_ipo_keys(Ipo *ipo) if (!icu->totvert){ /* Delete the curve */ BLI_remlink( &(ipo->curve), icu); - if(icu->bezt) MEM_freeN(icu->bezt); - MEM_freeN(icu); + free_ipo_curve(icu); } } } diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index f7368c58013..c7f4de25c7e 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -4114,6 +4114,7 @@ void adduplicate(int noTrans) Object *ob, *obn; Material ***matarar, *ma, *mao; ID *id; + Ipo *ipo; bConstraintChannel *chan; int a, didit, dupflag; @@ -4314,7 +4315,21 @@ void adduplicate(int noTrans) } base= base->next; } - + + /* ipos */ + ipo= G.main->ipo.first; + while(ipo) { + if(ipo->id.lib==NULL) { + IpoCurve *icu; + for(icu= ipo->curve.first; icu; icu= icu->next) { + if(icu->driver) { + ID_NEW(icu->driver->ob); + } + } + } + ipo= ipo->id.next; + } + /* materials */ if( dupflag & USER_DUP_MAT) { mao= G.main->mat.first; diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c index fce45d7ab39..06e7e418224 100644 --- a/source/blender/src/header_ipo.c +++ b/source/blender/src/header_ipo.c @@ -411,10 +411,13 @@ static uiBlock *ipo_editmenu(void *arg_unused) else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Edit Selected|TAB", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, ""); - ei = G.sipo->editipo; + ei = get_active_editipo(); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert Keyframe...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); + if(ei->icu && ei->icu->driver) + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert 1:1 Curve...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); + else + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert Keyframe...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); @@ -473,11 +476,14 @@ static void do_ipo_viewmenu(void *arg, int event) mainqenter(PADMINUS,1); break; case 6: /* Play Back Animation */ - play_anim(0); - break; + play_anim(0); + break; case 7: /* Play Back Animation in All */ - play_anim(1); - break; + play_anim(1); + break; + case 8: + add_blockhandler(curarea, IPO_HANDLER_PROPERTIES, UI_PNL_UNSTOW); + break; } } @@ -492,6 +498,8 @@ static uiBlock *ipo_viewmenu(void *arg_unused) block= uiNewBlock(&curarea->uiblocks, "ipo_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin); uiBlockSetButmFunc(block, do_ipo_viewmenu, NULL); + + uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Channel Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); if (G.sipo->showkey) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Show Keys|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, ""); else @@ -692,6 +700,8 @@ void do_ipo_buttons(short event) v2d->cur.ymax= v2d->tot.ymax+ dy; test_view2d(G.v2d, curarea->winx, curarea->winy); + if(G.sipo->ipo) G.sipo->ipo->cur = G.v2d->cur; + scrarea_queue_winredraw(curarea); break; case B_IPOBORDER: diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 78b94c42564..f7429c3bc57 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -1225,7 +1225,8 @@ static int ui_do_but_MENU(uiBut *but) uibut_do_func(but); - return event; + if(event == UI_NOTHING) return 0; + else return but->retval; } @@ -3749,27 +3750,31 @@ static void ui_do_but_tip(uiBut *buttip) * as long as the mouse remains on top * of the button that owns it. */ + Mat4CpyMat4(UIwinmat, buttip->block->winmat); // get rid of uiwinmat once... uiPanelPush(buttip->block); // panel matrix od= ui_draw_but_tip(buttip); - while (1) { - char ascii; - short val; - unsigned short evt= extern_qread_ext(&val, &ascii); - - if (evt==MOUSEX || evt==MOUSEY) { - short mouse[2]; - uiGetMouse(od->oldwin, mouse); - - if (!uibut_contains_pt(buttip, mouse)) + if(od) { + while (1) { + char ascii; + short val; + unsigned short evt= extern_qread_ext(&val, &ascii); + + if (evt==MOUSEX || evt==MOUSEY) { + short mouse[2]; + uiGetMouse(od->oldwin, mouse); + + if (!uibut_contains_pt(buttip, mouse)) + break; + } else { + mainqpushback(evt, val, ascii); break; - } else { - mainqpushback(evt, val, ascii); - break; + } } + + ui_end_overdraw(od); } - ui_end_overdraw(od); uiPanelPop(buttip->block); // panel matrix /* still the evil global.... */ UIbuttip= NULL; |