Simulation Nodes: bake simulation states to disk #106937

Merged
Jacques Lucke merged 116 commits from JacquesLucke/blender:sim-bake into geometry-nodes-simulation 2023-04-22 14:48:56 +02:00
3 changed files with 46 additions and 29 deletions
Showing only changes of commit 5bee640698 - Show all commits

View File

@ -48,16 +48,18 @@ class BDataSharing {
/** The #ImplicitSharingInfo pointer is a weak user. */
Map<const ImplicitSharingInfo *, StoredByRuntimeValue> stored_by_runtime_;
Map<std::string, SharingInfoWithData> runtime_by_stored_;
/* TODO: Protect by mutex. */
mutable Map<std::string, SharingInfoWithData> runtime_by_stored_;
public:
~BDataSharing();
DictionaryValuePtr write_shared(const ImplicitSharingInfo *sharing_info,
FunctionRef<DictionaryValuePtr()> write_fn);
[[nodiscard]] DictionaryValuePtr write_shared(const ImplicitSharingInfo *sharing_info,
FunctionRef<DictionaryValuePtr()> write_fn);
SharingInfoWithData read_shared(const DictionaryValue &io_data,
FunctionRef<SharingInfoWithData()> read_fn);
[[nodiscard]] std::optional<SharingInfoWithData> read_shared(
const DictionaryValue &io_data,
FunctionRef<std::optional<SharingInfoWithData>()> read_fn) const;
};
class DiskBDataReader : public BDataReader {
@ -91,6 +93,7 @@ void serialize_modifier_simulation_state(const ModifierSimulationState &state,
DictionaryValue &r_io_root);
void deserialize_modifier_simulation_state(const DictionaryValue &io_root,
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing,
ModifierSimulationState &r_state);
} // namespace blender::bke::sim

View File

@ -73,8 +73,9 @@ void ModifierSimulationState::ensure_bake_loaded() const
}
const DiskBDataReader bdata_reader{*bdata_dir_};
const BDataSharing bdata_sharing;
deserialize_modifier_simulation_state(
*io_root, bdata_reader, const_cast<ModifierSimulationState &>(*this));
*io_root, bdata_reader, bdata_sharing, const_cast<ModifierSimulationState &>(*this));
bake_loaded_ = true;
}

View File

