diff options
-rw-r--r-- | source/blender/editors/space_graph/graph_edit.c | 128 |
1 files changed, 98 insertions, 30 deletions
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 5011b03955b..6042100a984 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -483,57 +483,125 @@ void GRAPH_OT_ghost_curves_clear(wmOperatorType *ot) /* ******************** Insert Keyframes Operator ************************* */ -/* defines for insert keyframes tool */ +/* Mode defines for insert keyframes tool */ +typedef enum eGraphKeys_InsertKey_Types { + GRAPHKEYS_INSERTKEY_ALL = (1 << 0), + GRAPHKEYS_INSERTKEY_SEL = (1 << 1), + GRAPHKEYS_INSERTKEY_CURSOR = (1 << 2), + GRAPHKEYS_INSERTKEY_ACTIVE = (1 << 3), +} eGraphKeys_InsertKey_Types; + +/* RNA mode types for insert keyframes tool */ static EnumPropertyItem prop_graphkeys_insertkey_types[] = { - {1, "ALL", 0, "All Channels", ""}, - {2, "SEL", 0, "Only Selected Channels", ""}, + {GRAPHKEYS_INSERTKEY_ALL, "ALL", 0, "All Channels", + "Insert a keyframe on all visible and editable F-Curves using each curve's current value"}, + {GRAPHKEYS_INSERTKEY_SEL, "SEL", 0, "Only Selected Channels", + "Insert a keyframe on selected F-Curves using each curve's current value"}, + {0, "", 0, "", ""}, + {GRAPHKEYS_INSERTKEY_ACTIVE | GRAPHKEYS_INSERTKEY_CURSOR, "CURSOR_ACTIVE", 0, + "Active Channels At Cursor", "Insert a keyframe for the active F-Curve at the cursor point"}, + {GRAPHKEYS_INSERTKEY_SEL | GRAPHKEYS_INSERTKEY_CURSOR, "CURSOR_SEL", 0, + "Selected Channels At Cursor", "Insert a keyframe for selected F-Curves at the cursor point"}, {0, NULL, 0, NULL, NULL} }; /* this function is responsible for snapping keyframes to frame-times */ -static void insert_graph_keys(bAnimContext *ac, short mode) +static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; + size_t num_items; ReportList *reports = ac->reports; + SpaceIpo *sipo = (SpaceIpo *)ac->sl; Scene *scene = ac->scene; short flag = 0; /* filter data */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); - if (mode == 2) filter |= ANIMFILTER_SEL; - - ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + if (mode & GRAPHKEYS_INSERTKEY_SEL) + filter |= ANIMFILTER_SEL; + else if (mode & GRAPHKEYS_INSERTKEY_ACTIVE) + filter |= ANIMFILTER_ACTIVE; + + num_items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + if (num_items == 0) { + if (mode & GRAPHKEYS_INSERTKEY_ACTIVE) + BKE_report(reports, RPT_ERROR, "No active F-Curve to add a keyframe to. Select an editable F-Curve first"); + else if (mode & GRAPHKEYS_INSERTKEY_SEL) + BKE_report(reports, RPT_ERROR, "No selected F-Curves to add keyframes to"); + else + BKE_report(reports, RPT_ERROR, "No channels to add keyframes to"); + + return; + } /* init keyframing flag */ flag = ANIM_get_keyframing_flags(scene, 1); /* insert keyframes */ - for (ale = anim_data.first; ale; ale = ale->next) { - AnimData *adt = ANIM_nla_mapping_get(ac, ale); - FCurve *fcu = (FCurve *)ale->key_data; - float cfra; - - /* adjust current frame for NLA-mapping */ - if (adt) - cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); - else - cfra = (float)CFRA; + if (mode & GRAPHKEYS_INSERTKEY_CURSOR) { + for (ale = anim_data.first; ale; ale = ale->next) { + AnimData *adt = ANIM_nla_mapping_get(ac, ale); + FCurve *fcu = (FCurve *)ale->key_data; - /* read value from property the F-Curve represents, or from the curve only? - * - ale->id != NULL: Typically, this means that we have enough info to try resolving the path - * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone, - * so it's easier for now to just read the F-Curve directly. - * (TODO: add the full-blown PointerRNA relative parsing case here...) - */ - if (ale->id && !ale->owner) - insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag); - else - insert_vert_fcurve(fcu, cfra, fcu->curval, 0); - - ale->update |= ANIM_UPDATE_DEFAULT; + short mapping_flag = ANIM_get_normalization_flags(ac); + float offset; + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag, &offset); + + float x, y; + + + /* perform time remapping for x-coordinate (if necessary) */ + if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS)) + x = sipo->cursorTime; + else if (adt) + x = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); + else + x = (float)CFRA; + + /* normalise units of cursor's value */ + if (sipo) + y = (sipo->cursorVal / unit_scale) - offset; + else + y = 0.0f; + + /* insert keyframe directly into the F-Curve */ + insert_vert_fcurve(fcu, x, y, 0); + + ale->update |= ANIM_UPDATE_DEFAULT; + } + } + else { + for (ale = anim_data.first; ale; ale = ale->next) { + AnimData *adt = ANIM_nla_mapping_get(ac, ale); + FCurve *fcu = (FCurve *)ale->key_data; + float cfra; + + /* adjust current frame for NLA-mapping */ + if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS)) + cfra = sipo->cursorTime; + else if (adt) + cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); + else + cfra = (float)CFRA; + + /* read value from property the F-Curve represents, or from the curve only? + * - ale->id != NULL: Typically, this means that we have enough info to try resolving the path + * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone, + * so it's easier for now to just read the F-Curve directly. + * (TODO: add the full-blown PointerRNA relative parsing case here...) + * - fcu->driver != NULL: If this is set, then it's a driver. If we don't check for this, we'd end + * up adding the keyframes on a new F-Curve in the action data instead. + */ + if (ale->id && !ale->owner && !fcu->driver) + insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag); + else + insert_vert_fcurve(fcu, cfra, fcu->curval, 0); + + ale->update |= ANIM_UPDATE_DEFAULT; + } } ANIM_animdata_update(ac, &anim_data); @@ -545,7 +613,7 @@ static void insert_graph_keys(bAnimContext *ac, short mode) static int graphkeys_insertkey_exec(bContext *C, wmOperator *op) { bAnimContext ac; - short mode; + eGraphKeys_InsertKey_Types mode; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) |