From 9355bece599582358d8ed7b39bdf376446ba7018 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Jun 2012 22:48:40 +0000 Subject: click dragging with the eye dropper now averages out colors - useful when you have grainy footage of a green screen. --- source/blender/editors/interface/interface_ops.c | 114 ++++++++++++++++++----- 1 file changed, 90 insertions(+), 24 deletions(-) (limited to 'source/blender/editors/interface/interface_ops.c') diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index dfd2d0cc4d0..3900e0f01f2 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -40,6 +40,7 @@ #include "BLI_blenlib.h" #include "BLI_math_color.h" +#include "BLI_math_vector.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -69,22 +70,42 @@ /* ********************************************************** */ typedef struct Eyedropper { + short do_color_management; + PointerRNA ptr; PropertyRNA *prop; int index; + + int accum_start; /* has mouse been presed */ + float accum_col[4]; + int accum_tot; } Eyedropper; static int eyedropper_init(bContext *C, wmOperator *op) { + Scene *scene = CTX_data_scene(C); + const int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; + Eyedropper *eye; op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper"); uiContextActiveProperty(C, &eye->ptr, &eye->prop, &eye->index); - - return (eye->ptr.data && eye->prop && RNA_property_editable(&eye->ptr, eye->prop)); + + if ((eye->ptr.data == NULL) || + (eye->prop == NULL) || + (RNA_property_editable(&eye->ptr, eye->prop) == FALSE) || + (RNA_property_array_length(&eye->ptr, eye->prop) < 3) || + (RNA_property_type(eye->prop) != PROP_FLOAT)) + { + return FALSE; + } + + eye->do_color_management = (color_manage && RNA_property_subtype(eye->prop) == PROP_COLOR); + + return TRUE; } - + static void eyedropper_exit(bContext *C, wmOperator *op) { WM_cursor_restore(CTX_wm_window(C)); @@ -100,29 +121,57 @@ static int eyedropper_cancel(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } -static void eyedropper_sample(bContext *C, Eyedropper *eye, int mx, int my) +/* *** eyedropper_color_ helper functions *** */ +static void eyedropper_color_sample_fl(Eyedropper *UNUSED(eye), int mx, int my, + float r_col[4]) { - if (RNA_property_type(eye->prop) == PROP_FLOAT) { - Scene *scene = CTX_data_scene(C); - const int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; - float col[4]; - - RNA_property_float_get_array(&eye->ptr, eye->prop, col); - - glReadBuffer(GL_FRONT); - glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, col); - glReadBuffer(GL_BACK); - - if (RNA_property_array_length(&eye->ptr, eye->prop) < 3) return; + glReadBuffer(GL_FRONT); + glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col); + glReadBuffer(GL_BACK); +} - /* convert from screen (srgb) space to linear rgb space */ - if (color_manage && RNA_property_subtype(eye->prop) == PROP_COLOR) - srgb_to_linearrgb_v3_v3(col, col); - - RNA_property_float_set_array(&eye->ptr, eye->prop, col); - - RNA_property_update(C, &eye->ptr, eye->prop); +static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[4]) +{ + float col_linear[4]; + /* convert from screen (srgb) space to linear rgb space */ + if (eye->do_color_management) { + srgb_to_linearrgb_v3_v3(col_linear, col); + } + else { + copy_v3_v3(col_linear, col); } + col_linear[3] = col[3]; + + RNA_property_float_set_array(&eye->ptr, eye->prop, col_linear); + + RNA_property_update(C, &eye->ptr, eye->prop); +} + +static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye) +{ + float col[4]; + mul_v4_v4fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); + eyedropper_color_set(C, eye, col); +} + +static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my) +{ + float col[4]; + + RNA_property_float_get_array(&eye->ptr, eye->prop, col); + + eyedropper_color_sample_fl(eye, mx, my, col); + + eyedropper_color_set(C, eye, col); +} + +static void eyedropper_color_sample_accum(Eyedropper *eye, int mx, int my) +{ + float col[4]; + eyedropper_color_sample_fl(eye, mx, my, col); + /* delay linear conversion */ + add_v4_v4(eye->accum_col, col); + eye->accum_tot++; } /* main modal status check */ @@ -136,10 +185,27 @@ static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event) return eyedropper_cancel(C, op); case LEFTMOUSE: if (event->val == KM_RELEASE) { - eyedropper_sample(C, eye, event->x, event->y); + if (eye->accum_tot == 0) { + eyedropper_color_sample(C, eye, event->x, event->y); + } + else { + eyedropper_color_set_accum(C, eye); + } eyedropper_exit(C, op); return OPERATOR_FINISHED; } + else if (event->val == KM_PRESS) { + /* enable accum and make first sample */ + eye->accum_start = TRUE; + eyedropper_color_sample_accum(eye, event->x, event->y); + } + break; + case MOUSEMOVE: + if (eye->accum_start) { + /* button is pressed so keep sampling */ + eyedropper_color_sample_accum(eye, event->x, event->y); + eyedropper_color_set_accum(C, eye); + } break; } -- cgit v1.2.3