WIP: Compositor: Add interpolation option to scale node #119902
|
@ -19,15 +19,31 @@ void ScaleNode::convert_to_operations(NodeConverter &converter,
|
|||
const CompositorContext &context) const
|
||||
{
|
||||
const bNode *bnode = this->get_bnode();
|
||||
const NodeScaleData *data = (const NodeScaleData *)bnode->storage;
|
||||
|
||||
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);
|
||||
|
||||
PixelSampler sampler = PixelSampler::Nearest;
|
||||
switch (data->interpolation) {
|
||||
case 0:
|
||||
sampler = PixelSampler::Nearest;
|
||||
break;
|
||||
case 1:
|
||||
sampler = PixelSampler::Bilinear;
|
||||
break;
|
||||
case 2:
|
||||
sampler = PixelSampler::Bicubic;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (bnode->custom1) {
|
||||
case CMP_NODE_SCALE_RELATIVE: {
|
||||
ScaleRelativeOperation *operation = new ScaleRelativeOperation();
|
||||
|
||||
operation->set_sampler(sampler);
|
||||
converter.add_operation(operation);
|
||||
|
||||
converter.map_input_socket(input_socket, operation->get_input_socket(0));
|
||||
|
@ -44,6 +60,8 @@ void ScaleNode::convert_to_operations(NodeConverter &converter,
|
|||
converter.add_operation(scale_factor_operation);
|
||||
|
||||
ScaleRelativeOperation *operation = new ScaleRelativeOperation();
|
||||
|
||||
operation->set_sampler(sampler);
|
||||
converter.add_operation(operation);
|
||||
|
||||
converter.map_input_socket(input_socket, operation->get_input_socket(0));
|
||||
|
@ -68,6 +86,7 @@ void ScaleNode::convert_to_operations(NodeConverter &converter,
|
|||
operation->set_offset(bnode->custom3, bnode->custom4);
|
||||
operation->set_new_width(rd->xsch * render_size_factor);
|
||||
operation->set_new_height(rd->ysch * render_size_factor);
|
||||
operation->set_sampler(sampler);
|
||||
converter.add_operation(operation);
|
||||
|
||||
converter.map_input_socket(input_socket, operation->get_input_socket(0));
|
||||
|
@ -80,6 +99,8 @@ void ScaleNode::convert_to_operations(NodeConverter &converter,
|
|||
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();
|
||||
|
||||
operation->set_sampler(sampler);
|
||||
converter.add_operation(operation);
|
||||
|
||||
converter.map_input_socket(input_socket, operation->get_input_socket(0));
|
||||
|
|
|
@ -23,9 +23,9 @@ class BaseScaleOperation : public MultiThreadedOperation {
|
|||
protected:
|
||||
BaseScaleOperation();
|
||||
|
||||
PixelSampler get_effective_sampler(PixelSampler sampler)
|
||||
PixelSampler get_effective_sampler()
|
||||
{
|
||||
return (sampler_ == -1) ? sampler : (PixelSampler)sampler_;
|
||||
return (PixelSampler)sampler_;
|
||||
}
|
||||
|
||||
int sampler_;
|
||||
|
|
|
@ -1418,6 +1418,13 @@ typedef struct NodeTranslateData {
|
|||
char relative;
|
||||
} NodeTranslateData;
|
||||
|
||||
typedef struct NodeScaleData {
|
||||
int16_t space, frame_method;
|
||||
float offset_x, offset_y;
|
||||
short interpolation;
|
||||
char _pad[2];
|
||||
} NodeScaleData;
|
||||
|
||||
typedef struct NodePlaneTrackDeformData {
|
||||
char tracking_object[64];
|
||||
char plane_track_name[64];
|
||||
|
|
|
@ -6612,28 +6612,55 @@ static void def_cmp_scale(StructRNA *srna)
|
|||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem interpolation_items[] = {
|
||||
{CMP_NODE_STABILIZE_INTERPOLATION_NEAREST,
|
||||
"NEAREST",
|
||||
0,
|
||||
"Nearest",
|
||||
"Use nearest interpolation"},
|
||||
{CMP_NODE_STABILIZE_INTERPOLATION_BILINEAR,
|
||||
"BILINEAR",
|
||||
0,
|
||||
"Bilinear",
|
||||
"Use bilinear interpolation"},
|
||||
{CMP_NODE_STABILIZE_INTERPOLATION_BICUBIC,
|
||||
"BICUBIC",
|
||||
0,
|
||||
"Bicubic",
|
||||
"Use bicubic interpolation"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
RNA_def_struct_sdna_from(srna, "NodeScaleData", "storage");
|
||||
|
||||
prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "custom1");
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "space");
|
||||
RNA_def_property_enum_items(prop, space_items);
|
||||
RNA_def_property_ui_text(prop, "Space", "Coordinate space to scale relative to");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_CompositorNodeScale_update");
|
||||
|
||||
/* expose 2 flags as a enum of 3 items */
|
||||
prop = RNA_def_property(srna, "frame_method", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, nullptr, "custom2");
|
||||
RNA_def_property_enum_bitflag_sdna(prop, nullptr, "frame_method");
|
||||
RNA_def_property_enum_items(prop, space_frame_items);
|
||||
RNA_def_property_ui_text(prop, "Frame Method", "How the image fits in the camera frame");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, nullptr, "custom3");
|
||||
RNA_def_property_float_sdna(prop, nullptr, "offset_x");
|
||||
RNA_def_property_ui_text(prop, "X Offset", "Offset image horizontally (factor of image size)");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, nullptr, "custom4");
|
||||
RNA_def_property_float_sdna(prop, nullptr, "offset_y");
|
||||
RNA_def_property_ui_text(prop, "Y Offset", "Offset image vertically (factor of image size)");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "interpolation");
|
||||
RNA_def_property_enum_items(prop, interpolation_items);
|
||||
RNA_def_property_ui_text(prop, "Interpolation", "Which interpolation method to use");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_cmp_rotate(StructRNA *srna)
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
namespace blender::nodes::node_composite_scale_cc {
|
||||
|
||||
NODE_STORAGE_FUNCS(NodeScaleData)
|
||||
|
||||
static void cmp_node_scale_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Color>("Image")
|
||||
|
@ -46,6 +48,12 @@ static void cmp_node_scale_declare(NodeDeclarationBuilder &b)
|
|||
b.add_output<decl::Color>("Image");
|
||||
}
|
||||
|
||||
static void node_composit_init_scale(bNodeTree * /*ntree*/, bNode *node)
|
||||
{
|
||||
NodeScaleData *data = MEM_cnew<NodeScaleData>(__func__);
|
||||
node->storage = data;
|
||||
}
|
||||
|
||||
static void node_composite_update_scale(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
bool use_xy_scale = ELEM(node->custom1, CMP_NODE_SCALE_RELATIVE, CMP_NODE_SCALE_ABSOLUTE);
|
||||
|
@ -60,6 +68,7 @@ static void node_composite_update_scale(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_composit_buts_scale(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "interpolation", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
|
||||
uiItemR(layout, ptr, "space", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
|
||||
|
||||
if (RNA_enum_get(ptr, "space") == CMP_NODE_SCALE_RENDER_SIZE) {
|
||||
|
@ -93,7 +102,10 @@ class ScaleOperation : public NodeOperation {
|
|||
const float3x3 transformation = math::from_loc_rot_scale<float3x3>(
|
||||
translation, rotation, scale);
|
||||
|
||||
transform(context(), input, output, transformation, input.get_realization_options());
|
||||
RealizationOptions realization_options = input.get_realization_options();
|
||||
realization_options.interpolation = get_interpolation();
|
||||
|
||||
transform(context(), input, output, transformation, realization_options);
|
||||
}
|
||||
|
||||
float2 get_scale()
|
||||
|
@ -113,6 +125,21 @@ class ScaleOperation : public NodeOperation {
|
|||
}
|
||||
}
|
||||
|
||||
Interpolation get_interpolation()
|
||||
{
|
||||
switch (node_storage(bnode()).interpolation) {
|
||||
case 0:
|
||||
return Interpolation::Nearest;
|
||||
case 1:
|
||||
return Interpolation::Bilinear;
|
||||
case 2:
|
||||
return Interpolation::Bicubic;
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
return Interpolation::Nearest;
|
||||
}
|
||||
|
||||
/* Scale by the input factors. */
|
||||
float2 get_scale_relative()
|
||||
{
|
||||
|
@ -201,17 +228,17 @@ class ScaleOperation : public NodeOperation {
|
|||
|
||||
CMPNodeScaleMethod get_scale_method()
|
||||
{
|
||||
return (CMPNodeScaleMethod)bnode().custom1;
|
||||
return (CMPNodeScaleMethod)node_storage(bnode()).space;
|
||||
}
|
||||
|
||||
CMPNodeScaleRenderSizeMethod get_scale_render_size_method()
|
||||
{
|
||||
return (CMPNodeScaleRenderSizeMethod)bnode().custom2;
|
||||
return (CMPNodeScaleRenderSizeMethod)node_storage(bnode()).frame_method;
|
||||
}
|
||||
|
||||
float2 get_offset()
|
||||
{
|
||||
return float2(bnode().custom3, bnode().custom4);
|
||||
return float2(node_storage(bnode()).offset_x, node_storage(bnode()).offset_y);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -233,6 +260,7 @@ void register_node_type_cmp_scale()
|
|||
ntype.draw_buttons = file_ns::node_composit_buts_scale;
|
||||
ntype.updatefunc = file_ns::node_composite_update_scale;
|
||||
ntype.get_compositor_operation = file_ns::get_compositor_operation;
|
||||
ntype.initfunc = file_ns::node_composit_init_scale;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue