[Bf-blender-cvs] [48e48653c29] master: Tool System: add radius option to the image sample tool

Campbell Barton noreply at git.blender.org
Thu Mar 7 08:04:52 CET 2019


Commit: 48e48653c2972aa3054ecac329f6f76ba110e0c1
Author: Campbell Barton
Date:   Thu Mar 7 18:02:52 2019 +1100
Branches: master
https://developer.blender.org/rB48e48653c2972aa3054ecac329f6f76ba110e0c1

Tool System: add radius option to the image sample tool

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	source/blender/editors/space_image/image_ops.c

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 11a816c7534..a754f45f12f 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -5108,6 +5108,17 @@ def km_generic_tool_annotate_eraser(params):
         ]},
     )
 
+
+def km_image_editor_tool_generic_sample(params):
+    return (
+        "Image Editor Tool: Sample",
+        {"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
+        {"items": [
+            ("image.sample", {"type": params.tool_mouse, "value": 'PRESS'}, None),
+        ]},
+    )
+
+
 def km_image_editor_tool_uv_cursor(params):
     return (
         "Image Editor Tool: Uv, Cursor",
@@ -6103,6 +6114,7 @@ def generate_keymaps(params=None):
         km_generic_tool_annotate_polygon(params),
         km_generic_tool_annotate_eraser(params),
 
+        km_image_editor_tool_generic_sample(params),
         km_image_editor_tool_uv_cursor(params),
         km_image_editor_tool_uv_select(params),
         km_image_editor_tool_uv_select_box(params),
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 99195873d11..00009575fa7 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -1016,14 +1016,18 @@ class _defs_image_generic:
     # Currently a place holder so we can switch away from the annotation tool.
     # Falls back to default image editor action.
     @ToolDef.from_fn
-    def measure():
+    def sample():
+        def draw_settings(context, layout, tool):
+            props = tool.operator_properties("image.sample")
+            layout.prop(props, "radius")
         return dict(
-            text="Measure",
+            text="Sample",
             description=(
-                "Measure pixel values under the cursor"
+                "Sample pixel values under the cursor"
             ),
-            icon="ops.view3d.ruler",  # XXX, needs own icon.
-            keymap=(),
+            icon="ops.paint.weight_sample",  # XXX, needs own icon.
+            keymap="Image Editor Tool: Sample",
+            draw_settings=draw_settings,
         )
 
 
@@ -1426,7 +1430,7 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel):
             # for all modes
         ],
         'VIEW': [
-            _defs_image_generic.measure,
+            _defs_image_generic.sample,
             *_tools_annotate,
         ],
         'UV': [
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index b1dd04b862b..2757fc4e827 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -65,6 +65,7 @@
 #include "DEG_depsgraph.h"
 
 #include "GPU_draw.h"
+#include "GPU_immediate.h"
 
 #include "IMB_colormanagement.h"
 #include "IMB_imbuf.h"
@@ -2873,6 +2874,9 @@ typedef struct ImageSampleInfo {
 	int x, y;
 	int channels;
 
+	int width, height;
+	int sample_radius;
+
 	unsigned char col[4];
 	float colf[4];
 	float linearcol[4];
@@ -2892,11 +2896,44 @@ typedef struct ImageSampleInfo {
 static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
 {
 	ImageSampleInfo *info = arg_info;
-	if (info->draw) {
-		Scene *scene = CTX_data_scene(C);
+	if (!info->draw) {
+		return;
+	}
+
+	Scene *scene = CTX_data_scene(C);
+	ED_image_draw_info(
+	        scene, ar, info->color_manage, info->use_default_view, info->channels,
+	        info->x, info->y, info->colp, info->colfp, info->linearcol, info->zp, info->zfp);
+
+	if (info->sample_radius) {
+		const wmWindow *win = CTX_wm_window(C);
+		const wmEvent *event = win->eventstate;
 
-		ED_image_draw_info(scene, ar, info->color_manage, info->use_default_view, info->channels,
-		                   info->x, info->y, info->colp, info->colfp, info->linearcol, info->zp, info->zfp);
+		SpaceImage *sima = CTX_wm_space_image(C);
+		GPUVertFormat *format = immVertexFormat();
+		uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+		const float color[3] = {1, 1, 1};
+		immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+		immUniformColor3fv(color);
+
+		rctf sample_rect_fl;
+		BLI_rctf_init_pt_radius(
+		        &sample_rect_fl,
+		        (float[2]){event->x - ar->winrct.xmin, event->y - ar->winrct.ymin},
+		        info->sample_radius * sima->zoom);
+
+		glEnable(GL_COLOR_LOGIC_OP);
+		glLogicOp(GL_XOR);
+		imm_draw_box_wire_2d(
+		        pos,
+		        (float)sample_rect_fl.xmin,
+		        (float)sample_rect_fl.ymin,
+		        (float)sample_rect_fl.xmax,
+		        (float)sample_rect_fl.ymax);
+		glDisable(GL_COLOR_LOGIC_OP);
+
+		immUnbindProgram();
 	}
 }
 
@@ -2940,6 +2977,85 @@ bool ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], flo
 	return ret;
 }
 
+
+/* -------------------------------------------------------------------- */
+/** \name Image Pixel Sample
+ * \{ */
+
+static void image_sample_pixel_color_ubyte(
+        const ImBuf *ibuf, const int coord[2],
+        uchar r_col[4], float r_col_linear[4])
+{
+	const uchar *cp = (unsigned char *)(ibuf->rect + coord[1] * ibuf->x + coord[0]);
+	copy_v4_v4_uchar(r_col, cp);
+	rgba_uchar_to_float(r_col_linear, r_col);
+	IMB_colormanagement_colorspace_to_scene_linear_v4(r_col_linear, false, ibuf->rect_colorspace);
+}
+
+static void image_sample_pixel_color_float(
+        ImBuf *ibuf, const int coord[2],
+        float r_col[4])
+{
+	const float *cp = ibuf->rect_float + (ibuf->channels) * (coord[1] * ibuf->x + coord[0]);
+	copy_v4_v4(r_col, cp);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Image Pixel Region Sample
+ * \{ */
+
+static void image_sample_rect_color_ubyte(
+        const ImBuf *ibuf, const rcti *rect,
+        uchar r_col[4], float r_col_linear[4])
+{
+	uint col_accum_ub[4];
+	zero_v4(r_col_linear);
+	int col_tot = 0;
+	int coord[2];
+	for (coord[0] = rect->xmin; coord[0] <= rect->xmax; coord[0]++) {
+		for (coord[1] = rect->ymin; coord[1] <= rect->ymax; coord[1]++) {
+			float col_temp_fl[4];
+			uchar col_temp_ub[4];
+			image_sample_pixel_color_ubyte(ibuf, coord, col_temp_ub, col_temp_fl);
+			add_v4_v4(r_col_linear, col_temp_fl);
+			col_accum_ub[0] += (uint)col_temp_ub[0];
+			col_accum_ub[1] += (uint)col_temp_ub[1];
+			col_accum_ub[2] += (uint)col_temp_ub[2];
+			col_accum_ub[3] += (uint)col_temp_ub[3];
+			col_tot += 1;
+		}
+	}
+	mul_v4_fl(r_col_linear, 1.0 / (float)col_tot);
+
+	r_col[0] = MIN2(col_accum_ub[0] / col_tot, 255);
+	r_col[1] = MIN2(col_accum_ub[1] / col_tot, 255);
+	r_col[2] = MIN2(col_accum_ub[2] / col_tot, 255);
+	r_col[3] = MIN2(col_accum_ub[3] / col_tot, 255);
+}
+
+
+static void image_sample_rect_color_float(
+        ImBuf *ibuf, const rcti *rect,
+        float r_col[4])
+{
+	zero_v4(r_col);
+	int col_tot = 0;
+	int coord[2];
+	for (coord[0] = rect->xmin; coord[0] <= rect->xmax; coord[0]++) {
+		for (coord[1] = rect->ymin; coord[1] <= rect->ymax; coord[1]++) {
+			float col_temp_fl[4];
+			image_sample_pixel_color_float(ibuf, coord, col_temp_fl);
+			add_v4_v4(r_col, col_temp_fl);
+			col_tot += 1;
+		}
+	}
+	mul_v4_fl(r_col, 1.0 / (float)col_tot);
+}
+
+/** \} */
+
 static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
 {
 	SpaceImage *sima = CTX_wm_space_image(C);
@@ -2960,16 +3076,17 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
 	UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fx, &fy);
 
 	if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
-		const float *fp;
-		unsigned char *cp;
 		int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
 		Image *image = ED_space_image(sima);
 
 		CLAMP(x, 0, ibuf->x - 1);
 		CLAMP(y, 0, ibuf->y - 1);
 
+		info->width = ibuf->x;
+		info->height = ibuf->y;
 		info->x = x;
 		info->y = y;
+
 		info->draw = true;
 		info->channels = ibuf->channels;
 
@@ -2980,45 +3097,32 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
 
 		info->use_default_view = (image->flag & IMA_VIEW_AS_RENDER) ? false : true;
 
+		rcti sample_rect;
+		BLI_rcti_init_pt_radius(&sample_rect, (int[2]){x, y}, info->sample_radius);
+		BLI_rcti_isect(
+		        &(rcti){ .xmin = 0, .ymin = 0, .xmax = ibuf->x - 1, .ymax = ibuf->y - 1},
+		        &sample_rect, &sample_rect);
+
 		if (ibuf->rect) {
-			cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
+			image_sample_rect_color_ubyte(ibuf, &sample_rect, info->col, info->linearcol);
+			rgba_uchar_to_float(info->colf, info->col);
 
-			info->col[0] = cp[0];
-			info->col[1] = cp[1];
-			info->col[2] = cp[2];
-			info->col[3] = cp[3];
 			info->colp = info->col;
-
-			info->colf[0] = (float)cp[0] / 255.0f;
-			info->colf[1] = (float)cp[1] / 255.0f;
-			info->colf[2] = (float)cp[2] / 255.0f;
-			info->colf[3] = (float)cp[3] / 255.0f;
 			info->colfp = info->colf;
-
-			copy_v4_v4(info->linearcol, info->colf);
-			IMB_colormanagement_colorspace_to_scene_linear_v4(info->linearcol, false, ibuf->rect_colorspace);
-
 			info->color_manage = true;
 		}
 		if (ibuf->rect_float) {
-			fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
+			image_sample_rect_color_float(ibuf, &sample_rect, info->colf);
 
 			if (ibuf->channels == 4) {
-				info->colf[0] = fp[0];
-				info->colf[1] = fp[1];
-				info->colf[2] = fp[2];
-				info->colf[3] = fp[3];
+				/* pass */
 			}
 			else if (ibuf->channels == 3) {
-				info->colf[0] = fp[0];
-				info->colf[1] = fp[1];
-				info->colf[2] = fp[2];
 				info->colf[3] = 1.0f;
 			}
 			else {
-				info->colf[0] = fp[0];
-				info->colf[1] = fp[0];
-				info->colf[2] = fp[0];
+				info->colf[1] = info->colf[0];
+				info->colf[2] = info->colf[0];
 				info->colf[3] = 1.0f;
 			}
 			info->colfp = info->colf;
@@ -3029,6 +3133,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
 		}
 
 		if (ibuf->zbuf) {
+			/* TODO, blend depth (not urgent). */
 			info->z = ibuf->zb

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list