Changeset View
Changeset View
Standalone View
Standalone View
source/blender/sequencer/intern/strip_edit.c
| Show All 33 Lines | |||||
| #include "BLT_translation.h" | #include "BLT_translation.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_movieclip.h" | #include "BKE_movieclip.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "BKE_sound.h" | #include "BKE_sound.h" | ||||
| #include "strip_time.h" | #include "strip_time.h" | ||||
| #include "utils.h" | |||||
| #include "SEQ_add.h" | #include "SEQ_add.h" | ||||
| #include "SEQ_edit.h" | #include "SEQ_edit.h" | ||||
| #include "SEQ_effects.h" | #include "SEQ_effects.h" | ||||
| #include "SEQ_iterator.h" | |||||
| #include "SEQ_relations.h" | #include "SEQ_relations.h" | ||||
| #include "SEQ_sequencer.h" | #include "SEQ_sequencer.h" | ||||
| #include "SEQ_time.h" | #include "SEQ_time.h" | ||||
| #include "SEQ_transform.h" | #include "SEQ_transform.h" | ||||
| #include "SEQ_utils.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(Sequence *seq_a, Sequence *seq_b, const char **error_str) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 284 Lines • ▼ Show 20 Lines | static void seq_split_set_left_offset(Sequence *seq, int timeline_frame) | ||||
| /* Adjust within range of extended stillframes after strip. */ | /* Adjust within range of extended stillframes after strip. */ | ||||
| if ((seq->start + seq->len) < timeline_frame) { | if ((seq->start + seq->len) < timeline_frame) { | ||||
| seq->start = timeline_frame - seq->len + 1; | seq->start = timeline_frame - seq->len + 1; | ||||
| seq->endstill = seq->enddisp - timeline_frame - 1; | seq->endstill = seq->enddisp - timeline_frame - 1; | ||||
| } | } | ||||
| SEQ_transform_set_left_handle_frame(seq, 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. | * Split Sequence at timeline_frame in two. | ||||
| * | * | ||||
| * \param bmain: Main in which Sequence is located | * \param bmain: Main in which Sequence is located | ||||
| * \param scene: Scene in which Sequence is located | * \param scene: Scene in which Sequence is located | ||||
| * \param seqbase: ListBase in which Sequence is located | * \param seqbase: ListBase in which Sequence is located | ||||
| * \param seq: Sequence to be split | * \param seq: Sequence to be split | ||||
| * \param timeline_frame: frame at which seq is split. | * \param timeline_frame: frame at which seq is split. | ||||
| * \param method: affects type of offset to be applied to resize Sequence | * \param method: affects type of offset to be applied to resize Sequence | ||||
| * \return The newly created sequence strip. This is always Sequence on right side. | * \return The newly created sequence strip. This is always Sequence on right side. | ||||
| */ | */ | ||||
| Sequence *SEQ_edit_strip_split(Main *bmain, | Sequence *SEQ_edit_strip_split(Main *bmain, | ||||
| Scene *scene, | Scene *scene, | ||||
| ListBase *seqbase, | ListBase *seqbase, | ||||
| Sequence *seq, | Sequence *seq, | ||||
| const int timeline_frame, | const int timeline_frame, | ||||
| const eSeqSplitMethod method) | const eSeqSplitMethod method) | ||||
| { | { | ||||
| if (timeline_frame <= seq->startdisp || timeline_frame >= seq->enddisp) { | if (timeline_frame <= seq->startdisp || timeline_frame >= seq->enddisp) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if (method == SEQ_SPLIT_HARD) { | SeqCollection *collection = SEQ_collection_create(); | ||||
| /* Precaution, needed because the length saved on-disk may not match the length saved in the | SEQ_collection_append_strip(seq, collection); | ||||
| * blend file, or our code may have minor differences reading file length between versions. | SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain); | ||||
| * This causes hard-split to fail, see: T47862. */ | |||||
| SEQ_add_reload_new_file(bmain, scene, seq, true); | /* Move strips in collection from seqbase to new ListBase. */ | ||||
| SEQ_time_update_sequence(scene, seq); | ListBase left_strips = {NULL, NULL}; | ||||
| SEQ_ITERATOR_FOREACH (seq, collection) { | |||||
| BLI_remlink(seqbase, seq); | |||||
| BLI_addtail(&left_strips, seq); | |||||
| } | } | ||||
| Sequence *left_seq = seq; | /* Sort list, so that no strip can depend on next strip in list. | ||||
| Sequence *right_seq = SEQ_sequence_dupli_recursive( | * This is important for SEQ_time_update_sequence functionality. */ | ||||
| scene, scene, seqbase, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); | seq_sort_ex(&left_strips); | ||||
| switch (method) { | /* Duplicate ListBase. */ | ||||
| case SEQ_SPLIT_SOFT: | ListBase right_strips = {NULL, NULL}; | ||||
| seq_split_set_left_offset(right_seq, timeline_frame); | SEQ_sequence_base_dupli_recursive( | ||||
| seq_split_set_right_offset(left_seq, timeline_frame); | scene, scene, &right_strips, &left_strips, SEQ_DUPE_ANIM | SEQ_DUPE_ALL, 0); | ||||
| break; | |||||
| case SEQ_SPLIT_HARD: | /* Split strips. */ | ||||
| seq_split_set_right_hold_offset(left_seq, timeline_frame); | Sequence *left_seq = left_strips.first; | ||||
| seq_split_set_left_hold_offset(right_seq, timeline_frame); | Sequence *right_seq = right_strips.first; | ||||
| SEQ_add_reload_new_file(bmain, scene, left_seq, false); | Sequence *return_seq = right_strips.first; | ||||
| SEQ_add_reload_new_file(bmain, scene, right_seq, false); | while (left_seq && right_seq) { | ||||
| break; | 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_time_update_sequence(scene, left_seq); | |||||
| SEQ_time_update_sequence(scene, right_seq); | /* Move strips back to seqbase. Move right strips first, so left strips don't change name. */ | ||||
| return right_seq; | BLI_movelisttolist(seqbase, &right_strips); | ||||
| BLI_movelisttolist(seqbase, &left_strips); | |||||
| LISTBASE_FOREACH (Sequence *, seq, seqbase) { | |||||
sergey: Declaration of `seq` here shadows a parameter. | |||||
| SEQ_recursive_apply(seq, SEQ_apply_unique_name_fn, scene); | |||||
| } | |||||
| return return_seq; | |||||
| } | } | ||||
| /** | /** | ||||
| * Find gap after initial_frame and move strips on right side to close the gap | * Find gap after initial_frame and move strips on right side to close the gap | ||||
| * | * | ||||
| * \param scene: Scene in which strips are located | * \param scene: Scene in which strips are located | ||||
| * \param seqbase: ListBase in which strips are located | * \param seqbase: ListBase in which strips are located | ||||
| * \param initial_frame: frame on timeline from where gaps are searched for | * \param initial_frame: frame on timeline from where gaps are searched for | ||||
| Show All 28 Lines | |||||
Declaration of seq here shadows a parameter.