Fix #104219: Node links are sometimes created from the wrong socket #104420
@ -247,24 +247,8 @@ static bool compare_node_depth(const bNode *a, const bNode *b)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void node_sort(SpaceNode &snode, bNodeTree &ntree)
|
void node_sort(bNodeTree &ntree)
|
||||||
{
|
{
|
||||||
/* A second operation can depend on the socket locations after nodes are reordered. Usually that
|
|
||||||
* is fine, but occasionally there is no redraw in between to recalculate the socket positions
|
|
||||||
* with the new node order. For example, node selection picking and the link drag operator can
|
|
||||||
* happen without a redraw in between. For these cases, we have to reorder the socket positions
|
|
||||||
* as well. */
|
|
||||||
const Span<float2> old_socket_locations = snode.runtime->all_socket_locations;
|
|
||||||
const bool copy_socket_locations = snode.edittree == &ntree && !old_socket_locations.is_empty();
|
|
||||||
Map<const bNodeSocket *, int> old_socket_indices;
|
|
||||||
if (copy_socket_locations) {
|
|
||||||
ntree.ensure_topology_cache();
|
|
||||||
old_socket_indices.reserve(ntree.all_sockets().size());
|
|
||||||
for (const bNodeSocket *socket : ntree.all_sockets()) {
|
|
||||||
old_socket_indices.add_new(socket, socket->index_in_tree());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Array<bNode *> sort_nodes = ntree.all_nodes();
|
Array<bNode *> sort_nodes = ntree.all_nodes();
|
||||||
std::stable_sort(sort_nodes.begin(), sort_nodes.end(), compare_node_depth);
|
std::stable_sort(sort_nodes.begin(), sort_nodes.end(), compare_node_depth);
|
||||||
|
|
||||||
@ -283,16 +267,6 @@ void node_sort(SpaceNode &snode, bNodeTree &ntree)
|
|||||||
ntree.runtime->nodes_by_id.add_new(sort_nodes[i]);
|
ntree.runtime->nodes_by_id.add_new(sort_nodes[i]);
|
||||||
sort_nodes[i]->runtime->index_in_tree = i;
|
sort_nodes[i]->runtime->index_in_tree = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy_socket_locations) {
|
|
||||||
ntree.ensure_topology_cache();
|
|
||||||
Vector<float2> new_socket_locations(ntree.all_sockets().size());
|
|
||||||
for (const bNodeSocket *socket : ntree.all_sockets()) {
|
|
||||||
const float2 old_location = old_socket_locations[old_socket_indices.lookup(socket)];
|
|
||||||
new_socket_locations[socket->index_in_tree()] = old_location;
|
|
||||||
}
|
|
||||||
snode.runtime->all_socket_locations = std::move(new_socket_locations);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Array<uiBlock *> node_uiblocks_init(const bContext &C, const Span<bNode *> nodes)
|
static Array<uiBlock *> node_uiblocks_init(const bContext &C, const Span<bNode *> nodes)
|
||||||
|
@ -173,7 +173,7 @@ void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, ui
|
|||||||
* Sort nodes by selection: unselected nodes first, then selected,
|
* Sort nodes by selection: unselected nodes first, then selected,
|
||||||
* then the active node at the very end. Relative order is kept intact.
|
* then the active node at the very end. Relative order is kept intact.
|
||||||
*/
|
*/
|
||||||
void node_sort(SpaceNode &snode, bNodeTree &ntree);
|
void node_sort(bNodeTree &ntree);
|
||||||
HooglyBoogly marked this conversation as resolved
|
|||||||
|
|
||||||
void node_set_cursor(wmWindow &win, SpaceNode &snode, const float2 &cursor);
|
void node_set_cursor(wmWindow &win, SpaceNode &snode, const float2 &cursor);
|
||||||
/* DPI scaled coords */
|
/* DPI scaled coords */
|
||||||
|
@ -1725,7 +1725,7 @@ static int node_parent_set_exec(bContext *C, wmOperator * /*op*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node_sort(snode, ntree);
|
node_sort(ntree);
|
||||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
@ -1812,7 +1812,7 @@ static int node_join_exec(bContext *C, wmOperator * /*op*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node_sort(snode, ntree);
|
node_sort(ntree);
|
||||||
ED_node_tree_propagate_change(C, &bmain, snode.edittree);
|
ED_node_tree_propagate_change(C, &bmain, snode.edittree);
|
||||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||||
|
|
||||||
@ -1903,7 +1903,7 @@ static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node_sort(snode, ntree);
|
node_sort(ntree);
|
||||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
@ -1978,7 +1978,7 @@ static int node_detach_exec(bContext *C, wmOperator * /*op*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node_sort(snode, ntree);
|
node_sort(ntree);
|
||||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
|
@ -439,7 +439,7 @@ static int node_select_grouped_exec(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
node_sort(snode, node_tree);
|
node_sort(node_tree);
|
||||||
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
@ -507,7 +507,7 @@ void node_select_single(bContext &C, bNode &node)
|
|||||||
ED_node_set_active(bmain, &snode, &node_tree, &node, &active_texture_changed);
|
ED_node_set_active(bmain, &snode, &node_tree, &node, &active_texture_changed);
|
||||||
ED_node_set_active_viewer_key(&snode);
|
ED_node_set_active_viewer_key(&snode);
|
||||||
|
|
||||||
node_sort(snode, node_tree);
|
node_sort(node_tree);
|
||||||
if (active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) {
|
if (active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) {
|
||||||
DEG_id_tag_update(&node_tree.id, ID_RECALC_COPY_ON_WRITE);
|
DEG_id_tag_update(&node_tree.id, ID_RECALC_COPY_ON_WRITE);
|
||||||
}
|
}
|
||||||
@ -665,7 +665,7 @@ static bool node_mouse_select(bContext *C,
|
|||||||
viewer_path::activate_geometry_node(bmain, snode, *node);
|
viewer_path::activate_geometry_node(bmain, snode, *node);
|
||||||
}
|
}
|
||||||
ED_node_set_active_viewer_key(&snode);
|
ED_node_set_active_viewer_key(&snode);
|
||||||
node_sort(snode, node_tree);
|
node_sort(node_tree);
|
||||||
if ((active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) ||
|
if ((active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) ||
|
||||||
viewer_node_changed) {
|
viewer_node_changed) {
|
||||||
DEG_id_tag_update(&snode.edittree->id, ID_RECALC_COPY_ON_WRITE);
|
DEG_id_tag_update(&snode.edittree->id, ID_RECALC_COPY_ON_WRITE);
|
||||||
@ -794,7 +794,7 @@ static int node_box_select_exec(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node_sort(snode, node_tree);
|
node_sort(node_tree);
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
||||||
|
|
||||||
@ -1101,7 +1101,7 @@ static int node_select_all_exec(bContext *C, wmOperator *op)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_sort(snode, node_tree);
|
node_sort(node_tree);
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
@ -1153,7 +1153,7 @@ static int node_select_linked_to_exec(bContext *C, wmOperator * /*op*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node_sort(snode, node_tree);
|
node_sort(node_tree);
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
@ -1203,7 +1203,7 @@ static int node_select_linked_from_exec(bContext *C, wmOperator * /*op*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node_sort(snode, node_tree);
|
node_sort(node_tree);
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
|
Loading…
Reference in New Issue
Block a user
This is problematic, because the tree might be visible in multiple node editors, all of which would have to be updated.