[Bf-blender-cvs] [abb9d0b] master: Curve Fitting: add high-quality flag

Campbell Barton noreply at git.blender.org
Mon Jun 13 18:25:45 CEST 2016


Commit: abb9d0b0ad297bf2e1b58e1cb8be58b9d5470faa
Author: Campbell Barton
Date:   Tue Jun 14 02:11:57 2016 +1000
Branches: master
https://developer.blender.org/rBabb9d0b0ad297bf2e1b58e1cb8be58b9d5470faa

Curve Fitting: add high-quality flag

When this flag is set - even when the curve error is under the threshold,
keep attempting a better fit.

Enable this for freehand drawing, since it gives nicer results and isn't noticeably slower.

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

M	extern/curve_fit_nd/curve_fit_nd.h
M	extern/curve_fit_nd/intern/curve_fit_cubic.c
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 ff6b951..3649802 100644
--- a/extern/curve_fit_nd/curve_fit_nd.h
+++ b/extern/curve_fit_nd/curve_fit_nd.h
@@ -60,6 +60,7 @@ int curve_fit_cubic_to_points_db(
         const unsigned int  points_len,
         const unsigned int  dims,
         const double        error_threshold,
+        const unsigned int  calc_flag,
         const unsigned int *corners,
         unsigned int        corners_len,
 
@@ -72,6 +73,7 @@ int curve_fit_cubic_to_points_fl(
         const unsigned int  points_len,
         const unsigned int  dims,
         const float         error_threshold,
+        const unsigned int  calc_flag,
         const unsigned int *corners,
         const unsigned int  corners_len,
 
@@ -117,6 +119,10 @@ int curve_fit_cubic_to_points_single_fl(
         float   r_handle_r[],
         float  *r_error_sq);
 
+enum {
+	CURVE_FIT_CALC_HIGH_QUALIY          = (1 << 0),
+};
+
 /* curve_fit_corners_detect.c */
 
 /**
diff --git a/extern/curve_fit_nd/intern/curve_fit_cubic.c b/extern/curve_fit_nd/intern/curve_fit_cubic.c
index 4364e8f..1a0f7dc 100644
--- a/extern/curve_fit_nd/intern/curve_fit_cubic.c
+++ b/extern/curve_fit_nd/intern/curve_fit_cubic.c
@@ -1086,11 +1086,7 @@ static bool fit_cubic_to_points(
 	*r_error_max_sq = error_max_sq;
 	*r_split_index  = split_index;
 
-	if (error_max_sq < error_threshold_sq) {
-		free(u);
-		return true;
-	}
-	else {
+	if (!(error_max_sq < error_threshold_sq)) {
 		cubic_copy(cubic_test, r_cubic, dims);
 
 		/* If error not too large, try some reparameterization and iteration */
@@ -1108,25 +1104,28 @@ static bool fit_cubic_to_points(
 			        points_offset_coords_length,
 #endif
 			        u_prime, tan_l, tan_r, dims, cubic_test);
-			error_max_sq = cubic_calc_error(
+
+			const double error_max_sq_test = cubic_calc_error(
 			        cubic_test, points_offset, points_offset_len, u_prime, dims,
 			        &split_index);
 
-			if (error_max_sq < error_threshold_sq) {
-				free(u_prime);
-				free(u);
-
-				cubic_copy(r_cubic, cubic_test, dims);
-				*r_error_max_sq = error_max_sq;
-				*r_split_index  = split_index;
-				return true;
-			}
-			else if (error_max_sq < *r_error_max_sq) {
+			if (error_max_sq > error_max_sq_test) {
+				error_max_sq = error_max_sq_test;
 				cubic_copy(r_cubic, cubic_test, dims);
 				*r_error_max_sq = error_max_sq;
 				*r_split_index = split_index;
 			}
 
+			if (!(error_max_sq < error_threshold_sq)) {
+				/* continue */
+			}
+			else {
+				assert((error_max_sq < error_threshold_sq));
+				free(u_prime);
+				free(u);
+				return true;
+			}
+
 			SWAP(double *, u, u_prime);
 		}
 		free(u_prime);
@@ -1134,6 +1133,10 @@ static bool fit_cubic_to_points(
 
 		return false;
 	}
+	else {
+		free(u);
+		return true;
+	}
 }
 
 static void fit_cubic_to_points_recursive(
@@ -1145,6 +1148,7 @@ static void fit_cubic_to_points_recursive(
         const double  tan_l[],
         const double  tan_r[],
         const double  error_threshold_sq,
+        const uint    calc_flag,
         const uint    dims,
         /* fill in the list */
         CubicList *clist)
@@ -1158,8 +1162,11 @@ static void fit_cubic_to_points_recursive(
 #ifdef USE_LENGTH_CACHE
 	        points_length_cache,
 #endif
-	        tan_l, tan_r, error_threshold_sq, dims,
-	        cubic, &error_max_sq, &split_index))
+	        tan_l, tan_r,
+	        (calc_flag & CURVE_FIT_CALC_HIGH_QUALIY) ? DBL_EPSILON : error_threshold_sq,
+	        dims,
+	        cubic, &error_max_sq, &split_index) ||
+	    (error_max_sq < error_threshold_sq))
 	{
 		cubic_list_prepend(clist, cubic);
 		return;
@@ -1211,13 +1218,13 @@ static void fit_cubic_to_points_recursive(
 #ifdef USE_LENGTH_CACHE
 	        points_length_cache,
 #endif
-	        tan_l, tan_center, error_threshold_sq, dims, clist);
+	        tan_l, tan_center, error_threshold_sq, calc_flag, dims, clist);
 	fit_cubic_to_points_recursive(
 	        &points_offset[split_index * dims], points_offset_len - split_index,
 #ifdef USE_LENGTH_CACHE
 	        points_length_cache + split_index,
 #endif
-	        tan_center, tan_r, error_threshold_sq, dims, clist);
+	        tan_center, tan_r, error_threshold_sq, calc_flag, dims, clist);
 
 }
 
