[Bf-blender-cvs] [58302012942] soc-2020-greasepencil-curve: GPencil: Add function to create editcurve from stroke

Falk David noreply at git.blender.org
Tue Jun 9 14:32:35 CEST 2020


Commit: 58302012942ad56c13995da38efc7d92da5a7ec6
Author: Falk David
Date:   Tue Jun 9 14:23:33 2020 +0200
Branches: soc-2020-greasepencil-curve
https://developer.blender.org/rB58302012942ad56c13995da38efc7d92da5a7ec6

GPencil: Add function to create editcurve from stroke

This BKE function uses curve_fit_cubic_to_points_fl to fit a curve
to a grease pencil stroke.

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

M	source/blender/blenkernel/BKE_gpencil_curve.h
M	source/blender/blenkernel/intern/gpencil_curve.c

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

diff --git a/source/blender/blenkernel/BKE_gpencil_curve.h b/source/blender/blenkernel/BKE_gpencil_curve.h
index cf6f9074bda..b76b9e8b27b 100644
--- a/source/blender/blenkernel/BKE_gpencil_curve.h
+++ b/source/blender/blenkernel/BKE_gpencil_curve.h
@@ -31,6 +31,7 @@ extern "C" {
 struct Main;
 struct Object;
 struct Scene;
+struct bGPDstroke;
 
 void BKE_gpencil_convert_curve(struct Main *bmain,
                                struct Scene *scene,
@@ -40,6 +41,8 @@ void BKE_gpencil_convert_curve(struct Main *bmain,
                                const bool use_collections,
                                const bool only_stroke);
 
+void BKE_gpencil_stroke_curve_create(struct bGPDstroke *gps);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index 8299943cc49..92febb8fecb 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -47,8 +47,12 @@
 #include "BKE_material.h"
 #include "BKE_object.h"
 
+#include "curve_fit_nd.h"
+
 #include "DEG_depsgraph_query.h"
 
+#define POINT_DIM 3
+
 /* Helper: Check materials with same color. */
 static int gpencil_check_same_material_color(Object *ob_gp, float color[4], Material **r_mat)
 {
@@ -447,4 +451,61 @@ void BKE_gpencil_convert_curve(Main *bmain,
   DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
 }
 
+/**
+ * Creates a new editcurve for a stroke by doing a cubic curve fitting.
+ * \param gps, the grease pencil stroke 
+ */
+void BKE_gpencil_stroke_curve_create(bGPDstroke *gps)
+{
+  if (gps == NULL || gps->totpoints < 0 || gps->editcurve != NULL) {
+    return;
+  }
+
+  float *points = MEM_callocN(sizeof(float) * gps->totpoints * POINT_DIM, __func__);
+  for (int i = 0; i < gps->totpoints; i++) {
+    bGPDspoint *pt = &gps->points[i];
+    float *to = &points[i * POINT_DIM];
+    copy_v3_v3(to, &pt->x);
+  }
+  float *r_cubic_array = NULL;
+  unsigned int r_cubic_array_len = 0;
+  unsigned int *r_cubic_orig_index = NULL;
+  unsigned int *r_corners_index_array = NULL;
+  unsigned int r_corners_index_len = 0;
+  int r = curve_fit_cubic_to_points_fl(points,
+                                       gps->totpoints,
+                                       POINT_DIM,
+                                       0.1f,
+                                       CURVE_FIT_CALC_HIGH_QUALIY,
+                                       NULL,
+                                       0,
+                                       &r_cubic_array,
+                                       &r_cubic_array_len,
+                                       &r_cubic_orig_index,
+                                       &r_corners_index_array,
+                                       &r_corners_index_len);
+  if (r == 0 && r_cubic_array_len > 0) {
+    bGPDcurve *editcurve = BKE_gpencil_stroke_editcurve_new(r_cubic_array_len);
+    gps->editcurve = editcurve;
+
+    for (int i = 0; i < r_cubic_array_len; i++) {
+      BezTriple *bezt = &editcurve->curve_points[i];
+      for (int j = 0; j < 3; j++) {
+        copy_v3_v3(bezt->vec[j], &r_cubic_array[i * 9 + j * 3]);
+      }
+    }
+  }
+
+  MEM_freeN(points);
+  if (r_cubic_array) {
+    free(r_cubic_array);
+  }
+  if (r_corners_index_array) {
+    free(r_corners_index_array);
+  }
+  if (r_cubic_orig_index) {
+    free(r_corners_index_array);
+  }
+}
+
 /** \} */



More information about the Bf-blender-cvs mailing list