swept_volume.cpp 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #include "swept_volume.h"
  2. #include "../swept_volume_bounding_box.h"
  3. #include "../swept_volume_signed_distance.h"
  4. #include "../voxel_grid.h"
  5. #include "marching_cubes.h"
  6. #include <iostream>
  7. IGL_INLINE void igl::copyleft::swept_volume(
  8. const Eigen::MatrixXd & V,
  9. const Eigen::MatrixXi & F,
  10. const std::function<Eigen::Affine3d(const double t)> & transform,
  11. const size_t steps,
  12. const size_t grid_res,
  13. const size_t isolevel_grid,
  14. Eigen::MatrixXd & SV,
  15. Eigen::MatrixXi & SF)
  16. {
  17. using namespace std;
  18. using namespace Eigen;
  19. using namespace igl;
  20. using namespace igl::copyleft;
  21. const auto & Vtransform =
  22. [&V,&transform](const size_t vi,const double t)->RowVector3d
  23. {
  24. Vector3d Vvi = V.row(vi).transpose();
  25. return (transform(t)*Vvi).transpose();
  26. };
  27. AlignedBox3d Mbox;
  28. swept_volume_bounding_box(V.rows(),Vtransform,steps,Mbox);
  29. // Amount of padding: pad*h should be >= isolevel
  30. const int pad = isolevel_grid+1;
  31. // number of vertices on the largest side
  32. const int s = grid_res+2*pad;
  33. const double h = Mbox.diagonal().maxCoeff()/(double)(s-2.*pad-1.);
  34. const double isolevel = isolevel_grid*h;
  35. // create grid
  36. RowVector3i res;
  37. MatrixXd GV;
  38. voxel_grid(Mbox,s,pad,GV,res);
  39. // compute values
  40. VectorXd S;
  41. swept_volume_signed_distance(V,F,transform,steps,GV,res,h,isolevel,S);
  42. S.array()-=isolevel;
  43. marching_cubes(S,GV,res(0),res(1),res(2),SV,SF);
  44. }