Blender V4.3
transform_convert_sequencer.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include "DNA_space_types.h"
11
12#include "MEM_guardedalloc.h"
13
14#include "BLI_listbase.h"
15#include "BLI_math_matrix.h"
16#include "BLI_math_vector.h"
17
18#include "BKE_report.hh"
19
20#include "ED_markers.hh"
21
22#include "SEQ_animation.hh"
23#include "SEQ_channels.hh"
24#include "SEQ_iterator.hh"
25#include "SEQ_relations.hh"
26#include "SEQ_sequencer.hh"
27#include "SEQ_time.hh"
28#include "SEQ_transform.hh"
29
30#include "UI_view2d.hh"
31
32#include "transform.hh"
33#include "transform_convert.hh"
34#include "transform_mode.hh"
35
36#define SEQ_EDGE_PAN_INSIDE_PAD 3.5
37#define SEQ_EDGE_PAN_OUTSIDE_PAD 0 /* Disable clamping for panning, use whole screen. */
38#define SEQ_EDGE_PAN_SPEED_RAMP 1
39#define SEQ_EDGE_PAN_MAX_SPEED 4 /* In UI units per second, slower than default. */
40#define SEQ_EDGE_PAN_DELAY 1.0f
41#define SEQ_EDGE_PAN_ZOOM_INFLUENCE 0.5f
42
54
58struct TransSeq {
62
63 /* Initial rect of the view2d, used for computing offset during edge panning. */
66
67 /* Strips that aren't selected, but their position entirely depends on transformed strips. */
69};
70
71/* -------------------------------------------------------------------- */
75/* This function applies the rules for transforming a strip so duplicate
76 * checks don't need to be added in multiple places.
77 *
78 * count and flag MUST be set.
79 */
80static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag)
81{
82 Scene *scene = t->scene;
85
86 /* For extend we need to do some tricks. */
87 if (t->mode == TFM_TIME_EXTEND) {
88
89 /* *** Extend Transform *** */
90 int cfra = scene->r.cfra;
91 int left = SEQ_time_left_handle_frame_get(scene, seq);
92 int right = SEQ_time_right_handle_frame_get(scene, seq);
93
94 if ((seq->flag & SELECT) == 0 || SEQ_transform_is_locked(channels, seq)) {
95 *r_count = 0;
96 *r_flag = 0;
97 }
98 else {
99 *r_count = 1; /* Unless its set to 0, extend will never set 2 handles at once. */
100 *r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
101
102 if (t->frame_side == 'R') {
103 if (right <= cfra) {
104 *r_count = *r_flag = 0;
105 } /* Ignore. */
106 else if (left > cfra) {
107 } /* Keep the selection. */
108 else {
109 *r_flag |= SEQ_RIGHTSEL;
110 }
111 }
112 else {
113 if (left >= cfra) {
114 *r_count = *r_flag = 0;
115 } /* Ignore. */
116 else if (right < cfra) {
117 } /* Keep the selection. */
118 else {
119 *r_flag |= SEQ_LEFTSEL;
120 }
121 }
122 }
123 }
124 else {
125
126 t->frame_side = 'B';
127
128 /* *** Normal Transform *** */
129
130 /* Count. */
131
132 /* Non nested strips (reset selection and handles). */
133 if ((seq->flag & SELECT) == 0 || SEQ_transform_is_locked(channels, seq)) {
134 *r_count = 0;
135 *r_flag = 0;
136 }
137 else {
138 if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
139 *r_flag = seq->flag;
140 *r_count = 2; /* We need 2 transdata's. */
141 }
142 else {
143 *r_flag = seq->flag;
144 *r_count = 1; /* Selected or with a handle selected. */
145 }
146 }
147 }
148}
149
150static int SeqTransCount(TransInfo *t, ListBase *seqbase)
151{
152 int tot = 0, count, flag;
153
154 LISTBASE_FOREACH (Sequence *, seq, seqbase) {
155 SeqTransInfo(t, seq, &count, &flag); /* Ignore the flag. */
156 tot += count;
157 }
158
159 return tot;
160}
161
163 TransData *td,
164 TransData2D *td2d,
165 TransDataSeq *tdsq,
166 Sequence *seq,
167 int flag,
168 int sel_flag)
169{
170 int start_left;
171
172 switch (sel_flag) {
173 case SELECT:
174 /* Use seq_tx_get_final_left() and an offset here
175 * so transform has the left hand location of the strip.
176 * `tdsq->start_offset` is used when flushing the tx data back. */
177 start_left = SEQ_time_left_handle_frame_get(scene, seq);
178 td2d->loc[0] = start_left;
179 tdsq->start_offset = start_left - seq->start; /* Use to apply the original location. */
180 break;
181 case SEQ_LEFTSEL:
182 start_left = SEQ_time_left_handle_frame_get(scene, seq);
183 td2d->loc[0] = start_left;
184 break;
185 case SEQ_RIGHTSEL:
186 td2d->loc[0] = SEQ_time_right_handle_frame_get(scene, seq);
187 break;
188 }
189
190 td2d->loc[1] = seq->machine; /* Channel - Y location. */
191 td2d->loc[2] = 0.0f;
192 td2d->loc2d = nullptr;
193
194 tdsq->seq = seq;
195
196 /* Use instead of seq->flag for nested strips and other
197 * cases where the selection may need to be modified. */
198 tdsq->flag = flag;
199 tdsq->sel_flag = sel_flag;
200
201 td->extra = (void *)tdsq; /* Allow us to update the strip from here. */
202
203 td->flag = 0;
204 td->loc = td2d->loc;
205 copy_v3_v3(td->center, td->loc);
206 copy_v3_v3(td->iloc, td->loc);
207
208 memset(td->axismtx, 0, sizeof(td->axismtx));
209 td->axismtx[2][2] = 1.0f;
210
211 td->ext = nullptr;
212 td->val = nullptr;
213
214 td->flag |= TD_SELECTED;
215 td->dist = 0.0;
216
217 unit_m3(td->mtx);
218 unit_m3(td->smtx);
219
220 /* Time Transform (extend). */
221 td->val = td2d->loc;
222 td->ival = td2d->loc[0];
223
224 return td;
225}
226
228 TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
229{
230 Scene *scene = t->scene;
231 int count, flag;
232 int tot = 0;
233
234 LISTBASE_FOREACH (Sequence *, seq, seqbase) {
235
236 SeqTransInfo(t, seq, &count, &flag);
237
238 /* Use 'flag' which is derived from seq->flag but modified for special cases. */
239 if (flag & SELECT) {
240 if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
241 if (flag & SEQ_LEFTSEL) {
242 SeqToTransData(scene, td++, td2d++, tdsq++, seq, flag, SEQ_LEFTSEL);
243 tot++;
244 }
245 if (flag & SEQ_RIGHTSEL) {
246 SeqToTransData(scene, td++, td2d++, tdsq++, seq, flag, SEQ_RIGHTSEL);
247 tot++;
248 }
249 }
250 else {
251 SeqToTransData(scene, td++, td2d++, tdsq++, seq, flag, SELECT);
252 tot++;
253 }
254 }
255 }
256 return tot;
257}
258
260{
261 if ((custom_data->data != nullptr) && custom_data->use_free) {
262 TransSeq *ts = static_cast<TransSeq *>(custom_data->data);
263 MEM_freeN(ts->tdseq);
264 MEM_delete(ts);
265 custom_data->data = nullptr;
266 }
267}
268
269/* Canceled, need to update the strips display. */
271{
273
274 for (Sequence *seq : transformed_strips) {
275 /* Handle pre-existing overlapping strips even when operator is canceled.
276 * This is necessary for SEQUENCER_OT_duplicate_move macro for example. */
277 if (SEQ_transform_test_overlap(t->scene, seqbase, seq)) {
278 SEQ_transform_seqbase_shuffle(seqbase, seq, t->scene);
279 }
280 }
281}
282
284{
285 Editing *ed = SEQ_editing_get(t->scene);
286 return SEQ_active_seqbase_get(ed);
287}
288
290{
291 for (Sequence *seq : transformed_strips) {
292 if (seq->flag & SEQ_OVERLAP) {
293 return true;
294 }
295 }
296 return false;
297}
298
301{
303 TransData *td = tc->data;
304 for (int a = 0; a < tc->data_len; a++, td++) {
305 Sequence *seq = ((TransDataSeq *)td->extra)->seq;
306 strips.add(seq);
307 }
308 return strips;
309}
310
311static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
312{
313 Editing *ed = SEQ_editing_get(t->scene);
314 if (ed == nullptr) {
315 free_transform_custom_data(custom_data);
316 return;
317 }
318
321 t->scene, seqbase_active_get(t), transformed_strips, SEQ_query_strip_effect_chain);
322
323 for (Sequence *seq : transformed_strips) {
324 seq->flag &= ~SEQ_IGNORE_CHANNEL_LOCK;
325 }
326
327 if (t->state == TRANS_CANCEL) {
328 seq_transform_cancel(t, transformed_strips);
329 free_transform_custom_data(custom_data);
330 return;
331 }
332
333 TransSeq *ts = static_cast<TransSeq *>(tc->custom.type.data);
334 ListBase *seqbasep = seqbase_active_get(t);
335 Scene *scene = t->scene;
336 const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
337 SEQ_MARKER_TRANS) != 0;
338 if (seq_transform_check_overlap(transformed_strips)) {
340 scene, seqbasep, transformed_strips, ts->time_dependent_strips, use_sync_markers);
341 }
342
344 free_transform_custom_data(custom_data);
345}
346
348{
350 LISTBASE_FOREACH (Sequence *, seq, seqbase) {
351 if ((seq->flag & SELECT) != 0 && ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0)) {
352 strips.add(seq);
353 }
354 }
355 return strips;
356}
357
362
363static Sequence *effect_input_get(const Scene *scene, Sequence *effect, SeqInputSide side)
364{
365 Sequence *input = effect->seq1;
366 if (effect->seq2 && (SEQ_time_left_handle_frame_get(scene, effect->seq2) -
367 SEQ_time_left_handle_frame_get(scene, effect->seq1)) *
368 side >
369 0)
370 {
371 input = effect->seq2;
372 }
373 return input;
374}
375
376static Sequence *effect_base_input_get(const Scene *scene, Sequence *effect, SeqInputSide side)
377{
378 Sequence *input = effect, *seq_iter = effect;
379 while (seq_iter != nullptr) {
380 input = seq_iter;
381 seq_iter = effect_input_get(scene, seq_iter, side);
382 }
383 return input;
384}
385
391 TransInfo *t, blender::VectorSet<Sequence *> &time_dependent_strips)
392{
393 ListBase *seqbase = seqbase_active_get(t);
394
395 /* Query dependent strips where used strips do not have handles selected.
396 * If all inputs of any effect even indirectly(through another effect) points to selected strip,
397 * its position will change. */
398
400 time_dependent_strips.add_multiple(strips_no_handles);
401
402 SEQ_iterator_set_expand(t->scene, seqbase, strips_no_handles, SEQ_query_strip_effect_chain);
403 bool strip_added = true;
404
405 while (strip_added) {
406 strip_added = false;
407
408 for (Sequence *seq : strips_no_handles) {
409 if (time_dependent_strips.contains(seq)) {
410 continue; /* Strip is already in collection, skip it. */
411 }
412
413 /* If both seq1 and seq2 exist, both must be selected. */
414 if (seq->seq1 && time_dependent_strips.contains(seq->seq1)) {
415 if (seq->seq2 && !time_dependent_strips.contains(seq->seq2)) {
416 continue;
417 }
418 strip_added = true;
419 time_dependent_strips.add(seq);
420 }
421 }
422 }
423
424 /* Query dependent strips where used strips do have handles selected.
425 * If any 2-input effect changes position because handles were moved, animation should be offset.
426 * With single input effect, it is less likely desirable to move animation. */
427
428 blender::VectorSet selected_strips = SEQ_query_selected_strips(seqbase);
429 SEQ_iterator_set_expand(t->scene, seqbase, selected_strips, SEQ_query_strip_effect_chain);
430 for (Sequence *seq : selected_strips) {
431 /* Check only 2 input effects. */
432 if (seq->seq1 == nullptr || seq->seq2 == nullptr) {
433 continue;
434 }
435
436 /* Find immediate base inputs(left and right side). */
437 Sequence *input_left = effect_base_input_get(t->scene, seq, SEQ_INPUT_LEFT);
438 Sequence *input_right = effect_base_input_get(t->scene, seq, SEQ_INPUT_RIGHT);
439
440 if ((input_left->flag & SEQ_RIGHTSEL) != 0 && (input_right->flag & SEQ_LEFTSEL) != 0) {
441 time_dependent_strips.add(seq);
442 }
443 }
444
445 /* Remove all non-effects. */
446 time_dependent_strips.remove_if(
447 [&](Sequence *seq) { return SEQ_transform_sequence_can_be_translated(seq); });
448}
449
450static void createTransSeqData(bContext * /*C*/, TransInfo *t)
451{
452 Scene *scene = t->scene;
453 Editing *ed = SEQ_editing_get(t->scene);
454 TransData *td = nullptr;
455 TransData2D *td2d = nullptr;
456 TransDataSeq *tdsq = nullptr;
457 TransSeq *ts = nullptr;
458
459 int count = 0;
460
462
463 if (ed == nullptr) {
464 tc->data_len = 0;
465 return;
466 }
467
468 /* Disable cursor wrapping for edge pan. */
469 if (t->mode == TFM_TRANSLATION) {
471 }
472
474 t->frame_side = transform_convert_frame_side_dir_get(t, float(scene->r.cfra));
475
476 count = SeqTransCount(t, ed->seqbasep);
477
478 /* Allocate memory for data. */
479 tc->data_len = count;
480
481 /* Stop if trying to build list if nothing selected. */
482 if (count == 0) {
483 return;
484 }
485
486 tc->custom.type.data = ts = MEM_new<TransSeq>(__func__);
487 tc->custom.type.use_free = true;
488 td = tc->data = static_cast<TransData *>(
489 MEM_callocN(tc->data_len * sizeof(TransData), "TransSeq TransData"));
490 td2d = tc->data_2d = static_cast<TransData2D *>(
491 MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D"));
492 ts->tdseq = tdsq = static_cast<TransDataSeq *>(
493 MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq"));
494
495 /* Custom data to enable edge panning during transformation. */
497 &ts->edge_pan,
505 ts->initial_v2d_cur = t->region->v2d.cur;
506
507 /* Loop 2: build transdata array. */
508 SeqToTransData_build(t, ed->seqbasep, td, td2d, tdsq);
509
512 if ((seq->flag & SELECT) != 0) {
515 }
516 }
517
519}
520
523/* -------------------------------------------------------------------- */
527static void view2d_edge_pan_loc_compensate(TransInfo *t, float offset[2])
528{
529 TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
530
531 const rctf rect_prev = t->region->v2d.cur;
532
533 if (t->options & CTX_VIEW2D_EDGE_PAN) {
534 if (t->state == TRANS_CANCEL) {
536 }
537 else {
538 /* Edge panning functions expect window coordinates, mval is relative to region. */
539 const int xy[2] = {
540 t->region->winrct.xmin + int(t->mval[0]),
541 t->region->winrct.ymin + int(t->mval[1]),
542 };
544 }
545 }
546
547 if (t->state != TRANS_CANCEL) {
548 if (!BLI_rctf_compare(&rect_prev, &t->region->v2d.cur, FLT_EPSILON)) {
549 /* Additional offset due to change in view2D rect. */
550 BLI_rctf_transform_pt_v(&t->region->v2d.cur, &rect_prev, offset, offset);
552 }
553 }
554}
555
557{
558 /* Editing null check already done. */
559 ListBase *seqbasep = seqbase_active_get(t);
560
561 int a, new_frame, offset;
562
563 TransData *td = nullptr;
564 TransData2D *td2d = nullptr;
565 TransDataSeq *tdsq = nullptr;
566 Sequence *seq;
567
568 Scene *scene = t->scene;
569
571
572 /* This is calculated for offsetting animation of effects that change position with inputs.
573 * Maximum(positive or negative) value is used, because individual strips can be clamped. This
574 * works fairly well in most scenarios, but there can be some edge cases.
575 *
576 * Better solution would be to store effect position and calculate real offset. However with many
577 * (>5) effects in chain, there is visible lag in strip position update, because during
578 * recalculation, hierarchy is not taken into account. */
579 int max_offset = 0;
580
581 float edge_pan_offset[2] = {0.0f, 0.0f};
582 view2d_edge_pan_loc_compensate(t, edge_pan_offset);
583
584 /* Flush to 2D vector from internally used 3D vector. */
585 for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
586 tdsq = (TransDataSeq *)td->extra;
587 seq = tdsq->seq;
588
589 new_frame = round_fl_to_int(td->loc[0] + edge_pan_offset[0]);
590
591 switch (tdsq->sel_flag) {
592 case SELECT: {
594 offset = new_frame - tdsq->start_offset - seq->start;
595 SEQ_transform_translate_sequence(scene, seq, offset);
596 if (abs(offset) > abs(max_offset)) {
597 max_offset = offset;
598 }
599 }
600 seq->machine = round_fl_to_int(td->loc[1] + edge_pan_offset[1]);
602 break;
603 }
604 case SEQ_LEFTSEL: { /* No vertical transform. */
605 /* Update right handle first if both handles are selected and the new_frame is right of
606 * the old one to avoid unexpected left handle clamping when canceling. See #126191. */
607 bool both_handles_selected = (tdsq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) ==
609 if (both_handles_selected && new_frame > SEQ_time_left_handle_frame_get(scene, seq)) {
610 a++, td++, td2d++;
611 int new_right_frame = round_fl_to_int(td->loc[0] + edge_pan_offset[0]);
612 SEQ_time_right_handle_frame_set(scene, seq, new_right_frame);
613 }
614 int old_startdisp = SEQ_time_left_handle_frame_get(scene, seq);
615 SEQ_time_left_handle_frame_set(t->scene, seq, new_frame);
616
617 if (abs(SEQ_time_left_handle_frame_get(scene, seq) - old_startdisp) > abs(max_offset)) {
618 max_offset = SEQ_time_left_handle_frame_get(scene, seq) - old_startdisp;
619 }
620 break;
621 }
622 case SEQ_RIGHTSEL: { /* No vertical transform. */
623 int old_enddisp = SEQ_time_right_handle_frame_get(scene, seq);
624 SEQ_time_right_handle_frame_set(t->scene, seq, new_frame);
625
626 if (abs(SEQ_time_right_handle_frame_get(scene, seq) - old_enddisp) > abs(max_offset)) {
627 max_offset = SEQ_time_right_handle_frame_get(scene, seq) - old_enddisp;
628 }
629 break;
630 }
631 }
632 }
633
634 TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
635
636 /* Update animation for effects. */
637 for (Sequence *seq : ts->time_dependent_strips) {
638 SEQ_offset_animdata(t->scene, seq, max_offset);
639 }
640
641 /* Need to do the overlap check in a new loop otherwise adjacent strips
642 * will not be updated and we'll get false positives. */
645 t->scene, seqbase_active_get(t), transformed_strips, SEQ_query_strip_effect_chain);
646
647 for (Sequence *seq : transformed_strips) {
648 /* Test overlap, displays red outline. */
649 seq->flag &= ~SEQ_OVERLAP;
650 if (SEQ_transform_test_overlap(scene, seqbasep, seq)) {
651 seq->flag |= SEQ_OVERLAP;
652 }
653 }
654}
655
657{
658 TransData *td;
659 int a;
660 Sequence *seq_prev = nullptr;
661
663
664 for (a = 0, td = tc->data; a < tc->data_len; a++, td++) {
665 TransDataSeq *tdsq = (TransDataSeq *)td->extra;
666 Sequence *seq = tdsq->seq;
667
668 if (seq != seq_prev) {
670 }
671
672 seq_prev = seq;
673 }
674
676
677 flushTransSeq(t);
678}
679
682/* -------------------------------------------------------------------- */
687{
688 SpaceSeq *sseq = (SpaceSeq *)t->area->spacedata.first;
689 if ((sseq->flag & SPACE_SEQ_DESELECT_STRIP_HANDLE) != 0 &&
691 {
694 for (Sequence *seq : strips) {
695 seq->flag &= ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
696 }
697 }
698
699 sseq->flag &= ~SPACE_SEQ_DESELECT_STRIP_HANDLE;
700
701 /* #freeSeqData in `transform_conversions.cc` does this
702 * keep here so the else at the end won't run. */
703 if (t->state == TRANS_CANCEL) {
704 return;
705 }
706
707 /* Marker transform, not especially nice but we may want to move markers
708 * at the same time as strips in the Video Sequencer. */
709 if (sseq->flag & SEQ_MARKER_TRANS) {
710 /* Can't use #TFM_TIME_EXTEND
711 * for some reason EXTEND is changed into TRANSLATE, so use frame_side instead. */
712
713 if (t->mode == TFM_SEQ_SLIDE) {
714 if (t->frame_side == 'B') {
717 }
718 }
719 else if (ELEM(t->frame_side, 'L', 'R')) {
722 }
723 }
724}
725
727{
728 const TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
729 const int channel_offset = round_fl_to_int(r_val[1]);
730 const int min_channel_after_transform = ts->selection_channel_range_min + channel_offset;
731 const int max_channel_after_transform = ts->selection_channel_range_max + channel_offset;
732
733 if (max_channel_after_transform > SEQ_MAX_CHANNELS) {
734 r_val[1] -= max_channel_after_transform - SEQ_MAX_CHANNELS;
735 }
736 if (min_channel_after_transform < 1) {
737 r_val[1] -= min_channel_after_transform - 1;
738 }
739}
740
744 /*flags*/ (T_POINTS | T_2D_EDIT),
745 /*create_trans_data*/ createTransSeqData,
746 /*recalc_data*/ recalcData_sequencer,
747 /*special_aftertrans_update*/ special_aftertrans_update__sequencer,
748};
#define LISTBASE_FOREACH(type, var, list)
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])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2], const float xy_src[2])
Definition rct.c:530
bool BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, float limit)
#define CLAMP(a, b, c)
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_SEQUENCER_STRIPS
Definition DNA_ID.h:1089
@ SEQ_RIGHTSEL
@ SEQ_OVERLAP
@ SEQ_LEFTSEL
@ SPACE_SEQ_DESELECT_STRIP_HANDLE
@ SEQ_MARKER_TRANS
@ TFM_TIME_TRANSLATE
@ TFM_TIME_EXTEND
@ TFM_SEQ_SLIDE
@ TFM_TRANSLATION
Read Guarded memory(de)allocation.
constexpr int SEQ_MAX_CHANNELS
void UI_view2d_edge_pan_set_limits(View2DEdgePanData *vpd, float xmin, float xmax, float ymin, float ymax)
void UI_view2d_edge_pan_cancel(bContext *C, View2DEdgePanData *vpd)
void UI_view2d_edge_pan_init(bContext *C, View2DEdgePanData *vpd, float inside_pad, float outside_pad, float speed_ramp, float max_speed, float delay, float zoom_influence)
void UI_view2d_edge_pan_apply(bContext *C, View2DEdgePanData *vpd, const int xy[2]) ATTR_NONNULL(1
int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, float value, char side)
void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs)
Definition animation.cc:69
ListBase * SEQ_channels_displayed_get(Editing *ed)
Definition channels.cc:23
bool add(const Key &key)
bool contains(const Key &key) const
void add_multiple(Span< Key > keys)
int64_t remove_if(Predicate &&predicate)
#define SELECT
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
int count
void SEQ_iterator_set_expand(const Scene *scene, ListBase *seqbase, VectorSet< Sequence * > &strips, void seq_query_func(const Scene *scene, Sequence *seq_reference, ListBase *seqbase, VectorSet< Sequence * > &strips))
Definition iterator.cc:61
void SEQ_query_strip_effect_chain(const Scene *scene, Sequence *reference_strip, ListBase *seqbase, VectorSet< Sequence * > &strips)
Definition iterator.cc:210
VectorSet< Sequence * > SEQ_query_selected_strips(ListBase *seqbase)
Definition iterator.cc:106
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
ListBase * SEQ_active_seqbase_get(const Editing *ed)
Definition sequencer.cc:416
Editing * SEQ_editing_get(const Scene *scene)
Definition sequencer.cc:262
#define FLT_MAX
Definition stdcycles.h:14
void SEQ_relations_invalidate_cache_composite(Scene *scene, Sequence *seq)
void SEQ_time_right_handle_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
void SEQ_time_left_handle_frame_set(const Scene *scene, Sequence *seq, int timeline_frame)
int SEQ_time_left_handle_frame_get(const Scene *, const Sequence *seq)
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
bool SEQ_transform_seqbase_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
bool SEQ_transform_test_overlap(const Scene *scene, ListBase *seqbasep, Sequence *test)
void SEQ_transform_translate_sequence(Scene *evil_scene, Sequence *seq, int delta)
bool SEQ_transform_is_locked(ListBase *channels, const Sequence *seq)
void SEQ_transform_handle_overlap(Scene *scene, ListBase *seqbasep, blender::Span< Sequence * > transformed_strips, bool use_sync_markers)
bool SEQ_transform_sequence_can_be_translated(const Sequence *seq)
ListBase * seqbasep
void * first
ListBase markers
ListBase spacedata
struct Sequence * seq1
struct Sequence * seq2
TransCustomData type
Definition transform.hh:425
unsigned int use_free
Definition transform.hh:410
void(* free_cb)(TransInfo *, TransDataContainer *tc, TransCustomData *custom_data)
Definition transform.hh:409
TransCustomDataContainer custom
Definition transform.hh:501
TransData * data
Definition transform.hh:445
TransData2D * data_2d
Definition transform.hh:449
float smtx[3][3]
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
eTfmMode mode
Definition transform.hh:517
char frame_side
Definition transform.hh:570
eTState state
Definition transform.hh:527
Scene * scene
Definition transform.hh:654
eTFlag flag
Definition transform.hh:523
ARegion * region
Definition transform.hh:652
float values_final[4]
Definition transform.hh:632
bContext * context
Definition transform.hh:649
blender::float2 mval
Definition transform.hh:663
eTContext options
Definition transform.hh:521
ScrArea * area
Definition transform.hh:651
View2DEdgePanData edge_pan
blender::VectorSet< Sequence * > time_dependent_strips
int ymin
int xmin
@ CTX_VIEW2D_EDGE_PAN
Definition transform.hh:84
void transformViewUpdate(TransInfo *t)
@ T_2D_EDIT
Definition transform.hh:104
@ T_NO_CURSOR_WRAP
Definition transform.hh:144
@ T_POINTS
Definition transform.hh:93
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition transform.hh:851
@ TRANS_CANCEL
Definition transform.hh:210
char transform_convert_frame_side_dir_get(TransInfo *t, float cframe)
conversion and adaptation of different datablocks to a common struct.
static void flushTransSeq(TransInfo *t)
static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
#define SEQ_EDGE_PAN_DELAY
static void seq_transform_cancel(TransInfo *t, blender::Span< Sequence * > transformed_strips)
static int SeqToTransData_build(TransInfo *t, ListBase *seqbase, TransData *td, TransData2D *td2d, TransDataSeq *tdsq)
static int SeqTransCount(TransInfo *t, ListBase *seqbase)
static void view2d_edge_pan_loc_compensate(TransInfo *t, float offset[2])
static Sequence * effect_input_get(const Scene *scene, Sequence *effect, SeqInputSide side)
bool seq_transform_check_overlap(blender::Span< Sequence * > transformed_strips)
static ListBase * seqbase_active_get(const TransInfo *t)
static void recalcData_sequencer(TransInfo *t)
static void special_aftertrans_update__sequencer(bContext *, TransInfo *t)
#define SEQ_EDGE_PAN_INSIDE_PAD
TransConvertTypeInfo TransConvertType_Sequencer
void transform_convert_sequencer_channel_clamp(TransInfo *t, float r_val[2])
static blender::VectorSet< Sequence * > query_selected_strips_no_handles(ListBase *seqbase)
#define SEQ_EDGE_PAN_ZOOM_INFLUENCE
static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag)
static void query_time_dependent_strips_strips(TransInfo *t, blender::VectorSet< Sequence * > &time_dependent_strips)
static void createTransSeqData(bContext *, TransInfo *t)
#define SEQ_EDGE_PAN_MAX_SPEED
#define SEQ_EDGE_PAN_OUTSIDE_PAD
static blender::VectorSet< Sequence * > seq_transform_collection_from_transdata(TransDataContainer *tc)
static void free_transform_custom_data(TransCustomData *custom_data)
#define SEQ_EDGE_PAN_SPEED_RAMP
static Sequence * effect_base_input_get(const Scene *scene, Sequence *effect, SeqInputSide side)
static TransData * SeqToTransData(Scene *scene, TransData *td, TransData2D *td2d, TransDataSeq *tdsq, Sequence *seq, int flag, int sel_flag)
@ TD_SELECTED
transform modes used by different operators.
bool transform_mode_edge_seq_slide_use_restore_handle_selection(const TransInfo *t)
ccl_device_inline int abs(int x)
Definition util/math.h:120
int xy[2]
Definition wm_draw.cc:170
uint8_t flag
Definition wm_window.cc:138