Fix T96699: Splitting strip does not copy animation

Since e49bf4019b, animation is handled explicitly. Split operator
wasn't updated.

Re-use backup-duplicate-restore animation functions, that other
operators use for splitting.
This commit is contained in:
Richard Antalik 2022-03-29 04:10:37 +02:00
parent f99beb730a
commit e74420124f
Notes: blender-bot 2023-02-14 09:02:40 +01:00
Referenced by commit 25a283acce, Fix memory leak duplicating sequencer strips
Referenced by issue #96699, Regression: Cutting a strip with keyframes in the VSE deletes the keyframes from the original (left) strip.
Referenced by issue #96241, 3.1: Potential candidates for corrective releases
4 changed files with 56 additions and 35 deletions

View File

@ -1643,35 +1643,6 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot)
/** \name Duplicate Strips Operator
* \{ */
static void sequencer_backup_original_animation(Scene *scene, ListBase *list)
{
if (scene->adt == NULL || scene->adt->action == NULL ||
BLI_listbase_is_empty(&scene->adt->action->curves)) {
return;
}
BLI_movelisttolist(list, &scene->adt->action->curves);
}
static void sequencer_restore_original_animation(Scene *scene, ListBase *list)
{
if (scene->adt == NULL || scene->adt->action == NULL || BLI_listbase_is_empty(list)) {
return;
}
BLI_movelisttolist(&scene->adt->action->curves, list);
}
static void sequencer_duplicate_animation(Scene *scene, Sequence *seq, ListBase *curves_backup)
{
GSet *fcurves = SEQ_fcurves_by_strip_get(seq, curves_backup);
GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) {
FCurve *fcu_cpy = BKE_fcurve_copy(fcu);
BLI_addtail(&scene->adt->action->curves, fcu_cpy);
}
GSET_FOREACH_END();
}
static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
@ -1697,7 +1668,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
* original curves from backup.
*/
ListBase fcurves_original_backup = {NULL, NULL};
sequencer_backup_original_animation(scene, &fcurves_original_backup);
SEQ_animation_backup_original(scene, &fcurves_original_backup);
Sequence *seq = duplicated_strips.first;
@ -1712,11 +1683,11 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
SEQ_select_active_set(scene, seq);
}
seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK);
sequencer_duplicate_animation(scene, seq, &fcurves_original_backup);
SEQ_animation_duplicate(scene, seq, &fcurves_original_backup);
SEQ_ensure_unique_name(seq, scene);
}
sequencer_restore_original_animation(scene, &fcurves_original_backup);
SEQ_animation_restore_original(scene, &fcurves_original_backup);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@ -2622,7 +2593,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
*/
ListBase fcurves_original_backup = {NULL, NULL};
sequencer_backup_original_animation(scene, &fcurves_original_backup);
SEQ_animation_backup_original(scene, &fcurves_original_backup);
sequencer_paste_animation(C);
/* Copy strips, temporarily restoring pointers to actual data-blocks. This
@ -2654,7 +2625,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
}
}
sequencer_restore_original_animation(scene, &fcurves_original_backup);
SEQ_animation_restore_original(scene, &fcurves_original_backup);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
DEG_relations_tag_update(bmain);

View File

@ -19,6 +19,18 @@ struct Sequence;
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);
/**
* Move all `F-curves` from `scene` to `list`.
*/
void SEQ_animation_backup_original(struct Scene *scene, struct ListBase *list);
/**
* Move all `F-curves` from `list` to `scene`.
*/
void SEQ_animation_restore_original(struct Scene *scene, struct ListBase *list);
/**
* Duplicate `F-curves` used by `seq` from `list` to `scene`.
*/
void SEQ_animation_duplicate(struct Scene *scene, struct Sequence *seq, struct ListBase *list);
#ifdef __cplusplus
}

View File

@ -104,3 +104,32 @@ void SEQ_free_animdata(Scene *scene, Sequence *seq)
GSET_FOREACH_END();
BLI_gset_free(fcurves, NULL);
}
void SEQ_animation_backup_original(Scene *scene, ListBase *list)
{
if (scene->adt == NULL || scene->adt->action == NULL ||
BLI_listbase_is_empty(&scene->adt->action->curves)) {
return;
}
BLI_movelisttolist(list, &scene->adt->action->curves);
}
void SEQ_animation_restore_original(Scene *scene, ListBase *list)
{
if (scene->adt == NULL || scene->adt->action == NULL || BLI_listbase_is_empty(list)) {
return;
}
BLI_movelisttolist(&scene->adt->action->curves, list);
}
void SEQ_animation_duplicate(Scene *scene, Sequence *seq, ListBase *list)
{
GSet *fcurves = SEQ_fcurves_by_strip_get(seq, list);
GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) {
FCurve *fcu_cpy = BKE_fcurve_copy(fcu);
BLI_addtail(&scene->adt->action->curves, fcu_cpy);
}
GSET_FOREACH_END();
}

View File

@ -457,11 +457,18 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
return NULL;
}
/* Move strips in collection from seqbase to new ListBase. */
/* Store `F-curves`, so original ones aren't renamed. */
ListBase fcurves_original_backup = {NULL, NULL};
SEQ_animation_backup_original(scene, &fcurves_original_backup);
ListBase left_strips = {NULL, NULL};
SEQ_ITERATOR_FOREACH (seq, collection) {
/* Move strips in collection from seqbase to new ListBase. */
BLI_remlink(seqbase, seq);
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_collection_free(collection);
@ -511,6 +518,8 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
SEQ_ensure_unique_name(seq_rename, scene);
}
SEQ_animation_restore_original(scene, &fcurves_original_backup);
return return_seq;
}