diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index fe78a058d24..81845598162 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -753,8 +753,8 @@ BeztEditFunc ANIM_editkeyframes_mirror(short type) static short set_bezier_auto(BeztEditData *bed, BezTriple *bezt) { if((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) { - if (bezt->f1 & SELECT) bezt->h1= 1; /* the secret code for auto */ - if (bezt->f3 & SELECT) bezt->h2= 1; + if (bezt->f1 & SELECT) bezt->h1= HD_AUTO; /* the secret code for auto */ + if (bezt->f3 & SELECT) bezt->h2= HD_AUTO; /* if the handles are not of the same type, set them * to type free @@ -809,7 +809,7 @@ static short set_bezier_free(BeztEditData *bed, BezTriple *bezt) return 0; } -/* Set all Bezier Handles to a single type */ +/* Set all selected Bezier Handles to a single type */ // calchandles_fcurve BeztEditFunc ANIM_editkeyframes_handles(short code) { diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 72ec45845c2..bb77ad40671 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -949,6 +949,18 @@ void ACTION_OT_interpolation_type (wmOperatorType *ot) /* ******************** Set Handle-Type Operator *********************** */ +EnumPropertyItem actkeys_handle_type_items[] = { + {0, "", 0, "For Selected Handles", ""}, + {HD_FREE, "FREE", 0, "Free", ""}, + {HD_AUTO, "AUTO", 0, "Auto", ""}, + {HD_VECT, "VECTOR", 0, "Vector", ""}, + {HD_ALIGN, "ALIGNED", 0, "Aligned", ""}, + {0, "", 0, "For Selected F-Curves", ""}, + {HD_AUTO_ANIM, "ANIM_CLAMPED", 0, "Auto Clamped", "Handles stay horizontal"}, + {0, NULL, 0, NULL, NULL}}; + +/* ------------------- */ + /* this function is responsible for setting handle-type of selected keyframes */ static void sethandles_action_keys(bAnimContext *ac, short mode) { @@ -964,25 +976,36 @@ static void sethandles_action_keys(bAnimContext *ac, short mode) /* loop through setting flags for handles * 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, calchandles_fcurve); + + /* cleanup */ + BLI_freelistN(&anim_data); +} + +/* this function is responsible for toggling clamped-handles */ +static void sethandles_clamped_action_keys(bAnimContext *ac) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* filter data */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* toggle auto-handles on the F-Curves, which forces handles to stay horizontal */ for (ale= anim_data.first; ale; ale= ale->next) { - if (mode == -1) { - BeztEditFunc toggle_cb; + FCurve *fcu= ale->data; + + /* only enable if curve is selected */ + if (SEL_FCU(fcu)) + fcu->flag |= FCURVE_AUTO_HANDLES; + else + fcu->flag &= ~FCURVE_AUTO_HANDLES; - /* check which type of handle to set (free or aligned) - * - check here checks for handles with free alignment already - */ - if (ANIM_fcurve_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, NULL)) - toggle_cb= ANIM_editkeyframes_handles(HD_FREE); - else - toggle_cb= ANIM_editkeyframes_handles(HD_ALIGN); - - /* set handle-type */ - ANIM_fcurve_keys_bezier_loop(NULL, ale->key_data, NULL, toggle_cb, calchandles_fcurve); - } - else { - /* directly set handle-type */ - ANIM_fcurve_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve); - } + /* force handles to be recalculated */ + calchandles_fcurve(fcu); } /* cleanup */ @@ -1006,7 +1029,10 @@ static int actkeys_handletype_exec(bContext *C, wmOperator *op) mode= RNA_enum_get(op->ptr, "type"); /* set handle type */ - sethandles_action_keys(&ac, mode); + if (mode == HD_AUTO_ANIM) + sethandles_clamped_action_keys(&ac); + else + sethandles_action_keys(&ac, mode); /* validate keyframes after editing */ ANIM_editkeyframes_refresh(&ac); @@ -1033,7 +1059,7 @@ void ACTION_OT_handle_type (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* id-props */ - ot->prop= RNA_def_enum(ot->srna, "type", beztriple_handle_type_items, 0, "Type", ""); + ot->prop= RNA_def_enum(ot->srna, "type", actkeys_handle_type_items, 0, "Type", ""); } /* ******************** Set Keyframe-Type Operator *********************** */ diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index fe06348c8ec..5e2e56abcc5 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1361,6 +1361,18 @@ void GRAPH_OT_interpolation_type (wmOperatorType *ot) /* ******************** Set Handle-Type Operator *********************** */ +EnumPropertyItem graphkeys_handle_type_items[] = { + {0, "", 0, "For Selected Handles", ""}, + {HD_FREE, "FREE", 0, "Free", ""}, + {HD_AUTO, "AUTO", 0, "Auto", ""}, + {HD_VECT, "VECTOR", 0, "Vector", ""}, + {HD_ALIGN, "ALIGNED", 0, "Aligned", ""}, + {0, "", 0, "For Selected F-Curves", ""}, + {HD_AUTO_ANIM, "ANIM_CLAMPED", 0, "Auto Clamped", "Handles stay horizontal"}, + {0, NULL, 0, NULL, NULL}}; + +/* ------------------- */ + /* this function is responsible for setting handle-type of selected keyframes */ static void sethandles_graph_keys(bAnimContext *ac, short mode) { @@ -1370,32 +1382,42 @@ static void sethandles_graph_keys(bAnimContext *ac, short mode) BeztEditFunc set_cb= ANIM_editkeyframes_handles(mode); /* filter data */ - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* loop through setting flags for handles * Note: we do not supply BeztEditData to the looper yet. Currently that's not necessary here... */ - // XXX we might need to supply BeztEditData to get it to only affect selected handles + for (ale= anim_data.first; ale; ale= ale->next) + ANIM_fcurve_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve); + + /* cleanup */ + BLI_freelistN(&anim_data); +} + +/* this function is responsible for toggling clamped-handles */ +static void sethandles_clamped_graph_keys(bAnimContext *ac) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* filter data */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* toggle auto-handles on the F-Curves, which forces handles to stay horizontal */ for (ale= anim_data.first; ale; ale= ale->next) { - if (mode == -1) { - BeztEditFunc toggle_cb; + FCurve *fcu= ale->data; + + /* only enable if curve is selected */ + if (SEL_FCU(fcu)) + fcu->flag |= FCURVE_AUTO_HANDLES; + else + fcu->flag &= ~FCURVE_AUTO_HANDLES; - /* check which type of handle to set (free or aligned) - * - check here checks for handles with free alignment already - */ - if (ANIM_fcurve_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, NULL)) - toggle_cb= ANIM_editkeyframes_handles(HD_FREE); - else - toggle_cb= ANIM_editkeyframes_handles(HD_ALIGN); - - /* set handle-type */ - ANIM_fcurve_keys_bezier_loop(NULL, ale->key_data, NULL, toggle_cb, calchandles_fcurve); - } - else { - /* directly set handle-type */ - ANIM_fcurve_keys_bezier_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve); - } + /* force handles to be recalculated */ + calchandles_fcurve(fcu); } /* cleanup */ @@ -1417,18 +1439,21 @@ static int graphkeys_handletype_exec(bContext *C, wmOperator *op) mode= RNA_enum_get(op->ptr, "type"); /* set handle type */ - sethandles_graph_keys(&ac, mode); + if (mode == HD_AUTO_ANIM) + sethandles_clamped_graph_keys(&ac); + else + sethandles_graph_keys(&ac, mode); /* validate keyframes after editing */ ANIM_editkeyframes_refresh(&ac); - /* set notifier that things have changed */ + /* set notifier that keyframe properties have changed */ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL); return OPERATOR_FINISHED; } -void GRAPH_OT_handle_type (wmOperatorType *ot) + void GRAPH_OT_handle_type (wmOperatorType *ot) { /* identifiers */ ot->name= "Set Keyframe Handle Type"; @@ -1444,7 +1469,7 @@ void GRAPH_OT_handle_type (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* id-props */ - ot->prop= RNA_def_enum(ot->srna, "type", beztriple_handle_type_items, 0, "Type", ""); + ot->prop= RNA_def_enum(ot->srna, "type", graphkeys_handle_type_items, 0, "Type", ""); } /* ************************************************************************** */ diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index f988511b146..c08c32490c1 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -297,7 +297,7 @@ typedef enum eBezTriple_Handle { HD_AUTO, HD_VECT, HD_ALIGN, - HD_AUTO_ANIM + HD_AUTO_ANIM, /* not real handle type, but is just used as dummy item for anim code */ } eBezTriple_Handle; /* interpolation modes (used only for BezTriple->ipo) */ diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 8555e206683..e276ef354f4 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -42,7 +42,6 @@ EnumPropertyItem beztriple_handle_type_items[] = { {HD_AUTO, "AUTO", 0, "Auto", ""}, {HD_VECT, "VECTOR", 0, "Vector", ""}, {HD_ALIGN, "ALIGNED", 0, "Aligned", ""}, - {HD_AUTO_ANIM, "AUTO_CLAMPED", 0, "Auto Clamped", ""}, {0, NULL, 0, NULL, NULL}}; EnumPropertyItem beztriple_interpolation_mode_items[] = {