40 #include <console_bridge/console.h> 
  102 Sphere::Sphere(
double r) : Shape()
 
  105     throw std::runtime_error(
"Sphere radius must be non-negative.");
 
  110 Cylinder::Cylinder() : Shape()
 
  113   length = radius = 0.0;
 
  116 Cylinder::Cylinder(
double r, 
double l) : Shape()
 
  119     throw std::runtime_error(
"Cylinder dimensions must be non-negative.");
 
  125 Cone::Cone() : 
Shape()
 
  128   length = radius = 0.0;
 
  134     throw std::runtime_error(
"Cone dimensions must be non-negative.");
 
  143   size[0] = size[1] = size[2] = 0.0;
 
  148   if (
x < 0 || 
y < 0 || 
z < 0)
 
  149     throw std::runtime_error(
"Box dimensions must be non-negative.");
 
  163   triangle_normals = 
nullptr;
 
  164   vertex_normals = 
nullptr;
 
  170   vertex_count = v_count;
 
  171   vertices = 
new double[v_count * 3];
 
  172   triangle_count = t_count;
 
  173   triangles = 
new unsigned int[t_count * 3];
 
  174   triangle_normals = 
new double[t_count * 3];
 
  175   vertex_normals = 
new double[v_count * 3];
 
  196 Plane::Plane(
double pa, 
double pb, 
double pc, 
double pd) : Shape()
 
  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)
 
  252   if (triangle_normals)
 
  253     for (
unsigned int i = 0; i < n; ++i)
 
  263 Plane* Plane::clone()
 const 
  265   return new Plane(a, b, c, 
d);
 
  268 OcTree* OcTree::clone()
 const 
  270   return new OcTree(octree);
 
  273 void OcTree::scaleAndPadd(
double , 
double )
 
  275   CONSOLE_BRIDGE_logWarn(
"OcTrees cannot be scaled or padded");
 
  278 void Plane::scaleAndPadd(
double , 
double )
 
  280   CONSOLE_BRIDGE_logWarn(
"Planes cannot be scaled or padded");
 
  283 void Shape::scale(
double scale)
 
  285   scaleAndPadd(scale, 0.0);
 
  288 void Shape::padd(
double padding)
 
  290   scaleAndPadd(1.0, padding);
 
  293 void Sphere::scaleAndPadd(
double scale, 
double padding)
 
  295   const auto tmpRadius = radius * scale + padding;
 
  297     throw std::runtime_error(
"Sphere radius must be non-negative.");
 
  301 void Cylinder::scaleAndPadd(
double scaleRadius, 
double scaleLength, 
double paddRadius, 
double paddLength)
 
  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.");
 
  311 void Cylinder::scale(
double scaleRadius, 
double scaleLength)
 
  313   scaleAndPadd(scaleRadius, scaleLength, 0.0, 0.0);
 
  316 void Cylinder::padd(
double paddRadius, 
double paddLength)
 
  318   scaleAndPadd(1.0, 1.0, paddRadius, paddLength);
 
  321 void Cylinder::scaleAndPadd(
double scale, 
double padd)
 
  323   scaleAndPadd(scale, scale, padd, padd);
 
  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.");
 
  336 void Cone::scale(
double scaleRadius, 
double scaleLength)
 
  338   scaleAndPadd(scaleRadius, scaleLength, 0.0, 0.0);
 
  341 void Cone::padd(
double paddRadius, 
double paddLength)
 
  343   scaleAndPadd(1.0, 1.0, paddRadius, paddLength);
 
  346 void Cone::scaleAndPadd(
double scale, 
double padd)
 
  348   scaleAndPadd(scale, scale, padd, padd);
 
  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.");
 
  363 void Box::scale(
double scaleX, 
double scaleY, 
double scaleZ)
 
  365   scaleAndPadd(scaleX, scaleY, scaleZ, 0.0, 0.0, 0.0);
 
  368 void Box::padd(
double paddX, 
double paddY, 
double paddZ)
 
  370   scaleAndPadd(1.0, 1.0, 1.0, paddX, paddY, paddZ);
 
  373 void Box::scaleAndPadd(
double scale, 
double padd)
 
  375   scaleAndPadd(scale, scale, scale, padd, padd, padd);
 
  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 scaledX = sx + dx * scaleX;
 
  405     double scaledY = sy + dy * scaleY;
 
  406     double scaledZ = sz + dz * scaleZ;
 
  408     vertices[i3] = scaledX + vertex_normals[i3] * paddX;
 
  409     vertices[i3 + 1] = scaledY + vertex_normals[i3 + 1] * paddY;
 
  410     vertices[i3 + 2] = scaledZ + vertex_normals[i3 + 2] * paddZ;
 
  414 void Mesh::scale(
double scaleX, 
double scaleY, 
double scaleZ)
 
  416   scaleAndPadd(scaleX, scaleY, scaleZ, 0.0, 0.0, 0.0);
 
  419 void Mesh::padd(
double paddX, 
double paddY, 
double paddZ)
 
  421   scaleAndPadd(1.0, 1.0, 1.0, paddX, paddY, paddZ);
 
  424 void Mesh::scaleAndPadd(
double scale, 
double padd)
 
  426   scaleAndPadd(scale, scale, scale, padd, padd, padd);
 
  429 void Shape::print(std::ostream& out)
 const 
  431   out << 
