VSE: Move whole strip chain to meta

Python API function Sequence.move_to_meta() did delete effect chain
when strip with effects was moved.

Use iterator API to query effect strips and move whole chain to meta.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D11206
This commit is contained in:
Richard Antalik 2021-05-18 23:28:00 +02:00
parent 748b5f025d
commit f7a14c116c
4 changed files with 60 additions and 44 deletions

View File

@ -1621,37 +1621,6 @@ static bool select_grouped_time_overlap(Editing *ed, Sequence *actseq)
return changed;
}
/* Query all effect strips that are directly or indirectly connected to seq_reference. */
static void query_strip_effect_chain(Sequence *seq_reference,
ListBase *seqbase,
SeqCollection *collection)
{
if (!SEQ_collection_append_strip(seq_reference, collection)) {
return; /* Strip is already in set, so all effects connected to it are as well. */
}
/* Find all strips that seq_reference is connected to. */
if (seq_reference->type & SEQ_TYPE_EFFECT) {
if (seq_reference->seq1) {
query_strip_effect_chain(seq_reference->seq1, seqbase, collection);
}
if (seq_reference->seq2) {
query_strip_effect_chain(seq_reference->seq2, seqbase, collection);
}
if (seq_reference->seq3) {
query_strip_effect_chain(seq_reference->seq3, seqbase, collection);
}
}
/* Find all strips connected to seq_reference. */
LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
if (seq_test->seq1 == seq_reference || seq_test->seq2 == seq_reference ||
seq_test->seq3 == seq_reference) {
query_strip_effect_chain(seq_test, seqbase, collection);
}
}
}
/* Query strips that are in lower channel and intersect in time with seq_reference. */
static void query_lower_channel_strips(Sequence *seq_reference,
ListBase *seqbase,
@ -1681,7 +1650,7 @@ static bool select_grouped_effect_link(Editing *ed,
SeqCollection *collection = SEQ_query_selected_strips(seqbase);
const int selected_strip_count = BLI_gset_len(collection->set);
SEQ_collection_expand(seqbase, collection, query_lower_channel_strips);
SEQ_collection_expand(seqbase, collection, query_strip_effect_chain);
SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain);
/* Check if other strips will be affected. */
const bool changed = BLI_gset_len(collection->set) > selected_strip_count;

View File

@ -86,6 +86,9 @@ SeqCollection *SEQ_query_by_reference(struct Sequence *seq_reference,
SeqCollection *collection));
SeqCollection *SEQ_query_selected_strips(struct ListBase *seqbase);
SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase);
void SEQ_query_strip_effect_chain(struct Sequence *seq_reference,
struct ListBase *seqbase,
SeqCollection *collection);
#ifdef __cplusplus
}

View File

@ -230,3 +230,42 @@ SeqCollection *SEQ_query_selected_strips(ListBase *seqbase)
}
return collection;
}
/**
* Query all effect strips that are directly or indirectly connected to seq_reference.
* This includes all effects of seq_reference, strips used by another inputs and their effects, so
* that whole chain is fully independent of other strips.
*
* \param seq_reference: reference strip
* \param seqbase: ListBase in which strips are queried
* \param collection: collection to be filled
*/
void SEQ_query_strip_effect_chain(Sequence *seq_reference,
ListBase *seqbase,
SeqCollection *collection)
{
if (!SEQ_collection_append_strip(seq_reference, collection)) {
return; /* Strip is already in set, so all effects connected to it are as well. */
}
/* Find all strips that seq_reference is connected to. */
if (seq_reference->type & SEQ_TYPE_EFFECT) {
if (seq_reference->seq1) {
SEQ_query_strip_effect_chain(seq_reference->seq1, seqbase, collection);
}
if (seq_reference->seq2) {
SEQ_query_strip_effect_chain(seq_reference->seq2, seqbase, collection);
}
if (seq_reference->seq3) {
SEQ_query_strip_effect_chain(seq_reference->seq3, seqbase, collection);
}
}
/* Find all strips connected to seq_reference. */
LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
if (seq_test->seq1 == seq_reference || seq_test->seq2 == seq_reference ||
seq_test->seq3 == seq_reference) {
SEQ_query_strip_effect_chain(seq_test, seqbase, collection);
}
}
}

View File

@ -43,6 +43,7 @@
#include "SEQ_add.h"
#include "SEQ_edit.h"
#include "SEQ_effects.h"
#include "SEQ_iterator.h"
#include "SEQ_relations.h"
#include "SEQ_sequencer.h"
#include "SEQ_time.h"
@ -251,22 +252,26 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene,
return false;
}
/* Remove users of src_seq. Ideally these could be moved into meta as well, but this would be
* best to do with generalized iterator as described in D10337. */
sequencer_flag_users_for_removal(scene, seqbase, src_seq);
SEQ_edit_remove_flagged_sequences(scene, seqbase);
SeqCollection *collection = SEQ_collection_create();
SEQ_collection_append_strip(src_seq, collection);
SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain);
/* Move to meta. */
BLI_remlink(seqbase, src_seq);
BLI_addtail(&dst_seqm->seqbase, src_seq);
SEQ_relations_invalidate_cache_preprocessed(scene, src_seq);
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, collection) {
/* Move to meta. */
BLI_remlink(seqbase, seq);
BLI_addtail(&dst_seqm->seqbase, seq);
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
/* Update meta. */
SEQ_time_update_sequence(scene, dst_seqm);
if (SEQ_transform_test_overlap(&dst_seqm->seqbase, src_seq)) {
SEQ_transform_seqbase_shuffle(&dst_seqm->seqbase, src_seq, scene);
/* Update meta. */
SEQ_time_update_sequence(scene, dst_seqm);
if (SEQ_transform_test_overlap(&dst_seqm->seqbase, seq)) {
SEQ_transform_seqbase_shuffle(&dst_seqm->seqbase, seq, scene);
}
}
SEQ_collection_free(collection);
return true;
}