Refactor: Nodes: decentralize detecting internal links

Previously, nodes which had their own special internal-links-behavior were
hardcoded in node tree update code. Now that is decentralized so that more nodes
can use this functionality without leaking special cases into general code.

Pull Request: https://projects.blender.org/blender/blender/pulls/138712
This commit is contained in:
Jacques Lucke
2025-05-11 05:23:43 +02:00
parent 19bfe03e54
commit 127719fc87
5 changed files with 39 additions and 13 deletions

View File

@@ -136,6 +136,9 @@ using NodeInverseElemEvalFunction =
void (*)(blender::nodes::value_elem::InverseElemEvalParams &params);
using NodeElemEvalFunction = void (*)(blender::nodes::value_elem::ElemEvalParams &params);
using NodeInverseEvalFunction = void (*)(blender::nodes::inverse_eval::InverseEvalParams &params);
using NodeInternallyLinkedInputFunction = const bNodeSocket *(*)(const bNodeTree &tree,
const bNode &node,
const bNodeSocket &output_socket);
/**
* \brief Defines a socket type.
@@ -365,6 +368,9 @@ struct bNodeType {
/** Get extra information that is drawn next to the node. */
NodeExtraInfoFunction get_extra_info = nullptr;
/** Get the internally linked input socket for the case when the node is muted. */
NodeInternallyLinkedInputFunction internally_linked_input = nullptr;
/**
* "Abstract" evaluation of the node. It tells the caller which parts of the inputs affect which
* parts of the outputs.

View File

@@ -676,7 +676,7 @@ class NodeTreeMainUpdater {
if (output_socket->flag & SOCK_NO_INTERNAL_LINK) {
continue;
}
const bNodeSocket *input_socket = this->find_internally_linked_input(output_socket);
const bNodeSocket *input_socket = this->find_internally_linked_input(ntree, output_socket);
if (input_socket == nullptr) {
continue;
}
@@ -713,22 +713,17 @@ class NodeTreeMainUpdater {
}
}
const bNodeSocket *find_internally_linked_input(const bNodeSocket *output_socket)
const bNodeSocket *find_internally_linked_input(const bNodeTree &ntree,
const bNodeSocket *output_socket)
{
const bNode &node = output_socket->owner_node();
if (node.typeinfo->internally_linked_input) {
return node.typeinfo->internally_linked_input(ntree, node, *output_socket);
}
const bNodeSocket *selected_socket = nullptr;
int selected_priority = -1;
bool selected_is_linked = false;
const bNode &node = output_socket->owner_node();
if (node.is_type("GeometryNodeBake")) {
/* Internal links should always map corresponding input and output sockets. */
return &node.input_by_identifier(output_socket->identifier);
}
if (node.is_type("GeometryNodeCaptureAttribute")) {
return &node.input_socket(output_socket->index());
}
if (node.is_type("GeometryNodeEvaluateClosure")) {
return nodes::evaluate_closure_node_internally_linked_input(*output_socket);
}
for (const bNodeSocket *input_socket : node.input_sockets()) {
if (!input_socket->is_available()) {
continue;

View File

@@ -245,6 +245,13 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
});
}
static const bNodeSocket *node_internally_linked_input(const bNodeTree & /*tree*/,
const bNode &node,
const bNodeSocket &output_socket)
{
return &node.input_socket(output_socket.index());
}
static void node_register()
{
static blender::bke::bNodeType ntype;
@@ -266,6 +273,7 @@ static void node_register()
ntype.draw_buttons_ex = node_layout_ex;
ntype.register_operators = node_operators;
ntype.gather_link_search_ops = node_gather_link_searches;
ntype.internally_linked_input = node_internally_linked_input;
blender::bke::node_register_type(ntype);
}
NOD_REGISTER_NODE(node_register)

View File

@@ -564,6 +564,14 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
});
}
static const bNodeSocket *node_internally_linked_input(const bNodeTree & /*tree*/,
const bNode &node,
const bNodeSocket &output_socket)
{
/* Internal links should always map corresponding input and output sockets. */
return &node.input_by_identifier(output_socket.identifier);
}
static void node_register()
{
static blender::bke::bNodeType ntype;
@@ -580,6 +588,7 @@ static void node_register()
ntype.get_extra_info = node_extra_info;
ntype.register_operators = node_operators;
ntype.gather_link_search_ops = node_gather_link_searches;
ntype.internally_linked_input = node_internally_linked_input;
blender::bke::node_type_storage(ntype, "NodeGeometryBake", node_free_storage, node_copy_storage);
blender::bke::node_register_type(ntype);
}

View File

@@ -100,6 +100,13 @@ static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
}
}
static const bNodeSocket *node_internally_linked_input(const bNodeTree & /*tree*/,
const bNode & /*node*/,
const bNodeSocket &output_socket)
{
return evaluate_closure_node_internally_linked_input(output_socket);
}
static void node_operators()
{
socket_items::ops::make_common_operators<EvaluateClosureInputItemsAccessor>();
@@ -117,6 +124,7 @@ static void node_register()
ntype.initfunc = node_init;
ntype.insert_link = node_insert_link;
ntype.draw_buttons_ex = node_layout_ex;
ntype.internally_linked_input = node_internally_linked_input;
ntype.register_operators = node_operators;
bke::node_type_storage(
ntype, "NodeGeometryEvaluateClosure", node_free_storage, node_copy_storage);