main.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include <igl/read_triangle_mesh.h>
  2. #include <igl/copyleft/cgal/oriented_bounding_box.h>
  3. #include <igl/copyleft/cgal/convex_hull.h>
  4. #include <igl/opengl/glfw/Viewer.h>
  5. #include <igl/oriented_bounding_box.h>
  6. #include <igl/moments.h>
  7. #include <igl/super_fibonacci.h>
  8. #include <igl/matlab_format.h>
  9. #include <igl/write_triangle_mesh.h>
  10. #include <igl/get_seconds.h>
  11. #include <igl/parallel_for.h>
  12. #include <Eigen/Core>
  13. #include <iostream>
  14. #include <limits>
  15. int main(int argc, char * argv[])
  16. {
  17. IGL_TICTOC_LAMBDA;
  18. Eigen::MatrixXi F;
  19. Eigen::MatrixXd V;
  20. // Read in inputs as double precision floating point meshes
  21. igl::read_triangle_mesh(
  22. argc>1?argv[1]: TUTORIAL_SHARED_PATH "/hand.mesh",V,F);
  23. V.array() += 1;
  24. tictoc();
  25. {
  26. Eigen::RowVector3d min_corner = V.colwise().minCoeff();
  27. Eigen::RowVector3d max_corner = V.colwise().maxCoeff();
  28. };
  29. double t_aabb = tictoc();
  30. // PCA
  31. tictoc();
  32. Eigen::RowVector3d mean = V.colwise().mean();
  33. Eigen::MatrixXd V_centered = V.rowwise() - mean;
  34. Eigen::Matrix3d cov = (V_centered.transpose() * V_centered) / (V.rows() - 1);
  35. Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eig(cov);
  36. Eigen::Matrix3d PR = eig.eigenvectors();
  37. double t_pca = tictoc();
  38. Eigen::Matrix3d R;
  39. tictoc();
  40. igl::copyleft::cgal::oriented_bounding_box(V, R);
  41. double t_cgal = tictoc();
  42. tictoc();
  43. Eigen::MatrixXd W;
  44. Eigen::MatrixXi G;
  45. igl::copyleft::cgal::convex_hull(V,W,G);
  46. Eigen::Matrix3d BR;
  47. igl::oriented_bounding_box(W, 50000, igl::ORIENTED_BOUNDING_BOX_MINIMIZE_SURFACE_AREA, BR);
  48. std::cout<<igl::matlab_format(BR, "saBR")<<std::endl;
  49. igl::oriented_bounding_box(W, 50000, igl::ORIENTED_BOUNDING_BOX_MINIMIZE_VOLUME, BR);
  50. std::cout<<igl::matlab_format(BR, "vBR")<<std::endl;
  51. double t_best = tictoc();
  52. // Cube mesh
  53. Eigen::MatrixXd CV(8,3);
  54. CV<<
  55. 0,0,0,
  56. 0,1,0,
  57. 1,0,0,
  58. 1,1,0,
  59. 1,0,1,
  60. 1,1,1,
  61. 0,0,1,
  62. 0,1,1;
  63. Eigen::MatrixXi CF(12,3);
  64. CF<<
  65. 1,2,0,
  66. 1,3,2,
  67. 3,4,2,
  68. 3,5,4,
  69. 0,4,6,
  70. 0,2,4,
  71. 7,3,1,
  72. 7,5,3,
  73. 7,0,6,
  74. 7,1,0,
  75. 5,6,4,
  76. 5,7,6;
  77. Eigen::MatrixXi CE(12,2);
  78. CE<<
  79. 0,1,
  80. 0,2,
  81. 0,6,
  82. 1,3,
  83. 1,7,
  84. 2,3,
  85. 2,4,
  86. 3,5,
  87. 4,5,
  88. 4,6,
  89. 5,7,
  90. 6,7;
  91. const auto transform_cube = [](const Eigen::MatrixXd & V, const Eigen::MatrixXd & CV)
  92. {
  93. Eigen::RowVector3d min_corner = V.colwise().minCoeff();
  94. Eigen::RowVector3d max_corner = V.colwise().maxCoeff();
  95. Eigen::RowVector3d diff = max_corner - min_corner;
  96. Eigen::MatrixXd AV = CV;
  97. AV.array().rowwise() *= diff.array();
  98. AV.rowwise() += min_corner;
  99. return AV;
  100. };
  101. Eigen::MatrixXd AV = transform_cube(V, CV);
  102. Eigen::MatrixXd OV = transform_cube((V*R).eval(), CV);
  103. OV = (OV*R.transpose()).eval();
  104. Eigen::MatrixXd PV = transform_cube((V*PR).eval(), CV);
  105. PV = (PV*PR.transpose()).eval();
  106. Eigen::MatrixXd BV = transform_cube((V*BR).eval(), CV);
  107. BV = (BV*BR.transpose()).eval();
  108. const auto volume = [](const Eigen::MatrixXd & V, const Eigen::MatrixXi & F)
  109. {
  110. Eigen::Vector3d m1;
  111. Eigen::Matrix3d m2;
  112. double vol = 0;
  113. igl::moments(V,F,vol,m1,m2);
  114. return vol;
  115. };
  116. double Avol = volume(AV,CF);
  117. double Pvol = volume(PV,CF);
  118. double Ovol = volume(OV,CF);
  119. double Bvol = volume(BV,CF);
  120. printf("method: %20s %20s %20s %20s\n", "AABB", "PCA", "CGAL", "super_fibonacci");
  121. printf("volume: %20g %20g %20g %20g\n", Avol, Pvol, Ovol, Bvol);
  122. printf("time: %20g %20g %20g %20g\n", t_aabb, t_pca, t_cgal, t_best);
  123. igl::opengl::glfw::Viewer viewer;
  124. viewer.data().set_mesh(V,F);
  125. viewer.data().set_face_based(true);
  126. viewer.append_mesh();
  127. viewer.data().set_mesh(AV,CF);
  128. viewer.data().set_face_based(true);
  129. viewer.data().set_colors(Eigen::RowVector4d(0.43064,0.77072,0.51013,0.5));
  130. viewer.data().set_edges(AV,CE,Eigen::RowVector3d(0,0,0));
  131. viewer.data().show_lines = false;
  132. viewer.append_mesh();
  133. viewer.data().set_mesh(PV,CF);
  134. viewer.data().set_face_based(true);
  135. viewer.data().set_colors(Eigen::RowVector4d(0.9374,0.54164,0.66868,0.5));
  136. viewer.data().set_edges(PV,CE,Eigen::RowVector3d(0,0,0));
  137. viewer.data().show_lines = false;
  138. viewer.append_mesh();
  139. viewer.data().set_mesh(OV,CF);
  140. viewer.data().set_face_based(true);
  141. viewer.data().set_colors(Eigen::RowVector4d(0.91191,0.60119,0.32995,0.5));
  142. viewer.data().show_lines = false;
  143. viewer.append_mesh();
  144. viewer.data().set_mesh(BV,CF);
  145. viewer.data().set_face_based(true);
  146. viewer.data().set_colors(Eigen::RowVector4d(0.34481,0.72126,0.96535,0.5));
  147. viewer.data().show_lines = false;
  148. viewer.data().set_edges(OV,CE,Eigen::RowVector3d(0,0,0));
  149. // set background to white
  150. viewer.core().background_color = Eigen::Vector4f(1,1,1,1);
  151. viewer.data().show_lines = false;
  152. viewer.launch();
  153. }