Fix for node group "make" adding sockets in wrong order

Making a group from a single node that has some connections will add the
connected outputs and inputs first, then add all unconnected outputs and
inputs. This can lead to incorrect socket order (out-in-out-in).

This patch integrates unconnected sockets into the main outputs/inputs
loops to ensure all outputs are added before inputs.

Pull Request: https://projects.blender.org/blender/blender/pulls/112281
This commit is contained in:
Lukas Tönne
2023-09-12 14:27:09 +02:00
parent c59d998ce5
commit 7b680850c6

View File

@@ -985,6 +985,9 @@ static void node_group_make_insert_selected(const bContext &C,
float2 real_min, real_max;
get_min_max_of_nodes(nodes_to_move, true, real_min, real_max);
/* If only one node is selected expose all its sockets regardless of links. */
const bool expose_visible = nodes_to_move.size() == 1;
/* Reuse an existing output node or create a new one. */
group.ensure_topology_cache();
bNode *output_node = [&]() {
@@ -1013,6 +1016,12 @@ static void node_group_make_insert_selected(const bContext &C,
const bNodeTreeInterfaceSocket *interface_socket;
};
struct NewInternalLinkInfo {
bNode *node;
bNodeSocket *socket;
const bNodeTreeInterfaceSocket *interface_socket;
};
/* Map from single non-selected output sockets to potentially many selected input sockets. */
Map<bNodeSocket *, InputSocketInfo> input_links;
Vector<OutputLinkInfo> output_links;
@@ -1020,11 +1029,16 @@ static void node_group_make_insert_selected(const bContext &C,
Set<bNodeLink *> links_to_remove;
/* Map old to new node identifiers. */
Map<int32_t, int32_t> node_identifier_map;
Vector<NewInternalLinkInfo> new_internal_links;
ntree.ensure_topology_cache();
/* Add all outputs first. */
for (bNode *node : nodes_to_move) {
for (bNodeSocket *output_socket : node->output_sockets()) {
if (!output_socket->is_available() || output_socket->is_hidden()) {
continue;
}
for (bNodeLink *link : output_socket->directly_linked_links()) {
if (nodeLinkIsHidden(link)) {
links_to_remove.add(link);
@@ -1047,11 +1061,22 @@ static void node_group_make_insert_selected(const bContext &C,
links_to_remove.add(link);
}
}
if (expose_visible && !output_socket->is_directly_linked()) {
bNodeTreeInterfaceSocket *io_socket = bke::node_interface::add_interface_socket_from_node(
group, *node, *output_socket);
if (io_socket) {
new_internal_links.append({node, output_socket, io_socket});
}
}
}
}
/* Now add all inputs. */
for (bNode *node : nodes_to_move) {
for (bNodeSocket *input_socket : node->input_sockets()) {
if (!input_socket->is_available() || input_socket->is_hidden()) {
continue;
}
for (bNodeLink *link : input_socket->directly_linked_links()) {
if (nodeLinkIsHidden(link)) {
links_to_remove.add(link);
@@ -1072,36 +1097,13 @@ static void node_group_make_insert_selected(const bContext &C,
info.interface_socket = add_interface_from_socket(ntree, group, *link->tosock);
}
}
}
}
struct NewInternalLinkInfo {
bNode *node;
bNodeSocket *socket;
const bNodeTreeInterfaceSocket *interface_socket;
};
const bool expose_visible = nodes_to_move.size() == 1;
Vector<NewInternalLinkInfo> new_internal_links;
if (expose_visible) {
for (bNode *node : nodes_to_move) {
auto expose_sockets = [&](const Span<bNodeSocket *> sockets) {
for (bNodeSocket *socket : sockets) {
if (!socket->is_available() || socket->is_hidden()) {
continue;
}
if (socket->is_directly_linked()) {
continue;
}
const bNodeTreeInterfaceSocket *io_socket =
bke::node_interface::add_interface_socket_from_node(group, *node, *socket);
if (io_socket) {
new_internal_links.append({node, socket, io_socket});
}
if (expose_visible && !input_socket->is_directly_linked()) {
bNodeTreeInterfaceSocket *io_socket = bke::node_interface::add_interface_socket_from_node(
group, *node, *input_socket);
if (io_socket) {
new_internal_links.append({node, input_socket, io_socket});
}
};
expose_sockets(node->output_sockets());
expose_sockets(node->input_sockets());
}
}
}