Page MenuHome
Paste P183

Curve interpolation (Fred Harthoorn's method) patch for Blender2.73 (experement)
ActivePublic

Authored by Campbell Barton (campbellbarton) on Dec 29 2014, 1:39 AM.
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 13a1468..611980c 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -182,4 +182,10 @@ void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
void BKE_nurb_bezt_handle_test(struct BezTriple *bezt, const bool use_handle);
void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles);
+#define USE_FREDCURVE
+#ifdef USE_FREDCURVE
+float BKE_nurb_fredcurve_res_grad(int gr);
+void BKE_nurb_fredcurve(const float *src_array, int src_stride, float *dst_array, int dst_stride, int src_tot, int resol, float res_grad);
+#endif
+
#endif /* __BKE_CURVE_H__ */
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 937ceff..3534301 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -1347,6 +1347,41 @@ void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float *
MEM_freeN(basisu);
}
+#ifdef USE_FREDCURVE
+#define log2f(x) (logf(x) * M_LOG2E)
+float BKE_nurb_fredcurve_res_grad(int gr)
+{
+ return 1.0f / powf(2.0f, (3.0f * log2f(gr)));
+}
+
+#define MAKEDDDT(StartValue, X0, X1, X2, X3, D3X, V) \
+{ \
+ X0 = X1; X1 = X2; X2 = X3; X3 = (V - StartValue); \
+ D3X = -X0 + X1 + X1 + X1 - X2 - X2 - X2 + X3; \
+} (void)0
+
+void BKE_nurb_fredcurve(const float *src_array, int src_stride, float *dst_array, int dst_stride, int src_tot, int resol, float res_grad)
+{
+ float series[4] = {0}, deriv[4] = {0};
+ const float *src_fp = src_array, *src_fp_next, p_start = *src_fp;
+ float *dst_fp = dst_array;
+ int i, j, src_last = src_tot - 1;
+
+#define STEP(v, ofs) (float *)((char *)v + ofs)
+ for (j = 0; j != src_last; j++, src_fp = src_fp_next) {
+ const float p_next = *(src_fp_next = STEP(src_fp, src_stride));
+ MAKEDDDT(p_start, series[0], series[1], series[2], series[3], deriv[3], p_next);
+ for (i = 0; i < resol; i++, dst_fp = STEP(dst_fp, dst_stride)) {
+ deriv[2] = deriv[2] + deriv[3];
+ deriv[1] = deriv[1] + deriv[2];
+ deriv[0] = deriv[0] + deriv[1];
+ *dst_fp = p_start + (deriv[0] * res_grad);
+ }
+ }
+#undef STEP
+}
+#endif /* USE_FREDCURVE */
+
/* forward differencing method for bezier curve */
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
{
@@ -2786,11 +2821,26 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
seglen = bl->seglen;
segbevcount = bl->segbevcount;
+#ifdef USE_FREDCURVE
+ {
+ const float res_grad = BKE_nurb_fredcurve_res_grad(resolu);
+ BKE_nurb_fredcurve(&nu->bp->vec[0], sizeof(BPoint), &bevp->vec[0], sizeof(BevPoint), nu->pntsu, resolu, res_grad);
+ BKE_nurb_fredcurve(&nu->bp->vec[1], sizeof(BPoint), &bevp->vec[1], sizeof(BevPoint), nu->pntsu, resolu, res_grad);
+ BKE_nurb_fredcurve(&nu->bp->vec[2], sizeof(BPoint), &bevp->vec[2], sizeof(BevPoint), nu->pntsu, resolu, res_grad);
+ if (do_tilt)
+ BKE_nurb_fredcurve(&nu->bp->alfa, sizeof(BPoint), &bevp->alfa, sizeof(BevPoint), nu->pntsu, resolu, res_grad);
+ if (do_radius)
+ BKE_nurb_fredcurve(&nu->bp->radius, sizeof(BPoint), &bevp->radius, sizeof(BevPoint), nu->pntsu, resolu, res_grad);
+ if (do_weight)
+ BKE_nurb_fredcurve(&nu->bp->weight, sizeof(BPoint), &bevp->weight, sizeof(BevPoint), nu->pntsu, resolu, res_grad);
+ }
+#else
BKE_nurb_makeCurve(nu, &bevp->vec[0],
do_tilt ? &bevp->alfa : NULL,
do_radius ? &bevp->radius : NULL,
do_weight ? &bevp->weight : NULL,
resolu, sizeof(BevPoint));
+#endif
/* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */
if (seglen != NULL) {
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 80a8d37..a22a48b 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -408,7 +408,17 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase,
if (nu->flagu & CU_NURB_CYCLIC)
dl->type = DL_POLY;
else dl->type = DL_SEGM;
+
+#ifdef USE_FREDCURVE
+ {
+ const float res_grad = BKE_nurb_fredcurve_res_grad(resolu);
+ BKE_nurb_fredcurve(&nu->bp->vec[0], sizeof(BPoint), &data[0], sizeof(float[3]), nu->pntsu, resolu, res_grad);
+ BKE_nurb_fredcurve(&nu->bp->vec[1], sizeof(BPoint), &data[1], sizeof(float[3]), nu->pntsu, resolu, res_grad);
+ BKE_nurb_fredcurve(&nu->bp->vec[2], sizeof(BPoint), &data[2], sizeof(float[3]), nu->pntsu, resolu, res_grad);
+ }
+#else
BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, 3 * sizeof(float));
+#endif
}
else if (nu->type == CU_POLY) {
len = nu->pntsu;

Event Timeline

Campbell Barton (campbellbarton) changed the title of this paste from untitled to Fred Harthoorn's curve interpolation patch for Blender2.73 (experement).
Campbell Barton (campbellbarton) updated the paste's language from autodetect to diff.
Campbell Barton (campbellbarton) changed the title of this paste from Fred Harthoorn's curve interpolation patch for Blender2.73 (experement) to Curve interpolation (Fred Harthoorn's method) patch for Blender2.73 (experement).