[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