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:
parent
f3a5d28e7e
commit
da8ad3c2b6
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ¶ms,
|
||||
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 ¶ms,
|
||||
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));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 ¶ms,
|
||||
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 ¶ms,
|
||||
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 ¶ms) const
|
||||
std::optional<bke::BakeState> get_bake_state_from_inputs(lf::Params ¶ms) const
|
||||
{
|
||||
Array<void *> input_values(inputs_.size());
|
||||
for (const int i : inputs_.index_range()) {
|
||||
|
|
Loading…
Reference in New Issue