[Bf-blender-cvs] [a808ade3a26] greasepencil-object: GPencil: Create one stroke for each spline

Antonioya noreply at git.blender.org
Tue Jul 16 12:13:56 CEST 2019


Commit: a808ade3a26750aa7caf71d944cdddcd3a6fd510
Author: Antonioya
Date:   Tue Jul 16 11:00:19 2019 +0200
Branches: greasepencil-object
https://developer.blender.org/rBa808ade3a26750aa7caf71d944cdddcd3a6fd510

GPencil: Create one stroke for each spline

For curves with several splines, must create a stroke for each of them or the shape would be wrong.

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

M	source/blender/blenkernel/intern/gpencil.c

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

diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 70c66805dc0..2c67f89cc14 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -2118,7 +2118,7 @@ static void gpencil_add_new_points(
   }
 }
 
-/* Helper function to get the first collection that includes the object */
+/* Helper function to get the first collection that includes the object. */
 static Collection *gpencil_get_parent_collection(Scene *scene, Object *ob)
 {
   Collection *mycol = NULL;
@@ -2134,52 +2134,19 @@ static Collection *gpencil_get_parent_collection(Scene *scene, Object *ob)
   return mycol;
 }
 
-/* Convert a curve object to grease pencil stroke.
- *
- * \param bmain: Main thread pointer
- * \param scene: Original scene.
- * \param ob_gp: Grease pencil object to add strokes.
- * \param ob_cu: Curve to convert.
- * \param gpencil_lines: Use lines for strokes.
- * \param use_collections: Create layers using collection names.
- */
-void BKE_gpencil_convert_curve(Main *bmain,
-                               Scene *scene,
-                               Object *ob_gp,
-                               Object *ob_cu,
-                               const bool gpencil_lines,
-                               const bool use_collections)
+/* Helper function to convert one spline to grease pencil stroke. */
+static void gpencil_convert_spline(Main *bmain,
+                                   Scene *scene,
+                                   Object *ob_gp,
+                                   Object *ob_cu,
+                                   const bool gpencil_lines,
+                                   const bool use_collections,
+                                   bGPDframe *gpf,
+                                   Nurb *nu)
 {
-  if (ELEM(NULL, ob_gp, ob_cu) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == NULL)) {
-    return;
-  }
-
-  bGPdata *gpd = (bGPdata *)ob_gp->data;
   Curve *cu = (Curve *)ob_cu->data;
-  Nurb *nu = NULL;
   bool cyclic = true;
-  bGPDlayer *gpl = NULL;
 
-  /* Check if there is an active layer. */
-  if (use_collections) {
-    Collection *collection = gpencil_get_parent_collection(scene, ob_cu);
-    if (collection != NULL) {
-      gpl = BLI_findstring(&gpd->layers, collection->id.name + 2, offsetof(bGPDlayer, info));
-      if (gpl == NULL) {
-        gpl = BKE_gpencil_layer_addnew(gpd, collection->id.name + 2, true);
-      }
-    }
-  }
-
-  if (gpl == NULL) {
-    gpl = BKE_gpencil_layer_getactive(gpd);
-    if (gpl == NULL) {
-      gpl = BKE_gpencil_layer_addnew(gpd, DATA_("GP_Layer"), true);
-    }
-  }
-
-  /* Check if there is an active frame. */
-  bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_COPY);
   /* Create Stroke. */
   bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "bGPDstroke");
   gps->thickness = 1.0f;
