[Bf-blender-cvs] [70260960994] master: Nodes: Use dynamic declarations for group nodes

Hans Goudey noreply at git.blender.org
Mon Jan 16 22:47:33 CET 2023


Commit: 70260960994d6cce3a33dfc16b4911a6cab9d4f2
Author: Hans Goudey
Date:   Mon Jan 16 15:47:10 2023 -0600
Branches: master
https://developer.blender.org/rB70260960994d6cce3a33dfc16b4911a6cab9d4f2

Nodes: Use dynamic declarations for group nodes

Since a year and a half ago we've been switching to a new way to
represent what sockets a node should have called "declarations"
that's easier to use, clearer, and more flexible for upcoming
features like dynamic socket counts or generic type sockets.

All builtin nodes with a static set of sockets have switched, but one
missing area has been group nodes and group input/output nodes. These
nodes have **dynamic** declarations which change based on their
properties or the group they're inside of. This patch addresses that,
in preparation for using the same dynamic declaration feature for
simulation nodes.

Generally there shouldn't be user-visible differences, but one benefit
is that user-created socket descriptions are now visible directly in
the node editor for group nodes and group input/output nodes.

The commit contains a few changes:
- Add a node type callback for building dynamic declarations with
  different arguments
- Add an `Extend` socket declaration for the "virtual" sockets used
  for connecting new links
- A similar `Custom` socket declaration is used for addon-defined socket
- Simplify the node update loop to use the declaration to build update
  sockets
- Replace the "group update" functions with the declaration building
- Move the node group input/output link creation to link drag operator
- Make the field status part of group node declarations
  (not for group input/output nodes though)
- Some fixes for declarations to make them update and build properly

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

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

M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/node_tree_update.cc
M	source/blender/editors/space_node/link_drag_search.cc
M	source/blender/editors/space_node/node_group.cc
M	source/blender/editors/space_node/node_relationships.cc
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/NOD_common.h
M	source/blender/nodes/NOD_node_declaration.hh
M	source/blender/nodes/NOD_socket.h
M	source/blender/nodes/NOD_socket_declarations.hh
M	source/blender/nodes/composite/nodes/node_composite_common.cc
M	source/blender/nodes/geometry/nodes/node_geo_common.cc
M	source/blender/nodes/intern/node_common.cc
M	source/blender/nodes/intern/node_declaration.cc
M	source/blender/nodes/intern/node_socket.cc
M	source/blender/nodes/intern/node_socket_declarations.cc
M	source/blender/nodes/intern/node_util.cc
M	source/blender/nodes/intern/node_util.h
M	source/blender/nodes/intern/socket_search_link.cc
M	source/blender/nodes/shader/nodes/node_shader_common.cc
M	source/blender/nodes/texture/nodes/node_texture_common.cc

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

diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index c99f5cb076e..c40839361e2 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -104,6 +104,7 @@ namespace nodes {
 class DNode;
 class NodeMultiFunctionBuilder;
 class GeoNodeExecParams;
+class NodeDeclaration;
 class NodeDeclarationBuilder;
 class GatherLinkSearchOpParams;
 }  // namespace nodes
@@ -118,6 +119,9 @@ using CPPTypeHandle = blender::CPPType;
 using NodeMultiFunctionBuildFunction = void (*)(blender::nodes::NodeMultiFunctionBuilder &builder);
 using NodeGeometryExecFunction = void (*)(blender::nodes::GeoNodeExecParams params);
 using NodeDeclareFunction = void (*)(blender::nodes::NodeDeclarationBuilder &builder);
+using NodeDeclareDynamicFunction = void (*)(const bNodeTree &tree,
+                                            const bNode &node,
+                                            blender::nodes::NodeDeclaration &r_declaration);
 using SocketGetCPPValueFunction = void (*)(const struct bNodeSocket &socket, void *r_value);
 using SocketGetGeometryNodesCPPValueFunction = void (*)(const struct bNodeSocket &socket,
                                                         void *r_value);
@@ -137,6 +141,7 @@ typedef void *NodeGetCompositorShaderNodeFunction;
 typedef void *NodeMultiFunctionBuildFunction;
 typedef void *NodeGeometryExecFunction;
 typedef void *NodeDeclareFunction;
