Blender V4.3
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 <cstdlib>
10
11#include "MEM_guardedalloc.h"
12
13#include "DNA_sequence_types.h"
14
15#include "ED_screen.hh"
16#include "ED_transform.hh"
17
18#include "UI_view2d.hh"
19
20#include "SEQ_channels.hh"
21#include "SEQ_effects.hh"
22#include "SEQ_iterator.hh"
23#include "SEQ_relations.hh"
24#include "SEQ_render.hh"
25#include "SEQ_sequencer.hh"
26#include "SEQ_time.hh"
27#include "SEQ_transform.hh"
28
29#include "transform.hh"
30#include "transform_convert.hh"
31#include "transform_snap.hh"
32
36
37#ifdef WITH_CXX_GUARDEDALLOC
38 MEM_CXX_CLASS_ALLOC_FUNCS("TransSeqSnapData")
39#endif
40};
41
42/* -------------------------------------------------------------------- */
45
47{
49
51 snap_sources = SEQ_query_selected_strips(seqbase);
52
53 return snap_sources;
54}
55
57{
59
60 Editing *ed = SEQ_editing_get(scene);
62
63 snap_sources = SEQ_query_rendered_strips(scene, channels, ed->seqbasep, scene->r.cfra, 0);
64 snap_sources.remove_if([&](Sequence *seq) { return (seq->flag & SELECT) == 0; });
65
66 return snap_sources;
67}
68
70{
71 return snap_sources.size() * 2;
72}
73
75{
76 /* Source points are four corners and the center of an image quad. */
77 return snap_sources.size() * 5;
78}
79
80static int cmp_fn(const void *a, const void *b)
81{
82 return round_fl_to_int((*(blender::float2 *)a)[0] - (*(blender::float2 *)b)[0]);
83}
84
86 TransSeqSnapData *snap_data,
87 const blender::Span<Sequence *> snap_sources)
88{
89
90 const size_t point_count_source = seq_get_snap_source_points_count_timeline(snap_sources);
91 if (point_count_source == 0) {
92 return false;
93 }
94
95 snap_data->source_snap_points.reinitialize(point_count_source);
96 int i = 0;
97 for (Sequence *seq : snap_sources) {
98 int left = 0, right = 0;
99 if (seq->flag & SEQ_LEFTSEL && !(seq->flag & SEQ_RIGHTSEL)) {
100 left = right = SEQ_time_left_handle_frame_get(scene, seq);
101 }
102 else if (seq->flag & SEQ_RIGHTSEL && !(seq->flag & SEQ_LEFTSEL)) {
103 left = right = SEQ_time_right_handle_frame_get(scene, seq);
104 }
105 else {
107 right = SEQ_time_right_handle_frame_get(scene, seq);
108 }
109
110 /* Set only the x-positions when snapping in the timeline. */
111 snap_data->source_snap_points[i][0] = left;
112 snap_data->source_snap_points[i + 1][0] = right;
113 i += 2;
114 BLI_assert(i <= snap_data->source_snap_points.size());
115 }
116
117 qsort(snap_data->source_snap_points.data(),
118 snap_data->source_snap_points.size(),
119 sizeof(blender::float2),
120 cmp_fn);
121
122 return true;
123}
124
126 TransSeqSnapData *snap_data,
127 const blender::Span<Sequence *> snap_sources)
128{
129
130 const size_t point_count_source = seq_get_snap_source_points_count_preview(snap_sources);
131 if (point_count_source == 0) {
132 return false;
133 }
134
135 snap_data->source_snap_points.reinitialize(point_count_source);
136 int i = 0;
137 for (Sequence *seq : snap_sources) {
138 float seq_image_quad[4][2];
139 SEQ_image_transform_final_quad_get(scene, seq, seq_image_quad);
140
141 for (int j = 0; j < 4; j++) {
142 snap_data->source_snap_points[i][0] = seq_image_quad[j][0];
143 snap_data->source_snap_points[i][1] = seq_image_quad[j][1];
144 i++;
145 }
146
147 /* Add origins last */
148 float image_origin[2];
149 SEQ_image_transform_origin_offset_pixelspace_get(scene, seq, image_origin);
150 snap_data->source_snap_points[i][0] = image_origin[0];
151 snap_data->source_snap_points[i][1] = image_origin[1];
152 i++;
153
154 BLI_assert(i <= snap_data->source_snap_points.size());
155 }
156
157 return true;
158}
159
161
162/* -------------------------------------------------------------------- */
165
166/* Add effect strips directly or indirectly connected to `seq_reference` to `collection`. */
167static void query_strip_effects_fn(const Scene *scene,
168 Sequence *seq_reference,
169 ListBase *seqbase,
171{
172 if (strips.contains(seq_reference)) {
173 return; /* Strip is already in set, so all effects connected to it are as well. */
174 }
175 strips.add(seq_reference);
176
177 /* Find all strips connected to `seq_reference`. */
178 LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
179 if (SEQ_relation_is_effect_of_strip(seq_test, seq_reference)) {
180 query_strip_effects_fn(scene, seq_test, seqbase, strips);
181 }
182 }
183}
184
186 Scene *scene, const blender::Span<Sequence *> snap_sources, const bool exclude_selected)
187{
188 Editing *ed = SEQ_editing_get(scene);
189 ListBase *seqbase = SEQ_active_seqbase_get(ed);
191 const short snap_flag = SEQ_tool_settings_snap_flag_get(scene);
192
193 /* Effects will always change position with strip to which they are connected and they don't
194 * have to be selected. Remove such strips from `snap_targets` collection. */
195 blender::VectorSet effects_of_snap_sources = snap_sources;
196 SEQ_iterator_set_expand(scene, seqbase, effects_of_snap_sources, query_strip_effects_fn);
197 effects_of_snap_sources.remove_if(
198 [&](Sequence *seq) { return SEQ_effect_get_num_inputs(seq->type) == 0; });
199
201 LISTBASE_FOREACH (Sequence *, seq, seqbase) {
202 if (exclude_selected && seq->flag & SELECT) {
203 continue; /* Selected are being transformed if there is no drag and drop. */
204 }
205 if (SEQ_render_is_muted(channels, seq) && (snap_flag & SEQ_SNAP_IGNORE_MUTED)) {
206 continue;
207 }
208 if (seq->type == SEQ_TYPE_SOUND_RAM && (snap_flag & SEQ_SNAP_IGNORE_SOUND)) {
209 continue;
210 }
211 if (effects_of_snap_sources.contains(seq)) {
212 continue;
213 }
214
215 snap_targets.add(seq);
216 }
217
218 return snap_targets;
219}
220
222 const short snap_mode)
223{
225
226 /* We don't need to calculate strip snap targets if the option is unselected. */
227 if ((snap_mode & SEQ_SNAP_TO_STRIPS_PREVIEW) == 0) {
228 return snap_targets;
229 }
230
231 Editing *ed = SEQ_editing_get(scene);
233
234 snap_targets = SEQ_query_rendered_strips(scene, channels, ed->seqbasep, scene->r.cfra, 0);
235 snap_targets.remove_if([&](Sequence *seq) { return (seq->flag & SELECT) == 1; });
236
237 return snap_targets;
238}
239
241 const short snap_mode,
242 const blender::Span<Sequence *> snap_targets)
243{
244 int count = 0;
245
246 if (snap_mode & SEQ_SNAP_TO_STRIPS) {
247 count += 2; /* Strip start and end are always used. */
248 }
249
250 if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) {
251 count += 2;
252 }
253
254 count *= snap_targets.size();
255
256 if (snap_mode & SEQ_SNAP_TO_CURRENT_FRAME) {
257 count++;
258 }
259
260 if (snap_mode & SEQ_SNAP_TO_MARKERS) {
261 count += BLI_listbase_count(&scene->markers);
262 }
263
264 return count;
265}
266
267static int seq_get_snap_target_points_count_preview(const short snap_mode,
268 const blender::Span<Sequence *> snap_targets)
269{
270 int count = 0;
271
272 if (snap_mode & SEQ_SNAP_TO_PREVIEW_BORDERS) {
273 /* Opposite corners of the view have enough information to snap to all four corners. */
274 count += 2;
275 }
276
277 if (snap_mode & SEQ_SNAP_TO_PREVIEW_CENTER) {
278 count++;
279 }
280
281 if (snap_mode & SEQ_SNAP_TO_STRIPS_PREVIEW) {
282 /* Snap to other strips' corners and center. */
283 count += snap_targets.size() * 5;
284 }
285
286 return count;
287}
288
290 const short snap_mode,
291 TransSeqSnapData *snap_data,
292 const blender::Span<Sequence *> snap_targets)
293{
294
295 const size_t point_count_target = seq_get_snap_target_points_count_timeline(
296 scene, snap_mode, snap_targets);
297 if (point_count_target == 0) {
298 return false;
299 }
300
301 snap_data->target_snap_points.reinitialize(point_count_target);
302 int i = 0;
303
304 if (snap_mode & SEQ_SNAP_TO_CURRENT_FRAME) {
305 snap_data->target_snap_points[i][0] = scene->r.cfra;
306 i++;
307 }
308
309 if (snap_mode & SEQ_SNAP_TO_MARKERS) {
310 LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
311 snap_data->target_snap_points[i][0] = marker->frame;
312 i++;
313 }
314 }
315
316 for (Sequence *seq : snap_targets) {
317 snap_data->target_snap_points[i][0] = SEQ_time_left_handle_frame_get(scene, seq);
318 snap_data->target_snap_points[i + 1][0] = SEQ_time_right_handle_frame_get(scene, seq);
319 i += 2;
320
321 if (snap_mode & SEQ_SNAP_TO_STRIP_HOLD) {
322 int content_start = SEQ_time_start_frame_get(seq);
323 int content_end = SEQ_time_content_end_frame_get(scene, seq);
324
325 /* Effects and single image strips produce incorrect content length. Skip these strips. */
326 if ((seq->type & SEQ_TYPE_EFFECT) != 0 || seq->len == 1) {
327 content_start = SEQ_time_left_handle_frame_get(scene, seq);
328 content_end = SEQ_time_right_handle_frame_get(scene, seq);
329 }
330
331 CLAMP(content_start,
334 CLAMP(content_end,
337
338 snap_data->target_snap_points[i][0] = content_start;
339 snap_data->target_snap_points[i + 1][0] = content_end;
340 i += 2;
341 }
342 }
343 BLI_assert(i <= snap_data->target_snap_points.size());
344 qsort(snap_data->target_snap_points.data(),
345 snap_data->target_snap_points.size(),
346 sizeof(blender::float2),
347 cmp_fn);
348 return true;
349}
350
352 const View2D *v2d,
353 const short snap_mode,
354 TransSeqSnapData *snap_data,
355 const blender::Span<Sequence *> snap_targets)
356{
357
358 const size_t point_count_target = seq_get_snap_target_points_count_preview(snap_mode,
359 snap_targets);
360 if (point_count_target == 0) {
361 return false;
362 }
363
364 snap_data->target_snap_points.reinitialize(point_count_target);
365 int i = 0;
366
367 if (snap_mode & SEQ_SNAP_TO_PREVIEW_BORDERS) {
368 snap_data->target_snap_points[i][0] = v2d->tot.xmin;
369 snap_data->target_snap_points[i][1] = v2d->tot.ymin;
370
371 snap_data->target_snap_points[i + 1][0] = v2d->tot.xmax;
372 snap_data->target_snap_points[i + 1][1] = v2d->tot.ymax;
373
374 i += 2;
375 }
376
377 if (snap_mode & SEQ_SNAP_TO_PREVIEW_CENTER) {
378 snap_data->target_snap_points[i][0] = 0;
379 snap_data->target_snap_points[i][1] = 0;
380
381 i++;
382 }
383
384 if (snap_mode & SEQ_SNAP_TO_STRIPS_PREVIEW) {
385 for (Sequence *seq : snap_targets) {
386 float seq_image_quad[4][2];
387 SEQ_image_transform_final_quad_get(scene, seq, seq_image_quad);
388
389 for (int j = 0; j < 4; j++) {
390 snap_data->target_snap_points[i][0] = seq_image_quad[j][0];
391 snap_data->target_snap_points[i][1] = seq_image_quad[j][1];
392 i++;
393 }
394
395 float image_origin[2];
396 SEQ_image_transform_origin_offset_pixelspace_get(scene, seq, image_origin);
397 snap_data->target_snap_points[i][0] = image_origin[0];
398 snap_data->target_snap_points[i][1] = image_origin[1];
399
400 i++;
401 }
402 }
403 BLI_assert(i <= snap_data->target_snap_points.size());
404
405 return true;
406}
407
409
410/* -------------------------------------------------------------------- */
413
415{
416 const int snap_distance = SEQ_tool_settings_snap_distance_get(t->scene);
417 const View2D *v2d = &t->region->v2d;
418 return UI_view2d_region_to_view_x(v2d, snap_distance) - UI_view2d_region_to_view_x(v2d, 0);
419}
420
425
427
429{
430 TransSeqSnapData *snap_data = MEM_new<TransSeqSnapData>(__func__);
431
432 Scene *scene = t->scene;
433 short snap_mode = t->tsnap.mode;
434
437 scene, snap_sources, true);
438
439 /* Build arrays of snap points. */
440 if (!seq_snap_source_points_build_timeline(scene, snap_data, snap_sources) ||
441 !seq_snap_target_points_build_timeline(scene, snap_mode, snap_data, snap_targets))
442 {
443 MEM_delete(snap_data);
444 return nullptr;
445 }
446
447 return snap_data;
448}
449
451{
452 TransSeqSnapData *snap_data = MEM_new<TransSeqSnapData>(__func__);
453
454 Scene *scene = t->scene;
455 short snap_mode = t->tsnap.mode;
456 View2D *v2d = &t->region->v2d;
457
459 blender::VectorSet<Sequence *> snap_targets = query_snap_targets_preview(scene, snap_mode);
460
461 /* Build arrays of snap points. */
462 if (!seq_snap_source_points_build_preview(scene, snap_data, snap_sources) ||
463 !seq_snap_target_points_build_preview(scene, v2d, snap_mode, snap_data, snap_targets))
464 {
465 MEM_delete(snap_data);
466 return nullptr;
467 }
468
469 return snap_data;
470}
471
485
490
492{
493 /* Prevent snapping when constrained to Y axis. */
494 if (t->con.mode & CON_APPLY && t->con.mode & CON_AXIS1) {
495 return false;
496 }
497
498 int best_dist = MAXFRAME, best_target_frame = 0, best_source_frame = 0;
499
500 for (const float *snap_source_point : snap_data->source_snap_points) {
501 for (const float *snap_target_point : snap_data->target_snap_points) {
502 int snap_source_frame = snap_source_point[0];
503 int snap_target_frame = snap_target_point[0];
504 int dist = abs(snap_target_frame - (snap_source_frame + round_fl_to_int(t->values[0])));
505 if (dist > best_dist) {
506 continue;
507 }
508
509 best_dist = dist;
510 best_target_frame = snap_target_frame;
511 best_source_frame = snap_source_frame;
512 }
513 }
514
515 if (best_dist > seq_snap_threshold_get_frame_distance(t)) {
516 return false;
517 }
518
519 t->tsnap.snap_target[0] = best_target_frame;
520 t->tsnap.snap_source[0] = best_source_frame;
521 return true;
522}
523
525{
526 /* Store best snap candidates in x and y directions separately. */
527 blender::float2 best_dist(std::numeric_limits<float>::max());
528 blender::float2 best_target_point(0.0f);
529 blender::float2 best_source_point(0.0f);
530
531 for (const float *snap_source_point : snap_data->source_snap_points) {
532 for (const float *snap_target_point : snap_data->target_snap_points) {
533 /* First update snaps in x direction, then y direction. */
534 for (int i = 0; i < 2; i++) {
535 int dist = abs(snap_target_point[i] - (snap_source_point[i] + t->values[i]));
536 if (dist > best_dist[i]) {
537 continue;
538 }
539
540 best_dist[i] = dist;
541 best_target_point[i] = snap_target_point[i];
542 best_source_point[i] = snap_source_point[i];
543 }
544 }
545 }
546
549
550 if (best_dist[0] <= thr) {
551 t->tsnap.snap_target[0] = best_target_point[0];
552 t->tsnap.snap_source[0] = best_source_point[0];
554 }
555
556 if (best_dist[1] <= thr) {
557 t->tsnap.snap_target[1] = best_target_point[1];
558 t->tsnap.snap_source[1] = best_source_point[1];
560 }
561
562 return (best_dist[0] <= thr || best_dist[1] <= thr);
563}
564
566{
567 const TransSeqSnapData *snap_data = t->tsnap.seq_context;
568 if (snap_data == nullptr) {
569 return false;
570 }
571
573 return transform_snap_sequencer_calc_timeline(t, snap_data);
574 }
575 else {
576 return transform_snap_sequencer_calc_preview(t, snap_data);
577 }
578}
579
581{
582 *vec = t->tsnap.snap_target[0] - t->tsnap.snap_source[0];
583}
584
586{
587 /* Apply snap along x and y axes independently. */
588 if (t->tsnap.direction & DIR_GLOBAL_X) {
589 vec[0] = t->tsnap.snap_target[0] - t->tsnap.snap_source[0];
590 }
591
592 if (t->tsnap.direction & DIR_GLOBAL_Y) {
593 vec[1] = t->tsnap.snap_target[1] - t->tsnap.snap_source[1];
594 }
595}
596
598 const int frame_1,
599 const int frame_2)
600{
601 Scene *scene = t->scene;
602 TransSeqSnapData *snap_data = MEM_new<TransSeqSnapData>(__func__);
603
606 scene, empty_col, false);
607
608 BLI_assert(frame_1 <= frame_2);
609 snap_data->source_snap_points.reinitialize(2);
610 snap_data->source_snap_points[0][0] = frame_1;
611 snap_data->source_snap_points[1][0] = frame_2;
612
613 short snap_mode = t->tsnap.mode;
614
615 /* Build arrays of snap target frames. */
616 seq_snap_target_points_build_timeline(scene, snap_mode, snap_data, snap_targets);
617
618 t->tsnap.seq_context = snap_data;
619 bool snap_success = transform_snap_sequencer_calc(t);
621 t->tsnap.seq_context = nullptr;
622
623 float snap_offset = 0;
624 if (snap_success) {
627 }
628 else {
630 }
631
632 return snap_offset;
633}
634
636 ARegion *region,
637 const int frame_1,
638 const int frame_2,
639 int *r_snap_distance,
640 float *r_snap_frame)
641{
642 TransInfo t = {nullptr};
643 t.scene = scene;
644 t.region = region;
645 t.values[0] = 0;
647
649 *r_snap_distance = transform_snap_sequencer_to_closest_strip_ex(&t, frame_1, frame_2);
650 *r_snap_frame = t.tsnap.snap_target[0];
651 return validSnap(&t);
652}
653
654void ED_draw_sequencer_snap_point(ARegion *region, const float snap_point)
655{
656 /* Reuse the snapping drawing code from the transform system. */
657 TransInfo t = {nullptr};
661 t.tsnap.flag = SCE_SNAP;
663 t.tsnap.snap_target[0] = snap_point;
664 t.region = region;
665
666 drawSnapping(&t);
667}
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int round_fl_to_int(float a)
#define CLAMP(a, b, c)
@ SEQ_SNAP_IGNORE_SOUND
@ SEQ_SNAP_IGNORE_MUTED
@ SEQ_SNAP_TO_STRIPS
@ SEQ_SNAP_TO_MARKERS
@ SEQ_SNAP_TO_PREVIEW_CENTER
@ SEQ_SNAP_TO_STRIPS_PREVIEW
@ SEQ_SNAP_TO_PREVIEW_BORDERS
@ SEQ_SNAP_TO_STRIP_HOLD
@ SEQ_SNAP_TO_CURRENT_FRAME
@ SCE_SNAP
#define MAXFRAME
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_EFFECT
@ SEQ_RIGHTSEL
@ SEQ_LEFTSEL
@ SPACE_SEQ
@ TFM_SEQ_SLIDE
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
float UI_view2d_region_to_view_x(const View2D *v2d, float x)
Definition view2d.cc:1652
ListBase * SEQ_channels_displayed_get(Editing *ed)
Definition channels.cc:23
int64_t size() const
Definition BLI_array.hh:245
constexpr int64_t size() const
Definition BLI_span.hh:253
bool add(const Key &key)
bool contains(const Key &key) const
int64_t remove_if(Predicate &&predicate)
local_group_size(16, 16) .push_constant(Type b
#define SELECT
int SEQ_effect_get_num_inputs(int seq_type)
Definition effects.cc:3467
int count
VectorSet< Sequence * > SEQ_query_rendered_strips(const Scene *scene, ListBase *channels, ListBase *seqbase, const int timeline_frame, const int displayed_channel)
Definition iterator.cc:184
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
VectorSet< Sequence * > SEQ_query_selected_strips(ListBase *seqbase)
Definition iterator.cc:106
static int left
VecBase< float, 2 > float2
bool SEQ_render_is_muted(const ListBase *channels, const Sequence *seq)
Definition render.cc:2154
ListBase * SEQ_active_seqbase_get(const Editing *ed)
Definition sequencer.cc:416
short SEQ_tool_settings_snap_mode_get(Scene *scene)
Definition sequencer.cc:380
int SEQ_tool_settings_snap_distance_get(Scene *scene)
Definition sequencer.cc:392
short SEQ_tool_settings_snap_flag_get(Scene *scene)
Definition sequencer.cc:386
Editing * SEQ_editing_get(const Scene *scene)
Definition sequencer.cc:262
bool SEQ_relation_is_effect_of_strip(const Sequence *effect, const Sequence *input)
int SEQ_time_left_handle_frame_get(const Scene *, const Sequence *seq)
float SEQ_time_content_end_frame_get(const Scene *scene, const Sequence *seq)
float SEQ_time_start_frame_get(const Sequence *seq)
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
void SEQ_image_transform_origin_offset_pixelspace_get(const Scene *scene, const Sequence *seq, float r_origin[2])
void SEQ_image_transform_final_quad_get(const Scene *scene, const Sequence *seq, float r_quad[4][2])
ListBase * seqbasep
struct RenderData r
ListBase markers
eTConstraint mode
Definition transform.hh:351
eTfmMode mode
Definition transform.hh:517
char spacetype
Definition transform.hh:582
float values[4]
Definition transform.hh:624
TransSnap tsnap
Definition transform.hh:537
eTModifier modifiers
Definition transform.hh:525
Scene * scene
Definition transform.hh:654
ARegion * region
Definition transform.hh:652
TransCon con
Definition transform.hh:534
TransConvertTypeInfo * data_type
Definition transform.hh:513
blender::Array< blender::float2 > target_snap_points
blender::Array< blender::float2 > source_snap_points
TransSeqSnapData * seq_context
Definition transform.hh:341
eSnapFlag flag
Definition transform.hh:310
eTSnap status
Definition transform.hh:318
float snap_target[3]
Definition transform.hh:327
float snap_source[3]
Definition transform.hh:325
eSnapMode mode
Definition transform.hh:312
eSnapDir direction
Definition transform.hh:323
float xmax
float xmin
float ymax
float ymin
@ SNAP_TARGET_FOUND
Definition transform.hh:177
@ SNAP_SOURCE_FOUND
Definition transform.hh:175
@ CON_APPLY
Definition transform.hh:193
@ CON_AXIS1
Definition transform.hh:196
@ MOD_SNAP
Definition transform.hh:163
@ DIR_GLOBAL_Y
Definition transform.hh:185
@ DIR_GLOBAL_X
Definition transform.hh:184
conversion and adaptation of different datablocks to a common struct.
TransConvertTypeInfo TransConvertType_Sequencer
TransConvertTypeInfo TransConvertType_SequencerRetiming
bool validSnap(const TransInfo *t)
void drawSnapping(TransInfo *t)
static blender::VectorSet< Sequence * > query_snap_sources_timeline(const Scene *scene)
void transform_snap_sequencer_image_apply_translate(TransInfo *t, float vec[2])
static int seq_get_snap_source_points_count_preview(const blender::Span< Sequence * > snap_sources)
void transform_snap_sequencer_apply_seqslide(TransInfo *t, float *vec)
static int seq_get_snap_target_points_count_preview(const short snap_mode, const blender::Span< Sequence * > snap_targets)
static int transform_snap_sequencer_to_closest_strip_ex(TransInfo *t, const int frame_1, const int frame_2)
static blender::VectorSet< Sequence * > query_snap_sources_preview(const Scene *scene)
static bool seq_snap_target_points_build_preview(const Scene *scene, const View2D *v2d, const short snap_mode, TransSeqSnapData *snap_data, const blender::Span< Sequence * > snap_targets)
static bool seq_snap_target_points_build_timeline(const Scene *scene, const short snap_mode, TransSeqSnapData *snap_data, const blender::Span< Sequence * > snap_targets)
void transform_snap_sequencer_data_free(TransSeqSnapData *data)
static bool seq_snap_source_points_build_preview(const Scene *scene, TransSeqSnapData *snap_data, const blender::Span< Sequence * > snap_sources)
static blender::VectorSet< Sequence * > query_snap_targets_timeline(Scene *scene, const blender::Span< Sequence * > snap_sources, const bool exclude_selected)
static bool transform_snap_sequencer_calc_preview(TransInfo *t, const TransSeqSnapData *snap_data)
static float seq_snap_threshold_get_view_distance(const TransInfo *t)
static int seq_get_snap_source_points_count_timeline(const blender::Span< Sequence * > snap_sources)
bool ED_transform_snap_sequencer_to_closest_strip_calc(Scene *scene, ARegion *region, const int frame_1, const int frame_2, int *r_snap_distance, float *r_snap_frame)
static TransSeqSnapData * transform_snap_sequencer_data_alloc_preview(const TransInfo *t)
static void query_strip_effects_fn(const Scene *scene, Sequence *seq_reference, ListBase *seqbase, blender::VectorSet< Sequence * > &strips)
static int seq_get_snap_target_points_count_timeline(const Scene *scene, const short snap_mode, const blender::Span< Sequence * > snap_targets)
static TransSeqSnapData * transform_snap_sequencer_data_alloc_timeline(const TransInfo *t)
void ED_draw_sequencer_snap_point(ARegion *region, const float snap_point)
TransSeqSnapData * transform_snap_sequencer_data_alloc(const TransInfo *t)
static bool seq_snap_source_points_build_timeline(const Scene *scene, TransSeqSnapData *snap_data, const blender::Span< Sequence * > snap_sources)
static int seq_snap_threshold_get_frame_distance(const TransInfo *t)
static bool transform_snap_sequencer_calc_timeline(TransInfo *t, const TransSeqSnapData *snap_data)
bool transform_snap_sequencer_calc(TransInfo *t)
static int cmp_fn(const void *a, const void *b)
static blender::VectorSet< Sequence * > query_snap_targets_preview(Scene *scene, const short snap_mode)
ccl_device_inline int abs(int x)
Definition util/math.h:120