Fix #110516: Geometry nodes use attribute toggle boolean values broken #111433
@ -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", "");
|
||||
}
|
||||
|
||||
|
@ -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<StringRef> 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
|
||||
|
@ -30,6 +30,9 @@ namespace blender::nodes {
|
||||
StringRef input_use_attribute_suffix();
|
||||
StringRef input_attribute_name_suffix();
|
||||
|
||||
std::optional<StringRef> input_attribute_name_get(const IDProperty &props,
|
||||
const bNodeSocket &io_input);
|
||||
|
||||
/**
|
||||
* \return Whether using an attribute to input values of this type is supported.
|
||||
*/
|
||||
|
@ -321,6 +321,31 @@ static void init_socket_cpp_value_from_property(const IDProperty &property,
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<StringRef> 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<StringRef> 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);
|
||||
|
Loading…
Reference in New Issue
Block a user