[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