main.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include <igl/marching_cubes.h>
  2. #include <igl/signed_distance.h>
  3. #include <igl/read_triangle_mesh.h>
  4. #include <igl/viewer/Viewer.h>
  5. #include <Eigen/Core>
  6. #include <iostream>
  7. int main(int argc, char * argv[])
  8. {
  9. using namespace Eigen;
  10. using namespace std;
  11. using namespace igl;
  12. MatrixXi F;
  13. MatrixXd V;
  14. // Read in inputs as double precision floating point meshes
  15. read_triangle_mesh(
  16. "../shared/armadillo.obj",V,F);
  17. // number of vertices on the largest side
  18. const int s = 50;
  19. const RowVector3d Vmin = V.colwise().minCoeff();
  20. const RowVector3d Vmax = V.colwise().maxCoeff();
  21. const double h = (Vmax-Vmin).maxCoeff()/(double)s;
  22. const RowVector3i res = (s*((Vmax-Vmin)/(Vmax-Vmin).maxCoeff())).cast<int>();
  23. // create grid
  24. cout<<"Creating grid..."<<endl;
  25. MatrixXd GV(res(0)*res(1)*res(2),3);
  26. for(int zi = 0;zi<res(2);zi++)
  27. {
  28. const auto lerp = [&](const int di, const int d)->double
  29. {return Vmin(d)+(double)di/(double)(res(d)-1)*(Vmax(d)-Vmin(d));};
  30. const double z = lerp(zi,2);
  31. for(int yi = 0;yi<res(1);yi++)
  32. {
  33. const double y = lerp(yi,1);
  34. for(int xi = 0;xi<res(0);xi++)
  35. {
  36. const double x = lerp(xi,0);
  37. GV.row(xi+res(0)*(yi + res(1)*zi)) = RowVector3d(x,y,z);
  38. }
  39. }
  40. }
  41. // compute values
  42. cout<<"Computing distances..."<<endl;
  43. VectorXd S,B;
  44. {
  45. VectorXi I;
  46. MatrixXd C,N;
  47. signed_distance(GV,V,F,SIGNED_DISTANCE_TYPE_PSEUDONORMAL,S,I,C,N);
  48. // Convert distances to binary inside-outside data --> aliasing artifacts
  49. B = S;
  50. for_each(B.data(),B.data()+B.size(),[](double& b){b=(b>0?1:(b<0?-1:0));});
  51. }
  52. cout<<"Marching cubes..."<<endl;
  53. MatrixXd SV,BV;
  54. MatrixXi SF,BF;
  55. marching_cubes(S,GV,res(0),res(1),res(2),SV,SF);
  56. marching_cubes(B,GV,res(0),res(1),res(2),BV,BF);
  57. cout<<R"(Usage:
  58. '1' Show original mesh.
  59. '2' Show marching cubes contour of signed distance.
  60. '3' Show marching cubes contour of indicator function.
  61. )";
  62. igl::viewer::Viewer viewer;
  63. viewer.data.set_mesh(SV,SF);
  64. viewer.callback_key_down =
  65. [&](igl::viewer::Viewer & viewer, unsigned char key, int mod)->bool
  66. {
  67. switch(key)
  68. {
  69. default:
  70. return false;
  71. case '1':
  72. viewer.data.clear();
  73. viewer.data.set_mesh(V,F);
  74. break;
  75. case '2':
  76. viewer.data.clear();
  77. viewer.data.set_mesh(SV,SF);
  78. break;
  79. case '3':
  80. viewer.data.clear();
  81. viewer.data.set_mesh(BV,BF);
  82. break;
  83. }
  84. viewer.data.set_face_based(true);
  85. return true;
  86. };
  87. viewer.launch();
  88. }