Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMatt Ebb <matt@mke3.net>2010-01-20 07:19:55 +0300
committerMatt Ebb <matt@mke3.net>2010-01-20 07:19:55 +0300
commit1d3186cbcf9e3e463e4e6362ac76862b801cf7ba (patch)
tree450dc8b914efeb8829f815dbba1f9aabd7449a0f /source
parent8bcf66e1d16ece55f8736797f7d4180a456060ff (diff)
Durian request: Added 'Color Balance' node to compositor. uses Lift/Gamma/Gain
similar to sequence editor. --> http://mke3.net/blender/devel/2.5/color_balance_node.jpg Also added 0 key (zero key) shortcut when mouse is over a button, to reset it to its default value. Same as the RMB menu ->Reset to Default, except for color wheels, it only resets the hue/sat/value components that that widget affects. Peter/Xavier: The existing color balance code can generate NaNs (fractional power of a negative), which causes havoc along the image pipeline. I added a check in the node code to prevent this. Still plenty of potential for lots of better colour correction tools in the compositor, just needs time...
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/node.c1
-rw-r--r--source/blender/blenlib/BLI_math_color.h4
-rw-r--r--source/blender/blenlib/intern/math_color.c14
-rw-r--r--source/blender/editors/interface/interface.c11
-rw-r--r--source/blender/editors/interface/interface_handlers.c59
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/space_image/space_image.c445
-rw-r--r--source/blender/editors/space_node/drawnode.c27
-rw-r--r--source/blender/makesdna/DNA_node_types.h12
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c51
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h1
-rw-r--r--source/blender/nodes/CMP_node.h1
-rw-r--r--source/blender/nodes/intern/node_util.h11
14 files changed, 418 insertions, 222 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 8da732af2dd..fe20c4d8158 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -354,6 +354,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
#define CMP_NODE_DIST_MATTE 257
#define CMP_NODE_VIEW_LEVELS 258
#define CMP_NODE_COLOR_MATTE 259
+#define CMP_NODE_COLORBALANCE 260
#define CMP_NODE_GLARE 301
#define CMP_NODE_TONEMAP 302
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index b7991d0c589..874529d9965 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2983,6 +2983,7 @@ static void registerCompositNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &cmp_node_invert);
nodeRegisterType(ntypelist, &cmp_node_alphaover);
nodeRegisterType(ntypelist, &cmp_node_zcombine);
+ nodeRegisterType(ntypelist, &cmp_node_colorbalance);
nodeRegisterType(ntypelist, &cmp_node_normal);
nodeRegisterType(ntypelist, &cmp_node_curve_vec);
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 2123765643e..41cce59c2b9 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -73,6 +73,10 @@ void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from);
int constrain_rgb(float *r, float *g, float *b);
void minmax_rgb(short c[3]);
+
+/***************** lift/gamma/gain / ASC-CDL conversion *****************/
+
+void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power);
void rgb_byte_to_float(char *in, float *out);
void rgb_float_to_byte(float *in, char *out);
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index a4bd11a4bc8..044f1ca743e 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -386,3 +386,17 @@ int constrain_rgb(float *r, float *g, float *b)
return 0; /* Color within RGB gamut */
}
+/* ********************************* lift/gamma/gain / ASC-CDL conversion ********************************* */
+
+void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power)
+{
+ int c;
+ for(c=0; c<3; c++) {
+ offset[c]= lift[c]*gain[c];
+ slope[c]= gain[c]*(1.0f-lift[c]);
+ if(gamma[c] == 0)
+ power[c]= FLT_MAX;
+ else
+ power[c]= 1.0f/gamma[c];
+ }
+}
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 48fd23ad0e7..8b59ff604b9 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1626,6 +1626,17 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
return 0;
}
+void ui_set_but_default(bContext *C, uiBut *but)
+{
+ /* if there is a valid property that is editable... */
+ if (but->rnapoin.data && but->rnaprop && RNA_property_editable(&but->rnapoin, but->rnaprop)) {
+ if(RNA_property_reset(&but->rnapoin, but->rnaprop, -1)) {
+ /* perform updates required for this property */
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+ }
+ }
+}
+
static double soft_range_round_up(double value, double max)
{
/* round up to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, .. */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 6873c64a188..37d5191691a 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2781,6 +2781,34 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
return WM_UI_HANDLER_BREAK;
}
+ else if (event->type == ZEROKEY && event->val == KM_PRESS) {
+ if (but->a1==9){
+ float rgb[3], hsv[3], def_hsv[3];
+ float *def;
+ int len;
+
+ /* reset only value */
+
+ len= RNA_property_array_length(&but->rnapoin, but->rnaprop);
+ if (len >= 3) {
+ def= MEM_callocN(sizeof(float)*len, "reset_defaults - float");
+
+ RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
+ rgb_to_hsv(def[0], def[1], def[2], def_hsv, def_hsv+1, def_hsv+2);
+
+ ui_get_but_vectorf(but, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+
+ hsv_to_rgb(hsv[0], hsv[1], def_hsv[2], rgb, rgb+1, rgb+2);
+ ui_set_but_vectorf(but, rgb);
+
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+
+ MEM_freeN(def);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
if(event->type == ESCKEY) {
@@ -2849,6 +2877,32 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
return WM_UI_HANDLER_BREAK;
}
+ else if (event->type == ZEROKEY && event->val == KM_PRESS) {
+ float rgb[3], hsv[3], def_hsv[3];
+ float *def;
+ int len;
+
+ /* reset only saturation */
+
+ len= RNA_property_array_length(&but->rnapoin, but->rnaprop);
+ if (len >= 3) {
+ def= MEM_callocN(sizeof(float)*len, "reset_defaults - float");
+
+ RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
+ rgb_to_hsv(def[0], def[1], def[2], def_hsv, def_hsv+1, def_hsv+2);
+
+ ui_get_but_vectorf(but, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+
+ hsv_to_rgb(hsv[0], def_hsv[1], hsv[2], rgb, rgb+1, rgb+2);
+ ui_set_but_vectorf(but, rgb);
+
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+
+ MEM_freeN(def);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
if(event->type == ESCKEY) {
@@ -3724,6 +3778,11 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
return WM_UI_HANDLER_BREAK;
}
+ /* reset to default */
+ else if(event->type == ZEROKEY && event->val == KM_PRESS) {
+ if (!(ELEM(but->type, HSVCIRCLE, HSVCUBE)))
+ ui_set_but_default(C, but);
+ }
/* handle menu */
else if(event->type == RIGHTMOUSE && event->val == KM_PRESS) {
/* RMB has two options now */
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 089ad85a5a1..1851255fd3b 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -345,6 +345,8 @@ extern void ui_get_but_string(uiBut *but, char *str, int maxlen);
extern int ui_set_but_string(struct bContext *C, uiBut *but, const char *str);
extern int ui_get_but_string_max_length(uiBut *but);
+extern void ui_set_but_default(struct bContext *C, uiBut *but);
+
extern void ui_set_but_soft_range(uiBut *but, double value);
extern void ui_check_but(uiBut *but);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 0a3367b0427..34737c62450 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -75,6 +75,228 @@
#include "image_intern.h"
+/**************************** common state *****************************/
+
+/* note; image_panel_properties() uses pointer to sima->image directly */
+Image *ED_space_image(SpaceImage *sima)
+{
+ return sima->image;
+}
+
+/* called to assign images to UV faces */
+void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, Image *ima)
+{
+ ED_uvedit_assign_image(scene, obedit, ima, sima->image);
+
+ /* change the space ima after because uvedit_face_visible uses the space ima
+ * to check if the face is displayed in UV-localview */
+ sima->image= ima;
+
+ if(ima == NULL || ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE)
+ sima->flag &= ~SI_DRAWTOOL;
+
+ if(sima->image)
+ BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
+
+ if(sima->image && sima->image->id.us==0)
+ sima->image->id.us= 1;
+
+ if(C) {
+ if(obedit)
+ WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
+ ED_area_tag_redraw(CTX_wm_area(C));
+ }
+}
+
+ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
+{
+ ImBuf *ibuf;
+
+ if(sima && sima->image) {
+#if 0
+ if(sima->image->type==IMA_TYPE_R_RESULT && BIF_show_render_spare())
+ return BIF_render_spare_imbuf();
+ else
+#endif
+ ibuf= BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r);
+
+ if(ibuf && (ibuf->rect || ibuf->rect_float))
+ return ibuf;
+ }
+
+ return NULL;
+}
+
+void ED_space_image_release_buffer(SpaceImage *sima, void *lock)
+{
+ if(sima && sima->image)
+ BKE_image_release_ibuf(sima->image, lock);
+}
+
+int ED_space_image_has_buffer(SpaceImage *sima)
+{
+ ImBuf *ibuf;
+ void *lock;
+ int has_buffer;
+
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
+ has_buffer= (ibuf != NULL);
+ ED_space_image_release_buffer(sima, lock);
+
+ return has_buffer;
+}
+
+void ED_image_size(Image *ima, int *width, int *height)
+{
+ ImBuf *ibuf= NULL;
+ void *lock;
+
+ if(ima)
+ ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
+ *width= ibuf->x;
+ *height= ibuf->y;
+ }
+ else {
+ *width= 256;
+ *height= 256;
+ }
+
+ if(ima)
+ BKE_image_release_ibuf(ima, lock);
+}
+
+void ED_space_image_size(SpaceImage *sima, int *width, int *height)
+{
+ Scene *scene= sima->iuser.scene;
+ ImBuf *ibuf;
+ void *lock;
+
+ ibuf= ED_space_image_acquire_buffer(sima, &lock);
+
+ if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
+ *width= ibuf->x;
+ *height= ibuf->y;
+ }
+ else if(sima->image && sima->image->type==IMA_TYPE_R_RESULT && scene) {
+ /* not very important, just nice */
+ *width= (scene->r.xsch*scene->r.size)/100;
+ *height= (scene->r.ysch*scene->r.size)/100;
+ }
+ /* I know a bit weak... but preview uses not actual image size */
+ // XXX else if(image_preview_active(sima, width, height));
+ else {
+ *width= 256;
+ *height= 256;
+ }
+
+ ED_space_image_release_buffer(sima, lock);
+}
+
+void ED_image_aspect(Image *ima, float *aspx, float *aspy)
+{
+ *aspx= *aspy= 1.0;
+
+ if((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) ||
+ (ima->aspx==0.0 || ima->aspy==0.0))
+ return;
+
+ /* x is always 1 */
+ *aspy = ima->aspy/ima->aspx;
+}
+
+void ED_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy)
+{
+ ED_image_aspect(ED_space_image(sima), aspx, aspy);
+}
+
+void ED_space_image_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy)
+{
+ int width, height;
+
+ ED_space_image_size(sima, &width, &height);
+
+ *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width);
+ *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height);
+}
+
+void ED_space_image_uv_aspect(SpaceImage *sima, float *aspx, float *aspy)
+{
+ int w, h;
+
+ ED_space_image_aspect(sima, aspx, aspy);
+ ED_space_image_size(sima, &w, &h);
+
+ *aspx *= (float)w/256.0f;
+ *aspy *= (float)h/256.0f;
+}
+
+void ED_image_uv_aspect(Image *ima, float *aspx, float *aspy)
+{
+ int w, h;
+
+ ED_image_aspect(ima, aspx, aspy);
+ ED_image_size(ima, &w, &h);
+
+ *aspx *= (float)w;
+ *aspy *= (float)h;
+}
+
+int ED_space_image_show_render(SpaceImage *sima)
+{
+ return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE));
+}
+
+int ED_space_image_show_paint(SpaceImage *sima)
+{
+ if(ED_space_image_show_render(sima))
+ return 0;
+
+ return (sima->flag & SI_DRAWTOOL);
+}
+
+int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
+{
+ if(ED_space_image_show_render(sima))
+ return 0;
+ if(ED_space_image_show_paint(sima))
+ return 0;
+
+ if(obedit && obedit->type == OB_MESH) {
+ EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
+ int ret;
+
+ ret = EM_texFaceCheck(em);
+
+ BKE_mesh_end_editmesh(obedit->data, em);
+ return ret;
+ }
+
+ return 0;
+}
+
+int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
+{
+ if(ED_space_image_show_render(sima))
+ return 0;
+
+ if(ED_space_image_show_paint(sima))
+ if(obedit && obedit->type == OB_MESH) {
+ EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
+ int ret;
+
+ ret = EM_texFaceCheck(em);
+
+ BKE_mesh_end_editmesh(obedit->data, em);
+ return ret;
+ }
+
+ return 0;
+}
+
+
static void image_histogram_tag_refresh(ScrArea *sa)
{
@@ -343,6 +565,8 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn)
case ND_MODE:
case ND_RENDER_RESULT:
case ND_COMPO_RESULT:
+ if (ED_space_image_show_render(sima))
+ image_histogram_tag_refresh(sa);
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
break;
@@ -650,224 +874,3 @@ void ED_spacetype_image(void)
BKE_spacetype_register(st);
}
-/**************************** common state *****************************/
-
-/* note; image_panel_properties() uses pointer to sima->image directly */
-Image *ED_space_image(SpaceImage *sima)
-{
- return sima->image;
-}
-
-/* called to assign images to UV faces */
-void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, Image *ima)
-{
- ED_uvedit_assign_image(scene, obedit, ima, sima->image);
-
- /* change the space ima after because uvedit_face_visible uses the space ima
- * to check if the face is displayed in UV-localview */
- sima->image= ima;
-
- if(ima == NULL || ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE)
- sima->flag &= ~SI_DRAWTOOL;
-
- if(sima->image)
- BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
-
- if(sima->image && sima->image->id.us==0)
- sima->image->id.us= 1;
-
- if(C) {
- if(obedit)
- WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
-
- ED_area_tag_redraw(CTX_wm_area(C));
- }
-}
-
-ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
-{
- ImBuf *ibuf;
-
- if(sima && sima->image) {
-#if 0
- if(sima->image->type==IMA_TYPE_R_RESULT && BIF_show_render_spare())
- return BIF_render_spare_imbuf();
- else
-#endif
- ibuf= BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r);
-
- if(ibuf && (ibuf->rect || ibuf->rect_float))
- return ibuf;
- }
-
- return NULL;
-}
-
-void ED_space_image_release_buffer(SpaceImage *sima, void *lock)
-{
- if(sima && sima->image)
- BKE_image_release_ibuf(sima->image, lock);
-}
-
-int ED_space_image_has_buffer(SpaceImage *sima)
-{
- ImBuf *ibuf;
- void *lock;
- int has_buffer;
-
- ibuf= ED_space_image_acquire_buffer(sima, &lock);
- has_buffer= (ibuf != NULL);
- ED_space_image_release_buffer(sima, lock);
-
- return has_buffer;
-}
-
-void ED_image_size(Image *ima, int *width, int *height)
-{
- ImBuf *ibuf= NULL;
- void *lock;
-
- if(ima)
- ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
-
- if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
- *width= ibuf->x;
- *height= ibuf->y;
- }
- else {
- *width= 256;
- *height= 256;
- }
-
- if(ima)
- BKE_image_release_ibuf(ima, lock);
-}
-
-void ED_space_image_size(SpaceImage *sima, int *width, int *height)
-{
- Scene *scene= sima->iuser.scene;
- ImBuf *ibuf;
- void *lock;
-
- ibuf= ED_space_image_acquire_buffer(sima, &lock);
-
- if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
- *width= ibuf->x;
- *height= ibuf->y;
- }
- else if(sima->image && sima->image->type==IMA_TYPE_R_RESULT && scene) {
- /* not very important, just nice */
- *width= (scene->r.xsch*scene->r.size)/100;
- *height= (scene->r.ysch*scene->r.size)/100;
- }
- /* I know a bit weak... but preview uses not actual image size */
- // XXX else if(image_preview_active(sima, width, height));
- else {
- *width= 256;
- *height= 256;
- }
-
- ED_space_image_release_buffer(sima, lock);
-}
-
-void ED_image_aspect(Image *ima, float *aspx, float *aspy)
-{
- *aspx= *aspy= 1.0;
-
- if((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) ||
- (ima->aspx==0.0 || ima->aspy==0.0))
- return;
-
- /* x is always 1 */
- *aspy = ima->aspy/ima->aspx;
-}
-
-void ED_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy)
-{
- ED_image_aspect(ED_space_image(sima), aspx, aspy);
-}
-
-void ED_space_image_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy)
-{
- int width, height;
-
- ED_space_image_size(sima, &width, &height);
-
- *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width);
- *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height);
-}
-
-void ED_space_image_uv_aspect(SpaceImage *sima, float *aspx, float *aspy)
-{
- int w, h;
-
- ED_space_image_aspect(sima, aspx, aspy);
- ED_space_image_size(sima, &w, &h);
-
- *aspx *= (float)w/256.0f;
- *aspy *= (float)h/256.0f;
-}
-
-void ED_image_uv_aspect(Image *ima, float *aspx, float *aspy)
-{
- int w, h;
-
- ED_image_aspect(ima, aspx, aspy);
- ED_image_size(ima, &w, &h);
-
- *aspx *= (float)w;
- *aspy *= (float)h;
-}
-
-int ED_space_image_show_render(SpaceImage *sima)
-{
- return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE));
-}
-
-int ED_space_image_show_paint(SpaceImage *sima)
-{
- if(ED_space_image_show_render(sima))
- return 0;
-
- return (sima->flag & SI_DRAWTOOL);
-}
-
-int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
-{
- if(ED_space_image_show_render(sima))
- return 0;
- if(ED_space_image_show_paint(sima))
- return 0;
-
- if(obedit && obedit->type == OB_MESH) {
- EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
- int ret;
-
- ret = EM_texFaceCheck(em);
-
- BKE_mesh_end_editmesh(obedit->data, em);
- return ret;
- }
-
- return 0;
-}
-
-int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
-{
- if(ED_space_image_show_render(sima))
- return 0;
-
- if(ED_space_image_show_paint(sima))
- if(obedit && obedit->type == OB_MESH) {
- EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
- int ret;
-
- ret = EM_texFaceCheck(em);
-
- BKE_mesh_end_editmesh(obedit->data, em);
- return ret;
- }
-
- return 0;
-}
-
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 5c5e316663c..3323183cb54 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -913,6 +913,28 @@ static void node_composit_buts_view_levels(uiLayout *layout, bContext *C, Pointe
uiItemR(layout, NULL, 0, ptr, "channel", UI_ITEM_R_EXPAND);
}
+static void node_composit_buts_colorbalance(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiLayout *split, *col, *row;
+
+ split = uiLayoutSplit(layout, 0, 0);
+ col = uiLayoutColumn(split, 0);
+ uiTemplateColorWheel(col, ptr, "lift", 1);
+ row = uiLayoutRow(col, 0);
+ uiItemR(row, NULL, 0, ptr, "lift", 0);
+
+ col = uiLayoutColumn(split, 0);
+ uiTemplateColorWheel(col, ptr, "gamma", 1);
+ row = uiLayoutRow(col, 0);
+ uiItemR(row, NULL, 0, ptr, "gamma", 0);
+
+ col = uiLayoutColumn(split, 0);
+ uiTemplateColorWheel(col, ptr, "gain", 1);
+ row = uiLayoutRow(col, 0);
+ uiItemR(row, NULL, 0, ptr, "gain", 0);
+
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -1042,9 +1064,12 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_PREMULKEY:
ntype->uifunc= node_composit_buts_premulkey;
break;
- case CMP_NODE_VIEW_LEVELS:
+ case CMP_NODE_VIEW_LEVELS:
ntype->uifunc=node_composit_buts_view_levels;
break;
+ case CMP_NODE_COLORBALANCE:
+ ntype->uifunc=node_composit_buts_colorbalance;
+ break;
default:
ntype->uifunc= NULL;
}
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 9b433c5bf8c..71b607247d3 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -300,6 +300,18 @@ typedef struct NodeLensDist {
short jit, proj, fit, pad;
} NodeLensDist;
+typedef struct NodeColorBalance {
+ /* for processing */
+ float slope[3];
+ float offset[3];
+ float power[3];
+
+ /* for ui representation */
+ float lift[3];
+ float gamma[3];
+ float gain[3];
+} NodeColorBalance;
+
/* TEX_output */
typedef struct TexNodeOutput {
char name[32];
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 2105e10bbd1..d151e911a9c 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -42,6 +42,8 @@
#include "BKE_image.h"
#include "BKE_texture.h"
+#include "BLI_math.h"
+
#include "WM_types.h"
#include "MEM_guardedalloc.h"
@@ -298,6 +300,23 @@ static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *p
rna_Node_update(bmain, scene, ptr);
}
+static void rna_Node_colorbalance_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bNode *node= (bNode*)ptr->data;
+ NodeColorBalance *ncb = node->storage;
+ float lift[3], gamma[3], gain[3];
+ float n_one[3] = {-1.f, -1.f, -1.f};
+
+ mul_v3_v3fl(lift, ncb->lift, 2.f);
+ add_v3_v3(lift, n_one);
+ mul_v3_v3fl(gamma, ncb->gamma, 2.f);
+ mul_v3_v3fl(gain, ncb->gain, 2.f);
+
+ lift_gamma_gain_to_asc_cdl(lift, gamma, gain, ncb->offset, ncb->slope, ncb->power);
+
+ rna_Node_update(bmain, scene, ptr);
+}
+
static EnumPropertyItem *renderresult_layers_add_enum(RenderLayer *rl)
{
EnumPropertyItem *item= NULL;
@@ -1854,6 +1873,38 @@ static void def_cmp_lensdist(StructRNA *srna)
RNA_def_property_ui_text(prop, "Fit", "For positive distortion factor only: scale image such that black areas are not visible");
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
}
+
+static void def_cmp_colorbalance(StructRNA *srna)
+{
+ PropertyRNA *prop;
+ static float default_col[3] = {0.5f, 0.5f, 0.5f};
+
+ RNA_def_struct_sdna_from(srna, "NodeColorBalance", "storage");
+
+ prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "lift");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_float_array_default(prop, default_col);
+ RNA_def_property_ui_range(prop, 0, 1, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Lift", "Correction for Shadows");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_colorbalance_update");
+
+ prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "gamma");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_float_array_default(prop, default_col);
+ RNA_def_property_ui_range(prop, 0, 1, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Gamma", "Correction for Midtones");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_colorbalance_update");
+
+ prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "gain");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_float_array_default(prop, default_col);
+ RNA_def_property_ui_range(prop, 0, 1, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Gain", "Correction for Highlights");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_colorbalance_update");
+}
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index d9a1db996de..936832221f9 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -107,6 +107,7 @@ DefNode( CompositorNode, CMP_NODE_LENSDIST, def_cmp_lensdist, "LENSD
DefNode( CompositorNode, CMP_NODE_VIEW_LEVELS, def_cmp_levels, "LEVELS", Levels, "Levels", "" )
DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR_MATTE", ColorMatte, "Color Matte", "" )
DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Matte", "" )
+DefNode( CompositorNode, CMP_NODE_COLORBALANCE, def_cmp_colorbalance, "COLORBALANCE", ColorBalance, "Color Balance", "" )
DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/CMP_node.h
index 041bf1c8361..8c3f4f4a847 100644
--- a/source/blender/nodes/CMP_node.h
+++ b/source/blender/nodes/CMP_node.h
@@ -59,6 +59,7 @@ extern bNodeType cmp_node_gamma;
extern bNodeType cmp_node_invert;
extern bNodeType cmp_node_alphaover;
extern bNodeType cmp_node_zcombine;
+extern bNodeType cmp_node_colorbalance;
extern bNodeType cmp_node_normal;
extern bNodeType cmp_node_curve_vec;
diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h
index 5c8ed19a8d1..6cfcd03fdc8 100644
--- a/source/blender/nodes/intern/node_util.h
+++ b/source/blender/nodes/intern/node_util.h
@@ -40,3 +40,14 @@ extern void node_copy_standard_storage(struct bNode *orig_node, struct bNode *ne
#endif
+// this is needed for inlining behaviour
+#if defined _WIN32
+# define DO_INLINE __inline
+#elif defined (__sgi)
+# define DO_INLINE
+#elif defined (__sun) || defined (__sun__)
+# define DO_INLINE
+#else
+# define DO_INLINE static inline
+#endif
+