Blender V5.0
node_fn_separate_color.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include "BLI_math_color.h"
8
10#include "UI_resources.hh"
11
12#include "NOD_rna_define.hh"
13
14#include "RNA_enum_types.hh"
15
17
19
21{
22 b.is_function_node();
23 b.add_input<decl::Color>("Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
24 b.add_output<decl::Float>("Red");
25 b.add_output<decl::Float>("Green");
26 b.add_output<decl::Float>("Blue");
27 b.add_output<decl::Float>("Alpha");
28};
29
30static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
31{
32 layout->prop(ptr, "mode", UI_ITEM_NONE, "", ICON_NONE);
33}
34
35static void node_update(bNodeTree * /*tree*/, bNode *node)
36{
37 const NodeCombSepColor &storage = node_storage(*node);
39}
40
41static void node_init(bNodeTree * /*tree*/, bNode *node)
42{
45 node->storage = data;
46}
47
48class SeparateRGBAFunction : public mf::MultiFunction {
49 public:
51 {
52 static const mf::Signature signature = []() {
53 mf::Signature signature;
54 mf::SignatureBuilder builder{"Separate Color", signature};
55 builder.single_input<ColorGeometry4f>("Color");
56 builder.single_output<float>("Red", mf::ParamFlag::SupportsUnusedOutput);
57 builder.single_output<float>("Green", mf::ParamFlag::SupportsUnusedOutput);
58 builder.single_output<float>("Blue", mf::ParamFlag::SupportsUnusedOutput);
59 builder.single_output<float>("Alpha", mf::ParamFlag::SupportsUnusedOutput);
60 return signature;
61 }();
62 this->set_signature(&signature);
63 }
64
65 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
66 {
67 const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
68 "Color");
69
70 MutableSpan<float> red = params.uninitialized_single_output_if_required<float>(1, "Red");
71 MutableSpan<float> green = params.uninitialized_single_output_if_required<float>(2, "Green");
72 MutableSpan<float> blue = params.uninitialized_single_output_if_required<float>(3, "Blue");
73 MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
74
75 std::array<MutableSpan<float>, 4> outputs = {red, green, blue, alpha};
76 Vector<int> used_outputs;
77 if (!red.is_empty()) {
78 used_outputs.append(0);
79 }
80 if (!green.is_empty()) {
81 used_outputs.append(1);
82 }
83 if (!blue.is_empty()) {
84 used_outputs.append(2);
85 }
86 if (!alpha.is_empty()) {
87 used_outputs.append(3);
88 }
89
90 devirtualize_varray(colors, [&](auto colors) {
91 mask.foreach_segment_optimized([&](const auto segment) {
92 const int used_outputs_num = used_outputs.size();
93 const int *used_outputs_data = used_outputs.data();
94
95 for (const int64_t i : segment) {
96 const ColorGeometry4f &color = colors[i];
97 for (const int out_i : IndexRange(used_outputs_num)) {
98 const int channel = used_outputs_data[out_i];
99 outputs[channel][i] = color[channel];
100 }
101 }
102 });
103 });
104 }
105};
106
107class SeparateHSVAFunction : public mf::MultiFunction {
108 public:
110 {
111 static const mf::Signature signature = []() {
112 mf::Signature signature;
113 mf::SignatureBuilder builder{"Separate Color", signature};
114 builder.single_input<ColorGeometry4f>("Color");
115 builder.single_output<float>("Hue");
116 builder.single_output<float>("Saturation");
117 builder.single_output<float>("Value");
118 builder.single_output<float>("Alpha", mf::ParamFlag::SupportsUnusedOutput);
119 return signature;
120 }();
121 this->set_signature(&signature);
122 }
123
124 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
125 {
126 const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
127 "Color");
128 MutableSpan<float> hue = params.uninitialized_single_output<float>(1, "Hue");
129 MutableSpan<float> saturation = params.uninitialized_single_output<float>(2, "Saturation");
130 MutableSpan<float> value = params.uninitialized_single_output<float>(3, "Value");
131 MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
132
133 mask.foreach_index_optimized<int64_t>([&](const int64_t i) {
134 rgb_to_hsv(colors[i].r, colors[i].g, colors[i].b, &hue[i], &saturation[i], &value[i]);
135 });
136
137 if (!alpha.is_empty()) {
138 mask.foreach_index_optimized<int64_t>([&](const int64_t i) { alpha[i] = colors[i].a; });
139 }
140 }
141};
142
143class SeparateHSLAFunction : public mf::MultiFunction {
144 public:
146 {
147 static const mf::Signature signature = []() {
148 mf::Signature signature;
149 mf::SignatureBuilder builder{"Separate Color", signature};
150 builder.single_input<ColorGeometry4f>("Color");
151 builder.single_output<float>("Hue");
152 builder.single_output<float>("Saturation");
153 builder.single_output<float>("Lightness");
154 builder.single_output<float>("Alpha", mf::ParamFlag::SupportsUnusedOutput);
155 return signature;
156 }();
157 this->set_signature(&signature);
158 }
159
160 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
161 {
162 const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
163 "Color");
164 MutableSpan<float> hue = params.uninitialized_single_output<float>(1, "Hue");
165 MutableSpan<float> saturation = params.uninitialized_single_output<float>(2, "Saturation");
166 MutableSpan<float> lightness = params.uninitialized_single_output<float>(3, "Lightness");
167 MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
168
169 mask.foreach_index_optimized<int64_t>([&](const int64_t i) {
170 rgb_to_hsl(colors[i].r, colors[i].g, colors[i].b, &hue[i], &saturation[i], &lightness[i]);
171 });
172
173 if (!alpha.is_empty()) {
174 mask.foreach_index_optimized<int64_t>([&](const int64_t i) { alpha[i] = colors[i].a; });
175 }
176 }
177};
178
180{
181 const NodeCombSepColor &storage = node_storage(builder.node());
182
183 switch (storage.mode) {
186 builder.set_matching_fn(fn);
187 break;
188 }
191 builder.set_matching_fn(fn);
192 break;
193 }
196 builder.set_matching_fn(fn);
197 break;
198 }
199 default: {
201 break;
202 }
203 }
204}
205
206static void node_rna(StructRNA *srna)
207{
209 "mode",
210 "Mode",
211 "Mode of color processing",
214}
215
216static void node_register()
217{
218 static blender::bke::bNodeType ntype;
219
220 fn_node_type_base(&ntype, "FunctionNodeSeparateColor", FN_NODE_SEPARATE_COLOR);
221 ntype.ui_name = "Separate Color";
222 ntype.ui_description = "Split a color into separate channels, based on a particular color model";
223 ntype.enum_name_legacy = "SEPARATE_COLOR";
225 ntype.declare = node_declare;
226 ntype.updatefunc = node_update;
227 ntype.initfunc = node_init;
229 ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
232
234
235 node_rna(ntype.rna_ext.srna);
236}
238
239} // namespace blender::nodes::node_fn_separate_color_cc
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:453
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1240
#define FN_NODE_SEPARATE_COLOR
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
void rgb_to_hsl(float r, float g, float b, float *r_h, float *r_s, float *r_l)
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
NodeCombSepColorMode
@ NODE_COMBSEP_COLOR_RGB
@ NODE_COMBSEP_COLOR_HSV
@ NODE_COMBSEP_COLOR_HSL
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
#define UI_ITEM_NONE
BMesh const char void * data
long long int int64_t
int64_t size() const
void append(const T &value)
void set_signature(const Signature *signature)
void set_matching_fn(const mf::MultiFunction *fn)
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:5414
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
static void node_init(bNodeTree *, bNode *node)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_declare(NodeDeclarationBuilder &b)
static void node_update(bNodeTree *, bNode *node)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
void devirtualize_varray(const VArray< T > &varray, const Func &func, bool enable=true)
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
void fn_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
static blender::bke::bNodeSocketTemplate outputs[]
void node_free_standard_storage(bNode *node)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
void node_combsep_color_label(const ListBase *sockets, NodeCombSepColorMode mode)
Definition node_util.cc:227
const EnumPropertyItem rna_enum_node_combsep_color_items[]
StructRNA * srna
void * storage
ListBase outputs
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:351
const char * enum_name_legacy
Definition BKE_node.hh:247
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:259
NodeDeclareFunction declare
Definition BKE_node.hh:362
void(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:281
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
i
Definition text_draw.cc:230
PointerRNA * ptr
Definition wm_files.cc:4238