diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-01-03 09:01:11 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-01-03 09:01:11 +0300 |
commit | 4b320c26a3918b9aca83dda850195c55d8b7eefd (patch) | |
tree | 6aeeb197a4e7a96e9c1406cde20dafbeaf4cf343 | |
parent | 61f7ba6fa20234d582481a50601a873d86f6ec65 (diff) |
2.5 - Action Editor: IPO Curve Protect works now
* Added the relevant filtering necessary for this to work, into the animation-channel filtering code.
* Updated most of the keyframe-editing tools to respect this
* Renamed keyframe-editing API loopers (added ANIM_ prefix) for consistency
* Added function for mapping keyframes to/from NLA-mapping for Ipo-Curves in addition to the one for IPO blocks. As a result, renamed the latter for consistency.
-rw-r--r-- | source/blender/editors/animation/anim_draw.c | 88 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 126 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_draw.c | 8 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_edit.c | 12 | ||||
-rw-r--r-- | source/blender/editors/include/ED_anim_api.h | 3 | ||||
-rw-r--r-- | source/blender/editors/include/ED_keyframes_edit.h | 9 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_edit.c | 36 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_select.c | 55 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 457 |
9 files changed, 277 insertions, 517 deletions
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index e7d803e438a..0b12db44b39 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -51,6 +51,7 @@ #include "BKE_utildefines.h" #include "ED_anim_api.h" +#include "ED_keyframes_edit.h" #include "ED_util.h" #include "WM_api.h" @@ -180,7 +181,7 @@ void ANIM_draw_previewrange (const bContext *C, View2D *v2d) } /* *************************************************** */ -/* KEYFRAME DRAWING UTILITIES */ +/* NLA-MAPPING UTILITIES (required for drawing and also editing keyframes) */ /* Obtain the Object providing NLA-scaling for the given channel (if applicable) */ Object *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale) @@ -255,38 +256,81 @@ void ANIM_nla_mapping_draw(gla2DDrawInfo *di, Object *ob, short restore) } } +/* ------------------- */ + +/* helper function for ANIM_nla_mapping_apply_ipocurve() -> "restore", i.e. mapping points back to IPO-time */ +static short bezt_nlamapping_restore(BeztEditData *bed, BezTriple *bezt) +{ + /* object providing scaling is stored in 'data', only_keys option is stored in i1 */ + Object *ob= (Object *)bed->data; + short only_keys= (short)bed->i1; + + /* adjust BezTriple handles only if allowed to */ + if (only_keys == 0) { + bezt->vec[0][0]= get_action_frame(ob, bezt->vec[0][0]); + bezt->vec[2][0]= get_action_frame(ob, bezt->vec[2][0]); + } + bezt->vec[1][0]= get_action_frame(ob, bezt->vec[1][0]); +} + +/* helper function for ANIM_nla_mapping_apply_ipocurve() -> "apply", i.e. mapping points to NLA-mapped global time */ +static short bezt_nlamapping_apply(BeztEditData *bed, BezTriple *bezt) +{ + /* object providing scaling is stored in 'data', only_keys option is stored in i1 */ + Object *ob= (Object *)bed->data; + short only_keys= (short)bed->i1; + + /* adjust BezTriple handles only if allowed to */ + if (only_keys == 0) { + bezt->vec[0][0]= get_action_frame_inv(ob, bezt->vec[0][0]); + bezt->vec[2][0]= get_action_frame_inv(ob, bezt->vec[2][0]); + } + bezt->vec[1][0]= get_action_frame_inv(ob, bezt->vec[1][0]); +} + + + +/* Apply/Unapply NLA mapping to all keyframes in the nominated IPO-Curve + * - restore = whether to map points back to ipo-time + * - only_keys = whether to only adjust the location of the center point of beztriples + */ +void ANIM_nla_mapping_apply_ipocurve(Object *ob, IpoCurve *icu, short restore, short only_keys) +{ + BeztEditData bed; + BeztEditFunc map_cb; + + /* init edit data + * - ob is stored in 'data' + * - only_keys is stored in 'i1' + */ + memset(&bed, 0, sizeof(BeztEditData)); + bed.data= (void *)ob; + bed.i1= (int)only_keys; + + /* get editing callback */ + if (restore) + map_cb= bezt_nlamapping_restore; + else + map_cb= bezt_nlamapping_apply; + + /* apply to IPO curve */ + ANIM_icu_keys_bezier_loop(&bed, icu, NULL, map_cb, NULL); +} + /* Apply/Unapply NLA mapping to all keyframes in the nominated IPO block * - restore = whether to map points back to ipo-time * - only_keys = whether to only adjust the location of the center point of beztriples */ // was called actstrip_map_ipo_keys() -void ANIM_nla_mapping_apply(Object *ob, Ipo *ipo, short restore, short only_keys) +void ANIM_nla_mapping_apply_ipo(Object *ob, Ipo *ipo, short restore, short only_keys) { IpoCurve *icu; - BezTriple *bezt; - int a; - if (ipo==NULL) return; + if (ipo == NULL) return; /* loop through all ipo curves, adjusting the times of the selected keys */ for (icu= ipo->curve.first; icu; icu= icu->next) { - for (a=0, bezt=icu->bezt; a<icu->totvert; a++, bezt++) { - /* are the times being adjusted for editing, or has editing finished */ - if (restore) { - if (only_keys == 0) { - bezt->vec[0][0]= get_action_frame(ob, bezt->vec[0][0]); - bezt->vec[2][0]= get_action_frame(ob, bezt->vec[2][0]); - } - bezt->vec[1][0]= get_action_frame(ob, bezt->vec[1][0]); - } - else { - if (only_keys == 0) { - bezt->vec[0][0]= get_action_frame_inv(ob, bezt->vec[0][0]); - bezt->vec[2][0]= get_action_frame_inv(ob, bezt->vec[2][0]); - } - bezt->vec[1][0]= get_action_frame_inv(ob, bezt->vec[1][0]); - } - } + ANIM_nla_mapping_apply_ipocurve(ob, icu, restore, only_keys); } } diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index e604af4d242..ad3f732e5c8 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -465,6 +465,7 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s IpoCurve *icu= (IpoCurve *)data; ale->flag= icu->flag; + ale->key_data= icu; ale->datatype= ALE_ICU; } @@ -486,6 +487,7 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s case ANIMTYPE_IPO: { ale->flag= 0; + ale->key_data= data; ale->datatype= ALE_IPO; } @@ -510,6 +512,36 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s /* ----------------------------------------- */ +// FIXME: use this... +static int animdata_filter_ipocurves (ListBase *anim_data, Ipo *ipo, int filter_mode, void *owner, short ownertype, ID *owner_id) +{ + bAnimListElem *ale = NULL; + IpoCurve *icu; + int items = 0; + + /* loop over ipo curves - assume that the caller of this has already checked that these should be included */ + for (icu= ipo->curve.first; icu; icu= icu->next) { + /* only work with this channel and its subchannels if it is editable */ + if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_ICU(icu)) { + /* only include this curve if selected or we are including all IPO-curves */ + if (!(filter_mode & ANIMFILTER_SEL) || (filter_mode & ANIMFILTER_ONLYICU) || (SEL_ICU(icu))) { + /* owner/ownertype will be either object or action-channel, depending if it was dopesheet or part of an action */ + ale= make_new_animlistelem(icu, ANIMTYPE_ICU, owner, ownertype); + + if (ale) { + /* ID will only be Object if data to write to directly belongs there, otherwise, another pointer will be used */ + ale->id= owner_id; + BLI_addtail(anim_data, ale); + items++; + } + } + } + } + + /* return the number of items added to the list */ + return items; +} + static int animdata_filter_actionchannel (ListBase *anim_data, bActionChannel *achan, int filter_mode, void *owner, short ownertype) { bAnimListElem *ale = NULL; @@ -563,15 +595,7 @@ static int animdata_filter_actionchannel (ListBase *anim_data, bActionChannel *a /* add ipo-curve channels? */ if (FILTER_IPO_ACHAN(achan) || (filter_mode & ANIMFILTER_ONLYICU)) { /* loop through ipo-curve channels, adding them */ - for (icu= achan->ipo->curve.first; icu; icu=icu->next) { - ale= make_new_animlistelem(icu, ANIMTYPE_ICU, achan, ANIMTYPE_ACHAN); - - if (ale) { - if (owned) ale->id= owner; - BLI_addtail(anim_data, ale); - items++; - } - } + items += animdata_filter_ipocurves(anim_data, achan->ipo, filter_mode, achan, ANIMTYPE_ACHAN, (owned)?(owner):(NULL)); } } @@ -755,14 +779,7 @@ static int animdata_filter_shapekey (ListBase *anim_data, Key *key, int filter_m } } else { - for (icu= key->ipo->curve.first; icu; icu=icu->next) { - ale= make_new_animlistelem(icu, ANIMTYPE_ICU, key, ANIMTYPE_SHAPEKEY); - if (ale) { - if (owned) ale->id= owner; - BLI_addtail(anim_data, ale); - items++; - } - } + items += animdata_filter_ipocurves(anim_data, key->ipo, filter_mode, key, ANIMTYPE_SHAPEKEY, (owned)?(owner):(NULL)); } } } @@ -877,21 +894,10 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads, if ( (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_ONLYICU)) && !(filter_mode & ANIMFILTER_IPOKEYS) ) { - /* loop through ipo-curve channels, adding them */ - for (icu= ma->ipo->curve.first; icu; icu=icu->next) { - /* only if selected (if checking for selection) */ - if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) { - ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT); - if (ale) { - /* make owner the material not object, so that indent is not just object level */ - ale->id= (ID *)ma; - BLI_addtail(anim_data, ale); - items++; - } - } - } + items += animdata_filter_ipocurves(anim_data, ma->ipo, filter_mode, base, ANIMTYPE_OBJECT, (ID *)ma); } } + } /* return the number of items added to the list */ @@ -903,7 +909,6 @@ static int animdata_filter_dopesheet_cam (ListBase *anim_data, bDopeSheet *ads, bAnimListElem *ale=NULL; Object *ob= base->object; Camera *ca= (Camera *)ob->data; - IpoCurve *icu; int items = 0; /* include camera-expand widget? */ @@ -919,19 +924,7 @@ static int animdata_filter_dopesheet_cam (ListBase *anim_data, bDopeSheet *ads, if ( (FILTER_CAM_OBJD(ca) || (filter_mode & ANIMFILTER_ONLYICU)) && !(filter_mode & ANIMFILTER_IPOKEYS) ) { - /* loop through ipo-curve channels, adding them */ - for (icu= ca->ipo->curve.first; icu; icu=icu->next) { - /* only if selected (if checking for selection) */ - if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) { - ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT); - if (ale) { - /* make owner the material not object, so that indent is not just object level */ - ale->id= (ID *)ca; - BLI_addtail(anim_data, ale); - items++; - } - } - } + items += animdata_filter_ipocurves(anim_data, ca->ipo, filter_mode, base, ANIMTYPE_OBJECT, (ID *)ca); } /* return the number of items added to the list */ @@ -943,7 +936,6 @@ static int animdata_filter_dopesheet_lamp (ListBase *anim_data, bDopeSheet *ads, bAnimListElem *ale=NULL; Object *ob= base->object; Lamp *la= (Lamp *)ob->data; - IpoCurve *icu; int items = 0; /* include lamp-expand widget? */ @@ -959,19 +951,7 @@ static int animdata_filter_dopesheet_lamp (ListBase *anim_data, bDopeSheet *ads, if ( (FILTER_LAM_OBJD(la) || (filter_mode & ANIMFILTER_ONLYICU)) && !(filter_mode & ANIMFILTER_IPOKEYS) ) { - /* loop through ipo-curve channels, adding them */ - for (icu= la->ipo->curve.first; icu; icu=icu->next) { - /* only if selected (if checking for selection) */ - if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) { - ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT); - if (ale) { - /* make owner the material not object, so that indent is not just object level */ - ale->id= (ID *)la; - BLI_addtail(anim_data, ale); - items++; - } - } - } + items += animdata_filter_ipocurves(anim_data, la->ipo, filter_mode, base, ANIMTYPE_OBJECT, (ID *)la); } /* return the number of items added to the list */ @@ -983,7 +963,6 @@ static int animdata_filter_dopesheet_curve (ListBase *anim_data, bDopeSheet *ads bAnimListElem *ale=NULL; Object *ob= base->object; Curve *cu= (Curve *)ob->data; - IpoCurve *icu; int items = 0; /* include curve-expand widget? */ @@ -999,19 +978,7 @@ static int animdata_filter_dopesheet_curve (ListBase *anim_data, bDopeSheet *ads if ( (FILTER_CUR_OBJD(cu) || (filter_mode & ANIMFILTER_ONLYICU)) && !(filter_mode & ANIMFILTER_IPOKEYS) ) { - /* loop through ipo-curve channels, adding them */ - for (icu= cu->ipo->curve.first; icu; icu=icu->next) { - /* only if selected (if checking for selection) */ - if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) { - ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT); - if (ale) { - /* make owner the material not object, so that indent is not just object level */ - ale->id= (ID *)cu; - BLI_addtail(anim_data, ale); - items++; - } - } - } + items += animdata_filter_ipocurves(anim_data, cu->ipo, filter_mode, base, ANIMTYPE_OBJECT, (ID *)cu); } /* return the number of items added to the list */ @@ -1024,7 +991,6 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B Scene *sce= (Scene *)ads->source; Object *ob= base->object; Key *key= ob_get_key(ob); - IpoCurve *icu; int items = 0; /* add this object as a channel first */ @@ -1058,17 +1024,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B if ( (FILTER_IPO_OBJC(ob) || (filter_mode & ANIMFILTER_ONLYICU)) && !(filter_mode & ANIMFILTER_IPOKEYS) ) { - /* loop through ipo-curve channels, adding them */ - for (icu= ob->ipo->curve.first; icu; icu=icu->next) { - /* only if selected (if checking for selection) */ - if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) { - ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT); - if (ale) { - BLI_addtail(anim_data, ale); - items++; - } - } - } + items += animdata_filter_ipocurves(anim_data, ob->ipo, filter_mode, base, ANIMTYPE_OBJECT, NULL); // err... why not set ob? } } @@ -1104,7 +1060,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B /* add channels */ if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) { - items += animdata_filter_shapekey (anim_data, key, filter_mode, ob, ANIMTYPE_OBJECT); + items += animdata_filter_shapekey(anim_data, key, filter_mode, ob, ANIMTYPE_OBJECT); } } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 30689b8724f..efe4f50c5e5 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -656,9 +656,9 @@ void action_nlascaled_to_keylist(Object *ob, bAction *act, ListBase *keys, ListB * - scaling correction only does times for center-points, so should be faster */ if (achan->ipo) { - ANIM_nla_mapping_apply(ob, achan->ipo, 0, 1); + ANIM_nla_mapping_apply_ipo(ob, achan->ipo, 0, 1); ipo_to_keylist(achan->ipo, keys, blocks, aki); - ANIM_nla_mapping_apply(ob, achan->ipo, 1, 1); + ANIM_nla_mapping_apply_ipo(ob, achan->ipo, 1, 1); } /* then, add keys from constraint channels @@ -666,9 +666,9 @@ void action_nlascaled_to_keylist(Object *ob, bAction *act, ListBase *keys, ListB */ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) { if (conchan->ipo) { - ANIM_nla_mapping_apply(ob, conchan->ipo, 0, 1); + ANIM_nla_mapping_apply_ipo(ob, conchan->ipo, 0, 1); ipo_to_keylist(conchan->ipo, keys, blocks, aki); - ANIM_nla_mapping_apply(ob, conchan->ipo, 1, 1); + ANIM_nla_mapping_apply_ipo(ob, conchan->ipo, 1, 1); } } } diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 3b41da56b50..5c67e17bb94 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -77,7 +77,7 @@ /* This function is used to loop over BezTriples in the given IpoCurve, applying a given * operation on them, and optionally applies an IPO-curve validate function afterwards. */ -short icu_keys_bezier_loop(BeztEditData *bed, IpoCurve *icu, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb) +short ANIM_icu_keys_bezier_loop(BeztEditData *bed, IpoCurve *icu, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb) { BezTriple *bezt; int b; @@ -117,7 +117,7 @@ short icu_keys_bezier_loop(BeztEditData *bed, IpoCurve *icu, BeztEditFunc bezt_o } /* This function is used to loop over the IPO curves (and subsequently the keyframes in them) */ -short ipo_keys_bezier_loop(BeztEditData *bed, Ipo *ipo, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb) +short ANIM_ipo_keys_bezier_loop(BeztEditData *bed, Ipo *ipo, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb) { IpoCurve *icu; @@ -127,7 +127,7 @@ short ipo_keys_bezier_loop(BeztEditData *bed, Ipo *ipo, BeztEditFunc bezt_ok, Be /* Loop through each curve in the Ipo */ for (icu= ipo->curve.first; icu; icu=icu->next) { - if (icu_keys_bezier_loop(bed, icu, bezt_ok, bezt_cb, icu_cb)) + if (ANIM_icu_keys_bezier_loop(bed, icu, bezt_ok, bezt_cb, icu_cb)) return 1; } @@ -137,7 +137,7 @@ short ipo_keys_bezier_loop(BeztEditData *bed, Ipo *ipo, BeztEditFunc bezt_ok, Be /* -------------------------------- Further Abstracted ----------------------------- */ /* This function is used to apply operation to all keyframes, regardless of the type */ -short animchannel_keys_bezier_loop(BeztEditData *bed, bAnimListElem *ale, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb) +short ANIM_animchannel_keys_bezier_loop(BeztEditData *bed, bAnimListElem *ale, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb) { /* sanity checks */ if (ale == NULL) @@ -146,9 +146,9 @@ short animchannel_keys_bezier_loop(BeztEditData *bed, bAnimListElem *ale, BeztEd /* method to use depends on the type of keyframe data */ switch (ale->datatype) { case ALE_ICU: /* ipo-curve */ - return icu_keys_bezier_loop(bed, ale->key_data, bezt_ok, bezt_cb, icu_cb); + return ANIM_icu_keys_bezier_loop(bed, ale->key_data, bezt_ok, bezt_cb, icu_cb); case ALE_IPO: /* ipo */ - return ipo_keys_bezier_loop(bed, ale->key_data, bezt_ok, bezt_cb, icu_cb); + return ANIM_ipo_keys_bezier_loop(bed, ale->key_data, bezt_ok, bezt_cb, icu_cb); case ALE_GROUP: /* action group */ //return group_keys_bezier_loop(bed, ale->data, bezt_ok, bezt_cb, icu_cb); diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index ddb63be1d1c..1c44fbbd6ac 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -308,7 +308,8 @@ struct Object *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale); void ANIM_nla_mapping_draw(struct gla2DDrawInfo *di, struct Object *ob, short restore); /* Apply/Unapply NLA mapping to all keyframes in the nominated IPO block */ -void ANIM_nla_mapping_apply(struct Object *ob, struct Ipo *ipo, short restore, short only_keys); +void ANIM_nla_mapping_apply_ipocurve(struct Object *ob, struct IpoCurve *icu, short restore, short only_keys); +void ANIM_nla_mapping_apply_ipo(struct Object *ob, struct Ipo *ipo, short restore, short only_keys); /* ------------- xxx macros ----------------------- */ diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 75faaf85d14..eb6f422e425 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -87,13 +87,12 @@ typedef enum eEditKeyframes_Mirror { /* --- Generic Properties for Bezier Edit Tools ----- */ -// XXX maybe a union would be more compact? typedef struct BeztEditData { ListBase list; /* temp list for storing custom list of data to check */ struct Scene *scene; /* pointer to current scene - many tools need access to cfra/etc. */ - void *data; /* pointer to custom data - not that useful? */ + void *data; /* pointer to custom data - usually 'Object', but could be other types too */ float f1, f2; /* storage of times/values as 'decimals' */ - int i1, i2; /* storage of times/values as 'whole' numbers */ + int i1, i2; /* storage of times/values/flags as 'whole' numbers */ } BeztEditData; /* ------- Function Pointer Typedefs ---------------- */ @@ -106,8 +105,8 @@ typedef short (*BeztEditFunc)(BeztEditData *bed, struct BezTriple *bezt); /* ---------------- Looping API --------------------- */ /* functions for looping over keyframes */ -short icu_keys_bezier_loop(BeztEditData *bed, struct IpoCurve *icu, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb); -short ipo_keys_bezier_loop(BeztEditData *bed, struct Ipo *ipo, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb); +short ANIM_icu_keys_bezier_loop(BeztEditData *bed, struct IpoCurve *icu, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb); +short ANIM_ipo_keys_bezier_loop(BeztEditData *bed, struct Ipo *ipo, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb); /* functions for making sure all keyframes are in good order */ void ANIM_editkeyframes_refresh(struct bAnimContext *ac); diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 4775a37e420..9fc1deab9f2 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -107,7 +107,7 @@ static void get_keyframe_extents (bAnimContext *ac, float *min, float *max) /* check if any channels to set range with */ if (anim_data.first) { - /* go through channels, finding max extents*/ + /* go through channels, finding max extents */ for (ale= anim_data.first; ale; ale= ale->next) { Object *nob= ANIM_nla_mapping_get(ac, ale); Ipo *ipo= (Ipo *)ale->key_data; @@ -856,7 +856,9 @@ static void setexpo_action_keys(bAnimContext *ac, short mode) filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS); ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype); - /* loop through setting mode per ipo-curve */ + /* loop through setting mode per ipo-curve + * Note: setting is on IPO-curve level not keyframe, so no need for Keyframe-Editing API + */ for (ale= anim_data.first; ale; ale= ale->next) setexprap_ipoloop(ale->key_data, mode); @@ -939,7 +941,7 @@ static void setipo_action_keys(bAnimContext *ac, short mode) * Note: we do not supply BeztEditData to the looper yet. Currently that's not necessary here... */ for (ale= anim_data.first; ale; ale= ale->next) - ipo_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, ANIM_editkeyframes_ipocurve_ipotype); + ANIM_ipo_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, ANIM_editkeyframes_ipocurve_ipotype); /* cleanup */ BLI_freelistN(&anim_data); @@ -1028,17 +1030,17 @@ static void sethandles_action_keys(bAnimContext *ac, short mode) /* check which type of handle to set (free or aligned) * - check here checks for handles with free alignment already */ - if (ipo_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, NULL)) + if (ANIM_ipo_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, NULL)) toggle_cb= ANIM_editkeyframes_handles(HD_FREE); else toggle_cb= ANIM_editkeyframes_handles(HD_ALIGN); /* set handle-type */ - ipo_keys_bezier_loop(NULL, ale->key_data, NULL, toggle_cb, calchandles_ipocurve); + ANIM_ipo_keys_bezier_loop(NULL, ale->key_data, NULL, toggle_cb, calchandles_ipocurve); } else { /* directly set handle-type */ - ipo_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, calchandles_ipocurve); + ANIM_ipo_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, calchandles_ipocurve); } } @@ -1137,7 +1139,7 @@ static int actkeys_cfrasnap_exec(bContext *C, wmOperator *op) ANIM_animdata_filter(&anim_data, filter, ac.data, ac.datatype); for (ale= anim_data.first; ale; ale= ale->next) - ipo_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_calc_average, NULL); + ANIM_ipo_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_calc_average, NULL); BLI_freelistN(&anim_data); @@ -1192,7 +1194,7 @@ static void snap_action_keys(bAnimContext *ac, short mode) if (ac->datatype == ANIMCONT_GPENCIL) filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT); else - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS); + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU); ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype); /* get beztriple editing callbacks */ @@ -1206,14 +1208,14 @@ static void snap_action_keys(bAnimContext *ac, short mode) Object *nob= ANIM_nla_mapping_get(ac, ale); if (nob) { - ANIM_nla_mapping_apply(nob, ale->key_data, 0, 1); - ipo_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve); - ANIM_nla_mapping_apply(nob, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 0, 1); + ANIM_icu_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve); + ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 1, 1); } //else if (ale->type == ACTTYPE_GPLAYER) // snap_gplayer_frames(ale->data, mode); else - ipo_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve); + ANIM_icu_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve); } BLI_freelistN(&anim_data); } @@ -1316,7 +1318,7 @@ static void mirror_action_keys(bAnimContext *ac, short mode) if (ac->datatype == ANIMCONT_GPENCIL) filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT); else - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS); + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU); ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype); /* mirror keyframes */ @@ -1324,14 +1326,14 @@ static void mirror_action_keys(bAnimContext *ac, short mode) Object *nob= ANIM_nla_mapping_get(ac, ale); if (nob) { - ANIM_nla_mapping_apply(nob, ale->key_data, 0, 1); - ipo_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve); - ANIM_nla_mapping_apply(nob, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 0, 1); + ANIM_icu_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve); + ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 1, 1); } //else if (ale->type == ACTTYPE_GPLAYER) // snap_gplayer_frames(ale->data, mode); else - ipo_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve); + ANIM_icu_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve); } BLI_freelistN(&anim_data); } diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 231f53a6171..039a5038027 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -415,9 +415,9 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short /* loop over data selecting */ if (ale->key_data) { if (ale->datatype == ALE_IPO) - ipo_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); else if (ale->datatype == ALE_ICU) - icu_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_icu_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); } else if (ale->type == ANIMTYPE_GROUP) { bActionGroup *agrp= ale->data; @@ -425,10 +425,10 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short bConstraintChannel *conchan; for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) { - ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) - ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); } } //else if (ale->type == ANIMTYPE_GPLAYER) { @@ -504,7 +504,6 @@ void ACT_OT_keyframes_borderselect(wmOperatorType *ot) ot->poll= ED_operator_areaactive; /* flags */ - // XXX er... ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; /* rna */ @@ -571,12 +570,12 @@ static void markers_selectkeys_between (bAnimContext *ac) Object *nob= ANIM_nla_mapping_get(ac, ale); if (nob) { - ANIM_nla_mapping_apply(nob, ale->key_data, 0, 1); - ipo_keys_bezier_loop(&bed, ale->key_data, NULL, select_cb, NULL); - ANIM_nla_mapping_apply(nob, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_ipo(nob, ale->key_data, 0, 1); + ANIM_ipo_keys_bezier_loop(&bed, ale->key_data, NULL, select_cb, NULL); + ANIM_nla_mapping_apply_ipo(nob, ale->key_data, 1, 1); } else { - ipo_keys_bezier_loop(&bed, ale->key_data, NULL, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, ale->key_data, NULL, select_cb, NULL); } } @@ -630,7 +629,7 @@ static void columnselect_action_keys (bAnimContext *ac, short mode) ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype); for (ale= anim_data.first; ale; ale= ale->next) - ipo_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_to_cfraelem, NULL); + ANIM_ipo_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_to_cfraelem, NULL); } BLI_freelistN(&anim_data); break; @@ -680,7 +679,7 @@ static void columnselect_action_keys (bAnimContext *ac, short mode) bed.f1= ce->cfra; /* select elements with frame number matching cfraelem */ - icu_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_icu_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); #if 0 // XXX reenable when Grease Pencil stuff is back if (ale->type == ANIMTYPE_GPLAYER) { @@ -882,33 +881,33 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short selectmode) /* apply selection to keyframes */ if (icu) - icu_keys_bezier_loop(&bed, icu, ok_cb, select_cb, NULL); + ANIM_icu_keys_bezier_loop(&bed, icu, ok_cb, select_cb, NULL); else if (ipo) - ipo_keys_bezier_loop(&bed, ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, ipo, ok_cb, select_cb, NULL); else if (conchan) - ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); else if (achan) - ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); else if (agrp) { for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) { - ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) - ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); } } else if (act) { for (achan= act->chanbase.first; achan; achan= achan->next) { - ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) - ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); } } else if (ob) { if (ob->ipo) { bed.f1= selx; - ipo_keys_bezier_loop(&bed, ob->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, ob->ipo, ok_cb, select_cb, NULL); } if (ob->action) { @@ -916,10 +915,10 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short selectmode) bed.f1= selxa; for (achan= ob->action->chanbase.first; achan; achan= achan->next) { - ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, achan->ipo, ok_cb, select_cb, NULL); for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) - ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); } } @@ -927,7 +926,7 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short selectmode) bed.f1= selx; for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) - ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, conchan->ipo, ok_cb, select_cb, NULL); } // FIXME: add data ipos too... @@ -979,14 +978,14 @@ static void selectkeys_leftright (bAnimContext *ac, short leftright, short selec Object *nob= ANIM_nla_mapping_get(ac, ale); if (nob) { - ANIM_nla_mapping_apply(nob, ale->key_data, 0, 1); - ipo_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); - ANIM_nla_mapping_apply(nob, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_ipo(nob, ale->key_data, 0, 1); + ANIM_ipo_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_nla_mapping_apply_ipo(nob, ale->key_data, 1, 1); } //else if (ale->type == ANIMTYPE_GPLAYER) // borderselect_gplayer_frames(ale->data, min, max, SELECT_ADD); else - ipo_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_ipo_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); } /* Cleanup */ @@ -1029,7 +1028,7 @@ static void mouse_columnselect_action_keys (bAnimContext *ac, float selx) bed.f1= selx; /* select elements with frame number matching cfraelem */ - icu_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_icu_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); #if 0 // XXX reenable when Grease Pencil stuff is back if (ale->type == ANIMTYPE_GPLAYER) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index ebac66d6b12..8d73c808745 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -160,8 +160,6 @@ void transform_aspect_ratio_tface_uv(float *a1, float *a2) {} /* local function prototype - for Object/Bone Constraints */ static short constraints_list_needinv(TransInfo *t, ListBase *list); -/* local function prototype - for finding number of keyframes that are selected for editing */ -static int count_ipo_keys(Ipo *ipo, char side, float cfra); /* ************************** Functions *************************** */ @@ -2674,66 +2672,79 @@ static void posttrans_gpd_clean (bGPdata *gpd) } } -/* Called by special_aftertrans_update to make sure selected keyframes replace +/* Called during special_aftertrans_update to make sure selected keyframes replace * any other keyframes which may reside on that frame (that is not selected). */ -static void posttrans_ipo_clean (Ipo *ipo) +static void posttrans_icu_clean (IpoCurve *icu) { - IpoCurve *icu; - int i; + float *selcache; /* cache for frame numbers of selected frames (icu->totvert*sizeof(float)) */ + int len, index, i; /* number of frames in cache, item index */ - /* delete any keyframes that occur on same frame as selected keyframe, but is not selected */ - for (icu= ipo->curve.first; icu; icu= icu->next) { - float *selcache; /* cache for frame numbers of selected frames (icu->totvert*sizeof(float)) */ - int len, index; /* number of frames in cache, item index */ - - /* allocate memory for the cache */ - // TODO: investigate using GHash for this instead? - if (icu->totvert == 0) - continue; - selcache= MEM_callocN(sizeof(float)*icu->totvert, "IcuSelFrameNums"); - len= 0; - index= 0; + /* allocate memory for the cache */ + // TODO: investigate using GHash for this instead? + if (icu->totvert == 0) + return; + selcache= MEM_callocN(sizeof(float)*icu->totvert, "IcuSelFrameNums"); + len= 0; + index= 0; + + /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting + * as there is no guarantee what order the keyframes are exactly, even though + * they have been sorted by time. + */ + + /* Loop 1: find selected keyframes */ + for (i = 0; i < icu->totvert; i++) { + BezTriple *bezt= &icu->bezt[i]; - /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting - * as there is no guarantee what order the keyframes are exactly, even though - * they have been sorted by time. - */ - - /* Loop 1: find selected keyframes */ + if (BEZSELECTED(bezt)) { + selcache[index]= bezt->vec[1][0]; + index++; + len++; + } + } + + /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */ + if (len) { for (i = 0; i < icu->totvert; i++) { BezTriple *bezt= &icu->bezt[i]; - if (BEZSELECTED(bezt)) { - selcache[index]= bezt->vec[1][0]; - index++; - len++; - } - } - - /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */ - if (len) { - for (i = 0; i < icu->totvert; i++) { - BezTriple *bezt= &icu->bezt[i]; - - if (BEZSELECTED(bezt) == 0) { - /* check beztriple should be removed according to cache */ - for (index= 0; index < len; index++) { - if (IS_EQ(bezt->vec[1][0], selcache[index])) { - delete_icu_key(icu, i, 0); - break; - } - else if (bezt->vec[1][0] > selcache[index]) - break; + if (BEZSELECTED(bezt) == 0) { + /* check beztriple should be removed according to cache */ + for (index= 0; index < len; index++) { + if (IS_EQ(bezt->vec[1][0], selcache[index])) { + delete_icu_key(icu, i, 0); + break; } + else if (bezt->vec[1][0] > selcache[index]) + break; } } - - testhandles_ipocurve(icu); } - /* free cache */ - MEM_freeN(selcache); + testhandles_ipocurve(icu); + } + + /* free cache */ + MEM_freeN(selcache); +} + +/* Called by special_aftertrans_update to make sure selected keyframes replace + * any other keyframes which may reside on that frame (that is not selected). + * remake_action_ipos should have already been called + */ +static void posttrans_ipo_clean (Ipo *ipo) +{ + IpoCurve *icu; + + if (ipo == NULL) + return; + + /* loop through relevant data, removing keyframes from the ipocurves + * - all keyframes are converted in/out of global time + */ + for (icu= ipo->curve.first; icu; icu= icu->next) { + posttrans_icu_clean(icu); } } @@ -2748,7 +2759,7 @@ static void posttrans_action_clean (bAnimContext *ac, bAction *act) int filter; /* filter data */ - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS); + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU); ANIM_animdata_filter(&anim_data, filter, act, ANIMCONT_ACTION); /* loop through relevant data, removing keyframes from the ipo-blocks that were attached @@ -2758,107 +2769,18 @@ static void posttrans_action_clean (bAnimContext *ac, bAction *act) Object *nob= ANIM_nla_mapping_get(ac, ale); if (nob) { - ANIM_nla_mapping_apply(nob, ale->key_data, 0, 1); - posttrans_ipo_clean(ale->key_data); - ANIM_nla_mapping_apply(nob, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 0, 1); + posttrans_icu_clean(ale->key_data); + ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 1, 1); } else - posttrans_ipo_clean(ale->key_data); + posttrans_icu_clean(ale->key_data); } /* free temp data */ BLI_freelistN(&anim_data); } -/* Called by special_aftertrans_update to make sure selected keyframes replace - * any other keyframes which may reside on that frame (that is not selected). - * remake_all_ipos should have already been called - */ -static void posttrans_nla_clean (TransInfo *t) -{ -#if 0 // TRANSFORM_FIX_ME - Base *base; - Object *ob; - bActionStrip *strip; - bActionChannel *achan; - bConstraintChannel *conchan; - float cfra; - char side; - int i; - - /* which side of the current frame should be allowed */ - if (t->mode == TFM_TIME_EXTEND) { - /* only side on which mouse is gets transformed */ - float xmouse, ymouse; - - areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse); - side = (xmouse > CFRA) ? 'R' : 'L'; - } - else { - /* normal transform - both sides of current frame are considered */ - side = 'B'; - } - - /* only affect keyframes */ - for (base=G.scene->base.first; base; base=base->next) { - ob= base->object; - - /* Check object ipos */ - i= count_ipo_keys(ob->ipo, side, (float)CFRA); - if (i) posttrans_ipo_clean(ob->ipo); - - /* Check object constraint ipos */ - for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) { - i= count_ipo_keys(conchan->ipo, side, (float)CFRA); - if (i) posttrans_ipo_clean(conchan->ipo); - } - - /* skip actions and nlastrips if object is collapsed */ - if (ob->nlaflag & OB_NLA_COLLAPSED) - continue; - - /* Check action ipos */ - if (ob->action) { - /* exclude if strip is selected too */ - for (strip=ob->nlastrips.first; strip; strip=strip->next) { - if (strip->flag & ACTSTRIP_SELECT) { - if (strip->act == ob->action) - break; - } - } - if (strip==NULL) { - cfra = get_action_frame(ob, (float)CFRA); - - for (achan=ob->action->chanbase.first; achan; achan=achan->next) { - if (EDITABLE_ACHAN(achan)) { - i= count_ipo_keys(achan->ipo, side, cfra); - if (i) { - actstrip_map_ipo_keys(ob, achan->ipo, 0, 1); - posttrans_ipo_clean(achan->ipo); - actstrip_map_ipo_keys(ob, achan->ipo, 1, 1); - } - - /* Check action constraint ipos */ - if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) { - for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) { - if (EDITABLE_CONCHAN(conchan)) { - i = count_ipo_keys(conchan->ipo, side, cfra); - if (i) { - actstrip_map_ipo_keys(ob, conchan->ipo, 0, 1); - posttrans_ipo_clean(conchan->ipo); - actstrip_map_ipo_keys(ob, conchan->ipo, 1, 1); - } - } - } - } - } - } - } - } - } -#endif -} - /* ----------------------------- */ /* This function tests if a point is on the "mouse" side of the cursor/frame-marking */ @@ -2875,27 +2797,24 @@ static short FrameOnMouseSide(char side, float frame, float cframe) } /* fully select selected beztriples, but only include if it's on the right side of cfra */ -static int count_ipo_keys(Ipo *ipo, char side, float cfra) +static int count_icu_keys(IpoCurve *icu, char side, float cfra) { - IpoCurve *icu; BezTriple *bezt; int i, count = 0; - if (ipo == NULL) + if (icu == NULL) return count; /* only include points that occur on the right side of cfra */ - for (icu= ipo->curve.first; icu; icu= icu->next) { - for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { - if (bezt->f2 & SELECT) { - /* fully select the other two keys */ - bezt->f1 |= SELECT; - bezt->f3 |= SELECT; - - /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */ - if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) - count += 3; - } + for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { + if (bezt->f2 & SELECT) { + /* fully select the other two keys */ + bezt->f1 |= SELECT; + bezt->f3 |= SELECT; + + /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */ + if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) + count += 3; } } @@ -2938,38 +2857,35 @@ static void TimeToTransData(TransData *td, float *time, Object *ob) /* This function advances the address to which td points to, so it must return * the new address so that the next time new transform data is added, it doesn't - * overwrite the existing ones... i.e. td = IpoToTransData(td, ipo, ob, side, cfra); + * overwrite the existing ones... i.e. td = IcuToTransData(td, icu, ob, side, cfra); * * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data * on the named side are used. */ -static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob, char side, float cfra) +static TransData *IcuToTransData(TransData *td, IpoCurve *icu, Object *ob, char side, float cfra) { - IpoCurve *icu; BezTriple *bezt; int i; - if (ipo == NULL) + if (icu == NULL) return td; - - for (icu= ipo->curve.first; icu; icu= icu->next) { - for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { - /* only add selected keyframes (for now, proportional edit is not enabled) */ - if (BEZSELECTED(bezt)) { - /* only add if on the right 'side' of the current frame */ - if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) { - /* each control point needs to be added separetely */ - TimeToTransData(td, bezt->vec[0], ob); - td++; - - TimeToTransData(td, bezt->vec[1], ob); - td++; - - TimeToTransData(td, bezt->vec[2], ob); - td++; - } - } - } + + for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { + /* only add selected keyframes (for now, proportional edit is not enabled) */ + if (BEZSELECTED(bezt)) { + /* only add if on the right 'side' of the current frame */ + if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) { + /* each control point needs to be added separetely */ + TimeToTransData(td, bezt->vec[0], ob); + td++; + + TimeToTransData(td, bezt->vec[1], ob); + td++; + + TimeToTransData(td, bezt->vec[2], ob); + td++; + } + } } return td; @@ -3056,7 +2972,7 @@ static void createTransActionData(bContext *C, TransInfo *t) if (ac.datatype == ANIMCONT_GPENCIL) filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT); else - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS); + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU); ANIM_animdata_filter(&anim_data, filter, ac.data, ac.datatype); /* which side of the current frame should be allowed */ @@ -3087,7 +3003,7 @@ static void createTransActionData(bContext *C, TransInfo *t) //if (ale->type == ANIMTYPE_GPLAYER) // count += count_gplayer_frames(ale->data, side, cfra); //else - count += count_ipo_keys(ale->key_data, side, cfra); + count += count_icu_keys(ale->key_data, side, cfra); } /* stop if trying to build list if nothing selected */ @@ -3128,7 +3044,7 @@ static void createTransActionData(bContext *C, TransInfo *t) //} //else { Object *nob= ANIM_nla_mapping_get(&ac, ale); - Ipo *ipo= (Ipo *)ale->key_data; + IpoCurve *icu= (IpoCurve *)ale->key_data; /* convert current-frame to action-time (slightly less accurate, espcially under * higher scaling ratios, but is faster than converting all points) @@ -3138,7 +3054,7 @@ static void createTransActionData(bContext *C, TransInfo *t) else cfra = (float)CFRA; - td= IpoToTransData(td, ipo, nob, side, cfra); + td= IcuToTransData(td, icu, nob, side, cfra); //} } @@ -3165,162 +3081,6 @@ static void createTransActionData(bContext *C, TransInfo *t) BLI_freelistN(&anim_data); } -static void createTransNlaData(bContext *C, TransInfo *t) -{ - // TRANSFORM_FIX_ME -#if 0 - Base *base; - bActionStrip *strip; - bActionChannel *achan; - bConstraintChannel *conchan; - - TransData *td = NULL; - int count=0, i; - float cfra; - char side; - - /* which side of the current frame should be allowed */ - if (t->mode == TFM_TIME_EXTEND) { - /* only side on which mouse is gets transformed */ - float xmouse, ymouse; - - areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse); - side = (xmouse > CFRA) ? 'R' : 'L'; - } - else { - /* normal transform - both sides of current frame are considered */ - side = 'B'; - } - - /* Ensure that partial selections result in beztriple selections */ - for (base=G.scene->base.first; base; base=base->next) { - /* Check object ipos */ - i= count_ipo_keys(base->object->ipo, side, (float)CFRA); - if (i) base->flag |= BA_HAS_RECALC_OB; - count += i; - - /* Check object constraint ipos */ - for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next) - count += count_ipo_keys(conchan->ipo, side, (float)CFRA); - - /* skip actions and nlastrips if object is collapsed */ - if (base->object->nlaflag & OB_NLA_COLLAPSED) - continue; - - /* Check action ipos */ - if (base->object->action) { - /* exclude if strip is selected too */ - for (strip=base->object->nlastrips.first; strip; strip=strip->next) { - if (strip->flag & ACTSTRIP_SELECT) { - if (strip->act == base->object->action) - break; - } - } - if (strip==NULL) { - cfra = get_action_frame(base->object, (float)CFRA); - - for (achan=base->object->action->chanbase.first; achan; achan=achan->next) { - if (EDITABLE_ACHAN(achan)) { - i= count_ipo_keys(achan->ipo, side, cfra); - if (i) base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA; - count += i; - - /* Check action constraint ipos */ - if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) { - for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) { - if (EDITABLE_CONCHAN(conchan)) - count += count_ipo_keys(conchan->ipo, side, cfra); - } - } - } - } - } - } - - /* Check nlastrips */ - for (strip=base->object->nlastrips.first; strip; strip=strip->next) { - if (strip->flag & ACTSTRIP_SELECT) { - base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA; - - if (FrameOnMouseSide(side, strip->start, (float)CFRA)) count++; - if (FrameOnMouseSide(side, strip->end, (float)CFRA)) count++; - } - } - } - - /* If nothing is selected, bail out */ - if (count == 0) - return; - - /* allocate memory for data */ - t->total= count; - t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (NLA Editor)"); - - /* build the transdata structure */ - td= t->data; - for (base=G.scene->base.first; base; base=base->next) { - /* Manipulate object ipos */ - /* - no scaling of keyframe times is allowed here */ - td= IpoToTransData(td, base->object->ipo, NULL, side, (float)CFRA); - - /* Manipulate object constraint ipos */ - /* - no scaling of keyframe times is allowed here */ - for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next) - td= IpoToTransData(td, conchan->ipo, NULL, side, (float)CFRA); - - /* skip actions and nlastrips if object collapsed */ - if (base->object->nlaflag & OB_NLA_COLLAPSED) - continue; - - /* Manipulate action ipos */ - if (base->object->action) { - /* exclude if strip that active action belongs to is selected too */ - for (strip=base->object->nlastrips.first; strip; strip=strip->next) { - if (strip->flag & ACTSTRIP_SELECT) { - if (strip->act == base->object->action) - break; - } - } - - /* can include if no strip found */ - if (strip==NULL) { - cfra = get_action_frame(base->object, (float)CFRA); - - for (achan=base->object->action->chanbase.first; achan; achan=achan->next) { - if (EDITABLE_ACHAN(achan)) { - td= IpoToTransData(td, achan->ipo, base->object, side, cfra); - - /* Manipulate action constraint ipos */ - if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) { - for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) { - if (EDITABLE_CONCHAN(conchan)) - td= IpoToTransData(td, conchan->ipo, base->object, side, cfra); - } - } - } - } - } - } - - /* Manipulate nlastrips */ - for (strip=base->object->nlastrips.first; strip; strip=strip->next) { - if (strip->flag & ACTSTRIP_SELECT) { - /* first TransData is the start, second is the end */ - if (FrameOnMouseSide(side, strip->start, (float)CFRA)) { - td->val = &strip->start; - td->ival = strip->start; - td++; - } - if (FrameOnMouseSide(side, strip->end, (float)CFRA)) { - td->val = &strip->end; - td->ival = strip->end; - td++; - } - } - } - } -#endif -} /* **************** IpoKey stuff, for Object TransData ********** */ @@ -3987,7 +3747,7 @@ void special_aftertrans_update(TransInfo *t) if (ac.datatype == ANIMCONT_DOPESHEET) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS); + short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU); /* get channels to work on */ ANIM_animdata_filter(&anim_data, filter, ac.data, ac.datatype); @@ -3995,18 +3755,18 @@ void special_aftertrans_update(TransInfo *t) /* these should all be ipo-blocks */ for (ale= anim_data.first; ale; ale= ale->next) { Object *nob= ANIM_nla_mapping_get(&ac, ale); - Ipo *ipo= ale->key_data; + IpoCurve *icu= (IpoCurve *)ale->key_data; if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { if (nob) { - ANIM_nla_mapping_apply(nob, ipo, 0, 1); - posttrans_ipo_clean(ipo); - ANIM_nla_mapping_apply(nob, ipo, 1, 1); + ANIM_nla_mapping_apply_ipocurve(nob, icu, 0, 1); + posttrans_icu_clean(icu); + ANIM_nla_mapping_apply_ipocurve(nob, icu, 1, 1); } else - posttrans_ipo_clean(ipo); + posttrans_icu_clean(icu); } } @@ -4037,8 +3797,6 @@ void special_aftertrans_update(TransInfo *t) Key *key= (Key *)ac.data; if (key->ipo) { - IpoCurve *icu; - if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { @@ -4413,7 +4171,8 @@ void createTransData(bContext *C, TransInfo *t) } else if (t->spacetype == SPACE_NLA) { t->flag |= T_POINTS|T_2D_EDIT; - createTransNlaData(C, t); + // TRANSFORM_FIX_ME + //createTransNlaData(C, t); } else if (t->spacetype == SPACE_IPO) { t->flag |= T_POINTS|T_2D_EDIT; |