Orange: and now for the real exr fun: float buffer support in Image window!
authorTon Roosendaal <ton@blender.org>
Mon, 9 Jan 2006 23:52:51 +0000 (23:52 +0000)
committerTon Roosendaal <ton@blender.org>
Mon, 9 Jan 2006 23:52:51 +0000 (23:52 +0000)
Image as loaded in Blender (from openexr.com):
http://www.blender.org/bf/exrcurve1.jpg

Image with different white point:
http://www.blender.org/bf/exrcurve2.jpg

Image with white and black point and a curve:
http://www.blender.org/bf/exrcurve3.jpg

Use SHIFT+click to set the black point, and CTRL+click for white point.
The buttons in the panel work too, of course.

The curves work after the black/white range was corrected, so you can
stick to curves with a normal 0-1 range.
There's also now a general color curve, marked with 'C' button.

Note; this currently only maps the float colors to a visible 8 bits per
channel rect. You can save it, but when the blender file loads the curve
or mapping is not executed until you click in the curves... have to look
at that still.
Speed for this is also quite unoptimized... still WIP, but fun!

14 files changed:
source/blender/blenkernel/BKE_colortools.h
source/blender/blenkernel/intern/colortools.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/BIF_editsima.h
source/blender/include/BIF_space.h
source/blender/include/blendef.h
source/blender/makesdna/DNA_color_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/src/butspace.c
source/blender/src/drawimage.c
source/blender/src/editsima.c
source/blender/src/header_image.c
source/blender/src/space.c

index 7521a9351186b9b38f4192e4f6057bedc50cabba..22faa244fcef9846dde4cbb1a0c3a1fa13d7d961 100644 (file)
 
 struct CurveMapping;
 struct CurveMap;
+struct Image;
 struct rctf;
  
 struct CurveMapping    *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
 void                           curvemapping_free(struct CurveMapping *cumap);
 struct CurveMapping    *curvemapping_copy(struct CurveMapping *cumap);
+void                           curvemapping_set_black_white(struct CurveMapping *cumap, float *black, float *white);
 
 void                           curvemap_remove(struct CurveMap *cuma, int flag);
 void                           curvemap_insert(struct CurveMap *cuma, float x, float y);
@@ -45,6 +47,7 @@ void                          curvemap_sethandle(struct CurveMap *cuma, int type);
 void                           curvemapping_changed(struct CurveMapping *cumap, int rem_doubles);
 float                          curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value);
 void                           curvemapping_evaluate3F(struct CurveMapping *cumap, float *vecout, const float *vecin);
+void                           curvemapping_do_image(struct CurveMapping *cumap, struct Image *ima);
 
 #endif
 
index 0ce9bfc9ee9c3da8294ed8e340a2a56b31af6628..85ef8f2b927a6256b35264f6acb597f13f1e1876 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "DNA_color_types.h"
 #include "DNA_curve_types.h"
+#include "DNA_image_types.h"
 #include "DNA_texture_types.h"
 
 #include "BKE_colortools.h"
@@ -48,6 +49,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 
+#include "IMB_imbuf_types.h"
 
 /* ********************************* color curve ********************* */
 
@@ -60,10 +62,14 @@ CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, floa
        
        cumap= MEM_callocN(sizeof(CurveMapping), "new curvemap");
        cumap->flag= CUMA_DO_CLIP;
+       if(tot==4) cumap->cur= 3;               /* rhms, hack for 'col' curve? */
        
        BLI_init_rctf(&cumap->curr, minx, maxx, miny, maxy);
        cumap->clipr= cumap->curr;
        
+       cumap->white[0]= cumap->white[1]= cumap->white[2]= 1.0f;
+       cumap->bwmul[0]= cumap->bwmul[1]= cumap->bwmul[2]= 1.0f;
+       
        for(a=0; a<tot; a++) {
                cumap->cm[a].totpoint= 2;
                cumap->cm[a].curve= MEM_callocN(2*sizeof(CurveMapPoint), "curve points");
@@ -106,6 +112,23 @@ CurveMapping *curvemapping_copy(CurveMapping *cumap)
        return NULL;
 }
 
