diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_edit.c | 15 | ||||
-rw-r--r-- | source/blender/sequencer/SEQ_utils.h | 1 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_edit.c | 81 | ||||
-rw-r--r-- | source/blender/sequencer/intern/utils.c | 76 | ||||
-rw-r--r-- | source/blender/sequencer/intern/utils.h | 1 |
5 files changed, 120 insertions, 54 deletions
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 1a1ba5a0754..4d87f0300e7 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1577,17 +1577,6 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot) /** \name Duplicate Strips Operator * \{ */ -static int apply_unique_name_fn(Sequence *seq, void *arg_pt) -{ - Scene *scene = (Scene *)arg_pt; - char name[sizeof(seq->name) - 2]; - - BLI_strncpy_utf8(name, seq->name + 2, sizeof(name)); - SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); - SEQ_dupe_animdata(scene, name, seq->name + 2); - return 1; -} - static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -1608,7 +1597,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) BLI_movelisttolist(ed->seqbasep, &nseqbase); for (; seq; seq = seq->next) { - SEQ_recursive_apply(seq, apply_unique_name_fn, scene); + SEQ_ensure_unique_name(seq, scene); } WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2465,7 +2454,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) for (iseq = iseq_first; iseq; iseq = iseq->next) { /* Make sure, that pasted strips have unique names. */ - SEQ_recursive_apply(iseq, apply_unique_name_fn, scene); + SEQ_ensure_unique_name(iseq, scene); /* Translate after name has been changed, otherwise this will affect animdata of original * strip. */ SEQ_transform_translate_sequence(scene, iseq, ofs); diff --git a/source/blender/sequencer/SEQ_utils.h b/source/blender/sequencer/SEQ_utils.h index 52fac5d7d0e..361246d74c5 100644 --- a/source/blender/sequencer/SEQ_utils.h +++ b/source/blender/sequencer/SEQ_utils.h @@ -60,6 +60,7 @@ int SEQ_seqbase_recursive_apply(struct ListBase *seqbase, int SEQ_recursive_apply(struct Sequence *seq, int (*apply_fn)(struct Sequence *, void *), void *arg); +void SEQ_ensure_unique_name(struct Sequence *seq, struct Scene *scene); #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index a26fb0244b6..b5b0dc2770e 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -39,6 +39,7 @@ #include "BKE_sound.h" #include "strip_time.h" +#include "utils.h" #include "SEQ_add.h" #include "SEQ_edit.h" @@ -348,6 +349,29 @@ static void seq_split_set_left_offset(Sequence *seq, int timeline_frame) SEQ_transform_set_left_handle_frame(seq, timeline_frame); } +static void seq_edit_split_handle_strip_offsets(Main *bmain, + Scene *scene, + Sequence *left_seq, + Sequence *right_seq, + const int timeline_frame, + const eSeqSplitMethod method) +{ + switch (method) { + case SEQ_SPLIT_SOFT: + seq_split_set_left_offset(right_seq, timeline_frame); + seq_split_set_right_offset(left_seq, timeline_frame); + break; + case SEQ_SPLIT_HARD: + seq_split_set_right_hold_offset(left_seq, timeline_frame); + seq_split_set_left_hold_offset(right_seq, timeline_frame); + SEQ_add_reload_new_file(bmain, scene, left_seq, false); + SEQ_add_reload_new_file(bmain, scene, right_seq, false); + break; + } + SEQ_time_update_sequence(scene, left_seq); + SEQ_time_update_sequence(scene, right_seq); +} + /** * Split Sequence at timeline_frame in two. * @@ -370,33 +394,44 @@ Sequence *SEQ_edit_strip_split(Main *bmain, return NULL; } - if (method == SEQ_SPLIT_HARD) { - /* Precaution, needed because the length saved on-disk may not match the length saved in the - * blend file, or our code may have minor differences reading file length between versions. - * This causes hard-split to fail, see: T47862. */ - SEQ_add_reload_new_file(bmain, scene, seq, true); - SEQ_time_update_sequence(scene, seq); + SeqCollection *collection = SEQ_collection_create(); + SEQ_collection_append_strip(seq, collection); + SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain); + + /* Move strips in collection from seqbase to new ListBase. */ + ListBase left_strips = {NULL, NULL}; + SEQ_ITERATOR_FOREACH (seq, collection) { + BLI_remlink(seqbase, seq); + BLI_addtail(&left_strips, seq); } - Sequence *left_seq = seq; - Sequence *right_seq = SEQ_sequence_dupli_recursive( - scene, scene, seqbase, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); + /* Sort list, so that no strip can depend on next strip in list. + * This is important for SEQ_time_update_sequence functionality. */ + seq_sort_seqbase(&left_strips); + + /* Duplicate ListBase. */ + ListBase right_strips = {NULL, NULL}; + SEQ_sequence_base_dupli_recursive( + scene, scene, &right_strips, &left_strips, SEQ_DUPE_ANIM | SEQ_DUPE_ALL, 0); + + /* Split strips. */ + Sequence *left_seq = left_strips.first; + Sequence *right_seq = right_strips.first; + Sequence *return_seq = right_strips.first; + while (left_seq && right_seq) { + seq_edit_split_handle_strip_offsets(bmain, scene, left_seq, right_seq, timeline_frame, method); + left_seq = left_seq->next; + right_seq = right_seq->next; + } - switch (method) { - case SEQ_SPLIT_SOFT: - seq_split_set_left_offset(right_seq, timeline_frame); - seq_split_set_right_offset(left_seq, timeline_frame); - break; - case SEQ_SPLIT_HARD: - seq_split_set_right_hold_offset(left_seq, timeline_frame); - seq_split_set_left_hold_offset(right_seq, timeline_frame); - SEQ_add_reload_new_file(bmain, scene, left_seq, false); - SEQ_add_reload_new_file(bmain, scene, right_seq, false); - break; + /* Move strips back to seqbase. Move right strips first, so left strips don't change name. */ + BLI_movelisttolist(seqbase, &right_strips); + BLI_movelisttolist(seqbase, &left_strips); + LISTBASE_FOREACH (Sequence *, seq_iter, seqbase) { + SEQ_ensure_unique_name(seq_iter, scene); } - SEQ_time_update_sequence(scene, left_seq); - SEQ_time_update_sequence(scene, right_seq); - return right_seq; + + return return_seq; } /** diff --git a/source/blender/sequencer/intern/utils.c b/source/blender/sequencer/intern/utils.c index 6d5332b2b15..8da71b0ac56 100644 --- a/source/blender/sequencer/intern/utils.c +++ b/source/blender/sequencer/intern/utils.c @@ -33,10 +33,7 @@ #include "DNA_scene_types.h" #include "DNA_sequence_types.h" -#include "BLI_listbase.h" -#include "BLI_path_util.h" -#include "BLI_string.h" -#include "BLI_utildefines.h" +#include "BLI_blenlib.h" #include "BKE_image.h" #include "BKE_main.h" @@ -55,21 +52,24 @@ #include "proxy.h" #include "utils.h" -void SEQ_sort(Scene *scene) +/** + * Sort strips in provided seqbase. Effect strips are trailing the list and they are sorted by + * channel position as well. + * This is important for SEQ_time_update_sequence to work properly + * + * \param seqbase: ListBase with strips + */ + +void seq_sort_seqbase(ListBase *seqbase) { /* all strips together per kind, and in order of y location ("machine") */ - ListBase seqbase, effbase; - Editing *ed = SEQ_editing_get(scene, false); + ListBase inputbase, effbase; Sequence *seq, *seqt; - if (ed == NULL) { - return; - } - - BLI_listbase_clear(&seqbase); + BLI_listbase_clear(&inputbase); BLI_listbase_clear(&effbase); - while ((seq = BLI_pophead(ed->seqbasep))) { + while ((seq = BLI_pophead(seqbase))) { if (seq->type & SEQ_TYPE_EFFECT) { seqt = effbase.first; @@ -85,22 +85,40 @@ void SEQ_sort(Scene *scene) } } else { - seqt = seqbase.first; + seqt = inputbase.first; while (seqt) { if (seqt->machine >= seq->machine) { - BLI_insertlinkbefore(&seqbase, seqt, seq); + BLI_insertlinkbefore(&inputbase, seqt, seq); break; } seqt = seqt->next; } if (seqt == NULL) { - BLI_addtail(&seqbase, seq); + BLI_addtail(&inputbase, seq); } } } - BLI_movelisttolist(&seqbase, &effbase); - *(ed->seqbasep) = seqbase; + BLI_movelisttolist(seqbase, &inputbase); + BLI_movelisttolist(seqbase, &effbase); +} + +/** + * Sort strips in active seqbase. Effect strips are trailing the list and they are sorted by + * channel position as well. + * This is important for SEQ_time_update_sequence to work properly + * + * \param scene: Scene to look for active seqbase in + */ +void SEQ_sort(Scene *scene) +{ + Editing *ed = SEQ_editing_get(scene, false); + + if (ed == NULL) { + return; + } + + seq_sort_seqbase(SEQ_active_seqbase_get(ed)); } typedef struct SeqUniqueInfo { @@ -612,3 +630,25 @@ int SEQ_recursive_apply(Sequence *seq, int (*apply_fn)(Sequence *, void *), void return ret; } + +/** + * Ensure, that provided Sequence has unique name. If animation data exists for this Sequence, it + * will be duplicated and mapped onto new name + * + * \param seq: Sequence which name will be ensured to be unique + * \param scene: Scene in which name must be unique + */ +void SEQ_ensure_unique_name(Sequence *seq, Scene *scene) +{ + char name[SEQ_NAME_MAXSTR]; + + BLI_strncpy_utf8(name, seq->name + 2, sizeof(name)); + SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); + SEQ_dupe_animdata(scene, name, seq->name + 2); + + if (seq->type == SEQ_TYPE_META) { + LISTBASE_FOREACH (Sequence *, seq_child, &seq->seqbase) { + SEQ_ensure_unique_name(seq_child, scene); + } + } +} diff --git a/source/blender/sequencer/intern/utils.h b/source/blender/sequencer/intern/utils.h index 97f33bb3ae0..0ec78a6cfa5 100644 --- a/source/blender/sequencer/intern/utils.h +++ b/source/blender/sequencer/intern/utils.h @@ -34,6 +34,7 @@ void seq_open_anim_file(struct Scene *scene, struct Sequence *seq, bool openfile struct Sequence *seq_find_metastrip_by_sequence(ListBase *seqbase /* = ed->seqbase */, struct Sequence *meta /* = NULL */, struct Sequence *seq); +void seq_sort_seqbase(ListBase *seqbase); #ifdef __cplusplus } |