Select more/less tool for mask splines
authorSv. Lockal <lockalsash@gmail.com>
Sat, 20 Jul 2013 10:24:16 +0000 (10:24 +0000)
committerSv. Lockal <lockalsash@gmail.com>
Sat, 20 Jul 2013 10:24:16 +0000 (10:24 +0000)
release/scripts/startup/bl_ui/properties_mask_common.py
source/blender/editors/mask/mask_edit.c
source/blender/editors/mask/mask_intern.h
source/blender/editors/mask/mask_select.c

index c9b1bc0ccff4cd23d7fd70f1716acb4a374e5d30..d38f5f934b41d6bc2fe6a19ae78bc04d61bb0ce2 100644 (file)
@@ -339,6 +339,11 @@ class MASK_MT_select(Menu):
 
         layout.separator()
 
+        layout.operator("mask.select_more")
+        layout.operator("mask.select_less")
+
+        layout.separator()
+
         layout.operator("mask.select_all").action = 'TOGGLE'
         layout.operator("mask.select_all", text="Inverse").action = 'INVERT'
 
index cd2995be4399ed97a6c9d414544388bd900f41ae..9ae5b436fb3202ca9795d37c1c2ad5df845f2f2a 100644 (file)
@@ -390,6 +390,8 @@ void ED_operatortypes_mask(void)
        WM_operatortype_append(MASK_OT_select_circle);
        WM_operatortype_append(MASK_OT_select_linked_pick);
        WM_operatortype_append(MASK_OT_select_linked);
+       WM_operatortype_append(MASK_OT_select_more);
+       WM_operatortype_append(MASK_OT_select_less);
 
        /* hide/reveal */
        WM_operatortype_append(MASK_OT_hide_view_clear);
@@ -466,6 +468,9 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
        kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
        RNA_boolean_set(kmi->ptr, "deselect", TRUE);
 
+       WM_keymap_add_item(keymap, "MASK_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
+       WM_keymap_add_item(keymap, "MASK_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
+
        /* hide/reveal */
        WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
        kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
index fcfcfb237e963b99b1606d31f734396fd0306e2f..bd148c48980bc3981689c62dc344c7f8583e26ac 100644 (file)
@@ -88,6 +88,8 @@ void MASK_OT_select_lasso(struct wmOperatorType *ot);
 void MASK_OT_select_circle(struct wmOperatorType *ot);
 void MASK_OT_select_linked_pick(struct wmOperatorType *ot);
 void MASK_OT_select_linked(struct wmOperatorType *ot);
+void MASK_OT_select_more(struct wmOperatorType *ot);
+void MASK_OT_select_less(struct wmOperatorType *ot);
 
 int ED_mask_spline_select_check(struct MaskSpline *spline);
 int ED_mask_layer_select_check(struct MaskLayer *masklay);
index 997f170c9f99d56ca95cd4fc511ef3846790a714..774a920f3669c28ee1e63c645e5a522fd59dfe48 100644 (file)
@@ -793,3 +793,115 @@ void MASK_OT_select_linked(wmOperatorType *ot)
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
+
+/**************** Select more/less **************/
+
+static int mask_select_more_less(bContext *C, bool more)
+{
+       Mask *mask = CTX_data_edit_mask(C);
+       MaskLayer *masklay;
+
+       for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+               MaskSpline *spline;
+
+               if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+                       continue;
+               }
+
+               for (spline = masklay->splines.first; spline; spline = spline->next) {
+                       int i;
+                       bool start_sel, end_sel, prev_sel, cur_sel, cyclic = spline->flag & MASK_SPLINE_CYCLIC;
+
+                       // reselect point if any handle is selected to make the result more predictable
+                       for (i = 0; i < spline->tot_point; i++) {
+                               BKE_mask_point_select_set(spline->points + i, MASKPOINT_ISSEL_ANY(spline->points + i));
+                       }
+
+                       // select more/less does not affect empty/single point splines
+                       if (spline->tot_point < 2) {
+                               continue;
+                       }
+
+                       if (cyclic) {
+                               start_sel = !!MASKPOINT_ISSEL_KNOT(spline->points);
+                               end_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[spline->tot_point - 1]);
+                       }
+
+                       for (i = 0; i < spline->tot_point; i++) {
+                               if (i == 0 && !cyclic) {
+                                       continue;
+                               }
+
+                               prev_sel = (i > 0) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i - 1]) : end_sel;
+                               cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]);
+
+                               if (cur_sel != more) {
+                                       if (prev_sel == more) {
+                                               BKE_mask_point_select_set(&spline->points[i], more);
+                                       }
+                                       i++;
+                               }
+                       }
+
+                       for (i = spline->tot_point - 1; i >= 0; i--) {
+                               if (i == spline->tot_point - 1 && !cyclic) {
+                                       continue;
+                               }
+
+                               prev_sel = (i < spline->tot_point - 1) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i + 1]) : start_sel;
+                               cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]);
+
+                               if (cur_sel != more) {
+                                       if (prev_sel == more) {
+                                               BKE_mask_point_select_set(&spline->points[i], more);
+                                       }
+                                       i--;
+                               }
+                       }
+               }
+       }
+
+       WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+
+       return OPERATOR_FINISHED;
+}
+
+static int mask_select_more_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       return mask_select_more_less(C, true);
+}
+
+void MASK_OT_select_more(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Select More";
+       ot->idname = "MASK_OT_select_more";
+       ot->description = "Select more spline points connected to initial selection";
+
+       /* api callbacks */
+       ot->exec = mask_select_more_exec;
+       ot->poll = ED_maskedit_mask_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int mask_select_less_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       return mask_select_more_less(C, false);
+}
+
+void MASK_OT_select_less(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Select Less";
+       ot->idname = "MASK_OT_select_less";
+       ot->description = "Deselect spline points at the boundary of each selection region";
+
+       /* api callbacks */
+       ot->exec = mask_select_less_exec;
+       ot->poll = ED_maskedit_mask_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}