+void curvemapping_set_black_white(CurveMapping *cumap, float *black, float *white)
+{
+       int a;
+       
+       if(white)
+               VECCOPY(cumap->white, white);
+       if(black)
+               VECCOPY(cumap->black, black);
+       
+       for(a=0; a<3; a++) {
+               if(cumap->white[a]==cumap->black[a])
+                       cumap->bwmul[a]= 0.0f;
+               else
+                       cumap->bwmul[a]= 1.0f/(cumap->white[a] - cumap->black[a]);
+       }       
+}
+
 /* ***************** operations on single curve ************* */
 /* ********** NOTE: requires curvemapping_changed() call after ******** */
 
@@ -461,9 +484,43 @@ float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value)
 
 void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *vecin)
 {
-       vecout[0]= curvemapping_evaluateF(cumap, 0, vecin[0]);
-       vecout[1]= curvemapping_evaluateF(cumap, 1, vecin[1]);
-       vecout[2]= curvemapping_evaluateF(cumap, 2, vecin[2]);
+       if(cumap->cm[3].curve) {
+               float fac;
+               
+               fac= (vecin[0] - cumap->black[0])*cumap->bwmul[0];
+               vecout[0]= curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, fac));
+               fac= (vecin[1] - cumap->black[0])*cumap->bwmul[1];
+               vecout[1]= curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, fac));
+               fac= (vecin[2] - cumap->black[0])*cumap->bwmul[2];
+               vecout[2]= curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, fac));
+       }
+       else {
+               vecout[0]= curvemapping_evaluateF(cumap, 0, vecin[0]);
+               vecout[1]= curvemapping_evaluateF(cumap, 1, vecin[1]);
+               vecout[2]= curvemapping_evaluateF(cumap, 2, vecin[2]);
+       }
 }
 
+#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
 
+void curvemapping_do_image(CurveMapping *cumap, Image *ima)
+{
+       int pixel;
+       
+       if(ima->ibuf==NULL)
+               return;
+       
+       if(ima->ibuf->rect_float && ima->ibuf->rect) {
+               float *pixf= ima->ibuf->rect_float;
+               float col[3];
+               char *pixc= (char *)ima->ibuf->rect;
+               
+               for(pixel= ima->ibuf->x*ima->ibuf->y; pixel>0; pixel--, pixf+=4, pixc+=4) {
+                       curvemapping_evaluate3F(cumap, col, pixf);
+                       pixc[0]= FTOCHAR(col[0]);
+                       pixc[1]= FTOCHAR(col[1]);
+                       pixc[2]= FTOCHAR(col[2]);
+                       /* assume alpha was set */
+               }
+       }
+}
index 1a630861b31c946d287fb7da12890955ba38212d..ec6289c38b70e1ce63873b87cf8b2e2ee2fef4ee 100644 (file)
@@ -3177,6 +3177,13 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                        soops->storeflag |= SO_TREESTORE_CLEANUP;       // at first draw
                                }
                        }
