GPencil: Added operators to select first and last points of strokes
authorJoshua Leung <aligorith@gmail.com>
Mon, 9 May 2016 05:23:15 +0000 (17:23 +1200)
committerJoshua Leung <aligorith@gmail.com>
Mon, 9 May 2016 05:23:36 +0000 (17:23 +1200)
These are useful for removing overshoots at the end of closed strokes (for fills)

release/scripts/startup/bl_ui/space_view3d.py
source/blender/editors/gpencil/gpencil_intern.h
source/blender/editors/gpencil/gpencil_ops.c
source/blender/editors/gpencil/gpencil_select.c

index b4525d4f4986dc0d2534fb81df4bc3459aecdf95..2b92f20dcf6d706eada3608fc4d87808dab2dd21 100644 (file)
@@ -992,6 +992,11 @@ class VIEW3D_MT_select_gpencil(Menu):
 
         layout.separator()
 
+        layout.operator("gpencil.select_first")
+        layout.operator("gpencil.select_last")
+
+        layout.separator()
+
         layout.operator("gpencil.select_more")
         layout.operator("gpencil.select_less")
 
index 368da618a1dce3cfc1bbc659b6bde468b2fd760f..dd28f6ac531ec5ef9900e51f432158a3dfb329ee 100644 (file)
@@ -177,6 +177,8 @@ void GPENCIL_OT_select_linked(struct wmOperatorType *ot);
 void GPENCIL_OT_select_grouped(struct wmOperatorType *ot);
 void GPENCIL_OT_select_more(struct wmOperatorType *ot);
 void GPENCIL_OT_select_less(struct wmOperatorType *ot);
+void GPENCIL_OT_select_first(struct wmOperatorType *ot);
+void GPENCIL_OT_select_last(struct wmOperatorType *ot);
 
 void GPENCIL_OT_duplicate(struct wmOperatorType *ot);
 void GPENCIL_OT_delete(struct wmOperatorType *ot);
index d3520ef3e32c49605aff9a62f8499f85bbcde67c..7241d4bb632b85713d00cc6e4b7683babf411452 100644 (file)
@@ -323,6 +323,8 @@ void ED_operatortypes_gpencil(void)
        WM_operatortype_append(GPENCIL_OT_select_grouped);
        WM_operatortype_append(GPENCIL_OT_select_more);
        WM_operatortype_append(GPENCIL_OT_select_less);
+       WM_operatortype_append(GPENCIL_OT_select_first);
+       WM_operatortype_append(GPENCIL_OT_select_last);
        
        WM_operatortype_append(GPENCIL_OT_duplicate);
        WM_operatortype_append(GPENCIL_OT_delete);
index 0a36df471f17c3e3dfb323207fbe38df49441125..b6482786b4f2d47f9e55fa3520d8b1e7146e8800 100644 (file)
@@ -348,6 +348,126 @@ void GPENCIL_OT_select_grouped(wmOperatorType *ot)
        ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, GP_SEL_SAME_LAYER, "Type", "");
 }
 
+/* ********************************************** */
+/* Select First */
+
+static int gpencil_select_first_exec(bContext *C, wmOperator *op)
+{
+       const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes");
+       const bool extend = RNA_boolean_get(op->ptr, "extend");
+       
+       CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+       {
+               /* skip stroke if we're only manipulating selected strokes */
+               if (only_selected && !(gps->flag & GP_STROKE_SELECT)) {
+                       continue;
+               }
+               
+               /* select first point */
+               BLI_assert(gps->totpoints >= 1);
+               
+               gps->points->flag |= GP_SPOINT_SELECT;
+               gps->flag |= GP_STROKE_SELECT;
+               
+               /* deselect rest? */
+               if ((extend == false) && (gps->totpoints > 1)) {
+                       /* start from index 1, to skip the first point that we'd just selected... */
+                       bGPDspoint *pt = &gps->points[1];
+                       int i = 1;
+                       
+                       for (; i < gps->totpoints; i++, pt++) {
+                               pt->flag &= ~GP_SPOINT_SELECT;
+                       }
+               }
+       }
+       CTX_DATA_END;
+       
+       /* updates */
+       WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+       return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_first(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Select First";
+       ot->idname = "GPENCIL_OT_select_first";
+       ot->description = "Select first point in Grease Pencil strokes";
+       
+       /* callbacks */
+       ot->exec = gpencil_select_first_exec;
+       ot->poll = gpencil_select_poll;
+       
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+       
+       /* properties */
+       RNA_def_boolean(ot->srna, "only_selected_strokes", false, "Selected Strokes Only",
+                       "Only select the first point of strokes that already have points selected");
+       
+       RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting all other selected points");
+}
+
+/* ********************************************** */
+/* Select First */
+
+static int gpencil_select_last_exec(bContext *C, wmOperator *op)
+{
+       const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes");
+       const bool extend = RNA_boolean_get(op->ptr, "extend");
+       
+       CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+       {
+               /* skip stroke if we're only manipulating selected strokes */
+               if (only_selected && !(gps->flag & GP_STROKE_SELECT)) {
+                       continue;
+               }
+               
+               /* select last point */
+               BLI_assert(gps->totpoints >= 1);
+               
+               gps->points[gps->totpoints - 1].flag |= GP_SPOINT_SELECT;
+               gps->flag |= GP_STROKE_SELECT;
+               
+               /* deselect rest? */
+               if ((extend == false) && (gps->totpoints > 1)) {
+                       /* don't include the last point... */
+                       bGPDspoint *pt = gps->points;
+                       int i = 1;
+                       
+                       for (; i < gps->totpoints - 1; i++, pt++) {
+                               pt->flag &= ~GP_SPOINT_SELECT;
+                       }
+               }
+       }
+       CTX_DATA_END;
+       
+       /* updates */
+       WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+       return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_last(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Select Last";
+       ot->idname = "GPENCIL_OT_select_last";
+       ot->description = "Select last point in Grease Pencil strokes";
+       
+       /* callbacks */
+       ot->exec = gpencil_select_last_exec;
+       ot->poll = gpencil_select_poll;
+       
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+       
+       /* properties */
+       RNA_def_boolean(ot->srna, "only_selected_strokes", false, "Selected Strokes Only",
+                       "Only select the last point of strokes that already have points selected");
+       
+       RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting all other selected points");
+}
+
 /* ********************************************** */
 /* Select More */