2.5 - Keyframe Types for DopeSheet
authorJoshua Leung <aligorith@gmail.com>
Fri, 4 Sep 2009 02:44:56 +0000 (02:44 +0000)
committerJoshua Leung <aligorith@gmail.com>
Fri, 4 Sep 2009 02:44:56 +0000 (02:44 +0000)
It is now possible to tag certain keyframes as being 'breakdowns' in the DopeSheet. Breakdown keyframes are drawn as slightly smaller blue diamonds.

Simply select the relevant keyframes and use the RKEY hotkey (or from the menus, Key->Keyframe Type) to choose between tagging the keyframe as a 'proper' keyframe and a 'breakdown' keyframe.

Notes:
* Please note that this feature does not currently imply anything about breakdowns moving around keyframes or behaving any differently from any other type of keyframe
* In future, if there is any such need, more keyframe types could be added, though this is not really likely at all

15 files changed:
source/blender/editors/animation/keyframes_draw.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_keyframes_draw.h
source/blender/editors/include/ED_keyframes_edit.h
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_action/action_header.c
source/blender/editors/space_action/action_intern.h
source/blender/editors/space_action/action_ops.c
source/blender/editors/space_graph/graph_header.c
source/blender/editors/space_nla/nla_buttons.c
source/blender/editors/space_nla/nla_draw.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_curve.c

index 2107e6e425219d35d77559ce542b1d248ffe900f..abea38e129ee34d5f3b1a362ea18585d37a6c18d 100644 (file)
@@ -98,9 +98,7 @@ static ActKeyColumn *bezt_to_new_actkeycolumn(BezTriple *bezt)
        /* store settings based on state of BezTriple */
        ak->cfra= bezt->vec[1][0];
        ak->sel= BEZSELECTED(bezt) ? SELECT : 0;
-       
-       // TODO: handle type = bezt->h1 or bezt->h2
-       ak->handle_type= 0; 
+       ak->key_type= BEZKEYTYPE(bezt); 
        
        /* set 'modified', since this is used to identify long keyframes */
        ak->modified = 1;
@@ -134,6 +132,10 @@ static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTriple *bezt)
                                if (BEZSELECTED(bezt)) ak->sel = SELECT;
                                ak->modified += 1;
                                
+                               /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
+                               if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME)
+                                       ak->key_type= BEZT_KEYTYPE_KEYFRAME;
+                               
                                /* done... no need to insert */
                                return;
                        }
@@ -340,7 +342,7 @@ static const float _unit_diamond_shape[4][2] = {
 }; 
 
 /* draw a simple diamond shape with OpenGL */
-void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short mode)
+void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode)
 {
        static GLuint displist1=0;
        static GLuint displist2=0;
@@ -371,6 +373,11 @@ void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel
                glEndList();
        }
        
+       /* tweak size of keyframe shape according to type of keyframe 
+        *      - 'proper' keyframes have key_type=0, so get drawn at full size
+        */
+       hsize -= 0.5f*key_type;
+       
        /* adjust view transform before starting */
        glTranslatef(x, y, 0.0f);
        glScalef(1.0f/xscale*hsize, hsize, 1.0f);
@@ -381,8 +388,22 @@ void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel
        /* draw! */
        if ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH) {
                /* interior - hardcoded colors (for selected and unselected only) */
-               if (sel) UI_ThemeColorShade(TH_STRIP_SELECT, 50);
-               else glColor3ub(0xE9, 0xE9, 0xE9);
+               switch (key_type) {
+                       case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames for now */
+                       {
+                               if (sel) glColor3f(0.33f, 0.75f, 0.93f);
+                               else glColor3f(0.70f, 0.86f, 0.91f);
+                       }
+                               break;
+                               
+                       case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames for now */
+                       default:
+                       {
+                               if (sel) UI_ThemeColorShade(TH_STRIP_SELECT, 50);
+                               else glColor3f(0.91f, 0.91f, 0.91f);
+                       }
+                               break;
+               }
                
                glCallList(displist2);
        }
@@ -454,7 +475,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
                        /* draw using OpenGL - uglier but faster */
                        // NOTE1: a previous version of this didn't work nice for some intel cards
                        // NOTE2: if we wanted to go back to icons, these are  icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3;
