[Bf-blender-cvs] [9ff1fd96e84] greasepencil-edit-curve: GPencil: Apply GSoC changes

Antonio Vazquez noreply at git.blender.org
Sat Jul 11 20:34:59 CEST 2020


Commit: 9ff1fd96e8469d5a34ae5efeaad0cf4888be2e24
Author: Antonio Vazquez
Date:   Sat Jul 11 20:34:19 2020 +0200
Branches: greasepencil-edit-curve
https://developer.blender.org/rB9ff1fd96e8469d5a34ae5efeaad0cf4888be2e24

GPencil: Apply GSoC changes

Also run a `make format`for fixing any clang issue

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

M	source/blender/blenkernel/BKE_gpencil.h
M	source/blender/blenkernel/BKE_gpencil_curve.h
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/blenkernel/intern/gpencil_curve.c
M	source/blender/editors/gpencil/gpencil_data.c
M	source/blender/editors/gpencil/gpencil_edit.c
M	source/blender/editors/gpencil/gpencil_edit_curve.c
M	source/blender/editors/gpencil/gpencil_select.c
M	source/blender/editors/gpencil/gpencil_utils.c
M	source/blender/makesrna/intern/rna_access_internal.h

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

diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index ffc16dbbaaf..9259729695d 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -104,7 +104,7 @@ void BKE_gpencil_batch_cache_dirty_tag(struct bGPdata *gpd);
 void BKE_gpencil_batch_cache_free(struct bGPdata *gpd);
 
 void BKE_gpencil_stroke_sync_selection(struct bGPDstroke *gps);
-void BKE_gpencil_curve_sync_selection(struct bGPDcurve *gpc);
+void BKE_gpencil_curve_sync_selection(struct bGPDstroke *gps);
 
 struct bGPDframe *BKE_gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe);
 struct bGPDframe *BKE_gpencil_frame_addcopy(struct bGPDlayer *gpl, int cframe);
diff --git a/source/blender/blenkernel/BKE_gpencil_curve.h b/source/blender/blenkernel/BKE_gpencil_curve.h
index f16e8ae7acb..3527d678355 100644
--- a/source/blender/blenkernel/BKE_gpencil_curve.h
+++ b/source/blender/blenkernel/BKE_gpencil_curve.h
@@ -51,6 +51,7 @@ void BKE_gpencil_stroke_editcurve_sync_selection(struct bGPDstroke *gps, struct
 void BKE_gpencil_selected_strokes_editcurve_update(struct bGPdata *gpd);
 void BKE_gpencil_stroke_update_geometry_from_editcurve(struct bGPDstroke *gps);
 void BKE_gpencil_editcurve_recalculate_handles(struct bGPDstroke *gps);
+void BKE_gpencil_editcurve_subdivide(struct bGPDstroke *gps, const int cuts);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index d9d7e8aa247..7932be4000f 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -934,13 +934,16 @@ void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps)
   }
 }
 
-void BKE_gpencil_curve_sync_selection(bGPDcurve *gpc)
+void BKE_gpencil_curve_sync_selection(bGPDstroke *gps)
 {
+  bGPDcurve *gpc = gps->editcurve;
   if (gpc == NULL) {
     return;
   }
 
+  gps->flag &= ~GP_STROKE_SELECT;
   gpc->flag &= ~GP_CURVE_SELECT;
+
   bool is_selected = false;
   for (int i = 0; i < gpc->tot_curve_points; i++) {
     bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
@@ -960,6 +963,7 @@ void BKE_gpencil_curve_sync_selection(bGPDcurve *gpc)
 
   if (is_selected) {
     gpc->flag |= GP_CURVE_SELECT;
+    gps->flag |= GP_STROKE_SELECT;
   }
 }
 
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index 4bd3c326a09..3bd60746028 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -852,4 +852,143 @@ void BKE_gpencil_editcurve_recalculate_handles(bGPDstroke *gps)
   }
 }
 
