main.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <igl/readOBJ.h>
  2. #include <igl/readDMAT.h>
  3. #include <igl/viewer/Viewer.h>
  4. #include <igl/barycenter.h>
  5. #include <igl/avg_edge_length.h>
  6. #include <vector>
  7. #include <igl/n_polyvector.h>
  8. #include <stdlib.h>
  9. // Input mesh
  10. Eigen::MatrixXd V;
  11. Eigen::MatrixXi F;
  12. // Face barycenters
  13. Eigen::MatrixXd B;
  14. // Scale for visualizing the fields
  15. double global_scale;
  16. // Input constraints
  17. Eigen::VectorXi isConstrained;
  18. std::vector<Eigen::MatrixXd> constraints;
  19. bool key_down(igl::Viewer& viewer, unsigned char key, int modifier)
  20. {
  21. using namespace std;
  22. using namespace Eigen;
  23. if (key <'0' || key >'4')
  24. return false;
  25. viewer.clear_mesh();
  26. viewer.set_mesh(V, F);
  27. viewer.options.show_lines = false;
  28. viewer.options.show_texture = false;
  29. int num = key - '0';
  30. if (num == 0)
  31. return false;
  32. // Interpolate
  33. cerr<<"Interpolating for n = "<<num<<"... ";
  34. // Interpolated polyVector field
  35. Eigen::MatrixXd pvf;
  36. igl::n_polyvector(V, F, isConstrained, constraints[num-1], pvf);
  37. cerr<<"done." <<endl;
  38. // Highlight in red the constrained faces
  39. MatrixXd C = MatrixXd::Constant(F.rows(),3,1);
  40. for (unsigned i=0; i<F.rows();++i)
  41. if (isConstrained[i])
  42. C.row(i) << 1, 0, 0;
  43. viewer.set_colors(C);
  44. for (int n =0; n<num; ++n)
  45. {
  46. // Frame field constraints
  47. MatrixXd F_t = MatrixXd::Zero(F.rows(),3);
  48. for (unsigned i=0; i<F.rows();++i)
  49. if (isConstrained[i])
  50. F_t.row(i) = constraints[num-1].block(i,n*3,1,3);
  51. const Eigen::MatrixXd &pvf_t = pvf.block(0,n*3,F.rows(),3);
  52. viewer.add_edges (B - global_scale*F_t, B + global_scale*F_t , Eigen::RowVector3d(0,0,1));
  53. viewer.add_edges (B - global_scale*pvf_t, B + global_scale*pvf_t , Eigen::RowVector3d(0,1,0));
  54. }
  55. return false;
  56. }
  57. int main(int argc, char *argv[])
  58. {
  59. using namespace Eigen;
  60. using namespace std;
  61. // Load a mesh in OBJ format
  62. igl::readOBJ("../shared/snail.obj", V, F);
  63. // Compute face barycenters
  64. igl::barycenter(V, F, B);
  65. // Compute scale for visualizing fields
  66. global_scale = .2*igl::avg_edge_length(V, F);
  67. // Allocate constraints and polyvector field
  68. constraints.resize(4);
  69. // Load constraints
  70. MatrixXd temp;
  71. for (int n =0; n<=3; ++n)
  72. {
  73. char cfile[1024]; sprintf(cfile, "../shared/snail%d.dmat",n+1);
  74. igl::readDMAT(cfile,temp);
  75. if (n == 0)
  76. isConstrained = temp.block(0,0,temp.rows(),1).cast<int>();
  77. constraints[n] = temp.block(0,1,temp.rows(),temp.cols()-1);
  78. }
  79. igl::Viewer viewer;
  80. // Plot the original mesh with a texture parametrization
  81. key_down(viewer,'0',0);
  82. // Launch the viewer
  83. viewer.callback_key_down = &key_down;
  84. viewer.launch();
  85. }