[Bf-blender-cvs] [1d96a482675] master: Geometry Nodes: Attribute search in the modifier

Hans Goudey noreply at git.blender.org
Thu Oct 21 20:55:06 CEST 2021


Commit: 1d96a482675dd2ccad2af31c274f74b9f6603d6b
Author: Hans Goudey
Date:   Thu Oct 21 13:54:48 2021 -0500
Branches: master
https://developer.blender.org/rB1d96a482675dd2ccad2af31c274f74b9f6603d6b

Geometry Nodes: Attribute search in the modifier

This adds attribute search to the geometry nodes modifier
for the input and output attributes. The "New" search item
is only shown for the output attributes.

Some of the attribute search code is extracted to a new file
in the interface code, to avoid some code duplication.

The UI code required two fixes so that the search would work
for dynamic length strings (IDProperties do not have a fixed size).

Since this does changes to the UI layout of the modifier, I also
addressed T91485 here.

Differential Revisiion: https://developer.blender.org/D12788

===================================================================

M	source/blender/editors/include/UI_interface.hh
M	source/blender/editors/interface/CMakeLists.txt
M	source/blender/editors/interface/interface_region_search.c
A	source/blender/editors/interface/interface_template_attribute_search.cc
M	source/blender/editors/space_node/node_geometry_attribute_search.cc
M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/nodes/NOD_geometry_nodes_eval_log.hh
M	source/blender/nodes/intern/geometry_nodes_eval_log.cc

===================================================================

diff --git a/source/blender/editors/include/UI_interface.hh b/source/blender/editors/include/UI_interface.hh
index 4a583d0225e..5edccfa8c88 100644
--- a/source/blender/editors/include/UI_interface.hh
+++ b/source/blender/editors/include/UI_interface.hh
@@ -24,10 +24,22 @@
 
 #include "BLI_string_ref.hh"
 
