WIP: Closures and deferred evaluation for geometry nodes #107842

Draft
Lukas Tönne wants to merge 35 commits from LukasTonne/blender:geometry-nodes-closures into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
5 changed files with 73 additions and 14 deletions
Showing only changes of commit 5cf33e914d - Show all commits

View File

@ -8,19 +8,20 @@
#include "BLI_cpp_type.hh"
#include "FN_lazy_function.hh"
#include "FN_lazy_function_graph_executor.hh"
namespace blender::fn {
namespace lazy_function {
class Graph;
}
class Closure {
private:
std::shared_ptr<lf::GraphExecutor> function_;
const lazy_function::Graph *graph_;
public:
Closure() = default;
Closure(const Closure &other) = default;
explicit Closure(const lf::GraphExecutor &function);
explicit Closure(const lazy_function::Graph &graph);
~Closure() = default;
Closure &operator=(const Closure &other) = default;

View File

@ -6,10 +6,12 @@
#include "FN_closure.hh"
#include "FN_lazy_function_graph.hh"
namespace blender::fn {
Closure::Closure(const lf::GraphExecutor &function)
: function_(std::make_shared<lf::GraphExecutor>(function))
Closure::Closure(const lf::Graph &graph)
: graph_(&graph)
{
}

View File

@ -4,6 +4,9 @@
#include "BKE_node_runtime.hh"
#include "FN_closure.hh"
#include "FN_lazy_function_graph.hh"
#include "UI_interface.h"
#include "UI_resources.h"
@ -51,15 +54,17 @@ static void node_layout(uiLayout *layout, bContext *C, PointerRNA *ptr)
static void node_geo_exec(GeoNodeExecParams params)
{
//GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
if (params.node().id) {
const bNodeTree &bind_tree = *reinterpret_cast<bNodeTree *>(params.node().id);
const std::unique_ptr<GeometryNodesLazyFunctionGraphInfo> &lf_graph_info_ptr =
bind_tree.runtime->geometry_nodes_lazy_function_graph_info;
BLI_assert(lf_graph_info_ptr);
//const NodeGeometryCurveFill &storage = node_storage(params.node());
//const GeometryNodeCurveFillMode mode = (GeometryNodeCurveFillMode)storage.mode;
fn::Closure closure(lf_graph_info_ptr->graph);
params.set_output("Function", std::move(closure));
}
//geometry_set.modify_geometry_sets(
// [&](GeometrySet &geometry_set) { curve_fill_calculate(geometry_set, mode); });
//params.set_output("Mesh", std::move(geometry_set));
params.set_default_remaining_outputs();
}
} // namespace blender::nodes::node_geo_bind_function_cc

View File

@ -4,6 +4,8 @@
#include "BLI_math_vector.h"
#include "BLI_string.h"
#include "FN_closure.hh"
#include "RNA_enum_types.h"
#include "UI_interface.h"

View File

@ -1507,6 +1507,10 @@ struct GeometryNodesLazyFunctionGraphBuilder {
this->handle_switch_node(*bnode);
break;
}
case GEO_NODE_BIND_FUNCTION: {
this->handle_bind_function_node(*bnode);
break;
}
default: {
if (node_type->geometry_node_execute) {
this->handle_geometry_node(*bnode);
@ -1805,6 +1809,51 @@ struct GeometryNodesLazyFunctionGraphBuilder {
}
}
void handle_bind_function_node(const bNode &bnode)
{
const bNodeTree *group_btree = reinterpret_cast<bNodeTree *>(bnode.id);
if (group_btree == nullptr) {
return;
}
const GeometryNodesLazyFunctionGraphInfo *group_lf_graph_info =
ensure_geometry_nodes_lazy_function_graph(*group_btree);
if (group_lf_graph_info == nullptr) {
return;
}
//auto lazy_function = std::make_unique<LazyFunctionForGroupNode>(bnode, *group_lf_graph_info);
//lf::FunctionNode &lf_node = lf_graph_->add_function(*lazy_function);
//for (const int i : bnode.input_sockets().index_range()) {
// const bNodeSocket &bsocket = bnode.input_socket(i);
// BLI_assert(!bsocket.is_multi_input());
// lf::InputSocket &lf_socket = lf_node.input(i);
// input_socket_map_.add(&bsocket, &lf_socket);
// mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket);
//}
//for (const int i : bnode.output_sockets().index_range()) {
// const bNodeSocket &bsocket = bnode.output_socket(i);
// lf::OutputSocket &lf_socket = lf_node.output(i);
// output_socket_map_.add_new(&bsocket, &lf_socket);
// mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket);
//}
//mapping_->group_node_map.add(&bnode, &lf_node);
//lf_graph_info_->num_inline_nodes_approximate +=
// group_lf_graph_info->num_inline_nodes_approximate;
//static const bool static_false = false;
//for (const int i : lazy_function->lf_input_for_output_bsocket_usage_.values()) {
// lf_node.input(i).set_default_value(&static_false);
// socket_usage_inputs_.add(&lf_node.input(i));
//}
///* Keep track of attribute set inputs that need to be populated later. */
//for (const auto [output_index, lf_input_index] :
// lazy_function->lf_input_for_attribute_propagation_to_output_.items()) {
// attribute_set_propagation_map_.add(&bnode.output_socket(output_index),
// &lf_node.input(lf_input_index));
//}
//lf_graph_info_->functions.append(std::move(lazy_function));
}
void handle_undefined_node(const bNode &bnode)
{
auto lazy_function = std::make_unique<LazyFunctionForUndefinedNode>(