diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_sequencer.py | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/colortools.c | 80 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 13 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 8 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_color_types.h | 9 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_color.c | 19 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ui_api.c | 1 |
8 files changed, 118 insertions, 16 deletions
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 84ae59772b6..dd90968bca3 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -1248,7 +1248,7 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel): box.prop(mod, "color_multiply") draw_color_balance(box, mod.color_balance) elif mod.type == 'CURVES': - box.template_curve_mapping(mod, "curve_mapping", type='COLOR') + box.template_curve_mapping(mod, "curve_mapping", type='COLOR', show_tone=True) elif mod.type == 'HUE_CORRECT': box.template_curve_mapping(mod, "curve_mapping", type='HUE') elif mod.type == 'BRIGHT_CONTRAST': diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index d18572a57f6..ddf11d148cb 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -938,6 +938,21 @@ void curvemapping_evaluateRGBF(const CurveMapping *cumap, float vecout[3], const vecout[2] = curvemap_evaluateF(&cumap->cm[2], curvemap_evaluateF(&cumap->cm[3], vecin[2])); } +static void curvemapping_evaluateRGBF_filmlike(const CurveMapping *cumap, float vecout[3], const float vecin[3], + const int channel_offset[3]) +{ + const float v0in = vecin[channel_offset[0]]; + const float v1in = vecin[channel_offset[1]]; + const float v2in = vecin[channel_offset[2]]; + + const float v0 = curvemap_evaluateF(&cumap->cm[channel_offset[0]], v0in); + const float v2 = curvemap_evaluateF(&cumap->cm[channel_offset[2]], v2in); + const float v1 = v2 + ((v0 - v2) * (v1in - v2in) / (v0in - v2in)); + + vecout[channel_offset[0]] = v0; + vecout[channel_offset[1]] = v1; + vecout[channel_offset[2]] = v2; +} /** same as #curvemapping_evaluate_premulRGBF * but black/bwmul are passed as args for the compositor * where they can change per pixel. @@ -950,17 +965,70 @@ void curvemapping_evaluateRGBF(const CurveMapping *cumap, float vecout[3], const void curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap, float vecout[3], const float vecin[3], const float black[3], const float bwmul[3]) { - vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - black[0]) * bwmul[0]); - vecout[1] = curvemap_evaluateF(&cumap->cm[1], (vecin[1] - black[1]) * bwmul[1]); - vecout[2] = curvemap_evaluateF(&cumap->cm[2], (vecin[2] - black[2]) * bwmul[2]); + const float r = (vecin[0] - black[0]) * bwmul[0]; + const float g = (vecin[1] - black[1]) * bwmul[1]; + const float b = (vecin[2] - black[2]) * bwmul[2]; + + switch (cumap->tone) + { + default: + case CURVE_TONE_STANDARD: + { + vecout[0] = curvemap_evaluateF(&cumap->cm[0], r); + vecout[1] = curvemap_evaluateF(&cumap->cm[1], g); + vecout[2] = curvemap_evaluateF(&cumap->cm[2], b); + break; + } + case CURVE_TONE_FILMLIKE: + { + if (r >= g) { + if (g > b) { + /* Case 1: r >= g > b */ + const int shuffeled_channels[] = {0, 1, 2}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else if (b > r) { + /* Case 2: b > r >= g */ + const int shuffeled_channels[] = {2, 0, 1}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else if (b > g) { + /* Case 3: r >= b > g */ + const int shuffeled_channels[] = {0, 2, 1}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else { + /* Case 4: r >= g == b */ + copy_v2_fl2(vecout, curvemap_evaluateF(&cumap->cm[0], r), curvemap_evaluateF(&cumap->cm[1], g)); + vecout[2] = vecout[1]; + } + } + else { + if (r >= b) { + /* Case 5: g > r >= b */ + const int shuffeled_channels[] = {1, 0, 2}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else if (b > g) { + /* Case 6: b > g > r */ + const int shuffeled_channels[] = {2, 1, 0}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else { + /* Case 7: g >= b > r */ + const int shuffeled_channels[] = {1, 2, 0}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + } + break; + } + } } /* RGB with black/white points and premult. tables are checked */ void curvemapping_evaluate_premulRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3]) { - vecout[0] = curvemap_evaluateF(&cumap->cm[0], (vecin[0] - cumap->black[0]) * cumap->bwmul[0]); - vecout[1] = curvemap_evaluateF(&cumap->cm[1], (vecin[1] - cumap->black[1]) * cumap->bwmul[1]); - vecout[2] = curvemap_evaluateF(&cumap->cm[2], (vecin[2] - cumap->black[2]) * cumap->bwmul[2]); + curvemapping_evaluate_premulRGBF_ex(cumap, vecout, vecin, cumap->black, cumap->bwmul); } /* same as above, byte version */ diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 824920bce73..5cc3e369439 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1074,7 +1074,7 @@ void uiTemplateWaveform(uiLayout *layout, struct PointerRNA *ptr, const char *pr void uiTemplateVectorscope(uiLayout *layout, struct PointerRNA *ptr, const char *propname); void uiTemplateCurveMapping( uiLayout *layout, struct PointerRNA *ptr, const char *propname, int type, - bool levels, bool brush, bool neg_slope); + bool levels, bool brush, bool neg_slope, bool tone); void uiTemplateColorPicker(uiLayout *layout, struct PointerRNA *ptr, const char *propname, bool value_slider, bool lock, bool lock_luminosity, bool cubic); void uiTemplatePalette(uiLayout *layout, struct PointerRNA *ptr, const char *propname, bool color); void uiTemplateCryptoPicker(uiLayout *layout, struct PointerRNA *ptr, const char *propname); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index e81ad1428d1..820b34c1ac4 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2942,7 +2942,7 @@ static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v) /* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */ static void curvemap_buttons_layout( uiLayout *layout, PointerRNA *ptr, char labeltype, bool levels, - bool brush, bool neg_slope, RNAUpdateCb *cb) + bool brush, bool neg_slope, bool tone, RNAUpdateCb *cb) { CurveMapping *cumap = ptr->data; CurveMap *cm = &cumap->cm[cumap->cur]; @@ -2956,6 +2956,11 @@ static void curvemap_buttons_layout( block = uiLayoutGetBlock(layout); + if (tone) { + split = uiLayoutSplit(layout, 0.0f, false); + uiItemR(uiLayoutRow(split, false), ptr, "tone", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + } + /* curve chooser */ row = uiLayoutRow(layout, false); @@ -3107,7 +3112,7 @@ static void curvemap_buttons_layout( void uiTemplateCurveMapping( uiLayout *layout, PointerRNA *ptr, const char *propname, int type, - bool levels, bool brush, bool neg_slope) + bool levels, bool brush, bool neg_slope, bool tone) { RNAUpdateCb *cb; PropertyRNA *prop = RNA_struct_find_property(ptr, propname); @@ -3138,7 +3143,7 @@ void uiTemplateCurveMapping( id = cptr.id.data; UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE); - curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, cb); + curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, tone, cb); UI_block_lock_clear(block); @@ -4797,7 +4802,7 @@ void uiTemplateColormanagedViewSettings(uiLayout *layout, bContext *UNUSED(C), P col = uiLayoutColumn(layout, false); uiItemR(col, &view_transform_ptr, "use_curve_mapping", 0, NULL, ICON_NONE); if (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) - uiTemplateCurveMapping(col, &view_transform_ptr, "curve_mapping", 'c', true, false, false); + uiTemplateCurveMapping(col, &view_transform_ptr, "curve_mapping", 'c', true, false, false, false); } /********************************* Component Menu *************************************/ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 4dfbb92971b..2634b3108fa 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -144,7 +144,7 @@ static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt } #endif - uiTemplateCurveMapping(layout, ptr, "curve", 's', false, false, false); + uiTemplateCurveMapping(layout, ptr, "curve", 's', false, false, false, false); row = uiLayoutRow(layout, true); uiItemR(row, ptr, "frame_start", 0, IFACE_("Sta"), ICON_NONE); @@ -158,7 +158,7 @@ static void node_buts_colorramp(uiLayout *layout, bContext *UNUSED(C), PointerRN static void node_buts_curvevec(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { - uiTemplateCurveMapping(layout, ptr, "mapping", 'v', false, false, false); + uiTemplateCurveMapping(layout, ptr, "mapping", 'v', false, false, false, false); } #define SAMPLE_FLT_ISNONE FLT_MAX @@ -186,7 +186,7 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA cumap->flag &= ~CUMA_DRAW_SAMPLE; } - uiTemplateCurveMapping(layout, ptr, "mapping", 'c', false, false, false); + uiTemplateCurveMapping(layout, ptr, "mapping", 'c', false, false, false, true); } static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -1975,7 +1975,7 @@ static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C), cumap->flag &= ~CUMA_DRAW_SAMPLE; } - uiTemplateCurveMapping(layout, ptr, "mapping", 'h', false, false, false); + uiTemplateCurveMapping(layout, ptr, "mapping", 'h', false, false, false, false); } static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h index 4f860e16b88..fe158f85cd9 100644 --- a/source/blender/makesdna/DNA_color_types.h +++ b/source/blender/makesdna/DNA_color_types.h @@ -82,6 +82,9 @@ typedef struct CurveMapping { float bwmul[3]; /* black/white point multiply value, for speed */ float sample[3]; /* sample values, if flag set it draws line and intersection */ + + short tone; + short pad[3]; } CurveMapping; /* cumapping->flag */ @@ -102,6 +105,12 @@ typedef enum eCurveMappingPreset { CURVE_PRESET_GAUSS = 7, } eCurveMappingPreset; +/* CurveMapping->tone */ +typedef enum eCurveMappingTone { + CURVE_TONE_STANDARD = 0, + CURVE_TONE_FILMLIKE = 1, +} eCurveMappingTone; + /* histogram->mode */ enum { HISTO_MODE_LUMA = 0, diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 083551f2367..4cbe365167c 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -114,6 +114,12 @@ static void rna_CurveMapping_white_level_set(PointerRNA *ptr, const float *value curvemapping_set_black_white(cumap, NULL, NULL); } +static void rna_CurveMapping_tone_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +{ + WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); + WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL); +} + static void rna_CurveMapping_clipminx_range(PointerRNA *ptr, float *min, float *max, float *UNUSED(softmin), float *UNUSED(softmax)) { @@ -757,11 +763,24 @@ static void rna_def_curvemapping(BlenderRNA *brna) PropertyRNA *prop; FunctionRNA *func; + static const EnumPropertyItem tone_items[] = { + {CURVE_TONE_STANDARD, "STANDARD", 0, "Standard", ""}, + {CURVE_TONE_FILMLIKE, "FILMLIKE", 0, "Film like", ""}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "CurveMapping", NULL); RNA_def_struct_ui_text(srna, "CurveMapping", "Curve mapping to map color, vector and scalar values to other values using " "a user defined curve"); + prop = RNA_def_property(srna, "tone", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "tone"); + RNA_def_property_enum_items(prop, tone_items); + RNA_def_property_ui_text(prop, "Tone", "Tone of the curve"); + RNA_def_property_update(prop, 0, "rna_CurveMapping_tone_update"); + + prop = RNA_def_property(srna, "use_clip", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CUMA_DO_CLIP); RNA_def_property_ui_text(prop, "Clip", "Force the curve view to fit a defined boundary"); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index a5deb0a32f1..6abd0002e3e 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -883,6 +883,7 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_boolean(func, "levels", false, "", "Show black/white levels"); RNA_def_boolean(func, "brush", false, "", "Show brush options"); RNA_def_boolean(func, "use_negative_slope", false, "", "Use a negative slope by default"); + RNA_def_boolean(func, "show_tone", false, "", "Show tone options"); func = RNA_def_function(srna, "template_color_ramp", "uiTemplateColorRamp"); RNA_def_function_ui_description(func, "Item. A color ramp widget"); |