-                       draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), KEYFRAME_SHAPE_BOTH);
+                       draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH);
                }       
        }
        
@@ -695,7 +716,7 @@ void gpl_to_keylist(bDopeSheet *ads, bGPDlayer *gpl, DLRBT_Tree *keys, DLRBT_Tre
                        
                        ak->cfra= (float)gpf->framenum;
                        ak->modified = 1;
-                       ak->handle_type= 0; 
+                       ak->key_type= 0; 
                        
                        if (gpf->flag & GP_FRAME_SELECT)
                                ak->sel = SELECT;
index 77826eca87a7ba326e434935c112d6ad0d2c86d9..ac04dc7d1a8ece09b75b602a7d01016dc7046f40 100644 (file)
@@ -655,7 +655,7 @@ static short set_bezt_bezier(BeztEditData *bed, BezTriple *bezt)
        return 0;
 }
 
-/* Set the interpolation type of the selected BezTriples in each IPO curve to the specified one */
+/* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */
 // ANIM_editkeyframes_ipocurve_ipotype() !
 BeztEditFunc ANIM_editkeyframes_ipo(short code)
 {
@@ -669,6 +669,35 @@ BeztEditFunc ANIM_editkeyframes_ipo(short code)
        }
 }
 
+/* ------- */
+
+static short set_keytype_keyframe(BeztEditData *bed, BezTriple *bezt) 
+{
+       if (bezt->f2 & SELECT) 
+               BEZKEYTYPE(bezt)= BEZT_KEYTYPE_KEYFRAME;
+       return 0;
+}
+
+static short set_keytype_breakdown(BeztEditData *bed, BezTriple *bezt) 
+{
+       if (bezt->f2 & SELECT) 
+               BEZKEYTYPE(bezt)= BEZT_KEYTYPE_BREAKDOWN;
+       return 0;
+}
+
+/* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */
+BeztEditFunc ANIM_editkeyframes_keytype(short code)
+{
+       switch (code) {
+               case BEZT_KEYTYPE_BREAKDOWN: /* breakdown */
+                       return set_keytype_breakdown;
+                       
+               case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */       
+               default:
+                       return set_keytype_keyframe;
+       }
+}
+
 /* ******************************************* */
 /* Selection */
 
index 179f362b13f6c9f4379921c4e2255ce10f69f084..af37cd8725467d3c2f235a1852aba6c499b231b1 100644 (file)
@@ -434,7 +434,12 @@ void ED_nla_postop_refresh(bAnimContext *ac);
 /* ------------- Utility macros ----------------------- */
 
 /* checks if the given BezTriple is selected */
-#define BEZSELECTED(bezt) ((bezt->f2 & SELECT) || (bezt->f1 & SELECT) || (bezt->f3 & SELECT))
+#define BEZSELECTED(bezt) (((bezt)->f2 & SELECT) || ((bezt)->f1 & SELECT) || ((bezt)->f3 & SELECT))
+
+/* provide access to Keyframe Type info in BezTriple
+ * NOTE: this is so that we can change it from being stored in 'hide'
+ */
+#define BEZKEYTYPE(bezt) ((bezt)->hide)
 
 /* set/clear/toggle macro 
  *     - channel - channel with a 'flag' member that we're setting
index e940aaed36e193ddda995a1a1f975cd300b67d2c..259104f7263c83879a2922ad0a403c087b5f4ef5 100644 (file)
@@ -56,8 +56,8 @@ typedef struct ActKeyColumn {
        char tree_col;                                          /* DLRB_BLACK or DLRB_RED */
        
                /* keyframe info */
-       char sel;
-       short handle_type;
+       char key_type;                                          /* eBezTripe_KeyframeType */
+       short sel;
        float cfra;
        
        /* only while drawing - used to determine if long-keyframe needs to be drawn */
@@ -99,7 +99,7 @@ typedef enum eKeyframeShapeDrawOpts {
 } eKeyframeShapeDrawOpts;
 
 /* draw simple diamond-shape keyframe (with OpenGL) */
-void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short mode);
+void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode);
 
 /* ******************************* Methods ****************************** */
 
