[Bf-blender-cvs] [98e5a7c8a50] temp-vse-transform-overwrite: VSE: Transform overwrite mode

Richard Antalik noreply at git.blender.org
Tue Aug 10 09:50:23 CEST 2021


Commit: 98e5a7c8a50eb348a7790d717d09061887a1f58c
Author: Richard Antalik
Date:   Tue Aug 10 03:37:45 2021 +0200
Branches: temp-vse-transform-overwrite
https://developer.blender.org/rB98e5a7c8a50eb348a7790d717d09061887a1f58c

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.

---

Demonstration:
{F10226243}

Reviewed By: mano-wii

Differential Revision: https://developer.blender.org/D11805

===================================================================

M	release/scripts/startup/bl_ui/space_sequencer.py
M	source/blender/editors/transform/transform_convert_sequencer.c
M	source/blender/editors/transform/transform_mode_edge_seq_slide.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_scene.c
M	source/blender/sequencer/SEQ_iterator.h
M	source/blender/sequencer/SEQ_sequencer.h
M	source/blender/sequencer/intern/iterator.c
M	source/blender/sequencer/intern/sequencer.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 20fb39e8c1f..80fd47c0207 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, "use_overwrite_mode", text="Overwrite Mode")
             row = layout.row(align=True)
             row.prop(tool_settings, "use_snap_sequencer", text="")
             sub = row.row(align=True)
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index 17512c79d03..5dec10059aa 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -27,12 +27,16 @@
 
 #include "BLI_listbase.h"
 #include "BLI_math.h"
+#include "BLI_rect.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"
@@ -299,7 +303,20 @@ static SeqCollection *extract_standalone_strips(SeqCollection *transformed_strip
   return collection;
 }
 
-/* Query strips positioned after left edge of transformed strips boundbox. */
+static void seq_collection_boundbox(SeqCollection *collection, rcti *r_boundbox)
+{
+  BLI_rcti_init(r_boundbox, MAXFRAME, MINFRAME, INT_MAX, 0);
+
+  Sequence *seq;
+  SEQ_ITERATOR_FOREACH (seq, collection) {
+    r_boundbox->xmin = min_ii(r_boundbox->xmin, seq->startdisp);
+    r_boundbox->xmax = max_ii(r_boundbox->xmax, seq->enddisp);
+    r_boundbox->ymin = min_ii(r_boundbox->ymin, seq->machine);
+    r_boundbox->ymax = max_ii(r_boundbox->ymax, seq->machine);
+  }
+}
+
+/* Query strips positioned after left edge of transformed strips r_boundbox. */
 static SeqCollection *query_right_side_strips(ListBase *seqbase, SeqCollection *transformed_strips)
 {
   int minframe = MAXFRAME;
@@ -341,12 +358,17 @@ static bool seq_transform_check_strip_effects(SeqCollection *transformed_strips)
   return false;
 }
 
