main.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include <igl/boundary_facets.h>
  2. #include <igl/cotmatrix.h>
  3. #include <igl/invert_diag.h>
  4. #include <igl/jet.h>
  5. #include <igl/massmatrix.h>
  6. #include <igl/min_quad_with_fixed.h>
  7. #include <igl/readOFF.h>
  8. #include <igl/viewer/Viewer.h>
  9. #include <Eigen/Sparse>
  10. #include <iostream>
  11. #include "tutorial_shared_path.h"
  12. int main(int argc, char *argv[])
  13. {
  14. using namespace Eigen;
  15. using namespace std;
  16. MatrixXd V;
  17. MatrixXi F;
  18. igl::readOFF(TUTORIAL_SHARED_PATH "/cheburashka.off",V,F);
  19. // Two fixed points
  20. VectorXi b(2,1);
  21. // Left hand, left foot
  22. b<<4331,5957;
  23. VectorXd bc(2,1);
  24. bc<<1,-1;
  25. // Construct Laplacian and mass matrix
  26. SparseMatrix<double> L,M,Minv,Q;
  27. igl::cotmatrix(V,F,L);
  28. igl::massmatrix(V,F,igl::MASSMATRIX_TYPE_VORONOI,M);
  29. igl::invert_diag(M,Minv);
  30. // Bi-Laplacian
  31. Q = L * (Minv * L);
  32. // Zero linear term
  33. VectorXd B = VectorXd::Zero(V.rows(),1);
  34. VectorXd Z,Z_const;
  35. {
  36. // Alternative, short hand
  37. igl::min_quad_with_fixed_data<double> mqwf;
  38. // Empty constraints
  39. VectorXd Beq;
  40. SparseMatrix<double> Aeq;
  41. igl::min_quad_with_fixed_precompute(Q,b,Aeq,true,mqwf);
  42. igl::min_quad_with_fixed_solve(mqwf,B,bc,Beq,Z);
  43. }
  44. {
  45. igl::min_quad_with_fixed_data<double> mqwf;
  46. // Constraint forcing difference of two points to be 0
  47. SparseMatrix<double> Aeq(1,V.rows());
  48. // Right hand, right foot
  49. Aeq.insert(0,6074) = 1;
  50. Aeq.insert(0,6523) = -1;
  51. Aeq.makeCompressed();
  52. VectorXd Beq(1,1);
  53. Beq(0) = 0;
  54. igl::min_quad_with_fixed_precompute(Q,b,Aeq,true,mqwf);
  55. igl::min_quad_with_fixed_solve(mqwf,B,bc,Beq,Z_const);
  56. }
  57. // Pseudo-color based on solution
  58. struct Data{
  59. MatrixXd C,C_const;
  60. } data;
  61. // Use same color axes
  62. const double min_z = std::min(Z.minCoeff(),Z_const.minCoeff());
  63. const double max_z = std::max(Z.maxCoeff(),Z_const.maxCoeff());
  64. igl::jet( Z,min_z,max_z,data.C);
  65. igl::jet(Z_const,min_z,max_z,data.C_const);
  66. // Plot the mesh with pseudocolors
  67. igl::viewer::Viewer viewer;
  68. viewer.data.set_mesh(V, F);
  69. viewer.core.show_lines = false;
  70. viewer.data.set_colors(data.C);
  71. viewer.callback_key_down =
  72. [](igl::viewer::Viewer& viewer,unsigned char key,int mod)->bool
  73. {
  74. if(key == ' ')
  75. {
  76. Data & data = *static_cast<Data*>(viewer.callback_key_down_data);
  77. static bool toggle = true;
  78. viewer.data.set_colors(toggle?data.C_const:data.C);
  79. toggle = !toggle;
  80. return true;
  81. }else
  82. {
  83. return false;
  84. }
  85. };
  86. viewer.callback_key_down_data = &data;
  87. cout<<
  88. "Press [space] to toggle between unconstrained and constrained."<<endl;
  89. viewer.launch();
  90. }