main.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include <igl/avg_edge_length.h>
  2. #include <igl/barycenter.h>
  3. #include <igl/jet.h>
  4. #include <igl/shapeup.h>
  5. #include <igl/shapeup_local_projections.h>
  6. #include <igl/quad_planarity.h>
  7. #include <igl/readDMAT.h>
  8. #include <igl/readOFF.h>
  9. #include <igl/slice.h>
  10. #include <igl/viewer/Viewer.h>
  11. #include <igl/PI.h>
  12. #include <vector>
  13. #include <cstdlib>
  14. #include "tutorial_shared_path.h"
  15. // Quad mesh loaded
  16. Eigen::MatrixXd VQC;
  17. Eigen::MatrixXi FQC;
  18. Eigen::MatrixXi E;
  19. Eigen::MatrixXi FQCtri;
  20. Eigen::MatrixXd PQC0, PQC1, PQC2, PQC3;
  21. // Euclidean-regular quad mesh
  22. Eigen::MatrixXd VQCregular;
  23. Eigen::MatrixXi FQCtriregular;
  24. Eigen::MatrixXd PQC0regular, PQC1regular, PQC2regular, PQC3regular;
  25. igl::ShapeupData su_data;
  26. // Scale for visualizing the fields
  27. double global_scale; //TODO: not used
  28. void quadAngleRegularity(const Eigen::MatrixXd& V, const Eigen::MatrixXi& Q, Eigen::VectorXd& angleRegularity)
  29. {
  30. angleRegularity.conservativeResize(Q.rows());
  31. angleRegularity.setZero();
  32. for (int i=0;i<Q.rows();i++){
  33. for (int j=0;j<4;j++){
  34. Eigen::RowVectorXd v21=(V.row(Q(i,j))-V.row(Q(i,(j+1)%4))).normalized();
  35. Eigen::RowVectorXd v23=(V.row(Q(i,(j+2)%4))-V.row(Q(i,(j+1)%4))).normalized();
  36. angleRegularity(i)+=(abs(acos(v21.dot(v23))-igl::PI/2.0)/(igl::PI/2.0))/4.0;
  37. }
  38. }
  39. }
  40. bool key_down(igl::viewer::Viewer& viewer, unsigned char key, int modifier)
  41. {
  42. using namespace std;
  43. using namespace Eigen;
  44. // Plot the original quad mesh
  45. if (key == '1')
  46. {
  47. viewer.data.clear();
  48. // Draw the triangulated quad mesh
  49. viewer.data.set_mesh(VQC, FQCtri);
  50. // Assign a color to each quad that corresponds to the average deviation of each angle from pi/2
  51. VectorXd angleRegularity(FQC.rows());
  52. quadAngleRegularity( VQC, FQC, angleRegularity);
  53. MatrixXd Ct;
  54. igl::jet(angleRegularity, 0.0, 0.05, Ct);
  55. MatrixXd C(FQCtri.rows(),3);
  56. C << Ct, Ct;
  57. viewer.data.set_colors(C);
  58. // Plot a line for each edge of the quad mesh
  59. viewer.data.add_edges(PQC0, PQC1, Eigen::RowVector3d(0,0,0));
  60. viewer.data.add_edges(PQC1, PQC2, Eigen::RowVector3d(0,0,0));
  61. viewer.data.add_edges(PQC2, PQC3, Eigen::RowVector3d(0,0,0));
  62. viewer.data.add_edges(PQC3, PQC0, Eigen::RowVector3d(0,0,0));
  63. }
  64. // Plot the planarized quad mesh
  65. if (key == '2')
  66. {
  67. viewer.data.clear();
  68. // Draw the triangulated quad mesh
  69. viewer.data.set_mesh(VQCregular, FQCtri);
  70. // Assign a color to each quad that corresponds to its planarity
  71. VectorXd angleRegularity(FQC.rows());
  72. quadAngleRegularity( VQCregular, FQC, angleRegularity);
  73. MatrixXd Ct;
  74. igl::jet(angleRegularity, 0, 0.05, Ct);
  75. MatrixXd C(FQCtri.rows(),3);
  76. C << Ct, Ct;
  77. viewer.data.set_colors(C);
  78. // Plot a line for each edge of the quad mesh
  79. viewer.data.add_edges(PQC0regular, PQC1regular, Eigen::RowVector3d(0,0,0));
  80. viewer.data.add_edges(PQC1regular, PQC2regular, Eigen::RowVector3d(0,0,0));
  81. viewer.data.add_edges(PQC2regular, PQC3regular, Eigen::RowVector3d(0,0,0));
  82. viewer.data.add_edges(PQC3regular, PQC0regular, Eigen::RowVector3d(0,0,0));
  83. }
  84. return false;
  85. }
  86. int main(int argc, char *argv[])
  87. {
  88. using namespace Eigen;
  89. using namespace std;
  90. // Load a quad mesh
  91. igl::readOFF(TUTORIAL_SHARED_PATH "/halftunnel.off", VQC, FQC);
  92. // Convert it in a triangle mesh
  93. FQCtri.resize(2*FQC.rows(), 3);
  94. FQCtri << FQC.col(0),FQC.col(1),FQC.col(2),
  95. FQC.col(2),FQC.col(3),FQC.col(0);
  96. igl::slice( VQC, FQC.col(0).eval(), 1, PQC0);
  97. igl::slice( VQC, FQC.col(1).eval(), 1, PQC1);
  98. igl::slice( VQC, FQC.col(2).eval(), 1, PQC2);
  99. igl::slice( VQC, FQC.col(3).eval(), 1, PQC3);
  100. // Create a planar version with ShapeUp
  101. //igl::planarize_quad_mesh(VQC, FQC, 100, 0.005, VQCregular);
  102. E.resize(FQC.size(),2);
  103. E.col(0)<<FQC.col(0),FQC.col(1),FQC.col(2),FQC.col(3);
  104. E.col(1)<<FQC.col(1),FQC.col(2),FQC.col(3),FQC.col(0);
  105. VectorXi b(1); b(0)=0; //setting the first vertex to be the same.
  106. VectorXd wShape=VectorXd::Constant(FQC.rows(),1.0);
  107. VectorXd wSmooth=VectorXd::Constant(E.rows(),1.0);
  108. MatrixXd bc(1,3); bc<<VQC.row(0);
  109. VectorXi array_of_fours=VectorXi::Constant(FQC.rows(),4);
  110. igl::shapeup_projection_function localFunction(igl::shapeup_regular_face_projection);
  111. su_data.maxIterations=200;
  112. shapeup_precomputation(VQC, array_of_fours,FQC,E,b,wShape, wSmooth,su_data);
  113. shapeup_solve(bc,localFunction, VQC,su_data, false,VQCregular);
  114. // Convert the planarized mesh to triangles
  115. igl::slice( VQCregular, FQC.col(0).eval(), 1, PQC0regular);
  116. igl::slice( VQCregular, FQC.col(1).eval(), 1, PQC1regular);
  117. igl::slice( VQCregular, FQC.col(2).eval(), 1, PQC2regular);
  118. igl::slice( VQCregular, FQC.col(3).eval(), 1, PQC3regular);
  119. // Launch the viewer
  120. igl::viewer::Viewer viewer;
  121. key_down(viewer,'1',0);
  122. viewer.core.invert_normals = true;
  123. viewer.core.show_lines = false;
  124. viewer.callback_key_down = &key_down;
  125. viewer.launch();
  126. }