-/* Offset all strips positioned after left edge of transformed strips boundbox by amount equal
+static ListBase *seqbase_from_trans_info(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 r_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_from_trans_info(t);
   ListBase *markers = &t->scene->markers;
   const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
                                  SEQ_MARKER_TRANS) != 0;
@@ -378,23 +400,192 @@ static void seq_transform_handle_expand_to_fit(TransInfo *t, SeqCollection *tran
   SEQ_collection_free(right_side_strips);
 }
 
+static SeqCollection *query_overwrite_targets(TransInfo *t, SeqCollection *transformed_strips)
+{
+  rcti transformed_boundbox;
+  seq_collection_boundbox(transformed_strips, &transformed_boundbox);
+  SeqCollection *collection = SEQ_query_unselected_strips(seqbase_from_trans_info(t));
+
+  Sequence *seq;
+  SEQ_ITERATOR_FOREACH (seq, collection) {
+    if (seq->enddisp < transformed_boundbox.xmin || seq->startdisp > transformed_boundbox.xmax) {
+      SEQ_collection_remove_strip(seq, collection);
+    }
+  }
+
+  /* In some cases effects of transformed strips are not selected. These must not be included. */
+  SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
+    SEQ_collection_remove_strip(seq, collection);
+  }
+
+  return collection;
+}
+
+static bool is_same_channel(Sequence *transformed, Sequence *target)
+{
+  if (transformed->machine == target->machine) {
+    return true;
+  }
+  return false;
+}
+
+static bool is_full_overlap(Sequence *transformed, Sequence *target)
+{
+  if (transformed->startdisp <= target->startdisp && transformed->enddisp >= target->enddisp) {
+    return true;
+  }
+  return false;
+}
+
+static bool is_inside_overlap(Sequence *transformed, Sequence *target)
+{
+  if (transformed->startdisp > target->startdisp && transformed->enddisp < target->enddisp) {
+    return true;
+  }
+  return false;
+}
+
+typedef enum ePartialOvelapSide {
+  LEFT_SIDE_OVERLAP,
+  RIGHT_SIDE_OVERLAP,
+} ePartialOvelapSide;
+
+static bool is_partial_overlap(Sequence *transformed, Sequence *target, ePartialOvelapSide *r_side)
+{
+  if (transformed->startdisp <= target->startdisp && target->startdisp <= transformed->enddisp) {
+    *r_side = LEFT_SIDE_OVERLAP;
+    return true;
+  }
+  if (transformed->startdisp <= target->enddisp && target->enddisp <= transformed->enddisp) {
+    *r_side = RIGHT_SIDE_OVERLAP;
+    return true;
+  }
+  return false;
+}
+
+static void seq_transform_handle_overwrite_split(TransInfo *t,
+                                                 Sequence *transformed,
+                                                 Sequence *target)
+{
+  Main *bmain = CTX_data_main(t->context);
+  Scene *scene = t->scene;
+  ListBase *seqbase = seqbase_from_trans_info(t);
+
+  Sequence *split_strip = SEQ_edit_strip_split(
+      bmain, scene, seqbase, target, transformed->startdisp, SEQ_SPLIT_SOFT);
+  SEQ_edit_strip_split(bmain, scene, seqbase, split_strip, transformed->enddisp, SEQ_SPLIT_SOFT);
+  SEQ_edit_flag_for_removal(scene, seqbase_from_trans_info(t), split_strip);
+}
+
+/* BUG must handle overlap with non-effect more gracefully. */
+
+/* Trim strips by adjusting handle position.
+ * This is bit more complicated in case overlap happens on effect. */
+static void seq_transform_handle_overwrite_trim(TransInfo *t,
+                                                Sequence *transformed,
+                                                Sequence *target,
+                                                ePartialOvelapSide overlap_side)
+{
+  SeqCollection *targets = SEQ_collection_create(__func__);
+  SEQ_collection_append_strip(target, targets);
+
+  /* Expand collection by adding all target's children, effects and their children. */
+  if ((target->type & SEQ_TYPE_EFFECT) != 0) {
+    SEQ_collection_expand(seqbase_from_trans_info(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_effect_get_num_inputs(seq->type) > 0) {
+      continue;
+    }
+    if (is_partial_overlap(transformed, seq, &overlap_side)) {
+      if (overlap_side == LEFT_SIDE_OVERLAP) {
+        SEQ_transform_set_left_handle_frame(seq, transformed->enddisp);
+      }
+      if (overlap_side == RIGHT_SIDE_OVERLAP) {
+        SEQ_transform_set_right_handle_frame(seq, transformed->startdisp);
+      }
+    }
+    SEQ_time_update_sequence(t->scene, seq);
+  }
+
+  SEQ_collection_free(targets);
+
+  /* Recalculate all effects influenced by target. */
+  SeqCollection *effects = SEQ_query_by_reference(
+      target, seqbase_from_trans_info(t), SEQ_query_strip_effect_chain);
+  SEQ_ITERATOR_FOREACH (seq, effects) {
+    SEQ_time_update_sequence(t->scene, seq);
+  }
+  SEQ_collection_free(effects);
+}
+
+static void seq_transform_handle_overwrite(TransInfo *t, SeqCollection *transformed_strips)
+{
+  SeqCollection *targets = query_overwrite_targets(t, transformed_strips);
+
+  ePartialOvelapSide overlap_side;
+  bool strips_delete = false;
+  Sequence *target;
+  Sequence *transformed;
+  SEQ_ITERATOR_FOREACH (target, targets) {
+    SEQ_ITERATOR_FOREACH (transformed, transformed_strips) {
+      if (!is_same_channel(transformed, target)) {
+        continue;
+      }
+
+      /* Remove covered strip. */
+      if (is_full_overlap(transformed, target)) {
+        SEQ_edit_flag_for_removal(t->scene, seqbase_from_trans_info(t), target);
+        strips_delete = true;
+      }
+      /* Split strip in 3 parts, remove middle part and fit transformed inside. */
+      else if (is_inside_overlap(transformed, target)) {
+        seq_transform_handle_overwrite_split(t, transformed, target);
+        strips_delete = true;
+      }
+      /* Nove handle by amount of overlap. */
+      else if (is_partial_overlap(transformed, target, &overlap_side)) {
+        seq_transform_handle_overwrite_trim(t, transformed, target, overlap_side);
+      }
+    }
+  }
+
+  SEQ_collection_free(targets);
+
+  if (strips_delete) {
+    SEQ_edit_remove_flagged_sequences(t->scene, seqbase_from_trans_info(t));
+  }
+}
+
+static void seq_transform_handle_overlap_shuffle(TransInfo *t, SeqCollection *transformed_strips)
+{
+  ListBase *seqbase = seqbase_from_trans_info(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)
 {
-  Editing *ed = SEQ_editing_get(t->scene, false);
-  ListBase *seqbasep = SEQ_active_seqbase_get(ed);
+  ListBase *seqbasep = seqbase_from_trans_info(t);
+  eSeqOverlapMode overlap_mode = SEQ_tool_settings_overlap_mode_get(t->scene);
 
-  if (t->flag & T_ALT_TRANSFORM) {
+  if ((overlap_mode & SEQ_OVERLAP_OVERWRITE) == 0 && t->flag & T_ALT_TRANSFORM) {
     seq_transform_handle_expand_to_fit(t, transformed_strips);
   }
+  else if ((ove

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list