[Bf-blender-cvs] [091e7979d31] master: GPencil: Use evaluated data in selection

Antonio Vazquez noreply at git.blender.org
Sat Aug 24 13:46:18 CEST 2019


Commit: 091e7979d314750ff9ecade6e7a3d0c08dba3a1a
Author: Antonio Vazquez
Date:   Sat Aug 24 13:46:00 2019 +0200
Branches: master
https://developer.blender.org/rB091e7979d314750ff9ecade6e7a3d0c08dba3a1a

GPencil: Use evaluated data in selection

Now the selection is using the position after evaluating the modifiers and makes possible to select a stroke point that has been moved from the original location.

Related to T66294

===================================================================

M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_select.c

===================================================================

diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 715665fe6e9..c2a9eae272f 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -639,6 +639,60 @@ struct GP_EditableStrokes_Iter {
   ((flag & (GP_SCULPT_MASK_SELECTMODE_POINT | GP_SCULPT_MASK_SELECTMODE_STROKE | \
             GP_SCULPT_MASK_SELECTMODE_SEGMENT)))
 
+/**
+ * Iterate over all editable strokes using evaluated data in the current context,
+ * stopping on each usable layer + stroke pair (i.e. gpl and gps)
+ * to perform some operations on the stroke.
+ *
+ * \param gpl: The identifier to use for the layer of the stroke being processed.
+ *                    Choose a suitable value to avoid name clashes.
+ * \param gps: The identifier to use for current stroke being processed.
+ *                    Choose a suitable value to avoid name clashes.
+ */
+#define GP_EVALUATED_STROKES_BEGIN(gpstroke_iter, C, gpl, gps) \
+  { \
+    struct GP_EditableStrokes_Iter gpstroke_iter = {{{0}}}; \
+    Depsgraph *depsgraph_ = CTX_data_ensure_evaluated_depsgraph(C); \
+    Object *obact_ = CTX_data_active_object(C); \
+    Object *obeval_ = DEG_get_evaluated_object(depsgraph_, obact_); \
+    bGPdata *gpd_ = CTX_data_gpencil_data(C); \
+    const bool is_multiedit_ = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_); \
+    int idx_eval = 0; \
+    for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { \
+      if (gpencil_layer_is_editable(gpl)) { \
+        bGPDframe *init_gpf_ = gpl->actframe; \
+        if (is_multiedit_) { \
+          init_gpf_ = gpl->frames.first; \
+        } \
+        for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
+          if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
+            ED_gpencil_parent_location(depsgraph_, obact_, gpd_, gpl, gpstroke_iter.diff_mat); \
+            invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
+            /* get evaluated frame with modifiers applied */ \
+            bGPDframe *gpf_eval_ = &obeval_->runtime.gpencil_evaluated_frames[idx_eval]; \
+            /* loop over strokes */ \
+            for (bGPDstroke *gps = gpf_eval_->strokes.first; gps; gps = gps->next) { \
+              /* skip strokes that are invalid for current view */ \
+              if (ED_gpencil_stroke_can_use(C, gps) == false) \
+                continue; \
+              /* check if the color is editable */ \
+              if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) \
+                continue; \
+    /* ... Do Stuff With Strokes ...  */
+
+#define GP_EVALUATED_STROKES_END(gpstroke_iter) \
+  } \
+  } \
+  if (!is_multiedit_) { \
+    break; \
+  } \
+  } \
+  } \
+  idx_eval++; \
+  } \
+  } \
+  (void)0
+
 /* ****************************************************** */
 
 #endif /* __GPENCIL_INTERN_H__ */
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 71ccf740153..7225bf43fbd 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -825,6 +825,7 @@ static bool gp_stroke_do_circle_sel(bGPDlayer *gpl,
 {
   bGPDspoint *pt1 = NULL;
   bGPDspoint *pt2 = NULL;
+  bGPDstroke *gps_orig = gps->runtime.gps_orig;
   int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
   int i;
   bool changed = false;
@@ -840,12 +841,12 @@ static bool gp_stroke_do_circle_sel(bGPDlayer *gpl,
       if (((x0 - mx) * (x0 - mx) + (y0 - my) * (y0 - my)) <= radius * radius) {
         /* change selection */
         if (select) {
-          gps->points->flag |= GP_SPOINT_SELECT;
-          gps->flag |= GP_STROKE_SELECT;
+          gps_orig->points->flag |= GP_SPOINT_SELECT;
+          gps_orig->flag |= GP_STROKE_SELECT;
         }
         else {
-          gps->points->flag &= ~GP_SPOINT_SELECT;
-          gps->flag &= ~GP_STROKE_SELECT;
+          gps_orig->points->flag &= ~GP_SPOINT_SELECT;
+          gps_orig->flag &= ~GP_STROKE_SELECT;
         }
 
         return true;
@@ -885,15 +886,21 @@ static bool gp_stroke_do_circle_sel(bGPDlayer *gpl,
            */
           hit = true;
           if (select) {
-            pt1->flag |= GP_SPOINT_SELECT;
-            pt2->flag |= GP_SPOINT_SELECT;
-
+            if (pt1->runtime.pt_orig != NULL) {
+              pt1->runtime.pt_orig->flag |= GP_SPOINT_SELECT;
+            }
+            if (pt2->runtime.pt_orig != NULL) {
+              pt2->runtime.pt_orig->flag |= GP_SPOINT_SELECT;
+            }
             changed = true;
           }
           else {
-            pt1->flag &= ~GP_SPOINT_SELECT;
-            pt2->flag &= ~GP_SPOINT_SELECT;
-
+            if (pt1->runtime.pt_orig != NULL) {
+              pt1->runtime.pt_orig->flag &= ~GP_SPOINT_SELECT;
+            }
+            if (pt2->runtime.pt_orig != NULL) {
+              pt2->runtime.pt_orig->flag &= ~GP_SPOINT_SELECT;
+            }
             changed = true;
           }
         }
@@ -907,24 +914,28 @@ static bool gp_stroke_do_circle_sel(bGPDlayer *gpl,
     /* if stroke mode expand selection */
     if ((hit) && (selectmode == GP_SELECTMODE_STROKE)) {
       for (i = 0, pt1 = gps->points; i < gps->totpoints; i++, pt1++) {
-        if (select) {
-          pt1->flag |= GP_SPOINT_SELECT;
-        }
-        else {
-          pt1->flag &= ~GP_SPOINT_SELECT;
+        if (pt1->runtime.pt_orig != NULL) {
+          if (select) {
+            pt1->runtime.pt_orig->flag |= GP_SPOINT_SELECT;
+          }
+          else {
+            pt1->runtime.pt_orig->flag &= ~GP_SPOINT_SELECT;
+          }
         }
       }
     }
 
     /* expand selection to segment */
-    if ((hit) && (selectmode == GP_SELECTMODE_SEGMENT) && (select)) {
+    if ((hit) && (selectmode == GP_SELECTMODE_SEGMENT) && (select) &&
+        (pt1->runtime.pt_orig != NULL)) {
       float r_hita[3], r_hitb[3];
       bool hit_select = (bool)(pt1->flag & GP_SPOINT_SELECT);
-      ED_gpencil_select_stroke_segment(gpl, gps, pt1, hit_select, false, scale, r_hita, r_hitb);
+      ED_gpencil_select_stroke_segment(
+          gpl, gps_orig, pt1->runtime.pt_orig, hit_select, false, scale, r_hita, r_hitb);
     }
 
     /* Ensure that stroke selection is in sync with its points */
-    BKE_gpencil_stroke_sync_selection(gps);
+    BKE_gpencil_stroke_sync_selection(gps_orig);
   }
 
   return changed;
@@ -982,11 +993,12 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
   rect.ymax = my + radius;
 
   /* find visible strokes, and select if hit */
-  GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
+  GP_EVALUATED_STROKES_BEGIN(gpstroke_iter, C, gpl, gps)
+  {
     changed |= gp_stroke_do_circle_sel(
         gpl, gps, &gsc, mx, my, radius, select, &rect, gpstroke_iter.diff_mat, selectmode, scale);
   }
-  GP_EDITABLE_STROKES_END(gpstroke_iter);
+  GP_EVALUATED_STROKES_END(gpstroke_iter);
 
   /* updates */
   if (changed) {
@@ -1090,27 +1102,38 @@ static int gpencil_generic_select_exec(bContext *C,
   }
 
   /* select/deselect points */
-  GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
+  GP_EVALUATED_STROKES_BEGIN(gpstroke_iter, C, gpl, gps)
+  {
 
     bGPDspoint *pt;
     int i;
     bool hit = false;
     for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+      if (pt->runtime.pt_orig == NULL) {
+        continue;
+      }
+
       /* convert point coords to screenspace */
       const bool is_inside = is_inside_fn(gps, pt, &gsc, gpstroke_iter.diff_mat, user_data);
       if (strokemode == false) {
-        const bool is_select = (pt->flag & GP_SPOINT_SELECT) != 0;
+        const bool is_select = (pt->runtime.pt_orig->flag & GP_SPOINT_SELECT) != 0;
         const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
         if (sel_op_result != -1) {
-          SET_FLAG_FROM_TEST(pt->flag, sel_op_result, GP_SPOINT_SELECT);
+          SET_FLAG_FROM_TEST(pt->runtime.pt_orig->flag, sel_op_result, GP_SPOINT_SELECT);
           changed = true;
 
           /* expand selection to segment */
           if ((sel_op_result != -1) && (segmentmode)) {
-            bool hit_select = (bool)(pt->flag & GP_SPOINT_SELECT);
+            bool hit_select = (bool)(pt->runtime.pt_orig->flag & GP_SPOINT_SELECT);
             float r_hita[3], r_hitb[3];
-            ED_gpencil_select_stroke_segment(
-                gpl, gps, pt, hit_select, false, scale, r_hita, r_hitb);
+            ED_gpencil_select_stroke_segment(gpl,
+                                             gps->runtime.gps_orig,
+                                             pt->runtime.pt_orig,
+                                             hit_select,
+                                             false,
+                                             scale,
+                                             r_hita,
+                                             r_hitb);
           }
         }
       }
@@ -1124,16 +1147,19 @@ static int gpencil_generic_select_exec(bContext *C,
 
     /* if stroke mode expand selection */
     if (strokemode) {
-      const bool is_select = BKE_gpencil_stroke_select_check(gps);
+      const bool is_select = BKE_gpencil_stroke_select_check(gps->runtime.gps_orig);
       const bool is_inside = hit;
       const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
       if (sel_op_result != -1) {
         for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+          if (pt->runtime.pt_orig == NULL) {
+            continue;
+          }
           if (sel_op_result) {
-            pt->flag |= GP_SPOINT_SELECT;
+            pt->runtime.pt_orig->flag |= GP_SPOINT_SELECT;
           }
           else {
-            pt->flag &= ~GP_SPOINT_SELECT;
+            pt->runtime.pt_orig->flag &= ~GP_SPOINT_SELECT;
           }
         }
         changed = true;
@@ -1141,9 +1167,9 @@ static int gpencil_generic_select_exec(bContext *C,
     }
 
     /* Ensure that stroke selection is in sync with its points */
-    BKE_gpencil_stroke_sync_selection(gps);
+    BKE_gpencil_stroke_sync_selection(gps->runtime.gps_orig);
   }
-

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list