diff options
Diffstat (limited to 'source/blender/sequencer/intern/strip_edit.c')
-rw-r--r-- | source/blender/sequencer/intern/strip_edit.c | 196 |
1 files changed, 82 insertions, 114 deletions
diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index 96bfce8f740..15c472dd5a7 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -37,11 +37,11 @@ #include "SEQ_transform.h" #include "SEQ_utils.h" -int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str) +int SEQ_edit_sequence_swap(Scene *scene, Sequence *seq_a, Sequence *seq_b, const char **error_str) { char name[sizeof(seq_a->name)]; - if (seq_a->len != seq_b->len) { + if (SEQ_time_strip_length_get(scene, seq_a) != SEQ_time_strip_length_get(scene, seq_b)) { *error_str = N_("Strips must be the same length"); return 0; } @@ -80,12 +80,12 @@ int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_ SWAP(Sequence *, seq_a->prev, seq_b->prev); SWAP(Sequence *, seq_a->next, seq_b->next); - SWAP(int, seq_a->start, seq_b->start); - SWAP(int, seq_a->startofs, seq_b->startofs); - SWAP(int, seq_a->endofs, seq_b->endofs); + SWAP(float, seq_a->start, seq_b->start); + SWAP(float, seq_a->startofs, seq_b->startofs); + SWAP(float, seq_a->endofs, seq_b->endofs); SWAP(int, seq_a->machine, seq_b->machine); - SWAP(int, seq_a->startdisp, seq_b->startdisp); - SWAP(int, seq_a->enddisp, seq_b->enddisp); + seq_time_effect_range_set(scene, seq_a); + seq_time_effect_range_set(scene, seq_b); return 1; } @@ -192,19 +192,6 @@ void SEQ_edit_remove_flagged_sequences(Scene *scene, ListBase *seqbase) } } -static bool seq_exists_in_seqbase(Sequence *seq, ListBase *seqbase) -{ - LISTBASE_FOREACH (Sequence *, seq_test, seqbase) { - if (seq_test->type == SEQ_TYPE_META && seq_exists_in_seqbase(seq, &seq_test->seqbase)) { - return true; - } - if (seq_test == seq) { - return true; - } - } - return false; -} - bool SEQ_edit_move_strip_to_seqbase(Scene *scene, ListBase *seqbase, Sequence *seq, @@ -216,7 +203,7 @@ bool SEQ_edit_move_strip_to_seqbase(Scene *scene, SEQ_relations_invalidate_cache_preprocessed(scene, seq); /* Update meta. */ - if (SEQ_transform_test_overlap(dst_seqbase, seq)) { + if (SEQ_transform_test_overlap(scene, dst_seqbase, seq)) { SEQ_transform_seqbase_shuffle(dst_seqbase, seq, scene); } @@ -230,7 +217,7 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene, { /* Find the appropriate seqbase */ Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, src_seq); + ListBase *seqbase = SEQ_get_seqbase_by_seq(scene, src_seq); if (dst_seqm->type != SEQ_TYPE_META) { *error_str = N_("Can not move strip to non-meta strip"); @@ -247,19 +234,19 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene, return false; } - if (src_seq->type == SEQ_TYPE_META && seq_exists_in_seqbase(dst_seqm, &src_seq->seqbase)) { + if (src_seq->type == SEQ_TYPE_META && SEQ_exists_in_seqbase(dst_seqm, &src_seq->seqbase)) { *error_str = N_("Moved strip is parent of provided meta strip"); return false; } - if (!seq_exists_in_seqbase(dst_seqm, &ed->seqbase)) { + if (!SEQ_exists_in_seqbase(dst_seqm, &ed->seqbase)) { *error_str = N_("Can not move strip to different scene"); return false; } SeqCollection *collection = SEQ_collection_create(__func__); SEQ_collection_append_strip(src_seq, collection); - SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain); + SEQ_collection_expand(scene, seqbase, collection, SEQ_query_strip_effect_chain); Sequence *seq; SEQ_ITERATOR_FOREACH (seq, collection) { @@ -272,138 +259,126 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene, return true; } -static void seq_split_set_left_hold_offset(Sequence *seq, int timeline_frame) +static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int timeline_frame) { /* Adjust within range of extended stillframes before strip. */ if (timeline_frame < seq->start) { - SEQ_time_left_handle_frame_set(seq, timeline_frame); - } - /* Adjust within range of strip contents. */ - else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) { - seq->anim_startofs += timeline_frame - seq->start; - seq->start = timeline_frame; - seq->startofs = 0; - } - /* Adjust within range of extended stillframes after strip. */ - else if ((seq->start + seq->len) < timeline_frame) { - const int right_handle_backup = SEQ_time_right_handle_frame_get(seq); - seq->start += timeline_frame - seq->start; - seq->anim_startofs += seq->len - 1; - seq->len = 1; - SEQ_time_left_handle_frame_set(seq, timeline_frame); - SEQ_time_right_handle_frame_set(seq, right_handle_backup); - } -} - -static void seq_split_set_right_hold_offset(Sequence *seq, int timeline_frame) -{ - /* Adjust within range of extended stillframes before strip. */ - if (timeline_frame < seq->start) { - const int left_handle_backup = SEQ_time_left_handle_frame_get(seq); seq->start = timeline_frame - 1; - SEQ_time_left_handle_frame_set(seq, left_handle_backup); - SEQ_time_right_handle_frame_set(seq, timeline_frame); + seq->anim_endofs += SEQ_time_strip_length_get(scene, seq) - 1; + seq->startstill = timeline_frame - seq->startdisp - 1; + seq->endstill = 0; } /* Adjust within range of strip contents. */ - else if ((timeline_frame >= seq->start) && (timeline_frame <= (seq->start + seq->len))) { - seq->anim_endofs += seq->start + seq->len - timeline_frame; + else if ((timeline_frame >= seq->start) && + (timeline_frame <= (seq->start + SEQ_time_strip_length_get(scene, seq)))) { seq->endofs = 0; + seq->endstill = 0; + seq->anim_endofs += (seq->start + SEQ_time_strip_length_get(scene, seq)) - timeline_frame; } /* Adjust within range of extended stillframes after strip. */ - else if ((seq->start + seq->len) < timeline_frame) { - SEQ_time_right_handle_frame_set(seq, timeline_frame); + else if ((seq->start + SEQ_time_strip_length_get(scene, seq)) < timeline_frame) { + seq->endstill = timeline_frame - seq->start - SEQ_time_strip_length_get(scene, seq); } } -static void seq_split_set_right_offset(Sequence *seq, int timeline_frame) +static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int timeline_frame) { /* Adjust within range of extended stillframes before strip. */ if (timeline_frame < seq->start) { - const int content_offset = seq->start - timeline_frame + 1; - seq->start = timeline_frame - 1; - seq->startofs += content_offset; + seq->startstill = seq->start - timeline_frame; + } + /* Adjust within range of strip contents. */ + else if ((timeline_frame >= seq->start) && + (timeline_frame <= (seq->start + SEQ_time_strip_length_get(scene, seq)))) { + seq->anim_startofs += timeline_frame - seq->start; + seq->start = timeline_frame; + seq->startstill = 0; + seq->startofs = 0; } - - SEQ_time_right_handle_frame_set(seq, timeline_frame); -} - -static void seq_split_set_left_offset(Sequence *seq, int timeline_frame) -{ /* Adjust within range of extended stillframes after strip. */ - if (timeline_frame > seq->start + seq->len) { - const int content_offset = timeline_frame - (seq->start + seq->len) + 1; - seq->start += content_offset; - seq->endofs += content_offset; + else if ((seq->start + SEQ_time_strip_length_get(scene, seq)) < timeline_frame) { + seq->start = timeline_frame; + seq->startofs = 0; + seq->anim_startofs += SEQ_time_strip_length_get(scene, seq) - 1; + seq->endstill = seq->enddisp - timeline_frame - 1; + seq->startstill = 0; } - - SEQ_time_left_handle_frame_set(seq, timeline_frame); } -static bool seq_edit_split_effect_intersect_check(const Sequence *seq, const int timeline_frame) +static bool seq_edit_split_effect_intersect_check(const Scene *scene, + const Sequence *seq, + const int timeline_frame) { - return timeline_frame > seq->startdisp && timeline_frame < seq->enddisp; + return timeline_frame > SEQ_time_left_handle_frame_get(scene, seq) && + timeline_frame < SEQ_time_right_handle_frame_get(scene, seq); } static void seq_edit_split_handle_strip_offsets(Main *bmain, Scene *scene, - ListBase *seqbase, Sequence *left_seq, Sequence *right_seq, const int timeline_frame, const eSeqSplitMethod method) { - if (seq_edit_split_effect_intersect_check(right_seq, timeline_frame)) { + if (seq_edit_split_effect_intersect_check(scene, right_seq, timeline_frame)) { switch (method) { case SEQ_SPLIT_SOFT: - seq_split_set_left_offset(right_seq, timeline_frame); + SEQ_time_left_handle_frame_set(scene, right_seq, timeline_frame); break; case SEQ_SPLIT_HARD: - seq_split_set_left_hold_offset(right_seq, timeline_frame); + seq_split_set_left_hold_offset(scene, right_seq, timeline_frame); SEQ_add_reload_new_file(bmain, scene, right_seq, false); break; } - SEQ_time_update_sequence(scene, seqbase, right_seq); } - if (seq_edit_split_effect_intersect_check(left_seq, timeline_frame)) { + if (seq_edit_split_effect_intersect_check(scene, left_seq, timeline_frame)) { switch (method) { case SEQ_SPLIT_SOFT: - seq_split_set_right_offset(left_seq, timeline_frame); + SEQ_time_right_handle_frame_set(scene, left_seq, timeline_frame); break; case SEQ_SPLIT_HARD: - seq_split_set_right_hold_offset(left_seq, timeline_frame); + seq_split_set_right_hold_offset(scene, left_seq, timeline_frame); SEQ_add_reload_new_file(bmain, scene, left_seq, false); break; } - SEQ_time_update_sequence(scene, seqbase, left_seq); } } -static bool seq_edit_split_effect_inputs_intersect(const Sequence *seq, const int timeline_frame) +static bool seq_edit_split_effect_inputs_intersect(const Scene *scene, + const Sequence *seq, + const int timeline_frame) { bool input_does_intersect = false; if (seq->seq1) { - input_does_intersect |= seq_edit_split_effect_intersect_check(seq->seq1, timeline_frame); + input_does_intersect |= seq_edit_split_effect_intersect_check( + scene, seq->seq1, timeline_frame); if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) { - input_does_intersect |= seq_edit_split_effect_inputs_intersect(seq->seq1, timeline_frame); + input_does_intersect |= seq_edit_split_effect_inputs_intersect( + scene, seq->seq1, timeline_frame); } } if (seq->seq2) { - input_does_intersect |= seq_edit_split_effect_intersect_check(seq->seq2, timeline_frame); + input_does_intersect |= seq_edit_split_effect_intersect_check( + scene, seq->seq2, timeline_frame); if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) { - input_does_intersect |= seq_edit_split_effect_inputs_intersect(seq->seq2, timeline_frame); + input_does_intersect |= seq_edit_split_effect_inputs_intersect( + scene, seq->seq2, timeline_frame); } } if (seq->seq3) { - input_does_intersect |= seq_edit_split_effect_intersect_check(seq->seq3, timeline_frame); + input_does_intersect |= seq_edit_split_effect_intersect_check( + scene, seq->seq3, timeline_frame); if ((seq->seq1->type & SEQ_TYPE_EFFECT) != 0) { - input_does_intersect |= seq_edit_split_effect_inputs_intersect(seq->seq3, timeline_frame); + input_does_intersect |= seq_edit_split_effect_inputs_intersect( + scene, seq->seq3, timeline_frame); } } return input_does_intersect; } -static bool seq_edit_split_operation_permitted_check(SeqCollection *strips, +static bool seq_edit_split_operation_permitted_check(const Scene *scene, + SeqCollection *strips, const int timeline_frame, const char **r_error) { @@ -412,7 +387,7 @@ static bool seq_edit_split_operation_permitted_check(SeqCollection *strips, if ((seq->type & SEQ_TYPE_EFFECT) == 0) { continue; } - if (!seq_edit_split_effect_intersect_check(seq, timeline_frame)) { + if (!seq_edit_split_effect_intersect_check(scene, seq, timeline_frame)) { continue; } if (SEQ_effect_get_num_inputs(seq->type) <= 1) { @@ -422,7 +397,7 @@ static bool seq_edit_split_operation_permitted_check(SeqCollection *strips, *r_error = "Splitting transition effect is not permitted."; return false; } - if (!seq_edit_split_effect_inputs_intersect(seq, timeline_frame)) { + if (!seq_edit_split_effect_inputs_intersect(scene, seq, timeline_frame)) { *r_error = "Effect inputs don't overlap. Can not split such effect."; return false; } @@ -438,16 +413,16 @@ Sequence *SEQ_edit_strip_split(Main *bmain, const eSeqSplitMethod method, const char **r_error) { - if (!seq_edit_split_effect_intersect_check(seq, timeline_frame)) { + if (!seq_edit_split_effect_intersect_check(scene, seq, timeline_frame)) { return NULL; } /* Whole strip chain must be duplicated in order to preserve relationships. */ SeqCollection *collection = SEQ_collection_create(__func__); SEQ_collection_append_strip(seq, collection); - SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain); + SEQ_collection_expand(scene, seqbase, collection, SEQ_query_strip_effect_chain); - if (!seq_edit_split_operation_permitted_check(collection, timeline_frame, r_error)) { + if (!seq_edit_split_operation_permitted_check(scene, collection, timeline_frame, r_error)) { SEQ_collection_free(collection); return NULL; } @@ -468,10 +443,6 @@ Sequence *SEQ_edit_strip_split(Main *bmain, SEQ_collection_free(collection); - /* Sort list, so that no strip can depend on next strip in list. - * This is important for SEQ_time_update_sequence functionality. */ - SEQ_sort(&left_strips); - /* Duplicate ListBase. */ ListBase right_strips = {NULL, NULL}; SEQ_sequence_base_dupli_recursive(scene, scene, &right_strips, &left_strips, SEQ_DUPE_ALL, 0); @@ -480,18 +451,23 @@ Sequence *SEQ_edit_strip_split(Main *bmain, Sequence *right_seq = right_strips.first; Sequence *return_seq = NULL; - /* Move strips from detached `ListBase`, otherwise they can't be flagged for removal, - * SEQ_time_update_sequence can fail to update meta strips and they can't be renamed. - * This is because these functions check all strips in `Editing` to manage relationships. */ + /* Move strips from detached `ListBase`, otherwise they can't be flagged for removal. */ BLI_movelisttolist(seqbase, &left_strips); BLI_movelisttolist(seqbase, &right_strips); + /* Rename duplicated strips. This has to be done immediately after adding + * strips to seqbase, for lookup cache to work correctly. */ + Sequence *seq_rename = right_seq; + for (; seq_rename; seq_rename = seq_rename->next) { + SEQ_ensure_unique_name(seq_rename, scene); + } + /* Split strips. */ while (left_seq && right_seq) { - if (left_seq->startdisp >= timeline_frame) { + if (SEQ_time_left_handle_frame_get(scene, left_seq) >= timeline_frame) { SEQ_edit_flag_for_removal(scene, seqbase, left_seq); } - if (right_seq->enddisp <= timeline_frame) { + else if (SEQ_time_right_handle_frame_get(scene, right_seq) <= timeline_frame) { SEQ_edit_flag_for_removal(scene, seqbase, right_seq); } else if (return_seq == NULL) { @@ -499,20 +475,12 @@ Sequence *SEQ_edit_strip_split(Main *bmain, return_seq = right_seq; } - seq_edit_split_handle_strip_offsets( - bmain, scene, seqbase, left_seq, right_seq, timeline_frame, method); + 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; } SEQ_edit_remove_flagged_sequences(scene, seqbase); - - /* Rename duplicated strips. */ - Sequence *seq_rename = return_seq; - for (; seq_rename; seq_rename = seq_rename->next) { - SEQ_ensure_unique_name(seq_rename, scene); - } - SEQ_animation_restore_original(scene, &fcurves_original_backup); return return_seq; |