[Bf-blender-cvs] [6fa8efd8159] soc-2020-greasepencil-curve: GPencil: Implement curve point circle select
Falk David
noreply at git.blender.org
Sat Jul 11 13:12:26 CEST 2020
Commit: 6fa8efd8159206da65a2d6c6da1ca71fd113da90
Author: Falk David
Date: Sat Jul 11 13:11:34 2020 +0200
Branches: soc-2020-greasepencil-curve
https://developer.blender.org/rB6fa8efd8159206da65a2d6c6da1ca71fd113da90
GPencil: Implement curve point circle select
===================================================================
M source/blender/editors/gpencil/gpencil_select.c
===================================================================
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 0a231bee5cc..1118ce2c10c 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -405,7 +405,6 @@ typedef enum eGP_SelectGrouped {
static bool gpencil_select_same_layer(bContext *C)
{
Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
@@ -460,7 +459,6 @@ static bool gpencil_select_same_layer(bContext *C)
/* Select all strokes with same colors as selected ones */
static bool gpencil_select_same_material(bContext *C)
{
- Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
/* First, build set containing all the colors of selected strokes */
@@ -1138,6 +1136,99 @@ static bool gpencil_stroke_do_circle_sel(bGPdata *gpd,
return changed;
}
+static bool gpencil_do_curve_circle_sel(bContext *C,
+ bGPdata *gpd,
+ bGPDlayer *gpl,
+ bGPDstroke *gps,
+ bGPDcurve *gpc,
+ const int mx,
+ const int my,
+ const int radius,
+ const bool select,
+ rcti *rect,
+ const float diff_mat[4][4],
+ const int selectmode)
+{
+ ARegion *region = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ const bool only_selected = (v3d->overlay.handle_display == CURVE_HANDLE_SELECTED);
+
+ bool hit = false;
+ for (int i = 0; i < gpc->tot_curve_points; i++) {
+ bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
+ BezTriple *bezt = &gpc_pt->bezt;
+
+ if (bezt->hide == 1) {
+ continue;
+ }
+
+ const bool handles_visible = (v3d->overlay.handle_display != CURVE_HANDLE_NONE) &&
+ (!only_selected || BEZT_ISSEL_ANY(bezt));
+
+ /* if the handles are not visible only check ctrl point (vec[1])*/
+ int from = (!handles_visible) ? 1 : 0;
+ int to = (!handles_visible) ? 2 : 3;
+
+ for (int j = from; j < to; j++) {
+ float parent_co[3];
+ mul_v3_m4v3(parent_co, diff_mat, bezt->vec[j]);
+ int screen_co[2];
+ /* do 2d projection */
+ if (ED_view3d_project_int_global(
+ region, parent_co, screen_co, V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) !=
+ V3D_PROJ_RET_OK) {
+ continue;
+ }
+
+ /* view and bounding box test */
+ if (ELEM(V2D_IS_CLIPPED, screen_co[0], screen_co[1]) &&
+ !BLI_rcti_isect_pt(rect, screen_co[0], screen_co[1])) {
+ continue;
+ }
+
+ /* test inside circle */
+ int dist_x = screen_co[0] - mx;
+ int dist_y = screen_co[1] - my;
+ int dist = dist_x * dist_x + dist_y * dist_y;
+ if (dist <= radius * radius) {
+ hit = true;
+ /* change selection */
+ if (select) {
+ gpc_pt->flag |= GP_CURVE_POINT_SELECT;
+ BEZT_SEL_IDX(bezt, j);
+ }
+ else {
+ BEZT_DESEL_IDX(bezt, j);
+ if (!BEZT_ISSEL_ANY(bezt)) {
+ gpc_pt->flag &= ~GP_CURVE_POINT_SELECT;
+ }
+ }
+ }
+ }
+ }
+
+ /* select the entire curve */
+ if (hit && (selectmode == GP_SELECTMODE_STROKE)) {
+ for (int i = 0; i < gpc->tot_curve_points; i++) {
+ bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
+ BezTriple *bezt = &gpc_pt->bezt;
+
+ if (select) {
+ gpc_pt->flag |= GP_CURVE_POINT_SELECT;
+ BEZT_SEL_ALL(bezt);
+ }
+ else {
+ gpc_pt->flag &= ~GP_CURVE_POINT_SELECT;
+ BEZT_DESEL_ALL(bezt);
+ }
+ }
+ }
+
+ BKE_gpencil_curve_sync_selection(gps);
+
+ return hit;
+}
+
static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -1169,11 +1260,6 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
const int my = RNA_int_get(op->ptr, "y");
const int radius = RNA_int_get(op->ptr, "radius");
- /* for bounding rect around circle (for quicky intersection testing) */
- rcti rect = {0};
-
- bool changed = false;
-
/* sanity checks */
if (area == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active area");
@@ -1184,6 +1270,18 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
WM_gesture_is_modal_first(op->customdata));
const bool select = (sel_op != SEL_OP_SUB);
+ bool changed = false;
+ /* for bounding rect around circle (for quicky intersection testing) */
+ rcti rect = {0};
+ rect.xmin = mx - radius;
+ rect.ymin = my - radius;
+ rect.xmax = mx + radius;
+ rect.ymax = my + radius;
+
+ GP_SpaceConversion gsc = {NULL};
+ /* init space conversion stuff */
+ gpencil_point_conversion_init(C, &gsc);
+
if (is_curve_edit) {
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
ED_gpencil_select_curve_toggle_all(C, SEL_DESELECT);
@@ -1191,24 +1289,19 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
}
/* TODO: do curve circle select */
+ GP_EDITABLE_CURVES_BEGIN(gps_iter, C, gpl, gps, gpc)
+ {
+ changed |= gpencil_do_curve_circle_sel(
+ C, gpd, gpl, gps, gpc, mx, my, radius, select, &rect, gps_iter.diff_mat, selectmode);
+ }
+ GP_EDITABLE_CURVES_END(gps_iter);
}
else {
- GP_SpaceConversion gsc = {NULL};
-
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
ED_gpencil_select_toggle_all(C, SEL_DESELECT);
changed = true;
}
- /* init space conversion stuff */
- gpencil_point_conversion_init(C, &gsc);
-
- /* rect is rectangle of selection circle */
- rect.xmin = mx - radius;
- rect.ymin = my - radius;
- rect.xmax = mx + radius;
- rect.ymax = my + radius;
-
/* find visible strokes, and select if hit */
GP_EVALUATED_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
changed |= gpencil_stroke_do_circle_sel(gpd,
More information about the Bf-blender-cvs
mailing list