VSE: Support copy-pasting strips with animation
When copying strips between 2 scenes, it wasn't possible to copy animation curves along with strips. In this patch curves are copied into clipboard `ListBase`. When pasted, original curves are moved into temporary `ListBase` and curves in clipboard are moved into scene action. This is because when strips from clipboard have to be renamed, function `SEQ_ensure_unique_name()` does fix RNA paths of curves, but this is done globally for all curves within action. After strips are renamed, restore original curves from backup. Note: This patch handles only fcurves. Drivers and actions are currently not handled anywhere in VSE. Fixes T77530 Reviewed By: sergey Differential Revision: https://developer.blender.org/D13845
This commit is contained in:
parent
e49bf4019b
commit
eddad4e9a1
Notes:
blender-bot
2023-02-14 00:20:19 +01:00
Referenced by issue #96699, Regression: Cutting a strip with keyframes in the VSE deletes the keyframes from the original (left) strip. Referenced by issue #96595, VSE Regression: Duplicating grouped strips does not maintain F-Curve keyframes Referenced by issue #77530, VSE: Pasted strip doesnt have F-Curve keyframes from the original (if pasted between scenes)
|
@ -2487,6 +2487,22 @@ static void seq_copy_del_sound(Scene *scene, Sequence *seq)
|
|||
}
|
||||
}
|
||||
|
||||
static void sequencer_copy_animation(Scene *scene, Sequence *seq)
|
||||
{
|
||||
if (scene->adt == NULL || scene->adt->action == NULL ||
|
||||
BLI_listbase_is_empty(&scene->adt->action->curves)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GSet *fcurves = SEQ_fcurves_by_strip_name_get(seq->name + 2, &scene->adt->action->curves);
|
||||
|
||||
GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) {
|
||||
BLI_addtail(&fcurves_clipboard, BKE_fcurve_copy(fcu));
|
||||
}
|
||||
GSET_FOREACH_END();
|
||||
BLI_gset_free(fcurves, NULL);
|
||||
}
|
||||
|
||||
static int sequencer_copy_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
@ -2513,8 +2529,10 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
|
|||
seqbase_clipboard_frame = scene->r.cfra;
|
||||
SEQ_clipboard_active_seq_name_store(scene);
|
||||
|
||||
/* Remove anything that references the current scene. */
|
||||
LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) {
|
||||
/* Copy curves. */
|
||||
sequencer_copy_animation(scene, seq);
|
||||
/* Remove anything that references the current scene. */
|
||||
seq_copy_del_sound(scene, seq);
|
||||
}
|
||||
|
||||
|
@ -2559,6 +2577,29 @@ void ED_sequencer_deselect_all(Scene *scene)
|
|||
}
|
||||
}
|
||||
|
||||
static void sequencer_paste_animation(bContext *C)
|
||||
{
|
||||
if (BLI_listbase_is_empty(&fcurves_clipboard)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bAction *act;
|
||||
|
||||
if (scene->adt != NULL && scene->adt->action != NULL) {
|
||||
act = scene->adt->action;
|
||||
}
|
||||
else {
|
||||
/* get action to add F-Curve+keyframe to */
|
||||
act = ED_id_action_ensure(bmain, &scene->id);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &fcurves_clipboard) {
|
||||
BLI_addtail(&act->curves, BKE_fcurve_copy(fcu));
|
||||
}
|
||||
}
|
||||
|
||||
static int sequencer_paste_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
@ -2589,12 +2630,15 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
/* Paste animation.
|
||||
* First backup original curves from scene and duplicate strip curves from backup into scene.
|
||||
* This way, when pasted strips are renamed, curves are renamed with them. Finally, restore
|
||||
* original curves from backup.
|
||||
* Note: Only fcurves are copied. Drivers and NLA action strips are not copied.
|
||||
* First backup original curves from scene and move curves from clipboard into scene. This way,
|
||||
* when pasted strips are renamed, pasted fcurves are renamed with them. Finally restore original
|
||||
* curves from backup.
|
||||
*/
|
||||
|
||||
ListBase fcurves_original_backup = {NULL, NULL};
|
||||
sequencer_backup_original_animation(scene, &fcurves_original_backup);
|
||||
sequencer_paste_animation(C);
|
||||
|
||||
/* Copy strips, temporarily restoring pointers to actual data-blocks. This
|
||||
* must happen on the clipboard itself, so that copying does user counting
|
||||
|
@ -2614,8 +2658,6 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
|
|||
SEQ_select_active_set(scene, iseq);
|
||||
}
|
||||
|
||||
sequencer_duplicate_animation(scene, iseq, &fcurves_original_backup);
|
||||
|
||||
/* Make sure, that pasted strips have unique names. */
|
||||
SEQ_ensure_unique_name(iseq, scene);
|
||||
/* Translate after name has been changed, otherwise this will affect animdata of original
|
||||
|
|
|
@ -33,6 +33,7 @@ struct Scene;
|
|||
struct Sequence;
|
||||
|
||||
extern struct ListBase seqbase_clipboard;
|
||||
extern struct ListBase fcurves_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);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
#include "DNA_sound_types.h"
|
||||
|
@ -35,6 +36,7 @@
|
|||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_movieclip.h"
|
||||
#include "BKE_scene.h"
|
||||
|
@ -58,6 +60,7 @@
|
|||
*/
|
||||
|
||||
ListBase seqbase_clipboard;
|
||||
ListBase fcurves_clipboard;
|
||||
int seqbase_clipboard_frame;
|
||||
static char seq_clipboard_active_seq_name[SEQ_NAME_MAXSTR];
|
||||
|
||||
|
@ -65,15 +68,17 @@ void seq_clipboard_pointers_free(struct ListBase *seqbase);
|
|||
|
||||
void SEQ_clipboard_free(void)
|
||||
{
|
||||
Sequence *seq, *nseq;
|
||||
|
||||
seq_clipboard_pointers_free(&seqbase_clipboard);
|
||||
|
||||
for (seq = seqbase_clipboard.first; seq; seq = nseq) {
|
||||
nseq = seq->next;
|
||||
LISTBASE_FOREACH_MUTABLE (Sequence *, seq, &seqbase_clipboard) {
|
||||
seq_free_sequence_recurse(NULL, seq, false);
|
||||
}
|
||||
BLI_listbase_clear(&seqbase_clipboard);
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &fcurves_clipboard) {
|
||||
BKE_fcurve_free(fcu);
|
||||
}
|
||||
BLI_listbase_clear(&fcurves_clipboard);
|
||||
}
|
||||
|
||||
#define ID_PT (*id_pt)
|
||||
|
|
Loading…
Reference in New Issue