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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ----------------------- */
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user