diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 64d6d1f5abd..3e494721621 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -43,6 +43,7 @@ #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_ipo_types.h" +#include "DNA_key_types.h" #include "DNA_nla_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -55,6 +56,7 @@ #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_ipo.h" +#include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_object.h" @@ -636,12 +638,14 @@ static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int } } -static void execute_ipochannels(Object *ob, ListBase *lb) +static void execute_ipochannels(ListBase *lb) { NlaIpoChannel *nic; for(nic= lb->first; nic; nic= nic->next) { - if(nic->poin) write_ipo_poin(nic->poin, nic->type, nic->val); + if(nic->poin) { + write_ipo_poin(nic->poin, nic->type, nic->val); + } } } @@ -721,6 +725,7 @@ static float nla_time(float cfra, float unit) static void do_nla(Object *ob, int blocktype) { bPose *tpose= NULL; + Key *key= NULL; ListBase tchanbase={NULL, NULL}, chanbase={NULL, NULL}; bActionStrip *strip; float striptime, frametime, length, actlength; @@ -731,6 +736,9 @@ static void do_nla(Object *ob, int blocktype) copy_pose(&tpose, ob->pose, 1); rest_pose(ob->pose); // potentially destroying current not-keyed pose } + else { + key= ob_get_key(ob); + } for (strip=ob->nlastrips.first; strip; strip=strip->next){ doit=0; @@ -776,12 +784,15 @@ static void do_nla(Object *ob, int blocktype) striptime = (float)fmod (striptime, 1.0); frametime = (striptime * actlength) + strip->actstart; + frametime= bsystem_time(ob, 0, frametime, 0.0); if(blocktype==ID_AR) - extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); - else if(blocktype==ID_OB) - extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", bsystem_time(ob, 0, frametime, 0.0)); - + extract_pose_from_action (tpose, strip->act, frametime); + else if(blocktype==ID_OB) { + extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); + if(key) + extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); + } doit=1; } } @@ -794,25 +805,32 @@ static void do_nla(Object *ob, int blocktype) striptime = (float)fmod (striptime, 1.0); frametime = (striptime * actlength) + strip->actstart; - - if(blocktype==ID_AR) - extract_pose_from_action (tpose, strip->act, nla_time(frametime, (float)strip->repeat)); - else if(blocktype==ID_OB) - extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", nla_time(frametime, (float)strip->repeat)); + frametime= nla_time(frametime, (float)strip->repeat); + if(blocktype==ID_AR) + extract_pose_from_action (tpose, strip->act, frametime); + else if(blocktype==ID_OB) { + extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); + if(key) + extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); + } doit=1; } /* Handle extend */ else{ if (strip->flag & ACTSTRIP_HOLDLASTFRAME){ striptime = 1.0; + frametime = (striptime * actlength) + strip->actstart; + frametime= bsystem_time(ob, 0, frametime, 0.0); if(blocktype==ID_AR) - extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); - else if(blocktype==ID_OB) - extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", bsystem_time(ob, 0, frametime, 0.0)); - + extract_pose_from_action (tpose, strip->act, frametime); + else if(blocktype==ID_OB) { + extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); + if(key) + extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); + } doit=1; } } @@ -842,7 +860,7 @@ static void do_nla(Object *ob, int blocktype) } if(blocktype==ID_OB) { - execute_ipochannels(ob, &chanbase); + execute_ipochannels(&chanbase); } if (tpose){ @@ -886,13 +904,17 @@ void do_all_object_actions(Object *ob) /* Do local action */ if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) { ListBase tchanbase= {NULL, NULL}; + Key *key= ob_get_key(ob); float cframe= (float) G.scene->r.cfra; cframe= get_action_frame(ob, cframe); extract_ipochannels_from_action(&tchanbase, &ob->id, ob->action, "Object", bsystem_time(ob, 0, cframe, 0.0)); + if(key) + extract_ipochannels_from_action(&tchanbase, &key->id, ob->action, "Shape", bsystem_time(ob, 0, cframe, 0.0)); + if(tchanbase.first) { - execute_ipochannels(ob, &tchanbase); + execute_ipochannels(&tchanbase); BLI_freelistN(&tchanbase); } } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index c5f87a495f4..95add0e8ae0 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1451,6 +1451,20 @@ static int object_modifiers_use_time(Object *ob) return 0; } +static int exists_channel(Object *ob, char *name) +{ + bActionStrip *strip; + + if(ob->action) + if(get_action_channel(ob->action, name)) + return 1; + + for (strip=ob->nlastrips.first; strip; strip=strip->next) + if(get_action_channel(strip->act, name)) + return 1; + return 0; +} + /* flag all objects that need recalc, for changes in time for example */ void DAG_scene_update_flags(Scene *sce, unsigned int lay) { @@ -1474,9 +1488,11 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay) if(ob->action || ob->nlastrips.first) { /* since actions now are mixed, we set the recalcs on the safe side */ ob->recalc |= OB_RECALC_OB; - if(ob->type==OB_ARMATURE) { + if(ob->type==OB_ARMATURE) ob->recalc |= OB_RECALC_DATA; - } + else if(exists_channel(ob, "Shape")) + ob->recalc |= OB_RECALC_DATA; + } else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA; else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index c6c99137761..842b30b4147 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1302,8 +1302,13 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type) } else if( GS(id->name)==ID_KE) { + KeyBlock *kb= ((Key *)id)->block.first; - poin= &(icu->curval); + for(; kb; kb= kb->next) + if(kb->adrcode==icu->adrcode) + break; + if(kb) + poin= &(kb->curval); } else if(GS(id->name)==ID_WO) { @@ -1981,6 +1986,7 @@ void do_all_data_ipos() World *wo; Ipo *ipo; Lamp *la; + Key *key; Camera *ca; bSound *snd; Sequence *seq; @@ -2018,24 +2024,22 @@ void do_all_data_ipos() ipo= ipo->id.next; } - tex= G.main->tex.first; - while(tex) { + for(tex= G.main->tex.first; tex; tex= tex->id.next) { if(tex->ipo) execute_ipo((ID *)tex, tex->ipo); - tex= tex->id.next; } - ma= G.main->mat.first; - while(ma) { + for(ma= G.main->mat.first; ma; ma= ma->id.next) { if(ma->ipo) execute_ipo((ID *)ma, ma->ipo); - ma= ma->id.next; } - wo= G.main->world.first; - while(wo) { + for(wo= G.main->world.first; wo; wo= wo->id.next) { if(wo->ipo) execute_ipo((ID *)wo, wo->ipo); - wo= wo->id.next; } - + + for(key= G.main->key.first; key; key= key->id.next) { + if(key->ipo) execute_ipo((ID *)key, key->ipo); + } + la= G.main->lamp.first; while(la) { if(la->ipo) execute_ipo((ID *)la, la->ipo); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 79ef90c7bbd..0877751016c 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -585,12 +585,10 @@ void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end) static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, float ctime, int mode) { KeyBlock *kb; - IpoCurve *icu; int *ofsp, ofs[3], elemsize, b; char *cp, *poin, *reffrom, *from, elemstr[8]; - if(key->from==0) return; - if(key->ipo==0) return; + if(key->from==NULL) return; if( GS(key->from->name)==ID_ME ) { ofs[0]= sizeof(MVert); @@ -627,14 +625,10 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, f while(kb) { if(kb!=key->refkey) { - float icuval= 0.0f; + float icuval= kb->curval; - icu= find_ipocurve(key->ipo, kb->adrcode); - if(icu) - icuval= icu->curval; - - /* only with value or weights, and no difference allowed */ - if((icuval!=0.0f || (icu==NULL && kb->weights)) && kb->totelem==tot) { + /* only with value, and no difference allowed */ + if(icuval!=0.0f && kb->totelem==tot) { float weight, *weights= kb->weights; poin= basispoin; @@ -984,14 +978,6 @@ static int do_mesh_key(Object *ob, 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); - } - if(me->key->type==KEY_RELATIVE) { KeyBlock *kb; @@ -1006,6 +992,11 @@ static int do_mesh_key(Object *ob, Mesh *me) } } else { + if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) { + ctime /= 100.0; + CLAMP(ctime, 0.0, 1.0); + } + flag= setkeys(ctime, &me->key->block, k, t, 0); if(flag==0) { do_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, k, t, 0); @@ -1142,15 +1133,16 @@ static int do_curve_key(Curve *cu) else { ctime= bsystem_time(0, 0, (float)G.scene->r.cfra, 0.0); - if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) { - ctime /= 100.0; - CLAMP(ctime, 0.0, 1.0); - } if(cu->key->type==KEY_RELATIVE) { do_rel_cu_key(cu, ctime); } else { + if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) { + ctime /= 100.0; + CLAMP(ctime, 0.0, 1.0); + } + flag= setkeys(ctime, &cu->key->block, k, t, 0); if(flag==0) do_cu_key(cu, k, t); @@ -1200,16 +1192,16 @@ static int do_latt_key(Lattice *lt) } else { ctime= bsystem_time(0, 0, (float)G.scene->r.cfra, 0.0); - if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) { - ctime /= 100.0; - CLAMP(ctime, 0.0, 1.0); - } if(lt->key->type==KEY_RELATIVE) { do_rel_key(0, tot, tot, (char *)lt->def->vec, lt->key, ctime, 0); } else { - + if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) { + ctime /= 100.0; + CLAMP(ctime, 0.0, 1.0); + } + flag= setkeys(ctime, <->key->block, k, t, 0); if(flag==0) { do_key(0, tot, tot, (char *)lt->def->vec, lt->key, k, t, 0); @@ -1273,6 +1265,7 @@ int do_ob_key(Object *ob) Key *ob_get_key(Object *ob) { + if(ob==NULL) return NULL; if(ob->type==OB_MESH) { Mesh *me= ob->data; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0cc09f9fac9..cc7ca11f81c 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1783,6 +1783,7 @@ void object_handle_update(Object *ob) if(ob->recalc & OB_RECALC_DATA) { // printf("recalcdata %s\n", ob->id.name+2); + /* includes all keys and modifiers */ if(ob->type==OB_MESH) { makeDispListMesh(ob); diff --git a/source/blender/include/BIF_editkey.h b/source/blender/include/BIF_editkey.h index ff78f78da2b..e5dae4fac3e 100644 --- a/source/blender/include/BIF_editkey.h +++ b/source/blender/include/BIF_editkey.h @@ -58,7 +58,7 @@ void insert_shapekey(struct Object *ob); void delete_key(struct Object *ob); void move_keys(struct Object *ob); -void make_rvk_slider(struct uiBlock *block, struct Key *key, int i, +void make_rvk_slider(struct uiBlock *block, struct Object *ob, int keynum, int x, int y, int w, int h, char *tip); #endif diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h index 5e3a4ec5562..4b3dbc283c4 100644 --- a/source/blender/include/BSE_editipo.h +++ b/source/blender/include/BSE_editipo.h @@ -68,7 +68,7 @@ void scale_editipo(void); unsigned int ipo_rainbow(int cur, int tot); -void test_editipo(void); +void test_editipo(int doit); void get_status_editipo(void); void update_editipo_flags(void); void set_editflag_editipo(void); diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h index 91a45dba77d..3292e07f80e 100644 --- a/source/blender/makesdna/DNA_key_types.h +++ b/source/blender/makesdna/DNA_key_types.h @@ -43,7 +43,7 @@ typedef struct KeyBlock { struct KeyBlock *next, *prev; float pos; - int pad; + float curval; short type, adrcode; int totelem; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 5fb2066836d..d464056bc90 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1429,10 +1429,13 @@ static void editing_panel_shapes(Object *ob) if( uiNewPanel(curarea, block, "Shapes", "Editing", 640, 0, 318, 204)==0) return; uiDefBut(block, BUT, B_ADDKEY, "Add Shape Key" , 10, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "Add new Shape Key"); - + key= ob_get_key(ob); - if(key==NULL) + if(key==NULL) { + /* label aligns add button */ + uiDefBut(block, LABEL, 0, "", 170, 180,140,20, NULL, 0, 0, 0, 0, ""); return; + } uiDefButS(block, TOG, B_RELKEY, "Relative", 170, 180,140,20, &key->type, 0, 0, 0, 0, "Makes Shape Keys relative"); @@ -1458,7 +1461,7 @@ static void editing_panel_shapes(Object *ob) if(key->type && (ob->shapeflag & OB_SHAPE_LOCK)==0 && ob->shapenr!=1) { uiBlockBeginAlign(block); - make_rvk_slider(block, key, ob->shapenr-1, 10, 120, 150, 20, "Key value, when used it inserts an animation curve point"); + make_rvk_slider(block, ob, ob->shapenr-1, 10, 120, 150, 20, "Key value, when used it inserts an animation curve point"); uiDefButF(block, NUM, B_REDR, "Min ", 160,120, 75, 20, &kb->slidermin, -10.0, 10.0, 100, 1, "Minumum for slider"); uiDefButF(block, NUM, B_REDR, "Max ", 235,120, 75, 20, &kb->slidermax, -10.0, 10.0, 100, 1, "Maximum for slider"); uiBlockEndAlign(block); diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index c1a4782b1fa..c6955955c09 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -88,28 +88,18 @@ /* local functions ----------------------------------------------------- */ -void drawactionspace(ScrArea *sa, void *spacedata); -static void draw_channel_names(void); -static void draw_channel_strips(SpaceAction *saction); int count_action_levels(bAction *act); static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert); static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert); static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert); static BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert); -static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos); void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos); -static void draw_action_mesh_names(Key *key); - -/* missing local prototypes -------------------------------------------- */ -void meshactionbuts(SpaceAction *saction, Key *key); -void do_actionbuts(unsigned short event); /* implementation ------------------------------------------------------ */ - extern short showsliders; /* editaction .c */ extern short ACTWIDTH; -void meshactionbuts(SpaceAction *saction, Key *key) +static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key) { int i; char str[64]; @@ -176,7 +166,7 @@ void meshactionbuts(SpaceAction *saction, Key *key) glRects(NAMEWIDTH, 0, NAMEWIDTH+SLIDERWIDTH, curarea->winy); uiBlockSetEmboss(block, UI_EMBOSS); for (i=1 ; i < key->totkey ; ++ i) { - make_rvk_slider(block, key, i, + make_rvk_slider(block, ob, i, x, y, SLIDERWIDTH-2, CHANNELHEIGHT-1, "Slider to control Shape Keys"); y-=CHANNELHEIGHT+CHANNELSKIP; @@ -670,7 +660,7 @@ void drawactionspace(ScrArea *sa, void *spacedata) /* if there is a mesh with rvk's selected, * then draw the key frames in the action window */ - meshactionbuts(G.saction, key); + meshactionbuts(G.saction, OBACT, key); } } } diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c index 22017ee9d8c..a108492a5a3 100644 --- a/source/blender/src/drawipo.c +++ b/source/blender/src/drawipo.c @@ -1990,7 +1990,7 @@ void drawipospace(ScrArea *sa, void *spacedata) } } - test_editipo(); /* test if current editipo is correct, make_editipo sets v2d->cur */ + test_editipo(0); /* test if current editipo is correct, make_editipo sets v2d->cur */ myortho2(v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax); diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 335f8ee9c72..981d92fe5ff 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -1180,7 +1180,7 @@ void transform_meshchannel_keys(char mode, Key *key) * future */ - DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB|OB_RECALC_DATA); allqueue (REDRAWVIEW3D, 0); allqueue (REDRAWACTION, 0); allqueue (REDRAWIPO, 0); diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index 853b069f484..3aa9bb83639 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -196,20 +196,23 @@ EditIpo *get_active_editipo(void) 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; + Object *ob= (Object *)G.sipo->from; + Key *key= ob_get_key(ob); - curkb= BLI_findlink(&key->block, index-1); - if(curkb) { - ob->shapenr= index; - ob->shapeflag |= OB_SHAPE_TEMPLOCK; + if(key) { + KeyBlock *curkb; - /* calc keypos */ - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSEDIT, 0); - } + 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); + } + } } } @@ -251,7 +254,7 @@ void editipo_changed(SpaceIpo *si, int doredraw) /* keylines? */ if(si->blocktype==ID_KE) { - key= (Key *)si->from; + key= ob_get_key((Object *)G.sipo->from); if(key && key->block.first) { kb= key->block.first; if(kb->pos < v2d->tot.ymin) v2d->tot.ymin= kb->pos; @@ -484,7 +487,7 @@ static void make_key_editipo(SpaceIpo *si) EditIpo *ei; int a; - key= (Key *)G.sipo->from; + key= ob_get_key((Object *)G.sipo->from); if(key==NULL) return; si->totipo= BLI_countlist(&key->block); @@ -998,8 +1001,19 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname else if(blocktype==ID_KE) { if(ob) { Key *key= ob_get_key(ob); - *from= (ID *)key; - if(key) *ipo= key->ipo; + + if(ob->ipoflag & OB_ACTION_KEY) { + if (ob->action) { + bActionChannel *achan= get_action_channel(ob->action, "Shape"); + if(achan) { + *ipo= achan->ipo; + BLI_strncpy(actname, achan->name, 32); + } + } + } + else if(key) *ipo= key->ipo; + + *from= (ID *)ob; } } else if(blocktype==ID_CU) { @@ -1034,9 +1048,9 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname } /* called on each redraw, check if editipo data has to be remade */ -void test_editipo(void) +/* if doit already set, it always makes (in case no ipo exists, we need to see the channels */ +void test_editipo(int doit) { - int doit= 0; if(G.sipo->pin==0) { Ipo *ipo; @@ -1292,8 +1306,7 @@ static short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt) void mouse_select_ipo(void) { Object *ob; - Key *key; - KeyBlock *kb, *actkb=NULL, *curkb; + KeyBlock *actkb=NULL; EditIpo *ei, *actei= 0; IpoCurve *icu; IpoKey *ik, *actik; @@ -1377,10 +1390,12 @@ void mouse_select_ipo(void) /* vertex keys ? */ if(G.sipo->blocktype==ID_KE && G.sipo->from) { + Key *key; + KeyBlock *kb, *curkb; int i, index= 1; - key= (Key *)G.sipo->from; - ob= OBACT; + ob= (Object *)G.sipo->from; + key= ob_get_key(ob); curkb= BLI_findlink(&key->block, ob->shapenr-1); ei= G.sipo->editipo; @@ -1634,6 +1649,17 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname) } return ob->ipo; } + else if(blocktype==ID_KE) { + Key *key= ob_get_key((Object *)G.sipo->from); + + if(key) { + if(key->ipo==NULL) { + key->ipo= add_ipo("KeyIpo", ID_KE); + } + return key->ipo; + } + return NULL; + } } break; case ID_MA: @@ -1678,16 +1704,6 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname) return cu->ipo; } break; - case ID_KE: - { - Key *key= (Key *)from; - - if(key->ipo==NULL) { - key->ipo= add_ipo("KeyIpo", ID_KE); - } - return key->ipo; - } - break; case ID_WO: { World *wo= (World *)from; @@ -1853,10 +1869,11 @@ void add_vert_ipo(void) if(mval[0]>G.v2d->mask.xmax) return; ei= get_active_editipo(); - if(ei==0) { + if(ei==NULL) { error("No active Ipo curve"); return; } + ei->flag |= IPO_VISIBLE; /* can happen it is active but not visible */ areamouseco_to_ipoco(G.v2d, mval, &x, &y); @@ -4084,9 +4101,6 @@ void ipo_record(void) if(anim < 1) return; if(anim!=2) anim= 0; -// ipo= verify_ipo(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname); -// test_editipo(); - ob= OBACT; /* find the curves... */ diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c index 2262d3298cf..32adf6289ac 100644 --- a/source/blender/src/editkey.c +++ b/source/blender/src/editkey.c @@ -44,19 +44,21 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "DNA_action_types.h" #include "DNA_curve_types.h" #include "DNA_ipo_types.h" #include "DNA_key_types.h" +#include "DNA_lattice_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_userdef_types.h" #include "DNA_view2d_types.h" -#include "DNA_lattice_types.h" -#include "DNA_scene_types.h" +#include "BKE_action.h" #include "BKE_anim.h" #include "BKE_curve.h" #include "BKE_depsgraph.h" @@ -96,7 +98,7 @@ float meshslidervals[64] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; -static IpoCurve *get_key_icu(Key *key, int keynum) +static IpoCurve *get_key_icu(Ipo *ipo, int keynum) { /* return the Ipocurve that has the specified * keynum as ardcode -- return NULL if no such @@ -104,13 +106,10 @@ static IpoCurve *get_key_icu(Key *key, int keynum) */ IpoCurve *icu; - /* why this? (ton) */ - if (!(key->ipo)) { - key->ipo= add_ipo("KeyIpo", ID_KE); + if (!ipo) return NULL; - } - for (icu = key->ipo->curve.first; icu ; icu = icu->next) { + for (icu = ipo->curve.first; icu ; icu = icu->next) { if (!icu->adrcode) continue; if (icu->adrcode == keynum) return icu; } @@ -144,23 +143,26 @@ static BezTriple *get_bezt_icu_time(IpoCurve *icu, float *frame, float *val) { return bezt; } -static void rvk_slider_func(void *voidkey, void *voidkeynum) +static void rvk_slider_func(void *voidob, void *voidkeynum) { /* the callback for the rvk sliders ... copies the * value from the temporary array into a bezier at the * right frame on the right ipo curve (creating both the * ipo curve and the bezier if needed). */ + Object *ob= voidob; IpoCurve *icu=NULL; BezTriple *bezt=NULL; - Key *key = (Key *) voidkey; - Object *ob= OBACT; float cfra, rvkval; int keynum = (int) voidkeynum; cfra = frame_to_float(CFRA); - icu = verify_ipocurve(&key->id, ID_KE, NULL, NULL, keynum); + /* ipo on action or ob? */ + if(ob->ipoflag & OB_ACTION_KEY) + icu = verify_ipocurve(&ob->id, ID_KE, "Shape", NULL, keynum); + else + icu = verify_ipocurve(&ob->id, ID_KE, NULL, NULL, keynum); if (icu) { /* if the ipocurve exists, try to get a bezier @@ -184,8 +186,6 @@ static void rvk_slider_func(void *voidkey, void *voidkeynum) */ sort_time_ipocurve(icu); testhandles_ipocurve(icu); - - do_ipo(key->ipo); ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); @@ -195,10 +195,9 @@ static void rvk_slider_func(void *voidkey, void *voidkeynum) allqueue (REDRAWNLA, 0); allqueue (REDRAWIPO, 0); allspace(REMAKEIPO, 0); - } -static float getrvkval(Key *key, int keynum) +static float getrvkval(Ipo *ipo, int keynum) { /* get the value of the rvk from the * ipo curve at the current time -- return 0 @@ -210,7 +209,7 @@ static float getrvkval(Key *key, int keynum) float cfra; cfra = frame_to_float(CFRA); - icu = get_key_icu(key, keynum); + icu = get_key_icu(ipo, keynum); if (icu) { bezt = get_bezt_icu_time(icu, &cfra, &rvkval); if (!bezt) { @@ -222,17 +221,32 @@ static float getrvkval(Key *key, int keynum) } -void make_rvk_slider(uiBlock *block, Key *key, int keynum, +void make_rvk_slider(uiBlock *block, Object *ob, int keynum, int x, int y, int w, int h, char *tip) { /* create a slider for the rvk */ - uiBut *but; + uiBut *but; + Ipo *ipo= NULL; + Key *key= ob_get_key(ob); KeyBlock *kb; float min, max; int i; + if(key==NULL) return; + + /* ipo on action or ob? */ + if(ob->ipoflag & OB_ACTION_KEY) { + if(ob->action) { + bActionChannel *achan; + + achan= get_action_channel(ob->action, "Shape"); + if(achan) ipo= achan->ipo; + } + } + else ipo= key->ipo; + /* global array */ - meshslidervals[keynum] = getrvkval(key, keynum); + meshslidervals[keynum] = getrvkval(ipo, keynum); kb= key->block.first; for (i=0; inext; @@ -252,7 +266,7 @@ void make_rvk_slider(uiBlock *block, Key *key, int keynum, x, y , w, h, meshslidervals+keynum, min, max, 10, 2, tip); - uiButSetFunc(but, rvk_slider_func, key, (void *)keynum); + uiButSetFunc(but, rvk_slider_func, ob, (void *)keynum); // no hilite, the winmatrix is not correct later on... uiButSetFlag(but, UI_NO_HILITE); diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index 7c343058d8a..c1da247120a 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -897,16 +897,13 @@ void deselectall(void) /* is toggle */ void selectswap(void) { Base *base; - int a=0; - base= FIRSTBASE; - while(base) { + for(base= FIRSTBASE; base; base= base->next) { if(base->lay & G.vd->lay) { if TESTBASE(base) base->flag &= ~SELECT; else base->flag |= SELECT; base->object->flag= base->flag; } - base= base->next; } allqueue(REDRAWVIEW3D, 0); diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c index 73439ec22bf..1bfef7a6567 100644 --- a/source/blender/src/header_ipo.c +++ b/source/blender/src/header_ipo.c @@ -64,6 +64,7 @@ #include "BKE_action.h" #include "BKE_constraint.h" #include "BKE_global.h" +#include "BKE_key.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_texture.h" @@ -336,7 +337,7 @@ static void do_ipo_editmenu_keymenu(void *arg, int event) Object *ob= OBACT; if(G.sipo->blocktype==ID_KE && totipo_edit==0 && totipo_sel==0) { - key= (Key *)G.sipo->from; + key= ob_get_key((Object *)G.sipo->from); if(key==NULL) return; kb= BLI_findlink(&key->block, ob->shapenr-1); @@ -925,6 +926,8 @@ void do_ipo_buttons(short event) set_exprap_ipo(IPO_CYCLX); break; case B_IPOMAIN: + /* pass 1 to enforce a refresh when there's no Ipo */ + test_editipo(1); scrarea_queue_winredraw(curarea); scrarea_queue_headredraw(curarea); if(ob) ob->ipowin= G.sipo->blocktype; @@ -986,8 +989,38 @@ void do_ipo_buttons(short event) allqueue(REDRAWNLA, 0); } break; - case B_IPO_ACTION_KEY: + case B_IPO_ACTION_KEY: + if(ob && G.sipo->from && G.sipo->pin==0) { + Key *key= ob_get_key(ob); + if(key) { + if(ob->ipoflag & OB_ACTION_KEY) { /* check if channel exists, and flip ipo link */ + bActionChannel *achan; + + if(ob->action==NULL) + ob->action= add_empty_action(ID_KE); + achan= verify_action_channel(ob->action, "Shape"); + if(achan->ipo==NULL && key->ipo) { + achan->ipo= key->ipo; + key->ipo= NULL; + } + } + else if(ob->action) { + bActionChannel *achan= get_action_channel(ob->action, "Shape"); + if(achan) { + if(achan->ipo && key->ipo==NULL) { + key->ipo= achan->ipo; + achan->ipo= NULL; + } + } + } + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWNLA, 0); + } + } break; } } @@ -1013,7 +1046,7 @@ void ipo_buttons(void) uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, windowtype_pup(), xco,0,XIC+10,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Displays Current Window Type. Click for menu of available types."); xco+= XIC+14; - test_editipo(); /* test if current editipo is OK, make_editipo sets v2d->cur */ + test_editipo(0); /* test if current editipo is OK, make_editipo sets v2d->cur */ uiBlockSetEmboss(block, UI_EMBOSSN); if(curarea->flag & HEADER_NO_PULLDOWN) { diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c index 64d4d77cc43..417bf489eae 100644 --- a/source/blender/src/outliner.c +++ b/source/blender/src/outliner.c @@ -1156,7 +1156,16 @@ static int tree_element_active_ipo(SpaceOops *soops, TreeElement *te, int set) tselems= TREESTORE(tes); if(set) { - ob->ipowin= tes->idcode; + if(tes->idcode==ID_AC) { + if(ob->ipoflag & OB_ACTION_OB) + ob->ipowin= ID_OB; + else if(ob->ipoflag & OB_ACTION_KEY) + ob->ipowin= ID_KE; + else + ob->ipowin= ID_PO; + } + else ob->ipowin= tes->idcode; + if(ob->ipowin==ID_MA) tree_element_active_material(soops, tes, 1); else if(ob->ipowin==ID_AC) { bActionChannel *chan; @@ -1173,21 +1182,29 @@ static int tree_element_active_ipo(SpaceOops *soops, TreeElement *te, int set) allqueue(REDRAWIPO, ob->ipowin); } - else if(ob->ipowin==tes->idcode) { - if(ob->ipowin==ID_MA) { - Material *ma= give_current_material(ob, ob->actcol); - if(ma==(Material *)tselems->id) return 1; - } - else if(ob->ipowin==ID_AC) { - bActionChannel *chan; - short a=0; - for(chan=ob->action->chanbase.first; chan; chan= chan->next) { - if(a==te->index) break; - if(chan->ipo) a++; + else { + if(tes->idcode==ID_AC) { + if(ob->ipoflag & OB_ACTION_OB) + return ob->ipowin==ID_OB; + else if(ob->ipoflag & OB_ACTION_KEY) + return ob->ipowin==ID_KE; + else if(ob->ipowin==ID_AC) { + bActionChannel *chan; + short a=0; + for(chan=ob->action->chanbase.first; chan; chan= chan->next) { + if(a==te->index) break; + if(chan->ipo) a++; + } + if(chan==get_hilighted_action_channel(ob->action)) return 1; } - if(chan==get_hilighted_action_channel(ob->action)) return 1; } - else return 1; + else if(ob->ipowin==tes->idcode) { + if(ob->ipowin==ID_MA) { + Material *ma= give_current_material(ob, ob->actcol); + if(ma==(Material *)tselems->id) return 1; + } + else return 1; + } } return 0; }