Blender V4.5
transform_snap_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
9#include <cstddef>
10#include <cstdlib>
11
12#include "BLI_assert.h"
13#include "BLI_listbase.h"
14#include "BLI_map.hh"
15#include "BLI_math_base.h"
16#include "BLI_math_vector.h"
17#include "BLI_math_vector.hh"
18#include "BLI_vector.hh"
19
20#include "MEM_guardedalloc.h"
21
22#include "DNA_scene_types.h"
23#include "DNA_screen_types.h"
24#include "DNA_sequence_types.h"
25#include "DNA_space_types.h"
26
27#include "ED_transform.hh"
28
29#include "UI_view2d.hh"
30
31#include "SEQ_channels.hh"
32#include "SEQ_effects.hh"
33#include "SEQ_iterator.hh"
34#include "SEQ_relations.hh"
35#include "SEQ_render.hh"
36#include "SEQ_retiming.hh"
37#include "SEQ_sequencer.hh"
38#include "SEQ_time.hh"
39#include "SEQ_transform.hh"
40
41#include "transform.hh"
42#include "transform_convert.hh"
43#include "transform_snap.hh"
44
45namespace blender::ed::transform {
46
50
51 MEM_CXX_CLASS_ALLOC_FUNCS("TransSeqSnapData")
52};
53
54/* -------------------------------------------------------------------- */
57
59 const Scene *scene, Map<SeqRetimingKey *, Strip *> &retiming_selection)
60{
61 VectorSet<Strip *> snap_sources;
62
64 snap_sources = seq::query_selected_strips(seqbase);
65
66 /* Add strips owned by retiming keys to exclude these from targets */
67 for (Strip *strip : retiming_selection.values()) {
68 snap_sources.add(strip);
69 }
70
71 return snap_sources;
72}
73
75{
76 VectorSet<Strip *> snap_sources;
77
78 Editing *ed = seq::editing_get(scene);
80
81 snap_sources = seq::query_rendered_strips(scene, channels, ed->seqbasep, scene->r.cfra, 0);
82 snap_sources.remove_if([&](Strip *strip) { return (strip->flag & SELECT) == 0; });
83
84 return snap_sources;
85}
86
87static int cmp_fn(const void *a, const void *b)
88{
89 return round_fl_to_int((*(float2 *)a)[0] - (*(float2 *)b)[0]);
90}
91
93 TransSeqSnapData *snap_data,
94 const Span<Strip *> snap_sources)
95{
96 for (Strip *strip : snap_sources) {
97 int left = 0, right = 0;
98 if (strip->flag & SEQ_LEFTSEL && !(strip->flag & SEQ_RIGHTSEL)) {
99 left = right = seq::time_left_handle_frame_get(scene, strip);
100 }
101 else if (strip->flag & SEQ_RIGHTSEL && !(strip->flag & SEQ_LEFTSEL)) {
102 left = right = seq::time_right_handle_frame_get(scene, strip);
103 }
104 else {
106 right = seq::time_right_handle_frame_get(scene, strip);
107 }
108
109 /* Set only the x-positions when snapping in the timeline. */
110 snap_data->source_snap_points.append(float2(left));
111 snap_data->source_snap_points.append(float2(right));
112 }
113
114 qsort(snap_data->source_snap_points.data(),
115 snap_data->source_snap_points.size(),
116 sizeof(float2),
117 cmp_fn);
118}
119
121 const Scene *scene,
122 TransSeqSnapData *snap_data,
123 const Map<SeqRetimingKey *, Strip *> &retiming_selection)
124{
125 for (auto item : retiming_selection.items()) {
126 const int key_frame = seq::retiming_key_timeline_frame_get(scene, item.value, item.key);
127 snap_data->source_snap_points.append(float2(key_frame));
128 }
129
130 qsort(snap_data->source_snap_points.data(),
131 snap_data->source_snap_points.size(),
132 sizeof(float2),
133 cmp_fn);
134}
135
137 TransSeqSnapData *snap_data,
138 const Span<Strip *> snap_sources)
139{
140 for (Strip *strip : snap_sources) {
141 const Array<float2> strip_image_quad = seq::image_transform_final_quad_get(scene, strip);
142
143 for (int i = 0; i < 4; i++) {
144 snap_data->source_snap_points.append(strip_image_quad[i]);
145 }
146
147 /* Add origins last */
148 const float2 image_origin = seq::image_transform_origin_offset_pixelspace_get(scene, strip);
149 snap_data->source_snap_points.append(image_origin);
150 }
151}
152
154 TransSeqSnapData *snap_data,
155 const Span<Strip *> snap_sources)
156{
157
158 const size_t point_count_source = snap_sources.size();
159
160 if (point_count_source == 0) {
161 return;
162 }
163
164 snap_data->source_snap_points.reinitialize(point_count_source);
165 int i = 0;
166 for (Strip *strip : snap_sources) {
167 /* Add origins last */
169 snap_data->source_snap_points[i][0] = image_origin[0];
170 snap_data->source_snap_points[i][1] = image_origin[1];
171 i++;
172 }
173
174 BLI_assert(i <= snap_data->source_snap_points.size());
175}
176
178
179/* -------------------------------------------------------------------- */
182
183/* Add effect strips directly or indirectly connected to `strip_reference` to `collection`. */
184static void query_strip_effects_fn(const Scene *scene,
185 Strip *strip_reference,
186 ListBase *seqbase,
187 VectorSet<Strip *> &strips)
188{
189 if (strips.contains(strip_reference)) {
190 return; /* Strip is already in set, so all effects connected to it are as well. */
191 }
192 strips.add(strip_reference);
193
194 /* Find all strips connected to `strip_reference`. */
195 LISTBASE_FOREACH (Strip *, strip_test, seqbase) {
196 if (seq::relation_is_effect_of_strip(strip_test, strip_reference)) {
197 query_strip_effects_fn(scene, strip_test, seqbase, strips);
198 }
199 }
200}
201
203 const Span<Strip *> snap_sources,
204 const bool exclude_selected)
205{
206 Editing *ed = seq::editing_get(scene);
209 const short snap_flag = seq::tool_settings_snap_flag_get(scene);
210
211 /* Effects will always change position with strip to which they are connected and they don't
212 * have to be selected. Remove such strips from `snap_targets` collection. */
213 VectorSet effects_of_snap_sources = snap_sources;
214 seq::iterator_set_expand(scene, seqbase, effects_of_snap_sources, query_strip_effects_fn);
215 effects_of_snap_sources.remove_if([&](Strip *strip) {
216 return (strip->type & STRIP_TYPE_EFFECT) != 0 && seq::effect_get_num_inputs(strip->type) == 0;
217 });
218
219 VectorSet<Strip *> snap_targets;
220 LISTBASE_FOREACH (Strip *, strip, seqbase) {
221 if (exclude_selected && strip->flag & SELECT) {
222 continue; /* Selected are being transformed if there is no drag and drop. */
223 }
224 if (seq::render_is_muted(channels, strip) && (snap_flag & SEQ_SNAP_IGNORE_MUTED)) {
225 continue;
226 }
227 if (strip->type == STRIP_TYPE_SOUND_RAM && (snap_flag & SEQ_SNAP_IGNORE_SOUND)) {
228 continue;
229 }
230 if (effects_of_snap_sources.contains(strip)) {
231 continue;
232 }
233
234 snap_targets.add(strip);
235 }
236
237 return snap_targets;
238}
239
241{
242 Scene *scene = t->scene;
243 short snap_mode = t->tsnap.mode;
244
245 VectorSet<Strip *> snap_targets;
246
247 /* We don't need to calculate strip snap targets if the option is unselected. */
248 if ((snap_mode & SEQ_SNAP_TO_STRIPS_PREVIEW) == 0) {
249 return snap_targets;
250 }
251
252 Editing *ed = seq::editing_get(scene);
254
255 snap_targets = seq::query_rendered_strips(scene, channels, ed->seqbasep, scene->r.cfra, 0);
256
257 /* Selected strips are only valid targets when snapping the cursor or origin. */
258 if ((t->data_type == &TransConvertType_SequencerImage) && (t->flag & T_ORIGIN) == 0) {
259 snap_targets.remove_if([&](Strip *strip) { return (strip->flag & SELECT) != 0; });
260 }
261
262 return snap_targets;
263}
264
266 Span<Strip *> snap_strip_targets)
267{
269
270 for (Strip *strip : snap_strip_targets) {
271 for (SeqRetimingKey &key : seq::retiming_keys_get(strip)) {
272 const int key_frame = seq::retiming_key_timeline_frame_get(scene, strip, &key);
273 if (seq::time_strip_intersects_frame(scene, strip, key_frame)) {
274 visible_keys.add(&key, strip);
275 }
276 }
277 }
278
279 return visible_keys;
280}
281
282static void points_build_targets_timeline(const Scene *scene,
283 const short snap_mode,
284 TransSeqSnapData *snap_data,
285 const Span<Strip *> strip_targets)
286{
287 if (snap_mode & SEQ_SNAP_TO_CURRENT_FRAME) {
288 snap_data->target_snap_points.append(float2(scene->r.cfra));
289 }
290
291 if (snap_mode & SEQ_SNAP_TO_MARKERS) {
292 LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
293 snap_data->target_snap_points.append(float2(marker->frame));
294 }
295 }
296
297 if (snap_mode & SEQ_SNAP_TO_FRAME_RANGE) {
298 snap_data->target_snap_points.append(float2(PSFRA));
299 snap_data->target_snap_points.append(float2(PEFRA + 1));
300 }
301
302 for (Strip *strip : strip_targets) {
303 snap_data->target_snap_points.append(float2(seq::time_left_handle_frame_get(scene, strip)));
304 snap_data->target_snap_points.append(float2(seq::time_right_handle_frame_get(scene, strip)));
305
306 if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) {
307 int content_start = seq::time_start_frame_get(strip);
308 int content_end = seq::time_content_end_frame_get(scene, strip);
309
310 /* Effects and single image strips produce incorrect content length. Skip these strips. */
311 if ((strip->type & STRIP_TYPE_EFFECT) != 0 || strip->len == 1) {
312 content_start = seq::time_left_handle_frame_get(scene, strip);
313 content_end = seq::time_right_handle_frame_get(scene, strip);
314 }
315
316 CLAMP(content_start,
319 CLAMP(content_end,
322
323 snap_data->target_snap_points.append(float2(content_start));
324 snap_data->target_snap_points.append(float2(content_end));
325 }
326 }
327
328 Map retiming_key_targets = visible_retiming_keys_get(scene, strip_targets);
329 if (snap_mode & SEQ_SNAP_TO_RETIMING) {
330 for (auto item : retiming_key_targets.items()) {
331 const int key_frame = seq::retiming_key_timeline_frame_get(scene, item.value, item.key);
332 snap_data->target_snap_points.append(float2(key_frame));
333 }
334 }
335
336 qsort(snap_data->target_snap_points.data(),
337 snap_data->target_snap_points.size(),
338 sizeof(float2),
339 cmp_fn);
340}
341
343 const short snap_mode,
344 TransSeqSnapData *snap_data)
345{
346 if (snap_mode & SEQ_SNAP_TO_PREVIEW_BORDERS) {
347 snap_data->target_snap_points.append(float2(v2d->tot.xmin, v2d->tot.ymin));
348 snap_data->target_snap_points.append(float2(v2d->tot.xmax, v2d->tot.ymax));
349 snap_data->target_snap_points.append(float2(v2d->tot.xmin, v2d->tot.ymax));
350 snap_data->target_snap_points.append(float2(v2d->tot.xmax, v2d->tot.ymin));
351 }
352
353 if (snap_mode & SEQ_SNAP_TO_PREVIEW_CENTER) {
354 snap_data->target_snap_points.append(float2(0));
355 }
356}
357
359 const View2D *v2d,
360 const short snap_mode,
361 TransSeqSnapData *snap_data,
362 const Span<Strip *> snap_targets)
363{
364 points_build_targets_preview_general(v2d, snap_mode, snap_data);
365
366 if (snap_mode & SEQ_SNAP_TO_STRIPS_PREVIEW) {
367 for (Strip *strip : snap_targets) {
368 const Array<float2> strip_image_quad = seq::image_transform_final_quad_get(scene, strip);
369
370 for (int i = 0; i < 4; i++) {
371 snap_data->target_snap_points.append(strip_image_quad[i]);
372 }
373
374 const float2 image_origin = seq::image_transform_origin_offset_pixelspace_get(scene, strip);
375 snap_data->target_snap_points.append(image_origin);
376 }
377 }
378}
379
380static void points_build_3x3_grid(const Scene *scene, TransSeqSnapData *snap_data, Strip *strip)
381{
382 const Array<float2> strip_image_quad = seq::image_transform_final_quad_get(scene, strip);
383 /* Corners. */
384 for (int i = 0; i < 4; i++) {
385 snap_data->target_snap_points.append(strip_image_quad[i]);
386 }
387
388 /* Middle top, bottom and center of the image. */
389 const float2 tm = blender::math::interpolate(strip_image_quad[0], strip_image_quad[3], 0.5f);
390 const float2 bm = blender::math::interpolate(strip_image_quad[1], strip_image_quad[2], 0.5f);
391 const float2 mm = blender::math::interpolate(bm, tm, 0.5f);
392 snap_data->target_snap_points.append(tm);
393 snap_data->target_snap_points.append(mm);
394 snap_data->target_snap_points.append(bm);
395 /* Left and right. */
396 snap_data->target_snap_points.append(
397 blender::math::interpolate(strip_image_quad[2], strip_image_quad[3], 0.5f));
398 snap_data->target_snap_points.append(
399 blender::math::interpolate(strip_image_quad[0], strip_image_quad[1], 0.5f));
400}
401
403 TransSeqSnapData *snap_data,
404 const Span<Strip *> snap_sources,
405 const Span<Strip *> snap_targets)
406{
407 for (Strip *strip : snap_sources) {
408 points_build_3x3_grid(scene, snap_data, strip);
409 }
410
411 for (Strip *strip : snap_targets) {
412 points_build_3x3_grid(scene, snap_data, strip);
413 }
414}
415
417
418/* -------------------------------------------------------------------- */
421
423{
424 const int snap_distance = seq::tool_settings_snap_distance_get(t->scene);
425 const View2D *v2d = &t->region->v2d;
426 return UI_view2d_region_to_view_x(v2d, snap_distance) - UI_view2d_region_to_view_x(v2d, 0);
427}
428
433
435
436/* -------------------------------------------------------------------- */
439
440static void snap_data_build_timeline(const TransInfo *t, TransSeqSnapData *snap_data)
441{
442 Scene *scene = t->scene;
443 short snap_mode = t->tsnap.mode;
444
445 Map retiming_selection = seq::retiming_selection_get(seq::editing_get(scene));
446 VectorSet<Strip *> snap_sources = query_snap_sources_timeline(scene, retiming_selection);
447 VectorSet<Strip *> snap_targets = query_snap_targets_timeline(scene, snap_sources, true);
448
449 /* Build arrays of snap points. */
451 points_build_sources_timeline_strips(scene, snap_data, snap_sources);
452 }
453 else { /* &TransConvertType_SequencerRetiming */
454 points_build_sources_timeline_retiming(scene, snap_data, retiming_selection);
455 }
456 points_build_targets_timeline(scene, snap_mode, snap_data, snap_targets);
457}
458
459static void snap_data_build_preview(const TransInfo *t, TransSeqSnapData *snap_data)
460{
461 Scene *scene = t->scene;
462 short snap_mode = t->tsnap.mode;
463 View2D *v2d = &t->region->v2d;
464 SpaceSeq *sseq = static_cast<SpaceSeq *>(t->area->spacedata.first);
465
467 VectorSet<Strip *> snap_targets;
468
469 snap_targets = query_snap_targets_preview(t);
470
471 /* Build arrays of snap points. */
473 if (t->flag & T_ORIGIN) {
474 points_build_sources_preview_origin(scene, snap_data, snap_sources);
475 points_build_targets_preview_origin(scene, snap_data, snap_sources, snap_targets);
476 }
477 else {
478 points_build_sources_preview_image(scene, snap_data, snap_sources);
479 points_build_targets_preview_image(scene, v2d, snap_mode, snap_data, snap_targets);
480 }
481 }
483 float2 cursor_view = float2(sseq->cursor) * float2(t->aspect);
484 snap_data->source_snap_points.append(cursor_view);
485 points_build_targets_preview_image(scene, v2d, snap_mode, snap_data, snap_targets);
486 }
487}
488
490{
491 TransSeqSnapData *snap_data = MEM_new<TransSeqSnapData>(__func__);
492
494 snap_data_build_timeline(t, snap_data);
495 }
496 else {
497 snap_data_build_preview(t, snap_data);
498 }
499
500 if (snap_data->source_snap_points.is_empty() || snap_data->target_snap_points.is_empty()) {
501 MEM_delete(snap_data);
502 return nullptr;
503 }
504
505 return snap_data;
506}
507
509{
510 MEM_delete(data);
511}
512
514
515/* -------------------------------------------------------------------- */
518
519static bool snap_calc_timeline(TransInfo *t, const TransSeqSnapData *snap_data)
520{
521 /* Prevent snapping when constrained to Y axis. */
522 if (t->con.mode & CON_APPLY && t->con.mode & CON_AXIS1) {
523 return false;
524 }
525
526 int best_dist = MAXFRAME, best_target_frame = 0, best_source_frame = 0;
527
528 for (const float *snap_source_point : snap_data->source_snap_points) {
529 for (const float *snap_target_point : snap_data->target_snap_points) {
530 int snap_source_frame = snap_source_point[0];
531 int snap_target_frame = snap_target_point[0];
532 int dist = abs(snap_target_frame - (snap_source_frame + round_fl_to_int(t->values[0])));
533 if (dist > best_dist) {
534 continue;
535 }
536
537 best_dist = dist;
538 best_target_frame = snap_target_frame;
539 best_source_frame = snap_source_frame;
540 }
541 }
542
543 if (best_dist > seq_snap_threshold_get_frame_distance(t)) {
544 return false;
545 }
546
547 t->tsnap.snap_target[0] = best_target_frame;
548 t->tsnap.snap_source[0] = best_source_frame;
549 return true;
550}
551
552static bool snap_calc_preview_origin(TransInfo *t, const TransSeqSnapData *snap_data)
553{
554 /* Store best snap candidates in x and y directions separately. */
555 float best_dist(std::numeric_limits<float>::max());
556 float2 best_target_point(0.0f);
557 float2 best_source_point(0.0f);
558
559 for (const float2 snap_source_point : snap_data->source_snap_points) {
560 for (const float2 snap_target_point : snap_data->target_snap_points) {
561 /* First update snaps in x direction, then y direction. */
562 const float2 transformed_point(snap_source_point.x + t->values[0],
563 snap_source_point.y + t->values[1]);
564 const float dist = blender::math::distance(snap_target_point, transformed_point);
565 if (dist > best_dist) {
566 continue;
567 }
568
569 best_dist = dist;
570 best_target_point = snap_target_point;
571 best_source_point = snap_source_point;
572 }
573 }
574
575 if (best_dist <= seq_snap_threshold_get_view_distance(t)) {
576 copy_v2_v2(t->tsnap.snap_target, best_target_point);
577 copy_v2_v2(t->tsnap.snap_source, best_source_point);
579 return true;
580 }
581 return false;
582}
583
584static bool snap_calc_preview_image(TransInfo *t, const TransSeqSnapData *snap_data)
585{
586 /* Store best snap candidates in x and y directions separately. */
587 float2 best_dist(std::numeric_limits<float>::max());
588 float2 best_target_point(0.0f);
589 float2 best_source_point(0.0f);
590
591 for (const float2 snap_source_point : snap_data->source_snap_points) {
592 for (const float2 snap_target_point : snap_data->target_snap_points) {
593 /* First update snaps in x direction, then y direction. */
594 for (int i = 0; i < 2; i++) {
595 int dist = abs(snap_target_point[i] - (snap_source_point[i] + t->values[i]));
596 if (dist > best_dist[i]) {
597 continue;
598 }
599
600 best_dist[i] = dist;
601 best_target_point[i] = snap_target_point[i];
602 best_source_point[i] = snap_source_point[i];
603 }
604 }
605 }
606
609
610 if (best_dist[0] <= thr) {
611 t->tsnap.snap_target[0] = best_target_point[0];
612 t->tsnap.snap_source[0] = best_source_point[0];
614 }
615
616 if (best_dist[1] <= thr) {
617 t->tsnap.snap_target[1] = best_target_point[1];
618 t->tsnap.snap_source[1] = best_source_point[1];
620 }
621
622 return (best_dist[0] <= thr || best_dist[1] <= thr);
623}
624
626{
627 const TransSeqSnapData *snap_data = t->tsnap.seq_context;
628 if (snap_data == nullptr) {
629 return false;
630 }
631
633 return snap_calc_timeline(t, snap_data);
634 }
635 if (t->flag & T_ORIGIN) {
636 return snap_calc_preview_origin(t, snap_data);
637 }
638 return snap_calc_preview_image(t, snap_data);
639}
640
642{
643 *vec = t->tsnap.snap_target[0] - t->tsnap.snap_source[0];
644}
645
647{
648 /* Apply snap along x and y axes independently. */
649 if (t->tsnap.direction & DIR_GLOBAL_X) {
650 vec[0] = t->tsnap.snap_target[0] - t->tsnap.snap_source[0];
651 }
652
653 if (t->tsnap.direction & DIR_GLOBAL_Y) {
654 vec[1] = t->tsnap.snap_target[1] - t->tsnap.snap_source[1];
655 }
656}
657
658static int snap_sequencer_to_closest_strip_ex(TransInfo *t, const int frame_1, const int frame_2)
659{
660 Scene *scene = t->scene;
661 TransSeqSnapData *snap_data = MEM_new<TransSeqSnapData>(__func__);
662
663 VectorSet<Strip *> empty_col;
664 VectorSet<Strip *> snap_targets = query_snap_targets_timeline(scene, empty_col, false);
665
666 BLI_assert(frame_1 <= frame_2);
667
668 snap_data->source_snap_points[0][0] = frame_1;
669 snap_data->source_snap_points[1][0] = frame_2;
670
671 short snap_mode = t->tsnap.mode;
672
673 /* Build arrays of snap target frames. */
674 points_build_targets_timeline(scene, snap_mode, snap_data, snap_targets);
675
676 t->tsnap.seq_context = snap_data;
677 bool snap_success = snap_sequencer_calc(t);
678 snap_sequencer_data_free(snap_data);
679 t->tsnap.seq_context = nullptr;
680
681 float snap_offset = 0;
682 if (snap_success) {
684 snap_sequencer_apply_seqslide(t, &snap_offset);
685 }
686 else {
688 }
689
690 return snap_offset;
691}
692
694 ARegion *region,
695 const int frame_1,
696 const int frame_2,
697 int *r_snap_distance,
698 float *r_snap_frame)
699{
700 TransInfo t = {nullptr};
701 t.scene = scene;
702 t.region = region;
703 t.values[0] = 0;
705
707 *r_snap_distance = snap_sequencer_to_closest_strip_ex(&t, frame_1, frame_2);
708 *r_snap_frame = t.tsnap.snap_target[0];
709 return validSnap(&t);
710}
711
712void sequencer_snap_point(ARegion *region, const float snap_point)
713{
714 /* Reuse the snapping drawing code from the transform system. */
715 TransInfo t = {nullptr};
719 t.tsnap.flag = SCE_SNAP;
721 t.tsnap.snap_target[0] = snap_point;
722 t.region = region;
723
724 drawSnapping(&t);
725}
726
728
729} // namespace blender::ed::transform
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
MINLINE int round_fl_to_int(float a)
MINLINE void copy_v2_v2(float r[2], const float a[2])
#define CLAMP(a, b, c)
#define ELEM(...)
@ SEQ_SNAP_IGNORE_SOUND
@ SEQ_SNAP_IGNORE_MUTED
@ SEQ_SNAP_TO_MARKERS
@ SEQ_SNAP_TO_FRAME_RANGE
@ SEQ_SNAP_TO_PREVIEW_CENTER
@ SEQ_SNAP_TO_STRIPS_PREVIEW
@ SEQ_SNAP_TO_PREVIEW_BORDERS
@ SEQ_SNAP_TO_STRIP_HOLD
@ SEQ_SNAP_TO_RETIMING
@ SEQ_SNAP_TO_CURRENT_FRAME
#define PSFRA
@ SCE_SNAP
#define PEFRA
#define MAXFRAME
@ SEQ_RIGHTSEL
@ SEQ_LEFTSEL
@ STRIP_TYPE_SOUND_RAM
@ STRIP_TYPE_EFFECT
@ SPACE_SEQ
Read Guarded memory(de)allocation.
float UI_view2d_region_to_view_x(const View2D *v2d, float x)
Definition view2d.cc:1656
BMesh const char void * data
BMesh * bm
ValueIterator values() const &
Definition BLI_map.hh:884
bool add(const Key &key, const Value &value)
Definition BLI_map.hh:295
ItemIterator items() const &
Definition BLI_map.hh:902
constexpr int64_t size() const
Definition BLI_span.hh:252
bool add(const Key &key)
bool contains(const Key &key) const
int64_t remove_if(Predicate &&predicate)
#define SELECT
#define abs
static int left
static void points_build_targets_timeline(const Scene *scene, const short snap_mode, TransSeqSnapData *snap_data, const Span< Strip * > strip_targets)
static bool snap_calc_preview_image(TransInfo *t, const TransSeqSnapData *snap_data)
static void points_build_sources_preview_image(const Scene *scene, TransSeqSnapData *snap_data, const Span< Strip * > snap_sources)
void sequencer_snap_point(ARegion *region, float snap_point)
static void points_build_3x3_grid(const Scene *scene, TransSeqSnapData *snap_data, Strip *strip)
TransConvertTypeInfo TransConvertType_Sequencer
static void snap_data_build_timeline(const TransInfo *t, TransSeqSnapData *snap_data)
static void points_build_sources_preview_origin(const Scene *scene, TransSeqSnapData *snap_data, const Span< Strip * > snap_sources)
static float seq_snap_threshold_get_view_distance(const TransInfo *t)
static Map< SeqRetimingKey *, Strip * > visible_retiming_keys_get(const Scene *scene, Span< Strip * > snap_strip_targets)
bool validSnap(const TransInfo *t)
static int seq_snap_threshold_get_frame_distance(const TransInfo *t)
void snap_sequencer_apply_seqslide(TransInfo *t, float *vec)
static void query_strip_effects_fn(const Scene *scene, Strip *strip_reference, ListBase *seqbase, VectorSet< Strip * > &strips)
static VectorSet< Strip * > query_snap_targets_timeline(Scene *scene, const Span< Strip * > snap_sources, const bool exclude_selected)
void snap_sequencer_image_apply_translate(TransInfo *t, float vec[2])
static void snap_data_build_preview(const TransInfo *t, TransSeqSnapData *snap_data)
static void points_build_sources_timeline_retiming(const Scene *scene, TransSeqSnapData *snap_data, const Map< SeqRetimingKey *, Strip * > &retiming_selection)
static VectorSet< Strip * > query_snap_sources_timeline(const Scene *scene, Map< SeqRetimingKey *, Strip * > &retiming_selection)
void drawSnapping(TransInfo *t)
TransSeqSnapData * snap_sequencer_data_alloc(const TransInfo *t)
static void points_build_targets_preview_origin(const Scene *scene, TransSeqSnapData *snap_data, const Span< Strip * > snap_sources, const Span< Strip * > snap_targets)
static void points_build_sources_timeline_strips(const Scene *scene, TransSeqSnapData *snap_data, const Span< Strip * > snap_sources)
bool snap_sequencer_to_closest_strip_calc(Scene *scene, ARegion *region, int frame_1, int frame_2, int *r_snap_distance, float *r_snap_frame)
static VectorSet< Strip * > query_snap_sources_preview(const Scene *scene)
static int snap_sequencer_to_closest_strip_ex(TransInfo *t, const int frame_1, const int frame_2)
static void points_build_targets_preview_general(const View2D *v2d, const short snap_mode, TransSeqSnapData *snap_data)
void snap_sequencer_data_free(TransSeqSnapData *data)
static VectorSet< Strip * > query_snap_targets_preview(const TransInfo *t)
static int cmp_fn(const void *a, const void *b)
TransConvertTypeInfo TransConvertType_CursorSequencer
static bool snap_calc_timeline(TransInfo *t, const TransSeqSnapData *snap_data)
static void points_build_targets_preview_image(const Scene *scene, const View2D *v2d, const short snap_mode, TransSeqSnapData *snap_data, const Span< Strip * > snap_targets)
static bool snap_calc_preview_origin(TransInfo *t, const TransSeqSnapData *snap_data)
T distance(const T &a, const T &b)
T interpolate(const T &a, const T &b, const FactorT &t)
bool render_is_muted(const ListBase *channels, const Strip *strip)
Definition render.cc:2092
int time_right_handle_frame_get(const Scene *scene, const Strip *strip)
Array< float2 > image_transform_final_quad_get(const Scene *scene, const Strip *strip)
ListBase * channels_displayed_get(const Editing *ed)
Definition channels.cc:28
float time_content_end_frame_get(const Scene *scene, const Strip *strip)
VectorSet< Strip * > query_selected_strips(ListBase *seqbase)
Definition iterator.cc:127
blender::Map< SeqRetimingKey *, Strip * > retiming_selection_get(const Editing *ed)
int retiming_key_timeline_frame_get(const Scene *scene, const Strip *strip, const SeqRetimingKey *key)
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:272
MutableSpan< SeqRetimingKey > retiming_keys_get(const Strip *strip)
int time_left_handle_frame_get(const Scene *, const Strip *strip)
float time_start_frame_get(const Strip *strip)
void iterator_set_expand(const Scene *scene, ListBase *seqbase, VectorSet< Strip * > &strips, void strip_query_func(const Scene *scene, Strip *strip_reference, ListBase *seqbase, VectorSet< Strip * > &strips))
Definition iterator.cc:82
bool time_strip_intersects_frame(const Scene *scene, const Strip *strip, const int timeline_frame)
float2 image_transform_origin_offset_pixelspace_get(const Scene *scene, const Strip *strip)
short tool_settings_snap_flag_get(Scene *scene)
Definition sequencer.cc:390
int tool_settings_snap_distance_get(Scene *scene)
Definition sequencer.cc:396
bool relation_is_effect_of_strip(const Strip *effect, const Strip *input)
VectorSet< Strip * > query_rendered_strips(const Scene *scene, ListBase *channels, ListBase *seqbase, const int timeline_frame, const int displayed_channel)
Definition iterator.cc:205
ListBase * active_seqbase_get(const Editing *ed)
Definition sequencer.cc:420
short tool_settings_snap_mode_get(Scene *scene)
Definition sequencer.cc:384
int effect_get_num_inputs(int strip_type)
Definition effects.cc:286
VecBase< float, 2 > float2
void * first
struct RenderData r
ListBase markers
ListBase spacedata
float cursor[2]
TransConvertTypeInfo * data_type
Definition transform.hh:805
float xmax
float xmin
float ymax
float ymin
i
Definition text_draw.cc:230
conversion and adaptation of different datablocks to a common struct.