From 618b459e8b3630eea747523febec666889a364f7 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 18 Mar 2010 13:04:46 +0000 Subject: F-Modifier Goodies (as requested by @ndy): * Copy/Paste operators for F-Modifiers Available in Graph and NLA Editors. Use the Copy/Paste buttons beside the 'Add Modifier' buttons. Copy copies all the modifiers of the ACTIVE F-Curve or Strip depending on the editor. Paste pastes modifiers from the buffer to all the selected F-Curves or Strips, adding the new modifiers to the ends of each list. * 'Stepped Interpolation' F-Modifier This modifier holds each interpolated value from the F-Curve for several frames without changing the timing. This allows to preview motions 'on-twos' for example without altering the timing, or having to go through setting heaps of keyframes. In this case, Andy wanted to use this for CG <-> StopMo. --- source/blender/editors/space_nla/nla_buttons.c | 5 + source/blender/editors/space_nla/nla_edit.c | 124 ++++++++++++++++++++++++- source/blender/editors/space_nla/nla_intern.h | 2 + source/blender/editors/space_nla/nla_ops.c | 2 + 4 files changed, 131 insertions(+), 2 deletions(-) (limited to 'source/blender/editors/space_nla') diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 4f944d1b855..944a93a713f 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -430,6 +430,11 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa) // XXX for now, this will be a operator button which calls a temporary 'add modifier' operator // FIXME: we need to set the only-active property so that this will only add modifiers for the active strip (not all selected) uiDefButO(block, BUT, "NLA_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, "Add Modifier", 10, 0, 150, 20, "Adds a new F-Modifier for the active NLA Strip"); + + /* copy/paste (as sub-row)*/ + row= uiLayoutRow(row, 1); + uiItemO(row, "", ICON_COPYDOWN, "NLA_OT_fmodifier_copy"); + uiItemO(row, "", ICON_PASTEDOWN, "NLA_OT_fmodifier_paste"); } /* draw each modifier */ diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 543fa1dfed7..bc99ded4db6 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -1633,8 +1633,7 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op) BLI_freelistN(&anim_data); /* set notifier that things have changed */ - // FIXME: this doesn't really do it justice... - WM_event_add_notifier(C, NC_ANIMATION, NULL); + WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_EDIT, NULL); /* done */ return OPERATOR_FINISHED; @@ -1659,4 +1658,125 @@ void NLA_OT_fmodifier_add (wmOperatorType *ot) RNA_def_boolean(ot->srna, "only_active", 0, "Only Active", "Only add F-Modifier of the specified type to the active strip."); } +/* ******************** Copy F-Modifiers Operator *********************** */ + +static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter, ok=0; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* clear buffer first */ + free_fmodifiers_copybuf(); + + /* get a list of the editable tracks being shown in the NLA */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_FOREDIT); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + /* for each NLA-Track, add the specified modifier to all selected strips */ + for (ale= anim_data.first; ale; ale= ale->next) { + NlaTrack *nlt= (NlaTrack *)ale->data; + NlaStrip *strip; + + for (strip= nlt->strips.first; strip; strip=strip->next) { + /* only add F-Modifier if on active strip? */ + if ((strip->flag & NLASTRIP_FLAG_ACTIVE)==0) + continue; + + // TODO: when 'active' vs 'all' boolean is added, change last param! + ok += ANIM_fmodifiers_copy_to_buf(&strip->modifiers, 0); + } + } + + /* successful or not? */ + if (ok == 0) { + BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied"); + return OPERATOR_CANCELLED; + } + else + return OPERATOR_FINISHED; +} + +void NLA_OT_fmodifier_copy (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy F-Modifiers"; + ot->idname= "NLA_OT_fmodifier_copy"; + ot->description= "Copy the F-Modifier(s) of the active NLA-Strip."; + + /* api callbacks */ + ot->exec= nla_fmodifier_copy_exec; + ot->poll= nlaop_poll_tweakmode_off; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* id-props */ + //ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All F-Modifiers", "Copy all the F-Modifiers, instead of just the active one"); +} + +/* ******************** Paste F-Modifiers Operator *********************** */ + +static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter, ok=0; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* get a list of the editable tracks being shown in the NLA */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_SEL | ANIMFILTER_FOREDIT); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + /* for each NLA-Track, add the specified modifier to all selected strips */ + for (ale= anim_data.first; ale; ale= ale->next) { + NlaTrack *nlt= (NlaTrack *)ale->data; + NlaStrip *strip; + + for (strip= nlt->strips.first; strip; strip=strip->next) { + // TODO: do we want to replace existing modifiers? add user pref for that! + ok += ANIM_fmodifiers_paste_from_buf(&strip->modifiers, 0); + } + } + + /* clean up */ + BLI_freelistN(&anim_data); + + /* successful or not? */ + if (ok) { + /* set notifier that things have changed */ + /* set notifier that things have changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_EDIT, NULL); + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_ERROR, "No F-Modifiers to paste"); + return OPERATOR_CANCELLED; + } +} + +void NLA_OT_fmodifier_paste (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Paste F-Modifiers"; + ot->idname= "NLA_OT_fmodifier_paste"; + ot->description= "Add copied F-Modifiers to the selected NLA-Strips"; + + /* api callbacks */ + ot->exec= nla_fmodifier_paste_exec; + ot->poll= nlaop_poll_tweakmode_off; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /* *********************************************** */ diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h index 1af2d2a1635..18ef91220f9 100644 --- a/source/blender/editors/space_nla/nla_intern.h +++ b/source/blender/editors/space_nla/nla_intern.h @@ -111,6 +111,8 @@ void NLA_OT_clear_scale(wmOperatorType *ot); void NLA_OT_snap(wmOperatorType *ot); void NLA_OT_fmodifier_add(wmOperatorType *ot); +void NLA_OT_fmodifier_copy(wmOperatorType *ot); +void NLA_OT_fmodifier_paste(wmOperatorType *ot); /* **************************************** */ diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c index 10ff10f46fd..249256a47f9 100644 --- a/source/blender/editors/space_nla/nla_ops.c +++ b/source/blender/editors/space_nla/nla_ops.c @@ -165,6 +165,8 @@ void nla_operatortypes(void) WM_operatortype_append(NLA_OT_snap); WM_operatortype_append(NLA_OT_fmodifier_add); + WM_operatortype_append(NLA_OT_fmodifier_copy); + WM_operatortype_append(NLA_OT_fmodifier_paste); } /* ************************** registration - keymaps **********************************/ -- cgit v1.2.3