+/* Helper: count how many new curve points must be generated. */
+static int gpencil_editcurve_subdivide_count(bGPDcurve *gpc, bool is_cyclic)
+{
+  int count = 0;
+  for (int i = 0; i < gpc->tot_curve_points - 1; i++) {
+    bGPDcurve_point *cpt = &gpc->curve_points[i];
+    bGPDcurve_point *cpt_next = &gpc->curve_points[i + 1];
+
+    if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
+      count++;
+    }
+  }
+
+  if (is_cyclic) {
+    bGPDcurve_point *cpt = &gpc->curve_points[0];
+    bGPDcurve_point *cpt_next = &gpc->curve_points[gpc->tot_curve_points - 1];
+
+    if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
+      count++;
+    }
+  }
+
+  return count;
+}
+
+static void gpencil_editcurve_subdivide_curve_segment(bGPDcurve_point *cpt_start,
+                                                      bGPDcurve_point *cpt_end,
+                                                      bGPDcurve_point *cpt_new)
+{
+  BezTriple *bezt_start = &cpt_start->bezt;
+  BezTriple *bezt_end = &cpt_end->bezt;
+  BezTriple *bezt_new = &cpt_new->bezt;
+  for (int axis = 0; axis < 3; axis++) {
+    float p0, p1, p2, p3, m0, m1, q0, q1, b;
+    p0 = bezt_start->vec[1][axis];
+    p1 = bezt_start->vec[2][axis];
+    p2 = bezt_end->vec[0][axis];
+    p3 = bezt_end->vec[1][axis];
+
+    m0 = (p0 + p1) / 2;
+    q0 = (p0 + 2 * p1 + p2) / 4;
+    b = (p0 + 3 * p1 + 3 * p2 + p3) / 8;
+    q1 = (p1 + 2 * p2 + p3) / 4;
+    m1 = (p2 + p3) / 2;
+
+    bezt_new->vec[0][axis] = q0;
+    bezt_new->vec[2][axis] = q1;
+    bezt_new->vec[1][axis] = b;
+
+    bezt_start->vec[2][axis] = m0;
+    bezt_end->vec[0][axis] = m1;
+  }
+
+  cpt_new->pressure = interpf(cpt_end->pressure, cpt_start->pressure, 0.5f);
+  cpt_new->strength = interpf(cpt_end->strength, cpt_start->strength, 0.5f);
+  interp_v4_v4v4(cpt_new->vert_color, cpt_start->vert_color, cpt_end->vert_color, 0.5f);
+}
+
+void BKE_gpencil_editcurve_subdivide(bGPDstroke *gps, const int cuts)
+{
+  bGPDcurve *gpc = gps->editcurve;
+  if (gpc == NULL || gpc->tot_curve_points < 2) {
+    return;
+  }
+  bool is_cyclic = gps->flag & GP_STROKE_CYCLIC;
+
+  /* repeat for number of cuts */
+  for (int s = 0; s < cuts; s++) {
+    int old_tot_curve_points = gpc->tot_curve_points;
+    int new_num_curve_points = gpencil_editcurve_subdivide_count(gpc, is_cyclic);
+    if (new_num_curve_points == 0) {
+      break;
+    }
+    int new_tot_curve_points = old_tot_curve_points + new_num_curve_points;
+
+    bGPDcurve_point *temp_curve_points = (bGPDcurve_point *)MEM_callocN(
+        sizeof(bGPDcurve_point) * new_tot_curve_points, __func__);
+
+    bool prev_subdivided = false;
+    int j = 0;
+    for (int i = 0; i < old_tot_curve_points - 1; i++, j++) {
+      bGPDcurve_point *cpt = &gpc->curve_points[i];
+      bGPDcurve_point *cpt_next = &gpc->curve_points[i + 1];
+
+      if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
+        bGPDcurve_point *cpt_new = &temp_curve_points[j + 1];
+        gpencil_editcurve_subdivide_curve_segment(cpt, cpt_next, cpt_new);
+
+        memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+        memcpy(&temp_curve_points[j + 2], cpt_next, sizeof(bGPDcurve_point));
+
+        cpt_new->flag |= GP_CURVE_POINT_SELECT;
+        cpt_new->bezt.h1 = HD_ALIGN;
+        cpt_new->bezt.h2 = HD_ALIGN;
+        BEZT_SEL_ALL(&cpt_new->bezt);
+
+        prev_subdivided = true;
+        j++;
+      }
+      else if (!prev_subdivided) {
+        memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+        prev_subdivided = false;
+      }
+      else {
+        prev_subdivided = false;
+      }
+    }
+
+    if (is_cyclic) {
+      bGPDcurve_point *cpt = &gpc->curve_points[old_tot_curve_points - 1];
+      bGPDcurve_point *cpt_next = &gpc->curve_points[0];
+
+      if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
+        bGPDcurve_point *cpt_new = &temp_curve_points[j + 1];
+        gpencil_editcurve_subdivide_curve_segment(cpt, cpt_next, cpt_new);
+
+        memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+        memcpy(&temp_curve_points[0], cpt_next, sizeof(bGPDcurve_point));
+
+        cpt_new->flag |= GP_CURVE_POINT_SELECT;
+        cpt_new->bezt.h1 = HD_ALIGN;
+        cpt_new->bezt.h2 = HD_ALIGN;
+        BEZT_SEL_ALL(&cpt_new->bezt);
+      }
+      else if (!prev_subdivided) {
+        memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+      }
+    }
+    else {
+      bGPDcurve_point *cpt = &gpc->curve_points[old_tot_curve_points - 1];
+      memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+    }
+
+    MEM_freeN(gpc->curve_points);
+    gpc->curve_points = temp_curve_points;
+    gpc->tot_curve_points = new_tot_curve_points;
+  }
+}
+
 /** \} */
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 40f71031dde..d3fc3aced97 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -1383,6 +1383,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
   const int direction = RNA_enum_get(op->ptr, "direction");
   const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
 
