Blender V5.0
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->val = nullptr;
94
95 if (is_sel_any) {
96 td->flag |= TD_SELECTED;
97 }
98
99 td->dist = 0.0;
100
101 unit_m3(td->mtx);
102 unit_m3(td->smtx);
103
104 if (which_handle == MASK_WHICH_HANDLE_LEFT) {
105 tdm->orig_handle_type = bezt->h1;
106 }
107 else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
108 tdm->orig_handle_type = bezt->h2;
109 }
110}
111
112static void MaskPointToTransData(Scene *scene,
113 MaskSplinePoint *point,
114 TransData *td,
115 TransData2D *td2d,
116 TransDataMasking *tdm,
117 const bool is_prop_edit,
118 const float asp[2])
119{
120 BezTriple *bezt = &point->bezt;
121 const bool is_sel_point = MASKPOINT_ISSEL_KNOT(point);
122 const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
123 float parent_matrix[3][3], parent_inverse_matrix[3][3];
124
125 BKE_mask_point_parent_matrix_get(point, scene->r.cfra, parent_matrix);
126 invert_m3_m3(parent_inverse_matrix, parent_matrix);
127
128 if (is_prop_edit || is_sel_point) {
129
130 tdm->point = point;
131 copy_m3_m3(tdm->vec, bezt->vec);
132
133 for (int i = 0; i < 3; i++) {
134 copy_m3_m3(tdm->parent_matrix, parent_matrix);
135 copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
136
137 /* CV coords are scaled by aspects. this is needed for rotations and
138 * proportional editing to be consistent with the stretched CV coords
139 * that are displayed. this also means that for display and number-input,
140 * and when the CV coords are flushed, these are converted each time. */
141 mul_v2_m3v2(td2d->loc, parent_matrix, bezt->vec[i]);
142 td2d->loc[0] *= asp[0];
143 td2d->loc[1] *= asp[1];
144 td2d->loc[2] = 0.0f;
145
146 td2d->loc2d = bezt->vec[i];
147
148 td->flag = 0;
149 td->loc = td2d->loc;
150 mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
151 td->center[0] *= asp[0];
152 td->center[1] *= asp[1];
153 copy_v3_v3(td->iloc, td->loc);
154
155 memset(td->axismtx, 0, sizeof(td->axismtx));
156 td->axismtx[2][2] = 1.0f;
157
158 if (i == 1) {
159 /* Scaling weights. */
160 td->val = &bezt->weight;
161 td->ival = *td->val;
162 }
163 else {
164 td->val = nullptr;
165 }
166
167 if (is_sel_any) {
168 td->flag |= TD_SELECTED;
169 }
170 td->dist = 0.0;
171
172 unit_m3(td->mtx);
173 unit_m3(td->smtx);
174
175 if (i == 0) {
176 tdm->orig_handle_type = bezt->h1;
177 }
178 else if (i == 2) {
179 tdm->orig_handle_type = bezt->h2;
180 }
181
182 td++;
183 td2d++;
184 tdm++;
185 }
186 }
187 else {
191 td,
192 td2d,
193 tdm,
194 asp,
195 parent_matrix,
196 parent_inverse_matrix);
197
198 td++;
199 td2d++;
200 tdm++;
201 }
202 else {
203 if (bezt->f1 & SELECT) {
206 td,
207 td2d,
208 tdm,
209 asp,
210 parent_matrix,
211 parent_inverse_matrix);
212
213 if (bezt->h1 == HD_VECT) {
214 bezt->h1 = HD_FREE;
215 }
216 else if (bezt->h1 == HD_AUTO) {
217 bezt->h1 = HD_ALIGN_DOUBLESIDE;
218 bezt->h2 = HD_ALIGN_DOUBLESIDE;
219 }
220
221 td++;
222 td2d++;
223 tdm++;
224 }
225 if (bezt->f3 & SELECT) {
228 td,
229 td2d,
230 tdm,
231 asp,
232 parent_matrix,
233 parent_inverse_matrix);
234
235 if (bezt->h2 == HD_VECT) {
236 bezt->h2 = HD_FREE;
237 }
238 else if (bezt->h2 == HD_AUTO) {
239 bezt->h1 = HD_ALIGN_DOUBLESIDE;
240 bezt->h2 = HD_ALIGN_DOUBLESIDE;
241 }
242
243 td++;
244 td2d++;
245 tdm++;
246 }
247 }
248 }
249}
250
252{
253 Scene *scene = CTX_data_scene(C);
255 TransData *td = nullptr;
256 TransData2D *td2d = nullptr;
257 TransDataMasking *tdm = nullptr;
258 int count = 0, countsel = 0;
259 const bool is_prop_edit = (t->flag & T_PROP_EDIT);
260 float asp[2];
261
263
264 tc->data_len = 0;
265
267 return;
268 }
269
270 /* Count. */
271 LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
272 if (masklay->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) {
273 continue;
274 }
275
276 LISTBASE_FOREACH (MaskSpline *, spline, &masklay->splines) {
277 int i;
278
279 for (i = 0; i < spline->tot_point; i++) {
280 MaskSplinePoint *point = &spline->points[i];
281
282 if (MASKPOINT_ISSEL_ANY(point)) {
283 if (MASKPOINT_ISSEL_KNOT(point)) {
284 countsel += 3;
285 }
286 else {
288 countsel += 1;
289 }
290 else {
291 BezTriple *bezt = &point->bezt;
292 if (bezt->f1 & SELECT) {
293 countsel++;
294 }
295 if (bezt->f3 & SELECT) {
296 countsel++;
297 }
298 }
299 }
300 }
301
302 if (is_prop_edit) {
303 count += 3;
304 }
305 }
306 }
307 }
308
309 /* NOTE: in prop mode we need at least 1 selected. */
310 if (countsel == 0) {
311 return;
312 }
313
314 ED_mask_get_aspect(t->area, t->region, &asp[0], &asp[1]);
315
316 tc->data_len = (is_prop_edit) ? count : countsel;
317 td = tc->data = MEM_calloc_arrayN<TransData>(tc->data_len, "TransObData(Mask Editing)");
318 /* For each 2d uv coord a 3d vector is allocated, so that they can be
319 * treated just as if they were 3d verts. */
320 td2d = tc->data_2d = MEM_calloc_arrayN<TransData2D>(tc->data_len, "TransObData2D(Mask Editing)");
322 tc->data_len, "TransDataMasking(Mask Editing)");
323 tc->custom.type.use_free = true;
324
325 /* Create data. */
326 LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
327 if (masklay->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) {
328 continue;
329 }
330
331 LISTBASE_FOREACH (MaskSpline *, spline, &masklay->splines) {
332 int i;
333
334 for (i = 0; i < spline->tot_point; i++) {
335 MaskSplinePoint *point = &spline->points[i];
336
337 if (is_prop_edit || MASKPOINT_ISSEL_ANY(point)) {
338 MaskPointToTransData(scene, point, td, td2d, tdm, is_prop_edit, asp);
339
340 if (is_prop_edit || MASKPOINT_ISSEL_KNOT(point)) {
341 td += 3;
342 td2d += 3;
343 tdm += 3;
344 }
345 else {
347 td++;
348 td2d++;
349 tdm++;
350 }
351 else {
352 BezTriple *bezt = &point->bezt;
353 if (bezt->f1 & SELECT) {
354 td++;
355 td2d++;
356 tdm++;
357 }
358 if (bezt->f3 & SELECT) {
359 td++;
360 td2d++;
361 tdm++;
362 }
363 }
364 }
365 }
366 }
367 }
368 }
369}
370
372
373/* -------------------------------------------------------------------- */
376
378{
379 TransData2D *td;
380 TransDataMasking *tdm;
381 int a;
382 float asp[2], inv[2];
383
385
386 ED_mask_get_aspect(t->area, t->region, &asp[0], &asp[1]);
387 inv[0] = 1.0f / asp[0];
388 inv[1] = 1.0f / asp[1];
389
390 /* Flush to 2d vector from internally used 3d vector. */
391 for (a = 0, td = tc->data_2d, tdm = static_cast<TransDataMasking *>(tc->custom.type.data);
392 a < tc->data_len;
393 a++, td++, tdm++)
394 {
395 td->loc2d[0] = td->loc[0] * inv[0];
396 td->loc2d[1] = td->loc[1] * inv[1];
398
399 if (tdm->is_handle) {
401 tdm->which_handle,
402 td->loc2d,
403 (t->flag & T_ALT_TRANSFORM) != 0,
404 tdm->orig_handle,
405 tdm->vec);
406 }
407
408 if (t->state == TRANS_CANCEL) {
410 tdm->point->bezt.h1 = tdm->orig_handle_type;
411 }
412 else if (tdm->which_handle == MASK_WHICH_HANDLE_RIGHT) {
413 tdm->point->bezt.h2 = tdm->orig_handle_type;
414 }
415 }
416 }
417}
418
420{
422
424
425 DEG_id_tag_update(&mask->id, 0);
426}
427
429
430/* -------------------------------------------------------------------- */
433
435{
436 Mask *mask = nullptr;
437
438 if (t->spacetype == SPACE_CLIP) {
439 SpaceClip *sc = static_cast<SpaceClip *>(t->area->spacedata.first);
441 }
442 else if (t->spacetype == SPACE_IMAGE) {
443 SpaceImage *sima = static_cast<SpaceImage *>(t->area->spacedata.first);
445 }
446 else {
447 BLI_assert(0);
448 }
449
452 }
453
454 /* TODO: don't key all masks. */
456 Scene *scene = t->scene;
457
460 DEG_id_tag_update(&mask->id, 0);
461 }
462 }
463}
464
466
468 /*flags*/ (T_POINTS | T_2D_EDIT),
469 /*create_trans_data*/ createTransMaskingData,
470 /*recalc_data*/ recalcData_mask_common,
471 /*special_aftertrans_update*/ special_aftertrans_update__mask,
472};
473
474} // 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:509
#define NC_MASK
Definition WM_types.hh:398
#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 * compositing_node_group
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)