VSE: Reduce transform code complexity
Reduce complexity of sequencer transform code by removing recursivity. This is possible by treating meta strips (mostly) as any other strip and containing all transform code within SEQ_ functions. Unfortunately internally meta strips still require special treatment, but all complexity from code all over transform code seems to be possible to contain within one function. Functional change: Previously adjusting handle of single image strip moved animation. Now animation is not moved, which is behavior for all other strips. Reviewed By: sergey, mano-wii Differential Revision: https://developer.blender.org/D11493
This commit is contained in:
@@ -367,8 +367,6 @@ static void draw_seq_waveform_overlay(View2D *v2d,
|
|||||||
|
|
||||||
static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
|
static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
|
||||||
{
|
{
|
||||||
/* Don't use SEQ_ALL_BEGIN/SEQ_ALL_END here,
|
|
||||||
* because it changes seq->depth, which is needed for transform. */
|
|
||||||
Sequence *seq;
|
Sequence *seq;
|
||||||
uchar col[4];
|
uchar col[4];
|
||||||
|
|
||||||
|
@@ -335,7 +335,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
/* Check meta-strips. */
|
/* Check meta-strips. */
|
||||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||||
if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) &&
|
if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK) &&
|
||||||
SEQ_transform_sequence_can_be_translated(seq)) {
|
SEQ_transform_sequence_can_be_translated(seq)) {
|
||||||
if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
|
if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
|
||||||
SEQ_transform_translate_sequence(
|
SEQ_transform_translate_sequence(
|
||||||
@@ -357,7 +357,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
/* Test for effects and overlap. */
|
/* Test for effects and overlap. */
|
||||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||||
if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) {
|
if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
|
||||||
seq->flag &= ~SEQ_OVERLAP;
|
seq->flag &= ~SEQ_OVERLAP;
|
||||||
if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
|
if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
|
||||||
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
|
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
|
||||||
@@ -2187,7 +2187,7 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i
|
|||||||
|
|
||||||
seq = ed->seqbasep->first;
|
seq = ed->seqbasep->first;
|
||||||
while (seq) {
|
while (seq) {
|
||||||
if ((seq != test) && (test->machine == seq->machine) && (test->depth == seq->depth) &&
|
if ((seq != test) && (test->machine == seq->machine) &&
|
||||||
((sel == -1) || (sel == (seq->flag & SELECT)))) {
|
((sel == -1) || (sel == (seq->flag & SELECT)))) {
|
||||||
dist = MAXFRAME * 2;
|
dist = MAXFRAME * 2;
|
||||||
|
|
||||||
|
@@ -76,12 +76,9 @@ typedef struct TransSeq {
|
|||||||
/* This function applies the rules for transforming a strip so duplicate
|
/* This function applies the rules for transforming a strip so duplicate
|
||||||
* checks don't need to be added in multiple places.
|
* checks don't need to be added in multiple places.
|
||||||
*
|
*
|
||||||
* recursive, count and flag MUST be set.
|
* 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 *r_recursive, int *r_count, int *r_flag)
|
static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag)
|
||||||
{
|
{
|
||||||
/* for extend we need to do some tricks */
|
/* for extend we need to do some tricks */
|
||||||
if (t->mode == TFM_TIME_EXTEND) {
|
if (t->mode == TFM_TIME_EXTEND) {
|
||||||
@@ -93,13 +90,11 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_c
|
|||||||
int left = SEQ_transform_get_left_handle_frame(seq);
|
int left = SEQ_transform_get_left_handle_frame(seq);
|
||||||
int right = SEQ_transform_get_right_handle_frame(seq);
|
int right = SEQ_transform_get_right_handle_frame(seq);
|
||||||
|
|
||||||
if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
|
if (((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
|
||||||
*r_recursive = false;
|
|
||||||
*r_count = 0;
|
*r_count = 0;
|
||||||
*r_flag = 0;
|
*r_flag = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*r_recursive = false;
|
|
||||||
*r_count = 1; /* unless its set to 0, extend will never set 2 handles at once */
|
*r_count = 1; /* unless its set to 0, extend will never set 2 handles at once */
|
||||||
*r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
|
*r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
|
||||||
|
|
||||||
@@ -131,43 +126,22 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_c
|
|||||||
|
|
||||||
/* *** Normal Transform *** */
|
/* *** Normal Transform *** */
|
||||||
|
|
||||||
if (seq->depth == 0) {
|
/* Count */
|
||||||
|
|
||||||
/* Count */
|
/* Non nested strips (resect selection and handles) */
|
||||||
|
if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
|
||||||
/* Non nested strips (resect selection and handles) */
|
*r_count = 0;
|
||||||
if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
|
*r_flag = 0;
|
||||||
*r_recursive = false;
|
|
||||||
*r_count = 0;
|
|
||||||
*r_flag = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
|
|
||||||
*r_flag = seq->flag;
|
|
||||||
*r_count = 2; /* we need 2 transdata's */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*r_flag = seq->flag;
|
|
||||||
*r_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 */
|
|
||||||
*r_recursive = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*r_recursive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Nested, different rules apply */
|
if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
|
||||||
|
*r_flag = seq->flag;
|
||||||
*r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
|
*r_count = 2; /* we need 2 transdata's */
|
||||||
*r_count = 1; /* ignore the selection for nested */
|
}
|
||||||
*r_recursive = (seq->type == SEQ_TYPE_META);
|
else {
|
||||||
|
*r_flag = seq->flag;
|
||||||
|
*r_count = 1; /* selected or with a handle selected */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,17 +149,11 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_c
|
|||||||
static int SeqTransCount(TransInfo *t, ListBase *seqbase, int depth)
|
static int SeqTransCount(TransInfo *t, ListBase *seqbase, int depth)
|
||||||
{
|
{
|
||||||
Sequence *seq;
|
Sequence *seq;
|
||||||
int tot = 0, recursive, count, flag;
|
int tot = 0, count, flag;
|
||||||
|
|
||||||
for (seq = seqbase->first; seq; seq = seq->next) {
|
for (seq = seqbase->first; seq; seq = seq->next) {
|
||||||
seq->depth = depth;
|
SeqTransInfo(t, seq, &count, &flag); /* ignore the flag */
|
||||||
|
|
||||||
SeqTransInfo(t, seq, &recursive, &count, &flag); /* ignore the flag */
|
|
||||||
tot += count;
|
tot += count;
|
||||||
|
|
||||||
if (recursive) {
|
|
||||||
tot += SeqTransCount(t, &seq->seqbase, depth + 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tot;
|
return tot;
|
||||||
@@ -251,27 +219,16 @@ static TransData *SeqToTransData(
|
|||||||
return td;
|
return td;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SeqToTransData_Recursive(
|
static int SeqToTransData_build(
|
||||||
TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
|
TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
|
||||||
{
|
{
|
||||||
Sequence *seq;
|
Sequence *seq;
|
||||||
int recursive, count, flag;
|
int count, flag;
|
||||||
int tot = 0;
|
int tot = 0;
|
||||||
|
|
||||||
for (seq = seqbase->first; seq; seq = seq->next) {
|
for (seq = seqbase->first; seq; seq = seq->next) {
|
||||||
|
|
||||||
SeqTransInfo(t, seq, &recursive, &count, &flag);
|
SeqTransInfo(t, seq, &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 */
|
/* use 'flag' which is derived from seq->flag but modified for special cases */
|
||||||
if (flag & SELECT) {
|
if (flag & SELECT) {
|
||||||
@@ -297,13 +254,13 @@ static int SeqToTransData_Recursive(
|
|||||||
static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
|
static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
|
||||||
{
|
{
|
||||||
Sequence *seq;
|
Sequence *seq;
|
||||||
int recursive, count, flag;
|
int count, flag;
|
||||||
int max = INT32_MIN, min = INT32_MAX;
|
int max = INT32_MIN, min = INT32_MAX;
|
||||||
|
|
||||||
for (seq = seqbase->first; seq; seq = seq->next) {
|
for (seq = seqbase->first; seq; seq = seq->next) {
|
||||||
|
|
||||||
/* just to get the flag since there are corner cases where this isn't totally obvious */
|
/* just to get the flag since there are corner cases where this isn't totally obvious */
|
||||||
SeqTransInfo(t, seq, &recursive, &count, &flag);
|
SeqTransInfo(t, seq, &count, &flag);
|
||||||
|
|
||||||
/* use 'flag' which is derived from seq->flag but modified for special cases */
|
/* use 'flag' which is derived from seq->flag but modified for special cases */
|
||||||
if (flag & SELECT) {
|
if (flag & SELECT) {
|
||||||
@@ -347,129 +304,108 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c
|
|||||||
Sequence *seq;
|
Sequence *seq;
|
||||||
|
|
||||||
if (!(t->state == TRANS_CANCEL)) {
|
if (!(t->state == TRANS_CANCEL)) {
|
||||||
|
int overlap = 0;
|
||||||
|
|
||||||
#if 0 /* Default 2.4 behavior. */
|
for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
|
||||||
|
seq = ((TransDataSeq *)td->extra)->seq;
|
||||||
/* flush to 2d vector from internally used 3d vector */
|
if ((seq != seq_prev) && (seq->flag & SEQ_OVERLAP)) {
|
||||||
for (a = 0; a < t->total; a++, td++) {
|
overlap = 1;
|
||||||
if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
|
break;
|
||||||
seq = ((TransDataSeq *)td->extra)->seq;
|
|
||||||
SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
seq_prev = seq;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* durian hack */
|
if (overlap) {
|
||||||
{
|
const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
|
||||||
int overlap = 0;
|
SEQ_MARKER_TRANS) != 0;
|
||||||
|
ListBase *markers = &t->scene->markers;
|
||||||
|
|
||||||
|
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) {
|
for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
|
||||||
seq = ((TransDataSeq *)td->extra)->seq;
|
seq = ((TransDataSeq *)td->extra)->seq;
|
||||||
if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
|
if ((seq != seq_prev)) {
|
||||||
overlap = 1;
|
/* check effects strips, we cant change their time */
|
||||||
break;
|
if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
|
||||||
|
has_effect_any = true;
|
||||||
|
has_effect_root = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Tag seq with a non zero value, used by
|
||||||
|
* SEQ_transform_seqbase_shuffle_time to identify the ones to shuffle */
|
||||||
|
seq->tmp = (void *)1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overlap) {
|
if (t->flag & T_ALT_TRANSFORM) {
|
||||||
const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
|
int minframe = MAXFRAME;
|
||||||
SEQ_MARKER_TRANS) != 0;
|
td = tc->data;
|
||||||
ListBase *markers = &t->scene->markers;
|
for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
|
||||||
|
seq = ((TransDataSeq *)td->extra)->seq;
|
||||||
bool has_effect_root = false, has_effect_any = false;
|
if (seq != seq_prev) {
|
||||||
for (seq = seqbasep->first; seq; seq = seq->next) {
|
minframe = min_ii(minframe, seq->startdisp);
|
||||||
seq->tmp = NULL;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (seq = seqbasep->first; seq; seq = seq->next) {
|
||||||
|
if (!(seq->flag & SELECT)) {
|
||||||
|
if (seq->startdisp >= minframe) {
|
||||||
|
seq->machine += MAXSEQ * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_effect_any) {
|
||||||
|
/* update effects strips based on strips just moved in time */
|
||||||
td = tc->data;
|
td = tc->data;
|
||||||
for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
|
for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
|
||||||
seq = ((TransDataSeq *)td->extra)->seq;
|
seq = ((TransDataSeq *)td->extra)->seq;
|
||||||
if ((seq != seq_prev)) {
|
if ((seq != seq_prev)) {
|
||||||
/* check effects strips, we cant change their time */
|
|
||||||
if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
|
if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
|
||||||
has_effect_any = true;
|
SEQ_time_update_sequence(t->scene, seq);
|
||||||
if (seq->depth == 0) {
|
|
||||||
has_effect_root = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Tag seq with a non zero value, used by
|
|
||||||
* SEQ_transform_seqbase_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;
|
if (has_effect_root) {
|
||||||
td = tc->data;
|
/* now if any effects _still_ overlap, we need to move them up */
|
||||||
for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
|
td = tc->data;
|
||||||
seq = ((TransDataSeq *)td->extra)->seq;
|
for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
|
||||||
if ((seq != seq_prev) && (seq->depth == 0)) {
|
seq = ((TransDataSeq *)td->extra)->seq;
|
||||||
minframe = min_ii(minframe, seq->startdisp);
|
if (seq != seq_prev) {
|
||||||
}
|
if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
|
||||||
}
|
if (SEQ_transform_test_overlap(seqbasep, seq)) {
|
||||||
|
SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
|
||||||
for (seq = seqbasep->first; seq; seq = seq->next) {
|
}
|
||||||
if (!(seq->flag & SELECT)) {
|
}
|
||||||
if (seq->startdisp >= minframe) {
|
}
|
||||||
seq->machine += MAXSEQ * 2;
|
}
|
||||||
}
|
/* done with effects */
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
SEQ_time_update_sequence(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 (SEQ_transform_test_overlap(seqbasep, seq)) {
|
|
||||||
SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* done with effects */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
for (seq = seqbasep->first; seq; seq = seq->next) {
|
for (seq = seqbasep->first; seq; seq = seq->next) {
|
||||||
/* We might want to build a list of effects that need to be updated during transform */
|
/* We might want to build a list of effects that need to be updated during transform */
|
||||||
@@ -492,7 +428,7 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c
|
|||||||
/* Canceled, need to update the strips display */
|
/* Canceled, need to update the strips display */
|
||||||
for (a = 0; a < tc->data_len; a++, td++) {
|
for (a = 0; a < tc->data_len; a++, td++) {
|
||||||
seq = ((TransDataSeq *)td->extra)->seq;
|
seq = ((TransDataSeq *)td->extra)->seq;
|
||||||
if ((seq != seq_prev) && (seq->depth == 0)) {
|
if (seq != seq_prev) {
|
||||||
if (seq->flag & SEQ_OVERLAP) {
|
if (seq->flag & SEQ_OVERLAP) {
|
||||||
SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
|
SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
|
||||||
}
|
}
|
||||||
@@ -574,7 +510,7 @@ void createTransSeqData(TransInfo *t)
|
|||||||
ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq");
|
ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq");
|
||||||
|
|
||||||
/* loop 2: build transdata array */
|
/* loop 2: build transdata array */
|
||||||
SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq);
|
SeqToTransData_build(t, ed->seqbasep, td, td2d, tdsq);
|
||||||
SeqTransDataBounds(t, ed->seqbasep, ts);
|
SeqTransDataBounds(t, ed->seqbasep, ts);
|
||||||
|
|
||||||
if (t->flag & T_MODAL) {
|
if (t->flag & T_MODAL) {
|
||||||
@@ -607,15 +543,10 @@ void createTransSeqData(TransInfo *t)
|
|||||||
|
|
||||||
BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag)
|
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.
|
||||||
/* Calculate this strip and all nested strips.
|
* Children are ALWAYS transformed first so we don't need to do this in another loop.
|
||||||
* Children are ALWAYS transformed first so we don't need to do this in another loop.
|
*/
|
||||||
*/
|
SEQ_time_update_sequence(sce, seq);
|
||||||
SEQ_time_update_sequence(sce, seq);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SEQ_time_update_sequence_bounds(sce, seq);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sel_flag == SELECT) {
|
if (sel_flag == SELECT) {
|
||||||
SEQ_offset_animdata(sce, seq, seq->start - old_start);
|
SEQ_offset_animdata(sce, seq, seq->start - old_start);
|
||||||
@@ -635,102 +566,49 @@ static void flushTransSeq(TransInfo *t)
|
|||||||
|
|
||||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
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 */
|
/* 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++) {
|
for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
|
||||||
int old_start;
|
|
||||||
tdsq = (TransDataSeq *)td->extra;
|
tdsq = (TransDataSeq *)td->extra;
|
||||||
seq = tdsq->seq;
|
seq = tdsq->seq;
|
||||||
old_start = seq->start;
|
|
||||||
new_frame = round_fl_to_int(td2d->loc[0]);
|
new_frame = round_fl_to_int(td2d->loc[0]);
|
||||||
|
|
||||||
switch (tdsq->sel_flag) {
|
switch (tdsq->sel_flag) {
|
||||||
case SELECT:
|
case SELECT:
|
||||||
if ((seq->depth != 0 || SEQ_transform_sequence_can_be_translated(seq))) {
|
if (SEQ_transform_sequence_can_be_translated(seq)) {
|
||||||
/* for meta's, their children move */
|
const int offset = new_frame - tdsq->start_offset - seq->start;
|
||||||
seq->start = new_frame - tdsq->start_offset;
|
SEQ_transform_translate_sequence(t->scene, seq, offset);
|
||||||
}
|
|
||||||
if (seq->depth == 0) {
|
|
||||||
seq->machine = round_fl_to_int(td2d->loc[1]);
|
|
||||||
CLAMP(seq->machine, 1, MAXSEQ);
|
|
||||||
}
|
}
|
||||||
|
seq->machine = round_fl_to_int(td2d->loc[1]);
|
||||||
|
CLAMP(seq->machine, 1, MAXSEQ);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQ_LEFTSEL: /* no vertical transform */
|
case SEQ_LEFTSEL: /* no vertical transform */
|
||||||
SEQ_transform_set_left_handle_frame(seq, new_frame);
|
SEQ_transform_set_left_handle_frame(seq, new_frame);
|
||||||
SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
|
SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
|
||||||
|
|
||||||
/* todo - move this into aftertrans update? - old seq tx needed it anyway */
|
|
||||||
SEQ_transform_fix_single_image_seq_offsets(seq);
|
SEQ_transform_fix_single_image_seq_offsets(seq);
|
||||||
|
SEQ_time_update_sequence(t->scene, seq);
|
||||||
break;
|
break;
|
||||||
case SEQ_RIGHTSEL: /* no vertical transform */
|
case SEQ_RIGHTSEL: /* no vertical transform */
|
||||||
SEQ_transform_set_right_handle_frame(seq, new_frame);
|
SEQ_transform_set_right_handle_frame(seq, new_frame);
|
||||||
SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
|
SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
|
||||||
|
|
||||||
/* todo - move this into aftertrans update? - old seq tx needed it anyway */
|
|
||||||
SEQ_transform_fix_single_image_seq_offsets(seq);
|
SEQ_transform_fix_single_image_seq_offsets(seq);
|
||||||
|
SEQ_time_update_sequence(t->scene, seq);
|
||||||
break;
|
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! */
|
/* Update all effects. */
|
||||||
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)) {
|
if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) {
|
||||||
/* Special annoying case here, need to calc meta-strips with TFM_TIME_EXTEND only */
|
|
||||||
|
|
||||||
/* calc all meta's then effects T27953. */
|
|
||||||
for (seq = seqbasep->first; seq; seq = seq->next) {
|
|
||||||
if (seq->type == SEQ_TYPE_META && seq->flag & SELECT) {
|
|
||||||
SEQ_time_update_sequence(t->scene, seq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (seq = seqbasep->first; seq; seq = seq->next) {
|
for (seq = seqbasep->first; seq; seq = seq->next) {
|
||||||
if (seq->seq1 || seq->seq2 || seq->seq3) {
|
if (seq->seq1 || seq->seq2 || seq->seq3) {
|
||||||
SEQ_time_update_sequence(t->scene, seq);
|
SEQ_time_update_sequence(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) {
|
|
||||||
SEQ_time_update_sequence(t->scene, seq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* need to do the overlap check in a new loop otherwise adjacent strips
|
/* need to do the overlap check in a new loop otherwise adjacent strips
|
||||||
* will not be updated and we'll get false positives */
|
* will not be updated and we'll get false positives */
|
||||||
|
Sequence *seq_prev = NULL;
|
||||||
seq_prev = NULL;
|
seq_prev = NULL;
|
||||||
for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
|
for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
|
||||||
|
|
||||||
@@ -738,12 +616,10 @@ static void flushTransSeq(TransInfo *t)
|
|||||||
seq = tdsq->seq;
|
seq = tdsq->seq;
|
||||||
|
|
||||||
if (seq != seq_prev) {
|
if (seq != seq_prev) {
|
||||||
if (seq->depth == 0) {
|
/* test overlap, displays red outline */
|
||||||
/* test overlap, displays red outline */
|
seq->flag &= ~SEQ_OVERLAP;
|
||||||
seq->flag &= ~SEQ_OVERLAP;
|
if (SEQ_transform_test_overlap(seqbasep, seq)) {
|
||||||
if (SEQ_transform_test_overlap(seqbasep, seq)) {
|
seq->flag |= SEQ_OVERLAP;
|
||||||
seq->flag |= SEQ_OVERLAP;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
seq_prev = seq;
|
seq_prev = seq;
|
||||||
|
@@ -167,8 +167,9 @@ typedef struct Sequence {
|
|||||||
* frames that use the last frame after data ends.
|
* frames that use the last frame after data ends.
|
||||||
*/
|
*/
|
||||||
int startstill, endstill;
|
int startstill, endstill;
|
||||||
/** Machine: the strip channel, depth the depth in the sequence when dealing with metastrips. */
|
/** Machine: the strip channel */
|
||||||
int machine, depth;
|
int machine;
|
||||||
|
int _pad3;
|
||||||
/** Starting and ending points of the strip in the sequence. */
|
/** Starting and ending points of the strip in the sequence. */
|
||||||
int startdisp, enddisp;
|
int startdisp, enddisp;
|
||||||
float sat;
|
float sat;
|
||||||
|
@@ -46,6 +46,7 @@ void SEQ_time_update_sequence(struct Scene *scene, struct Sequence *seq);
|
|||||||
void SEQ_time_update_sequence_bounds(struct Scene *scene, struct Sequence *seq);
|
void SEQ_time_update_sequence_bounds(struct Scene *scene, struct Sequence *seq);
|
||||||
int SEQ_time_cmp_time_startdisp(const void *a, const void *b);
|
int SEQ_time_cmp_time_startdisp(const void *a, const void *b);
|
||||||
bool SEQ_time_strip_intersects_frame(const struct Sequence *seq, const int timeline_frame);
|
bool SEQ_time_strip_intersects_frame(const struct Sequence *seq, const int timeline_frame);
|
||||||
|
void SEQ_time_update_meta_strip_range(struct Scene *scene, struct Sequence *seq_meta);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -184,7 +184,7 @@ static void seq_time_update_meta_strip(Scene *scene, Sequence *seq_meta)
|
|||||||
seq_update_sound_bounds_recursive(scene, seq_meta);
|
seq_update_sound_bounds_recursive(scene, seq_meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void seq_time_update_meta_strip_range(Scene *scene, Sequence *seq_meta)
|
void SEQ_time_update_meta_strip_range(Scene *scene, Sequence *seq_meta)
|
||||||
{
|
{
|
||||||
seq_time_update_meta_strip(scene, seq_meta);
|
seq_time_update_meta_strip(scene, seq_meta);
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ void SEQ_time_update_sequence(Scene *scene, Sequence *seq)
|
|||||||
Editing *ed = SEQ_editing_get(scene, false);
|
Editing *ed = SEQ_editing_get(scene, false);
|
||||||
MetaStack *ms = SEQ_meta_stack_active_get(ed);
|
MetaStack *ms = SEQ_meta_stack_active_get(ed);
|
||||||
if (ms != NULL) {
|
if (ms != NULL) {
|
||||||
seq_time_update_meta_strip_range(scene, ms->parseq);
|
SEQ_time_update_meta_strip_range(scene, ms->parseq);
|
||||||
}
|
}
|
||||||
|
|
||||||
SEQ_time_update_sequence_bounds(scene, seq);
|
SEQ_time_update_sequence_bounds(scene, seq);
|
||||||
|
@@ -233,14 +233,22 @@ void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delt
|
|||||||
SEQ_offset_animdata(evil_scene, seq, delta);
|
SEQ_offset_animdata(evil_scene, seq, delta);
|
||||||
seq->start += delta;
|
seq->start += delta;
|
||||||
|
|
||||||
|
/* Meta strips requires special handling: their content is to be translated, and then frame range
|
||||||
|
* of the meta is to be updated for the updated content. */
|
||||||
if (seq->type == SEQ_TYPE_META) {
|
if (seq->type == SEQ_TYPE_META) {
|
||||||
Sequence *seq_child;
|
Sequence *seq_child;
|
||||||
for (seq_child = seq->seqbase.first; seq_child; seq_child = seq_child->next) {
|
for (seq_child = seq->seqbase.first; seq_child; seq_child = seq_child->next) {
|
||||||
SEQ_transform_translate_sequence(evil_scene, seq_child, delta);
|
SEQ_transform_translate_sequence(evil_scene, seq_child, delta);
|
||||||
}
|
}
|
||||||
|
/* Ensure that meta bounds are updated, but this function prevents resets seq->start and
|
||||||
|
* start/end point in timeline. */
|
||||||
|
SEQ_time_update_meta_strip_range(evil_scene, seq);
|
||||||
|
/* Move meta start/end points. */
|
||||||
|
SEQ_transform_set_left_handle_frame(seq, seq->startdisp + delta);
|
||||||
|
SEQ_transform_set_right_handle_frame(seq, seq->enddisp + delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
SEQ_time_update_sequence_bounds(evil_scene, seq);
|
SEQ_time_update_sequence(evil_scene, seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return 0 if there weren't enough space */
|
/* return 0 if there weren't enough space */
|
||||||
|
Reference in New Issue
Block a user