Blender  V2.93
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) 2012 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <stddef.h>
25 #include <string.h>
26 
27 #include "CLG_log.h"
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "BLI_endian_switch.h"
32 #include "BLI_ghash.h"
33 #include "BLI_listbase.h"
34 #include "BLI_math.h"
35 #include "BLI_string.h"
36 #include "BLI_string_utils.h"
37 #include "BLI_utildefines.h"
38 
39 #include "BLT_translation.h"
40 
41 #include "DNA_mask_types.h"
42 
43 #include "BKE_animsys.h"
44 #include "BKE_curve.h"
45 #include "BKE_idtype.h"
46 
47 #include "BKE_anim_data.h"
48 #include "BKE_image.h"
49 #include "BKE_lib_id.h"
50 #include "BKE_lib_query.h"
51 #include "BKE_main.h"
52 #include "BKE_mask.h"
53 #include "BKE_movieclip.h"
54 #include "BKE_tracking.h"
55 
56 #include "DEG_depsgraph_build.h"
57 
58 #include "BLO_read_write.h"
59 
60 static CLG_LogRef LOG = {"bke.mask"};
61 
62 static void mask_copy_data(Main *UNUSED(bmain),
63  ID *id_dst,
64  const ID *id_src,
65  const int UNUSED(flag))
66 {
67  Mask *mask_dst = (Mask *)id_dst;
68  const Mask *mask_src = (const Mask *)id_src;
69 
70  BLI_listbase_clear(&mask_dst->masklayers);
71 
72  /* TODO add unused flag to those as well. */
73  BKE_mask_layer_copy_list(&mask_dst->masklayers, &mask_src->masklayers);
74 
75  /* enable fake user by default */
76  id_fake_user_set(&mask_dst->id);
77 }
78 
79 static void mask_free_data(ID *id)
80 {
81  Mask *mask = (Mask *)id;
82 
83  /* free mask data */
84  BKE_mask_layer_free_list(&mask->masklayers);
85 }
86 
88 {
89  Mask *mask = (Mask *)id;
90 
91  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
92  LISTBASE_FOREACH (MaskSpline *, mask_spline, &mask_layer->splines) {
93  for (int i = 0; i < mask_spline->tot_point; i++) {
94  MaskSplinePoint *point = &mask_spline->points[i];
96  }
97  }
98  }
99 }
100 
101 static void mask_blend_write(BlendWriter *writer, ID *id, const void *id_address)
102 {
103  Mask *mask = (Mask *)id;
104  if (mask->id.us > 0 || BLO_write_is_undo(writer)) {
105  MaskLayer *masklay;
106 
107  BLO_write_id_struct(writer, Mask, id_address, &mask->id);
108  BKE_id_blend_write(writer, &mask->id);
109 
110  if (mask->adt) {
111  BKE_animdata_blend_write(writer, mask->adt);
112  }
113 
114  for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
115  MaskSpline *spline;
116  MaskLayerShape *masklay_shape;
117 
118  BLO_write_struct(writer, MaskLayer, masklay);
119 
120  for (spline = masklay->splines.first; spline; spline = spline->next) {
121  int i;
122 
123  void *points_deform = spline->points_deform;
124  spline->points_deform = NULL;
125 
126  BLO_write_struct(writer, MaskSpline, spline);
127  BLO_write_struct_array(writer, MaskSplinePoint, spline->tot_point, spline->points);
128 
129  spline->points_deform = points_deform;
130 
131  for (i = 0; i < spline->tot_point; i++) {
132  MaskSplinePoint *point = &spline->points[i];
133 
134  if (point->tot_uw) {
135  BLO_write_struct_array(writer, MaskSplinePointUW, point->tot_uw, point->uw);
136  }
137  }
138  }
139 
140  for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
141  masklay_shape = masklay_shape->next) {
142  BLO_write_struct(writer, MaskLayerShape, masklay_shape);
144  writer, masklay_shape->tot_vert * MASK_OBJECT_SHAPE_ELEM_SIZE, masklay_shape->data);
145  }
146  }
147  }
148 }
149 
150 static void mask_blend_read_data(BlendDataReader *reader, ID *id)
151 {
152  Mask *mask = (Mask *)id;
153  BLO_read_data_address(reader, &mask->adt);
154 
155  BLO_read_list(reader, &mask->masklayers);
156 
157  LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
158  /* can't use newdataadr since it's a pointer within an array */
159  MaskSplinePoint *act_point_search = NULL;
160 
161  BLO_read_list(reader, &masklay->splines);
162 
163  LISTBASE_FOREACH (MaskSpline *, spline, &masklay->splines) {
164  MaskSplinePoint *points_old = spline->points;
165 
166  BLO_read_data_address(reader, &spline->points);
167 
168  for (int i = 0; i < spline->tot_point; i++) {
169  MaskSplinePoint *point = &spline->points[i];
170 
171  if (point->tot_uw) {
172  BLO_read_data_address(reader, &point->uw);
173  }
174  }
175 
176  /* detect active point */
177  if ((act_point_search == NULL) && (masklay->act_point >= points_old) &&
178  (masklay->act_point < points_old + spline->tot_point)) {
179  act_point_search = &spline->points[masklay->act_point - points_old];
180  }
181  }
182 
183  BLO_read_list(reader, &masklay->splines_shapes);
184 
185  LISTBASE_FOREACH (MaskLayerShape *, masklay_shape, &masklay->splines_shapes) {
186  BLO_read_data_address(reader, &masklay_shape->data);
187 
188  if (masklay_shape->tot_vert) {
189  if (BLO_read_requires_endian_switch(reader)) {
190  BLI_endian_switch_float_array(masklay_shape->data,
191  masklay_shape->tot_vert * sizeof(float) *
193  }
194  }
195  }
196 
197  BLO_read_data_address(reader, &masklay->act_spline);
198  masklay->act_point = act_point_search;
199  }
200 }
201 
202 static void lib_link_mask_parent(BlendLibReader *reader, Mask *mask, MaskParent *parent)
203 {
204  BLO_read_id_address(reader, mask->id.lib, &parent->id);
205 }
206 
207 static void mask_blend_read_lib(BlendLibReader *reader, ID *id)
208 {
209  Mask *mask = (Mask *)id;
210  LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
211  MaskSpline *spline;
212 
213  spline = masklay->splines.first;
214  while (spline) {
215  for (int i = 0; i < spline->tot_point; i++) {
216  MaskSplinePoint *point = &spline->points[i];
217 
218  lib_link_mask_parent(reader, mask, &point->parent);
219  }
220 
221  lib_link_mask_parent(reader, mask, &spline->parent);
222 
223  spline = spline->next;
224  }
225  }
226 }
227 
228 static void expand_mask_parent(BlendExpander *expander, MaskParent *parent)
229 {
230  if (parent->id) {
231  BLO_expand(expander, parent->id);
232  }
233 }
234 
235 static void mask_blend_read_expand(BlendExpander *expander, ID *id)
236 {
237  Mask *mask = (Mask *)id;
238  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
239  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
240  for (int i = 0; i < spline->tot_point; i++) {
241  MaskSplinePoint *point = &spline->points[i];
242  expand_mask_parent(expander, &point->parent);
243  }
244 
245  expand_mask_parent(expander, &spline->parent);
246  }
247  }
248 }
249 
251  .id_code = ID_MSK,
252  .id_filter = FILTER_ID_MSK,
253  .main_listbase_index = INDEX_ID_MSK,
254  .struct_size = sizeof(Mask),
255  .name = "Mask",
256  .name_plural = "masks",
257  .translation_context = BLT_I18NCONTEXT_ID_MASK,
258  .flags = 0,
259 
260  .init_data = NULL,
261  .copy_data = mask_copy_data,
262  .free_data = mask_free_data,
263  .make_local = NULL,
264  .foreach_id = mask_foreach_id,
265  .foreach_cache = NULL,
266  .owner_get = NULL,
267 
268  .blend_write = mask_blend_write,
269  .blend_read_data = mask_blend_read_data,
270  .blend_read_lib = mask_blend_read_lib,
271  .blend_read_expand = mask_blend_read_expand,
272 
273  .blend_read_undo_preserve = NULL,
274 
275  .lib_override_apply_post = NULL,
276 };
277 
278 static struct {
280  struct GHash *id_hash;
282 
284  MaskSplinePoint *points_array,
285  MaskSplinePoint *point)
286 {
287  if (point == &points_array[spline->tot_point - 1]) {
288  if (spline->flag & MASK_SPLINE_CYCLIC) {
289  return &points_array[0];
290  }
291 
292  return NULL;
293  }
294 
295  return point + 1;
296 }
297 
299  MaskSplinePoint *points_array,
300  MaskSplinePoint *point)
301 {
302  if (point == points_array) {
303  if (spline->flag & MASK_SPLINE_CYCLIC) {
304  return &points_array[spline->tot_point - 1];
305  }
306 
307  return NULL;
308  }
309 
310  return point - 1;
311 }
312 
314  MaskSplinePoint *points_array,
315  MaskSplinePoint *point)
316 {
317  if (point == &points_array[spline->tot_point - 1]) {
318  if (spline->flag & MASK_SPLINE_CYCLIC) {
319  return &(points_array[0].bezt);
320  }
321 
322  return NULL;
323  }
324 
325  return &((point + 1))->bezt;
326 }
327 
329 {
330  return spline->points_deform ? spline->points_deform : spline->points;
331 }
332 
334  const MaskSplinePoint *point_ref)
335 {
336  if ((point_ref >= spline->points) && (point_ref < &spline->points[spline->tot_point])) {
337  return spline->points;
338  }
339 
340  if ((point_ref >= spline->points_deform) &&
341  (point_ref < &spline->points_deform[spline->tot_point])) {
342  return spline->points_deform;
343  }
344 
345  BLI_assert(!"wrong array");
346  return NULL;
347 }
348 
349 /* mask layers */
350 
351 MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name)
352 {
353  MaskLayer *masklay = MEM_callocN(sizeof(MaskLayer), __func__);
354 
355  if (name && name[0]) {
356  BLI_strncpy(masklay->name, name, sizeof(masklay->name));
357  }
358  else {
359  strcpy(masklay->name, "MaskLayer");
360  }
361 
362  BLI_addtail(&mask->masklayers, masklay);
363 
365 
366  mask->masklay_tot++;
367 
368  masklay->blend = MASK_BLEND_MERGE_ADD;
369  masklay->alpha = 1.0f;
371 
372  return masklay;
373 }
374 
375 /* note: may still be hidden, caller needs to check */
377 {
378  return BLI_findlink(&mask->masklayers, mask->masklay_act);
379 }
380 
382 {
383  mask->masklay_act = BLI_findindex(&mask->masklayers, masklay);
384 }
385 
387 {
388  BLI_remlink(&mask->masklayers, masklay);
389  BKE_mask_layer_free(masklay);
390 
391  mask->masklay_tot--;
392 
393  if (mask->masklay_act >= mask->masklay_tot) {
394  mask->masklay_act = mask->masklay_tot - 1;
395  }
396 }
397 
399 {
400  BLI_uniquename(&mask->masklayers,
401  masklay,
402  DATA_("MaskLayer"),
403  '.',
404  offsetof(MaskLayer, name),
405  sizeof(masklay->name));
406 }
407 
408 void BKE_mask_layer_rename(Mask *mask, MaskLayer *masklay, char *oldname, char *newname)
409 {
410  BLI_strncpy(masklay->name, newname, sizeof(masklay->name));
411 
413 
414  /* now fix animation paths */
415  BKE_animdata_fix_paths_rename_all(&mask->id, "layers", oldname, masklay->name);
416 }
417 
419 {
420  MaskLayer *masklay_new;
421  MaskSpline *spline;
422 
423  masklay_new = MEM_callocN(sizeof(MaskLayer), "new mask layer");
424 
425  BLI_strncpy(masklay_new->name, masklay->name, sizeof(masklay_new->name));
426 
427  masklay_new->alpha = masklay->alpha;
428  masklay_new->blend = masklay->blend;
429  masklay_new->blend_flag = masklay->blend_flag;
430  masklay_new->flag = masklay->flag;
431  masklay_new->falloff = masklay->falloff;
432  masklay_new->restrictflag = masklay->restrictflag;
433 
434  for (spline = masklay->splines.first; spline; spline = spline->next) {
435  MaskSpline *spline_new = BKE_mask_spline_copy(spline);
436 
437  BLI_addtail(&masklay_new->splines, spline_new);
438 
439  if (spline == masklay->act_spline) {
440  masklay_new->act_spline = spline_new;
441  }
442 
443  if (masklay->act_point >= spline->points &&
444  masklay->act_point < spline->points + spline->tot_point) {
445  const size_t point_index = masklay->act_point - spline->points;
446  masklay_new->act_point = spline_new->points + point_index;
447  }
448  }
449 
450  /* correct animation */
451  if (masklay->splines_shapes.first) {
452  MaskLayerShape *masklay_shape;
453  MaskLayerShape *masklay_shape_new;
454 
455  for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
456  masklay_shape = masklay_shape->next) {
457  masklay_shape_new = MEM_callocN(sizeof(MaskLayerShape), "new mask layer shape");
458 
459  masklay_shape_new->data = MEM_dupallocN(masklay_shape->data);
460  masklay_shape_new->tot_vert = masklay_shape->tot_vert;
461  masklay_shape_new->flag = masklay_shape->flag;
462  masklay_shape_new->frame = masklay_shape->frame;
463 
464  BLI_addtail(&masklay_new->splines_shapes, masklay_shape_new);
465  }
466  }
467 
468  return masklay_new;
469 }
470 
471 void BKE_mask_layer_copy_list(ListBase *masklayers_new, const ListBase *masklayers)
472 {
473  MaskLayer *layer;
474 
475  for (layer = masklayers->first; layer; layer = layer->next) {
476  MaskLayer *layer_new = BKE_mask_layer_copy(layer);
477 
478  BLI_addtail(masklayers_new, layer_new);
479  }
480 }
481 
482 /* splines */
483 
485 {
486  MaskSpline *spline;
487 
488  spline = MEM_callocN(sizeof(MaskSpline), "new mask spline");
489  BLI_addtail(&masklay->splines, spline);
490 
491  /* spline shall have one point at least */
492  spline->points = MEM_callocN(sizeof(MaskSplinePoint), "new mask spline point");
493  spline->tot_point = 1;
494 
495  /* cyclic shapes are more usually used */
496  /* Disable because its not so nice for drawing. could be done differently. */
497 #if 0
498  spline->flag |= MASK_SPLINE_CYCLIC;
499 #endif
500 
502 
503  BKE_mask_parent_init(&spline->parent);
504 
505  return spline;
506 }
507 
508 bool BKE_mask_spline_remove(MaskLayer *mask_layer, MaskSpline *spline)
509 {
510  if (BLI_remlink_safe(&mask_layer->splines, spline) == false) {
511  return false;
512  }
513 
514  BKE_mask_spline_free(spline);
515 
516  return true;
517 }
518 
520 {
521  const int tot_uw = point->tot_uw;
522  const int tot_uw_half = tot_uw / 2;
523 
524  float co_tmp[2];
525 
526  /* swap handles */
527  copy_v2_v2(co_tmp, point->bezt.vec[0]);
528  copy_v2_v2(point->bezt.vec[0], point->bezt.vec[2]);
529  copy_v2_v2(point->bezt.vec[2], co_tmp);
530  /* in this case the flags are unlikely to be different but swap anyway */
531  SWAP(uint8_t, point->bezt.f1, point->bezt.f3);
532  SWAP(uint8_t, point->bezt.h1, point->bezt.h2);
533 
534  /* swap UW's */
535  if (tot_uw > 1) {
536  /* count */
537  for (int i = 0; i < tot_uw_half; i++) {
538  MaskSplinePointUW *uw_a = &point->uw[i];
539  MaskSplinePointUW *uw_b = &point->uw[tot_uw - (i + 1)];
540  SWAP(MaskSplinePointUW, *uw_a, *uw_b);
541  }
542  }
543 
544  for (int i = 0; i < tot_uw; i++) {
545  MaskSplinePointUW *uw = &point->uw[i];
546  uw->u = 1.0f - uw->u;
547  }
548 }
549 
551 {
552  const int tot_point = spline->tot_point;
553  const int tot_point_half = tot_point / 2;
554  int i, i_prev;
555 
556  if (tot_point < 2) {
557  return;
558  }
559 
560  /* count */
561  for (i = 0; i < tot_point_half; i++) {
562  MaskSplinePoint *point_a = &spline->points[i];
563  MaskSplinePoint *point_b = &spline->points[tot_point - (i + 1)];
564  SWAP(MaskSplinePoint, *point_a, *point_b);
565  }
566 
567  /* correct UW's */
568  i_prev = tot_point - 1;
569  for (i = 0; i < tot_point; i++) {
570 
572 
573  SWAP(MaskSplinePointUW *, spline->points[i].uw, spline->points[i_prev].uw);
574  SWAP(int, spline->points[i].tot_uw, spline->points[i_prev].tot_uw);
575 
576  i_prev = i;
577  }
578 
579  /* correct animation */
580  if (masklay->splines_shapes.first) {
581  MaskLayerShape *masklay_shape;
582 
583  const int spline_index = BKE_mask_layer_shape_spline_to_index(masklay, spline);
584 
585  for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
586  masklay_shape = masklay_shape->next) {
587  MaskLayerShapeElem *fp_arr = (MaskLayerShapeElem *)masklay_shape->data;
588 
589  for (i = 0; i < tot_point_half; i++) {
590  MaskLayerShapeElem *fp_a = &fp_arr[spline_index + (i)];
591  MaskLayerShapeElem *fp_b = &fp_arr[spline_index + (tot_point - (i + 1))];
592  SWAP(MaskLayerShapeElem, *fp_a, *fp_b);
593  }
594  }
595  }
596 }
597 
599  MaskSplinePoint *point,
600  float start_u,
601  const float co[2],
602  const eMaskSign sign)
603 {
604  const float proj_eps = 1e-3;
605  const float proj_eps_sq = proj_eps * proj_eps;
606  const int N = 1000;
607  float u = -1.0f, du = 1.0f / N, u1 = start_u, u2 = start_u;
608  float ang = -1.0f;
609 
610  BLI_assert(abs(sign) <= 1); /* (-1, 0, 1) */
611 
612  while (u1 > 0.0f || u2 < 1.0f) {
613  float n1[2], n2[2], co1[2], co2[2];
614  float v1[2], v2[2];
615  float ang1, ang2;
616 
617  if (u1 >= 0.0f) {
618  BKE_mask_point_segment_co(spline, point, u1, co1);
619  BKE_mask_point_normal(spline, point, u1, n1);
620  sub_v2_v2v2(v1, co, co1);
621 
622  if ((sign == MASK_PROJ_ANY) || ((sign == MASK_PROJ_NEG) && (dot_v2v2(v1, n1) <= 0.0f)) ||
623  ((sign == MASK_PROJ_POS) && (dot_v2v2(v1, n1) >= 0.0f))) {
624 
625  if (len_squared_v2(v1) > proj_eps_sq) {
626  ang1 = angle_v2v2(v1, n1);
627  if (ang1 > (float)M_PI / 2.0f) {
628  ang1 = (float)M_PI - ang1;
629  }
630 
631  if (ang < 0.0f || ang1 < ang) {
632  ang = ang1;
633  u = u1;
634  }
635  }
636  else {
637  u = u1;
638  break;
639  }
640  }
641  }
642 
643  if (u2 <= 1.0f) {
644  BKE_mask_point_segment_co(spline, point, u2, co2);
645  BKE_mask_point_normal(spline, point, u2, n2);
646  sub_v2_v2v2(v2, co, co2);
647 
648  if ((sign == MASK_PROJ_ANY) || ((sign == MASK_PROJ_NEG) && (dot_v2v2(v2, n2) <= 0.0f)) ||
649  ((sign == MASK_PROJ_POS) && (dot_v2v2(v2, n2) >= 0.0f))) {
650 
651  if (len_squared_v2(v2) > proj_eps_sq) {
652  ang2 = angle_v2v2(v2, n2);
653  if (ang2 > (float)M_PI / 2.0f) {
654  ang2 = (float)M_PI - ang2;
655  }
656 
657  if (ang2 < ang) {
658  ang = ang2;
659  u = u2;
660  }
661  }
662  else {
663  u = u2;
664  break;
665  }
666  }
667  }
668 
669  u1 -= du;
670  u2 += du;
671  }
672 
673  return u;
674 }
675 
676 /* point */
677 
679 {
680  const BezTriple *bezt = &point->bezt;
681 
682  if (bezt->h1 == bezt->h2 && bezt->h1 == HD_ALIGN) {
683  return MASK_HANDLE_MODE_STICK;
684  }
685 
687 }
688 
690  eMaskWhichHandle which_handle,
691  float r_handle[2])
692 {
693  const BezTriple *bezt = &point->bezt;
694 
695  if (which_handle == MASK_WHICH_HANDLE_STICK) {
696  float vec[2];
697 
698  sub_v2_v2v2(vec, bezt->vec[0], bezt->vec[1]);
699 
700  r_handle[0] = (bezt->vec[1][0] + vec[1]);
701  r_handle[1] = (bezt->vec[1][1] - vec[0]);
702  }
703  else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
704  copy_v2_v2(r_handle, bezt->vec[0]);
705  }
706  else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
707  copy_v2_v2(r_handle, bezt->vec[2]);
708  }
709  else {
710  BLI_assert(!"Unknown handle passed to BKE_mask_point_handle");
711  }
712 }
713 
715  eMaskWhichHandle which_handle,
716  float loc[2],
717  bool keep_direction,
718  float orig_handle[2],
719  float orig_vec[3][3])
720 {
721  BezTriple *bezt = &point->bezt;
722 
723  if (which_handle == MASK_WHICH_HANDLE_STICK) {
724  float v1[2], v2[2], vec[2];
725  if (keep_direction) {
726  sub_v2_v2v2(v1, loc, orig_vec[1]);
727  sub_v2_v2v2(v2, orig_handle, orig_vec[1]);
728 
729  project_v2_v2v2(vec, v1, v2);
730 
731  if (dot_v2v2(v2, vec) > 0) {
732  float len = len_v2(vec);
733 
734  sub_v2_v2v2(v1, orig_vec[0], orig_vec[1]);
735 
736  mul_v2_fl(v1, len / len_v2(v1));
737 
738  add_v2_v2v2(bezt->vec[0], bezt->vec[1], v1);
739  sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v1);
740  }
741  else {
742  copy_v3_v3(bezt->vec[0], bezt->vec[1]);
743  copy_v3_v3(bezt->vec[2], bezt->vec[1]);
744  }
745  }
746  else {
747  sub_v2_v2v2(v1, loc, bezt->vec[1]);
748 
749  v2[0] = -v1[1];
750  v2[1] = v1[0];
751 
752  add_v2_v2v2(bezt->vec[0], bezt->vec[1], v2);
753  sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v2);
754  }
755  }
756  else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
757  copy_v2_v2(bezt->vec[0], loc);
758  }
759  else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
760  copy_v2_v2(bezt->vec[2], loc);
761  }
762  else {
763  BLI_assert(!"unknown handle passed to BKE_mask_point_set_handle");
764  }
765 }
766 
767 void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float u, float co[2])
768 {
769  MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
770 
771  BezTriple *bezt = &point->bezt, *bezt_next;
772 
773  bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
774 
775  if (!bezt_next) {
776  copy_v2_v2(co, bezt->vec[1]);
777  return;
778  }
779 
781  co, bezt->vec[1], bezt->vec[2], bezt_next->vec[0], bezt_next->vec[1], u);
782 }
783 
784 BLI_INLINE void orthogonal_direction_get(const float vec[2], float result[2])
785 {
786  result[0] = -vec[1];
787  result[1] = vec[0];
789 }
790 
791 /* TODO(sergey): This function will re-calculate loads of stuff again and again
792  * when differentiating feather points. This might be easily cached
793  * in the callee function for this case.
794  */
795 void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u, float n[2])
796 {
797 
798  MaskSplinePoint *point_prev, *point_next;
799 
800  /* TODO(sergey): This actually depends on a resolution. */
801  const float du = 0.05f;
802 
803  BKE_mask_get_handle_point_adjacent(spline, point, &point_prev, &point_next);
804 
805  if (u - du < 0.0f && point_prev == NULL) {
806  float co[2], dir[2];
807  BKE_mask_point_segment_co(spline, point, u + du, co);
808  sub_v2_v2v2(dir, co, point->bezt.vec[1]);
809  orthogonal_direction_get(dir, n);
810  }
811  else if (u + du > 1.0f && point_next == NULL) {
812  float co[2], dir[2];
813  BKE_mask_point_segment_co(spline, point, u - du, co);
814  sub_v2_v2v2(dir, point->bezt.vec[1], co);
815  orthogonal_direction_get(dir, n);
816  }
817  else {
818  float prev_co[2], next_co[2], co[2];
819  float dir1[2], dir2[2], dir[2];
820 
821  if (u - du < 0.0f) {
822  BKE_mask_point_segment_co(spline, point_prev, 1.0f + (u - du), prev_co);
823  }
824  else {
825  BKE_mask_point_segment_co(spline, point, u - du, prev_co);
826  }
827 
828  BKE_mask_point_segment_co(spline, point, u, co);
829 
830  if (u + du > 1.0f) {
831  BKE_mask_point_segment_co(spline, point_next, u + du - 1.0f, next_co);
832  }
833  else {
834  BKE_mask_point_segment_co(spline, point, u + du, next_co);
835  }
836 
837  sub_v2_v2v2(dir1, co, prev_co);
838  sub_v2_v2v2(dir2, next_co, co);
839 
840  normalize_v2(dir1);
841  normalize_v2(dir2);
842  add_v2_v2v2(dir, dir1, dir2);
843 
844  orthogonal_direction_get(dir, n);
845  }
846 }
847 
848 static float mask_point_interp_weight(BezTriple *bezt, BezTriple *bezt_next, const float u)
849 {
850  return (bezt->weight * (1.0f - u)) + (bezt_next->weight * u);
851 }
852 
853 float BKE_mask_point_weight_scalar(MaskSpline *spline, MaskSplinePoint *point, const float u)
854 {
855  MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
856  BezTriple *bezt = &point->bezt, *bezt_next;
857 
858  bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
859 
860  if (!bezt_next) {
861  return bezt->weight;
862  }
863  if (u <= 0.0f) {
864  return bezt->weight;
865  }
866  if (u >= 1.0f) {
867  return bezt_next->weight;
868  }
869 
870  return mask_point_interp_weight(bezt, bezt_next, u);
871 }
872 
873 float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const float u)
874 {
875  MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
876  BezTriple *bezt = &point->bezt, *bezt_next;
877 
878  bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
879 
880  if (!bezt_next) {
881  return bezt->weight;
882  }
883  if (u <= 0.0f) {
884  return bezt->weight;
885  }
886  if (u >= 1.0f) {
887  return bezt_next->weight;
888  }
889 
890  float cur_u = 0.0f, cur_w = 0.0f, next_u = 0.0f, next_w = 0.0f, fac; /* Quite warnings */
891 
892  for (int i = 0; i <= point->tot_uw; i++) {
893  if (i == 0) {
894  cur_u = 0.0f;
895  cur_w = 1.0f; /* mask_point_interp_weight will scale it */
896  }
897  else {
898  cur_u = point->uw[i - 1].u;
899  cur_w = point->uw[i - 1].w;
900  }
901 
902  if (i == point->tot_uw) {
903  next_u = 1.0f;
904  next_w = 1.0f; /* mask_point_interp_weight will scale it */
905  }
906  else {
907  next_u = point->uw[i].u;
908  next_w = point->uw[i].w;
909  }
910 
911  if (u >= cur_u && u <= next_u) {
912  break;
913  }
914  }
915 
916  fac = (u - cur_u) / (next_u - cur_u);
917 
918  cur_w *= mask_point_interp_weight(bezt, bezt_next, cur_u);
919  next_w *= mask_point_interp_weight(bezt, bezt_next, next_u);
920 
921  if (spline->weight_interp == MASK_SPLINE_INTERP_EASE) {
922  return cur_w + (next_w - cur_w) * (3.0f * fac * fac - 2.0f * fac * fac * fac);
923  }
924 
925  return (1.0f - fac) * cur_w + fac * next_w;
926 }
927 
929 {
930  if (point->tot_uw > 1) {
931  int idx = uw - point->uw;
932 
933  if (idx > 0 && point->uw[idx - 1].u > uw->u) {
934  while (idx > 0 && point->uw[idx - 1].u > point->uw[idx].u) {
935  SWAP(MaskSplinePointUW, point->uw[idx - 1], point->uw[idx]);
936  idx--;
937  }
938  }
939 
940  if (idx < point->tot_uw - 1 && point->uw[idx + 1].u < uw->u) {
941  while (idx < point->tot_uw - 1 && point->uw[idx + 1].u < point->uw[idx].u) {
942  SWAP(MaskSplinePointUW, point->uw[idx + 1], point->uw[idx]);
943  idx++;
944  }
945  }
946 
947  return &point->uw[idx];
948  }
949 
950  return uw;
951 }
952 
953 void BKE_mask_point_add_uw(MaskSplinePoint *point, float u, float w)
954 {
955  if (!point->uw) {
956  point->uw = MEM_mallocN(sizeof(*point->uw), "mask point uw");
957  }
958  else {
959  point->uw = MEM_reallocN(point->uw, (point->tot_uw + 1) * sizeof(*point->uw));
960  }
961 
962  point->uw[point->tot_uw].u = u;
963  point->uw[point->tot_uw].w = w;
964  point->uw[point->tot_uw].flag = 0;
965 
966  point->tot_uw++;
967 
968  BKE_mask_point_sort_uw(point, &point->uw[point->tot_uw - 1]);
969 }
970 
971 void BKE_mask_point_select_set(MaskSplinePoint *point, const bool do_select)
972 {
973  if (do_select) {
974  MASKPOINT_SEL_ALL(point);
975  }
976  else {
977  MASKPOINT_DESEL_ALL(point);
978  }
979 
980  for (int i = 0; i < point->tot_uw; i++) {
981  if (do_select) {
982  point->uw[i].flag |= SELECT;
983  }
984  else {
985  point->uw[i].flag &= ~SELECT;
986  }
987  }
988 }
989 
991  const eMaskWhichHandle which_handle,
992  const bool do_select)
993 {
994  if (do_select) {
996  point->bezt.f1 |= SELECT;
997  point->bezt.f3 |= SELECT;
998  }
999  else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
1000  point->bezt.f1 |= SELECT;
1001  }
1002  else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
1003  point->bezt.f3 |= SELECT;
1004  }
1005  else {
1006  BLI_assert(!"Wrong which_handle passed to BKE_mask_point_select_set_handle");
1007  }
1008  }
1009  else {
1010  if (ELEM(which_handle, MASK_WHICH_HANDLE_STICK, MASK_WHICH_HANDLE_BOTH)) {
1011  point->bezt.f1 &= ~SELECT;
1012  point->bezt.f3 &= ~SELECT;
1013  }
1014  else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
1015  point->bezt.f1 &= ~SELECT;
1016  }
1017  else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
1018  point->bezt.f3 &= ~SELECT;
1019  }
1020  else {
1021  BLI_assert(!"Wrong which_handle passed to BKE_mask_point_select_set_handle");
1022  }
1023  }
1024 }
1025 
1026 /* only mask block itself */
1027 static Mask *mask_alloc(Main *bmain, const char *name)
1028 {
1029  Mask *mask;
1030 
1031  mask = BKE_libblock_alloc(bmain, ID_MSK, name, 0);
1032 
1033  id_fake_user_set(&mask->id);
1034 
1035  return mask;
1036 }
1037 
1038 Mask *BKE_mask_new(Main *bmain, const char *name)
1039 {
1040  Mask *mask;
1041  char mask_name[MAX_ID_NAME - 2];
1042 
1043  if (name && name[0]) {
1044  BLI_strncpy(mask_name, name, sizeof(mask_name));
1045  }
1046  else {
1047  strcpy(mask_name, "Mask");
1048  }
1049 
1050  mask = mask_alloc(bmain, mask_name);
1051 
1052  /* arbitrary defaults */
1053  mask->sfra = 1;
1054  mask->efra = 100;
1055 
1056  DEG_relations_tag_update(bmain);
1057 
1058  return mask;
1059 }
1060 
1062 {
1063  if (point->uw) {
1064  MEM_freeN(point->uw);
1065  }
1066 }
1067 
1069 {
1070  int i = 0;
1071 
1072  for (i = 0; i < spline->tot_point; i++) {
1073  MaskSplinePoint *point;
1074  point = &spline->points[i];
1075  BKE_mask_point_free(point);
1076 
1077  if (spline->points_deform) {
1078  point = &spline->points_deform[i];
1079  BKE_mask_point_free(point);
1080  }
1081  }
1082 
1083  MEM_freeN(spline->points);
1084 
1085  if (spline->points_deform) {
1086  MEM_freeN(spline->points_deform);
1087  }
1088 
1089  MEM_freeN(spline);
1090 }
1091 
1093 {
1094  MaskSpline *spline = splines->first;
1095  while (spline) {
1096  MaskSpline *next_spline = spline->next;
1097 
1098  BLI_remlink(splines, spline);
1099  BKE_mask_spline_free(spline);
1100 
1101  spline = next_spline;
1102  }
1103 }
1104 
1105 static MaskSplinePoint *mask_spline_points_copy(const MaskSplinePoint *points, int tot_point)
1106 {
1107  MaskSplinePoint *npoints = MEM_dupallocN(points);
1108 
1109  for (int i = 0; i < tot_point; i++) {
1110  MaskSplinePoint *point = &npoints[i];
1111 
1112  if (point->uw) {
1113  point->uw = MEM_dupallocN(point->uw);
1114  }
1115  }
1116 
1117  return npoints;
1118 }
1119 
1121 {
1122  MaskSpline *nspline = MEM_callocN(sizeof(MaskSpline), "new spline");
1123 
1124  *nspline = *spline;
1125 
1126  nspline->points_deform = NULL;
1127  nspline->points = mask_spline_points_copy(spline->points, spline->tot_point);
1128 
1129  if (spline->points_deform) {
1130  nspline->points_deform = mask_spline_points_copy(spline->points_deform, spline->tot_point);
1131  }
1132 
1133  return nspline;
1134 }
1135 
1136 /* note: does NOT add to the list */
1138 {
1139  MaskLayerShape *masklay_shape;
1140  int tot_vert = BKE_mask_layer_shape_totvert(masklay);
1141 
1142  masklay_shape = MEM_mallocN(sizeof(MaskLayerShape), __func__);
1143  masklay_shape->frame = frame;
1144  masklay_shape->tot_vert = tot_vert;
1145  masklay_shape->data = MEM_mallocN(tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE,
1146  __func__);
1147 
1148  return masklay_shape;
1149 }
1150 
1152 {
1153  if (masklay_shape->data) {
1154  MEM_freeN(masklay_shape->data);
1155  }
1156 
1157  MEM_freeN(masklay_shape);
1158 }
1159 
1163 {
1164  MaskLayerShape *masklay_shape;
1165 
1166  /* free animation data */
1167  masklay_shape = masklay->splines_shapes.first;
1168  while (masklay_shape) {
1169  MaskLayerShape *next_masklay_shape = masklay_shape->next;
1170 
1171  BLI_remlink(&masklay->splines_shapes, masklay_shape);
1172  BKE_mask_layer_shape_free(masklay_shape);
1173 
1174  masklay_shape = next_masklay_shape;
1175  }
1176 }
1177 
1179 {
1180  /* free splines */
1182 
1183  /* free animation data */
1184  BKE_mask_layer_free_shapes(masklay);
1185 
1186  MEM_freeN(masklay);
1187 }
1188 
1190 {
1191  MaskLayer *masklay = masklayers->first;
1192 
1193  while (masklay) {
1194  MaskLayer *masklay_next = masklay->next;
1195 
1196  BLI_remlink(masklayers, masklay);
1197  BKE_mask_layer_free(masklay);
1198 
1199  masklay = masklay_next;
1200  }
1201 }
1202 
1203 void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2])
1204 {
1205  if (frame_size[0] == frame_size[1]) {
1206  r_co[0] = co[0];
1207  r_co[1] = co[1];
1208  }
1209  else if (frame_size[0] < frame_size[1]) {
1210  r_co[0] = ((co[0] - 0.5f) * (frame_size[0] / frame_size[1])) + 0.5f;
1211  r_co[1] = co[1];
1212  }
1213  else { /* (frame_size[0] > frame_size[1]) */
1214  r_co[0] = co[0];
1215  r_co[1] = ((co[1] - 0.5f) * (frame_size[1] / frame_size[0])) + 0.5f;
1216  }
1217 }
1218 
1220  MovieClipUser *user,
1221  float r_co[2],
1222  const float co[2])
1223 {
1224  float aspx, aspy;
1225  float frame_size[2];
1226 
1227  /* scaling for the clip */
1228  BKE_movieclip_get_size_fl(clip, user, frame_size);
1229  BKE_movieclip_get_aspect(clip, &aspx, &aspy);
1230 
1231  frame_size[1] *= (aspy / aspx);
1232 
1233  BKE_mask_coord_from_frame(r_co, co, frame_size);
1234 }
1235 
1236 void BKE_mask_coord_from_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2])
1237 {
1238  float aspx, aspy;
1239  float frame_size[2];
1240 
1241  BKE_image_get_size_fl(image, iuser, frame_size);
1242  BKE_image_get_aspect(image, &aspx, &aspy);
1243 
1244  frame_size[1] *= (aspy / aspx);
1245 
1246  BKE_mask_coord_from_frame(r_co, co, frame_size);
1247 }
1248 
1249 /* as above but divide */
1250 void BKE_mask_coord_to_frame(float r_co[2], const float co[2], const float frame_size[2])
1251 {
1252  if (frame_size[0] == frame_size[1]) {
1253  r_co[0] = co[0];
1254  r_co[1] = co[1];
1255  }
1256  else if (frame_size[0] < frame_size[1]) {
1257  r_co[0] = ((co[0] - 0.5f) / (frame_size[0] / frame_size[1])) + 0.5f;
1258  r_co[1] = co[1];
1259  }
1260  else { /* (frame_size[0] > frame_size[1]) */
1261  r_co[0] = co[0];
1262  r_co[1] = ((co[1] - 0.5f) / (frame_size[1] / frame_size[0])) + 0.5f;
1263  }
1264 }
1265 
1267  MovieClipUser *user,
1268  float r_co[2],
1269  const float co[2])
1270 {
1271  float aspx, aspy;
1272  float frame_size[2];
1273 
1274  /* scaling for the clip */
1275  BKE_movieclip_get_size_fl(clip, user, frame_size);
1276  BKE_movieclip_get_aspect(clip, &aspx, &aspy);
1277 
1278  frame_size[1] *= (aspy / aspx);
1279 
1280  BKE_mask_coord_to_frame(r_co, co, frame_size);
1281 }
1282 
1283 void BKE_mask_coord_to_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2])
1284 {
1285  float aspx, aspy;
1286  float frame_size[2];
1287 
1288  /* scaling for the clip */
1289  BKE_image_get_size_fl(image, iuser, frame_size);
1290  BKE_image_get_aspect(image, &aspx, &aspy);
1291 
1292  frame_size[1] *= (aspy / aspx);
1293 
1294  BKE_mask_coord_to_frame(r_co, co, frame_size);
1295 }
1296 
1298  float ctime,
1299  float parent_matrix[3][3])
1300 {
1301  MaskParent *parent = &point->parent;
1302 
1303  unit_m3(parent_matrix);
1304 
1305  if (!parent) {
1306  return;
1307  }
1308 
1309  if (parent->id_type == ID_MC) {
1310  if (parent->id) {
1311  MovieClip *clip = (MovieClip *)parent->id;
1312  MovieTracking *tracking = (MovieTracking *)&clip->tracking;
1313  MovieTrackingObject *ob = BKE_tracking_object_get_named(tracking, parent->parent);
1314 
1315  if (ob) {
1316  MovieClipUser user = {0};
1317  float clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
1318  BKE_movieclip_user_set_frame(&user, ctime);
1319 
1320  if (parent->type == MASK_PARENT_POINT_TRACK) {
1322  tracking, ob, parent->sub_parent);
1323 
1324  if (track) {
1325  float marker_position[2], parent_co[2];
1326  BKE_tracking_marker_get_subframe_position(track, clip_framenr, marker_position);
1327  BKE_mask_coord_from_movieclip(clip, &user, parent_co, marker_position);
1328  sub_v2_v2v2(parent_matrix[2], parent_co, parent->parent_orig);
1329  }
1330  }
1331  else /* if (parent->type == MASK_PARENT_PLANE_TRACK) */ {
1333  tracking, ob, parent->sub_parent);
1334 
1335  if (plane_track) {
1336  float corners[4][2];
1337  float aspx, aspy;
1338  float frame_size[2], H[3][3], mask_from_clip_matrix[3][3], mask_to_clip_matrix[3][3];
1339 
1340  BKE_tracking_plane_marker_get_subframe_corners(plane_track, ctime, corners);
1342 
1343  unit_m3(mask_from_clip_matrix);
1344 
1345  BKE_movieclip_get_size_fl(clip, &user, frame_size);
1346  BKE_movieclip_get_aspect(clip, &aspx, &aspy);
1347 
1348  frame_size[1] *= (aspy / aspx);
1349  if (frame_size[0] == frame_size[1]) {
1350  /* pass */
1351  }
1352  else if (frame_size[0] < frame_size[1]) {
1353  mask_from_clip_matrix[0][0] = frame_size[1] / frame_size[0];
1354  mask_from_clip_matrix[2][0] = -0.5f * (frame_size[1] / frame_size[0]) + 0.5f;
1355  }
1356  else { /* (frame_size[0] > frame_size[1]) */
1357  mask_from_clip_matrix[1][1] = frame_size[1] / frame_size[0];
1358  mask_from_clip_matrix[2][1] = -0.5f * (frame_size[1] / frame_size[0]) + 0.5f;
1359  }
1360 
1361  invert_m3_m3(mask_to_clip_matrix, mask_from_clip_matrix);
1362  mul_m3_series(parent_matrix, mask_from_clip_matrix, H, mask_to_clip_matrix);
1363  }
1364  }
1365  }
1366  }
1367  }
1368 }
1369 
1371  MaskSplinePoint *point_prev,
1372  MaskSplinePoint *point_next)
1373 {
1374  BezTriple *bezt = &point->bezt;
1375  BezTriple *bezt_prev = NULL, *bezt_next = NULL;
1376  // int handle_type = bezt->h1;
1377 
1378  if (point_prev) {
1379  bezt_prev = &point_prev->bezt;
1380  }
1381 
1382  if (point_next) {
1383  bezt_next = &point_next->bezt;
1384  }
1385 
1386 #if 1
1387  if (bezt_prev || bezt_next) {
1388  BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0, 0);
1389  }
1390 #else
1391  if (handle_type == HD_VECT) {
1392  BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0, 0);
1393  }
1394  else if (handle_type == HD_AUTO) {
1395  BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0, 0);
1396  }
1397  else if (handle_type == HD_ALIGN || handle_type == HD_ALIGN_DOUBLESIDE) {
1398  float v1[3], v2[3];
1399  float vec[3], h[3];
1400 
1401  sub_v3_v3v3(v1, bezt->vec[0], bezt->vec[1]);
1402  sub_v3_v3v3(v2, bezt->vec[2], bezt->vec[1]);
1403  add_v3_v3v3(vec, v1, v2);
1404 
1405  if (len_squared_v3(vec) > (1e-3f * 1e-3f)) {
1406  h[0] = vec[1];
1407  h[1] = -vec[0];
1408  h[2] = 0.0f;
1409  }
1410  else {
1411  copy_v3_v3(h, v1);
1412  }
1413 
1414  add_v3_v3v3(bezt->vec[0], bezt->vec[1], h);
1415  sub_v3_v3v3(bezt->vec[2], bezt->vec[1], h);
1416  }
1417 #endif
1418 }
1419 
1421  MaskSplinePoint *point,
1422  MaskSplinePoint **r_point_prev,
1423  MaskSplinePoint **r_point_next)
1424 {
1425  /* TODO, could avoid calling this at such low level */
1426  MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
1427 
1428  *r_point_prev = mask_spline_point_prev(spline, points_array, point);
1429  *r_point_next = mask_spline_point_next(spline, points_array, point);
1430 }
1431 
1432 /* calculates the tangent of a point by its previous and next
1433  * (ignoring handles - as if its a poly line) */
1435 {
1436  float tvec_a[2], tvec_b[2];
1437 
1438  MaskSplinePoint *point_prev, *point_next;
1439 
1440  BKE_mask_get_handle_point_adjacent(spline, point, &point_prev, &point_next);
1441 
1442  if (point_prev) {
1443  sub_v2_v2v2(tvec_a, point->bezt.vec[1], point_prev->bezt.vec[1]);
1444  normalize_v2(tvec_a);
1445  }
1446  else {
1447  zero_v2(tvec_a);
1448  }
1449 
1450  if (point_next) {
1451  sub_v2_v2v2(tvec_b, point_next->bezt.vec[1], point->bezt.vec[1]);
1452  normalize_v2(tvec_b);
1453  }
1454  else {
1455  zero_v2(tvec_b);
1456  }
1457 
1458  add_v2_v2v2(t, tvec_a, tvec_b);
1459  normalize_v2(t);
1460 }
1461 
1463 {
1464  MaskSplinePoint *point_prev, *point_next;
1465 
1466  BKE_mask_get_handle_point_adjacent(spline, point, &point_prev, &point_next);
1467 
1468  mask_calc_point_handle(point, point_prev, point_next);
1469 }
1470 
1472  MaskSplinePoint *point,
1473  const float u)
1474 {
1475  /* TODO! - make this interpolate between siblings - not always midpoint! */
1476  int length_tot = 0;
1477  float length_average = 0.0f;
1478  float weight_average = 0.0f;
1479 
1480  MaskSplinePoint *point_prev, *point_next;
1481 
1482  BLI_assert(u >= 0.0f && u <= 1.0f);
1483 
1484  BKE_mask_get_handle_point_adjacent(spline, point, &point_prev, &point_next);
1485 
1486  if (point_prev && point_next) {
1487  length_average = ((len_v2v2(point_prev->bezt.vec[0], point_prev->bezt.vec[1]) * (1.0f - u)) +
1488  (len_v2v2(point_next->bezt.vec[2], point_next->bezt.vec[1]) * u));
1489 
1490  weight_average = (point_prev->bezt.weight * (1.0f - u) + point_next->bezt.weight * u);
1491  length_tot = 1;
1492  }
1493  else {
1494  if (point_prev) {
1495  length_average += len_v2v2(point_prev->bezt.vec[0], point_prev->bezt.vec[1]);
1496  weight_average += point_prev->bezt.weight;
1497  length_tot++;
1498  }
1499 
1500  if (point_next) {
1501  length_average += len_v2v2(point_next->bezt.vec[2], point_next->bezt.vec[1]);
1502  weight_average += point_next->bezt.weight;
1503  length_tot++;
1504  }
1505  }
1506 
1507  if (length_tot) {
1508  length_average /= (float)length_tot;
1509  weight_average /= (float)length_tot;
1510 
1511  dist_ensure_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
1512  dist_ensure_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
1513  point->bezt.weight = weight_average;
1514  }
1515 }
1516 
1523  MaskSplinePoint *point,
1524  const bool do_recalc_length)
1525 {
1526  MaskSplinePoint *point_prev, *point_next;
1527  const char h_back[2] = {point->bezt.h1, point->bezt.h2};
1528  const float length_average = (do_recalc_length) ?
1529  0.0f /* dummy value */ :
1530  (len_v3v3(point->bezt.vec[0], point->bezt.vec[1]) +
1531  len_v3v3(point->bezt.vec[1], point->bezt.vec[2])) /
1532  2.0f;
1533 
1534  BKE_mask_get_handle_point_adjacent(spline, point, &point_prev, &point_next);
1535 
1536  point->bezt.h1 = HD_AUTO;
1537  point->bezt.h2 = HD_AUTO;
1538  mask_calc_point_handle(point, point_prev, point_next);
1539 
1540  point->bezt.h1 = h_back[0];
1541  point->bezt.h2 = h_back[1];
1542 
1543  /* preserve length by applying it back */
1544  if (do_recalc_length == false) {
1545  dist_ensure_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
1546  dist_ensure_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
1547  }
1548 }
1549 
1551 {
1552  MaskSpline *spline;
1553  for (spline = masklay->splines.first; spline; spline = spline->next) {
1554  for (int i = 0; i < spline->tot_point; i++) {
1555  BKE_mask_calc_handle_point(spline, &spline->points[i]);
1556  }
1557  }
1558 }
1559 
1561 {
1562  int allocated_points = (MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform));
1563  // printf("SPLINE ALLOC %p %d\n", spline->points_deform, allocated_points);
1564 
1565  if (spline->points_deform == NULL || allocated_points != spline->tot_point) {
1566  // printf("alloc new deform spline\n");
1567 
1568  if (spline->points_deform) {
1569  for (int i = 0; i < allocated_points; i++) {
1570  MaskSplinePoint *point = &spline->points_deform[i];
1571  BKE_mask_point_free(point);
1572  }
1573 
1574  MEM_freeN(spline->points_deform);
1575  }
1576 
1577  spline->points_deform = MEM_callocN(sizeof(*spline->points_deform) * spline->tot_point,
1578  __func__);
1579  }
1580  else {
1581  // printf("alloc spline done\n");
1582  }
1583 }
1584 
1585 void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool do_newframe)
1586 {
1587  /* Animation if available. */
1588  if (do_newframe) {
1589  BKE_mask_layer_evaluate_animation(masklay, ctime);
1590  }
1591  /* Update deform. */
1592  BKE_mask_layer_evaluate_deform(masklay, ctime);
1593 }
1594 
1595 void BKE_mask_evaluate(Mask *mask, const float ctime, const bool do_newframe)
1596 {
1597  MaskLayer *masklay;
1598 
1599  for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
1600  BKE_mask_layer_evaluate(masklay, ctime, do_newframe);
1601  }
1602 }
1603 
1605 {
1606  parent->id_type = ID_MC;
1607 }
1608 
1609 /* *** own animation/shapekey implementation ***
1610  * BKE_mask_layer_shape_XXX */
1611 
1613 {
1614  int tot = 0;
1615  MaskSpline *spline;
1616 
1617  for (spline = masklay->splines.first; spline; spline = spline->next) {
1618  tot += spline->tot_point;
1619  }
1620 
1621  return tot;
1622 }
1623 
1625  float fp[MASK_OBJECT_SHAPE_ELEM_SIZE])
1626 {
1627  copy_v2_v2(&fp[0], bezt->vec[0]);
1628  copy_v2_v2(&fp[2], bezt->vec[1]);
1629  copy_v2_v2(&fp[4], bezt->vec[2]);
1630  fp[6] = bezt->weight;
1631  fp[7] = bezt->radius;
1632 }
1633 
1635  const float fp[MASK_OBJECT_SHAPE_ELEM_SIZE])
1636 {
1637  copy_v2_v2(bezt->vec[0], &fp[0]);
1638  copy_v2_v2(bezt->vec[1], &fp[2]);
1639  copy_v2_v2(bezt->vec[2], &fp[4]);
1640  bezt->weight = fp[6];
1641  bezt->radius = fp[7];
1642 }
1643 
1644 /* these functions match. copy is swapped */
1646 {
1647  int tot = BKE_mask_layer_shape_totvert(masklay);
1648 
1649  if (masklay_shape->tot_vert == tot) {
1650  float *fp = masklay_shape->data;
1651 
1652  MaskSpline *spline;
1653  for (spline = masklay->splines.first; spline; spline = spline->next) {
1654  for (int i = 0; i < spline->tot_point; i++) {
1655  mask_layer_shape_from_mask_point(&spline->points[i].bezt, fp);
1657  }
1658  }
1659  }
1660  else {
1661  CLOG_ERROR(&LOG,
1662  "vert mismatch %d != %d (frame %d)",
1663  masklay_shape->tot_vert,
1664  tot,
1665  masklay_shape->frame);
1666  }
1667 }
1668 
1670 {
1671  int tot = BKE_mask_layer_shape_totvert(masklay);
1672 
1673  if (masklay_shape->tot_vert == tot) {
1674  float *fp = masklay_shape->data;
1675 
1676  MaskSpline *spline;
1677  for (spline = masklay->splines.first; spline; spline = spline->next) {
1678  for (int i = 0; i < spline->tot_point; i++) {
1679  mask_layer_shape_to_mask_point(&spline->points[i].bezt, fp);
1681  }
1682  }
1683  }
1684  else {
1685  CLOG_ERROR(&LOG,
1686  "vert mismatch %d != %d (frame %d)",
1687  masklay_shape->tot_vert,
1688  tot,
1689  masklay_shape->frame);
1690  }
1691 }
1692 
1694  float target[2], const float a[2], const float b[2], const float t, const float s)
1695 {
1696  target[0] = s * a[0] + t * b[0];
1697  target[1] = s * a[1] + t * b[1];
1698 }
1699 
1700 /* linear interpolation only */
1702  MaskLayerShape *masklay_shape_a,
1703  MaskLayerShape *masklay_shape_b,
1704  const float fac)
1705 {
1706  int tot = BKE_mask_layer_shape_totvert(masklay);
1707  if (masklay_shape_a->tot_vert == tot && masklay_shape_b->tot_vert == tot) {
1708  const float *fp_a = masklay_shape_a->data;
1709  const float *fp_b = masklay_shape_b->data;
1710  const float ifac = 1.0f - fac;
1711 
1712  MaskSpline *spline;
1713  for (spline = masklay->splines.first; spline; spline = spline->next) {
1714  for (int i = 0; i < spline->tot_point; i++) {
1715  BezTriple *bezt = &spline->points[i].bezt;
1716  /* *** BKE_mask_layer_shape_from_mask - swapped *** */
1717  interp_v2_v2v2_flfl(bezt->vec[0], fp_a, fp_b, fac, ifac);
1718  fp_a += 2;
1719  fp_b += 2;
1720  interp_v2_v2v2_flfl(bezt->vec[1], fp_a, fp_b, fac, ifac);
1721  fp_a += 2;
1722  fp_b += 2;
1723  interp_v2_v2v2_flfl(bezt->vec[2], fp_a, fp_b, fac, ifac);
1724  fp_a += 2;
1725  fp_b += 2;
1726  bezt->weight = (fp_a[0] * ifac) + (fp_b[0] * fac);
1727  bezt->radius = (fp_a[1] * ifac) + (fp_b[1] * fac);
1728  fp_a += 2;
1729  fp_b += 2;
1730  }
1731  }
1732  }
1733  else {
1734  CLOG_ERROR(&LOG,
1735  "vert mismatch %d != %d != %d (frame %d - %d)",
1736  masklay_shape_a->tot_vert,
1737  masklay_shape_b->tot_vert,
1738  tot,
1739  masklay_shape_a->frame,
1740  masklay_shape_b->frame);
1741  }
1742 }
1743 
1745 {
1746  MaskLayerShape *masklay_shape;
1747 
1748  for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
1749  masklay_shape = masklay_shape->next) {
1750  if (frame == masklay_shape->frame) {
1751  return masklay_shape;
1752  }
1753  if (frame < masklay_shape->frame) {
1754  break;
1755  }
1756  }
1757 
1758  return NULL;
1759 }
1760 
1765  const float frame,
1766  MaskLayerShape **r_masklay_shape_a,
1767  MaskLayerShape **r_masklay_shape_b)
1768 {
1769  MaskLayerShape *masklay_shape;
1770 
1771  for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
1772  masklay_shape = masklay_shape->next) {
1773  if (frame == masklay_shape->frame) {
1774  *r_masklay_shape_a = masklay_shape;
1775  *r_masklay_shape_b = NULL;
1776  return 1;
1777  }
1778  if (frame < masklay_shape->frame) {
1779  if (masklay_shape->prev) {
1780  *r_masklay_shape_a = masklay_shape->prev;
1781  *r_masklay_shape_b = masklay_shape;
1782  return 2;
1783  }
1784 
1785  *r_masklay_shape_a = masklay_shape;
1786  *r_masklay_shape_b = NULL;
1787  return 1;
1788  }
1789  }
1790 
1791  if ((masklay_shape = masklay->splines_shapes.last)) {
1792  *r_masklay_shape_a = masklay_shape;
1793  *r_masklay_shape_b = NULL;
1794  return 1;
1795  }
1796 
1797  *r_masklay_shape_a = NULL;
1798  *r_masklay_shape_b = NULL;
1799 
1800  return 0;
1801 }
1802 
1804 {
1805  MaskLayerShape *masklay_shape;
1806 
1807  masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame);
1808 
1809  if (masklay_shape == NULL) {
1810  masklay_shape = BKE_mask_layer_shape_alloc(masklay, frame);
1811  BLI_addtail(&masklay->splines_shapes, masklay_shape);
1812  BKE_mask_layer_shape_sort(masklay);
1813  }
1814 
1815  return masklay_shape;
1816 }
1817 
1819 {
1820  MaskLayerShape *masklay_shape_copy;
1821 
1822  masklay_shape_copy = MEM_dupallocN(masklay_shape);
1823 
1824  if (LIKELY(masklay_shape_copy->data)) {
1825  masklay_shape_copy->data = MEM_dupallocN(masklay_shape_copy->data);
1826  }
1827 
1828  return masklay_shape_copy;
1829 }
1830 
1832 {
1833  BLI_remlink(&masklay->splines_shapes, masklay_shape);
1834 
1835  BKE_mask_layer_shape_free(masklay_shape);
1836 }
1837 
1838 static int mask_layer_shape_sort_cb(const void *masklay_shape_a_ptr,
1839  const void *masklay_shape_b_ptr)
1840 {
1841  const MaskLayerShape *masklay_shape_a = masklay_shape_a_ptr;
1842  const MaskLayerShape *masklay_shape_b = masklay_shape_b_ptr;
1843 
1844  if (masklay_shape_a->frame < masklay_shape_b->frame) {
1845  return -1;
1846  }
1847  if (masklay_shape_a->frame > masklay_shape_b->frame) {
1848  return 1;
1849  }
1850 
1851  return 0;
1852 }
1853 
1855 {
1857 }
1858 
1860  int index,
1861  MaskSpline **r_masklay_shape,
1862  int *r_index)
1863 {
1864  MaskSpline *spline;
1865 
1866  for (spline = masklay->splines.first; spline; spline = spline->next) {
1867  if (index < spline->tot_point) {
1868  *r_masklay_shape = spline;
1869  *r_index = index;
1870  return true;
1871  }
1872  index -= spline->tot_point;
1873  }
1874 
1875  return false;
1876 }
1877 
1879 {
1880  MaskSpline *spline_iter;
1881  int i_abs = 0;
1882  for (spline_iter = masklay->splines.first; spline_iter && spline_iter != spline;
1883  i_abs += spline_iter->tot_point, spline_iter = spline_iter->next) {
1884  /* pass */
1885  }
1886 
1887  return i_abs;
1888 }
1889 
1890 /* basic 2D interpolation functions, could make more comprehensive later */
1891 static void interp_weights_uv_v2_calc(float r_uv[2],
1892  const float pt[2],
1893  const float pt_a[2],
1894  const float pt_b[2])
1895 {
1896  const float segment_len = len_v2v2(pt_a, pt_b);
1897  if (segment_len == 0.0f) {
1898  r_uv[0] = 1.0f;
1899  r_uv[1] = 0.0f;
1900  return;
1901  }
1902 
1903  float pt_on_line[2];
1904  r_uv[0] = closest_to_line_v2(pt_on_line, pt, pt_a, pt_b);
1905 
1906  r_uv[1] = (len_v2v2(pt_on_line, pt) / segment_len) *
1907  /* This line only sets the sign. */
1908  ((line_point_side_v2(pt_a, pt_b, pt) < 0.0f) ? -1.0f : 1.0f);
1909 }
1910 
1911 static void interp_weights_uv_v2_apply(const float uv[2],
1912  float r_pt[2],
1913  const float pt_a[2],
1914  const float pt_b[2])
1915 {
1916  const float dvec[2] = {pt_b[0] - pt_a[0], pt_b[1] - pt_a[1]};
1917 
1918  /* u */
1919  madd_v2_v2v2fl(r_pt, pt_a, dvec, uv[0]);
1920 
1921  /* v */
1922  r_pt[0] += -dvec[1] * uv[1];
1923  r_pt[1] += dvec[0] * uv[1];
1924 }
1925 
1926 /* when a new points added - resize all shapekey array */
1928  int index,
1929  bool do_init,
1930  bool do_init_interpolate)
1931 {
1932  MaskLayerShape *masklay_shape;
1933 
1934  /* spline index from masklay */
1935  MaskSpline *spline;
1936  int spline_point_index;
1937 
1938  if (BKE_mask_layer_shape_spline_from_index(masklay, index, &spline, &spline_point_index)) {
1939  /* sanity check */
1940  /* The point has already been removed in this array
1941  * so subtract one when comparing with the shapes. */
1942  int tot = BKE_mask_layer_shape_totvert(masklay) - 1;
1943 
1944  /* for interpolation */
1945  /* TODO - assumes closed curve for now */
1946  float uv[3][2]; /* 3x 2D handles */
1947  const int pi_curr = spline_point_index;
1948  const int pi_prev = ((spline_point_index - 1) + spline->tot_point) % spline->tot_point;
1949  const int pi_next = (spline_point_index + 1) % spline->tot_point;
1950 
1951  const int index_offset = index - spline_point_index;
1952  /* const int pi_curr_abs = index; */
1953  const int pi_prev_abs = pi_prev + index_offset;
1954  const int pi_next_abs = pi_next + index_offset;
1955 
1956  if (do_init_interpolate) {
1957  for (int i = 0; i < 3; i++) {
1959  spline->points[pi_curr].bezt.vec[i],
1960  spline->points[pi_prev].bezt.vec[i],
1961  spline->points[pi_next].bezt.vec[i]);
1962  }
1963  }
1964 
1965  for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
1966  masklay_shape = masklay_shape->next) {
1967  if (tot == masklay_shape->tot_vert) {
1968  float *data_resized;
1969 
1970  masklay_shape->tot_vert++;
1971  data_resized = MEM_mallocN(
1972  masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__);
1973  if (index > 0) {
1974  memcpy(data_resized,
1975  masklay_shape->data,
1976  index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE);
1977  }
1978 
1979  if (index != masklay_shape->tot_vert - 1) {
1980  memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE],
1981  masklay_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE),
1982  (masklay_shape->tot_vert - (index + 1)) * sizeof(float) *
1984  }
1985 
1986  if (do_init) {
1987  float *fp = &data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE];
1988 
1989  mask_layer_shape_from_mask_point(&spline->points[spline_point_index].bezt, fp);
1990 
1991  if (do_init_interpolate && spline->tot_point > 2) {
1992  for (int i = 0; i < 3; i++) {
1994  uv[i],
1995  &fp[i * 2],
1996  &data_resized[(pi_prev_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)],
1997  &data_resized[(pi_next_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)]);
1998  }
1999  }
2000  }
2001  else {
2002  memset(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE],
2003  0,
2004  sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE);
2005  }
2006 
2007  MEM_freeN(masklay_shape->data);
2008  masklay_shape->data = data_resized;
2009  }
2010  else {
2011  CLOG_ERROR(&LOG,
2012  "vert mismatch %d != %d (frame %d)",
2013  masklay_shape->tot_vert,
2014  tot,
2015  masklay_shape->frame);
2016  }
2017  }
2018  }
2019 }
2020 
2021 /* move array to account for removed point */
2023 {
2024  MaskLayerShape *masklay_shape;
2025 
2026  /* the point has already been removed in this array so add one when comparing with the shapes */
2027  int tot = BKE_mask_layer_shape_totvert(masklay);
2028 
2029  for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
2030  masklay_shape = masklay_shape->next) {
2031  if (tot == masklay_shape->tot_vert - count) {
2032  float *data_resized;
2033 
2034  masklay_shape->tot_vert -= count;
2035  data_resized = MEM_mallocN(
2036  masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__);
2037  if (index > 0) {
2038  memcpy(data_resized,
2039  masklay_shape->data,
2040  index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE);
2041  }
2042 
2043  if (index != masklay_shape->tot_vert) {
2044  memcpy(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE],
2045  masklay_shape->data + ((index + count) * MASK_OBJECT_SHAPE_ELEM_SIZE),
2046  (masklay_shape->tot_vert - index) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE);
2047  }
2048 
2049  MEM_freeN(masklay_shape->data);
2050  masklay_shape->data = data_resized;
2051  }
2052  else {
2053  CLOG_ERROR(&LOG,
2054  "vert mismatch %d != %d (frame %d)",
2055  masklay_shape->tot_vert - count,
2056  tot,
2057  masklay_shape->frame);
2058  }
2059  }
2060 }
2061 
2063 {
2064  return max_ii(1, mask->efra - mask->sfra);
2065 }
2066 
2067 /*********************** clipboard *************************/
2068 
2069 static void mask_clipboard_free_ex(bool final_free)
2070 {
2073  if (mask_clipboard.id_hash) {
2074  if (final_free) {
2076  }
2077  else {
2079  }
2080  }
2081 }
2082 
2083 /* Free the clipboard. */
2085 {
2086  mask_clipboard_free_ex(true);
2087 }
2088 
2089 /* Copy selected visible splines from the given layer to clipboard. */
2091 {
2092  MaskSpline *spline;
2093 
2094  /* Nothing to do if selection if disabled for the given layer. */
2095  if (mask_layer->restrictflag & MASK_RESTRICT_SELECT) {
2096  return;
2097  }
2098 
2099  mask_clipboard_free_ex(false);
2100  if (mask_clipboard.id_hash == NULL) {
2101  mask_clipboard.id_hash = BLI_ghash_ptr_new("mask clipboard ID hash");
2102  }
2103 
2104  for (spline = mask_layer->splines.first; spline; spline = spline->next) {
2105  if (spline->flag & SELECT) {
2106  MaskSpline *spline_new = BKE_mask_spline_copy(spline);
2107  for (int i = 0; i < spline_new->tot_point; i++) {
2108  MaskSplinePoint *point = &spline_new->points[i];
2109  if (point->parent.id) {
2110  if (!BLI_ghash_lookup(mask_clipboard.id_hash, point->parent.id)) {
2111  int len = strlen(point->parent.id->name);
2112  char *name_copy = MEM_mallocN(len + 1, "mask clipboard ID name");
2113  strcpy(name_copy, point->parent.id->name);
2114  BLI_ghash_insert(mask_clipboard.id_hash, point->parent.id, name_copy);
2115  }
2116  }
2117  }
2118 
2119  BLI_addtail(&mask_clipboard.splines, spline_new);
2120  }
2121  }
2122 }
2123 
2124 /* Check clipboard is empty. */
2126 {
2127  return BLI_listbase_is_empty(&mask_clipboard.splines);
2128 }
2129 
2130 /* Paste the contents of clipboard to given mask layer */
2132 {
2133  MaskSpline *spline;
2134 
2135  for (spline = mask_clipboard.splines.first; spline; spline = spline->next) {
2136  MaskSpline *spline_new = BKE_mask_spline_copy(spline);
2137 
2138  for (int i = 0; i < spline_new->tot_point; i++) {
2139  MaskSplinePoint *point = &spline_new->points[i];
2140  if (point->parent.id) {
2141  const char *id_name = BLI_ghash_lookup(mask_clipboard.id_hash, point->parent.id);
2142  ListBase *listbase;
2143 
2144  BLI_assert(id_name != NULL);
2145 
2146  listbase = which_libbase(bmain, GS(id_name));
2147  point->parent.id = BLI_findstring(listbase, id_name + 2, offsetof(ID, name) + 2);
2148  }
2149  }
2150 
2151  BLI_addtail(&mask_layer->splines, spline_new);
2152  }
2153 }
typedef float(TangentPoint)[2]
void BKE_animdata_blend_write(struct BlendWriter *writer, struct AnimData *adt)
Definition: anim_data.c:1552
void BKE_animdata_fix_paths_rename_all(struct ID *ref_id, const char *prefix, const char *oldName, const char *newName)
Definition: anim_data.c:1414
void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next, const bool is_fcurve, const char smoothing)
Definition: curve.c:4069
void BKE_image_get_size_fl(struct Image *image, struct ImageUser *iuser, float r_size[2])
Definition: image.c:5535
void BKE_image_get_aspect(struct Image *image, float *r_aspx, float *r_aspy)
Definition: image.c:5544
void id_fake_user_set(struct ID *id)
Definition: lib_id.c:328
void * BKE_libblock_alloc(struct Main *bmain, short type, const char *name, const int flag) ATTR_WARN_UNUSED_RESULT
Definition: lib_id.c:1062
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
Definition: lib_id.c:2395
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag)
struct ListBase * which_libbase(struct Main *bmain, short type)
Definition: main.c:447
eMaskhandleMode
Definition: BKE_mask.h:54
@ MASK_HANDLE_MODE_INDIVIDUAL_HANDLES
Definition: BKE_mask.h:56
@ MASK_HANDLE_MODE_STICK
Definition: BKE_mask.h:55
void BKE_mask_layer_evaluate_animation(struct MaskLayer *masklay, const float ctime)
eMaskWhichHandle
Definition: BKE_mask.h:46
@ MASK_WHICH_HANDLE_BOTH
Definition: BKE_mask.h:51
@ 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_SEL_ALL(p)
Definition: BKE_mask.h:241
void BKE_mask_layer_evaluate_deform(struct MaskLayer *masklay, const float ctime)
eMaskSign
Definition: BKE_mask.h:96
@ MASK_PROJ_ANY
Definition: BKE_mask.h:98
@ MASK_PROJ_NEG
Definition: BKE_mask.h:97
@ MASK_PROJ_POS
Definition: BKE_mask.h:99
#define MASKPOINT_DESEL_ALL(p)
Definition: BKE_mask.h:248
void BKE_movieclip_get_aspect(struct MovieClip *clip, float *aspx, float *aspy)
Definition: movieclip.c:1608
float BKE_movieclip_remap_scene_to_clip_frame(const struct MovieClip *clip, float framenr)
void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr)
Definition: movieclip.c:1633
void BKE_movieclip_get_size_fl(struct MovieClip *clip, struct MovieClipUser *user, float size[2])
Definition: movieclip.c:1573
struct MovieTrackingTrack * BKE_tracking_track_get_named(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name)
Definition: tracking.c:1119
struct MovieTrackingPlaneTrack * BKE_tracking_plane_track_get_named(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name)
Definition: tracking.c:1806
struct MovieTrackingObject * BKE_tracking_object_get_named(struct MovieTracking *tracking, const char *name)
Definition: tracking.c:2183
void BKE_tracking_plane_marker_get_subframe_corners(struct MovieTrackingPlaneTrack *plane_track, float framenr, float corners[4][2])
Definition: tracking.c:2075
void BKE_tracking_marker_get_subframe_position(struct MovieTrackingTrack *track, float framenr, float pos[2])
Definition: tracking.c:1674
void BKE_tracking_homography_between_two_quads(float reference_corners[4][2], float corners[4][2], float H[3][3])
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
void BLI_endian_switch_float_array(float *val, const int size) ATTR_NONNULL(1)
Definition: endian_switch.c:65
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:996
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
bool BLI_remlink_safe(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:159
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
#define M_PI
Definition: BLI_math_base.h:38
float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
Definition: math_geom.c:3371
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1161
#define mul_m3_series(...)
MINLINE float len_squared_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
float angle_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:483
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
void dist_ensure_v2_v2fl(float v1[2], const float v2[2], const float dist)
Definition: math_vector.c:1079
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v2(float r[2])
MINLINE float dot_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v2(float r[2])
void interp_v2_v2v2v2v2_cubic(float p[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2], const float u)
Definition: math_vector.c:168
void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2])
Definition: math_vector.c:658
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t len)
Definition: string_utils.c:381
#define SWAP(type, a, b)
#define UNUSED(x)
#define ELEM(...)
#define LIKELY(x)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5654
void BLO_write_float_array(BlendWriter *writer, uint num, const float *data_ptr)
Definition: writefile.c:1378
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define BLO_expand(expander, id)
bool BLO_read_requires_endian_switch(BlendDataReader *reader)
Definition: readfile.c:5620
bool BLO_write_is_undo(BlendWriter *writer)
Definition: writefile.c:1412
#define DATA_(msgid)
#define BLT_I18NCONTEXT_ID_MASK
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:204
void DEG_relations_tag_update(struct Main *bmain)
#define MAX_ID_NAME
Definition: DNA_ID.h:269
#define FILTER_ID_MSK
Definition: DNA_ID.h:720
@ INDEX_ID_MSK
Definition: DNA_ID.h:807
@ ID_MC
Definition: DNA_ID_enums.h:85
@ ID_MSK
Definition: DNA_ID_enums.h:86
@ HD_VECT
@ HD_AUTO
@ HD_ALIGN_DOUBLESIDE
@ HD_ALIGN
@ MASK_LAYERFLAG_FILL_OVERLAP
@ MASK_LAYERFLAG_FILL_DISCRETE
@ MASK_PARENT_POINT_TRACK
#define MASK_RESTRICT_SELECT
@ MASK_BLEND_MERGE_ADD
#define MASK_OBJECT_SHAPE_ELEM_SIZE
@ MASK_SPLINE_INTERP_EASE
struct Mask Mask
@ MASK_SPLINE_CYCLIC
_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 u2
_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 u1
_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
_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 v1
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
static void init_data(ModifierData *md)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
std::string id_name(void *id)
#define SELECT
int count
#define GS(x)
Definition: iris.c:241
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:40
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static void mask_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition: mask.c:101
void BKE_mask_layer_shape_unlink(MaskLayer *masklay, MaskLayerShape *masklay_shape)
Definition: mask.c:1831
void BKE_mask_coord_from_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2])
Definition: mask.c:1219
void BKE_mask_calc_handle_point(MaskSpline *spline, MaskSplinePoint *point)
Definition: mask.c:1462
static MaskSplinePoint * mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
Definition: mask.c:283
void BKE_mask_layer_calc_handles(MaskLayer *masklay)
Definition: mask.c:1550
void BKE_mask_layer_shape_from_mask(MaskLayer *masklay, MaskLayerShape *masklay_shape)
Definition: mask.c:1645
MaskLayer * BKE_mask_layer_active(Mask *mask)
Definition: mask.c:376
float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const float u)
Definition: mask.c:873
static void expand_mask_parent(BlendExpander *expander, MaskParent *parent)
Definition: mask.c:228
static void mask_layer_shape_to_mask_point(BezTriple *bezt, const float fp[MASK_OBJECT_SHAPE_ELEM_SIZE])
Definition: mask.c:1634
static int mask_layer_shape_sort_cb(const void *masklay_shape_a_ptr, const void *masklay_shape_b_ptr)
Definition: mask.c:1838
MaskSpline * BKE_mask_spline_copy(const MaskSpline *spline)
Definition: mask.c:1120
static void mask_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int UNUSED(flag))
Definition: mask.c:62
void BKE_mask_calc_handle_adjacent_interp(MaskSpline *spline, MaskSplinePoint *point, const float u)
Definition: mask.c:1471
Mask * BKE_mask_new(Main *bmain, const char *name)
Definition: mask.c:1038
static void lib_link_mask_parent(BlendLibReader *reader, Mask *mask, MaskParent *parent)
Definition: mask.c:202
BezTriple * BKE_mask_spline_point_next_bezt(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
Definition: mask.c:313
static void mask_foreach_id(ID *id, LibraryForeachIDData *data)
Definition: mask.c:87
void BKE_mask_get_handle_point_adjacent(MaskSpline *spline, MaskSplinePoint *point, MaskSplinePoint **r_point_prev, MaskSplinePoint **r_point_next)
Definition: mask.c:1420
void BKE_mask_layer_unique_name(Mask *mask, MaskLayer *masklay)
Definition: mask.c:398
MaskSplinePoint * BKE_mask_spline_point_array(MaskSpline *spline)
Definition: mask.c:328
static MaskSplinePoint * mask_spline_point_prev(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
Definition: mask.c:298
ListBase splines
Definition: mask.c:279
MaskLayerShape * BKE_mask_layer_shape_alloc(MaskLayer *masklay, const int frame)
Definition: mask.c:1137
void BKE_mask_layer_rename(Mask *mask, MaskLayer *masklay, char *oldname, char *newname)
Definition: mask.c:408
void BKE_mask_point_add_uw(MaskSplinePoint *point, float u, float w)
Definition: mask.c:953
void BKE_mask_clipboard_paste_to_layer(Main *bmain, MaskLayer *mask_layer)
Definition: mask.c:2131
BLI_INLINE void interp_v2_v2v2_flfl(float target[2], const float a[2], const float b[2], const float t, const float s)
Definition: mask.c:1693
void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u, float n[2])
Definition: mask.c:795
void BKE_mask_layer_shape_changed_remove(MaskLayer *masklay, int index, int count)
Definition: mask.c:2022
void BKE_mask_layer_free_list(ListBase *masklayers)
Definition: mask.c:1189
void BKE_mask_spline_direction_switch(MaskLayer *masklay, MaskSpline *spline)
Definition: mask.c:550
bool BKE_mask_spline_remove(MaskLayer *mask_layer, MaskSpline *spline)
Definition: mask.c:508
static void interp_weights_uv_v2_apply(const float uv[2], float r_pt[2], const float pt_a[2], const float pt_b[2])
Definition: mask.c:1911
void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const eMaskWhichHandle which_handle, const bool do_select)
Definition: mask.c:990
int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay, const float frame, MaskLayerShape **r_masklay_shape_a, MaskLayerShape **r_masklay_shape_b)
Definition: mask.c:1764
MaskSpline * BKE_mask_spline_add(MaskLayer *masklay)
Definition: mask.c:484
void BKE_mask_layer_shape_sort(MaskLayer *masklay)
Definition: mask.c:1854
void BKE_mask_point_select_set(MaskSplinePoint *point, const bool do_select)
Definition: mask.c:971
void BKE_mask_parent_init(MaskParent *parent)
Definition: mask.c:1604
eMaskhandleMode BKE_mask_point_handles_mode_get(const MaskSplinePoint *point)
Definition: mask.c:678
void BKE_mask_point_handle(const MaskSplinePoint *point, eMaskWhichHandle which_handle, float r_handle[2])
Definition: mask.c:689
MaskSplinePointUW * BKE_mask_point_sort_uw(MaskSplinePoint *point, MaskSplinePointUW *uw)
Definition: mask.c:928
static void mask_blend_read_data(BlendDataReader *reader, ID *id)
Definition: mask.c:150
MaskLayerShape * BKE_mask_layer_shape_verify_frame(MaskLayer *masklay, const int frame)
Definition: mask.c:1803
void BKE_mask_layer_copy_list(ListBase *masklayers_new, const ListBase *masklayers)
Definition: mask.c:471
struct GHash * id_hash
Definition: mask.c:280
void BKE_mask_layer_shape_to_mask_interp(MaskLayer *masklay, MaskLayerShape *masklay_shape_a, MaskLayerShape *masklay_shape_b, const float fac)
Definition: mask.c:1701
void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float u, float co[2])
Definition: mask.c:767
void BKE_mask_coord_to_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2])
Definition: mask.c:1283
bool BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index, MaskSpline **r_masklay_shape, int *r_index)
Definition: mask.c:1859
void BKE_mask_point_set_handle(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_parent_matrix_get(MaskSplinePoint *point, float ctime, float parent_matrix[3][3])
Definition: mask.c:1297
static void mask_layer_shape_from_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE])
Definition: mask.c:1624
float BKE_mask_point_weight_scalar(MaskSpline *spline, MaskSplinePoint *point, const float u)
Definition: mask.c:853
void BKE_mask_coord_to_frame(float r_co[2], const float co[2], const float frame_size[2])
Definition: mask.c:1250
MaskLayerShape * BKE_mask_layer_shape_duplicate(MaskLayerShape *masklay_shape)
Definition: mask.c:1818
void BKE_mask_layer_free(MaskLayer *masklay)
Definition: mask.c:1178
void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2])
Definition: mask.c:1266
MaskSplinePoint * BKE_mask_spline_point_array_from_point(MaskSpline *spline, const MaskSplinePoint *point_ref)
Definition: mask.c:333
void BKE_mask_layer_shape_to_mask(MaskLayer *masklay, MaskLayerShape *masklay_shape)
Definition: mask.c:1669
float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, float start_u, const float co[2], const eMaskSign sign)
Definition: mask.c:598
static float mask_point_interp_weight(BezTriple *bezt, BezTriple *bezt_next, const float u)
Definition: mask.c:848
void BKE_mask_coord_from_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2])
Definition: mask.c:1236
void BKE_mask_layer_remove(Mask *mask, MaskLayer *masklay)
Definition: mask.c:386
int BKE_mask_layer_shape_totvert(MaskLayer *masklay)
Definition: mask.c:1612
static void mask_free_data(ID *id)
Definition: mask.c:79
BLI_INLINE void orthogonal_direction_get(const float vec[2], float result[2])
Definition: mask.c:784
void BKE_mask_layer_shape_free(MaskLayerShape *masklay_shape)
Definition: mask.c:1151
static void mask_blend_read_expand(BlendExpander *expander, ID *id)
Definition: mask.c:235
void BKE_mask_spline_ensure_deform(MaskSpline *spline)
Definition: mask.c:1560
void BKE_mask_spline_free(MaskSpline *spline)
Definition: mask.c:1068
void BKE_mask_layer_free_shapes(MaskLayer *masklay)
Free all animation keys for a mask layer.
Definition: mask.c:1162
int BKE_mask_layer_shape_spline_to_index(MaskLayer *masklay, MaskSpline *spline)
Definition: mask.c:1878
static struct @95 mask_clipboard
static CLG_LogRef LOG
Definition: mask.c:60
static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *point_prev, MaskSplinePoint *point_next)
Definition: mask.c:1370
int BKE_mask_get_duration(Mask *mask)
Definition: mask.c:2062
static void mask_clipboard_free_ex(bool final_free)
Definition: mask.c:2069
void BKE_mask_point_free(MaskSplinePoint *point)
Definition: mask.c:1061
IDTypeInfo IDType_ID_MSK
Definition: mask.c:250
void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool do_newframe)
Definition: mask.c:1585
void BKE_mask_clipboard_free(void)
Definition: mask.c:2084
void BKE_mask_layer_active_set(Mask *mask, MaskLayer *masklay)
Definition: mask.c:381
static void mask_blend_read_lib(BlendLibReader *reader, ID *id)
Definition: mask.c:207
void BKE_mask_point_direction_switch(MaskSplinePoint *point)
Definition: mask.c:519
void BKE_mask_clipboard_copy_from_layer(MaskLayer *mask_layer)
Definition: mask.c:2090
void BKE_mask_spline_free_list(ListBase *splines)
Definition: mask.c:1092
bool BKE_mask_clipboard_is_empty(void)
Definition: mask.c:2125
static MaskSplinePoint * mask_spline_points_copy(const MaskSplinePoint *points, int tot_point)
Definition: mask.c:1105
static Mask * mask_alloc(Main *bmain, const char *name)
Definition: mask.c:1027
MaskLayer * BKE_mask_layer_copy(const MaskLayer *masklay)
Definition: mask.c:418
static void interp_weights_uv_v2_calc(float r_uv[2], const float pt[2], const float pt_a[2], const float pt_b[2])
Definition: mask.c:1891
MaskLayerShape * BKE_mask_layer_shape_find_frame(MaskLayer *masklay, const int frame)
Definition: mask.c:1744
void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2])
Definition: mask.c:1203
void BKE_mask_calc_tangent_polyline(MaskSpline *spline, MaskSplinePoint *point, float t[2])
Definition: mask.c:1434
void BKE_mask_layer_shape_changed_add(MaskLayer *masklay, int index, bool do_init, bool do_init_interpolate)
Definition: mask.c:1927
void BKE_mask_evaluate(Mask *mask, const float ctime, const bool do_newframe)
Definition: mask.c:1595
void BKE_mask_calc_handle_point_auto(MaskSpline *spline, MaskSplinePoint *point, const bool do_recalc_length)
Resets auto handles even for non-auto bezier points.
Definition: mask.c:1522
MaskLayer * BKE_mask_layer_new(Mask *mask, const char *name)
Definition: mask.c:351
static unsigned a[3]
Definition: RandGen.cpp:92
double sign(double arg)
Definition: utility.h:250
params N
unsigned char uint8_t
Definition: stdint.h:81
float vec[3][3]
short id_code
Definition: BKE_idtype.h:120
Definition: DNA_ID.h:273
char name[66]
Definition: DNA_ID.h:283
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
struct MaskLayerShape * prev
struct MaskLayerShape * next
struct MaskLayer * next
ListBase splines_shapes
ListBase splines
struct MaskSplinePoint * act_point
char name[64]
char restrictflag
struct MaskSpline * act_spline
char parent[64]
float parent_orig[2]
float parent_corners_orig[4][2]
char sub_parent[64]
MaskSplinePointUW * uw
MaskParent parent
MaskParent parent
MaskSplinePoint * points_deform
char weight_interp
struct MaskSpline * next
MaskSplinePoint * points
ListBase masklayers
struct MovieTracking tracking
__forceinline const avxi abs(const avxi &a)
Definition: util_avxi.h:186
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
#define H(x, y, z)
uint len