support fro HDR color picking (values over 1.0) when color picking in the image edito...
authorCampbell Barton <ideasman42@gmail.com>
Thu, 16 Aug 2012 14:47:14 +0000 (14:47 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 16 Aug 2012 14:47:14 +0000 (14:47 +0000)
source/blender/editors/include/ED_image.h
source/blender/editors/include/ED_node.h
source/blender/editors/interface/interface_ops.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_node/node_view.c

index d291c500547609cd25e65ac790ea68ce11aa37ca..6f41bef81f45e2dc67023aa93a2f98e72b7e6ace 100644 (file)
@@ -46,6 +46,7 @@ void          ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, s
 struct Mask  *ED_space_image_get_mask(struct SpaceImage *sima);
 void          ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask);
 
+int ED_space_image_color_sample(struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]);
 struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r);
 void ED_space_image_release_buffer(struct SpaceImage *sima, void *lock);
 int ED_space_image_has_buffer(struct SpaceImage *sima);
index b6a1fd0f979d851fd8cbc783be738247367c3a18..32baa8883e16f7d3050ebbb98e6bd007cd7887ea 100644 (file)
@@ -76,8 +76,11 @@ void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNod
 
 void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, struct Scene *scene_owner);
 
-/* node ops.c */
+/* node_ops.c */
 void ED_operatormacros_node(void);
 
+/* node_view.c */
+int ED_space_node_color_sample(struct SpaceNode *snode, struct ARegion *ar, int mval[2], float r_col[3]);
+
 #endif /* __ED_NODE_H__ */
 
index b76907bc3ba7a9ad8aa4563831460b4ecac4d9bc..b3b48cb3a461bb9c01672dc4207f0c6ef6979551 100644 (file)
@@ -69,6 +69,8 @@
 #include "BKE_main.h"
 #include "BLI_ghash.h"
 
+#include "ED_image.h"  /* for HDR color sampling */
+#include "ED_node.h"   /* for HDR color sampling */
 
 /* ********************************************************** */
 
@@ -126,9 +128,47 @@ static int eyedropper_cancel(bContext *C, wmOperator *op)
 
 /* *** eyedropper_color_ helper functions *** */
 
-/* simply get the color from the screen */
-static void eyedropper_color_sample_fl(Eyedropper *UNUSED(eye), int mx, int my, float r_col[3])
+/**
+ * \brief get the color from the screen.
+ *
+ * Special check for image or nodes where we MAY have HDR pixels which don't display.
+ */
+static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int mx, int my, float r_col[3])
 {
+
+       /* we could use some clever */
+       wmWindow *win = CTX_wm_window(C);
+       ScrArea *sa;
+       for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+               if (BLI_in_rcti(&sa->totrct, mx, my)) {
+                       if (sa->spacetype == SPACE_IMAGE) {
+                               ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+                               if (BLI_in_rcti(&ar->winrct, mx, my)) {
+                                       SpaceImage *sima = sa->spacedata.first;
+                                       int mval[2] = {mx - ar->winrct.xmin,
+                                                      my - ar->winrct.ymin};
+
+                                       if (ED_space_image_color_sample(sima, ar, mval, r_col)) {
+                                               return;
+                                       }
+                               }
+                       }
+                       else if (sa->spacetype == SPACE_NODE) {
+                               ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+                               if (BLI_in_rcti(&ar->winrct, mx, my)) {
+                                       SpaceNode *snode = sa->spacedata.first;
+                                       int mval[2] = {mx - ar->winrct.xmin,
+                                                      my - ar->winrct.ymin};
+
+                                       if (ED_space_node_color_sample(snode, ar, mval, r_col)) {
+                                               return;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /* fallback to simple opengl picker */
        glReadBuffer(GL_FRONT);
        glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col);
        glReadBuffer(GL_BACK);
@@ -167,14 +207,14 @@ static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye)
 static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my)
 {
        float col[3];
-       eyedropper_color_sample_fl(eye, mx, my, col);
+       eyedropper_color_sample_fl(C, eye, mx, my, col);
        eyedropper_color_set(C, eye, col);
 }
 
-static void eyedropper_color_sample_accum(Eyedropper *eye, int mx, int my)
+static void eyedropper_color_sample_accum(bContext *C, Eyedropper *eye, int mx, int my)
 {
        float col[3];
-       eyedropper_color_sample_fl(eye, mx, my, col);
+       eyedropper_color_sample_fl(C, eye, mx, my, col);
        /* delay linear conversion */
        add_v3_v3(eye->accum_col, col);
        eye->accum_tot++;
@@ -203,13 +243,13 @@ static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event)
                        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);
+                               eyedropper_color_sample_accum(C, 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_sample_accum(C, eye, event->x, event->y);
                                eyedropper_color_set_accum(C, eye);
                        }
                        break;
@@ -217,7 +257,7 @@ static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event)
                        if (event->val == KM_RELEASE) {
                                eye->accum_tot = 0;
                                zero_v3(eye->accum_col);
-                               eyedropper_color_sample_accum(eye, event->x, event->y);
+                               eyedropper_color_sample_accum(C, eye, event->x, event->y);
                                eyedropper_color_set_accum(C, eye);
                        }
                        break;
