Geometry Nodes: simplify bake state api

This introduces `BakeState` and `BakeStateRef` to replace
the use of `Map<int, BakeItem pointer>` in various places.
This commit is contained in:
Jacques Lucke 2023-09-01 11:23:53 +02:00
parent f3a5d28e7e
commit da8ad3c2b6
11 changed files with 109 additions and 122 deletions

View File

@ -19,6 +19,22 @@ class BakeItem {
virtual ~BakeItem() = default;
};
struct BakeState {
/**
* The ids are usually correspond to socket ids, so that the mapping stays intact even if socket
* order changes.
*/
Map<int, std::unique_ptr<BakeItem>> items_by_id;
};
/** Same as above, but does not own the bake items. */
struct BakeStateRef {
Map<int, const BakeItem *> items_by_id;
BakeStateRef() = default;
BakeStateRef(const BakeState &bake_state);
};
class GeometryBakeItem : public BakeItem {
public:
GeometrySet geometry;

View File

@ -150,16 +150,13 @@ std::unique_ptr<BakeItem> deserialize_bake_item(const io::serialize::DictionaryV
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing);
void serialize_bake(const Map<int, const BakeItem *> &items_by_id,
BDataWriter &bdata_writer,
BDataSharing &bdata_sharing,
std::ostream &r_stream);
void serialize_bake(const Map<int, std::unique_ptr<BakeItem>> &items_by_id,
void serialize_bake(const BakeState &bake_state,
BDataWriter &bdata_writer,
BDataSharing &bdata_sharing,
std::ostream &r_stream);
std::optional<Map<int, std::unique_ptr<BakeItem>>> deserialize_bake(
std::istream &stream, const BDataReader &bdata_reader, const BDataSharing &bdata_sharing);
std::optional<BakeState> deserialize_bake(std::istream &stream,
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing);
} // namespace blender::bke

View File

@ -31,13 +31,13 @@ enum class CacheState {
struct SimulationZoneFrameCache {
SubFrame frame;
Map<int, std::unique_ptr<BakeItem>> items;
BakeState state;
/** Used when the baked data is loaded lazily. */
std::optional<std::string> meta_path;
};
struct SimulationZonePrevState {
Map<int, std::unique_ptr<BakeItem>> items;
BakeState state;
SubFrame frame;
};

View File

@ -73,4 +73,12 @@ PrimitiveBakeItem::~PrimitiveBakeItem()
StringBakeItem::StringBakeItem(std::string value) : value_(std::move(value)) {}
BakeStateRef::BakeStateRef(const BakeState &bake_state)
{
this->items_by_id.reserve(bake_state.items_by_id.size());
for (auto item : bake_state.items_by_id.items()) {
this->items_by_id.add_new(item.key, item.value.get());
}
}
} // namespace blender::bke

View File

@ -1066,7 +1066,7 @@ std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io_item,
static constexpr int bake_file_version = 3;
void serialize_bake(const Map<int, const BakeItem *> &items_by_id,
void serialize_bake(const BakeState &bake_state,
BDataWriter &bdata_writer,
BDataSharing &bdata_sharing,
std::ostream &r_stream)
@ -1074,7 +1074,7 @@ void serialize_bake(const Map<int, const BakeItem *> &items_by_id,
io::serialize::DictionaryValue io_root;
io_root.append_int("version", bake_file_version);
io::serialize::DictionaryValue &io_items = *io_root.append_dict("items");
for (auto item : items_by_id.items()) {
for (auto item : bake_state.items_by_id.items()) {
io::serialize::DictionaryValue &io_item = *io_items.append_dict(std::to_string(item.key));
bke::serialize_bake_item(*item.value, bdata_writer, bdata_sharing, io_item);
}
@ -1083,21 +1083,9 @@ void serialize_bake(const Map<int, const BakeItem *> &items_by_id,
formatter.serialize(r_stream, io_root);
}
void serialize_bake(const Map<int, std::unique_ptr<BakeItem>> &items_by_id,
BDataWriter &bdata_writer,
BDataSharing &bdata_sharing,
std::ostream &r_stream)
{
Map<int, const BakeItem *> map;
map.reserve(items_by_id.size());
for (auto item : items_by_id.items()) {
map.add_new(item.key, item.value.get());
}
serialize_bake(map, bdata_writer, bdata_sharing, r_stream);
}
std::optional<Map<int, std::unique_ptr<BakeItem>>> deserialize_bake(
std::istream &stream, const BDataReader &bdata_reader, const BDataSharing &bdata_sharing)
std::optional<BakeState> deserialize_bake(std::istream &stream,
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing)
{
JsonFormatter formatter;
std::unique_ptr<io::serialize::Value> io_root_value = formatter.deserialize(stream);
@ -1116,7 +1104,7 @@ std::optional<Map<int, std::unique_ptr<BakeItem>>> deserialize_bake(
if (!io_items) {
return std::nullopt;
}
Map<int, std::unique_ptr<BakeItem>> bake_items;
BakeState bake_state;
for (const auto &io_item_value : io_items->elements()) {
const io::serialize::DictionaryValue *io_item = io_item_value.second->as_dictionary_value();
if (!io_item) {
@ -1129,7 +1117,7 @@ std::optional<Map<int, std::unique_ptr<BakeItem>>> deserialize_bake(
catch (...) {
return std::nullopt;
}
if (bake_items.contains(id)) {
if (bake_state.items_by_id.contains(id)) {
return std::nullopt;
}
std::unique_ptr<BakeItem> bake_item = deserialize_bake_item(
@ -1137,9 +1125,9 @@ std::optional<Map<int, std::unique_ptr<BakeItem>>> deserialize_bake(
if (!bake_item) {
return std::nullopt;
}
bake_items.add_new(id, std::move(bake_item));
bake_state.items_by_id.add_new(id, std::move(bake_item));
}
return bake_items;
return bake_state;
}
} // namespace blender::bke

View File

@ -360,7 +360,7 @@ static void bake_simulation_job_startjob(void *customdata,
bke::DiskBDataWriter bdata_writer{bdata_file_name, bdata_file, 0};
fstream meta_file{meta_path, std::ios::out};
bke::serialize_bake(
frame_cache.items, bdata_writer, *zone_bake_data.bdata_sharing, meta_file);
frame_cache.state, bdata_writer, *zone_bake_data.bdata_sharing, meta_file);
}
}
}

View File

@ -811,7 +811,7 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
zone_cache.cache_state = CacheState::Invalid;
}
output_copy_info.delta_time = delta_frames / fps_;
output_copy_info.items_by_id = this->to_readonly_items_map(prev_frame_cache.items);
output_copy_info.state = prev_frame_cache.state;
this->output_store_frame_cache(zone_cache, zone_behavior);
return;
}
@ -828,7 +828,7 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
max_delta_frames, float(zone_cache.prev_state->frame) - float(current_frame_));
auto &output_move_info = zone_behavior.input.emplace<sim_input::OutputMove>();
output_move_info.delta_time = delta_frames / fps_;
output_move_info.items_by_id = std::move(zone_cache.prev_state->items);
output_move_info.state = std::move(zone_cache.prev_state->state);
this->store_as_prev_items(zone_cache, zone_behavior);
return;
}
@ -836,9 +836,9 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
/* Just read from the previous state if the frame has not changed. */
auto &output_copy_info = zone_behavior.input.emplace<sim_input::OutputCopy>();
output_copy_info.delta_time = 0.0f;
output_copy_info.items_by_id = this->to_readonly_items_map(zone_cache.prev_state->items);
output_copy_info.state = zone_cache.prev_state->state;
auto &read_single_info = zone_behavior.output.emplace<sim_output::ReadSingle>();
read_single_info.items_by_id = this->to_readonly_items_map(zone_cache.prev_state->items);
read_single_info.state = zone_cache.prev_state->state;
return;
}
if (!depsgraph_is_active_) {
@ -900,16 +900,15 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
{
auto &store_and_pass_through_info =
zone_behavior.output.emplace<sim_output::StoreAndPassThrough>();
store_and_pass_through_info.store_fn =
[simulation_cache = simulation_cache_,
zone_cache = &zone_cache,
current_frame = current_frame_](Map<int, std::unique_ptr<bke::BakeItem>> items) {
std::lock_guard lock{simulation_cache->mutex};
auto frame_cache = std::make_unique<bke::sim::SimulationZoneFrameCache>();
frame_cache->frame = current_frame;
frame_cache->items = std::move(items);
zone_cache->frame_caches.append(std::move(frame_cache));
};
store_and_pass_through_info.store_fn = [simulation_cache = simulation_cache_,
zone_cache = &zone_cache,
current_frame = current_frame_](bke::BakeState state) {
std::lock_guard lock{simulation_cache->mutex};
auto frame_cache = std::make_unique<bke::sim::SimulationZoneFrameCache>();
frame_cache->frame = current_frame;
frame_cache->state = std::move(state);
zone_cache->frame_caches.append(std::move(frame_cache));
};
}
void store_as_prev_items(bke::sim::SimulationZoneCache &zone_cache,
@ -917,17 +916,16 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
{
auto &store_and_pass_through_info =
zone_behavior.output.emplace<sim_output::StoreAndPassThrough>();
store_and_pass_through_info.store_fn =
[simulation_cache = simulation_cache_,
zone_cache = &zone_cache,
current_frame = current_frame_](Map<int, std::unique_ptr<bke::BakeItem>> items) {
std::lock_guard lock{simulation_cache->mutex};
if (!zone_cache->prev_state) {
zone_cache->prev_state.emplace();
}
zone_cache->prev_state->items = std::move(items);
zone_cache->prev_state->frame = current_frame;
};
store_and_pass_through_info.store_fn = [simulation_cache = simulation_cache_,
zone_cache = &zone_cache,
current_frame = current_frame_](bke::BakeState state) {
std::lock_guard lock{simulation_cache->mutex};
if (!zone_cache->prev_state) {
zone_cache->prev_state.emplace();
}
zone_cache->prev_state->state = std::move(state);
zone_cache->prev_state->frame = current_frame;
};
}
void read_from_cache(const FrameIndices &frame_indices,
@ -941,9 +939,7 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
const float delta_frames = std::min(max_delta_frames,
float(current_frame_) - float(frame_cache.frame));
output_copy_info.delta_time = delta_frames / fps_;
for (auto item : frame_cache.items.items()) {
output_copy_info.items_by_id.add_new(item.key, item.value.get());
}
output_copy_info.state = frame_cache.state;
}
else {
zone_behavior.input.emplace<sim_input::PassThrough>();
@ -980,7 +976,7 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
bke::sim::SimulationZoneFrameCache &frame_cache = *zone_cache.frame_caches[frame_index];
this->ensure_bake_loaded(zone_cache, frame_cache);
auto &read_single_info = zone_behavior.output.emplace<sim_output::ReadSingle>();
read_single_info.items_by_id = this->to_readonly_items_map(frame_cache.items);
read_single_info.state = frame_cache.state;
}
void read_interpolated(const int prev_frame_index,
@ -998,24 +994,14 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
read_interpolated_info.mix_factor = (float(current_frame_) - float(prev_frame_cache.frame)) /
(float(next_frame_cache.frame) -
float(prev_frame_cache.frame));
read_interpolated_info.prev_items_by_id = this->to_readonly_items_map(prev_frame_cache.items);
read_interpolated_info.next_items_by_id = this->to_readonly_items_map(next_frame_cache.items);
}
Map<int, const bke::BakeItem *> to_readonly_items_map(
const Map<int, std::unique_ptr<bke::BakeItem>> &items) const
{
Map<int, const bke::BakeItem *> map;
for (auto item : items.items()) {
map.add_new(item.key, item.value.get());
}
return map;
read_interpolated_info.prev_state = prev_frame_cache.state;
read_interpolated_info.next_state = next_frame_cache.state;
}
void ensure_bake_loaded(bke::sim::SimulationZoneCache &zone_cache,
bke::sim::SimulationZoneFrameCache &frame_cache) const
{
if (!frame_cache.items.is_empty()) {
if (!frame_cache.state.items_by_id.is_empty()) {
return;
}
if (!zone_cache.bdata_dir) {
@ -1026,12 +1012,12 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
}
bke::DiskBDataReader bdata_reader{*zone_cache.bdata_dir};
fstream meta_file{*frame_cache.meta_path};
std::optional<Map<int, std::unique_ptr<bke::BakeItem>>> bake_items = bke::deserialize_bake(
std::optional<bke::BakeState> bake_state = bke::deserialize_bake(
meta_file, bdata_reader, *zone_cache.bdata_sharing);
if (!bake_items.has_value()) {
if (!bake_state.has_value()) {
return;
}
frame_cache.items = std::move(*bake_items);
frame_cache.state = std::move(*bake_state);
}
};

View File

@ -57,7 +57,7 @@ struct PassThrough {
*/
struct OutputCopy {
float delta_time;
Map<int, const bke::BakeItem *> items_by_id;
bke::BakeStateRef state;
};
/**
@ -66,7 +66,7 @@ struct OutputCopy {
*/
struct OutputMove {
float delta_time;
Map<int, std::unique_ptr<bke::BakeItem>> items_by_id;
bke::BakeState state;
};
using Behavior = std::variant<PassThrough, OutputCopy, OutputMove>;
@ -88,14 +88,14 @@ struct PassThrough {
* This allows the caller of geometry nodes (e.g. the modifier), to cache the new simulation state.
*/
struct StoreAndPassThrough {
std::function<void(Map<int, std::unique_ptr<bke::BakeItem>> items_by_id)> store_fn;
std::function<void(bke::BakeState state)> store_fn;
};
/**
* The inputs are not evaluated, instead the given cached items are output directly.
*/
struct ReadSingle {
Map<int, const bke::BakeItem *> items_by_id;
bke::BakeStateRef state;
};
/**
@ -104,8 +104,8 @@ struct ReadSingle {
struct ReadInterpolated {
/** Factor between 0 and 1 that determines the influence of the two simulation states. */
float mix_factor;
Map<int, const bke::BakeItem *> prev_items_by_id;
Map<int, const bke::BakeItem *> next_items_by_id;
bke::BakeStateRef prev_state;
bke::BakeStateRef next_state;
};
using Behavior = std::variant<PassThrough, StoreAndPassThrough, ReadSingle, ReadInterpolated>;

View File

@ -137,16 +137,16 @@ void socket_declarations_for_simulation_items(Span<NodeSimulationItem> items,
const CPPType &get_simulation_item_cpp_type(eNodeSocketDatatype socket_type);
const CPPType &get_simulation_item_cpp_type(const NodeSimulationItem &item);
Map<int, std::unique_ptr<bke::BakeItem>> move_values_to_simulation_state(
bke::BakeState move_values_to_simulation_state(
const Span<NodeSimulationItem> node_simulation_items, const Span<void *> input_values);
void move_simulation_state_to_values(const Span<NodeSimulationItem> node_simulation_items,
Map<int, std::unique_ptr<bke::BakeItem>> zone_state,
bke::BakeState zone_state,
const Object &self_object,
const ComputeContext &compute_context,
const bNode &sim_output_node,
Span<void *> r_output_values);
void copy_simulation_state_to_values(const Span<NodeSimulationItem> node_simulation_items,
const Map<int, const bke::BakeItem *> &zone_state,
const bke::BakeStateRef &zone_state,
const Object &self_object,
const ComputeContext &compute_context,
const bNode &sim_output_node,

View File

@ -86,11 +86,11 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
float delta_time = 0.0f;
if (auto *info = std::get_if<sim_input::OutputCopy>(&input_behavior)) {
delta_time = info->delta_time;
this->output_simulation_state_copy(params, user_data, info->items_by_id);
this->output_simulation_state_copy(params, user_data, info->state);
}
else if (auto *info = std::get_if<sim_input::OutputMove>(&input_behavior)) {
delta_time = info->delta_time;
this->output_simulation_state_move(params, user_data, std::move(info->items_by_id));
this->output_simulation_state_move(params, user_data, std::move(info->state));
}
else if (std::get_if<sim_input::PassThrough>(&input_behavior)) {
delta_time = 0.0f;
@ -106,14 +106,14 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
void output_simulation_state_copy(lf::Params &params,
const GeoNodesLFUserData &user_data,
const Map<int, const bke::BakeItem *> &zone_state) const
const bke::BakeStateRef &zone_state) const
{
Array<void *> outputs(simulation_items_.size());
for (const int i : simulation_items_.index_range()) {
outputs[i] = params.get_output_data_ptr(i + 1);
}
copy_simulation_state_to_values(simulation_items_,
std::move(zone_state),
zone_state,
*user_data.modifier_data->self_object,
*user_data.compute_context,
node_,
@ -125,7 +125,7 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
void output_simulation_state_move(lf::Params &params,
const GeoNodesLFUserData &user_data,
Map<int, std::unique_ptr<bke::BakeItem>> zone_state) const
bke::BakeState zone_state) const
{
Array<void *> outputs(simulation_items_.size());
for (const int i : simulation_items_.index_range()) {
@ -155,9 +155,8 @@ class LazyFunctionForSimulationInputNode final : public LazyFunction {
/* Instead of outputting the initial values directly, convert them to a simulation state and
* then back. This ensures that some geometry processing happens on the data consistently (e.g.
* removing anonymous attributes). */
Map<int, std::unique_ptr<bke::BakeItem>> bake_items = move_values_to_simulation_state(
simulation_items_, input_values);
this->output_simulation_state_move(params, user_data, std::move(bake_items));
bke::BakeState bake_state = move_values_to_simulation_state(simulation_items_, input_values);
this->output_simulation_state_move(params, user_data, std::move(bake_state));
}
};

View File

@ -185,7 +185,7 @@ static std::shared_ptr<AnonymousAttributeFieldInput> make_attribute_field(
}
void move_simulation_state_to_values(const Span<NodeSimulationItem> node_simulation_items,
Map<int, std::unique_ptr<bke::BakeItem>> zone_state,
bke::BakeState zone_state,
const Object &self_object,
const ComputeContext &compute_context,
const bNode &node,
@ -194,7 +194,7 @@ void move_simulation_state_to_values(const Span<NodeSimulationItem> node_simulat
const bke::BakeSocketConfig config = make_bake_socket_config(node_simulation_items);
Vector<bke::BakeItem *> bake_items;
for (const NodeSimulationItem &item : node_simulation_items) {
auto *bake_item = zone_state.lookup_ptr(item.identifier);
auto *bake_item = zone_state.items_by_id.lookup_ptr(item.identifier);
bake_items.append(bake_item ? bake_item->get() : nullptr);
}
@ -209,7 +209,7 @@ void move_simulation_state_to_values(const Span<NodeSimulationItem> node_simulat
}
void copy_simulation_state_to_values(const Span<NodeSimulationItem> node_simulation_items,
const Map<int, const bke::BakeItem *> &zone_state,
const bke::BakeStateRef &zone_state,
const Object &self_object,
const ComputeContext &compute_context,
const bNode &node,
@ -218,7 +218,7 @@ void copy_simulation_state_to_values(const Span<NodeSimulationItem> node_simulat
const bke::BakeSocketConfig config = make_bake_socket_config(node_simulation_items);
Vector<const bke::BakeItem *> bake_items;
for (const NodeSimulationItem &item : node_simulation_items) {
const bke::BakeItem *const *bake_item = zone_state.lookup_ptr(item.identifier);
const bke::BakeItem *const *bake_item = zone_state.items_by_id.lookup_ptr(item.identifier);
bake_items.append(bake_item ? *bake_item : nullptr);
}
@ -232,7 +232,7 @@ void copy_simulation_state_to_values(const Span<NodeSimulationItem> node_simulat
r_output_values);
}
Map<int, std::unique_ptr<bke::BakeItem>> move_values_to_simulation_state(
bke::BakeState move_values_to_simulation_state(
const Span<NodeSimulationItem> node_simulation_items, const Span<void *> input_values)
{
const bke::BakeSocketConfig config = make_bake_socket_config(node_simulation_items);
@ -240,15 +240,15 @@ Map<int, std::unique_ptr<bke::BakeItem>> move_values_to_simulation_state(
Array<std::unique_ptr<bke::BakeItem>> bake_items = bke::move_socket_values_to_bake_items(
input_values, config);
Map<int, std::unique_ptr<bke::BakeItem>> bake_items_map;
bke::BakeState bake_state;
for (const int i : node_simulation_items.index_range()) {
const NodeSimulationItem &item = node_simulation_items[i];
std::unique_ptr<bke::BakeItem> &bake_item = bake_items[i];
if (bake_item) {
bake_items_map.add_new(item.identifier, std::move(bake_item));
bake_state.items_by_id.add_new(item.identifier, std::move(bake_item));
}
}
return bake_items_map;
return bake_state;
}
} // namespace blender::nodes
@ -567,14 +567,14 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
}
sim_output::Behavior &output_behavior = zone_behavior->output;
if (auto *info = std::get_if<sim_output::ReadSingle>(&output_behavior)) {
this->output_cached_state(params, user_data, info->items_by_id);
this->output_cached_state(params, user_data, info->state);
}
else if (auto *info = std::get_if<sim_output::ReadInterpolated>(&output_behavior)) {
this->output_mixed_cached_state(params,
*modifier_data.self_object,
*user_data.compute_context,
info->prev_items_by_id,
info->next_items_by_id,
info->prev_state,
info->next_state,
info->mix_factor);
}
else if (std::get_if<sim_output::PassThrough>(&output_behavior)) {
@ -590,7 +590,7 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
void output_cached_state(lf::Params &params,
GeoNodesLFUserData &user_data,
const Map<int, const bke::BakeItem *> &state) const
const bke::BakeStateRef &state) const
{
Array<void *> output_values(simulation_items_.size());
for (const int i : simulation_items_.index_range()) {
@ -610,8 +610,8 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
void output_mixed_cached_state(lf::Params &params,
const Object &self_object,
const ComputeContext &compute_context,
const Map<int, const bke::BakeItem *> &prev_state,
const Map<int, const bke::BakeItem *> &next_state,
const bke::BakeStateRef &prev_state,
const bke::BakeStateRef &next_state,
const float mix_factor) const
{
Array<void *> output_values(simulation_items_.size());
@ -649,9 +649,8 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
/* Instead of outputting the initial values directly, convert them to a simulation state and
* then back. This ensures that some geometry processing happens on the data consistently (e.g.
* removing anonymous attributes). */
std::optional<Map<int, std::unique_ptr<bke::BakeItem>>> bake_items =
this->get_bake_items_from_inputs(params);
if (!bake_items) {
std::optional<bke::BakeState> bake_state = this->get_bake_state_from_inputs(params);
if (!bake_state) {
/* Wait for inputs to be computed. */
return;
}
@ -661,7 +660,7 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
output_values[i] = params.get_output_data_ptr(i);
}
move_simulation_state_to_values(simulation_items_,
std::move(*bake_items),
std::move(*bake_state),
*user_data.modifier_data->self_object,
*user_data.compute_context,
node_,
@ -675,22 +674,16 @@ class LazyFunctionForSimulationOutputNode final : public LazyFunction {
GeoNodesLFUserData &user_data,
const sim_output::StoreAndPassThrough &info) const
{
std::optional<Map<int, std::unique_ptr<bke::BakeItem>>> bake_items =
this->get_bake_items_from_inputs(params);
if (!bake_items) {
std::optional<bke::BakeState> bake_state = this->get_bake_state_from_inputs(params);
if (!bake_state) {
/* Wait for inputs to be computed. */
return;
}
Map<int, const bke::BakeItem *> bake_item_pointers;
for (const auto item : bake_items->items()) {
bake_item_pointers.add_new(item.key, item.value.get());
}
this->output_cached_state(params, user_data, bake_item_pointers);
info.store_fn(std::move(*bake_items));
this->output_cached_state(params, user_data, *bake_state);
info.store_fn(std::move(*bake_state));
}
std::optional<Map<int, std::unique_ptr<bke::BakeItem>>> get_bake_items_from_inputs(
lf::Params &params) const
std::optional<bke::BakeState> get_bake_state_from_inputs(lf::Params &params) const
{
Array<void *> input_values(inputs_.size());
for (const int i : inputs_.index_range()) {