Blender V4.3
node_composite_inpaint.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 "UI_interface.hh"
10#include "UI_resources.hh"
11
12#include "DNA_scene_types.h"
13
16#include "COM_node_operation.hh"
17#include "COM_utilities.hh"
18
20
21/* **************** Inpaint/ ******************** */
22
24
26{
27 b.add_input<decl::Color>("Image")
28 .default_value({1.0f, 1.0f, 1.0f, 1.0f})
29 .compositor_domain_priority(0);
30 b.add_output<decl::Color>("Image");
31}
32
34{
35 uiItemR(layout, ptr, "distance", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
36}
37
38using namespace blender::realtime_compositor;
39
41 public:
43
44 void execute() override
45 {
46 Result &input = get_input("Image");
47 Result &output = get_result("Image");
48 if (input.is_single_value() || get_max_distance() == 0) {
49 input.pass_through(output);
50 return;
51 }
52
53 Result inpainting_boundary = compute_inpainting_boundary();
54
55 /* Compute a jump flooding table to get the closest boundary pixel to each pixel. */
56 Result flooded_boundary = context().create_result(ResultType::Int2, ResultPrecision::Half);
57 jump_flooding(context(), inpainting_boundary, flooded_boundary);
58 inpainting_boundary.release();
59
60 Result filled_region = context().create_result(ResultType::Color);
61 Result distance_to_boundary = context().create_result(ResultType::Float,
62 ResultPrecision::Half);
63 Result smoothing_radius = context().create_result(ResultType::Float, ResultPrecision::Half);
65 flooded_boundary, filled_region, distance_to_boundary, smoothing_radius);
66 flooded_boundary.release();
67
68 Result smoothed_region = context().create_result(ResultType::Color);
70 filled_region,
71 smoothed_region,
72 smoothing_radius,
75 filled_region.release();
76 smoothing_radius.release();
77
78 compute_inpainting_region(smoothed_region, distance_to_boundary);
79 distance_to_boundary.release();
80 smoothed_region.release();
81 }
82
83 /* Compute an image that marks the boundary pixels of the inpainting region as seed pixels for
84 * the jump flooding algorithm. The inpainting region is the region composed of pixels that are
85 * not opaque. */
87 {
88 GPUShader *shader = context().get_shader("compositor_inpaint_compute_boundary",
89 ResultPrecision::Half);
90 GPU_shader_bind(shader);
91
92 const Result &input = get_input("Image");
93 input.bind_as_texture(shader, "input_tx");
94
95 Result inpainting_boundary = context().create_result(ResultType::Int2, ResultPrecision::Half);
96 const Domain domain = compute_domain();
97 inpainting_boundary.allocate_texture(domain);
98 inpainting_boundary.bind_as_image(shader, "boundary_img");
99
100 compute_dispatch_threads_at_least(shader, domain.size);
101
102 input.unbind_as_texture();
103 inpainting_boundary.unbind_as_image();
105
106 return inpainting_boundary;
107 }
108
109 /* Fill the inpainting region based on the jump flooding table and write the distance to the
110 * closest boundary pixel to an intermediate buffer. */
111 void fill_inpainting_region(Result &flooded_boundary,
112 Result &filled_region,
113 Result &distance_to_boundary,
114 Result &smoothing_radius)
115 {
116 GPUShader *shader = context().get_shader("compositor_inpaint_fill_region");
117 GPU_shader_bind(shader);
118
119 GPU_shader_uniform_1i(shader, "max_distance", get_max_distance());
120
121 const Result &input = get_input("Image");
122 input.bind_as_texture(shader, "input_tx");
123
124 flooded_boundary.bind_as_texture(shader, "flooded_boundary_tx");
125
126 const Domain domain = compute_domain();
127 filled_region.allocate_texture(domain);
128 filled_region.bind_as_image(shader, "filled_region_img");
129
130 distance_to_boundary.allocate_texture(domain);
131 distance_to_boundary.bind_as_image(shader, "distance_to_boundary_img");
132
133 smoothing_radius.allocate_texture(domain);
134 smoothing_radius.bind_as_image(shader, "smoothing_radius_img");
135
136 compute_dispatch_threads_at_least(shader, domain.size);
137
138 input.unbind_as_texture();
139 flooded_boundary.unbind_as_texture();
140 filled_region.unbind_as_image();
141 distance_to_boundary.unbind_as_image();
142 smoothing_radius.unbind_as_image();
144 }
145
146 /* Compute the inpainting region by mixing the smoothed inpainted region with the original input
147 * up to the inpainting distance. */
148 void compute_inpainting_region(Result &inpainted_region, Result &distance_to_boundary)
149 {
150 GPUShader *shader = context().get_shader("compositor_inpaint_compute_region");
151 GPU_shader_bind(shader);
152
153 GPU_shader_uniform_1i(shader, "max_distance", get_max_distance());
154
155 const Result &input = get_input("Image");
156 input.bind_as_texture(shader, "input_tx");
157
158 inpainted_region.bind_as_texture(shader, "inpainted_region_tx");
159 distance_to_boundary.bind_as_texture(shader, "distance_to_boundary_tx");
160
161 const Domain domain = compute_domain();
162 Result &output = get_result("Image");
163 output.allocate_texture(domain);
164 output.bind_as_image(shader, "output_img");
165
166 compute_dispatch_threads_at_least(shader, domain.size);
167
168 input.unbind_as_texture();
169 inpainted_region.unbind_as_texture();
170 distance_to_boundary.unbind_as_texture();
171 output.unbind_as_image();
173 }
174
176 {
177 return bnode().custom2;
178 }
179};
180
182{
183 return new InpaintOperation(context, node);
184}
185
186} // namespace blender::nodes::node_composite_inpaint_cc
187
189{
191
192 static blender::bke::bNodeType ntype;
193
194 cmp_node_type_base(&ntype, CMP_NODE_INPAINT, "Inpaint", NODE_CLASS_OP_FILTER);
195 ntype.declare = file_ns::cmp_node_inpaint_declare;
196 ntype.draw_buttons = file_ns::node_composit_buts_inpaint;
197 ntype.get_compositor_operation = file_ns::get_compositor_operation;
198
200}
#define NODE_CLASS_OP_FILTER
Definition BKE_node.hh:408
@ R_FILTER_GAUSS
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
void GPU_shader_bind(GPUShader *shader)
void GPU_shader_unbind()
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
struct GPUShader GPUShader
void compute_inpainting_region(Result &inpainted_region, Result &distance_to_boundary)
void fill_inpainting_region(Result &flooded_boundary, Result &filled_region, Result &distance_to_boundary, Result &smoothing_radius)
GPUShader * get_shader(const char *info_name, ResultPrecision precision)
Result create_result(ResultType type, 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
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_register_type(bNodeType *ntype)
Definition node.cc:1708
static void node_composit_buts_inpaint(uiLayout *layout, bContext *, PointerRNA *ptr)
static void cmp_node_inpaint_declare(NodeDeclarationBuilder &b)
static NodeOperation * get_compositor_operation(Context &context, DNode node)
void jump_flooding(Context &context, Result &input, Result &output)
void symmetric_separable_blur_variable_size(Context &context, Result &input, Result &output, Result &radius, int filter_type=R_FILTER_GAUSS, int weights_resolution=128)
void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, int2 local_size=int2(16))
Definition utilities.cc:131
void register_node_type_cmp_inpaint()
void cmp_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
int16_t custom2
Defines a node type.
Definition BKE_node.hh:218
NodeGetCompositorOperationFunction get_compositor_operation
Definition BKE_node.hh:324
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