Commit: 1fbd74296df79fff2b4fd3234ea20b0ade51b0f9
Author: Joshua Leung
Date:   Tue Dec 15 04:03:25 2015 +1300
Branches: master
https://developer.blender.org/rB1fbd74296df79fff2b4fd3234ea20b0ade51b0f9

Graph Editor: "Add at Cursor" options for Insert Key operator in Graph Editor

* Added the ability to add a keyframe at the current cursor location in the
  Graph Editor. This is useful for precisely defining the shape of driver 
F-Curves.

* Fixed a bug where the wrong cursor-x time was being used in Drivers mode
  (i.e. it was still using time, and not just any time-value, but the 
NLA-mapped time!)

===================================================================

M       source/blender/editors/space_graph/graph_edit.c

===================================================================

diff --git a/source/blender/editors/space_graph/graph_edit.c 
b/source/blender/editors/space_graph/graph_edit.c
index 5011b03..6042100 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)

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to