10#define USE_FORCE_BILINEAR
19#ifdef USE_FORCE_BILINEAR
38float ScaleOperation::get_constant_scale(
const int input_op_idx,
const float factor)
49float ScaleOperation::get_constant_scale_x(
const float width)
54float ScaleOperation::get_constant_scale_y(
const float height)
59bool ScaleOperation::is_scaling_variable()
67 const rcti src_area = area;
75 float scale_offset_x, scale_offset_y;
84 area.xmax = area.xmin + max_size.x;
87 area.ymax = area.ymin + max_size.y;
98 const rcti &scale_canvas,
99 float &r_scale_offset_x,
100 float &r_scale_offset_y)
107 const rcti &scale_canvas,
108 const float relative_scale_x,
109 const float relative_scale_y,
110 const rcti &output_area,
115 float scale_offset_x, scale_offset_y;
129 const rcti &output_area,
132 r_input_area = output_area;
133 if (input_idx != 0 || is_scaling_variable()) {
138 const float scale_x = get_constant_scale_x(image_op->
get_width());
139 const float scale_y = get_constant_scale_y(image_op->
get_height());
142 image_op->
get_canvas(), this->get_canvas(), scale_x, scale_y, output_area, r_input_area);
151 const int input_image_width = input_image_op->
get_width();
152 const int input_image_height = input_image_op->
get_height();
155 const float scale_center_x = input_image_width / 2.0f;
156 const float scale_center_y = input_image_height / 2.0f;
157 float from_scale_offset_x, from_scale_offset_y;
159 input_image_op->
get_canvas(), this->get_canvas(), from_scale_offset_x, from_scale_offset_y);
165 for (; !it.is_end(); ++it) {
166 const float rel_scale_x = *it.in(0) * scale_x_factor;
167 const float rel_scale_y = *it.in(1) * scale_y_factor;
184 const bool image_determined =
186 if (image_determined) {
187 rcti image_canvas = r_area;
193 if (is_scaling_variable()) {
201 const float scale_x = get_constant_scale_x(input_width);
202 const float scale_y = get_constant_scale_y(input_height);
229 rel_x_ = input_width /
float(new_width_);
230 rel_y_ = input_height /
float(new_height_);
233 if (offset_x_ != 0.0f || offset_y_ != 0.0f) {
236 if (new_width_ > new_height_) {
237 offset_x_ *= new_width_;
238 offset_y_ *= new_width_;
241 offset_x_ *= new_height_;
242 offset_y_ *= new_height_;
248 const float w_src = input_width;
249 const float h_src = input_height;
252 const float w_dst = new_width_;
253 const float h_dst = new_height_;
255 const float asp_src = w_src / h_src;
256 const float asp_dst = w_dst / h_dst;
258 if (
fabsf(asp_src - asp_dst) >= FLT_EPSILON) {
259 if ((asp_src > asp_dst) == (is_crop_ ==
true)) {
261 const float div = asp_src / asp_dst;
263 offset_x_ += ((w_src - (w_src * div)) / (w_src / w_dst)) / 2.0f;
265 int fit_width = new_width_ * div;
267 const int added_width = fit_width - new_width_;
268 new_width_ += added_width;
269 offset_x_ += added_width / 2.0f;
274 const float div = asp_dst / asp_src;
276 offset_y_ += ((h_src - (h_src * div)) / (h_src / h_dst)) / 2.0f;
278 int fit_height = new_height_ * div;
280 const int added_height = fit_height - new_height_;
281 new_height_ += added_height;
282 offset_y_ += added_height / 2.0f;
294 rcti local_preferred = preferred_area;
295 local_preferred.
xmax = local_preferred.
xmin + new_width_;
296 local_preferred.
ymax = local_preferred.
ymin + new_height_;
300 if (input_determined) {
302 r_area = input_canvas;
303 r_area.
xmin /= rel_x_;
304 r_area.
ymin /= rel_y_;
305 r_area.
xmin += offset_x_;
306 r_area.
ymin += offset_y_;
308 r_area.
xmax = r_area.
xmin + new_width_;
309 r_area.
ymax = r_area.
ymin + new_height_;
314 const rcti &output_area,
320 r_input_area.
xmax =
ceilf((output_area.
xmax - offset_x_) * rel_x_);
321 r_input_area.
xmin =
floorf((output_area.
xmin - offset_x_) * rel_x_);
322 r_input_area.
ymax =
ceilf((output_area.
ymax - offset_y_) * rel_y_);
323 r_input_area.
ymin =
floorf((output_area.
ymin - offset_y_) * rel_y_);
336 for (; !it.is_end(); ++it) {
337 const float nx = it.x * rel_x_ + add_x;
338 const float ny = it.y * rel_y_ + add_y;
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
void BLI_rcti_translate(struct rcti *rect, int x, int y)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
#define UNUSED_VARS_NDEBUG(...)
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)
NodeOperation contains calculation logic.
unsigned int get_height() const
void add_output_socket(DataType datatype)
const NodeOperationFlags get_flags() const
unsigned int get_width() const
NodeOperationFlags flags_
const rcti & get_canvas() const
NodeOperation * get_input_operation(int index)
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 update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void determine_canvas(const rcti &preferred_area, rcti &r_area) 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.
ScaleFixedSizeOperation()
static constexpr int Y_INPUT_INDEX
static constexpr int IMAGE_INPUT_INDEX
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)
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.
virtual float get_relative_scale_x_factor(float width)=0
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 init_data() override
virtual float get_relative_scale_y_factor(float height)=0
void determine_canvas(const rcti &preferred_area, rcti &r_area) override
static constexpr int X_INPUT_INDEX
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
static void clamp_area_size_max(rcti &area, Size2f max_size)
static float scale_coord(const float coord, const float center, const float relative_scale)
local_group_size(16, 16) .push_constant(Type local_group_size(16, 16) .push_constant(Type input_tx sampler(1, ImageType::FLOAT_2D, "matte_tx") .image(0
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
DataType
possible data types for sockets
void expand_area_for_sampler(rcti &area, PixelSampler sampler)
constexpr rcti COM_AREA_NONE
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
bool is_constant_operation