index 77e95dc77de788af2f924eb2b518d6e2231a36c6..390729eaec43c39528a655b48d61be4d85788704 100644 (file)
@@ -40,8 +40,6 @@ struct Scene;
 
 /* --------- BezTriple Selection ------------- */
 
-#define BEZSELECTED(bezt) ((bezt->f2 & SELECT) || (bezt->f1 & SELECT) || (bezt->f3 & SELECT))
-
 #define BEZ_SEL(bezt)          { (bezt)->f1 |=  SELECT; (bezt)->f2 |=  SELECT; (bezt)->f3 |=  SELECT; }
 #define BEZ_DESEL(bezt)                { (bezt)->f1 &= ~SELECT; (bezt)->f2 &= ~SELECT; (bezt)->f3 &= ~SELECT; }
 #define BEZ_INVSEL(bezt)       { (bezt)->f1 ^=  SELECT; (bezt)->f2 ^=  SELECT; (bezt)->f3 ^=  SELECT; }
@@ -133,6 +131,7 @@ BeztEditFunc ANIM_editkeyframes_mirror(short mode);
 BeztEditFunc ANIM_editkeyframes_select(short mode);
 BeztEditFunc ANIM_editkeyframes_handles(short mode);
 BeztEditFunc ANIM_editkeyframes_ipo(short mode);
+BeztEditFunc ANIM_editkeyframes_keytype(short mode);
 
 /* ----------- BezTriple Callback (Assorted Utilities) ---------- */
 
index d4709e94e5e111b2994cf73515f4c77ea9b2cd09..b087736a368505b08a8d3031c4dfa451f6f5d0c5 100644 (file)
@@ -1038,6 +1038,77 @@ void ACT_OT_handle_type (wmOperatorType *ot)
        RNA_def_enum(ot->srna, "type", beztriple_handle_type_items, 0, "Type", "");
 }
 
+/* ******************** Set Keyframe-Type Operator *********************** */
+
+/* this function is responsible for setting interpolation mode for keyframes */
+static void setkeytype_action_keys(bAnimContext *ac, short mode) 
+{
+       ListBase anim_data = {NULL, NULL};
+       bAnimListElem *ale;
+       int filter;
+       BeztEditFunc set_cb= ANIM_editkeyframes_keytype(mode);
+       
+       /* filter data */
+       filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+       ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+       
+       /* loop through setting BezTriple interpolation
+        * 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)
+               ANIM_fcurve_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, NULL);
+       
+       /* cleanup */
+       BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int actkeys_keytype_exec(bContext *C, wmOperator *op)
+{
+       bAnimContext ac;
+       short mode;
+       
+       /* get editor data */
+       if (ANIM_animdata_get_context(C, &ac) == 0)
+               return OPERATOR_CANCELLED;
+       if (ac.datatype == ANIMCONT_GPENCIL) 
+               return OPERATOR_PASS_THROUGH;
+               
+       /* get handle setting mode */
+       mode= RNA_enum_get(op->ptr, "type");
+       
+       /* set handle type */
+       setkeytype_action_keys(&ac, mode);
+       
+       /* validate keyframes after editing */
+       ANIM_editkeyframes_refresh(&ac);
+       
+       /* set notifier that keyframe properties have changed */
+       WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+       
+       return OPERATOR_FINISHED;
+}
+void ACT_OT_keyframe_type (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Set Keyframe Type";
+       ot->idname= "ACT_OT_keyframe_type";
+       ot->description= "Set type of keyframe for the seleced keyframes.";
+       
+       /* api callbacks */
+       ot->invoke= WM_menu_invoke;
+       ot->exec= actkeys_keytype_exec;
+       ot->poll= ED_operator_action_active;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       /* id-props */
+       RNA_def_enum(ot->srna, "type", beztriple_keyframe_type_items, 0, "Type", "");
+}
+
 /* ************************************************************************** */
 /* TRANSFORM STUFF */
 
index e2a725164c985127646459710781248c38abd9aa..f18d31915f9247130e5082c5131b694033f2e72f 100644 (file)
@@ -168,7 +168,7 @@ static void act_edit_transformmenu(bContext *C, uiLayout *layout, void *arg_unus
 
 static void act_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); 
        uiItemEnumO(layout, NULL, 0, "ACT_OT_snap", "type", ACTKEYS_SNAP_CFRA);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_snap", "type", ACTKEYS_SNAP_NEAREST_FRAME);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_snap", "type", ACTKEYS_SNAP_NEAREST_SECOND);
