[Bf-blender-cvs] [44a1990286b] temp-gpencil-bezier-stroke-type: GPencil: join bezier strokes operator

Falk David noreply at git.blender.org
Mon Mar 15 00:36:26 CET 2021


Commit: 44a1990286bb29083fe8a86e4a196efa0fe54cb5
Author: Falk David
Date:   Sun Mar 14 22:19:52 2021 +0100
Branches: temp-gpencil-bezier-stroke-type
https://developer.blender.org/rB44a1990286bb29083fe8a86e4a196efa0fe54cb5

GPencil: join bezier strokes operator

This also implements the flip BKE for curves.

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

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

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

diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index d84f47e7d7f..307fd23d1d0 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -2679,49 +2679,108 @@ void BKE_gpencil_stroke_set_random_color(bGPDstroke *gps)
   }
 }
 
+static void gpencil_flip_beztriple(BezTriple *bezt)
+{
+  /* Flip handle position. */
+  float tmp[3];
+  copy_v3_v3(tmp, bezt->vec[0]);
+  copy_v3_v3(bezt->vec[0], bezt->vec[2]);
+  copy_v3_v3(bezt->vec[2], tmp);
+
+  /* Flip type and slection flag. */
+  SWAP(uint8_t, bezt->h1, bezt->h2);
+  SWAP(uint8_t, bezt->f1, bezt->f3);
+}
+
 /* Flip stroke. */
 void BKE_gpencil_stroke_flip(bGPDstroke *gps)
 {
-  int end = gps->totpoints - 1;
-
-  for (int i = 0; i < gps->totpoints / 2; i++) {
-    bGPDspoint *point, *point2;
-    bGPDspoint pt;
-
-    /* save first point */
-    point = &gps->points[i];
-    pt.x = point->x;
-    pt.y = point->y;
-    pt.z = point->z;
-    pt.flag = point->flag;
-    pt.pressure = point->pressure;
-    pt.strength = point->strength;
-    pt.time = point->time;
-    copy_v4_v4(pt.vert_color, point->vert_color);
-
-    /* replace first point with last point */
-    point2 = &gps->points[end];
-    point->x = point2->x;
-    point->y = point2->y;
-    point->z = point2->z;
-    point->flag = point2->flag;
-    point->pressure = point2->pressure;
-    point->strength = point2->strength;
-    point->time = point2->time;
-    copy_v4_v4(point->vert_color, point2->vert_color);
-
-    /* replace last point with first saved before */
-    point = &gps->points[end];
-    point->x = pt.x;
-    point->y = pt.y;
-    point->z = pt.z;
-    point->flag = pt.flag;
-    point->pressure = pt.pressure;
-    point->strength = pt.strength;
-    point->time = pt.time;
-    copy_v4_v4(point->vert_color, pt.vert_color);
-
-    end--;
+  if (GPENCIL_STROKE_TYPE_BEZIER(gps)) {
+    bGPDcurve *gpc = gps->editcurve;
+
+    int end = gpc->tot_curve_points - 1;
+    for (int i = 0; i < gpc->tot_curve_points / 2; i++) {
+      bGPDcurve_point *cpt_first = &gpc->curve_points[i];
+      bGPDcurve_point *cpt_last = &gpc->curve_points[end];
+      bGPDcurve_point temp;
+
+      memcpy(&temp.bezt, &cpt_first->bezt, sizeof(BezTriple));
+      temp.pressure = cpt_first->pressure;
+      temp.strength = cpt_first->strength;
+      temp.point_index = cpt_first->point_index;
+      temp.flag = cpt_first->flag;
+      temp.uv_fac = cpt_first->uv_fac;
+      temp.uv_rot = cpt_first->uv_rot;
+      copy_v2_v2(temp.uv_fill, cpt_first->uv_fill);
+      copy_v4_v4(temp.vert_color, cpt_first->vert_color);
+
+      memcpy(&cpt_first->bezt, &cpt_last->bezt, sizeof(BezTriple));
+      gpencil_flip_beztriple(&cpt_first->bezt);
+      cpt_first->pressure = cpt_last->pressure;
+      cpt_first->strength = cpt_last->strength;
+      cpt_first->point_index = cpt_last->point_index;
+      cpt_first->flag = cpt_last->flag;
+      cpt_first->uv_fac = cpt_last->uv_fac;
+      cpt_first->uv_rot = cpt_last->uv_rot;
+      copy_v2_v2(cpt_first->uv_fill, cpt_last->uv_fill);
+      copy_v4_v4(cpt_first->vert_color, cpt_last->vert_color);
+
+      memcpy(&cpt_last->bezt, &temp.bezt, sizeof(BezTriple));
+      gpencil_flip_beztriple(&cpt_last->bezt);
+      cpt_last->pressure = temp.pressure;
+      cpt_last->strength = temp.strength;
+      cpt_last->point_index = temp.point_index;
+      cpt_last->flag = temp.flag;
+      cpt_last->uv_fac = temp.uv_fac;
+      cpt_last->uv_rot = temp.uv_rot;
+      copy_v2_v2(cpt_last->uv_fill, temp.uv_fill);
+      copy_v4_v4(cpt_last->vert_color, temp.vert_color);
+
+      end--;
+    }
+  }
+  else {
+    int end = gps->totpoints - 1;
+
+    for (int i = 0; i < gps->totpoints / 2; i++) {
+      bGPDspoint *point, *point2;
+      bGPDspoint pt;
+
+      /* save first point */
+      point = &gps->points[i];
+      pt.x = point->x;
+      pt.y = point->y;
+      pt.z = point->z;
+      pt.flag = point->flag;
+      pt.pressure = point->pressure;
+      pt.strength = point->strength;
+      pt.time = point->time;
+      copy_v4_v4(pt.vert_color, point->vert_color);
+
+      /* replace first point with last point */
+      point2 = &gps->points[end];
+      point->x = point2->x;
+      point->y = point2->y;
+      point->z = point2->z;
+      point->flag = point2->flag;
+      point->pressure = point2->pressure;
+      point->strength = point2->strength;
+      point->time = point2->time;
+      copy_v4_v4(point->vert_color, point2->vert_color);
+
+      /* replace last point with first saved before */
+      point = &gps->points[end];
+      point->x = pt.x;
+      point->y = pt.y;
+      point->z = pt.z;
+      point->flag = pt.flag;
+      point->pressure = pt.pressure;
+      point->strength = pt.strength;
+      point->time = pt.time;
+      copy_v4_v4(point->vert_color, pt.vert_color);
+
+      end--;
+    }
   }
 }
 
@@ -3149,7 +3208,6 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
 {
   bGPDspoint point;
   bGPDspoint *pt;
-  int i;
   const float delta[3] = {1.0f, 1.0f, 1.0f};
   float deltatime = 0.0f;
 
@@ -3158,6 +3216,11 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
     return;
   }
 
+  /* Cannot join strokes of different types for now... */
+  if (GPENCIL_STROKE_TYPE_BEZIER(gps_a) != GPENCIL_STROKE_TYPE_BEZIER(gps_b)) {
+    return;
+  }
+
   if ((gps_a->totpoints == 0) || (gps_b->totpoints == 0)) {
     return;
   }
@@ -3210,28 +3273,54 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
     BKE_gpencil_stroke_flip(gps_b);
   }
 
