From 0ad73bb9655f04afb5ad56174d8fb416cded3e4c Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 28 Apr 2022 08:39:30 -0500 Subject: Geometry Nodes: Add default attribute name to field inputs/outputs Geometry node group inputs and outputs get a new property that controls the attribute name used for that field input/output when assigning the node group to a modifier for the first time. If the default name is assigned to an input, the default "Use attribute name" is true . In order to properly detect when a node group is first assigned, the modifier now clears its properties when clearing the node group. Ref T96707 Differential Revision: https://developer.blender.org/D14761 --- release/scripts/startup/bl_ui/space_node.py | 6 ++++-- source/blender/blenkernel/intern/node.cc | 9 +++++++++ source/blender/makesdna/DNA_node_types.h | 8 ++++++++ source/blender/makesrna/intern/rna_nodetree.c | 8 ++++++++ source/blender/modifiers/intern/MOD_nodes.cc | 28 +++++++++++++++++++++++---- 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index cc673a8bc39..e105b07ec53 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -797,8 +797,10 @@ class NodeTreeInterfacePanel: active_socket.bl_socket_idname.startswith(prefix) for prefix in field_socket_prefixes ) - if in_out == 'OUT' and is_field_type: - layout.prop(active_socket, "attribute_domain") + if is_field_type: + if in_out == 'OUT': + layout.prop(active_socket, "attribute_domain") + layout.prop(active_socket, "default_attribute_name") active_socket.draw(context, layout) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 4acccca322a..d3f61d381f2 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -487,6 +487,9 @@ static void write_node_socket(BlendWriter *writer, bNodeSocket *sock) IDP_BlendWrite(writer, sock->prop); } + /* This property should only be used for group node "interface" sockets. */ + BLI_assert(sock->default_attribute_name == nullptr); + write_node_socket_default_value(writer, sock); } static void write_node_socket_interface(BlendWriter *writer, bNodeSocket *sock) @@ -497,6 +500,8 @@ static void write_node_socket_interface(BlendWriter *writer, bNodeSocket *sock) IDP_BlendWrite(writer, sock->prop); } + BLO_write_string(writer, sock->default_attribute_name); + write_node_socket_default_value(writer, sock); } @@ -650,6 +655,7 @@ static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock) sock->typeinfo = nullptr; BLO_read_data_address(reader, &sock->storage); BLO_read_data_address(reader, &sock->default_value); + BLO_read_data_address(reader, &sock->default_attribute_name); sock->total_inputs = 0; /* Clear runtime data set before drawing. */ sock->cache = nullptr; sock->declaration = nullptr; @@ -2161,6 +2167,9 @@ static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, } } + sock_dst->default_attribute_name = static_cast( + MEM_dupallocN(sock_src->default_attribute_name)); + sock_dst->stack_index = 0; /* XXX some compositor nodes (e.g. image, render layers) still store * some persistent buffer data here, need to clear this to avoid dangling pointers. */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 1b9192c75cf..d18fe1b81dd 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -139,6 +139,14 @@ typedef struct bNodeSocket { char label[64]; char description[64]; + /** + * The default attribute name to use for geometry nodes modifier output attribute sockets. + * \note Storing this pointer in every single socket exposes the bad design of using sockets + * to describe group inputs and outputs. In the future, it should be stored in socket + * declarations. + */ + char *default_attribute_name; + /** Cached data from execution. */ void *cache; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4195782db08..4d68330c84d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -10890,6 +10890,14 @@ static void rna_def_node_socket_interface(BlenderRNA *brna) "Attribute domain used by the geometry nodes modifier to create an attribute output"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + prop = RNA_def_property(srna, "default_attribute_name", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "default_attribute_name"); + RNA_def_property_ui_text(prop, + "Default Attribute", + "The attribute name used by default when the node group is used by a " + "geometry nodes modifier"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + /* registration */ prop = RNA_def_property(srna, "bl_socket_idname", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname"); diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 3867abbd29c..1c890190678 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -628,6 +628,10 @@ static void init_socket_cpp_value_from_property(const IDProperty &property, void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd) { if (nmd->node_group == nullptr) { + if (nmd->settings.properties) { + IDP_FreeProperty(nmd->settings.properties); + nmd->settings.properties = nullptr; + } return; } @@ -680,7 +684,13 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd) IDProperty *attribute_prop = IDP_New(IDP_STRING, &idprop, attribute_name_id.c_str()); IDP_AddToGroup(nmd->settings.properties, attribute_prop); - if (old_properties != nullptr) { + if (old_properties == nullptr) { + if (socket->default_attribute_name && socket->default_attribute_name[0] != '\0') { + IDP_AssignString(attribute_prop, socket->default_attribute_name, MAX_NAME); + IDP_Int(use_attribute_prop) = 1; + } + } + else { IDProperty *old_prop_use_attribute = IDP_GetPropertyFromGroup(old_properties, use_attribute_id.c_str()); if (old_prop_use_attribute != nullptr) { @@ -709,7 +719,12 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd) } IDP_AddToGroup(nmd->settings.properties, new_prop); - if (old_properties != nullptr) { + if (old_properties == nullptr) { + if (socket->default_attribute_name && socket->default_attribute_name[0] != '\0') { + IDP_AssignString(new_prop, socket->default_attribute_name, MAX_NAME); + } + } + else { IDProperty *old_prop = IDP_GetPropertyFromGroup(old_properties, idprop_name.c_str()); if (old_prop != nullptr) { /* #IDP_CopyPropertyContent replaces the UI data as well, which we don't (we only @@ -1728,8 +1743,13 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md) static void blendRead(BlendDataReader *reader, ModifierData *md) { NodesModifierData *nmd = reinterpret_cast(md); - BLO_read_data_address(reader, &nmd->settings.properties); - IDP_BlendDataRead(reader, &nmd->settings.properties); + if (nmd->node_group == nullptr) { + nmd->settings.properties = nullptr; + } + else { + BLO_read_data_address(reader, &nmd->settings.properties); + IDP_BlendDataRead(reader, &nmd->settings.properties); + } nmd->runtime_eval_log = nullptr; } -- cgit v1.2.3