[Bf-blender-cvs] [2b796ed] master: ColorRamp HSV, HSL Blend Modes

Campbell Barton noreply at git.blender.org
Fri Aug 15 07:31:59 CEST 2014


Commit: 2b796ed03d8d256a1325e62d19c51702937df027
Author: Campbell Barton
Date:   Fri Aug 15 15:29:08 2014 +1000
Branches: master
https://developer.blender.org/rB2b796ed03d8d256a1325e62d19c51702937df027

ColorRamp HSV, HSL Blend Modes

D297 by charlie with own edits

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

M	source/blender/blenkernel/intern/texture.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/makesdna/DNA_texture_types.h
M	source/blender/makesrna/intern/rna_color.c

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

diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 77f6277..62e55a7 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -41,6 +41,7 @@
 #include "BLI_math.h"
 #include "BLI_kdopbvh.h"
 #include "BLI_utildefines.h"
+#include "BLI_math_color.h"
 
 #include "DNA_key_types.h"
 #include "DNA_object_types.h"
@@ -237,7 +238,7 @@ void init_colorband(ColorBand *coba, bool rangetype)
 	}
 	
 	coba->tot = 2;
-	
+	coba->color_mode = COLBAND_BLEND_RGB;
 }
 
 ColorBand *add_colorband(bool rangetype)
@@ -252,106 +253,219 @@ ColorBand *add_colorband(bool rangetype)
 
 /* ------------------------------------------------------------------------- */
 