@@ -1240,6 +1247,7 @@ int curve_fit_cubic_to_points_db(
         const uint    points_len,
         const uint    dims,
         const double  error_threshold,
+        const uint    calc_flag,
         const uint   *corners,
         uint          corners_len,
 
@@ -1315,7 +1323,7 @@ int curve_fit_cubic_to_points_db(
 #ifdef USE_LENGTH_CACHE
 			        points_length_cache,
 #endif
-			        tan_l, tan_r, error_threshold_sq, dims, &clist);
+			        tan_l, tan_r, error_threshold_sq, calc_flag, dims, &clist);
 		}
 		else if (points_len == 1) {
 			assert(points_offset_len == 1);
@@ -1382,6 +1390,7 @@ int curve_fit_cubic_to_points_fl(
         const uint    points_len,
         const uint    dims,
         const float   error_threshold,
+        const uint    calc_flag,
         const uint   *corners,
         const uint    corners_len,
 
@@ -1399,7 +1408,7 @@ int curve_fit_cubic_to_points_fl(
 	uint    cubic_array_len = 0;
 
 	int result = curve_fit_cubic_to_points_db(
-	        points_db, points_len, dims, error_threshold, corners, corners_len,
+	        points_db, points_len, dims, error_threshold, calc_flag, corners, corners_len,
 	        &cubic_array_db, &cubic_array_len,
 	        r_cubic_orig_index,
 	        r_corner_index_array, r_corner_index_len);
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index bb7cc61..3801854 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -911,7 +911,7 @@ static int curve_draw_exec(bContext *C, wmOperator *op)
 		unsigned int  corners_index_len = 0;
 
 		const int result = curve_fit_cubic_to_points_fl(
-		        coords, stroke_len, dims, error_threshold,
+		        coords, stroke_len, dims, error_threshold, CURVE_FIT_CALC_HIGH_QUALIY,
 		        corners, corners_len,
 		        &cubic_spline, &cubic_spline_len,
 		        NULL,




More information about the Bf-blender-cvs mailing list