Geometry Nodes: rename bdata to blob
Blob stands for "binary large object" and is a known term. I used to use the term `bdata`
to mean "binary data", mainly because I didn't think of a better name. Blob is a much
better name as it captures the intend of those files much better.
This change breaks existing bakes, because I rename the folder from `bdata` to `blobs`.
I think that is ok, because I also just broke bakes two days ago in a larger refactor
(e92c59bc9b
).
Pull Request: https://projects.blender.org/blender/blender/pulls/111822
This commit is contained in:
parent
3082037743
commit
d1c2b45836
|
@ -25,10 +25,10 @@ struct BakePath {
|
||||||
* Path to the directory that contains the binary data. Could be shared between multiple bakes
|
* Path to the directory that contains the binary data. Could be shared between multiple bakes
|
||||||
* to reduce memory consumption.
|
* to reduce memory consumption.
|
||||||
*/
|
*/
|
||||||
std::string bdata_dir;
|
std::string blobs_dir;
|
||||||
/**
|
/**
|
||||||
* Folder that is allowed to be deleted when the bake is deleted and it doesn't contain anything
|
* Folder that is allowed to be deleted when the bake is deleted and it doesn't contain anything
|
||||||
* else. Typically, this contains the meta and bdata directories.
|
* else. Typically, this contains the meta and blob directories.
|
||||||
*/
|
*/
|
||||||
std::optional<std::string> bake_dir;
|
std::optional<std::string> bake_dir;
|
||||||
|
|
||||||
|
|
|
@ -13,44 +13,45 @@ namespace blender::bke {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to a slice of memory typically stored on disk.
|
* Reference to a slice of memory typically stored on disk.
|
||||||
|
* A blob is a "binary large object".
|
||||||
*/
|
*/
|
||||||
struct BDataSlice {
|
struct BlobSlice {
|
||||||
std::string name;
|
std::string name;
|
||||||
IndexRange range;
|
IndexRange range;
|
||||||
|
|
||||||
std::shared_ptr<io::serialize::DictionaryValue> serialize() const;
|
std::shared_ptr<io::serialize::DictionaryValue> serialize() const;
|
||||||
static std::optional<BDataSlice> deserialize(const io::serialize::DictionaryValue &io_slice);
|
static std::optional<BlobSlice> deserialize(const io::serialize::DictionaryValue &io_slice);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for loading binary data.
|
* Abstract base class for loading binary data.
|
||||||
*/
|
*/
|
||||||
class BDataReader {
|
class BlobReader {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Read the data from the given slice into the provided memory buffer.
|
* Read the data from the given slice into the provided memory buffer.
|
||||||
* \return True on success, otherwise false.
|
* \return True on success, otherwise false.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] virtual bool read(const BDataSlice &slice, void *r_data) const = 0;
|
[[nodiscard]] virtual bool read(const BlobSlice &slice, void *r_data) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for writing binary data.
|
* Abstract base class for writing binary data.
|
||||||
*/
|
*/
|
||||||
class BDataWriter {
|
class BlobWriter {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Write the provided binary data.
|
* Write the provided binary data.
|
||||||
* \return Slice where the data has been written to.
|
* \return Slice where the data has been written to.
|
||||||
*/
|
*/
|
||||||
virtual BDataSlice write(const void *data, int64_t size) = 0;
|
virtual BlobSlice write(const void *data, int64_t size) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows for simple data deduplication when writing or reading data by making use of implicit
|
* Allows for simple data deduplication when writing or reading data by making use of implicit
|
||||||
* sharing.
|
* sharing.
|
||||||
*/
|
*/
|
||||||
class BDataSharing {
|
class BlobSharing {
|
||||||
private:
|
private:
|
||||||
struct StoredByRuntimeValue {
|
struct StoredByRuntimeValue {
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +61,7 @@ class BDataSharing {
|
||||||
int64_t sharing_info_version;
|
int64_t sharing_info_version;
|
||||||
/**
|
/**
|
||||||
* Identifier of the stored data. This includes information for where the data is stored (a
|
* Identifier of the stored data. This includes information for where the data is stored (a
|
||||||
* #BDataSlice) and optionally information for how it is loaded (e.g. endian information).
|
* #BlobSlice) and optionally information for how it is loaded (e.g. endian information).
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<io::serialize::DictionaryValue> io_data;
|
std::shared_ptr<io::serialize::DictionaryValue> io_data;
|
||||||
};
|
};
|
||||||
|
@ -83,7 +84,7 @@ class BDataSharing {
|
||||||
mutable Map<std::string, ImplicitSharingInfoAndData> runtime_by_stored_;
|
mutable Map<std::string, ImplicitSharingInfoAndData> runtime_by_stored_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~BDataSharing();
|
~BlobSharing();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the data referenced by `sharing_info` has been written before. If yes, return the
|
* Check if the data referenced by `sharing_info` has been written before. If yes, return the
|
||||||
|
@ -105,44 +106,44 @@ class BDataSharing {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specific #BDataReader that reads from disk.
|
* A specific #BlobReader that reads from disk.
|
||||||
*/
|
*/
|
||||||
class DiskBDataReader : public BDataReader {
|
class DiskBlobReader : public BlobReader {
|
||||||
private:
|
private:
|
||||||
const std::string bdata_dir_;
|
const std::string blobs_dir_;
|
||||||
mutable std::mutex mutex_;
|
mutable std::mutex mutex_;
|
||||||
mutable Map<std::string, std::unique_ptr<fstream>> open_input_streams_;
|
mutable Map<std::string, std::unique_ptr<fstream>> open_input_streams_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DiskBDataReader(std::string bdata_dir);
|
DiskBlobReader(std::string blobs_dir);
|
||||||
[[nodiscard]] bool read(const BDataSlice &slice, void *r_data) const override;
|
[[nodiscard]] bool read(const BlobSlice &slice, void *r_data) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specific #BDataWriter that writes to a file on disk.
|
* A specific #BlobWriter that writes to a file on disk.
|
||||||
*/
|
*/
|
||||||
class DiskBDataWriter : public BDataWriter {
|
class DiskBlobWriter : public BlobWriter {
|
||||||
private:
|
private:
|
||||||
/** Name of the file that data is written to. */
|
/** Name of the file that data is written to. */
|
||||||
std::string bdata_name_;
|
std::string blob_name_;
|
||||||
/** File handle. */
|
/** File handle. */
|
||||||
std::ostream &bdata_file_;
|
std::ostream &blob_file_;
|
||||||
/** Current position in the file. */
|
/** Current position in the file. */
|
||||||
int64_t current_offset_;
|
int64_t current_offset_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DiskBDataWriter(std::string bdata_name, std::ostream &bdata_file, int64_t current_offset);
|
DiskBlobWriter(std::string blob_name, std::ostream &blob_file, int64_t current_offset);
|
||||||
|
|
||||||
BDataSlice write(const void *data, int64_t size) override;
|
BlobSlice write(const void *data, int64_t size) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
void serialize_bake(const BakeState &bake_state,
|
void serialize_bake(const BakeState &bake_state,
|
||||||
BDataWriter &bdata_writer,
|
BlobWriter &blob_writer,
|
||||||
BDataSharing &bdata_sharing,
|
BlobSharing &blob_sharing,
|
||||||
std::ostream &r_stream);
|
std::ostream &r_stream);
|
||||||
|
|
||||||
std::optional<BakeState> deserialize_bake(std::istream &stream,
|
std::optional<BakeState> deserialize_bake(std::istream &stream,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing);
|
const BlobSharing &blob_sharing);
|
||||||
|
|
||||||
} // namespace blender::bke
|
} // namespace blender::bke
|
||||||
|
|
|
@ -46,8 +46,8 @@ struct SimulationZoneCache {
|
||||||
Vector<std::unique_ptr<SimulationZoneFrameCache>> frame_caches;
|
Vector<std::unique_ptr<SimulationZoneFrameCache>> frame_caches;
|
||||||
std::optional<SimulationZonePrevState> prev_state;
|
std::optional<SimulationZonePrevState> prev_state;
|
||||||
|
|
||||||
std::optional<std::string> bdata_dir;
|
std::optional<std::string> blobs_dir;
|
||||||
std::unique_ptr<BDataSharing> bdata_sharing;
|
std::unique_ptr<BlobSharing> blob_sharing;
|
||||||
bool failed_finding_bake = false;
|
bool failed_finding_bake = false;
|
||||||
CacheState cache_state = CacheState::Valid;
|
CacheState cache_state = CacheState::Valid;
|
||||||
|
|
||||||
|
|
|
@ -63,12 +63,12 @@ BakePath BakePath::from_single_root(StringRefNull root_dir)
|
||||||
{
|
{
|
||||||
char meta_dir[FILE_MAX];
|
char meta_dir[FILE_MAX];
|
||||||
BLI_path_join(meta_dir, sizeof(meta_dir), root_dir.c_str(), "meta");
|
BLI_path_join(meta_dir, sizeof(meta_dir), root_dir.c_str(), "meta");
|
||||||
char bdata_dir[FILE_MAX];
|
char blobs_dir[FILE_MAX];
|
||||||
BLI_path_join(bdata_dir, sizeof(bdata_dir), root_dir.c_str(), "bdata");
|
BLI_path_join(blobs_dir, sizeof(blobs_dir), root_dir.c_str(), "blobs");
|
||||||
|
|
||||||
BakePath bake_path;
|
BakePath bake_path;
|
||||||
bake_path.meta_dir = meta_dir;
|
bake_path.meta_dir = meta_dir;
|
||||||
bake_path.bdata_dir = bdata_dir;
|
bake_path.blobs_dir = blobs_dir;
|
||||||
bake_path.bake_dir = root_dir;
|
bake_path.bake_dir = root_dir;
|
||||||
return bake_path;
|
return bake_path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace blender::bke {
|
||||||
using namespace io::serialize;
|
using namespace io::serialize;
|
||||||
using DictionaryValuePtr = std::shared_ptr<DictionaryValue>;
|
using DictionaryValuePtr = std::shared_ptr<DictionaryValue>;
|
||||||
|
|
||||||
std::shared_ptr<DictionaryValue> BDataSlice::serialize() const
|
std::shared_ptr<DictionaryValue> BlobSlice::serialize() const
|
||||||
{
|
{
|
||||||
auto io_slice = std::make_shared<DictionaryValue>();
|
auto io_slice = std::make_shared<DictionaryValue>();
|
||||||
io_slice->append_str("name", this->name);
|
io_slice->append_str("name", this->name);
|
||||||
|
@ -36,7 +36,7 @@ std::shared_ptr<DictionaryValue> BDataSlice::serialize() const
|
||||||
return io_slice;
|
return io_slice;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<BDataSlice> BDataSlice::deserialize(const DictionaryValue &io_slice)
|
std::optional<BlobSlice> BlobSlice::deserialize(const DictionaryValue &io_slice)
|
||||||
{
|
{
|
||||||
const std::optional<StringRefNull> name = io_slice.lookup_str("name");
|
const std::optional<StringRefNull> name = io_slice.lookup_str("name");
|
||||||
const std::optional<int64_t> start = io_slice.lookup_int("start");
|
const std::optional<int64_t> start = io_slice.lookup_int("start");
|
||||||
|
@ -45,48 +45,48 @@ std::optional<BDataSlice> BDataSlice::deserialize(const DictionaryValue &io_slic
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BDataSlice{*name, {*start, *size}};
|
return BlobSlice{*name, {*start, *size}};
|
||||||
}
|
}
|
||||||
|
|
||||||
DiskBDataReader::DiskBDataReader(std::string bdata_dir) : bdata_dir_(std::move(bdata_dir)) {}
|
DiskBlobReader::DiskBlobReader(std::string blobs_dir) : blobs_dir_(std::move(blobs_dir)) {}
|
||||||
|
|
||||||
[[nodiscard]] bool DiskBDataReader::read(const BDataSlice &slice, void *r_data) const
|
[[nodiscard]] bool DiskBlobReader::read(const BlobSlice &slice, void *r_data) const
|
||||||
{
|
{
|
||||||
if (slice.range.is_empty()) {
|
if (slice.range.is_empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char bdata_path[FILE_MAX];
|
char blob_path[FILE_MAX];
|
||||||
BLI_path_join(bdata_path, sizeof(bdata_path), bdata_dir_.c_str(), slice.name.c_str());
|
BLI_path_join(blob_path, sizeof(blob_path), blobs_dir_.c_str(), slice.name.c_str());
|
||||||
|
|
||||||
std::lock_guard lock{mutex_};
|
std::lock_guard lock{mutex_};
|
||||||
std::unique_ptr<fstream> &bdata_file = open_input_streams_.lookup_or_add_cb_as(
|
std::unique_ptr<fstream> &blob_file = open_input_streams_.lookup_or_add_cb_as(blob_path, [&]() {
|
||||||
bdata_path,
|
return std::make_unique<fstream>(blob_path, std::ios::in | std::ios::binary);
|
||||||
[&]() { return std::make_unique<fstream>(bdata_path, std::ios::in | std::ios::binary); });
|
});
|
||||||
bdata_file->seekg(slice.range.start());
|
blob_file->seekg(slice.range.start());
|
||||||
bdata_file->read(static_cast<char *>(r_data), slice.range.size());
|
blob_file->read(static_cast<char *>(r_data), slice.range.size());
|
||||||
if (bdata_file->gcount() != slice.range.size()) {
|
if (blob_file->gcount() != slice.range.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DiskBDataWriter::DiskBDataWriter(std::string bdata_name,
|
DiskBlobWriter::DiskBlobWriter(std::string blob_name,
|
||||||
std::ostream &bdata_file,
|
std::ostream &blob_file,
|
||||||
const int64_t current_offset)
|
const int64_t current_offset)
|
||||||
: bdata_name_(std::move(bdata_name)), bdata_file_(bdata_file), current_offset_(current_offset)
|
: blob_name_(std::move(blob_name)), blob_file_(blob_file), current_offset_(current_offset)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
BDataSlice DiskBDataWriter::write(const void *data, const int64_t size)
|
BlobSlice DiskBlobWriter::write(const void *data, const int64_t size)
|
||||||
{
|
{
|
||||||
const int64_t old_offset = current_offset_;
|
const int64_t old_offset = current_offset_;
|
||||||
bdata_file_.write(static_cast<const char *>(data), size);
|
blob_file_.write(static_cast<const char *>(data), size);
|
||||||
current_offset_ += size;
|
current_offset_ += size;
|
||||||
return {bdata_name_, {old_offset, size}};
|
return {blob_name_, {old_offset, size}};
|
||||||
}
|
}
|
||||||
|
|
||||||
BDataSharing::~BDataSharing()
|
BlobSharing::~BlobSharing()
|
||||||
{
|
{
|
||||||
for (const ImplicitSharingInfo *sharing_info : stored_by_runtime_.keys()) {
|
for (const ImplicitSharingInfo *sharing_info : stored_by_runtime_.keys()) {
|
||||||
sharing_info->remove_weak_user_and_delete_if_last();
|
sharing_info->remove_weak_user_and_delete_if_last();
|
||||||
|
@ -98,8 +98,8 @@ BDataSharing::~BDataSharing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DictionaryValuePtr BDataSharing::write_shared(const ImplicitSharingInfo *sharing_info,
|
DictionaryValuePtr BlobSharing::write_shared(const ImplicitSharingInfo *sharing_info,
|
||||||
FunctionRef<DictionaryValuePtr()> write_fn)
|
FunctionRef<DictionaryValuePtr()> write_fn)
|
||||||
{
|
{
|
||||||
if (sharing_info == nullptr) {
|
if (sharing_info == nullptr) {
|
||||||
return write_fn();
|
return write_fn();
|
||||||
|
@ -126,7 +126,7 @@ DictionaryValuePtr BDataSharing::write_shared(const ImplicitSharingInfo *sharing
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ImplicitSharingInfoAndData> BDataSharing::read_shared(
|
std::optional<ImplicitSharingInfoAndData> BlobSharing::read_shared(
|
||||||
const DictionaryValue &io_data,
|
const DictionaryValue &io_data,
|
||||||
FunctionRef<std::optional<ImplicitSharingInfoAndData>()> read_fn) const
|
FunctionRef<std::optional<ImplicitSharingInfoAndData>()> read_fn) const
|
||||||
{
|
{
|
||||||
|
@ -196,10 +196,10 @@ static std::optional<eCustomDataType> get_data_type_from_io_name(const StringRef
|
||||||
/**
|
/**
|
||||||
* Write the data and remember which endianness the data had.
|
* Write the data and remember which endianness the data had.
|
||||||
*/
|
*/
|
||||||
static std::shared_ptr<DictionaryValue> write_bdata_raw_data_with_endian(
|
static std::shared_ptr<DictionaryValue> write_blob_raw_data_with_endian(
|
||||||
BDataWriter &bdata_writer, const void *data, const int64_t size_in_bytes)
|
BlobWriter &blob_writer, const void *data, const int64_t size_in_bytes)
|
||||||
{
|
{
|
||||||
auto io_data = bdata_writer.write(data, size_in_bytes).serialize();
|
auto io_data = blob_writer.write(data, size_in_bytes).serialize();
|
||||||
if (ENDIAN_ORDER == B_ENDIAN) {
|
if (ENDIAN_ORDER == B_ENDIAN) {
|
||||||
io_data->append_str("endian", get_endian_io_name(ENDIAN_ORDER));
|
io_data->append_str("endian", get_endian_io_name(ENDIAN_ORDER));
|
||||||
}
|
}
|
||||||
|
@ -209,20 +209,20 @@ static std::shared_ptr<DictionaryValue> write_bdata_raw_data_with_endian(
|
||||||
/**
|
/**
|
||||||
* Read data of an into an array and optionally perform an endian switch if necessary.
|
* Read data of an into an array and optionally perform an endian switch if necessary.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] static bool read_bdata_raw_data_with_endian(const BDataReader &bdata_reader,
|
[[nodiscard]] static bool read_blob_raw_data_with_endian(const BlobReader &blob_reader,
|
||||||
const DictionaryValue &io_data,
|
const DictionaryValue &io_data,
|
||||||
const int64_t element_size,
|
const int64_t element_size,
|
||||||
const int64_t elements_num,
|
const int64_t elements_num,
|
||||||
void *r_data)
|
void *r_data)
|
||||||
{
|
{
|
||||||
const std::optional<BDataSlice> slice = BDataSlice::deserialize(io_data);
|
const std::optional<BlobSlice> slice = BlobSlice::deserialize(io_data);
|
||||||
if (!slice) {
|
if (!slice) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (slice->range.size() != element_size * elements_num) {
|
if (slice->range.size() != element_size * elements_num) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!bdata_reader.read(*slice, r_data)) {
|
if (!blob_reader.read(*slice, r_data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const StringRefNull stored_endian = io_data.lookup_str("endian").value_or("little");
|
const StringRefNull stored_endian = io_data.lookup_str("endian").value_or("little");
|
||||||
|
@ -249,95 +249,95 @@ static std::shared_ptr<DictionaryValue> write_bdata_raw_data_with_endian(
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write bytes ignoring endianness. */
|
/** Write bytes ignoring endianness. */
|
||||||
static std::shared_ptr<DictionaryValue> write_bdata_raw_bytes(BDataWriter &bdata_writer,
|
static std::shared_ptr<DictionaryValue> write_blob_raw_bytes(BlobWriter &blob_writer,
|
||||||
const void *data,
|
const void *data,
|
||||||
const int64_t size_in_bytes)
|
const int64_t size_in_bytes)
|
||||||
{
|
{
|
||||||
return bdata_writer.write(data, size_in_bytes).serialize();
|
return blob_writer.write(data, size_in_bytes).serialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read bytes ignoring endianness. */
|
/** Read bytes ignoring endianness. */
|
||||||
[[nodiscard]] static bool read_bdata_raw_bytes(const BDataReader &bdata_reader,
|
[[nodiscard]] static bool read_blob_raw_bytes(const BlobReader &blob_reader,
|
||||||
const DictionaryValue &io_data,
|
const DictionaryValue &io_data,
|
||||||
const int64_t bytes_num,
|
const int64_t bytes_num,
|
||||||
void *r_data)
|
void *r_data)
|
||||||
{
|
{
|
||||||
const std::optional<BDataSlice> slice = BDataSlice::deserialize(io_data);
|
const std::optional<BlobSlice> slice = BlobSlice::deserialize(io_data);
|
||||||
if (!slice) {
|
if (!slice) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (slice->range.size() != bytes_num) {
|
if (slice->range.size() != bytes_num) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return bdata_reader.read(*slice, r_data);
|
return blob_reader.read(*slice, r_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<DictionaryValue> write_bdata_simple_gspan(BDataWriter &bdata_writer,
|
static std::shared_ptr<DictionaryValue> write_blob_simple_gspan(BlobWriter &blob_writer,
|
||||||
const GSpan data)
|
const GSpan data)
|
||||||
{
|
{
|
||||||
const CPPType &type = data.type();
|
const CPPType &type = data.type();
|
||||||
BLI_assert(type.is_trivial());
|
BLI_assert(type.is_trivial());
|
||||||
if (type.size() == 1 || type.is<ColorGeometry4b>()) {
|
if (type.size() == 1 || type.is<ColorGeometry4b>()) {
|
||||||
return write_bdata_raw_bytes(bdata_writer, data.data(), data.size_in_bytes());
|
return write_blob_raw_bytes(blob_writer, data.data(), data.size_in_bytes());
|
||||||
}
|
}
|
||||||
return write_bdata_raw_data_with_endian(bdata_writer, data.data(), data.size_in_bytes());
|
return write_blob_raw_data_with_endian(blob_writer, data.data(), data.size_in_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static bool read_bdata_simple_gspan(const BDataReader &bdata_reader,
|
[[nodiscard]] static bool read_blob_simple_gspan(const BlobReader &blob_reader,
|
||||||
const DictionaryValue &io_data,
|
const DictionaryValue &io_data,
|
||||||
GMutableSpan r_data)
|
GMutableSpan r_data)
|
||||||
{
|
{
|
||||||
const CPPType &type = r_data.type();
|
const CPPType &type = r_data.type();
|
||||||
BLI_assert(type.is_trivial());
|
BLI_assert(type.is_trivial());
|
||||||
if (type.size() == 1 || type.is<ColorGeometry4b>()) {
|
if (type.size() == 1 || type.is<ColorGeometry4b>()) {
|
||||||
return read_bdata_raw_bytes(bdata_reader, io_data, r_data.size_in_bytes(), r_data.data());
|
return read_blob_raw_bytes(blob_reader, io_data, r_data.size_in_bytes(), r_data.data());
|
||||||
}
|
}
|
||||||
if (type.is_any<int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, float>()) {
|
if (type.is_any<int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, float>()) {
|
||||||
return read_bdata_raw_data_with_endian(
|
return read_blob_raw_data_with_endian(
|
||||||
bdata_reader, io_data, type.size(), r_data.size(), r_data.data());
|
blob_reader, io_data, type.size(), r_data.size(), r_data.data());
|
||||||
}
|
}
|
||||||
if (type.is_any<float2, int2>()) {
|
if (type.is_any<float2, int2>()) {
|
||||||
return read_bdata_raw_data_with_endian(
|
return read_blob_raw_data_with_endian(
|
||||||
bdata_reader, io_data, sizeof(int32_t), r_data.size() * 2, r_data.data());
|
blob_reader, io_data, sizeof(int32_t), r_data.size() * 2, r_data.data());
|
||||||
}
|
}
|
||||||
if (type.is<float3>()) {
|
if (type.is<float3>()) {
|
||||||
return read_bdata_raw_data_with_endian(
|
return read_blob_raw_data_with_endian(
|
||||||
bdata_reader, io_data, sizeof(float), r_data.size() * 3, r_data.data());
|
blob_reader, io_data, sizeof(float), r_data.size() * 3, r_data.data());
|
||||||
}
|
}
|
||||||
if (type.is<float4x4>()) {
|
if (type.is<float4x4>()) {
|
||||||
return read_bdata_raw_data_with_endian(
|
return read_blob_raw_data_with_endian(
|
||||||
bdata_reader, io_data, sizeof(float), r_data.size() * 16, r_data.data());
|
blob_reader, io_data, sizeof(float), r_data.size() * 16, r_data.data());
|
||||||
}
|
}
|
||||||
if (type.is<ColorGeometry4f>()) {
|
if (type.is<ColorGeometry4f>()) {
|
||||||
return read_bdata_raw_data_with_endian(
|
return read_blob_raw_data_with_endian(
|
||||||
bdata_reader, io_data, sizeof(float), r_data.size() * 4, r_data.data());
|
blob_reader, io_data, sizeof(float), r_data.size() * 4, r_data.data());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<DictionaryValue> write_bdata_shared_simple_gspan(
|
static std::shared_ptr<DictionaryValue> write_blob_shared_simple_gspan(
|
||||||
BDataWriter &bdata_writer,
|
BlobWriter &blob_writer,
|
||||||
BDataSharing &bdata_sharing,
|
BlobSharing &blob_sharing,
|
||||||
const GSpan data,
|
const GSpan data,
|
||||||
const ImplicitSharingInfo *sharing_info)
|
const ImplicitSharingInfo *sharing_info)
|
||||||
{
|
{
|
||||||
return bdata_sharing.write_shared(
|
return blob_sharing.write_shared(sharing_info,
|
||||||
sharing_info, [&]() { return write_bdata_simple_gspan(bdata_writer, data); });
|
[&]() { return write_blob_simple_gspan(blob_writer, data); });
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static const void *read_bdata_shared_simple_gspan(
|
[[nodiscard]] static const void *read_blob_shared_simple_gspan(
|
||||||
const DictionaryValue &io_data,
|
const DictionaryValue &io_data,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing,
|
const BlobSharing &blob_sharing,
|
||||||
const CPPType &cpp_type,
|
const CPPType &cpp_type,
|
||||||
const int size,
|
const int size,
|
||||||
const ImplicitSharingInfo **r_sharing_info)
|
const ImplicitSharingInfo **r_sharing_info)
|
||||||
{
|
{
|
||||||
const std::optional<ImplicitSharingInfoAndData> sharing_info_and_data =
|
const std::optional<ImplicitSharingInfoAndData> sharing_info_and_data = blob_sharing.read_shared(
|
||||||
bdata_sharing.read_shared(io_data, [&]() -> std::optional<ImplicitSharingInfoAndData> {
|
io_data, [&]() -> std::optional<ImplicitSharingInfoAndData> {
|
||||||
void *data_mem = MEM_mallocN_aligned(
|
void *data_mem = MEM_mallocN_aligned(
|
||||||
size * cpp_type.size(), cpp_type.alignment(), __func__);
|
size * cpp_type.size(), cpp_type.alignment(), __func__);
|
||||||
if (!read_bdata_simple_gspan(bdata_reader, io_data, {cpp_type, data_mem, size})) {
|
if (!read_blob_simple_gspan(blob_reader, io_data, {cpp_type, data_mem, size})) {
|
||||||
MEM_freeN(data_mem);
|
MEM_freeN(data_mem);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -352,22 +352,22 @@ static std::shared_ptr<DictionaryValue> write_bdata_shared_simple_gspan(
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]] static bool read_bdata_shared_simple_span(const DictionaryValue &io_data,
|
[[nodiscard]] static bool read_blob_shared_simple_span(const DictionaryValue &io_data,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing,
|
const BlobSharing &blob_sharing,
|
||||||
const int size,
|
const int size,
|
||||||
T **r_data,
|
T **r_data,
|
||||||
const ImplicitSharingInfo **r_sharing_info)
|
const ImplicitSharingInfo **r_sharing_info)
|
||||||
{
|
{
|
||||||
*r_data = const_cast<T *>(static_cast<const T *>(read_bdata_shared_simple_gspan(
|
*r_data = const_cast<T *>(static_cast<const T *>(read_blob_shared_simple_gspan(
|
||||||
io_data, bdata_reader, bdata_sharing, CPPType::get<T>(), size, r_sharing_info)));
|
io_data, blob_reader, blob_sharing, CPPType::get<T>(), size, r_sharing_info)));
|
||||||
return *r_data != nullptr;
|
return *r_data != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static bool load_attributes(const io::serialize::ArrayValue &io_attributes,
|
[[nodiscard]] static bool load_attributes(const io::serialize::ArrayValue &io_attributes,
|
||||||
bke::MutableAttributeAccessor &attributes,
|
bke::MutableAttributeAccessor &attributes,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing)
|
const BlobSharing &blob_sharing)
|
||||||
{
|
{
|
||||||
for (const auto &io_attribute_value : io_attributes.elements()) {
|
for (const auto &io_attribute_value : io_attributes.elements()) {
|
||||||
const auto *io_attribute = io_attribute_value->as_dictionary_value();
|
const auto *io_attribute = io_attribute_value->as_dictionary_value();
|
||||||
|
@ -393,8 +393,8 @@ template<typename T>
|
||||||
}
|
}
|
||||||
const int domain_size = attributes.domain_size(*domain);
|
const int domain_size = attributes.domain_size(*domain);
|
||||||
const ImplicitSharingInfo *attribute_sharing_info;
|
const ImplicitSharingInfo *attribute_sharing_info;
|
||||||
const void *attribute_data = read_bdata_shared_simple_gspan(
|
const void *attribute_data = read_blob_shared_simple_gspan(
|
||||||
*io_data, bdata_reader, bdata_sharing, *cpp_type, domain_size, &attribute_sharing_info);
|
*io_data, blob_reader, blob_sharing, *cpp_type, domain_size, &attribute_sharing_info);
|
||||||
if (!attribute_data) {
|
if (!attribute_data) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -425,8 +425,8 @@ template<typename T>
|
||||||
}
|
}
|
||||||
|
|
||||||
static PointCloud *try_load_pointcloud(const DictionaryValue &io_geometry,
|
static PointCloud *try_load_pointcloud(const DictionaryValue &io_geometry,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing)
|
const BlobSharing &blob_sharing)
|
||||||
{
|
{
|
||||||
const DictionaryValue *io_pointcloud = io_geometry.lookup_dict("pointcloud");
|
const DictionaryValue *io_pointcloud = io_geometry.lookup_dict("pointcloud");
|
||||||
if (!io_pointcloud) {
|
if (!io_pointcloud) {
|
||||||
|
@ -446,15 +446,15 @@ static PointCloud *try_load_pointcloud(const DictionaryValue &io_geometry,
|
||||||
};
|
};
|
||||||
|
|
||||||
bke::MutableAttributeAccessor attributes = pointcloud->attributes_for_write();
|
bke::MutableAttributeAccessor attributes = pointcloud->attributes_for_write();
|
||||||
if (!load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing)) {
|
if (!load_attributes(*io_attributes, attributes, blob_reader, blob_sharing)) {
|
||||||
return cancel();
|
return cancel();
|
||||||
}
|
}
|
||||||
return pointcloud;
|
return pointcloud;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Curves *try_load_curves(const DictionaryValue &io_geometry,
|
static Curves *try_load_curves(const DictionaryValue &io_geometry,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing)
|
const BlobSharing &blob_sharing)
|
||||||
{
|
{
|
||||||
const DictionaryValue *io_curves = io_geometry.lookup_dict("curves");
|
const DictionaryValue *io_curves = io_geometry.lookup_dict("curves");
|
||||||
if (!io_curves) {
|
if (!io_curves) {
|
||||||
|
@ -482,19 +482,19 @@ static Curves *try_load_curves(const DictionaryValue &io_geometry,
|
||||||
if (!io_curve_offsets) {
|
if (!io_curve_offsets) {
|
||||||
return cancel();
|
return cancel();
|
||||||
}
|
}
|
||||||
if (!read_bdata_shared_simple_span(*io_curve_offsets,
|
if (!read_blob_shared_simple_span(*io_curve_offsets,
|
||||||
bdata_reader,
|
blob_reader,
|
||||||
bdata_sharing,
|
blob_sharing,
|
||||||
curves.curves_num() + 1,
|
curves.curves_num() + 1,
|
||||||
&curves.curve_offsets,
|
&curves.curve_offsets,
|
||||||
&curves.runtime->curve_offsets_sharing_info))
|
&curves.runtime->curve_offsets_sharing_info))
|
||||||
{
|
{
|
||||||
return cancel();
|
return cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
|
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
|
||||||
if (!load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing)) {
|
if (!load_attributes(*io_attributes, attributes, blob_reader, blob_sharing)) {
|
||||||
return cancel();
|
return cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,8 +504,8 @@ static Curves *try_load_curves(const DictionaryValue &io_geometry,
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mesh *try_load_mesh(const DictionaryValue &io_geometry,
|
static Mesh *try_load_mesh(const DictionaryValue &io_geometry,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing)
|
const BlobSharing &blob_sharing)
|
||||||
{
|
{
|
||||||
const DictionaryValue *io_mesh = io_geometry.lookup_dict("mesh");
|
const DictionaryValue *io_mesh = io_geometry.lookup_dict("mesh");
|
||||||
if (!io_mesh) {
|
if (!io_mesh) {
|
||||||
|
@ -537,19 +537,19 @@ static Mesh *try_load_mesh(const DictionaryValue &io_geometry,
|
||||||
if (!io_poly_offsets) {
|
if (!io_poly_offsets) {
|
||||||
return cancel();
|
return cancel();
|
||||||
}
|
}
|
||||||
if (!read_bdata_shared_simple_span(*io_poly_offsets,
|
if (!read_blob_shared_simple_span(*io_poly_offsets,
|
||||||
bdata_reader,
|
blob_reader,
|
||||||
bdata_sharing,
|
blob_sharing,
|
||||||
mesh->faces_num + 1,
|
mesh->faces_num + 1,
|
||||||
&mesh->face_offset_indices,
|
&mesh->face_offset_indices,
|
||||||
&mesh->runtime->face_offsets_sharing_info))
|
&mesh->runtime->face_offsets_sharing_info))
|
||||||
{
|
{
|
||||||
return cancel();
|
return cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||||
if (!load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing)) {
|
if (!load_attributes(*io_attributes, attributes, blob_reader, blob_sharing)) {
|
||||||
return cancel();
|
return cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,12 +557,12 @@ static Mesh *try_load_mesh(const DictionaryValue &io_geometry,
|
||||||
}
|
}
|
||||||
|
|
||||||
static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing);
|
const BlobSharing &blob_sharing);
|
||||||
|
|
||||||
static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue &io_geometry,
|
static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue &io_geometry,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing)
|
const BlobSharing &blob_sharing)
|
||||||
{
|
{
|
||||||
const DictionaryValue *io_instances = io_geometry.lookup_dict("instances");
|
const DictionaryValue *io_instances = io_geometry.lookup_dict("instances");
|
||||||
if (!io_instances) {
|
if (!io_instances) {
|
||||||
|
@ -588,7 +588,7 @@ static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue
|
||||||
const DictionaryValue *io_reference = io_reference_value->as_dictionary_value();
|
const DictionaryValue *io_reference = io_reference_value->as_dictionary_value();
|
||||||
GeometrySet reference_geometry;
|
GeometrySet reference_geometry;
|
||||||
if (io_reference) {
|
if (io_reference) {
|
||||||
reference_geometry = load_geometry(*io_reference, bdata_reader, bdata_sharing);
|
reference_geometry = load_geometry(*io_reference, blob_reader, blob_sharing);
|
||||||
}
|
}
|
||||||
instances->add_reference(std::move(reference_geometry));
|
instances->add_reference(std::move(reference_geometry));
|
||||||
}
|
}
|
||||||
|
@ -597,7 +597,7 @@ static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue
|
||||||
if (!io_transforms) {
|
if (!io_transforms) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (!read_bdata_simple_gspan(bdata_reader, *io_transforms, instances->transforms())) {
|
if (!read_blob_simple_gspan(blob_reader, *io_transforms, instances->transforms())) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,12 +605,12 @@ static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue
|
||||||
if (!io_handles) {
|
if (!io_handles) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (!read_bdata_simple_gspan(bdata_reader, *io_handles, instances->reference_handles())) {
|
if (!read_blob_simple_gspan(blob_reader, *io_handles, instances->reference_handles())) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bke::MutableAttributeAccessor attributes = instances->attributes_for_write();
|
bke::MutableAttributeAccessor attributes = instances->attributes_for_write();
|
||||||
if (!load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing)) {
|
if (!load_attributes(*io_attributes, attributes, blob_reader, blob_sharing)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,15 +618,14 @@ static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue
|
||||||
}
|
}
|
||||||
|
|
||||||
static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing)
|
const BlobSharing &blob_sharing)
|
||||||
{
|
{
|
||||||
GeometrySet geometry;
|
GeometrySet geometry;
|
||||||
geometry.replace_mesh(try_load_mesh(io_geometry, bdata_reader, bdata_sharing));
|
geometry.replace_mesh(try_load_mesh(io_geometry, blob_reader, blob_sharing));
|
||||||
geometry.replace_pointcloud(try_load_pointcloud(io_geometry, bdata_reader, bdata_sharing));
|
geometry.replace_pointcloud(try_load_pointcloud(io_geometry, blob_reader, blob_sharing));
|
||||||
geometry.replace_curves(try_load_curves(io_geometry, bdata_reader, bdata_sharing));
|
geometry.replace_curves(try_load_curves(io_geometry, blob_reader, blob_sharing));
|
||||||
geometry.replace_instances(
|
geometry.replace_instances(try_load_instances(io_geometry, blob_reader, blob_sharing).release());
|
||||||
try_load_instances(io_geometry, bdata_reader, bdata_sharing).release());
|
|
||||||
return geometry;
|
return geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,8 +650,8 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_material_slots(
|
||||||
|
|
||||||
static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
|
static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
|
||||||
const bke::AttributeAccessor &attributes,
|
const bke::AttributeAccessor &attributes,
|
||||||
BDataWriter &bdata_writer,
|
BlobWriter &blob_writer,
|
||||||
BDataSharing &bdata_sharing,
|
BlobSharing &blob_sharing,
|
||||||
const Set<std::string> &attributes_to_ignore)
|
const Set<std::string> &attributes_to_ignore)
|
||||||
{
|
{
|
||||||
auto io_attributes = std::make_shared<io::serialize::ArrayValue>();
|
auto io_attributes = std::make_shared<io::serialize::ArrayValue>();
|
||||||
|
@ -676,9 +675,9 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
|
||||||
const bke::GAttributeReader attribute = attributes.lookup(attribute_id);
|
const bke::GAttributeReader attribute = attributes.lookup(attribute_id);
|
||||||
const GVArraySpan attribute_span(attribute.varray);
|
const GVArraySpan attribute_span(attribute.varray);
|
||||||
io_attribute->append("data",
|
io_attribute->append("data",
|
||||||
write_bdata_shared_simple_gspan(
|
write_blob_shared_simple_gspan(
|
||||||
bdata_writer,
|
blob_writer,
|
||||||
bdata_sharing,
|
blob_sharing,
|
||||||
attribute_span,
|
attribute_span,
|
||||||
attribute.varray.is_span() ? attribute.sharing_info : nullptr));
|
attribute.varray.is_span() ? attribute.sharing_info : nullptr));
|
||||||
return true;
|
return true;
|
||||||
|
@ -687,8 +686,8 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet &geometry,
|
static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet &geometry,
|
||||||
BDataWriter &bdata_writer,
|
BlobWriter &blob_writer,
|
||||||
BDataSharing &bdata_sharing)
|
BlobSharing &blob_sharing)
|
||||||
{
|
{
|
||||||
auto io_geometry = std::make_shared<DictionaryValue>();
|
auto io_geometry = std::make_shared<DictionaryValue>();
|
||||||
if (geometry.has_mesh()) {
|
if (geometry.has_mesh()) {
|
||||||
|
@ -702,16 +701,16 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
||||||
|
|
||||||
if (mesh.faces_num > 0) {
|
if (mesh.faces_num > 0) {
|
||||||
io_mesh->append("poly_offsets",
|
io_mesh->append("poly_offsets",
|
||||||
write_bdata_shared_simple_gspan(bdata_writer,
|
write_blob_shared_simple_gspan(blob_writer,
|
||||||
bdata_sharing,
|
blob_sharing,
|
||||||
mesh.face_offsets(),
|
mesh.face_offsets(),
|
||||||
mesh.runtime->face_offsets_sharing_info));
|
mesh.runtime->face_offsets_sharing_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto io_materials = serialize_material_slots({mesh.mat, mesh.totcol});
|
auto io_materials = serialize_material_slots({mesh.mat, mesh.totcol});
|
||||||
io_mesh->append("materials", io_materials);
|
io_mesh->append("materials", io_materials);
|
||||||
|
|
||||||
auto io_attributes = serialize_attributes(mesh.attributes(), bdata_writer, bdata_sharing, {});
|
auto io_attributes = serialize_attributes(mesh.attributes(), blob_writer, blob_sharing, {});
|
||||||
io_mesh->append("attributes", io_attributes);
|
io_mesh->append("attributes", io_attributes);
|
||||||
}
|
}
|
||||||
if (geometry.has_pointcloud()) {
|
if (geometry.has_pointcloud()) {
|
||||||
|
@ -724,7 +723,7 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
||||||
io_pointcloud->append("materials", io_materials);
|
io_pointcloud->append("materials", io_materials);
|
||||||
|
|
||||||
auto io_attributes = serialize_attributes(
|
auto io_attributes = serialize_attributes(
|
||||||
pointcloud.attributes(), bdata_writer, bdata_sharing, {});
|
pointcloud.attributes(), blob_writer, blob_sharing, {});
|
||||||
io_pointcloud->append("attributes", io_attributes);
|
io_pointcloud->append("attributes", io_attributes);
|
||||||
}
|
}
|
||||||
if (geometry.has_curves()) {
|
if (geometry.has_curves()) {
|
||||||
|
@ -739,17 +738,16 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
||||||
if (curves.curve_num > 0) {
|
if (curves.curve_num > 0) {
|
||||||
io_curves->append(
|
io_curves->append(
|
||||||
"curve_offsets",
|
"curve_offsets",
|
||||||
write_bdata_shared_simple_gspan(bdata_writer,
|
write_blob_shared_simple_gspan(blob_writer,
|
||||||
bdata_sharing,
|
blob_sharing,
|
||||||
curves.offsets(),
|
curves.offsets(),
|
||||||
curves.runtime->curve_offsets_sharing_info));
|
curves.runtime->curve_offsets_sharing_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto io_materials = serialize_material_slots({curves_id.mat, curves_id.totcol});
|
auto io_materials = serialize_material_slots({curves_id.mat, curves_id.totcol});
|
||||||
io_curves->append("materials", io_materials);
|
io_curves->append("materials", io_materials);
|
||||||
|
|
||||||
auto io_attributes = serialize_attributes(
|
auto io_attributes = serialize_attributes(curves.attributes(), blob_writer, blob_sharing, {});
|
||||||
curves.attributes(), bdata_writer, bdata_sharing, {});
|
|
||||||
io_curves->append("attributes", io_attributes);
|
io_curves->append("attributes", io_attributes);
|
||||||
}
|
}
|
||||||
if (geometry.has_instances()) {
|
if (geometry.has_instances()) {
|
||||||
|
@ -762,16 +760,16 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
||||||
for (const bke::InstanceReference &reference : instances.references()) {
|
for (const bke::InstanceReference &reference : instances.references()) {
|
||||||
BLI_assert(reference.type() == bke::InstanceReference::Type::GeometrySet);
|
BLI_assert(reference.type() == bke::InstanceReference::Type::GeometrySet);
|
||||||
io_references->append(
|
io_references->append(
|
||||||
serialize_geometry_set(reference.geometry_set(), bdata_writer, bdata_sharing));
|
serialize_geometry_set(reference.geometry_set(), blob_writer, blob_sharing));
|
||||||
}
|
}
|
||||||
|
|
||||||
io_instances->append("transforms",
|
io_instances->append("transforms",
|
||||||
write_bdata_simple_gspan(bdata_writer, instances.transforms()));
|
write_blob_simple_gspan(blob_writer, instances.transforms()));
|
||||||
io_instances->append("handles",
|
io_instances->append("handles",
|
||||||
write_bdata_simple_gspan(bdata_writer, instances.reference_handles()));
|
write_blob_simple_gspan(blob_writer, instances.reference_handles()));
|
||||||
|
|
||||||
auto io_attributes = serialize_attributes(
|
auto io_attributes = serialize_attributes(
|
||||||
instances.attributes(), bdata_writer, bdata_sharing, {"position"});
|
instances.attributes(), blob_writer, blob_sharing, {"position"});
|
||||||
io_instances->append("attributes", io_attributes);
|
io_instances->append("attributes", io_attributes);
|
||||||
}
|
}
|
||||||
return io_geometry;
|
return io_geometry;
|
||||||
|
@ -961,15 +959,15 @@ template<typename T>
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serialize_bake_item(const BakeItem &item,
|
static void serialize_bake_item(const BakeItem &item,
|
||||||
BDataWriter &bdata_writer,
|
BlobWriter &blob_writer,
|
||||||
BDataSharing &bdata_sharing,
|
BlobSharing &blob_sharing,
|
||||||
DictionaryValue &r_io_item)
|
DictionaryValue &r_io_item)
|
||||||
{
|
{
|
||||||
if (const auto *geometry_state_item = dynamic_cast<const GeometryBakeItem *>(&item)) {
|
if (const auto *geometry_state_item = dynamic_cast<const GeometryBakeItem *>(&item)) {
|
||||||
r_io_item.append_str("type", "GEOMETRY");
|
r_io_item.append_str("type", "GEOMETRY");
|
||||||
|
|
||||||
const GeometrySet &geometry = geometry_state_item->geometry;
|
const GeometrySet &geometry = geometry_state_item->geometry;
|
||||||
auto io_geometry = serialize_geometry_set(geometry, bdata_writer, bdata_sharing);
|
auto io_geometry = serialize_geometry_set(geometry, blob_writer, blob_sharing);
|
||||||
r_io_item.append("data", io_geometry);
|
r_io_item.append("data", io_geometry);
|
||||||
}
|
}
|
||||||
else if (const auto *attribute_state_item = dynamic_cast<const AttributeBakeItem *>(&item)) {
|
else if (const auto *attribute_state_item = dynamic_cast<const AttributeBakeItem *>(&item)) {
|
||||||
|
@ -980,12 +978,12 @@ static void serialize_bake_item(const BakeItem &item,
|
||||||
r_io_item.append_str("type", "STRING");
|
r_io_item.append_str("type", "STRING");
|
||||||
const StringRefNull str = string_state_item->value();
|
const StringRefNull str = string_state_item->value();
|
||||||
/* Small strings are inlined, larger strings are stored separately. */
|
/* Small strings are inlined, larger strings are stored separately. */
|
||||||
const int64_t bdata_threshold = 100;
|
const int64_t blob_threshold = 100;
|
||||||
if (str.size() < bdata_threshold) {
|
if (str.size() < blob_threshold) {
|
||||||
r_io_item.append_str("data", string_state_item->value());
|
r_io_item.append_str("data", string_state_item->value());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
r_io_item.append("data", write_bdata_raw_bytes(bdata_writer, str.data(), str.size()));
|
r_io_item.append("data", write_blob_raw_bytes(blob_writer, str.data(), str.size()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (const auto *primitive_state_item = dynamic_cast<const PrimitiveBakeItem *>(&item)) {
|
else if (const auto *primitive_state_item = dynamic_cast<const PrimitiveBakeItem *>(&item)) {
|
||||||
|
@ -997,8 +995,8 @@ static void serialize_bake_item(const BakeItem &item,
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io_item,
|
static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io_item,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing)
|
const BlobSharing &blob_sharing)
|
||||||
{
|
{
|
||||||
|
|
||||||
const std::optional<StringRefNull> state_item_type = io_item.lookup_str("type");
|
const std::optional<StringRefNull> state_item_type = io_item.lookup_str("type");
|
||||||
|
@ -1010,7 +1008,7 @@ static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io
|
||||||
if (!io_geometry) {
|
if (!io_geometry) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
GeometrySet geometry = load_geometry(*io_geometry, bdata_reader, bdata_sharing);
|
GeometrySet geometry = load_geometry(*io_geometry, blob_reader, blob_sharing);
|
||||||
return std::make_unique<GeometryBakeItem>(std::move(geometry));
|
return std::make_unique<GeometryBakeItem>(std::move(geometry));
|
||||||
}
|
}
|
||||||
if (*state_item_type == StringRef("ATTRIBUTE")) {
|
if (*state_item_type == StringRef("ATTRIBUTE")) {
|
||||||
|
@ -1041,7 +1039,7 @@ static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io
|
||||||
}
|
}
|
||||||
std::string str;
|
std::string str;
|
||||||
str.resize(*size);
|
str.resize(*size);
|
||||||
if (!read_bdata_raw_bytes(bdata_reader, *io_string, *size, str.data())) {
|
if (!read_blob_raw_bytes(blob_reader, *io_string, *size, str.data())) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return std::make_unique<StringBakeItem>(std::move(str));
|
return std::make_unique<StringBakeItem>(std::move(str));
|
||||||
|
@ -1067,8 +1065,8 @@ static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io
|
||||||
static constexpr int bake_file_version = 3;
|
static constexpr int bake_file_version = 3;
|
||||||
|
|
||||||
void serialize_bake(const BakeState &bake_state,
|
void serialize_bake(const BakeState &bake_state,
|
||||||
BDataWriter &bdata_writer,
|
BlobWriter &blob_writer,
|
||||||
BDataSharing &bdata_sharing,
|
BlobSharing &blob_sharing,
|
||||||
std::ostream &r_stream)
|
std::ostream &r_stream)
|
||||||
{
|
{
|
||||||
io::serialize::DictionaryValue io_root;
|
io::serialize::DictionaryValue io_root;
|
||||||
|
@ -1076,7 +1074,7 @@ void serialize_bake(const BakeState &bake_state,
|
||||||
io::serialize::DictionaryValue &io_items = *io_root.append_dict("items");
|
io::serialize::DictionaryValue &io_items = *io_root.append_dict("items");
|
||||||
for (auto item : bake_state.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));
|
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);
|
bke::serialize_bake_item(*item.value, blob_writer, blob_sharing, io_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
io::serialize::JsonFormatter formatter;
|
io::serialize::JsonFormatter formatter;
|
||||||
|
@ -1084,8 +1082,8 @@ void serialize_bake(const BakeState &bake_state,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<BakeState> deserialize_bake(std::istream &stream,
|
std::optional<BakeState> deserialize_bake(std::istream &stream,
|
||||||
const BDataReader &bdata_reader,
|
const BlobReader &blob_reader,
|
||||||
const BDataSharing &bdata_sharing)
|
const BlobSharing &blob_sharing)
|
||||||
{
|
{
|
||||||
JsonFormatter formatter;
|
JsonFormatter formatter;
|
||||||
std::unique_ptr<io::serialize::Value> io_root_value = formatter.deserialize(stream);
|
std::unique_ptr<io::serialize::Value> io_root_value = formatter.deserialize(stream);
|
||||||
|
@ -1121,7 +1119,7 @@ std::optional<BakeState> deserialize_bake(std::istream &stream,
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
std::unique_ptr<BakeItem> bake_item = deserialize_bake_item(
|
std::unique_ptr<BakeItem> bake_item = deserialize_bake_item(
|
||||||
*io_item, bdata_reader, bdata_sharing);
|
*io_item, blob_reader, blob_sharing);
|
||||||
if (!bake_item) {
|
if (!bake_item) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,8 @@ void SimulationZoneCache::reset()
|
||||||
{
|
{
|
||||||
this->frame_caches.clear();
|
this->frame_caches.clear();
|
||||||
this->prev_state.reset();
|
this->prev_state.reset();
|
||||||
this->bdata_dir.reset();
|
this->blobs_dir.reset();
|
||||||
this->bdata_sharing.reset();
|
this->blob_sharing.reset();
|
||||||
this->failed_finding_bake = false;
|
this->failed_finding_bake = false;
|
||||||
this->cache_state = CacheState::Valid;
|
this->cache_state = CacheState::Valid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,7 @@ static bool bake_simulation_poll(bContext *C)
|
||||||
struct ZoneBakeData {
|
struct ZoneBakeData {
|
||||||
int zone_id;
|
int zone_id;
|
||||||
bke::bake_paths::BakePath path;
|
bke::bake_paths::BakePath path;
|
||||||
std::unique_ptr<bke::BDataSharing> bdata_sharing;
|
std::unique_ptr<bke::BlobSharing> blob_sharing;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModifierBakeData {
|
struct ModifierBakeData {
|
||||||
|
@ -285,7 +285,7 @@ static void bake_simulation_job_startjob(void *customdata,
|
||||||
for (const bNestedNodeRef &nested_node_ref : nmd->node_group->nested_node_refs_span()) {
|
for (const bNestedNodeRef &nested_node_ref : nmd->node_group->nested_node_refs_span()) {
|
||||||
ZoneBakeData zone_bake_data;
|
ZoneBakeData zone_bake_data;
|
||||||
zone_bake_data.zone_id = nested_node_ref.id;
|
zone_bake_data.zone_id = nested_node_ref.id;
|
||||||
zone_bake_data.bdata_sharing = std::make_unique<bke::BDataSharing>();
|
zone_bake_data.blob_sharing = std::make_unique<bke::BlobSharing>();
|
||||||
if (std::optional<bke::bake_paths::BakePath> path =
|
if (std::optional<bke::bake_paths::BakePath> path =
|
||||||
bke::sim::get_simulation_zone_bake_path(
|
bke::sim::get_simulation_zone_bake_path(
|
||||||
*job.bmain, *object, *nmd, nested_node_ref.id))
|
*job.bmain, *object, *nmd, nested_node_ref.id))
|
||||||
|
@ -344,23 +344,23 @@ static void bake_simulation_job_startjob(void *customdata,
|
||||||
|
|
||||||
const bke::bake_paths::BakePath path = zone_bake_data.path;
|
const bke::bake_paths::BakePath path = zone_bake_data.path;
|
||||||
|
|
||||||
const std::string bdata_file_name = frame_file_name + ".bdata";
|
const std::string blob_file_name = frame_file_name + ".blob";
|
||||||
|
|
||||||
char bdata_path[FILE_MAX];
|
char blob_path[FILE_MAX];
|
||||||
BLI_path_join(
|
BLI_path_join(
|
||||||
bdata_path, sizeof(bdata_path), path.bdata_dir.c_str(), bdata_file_name.c_str());
|
blob_path, sizeof(blob_path), path.blobs_dir.c_str(), blob_file_name.c_str());
|
||||||
char meta_path[FILE_MAX];
|
char meta_path[FILE_MAX];
|
||||||
BLI_path_join(meta_path,
|
BLI_path_join(meta_path,
|
||||||
sizeof(meta_path),
|
sizeof(meta_path),
|
||||||
path.meta_dir.c_str(),
|
path.meta_dir.c_str(),
|
||||||
(frame_file_name + ".json").c_str());
|
(frame_file_name + ".json").c_str());
|
||||||
BLI_file_ensure_parent_dir_exists(meta_path);
|
BLI_file_ensure_parent_dir_exists(meta_path);
|
||||||
BLI_file_ensure_parent_dir_exists(bdata_path);
|
BLI_file_ensure_parent_dir_exists(blob_path);
|
||||||
fstream bdata_file{bdata_path, std::ios::out | std::ios::binary};
|
fstream blob_file{blob_path, std::ios::out | std::ios::binary};
|
||||||
bke::DiskBDataWriter bdata_writer{bdata_file_name, bdata_file, 0};
|
bke::DiskBlobWriter blob_writer{blob_file_name, blob_file, 0};
|
||||||
fstream meta_file{meta_path, std::ios::out};
|
fstream meta_file{meta_path, std::ios::out};
|
||||||
bke::serialize_bake(
|
bke::serialize_bake(
|
||||||
frame_cache.state, bdata_writer, *zone_bake_data.bdata_sharing, meta_file);
|
frame_cache.state, blob_writer, *zone_bake_data.blob_sharing, meta_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,10 +471,10 @@ static bool bake_directory_has_data(const StringRefNull absolute_bake_dir)
|
||||||
{
|
{
|
||||||
char meta_dir[FILE_MAX];
|
char meta_dir[FILE_MAX];
|
||||||
BLI_path_join(meta_dir, sizeof(meta_dir), absolute_bake_dir.c_str(), "meta");
|
BLI_path_join(meta_dir, sizeof(meta_dir), absolute_bake_dir.c_str(), "meta");
|
||||||
char bdata_dir[FILE_MAX];
|
char blobs_dir[FILE_MAX];
|
||||||
BLI_path_join(bdata_dir, sizeof(bdata_dir), absolute_bake_dir.c_str(), "bdata");
|
BLI_path_join(blobs_dir, sizeof(blobs_dir), absolute_bake_dir.c_str(), "blobs");
|
||||||
|
|
||||||
if (!BLI_is_dir(meta_dir) || !BLI_is_dir(bdata_dir)) {
|
if (!BLI_is_dir(meta_dir) || !BLI_is_dir(blobs_dir)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,11 +647,11 @@ static int delete_baked_simulation_exec(bContext *C, wmOperator *op)
|
||||||
BKE_reportf(op->reports, RPT_ERROR, "Failed to remove meta directory %s", meta_dir);
|
BKE_reportf(op->reports, RPT_ERROR, "Failed to remove meta directory %s", meta_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const char *bdata_dir = bake_path->bdata_dir.c_str();
|
const char *blobs_dir = bake_path->blobs_dir.c_str();
|
||||||
if (BLI_exists(bdata_dir)) {
|
if (BLI_exists(blobs_dir)) {
|
||||||
if (BLI_delete(bdata_dir, true, true)) {
|
if (BLI_delete(blobs_dir, true, true)) {
|
||||||
BKE_reportf(
|
BKE_reportf(
|
||||||
op->reports, RPT_ERROR, "Failed to remove bdata directory %s", bdata_dir);
|
op->reports, RPT_ERROR, "Failed to remove blobs directory %s", blobs_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bake_path->bake_dir.has_value()) {
|
if (bake_path->bake_dir.has_value()) {
|
||||||
|
|
|
@ -768,8 +768,8 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
|
||||||
frame_cache->meta_path = meta_file.path;
|
frame_cache->meta_path = meta_file.path;
|
||||||
zone_cache.frame_caches.append(std::move(frame_cache));
|
zone_cache.frame_caches.append(std::move(frame_cache));
|
||||||
}
|
}
|
||||||
zone_cache.bdata_dir = zone_bake_path->bdata_dir;
|
zone_cache.blobs_dir = zone_bake_path->blobs_dir;
|
||||||
zone_cache.bdata_sharing = std::make_unique<bke::BDataSharing>();
|
zone_cache.blob_sharing = std::make_unique<bke::BlobSharing>();
|
||||||
zone_cache.cache_state = CacheState::Baked;
|
zone_cache.cache_state = CacheState::Baked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1003,16 +1003,16 @@ class NodesModifierSimulationParams : public nodes::GeoNodesSimulationParams {
|
||||||
if (!frame_cache.state.items_by_id.is_empty()) {
|
if (!frame_cache.state.items_by_id.is_empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!zone_cache.bdata_dir) {
|
if (!zone_cache.blobs_dir) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!frame_cache.meta_path) {
|
if (!frame_cache.meta_path) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bke::DiskBDataReader bdata_reader{*zone_cache.bdata_dir};
|
bke::DiskBlobReader blob_reader{*zone_cache.blobs_dir};
|
||||||
fstream meta_file{*frame_cache.meta_path};
|
fstream meta_file{*frame_cache.meta_path};
|
||||||
std::optional<bke::BakeState> bake_state = bke::deserialize_bake(
|
std::optional<bke::BakeState> bake_state = bke::deserialize_bake(
|
||||||
meta_file, bdata_reader, *zone_cache.bdata_sharing);
|
meta_file, blob_reader, *zone_cache.blob_sharing);
|
||||||
if (!bake_state.has_value()) {
|
if (!bake_state.has_value()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue