[Bf-blender-cvs] [331e1639c49] soc-2020-greasepencil-curve: GPencil: Fix curve point deletion in cyclic curve

Falk David noreply at git.blender.org
Thu Jul 30 14:57:45 CEST 2020


Commit: 331e1639c49989e83da3467e1d9a3dc41a197ac3
Author: Falk David
Date:   Thu Jul 30 14:52:29 2020 +0200
Branches: soc-2020-greasepencil-curve
https://developer.blender.org/rB331e1639c49989e83da3467e1d9a3dc41a197ac3

GPencil: Fix curve point deletion in cyclic curve

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

M	source/blender/blenkernel/intern/gpencil_curve.c
M	source/blender/editors/gpencil/gpencil_edit.c

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

diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index 2d1fe8fccd6..96bee649844 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -988,7 +988,7 @@ void BKE_gpencil_editcurve_recalculate_handles(bGPDstroke *gps)
 
   bool changed = false;
   bGPDcurve *gpc = gps->editcurve;
-  if (gpc->tot_curve_points < 1) {
+  if (gpc->tot_curve_points < 2) {
     return;
   }
 
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 962aeb692bf..61fe7c7e905 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -2057,7 +2057,6 @@ typedef enum eGP_DissolveMode {
 static int gpencil_delete_selected_strokes(bContext *C)
 {
   bGPdata *gpd = ED_gpencil_data_get_active(C);
-  const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
   const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
 
   bool changed = false;
@@ -2720,19 +2719,22 @@ void gpencil_stroke_delete_tagged_points(bGPdata *gpd,
   BKE_gpencil_free_stroke(gps);
 }
 
-void gpencil_curve_delete_tagged_points(bGPdata *gpd,
-                                        bGPDframe *gpf,
-                                        bGPDstroke *gps,
-                                        bGPDstroke *next_stroke,
-                                        bGPDcurve *gpc,
-                                        int tag_flags,
-                                        bool select,
-                                        int limit)
+static void gpencil_curve_delete_tagged_points(bGPdata *gpd,
+                                               bGPDframe *gpf,
+                                               bGPDstroke *gps,
+                                               bGPDstroke *next_stroke,
+                                               bGPDcurve *gpc,
+                                               int tag_flags,
+                                               bool select,
+                                               int limit)
 {
   if (gpc == NULL) {
     return;
   }
   const bool is_cyclic = gps->flag & GP_STROKE_CYCLIC;
+  const int idx_last = gpc->tot_curve_points - 1;
+  bGPDstroke *gps_first = NULL;
+  bGPDstroke *gps_last = NULL;
 
   int idx_start = 0;
   int idx_end = 0;
@@ -2742,16 +2744,35 @@ void gpencil_curve_delete_tagged_points(bGPdata *gpd,
     if (prev_selected == true && selected == false) {
       idx_start = i;
     }
-    if ((prev_selected == false && selected == true) ||
-        (selected == false && i == gpc->tot_curve_points - 1)) {
-      idx_end = selected ? i - 1 : i;
+    /* Island ends if the current point is selected or if we reached the end of the stroke */
+    if ((prev_selected == false && selected == true) || (selected == false && i == idx_last)) {
 
+      idx_end = selected ? i - 1 : i;
       int island_length = idx_end - idx_start + 1;
+
+      /* If an island has only a single curve point, there is no curve segment, so skip island */
+      if (island_length == 1) {
+        if (is_cyclic) {
+          if (idx_start > 0 && idx_end < idx_last) {
+            prev_selected = selected;
+            continue;
+          }
+        }
+        else {
+          prev_selected = selected;
+          continue;
+        }
+      }
+
       bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps, false, false);
       new_stroke->points = NULL;
       new_stroke->flag &= ~GP_STROKE_CYCLIC;
       new_stroke->editcurve = BKE_gpencil_stroke_editcurve_new(island_length);
 
+      if (gps_first == NULL) {
+        gps_first = new_stroke;
+      }
+
       bGPDcurve *new_gpc = new_stroke->editcurve;
       memcpy(new_gpc->curve_points,
              gpc->curve_points + idx_start,
@@ -2769,10 +2790,38 @@ void gpencil_curve_delete_tagged_points(bGPdata *gpd,
       else {
         BLI_addtail(&gpf->strokes, new_stroke);
       }
+
+      gps_last = new_stroke;
     }
     prev_selected = selected;
   }
 
+  /* join first and last stroke if cyclic */
+  if (is_cyclic && gps_first != NULL && gps_last != NULL && gps_first != gps_last) {
+    bGPDcurve *gpc_first = gps_first->editcurve;
+    bGPDcurve *gpc_last = gps_last->editcurve;
+    int first_tot_points = gpc_first->tot_curve_points;
+    int old_tot_points = gpc_last->tot_curve_points;
+
+    gpc_last->tot_curve_points = first_tot_points + old_tot_points;
+    gpc_last->curve_points = MEM_recallocN(gpc_last->curve_points,
+                                           sizeof(bGPDcurve_point) * gpc_last->tot_curve_points);
+    /* copy data from first to last */
+    memcpy(gpc_last->curve_points + old_tot_points,
+           gpc_first->curve_points,
+           sizeof(bGPDcurve_point) * first_tot_points);
+
+    BKE_gpencil_editcurve_recalculate_handles(gps_last);
+    gps_last->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
+
+    /* Calc geometry data. */
+    BKE_gpencil_stroke_geometry_update(gpd, gps_last);
+
+    /* remove first one */
+    BLI_remlink(&gpf->strokes, gps_first);
+    BKE_gpencil_free_stroke(gps_first);
+  }
+
   /* Delete the old stroke */
   BLI_remlink(&gpf->strokes, gps);
   BKE_gpencil_free_stroke(gps);
@@ -2814,7 +2863,6 @@ static int gpencil_delete_selected_points(bContext *C)
             gps->flag &= ~GP_STROKE_SELECT;
 
             if (is_curve_edit) {
-              /* TODO: do curve point delete */
               bGPDcurve *gpc = gps->editcurve;
               gpencil_curve_delete_tagged_points(
                   gpd, gpf, gps, gps->next, gpc, GP_CURVE_POINT_SELECT, false, 0);



More information about the Bf-blender-cvs mailing list