+static float colorband_hue_interp(
+        const int ipotype_hue,
+        const float mfac, const float fac,
+        float h1, float h2)
+{
+	float h_interp;
+	int mode = 0;
+
+#define HUE_INTERP(h_a, h_b) ((mfac * (h_a)) + (fac * (h_b)))
+#define HUE_MOD(h) (((h) < 1.0f) ? (h) : (h) - 1.0f)
+
+	h1 = HUE_MOD(h1);
+	h2 = HUE_MOD(h2);
+
+	BLI_assert(h1 >= 0.0f && h1 < 1.0f);
+	BLI_assert(h2 >= 0.0f && h2 < 1.0f);
+
+	switch (ipotype_hue) {
+		case COLBAND_HUE_NEAR:
+		{
+			if      ((h1 < h2) && (h2 - h1) > +0.5f) mode = 1;
+			else if ((h1 > h2) && (h2 - h1) < -0.5f) mode = 2;
+			else                                     mode = 0;
+			break;
+		}
+		case COLBAND_HUE_FAR:
+		{
+			if      ((h1 < h2) && (h2 - h1) < +0.5f) mode = 1;
+			else if ((h1 > h2) && (h2 - h1) > -0.5f) mode = 2;
+			else                                     mode = 0;
+			break;
+		}
+		case COLBAND_HUE_CW:
+		{
+			if (h1 > h2) mode = 2;
+			else         mode = 0;
+			break;
+		}
+		case COLBAND_HUE_CCW:
+		{
+			if (h1 < h2) mode = 1;
+			else         mode = 0;
+			break;
+		}
+	}
+
+	switch (mode) {
+		case 0:
+			h_interp = HUE_INTERP(h1, h2);
+			break;
+		case 1:
+			h_interp = HUE_INTERP(h1 + 1.0f, h2);
+			h_interp = HUE_MOD(h_interp);
+			break;
+		case 2:
+			h_interp = HUE_INTERP(h1, h2 + 1.0f);
+			h_interp = HUE_MOD(h_interp);
+			break;
+	}
+
+	BLI_assert(h_interp >= 0.0f && h_interp < 1.0f);
+
+#undef HUE_INTERP
+#undef HUE_MOD
+
+	return h_interp;
+}
+
 bool do_colorband(const ColorBand *coba, float in, float out[4])
 {
 	const CBData *cbd1, *cbd2, *cbd0, *cbd3;
-	float fac, mfac, t[4];
+	float fac;
+	int ipotype;
 	int a;
 	
 	if (coba == NULL || coba->tot == 0) return 0;
 	
 	cbd1 = coba->data;
+
+	ipotype = (coba->color_mode == COLBAND_BLEND_RGB) ? coba->ipotype : COLBAND_INTERP_LINEAR;
+
 	if (coba->tot == 1) {
 		out[0] = cbd1->r;
 		out[1] = cbd1->g;
 		out[2] = cbd1->b;
 		out[3] = cbd1->a;
 	}
+	else if ((in <= cbd1->pos) && ELEM(ipotype, COLBAND_INTERP_LINEAR, COLBAND_INTERP_EASE)) {
+		out[0] = cbd1->r;
+		out[1] = cbd1->g;
+		out[2] = cbd1->b;
+		out[3] = cbd1->a;
+	}
 	else {
-		if (in <= cbd1->pos && coba->ipotype < 2) {
+		CBData left, right;
+
+		/* we're looking for first pos > in */
+		for (a = 0; a < coba->tot; a++, cbd1++) if (cbd1->pos > in) break;
+
+		if (a == coba->tot) {
+			cbd2 = cbd1 - 1;
+			right = *cbd2;
+			right.pos = 1.0f;
+			cbd1 = &right;
+		}
+		else if (a == 0) {
+			left = *cbd1;
+			left.pos = 0.0f;
+			cbd2 = &left;
+		}
+		else {
+			cbd2 = cbd1 - 1;
+		}
+
+		if ((in >= cbd1->pos) && ELEM(ipotype, COLBAND_INTERP_LINEAR, COLBAND_INTERP_EASE)) {
 			out[0] = cbd1->r;
 			out[1] = cbd1->g;
 			out[2] = cbd1->b;
 			out[3] = cbd1->a;
 		}
 		else {
-			CBData left, right;
-			
-			/* we're looking for first pos > in */
-			for (a = 0; a < coba->tot; a++, cbd1++) if (cbd1->pos > in) break;
-				
-			if (a == coba->tot) {
-				cbd2 = cbd1 - 1;
-				right = *cbd2;
-				right.pos = 1.0f;
-				cbd1 = &right;
-			}
-			else if (a == 0) {
-				left = *cbd1;
-				left.pos = 0.0f;
-				cbd2 = &left;
+
+			if (cbd2->pos != cbd1->pos) {
+				fac = (in - cbd1->pos) / (cbd2->pos - cbd1->pos);
 			}
 			else {
-				cbd2 = cbd1 - 1;
+				/* was setting to 0.0 in 2.56 & previous, but this
+				 * is incorrect for the last element, see [#26732] */
+				fac = (a != coba->tot) ? 0.0f : 1.0f;
 			}
-			
-			if (in >= cbd1->pos && coba->ipotype < 2) {
-				out[0] = cbd1->r;
-				out[1] = cbd1->g;
-				out[2] = cbd1->b;
-				out[3] = cbd1->a;
+
+			if (coba->ipotype == COLBAND_INTERP_CONSTANT) {
+				/* constant */
+				out[0] = cbd2->r;
+				out[1] = cbd2->g;
+				out[2] = cbd2->b;
+				out[3] = cbd2->a;
 			}
-			else {
-		
-				if (cbd2->pos != cbd1->pos)
-					fac = (in - cbd1->pos) / (cbd2->pos - cbd1->pos);
+			else if (ipotype >= COLBAND_INTERP_B_SPLINE) {
+				/* ipo from right to left: 3 2 1 0 */
+				float t[4];
+
+				if (a >= coba->tot - 1) cbd0 = cbd1;
+				else cbd0 = cbd1 + 1;
+				if (a < 2) cbd3 = cbd2;
+				else cbd3 = cbd2 - 1;
+
+				CLAMP(fac, 0.0f, 1.0f);
+
+				if (ipotype == COLBAND_INTERP_CARDINAL) {
+					key_curve_position_weights(fac, t, KEY_CARDINAL);
+				}
 				else {
-					/* was setting to 0.0 in 2.56 & previous, but this
-					 * is incorrect for the last element, see [#26732] */
-					fac = (a != coba->tot) ? 0.0f : 1.0f;
+					key_curve_position_weights(fac, t, KEY_BSPLINE);
 				}
-				
-				if (coba->ipotype == 4) {
-					/* constant */
-					out[0] = cbd2->r;
-					out[1] = cbd2->g;
-					out[2] = cbd2->b;
-					out[3] = cbd2->a;
-					return 1;
+
+				out[0] = t[3] * cbd3->r + t[2] * cbd2->r + t[1] * cbd1->r + t[0] * cbd0->r;
+				out[1] = t[3] * cbd3->g + t[2] * cbd2->g + t[1] * cbd1->g + t[0] * cbd0->g;
+				out[2] = t[3] * cbd3->b + t[2] * cbd2->b + t[1] * cbd1->b + t[0] * cbd0->b;
+				out[3] = t[3] * cbd3->a + t[2] * cbd2->a + t[1] * cbd1->a + t[0] * cbd0->a;
+				CLAMP(out[0], 0.0f, 1.0f);
+				CLAMP(out[1], 0.0f, 1.0f);
+				CLAMP(out[2], 0.0f, 1.0f);
+				CLAMP(out[3], 0.0f, 1.0f);
+			}
+			else {
+				float mfac;
+
+				if (ipotype == COLBAND_INTERP_EASE) {
+					mfac = fac * fac;
+					fac = 3.0f * mfac - 2.0f * mfac * fac;
 				}
-				
-				if (coba->ipotype >= 2) {
-					/* ipo from right to left: 3 2 1 0 */
-					
-					if (a >= coba->tot - 1) cbd0 = cbd1;
-					else cbd0 = cbd1 + 1;
-					if (a < 2) cbd3 = cbd2;
-					else cbd3 = cbd2 - 1;
-					
-					CLAMP(fac, 0.0f, 1.0f);
-					
-					if (coba->ipotype == 3)
-						key_curve_position_weights(fac, t, KEY_CARDINAL);
-					else
-						key_curve_position_weights(fac, t, KEY_BSPLINE);
-
-					out[0] = t[3] * cbd3->r + t[2] * cbd2->r + t[1] * cbd1->r + t[0] * cbd0->r;
-					out[1] = t[3] * cbd3->g + t[2] * cbd2->g + t[1] * cbd1->g + t[0] * cbd0->g;
-					out[2] = t[3] * cbd3->b + t[2] * cbd2->b + t[1] * cbd1->b + t[0] * cbd0->b;
-					out[3] = t[3] * cbd3->a + t[2] * cbd2->a + t[1] * cbd1->a + t[0] * cbd0->a;
-					CLAMP(out[0], 0.0f, 1.0f);
-					CLAMP(out[1], 0.0f, 1.0f);
-					CLAMP(out[2], 0.0f, 1.0f);
-					CLAMP(out[3], 0.0f, 1.0f);
+
+				mfac = 1.0f - fac;
+
+				if (UNLIKELY(coba->color_mode == COLBAND_BLEND_HSV)) {
+					float col1[3], col2[3];
+
+					linearrgb_to_srgb_v3_v3(col1, &cbd1->r);
+					linearrgb_to_srgb_v3_v3(col2, &cbd2->r);
+
+					rgb_to_hsv_v(col1, col1);
+					rgb_to_hsv_v(col2, col2);
+
+					out[0] = colorband_hue_interp(coba->ipotype_hue, mfac, fac, col1[0], col2[0]);
+					out[1] = mfac * col1[1] + fac * col2[1];
+					out[2] = mfac * col1[2] + fac * col2[2];
+					out[3] = mfac * cbd1->a + fac * cbd2->a;
+
+					hsv_to_rgb_v(out, out);
+
+					srgb_to_linearrgb_v3_v3(out, out);
+				}
+				else if (UNLIKELY(coba->color_mode == COLBAND_BLEND_HSL)) {
+					float col1[3], col2[3];
+
+					linearrgb_to_srgb_v3_v3(col1, &cbd1->r);
+					linearrgb_to_srgb_v3_v3(col2, &cbd2->r);
+
+					rgb_to_hsl_v(col1, col1);
+					rgb_to_hsl_v(col2, col2);
+
+					out[0] = colorband_hue_interp(coba->ipotype_hue, mfac, fac, col1[0], col2[0]);
+					out[1] = mfac * col1[1] + fac * col2[1];
+					out[2] = mfac * col1[2] + fac * col2[2];
+					out[3] = mfac * cbd1->a + fac * cbd2->a;
+
+					hsl_to_rgb_v(out, out);
+
+					srgb_to_linearrgb_v3_v3(out, out);
 				}
 				else {
-				
-					if (coba->ipotype == 1) { /* EASE */
-						mfac = fac * fac;
-						fac = 3.0f * mfac - 2.0f * mfac * fac;
-					}
-					mfac = 1.0f - fac;
-					
+					/* COLBAND_BLEND_RGB */
 					out[0] = mfac * cbd1->r + fac * cbd2->r;
 					out[1] = mfac * cbd1->g + fac * cbd2->g;
 					out[2] = mfac * cbd1->b + fac * cbd2->b;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index cb5f533..7f85a23 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -37,6 +37,7 @@
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
 #include "DNA_brush_types.h"
+#include "DNA_texture_types.h"
 
 #include "BLI_utildefines.h"
 #include "BLI_string.h"
@@ -1529,7 +1530,15 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand
 
 	row = uiLayoutRow(split, false);
 
-	uiItemR(row, &ptr, "interpolation", 0, "", ICON_NONE);
+	uiBlockBeginAlign(block);
+	uiItemR(row, &ptr, "color_mode", 0, "", ICON_NONE);
+	if (ELEM(coba->color_mode, COLBAND_BLEND_HSV, COLBAND_BLEND_HSL)) {
+		uiItemR(row, &ptr, "hue_interpolation", 0, "", ICON_NONE);
+	}
+	else {  /* COLBAND_BLEND_RGB */
+		uiItemR(row, &ptr, "interpolation", 0, "", ICON_NONE);
+	}
+	uiBlockEndAlign(block);
 
 	row = uiLayoutRow(layout, false);
 
@@ -1567,7 +1576,7 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand
 			uiDefButS(block, NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)),
 			          0, 0, TIP_("Choose active color stop"));
 			row = uiLayoutRow(subsplit, false);
-			uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
+			uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
 			bt = block->buttons.last;
 			uiButSetFunc(bt, colorband_update_cb, bt, coba);
 
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index dc891f8..059a12b 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -111,9 +111,12 @@ typedef struct CBData {
 /* 32 = MAXCOLORBAND */
 /* note that this has

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list