diff --git a/source/blender/blenkernel/BKE_node.hh b/source/blender/blenkernel/BKE_node.hh index e7ad3edce31..9345f521f39 100644 --- a/source/blender/blenkernel/BKE_node.hh +++ b/source/blender/blenkernel/BKE_node.hh @@ -226,6 +226,8 @@ struct NodeInsertLinkParams { bNodeTree &ntree; bNode &node; bNodeLink &link; + /** Optional context to allow for more advanced link insertion functionality. */ + bContext *C = nullptr; }; /** diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 8c9c3f0d429..22bb0e276fe 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -286,7 +286,8 @@ static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, in return nullptr; } -static bool snode_autoconnect_input(SpaceNode &snode, +static bool snode_autoconnect_input(bContext &C, + SpaceNode &snode, bNode *node_fr, bNodeSocket *sock_fr, bNode *node_to, @@ -302,14 +303,14 @@ static bool snode_autoconnect_input(SpaceNode &snode, bNodeLink &link = bke::node_add_link(*ntree, *node_fr, *sock_fr, *node_to, *sock_to); if (link.fromnode->typeinfo->insert_link) { - bke::NodeInsertLinkParams params{*ntree, *link.fromnode, link}; + bke::NodeInsertLinkParams params{*ntree, *link.fromnode, link, &C}; if (!link.fromnode->typeinfo->insert_link(params)) { bke::node_remove_link(ntree, link); return false; } } if (link.tonode->typeinfo->insert_link) { - bke::NodeInsertLinkParams params{*ntree, *link.tonode, link}; + bke::NodeInsertLinkParams params{*ntree, *link.tonode, link, &C}; if (!link.tonode->typeinfo->insert_link(params)) { bke::node_remove_link(ntree, link); return false; @@ -365,7 +366,10 @@ void update_multi_input_indices_for_removed_links(bNode &node) } } -static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const bool replace) +static void snode_autoconnect(bContext &C, + SpaceNode &snode, + const bool allow_multiple, + const bool replace) { bNodeTree *ntree = snode.edittree; Vector sorted_nodes = get_selected_nodes(*ntree).extract_vector(); @@ -401,7 +405,7 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const continue; } - if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) { + if (snode_autoconnect_input(C, snode, node_fr, sock_fr, node_to, sock_to, replace)) { // numlinks++; } } @@ -425,7 +429,7 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const continue; } - if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) { + if (snode_autoconnect_input(C, snode, node_fr, sock_fr, node_to, sock_to, replace)) { // numlinks++; break; } @@ -1260,14 +1264,14 @@ static void add_dragged_links_to_tree(bContext &C, bNodeLinkDrag &nldrag) bNodeLink *new_link = MEM_mallocN(__func__); *new_link = link; if (link.fromnode->typeinfo->insert_link) { - bke::NodeInsertLinkParams params{ntree, *link.fromnode, *new_link}; + bke::NodeInsertLinkParams params{ntree, *link.fromnode, *new_link, &C}; if (!link.fromnode->typeinfo->insert_link(params)) { MEM_freeN(new_link); continue; } } if (link.tonode->typeinfo->insert_link) { - bke::NodeInsertLinkParams params{ntree, *link.tonode, *new_link}; + bke::NodeInsertLinkParams params{ntree, *link.tonode, *new_link, &C}; if (!link.tonode->typeinfo->insert_link(params)) { MEM_freeN(new_link); continue; @@ -1660,7 +1664,7 @@ static wmOperatorStatus node_make_link_exec(bContext *C, wmOperator *op) ED_preview_kill_jobs(CTX_wm_manager(C), &bmain); - snode_autoconnect(snode, true, replace); + snode_autoconnect(*C, snode, true, replace); /* Deselect sockets after linking. */ node_deselect_all_input_sockets(node_tree, false); diff --git a/source/blender/nodes/NOD_sync_sockets.hh b/source/blender/nodes/NOD_sync_sockets.hh index e728a4ca0df..934962de2be 100644 --- a/source/blender/nodes/NOD_sync_sockets.hh +++ b/source/blender/nodes/NOD_sync_sockets.hh @@ -12,6 +12,7 @@ struct ReportList; struct bContext; struct bNodeTree; struct Main; +struct bNodeSocket; namespace blender::nodes { @@ -32,16 +33,20 @@ void node_can_sync_cache_clear(Main &bmain); void sync_sockets_evaluate_closure(SpaceNode &snode, bNode &evaluate_closure_node, - ReportList *reports); + ReportList *reports, + const bNodeSocket *src_closure_socket = nullptr); void sync_sockets_separate_bundle(SpaceNode &snode, bNode &separate_bundle_node, - ReportList *reports); + ReportList *reports, + const bNodeSocket *src_bundle_socket = nullptr); void sync_sockets_combine_bundle(SpaceNode &snode, bNode &combine_bundle_node, - ReportList *reports); + ReportList *reports, + const bNodeSocket *src_bundle_socket = nullptr); void sync_sockets_closure(SpaceNode &snode, bNode &closure_input_node, bNode &closure_output_node, - ReportList *reports); + ReportList *reports, + const bNodeSocket *src_closure_socket = nullptr); } // namespace blender::nodes diff --git a/source/blender/nodes/geometry/nodes/node_geo_closure.cc b/source/blender/nodes/geometry/nodes/node_geo_closure.cc index ebeb2e94b27..f6b4d372f26 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_closure.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_closure.cc @@ -181,6 +181,20 @@ static void node_free_storage(bNode *node) static bool node_insert_link(bke::NodeInsertLinkParams ¶ms) { + if (params.C && params.link.fromnode == ¶ms.node) { + const NodeGeometryClosureOutput &storage = node_storage(params.node); + if (storage.input_items.items_num == 0 && storage.output_items.items_num == 0) { + SpaceNode *snode = CTX_wm_space_node(params.C); + if (snode && snode->edittree == ¶ms.ntree) { + bNode *input_node = bke::zone_type_by_node_type(GEO_NODE_CLOSURE_OUTPUT) + ->get_corresponding_input(params.ntree, params.node); + if (input_node) { + sync_sockets_closure(*snode, *input_node, params.node, nullptr, params.link.tosock); + } + } + } + return true; + } return socket_items::try_add_item_via_any_extend_socket( params.ntree, params.node, params.node, params.link); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc b/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc index a7de6c9483b..eb138ed9e19 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_combine_bundle.cc @@ -67,6 +67,16 @@ static void node_free_storage(bNode *node) static bool node_insert_link(bke::NodeInsertLinkParams ¶ms) { + if (params.C && params.link.fromnode == ¶ms.node) { + const NodeGeometryCombineBundle &storage = node_storage(params.node); + if (storage.items_num == 0) { + SpaceNode *snode = CTX_wm_space_node(params.C); + if (snode && snode->edittree == ¶ms.ntree) { + sync_sockets_combine_bundle(*snode, params.node, nullptr, params.link.tosock); + } + } + return true; + } return socket_items::try_add_item_via_any_extend_socket( params.ntree, params.node, params.node, params.link); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_evaluate_closure.cc b/source/blender/nodes/geometry/nodes/node_geo_evaluate_closure.cc index 3b170704aee..7f76f1df2a8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_evaluate_closure.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_evaluate_closure.cc @@ -77,6 +77,16 @@ static void node_free_storage(bNode *node) static bool node_insert_link(bke::NodeInsertLinkParams ¶ms) { if (params.link.tonode == ¶ms.node) { + if (params.link.tosock == params.node.inputs.first) { + const NodeGeometryEvaluateClosure &storage = node_storage(params.node); + if (storage.input_items.items_num == 0 && storage.output_items.items_num == 0) { + SpaceNode *snode = CTX_wm_space_node(params.C); + if (snode && snode->edittree == ¶ms.ntree) { + sync_sockets_evaluate_closure(*snode, params.node, nullptr, params.link.fromsock); + } + } + return true; + } return socket_items::try_add_item_via_any_extend_socket( params.ntree, params.node, params.node, params.link); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc index 08d1a308b8e..f16b2b5dd3b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_separate_bundle.cc @@ -71,6 +71,16 @@ static void node_free_storage(bNode *node) static bool node_insert_link(bke::NodeInsertLinkParams ¶ms) { + if (params.C && params.link.tonode == ¶ms.node) { + const NodeGeometrySeparateBundle &storage = node_storage(params.node); + if (storage.items_num == 0) { + SpaceNode *snode = CTX_wm_space_node(params.C); + if (snode && snode->edittree == ¶ms.ntree) { + sync_sockets_separate_bundle(*snode, params.node, nullptr, params.link.fromsock); + } + } + return true; + } return socket_items::try_add_item_via_any_extend_socket( params.ntree, params.node, params.node, params.link); } diff --git a/source/blender/nodes/intern/sync_sockets.cc b/source/blender/nodes/intern/sync_sockets.cc index 5ce82b6eeaf..5c6789bc194 100644 --- a/source/blender/nodes/intern/sync_sockets.cc +++ b/source/blender/nodes/intern/sync_sockets.cc @@ -53,18 +53,22 @@ struct ClosureSyncState { std::optional source_signature; }; -static BundleSyncState get_sync_state_separate_bundle(const SpaceNode &snode, - const bNode &separate_bundle_node) +static BundleSyncState get_sync_state_separate_bundle( + const SpaceNode &snode, + const bNode &separate_bundle_node, + const bNodeSocket *src_bundle_socket = nullptr) { BLI_assert(separate_bundle_node.is_type("GeometryNodeSeparateBundle")); snode.edittree->ensure_topology_cache(); - const bNodeSocket &bundle_socket = separate_bundle_node.input_socket(0); + if (!src_bundle_socket) { + src_bundle_socket = &separate_bundle_node.input_socket(0); + } bke::ComputeContextCache compute_context_cache; const ComputeContext *current_context = ed::space_node::compute_context_for_edittree_socket( - snode, compute_context_cache, bundle_socket); + snode, compute_context_cache, *src_bundle_socket); const Vector source_signatures = gather_linked_origin_bundle_signatures( - current_context, bundle_socket, compute_context_cache); + current_context, *src_bundle_socket, compute_context_cache); if (source_signatures.is_empty()) { return {NodeSyncState::NoSyncSource}; } @@ -80,18 +84,22 @@ static BundleSyncState get_sync_state_separate_bundle(const SpaceNode &snode, return {NodeSyncState::Synced}; } -static BundleSyncState get_sync_state_combine_bundle(const SpaceNode &snode, - const bNode &combine_bundle_node) +static BundleSyncState get_sync_state_combine_bundle( + const SpaceNode &snode, + const bNode &combine_bundle_node, + const bNodeSocket *src_bundle_socket = nullptr) { BLI_assert(combine_bundle_node.is_type("GeometryNodeCombineBundle")); snode.edittree->ensure_topology_cache(); - const bNodeSocket &bundle_socket = combine_bundle_node.output_socket(0); + if (!src_bundle_socket) { + src_bundle_socket = &combine_bundle_node.output_socket(0); + } bke::ComputeContextCache compute_context_cache; const ComputeContext *current_context = ed::space_node::compute_context_for_edittree_socket( - snode, compute_context_cache, bundle_socket); + snode, compute_context_cache, *src_bundle_socket); const Vector source_signatures = gather_linked_target_bundle_signatures( - current_context, bundle_socket, compute_context_cache); + current_context, *src_bundle_socket, compute_context_cache); if (source_signatures.is_empty()) { return {NodeSyncState::NoSyncSource}; } @@ -107,18 +115,22 @@ static BundleSyncState get_sync_state_combine_bundle(const SpaceNode &snode, return {NodeSyncState::Synced}; } -static ClosureSyncState get_sync_state_closure_output(const SpaceNode &snode, - const bNode &closure_output_node) +static ClosureSyncState get_sync_state_closure_output( + const SpaceNode &snode, + const bNode &closure_output_node, + const bNodeSocket *src_closure_socket = nullptr) { snode.edittree->ensure_topology_cache(); - const bNodeSocket &closure_socket = closure_output_node.output_socket(0); + if (!src_closure_socket) { + src_closure_socket = &closure_output_node.output_socket(0); + } bke::ComputeContextCache compute_context_cache; const ComputeContext *current_context = ed::space_node::compute_context_for_edittree_socket( - snode, compute_context_cache, closure_socket); + snode, compute_context_cache, *src_closure_socket); const Vector source_signatures = gather_linked_target_closure_signatures( - current_context, closure_socket, compute_context_cache); + current_context, *src_closure_socket, compute_context_cache); if (source_signatures.is_empty()) { return {NodeSyncState::NoSyncSource}; } @@ -134,18 +146,22 @@ static ClosureSyncState get_sync_state_closure_output(const SpaceNode &snode, return {NodeSyncState::Synced}; } -static ClosureSyncState get_sync_state_evaluate_closure(const SpaceNode &snode, - const bNode &evaluate_closure_node) +static ClosureSyncState get_sync_state_evaluate_closure( + const SpaceNode &snode, + const bNode &evaluate_closure_node, + const bNodeSocket *src_closure_socket = nullptr) { snode.edittree->ensure_topology_cache(); - const bNodeSocket &closure_socket = evaluate_closure_node.input_socket(0); + if (!src_closure_socket) { + src_closure_socket = &evaluate_closure_node.input_socket(0); + } bke::ComputeContextCache compute_context_cache; const ComputeContext *current_context = ed::space_node::compute_context_for_edittree_socket( - snode, compute_context_cache, closure_socket); + snode, compute_context_cache, *src_closure_socket); const Vector source_signatures = gather_linked_origin_closure_signatures( - current_context, closure_socket, compute_context_cache); + current_context, *src_closure_socket, compute_context_cache); if (source_signatures.is_empty()) { return {NodeSyncState::NoSyncSource}; } @@ -163,9 +179,11 @@ static ClosureSyncState get_sync_state_evaluate_closure(const SpaceNode &snode, void sync_sockets_separate_bundle(SpaceNode &snode, bNode &separate_bundle_node, - ReportList *reports) + ReportList *reports, + const bNodeSocket *src_bundle_socket) { - const BundleSyncState sync_state = get_sync_state_separate_bundle(snode, separate_bundle_node); + const BundleSyncState sync_state = get_sync_state_separate_bundle( + snode, separate_bundle_node, src_bundle_socket); switch (sync_state.state) { case NodeSyncState::Synced: return; @@ -200,9 +218,13 @@ void sync_sockets_separate_bundle(SpaceNode &snode, BKE_ntree_update_tag_node_property(snode.edittree, &separate_bundle_node); } -void sync_sockets_combine_bundle(SpaceNode &snode, bNode &combine_bundle_node, ReportList *reports) +void sync_sockets_combine_bundle(SpaceNode &snode, + bNode &combine_bundle_node, + ReportList *reports, + const bNodeSocket *src_bundle_socket) { - const BundleSyncState sync_state = get_sync_state_combine_bundle(snode, combine_bundle_node); + const BundleSyncState sync_state = get_sync_state_combine_bundle( + snode, combine_bundle_node, src_bundle_socket); switch (sync_state.state) { case NodeSyncState::Synced: return; @@ -240,10 +262,11 @@ void sync_sockets_combine_bundle(SpaceNode &snode, bNode &combine_bundle_node, R void sync_sockets_evaluate_closure(SpaceNode &snode, bNode &evaluate_closure_node, - ReportList *reports) + ReportList *reports, + const bNodeSocket *src_closure_socket) { - const ClosureSyncState sync_state = get_sync_state_evaluate_closure(snode, - evaluate_closure_node); + const ClosureSyncState sync_state = get_sync_state_evaluate_closure( + snode, evaluate_closure_node, src_closure_socket); switch (sync_state.state) { case NodeSyncState::Synced: return; @@ -297,9 +320,11 @@ void sync_sockets_evaluate_closure(SpaceNode &snode, void sync_sockets_closure(SpaceNode &snode, bNode &closure_input_node, bNode &closure_output_node, - ReportList *reports) + ReportList *reports, + const bNodeSocket *src_closure_socket) { - const ClosureSyncState sync_state = get_sync_state_closure_output(snode, closure_output_node); + const ClosureSyncState sync_state = get_sync_state_closure_output( + snode, closure_output_node, src_closure_socket); switch (sync_state.state) { case NodeSyncState::Synced: return; diff --git a/source/blender/nodes/intern/trace_values.cc b/source/blender/nodes/intern/trace_values.cc index b12ae8d8357..7b183a038d0 100644 --- a/source/blender/nodes/intern/trace_values.cc +++ b/source/blender/nodes/intern/trace_values.cc @@ -8,6 +8,7 @@ #include "NOD_geometry_nodes_closure_location.hh" #include "NOD_geometry_nodes_closure_signature.hh" #include "NOD_node_in_compute_context.hh" +#include "NOD_trace_values.hh" #include "BKE_compute_context_cache.hh" #include "BKE_node_tree_zones.hh"