Blender  V2.93
mask_select.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_lasso_2d.h"
27 #include "BLI_listbase.h"
28 #include "BLI_math.h"
29 #include "BLI_rect.h"
30 #include "BLI_utildefines.h"
31 
32 #include "BKE_context.h"
33 #include "BKE_mask.h"
34 
35 #include "DEG_depsgraph.h"
36 #include "DEG_depsgraph_query.h"
37 
38 #include "DNA_mask_types.h"
39 
40 #include "WM_api.h"
41 #include "WM_types.h"
42 
43 #include "ED_clip.h"
44 #include "ED_mask.h" /* own include */
45 #include "ED_select_utils.h"
46 
47 #include "RNA_access.h"
48 #include "RNA_define.h"
49 
50 #include "DEG_depsgraph.h"
51 
52 #include "mask_intern.h" /* own include */
53 
54 /* -------------------------------------------------------------------- */
58 /* 'check' select */
60 {
61  for (int i = 0; i < spline->tot_point; i++) {
62  MaskSplinePoint *point = &spline->points[i];
63 
64  if (MASKPOINT_ISSEL_ANY(point)) {
65  return true;
66  }
67  }
68 
69  return false;
70 }
71 
72 bool ED_mask_layer_select_check(const MaskLayer *mask_layer)
73 {
75  return false;
76  }
77 
78  LISTBASE_FOREACH (const MaskSpline *, spline, &mask_layer->splines) {
79  if (ED_mask_spline_select_check(spline)) {
80  return true;
81  }
82  }
83 
84  return false;
85 }
86 
88 {
89  LISTBASE_FOREACH (const MaskLayer *, mask_layer, &mask->masklayers) {
90  if (ED_mask_layer_select_check(mask_layer)) {
91  return true;
92  }
93  }
94 
95  return false;
96 }
97 
98 /* 'sel' select */
99 void ED_mask_spline_select_set(MaskSpline *spline, const bool do_select)
100 {
101  if (do_select) {
102  spline->flag |= SELECT;
103  }
104  else {
105  spline->flag &= ~SELECT;
106  }
107 
108  for (int i = 0; i < spline->tot_point; i++) {
109  MaskSplinePoint *point = &spline->points[i];
110 
111  BKE_mask_point_select_set(point, do_select);
112  }
113 }
114 
115 void ED_mask_layer_select_set(MaskLayer *mask_layer, const bool do_select)
116 {
117  if (mask_layer->restrictflag & MASK_RESTRICT_SELECT) {
118  if (do_select == true) {
119  return;
120  }
121  }
122 
123  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
124  ED_mask_spline_select_set(spline, do_select);
125  }
126 }
127 
129 {
130  if (action == SEL_TOGGLE) {
131  if (ED_mask_select_check(mask)) {
132  action = SEL_DESELECT;
133  }
134  else {
135  action = SEL_SELECT;
136  }
137  }
138 
139  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
140 
141  if (mask_layer->restrictflag & MASK_RESTRICT_VIEW) {
142  continue;
143  }
144 
145  if (action == SEL_INVERT) {
146  /* we don't have generic functions for this, its restricted to this operator
147  * if one day we need to re-use such functionality, they can be split out */
148 
149  if (mask_layer->restrictflag & MASK_RESTRICT_SELECT) {
150  continue;
151  }
152  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
153  for (int i = 0; i < spline->tot_point; i++) {
154  MaskSplinePoint *point = &spline->points[i];
156  }
157  }
158  }
159  else {
160  ED_mask_layer_select_set(mask_layer, (action == SEL_SELECT) ? true : false);
161  }
162  }
163 }
164 
166 {
167  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
168  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
169  spline->flag &= ~SELECT;
170 
171  /* intentionally _dont_ do this in the mask layer loop
172  * so we clear flags on all splines */
173  if (mask_layer->restrictflag & MASK_RESTRICT_VIEW) {
174  continue;
175  }
176 
177  for (int i = 0; i < spline->tot_point; i++) {
178  MaskSplinePoint *cur_point = &spline->points[i];
179 
180  if (MASKPOINT_ISSEL_ANY(cur_point)) {
181  spline->flag |= SELECT;
182  }
183  else {
184  int j;
185 
186  for (j = 0; j < cur_point->tot_uw; j++) {
187  if (cur_point->uw[j].flag & SELECT) {
188  spline->flag |= SELECT;
189  break;
190  }
191  }
192  }
193  }
194  }
195  }
196 }
197 
199 {
201  if (mask) {
206  }
207 }
208 
211 /* -------------------------------------------------------------------- */
216 {
218  int action = RNA_enum_get(op->ptr, "action");
219 
220  MaskViewLockState lock_state;
221  ED_mask_view_lock_state_store(C, &lock_state);
222 
225 
228 
230 
231  return OPERATOR_FINISHED;
232 }
233 
235 {
236  /* identifiers */
237  ot->name = "(De)select All";
238  ot->description = "Change selection of all curve points";
239  ot->idname = "MASK_OT_select_all";
240 
241  /* api callbacks */
244 
245  /* flags */
247 
248  /* properties */
250 }
251 
254 /* -------------------------------------------------------------------- */
258 static int select_exec(bContext *C, wmOperator *op)
259 {
261  MaskLayer *mask_layer;
262  MaskSpline *spline;
263  MaskSplinePoint *point = NULL;
264  float co[2];
265  bool extend = RNA_boolean_get(op->ptr, "extend");
266  bool deselect = RNA_boolean_get(op->ptr, "deselect");
267  bool toggle = RNA_boolean_get(op->ptr, "toggle");
268  const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
269  eMaskWhichHandle which_handle;
270  const float threshold = 19;
271 
272  MaskViewLockState lock_state;
273  ED_mask_view_lock_state_store(C, &lock_state);
274 
275  RNA_float_get_array(op->ptr, "location", co);
276 
278  C, mask, co, threshold, &mask_layer, &spline, &which_handle, NULL);
279 
280  if (extend == false && deselect == false && toggle == false) {
282  }
283 
284  if (point) {
285  if (which_handle != MASK_WHICH_HANDLE_NONE) {
286  if (extend) {
287  mask_layer->act_spline = spline;
288  mask_layer->act_point = point;
289 
290  BKE_mask_point_select_set_handle(point, which_handle, true);
291  }
292  else if (deselect) {
293  BKE_mask_point_select_set_handle(point, which_handle, false);
294  }
295  else {
296  mask_layer->act_spline = spline;
297  mask_layer->act_point = point;
298 
299  if (!MASKPOINT_ISSEL_HANDLE(point, which_handle)) {
300  BKE_mask_point_select_set_handle(point, which_handle, true);
301  }
302  else if (toggle) {
303  BKE_mask_point_select_set_handle(point, which_handle, false);
304  }
305  }
306  }
307  else {
308  if (extend) {
309  mask_layer->act_spline = spline;
310  mask_layer->act_point = point;
311 
312  BKE_mask_point_select_set(point, true);
313  }
314  else if (deselect) {
315  BKE_mask_point_select_set(point, false);
316  }
317  else {
318  mask_layer->act_spline = spline;
319  mask_layer->act_point = point;
320 
321  if (!MASKPOINT_ISSEL_ANY(point)) {
322  BKE_mask_point_select_set(point, true);
323  }
324  else if (toggle) {
325  BKE_mask_point_select_set(point, false);
326  }
327  }
328  }
329 
330  mask_layer->act_spline = spline;
331  mask_layer->act_point = point;
332 
334 
337 
339 
340  return OPERATOR_FINISHED;
341  }
342 
343  MaskSplinePointUW *uw;
344 
346  C, mask, co, threshold, &mask_layer, &spline, &point, &uw, NULL)) {
347 
348  if (extend) {
349  mask_layer->act_spline = spline;
350  mask_layer->act_point = point;
351 
352  if (uw) {
353  uw->flag |= SELECT;
354  }
355  }
356  else if (deselect) {
357  if (uw) {
358  uw->flag &= ~SELECT;
359  }
360  }
361  else {
362  mask_layer->act_spline = spline;
363  mask_layer->act_point = point;
364 
365  if (uw) {
366  if (!(uw->flag & SELECT)) {
367  uw->flag |= SELECT;
368  }
369  else if (toggle) {
370  uw->flag &= ~SELECT;
371  }
372  }
373  }
374 
376 
379 
381 
382  return OPERATOR_FINISHED;
383  }
384  if (deselect_all) {
385  /* For clip editor tracks, leave deselect all to clip editor. */
386  if (!ED_clip_can_select(C)) {
389  return OPERATOR_FINISHED;
390  }
391  }
392 
393  return OPERATOR_PASS_THROUGH;
394 }
395 
396 static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
397 {
399  ARegion *region = CTX_wm_region(C);
400 
401  float co[2];
402 
403  ED_mask_mouse_pos(area, region, event->mval, co);
404 
405  RNA_float_set_array(op->ptr, "location", co);
406 
407  return select_exec(C, op);
408 }
409 
411 {
412  /* identifiers */
413  ot->name = "Select";
414  ot->description = "Select spline points";
415  ot->idname = "MASK_OT_select";
416 
417  /* api callbacks */
418  ot->exec = select_exec;
421 
422  /* flags */
423  ot->flag = OPTYPE_UNDO;
424 
425  /* properties */
427 
429  "location",
430  2,
431  NULL,
432  -FLT_MAX,
433  FLT_MAX,
434  "Location",
435  "Location of vertex in normalized space",
436  -1.0f,
437  1.0f);
438 }
439 
442 /* -------------------------------------------------------------------- */
447 {
449  ARegion *region = CTX_wm_region(C);
450 
451  Mask *mask_orig = CTX_data_edit_mask(C);
453  Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
454 
455  rcti rect;
456  rctf rectf;
457  bool changed = false;
458 
459  const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
460  const bool select = (sel_op != SEL_OP_SUB);
461  if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
463  changed = true;
464  }
465 
466  /* get rectangle from operator */
468 
469  ED_mask_point_pos(area, region, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
470  ED_mask_point_pos(area, region, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
471 
472  /* do actual selection */
473  for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
474  *mask_layer_eval = mask_eval->masklayers.first;
475  mask_layer_orig != NULL;
476  mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
477  if (mask_layer_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
478  continue;
479  }
480  for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
481  *spline_eval = mask_layer_eval->splines.first;
482  spline_orig != NULL;
483  spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
484 
485  MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval);
486 
487  for (int i = 0; i < spline_orig->tot_point; i++) {
488  MaskSplinePoint *point = &spline_orig->points[i];
489  MaskSplinePoint *point_deform = &points_array[i];
490 
491  /* TODO: handles? */
492  /* TODO: uw? */
493  if (BLI_rctf_isect_pt_v(&rectf, point_deform->bezt.vec[1])) {
496  changed = true;
497  }
498  }
499  }
500  }
501 
502  if (changed) {
503  ED_mask_select_flush_all(mask_orig);
504 
505  DEG_id_tag_update(&mask_orig->id, ID_RECALC_SELECT);
506  WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask_orig);
507 
508  return OPERATOR_FINISHED;
509  }
510 
511  return OPERATOR_CANCELLED;
512 }
513 
515 {
516  /* identifiers */
517  ot->name = "Box Select";
518  ot->description = "Select curve points using box selection";
519  ot->idname = "MASK_OT_select_box";
520 
521  /* api callbacks */
526 
527  /* flags */
528  ot->flag = OPTYPE_UNDO;
529 
530  /* properties */
533 }
534 
537 /* -------------------------------------------------------------------- */
542  const int mcoords[][2],
543  const int mcoords_len,
544  const eSelectOp sel_op)
545 {
547  ARegion *region = CTX_wm_region(C);
548 
549  Mask *mask_orig = CTX_data_edit_mask(C);
551  Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
552 
553  rcti rect;
554  bool changed = false;
555 
556  const bool select = (sel_op != SEL_OP_SUB);
557  if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
559  changed = true;
560  }
561 
562  /* get rectangle from operator */
563  BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
564 
565  /* do actual selection */
566  for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
567  *mask_layer_eval = mask_eval->masklayers.first;
568  mask_layer_orig != NULL;
569  mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
570  if (mask_layer_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
571  continue;
572  }
573  for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
574  *spline_eval = mask_layer_eval->splines.first;
575  spline_orig != NULL;
576  spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
577 
578  MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval);
579 
580  for (int i = 0; i < spline_orig->tot_point; i++) {
581  MaskSplinePoint *point = &spline_orig->points[i];
582  MaskSplinePoint *point_deform = &points_array[i];
583 
584  /* TODO: handles? */
585  /* TODO: uw? */
586 
587  if (MASKPOINT_ISSEL_ANY(point) && select) {
588  continue;
589  }
590 
591  float screen_co[2];
592 
593  /* point in screen coords */
595  region,
596  point_deform->bezt.vec[1][0],
597  point_deform->bezt.vec[1][1],
598  &screen_co[0],
599  &screen_co[1]);
600 
601  if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
602  BLI_lasso_is_point_inside(mcoords, mcoords_len, screen_co[0], screen_co[1], INT_MAX)) {
605  changed = true;
606  }
607  }
608  }
609  }
610 
611  if (changed) {
612  ED_mask_select_flush_all(mask_orig);
613 
614  DEG_id_tag_update(&mask_orig->id, ID_RECALC_SELECT);
615  WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask_orig);
616  }
617 
618  return changed;
619 }
620 
622 {
623  int mcoords_len;
624  const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
625 
626  if (mcoords) {
627  const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
628  do_lasso_select_mask(C, mcoords, mcoords_len, sel_op);
629 
630  MEM_freeN((void *)mcoords);
631 
632  return OPERATOR_FINISHED;
633  }
634  return OPERATOR_PASS_THROUGH;
635 }
636 
638 {
639  /* identifiers */
640  ot->name = "Lasso Select";
641  ot->description = "Select curve points using lasso selection";
642  ot->idname = "MASK_OT_select_lasso";
643 
644  /* api callbacks */
650 
651  /* flags */
652  ot->flag = OPTYPE_UNDO;
653 
654  /* properties */
657 }
658 
661 /* -------------------------------------------------------------------- */
666  const float offset[2],
667  const float ellipse[2])
668 {
669  /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
670  float x, y;
671 
672  x = (bezt->vec[1][0] - offset[0]) * ellipse[0];
673  y = (bezt->vec[1][1] - offset[1]) * ellipse[1];
674 
675  return x * x + y * y < 1.0f;
676 }
677 
679 {
681  ARegion *region = CTX_wm_region(C);
682 
683  Mask *mask_orig = CTX_data_edit_mask(C);
685  Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
686 
687  float zoomx, zoomy, offset[2], ellipse[2];
688  int width, height;
689  bool changed = false;
690 
691  /* get operator properties */
692  const int x = RNA_int_get(op->ptr, "x");
693  const int y = RNA_int_get(op->ptr, "y");
694  const int radius = RNA_int_get(op->ptr, "radius");
695 
696  /* compute ellipse and position in unified coordinates */
698  ED_mask_zoom(area, region, &zoomx, &zoomy);
700 
701  ellipse[0] = width * zoomx / radius;
702  ellipse[1] = height * zoomy / radius;
703 
704  ED_mask_point_pos(area, region, x, y, &offset[0], &offset[1]);
705 
706  const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"),
708  const bool select = (sel_op != SEL_OP_SUB);
709  if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
711  changed = true;
712  }
713 
714  /* do actual selection */
715  for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
716  *mask_layer_eval = mask_eval->masklayers.first;
717  mask_layer_orig != NULL;
718  mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
719  if (mask_layer_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
720  continue;
721  }
722  for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
723  *spline_eval = mask_layer_eval->splines.first;
724  spline_orig != NULL;
725  spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
726 
727  MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval);
728 
729  for (int i = 0; i < spline_orig->tot_point; i++) {
730  MaskSplinePoint *point = &spline_orig->points[i];
731  MaskSplinePoint *point_deform = &points_array[i];
732 
733  if (mask_spline_point_inside_ellipse(&point_deform->bezt, offset, ellipse)) {
736 
737  changed = true;
738  }
739  }
740  }
741  }
742 
743  if (changed) {
744  ED_mask_select_flush_all(mask_orig);
745 
746  DEG_id_tag_update(&mask_orig->id, ID_RECALC_SELECT);
747  WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask_orig);
748 
749  return OPERATOR_FINISHED;
750  }
751 
752  return OPERATOR_CANCELLED;
753 }
754 
756 {
757  /* identifiers */
758  ot->name = "Circle Select";
759  ot->description = "Select curve points using circle selection";
760  ot->idname = "MASK_OT_select_circle";
761 
762  /* api callbacks */
767 
768  /* flags */
770 
771  /* properties */
774 }
775 
778 /* -------------------------------------------------------------------- */
783 {
785  ARegion *region = CTX_wm_region(C);
786 
788  MaskLayer *mask_layer;
789  MaskSpline *spline;
790  MaskSplinePoint *point = NULL;
791  float co[2];
792  bool do_select = !RNA_boolean_get(op->ptr, "deselect");
793  const float threshold = 19;
794  bool changed = false;
795 
796  ED_mask_mouse_pos(area, region, event->mval, co);
797 
798  point = ED_mask_point_find_nearest(C, mask, co, threshold, &mask_layer, &spline, NULL, NULL);
799 
800  if (point) {
801  ED_mask_spline_select_set(spline, do_select);
802  mask_layer->act_spline = spline;
803  mask_layer->act_point = point;
804 
805  changed = true;
806  }
807 
808  if (changed) {
810 
813 
814  return OPERATOR_FINISHED;
815  }
816 
817  return OPERATOR_CANCELLED;
818 }
819 
821 {
822  /* identifiers */
823  ot->name = "Select Linked";
824  ot->idname = "MASK_OT_select_linked_pick";
825  ot->description = "(De)select all points linked to the curve under the mouse cursor";
826 
827  /* api callbacks */
830 
831  /* flags */
833 
834  RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "");
835 }
836 
839 /* -------------------------------------------------------------------- */
844 {
846 
847  bool changed = false;
848 
849  /* do actual selection */
850  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
851  if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
852  continue;
853  }
854 
855  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
856  if (ED_mask_spline_select_check(spline)) {
857  ED_mask_spline_select_set(spline, true);
858  changed = true;
859  }
860  }
861  }
862 
863  if (changed) {
865 
868 
869  return OPERATOR_FINISHED;
870  }
871 
872  return OPERATOR_CANCELLED;
873 }
874 
876 {
877  /* identifiers */
878  ot->name = "Select Linked All";
879  ot->idname = "MASK_OT_select_linked";
880  ot->description = "Select all curve points linked to already selected ones";
881 
882  /* api callbacks */
885 
886  /* flags */
888 }
889 
892 /* -------------------------------------------------------------------- */
896 static int mask_select_more_less(bContext *C, bool more)
897 {
899 
900  LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
901  if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
902  continue;
903  }
904 
905  LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
906  const bool cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0;
907  bool start_sel, end_sel, prev_sel, cur_sel;
908 
909  /* reselect point if any handle is selected to make the result more predictable */
910  for (int i = 0; i < spline->tot_point; i++) {
911  BKE_mask_point_select_set(spline->points + i, MASKPOINT_ISSEL_ANY(spline->points + i));
912  }
913 
914  /* select more/less does not affect empty/single point splines */
915  if (spline->tot_point < 2) {
916  continue;
917  }
918 
919  if (cyclic) {
920  start_sel = !!MASKPOINT_ISSEL_KNOT(spline->points);
921  end_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[spline->tot_point - 1]);
922  }
923  else {
924  start_sel = false;
925  end_sel = false;
926  }
927 
928  for (int i = 0; i < spline->tot_point; i++) {
929  if (i == 0 && !cyclic) {
930  continue;
931  }
932 
933  prev_sel = (i > 0) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i - 1]) : end_sel;
934  cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]);
935 
936  if (cur_sel != more) {
937  if (prev_sel == more) {
938  BKE_mask_point_select_set(&spline->points[i], more);
939  }
940  i++;
941  }
942  }
943 
944  for (int i = spline->tot_point - 1; i >= 0; i--) {
945  if (i == spline->tot_point - 1 && !cyclic) {
946  continue;
947  }
948 
949  prev_sel = (i < spline->tot_point - 1) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i + 1]) :
950  start_sel;
951  cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]);
952 
953  if (cur_sel != more) {
954  if (prev_sel == more) {
955  BKE_mask_point_select_set(&spline->points[i], more);
956  }
957  i--;
958  }
959  }
960  }
961  }
962 
965 
966  return OPERATOR_FINISHED;
967 }
968 
970 {
971  return mask_select_more_less(C, true);
972 }
973 
975 {
976  /* identifiers */
977  ot->name = "Select More";
978  ot->idname = "MASK_OT_select_more";
979  ot->description = "Select more spline points connected to initial selection";
980 
981  /* api callbacks */
984 
985  /* flags */
987 }
988 
990 {
991  return mask_select_more_less(C, false);
992 }
993 
995 {
996  /* identifiers */
997  ot->name = "Select Less";
998  ot->idname = "MASK_OT_select_less";
999  ot->description = "Deselect spline points at the boundary of each selection region";
1000 
1001  /* api callbacks */
1004 
1005  /* flags */
1007 }
1008 
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
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
#define MASKPOINT_ISSEL_ANY(p)
Definition: BKE_mask.h:232
void BKE_mask_point_select_set(struct MaskSplinePoint *point, const bool do_select)
Definition: mask.c:971
eMaskWhichHandle
Definition: BKE_mask.h:46
@ MASK_WHICH_HANDLE_NONE
Definition: BKE_mask.h:47
@ MASK_WHICH_HANDLE_BOTH
Definition: BKE_mask.h:51
#define MASKPOINT_ISSEL_KNOT(p)
Definition: BKE_mask.h:233
#define MASKPOINT_ISSEL_HANDLE(point, which_handle)
Definition: BKE_mask.h:235
struct MaskSplinePoint * BKE_mask_spline_point_array(struct MaskSpline *spline)
Definition: mask.c:328
void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const eMaskWhichHandle which_handle, const bool do_select)
Definition: mask.c:990
void BLI_lasso_boundbox(struct rcti *rect, const int mcoords[][2], const unsigned int mcoords_len)
Definition: lasso_2d.c:31
bool BLI_lasso_is_point_inside(const int mcoords[][2], const unsigned int mcoords_len, const int sx, const int sy, const int error_value)
Definition: lasso_2d.c:54
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
MINLINE int max_ii(int a, int b)
bool BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2])
bool BLI_rcti_isect_pt(const struct rcti *rect, const int x, const int y)
#define UNUSED(x)
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_SELECT
Definition: DNA_ID.h:638
#define MASK_RESTRICT_SELECT
#define MASK_RESTRICT_VIEW
@ MASK_SPLINE_CYCLIC
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
bool ED_clip_can_select(struct bContext *C)
void ED_mask_zoom(struct ScrArea *area, struct ARegion *region, float *zoomx, float *zoomy)
Definition: mask_query.c:726
void ED_mask_point_pos__reverse(struct ScrArea *area, struct ARegion *region, float x, float y, float *xr, float *yr)
Definition: mask_query.c:565
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_point_pos(struct ScrArea *area, struct ARegion *region, float x, float y, float *xr, float *yr)
Definition: mask_query.c:528
void ED_mask_get_size(struct ScrArea *area, int *width, int *height)
Definition: mask_query.c:691
#define SEL_OP_USE_PRE_DESELECT(sel_op)
@ SEL_SELECT
@ SEL_INVERT
@ SEL_DESELECT
@ SEL_TOGGLE
eSelectOp ED_select_op_modal(const eSelectOp sel_op, const bool is_first)
Definition: select_utils.c:77
eSelectOp
@ SEL_OP_SUB
_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 y
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_SELECT
Definition: WM_types.h:407
#define NC_MASK
Definition: WM_types.h:299
#define SELECT
const Depsgraph * depsgraph
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
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
void ED_mask_view_lock_state_store(const bContext *C, MaskViewLockState *state)
Definition: mask_edit.c:192
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_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)
void MASK_OT_select_circle(wmOperatorType *ot)
Definition: mask_select.c:755
static int mask_select_more_less(bContext *C, bool more)
Definition: mask_select.c:896
static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: mask_select.c:396
bool ED_mask_spline_select_check(const MaskSpline *spline)
Definition: mask_select.c:59
static int select_exec(bContext *C, wmOperator *op)
Definition: mask_select.c:258
void MASK_OT_select_more(wmOperatorType *ot)
Definition: mask_select.c:974
static int select_all_exec(bContext *C, wmOperator *op)
Definition: mask_select.c:215
static int box_select_exec(bContext *C, wmOperator *op)
Definition: mask_select.c:446
void MASK_OT_select(wmOperatorType *ot)
Definition: mask_select.c:410
bool ED_mask_select_check(const Mask *mask)
Definition: mask_select.c:87
static int mask_spline_point_inside_ellipse(BezTriple *bezt, const float offset[2], const float ellipse[2])
Definition: mask_select.c:665
static int clip_lasso_select_exec(bContext *C, wmOperator *op)
Definition: mask_select.c:621
static int mask_select_less_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_select.c:989
void ED_mask_layer_select_set(MaskLayer *mask_layer, const bool do_select)
Definition: mask_select.c:115
static int mask_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_select.c:843
void MASK_OT_select_less(wmOperatorType *ot)
Definition: mask_select.c:994
static int circle_select_exec(bContext *C, wmOperator *op)
Definition: mask_select.c:678
void ED_mask_spline_select_set(MaskSpline *spline, const bool do_select)
Definition: mask_select.c:99
void MASK_OT_select_linked(wmOperatorType *ot)
Definition: mask_select.c:875
bool ED_mask_layer_select_check(const MaskLayer *mask_layer)
Definition: mask_select.c:72
void MASK_OT_select_box(wmOperatorType *ot)
Definition: mask_select.c:514
void ED_mask_select_flush_all(Mask *mask)
Definition: mask_select.c:165
void MASK_OT_select_all(wmOperatorType *ot)
Definition: mask_select.c:234
void MASK_OT_select_lasso(wmOperatorType *ot)
Definition: mask_select.c:637
static bool do_lasso_select_mask(bContext *C, const int mcoords[][2], const int mcoords_len, const eSelectOp sel_op)
Definition: mask_select.c:541
void ED_mask_select_toggle_all(Mask *mask, int action)
Definition: mask_select.c:128
void ED_mask_deselect_all(const bContext *C)
Definition: mask_select.c:198
static int mask_select_more_exec(bContext *C, wmOperator *UNUSED(op))
Definition: mask_select.c:969
static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: mask_select.c:782
void MASK_OT_select_linked_pick(wmOperatorType *ot)
Definition: mask_select.c:820
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
Definition: rna_access.c:6378
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
Definition: rna_access.c:6390
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_float_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3851
float vec[3][3]
void * first
Definition: DNA_listBase.h:47
ListBase splines
struct MaskSplinePoint * act_point
char restrictflag
struct MaskSpline * act_spline
MaskSplinePointUW * uw
MaskSplinePoint * points
ListBase masklayers
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
int mval[2]
Definition: WM_types.h:583
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
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
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
struct PointerRNA * ptr
__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)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3156
bool WM_gesture_is_modal_first(const wmGesture *gesture)
Definition: wm_gesture.c:124
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
void WM_gesture_lasso_cancel(bContext *C, wmOperator *op)
int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const int(* WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *r_mcoords_len))[2]
void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
void WM_operator_properties_gesture_box(wmOperatorType *ot)
void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
void WM_operator_properties_gesture_lasso(wmOperatorType *ot)
void WM_operator_properties_gesture_circle(wmOperatorType *ot)
void WM_operator_properties_select_all(wmOperatorType *ot)
void WM_operator_properties_mouse_select(wmOperatorType *ot)