main.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "check_mesh_for_issues.h"
  2. #include "get_soft_constraint_for_circle.h"
  3. #include "get_cube_corner_constraints.h"
  4. #include "param_2d_demo_iter.h"
  5. #include <igl/slim.h>
  6. #include <igl/readOBJ.h>
  7. #include <igl/writeOBJ.h>
  8. #include <igl/Timer.h>
  9. #include <igl/MappingEnergyType.h>
  10. #include <igl/serialize.h>
  11. #include <igl/read_triangle_mesh.h>
  12. #include <igl/opengl/glfw/Viewer.h>
  13. #include <igl/barycenter.h>
  14. #include <iostream>
  15. #include <cstdlib>
  16. #include <string>
  17. #include <vector>
  18. void soft_const_demo_iter(igl::opengl::glfw::Viewer& viewer);
  19. void deform_3d_demo_iter(igl::opengl::glfw::Viewer& viewer);
  20. void display_3d_mesh(igl::opengl::glfw::Viewer& viewer);
  21. Eigen::MatrixXd V;
  22. Eigen::MatrixXi F;
  23. bool first_iter = true;
  24. igl::SLIMData sData;
  25. igl::Timer timer;
  26. double uv_scale_param;
  27. enum DEMO_TYPE {
  28. PARAM_2D,
  29. SOFT_CONST,
  30. DEFORM_3D
  31. };
  32. DEMO_TYPE demo_type;
  33. bool key_down(igl::opengl::glfw::Viewer& viewer, unsigned char key, int modifier){
  34. if (key == ' ') {
  35. switch (demo_type) {
  36. case PARAM_2D: {
  37. param_2d_demo_iter(V,F,uv_scale_param,first_iter,sData,timer,viewer);
  38. break;
  39. }
  40. case SOFT_CONST: {
  41. soft_const_demo_iter(viewer);
  42. break;
  43. }
  44. case DEFORM_3D: {
  45. deform_3d_demo_iter(viewer);
  46. break;
  47. }
  48. default:
  49. break;
  50. }
  51. }
  52. return false;
  53. }
  54. void soft_const_demo_iter(igl::opengl::glfw::Viewer& viewer) {
  55. using namespace std;
  56. if (first_iter) {
  57. igl::read_triangle_mesh(TUTORIAL_SHARED_PATH "/circle.obj", V, F);
  58. check_mesh_for_issues(V,F);
  59. cout << "\tMesh is valid!" << endl;
  60. Eigen::MatrixXd V_0 = V.block(0,0,V.rows(),2);
  61. Eigen::VectorXi b; Eigen::MatrixXd bc;
  62. get_soft_constraint_for_circle(V_0,F,b,bc);
  63. double soft_const_p = 1e5;
  64. slim_precompute(V,F,V_0,sData,igl::MappingEnergyType::SYMMETRIC_DIRICHLET,b,bc,soft_const_p);
  65. viewer.data().set_mesh(V, F);
  66. viewer.core().align_camera_center(V,F);
  67. viewer.data().compute_normals();
  68. viewer.data().show_lines = true;
  69. first_iter = false;
  70. } else {
  71. slim_solve(sData,1); // 1 iter
  72. viewer.data().set_mesh(sData.V_o, F);
  73. }
  74. }
  75. void deform_3d_demo_iter(igl::opengl::glfw::Viewer& viewer) {
  76. using namespace std;
  77. if (first_iter) {
  78. timer.start();
  79. igl::readOBJ(TUTORIAL_SHARED_PATH "/cube_40k.obj", V, F);
  80. Eigen::MatrixXd V_0 = V;
  81. Eigen::VectorXi b; Eigen::MatrixXd bc;
  82. get_cube_corner_constraints(V_0,F,b,bc);
  83. double soft_const_p = 1e5;
  84. sData.exp_factor = 5.0;
  85. slim_precompute(V,F,V_0,sData,igl::MappingEnergyType::EXP_CONFORMAL,b,bc,soft_const_p);
  86. //cout << "precomputed" << endl;
  87. first_iter = false;
  88. display_3d_mesh(viewer);
  89. } else {
  90. timer.start();
  91. slim_solve(sData,1); // 1 iter
  92. display_3d_mesh(viewer);
  93. }
  94. cout << "time = " << timer.getElapsedTime() << endl;
  95. cout << "energy = " << sData.energy << endl;
  96. }
  97. void display_3d_mesh(igl::opengl::glfw::Viewer& viewer) {
  98. using namespace std;
  99. using namespace Eigen;
  100. MatrixXd V_temp; MatrixXi F_temp;
  101. Eigen::MatrixXd Barycenters;
  102. igl::barycenter(sData.V,sData.F,Barycenters);
  103. //cout << "Barycenters.rows() = " << Barycenters.rows() << endl;
  104. //double t = double((key - '1')+1) / 9.0;
  105. double view_depth = 10.;
  106. double t = view_depth/9.;
  107. VectorXd v = Barycenters.col(2).array() - Barycenters.col(2).minCoeff();
  108. v /= v.col(0).maxCoeff();
  109. vector<int> s;
  110. for (unsigned i=0; i<v.size();++i)
  111. if (v(i) < t)
  112. s.push_back(i);
  113. V_temp.resize(s.size()*4,3);
  114. F_temp.resize(s.size()*4,3);
  115. for (unsigned i=0; i<s.size();++i){
  116. V_temp.row(i*4+0) = sData.V_o.row(sData.F(s[i],0));
  117. V_temp.row(i*4+1) = sData.V_o.row(sData.F(s[i],1));
  118. V_temp.row(i*4+2) = sData.V_o.row(sData.F(s[i],2));
  119. V_temp.row(i*4+3) = sData.V_o.row(sData.F(s[i],3));
  120. F_temp.row(i*4+0) << (i*4)+0, (i*4)+1, (i*4)+3;
  121. F_temp.row(i*4+1) << (i*4)+0, (i*4)+2, (i*4)+1;
  122. F_temp.row(i*4+2) << (i*4)+3, (i*4)+2, (i*4)+0;
  123. F_temp.row(i*4+3) << (i*4)+1, (i*4)+2, (i*4)+3;
  124. }
  125. viewer.data().set_mesh(V_temp,F_temp);
  126. viewer.core().align_camera_center(V_temp,F_temp);
  127. viewer.data().set_face_based(true);
  128. viewer.data().show_lines = true;
  129. }
  130. int main(int argc, char *argv[]) {
  131. using namespace std;
  132. using namespace Eigen;
  133. cerr << "Press space for running an iteration." << std::endl;
  134. cerr << "Syntax: " << argv[0] << " demo_number (1 to 3)" << std::endl;
  135. cerr << "1. 2D unconstrained parametrization" << std::endl;
  136. cerr << "2. 2D deformation with positional constraints" << std::endl;
  137. cerr << "3. 3D mesh deformation with positional constraints" << std::endl;
  138. demo_type = PARAM_2D;
  139. if (argc == 2) {
  140. switch (std::atoi(argv[1])) {
  141. case 1: {
  142. demo_type = PARAM_2D;
  143. break;
  144. } case 2: {
  145. demo_type = SOFT_CONST;
  146. break;
  147. } case 3: {
  148. demo_type = DEFORM_3D;
  149. break;
  150. }
  151. default: {
  152. cerr << "Wrong demo number - Please choose one between 1-3" << std:: endl;
  153. exit(1);
  154. }
  155. }
  156. }
  157. // Launch the viewer
  158. igl::opengl::glfw::Viewer viewer;
  159. viewer.callback_key_down = &key_down;
  160. // Disable wireframe
  161. viewer.data().show_lines = false;
  162. // Draw checkerboard texture
  163. viewer.data().show_texture = false;
  164. // First iteration
  165. key_down(viewer, ' ', 0);
  166. viewer.launch();
  167. return 0;
  168. }