-  /* don't visibly link the first and last points? */
-  if (leave_gaps) {
-    /* 1st: add one tail point to start invisible area */
-    point = gps_a->points[gps_a->totpoints - 1];
-    deltatime = point.time;
+  const float thickness_ratio = (fit_thickness && gps_a->thickness > 0.0f) ?
+                                    (float)gps_b->thickness / (float)gps_a->thickness :
+                                    1.0f;
 
-    gpencil_stroke_copy_point(gps_a, NULL, &point, delta, 0.0f, 0.0f, 0.0f);
+  if (GPENCIL_STROKE_TYPE_BEZIER(gps_a)) {
+    /* TODO: Support leave gaps. */
+    bGPDcurve *gpc_a = gps_a->editcurve;
+    bGPDcurve *gpc_b = gps_b->editcurve;
 
-    /* 2nd: add one head point to finish invisible area */
-    point = gps_b->points[0];
-    gpencil_stroke_copy_point(gps_a, NULL, &point, delta, 0.0f, 0.0f, deltatime);
+    int old_num_points = gpc_a->tot_curve_points;
+    gpc_a->tot_curve_points += gpc_b->tot_curve_points;
+    gpc_a->curve_points = MEM_recallocN(gpc_a->curve_points,
+                                        sizeof(bGPDcurve_point) * gpc_a->tot_curve_points);
+
+    memcpy(gpc_a->curve_points + old_num_points,
+           gpc_b->curve_points,
+           sizeof(bGPDcurve_point) * gpc_b->tot_curve_points);
+    /* TODO: copy dvert curve data. */
+
+    /* Rescale other points. */
+    for (int i = old_num_points; i < gpc_a->tot_curve_points; i++) {
+      bGPDcurve_point *cpt = &gpc_a->curve_points[i];
+      cpt->pressure *= thickness_ratio;
+    }
+
+    gps_a->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
   }
+  else {
+    /* don't visibly link the first and last points? */
+    if (leave_gaps) {
+      /* 1st: add one tail point to start invisible area */
+      point = gps_a->points[gps_a->totpoints - 1];
+      deltatime = point.time;
 
-  const float ratio = (fit_thickness && gps_a->thickness > 0.0f) ?
-                          (float)gps_b->thickness / (float)gps_a->thickness :
-                          1.0f;
+      gpencil_stroke_copy_point(gps_a, NULL, &point, delta, 0.0f, 0.0f, 0.0f);
 
-  /* 3rd: add all points */
-  for (i = 0, pt = gps_b->points; i < gps_b->totpoints && pt; i++, pt++) {
-    MDeformVert *dvert = (gps_b->dvert) ? &gps_b->dvert[i] : NULL;
-    gpencil_stroke_copy_point(
-        gps_a, dvert, pt, delta, pt->pressure * ratio, pt->strength, deltatime);
+      /* 2nd: add one head point to finish invisible area */
+      point = gps_b->points[0];
+      gpencil_stroke_copy_point(gps_a, NULL, &point, delta, 0.0f, 0.0f, deltatime);
+    }
+
+    /* 3rd: add all points */
+    for (int i = 0; i < gps_b->totpoints && pt; i++) {
+      pt = &gps_b->points[i];
+      MDeformVert *dvert = (gps_b->dvert) ? &gps_b->dvert[i] : NULL;
+      gpencil_stroke_copy_point(
+          gps_a, dvert, pt, delta, pt->pressure * thickness_ratio, pt->strength, deltatime);
+    }
   }
 }
 
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 223522591df..79ff5d4c26b 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3742,11 +3742,6 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
     return OPERATOR_CANCELLED;
   }
 
-  const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
-  if (is_curve_edit) {
-    return OPERATOR_CANCELLED;
-  }
-
   if (activegpl->flag & GP_LAYER_LOCKED) {
     return OPERATOR_CANCELLED;
   }
@@ -3766,29 +3761,34 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
 
     /* Add all stroke selected of the frame. */
     LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
-      if (gps->flag & GP_STROKE_SELECT) {
-        /* 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_material_editable(ob, gpl, gps) == false) {
-          continue;
-        }
-        elem = &strokes_list[tot_strokes];
-        elem->gpf = gpf;
-        elem->gps = gps;
-        elem->used = false;
-
-        tot_strokes++;
-        /* Limit the number of strokes. */
-        if (tot_strokes == max_join_strokes) {
-          BKE_reportf(op->reports,
-                      RPT_WARNING,
-                      "Too many strokes selected, only joined first %d strokes",
-                      max_join_strokes);
-          break;
-        }
+      bool is_stroke_selected = GPENCIL_STROKE_TYPE_BEZIER(gps) ?
+                                    (bool)(gps->editcurve->flag & GP_CURVE_SELECT) :
+        

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list