[Bf-blender-cvs] [bdb57541475] master: Nodes: Add node group assets to search menus

Hans Goudey noreply at git.blender.org
Mon Sep 19 18:59:49 CEST 2022


Commit: bdb57541475f20ccc4f6e5f8fc075ac424becc19
Author: Hans Goudey
Date:   Mon Sep 19 11:57:10 2022 -0500
Branches: master
https://developer.blender.org/rBbdb57541475f20ccc4f6e5f8fc075ac424becc19

Nodes: Add node group assets to search menus

Currently node group assets are supported, but using them by dragging
from the asset browser is cumbersome. This patch adds all node group
assets from user asset libraries and the current file libraries to the
add node search menu and the link drag search menu.

Node groups added through the search will have their "options" hidden,
meaning the data-block selector is displayed. This helps keep the UI
clean, and the selector shouldn't be necessary anyway.

To make that possible, metadata like the node tree type and its inputs
and outputs has to be saved in the file. This requires re-saving the
files that contain the assets with the patch applied.

The node add search operator is moved from Python to C++ to ease
development and allow more flexibility. It supports a tooltip that
gives the description of assets.

Currently the node groups are added with the asset system's existing
"Append & Reuse" behavior. It's likely that linking should be possible
in the future too, but for now the idea is to use the more foolproof
option that doesn't create dependencies between files.

Because loading assets can potentially take a long time, the search
menu refreshes its items as new assets are loaded. However, changing
the search field is necessary to see the update.

Differential Revision: https://developer.blender.org/D15568

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

M	release/scripts/startup/bl_operators/node.py
M	source/blender/blenkernel/intern/node.cc
M	source/blender/editors/asset/ED_asset_handle.h
M	source/blender/editors/asset/intern/asset_handle.cc
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.cc
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_region_search.cc
M	source/blender/editors/space_node/CMakeLists.txt
A	source/blender/editors/space_node/add_node_search.cc
M	source/blender/editors/space_node/link_drag_search.cc
M	source/blender/editors/space_node/node_add.cc
M	source/blender/editors/space_node/node_intern.hh
M	source/blender/editors/space_node/node_ops.cc

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

diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index ff9b5a06fb7..5cc9c850ebe 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -149,78 +149,6 @@ class NODE_OT_add_node(NodeAddOperator, Operator):
     bl_options = {'REGISTER', 'UNDO'}
 
 
-class NODE_OT_add_search(NodeAddOperator, Operator):
-    '''Add a node to the active tree'''
-    bl_idname = "node.add_search"
-    bl_label = "Search and Add Node"
-    bl_options = {'REGISTER', 'UNDO'}
-    bl_property = "node_item"
-
-    _enum_item_hack = []
-
-    # Create an enum list from node items
-    def node_enum_items(self, context):
-        import nodeitems_utils
-
-        enum_items = NODE_OT_add_search._enum_item_hack
-        enum_items.clear()
-
-        for index, item in enumerate(nodeitems_utils.node_items_iter(context)):
-            if isinstance(item, nodeitems_utils.NodeItem):
-                enum_items.append(
-                    (str(index),
-                     item.label,
-                     "",
-                     index,
-                     ))
-        return enum_items
-
-    # Look up the item based on index
-    def find_node_item(self, context):
-        import nodeitems_utils
-
-        node_item = int(self.node_item)
-        for index, item in enumerate(nodeitems_utils.node_items_iter(context)):
-            if index == node_item:
-                return item
-        return None
-
-    node_item: EnumProperty(
-        name="Node Type",
-        description="Node type",
-        items=NODE_OT_add_search.node_enum_items,
-    )
-
-    def execute(self, context):
-        item = self.find_node_item(context)
-
-        # no need to keep
-        self._enum_item_hack.clear()
-
-        if item:
-            # apply settings from the node item
-            for setting in item.settings.items():
-                ops = self.settings.add()
-                ops.name = setting[0]
-                ops.value = setting[1]
-
-            self.create_node(context, item.nodetype)
-
-            if self.use_transform:
-                bpy.ops.node.translate_attach_remove_on_cancel(
-                    'INVOKE_DEFAULT')
-
-            return {'FINISHED'}
-        else:
-            return {'CANCELLED'}
-
-    def invoke(self, context, event):
-        self.store_mouse_cursor(context, event)
-        # Delayed execution in the search popup
-        context.window_manager.invoke_search_popup(self)
-        return {'CANCELLED'}
-
-
 class NODE_OT_collapse_hide_unused_toggle(Operator):
     '''Toggle collapsed nodes and hide unused sockets'''
     bl_idname = "node.collapse_hide_unused_toggle"
