diff options
Diffstat (limited to 'source/blender/editors/animation/keyframing.c')
-rw-r--r-- | source/blender/editors/animation/keyframing.c | 106 |
1 files changed, 77 insertions, 29 deletions
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index fb4c0ae0758..3fb707078b8 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -162,7 +162,7 @@ bAction *ED_id_action_ensure(Main *bmain, ID *id) * so that users can't accidentally break actions by assigning them * to the wrong places */ - adt->action->idroot = GS(id->name); + BKE_animdata_action_ensure_idroot(id, adt->action); /* Tag depsgraph to be rebuilt to include time dependency. */ DEG_relations_tag_update(bmain); @@ -407,7 +407,7 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) /* are there already keyframes? */ if (fcu->bezt) { bool replace; - i = binarysearch_bezt_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace); + i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace); /* replace an existing keyframe? */ if (replace) { @@ -462,8 +462,8 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) /* no keyframes already, but can only add if... * 1) keyframing modes say that keyframes can only be replaced, so adding new ones won't know * 2) there are no samples on the curve - * // NOTE: maybe we may want to allow this later when doing samples -> bezt conversions, - * // but for now, having both is asking for trouble + * NOTE: maybe we may want to allow this later when doing samples -> bezt conversions, + * but for now, having both is asking for trouble */ else if ((flag & INSERTKEY_REPLACE) == 0 && (fcu->fpt == NULL)) { /* create new keyframes array */ @@ -483,6 +483,57 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) return i; } +/** Update the FCurve to allow insertion of `bezt` without modifying the curve shape. + * + * Checks whether it is necessary to apply Bezier subdivision due to involvement of non-auto + * handles. If necessary, changes `bezt` handles from Auto to Aligned. + * + * \param bezt: key being inserted + * \param prev: keyframe before that key + * \param next: keyframe after that key + */ +static void subdivide_nonauto_handles(const FCurve *fcu, + BezTriple *bezt, + BezTriple *prev, + BezTriple *next) +{ + if (prev->ipo != BEZT_IPO_BEZ || bezt->ipo != BEZT_IPO_BEZ) { + return; + } + + /* Don't change Vector handles, or completely auto regions. */ + const bool bezt_auto = BEZT_IS_AUTOH(bezt) || (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT); + const bool prev_auto = BEZT_IS_AUTOH(prev) || (prev->h2 == HD_VECT); + const bool next_auto = BEZT_IS_AUTOH(next) || (next->h1 == HD_VECT); + if (bezt_auto && prev_auto && next_auto) { + return; + } + + /* Subdivide the curve. */ + float delta; + if (!BKE_fcurve_bezt_subdivide_handles(bezt, prev, next, &delta)) { + return; + } + + /* Decide when to force auto to manual. */ + if (!BEZT_IS_AUTOH(bezt)) { + return; + } + if ((prev_auto || next_auto) && fcu->auto_smoothing == FCURVE_SMOOTH_CONT_ACCEL) { + const float hx = bezt->vec[1][0] - bezt->vec[0][0]; + const float dx = bezt->vec[1][0] - prev->vec[1][0]; + + /* This mode always uses 1/3 of key distance for handle x size. */ + const bool auto_works_well = fabsf(hx - dx / 3.0f) < 0.001f; + if (auto_works_well) { + return; + } + } + + /* Turn off auto mode. */ + bezt->h1 = bezt->h2 = HD_ALIGN; +} + /** * This function is a wrapper for #insert_bezt_fcurve(), and should be used when * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere else yet. @@ -554,6 +605,7 @@ int insert_vert_fcurve( /* add temp beztriple to keyframes */ a = insert_bezt_fcurve(fcu, &beztr, flag); + BKE_fcurve_active_keyframe_set(fcu, &fcu->bezt[a]); /* what if 'a' is a negative index? * for now, just exit to prevent any segfaults @@ -562,14 +614,6 @@ int insert_vert_fcurve( return -1; } - /* don't recalculate handles if fast is set - * - this is a hack to make importers faster - * - we may calculate twice (due to autohandle needing to be calculated twice) - */ - if ((flag & INSERTKEY_FAST) == 0) { - calchandles_fcurve(fcu); - } - /* set handletype and interpolation */ if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE) == 0) { BezTriple *bezt = (fcu->bezt + a); @@ -586,17 +630,21 @@ int insert_vert_fcurve( else if (a < fcu->totvert - 1) { bezt->ipo = (bezt + 1)->ipo; } - } - /* don't recalculate handles if fast is set - * - this is a hack to make importers faster - * - we may calculate twice (due to autohandle needing to be calculated twice) - */ - if ((flag & INSERTKEY_FAST) == 0) { - calchandles_fcurve(fcu); + if (0 < a && a < (fcu->totvert - 1) && (flag & INSERTKEY_OVERWRITE_FULL) == 0) { + subdivide_nonauto_handles(fcu, bezt, bezt - 1, bezt + 1); + } } } + /* don't recalculate handles if fast is set + * - this is a hack to make importers faster + * - we may calculate twice (due to autohandle needing to be calculated twice) + */ + if ((flag & INSERTKEY_FAST) == 0) { + calchandles_fcurve(fcu); + } + /* return the index at which the keyframe was added */ return a; } @@ -1557,7 +1605,7 @@ static bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra) int i; /* try to find index of beztriple to get rid of */ - i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found); + i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, cfra, fcu->totvert, &found); if (found) { /* delete the key at the index (will sanity check + do recalc afterwards) */ delete_fcurve_key(fcu, i, 1); @@ -1826,7 +1874,7 @@ static int insert_key_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); bool ob_edit_mode = false; - float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap + float cfra = (float)CFRA; /* XXX for now, don't bother about all the yucky offset crap */ int num_channels; KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene); @@ -2009,7 +2057,7 @@ void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot) /* confirm whether a keyframe was added by showing a popup * - by default, this is disabled so that if a menu is shown, this doesn't come up too */ - // XXX should this just be always on? + /* XXX should this just be always on? */ prop = RNA_def_boolean(ot->srna, "confirm_success", 0, @@ -2030,7 +2078,7 @@ void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot) static int delete_key_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap + float cfra = (float)CFRA; /* XXX for now, don't bother about all the yucky offset crap */ int num_channels; KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene); @@ -2560,7 +2608,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op) PropertyRNA *prop = NULL; Main *bmain = CTX_data_main(C); char *path; - float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap + float cfra = (float)CFRA; /* XXX for now, don't bother about all the yucky offset crap */ bool changed = false; int index; const bool all = RNA_boolean_get(op->ptr, "all"); @@ -2600,7 +2648,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op) int i; /* try to find index of beztriple to get rid of */ - i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found); + i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, cfra, fcu->totvert, &found); if (found) { /* delete the key at the index (will sanity check + do recalc afterwards) */ delete_fcurve_key(fcu, i, 1); @@ -2732,7 +2780,7 @@ void ANIM_OT_keyframe_clear_button(wmOperatorType *ot) bool autokeyframe_cfra_can_key(const Scene *scene, ID *id) { - float cfra = (float)CFRA; // XXX for now, this will do + float cfra = (float)CFRA; /* XXX for now, this will do */ /* only filter if auto-key mode requires this */ if (IS_AUTOKEY_ON(scene) == 0) { @@ -2774,9 +2822,9 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter) /* we either include all regardless of muting, or only non-muted */ if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED) == 0) { bool replace; - int i = binarysearch_bezt_index(fcu->bezt, frame, fcu->totvert, &replace); + int i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, frame, fcu->totvert, &replace); - /* binarysearch_bezt_index will set replace to be 0 or 1 + /* BKE_fcurve_bezt_binarysearch_index will set replace to be 0 or 1 * - obviously, 1 represents a match */ if (replace) { @@ -2932,7 +2980,7 @@ bool id_frame_has_keyframe(ID *id, float frame, short filter) case ID_OB: /* object */ return object_frame_has_keyframe((Object *)id, frame, filter); #if 0 - // XXX TODO... for now, just use 'normal' behavior + /* XXX TODO... for now, just use 'normal' behavior */ case ID_SCE: /* scene */ break; #endif |