Files
test2/source/blender/compositor/nodes/COM_ScaleNode.cc
Omar Emara 60bb3b6677 Fix #124737: Scale To Render size is not precise
The Scale node in the Scale To Render size mode is not precise in case
of the use of render size percentage. This is due to floating point
imprecisions and we mitigate it by rounding instead of flooring after
multiplying by the percentage.
2024-09-30 18:58:13 +03:00

98 lines
3.9 KiB
C++

/* SPDX-FileCopyrightText: 2011 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "COM_ScaleNode.h"
#include "BKE_node.hh"
#include "COM_ScaleOperation.h"
#include "COM_SetValueOperation.h"
namespace blender::compositor {
ScaleNode::ScaleNode(bNode *editor_node) : Node(editor_node)
{
/* pass */
}
void ScaleNode::convert_to_operations(NodeConverter &converter,
const CompositorContext &context) const
{
const bNode *bnode = this->get_bnode();
NodeInput *input_socket = this->get_input_socket(0);
NodeInput *input_xsocket = this->get_input_socket(1);
NodeInput *input_ysocket = this->get_input_socket(2);
NodeOutput *output_socket = this->get_output_socket(0);
switch (bnode->custom1) {
case CMP_NODE_SCALE_RELATIVE: {
ScaleRelativeOperation *operation = new ScaleRelativeOperation();
converter.add_operation(operation);
converter.map_input_socket(input_socket, operation->get_input_socket(0));
converter.map_input_socket(input_xsocket, operation->get_input_socket(1));
converter.map_input_socket(input_ysocket, operation->get_input_socket(2));
converter.map_output_socket(output_socket, operation->get_output_socket(0));
operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked());
break;
}
case CMP_NODE_SCALE_RENDER_PERCENT: {
SetValueOperation *scale_factor_operation = new SetValueOperation();
scale_factor_operation->set_value(context.get_render_percentage_as_factor());
converter.add_operation(scale_factor_operation);
ScaleRelativeOperation *operation = new ScaleRelativeOperation();
converter.add_operation(operation);
converter.map_input_socket(input_socket, operation->get_input_socket(0));
converter.add_link(scale_factor_operation->get_output_socket(),
operation->get_input_socket(1));
converter.add_link(scale_factor_operation->get_output_socket(),
operation->get_input_socket(2));
converter.map_output_socket(output_socket, operation->get_output_socket(0));
operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked());
break;
}
case CMP_NODE_SCALE_RENDER_SIZE: {
const RenderData *rd = context.get_render_data();
const float render_size_factor = context.get_render_percentage_as_factor();
ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation();
/* framing options */
operation->set_is_aspect(
ELEM(bnode->custom2, CMP_NODE_SCALE_RENDER_SIZE_FIT, CMP_NODE_SCALE_RENDER_SIZE_CROP));
operation->set_is_crop(bnode->custom2 == CMP_NODE_SCALE_RENDER_SIZE_CROP);
operation->set_offset(bnode->custom3, bnode->custom4);
operation->set_new_width(int(math::round(rd->xsch * render_size_factor)));
operation->set_new_height(int(math::round(rd->ysch * render_size_factor)));
converter.add_operation(operation);
converter.map_input_socket(input_socket, operation->get_input_socket(0));
converter.map_output_socket(output_socket, operation->get_output_socket(0));
operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked());
break;
}
case CMP_NODE_SCALE_ABSOLUTE: {
/* TODO: what is the use of this one.... perhaps some issues when the ui was updated... */
ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation();
converter.add_operation(operation);
converter.map_input_socket(input_socket, operation->get_input_socket(0));
converter.map_input_socket(input_xsocket, operation->get_input_socket(1));
converter.map_input_socket(input_ysocket, operation->get_input_socket(2));
converter.map_output_socket(output_socket, operation->get_output_socket(0));
operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked());
break;
}
}
}
} // namespace blender::compositor