[Bf-blender-cvs] [77a581f] temp-curve-draw: Change curve fitting not to store duplicate points.

Campbell Barton noreply at git.blender.org
Wed Apr 13 19:09:53 CEST 2016


Commit: 77a581f8b9ea74ae0f162c0077b1ecb7bfa13c1f
Author: Campbell Barton
Date:   Thu Apr 14 03:08:24 2016 +1000
Branches: temp-curve-draw
https://developer.blender.org/rB77a581f8b9ea74ae0f162c0077b1ecb7bfa13c1f

Change curve fitting not to store duplicate points.

Return an array of [handle, knot, handle]'s instead of [knot, handle, handle, knot].

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

M	extern/curve_fit_nd/curve_fit_nd.h
M	extern/curve_fit_nd/intern/curve_fit_cubic.c
M	extern/curve_fit_nd/intern/curve_fit_inline.h
M	source/blender/editors/curve/editcurve_paint.c

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

diff --git a/extern/curve_fit_nd/curve_fit_nd.h b/extern/curve_fit_nd/curve_fit_nd.h
index 486862f..3ee39c7 100644
--- a/extern/curve_fit_nd/curve_fit_nd.h
+++ b/extern/curve_fit_nd/curve_fit_nd.h
@@ -40,9 +40,9 @@
  * `points[dims]`
  *
  * And calculates cubic (bezier) splines:
- * `r_cubic_array[r_cubic_array_len][4][dims]`.
+ * `r_cubic_array[r_cubic_array_len][3][dims]`.
  *
