shape_operations.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2008, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Ioan Sucan */
36 
38 
39 #include <cstdio>
40 #include <cmath>
41 #include <algorithm>
42 #include <set>
43 #include <float.h>
44 
45 #include <console_bridge/console.h>
46 
47 #include <Eigen/Geometry>
48 
52 
53 namespace shapes
54 {
55 Shape* constructShapeFromMsg(const shape_msgs::Plane& shape_msg)
56 {
57  return new Plane(shape_msg.coef[0], shape_msg.coef[1], shape_msg.coef[2], shape_msg.coef[3]);
58 }
59 
60 Shape* constructShapeFromMsg(const shape_msgs::Mesh& shape_msg)
61 {
62  if (shape_msg.triangles.empty() || shape_msg.vertices.empty())
63  {
64  CONSOLE_BRIDGE_logWarn("Mesh definition is empty");
65  return nullptr;
66  }
67  else
68  {
69  EigenSTL::vector_Vector3d vertices(shape_msg.vertices.size());
70  std::vector<unsigned int> triangles(shape_msg.triangles.size() * 3);
71  for (unsigned int i = 0; i < shape_msg.vertices.size(); ++i)
72  vertices[i] = Eigen::Vector3d(shape_msg.vertices[i].x, shape_msg.vertices[i].y, shape_msg.vertices[i].z);
73  for (unsigned int i = 0; i < shape_msg.triangles.size(); ++i)
74  {
75  unsigned int i3 = i * 3;
76  triangles[i3++] = shape_msg.triangles[i].vertex_indices[0];
77  triangles[i3++] = shape_msg.triangles[i].vertex_indices[1];
78  triangles[i3] = shape_msg.triangles[i].vertex_indices[2];
79  }
80  return createMeshFromVertices(vertices, triangles);
81  }
82 }
83 
84 Shape* constructShapeFromMsg(const shape_msgs::SolidPrimitive& shape_msg)
85 {
86  Shape* shape = nullptr;
87  if (shape_msg.type == shape_msgs::SolidPrimitive::SPHERE)
88  {
89  if (shape_msg.dimensions.size() >=
91  shape = new Sphere(shape_msg.dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS]);
92  }
93  else if (shape_msg.type == shape_msgs::SolidPrimitive::BOX)
94  {
96  shape = new Box(shape_msg.dimensions[shape_msgs::SolidPrimitive::BOX_X],
97  shape_msg.dimensions[shape_msgs::SolidPrimitive::BOX_Y],
98  shape_msg.dimensions[shape_msgs::SolidPrimitive::BOX_Z]);
99  }
100  else if (shape_msg.type == shape_msgs::SolidPrimitive::CYLINDER)
101  {
102  if (shape_msg.dimensions.size() >=
104  shape = new Cylinder(shape_msg.dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS],
105  shape_msg.dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT]);
106  }
107  else if (shape_msg.type == shape_msgs::SolidPrimitive::CONE)
108  {
109  if (shape_msg.dimensions.size() >=
111  shape = new Cone(shape_msg.dimensions[shape_msgs::SolidPrimitive::CONE_RADIUS],
112  shape_msg.dimensions[shape_msgs::SolidPrimitive::CONE_HEIGHT]);
113  }
114  if (shape == nullptr)
115  CONSOLE_BRIDGE_logError("Unable to construct shape corresponding to shape_msg of type %d", (int)shape_msg.type);
116 
117  return shape;
118 }
119 
120 namespace
121 {
122 class ShapeVisitorAlloc : public boost::static_visitor<Shape*>
123 {
124 public:
125  Shape* operator()(const shape_msgs::Plane& shape_msg) const
126  {
127  return constructShapeFromMsg(shape_msg);
128  }
129 
130  Shape* operator()(const shape_msgs::Mesh& shape_msg) const
131  {
132  return constructShapeFromMsg(shape_msg);
133  }
134 
135  Shape* operator()(const shape_msgs::SolidPrimitive& shape_msg) const
136  {
137  return constructShapeFromMsg(shape_msg);
138  }
139 };
140 } // namespace
141 
143 {
144  return boost::apply_visitor(ShapeVisitorAlloc(), shape_msg);
145 }
146 
147 namespace
148 {
149 class ShapeVisitorMarker : public boost::static_visitor<void>
150 {
151 public:
152  ShapeVisitorMarker(visualization_msgs::Marker* marker, bool use_mesh_triangle_list)
153  : boost::static_visitor<void>(), use_mesh_triangle_list_(use_mesh_triangle_list), marker_(marker)
154  {
155  }
156 
157  void operator()(const shape_msgs::Plane& /* shape_msg */) const
158  {
159  throw std::runtime_error("No visual markers can be constructed for planes");
160  }
161 
162  void operator()(const shape_msgs::Mesh& shape_msg) const
163  {
165  }
166 
167  void operator()(const shape_msgs::SolidPrimitive& shape_msg) const
168  {
170  }
171 
172 private:
174  visualization_msgs::Marker* marker_;
175 };
176 } // namespace
177 
178 bool constructMarkerFromShape(const Shape* shape, visualization_msgs::Marker& marker, bool use_mesh_triangle_list)
179 {
180  ShapeMsg shape_msg;
181  if (constructMsgFromShape(shape, shape_msg))
182  {
183  bool ok = false;
184  try
185  {
186  boost::apply_visitor(ShapeVisitorMarker(&marker, use_mesh_triangle_list), shape_msg);
187  ok = true;
188  }
189  catch (std::runtime_error& ex)
190  {
191  CONSOLE_BRIDGE_logError("%s", ex.what());
192  }
193  if (ok)
194  return true;
195  }
196  return false;
197 }
198 
199 namespace
200 {
201 class ShapeVisitorComputeExtents : public boost::static_visitor<Eigen::Vector3d>
202 {
203 public:
204  Eigen::Vector3d operator()(const shape_msgs::Plane& /* shape_msg */) const
205  {
206  Eigen::Vector3d e(0.0, 0.0, 0.0);
207  return e;
208  }
209 
210  Eigen::Vector3d operator()(const shape_msgs::Mesh& shape_msg) const
211  {
212  double x_extent, y_extent, z_extent;
213  geometric_shapes::getShapeExtents(shape_msg, x_extent, y_extent, z_extent);
214  Eigen::Vector3d e(x_extent, y_extent, z_extent);
215  return e;
216  }
217 
218  Eigen::Vector3d operator()(const shape_msgs::SolidPrimitive& shape_msg) const
219  {
220  double x_extent, y_extent, z_extent;
221  geometric_shapes::getShapeExtents(shape_msg, x_extent, y_extent, z_extent);
222  Eigen::Vector3d e(x_extent, y_extent, z_extent);
223  return e;
224  }
225 };
226 } // namespace
227 
228 Eigen::Vector3d computeShapeExtents(const ShapeMsg& shape_msg)
229 {
230  return boost::apply_visitor(ShapeVisitorComputeExtents(), shape_msg);
231 }
232 
233 Eigen::Vector3d computeShapeExtents(const Shape* shape)
234 {
235  if (shape->type == SPHERE)
236  {
237  double d = static_cast<const Sphere*>(shape)->radius * 2.0;
238  return Eigen::Vector3d(d, d, d);
239  }
240  else if (shape->type == BOX)
241  {
242  const double* sz = static_cast<const Box*>(shape)->size;
243  return Eigen::Vector3d(sz[0], sz[1], sz[2]);
244  }
245  else if (shape->type == CYLINDER)
246  {
247  double d = static_cast<const Cylinder*>(shape)->radius * 2.0;
248  return Eigen::Vector3d(d, d, static_cast<const Cylinder*>(shape)->length);
249  }
250  else if (shape->type == CONE)
251  {
252  double d = static_cast<const Cone*>(shape)->radius * 2.0;
253  return Eigen::Vector3d(d, d, static_cast<const Cone*>(shape)->length);
254  }
255  else if (shape->type == MESH)
256  {
257  const Mesh* mesh = static_cast<const Mesh*>(shape);
258  if (mesh->vertex_count > 1)
259  {
260  std::vector<double> vmin(3, std::numeric_limits<double>::max());
261  std::vector<double> vmax(3, -std::numeric_limits<double>::max());
262  for (unsigned int i = 0; i < mesh->vertex_count; ++i)
263  {
264  unsigned int i3 = i * 3;
265  for (unsigned int k = 0; k < 3; ++k)
266  {
267  unsigned int i3k = i3 + k;
268  if (mesh->vertices[i3k] > vmax[k])
269  vmax[k] = mesh->vertices[i3k];
270  if (mesh->vertices[i3k] < vmin[k])
271  vmin[k] = mesh->vertices[i3k];
272  }
273  }
274  return Eigen::Vector3d(vmax[0] - vmin[0], vmax[1] - vmin[1], vmax[2] - vmin[2]);
275  }
276  else
277  return Eigen::Vector3d(0.0, 0.0, 0.0);
278  }
279  else
280  return Eigen::Vector3d(0.0, 0.0, 0.0);
281 }
282 
283 void computeShapeBoundingSphere(const Shape* shape, Eigen::Vector3d& center, double& radius)
284 {
285  center.x() = 0.0;
286  center.y() = 0.0;
287  center.z() = 0.0;
288  radius = 0.0;
289 
290  if (shape->type == SPHERE)
291  {
292  radius = static_cast<const Sphere*>(shape)->radius;
293  }
294  else if (shape->type == BOX)
295  {
296  const double* sz = static_cast<const Box*>(shape)->size;
297  double half_width = sz[0] * 0.5;
298  double half_height = sz[1] * 0.5;
299  double half_depth = sz[2] * 0.5;
300  radius = std::sqrt(half_width * half_width + half_height * half_height + half_depth * half_depth);
301  }
302  else if (shape->type == CYLINDER)
303  {
304  double cyl_radius = static_cast<const Cylinder*>(shape)->radius;
305  double half_len = static_cast<const Cylinder*>(shape)->length * 0.5;
306  radius = std::sqrt(cyl_radius * cyl_radius + half_len * half_len);
307  }
308  else if (shape->type == CONE)
309  {
310  double cone_radius = static_cast<const Cone*>(shape)->radius;
311  double cone_height = static_cast<const Cone*>(shape)->length;
312 
313  if (cone_height > cone_radius)
314  {
315  // center of sphere is intersection of perpendicular bisectors:
316  double z = (cone_height - (cone_radius * cone_radius / cone_height)) * 0.5;
317  center.z() = z - (cone_height * 0.5);
318  radius = cone_height - z;
319  }
320  else
321  {
322  // short cone. Bounding sphere touches base only.
323  center.z() = -(cone_height * 0.5);
324  radius = cone_radius;
325  }
326  }
327  else if (shape->type == MESH)
328  {
329  const Mesh* mesh = static_cast<const Mesh*>(shape);
330  if (mesh->vertex_count > 1)
331  {
332  double mx = std::numeric_limits<double>::max();
333  Eigen::Vector3d min(mx, mx, mx);
334  Eigen::Vector3d max(-mx, -mx, -mx);
335  unsigned int cnt = mesh->vertex_count * 3;
336  for (unsigned int i = 0; i < cnt; i += 3)
337  {
338  Eigen::Vector3d v(mesh->vertices[i + 0], mesh->vertices[i + 1], mesh->vertices[i + 2]);
339  min = min.cwiseMin(v);
340  max = max.cwiseMax(v);
341  }
342 
343  center = (min + max) * 0.5;
344  radius = (max - min).norm() * 0.5;
345  }
346  }
347 }
348 
349 bool constructMsgFromShape(const Shape* shape, ShapeMsg& shape_msg)
350 {
351  if (shape->type == SPHERE)
352  {
353  shape_msgs::SolidPrimitive s;
356  s.dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS] = static_cast<const Sphere*>(shape)->radius;
357  shape_msg = s;
358  }
359  else if (shape->type == BOX)
360  {
361  shape_msgs::SolidPrimitive s;
363  const double* sz = static_cast<const Box*>(shape)->size;
365  s.dimensions[shape_msgs::SolidPrimitive::BOX_X] = sz[0];
366  s.dimensions[shape_msgs::SolidPrimitive::BOX_Y] = sz[1];
367  s.dimensions[shape_msgs::SolidPrimitive::BOX_Z] = sz[2];
368  shape_msg = s;
369  }
370  else if (shape->type == CYLINDER)
371  {
372  shape_msgs::SolidPrimitive s;
375  s.dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS] = static_cast<const Cylinder*>(shape)->radius;
376  s.dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT] = static_cast<const Cylinder*>(shape)->length;
377  shape_msg = s;
378  }
379  else if (shape->type == CONE)
380  {
381  shape_msgs::SolidPrimitive s;
384  s.dimensions[shape_msgs::SolidPrimitive::CONE_RADIUS] = static_cast<const Cone*>(shape)->radius;
385  s.dimensions[shape_msgs::SolidPrimitive::CONE_HEIGHT] = static_cast<const Cone*>(shape)->length;
386  shape_msg = s;
387  }
388  else if (shape->type == PLANE)
389  {
390  shape_msgs::Plane s;
391  const Plane* p = static_cast<const Plane*>(shape);
392  s.coef[0] = p->a;
393  s.coef[1] = p->b;
394  s.coef[2] = p->c;
395  s.coef[3] = p->d;
396  shape_msg = s;
397  }
398  else if (shape->type == MESH)
399  {
400  shape_msgs::Mesh s;
401  const Mesh* mesh = static_cast<const Mesh*>(shape);
402  s.vertices.resize(mesh->vertex_count);
403  s.triangles.resize(mesh->triangle_count);
404 
405  for (unsigned int i = 0; i < mesh->vertex_count; ++i)
406  {
407  unsigned int i3 = i * 3;
408  s.vertices[i].x = mesh->vertices[i3];
409  s.vertices[i].y = mesh->vertices[i3 + 1];
410  s.vertices[i].z = mesh->vertices[i3 + 2];
411  }
412 
413  for (unsigned int i = 0; i < s.triangles.size(); ++i)
414  {
415  unsigned int i3 = i * 3;
416  s.triangles[i].vertex_indices[0] = mesh->triangles[i3];
417  s.triangles[i].vertex_indices[1] = mesh->triangles[i3 + 1];
418  s.triangles[i].vertex_indices[2] = mesh->triangles[i3 + 2];
419  }
420  shape_msg = s;
421  }
422  else
423  {
424  CONSOLE_BRIDGE_logError("Unable to construct shape message for shape of type %d", (int)shape->type);
425  return false;
426  }
427 
428  return true;
429 }
430 
431 void saveAsText(const Shape* shape, std::ostream& out)
432 {
433  if (shape->type == SPHERE)
434  {
435  out << Sphere::STRING_NAME << std::endl;
436  out << static_cast<const Sphere*>(shape)->radius << std::endl;
437  }
438  else if (shape->type == BOX)
439  {
440  out << Box::STRING_NAME << std::endl;
441  const double* sz = static_cast<const Box*>(shape)->size;
442  out << sz[0] << " " << sz[1] << " " << sz[2] << std::endl;
443  }
444  else if (shape->type == CYLINDER)
445  {
446  out << Cylinder::STRING_NAME << std::endl;
447  out << static_cast<const Cylinder*>(shape)->radius << " " << static_cast<const Cylinder*>(shape)->length
448  << std::endl;
449  }
450  else if (shape->type == CONE)
451  {
452  out << Cone::STRING_NAME << std::endl;
453  out << static_cast<const Cone*>(shape)->radius << " " << static_cast<const Cone*>(shape)->length << std::endl;
454  }
455  else if (shape->type == PLANE)
456  {
457  out << Plane::STRING_NAME << std::endl;
458  const Plane* p = static_cast<const Plane*>(shape);
459  out << p->a << " " << p->b << " " << p->c << " " << p->d << std::endl;
460  }
461  else if (shape->type == MESH)
462  {
463  out << Mesh::STRING_NAME << std::endl;
464  const Mesh* mesh = static_cast<const Mesh*>(shape);
465  out << mesh->vertex_count << " " << mesh->triangle_count << std::endl;
466 
467  for (unsigned int i = 0; i < mesh->vertex_count; ++i)
468  {
469  unsigned int i3 = i * 3;
470  out << mesh->vertices[i3] << " " << mesh->vertices[i3 + 1] << " " << mesh->vertices[i3 + 2] << std::endl;
471  }
472 
473  for (unsigned int i = 0; i < mesh->triangle_count; ++i)
474  {
475  unsigned int i3 = i * 3;
476  out << mesh->triangles[i3] << " " << mesh->triangles[i3 + 1] << " " << mesh->triangles[i3 + 2] << std::endl;
477  }
478  }
479  else
480  {
481  CONSOLE_BRIDGE_logError("Unable to save shape of type %d", (int)shape->type);
482  }
483 }
484 
485 Shape* constructShapeFromText(std::istream& in)
486 {
487  Shape* result = nullptr;
488  if (in.good() && !in.eof())
489  {
490  std::string type;
491  in >> type;
492  if (in.good() && !in.eof())
493  {
494  if (type == Sphere::STRING_NAME)
495  {
496  double radius;
497  in >> radius;
498  result = new Sphere(radius);
499  }
500  else if (type == Box::STRING_NAME)
501  {
502  double x, y, z;
503  in >> x >> y >> z;
504  result = new Box(x, y, z);
505  }
506  else if (type == Cylinder::STRING_NAME)
507  {
508  double r, l;
509  in >> r >> l;
510  result = new Cylinder(r, l);
511  }
512  else if (type == Cone::STRING_NAME)
513  {
514  double r, l;
515  in >> r >> l;
516  result = new Cone(r, l);
517  }
518  else if (type == Plane::STRING_NAME)
519  {
520  double a, b, c, d;
521  in >> a >> b >> c >> d;
522  result = new Plane(a, b, c, d);
523  }
524  else if (type == Mesh::STRING_NAME)
525  {
526  unsigned int v, t;
527  in >> v >> t;
528  Mesh* m = new Mesh(v, t);
529  result = m;
530  for (unsigned int i = 0; i < m->vertex_count; ++i)
531  {
532  unsigned int i3 = i * 3;
533  in >> m->vertices[i3] >> m->vertices[i3 + 1] >> m->vertices[i3 + 2];
534  }
535  for (unsigned int i = 0; i < m->triangle_count; ++i)
536  {
537  unsigned int i3 = i * 3;
538  in >> m->triangles[i3] >> m->triangles[i3 + 1] >> m->triangles[i3 + 2];
539  }
542  }
543  else
544  CONSOLE_BRIDGE_logError("Unknown shape type: '%s'", type.c_str());
545  }
546  }
547  return result;
548 }
549 
550 const std::string& shapeStringName(const Shape* shape)
551 {
552  static const std::string unknown = "unknown";
553  if (shape)
554  switch (shape->type)
555  {
556  case SPHERE:
557  return Sphere::STRING_NAME;
558  case CYLINDER:
559  return Cylinder::STRING_NAME;
560  case CONE:
561  return Cone::STRING_NAME;
562  case BOX:
563  return Box::STRING_NAME;
564  case PLANE:
565  return Plane::STRING_NAME;
566  case MESH:
567  return Mesh::STRING_NAME;
568  case OCTREE:
569  return OcTree::STRING_NAME;
570  default:
571  return unknown;
572  }
573  else
574  {
575  static const std::string empty;
576  return empty;
577  }
578 }
579 } // namespace shapes
d
Definition of various shapes. No properties such as position are included. These are simply the descr...
Definition of a cylinder Length is along z axis. Origin is at center of mass.
Definition: shapes.h:127
std::vector< Eigen::Vector3d, Eigen::aligned_allocator< Eigen::Vector3d > > vector_Vector3d
double b
Definition: shapes.h:381
ShapeType type
The type of the shape.
Definition: shapes.h:102
static const std::string STRING_NAME
The type of the shape, as a string.
Definition: shapes.h:139
double d
Definition: shapes.h:381
double c
Definition: shapes.h:381
unsigned int * triangles
The vertex indices for each triangle triangle k has vertices at index (3k, 3k+1, 3k+2) = (v1...
Definition: shapes.h:354
double y
Definition of a plane with equation ax + by + cz + d = 0.
Definition: shapes.h:366
double a
The plane equation is ax + by + cz + d = 0.
Definition: shapes.h:381
visualization_msgs::Marker * marker_
Definition of a cone Tip is on positive z axis. Center of base is on negative z axis. Origin is halway between tip and center of base.
Definition: shapes.h:178
unsigned int vertex_count
The number of available vertices.
Definition: shapes.h:343
Mesh * createMeshFromVertices(const EigenSTL::vector_Vector3d &vertices, const std::vector< unsigned int > &triangles)
Load a mesh from a set of vertices.
A basic definition of a shape. Shapes are considered centered at origin.
Definition: shapes.h:77
unsigned int triangle_count
The number of triangles formed with the vertices.
Definition: shapes.h:350
double z
double * vertices
The position for each vertex vertex k has values at index (3k, 3k+1, 3k+2) = (x,y,z)
Definition: shapes.h:347
void saveAsText(const Shape *shape, std::ostream &out)
Save all the information about this shape as plain text.
void computeVertexNormals()
Compute vertex normals by averaging from adjacent triangle normals.
Definition: shapes.cpp:526
bool constructMarkerFromShape(const Shape *shape, visualization_msgs::Marker &mk, bool use_mesh_triangle_list=false)
Construct the marker that corresponds to the shape. Return false on failure.
Shape * constructShapeFromMsg(const shape_msgs::SolidPrimitive &shape_msg)
Construct the shape that corresponds to the message. Return NULL on failure.
Definition of a sphere.
Definition: shapes.h:106
const std::string & shapeStringName(const Shape *shape)
Get the string name of the shape.
void computeTriangleNormals()
Compute the normals of each triangle from its vertices via cross product.
Definition: shapes.cpp:503
void computeShapeBoundingSphere(const Shape *shape, Eigen::Vector3d &center, double &radius)
Compute a sphere bounding a shape.
static const std::string STRING_NAME
The type of the shape, as a string.
Definition: shapes.h:373
static const std::string STRING_NAME
The type of the shape, as a string.
Definition: shapes.h:392
bool constructMsgFromShape(const Shape *shape, ShapeMsg &shape_msg)
Construct the message that corresponds to the shape. Return false on failure.
bool use_mesh_triangle_list_
Definition of a triangle mesh By convention the "center" of the shape is at the origin. For a mesh this implies that the AABB of the mesh is centered at the origin. Some methods may not work with arbitrary meshes whose AABB is not centered at the origin. Padding is not applied to vertices plainly coordinate-wise, but instead the padding value is added to the length of the direction vector between centroid and each vertex.
Definition: shapes.h:281
Definition of a box Aligned with the XYZ axes.
Definition: shapes.h:226
#define CONSOLE_BRIDGE_logError(fmt,...)
static const std::string STRING_NAME
The type of the shape, as a string.
Definition: shapes.h:292
void constructMarkerFromShape(const shape_msgs::Mesh &shape_msg, visualization_msgs::Marker &marker, bool use_mesh_triangle_list=true)
Convert a shape_msgs::Mesh shape_msg to a visualization_msgs::Marker marker.
Shape * constructShapeFromText(std::istream &in)
Construct a shape from plain text description.
void getShapeExtents(const shape_msgs::SolidPrimitive &shape_msg, double &x_extent, double &y_extent, double &z_extent)
Get the dimensions of an axis-aligned bounding box for the shape described by shape_msg.
static const std::string STRING_NAME
The type of the shape, as a string.
Definition: shapes.h:115
static const std::string STRING_NAME
The type of the shape, as a string.
Definition: shapes.h:236
Eigen::Vector3d computeShapeExtents(const ShapeMsg &shape_msg)
Compute the extents of a shape.
double x
r
static const std::string STRING_NAME
The type of the shape, as a string.
Definition: shapes.h:188
boost::variant< shape_msgs::SolidPrimitive, shape_msgs::Mesh, shape_msgs::Plane > ShapeMsg
Type that can hold any of the desired shape message types.
The number of dimensions of a particular shape.


geometric_shapes
Author(s): Ioan Sucan , Gil Jones
autogenerated on Fri Apr 14 2023 02:14:40