From 076d033e10eee29bfc8315344bd2ba1f0951ad06 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Sun, 26 Jul 2020 16:07:34 +0200 Subject: VSE: Refactor delete operator and API Operator logic is limited to iterating over selection and executing same code as python API does. Functional changes: - No attempt to preserve effects is made. Dependant effects are deleted. - No attempt to change meta strip boundaries. Partially fixes T73828 Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D6892 --- source/blender/blenkernel/BKE_sequencer.h | 4 + source/blender/blenkernel/intern/sequencer.c | 58 ++++++++++ .../editors/space_sequencer/sequencer_edit.c | 121 +-------------------- source/blender/makesrna/intern/rna_sequencer_api.c | 5 +- 4 files changed, 70 insertions(+), 118 deletions(-) diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index c32abbb41c6..2873a13d1f7 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -625,6 +625,10 @@ void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb, void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra); bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports); bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq); +void BKE_sequencer_flag_for_removal(struct Scene *scene, + struct ListBase *seqbase, + struct Sequence *seq); +void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 742b20c7de9..4b2d42c704e 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -6069,3 +6069,61 @@ bool BKE_sequencer_render_loop_check(Sequence *seq_main, Sequence *seq) return false; } + +static void sequencer_flag_users_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq) +{ + LISTBASE_FOREACH (Sequence *, user_seq, seqbase) { + /* Look in metas for usage of seq. */ + if (user_seq->type == SEQ_TYPE_META) { + sequencer_flag_users_for_removal(scene, &user_seq->seqbase, seq); + } + + /* Clear seq from modifiers. */ + SequenceModifierData *smd; + for (smd = user_seq->modifiers.first; smd; smd = smd->next) { + if (smd->mask_sequence == seq) { + smd->mask_sequence = NULL; + } + } + + /* Remove effects, that use seq. */ + if ((user_seq->seq1 && user_seq->seq1 == seq) || (user_seq->seq2 && user_seq->seq2 == seq) || + (user_seq->seq3 && user_seq->seq3 == seq)) { + user_seq->flag |= SEQ_FLAG_DELETE; + /* Strips can be used as mask even if not in same seqbase. */ + sequencer_flag_users_for_removal(scene, &scene->ed->seqbase, user_seq); + } + } +} + +/* Flag seq and its users (effects) for removal. */ +void BKE_sequencer_flag_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq) +{ + if (seq == NULL || (seq->flag & SEQ_FLAG_DELETE) != 0) { + return; + } + + /* Flag and remove meta children. */ + if (seq->type == SEQ_TYPE_META) { + LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) { + BKE_sequencer_flag_for_removal(scene, &seq->seqbase, meta_child); + } + } + + seq->flag |= SEQ_FLAG_DELETE; + sequencer_flag_users_for_removal(scene, seqbase, seq); +} + +/* Remove all flagged sequences, return true if sequence is removed. */ +void BKE_sequencer_remove_flagged_sequences(Scene *scene, ListBase *seqbase) +{ + LISTBASE_FOREACH_MUTABLE (Sequence *, seq, seqbase) { + if (seq->flag & SEQ_FLAG_DELETE) { + if (seq->type == SEQ_TYPE_META) { + BKE_sequencer_remove_flagged_sequences(scene, &seq->seqbase); + } + BLI_remlink(seqbase, seq); + BKE_sequence_free(scene, seq, true); + } + } +} diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index ce4fc0ff538..604d2f2a108 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -666,74 +666,6 @@ int seq_effect_find_selected(Scene *scene, /** \name Delete Utilities * \{ */ -static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq) -{ - Sequence *seq1, *seq2, *seq3; - - /* Try to find a replacement input sequence, and flag for later deletion if - * no replacement can be found. */ - - if (!seq) { - return NULL; - } - if (!(seq->type & SEQ_TYPE_EFFECT)) { - return ((seq->flag & SELECT) ? NULL : seq); - } - if (!(seq->flag & SELECT)) { - /* Try to find replacement for effect inputs. */ - seq1 = del_seq_find_replace_recurs(scene, seq->seq1); - seq2 = del_seq_find_replace_recurs(scene, seq->seq2); - seq3 = del_seq_find_replace_recurs(scene, seq->seq3); - - if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) { - /* Pass. */ - } - else if (seq1 || seq2 || seq3) { - seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3; - seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3; - seq->seq3 = (seq3) ? seq3 : (seq1) ? seq1 : seq2; - - BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1); - } - else { - seq->flag |= SELECT; /* Mark for delete. */ - } - } - - if (seq->flag & SELECT) { - if ((seq1 = del_seq_find_replace_recurs(scene, seq->seq1))) { - return seq1; - } - if ((seq2 = del_seq_find_replace_recurs(scene, seq->seq2))) { - return seq2; - } - if ((seq3 = del_seq_find_replace_recurs(scene, seq->seq3))) { - return seq3; - } - return NULL; - } - return seq; -} - -static void del_seq_clear_modifiers_recurs(Scene *scene, Sequence *deleting_sequence) -{ - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *current_sequence; - - SEQP_BEGIN (ed, current_sequence) { - if (!(current_sequence->flag & SELECT) && current_sequence != deleting_sequence) { - SequenceModifierData *smd; - - for (smd = current_sequence->modifiers.first; smd; smd = smd->next) { - if (smd->mask_sequence == deleting_sequence) { - smd->mask_sequence = NULL; - } - } - } - } - SEQ_END; -} - static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short deleteall) { Sequence *seq, *seqn; @@ -2582,61 +2514,18 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, false); Sequence *seq; - MetaStack *ms; - bool nothing_selected = true; - - BKE_sequencer_prefetch_stop(scene); - - seq = BKE_sequencer_active_get(scene); - if (seq && seq->flag & SELECT) { /* Avoid a loop since this is likely to be selected. */ - nothing_selected = false; - } - else { - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->flag & SELECT) { - nothing_selected = false; - break; - } - } - } - - if (nothing_selected) { - return OPERATOR_FINISHED; - } - /* For effects and modifiers, try to find a replacement input. */ - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (!(seq->flag & SELECT)) { - if ((seq->type & SEQ_TYPE_EFFECT)) { - del_seq_find_replace_recurs(scene, seq); - } - } - else { - del_seq_clear_modifiers_recurs(scene, seq); + SEQP_BEGIN (scene->ed, seq) { + if (seq->flag & SELECT) { + BKE_sequencer_flag_for_removal(scene, ed->seqbasep, seq); } } - - /* Delete all selected strips. */ - recurs_del_seq_flag(scene, ed->seqbasep, SELECT, 0); - - /* Update lengths, etc. */ - seq = ed->seqbasep->first; - while (seq) { - BKE_sequence_calc(scene, seq); - seq = seq->next; - } - - /* Free parent metas. */ - ms = ed->metastack.last; - while (ms) { - BKE_sequence_calc(scene, ms->parseq); - ms = ms->prev; - } + SEQ_END; + BKE_sequencer_remove_flagged_sequences(scene, ed->seqbasep); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); - return OPERATOR_FINISHED; } diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 4157747455d..59cedf8fcb8 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -370,13 +370,14 @@ static void rna_Sequences_remove( Sequence *seq = seq_ptr->data; Scene *scene = (Scene *)id; - if (BLI_remlink_safe(&ed->seqbase, seq) == false) { + if (BLI_findindex(&ed->seqbase, seq) == -1) { BKE_reportf( reports, RPT_ERROR, "Sequence '%s' not in scene '%s'", seq->name + 2, scene->id.name + 2); return; } - BKE_sequence_free(scene, seq, true); + BKE_sequencer_flag_for_removal(scene, &ed->seqbase, seq); + BKE_sequencer_remove_flagged_sequences(scene, &ed->seqbase); RNA_POINTER_INVALIDATE(seq_ptr); DEG_relations_tag_update(bmain); -- cgit v1.2.3