this << std::endl;
 
  434 void Sphere::print(std::ostream& out)
 const 
  436   out << 
"Sphere[radius=" << radius << 
"]" << std::endl;
 
  439 void Cylinder::print(std::ostream& out)
 const 
  441   out << 
"Cylinder[radius=" << radius << 
", length=" << length << 
"]" << std::endl;
 
  444 void Cone::print(std::ostream& out)
 const 
  446   out << 
"Cone[radius=" << radius << 
", length=" << length << 
"]" << std::endl;
 
  449 void Box::print(std::ostream& out)
 const 
  451   out << 
"Box[x=length=" << size[0] << 
", y=width=" << size[1] << 
"z=height=" << size[2] << 
"]" << std::endl;
 
  454 void Mesh::print(std::ostream& out)
 const 
  456   out << 
"Mesh[vertices=" << vertex_count << 
", triangles=" << triangle_count << 
"]" << std::endl;
 
  459 void Plane::print(std::ostream& out)
 const 
  461   out << 
"Plane[a=" << a << 
", b=" << b << 
", c=" << c << 
", d=" << 
d << 
"]" << std::endl;
 
  464 void OcTree::print(std::ostream& out)
 const 
  468     double minx, miny, minz, maxx, maxy, maxz;
 
  469     octree->getMetricMin(minx, miny, minz);
 
  470     octree->getMetricMax(maxx, maxy, maxz);
 
  471     out << 
"OcTree[depth = " << octree->getTreeDepth() << 
", resolution = " << octree->getResolution()
 
  472         << 
" inside box (minx=" << minx << 
", miny=" << miny << 
", minz=" << minz << 
", maxx=" << maxx
 
  473         << 
", maxy=" << maxy << 
", maxz=" << maxz << 
")]" << std::endl;
 
  476     out << 
"OcTree[NULL]" << std::endl;
 
  479 bool Shape::isFixed()
 const 
  484 bool OcTree::isFixed()
 const 
  489 bool Plane::isFixed()
 const 
  494 void Mesh::computeTriangleNormals()
 
  496   if (triangle_count && !triangle_normals)
 
  497     triangle_normals = 
new double[triangle_count * 3];
 
  500   for (
unsigned int i = 0; i < triangle_count; ++i)
 
  502     unsigned int i3 = i * 3;
 
  503     Eigen::Vector3d s1(vertices[triangles[i3] * 3] - vertices[triangles[i3 + 1] * 3],
 
  504                        vertices[triangles[i3] * 3 + 1] - vertices[triangles[i3 + 1] * 3 + 1],
 
  505                        vertices[triangles[i3] * 3 + 2] - vertices[triangles[i3 + 1] * 3 + 2]);
 
  506     Eigen::Vector3d s2(vertices[triangles[i3 + 1] * 3] - vertices[triangles[i3 + 2] * 3],
 
  507                        vertices[triangles[i3 + 1] * 3 + 1] - vertices[triangles[i3 + 2] * 3 + 1],
 
  508                        vertices[triangles[i3 + 1] * 3 + 2] - vertices[triangles[i3 + 2] * 3 + 2]);
 
  509     Eigen::Vector3d normal = s1.cross(s2);
 
  511     triangle_normals[i3] = normal.x();
 
  512     triangle_normals[i3 + 1] = normal.y();
 
  513     triangle_normals[i3 + 2] = normal.z();
 
  517 void Mesh::computeVertexNormals()
 
  519   if (!triangle_normals)
 
  520     computeTriangleNormals();
 
  521   if (vertex_count && !vertex_normals)
 
  522     vertex_normals = 
