Orange: and now for the real exr fun: float buffer support in Image window!

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!
This commit is contained in:
2006-01-09 23:52:51 +00:00
parent a094eb4e9a
commit 3b4907415c
14 changed files with 238 additions and 31 deletions

View File

@@ -31,11 +31,13 @@
struct CurveMapping; struct CurveMapping;
struct CurveMap; struct CurveMap;
struct Image;
struct rctf; struct rctf;
struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy); struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
void curvemapping_free(struct CurveMapping *cumap); void curvemapping_free(struct CurveMapping *cumap);
struct CurveMapping *curvemapping_copy(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_remove(struct CurveMap *cuma, int flag);
void curvemap_insert(struct CurveMap *cuma, float x, float y); 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); void curvemapping_changed(struct CurveMapping *cumap, int rem_doubles);
float curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value); float curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value);
void curvemapping_evaluate3F(struct CurveMapping *cumap, float *vecout, const float *vecin); void curvemapping_evaluate3F(struct CurveMapping *cumap, float *vecout, const float *vecin);
void curvemapping_do_image(struct CurveMapping *cumap, struct Image *ima);
#endif #endif

View File

@@ -36,6 +36,7 @@
#include "DNA_color_types.h" #include "DNA_color_types.h"
#include "DNA_curve_types.h" #include "DNA_curve_types.h"
#include "DNA_image_types.h"
#include "DNA_texture_types.h" #include "DNA_texture_types.h"
#include "BKE_colortools.h" #include "BKE_colortools.h"
@@ -48,6 +49,7 @@
#include "BLI_blenlib.h" #include "BLI_blenlib.h"
#include "BLI_arithb.h" #include "BLI_arithb.h"
#include "IMB_imbuf_types.h"
/* ********************************* color curve ********************* */ /* ********************************* 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= MEM_callocN(sizeof(CurveMapping), "new curvemap");
cumap->flag= CUMA_DO_CLIP; 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); BLI_init_rctf(&cumap->curr, minx, maxx, miny, maxy);
cumap->clipr= cumap->curr; 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++) { for(a=0; a<tot; a++) {
cumap->cm[a].totpoint= 2; cumap->cm[a].totpoint= 2;
cumap->cm[a].curve= MEM_callocN(2*sizeof(CurveMapPoint), "curve points"); cumap->cm[a].curve= MEM_callocN(2*sizeof(CurveMapPoint), "curve points");
@@ -106,6 +112,23 @@ CurveMapping *curvemapping_copy(CurveMapping *cumap)
return NULL; 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 ************* */ /* ***************** operations on single curve ************* */
/* ********** NOTE: requires curvemapping_changed() call after ******** */ /* ********** 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) void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *vecin)
{ {
vecout[0]= curvemapping_evaluateF(cumap, 0, vecin[0]); if(cumap->cm[3].curve) {
vecout[1]= curvemapping_evaluateF(cumap, 1, vecin[1]); float fac;
vecout[2]= curvemapping_evaluateF(cumap, 2, vecin[2]);
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 */
}
}
}

View File

