From 59eebc8654420463e8d20f902c7ee9a0401ee4bf Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 25 Sep 2025 15:00:02 +0200 Subject: [PATCH] Color Management: Add "Working Space" as a color space choice in the enum And make it the default in the compositing Convert Color Space node. This is useful to create compositing nodes that give the same result regardless of the working space, particularly for node group assets. For example you might convert from the working space to a log space, do some color correction operations and convert back. I'm less certain about including this also for images. I can imagine use cases for that too, for example with an Image node in the compositor that is known to read back the EXR sequence written from the current scene. But it's a bit more obscure and there is some potential for using this when it's not appropriate. Still there is nothing that automatically selects it, so it seems fine. Ref #144911 Pull Request: https://projects.blender.org/blender/blender/pulls/146598 --- .../blender/imbuf/intern/colormanagement.cc | 25 +++++++++++++++++++ .../node_composite_convert_color_space.cc | 12 ++------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/source/blender/imbuf/intern/colormanagement.cc b/source/blender/imbuf/intern/colormanagement.cc index cf039ac46d5..d1b1a5cf964 100644 --- a/source/blender/imbuf/intern/colormanagement.cc +++ b/source/blender/imbuf/intern/colormanagement.cc @@ -3140,6 +3140,12 @@ const ColorSpace *colormanage_colorspace_get_roled(const int role) int IMB_colormanagement_colorspace_get_named_index(const char *name) { + /* Roles. */ + if (STREQ(name, OCIO_ROLE_SCENE_LINEAR)) { + return g_config->get_num_color_spaces(); + } + + /* Regular color spaces. */ const ColorSpace *colorspace = colormanage_colorspace_get_named(name); if (colorspace) { return colorspace->index; @@ -3149,6 +3155,12 @@ int IMB_colormanagement_colorspace_get_named_index(const char *name) const char *IMB_colormanagement_colorspace_get_indexed_name(const int index) { + /* Roles. */ + if (index == g_config->get_num_color_spaces()) { + return OCIO_ROLE_SCENE_LINEAR; + } + + /* Regular color spaces. */ const ColorSpace *colorspace = g_config->get_color_space_by_index(index); if (colorspace) { return colorspace->name().c_str(); @@ -3747,6 +3759,7 @@ void IMB_colormanagement_look_items_add(EnumPropertyItem **items, void IMB_colormanagement_colorspace_items_add(EnumPropertyItem **items, int *totitem) { + /* Regular color spaces. */ for (const int colorspace_index : blender::IndexRange(g_config->get_num_color_spaces())) { const ColorSpace *colorspace = g_config->get_sorted_color_space_by_index(colorspace_index); if (!colorspace->is_invertible()) { @@ -3763,6 +3776,18 @@ void IMB_colormanagement_colorspace_items_add(EnumPropertyItem **items, int *tot RNA_enum_item_add(items, totitem, &item); } + + /* Scene linear role. This is useful for example to create compositing convert colorspace + * nodes that work the same regardless of working space. */ + EnumPropertyItem item; + + item.value = g_config->get_num_color_spaces(); + item.name = "Working Space"; + item.identifier = OCIO_ROLE_SCENE_LINEAR; + item.icon = 0; + item.description = "Working color space of the current file"; + + RNA_enum_item_add(items, totitem, &item); } /** \} */ diff --git a/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc b/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc index ce788afb438..9912b2e8804 100644 --- a/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc +++ b/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc @@ -37,16 +37,8 @@ static void CMP_NODE_CONVERT_COLOR_SPACE_declare(NodeDeclarationBuilder &b) static void node_composit_init_convert_colorspace(bNodeTree * /*ntree*/, bNode *node) { NodeConvertColorSpace *ncs = MEM_callocN("node colorspace"); - const char *first_colorspace = IMB_colormanagement_role_colorspace_name_get( - COLOR_ROLE_SCENE_LINEAR); - if (first_colorspace && first_colorspace[0]) { - STRNCPY_UTF8(ncs->from_color_space, first_colorspace); - STRNCPY_UTF8(ncs->to_color_space, first_colorspace); - } - else { - ncs->from_color_space[0] = 0; - ncs->to_color_space[0] = 0; - } + STRNCPY_UTF8(ncs->from_color_space, "scene_linear"); + STRNCPY_UTF8(ncs->to_color_space, "scene_linear"); node->storage = ncs; }