Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/extern
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-06-13 19:11:57 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-06-13 19:27:32 +0300
commitabb9d0b0ad297bf2e1b58e1cb8be58b9d5470faa (patch)
tree88311426ec53dd19b6c2335b4123f27513f1a0e8 /extern
parentb0985b393ce0335ffbdf5a67bc7cd01d55323ad1 (diff)
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.
Diffstat (limited to 'extern')
-rw-r--r--extern/curve_fit_nd/curve_fit_nd.h6
-rw-r--r--extern/curve_fit_nd/intern/curve_fit_cubic.c53
2 files changed, 37 insertions, 22 deletions
diff --git a/extern/curve_fit_nd/curve_fit_nd.h b/extern/curve_fit_nd/curve_fit_nd.h
index ff6b9513a9b..3649802a425 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 4364e8f878f..1a0f7dcfdee 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);