@@ -276,7 +204,6 @@ classes = (
     NodeSetting,
 
     NODE_OT_add_node,
-    NODE_OT_add_search,
     NODE_OT_collapse_hide_unused_toggle,
     NODE_OT_tree_path_parent,
 )
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 04f5b131743..3a241efdac2 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -47,6 +47,7 @@
 
 #include "BKE_anim_data.h"
 #include "BKE_animsys.h"
+#include "BKE_asset.h"
 #include "BKE_bpath.h"
 #include "BKE_colortools.h"
 #include "BKE_context.h"
@@ -54,6 +55,7 @@
 #include "BKE_global.h"
 #include "BKE_icons.h"
 #include "BKE_idprop.h"
+#include "BKE_idprop.hh"
 #include "BKE_idtype.h"
 #include "BKE_image_format.h"
 #include "BKE_lib_id.h"
@@ -1026,6 +1028,33 @@ static void ntree_blend_read_expand(BlendExpander *expander, ID *id)
   ntreeBlendReadExpand(expander, ntree);
 }
 
+namespace blender::bke {
+
+static void node_tree_asset_pre_save(void *asset_ptr, struct AssetMetaData *asset_data)
+{
+  bNodeTree &node_tree = *static_cast<bNodeTree *>(asset_ptr);
+
+  BKE_asset_metadata_idprop_ensure(asset_data, idprop::create("type", node_tree.type).release());
+  auto inputs = idprop::create_group("inputs");
+  auto outputs = idprop::create_group("outputs");
+  LISTBASE_FOREACH (const bNodeSocket *, socket, &node_tree.inputs) {
+    auto property = idprop::create(socket->name, socket->typeinfo->idname);
+    IDP_AddToGroup(inputs.get(), property.release());
+  }
+  LISTBASE_FOREACH (const bNodeSocket *, socket, &node_tree.outputs) {
+    auto property = idprop::create(socket->name, socket->typeinfo->idname);
+    IDP_AddToGroup(outputs.get(), property.release());
+  }
+  BKE_asset_metadata_idprop_ensure(asset_data, inputs.release());
+  BKE_asset_metadata_idprop_ensure(asset_data, outputs.release());
+}
+
+}  // namespace blender::bke
+
+static AssetTypeInfo AssetType_NT = {
+    /* pre_save_fn */ blender::bke::node_tree_asset_pre_save,
+};
+
 IDTypeInfo IDType_ID_NT = {
     /* id_code */ ID_NT,
     /* id_filter */ FILTER_ID_NT,
@@ -1035,7 +1064,7 @@ IDTypeInfo IDType_ID_NT = {
     /* name_plural */ "node_groups",
     /* translation_context */ BLT_I18NCONTEXT_ID_NODETREE,
     /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE,
-    /* asset_type_info */ nullptr,
+    /* asset_type_info */ &AssetType_NT,
 
     /* init_data */ ntree_init_data,
     /* copy_data */ ntree_copy_data,
diff --git a/source/blender/editors/asset/ED_asset_handle.h b/source/blender/editors/asset/ED_asset_handle.h
index b408e919f32..4a81840c40d 100644
--- a/source/blender/editors/asset/ED_asset_handle.h
+++ b/source/blender/editors/asset/ED_asset_handle.h
@@ -35,3 +35,16 @@ void ED_asset_handle_get_full_library_path(const struct bContext *C,
 #ifdef __cplusplus
 }
 #endif
+
+#ifdef __cplusplus
+
+namespace blender::ed::asset {
+
+/** If the ID already exists in the database, return it, otherwise add it. */
+ID *get_local_id_from_asset_or_append_and_reuse(Main &bmain,
+                                                const AssetLibraryReference &library_ref,
+                                                AssetHandle asset);
+
+}  // namespace blender::ed::asset
+
+#endif
diff --git a/source/blender/editors/asset/intern/asset_handle.cc b/source/blender/editors/asset/intern/asset_handle.cc
index ade8b803ed3..00fffd595c0 100644
--- a/source/blender/editors/asset/intern/asset_handle.cc
+++ b/source/blender/editors/asset/intern/asset_handle.cc
@@ -13,6 +13,8 @@
 #include "ED_asset_handle.h"
 #include "ED_asset_list.hh"
 
+#include "WM_api.h"
+
 const char *ED_asset_handle_get_name(const AssetHandle *asset)
 {
   return asset->file_data->name;
@@ -52,3 +54,31 @@ void ED_asset_handle_get_full_library_path(const bContext *C,
 
   BLO_library_path_explode(asset_path.c_str(), r_full_lib_path, nullptr, nullptr);
 }
+
+namespace blender::ed::asset {
+
+ID *get_local_id_from_asset_or_append_and_reuse(Main &bmain,
+                                                const AssetLibraryReference &library_ref,
+                                                const AssetHandle asset)
+{
+  if (ID *local_id = ED_asset_handle_get_local_id(&asset)) {
+    return local_id;
+  }
+
+  char blend_path[FILE_MAX_LIBEXTRA];
+  ED_asset_handle_get_full_library_path(nullptr, &library_ref, &asset, blend_path);
+  const char *id_name = ED_asset_handle_get_name(&asset);
+
+  return WM_file_append_datablock(&bmain,
+                                  nullptr,
+                                  nullptr,
+                                  nullptr,
+                                  blend_path,
+                                  ED_asset_handle_get_id_type(&asset),
+                                  id_name,
+                                  BLO_LIBLINK_APPEND_RECURSIVE |
+                                      BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR |
+                                      BLO_LIBLINK_APPEND_LOCAL_ID_REUSE);
+}
+
+}  // namespace blender::ed::asset
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 27e2f89f684..c3376493413 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -532,6 +532,7 @@ typedef struct ARegion *(*uiButSearchTooltipFn)(struct bContext *C,
                                                 const struct rcti *item_rect,
                                                 void *arg,
                                                 void *active);
+typedef void (*uiButSearchListenFn)(const struct wmRegionListenerParams *params, void *arg);
 
 /* Must return allocated string. */
 typedef char *(*uiButToolTipFunc)(struct bContext *C, void *argN, const char *tip);
@@ -1659,6 +1660,7 @@ void UI_but_func_search_set(uiBut *but,
                             void *active);
 void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn context_menu_fn);
 void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn);
+void UI_but_func_search_set_listen(uiBut *but, uiButSearchListenFn listen_fn);
 /**
  * \param search_sep_string: when not NULL, this string is used as a separator,
  * showing the icon and highlighted text after the last instance of this string.
diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc
index ca4918b2e8d..64f7e035d3f 100644
--- a/source/blender/editors/interface/interface.cc
+++ b/source/blender/editors/interface/interface.cc
@@ -6321,6 +6321,13 @@ void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn)
   but_search->item_tooltip_fn = tooltip_fn;
 }
 
+void UI_but_func_search_set_listen(uiBut *but, uiButSearchListenFn listen_fn)
+{
+  uiButSearch *but_search = (uiButSearch *)but;
+  BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+  but_search->listen_fn = listen_fn;
+}
+
 void UI_but_func_search_set_results_are_suggestions(uiBut *but, const bool value)
 {
   uiButSearch *but_search = (uiButSearch *)but;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 0c842084de6..6ef7d346418 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -307,6 +307,8 @@ typedef struct uiButSearch {
 
   uiButSearchCreateFn popup_create_fn;
   uiButSearchUpdateFn items_update_fn;
+  uiButSearchListenFn listen_fn;
+
   void *i

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list