Blender V5.0
node_composite_mask.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2012 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_math_base.hh"
10#include "BLI_string_utf8.h"
11
12#include "DNA_mask_types.h"
13
14#include "UI_interface.hh"
16
17#include "COM_cached_mask.hh"
18#include "COM_node_operation.hh"
19
21
23
25 {0, "SCENE", 0, "Scene Size", ""},
26 {CMP_NODE_MASK_FLAG_SIZE_FIXED, "FIXED", 0, N_("Fixed"), N_("Use pixel size for the buffer")},
28 "FIXED_SCENE",
29 0,
30 N_("Fixed/Scene"),
31 N_("Pixel size scaled by scene percentage")},
32 {0, nullptr, 0, nullptr, nullptr},
33};
34
36{
37 b.use_custom_socket_order();
38
39 b.add_output<decl::Float>("Mask").structure_type(StructureType::Dynamic);
40
41 b.add_layout([](uiLayout *layout, bContext *C, PointerRNA *ptr) {
42 uiTemplateID(layout, C, ptr, "mask", nullptr, nullptr, nullptr);
43 });
44
45 b.add_input<decl::Menu>("Size Source")
46 .default_value(MenuValue(0))
47 .static_items(size_source_items)
49 .description("The source where the size of the mask is retrieved");
50 b.add_input<decl::Int>("Size X")
51 .default_value(256)
52 .min(1)
53 .usage_by_menu("Size Source",
55 .description("The resolution of the mask along the X direction");
56 b.add_input<decl::Int>("Size Y")
57 .default_value(256)
58 .min(1)
59 .usage_by_menu("Size Source",
61 .description("The resolution of the mask along the Y direction");
62 b.add_input<decl::Bool>("Feather").default_value(true).description(
63 "Use feather information from the mask");
64
65 PanelDeclarationBuilder &motion_blur_panel = b.add_panel("Motion Blur").default_closed(true);
66 motion_blur_panel.add_input<decl::Bool>("Motion Blur")
67 .default_value(false)
68 .panel_toggle()
69 .description("Use multi-sampled motion blur of the mask");
70 motion_blur_panel.add_input<decl::Int>("Samples", "Motion Blur Samples")
71 .default_value(16)
72 .min(1)
73 .max(64)
74 .description("Number of motion blur samples");
75 motion_blur_panel.add_input<decl::Float>("Shutter", "Motion Blur Shutter")
76 .default_value(0.5f)
78 .min(0.0f)
79 .max(1.0f)
80 .description("Exposure for motion blur as a factor of FPS");
81}
82
83static void node_mask_label(const bNodeTree * /*ntree*/,
84 const bNode *node,
85 char *label,
86 int label_maxncpy)
87{
88 BLI_strncpy_utf8(label, node->id ? node->id->name + 2 : IFACE_("Mask"), label_maxncpy);
89}
90
91using namespace blender::compositor;
92
94 public:
96
97 void execute() override
98 {
99 Result &output_mask = this->get_result("Mask");
100 if (!this->get_mask() ||
101 (!this->is_fixed_size() && !this->context().is_valid_compositing_region()))
102 {
103 output_mask.allocate_invalid();
104 return;
105 }
106
107 const Domain domain = compute_domain();
108 Result &cached_mask = context().cache_manager().cached_masks.get(
109 this->context(),
110 this->get_mask(),
111 domain.size,
112 this->get_aspect_ratio(),
113 this->get_use_feather(),
114 this->get_motion_blur_samples(),
115 this->get_motion_blur_shutter());
116
117 output_mask.wrap_external(cached_mask);
118 }
119
121 {
122 return Domain(this->compute_size());
123 }
124
126 {
128 return this->get_size();
129 }
130
132 return this->get_size() * this->context().get_render_percentage();
133 }
134
135 return this->context().get_compositing_region_size();
136 }
137
139 {
140 return int2(math::max(1, this->get_input("Size X").get_single_value_default(256)),
141 math::max(1, this->get_input("Size Y").get_single_value_default(256)));
142 }
143
145 {
146 if (this->is_fixed_size()) {
147 return 1.0f;
148 }
149
150 return this->context().get_render_data().yasp / this->context().get_render_data().xasp;
151 }
152
158
160 {
161 return this->get_input("Feather").get_single_value_default(true);
162 }
163
165 {
166 const int samples = math::clamp(
167 this->get_input("Motion Blur Samples").get_single_value_default(16), 1, 64);
168 return this->use_motion_blur() ? samples : 1;
169 }
170
172 {
173 return math::clamp(
174 this->get_input("Motion Blur Shutter").get_single_value_default(0.5f), 0.0f, 1.0f);
175 }
176
178 {
179 return this->get_input("Motion Blur").get_single_value_default(false);
180 }
181
183 {
184 const Result &input = this->get_input("Size Source");
185 const MenuValue default_menu_value = MenuValue(0);
186 const MenuValue menu_value = input.get_single_value_default(default_menu_value);
187 return static_cast<CMPNodeMaskFlags>(menu_value.value);
188 }
189
191 {
192 return reinterpret_cast<Mask *>(this->bnode().id);
193 }
194};
195
197{
198 return new MaskOperation(context, node);
199}
200
201} // namespace blender::nodes::node_composite_mask_cc
202
204{
205 namespace file_ns = blender::nodes::node_composite_mask_cc;
206
207 static blender::bke::bNodeType ntype;
208
209 cmp_node_type_base(&ntype, "CompositorNodeMask", CMP_NODE_MASK);
210 ntype.ui_name = "Mask";
211 ntype.ui_description = "Input mask from a mask data-block, created in the image editor";
212 ntype.enum_name_legacy = "MASK";
213 ntype.nclass = NODE_CLASS_INPUT;
214 ntype.declare = file_ns::cmp_node_mask_declare;
215 ntype.labelfunc = file_ns::node_mask_label;
216 ntype.get_compositor_operation = file_ns::get_compositor_operation;
217
219}
#define NODE_CLASS_INPUT
Definition BKE_node.hh:447
#define CMP_NODE_MASK
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define IFACE_(msgid)
CMPNodeMaskFlags
@ CMP_NODE_MASK_FLAG_SIZE_FIXED
@ CMP_NODE_MASK_FLAG_SIZE_FIXED_SCENE
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ PROP_FACTOR
Definition RNA_types.hh:251
#define C
Definition RandGen.cpp:29
void uiTemplateID(uiLayout *layout, const bContext *C, PointerRNA *ptr, blender::StringRefNull propname, const char *newop, const char *openop, const char *unlinkop, int filter=UI_TEMPLATE_ID_FILTER_ALL, bool live_icon=false, std::optional< blender::StringRef > text=std::nullopt)
Result & get(Context &context, Mask *mask, int2 size, float aspect_ratio, bool use_feather, int motion_blur_samples, float motion_blur_shutter)
virtual const RenderData & get_render_data() const
NodeOperation(Context &context, DNode node)
Result & get_result(StringRef identifier)
Definition operation.cc:39
Result & get_input(StringRef identifier) const
Definition operation.cc:138
T get_single_value_default(const T &default_value) const
void wrap_external(blender::gpu::Texture *texture)
Definition result.cc:584
DeclType::Builder & add_input(StringRef name, StringRef identifier="")
#define input
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
T clamp(const T &a, const T &min, const T &max)
T max(const T &a, const T &b)
static void cmp_node_mask_declare(NodeDeclarationBuilder &b)
static const EnumPropertyItem size_source_items[]
static void node_mask_label(const bNodeTree *, const bNode *node, char *label, int label_maxncpy)
static NodeOperation * get_compositor_operation(Context &context, DNode node)
VecBase< int32_t, 2 > int2
static void register_node_type_cmp_mask()
void cmp_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
char name[258]
Definition DNA_ID.h:432
struct ID * id
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
void(* labelfunc)(const bNodeTree *ntree, const bNode *node, char *label, int label_maxncpy)
Definition BKE_node.hh:270
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:362
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4238