Blender V4.3
COM_TranslateOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7namespace blender::compositor {
8
11{
12 this->add_input_socket(data_type, resize_mode);
15 this->add_output_socket(data_type);
17 is_delta_set_ = false;
18 is_relative_ = false;
21 this->sampler_ = PixelSampler::Nearest;
22
23 this->flags_.can_be_constant = true;
24}
25
26void TranslateOperation::set_wrapping(int wrapping_type)
27{
28 switch (wrapping_type) {
29 case CMP_NODE_WRAP_X:
31 break;
32 case CMP_NODE_WRAP_Y:
34 break;
38 break;
39 default:
40 break;
41 }
42}
43
45 const rcti & /*area*/,
46 Span<MemoryBuffer *> /*inputs*/)
47{
49}
50
52 const rcti &output_area,
53 rcti &r_input_area)
54{
55 if (input_idx == 0) {
57 r_input_area = output_area;
59 const int delta_x = this->get_delta_x();
60 BLI_rcti_translate(&r_input_area, -delta_x, 0);
61 }
63 /* The region of interest should consider the whole input image to avoid cropping effects,
64 * e.g. by prior scaling or rotating.
65 * NOTE: this is still consistent with immediate realization of transform nodes in GPU
66 * compositor, where nodes are to be evaluated from left to right. */
67 const int in_width = get_width();
68 BLI_rcti_resize_x(&r_input_area, in_width);
69 }
70
72 const int delta_y = this->get_delta_y();
73 BLI_rcti_translate(&r_input_area, 0, -delta_y);
74 }
76 const int in_height = get_height();
77 BLI_rcti_resize_y(&r_input_area, in_height);
78 }
79 }
80 else {
81 r_input_area = output_area;
82 }
83}
84
86 const rcti &area,
88{
89 MemoryBuffer *input = inputs[0];
90 /* Linking X and Y input sockets to non-constant input may result in a non-constant output, see
91 * Stabilize2dNode for example. */
92 if (input->is_a_single_elem() && output->is_a_single_elem()) {
93 copy_v4_v4(output->get_elem(0, 0), input->get_elem(0, 0));
94 return;
95 }
96
97 /* Some compositor operations produce an empty output buffer by specifying a COM_AREA_NONE canvas
98 * to indicate an invalid output, for instance, when the Mask operation reference an invalid
99 * mask. The intention is that this buffer would signal that a fallback value would fill the
100 * canvas of consumer operations. Since the aforementioned filling is achieved through the
101 * Translate operation as part of canvas conversion in COM_convert_canvas, we handle the empty
102 * buffer case here and fill the output using a fallback black color. */
103 if (BLI_rcti_is_empty(&input->get_rect())) {
104 const float value[4] = {0.0f, 0.0f, 0.0f, 1.0f};
105 output->fill(area, value);
106 return;
107 }
108
109 float delta_x = this->get_delta_x();
110 float delta_y = this->get_delta_y();
111 if (sampler_ == PixelSampler::Nearest) {
112 /* Use same rounding convention for GPU compositor. */
113 delta_x = round(delta_x);
114 delta_y = round(delta_y);
115 }
116
117 for (int y = area.ymin; y < area.ymax; y++) {
118 float *out = output->get_elem(area.xmin, y);
119 for (int x = area.xmin; x < area.xmax; x++) {
120 const float input_x = x - delta_x;
121 const float input_y = y - delta_y;
122 input->read(out, input_x, input_y, sampler_, x_extend_mode_, y_extend_mode_);
123 out += output->elem_stride;
124 }
125 }
126}
127
132
133void TranslateCanvasOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
134{
135 const bool determined =
136 get_input_socket(IMAGE_INPUT_INDEX)->determine_canvas(preferred_area, r_area);
137 if (determined) {
140 rcti unused = COM_AREA_NONE;
141 x_socket->determine_canvas(r_area, unused);
142 y_socket->determine_canvas(r_area, unused);
143
144 ensure_delta();
145 const float delta_x = x_extend_mode_ == MemoryBufferExtend::Clip ? get_delta_x() : 0.0f;
146 const float delta_y = y_extend_mode_ == MemoryBufferExtend::Clip ? get_delta_y() : 0.0f;
147 BLI_rcti_translate(&r_area, delta_x, delta_y);
148 }
149}
150
151} // namespace blender::compositor
MINLINE void copy_v4_v4(float r[4], const float a[4])
void BLI_rcti_translate(struct rcti *rect, int x, int y)
Definition rct.c:560
void BLI_rcti_resize_y(struct rcti *rect, int y)
Definition rct.c:609
void BLI_rcti_resize_x(struct rcti *rect, int x)
Definition rct.c:603
bool BLI_rcti_is_empty(const struct rcti *rect)
@ CMP_NODE_WRAP_X
@ CMP_NODE_WRAP_Y
@ CMP_NODE_WRAP_XY
a MemoryBuffer contains access to the data
bool determine_canvas(const rcti &preferred_area, rcti &r_area)
void add_output_socket(DataType datatype)
NodeOperationInput * get_input_socket(unsigned int index)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
void set_canvas_input_index(unsigned int index)
set the index of the input socket that will determine the canvas of this operation
void determine_canvas(const rcti &preferred_area, rcti &r_area) override
void update_memory_buffer_started(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
DataType
possible data types for sockets
Definition COM_defines.h:21
ResizeMode
Resize modes of inputsockets How are the input and working resolutions matched.
constexpr rcti COM_AREA_NONE
Definition COM_defines.h:89