[Bf-blender-cvs] [5a82aa69f7a] temp-gpencil-bezier-stroke-type: GPencil: Duplicate curves

Falk David noreply at git.blender.org
Sat Mar 13 14:19:58 CET 2021


Commit: 5a82aa69f7a49c5ff9c85caa7c4ed132bc5f707c
Author: Falk David
Date:   Sat Mar 13 12:32:12 2021 +0100
Branches: temp-gpencil-bezier-stroke-type
https://developer.blender.org/rB5a82aa69f7a49c5ff9c85caa7c4ed132bc5f707c

GPencil: Duplicate curves

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

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 d5654f69b5e..97883da9935 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -846,24 +846,85 @@ static void gpencil_duplicate_points(bGPdata *gpd,
                                      ListBase *new_strokes,
                                      const char *layername)
 {
-  bGPDspoint *pt;
-  int i;
-
   int start_idx = -1;
 
-  /* Step through the original stroke's points:
-   * - We accumulate selected points (from start_idx to current index)
-   *   and then convert that to a new stroke
-   */
-  for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
-    /* searching for start, are waiting for end? */
-    if (start_idx == -1) {
-      /* is this the first selected point for a new island? */
-      if (pt->flag & GP_SPOINT_SELECT) {
-        start_idx = i;
+  if (GPENCIL_STROKE_TYPE_BEZIER(gps)) {
+    bGPDcurve *gpc = gps->editcurve;
+    for (int i = 0; i < gpc->tot_curve_points; i++) {
+      bGPDcurve_point *cpt = &gpc->curve_points[i];
+      if (start_idx == -1) {
+        if (cpt->flag & GP_CURVE_POINT_SELECT) {
+          start_idx = i;
+        }
+        continue;
+      }
+
+      size_t len = 0;
+
+      if ((cpt->flag & GP_CURVE_POINT_SELECT) == 0) {
+        len = i - start_idx;
       }
+      else if (i == gpc->tot_curve_points - 1) {
+        len = i - start_idx + 1;
+      }
+
+      if (len < 1) {
+        continue;
+      }
+
+      /* make a stupid copy first of the entire stroke (to get the flags too) */
+      bGPDstroke *gpsd = BKE_gpencil_stroke_duplicate((bGPDstroke *)gps, false, false);
+
+      /* saves original layer name */
+      BLI_strncpy(gpsd->runtime.tmp_layerinfo, layername, sizeof(gpsd->runtime.tmp_layerinfo));
+
+      /* To avoid a curve update, we just copy the points. */
+      int start_idx_stroke = gpc->curve_points[start_idx].point_index;
+      int len_stroke = (gpc->curve_points[start_idx + len - 1].point_index - start_idx_stroke) + 1;
+
+      gpsd->points = MEM_mallocN(sizeof(bGPDspoint) * len_stroke, "gps stroke points copy");
+      memcpy(gpsd->points, gps->points + start_idx_stroke, sizeof(bGPDspoint) * len_stroke);
+      gpsd->totpoints = len_stroke;
+
+      gpsd->editcurve = BKE_gpencil_stroke_editcurve_new(len);
+      bGPDcurve *gpcd = gpsd->editcurve;
+      memcpy(gpcd->curve_points, gpc->curve_points + start_idx, sizeof(bGPDcurve_point) * len);
+
+      /* TODO: Copy vertex weights*/
+      for (uint32_t j = 0; j < gpcd->tot_curve_points; j++) {
+        bGPDcurve_point *gpcd_pt = &gpcd->curve_points[j];
+        BezTriple *bezt = &gpcd_pt->bezt;
+        gpcd_pt->flag |= GP_CURVE_POINT_SELECT;
+        BEZT_SEL_ALL(bezt);
+      }
+      gpcd->flag |= GP_CURVE_SELECT;
+
+      BKE_gpencil_stroke_geometry_update(gpd, gpsd);
+
+      /* add to temp buffer */
+      gpsd->next = gpsd->prev = NULL;
+
+      BLI_addtail(new_strokes, gpsd);
+
+      start_idx = -1;
     }
-    else {
+  }
+  else {
+    /* Step through the original stroke's points:
+     * - We accumulate selected points (from start_idx to current index)
+     *   and then convert that to a new stroke
+     */
+    for (int i = 0; i < gps->totpoints; i++) {
+      bGPDspoint *pt = &gps->points[i];
+      /* searching for start, are waiting for end? */
+      if (start_idx == -1) {
+        /* is this the first selected point for a new island? */
+        if (pt->flag & GP_SPOINT_SELECT) {
+          start_idx = i;
+        }
+        continue;
+      }
+
       size_t len = 0;
 
       /* is this the end of current island yet?
@@ -877,45 +938,47 @@ static void gpencil_duplicate_points(bGPdata *gpd,
         len = i - start_idx + 1;
       }
 
+      if (len < 1) {
+        continue;
+      }
+
       /* make copies of the relevant data */
-      if (len) {
-        bGPDstroke *gpsd;
+      bGPDstroke *gpsd;
 
-        /* make a stupid copy first of the entire stroke (to get the flags too) */
-        gpsd = BKE_gpencil_stroke_duplicate((bGPDstroke *)gps, false, true);
+      /* make a stupid copy first of the entire stroke (to get the flags too) */
+      gpsd = BKE_gpencil_stroke_duplicate((bGPDstroke *)gps, false, false);
 
-        /* saves original layer name */
-        BLI_strncpy(gpsd->runtime.tmp_layerinfo, layername, sizeof(gpsd->runtime.tmp_layerinfo));
+      /* saves original layer name */
+      BLI_strncpy(gpsd->runtime.tmp_layerinfo, layername, sizeof(gpsd->runtime.tmp_layerinfo));
 
-        /* now, make a new points array, and copy of the relevant parts */
-        gpsd->points = MEM_mallocN(sizeof(bGPDspoint) * len, "gps stroke points copy");
-        memcpy(gpsd->points, gps->points + start_idx, sizeof(bGPDspoint) * len);
-        gpsd->totpoints = len;
+      /* now, make a new points array, and copy of the relevant parts */
+      gpsd->points = MEM_mallocN(sizeof(bGPDspoint) * len, "gps stroke points copy");
+      memcpy(gpsd->points, gps->points + start_idx, sizeof(bGPDspoint) * len);
+      gpsd->totpoints = len;
 
-        if (gps->dvert != NULL) {
-          gpsd->dvert = MEM_mallocN(sizeof(MDeformVert) * len, "gps stroke weights copy");
-          memcpy(gpsd->dvert, gps->dvert + start_idx, sizeof(MDeformVert) * len);
-
-          /* Copy weights */
-          int e = start_idx;
-          for (int j = 0; j < gpsd->totpoints; j++) {
-            MDeformVert *dvert_dst = &gps->dvert[e];
-            MDeformVert *dvert_src = &gps->dvert[j];
-            dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
-            e++;
-          }
+      if (gps->dvert != NULL) {
+        gpsd->dvert = MEM_mallocN(sizeof(MDeformVert) * len, "gps stroke weights copy");
+        memcpy(gpsd->dvert, gps->dvert + start_idx, sizeof(MDeformVert) * len);
+
+        /* Copy weights */
+        int e = start_idx;
+        for (int j = 0; j < gpsd->totpoints; j++) {
+          MDeformVert *dvert_dst = &gps->dvert[e];
+          MDeformVert *dvert_src = &gps->dvert[j];
+          dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
+          e++;
         }
+      }
 
-        BKE_gpencil_stroke_geometry_update(gpd, gpsd);
+      BKE_gpencil_stroke_geometry_update(gpd, gpsd);
 
-        /* add to temp buffer */
-        gpsd->next = gpsd->prev = NULL;
+      /* add to temp buffer */
+      gpsd->next = gpsd->prev = NULL;
 
-        BLI_addtail(new_strokes, gpsd);
+      BLI_addtail(new_strokes, gpsd);
 
-        /* cleanup + reset for next */
-        start_idx = -1;
-      }
+      /* cleanup + reset for next */
+      start_idx = -1;
     }
   }
 }
@@ -923,7 +986,6 @@ static void gpencil_duplicate_points(bGPdata *gpd,
 static int gpencil_duplicate_exec(bContext *C, wmOperator *op)
 {
   bGPdata *gpd = ED_gpencil_data_get_active(C);
-  const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
 
   if (gpd == NULL) {
     BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
@@ -936,74 +998,108 @@ static int gpencil_duplicate_exec(bContext *C, wmOperator *op)
   }
 
   bool changed = false;
-  if (is_curve_edit) {
-    BKE_report(op->reports, RPT_ERROR, "Not implemented!");
-  }
-  else {
-    /* for each visible (and editable) layer's selected strokes,
-     * copy the strokes into a temporary buffer, then append
-     * once all done
-     */
-    CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
-      ListBase new_strokes = {NULL, NULL};
-      bGPDframe *gpf = gpl->actframe;
-      bGPDstroke *gps;
+  /* for each visible (and editable) layer's selected strokes,
+   * copy the strokes into a temporary buffer, then append
+   * once all done
+   */
+  CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+    ListBase new_strokes = {NULL, NULL};
+    bGPDframe *gpf = gpl->actframe;
 
-      if (gpf == NULL) {
+    if (gpf == NULL) {
+      continue;
+    }
+
+    /* make copies of selected strokes, and deselect these once we're done */
+    LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+      /* skip strokes that are invalid for current view */
+      if (ED_gpencil_stroke_can_use(C, gps) == false) {
         continue;
       }
 
-      /* make copies of selected strokes, and deselect these once we're done */
-      for (gps = gpf->strokes.first; gps; gps = gps->next) {
-        /* skip strokes that are invalid for current view */
-        if (ED_gpencil_stroke_can_use(C, gps) == false) {
+      if (GPENCIL_STROKE_TYPE_BEZIER(gps)) {
+        bGPDcurve *gpc = gps->editcurve;
+        if ((gpc->flag & GP_CURVE_SELECT) == 0) {
           continue;
         }
 
-        if (gps->flag & GP_STROKE_SELECT) {
-          if (gps->totpoints == 1) {
-            /* Special Case: If there's just a single point in this stroke... */
-            bGPDstroke *gpsd;
+        if (gpc->tot_curve_points == 1) {
+          /* Special Case: If there's just a single point in this stroke... */
+          bGPDstroke *gpsd;
 
-            /* make direct copies of the stroke and its points */
-            gpsd = BKE_gpencil_stroke_duplicate(gps, true, true);
+          /* make direct copies of the stroke and its points */
+          gpsd = BKE_gpencil_stroke_duplicate(gps, true, true);
 
-            BLI_strncpy(
-                gpsd->runtime.tmp_layerinfo, gpl->info, sizeof(gpsd->runtime.tmp_layerinfo));
+          BLI_strncpy(gpsd->runtime.tmp_layerinfo, gpl->info, sizeof(gpsd->runtime.tmp_layerinfo));
 
-            /* Initialize triangle information. */
-            BKE_gpencil_stroke_geometry_update(gpd, gpsd);
+          /* Initialize triangle information. */
+          BKE_gpencil_stroke_geometry_update(gpd, gpsd);
 
-            /* add to temp buffer */
-            gpsd->next = gpsd->prev = NULL;
-            BLI_addtail(&new_strokes, gpsd);
-          }
-          else {
-            /* delegate to a helper, as there's too much to fit in here (for copying subsets)... */
-            gpencil_duplicate_points(gpd, gps, &new_strokes, gpl->info);
-          }
-
-          /* deselect original stroke, or else the originals get moved too
-           * (when using the copy + move macro)
-           */
-          bGPD

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list