[Bf-blender-cvs] [c944003d294] temp-gpencil-bezier-stroke-type: GPencil: Add dissolve for curves with refit option

Falk David noreply at git.blender.org
Tue Mar 16 10:36:05 CET 2021


Commit: c944003d29405aa6a0cfd26a185f164d35cf8596
Author: Falk David
Date:   Tue Mar 16 10:35:22 2021 +0100
Branches: temp-gpencil-bezier-stroke-type
https://developer.blender.org/rBc944003d29405aa6a0cfd26a185f164d35cf8596

GPencil: Add dissolve for curves with refit option

This implements the dissolve operator for bezier strokes.
The operator now has an option to refit the segments after the points
were removed. Note that this makes use of
`BKE_gpencil_stroke_editcurve_regenerate_single`.

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

M	source/blender/editors/gpencil/gpencil_edit.c

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

diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 0c52f12dcb2..b0e29cad35c 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -2318,243 +2318,319 @@ static int gpencil_delete_selected_strokes(bContext *C)
 
 /* ----------------------------------- */
 
-static bool gpencil_dissolve_selected_curve_points(bContext *C,
-                                                   bGPdata *gpd,
-                                                   eGP_DissolveMode mode)
+static void gpencil_refit_single_from_to(bGPDstroke *gps,
+                                         bGPDcurve *gpc,
+                                         bGPDcurve_point *new_points,
+                                         int from_start,
+                                         int from_end,
+                                         int to_start,
+                                         int to_end,
+                                         float error_threshold)
 {
-  bool changed = false;
-  GP_EDITABLE_CURVES_BEGIN(gps_iter, C, gpl, gps, gpc)
-  {
-    if (gpc->flag & GP_CURVE_SELECT) {
-      int first = 0, last = 0;
-      int num_points_remaining = gpc->tot_curve_points;
+  bGPDcurve_point *cpt_start = &gpc->curve_points[from_start];
+  bGPDcurve_point *cpt_end = &gpc->curve_points[from_end];
+  bGPDcurve_point *new_cpt_start = &new_points[to_start];
+  bGPDcurve_point *new_cpt_end = &new_points[to_end];
 
-      switch (mode) {
-        case GP_DISSOLVE_POINTS:
-          for (int i = 0; i < gpc->tot_curve_points; i++) {
-            bGPDcurve_point *cpt = &gpc->curve_points[i];
-            if (cpt->flag & GP_CURVE_POINT_SELECT) {
-              num_points_remaining--;
-            }
+  BKE_gpencil_stroke_editcurve_regenerate_single(gps, from_start, from_end, error_threshold);
+
+  memcpy(new_cpt_start, cpt_start, sizeof(bGPDcurve_point));
+  memcpy(new_cpt_end, cpt_end, sizeof(bGPDcurve_point));
+}
+
+static bool gpencil_dissolve_selected_curve_points(bGPdata *gpd,
+                                                   bGPDframe *gpf,
+                                                   bGPDstroke *gps,
+                                                   bGPDcurve *gpc,
+                                                   eGP_DissolveMode mode,
+                                                   const bool do_segments_refit,
+                                                   const float error_threshold)
+{
+  if ((gpc->flag & GP_CURVE_SELECT) == 0) {
+    return false;
+  }
+  int first = -1, last = 0;
+  int num_points_remaining = gpc->tot_curve_points;
+  const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC);
+
+  switch (mode) {
+    case GP_DISSOLVE_POINTS:
+      for (int i = 0; i < gpc->tot_curve_points; i++) {
+        bGPDcurve_point *cpt = &gpc->curve_points[i];
+        if (cpt->flag & GP_CURVE_POINT_SELECT) {
+          num_points_remaining--;
+        }
+        else {
+          if (first < 0) {
+            first = i;
           }
-          break;
-        case GP_DISSOLVE_BETWEEN:
-          first = -1;
-          for (int i = 0; i < gpc->tot_curve_points; i++) {
-            bGPDcurve_point *cpt = &gpc->curve_points[i];
-            if (cpt->flag & GP_CURVE_POINT_SELECT) {
-              if (first < 0) {
-                first = i;
-              }
-              last = i;
-            }
+          last = i;
+        }
+      }
+      break;
+    case GP_DISSOLVE_BETWEEN:
+      for (int i = 0; i < gpc->tot_curve_points; i++) {
+        bGPDcurve_point *cpt = &gpc->curve_points[i];
+        if (cpt->flag & GP_CURVE_POINT_SELECT) {
+          if (first < 0) {
+            first = i;
           }
+          last = i;
+        }
+      }
 
-          for (int i = first + 1; i < last; i++) {
-            bGPDcurve_point *cpt = &gpc->curve_points[i];
-            if ((cpt->flag & GP_CURVE_POINT_SELECT) == 0) {
-              num_points_remaining--;
-            }
+      for (int i = first + 1; i < last; i++) {
+        bGPDcurve_point *cpt = &gpc->curve_points[i];
+        if ((cpt->flag & GP_CURVE_POINT_SELECT) == 0) {
+          num_points_remaining--;
+        }
+      }
+      break;
+    case GP_DISSOLVE_UNSELECT:
+      for (int i = 0; i < gpc->tot_curve_points; i++) {
+        bGPDcurve_point *cpt = &gpc->curve_points[i];
+        if ((cpt->flag & GP_CURVE_POINT_SELECT) == 0) {
+          num_points_remaining--;
+        }
+        else {
+          if (first < 0) {
+            first = i;
           }
-          break;
-        case GP_DISSOLVE_UNSELECT:
-          for (int i = 0; i < gpc->tot_curve_points; i++) {
-            bGPDcurve_point *cpt = &gpc->curve_points[i];
-            if ((cpt->flag & GP_CURVE_POINT_SELECT) == 0) {
-              num_points_remaining--;
-            }
+          last = i;
+        }
+      }
+      break;
+    default:
+      return false;
+      break;
+  }
+
+  if (num_points_remaining < 1) {
+    /* Delete stroke */
+    BLI_remlink(&gpf->strokes, gps);
+    BKE_gpencil_free_stroke(gps);
+    return true;
+  }
+  else if (num_points_remaining == gpc->tot_curve_points) {
+    /* Nothing to do so return. */
+    return true;
+  }
+
+  bGPDcurve_point *new_points = MEM_callocN(sizeof(bGPDcurve_point) * num_points_remaining,
+                                            __func__);
+
+  /* Should have at least one selected and one deselected point here. */
+  BLI_assert(first >= 0);
+
+  int new_idx = 0, start = 0, end = 0;
+  switch (mode) {
+    case GP_DISSOLVE_POINTS:
+      start = end = first;
+      for (int i = first; i < gpc->tot_curve_points; i++) {
+        bGPDcurve_point *cpt = &gpc->curve_points[i];
+        bGPDcurve_point *new_cpt = &new_points[new_idx];
+        if ((cpt->flag & GP_CURVE_POINT_SELECT) == 0) {
+          *new_cpt = *cpt;
+
+          /* Check that the indices are in bounds. */
+          if (do_segments_refit && (end > start) && (start > 0) && (end < gpc->tot_curve_points)) {
+            /* Refit this segment. */
+            gpencil_refit_single_from_to(
+                gps, gpc, new_points, start - 1, end, new_idx - 1, new_idx, error_threshold);
+
+            start = end = i;
           }
-          break;
-        default:
-          return false;
-          break;
+
+          new_idx++;
+          start++;
+        }
+
+        end++;
       }
+      break;
+    case GP_DISSOLVE_BETWEEN:
+      for (int i = 0; i < first; i++) {
+        bGPDcurve_point *cpt = &gpc->curve_points[i];
+        bGPDcurve_point *new_cpt = &new_points[new_idx];
 
-      if (num_points_remaining < 1) {
-        /* Delete stroke */
-        BLI_remlink(&gpf_->strokes, gps);
-        BKE_gpencil_free_stroke(gps);
+        *new_cpt = *cpt;
+        new_idx++;
       }
-      else {
-        bGPDcurve_point *new_points = MEM_callocN(sizeof(bGPDcurve_point) * num_points_remaining,
-                                                  __func__);
 
-        int idx = 0;
-        switch (mode) {
-          case GP_DISSOLVE_POINTS:
-            for (int i = 0; i < gpc->tot_curve_points; i++) {
-              bGPDcurve_point *cpt = &gpc->curve_points[i];
-              bGPDcurve_point *new_cpt = &new_points[idx];
-              if ((cpt->flag & GP_CURVE_POINT_SELECT) == 0) {
-                *new_cpt = *cpt;
-                idx++;
-              }
-            }
-            break;
-          case GP_DISSOLVE_BETWEEN:
-            for (int i = 0; i < first; i++) {
-              bGPDcurve_point *cpt = &gpc->curve_points[i];
-              bGPDcurve_point *new_cpt = &new_points[idx];
+      start = end = first;
 
-              *new_cpt = *cpt;
-              idx++;
-            }
+      for (int i = first; i < last; i++) {
+        bGPDcurve_point *cpt = &gpc->curve_points[i];
+        bGPDcurve_point *new_cpt = &new_points[new_idx];
+        if (cpt->flag & GP_CURVE_POINT_SELECT) {
+          *new_cpt = *cpt;
 
-            for (int i = first; i < last; i++) {
-              bGPDcurve_point *cpt = &gpc->curve_points[i];
-              bGPDcurve_point *new_cpt = &new_points[idx];
-              if (cpt->flag & GP_CURVE_POINT_SELECT) {
-                *new_cpt = *cpt;
-                idx++;
-              }
-            }
+          if (do_segments_refit && (end > start) && (start > first)) {
+            /* Refit this segment. */
+            gpencil_refit_single_from_to(
+                gps, gpc, new_points, start - 1, end, new_idx - 1, new_idx, error_threshold);
 
-            for (int i = last; i < gpc->tot_curve_points; i++) {
-              bGPDcurve_point *cpt = &gpc->curve_points[i];
-              bGPDcurve_point *new_cpt = &new_points[idx];
+            start = end = i;
+          }
 
-              *new_cpt = *cpt;
-              idx++;
-            }
-            break;
-          case GP_DISSOLVE_UNSELECT:
-            for (int i = 0; i < gpc->tot_curve_points; i++) {
-              bGPDcurve_point *cpt = &gpc->curve_points[i];
-              bGPDcurve_point *new_cpt = &new_points[idx];
-              if (cpt->flag & GP_CURVE_POINT_SELECT) {
-                *new_cpt = *cpt;
-                idx++;
-              }
-            }
-            break;
-          default:
-            return false;
-            break;
+          new_idx++;
+          start++;
         }
 
-        if (gpc->curve_points != NULL) {
-          MEM_freeN(gpc->curve_points);
-        }
+        end++;
+      }
 
-        gpc->curve_points = new_points;
-        gpc->tot_curve_points = num_points_remaining;
+      if (do_segments_refit && (end > start) && (start > first) && (end < gpc->tot_curve_points)) {
+        /* Refit this segment. */
+        gpencil_refit_single_from_to(
+            gps, gpc, new_points, start - 1, end, new_idx - 1, new_idx, error_threshold);
+      }
 
-        BKE_gpencil_editcurve_recalculate_handles(gps);
-        gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
-        BKE_gpencil_stroke_geometry_update(gpd, gps);
+      for (int i = last; i < gpc->tot_curve_points; i++) {
+        bGPDcurve_point *cpt = &gpc->curve_points[i];
+        bGPDcurve_point *new_cpt = &new_points[new_idx];
+
+ 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list