Visualizer.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
5  * Karlsruhe Institute of Technology (KIT), all rights reserved.
6  *
7  * ArmarX is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * ArmarX is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  *
19  * @author Rainer Kartmann (rainer dot kartmann at student dot kit dot edu)
20  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21  * GNU General Public License
22  */
23 
24 #pragma once
25 
26 #include <thread>
27 
28 #include <Eigen/Geometry>
29 
30 #include <VirtualRobot/math/Helpers.h>
31 
33 
34 #include "VoxelGrid.hpp"
35 
36 namespace visionx::voxelgrid
37 {
38 
39  /**
40  * Visualizer for voxel grids of with voxel type VoxelT.
41  */
42  template <typename VoxelT>
43  class Visualizer
44  {
45  public:
46  /// Default constructor.
47  Visualizer();
48  /// Initialize with debug drawer and voxel grid.
50  const std::string& voxelLayer = "VoxelGrid");
51 
52  /// Virtual destructor.
53  virtual ~Visualizer()
54  {
55  }
56 
57  /// Clear the layer.
58  void clearLayer();
59  /// Clear the voxel layer.
60  void clearVoxelLayer(bool sleep = false);
61 
62  /// Draw the voxel grid.
63  void draw(const VoxelGrid<VoxelT>& grid);
64 
65  /// Draw the bounding edges of the voxel grid.
66  void drawBoundingEdges(const VoxelGrid<VoxelT>& grid);
67 
68  /// Draw the bounding edges of the voxel grid.
69  void drawStructure(const VoxelGrid<VoxelT>& grid,
70  float lineWidth = 1,
71  const armarx::DrawColor& colorEdges = {0, .5, 1, 1},
72  const armarx::DrawColor& colorStructure = {0, 1, 1, 1},
73  bool drawOriginVoxel = false);
74 
75  /// Set the debug drawer.
76  void
78  {
79  this->_debugDrawer = debugDrawer;
80  }
81 
82  /// Set the layer name.
83  void
84  setLayer(const std::string& layer)
85  {
86  this->_layer = layer;
87  }
88 
89  operator bool() const
90  {
91  return _debugDrawer.operator bool();
92  }
93 
94 
95  protected:
96  /// Information about a voxel about to-be-drawn.
98  {
99  const VoxelGrid<VoxelT>& grid; /// The voxel grid.
100  const std::string& name; /// A unique visu name for this voxel.
101 
102  std::size_t index; /// The voxel's index.
103  const VoxelT& voxel; /// The voxel.
104 
105  const Eigen::Vector3f& pos; /// The voxel's position.
106  const Eigen::Quaternionf& ori; /// The voxel's orientation.
107  const Eigen::Vector3f& extents; /// The voxel extents.
108  };
109 
110  /// Indicate whether a voxel shall be drawn.
111  /// Voxels for which this method returns false are not passed to drawVoxel().
112  virtual bool
113  isVisible(const VoxelVisuData& visu) const
114  {
115  (void)visu;
116  return true;
117  }
118 
119  /// Draw a voxel.
120  virtual void drawVoxel(const VoxelVisuData& visu);
121 
122  /// Get the debug drawer.
125  {
126  return _debugDrawer;
127  }
128 
130  drawer() const
131  {
132  return _debugDrawer;
133  }
134 
135  /// Get the layer name.
136  std::string
138  {
139  return _layer + "_voxels";
140  }
141 
142 
143  private:
144  /// The debug drawer.
145  armarx::DebugDrawerTopic _debugDrawer;
146 
147  /// The layer name.
148  std::string _layer;
149  };
150 
151  // IMPLEMENTATION
152 
153 
154  template <typename VT>
156  {
157  }
158 
159  template <typename VT>
161  const std::string& layer) :
162  _debugDrawer(debugDrawer), _layer(layer)
163  {
164  using namespace std::chrono_literals;
165  _debugDrawer.setLayer(layer);
166  _debugDrawer.setShortSleepDuration(100ms);
167  }
168 
169  template <typename VT>
170  void
172  {
173  _debugDrawer.clearLayer(_layer);
174  }
175 
176  template <typename VT>
177  void
179  {
180  _debugDrawer.clearLayer(getVoxelLayer(), sleep);
181  }
182 
183  template <typename VT>
184  void
186  {
187  if (!_debugDrawer)
188  {
189  return;
190  }
191 
192  std::vector<Eigen::Vector3f> points;
193  float width = 0.025f;
194  armarx::DrawColor color{0, 1, 1, 1};
195 
196  const Eigen::Matrix32f bb = grid.getLocalBoundingBox();
197  const Eigen::Matrix4f pose = grid.getPose();
198 
199  auto addLine = [&](int x1, int y1, int z1, int x2, int y2, int z2)
200  {
201  Eigen::Vector3f start = {bb.col(x1).x(), bb.col(y1).y(), bb.col(z1).z()};
202  Eigen::Vector3f end = {bb.col(x2).x(), bb.col(y2).y(), bb.col(z2).z()};
203 
204  start = math::Helpers::TransformPosition(pose, start);
205  end = math::Helpers::TransformPosition(pose, end);
206 
207  points.push_back({start.x(), start.y(), start.z()});
208  points.push_back({end.x(), end.y(), end.z()});
209  };
210 
211  /* 001 +-----+ 011
212  * /| 111/|
213  * 101 +-----+ |
214  * | +---|-+ 010
215  * |/000 |/
216  * 100 +-----+ 110
217  */
218 
219  // 000 -> 100, 010, 001
220  addLine(0, 0, 0, 1, 0, 0);
221  addLine(0, 0, 0, 0, 1, 0);
222  addLine(0, 0, 0, 0, 0, 1);
223 
224  // 111 -> 011, 101, 110
225  addLine(1, 1, 1, 0, 1, 1);
226  addLine(1, 1, 1, 1, 0, 1);
227  addLine(1, 1, 1, 1, 1, 0);
228 
229  // 100 -> 101, 110
230  addLine(1, 0, 0, 1, 0, 1);
231  addLine(1, 0, 0, 1, 1, 0);
232 
233  // 010 -> 110, 011
234  addLine(0, 1, 0, 1, 1, 0);
235  addLine(0, 1, 0, 0, 1, 1);
236 
237  // 001 -> 101, 011
238  addLine(0, 0, 1, 1, 0, 1);
239  addLine(0, 0, 1, 0, 1, 1);
240 
241  _debugDrawer.drawLineSet({_layer, "edges"}, points, width, color);
242  }
243 
244  template <typename VT>
245  void
247  float lineWidth,
248  const armarx::DrawColor& colorEdges,
249  const armarx::DrawColor& colorStructure,
250  bool drawOriginVoxel)
251  {
252  if (!_debugDrawer)
253  {
254  return;
255  }
256 
257  armarx::DebugDrawerLineSet lines;
258  lines.lineWidth = lineWidth;
259  lines.colorNoIntensity = colorStructure;
260  lines.colorFullIntensity = colorEdges;
261 
262  const Eigen::Matrix32f bb = grid.getLocalBoundingBox();
263  const Eigen::Matrix4f pose = grid.getPose();
264 
265  auto addLine = [&](const Eigen::Vector3f& startLocal,
266  const Eigen::Vector3f& endLocal,
267  float intensity = 1)
268  {
269  const Eigen::Vector3f start = math::Helpers::TransformPosition(pose, startLocal);
270  const Eigen::Vector3f end = math::Helpers::TransformPosition(pose, endLocal);
271 
272  lines.points.push_back({start.x(), start.y(), start.z()});
273  lines.points.push_back({end.x(), end.y(), end.z()});
274 
275  lines.intensities.push_back(intensity);
276  };
277 
278  auto addEdge = [&](int x1, int y1, int z1, int x2, int y2, int z2)
279  {
280  const Eigen::Vector3f start = {bb.col(x1).x(), bb.col(y1).y(), bb.col(z1).z()};
281  const Eigen::Vector3f end = {bb.col(x2).x(), bb.col(y2).y(), bb.col(z2).z()};
282  addLine(start, end, 1);
283  };
284 
285  /* 001 +-----+ 011
286  * /| 111/|
287  * 101 +-----+ |
288  * | +---|-+ 010
289  * |/000 |/
290  * 100 +-----+ 110
291  */
292 
293  // 000 -> 100, 010, 001
294  addEdge(0, 0, 0, 1, 0, 0);
295  addEdge(0, 0, 0, 0, 1, 0);
296  addEdge(0, 0, 0, 0, 0, 1);
297 
298  // 111 -> 011, 101, 110
299  addEdge(1, 1, 1, 0, 1, 1);
300  addEdge(1, 1, 1, 1, 0, 1);
301  addEdge(1, 1, 1, 1, 1, 0);
302 
303  // 100 -> 101, 110
304  addEdge(1, 0, 0, 1, 0, 1);
305  addEdge(1, 0, 0, 1, 1, 0);
306 
307  // 010 -> 110, 011
308  addEdge(0, 1, 0, 1, 1, 0);
309  addEdge(0, 1, 0, 0, 1, 1);
310 
311  // 001 -> 101, 011
312  addEdge(0, 0, 1, 1, 0, 1);
313  addEdge(0, 0, 1, 0, 1, 1);
314 
315  const auto min = bb.col(0);
316  const auto max = bb.col(1);
317 
318  auto addQuad = [&](const Eigen::Vector3f& center, int h1, int h2, float intensity = 0)
319  {
320  /* -/+ D----^----C +/+
321  * | h2| |
322  * | +---->
323  * | c h1 |
324  * -/- A---------B +/-
325  */
326 
327  Eigen::Vector3f A, B, C, D;
328  A = B = C = D = center;
329 
330  A(h1) = min(h1);
331  A(h2) = min(h2);
332 
333  B(h1) = max(h1);
334  B(h2) = min(h2);
335 
336  C(h1) = max(h1);
337  C(h2) = max(h2);
338 
339  D(h1) = min(h1);
340  D(h2) = max(h2);
341 
342  addLine(A, B, intensity);
343  addLine(B, C, intensity);
344  addLine(C, D, intensity);
345  addLine(D, A, intensity);
346  };
347 
348 
349  Eigen::Vector3i index = index.Zero();
350  Eigen::Vector3f center = center.Zero();
351 
352  const Eigen::Vector3i indicesMinMax[2] = {grid.getVoxelGridIndexMin(),
353  grid.getVoxelGridIndexMax()};
354 
355  for (int i = 0; i < 3; ++i)
356  {
357  int h1 = (i + 1) % 3;
358  int h2 = (i + 2) % 3;
359 
360  for (int mm : {0, 1}) // min / max
361  {
362  index(i) = indicesMinMax[mm](i);
363  center(i) = grid.getVoxelCenter(index, true)(i);
364 
365  // Shift: min => -size, max => +size
366  float shift = (mm == 0 ? -1 : +1) * grid.getVoxelSizes()(i);
367 
368  // Add quad at bounding edge (shift one voxel to center).
369  // (min => +shift, max => -shift)
370  center(i) -= shift;
371  addQuad(center, h1, h2);
372 
373  // Add quad at origin (at +- size/2 around origin).
374  center(i) = shift / 2;
375  addQuad(center, h1, h2);
376  }
377  if (grid.getGridSizes()(i) % 2 == 0)
378  {
379  // Also add a quad at origin for min of voxels at -1.
380  center(i) = -1.5 * grid.getVoxelSizes()(i);
381  addQuad(center, h1, h2);
382  }
383  }
384 
385  _debugDrawer.drawLineSet({_layer, "structure"}, lines);
386 
387  if (drawOriginVoxel)
388  {
389  _debugDrawer.drawBox({_layer, "origin_voxel"},
390  grid.getOrigin(),
391  grid.getOrientation(),
392  grid.getVoxelSizes(),
393  _debugDrawer.toDrawColor(colorEdges, .25));
394  }
395  }
396 
397  template <typename VoxelT>
398  void
400  {
401  if (!_debugDrawer)
402  {
403  return;
404  }
405 
406  for (std::size_t i = 0; i < grid.numVoxels(); ++i)
407  {
408  const VoxelT& voxel = grid.getVoxels()[i];
409  const Eigen::Vector3f center = grid.getVoxelCenter(i);
410 
411  VoxelVisuData visu{grid,
412  "voxel_" + std::to_string(i),
413  i,
414  voxel,
415  center,
416  grid.getOrientation(),
417  grid.getVoxelSizes()};
418 
419  if (isVisible(visu))
420  {
421  drawVoxel(visu);
422  }
423  }
424  }
425 
426  template <typename VoxelT>
427  void
428  Visualizer<VoxelT>::drawVoxel(const VoxelVisuData& visu)
429  {
430  const armarx::DrawColor color{.5, .5, .5, 1};
431  drawer().drawBox({getVoxelLayer(), visu.name}, visu.pos, visu.ori, visu.extents, color);
432  }
433 
434 } // namespace visionx::voxelgrid
visionx::voxelgrid::VoxelGrid< VoxelT >
armarx::DebugDrawerTopic
The DebugDrawerTopic wraps a DebugDrawerInterfacePrx and provides a more useful interface than the Ic...
Definition: DebugDrawerTopic.h:151
visionx::voxelgrid::Visualizer::clearVoxelLayer
void clearVoxelLayer(bool sleep=false)
Clear the voxel layer.
Definition: Visualizer.hpp:178
visionx::voxelgrid::Visualizer::VoxelVisuData
Information about a voxel about to-be-drawn.
Definition: Visualizer.hpp:97
index
uint8_t index
Definition: EtherCATFrame.h:59
visionx::voxelgrid::VoxelGrid::getVoxelSizes
Eigen::Vector3f getVoxelSizes() const
Get the voxel size.
Definition: VoxelGrid.hpp:211
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
visionx::voxelgrid::Visualizer::VoxelVisuData::pos
const Eigen::Vector3f & pos
The voxel.
Definition: Visualizer.hpp:105
visionx::voxelgrid::VoxelGrid::getPose
Eigen::Matrix4f getPose() const
Get the grid pose in the world frame.
Definition: VoxelGrid.hpp:363
visionx::voxelgrid::Visualizer::drawer
armarx::DebugDrawerTopic & drawer()
Get the debug drawer.
Definition: Visualizer.hpp:124
visionx::voxelgrid::Visualizer::VoxelVisuData::ori
const Eigen::Quaternionf & ori
The voxel's position.
Definition: Visualizer.hpp:106
visionx::voxelgrid::Visualizer
Visualizer for voxel grids of with voxel type VoxelT.
Definition: Visualizer.hpp:43
visionx::voxelgrid::Visualizer::drawBoundingEdges
void drawBoundingEdges(const VoxelGrid< VoxelT > &grid)
Draw the bounding edges of the voxel grid.
Definition: Visualizer.hpp:185
visionx::voxelgrid::Visualizer::drawStructure
void drawStructure(const VoxelGrid< VoxelT > &grid, float lineWidth=1, const armarx::DrawColor &colorEdges={0,.5, 1, 1}, const armarx::DrawColor &colorStructure={0, 1, 1, 1}, bool drawOriginVoxel=false)
Draw the bounding edges of the voxel grid.
Definition: Visualizer.hpp:246
visionx::voxelgrid
Definition: exceptions.cpp:7
DebugDrawerTopic.h
visionx::voxelgrid::VoxelGrid::numVoxels
std::size_t numVoxels() const
Get the number of voxels in the grid.
Definition: VoxelGrid.hpp:175
visionx::voxelgrid::Visualizer::clearLayer
void clearLayer()
Clear the layer.
Definition: Visualizer.hpp:171
visionx::voxelgrid::Visualizer::VoxelVisuData::index
std::size_t index
A unique visu name for this voxel.
Definition: Visualizer.hpp:102
visionx::voxelgrid::Visualizer::getVoxelLayer
std::string getVoxelLayer() const
Get the layer name.
Definition: Visualizer.hpp:137
visionx::voxelgrid::Visualizer::VoxelVisuData::voxel
const VoxelT & voxel
The voxel's index.
Definition: Visualizer.hpp:103
visionx::voxelgrid::Visualizer::VoxelVisuData::grid
const VoxelGrid< VoxelT > & grid
Definition: Visualizer.hpp:99
visionx::voxelgrid::Visualizer::isVisible
virtual bool isVisible(const VoxelVisuData &visu) const
Indicate whether a voxel shall be drawn.
Definition: Visualizer.hpp:113
armarx::DebugDrawerTopic::drawBox
void drawBox(const VisuID &id, const Eigen::Vector3f &position, const Eigen::Quaternionf &orientation, const Eigen::Vector3f &extents, const DrawColor &color=DEFAULTS.colorBox, bool ignoreLengthScale=false)
Draw a box.
Definition: DebugDrawerTopic.cpp:207
max
T max(T t1, T t2)
Definition: gdiam.h:51
visionx::voxelgrid::VoxelGrid::getVoxelGridIndexMax
Eigen::Vector3i getVoxelGridIndexMax() const
Get the maximal (along each axis) voxel grid index.
Definition: VoxelGrid.hpp:275
visionx::voxelgrid::VoxelGrid::getOrientation
Eigen::Quaternionf getOrientation() const
Get the grid orienation in the world frame.
Definition: VoxelGrid.hpp:321
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:41
visionx::voxelgrid::Visualizer::Visualizer
Visualizer()
Default constructor.
Definition: Visualizer.hpp:155
visionx::voxelgrid::Visualizer::setLayer
void setLayer(const std::string &layer)
Set the layer name.
Definition: Visualizer.hpp:84
visionx::voxelgrid::VoxelGrid::getOrigin
Eigen::Vector3f getOrigin() const
Get the grid origin in the world frame (center of voxel [0 0 0]).
Definition: VoxelGrid.hpp:305
A
class A(deque< T, A >)) ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T
Enables hashing of std::list.
visionx::voxelgrid::Visualizer::VoxelVisuData::extents
const Eigen::Vector3f & extents
The voxel's orientation.
Definition: Visualizer.hpp:107
visionx::voxelgrid::Visualizer::drawer
const armarx::DebugDrawerTopic & drawer() const
Definition: Visualizer.hpp:130
armarx::Quaternion< float, 0 >
visionx::voxelgrid::Visualizer::draw
void draw(const VoxelGrid< VoxelT > &grid)
Draw the voxel grid.
Definition: Visualizer.hpp:399
IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface >
visionx::voxelgrid::Visualizer::setDebugDrawer
void setDebugDrawer(const armarx::DebugDrawerInterfacePrx &debugDrawer)
Set the debug drawer.
Definition: Visualizer.hpp:77
visionx::voxelgrid::Visualizer::drawVoxel
virtual void drawVoxel(const VoxelVisuData &visu)
Draw a voxel.
Definition: Visualizer.hpp:428
visionx::voxelgrid::VoxelGrid::getVoxels
const std::vector< VoxelT > & getVoxels() const
Get the voxels.
Definition: VoxelGrid.hpp:156
visionx::voxelgrid::VoxelGrid::getGridSizes
Eigen::Vector3i getGridSizes() const
Get the grid size.
Definition: VoxelGrid.hpp:189
Eigen::Matrix
Definition: EigenForwardDeclarations.h:27
visionx::voxelgrid::VoxelGrid::getVoxelCenter
Eigen::Vector3f getVoxelCenter(std::size_t index, bool local=false) const
Get the center of the voxel with the given index.
Definition: VoxelGrid.hpp:282
min
T min(T t1, T t2)
Definition: gdiam.h:44
visionx::voxelgrid::Visualizer::~Visualizer
virtual ~Visualizer()
Virtual destructor.
Definition: Visualizer.hpp:53
visionx::voxelgrid::VoxelGrid::getLocalBoundingBox
Eigen::Matrix32f getLocalBoundingBox() const
Get the local axis aligned bounding box of the grid (minimal/maximal values in columns).
Definition: VoxelGrid.hpp:408
VoxelGrid.hpp
visionx::voxelgrid::VoxelGrid::getVoxelGridIndexMin
Eigen::Vector3i getVoxelGridIndexMin() const
Get the minimal (along each axis) voxel grid index.
Definition: VoxelGrid.hpp:268
visionx::voxelgrid::Visualizer::VoxelVisuData::name
const std::string & name
The voxel grid.
Definition: Visualizer.hpp:100