Compositor: Turn Flip node options to inputs

This patch turns the Flip node options to inputs.

Reference #137223.

Pull Request: https://projects.blender.org/blender/blender/pulls/139722
This commit is contained in:
Omar Emara
2025-06-02 12:48:00 +02:00
committed by Omar Emara
parent 0e8d041cb3
commit 425be6bb02
5 changed files with 92 additions and 25 deletions

View File

@@ -27,7 +27,7 @@
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 84
#define BLENDER_FILE_SUBVERSION 85
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@@ -1146,6 +1146,22 @@ static void write_compositor_legacy_properties(bNodeTree &node_tree)
storage->sizey = int(
math::ceil(size_input->default_value_typed<bNodeSocketValueVector>()->value[1]));
}
if (node->type_legacy == CMP_NODE_FLIP) {
const bNodeSocket *x_input = blender::bke::node_find_socket(*node, SOCK_IN, "Flip X");
const bNodeSocket *y_input = blender::bke::node_find_socket(*node, SOCK_IN, "Flip Y");
const bool flip_x = x_input->default_value_typed<bNodeSocketValueBoolean>()->value;
const bool flip_y = y_input->default_value_typed<bNodeSocketValueBoolean>()->value;
if (flip_x && flip_y) {
node->custom1 = 2;
}
else if (flip_y) {
node->custom1 = 1;
}
else {
node->custom1 = 0;
}
}
}
}

View File

@@ -4305,6 +4305,22 @@ static void do_convert_gp_jitter_flags(Brush *brush)
}
}
/* The options were converted into inputs. */
static void do_version_flip_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
{
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Flip X")) {
bNodeSocket *input = blender::bke::node_add_static_socket(
*node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Flip X", "Flip X");
input->default_value_typed<bNodeSocketValueBoolean>()->value = ELEM(node->custom1, 0, 2);
}
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Flip Y")) {
bNodeSocket *input = blender::bke::node_add_static_socket(
*node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Flip Y", "Flip Y");
input->default_value_typed<bNodeSocketValueBoolean>()->value = ELEM(node->custom1, 1, 2);
}
}
void do_versions_after_linking_450(FileData * /*fd*/, Main *bmain)
{
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 8)) {
@@ -6154,6 +6170,20 @@ void blo_do_versions_450(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
}
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 85)) {
FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
if (node_tree->type == NTREE_COMPOSIT) {
LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
if (node->type_legacy == CMP_NODE_FLIP) {
do_version_flip_node_options_to_inputs(node_tree, node);
}
}
}
}
FOREACH_NODETREE_END;
}
/* Always run this versioning (keep at the bottom of the function). Meshes are written with the
* legacy format which always needs to be converted to the new format on file load. To be moved
* to a subversion check in 5.0. */

View File

