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.
This commit is contained in:
Lukas Stockner 2023-01-12 00:48:56 +01:00
parent 2b32a2c3b2
commit 2b4bf586ad
Notes: blender-bot 2023-02-14 06:45:14 +01:00
Referenced by issue #103837, Regression : crash opening file with uv from GN primitive
Referenced by issue #102920, Muted node only passes through on last connected ouput of type
1 changed files with 19 additions and 14 deletions

View File

@ -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);
}
}
}
}
}