diff options
author | Joshua Leung <aligorith@gmail.com> | 2008-05-14 13:00:22 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2008-05-14 13:00:22 +0400 |
commit | 9fdb4965a32fdc5fbfe6ad169630672e70d85470 (patch) | |
tree | 8c25094eb69f70bcb2b05fbf19fcb4be74f4d7e1 /source/blender/src/transform_conversions.c | |
parent | f98085bd7ec3aba6775df4ab25c2c5475e37cae3 (diff) |
NLA and IPO now have the "AfterTrans Keyframe" option that prevents the creation of duplicate keyframes after transform.
Diffstat (limited to 'source/blender/src/transform_conversions.c')
-rw-r--r-- | source/blender/src/transform_conversions.c | 115 |
1 files changed, 112 insertions, 3 deletions
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 6636c435b8c..e42eedee1f7 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -144,6 +144,8 @@ extern ListBase editelems; /* 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 *************************** */ @@ -2490,6 +2492,93 @@ static void posttrans_action_clean (bAction *act) BLI_freelistN(&act_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) +{ + 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, 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, CFRA); + if (i) posttrans_ipo_clean(ob->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, 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); + } + } + } + } + } + } + } + } + } +} + /* ----------------------------- */ /* This function tests if a point is on the "mouse" side of the cursor/frame-marking */ @@ -3487,8 +3576,6 @@ void special_aftertrans_update(TransInfo *t) if (key->ipo) { IpoCurve *icu; - - if ( (G.saction->flag & SACTION_NOTRANSKEYCULL)==0 && (cancelled == 0) ) { @@ -3507,17 +3594,39 @@ void special_aftertrans_update(TransInfo *t) G.saction->flag &= ~SACTION_MOVING; } else if (t->spacetype == SPACE_NLA) { + recalc_all_ipos(); // bad synchronize_action_strips(); /* cleanup */ for (base=G.scene->base.first; base; base=base->next) base->flag &= ~(BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA); - recalc_all_ipos(); // bad + /* after transform, remove duplicate keyframes on a frame that resulted from transform */ + if ( (G.snla->flag & SNLA_NOTRANSKEYCULL)==0 && + (cancelled == 0) ) + { + posttrans_nla_clean(t); + } } else if (t->spacetype == SPACE_IPO) { // FIXME! is there any code from the old transform_ipo that needs to be added back? + /* after transform, remove duplicate keyframes on a frame that resulted from transform */ + if (G.sipo->ipo) + { + if ( (G.sipo->flag & SIPO_NOTRANSKEYCULL)==0 && + (cancelled == 0) ) + { + if (NLA_IPO_SCALED) { + actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 0, 1); + posttrans_ipo_clean(G.sipo->ipo); + actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 1, 1); + } + else + posttrans_ipo_clean(G.sipo->ipo); + } + } + /* resetting slow-parents isn't really necessary when editing sequence ipo's */ if (G.sipo->blocktype==ID_SEQ) resetslowpar= 0; |