new double[vertex_count * 3];
 
  523   Eigen::Map<Eigen::Matrix<double, 3, Eigen::Dynamic>> mapped_normals(vertex_normals, 3, vertex_count);
 
  524   mapped_normals.setZero();
 
  526   for (
unsigned int tIdx = 0; tIdx < triangle_count; ++tIdx)
 
  528     unsigned int tIdx3 = 3 * tIdx;
 
  529     unsigned int tIdx3_1 = tIdx3 + 1;
 
  530     unsigned int tIdx3_2 = tIdx3 + 2;
 
  532     unsigned int v1 = triangles[tIdx3];
 
  533     unsigned int v2 = triangles[tIdx3_1];
 
  534     unsigned int v3 = triangles[tIdx3_2];
 
  537     Eigen::Map<Eigen::Vector3d> p1{ vertices + 3 * v1, 3 };
 
  538     Eigen::Map<Eigen::Vector3d> p2{ vertices + 3 * v2, 3 };
 
  539     Eigen::Map<Eigen::Vector3d> p3{ vertices + 3 * v3, 3 };
 
  542     auto angleBetweenVectors = [](
const Eigen::Vector3d& vec1, 
const Eigen::Vector3d& vec2) -> 
double {
 
  543       Eigen::AngleAxisd a(Eigen::Quaterniond::FromTwoVectors(vec1, vec2));
 
  546     auto ang1 = angleBetweenVectors(p2 - p1, p3 - p1);
 
  547     auto ang2 = angleBetweenVectors(p1 - p2, p3 - p2);
 
  548     auto ang3 = angleBetweenVectors(p1 - p3, p2 - p3);
 
  551     Eigen::Map<Eigen::Vector3d> triangle_normal{ triangle_normals + tIdx3, 3 };
 
  552     mapped_normals.col(v1) += triangle_normal * ang1;
 
  553     mapped_normals.col(v2) += triangle_normal * ang2;
 
  554     mapped_normals.col(v3) += triangle_normal * ang3;
 
  558   for (
int i = 0; i < mapped_normals.cols(); ++i)
 
  560     auto mapped_normal = mapped_normals.col(i);
 
  561     if (mapped_normal.squaredNorm() != 0.0)
 
  563       mapped_normal.normalize();
 
  568 void Mesh::mergeVertices(
double threshold)
 
  570   const double thresholdSQR = threshold * threshold;
 
  572   std::vector<unsigned int> vertex_map(vertex_count);
 
  576   for (
unsigned int vIdx = 0; vIdx < vertex_count; ++vIdx)
 
  578     orig_vertices[vIdx][0] = vertices[3 * vIdx];
 
  579     orig_vertices[vIdx][1] = vertices[3 * vIdx + 1];
 
  580     orig_vertices[vIdx][2] = vertices[3 * vIdx + 2];
 
  581     vertex_map[vIdx] = vIdx;
 
  584   for (
unsigned int vIdx1 = 0; vIdx1 < vertex_count; ++vIdx1)
 
  586     if (vertex_map[vIdx1] != vIdx1)
 
  589     vertex_map[vIdx1] = compressed_vertices.size();
 
  590     compressed_vertices.push_back(orig_vertices[vIdx1]);
 
  592     for (
unsigned int vIdx2 = vIdx1 + 1; vIdx2 < vertex_count; ++vIdx2)
 
  594       double distanceSQR = (orig_vertices[vIdx1] - orig_vertices[vIdx2]).squaredNorm();
 
  596         vertex_map[vIdx2] = vertex_map[vIdx1];
 
  600   if (compressed_vertices.size() == orig_vertices.size())
 
  604   for (
unsigned int tIdx = 0; tIdx < triangle_count; ++tIdx)
 
  606     unsigned int i3 = 3 * tIdx;
 
  607     triangles[i3] = vertex_map[triangles[i3]];
 
  608     triangles[i3 + 1] = vertex_map[triangles[i3 + 1]];
 
  609     triangles[i3 + 2] = vertex_map[triangles[i3 + 2]];
 
  612   vertex_count = compressed_vertices.size();
 
  614   vertices = 
new double[vertex_count * 3];
 
  616   for (
unsigned int vIdx = 0; vIdx < vertex_count; ++vIdx)
 
  618     unsigned int i3 = 3 * vIdx;
 
  619     vertices[i3] = compressed_vertices[vIdx][0];
 
  620     vertices[i3 + 1] = compressed_vertices[vIdx][1];
 
  621     vertices[i3 + 2] = compressed_vertices[vIdx][2];
 
  624   if (triangle_normals)
 
  625     computeTriangleNormals();
 
  627     computeVertexNormals();