[Bf-blender-cvs] [8c74ebb] master: Support Auto-Clamped Handle for Curve-Mapping

Campbell Barton noreply at git.blender.org
Mon Aug 1 01:04:49 CEST 2016


Commit: 8c74ebb64f883701aecd291e5543b0f27ded8764
Author: Campbell Barton
Date:   Mon Aug 1 09:01:43 2016 +1000
Branches: master
https://developer.blender.org/rB8c74ebb64f883701aecd291e5543b0f27ded8764

Support Auto-Clamped Handle for Curve-Mapping

This patch supports auto-clamped handles for curves,
useful since without this it can be difficult to have 'flat' sections of a curve.

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

M	source/blender/blenkernel/BKE_colortools.h
M	source/blender/blenkernel/intern/colortools.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/makesdna/DNA_color_types.h
M	source/blender/makesrna/intern/rna_color.c

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

diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index e5d3480..5b4f591 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -61,7 +61,7 @@ void                    curvemap_reset(struct CurveMap *cuma, const struct rctf
 void                    curvemap_remove(struct CurveMap *cuma, const short flag);
 bool                    curvemap_remove_point(struct CurveMap *cuma, struct CurveMapPoint *cmp);
 struct CurveMapPoint   *curvemap_insert(struct CurveMap *cuma, float x, float y);
-void                    curvemap_sethandle(struct CurveMap *cuma, int type);
+void                    curvemap_handle_set(struct CurveMap *cuma, int type);
 
 void                curvemapping_changed(struct CurveMapping *cumap, const bool rem_doubles);
 void                curvemapping_changed_all(struct CurveMapping *cumap);
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 53a7402..4f3ffed 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -293,8 +293,8 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
 			cuma->curve[1].x = clipr->xmax;
 			cuma->curve[1].y = clipr->ymin;
 			if (slope == CURVEMAP_SLOPE_POS_NEG) {
-				cuma->curve[0].flag |= CUMA_VECTOR;
-				cuma->curve[1].flag |= CUMA_VECTOR;
+				cuma->curve[0].flag |= CUMA_HANDLE_VECTOR;
+				cuma->curve[1].flag |= CUMA_HANDLE_VECTOR;
 			}
 			break;
 		case CURVE_PRESET_SHARP:
@@ -391,15 +391,25 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
 	}
 }
 
-/* if type==1: vector, else auto */
-void curvemap_sethandle(CurveMap *cuma, int type)
+/**
+ * \param type: eBezTriple_Handle
+ */
+void curvemap_handle_set(CurveMap *cuma, int type)
 {
 	int a;
 	
 	for (a = 0; a < cuma->totpoint; a++) {
 		if (cuma->curve[a].flag & CUMA_SELECT) {
-			if (type) cuma->curve[a].flag |= CUMA_VECTOR;
-			else cuma->curve[a].flag &= ~CUMA_VECTOR;
+			cuma->curve[a].flag &= ~(CUMA_HANDLE_VECTOR | CUMA_HANDLE_AUTO_ANIM);
+			if (type == HD_VECT) {
+				cuma->curve[a].flag |= CUMA_HANDLE_VECTOR;
+			}
+			else if (type == HD_AUTO_ANIM) {
+				cuma->curve[a].flag |= CUMA_HANDLE_AUTO_ANIM;
+			}
+			else {
+				/* pass */
+			}
 		}
 	}
 }
@@ -457,7 +467,7 @@ static void calchandle_curvemap(
 	if (len_a == 0.0f) len_a = 1.0f;
 	if (len_b == 0.0f) len_b = 1.0f;
 
-	if (bezt->h1 == HD_AUTO || bezt->h2 == HD_AUTO) { /* auto */
+	if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) || ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {    /* auto */
 		float tvec[2];
 		tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a;
 		tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a;
@@ -465,13 +475,57 @@ static void calchandle_curvemap(
 		len = len_v2(tvec) * 2.5614f;
 		if (len != 0.0f) {
 			
-			if (bezt->h1 == HD_AUTO) {
+			if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) {
 				len_a /= len;
 				madd_v2_v2v2fl(p2_h1, p2, tvec, -len_a);
+
+				if ((bezt->h1 == HD_AUTO_ANIM) && next && prev) { /* keep horizontal if extrema */
+					const float ydiff1 = prev->vec[1][1] - bezt->vec[1][1];
+					const float ydiff2 = next->vec[1][1] - bezt->vec[1][1];
+					if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) ||
+					    (ydiff1 >= 0.0f && ydiff2 >= 0.0f))
+					{
+						bezt->vec[0][1] = bezt->vec[1][1];
+					}
+					else { /* handles should not be beyond y coord of two others */
+						if (ydiff1 <= 0.0f) {
+							if (prev->vec[1][1] > bezt->vec[0][1]) {
+								bezt->vec[0][1] = prev->vec[1][1];
+							}
+						}
+						else {
+							if (prev->vec[1][1] < bezt->vec[0][1]) {
+								bezt->vec[0][1] = prev->vec[1][1];
+							}
+						}
+					}
+				}
 			}
-			if (bezt->h2 == HD_AUTO) {
+			if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
 				len_b /= len;
 				madd_v2_v2v2fl(p2_h2, p2, tvec,  len_b);
+
+				if ((bezt->h2 == HD_AUTO_ANIM) && next && prev) { /* keep horizontal if extrema */
+					const float ydiff1 = prev->vec[1][1] - bezt->vec[1][1];
+					const float ydiff2 = next->vec[1][1] - bezt->vec[1][1];
+					if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f)||
+					    (ydiff1 >= 0.0f && ydiff2 >= 0.0f))
+					{
+						bezt->vec[2][1] = bezt->vec[1][1];
+					}
+					else { /* handles should not be beyond y coord of two others */
+						if (ydiff1 <= 0.0f) {
+							if (next->vec[1][1] < bezt->vec[2][1]) {
+								bezt->vec[2][1] = next->vec[1][1];
+							}
+						}
+						else {
+							if (next->vec[1][1] > bezt->vec[2][1]) {
+								bezt->vec[2][1] = next->vec[1][1];
+							}
+						}
+					}
+				}
 			}
 		}
 	}