@@ -3985,6 +3985,33 @@ static void rna_NodeCrop_size_y_set(PointerRNA *ptr, const int value)
input->default_value_typed<bNodeSocketValueVector>()->value[1] = float(value);
}
static int rna_NodeFlip_axis_get(PointerRNA *ptr)
{
bNode *node = ptr->data_as<bNode>();
const bNodeSocket *x_input = blender::bke::node_find_socket(*node, SOCK_IN, "Flip X");
const bNodeSocket *y_input = blender::bke::node_find_socket(*node, SOCK_IN, "Flip Y");
const bool flip_x = x_input->default_value_typed<bNodeSocketValueBoolean>()->value;
const bool flip_y = y_input->default_value_typed<bNodeSocketValueBoolean>()->value;
if (flip_x && flip_y) {
return 2;
}
if (flip_y) {
return 1;
}
return 0;
}
static void rna_NodeFlip_axis_set(PointerRNA *ptr, const int value)
{
bNode *node = ptr->data_as<bNode>();
bNodeSocket *x_input = blender::bke::node_find_socket(*node, SOCK_IN, "Flip X");
bNodeSocket *y_input = blender::bke::node_find_socket(*node, SOCK_IN, "Flip Y");
x_input->default_value_typed<bNodeSocketValueBoolean>()->value = value != 1;
y_input->default_value_typed<bNodeSocketValueBoolean>()->value = value != 0;
}
/* A getter that returns the value of the input socket with the given template identifier and type.
* The RNA pointer is assumed to represent a node. */
template<typename T, const char *identifier>
@@ -8544,9 +8571,9 @@ static void def_cmp_flip(BlenderRNA * /*brna*/, StructRNA *srna)
PropertyRNA *prop;
prop = RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, nullptr, "custom1");
RNA_def_property_enum_funcs(prop, "rna_NodeFlip_axis_get", "rna_NodeFlip_axis_set", nullptr);
RNA_def_property_enum_items(prop, node_flip_items);
RNA_def_property_ui_text(prop, "Axis", "");
RNA_def_property_ui_text(prop, "Axis", "(Deprecated: Use Flip X and Flip Y inputs instead.)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}

View File

@@ -7,10 +7,6 @@
*/
#include "BLI_math_vector_types.hh"
#include "BLI_utildefines.h"
#include "UI_interface.hh"
#include "UI_resources.hh"
#include "GPU_shader.hh"
@@ -25,15 +21,11 @@ namespace blender::nodes::node_composite_flip_cc {
static void cmp_node_flip_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Color>("Image")
.default_value({1.0f, 1.0f, 1.0f, 1.0f})
.compositor_domain_priority(0);
b.add_output<decl::Color>("Image");
}
b.add_input<decl::Color>("Image").default_value({1.0f, 1.0f, 1.0f, 1.0f});
b.add_input<decl::Bool>("Flip X").default_value(false).compositor_expects_single_value();
b.add_input<decl::Bool>("Flip Y").default_value(false).compositor_expects_single_value();
static void node_composit_buts_flip(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
layout->prop(ptr, "axis", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
b.add_output<decl::Color>("Image");
}
using namespace blender::compositor;
@@ -45,7 +37,7 @@ class FlipOperation : public NodeOperation {
void execute() override
{
const Result &input = this->get_input("Image");
if (input.is_single_value()) {
if (input.is_single_value() || (!this->get_flip_x() && !this->get_flip_y())) {
Result &output = this->get_result("Image");
output.share_data(input);
return;
@@ -64,10 +56,8 @@ class FlipOperation : public NodeOperation {
GPUShader *shader = context().get_shader("compositor_flip");
GPU_shader_bind(shader);
GPU_shader_uniform_1b(
shader, "flip_x", ELEM(get_flip_mode(), CMP_NODE_FLIP_X, CMP_NODE_FLIP_X_Y));
GPU_shader_uniform_1b(
shader, "flip_y", ELEM(get_flip_mode(), CMP_NODE_FLIP_Y, CMP_NODE_FLIP_X_Y));
GPU_shader_uniform_1b(shader, "flip_x", this->get_flip_x());
GPU_shader_uniform_1b(shader, "flip_y", this->get_flip_y());
Result &input = get_input("Image");
input.bind_as_texture(shader, "input_tx");
@@ -86,8 +76,8 @@ class FlipOperation : public NodeOperation {
void execute_cpu()
{
const bool flip_x = ELEM(get_flip_mode(), CMP_NODE_FLIP_X, CMP_NODE_FLIP_X_Y);
const bool flip_y = ELEM(get_flip_mode(), CMP_NODE_FLIP_Y, CMP_NODE_FLIP_X_Y);
const bool flip_x = this->get_flip_x();
const bool flip_y = this->get_flip_y();
Result &input = get_input("Image");
@@ -108,9 +98,14 @@ class FlipOperation : public NodeOperation {
});
}
CMPNodeFlipMode get_flip_mode()
bool get_flip_x()
{
return static_cast<CMPNodeFlipMode>(bnode().custom1);
return this->get_input("Flip X").get_single_value_default(false);
}
bool get_flip_y()
{
return this->get_input("Flip Y").get_single_value_default(false);
}
};
@@ -133,7 +128,6 @@ static void register_node_type_cmp_flip()
ntype.enum_name_legacy = "FLIP";
ntype.nclass = NODE_CLASS_DISTORT;
ntype.declare = file_ns::cmp_node_flip_declare;
ntype.draw_buttons = file_ns::node_composit_buts_flip;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
blender::bke::node_register_type(ntype);