Blender  V3.3
transform_convert_mask.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include "DNA_mask_types.h"
9 #include "DNA_space_types.h"
10 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_math.h"
14 
15 #include "BKE_context.h"
16 #include "BKE_mask.h"
17 
18 #include "ED_clip.h"
19 #include "ED_image.h"
20 #include "ED_keyframing.h"
21 #include "ED_mask.h"
22 
23 #include "WM_api.h"
24 #include "WM_types.h"
25 
26 #include "transform.h"
27 #include "transform_convert.h"
28 
29 typedef struct TransDataMasking {
30  bool is_handle;
31 
32  float handle[2], orig_handle[2];
33  float vec[3][3];
35  float parent_matrix[3][3];
36  float parent_inverse_matrix[3][3];
38 
41 
42 /* -------------------------------------------------------------------- */
47  eMaskWhichHandle which_handle,
48  TransData *td,
49  TransData2D *td2d,
50  TransDataMasking *tdm,
51  const float asp[2],
52  /*const*/ const float parent_matrix[3][3],
53  /*const*/ const float parent_inverse_matrix[3][3])
54 {
55  BezTriple *bezt = &point->bezt;
56  const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
57 
58  tdm->point = point;
59  copy_m3_m3(tdm->vec, bezt->vec);
60 
61  tdm->is_handle = true;
62  copy_m3_m3(tdm->parent_matrix, parent_matrix);
63  copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
64 
65  BKE_mask_point_handle(point, which_handle, tdm->handle);
66  tdm->which_handle = which_handle;
67 
68  copy_v2_v2(tdm->orig_handle, tdm->handle);
69 
70  mul_v2_m3v2(td2d->loc, parent_matrix, tdm->handle);
71  td2d->loc[0] *= asp[0];
72  td2d->loc[1] *= asp[1];
73  td2d->loc[2] = 0.0f;
74 
75  td2d->loc2d = tdm->handle;
76 
77  td->flag = 0;
78  td->loc = td2d->loc;
79  mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
80  td->center[0] *= asp[0];
81  td->center[1] *= asp[1];
82  copy_v3_v3(td->iloc, td->loc);
83 
84  memset(td->axismtx, 0, sizeof(td->axismtx));
85  td->axismtx[2][2] = 1.0f;
86 
87  td->ext = NULL;
88  td->val = NULL;
89 
90  if (is_sel_any) {
91  td->flag |= TD_SELECTED;
92  }
93 
94  td->dist = 0.0;
95 
96  unit_m3(td->mtx);
97  unit_m3(td->smtx);
98 
99  if (which_handle == MASK_WHICH_HANDLE_LEFT) {
100  tdm->orig_handle_type = bezt->h1;
101  }
102  else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
103  tdm->orig_handle_type = bezt->h2;
104  }
105 }
106 
109  TransData *td,
110  TransData2D *td2d,
111  TransDataMasking *tdm,
112  const bool is_prop_edit,
113  const float asp[2])
114 {
115  BezTriple *bezt = &point->bezt;
116  const bool is_sel_point = MASKPOINT_ISSEL_KNOT(point);
117  const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
118  float parent_matrix[3][3], parent_inverse_matrix[3][3];
119 
121  invert_m3_m3(parent_inverse_matrix, parent_matrix);
122 
123  if (is_prop_edit || is_sel_point) {
124 
125  tdm->point = point;
126  copy_m3_m3(tdm->vec, bezt->vec);
127 
128  for (int i = 0; i < 3; i++) {
129  copy_m3_m3(tdm->parent_matrix, parent_matrix);
130  copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
131 
132  /* CV coords are scaled by aspects. this is needed for rotations and
133  * proportional editing to be consistent with the stretched CV coords
134  * that are displayed. this also means that for display and number-input,
135  * and when the CV coords are flushed, these are converted each time */
136  mul_v2_m3v2(td2d->loc, parent_matrix, bezt->vec[i]);
137  td2d->loc[0] *= asp[0];
138  td2d->loc[1] *= asp[1];
139  td2d->loc[2] = 0.0f;
140 
141  td2d->loc2d = bezt->vec[i];
142 
143  td->flag = 0;
144  td->loc = td2d->loc;
145  mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
146  td->center[0] *= asp[0];
147  td->center[1] *= asp[1];
148  copy_v3_v3(td->iloc, td->loc);
149 
150  memset(td->axismtx, 0, sizeof(td->axismtx));
151  td->axismtx[2][2] = 1.0f;
152 
153  td->ext = NULL;
154 
155  if (i == 1) {
156  /* scaling weights */
157  td->val = &bezt->weight;
158  td->ival = *td->val;
159  }
160  else {
161  td->val = NULL;
162  }
163 
164  if (is_sel_any) {
165  td->flag |= TD_SELECTED;
166  }
167  td->dist = 0.0;
168 
169  unit_m3(td->mtx);
170  unit_m3(td->smtx);
171 
172  if (i == 0) {
173  tdm->orig_handle_type = bezt->h1;
174  }
175  else if (i == 2) {
176  tdm->orig_handle_type = bezt->h2;
177  }
178 
179  td++;
180  td2d++;
181  tdm++;
182  }
183  }
184  else {
188  td,
189  td2d,
190  tdm,
191  asp,
192  parent_matrix,
193  parent_inverse_matrix);
194 
195  td++;
196  td2d++;
197  tdm++;
198  }
199  else {
200  if (bezt->f1 & SELECT) {
203  td,
204  td2d,
205  tdm,
206  asp,
207  parent_matrix,
208  parent_inverse_matrix);
209 
210  if (bezt->h1 == HD_VECT) {
211  bezt->h1 = HD_FREE;
212  }
213  else if (bezt->h1 == HD_AUTO) {
216  }
217 
218  td++;
219  td2d++;
220  tdm++;
221  }
222  if (bezt->f3 & SELECT) {
225  td,
226  td2d,
227  tdm,
228  asp,
229  parent_matrix,
230  parent_inverse_matrix);
231 
232  if (bezt->h2 == HD_VECT) {
233  bezt->h2 = HD_FREE;
234  }
235  else if (bezt->h2 == HD_AUTO) {
238  }
239 
240  td++;
241  td2d++;
242  tdm++;
243  }
244  }
245  }
246 }
247 
249 {
252  MaskLayer *masklay;
253  TransData *td = NULL;
254  TransData2D *td2d = NULL;
255  TransDataMasking *tdm = NULL;
256  int count = 0, countsel = 0;
257  const bool is_prop_edit = (t->flag & T_PROP_EDIT);
258  float asp[2];
259 
261 
262  tc->data_len = 0;
263 
265  return;
266  }
267 
268  /* count */
269  for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
270  MaskSpline *spline;
271 
272  if (masklay->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) {
273  continue;
274  }
275 
276  for (spline = masklay->splines.first; spline; spline = spline->next) {
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)) {
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_callocN(tc->data_len * sizeof(TransData), "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_callocN(tc->data_len * sizeof(TransData2D),
321  "TransObData2D(Mask Editing)");
322  tc->custom.type.data = tdm = MEM_callocN(tc->data_len * sizeof(TransDataMasking),
323  "TransDataMasking(Mask Editing)");
324  tc->custom.type.use_free = true;
325 
326  /* create data */
327  for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
328  MaskSpline *spline;
329 
330  if (masklay->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) {
331  continue;
332  }
333 
334  for (spline = masklay->splines.first; spline; spline = spline->next) {
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 
376 /* -------------------------------------------------------------------- */
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 = tc->custom.type.data; a < tc->data_len; a++, td++, tdm++) {
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) {
409  if (tdm->which_handle == MASK_WHICH_HANDLE_LEFT) {
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 {
421  Mask *mask = CTX_data_edit_mask(t->context);
422 
424 
425  DEG_id_tag_update(&mask->id, 0);
426 }
427 
430 /* -------------------------------------------------------------------- */
435 {
436  Mask *mask = NULL;
437 
438  if (t->spacetype == SPACE_CLIP) {
439  SpaceClip *sc = t->area->spacedata.first;
441  }
442  else if (t->spacetype == SPACE_IMAGE) {
443  SpaceImage *sima = t->area->spacedata.first;
445  }
446  else {
447  BLI_assert(0);
448  }
449 
450  if (t->scene->nodetree) {
452  }
453 
454  /* TODO: don't key all masks. */
455  if (IS_AUTOKEY_ON(t->scene)) {
456  Scene *scene = t->scene;
457 
460  DEG_id_tag_update(&mask->id, 0);
461  }
462  }
463 }
464 
468  /* flags */ (T_POINTS | T_2D_EDIT),
469  /* createTransData */ createTransMaskingData,
470  /* recalcData */ recalcData_mask_common,
471  /* special_aftertrans_update */ special_aftertrans_update__mask,
472 };
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct Mask * CTX_data_edit_mask(const bContext *C)
Definition: context.c:1390
@ MASK_HANDLE_MODE_STICK
Definition: BKE_mask.h:40
#define MASKPOINT_ISSEL_ANY(p)
Definition: BKE_mask.h:296
eMaskWhichHandle
Definition: BKE_mask.h:31
@ MASK_WHICH_HANDLE_RIGHT
Definition: BKE_mask.h:35
@ MASK_WHICH_HANDLE_LEFT
Definition: BKE_mask.h:34
@ MASK_WHICH_HANDLE_STICK
Definition: BKE_mask.h:33
#define MASKPOINT_ISSEL_KNOT(p)
Definition: BKE_mask.h:297
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])
Definition: mask.c:699
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])
Definition: mask.c:1277
eMaskhandleMode BKE_mask_point_handles_mode_get(const struct MaskSplinePoint *point)
#define BLI_assert(a)
Definition: BLI_assert.h:46
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:71
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void mul_m3_v2(const float m[3][3], float r[2])
Definition: math_matrix.c:724
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1180
void mul_v2_m3v2(float r[2], const float m[3][3], const float v[2])
Definition: math_matrix.c:711
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(struct ID *id, int flag)
@ HD_VECT
@ HD_FREE
@ HD_AUTO
@ HD_ALIGN_DOUBLESIDE
#define MASK_HIDE_SELECT
#define MASK_HIDE_VIEW
@ SPACE_CLIP
@ SPACE_IMAGE
struct Mask * ED_space_clip_get_mask(struct SpaceClip *sc)
Definition: clip_editor.c:631
struct Mask * ED_space_image_get_mask(const struct SpaceImage *sima)
#define IS_AUTOKEY_ON(scene)
void ED_mask_get_aspect(struct ScrArea *area, struct ARegion *region, float *aspx, float *aspy)
bool ED_maskedit_mask_visible_splines_poll(struct bContext *C)
Definition: mask_edit.c:77
bool ED_mask_layer_shape_auto_key_select(struct Mask *mask, int frame)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
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 Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise 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 C
Definition: RandGen.cpp:25
#define ND_DATA
Definition: WM_types.h:456
#define NC_MASK
Definition: WM_types.h:348
#define SELECT
Scene scene
int count
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static unsigned a[3]
Definition: RandGen.cpp:78
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
uint8_t h1
uint8_t f3
float vec[3][3]
uint8_t f1
uint8_t h2
void * first
Definition: DNA_listBase.h:31
struct MaskLayer * next
char visibility_flag
ListBase splines
struct MaskSpline * next
MaskSplinePoint * points
struct RenderData r
float * loc2d
float loc[3]
eMaskWhichHandle which_handle
struct MaskSplinePoint * point
float parent_inverse_matrix[3][3]
float smtx[3][3]
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
float * val
conversion and adaptation of different datablocks to a common struct.
static void special_aftertrans_update__mask(bContext *C, TransInfo *t)
struct TransDataMasking TransDataMasking
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)