[Bf-blender-cvs] [861f65040b5] node-tree-update-refactor: progress

Jacques Lucke noreply at git.blender.org
Mon Nov 15 19:09:22 CET 2021


Commit: 861f65040b582b7d52afee3fa7117f7f0d3f6cdb
Author: Jacques Lucke
Date:   Mon Nov 15 18:24:56 2021 +0100
Branches: node-tree-update-refactor
https://developer.blender.org/rB861f65040b582b7d52afee3fa7117f7f0d3f6cdb

progress

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

M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/node_tree_update.cc

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

diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 645b4410623..59664d42c4c 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -489,6 +489,7 @@ void ntreeUpdateAllUsers(struct Main *main, struct ID *id, int tree_update_flag)
 void ntreeGetDependencyList(struct bNodeTree *ntree,
                             struct bNode ***r_deplist,
                             int *r_deplist_len);
+void ntreeUpdateNodeLevels(struct bNodeTree *ntree);
 
 /* XXX old trees handle output flags automatically based on special output
  * node types and last active selection.
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 4fa2e0c379a..4079b5f2422 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -4454,7 +4454,7 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist,
 }
 
 /* only updates node->level for detecting cycles links */
-static void ntree_update_node_level(bNodeTree *ntree)
+void ntreeUpdateNodeLevels(bNodeTree *ntree)
 {
   /* first clear tag */
   LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
@@ -4542,519 +4542,6 @@ void ntreeUpdateAllNew(Main *main)
   BKE_node_tree_update_main(main, nullptr);
 }
 
