45 #include <console_bridge/console.h> 47 #include <Eigen/Geometry> 57 return new Plane(shape_msg.coef[0], shape_msg.coef[1], shape_msg.coef[2], shape_msg.coef[3]);
62 if (shape_msg.triangles.empty() || shape_msg.vertices.empty())
64 CONSOLE_BRIDGE_logWarn(
"Mesh definition is empty");
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)
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];
86 Shape* shape =
nullptr;
89 if (shape_msg.dimensions.size() >=
91 shape =
new Sphere(shape_msg.dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS]);
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]);
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]);
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]);
114 if (shape ==
nullptr)
115 CONSOLE_BRIDGE_logError(
"Unable to construct shape corresponding to shape_msg of type %d", (
int)shape_msg.type);
122 class ShapeVisitorAlloc :
public boost::static_visitor<Shape*>
125 Shape* operator()(
const shape_msgs::Plane& shape_msg)
const 130 Shape* operator()(
const shape_msgs::Mesh& shape_msg)
const 135 Shape* operator()(
const shape_msgs::SolidPrimitive& shape_msg)
const 144 return boost::apply_visitor(ShapeVisitorAlloc(), shape_msg);
149 class ShapeVisitorMarker :
public boost::static_visitor<void>
152 ShapeVisitorMarker(visualization_msgs::Marker* marker,
bool use_mesh_triangle_list)
157 void operator()(
const shape_msgs::Plane& )
const 159 throw std::runtime_error(
"No visual markers can be constructed for planes");
162 void operator()(
const shape_msgs::Mesh& shape_msg)
const 167 void operator()(
const shape_msgs::SolidPrimitive& shape_msg)
const 186 boost::apply_visitor(ShapeVisitorMarker(&marker, use_mesh_triangle_list), shape_msg);
189 catch (std::runtime_error& ex)
201 class ShapeVisitorComputeExtents :
public boost::static_visitor<Eigen::Vector3d>
204 Eigen::Vector3d operator()(
const shape_msgs::Plane& )
const 206 Eigen::Vector3d e(0.0, 0.0, 0.0);
210 Eigen::Vector3d operator()(
const shape_msgs::Mesh& shape_msg)
const 212 double x_extent, y_extent, z_extent;
214 Eigen::Vector3d e(x_extent, y_extent, z_extent);
218 Eigen::Vector3d operator()(
const shape_msgs::SolidPrimitive& shape_msg)
const 220 double x_extent, y_extent, z_extent;
222 Eigen::Vector3d e(x_extent, y_extent, z_extent);
230 return boost::apply_visitor(ShapeVisitorComputeExtents(), shape_msg);
237 double d =
static_cast<const Sphere*
>(shape)->radius * 2.0;
238 return Eigen::Vector3d(d, d, d);
242 const double* sz =
static_cast<const Box*
>(shape)->size;
243 return Eigen::Vector3d(sz[0], sz[1], sz[2]);
247 double d =
static_cast<const Cylinder*
>(shape)->radius * 2.0;
248 return Eigen::Vector3d(d, d, static_cast<const Cylinder*>(shape)->length);
252 double d =
static_cast<const Cone*
>(shape)->radius * 2.0;
253 return Eigen::Vector3d(d, d, static_cast<const Cone*>(shape)->length);
257 const Mesh* mesh =
static_cast<const Mesh*
>(shape);
260 std::vector<double> vmin(3, std::numeric_limits<double>::max());
261 std::vector<double> vmax(3, -std::numeric_limits<double>::max());
264 unsigned int i3 = i * 3;
265 for (
unsigned int k = 0; k < 3; ++k)
267 unsigned int i3k = i3 + k;
274 return Eigen::Vector3d(vmax[0] - vmin[0], vmax[1] - vmin[1], vmax[2] - vmin[2]);
277 return Eigen::Vector3d(0.0, 0.0, 0.0);
280 return Eigen::Vector3d(0.0, 0.0, 0.0);
292 radius =
static_cast<const Sphere*
>(shape)->radius;
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);
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);
310 double cone_radius =
static_cast<const Cone*
>(shape)->radius;
311 double cone_height =
static_cast<const Cone*
>(shape)->length;
313 if (cone_height > cone_radius)
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;
323 center.z() = -(cone_height * 0.5);
324 radius = cone_radius;
329 const Mesh* mesh =
static_cast<const Mesh*
>(shape);
332 double mx = std::numeric_limits<double>::max();
333 Eigen::Vector3d min(mx, mx, mx);
334 Eigen::Vector3d max(-mx, -mx, -mx);
336 for (
unsigned int i = 0; i < cnt; i += 3)
339 min = min.cwiseMin(v);
340 max = max.cwiseMax(v);
343 center = (min + max) * 0.5;
344 radius = (max - min).norm() * 0.5;
353 shape_msgs::SolidPrimitive s;
356 s.dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS] =
static_cast<const Sphere*
>(shape)->radius;
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];
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;
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;
391 const Plane* p =
static_cast<const Plane*
>(shape);
401 const Mesh* mesh =
static_cast<const Mesh*
>(shape);
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];
413 for (
unsigned int i = 0; i < s.triangles.size(); ++i)
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];
436 out << static_cast<const Sphere*>(shape)->radius << std::endl;
441 const double* sz =
static_cast<const Box*
>(shape)->size;
442 out << sz[0] <<
" " << sz[1] <<
" " << sz[2] << std::endl;
447 out << static_cast<const Cylinder*>(shape)->radius <<
" " << static_cast<const Cylinder*>(shape)->length
453 out << static_cast<const Cone*>(shape)->radius <<
" " << static_cast<const Cone*>(shape)->length << std::endl;
458 const Plane* p =
static_cast<const Plane*
>(shape);
459 out << p->
a <<
" " << p->
b <<
" " << p->
c <<
" " << p->
d << std::endl;
464 const Mesh* mesh =
static_cast<const Mesh*
>(shape);
469 unsigned int i3 = i * 3;
475 unsigned int i3 = i * 3;
487 Shape* result =
nullptr;
488 if (in.good() && !in.eof())
492 if (in.good() && !in.eof())
498 result =
new Sphere(radius);
504 result =
new Box(x, y, z);
516 result =
new Cone(r, l);
521 in >> a >> b >> c >> d;
522 result =
new Plane(a, b, c, d);
532 unsigned int i3 = i * 3;
537 unsigned int i3 = i * 3;
552 static const std::string unknown =
"unknown";
575 static const std::string empty;
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.
std::vector< Eigen::Vector3d, Eigen::aligned_allocator< Eigen::Vector3d > > vector_Vector3d
ShapeType type
The type of the shape.
static const std::string STRING_NAME
The type of the shape, as a string.
unsigned int * triangles
The vertex indices for each triangle triangle k has vertices at index (3k, 3k+1, 3k+2) = (v1...
Definition of a plane with equation ax + by + cz + d = 0.
double a
The plane equation is ax + by + cz + d = 0.
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.
unsigned int vertex_count
The number of available vertices.
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.
unsigned int triangle_count
The number of triangles formed with the vertices.
double * vertices
The position for each vertex vertex k has values at index (3k, 3k+1, 3k+2) = (x,y,z)
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.
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.
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.
void computeShapeBoundingSphere(const Shape *shape, Eigen::Vector3d ¢er, double &radius)
Compute a sphere bounding a shape.
static const std::string STRING_NAME
The type of the shape, as a string.
static const std::string STRING_NAME
The type of the shape, as a string.
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 of a box Aligned with the XYZ axes.
static const std::string STRING_NAME
The type of the shape, as a string.
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.
static const std::string STRING_NAME
The type of the shape, as a string.
Eigen::Vector3d computeShapeExtents(const ShapeMsg &shape_msg)
Compute the extents of a shape.
static const std::string STRING_NAME
The type of the shape, as a string.
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.