@@ -3177,6 +3177,13 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw 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) { else if(sl->spacetype==SPACE_NODE) {
SpaceNode *snode= (SpaceNode *)sl; SpaceNode *snode= (SpaceNode *)sl;
snode->nodetree= snode->edittree= NULL; snode->nodetree= snode->edittree= NULL;

View File

@@ -1319,7 +1319,11 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
} }
} }
else if(sl->spacetype==SPACE_IMAGE) { else if(sl->spacetype==SPACE_IMAGE) {
SpaceImage *sima= (SpaceImage *)sl;
writestruct(wd, DATA, "SpaceImage", 1, sl); writestruct(wd, DATA, "SpaceImage", 1, sl);
if(sima->cumap)
write_curvemapping(wd, sima->cumap);
} }
else if(sl->spacetype==SPACE_IMASEL) { else if(sl->spacetype==SPACE_IMASEL) {
writestruct(wd, DATA, "SpaceImaSel", 1, sl); writestruct(wd, DATA, "SpaceImaSel", 1, sl);

View File

@@ -67,5 +67,7 @@ void weld_align_tface_uv(char tool);
void be_square_tface_uv(struct Mesh *me); void be_square_tface_uv(struct Mesh *me);
void select_pinned_tface_uv(void); void select_pinned_tface_uv(void);
void sima_sample_color(void);
#define UV_SELECT_ALL 1 #define UV_SELECT_ALL 1
#define UV_SELECT_PINNED 2 #define UV_SELECT_PINNED 2

View File

@@ -60,6 +60,7 @@ struct SpaceOops;
/* image handler codes */ /* image handler codes */
#define IMAGE_HANDLER_PROPERTIES 30 #define IMAGE_HANDLER_PROPERTIES 30
#define IMAGE_HANDLER_PAINT 31 #define IMAGE_HANDLER_PAINT 31
#define IMAGE_HANDLER_CURVES 32
/* action handler codes */ /* action handler codes */
#define ACTION_HANDLER_PROPERTIES 40 #define ACTION_HANDLER_PROPERTIES 40

View File

@@ -310,6 +310,8 @@
#define B_SIMACLONEDELETE 366 #define B_SIMACLONEDELETE 366
#define B_SIMABRUSHCHANGE 367 #define B_SIMABRUSHCHANGE 367
#define B_SIMANOTHING 368 #define B_SIMANOTHING 368
#define B_SIMACURVES 369
#define B_SIMARANGE 370
/* BUTS: 400 */ /* BUTS: 400 */
#define B_BUTSHOME 401 #define B_BUTSHOME 401

View File

@@ -64,6 +64,8 @@ typedef struct CurveMapping {
rctf curr, clipr; /* current rect, clip rect (is default rect too) */ rctf curr, clipr; /* current rect, clip rect (is default rect too) */
CurveMap cm[4]; /* max 4 builtin curves per mapping struct now */ 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; } CurveMapping;
/* cuma->flag */ /* cuma->flag */

View File

@@ -219,6 +219,7 @@ typedef struct SpaceImage {
View2D v2d; View2D v2d;
struct Image *image; struct Image *image;
struct CurveMapping *cumap;
float zoom; float zoom;
short mode, menunr; short mode, menunr;
short imanr, curtile; short imanr, curtile;

View File

@@ -248,8 +248,8 @@ static void curvemap_buttons_zoom_in(void *cumap_v, void *unused)
CurveMapping *cumap = cumap_v; CurveMapping *cumap = cumap_v;
float d; float d;
/* we allow 5 times zoom */ /* we allow 20 times zoom */
if( (cumap->curr.xmax - cumap->curr.xmin) > 0.2f*(cumap->clipr.xmax - cumap->clipr.xmin) ) { if( (cumap->curr.xmax - cumap->curr.xmin) > 0.04f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
d= 0.1154f*(cumap->curr.xmax - cumap->curr.xmin); d= 0.1154f*(cumap->curr.xmax - cumap->curr.xmin);
cumap->curr.xmin+= d; cumap->curr.xmin+= d;
cumap->curr.xmax-= d; cumap->curr.xmax-= d;
@@ -264,8 +264,8 @@ static void curvemap_buttons_zoom_out(void *cumap_v, void *unused)
CurveMapping *cumap = cumap_v; CurveMapping *cumap = cumap_v;
float d; float d;
/* we allow 5 times zoom */ /* we allow 20 times zoom */
if( (cumap->curr.xmax - cumap->curr.xmin) < 5.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) { if( (cumap->curr.xmax - cumap->curr.xmin) < 20.0f*(cumap->clipr.xmax - cumap->clipr.xmin) ) {
d= 0.15f*(cumap->curr.xmax - cumap->curr.xmin); d= 0.15f*(cumap->curr.xmax - cumap->curr.xmin);
cumap->curr.xmin-= d; cumap->curr.xmin-= d;
cumap->curr.xmax+= d; cumap->curr.xmax+= d;
@@ -307,10 +307,10 @@ static uiBlock *curvemap_clipping_func(void *cumap_v)
uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL); uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL);
uiBlockBeginAlign(block); 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 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, -10.0, cumap->clipr.ymax, 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, 10.0, 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, 10.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); uiBlockSetDirection(block, UI_RIGHT);
@@ -371,8 +371,8 @@ void curvemap_buttons(uiBlock *block, CurveMapping *cumap, char labeltype, short
yco= (short)(rect->ymax-18.0f); yco= (short)(rect->ymax-18.0f);
/* curve choice options + tools/settings, 8 icons */ /* curve choice options + tools/settings, 8 icons + spacer */
dx= (rect->xmax-rect->xmin)/(8.0f); dx= (rect->xmax-rect->xmin)/(9.0f);
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
if(labeltype=='v') { /* vector */ if(labeltype=='v') { /* vector */
@@ -388,35 +388,38 @@ void curvemap_buttons(uiBlock *block, CurveMapping *cumap, char labeltype, short
} }
else if(labeltype=='c') { /* color */ else if(labeltype=='c') { /* color */
xco= (short)rect->xmin; xco= (short)rect->xmin;
if(cumap->cm[0].curve) if(cumap->cm[3].curve)
uiDefButI(block, ROW, redraw, "R", xco, yco+2, dx, 16, &cumap->cur, 0.0, 0.0, 0.0, 0.0, ""); 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); xco= (short)(rect->xmin+1.0f*dx);
if(cumap->cm[1].curve) if(cumap->cm[0].curve)
uiDefButI(block, ROW, redraw, "G", xco, yco+2, dx, 16, &cumap->cur, 0.0, 1.0, 0.0, 0.0, ""); 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); 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) 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 ! */ /* else no channels ! */
uiBlockEndAlign(block); uiBlockEndAlign(block);
xco= (short)(rect->xmin+3.5f*dx); xco= (short)(rect->xmin+4.5f*dx);
uiBlockSetEmboss(block, UI_EMBOSSN); 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"); 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); 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"); 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); 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"); 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; 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"); 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"); 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); uiButSetFunc(bt, curvemap_buttons_delete, cumap, NULL);

View File

@@ -49,6 +49,7 @@
#include "IMB_imbuf_types.h" #include "IMB_imbuf_types.h"
#include "DNA_color_types.h"
#include "DNA_image_types.h" #include "DNA_image_types.h"
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
@@ -58,6 +59,7 @@
#include "DNA_space_types.h" #include "DNA_space_types.h"
#include "DNA_userdef_types.h" #include "DNA_userdef_types.h"
#include "BKE_colortools.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_main.h" #include "BKE_main.h"
@@ -816,6 +818,17 @@ void do_imagebuts(unsigned short event)
case B_SIMABRUSHCHANGE: case B_SIMABRUSHCHANGE:
allqueue(REDRAWIMAGE, 0); allqueue(REDRAWIMAGE, 0);
break; 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); block= uiNewBlock(&curarea->uiblocks, "image_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(IMAGE_HANDLER_PROPERTIES); // for close and esc 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; return;
if (G.sima->image && G.sima->image->ibuf) { 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); 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, ""); uiDefBut(block, LABEL, B_NOP, str, 10,180,300,19, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block); 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"); 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) static void image_blockhandlers(ScrArea *sa)
{ {
SpaceImage *sima= sa->spacedata.first; SpaceImage *sima= sa->spacedata.first;
@@ -919,6 +971,9 @@ static void image_blockhandlers(ScrArea *sa)
case IMAGE_HANDLER_PAINT: case IMAGE_HANDLER_PAINT:
image_panel_paint(sima->blockhandler[a+1]); image_panel_paint(sima->blockhandler[a+1]);
break; break;
case IMAGE_HANDLER_CURVES:
image_panel_curves(sima->blockhandler[a+1]);
break;
} }
/* clear action value for event */ /* clear action value for event */
sima->blockhandler[a+1]= 0; sima->blockhandler[a+1]= 0;
@@ -1120,6 +1175,7 @@ void drawimagespace(ScrArea *sa, void *spacedata)
draw_image_transform(ibuf); 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); myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
draw_image_view_tool(); draw_image_view_tool();

