diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index b14594ba5da..c9b0737e487 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -48,6 +48,7 @@ #include "BKE_geometry_set.hh" #include "BKE_global.h" #include "BKE_gpencil_modifier_legacy.h" +#include "BKE_idprop.h" #include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_layer.h" @@ -3623,15 +3624,24 @@ static int geometry_nodes_input_attribute_toggle_exec(bContext *C, wmOperator *o return OPERATOR_CANCELLED; } - char prop_path[MAX_NAME]; - RNA_string_get(op->ptr, "prop_path", prop_path); + char input_name[MAX_NAME]; + RNA_string_get(op->ptr, "input_name", input_name); - PointerRNA mod_ptr; - RNA_pointer_create(&ob->id, &RNA_Modifier, nmd, &mod_ptr); + IDProperty *use_attribute = IDP_GetPropertyFromGroup( + nmd->settings.properties, std::string(input_name + std::string("_use_attribute")).c_str()); + if (!use_attribute) { + return OPERATOR_CANCELLED; + } - const int old_value = RNA_int_get(&mod_ptr, prop_path); - const int new_value = !old_value; - RNA_int_set(&mod_ptr, prop_path, new_value); + if (use_attribute->type == IDP_INT) { + IDP_Int(use_attribute) = !IDP_Int(use_attribute); + } + else if (use_attribute->type == IDP_BOOLEAN) { + IDP_Bool(use_attribute) = !IDP_Bool(use_attribute); + } + else { + return OPERATOR_CANCELLED; + } DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -3650,7 +3660,7 @@ void OBJECT_OT_geometry_nodes_input_attribute_toggle(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - RNA_def_string(ot->srna, "prop_path", nullptr, 0, "Prop Path", ""); + RNA_def_string(ot->srna, "input_name", nullptr, 0, "Input Name", ""); RNA_def_string(ot->srna, "modifier_name", nullptr, MAX_NAME, "Modifier Name", ""); } diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index f1ef2e800ea..abca50e936a 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1121,8 +1121,6 @@ static void add_attribute_search_or_value_buttons(const bContext &C, char socket_id_esc[sizeof(socket.identifier) * 2]; BLI_str_escape(socket_id_esc, socket.identifier, sizeof(socket_id_esc)); const std::string rna_path = "[\"" + std::string(socket_id_esc) + "\"]"; - const std::string rna_path_use_attribute = "[\"" + std::string(socket_id_esc) + - nodes::input_use_attribute_suffix() + "\"]"; const std::string rna_path_attribute_name = "[\"" + std::string(socket_id_esc) + nodes::input_attribute_name_suffix() + "\"]"; @@ -1133,8 +1131,9 @@ static void add_attribute_search_or_value_buttons(const bContext &C, uiLayout *name_row = uiLayoutRow(split, false); uiLayoutSetAlignment(name_row, UI_LAYOUT_ALIGN_RIGHT); - const int use_attribute = RNA_int_get(md_ptr, rna_path_use_attribute.c_str()) != 0; - if (socket.type == SOCK_BOOLEAN && !use_attribute) { + const std::optional attribute_name = nodes::input_attribute_name_get( + *nmd.settings.properties, socket); + if (socket.type == SOCK_BOOLEAN && !attribute_name) { uiItemL(name_row, "", ICON_NONE); } else { @@ -1147,7 +1146,7 @@ static void add_attribute_search_or_value_buttons(const bContext &C, uiLayoutSetAlignment(prop_row, UI_LAYOUT_ALIGN_EXPAND); } - if (use_attribute) { + if (attribute_name) { add_attribute_search_button(C, prop_row, nmd, md_ptr, rna_path_attribute_name, socket, false); uiItemL(layout, "", ICON_BLANK1); } @@ -1167,7 +1166,7 @@ static void add_attribute_search_or_value_buttons(const bContext &C, UI_ITEM_NONE, &props); RNA_string_set(&props, "modifier_name", nmd.modifier.name); - RNA_string_set(&props, "prop_path", rna_path_use_attribute.c_str()); + RNA_string_set(&props, "input_name", socket.identifier); } /* Drawing the properties manually with #uiItemR instead of #uiDefAutoButsRNA allows using diff --git a/source/blender/nodes/NOD_geometry_nodes_execute.hh b/source/blender/nodes/NOD_geometry_nodes_execute.hh index fc1e575bdc4..4b448f6747d 100644 --- a/source/blender/nodes/NOD_geometry_nodes_execute.hh +++ b/source/blender/nodes/NOD_geometry_nodes_execute.hh @@ -30,6 +30,9 @@ namespace blender::nodes { StringRef input_use_attribute_suffix(); StringRef input_attribute_name_suffix(); +std::optional input_attribute_name_get(const IDProperty &props, + const bNodeSocket &io_input); + /** * \return Whether using an attribute to input values of this type is supported. */ diff --git a/source/blender/nodes/intern/geometry_nodes_execute.cc b/source/blender/nodes/intern/geometry_nodes_execute.cc index cdc4259923c..0018010efc8 100644 --- a/source/blender/nodes/intern/geometry_nodes_execute.cc +++ b/source/blender/nodes/intern/geometry_nodes_execute.cc @@ -321,6 +321,31 @@ static void init_socket_cpp_value_from_property(const IDProperty &property, } } +std::optional input_attribute_name_get(const IDProperty &props, + const bNodeSocket &io_input) +{ + IDProperty *use_attribute = IDP_GetPropertyFromGroup( + &props, (io_input.identifier + input_use_attribute_suffix()).c_str()); + if (!use_attribute) { + return std::nullopt; + } + if (use_attribute->type == IDP_INT) { + if (IDP_Int(use_attribute) == 0) { + return std::nullopt; + } + } + if (use_attribute->type == IDP_BOOLEAN) { + if (!IDP_Bool(use_attribute)) { + return std::nullopt; + } + } + + const IDProperty *property_attribute_name = IDP_GetPropertyFromGroup( + &props, (io_input.identifier + input_attribute_name_suffix()).c_str()); + + return IDP_String(property_attribute_name); +} + static void initialize_group_input(const bNodeTree &tree, const IDProperty *properties, const int input_index, @@ -348,23 +373,9 @@ static void initialize_group_input(const bNodeTree &tree, return; } - const IDProperty *property_use_attribute = IDP_GetPropertyFromGroup( - properties, (io_input.identifier + input_use_attribute_suffix()).c_str()); - const IDProperty *property_attribute_name = IDP_GetPropertyFromGroup( - properties, (io_input.identifier + input_attribute_name_suffix()).c_str()); - if (property_use_attribute == nullptr || property_attribute_name == nullptr) { - init_socket_cpp_value_from_property(*property, socket_data_type, r_value); - return; - } - - const bool use_attribute = IDP_Int(property_use_attribute) != 0; - if (use_attribute) { - const StringRef attribute_name{IDP_String(property_attribute_name)}; - if (!bke::allow_procedural_attribute_access(attribute_name)) { - init_socket_cpp_value_from_property(*property, socket_data_type, r_value); - return; - } - fn::GField attribute_field = bke::AttributeFieldInput::Create(attribute_name, + const std::optional attribute_name = input_attribute_name_get(*properties, io_input); + if (attribute_name && bke::allow_procedural_attribute_access(*attribute_name)) { + fn::GField attribute_field = bke::AttributeFieldInput::Create(*attribute_name, *socket_type.base_cpp_type); const auto *value_or_field_cpp_type = fn::ValueOrFieldCPPType::get_from_self( *socket_type.geometry_nodes_cpp_type);