JsonIO.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <fstream>
4 #include <functional>
5 #include <iostream>
6 #include <map>
7 
8 #include <SimoxUtility/json/json.hpp>
9 
11 
12 #include "../VoxelGrid.hpp"
13 #include "to_from_json.h"
14 
15 namespace visionx::voxelgrid::io
16 {
17 
18  /// Function to get an attribute of a voxel.
19  template <class VoxelT>
20  using VoxelAttributeGetter = std::function<nlohmann::json(const VoxelT& voxel)>;
21  /// Function to set an attribute of a voxel.
22  template <class VoxelT>
23  using VoxelAttributeSetter = std::function<void(const nlohmann::json& j, VoxelT& voxel)>;
24 
25  /// Map of attribute name to attribute getter.
26  template <class VoxelT>
27  using VoxelAttributeGetterMap = std::map<std::string, VoxelAttributeGetter<VoxelT>>;
28  /// Map of attribute name to attribute setter.
29  template <class VoxelT>
30  using VoxelAttributeSetterMap = std::map<std::string, VoxelAttributeSetter<VoxelT>>;
31 
32  /// Make an attribute getter getting a member variable.
33  /// Usage: `makeGetter(&MyVoxel::myVar)`
34  template <class VoxelT, class MemberT>
36  makeGetter(MemberT VoxelT::*memberVariable)
37  {
38  return [memberVariable](const VoxelT& v) { return nlohmann::json(v.*memberVariable); };
39  }
40 
41  /// Make an attribute getter calling a member function.
42  /// Usage: `makeGetter(&MyVoxel::myGetter)`
43  template <class VoxelT, class MemberT>
44  static VoxelAttributeGetter<VoxelT>
45  makeGetter(MemberT (VoxelT::*memberFunc)() const)
46  {
47  return [memberFunc](const VoxelT& v) { return (v.*memberFunc)(); };
48  }
49 
50  /// Make an attribute setter setting a member variable.
51  /// Usage: `makeSetter(&MyVoxel::myVariable)`
52  template <class VoxelT, class MemberT>
53  static VoxelAttributeSetter<VoxelT>
54  makeSetter(MemberT VoxelT::*memberVariable)
55  {
56  return [memberVariable](const nlohmann::json& j, VoxelT& v)
57  { return v.*memberVariable = j.get<MemberT>(); };
58  }
59 
60  /// Make an attribute setter calling a member function.
61  /// Usage: `makeSetter(&MyVoxel::mySetter)`
62  template <class VoxelT, class MemberT>
63  static VoxelAttributeSetter<VoxelT>
64  makeSetter(void (VoxelT::*memberFunc)(const MemberT&))
65  {
66  return [memberFunc](const nlohmann::json& j, VoxelT& v)
67  { return (v.*memberFunc)(j.get<MemberT>()); };
68  }
69 
70  /**
71  * @brief Class to store voxel grids in a vectorized JSON format.
72  *
73  * The methods in class can be used to store voxel grids in JSON format.
74  * A voxel grid essentially consists of its structure (grid and voxel
75  * size, pose) and its voxel data.
76  *
77  * In the format produced by this class, there is one top-level JSON
78  * element for each voxel attribute to store. Each of this elements
79  * is an array storing the attribute value of each voxel.
80  *
81  * For example, if a voxel has two attributes, `int foo` and `float bar`,
82  * the produces JSON object would look like this:
83  * @code
84  * {
85  * "structure: { ... },
86  * "foo": [0 1 1 2 ... -1 0],
87  * "bar": [0.0, 1.0, 1.1, ... , 0.0, -1.0]
88  * }
89  * @endcode
90  *
91  * This is done to reduce the redundancy of JSON for a large number of voxels.
92  */
93  class JsonIO
94  {
95  public:
96  // WRITE
97 
98  /// Write a voxel grid to file.
99  template <class VoxelT>
100  static void
101  write(const std::string& filename,
102  const VoxelGrid<VoxelT>& grid,
103  const VoxelAttributeGetterMap<VoxelT>& attributeMap,
104  int indent = -1,
105  char indentChar = ' ')
106  {
107  writeJson(filename, toJson(grid, attributeMap), indent, indentChar);
108  }
109 
110  /// Write a voxel grid to `os`.
111  template <class VoxelT>
112  static void
113  write(std::ostream& os,
114  const VoxelGrid<VoxelT>& grid,
115  const VoxelAttributeGetterMap<VoxelT>& attributeMap,
116  int indent = -1,
117  char indentChar = ' ')
118  {
119  writeJson(os, toJson(grid, attributeMap), indent, indentChar);
120  }
121 
122  // READ
123 
124  /// Read a voxel grid from file.
125  template <class VoxelT>
126  static void
127  read(const std::string& filename,
128  VoxelGrid<VoxelT>& grid,
129  const VoxelAttributeGetterMap<VoxelT>& attributeMap)
130  {
131  fromJson(readJson(filename), grid, attributeMap);
132  }
133 
134  /// Read a voxel grid from file.
135  template <class VoxelT>
136  static VoxelGrid<VoxelT> read(const std::string& filename,
137  const VoxelAttributeGetterMap<VoxelT>& attributeMap);
138 
139  /// Read a voxel grid from `is`.
140  template <class VoxelT>
141  static void
142  read(std::istream& is,
143  VoxelGrid<VoxelT>& grid,
144  const VoxelAttributeGetterMap<VoxelT>& attributeMap)
145  {
146  fromJson(readJson(is), grid, attributeMap);
147  }
148 
149  /// Read a voxel grid from `is`.
150  template <class VoxelT>
151  static VoxelGrid<VoxelT> read(std::istream& is,
152  const VoxelAttributeGetterMap<VoxelT>& attributeMap);
153 
154 
155  // Grid -> JSON
156 
157  /// Serialize a voxel grid to JSON.
158  template <class VoxelT>
159  static void toJson(nlohmann::json& j,
160  const VoxelGrid<VoxelT>& grid,
161  const VoxelAttributeGetterMap<VoxelT>& attributeMap);
162 
163  /// Serialize a voxel grid to JSON.
164  template <class VoxelT>
165  static nlohmann::json toJson(const VoxelGrid<VoxelT>& grid,
166  const VoxelAttributeGetterMap<VoxelT>& attributeMap);
167 
168  /// Serialize a voxel grid to JSON with plain voxel array (with name `voxelArrayName`).
169  /// VoxelT must provide an implementation of `to_json()`.
170  template <class VoxelT>
171  static void toJson(nlohmann::json& j,
172  const VoxelGrid<VoxelT>& grid,
173  const std::string& voxelArrayName = "voxels");
174 
175  /// Serialize a voxel grid to JSON with plain voxel array (with name `voxelArrayName`).
176  /// VoxelT must provide an implementation of `to_json()`.
177  template <class VoxelT>
178  static nlohmann::json toJson(const VoxelGrid<VoxelT>& grid,
179  const std::string& voxelArrayName = "voxels");
180 
181 
182  // JSON -> Grid
183 
184  /// Deserialize a voxel grid from JSON.
185  template <class VoxelT>
186  static void fromJson(const nlohmann::json& j,
187  VoxelGrid<VoxelT>& grid,
188  const VoxelAttributeSetterMap<VoxelT>& attributeMap);
189 
190 
191  /// Deserialize a voxel grid from JSON with plain voxel array (with name `voxelArrayName`).
192  /// VoxelT must provide an implementation of `from_json()`.
193  template <class VoxelT>
194  static void fromJson(const nlohmann::json& j,
195  VoxelGrid<VoxelT>& grid,
196  const std::string& voxelArrayName = "voxels");
197 
198 
199  /// Write JSON json to file.
200  static void writeJson(const std::string& filename,
201  const nlohmann::json& j,
202  int indent = -1,
203  char indentChar = ' ');
204  /// Write JSON json to `os`.
205  static void writeJson(std::ostream& os,
206  const nlohmann::json& j,
207  int indent = -1,
208  char indentChar = ' ');
209 
210  /// Read JSON from file.
211  static nlohmann::json readJson(const std::string& filename);
212  /// Read JSON json `is`.
213  static nlohmann::json readJson(std::istream& is);
214  };
215 
216  template <class VoxelT>
218  JsonIO::read(const std::string& filename, const VoxelAttributeGetterMap<VoxelT>& attributeMap)
219  {
220  VoxelGrid<VoxelT> grid;
221  read(filename, grid, attributeMap);
222  return grid;
223  }
224 
225  template <class VoxelT>
227  JsonIO::read(std::istream& is, const VoxelAttributeGetterMap<VoxelT>& attributeMap)
228  {
229  VoxelGrid<VoxelT> grid;
230  read(is, grid, attributeMap);
231  return grid;
232  }
233 
234  template <class VoxelT>
235  nlohmann::json
237  const VoxelAttributeGetterMap<VoxelT>& attributeMap)
238  {
239  nlohmann::json j;
240  toJson(j, grid, attributeMap);
241  return j;
242  }
243 
244  template <class VoxelT>
245  void
246  JsonIO::toJson(nlohmann::json& j,
247  const VoxelGrid<VoxelT>& grid,
248  const VoxelAttributeGetterMap<VoxelT>& attributeMap)
249  {
250  // Serialize structure.
251  j["structure"] = grid.getStructure();
252 
253  // Serialize voxel data.
254 
255  // Insert array elements.
256  for (const auto& item : attributeMap)
257  {
258  j[item.first] = nlohmann::json::array();
259  }
260 
261  // Add data.
262  for (const VoxelT& voxel : grid)
263  {
264  for (const auto& item : attributeMap)
265  {
266  // Fetch serialized attribute from voxel.
267  j[item.first].push_back(item.second(voxel));
268  }
269  }
270  }
271 
272  template <class VoxelT>
273  void
274  JsonIO::toJson(nlohmann::json& j,
275  const VoxelGrid<VoxelT>& grid,
276  const std::string& voxelArrayName)
277  {
278  // Serialize structure.
279  j["structure"] = grid.getStructure();
280  // Serialize voxel data.
281  j[voxelArrayName] = grid.getVoxels();
282  }
283 
284  template <class VoxelT>
285  nlohmann::json
286  JsonIO::toJson(const VoxelGrid<VoxelT>& grid, const std::string& voxelArrayName)
287  {
288  nlohmann::json j;
289  toJson(j, grid, voxelArrayName);
290  return j;
291  }
292 
293  template <class VoxelT>
294  void
295  JsonIO::fromJson(const nlohmann::json& j,
296  VoxelGrid<VoxelT>& grid,
297  const VoxelAttributeSetterMap<VoxelT>& attributeMap)
298  {
299  // Deserialize structure.
300  grid.resetStructure(j.at("structure").get<VoxelGridStructure>());
301 
302  ARMARX_CHECK_EQUAL(grid.getVoxels().size(), grid.getStructure().getNumVoxels());
303 
304  // Deserialize voxel data.
305  for (std::size_t i = 0; i < grid.numVoxels(); ++i)
306  {
307  VoxelT& voxel = grid[i];
308  for (const auto& item : attributeMap)
309  {
310  // Deserialize and set voxel attribute.
311  item.second(j[item.first].at(i), voxel);
312  }
313  }
314  }
315 
316  template <class VoxelT>
317  void
318  JsonIO::fromJson(const nlohmann::json& j,
319  VoxelGrid<VoxelT>& grid,
320  const std::string& voxelArrayName)
321  {
322  // Deserialize structure.
323  grid.resetStructure(j.at("structure").get<VoxelGridStructure>());
324  ARMARX_CHECK_EQUAL(grid.getVoxels().size(), grid.getStructure().getNumVoxels());
325 
326  // Deserialize voxel data.
327  grid.setVoxels(j.at(voxelArrayName).get<std::vector<VoxelT>>());
328  }
329 
330 } // namespace visionx::voxelgrid::io
visionx::voxelgrid::io
Definition: BinaryIO.cpp:5
visionx::voxelgrid::io::JsonIO::read
static void read(const std::string &filename, VoxelGrid< VoxelT > &grid, const VoxelAttributeGetterMap< VoxelT > &attributeMap)
Read a voxel grid from file.
Definition: JsonIO.h:127
visionx::voxelgrid::io::JsonIO::fromJson
static void fromJson(const nlohmann::json &j, VoxelGrid< VoxelT > &grid, const VoxelAttributeSetterMap< VoxelT > &attributeMap)
Deserialize a voxel grid from JSON.
Definition: JsonIO.h:295
visionx::voxelgrid::VoxelGrid::setVoxels
void setVoxels(const std::vector< VoxelT > &voxels)
Set the voxels.
Definition: VoxelGrid.hpp:164
visionx::voxelgrid::io::VoxelAttributeGetter
std::function< nlohmann::json(const VoxelT &voxel)> VoxelAttributeGetter
Function to get an attribute of a voxel.
Definition: JsonIO.h:20
visionx::voxelgrid::VoxelGrid< VoxelT >
visionx::voxelgrid::io::JsonIO::toJson
static void toJson(nlohmann::json &j, const VoxelGrid< VoxelT > &grid, const VoxelAttributeGetterMap< VoxelT > &attributeMap)
Serialize a voxel grid to JSON.
Definition: JsonIO.h:246
visionx::voxelgrid::io::VoxelAttributeGetterMap
std::map< std::string, VoxelAttributeGetter< VoxelT > > VoxelAttributeGetterMap
Map of attribute name to attribute getter.
Definition: JsonIO.h:27
visionx::voxelgrid::io::JsonIO::read
static void read(std::istream &is, VoxelGrid< VoxelT > &grid, const VoxelAttributeGetterMap< VoxelT > &attributeMap)
Read a voxel grid from is.
Definition: JsonIO.h:142
visionx::voxelgrid::VoxelGrid::resetStructure
void resetStructure(const VoxelGridStructure &structure)
Set the voxel grid structure and reset voxel data.
Definition: VoxelGrid.hpp:94
visionx::voxelgrid::io::JsonIO::write
static void write(const std::string &filename, const VoxelGrid< VoxelT > &grid, const VoxelAttributeGetterMap< VoxelT > &attributeMap, int indent=-1, char indentChar=' ')
Write a voxel grid to file.
Definition: JsonIO.h:101
visionx::voxelgrid::io::JsonIO::writeJson
static void writeJson(const std::string &filename, const nlohmann::json &j, int indent=-1, char indentChar=' ')
Write JSON json to file.
Definition: JsonIO.cpp:8
visionx::voxelgrid::VoxelGrid::getStructure
VoxelGridStructure getStructure() const
Get the voxel grid structure.
Definition: VoxelGrid.hpp:87
visionx::voxelgrid::VoxelGrid::numVoxels
std::size_t numVoxels() const
Get the number of voxels in the grid.
Definition: VoxelGrid.hpp:175
visionx::voxelgrid::VoxelGridStructure
Geometric structure of a 3D voxel grid.
Definition: VoxelGridStructure.h:94
visionx::voxelgrid::io::JsonIO
Class to store voxel grids in a vectorized JSON format.
Definition: JsonIO.h:93
visionx::voxelgrid::io::JsonIO::readJson
static nlohmann::json readJson(const std::string &filename)
Read JSON from file.
Definition: JsonIO.cpp:24
visionx::voxelgrid::io::JsonIO::write
static void write(std::ostream &os, const VoxelGrid< VoxelT > &grid, const VoxelAttributeGetterMap< VoxelT > &attributeMap, int indent=-1, char indentChar=' ')
Write a voxel grid to os.
Definition: JsonIO.h:113
filename
std::string filename
Definition: VisualizationRobot.cpp:86
visionx::voxelgrid::io::VoxelAttributeSetterMap
std::map< std::string, VoxelAttributeSetter< VoxelT > > VoxelAttributeSetterMap
Map of attribute name to attribute setter.
Definition: JsonIO.h:30
ExpressionException.h
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
visionx::voxelgrid::VoxelGridStructure::getNumVoxels
std::size_t getNumVoxels() const
Get the number of voxels contained in the structure.
Definition: VoxelGridStructure.cpp:107
visionx::voxelgrid::VoxelGrid::getVoxels
const std::vector< VoxelT > & getVoxels() const
Get the voxels.
Definition: VoxelGrid.hpp:156
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
to_from_json.h
visionx::voxelgrid::io::VoxelAttributeSetter
std::function< void(const nlohmann::json &j, VoxelT &voxel)> VoxelAttributeSetter
Function to set an attribute of a voxel.
Definition: JsonIO.h:23