View File

@@ -59,6 +59,7 @@
#include "DNA_image_types.h" #include "DNA_image_types.h"
#include "DNA_object_types.h" // only for uvedit_selectionCB() (struct Object) #include "DNA_object_types.h" // only for uvedit_selectionCB() (struct Object)
#include "BKE_colortools.h"
#include "BKE_depsgraph.h" #include "BKE_depsgraph.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
@@ -1449,3 +1450,50 @@ int minmax_tface_uv(float *min, float *max)
return sel; 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);
}
}
}
}
}

View File

@@ -445,6 +445,9 @@ static void do_image_viewmenu(void *arg, int event)
G.sima->flag ^= SI_COORDFLOATS; G.sima->flag ^= SI_COORDFLOATS;
allqueue(REDRAWIMAGE, 0); allqueue(REDRAWIMAGE, 0);
break; break;
case 11: /* Curves Panel... */
add_blockhandler(curarea, IMAGE_HANDLER_CURVES, UI_PNL_UNSTOW);
break;
} }
allqueue(REDRAWVIEW3D, 0); 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); block= uiNewBlock(&curarea->uiblocks, "image_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_image_viewmenu, NULL); 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, "Show 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 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, ""); 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, ""); else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Display Normalized Coordinates|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");

View File

@@ -70,6 +70,7 @@
#include "DNA_view3d_types.h" #include "DNA_view3d_types.h"
#include "BKE_blender.h" #include "BKE_blender.h"
#include "BKE_colortools.h"
#include "BKE_curve.h" #include "BKE_curve.h"
#include "BKE_depsgraph.h" #include "BKE_depsgraph.h"
#include "BKE_displist.h" #include "BKE_displist.h"
@@ -3895,8 +3896,16 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
/* Draw tool is inactive */ /* Draw tool is inactive */
switch(event) { switch(event) {
case LEFTMOUSE: case LEFTMOUSE:
if(G.qual & LR_SHIFTKEY) mouseco_to_curtile(); if(G.qual & LR_SHIFTKEY) {
else gesture(); 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; break;
case RIGHTMOUSE: case RIGHTMOUSE:
if(G.f & G_FACESELECT) if(G.f & G_FACESELECT)
@@ -4665,6 +4674,11 @@ void freespacelist(ListBase *lb)
else if(sl->spacetype==SPACE_SOUND) { else if(sl->spacetype==SPACE_SOUND) {
free_soundspace((SpaceSound *)sl); 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) { else if(sl->spacetype==SPACE_NODE) {
/* SpaceNode *snode= (SpaceNode *)sl; */ /* SpaceNode *snode= (SpaceNode *)sl; */
} }
@@ -4697,8 +4711,6 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
else if(sl->spacetype==SPACE_IMASEL) { else if(sl->spacetype==SPACE_IMASEL) {
check_imasel_copy((SpaceImaSel *) sl); check_imasel_copy((SpaceImaSel *) sl);
} }
else if(sl->spacetype==SPACE_TEXT) {
}
else if(sl->spacetype==SPACE_NODE) { else if(sl->spacetype==SPACE_NODE) {
SpaceNode *snode= (SpaceNode *)sl; SpaceNode *snode= (SpaceNode *)sl;
snode->nodetree= NULL; snode->nodetree= NULL;
@@ -4738,6 +4750,11 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
} }
vd->clipbb= MEM_dupallocN(vd->clipbb); 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; sl= sl->next;
} }