[Bf-blender-cvs] [a0562388286] temp-gpencil-bezier-v2: GPencil: Add click select for curves
Falk David
noreply at git.blender.org
Sat Mar 6 16:34:39 CET 2021
Commit: a0562388286cca680dd6a169ed787a019573ac20
Author: Falk David
Date: Sat Mar 6 16:31:53 2021 +0100
Branches: temp-gpencil-bezier-v2
https://developer.blender.org/rBa0562388286cca680dd6a169ed787a019573ac20
GPencil: Add click select for curves
Adapts the click selection code to handle curves.
===================================================================
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 0f61818c909..a15d0cf155d 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -2095,56 +2095,90 @@ void GPENCIL_OT_select_lasso(wmOperatorType *ot)
/** \name Mouse Pick Select Operator
* \{ */
-static void gpencil_select_curve_point(bContext *C,
- const int mval[2],
- const int radius_squared,
- bGPDlayer **r_gpl,
- bGPDstroke **r_gps,
- bGPDcurve **r_gpc,
- bGPDcurve_point **r_pt,
- char *handle)
+static bool gpencil_select_curve_point_closest(bContext *C,
+ bGPDcurve *gpc,
+ struct GP_EditableStrokes_Iter *gps_iter,
+ const int mval[2],
+ const int radius_squared,
+ bGPDcurve_point **r_pt,
+ int *handle_idx,
+ int *hit_distance)
{
+ bool hit = false;
ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
const bool only_selected = (v3d->overlay.handle_display == CURVE_HANDLE_SELECTED);
- int hit_distance = radius_squared;
+ for (int i = 0; i < gpc->tot_curve_points; i++) {
+ bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
+ BezTriple *bezt = &gpc_pt->bezt;
+ bGPDcurve_point *gpc_active_pt = (gpc_pt->runtime.gpc_pt_orig) ? gpc_pt->runtime.gpc_pt_orig :
+ gpc_pt;
- GP_EDITABLE_CURVES_BEGIN(gps_iter, C, gpl, gps, gpc)
- {
- 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;
+ }
- if (bezt->hide == 1) {
- continue;
- }
+ const bool handles_visible = (v3d->overlay.handle_display != CURVE_HANDLE_NONE) &&
+ (!only_selected || BEZT_ISSEL_ANY(bezt));
- 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++) {
- int screen_co[2];
- if (gpencil_3d_point_to_screen_space(region, gps_iter.diff_mat, bezt->vec[j], screen_co)) {
- const int pt_distance = len_manhattan_v2v2_int(mval, screen_co);
-
- if (pt_distance <= radius_squared && pt_distance < hit_distance) {
- *r_gpl = gpl;
- *r_gps = gps;
- *r_gpc = gpc;
- *r_pt = gpc_pt;
- *handle = j;
- hit_distance = pt_distance;
- }
+ /* 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++) {
+ int screen_co[2];
+ if (gpencil_3d_point_to_screen_space(region, gps_iter->diff_mat, bezt->vec[j], screen_co)) {
+ const int pt_distance = len_manhattan_v2v2_int(mval, screen_co);
+
+ if (pt_distance <= radius_squared && pt_distance < *hit_distance) {
+ *r_pt = gpc_active_pt;
+ *handle_idx = j;
+ *hit_distance = pt_distance;
+ hit = true;
}
}
}
}
- GP_EDITABLE_CURVES_END(gps_iter);
+
+ return hit;
+}
+
+static bool gpencil_select_stroke_point_closest(bGPDstroke *gps,
+ struct GP_EditableStrokes_Iter *gps_iter,
+ GP_SpaceConversion *gsc,
+ const int mval[2],
+ const int radius_squared,
+ bGPDspoint **r_pt,
+ int *hit_distance)
+{
+ bool hit = false;
+ bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
+
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ bGPDspoint *pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
+ int xy[2];
+
+ bGPDspoint pt2;
+ gpencil_point_to_parent_space(pt, gps_iter->diff_mat, &pt2);
+ gpencil_point_to_xy(gsc, gps_active, &pt2, &xy[0], &xy[1]);
+
+ /* do boundbox check first */
+ if (!ELEM(V2D_IS_CLIPPED, xy[0], xy[1])) {
+ const int pt_distance = len_manhattan_v2v2_int(mval, xy);
+
+ /* check if point is inside */
+ if (pt_distance <= radius_squared && pt_distance < *hit_distance) {
+ /* only use this point if it is a better match than the current hit - T44685 */
+ *r_pt = pt_active;
+ *hit_distance = pt_distance;
+ hit = true;
+ }
+ }
+ }
+
+ return hit;
}
static int gpencil_select_exec(bContext *C, wmOperator *op)
@@ -2154,7 +2188,6 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
bGPdata *gpd = ED_gpencil_data_get_active(C);
ToolSettings *ts = CTX_data_tool_settings(C);
const float scale = ts->gp_sculpt.isect_threshold;
- const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
/* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */
const float radius = 0.4f * U.widget_unit;
@@ -2171,14 +2204,12 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
/* get mouse location */
RNA_int_get_array(op->ptr, "location", mval);
- GP_SpaceConversion gsc = {NULL};
-
bGPDlayer *hit_layer = NULL;
bGPDstroke *hit_stroke = NULL;
bGPDspoint *hit_point = NULL;
bGPDcurve *hit_curve = NULL;
bGPDcurve_point *hit_curve_point = NULL;
- char hit_curve_handle = 0;
+ int hit_curve_handle_idx = 0;
int hit_distance = radius_squared;
/* sanity checks */
@@ -2200,62 +2231,46 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
whole = (bool)(ts->gpencil_selectmode_edit == GP_SELECTMODE_STROKE);
}
- if (is_curve_edit) {
- gpencil_select_curve_point(C,
- mval,
- radius_squared,
- &hit_layer,
- &hit_stroke,
- &hit_curve,
- &hit_curve_point,
- &hit_curve_handle);
- }
-
- if (hit_curve == NULL) {
- /* init space conversion stuff */
- gpencil_point_conversion_init(C, &gsc);
-
- /* First Pass: Find stroke point which gets hit */
- GP_EVALUATED_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
- bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
- bGPDspoint *pt;
- int i;
+ GP_SpaceConversion gsc = {NULL};
+ /* init space conversion stuff */
+ gpencil_point_conversion_init(C, &gsc);
- /* firstly, check for hit-point */
- for (i = 0, pt = gps_active->points; i < gps_active->totpoints; i++, pt++) {
- int xy[2];
-
- bGPDspoint pt2;
- gpencil_point_to_parent_space(pt, gpstroke_iter.diff_mat, &pt2);
- gpencil_point_to_xy(&gsc, gps_active, &pt2, &xy[0], &xy[1]);
-
- /* do boundbox check first */
- if (!ELEM(V2D_IS_CLIPPED, xy[0], xy[1])) {
- const int pt_distance = len_manhattan_v2v2_int(mval, xy);
-
- /* check if point is inside */
- if (pt_distance <= radius_squared) {
- /* only use this point if it is a better match than the current hit - T44685 */
- if (pt_distance < hit_distance) {
- hit_layer = gpl;
- hit_stroke = gps_active;
- hit_point = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
- hit_distance = pt_distance;
- }
- }
- }
+ /* First Pass: Find point which gets hit */
+ GP_EVALUATED_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
+ bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
+ if (GPENCIL_STROKE_IS_CURVE(gps_active)) {
+ bGPDcurve *gpc = gps->editcurve;
+ bGPDcurve *gpc_active = (gpc->runtime.gpc_orig) ? gpc->runtime.gpc_orig : gpc;
+ if (gpencil_select_curve_point_closest(C,
+ gpc,
+ &gpstroke_iter,
+ mval,
+ radius_squared,
+ &hit_curve_point,
+ &hit_curve_handle_idx,
+ &hit_distance)) {
+ hit_layer = gpl;
+ hit_stroke = gps_active;
+ hit_point = &gps->points[hit_curve_point->point_index];
+ hit_curve = gpc_active;
+ }
+ }
+ else {
+ if (gpencil_select_stroke_point_closest(
+ gps, &gpstroke_iter, &gsc, mval, radius_squared, &hit_point, &hit_distance)) {
+ hit_layer = gpl;
+ hit_stroke = gps_active;
}
}
- GP_EVALUATED_STROKES_END(gpstroke_iter);
}
+ GP_EVALUATED_STROKES_END(gpstroke_iter);
/* Abort if nothing hit... */
- if (!hit_curve && !hit_curve_point && !hit_point && !hit_stroke) {
-
+ if ((hit_curve == NULL && hit_curve_point == NULL) &&
+ (hit_point == NULL && hit_stroke == NULL)) {
if (deselect_all) {
/* since left mouse select change, deselect all if click outside any hit */
deselect_all_selected(C);
-
/* copy on write tag is needed, or else no refresh happens */
DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY)
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list