swept_volume.cpp 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  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::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 igl;
  18. const auto & Vtransform =
  19. [&V,&transform](const size_t vi,const double t)->Eigen::RowVector3d
  20. {
  21. Eigen::Vector3d Vvi = V.row(vi).transpose();
  22. return (transform(t)*Vvi).transpose();
  23. };
  24. Eigen::AlignedBox3d Mbox;
  25. swept_volume_bounding_box(V.rows(),Vtransform,steps,Mbox);
  26. // Amount of padding: pad*h should be >= isolevel
  27. const int pad = isolevel_grid+1;
  28. // number of vertices on the largest side
  29. const int s = grid_res+2*pad;
  30. const double h = Mbox.diagonal().maxCoeff()/(double)(s-2.*pad-1.);
  31. const double isolevel = isolevel_grid*h;
  32. // create grid
  33. Eigen::RowVector3i res;
  34. Eigen::MatrixXd GV;
  35. voxel_grid(Mbox,s,pad,GV,res);
  36. // compute values
  37. Eigen::VectorXd S;
  38. swept_volume_signed_distance(V,F,transform,steps,GV,res,h,isolevel,S);
  39. S.array()-=isolevel;
  40. marching_cubes(S,GV,res(0),res(1),res(2),0,SV,SF);
  41. }