Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c15
-rw-r--r--source/blender/sequencer/SEQ_utils.h1
-rw-r--r--source/blender/sequencer/intern/strip_edit.c81
-rw-r--r--source/blender/sequencer/intern/utils.c76
-rw-r--r--source/blender/sequencer/intern/utils.h1
5 files changed, 120 insertions, 54 deletions
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, bool openfile
struct Sequence *seq_find_metastrip_by_sequence(ListBase *seqbase /* = ed->seqbase */,
struct Sequence *meta /* = NULL */,
struct Sequence *seq);
+void seq_sort_seqbase(ListBase *seqbase);
#ifdef __cplusplus
}