Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/animation/keyframes_general.c
| Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| * There are also a few tools here which cannot be easily coded for in the other system (yet). | * There are also a few tools here which cannot be easily coded for in the other system (yet). | ||||
| * These may also be moved around at some point, but for now, they are best added here. | * These may also be moved around at some point, but for now, they are best added here. | ||||
| * | * | ||||
| * - Joshua Leung, Dec 2008 | * - Joshua Leung, Dec 2008 | ||||
| */ | */ | ||||
| /* **************************************************** */ | /* **************************************************** */ | ||||
| void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc) | |||||
| { | |||||
| /* sanity check */ | |||||
| if (fcu == NULL) { | |||||
| return; | |||||
| } | |||||
| /* verify the index: | |||||
| * 1) cannot be greater than the number of available keyframes | |||||
| * 2) negative indices are for specifying a value from the end of the array | |||||
| */ | |||||
| if (abs(index) >= fcu->totvert) { | |||||
| return; | |||||
| } | |||||
| if (index < 0) { | |||||
| index += fcu->totvert; | |||||
| } | |||||
| /* Delete this keyframe */ | |||||
| memmove( | |||||
| &fcu->bezt[index], &fcu->bezt[index + 1], sizeof(BezTriple) * (fcu->totvert - index - 1)); | |||||
| fcu->totvert--; | |||||
| if (fcu->totvert == 0) { | |||||
| MEM_SAFE_FREE(fcu->bezt); | |||||
| } | |||||
| /* recalc handles - only if it won't cause problems */ | |||||
| if (do_recalc) { | |||||
| calchandles_fcurve(fcu); | |||||
| } | |||||
| } | |||||
| bool delete_fcurve_keys(FCurve *fcu) | |||||
| { | |||||
| bool changed = false; | |||||
| if (fcu->bezt == NULL) { /* ignore baked curves */ | |||||
| return false; | |||||
| } | |||||
| /* Delete selected BezTriples */ | |||||
| for (int i = 0; i < fcu->totvert; i++) { | |||||
| if (fcu->bezt[i].f2 & SELECT) { | |||||
| if (i == fcu->active_keyframe_index) { | |||||
| BKE_fcurve_active_keyframe_set(fcu, NULL); | |||||
| } | |||||
| memmove(&fcu->bezt[i], &fcu->bezt[i + 1], sizeof(BezTriple) * (fcu->totvert - i - 1)); | |||||
| fcu->totvert--; | |||||
| i--; | |||||
| changed = true; | |||||
| } | |||||
| } | |||||
| /* Free the array of BezTriples if there are not keyframes */ | |||||
| if (fcu->totvert == 0) { | |||||
| clear_fcurve_keys(fcu); | |||||
| } | |||||
| return changed; | |||||
| } | |||||
| void clear_fcurve_keys(FCurve *fcu) | |||||
| { | |||||
| MEM_SAFE_FREE(fcu->bezt); | |||||
| fcu->totvert = 0; | |||||
| } | |||||
| /* ---------------- */ | |||||
| bool duplicate_fcurve_keys(FCurve *fcu) | bool duplicate_fcurve_keys(FCurve *fcu) | ||||
| { | { | ||||
| bool changed = false; | bool changed = false; | ||||
| /* this can only work when there is an F-Curve, and also when there are some BezTriples */ | /* this can only work when there is an F-Curve, and also when there are some BezTriples */ | ||||
| if (ELEM(NULL, fcu, fcu->bezt)) { | if (ELEM(NULL, fcu, fcu->bezt)) { | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | if (cleardefault && fcu->totvert == 1) { | ||||
| /* get property to read from, and get value as appropriate */ | /* get property to read from, and get value as appropriate */ | ||||
| if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) { | if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) { | ||||
| if (RNA_property_type(prop) == PROP_FLOAT) { | if (RNA_property_type(prop) == PROP_FLOAT) { | ||||
| default_value = RNA_property_float_get_default_index(&ptr, prop, fcu->array_index); | default_value = RNA_property_float_get_default_index(&ptr, prop, fcu->array_index); | ||||
| } | } | ||||
| } | } | ||||
| if (fcu->bezt->vec[1][1] == default_value) { | if (fcu->bezt->vec[1][1] == default_value) { | ||||
| clear_fcurve_keys(fcu); | BKE_fcurve_delete_keys_all(fcu); | ||||
| /* check if curve is really unused and if it is, return signal for deletion */ | /* check if curve is really unused and if it is, return signal for deletion */ | ||||
| if (BKE_fcurve_is_empty(fcu)) { | if (BKE_fcurve_is_empty(fcu)) { | ||||
| AnimData *adt = ale->adt; | AnimData *adt = ale->adt; | ||||
| ANIM_fcurve_delete_from_animdata(ac, adt, fcu); | ANIM_fcurve_delete_from_animdata(ac, adt, fcu); | ||||
| ale->key_data = NULL; | ale->key_data = NULL; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 380 Lines • ▼ Show 20 Lines | for (int i = 0; i < totSel; i++, tsb++) { | ||||
| } | } | ||||
| } | } | ||||
| /* free memory required for tarray */ | /* free memory required for tarray */ | ||||
| MEM_freeN(tarray); | MEM_freeN(tarray); | ||||
| } | } | ||||
| /* recalculate handles */ | /* recalculate handles */ | ||||
| calchandles_fcurve(fcu); | BKE_fcurve_handles_recalc(fcu); | ||||
| } | } | ||||
| /* ---------------- */ | /* ---------------- */ | ||||
| /* little cache for values... */ | /* little cache for values... */ | ||||
| typedef struct TempFrameValCache { | typedef struct TempFrameValCache { | ||||
| float frame, val; | float frame, val; | ||||
| } TempFrameValCache; | } TempFrameValCache; | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | if (BEZT_ISSEL_ANY(bezt)) { | ||||
| /* just set start keyframe */ | /* just set start keyframe */ | ||||
| start = bezt; | start = bezt; | ||||
| end = NULL; | end = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* recalculate channel's handles? */ | /* recalculate channel's handles? */ | ||||
| calchandles_fcurve(fcu); | BKE_fcurve_handles_recalc(fcu); | ||||
| } | } | ||||
| /* **************************************************** */ | /* **************************************************** */ | ||||
| /* Copy/Paste Tools: | /* Copy/Paste Tools: | ||||
| * - The copy/paste buffer currently stores a set of temporary F-Curves containing only the | * - The copy/paste buffer currently stores a set of temporary F-Curves containing only the | ||||
| * keyframes that were selected in each of the original F-Curves. | * keyframes that were selected in each of the original F-Curves. | ||||
| * - All pasted frames are offset by the same amount. | * - All pasted frames are offset by the same amount. | ||||
| * This is calculated as the difference in the times of the current frame and the | * This is calculated as the difference in the times of the current frame and the | ||||
| ▲ Show 20 Lines • Show All 342 Lines • ▼ Show 20 Lines | static void paste_animedit_keys_fcurve( | ||||
| /* mix mode with existing data */ | /* mix mode with existing data */ | ||||
| switch (merge_mode) { | switch (merge_mode) { | ||||
| case KEYFRAME_PASTE_MERGE_MIX: | case KEYFRAME_PASTE_MERGE_MIX: | ||||
| /* do-nothing */ | /* do-nothing */ | ||||
| break; | break; | ||||
| case KEYFRAME_PASTE_MERGE_OVER: | case KEYFRAME_PASTE_MERGE_OVER: | ||||
| /* remove all keys */ | /* remove all keys */ | ||||
| clear_fcurve_keys(fcu); | BKE_fcurve_delete_keys_all(fcu); | ||||
| break; | break; | ||||
| case KEYFRAME_PASTE_MERGE_OVER_RANGE: | case KEYFRAME_PASTE_MERGE_OVER_RANGE: | ||||
| case KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL: { | case KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL: { | ||||
| float f_min; | float f_min; | ||||
| float f_max; | float f_max; | ||||
| if (merge_mode == KEYFRAME_PASTE_MERGE_OVER_RANGE) { | if (merge_mode == KEYFRAME_PASTE_MERGE_OVER_RANGE) { | ||||
| Show All 10 Lines | case KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL: { | ||||
| /* select verts in range for removal */ | /* select verts in range for removal */ | ||||
| for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { | for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { | ||||
| if ((f_min < bezt[0].vec[1][0]) && (bezt[0].vec[1][0] < f_max)) { | if ((f_min < bezt[0].vec[1][0]) && (bezt[0].vec[1][0] < f_max)) { | ||||
| bezt->f2 |= SELECT; | bezt->f2 |= SELECT; | ||||
| } | } | ||||
| } | } | ||||
| /* remove frames in the range */ | /* remove frames in the range */ | ||||
| delete_fcurve_keys(fcu); | BKE_fcurve_delete_keys_selected(fcu); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| /* just start pasting, with the first keyframe on the current frame, and so on */ | /* just start pasting, with the first keyframe on the current frame, and so on */ | ||||
| for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) { | for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) { | ||||
| /* temporarily apply offset to src beztriple while copying */ | /* temporarily apply offset to src beztriple while copying */ | ||||
| Show All 17 Lines | for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) { | ||||
| bezt->vec[2][0] -= offset; | bezt->vec[2][0] -= offset; | ||||
| if (flip) { | if (flip) { | ||||
| do_curve_mirror_flippping(aci, bezt); | do_curve_mirror_flippping(aci, bezt); | ||||
| } | } | ||||
| } | } | ||||
| /* recalculate F-Curve's handles? */ | /* recalculate F-Curve's handles? */ | ||||
| calchandles_fcurve(fcu); | BKE_fcurve_handles_recalc(fcu); | ||||
| } | } | ||||
| const EnumPropertyItem rna_enum_keyframe_paste_offset_items[] = { | const EnumPropertyItem rna_enum_keyframe_paste_offset_items[] = { | ||||
| {KEYFRAME_PASTE_OFFSET_CFRA_START, | {KEYFRAME_PASTE_OFFSET_CFRA_START, | ||||
| "START", | "START", | ||||
| 0, | 0, | ||||
| "Frame Start", | "Frame Start", | ||||
| "Paste keys starting at current frame"}, | "Paste keys starting at current frame"}, | ||||
| ▲ Show 20 Lines • Show All 146 Lines • Show Last 20 Lines | |||||