[Bf-blender-cvs] [bce924b] master: HSL color wheel implementation.

Antony Riakiotakis noreply at git.blender.org
Wed Mar 12 17:58:54 CET 2014


Commit: bce924b43c4c5ff46eec7b340b68f37ae8e15215
Author: Antony Riakiotakis
Date:   Wed Mar 12 18:58:50 2014 +0200
https://developer.blender.org/rBbce924b43c4c5ff46eec7b340b68f37ae8e15215

HSL color wheel implementation.

This is a standard Hue - Saturation - Lightness model
(see for instance entry on wikipedia here: https://en.wikipedia.org/wiki/HSL_and_HSV)
Note though the difference between HSV and HSL saturation, which are not the same.

The advantage of having this color selection scheme is that artists can select
shades and tints of a color easily by using the lightness slider. Also colors
are arranged on (approximated) perceived lightness on the color wheel.

Beware, Old files opened with this preference saved will crash!

Reviewers: sergey, brecht, campbellbarton

Differential Revision: https://developer.blender.org/D385

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

M	source/blender/blenlib/BLI_math_color.h
M	source/blender/blenlib/intern/math_color.c
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_regions.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/editors/interface/interface_widgets.c
M	source/blender/makesdna/DNA_userdef_types.h
M	source/blender/makesrna/intern/rna_userdef.c

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

diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 3892c98..8a6bc35 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -55,6 +55,8 @@ extern "C" {
 
 void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
 void hsv_to_rgb_v(const float hsv[3], float r_rgb[3]);
+void hsl_to_rgb(float h, float c, float l, float *r, float *g, float *b);
+void hsl_to_rgb_v(const float hcl[3], float r_rgb[3]);
 void hex_to_rgb(char *hexcol, float *r, float *g, float *b);
 void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb);
 void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, int colorspace);
@@ -69,6 +71,8 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
 void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]);
 void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll);
 void rgb_to_hsl_v(const float rgb[3], float r_hsl[3]);
+void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll);
+void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3]);
 void rgb_to_hsv_compat(float r, float g, float b, float *lh, float *ls, float *lv);
 void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3]);
 void rgb_to_lab(float r, float g, float b, float *ll, float *la, float *lb);
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 51980ad..43f6d4c 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -94,12 +94,71 @@ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b)
 	}
 }
 
+/* HSL to rgb conversion from https://en.wikipedia.org/wiki/HSL_and_HSV */
+void hsl_to_rgb(float h, float s, float l, float *r, float *g, float *b)
+{
+	float i, f, c;
+	h = (h - floorf(h)) * 6.0f;
+	c = (l > 0.5f) ? (2.0f * (1.0f - l) * s) : (2.0f * l * s);
+	i = floorf(h);
+	f = h - i;
+
+#define x2 (c * f)
+#define x1 (c * (1.0f - f))
+
+	/* faster to compare floats then int conversion */
+	if (i < 1.0f) {
+		*r = c;
+		*g = x2;
+		*b = 0;
+	}
+	else if (i < 2.0f) {
+		*r = x1;
+		*g = c;
+		*b = 0;
+	}
+	else if (i < 3.0f) {
+		*r = 0;
+		*g = c;
+		*b = x2;
+	}
+	else if (i < 4.0f) {
+		*r = 0;
+		*g = x1;
+		*b = c;
+	}
+	else if (i < 5.0f) {
+		*r = x2;
+		*g = 0;
+		*b = c;
+	}
+	else {
+		*r = c;
+		*g = 0;
+		*b = x1;
+	}
+
+#undef x1
+#undef x2
+
+	f = l - 0.5f * c;
+	*r += f;
+	*g += f;
+	*b += f;
+}
+
 /* convenience function for now */
 void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
 {
 	hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
 }
 