-namespace blender::bke::node_field_inferencing {
-
-static bool is_field_socket_type(eNodeSocketDatatype type)
-{
-  return ELEM(type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA);
-}
-
-static bool is_field_socket_type(const SocketRef &socket)
-{
-  return is_field_socket_type((eNodeSocketDatatype)socket.typeinfo()->type);
-}
-
-static bool update_field_inferencing(bNodeTree &btree);
-
-static InputSocketFieldType get_interface_input_field_type(const NodeRef &node,
-                                                           const InputSocketRef &socket)
-{
-  if (!is_field_socket_type(socket)) {
-    return InputSocketFieldType::None;
-  }
-  if (node.is_reroute_node()) {
-    return InputSocketFieldType::IsSupported;
-  }
-  if (node.is_group_output_node()) {
-    /* Outputs always support fields when the data type is correct. */
-    return InputSocketFieldType::IsSupported;
-  }
-  if (node.is_undefined()) {
-    return InputSocketFieldType::None;
-  }
-
-  const NodeDeclaration *node_decl = node.declaration();
-
-  /* Node declarations should be implemented for nodes involved here. */
-  BLI_assert(node_decl != nullptr);
-
-  /* Get the field type from the declaration. */
-  const SocketDeclaration &socket_decl = *node_decl->inputs()[socket.index()];
-  const InputSocketFieldType field_type = socket_decl.input_field_type();
-  if (field_type == InputSocketFieldType::Implicit) {
-    return field_type;
-  }
-  if (node_decl->is_function_node()) {
-    /* In a function node, every socket supports fields. */
-    return InputSocketFieldType::IsSupported;
-  }
-  return field_type;
-}
-
-static OutputFieldDependency get_interface_output_field_dependency(const NodeRef &node,
-                                                                   const OutputSocketRef &socket)
-{
-  if (!is_field_socket_type(socket)) {
-    /* Non-field sockets always output data. */
-    return OutputFieldDependency::ForDataSource();
-  }
-  if (node.is_reroute_node()) {
-    /* The reroute just forwards what is passed in. */
-    return OutputFieldDependency::ForDependentField();
-  }
-  if (node.is_group_input_node()) {
-    /* Input nodes get special treatment in #determine_group_input_states. */
-    return OutputFieldDependency::ForDependentField();
-  }
-  if (node.is_undefined()) {
-    return OutputFieldDependency::ForDataSource();
-  }
-
-  const NodeDeclaration *node_decl = node.declaration();
-
-  /* Node declarations should be implemented for nodes involved here. */
-  BLI_assert(node_decl != nullptr);
-
-  if (node_decl->is_function_node()) {
-    /* In a generic function node, all outputs depend on all inputs. */
-    return OutputFieldDependency::ForDependentField();
-  }
-
-  /* Use the socket declaration. */
-  const SocketDeclaration &socket_decl = *node_decl->outputs()[socket.index()];
-  return socket_decl.output_field_dependency();
-}
-
-static FieldInferencingInterface get_dummy_field_inferencing_interface(const NodeRef &node)
-{
-  FieldInferencingInterface inferencing_interface;
-  inferencing_interface.inputs.append_n_times(InputSocketFieldType::None, node.inputs().size());
-  inferencing_interface.outputs.append_n_times(OutputFieldDependency::ForDataSource(),
-                                               node.outputs().size());
-  return inferencing_interface;
-}
-
-/**
- * Retrieves information about how the node interacts with fields.
- * In the future, this information can be stored in the node declaration. This would allow this
- * function to return a reference, making it more efficient.
- */
-static FieldInferencingInterface get_node_field_inferencing_interface(const NodeRef &node)
-{
-  /* Node groups already reference all required information, so just return that. */
-  if (node.is_group_node()) {
-    bNodeTree *group = (bNodeTree *)node.bnode()->id;
-    if (group == nullptr) {
-      return FieldInferencingInterface();
-    }
-    if (!ntreeIsRegistered(group)) {
-      /* This can happen when there is a linked node group that was not found (see T92799). */
-      return get_dummy_field_inferencing_interface(node);
-    }
-    if (group->field_inferencing_interface == nullptr) {
-      /* Update group recursively. */
-      update_field_inferencing(*group);
-    }
-    return *group->field_inferencing_interface;
-  }
-
-  FieldInferencingInterface inferencing_interface;
-  for (const InputSocketRef *input_socket : node.inputs()) {
-    inferencing_interface.inputs.append(get_interface_input_field_type(node, *input_socket));
-  }
-
-  for (const OutputSocketRef *output_socket : node.outputs()) {
-    inferencing_interface.outputs.append(
-        get_interface_output_field_dependency(node, *output_socket));
-  }
-  return inferencing_interface;
-}
-
-/**
- * This struct contains information for every socket. The values are propagated through the
- * network.
- */
-struct SocketFieldState {
-  /* This socket starts a new field. */
-  bool is_field_source = false;
-  /* This socket can never become a field, because the node itself does not support it. */
-  bool is_always_single = false;
-  /* This socket is currently a single value. It could become a field though. */
-  bool is_single = true;
-  /* This socket is required to be a single value. This can be because the node itself only
-   * supports this socket to be a single value, or because a node afterwards requires this to be a
-   * single value. */
-  bool requires_single = false;
-};
-
-static Vector<const InputSocketRef *> gather_input_socket_dependencies(
-    const OutputFieldDependency &field_dependency, const NodeRef &node)
-{
-  const OutputSocketFieldType type = field_dependency.field_type();
-  Vector<const InputSocketRef *> input_sockets;
-  switch (type) {
-    case OutputSocketFieldType::FieldSource:
-    case OutputSocketFieldType::None: {
-      break;
-    }
-    case OutputSocketFieldType::DependentField: {
-      /* This output depends on all inputs. */
-      input_sockets.extend(node.inputs());
-      break;
-    }
-    case OutputSocketFieldType::PartiallyDependent: {
-      /* This output depends only on a few inputs. */
-      for (const int i : field_dependency.linked_input_indices()) {
-        input_sockets.append(&node.input(i));
-      }
-      break;
-    }
-  }
-  return input_sockets;
-}
-
-/**
- * Check what the group output socket depends on. Potentially traverses the node tree
- * to figure out if it is always a field or if it depends on any group inputs.
- */
-static OutputFieldDependency find_group_output_dependencies(
-    const InputSocketRef &group_output_socket,
-    const Span<SocketFieldState> field_state_by_socket_id)
-{
-  if (!is_field_socket_type(group_output_socket)) {
-    return OutputFieldDependency::ForDataSource();
-  }
-
-  /* Use a Set here instead of an array indexed by socket id, because we my only need to look at
-   * very few sockets. */
-  Set<const InputSocketRef *> handled_sockets;
-  Stack<const InputSocketRef *> sockets_to_check;
-
-  handled_sockets.add(&group_output_socket);
-  sockets_to_check.push(&group_output_socket);
-
-  /* Keeps track of group input indices that are (indirectly) connected to the output. */
-  Vector<int> linked_input_indices;
-
-  while (!sockets_to_check.is_empty()) {
-    const InputSocketRef *input_socket = sockets_to_check.pop();
-
-    for (const OutputSocketRef *origin_socket : input_socket->directly_linked_sockets()) {
-      const NodeRef &origin_node = origin_socket->node();
-      const SocketFieldState &origin_state = field_state_by_socket_id[origin_socket->id()];
-
-      if (origin_state.is_field_source) {
-        if (origin_node.is_group_input_node()) {
-          /* Found a group input that the group output depends on. */
-          linked_input_indices.append_non_duplicates(origin_socket->index());
-        }
-        else {
-          /* Found a field source that is not the group input. So the output is always a field. */
-          return OutputFieldDependency::ForFieldSource();
-        }
-      }
-      else if (!origin_state.is_single) {
-        const FieldInferencingInterface inferencing_interface =
-            get_node_field_inferencing_interface(origin_node);
-        const OutputFieldDependency &field_dependency =
-            inferencing_interface.outputs[origin_socket->index()];
-
-        /* Propagate search further to the left. */
-        for (const InputSocketRef *origin_input_socket :
-             gather_input_socket_dependencies(field_dependency, origin_node)) {
-          if (!origin_input_socket->is_available()) {
-            continue;
-          }
-          if (!field_state_by_socket_id[origin_input_socket->id()].is_single) {
-            if (handled_sockets.add(origin_input_socket)) {
-              sockets_to_check.push(origin_input_socket);
-            }
-          }
-        }
-      }
-    }
-  }
-  return OutputFi

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list