Nodes: Recursively apply usage inference
This patch extends the usage_by_menu method to also consider the usage of the menu socket in the make available and usage inference callbacks. This essentially means that if a socket depends on menu B which, in turn, depends on menu A, it will be sufficiently to check the value of menu B, while A will be checked recursively. The single variant of the usage_by_menu function is now implemented in terms of its overloaded vector variant for code deduplication since the new code increase the size quite a bit. Pull Request: https://projects.blender.org/blender/blender/pulls/146141
This commit is contained in:
@@ -825,7 +825,7 @@ BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::usage_by_single_menu
|
||||
const bNodeSocket &socket = find_single_menu_input(params.node);
|
||||
if (const std::optional<bool> any_output_used = params.any_output_is_used()) {
|
||||
if (!*any_output_used) {
|
||||
/* If no output is used, none if the inputs is used either. */
|
||||
/* If no output is used, none of the inputs is used either. */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -842,16 +842,8 @@ BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::usage_by_single_menu
|
||||
BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::usage_by_menu(
|
||||
const StringRef menu_input_identifier, const int menu_value)
|
||||
{
|
||||
this->make_available([menu_input_identifier, menu_value](bNode &node) {
|
||||
bNodeSocket &socket = *blender::bke::node_find_socket(node, SOCK_IN, menu_input_identifier);
|
||||
bNodeSocketValueMenu *value = socket.default_value_typed<bNodeSocketValueMenu>();
|
||||
value->value = menu_value;
|
||||
});
|
||||
this->usage_inference(
|
||||
[menu_input_identifier, menu_value](
|
||||
const socket_usage_inference::InputSocketUsageParams ¶ms) -> std::optional<bool> {
|
||||
return params.menu_input_may_be(menu_input_identifier, menu_value);
|
||||
});
|
||||
Array<int> menu_values = {menu_value};
|
||||
this->usage_by_menu(menu_input_identifier, menu_values);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -859,20 +851,54 @@ BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::usage_by_menu(
|
||||
const StringRef menu_input_identifier, const Array<int> menu_values)
|
||||
{
|
||||
this->make_available([menu_input_identifier, menu_values](bNode &node) {
|
||||
bNodeSocket &socket = *blender::bke::node_find_socket(node, SOCK_IN, menu_input_identifier);
|
||||
bNodeSocketValueMenu *value = socket.default_value_typed<bNodeSocketValueMenu>();
|
||||
bNodeSocket &menu_socket = *blender::bke::node_find_socket(
|
||||
node, SOCK_IN, menu_input_identifier);
|
||||
const SocketDeclaration &socket_declaration = *menu_socket.runtime->declaration;
|
||||
socket_declaration.make_available(node);
|
||||
bNodeSocketValueMenu *value = menu_socket.default_value_typed<bNodeSocketValueMenu>();
|
||||
value->value = menu_values[0];
|
||||
});
|
||||
this->usage_inference(
|
||||
[menu_input_identifier, menu_values](
|
||||
const socket_usage_inference::InputSocketUsageParams ¶ms) -> std::optional<bool> {
|
||||
for (const int menu_value : menu_values) {
|
||||
const bool might_be = params.menu_input_may_be(menu_input_identifier, menu_value);
|
||||
if (might_be) {
|
||||
return true;
|
||||
if (const std::optional<bool> any_output_used = params.any_output_is_used()) {
|
||||
if (!*any_output_used) {
|
||||
/* If no output is used, none of the inputs is used either. */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
else {
|
||||
/* It's not known if any output is used yet. This function will be called again once new
|
||||
* information about output usages is available. */
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/* Check if the menu might be any of the given values. */
|
||||
bool menu_might_be_any_value = false;
|
||||
for (const int menu_value : menu_values) {
|
||||
menu_might_be_any_value = params.menu_input_may_be(menu_input_identifier, menu_value);
|
||||
if (menu_might_be_any_value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const bNodeSocket &menu_socket = *blender::bke::node_find_socket(
|
||||
params.node, SOCK_IN, menu_input_identifier);
|
||||
const SocketDeclaration &menu_socket_declaration = *menu_socket.runtime->declaration;
|
||||
if (!menu_socket_declaration.usage_inference_fn) {
|
||||
return menu_might_be_any_value;
|
||||
}
|
||||
|
||||
/* If the menu socket has a usage inference function, check if it might be used. */
|
||||
const std::optional<bool> menu_might_be_used =
|
||||
(*menu_socket_declaration.usage_inference_fn)(params);
|
||||
if (!menu_might_be_used.has_value()) {
|
||||
return menu_might_be_any_value;
|
||||
}
|
||||
|
||||
/* The input is only used if the menu might be any of the values and the menu itself is
|
||||
* used. */
|
||||
return *menu_might_be_used && menu_might_be_any_value;
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user