From 8e684c722abcac46a663a0be2f6b58d873ece54c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Wed, 5 Apr 2023 17:18:35 +0200 Subject: [PATCH 1/4] Remove simulation inputs when deleting outputs and vice versa. To avoid "orphaned" simulation inputs or outputs, whenever deleting such nodes the respective paired node should be deleted as well. A simple utility function selects paired nodes before the delete operator removes them. This does not affect API methods, which still remove only individual nodes. The feature is primarily a workflow improvement. Resolves #105728 --- .../blender/editors/space_node/node_edit.cc | 6 +++++ .../blender/editors/space_node/node_intern.hh | 4 ++++ .../blender/editors/space_node/node_select.cc | 24 +++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 89e4ab12db8..f9dd2015771 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1765,6 +1765,9 @@ static int node_delete_exec(bContext *C, wmOperator * /*op*/) ED_preview_kill_jobs(CTX_wm_manager(C), bmain); + /* Delete paired nodes as well. */ + node_select_paired(snode->edittree); + LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { nodeRemoveNode(bmain, snode->edittree, node, true); @@ -1852,6 +1855,9 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator * /*op*/) ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); + /* Delete paired nodes as well. */ + node_select_paired(snode->edittree); + LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { nodeInternalRelink(snode->edittree, node); diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index a18d1d19240..b3ab77892bb 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -190,6 +190,10 @@ void node_socket_select(bNode *node, bNodeSocket &sock); void node_socket_deselect(bNode *node, bNodeSocket &sock, bool deselect_node); void node_deselect_all_input_sockets(bNodeTree &node_tree, bool deselect_nodes); void node_deselect_all_output_sockets(bNodeTree &node_tree, bool deselect_nodes); +/** + * Select nodes that are paired to a selected node. + */ +void node_select_paired(bNodeTree *node_tree); void node_select_single(bContext &C, bNode &node); void NODE_OT_select(wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index 663a235b834..beeae2ec6c9 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -308,6 +308,30 @@ void node_deselect_all_output_sockets(bNodeTree &node_tree, const bool deselect_ } } +void node_select_paired(bNodeTree *node_tree) +{ + for (bNode *node : node_tree->all_nodes()) { + if (node->flag & NODE_SELECT) { + if (node->type == GEO_NODE_SIMULATION_INPUT) { + NodeGeometrySimulationInput *storage = static_cast( + node->storage); + if (bNode *output_node = node_tree->node_by_id(storage->output_node_id)) { + output_node->flag |= NODE_SELECT; + } + } + if (node->type == GEO_NODE_SIMULATION_OUTPUT) { + for (bNode *input_node : node_tree->nodes_by_type("GeometryNodeSimulationInput")) { + NodeGeometrySimulationInput *storage = static_cast( + input_node->storage); + if (storage->output_node_id == node->identifier) { + input_node->flag |= NODE_SELECT; + } + } + } + } + } +} + VectorSet get_selected_nodes(bNodeTree &node_tree) { VectorSet selected_nodes; -- 2.30.2 From 1f07e71e22266a9101db293523bc8fb388778de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Wed, 5 Apr 2023 17:55:18 +0200 Subject: [PATCH 2/4] Better implementation of `node_select_paired` using `nodes_by_type`. --- .../blender/editors/space_node/node_select.cc | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index beeae2ec6c9..fb3967f1c79 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -310,23 +310,15 @@ void node_deselect_all_output_sockets(bNodeTree &node_tree, const bool deselect_ void node_select_paired(bNodeTree *node_tree) { - for (bNode *node : node_tree->all_nodes()) { - if (node->flag & NODE_SELECT) { - if (node->type == GEO_NODE_SIMULATION_INPUT) { - NodeGeometrySimulationInput *storage = static_cast( - node->storage); - if (bNode *output_node = node_tree->node_by_id(storage->output_node_id)) { - output_node->flag |= NODE_SELECT; - } + for (bNode *input_node : node_tree->nodes_by_type("GeometryNodeSimulationInput")) { + NodeGeometrySimulationInput *storage = static_cast( + input_node->storage); + if (bNode *output_node = node_tree->node_by_id(storage->output_node_id)) { + if (input_node->flag & NODE_SELECT) { + output_node->flag |= NODE_SELECT; } - if (node->type == GEO_NODE_SIMULATION_OUTPUT) { - for (bNode *input_node : node_tree->nodes_by_type("GeometryNodeSimulationInput")) { - NodeGeometrySimulationInput *storage = static_cast( - input_node->storage); - if (storage->output_node_id == node->identifier) { - input_node->flag |= NODE_SELECT; - } - } + if (output_node->flag & NODE_SELECT) { + input_node->flag |= NODE_SELECT; } } } -- 2.30.2 From f12773ab80dde87b3c2d6327a8a4caa9cf190700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Wed, 5 Apr 2023 17:58:49 +0200 Subject: [PATCH 3/4] Reference instead of pointer for non-null node tree argument. --- source/blender/editors/space_node/node_edit.cc | 4 ++-- source/blender/editors/space_node/node_intern.hh | 2 +- source/blender/editors/space_node/node_select.cc | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index f9dd2015771..9e556dcc6b0 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1766,7 +1766,7 @@ static int node_delete_exec(bContext *C, wmOperator * /*op*/) ED_preview_kill_jobs(CTX_wm_manager(C), bmain); /* Delete paired nodes as well. */ - node_select_paired(snode->edittree); + node_select_paired(*snode->edittree); LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { @@ -1856,7 +1856,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator * /*op*/) ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); /* Delete paired nodes as well. */ - node_select_paired(snode->edittree); + node_select_paired(*snode->edittree); LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index b3ab77892bb..6a90ffeebf1 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -193,7 +193,7 @@ void node_deselect_all_output_sockets(bNodeTree &node_tree, bool deselect_nodes) /** * Select nodes that are paired to a selected node. */ -void node_select_paired(bNodeTree *node_tree); +void node_select_paired(bNodeTree &node_tree); void node_select_single(bContext &C, bNode &node); void NODE_OT_select(wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index fb3967f1c79..e72ca62a5a2 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -308,12 +308,12 @@ void node_deselect_all_output_sockets(bNodeTree &node_tree, const bool deselect_ } } -void node_select_paired(bNodeTree *node_tree) +void node_select_paired(bNodeTree &node_tree) { - for (bNode *input_node : node_tree->nodes_by_type("GeometryNodeSimulationInput")) { + for (bNode *input_node : node_tree.nodes_by_type("GeometryNodeSimulationInput")) { NodeGeometrySimulationInput *storage = static_cast( input_node->storage); - if (bNode *output_node = node_tree->node_by_id(storage->output_node_id)) { + if (bNode *output_node = node_tree.node_by_id(storage->output_node_id)) { if (input_node->flag & NODE_SELECT) { output_node->flag |= NODE_SELECT; } -- 2.30.2 From 414f9e037b41f13a78651d67468e7329ee8c537f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Wed, 5 Apr 2023 18:00:06 +0200 Subject: [PATCH 4/4] Const storage. --- source/blender/editors/space_node/node_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index e72ca62a5a2..3d56cfa5d68 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -311,7 +311,7 @@ void node_deselect_all_output_sockets(bNodeTree &node_tree, const bool deselect_ void node_select_paired(bNodeTree &node_tree) { for (bNode *input_node : node_tree.nodes_by_type("GeometryNodeSimulationInput")) { - NodeGeometrySimulationInput *storage = static_cast( + const NodeGeometrySimulationInput *storage = static_cast( input_node->storage); if (bNode *output_node = node_tree.node_by_id(storage->output_node_id)) { if (input_node->flag & NODE_SELECT) { -- 2.30.2