#ifndef GRID3_Serialization #define GRID3_Serialization #include #include #include "grid3.hpp" constexpr char magic[4] = {'Y', 'G', 'G', '3'}; inline bool VoxelGrid::serializeToFile(const std::string& filename) { std::ofstream file(filename, std::ios::binary); if (!file.is_open()) { std::cerr << "failed to open file (serializeToFile): " << filename << std::endl; return false; } file.write(magic, 4); int dims[3] = {gridSize.x, gridSize.y, gridSize.z}; file.write(reinterpret_cast(dims), sizeof(dims)); size_t voxelCount = voxels.size(); for (const Voxel& voxel : voxels) { auto write_member = [&file](const auto& member) { file.write(reinterpret_cast(&member), sizeof(member)); }; std::apply([&write_member](const auto&... members) { (write_member(members), ...); }, voxel.members()); } file.close(); return !file.fail(); } std::unique_ptr VoxelGrid::deserializeFromFile(const std::string& filename) { std::ifstream file(filename, std::ios::binary); if (!file.is_open()) { std::cerr << "failed to open file (deserializeFromFile): " << filename << std::endl; return nullptr; } // Read and verify magic number char filemagic[4]; file.read(filemagic, 4); if (std::strncmp(filemagic, magic, 4) != 0) { std::cerr << "Error: Invalid file format or corrupted file (expected " << magic[0] << magic[1] << magic[2] << magic[3] << ", got " << filemagic[0] << filemagic[1] << filemagic[2] << filemagic[3] << ")" << std::endl; return nullptr; } // Create output grid auto outgrid = std::make_unique(); // Read grid dimensions int dims[3]; file.read(reinterpret_cast(dims), sizeof(dims)); // Resize grid outgrid->gridSize = Vec3i(dims[0], dims[1], dims[2]); outgrid->voxels.resize(dims[0] * dims[1] * dims[2]); // Read voxel count size_t voxelCount; file.read(reinterpret_cast(&voxelCount), sizeof(voxelCount)); // Verify voxel count matches grid dimensions size_t expectedCount = static_cast(dims[0]) * dims[1] * dims[2]; if (voxelCount != expectedCount) { std::cerr << "Error: Voxel count mismatch. Expected " << expectedCount << ", found " << voxelCount << std::endl; return nullptr; } // Read all voxels for (size_t i = 0; i < voxelCount; ++i) { auto members = outgrid->voxels[i].members(); std::apply([&file](auto&... member) { ((file.read(reinterpret_cast(&member), sizeof(member))), ...); }, members); } file.close(); if (file.fail() && !file.eof()) { std::cerr << "Error: Failed to read from file: " << filename << std::endl; return nullptr; } std::cout << "Successfully loaded grid: " << dims[0] << " x " << dims[1] << " x " << dims[2] << std::endl; return outgrid; } #endif