diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 2107e6e4252..abea38e129e 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -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; diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 77826eca87a..ac04dc7d1a8 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -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 */ diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 179f362b13f..af37cd87254 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -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 diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index e940aaed36e..259104f7263 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -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 ****************************** */ diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 77e95dc77de..390729eaec4 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -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) ---------- */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index d4709e94e5e..b087736a368 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -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 */ diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index e2a725164c9..f18d31915f9 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -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); diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h index 1aeeeff0c80..e5f0ab8994e 100644 --- a/source/blender/editors/space_action/action_intern.h +++ b/source/blender/editors/space_action/action_intern.h @@ -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); diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index f18b6197eb3..42b033040b1 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -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); diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c index 06d48fe20f3..dd304cd8cf3 100644 --- a/source/blender/editors/space_graph/graph_header.c +++ b/source/blender/editors/space_graph/graph_header.c @@ -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); } diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index facea34510e..bbf1358a37c 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -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); diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index f30954292b4..b21f37ab678 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -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); diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index b0f089d670f..3bac2c73bcb 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -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 */ diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 3bba474677f..a59fc8716ec 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -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[]; diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index bb094eef962..503ca031fb6 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -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);