diff options
author | Matt Ebb <matt@mke3.net> | 2010-01-27 03:22:29 +0300 |
---|---|---|
committer | Matt Ebb <matt@mke3.net> | 2010-01-27 03:22:29 +0300 |
commit | 0bb36e9ced06b04b961300b21211f456c7035bcf (patch) | |
tree | 9e38b0b5e9b84a22a7a03c5cad4139106168685c /source/blender | |
parent | ebafb7e484fa45aed0f4be75cfb5d570d7d43f81 (diff) |
Fixes to Color Balance node:
* The Lift/Gamma/Gain formula previously was incorrect, fixed this and
removed conversions - now the RNA values are the same as what goes into
the formula.
* Because of this, added the ability for the Value slider to map to a wider range
than 0.0-1.0. The black/white gradient remains the same, in this case just
indicating darker/brighter rather than absolute colour values. Also added ability
for color wheels to be locked at full brightness (useful for this case, where the
color value itself is dark).
* Added an alternate formula - offset/power/slope (asc-cdl). This fits the standard
Color Decision List formula, here for compatibility with other systems, though
default Lift/Gamma/Gain is easier to use and gives nicer results.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 8 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 9 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 11 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 51 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 70 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ui_api.c | 1 | ||||
-rw-r--r-- | source/blender/nodes/intern/CMP_nodes/CMP_colorbalance.c | 88 |
8 files changed, 170 insertions, 70 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 309cee7cb9c..c94f20da459 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -677,7 +677,7 @@ void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struc void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand); void uiTemplateHistogram(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand); void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, char *propname, int type, int levels, int brush); -void uiTemplateColorWheel(uiLayout *layout, struct PointerRNA *ptr, char *propname, int value_slider); +void uiTemplateColorWheel(uiLayout *layout, struct PointerRNA *ptr, char *propname, int value_slider, int lock); void uiTemplateTriColorSet(uiLayout *layout, struct PointerRNA *ptr, char *propname); void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname, PointerRNA *used_ptr, char *used_propname, int active_layer); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index b84bdcd958e..bb3709295f8 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2872,10 +2872,18 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, hsv[2]= x; } else if (but->a1==9){ + float range; + /* vertical 'value' strip */ hsv[2]= y; + + /* exception only for value strip - use the range set in but->min/max */ + range = but->softmax - but->softmin; + hsv[2] = y*range + but->softmin; + if (color_profile) hsv[2] = srgb_to_linearrgb(hsv[2]); + } hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 264bc724bce..44f653669f2 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1965,26 +1965,29 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, char *propname, i #define WHEEL_SIZE 100 -void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, char *propname, int value_slider) +void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, char *propname, int value_slider, int lock) { PropertyRNA *prop= RNA_struct_find_property(ptr, propname); uiBlock *block= uiLayoutGetBlock(layout); uiLayout *col, *row; + float softmin, softmax, step, precision; if (!prop) { printf("uiTemplateColorWheel: property not found: %s\n", propname); return; } + RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); + col = uiLayoutColumn(layout, 0); row= uiLayoutRow(col, 1); - uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 0, 0, ""); + uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 0, lock, ""); uiItemS(row); if (value_slider) - uiDefButR(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 9, 0, ""); + uiDefButR(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, propname, -1, softmin, softmax, 9, 0, ""); /* maybe a switch for this? row= uiLayoutRow(col, 0); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index d9e8f6f55d2..aeea7d4a354 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1577,6 +1577,11 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, rcti *rect) rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); copy_v3_v3(hsvo, hsv); + /* exception: if 'lock' is set (stored in but->a2), + * lock the value of the color wheel to 1. + * Useful for color correction tools where you're only interested in hue. */ + if (but->a2) hsv[2] = 1.f; + hsv_to_rgb(0.f, 0.f, hsv[2], colcent, colcent+1, colcent+2); glShadeModel(GL_SMOOTH); @@ -1793,7 +1798,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) uiWidgetBase wtb; float rad= 0.5f*(rect->xmax - rect->xmin); float x, y; - float rgb[3], hsv[3], v; + float rgb[3], hsv[3], v, range; int color_profile = but->block->color_profile; if (but->rnaprop) { @@ -1808,6 +1813,10 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) if (color_profile) v = linearrgb_to_srgb(v); + + /* map v from property range to [0,1] */ + range = but->softmax - but->softmin; + v = (v - but->softmin)/range; widget_init(&wtb); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 3092aaba507..fe5c7bca3a6 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -125,7 +125,7 @@ static void node_buts_rgb(uiLayout *layout, bContext *C, PointerRNA *ptr) RNA_property_collection_lookup_int(ptr, prop, 0, &sockptr); col = uiLayoutColumn(layout, 0); - uiTemplateColorWheel(col, &sockptr, "default_value", 1); + uiTemplateColorWheel(col, &sockptr, "default_value", 1, 0); uiItemR(col, "", 0, &sockptr, "default_value", 0); } @@ -917,21 +917,44 @@ static void node_composit_buts_colorbalance(uiLayout *layout, bContext *C, Point { 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); + uiItemR(layout, NULL, 0, ptr, "correction_formula", 0); - col = uiLayoutColumn(split, 0); - uiTemplateColorWheel(col, ptr, "gamma", 1); - row = uiLayoutRow(col, 0); - uiItemR(row, NULL, 0, ptr, "gamma", 0); + if (RNA_enum_get(ptr, "correction_formula")== 0) { - col = uiLayoutColumn(split, 0); - uiTemplateColorWheel(col, ptr, "gain", 1); - row = uiLayoutRow(col, 0); - uiItemR(row, NULL, 0, ptr, "gain", 0); + split = uiLayoutSplit(layout, 0, 0); + col = uiLayoutColumn(split, 0); + uiTemplateColorWheel(col, ptr, "lift", 1, 1); + row = uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "lift", 0); + + col = uiLayoutColumn(split, 0); + uiTemplateColorWheel(col, ptr, "gamma", 1, 1); + row = uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "gamma", 0); + + col = uiLayoutColumn(split, 0); + uiTemplateColorWheel(col, ptr, "gain", 1, 1); + row = uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "gain", 0); + + } else { + + split = uiLayoutSplit(layout, 0, 0); + col = uiLayoutColumn(split, 0); + uiTemplateColorWheel(col, ptr, "offset", 1, 1); + row = uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "offset", 0); + + col = uiLayoutColumn(split, 0); + uiTemplateColorWheel(col, ptr, "power", 1, 1); + row = uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "power", 0); + + col = uiLayoutColumn(split, 0); + uiTemplateColorWheel(col, ptr, "slope", 1, 1); + row = uiLayoutRow(col, 0); + uiItemR(row, NULL, 0, ptr, "slope", 0); + } } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index fa14bea4228..8b9eb00e96a 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -300,24 +300,6 @@ 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]; - - lift[0] = (ncb->lift[0] * 2.f - 1.f)*0.5f; - lift[1] = (ncb->lift[1] * 2.f - 1.f)*0.5f; - lift[2] = (ncb->lift[2] * 2.f - 1.f)*0.5f; - - 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; @@ -1878,33 +1860,67 @@ static void def_cmp_lensdist(StructRNA *srna) static void def_cmp_colorbalance(StructRNA *srna) { PropertyRNA *prop; - static float default_col[3] = {0.5f, 0.5f, 0.5f}; + static float default_1[3] = {1.f, 1.f, 1.f}; + + static EnumPropertyItem type_items[] = { + {0, "LIFT_GAMMA_GAIN", 0, "Lift/Gamma/Gain", ""}, + {1, "OFFSET_POWER_SLOPE", 0, "Offset/Power/Slope (ASC-CDL)", "ASC-CDL standard color correction"}, + {0, NULL, 0, NULL, NULL}}; + + prop = RNA_def_property(srna, "correction_formula", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, type_items); + RNA_def_property_ui_text(prop, "Correction Formula", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); 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"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_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_float_array_default(prop, default_1); + RNA_def_property_ui_range(prop, 0, 2, 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"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_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_float_array_default(prop, default_1); + RNA_def_property_ui_range(prop, 0, 2, 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"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + + prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "lift"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_range(prop, 0, 1, 0.1, 3); + RNA_def_property_ui_text(prop, "Offset", "Correction for Shadows"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "power", 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_1); + RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); + RNA_def_property_ui_text(prop, "Power", "Correction for Midtones"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "slope", 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_1); + RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); + RNA_def_property_ui_text(prop, "Slope", "Correction for Highlights"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); } static void def_cmp_huecorrect(StructRNA *srna) diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index cd7051fc171..07bf20b0c03 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -344,6 +344,7 @@ void RNA_api_ui_layout(StructRNA *srna) func= RNA_def_function(srna, "template_color_wheel", "uiTemplateColorWheel"); api_ui_item_rna_common(func); RNA_def_boolean(func, "value_slider", 0, "", "Display the value slider to the right of the color wheel"); + RNA_def_boolean(func, "lock", 0, "", "Lock the color wheel display to value 1.0 regardless of actual color"); func= RNA_def_function(srna, "template_triColorSet", "uiTemplateTriColorSet"); api_ui_item_rna_common(func); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_colorbalance.c b/source/blender/nodes/intern/CMP_nodes/CMP_colorbalance.c index 9d3a670fad2..09dccd8e3c4 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_colorbalance.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_colorbalance.c @@ -43,34 +43,66 @@ static bNodeSocketType cmp_node_colorbalance_out[]={ {-1,0,""} }; -DO_INLINE float colorbalance(float in, float slope, float offset, float power) +DO_INLINE float colorbalance_cdl(float in, float offset, float power, float slope) { float x = in * slope + offset; /* prevent NaN */ if (x < 0.f) x = 0.f; - return powf(x, power); + //powf(in * slope + offset, power) + return powf(x, 1.f/power); } -static void do_colorbalance(bNode *node, float* out, float *in) +DO_INLINE float colorbalance_lgg(float in, float lift, float gamma, float gain) +{ + float x = gain*(in+lift*(1-in)); + + /* prevent NaN */ + if (x < 0.f) x = 0.f; + + return powf(x, (1.f/gamma)); +} + +static void do_colorbalance_cdl(bNode *node, float* out, float *in) { NodeColorBalance *n= (NodeColorBalance *)node->storage; - out[0] = colorbalance(in[0], n->slope[0], n->offset[0], n->power[0]); - out[1] = colorbalance(in[1], n->slope[1], n->offset[1], n->power[1]); - out[2] = colorbalance(in[2], n->slope[2], n->offset[2], n->power[2]); + out[0] = colorbalance_cdl(in[0], n->lift[0], n->gamma[0], n->gain[0]); + out[1] = colorbalance_cdl(in[1], n->lift[1], n->gamma[1], n->gain[1]); + out[2] = colorbalance_cdl(in[2], n->lift[2], n->gamma[2], n->gain[2]); out[3] = in[3]; } -static void do_colorbalance_fac(bNode *node, float* out, float *in, float *fac) +static void do_colorbalance_cdl_fac(bNode *node, float* out, float *in, float *fac) { NodeColorBalance *n= (NodeColorBalance *)node->storage; const float mfac= 1.0f - *fac; - out[0] = mfac*in[0] + *fac * colorbalance(in[0], n->slope[0], n->offset[0], n->power[0]); - out[1] = mfac*in[1] + *fac * colorbalance(in[1], n->slope[1], n->offset[1], n->power[1]); - out[2] = mfac*in[2] + *fac * colorbalance(in[2], n->slope[2], n->offset[2], n->power[2]); + out[0] = mfac*in[0] + *fac * colorbalance_cdl(in[0], n->lift[0], n->gamma[0], n->gain[0]); + out[1] = mfac*in[1] + *fac * colorbalance_cdl(in[1], n->lift[1], n->gamma[1], n->gain[1]); + out[2] = mfac*in[2] + *fac * colorbalance_cdl(in[2], n->lift[2], n->gamma[2], n->gain[2]); + out[3] = in[3]; +} + +static void do_colorbalance_lgg(bNode *node, float* out, float *in) +{ + NodeColorBalance *n= (NodeColorBalance *)node->storage; + + out[0] = colorbalance_lgg(in[0], n->lift[0], n->gamma[0], n->gain[0]); + out[1] = colorbalance_lgg(in[1], n->lift[1], n->gamma[1], n->gain[1]); + out[2] = colorbalance_lgg(in[2], n->lift[2], n->gamma[2], n->gain[2]); + out[3] = in[3]; +} + +static void do_colorbalance_lgg_fac(bNode *node, float* out, float *in, float *fac) +{ + NodeColorBalance *n= (NodeColorBalance *)node->storage; + const float mfac= 1.0f - *fac; + + out[0] = mfac*in[0] + *fac * colorbalance_lgg(in[0], n->lift[0], n->gamma[0], n->gain[0]); + out[1] = mfac*in[1] + *fac * colorbalance_lgg(in[1], n->lift[1], n->gamma[1], n->gain[1]); + out[2] = mfac*in[2] + *fac * colorbalance_lgg(in[2], n->lift[2], n->gamma[2], n->gain[2]); out[3] = in[3]; } @@ -90,12 +122,24 @@ static void node_composit_exec_colorbalance(void *data, bNode *node, bNodeStack if (cbuf) { stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* create output based on image input */ - - if ((in[0]->data==NULL) && (in[0]->vec[0] == 1.f)) { - composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_colorbalance, CB_RGBA); - } - else { - composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_colorbalance_fac, CB_RGBA, CB_VAL); + + if (node->custom1 == 0) { + /* lift gamma gain */ + if ((in[0]->data==NULL) && (in[0]->vec[0] >= 1.f)) { + composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_colorbalance_lgg, CB_RGBA); + } + else { + composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_colorbalance_lgg_fac, CB_RGBA, CB_VAL); + } + } else { + /* offset/power/slope : ASC-CDL */ + if ((in[0]->data==NULL) && (in[0]->vec[0] >= 1.f)) { + composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_colorbalance_cdl, CB_RGBA); + } + else { + composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_colorbalance_cdl_fac, CB_RGBA, CB_VAL); + } + } out[0]->data=stackbuf; @@ -105,14 +149,10 @@ static void node_composit_exec_colorbalance(void *data, bNode *node, bNodeStack static void node_composit_init_colorbalance(bNode *node) { NodeColorBalance *n= node->storage= MEM_callocN(sizeof(NodeColorBalance), "node colorbalance"); - n->slope[0] = n->slope[1] = n->slope[2] = 1.f; - n->offset[0] = n->offset[1] = n->offset[2] = 0.f; - n->power[0] = n->power[1] = n->power[2] = 1.f; - - /* for ui, converted to slope/offset/power in RNA */ - n->lift[0] = n->lift[1] = n->lift[2] = 0.5f; - n->gamma[0] = n->gamma[1] = n->gamma[2] = 0.5f; - n->gain[0] = n->gain[1] = n->gain[2] = 0.5f; + + n->lift[0] = n->lift[1] = n->lift[2] = 0.0f; + n->gamma[0] = n->gamma[1] = n->gamma[2] = 1.0f; + n->gain[0] = n->gain[1] = n->gain[2] = 1.0f; } bNodeType cmp_node_colorbalance={ |