Blender V4.5
transform_convert_mask.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 "DNA_mask_types.h"
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_context.hh"
19#include "BKE_mask.h"
20
21#include "ED_clip.hh"
22#include "ED_image.hh"
23#include "ED_mask.hh"
24
25#include "ANIM_keyframing.hh"
26
27#include "WM_api.hh"
28#include "WM_types.hh"
29
30#include "transform.hh"
31#include "transform_convert.hh"
32
33namespace blender::ed::transform {
34
47
48/* -------------------------------------------------------------------- */
51
53 eMaskWhichHandle which_handle,
54 TransData *td,
55 TransData2D *td2d,
57 const float asp[2],
58 /*const*/ const float parent_matrix[3][3],
59 /*const*/ const float parent_inverse_matrix[3][3])
60{
61 BezTriple *bezt = &point->bezt;
62 const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
63
64 tdm->point = point;
65 copy_m3_m3(tdm->vec, bezt->vec);
66
67 tdm->is_handle = true;
68 copy_m3_m3(tdm->parent_matrix, parent_matrix);
69 copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
70
71 BKE_mask_point_handle(point, which_handle, tdm->handle);
72 tdm->which_handle = which_handle;
73
74 copy_v2_v2(tdm->orig_handle, tdm->handle);
75
76 mul_v2_m3v2(td2d->loc, parent_matrix, tdm->handle);
77 td2d->loc[0] *= asp[0];
78 td2d->loc[1] *= asp[1];
79 td2d->loc[2] = 0.0f;
80
81 td2d->loc2d = tdm->handle;
82
83 td->flag = 0;
84 td->loc = td2d->loc;
85 mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
86 td->center[0] *= asp[0];
87 td->center[1] *= asp[1];
88 copy_v3_v3(td->iloc, td->loc);
89
90 memset(td->axismtx, 0, sizeof(td->axismtx));
91 td->axismtx[2][2] = 1.0f;
92
93 td->ext = nullptr;
94 td->val = nullptr;
95
96 if (is_sel_any) {
97 td->flag |= TD_SELECTED;
98 }
99
100 td->dist = 0.0;
101
102 unit_m3(td->mtx);
103 unit_m3(td->smtx);
104
105 if (which_handle == MASK_WHICH_HANDLE_LEFT) {
106 tdm->orig_handle_type = bezt->h1;
107 }
108 else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
109 tdm->orig_handle_type = bezt->h2;
110 }
111}
112
113static void MaskPointToTransData(Scene *scene,
114 MaskSplinePoint *point,
115 TransData *td,
116 TransData2D *td2d,
117 TransDataMasking *tdm,
118 const bool is_prop_edit,
119 const float asp[2])
120{
121 BezTriple *bezt = &point->bezt;
122 const bool is_sel_point = MASKPOINT_ISSEL_KNOT(point);
123 const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
124 float parent_matrix[3][3], parent_inverse_matrix[3][3];
125
126 BKE_mask_point_parent_matrix_get(point, scene->r.cfra, parent_matrix);
127 invert_m3_m3(parent_inverse_matrix, parent_matrix);
128
129 if (is_prop_edit || is_sel_point) {
130
131 tdm->point = point;
132 copy_m3_m3(tdm->vec, bezt->vec);
133
134 for (int i = 0; i < 3; i++) {
135 copy_m3_m3(tdm->parent_matrix, parent_matrix);
136 copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
137
138 /* CV coords are scaled by aspects. this is needed for rotations and
139 * proportional editing to be consistent with the stretched CV coords
140 * that are displayed. this also means that for display and number-input,
141 * and when the CV coords are flushed, these are converted each time. */
142 mul_v2_m3v2(td2d->loc, parent_matrix, bezt->vec[i]);
143 td2d->loc[0] *= asp[0];
144 td2d->loc[1] *= asp[1];
145 td2d->loc[2] = 0.0f;
146
147 td2d->loc2d = bezt->vec[i];
148
149 td->flag = 0;
150 td->loc = td2d->loc;
151 mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
152 td->center[0] *= asp[0];
153 td->center[1] *= asp[1];
154 copy_v3_v3(td->iloc, td->loc);
155
156 memset(td->axismtx, 0, sizeof(td->axismtx));
157 td->axismtx[2][2] = 1.0f;
158
159 td->ext = nullptr;
160
161 if (i == 1) {
162 /* Scaling weights. */
163 td->val = &bezt->weight;
164 td->ival = *td->val;
165 }
166 else {
167 td->val = nullptr;
168 }
169
170 if (is_sel_any) {
171 td->flag |= TD_SELECTED;
172 }
173 td->dist = 0.0;
174
175 unit_m3(td->mtx);
176 unit_m3(td->smtx);
177
178 if (i == 0) {
179 tdm->orig_handle_type = bezt->h1;
180 }
181 else if (i == 2) {
182 tdm->orig_handle_type = bezt->h2;
183 }
184
185 td++;
186 td2d++;
187 tdm++;
188 }
189 }
190 else {
194 td,
195 td2d,
196 tdm,
197 asp,
198 parent_matrix,
199 parent_inverse_matrix);
200
201 td++;
202 td2d++;
203 tdm++;
204 }
205 else {
206 if (bezt->f1 & SELECT) {
209 td,
210 td2d,
211 tdm,
212 asp,
213 parent_matrix,
214 parent_inverse_matrix);
215
216 if (bezt->h1 == HD_VECT) {
217 bezt->h1 = HD_FREE;
218 }
219 else if (bezt->h1 == HD_AUTO) {
220 bezt->h1 = HD_ALIGN_DOUBLESIDE;
221 bezt->h2 = HD_ALIGN_DOUBLESIDE;
222 }
223
224 td++;
225 td2d++;
226 tdm++;
227 }
228 if (bezt->f3 & SELECT) {
231 td,
232 td2d,
233 tdm,
234 asp,
235 parent_matrix,
236 parent_inverse_matrix);
237
238 if (bezt->h2 == HD_VECT) {
239 bezt->h2 = HD_FREE;
240 }
241 else if (bezt->h2 == HD_AUTO) {
242 bezt->h1 = HD_ALIGN_DOUBLESIDE;
243 bezt->h2 = HD_ALIGN_DOUBLESIDE;
244 }
245
246 td++;
247 td2d++;
248 tdm++;
249 }
250 }
251 }
252}
253
255{
256 Scene *scene = CTX_data_scene(C);
258 TransData *td = nullptr;
259 TransData2D *td2d = nullptr;
260 TransDataMasking *tdm = nullptr;
261 int count = 0, countsel = 0;
262 const bool is_prop_edit = (t->flag & T_PROP_EDIT);
263 float asp[2];
264
266
267 tc->data_len = 0;
268
270 return;
271 }
272
273 /* Count. */
274 LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
275 if (masklay->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) {
276 continue;
277 }
278
279 LISTBASE_FOREACH (MaskSpline *, spline, &masklay->splines) {
280 int i;
281
282 for (i = 0; i < spline->tot_point; i++) {
283 MaskSplinePoint *point = &spline->points[i];
284
285 if (MASKPOINT_ISSEL_ANY(point)) {
286 if (MASKPOINT_ISSEL_KNOT(point)) {
287 countsel += 3;
288 }
289 else {
291 countsel += 1;
292 }
293 else {
294 BezTriple *bezt = &point->bezt;
295 if (bezt->f1 & SELECT) {
296 countsel++;
297 }
298 if (bezt->f3 & SELECT) {
299 countsel++;
300 }
301 }
302 }
303 }
304
305 if (is_prop_edit) {
306 count += 3;
307 }
308 }
309 }
310 }
311
312 /* NOTE: in prop mode we need at least 1 selected. */
313 if (countsel == 0) {
314 return;
315 }
316
317 ED_mask_get_aspect(t->area, t->region, &asp[0], &asp[1]);
318
319 tc->data_len = (is_prop_edit) ? count : countsel;
320 td = tc->data = MEM_calloc_arrayN<TransData>(tc->data_len, "TransObData(Mask Editing)");
321 /* For each 2d uv coord a 3d vector is allocated, so that they can be
322 * treated just as if they were 3d verts. */
323 td2d = tc->data_2d = MEM_calloc_arrayN<TransData2D>(tc->data_len, "TransObData2D(Mask Editing)");
325 tc->data_len, "TransDataMasking(Mask Editing)");
326 tc->custom.type.use_free = true;
327
328 /* Create data. */
329 LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
330 if (masklay->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) {
331 continue;
332 }
333
334 LISTBASE_FOREACH (MaskSpline *, spline, &masklay->splines) {
335 int i;
336
337 for (i = 0; i < spline->tot_point; i++) {
338 MaskSplinePoint *point = &spline->points[i];
339
340 if (is_prop_edit || MASKPOINT_ISSEL_ANY(point)) {
341 MaskPointToTransData(scene, point, td, td2d, tdm, is_prop_edit, asp);
342
343 if (is_prop_edit || MASKPOINT_ISSEL_KNOT(point)) {
344 td += 3;
345 td2d += 3;
346 tdm += 3;
347 }
348 else {
350 td++;
351 td2d++;
352 tdm++;
353 }
354 else {
355 BezTriple *bezt = &point->bezt;
356 if (bezt->f1 & SELECT) {
357 td++;
358 td2d++;
359 tdm++;
360 }
361 if (bezt->f3 & SELECT) {
362 td++;
363 td2d++;
364 tdm++;
365 }
366 }
367 }
368 }
369 }
370 }
371 }
372}
373
375
376/* -------------------------------------------------------------------- */
379
381{
382 TransData2D *td;
383 TransDataMasking *tdm;
384 int a;
385 float asp[2], inv[2];
386
388
389 ED_mask_get_aspect(t->area, t->region, &asp[0], &asp[1]);
390 inv[0] = 1.0f / asp[0];
391 inv[1] = 1.0f / asp[1];
392
393 /* Flush to 2d vector from internally used 3d vector. */
394 for (a = 0, td = tc->data_2d, tdm = static_cast<TransDataMasking *>(tc->custom.type.data);
395 a < tc->data_len;
396 a++, td++, tdm++)
397 {
398 td->loc2d[0] = td->loc[0] * inv[0];
399 td->loc2d[1] = td->loc[1] * inv[1];
401
402 if (tdm->is_handle) {
404 tdm->which_handle,
405 td->loc2d,
406 (t->flag & T_ALT_TRANSFORM) != 0,
407 tdm->orig_handle,
408 tdm->vec);
409 }
410
411 if (t->state == TRANS_CANCEL) {
413 tdm->point->bezt.h1 = tdm->orig_handle_type;
414 }
415 else if (tdm->which_handle == MASK_WHICH_HANDLE_RIGHT) {
416 tdm->point->bezt.h2 = tdm->orig_handle_type;
417 }
418 }
419 }
420}
421
423{
425
427
428 DEG_id_tag_update(&mask->id, 0);
429}
430
432
433/* -------------------------------------------------------------------- */
436
438{
439 Mask *mask = nullptr;
440
441 if (t->spacetype == SPACE_CLIP) {
442 SpaceClip *sc = static_cast<SpaceClip *>(t->area->spacedata.first);
444 }
445 else if (t->spacetype == SPACE_IMAGE) {
446 SpaceImage *sima = static_cast<SpaceImage *>(t->area->spacedata.first);
448 }
449 else {
450 BLI_assert(0);
451 }
452
453 if (t->scene->nodetree) {
455 }
456
457 /* TODO: don't key all masks. */
459 Scene *scene = t->scene;
460
463 DEG_id_tag_update(&mask->id, 0);
464 }
465 }
466}
467
469
471 /*flags*/ (T_POINTS | T_2D_EDIT),
472 /*create_trans_data*/ createTransMaskingData,
473 /*recalc_data*/ recalcData_mask_common,
474 /*special_aftertrans_update*/ special_aftertrans_update__mask,
475};
476
477} // namespace blender::ed::transform
Functions to insert, delete or modify keyframes.
Mask * CTX_data_edit_mask(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
@ MASK_HANDLE_MODE_STICK
Definition BKE_mask.h:37
#define MASKPOINT_ISSEL_ANY(p)
Definition BKE_mask.h:292
eMaskWhichHandle
Definition BKE_mask.h:28
@ MASK_WHICH_HANDLE_RIGHT
Definition BKE_mask.h:32
@ MASK_WHICH_HANDLE_LEFT
Definition BKE_mask.h:31
@ MASK_WHICH_HANDLE_STICK
Definition BKE_mask.h:30
#define MASKPOINT_ISSEL_KNOT(p)
Definition BKE_mask.h:293
void BKE_mask_point_set_handle(struct MaskSplinePoint *point, eMaskWhichHandle which_handle, float loc[2], bool keep_direction, float orig_handle[2], float orig_vec[3][3])
void BKE_mask_point_handle(const struct MaskSplinePoint *point, eMaskWhichHandle which_handle, float r_handle[2])
void BKE_mask_point_parent_matrix_get(struct MaskSplinePoint *point, float ctime, float parent_matrix[3][3])
eMaskhandleMode BKE_mask_point_handles_mode_get(const struct MaskSplinePoint *point)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
void copy_m3_m3(float m1[3][3], const float m2[3][3])
void unit_m3(float m[3][3])
void mul_m3_v2(const float m[3][3], float r[2])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void mul_v2_m3v2(float r[2], const float m[3][3], const float v[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])
void DEG_id_tag_update(ID *id, unsigned int flags)
@ HD_VECT
@ HD_FREE
@ HD_AUTO
@ HD_ALIGN_DOUBLESIDE
@ MASK_HIDE_SELECT
@ MASK_HIDE_VIEW
@ SPACE_CLIP
@ SPACE_IMAGE
Mask * ED_space_clip_get_mask(const SpaceClip *sc)
Mask * ED_space_image_get_mask(const SpaceImage *sima)
void ED_mask_get_aspect(ScrArea *area, ARegion *region, float *r_aspx, float *r_aspy)
bool ED_mask_layer_shape_auto_key_select(Mask *mask, int frame)
bool ED_maskedit_mask_visible_splines_poll(bContext *C)
Definition mask_edit.cc:76
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
#define ND_DATA
Definition WM_types.hh:506
#define NC_MASK
Definition WM_types.hh:395
#define SELECT
int count
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
bool is_autokey_on(const Scene *scene)
TransConvertTypeInfo TransConvertType_Mask
static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point, TransData *td, TransData2D *td2d, TransDataMasking *tdm, const bool is_prop_edit, const float asp[2])
static void MaskHandleToTransData(MaskSplinePoint *point, eMaskWhichHandle which_handle, TransData *td, TransData2D *td2d, TransDataMasking *tdm, const float asp[2], const float parent_matrix[3][3], const float parent_inverse_matrix[3][3])
static void flushTransMasking(TransInfo *t)
static void createTransMaskingData(bContext *C, TransInfo *t)
static void special_aftertrans_update__mask(bContext *C, TransInfo *t)
static void recalcData_mask_common(TransInfo *t)
float vec[3][3]
void * first
struct bNodeTree * nodetree
struct RenderData r
ListBase spacedata
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.
void WM_event_add_notifier(const bContext *C, uint type, void *reference)