EasyNav Plugins
Loading...
Searching...
No Matches
serialization.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <stdio.h>
4
5#include <cstring>
6#include <exception>
7#include <fstream>
8#include <iostream>
9#include <type_traits>
10#include <typeinfo>
11
12#include "bonxai/bonxai.hpp"
13
14#ifdef __GNUG__
15#include <cxxabi.h>
16
17#include <cstdlib>
18#include <memory>
19#endif
20
21namespace Bonxai
22{
26template<typename DataT>
27inline void Serialize(std::ostream & out, const VoxelGrid<DataT> & grid);
28
30{
31 std::string type_name;
32 int inner_bits = 0;
33 int leaf_bits = 0;
34 double resolution = 0;
35};
36
43inline HeaderInfo GetHeaderInfo(std::string header);
44
49template<typename DataT>
50inline VoxelGrid<DataT> Deserialize(std::istream & input, HeaderInfo info);
51
52//---------------------------------------------------------
53namespace details
54{
55#ifdef __GNUG__
56inline std::string demangle(const char * name)
57{
58 int status = -4; // some arbitrary value to eliminate the compiler warning
59
60 std::unique_ptr<char, void (*)(void *)> res{
61 abi::__cxa_demangle(name, NULL, NULL, &status), std::free};
62 return (status == 0) ? res.get() : name;
63}
64
65#else
66
67// does nothing if not g++
68inline std::string demangle(const char * name)
69{
70 return name;
71}
72#endif
73
74} // namespace details
75
76template<typename T>
77inline void Write(std::ostream & out, const T & val)
78{
79 static_assert(std::is_trivially_copyable_v<T>, "Must be trivially copyable");
80 out.write(reinterpret_cast<const char *>(&val), sizeof(T));
81}
82
83template<typename DataT>
84inline void Serialize(std::ostream & out, const VoxelGrid<DataT> & grid)
85{
86 static_assert(std::is_trivially_copyable_v<DataT>, "DataT must be trivially copyable");
87
88 char header[256];
89 std::string type_name = details::demangle(typeid(DataT).name());
90
91 sprintf(
92 header, "Bonxai::VoxelGrid<%s,%d,%d>(%lf)\n", type_name.c_str(), grid.innetBits(),
93 grid.leafBits(), grid.voxelSize());
94
95 out.write(header, std::strlen(header));
96
97 //------------
98 Write(out, uint32_t(grid.rootMap().size()));
99
100 for (const auto & it : grid.rootMap()) {
101 const CoordT & root_coord = it.first;
102 Write(out, root_coord.x);
103 Write(out, root_coord.y);
104 Write(out, root_coord.z);
105
106 const auto & inner_grid = it.second;
107 for (size_t w = 0; w < inner_grid.mask().wordCount(); w++) {
108 Write(out, inner_grid.mask().getWord(w));
109 }
110 for (auto inner = inner_grid.mask().beginOn(); inner; ++inner) {
111 const uint32_t inner_index = *inner;
112 const auto & leaf_grid = *(inner_grid.cell(inner_index));
113
114 for (size_t w = 0; w < leaf_grid.mask().wordCount(); w++) {
115 Write(out, leaf_grid.mask().getWord(w));
116 }
117 for (auto leaf = leaf_grid.mask().beginOn(); leaf; ++leaf) {
118 const uint32_t leaf_index = *leaf;
119 Write(out, leaf_grid.cell(leaf_index));
120 }
121 }
122 }
123}
124
125template<typename T>
126inline T Read(std::istream & input)
127{
128 T out;
129 static_assert(std::is_trivially_copyable_v<T>, "Must be trivially copyable");
130 input.read(reinterpret_cast<char *>(&out), sizeof(T));
131 return out;
132}
133
134inline HeaderInfo GetHeaderInfo(std::string header)
135{
136 const std::string expected_prefix = "Bonxai::VoxelGrid<";
137 if (header.rfind(expected_prefix, 0) != 0) {
138 throw std::runtime_error("Header wasn't recognized");
139 }
140 int p1 = header.find(",", 18) + 1;
141 auto part_type = header.substr(18, p1 - 18 - 1);
142
143 int p2 = header.find(",", p1 + 1) + 1;
144 auto part_ibits = header.substr(p1, p2 - p1 - 1);
145
146 int p3 = header.find(">", p2) + 1;
147 auto part_lbits = header.substr(p2, p3 - p2 - 1);
148
149 int p4 = header.find("(", p3) + 1;
150 int p5 = header.find(")", p4);
151 auto part_res = header.substr(p4, p5 - p4);
152
153 HeaderInfo info;
154 info.type_name = part_type;
155 info.inner_bits = std::stoi(part_ibits);
156 info.leaf_bits = std::stoi(part_lbits);
157 info.resolution = std::stod(part_res);
158
159 return info;
160}
161
162template<typename DataT>
163inline VoxelGrid<DataT> Deserialize(std::istream & input, HeaderInfo info)
164{
165 std::string type_name = details::demangle(typeid(DataT).name());
166 if (type_name != info.type_name) {
167 throw std::runtime_error("DataT does not match");
168 }
169
170 //------------
171
172 VoxelGrid<DataT> grid(info.resolution, info.inner_bits, info.leaf_bits);
173
174 uint32_t root_count = Read<uint32_t>(input);
175
176 for (size_t root_index = 0; root_index < root_count; root_index++) {
177 CoordT root_coord;
178 root_coord.x = Read<int32_t>(input);
179 root_coord.y = Read<int32_t>(input);
180 root_coord.z = Read<int32_t>(input);
181
182 auto inner_it = grid.rootMap().find(root_coord);
183 if (inner_it == grid.rootMap().end()) {
184 inner_it = grid.rootMap()
185 .insert({root_coord, typename VoxelGrid<DataT>::InnerGrid(info.inner_bits)})
186 .first;
187 }
188 auto & inner_grid = inner_it->second;
189
190 for (size_t w = 0; w < inner_grid.mask().wordCount(); w++) {
191 uint64_t word = Read<uint64_t>(input);
192 inner_grid.mask().setWord(w, word);
193 }
194 for (auto inner = inner_grid.mask().beginOn(); inner; ++inner) {
195 auto & leaf_grid = inner_grid.cell(*inner);
196 leaf_grid = grid.allocateLeafGrid();
197
198 for (size_t w = 0; w < leaf_grid->mask().wordCount(); w++) {
199 uint64_t word = Read<uint64_t>(input);
200 leaf_grid->mask().setWord(w, word);
201 }
202 for (auto leaf = leaf_grid->mask().beginOn(); leaf; ++leaf) {
203 const uint32_t leaf_index = *leaf;
204 leaf_grid->cell(leaf_index) = Read<DataT>(input);
205 }
206 }
207 }
208 return grid;
209}
210
211} // namespace Bonxai
Definition bonxai.hpp:124
uint32_t innetBits() const
Definition bonxai.hpp:155
Grid< std::shared_ptr< LeafGrid > > InnerGrid
Definition bonxai.hpp:138
uint32_t leafBits() const
Definition bonxai.hpp:159
const RootMap & rootMap() const
Definition bonxai.hpp:168
double voxelSize() const
Definition bonxai.hpp:163
std::shared_ptr< LeafGrid > allocateLeafGrid()
Definition bonxai.hpp:610
Definition serialization.hpp:54
std::string demangle(const char *name)
Definition serialization.hpp:68
Definition bonxai.hpp:28
void Write(std::ostream &out, const T &val)
Definition serialization.hpp:77
void Serialize(std::ostream &out, const VoxelGrid< DataT > &grid)
Serialize a grid to ostream.
Definition serialization.hpp:84
T Read(std::istream &input)
Definition serialization.hpp:126
VoxelGrid< DataT > Deserialize(std::istream &input, HeaderInfo info)
Deserialize create a grid.
Definition serialization.hpp:163
HeaderInfo GetHeaderInfo(std::string header)
GetHeaderInfo is used to recover informations from the header of a file/stream.
Definition serialization.hpp:134
Definition grid_coord.hpp:67
int32_t z
Definition grid_coord.hpp:70
int32_t y
Definition grid_coord.hpp:69
int32_t x
Definition grid_coord.hpp:68
Definition serialization.hpp:30
double resolution
Definition serialization.hpp:34
std::string type_name
Definition serialization.hpp:31
int inner_bits
Definition serialization.hpp:32
int leaf_bits
Definition serialization.hpp:33