Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2022-09-29 13:43:27 +0300
committerJacques Lucke <jacques@blender.org>2022-09-29 13:43:43 +0300
commit5ffbabb24c8cca4ab2802811ecdbcdb484745107 (patch)
tree1ad6ab02b48b3c2f8ecf289ddde21607565dfa05 /source
parent1494a22a900a91483c91cdb259523e3ce063f9c3 (diff)
Nodes: fix missing updates with muted nodes and reroutes
Muted nodes and reroutes can potentially affect the output when they are linked to an input socket and don't have any inputs on their own. The issues was that previously "logically linked sockets" where used which hide reroutes and muted nodes away. The solution is to work with the directly linked sockets instead and handle reroutes etc explicitly.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/node_tree_update.cc102
1 files changed, 70 insertions, 32 deletions
diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc
index 44ca2752782..213174f31ea 100644
--- a/source/blender/blenkernel/intern/node_tree_update.cc
+++ b/source/blender/blenkernel/intern/node_tree_update.cc
@@ -1402,12 +1402,17 @@ class NodeTreeMainUpdater {
}
Array<uint32_t> get_socket_topology_hashes(const bNodeTree &tree,
- Span<const bNodeSocket *> sockets)
+ const Span<const bNodeSocket *> sockets)
{
BLI_assert(!tree.has_available_link_cycle());
Array<std::optional<uint32_t>> hash_by_socket_id(tree.all_sockets().size());
Stack<const bNodeSocket *> sockets_to_check = sockets;
+ auto get_socket_ptr_hash = [&](const bNodeSocket &socket) {
+ const uint64_t socket_ptr = uintptr_t(&socket);
+ return noise::hash(socket_ptr, socket_ptr >> 32);
+ };
+
while (!sockets_to_check.is_empty()) {
const bNodeSocket &socket = *sockets_to_check.peek();
const bNode &node = socket.owner_node();
@@ -1418,31 +1423,45 @@ class NodeTreeMainUpdater {
continue;
}
+ uint32_t socket_hash = 0;
if (socket.is_input()) {
/* For input sockets, first compute the hashes of all linked sockets. */
bool all_origins_computed = true;
- for (const bNodeSocket *origin_socket : socket.logically_linked_sockets()) {
- if (!hash_by_socket_id[origin_socket->index_in_tree()].has_value()) {
- sockets_to_check.push(origin_socket);
+ bool get_value_from_origin = false;
+ for (const bNodeLink *link : socket.directly_linked_links()) {
+ if (link->is_muted()) {
+ continue;
+ }
+ if (!link->is_available()) {
+ continue;
+ }
+ const bNodeSocket &origin_socket = *link->fromsock;
+ const std::optional<uint32_t> origin_hash =
+ hash_by_socket_id[origin_socket.index_in_tree()];
+ if (origin_hash.has_value()) {
+ if (get_value_from_origin || socket.type != origin_socket.type) {
+ socket_hash = noise::hash(socket_hash, *origin_hash);
+ }
+ else {
+ /* Copy the socket hash because the link did not change it. */
+ socket_hash = *origin_hash;
+ }
+ get_value_from_origin = true;
+ }
+ else {
+ sockets_to_check.push(&origin_socket);
all_origins_computed = false;
}
}
if (!all_origins_computed) {
continue;
}
- /* When the hashes for the linked sockets are ready, combine them into a hash for the input
- * socket. */
- const uint64_t socket_ptr = uintptr_t(&socket);
- uint32_t socket_hash = noise::hash(socket_ptr, socket_ptr >> 32);
- for (const bNodeSocket *origin_socket : socket.logically_linked_sockets()) {
- const uint32_t origin_socket_hash = *hash_by_socket_id[origin_socket->index_in_tree()];
- socket_hash = noise::hash(socket_hash, origin_socket_hash);
+
+ if (!get_value_from_origin) {
+ socket_hash = get_socket_ptr_hash(socket);
}
- hash_by_socket_id[socket.index_in_tree()] = socket_hash;
- sockets_to_check.pop();
}
else {
- /* For output sockets, first compute the hashes of all available input sockets. */
bool all_available_inputs_computed = true;
for (const bNodeSocket *input_socket : node.input_sockets()) {
if (input_socket->is_available()) {
@@ -1455,29 +1474,48 @@ class NodeTreeMainUpdater {
if (!all_available_inputs_computed) {
continue;
}
- /* When all input socket hashes have been computed, combine them into a hash for the output
- * socket. */
- const uint64_t socket_ptr = uintptr_t(&socket);
- uint32_t socket_hash = noise::hash(socket_ptr, socket_ptr >> 32);
- for (const bNodeSocket *input_socket : node.input_sockets()) {
- if (input_socket->is_available()) {
- const uint32_t input_socket_hash = *hash_by_socket_id[input_socket->index_in_tree()];
- socket_hash = noise::hash(socket_hash, input_socket_hash);
+ if (node.type == NODE_REROUTE) {
+ socket_hash = *hash_by_socket_id[node.input_socket(0).index_in_tree()];
+ }
+ else if (node.is_muted()) {
+ const bNodeSocket *internal_input = socket.internal_link_input();
+ if (internal_input == nullptr) {
+ socket_hash = get_socket_ptr_hash(socket);
+ }
+ else {
+ if (internal_input->type == socket.type) {
+ socket_hash = *hash_by_socket_id[internal_input->index_in_tree()];
+ }
+ else {
+ socket_hash = get_socket_ptr_hash(socket);
+ }
}
}
- /* The Image Texture node has a special case. The behavior of the color output changes
- * depending on whether the Alpha output is linked. */
- if (node.type == SH_NODE_TEX_IMAGE && socket.index() == 0) {
- BLI_assert(STREQ(socket.name, "Color"));
- const bNodeSocket &alpha_socket = node.output_socket(1);
- BLI_assert(STREQ(alpha_socket.name, "Alpha"));
- if (alpha_socket.is_directly_linked()) {
- socket_hash = noise::hash(socket_hash);
+ else {
+ socket_hash = get_socket_ptr_hash(socket);
+ for (const bNodeSocket *input_socket : node.input_sockets()) {
+ if (input_socket->is_available()) {
+ const uint32_t input_socket_hash = *hash_by_socket_id[input_socket->index_in_tree()];
+ socket_hash = noise::hash(socket_hash, input_socket_hash);
+ }
+ }
+
+ /* The Image Texture node has a special case. The behavior of the color output changes
+ * depending on whether the Alpha output is linked. */
+ if (node.type == SH_NODE_TEX_IMAGE && socket.index() == 0) {
+ BLI_assert(STREQ(socket.name, "Color"));
+ const bNodeSocket &alpha_socket = node.output_socket(1);
+ BLI_assert(STREQ(alpha_socket.name, "Alpha"));
+ if (alpha_socket.is_directly_linked()) {
+ socket_hash = noise::hash(socket_hash);
+ }
}
}
- hash_by_socket_id[socket.index_in_tree()] = socket_hash;
- sockets_to_check.pop();
}
+ hash_by_socket_id[socket.index_in_tree()] = socket_hash;
+ /* Check that nothing has been pushed in the meantime. */
+ BLI_assert(sockets_to_check.peek() == &socket);
+ sockets_to_check.pop();
}
/* Create output array. */