@@ -540,10 +594,15 @@ static void curvemap_make_table(CurveMap *cuma, const rctf *clipr)
 		cuma->maxtable = max_ff(cuma->maxtable, cmp[a].x);
 		bezt[a].vec[1][0] = cmp[a].x;
 		bezt[a].vec[1][1] = cmp[a].y;
-		if (cmp[a].flag & CUMA_VECTOR)
+		if (cmp[a].flag & CUMA_HANDLE_VECTOR) {
 			bezt[a].h1 = bezt[a].h2 = HD_VECT;
-		else
+		}
+		else if (cmp[a].flag & CUMA_HANDLE_AUTO_ANIM) {
+			bezt[a].h1 = bezt[a].h2 = HD_AUTO_ANIM;
+		}
+		else {
 			bezt[a].h1 = bezt[a].h2 = HD_AUTO;
+		}
 	}
 	
 	const BezTriple *bezt_prev = NULL;
@@ -773,12 +832,12 @@ void curvemapping_changed(CurveMapping *cumap, const bool rem_doubles)
 			dy = cmp[a].y - cmp[a + 1].y;
 			if (sqrtf(dx * dx + dy * dy) < thresh) {
 				if (a == 0) {
-					cmp[a + 1].flag |= CUMA_VECTOR;
+					cmp[a + 1].flag |= CUMA_HANDLE_VECTOR;
 					if (cmp[a + 1].flag & CUMA_SELECT)
 						cmp[a].flag |= CUMA_SELECT;
 				}
 				else {
-					cmp[a].flag |= CUMA_VECTOR;
+					cmp[a].flag |= CUMA_HANDLE_VECTOR;
 					if (cmp[a].flag & CUMA_SELECT)
 						cmp[a + 1].flag |= CUMA_SELECT;
 				}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index aec4065..58cadf5 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1940,6 +1940,7 @@ enum {
 	UICURVE_FUNC_RESET_VIEW,
 	UICURVE_FUNC_HANDLE_VECTOR,
 	UICURVE_FUNC_HANDLE_AUTO,
+	UICURVE_FUNC_HANDLE_AUTO_ANIM,
 	UICURVE_FUNC_EXTEND_HOZ,
 	UICURVE_FUNC_EXTEND_EXP,
 };
@@ -1960,13 +1961,16 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
 			cumap->curr = cumap->clipr;
 			break;
 		case UICURVE_FUNC_HANDLE_VECTOR: /* set vector */
-			curvemap_sethandle(cuma, 1);
+			curvemap_handle_set(cuma, HD_VECT);
 			curvemapping_changed(cumap, false);
 			break;
 		case UICURVE_FUNC_HANDLE_AUTO: /* set auto */
-			curvemap_sethandle(cuma, 0);
+			curvemap_handle_set(cuma, HD_AUTO);
 			curvemapping_changed(cumap, false);
 			break;
+		case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */
+			curvemap_handle_set(cuma, HD_AUTO_ANIM);
+			curvemapping_changed(cumap, false);
 		case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
 			cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
 			curvemapping_changed(cumap, false);
@@ -2000,6 +2004,9 @@ static uiBlock *curvemap_tools_func(
 		uiDefIconTextBut(
 		        block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Handle"),
 		        0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO, "");
+		uiDefIconTextBut(
+		        block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Clamped Handle"),
+		        0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO_ANIM, "");
 	}
 
 	if (show_extend) {
diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h
index 1d88b01..f7ee1ff 100644
--- a/source/blender/makesdna/DNA_color_types.h
+++ b/source/blender/makesdna/DNA_color_types.h
@@ -49,7 +49,8 @@ typedef struct CurveMapPoint {
 /* curvepoint->flag */
 enum {
 	CUMA_SELECT = 1,
-	CUMA_VECTOR = 2
+	CUMA_HANDLE_VECTOR = 2,
+	CUMA_HANDLE_AUTO_ANIM = 4,
 };
 
 typedef struct CurveMap {
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 78e3bbe..24f2d81 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -690,7 +690,8 @@ static void rna_def_curvemappoint(BlenderRNA *brna)
 	PropertyRNA *prop;
 	static EnumPropertyItem prop_handle_type_items[] = {
 		{0, "AUTO", 0, "Auto Handle", ""},
-		{CUMA_VECTOR, "VECTOR", 0, "Vector Handle", ""},
+		{CUMA_HANDLE_AUTO_ANIM, "AUTO_CLAMPED", 0, "Auto Clamped Handle", ""},
+		{CUMA_HANDLE_VECTOR, "VECTOR", 0, "Vector Handle", ""},
 		{0, NULL, 0, NULL, NULL}
 	};




More information about the Bf-blender-cvs mailing list