From 6b7d0fe425c692cb83df926dbb1192ece5c95219 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Fri, 20 Oct 2023 14:51:30 +0200 Subject: [PATCH] GPv3: Layer Selection modifier input Known limitations to be addressed separately: * We are not warning/keeping track of the named layers. * There is no lookup for layers (groups) yet. Ref !113908. --- .../intern/node_tree_field_inferencing.cc | 4 ++++ source/blender/editors/space_node/drawnode.cc | 17 +++++++++++++---- .../makesdna/DNA_node_tree_interface_types.h | 3 ++- .../intern/rna_node_tree_interface.cc | 7 +++++++ source/blender/modifiers/intern/MOD_nodes.cc | 10 +++++++++- source/blender/nodes/NOD_geometry.hh | 5 +++++ .../nodes/geometry/node_geometry_tree.cc | 14 ++++++++++++++ .../nodes/intern/geometry_nodes_execute.cc | 19 +++++++++++++++++++ 8 files changed, 73 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc index 62134ecdada..d584e42d749 100644 --- a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc +++ b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc @@ -5,6 +5,7 @@ #include "BKE_node.hh" #include "BKE_node_runtime.hh" +#include "NOD_geometry.hh" #include "NOD_node_declaration.hh" #include "NOD_socket.hh" @@ -507,6 +508,9 @@ static void determine_group_input_states( else if (group_input->default_input != NODE_INPUT_DEFAULT_VALUE) { new_inferencing_interface.inputs[index] = InputSocketFieldType::Implicit; } + else if (is_layer_selection_field(*group_input)) { + new_inferencing_interface.inputs[index] = InputSocketFieldType::Implicit; + } else if (group_input->flag & NODE_INTERFACE_SOCKET_SINGLE_VALUE_ONLY) { new_inferencing_interface.inputs[index] = InputSocketFieldType::None; } diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 461804df246..bd2b53b63e9 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1523,11 +1523,20 @@ static void std_node_socket_interface_draw(ID *id, } if (interface_socket->flag & NODE_INTERFACE_SOCKET_INPUT && node_tree->type == NTREE_GEOMETRY) { - uiItemR(col, &ptr, "hide_in_modifier", DEFAULT_FLAGS, nullptr, ICON_NONE); + if (U.experimental.use_grease_pencil_version3) { + if (type == SOCK_BOOLEAN) { + uiItemR(col, &ptr, "layer_selection_field", DEFAULT_FLAGS, nullptr, ICON_NONE); + } + } + uiLayout *sub = uiLayoutColumn(col, false); + uiLayoutSetActive(sub, !is_layer_selection_field(*interface_socket)); + uiItemR(sub, &ptr, "hide_in_modifier", DEFAULT_FLAGS, nullptr, ICON_NONE); if (nodes::socket_type_supports_fields(type)) { - uiLayout *sub = uiLayoutColumn(col, false); - uiLayoutSetActive(sub, interface_socket->default_input == NODE_INPUT_DEFAULT_VALUE); - uiItemR(sub, &ptr, "force_non_field", DEFAULT_FLAGS, nullptr, ICON_NONE); + uiLayout *sub_sub = uiLayoutColumn(col, false); + uiLayoutSetActive(sub_sub, + (interface_socket->default_input == NODE_INPUT_DEFAULT_VALUE) && + !is_layer_selection_field(*interface_socket)); + uiItemR(sub_sub, &ptr, "force_non_field", DEFAULT_FLAGS, nullptr, ICON_NONE); } } } diff --git a/source/blender/makesdna/DNA_node_tree_interface_types.h b/source/blender/makesdna/DNA_node_tree_interface_types.h index 7a30d44791f..20e4d8a4a96 100644 --- a/source/blender/makesdna/DNA_node_tree_interface_types.h +++ b/source/blender/makesdna/DNA_node_tree_interface_types.h @@ -64,8 +64,9 @@ typedef enum NodeTreeInterfaceSocketFlag { NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER = 1 << 3, NODE_INTERFACE_SOCKET_COMPACT = 1 << 4, NODE_INTERFACE_SOCKET_SINGLE_VALUE_ONLY = 1 << 5, + NODE_INTERFACE_SOCKET_LAYER_SELECTION = 1 << 6, } NodeTreeInterfaceSocketFlag; -ENUM_OPERATORS(NodeTreeInterfaceSocketFlag, NODE_INTERFACE_SOCKET_SINGLE_VALUE_ONLY); +ENUM_OPERATORS(NodeTreeInterfaceSocketFlag, NODE_INTERFACE_SOCKET_LAYER_SELECTION); typedef struct bNodeTreeInterfaceSocket { bNodeTreeInterfaceItem item; diff --git a/source/blender/makesrna/intern/rna_node_tree_interface.cc b/source/blender/makesrna/intern/rna_node_tree_interface.cc index 409a52b74da..a124f475292 100644 --- a/source/blender/makesrna/intern/rna_node_tree_interface.cc +++ b/source/blender/makesrna/intern/rna_node_tree_interface.cc @@ -1000,6 +1000,13 @@ static void rna_def_node_interface_socket(BlenderRNA *brna) prop, "Single Value", "Only allow single value inputs rather than fields"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update"); + prop = RNA_def_property(srna, "layer_selection_field", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, nullptr, "flag", NODE_INTERFACE_SOCKET_LAYER_SELECTION); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text( + prop, "Layer Selection", "Take Grease Pencil Layer or Layer Group as selection field"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update"); + prop = RNA_def_property(srna, "attribute_domain", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_domain_items); RNA_def_property_enum_funcs( diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 3ef7dfccff7..842059f6120 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1621,6 +1621,13 @@ static void draw_property_for_socket(const bContext &C, uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "images", name, ICON_IMAGE); break; } + case SOCK_BOOLEAN: { + if (is_layer_selection_field(socket)) { + uiItemR(row, md_ptr, rna_path, UI_ITEM_NONE, name, ICON_NONE); + break; + } + ATTR_FALLTHROUGH; + } default: { if (nodes::input_has_attribute_toggle(*nmd->node_group, socket_index)) { add_attribute_search_or_value_buttons(C, row, *nmd, md_ptr, socket); @@ -1689,7 +1696,8 @@ static void panel_draw(const bContext *C, Panel *panel) for (const int socket_index : nmd->node_group->interface_inputs().index_range()) { const bNodeTreeInterfaceSocket *socket = nmd->node_group->interface_inputs()[socket_index]; - if (!(socket->flag & NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER)) { + if (is_layer_selection_field(*socket) || + !(socket->flag & NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER)) { draw_property_for_socket(*C, layout, nmd, &bmain_ptr, ptr, *socket, socket_index); } } diff --git a/source/blender/nodes/NOD_geometry.hh b/source/blender/nodes/NOD_geometry.hh index 474840a7fc7..390592a5435 100644 --- a/source/blender/nodes/NOD_geometry.hh +++ b/source/blender/nodes/NOD_geometry.hh @@ -10,3 +10,8 @@ extern bNodeTreeType *ntreeType_Geometry; void register_node_tree_type_geo(); void register_node_type_geo_custom_group(bNodeType *ntype); + +/** + * Returns true if the socket is a Named Layer Selection field. + */ +bool is_layer_selection_field(const bNodeTreeInterfaceSocket &socket); diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc index a1eb0c60a81..873dea72a18 100644 --- a/source/blender/nodes/geometry/node_geometry_tree.cc +++ b/source/blender/nodes/geometry/node_geometry_tree.cc @@ -134,3 +134,17 @@ void register_node_tree_type_geo() ntreeTypeAdd(tt); } + +bool is_layer_selection_field(const bNodeTreeInterfaceSocket &socket) +{ + if (!U.experimental.use_grease_pencil_version3) { + return false; + } + const bNodeSocketType *typeinfo = socket.socket_typeinfo(); + BLI_assert(typeinfo != nullptr); + + if (typeinfo->type != SOCK_BOOLEAN) { + return false; + } + return (socket.flag & NODE_INTERFACE_SOCKET_LAYER_SELECTION) != 0; +} diff --git a/source/blender/nodes/intern/geometry_nodes_execute.cc b/source/blender/nodes/intern/geometry_nodes_execute.cc index 1aa6afceb06..1bd77e2d270 100644 --- a/source/blender/nodes/intern/geometry_nodes_execute.cc +++ b/source/blender/nodes/intern/geometry_nodes_execute.cc @@ -11,6 +11,7 @@ #include "BLI_math_quaternion.hh" #include "BLI_string.h" +#include "NOD_geometry.hh" #include "NOD_geometry_nodes_execute.hh" #include "NOD_geometry_nodes_lazy_function.hh" #include "NOD_node_declaration.hh" @@ -119,6 +120,10 @@ std::unique_ptr id_property_create_f return property; } case SOCK_BOOLEAN: { + if (is_layer_selection_field(socket)) { + /* We can't use the value from the socket here since it doesn't storing a string. */ + return bke::idprop::create(identifier, ""); + } const bNodeSocketValueBoolean *value = static_cast( socket.socket_data); auto property = bke::idprop::create_bool(identifier, value->value); @@ -200,6 +205,9 @@ bool id_property_type_matches_socket(const bNodeTreeInterfaceSocket &socket, return property.type == IDP_ARRAY && ELEM(property.subtype, IDP_INT, IDP_FLOAT, IDP_DOUBLE) && property.len == 4; case SOCK_BOOLEAN: + if (is_layer_selection_field(socket)) { + return property.type == IDP_STRING; + } return property.type == IDP_BOOLEAN; case SOCK_STRING: return property.type == IDP_STRING; @@ -398,6 +406,17 @@ static void initialize_group_input(const bNodeTree &tree, BLI_assert(value_or_field_cpp_type != nullptr); value_or_field_cpp_type->construct_from_field(r_value, std::move(attribute_field)); } + else if (is_layer_selection_field(io_input)) { + const IDProperty *property_layer_name = IDP_GetPropertyFromGroup(properties, + io_input.identifier); + StringRef layer_name = IDP_String(property_layer_name); + const fn::GField selection_field( + std::make_shared(layer_name), 0); + const auto *value_or_field_cpp_type = fn::ValueOrFieldCPPType::get_from_self( + *typeinfo->geometry_nodes_cpp_type); + BLI_assert(value_or_field_cpp_type != nullptr); + value_or_field_cpp_type->construct_from_field(r_value, std::move(selection_field)); + } else { init_socket_cpp_value_from_property(*property, socket_data_type, r_value); }