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 44 deletions
Showing only changes of commit 9858f253b5 - Show all commits

View File

@ -29,9 +29,17 @@ class BDataReader {
class BDataWriter {
public:
virtual BDataSlice write(const void *data, int64_t size) = 0;
};
virtual DictionaryValuePtr write_shared(const ImplicitSharingInfo *sharing_info,
FunctionRef<DictionaryValuePtr()> write_fn) = 0;
class BDataSharing {
private:
Map<const ImplicitSharingInfo *, DictionaryValuePtr> map_;
public:
~BDataSharing();
DictionaryValuePtr write_shared(const ImplicitSharingInfo *sharing_info,
FunctionRef<DictionaryValuePtr()> write_fn);
};
class DiskBDataReader : public BDataReader {
@ -48,19 +56,11 @@ class DiskBDataWriter : public BDataWriter {
std::string bdata_name_;
std::ostream &bdata_file_;
int64_t current_offset_;
Map<const ImplicitSharingInfo *, DictionaryValuePtr> &shared_data_;
public:
DiskBDataWriter(std::string bdata_name,
std::ostream &bdata_file,
int64_t current_offset,
Map<const ImplicitSharingInfo *, std::shared_ptr<io::serialize::DictionaryValue>>
&shared_data);
DiskBDataWriter(std::string bdata_name, std::ostream &bdata_file, int64_t current_offset);
BDataSlice write(const void *data, int64_t size) override;
DictionaryValuePtr write_shared(const ImplicitSharingInfo *sharing_info,
FunctionRef<DictionaryValuePtr()> write_fn) override;
};
std::string get_bake_directory(const Main &bmain, const Object &object, const ModifierData &md);
@ -69,6 +69,7 @@ std::string get_meta_directory(const Main &bmain, const Object &object, const Mo

A couple more words after "Identifier" could help the reader figure out the type of this value, something like "Identifier file name"

A couple more words after "Identifier" could help the reader figure out the type of this value, something like "Identifier file name"
void serialize_modifier_simulation_state(const ModifierSimulationState &state,
BDataWriter &bdata_writer,
BDataSharing &bdata_sharing,
DictionaryValue &r_io_root);
void deserialize_modifier_simulation_state(const DictionaryValue &io_root,
const BDataReader &bdata_reader,
HooglyBoogly marked this conversation as resolved Outdated

Simpler wording suggestion:

Map used to detect when some data has already been written. It keeps a weak reference to #ImplicitSharingInfo, allowing it to check for equality of two arrays just by comparing the sharing info's pointer and version.

Simpler wording suggestion: >Map used to detect when some data has already been written. It keeps a weak reference to #ImplicitSharingInfo, allowing it to check for equality of two arrays just by comparing the sharing info's pointer and version.

View File

@ -522,6 +522,7 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_material_slots(
static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
const bke::AttributeAccessor &attributes,
BDataWriter &bdata_writer,
BDataSharing &bdata_sharing,
const Set<std::string> &attributes_to_ignore)
{
auto io_attributes = std::make_shared<io::serialize::ArrayValue>();
@ -543,7 +544,7 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
const bke::GAttributeReader attribute = attributes.lookup(attribute_id);
const GVArraySpan attribute_span(attribute.varray);
io_attribute->append("data", bdata_writer.write_shared(attribute.sharing_info, [&]() {
io_attribute->append("data", bdata_sharing.write_shared(attribute.sharing_info, [&]() {
return write_bdata_simple_gspan(bdata_writer, attribute_span);
}));
@ -553,7 +554,7 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
}
static std::shared_ptr<io::serialize::DictionaryValue> serialize_geometry_set(
const GeometrySet &geometry, BDataWriter &bdata_writer)
const GeometrySet &geometry, BDataWriter &bdata_writer, BDataSharing &bdata_sharing)
{
auto io_geometry = std::make_shared<io::serialize::DictionaryValue>();
if (geometry.has_mesh()) {
@ -567,7 +568,7 @@ static std::shared_ptr<io::serialize::DictionaryValue> serialize_geometry_set(
if (mesh.totpoly > 0) {
io_mesh->append("poly_offsets",
bdata_writer.write_shared(mesh.runtime->poly_offsets_sharing_info, [&]() {
bdata_sharing.write_shared(mesh.runtime->poly_offsets_sharing_info, [&]() {
return write_bdata_int_array(bdata_writer, mesh.poly_offsets());
}));
}
@ -575,7 +576,7 @@ static std::shared_ptr<io::serialize::DictionaryValue> serialize_geometry_set(
auto io_materials = serialize_material_slots({mesh.mat, mesh.totcol});
io_mesh->append("materials", io_materials);
auto io_attributes = serialize_attributes(mesh.attributes(), bdata_writer, {});
auto io_attributes = serialize_attributes(mesh.attributes(), bdata_writer, bdata_sharing, {});
HooglyBoogly marked this conversation as resolved Outdated

These functions handle null inputs already, this is a bit prettier :)

  GeometrySet geometry;
  geometry.replace_mesh(try_load_mesh(io_geometry, bdata_reader, bdata_sharing));
  geometry.replace_pointcloud(try_load_pointcloud(io_geometry, bdata_reader, bdata_sharing));
  geometry.replace_curves(try_load_curves(io_geometry, bdata_reader, bdata_sharing));
  geometry.replace_instances(try_load_instances(io_geometry, bdata_reader, bdata_sharing));
  return geometry;
These functions handle null inputs already, this is a bit prettier :) ```cpp GeometrySet geometry; geometry.replace_mesh(try_load_mesh(io_geometry, bdata_reader, bdata_sharing)); geometry.replace_pointcloud(try_load_pointcloud(io_geometry, bdata_reader, bdata_sharing)); geometry.replace_curves(try_load_curves(io_geometry, bdata_reader, bdata_sharing)); geometry.replace_instances(try_load_instances(io_geometry, bdata_reader, bdata_sharing)); return geometry; ```
io_mesh->append("attributes", io_attributes);
}
if (geometry.has_pointcloud()) {
@ -587,7 +588,8 @@ static std::shared_ptr<io::serialize::DictionaryValue> serialize_geometry_set(
auto io_materials = serialize_material_slots({pointcloud.mat, pointcloud.totcol});
io_pointcloud->append("materials", io_materials);
auto io_attributes = serialize_attributes(pointcloud.attributes(), bdata_writer, {});
auto io_attributes = serialize_attributes(
pointcloud.attributes(), bdata_writer, bdata_sharing, {});
io_pointcloud->append("attributes", io_attributes);
}
if (geometry.has_curves()) {
@ -602,7 +604,7 @@ static std::shared_ptr<io::serialize::DictionaryValue> serialize_geometry_set(
if (curves.curve_num > 0) {
io_curves->append(
"curve_offsets",
bdata_writer.write_shared(curves.runtime->curve_offsets_sharing_info, [&]() {
bdata_sharing.write_shared(curves.runtime->curve_offsets_sharing_info, [&]() {
return write_bdata_int_array(bdata_writer, curves.offsets());
}));
}
@ -610,7 +612,8 @@ static std::shared_ptr<io::serialize::DictionaryValue> serialize_geometry_set(
auto io_materials = serialize_material_slots({curves_id.mat, curves_id.totcol});
io_curves->append("materials", io_materials);
auto io_attributes = serialize_attributes(curves.attributes(), bdata_writer, {});
auto io_attributes = serialize_attributes(
curves.attributes(), bdata_writer, bdata_sharing, {});
io_curves->append("attributes", io_attributes);
}
if (geometry.has_instances()) {
@ -622,7 +625,8 @@ static std::shared_ptr<io::serialize::DictionaryValue> serialize_geometry_set(
auto io_references = io_instances->append_array("references");
for (const bke::InstanceReference &reference : instances.references()) {
BLI_assert(reference.type() == bke::InstanceReference::Type::GeometrySet);
io_references->append(serialize_geometry_set(reference.geometry_set(), bdata_writer));
io_references->append(
serialize_geometry_set(reference.geometry_set(), bdata_writer, bdata_sharing));
}
io_instances->append("transforms",
@ -630,7 +634,8 @@ static std::shared_ptr<io::serialize::DictionaryValue> serialize_geometry_set(
io_instances->append("handles",
write_bdata_simple_span(bdata_writer, instances.reference_handles()));
auto io_attributes = serialize_attributes(instances.attributes(), bdata_writer, {"position"});
auto io_attributes = serialize_attributes(
instances.attributes(), bdata_writer, bdata_sharing, {"position"});
io_instances->append("attributes", io_attributes);
}
return io_geometry;
@ -638,6 +643,7 @@ static std::shared_ptr<io::serialize::DictionaryValue> serialize_geometry_set(
void serialize_modifier_simulation_state(const ModifierSimulationState &state,
BDataWriter &bdata_writer,
BDataSharing &bdata_sharing,
io::serialize::DictionaryValue &r_io_root)
{
r_io_root.append_int("version", 1);
@ -670,7 +676,7 @@ void serialize_modifier_simulation_state(const ModifierSimulationState &state,
const GeometrySet &geometry = geometry_state_item->geometry();
auto io_geometry = serialize_geometry_set(geometry, bdata_writer);
auto io_geometry = serialize_geometry_set(geometry, bdata_writer, bdata_sharing);
io_state_item->append("data", io_geometry);
}
}
@ -758,15 +764,10 @@ DiskBDataReader::DiskBDataReader(std::string bdata_dir) : bdata_dir_(std::move(b
return true;
}
DiskBDataWriter::DiskBDataWriter(
std::string bdata_name,
std::ostream &bdata_file,
const int64_t current_offset,
Map<const ImplicitSharingInfo *, std::shared_ptr<io::serialize::DictionaryValue>> &shared_data)
: bdata_name_(std::move(bdata_name)),
bdata_file_(bdata_file),
current_offset_(current_offset),
shared_data_(shared_data)
DiskBDataWriter::DiskBDataWriter(std::string bdata_name,
std::ostream &bdata_file,
const int64_t current_offset)
: bdata_name_(std::move(bdata_name)), bdata_file_(bdata_file), current_offset_(current_offset)
{
}
@ -778,13 +779,20 @@ BDataSlice DiskBDataWriter::write(const void *data, const int64_t size)
return {bdata_name_, {old_offset, size}};
}
DictionaryValuePtr DiskBDataWriter::write_shared(const ImplicitSharingInfo *sharing_info,
const FunctionRef<DictionaryValuePtr()> write_fn)
BDataSharing::~BDataSharing()
{
for (const ImplicitSharingInfo *sharing_info : map_.keys()) {
sharing_info->remove_weak_user_and_delete_if_last();
}
}
DictionaryValuePtr BDataSharing::write_shared(const ImplicitSharingInfo *sharing_info,
FunctionRef<DictionaryValuePtr()> write_fn)
{
if (sharing_info == nullptr) {
return write_fn();
}
return shared_data_.lookup_or_add_cb(sharing_info, [&]() {
return map_.lookup_or_add_cb(sharing_info, [&]() {
sharing_info->add_weak_user();
return write_fn();
});

View File

@ -85,14 +85,7 @@ struct ModifierBakeData {
NodesModifierData *nmd;
std::string meta_dir;
std::string bdata_dir;
Map<const ImplicitSharingInfo *, std::shared_ptr<io::serialize::DictionaryValue>> shared_data;
~ModifierBakeData()
{
for (const ImplicitSharingInfo *sharing_info : shared_data.keys()) {
sharing_info->remove_weak_user_and_delete_if_last();
};
}
bke::sim::BDataSharing bdata_sharing;
};
struct ObjectBakeData {
@ -172,11 +165,11 @@ static int bake_simulation_exec(bContext *C, wmOperator * /*op*/)
BLI_make_existing_file(bdata_path);
fstream bdata_file{bdata_path, std::ios::out | std::ios::binary};
bke::sim::DiskBDataWriter bdata_writer{
bdata_file_name, bdata_file, 0, modifier_bake_data.shared_data};
bke::sim::DiskBDataWriter bdata_writer{bdata_file_name, bdata_file, 0};
io::serialize::DictionaryValue io_root;
bke::sim::serialize_modifier_simulation_state(*sim_state, bdata_writer, io_root);
bke::sim::serialize_modifier_simulation_state(
*sim_state, bdata_writer, modifier_bake_data.bdata_sharing, io_root);
BLI_make_existing_file(meta_path);
fstream meta_file{meta_path, std::ios::out};