Blender V4.3
node_composite_ellipsemask.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
9#include <cmath>
10
12
13#include "UI_interface.hh"
14#include "UI_resources.hh"
15
16#include "GPU_shader.hh"
17
18#include "COM_node_operation.hh"
19#include "COM_utilities.hh"
20
22
23/* **************** SCALAR MATH ******************** */
24
26
28
30{
31 b.add_input<decl::Float>("Mask")
32 .default_value(0.0f)
33 .min(0.0f)
34 .max(1.0f)
36 b.add_input<decl::Float>("Value")
37 .default_value(1.0f)
38 .min(0.0f)
39 .max(1.0f)
41 b.add_output<decl::Float>("Mask");
42}
43
44static void node_composit_init_ellipsemask(bNodeTree * /*ntree*/, bNode *node)
45{
46 NodeEllipseMask *data = MEM_cnew<NodeEllipseMask>(__func__);
47 data->x = 0.5;
48 data->y = 0.5;
49 data->width = 0.2;
50 data->height = 0.1;
51 data->rotation = 0.0;
52 node->storage = data;
53}
54
56{
57 uiLayout *row;
58 row = uiLayoutRow(layout, true);
59 uiItemR(row, ptr, "x", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
60 uiItemR(row, ptr, "y", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
61 row = uiLayoutRow(layout, true);
62 uiItemR(
63 row, ptr, "mask_width", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
64 uiItemR(
65 row, ptr, "mask_height", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
66
67 uiItemR(layout, ptr, "rotation", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
68 uiItemR(layout, ptr, "mask_type", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
69}
70
71using namespace blender::realtime_compositor;
72
74 public:
76
77 void execute() override
78 {
79 const Result &input_mask = get_input("Mask");
80 Result &output_mask = get_result("Mask");
81 /* For single value masks, the output will assume the compositing region, so ensure it is valid
82 * first. See the compute_domain method. */
83 if (input_mask.is_single_value() && !context().is_valid_compositing_region()) {
84 output_mask.allocate_invalid();
85 return;
86 }
87
89 GPU_shader_bind(shader);
90
91 const Domain domain = compute_domain();
92
93 GPU_shader_uniform_2iv(shader, "domain_size", domain.size);
94
95 GPU_shader_uniform_2fv(shader, "location", get_location());
96 GPU_shader_uniform_2fv(shader, "radius", get_size() / 2.0f);
97 GPU_shader_uniform_1f(shader, "cos_angle", std::cos(get_angle()));
98 GPU_shader_uniform_1f(shader, "sin_angle", std::sin(get_angle()));
99
100 input_mask.bind_as_texture(shader, "base_mask_tx");
101
102 const Result &value = get_input("Value");
103 value.bind_as_texture(shader, "mask_value_tx");
104
105 output_mask.allocate_texture(domain);
106 output_mask.bind_as_image(shader, "output_mask_img");
107
108 compute_dispatch_threads_at_least(shader, domain.size);
109
110 input_mask.unbind_as_texture();
111 value.unbind_as_texture();
112 output_mask.unbind_as_image();
114 }
115
117 {
118 if (get_input("Mask").is_single_value()) {
119 return Domain(context().get_compositing_region_size());
120 }
121 return get_input("Mask").domain();
122 }
123
128
129 const char *get_shader_name()
130 {
131 switch (get_mask_type()) {
132 default:
134 return "compositor_ellipse_mask_add";
136 return "compositor_ellipse_mask_subtract";
138 return "compositor_ellipse_mask_multiply";
140 return "compositor_ellipse_mask_not";
141 }
142 }
143
145 {
146 return float2(node_storage(bnode()).x, node_storage(bnode()).y);
147 }
148
150 {
151 return float2(node_storage(bnode()).width, node_storage(bnode()).height);
152 }
153
154 float get_angle()
155 {
156 return node_storage(bnode()).rotation;
157 }
158};
159
161{
162 return new EllipseMaskOperation(context, node);
163}
164
165} // namespace blender::nodes::node_composite_ellipsemask_cc
166
168{
170
171 static blender::bke::bNodeType ntype;
172
173 cmp_node_type_base(&ntype, CMP_NODE_MASK_ELLIPSE, "Ellipse Mask", NODE_CLASS_MATTE);
174 ntype.declare = file_ns::cmp_node_ellipsemask_declare;
175 ntype.draw_buttons = file_ns::node_composit_buts_ellipsemask;
176 blender::bke::node_type_size(&ntype, 260, 110, 320);
177 ntype.initfunc = file_ns::node_composit_init_ellipsemask;
179 &ntype, "NodeEllipseMask", node_free_standard_storage, node_copy_standard_storage);
180 ntype.get_compositor_operation = file_ns::get_compositor_operation;
181
183}
#define NODE_CLASS_MATTE
Definition BKE_node.hh:411
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1799
CMPNodeMaskType
@ CMP_NODE_MASKTYPE_NOT
@ CMP_NODE_MASKTYPE_SUBTRACT
@ CMP_NODE_MASKTYPE_MULTIPLY
@ CMP_NODE_MASKTYPE_ADD
void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2])
void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value)
void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2])
void GPU_shader_bind(GPUShader *shader)
void GPU_shader_unbind()
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
@ UI_ITEM_R_SLIDER
struct GPUShader GPUShader
GPUShader * get_shader(const char *info_name, ResultPrecision precision)
NodeOperation(Context &context, DNode node)
Result & get_input(StringRef identifier) const
Definition operation.cc:144
Result & get_result(StringRef identifier)
Definition operation.cc:46
void bind_as_image(GPUShader *shader, const char *image_name, bool read=false) const
Definition result.cc:264
const Domain & domain() const
Definition result.cc:712
void allocate_texture(Domain domain, bool from_pool=true)
Definition result.cc:204
void bind_as_texture(GPUShader *shader, const char *texture_name) const
Definition result.cc:253
local_group_size(16, 16) .push_constant(Type b
void node_type_size(bNodeType *ntype, int width, int minwidth, int maxwidth)
Definition node.cc:4602
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:4632
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static void node_composit_init_ellipsemask(bNodeTree *, bNode *node)
static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *, PointerRNA *ptr)
static void cmp_node_ellipsemask_declare(NodeDeclarationBuilder &b)
static NodeOperation * get_compositor_operation(Context &context, DNode node)
void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, int2 local_size=int2(16))
Definition utilities.cc:131
VecBase< float, 2 > float2
void register_node_type_cmp_ellipsemask()
void cmp_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:46
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:58
int16_t custom1
Defines a node type.
Definition BKE_node.hh:218
NodeGetCompositorOperationFunction get_compositor_operation
Definition BKE_node.hh:324
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:238
NodeDeclareFunction declare
Definition BKE_node.hh:347
PointerRNA * ptr
Definition wm_files.cc:4126