Blender V4.3
transform_convert_sequencer_image.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "MEM_guardedalloc.h"
10
11#include "DNA_sequence_types.h"
12#include "DNA_space_types.h"
13
14#include "BLI_math_matrix.h"
15#include "BLI_math_rotation.h"
16#include "BLI_math_vector.h"
17
18#include "BKE_report.hh"
19
20#include "SEQ_channels.hh"
21#include "SEQ_iterator.hh"
22#include "SEQ_relations.hh"
23#include "SEQ_sequencer.hh"
24#include "SEQ_transform.hh"
25
26#include "ANIM_keyframing.hh"
27
28#include "RNA_access.hh"
29#include "RNA_prototypes.hh"
30
31#include "transform.hh"
32#include "transform_convert.hh"
33
35struct TransDataSeq {
39 float orig_scale[2];
41};
42
43static TransData *SeqToTransData(const Scene *scene,
44 Sequence *seq,
45 TransData *td,
46 TransData2D *td2d,
47 TransDataSeq *tdseq,
48 int vert_index)
49{
51 float origin[2];
53 float vertex[2] = {origin[0], origin[1]};
54
55 /* Add control vertex, so rotation and scale can be calculated.
56 * All three vertices will form a "L" shape that is aligned to the local strip axis.
57 */
58 if (vert_index == 1) {
59 vertex[0] += cosf(transform->rotation);
60 vertex[1] += sinf(transform->rotation);
61 }
62 else if (vert_index == 2) {
63 vertex[0] -= sinf(transform->rotation);
64 vertex[1] += cosf(transform->rotation);
65 }
66
67 td2d->loc[0] = vertex[0];
68 td2d->loc[1] = vertex[1];
69 td2d->loc2d = nullptr;
70 td->loc = td2d->loc;
71 copy_v3_v3(td->iloc, td->loc);
72
73 td->center[0] = origin[0];
74 td->center[1] = origin[1];
75
76 unit_m3(td->mtx);
77 unit_m3(td->smtx);
78
79 axis_angle_to_mat3_single(td->axismtx, 'Z', transform->rotation);
81
82 tdseq->seq = seq;
83 copy_v2_v2(tdseq->orig_origin_position, origin);
84 tdseq->orig_translation[0] = transform->xofs;
85 tdseq->orig_translation[1] = transform->yofs;
86 tdseq->orig_scale[0] = transform->scale_x;
87 tdseq->orig_scale[1] = transform->scale_y;
88 tdseq->orig_rotation = transform->rotation;
89
90 td->extra = (void *)tdseq;
91 td->ext = nullptr;
92 td->flag |= TD_SELECTED;
93 td->dist = 0.0;
94
95 return td;
96}
97
98static void freeSeqData(TransInfo * /*t*/,
100 TransCustomData * /*custom_data*/)
101{
102 TransData *td = (TransData *)tc->data;
103 MEM_freeN(td->extra);
104}
105
107{
108 Editing *ed = SEQ_editing_get(t->scene);
109 const SpaceSeq *sseq = static_cast<const SpaceSeq *>(t->area->spacedata.first);
110 const ARegion *region = t->region;
111
112 if (ed == nullptr) {
113 return;
114 }
115 if (sseq->mainb != SEQ_DRAW_IMG_IMBUF) {
116 return;
117 }
118 if (region->regiontype == RGN_TYPE_PREVIEW && sseq->view == SEQ_VIEW_SEQUENCE_PREVIEW) {
119 return;
120 }
121
122 ListBase *seqbase = SEQ_active_seqbase_get(ed);
125 t->scene, channels, seqbase, t->scene->r.cfra, 0);
126 strips.remove_if([&](Sequence *seq) { return (seq->flag & SELECT) == 0; });
127
128 if (strips.is_empty()) {
129 return;
130 }
131
134
135 tc->data_len = strips.size() * 3; /* 3 vertices per sequence are needed. */
136 TransData *td = tc->data = static_cast<TransData *>(
137 MEM_callocN(tc->data_len * sizeof(TransData), "TransSeq TransData"));
138 TransData2D *td2d = tc->data_2d = static_cast<TransData2D *>(
139 MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D"));
140 TransDataSeq *tdseq = static_cast<TransDataSeq *>(
141 MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq"));
142
143 for (Sequence *seq : strips) {
144 /* One `Sequence` needs 3 `TransData` entries - center point placed in image origin, then 2
145 * points offset by 1 in X and Y direction respectively, so rotation and scale can be
146 * calculated from these points. */
147 SeqToTransData(t->scene, seq, td++, td2d++, tdseq++, 0);
148 SeqToTransData(t->scene, seq, td++, td2d++, tdseq++, 1);
149 SeqToTransData(t->scene, seq, td++, td2d++, tdseq++, 2);
150 }
151}
152
154 Scene *scene,
156 const int tmode)
157{
158 PropertyRNA *prop;
159 PointerRNA ptr = RNA_pointer_create(&scene->id, &RNA_SequenceTransform, transform);
160
161 const bool around_cursor = scene->toolsettings->sequencer_tool_settings->pivot_point ==
163 const bool do_loc = tmode == TFM_TRANSLATION || around_cursor;
164 const bool do_rot = tmode == TFM_ROTATION;
165 const bool do_scale = tmode == TFM_RESIZE;
166 const bool only_when_keyed = blender::animrig::is_keying_flag(scene,
168
169 bool changed = false;
170 if (do_rot) {
171 prop = RNA_struct_find_property(&ptr, "rotation");
173 C, scene, &ptr, prop, -1, scene->r.cfra, only_when_keyed);
174 }
175 if (do_loc) {
176 prop = RNA_struct_find_property(&ptr, "offset_x");
178 C, scene, &ptr, prop, -1, scene->r.cfra, only_when_keyed);
179 prop = RNA_struct_find_property(&ptr, "offset_y");
181 C, scene, &ptr, prop, -1, scene->r.cfra, only_when_keyed);
182 }
183 if (do_scale) {
184 prop = RNA_struct_find_property(&ptr, "scale_x");
186 C, scene, &ptr, prop, -1, scene->r.cfra, only_when_keyed);
187 prop = RNA_struct_find_property(&ptr, "scale_y");
189 C, scene, &ptr, prop, -1, scene->r.cfra, only_when_keyed);
190 }
191
192 return changed;
193}
194
196{
198 TransData *td = nullptr;
199 TransData2D *td2d = nullptr;
200 int i;
201
202 for (i = 0, td = tc->data, td2d = tc->data_2d; i < tc->data_len; i++, td++, td2d++) {
203 /* Origin. */
204 float origin[2];
205 copy_v2_v2(origin, td2d->loc);
206 i++;
207 td++;
208 td2d++;
209
210 /* X and Y control points used to read scale and rotation. */
211 float handle_x[2];
212 copy_v2_v2(handle_x, td2d->loc);
213 sub_v2_v2(handle_x, origin);
214 i++;
215 td++;
216 td2d++;
217
218 float handle_y[2];
219 copy_v2_v2(handle_y, td2d->loc);
220 sub_v2_v2(handle_y, origin);
221
222 TransDataSeq *tdseq = static_cast<TransDataSeq *>(td->extra);
223 Sequence *seq = tdseq->seq;
225 float mirror[2];
227
228 /* Calculate translation. */
229 float translation[2];
230 copy_v2_v2(translation, tdseq->orig_origin_position);
231 sub_v2_v2(translation, origin);
232 mul_v2_v2(translation, mirror);
233 translation[0] *= t->scene->r.yasp / t->scene->r.xasp;
234
235 /* Round resulting position to integer pixels. Resulting strip
236 * will more often end up using faster interpolation (without bilinear),
237 * and avoids "text edges are too dark" artifacts with light text strips
238 * on light backgrounds. The latter happens because bilinear filtering
239 * does not do full alpha pre-multiplication. */
240 transform->xofs = roundf(tdseq->orig_translation[0] - translation[0]);
241 transform->yofs = roundf(tdseq->orig_translation[1] - translation[1]);
242
243 /* Scale. */
244 transform->scale_x = tdseq->orig_scale[0] * fabs(len_v2(handle_x));
245 transform->scale_y = tdseq->orig_scale[1] * fabs(len_v2(handle_y));
246
247 /* Rotation. Scaling can cause negative rotation. */
248 if (t->mode == TFM_ROTATION) {
249 transform->rotation = tdseq->orig_rotation - t->values_final[0];
250 }
251
255 }
256
258 }
259}
260
262{
263
265 TransData *td = nullptr;
266 TransData2D *td2d = nullptr;
267 int i;
268
269 for (i = 0, td = tc->data, td2d = tc->data_2d; i < tc->data_len; i++, td++, td2d++) {
270 TransDataSeq *tdseq = static_cast<TransDataSeq *>(td->extra);
271 Sequence *seq = tdseq->seq;
273 if (t->state == TRANS_CANCEL) {
274 if (t->mode == TFM_ROTATION) {
275 transform->rotation = tdseq->orig_rotation;
276 }
277 continue;
278 }
279
282 }
283 }
284}
285
287 /*flags*/ (T_POINTS | T_2D_EDIT),
288 /*create_trans_data*/ createTransSeqImageData,
289 /*recalc_data*/ recalcData_sequencer_image,
290 /*special_aftertrans_update*/ special_aftertrans_update__sequencer_image,
291};
Functions to insert, delete or modify keyframes.
void unit_m3(float m[3][3])
void normalize_m3(float R[3][3]) ATTR_NONNULL()
void axis_angle_to_mat3_single(float R[3][3], char axis, float angle)
MINLINE float len_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v2_v2(float r[2], const float a[2])
MINLINE void mul_v2_v2(float r[2], const float a[2])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
@ RGN_TYPE_PREVIEW
struct Sequence Sequence
@ SEQ_VIEW_SEQUENCE_PREVIEW
@ SEQ_DRAW_IMG_IMBUF
@ AUTOKEY_FLAG_INSERTAVAILABLE
@ V3D_AROUND_CURSOR
@ TFM_RESIZE
@ TFM_ROTATION
@ 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
#define C
Definition RandGen.cpp:29
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
ListBase * SEQ_channels_displayed_get(Editing *ed)
Definition channels.cc:23
int64_t size() const
int64_t remove_if(Predicate &&predicate)
#define SELECT
#define sinf(x)
#define cosf(x)
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 MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
ccl_device_inline float2 fabs(const float2 a)
bool is_autokey_on(const Scene *scene)
bool autokeyframe_property(bContext *C, Scene *scene, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, float cfra, bool only_if_property_keyed)
bool is_keying_flag(const Scene *scene, eKeying_Flag flag)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
ListBase * SEQ_active_seqbase_get(const Editing *ed)
Definition sequencer.cc:416
Editing * SEQ_editing_get(const Scene *scene)
Definition sequencer.cc:262
void SEQ_relations_invalidate_cache_preprocessed(Scene *scene, Sequence *seq)
void SEQ_image_transform_origin_offset_pixelspace_get(const Scene *scene, const Sequence *seq, float r_origin[2])
void SEQ_image_transform_mirror_factor_get(const Sequence *seq, float r_mirror[2])
void * first
struct ToolSettings * toolsettings
struct RenderData r
ListBase spacedata
StripTransform * transform
struct SequencerToolSettings * sequencer_tool_settings
TransCustomData type
Definition transform.hh:425
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
wmTimer * animtimer
Definition transform.hh:657
eTState state
Definition transform.hh:527
Scene * scene
Definition transform.hh:654
ARegion * region
Definition transform.hh:652
float values_final[4]
Definition transform.hh:632
bContext * context
Definition transform.hh:649
ScrArea * area
Definition transform.hh:651
@ T_2D_EDIT
Definition transform.hh:104
@ T_POINTS
Definition transform.hh:93
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition transform.hh:851
@ TRANS_CANCEL
Definition transform.hh:210
void animrecord_check_state(TransInfo *t, ID *id)
conversion and adaptation of different datablocks to a common struct.
TransConvertTypeInfo TransConvertType_SequencerImage
static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
static void freeSeqData(TransInfo *, TransDataContainer *tc, TransCustomData *)
static bool autokeyframe_sequencer_image(bContext *C, Scene *scene, StripTransform *transform, const int tmode)
static void recalcData_sequencer_image(TransInfo *t)
static void special_aftertrans_update__sequencer_image(bContext *, TransInfo *t)
static void createTransSeqImageData(bContext *, TransInfo *t)
static TransData * SeqToTransData(const Scene *scene, Sequence *seq, TransData *td, TransData2D *td2d, TransDataSeq *tdseq, int vert_index)
@ TD_SELECTED
PointerRNA * ptr
Definition wm_files.cc:4126