+/* convenience function for now */
+void hsl_to_rgb_v(const float hcl[3], float r_rgb[3])
+{
+	hsl_to_rgb(hcl[0], hcl[1], hcl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
+}
+
 void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv)
 {
 	float y, u, v;
@@ -315,6 +374,33 @@ void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll)
 	*ll = l;
 }
 
+void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll)
+{
+	float orig_s = *ls;
+	float orig_h = *lh;
+
+	rgb_to_hsl(r, g, b, lh, ls, ll);
+
+	if (*ll <= 0.0f) {
+		*lh = orig_h;
+		*ls = orig_s;
+	}
+	else if (*ls <= 0.0f) {
+		*lh = orig_h;
+		*ls = orig_s;
+	}
+
+	if (*lh == 0.0f && orig_h >= 1.0f) {
+		*lh = 1.0f;
+	}
+}
+
+void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3])
+{
+	rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
+}
+
+
 /* convenience function for now */
 void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
 {
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index e486ccc8..2177b06 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -283,6 +283,7 @@ typedef enum {
 #define UI_GRAD_V       5
 
 #define UI_GRAD_V_ALT   9
+#define UI_GRAD_L_ALT   10
 
 /* Drawing
  *
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index b8e0002..744d19d 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1096,7 +1096,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
 		block->auto_open_last = block->oldblock->auto_open_last;
 		block->tooltipdisabled = block->oldblock->tooltipdisabled;
 		copy_v3_v3(ui_block_hsv_get(block),
-		           ui_block_hsv_get(block->oldblock));
+				   ui_block_hsv_get(block->oldblock));
 
 		block->oldblock = NULL;
 	}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 8ead084..f25e045 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4300,7 +4300,10 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
 	if (use_display_colorspace)
 		ui_block_to_display_space_v3(but->block, rgb);
 
-	rgb_to_hsv_compat_v(rgb, hsv);
+	if (but->a1 == UI_GRAD_L_ALT)
+		rgb_to_hsl_compat_v(rgb, hsv);
+	else
+		rgb_to_hsv_compat_v(rgb, hsv);
 	
 	/* only apply the delta motion, not absolute */
 	if (shift) {
@@ -4315,7 +4318,10 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
 			ui_block_to_display_space_v3(but->block, rgb);
 		
 		copy_v3_v3(hsvo, ui_block_hsv_get(but->block));
-		rgb_to_hsv_compat_v(rgb, hsvo);
+		if (but->a1 == UI_GRAD_L_ALT)
+			rgb_to_hsl_compat_v(rgb, hsvo);
+		else
+			rgb_to_hsv_compat_v(rgb, hsvo);
 		
 		/* and original position */
 		ui_hsvcube_pos_from_vals(but, &rect_i, hsvo, &xpos, &ypos);
@@ -4353,11 +4359,11 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
 			hsv[2] = x;
 			break;
 		case UI_GRAD_V_ALT:
+		case UI_GRAD_L_ALT:
 			/* vertical 'value' strip */
 
 			/* exception only for value strip - use the range set in but->min/max */
 			hsv[2] = y * (but->softmax - but->softmin) + but->softmin;
-
 			break;
 		default:
 			BLI_assert(0);
@@ -4370,13 +4376,16 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
 		}
 	}
 
-	hsv_to_rgb_v(hsv, rgb);
+	if (but->a1 == UI_GRAD_L_ALT)
+		hsl_to_rgb_v(hsv, rgb);
+	else
+		hsv_to_rgb_v(hsv, rgb);
 
 	if (use_display_colorspace)
 		ui_block_to_scene_linear_v3(but->block, rgb);
 
 	/* clamp because with color conversion we can exceed range [#34295] */
-	if ((int)but->a1 == UI_GRAD_V_ALT) {
+	if (ELEM((int)but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) {
 		clamp_axis_max_v3(rgb, but->softmax);
 	}
 
@@ -4403,8 +4412,11 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
 	if (use_display_colorspace)
 		ui_block_to_display_space_v3(but->block, rgb);
 
-	rgb_to_hsv_compat_v(rgb, hsv);
-	
+	if (but->a1 == UI_GRAD_L_ALT)
+		rgb_to_hsl_compat_v(rgb, hsv);
+	else
+		rgb_to_hsv_compat_v(rgb, hsv);
+
 	switch ((int)but->a1) {
 		case UI_GRAD_SV:
 			hsv[2] += ndof->rvec[2] * sensitivity;
@@ -4428,6 +4440,7 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
 			hsv[2] += ndof->rvec[2] * sensitivity;
 			break;
 		case UI_GRAD_V_ALT:
+		case UI_GRAD_L_ALT:
 			/* vertical 'value' strip */
 			
 			/* exception only for value strip - use the range set in but->min/max */
@@ -4449,7 +4462,10 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
 	/* ndof specific: the changes above aren't clamping */
 	hsv_clamp_v(hsv, hsv_v_max);
 
-	hsv_to_rgb_v(hsv, rgb);
+	if (but->a1 == UI_GRAD_L_ALT)
+		hsl_to_rgb_v(hsv, rgb);
+	else
+		hsv_to_rgb_v(hsv, rgb);
 
 	if (use_display_colorspace)
 		ui_block_to_scene_linear_v3(but->block, rgb);
@@ -4501,11 +4517,10 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 				/* reset only value */
 				
 				len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
-				if (len >= 3) {
+				if (ELEM(len, 3, 4)) {
 					float rgb[3], def_hsv[3];
-					float *def;
+					float def[4];
 					float *hsv = ui_block_hsv_get(but->block);
-					def = MEM_callocN(sizeof(float) * len, "reset_defaults - float");
 					
 					RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
 					rgb_to_hsv_v(def, def_hsv);
@@ -4519,9 +4534,34 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 					hsv_to_rgb_v(def_hsv, rgb);
 					ui_set_but_vectorf(but, rgb);
 					
+					RNA_property_update(C, &but->rnapoin, but->rnaprop);					
+				}
+				return WM_UI_HANDLER_BREAK;
+			}
+			else if (but->a1 == UI_GRAD_L_ALT) {
+				int len;
+
+				/* reset only value */
+
+				len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
+				if (ELEM(len, 3, 4)) {
+					float rgb[3], def_hsl[3];
+					float def[4];
+					float *hsl = ui_block_hsv_get(but->block);
+
+					RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
+					rgb_to_hsl_v(def, def_hsl);
+
+					ui_get_but_vectorf(but, rgb);
+					rgb_to_hsl_compat_v(rgb, hsl);
+
+					def_hsl[0] = hsl[0];
+					def_hsl[1] = hsl[1];
+
+					hsl_to_rgb_v(def_hsl, rgb);
+					ui_set_but_vectorf(but, rgb);
+
 					RNA_property_update(C, &but->rnapoin, but->rnaprop);
-					
-					MEM_freeN(def);
 				}
 				return WM_UI_HANDLER_BREAK;
 			}
@@ -4585,8 +4625,9 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
 
 	ui_get_but_vectorf(but, rgb);
 	copy_v3_v3(hsv, ui_block_hsv_get(but->block));
-	rgb_to_hsv_compat_v(rgb, hsv);
-	
+
+	ui_rgb_to_color_picker_compat_v(rgb, hsv);
+
 	/* exception, when using color wheel in 'locked' value state:
 	 * allow choosing a hue for black values, by giving a tiny increment */
 	if (but->flag & UI_BUT_COLOR_LOCK) { // lock
@@ -4599,10 +4640,12 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
 		
 		/* calculate original hsv again */
 		copy_v3_v3(hsvo, ui_block_hsv_get(but->block));
-		rgb_to_hsv_compat_v(data->origvec, hsvo);
+
+		ui_rgb_to_color_picker_compat_v(data->origvec, hsvo);
+
 		/* and original position */
 		ui_hsvcircle_pos_from_vals(but, &rect

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list