[Bf-blender-cvs] [aca38148ad5] master: Fix T92131: handle node declaration in material properties

Jacques Lucke noreply at git.blender.org
Fri Oct 15 12:30:21 CEST 2021


Commit: aca38148ad56c27840de1ee6ebb7bd1841ab0ca4
Author: Jacques Lucke
Date:   Fri Oct 15 12:12:36 2021 +0200
Branches: master
https://developer.blender.org/rBaca38148ad56c27840de1ee6ebb7bd1841ab0ca4

Fix T92131: handle node declaration in material properties

The issue was that this menu was only looking at socket templates,
but not at the new node declarations. This fix is to just check those
as well. The fix comes with a small refactor that makes the memory
management a bit simpler.

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

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

M	source/blender/editors/space_node/node_templates.cc

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

diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc
index 648ede7abd5..f68d8589624 100644
--- a/source/blender/editors/space_node/node_templates.cc
+++ b/source/blender/editors/space_node/node_templates.cc
@@ -20,6 +20,7 @@
 
 #include <cstdlib>
 #include <cstring>
+#include <optional>
 
 #include "MEM_guardedalloc.h"
 
@@ -39,7 +40,9 @@
 
 #include "RNA_access.h"
 
+#include "NOD_node_declaration.hh"
 #include "NOD_socket.h"
+#include "NOD_socket_declarations.hh"
 
 #include "../interface/interface_intern.h" /* XXX bad level */
 #include "UI_interface.h"
@@ -49,17 +52,20 @@
 
 #include "ED_undo.h"
 
+using blender::Vector;
+using blender::nodes::NodeDeclaration;
+
 /************************* Node Socket Manipulation **************************/
 
 /* describes an instance of a node type and a specific socket to link */
 struct NodeLinkItem {
-  int socket_index;        /* index for linking */
-  int socket_type;         /* socket type for compatibility check */
-  const char *socket_name; /* ui label of the socket */
-  const char *node_name;   /* ui label of the node */
+  int socket_index = -1;             /* index for linking */
+  int socket_type = SOCK_CUSTOM;     /* socket type for compatibility check */
+  const char *socket_name = nullptr; /* ui label of the socket */
+  const char *node_name = nullptr;   /* ui label of the node */
 
   /* extra settings */
-  bNodeTree *ngroup; /* group node tree */
+  bNodeTree *ngroup = nullptr; /* group node tree */
 };
 
 /* Compare an existing node to a link item to see if it can be reused.
@@ -319,15 +325,13 @@ struct NodeLinkArg {
   uiLayout *layout;
 };
 
-static void ui_node_link_items(NodeLinkArg *arg,
-                               int in_out,
-                               NodeLinkItem **r_items,
-                               int *r_totitems)
+static Vector<NodeLinkItem> ui_node_link_items(NodeLinkArg *arg,
+                                               int in_out,
+                                               std::optional<NodeDeclaration> &r_node_decl)
 {
-  /* XXX this should become a callback for node types! */
-  NodeLinkItem *items = nullptr;
-  int totitems = 0;
+  Vector<NodeLinkItem> items;
 
+  /* XXX this should become a callback for node types! */
   if (arg->node_type->type == NODE_GROUP) {
     bNodeTree *ngroup;
     int i;
@@ -339,69 +343,86 @@ static void ui_node_link_items(NodeLinkArg *arg,
           !nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
         continue;
       }
-
-      ListBase *lb = ((in_out == SOCK_IN) ? &ngroup->inputs : &ngroup->outputs);
-      totitems += BLI_listbase_count(lb);
     }
 
