Fix #152602: Avoid type conversion when making node groups

Making node groups uses the first internal socket type for an input,
which is shared with all the internal group sockets connected to the
same external socket. This can force a type conversion where there
wasn't any before making the group, leading to changes in behavior.

Exposing output sockets also adds multiple redundant group outputs,
which all use the same socket type and are connected to only one
external socket.

This patch fixes both of these issues:
- The type of a group node input is based on the external socket type.
  If this is connected to multiple internal inputs they still share the
  same   group input connection, but no new type conversions are
  created.
- Exposing an output socket with multiple links creates just one unique
  group socket now.

To make this work the `add_interface_socket_from_node` function has been
extended with an `in_out` argument, so that the socket type can be based
on the external (output) socket but create a group input socket. Some
variants of this function have been removed because they are
unnecessary. The function had a `socket_type` argument that wasn't
actually used, and wouldn't have worked anyway because
`interface_from_socket` expects matching socket/io_socket types.

Pull Request: https://projects.blender.org/blender/blender/pulls/153992
This commit is contained in:
Lukas Tönne 2026-02-24 09:38:14 +01:00
parent 6d9d9b0e06
commit 63fccca32d
7 changed files with 53 additions and 70 deletions

View file

@ -267,6 +267,8 @@ def execute_group_insert(test_case, test_tree, expected_tree=None):
# Should have one node group labeled "external".
assert len(test_nodes_external) == 1
group_node = test_nodes_external[0]
# Ensure single-user node group, so that inserting nodes does not modify a shared tree.
group_node.node_tree = group_node.node_tree.copy()
with node_editor_context_override(bpy.context, test_tree, selected_nodes=test_nodes_internal + [group_node], active_node=group_node):
bpy.ops.node.group_insert()
@ -400,7 +402,7 @@ class AbstractNodeCopyOperatorTest(unittest.TestCase):
self.assertTrue(args.testdir.exists(),
'Test dir {0} should exist'.format(args.testdir))
open_test_file()
self.assertEqual(bpy.data.version, (5, 1, 27))
self.assertEqual(bpy.data.version, (5, 2, 5))
def tearDown(self):
self._tempdir.cleanup()