voxel_grid.cpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "voxel_grid.h"
  9. #include "grid.h"
  10. IGL_INLINE void igl::voxel_grid(
  11. const Eigen::AlignedBox3d & box,
  12. const int in_s,
  13. const int pad_count,
  14. Eigen::MatrixXd & GV,
  15. Eigen::RowVector3i & side)
  16. {
  17. using namespace Eigen;
  18. using namespace std;
  19. MatrixXd::Index si = -1;
  20. box.diagonal().maxCoeff(&si);
  21. //MatrixXd::Index si = 0;
  22. //assert(si>=0);
  23. const double s_len = box.diagonal()(si);
  24. assert(in_s>(pad_count*2+1) && "s should be > 2*pad_count+1");
  25. const double s = in_s - 2*pad_count;
  26. side(si) = s;
  27. for(int i = 0;i<3;i++)
  28. {
  29. if(i!=si)
  30. {
  31. side(i) = std::ceil(s * (box.max()(i)-box.min()(i))/s_len);
  32. }
  33. }
  34. side.array() += 2*pad_count;
  35. grid(side,GV);
  36. // A * p/s + B = min
  37. // A * (1-p/s) + B = max
  38. // B = min - A * p/s
  39. // A * (1-p/s) + min - A * p/s = max
  40. // A * (1-p/s) - A * p/s = max-min
  41. // A * (1-2p/s) = max-min
  42. // A = (max-min)/(1-2p/s)
  43. const Array<double,3,1> ps=
  44. (double)(pad_count)/(side.transpose().cast<double>().array()-1.);
  45. const Array<double,3,1> A = box.diagonal().array()/(1.0-2.*ps);
  46. //// This would result in an "anamorphic", but perfectly fit grid:
  47. //const Array<double,3,1> B = box.min().array() - A.array()*ps;
  48. //GV.array().rowwise() *= A.transpose();
  49. //GV.array().rowwise() += B.transpose();
  50. // Instead scale by largest factor and move to match center
  51. Array<double,3,1>::Index ai = -1;
  52. double a = A.maxCoeff(&ai);
  53. const Array<double,1,3> ratio =
  54. a*(side.cast<double>().array()-1.0)/(double)(side(ai)-1.0);
  55. GV.array().rowwise() *= ratio;
  56. GV.rowwise() += (box.center().transpose()-GV.colwise().mean()).eval();
  57. }