+  bool changed = false;
   CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
     /* temp listbase to store selected strokes */
     ListBase selected = {NULL};
@@ -1441,7 +1442,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
               break;
             /* Bring Forward */
             case GP_STROKE_MOVE_UP:
-              for (LinkData *link = selected.last; link; link = link->prev) {
+              LISTBASE_FOREACH_BACKWARD (LinkData *, link, &selected) {
                 gps = link->data;
                 BLI_listbase_link_move(&gpf->strokes, gps, 1);
               }
@@ -1455,7 +1456,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
               break;
             /* Send to Back */
             case GP_STROKE_MOVE_BOTTOM:
-              for (LinkData *link = selected.last; link; link = link->prev) {
+              LISTBASE_FOREACH_BACKWARD (LinkData *, link, &selected) {
                 gps = link->data;
                 BLI_remlink(&gpf->strokes, gps);
                 BLI_addhead(&gpf->strokes, gps);
@@ -1464,6 +1465,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
             default:
               BLI_assert(0);
               break;
+              changed = true;
           }
         }
         BLI_freelistN(&selected);
@@ -1477,9 +1479,11 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
   }
   CTX_DATA_END;
 
-  /* notifiers */
-  DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
-  WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+  if (changed) {
+    /* notifiers */
+    DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+    WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+  }
 
   return OPERATOR_FINISHED;
 }
@@ -1545,6 +1549,7 @@ static int gpencil_stroke_change_color_exec(bContext *C, wmOperator *op)
     return OPERATOR_CANCELLED;
   }
 
+  bool changed = false;
   /* loop all strokes */
   CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
     bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
@@ -1569,6 +1574,8 @@ static int gpencil_stroke_change_color

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list