[Bf-blender-cvs] [d373b43f07f] master: VSE: Better handling of effect strip splitting

Richard Antalik noreply at git.blender.org
Tue May 18 23:42:50 CEST 2021


Commit: d373b43f07f5403826035b5dee71b09f433b0540
Author: Richard Antalik
Date:   Tue May 18 23:38:33 2021 +0200
Branches: master
https://developer.blender.org/rBd373b43f07f5403826035b5dee71b09f433b0540

VSE: Better handling of effect strip splitting

Splitting of effect strip alone wasn't handled properly. Previously
this resulted in duplicating effect strip, and it was broken at least
from 2.79.

Change in rB8ec6b34b8eb2 was intended to allow splitting strips
individually, so it can be used as RNA API function but also so it
requires as little glue logic as possible.

This is fixed by splitting all dependent strips at once in 2 separate
ListBases for left and right strips. Strips can be finally moved into
original `ListBase`.

With this fix it is still possible to split strips individually with
little glue logic. RNA API function could return list of split strips
as well, currently at least one strip in chain will be provided so
chain can be reconstructed on python side.

Reviewed By: sergey

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

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

M	source/blender/editors/space_sequencer/sequencer_edit.c
M	source/blender/sequencer/SEQ_utils.h
M	source/blender/sequencer/intern/strip_edit.c
M	source/blender/sequencer/intern/utils.c
M	source/blender/sequencer/intern/utils.h

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

diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 1a1ba5a0754..4d87f0300e7 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1577,17 +1577,6 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot)
 /** \name Duplicate Strips Operator
  * \{ */
 
