Blender V4.5
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 "UI_interface.hh"
8#include "UI_resources.hh"
9
10#include "NOD_rna_define.hh"
11
12#include "RNA_enum_types.hh"
13
15
17
19{
20 b.is_function_node();
21 b.add_input<decl::Color>("Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
22 b.add_output<decl::Float>("Red");
23 b.add_output<decl::Float>("Green");
24 b.add_output<decl::Float>("Blue");
25 b.add_output<decl::Float>("Alpha");
26};
27
28static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
29{
30 layout->prop(ptr, "mode", UI_ITEM_NONE, "", ICON_NONE);
31}
32
33static void node_update(bNodeTree * /*tree*/, bNode *node)
34{
35 const NodeCombSepColor &storage = node_storage(*node);
37}
38
39static void node_init(bNodeTree * /*tree*/, bNode *node)
40{
43 node->storage = data;
44}
45
46class SeparateRGBAFunction : public mf::MultiFunction {
47 public:
49 {
50 static const mf::Signature signature = []() {
51 mf::Signature signature;
52 mf::SignatureBuilder builder{"Separate Color", signature};
53 builder.single_input<ColorGeometry4f>("Color");
54 builder.single_output<float>("Red", mf::ParamFlag::SupportsUnusedOutput);
55 builder.single_output<float>("Green", mf::ParamFlag::SupportsUnusedOutput);
56 builder.single_output<float>("Blue", mf::ParamFlag::SupportsUnusedOutput);
57 builder.single_output<float>("Alpha", mf::ParamFlag::SupportsUnusedOutput);
58 return signature;
59 }();
60 this->set_signature(&signature);
61 }
62
63 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
64 {
65 const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
66 "Color");
67
68 MutableSpan<float> red = params.uninitialized_single_output_if_required<float>(1, "Red");
69 MutableSpan<float> green = params.uninitialized_single_output_if_required<float>(2, "Green");
70 MutableSpan<float> blue = params.uninitialized_single_output_if_required<float>(3, "Blue");
71 MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
72
73 std::array<MutableSpan<float>, 4> outputs = {red, green, blue, alpha};
74 Vector<int> used_outputs;
75 if (!red.is_empty()) {
76 used_outputs.append(0);
77 }
78 if (!green.is_empty()) {
79 used_outputs.append(1);
80 }
81 if (!blue.is_empty()) {
82 used_outputs.append(2);
83 }
84 if (!alpha.is_empty()) {
85 used_outputs.append(3);
86 }
87
88 devirtualize_varray(colors, [&](auto colors) {
89 mask.foreach_segment_optimized([&](const auto segment) {
90 const int used_outputs_num = used_outputs.size();
91 const int *used_outputs_data = used_outputs.data();
92
93 for (const int64_t i : segment) {
94 const ColorGeometry4f &color = colors[i];
95 for (const int out_i : IndexRange(used_outputs_num)) {
96 const int channel = used_outputs_data[out_i];
97 outputs[channel][i] = color[channel];
98 }
99 }
100 });
101 });
102 }
103};
104
105class SeparateHSVAFunction : public mf::MultiFunction {
106 public:
108 {
109 static const mf::Signature signature = []() {
110 mf::Signature signature;
111 mf::SignatureBuilder builder{"Separate Color", signature};
112 builder.single_input<ColorGeometry4f>("Color");
113 builder.single_output<float>("Hue");
114 builder.single_output<float>("Saturation");
115 builder.single_output<float>("Value");
116 builder.single_output<float>("Alpha", mf::ParamFlag::SupportsUnusedOutput);
117 return signature;
118 }();
119 this->set_signature(&signature);
120 }
121
122 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
123 {
124 const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
125 "Color");
126 MutableSpan<float> hue = params.uninitialized_single_output<float>(1, "Hue");
127 MutableSpan<float> saturation = params.uninitialized_single_output<float>(2, "Saturation");
128 MutableSpan<float> value = params.uninitialized_single_output<float>(3, "Value");
129 MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
130
131 mask.foreach_index_optimized<int64_t>([&](const int64_t i) {
132 rgb_to_hsv(colors[i].r, colors[i].g, colors[i].b, &hue[i], &saturation[i], &value[i]);
133 });
134
135 if (!alpha.is_empty()) {
136 mask.foreach_index_optimized<int64_t>([&](const int64_t i) { alpha[i] = colors[i].a; });
137 }
138 }
139};
140
141class SeparateHSLAFunction : public mf::MultiFunction {
142 public:
144 {
145 static const mf::Signature signature = []() {
146 mf::Signature signature;
147 mf::SignatureBuilder builder{"Separate Color", signature};
148 builder.single_input<ColorGeometry4f>("Color");
149 builder.single_output<float>("Hue");
150 builder.single_output<float>("Saturation");
151 builder.single_output<float>("Lightness");
152 builder.single_output<float>("Alpha", mf::ParamFlag::SupportsUnusedOutput);
153 return signature;
154 }();
155 this->set_signature(&signature);
156 }
157
158 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
159 {
160 const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
161 "Color");
162 MutableSpan<float> hue = params.uninitialized_single_output<float>(1, "Hue");
163 MutableSpan<float> saturation = params.uninitialized_single_output<float>(2, "Saturation");
164 MutableSpan<float> lightness = params.uninitialized_single_output<float>(3, "Lightness");
165 MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
166
167 mask.foreach_index_optimized<int64_t>([&](const int64_t i) {
168 rgb_to_hsl(colors[i].r, colors[i].g, colors[i].b, &hue[i], &saturation[i], &lightness[i]);
169 });
170
171 if (!alpha.is_empty()) {
172 mask.foreach_index_optimized<int64_t>([&](const int64_t i) { alpha[i] = colors[i].a; });
173 }
174 }
175};
176
178{
179 const NodeCombSepColor &storage = node_storage(builder.node());
180
181 switch (storage.mode) {
184 builder.set_matching_fn(fn);
185 break;
186 }
189 builder.set_matching_fn(fn);
190 break;
191 }
194 builder.set_matching_fn(fn);
195 break;
196 }
197 default: {
199 break;
200 }
201 }
202}
203
204static void node_rna(StructRNA *srna)
205{
207 "mode",
208 "Mode",
209 "Mode of color processing",
212}
213
214static void node_register()
215{
216 static blender::bke::bNodeType ntype;
217
218 fn_node_type_base(&ntype, "FunctionNodeSeparateColor", FN_NODE_SEPARATE_COLOR);
219 ntype.ui_name = "Separate Color";
220 ntype.enum_name_legacy = "SEPARATE_COLOR";
222 ntype.declare = node_declare;
223 ntype.updatefunc = node_update;
224 ntype.initfunc = node_init;
226 ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
229
231
232 node_rna(ntype.rna_ext.srna);
233}
235
236} // namespace blender::nodes::node_fn_separate_color_cc
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:439
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1215
#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:2748
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:5603
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
Definition BLI_color.hh:342
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:240
const EnumPropertyItem rna_enum_node_combsep_color_items[]
StructRNA * srna
Definition RNA_types.hh:909
void * storage
ListBase outputs
Defines a node type.
Definition BKE_node.hh:226
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:277
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:344
const char * enum_name_legacy
Definition BKE_node.hh:235
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:355
void(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:269
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:4227