index b2a9584b243a7d02dcc9b53027cc77e2f64c82b3..30480bd095f879f9d0c3e61f654f6c127480b771 100644 (file)
@@ -1948,6 +1948,54 @@ static void image_sample_draw(const bContext *UNUSED(C), ARegion *ar, void *arg_
        }
 }
 
+/* returns color in SRGB */
+/* matching ED_space_node_color_sample() */
+int ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], float r_col[3])
+{
+       void *lock;
+       ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
+       float fx, fy;
+       int ret = FALSE;
+
+       if (ibuf == NULL) {
+               ED_space_image_release_buffer(sima, lock);
+               return FALSE;
+       }
+
+       UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &fx, &fy);
+
+       if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
+               float *fp;
+               unsigned char *cp;
+               int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
+
+               CLAMP(x, 0, ibuf->x - 1);
+               CLAMP(y, 0, ibuf->y - 1);
+
+               if (ibuf->rect_float) {
+                       fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
+
+                       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
+                               linearrgb_to_srgb_v3_v3(r_col, fp);
+                       }
+                       else {
+                               copy_v3_v3(r_col, fp);
+                       }
+                       ret = TRUE;
+               }
+               else if (ibuf->rect) {
+                       cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
+                       r_col[0] = cp[0] / 255.0f;
+                       r_col[1] = cp[1] / 255.0f;
+                       r_col[2] = cp[2] / 255.0f;
+                       ret = TRUE;
+               }
+       }
+
+       ED_space_image_release_buffer(sima, lock);
+       return ret;
+}
+
 static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
 {
        SpaceImage *sima = CTX_wm_space_image(C);
index 4be51a0213798835807dcb52c4a147038191f2c0..e0cbbd697d74e4306cadd7787e21da264f1962a5 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "BLI_rect.h"
 #include "BLI_utildefines.h"
+#include "BLI_math.h"
 
 #include "BKE_context.h"
 #include "BKE_image.h"
@@ -350,6 +351,61 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
        }
 }
 
+/* returns color in SRGB */
+/* matching ED_space_image_color_sample() */
+int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float r_col[3])
+{
+       void *lock;
+       Image *ima;
+       ImBuf *ibuf;
+       float fx, fy, bufx, bufy;
+       int ret = FALSE;
+
+       ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+       ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+       if (!ibuf) {
+               return FALSE;
+       }
+
+       /* map the mouse coords to the backdrop image space */
+       bufx = ibuf->x * snode->zoom;
+       bufy = ibuf->y * snode->zoom;
+       fx = (bufx > 0.0f ? ((float)mval[0] - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f);
+       fy = (bufy > 0.0f ? ((float)mval[1] - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f);
+
+       if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) {
+               float *fp;
+               char *cp;
+               int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y);
+
+               CLAMP(x, 0, ibuf->x - 1);
+               CLAMP(y, 0, ibuf->y - 1);
+
+               if (ibuf->rect_float) {
+                       fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
+
+                       if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
+                               linearrgb_to_srgb_v3_v3(r_col, fp);
+                       }
+                       else {
+                               copy_v3_v3(r_col, fp);
+                       }
+                       ret = TRUE;
+               }
+               else if (ibuf->rect) {
+                       cp = (char *)(ibuf->rect + y * ibuf->x + x);
+                       r_col[0] = cp[0] / 255.0f;
+                       r_col[1] = cp[1] / 255.0f;
+                       r_col[2] = cp[2] / 255.0f;
+                       ret = TRUE;
+               }
+       }
+
+       BKE_image_release_ibuf(ima, lock);
+
+       return ret;
+}
+
 static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
 {
        SpaceNode *snode = CTX_wm_space_node(C);