- * Where each cubic has 0 and 3 for the points and indices 1 and 2 for the handles.
+ * Where each point has 0 and 2 for the tangents and the middle index 1 for the knot.
  */
 int spline_fit_cubic_to_points_db(
         const double *points,
diff --git a/extern/curve_fit_nd/intern/curve_fit_cubic.c b/extern/curve_fit_nd/intern/curve_fit_cubic.c
index 9b0f4f7..54cb838 100644
--- a/extern/curve_fit_nd/intern/curve_fit_cubic.c
+++ b/extern/curve_fit_nd/intern/curve_fit_cubic.c
@@ -143,20 +143,34 @@ static void cubic_list_prepend(CubicList *clist, Cubic *cubic)
 static double *cubic_list_as_array(const CubicList *clist)
 {
 	const uint dims = clist->dims;
-	const uint array_flat_len = clist->len * 4 * dims;
+	const uint array_flat_len = (clist->len + 1) * 3 * dims;
 
 	double *array = malloc(sizeof(double) * array_flat_len);
 
+	const double *handle_prev = &((Cubic *)clist->items)->pt_data[dims];
+
 	/* fill the array backwards */
-	const size_t array_chunk = 4 * dims;
-	const size_t array_chunk_size = sizeof(double) * array_chunk;
+	const size_t array_chunk = 3 * dims;
 	double *array_iter = array + array_flat_len;
 	for (Cubic *citer = clist->items; citer; citer = citer->next) {
 		array_iter -= array_chunk;
-		memcpy(array_iter, citer->pt_data, array_chunk_size);
+		memcpy(array_iter, &citer->pt_data[2 * dims], sizeof(double) * 2 * dims);
+		memcpy(&array_iter[2 * dims], &handle_prev[dims], sizeof(double) * dims);
+		handle_prev = citer->pt_data;
 	}
+
+	/* flip tangent for first and last (we could leave at zero, but set to something useful) */
+
+	/* first */
+	array_iter -= array_chunk;
+	memcpy(&array_iter[dims], handle_prev, sizeof(double) * 2 * dims);
+	flip_vn_vnvn(&array_iter[0 * dims], &array_iter[1 * dims], &array_iter[2 * dims], dims);
 	assert(array == array_iter);
 
+	/* last */
+	array_iter += array_flat_len - (3 * dims);
+	flip_vn_vnvn(&array_iter[2 * dims], &array_iter[1 * dims], &array_iter[0 * dims], dims);
+
 	return array;
 }
 
@@ -870,7 +884,7 @@ int spline_fit_cubic_to_points_db(
 
 	/* allocate a contiguous array and free the linked list */
 	*r_cubic_array = cubic_list_as_array(&clist);
-	*r_cubic_array_len = clist.len;
+	*r_cubic_array_len = clist.len + 1;
 
 	cubic_list_clear(&clist);
 
@@ -907,7 +921,7 @@ int spline_fit_cubic_to_points_fl(
 	free(points_db);
 
 	if (!result) {
-		uint cubic_array_flat_len = cubic_array_len * 4 * dims;
+		uint cubic_array_flat_len = cubic_array_len * 3 * dims;
 		cubic_array_fl = malloc(sizeof(float) * cubic_array_flat_len);
 		for (uint i = 0; i < cubic_array_flat_len; i++) {
 			cubic_array_fl[i] = (float)cubic_array_db[i];
diff --git a/extern/curve_fit_nd/intern/curve_fit_inline.h b/extern/curve_fit_nd/intern/curve_fit_inline.h
index ccaf351..87a18dc 100644
--- a/extern/curve_fit_nd/intern/curve_fit_inline.h
+++ b/extern/curve_fit_nd/intern/curve_fit_inline.h
@@ -49,13 +49,21 @@ static inline double max(const double a, const double b)
 }
 
 static inline void zero_vn(
-		double *v0, const uint dims)
+		double v0[], const uint dims)
 {
 	for (uint j = 0; j < dims; j++) {
 		v0[j] = 0.0;
 	}
 }
 
+static inline void flip_vn_vnvn(
+		double v_out[], const double v0[], const double v1[], const uint dims)
+{
+	for (uint j = 0; j < dims; j++) {
+		v_out[j] = v0[j] + (v0[j] - v1[j]);
+	}
+}
+
 static inline void copy_vnvn(
         double v0[], const double v1[], const uint dims)
 {
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 9847a46..9f8a81c 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -439,62 +439,46 @@ static int curve_draw_exec(bContext *C, wmOperator *op)
 		}
 
 		if (result == 0) {
-			nu->pntsu = cubic_spline_len + 1;
+			nu->pntsu = cubic_spline_len;
 			nu->bezt = MEM_callocN(sizeof(BezTriple) * nu->pntsu, __func__);
 
 			float *fl = cubic_spline;
-			for (int j = 0; j < cubic_spline_len; j++, fl += (DIMS * 4)) {
-				const float *pt_l     = fl + (DIMS * 0);
-				const float *handle_l = fl + (DIMS * 1);
+			BezTriple *bezt = nu->bezt;
+			for (int j = 0; j < cubic_spline_len; j++, bezt++, fl += (DIMS * 3)) {
+				const float *handle_l = fl + (DIMS * 0);
+				const float *pt       = fl + (DIMS * 1);
 				const float *handle_r = fl + (DIMS * 2);
-				const float *pt_r     = fl + (DIMS * 3);
 
-				zero_v3(nu->bezt[j + 0].vec[1]);
-				zero_v3(nu->bezt[j + 0].vec[2]);
-				zero_v3(nu->bezt[j + 1].vec[0]);
-				zero_v3(nu->bezt[j + 1].vec[1]);
-
-				copy_v3_v3(nu->bezt[j + 0].vec[1], pt_l);
-				copy_v3_v3(nu->bezt[j + 0].vec[2], handle_l);
-				copy_v3_v3(nu->bezt[j + 1].vec[0], handle_r);
-				copy_v3_v3(nu->bezt[j + 1].vec[1], pt_r);
+				copy_v3_v3(bezt->vec[0], handle_l);
+				copy_v3_v3(bezt->vec[1], pt);
+				copy_v3_v3(bezt->vec[2], handle_r);
 
 				if (use_pressure_radius) {
-					nu->bezt[j + 0].radius = (pt_l[3] * radius_range) + radius_min;
-					nu->bezt[j + 1].radius = (pt_r[3] * radius_range) + radius_min;
+					bezt->radius = (pt[3] * radius_range) + radius_min;
 				}
 				else {
-					nu->bezt[j + 0].radius = radius_max;
-					nu->bezt[j + 1].radius = radius_max;
+					bezt->radius = radius_max;
 				}
-			}
 
-			{
-				BezTriple *bezt;
-				bezt = &nu->bezt[0];
-				flip_v3_v3v3(bezt->vec[0], bezt->vec[1], bezt->vec[2]);
+				/* check handle alignment */
 
-				bezt = &nu->bezt[nu->pntsu - 1];
-				flip_v3_v3v3(bezt->vec[2], bezt->vec[1], bezt->vec[0]);
-			}
+				{
+					float tan[2][3];
 
-			for (int j = 0; j < nu->pntsu; j++) {
-				BezTriple *bezt = &nu->bezt[j];
-				float tan[2][3];
+					sub_v3_v3v3(tan[0], bezt->vec[0], bezt->vec[1]);
+					sub_v3_v3v3(tan[1], bezt->vec[2], bezt->vec[1]);
+					float cross[3];
 
-				sub_v3_v3v3(tan[0], bezt->vec[0], bezt->vec[1]);
-				sub_v3_v3v3(tan[1], bezt->vec[2], bezt->vec[1]);
-				float cross[3];
+					cross_v3_v3v3(cross, tan[0], tan[1]);
+					if (len_squared_v3(cross) < 1e-4f) {
+						bezt->h1 = bezt->h2 = HD_ALIGN;
+					}
+					else {
+						bezt->h1 = bezt->h2 = HD_FREE;
+					}
 
-				cross_v3_v3v3(cross, tan[0], tan[1]);
-				if (len_squared_v3(cross) < 1e-4f) {
-					bezt->h1 = bezt->h2 = HD_ALIGN;
+					bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
 				}
-				else {
-					bezt->h1 = bezt->h2 = HD_FREE;
-				}
-
-				bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
 			}
 
 		}




More information about the Bf-blender-cvs mailing list