Blender V4.5
node_composite_relative_to_pixel.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_assert.h"
6#include "BLI_math_vector.hh"
8
9#include "UI_interface.hh"
10#include "UI_resources.hh"
11
12#include "NOD_rna_define.hh"
13
14#include "COM_node_operation.hh"
16
18
20
22{
23 b.add_input<decl::Vector>("Value", "Vector Value")
24 .subtype(PROP_FACTOR)
25 .dimensions(2)
26 .default_value({0.0f, 0.0f})
27 .min(0.0f)
28 .max(1.0f)
29 .description(
30 "A value that is relative to the image size and needs to be converted to be in pixels")
31 .compositor_expects_single_value();
32 b.add_input<decl::Float>("Value", "Float Value")
33 .default_value(0.0f)
35 .min(0.0f)
36 .max(1.0f)
37 .description(
38 "A value that is relative to the image size and needs to be converted to be in pixels")
39 .compositor_expects_single_value();
40 b.add_input<decl::Color>("Image").compositor_realization_mode(
42
43 b.add_output<decl::Float>("Value", "Float Value");
44 b.add_output<decl::Vector>("Value", "Vector Value").dimensions(2);
45}
46
52
53static void node_update(bNodeTree *ntree, bNode *node)
54{
55 const auto data_type = CMPNodeRelativeToPixelDataType(node->custom1);
56 const auto reference_dimension = CMPNodeRelativeToPixelReferenceDimension(node->custom2);
57
58 bNodeSocket *float_input = bke::node_find_socket(*node, SOCK_IN, "Float Value");
60 *ntree, *float_input, data_type == CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT);
61
62 bNodeSocket *vector_input = bke::node_find_socket(*node, SOCK_IN, "Vector Value");
64 *ntree, *vector_input, data_type == CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_VECTOR);
65
66 /* The float output doesn't exist if the reference is per dimension, since each dimension can be
67 * different. */
68 const bool is_per_dimension = reference_dimension ==
70 bNodeSocket *float_output = bke::node_find_socket(*node, SOCK_OUT, "Float Value");
72 *ntree,
73 *float_output,
74 data_type == CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT && !is_per_dimension);
75
76 /* The vector output exist if the reference is per dimension even if the data type is float,
77 * since each dimension can be different. */
78 bNodeSocket *vector_output = bke::node_find_socket(*node, SOCK_OUT, "Vector Value");
80 *ntree,
81 *vector_output,
82 data_type == CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_VECTOR || is_per_dimension);
83}
84
85static void node_rna(StructRNA *srna)
86{
87 static const EnumPropertyItem data_type_items[] = {
88 {CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT, "FLOAT", ICON_NONE, "Float", "Float value"},
89 {CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_VECTOR, "VECTOR", ICON_NONE, "Vector", "Vector value"},
90 {0, nullptr, 0, nullptr, nullptr},
91 };
92
94 "data_type",
95 "Data Type",
96 "The type of data",
97 data_type_items,
100 nullptr,
101 true);
102
103 static const EnumPropertyItem reference_dimension_items[] = {
105 "PER_DIMENSION",
106 ICON_NONE,
107 "Per Dimension",
108 "The value is relative to each of the dimensions of the image independently"},
110 "X",
111 ICON_NONE,
112 "X",
113 "The value is relative to the X dimension of the image"},
115 "Y",
116 ICON_NONE,
117 "Y",
118 "The value is relative to the Y dimension of the image"},
120 "Greater",
121 ICON_NONE,
122 "Greater",
123 "The value is relative to the greater dimension of the image"},
125 "Smaller",
126 ICON_NONE,
127 "Smaller",
128 "The value is relative to the smaller dimension of the image"},
130 "Diagonal",
131 ICON_NONE,
132 "Diagonal",
133 "The value is relative to the diagonal of the image"},
134 {0, nullptr, 0, nullptr, nullptr},
135 };
136
138 srna,
139 "reference_dimension",
140 "Reference Dimension",
141 "Defines the dimension of the image that the relative value is in reference to",
142 reference_dimension_items,
145 nullptr,
146 true);
147}
148
149static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
150{
151 layout->prop(ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
152 layout->prop(ptr, "reference_dimension", UI_ITEM_NONE, "", ICON_NONE);
153}
154
155using namespace blender::compositor;
156
158 public:
160 {
161 InputDescriptor &image_descriptor = this->get_input_descriptor("Image");
162 image_descriptor.skip_type_conversion = true;
163 }
164
165 void execute() override
166 {
167 const float2 input_value = this->get_input_value();
168 const float2 reference_size = this->compute_reference_size();
169
170 const float2 value_in_pixels = input_value * reference_size;
171
172 /* The float output doesn't exist if the reference is per dimension, since each dimension can
173 * be different. */
174 const bool is_per_dimension = this->get_reference_dimension() ==
176 if (this->get_data_type() == CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT && !is_per_dimension) {
177 Result &output_float_value = this->get_result("Float Value");
178 if (output_float_value.should_compute()) {
179 output_float_value.allocate_single_value();
180 /* Both values of the float2 are identical in this case, so just set the x component. */
181 output_float_value.set_single_value(value_in_pixels.x);
182 }
183 }
184
185 /* The vector output exist if the reference is per dimension even if the data type is float,
186 * since each dimension can be different. */
187 if (this->get_data_type() == CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_VECTOR || is_per_dimension) {
188 Result &output_vector_value = this->get_result("Vector Value");
189 if (output_vector_value.should_compute()) {
190 output_vector_value.allocate_single_value();
191 output_vector_value.set_single_value(float3(value_in_pixels, 0.0f));
192 }
193 }
194 }
195
197 {
199 return float2(this->get_input("Float Value").get_single_value_default(0.0f));
200 }
201 return this->get_input("Vector Value").get_single_value_default(float3(0.0f)).xy();
202 }
203
205 {
206 const Result &input_image = this->get_input("Image");
207 if (input_image.is_single_value()) {
208 return float2(1.0f);
209 }
210
212 this->context(), input_image.domain());
213 const float2 image_size = float2(domain.size);
214 switch (this->get_reference_dimension()) {
216 return image_size;
218 return float2(image_size.x);
220 return float2(image_size.y);
222 return float2(math::reduce_max(image_size));
224 return float2(math::reduce_min(image_size));
226 return float2(math::length(image_size));
227 }
228
230 return float2(1.0f);
231 }
232
237
242};
243
245{
246 return new RelativeToPixelOperation(context, node);
247}
248
249static void register_node()
250{
251 static blender::bke::bNodeType ntype;
252
253 cmp_node_type_base(&ntype, "CompositorNodeRelativeToPixel");
254 ntype.ui_name = "Relative To Pixel";
255 ntype.ui_description =
256 "Converts values that are relative to the image size to be in terms of pixels";
258 ntype.declare = node_declare;
259 ntype.initfunc = node_init;
260 ntype.updatefunc = node_update;
263
265
266 node_rna(ntype.rna_ext.srna);
267}
269
270} // namespace blender::nodes::node_composite_relative_to_pixel_cc
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:439
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
CMPNodeRelativeToPixelDataType
@ CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_VECTOR
@ CMP_NODE_RELATIVE_TO_PIXEL_DATA_TYPE_FLOAT
@ SOCK_OUT
@ SOCK_IN
CMPNodeRelativeToPixelReferenceDimension
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_DIAGONAL
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_PER_DIMENSION
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_Y
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_X
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_GREATER
@ CMP_NODE_RELATIVE_TO_PIXEL_REFERENCE_DIMENSION_SMALLER
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_inline_enum_accessors(member)
@ PROP_FACTOR
Definition RNA_types.hh:239
#define UI_ITEM_NONE
NodeOperation(Context &context, DNode node)
Result & get_result(StringRef identifier)
Definition operation.cc:39
Result & get_input(StringRef identifier) const
Definition operation.cc:138
InputDescriptor & get_input_descriptor(StringRef identifier)
Definition operation.cc:158
static Domain compute_realized_transformation_domain(Context &context, const Domain &domain)
T get_single_value_default(const T &default_value) const
void set_single_value(const T &value)
const Domain & domain() const
bool is_single_value() const
Definition result.cc:625
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:2864
void node_register_type(bNodeType &ntype)
Definition node.cc:2748
void node_set_socket_availability(bNodeTree &ntree, bNodeSocket &sock, bool is_available)
Definition node.cc:5011
T reduce_max(const VecBase< T, Size > &a)
T length(const VecBase< T, Size > &a)
T reduce_min(const VecBase< T, Size > &a)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static NodeOperation * get_compositor_operation(Context &context, DNode 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)
VecBase< float, 2 > float2
VecBase< float, 3 > float3
void cmp_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
#define min(a, b)
Definition sort.cc:36
StructRNA * srna
Definition RNA_types.hh:909
int16_t custom1
int16_t custom2
Defines a node type.
Definition BKE_node.hh:226
std::string ui_description
Definition BKE_node.hh:232
NodeGetCompositorOperationFunction get_compositor_operation
Definition BKE_node.hh:336
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:277
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)
PointerRNA * ptr
Definition wm_files.cc:4227