Lasso Select for GPencil Strokes

This commit is contained in:
Joshua Leung 2014-12-02 13:52:48 +13:00
parent 8b6759a4a9
commit 367204a063
Notes: blender-bot 2023-02-14 09:44:56 +01:00
Referenced by issue #42806, Cannot customize shortcut for Loop Cut and Slide
4 changed files with 116 additions and 0 deletions

View File

@ -195,12 +195,14 @@ class GPENCIL_PIE_tool_palette(Menu):
# NW - Select (Non-Modal)
col = pie.column()
col.operator("gpencil.select_all", text="Select All", icon='PARTICLE_POINT')
col.operator("gpencil.select_all", text="Select Inverse", icon='BLANK1')
col.operator("gpencil.select_linked", text="Select Linked", icon='LINKED')
# NE - Select (Modal)
col = pie.column()
col.operator("gpencil.select_border", text="Border Select", icon='BORDER_RECT')
col.operator("gpencil.select_circle", text="Circle Select", icon='META_EMPTY')
col.operator("gpencil.select_lasso", text="Lasso Select", icon='BORDER_LASSO')
# SW - Edit Tools
col = pie.column()

View File

@ -117,6 +117,7 @@ void GPENCIL_OT_select(struct wmOperatorType *ot);
void GPENCIL_OT_select_all(struct wmOperatorType *ot);
void GPENCIL_OT_select_circle(struct wmOperatorType *ot);
void GPENCIL_OT_select_border(struct wmOperatorType *ot);
void GPENCIL_OT_select_lasso(struct wmOperatorType *ot);
void GPENCIL_OT_select_linked(struct wmOperatorType *ot);
void GPENCIL_OT_select_more(struct wmOperatorType *ot);

View File

@ -124,6 +124,12 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
/* border select */
WM_keymap_add_item(keymap, "GPENCIL_OT_select_border", BKEY, KM_PRESS, 0, 0);
/* lasso select */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "deselect", true);
/* normal select */
WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
@ -201,6 +207,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_select_all);
WM_operatortype_append(GPENCIL_OT_select_circle);
WM_operatortype_append(GPENCIL_OT_select_border);
WM_operatortype_append(GPENCIL_OT_select_lasso);
WM_operatortype_append(GPENCIL_OT_select_linked);
WM_operatortype_append(GPENCIL_OT_select_more);

View File

@ -37,6 +37,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_lasso.h"
#include "BLI_utildefines.h"
#include "DNA_gpencil_types.h"
@ -657,6 +658,111 @@ void GPENCIL_OT_select_border(wmOperatorType *ot)
WM_operator_properties_gesture_border(ot, true);
}
/* ********************************************** */
/* Lasso */
static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
{
GP_SpaceConversion gsc = {NULL};
rcti rect = {0};
const bool extend = RNA_boolean_get(op->ptr, "extend");
const bool select = !RNA_boolean_get(op->ptr, "deselect");
int mcords_tot;
const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
bool changed = false;
/* sanity check */
if (mcords == NULL)
return OPERATOR_PASS_THROUGH;
/* compute boundbox of lasso (for faster testing later) */
BLI_lasso_boundbox(&rect, mcords, mcords_tot);
/* init space conversion stuff */
gp_point_conversion_init(C, &gsc);
/* deselect all strokes first? */
if (select && !extend) {
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
bGPDspoint *pt;
int i;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
gps->flag &= ~GP_STROKE_SELECT;
}
CTX_DATA_END;
}
/* select/deselect points */
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
bGPDspoint *pt;
int i;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
int x0, y0;
/* convert point coords to screenspace */
gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
/* test if in lasso boundbox + within the lasso noose */
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0) &&
BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX))
{
if (select) {
pt->flag |= GP_SPOINT_SELECT;
}
else {
pt->flag &= ~GP_SPOINT_SELECT;
}
changed = true;
}
}
/* Ensure that stroke selection is in sync with its points */
gpencil_stroke_sync_selection(gps);
}
CTX_DATA_END;
/* cleanup */
MEM_freeN((void *)mcords);
/* updates */
if (changed) {
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
}
return OPERATOR_FINISHED;
}
void GPENCIL_OT_select_lasso(wmOperatorType *ot)
{
ot->name = "Lasso Select Strokes";
ot->description = "Select Grease Pencil strokes using lasso selection";
ot->idname = "GPENCIL_OT_select_lasso";
ot->invoke = WM_gesture_lasso_invoke;
ot->modal = WM_gesture_lasso_modal;
ot->exec = gpencil_lasso_select_exec;
ot->poll = gpencil_select_poll;
ot->cancel = WM_gesture_lasso_cancel;
/* flags */
ot->flag = OPTYPE_UNDO;
RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items");
RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first");
}
/* ********************************************** */
/* Mouse Click to Select */