diff options
author | Richard Antalik <richardantalik@gmail.com> | 2021-08-27 13:59:46 +0300 |
---|---|---|
committer | Richard Antalik <richardantalik@gmail.com> | 2021-08-27 13:59:46 +0300 |
commit | 59cd9c6da682675c439731781d127b1b02f12a76 (patch) | |
tree | be3547652d6e9bf2e4051dbd54a71b771ec5afad | |
parent | 7f7370fa26fbe8597cbb9832755f854fd4a8d0e5 (diff) |
VSE: Transform overwrite mode
Add mode to overwrite strips on overlap instead of resolving overlap.
When overlap is created, 3 things can happen:
- On partial overlap, handles of overlapped strip are moved
- On complete overlap with smaller strip, overlapped strip is split
- On complete overlap with larger strip, overlapped strip is removed
This mode can be enabled in header.
Reviewed By: fsiddi, mano-wii
Differential Revision: https://developer.blender.org/D11805
-rw-r--r-- | release/scripts/startup/bl_ui/space_sequencer.py | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_blender_version.h | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_300.c | 31 | ||||
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_draw.c | 9 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_convert_sequencer.c | 220 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_mode_edge_seq_slide.c | 25 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 9 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 20 | ||||
-rw-r--r-- | source/blender/sequencer/SEQ_iterator.h | 11 | ||||
-rw-r--r-- | source/blender/sequencer/SEQ_sequencer.h | 1 | ||||
-rw-r--r-- | source/blender/sequencer/SEQ_transform.h | 1 | ||||
-rw-r--r-- | source/blender/sequencer/intern/iterator.c | 18 | ||||
-rw-r--r-- | source/blender/sequencer/intern/sequencer.c | 8 | ||||
-rw-r--r-- | source/blender/sequencer/intern/strip_transform.c | 6 |
14 files changed, 286 insertions, 78 deletions
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 20fb39e8c1f..79c1cb973ca 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -150,6 +150,9 @@ class SEQUENCER_HT_header(Header): if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}: tool_settings = context.tool_settings + sequencer_tool_settings = tool_settings.sequencer_tool_settings + row = layout.row(align=True) + row.prop(sequencer_tool_settings, "overlap_mode", text="") row = layout.row(align=True) row.prop(tool_settings, "use_snap_sequencer", text="") sub = row.row(align=True) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 4ed4225c836..315a77499e5 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -39,7 +39,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 18 +#define BLENDER_FILE_SUBVERSION 19 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index 72572b05ef6..aee6d798799 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -776,18 +776,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - /** - * Versioning code until next subversion bump goes here. - * - * \note Be sure to check when bumping the version: - * - "versioning_userdef.c", #blo_do_versions_userdef - * - "versioning_userdef.c", #do_versions_theme - * - * \note Keep this message at the bottom of the function. - */ - { - /* Keep this block, even when empty. */ - + if (!MAIN_VERSION_ATLEAST(bmain, 300, 19)) { /* Add node storage for subdivision surface node. */ FOREACH_NODETREE_BEGIN (bmain, ntree, id) { if (ntree->type == NTREE_GEOMETRY) { @@ -818,5 +807,23 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + SequencerToolSettings *sequencer_tool_settings = SEQ_tool_settings_ensure(scene); + sequencer_tool_settings->overlap_mode = SEQ_OVERLAP_SHUFFLE; + } + } + + /** + * Versioning code until next subversion bump goes here. + * + * \note Be sure to check when bumping the version: + * - "versioning_userdef.c", #blo_do_versions_userdef + * - "versioning_userdef.c", #do_versions_theme + * + * \note Keep this message at the bottom of the function. + */ + { + /* Keep this block, even when empty. */ } } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index b3c39e2fa6f..fe3ff469e50 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -737,7 +737,8 @@ static void draw_seq_handle(View2D *v2d, } } -static void draw_seq_outline(Sequence *seq, +static void draw_seq_outline(Scene *scene, + Sequence *seq, uint pos, float x1, float x2, @@ -765,7 +766,9 @@ static void draw_seq_outline(Sequence *seq, * - Slightly lighter. * - Red when overlapping with other strips. */ - if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT)) { + const eSeqOverlapMode overlap_mode = SEQ_tool_settings_overlap_mode_get(scene); + if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT) && + overlap_mode != SEQ_OVERLAP_OVERWRITE) { if (seq->flag & SEQ_OVERLAP) { col[0] = 255; col[1] = col[2] = 33; @@ -1383,7 +1386,7 @@ static void draw_seq_strip(const bContext *C, v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE, pos, seq_active, pixelx, y_threshold); } - draw_seq_outline(seq, pos, x1, x2, y1, y2, pixelx, pixely, seq_active); + draw_seq_outline(scene, seq, pos, x1, x2, y1, y2, pixelx, pixely, seq_active); immUnbindProgram(); diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 45ed0f3b664..9548498f0b8 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -29,10 +29,13 @@ #include "BLI_math.h" #include "BKE_context.h" +#include "BKE_main.h" #include "BKE_report.h" #include "ED_markers.h" +#include "SEQ_edit.h" +#include "SEQ_effects.h" #include "SEQ_iterator.h" #include "SEQ_relations.h" #include "SEQ_sequencer.h" @@ -341,12 +344,17 @@ static bool seq_transform_check_strip_effects(SeqCollection *transformed_strips) return false; } +static ListBase *seqbase_active_get(const TransInfo *t) +{ + Editing *ed = SEQ_editing_get(t->scene, false); + return SEQ_active_seqbase_get(ed); +} + /* Offset all strips positioned after left edge of transformed strips boundbox by amount equal * to overlap of transformed strips. */ static void seq_transform_handle_expand_to_fit(TransInfo *t, SeqCollection *transformed_strips) { - Editing *ed = SEQ_editing_get(t->scene, false); - ListBase *seqbasep = SEQ_active_seqbase_get(ed); + ListBase *seqbasep = seqbase_active_get(t); ListBase *markers = &t->scene->markers; const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag & SEQ_MARKER_TRANS) != 0; @@ -378,23 +386,178 @@ static void seq_transform_handle_expand_to_fit(TransInfo *t, SeqCollection *tran SEQ_collection_free(right_side_strips); } -static void seq_transform_handle_overlap(TransInfo *t, SeqCollection *transformed_strips) +static SeqCollection *query_overwrite_targets(const TransInfo *t, + SeqCollection *transformed_strips) { - Editing *ed = SEQ_editing_get(t->scene, false); - ListBase *seqbasep = SEQ_active_seqbase_get(ed); + SeqCollection *collection = SEQ_query_unselected_strips(seqbase_active_get(t)); + + Sequence *seq, *seq_transformed; + SEQ_ITERATOR_FOREACH (seq, collection) { + bool does_overlap = false; - if (t->flag & T_ALT_TRANSFORM) { - seq_transform_handle_expand_to_fit(t, transformed_strips); + SEQ_ITERATOR_FOREACH (seq_transformed, transformed_strips) { + /* Effects of transformed strips can be unselected. These must not be included. */ + if (seq == seq_transformed) { + SEQ_collection_remove_strip(seq, collection); + } + if (SEQ_transform_test_overlap_seq_seq(seq, seq_transformed)) { + does_overlap = true; + } + } + + if (!does_overlap) { + SEQ_collection_remove_strip(seq, collection); + } } - else { - ListBase *markers = &t->scene->markers; - const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag & - SEQ_MARKER_TRANS) != 0; - /* Shuffle non strips with no effects attached. */ - SeqCollection *standalone_strips = extract_standalone_strips(transformed_strips); - SEQ_transform_seqbase_shuffle_time( - standalone_strips, seqbasep, t->scene, markers, use_sync_markers); - SEQ_collection_free(standalone_strips); + + return collection; +} + +typedef enum eOvelapDescrition { + /* No overlap. */ + STRIP_OVERLAP_NONE, + /* Overlapping strip covers overlapped completely. */ + STRIP_OVERLAP_IS_FULL, + /* Overlapping strip is inside overlapped. */ + STRIP_OVERLAP_IS_INSIDE, + /* Partial overlap between 2 strips. */ + STRIP_OVERLAP_LEFT_SIDE, + STRIP_OVERLAP_RIGHT_SIDE, +} eOvelapDescrition; + +static eOvelapDescrition overlap_description_get(const Sequence *transformed, + const Sequence *target) +{ + if (transformed->startdisp <= target->startdisp && transformed->enddisp >= target->enddisp) { + return STRIP_OVERLAP_IS_FULL; + } + if (transformed->startdisp > target->startdisp && transformed->enddisp < target->enddisp) { + return STRIP_OVERLAP_IS_INSIDE; + } + if (transformed->startdisp <= target->startdisp && target->startdisp <= transformed->enddisp) { + return STRIP_OVERLAP_LEFT_SIDE; + } + if (transformed->startdisp <= target->enddisp && target->enddisp <= transformed->enddisp) { + return STRIP_OVERLAP_RIGHT_SIDE; + } + return STRIP_OVERLAP_NONE; +} + +/* Split strip in 3 parts, remove middle part and fit transformed inside. */ +static void seq_transform_handle_overwrite_split(const TransInfo *t, + const Sequence *transformed, + Sequence *target) +{ + Main *bmain = CTX_data_main(t->context); + Scene *scene = t->scene; + ListBase *seqbase = seqbase_active_get(t); + + Sequence *split_strip = SEQ_edit_strip_split( + bmain, scene, seqbase, target, transformed->startdisp, SEQ_SPLIT_SOFT, NULL); + SEQ_edit_strip_split( + bmain, scene, seqbase, split_strip, transformed->enddisp, SEQ_SPLIT_SOFT, NULL); + SEQ_edit_flag_for_removal(scene, seqbase_active_get(t), split_strip); +} + +/* Trim strips by adjusting handle position. + * This is bit more complicated in case overlap happens on effect. */ +static void seq_transform_handle_overwrite_trim(const TransInfo *t, + const Sequence *transformed, + Sequence *target, + const eOvelapDescrition overlap) +{ + SeqCollection *targets = SEQ_query_by_reference( + target, seqbase_active_get(t), SEQ_query_strip_effect_chain); + + /* Expand collection by adding all target's children, effects and their children. */ + if ((target->type & SEQ_TYPE_EFFECT) != 0) { + SEQ_collection_expand(seqbase_active_get(t), targets, SEQ_query_strip_effect_chain); + } + + /* Trim all non effects, that have influence on effect length which is overlapping. */ + Sequence *seq; + SEQ_ITERATOR_FOREACH (seq, targets) { + if ((seq->type & SEQ_TYPE_EFFECT) != 0 && SEQ_effect_get_num_inputs(seq->type) > 0) { + continue; + } + if (overlap == STRIP_OVERLAP_LEFT_SIDE) { + SEQ_transform_set_left_handle_frame(seq, transformed->enddisp); + } + else { + BLI_assert(overlap == STRIP_OVERLAP_RIGHT_SIDE); + SEQ_transform_set_right_handle_frame(seq, transformed->startdisp); + } + SEQ_time_update_sequence(t->scene, seq); + } + SEQ_collection_free(targets); +} + +static void seq_transform_handle_overwrite(const TransInfo *t, SeqCollection *transformed_strips) +{ + SeqCollection *targets = query_overwrite_targets(t, transformed_strips); + + bool strips_delete = false; + Sequence *target; + Sequence *transformed; + SEQ_ITERATOR_FOREACH (target, targets) { + SEQ_ITERATOR_FOREACH (transformed, transformed_strips) { + if (transformed->machine != target->machine) { + continue; + } + + const eOvelapDescrition overlap = overlap_description_get(transformed, target); + + if (overlap == STRIP_OVERLAP_IS_FULL) { + /* Remove covered strip. */ + SEQ_edit_flag_for_removal(t->scene, seqbase_active_get(t), target); + strips_delete = true; + } + else if (overlap == STRIP_OVERLAP_IS_INSIDE) { + seq_transform_handle_overwrite_split(t, transformed, target); + strips_delete = true; + } + else if (ELEM(overlap, STRIP_OVERLAP_LEFT_SIDE, STRIP_OVERLAP_RIGHT_SIDE)) { + seq_transform_handle_overwrite_trim(t, transformed, target, overlap); + } + } + } + + SEQ_collection_free(targets); + + if (strips_delete) { + SEQ_edit_remove_flagged_sequences(t->scene, seqbase_active_get(t)); + } +} + +static void seq_transform_handle_overlap_shuffle(const TransInfo *t, + SeqCollection *transformed_strips) +{ + ListBase *seqbase = seqbase_active_get(t); + ListBase *markers = &t->scene->markers; + const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag & + SEQ_MARKER_TRANS) != 0; + /* Shuffle non strips with no effects attached. */ + SeqCollection *standalone_strips = extract_standalone_strips(transformed_strips); + SEQ_transform_seqbase_shuffle_time( + standalone_strips, seqbase, t->scene, markers, use_sync_markers); + SEQ_collection_free(standalone_strips); +} + +static void seq_transform_handle_overlap(TransInfo *t, SeqCollection *transformed_strips) +{ + ListBase *seqbasep = seqbase_active_get(t); + const eSeqOverlapMode overlap_mode = SEQ_tool_settings_overlap_mode_get(t->scene); + + switch (overlap_mode) { + case SEQ_OVERLAP_EXPAND: + seq_transform_handle_expand_to_fit(t, transformed_strips); + break; + case SEQ_OVERLAP_OVERWRITE: + seq_transform_handle_overwrite(t, transformed_strips); + break; + case SEQ_OVERLAP_SHUFFLE: + seq_transform_handle_overlap_shuffle(t, transformed_strips); + break; } if (seq_transform_check_strip_effects(transformed_strips)) { @@ -409,6 +572,7 @@ static void seq_transform_handle_overlap(TransInfo *t, SeqCollection *transforme if (SEQ_transform_test_overlap(seqbasep, seq)) { SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene); } + seq->flag &= ~SEQ_OVERLAP; } } @@ -432,6 +596,7 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c } SeqCollection *transformed_strips = seq_transform_collection_from_transdata(tc); + SEQ_collection_expand(seqbase_active_get(t), transformed_strips, SEQ_query_strip_effect_chain); if (t->state == TRANS_CANCEL) { seq_transform_cancel(t, transformed_strips); @@ -549,7 +714,7 @@ BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int s static void flushTransSeq(TransInfo *t) { /* Editing null check already done */ - ListBase *seqbasep = SEQ_editing_get(t->scene, false)->seqbasep; + ListBase *seqbasep = seqbase_active_get(t); int a, new_frame; TransData *td = NULL; @@ -601,22 +766,17 @@ static void flushTransSeq(TransInfo *t) /* need to do the overlap check in a new loop otherwise adjacent strips * will not be updated and we'll get false positives */ - Sequence *seq_prev = NULL; - seq_prev = NULL; - for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) { - - tdsq = (TransDataSeq *)td->extra; - seq = tdsq->seq; + SeqCollection *transformed_strips = seq_transform_collection_from_transdata(tc); + SEQ_collection_expand(seqbase_active_get(t), transformed_strips, SEQ_query_strip_effect_chain); - if (seq != seq_prev) { - /* test overlap, displays red outline */ - seq->flag &= ~SEQ_OVERLAP; - if (SEQ_transform_test_overlap(seqbasep, seq)) { - seq->flag |= SEQ_OVERLAP; - } + SEQ_ITERATOR_FOREACH (seq, transformed_strips) { + /* test overlap, displays red outline */ + seq->flag &= ~SEQ_OVERLAP; + if (SEQ_transform_test_overlap(seqbasep, seq)) { + seq->flag |= SEQ_OVERLAP; } - seq_prev = seq; } + SEQ_collection_free(transformed_strips); } /* helper for recalcData() - for sequencer transforms */ diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c index a8f7fc43b5e..fb70d04a530 100644 --- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c @@ -54,18 +54,6 @@ /** \name Transform (Sequencer Slide) * \{ */ -static eRedrawFlag seq_slide_handleEvent(struct TransInfo *t, const wmEvent *event) -{ - BLI_assert(t->mode == TFM_SEQ_SLIDE); - const wmKeyMapItem *kmi = t->custom.mode.data; - if (kmi && event->type == kmi->type && event->val == kmi->val) { - /* Allows the "Expand to Fit" effect to be enabled as a toggle. */ - t->flag ^= T_ALT_TRANSFORM; - return TREDRAW_HARD; - } - return TREDRAW_NOTHING; -} - static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRAW_STR]) { char tvec[NUM_STR_REP_LEN * 3]; @@ -79,17 +67,7 @@ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRA } ofs += BLI_snprintf_rlen( - str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text); - - const wmKeyMapItem *kmi = t->custom.mode.data; - if (kmi) { - ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs); - } - - ofs += BLI_snprintf_rlen(str + ofs, - UI_MAX_DRAW_STR - ofs, - TIP_(" or Alt) Expand to fit %s"), - WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0)); + str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s"), &tvec[0], t->con.text); } static void applySeqSlideValue(TransInfo *t, const float val[2]) @@ -148,7 +126,6 @@ static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2])) void initSeqSlide(TransInfo *t) { t->transform = applySeqSlide; - t->handleEvent = seq_slide_handleEvent; t->tsnap.applySnap = transform_snap_sequencer_apply_translate; initMouseInputMode(t, &t->mouse, INPUT_VECTOR); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 3cd5a068e86..7800e7f9efe 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1339,12 +1339,19 @@ typedef struct SequencerToolSettings { int fit_method; short snap_mode; short snap_flag; - int _pad0; + /* eSeqOverlapMode */ + int overlap_mode; /** When there are many snap points, 0-1 range corresponds to resolution from boundbox to all * possible snap points. */ int snap_distance; } SequencerToolSettings; +typedef enum eSeqOverlapMode { + SEQ_OVERLAP_EXPAND, + SEQ_OVERLAP_OVERWRITE, + SEQ_OVERLAP_SHUFFLE, +} eSeqOverlapMode; + typedef enum eSeqImageFitMethod { SEQ_SCALE_TO_FIT, SEQ_SCALE_TO_FILL, diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 9d158761a21..0583cdeb1bb 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3510,6 +3510,21 @@ static void rna_def_sequencer_tool_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem scale_overlap_modes[] = { + {SEQ_OVERLAP_EXPAND, "EXPAND", 0, "Expand", "Move strips so transformed strips fits"}, + {SEQ_OVERLAP_OVERWRITE, + "OVERWRITE", + 0, + "Overwrite", + "Trim or split strips to resolve overlap"}, + {SEQ_OVERLAP_SHUFFLE, + "SHUFFLE", + 0, + "Shuffle", + "Move transformed strips to nearest free space to resolve overlap"}, + {0, NULL, 0, NULL, NULL}, + }; + srna = RNA_def_struct(brna, "SequencerToolSettings", NULL); RNA_def_struct_path_func(srna, "rna_SequencerToolSettings_path"); RNA_def_struct_ui_text(srna, "Sequencer Tool Settings", ""); @@ -3548,6 +3563,11 @@ static void rna_def_sequencer_tool_settings(BlenderRNA *brna) RNA_def_property_int_default(prop, 15); RNA_def_property_ui_range(prop, 0, 50, 1, 1); RNA_def_property_ui_text(prop, "Snapping Distance", "Maximum distance for snapping in pixels"); + + /* Transform overlap handling. */ + prop = RNA_def_property(srna, "overlap_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, scale_overlap_modes); + RNA_def_property_ui_text(prop, "Overlap Mode", "How to resolve overlap after transformation"); } static void rna_def_unified_paint_settings(BlenderRNA *brna) diff --git a/source/blender/sequencer/SEQ_iterator.h b/source/blender/sequencer/SEQ_iterator.h index 055db07f646..9fca25653e1 100644 --- a/source/blender/sequencer/SEQ_iterator.h +++ b/source/blender/sequencer/SEQ_iterator.h @@ -34,10 +34,12 @@ struct GSet; struct GSetIterator; struct Sequence; -#define SEQ_ITERATOR_FOREACH(var, collection) \ - for (SeqIterator iter = {{{NULL}}}; \ - SEQ_iterator_ensure(collection, &iter, &var) && var != NULL; \ - var = SEQ_iterator_yield(&iter)) +#define SEQ_ITERATOR_FOREACH_IMPL(var, collection, suffix) \ + for (SeqIterator iter##suffix = {{{NULL}}}; \ + SEQ_iterator_ensure(collection, &iter##suffix, &var) && var != NULL; \ + var = SEQ_iterator_yield(&iter##suffix)) + +#define SEQ_ITERATOR_FOREACH(var, collection) SEQ_ITERATOR_FOREACH_IMPL(var, collection, __LINE__) typedef struct SeqCollection { struct GSet *set; @@ -79,6 +81,7 @@ SeqCollection *SEQ_query_by_reference(struct Sequence *seq_reference, struct ListBase *seqbase, SeqCollection *collection)); SeqCollection *SEQ_query_selected_strips(struct ListBase *seqbase); +SeqCollection *SEQ_query_unselected_strips(struct ListBase *seqbase); SeqCollection *SEQ_query_all_strips(struct ListBase *seqbase); SeqCollection *SEQ_query_all_strips_recursive(struct ListBase *seqbase); void SEQ_query_strip_effect_chain(struct Sequence *seq_reference, diff --git a/source/blender/sequencer/SEQ_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h index 54ef37b9049..15fe0be3571 100644 --- a/source/blender/sequencer/SEQ_sequencer.h +++ b/source/blender/sequencer/SEQ_sequencer.h @@ -63,6 +63,7 @@ void SEQ_tool_settings_fit_method_set(struct Scene *scene, eSeqImageFitMethod fi short SEQ_tool_settings_snap_flag_get(struct Scene *scene); short SEQ_tool_settings_snap_mode_get(struct Scene *scene); int SEQ_tool_settings_snap_distance_get(struct Scene *scene); +eSeqOverlapMode SEQ_tool_settings_overlap_mode_get(struct Scene *scene); struct SequencerToolSettings *SEQ_tool_settings_copy(struct SequencerToolSettings *tool_settings); struct Editing *SEQ_editing_get(struct Scene *scene, bool alloc); struct Editing *SEQ_editing_ensure(struct Scene *scene); diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h index 9ff827333be..1977835f627 100644 --- a/source/blender/sequencer/SEQ_transform.h +++ b/source/blender/sequencer/SEQ_transform.h @@ -41,6 +41,7 @@ bool SEQ_transform_sequence_can_be_translated(struct Sequence *seq); bool SEQ_transform_single_image_check(struct Sequence *seq); void SEQ_transform_fix_single_image_seq_offsets(struct Sequence *seq); bool SEQ_transform_test_overlap(struct ListBase *seqbasep, struct Sequence *test); +bool SEQ_transform_test_overlap_seq_seq(struct Sequence *seq1, struct Sequence *seq2); void SEQ_transform_translate_sequence(struct Scene *scene, struct Sequence *seq, int delta); bool SEQ_transform_seqbase_shuffle_ex(struct ListBase *seqbasep, struct Sequence *test, diff --git a/source/blender/sequencer/intern/iterator.c b/source/blender/sequencer/intern/iterator.c index a9cbf4879f1..58f68205f51 100644 --- a/source/blender/sequencer/intern/iterator.c +++ b/source/blender/sequencer/intern/iterator.c @@ -341,6 +341,24 @@ SeqCollection *SEQ_query_selected_strips(ListBase *seqbase) } /** + * Query all unselected strips in seqbase. + * + * \param seqbase: ListBase in which strips are queried + * \return strip collection + */ +SeqCollection *SEQ_query_unselected_strips(ListBase *seqbase) +{ + SeqCollection *collection = SEQ_collection_create(__func__); + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if ((seq->flag & SELECT) != 0) { + continue; + } + SEQ_collection_append_strip(seq, collection); + } + 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. diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c index 2863af8fb2e..a62b76cd832 100644 --- a/source/blender/sequencer/intern/sequencer.c +++ b/source/blender/sequencer/intern/sequencer.c @@ -323,6 +323,8 @@ SequencerToolSettings *SEQ_tool_settings_init(void) tool_settings->snap_mode = SEQ_SNAP_TO_STRIPS | SEQ_SNAP_TO_CURRENT_FRAME | SEQ_SNAP_TO_STRIP_HOLD; tool_settings->snap_distance = 15; + tool_settings->overlap_mode = SEQ_OVERLAP_SHUFFLE; + return tool_settings; } @@ -372,6 +374,12 @@ void SEQ_tool_settings_fit_method_set(Scene *scene, eSeqImageFitMethod fit_metho tool_settings->fit_method = fit_method; } +eSeqOverlapMode SEQ_tool_settings_overlap_mode_get(Scene *scene) +{ + const SequencerToolSettings *tool_settings = SEQ_tool_settings_ensure(scene); + return tool_settings->overlap_mode; +} + /** * Get seqbase that is being viewed currently. This can be main seqbase or meta strip seqbase * diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index 9f69f434ca0..3a5f93a72b0 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -208,7 +208,7 @@ bool SEQ_transform_sequence_can_be_translated(Sequence *seq) return !(seq->type & SEQ_TYPE_EFFECT) || (SEQ_effect_get_num_inputs(seq->type) == 0); } -static bool seq_overlap(Sequence *seq1, Sequence *seq2) +bool SEQ_transform_test_overlap_seq_seq(Sequence *seq1, Sequence *seq2) { return (seq1 != seq2 && seq1->machine == seq2->machine && ((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp)) == 0); @@ -220,7 +220,7 @@ bool SEQ_transform_test_overlap(ListBase *seqbasep, Sequence *test) seq = seqbasep->first; while (seq) { - if (seq_overlap(test, seq)) { + if (SEQ_transform_test_overlap_seq_seq(test, seq)) { return true; } @@ -316,7 +316,7 @@ static int shuffle_seq_time_offset_test(SeqCollection *strips_to_shuffle, SEQ_ITERATOR_FOREACH (seq, strips_to_shuffle) { LISTBASE_FOREACH (Sequence *, seq_other, seqbasep) { - if (!seq_overlap(seq, seq_other)) { + if (!SEQ_transform_test_overlap_seq_seq(seq, seq_other)) { continue; } if (UNLIKELY(SEQ_collection_has_strip(seq_other, strips_to_shuffle))) { |