Fix #124467: lazy-connect does not work with Capture Attribute node

The lazy-connect feature of node wrangler uses the built-in `connect_sockets`
function which automatically handles virtual sockets in group input and output
nodes already. However, it does not handle virtual sockets in other nodes.

The fix is to generalize this behavior. For that, a new `handle_dynamic_sockets`
boolean input is added to `tree.links.new`. When enabled, virtual sockets are
handled properly by internally calling the `bNodeType.insert_link` methods.

The new behavior is turned of by default for compatibility reasons.

Pull Request: https://projects.blender.org/blender/blender/pulls/126282
This commit is contained in:
Jacques Lucke
2024-08-13 16:25:20 +02:00
parent 59a4fdfc81
commit d81ba55ce4
2 changed files with 36 additions and 17 deletions

View File

@@ -74,21 +74,7 @@ def connect_sockets(input, output):
print("Cannot connect two virtual sockets together")
return
if output_node.type == 'GROUP_OUTPUT' and type(input) == bpy.types.NodeSocketVirtual:
output_type = find_base_socket_type(output)
socket_interface = output_node.id_data.interface.new_socket(
name=output.name, socket_type=output_type, in_out='OUTPUT'
)
input = output_node.inputs[-2]
if input_node.type == 'GROUP_INPUT' and type(output) == bpy.types.NodeSocketVirtual:
input_type = find_base_socket_type(input)
socket_interface = input_node.id_data.interface.new_socket(
name=input.name, socket_type=input_type, in_out='INPUT'
)
output = input_node.outputs[-2]
return input_node.id_data.links.new(input, output)
return input_node.id_data.links.new(input, output, handle_dynamic_sockets=True)
# XXX Names are not unique. Returns the first match.

View File

@@ -1244,7 +1244,8 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree,
ReportList *reports,
bNodeSocket *fromsock,
bNodeSocket *tosock,
bool verify_limits)
bool verify_limits,
bool handle_dynamic_sockets)
{
bNodeLink *ret;
bNode *fromnode = nullptr, *tonode = nullptr;
@@ -1262,11 +1263,38 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree,
return nullptr;
}
if (&fromsock->in_out == &tosock->in_out) {
if (fromsock->in_out == tosock->in_out) {
BKE_report(reports, RPT_ERROR, "Same input/output direction of sockets");
return nullptr;
}
if (fromsock->in_out == SOCK_IN) {
std::swap(fromsock, tosock);
std::swap(fromnode, tonode);
}
if (handle_dynamic_sockets) {
bNodeLink new_link{};
new_link.fromnode = fromnode;
new_link.fromsock = fromsock;
new_link.tonode = tonode;
new_link.tosock = tosock;
if (fromnode->typeinfo->insert_link) {
if (!fromnode->typeinfo->insert_link(ntree, fromnode, &new_link)) {
return nullptr;
}
}
if (tonode->typeinfo->insert_link) {
if (!tonode->typeinfo->insert_link(ntree, tonode, &new_link)) {
return nullptr;
}
}
fromsock = new_link.fromsock;
tosock = new_link.tosock;
}
if (verify_limits) {
/* remove other socket links if limit is exceeded */
if (blender::bke::nodeCountSocketLinks(ntree, fromsock) + 1 >
@@ -10686,6 +10714,11 @@ static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop)
true,
"Verify Limits",
"Remove existing links if connection limit is exceeded");
RNA_def_boolean(func,
"handle_dynamic_sockets",
false,
"Handle Dynamic Sockets",
"Handle node specific features like virtual sockets");
/* return */
parm = RNA_def_pointer(func, "link", "NodeLink", "", "New node link");
RNA_def_function_return(func, parm);