@@ -177,16 +177,23 @@ static void act_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused)
 
 static void act_edit_mirrormenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_mirror", "type", ACTKEYS_MIRROR_CFRA);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_mirror", "type", ACTKEYS_MIRROR_YAXIS);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_mirror", "type", ACTKEYS_MIRROR_XAXIS);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_mirror", "type", ACTKEYS_MIRROR_MARKER);
 }
 
+static void act_edit_keytypesmenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
+       uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_KEYFRAME);
+       uiItemEnumO(layout, NULL, 0, "ACT_OT_keyframe_type", "type", BEZT_KEYTYPE_BREAKDOWN);
+}
+
 static void act_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_handle_type", "type", HD_FREE);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_handle_type", "type", HD_AUTO);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_handle_type", "type", HD_VECT);
@@ -196,7 +203,7 @@ static void act_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unused
 
 static void act_edit_ipomenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_interpolation_type", "type", BEZT_IPO_CONST);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_interpolation_type", "type", BEZT_IPO_LIN);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_interpolation_type", "type", BEZT_IPO_BEZ);
@@ -204,7 +211,7 @@ static void act_edit_ipomenu(bContext *C, uiLayout *layout, void *arg_unused)
 
 static void act_edit_expomenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_CONSTANT);
        uiItemEnumO(layout, NULL, 0, "ACT_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_LINEAR);
 }
@@ -226,6 +233,7 @@ static void act_editmenu(bContext *C, uiLayout *layout, void *arg_unused)
        
        uiItemS(layout);
        
+       uiItemMenuF(layout, "Keyframe Type", 0, act_edit_keytypesmenu, NULL);
        uiItemMenuF(layout, "Handle Type", 0, act_edit_handlesmenu, NULL);
        uiItemMenuF(layout, "Interpolation Mode", 0, act_edit_ipomenu, NULL);
        uiItemMenuF(layout, "Extrapolation Mode", 0, act_edit_expomenu, NULL);
index 1aeeeff0c80ff31f7609e13071f7deb535aefe77..e5f0ab8994e4893b72b2f32485a2f5c85350a59e 100644 (file)
@@ -89,6 +89,7 @@ void ACT_OT_delete(struct wmOperatorType *ot);
 void ACT_OT_clean(struct wmOperatorType *ot);
 void ACT_OT_sample(struct wmOperatorType *ot);
 
+void ACT_OT_keyframe_type(struct wmOperatorType *ot);
 void ACT_OT_handle_type(struct wmOperatorType *ot);
 void ACT_OT_interpolation_type(struct wmOperatorType *ot);
 void ACT_OT_extrapolation_type(struct wmOperatorType *ot);
index f18b6197eb39f689583444a896806331ee8f4785..42b033040b1f5b07db7b767aace693c9f5f7c8ed 100644 (file)
@@ -75,6 +75,7 @@ void action_operatortypes(void)
        WM_operatortype_append(ACT_OT_handle_type);
        WM_operatortype_append(ACT_OT_interpolation_type);
        WM_operatortype_append(ACT_OT_extrapolation_type);
+       WM_operatortype_append(ACT_OT_keyframe_type);
        WM_operatortype_append(ACT_OT_sample);
        WM_operatortype_append(ACT_OT_clean);
        WM_operatortype_append(ACT_OT_delete);
@@ -133,6 +134,7 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
        WM_keymap_add_item(keymap, "ACT_OT_handle_type", HKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "ACT_OT_interpolation_type", TKEY, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "ACT_OT_extrapolation_type", EKEY, KM_PRESS, KM_SHIFT, 0); 
+       WM_keymap_add_item(keymap, "ACT_OT_keyframe_type", RKEY, KM_PRESS, 0, 0); 
        
                /* destructive */
        WM_keymap_add_item(keymap, "ACT_OT_clean", OKEY, KM_PRESS, 0, 0);
