Remove simulation inputs when deleting outputs and vice versa #106597

Merged
3 changed files with 26 additions and 0 deletions

View File

@ -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);

View File

@ -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);
LukasTonne marked this conversation as resolved Outdated

Use a reference rather than a pointer if node_tree is expected to be non-null.

Use a reference rather than a pointer if `node_tree` is expected to be non-null.
void node_select_single(bContext &C, bNode &node);
void NODE_OT_select(wmOperatorType *ot);

View File

@ -308,6 +308,22 @@ 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")) {
LukasTonne marked this conversation as resolved Outdated

Rather than looping over all nodes, this could use nodes_by_type at the start too. That makes sense, since there are plenty of large node trees that don't use simulation nodes (or any paired nodes) at all, and it reduces reliance on bNode::type, which would be good to remove eventually.

Rather than looping over all nodes, this could use `nodes_by_type` at the start too. That makes sense, since there are plenty of large node trees that don't use simulation nodes (or any paired nodes) at all, and it reduces reliance on `bNode::type`, which would be good to remove eventually.
const NodeGeometrySimulationInput *storage = static_cast<NodeGeometrySimulationInput *>(
LukasTonne marked this conversation as resolved Outdated

It usually makes sense to flip the condition and use continue rather than indenting the rest of the function, I'd say that applies here too.

It usually makes sense to flip the condition and use `continue` rather than indenting the rest of the function, I'd say that applies here too.
input_node->storage);
if (bNode *output_node = node_tree.node_by_id(storage->output_node_id)) {
LukasTonne marked this conversation as resolved Outdated

NodeGeometrySimulationInput * -> const NodeGeometrySimulationInput *

Here and below

`NodeGeometrySimulationInput *` -> `const NodeGeometrySimulationInput *` Here and below
if (input_node->flag & NODE_SELECT) {
output_node->flag |= NODE_SELECT;
}
if (output_node->flag & NODE_SELECT) {
input_node->flag |= NODE_SELECT;
}
}
}
}
VectorSet<bNode *> get_selected_nodes(bNodeTree &node_tree)
{
VectorSet<bNode *> selected_nodes;