Blender V5.0
node_composite_levels.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2006 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cmath>
10
11#include "BLI_math_vector.hh"
13
14#include "RNA_types.hh"
15
17
19#include "COM_node_operation.hh"
20
22
24
26 {CMP_NODE_LEVLES_LUMINANCE, "COMBINED_RGB", 0, N_("Combined"), N_("Combined RGB")},
27 {CMP_NODE_LEVLES_RED, "RED", 0, N_("Red"), N_("Red Channel")},
28 {CMP_NODE_LEVLES_GREEN, "GREEN", 0, N_("Green"), N_("Green Channel")},
29 {CMP_NODE_LEVLES_BLUE, "BLUE", 0, N_("Blue"), N_("Blue Channel")},
30 {CMP_NODE_LEVLES_LUMINANCE_BT709, "LUMINANCE", 0, N_("Luminance"), N_("Luminance Channel")},
31 {0, nullptr, 0, nullptr, nullptr},
32};
33
35{
36 b.add_input<decl::Color>("Image")
37 .default_value({0.0f, 0.0f, 0.0f, 1.0f})
38 .structure_type(StructureType::Dynamic);
39 b.add_input<decl::Menu>("Channel")
40 .default_value(CMP_NODE_LEVLES_LUMINANCE)
41 .static_items(channel_items)
43
44 b.add_output<decl::Float>("Mean");
45 b.add_output<decl::Float>("Standard Deviation");
46}
47
48using namespace blender::compositor;
49
51 private:
52 constexpr static float luminance_coefficients_bt709_[3] = {0.2126f, 0.7152f, 0.0722f};
53
54 public:
56
57 void execute() override
58 {
59 if (get_input("Image").is_single_value()) {
61 return;
62 }
63
64 const float mean = compute_mean();
65
66 Result &mean_result = get_result("Mean");
67 if (mean_result.should_compute()) {
68 mean_result.allocate_single_value();
69 mean_result.set_single_value(mean);
70 }
71
72 Result &standard_deviation_result = get_result("Standard Deviation");
73 if (standard_deviation_result.should_compute()) {
74 const float standard_deviation = compute_standard_deviation(mean);
75 standard_deviation_result.allocate_single_value();
76 standard_deviation_result.set_single_value(standard_deviation);
77 }
78 }
79
81 {
82 Result &standard_deviation_result = get_result("Standard Deviation");
83 if (standard_deviation_result.should_compute()) {
84 standard_deviation_result.allocate_single_value();
85 standard_deviation_result.set_single_value(0.0f);
86 }
87
88 Result &mean_result = get_result("Mean");
89 if (!mean_result.should_compute()) {
90 return;
91 }
92
93 mean_result.allocate_single_value();
94 const float3 input = float3(get_input("Image").get_single_value<float4>());
95
96 switch (get_channel()) {
98 mean_result.set_single_value(input.x);
99 break;
101 mean_result.set_single_value(input.y);
102 break;
104 mean_result.set_single_value(input.z);
105 break;
107 mean_result.set_single_value(math::dot(input, float3(luminance_coefficients_bt709_)));
108 break;
110 float luminance_coefficients[3];
112 mean_result.set_single_value(math::dot(input, float3(luminance_coefficients)));
113 break;
114 }
115 }
116 }
117
119 {
120 const Result &input = get_input("Image");
121 return compute_sum() / (input.domain().size.x * input.domain().size.y);
122 }
123
125 {
126 const Result &input = get_input("Image");
127 switch (get_channel()) {
129 return sum_red(context(), input);
131 return sum_green(context(), input);
133 return sum_blue(context(), input);
135 return sum_luminance(context(), input, float3(luminance_coefficients_bt709_));
137 float luminance_coefficients[3];
139 return sum_luminance(context(), input, float3(luminance_coefficients));
140 }
141 }
142
143 return 0.0f;
144 }
145
147 {
148 const Result &input = get_input("Image");
149 const float sum = compute_sum_squared_difference(mean);
150 return std::sqrt(sum / (input.domain().size.x * input.domain().size.y));
151 }
152
153 float compute_sum_squared_difference(float subtrahend)
154 {
155 const Result &input = get_input("Image");
156 switch (get_channel()) {
158 return sum_red_squared_difference(context(), input, subtrahend);
160 return sum_green_squared_difference(context(), input, subtrahend);
162 return sum_blue_squared_difference(context(), input, subtrahend);
165 context(), input, float3(luminance_coefficients_bt709_), subtrahend);
167 float luminance_coefficients[3];
170 context(), input, float3(luminance_coefficients), subtrahend);
171 }
172 }
173
174 return 0.0f;
175 }
176
178 {
179 const Result &input = this->get_input("Channel");
180 const MenuValue default_menu_value = MenuValue(CMP_NODE_LEVLES_LUMINANCE);
181 const MenuValue menu_value = input.get_single_value_default(default_menu_value);
182 return static_cast<CMPNodeLevelsChannel>(menu_value.value);
183 }
184};
185
187{
188 return new LevelsOperation(context, node);
189}
190
191} // namespace blender::nodes::node_composite_levels_cc
192
194{
196
197 static blender::bke::bNodeType ntype;
198
199 cmp_node_type_base(&ntype, "CompositorNodeLevels", CMP_NODE_VIEW_LEVELS);
200 ntype.ui_name = "Levels";
201 ntype.ui_description = "Compute average and standard deviation of pixel values";
202 ntype.enum_name_legacy = "LEVELS";
204 ntype.declare = file_ns::cmp_node_levels_declare;
205 ntype.flag |= NODE_PREVIEW;
206 ntype.get_compositor_operation = file_ns::get_compositor_operation;
207
209}
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:453
#define CMP_NODE_VIEW_LEVELS
@ NODE_PREVIEW
CMPNodeLevelsChannel
@ CMP_NODE_LEVLES_LUMINANCE
@ CMP_NODE_LEVLES_GREEN
@ CMP_NODE_LEVLES_LUMINANCE_BT709
@ CMP_NODE_LEVLES_RED
@ CMP_NODE_LEVLES_BLUE
BLI_INLINE void IMB_colormanagement_get_luminance_coefficients(float r_rgb[3])
#define NOD_REGISTER_NODE(REGISTER_FUNC)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
static T sum(const btAlignedObjectArray< T > &items)
NodeOperation(Context &context, DNode node)
Result & get_result(StringRef identifier)
Definition operation.cc:39
Result & get_input(StringRef identifier) const
Definition operation.cc:138
void set_single_value(const T &value)
#define input
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
float sum_red(Context &context, const Result &result)
float sum_red_squared_difference(Context &context, const Result &result, const float subtrahend)
float sum_luminance(Context &context, const Result &result, const float3 &luminance_coefficients)
float sum_blue_squared_difference(Context &context, const Result &result, const float subtrahend)
float sum_luminance_squared_difference(Context &context, const Result &result, const float3 &luminance_coefficients, const float subtrahend)
float sum_green_squared_difference(Context &context, const Result &result, const float subtrahend)
float sum_green(Context &context, const Result &result)
float sum_blue(Context &context, const Result &result)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
static void cmp_node_levels_declare(NodeDeclarationBuilder &b)
static const EnumPropertyItem channel_items[]
static NodeOperation * get_compositor_operation(Context &context, DNode node)
VecBase< float, 3 > float3
static void register_node_type_cmp_view_levels()
void cmp_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
NodeGetCompositorOperationFunction get_compositor_operation
Definition BKE_node.hh:348
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:362
#define N_(msgid)