main.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #undef IGL_STATIC_LIBRARY
  2. #include <igl/readOBJ.h>
  3. #include <igl/readDMAT.h>
  4. #include <igl/viewer/Viewer.h>
  5. #include <igl/barycenter.h>
  6. #include <igl/avg_edge_length.h>
  7. #include <vector>
  8. #include <igl/n_polyvector.h>
  9. #include <igl/conjugate_frame_fields.h>
  10. #include <stdlib.h>
  11. // Input mesh
  12. Eigen::MatrixXd V;
  13. Eigen::MatrixXi F;
  14. // Face barycenters
  15. Eigen::MatrixXd B;
  16. // Scale for visualizing the fields
  17. double global_scale;
  18. // Input constraints
  19. Eigen::VectorXi isConstrained;
  20. Eigen::MatrixXd constraints;
  21. Eigen::MatrixXd smooth_pvf;
  22. Eigen::MatrixXd conjugate_pvf;
  23. igl::ConjugateFFSolverData<Eigen::MatrixXd, Eigen::MatrixXi> *csdata;
  24. int conjIter = 2;
  25. int totalConjIter = 0;
  26. double lambdaOrtho = .1;
  27. double lambdaInit = 100;
  28. double lambdaMultFactor = 1.01;
  29. bool doHardConstraints = true;
  30. bool key_down(igl::Viewer& viewer, unsigned char key, int modifier)
  31. {
  32. using namespace std;
  33. using namespace Eigen;
  34. if (key <'1' || key >'3')
  35. return false;
  36. viewer.clear_mesh();
  37. viewer.set_mesh(V, F);
  38. viewer.options.show_lines = false;
  39. viewer.options.show_texture = false;
  40. // Highlight in red the constrained faces
  41. MatrixXd C = MatrixXd::Constant(F.rows(),3,1);
  42. for (unsigned i=0; i<F.rows();++i)
  43. if (isConstrained[i])
  44. C.row(i) << 1, 0, 0;
  45. viewer.set_colors(C);
  46. if (key == '1')
  47. {
  48. // Frame field constraints
  49. MatrixXd F1_t = MatrixXd::Zero(F.rows(),3);
  50. MatrixXd F2_t = MatrixXd::Zero(F.rows(),3);
  51. for (unsigned i=0; i<F.rows();++i)
  52. if (isConstrained[i])
  53. {
  54. F1_t.row(i) = constraints.block(i,0,1,3);
  55. F2_t.row(i) = constraints.block(i,3,1,3);
  56. }
  57. viewer.add_edges (B - global_scale*F1_t, B + global_scale*F1_t , Eigen::RowVector3d(0,0,1));
  58. viewer.add_edges (B - global_scale*F2_t, B + global_scale*F2_t , Eigen::RowVector3d(0,0,1));
  59. }
  60. if (key == '2')
  61. {
  62. viewer.add_edges (B - global_scale*smooth_pvf.block(0,0,F.rows(),3),
  63. B + global_scale*smooth_pvf.block(0,0,F.rows(),3),
  64. Eigen::RowVector3d(0,1,0));
  65. viewer.add_edges (B - global_scale*smooth_pvf.block(0,3,F.rows(),3),
  66. B + global_scale*smooth_pvf.block(0,3,F.rows(),3),
  67. Eigen::RowVector3d(0,1,0));
  68. }
  69. if (key == '3')
  70. {
  71. if (totalConjIter <50)
  72. {
  73. double lambdaOut;
  74. igl::conjugate_frame_fields(*csdata, isConstrained, conjugate_pvf, conjugate_pvf, conjIter, lambdaOrtho, lambdaInit, lambdaMultFactor, doHardConstraints,
  75. &lambdaOut);
  76. totalConjIter += 2;
  77. lambdaInit = lambdaOut;
  78. }
  79. viewer.add_edges (B - global_scale*conjugate_pvf.block(0,0,F.rows(),3),
  80. B + global_scale*conjugate_pvf.block(0,0,F.rows(),3),
  81. Eigen::RowVector3d(0,1,0));
  82. viewer.add_edges (B - global_scale*conjugate_pvf.block(0,3,F.rows(),3),
  83. B + global_scale*conjugate_pvf.block(0,3,F.rows(),3),
  84. Eigen::RowVector3d(0,1,0));
  85. }
  86. return false;
  87. }
  88. int main(int argc, char *argv[])
  89. {
  90. using namespace Eigen;
  91. using namespace std;
  92. // Load a mesh in OBJ format
  93. igl::readOBJ("../shared/inspired_mesh.obj", V, F);
  94. // Compute face barycenters
  95. igl::barycenter(V, F, B);
  96. // Compute scale for visualizing fields
  97. global_scale = .2*igl::avg_edge_length(V, F);
  98. // Load constraints
  99. MatrixXd temp;
  100. igl::readDMAT("../shared/inspired_mesh.dmat",temp);
  101. isConstrained = temp.block(0,0,temp.rows(),1).cast<int>();
  102. constraints = temp.block(0,1,temp.rows(),temp.cols()-1);
  103. // Interpolate to get a smooth field
  104. igl::n_polyvector(V, F, isConstrained, constraints, smooth_pvf);
  105. // Initialize conjugate field with smooth field
  106. csdata = new igl::ConjugateFFSolverData<Eigen::MatrixXd,Eigen::MatrixXi>(V,F);
  107. conjugate_pvf = smooth_pvf;
  108. igl::Viewer viewer;
  109. // Plot the original mesh with a texture parametrization
  110. key_down(viewer,'1',0);
  111. // Launch the viewer
  112. viewer.callback_key_down = &key_down;
  113. viewer.launch();
  114. }