oriented_bounding_box.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. #include "oriented_bounding_box.h"
  2. #include "super_fibonacci.h"
  3. #include "parallel_for.h"
  4. template <typename DerivedP, typename DerivedR>
  5. IGL_INLINE void igl::oriented_bounding_box(
  6. const Eigen::MatrixBase<DerivedP>& P,
  7. const int n,
  8. const OrientedBoundingBoxMinimizeType minimize_type,
  9. Eigen::PlainObjectBase<DerivedR> & R)
  10. {
  11. typedef typename DerivedP::Scalar Scalar;
  12. Eigen::Matrix<Scalar,Eigen::Dynamic,4,Eigen::RowMajor> Q;
  13. igl::super_fibonacci(n-1, Q);
  14. Q.conservativeResize(n, 4);
  15. Q.row(Q.rows()-1) << 0, 0, 0, 1;
  16. Eigen::Matrix<Scalar,Eigen::Dynamic,1> losses(Q.rows());
  17. igl::parallel_for(Q.rows(),[&](const int i)
  18. {
  19. Eigen::Quaternion<Scalar> q(Q(i,3), Q(i,0), Q(i,1), Q(i,2));
  20. const auto R = q.toRotationMatrix();
  21. const auto PR = (P*R).eval();
  22. Eigen::Matrix<Scalar,1,3> min_corner = PR.colwise().minCoeff();
  23. Eigen::Matrix<Scalar,1,3> max_corner = PR.colwise().maxCoeff();
  24. Eigen::Matrix<Scalar,1,3> diagonal = max_corner - min_corner;
  25. switch(minimize_type)
  26. {
  27. case ORIENTED_BOUNDING_BOX_MINIMIZE_VOLUME:
  28. losses(i) = diagonal.prod();
  29. break;
  30. case ORIENTED_BOUNDING_BOX_MINIMIZE_SURFACE_AREA:
  31. losses(i) = 2 * (diagonal(0) * diagonal(1) + diagonal(1) * diagonal(2) + diagonal(0) * diagonal(2));
  32. break;
  33. case ORIENTED_BOUNDING_BOX_MINIMIZE_DIAGONAL_LENGTH:
  34. losses(i) = diagonal.squaredNorm();
  35. break;
  36. default:
  37. assert(false && "Unknown minimize type");
  38. }
  39. });
  40. int bi;
  41. const Scalar best_loss = losses.minCoeff(&bi);
  42. R = Eigen::Quaternion<Scalar>(Q(bi,3), Q(bi,0), Q(bi,1), Q(bi,2)).toRotationMatrix().eval();
  43. }
  44. #ifdef IGL_STATIC_LIBRARY
  45. // Explicit instantiation of template function
  46. template void igl::oriented_bounding_box<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 3, 0, 3, 3>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, int, igl::OrientedBoundingBoxMinimizeType, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 3, 0, 3, 3>>&);
  47. #endif