Refactor: Functions: extract user data to separate header
Previously, the `UserData` and `LocalUserData` classes were only supposed to be used by the lazy-function system. However, they are generic enough so that they can also be used by the multi-function system. Therefore, this patch extracts them into a separate header that can be used in both evaluation systems. I'm doing this in preparation for being able to pass the geometry nodes logger to multi-functions, to be able to report errors from there. Pull Request: https://projects.blender.org/blender/blender/pulls/138861
This commit is contained in:
@@ -22,6 +22,7 @@ set(SRC
|
||||
intern/multi_function_procedure_builder.cc
|
||||
intern/multi_function_procedure_executor.cc
|
||||
intern/multi_function_procedure_optimization.cc
|
||||
intern/user_data.cc
|
||||
|
||||
FN_field.hh
|
||||
FN_lazy_function.hh
|
||||
@@ -39,6 +40,7 @@ set(SRC
|
||||
FN_multi_function_procedure_executor.hh
|
||||
FN_multi_function_procedure_optimization.hh
|
||||
FN_multi_function_signature.hh
|
||||
FN_user_data.hh
|
||||
)
|
||||
|
||||
set(LIB
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#include "BLI_linear_allocator.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "FN_user_data.hh"
|
||||
|
||||
#ifndef NDEBUG
|
||||
# include <atomic>
|
||||
# include <thread>
|
||||
@@ -72,33 +74,6 @@ enum class ValueUsage : uint8_t {
|
||||
|
||||
class LazyFunction;
|
||||
|
||||
/**
|
||||
* Extension of #UserData that is thread-local. This avoids accessing e.g.
|
||||
* `EnumerableThreadSpecific.local()` in every nested lazy-function because the thread local
|
||||
* data is passed in by the caller.
|
||||
*/
|
||||
class LocalUserData {
|
||||
public:
|
||||
virtual ~LocalUserData() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* This allows passing arbitrary data into a lazy-function during execution. For that, #UserData
|
||||
* has to be subclassed. This mainly exists because it's more type safe than passing a `void *`
|
||||
* with no type information attached.
|
||||
*
|
||||
* Some lazy-functions may expect to find a certain type of user data when executed.
|
||||
*/
|
||||
class UserData {
|
||||
public:
|
||||
virtual ~UserData() = default;
|
||||
|
||||
/**
|
||||
* Get thread local data for this user-data and the current thread.
|
||||
*/
|
||||
virtual destruct_ptr<LocalUserData> get_local(LinearAllocator<> &allocator);
|
||||
};
|
||||
|
||||
/**
|
||||
* Passed to the lazy-function when it is executed.
|
||||
*/
|
||||
|
||||
38
source/blender/functions/FN_user_data.hh
Normal file
38
source/blender/functions/FN_user_data.hh
Normal file
@@ -0,0 +1,38 @@
|
||||
/* SPDX-FileCopyrightText: 2025 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_linear_allocator.hh"
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
/**
|
||||
* Extension of #UserData that is thread-local. This avoids accessing e.g.
|
||||
* `EnumerableThreadSpecific.local()` in every nested lazy-function because the thread local
|
||||
* data is passed in by the caller.
|
||||
*/
|
||||
class LocalUserData {
|
||||
public:
|
||||
virtual ~LocalUserData() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* This allows passing arbitrary data into a function. For that, #UserData has to be subclassed.
|
||||
* This mainly exists because it's more type safe than passing a `void *` with no type information
|
||||
* attached.
|
||||
*
|
||||
* Some lazy-functions may expect to find a certain type of user data when executed.
|
||||
*/
|
||||
class UserData {
|
||||
public:
|
||||
virtual ~UserData() = default;
|
||||
|
||||
/**
|
||||
* Get thread local data for this user-data and the current thread.
|
||||
*/
|
||||
virtual destruct_ptr<LocalUserData> get_local(LinearAllocator<> &allocator);
|
||||
};
|
||||
|
||||
} // namespace blender::fn
|
||||
@@ -68,9 +68,4 @@ bool Params::try_enable_multi_threading_impl()
|
||||
return false;
|
||||
}
|
||||
|
||||
destruct_ptr<LocalUserData> UserData::get_local(LinearAllocator<> & /*allocator*/)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace blender::fn::lazy_function
|
||||
|
||||
14
source/blender/functions/intern/user_data.cc
Normal file
14
source/blender/functions/intern/user_data.cc
Normal file
@@ -0,0 +1,14 @@
|
||||
/* SPDX-FileCopyrightText: 2025 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "FN_user_data.hh"
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
destruct_ptr<LocalUserData> UserData::get_local(LinearAllocator<> & /*allocator*/)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace blender::fn
|
||||
@@ -261,14 +261,14 @@ class GeoNodeExecParams {
|
||||
|
||||
Main *bmain() const;
|
||||
|
||||
GeoNodesLFUserData *user_data() const
|
||||
GeoNodesUserData *user_data() const
|
||||
{
|
||||
return static_cast<GeoNodesLFUserData *>(lf_context_.user_data);
|
||||
return static_cast<GeoNodesUserData *>(lf_context_.user_data);
|
||||
}
|
||||
|
||||
GeoNodesLFLocalUserData *local_user_data() const
|
||||
GeoNodesLocalUserData *local_user_data() const
|
||||
{
|
||||
return static_cast<GeoNodesLFLocalUserData *>(lf_context_.local_user_data);
|
||||
return static_cast<GeoNodesLocalUserData *>(lf_context_.local_user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,7 +30,7 @@ struct ClosureEagerEvalParams {
|
||||
|
||||
Vector<InputItem> inputs;
|
||||
Vector<OutputItem> outputs;
|
||||
GeoNodesLFUserData *user_data = nullptr;
|
||||
GeoNodesUserData *user_data = nullptr;
|
||||
};
|
||||
|
||||
void evaluate_closure_eagerly(const Closure &closure, ClosureEagerEvalParams ¶ms);
|
||||
|
||||
@@ -259,9 +259,9 @@ struct GeoNodesCallData {
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom user data that is passed to every geometry nodes related lazy-function evaluation.
|
||||
* Custom user data that can be passed to every geometry nodes related evaluation.
|
||||
*/
|
||||
struct GeoNodesLFUserData : public lf::UserData {
|
||||
struct GeoNodesUserData : public fn::UserData {
|
||||
/**
|
||||
* Data provided by the root caller of geometry nodes.
|
||||
*/
|
||||
@@ -276,10 +276,10 @@ struct GeoNodesLFUserData : public lf::UserData {
|
||||
*/
|
||||
bool log_socket_values = true;
|
||||
|
||||
destruct_ptr<lf::LocalUserData> get_local(LinearAllocator<> &allocator) override;
|
||||
destruct_ptr<fn::LocalUserData> get_local(LinearAllocator<> &allocator) override;
|
||||
};
|
||||
|
||||
struct GeoNodesLFLocalUserData : public lf::LocalUserData {
|
||||
struct GeoNodesLocalUserData : public fn::LocalUserData {
|
||||
private:
|
||||
/**
|
||||
* Thread-local logger for the current node tree in the current compute context. It is only
|
||||
@@ -288,13 +288,13 @@ struct GeoNodesLFLocalUserData : public lf::LocalUserData {
|
||||
mutable std::optional<geo_eval_log::GeoTreeLogger *> tree_logger_;
|
||||
|
||||
public:
|
||||
GeoNodesLFLocalUserData(GeoNodesLFUserData & /*user_data*/) {}
|
||||
GeoNodesLocalUserData(GeoNodesUserData & /*user_data*/) {}
|
||||
|
||||
/**
|
||||
* Get the current tree logger. This method is not thread-safe, each thread is supposed to have
|
||||
* a separate logger.
|
||||
*/
|
||||
geo_eval_log::GeoTreeLogger *try_get_tree_logger(const GeoNodesLFUserData &user_data) const
|
||||
geo_eval_log::GeoTreeLogger *try_get_tree_logger(const GeoNodesUserData &user_data) const
|
||||
{
|
||||
if (!tree_logger_.has_value()) {
|
||||
this->ensure_tree_logger(user_data);
|
||||
@@ -303,7 +303,7 @@ struct GeoNodesLFLocalUserData : public lf::LocalUserData {
|
||||
}
|
||||
|
||||
private:
|
||||
void ensure_tree_logger(const GeoNodesLFUserData &user_data) const;
|
||||
void ensure_tree_logger(const GeoNodesUserData &user_data) const;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -468,7 +468,7 @@ struct FoundNestedNodeID {
|
||||
bool is_in_closure = false;
|
||||
};
|
||||
|
||||
std::optional<FoundNestedNodeID> find_nested_node_id(const GeoNodesLFUserData &user_data,
|
||||
std::optional<FoundNestedNodeID> find_nested_node_id(const GeoNodesUserData &user_data,
|
||||
const int node_id);
|
||||
|
||||
/**
|
||||
@@ -497,8 +497,8 @@ class ScopedComputeContextTimer {
|
||||
~ScopedComputeContextTimer()
|
||||
{
|
||||
const geo_eval_log::TimePoint end = geo_eval_log::Clock::now();
|
||||
auto &user_data = static_cast<GeoNodesLFUserData &>(*context_.user_data);
|
||||
auto &local_user_data = static_cast<GeoNodesLFLocalUserData &>(*context_.local_user_data);
|
||||
auto &user_data = static_cast<GeoNodesUserData &>(*context_.user_data);
|
||||
auto &local_user_data = static_cast<GeoNodesLocalUserData &>(*context_.local_user_data);
|
||||
if (geo_eval_log::GeoTreeLogger *tree_logger = local_user_data.try_get_tree_logger(user_data))
|
||||
{
|
||||
tree_logger->execution_time += (end - start_);
|
||||
@@ -524,8 +524,8 @@ class ScopedNodeTimer {
|
||||
~ScopedNodeTimer()
|
||||
{
|
||||
const geo_eval_log::TimePoint end = geo_eval_log::Clock::now();
|
||||
auto &user_data = static_cast<GeoNodesLFUserData &>(*context_.user_data);
|
||||
auto &local_user_data = static_cast<GeoNodesLFLocalUserData &>(*context_.local_user_data);
|
||||
auto &user_data = static_cast<GeoNodesUserData &>(*context_.user_data);
|
||||
auto &local_user_data = static_cast<GeoNodesLocalUserData &>(*context_.local_user_data);
|
||||
if (geo_eval_log::GeoTreeLogger *tree_logger = local_user_data.try_get_tree_logger(user_data))
|
||||
{
|
||||
tree_logger->node_execution_times.append(*tree_logger->allocator,
|
||||
@@ -534,7 +534,7 @@ class ScopedNodeTimer {
|
||||
}
|
||||
};
|
||||
|
||||
bool should_log_socket_values_for_context(const GeoNodesLFUserData &user_data,
|
||||
bool should_log_socket_values_for_context(const GeoNodesUserData &user_data,
|
||||
const ComputeContextHash hash);
|
||||
|
||||
/**
|
||||
|
||||
@@ -235,8 +235,8 @@ class LazyFunctionForBakeNode final : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const final
|
||||
{
|
||||
GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesLFLocalUserData &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(
|
||||
GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
GeoNodesLocalUserData &local_user_data = *static_cast<GeoNodesLocalUserData *>(
|
||||
context.local_user_data);
|
||||
if (!user_data.call_data->self_object()) {
|
||||
/* The self object is currently required for generating anonymous attribute names. */
|
||||
@@ -300,7 +300,7 @@ class LazyFunctionForBakeNode final : public LazyFunction {
|
||||
}
|
||||
|
||||
void pass_through(lf::Params ¶ms,
|
||||
GeoNodesLFUserData &user_data,
|
||||
GeoNodesUserData &user_data,
|
||||
bke::bake::BakeDataBlockMap *data_block_map) const
|
||||
{
|
||||
std::optional<bake::BakeState> bake_state = this->get_bake_state_from_inputs(params,
|
||||
@@ -324,7 +324,7 @@ class LazyFunctionForBakeNode final : public LazyFunction {
|
||||
}
|
||||
|
||||
void store(lf::Params ¶ms,
|
||||
GeoNodesLFUserData &user_data,
|
||||
GeoNodesUserData &user_data,
|
||||
bke::bake::BakeDataBlockMap *data_block_map,
|
||||
const sim_output::StoreNewState &info) const
|
||||
{
|
||||
@@ -339,7 +339,7 @@ class LazyFunctionForBakeNode final : public LazyFunction {
|
||||
}
|
||||
|
||||
void output_cached_state(lf::Params ¶ms,
|
||||
GeoNodesLFUserData &user_data,
|
||||
GeoNodesUserData &user_data,
|
||||
bke::bake::BakeDataBlockMap *data_block_map,
|
||||
const bake::BakeStateRef &bake_state) const
|
||||
{
|
||||
|
||||
@@ -287,8 +287,7 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const final
|
||||
{
|
||||
const GeoNodesLFUserData &user_data = *static_cast<const GeoNodesLFUserData *>(
|
||||
context.user_data);
|
||||
const GeoNodesUserData &user_data = *static_cast<const GeoNodesUserData *>(context.user_data);
|
||||
if (!user_data.call_data->simulation_params) {
|
||||
this->set_default_outputs(params);
|
||||
return;
|
||||
@@ -343,7 +342,7 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
|
||||
}
|
||||
|
||||
void output_simulation_state_copy(lf::Params ¶ms,
|
||||
const GeoNodesLFUserData &user_data,
|
||||
const GeoNodesUserData &user_data,
|
||||
bke::bake::BakeDataBlockMap *data_block_map,
|
||||
const bke::bake::BakeStateRef &zone_state) const
|
||||
{
|
||||
@@ -364,7 +363,7 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
|
||||
}
|
||||
|
||||
void output_simulation_state_move(lf::Params ¶ms,
|
||||
const GeoNodesLFUserData &user_data,
|
||||
const GeoNodesUserData &user_data,
|
||||
bke::bake::BakeDataBlockMap *data_block_map,
|
||||
bke::bake::BakeState zone_state) const
|
||||
{
|
||||
@@ -385,7 +384,7 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
|
||||
}
|
||||
|
||||
void pass_through(lf::Params ¶ms,
|
||||
const GeoNodesLFUserData &user_data,
|
||||
const GeoNodesUserData &user_data,
|
||||
bke::bake::BakeDataBlockMap *data_block_map) const
|
||||
{
|
||||
Array<void *> input_values(inputs_.size());
|
||||
@@ -560,7 +559,7 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const final
|
||||
{
|
||||
GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
if (!user_data.call_data->self_object()) {
|
||||
/* The self object is currently required for generating anonymous attribute names. */
|
||||
this->set_default_outputs(params);
|
||||
@@ -615,7 +614,7 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
|
||||
}
|
||||
|
||||
void output_cached_state(lf::Params ¶ms,
|
||||
GeoNodesLFUserData &user_data,
|
||||
GeoNodesUserData &user_data,
|
||||
bke::bake::BakeDataBlockMap *data_block_map,
|
||||
const bke::bake::BakeStateRef &state) const
|
||||
{
|
||||
@@ -687,7 +686,7 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
|
||||
}
|
||||
|
||||
void pass_through(lf::Params ¶ms,
|
||||
GeoNodesLFUserData &user_data,
|
||||
GeoNodesUserData &user_data,
|
||||
bke::bake::BakeDataBlockMap *data_block_map) const
|
||||
{
|
||||
std::optional<bke::bake::BakeState> bake_state = this->get_bake_state_from_inputs(
|
||||
@@ -714,7 +713,7 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
|
||||
}
|
||||
|
||||
void store_new_state(lf::Params ¶ms,
|
||||
GeoNodesLFUserData &user_data,
|
||||
GeoNodesUserData &user_data,
|
||||
bke::bake::BakeDataBlockMap *data_block_map,
|
||||
const sim_output::StoreNewState &info) const
|
||||
{
|
||||
|
||||
@@ -55,8 +55,8 @@ class LazyFunctionForWarningNode : public LazyFunction {
|
||||
return;
|
||||
}
|
||||
std::string message = message_variant->extract<std::string>();
|
||||
GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesLFLocalUserData &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(
|
||||
GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
GeoNodesLocalUserData &local_user_data = *static_cast<GeoNodesLocalUserData *>(
|
||||
context.local_user_data);
|
||||
if (geo_eval_log::GeoTreeLogger *tree_logger = local_user_data.try_get_tree_logger(user_data))
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ class ClosureIntermediateGraphSideEffectProvider : public lf::GraphExecutorSideE
|
||||
Vector<const lf::FunctionNode *> get_nodes_with_side_effects(
|
||||
const lf::Context &context) const override
|
||||
{
|
||||
const GeoNodesLFUserData &user_data = *dynamic_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
const GeoNodesUserData &user_data = *dynamic_cast<GeoNodesUserData *>(context.user_data);
|
||||
const ComputeContextHash &context_hash = user_data.compute_context->hash();
|
||||
if (!user_data.call_data->side_effect_nodes) {
|
||||
/* There are no requested side effect nodes at all. */
|
||||
@@ -132,7 +132,7 @@ class LazyFunctionForClosureZone : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
|
||||
/* All border links are captured currently. */
|
||||
for (const int i : zone_.border_links.index_range()) {
|
||||
@@ -335,9 +335,9 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
|
||||
{
|
||||
const ScopedNodeTimer node_timer{context, bnode_};
|
||||
|
||||
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
auto &eval_storage = *static_cast<EvaluateClosureEvalStorage *>(context.storage);
|
||||
auto local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
auto local_user_data = *static_cast<GeoNodesLocalUserData *>(context.local_user_data);
|
||||
|
||||
if (!eval_storage.graph_executor) {
|
||||
if (this->is_recursive_call(user_data)) {
|
||||
@@ -376,18 +376,18 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
|
||||
|
||||
bke::EvaluateClosureComputeContext closure_compute_context{
|
||||
user_data.compute_context, bnode_.identifier, &bnode_, closure_source_location};
|
||||
GeoNodesLFUserData closure_user_data = user_data;
|
||||
GeoNodesUserData closure_user_data = user_data;
|
||||
closure_user_data.compute_context = &closure_compute_context;
|
||||
closure_user_data.log_socket_values = should_log_socket_values_for_context(
|
||||
user_data, closure_compute_context.hash());
|
||||
GeoNodesLFLocalUserData closure_local_user_data{closure_user_data};
|
||||
GeoNodesLocalUserData closure_local_user_data{closure_user_data};
|
||||
|
||||
lf::Context eval_graph_context{
|
||||
eval_storage.graph_executor_storage, &closure_user_data, &closure_local_user_data};
|
||||
eval_storage.graph_executor->execute(params, eval_graph_context);
|
||||
}
|
||||
|
||||
bool is_recursive_call(const GeoNodesLFUserData &user_data) const
|
||||
bool is_recursive_call(const GeoNodesUserData &user_data) const
|
||||
{
|
||||
for (const ComputeContext *context = user_data.compute_context; context;
|
||||
context = context->parent())
|
||||
@@ -418,8 +418,8 @@ class LazyFunctionForEvaluateClosureNode : public LazyFunction {
|
||||
const lf::Context &context) const
|
||||
{
|
||||
const auto &node_storage = *static_cast<const NodeGeometryEvaluateClosure *>(bnode_.storage);
|
||||
const auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
const auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
const auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const auto &local_user_data = *static_cast<GeoNodesLocalUserData *>(context.local_user_data);
|
||||
geo_eval_log::GeoTreeLogger *tree_logger = local_user_data.try_get_tree_logger(user_data);
|
||||
if (tree_logger == nullptr) {
|
||||
return;
|
||||
@@ -729,7 +729,7 @@ void evaluate_closure_eagerly(const Closure &closure, ClosureEagerEvalParams &pa
|
||||
ResourceScope scope;
|
||||
LinearAllocator<> &allocator = scope.allocator();
|
||||
|
||||
GeoNodesLFLocalUserData local_user_data(*params.user_data);
|
||||
GeoNodesLocalUserData local_user_data(*params.user_data);
|
||||
void *storage = fn.init_storage(allocator);
|
||||
lf::Context lf_context{storage, params.user_data, &local_user_data};
|
||||
|
||||
|
||||
@@ -844,7 +844,7 @@ bke::GeometrySet execute_geometry_nodes_on_geometry(const bNodeTree &btree,
|
||||
.slice(function.outputs.input_usages)
|
||||
.fill(lf::ValueUsage::Unused);
|
||||
|
||||
GeoNodesLFUserData user_data;
|
||||
GeoNodesUserData user_data;
|
||||
user_data.call_data = &call_data;
|
||||
call_data.root_ntree = &btree;
|
||||
|
||||
@@ -895,7 +895,7 @@ bke::GeometrySet execute_geometry_nodes_on_geometry(const bNodeTree &btree,
|
||||
param_outputs[i] = {type, buffer};
|
||||
}
|
||||
|
||||
GeoNodesLFLocalUserData local_user_data(user_data);
|
||||
GeoNodesLocalUserData local_user_data(user_data);
|
||||
|
||||
lf::Context lf_context(lazy_function.init_storage(allocator), &user_data, &local_user_data);
|
||||
lf::BasicParams lf_params{lazy_function,
|
||||
|
||||
@@ -142,7 +142,7 @@ class ForeachGeometryElementNodeExecuteWrapper : public lf::GraphExecutorNodeExe
|
||||
lf::Params ¶ms,
|
||||
const lf::Context &context) const override
|
||||
{
|
||||
GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const int index = lf_body_nodes_->index_of_try(const_cast<lf::FunctionNode *>(&node));
|
||||
const LazyFunction &fn = node.function();
|
||||
if (index == -1) {
|
||||
@@ -154,12 +154,12 @@ class ForeachGeometryElementNodeExecuteWrapper : public lf::GraphExecutorNodeExe
|
||||
/* Setup context for the loop body evaluation. */
|
||||
bke::ForeachGeometryElementZoneComputeContext body_compute_context{
|
||||
user_data.compute_context, *output_bnode_, index};
|
||||
GeoNodesLFUserData body_user_data = user_data;
|
||||
GeoNodesUserData body_user_data = user_data;
|
||||
body_user_data.compute_context = &body_compute_context;
|
||||
body_user_data.log_socket_values = should_log_socket_values_for_context(
|
||||
user_data, body_compute_context.hash());
|
||||
|
||||
GeoNodesLFLocalUserData body_local_user_data{body_user_data};
|
||||
GeoNodesLocalUserData body_local_user_data{body_user_data};
|
||||
lf::Context body_context{context.storage, &body_user_data, &body_local_user_data};
|
||||
fn.execute(params, body_context);
|
||||
}
|
||||
@@ -177,7 +177,7 @@ class ForeachGeometryElementZoneSideEffectProvider : public lf::GraphExecutorSid
|
||||
Vector<const lf::FunctionNode *> get_nodes_with_side_effects(
|
||||
const lf::Context &context) const override
|
||||
{
|
||||
GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const GeoNodesCallData &call_data = *user_data.call_data;
|
||||
if (!call_data.side_effect_nodes) {
|
||||
return {};
|
||||
@@ -324,8 +324,8 @@ class LazyFunctionForForeachGeometryElementZone : public LazyFunction {
|
||||
{
|
||||
const ScopedNodeTimer node_timer{context, output_bnode_};
|
||||
|
||||
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
auto &local_user_data = *static_cast<GeoNodesLocalUserData *>(context.local_user_data);
|
||||
|
||||
const auto &node_storage = *static_cast<const NodeGeometryForeachGeometryElementOutput *>(
|
||||
output_bnode_.storage);
|
||||
@@ -852,7 +852,7 @@ void LazyFunctionForReduceForeachGeometryElement::execute_impl(lf::Params ¶m
|
||||
void LazyFunctionForReduceForeachGeometryElement::handle_main_items_and_geometry(
|
||||
lf::Params ¶ms, const lf::Context &context) const
|
||||
{
|
||||
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const auto &node_storage = *static_cast<NodeGeometryForeachGeometryElementOutput *>(
|
||||
parent_.output_bnode_.storage);
|
||||
const int body_main_outputs_num = node_storage.main_items.items_num +
|
||||
@@ -999,7 +999,7 @@ void LazyFunctionForReduceForeachGeometryElement::handle_generation_items_group(
|
||||
const int geometry_item_i,
|
||||
const IndexRange generation_items_range) const
|
||||
{
|
||||
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const auto &node_storage = *static_cast<NodeGeometryForeachGeometryElementOutput *>(
|
||||
parent_.output_bnode_.storage);
|
||||
const int body_main_outputs_num = node_storage.main_items.items_num +
|
||||
|
||||
@@ -197,7 +197,7 @@ class LazyFunctionForGeometryNode : public LazyFunction {
|
||||
{
|
||||
const ScopedNodeTimer node_timer{context, node_};
|
||||
|
||||
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData *user_data = dynamic_cast<GeoNodesUserData *>(context.user_data);
|
||||
BLI_assert(user_data != nullptr);
|
||||
|
||||
bool used_non_attribute_output_exists = false;
|
||||
@@ -286,7 +286,7 @@ class LazyFunctionForGeometryNode : public LazyFunction {
|
||||
}
|
||||
|
||||
void output_anonymous_attribute_field(lf::Params ¶ms,
|
||||
const GeoNodesLFUserData &user_data,
|
||||
const GeoNodesUserData &user_data,
|
||||
const int lf_index,
|
||||
const bNodeSocket &socket) const
|
||||
{
|
||||
@@ -303,7 +303,7 @@ class LazyFunctionForGeometryNode : public LazyFunction {
|
||||
params.output_set(lf_index);
|
||||
}
|
||||
|
||||
std::string anonymous_attribute_name_for_output(const GeoNodesLFUserData &user_data,
|
||||
std::string anonymous_attribute_name_for_output(const GeoNodesUserData &user_data,
|
||||
const int output_index) const
|
||||
{
|
||||
return bke::hash_to_anonymous_attribute_name(user_data.call_data->self_object()->id.name,
|
||||
@@ -801,8 +801,8 @@ class LazyFunctionForViewerNode : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
const auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
const auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
const auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const auto &local_user_data = *static_cast<GeoNodesLocalUserData *>(context.local_user_data);
|
||||
geo_eval_log::GeoTreeLogger *tree_logger = local_user_data.try_get_tree_logger(user_data);
|
||||
if (tree_logger == nullptr) {
|
||||
return;
|
||||
@@ -875,7 +875,7 @@ class LazyFunctionForViewerInputUsage : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData *user_data = dynamic_cast<GeoNodesUserData *>(context.user_data);
|
||||
BLI_assert(user_data != nullptr);
|
||||
if (!user_data->call_data->side_effect_nodes) {
|
||||
params.set_output<bool>(0, false);
|
||||
@@ -891,8 +891,7 @@ class LazyFunctionForViewerInputUsage : public LazyFunction {
|
||||
};
|
||||
|
||||
/** Checks if the geometry nodes caller requested this gizmo to be evaluated. */
|
||||
static bool gizmo_is_used(const GeoNodesLFUserData &user_data,
|
||||
const lf::FunctionNode &lf_gizmo_node)
|
||||
static bool gizmo_is_used(const GeoNodesUserData &user_data, const lf::FunctionNode &lf_gizmo_node)
|
||||
{
|
||||
if (!user_data.call_data->side_effect_nodes) {
|
||||
return false;
|
||||
@@ -946,7 +945,7 @@ class LazyFunctionForGizmoNode : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
const auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
const auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
if (!gizmo_is_used(user_data, *this->self_node)) {
|
||||
set_default_remaining_node_outputs(params, bnode_);
|
||||
return;
|
||||
@@ -966,7 +965,7 @@ class LazyFunctionForGizmoNode : public LazyFunction {
|
||||
params.try_get_input_data_ptr_or_request(i);
|
||||
}
|
||||
|
||||
const auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
const auto &local_user_data = *static_cast<GeoNodesLocalUserData *>(context.local_user_data);
|
||||
if (geo_eval_log::GeoTreeLogger *tree_logger = local_user_data.try_get_tree_logger(user_data))
|
||||
{
|
||||
tree_logger->evaluated_gizmo_nodes.append(*tree_logger->allocator, {bnode_.identifier});
|
||||
@@ -988,7 +987,7 @@ class LazyFunctionForGizmoInputsUsage : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
const auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
const auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const bool is_used = gizmo_is_used(user_data, *lf_gizmo_node_);
|
||||
params.set_output(0, is_used);
|
||||
}
|
||||
@@ -1008,7 +1007,7 @@ class LazyFunctionForSimulationInputsUsage : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
const GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
const GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const GeoNodesCallData &call_data = *user_data.call_data;
|
||||
if (!call_data.simulation_params) {
|
||||
this->set_default_outputs(params);
|
||||
@@ -1064,7 +1063,7 @@ class LazyFunctionForBakeInputsUsage : public LazyFunction {
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
const GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
const GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
if (!user_data.call_data->bake_params) {
|
||||
this->set_default_outputs(params);
|
||||
return;
|
||||
@@ -1095,7 +1094,7 @@ class LazyFunctionForBakeInputsUsage : public LazyFunction {
|
||||
}
|
||||
};
|
||||
|
||||
bool should_log_socket_values_for_context(const GeoNodesLFUserData &user_data,
|
||||
bool should_log_socket_values_for_context(const GeoNodesUserData &user_data,
|
||||
const ComputeContextHash hash)
|
||||
{
|
||||
if (const Set<ComputeContextHash> *contexts = user_data.call_data->socket_log_contexts) {
|
||||
@@ -1163,7 +1162,7 @@ class LazyFunctionForGroupNode : public LazyFunction {
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
const ScopedNodeTimer node_timer{context, group_node_};
|
||||
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData *user_data = dynamic_cast<GeoNodesUserData *>(context.user_data);
|
||||
BLI_assert(user_data != nullptr);
|
||||
|
||||
if (has_many_nodes_) {
|
||||
@@ -1181,12 +1180,12 @@ class LazyFunctionForGroupNode : public LazyFunction {
|
||||
storage->context_hash_cache};
|
||||
storage->context_hash_cache = compute_context.hash();
|
||||
|
||||
GeoNodesLFUserData group_user_data = *user_data;
|
||||
GeoNodesUserData group_user_data = *user_data;
|
||||
group_user_data.compute_context = &compute_context;
|
||||
group_user_data.log_socket_values = should_log_socket_values_for_context(
|
||||
*user_data, compute_context.hash());
|
||||
|
||||
GeoNodesLFLocalUserData group_local_user_data{group_user_data};
|
||||
GeoNodesLocalUserData group_local_user_data{group_user_data};
|
||||
lf::Context group_context{storage->group_storage, &group_user_data, &group_local_user_data};
|
||||
|
||||
ScopedComputeContextTimer timer(group_context);
|
||||
@@ -1503,17 +1502,17 @@ class LazyFunctionForSimulationZone : public LazyFunction {
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
|
||||
{
|
||||
ScopedNodeTimer node_timer{context, sim_output_bnode_};
|
||||
GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
|
||||
bke::SimulationZoneComputeContext compute_context{user_data.compute_context,
|
||||
sim_output_bnode_};
|
||||
|
||||
GeoNodesLFUserData zone_user_data = user_data;
|
||||
GeoNodesUserData zone_user_data = user_data;
|
||||
zone_user_data.compute_context = &compute_context;
|
||||
zone_user_data.log_socket_values = should_log_socket_values_for_context(
|
||||
user_data, compute_context.hash());
|
||||
|
||||
GeoNodesLFLocalUserData zone_local_user_data{zone_user_data};
|
||||
GeoNodesLocalUserData zone_local_user_data{zone_user_data};
|
||||
lf::Context zone_context{context.storage, &zone_user_data, &zone_local_user_data};
|
||||
fn_.execute(params, zone_context);
|
||||
}
|
||||
@@ -1708,11 +1707,11 @@ class GeometryNodesLazyFunctionLogger : public lf::GraphExecutor::Logger {
|
||||
const GPointer value,
|
||||
const lf::Context &context) const override
|
||||
{
|
||||
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
if (!user_data.log_socket_values) {
|
||||
return;
|
||||
}
|
||||
auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
auto &local_user_data = *static_cast<GeoNodesLocalUserData *>(context.local_user_data);
|
||||
geo_eval_log::GeoTreeLogger *tree_logger = local_user_data.try_get_tree_logger(user_data);
|
||||
if (tree_logger == nullptr) {
|
||||
return;
|
||||
@@ -1746,7 +1745,7 @@ class GeometryNodesLazyFunctionLogger : public lf::GraphExecutor::Logger {
|
||||
{
|
||||
std::lock_guard lock{dump_error_context_mutex};
|
||||
|
||||
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData *user_data = dynamic_cast<GeoNodesUserData *>(context.user_data);
|
||||
BLI_assert(user_data != nullptr);
|
||||
user_data->compute_context->print_stack(std::cout, node.name());
|
||||
std::cout << "Missing outputs:\n";
|
||||
@@ -1765,7 +1764,7 @@ class GeometryNodesLazyFunctionLogger : public lf::GraphExecutor::Logger {
|
||||
ss << from_socket.node().name() << ":" << from_socket.name() << " -> "
|
||||
<< target_socket.node().name() << ":" << target_socket.name();
|
||||
|
||||
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData *user_data = dynamic_cast<GeoNodesUserData *>(context.user_data);
|
||||
BLI_assert(user_data != nullptr);
|
||||
user_data->compute_context->print_stack(std::cout, ss.str());
|
||||
}
|
||||
@@ -1786,8 +1785,8 @@ class GeometryNodesLazyFunctionLogger : public lf::GraphExecutor::Logger {
|
||||
static thread_local const int thread_id = thread_id_source.fetch_add(1);
|
||||
static thread_local const std::string thread_id_str = "Thread: " + std::to_string(thread_id);
|
||||
|
||||
const auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
const auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
const auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const auto &local_user_data = *static_cast<GeoNodesLocalUserData *>(context.local_user_data);
|
||||
geo_eval_log::GeoTreeLogger *tree_logger = local_user_data.try_get_tree_logger(user_data);
|
||||
if (tree_logger == nullptr) {
|
||||
return;
|
||||
@@ -1835,7 +1834,7 @@ class GeometryNodesLazyFunctionSideEffectProvider : public lf::GraphExecutor::Si
|
||||
Vector<const lf::FunctionNode *> get_nodes_with_side_effects(
|
||||
const lf::Context &context) const override
|
||||
{
|
||||
GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData *user_data = dynamic_cast<GeoNodesUserData *>(context.user_data);
|
||||
BLI_assert(user_data != nullptr);
|
||||
const GeoNodesCallData &call_data = *user_data->call_data;
|
||||
if (!call_data.side_effect_nodes) {
|
||||
@@ -4186,12 +4185,12 @@ const GeometryNodesLazyFunctionGraphInfo *ensure_geometry_nodes_lazy_function_gr
|
||||
return lf_graph_info_ptr.get();
|
||||
}
|
||||
|
||||
destruct_ptr<lf::LocalUserData> GeoNodesLFUserData::get_local(LinearAllocator<> &allocator)
|
||||
destruct_ptr<fn::LocalUserData> GeoNodesUserData::get_local(LinearAllocator<> &allocator)
|
||||
{
|
||||
return allocator.construct<GeoNodesLFLocalUserData>(*this);
|
||||
return allocator.construct<GeoNodesLocalUserData>(*this);
|
||||
}
|
||||
|
||||
void GeoNodesLFLocalUserData::ensure_tree_logger(const GeoNodesLFUserData &user_data) const
|
||||
void GeoNodesLocalUserData::ensure_tree_logger(const GeoNodesUserData &user_data) const
|
||||
{
|
||||
if (geo_eval_log::GeoModifierLog *log = user_data.call_data->eval_log) {
|
||||
tree_logger_.emplace(&log->get_local_tree_logger(*user_data.compute_context));
|
||||
@@ -4200,7 +4199,7 @@ void GeoNodesLFLocalUserData::ensure_tree_logger(const GeoNodesLFUserData &user_
|
||||
this->tree_logger_.emplace(nullptr);
|
||||
}
|
||||
|
||||
std::optional<FoundNestedNodeID> find_nested_node_id(const GeoNodesLFUserData &user_data,
|
||||
std::optional<FoundNestedNodeID> find_nested_node_id(const GeoNodesUserData &user_data,
|
||||
const int node_id)
|
||||
{
|
||||
FoundNestedNodeID found;
|
||||
|
||||
@@ -37,7 +37,7 @@ class RepeatBodyNodeExecuteWrapper : public lf::GraphExecutorNodeExecuteWrapper
|
||||
lf::Params ¶ms,
|
||||
const lf::Context &context) const override
|
||||
{
|
||||
GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const int iteration = lf_body_nodes_->index_of_try(const_cast<lf::FunctionNode *>(&node));
|
||||
const LazyFunction &fn = node.function();
|
||||
if (iteration == -1) {
|
||||
@@ -49,12 +49,12 @@ class RepeatBodyNodeExecuteWrapper : public lf::GraphExecutorNodeExecuteWrapper
|
||||
/* Setup context for the loop body evaluation. */
|
||||
bke::RepeatZoneComputeContext body_compute_context{
|
||||
user_data.compute_context, *repeat_output_bnode_, iteration};
|
||||
GeoNodesLFUserData body_user_data = user_data;
|
||||
GeoNodesUserData body_user_data = user_data;
|
||||
body_user_data.compute_context = &body_compute_context;
|
||||
body_user_data.log_socket_values = should_log_socket_values_for_context(
|
||||
user_data, body_compute_context.hash());
|
||||
|
||||
GeoNodesLFLocalUserData body_local_user_data{body_user_data};
|
||||
GeoNodesLocalUserData body_local_user_data{body_user_data};
|
||||
lf::Context body_context{context.storage, &body_user_data, &body_local_user_data};
|
||||
fn.execute(params, body_context);
|
||||
}
|
||||
@@ -71,7 +71,7 @@ class RepeatZoneSideEffectProvider : public lf::GraphExecutorSideEffectProvider
|
||||
Vector<const lf::FunctionNode *> get_nodes_with_side_effects(
|
||||
const lf::Context &context) const override
|
||||
{
|
||||
GeoNodesLFUserData &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
GeoNodesUserData &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
const GeoNodesCallData &call_data = *user_data.call_data;
|
||||
if (!call_data.side_effect_nodes) {
|
||||
return {};
|
||||
@@ -150,8 +150,8 @@ class LazyFunctionForRepeatZone : public LazyFunction {
|
||||
{
|
||||
const ScopedNodeTimer node_timer{context, repeat_output_bnode_};
|
||||
|
||||
auto &user_data = *static_cast<GeoNodesLFUserData *>(context.user_data);
|
||||
auto &local_user_data = *static_cast<GeoNodesLFLocalUserData *>(context.local_user_data);
|
||||
auto &user_data = *static_cast<GeoNodesUserData *>(context.user_data);
|
||||
auto &local_user_data = *static_cast<GeoNodesLocalUserData *>(context.local_user_data);
|
||||
|
||||
const NodeGeometryRepeatOutput &node_storage = *static_cast<const NodeGeometryRepeatOutput *>(
|
||||
repeat_output_bnode_.storage);
|
||||
@@ -191,8 +191,8 @@ class LazyFunctionForRepeatZone : public LazyFunction {
|
||||
void initialize_execution_graph(lf::Params ¶ms,
|
||||
RepeatEvalStorage &eval_storage,
|
||||
const NodeGeometryRepeatOutput &node_storage,
|
||||
GeoNodesLFUserData &user_data,
|
||||
GeoNodesLFLocalUserData &local_user_data) const
|
||||
GeoNodesUserData &user_data,
|
||||
GeoNodesLocalUserData &local_user_data) const
|
||||
{
|
||||
const int num_repeat_items = node_storage.items_num;
|
||||
const int num_border_links = body_fn_.indices.inputs.border_links.size();
|
||||
|
||||
Reference in New Issue
Block a user