Blender  V2.93
transform_convert_mask.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include "DNA_mask_types.h"
25 #include "DNA_space_types.h"
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "BLI_math.h"
30 
31 #include "BKE_context.h"
32 #include "BKE_mask.h"
33 
34 #include "ED_clip.h"
35 #include "ED_image.h"
36 #include "ED_keyframing.h"
37 #include "ED_mask.h"
38 
39 #include "WM_api.h"
40 #include "WM_types.h"
41 
42 #include "transform.h"
43 #include "transform_convert.h"
44 
45 typedef struct TransDataMasking {
46  bool is_handle;
47 
48  float handle[2], orig_handle[2];
49  float vec[3][3];
51  float parent_matrix[3][3];
52  float parent_inverse_matrix[3][3];
54 
57 
58 /* -------------------------------------------------------------------- */
63  eMaskWhichHandle which_handle,
64  TransData *td,
65  TransData2D *td2d,
66  TransDataMasking *tdm,
67  const float asp[2],
68  /*const*/ const float parent_matrix[3][3],
69  /*const*/ const float parent_inverse_matrix[3][3])
70 {
71  BezTriple *bezt = &point->bezt;
72  const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
73 
74  tdm->point = point;
75  copy_m3_m3(tdm->vec, bezt->vec);
76 
77  tdm->is_handle = true;
78  copy_m3_m3(tdm->parent_matrix, parent_matrix);
79  copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
80 
81  BKE_mask_point_handle(point, which_handle, tdm->handle);
82  tdm->which_handle = which_handle;
83 
84  copy_v2_v2(tdm->orig_handle, tdm->handle);
85 
86  mul_v2_m3v2(td2d->loc, parent_matrix, tdm->handle);
87  td2d->loc[0] *= asp[0];
88  td2d->loc[1] *= asp[1];
89  td2d->loc[2] = 0.0f;
90 
91  td2d->loc2d = tdm->handle;
92 
93  td->flag = 0;
94  td->loc = td2d->loc;
95  mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
96  td->center[0] *= asp[0];
97  td->center[1] *= asp[1];
98  copy_v3_v3(td->iloc, td->loc);
99 
100  memset(td->axismtx, 0, sizeof(td->axismtx));
101  td->axismtx[2][2] = 1.0f;
102 
103  td->ext = NULL;
104  td->val = NULL;
105 
106  if (is_sel_any) {
107  td->flag |= TD_SELECTED;
108  }
109 
110  td->dist = 0.0;
111 
112  unit_m3(td->mtx);
113  unit_m3(td->smtx);
114 
115  if (which_handle == MASK_WHICH_HANDLE_LEFT) {
116  tdm->orig_handle_type = bezt->h1;
117  }
118  else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
119  tdm->orig_handle_type = bezt->h2;
120  }
121 }
122 
124  MaskSplinePoint *point,
125  TransData *td,
126  TransData2D *td2d,
127  TransDataMasking *tdm,
128  const bool is_prop_edit,
129  const float asp[2])
130 {
131  BezTriple *bezt = &point->bezt;
132  const bool is_sel_point = MASKPOINT_ISSEL_KNOT(point);
133  const bool is_sel_any = MASKPOINT_ISSEL_ANY(point);
134  float parent_matrix[3][3], parent_inverse_matrix[3][3];
135 
136  BKE_mask_point_parent_matrix_get(point, CFRA, parent_matrix);
137  invert_m3_m3(parent_inverse_matrix, parent_matrix);
138 
139  if (is_prop_edit || is_sel_point) {
140 
141  tdm->point = point;
142  copy_m3_m3(tdm->vec, bezt->vec);
143 
144  for (int i = 0; i < 3; i++) {
145  copy_m3_m3(tdm->parent_matrix, parent_matrix);
146  copy_m3_m3(tdm->parent_inverse_matrix, parent_inverse_matrix);
147 
148  /* CV coords are scaled by aspects. this is needed for rotations and
149  * proportional editing to be consistent with the stretched CV coords
150  * that are displayed. this also means that for display and number-input,
151  * and when the CV coords are flushed, these are converted each time */
152  mul_v2_m3v2(td2d->loc, parent_matrix, bezt->vec[i]);
153  td2d->loc[0] *= asp[0];
154  td2d->loc[1] *= asp[1];
155  td2d->loc[2] = 0.0f;
156 
157  td2d->loc2d = bezt->vec[i];
158 
159  td->flag = 0;
160  td->loc = td2d->loc;
161  mul_v2_m3v2(td->center, parent_matrix, bezt->vec[1]);
162  td->center[0] *= asp[0];
163  td->center[1] *= asp[1];
164  copy_v3_v3(td->iloc, td->loc);
165 
166  memset(td->axismtx, 0, sizeof(td->axismtx));
167  td->axismtx[2][2] = 1.0f;
168 
169  td->ext = NULL;
170 
171  if (i == 1) {
172  /* scaling weights */
173  td->val = &bezt->weight;
174  td->ival = *td->val;
175  }
176  else {
177  td->val = NULL;
178  }
179 
180  if (is_sel_any) {
181  td->flag |= TD_SELECTED;
182  }
183  td->dist = 0.0;
184 
185  unit_m3(td->mtx);
186  unit_m3(td->smtx);
187 
188  if (i == 0) {
189  tdm->orig_handle_type = bezt->h1;
190  }
191  else if (i == 2) {
192  tdm->orig_handle_type = bezt->h2;
193  }
194 
195  td++;
196  td2d++;
197  tdm++;
198  }
199  }
200  else {
202  MaskHandleToTransData(point,
204  td,
205  td2d,
206  tdm,
207  asp,
208  parent_matrix,
209  parent_inverse_matrix);
210 
211  td++;
212  td2d++;
213  tdm++;
214  }
215  else {
216  if (bezt->f1 & SELECT) {
217  MaskHandleToTransData(point,
219  td,
220  td2d,
221  tdm,
222  asp,
223  parent_matrix,
224  parent_inverse_matrix);
225 
226  if (bezt->h1 == HD_VECT) {
227  bezt->h1 = HD_FREE;
228  }
229  else if (bezt->h1 == HD_AUTO) {
232  }
233 
234  td++;
235  td2d++;
236  tdm++;
237  }
238  if (bezt->f3 & SELECT) {
239  MaskHandleToTransData(point,
241  td,
242  td2d,
243  tdm,
244  asp,
245  parent_matrix,
246  parent_inverse_matrix);
247 
248  if (bezt->h2 == HD_VECT) {
249  bezt->h2 = HD_FREE;
250  }
251  else if (bezt->h2 == HD_AUTO) {
254  }
255 
256  td++;
257  td2d++;
258  tdm++;
259  }
260  }
261  }
262 }
263 
265 {
268  MaskLayer *masklay;
269  TransData *td = NULL;
270  TransData2D *td2d = NULL;
271  TransDataMasking *tdm = NULL;
272  int count = 0, countsel = 0;
273  const bool is_prop_edit = (t->flag & T_PROP_EDIT);
274  float asp[2];
275 
277 
278  tc->data_len = 0;
279 
280  if (!mask) {
281  return;
282  }
283 
284  if (t->spacetype == SPACE_CLIP) {
285  SpaceClip *sc = t->area->spacedata.first;
286  MovieClip *clip = ED_space_clip_get_clip(sc);
287  if (!clip) {
288  return;
289  }
290  }
291 
292  /* count */
293  for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
294  MaskSpline *spline;
295 
297  continue;
298  }
299 
300  for (spline = masklay->splines.first; spline; spline = spline->next) {
301  int i;
302 
303  for (i = 0; i < spline->tot_point; i++) {
304  MaskSplinePoint *point = &spline->points[i];
305 
306  if (MASKPOINT_ISSEL_ANY(point)) {
307  if (MASKPOINT_ISSEL_KNOT(point)) {
308  countsel += 3;
309  }
310  else {
312  countsel += 1;
313  }
314  else {
315  BezTriple *bezt = &point->bezt;
316  if (bezt->f1 & SELECT) {
317  countsel++;
318  }
319  if (bezt->f3 & SELECT) {
320  countsel++;
321  }
322  }
323  }
324  }
325 
326  if (is_prop_edit) {
327  count += 3;
328  }
329  }
330  }
331  }
332 
333  /* note: in prop mode we need at least 1 selected */
334  if (countsel == 0) {
335  return;
336  }
337 
338  ED_mask_get_aspect(t->area, t->region, &asp[0], &asp[1]);
339 
340  tc->data_len = (is_prop_edit) ? count : countsel;
341  td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mask Editing)");
342  /* for each 2d uv coord a 3d vector is allocated, so that they can be
343  * treated just as if they were 3d verts */
344  td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D),
345  "TransObData2D(Mask Editing)");
346  tc->custom.type.data = tdm = MEM_callocN(tc->data_len * sizeof(TransDataMasking),
347  "TransDataMasking(Mask Editing)");
348  tc->custom.type.use_free = true;
349 
350  /* create data */
351  for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
352  MaskSpline *spline;
353 
355  continue;
356  }
357 
358  for (spline = masklay->splines.first; spline; spline = spline->next) {
359  int i;
360 
361  for (i = 0; i < spline->tot_point; i++) {
362  MaskSplinePoint *point = &spline->points[i];
363 
364  if (is_prop_edit || MASKPOINT_ISSEL_ANY(point)) {
365  MaskPointToTransData(scene, point, td, td2d, tdm, is_prop_edit, asp);
366 
367  if (is_prop_edit || MASKPOINT_ISSEL_KNOT(point)) {
368  td += 3;
369  td2d += 3;
370  tdm += 3;
371  }
372  else {
374  td++;
375  td2d++;
376  tdm++;
377  }
378  else {
379  BezTriple *bezt = &point->bezt;
380  if (bezt->f1 & SELECT) {
381  td++;
382  td2d++;
383  tdm++;
384  }
385  if (bezt->f3 & SELECT) {
386  td++;
387  td2d++;
388  tdm++;
389  }
390  }
391  }
392  }
393  }
394  }
395  }
396 }
397 
400 /* -------------------------------------------------------------------- */
405 {
406  TransData2D *td;
407  TransDataMasking *tdm;
408  int a;
409  float asp[2], inv[2];
410 
412 
413  ED_mask_get_aspect(t->area, t->region, &asp[0], &asp[1]);
414  inv[0] = 1.0f / asp[0];
415  inv[1] = 1.0f / asp[1];
416 
417  /* flush to 2d vector from internally used 3d vector */
418  for (a = 0, td = tc->data_2d, tdm = tc->custom.type.data; a < tc->data_len; a++, td++, tdm++) {
419  td->loc2d[0] = td->loc[0] * inv[0];
420  td->loc2d[1] = td->loc[1] * inv[1];
422 
423  if (tdm->is_handle) {
425  tdm->which_handle,
426  td->loc2d,
427  (t->flag & T_ALT_TRANSFORM) != 0,
428  tdm->orig_handle,
429  tdm->vec);
430  }
431 
432  if (t->state == TRANS_CANCEL) {
433  if (tdm->which_handle == MASK_WHICH_HANDLE_LEFT) {
434  tdm->point->bezt.h1 = tdm->orig_handle_type;
435  }
436  else if (tdm->which_handle == MASK_WHICH_HANDLE_RIGHT) {
437  tdm->point->bezt.h2 = tdm->orig_handle_type;
438  }
439  }
440  }
441 }
442 
444 {
445  Mask *mask = CTX_data_edit_mask(t->context);
446 
448 
449  DEG_id_tag_update(&mask->id, 0);
450 }
451 
454 /* -------------------------------------------------------------------- */
459 {
460  Mask *mask = NULL;
461 
462  if (t->spacetype == SPACE_CLIP) {
463  SpaceClip *sc = t->area->spacedata.first;
465  }
466  else if (t->spacetype == SPACE_IMAGE) {
467  SpaceImage *sima = t->area->spacedata.first;
469  }
470  else {
471  BLI_assert(0);
472  }
473 
474  if (t->scene->nodetree) {
475  /* tracks can be used for stabilization nodes,
476  * flush update for such nodes */
477  // if (nodeUpdateID(t->scene->nodetree, &mask->id))
478  {
480  }
481  }
482 
483  /* TODO: don't key all masks. */
484  if (IS_AUTOKEY_ON(t->scene)) {
485  Scene *scene = t->scene;
486 
489  DEG_id_tag_update(&mask->id, 0);
490  }
491  }
492 }
493 
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct Mask * CTX_data_edit_mask(const bContext *C)
Definition: context.c:1316
@ MASK_HANDLE_MODE_STICK
Definition: BKE_mask.h:55
#define MASKPOINT_ISSEL_ANY(p)
Definition: BKE_mask.h:232
eMaskWhichHandle
Definition: BKE_mask.h:46
@ MASK_WHICH_HANDLE_RIGHT
Definition: BKE_mask.h:50
@ MASK_WHICH_HANDLE_LEFT
Definition: BKE_mask.h:49
@ MASK_WHICH_HANDLE_STICK
Definition: BKE_mask.h:48
#define MASKPOINT_ISSEL_KNOT(p)
Definition: BKE_mask.h:233
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:714
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:1297
eMaskhandleMode BKE_mask_point_handles_mode_get(const struct MaskSplinePoint *point)
#define BLI_assert(a)
Definition: BLI_assert.h:58
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:89
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
void mul_m3_v2(const float m[3][3], float r[2])
Definition: math_matrix.c:727
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1161
void mul_v2_m3v2(float r[2], const float m[3][3], const float v[2])
Definition: math_matrix.c:714
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_RESTRICT_SELECT
#define MASK_RESTRICT_VIEW
#define CFRA
@ SPACE_CLIP
@ SPACE_IMAGE
struct Mask * ED_space_clip_get_mask(struct SpaceClip *sc)
Definition: clip_editor.c:633
struct MovieClip * ED_space_clip_get_clip(struct SpaceClip *sc)
Definition: clip_editor.c:572
struct Mask * ED_space_image_get_mask(struct SpaceImage *sima)
Definition: image_edit.c:122
#define IS_AUTOKEY_ON(scene)
void ED_mask_get_aspect(struct ScrArea *area, struct ARegion *region, float *aspx, float *aspy)
bool ED_mask_layer_shape_auto_key_select(struct Mask *mask, const 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.
#define C
Definition: RandGen.cpp:39
#define ND_DATA
Definition: WM_types.h:408
#define NC_MASK
Definition: WM_types.h:299
#define SELECT
Scene scene
int count
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned a[3]
Definition: RandGen.cpp:92
float vec[3][3]
void * first
Definition: DNA_listBase.h:47
struct MaskLayer * next
ListBase splines
char restrictflag
struct MaskSpline * next
MaskSplinePoint * points
TransCustomData type
Definition: transform.h:428
unsigned int use_free
Definition: transform.h:408
float loc[3]
TransCustomDataContainer custom
Definition: transform.h:501
TransData * data
Definition: transform.h:448
TransData2D * data_2d
Definition: transform.h:452
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
@ T_ALT_TRANSFORM
Definition: transform.h:140
@ T_PROP_EDIT
Definition: transform.h:111
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition: transform.h:810
@ TRANS_CANCEL
Definition: transform.h:193
conversion and adaptation of different datablocks to a common struct.
struct TransDataMasking TransDataMasking
void createTransMaskingData(bContext *C, TransInfo *t)
static void flushTransMasking(TransInfo *t)
void special_aftertrans_update__mask(bContext *C, TransInfo *t)
void recalcData_mask_common(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
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)