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:
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. */