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:
Diffstat (limited to 'source/blender/editors/transform/transform_snap_sequencer.c')
-rw-r--r--source/blender/editors/transform/transform_snap_sequencer.c82
1 files changed, 69 insertions, 13 deletions
diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c
index d0b730383d5..a1f396eb503 100644
--- a/source/blender/editors/transform/transform_snap_sequencer.c
+++ b/source/blender/editors/transform/transform_snap_sequencer.c
@@ -34,6 +34,7 @@
#include "UI_view2d.h"
+#include "SEQ_effects.h"
#include "SEQ_iterator.h"
#include "SEQ_sequencer.h"
@@ -104,11 +105,41 @@ static void seq_snap_source_points_build(const TransInfo *UNUSED(t),
/** \name Snap targets
* \{ */
-static SeqCollection *query_snap_targets(const TransInfo *t)
+/* Add effect strips directly or indirectly connected to `seq_reference` to `collection`. */
+static void query_strip_effects_fn(Sequence *seq_reference,
+ ListBase *seqbase,
+ SeqCollection *collection)
{
- const ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene, false));
+ if (!SEQ_collection_append_strip(seq_reference, collection)) {
+ return; /* Strip is already in set, so all effects connected to it are as well. */
+ }
+
+ /* Find all strips connected to `seq_reference`. */
+ LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
+ if (seq_test->seq1 == seq_reference || seq_test->seq2 == seq_reference ||
+ seq_test->seq3 == seq_reference) {
+ query_strip_effects_fn(seq_test, seqbase, collection);
+ }
+ }
+}
+
+static SeqCollection *seq_collection_extract_effects(SeqCollection *collection)
+{
+ SeqCollection *effects = SEQ_collection_create(__func__);
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, collection) {
+ if (SEQ_effect_get_num_inputs(seq->type) > 0) {
+ SEQ_collection_append_strip(seq, effects);
+ }
+ }
+ return effects;
+}
+
+static SeqCollection *query_snap_targets(const TransInfo *t, SeqCollection *snap_sources)
+{
+ ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene, false));
const short snap_flag = SEQ_tool_settings_snap_flag_get(t->scene);
- SeqCollection *collection = SEQ_collection_create(__func__);
+ SeqCollection *snap_targets = SEQ_collection_create(__func__);
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
if ((seq->flag & SELECT)) {
continue; /* Selected are being transformed. */
@@ -119,9 +150,18 @@ static SeqCollection *query_snap_targets(const TransInfo *t)
if (seq->type == SEQ_TYPE_SOUND_RAM && (snap_flag & SEQ_SNAP_IGNORE_SOUND)) {
continue;
}
- SEQ_collection_append_strip(seq, collection);
+ SEQ_collection_append_strip(seq, snap_targets);
}
- return collection;
+
+ /* Effects will always change position with strip to which they are connected and they don't have
+ * to be selected. Remove such strips from `snap_targets` collection. */
+ SeqCollection *snap_sources_temp = SEQ_collection_duplicate(snap_sources);
+ SEQ_collection_expand(seqbase, snap_sources_temp, query_strip_effects_fn);
+ SeqCollection *snap_sources_effects = seq_collection_extract_effects(snap_sources_temp);
+ SEQ_collection_exclude(snap_targets, snap_sources_effects);
+ SEQ_collection_free(snap_sources_temp);
+
+ return snap_targets;
}
static int seq_get_snap_target_points_count(const TransInfo *t,
@@ -178,11 +218,14 @@ static void seq_snap_target_points_build(const TransInfo *t,
if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) {
int content_start = min_ii(seq->enddisp, seq->start);
int content_end = max_ii(seq->startdisp, seq->start + seq->len);
- if (seq->anim_startofs == 0) {
- content_start = seq->startdisp;
- }
- if (seq->anim_endofs == 0) {
- content_end = seq->enddisp;
+ /* Effects and single image strips produce incorrect content length. Skip these strips. */
+ if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->len == 1) {
+ if (seq->anim_startofs == 0 && seq->startstill == 0) {
+ content_start = seq->startdisp;
+ }
+ if (seq->anim_endofs == 0 && seq->endstill == 0) {
+ content_end = seq->enddisp;
+ }
}
snap_data->target_snap_points[i] = content_start;
snap_data->target_snap_points[i + 1] = content_end;
@@ -214,16 +257,25 @@ TransSeqSnapData *transform_snap_sequencer_data_alloc(const TransInfo *t)
TransSeqSnapData *snap_data = MEM_callocN(sizeof(TransSeqSnapData), __func__);
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene, false));
- /* Build arrays of snap points. */
SeqCollection *snap_sources = SEQ_query_selected_strips(seqbase);
+ SeqCollection *snap_targets = query_snap_targets(t, snap_sources);
+
+ if (SEQ_collection_len(snap_sources) == 0 || SEQ_collection_len(snap_targets) == 0) {
+ SEQ_collection_free(snap_targets);
+ SEQ_collection_free(snap_sources);
+ MEM_freeN(snap_data);
+ return NULL;
+ }
+
+ /* Build arrays of snap points. */
seq_snap_source_points_alloc(snap_data, snap_sources);
seq_snap_source_points_build(t, snap_data, snap_sources);
SEQ_collection_free(snap_sources);
- SeqCollection *snap_targets = query_snap_targets(t);
seq_snap_target_points_alloc(t, snap_data, snap_targets);
seq_snap_target_points_build(t, snap_data, snap_targets);
SEQ_collection_free(snap_targets);
+
return snap_data;
}
@@ -236,12 +288,16 @@ void transform_snap_sequencer_data_free(TransSeqSnapData *data)
bool transform_snap_sequencer_calc(TransInfo *t)
{
+ const TransSeqSnapData *snap_data = t->tsnap.seq_context;
+ if (snap_data == NULL) {
+ return false;
+ }
+
/* Prevent snapping when constrained to Y axis. */
if (t->con.mode & CON_APPLY && t->con.mode & CON_AXIS1) {
return false;
}
- const TransSeqSnapData *snap_data = t->tsnap.seq_context;
int best_dist = MAXFRAME, best_target_frame = 0, best_source_frame = 0;
for (int i = 0; i < snap_data->source_snap_point_count; i++) {