diff options
author | Richard Antalik <richardantalik@gmail.com> | 2020-04-13 00:56:03 +0300 |
---|---|---|
committer | Richard Antalik <richardantalik@gmail.com> | 2020-04-13 00:56:03 +0300 |
commit | c456671b53695e4ae7bc4871cb48835f4a7f1d3b (patch) | |
tree | fa86e755532f014c6cb673dc8dbaaad556d0cf69 /source/blender/editors/space_image | |
parent | 0c9e47705d287dc7ce976059b7eb0e7b463b2b42 (diff) |
Refactor sample operator
Move sample operator functions to `ed_util_imbuf.c` and change common functions,
so they can be used in image editor and sequencer.
Reviewed By: campbellbarton
Differential Revision: https://developer.blender.org/D7315
Diffstat (limited to 'source/blender/editors/space_image')
-rw-r--r-- | source/blender/editors/space_image/image_ops.c | 389 |
1 files changed, 8 insertions, 381 deletions
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 14245327bdd..992727e3b11 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -91,6 +91,7 @@ #include "ED_screen.h" #include "ED_space_api.h" #include "ED_util.h" +#include "ED_util_imbuf.h" #include "ED_uvedit.h" #include "UI_interface.h" @@ -277,28 +278,6 @@ static bool space_image_main_area_not_uv_brush_poll(bContext *C) return 0; } -static bool image_sample_poll(bContext *C) -{ - SpaceImage *sima = CTX_wm_space_image(C); - if (sima == NULL) { - return false; - } - - Object *obedit = CTX_data_edit_object(C); - if (obedit) { - /* Disable when UV editing so it doesn't swallow all click events - * (use for setting cursor). */ - if (ED_space_image_show_uvedit(sima, obedit)) { - return false; - } - } - else if (sima->mode != SI_MODE_VIEW) { - return false; - } - - return true; -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -3099,85 +3078,6 @@ void IMAGE_OT_unpack(wmOperatorType *ot) /** \name Sample Image Operator * \{ */ -typedef struct ImageSampleInfo { - ARegionType *art; - void *draw_handle; - int x, y; - int channels; - - int width, height; - int sample_size; - - uchar col[4]; - float colf[4]; - float linearcol[4]; - int z; - float zf; - - uchar *colp; - const float *colfp; - int *zp; - float *zfp; - - bool draw; - bool color_manage; - int use_default_view; -} ImageSampleInfo; - -static void image_sample_draw(const bContext *C, ARegion *region, void *arg_info) -{ - ImageSampleInfo *info = arg_info; - if (!info->draw) { - return; - } - - Scene *scene = CTX_data_scene(C); - ED_image_draw_info(scene, - region, - 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_size > 1) { - const wmWindow *win = CTX_wm_window(C); - const wmEvent *event = win->eventstate; - - 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); - - /* TODO(campbell): lock to pixels. */ - rctf sample_rect_fl; - BLI_rctf_init_pt_radius( - &sample_rect_fl, - (float[2]){event->x - region->winrct.xmin, event->y - region->winrct.ymin}, - (float)(info->sample_size / 2.0f) * sima->zoom); - - glEnable(GL_COLOR_LOGIC_OP); - glLogicOp(GL_XOR); - GPU_line_width(1.0f); - 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(); - } -} - /* Returns color in linear space, matching ED_space_node_color_sample(). */ bool ED_space_image_color_sample(SpaceImage *sima, ARegion *region, int mval[2], float r_col[3]) { @@ -3222,279 +3122,6 @@ bool ED_space_image_color_sample(SpaceImage *sima, ARegion *region, int mval[2], 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 = (uchar *)(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] = {0, 0, 0, 0}; - 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); - ARegion *region = CTX_wm_region(C); - Image *image = ED_space_image(sima); - - float uv[2]; - UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &uv[0], &uv[1]); - int tile = BKE_image_get_tile_from_pos(sima->image, uv, uv, NULL); - - void *lock; - ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock, tile); - ImageSampleInfo *info = op->customdata; - Scene *scene = CTX_data_scene(C); - CurveMapping *curve_mapping = scene->view_settings.curve_mapping; - - if (ibuf == NULL) { - ED_space_image_release_buffer(sima, ibuf, lock); - info->draw = false; - return; - } - - if (uv[0] >= 0.0f && uv[1] >= 0.0f && uv[0] < 1.0f && uv[1] < 1.0f) { - int x = (int)(uv[0] * ibuf->x), y = (int)(uv[1] * ibuf->y); - - 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; - - info->colp = NULL; - info->colfp = NULL; - info->zp = NULL; - info->zfp = NULL; - - info->use_default_view = (image->flag & IMA_VIEW_AS_RENDER) ? false : true; - - rcti sample_rect; - sample_rect.xmin = max_ii(0, x - info->sample_size / 2); - sample_rect.ymin = max_ii(0, y - info->sample_size / 2); - sample_rect.xmax = min_ii(ibuf->x, sample_rect.xmin + info->sample_size) - 1; - sample_rect.ymax = min_ii(ibuf->y, sample_rect.ymin + info->sample_size) - 1; - - if (ibuf->rect) { - image_sample_rect_color_ubyte(ibuf, &sample_rect, info->col, info->linearcol); - rgba_uchar_to_float(info->colf, info->col); - - info->colp = info->col; - info->colfp = info->colf; - info->color_manage = true; - } - if (ibuf->rect_float) { - image_sample_rect_color_float(ibuf, &sample_rect, info->colf); - - if (ibuf->channels == 4) { - /* pass */ - } - else if (ibuf->channels == 3) { - info->colf[3] = 1.0f; - } - else { - info->colf[1] = info->colf[0]; - info->colf[2] = info->colf[0]; - info->colf[3] = 1.0f; - } - info->colfp = info->colf; - - copy_v4_v4(info->linearcol, info->colf); - - info->color_manage = true; - } - - if (ibuf->zbuf) { - /* TODO, blend depth (not urgent). */ - info->z = ibuf->zbuf[y * ibuf->x + x]; - info->zp = &info->z; - if (ibuf->zbuf == (int *)ibuf->rect) { - info->colp = NULL; - } - } - if (ibuf->zbuf_float) { - /* TODO, blend depth (not urgent). */ - info->zf = ibuf->zbuf_float[y * ibuf->x + x]; - info->zfp = &info->zf; - if (ibuf->zbuf_float == ibuf->rect_float) { - info->colfp = NULL; - } - } - - if (curve_mapping && ibuf->channels == 4) { - /* we reuse this callback for set curves point operators */ - if (RNA_struct_find_property(op->ptr, "point")) { - int point = RNA_enum_get(op->ptr, "point"); - - if (point == 1) { - BKE_curvemapping_set_black_white(curve_mapping, NULL, info->linearcol); - } - else if (point == 0) { - BKE_curvemapping_set_black_white(curve_mapping, info->linearcol, NULL); - } - WM_event_add_notifier(C, NC_WINDOW, NULL); - } - } - - // XXX node curve integration .. -#if 0 - { - ScrArea *area, *cur = curarea; - - node_curvemap_sample(fp); /* sends global to node editor */ - for (area = G.curscreen->areabase.first; area; area = area->next) { - if (area->spacetype == SPACE_NODE) { - areawinset(area->win); - scrarea_do_windraw(area); - } - } - node_curvemap_sample(NULL); /* clears global in node editor */ - curarea = cur; - } -#endif - } - else { - info->draw = 0; - } - - ED_space_image_release_buffer(sima, ibuf, lock); - ED_area_tag_redraw(CTX_wm_area(C)); -} - -static void image_sample_exit(bContext *C, wmOperator *op) -{ - ImageSampleInfo *info = op->customdata; - - ED_region_draw_cb_exit(info->art, info->draw_handle); - ED_area_tag_redraw(CTX_wm_area(C)); - MEM_freeN(info); -} - -static int image_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - SpaceImage *sima = CTX_wm_space_image(C); - ARegion *region = CTX_wm_region(C); - ImageSampleInfo *info; - - if (region->regiontype == RGN_TYPE_WINDOW) { - if (event->mval[1] <= 16 && ED_space_image_show_cache(sima)) { - return OPERATOR_PASS_THROUGH; - } - } - - if (!ED_space_image_has_buffer(sima)) { - return OPERATOR_CANCELLED; - } - - info = MEM_callocN(sizeof(ImageSampleInfo), "ImageSampleInfo"); - - info->art = region->type; - info->draw_handle = ED_region_draw_cb_activate( - region->type, image_sample_draw, info, REGION_DRAW_POST_PIXEL); - info->sample_size = RNA_int_get(op->ptr, "size"); - op->customdata = info; - - image_sample_apply(C, op, event); - - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int image_sample_modal(bContext *C, wmOperator *op, const wmEvent *event) -{ - switch (event->type) { - case LEFTMOUSE: - case RIGHTMOUSE: // XXX hardcoded - if (event->val == KM_RELEASE) { - image_sample_exit(C, op); - return OPERATOR_CANCELLED; - } - break; - case MOUSEMOVE: - image_sample_apply(C, op, event); - break; - } - - return OPERATOR_RUNNING_MODAL; -} - -static void image_sample_cancel(bContext *C, wmOperator *op) -{ - image_sample_exit(C, op); -} - void IMAGE_OT_sample(wmOperatorType *ot) { /* identifiers */ @@ -3503,10 +3130,10 @@ void IMAGE_OT_sample(wmOperatorType *ot) ot->description = "Use mouse to sample a color in current image"; /* api callbacks */ - ot->invoke = image_sample_invoke; - ot->modal = image_sample_modal; - ot->cancel = image_sample_cancel; - ot->poll = image_sample_poll; + ot->invoke = ED_imbuf_sample_invoke; + ot->modal = ED_imbuf_sample_modal; + ot->cancel = ED_imbuf_sample_cancel; + ot->poll = ED_imbuf_sample_poll; /* flags */ ot->flag = OPTYPE_BLOCKING; @@ -3632,9 +3259,9 @@ void IMAGE_OT_curves_point_set(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* api callbacks */ - ot->invoke = image_sample_invoke; - ot->modal = image_sample_modal; - ot->cancel = image_sample_cancel; + ot->invoke = ED_imbuf_sample_invoke; + ot->modal = ED_imbuf_sample_modal; + ot->cancel = ED_imbuf_sample_cancel; ot->poll = space_image_main_area_not_uv_brush_poll; /* properties */ |