From d2225edfce87ecb92d19b56859146a0738027c7e Mon Sep 17 00:00:00 2001 From: Robert Holcomb Date: Tue, 23 Mar 2010 01:22:33 +0000 Subject: Added a line sampler to the histogram panel in the image space. Patch #21712 from Xavier Thomas. now updates in real time as you pull the line. --- source/blender/editors/space_image/image_draw.c | 11 ++ source/blender/editors/space_image/image_intern.h | 2 + source/blender/editors/space_image/image_ops.c | 162 +++++++++++++++++++++- source/blender/editors/space_image/space_image.c | 1 + 4 files changed, 175 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 797bb20ddf9..0baa81fc699 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -158,6 +158,17 @@ void draw_image_info(ARegion *ar, int channels, int x, int y, char *cp, float *f UI_DrawString(10, 10, str); } +void draw_image_line(struct ARegion *ar, int x1, int y1, int x2, int y2) +{ + glColor3ub(0,0,0); + glBegin(GL_LINES); + + glVertex2i(x1, y1); + glVertex2i(x2, y2); + + glEnd(); +} + /* image drawing */ static void draw_image_grid(ARegion *ar, float zoomx, float zoomy) diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 09bd9edc86d..8c8a8f76710 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -55,6 +55,7 @@ void IMAGE_OT_toolbox(struct wmOperatorType *ot); void draw_image_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene); void draw_image_info(struct ARegion *ar, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf); void draw_image_grease_pencil(struct bContext *C, short onlyv2d); +void draw_image_line(struct ARegion *ar, int x1, int y1, int x2, int y2); /* image_ops.c */ int space_image_main_area_poll(struct bContext *C); @@ -80,6 +81,7 @@ void IMAGE_OT_unpack(struct wmOperatorType *ot); void IMAGE_OT_cycle_render_slot(struct wmOperatorType *ot); void IMAGE_OT_sample(struct wmOperatorType *ot); +void IMAGE_OT_sample_line(struct wmOperatorType *ot); void IMAGE_OT_curves_point_set(struct wmOperatorType *ot); void IMAGE_OT_record_composite(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 3aa766c32d0..386259278df 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -20,7 +20,7 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * Contributor(s): Blender Foundation, 2002-2009 + * Contributor(s): Blender Foundation, 2002-2009, Xavier Thomas * * ***** END GPL LICENSE BLOCK ***** */ @@ -1641,6 +1641,166 @@ void IMAGE_OT_sample(wmOperatorType *ot) ot->flag= OPTYPE_BLOCKING; } +/******************** sample line operator ********************/ +typedef struct ImageSampleLineInfo { + ARegionType *art; + void *draw_handle; + int started; + int x_start, y_start, x_stop, y_stop; +} ImageSampleLineInfo; + +static void sample_line_draw(const bContext *C, ARegion *ar, void *arg_info) +{ + ImageSampleLineInfo *info= arg_info; + draw_image_line(ar, info->x_start, info->y_start, info->x_stop, info->y_stop); +} + +static void sample_line_apply(bContext *C, wmOperator *op) +{ + SpaceImage *sima= CTX_wm_space_image(C); + ImageSampleLineInfo *info= op->customdata; + ARegion *ar= CTX_wm_region(C); + void *lock; + ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock); + Histogram *hist= &sima->sample_line_hist; + float x1f, y1f, x2f, y2f; + int x1, y1, x2, y2; + int i, x, y; + float *fp; + unsigned char *cp; + + if (ibuf == NULL) { + ED_space_image_release_buffer(sima, lock); + return; + } + /* hmmmm */ + if (ibuf->channels < 3) { + ED_space_image_release_buffer(sima, lock); + return; + } + + UI_view2d_region_to_view(&ar->v2d, info->x_start, info->y_start, &x1f, &y1f); + UI_view2d_region_to_view(&ar->v2d, info->x_stop, info->y_stop, &x2f, &y2f); + x1= 0.5f+ x1f*ibuf->x; + x2= 0.5f+ x2f*ibuf->x; + y1= 0.5f+ y1f*ibuf->y; + y2= 0.5f+ y2f*ibuf->y; + + hist->channels = 3; + hist->x_resolution = 256; + hist->xmax = 1.0f; + hist->ymax = 1.0f; + + for (i=0; i<256; i++) { + x= (int)(0.5f + x1 + (float)i*(x2-x1)/255.0f); + y= (int)(0.5f + y1 + (float)i*(y2-y1)/255.0f); + + if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) { + hist->data_r[i] = hist->data_g[i]= hist->data_b[i] = 0.0f; + } else { + if (ibuf->rect_float) { + fp= (ibuf->rect_float + (ibuf->channels)*(y*ibuf->x + x)); + hist->data_r[i] = fp[0]; + hist->data_g[i] = fp[1]; + hist->data_b[i] = fp[2]; + } + else if (ibuf->rect) { + cp= (unsigned char *)(ibuf->rect + y*ibuf->x + x); + hist->data_r[i] = (float)cp[0]/255.0f; + hist->data_g[i] = (float)cp[1]/255.0f; + hist->data_b[i] = (float)cp[2]/255.0f; + } + } + } + hist->ok=1; + + ED_space_image_release_buffer(sima, lock); +} + +static void sample_line_exit(bContext *C, wmOperator *op) +{ + ImageSampleLineInfo *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 sample_line_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceImage *sima= CTX_wm_space_image(C); + ImageSampleLineInfo *info; + + if(!ED_space_image_has_buffer(sima)) + return OPERATOR_CANCELLED; + + info= MEM_callocN(sizeof(ImageSampleLineInfo), "ImageSampleLineInfo"); + info->started= 0; + op->customdata= info; + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int sample_line_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + ImageSampleLineInfo *info= op->customdata; + ARegion *ar= CTX_wm_region(C); + + switch(event->type) { + case LEFTMOUSE: + if (info->started == 0) { + info->x_start = event->mval[0]; + info->y_start = event->mval[1]; + info->art= ar->type; + info->draw_handle = ED_region_draw_cb_activate(ar->type, sample_line_draw, info, REGION_DRAW_POST_PIXEL); + info->started = 1; + } else { + sample_line_apply(C, op); + sample_line_exit(C, op); + return OPERATOR_FINISHED; + } + break; + case RIGHTMOUSE: // XXX hardcoded + case ESCKEY: + sample_line_exit(C, op); + return OPERATOR_CANCELLED; + case MOUSEMOVE: + if (info->started == 1) { + info->x_stop = event->mval[0]; + info->y_stop = event->mval[1]; + ED_area_tag_redraw(CTX_wm_area(C)); + sample_line_apply(C, op); + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +static int sample_line_cancel(bContext *C, wmOperator *op) +{ + sample_line_exit(C, op); + return OPERATOR_CANCELLED; +} + +void IMAGE_OT_sample_line(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Sample Line"; + ot->idname= "IMAGE_OT_sample_line"; + + /* api callbacks */ + ot->invoke= sample_line_invoke; + ot->modal= sample_line_modal; + ot->cancel= sample_line_cancel; + ot->poll= space_image_main_area_poll; + + /* flags */ + ot->flag= OPTYPE_BLOCKING; +} + /******************** set curve point operator ********************/ void IMAGE_OT_curves_point_set(wmOperatorType *ot) diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 3d4d81c836b..8d2e54e0fca 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -475,6 +475,7 @@ void image_operatortypes(void) WM_operatortype_append(IMAGE_OT_cycle_render_slot); WM_operatortype_append(IMAGE_OT_sample); + WM_operatortype_append(IMAGE_OT_sample_line); WM_operatortype_append(IMAGE_OT_curves_point_set); WM_operatortype_append(IMAGE_OT_record_composite); -- cgit v1.2.3