Blender  V2.93
mask_ops.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 "MEM_guardedalloc.h"
25 
26 #include "BLI_listbase.h"
27 #include "BLI_math.h"
28 
29 #include "BKE_context.h"
30 #include "BKE_main.h"
31 #include "BKE_mask.h"
32 
33 #include "DEG_depsgraph.h"
34 #include "DEG_depsgraph_query.h"
35 
36 #include "DNA_mask_types.h"
37 #include "DNA_object_types.h" /* SELECT */
38 #include "DNA_scene_types.h"
39 
40 #include "WM_api.h"
41 #include "WM_types.h"
42 
43 #include "ED_clip.h"
44 #include "ED_image.h"
45 #include "ED_keyframing.h"
46 #include "ED_mask.h"
47 #include "ED_screen.h"
48 #include "ED_select_utils.h"
49 
50 #include "RNA_access.h"
51 #include "RNA_define.h"
52 
53 #include "mask_intern.h" /* own include */
54 
55 /******************** create new mask *********************/
56 
57 Mask *ED_mask_new(bContext *C, const char *name)
58 {
60  Main *bmain = CTX_data_main(C);
61  Mask *mask;
62 
63  mask = BKE_mask_new(bmain, name);
64 
65  if (area && area->spacedata.first) {
66  switch (area->spacetype) {
67  case SPACE_CLIP: {
68  SpaceClip *sc = area->spacedata.first;
70  break;
71  }
72  case SPACE_SEQ: {
73  /* do nothing */
74  break;
75  }
76  case SPACE_IMAGE: {
77  SpaceImage *sima = area->spacedata.first;
79  break;
80  }
81  }
82  }
83 
84  return mask;
85 }
86 
87 /* Get ative layer. Will create mask/layer to be sure there's an active layer. */
88 MaskLayer *ED_mask_layer_ensure(bContext *C, bool *r_added_mask)
89 {
91  MaskLayer *mask_layer;
92 
93  if (mask == NULL) {
94  /* If there's no active mask, create one. */
95  mask = ED_mask_new(C, NULL);
96  *r_added_mask = true;
97  }
98 
99  mask_layer = BKE_mask_layer_active(mask);
100  if (mask_layer == NULL) {
101  /* If there's no active mask layer, create one. */
102  mask_layer = BKE_mask_layer_new(mask, "");
103  }
104 
105  return mask_layer;
106 }
107 
109 {
110  char name[MAX_ID_NAME - 2];
111 
112  RNA_string_get(op->ptr, "name", name);
113 
114  ED_mask_new(C, name);
115 
117 
118  return OPERATOR_FINISHED;
119 }
120 
122 {
123  /* identifiers */
124  ot->name = "New Mask";
125  ot->description = "Create new mask";
126  ot->idname = "MASK_OT_new";
127 
128  /* flags */
130 
131  /* api callbacks */
132  ot->exec = mask_new_exec;
134 
135  /* properties */
136  RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Name of new mask");
137 }
138 
139 /******************** create new mask layer *********************/
140 
142 {
144  char name[MAX_ID_NAME - 2];
145 
146  RNA_string_get(op->ptr, "name", name);
147 
148  BKE_mask_layer_new(mask, name);
149  mask->masklay_act = mask->masklay_tot - 1;
150 
153 
154  return OPERATOR_FINISHED;
155 }
156 
158 {
159  /* identifiers */
160  ot->name = "Add Mask Layer";
161  ot->description = "Add new mask layer for masking";
162  ot->idname = "MASK_OT_layer_new";
163 
164  /* api callbacks */
167 
168  /* flags */
170 
171  /* properties */
172  RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Name of new mask layer");
173 }
174 
175 /******************** remove mask layer *********************/
176 
178 {
180  MaskLayer *mask_layer = BKE_mask_layer_active(mask);
181 
182  if (mask_layer) {
183  BKE_mask_layer_remove(mask, mask_layer);
184 
187  }
188 
189  return OPERATOR_FINISHED;
190 }
191 
193 {
194  /* identifiers */
195  ot->name = "Remove Mask Layer";
196  ot->description = "Remove mask layer";
197  ot->idname = "MASK_OT_layer_remove";
198 
199  /* api callbacks */
202 
203  /* flags */
205 }
206 
207 /******************** slide *********************/
208 
209 enum {
215 };
216 
217 typedef struct SlidePointData {
218  /* Generic fields. */
220  int action;
227  int width, height;
228 
230 
231  /* Previous clip coordinate which was resolved from mouse position (0, 0).
232  * Is used to compensate for view offset moving in-between of mouse events when
233  * lock-to-selection is enabled. */
234  float prev_zero_coord[2];
235 
236  float no[2];
237 
239 
241 
242  /* Data needed to restore the state. */
243  float vec[3][3];
244  char old_h1, old_h2;
245 
246  /* Point sliding. */
247 
248  /* Handle sliding. */
250 
251  /* Feather sliding. */
255 
256 static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], const float co[2])
257 {
258  BKE_mask_coord_to_movieclip(sc->clip, &sc->user, r_co, co);
259  ED_clip_point_undistorted_pos(sc, r_co, r_co);
260  BKE_mask_coord_from_movieclip(sc->clip, &sc->user, r_co, r_co);
261 }
262 
263 static bool spline_under_mouse_get(const bContext *C,
264  Mask *mask_orig,
265  const float co[2],
266  MaskLayer **r_mask_layer,
267  MaskSpline **r_mask_spline)
268 {
269  const float threshold = 19.0f;
272  float closest_dist_squared = 0.0f;
273  MaskLayer *closest_layer = NULL;
274  MaskSpline *closest_spline = NULL;
275  bool undistort = false;
276  *r_mask_layer = NULL;
277  *r_mask_spline = NULL;
278 
280  Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
281 
282  int width, height;
284  float pixel_co[2];
285  pixel_co[0] = co[0] * width;
286  pixel_co[1] = co[1] * height;
287  if (sc != NULL) {
288  undistort = (sc->clip != NULL) && (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0;
289  }
290 
291  for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
292  *mask_layer_eval = mask_eval->masklayers.first;
293  mask_layer_orig != NULL;
294  mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
295  if (mask_layer_orig->restrictflag & MASK_RESTRICT_SELECT) {
296  continue;
297  }
298  for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
299  *spline_eval = mask_layer_eval->splines.first;
300  spline_orig != NULL;
301  spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
302  if ((spline_orig->flag & SELECT) == 0) {
303  continue;
304  }
305  MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval);
306  float min[2], max[2], center[2];
307  INIT_MINMAX2(min, max);
308  for (int i = 0; i < spline_orig->tot_point; i++) {
309  MaskSplinePoint *point_deform = &points_array[i];
310  BezTriple *bezt = &point_deform->bezt;
311 
312  float vert[2];
313 
314  copy_v2_v2(vert, bezt->vec[1]);
315 
316  if (undistort) {
317  mask_point_undistort_pos(sc, vert, vert);
318  }
319 
320  minmax_v2v2_v2(min, max, vert);
321  }
322 
323  center[0] = (min[0] + max[0]) / 2.0f * width;
324  center[1] = (min[1] + max[1]) / 2.0f * height;
325  float dist_squared = len_squared_v2v2(pixel_co, center);
326  float max_bb_side = min_ff((max[0] - min[0]) * width, (max[1] - min[1]) * height);
327  if (dist_squared <= max_bb_side * max_bb_side * 0.5f &&
328  (closest_spline == NULL || dist_squared < closest_dist_squared)) {
329  closest_layer = mask_layer_orig;
330  closest_spline = spline_orig;
331  closest_dist_squared = dist_squared;
332  }
333  }
334  }
335  if (closest_dist_squared < square_f(threshold) && closest_spline != NULL) {
336  float diff_score;
338  mask_orig,
339  co,
340  threshold,
341  false,
342  NULL,
343  true,
344  false,
345  NULL,
346  NULL,
347  NULL,
348  NULL,
349  &diff_score)) {
350  if (square_f(diff_score) < closest_dist_squared) {
351  return false;
352  }
353  }
354 
355  *r_mask_layer = closest_layer;
356  *r_mask_spline = closest_spline;
357  return true;
358  }
359  return false;
360 }
361 
363 {
364  for (int i = 0; i < spline->tot_point; i++) {
365  MaskSplinePoint *point = &spline->points[i];
366 
367  if (point->bezt.weight != 0.0f) {
368  return false;
369  }
370  }
371 
372  return true;
373 }
374 
376  MaskLayer *mask_layer,
377  MaskSpline *spline,
378  MaskSplinePoint *point,
379  eMaskWhichHandle which_handle)
380 {
382 
383  switch (which_handle) {
385  BKE_mask_point_select_set(point, true);
386  break;
388  point->bezt.f1 |= SELECT;
389  break;
391  point->bezt.f3 |= SELECT;
392  break;
394  point->bezt.f1 |= SELECT;
395  point->bezt.f3 |= SELECT;
396  break;
397  default:
398  BLI_assert(!"Unexpected situation in select_sliding_point()");
399  }
400 
401  mask_layer->act_spline = spline;
402  mask_layer->act_point = point;
404 }
405 
407 {
408  BezTriple *bezt = &point->bezt;
409 
410  if (which_handle == MASK_WHICH_HANDLE_LEFT) {
411  if (bezt->h1 == HD_VECT) {
412  bezt->h1 = HD_FREE;
413  }
414  else if (bezt->h1 == HD_AUTO) {
415  bezt->h1 = HD_ALIGN_DOUBLESIDE;
416  bezt->h2 = HD_ALIGN_DOUBLESIDE;
417  }
418  }
419  else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
420  if (bezt->h2 == HD_VECT) {
421  bezt->h2 = HD_FREE;
422  }
423  else if (bezt->h2 == HD_AUTO) {
424  bezt->h1 = HD_ALIGN_DOUBLESIDE;
425  bezt->h2 = HD_ALIGN_DOUBLESIDE;
426  }
427  }
428 }
429 
430 static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *event)
431 {
433  ARegion *region = CTX_wm_region(C);
434 
436  SlidePointData *customdata = NULL;
437  MaskLayer *mask_layer, *cv_mask_layer, *feather_mask_layer;
438  MaskSpline *spline, *cv_spline, *feather_spline;
439  MaskSplinePoint *point, *cv_point, *feather_point;
440  MaskSplinePointUW *uw = NULL;
441  int width, height, action = SLIDE_ACTION_NONE;
442  const bool slide_feather = RNA_boolean_get(op->ptr, "slide_feather");
443  float co[2], cv_score, feather_score;
444  const float threshold = 19;
445  eMaskWhichHandle which_handle;
446 
447  MaskViewLockState lock_state;
448  ED_mask_view_lock_state_store(C, &lock_state);
449 
450  ED_mask_mouse_pos(area, region, event->mval, co);
452 
453  cv_point = ED_mask_point_find_nearest(
454  C, mask, co, threshold, &cv_mask_layer, &cv_spline, &which_handle, &cv_score);
455 
457  mask,
458  co,
459  threshold,
460  &feather_mask_layer,
461  &feather_spline,
462  &feather_point,
463  &uw,
464  &feather_score)) {
465  if (slide_feather || !cv_point || feather_score < cv_score) {
466  action = SLIDE_ACTION_FEATHER;
467 
468  mask_layer = feather_mask_layer;
469  spline = feather_spline;
470  point = feather_point;
471  }
472  }
473 
474  if (cv_point && action == SLIDE_ACTION_NONE) {
475  if (which_handle != MASK_WHICH_HANDLE_NONE) {
476  action = SLIDE_ACTION_HANDLE;
477  }
478  else {
479  action = SLIDE_ACTION_POINT;
480  }
481 
482  mask_layer = cv_mask_layer;
483  spline = cv_spline;
484  point = cv_point;
485  }
486 
487  if (action == SLIDE_ACTION_NONE) {
488  if (spline_under_mouse_get(C, mask, co, &mask_layer, &spline)) {
489  action = SLIDE_ACTION_SPLINE;
490  point = NULL;
491  }
492  }
493 
494  if (action != SLIDE_ACTION_NONE) {
495  customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data");
496  customdata->event_invoke_type = event->type;
497  customdata->mask = mask;
498  customdata->mask_layer = mask_layer;
499  customdata->spline = spline;
500  customdata->point = point;
501  customdata->width = width;
502  customdata->height = height;
503  customdata->action = action;
504  customdata->uw = uw;
505 
506  customdata->is_sliding_new_point = RNA_boolean_get(op->ptr, "is_new_point");
507 
508  if (customdata->action != SLIDE_ACTION_SPLINE) {
509  customdata->old_h1 = point->bezt.h1;
510  customdata->old_h2 = point->bezt.h2;
511  select_sliding_point(mask, mask_layer, spline, point, which_handle);
512  check_sliding_handle_type(point, which_handle);
513  }
514 
515  if (uw) {
516  float co_uw[2];
517  float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u);
518 
519  customdata->weight = uw->w;
520  customdata->weight_scalar = weight_scalar;
521  BKE_mask_point_segment_co(spline, point, uw->u, co_uw);
522  BKE_mask_point_normal(spline, point, uw->u, customdata->no);
523 
524  madd_v2_v2v2fl(customdata->prev_feather_coord, co_uw, customdata->no, uw->w * weight_scalar);
525  }
526  else if (customdata->action != SLIDE_ACTION_SPLINE) {
527  BezTriple *bezt = &point->bezt;
528 
529  customdata->weight = bezt->weight;
530  customdata->weight_scalar = 1.0f;
531  BKE_mask_point_normal(spline, point, 0.0f, customdata->no);
532 
533  madd_v2_v2v2fl(customdata->prev_feather_coord, bezt->vec[1], customdata->no, bezt->weight);
534  }
535 
536  if (customdata->action == SLIDE_ACTION_FEATHER) {
538  }
539 
540  if (customdata->action != SLIDE_ACTION_SPLINE) {
541  copy_m3_m3(customdata->vec, point->bezt.vec);
542  if (which_handle != MASK_WHICH_HANDLE_NONE) {
543  BKE_mask_point_handle(point, which_handle, customdata->orig_handle_coord);
544  copy_v2_v2(customdata->prev_handle_coord, customdata->orig_handle_coord);
545  }
546  }
547  customdata->which_handle = which_handle;
548 
549  {
551  DEG_id_tag_update(&mask->id, 0);
552 
554  }
555 
556  ED_mask_mouse_pos(area, region, event->mval, customdata->prev_mouse_coord);
557  ED_mask_mouse_pos(area, region, (int[2]){0, 0}, customdata->prev_zero_coord);
558  }
559 
560  return customdata;
561 }
562 
563 static int slide_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
564 {
566  SlidePointData *slidedata;
567 
568  if (mask == NULL) {
569  return OPERATOR_PASS_THROUGH;
570  }
571 
572  slidedata = slide_point_customdata(C, op, event);
573 
574  if (slidedata) {
575  op->customdata = slidedata;
576 
578 
579  slidedata->mask_layer->act_spline = slidedata->spline;
580  slidedata->mask_layer->act_point = slidedata->point;
581 
583 
584  return OPERATOR_RUNNING_MODAL;
585  }
586 
587  return OPERATOR_PASS_THROUGH;
588 }
589 
591 {
592  for (int i = 0; i < data->spline->tot_point; i++) {
593  MaskSplinePoint *point = &data->spline->points[i];
594  MaskSplinePoint *orig_point = &data->orig_spline->points[i];
595 
596  point->bezt.weight = orig_point->bezt.weight + delta;
597  if (point->bezt.weight < 0.0f) {
598  point->bezt.weight = 0.0f;
599  }
600  }
601 }
602 
604 {
605  for (int i = 0; i < data->spline->tot_point; i++) {
606  MaskSplinePoint *point = &data->spline->points[i];
607  MaskSplinePoint *orig_point = &data->orig_spline->points[i];
608 
609  point->bezt = orig_point->bezt;
610 
611  for (int j = 0; j < point->tot_uw; j++) {
612  point->uw[j] = orig_point->uw[j];
613  }
614  }
615 }
616 
618 {
619  /* cancel sliding */
620 
621  if (data->orig_spline) {
623  }
624  else {
625  if (data->action == SLIDE_ACTION_FEATHER) {
626  if (data->uw) {
627  data->uw->w = data->weight;
628  }
629  else {
630  data->point->bezt.weight = data->weight;
631  }
632  }
633  else if (data->action != SLIDE_ACTION_SPLINE) {
634  copy_m3_m3(data->point->bezt.vec, data->vec);
635  data->point->bezt.h1 = data->old_h1;
636  data->point->bezt.h2 = data->old_h2;
637  }
638  }
639 }
640 
642 {
643  if (data->orig_spline) {
644  BKE_mask_spline_free(data->orig_spline);
645  }
646 
647  MEM_freeN(data);
648 }
649 
650 static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
651 {
653  BezTriple *bezt = &data->point->bezt;
654  float co[2];
655 
656  switch (event->type) {
657  case EVT_LEFTALTKEY:
658  case EVT_RIGHTALTKEY:
659  case EVT_LEFTSHIFTKEY:
660  case EVT_RIGHTSHIFTKEY:
661  if (ELEM(event->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY)) {
662  if (data->action == SLIDE_ACTION_FEATHER) {
663  data->is_overall_feather = (event->val == KM_PRESS);
664  }
665  else {
666  data->is_curvature_only = (event->val == KM_PRESS);
667  }
668  }
669 
671  data->is_accurate = (event->val == KM_PRESS);
672  }
673 
674  ATTR_FALLTHROUGH; /* update CV position */
675  case MOUSEMOVE: {
677  ARegion *region = CTX_wm_region(C);
678  float delta[2];
679 
680  ED_mask_mouse_pos(area, region, event->mval, co);
681  sub_v2_v2v2(delta, co, data->prev_mouse_coord);
682  copy_v2_v2(data->prev_mouse_coord, co);
683 
684  /* Compensate for possibly moved view offset since the last event.
685  * The idea is to see how mapping of a fixed and known position did change. */
686  {
687  float zero_coord[2];
688  ED_mask_mouse_pos(area, region, (int[2]){0, 0}, zero_coord);
689 
690  float zero_delta[2];
691  sub_v2_v2v2(zero_delta, zero_coord, data->prev_zero_coord);
692  sub_v2_v2(delta, zero_delta);
693 
694  copy_v2_v2(data->prev_zero_coord, zero_coord);
695  }
696 
697  if (data->is_accurate) {
698  mul_v2_fl(delta, 0.2f);
699  }
700 
701  if (data->action == SLIDE_ACTION_HANDLE) {
702  float new_handle[2];
703 
704  if (data->is_sliding_new_point && data->which_handle == MASK_WHICH_HANDLE_STICK) {
705  if (ELEM(data->point,
706  &data->spline->points[0],
707  &data->spline->points[data->spline->tot_point - 1])) {
708  SWAP(float, delta[0], delta[1]);
709  delta[1] *= -1;
710 
711  /* flip last point */
712  if (data->point != &data->spline->points[0]) {
713  negate_v2(delta);
714  }
715  }
716  }
717 
718  add_v2_v2v2(new_handle, data->prev_handle_coord, delta);
719 
721  data->which_handle,
722  new_handle,
723  data->is_curvature_only,
724  data->orig_handle_coord,
725  data->vec);
726  BKE_mask_point_handle(data->point, data->which_handle, data->prev_handle_coord);
727 
728  if (data->is_sliding_new_point) {
730  float vec[2];
731  short self_handle = (data->which_handle == MASK_WHICH_HANDLE_LEFT) ? 0 : 2;
732  short other_handle = (data->which_handle == MASK_WHICH_HANDLE_LEFT) ? 2 : 0;
733 
734  sub_v2_v2v2(vec, bezt->vec[1], bezt->vec[self_handle]);
735  add_v2_v2v2(bezt->vec[other_handle], bezt->vec[1], vec);
736  }
737  }
738  }
739  else if (data->action == SLIDE_ACTION_POINT) {
740  add_v2_v2(bezt->vec[0], delta);
741  add_v2_v2(bezt->vec[1], delta);
742  add_v2_v2(bezt->vec[2], delta);
743  }
744  else if (data->action == SLIDE_ACTION_FEATHER) {
745  float vec[2], no[2], p[2], c[2], w, offco[2];
746  float *weight = NULL;
747  float weight_scalar = 1.0f;
748  bool is_overall_feather = data->is_overall_feather || data->is_initial_feather;
749 
750  add_v2_v2v2(offco, data->prev_feather_coord, delta);
751 
752  if (data->uw) {
753  /* project on both sides and find the closest one,
754  * prevents flickering when projecting onto both sides can happen */
755  const float u_pos = BKE_mask_spline_project_co(
756  data->spline, data->point, data->uw->u, offco, MASK_PROJ_NEG);
757  const float u_neg = BKE_mask_spline_project_co(
758  data->spline, data->point, data->uw->u, offco, MASK_PROJ_POS);
759  float dist_pos = FLT_MAX;
760  float dist_neg = FLT_MAX;
761  float co_pos[2];
762  float co_neg[2];
763  float u;
764 
765  if (u_pos > 0.0f && u_pos < 1.0f) {
766  BKE_mask_point_segment_co(data->spline, data->point, u_pos, co_pos);
767  dist_pos = len_squared_v2v2(offco, co_pos);
768  }
769 
770  if (u_neg > 0.0f && u_neg < 1.0f) {
771  BKE_mask_point_segment_co(data->spline, data->point, u_neg, co_neg);
772  dist_neg = len_squared_v2v2(offco, co_neg);
773  }
774 
775  u = dist_pos < dist_neg ? u_pos : u_neg;
776 
777  if (u > 0.0f && u < 1.0f) {
778  data->uw->u = u;
779 
780  data->uw = BKE_mask_point_sort_uw(data->point, data->uw);
781  weight = &data->uw->w;
782  weight_scalar = BKE_mask_point_weight_scalar(data->spline, data->point, u);
783  if (weight_scalar != 0.0f) {
784  weight_scalar = 1.0f / weight_scalar;
785  }
786 
787  BKE_mask_point_normal(data->spline, data->point, data->uw->u, no);
788  BKE_mask_point_segment_co(data->spline, data->point, data->uw->u, p);
789  }
790  }
791  else {
792  weight = &bezt->weight;
793  /* weight_scalar = 1.0f; keep as is */
794  copy_v2_v2(no, data->no);
795  copy_v2_v2(p, bezt->vec[1]);
796  }
797 
798  if (weight) {
799  sub_v2_v2v2(c, offco, p);
800  project_v2_v2v2_normalized(vec, c, no);
801 
802  w = len_v2(vec);
803 
804  if (is_overall_feather) {
805  float w_delta;
806 
807  if (dot_v2v2(no, vec) <= 0.0f) {
808  w = -w;
809  }
810 
811  w_delta = w - data->weight * data->weight_scalar;
812 
813  if (data->orig_spline == NULL) {
814  /* restore weight for currently sliding point, so orig_spline would be created
815  * with original weights used
816  */
817  *weight = data->weight;
818 
819  data->orig_spline = BKE_mask_spline_copy(data->spline);
820  }
821 
822  if (data->is_initial_feather) {
823  *weight = w * weight_scalar;
824  }
825 
827  }
828  else {
829  if (dot_v2v2(no, vec) <= 0.0f) {
830  w = 0.0f;
831  }
832 
833  if (data->orig_spline) {
834  /* restore possible overall feather changes */
836 
837  BKE_mask_spline_free(data->orig_spline);
838  data->orig_spline = NULL;
839  }
840 
841  if (weight_scalar != 0.0f) {
842  *weight = w * weight_scalar;
843  }
844  }
845 
846  copy_v2_v2(data->prev_feather_coord, offco);
847  }
848  }
849  else if (data->action == SLIDE_ACTION_SPLINE) {
850  if (data->orig_spline == NULL) {
851  data->orig_spline = BKE_mask_spline_copy(data->spline);
852  }
853 
854  for (int i = 0; i < data->spline->tot_point; i++) {
855  MaskSplinePoint *point = &data->spline->points[i];
856  add_v2_v2(point->bezt.vec[0], delta);
857  add_v2_v2(point->bezt.vec[1], delta);
858  add_v2_v2(point->bezt.vec[2], delta);
859  }
860  }
861 
863  DEG_id_tag_update(&data->mask->id, 0);
864 
865  break;
866  }
867 
868  case LEFTMOUSE:
869  case RIGHTMOUSE:
870  if (event->type == data->event_invoke_type && event->val == KM_RELEASE) {
872 
873  /* Don't key sliding feather UW's. */
874  if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == false) {
875  if (IS_AUTOKEY_ON(scene)) {
876  ED_mask_layer_shape_auto_key(data->mask_layer, CFRA);
877  }
878  }
879 
880  if (data->is_sliding_new_point) {
881  if (len_squared_v2v2(bezt->vec[0], bezt->vec[1]) < FLT_EPSILON) {
882  bezt->h1 = HD_VECT;
883  }
884  if (len_squared_v2v2(bezt->vec[2], bezt->vec[1]) < FLT_EPSILON) {
885  bezt->h2 = HD_VECT;
886  }
887  }
888 
890  DEG_id_tag_update(&data->mask->id, 0);
891 
892  free_slide_point_data(op->customdata); /* keep this last! */
893  return OPERATOR_FINISHED;
894  }
895  else if (event->type != data->event_invoke_type && event->val == KM_PRESS) {
896  /* pass to ESCKEY */
897  }
898  else {
899  break;
900  }
901 
902  case EVT_ESCKEY:
904 
906  DEG_id_tag_update(&data->mask->id, 0);
907 
908  free_slide_point_data(op->customdata); /* keep this last! */
909  return OPERATOR_CANCELLED;
910  }
911 
912  return OPERATOR_RUNNING_MODAL;
913 }
914 
916 {
917  PropertyRNA *prop;
918 
919  /* identifiers */
920  ot->name = "Slide Point";
921  ot->description = "Slide control points";
922  ot->idname = "MASK_OT_slide_point";
923 
924  /* api callbacks */
928 
929  /* flags */
931 
933  "slide_feather",
934  0,
935  "Slide Feather",
936  "First try to slide feather instead of vertex");
937 
938  prop = RNA_def_boolean(
939  ot->srna, "is_new_point", 0, "Slide New Point", "Newly created vertex is being slid");
941 }
942 
943 /******************** slide spline curvature *********************/
944 
945 typedef struct SlideSplineCurvatureData {
947 
952  float u;
953  bool accurate;
954 
957 
960 
961  float P0[2], P1[2], P2[2], P3[3];
963 
965 {
966  *slide_data->adjust_bezt = slide_data->bezt_backup;
967  *slide_data->other_bezt = slide_data->other_bezt_backup;
968 }
969 
971 {
972  MEM_freeN(slide_data);
973 }
974 
975 static bool slide_spline_curvature_check(bContext *C, const wmEvent *event)
976 {
978  float co[2];
979  const float threshold = 19.0f;
980 
982 
983  if (ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL)) {
984  return false;
985  }
986 
987  if (ED_mask_feather_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL, NULL)) {
988  return false;
989  }
990 
991  return true;
992 }
993 
995  const wmEvent *event)
996 {
997  const float threshold = 19.0f;
998 
1000  SlideSplineCurvatureData *slide_data;
1001  MaskLayer *mask_layer;
1002  MaskSpline *spline;
1003  MaskSplinePoint *point;
1004  float u, co[2];
1005  BezTriple *next_bezt;
1006 
1007  MaskViewLockState lock_state;
1008  ED_mask_view_lock_state_store(C, &lock_state);
1009 
1011 
1013  mask,
1014  co,
1015  threshold,
1016  false,
1017  NULL,
1018  true,
1019  false,
1020  &mask_layer,
1021  &spline,
1022  &point,
1023  &u,
1024  NULL)) {
1025  return NULL;
1026  }
1027 
1028  next_bezt = BKE_mask_spline_point_next_bezt(spline, spline->points, point);
1029  if (next_bezt == NULL) {
1030  return NULL;
1031  }
1032 
1033  slide_data = MEM_callocN(sizeof(SlideSplineCurvatureData), "slide curvature slide");
1034  slide_data->event_invoke_type = event->type;
1035  slide_data->mask = mask;
1036  slide_data->mask_layer = mask_layer;
1037  slide_data->spline = spline;
1038  slide_data->point = point;
1039  slide_data->u = u;
1040 
1041  copy_v2_v2(slide_data->prev_mouse_coord, co);
1042  BKE_mask_point_segment_co(spline, point, u, slide_data->prev_spline_coord);
1043 
1044  copy_v2_v2(slide_data->P0, point->bezt.vec[1]);
1045  copy_v2_v2(slide_data->P1, point->bezt.vec[2]);
1046  copy_v2_v2(slide_data->P2, next_bezt->vec[0]);
1047  copy_v2_v2(slide_data->P3, next_bezt->vec[1]);
1048 
1049  /* Depending to which end we're closer to adjust either left or right side of the spline. */
1050  if (u <= 0.5f) {
1051  slide_data->adjust_bezt = &point->bezt;
1052  slide_data->other_bezt = next_bezt;
1053  }
1054  else {
1055  slide_data->adjust_bezt = next_bezt;
1056  slide_data->other_bezt = &point->bezt;
1057  }
1058 
1059  /* Data needed for restoring state. */
1060  slide_data->bezt_backup = *slide_data->adjust_bezt;
1061  slide_data->other_bezt_backup = *slide_data->other_bezt;
1062 
1063  /* Let's don't touch other side of the point for now, so set handle to FREE. */
1064  if (u < 0.5f) {
1065  if (slide_data->adjust_bezt->h2 <= HD_VECT) {
1066  slide_data->adjust_bezt->h2 = HD_FREE;
1067  }
1068  }
1069  else {
1070  if (slide_data->adjust_bezt->h1 <= HD_VECT) {
1071  slide_data->adjust_bezt->h1 = HD_FREE;
1072  }
1073  }
1074 
1075  /* Change selection */
1077  slide_data->adjust_bezt->f2 |= SELECT;
1078  slide_data->other_bezt->f2 |= SELECT;
1079  if (u < 0.5f) {
1080  slide_data->adjust_bezt->f3 |= SELECT;
1081  slide_data->other_bezt->f1 |= SELECT;
1082  }
1083  else {
1084  slide_data->adjust_bezt->f1 |= SELECT;
1085  slide_data->other_bezt->f3 |= SELECT;
1086  }
1087  mask_layer->act_spline = spline;
1088  mask_layer->act_point = point;
1090 
1091  DEG_id_tag_update(&mask->id, 0);
1093 
1094  return slide_data;
1095 }
1096 
1098 {
1100  SlideSplineCurvatureData *slide_data;
1101 
1102  if (mask == NULL) {
1103  return OPERATOR_PASS_THROUGH;
1104  }
1105 
1106  /* Be sure we don't conflict with point slide here. */
1107  if (!slide_spline_curvature_check(C, event)) {
1108  return OPERATOR_PASS_THROUGH;
1109  }
1110 
1111  slide_data = slide_spline_curvature_customdata(C, event);
1112  if (slide_data != NULL) {
1113  op->customdata = slide_data;
1116  return OPERATOR_RUNNING_MODAL;
1117  }
1118 
1119  return OPERATOR_PASS_THROUGH;
1120 }
1121 
1122 static void slide_spline_solve_P1(const float u,
1123  const float B[2],
1124  const float P0[2],
1125  const float P2[2],
1126  const float P3[2],
1127  float solution[2])
1128 {
1129  const float u2 = u * u, u3 = u * u * u;
1130  const float v = 1.0f - u;
1131  const float v2 = v * v, v3 = v * v * v;
1132  const float inv_divider = 1.0f / (3.0f * v2 * u);
1133  const float t = 3.0f * v * u2;
1134  solution[0] = -(v3 * P0[0] + t * P2[0] + u3 * P3[0] - B[0]) * inv_divider;
1135  solution[1] = -(v3 * P0[1] + t * P2[1] + u3 * P3[1] - B[1]) * inv_divider;
1136 }
1137 
1138 static void slide_spline_solve_P2(const float u,
1139  const float B[2],
1140  const float P0[2],
1141  const float P1[2],
1142  const float P3[2],
1143  float solution[2])
1144 {
1145  const float u2 = u * u, u3 = u * u * u;
1146  const float v = 1.0f - u;
1147  const float v2 = v * v, v3 = v * v * v;
1148  const float inv_divider = 1.0f / (3.0f * v * u2);
1149  const float t = 3.0f * v2 * u;
1150  solution[0] = -(v3 * P0[0] + t * P1[0] + u3 * P3[0] - B[0]) * inv_divider;
1151  solution[1] = -(v3 * P0[1] + t * P1[1] + u3 * P3[1] - B[1]) * inv_divider;
1152 }
1153 
1155 {
1157  const float margin = 0.2f;
1159  float u = slide_data->u;
1160 
1161  switch (event->type) {
1162  case EVT_LEFTSHIFTKEY:
1163  case EVT_RIGHTSHIFTKEY:
1164  case EVT_LEFTCTRLKEY:
1165  case EVT_RIGHTCTRLKEY:
1166  if (ELEM(event->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY)) {
1167  slide_data->accurate = (event->val == KM_PRESS);
1168  }
1169 
1170  if (ELEM(event->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY)) {
1171  if (event->val == KM_PRESS) {
1172  slide_data->adjust_bezt->h1 = slide_data->adjust_bezt->h2 = HD_FREE;
1173  if ((u > margin && u < 0.5f) || (u >= 0.5f && u < 1.0f - margin)) {
1174  slide_data->other_bezt->h1 = slide_data->other_bezt->h2 = HD_FREE;
1175  }
1176  }
1177  else if (event->val == KM_RELEASE) {
1178  slide_data->adjust_bezt->h1 = slide_data->bezt_backup.h1;
1179  slide_data->adjust_bezt->h2 = slide_data->bezt_backup.h2;
1180  slide_data->other_bezt->h1 = slide_data->other_bezt_backup.h1;
1181  slide_data->other_bezt->h2 = slide_data->other_bezt_backup.h2;
1182  }
1183 
1184  if (u < 0.5f) {
1185  copy_v2_v2(slide_data->adjust_bezt->vec[0], slide_data->bezt_backup.vec[0]);
1186  copy_v2_v2(slide_data->other_bezt->vec[2], slide_data->other_bezt_backup.vec[2]);
1187  }
1188  else {
1189  copy_v2_v2(slide_data->adjust_bezt->vec[2], slide_data->bezt_backup.vec[2]);
1190  copy_v2_v2(slide_data->other_bezt->vec[0], slide_data->other_bezt_backup.vec[0]);
1191  }
1192  }
1193 
1194  ATTR_FALLTHROUGH; /* update CV position */
1195  case MOUSEMOVE: {
1196  float B[2], mouse_coord[2], delta[2];
1197 
1198  /* Get coordinate spline is expected to go through. */
1199  ED_mask_mouse_pos(CTX_wm_area(C), CTX_wm_region(C), event->mval, mouse_coord);
1200  sub_v2_v2v2(delta, mouse_coord, slide_data->prev_mouse_coord);
1201  if (slide_data->accurate) {
1202  mul_v2_fl(delta, 0.2f);
1203  }
1204  add_v2_v2v2(B, slide_data->prev_spline_coord, delta);
1205  copy_v2_v2(slide_data->prev_spline_coord, B);
1206  copy_v2_v2(slide_data->prev_mouse_coord, mouse_coord);
1207 
1208  if (u < 0.5f) {
1209  float oldP2[2];
1210  bool need_restore_P2 = false;
1211 
1212  if (u > margin) {
1213  float solution[2];
1214  float x = (u - margin) * 0.5f / (0.5f - margin);
1215  float weight = (3 * x * x - 2 * x * x * x);
1216 
1217  slide_spline_solve_P2(u, B, slide_data->P0, slide_data->P1, slide_data->P3, solution);
1218 
1219  copy_v2_v2(oldP2, slide_data->P2);
1220  interp_v2_v2v2(slide_data->P2, slide_data->P2, solution, weight);
1221  copy_v2_v2(slide_data->other_bezt->vec[0], slide_data->P2);
1222  need_restore_P2 = true;
1223 
1224  /* Tweak handle type in order to be able to apply the delta. */
1225  if (weight > 0.0f) {
1226  if (slide_data->other_bezt->h1 <= HD_VECT) {
1227  slide_data->other_bezt->h1 = HD_FREE;
1228  }
1229  }
1230  }
1231 
1233  u, B, slide_data->P0, slide_data->P2, slide_data->P3, slide_data->adjust_bezt->vec[2]);
1234 
1235  if (need_restore_P2) {
1236  copy_v2_v2(slide_data->P2, oldP2);
1237  }
1238  }
1239  else {
1240  float oldP1[2];
1241  bool need_restore_P1 = false;
1242 
1243  if (u < 1.0f - margin) {
1244  float solution[2];
1245  float x = ((1.0f - u) - margin) * 0.5f / (0.5f - margin);
1246  float weight = 3 * x * x - 2 * x * x * x;
1247 
1248  slide_spline_solve_P1(u, B, slide_data->P0, slide_data->P2, slide_data->P3, solution);
1249 
1250  copy_v2_v2(oldP1, slide_data->P1);
1251  interp_v2_v2v2(slide_data->P1, slide_data->P1, solution, weight);
1252  copy_v2_v2(slide_data->other_bezt->vec[2], slide_data->P1);
1253  need_restore_P1 = true;
1254 
1255  /* Tweak handle type in order to be able to apply the delta. */
1256  if (weight > 0.0f) {
1257  if (slide_data->other_bezt->h2 <= HD_VECT) {
1258  slide_data->other_bezt->h2 = HD_FREE;
1259  }
1260  }
1261  }
1262 
1264  u, B, slide_data->P0, slide_data->P1, slide_data->P3, slide_data->adjust_bezt->vec[0]);
1265 
1266  if (need_restore_P1) {
1267  copy_v2_v2(slide_data->P1, oldP1);
1268  }
1269  }
1270 
1271  WM_event_add_notifier(C, NC_MASK | NA_EDITED, slide_data->mask);
1272  DEG_id_tag_update(&slide_data->mask->id, 0);
1273 
1274  break;
1275  }
1276 
1277  case LEFTMOUSE:
1278  case RIGHTMOUSE:
1279  if (event->type == slide_data->event_invoke_type && event->val == KM_RELEASE) {
1280  /* Don't key sliding feather UW's. */
1281  if (IS_AUTOKEY_ON(scene)) {
1283  }
1284 
1285  WM_event_add_notifier(C, NC_MASK | NA_EDITED, slide_data->mask);
1286  DEG_id_tag_update(&slide_data->mask->id, 0);
1287 
1288  free_slide_spline_curvature_data(slide_data); /* keep this last! */
1289  return OPERATOR_FINISHED;
1290  }
1291 
1292  break;
1293 
1294  case EVT_ESCKEY:
1295  cancel_slide_spline_curvature(slide_data);
1296 
1297  WM_event_add_notifier(C, NC_MASK | NA_EDITED, slide_data->mask);
1298  DEG_id_tag_update(&slide_data->mask->id, 0);
1299 
1300  free_slide_spline_curvature_data(op->customdata); /* keep this last! */
1301  return OPERATOR_CANCELLED;
1302  }
1303 
1304  return OPERATOR_RUNNING_MODAL;
1305 }
1306 
1308 {
1309  /* identifiers */
1310  ot->name = "Slide Spline Curvature";
1311  ot->description = "Slide a point on the spline to define its curvature";
1312  ot->idname = "MASK_OT_slide_spline_curvature";
1313 
1314  /* api callbacks */
1318 
1319  /* flags */
1321 }
1322 
1323 /******************** toggle cyclic *********************/
1324 
1326 {
1328 
1329  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
1330  if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
1331  continue;
1332  }
1333 
1334  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
1335  if (ED_mask_spline_select_check(spline)) {
1336  spline->flag ^= MASK_SPLINE_CYCLIC;
1337  }
1338  }
1339  }
1340 
1341  DEG_id_tag_update(&mask->id, 0);
1343 
1344  return OPERATOR_FINISHED;
1345 }
1346 
1348 {
1349  /* identifiers */
1350  ot->name = "Toggle Cyclic";
1351  ot->description = "Toggle cyclic for selected splines";
1352  ot->idname = "MASK_OT_cyclic_toggle";
1353 
1354  /* api callbacks */
1357 
1358  /* flags */
1360 }
1361 
1362 /******************** delete *********************/
1363 
1365 {
1366  int count = 0;
1367 
1368  if (!point->tot_uw) {
1369  return;
1370  }
1371 
1372  for (int i = 0; i < point->tot_uw; i++) {
1373  if ((point->uw[i].flag & SELECT) == 0) {
1374  count++;
1375  }
1376  }
1377 
1378  if (count == 0) {
1379  MEM_freeN(point->uw);
1380  point->uw = NULL;
1381  point->tot_uw = 0;
1382  }
1383  else {
1384  MaskSplinePointUW *new_uw;
1385  int j = 0;
1386 
1387  new_uw = MEM_callocN(count * sizeof(MaskSplinePointUW), "new mask uw points");
1388 
1389  for (int i = 0; i < point->tot_uw; i++) {
1390  if ((point->uw[i].flag & SELECT) == 0) {
1391  new_uw[j++] = point->uw[i];
1392  }
1393  }
1394 
1395  MEM_freeN(point->uw);
1396 
1397  point->uw = new_uw;
1398  point->tot_uw = count;
1399  }
1400 }
1401 
1403 {
1405  bool changed = false;
1406 
1407  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
1408  MaskSpline *spline;
1409  int mask_layer_shape_ofs = 0;
1410 
1411  if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
1412  continue;
1413  }
1414 
1415  spline = mask_layer->splines.first;
1416 
1417  while (spline) {
1418  const int tot_point_orig = spline->tot_point;
1419  int count = 0;
1420  MaskSpline *next_spline = spline->next;
1421 
1422  /* count unselected points */
1423  for (int i = 0; i < spline->tot_point; i++) {
1424  MaskSplinePoint *point = &spline->points[i];
1425 
1426  if (!MASKPOINT_ISSEL_ANY(point)) {
1427  count++;
1428  }
1429  }
1430 
1431  if (count == 0) {
1432  /* delete the whole spline */
1433  BLI_remlink(&mask_layer->splines, spline);
1434  BKE_mask_spline_free(spline);
1435 
1436  if (spline == mask_layer->act_spline) {
1437  mask_layer->act_spline = NULL;
1438  mask_layer->act_point = NULL;
1439  }
1440 
1441  BKE_mask_layer_shape_changed_remove(mask_layer, mask_layer_shape_ofs, tot_point_orig);
1442  }
1443  else {
1444  MaskSplinePoint *new_points;
1445 
1446  new_points = MEM_callocN(count * sizeof(MaskSplinePoint), "deleteMaskPoints");
1447 
1448  for (int i = 0, j = 0; i < tot_point_orig; i++) {
1449  MaskSplinePoint *point = &spline->points[i];
1450 
1451  if (!MASKPOINT_ISSEL_ANY(point)) {
1452  if (point == mask_layer->act_point) {
1453  mask_layer->act_point = &new_points[j];
1454  }
1455 
1456  delete_feather_points(point);
1457 
1458  new_points[j] = *point;
1459  j++;
1460  }
1461  else {
1462  if (point == mask_layer->act_point) {
1463  mask_layer->act_point = NULL;
1464  }
1465 
1466  BKE_mask_point_free(point);
1467  spline->tot_point--;
1468 
1469  BKE_mask_layer_shape_changed_remove(mask_layer, mask_layer_shape_ofs + j, 1);
1470  }
1471  }
1472 
1473  mask_layer_shape_ofs += spline->tot_point;
1474 
1475  MEM_freeN(spline->points);
1476  spline->points = new_points;
1477 
1479  }
1480 
1481  changed = true;
1482  spline = next_spline;
1483  }
1484 
1485  /* Not essential but confuses users when there are keys with no data!
1486  * Assume if they delete all data from the layer they also don't care about keys. */
1487  if (BLI_listbase_is_empty(&mask_layer->splines)) {
1488  BKE_mask_layer_free_shapes(mask_layer);
1489  }
1490  }
1491 
1492  if (!changed) {
1493  return OPERATOR_CANCELLED;
1494  }
1495 
1497 
1499 
1500  return OPERATOR_FINISHED;
1501 }
1502 
1504 {
1505  /* identifiers */
1506  ot->name = "Delete";
1507  ot->description = "Delete selected control points or splines";
1508  ot->idname = "MASK_OT_delete";
1509 
1510  /* api callbacks */
1512  ot->exec = delete_exec;
1514 
1515  /* flags */
1517 }
1518 
1519 /* *** switch direction *** */
1521 {
1524 
1525  bool changed = false;
1526 
1527  /* do actual selection */
1528  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
1529  bool changed_layer = false;
1530 
1531  if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
1532  continue;
1533  }
1534 
1535  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
1536  if (ED_mask_spline_select_check(spline)) {
1537  BKE_mask_spline_direction_switch(mask_layer, spline);
1538  changed = true;
1539  changed_layer = true;
1540  }
1541  }
1542 
1543  if (changed_layer) {
1544  if (IS_AUTOKEY_ON(scene)) {
1545  ED_mask_layer_shape_auto_key(mask_layer, CFRA);
1546  }
1547  }
1548  }
1549 
1550  if (changed) {
1552 
1555 
1556  return OPERATOR_FINISHED;
1557  }
1558 
1559  return OPERATOR_CANCELLED;
1560 }
1561 
1563 {
1564  /* identifiers */
1565  ot->name = "Switch Direction";
1566  ot->description = "Switch direction of selected splines";
1567  ot->idname = "MASK_OT_switch_direction";
1568 
1569  /* api callbacks */
1572 
1573  /* flags */
1575 }
1576 
1577 /* *** recalc normals *** */
1579 {
1582 
1583  bool changed = false;
1584 
1585  /* do actual selection */
1586  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
1587  bool changed_layer = false;
1588 
1589  if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
1590  continue;
1591  }
1592 
1593  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
1594  for (int i = 0; i < spline->tot_point; i++) {
1595  MaskSplinePoint *point = &spline->points[i];
1596 
1597  if (MASKPOINT_ISSEL_ANY(point)) {
1598  BKE_mask_calc_handle_point_auto(spline, point, false);
1599  changed = true;
1600  changed_layer = true;
1601  }
1602  }
1603  }
1604 
1605  if (changed_layer) {
1606  if (IS_AUTOKEY_ON(scene)) {
1607  ED_mask_layer_shape_auto_key(mask_layer, CFRA);
1608  }
1609  }
1610  }
1611 
1612  if (changed) {
1614 
1617 
1618  return OPERATOR_FINISHED;
1619  }
1620 
1621  return OPERATOR_CANCELLED;
1622 }
1623 
1624 /* Named to match mesh recalculate normals. */
1626 {
1627  /* identifiers */
1628  ot->name = "Recalculate Handles";
1629  ot->description = "Recalculate the direction of selected handles";
1630  ot->idname = "MASK_OT_normals_make_consistent";
1631 
1632  /* api callbacks */
1635 
1636  /* flags */
1638 }
1639 
1640 /******************** set handle type *********************/
1641 
1643 {
1645  int handle_type = RNA_enum_get(op->ptr, "type");
1646 
1647  bool changed = false;
1648 
1649  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
1650  if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
1651  continue;
1652  }
1653 
1654  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
1655  for (int i = 0; i < spline->tot_point; i++) {
1656  MaskSplinePoint *point = &spline->points[i];
1657 
1658  if (MASKPOINT_ISSEL_ANY(point)) {
1659  BezTriple *bezt = &point->bezt;
1660 
1661  if (bezt->f2 & SELECT) {
1662  bezt->h1 = handle_type;
1663  bezt->h2 = handle_type;
1664  }
1665  else {
1666  if (bezt->f1 & SELECT) {
1667  bezt->h1 = handle_type;
1668  }
1669  if (bezt->f3 & SELECT) {
1670  bezt->h2 = handle_type;
1671  }
1672  }
1673 
1674  if (handle_type == HD_ALIGN) {
1675  float vec[3];
1676  sub_v3_v3v3(vec, bezt->vec[0], bezt->vec[1]);
1677  add_v3_v3v3(bezt->vec[2], bezt->vec[1], vec);
1678  }
1679 
1680  changed = true;
1681  }
1682  }
1683  }
1684  }
1685 
1686  if (changed) {
1688  DEG_id_tag_update(&mask->id, 0);
1689 
1690  return OPERATOR_FINISHED;
1691  }
1692  return OPERATOR_CANCELLED;
1693 }
1694 
1696 {
1697  static const EnumPropertyItem editcurve_handle_type_items[] = {
1698  {HD_AUTO, "AUTO", 0, "Auto", ""},
1699  {HD_VECT, "VECTOR", 0, "Vector", ""},
1700  {HD_ALIGN, "ALIGNED", 0, "Aligned Single", ""},
1701  {HD_ALIGN_DOUBLESIDE, "ALIGNED_DOUBLESIDE", 0, "Aligned", ""},
1702  {HD_FREE, "FREE", 0, "Free", ""},
1703  {0, NULL, 0, NULL, NULL},
1704  };
1705 
1706  /* identifiers */
1707  ot->name = "Set Handle Type";
1708  ot->description = "Set type of handles for selected control points";
1709  ot->idname = "MASK_OT_handle_type_set";
1710 
1711  /* api callbacks */
1715 
1716  /* flags */
1718 
1719  /* properties */
1720  ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type");
1721 }
1722 
1723 /* ********* clear/set restrict view *********/
1725 {
1727  bool changed = false;
1728  const bool select = RNA_boolean_get(op->ptr, "select");
1729 
1730  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
1731 
1732  if (mask_layer->restrictflag & OB_RESTRICT_VIEWPORT) {
1733  ED_mask_layer_select_set(mask_layer, select);
1734  mask_layer->restrictflag &= ~OB_RESTRICT_VIEWPORT;
1735  changed = true;
1736  }
1737  }
1738 
1739  if (changed) {
1741  DEG_id_tag_update(&mask->id, 0);
1742 
1743  return OPERATOR_FINISHED;
1744  }
1745  return OPERATOR_CANCELLED;
1746 }
1747 
1749 {
1750 
1751  /* identifiers */
1752  ot->name = "Clear Restrict View";
1753  ot->description = "Reveal the layer by setting the hide flag";
1754  ot->idname = "MASK_OT_hide_view_clear";
1755 
1756  /* api callbacks */
1759 
1760  /* flags */
1762 
1763  RNA_def_boolean(ot->srna, "select", true, "Select", "");
1764 }
1765 
1767 {
1769  const bool unselected = RNA_boolean_get(op->ptr, "unselected");
1770  bool changed = false;
1771 
1772  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
1773 
1774  if (mask_layer->restrictflag & MASK_RESTRICT_SELECT) {
1775  continue;
1776  }
1777 
1778  if (!unselected) {
1779  if (ED_mask_layer_select_check(mask_layer)) {
1780  ED_mask_layer_select_set(mask_layer, false);
1781 
1782  mask_layer->restrictflag |= OB_RESTRICT_VIEWPORT;
1783  changed = true;
1784  if (mask_layer == BKE_mask_layer_active(mask)) {
1786  }
1787  }
1788  }
1789  else {
1790  if (!ED_mask_layer_select_check(mask_layer)) {
1791  mask_layer->restrictflag |= OB_RESTRICT_VIEWPORT;
1792  changed = true;
1793  if (mask_layer == BKE_mask_layer_active(mask)) {
1795  }
1796  }
1797  }
1798  }
1799 
1800  if (changed) {
1802  DEG_id_tag_update(&mask->id, 0);
1803 
1804  return OPERATOR_FINISHED;
1805  }
1806  return OPERATOR_CANCELLED;
1807 }
1808 
1810 {
1811  /* identifiers */
1812  ot->name = "Set Restrict View";
1813  ot->description = "Hide the layer by setting the hide flag";
1814  ot->idname = "MASK_OT_hide_view_set";
1815 
1816  /* api callbacks */
1819 
1820  /* flags */
1822 
1824  ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected layers");
1825 }
1826 
1828 {
1830  bool changed = false;
1831 
1832  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
1833  if (mask_layer->restrictflag & (MASK_RESTRICT_SELECT | MASK_RESTRICT_VIEW)) {
1834  continue;
1835  }
1836 
1837  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
1838  for (int i = 0; i < spline->tot_point; i++) {
1839  MaskSplinePoint *point = &spline->points[i];
1840 
1841  if (MASKPOINT_ISSEL_ANY(point)) {
1842  BezTriple *bezt = &point->bezt;
1843  bezt->weight = 0.0f;
1844  changed = true;
1845  }
1846  }
1847  }
1848  }
1849 
1850  if (changed) {
1852 
1854  DEG_id_tag_update(&mask->id, 0);
1855 
1856  return OPERATOR_FINISHED;
1857  }
1858  return OPERATOR_CANCELLED;
1859 }
1860 
1862 {
1863  /* identifiers */
1864  ot->name = "Clear Feather Weight";
1865  ot->description = "Reset the feather weight to zero";
1866  ot->idname = "MASK_OT_feather_weight_clear";
1867 
1868  /* api callbacks */
1871 
1872  /* flags */
1874 }
1875 
1876 /******************** move mask layer operator *********************/
1877 
1879 {
1880  if (ED_maskedit_mask_poll(C)) {
1882 
1883  return mask->masklay_tot > 0;
1884  }
1885 
1886  return false;
1887 }
1888 
1890 {
1892  MaskLayer *mask_layer = BLI_findlink(&mask->masklayers, mask->masklay_act);
1893  MaskLayer *mask_layer_other;
1894  int direction = RNA_enum_get(op->ptr, "direction");
1895 
1896  if (!mask_layer) {
1897  return OPERATOR_CANCELLED;
1898  }
1899 
1900  if (direction == -1) {
1901  mask_layer_other = mask_layer->prev;
1902 
1903  if (!mask_layer_other) {
1904  return OPERATOR_CANCELLED;
1905  }
1906 
1907  BLI_remlink(&mask->masklayers, mask_layer);
1908  BLI_insertlinkbefore(&mask->masklayers, mask_layer_other, mask_layer);
1909  mask->masklay_act--;
1910  }
1911  else if (direction == 1) {
1912  mask_layer_other = mask_layer->next;
1913 
1914  if (!mask_layer_other) {
1915  return OPERATOR_CANCELLED;
1916  }
1917 
1918  BLI_remlink(&mask->masklayers, mask_layer);
1919  BLI_insertlinkafter(&mask->masklayers, mask_layer_other, mask_layer);
1920  mask->masklay_act++;
1921  }
1922 
1925 
1926  return OPERATOR_FINISHED;
1927 }
1928 
1930 {
1931  static const EnumPropertyItem direction_items[] = {
1932  {-1, "UP", 0, "Up", ""},
1933  {1, "DOWN", 0, "Down", ""},
1934  {0, NULL, 0, NULL, NULL},
1935  };
1936 
1937  /* identifiers */
1938  ot->name = "Move Layer";
1939  ot->description = "Move the active layer up/down in the list";
1940  ot->idname = "MASK_OT_layer_move";
1941 
1942  /* api callbacks */
1945 
1946  /* flags */
1948 
1949  /* properties */
1950  RNA_def_enum(ot->srna,
1951  "direction",
1952  direction_items,
1953  0,
1954  "Direction",
1955  "Direction to move the active layer");
1956 }
1957 
1958 /******************** duplicate *********************/
1959 
1961 {
1963 
1964  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
1965  for (MaskSpline *spline = mask_layer->splines.last; spline; spline = spline->prev) {
1966  MaskSplinePoint *point = spline->points;
1967  int i = 0;
1968  while (i < spline->tot_point) {
1969  int start = i, end = -1;
1970  /* Find next selected segment. */
1971  while (MASKPOINT_ISSEL_ANY(point)) {
1972  BKE_mask_point_select_set(point, false);
1973  end = i;
1974  if (i >= spline->tot_point - 1) {
1975  break;
1976  }
1977  i++;
1978  point++;
1979  }
1980  if (end >= start) {
1981  int tot_point;
1982  int tot_point_shape_start = 0;
1983  MaskSpline *new_spline = BKE_mask_spline_add(mask_layer);
1984  MaskSplinePoint *new_point;
1985  int b;
1986 
1987  /* BKE_mask_spline_add might allocate the points,
1988  * need to free them in this case. */
1989  if (new_spline->points) {
1990  MEM_freeN(new_spline->points);
1991  }
1992 
1993  /* Copy options from old spline. */
1994  new_spline->flag = spline->flag;
1995  new_spline->offset_mode = spline->offset_mode;
1996  new_spline->weight_interp = spline->weight_interp;
1997  new_spline->parent = spline->parent;
1998 
1999  /* Allocate new points and copy them from old spline. */
2000  new_spline->tot_point = end - start + 1;
2001  new_spline->points = MEM_mallocN(sizeof(MaskSplinePoint) * new_spline->tot_point,
2002  "duplicated mask points");
2003 
2004  memcpy(new_spline->points,
2005  spline->points + start,
2006  new_spline->tot_point * sizeof(MaskSplinePoint));
2007 
2008  tot_point = new_spline->tot_point;
2009 
2010  /* animation requires points added one by one */
2011  if (mask_layer->splines_shapes.first) {
2012  new_spline->tot_point = 0;
2013  tot_point_shape_start = BKE_mask_layer_shape_spline_to_index(mask_layer, new_spline);
2014  }
2015 
2016  /* Select points and duplicate their UWs (if needed). */
2017  for (b = 0, new_point = new_spline->points; b < tot_point; b++, new_point++) {
2018  if (new_point->uw) {
2019  new_point->uw = MEM_dupallocN(new_point->uw);
2020  }
2021  BKE_mask_point_select_set(new_point, true);
2022 
2023  if (mask_layer->splines_shapes.first) {
2024  new_spline->tot_point++;
2025  BKE_mask_layer_shape_changed_add(mask_layer, tot_point_shape_start + b, true, false);
2026  }
2027  }
2028 
2029  /* Clear cyclic flag if we didn't copy the whole spline. */
2030  if (new_spline->flag & MASK_SPLINE_CYCLIC) {
2031  if (start != 0 || end != spline->tot_point - 1) {
2032  new_spline->flag &= ~MASK_SPLINE_CYCLIC;
2033  }
2034  }
2035 
2036  /* Flush selection to splines. */
2037  new_spline->flag |= SELECT;
2038  spline->flag &= ~SELECT;
2039 
2040  mask_layer->act_spline = new_spline;
2041  }
2042  i++;
2043  point++;
2044  }
2045  }
2046  }
2047 
2049 
2051 
2052  return OPERATOR_FINISHED;
2053 }
2054 
2056 {
2057  /* identifiers */
2058  ot->name = "Duplicate Mask";
2059  ot->description = "Duplicate selected control points and segments between them";
2060  ot->idname = "MASK_OT_duplicate";
2061 
2062  /* api callbacks */
2065 
2066  /* flags */
2068 }
2069 
2070 /********************** copy splines to clipboard operator *********************/
2071 
2073 {
2075  MaskLayer *mask_layer = BKE_mask_layer_active(mask);
2076 
2077  if (mask_layer == NULL) {
2078  return OPERATOR_CANCELLED;
2079  }
2080 
2082 
2083  return OPERATOR_FINISHED;
2084 }
2085 
2087 {
2088  /* identifiers */
2089  ot->name = "Copy Splines";
2090  ot->description = "Copy selected splines to clipboard";
2091  ot->idname = "MASK_OT_copy_splines";
2092 
2093  /* api callbacks */
2096 
2097  /* flags */
2098  ot->flag = OPTYPE_REGISTER;
2099 }
2100 
2101 /********************** paste tracks from clipboard operator *********************/
2102 
2104 {
2105  if (ED_maskedit_mask_poll(C)) {
2106  return BKE_mask_clipboard_is_empty() == false;
2107  }
2108 
2109  return 0;
2110 }
2111 
2113 {
2115  MaskLayer *mask_layer = BKE_mask_layer_active(mask);
2116 
2117  if (mask_layer == NULL) {
2118  mask_layer = BKE_mask_layer_new(mask, "");
2119  }
2120 
2122 
2124 
2126 
2127  return OPERATOR_FINISHED;
2128 }
2129 
2131 {
2132  /* identifiers */
2133  ot->name = "Paste Splines";
2134  ot->description = "Paste splines from clipboard";
2135  ot->idname = "MASK_OT_paste_splines";
2136 
2137  /* api callbacks */
2140 
2141  /* flags */
2143 }
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct SpaceClip * CTX_wm_space_clip(const bContext *C)
Definition: context.c:899
struct Mask * CTX_data_edit_mask(const bContext *C)
Definition: context.c:1316
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
#define MASKPOINT_ISSEL_ANY(p)
Definition: BKE_mask.h:232
void BKE_mask_layer_shape_changed_add(struct MaskLayer *masklay, int index, bool do_init, bool do_init_interpolate)
Definition: mask.c:1927
void BKE_mask_point_select_set(struct MaskSplinePoint *point, const bool do_select)
Definition: mask.c:971
void BKE_mask_layer_remove(struct Mask *mask, struct MaskLayer *masklay)
Definition: mask.c:386
eMaskWhichHandle
Definition: BKE_mask.h:46
@ MASK_WHICH_HANDLE_NONE
Definition: BKE_mask.h:47
@ 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
void BKE_mask_spline_free(struct MaskSpline *spline)
Definition: mask.c:1068
struct MaskLayer * BKE_mask_layer_new(struct Mask *mask, const char *name)
Definition: mask.c:351
void BKE_mask_point_free(struct MaskSplinePoint *point)
Definition: mask.c:1061
struct MaskLayer * BKE_mask_layer_active(struct Mask *mask)
Definition: mask.c:376
struct MaskSplinePointUW * BKE_mask_point_sort_uw(struct MaskSplinePoint *point, struct MaskSplinePointUW *uw)
Definition: mask.c:928
void BKE_mask_layer_active_set(struct Mask *mask, struct MaskLayer *masklay)
Definition: mask.c:381
float BKE_mask_spline_project_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float start_u, const float co[2], const eMaskSign sign)
Definition: mask.c:598
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
@ MASK_PROJ_NEG
Definition: BKE_mask.h:97
@ MASK_PROJ_POS
Definition: BKE_mask.h:99
struct MaskSpline * BKE_mask_spline_copy(const struct MaskSpline *spline)
void BKE_mask_clipboard_paste_to_layer(struct Main *bmain, struct MaskLayer *mask_layer)
Definition: mask.c:2131
void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2])
Definition: mask.c:1266
void BKE_mask_layer_free_shapes(struct MaskLayer *masklay)
Free all animation keys for a mask layer.
Definition: mask.c:1162
void BKE_mask_point_handle(const struct MaskSplinePoint *point, eMaskWhichHandle which_handle, float r_handle[2])
void BKE_mask_calc_handle_point_auto(struct MaskSpline *spline, struct MaskSplinePoint *point, const bool do_recalc_length)
Resets auto handles even for non-auto bezier points.
Definition: mask.c:1522
void BKE_mask_point_normal(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float n[2])
Definition: mask.c:795
void BKE_mask_point_segment_co(struct MaskSpline *spline, struct MaskSplinePoint *point, float u, float co[2])
Definition: mask.c:767
struct MaskSplinePoint * BKE_mask_spline_point_array(struct MaskSpline *spline)
Definition: mask.c:328
int BKE_mask_layer_shape_spline_to_index(struct MaskLayer *masklay, struct MaskSpline *spline)
Definition: mask.c:1878
void BKE_mask_coord_from_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2])
Definition: mask.c:1219
void BKE_mask_layer_shape_changed_remove(struct MaskLayer *masklay, int index, int count)
Definition: mask.c:2022
bool BKE_mask_clipboard_is_empty(void)
Definition: mask.c:2125
float BKE_mask_point_weight_scalar(struct MaskSpline *spline, struct MaskSplinePoint *point, const float u)
Definition: mask.c:853
struct BezTriple * BKE_mask_spline_point_next_bezt(struct MaskSpline *spline, struct MaskSplinePoint *points_array, struct MaskSplinePoint *point)
Definition: mask.c:313
void BKE_mask_clipboard_copy_from_layer(struct MaskLayer *mask_layer)
Definition: mask.c:2090
struct MaskSpline * BKE_mask_spline_add(struct MaskLayer *masklay)
Definition: mask.c:484
void BKE_mask_spline_direction_switch(struct MaskLayer *masklay, struct MaskSpline *spline)
Definition: mask.c:550
struct Mask * BKE_mask_new(struct Main *bmain, const char *name)
Definition: mask.c:1038
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define ATTR_FALLTHROUGH
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
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:352
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:395
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float min_ff(float a, float b)
MINLINE float square_f(float a)
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:89
void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_proj[2])
Definition: math_vector.c:705
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t)
Definition: math_vector.c:32
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
MINLINE void sub_v2_v2(float r[2], const float a[2])
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 negate_v2(float r[2])
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
Definition: math_vector.c:1043
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
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 dot_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
#define INIT_MINMAX2(min, max)
#define SWAP(type, a, b)
#define UNUSED(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update(struct ID *id, int flag)
struct ID * DEG_get_evaluated_id(const struct Depsgraph *depsgraph, struct ID *id)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
#define MAX_ID_NAME
Definition: DNA_ID.h:269
@ HD_VECT
@ HD_FREE
@ HD_AUTO
@ HD_ALIGN_DOUBLESIDE
@ HD_ALIGN
#define MASK_RESTRICT_SELECT
#define MASK_RESTRICT_VIEW
@ MASK_SPLINE_CYCLIC
@ MCLIP_PROXY_RENDER_UNDISTORT
Object is a sort of wrapper for general info.
@ OB_RESTRICT_VIEWPORT
#define CFRA
@ SPACE_CLIP
@ SPACE_SEQ
@ SPACE_IMAGE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask)
Definition: clip_editor.c:638
void ED_clip_point_undistorted_pos(struct SpaceClip *sc, const float co[2], float r_co[2])
Definition: clip_editor.c:459
void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask)
Definition: image_edit.c:127
#define IS_AUTOKEY_ON(scene)
void ED_mask_layer_shape_auto_key(struct MaskLayer *mask_layer, const int frame)
void ED_mask_mouse_pos(struct ScrArea *area, struct ARegion *region, const int mval[2], float co[2])
Definition: mask_query.c:493
void ED_mask_get_size(struct ScrArea *area, int *width, int *height)
Definition: mask_query.c:691
bool ED_operator_mask(struct bContext *C)
Definition: screen_ops.c:616
@ SEL_DESELECT
NSNotificationCenter * center
_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 width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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.
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
#define ND_DRAW
Definition: WM_types.h:362
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_DATA
Definition: WM_types.h:408
#define NA_ADDED
Definition: WM_types.h:464
#define NA_EDITED
Definition: WM_types.h:462
#define KM_PRESS
Definition: WM_types.h:242
#define ND_SELECT
Definition: WM_types.h:407
#define NC_MASK
Definition: WM_types.h:299
#define KM_RELEASE
Definition: WM_types.h:243
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
#define SELECT
Scene scene
const Depsgraph * depsgraph
int count
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
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
void ED_mask_view_lock_state_restore_no_jump(const bContext *C, const MaskViewLockState *state)
Definition: mask_edit.c:200
bool ED_maskedit_mask_poll(bContext *C)
Definition: mask_edit.c:61
bool ED_maskedit_poll(bContext *C)
Definition: mask_edit.c:45
void ED_mask_view_lock_state_store(const bContext *C, MaskViewLockState *state)
Definition: mask_edit.c:192
void ED_mask_select_flush_all(struct Mask *mask)
Definition: mask_select.c:165
struct MaskSplinePoint * ED_mask_point_find_nearest(const struct bContext *C, struct Mask *mask, const float normal_co[2], const float threshold, struct MaskLayer **r_mask_layer, struct MaskSpline **r_spline, eMaskWhichHandle *r_which_handle, float *r_score)
bool ED_mask_find_nearest_diff_point(const struct bContext *C, struct Mask *mask, const float normal_co[2], int threshold, bool feather, float tangent[2], const bool use_deform, const bool use_project, struct MaskLayer **r_mask_layer, struct MaskSpline **r_spline, struct MaskSplinePoint **r_point, float *r_u, float *r_score)
void ED_mask_layer_select_set(struct MaskLayer *mask_layer, const bool do_select)
Definition: mask_select.c:115
void ED_mask_select_toggle_all(struct Mask *mask, int action)
Definition: mask_select.c:128
bool ED_mask_layer_select_check(const struct MaskLayer *mask_layer)
bool ED_mask_feather_find_nearest(const struct bContext *C, struct Mask *mask, const float normal_co[2], const float threshold, struct MaskLayer **r_mask_layer, struct MaskSpline **r_spline, struct MaskSplinePoint **r_point, struct MaskSplinePointUW **r_uw, float *r_score)
bool ED_mask_spline_select_check(const struct MaskSpline *spline)
static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: mask_ops.c:650
static void cancel_slide_point(SlidePointData *data)
Definition: mask_ops.c:617
static bool paste_splines_poll(bContext *C)
Definition: mask_ops.c:2103
static void cancel_slide_spline_curvature(SlideSplineCurvatureData *slide_data)
Definition: mask_ops.c:964
struct SlidePointData SlidePointData
static int paste_splines_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_ops.c:2112
static int mask_hide_view_set_exec(bContext *C, wmOperator *op)
Definition: mask_ops.c:1766
void MASK_OT_slide_spline_curvature(wmOperatorType *ot)
Definition: mask_ops.c:1307
void MASK_OT_copy_splines(wmOperatorType *ot)
Definition: mask_ops.c:2086
static int mask_new_exec(bContext *C, wmOperator *op)
Definition: mask_ops.c:108
static void check_sliding_handle_type(MaskSplinePoint *point, eMaskWhichHandle which_handle)
Definition: mask_ops.c:406
void MASK_OT_layer_move(wmOperatorType *ot)
Definition: mask_ops.c:1929
static int slide_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: mask_ops.c:563
void MASK_OT_feather_weight_clear(wmOperatorType *ot)
Definition: mask_ops.c:1861
void MASK_OT_layer_remove(wmOperatorType *ot)
Definition: mask_ops.c:192
static bool slide_point_check_initial_feather(MaskSpline *spline)
Definition: mask_ops.c:362
struct SlideSplineCurvatureData SlideSplineCurvatureData
void MASK_OT_paste_splines(wmOperatorType *ot)
Definition: mask_ops.c:2130
static int mask_hide_view_clear_exec(bContext *C, wmOperator *op)
Definition: mask_ops.c:1724
void MASK_OT_layer_new(wmOperatorType *ot)
Definition: mask_ops.c:157
static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_ops.c:1520
static bool slide_spline_curvature_check(bContext *C, const wmEvent *event)
Definition: mask_ops.c:975
static int delete_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_ops.c:1402
static int mask_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_ops.c:1960
static int slide_spline_curvature_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: mask_ops.c:1097
static void select_sliding_point(Mask *mask, MaskLayer *mask_layer, MaskSpline *spline, MaskSplinePoint *point, eMaskWhichHandle which_handle)
Definition: mask_ops.c:375
static void * slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *event)
Definition: mask_ops.c:430
static int set_handle_type_exec(bContext *C, wmOperator *op)
Definition: mask_ops.c:1642
static int mask_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_ops.c:177
static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], const float co[2])
Definition: mask_ops.c:256
static void free_slide_spline_curvature_data(SlideSplineCurvatureData *slide_data)
Definition: mask_ops.c:970
Mask * ED_mask_new(bContext *C, const char *name)
Definition: mask_ops.c:57
static void slide_spline_solve_P1(const float u, const float B[2], const float P0[2], const float P2[2], const float P3[2], float solution[2])
Definition: mask_ops.c:1122
void MASK_OT_hide_view_clear(wmOperatorType *ot)
Definition: mask_ops.c:1748
static bool mask_layer_move_poll(bContext *C)
Definition: mask_ops.c:1878
static int mask_layer_new_exec(bContext *C, wmOperator *op)
Definition: mask_ops.c:141
void MASK_OT_new(wmOperatorType *ot)
Definition: mask_ops.c:121
static int copy_splines_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_ops.c:2072
static void slide_point_delta_all_feather(SlidePointData *data, float delta)
Definition: mask_ops.c:590
void MASK_OT_handle_type_set(wmOperatorType *ot)
Definition: mask_ops.c:1695
static int mask_normals_make_consistent_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_ops.c:1578
void MASK_OT_duplicate(wmOperatorType *ot)
Definition: mask_ops.c:2055
static SlideSplineCurvatureData * slide_spline_curvature_customdata(bContext *C, const wmEvent *event)
Definition: mask_ops.c:994
void MASK_OT_cyclic_toggle(wmOperatorType *ot)
Definition: mask_ops.c:1347
static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_ops.c:1325
MaskLayer * ED_mask_layer_ensure(bContext *C, bool *r_added_mask)
Definition: mask_ops.c:88
static void slide_spline_solve_P2(const float u, const float B[2], const float P0[2], const float P1[2], const float P3[2], float solution[2])
Definition: mask_ops.c:1138
static void free_slide_point_data(SlidePointData *data)
Definition: mask_ops.c:641
void MASK_OT_delete(wmOperatorType *ot)
Definition: mask_ops.c:1503
static void delete_feather_points(MaskSplinePoint *point)
Definition: mask_ops.c:1364
static bool spline_under_mouse_get(const bContext *C, Mask *mask_orig, const float co[2], MaskLayer **r_mask_layer, MaskSpline **r_mask_spline)
Definition: mask_ops.c:263
static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_ops.c:1827
void MASK_OT_hide_view_set(wmOperatorType *ot)
Definition: mask_ops.c:1809
@ SLIDE_ACTION_NONE
Definition: mask_ops.c:210
@ SLIDE_ACTION_POINT
Definition: mask_ops.c:211
@ SLIDE_ACTION_SPLINE
Definition: mask_ops.c:214
@ SLIDE_ACTION_HANDLE
Definition: mask_ops.c:212
@ SLIDE_ACTION_FEATHER
Definition: mask_ops.c:213
static int slide_spline_curvature_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: mask_ops.c:1154
void MASK_OT_slide_point(wmOperatorType *ot)
Definition: mask_ops.c:915
void MASK_OT_switch_direction(wmOperatorType *ot)
Definition: mask_ops.c:1562
void MASK_OT_normals_make_consistent(wmOperatorType *ot)
Definition: mask_ops.c:1625
static int mask_layer_move_exec(bContext *C, wmOperator *op)
Definition: mask_ops.c:1889
static void slide_point_restore_spline(SlidePointData *data)
Definition: mask_ops.c:603
#define B
static unsigned c
Definition: RandGen.cpp:97
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:6514
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3675
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
#define min(a, b)
Definition: sort.c:51
float vec[3][3]
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
struct MaskLayer * next
struct MaskLayer * prev
struct MaskSplinePoint * act_point
struct MaskSpline * act_spline
char parent[64]
MaskSplinePointUW * uw
MaskParent parent
struct MaskSpline * prev
char weight_interp
struct MaskSpline * next
MaskSplinePoint * points
ListBase masklayers
float vec[3][3]
Definition: mask_ops.c:243
short event_invoke_type
Definition: mask_ops.c:219
float orig_handle_coord[2]
Definition: mask_ops.c:249
float prev_zero_coord[2]
Definition: mask_ops.c:234
float prev_handle_coord[2]
Definition: mask_ops.c:249
float prev_feather_coord[2]
Definition: mask_ops.c:252
eMaskWhichHandle which_handle
Definition: mask_ops.c:226
MaskSpline * spline
Definition: mask_ops.c:223
float weight_scalar
Definition: mask_ops.c:253
bool is_accurate
Definition: mask_ops.c:238
float weight
Definition: mask_ops.c:253
bool is_sliding_new_point
Definition: mask_ops.c:240
MaskLayer * mask_layer
Definition: mask_ops.c:222
bool is_curvature_only
Definition: mask_ops.c:238
MaskSplinePoint * point
Definition: mask_ops.c:224
MaskSpline * orig_spline
Definition: mask_ops.c:223
bool is_overall_feather
Definition: mask_ops.c:238
Mask * mask
Definition: mask_ops.c:221
float no[2]
Definition: mask_ops.c:236
MaskSplinePointUW * uw
Definition: mask_ops.c:225
float prev_mouse_coord[2]
Definition: mask_ops.c:229
bool is_initial_feather
Definition: mask_ops.c:238
float prev_spline_coord[2]
Definition: mask_ops.c:959
BezTriple * other_bezt
Definition: mask_ops.c:955
MaskSpline * spline
Definition: mask_ops.c:950
MaskSplinePoint * point
Definition: mask_ops.c:951
BezTriple * adjust_bezt
Definition: mask_ops.c:955
MaskLayer * mask_layer
Definition: mask_ops.c:949
BezTriple other_bezt_backup
Definition: mask_ops.c:956
struct MovieClipUser user
struct MovieClip * clip
short val
Definition: WM_types.h:579
int mval[2]
Definition: WM_types.h:583
short type
Definition: WM_types.h:577
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct PointerRNA * ptr
float max
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: util_avxb.h:167
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ RIGHTMOUSE
@ EVT_RIGHTCTRLKEY
@ EVT_LEFTCTRLKEY
@ MOUSEMOVE
@ EVT_RIGHTALTKEY
@ LEFTMOUSE
@ EVT_LEFTALTKEY
@ EVT_ESCKEY
@ EVT_RIGHTSHIFTKEY
@ EVT_LEFTSHIFTKEY
wmOperatorType * ot
Definition: wm_files.c:3156
int WM_operator_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: wm_operators.c:982