main.cpp 2.6 KB

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