Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_nodes.cc')
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc106
1 files changed, 99 insertions, 7 deletions
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 3b952e1e649..011890f4d43 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -68,6 +68,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "WM_types.h"
+
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -291,6 +293,17 @@ static bool logging_enabled(const ModifierEvalContext *ctx)
return true;
}
+static const std::string use_attribute_suffix = "_use_attribute";
+static const std::string attribute_name_suffix = "_attribute_name";
+
+/**
+ * \return Whether using an attribute to input values of this type is supported.
+ */
+static bool socket_type_has_attribute_toggle(const bNodeSocket &socket)
+{
+ return ELEM(socket.type, SOCK_FLOAT, SOCK_VECTOR, SOCK_BOOLEAN, SOCK_RGBA, SOCK_INT);
+}
+
static IDProperty *id_property_create_from_socket(const bNodeSocket &socket)
{
switch (socket.type) {
@@ -546,6 +559,32 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd)
new_prop->ui_data = ui_data;
}
}
+
+ if (socket_type_has_attribute_toggle(*socket)) {
+ const std::string use_attribute_id = socket->identifier + use_attribute_suffix;
+ const std::string attribute_name_id = socket->identifier + attribute_name_suffix;
+
+ IDPropertyTemplate idprop = {0};
+ IDProperty *use_attribute_prop = IDP_New(IDP_INT, &idprop, use_attribute_id.c_str());
+ IDP_AddToGroup(nmd->settings.properties, use_attribute_prop);
+
+ IDProperty *attribute_prop = IDP_New(IDP_STRING, &idprop, attribute_name_id.c_str());
+ IDP_AddToGroup(nmd->settings.properties, attribute_prop);
+
+ if (old_properties != nullptr) {
+ IDProperty *old_prop_use_attribute = IDP_GetPropertyFromGroup(old_properties,
+ use_attribute_id.c_str());
+ if (old_prop_use_attribute != nullptr) {
+ IDP_CopyPropertyContent(use_attribute_prop, old_prop_use_attribute);
+ }
+
+ IDProperty *old_attribute_name_prop = IDP_GetPropertyFromGroup(old_properties,
+ attribute_name_id.c_str());
+ if (old_attribute_name_prop != nullptr) {
+ IDP_CopyPropertyContent(attribute_prop, old_attribute_name_prop);
+ }
+ }
+ }
}
if (old_properties != nullptr) {
@@ -601,8 +640,31 @@ static void initialize_group_input(NodesModifierData &nmd,
return;
}
- init_socket_cpp_value_from_property(
- *property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
+ if (!socket_type_has_attribute_toggle(socket)) {
+ init_socket_cpp_value_from_property(
+ *property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
+ }
+
+ const IDProperty *property_use_attribute = IDP_GetPropertyFromGroup(
+ nmd.settings.properties, (socket.identifier + use_attribute_suffix).c_str());
+ const IDProperty *property_attribute_name = IDP_GetPropertyFromGroup(
+ nmd.settings.properties, (socket.identifier + attribute_name_suffix).c_str());
+ if (property_use_attribute == nullptr || property_attribute_name == nullptr) {
+ socket.typeinfo->get_geometry_nodes_cpp_value(socket, 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)};
+ auto attribute_input = std::make_shared<blender::bke::AttributeFieldInput>(
+ attribute_name, *socket.typeinfo->get_base_cpp_type());
+ new (r_value) blender::fn::GField(std::move(attribute_input), 0);
+ }
+ else {
+ init_socket_cpp_value_from_property(
+ *property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
+ }
}
static Vector<SpaceSpreadsheet *> find_spreadsheet_editors(Main *bmain)
@@ -912,13 +974,13 @@ static void modifyGeometrySet(ModifierData *md,
* the node socket identifier for the property names, since they are unique, but also having
* the correct label displayed in the UI. */
static void draw_property_for_socket(uiLayout *layout,
+ NodesModifierData *nmd,
PointerRNA *bmain_ptr,
PointerRNA *md_ptr,
- const IDProperty *modifier_props,
const bNodeSocket &socket)
{
/* The property should be created in #MOD_nodes_update_interface with the correct type. */
- IDProperty *property = IDP_GetPropertyFromGroup(modifier_props, socket.identifier);
+ IDProperty *property = IDP_GetPropertyFromGroup(nmd->settings.properties, socket.identifier);
/* IDProperties can be removed with python, so there could be a situation where
* there isn't a property for a socket or it doesn't have the correct type. */
@@ -959,8 +1021,38 @@ static void draw_property_for_socket(uiLayout *layout,
uiItemPointerR(layout, md_ptr, rna_path, bmain_ptr, "textures", socket.name, ICON_TEXTURE);
break;
}
- default:
- uiItemR(layout, md_ptr, rna_path, 0, socket.name, ICON_NONE);
+ default: {
+ if (socket_type_has_attribute_toggle(socket) &&
+ USER_EXPERIMENTAL_TEST(&U, use_geometry_nodes_fields)) {
+ const std::string rna_path_use_attribute = "[\"" + std::string(socket_id_esc) +
+ use_attribute_suffix + "\"]";
+ const std::string rna_path_attribute_name = "[\"" + std::string(socket_id_esc) +
+ attribute_name_suffix + "\"]";
+
+ uiLayout *row = uiLayoutRow(layout, true);
+ const int use_attribute = RNA_int_get(md_ptr, rna_path_use_attribute.c_str()) != 0;
+ if (use_attribute) {
+ uiItemR(row, md_ptr, rna_path_attribute_name.c_str(), 0, socket.name, ICON_NONE);
+ }
+ else {
+ uiItemR(row, md_ptr, rna_path, 0, socket.name, ICON_NONE);
+ }
+ PointerRNA props;
+ uiItemFullO(row,
+ "object.geometry_nodes_input_attribute_toggle",
+ "",
+ ICON_SPREADSHEET,
+ nullptr,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &props);
+ RNA_string_set(&props, "modifier_name", nmd->modifier.name);
+ RNA_string_set(&props, "prop_path", rna_path_use_attribute.c_str());
+ }
+ else {
+ uiItemR(layout, md_ptr, rna_path, 0, socket.name, ICON_NONE);
+ }
+ }
}
}
@@ -991,7 +1083,7 @@ static void panel_draw(const bContext *C, Panel *panel)
RNA_main_pointer_create(bmain, &bmain_ptr);
LISTBASE_FOREACH (bNodeSocket *, socket, &nmd->node_group->inputs) {
- draw_property_for_socket(layout, &bmain_ptr, ptr, nmd->settings.properties, *socket);
+ draw_property_for_socket(layout, nmd, &bmain_ptr, ptr, *socket);
}
}