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:
authormano-wii <germano.costa@ig.com.br>2019-09-05 20:34:54 +0300
committermano-wii <germano.costa@ig.com.br>2019-09-05 20:35:38 +0300
commit4e731ec97bd4b689a725f4bdcd49ab1f5c68c12c (patch)
tree2d38d51d080bc50f6e0e9d4cdc9afb0895744140 /source/blender/editors/transform/transform_convert_sequencer.c
parentc90b81172b30b15e4f2f9e6a9a454f1d177176ac (diff)
Transform: Split transform_conversions into multiple files.
Part of T68836 `transform conversions.c` is a file that is getting too big (almost 10,000 lines). So it's a good idea to split it into smaller files. differential revision: https://developer.blender.org/D5677
Diffstat (limited to 'source/blender/editors/transform/transform_convert_sequencer.c')
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c769
1 files changed, 769 insertions, 0 deletions
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
new file mode 100644
index 00000000000..7b79ee7aeb4
--- /dev/null
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -0,0 +1,769 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edtransform
+ */
+
+#include "DNA_space_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+#include "BKE_sequencer.h"
+#include "BKE_report.h"
+
+#include "UI_view2d.h"
+
+#include "transform.h"
+#include "transform_convert.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Sequencer Transform Creation
+ *
+ * \{ */
+
+/* This function applies the rules for transforming a strip so duplicate
+ * checks don't need to be added in multiple places.
+ *
+ * recursive, count and flag MUST be set.
+ *
+ * seq->depth must be set before running this function so we know if the strips
+ * are root level or not
+ */
+static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count, int *flag)
+{
+ /* for extend we need to do some tricks */
+ if (t->mode == TFM_TIME_EXTEND) {
+
+ /* *** Extend Transform *** */
+
+ Scene *scene = t->scene;
+ int cfra = CFRA;
+ int left = BKE_sequence_tx_get_final_left(seq, true);
+ int right = BKE_sequence_tx_get_final_right(seq, true);
+
+ if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
+ *recursive = false;
+ *count = 0;
+ *flag = 0;
+ }
+ else if (seq->type == SEQ_TYPE_META) {
+
+ /* for meta's we only ever need to extend their children, no matter what depth
+ * just check the meta's are in the bounds */
+ if (t->frame_side == 'R' && right <= cfra) {
+ *recursive = false;
+ }
+ else if (t->frame_side == 'L' && left >= cfra) {
+ *recursive = false;
+ }
+ else {
+ *recursive = true;
+ }
+
+ *count = 1;
+ *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
+ }
+ else {
+
+ *recursive = false; /* not a meta, so no thinking here */
+ *count = 1; /* unless its set to 0, extend will never set 2 handles at once */
+ *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
+
+ if (t->frame_side == 'R') {
+ if (right <= cfra) {
+ *count = *flag = 0;
+ } /* ignore */
+ else if (left > cfra) {
+ } /* keep the selection */
+ else {
+ *flag |= SEQ_RIGHTSEL;
+ }
+ }
+ else {
+ if (left >= cfra) {
+ *count = *flag = 0;
+ } /* ignore */
+ else if (right < cfra) {
+ } /* keep the selection */
+ else {
+ *flag |= SEQ_LEFTSEL;
+ }
+ }
+ }
+ }
+ else {
+
+ t->frame_side = 'B';
+
+ /* *** Normal Transform *** */
+
+ if (seq->depth == 0) {
+
+ /* Count */
+
+ /* Non nested strips (resect selection and handles) */
+ if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
+ *recursive = false;
+ *count = 0;
+ *flag = 0;
+ }
+ else {
+ if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
+ *flag = seq->flag;
+ *count = 2; /* we need 2 transdata's */
+ }
+ else {
+ *flag = seq->flag;
+ *count = 1; /* selected or with a handle selected */
+ }
+
+ /* Recursive */
+
+ if ((seq->type == SEQ_TYPE_META) && ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0)) {
+ /* if any handles are selected, don't recurse */
+ *recursive = true;
+ }
+ else {
+ *recursive = false;
+ }
+ }
+ }
+ else {
+ /* Nested, different rules apply */
+
+#ifdef SEQ_TX_NESTED_METAS
+ *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
+ *count = 1; /* ignore the selection for nested */
+ *recursive = (seq->type == SEQ_TYPE_META);
+#else
+ if (seq->type == SEQ_TYPE_META) {
+ /* Meta's can only directly be moved between channels since they
+ * don't have their start and length set directly (children affect that)
+ * since this Meta is nested we don't need any of its data in fact.
+ * BKE_sequence_calc() will update its settings when run on the toplevel meta */
+ *flag = 0;
+ *count = 0;
+ *recursive = true;
+ }
+ else {
+ *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
+ *count = 1; /* ignore the selection for nested */
+ *recursive = false;
+ }
+#endif
+ }
+ }
+}
+
+static int SeqTransCount(TransInfo *t, Sequence *parent, ListBase *seqbase, int depth)
+{
+ Sequence *seq;
+ int tot = 0, recursive, count, flag;
+
+ for (seq = seqbase->first; seq; seq = seq->next) {
+ seq->depth = depth;
+
+ /* 'seq->tmp' is used by seq_tx_get_final_{left, right}
+ * to check sequence's range and clamp to it if needed.
+ * It's first place where digging into sequences tree, so store link to parent here. */
+ seq->tmp = parent;
+
+ SeqTransInfo(t, seq, &recursive, &count, &flag); /* ignore the flag */
+ tot += count;
+
+ if (recursive) {
+ tot += SeqTransCount(t, seq, &seq->seqbase, depth + 1);
+ }
+ }
+
+ return tot;
+}
+
+static TransData *SeqToTransData(
+ TransData *td, TransData2D *td2d, TransDataSeq *tdsq, Sequence *seq, int flag, int sel_flag)
+{
+ int start_left;
+
+ switch (sel_flag) {
+ case SELECT:
+ /* Use seq_tx_get_final_left() and an offset here
+ * so transform has the left hand location of the strip.
+ * tdsq->start_offset is used when flushing the tx data back */
+ start_left = BKE_sequence_tx_get_final_left(seq, false);
+ td2d->loc[0] = start_left;
+ tdsq->start_offset = start_left - seq->start; /* use to apply the original location */
+ break;
+ case SEQ_LEFTSEL:
+ start_left = BKE_sequence_tx_get_final_left(seq, false);
+ td2d->loc[0] = start_left;
+ break;
+ case SEQ_RIGHTSEL:
+ td2d->loc[0] = BKE_sequence_tx_get_final_right(seq, false);
+ break;
+ }
+
+ td2d->loc[1] = seq->machine; /* channel - Y location */
+ td2d->loc[2] = 0.0f;
+ td2d->loc2d = NULL;
+
+ tdsq->seq = seq;
+
+ /* Use instead of seq->flag for nested strips and other
+ * cases where the selection may need to be modified */
+ tdsq->flag = flag;
+ tdsq->sel_flag = sel_flag;
+
+ td->extra = (void *)tdsq; /* allow us to update the strip from here */
+
+ td->flag = 0;
+ td->loc = td2d->loc;
+ copy_v3_v3(td->center, td->loc);
+ copy_v3_v3(td->iloc, td->loc);
+
+ memset(td->axismtx, 0, sizeof(td->axismtx));
+ td->axismtx[2][2] = 1.0f;
+
+ td->ext = NULL;
+ td->val = NULL;
+
+ td->flag |= TD_SELECTED;
+ td->dist = 0.0;
+
+ unit_m3(td->mtx);
+ unit_m3(td->smtx);
+
+ /* Time Transform (extend) */
+ td->val = td2d->loc;
+ td->ival = td2d->loc[0];
+
+ return td;
+}
+
+static int SeqToTransData_Recursive(
+ TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
+{
+ Sequence *seq;
+ int recursive, count, flag;
+ int tot = 0;
+
+ for (seq = seqbase->first; seq; seq = seq->next) {
+
+ SeqTransInfo(t, seq, &recursive, &count, &flag);
+
+ /* add children first so recalculating metastrips does nested strips first */
+ if (recursive) {
+ int tot_children = SeqToTransData_Recursive(t, &seq->seqbase, td, td2d, tdsq);
+
+ td = td + tot_children;
+ td2d = td2d + tot_children;
+ tdsq = tdsq + tot_children;
+
+ tot += tot_children;
+ }
+
+ /* use 'flag' which is derived from seq->flag but modified for special cases */
+ if (flag & SELECT) {
+ if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
+ if (flag & SEQ_LEFTSEL) {
+ SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_LEFTSEL);
+ tot++;
+ }
+ if (flag & SEQ_RIGHTSEL) {
+ SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_RIGHTSEL);
+ tot++;
+ }
+ }
+ else {
+ SeqToTransData(td++, td2d++, tdsq++, seq, flag, SELECT);
+ tot++;
+ }
+ }
+ }
+ return tot;
+}
+
+static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
+{
+ Sequence *seq;
+ int recursive, count, flag;
+ int max = INT32_MIN, min = INT32_MAX;
+
+ for (seq = seqbase->first; seq; seq = seq->next) {
+
+ /* just to get the flag since there are corner cases where this isn't totally obvious */
+ SeqTransInfo(t, seq, &recursive, &count, &flag);
+
+ /* use 'flag' which is derived from seq->flag but modified for special cases */
+ if (flag & SELECT) {
+ if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
+ if (flag & SEQ_LEFTSEL) {
+ min = min_ii(seq->startdisp, min);
+ max = max_ii(seq->startdisp, max);
+ }
+ if (flag & SEQ_RIGHTSEL) {
+ min = min_ii(seq->enddisp, min);
+ max = max_ii(seq->enddisp, max);
+ }
+ }
+ else {
+ min = min_ii(seq->startdisp, min);
+ max = max_ii(seq->enddisp, max);
+ }
+ }
+ }
+
+ if (ts) {
+ ts->max = max;
+ ts->min = min;
+ }
+}
+
+static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
+{
+ Editing *ed = BKE_sequencer_editing_get(t->scene, false);
+
+ if (ed != NULL) {
+
+ ListBase *seqbasep = ed->seqbasep;
+ TransData *td = tc->data;
+ int a;
+
+ /* prevent updating the same seq twice
+ * if the transdata order is changed this will mess up
+ * but so will TransDataSeq */
+ Sequence *seq_prev = NULL;
+ Sequence *seq;
+
+ if (!(t->state == TRANS_CANCEL)) {
+
+#if 0 // default 2.4 behavior
+
+ /* flush to 2d vector from internally used 3d vector */
+ for (a = 0; a < t->total; a++, td++) {
+ if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
+ seq = ((TransDataSeq *)td->extra)->seq;
+ BKE_sequence_base_shuffle(seqbasep, seq, t->scene);
+ }
+
+ seq_prev = seq;
+ }
+
+#else // durian hack
+ {
+ int overlap = 0;
+
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
+ seq = ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
+ overlap = 1;
+ break;
+ }
+ }
+
+ if (overlap) {
+ bool has_effect_root = false, has_effect_any = false;
+ for (seq = seqbasep->first; seq; seq = seq->next) {
+ seq->tmp = NULL;
+ }
+
+ td = tc->data;
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
+ seq = ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev)) {
+ /* check effects strips, we cant change their time */
+ if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
+ has_effect_any = true;
+ if (seq->depth == 0) {
+ has_effect_root = true;
+ }
+ }
+ else {
+ /* Tag seq with a non zero value, used by
+ * BKE_sequence_base_shuffle_time to identify the ones to shuffle */
+ if (seq->depth == 0) {
+ seq->tmp = (void *)1;
+ }
+ }
+ }
+ }
+
+ if (t->flag & T_ALT_TRANSFORM) {
+ int minframe = MAXFRAME;
+ td = tc->data;
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
+ seq = ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev) && (seq->depth == 0)) {
+ minframe = min_ii(minframe, seq->startdisp);
+ }
+ }
+
+ for (seq = seqbasep->first; seq; seq = seq->next) {
+ if (!(seq->flag & SELECT)) {
+ if (seq->startdisp >= minframe) {
+ seq->machine += MAXSEQ * 2;
+ }
+ }
+ }
+
+ BKE_sequence_base_shuffle_time(seqbasep, t->scene);
+
+ for (seq = seqbasep->first; seq; seq = seq->next) {
+ if (seq->machine >= MAXSEQ * 2) {
+ seq->machine -= MAXSEQ * 2;
+ seq->tmp = (void *)1;
+ }
+ else {
+ seq->tmp = NULL;
+ }
+ }
+
+ BKE_sequence_base_shuffle_time(seqbasep, t->scene);
+ }
+ else {
+ BKE_sequence_base_shuffle_time(seqbasep, t->scene);
+ }
+
+ if (has_effect_any) {
+ /* update effects strips based on strips just moved in time */
+ td = tc->data;
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
+ seq = ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev)) {
+ if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
+ BKE_sequence_calc(t->scene, seq);
+ }
+ }
+ }
+ }
+
+ if (has_effect_root) {
+ /* now if any effects _still_ overlap, we need to move them up */
+ td = tc->data;
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
+ seq = ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev) && (seq->depth == 0)) {
+ if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
+ if (BKE_sequence_test_overlap(seqbasep, seq)) {
+ BKE_sequence_base_shuffle(seqbasep, seq, t->scene);
+ }
+ }
+ }
+ }
+ /* done with effects */
+ }
+ }
+ }
+#endif
+
+ for (seq = seqbasep->first; seq; seq = seq->next) {
+ /* We might want to build a list of effects that need to be updated during transform */
+ if (seq->type & SEQ_TYPE_EFFECT) {
+ if (seq->seq1 && seq->seq1->flag & SELECT) {
+ BKE_sequence_calc(t->scene, seq);
+ }
+ else if (seq->seq2 && seq->seq2->flag & SELECT) {
+ BKE_sequence_calc(t->scene, seq);
+ }
+ else if (seq->seq3 && seq->seq3->flag & SELECT) {
+ BKE_sequence_calc(t->scene, seq);
+ }
+ }
+ }
+
+ BKE_sequencer_sort(t->scene);
+ }
+ else {
+ /* Canceled, need to update the strips display */
+ for (a = 0; a < tc->data_len; a++, td++) {
+ seq = ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev) && (seq->depth == 0)) {
+ if (seq->flag & SEQ_OVERLAP) {
+ BKE_sequence_base_shuffle(seqbasep, seq, t->scene);
+ }
+
+ BKE_sequence_calc_disp(t->scene, seq);
+ }
+ seq_prev = seq;
+ }
+ }
+ }
+
+ if ((custom_data->data != NULL) && custom_data->use_free) {
+ TransSeq *ts = custom_data->data;
+ MEM_freeN(ts->tdseq);
+ MEM_freeN(custom_data->data);
+ custom_data->data = NULL;
+ }
+
+ DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS);
+}
+
+void createTransSeqData(bContext *C, TransInfo *t)
+{
+#define XXX_DURIAN_ANIM_TX_HACK
+
+ View2D *v2d = UI_view2d_fromcontext(C);
+ Scene *scene = t->scene;
+ Editing *ed = BKE_sequencer_editing_get(t->scene, false);
+ TransData *td = NULL;
+ TransData2D *td2d = NULL;
+ TransDataSeq *tdsq = NULL;
+ TransSeq *ts = NULL;
+ int xmouse;
+
+ int count = 0;
+
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
+ if (ed == NULL) {
+ tc->data_len = 0;
+ return;
+ }
+
+ tc->custom.type.free_cb = freeSeqData;
+
+ xmouse = (int)UI_view2d_region_to_view_x(v2d, t->mouse.imval[0]);
+
+ /* which side of the current frame should be allowed */
+ if (t->mode == TFM_TIME_EXTEND) {
+ /* only side on which mouse is gets transformed */
+ t->frame_side = (xmouse > CFRA) ? 'R' : 'L';
+ }
+ else {
+ /* normal transform - both sides of current frame are considered */
+ t->frame_side = 'B';
+ }
+
+#ifdef XXX_DURIAN_ANIM_TX_HACK
+ {
+ Sequence *seq;
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ /* hack */
+ if ((seq->flag & SELECT) == 0 && seq->type & SEQ_TYPE_EFFECT) {
+ Sequence *seq_user;
+ int i;
+ for (i = 0; i < 3; i++) {
+ seq_user = *((&seq->seq1) + i);
+ if (seq_user && (seq_user->flag & SELECT) && !(seq_user->flag & SEQ_LOCK) &&
+ !(seq_user->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL))) {
+ seq->flag |= SELECT;
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ count = SeqTransCount(t, NULL, ed->seqbasep, 0);
+
+ /* allocate memory for data */
+ tc->data_len = count;
+
+ /* stop if trying to build list if nothing selected */
+ if (count == 0) {
+ return;
+ }
+
+ tc->custom.type.data = ts = MEM_callocN(sizeof(TransSeq), "transseq");
+ tc->custom.type.use_free = true;
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransSeq TransData");
+ td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D");
+ ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq");
+
+ /* loop 2: build transdata array */
+ SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq);
+ SeqTransDataBounds(t, ed->seqbasep, ts);
+
+ /* set the snap mode based on how close the mouse is at the end/start points */
+ if (abs(xmouse - ts->max) > abs(xmouse - ts->min)) {
+ ts->snap_left = true;
+ }
+
+#undef XXX_DURIAN_ANIM_TX_HACK
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UVs Transform Flush
+ *
+ * \{ */
+
+/* commented _only_ because the meta may have animation data which
+ * needs moving too [#28158] */
+
+#define SEQ_TX_NESTED_METAS
+
+BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag)
+{
+ if (seq->depth == 0) {
+ /* Calculate this strip and all nested strips.
+ * Children are ALWAYS transformed first so we don't need to do this in another loop.
+ */
+ BKE_sequence_calc(sce, seq);
+ }
+ else {
+ BKE_sequence_calc_disp(sce, seq);
+ }
+
+ if (sel_flag == SELECT) {
+ BKE_sequencer_offset_animdata(sce, seq, seq->start - old_start);
+ }
+}
+
+void flushTransSeq(TransInfo *t)
+{
+ /* Editing null check already done */
+ ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, false)->seqbasep;
+
+ int a, new_frame;
+ TransData *td = NULL;
+ TransData2D *td2d = NULL;
+ TransDataSeq *tdsq = NULL;
+ Sequence *seq;
+
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
+ /* prevent updating the same seq twice
+ * if the transdata order is changed this will mess up
+ * but so will TransDataSeq */
+ Sequence *seq_prev = NULL;
+ int old_start_prev = 0, sel_flag_prev = 0;
+
+ /* flush to 2d vector from internally used 3d vector */
+ for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
+ int old_start;
+ tdsq = (TransDataSeq *)td->extra;
+ seq = tdsq->seq;
+ old_start = seq->start;
+ new_frame = round_fl_to_int(td2d->loc[0]);
+
+ switch (tdsq->sel_flag) {
+ case SELECT:
+#ifdef SEQ_TX_NESTED_METAS
+ if ((seq->depth != 0 || BKE_sequence_tx_test(seq))) {
+ /* for meta's, their children move */
+ seq->start = new_frame - tdsq->start_offset;
+ }
+#else
+ if (seq->type != SEQ_TYPE_META && (seq->depth != 0 || seq_tx_test(seq))) {
+ /* for meta's, their children move */
+ seq->start = new_frame - tdsq->start_offset;
+ }
+#endif
+ if (seq->depth == 0) {
+ seq->machine = round_fl_to_int(td2d->loc[1]);
+ CLAMP(seq->machine, 1, MAXSEQ);
+ }
+ break;
+ case SEQ_LEFTSEL: /* no vertical transform */
+ BKE_sequence_tx_set_final_left(seq, new_frame);
+ BKE_sequence_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
+
+ /* todo - move this into aftertrans update? - old seq tx needed it anyway */
+ BKE_sequence_single_fix(seq);
+ break;
+ case SEQ_RIGHTSEL: /* no vertical transform */
+ BKE_sequence_tx_set_final_right(seq, new_frame);
+ BKE_sequence_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
+
+ /* todo - move this into aftertrans update? - old seq tx needed it anyway */
+ BKE_sequence_single_fix(seq);
+ break;
+ }
+
+ /* Update *previous* seq! Else, we would update a seq after its first transform,
+ * and if it has more than one (like e.g. SEQ_LEFTSEL and SEQ_RIGHTSEL),
+ * the others are not updated! See T38469.
+ */
+ if (seq != seq_prev) {
+ if (seq_prev) {
+ trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
+ }
+
+ seq_prev = seq;
+ old_start_prev = old_start;
+ sel_flag_prev = tdsq->sel_flag;
+ }
+ else {
+ /* We want to accumulate *all* sel_flags for this seq! */
+ sel_flag_prev |= tdsq->sel_flag;
+ }
+ }
+
+ /* Don't forget to update the last seq! */
+ if (seq_prev) {
+ trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
+ }
+
+ /* originally TFM_TIME_EXTEND, transform changes */
+ if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) {
+ /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */
+
+ /* calc all meta's then effects [#27953] */
+ for (seq = seqbasep->first; seq; seq = seq->next) {
+ if (seq->type == SEQ_TYPE_META && seq->flag & SELECT) {
+ BKE_sequence_calc(t->scene, seq);
+ }
+ }
+ for (seq = seqbasep->first; seq; seq = seq->next) {
+ if (seq->seq1 || seq->seq2 || seq->seq3) {
+ BKE_sequence_calc(t->scene, seq);
+ }
+ }
+
+ /* update effects inside meta's */
+ for (a = 0, seq_prev = NULL, td = tc->data, td2d = tc->data_2d; a < tc->data_len;
+ a++, td++, td2d++, seq_prev = seq) {
+ tdsq = (TransDataSeq *)td->extra;
+ seq = tdsq->seq;
+ if ((seq != seq_prev) && (seq->depth != 0)) {
+ if (seq->seq1 || seq->seq2 || seq->seq3) {
+ BKE_sequence_calc(t->scene, seq);
+ }
+ }
+ }
+ }
+
+ /* need to do the overlap check in a new loop otherwise adjacent strips
+ * will not be updated and we'll get false positives */
+ seq_prev = NULL;
+ for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
+
+ tdsq = (TransDataSeq *)td->extra;
+ seq = tdsq->seq;
+
+ if (seq != seq_prev) {
+ if (seq->depth == 0) {
+ /* test overlap, displays red outline */
+ seq->flag &= ~SEQ_OVERLAP;
+ if (BKE_sequence_test_overlap(seqbasep, seq)) {
+ seq->flag |= SEQ_OVERLAP;
+ }
+ }
+ }
+ seq_prev = seq;
+ }
+}
+
+/** \} */