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