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