main.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include <igl/avg_edge_length.h>
  2. #include <igl/per_vertex_normals.h>
  3. #include <igl/readOFF.h>
  4. #include <igl/lim/lim.h>
  5. #include <igl/viewer/Viewer.h>
  6. #include <iostream>
  7. #include "tutorial_shared_path.h"
  8. using namespace igl::lim;
  9. // Mesh
  10. Eigen::MatrixX3d V0;
  11. Eigen::MatrixX3d V1;
  12. Eigen::MatrixXi F;
  13. Eigen::SparseMatrix<double> C;
  14. Eigen::VectorXd b;
  15. Energy energyType;
  16. bool barriersEnabled;
  17. // This function is called every time a keyboard button is pressed
  18. // keys: 0:Original Mesh / 1:Harmonic / 2:Biharmonic / 3:Green / 4:ARAP
  19. bool key_down(igl::viewer::Viewer& viewer,unsigned char key,int modifier)
  20. {
  21. using namespace std;
  22. using namespace Eigen;
  23. if(key >= '0' && key <= '5' || key == 'B')
  24. {
  25. // compute locally injective map
  26. Energy energy = Energy(key - '1');
  27. V1 = V0;
  28. if(key == 'B')
  29. {
  30. barriersEnabled = !barriersEnabled;
  31. }
  32. else
  33. {
  34. if(energy >= 0)
  35. energyType = energy;
  36. }
  37. if(key != '0')
  38. {
  39. lim(V1,V0,F,C,b,energyType,1e-8,100,true,true,barriersEnabled,true,-1,-1);
  40. }
  41. // set mesh
  42. viewer.data.set_vertices(V1);
  43. return true;
  44. }
  45. return false;
  46. }
  47. int main(int argc, char *argv[])
  48. {
  49. using namespace std;
  50. using namespace Eigen;
  51. energyType = Dirichlet;
  52. barriersEnabled = true;
  53. // load a mesh in OFF format
  54. igl::readOFF(TUTORIAL_SHARED_PATH "/grid.off",V0,F);
  55. V1 = V0;
  56. // find bottom and left boundary vertices
  57. vector<int> fixedVertices;
  58. for(int i=0;i<V0.rows();i++)
  59. {
  60. if(V0.row(i)[0] == 0 || V0.row(i)[1] == 0)
  61. fixedVertices.push_back(i);
  62. }
  63. // fix boundaries
  64. C.resize(2*fixedVertices.size()+2,V0.rows()*2);
  65. for(int i=0;i<fixedVertices.size();i++)
  66. {
  67. C.insert(2*i,2*fixedVertices[i]) = 1;
  68. C.insert(2*i+1,2*fixedVertices[i]+1) = 1;
  69. }
  70. // constraint targets
  71. b.resize(2*fixedVertices.size()+2);
  72. for(int i=0;i<fixedVertices.size();i++)
  73. {
  74. b(2*i) = V0.row(fixedVertices[i])[0];
  75. b(2*i+1) = V0.row(fixedVertices[i])[1];
  76. }
  77. // drag top left corner vertex to the center
  78. int id = 2;
  79. C.insert(2*fixedVertices.size(),2*id) = 1;
  80. C.insert(2*fixedVertices.size()+1,2*id+1) = 1;
  81. b(2*fixedVertices.size()) = 0.2;
  82. b(2*fixedVertices.size()+1) = 0.2;
  83. // compute locally injective map
  84. lim(V1,V0,F,C,b,energyType,1e-8,100,true,true,barriersEnabled,true,-1,-1);
  85. // Show mesh
  86. igl::viewer::Viewer viewer;
  87. viewer.callback_key_down = &key_down;
  88. viewer.data.set_mesh(V1, F);
  89. viewer.core.show_lines = true;
  90. viewer.core.lighting_factor = 0.0f;
  91. viewer.launch();
  92. }