diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 96f8d2fe269..3865aee8327 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1606,8 +1606,8 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) * This way, when pasted strips are renamed, curves are renamed with them. Finally, restore * original curves from backup. */ - ListBase fcurves_original_backup = {NULL, NULL}; - SEQ_animation_backup_original(scene, &fcurves_original_backup); + SeqAnimationBackup animation_backup = {0}; + SEQ_animation_backup_original(scene, &animation_backup); Sequence *seq = duplicated_strips.first; @@ -1623,12 +1623,15 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) } seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK); seq->flag |= SEQ_IGNORE_CHANNEL_LOCK; - SEQ_animation_duplicate(scene, seq, &fcurves_original_backup); + + SEQ_animation_duplicate_backup_to_scene(scene, seq, &animation_backup); SEQ_ensure_unique_name(seq, scene); } - SEQ_animation_restore_original(scene, &fcurves_original_backup); + SEQ_animation_restore_original(scene, &animation_backup); + DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); + DEG_relations_tag_update(CTX_data_main(C)); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; } @@ -2393,33 +2396,41 @@ static void seq_copy_del_sound(Scene *scene, Sequence *seq) } } -static void sequencer_copy_animation(Scene *scene, Sequence *seq) +static void sequencer_copy_animation_listbase(Scene *scene, + Sequence *seq, + ListBase *clipboard, + ListBase *fcurve_base) { - if (scene->adt == NULL || scene->adt->action == NULL || - BLI_listbase_is_empty(&scene->adt->action->curves)) { - return; - } - /* Add curves for strips inside meta strip. */ if (seq->type == SEQ_TYPE_META) { LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) { - sequencer_copy_animation(scene, meta_child); + sequencer_copy_animation_listbase(scene, meta_child, clipboard, fcurve_base); } } - GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); + GSet *fcurves = SEQ_fcurves_by_strip_get(seq, fcurve_base); if (fcurves == NULL) { return; } GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { - BLI_addtail(&fcurves_clipboard, BKE_fcurve_copy(fcu)); + BLI_addtail(clipboard, BKE_fcurve_copy(fcu)); } GSET_FOREACH_END(); BLI_gset_free(fcurves, NULL); } +static void sequencer_copy_animation(Scene *scene, Sequence *seq) +{ + if (SEQ_animation_curves_exist(scene)) { + sequencer_copy_animation_listbase(scene, seq, &fcurves_clipboard, &scene->adt->action->curves); + } + if (SEQ_animation_drivers_exist(scene)) { + sequencer_copy_animation_listbase(scene, seq, &drivers_clipboard, &scene->adt->drivers); + } +} + static int sequencer_copy_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -2496,7 +2507,7 @@ void ED_sequencer_deselect_all(Scene *scene) static void sequencer_paste_animation(bContext *C) { - if (BLI_listbase_is_empty(&fcurves_clipboard)) { + if (BLI_listbase_is_empty(&fcurves_clipboard) && BLI_listbase_is_empty(&drivers_clipboard)) { return; } @@ -2515,6 +2526,9 @@ static void sequencer_paste_animation(bContext *C) LISTBASE_FOREACH (FCurve *, fcu, &fcurves_clipboard) { BLI_addtail(&act->curves, BKE_fcurve_copy(fcu)); } + LISTBASE_FOREACH (FCurve *, fcu, &drivers_clipboard) { + BLI_addtail(&scene->adt->drivers, BKE_fcurve_copy(fcu)); + } } static int sequencer_paste_exec(bContext *C, wmOperator *op) @@ -2553,8 +2567,8 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) * curves from backup. */ - ListBase fcurves_original_backup = {NULL, NULL}; - SEQ_animation_backup_original(scene, &fcurves_original_backup); + SeqAnimationBackup animation_backup = {0}; + SEQ_animation_backup_original(scene, &animation_backup); sequencer_paste_animation(C); /* Copy strips, temporarily restoring pointers to actual data-blocks. This @@ -2589,7 +2603,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) } } - SEQ_animation_restore_original(scene, &fcurves_original_backup); + SEQ_animation_restore_original(scene, &animation_backup); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); DEG_relations_tag_update(bmain); diff --git a/source/blender/sequencer/SEQ_animation.h b/source/blender/sequencer/SEQ_animation.h index b8f74e5a510..7d40cf44cfa 100644 --- a/source/blender/sequencer/SEQ_animation.h +++ b/source/blender/sequencer/SEQ_animation.h @@ -15,22 +15,31 @@ struct GSet; struct ListBase; struct Scene; struct Sequence; +struct SeqAnimationBackup; +bool SEQ_animation_curves_exist(struct Scene *scene); +bool SEQ_animation_drivers_exist(struct Scene *scene); void SEQ_free_animdata(struct Scene *scene, struct Sequence *seq); void SEQ_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs); struct GSet *SEQ_fcurves_by_strip_get(const struct Sequence *seq, struct ListBase *fcurve_base); +typedef struct SeqAnimationBackup { + ListBase curves; + ListBase drivers; +} SeqAnimationBackup; /** - * Move all `F-Curves` from `scene` to `list`. + * Move all F-Curves and drivers from `scene` to `backup`. */ -void SEQ_animation_backup_original(struct Scene *scene, struct ListBase *list); +void SEQ_animation_backup_original(struct Scene *scene, struct SeqAnimationBackup *backup); /** - * Move all `F-Curves` from `list` to `scene`. + * Move all F-Curves and drivers from `backup` to `scene`. */ -void SEQ_animation_restore_original(struct Scene *scene, struct ListBase *list); +void SEQ_animation_restore_original(struct Scene *scene, struct SeqAnimationBackup *backup); /** - * Duplicate `F-Curves` used by `seq` from `list` to `scene`. + * Duplicate F-Curves and drivers used by `seq` from `backup` to `scene`. */ -void SEQ_animation_duplicate(struct Scene *scene, struct Sequence *seq, struct ListBase *list); +void SEQ_animation_duplicate_backup_to_scene(struct Scene *scene, + struct Sequence *seq, + struct SeqAnimationBackup *backup); #ifdef __cplusplus } diff --git a/source/blender/sequencer/SEQ_clipboard.h b/source/blender/sequencer/SEQ_clipboard.h index 5625f8886c9..1e5b877204b 100644 --- a/source/blender/sequencer/SEQ_clipboard.h +++ b/source/blender/sequencer/SEQ_clipboard.h @@ -18,6 +18,7 @@ struct Sequence; extern struct ListBase seqbase_clipboard; extern struct ListBase fcurves_clipboard; +extern struct ListBase drivers_clipboard; extern int seqbase_clipboard_frame; void SEQ_clipboard_pointers_store(struct Main *bmain, struct ListBase *seqbase); void SEQ_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain); diff --git a/source/blender/sequencer/intern/animation.c b/source/blender/sequencer/intern/animation.c index 280d2177d89..ec9deb2acd7 100644 --- a/source/blender/sequencer/intern/animation.c +++ b/source/blender/sequencer/intern/animation.c @@ -22,13 +22,15 @@ #include "SEQ_animation.h" -static bool seq_animation_curves_exist(Scene *scene) +bool SEQ_animation_curves_exist(Scene *scene) { - if (scene->adt == NULL || scene->adt->action == NULL || - BLI_listbase_is_empty(&scene->adt->action->curves)) { - return false; - } - return true; + return scene->adt != NULL && scene->adt->action != NULL && + !BLI_listbase_is_empty(&scene->adt->action->curves); +} + +bool SEQ_animation_drivers_exist(Scene *scene) +{ + return scene->adt != NULL && !BLI_listbase_is_empty(&scene->adt->drivers); } /* r_prefix + [" + escaped_name + "] + \0 */ @@ -66,7 +68,7 @@ GSet *SEQ_fcurves_by_strip_get(const Sequence *seq, ListBase *fcurve_base) void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs) { - if (!seq_animation_curves_exist(scene) || ofs == 0) { + if (!SEQ_animation_curves_exist(scene) || ofs == 0) { return; } GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); @@ -99,7 +101,7 @@ void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs) void SEQ_free_animdata(Scene *scene, Sequence *seq) { - if (!seq_animation_curves_exist(scene)) { + if (!SEQ_animation_curves_exist(scene)) { return; } GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); @@ -115,46 +117,55 @@ void SEQ_free_animdata(Scene *scene, Sequence *seq) BLI_gset_free(fcurves, NULL); } -void SEQ_animation_backup_original(Scene *scene, ListBase *list) +void SEQ_animation_backup_original(Scene *scene, SeqAnimationBackup *backup) { - if (scene->adt == NULL || scene->adt->action == NULL || - BLI_listbase_is_empty(&scene->adt->action->curves)) { - return; + if (SEQ_animation_curves_exist(scene)) { + BLI_movelisttolist(&backup->curves, &scene->adt->action->curves); + } + if (SEQ_animation_drivers_exist(scene)) { + BLI_movelisttolist(&backup->drivers, &scene->adt->drivers); } - - BLI_movelisttolist(list, &scene->adt->action->curves); } -void SEQ_animation_restore_original(Scene *scene, ListBase *list) +void SEQ_animation_restore_original(Scene *scene, SeqAnimationBackup *backup) { - if (scene->adt == NULL || scene->adt->action == NULL || BLI_listbase_is_empty(list)) { - return; + if (!BLI_listbase_is_empty(&backup->curves)) { + BLI_movelisttolist(&scene->adt->action->curves, &backup->curves); + } + if (!BLI_listbase_is_empty(&backup->drivers)) { + BLI_movelisttolist(&scene->adt->drivers, &backup->drivers); } - - BLI_movelisttolist(&scene->adt->action->curves, list); } -void SEQ_animation_duplicate(Scene *scene, Sequence *seq, ListBase *list) +static void seq_animation_duplicate(Scene *scene, Sequence *seq, ListBase *dst, ListBase *src) { - if (BLI_listbase_is_empty(list)) { - return; - } - if (seq->type == SEQ_TYPE_META) { LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) { - SEQ_animation_duplicate(scene, meta_child, list); + seq_animation_duplicate(scene, meta_child, dst, src); } } - GSet *fcurves = SEQ_fcurves_by_strip_get(seq, list); + GSet *fcurves = SEQ_fcurves_by_strip_get(seq, src); if (fcurves == NULL) { return; } GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { FCurve *fcu_cpy = BKE_fcurve_copy(fcu); - BLI_addtail(&scene->adt->action->curves, fcu_cpy); + BLI_addtail(dst, fcu_cpy); } GSET_FOREACH_END(); BLI_gset_free(fcurves, NULL); } + +void SEQ_animation_duplicate_backup_to_scene(Scene *scene, + Sequence *seq, + SeqAnimationBackup *backup) +{ + if (!BLI_listbase_is_empty(&backup->curves)) { + seq_animation_duplicate(scene, seq, &scene->adt->action->curves, &backup->curves); + } + if (!BLI_listbase_is_empty(&backup->drivers)) { + seq_animation_duplicate(scene, seq, &scene->adt->drivers, &backup->drivers); + } +} diff --git a/source/blender/sequencer/intern/clipboard.c b/source/blender/sequencer/intern/clipboard.c index dc3c82d1fdc..c8777dc9690 100644 --- a/source/blender/sequencer/intern/clipboard.c +++ b/source/blender/sequencer/intern/clipboard.c @@ -44,6 +44,7 @@ ListBase seqbase_clipboard; ListBase fcurves_clipboard; +ListBase drivers_clipboard; int seqbase_clipboard_frame; static char seq_clipboard_active_seq_name[SEQ_NAME_MAXSTR]; @@ -62,6 +63,11 @@ void SEQ_clipboard_free(void) BKE_fcurve_free(fcu); } BLI_listbase_clear(&fcurves_clipboard); + + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &drivers_clipboard) { + BKE_fcurve_free(fcu); + } + BLI_listbase_clear(&drivers_clipboard); } #define ID_PT (*id_pt) diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index 5ac4bd03f43..d0f7521bd10 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -436,8 +436,8 @@ Sequence *SEQ_edit_strip_split(Main *bmain, } /* Store `F-Curves`, so original ones aren't renamed. */ - ListBase fcurves_original_backup = {NULL, NULL}; - SEQ_animation_backup_original(scene, &fcurves_original_backup); + SeqAnimationBackup animation_backup = {0}; + SEQ_animation_backup_original(scene, &animation_backup); ListBase left_strips = {NULL, NULL}; SEQ_ITERATOR_FOREACH (seq, collection) { @@ -446,7 +446,7 @@ Sequence *SEQ_edit_strip_split(Main *bmain, BLI_addtail(&left_strips, seq); /* Duplicate curves from backup, so they can be renamed along with split strips. */ - SEQ_animation_duplicate(scene, seq, &fcurves_original_backup); + SEQ_animation_duplicate_backup_to_scene(scene, seq, &animation_backup); } SEQ_collection_free(collection); @@ -489,7 +489,7 @@ Sequence *SEQ_edit_strip_split(Main *bmain, } SEQ_edit_remove_flagged_sequences(scene, seqbase); - SEQ_animation_restore_original(scene, &fcurves_original_backup); + SEQ_animation_restore_original(scene, &animation_backup); return return_seq; }