main.cpp 2.6 KB

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