Blender V4.3
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
9#include "DNA_mask_types.h"
10#include "DNA_space_types.h"
11
12#include "MEM_guardedalloc.h"
13
14#include "BLI_math_matrix.h"
15#include "BLI_math_vector.h"
16
17#include "BKE_context.hh"
18#include "BKE_mask.h"
19
20#include "ED_clip.hh"
21#include "ED_image.hh"
22#include "ED_mask.hh"
23
24#include "ANIM_keyframing.hh"
25
26#include "WM_api.hh"
27#include "WM_types.hh"
28
29#include "transform.hh"
30#include "transform_convert.hh"
31
44
45/* -------------------------------------------------------------------- */
50 eMaskWhichHandle which_handle,
51 TransData *td,
52 TransData2D *td2d,
54 const float asp[2],
55 /*const*/ const float parent_matrix[3][3],
56 /*const*/ const float parent_inverse_matrix[3][3])
57{
58 BezTriple *bezt = &point->bezt;
59 const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
60
61 tdm->point = point;
62 copy_m3_m3(tdm->vec, bezt->vec);
63
64 tdm->is_handle = true;
65 copy_m3_m3(tdm->parent_matrix, parent_matrix);
66 copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
67
68 BKE_mask_point_handle(point, which_handle, tdm->handle);
69 tdm->which_handle = which_handle;
70
71 copy_v2_v2(tdm->orig_handle, tdm->handle);
72
73 mul_v2_m3v2(td2d->loc, parent_matrix, tdm->handle);
74 td2d->loc[0] *= asp[0];
75 td2d->loc[1] *= asp[1];
76 td2d->loc[2] = 0.0f;
77
78 td2d->loc2d = tdm->handle;
79
80 td->flag = 0;
81 td->loc = td2d->loc;
82 mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
83 td->center[0] *= asp[0];
84 td->center[1] *= asp[1];
85 copy_v3_v3(td->iloc, td->loc);
86
87 memset(td->axismtx, 0, sizeof(td->axismtx));
88 td->axismtx[2][2] = 1.0f;
89
90 td->ext = nullptr;
91 td->val = nullptr;
92
93 if (is_sel_any) {
94 td->flag |= TD_SELECTED;
95 }
96
97 td->dist = 0.0;
98
99 unit_m3(td->mtx);
100 unit_m3(td->smtx);
101
102 if (which_handle == MASK_WHICH_HANDLE_LEFT) {
103 tdm->orig_handle_type = bezt->h1;
104 }
105 else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
106 tdm->orig_handle_type = bezt->h2;
107 }
108}
109
110static void MaskPointToTransData(Scene *scene,
111 MaskSplinePoint *point,
112 TransData *td,
113 TransData2D *td2d,
114 TransDataMasking *tdm,
115 const bool is_prop_edit,
116 const float asp[2])
117{
118 BezTriple *bezt = &point->bezt;
119 const bool is_sel_point = MASKPOINT_ISSEL_KNOT(point);
120 const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
121 float parent_matrix[3][3], parent_inverse_matrix[3][3];
122
123 BKE_mask_point_parent_matrix_get(point, scene->r.cfra, parent_matrix);
124 invert_m3_m3(parent_inverse_matrix, parent_matrix);
125
126 if (is_prop_edit || is_sel_point) {
127
128 tdm->point = point;
129 copy_m3_m3(tdm->vec, bezt->vec);
130
131 for (int i = 0; i < 3; i++) {
132 copy_m3_m3(tdm->parent_matrix, parent_matrix);
133 copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
134
135 /* CV coords are scaled by aspects. this is needed for rotations and
136 * proportional editing to be consistent with the stretched CV coords
137 * that are displayed. this also means that for display and number-input,
138 * and when the CV coords are flushed, these are converted each time. */
139 mul_v2_m3v2(td2d->loc, parent_matrix, bezt->vec[i]);
140 td2d->loc[0] *= asp[0];
141 td2d->loc[1] *= asp[1];
142 td2d->loc[2] = 0.0f;
143
144 td2d->loc2d = bezt->vec[i];
145
146 td->flag = 0;
147 td->loc = td2d->loc;
148 mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
149 td->center[0] *= asp[0];
150 td->center[1] *= asp[1];
151 copy_v3_v3(td->iloc, td->loc);
152
153 memset(td->axismtx, 0, sizeof(td->axismtx));
154 td->axismtx[2][2] = 1.0f;
155
156 td->ext = nullptr;
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);
254 Mask *mask = CTX_data_edit_mask(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 = static_cast<TransData *>(
318 MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mask Editing)"));
319 /* For each 2d uv coord a 3d vector is allocated, so that they can be
320 * treated just as if they were 3d verts. */
321 td2d = tc->data_2d = static_cast<TransData2D *>(
322 MEM_callocN(tc->data_len * sizeof(TransData2D), "TransObData2D(Mask Editing)"));
323 tc->custom.type.data = tdm = static_cast<TransDataMasking *>(
324 MEM_callocN(tc->data_len * sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"));
325 tc->custom.type.use_free = true;
326
327 /* Create data. */
328 LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
329 if (masklay->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) {
330 continue;
331 }
332
333 LISTBASE_FOREACH (MaskSpline *, spline, &masklay->splines) {
334 int i;
335
336 for (i = 0; i < spline->tot_point; i++) {
337 MaskSplinePoint *point = &spline->points[i];
338
339 if (is_prop_edit || MASKPOINT_ISSEL_ANY(point)) {
340 MaskPointToTransData(scene, point, td, td2d, tdm, is_prop_edit, asp);
341
342 if (is_prop_edit || MASKPOINT_ISSEL_KNOT(point)) {
343 td += 3;
344 td2d += 3;
345 tdm += 3;
346 }
347 else {
349 td++;
350 td2d++;
351 tdm++;
352 }
353 else {
354 BezTriple *bezt = &point->bezt;
355 if (bezt->f1 & SELECT) {
356 td++;
357 td2d++;
358 tdm++;
359 }
360 if (bezt->f3 & SELECT) {
361 td++;
362 td2d++;
363 tdm++;
364 }
365 }
366 }
367 }
368 }
369 }
370 }
371}
372
375/* -------------------------------------------------------------------- */
380{
381 TransData2D *td;
382 TransDataMasking *tdm;
383 int a;
384 float asp[2], inv[2];
385
387
388 ED_mask_get_aspect(t->area, t->region, &asp[0], &asp[1]);
389 inv[0] = 1.0f / asp[0];
390 inv[1] = 1.0f / asp[1];
391
392 /* Flush to 2d vector from internally used 3d vector. */
393 for (a = 0, td = tc->data_2d, tdm = static_cast<TransDataMasking *>(tc->custom.type.data);
394 a < tc->data_len;
395 a++, td++, tdm++)
396 {
397 td->loc2d[0] = td->loc[0] * inv[0];
398 td->loc2d[1] = td->loc[1] * inv[1];
400
401 if (tdm->is_handle) {
403 tdm->which_handle,
404 td->loc2d,
405 (t->flag & T_ALT_TRANSFORM) != 0,
406 tdm->orig_handle,
407 tdm->vec);
408 }
409
410 if (t->state == TRANS_CANCEL) {
412 tdm->point->bezt.h1 = tdm->orig_handle_type;
413 }
414 else if (tdm->which_handle == MASK_WHICH_HANDLE_RIGHT) {
415 tdm->point->bezt.h2 = tdm->orig_handle_type;
416 }
417 }
418 }
419}
420
422{
423 Mask *mask = CTX_data_edit_mask(t->context);
424
426
427 DEG_id_tag_update(&mask->id, 0);
428}
429
432/* -------------------------------------------------------------------- */
437{
438 Mask *mask = nullptr;
439
440 if (t->spacetype == SPACE_CLIP) {
441 SpaceClip *sc = static_cast<SpaceClip *>(t->area->spacedata.first);
442 mask = ED_space_clip_get_mask(sc);
443 }
444 else if (t->spacetype == SPACE_IMAGE) {
445 SpaceImage *sima = static_cast<SpaceImage *>(t->area->spacedata.first);
446 mask = ED_space_image_get_mask(sima);
447 }
448 else {
449 BLI_assert(0);
450 }
451
452 if (t->scene->nodetree) {
453 WM_event_add_notifier(C, NC_MASK | ND_DATA, &mask->id);
454 }
455
456 /* TODO: don't key all masks. */
458 Scene *scene = t->scene;
459
460 if (ED_mask_layer_shape_auto_key_select(mask, scene->r.cfra)) {
461 WM_event_add_notifier(C, NC_MASK | ND_DATA, &mask->id);
462 DEG_id_tag_update(&mask->id, 0);
463 }
464 }
465}
466
470 /*flags*/ (T_POINTS | T_2D_EDIT),
471 /*create_trans_data*/ createTransMaskingData,
472 /*recalc_data*/ recalcData_mask_common,
473 /*special_aftertrans_update*/ special_aftertrans_update__mask,
474};
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:41
#define MASKPOINT_ISSEL_ANY(p)
Definition BKE_mask.h:297
eMaskWhichHandle
Definition BKE_mask.h:32
@ MASK_WHICH_HANDLE_RIGHT
Definition BKE_mask.h:36
@ MASK_WHICH_HANDLE_LEFT
Definition BKE_mask.h:35
@ MASK_WHICH_HANDLE_STICK
Definition BKE_mask.h:34
#define MASKPOINT_ISSEL_KNOT(p)
Definition BKE_mask.h:298
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:50
#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:78
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
#define ND_DATA
Definition WM_types.hh:475
#define NC_MASK
Definition WM_types.hh:365
#define SELECT
int count
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
bool is_autokey_on(const Scene *scene)
float vec[3][3]
void * first
struct bNodeTree * nodetree
ListBase spacedata
TransCustomData type
Definition transform.hh:425
unsigned int use_free
Definition transform.hh:410
TransCustomDataContainer custom
Definition transform.hh:501
TransData * data
Definition transform.hh:445
TransData2D * data_2d
Definition transform.hh:449
eMaskWhichHandle which_handle
MaskSplinePoint * point
float smtx[3][3]
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
char spacetype
Definition transform.hh:582
eTState state
Definition transform.hh:527
Scene * scene
Definition transform.hh:654
eTFlag flag
Definition transform.hh:523
ARegion * region
Definition transform.hh:652
bContext * context
Definition transform.hh:649
ScrArea * area
Definition transform.hh:651
@ T_ALT_TRANSFORM
Definition transform.hh:126
@ T_PROP_EDIT
Definition transform.hh:98
@ 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
conversion and adaptation of different datablocks to a common struct.
static void special_aftertrans_update__mask(bContext *C, TransInfo *t)
TransConvertTypeInfo TransConvertType_Mask
static void recalcData_mask_common(TransInfo *t)
static void flushTransMasking(TransInfo *t)
static void createTransMaskingData(bContext *C, TransInfo *t)
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])
@ TD_SELECTED
void WM_event_add_notifier(const bContext *C, uint type, void *reference)