mirror of
https://github.com/blender/blender
synced 2026-11-01 03:16:58 +03:00
When inside a group, the `Connect to Socket` operator creates a temporary socket for viewing. This uses `node_utils.find_base_socket_type` to determine which data type to use for the new socket. This function is missing newer socket types, causing errors upstream when a type couldn't be determined. This patch updates the helper function to have a basic fallback case that follows the most common pattern. This makes it so that the function doesn't have to be updated for each new socket type, provided it follows the common convention. Pull Request: https://projects.blender.org/blender/blender/pulls/164271
91 lines
2.6 KiB
Python
91 lines
2.6 KiB
Python
# SPDX-FileCopyrightText: 2009-2023 Blender Authors
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
__all__ = (
|
|
"connect_sockets",
|
|
"find_base_socket_type",
|
|
"find_node_input",
|
|
)
|
|
|
|
|
|
def find_base_socket_type(socket):
|
|
"""
|
|
Find the base class of the socket.
|
|
|
|
Sockets can have a subtype such as NodeSocketFloatFactor,
|
|
but only the base type is allowed, e.g. NodeSocketFloat
|
|
|
|
:param socket: The socket to find the base type for.
|
|
:type socket: :class:`bpy.types.NodeSocket`
|
|
:return: The base socket type identifier.
|
|
:rtype: str
|
|
"""
|
|
if socket.type == 'CUSTOM':
|
|
# Custom socket types are used directly
|
|
return socket.bl_idname
|
|
if socket.type == 'VALUE':
|
|
return 'NodeSocketFloat'
|
|
if socket.type == 'BOOLEAN':
|
|
return 'NodeSocketBool'
|
|
if socket.type == 'RGBA':
|
|
return 'NodeSocketColor'
|
|
else:
|
|
return "NodeSocket" + socket.type.title()
|
|
|
|
|
|
def connect_sockets(input, output):
|
|
"""
|
|
Connect sockets in a node tree.
|
|
|
|
This is useful because the links created through the normal Python API are
|
|
invalid when one of the sockets is a virtual socket (grayed out sockets in
|
|
Group Input and Group Output nodes).
|
|
|
|
It replaces node_tree.links.new(input, output)
|
|
|
|
:param input: The input socket.
|
|
:type input: :class:`bpy.types.NodeSocket`
|
|
:param output: The output socket.
|
|
:type output: :class:`bpy.types.NodeSocket`
|
|
:return: The created link, or ``None`` when the sockets cannot be connected.
|
|
:rtype: :class:`bpy.types.NodeLink` | None
|
|
"""
|
|
import bpy
|
|
|
|
# Swap sockets if they are not passed in the proper order
|
|
if input.is_output and not output.is_output:
|
|
input, output = output, input
|
|
|
|
input_node = output.node
|
|
output_node = input.node
|
|
|
|
if input_node.id_data is not output_node.id_data:
|
|
print("Sockets do not belong to the same node tree")
|
|
return
|
|
|
|
if type(input) == type(output) == bpy.types.NodeSocketVirtual:
|
|
print("Cannot connect two virtual sockets together")
|
|
return
|
|
|
|
return input_node.id_data.links.new(input, output, handle_dynamic_sockets=True)
|
|
|
|
|
|
def find_node_input(node, name):
|
|
"""
|
|
Find a node input socket by name.
|
|
|
|
Note that names are not unique, returns the first match.
|
|
|
|
:param node: The node to search.
|
|
:type node: :class:`bpy.types.Node`
|
|
:param name: The name of the input socket.
|
|
:type name: str
|
|
:return: The input socket or None if not found.
|
|
:rtype: :class:`bpy.types.NodeSocket` | None
|
|
"""
|
|
for input in node.inputs:
|
|
if input.name == name:
|
|
return input
|
|
|
|
return None
|