40 #include <console_bridge/console.h> 105 throw std::runtime_error(
"Sphere radius must be non-negative.");
119 throw std::runtime_error(
"Cylinder dimensions must be non-negative.");
134 throw std::runtime_error(
"Cone dimensions must be non-negative.");
148 if (x < 0 || y < 0 || z < 0)
149 throw std::runtime_error(
"Box dimensions must be non-negative.");
173 triangles =
new unsigned int[t_count * 3];
217 return new Sphere(radius);
222 return new Cylinder(radius, length);
227 return new Cone(radius, length);
232 return new Box(size[0], size[1], size[2]);
237 Mesh* dest =
new Mesh(vertex_count, triangle_count);
238 unsigned int n = 3 * vertex_count;
239 for (
unsigned int i = 0; i < n; ++i)
242 for (
unsigned int i = 0; i < n; ++i)
249 n = 3 * triangle_count;
250 for (
unsigned int i = 0; i < n; ++i)
251 dest->triangles[i] = triangles[i];
252 if (triangle_normals)
253 for (
unsigned int i = 0; i < n; ++i)
254 dest->triangle_normals[i] = triangle_normals[i];
257 delete[] dest->triangle_normals;
258 dest->triangle_normals =
nullptr;
265 return new Plane(a, b, c,
d);
275 CONSOLE_BRIDGE_logWarn(
"OcTrees cannot be scaled or padded");
280 CONSOLE_BRIDGE_logWarn(
"Planes cannot be scaled or padded");
295 const auto tmpRadius = radius * scale + padding;
297 throw std::runtime_error(
"Sphere radius must be non-negative.");
303 const auto tmpRadius = radius * scaleRadius + paddRadius;
304 const auto tmpLength = length * scaleLength + 2.0 * paddLength;
305 if (tmpRadius < 0 || tmpLength < 0)
306 throw std::runtime_error(
"Cylinder dimensions must be non-negative.");
326 void Cone::scaleAndPadd(
double scaleRadius,
double scaleLength,
double paddRadius,
double paddLength)
328 const auto tmpRadius = radius * scaleRadius + paddRadius;
329 const auto tmpLength = length * scaleLength + 2.0 * paddLength;
330 if (tmpRadius < 0 || tmpLength < 0)
331 throw std::runtime_error(
"Cone dimensions must be non-negative.");
351 void Box::scaleAndPadd(
double scaleX,
double scaleY,
double scaleZ,
double paddX,
double paddY,
double paddZ)
353 const auto tmpSize0 = size[0] * scaleX + paddX * 2.0;
354 const auto tmpSize1 = size[1] * scaleY + paddY * 2.0;
355 const auto tmpSize2 = size[2] * scaleZ + paddZ * 2.0;
356 if (tmpSize0 < 0 || tmpSize1 < 0 || tmpSize2 < 0)
357 throw std::runtime_error(
"Box dimensions must be non-negative.");
368 void Box::padd(
double paddX,
double paddY,
double paddZ)
378 void Mesh::scaleAndPadd(
double scaleX,
double scaleY,
double scaleZ,
double paddX,
double paddY,
double paddZ)
381 double sx = 0.0, sy = 0.0, sz = 0.0;
382 for (
unsigned int i = 0; i < vertex_count; ++i)
384 unsigned int i3 = i * 3;
386 sy += vertices[i3 + 1];
387 sz += vertices[i3 + 2];
389 sx /= (double)vertex_count;
390 sy /= (double)vertex_count;
391 sz /= (double)vertex_count;
394 for (
unsigned int i = 0; i < vertex_count; ++i)
396 unsigned int i3 = i * 3;
399 double dx = vertices[i3] - sx;
400 double dy = vertices[i3 + 1] - sy;
401 double dz = vertices[i3 + 2] - sz;
404 double norm = sqrt(dx * dx + dy * dy + dz * dz);
407 vertices[i3] = sx + dx * (scaleX + paddX / norm);
408 vertices[i3 + 1] = sy + dy * (scaleY + paddY / norm);
409 vertices[i3 + 2] = sz + dz * (scaleZ + paddZ / norm);
413 double ndx = ((dx > 0) ? dx + paddX : dx - paddX);
414 double ndy = ((dy > 0) ? dy + paddY : dy - paddY);
415 double ndz = ((dz > 0) ? dz + paddZ : dz - paddZ);
416 vertices[i3] = sx + ndx;
417 vertices[i3 + 1] = sy + ndy;
418 vertices[i3 + 2] = sz + ndz;
440 out <<
this << std::endl;
445 out <<
"Sphere[radius=" << radius <<
"]" << std::endl;
450 out <<
"Cylinder[radius=" << radius <<
", length=" << length <<
"]" << std::endl;
455 out <<
"Cone[radius=" << radius <<
", length=" << length <<
"]" << std::endl;
460 out <<
"Box[x=length=" << size[0] <<
", y=width=" << size[1] <<
"z=height=" << size[2] <<
"]" << std::endl;
465 out <<
"Mesh[vertices=" << vertex_count <<
", triangles=" << triangle_count <<
"]" << std::endl;
470 out <<
"Plane[a=" << a <<
", b=" << b <<
", c=" << c <<
", d=" <<
d <<
"]" << std::endl;
477 double minx, miny, minz, maxx, maxy, maxz;
478 octree->getMetricMin(minx, miny, minz);
479 octree->getMetricMax(maxx, maxy, maxz);
480 out <<
"OcTree[depth = " <<
octree->getTreeDepth() <<
", resolution = " <<
octree->getResolution()
481 <<
" inside box (minx=" << minx <<
", miny=" << miny <<
", minz=" << minz <<
", maxx=" << maxx
482 <<
", maxy=" << maxy <<
", maxz=" << maxz <<
")]" << std::endl;
485 out <<
"OcTree[NULL]" << std::endl;
505 if (triangle_count && !triangle_normals)
506 triangle_normals =
new double[triangle_count * 3];
509 for (
unsigned int i = 0; i < triangle_count; ++i)
511 unsigned int i3 = i * 3;
512 Eigen::Vector3d s1(vertices[triangles[i3] * 3] - vertices[triangles[i3 + 1] * 3],
513 vertices[triangles[i3] * 3 + 1] - vertices[triangles[i3 + 1] * 3 + 1],
514 vertices[triangles[i3] * 3 + 2] - vertices[triangles[i3 + 1] * 3 + 2]);
515 Eigen::Vector3d s2(vertices[triangles[i3 + 1] * 3] - vertices[triangles[i3 + 2] * 3],
516 vertices[triangles[i3 + 1] * 3 + 1] - vertices[triangles[i3 + 2] * 3 + 1],
517 vertices[triangles[i3 + 1] * 3 + 2] - vertices[triangles[i3 + 2] * 3 + 2]);
518 Eigen::Vector3d normal = s1.cross(s2);
520 triangle_normals[i3] = normal.x();
521 triangle_normals[i3 + 1] = normal.y();
522 triangle_normals[i3 + 2] = normal.z();
528 if (!triangle_normals)
529 computeTriangleNormals();
530 if (vertex_count && !vertex_normals)
531 vertex_normals =
new double[vertex_count * 3];
534 for (
unsigned int tIdx = 0; tIdx < triangle_count; ++tIdx)
536 unsigned int tIdx3 = 3 * tIdx;
537 unsigned int tIdx3_1 = tIdx3 + 1;
538 unsigned int tIdx3_2 = tIdx3 + 2;
540 unsigned int v1 = triangles[tIdx3];
541 unsigned int v2 = triangles[tIdx3_1];
542 unsigned int v3 = triangles[tIdx3_2];
544 avg_normals[v1][0] += triangle_normals[tIdx3];
545 avg_normals[v1][1] += triangle_normals[tIdx3_1];
546 avg_normals[v1][2] += triangle_normals[tIdx3_2];
548 avg_normals[v2][0] += triangle_normals[tIdx3];
549 avg_normals[v2][1] += triangle_normals[tIdx3_1];
550 avg_normals[v2][2] += triangle_normals[tIdx3_2];
552 avg_normals[v3][0] += triangle_normals[tIdx3];
553 avg_normals[v3][1] += triangle_normals[tIdx3_1];
554 avg_normals[v3][2] += triangle_normals[tIdx3_2];
556 for (std::size_t i = 0; i < avg_normals.size(); ++i)
558 if (avg_normals[i].squaredNorm() > 0.0)
559 avg_normals[i].normalize();
560 unsigned int i3 = i * 3;
561 vertex_normals[i3] = avg_normals[i][0];
562 vertex_normals[i3 + 1] = avg_normals[i][1];
563 vertex_normals[i3 + 2] = avg_normals[i][2];
569 const double thresholdSQR = threshold * threshold;
571 std::vector<unsigned int> vertex_map(vertex_count);
575 for (
unsigned int vIdx = 0; vIdx < vertex_count; ++vIdx)
577 orig_vertices[vIdx][0] = vertices[3 * vIdx];
578 orig_vertices[vIdx][1] = vertices[3 * vIdx + 1];
579 orig_vertices[vIdx][2] = vertices[3 * vIdx + 2];
580 vertex_map[vIdx] = vIdx;
583 for (
unsigned int vIdx1 = 0; vIdx1 < vertex_count; ++vIdx1)
585 if (vertex_map[vIdx1] != vIdx1)
588 vertex_map[vIdx1] = compressed_vertices.size();
589 compressed_vertices.push_back(orig_vertices[vIdx1]);
591 for (
unsigned int vIdx2 = vIdx1 + 1; vIdx2 < vertex_count; ++vIdx2)
593 double distanceSQR = (orig_vertices[vIdx1] - orig_vertices[vIdx2]).squaredNorm();
594 if (distanceSQR <= thresholdSQR)
595 vertex_map[vIdx2] = vertex_map[vIdx1];
599 if (compressed_vertices.size() == orig_vertices.size())
603 for (
unsigned int tIdx = 0; tIdx < triangle_count; ++tIdx)
605 unsigned int i3 = 3 * tIdx;
606 triangles[i3] = vertex_map[triangles[i3]];
607 triangles[i3 + 1] = vertex_map[triangles[i3 + 1]];
608 triangles[i3 + 2] = vertex_map[triangles[i3 + 2]];
611 vertex_count = compressed_vertices.size();
613 vertices =
new double[vertex_count * 3];
615 for (
unsigned int vIdx = 0; vIdx < vertex_count; ++vIdx)
617 unsigned int i3 = 3 * vIdx;
618 vertices[i3] = compressed_vertices[vIdx][0];
619 vertices[i3 + 1] = compressed_vertices[vIdx][1];
620 vertices[i3 + 2] = compressed_vertices[vIdx][2];
623 if (triangle_normals)
624 computeTriangleNormals();
626 computeVertexNormals();
Definition of various shapes. No properties such as position are included. These are simply the descr...
double radius
The radius of the cylinder.
Cylinder * clone() const override
Create a copy of this shape.
void scaleAndPadd(double scaleX, double scaleY, double scaleZ, double paddX, double paddY, double paddZ)
Scale this shape by a non-uniform factor and then add non-uniform padding.
void scale(double scaleX, double scaleY, double scaleZ)
Scale this shape by a non-uniform factor.
void scale(double scale)
Uniformly scale this shape by a factor.
void mergeVertices(double threshold)
Merge vertices that are very close to each other, up to a threshold.
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
void print(std::ostream &out=std::cout) const override
Print information about this shape.
double length
The length (height) of the cone.
Sphere * clone() const override
Create a copy of this shape.
double size[3]
x, y, z dimensions of the box (axis-aligned)
Plane * clone() const override
Create a copy of this shape.
ShapeType type
The type of the shape.
static double distanceSQR(const Eigen::Vector3d &p, const Eigen::Vector3d &origin, const Eigen::Vector3d &dir)
Compute the square of the distance between a ray and a point Note: this requires 'dir' to be normaliz...
double radius
The radius of the cone.
static const std::string STRING_NAME
The type of the shape, as a string.
double length
The length of the cylinder.
void scale(double scaleX, double scaleY, double scaleZ)
Scale this shape by a non-uniform factor.
void scaleAndPadd(double scale, double padd) override
Uniformly scale and padd this shape.
unsigned int * triangles
The vertex indices for each triangle triangle k has vertices at index (3k, 3k+1, 3k+2) = (v1...
void scaleAndPadd(double scale, double padd) override
Uniformly scale and padd this shape.
void print(std::ostream &out=std::cout) const override
Print information about this shape.
Definition of a plane with equation ax + by + cz + d = 0.
double a
The plane equation is ax + by + cz + d = 0.
void padd(double paddRadius, double paddLength)
Add non-uniform padding to this shape.
double * vertex_normals
The normal to each vertex; unit vector represented as (x,y,z); If missing from the mesh...
Representation of an octomap::OcTree as a Shape.
std::ostream & operator<<(std::ostream &ss, ShapeType type)
std::shared_ptr< const octomap::OcTree > octree
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.
void padd(double padding)
Add uniform padding to this shape.
A basic definition of a shape. Shapes are considered centered at origin.
void padd(double paddX, double paddY, double paddZ)
Add non-uniform padding to this shape.
OcTree * clone() const override
Create a copy of this shape.
void scale(double scaleRadius, double scaleLength)
Scale this shape by a non-uniform factor.
bool isFixed() const override
Return a flag indicating whether this shape can be scaled and/or padded.
unsigned int triangle_count
The number of triangles formed with the vertices.
virtual bool isFixed() const
Return a flag indicating whether this shape can be scaled and/or padded.
ShapeType
A list of known shape types.
double * vertices
The position for each vertex vertex k has values at index (3k, 3k+1, 3k+2) = (x,y,z)
Cone * clone() const override
Create a copy of this shape.
double * triangle_normals
The normal to each triangle; unit vector represented as (x,y,z); If missing from the mesh...
void print(std::ostream &out=std::cout) const override
Print information about this shape.
void computeVertexNormals()
Compute vertex normals by averaging from adjacent triangle normals.
void print(std::ostream &out=std::cout) const override
Print information about this shape.
void print(std::ostream &out=std::cout) const override
Print information about this shape.
void computeTriangleNormals()
Compute the normals of each triangle from its vertices via cross product.
static const std::string STRING_NAME
The type of the shape, as a string.
void scaleAndPadd(double scaleRadius, double scaleLength, double paddRadius, double paddLength)
Scale this shape by a non-uniform factor and then add non-uniform padding.
static const std::string STRING_NAME
The type of the shape, as a string.
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.
void scaleAndPadd(double scaleX, double scaleY, double scaleZ, double paddX, double paddY, double paddZ)
Scale this shape by a non-uniform factor and then add non-uniform padding.
void padd(double paddX, double paddY, double paddZ)
Add non-uniform padding to this shape.
void padd(double paddRadius, double paddLength)
Add non-uniform padding to this shape.
static const std::string STRING_NAME
The type of the shape, as a string.
void scale(double scaleRadius, double scaleLength)
Scale this shape by a non-uniform factor.
bool isFixed() const override
Return a flag indicating whether this shape can be scaled and/or padded.
Box * clone() const override
Create a copy of this shape.
double radius
The radius of the sphere.
void print(std::ostream &out=std::cout) const override
Print information about this shape.
void print(std::ostream &out=std::cout) const override
Print information about this shape.
static const std::string STRING_NAME
The type of the shape, as a string.
virtual void print(std::ostream &out=std::cout) const
Print information about this shape.
void scaleAndPadd(double scale, double padd) override
Uniformly scale and padd this shape.
static const std::string STRING_NAME
The type of the shape, as a string.
Mesh * clone() const override
Create a copy of this shape.
void scaleAndPadd(double scaleRadius, double scaleLength, double paddRadius, double paddLength)
Scale this shape by a non-uniform factor and then add non-uniform padding.
static const std::string STRING_NAME
The type of the shape, as a string.