Compositor: Turn Invert node options into inputs
This patch turns the options of the Invert node into inputs. Reference #137223. Pull Request: https://projects.blender.org/blender/blender/pulls/137527
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 26
|
||||
#define BLENDER_FILE_SUBVERSION 27
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -747,6 +747,11 @@ static void write_compositor_legacy_properties(bNodeTree &node_tree)
|
||||
const bNodeSocket *input = blender::bke::node_find_socket(*node, SOCK_IN, "Factor");
|
||||
node->custom1 = int(input->default_value_typed<bNodeSocketValueFloat>()->value * 100.0f);
|
||||
}
|
||||
|
||||
if (node->type_legacy == CMP_NODE_INVERT) {
|
||||
write_input_to_property_bool_int16_flag("Invert Color", node->custom1, CMP_CHAN_RGB);
|
||||
write_input_to_property_bool_int16_flag("Invert Alpha", node->custom1, CMP_CHAN_A);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2117,6 +2117,56 @@ static void do_version_split_node_options_to_inputs_animation(bNodeTree *node_tr
|
||||
});
|
||||
}
|
||||
|
||||
/* The options were converted into inputs. */
|
||||
static void do_version_invert_node_options_to_inputs(bNodeTree *node_tree, bNode *node)
|
||||
{
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Invert Color")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Invert Color", "Invert Color");
|
||||
input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1 &
|
||||
CMP_CHAN_RGB);
|
||||
}
|
||||
|
||||
if (!blender::bke::node_find_socket(*node, SOCK_IN, "Invert Alpha")) {
|
||||
bNodeSocket *input = blender::bke::node_add_static_socket(
|
||||
*node_tree, *node, SOCK_IN, SOCK_BOOLEAN, PROP_NONE, "Invert Alpha", "Invert Alpha");
|
||||
input->default_value_typed<bNodeSocketValueBoolean>()->value = bool(node->custom1 &
|
||||
CMP_CHAN_A);
|
||||
}
|
||||
}
|
||||
|
||||
/* The options were converted into inputs. */
|
||||
static void do_version_invert_node_options_to_inputs_animation(bNodeTree *node_tree, bNode *node)
|
||||
{
|
||||
/* Compute the RNA path of the node. */
|
||||
char escaped_node_name[sizeof(node->name) * 2 + 1];
|
||||
BLI_str_escape(escaped_node_name, node->name, sizeof(escaped_node_name));
|
||||
const std::string node_rna_path = fmt::format("nodes[\"{}\"]", escaped_node_name);
|
||||
|
||||
BKE_fcurves_id_cb(&node_tree->id, [&](ID * /*id*/, FCurve *fcurve) {
|
||||
/* The FCurve does not belong to the node since its RNA path doesn't start with the node's RNA
|
||||
* path. */
|
||||
if (!blender::StringRef(fcurve->rna_path).startswith(node_rna_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Change the RNA path of the FCurve from the old properties to the new inputs, adjusting the
|
||||
* values of the FCurves frames when needed. */
|
||||
char *old_rna_path = fcurve->rna_path;
|
||||
if (BLI_str_endswith(fcurve->rna_path, "invert_rgb")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[2].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(fcurve->rna_path, "invert_alpha")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", node_rna_path.c_str(), "inputs[3].default_value");
|
||||
}
|
||||
|
||||
/* The RNA path was changed, free the old path. */
|
||||
if (fcurve->rna_path != old_rna_path) {
|
||||
MEM_freeN(old_rna_path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void do_version_viewer_shortcut(bNodeTree *node_tree)
|
||||
{
|
||||
LISTBASE_FOREACH_MUTABLE (bNode *, node, &node_tree->nodes) {
|
||||
@@ -2623,6 +2673,19 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain)
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 27)) {
|
||||
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_INVERT) {
|
||||
do_version_invert_node_options_to_inputs_animation(node_tree, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||
@@ -7247,6 +7310,19 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 27)) {
|
||||
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_INVERT) {
|
||||
do_version_invert_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. */
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
#include "gpu_shader_common_color_utils.glsl"
|
||||
|
||||
void node_composite_invert(
|
||||
float fac, float4 color, float do_rgb, float do_alpha, out float4 result)
|
||||
float fac, float4 color, float invert_color, float invert_alpha, out float4 result)
|
||||
{
|
||||
result = color;
|
||||
if (do_rgb != 0.0f) {
|
||||
if (invert_color != 0.0f) {
|
||||
result.rgb = 1.0f - result.rgb;
|
||||
}
|
||||
if (do_alpha != 0.0f) {
|
||||
if (invert_alpha != 0.0f) {
|
||||
result.a = 1.0f - result.a;
|
||||
}
|
||||
result = mix(color, result, fac);
|
||||
|
||||
@@ -3881,6 +3881,10 @@ static const char node_input_motion_blur_shutter[] = "Motion Blur Shutter";
|
||||
/* Switch node. */
|
||||
static const char node_input_switch[] = "Switch";
|
||||
|
||||
/* Invert node. */
|
||||
static const char node_input_invert_color[] = "Invert Color";
|
||||
static const char node_input_invert_alpha[] = "Invert Alpha";
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* White Balance Node.
|
||||
*/
|
||||
@@ -8164,13 +8168,19 @@ static void def_cmp_invert(BlenderRNA * /*brna*/, StructRNA *srna)
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_property(srna, "invert_rgb", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "custom1", CMP_CHAN_RGB);
|
||||
RNA_def_property_ui_text(prop, "RGB", "");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop,
|
||||
"rna_node_property_to_input_getter<bool, node_input_invert_color>",
|
||||
"rna_node_property_to_input_setter<bool, node_input_invert_color>");
|
||||
RNA_def_property_ui_text(prop, "RGB", "(Deprecated: Use Invert Color node instead.)");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "invert_alpha", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "custom1", CMP_CHAN_A);
|
||||
RNA_def_property_ui_text(prop, "Alpha", "");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop,
|
||||
"rna_node_property_to_input_getter<bool, node_input_invert_alpha>",
|
||||
"rna_node_property_to_input_setter<bool, node_input_invert_alpha>");
|
||||
RNA_def_property_ui_text(prop, "Alpha", "(Deprecated: Use Invert Alpha node instead.)");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
|
||||
@@ -35,110 +35,40 @@ static void cmp_node_invert_declare(NodeDeclarationBuilder &b)
|
||||
b.add_input<decl::Color>("Color")
|
||||
.default_value({1.0f, 1.0f, 1.0f, 1.0f})
|
||||
.compositor_domain_priority(0);
|
||||
b.add_input<decl::Bool>("Invert Color").default_value(true).compositor_domain_priority(2);
|
||||
b.add_input<decl::Bool>("Invert Alpha").default_value(false).compositor_domain_priority(3);
|
||||
|
||||
b.add_output<decl::Color>("Color");
|
||||
}
|
||||
|
||||
static void node_composit_init_invert(bNodeTree * /*ntree*/, bNode *node)
|
||||
{
|
||||
node->custom1 |= CMP_CHAN_RGB;
|
||||
}
|
||||
|
||||
static void node_composit_buts_invert(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
{
|
||||
uiLayout *col;
|
||||
|
||||
col = uiLayoutColumn(layout, false);
|
||||
uiItemR(col, ptr, "invert_rgb", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
uiItemR(col, ptr, "invert_alpha", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
|
||||
}
|
||||
|
||||
using namespace blender::compositor;
|
||||
|
||||
static bool should_invert_rgb(const bNode &node)
|
||||
{
|
||||
return node.custom1 & CMP_CHAN_RGB;
|
||||
}
|
||||
|
||||
static bool should_invert_alpha(const bNode &node)
|
||||
{
|
||||
return node.custom1 & CMP_CHAN_A;
|
||||
}
|
||||
|
||||
static int node_gpu_material(GPUMaterial *material,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *inputs,
|
||||
GPUNodeStack *outputs)
|
||||
{
|
||||
const float do_rgb = should_invert_rgb(*node);
|
||||
const float do_alpha = should_invert_alpha(*node);
|
||||
|
||||
return GPU_stack_link(material,
|
||||
node,
|
||||
"node_composite_invert",
|
||||
inputs,
|
||||
outputs,
|
||||
GPU_constant(&do_rgb),
|
||||
GPU_constant(&do_alpha));
|
||||
}
|
||||
|
||||
template<bool ShouldInvertRGB, bool ShouldInvertAlpha>
|
||||
static float4 invert(const float factor, const float4 &color)
|
||||
{
|
||||
float4 result = color;
|
||||
if constexpr (ShouldInvertRGB) {
|
||||
result = float4(1.0f - result.xyz(), result.w);
|
||||
}
|
||||
if constexpr (ShouldInvertAlpha) {
|
||||
result = float4(result.xyz(), 1.0f - result.w);
|
||||
}
|
||||
return math::interpolate(color, result, factor);
|
||||
return GPU_stack_link(material, node, "node_composite_invert", inputs, outputs);
|
||||
}
|
||||
|
||||
static void node_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
|
||||
{
|
||||
static auto rgb_alpha_function = mf::build::SI2_SO<float, float4, float4>(
|
||||
"Invert RGB Alpha",
|
||||
[](const float factor, const float4 &color) -> float4 {
|
||||
return invert<true, true>(factor, color);
|
||||
static auto function = mf::build::SI4_SO<float, float4, bool, bool, float4>(
|
||||
"Invert Color",
|
||||
[](const float factor, const float4 &color, const bool invert_color, const bool invert_alpha)
|
||||
-> float4 {
|
||||
float4 result = color;
|
||||
if (invert_color) {
|
||||
result = float4(1.0f - result.xyz(), result.w);
|
||||
}
|
||||
if (invert_alpha) {
|
||||
result = float4(result.xyz(), 1.0f - result.w);
|
||||
}
|
||||
return math::interpolate(color, result, factor);
|
||||
},
|
||||
mf::build::exec_presets::SomeSpanOrSingle<1>());
|
||||
|
||||
static auto rgb_function = mf::build::SI2_SO<float, float4, float4>(
|
||||
"Invert RGB",
|
||||
[](const float factor, const float4 &color) -> float4 {
|
||||
return invert<true, false>(factor, color);
|
||||
},
|
||||
mf::build::exec_presets::SomeSpanOrSingle<1>());
|
||||
|
||||
static auto alpha_function = mf::build::SI2_SO<float, float4, float4>(
|
||||
"Invert Alpha",
|
||||
[](const float factor, const float4 &color) -> float4 {
|
||||
return invert<false, true>(factor, color);
|
||||
},
|
||||
mf::build::exec_presets::SomeSpanOrSingle<1>());
|
||||
|
||||
static auto identity_function = mf::build::SI2_SO<float, float4, float4>(
|
||||
"Identity",
|
||||
[](const float /*factor*/, const float4 &color) -> float4 { return color; },
|
||||
mf::build::exec_presets::SomeSpanOrSingle<1>());
|
||||
|
||||
if (should_invert_rgb(builder.node())) {
|
||||
if (should_invert_alpha(builder.node())) {
|
||||
builder.set_matching_fn(rgb_alpha_function);
|
||||
}
|
||||
else {
|
||||
builder.set_matching_fn(rgb_function);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (should_invert_alpha(builder.node())) {
|
||||
builder.set_matching_fn(alpha_function);
|
||||
}
|
||||
else {
|
||||
builder.set_matching_fn(identity_function);
|
||||
}
|
||||
}
|
||||
builder.set_matching_fn(function);
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::node_composite_invert_cc
|
||||
@@ -155,8 +85,6 @@ void register_node_type_cmp_invert()
|
||||
ntype.enum_name_legacy = "INVERT";
|
||||
ntype.nclass = NODE_CLASS_OP_COLOR;
|
||||
ntype.declare = file_ns::cmp_node_invert_declare;
|
||||
ntype.draw_buttons = file_ns::node_composit_buts_invert;
|
||||
ntype.initfunc = file_ns::node_composit_init_invert;
|
||||
ntype.gpu_fn = file_ns::node_gpu_material;
|
||||
ntype.build_multi_function = file_ns::node_build_multi_function;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user