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
8
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/* -------------------------------------------------------------------- */
74
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
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
522
523/* -------------------------------------------------------------------- */
526
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
681
682/* -------------------------------------------------------------------- */
685
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
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
742
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_IGNORE_CHANNEL_LOCK
@ 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.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
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
static int left
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
struct RenderData r
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.
TransConvertTypeInfo TransConvertType_Sequencer
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
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