[Bf-blender-cvs] [2b4bf586ade] master: Fix T102920: Cycles doesn't support multiple outputs on muted nodes

Lukas Stockner noreply at git.blender.org
Thu Jan 12 00:56:56 CET 2023


Commit: 2b4bf586ade5a5941f116383074871941a629f23
Author: Lukas Stockner
Date:   Thu Jan 12 00:48:56 2023 +0100
Branches: master
https://developer.blender.org/rB2b4bf586ade5a5941f116383074871941a629f23

Fix T102920: Cycles doesn't support multiple outputs on muted nodes

Cycles converts internal links to converter nodes which don't do anything and
later on get collapsed by the graph optimization. However, the previous code
assumed that one Blender input socket maps to one Cycles input socket.

When a node is muted, there might be internal links from one input to multiple
outputs. In Cycles, this meant that one Blender input socket now mapped to
multiple input sockets on all the converter nodes, so only the last one survived.

THe fix is simple, just make the mapping a MultiMap.

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

M	intern/cycles/blender/shader.cpp

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

diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp
index f25e98469fb..5220e680a50 100644
--- a/intern/cycles/blender/shader.cpp
+++ b/intern/cycles/blender/shader.cpp
@@ -26,7 +26,7 @@
 
 CCL_NAMESPACE_BEGIN
 
-typedef map<void *, ShaderInput *> PtrInputMap;
+typedef unordered_multimap<void *, ShaderInput *> PtrInputMap;
 typedef map<void *, ShaderOutput *> PtrOutputMap;
 typedef map<string, ConvertNode *> ProxyMap;
 
@@ -1251,7 +1251,9 @@ static void add_nodes(Scene *scene,
 
         ConvertNode *proxy = graph->create_node<ConvertNode>(to_socket_type, to_socket_type, true);
 
-        input_map[b_link.from_socket().ptr.data] = proxy->inputs[0];
+        /* Muted nodes can result in multiple Cycles input sockets mapping to the same Blender
+         * input socket, so this needs to be a multimap. */
+        input_map.emplace(b_link.from_socket().ptr.data, proxy->inputs[0]);
         output_map[b_link.to_socket().ptr.data] = proxy->outputs[0];
 
         graph->add(proxy);
@@ -1286,7 +1288,7 @@ static void add_nodes(Scene *scene,
         /* register the proxy node for internal binding */
         group_proxy_input_map[b_input.identifier()] = proxy;
 
-        input_map[b_input.ptr.data] = proxy->inputs[0];
+        input_map.emplace(b_input.ptr.data, proxy->inputs[0]);
 
         set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
       }
@@ -1338,7 +1340,7 @@ static void add_nodes(Scene *scene,
           if (proxy_it != proxy_output_map.end()) {
             ConvertNode *proxy = proxy_it->second;
 
-            input_map[b_input.ptr.data] = proxy->inputs[0];
+            input_map.emplace(b_input.ptr.data, proxy->inputs[0]);
 
             set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
           }
@@ -1369,7 +1371,7 @@ static void add_nodes(Scene *scene,
             /* XXX should not happen, report error? */
             continue;
           }
-          input_map[b_input.ptr.data] = input;
+          input_map.emplace(b_input.ptr.data, input);
 
           set_default_value(input, b_input, b_data, b_ntree);
         }
@@ -1401,20 +1403,23 @@ static void add_nodes(Scene *scene,
     BL::NodeSocket b_from_sock = b_link.from_socket();
     BL::NodeSocket b_to_sock = b_link.to_socket();
 
-    ShaderOutput *output = 0;
-    ShaderInput *input = 0;
-
+    ShaderOutput *output = nullptr;
     PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
     if (output_it != output_map.end())
       output = output_it->second;
-    PtrInputMap::iterator input_it = input_map.find(b_to_sock.ptr.data);
-    if (input_it != input_map.end())
-      input = input_it->second;
 
-    /* either node may be NULL when the node was not exported, typically
+    /* either socket may be NULL when the node was not exported, typically
      * because the node type is not supported */
-    if (output && input)
-      graph->connect(output, input);
+    if (output != nullptr) {
+      ShaderOutput *output = output_it->second;
+      auto inputs = input_map.equal_range(b_to_sock.ptr.data);
+      for (PtrInputMap::iterator input_it = inputs.first; input_it != inputs.second; ++input_it) {
+        ShaderInput *input = input_it->second;
+        if (input != nullptr) {
+          graph->connect(output, input);
+        }
+      }
+    }
   }
 }



More information about the Bf-blender-cvs mailing list