[Bf-blender-cvs] [f4a990b] master: Fix for curve smooth ignoring cyclic

Walid Shouman noreply at git.blender.org
Thu Mar 27 23:27:38 CET 2014


Commit: f4a990bfcd27e05b36a3cec5b14aabbb189c5240
Author: Walid Shouman
Date:   Fri Mar 28 09:21:01 2014 +1100
https://developer.blender.org/rBf4a990bfcd27e05b36a3cec5b14aabbb189c5240

Fix for curve smooth ignoring cyclic

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

M	source/blender/editors/curve/editcurve.c

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

diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index db233c6..7444f9e 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -2565,55 +2565,128 @@ void CURVE_OT_radius_set(wmOperatorType *ot)
 
 /********************* smooth operator ********************/
 
+static void smooth_single_bezt(
+        BezTriple *bezt,
+        const BezTriple *bezt_orig_prev, const BezTriple *bezt_orig_next,
+        float factor)
+{
+	int i;
+
+	BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f));
+
+	for (i = 0; i < 3; i++) {
+		float val_old, val_new, offset;
+
+		/* get single dimension pos of the mid handle */
+		val_old = bezt->vec[1][i];
+
+		/* get the weights of the previous/next mid handles and calc offset */
+		val_new = (bezt_orig_prev->vec[1][i] * 0.5f) + (bezt_orig_next->vec[1][i] * 0.5f);
+		offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old;
+
+		/* offset midpoint and 2 handles */
+		bezt->vec[1][i] += offset;
+		bezt->vec[0][i] += offset;
+		bezt->vec[2][i] += offset;
+	}
+}
+
+/**
+ * Same as smooth_single_bezt(), keep in sync
+ */
+static void smooth_single_bp(
+        BPoint *bp,
+        const BPoint *bp_orig_prev, const BPoint *bp_orig_next,
+        float factor)
+{
+	int i;
+
+	BLI_assert(IN_RANGE_INCL(factor, 0.0f, 1.0f));
+
+	for (i = 0; i < 3; i++) {
+		float val_old, val_new, offset;
+
+		val_old = bp->vec[i];
+		val_new = (bp_orig_prev->vec[i] * 0.5f) + (bp_orig_next->vec[i] * 0.5f);
+		offset = (val_old * (1.0f - factor)) + (val_new * factor) - val_old;
+
+		bp->vec[i] += offset;
+	}
+}
+
 static int smooth_exec(bContext *C, wmOperator *UNUSED(op))
 {
+	const float factor = 1.0f / 6.0f;
 	Object *obedit = CTX_data_edit_object(C);
 	ListBase *editnurb = object_editcurve_get(obedit);
 	Nurb *nu;
-	BezTriple *bezt, *beztOrig;
-	BPoint *bp, *bpOrig;
-	float val, newval, offset;
-	int a, i;
+
+	int a, a_end;
 	bool changed = false;
-	
+
 	for (nu = editnurb->first; nu; nu = nu->next) {
 		if (nu->bezt) {
+			/* duplicate the curve to use in weight calculation */
+			const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt);
+			BezTriple *bezt;
 			changed = false;
-			beztOrig = MEM_dupallocN(nu->bezt);
-			for (bezt = &nu->bezt[1], a = 1; a < nu->pntsu - 1; a++, bezt++) {
+
+			/* check whether its cyclic or not, and set initial & final conditions */
+			if (nu->flagu & CU_NURB_CYCLIC) {
+				a = 0;
+				a_end = nu->pntsu;
+			}
+			else {
+				a = 1;
+				a_end = nu->pntsu - 1;
+			}
+
+			/* for all the curve points */
+			for (; a < a_end; a++) {
+				/* respect selection */
+				bezt = &nu->bezt[a];
 				if (bezt->f2 & SELECT) {
-					for (i = 0; i < 3; i++) {
-						val = bezt->vec[1][i];
-						newval = ((beztOrig + (a - 1))->vec[1][i] * 0.5f) + ((beztOrig + (a + 1))->vec[1][i] * 0.5f);
-						offset = (val * ((1.0f / 6.0f) * 5.0f)) + (newval * (1.0f / 6.0f)) - val;
-						/* offset handles */
-						bezt->vec[1][i] += offset;
-						bezt->vec[0][i] += offset;
-						bezt->vec[2][i] += offset;
-					}
+					const BezTriple *bezt_orig_prev, *bezt_orig_next;
+
+					bezt_orig_prev = &bezt_orig[mod_i(a - 1, nu->pntsu)];
+					bezt_orig_next = &bezt_orig[mod_i(a + 1, nu->pntsu)];
+
+					smooth_single_bezt(bezt, bezt_orig_prev, bezt_orig_next, factor);
+
 					changed = true;
 				}
 			}
-			MEM_freeN(beztOrig);
+			MEM_freeN((void *)bezt_orig);
 			if (changed) {
 				BKE_nurb_handles_calc(nu);
 			}
 		}
 		else if (nu->bp) {
-			bpOrig = MEM_dupallocN(nu->bp);
 			/* Same as above, keep these the same! */
-			for (bp = &nu->bp[1], a = 1; a < nu->pntsu - 1; a++, bp++) {
+			const BPoint *bp_orig = MEM_dupallocN(nu->bp);
+			BPoint *bp;
+
+			if (nu->flagu & CU_NURB_CYCLIC) {
+				a = 0;
+				a_end = nu->pntsu;
+			}
+			else {
+				a = 1;
+				a_end = nu->pntsu - 1;
+			}
+
+			for (; a < a_end; a++) {
+				bp = &nu->bp[a];
 				if (bp->f1 & SELECT) {
-					for (i = 0; i < 3; i++) {
-						val = bp->vec[i];
-						newval = ((bpOrig + (a - 1))->vec[i] * 0.5f) + ((bpOrig + (a + 1))->vec[i] * 0.5f);
-						offset = (val * ((1.0f / 6.0f) * 5.0f)) + (newval * (1.0f / 6.0f)) - val;
-					
-						bp->vec[i] += offset;
-					}
+					const BPoint *bp_orig_prev, *bp_orig_next;
+
+					bp_orig_prev = &bp_orig[mod_i(a - 1, nu->pntsu)];
+					bp_orig_next = &bp_orig[mod_i(a + 1, nu->pntsu)];
+
+					smooth_single_bp(bp, bp_orig_prev, bp_orig_next, factor);
 				}
 			}
-			MEM_freeN(bpOrig);
+			MEM_freeN((void *)bp_orig);
 		}
 	}




More information about the Bf-blender-cvs mailing list