+typedef void *NodeDeclareDynamicFunction;
 typedef void *NodeGatherSocketLinkOperationsFunction;
 typedef void *SocketGetCPPTypeFunction;
 typedef void *SocketGetGeometryNodesCPPTypeFunction;
@@ -173,11 +178,6 @@ typedef struct bNodeSocketType {
                                 struct bNode *node,
                                 struct bNodeSocket *sock,
                                 const char *data_path);
-  void (*interface_verify_socket)(struct bNodeTree *ntree,
-                                  const struct bNodeSocket *interface_socket,
-                                  struct bNode *node,
-                                  struct bNodeSocket *sock,
-                                  const char *data_path);
   void (*interface_from_socket)(struct bNodeTree *ntree,
                                 struct bNodeSocket *interface_socket,
                                 const struct bNode *node,
@@ -306,8 +306,8 @@ typedef struct bNodeType {
                         const struct bNodeTree *nodetree,
                         const char **r_disabled_hint);
 
-  /* optional handling of link insertion */
-  void (*insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link);
+  /* optional handling of link insertion. Returns false if the link shouldn't be created. */
+  bool (*insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link);
 
   void (*free_self)(struct bNodeType *ntype);
 
@@ -344,8 +344,13 @@ typedef struct bNodeType {
 
   /* Declares which sockets the node has. */
   NodeDeclareFunction declare;
-  /* Different nodes of this type can have different declarations. */
-  bool declaration_is_dynamic;
+  /**
+   * Declare which sockets the node has for declarations that aren't static per node type.
+   * In other words, defining this callback means that different nodes of this type can have
+   * different declarations and different sockets.
+   */
+  NodeDeclareDynamicFunction declare_dynamic;
+
   /* Declaration to be used when it is not dynamic. */
   NodeDeclarationHandle *fixed_declaration;
 
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 9c2ac298fd2..cb650c038e4 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -1378,7 +1378,7 @@ void nodeRegisterType(bNodeType *nt)
   BLI_assert(nt->idname[0] != '\0');
   BLI_assert(nt->poll != nullptr);
 
-  if (nt->declare && !nt->declaration_is_dynamic) {
+  if (nt->declare && !nt->declare_dynamic) {
     if (nt->fixed_declaration == nullptr) {
       nt->fixed_declaration = new blender::nodes::NodeDeclaration();
       blender::nodes::build_node_declaration(*nt, *nt->fixed_declaration);
@@ -2990,7 +2990,7 @@ void node_free_node(bNodeTree *ntree, bNode *node)
     MEM_freeN(node->prop);
   }
 
-  if (node->typeinfo->declaration_is_dynamic) {
+  if (node->typeinfo->declare_dynamic) {
     delete node->runtime->declaration;
   }
 
@@ -3602,7 +3602,7 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree * /*ntree*/, bNode *node)
   if (node->typeinfo->declare == nullptr) {
     return false;
   }
-  if (node->typeinfo->declaration_is_dynamic) {
+  if (node->typeinfo->declare_dynamic) {
     node->runtime->declaration = new blender::nodes::NodeDeclaration();
     blender::nodes::build_node_declaration(*node->typeinfo, *node->runtime->declaration);
   }
diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc
index 397556e23fc..2943bea830b 100644
--- a/source/blender/blenkernel/intern/node_tree_update.cc
+++ b/source/blender/blenkernel/intern/node_tree_update.cc
@@ -22,6 +22,7 @@
 #include "MOD_nodes.h"
 
 #include "NOD_node_declaration.hh"
+#include "NOD_socket.h"
 #include "NOD_texture.h"
 
 #include "DEG_depsgraph_query.h"
@@ -538,7 +539,6 @@ class NodeTreeMainUpdater {
 
   void update_individual_nodes(bNodeTree &ntree)
   {
-    Vector<bNode *> group_inout_nodes;
     for (bNode *node : ntree.all_nodes()) {
       nodeDeclarationEnsure(&ntree, node);
       if (this->should_update_individual_node(ntree, *node)) {
@@ -549,18 +549,9 @@ class NodeTreeMainUpdater {
         if (ntype.updatefunc) {
           ntype.updatefunc(&ntree, node);
         }
-      }
-      if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
-        group_inout_nodes.append(node);
-      }
-    }
-    /* The update function of group input/output nodes may add new interface sockets. When that
-     * happens, all the input/output nodes have to be updated again. In the future it would be
-     * better to move this functionality out of the node update function into the operator that's
-     * supposed to create the new interface socket. */
-    if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE) {
-      for (bNode *node : group_inout_nodes) {
-        node->typeinfo->updatefunc(&ntree, node);
+        if (ntype.declare_dynamic) {
+          nodes::update_node_declaration_and_sockets(ntree, *node);
+        }
       }
     }
   }
@@ -574,23 +565,8 @@ class NodeTreeMainUpdater {
       return true;
     }
     if (ntree.runtime->changed_flag & NTREE_CHANGED_LINK) {
-      ntree.ensure_topology_cache();
-      /* Node groups currently always rebuilt their sockets when they are updated.
-       * So avoid calling the update method when no new link was added to it. */
-      if (node.type == NODE_GROUP_INPUT) {
-        if (node.output_sockets().last()->is_directly_linked()) {
-          return true;
-        }
-      }
-      else if (node.type == NODE_GROUP_OUTPUT) {
-        if (node.input_sockets().last()->is_directly_linked()) {
-          return true;
-        }
-      }
-      else {
-        /* Currently we have no way to tell if a node needs to be updated when a link changed. */
-        return true;
-      }
+      /* Currently we have no way to tell if a node needs to be updated when a link changed. */
+      return true;
     }
     if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE) {
       if (ELEM(node.type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
diff --git a/source/blender/editors/space_node/link_drag_search.cc b/source/blender/editors/space_node/link_drag_search.cc
index 08d9f6ecc4f..73be1a58a86 100644
--- a/source/blender/editors/space_node/link_drag_search.cc
+++ b/source/blender/editors/space_node/link_drag_search.cc
@@ -13,6 +13,7 @@
 #include "BKE_node_tree_update.h"
 #include "BKE_screen.h"
 
+#include "NOD_socket.h"
 #include "NOD_socket_search_link.hh"
 
 #include "BLT_translation.h"
@@ -198,7 +199,7 @@ static void search_link_ops_for_asset_metadata(const bNodeTree &node_tree,
            DEG_relations_tag_update(&bmain);
 
            /* Create the inputs and outputs on the new node. */
-           node.typeinfo->group_update_func(&params.node_tree, &node);
+           nodes::update_node_declaration_and_sockets(params.node_tree, node);
 
            bNodeSocket *new_node_socket = bke::node_find_enabled_socket(
                node, in_out, socket_property->name);
diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc
index d89600cca0b..ca0361e82dc 100644
--- a/source/blender/editors/space_node/node_group.cc
+++ b/source/blender/editors/space_node/node_group.cc
@@ -933,9 +933,9 @@ static void node_group_make_insert_selected(const bContext &C,
   }
   nodeRebuildIDVector(&ntree);
 
-  node_group_update(&ntree, gnode);
-  node_group_input_update(&group, input_node);
-  node_group_output_update(&group, output_node);
+  /* Update input and output node first, since the group node declaration can depend on them. */
+  nodes::update_node_declaration_and_sockets(group, *input_node);
+  nodes::update_node_declaration_and_sockets(group, *output_node);
 
   /* move nodes in the group to the center */
   for (bNode *node : nodes_to_move) {
@@ -956,6 +956,7 @@ static void node_group_make_insert_selected(const bContext &C,
     nodeRemLink(&ntree, link);
   }
 
+  /* Handle links to the new group inputs. */
   for (const auto item : input_links.items()) {
     const char *interface_identifier = item.value.interface_socket->identifier;
     bNodeSocket *input_socket = node_group_input_find_socket(input_node, interface_identifier);
@@ -969,23 +970,17 @@ static void node_group_make_insert_selected(const bContext &C,
       link->fromnode = input_node;
       link->fromsock = input_socket;
     }
-
-    /* Add a new link outside of the group. */
-    bNodeSocket *group_node_socket = node_group_find_input_socket(gnode, interface_identifier);
-    nodeAddLink(&ntree, item.value.from_node, item.key, gnode, group_node_socket);
   }
 
+  /* Handle links to new group outputs. */
   for (const OutputLinkI

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list