[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