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.
This commit is contained in:
2009-01-03 06:01:11 +00:00
parent 61f7ba6fa2
commit 4b320c26a3
9 changed files with 282 additions and 522 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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 ----------------------- */

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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 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_icu_clean (IpoCurve *icu)
{
float *selcache; /* cache for frame numbers of selected frames (icu->totvert*sizeof(float)) */
int len, index, i; /* number of frames in cache, item index */
/* 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];
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;
}
}
}
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;
int i;
/* delete any keyframes that occur on same frame as selected keyframe, but is not selected */
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) {
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;
/* 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];
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;
}
}
}
testhandles_ipocurve(icu);
}
/* free cache */
MEM_freeN(selcache);
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;