Geometry Nodes: support creating Evaluate Closure node based on closure
Similar to #140187. This allows creating an Evaluate Closure node with the right signature for an existing closure when using link-drag-search. Pull Request: https://projects.blender.org/blender/blender/pulls/140191
This commit is contained in:
@@ -130,6 +130,14 @@ bool node_editor_is_for_geometry_nodes_modifier(const SpaceNode &snode,
|
||||
bke::ComputeContextCache &compute_context_cache,
|
||||
const std::optional<nodes::ClosureSourceLocation> &source_location);
|
||||
|
||||
/**
|
||||
* Finds closure output nodes that are linked to the given closure socket.
|
||||
*/
|
||||
Vector<const bNode *> gather_linked_closure_origin_nodes(
|
||||
const ComputeContext *closure_socket_context,
|
||||
const bNodeSocket &closure_socket,
|
||||
bke::ComputeContextCache &compute_context_cache);
|
||||
|
||||
Vector<const bNode *> gather_linked_separate_bundle_nodes(
|
||||
const ComputeContext *bundle_socket_context,
|
||||
const bNodeSocket &bundle_socket,
|
||||
|
||||
@@ -773,6 +773,24 @@ static Vector<nodes::SocketInContext> find_origin_sockets_through_contexts(
|
||||
return found_origins.extract_vector();
|
||||
}
|
||||
|
||||
Vector<const bNode *> gather_linked_closure_origin_nodes(
|
||||
const ComputeContext *closure_socket_context,
|
||||
const bNodeSocket &closure_socket,
|
||||
bke::ComputeContextCache &compute_context_cache)
|
||||
{
|
||||
const Vector<nodes::SocketInContext> origin_sockets = find_origin_sockets_through_contexts(
|
||||
{closure_socket_context, &closure_socket},
|
||||
compute_context_cache,
|
||||
"GeometryNodeClosureOutput",
|
||||
true);
|
||||
Vector<const bNode *> closure_origin_nodes;
|
||||
for (const nodes::SocketInContext &origin_socket : origin_sockets) {
|
||||
const nodes::NodeInContext &origin_node = origin_socket.owner_node();
|
||||
closure_origin_nodes.append(origin_node.node);
|
||||
}
|
||||
return closure_origin_nodes;
|
||||
}
|
||||
|
||||
Vector<const bNode *> gather_linked_combine_bundle_nodes(
|
||||
const ComputeContext *bundle_socket_context,
|
||||
const bNodeSocket &bundle_socket,
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
#include "UI_interface.hh"
|
||||
#include "UI_resources.hh"
|
||||
|
||||
#include "BKE_compute_context_cache.hh"
|
||||
|
||||
#include "NOD_geo_closure.hh"
|
||||
#include "NOD_socket_items_blend.hh"
|
||||
#include "NOD_socket_items_ops.hh"
|
||||
#include "NOD_socket_items_ui.hh"
|
||||
#include "NOD_socket_search_link.hh"
|
||||
|
||||
#include "BLO_read_write.hh"
|
||||
|
||||
@@ -117,6 +120,62 @@ static const bNodeSocket *node_internally_linked_input(const bNodeTree & /*tree*
|
||||
return evaluate_closure_node_internally_linked_input(output_socket);
|
||||
}
|
||||
|
||||
static void try_initialize_evaluate_closure_node_from_origin_socket(SpaceNode &snode,
|
||||
bNode &evaluate_closure_node)
|
||||
{
|
||||
snode.edittree->ensure_topology_cache();
|
||||
bNodeSocket &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);
|
||||
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 Vector<const bNode *> closure_origin_nodes =
|
||||
ed::space_node::gather_linked_closure_origin_nodes(
|
||||
current_context, closure_socket, compute_context_cache);
|
||||
if (closure_origin_nodes.is_empty()) {
|
||||
return;
|
||||
}
|
||||
const bNode &closure_node = *closure_origin_nodes[0];
|
||||
const NodeGeometryClosureOutput &closure_storage =
|
||||
*static_cast<const NodeGeometryClosureOutput *>(closure_node.storage);
|
||||
|
||||
for (const int i : IndexRange(closure_storage.input_items.items_num)) {
|
||||
const NodeGeometryClosureInputItem &item = closure_storage.input_items.items[i];
|
||||
socket_items::add_item_with_socket_type_and_name<EvaluateClosureInputItemsAccessor>(
|
||||
evaluate_closure_node, eNodeSocketDatatype(item.socket_type), item.name);
|
||||
}
|
||||
for (const int i : IndexRange(closure_storage.output_items.items_num)) {
|
||||
const NodeGeometryClosureOutputItem &item = closure_storage.output_items.items[i];
|
||||
socket_items::add_item_with_socket_type_and_name<EvaluateClosureOutputItemsAccessor>(
|
||||
evaluate_closure_node, eNodeSocketDatatype(item.socket_type), item.name);
|
||||
}
|
||||
BKE_ntree_update_tag_node_property(snode.edittree, &evaluate_closure_node);
|
||||
}
|
||||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const bNodeSocket &other_socket = params.other_socket();
|
||||
if (other_socket.type != SOCK_CLOSURE) {
|
||||
return;
|
||||
}
|
||||
if (other_socket.in_out == SOCK_IN) {
|
||||
return;
|
||||
}
|
||||
|
||||
params.add_item("Closure", [](LinkSearchOpParams ¶ms) {
|
||||
bNode &node = params.add_node("GeometryNodeEvaluateClosure");
|
||||
params.connect_available_socket(node, "Closure");
|
||||
|
||||
SpaceNode &snode = *CTX_wm_space_node(¶ms.C);
|
||||
try_initialize_evaluate_closure_node_from_origin_socket(snode, node);
|
||||
});
|
||||
}
|
||||
|
||||
static void node_operators()
|
||||
{
|
||||
socket_items::ops::make_common_operators<EvaluateClosureInputItemsAccessor>();
|
||||
@@ -147,6 +206,7 @@ static void node_register()
|
||||
ntype.insert_link = node_insert_link;
|
||||
ntype.draw_buttons_ex = node_layout_ex;
|
||||
ntype.internally_linked_input = node_internally_linked_input;
|
||||
ntype.gather_link_search_ops = node_gather_link_searches;
|
||||
ntype.register_operators = node_operators;
|
||||
ntype.blend_write_storage_content = node_blend_write;
|
||||
ntype.blend_data_read_storage_content = node_blend_read;
|
||||
|
||||
Reference in New Issue
Block a user