+namespace blender::nodes::geometry_nodes_eval_log {
+struct GeometryAttributeInfo;
+}
+
 struct uiBlock;
 namespace blender::ui {
 class AbstractTreeView;
-}
+
+void attribute_search_add_items(
+    StringRefNull str,
+    const bool is_output,
+    Span<const nodes::geometry_nodes_eval_log::GeometryAttributeInfo *> infos,
+    uiSearchItems *items,
+    const bool is_first);
+
+}  // namespace blender::ui
 
 blender::ui::AbstractTreeView *UI_block_add_view(
     uiBlock &block,
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index 8fcc704a301..b2659f5ed52 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -25,9 +25,11 @@ set(INC
   ../../depsgraph
   ../../draw
   ../../gpu
+  ../../functions
   ../../imbuf
   ../../makesdna
   ../../makesrna
+  ../../nodes
   ../../python
   ../../render
   ../../windowmanager
@@ -69,6 +71,7 @@ set(SRC
   interface_style.c
   interface_template_asset_view.cc
   interface_template_list.cc
+  interface_template_attribute_search.cc
   interface_template_search_menu.c
   interface_template_search_operator.c
   interface_templates.c
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 1cd3ef89ed3..5bea03dee63 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -316,7 +316,11 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
 
     const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
 
-    BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
+    /* Search button with dynamic string properties may have their own method of applying
+     * the search results, so only copy the result if there is a proper space for it. */
+    if (but->hardmax != 0) {
+      BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
+    }
 
     search_but->item_active = data->items.pointers[data->active];
 
@@ -878,7 +882,8 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C,
   else {
     data->items.maxitem = SEARCH_ITEMS;
   }
-  data->items.maxstrlen = but->hardmax;
+  /* In case the button's string is dynamic, make sure there are buffers available. */
+  data->items.maxstrlen = but->hardmax == 0 ? UI_MAX_NAME_STR : but->hardmax;
   data->items.totitem = 0;
   data->items.names = MEM_callocN(data->items.maxitem * sizeof(void *), "search names");
   data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers");
@@ -886,7 +891,7 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C,
   data->items.states = MEM_callocN(data->items.maxitem * sizeof(int), "search flags");
   data->items.name_prefix_offsets = NULL; /* Lazy initialized as needed. */
   for (int i = 0; i < data->items.maxitem; i++) {
-    data->items.names[i] = MEM_callocN(but->hardmax + 1, "search pointers");
+    data->items.names[i] = MEM_callocN(data->items.maxstrlen + 1, "search pointers");
   }
 
   return region;
diff --git a/source/blender/editors/interface/interface_template_attribute_search.cc b/source/blender/editors/interface/interface_template_attribute_search.cc
new file mode 100644
index 00000000000..0157d0b66a3
--- /dev/null
+++ b/source/blender/editors/interface/interface_template_attribute_search.cc
@@ -0,0 +1,125 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup edinterface
+ */
+
+#include "BLI_string_ref.hh"
+#include "BLI_string_search.h"
+
+#include "DNA_customdata_types.h"
+
+#include "RNA_access.h"
+#include "RNA_enum_types.h"
+
+#include "BLT_translation.h"
+
+#include "NOD_geometry_nodes_eval_log.hh"
+
+#include "UI_interface.h"
+#include "UI_interface.hh"
+#include "UI_resources.h"
+
+using blender::nodes::geometry_nodes_eval_log::GeometryAttributeInfo;
+
+namespace blender::ui {
+
+static StringRef attribute_data_type_string(const CustomDataType type)
+{
+  const char *name = nullptr;
+  RNA_enum_name_from_value(rna_enum_attribute_type_items, type, &name);
+  return StringRef(IFACE_(name));
+}
+
+static StringRef attribute_domain_string(const AttributeDomain domain)
+{
+  const char *name = nullptr;
+  RNA_enum_name_from_value(rna_enum_attribute_domain_items, domain, &name);
+  return StringRef(IFACE_(name));
+}
+
+static bool attribute_search_item_add(uiSearchItems *items, const GeometryAttributeInfo &item)
+{
+  const StringRef data_type_name = attribute_data_type_string(item.data_type);
+  const StringRef domain_name = attribute_domain_string(item.domain);
+  std::string search_item_text = domain_name + " " + UI_MENU_ARROW_SEP + item.name + UI_SEP_CHAR +
+                                 data_type_name;
+
+  return UI_search_item_add(
+      items, search_item_text.c_str(), (void *)&item, ICON_NONE, UI_BUT_HAS_SEP_CHAR, 0);
+}
+
+void attribute_search_add_items(StringRefNull str,
+                                const bool is_output,
+                                Span<const GeometryAttributeInfo *> infos,
+                                uiSearchItems *seach_items,
+                                const bool is_first)
+{
+  static GeometryAttributeInfo dummy_info;
+
+  /* Any string may be valid, so add the current search string along with the hints. */
+  if (str[0] != '\0') {
+    bool contained = false;
+    for (const GeometryAttributeInfo *attribute_info : infos) {
+      if (attribute_info->name == str) {
+        contained = true;
+        break;
+      }
+    }
+    if (!contained && is_output) {
+      dummy_info.name = str;
+      UI_search_item_add(seach_items, str.c_str(), &dummy_info, ICON_ADD, 0, 0);
+    }
+  }
+
+  if (str[0] == '\0' && !is_first) {
+    /* Allow clearing the text field when the string is empty, but not on the first pass,
+     * or opening an attribute field for the first time would show this search item. */
+    dummy_info.name = str;
+    UI_search_item_add(seach_items, str.c_str(), &dummy_info, ICON_X, 0, 0);
+  }
+
+  /* Don't filter when the menu is first opened, but still run the search
+   * so the items are in the same order they will appear in while searching. */
+  const char *string = is_first ? "" : str.c_str();
+
+  StringSearch *search = BLI_string_search_new();
+  for (const GeometryAttributeInfo *item : infos) {
+
+    /* Don't show the legacy "normal" attribute. */
+    if (item->name == "normal" && item->domain == ATTR_DOMAIN_FACE) {
+      continue;
+    }
+
+    BLI_string_search_add(search, item->name.c_str(), (void *)item);
+  }
+
+  GeometryAttributeInfo **filtered_items;
+  const int filtered_amount = BLI_string_search_query(search, string, (void ***)&filtered_items);
+
+  for (const int i : IndexRange(filtered_amount)) {
+    const GeometryAttributeInfo *item = filtered_items[i];
+    if (!attribute_search_item_add(seach_items, *item)) {
+      break;
+    }
+  }
+
+  MEM_freeN(filtered_items);
+  BLI_string_search_free(search);
+}
+
+}  // namespace blender::ui
\ No newline at end of file
diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc
index a69109db69c..d0ccbb03107 100644
--- a/source/blender/editors/space_node/node_geometry_attribute_search.cc
+++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc
@@ -38,6 +38,7 @@
 #include "BLT_translation.h"
 
 #include "UI_interface.h"
+#include "UI_interface.hh"
 #include "UI_resources.h"
 
 #include "NOD_geometry_nodes_eval_log.hh"
@@ -60,37 +61,6 @@ struct AttributeSearchData {
 /* This class must not have a destructor, since it is used by buttons and freed with #MEM_freeN. */
 BLI_STATIC_ASSERT(std::is_trivially_destructible_v<AttributeSearchData>, "");
 
-static StringRef attribute_data_type_string(const CustomDataType type)
-{
-  const char *name = nullptr;
-  RNA_enum_name_from_value(rna_enum_attribute_type_items, type, &name);
-  return StringRef(IFACE_(name));
-}
-
-static StringRef attribute_domain_string(const AttributeDomain domain)
-{
-  const char *name = nullptr;
-  RNA_enum_name_from_value(rna_enum_attribute_domain_items, domain, &name);
-  return StringRef(IFACE_(name));
-}
-
-static bool attribute_search_item_add(uiSearchItems *items, const GeometryAttributeInfo &item)
-{
-  const StringRef data_type_name = attribute_data_type_string(item.data_type);
-  const StringRef domain_name = attribute_domain_string(item.domain);
-  std::string search_item_text = domain_name + " " + UI_MENU_ARROW_SEP + item.name + UI_SEP_CHAR +
-                                 data_type_name;
-
-  return UI_search_item_add(
-      items, search_item_text.c_str(), (void *)&item, ICON_NONE, UI_BUT_HAS_SEP_CHAR, 0);
-}
-
-static GeometryAttributeInfo &get_dummy_item_info()
-{
-  static GeometryAttributeInfo info;
-  return info;
-}
-
 static void attribute_search_update_fn(
     const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
 {
@@ -104,51 +74,7 @@ static void attribute_search_update_fn(
   }
   blender::Vector<const GeometryAttr

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list