@@ -2200,20 +2167,16 @@ void BKE_gpencil_convert_curve(Main *bmain,
    */
   int totpoints = 0;
   int segments = 0;
-  for (nu = cu->nurb.first; nu; nu = nu->next) {
-    int resolu = nu->resolu + 1;
-    if (nu->type == CU_BEZIER) {
-      segments = nu->pntsu;
-      if (((nu->flagu & CU_NURB_CYCLIC) == 0) || (nu->pntsu == 2)) {
-        segments--;
-        cyclic = false;
-      }
-      totpoints += resolu * segments;
-    }
+  int resolu = nu->resolu + 1;
+  segments = nu->pntsu;
+  if (((nu->flagu & CU_NURB_CYCLIC) == 0) || (nu->pntsu == 2)) {
+    segments--;
+    cyclic = false;
   }
-  totpoints -= segments - 1;
-  gps->totpoints = totpoints;
+  totpoints = (resolu * segments) - (segments - 1);
+
   /* Allocate memory for storage points, but keep empty. */
+  gps->totpoints = totpoints;
   gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
   /* Initialize triangle memory to dummy data. */
   gps->tot_triangles = 0;
@@ -2263,11 +2226,11 @@ void BKE_gpencil_convert_curve(Main *bmain,
       /* Also use the first color if the fill is none for stroke color. */
       ma_stroke = give_current_material(ob_cu, 1);
       linearrgb_to_srgb_v3_v3(mat_gp->gp_style->stroke_rgba, &ma_stroke->r);
-      /* set fill to off */
+      /* set fill to off. */
       mat_gp->gp_style->flag &= ~GP_STYLE_FILL_SHOW;
     }
   }
-
+  /* Assign material index to stroke. */
   gps->mat_nr = r_idx;
 
   /* Add stroke to frame.*/
@@ -2275,46 +2238,101 @@ void BKE_gpencil_convert_curve(Main *bmain,
 
   /* Read all segments of the curve. */
   int init = 0;
-  for (nu = cu->nurb.first; nu; nu = nu->next) {
-    int resolu = nu->resolu + 1;
-    if (nu->type == CU_BEZIER) {
-      segments = nu->pntsu;
-      if (((nu->flagu & CU_NURB_CYCLIC) == 0) || (nu->pntsu == 2)) {
-        segments--;
-      }
-      /* Get all interpolated curve points of Beziert */
-      for (int s = 0; s < segments; s++) {
-        int inext = (s + 1) % nu->pntsu;
-        BezTriple *prevbezt = &nu->bezt[s];
-        BezTriple *bezt = &nu->bezt[inext];
-
-        float *coord_array = MEM_callocN(3 * resolu * sizeof(float), __func__);
-
-        for (int j = 0; j < 3; j++) {
-          BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
-                                        prevbezt->vec[2][j],
-                                        bezt->vec[0][j],
-                                        bezt->vec[1][j],
-                                        coord_array + j,
-                                        resolu - 1,
-                                        3 * sizeof(float));
-        }
-        /* Add points to the stroke */
-        gpencil_add_new_points(gps, coord_array, bezt->radius, init, resolu);
-        /* Free memory. */
-        MEM_SAFE_FREE(coord_array);
-
-        /* As the last point of segment is the first point of next segment, back one array
-         * element to avoid duplicated points on the same location.
-         */
-        init += resolu - 1;
-      }
+  resolu = nu->resolu + 1;
+  segments = nu->pntsu;
+  if (((nu->flagu & CU_NURB_CYCLIC) == 0) || (nu->pntsu == 2)) {
+    segments--;
+  }
+  /* Get all interpolated curve points of Beziert */
+  for (int s = 0; s < segments; s++) {
+    int inext = (s + 1) % nu->pntsu;
+    BezTriple *prevbezt = &nu->bezt[s];
+    BezTriple *bezt = &nu->bezt[inext];
+
+    float *coord_array = MEM_callocN(3 * resolu * sizeof(float), __func__);
+
+    for (int j = 0; j < 3; j++) {
+      BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
+                                    prevbezt->vec[2][j],
+                                    bezt->vec[0][j],
+                                    bezt->vec[1][j],
+                                    coord_array + j,
+                                    resolu - 1,
+                                    3 * sizeof(float));
     }
+    /* Add points to the stroke */
+    gpencil_add_new_points(gps, coord_array, bezt->radius, init, resolu);
+    /* Free memory. */
+    MEM_SAFE_FREE(coord_array);
+
+    /* As the last point of segment is the first point of next segment, back one array
+     * element to avoid duplicated points on the same location.
+     */
+    init += resolu - 1;
   }
   /* Cyclic curve, close stroke. */
   if ((cyclic) && (!only_stroke)) {
     BKE_gpencil_close_stroke(gps);
   }
+}
+
+/* Convert a curve object to grease pencil stroke.
+ *
+ * \param bmain: Main thread pointer
+ * \param scene: Original scene.
+ * \param ob_gp: Grease pencil object to add strokes.
+ * \param ob_cu: Curve to convert.
+ * \param gpencil_lines: Use lines for strokes.
+ * \param use_collections: Create layers using collection names.
+ */
+void BKE_gpencil_convert_curve(Main *bmain,
+                               Scene *scene,
+                               Object *ob_gp,
+                               Object *ob_cu,
+                               const bool gpencil_lines,
+                               const bool use_collections)
+{
+  if (ELEM(NULL, ob_gp, ob_cu) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == NULL)) {
+    return;
+  }
+
+  Curve *cu = (Curve *)ob_cu->data;
+  bGPdata *gpd = (bGPdata *)ob_gp->data;
+  bGPDlayer *gpl = NULL;
+
+  /* If the curve is empty, cancel. */
+  if (cu->nurb.first == NULL) {
+    return;
+  }
+
+  /* Check if there is an active layer. */
+  if (use_collections) {
+    Collection *collection = gpencil_get_parent_collection(scene, ob_cu);
+    if (collection != NULL) {
+      gpl = BLI_findstring(&gpd->layers, collection->id.name + 2, offsetof(bGPDlayer, info));
+      if (gpl == NULL) {
+        gpl = BKE_gpencil_layer_addnew(gpd, collection->id.name + 2, true);
+      }
+    }
+  }
+
+  if (gpl == NULL) {
+    gpl = BKE_gpencil_layer_getactive(gpd);
+    if (gpl == NULL) {
+      gpl = BKE_gpencil_layer_addnew(gpd, DATA_("GP_Layer"), true);
+    }
+  }
+
+  /* Check if there is an active frame and add if needed. */
+  bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_COPY);
+
+  /* Read all splines of the curve and create a stroke for each. */
+  for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) {
+    if (nu->type == CU_BEZIER) {
+      gpencil_convert_spline(bmain, scene, ob_gp, ob_cu, gpencil_lines, use_collections, gpf, nu);
+    }
+  }
 
+  /* Tag for recalculation */
   DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
 }



More information about the Bf-blender-cvs mailing list