+                       else if(sl->spacetype==SPACE_IMAGE) {
+                               SpaceImage *sima= (SpaceImage *)sl;
+                               
+                               sima->cumap= newdataadr(fd, sima->cumap);
+                               if(sima->cumap)
+                                       direct_link_curvemapping(fd, sima->cumap);
+                       }
                        else if(sl->spacetype==SPACE_NODE) {
                                SpaceNode *snode= (SpaceNode *)sl;
                                snode->nodetree= snode->edittree= NULL;
index 9ead3517fa8f184ded998bf234a6c2d7f0afeed4..d5b3c4a29f5d8eee6bb2f1df4271f019a07db070 100644 (file)
@@ -1319,7 +1319,11 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        }
                                }
                                else if(sl->spacetype==SPACE_IMAGE) {
+                                       SpaceImage *sima= (SpaceImage *)sl;
+                                       
                                        writestruct(wd, DATA, "SpaceImage", 1, sl);
+                                       if(sima->cumap)
+                                               write_curvemapping(wd, sima->cumap);
                                }
                                else if(sl->spacetype==SPACE_IMASEL) {
                                        writestruct(wd, DATA, "SpaceImaSel", 1, sl);
index 7c9accdeed598813c2a116b56094171ebef11b4f..3c0084cf3f18ebc6ebd35d85e49cf9d1c04a7382 100644 (file)
@@ -67,5 +67,7 @@ void weld_align_tface_uv(char tool);
 void be_square_tface_uv(struct Mesh *me);
 void select_pinned_tface_uv(void);
 
+void sima_sample_color(void);
+
 #define UV_SELECT_ALL          1
 #define UV_SELECT_PINNED       2
index 8213192a2ae2e90d23aa920aae9ddba78f173940..2a417a385fad3f9627ec57fe66119e7d5d5de53d 100644 (file)
@@ -60,6 +60,7 @@ struct SpaceOops;
 /* image handler codes */
 #define IMAGE_HANDLER_PROPERTIES       30
 #define IMAGE_HANDLER_PAINT                    31
+#define IMAGE_HANDLER_CURVES           32
 
 /* action handler codes */
 #define ACTION_HANDLER_PROPERTIES      40
index e0061dc3403b99f881b56688f497d5160cd60b0e..45450eb905390321ac19bf2d9480d1f7583bb0f0 100644 (file)
 #define B_SIMACLONEDELETE      366
 #define B_SIMABRUSHCHANGE      367
 #define B_SIMANOTHING          368
+#define B_SIMACURVES           369
+#define B_SIMARANGE                    370
 
 /* BUTS: 400 */
 #define B_BUTSHOME             401
index af83b162bdf259adf2c266917a847de74a50bfec..1829398e4e8cfc3b533812ab8771d62f9530e3c9 100644 (file)
@@ -64,6 +64,8 @@ typedef struct CurveMapping {
        rctf curr, clipr;                               /* current rect, clip rect (is default rect too) */
        
        CurveMap cm[4];                                 /* max 4 builtin curves per mapping struct now */
+       float black[3], white[3];               /* black/white point */
+       float bwmul[3], padf;                   /* black/white point multiply value, for speed */
 } CurveMapping;
 
 /* cuma->flag */
index 4bb6af1f9945ead8ec4503b0e7f4c0a72b6a81cf..50572f45d364a8523267dce9395e4a5a8419a2ee 100644 (file)
@@ -219,6 +219,7 @@ typedef struct SpaceImage {
        View2D v2d;
        
        struct Image *image;
+       struct CurveMapping *cumap;
        float zoom;
        short mode, menunr;
        short imanr, curtile;
index a702f294d47cd0d1a393ac36a04a231b65cf50e2..84d051c887a8117675949ec1863e228c9958ed0c 100644 (file)
@@ -248,8 +248,8 @@ static void curvemap_buttons_zoom_in(void *cumap_v, void *unused)
        CurveMapping *cumap = cumap_v;
        float d;
        
-       /* we allow 5 times zoom */
-       if( (cumap->curr.xmax - cumap->curr.xmin) > 0.2f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
+       /* we allow 20 times zoom */
+       if( (cumap->curr.xmax - cumap->curr.xmin) > 0.04f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
                d= 0.1154f*(cumap->curr.xmax - cumap->curr.xmin);
                cumap->curr.xmin+= d;
                cumap->curr.xmax-= d;
@@ -264,8 +264,8 @@ static void curvemap_buttons_zoom_out(void *cumap_v, void *unused)
        CurveMapping *cumap = cumap_v;
        float d;
        
-       /* we allow 5 times zoom */
-       if( (cumap->curr.xmax - cumap->curr.xmin) < 5.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
+       /* we allow 20 times zoom */
+       if( (cumap->curr.xmax - cumap->curr.xmin) < 20.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
                d= 0.15f*(cumap->curr.xmax - cumap->curr.xmin);
                cumap->curr.xmin-= d;
                cumap->curr.xmax+= d;
@@ -307,10 +307,10 @@ static uiBlock *curvemap_clipping_func(void *cumap_v)
        uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL);
 
        uiBlockBeginAlign(block);
-       uiDefButF(block, NUM, 0, "Min X ",       0,74,120,18, &cumap->clipr.xmin, -10.0, cumap->clipr.xmax, 10, 0, "");
-       uiDefButF(block, NUM, 0, "Min Y ",       0,56,120,18, &cumap->clipr.ymin, -10.0, cumap->clipr.ymax, 10, 0, "");
-       uiDefButF(block, NUM, 0, "Max X ",       0,38,120,18, &cumap->clipr.xmax, cumap->clipr.xmin, 10.0, 10, 0, "");
-       uiDefButF(block, NUM, 0, "Max Y ",       0,20,120,18, &cumap->clipr.ymax, cumap->clipr.ymin, 10.0, 10, 0, "");
+       uiDefButF(block, NUM, 0, "Min X ",       0,74,120,18, &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 0, "");
+       uiDefButF(block, NUM, 0, "Min Y ",       0,56,120,18, &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 0, "");
+       uiDefButF(block, NUM, 0, "Max X ",       0,38,120,18, &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 0, "");
+       uiDefButF(block, NUM, 0, "Max Y ",       0,20,120,18, &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 0, "");
        
        uiBlockSetDirection(block, UI_RIGHT);
        
@@ -371,8 +371,8 @@ void curvemap_buttons(uiBlock *block, CurveMapping *cumap, char labeltype, short
        
        yco= (short)(rect->ymax-18.0f);
        
-       /* curve choice options + tools/settings, 8 icons */
-       dx= (rect->xmax-rect->xmin)/(8.0f);
+       /* curve choice options + tools/settings, 8 icons + spacer */
+       dx= (rect->xmax-rect->xmin)/(9.0f);
        
        uiBlockBeginAlign(block);
        if(labeltype=='v') {    /* vector */
@@ -388,35 +388,38 @@ void curvemap_buttons(uiBlock *block, CurveMapping *cumap, char labeltype, short
        }
        else if(labeltype=='c') { /* color */
                xco= (short)rect->xmin;
-               if(cumap->cm[0].curve)
-               uiDefButI(block, ROW, redraw, "R", xco, yco+2, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
+               if(cumap->cm[3].curve)
+                       uiDefButI(block, ROW, redraw, "C", xco, yco+2, dx, 16, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
                xco= (short)(rect->xmin+1.0f*dx);
-               if(cumap->cm[1].curve)
-               uiDefButI(block, ROW, redraw, "G", xco, yco+2, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+               if(cumap->cm[0].curve)
+                       uiDefButI(block, ROW, redraw, "R", xco, yco+2, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
                xco= (short)(rect->xmin+2.0f*dx);
+               if(cumap->cm[1].curve)
+                       uiDefButI(block, ROW, redraw, "G", xco, yco+2, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+               xco= (short)(rect->xmin+3.0f*dx);
                if(cumap->cm[2].curve)
-               uiDefButI(block, ROW, redraw, "B", xco, yco+2, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
+                       uiDefButI(block, ROW, redraw, "B", xco, yco+2, dx, 16, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
        }
        /* else no channels ! */
        uiBlockEndAlign(block);
 
-       xco= (short)(rect->xmin+3.5f*dx);
+       xco= (short)(rect->xmin+4.5f*dx);
        uiBlockSetEmboss(block, UI_EMBOSSN);
        bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMIN, xco, yco, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom in");
        uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL);
        
-       xco= (short)(rect->xmin+4.25f*dx);
+       xco= (short)(rect->xmin+5.25f*dx);
        bt= uiDefIconBut(block, BUT, redraw, ICON_ZOOMOUT, xco, yco, dx, 14, NULL, 0.0, 0.0, 0.0, 0.0, "Zoom out");
        uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL);
        
-       xco= (short)(rect->xmin+5.0f*dx);
+       xco= (short)(rect->xmin+6.0f*dx);
        bt= uiDefIconBlockBut(block, curvemap_tools_func, cumap, event, ICON_MODIFIER, xco, yco, dx, 18, "Tools");
        
-       xco= (short)(rect->xmin+6.0f*dx);
+       xco= (short)(rect->xmin+7.0f*dx);
        if(cumap->flag & CUMA_DO_CLIP) icon= ICON_CLIPUV_HLT; else icon= ICON_CLIPUV_DEHLT;
        bt= uiDefIconBlockBut(block, curvemap_clipping_func, cumap, event, icon, xco, yco, dx, 18, "Clipping Options");
        
-       xco= (short)(rect->xmin+7.0f*dx);
+       xco= (short)(rect->xmin+8.0f*dx);
        bt= uiDefIconBut(block, BUT, redraw, ICON_X, xco, yco, dx, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Delete points");
        uiButSetFunc(bt, curvemap_buttons_delete, cumap, NULL);
        
index 115bcd4627098824cfedf675a6eaf4a15d0ba17a..9f1972ce04737f2ec8f82f5d576cdd6de0058f9d 100644 (file)
@@ -49,6 +49,7 @@
 
 #include "IMB_imbuf_types.h"
 
+#include "DNA_color_types.h"
 #include "DNA_image_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
@@ -58,6 +59,7 @@
 #include "DNA_space_types.h"
 #include "DNA_userdef_types.h"
 
+#include "BKE_colortools.h"
 #include "BKE_utildefines.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
@@ -816,6 +818,17 @@ void do_imagebuts(unsigned short event)
        case B_SIMABRUSHCHANGE:
                allqueue(REDRAWIMAGE, 0);
                break;
+               
+       case B_SIMACURVES:
+               curvemapping_do_image(G.sima->cumap, G.sima->image);
+               allqueue(REDRAWIMAGE, 0);
+               break;
+               
+       case B_SIMARANGE:
+               curvemapping_set_black_white(G.sima->cumap, NULL, NULL);
+               curvemapping_do_image(G.sima->cumap, G.sima->image);
+               allqueue(REDRAWIMAGE, 0);
+               break;
        }
 }
 
@@ -826,13 +839,18 @@ static void image_panel_properties(short cntrl)   // IMAGE_HANDLER_PROPERTIES
        block= uiNewBlock(&curarea->uiblocks, "image_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
        uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
        uiSetPanelHandler(IMAGE_HANDLER_PROPERTIES);  // for close and esc
-       if(uiNewPanel(curarea, block, "Properties", "Image", 10, 230, 318, 204)==0)
+       if(uiNewPanel(curarea, block, "Properties", "Image", 10, 10, 318, 204)==0)
                return;
 
        if (G.sima->image && G.sima->image->ibuf) {
-               char str[32];
+               char str[64];
 
                sprintf(str, "Image: size %d x %d", G.sima->image->ibuf->x, G.sima->image->ibuf->y);
+               if(G.sima->image->ibuf->rect_float)
+                       strcat(str, " 4x32 bits");
+               else 
+                       strcat(str, " 4x8 bits");
+               
                uiDefBut(block, LABEL, B_NOP, str,              10,180,300,19, 0, 0, 0, 0, 0, "");
 
                uiBlockBeginAlign(block);
@@ -902,6 +920,40 @@ static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PROPERTIES
        uiDefButBitS(block, TOG|BIT, IMAGEPAINT_TORUS, B_SIMABRUSHCHANGE, "Wrap", 890,1,50,19, &Gip.flag, 0, 0, 0, 0, "Enables torus wrapping");
 }
 
+static void image_panel_curves(short cntrl)    // IMAGE_HANDLER_PROPERTIES
+{
+       uiBlock *block;
+       
+       block= uiNewBlock(&curarea->uiblocks, "image_panel_curves", UI_EMBOSS, UI_HELV, curarea->win);
+       uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
+       uiSetPanelHandler(IMAGE_HANDLER_CURVES);  // for close and esc
+       if(uiNewPanel(curarea, block, "Curves", "Image", 10, 450, 318, 204)==0)
+               return;
+       
+       if (G.sima->image && G.sima->image->ibuf) {
+               rctf rect;
+               
+               if(G.sima->cumap==NULL)
+                       G.sima->cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
+               
+               rect.xmin= 110; rect.xmax= 310;
+               rect.ymin= 10; rect.ymax= 200;
+               curvemap_buttons(block, G.sima->cumap, 'c', B_SIMACURVES, B_SIMAGEDRAW, &rect);
+               
+               uiBlockBeginAlign(block);
+               uiDefButF(block, NUM, B_SIMARANGE, "Min R:",    10, 120, 90, 19, G.sima->cumap->black, -1000.0f, 1000.0f, 10, 2, "Black level");
+               uiDefButF(block, NUM, B_SIMARANGE, "Min G:",    10, 100, 90, 19, G.sima->cumap->black+1, -1000.0f, 1000.0f, 10, 2, "Black level");
+               uiDefButF(block, NUM, B_SIMARANGE, "Min B:",    10, 80, 90, 19, G.sima->cumap->black+2, -1000.0f, 1000.0f, 10, 2, "Black level");
+               
+               uiBlockBeginAlign(block);
+               uiDefButF(block, NUM, B_SIMARANGE, "Max R:",    10, 50, 90, 19, G.sima->cumap->white, -1000.0f, 1000.0f, 10, 2, "White level");
+               uiDefButF(block, NUM, B_SIMARANGE, "Max G:",    10, 30, 90, 19, G.sima->cumap->white+1, -1000.0f, 1000.0f, 10, 2, "White level");
+               uiDefButF(block, NUM, B_SIMARANGE, "Max B:",    10, 10, 90, 19, G.sima->cumap->white+2, -1000.0f, 1000.0f, 10, 2, "White level");
+       }
+}
+
+
+
 static void image_blockhandlers(ScrArea *sa)
 {
        SpaceImage *sima= sa->spacedata.first;
@@ -919,6 +971,9 @@ static void image_blockhandlers(ScrArea *sa)
                case IMAGE_HANDLER_PAINT:
                        image_panel_paint(sima->blockhandler[a+1]);
                        break;          
+               case IMAGE_HANDLER_CURVES:
+                       image_panel_curves(sima->blockhandler[a+1]);
+                       break;          
                }
                /* clear action value for event */
                sima->blockhandler[a+1]= 0;
@@ -1120,6 +1175,7 @@ void drawimagespace(ScrArea *sa, void *spacedata)
 
        draw_image_transform(ibuf);
 
+       mywinset(sa->win);      /* restore scissor after gla call... */
        myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
 
        draw_image_view_tool();
index 6e717147bdad5eec178e87899be6d60037a8b992..3b2a350e5900d31a1706e5d57a74ef83bb40705d 100644 (file)
@@ -59,6 +59,7 @@
 #include "DNA_image_types.h"
 #include "DNA_object_types.h" // only for uvedit_selectionCB() (struct Object)
 
+#include "BKE_colortools.h"
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
 #include "BKE_mesh.h"
@@ -1449,3 +1450,50 @@ int minmax_tface_uv(float *min, float *max)
        return sel;
 }
 
+void sima_sample_color(void)
+{
+       ImBuf *ibuf;
+       float fx, fy;
+       short mval[2];
+       
+       if(G.sima->image==NULL) return;
+       if(G.sima->image->ibuf==NULL) return;
+       ibuf= G.sima->image->ibuf;
+       
+       calc_image_view(G.sima, 'f');
+       
+       getmouseco_areawin(mval);
+       areamouseco_to_ipoco(G.v2d, mval, &fx, &fy);
+       
+       if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) {
+               int x= (int) (fx*ibuf->x);
+               int y= (int) (fy*ibuf->y);
+               
+               if(x>=ibuf->x) x= ibuf->x-1;
+               if(y>=ibuf->y) y= ibuf->y-1;
+               
+               if(ibuf->rect) {
+                       char *cp= (char *)(ibuf->rect + y*ibuf->x + x);
+                       printf("rgba %d %d %d %d\n", cp[0], cp[1], cp[2], cp[3]);
+               }
+               if(ibuf->rect_float) {
+                       float *fp= (ibuf->rect_float + 4*(y*ibuf->x + x));
+                       printf("rgba %f %f %f %f\n", fp[0], fp[1], fp[2], fp[3]);
+                       
+                       if(G.sima->cumap) {
+                               if(G.qual & LR_CTRLKEY) {
+                                       curvemapping_set_black_white(G.sima->cumap, NULL, fp);
+                                       curvemapping_do_image(G.sima->cumap, G.sima->image);
+                                       allqueue(REDRAWIMAGE, 0);
+                               }
+                               else if(G.qual & LR_SHIFTKEY) {
+                                       curvemapping_set_black_white(G.sima->cumap, fp, NULL);
+                                       curvemapping_do_image(G.sima->cumap, G.sima->image);
+                                       allqueue(REDRAWIMAGE, 0);
+                               }
+                       }
+               }
+       }               
+}
+
+
index 6bb93d41a6f3469ebe2c1e1e7c8133ba4858634e..2e8608332a680bb9f4cfa186b1cc5bcbfd9c9118 100644 (file)
@@ -445,6 +445,9 @@ static void do_image_viewmenu(void *arg, int event)
                G.sima->flag ^= SI_COORDFLOATS;
                allqueue(REDRAWIMAGE, 0);
                break;
+       case 11: /* Curves Panel... */
+               add_blockhandler(curarea, IMAGE_HANDLER_CURVES, UI_PNL_UNSTOW);
+               break;
        }
        allqueue(REDRAWVIEW3D, 0);
 }
@@ -458,8 +461,9 @@ static uiBlock *image_viewmenu(void *arg_unused)
        block= uiNewBlock(&curarea->uiblocks, "image_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
        uiBlockSetButmFunc(block, do_image_viewmenu, NULL);
 
-       uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "View Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "View Paint Tool...|C",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Paint Tool...|C",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Curves Tool...",        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
 
        if(G.sima->flag & SI_COORDFLOATS) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Display Normalized Coordinates|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Display Normalized Coordinates|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
index 4fdc764bc763b516219421ee7ec8ea93fcd47c6a..5c2e308a4fac9603517a5ec1152646e50ac3bb0d 100644 (file)
@@ -70,6 +70,7 @@
 #include "DNA_view3d_types.h"
 
 #include "BKE_blender.h"
+#include "BKE_colortools.h"
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_displist.h"
@@ -3895,8 +3896,16 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                /* Draw tool is inactive */
                switch(event) {
                        case LEFTMOUSE:
-                               if(G.qual & LR_SHIFTKEY) mouseco_to_curtile();
-                               else gesture();
+                               if(G.qual & LR_SHIFTKEY) {
+                                       if(G.sima->image && G.sima->image->tpageflag & IMA_TILES)
+                                               mouseco_to_curtile();
+                                       else
+                                               sima_sample_color();
+                               }
+                               else if(G.f & G_FACESELECT)
+                                       gesture();
+                               else 
+                                       sima_sample_color();
                                break;
                        case RIGHTMOUSE:
                                if(G.f & G_FACESELECT)
@@ -4665,6 +4674,11 @@ void freespacelist(ListBase *lb)
                else if(sl->spacetype==SPACE_SOUND) {
                        free_soundspace((SpaceSound *)sl);
                }
+               else if(sl->spacetype==SPACE_IMAGE) {
+                       SpaceImage *sima= (SpaceImage *)sl;
+                       if(sima->cumap)
+                               curvemapping_free(sima->cumap);
+               }
                else if(sl->spacetype==SPACE_NODE) {
 /*                     SpaceNode *snode= (SpaceNode *)sl; */
                }
@@ -4697,8 +4711,6 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
                else if(sl->spacetype==SPACE_IMASEL) {
                        check_imasel_copy((SpaceImaSel *) sl);
                }
-               else if(sl->spacetype==SPACE_TEXT) {
-               }
                else if(sl->spacetype==SPACE_NODE) {
                        SpaceNode *snode= (SpaceNode *)sl;
                        snode->nodetree= NULL;
@@ -4738,6 +4750,11 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
                        }
                        vd->clipbb= MEM_dupallocN(vd->clipbb);
                }
+               else if(sl->spacetype==SPACE_IMAGE) {
+                       SpaceImage *sima= (SpaceImage *)sl;
+                       if(sima->cumap)
+                               sima->cumap= curvemapping_copy(sima->cumap);
+               }
                sl= sl->next;
        }