-    if (totitems > 0) {
-      items = (NodeLinkItem *)MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
-
-      i = 0;
-      for (ngroup = (bNodeTree *)arg->bmain->nodetrees.first; ngroup;
-           ngroup = (bNodeTree *)ngroup->id.next) {
-        const char *disabled_hint;
-        if ((ngroup->type != arg->ntree->type) ||
-            !nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
-          continue;
-        }
+    i = 0;
+    for (ngroup = (bNodeTree *)arg->bmain->nodetrees.first; ngroup;
+         ngroup = (bNodeTree *)ngroup->id.next) {
+      const char *disabled_hint;
+      if ((ngroup->type != arg->ntree->type) ||
+          !nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
+        continue;
+      }
 
-        ListBase *lb = (in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs);
-        bNodeSocket *stemp;
-        int index;
-        for (stemp = (bNodeSocket *)lb->first, index = 0; stemp;
-             stemp = stemp->next, index++, i++) {
-          NodeLinkItem *item = &items[i];
-
-          item->socket_index = index;
-          /* NOTE: int stemp->type is not fully reliable, not used for node group
-           * interface sockets. use the typeinfo->type instead.
-           */
-          item->socket_type = stemp->typeinfo->type;
-          item->socket_name = stemp->name;
-          item->node_name = ngroup->id.name + 2;
-          item->ngroup = ngroup;
-        }
+      ListBase *lb = (in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs);
+      bNodeSocket *stemp;
+      int index;
+      for (stemp = (bNodeSocket *)lb->first, index = 0; stemp; stemp = stemp->next, index++, i++) {
+        NodeLinkItem item;
+        item.socket_index = index;
+        /* NOTE: int stemp->type is not fully reliable, not used for node group
+         * interface sockets. use the typeinfo->type instead.
+         */
+        item.socket_type = stemp->typeinfo->type;
+        item.socket_name = stemp->name;
+        item.node_name = ngroup->id.name + 2;
+        item.ngroup = ngroup;
+
+        items.append(item);
       }
     }
   }
+  else if (arg->node_type->declare != nullptr) {
+    using namespace blender;
+    using namespace blender::nodes;
+
+    r_node_decl.emplace(NodeDeclaration());
+    NodeDeclarationBuilder node_decl_builder{*r_node_decl};
+    arg->node_type->declare(node_decl_builder);
+    Span<SocketDeclarationPtr> socket_decls = (in_out == SOCK_IN) ? r_node_decl->inputs() :
+                                                                    r_node_decl->outputs();
+    int index = 0;
+    for (const SocketDeclarationPtr &socket_decl_ptr : socket_decls) {
+      const SocketDeclaration &socket_decl = *socket_decl_ptr;
+      NodeLinkItem item;
+      item.socket_index = index++;
+      /* A socket declaration does not necessarily map to exactly one built-in socket type. So only
+       * check for the types that matter here. */
+      if (dynamic_cast<const decl::Color *>(&socket_decl)) {
+        item.socket_type = SOCK_RGBA;
+      }
+      else if (dynamic_cast<const decl::Float *>(&socket_decl)) {
+        item.socket_type = SOCK_FLOAT;
+      }
+      else if (dynamic_cast<const decl::Vector *>(&socket_decl)) {
+        item.socket_type = SOCK_VECTOR;
+      }
+      else {
+        item.socket_type = SOCK_CUSTOM;
+      }
+      item.socket_name = socket_decl.name().c_str();
+      item.node_name = arg->node_type->ui_name;
+      items.append(item);
+    }
+  }
   else {
     bNodeSocketTemplate *socket_templates = (in_out == SOCK_IN ? arg->node_type->inputs :
                                                                  arg->node_type->outputs);
     bNodeSocketTemplate *stemp;
     int i;
 
-    for (stemp = socket_templates; stemp && stemp->type != -1; stemp++) {
-      totitems++;
-    }
-
-    if (totitems > 0) {
-      items = (NodeLinkItem *)MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
-
-      i = 0;
-      for (stemp = socket_templates; stemp && stemp->type != -1; stemp++, i++) {
-        NodeLinkItem *item = &items[i];
-
-        item->socket_index = i;
-        item->socket_type = stemp->type;
-        item->socket_name = stemp->name;
-        item->node_name = arg->node_type->ui_name;
-      }
+    i = 0;
+    for (stemp = socket_templates; stemp && stemp->type != -1; stemp++, i++) {
+      NodeLinkItem item;
+      item.socket_index = i;
+      item.socket_type = stemp->type;
+      item.socket_name = stemp->name;
+      item.node_name = arg->node_type->ui_name;
+      items.append(item);
     }
   }
 
-  *r_items = items;
-  *r_totitems = totitems;
+  return items;
 }
 
 static void ui_node_link(bContext *C, void *arg_p, void *event_p)
@@ -513,8 +534,6 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
   /* generate UI */
   for (int j = 0; j < sorted_ntypes.size(); j++) {
     bNodeType *ntype = sorted_ntypes[j];
-    NodeLinkItem *items;
-    int totitems;
     char name[UI_MAX_NAME_STR];
     const char *cur_node_name = nullptr;
     int num = 0;
@@ -522,16 +541,17 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
 
     arg->node_type = ntype;
 
-    ui_node_link_items(arg, SOCK_OUT, &items, &totitems);
+    std::optional<blender::nodes::NodeDeclaration> node_decl;
+    Vector<NodeLinkItem> items = ui_node_link_items(arg, SOCK_OUT, node_decl);
 
-    for (int i = 0; i < totitems; i++) {
-      if (ui_compatible_sockets(items[i].socket_type, sock->type)) {
+    for (const NodeLinkItem &item : items) {
+      if (ui_compatible_sockets(item.socket_type, sock->type)) {
         num++;
       }
     }
 
-    for (int i = 0; i < totitems; i++) {
-      if (!ui_compatible_sockets(items[i].socket_type, sock->type)) {
+    for (const NodeLinkItem &item : items) {
+      if (!ui_compatible_sockets(item.socket_type, sock->type)) {
         continue;
       }
 
@@ -546,8 +566,8 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
       }
 
       if (num > 1) {
-        if (!cur_node_name || !STREQ(cur_node_name, items[i].node_name)) {
-          cur_node_name = items[i].node_name;
+        if (!cur_node_name || !STREQ(cur_node_name, item.node_name)) {
+          cur_node_name = item.node_name;
           /* XXX Do not use uiItemL here,
            * it would add an empty icon as we are in a menu! */
           uiDefBut(block,
@@ -566,11 +586,11 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
                    "");
         }
 
-        BLI_snprintf(name, UI_MAX_NAME_STR, "%s", IFACE_(items[i].socket_name));
+        BLI_snprintf(name, UI_MAX_NAME_STR, "%s", IFACE_(item.socket_name));
         icon = ICON_BLANK1;
       }
       else {
-        BLI_strncpy(name, IFACE_(items[i].node_name), UI_MAX_NAME_STR);
+        BLI_strncpy(name, IFACE_(item.node_name), UI_MAX_NAME_STR);
         icon = ICON_NONE;
       }
 
@@ -591,13 +611,9 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
                              TIP_("Add node to input"));
 
       argN = (NodeLinkArg *)MEM_dupallocN(arg);
-      argN->item = items[i];
+      argN->item = item;
       UI_but_funcN_set(but, ui_node_link, argN, nullptr);
     }
-
-    if (items) {
-      MEM_freeN(items);
-    }
   }
 }



More information about the Bf-blender-cvs mailing list