Blender V4.3
COM_TransformOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6#include "BLI_math_rotation.h"
9
10namespace blender::compositor {
11
28
30{
31
32 translate_x_ = get_input_operation(X_INPUT_INDEX)->get_constant_value_default(0.0f) *
33 translate_factor_x_;
34 translate_y_ = get_input_operation(Y_INPUT_INDEX)->get_constant_value_default(0.0f) *
35 translate_factor_y_;
36
37 const float degree = get_input_operation(DEGREE_INPUT_INDEX)->get_constant_value_default(0.0f);
38 const double rad = convert_degree_to_rad_ ? DEG2RAD(double(degree)) : degree;
39 rotate_cosine_ = cos(rad);
40 rotate_sine_ = sin(rad);
41
42 scale_ = get_input_operation(SCALE_INPUT_INDEX)->get_constant_value_default(1.0f);
43}
44
46 const rcti &output_area,
47 rcti &r_input_area)
48{
49 switch (input_idx) {
50 case IMAGE_INPUT_INDEX: {
51 NodeOperation *image_op = get_input_operation(IMAGE_INPUT_INDEX);
52 const rcti &image_canvas = image_op->get_canvas();
53 if (invert_) {
54 /* Scale -> Rotate -> Translate. */
55 r_input_area = output_area;
56 BLI_rcti_translate(&r_input_area, -translate_x_, -translate_y_);
58 rotate_canvas_,
59 rotate_sine_,
60 rotate_cosine_,
61 r_input_area,
62 r_input_area);
64 image_canvas, scale_canvas_, scale_, scale_, r_input_area, r_input_area);
65 }
66 else {
67 /* Translate -> Rotate -> Scale. */
69 rotate_canvas_, scale_canvas_, scale_, scale_, output_area, r_input_area);
71 rotate_canvas_,
72 rotate_sine_,
73 rotate_cosine_,
74 r_input_area,
75 r_input_area);
76 BLI_rcti_translate(&r_input_area, -translate_x_, -translate_y_);
77 }
78 expand_area_for_sampler(r_input_area, sampler_);
79 break;
80 }
81 case X_INPUT_INDEX:
82 case Y_INPUT_INDEX:
83 case DEGREE_INPUT_INDEX:
84 case SCALE_INPUT_INDEX: {
86 break;
87 }
88 }
89}
90
92 const rcti &area,
94{
95 const MemoryBuffer *input_img = inputs[IMAGE_INPUT_INDEX];
96 BuffersIterator<float> it = output->iterate_with({}, area);
97 if (invert_) {
98 transform_inverted(it, input_img);
99 }
100 else {
101 transform(it, input_img);
102 }
103}
104
105void TransformOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
106{
107 const bool image_determined =
108 get_input_socket(IMAGE_INPUT_INDEX)->determine_canvas(preferred_area, r_area);
109 if (image_determined) {
110 rcti image_canvas = r_area;
111 rcti unused = COM_AREA_NONE;
112 get_input_socket(X_INPUT_INDEX)->determine_canvas(image_canvas, unused);
113 get_input_socket(Y_INPUT_INDEX)->determine_canvas(image_canvas, unused);
114 get_input_socket(DEGREE_INPUT_INDEX)->determine_canvas(image_canvas, unused);
115 get_input_socket(SCALE_INPUT_INDEX)->determine_canvas(image_canvas, unused);
116
117 init_data();
118 if (invert_) {
119 /* Scale -> Rotate -> Translate. */
120 scale_canvas_ = image_canvas;
121 ScaleOperation::scale_area(scale_canvas_, scale_, scale_);
122
124 scale_canvas_, rotate_sine_, rotate_cosine_, rotate_canvas_);
125
126 translate_canvas_ = rotate_canvas_;
127 BLI_rcti_translate(&translate_canvas_, translate_x_, translate_y_);
128
129 r_area = translate_canvas_;
130 }
131 else {
132 /* Translate -> Rotate -> Scale. */
133 translate_canvas_ = image_canvas;
134 BLI_rcti_translate(&translate_canvas_, translate_x_, translate_y_);
135
137 translate_canvas_, rotate_sine_, rotate_cosine_, rotate_canvas_);
138
139 scale_canvas_ = rotate_canvas_;
140 ScaleOperation::scale_area(scale_canvas_, scale_, scale_);
141
142 r_area = scale_canvas_;
143 }
144 }
145}
146
147void TransformOperation::transform(BuffersIterator<float> &it, const MemoryBuffer *input_img)
148{
149 float rotate_center_x, rotate_center_y;
150 RotateOperation::get_rotation_center(translate_canvas_, rotate_center_x, rotate_center_y);
151 float rotate_offset_x, rotate_offset_y;
153 translate_canvas_, rotate_canvas_, rotate_offset_x, rotate_offset_y);
154
155 const float scale_center_x = BLI_rcti_size_x(&rotate_canvas_) / 2.0f;
156 const float scale_center_y = BLI_rcti_size_y(&rotate_canvas_) / 2.0f;
157 float scale_offset_x, scale_offset_y;
158 ScaleOperation::get_scale_offset(rotate_canvas_, scale_canvas_, scale_offset_x, scale_offset_y);
159
160 for (; !it.is_end(); ++it) {
161 float x = ScaleOperation::scale_coord_inverted(it.x + scale_offset_x, scale_center_x, scale_);
162 float y = ScaleOperation::scale_coord_inverted(it.y + scale_offset_y, scale_center_y, scale_);
163
164 x = rotate_offset_x + x;
165 y = rotate_offset_y + y;
167 x, y, rotate_center_x, rotate_center_y, rotate_sine_, rotate_cosine_);
168
169 input_img->read_elem_sampled(x - translate_x_, y - translate_y_, sampler_, it.out);
170 }
171}
172
173void TransformOperation::transform_inverted(BuffersIterator<float> &it,
174 const MemoryBuffer *input_img)
175{
176 const rcti &image_canvas = get_input_operation(IMAGE_INPUT_INDEX)->get_canvas();
177 const float scale_center_x = BLI_rcti_size_x(&image_canvas) / 2.0f - translate_x_;
178 const float scale_center_y = BLI_rcti_size_y(&image_canvas) / 2.0f - translate_y_;
179 float scale_offset_x, scale_offset_y;
180 ScaleOperation::get_scale_offset(image_canvas, scale_canvas_, scale_offset_x, scale_offset_y);
181
182 float rotate_center_x, rotate_center_y;
183 RotateOperation::get_rotation_center(translate_canvas_, rotate_center_x, rotate_center_y);
184 rotate_center_x -= translate_x_;
185 rotate_center_y -= translate_y_;
186 float rotate_offset_x, rotate_offset_y;
188 scale_canvas_, rotate_canvas_, rotate_offset_x, rotate_offset_y);
189
190 for (; !it.is_end(); ++it) {
191 float x = rotate_offset_x + (it.x - translate_x_);
192 float y = rotate_offset_y + (it.y - translate_y_);
194 x, y, rotate_center_x, rotate_center_y, rotate_sine_, rotate_cosine_);
195
196 x = ScaleOperation::scale_coord_inverted(x + scale_offset_x, scale_center_x, scale_);
197 y = ScaleOperation::scale_coord_inverted(y + scale_offset_y, scale_center_y, scale_);
198
199 input_img->read_elem_sampled(x, y, sampler_, it.out);
200 }
201}
202
203} // namespace blender::compositor
#define DEG2RAD(_deg)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
void BLI_rcti_translate(struct rcti *rect, int x, int y)
Definition rct.c:560
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
a MemoryBuffer contains access to the data
void read_elem_sampled(float x, float y, PixelSampler sampler, float *out) const
BuffersIterator< float > iterate_with(Span< MemoryBuffer * > inputs)
bool determine_canvas(const rcti &preferred_area, rcti &r_area)
NodeOperation contains calculation logic.
void add_output_socket(DataType datatype)
float get_constant_value_default(float default_value)
NodeOperation * get_input_operation(int index)
NodeOperationInput * get_input_socket(unsigned int index)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
static void get_rotation_offset(const rcti &input_canvas, const rcti &rotate_canvas, float &r_offset_x, float &r_offset_y)
static void rotate_coords(float &x, float &y, float center_x, float center_y, float sine, float cosine)
static void get_rotation_area_of_interest(const rcti &input_canvas, const rcti &rotate_canvas, float sine, float cosine, const rcti &output_area, rcti &r_input_area)
static void get_rotation_canvas(const rcti &input_canvas, float sine, float cosine, rcti &r_canvas)
static void get_rotation_center(const rcti &area, float &r_x, float &r_y)
static void get_scale_offset(const rcti &input_canvas, const rcti &scale_canvas, float &r_scale_offset_x, float &r_scale_offset_y)
static void get_scale_area_of_interest(const rcti &input_canvas, const rcti &scale_canvas, float relative_scale_x, float relative_scale_y, const rcti &output_area, rcti &r_input_area)
static void scale_area(rcti &area, float relative_scale_x, float relative_scale_y)
static float scale_coord_inverted(const float coord, const float center, const float relative_scale)
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.
void determine_canvas(const rcti &preferred_area, rcti &r_area) override
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
ccl_device_inline float3 cos(float3 v)
void expand_area_for_sampler(rcti &area, PixelSampler sampler)
Definition COM_Enums.cc:9
constexpr rcti COM_CONSTANT_INPUT_AREA_OF_INTEREST
Definition COM_defines.h:90
constexpr rcti COM_AREA_NONE
Definition COM_defines.h:89
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator