Blender  V2.93
transform_convert_sequencer.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include "DNA_space_types.h"
25 
26 #include "MEM_guardedalloc.h"
27 
28 #include "BLI_listbase.h"
29 #include "BLI_math.h"
30 
31 #include "BKE_context.h"
32 #include "BKE_report.h"
33 
34 #include "ED_markers.h"
35 
36 #include "SEQ_relations.h"
37 #include "SEQ_sequencer.h"
38 #include "SEQ_time.h"
39 #include "SEQ_transform.h"
40 #include "SEQ_utils.h"
41 
42 #include "UI_view2d.h"
43 
44 #include "transform.h"
45 #include "transform_convert.h"
46 
48 typedef struct TransDataSeq {
49  struct Sequence *seq;
51  int flag;
56  short sel_flag;
57 
59 
63 typedef struct TransSeq {
65  int min;
66  int max;
67  bool snap_left;
71 
72 /* -------------------------------------------------------------------- */
76 /* This function applies the rules for transforming a strip so duplicate
77  * checks don't need to be added in multiple places.
78  *
79  * recursive, count and flag MUST be set.
80  *
81  * seq->depth must be set before running this function so we know if the strips
82  * are root level or not
83  */
84 static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_count, int *r_flag)
85 {
86  /* for extend we need to do some tricks */
87  if (t->mode == TFM_TIME_EXTEND) {
88 
89  /* *** Extend Transform *** */
90 
91  Scene *scene = t->scene;
92  int cfra = CFRA;
93  int left = SEQ_transform_get_left_handle_frame(seq, false);
95 
96  if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
97  *r_recursive = false;
98  *r_count = 0;
99  *r_flag = 0;
100  }
101  else {
102  *r_recursive = false;
103  *r_count = 1; /* unless its set to 0, extend will never set 2 handles at once */
104  *r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
105 
106  if (t->frame_side == 'R') {
107  if (right <= cfra) {
108  *r_count = *r_flag = 0;
109  } /* ignore */
110  else if (left > cfra) {
111  } /* keep the selection */
112  else {
113  *r_flag |= SEQ_RIGHTSEL;
114  }
115  }
116  else {
117  if (left >= cfra) {
118  *r_count = *r_flag = 0;
119  } /* ignore */
120  else if (right < cfra) {
121  } /* keep the selection */
122  else {
123  *r_flag |= SEQ_LEFTSEL;
124  }
125  }
126  }
127  }
128  else {
129 
130  t->frame_side = 'B';
131 
132  /* *** Normal Transform *** */
133 
134  if (seq->depth == 0) {
135 
136  /* Count */
137 
138  /* Non nested strips (resect selection and handles) */
139  if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
140  *r_recursive = false;
141  *r_count = 0;
142  *r_flag = 0;
143  }
144  else {
145  if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
146  *r_flag = seq->flag;
147  *r_count = 2; /* we need 2 transdata's */
148  }
149  else {
150  *r_flag = seq->flag;
151  *r_count = 1; /* selected or with a handle selected */
152  }
153 
154  /* Recursive */
155 
156  if ((seq->type == SEQ_TYPE_META) && ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0)) {
157  /* if any handles are selected, don't recurse */
158  *r_recursive = true;
159  }
160  else {
161  *r_recursive = false;
162  }
163  }
164  }
165  else {
166  /* Nested, different rules apply */
167 
168  *r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
169  *r_count = 1; /* ignore the selection for nested */
170  *r_recursive = (seq->type == SEQ_TYPE_META);
171  }
172  }
173 }
174 
175 static int SeqTransCount(TransInfo *t, Sequence *parent, ListBase *seqbase, int depth)
176 {
177  Sequence *seq;
178  int tot = 0, recursive, count, flag;
179 
180  for (seq = seqbase->first; seq; seq = seq->next) {
181  seq->depth = depth;
182 
183  /* 'seq->tmp' is used by seq_tx_get_final_{left, right}
184  * to check sequence's range and clamp to it if needed.
185  * It's first place where digging into sequences tree, so store link to parent here. */
186  seq->tmp = parent;
187 
188  SeqTransInfo(t, seq, &recursive, &count, &flag); /* ignore the flag */
189  tot += count;
190 
191  if (recursive) {
192  tot += SeqTransCount(t, seq, &seq->seqbase, depth + 1);
193  }
194  }
195 
196  return tot;
197 }
198 
200  TransData *td, TransData2D *td2d, TransDataSeq *tdsq, Sequence *seq, int flag, int sel_flag)
201 {
202  int start_left;
203 
204  switch (sel_flag) {
205  case SELECT:
206  /* Use seq_tx_get_final_left() and an offset here
207  * so transform has the left hand location of the strip.
208  * tdsq->start_offset is used when flushing the tx data back */
209  start_left = SEQ_transform_get_left_handle_frame(seq, false);
210  td2d->loc[0] = start_left;
211  tdsq->start_offset = start_left - seq->start; /* use to apply the original location */
212  break;
213  case SEQ_LEFTSEL:
214  start_left = SEQ_transform_get_left_handle_frame(seq, false);
215  td2d->loc[0] = start_left;
216  break;
217  case SEQ_RIGHTSEL:
218  td2d->loc[0] = SEQ_transform_get_right_handle_frame(seq, false);
219  break;
220  }
221 
222  td2d->loc[1] = seq->machine; /* channel - Y location */
223  td2d->loc[2] = 0.0f;
224  td2d->loc2d = NULL;
225 
226  tdsq->seq = seq;
227 
228  /* Use instead of seq->flag for nested strips and other
229  * cases where the selection may need to be modified */
230  tdsq->flag = flag;
231  tdsq->sel_flag = sel_flag;
232 
233  td->extra = (void *)tdsq; /* allow us to update the strip from here */
234 
235  td->flag = 0;
236  td->loc = td2d->loc;
237  copy_v3_v3(td->center, td->loc);
238  copy_v3_v3(td->iloc, td->loc);
239 
240  memset(td->axismtx, 0, sizeof(td->axismtx));
241  td->axismtx[2][2] = 1.0f;
242 
243  td->ext = NULL;
244  td->val = NULL;
245 
246  td->flag |= TD_SELECTED;
247  td->dist = 0.0;
248 
249  unit_m3(td->mtx);
250  unit_m3(td->smtx);
251 
252  /* Time Transform (extend) */
253  td->val = td2d->loc;
254  td->ival = td2d->loc[0];
255 
256  return td;
257 }
258 
260  TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
261 {
262  Sequence *seq;
263  int recursive, count, flag;
264  int tot = 0;
265 
266  for (seq = seqbase->first; seq; seq = seq->next) {
267 
268  SeqTransInfo(t, seq, &recursive, &count, &flag);
269 
270  /* add children first so recalculating metastrips does nested strips first */
271  if (recursive) {
272  int tot_children = SeqToTransData_Recursive(t, &seq->seqbase, td, td2d, tdsq);
273 
274  td = td + tot_children;
275  td2d = td2d + tot_children;
276  tdsq = tdsq + tot_children;
277 
278  tot += tot_children;
279  }
280 
281  /* use 'flag' which is derived from seq->flag but modified for special cases */
282  if (flag & SELECT) {
283  if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
284  if (flag & SEQ_LEFTSEL) {
285  SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_LEFTSEL);
286  tot++;
287  }
288  if (flag & SEQ_RIGHTSEL) {
289  SeqToTransData(td++, td2d++, tdsq++, seq, flag, SEQ_RIGHTSEL);
290  tot++;
291  }
292  }
293  else {
294  SeqToTransData(td++, td2d++, tdsq++, seq, flag, SELECT);
295  tot++;
296  }
297  }
298  }
299  return tot;
300 }
301 
302 static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
303 {
304  Sequence *seq;
305  int recursive, count, flag;
306  int max = INT32_MIN, min = INT32_MAX;
307 
308  for (seq = seqbase->first; seq; seq = seq->next) {
309 
310  /* just to get the flag since there are corner cases where this isn't totally obvious */
311  SeqTransInfo(t, seq, &recursive, &count, &flag);
312 
313  /* use 'flag' which is derived from seq->flag but modified for special cases */
314  if (flag & SELECT) {
315  if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
316  if (flag & SEQ_LEFTSEL) {
317  min = min_ii(seq->startdisp, min);
318  max = max_ii(seq->startdisp, max);
319  }
320  if (flag & SEQ_RIGHTSEL) {
321  min = min_ii(seq->enddisp, min);
322  max = max_ii(seq->enddisp, max);
323  }
324  }
325  else {
326  min = min_ii(seq->startdisp, min);
327  max = max_ii(seq->enddisp, max);
328  }
329  }
330  }
331 
332  if (ts) {
333  ts->max = max;
334  ts->min = min;
335  }
336 }
337 
338 static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
339 {
340  Editing *ed = SEQ_editing_get(t->scene, false);
341 
342  if (ed != NULL) {
343 
344  ListBase *seqbasep = ed->seqbasep;
345  TransData *td = tc->data;
346  int a;
347 
348  /* prevent updating the same seq twice
349  * if the transdata order is changed this will mess up
350  * but so will TransDataSeq */
351  Sequence *seq_prev = NULL;
352  Sequence *seq;
353 
354  if (!(t->state == TRANS_CANCEL)) {
355 
356 #if 0 /* Default 2.4 behavior. */
357 
358  /* flush to 2d vector from internally used 3d vector */
359  for (a = 0; a < t->total; a++, td++) {
360  if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
361  seq = ((TransDataSeq *)td->extra)->seq;
362  SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
363  }
364 
365  seq_prev = seq;
366  }
367 
368 #else /* durian hack */
369  {
370  int overlap = 0;
371 
372  for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
373  seq = ((TransDataSeq *)td->extra)->seq;
374  if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
375  overlap = 1;
376  break;
377  }
378  }
379 
380  if (overlap) {
381  const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
382  SEQ_MARKER_TRANS) != 0;
383  ListBase *markers = &t->scene->markers;
384 
385  bool has_effect_root = false, has_effect_any = false;
386  for (seq = seqbasep->first; seq; seq = seq->next) {
387  seq->tmp = NULL;
388  }
389 
390  td = tc->data;
391  for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
392  seq = ((TransDataSeq *)td->extra)->seq;
393  if ((seq != seq_prev)) {
394  /* check effects strips, we cant change their time */
395  if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
396  has_effect_any = true;
397  if (seq->depth == 0) {
398  has_effect_root = true;
399  }
400  }
401  else {
402  /* Tag seq with a non zero value, used by
403  * SEQ_transform_seqbase_shuffle_time to identify the ones to shuffle */
404  if (seq->depth == 0) {
405  seq->tmp = (void *)1;
406  }
407  }
408  }
409  }
410 
411  if (t->flag & T_ALT_TRANSFORM) {
412  int minframe = MAXFRAME;
413  td = tc->data;
414  for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
415  seq = ((TransDataSeq *)td->extra)->seq;
416  if ((seq != seq_prev) && (seq->depth == 0)) {
417  minframe = min_ii(minframe, seq->startdisp);
418  }
419  }
420 
421  for (seq = seqbasep->first; seq; seq = seq->next) {
422  if (!(seq->flag & SELECT)) {
423  if (seq->startdisp >= minframe) {
424  seq->machine += MAXSEQ * 2;
425  }
426  }
427  }
428 
429  SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
430 
431  for (seq = seqbasep->first; seq; seq = seq->next) {
432  if (seq->machine >= MAXSEQ * 2) {
433  seq->machine -= MAXSEQ * 2;
434  seq->tmp = (void *)1;
435  }
436  else {
437  seq->tmp = NULL;
438  }
439  }
440 
441  SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
442  }
443  else {
444  SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers);
445  }
446 
447  if (has_effect_any) {
448  /* update effects strips based on strips just moved in time */
449  td = tc->data;
450  for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
451  seq = ((TransDataSeq *)td->extra)->seq;
452  if ((seq != seq_prev)) {
453  if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
454  SEQ_time_update_sequence(t->scene, seq);
455  }
456  }
457  }
458  }
459 
460  if (has_effect_root) {
461  /* now if any effects _still_ overlap, we need to move them up */
462  td = tc->data;
463  for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
464  seq = ((TransDataSeq *)td->extra)->seq;
465  if ((seq != seq_prev) && (seq->depth == 0)) {
466  if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
467  if (SEQ_transform_test_overlap(seqbasep, seq)) {
468  SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
469  }
470  }
471  }
472  }
473  /* done with effects */
474  }
475  }
476  }
477 #endif
478 
479  for (seq = seqbasep->first; seq; seq = seq->next) {
480  /* We might want to build a list of effects that need to be updated during transform */
481  if (seq->type & SEQ_TYPE_EFFECT) {
482  if (seq->seq1 && seq->seq1->flag & SELECT) {
483  SEQ_time_update_sequence(t->scene, seq);
484  }
485  else if (seq->seq2 && seq->seq2->flag & SELECT) {
486  SEQ_time_update_sequence(t->scene, seq);
487  }
488  else if (seq->seq3 && seq->seq3->flag & SELECT) {
489  SEQ_time_update_sequence(t->scene, seq);
490  }
491  }
492  }
493 
494  SEQ_sort(t->scene);
495  }
496  else {
497  /* Canceled, need to update the strips display */
498  for (a = 0; a < tc->data_len; a++, td++) {
499  seq = ((TransDataSeq *)td->extra)->seq;
500  if ((seq != seq_prev) && (seq->depth == 0)) {
501  if (seq->flag & SEQ_OVERLAP) {
502  SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene);
503  }
504 
505  SEQ_time_update_sequence_bounds(t->scene, seq);
506  }
507  seq_prev = seq;
508  }
509  }
510  }
511 
512  if ((custom_data->data != NULL) && custom_data->use_free) {
513  TransSeq *ts = custom_data->data;
514  MEM_freeN(ts->tdseq);
515  MEM_freeN(custom_data->data);
516  custom_data->data = NULL;
517  }
518 
520 }
521 
523 {
524 #define XXX_DURIAN_ANIM_TX_HACK
525 
526  Scene *scene = t->scene;
527  Editing *ed = SEQ_editing_get(t->scene, false);
528  TransData *td = NULL;
529  TransData2D *td2d = NULL;
530  TransDataSeq *tdsq = NULL;
531  TransSeq *ts = NULL;
532 
533  int count = 0;
534 
536 
537  if (ed == NULL) {
538  tc->data_len = 0;
539  return;
540  }
541 
543  t->frame_side = transform_convert_frame_side_dir_get(t, (float)CFRA);
544 
545 #ifdef XXX_DURIAN_ANIM_TX_HACK
546  {
547  Sequence *seq;
548  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
549  /* hack */
550  if ((seq->flag & SELECT) == 0 && seq->type & SEQ_TYPE_EFFECT) {
551  Sequence *seq_user;
552  int i;
553  for (i = 0; i < 3; i++) {
554  seq_user = *((&seq->seq1) + i);
555  if (seq_user && (seq_user->flag & SELECT) && !(seq_user->flag & SEQ_LOCK) &&
556  !(seq_user->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL))) {
557  seq->flag |= SELECT;
558  }
559  }
560  }
561  }
562  }
563 #endif
564 
565  count = SeqTransCount(t, NULL, ed->seqbasep, 0);
566 
567  /* allocate memory for data */
568  tc->data_len = count;
569 
570  /* stop if trying to build list if nothing selected */
571  if (count == 0) {
572  return;
573  }
574 
575  tc->custom.type.data = ts = MEM_callocN(sizeof(TransSeq), "transseq");
576  tc->custom.type.use_free = true;
577  td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransSeq TransData");
578  td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D");
579  ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq");
580 
581  /* loop 2: build transdata array */
582  SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq);
583  SeqTransDataBounds(t, ed->seqbasep, ts);
584 
585  if (t->flag & T_MODAL) {
586  /* set the snap mode based on how close the mouse is at the end/start points */
587  int xmouse = (int)UI_view2d_region_to_view_x((View2D *)t->view, t->mouse.imval[0]);
588  if (abs(xmouse - ts->max) > abs(xmouse - ts->min)) {
589  ts->snap_left = true;
590  }
591  }
592 
595  if ((seq->flag & SELECT) != 0) {
598  }
599  }
600 
601 #undef XXX_DURIAN_ANIM_TX_HACK
602 }
603 
606 /* -------------------------------------------------------------------- */
610 /* commented _only_ because the meta may have animation data which
611  * needs moving too T28158. */
612 
613 BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag)
614 {
615  if (seq->depth == 0) {
616  /* Calculate this strip and all nested strips.
617  * Children are ALWAYS transformed first so we don't need to do this in another loop.
618  */
619  SEQ_time_update_sequence(sce, seq);
620  }
621  else {
623  }
624 
625  if (sel_flag == SELECT) {
626  SEQ_offset_animdata(sce, seq, seq->start - old_start);
627  }
628 }
629 
630 static void flushTransSeq(TransInfo *t)
631 {
632  /* Editing null check already done */
633  ListBase *seqbasep = SEQ_editing_get(t->scene, false)->seqbasep;
634 
635  int a, new_frame;
636  TransData *td = NULL;
637  TransData2D *td2d = NULL;
638  TransDataSeq *tdsq = NULL;
639  Sequence *seq;
640 
642 
643  /* prevent updating the same seq twice
644  * if the transdata order is changed this will mess up
645  * but so will TransDataSeq */
646  Sequence *seq_prev = NULL;
647  int old_start_prev = 0, sel_flag_prev = 0;
648 
649  /* flush to 2d vector from internally used 3d vector */
650  for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
651  int old_start;
652  tdsq = (TransDataSeq *)td->extra;
653  seq = tdsq->seq;
654  old_start = seq->start;
655  new_frame = round_fl_to_int(td2d->loc[0]);
656 
657  switch (tdsq->sel_flag) {
658  case SELECT:
659  if ((seq->depth != 0 || SEQ_transform_sequence_can_be_translated(seq))) {
660  /* for meta's, their children move */
661  seq->start = new_frame - tdsq->start_offset;
662  }
663  if (seq->depth == 0) {
664  seq->machine = round_fl_to_int(td2d->loc[1]);
665  CLAMP(seq->machine, 1, MAXSEQ);
666  }
667  break;
668  case SEQ_LEFTSEL: /* no vertical transform */
669  SEQ_transform_set_left_handle_frame(seq, new_frame);
671 
672  /* todo - move this into aftertrans update? - old seq tx needed it anyway */
674  break;
675  case SEQ_RIGHTSEL: /* no vertical transform */
676  SEQ_transform_set_right_handle_frame(seq, new_frame);
678 
679  /* todo - move this into aftertrans update? - old seq tx needed it anyway */
681  break;
682  }
683 
684  /* Update *previous* seq! Else, we would update a seq after its first transform,
685  * and if it has more than one (like e.g. SEQ_LEFTSEL and SEQ_RIGHTSEL),
686  * the others are not updated! See T38469.
687  */
688  if (seq != seq_prev) {
689  if (seq_prev) {
690  trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
691  }
692 
693  seq_prev = seq;
694  old_start_prev = old_start;
695  sel_flag_prev = tdsq->sel_flag;
696  }
697  else {
698  /* We want to accumulate *all* sel_flags for this seq! */
699  sel_flag_prev |= tdsq->sel_flag;
700  }
701  }
702 
703  /* Don't forget to update the last seq! */
704  if (seq_prev) {
705  trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
706  }
707 
708  /* originally TFM_TIME_EXTEND, transform changes */
709  if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) {
710  /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */
711 
712  /* calc all meta's then effects T27953. */
713  for (seq = seqbasep->first; seq; seq = seq->next) {
714  if (seq->type == SEQ_TYPE_META && seq->flag & SELECT) {
715  SEQ_time_update_sequence(t->scene, seq);
716  }
717  }
718  for (seq = seqbasep->first; seq; seq = seq->next) {
719  if (seq->seq1 || seq->seq2 || seq->seq3) {
720  SEQ_time_update_sequence(t->scene, seq);
721  }
722  }
723 
724  /* update effects inside meta's */
725  for (a = 0, seq_prev = NULL, td = tc->data, td2d = tc->data_2d; a < tc->data_len;
726  a++, td++, td2d++, seq_prev = seq) {
727  tdsq = (TransDataSeq *)td->extra;
728  seq = tdsq->seq;
729  if ((seq != seq_prev) && (seq->depth != 0)) {
730  if (seq->seq1 || seq->seq2 || seq->seq3) {
731  SEQ_time_update_sequence(t->scene, seq);
732  }
733  }
734  }
735  }
736 
737  /* need to do the overlap check in a new loop otherwise adjacent strips
738  * will not be updated and we'll get false positives */
739  seq_prev = NULL;
740  for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
741 
742  tdsq = (TransDataSeq *)td->extra;
743  seq = tdsq->seq;
744 
745  if (seq != seq_prev) {
746  if (seq->depth == 0) {
747  /* test overlap, displays red outline */
748  seq->flag &= ~SEQ_OVERLAP;
749  if (SEQ_transform_test_overlap(seqbasep, seq)) {
750  seq->flag |= SEQ_OVERLAP;
751  }
752  }
753  }
754  seq_prev = seq;
755  }
756 }
757 
758 /* helper for recalcData() - for sequencer transforms */
760 {
761  TransData *td;
762  int a;
763  Sequence *seq_prev = NULL;
764 
766 
767  for (a = 0, td = tc->data; a < tc->data_len; a++, td++) {
768  TransDataSeq *tdsq = (TransDataSeq *)td->extra;
769  Sequence *seq = tdsq->seq;
770 
771  if (seq != seq_prev) {
773  }
774 
775  seq_prev = seq;
776  }
777 
779 
780  flushTransSeq(t);
781 }
782 
785 /* -------------------------------------------------------------------- */
790 {
791  if (t->state == TRANS_CANCEL) {
792  return;
793  }
794  /* freeSeqData in transform_conversions.c does this
795  * keep here so the else at the end wont run... */
796 
797  SpaceSeq *sseq = (SpaceSeq *)t->area->spacedata.first;
798 
799  /* Marker transform, not especially nice but we may want to move markers
800  * at the same time as strips in the Video Sequencer. */
801  if (sseq->flag & SEQ_MARKER_TRANS) {
802  /* can't use TFM_TIME_EXTEND
803  * for some reason EXTEND is changed into TRANSLATE, so use frame_side instead */
804 
805  if (t->mode == TFM_SEQ_SLIDE) {
806  if (t->frame_side == 'B') {
808  &t->scene->markers, t->scene, TFM_TIME_TRANSLATE, t->values_final[0], t->frame_side);
809  }
810  }
811  else if (ELEM(t->frame_side, 'L', 'R')) {
813  &t->scene->markers, t->scene, TFM_TIME_EXTEND, t->values_final[0], t->frame_side);
814  }
815  }
816 }
817 
819 {
820  const TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
821  const int channel_offset = round_fl_to_int(t->values[1]);
822  const int min_channel_after_transform = ts->selection_channel_range_min + channel_offset;
823  const int max_channel_after_transform = ts->selection_channel_range_max + channel_offset;
824 
825  if (max_channel_after_transform > MAXSEQ) {
826  t->values[1] -= max_channel_after_transform - MAXSEQ;
827  }
828  if (min_channel_after_transform < 1) {
829  t->values[1] -= min_channel_after_transform - 1;
830  }
831 }
832 
834 {
835  TransSeq *ts = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
836  return ts->snap_left ? ts->min : ts->max;
837 }
838 
#define BLI_INLINE
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
MINLINE int round_fl_to_int(float a)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define UNUSED(x)
#define ELEM(...)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_SEQUENCER_STRIPS
Definition: DNA_ID.h:658
#define CFRA
#define MAXFRAME
@ SEQ_RIGHTSEL
@ SEQ_OVERLAP
@ SEQ_LOCK
@ SEQ_LEFTSEL
#define MAXSEQ
@ SEQ_TYPE_META
@ SEQ_TYPE_EFFECT
@ SEQ_MARKER_TRANS
@ TFM_TIME_TRANSLATE
Definition: ED_transform.h:65
@ TFM_TIME_EXTEND
Definition: ED_transform.h:68
@ TFM_SEQ_SLIDE
Definition: ED_transform.h:76
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble right
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera CLAMP
#define C
Definition: RandGen.cpp:39
float UI_view2d_region_to_view_x(const struct View2D *v2d, float x)
Definition: view2d.c:1659
int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, float value, char side)
Definition: anim_markers.c:130
#define SELECT
Scene scene
const vector< Marker > & markers
int count
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static int left
static unsigned a[3]
Definition: RandGen.cpp:92
ListBase * SEQ_active_seqbase_get(const Editing *ed)
Definition: sequencer.c:350
void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs)
Definition: sequencer.c:620
Editing * SEQ_editing_get(Scene *scene, bool alloc)
Definition: sequencer.c:232
#define min(a, b)
Definition: sort.c:51
#define INT32_MAX
Definition: stdint.h:140
#define INT32_MIN
Definition: stdint.h:139
void SEQ_relations_invalidate_cache_composite(Scene *scene, Sequence *seq)
void SEQ_time_update_sequence_bounds(Scene *scene, Sequence *seq)
Definition: strip_time.c:150
void SEQ_time_update_sequence(Scene *scene, Sequence *seq)
Definition: strip_time.c:197
bool SEQ_transform_seqbase_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
bool SEQ_transform_sequence_can_be_translated(Sequence *seq)
bool SEQ_transform_test_overlap(ListBase *seqbasep, Sequence *test)
void SEQ_transform_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
void SEQ_transform_fix_single_image_seq_offsets(Sequence *seq)
void SEQ_transform_set_right_handle_frame(Sequence *seq, int val)
int SEQ_transform_get_right_handle_frame(Sequence *seq, bool metaclip)
bool SEQ_transform_seqbase_shuffle_time(ListBase *seqbasep, Scene *evil_scene, ListBase *markers, const bool use_sync_markers)
void SEQ_transform_set_left_handle_frame(Sequence *seq, int val)
int SEQ_transform_get_left_handle_frame(Sequence *seq, bool metaclip)
ListBase * seqbasep
void * first
Definition: DNA_listBase.h:47
struct Sequence * seq3
ListBase seqbase
struct Sequence * seq1
struct Sequence * seq2
struct Sequence * next
TransCustomData type
Definition: transform.h:428
unsigned int use_free
Definition: transform.h:408
void(* free_cb)(struct TransInfo *, struct TransDataContainer *tc, struct TransCustomData *custom_data)
Definition: transform.h:405
float loc[3]
TransCustomDataContainer custom
Definition: transform.h:501
TransData * data
Definition: transform.h:448
TransData2D * data_2d
Definition: transform.h:452
struct Sequence * seq
float smtx[3][3]
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
float * val
TransDataSeq * tdseq
@ T_MODAL
Definition: transform.h:132
@ T_ALT_TRANSFORM
Definition: transform.h:140
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition: transform.h:810
@ TRANS_CANCEL
Definition: transform.h:193
char transform_convert_frame_side_dir_get(TransInfo *t, float cframe)
conversion and adaptation of different datablocks to a common struct.
static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
static void flushTransSeq(TransInfo *t)
static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
static int SeqTransCount(TransInfo *t, Sequence *parent, ListBase *seqbase, int depth)
void createTransSeqData(TransInfo *t)
struct TransDataSeq TransDataSeq
int transform_convert_sequencer_get_snap_bound(TransInfo *t)
void transform_convert_sequencer_channel_clamp(TransInfo *t)
static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_count, int *r_flag)
static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
static TransData * SeqToTransData(TransData *td, TransData2D *td2d, TransDataSeq *tdsq, Sequence *seq, int flag, int sel_flag)
BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag)
void recalcData_sequencer(TransInfo *t)
struct TransSeq TransSeq
void special_aftertrans_update__sequencer(bContext *UNUSED(C), TransInfo *t)
@ TD_SELECTED
float max
__forceinline const avxi abs(const avxi &a)
Definition: util_avxi.h:186
void SEQ_sort(Scene *scene)
Definition: utils.c:58