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.
8 changed files with 86 additions and 73 deletions
Showing only changes of commit 132bf55c48 - Show all commits

View File

@ -11,7 +11,6 @@ set(INC_SYS
)
set(SRC
intern/closure.cc
intern/cpp_types.cc
intern/field.cc
intern/field_cpp_type.cc
@ -27,7 +26,6 @@ set(SRC
intern/multi_function_procedure_executor.cc
intern/multi_function_procedure_optimization.cc
FN_closure.hh
FN_field.hh
FN_field_cpp_type.hh
FN_field_cpp_type_make.hh

View File

@ -1,31 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup fn
*/
#include "BLI_cpp_type.hh"
namespace blender::fn {
namespace lazy_function {
class Graph;
}
class Closure {
private:
const lazy_function::Graph *graph_;
public:
Closure() = default;
Closure(const Closure &other) = default;
explicit Closure(const lazy_function::Graph &graph);
~Closure() = default;
Closure &operator=(const Closure &other) = default;
};
} // namespace blender::fn

View File

@ -1,18 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup fn
*/
#include "FN_closure.hh"
#include "FN_lazy_function_graph.hh"
namespace blender::fn {
Closure::Closure(const lf::Graph &graph)
: graph_(&graph)
{
}
} // namespace blender::fn

View File

@ -40,6 +40,7 @@ set(INC
set(SRC
intern/add_node_search.cc
intern/closure.cc
intern/derived_node_tree.cc
intern/geometry_nodes_lazy_function.cc
intern/geometry_nodes_log.cc
@ -56,6 +57,7 @@ set(SRC
intern/socket_search_link.cc
NOD_add_node_search.hh
NOD_closure.hh
NOD_common.h
NOD_composite.h
NOD_derived_node_tree.hh

View File

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup nodes
*/
#include "BLI_cpp_type.hh"
namespace blender::nodes {
struct GeometryNodesLazyFunctionGraphInfo;
class Closure {
private:
const GeometryNodesLazyFunctionGraphInfo *lf_graph_info_;
public:
Closure() = default;
Closure(const Closure &other) = default;
explicit Closure(const GeometryNodesLazyFunctionGraphInfo &lf_graph_info);
~Closure() = default;
Closure &operator=(const Closure &other) = default;
const GeometryNodesLazyFunctionGraphInfo *lf_graph_info() const;
};
} // namespace blender::nodes

View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup fn
*/
#include "NOD_closure.hh"
#include "NOD_geometry_nodes_lazy_function.hh"
namespace blender::nodes {
Closure::Closure(const GeometryNodesLazyFunctionGraphInfo &lf_graph_info)
: lf_graph_info_(&lf_graph_info)
{
}
const GeometryNodesLazyFunctionGraphInfo *Closure::lf_graph_info() const
{
return *lf_graph_info_;
}
} // namespace blender::nodes

View File

@ -13,6 +13,7 @@
* complexity. So far, this does not seem to be a performance issue.
*/
#include "NOD_closure.hh"
#include "NOD_geometry_exec.hh"
#include "NOD_geometry_nodes_lazy_function.hh"
#include "NOD_multi_function.hh"
@ -1158,21 +1159,6 @@ class LazyFunctionForEvaluateFunctionNode : public LazyFunction {
};
public:
/**
* For every input bsocket there is a corresponding boolean output that indicates whether that
* input is used.
*/
Map<int, int> lf_output_for_input_bsocket_usage_;
/**
* For every output bsocket there is a corresponding boolean input that indicates whether the
* output is used.
*/
Map<int, int> lf_input_for_output_bsocket_usage_;
/**
* For every geometry output that can propagate attributes from an input, there is an attribute
* set input. It indicates which attributes should be propagated to the output.
*/
Map<int, int> lf_input_for_attribute_propagation_to_output_;
LazyFunctionForEvaluateFunctionNode(const bNode &eval_node) : eval_node_(eval_node)
{
@ -1186,6 +1172,11 @@ class LazyFunctionForEvaluateFunctionNode : public LazyFunction {
void execute_impl(lf::Params &params, const lf::Context &context) const override
{
const Closure *closure = params.get_input<Closure *>(0);
if (!closure->lf_graph_info()) {
return;
}
const GeometryNodesLazyFunctionGraphInfo &lf_graph_info = *closure->lf_graph_info();
// has_many_nodes_ = lf_graph_info.num_inline_nodes_approximate > 1000;
@ -1193,12 +1184,29 @@ class LazyFunctionForEvaluateFunctionNode : public LazyFunction {
/* Add inputs that also exist on the bnode. */
graph_inputs.extend(lf_graph_info.mapping.group_input_sockets);
/**
* For every input bsocket there is a corresponding boolean output that indicates whether that
* input is used.
*/
Map<int, int> lf_output_for_input_bsocket_usage;
/**
* For every output bsocket there is a corresponding boolean input that indicates whether the
* output is used.
*/
Map<int, int> lf_input_for_output_bsocket_usage;
/**
* For every geometry output that can propagate attributes from an input, there is an attribute
* set input. It indicates which attributes should be propagated to the output.
*/
Map<int, int> lf_input_for_attribute_propagation_to_output;
/* Add a boolean input for every output bsocket that indicates whether that socket is used. */
for (const int i : group_node.output_sockets().index_range()) {
lf_input_for_output_bsocket_usage_.add_new(
//const NodeGeometryEvaluateFunction &node_data = params.
for (const int i : group_node.output_sockets().index_range()) {
lf_input_for_output_bsocket_usage.add_new(
i,
graph_inputs.append_and_get_index(lf_graph_info.mapping.group_output_used_sockets[i]));
inputs_.append_as("Output is Used", CPPType::get<bool>(), lf::ValueUsage::Maybe);
//inputs_.append_as("Output is Used", CPPType::get<bool>(), lf::ValueUsage::Maybe);
}
graph_inputs.extend(lf_graph_info.mapping.group_output_used_sockets);
@ -1209,7 +1217,7 @@ class LazyFunctionForEvaluateFunctionNode : public LazyFunction {
const int lf_index = inputs_.append_and_get_index_as(
"Attribute Set", CPPType::get<bke::AnonymousAttributeSet>(), lf::ValueUsage::Maybe);
graph_inputs.append(lf_socket);
lf_input_for_attribute_propagation_to_output_.add(output_index, lf_index);
lf_input_for_attribute_propagation_to_output.add(output_index, lf_index);
}
Vector<const lf::InputSocket *> graph_outputs;
@ -1220,9 +1228,9 @@ class LazyFunctionForEvaluateFunctionNode : public LazyFunction {
const InputUsageHint &input_usage_hint = lf_graph_info.mapping.group_input_usage_hints[i];
if (input_usage_hint.type == InputUsageHintType::DynamicSocket) {
const lf::InputSocket *lf_socket = lf_graph_info.mapping.group_input_usage_sockets[i];
lf_output_for_input_bsocket_usage_.add_new(i,
lf_output_for_input_bsocket_usage.add_new(i,
graph_outputs.append_and_get_index(lf_socket));
outputs_.append_as("Input is Used", CPPType::get<bool>());
//outputs_.append_as("Input is Used", CPPType::get<bool>());
}
}

View File

@ -30,10 +30,10 @@
#include "MEM_guardedalloc.h"
#include "NOD_closure.hh"
#include "NOD_node_declaration.hh"
#include "NOD_socket.h"
#include "FN_closure.hh"
#include "FN_field.hh"
using namespace blender;