Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/gpencil/gpencil_select.c
| Context not available. | |||||
| #include "DNA_gpencil_types.h" | #include "DNA_gpencil_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_space_types.h" | |||||
| #include "DNA_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| Context not available. | |||||
| #include "ED_gpencil.h" | #include "ED_gpencil.h" | ||||
| #include "DEG_depsgraph.h" | |||||
| #include "gpencil_intern.h" | #include "gpencil_intern.h" | ||||
| /* ********************************************** */ | /* ********************************************** */ | ||||
| Context not available. | |||||
| { | { | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | bGPdata *gpd = ED_gpencil_data_get_active(C); | ||||
| /* we just need some visible strokes, and to be in editmode */ | /* we just need some visible strokes, and to be in editmode or other modes only to catch event */ | ||||
| if ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)) { | if (GPENCIL_ANY_MODE(gpd)) { | ||||
| /* TODO: include a check for visible strokes? */ | /* TODO: include a check for visible strokes? */ | ||||
| if (gpd->layers.first) | if (gpd->layers.first) | ||||
| return true; | return true; | ||||
| Context not available. | |||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* if not edit/sculpt mode, the event is catched but not processed */ | |||||
| if (GPENCIL_NONE_EDIT_MODE(gpd)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| /* for "toggle", test for existing selected strokes */ | /* for "toggle", test for existing selected strokes */ | ||||
| if (action == SEL_TOGGLE) { | if (action == SEL_TOGGLE) { | ||||
| action = SEL_SELECT; | action = SEL_SELECT; | ||||
| Context not available. | |||||
| } | } | ||||
| /* updates */ | /* updates */ | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| Context not available. | |||||
| BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); | BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* if not edit/sculpt mode, the event is catched but not processed */ | |||||
| if (GPENCIL_NONE_EDIT_MODE(gpd)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| /* select all points in selected strokes */ | /* select all points in selected strokes */ | ||||
| CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | ||||
| { | { | ||||
| Context not available. | |||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| /* updates */ | /* updates */ | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| Context not available. | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| } | } | ||||
| /* ********************************************** */ | |||||
| /* Select Alternate */ | |||||
| static int gpencil_select_alternate_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| const bool unselect_ends = RNA_boolean_get(op->ptr, "unselect_ends"); | |||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| if (gpd == NULL) { | |||||
| BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| /* if not edit/sculpt mode, the event is catched but not processed */ | |||||
| if (GPENCIL_NONE_EDIT_MODE(gpd)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| /* select all points in selected strokes */ | |||||
| CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | |||||
| { | |||||
| if ((gps->flag & GP_STROKE_SELECT) && (gps->totpoints > 1)) { | |||||
| bGPDspoint *pt; | |||||
| int row = 0; | |||||
| int start = 0; | |||||
| if (unselect_ends) { | |||||
| start = 1; | |||||
| } | |||||
| for (int i = start; i < gps->totpoints; i++) { | |||||
| pt = &gps->points[i]; | |||||
| if ((row % 2) == 0) { | |||||
| pt->flag |= GP_SPOINT_SELECT; | |||||
| } | |||||
| else { | |||||
| pt->flag &= ~GP_SPOINT_SELECT; | |||||
| } | |||||
| row++; | |||||
| } | |||||
| /* unselect start and end points */ | |||||
| if (unselect_ends) { | |||||
| pt = &gps->points[0]; | |||||
| pt->flag &= ~GP_SPOINT_SELECT; | |||||
| pt = &gps->points[gps->totpoints - 1]; | |||||
| pt->flag &= ~GP_SPOINT_SELECT; | |||||
| } | |||||
| } | |||||
| } | |||||
| CTX_DATA_END; | |||||
| /* updates */ | |||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| void GPENCIL_OT_select_alternate(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Alternated"; | |||||
| ot->idname = "GPENCIL_OT_select_alternate"; | |||||
| ot->description = "Select alternative points in same strokes as already selected points"; | |||||
| /* callbacks */ | |||||
| ot->exec = gpencil_select_alternate_exec; | |||||
| ot->poll = gpencil_select_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| /* properties */ | |||||
| RNA_def_boolean(ot->srna, "unselect_ends", true, "Unselect Ends", "Do not select the first and last point of the stroke"); | |||||
| } | |||||
| /* ********************************************** */ | /* ********************************************** */ | ||||
| /* Select Grouped */ | /* Select Grouped */ | ||||
| Context not available. | |||||
| /* Select all strokes with same colors as selected ones */ | /* Select all strokes with same colors as selected ones */ | ||||
| static void gp_select_same_color(bContext *C) | static void gp_select_same_color(bContext *C) | ||||
| { | { | ||||
| /* First, build set containing all the colors of selected strokes | /* First, build set containing all the colors of selected strokes */ | ||||
| * - We use the palette names, so that we can select all strokes with one | |||||
| * (potentially missing) color, and remap them to something else | |||||
| */ | |||||
| GSet *selected_colors = BLI_gset_str_new("GP Selected Colors"); | GSet *selected_colors = BLI_gset_str_new("GP Selected Colors"); | ||||
| CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | ||||
| Context not available. | |||||
| /* add instead of insert here, otherwise the uniqueness check gets skipped, | /* add instead of insert here, otherwise the uniqueness check gets skipped, | ||||
| * and we get many duplicate entries... | * and we get many duplicate entries... | ||||
| */ | */ | ||||
| BLI_gset_add(selected_colors, gps->colorname); | BLI_gset_add(selected_colors, &gps->mat_nr); | ||||
| } | } | ||||
| } | } | ||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| Context not available. | |||||
| /* Second, select any visible stroke that uses these colors */ | /* Second, select any visible stroke that uses these colors */ | ||||
| CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | ||||
| { | { | ||||
| if (BLI_gset_haskey(selected_colors, gps->colorname)) { | if (BLI_gset_haskey(selected_colors, &gps->mat_nr)) { | ||||
| /* select this stroke */ | /* select this stroke */ | ||||
| bGPDspoint *pt; | bGPDspoint *pt; | ||||
| int i; | int i; | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| /* free memomy */ | |||||
| if (selected_colors != NULL) { | |||||
| BLI_gset_free(selected_colors, NULL); | |||||
| } | |||||
| } | } | ||||
| Context not available. | |||||
| static int gpencil_select_grouped_exec(bContext *C, wmOperator *op) | static int gpencil_select_grouped_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| eGP_SelectGrouped mode = RNA_enum_get(op->ptr, "type"); | eGP_SelectGrouped mode = RNA_enum_get(op->ptr, "type"); | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| /* if not edit/sculpt mode, the event is catched but not processed */ | |||||
| if (GPENCIL_NONE_EDIT_MODE(gpd)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| switch (mode) { | switch (mode) { | ||||
| case GP_SEL_SAME_LAYER: | case GP_SEL_SAME_LAYER: | ||||
| gp_select_same_layer(C); | gp_select_same_layer(C); | ||||
| Context not available. | |||||
| } | } | ||||
| /* updates */ | /* updates */ | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| Context not available. | |||||
| static int gpencil_select_first_exec(bContext *C, wmOperator *op) | static int gpencil_select_first_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| /* if not edit/sculpt mode, the event is catched but not processed */ | |||||
| if (GPENCIL_NONE_EDIT_MODE(gpd)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes"); | const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes"); | ||||
| const bool extend = RNA_boolean_get(op->ptr, "extend"); | const bool extend = RNA_boolean_get(op->ptr, "extend"); | ||||
| Context not available. | |||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| /* updates */ | /* updates */ | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| Context not available. | |||||
| static int gpencil_select_last_exec(bContext *C, wmOperator *op) | static int gpencil_select_last_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| /* if not edit/sculpt mode, the event is catched but not processed */ | |||||
| if (GPENCIL_NONE_EDIT_MODE(gpd)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes"); | const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes"); | ||||
| const bool extend = RNA_boolean_get(op->ptr, "extend"); | const bool extend = RNA_boolean_get(op->ptr, "extend"); | ||||
| Context not available. | |||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| /* updates */ | /* updates */ | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| Context not available. | |||||
| static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op)) | static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| /* if not edit/sculpt mode, the event is catched but not processed */ | |||||
| if (GPENCIL_NONE_EDIT_MODE(gpd)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | ||||
| { | { | ||||
| if (gps->flag & GP_STROKE_SELECT) { | if (gps->flag & GP_STROKE_SELECT) { | ||||
| Context not available. | |||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| /* updates */ | /* updates */ | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| Context not available. | |||||
| static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op)) | static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| /* if not edit/sculpt mode, the event is catched but not processed */ | |||||
| if (GPENCIL_NONE_EDIT_MODE(gpd)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) | ||||
| { | { | ||||
| if (gps->flag & GP_STROKE_SELECT) { | if (gps->flag & GP_STROKE_SELECT) { | ||||
| Context not available. | |||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| /* updates */ | /* updates */ | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| Context not available. | |||||
| static bool gp_stroke_do_circle_sel( | static bool gp_stroke_do_circle_sel( | ||||
| bGPDstroke *gps, GP_SpaceConversion *gsc, | bGPDstroke *gps, GP_SpaceConversion *gsc, | ||||
| const int mx, const int my, const int radius, | const int mx, const int my, const int radius, | ||||
| const bool select, rcti *rect, const bool parented, float diff_mat[4][4]) | const bool select, rcti *rect, float diff_mat[4][4]) | ||||
| { | { | ||||
| bGPDspoint *pt1, *pt2; | bGPDspoint *pt1, *pt2; | ||||
| int x0 = 0, y0 = 0, x1 = 0, y1 = 0; | int x0 = 0, y0 = 0, x1 = 0, y1 = 0; | ||||
| Context not available. | |||||
| bool changed = false; | bool changed = false; | ||||
| if (gps->totpoints == 1) { | if (gps->totpoints == 1) { | ||||
| if (!parented) { | bGPDspoint pt_temp; | ||||
| gp_point_to_xy(gsc, gps, gps->points, &x0, &y0); | gp_point_to_parent_space(gps->points, diff_mat, &pt_temp); | ||||
| } | gp_point_to_xy(gsc, gps, &pt_temp, &x0, &y0); | ||||
| else { | |||||
| bGPDspoint pt_temp; | |||||
| gp_point_to_parent_space(gps->points, diff_mat, &pt_temp); | |||||
| gp_point_to_xy(gsc, gps, &pt_temp, &x0, &y0); | |||||
| } | |||||
| /* do boundbox check first */ | /* do boundbox check first */ | ||||
| if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) { | if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) { | ||||
| Context not available. | |||||
| /* get points to work with */ | /* get points to work with */ | ||||
| pt1 = gps->points + i; | pt1 = gps->points + i; | ||||
| pt2 = gps->points + i + 1; | pt2 = gps->points + i + 1; | ||||
| if (!parented) { | bGPDspoint npt; | ||||
| gp_point_to_xy(gsc, gps, pt1, &x0, &y0); | gp_point_to_parent_space(pt1, diff_mat, &npt); | ||||
| gp_point_to_xy(gsc, gps, pt2, &x1, &y1); | gp_point_to_xy(gsc, gps, &npt, &x0, &y0); | ||||
| } | |||||
| else { | |||||
| bGPDspoint npt; | |||||
| gp_point_to_parent_space(pt1, diff_mat, &npt); | |||||
| gp_point_to_xy(gsc, gps, &npt, &x0, &y0); | |||||
| gp_point_to_parent_space(pt2, diff_mat, &npt); | gp_point_to_parent_space(pt2, diff_mat, &npt); | ||||
| gp_point_to_xy(gsc, gps, &npt, &x1, &y1); | gp_point_to_xy(gsc, gps, &npt, &x1, &y1); | ||||
| } | |||||
| /* check that point segment of the boundbox of the selection stroke */ | /* check that point segment of the boundbox of the selection stroke */ | ||||
| if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) || | if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) || | ||||
| Context not available. | |||||
| static int gpencil_circle_select_exec(bContext *C, wmOperator *op) | static int gpencil_circle_select_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| /* if not edit/sculpt mode, the event is catched but not processed */ | |||||
| if (GPENCIL_NONE_EDIT_MODE(gpd)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| ScrArea *sa = CTX_wm_area(C); | ScrArea *sa = CTX_wm_area(C); | ||||
| const int mx = RNA_int_get(op->ptr, "x"); | const int mx = RNA_int_get(op->ptr, "x"); | ||||
| Context not available. | |||||
| GP_EDITABLE_STROKES_BEGIN(C, gpl, gps) | GP_EDITABLE_STROKES_BEGIN(C, gpl, gps) | ||||
| { | { | ||||
| changed |= gp_stroke_do_circle_sel( | changed |= gp_stroke_do_circle_sel( | ||||
| gps, &gsc, mx, my, radius, select, &rect, | gps, &gsc, mx, my, radius, select, &rect, diff_mat); | ||||
| (gpl->parent != NULL), diff_mat); | |||||
| } | } | ||||
| GP_EDITABLE_STROKES_END; | GP_EDITABLE_STROKES_END; | ||||
| /* updates */ | /* updates */ | ||||
| if (changed) { | if (changed) { | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| } | } | ||||
| Context not available. | |||||
| static int gpencil_border_select_exec(bContext *C, wmOperator *op) | static int gpencil_border_select_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| ScrArea *sa = CTX_wm_area(C); | ScrArea *sa = CTX_wm_area(C); | ||||
| const bool select = !RNA_boolean_get(op->ptr, "deselect"); | const bool select = !RNA_boolean_get(op->ptr, "deselect"); | ||||
| const bool extend = RNA_boolean_get(op->ptr, "extend"); | const bool extend = RNA_boolean_get(op->ptr, "extend") && ((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0); | ||||
| GP_SpaceConversion gsc = {NULL}; | GP_SpaceConversion gsc = {NULL}; | ||||
| rcti rect = {0}; | rcti rect = {0}; | ||||
| Context not available. | |||||
| int x0, y0; | int x0, y0; | ||||
| /* convert point coords to screenspace */ | /* convert point coords to screenspace */ | ||||
| if (gpl->parent == NULL) { | bGPDspoint pt2; | ||||
| gp_point_to_xy(&gsc, gps, pt, &x0, &y0); | gp_point_to_parent_space(pt, diff_mat, &pt2); | ||||
| } | gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0); | ||||
| else { | |||||
| bGPDspoint pt2; | |||||
| gp_point_to_parent_space(pt, diff_mat, &pt2); | |||||
| gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0); | |||||
| } | |||||
| /* test if in selection rect */ | /* test if in selection rect */ | ||||
| if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0)) { | if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0)) { | ||||
| Context not available. | |||||
| } | } | ||||
| GP_EDITABLE_STROKES_END; | GP_EDITABLE_STROKES_END; | ||||
| /* if paint mode,delete selected points */ | |||||
| if (gpd->flag & GP_DATA_STROKE_PAINTMODE) { | |||||
| gp_delete_selected_point_wrap(C); | |||||
| changed = true; | |||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); | |||||
| } | |||||
| /* updates */ | /* updates */ | ||||
| if (changed) { | if (changed) { | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| } | } | ||||
| Context not available. | |||||
| static int gpencil_lasso_select_exec(bContext *C, wmOperator *op) | static int gpencil_lasso_select_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| GP_SpaceConversion gsc = {NULL}; | GP_SpaceConversion gsc = {NULL}; | ||||
| rcti rect = {0}; | rcti rect = {0}; | ||||
| const bool extend = RNA_boolean_get(op->ptr, "extend"); | const bool extend = RNA_boolean_get(op->ptr, "extend") && ((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0); | ||||
| const bool select = !RNA_boolean_get(op->ptr, "deselect"); | const bool select = !RNA_boolean_get(op->ptr, "deselect"); | ||||
| int mcords_tot; | int mcords_tot; | ||||
| Context not available. | |||||
| int x0, y0; | int x0, y0; | ||||
| /* convert point coords to screenspace */ | /* convert point coords to screenspace */ | ||||
| if (gpl->parent == NULL) { | bGPDspoint pt2; | ||||
| gp_point_to_xy(&gsc, gps, pt, &x0, &y0); | gp_point_to_parent_space(pt, diff_mat, &pt2); | ||||
| } | gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0); | ||||
| else { | |||||
| bGPDspoint pt2; | |||||
| gp_point_to_parent_space(pt, diff_mat, &pt2); | |||||
| gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0); | |||||
| } | |||||
| /* test if in lasso boundbox + within the lasso noose */ | /* test if in lasso boundbox + within the lasso noose */ | ||||
| if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0) && | 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)) | BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX)) | ||||
| Context not available. | |||||
| /* cleanup */ | /* cleanup */ | ||||
| MEM_freeN((void *)mcords); | MEM_freeN((void *)mcords); | ||||
| /* if paint mode,delete selected points */ | |||||
| if (gpd->flag & GP_DATA_STROKE_PAINTMODE) { | |||||
| gp_delete_selected_point_wrap(C); | |||||
| changed = true; | |||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); | |||||
| } | |||||
| /* updates */ | /* updates */ | ||||
| if (changed) { | if (changed) { | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| } | } | ||||
| Context not available. | |||||
| static int gpencil_select_exec(bContext *C, wmOperator *op) | static int gpencil_select_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| ScrArea *sa = CTX_wm_area(C); | ScrArea *sa = CTX_wm_area(C); | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| /* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */ | /* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */ | ||||
| const float radius = 0.75f * U.widget_unit; | const float radius = 0.75f * U.widget_unit; | ||||
| const int radius_squared = (int)(radius * radius); | const int radius_squared = (int)(radius * radius); | ||||
| Context not available. | |||||
| for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { | for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { | ||||
| int xy[2]; | int xy[2]; | ||||
| if (gpl->parent == NULL) { | bGPDspoint pt2; | ||||
| gp_point_to_xy(&gsc, gps, pt, &xy[0], &xy[1]); | gp_point_to_parent_space(pt, diff_mat, &pt2); | ||||
| } | gp_point_to_xy(&gsc, gps, &pt2, &xy[0], &xy[1]); | ||||
| else { | |||||
| bGPDspoint pt2; | |||||
| gp_point_to_parent_space(pt, diff_mat, &pt2); | |||||
| gp_point_to_xy(&gsc, gps, &pt2, &xy[0], &xy[1]); | |||||
| } | |||||
| /* do boundbox check first */ | /* do boundbox check first */ | ||||
| if (!ELEM(V2D_IS_CLIPPED, xy[0], xy[1])) { | if (!ELEM(V2D_IS_CLIPPED, xy[0], xy[1])) { | ||||
| Context not available. | |||||
| /* updates */ | /* updates */ | ||||
| if (hit_point != NULL) { | if (hit_point != NULL) { | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); | ||||
| } | } | ||||
| Context not available. | |||||