index 06d48fe20f3e288b99b67b0df6c189f85f577469..dd304cd8cf3d79761f9b48812bc0bc280e15cb69 100644 (file)
@@ -160,7 +160,7 @@ static void graph_edit_transformmenu(bContext *C, uiLayout *layout, void *arg_un
 
 static void graph_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_CFRA);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_FRAME);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_SECOND);
@@ -169,7 +169,7 @@ static void graph_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused)
 
 static void graph_edit_mirrormenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_CFRA);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_YAXIS);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_XAXIS);
@@ -178,7 +178,7 @@ static void graph_edit_mirrormenu(bContext *C, uiLayout *layout, void *arg_unuse
 
 static void graph_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_FREE);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_AUTO);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_VECT);
@@ -188,7 +188,7 @@ static void graph_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unus
 
 static void graph_edit_ipomenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_interpolation_type", "type", BEZT_IPO_CONST);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_interpolation_type", "type", BEZT_IPO_LIN);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_interpolation_type", "type", BEZT_IPO_BEZ);
@@ -196,7 +196,7 @@ static void graph_edit_ipomenu(bContext *C, uiLayout *layout, void *arg_unused)
 
 static void graph_edit_expomenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); // xxx?
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_CONSTANT);
        uiItemEnumO(layout, NULL, 0, "GRAPH_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_LINEAR);
 }
index facea34510e6952a15ac038ebdcf4955c73e0701..bbf1358a37ccf10f5bb97ef33e6898870f0a3e31 100644 (file)
@@ -211,7 +211,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa)
        /* Active Action Properties ------------------------------------- */
        /* action */
        row= uiLayoutRow(layout, 1);
-               uiTemplateID(row, C, &adt_ptr, "action", NULL, NULL/*"ACT_OT_new", "ACT_OT_unlink"*/); // XXX: need to make these operators
+               uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL, NULL/*"ACT_OT_new", "ACT_OT_unlink"*/); // XXX: need to make these operators
        
        /* extrapolation */
        row= uiLayoutRow(layout, 1);
