Geometry Nodes: support creating closure with correct interface using link-drag-search
This significantly simplifies creating closures a specific Evaluate Closure node, because one does not have to create all the inputs and outputs manually. Pull Request: https://projects.blender.org/blender/blender/pulls/137687
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
#include "NOD_socket_items_ui.hh"
|
||||
#include "NOD_socket_search_link.hh"
|
||||
|
||||
#include "BKE_compute_context_cache.hh"
|
||||
|
||||
#include "BLO_read_write.hh"
|
||||
|
||||
namespace blender::nodes::node_geo_closure_cc {
|
||||
@@ -182,6 +184,50 @@ static void node_operators()
|
||||
socket_items::ops::make_common_operators<ClosureOutputItemsAccessor>();
|
||||
}
|
||||
|
||||
static void try_initialize_closure_from_evaluator(SpaceNode &snode, bNode &closure_output_node)
|
||||
{
|
||||
snode.edittree->ensure_topology_cache();
|
||||
bNodeSocket &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);
|
||||
if (!current_context) {
|
||||
/* The current tree does not have a known context, e.g. it is pinned but the modifier has been
|
||||
* removed. */
|
||||
return;
|
||||
}
|
||||
const ComputeContext *evaluate_context_generic =
|
||||
ed::space_node::compute_context_for_closure_evaluation(
|
||||
current_context, closure_socket, compute_context_cache, std::nullopt);
|
||||
if (!evaluate_context_generic) {
|
||||
/* No evaluation of the closure found. */
|
||||
return;
|
||||
}
|
||||
const auto *evaluate_context = dynamic_cast<const bke::EvaluateClosureComputeContext *>(
|
||||
evaluate_context_generic);
|
||||
if (!evaluate_context) {
|
||||
return;
|
||||
}
|
||||
const bNode *evaluate_node = evaluate_context->evaluate_node();
|
||||
if (!evaluate_node) {
|
||||
return;
|
||||
}
|
||||
const auto *storage = static_cast<const NodeGeometryEvaluateClosure *>(evaluate_node->storage);
|
||||
|
||||
for (const int i : IndexRange(storage->input_items.items_num)) {
|
||||
const NodeGeometryEvaluateClosureInputItem &evaluate_item = storage->input_items.items[i];
|
||||
socket_items::add_item_with_socket_type_and_name<ClosureInputItemsAccessor>(
|
||||
closure_output_node, eNodeSocketDatatype(evaluate_item.socket_type), evaluate_item.name);
|
||||
}
|
||||
for (const int i : IndexRange(storage->output_items.items_num)) {
|
||||
const NodeGeometryEvaluateClosureOutputItem &evaluate_item = storage->output_items.items[i];
|
||||
socket_items::add_item_with_socket_type_and_name<ClosureOutputItemsAccessor>(
|
||||
closure_output_node, eNodeSocketDatatype(evaluate_item.socket_type), evaluate_item.name);
|
||||
}
|
||||
BKE_ntree_update_tag_node_property(snode.edittree, &closure_output_node);
|
||||
}
|
||||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const bNodeSocket &other_socket = params.other_socket();
|
||||
@@ -200,6 +246,9 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
input_storage.output_node_id = output_node.identifier;
|
||||
|
||||
params.connect_available_socket(output_node, "Closure");
|
||||
|
||||
SpaceNode &snode = *CTX_wm_space_node(¶ms.C);
|
||||
try_initialize_closure_from_evaluator(snode, output_node);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user