-static int apply_unique_name_fn(Sequence *seq, void *arg_pt)
-{
-  Scene *scene = (Scene *)arg_pt;
-  char name[sizeof(seq->name) - 2];
-
-  BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
-  SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
-  SEQ_dupe_animdata(scene, name, seq->name + 2);
-  return 1;
-}
-
 static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
 {
   Scene *scene = CTX_data_scene(C);
@@ -1608,7 +1597,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
     BLI_movelisttolist(ed->seqbasep, &nseqbase);
 
     for (; seq; seq = seq->next) {
-      SEQ_recursive_apply(seq, apply_unique_name_fn, scene);
+      SEQ_ensure_unique_name(seq, scene);
     }
 
     WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -2465,7 +2454,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
 
   for (iseq = iseq_first; iseq; iseq = iseq->next) {
     /* Make sure, that pasted strips have unique names. */
-    SEQ_recursive_apply(iseq, apply_unique_name_fn, scene);
+    SEQ_ensure_unique_name(iseq, scene);
     /* Translate after name has been changed, otherwise this will affect animdata of original
      * strip. */
     SEQ_transform_translate_sequence(scene, iseq, ofs);
diff --git a/source/blender/sequencer/SEQ_utils.h b/source/blender/sequencer/SEQ_utils.h
index 52fac5d7d0e..361246d74c5 100644
--- a/source/blender/sequencer/SEQ_utils.h
+++ b/source/blender/sequencer/SEQ_utils.h
@@ -60,6 +60,7 @@ int SEQ_seqbase_recursive_apply(struct ListBase *seqbase,
 int SEQ_recursive_apply(struct Sequence *seq,
                         int (*apply_fn)(struct Sequence *, void *),
                         void *arg);
+void SEQ_ensure_unique_name(struct Sequence *seq, struct Scene *scene);
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c
index a26fb0244b6..b5b0dc2770e 100644
--- a/source/blender/sequencer/intern/strip_edit.c
+++ b/source/blender/sequencer/intern/strip_edit.c
@@ -39,6 +39,7 @@
 #include "BKE_sound.h"
 
 #include "strip_time.h"
+#include "utils.h"
 
 #include "SEQ_add.h"
 #include "SEQ_edit.h"
@@ -348,6 +349,29 @@ static void seq_split_set_left_offset(Sequence *seq, int 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.
  *
@@ -370,33 +394,44 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
     return NULL;
   }
 
-  if (method == SEQ_SPLIT_HARD) {
-    /* Precaution, needed because the length saved on-disk may not match the length saved in the
-     * blend file, or our code may have minor differences reading file length between versions.
-     * This causes hard-split to fail, see: T47862. */
-    SEQ_add_reload_new_file(bmain, scene, seq, true);
-    SEQ_time_update_sequence(scene, seq);
+  SeqCollection *collection = SEQ_collection_create();
+  SEQ_collection_append_strip(seq, collection);
+  SEQ_collection_expand(seqbase, collection, SEQ_query_strip_effect_chain);
+
+  /* Move strips in collection from seqbase to new ListBase. */
+  ListBase left_strips = {NULL, NULL};
+  SEQ_ITERATOR_FOREACH (seq, collection) {
+    BLI_remlink(seqbase, seq);
+    BLI_addtail(&left_strips, seq);
   }
 
-  Sequence *left_seq = seq;
-  Sequence *right_seq = SEQ_sequence_dupli_recursive(
-      scene, scene, seqbase, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
+  /* Sort list, so that no strip can depend on next strip in list.
+   * This is important for SEQ_time_update_sequence functionality. */
+  seq_sort_seqbase(&left_strips);
+
+  /* Duplicate ListBase. */
+  ListBase right_strips = {NULL, NULL};
+  SEQ_sequence_base_dupli_recursive(
+      scene, scene, &right_strips, &left_strips, SEQ_DUPE_ANIM | SEQ_DUPE_ALL, 0);
+
+  /* Split strips. */
+  Sequence *left_seq = left_strips.first;
+  Sequence *right_seq = right_strips.first;
+  Sequence *return_seq = right_strips.first;
+  while (left_seq && right_seq) {
+    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;
+  }
 
-  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;
+  /* Move strips back to seqbase. Move right strips first, so left strips don't change name. */
+  BLI_movelisttolist(seqbase, &right_strips);
+  BLI_movelisttolist(seqbase, &left_strips);
+  LISTBASE_FOREACH (Sequence *, seq_iter, seqbase) {
+    SEQ_ensure_unique_name(seq_iter, scene);
   }
-  SEQ_time_update_sequence(scene, left_seq);
-  SEQ_time_update_sequence(scene, right_seq);
-  return right_seq;
+
+  return return_seq;
 }
 
 /**
diff --git a/source/blender/sequencer/intern/utils.c b/source/blender/sequencer/intern/utils.c
index 6d5332b2b15..8da71b0ac56 100644
--- a/source/blender/sequencer/intern/utils.c
+++ b/source/blender/sequencer/intern/utils.c
@@ -33,10 +33,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_sequence_types.h"
 
-#include "BLI_listbase.h"
-#include "BLI_path_util.h"
-#include "BLI_string.h"
-#include "BLI_utildefines.h"
+#include "BLI_blenlib.h"
 
 #include "BKE_image.h"
 #include "BKE_main.h"
@@ -55,21 +52,24 @@
 #include "proxy.h"
 #include "utils.h"
 
-void SEQ_sort(Scene *scene)
+/**
+ * Sort strips in provided seqbase. Effect strips are trailing the list and they are sorted by
+ * channel position as well.
+ * This is important for SEQ_time_update_sequence to work properly
+ *
+ * \param seqbase: ListBase with strips
+ */
+
+void seq_sort_seqbase(ListBase *seqbase)
 {
   /* all strips together per kind, and in order of y location ("machine") */
-  ListBase seqbase, effbase;
-  Editing *ed = SEQ_editing_get(scene, false);
+  ListBase inputbase, effbase;
   Sequence *seq, *seqt;
 
-  if (ed == NULL) {
-    return;
-  }
-
-  BLI_listbase_clear(&seqbase);
+  BLI_listbase_clear(&inputbase);
   BLI_listbase_clear(&effbase);
 
-  while ((seq = BLI_pophead(ed->seqbasep))) {
+  while ((seq = BLI_pophead(seqbase))) {
 
     if (seq->type & SEQ_TYPE_EFFECT) {
       seqt = effbase.first;
@@ -85,22 +85,40 @@ void SEQ_sort(Scene *scene)
       }
     }
     else {
-      seqt = seqbase.first;
+      seqt = inputbase.first;
       while (seqt) {
         if (seqt->machine >= seq->machine) {
-          BLI_insertlinkbefore(&seqbase, seqt, seq);
+          BLI_insertlinkbefore(&inputbase, seqt, seq);
           break;
         }
         seqt = seqt->next;
       }
       if (seqt == NULL) {
-        BLI_addtail(&seqbase, seq);
+        BLI_addtail(&inputbase, seq);
       }
     }
   }
 
-  BLI_movelisttolist(&seqbase, &effbase);
-  *(ed->seqbasep) = seqbase;
+  BLI_movelisttolist(seqbase, &inputbase);
+  BLI_movelisttolist(seqbase, &effbase);
+}
+
+/**
+ * Sort strips in active seqbase. Effect strips are trailing the list and they are sorted by
+ * channel position as well.
+ * This is important for SEQ_time_update_sequence to work properly
+ *
+ * \param scene: Scene to look for active seqbase in
+ */
+void SEQ_sort(Scene *scene)
+{
+  Editing *ed = SEQ_editing_get(scene, false);
+
+  if (ed == NULL) {
+    return;
+  }
+
+  seq_sort_seqbase(SEQ_active_seqbase_get(ed));
 }
 
 typedef struct SeqUniqueInfo {
@@ -612,3 +630,25 @@ int SEQ_recursive_apply(Sequence *seq, int (*apply_fn)(Sequence *, void *), void
 
   return ret;
 }
+
+/**
+ * Ensure, that provided Sequence has unique name. If animation data exists for this Sequence, it
+ * will be duplicated and mapped onto new name
+ *
+ * \param seq: Sequence which name will be ensured to be unique
+ * \param scene: Scene in which name must be unique
+ */
+void SEQ_ensure_unique_name(Sequence *seq, Scene *scene)
+{
+  char name[SEQ_NAME_MAXSTR];
+
+  BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
+  SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
+  SEQ_dupe_animdata(scene, name, seq->name + 2);
+
+  if (seq->type == SEQ_TYPE_META) {
+    LISTBASE_FOREACH (Sequence *, seq_child, &seq->seqbase) {
+      SEQ_ensure_unique_name(seq_child, scene);
+    }
+  }
+}
diff --git a/source/blender/sequencer/intern/utils.h b/source/blender/sequencer/intern/utils.h
index 97f33bb3ae0..0ec78a6cfa5 100644
--- a/source/blender/sequencer/intern/utils.h
+++ b/source/blender/sequencer/intern/utils.h
@@ -34,6 +34,7 @@ void seq_open_anim_file(struct Scene *scene, struct Sequence *seq, boo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list