index f30954292b471c8f3c9bb64b25415964dcbaf472..b21f37ab678d4e6873bf0f8a4cfa7026292e91e2 100644 (file)
@@ -167,7 +167,7 @@ static void nla_action_draw_keyframes (AnimData *adt, bAction *act, View2D *v2d,
         *      - size is 3.0f which is smaller than the editable keyframes, so that there is a distinction
         */
        for (ak= keys.first; ak; ak= ak->next)
-               draw_keyframe_shape(ak->cfra, y, xscale, 3.0f, 0, KEYFRAME_SHAPE_FRAME);
+               draw_keyframe_shape(ak->cfra, y, xscale, 3.0f, 0, ak->key_type, KEYFRAME_SHAPE_FRAME);
        
        /* free icons */
        BLI_dlrbTree_free(&keys);
index b0f089d670f1ec621837f04e5c7a5911c09972d4..3bac2c73bcb28a2dee56bd7049467e009bc7814a 100644 (file)
@@ -75,25 +75,28 @@ typedef struct BevPoint {
        short f1, f2;
 } BevPoint;
 
-/* Keyframes on IPO curves and Points on Bezier Curves/Paths are generally BezTriples */
+/* Keyframes on F-Curves (allows code reuse of Bezier eval code) and 
+ * Points on Bezier Curves/Paths are generally BezTriples 
+ */
 /* note: alfa location in struct is abused by Key system */
 /* vec in BezTriple looks like this:
        vec[0][0]=x location of handle 1
        vec[0][1]=y location of handle 1
-       vec[0][2]=z location of handle 1 (not used for IpoCurve Points(2d))
+       vec[0][2]=z location of handle 1 (not used for FCurve Points(2d))
        vec[1][0]=x location of control point
        vec[1][1]=y location of control point
        vec[1][2]=z location of control point
        vec[2][0]=x location of handle 2
        vec[2][1]=y location of handle 2
-       vec[2][2]=z location of handle 2 (not used for IpoCurve Points(2d))
+       vec[2][2]=z location of handle 2 (not used for FCurve Points(2d))
 */
 typedef struct BezTriple {
        float vec[3][3];
        float alfa, weight, radius;     /* alfa: tilt in 3D View, weight: used for softbody goal weight, radius: for bevel tapering */
        short ipo;                                      /* ipo: interpolation mode for segment from this BezTriple to the next */
        char h1, h2;                            /* h1, h2: the handle type of the two handles */
-       char f1, f2, f3, hide;          /* f1, f2, f3: used for selection status,  hide: used to indicate whether BezTriple is hidden */
+       char f1, f2, f3;                        /* f1, f2, f3: used for selection status */
+       char hide;                                      /* hide: used to indicate whether BezTriple is hidden (3D), type of keyframe (eBezTriple_KeyframeTypes) */
 } BezTriple;
 
 /* note; alfa location in struct is abused by Key system */
@@ -279,6 +282,12 @@ typedef enum eBezTriple_Interpolation {
        BEZT_IPO_BEZ,           /* bezier interpolation */
 } eBezTriple_Interpolation;
 
+/* types of keyframe (used only for BezTriple->hide when BezTriple is used in F-Curves) */
+typedef enum eBezTriple_KeyframeType {
+       BEZT_KEYTYPE_KEYFRAME = 0,      /* default - 'proper' Keyframe */
+       BEZT_KEYTYPE_BREAKDOWN,         /* 'breakdown' keyframe */
+} eBezTriple_KeyframeType;
+
 /* *************** CHARINFO **************** */
 
 /* flag */
index 3bba474677f8541a582436cfe7807b9dfdbf63b3..a59fc8716ec3c4d7fe98cdb93354f7bea8770501 100644 (file)
@@ -38,6 +38,7 @@ extern EnumPropertyItem modifier_type_items[];
 extern EnumPropertyItem constraint_type_items[];
 extern EnumPropertyItem boidrule_type_items[];
 
+extern EnumPropertyItem beztriple_keyframe_type_items[];
 extern EnumPropertyItem beztriple_handle_type_items[];
 extern EnumPropertyItem beztriple_interpolation_mode_items[];
 
index bb094eef96261740e1eef43d71972fd572f42d66..503ca031fb6972608eb7918720f4aa8e41265034 100644 (file)
@@ -48,6 +48,11 @@ EnumPropertyItem beztriple_interpolation_mode_items[] = {
                {BEZT_IPO_LIN, "LINEAR", 0, "Linear", ""},
                {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""},
                {0, NULL, 0, NULL, NULL}};
+               
+EnumPropertyItem beztriple_keyframe_type_items[] = {
+               {BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", 0, "Keyframe", ""},
+               {BEZT_KEYTYPE_BREAKDOWN, "BREAKDOWN", 0, "Breakdown", ""},
+               {0, NULL, 0, NULL, NULL}};
 
 #ifdef RNA_RUNTIME
 
@@ -155,7 +160,10 @@ static void rna_Curve_update_data(bContext *C, PointerRNA *ptr)
        Scene *scene= CTX_data_scene(C);
        Curve *cu= ptr->id.data;
        Object *ob;
-
+       
+       if (cu == NULL)
+               return;
+       
        for(ob=bmain->object.first; ob; ob= ob->id.next) {
                if(ob->data == cu) {
                        /* XXX this will loop over all objects again (slow) */
@@ -259,10 +267,15 @@ static void rna_def_beztriple(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "ipo");
-       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_enum_items(prop, beztriple_interpolation_mode_items);
        RNA_def_property_ui_text(prop, "Interpolation", "(For F-Curves Only) Interpolation to use for segment of curve starting from current BezTriple.");
-       RNA_def_property_update(prop, 0, "rna_Curve_update_data");
+       //RNA_def_property_update(prop, 0, "rna_Curve_update_data"); // this should be an F-Curve update call instead...
+       
+       prop= RNA_def_property(srna, "keyframe_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "hide");
+       RNA_def_property_enum_items(prop, beztriple_keyframe_type_items);
+       RNA_def_property_ui_text(prop, "Keyframe Type", "(For F-Curves only) The type of keyframe this control point defines.");
+       //RNA_def_property_update(prop, 0, "rna_Curve_update_data"); // this should be an F-Curve update call instead...
 
        /* Vector values */
        prop= RNA_def_property(srna, "handle1", PROP_FLOAT, PROP_TRANSLATION);