@ -290,7 +290,8 @@ template<typename T>
static void load_attributes(const io::serialize::ArrayValue &io_attributes,
bke::MutableAttributeAccessor &attributes,
const BDataReader &bdata_reader)
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing)
{
for (const auto &io_attribute_value : io_attributes.elements()) {
const auto *io_attribute = io_attribute_value->as_dictionary_value();
@ -314,6 +315,7 @@ static void load_attributes(const io::serialize::ArrayValue &io_attributes,
continue;
}
const CPPType &cpp_type = attribute.span.type();
if (!read_bdata_simple_gspan(bdata_reader, *io_data, attribute.span)) {
cpp_type.value_initialize_n(attribute.span.data(), attribute.span.size());
}
@ -323,7 +325,8 @@ static void load_attributes(const io::serialize::ArrayValue &io_attributes,
}
static PointCloud *try_load_pointcloud(const io::serialize::DictionaryValue &io_geometry,
const BDataReader &bdata_reader)
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing)
{
const io::serialize::DictionaryValue *io_pointcloud = io_geometry.lookup_dict("pointcloud");
if (!io_pointcloud) {
@ -336,12 +339,13 @@ static PointCloud *try_load_pointcloud(const io::serialize::DictionaryValue &io_
}
PointCloud *pointcloud = BKE_pointcloud_new_nomain(num_points);
bke::MutableAttributeAccessor attributes = pointcloud->attributes_for_write();
load_attributes(*io_attributes, attributes, bdata_reader);
load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing);
return pointcloud;
}
static Curves *try_load_curves(const io::serialize::DictionaryValue &io_geometry,
const BDataReader &bdata_reader)
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing)
{
const io::serialize::DictionaryValue *io_curves = io_geometry.lookup_dict("curves");
if (!io_curves) {
@ -374,13 +378,14 @@ static Curves *try_load_curves(const io::serialize::DictionaryValue &io_geometry
}
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
load_attributes(*io_attributes, attributes, bdata_reader);
load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing);
return curves_id;
}
static Mesh *try_load_mesh(const io::serialize::DictionaryValue &io_geometry,
const BDataReader &bdata_reader)
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing)
{
const io::serialize::DictionaryValue *io_mesh = io_geometry.lookup_dict("mesh");
if (!io_mesh) {
@ -414,16 +419,18 @@ static Mesh *try_load_mesh(const io::serialize::DictionaryValue &io_geometry,
}
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
load_attributes(*io_attributes, attributes, bdata_reader);
load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing);
return mesh;
}
static GeometrySet load_geometry(const io::serialize::DictionaryValue &io_geometry,
const BDataReader &bdata_reader);
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing);
static bke::Instances *try_load_instances(const io::serialize::DictionaryValue &io_geometry,
HooglyBoogly marked this conversation as resolved Outdated

It's probably worth creating empty curves first, then assigning the offsets, to avoid allocating them and then freeing them.

This could be a TODO comment too I guess

It's probably worth creating empty curves first, then assigning the offsets, to avoid allocating them and then freeing them. This could be a TODO comment too I guess
const BDataReader &bdata_reader)
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing)
{
const io::serialize::DictionaryValue *io_instances = io_geometry.lookup_dict("instances");
if (!io_instances) {
@ -454,7 +461,7 @@ static bke::Instances *try_load_instances(const io::serialize::DictionaryValue &
const io::serialize::DictionaryValue *io_reference = io_reference_value->as_dictionary_value();
GeometrySet reference_geometry;
if (io_reference) {
reference_geometry = load_geometry(*io_reference, bdata_reader);
reference_geometry = load_geometry(*io_reference, bdata_reader, bdata_sharing);
}
instances->add_reference(std::move(reference_geometry));
}
@ -476,25 +483,26 @@ static bke::Instances *try_load_instances(const io::serialize::DictionaryValue &
}
bke::MutableAttributeAccessor attributes = instances->attributes_for_write();
load_attributes(*io_attributes, attributes, bdata_reader);
load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing);
return instances;
}
static GeometrySet load_geometry(const io::serialize::DictionaryValue &io_geometry,
const BDataReader &bdata_reader)
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing)
{
GeometrySet geometry;
if (Mesh *mesh = try_load_mesh(io_geometry, bdata_reader)) {
if (Mesh *mesh = try_load_mesh(io_geometry, bdata_reader, bdata_sharing)) {
geometry.replace_mesh(mesh);
}
if (PointCloud *pointcloud = try_load_pointcloud(io_geometry, bdata_reader)) {
if (PointCloud *pointcloud = try_load_pointcloud(io_geometry, bdata_reader, bdata_sharing)) {
geometry.replace_pointcloud(pointcloud);
}
if (Curves *curves = try_load_curves(io_geometry, bdata_reader)) {
if (Curves *curves = try_load_curves(io_geometry, bdata_reader, bdata_sharing)) {
geometry.replace_curves(curves);
}
if (bke::Instances *instances = try_load_instances(io_geometry, bdata_reader)) {
if (bke::Instances *instances = try_load_instances(io_geometry, bdata_reader, bdata_sharing)) {
geometry.replace_instances(instances);
}
return geometry;
@ -685,6 +693,7 @@ void serialize_modifier_simulation_state(const ModifierSimulationState &state,
void deserialize_modifier_simulation_state(const io::serialize::DictionaryValue &io_root,
const BDataReader &bdata_reader,
const BDataSharing &bdata_sharing,
ModifierSimulationState &r_state)
{
io::serialize::JsonFormatter formatter;
@ -736,7 +745,7 @@ void deserialize_modifier_simulation_state(const io::serialize::DictionaryValue
if (!io_geometry) {
continue;
}
GeometrySet geometry = load_geometry(*io_geometry, bdata_reader);
GeometrySet geometry = load_geometry(*io_geometry, bdata_reader, bdata_sharing);
auto state_item = std::make_unique<bke::sim::GeometrySimulationStateItem>(
std::move(geometry));
zone_state->items.append(std::move(state_item));
@ -819,8 +828,9 @@ DictionaryValuePtr BDataSharing::write_shared(const ImplicitSharingInfo *sharing
});
}
BDataSharing::SharingInfoWithData BDataSharing::read_shared(
const DictionaryValue &io_data, FunctionRef<SharingInfoWithData()> read_fn)
std::optional<BDataSharing::SharingInfoWithData> BDataSharing::read_shared(
const DictionaryValue &io_data,
FunctionRef<std::optional<SharingInfoWithData>()> read_fn) const
{
io::serialize::JsonFormatter formatter;
std::stringstream ss;
@ -831,10 +841,13 @@ BDataSharing::SharingInfoWithData BDataSharing::read_shared(
shared_data->sharing_info->add_user();
return *shared_data;
}
SharingInfoWithData data = read_fn();
if (data.sharing_info != nullptr) {
data.sharing_info->add_user();
runtime_by_stored_.add_new(key, data);
std::optional<SharingInfoWithData> data = read_fn();
if (!data) {
return std::nullopt;
}
if (data->sharing_info != nullptr) {
data->sharing_info->add_user();
runtime_by_stored_.add_new(key, *data);
}
return data;
}