Blender V4.5
transform_convert_sequencer_retiming.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "MEM_guardedalloc.h"
10
11#include "DNA_screen_types.h"
12#include "DNA_sequence_types.h"
13#include "DNA_space_types.h"
14
15#include "BLI_math_matrix.h"
16#include "BLI_math_vector.h"
17
18#include "BKE_context.hh"
19
20#include "SEQ_iterator.hh"
21#include "SEQ_relations.hh"
22#include "SEQ_retiming.hh"
23#include "SEQ_sequencer.hh"
24#include "SEQ_transform.hh"
25
26#include "transform.hh"
27#include "transform_convert.hh"
28
29namespace blender::ed::transform {
30
32struct TransDataSeq {
35 int key_index; /* Some actions may need to destroy original data, use index to access it. */
36};
37
38static TransData *SeqToTransData(const Scene *scene,
39 Strip *strip,
40 const SeqRetimingKey *key,
41 TransData *td,
42 TransData2D *td2d,
43 TransDataSeq *tdseq)
44{
45
46 td2d->loc[0] = seq::retiming_key_timeline_frame_get(scene, strip, key);
47 td2d->loc[1] = key->retiming_factor;
48 td2d->loc2d = nullptr;
49 td->loc = td2d->loc;
50 copy_v3_v3(td->iloc, td->loc);
51 copy_v3_v3(td->center, td->loc);
52 memset(td->axismtx, 0, sizeof(td->axismtx));
53 td->axismtx[2][2] = 1.0f;
54 unit_m3(td->mtx);
55 unit_m3(td->smtx);
56
57 tdseq->strip = strip;
58 tdseq->orig_timeline_frame = seq::retiming_key_timeline_frame_get(scene, strip, key);
59 tdseq->key_index = seq::retiming_key_index_get(strip, key);
60
61 td->extra = static_cast<void *>(tdseq);
62 td->ext = nullptr;
63 td->flag |= TD_SELECTED;
64 td->dist = 0.0;
65
66 return td;
67}
68
69static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData * /*custom_data*/)
70{
71 const TransData *const td = tc->data;
72 Scene *scene = t->scene;
73 const Editing *ed = seq::editing_get(t->scene);
74
75 /* Handle overlapping strips. */
76
77 VectorSet<Strip *> transformed_strips;
78 for (int i = 0; i < tc->data_len; i++) {
79 Strip *strip = ((TransDataSeq *)(td + i)->extra)->strip;
80 transformed_strips.add(strip);
81 }
82
84 seq::iterator_set_expand(scene, seqbasep, transformed_strips, seq::query_strip_effect_chain);
85
86 VectorSet<Strip *> dependant;
87 dependant.add_multiple(transformed_strips);
88 dependant.remove_if([&](Strip *strip) { return seq::transform_strip_can_be_translated(strip); });
89
90 if (seq_transform_check_overlap(transformed_strips)) {
91 const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
92 SEQ_MARKER_TRANS) != 0;
94 scene, seqbasep, transformed_strips, dependant, use_sync_markers);
95 }
96
97 MEM_freeN(td->extra);
98}
99
101{
102 const Editing *ed = seq::editing_get(t->scene);
103 if (ed == nullptr) {
104 return;
105 }
106
108
109 if (selection.is_empty()) {
110 return;
111 }
112
115
116 tc->data_len = selection.size();
117 tc->data = MEM_calloc_arrayN<TransData>(tc->data_len, "TransSeq TransData");
118 tc->data_2d = MEM_calloc_arrayN<TransData2D>(tc->data_len, "TransSeq TransData2D");
119 TransDataSeq *tdseq = MEM_calloc_arrayN<TransDataSeq>(tc->data_len, "TransSeq TransDataSeq");
120 TransData *td = tc->data;
121 TransData2D *td2d = tc->data_2d;
122
123 for (auto item : selection.items()) {
124 SeqToTransData(t->scene, item.value, item.key, td++, td2d++, tdseq++);
125 }
126}
127
129{
131 const TransData *td = nullptr;
132 const TransData2D *td2d = nullptr;
133 int i;
134
135 VectorSet<Strip *> transformed_strips;
136
137 for (i = 0, td = tc->data, td2d = tc->data_2d; i < tc->data_len; i++, td++, td2d++) {
138 const TransDataSeq *tdseq = static_cast<TransDataSeq *>(td->extra);
139 Strip *strip = tdseq->strip;
140
141 transformed_strips.add(strip);
142
143 /* Calculate translation. */
144
145 const MutableSpan keys = seq::retiming_keys_get(strip);
146 SeqRetimingKey *key = &keys[tdseq->key_index];
147
150 {
152 }
153 else {
154 seq::retiming_key_timeline_frame_set(t->scene, strip, key, td2d->loc[0]);
155 }
156
158 }
159
160 /* Test overlap, displays red outline. */
164 for (Strip *strip : transformed_strips) {
165 strip->flag &= ~SEQ_OVERLAP;
167 strip->flag |= SEQ_OVERLAP;
168 }
169 }
170}
171
177
178} // namespace blender::ed::transform
MINLINE int round_fl_to_int(float a)
void unit_m3(float m[3][3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
@ SEQ_OVERLAP
@ SEQ_MARKER_TRANS
Read Guarded memory(de)allocation.
int64_t size() const
Definition BLI_map.hh:976
bool is_empty() const
Definition BLI_map.hh:986
ItemIterator items() const &
Definition BLI_map.hh:902
bool add(const Key &key)
void add_multiple(Span< Key > keys)
int64_t remove_if(Predicate &&predicate)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static TransData * SeqToTransData(Scene *scene, TransData *td, TransData2D *td2d, TransDataSeq *tdsq, Strip *strip, int flag, int sel_flag)
static void recalcData_sequencer_retiming(TransInfo *t)
static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
bool seq_transform_check_overlap(Span< Strip * > transformed_strips)
static void createTransSeqRetimingData(bContext *, TransInfo *t)
int retiming_key_index_get(const Strip *strip, const SeqRetimingKey *key)
void relations_invalidate_cache(Scene *scene, Strip *strip)
bool retiming_selection_has_whole_transition(const Editing *ed, SeqRetimingKey *key)
void retiming_key_timeline_frame_set(const Scene *scene, Strip *strip, SeqRetimingKey *key, const int timeline_frame)
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)
bool transform_test_overlap(const Scene *scene, Strip *strip1, Strip *strip2)
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:272
MutableSpan< SeqRetimingKey > retiming_keys_get(const Strip *strip)
void query_strip_effect_chain(const Scene *scene, Strip *reference_strip, ListBase *seqbase, VectorSet< Strip * > &r_strips)
Definition iterator.cc:231
bool retiming_key_is_transition_type(const SeqRetimingKey *key)
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
void retiming_transition_key_frame_set(const Scene *scene, const Strip *strip, SeqRetimingKey *key, const int timeline_frame)
void transform_handle_overlap(Scene *scene, ListBase *seqbasep, blender::Span< Strip * > transformed_strips, bool use_sync_markers)
ListBase * active_seqbase_get(const Editing *ed)
Definition sequencer.cc:420
bool transform_strip_can_be_translated(const Strip *strip)
void * first
ListBase spacedata
void(* free_cb)(TransInfo *, TransDataContainer *tc, TransCustomData *custom_data)
Definition transform.hh:628
i
Definition text_draw.cc:230
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition transform.hh:39
conversion and adaptation of different datablocks to a common struct.