main.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <igl/read_triangle_mesh.h>
  2. #include <igl/readTGF.h>
  3. #include <igl/readDMAT.h>
  4. #include <igl/lbs_matrix.h>
  5. #include <igl/deform_skeleton.h>
  6. #include <igl/direct_delta_mush.h>
  7. #include <igl/opengl/glfw/Viewer.h>
  8. #include "tutorial_shared_path.h"
  9. #include <Eigen/Geometry>
  10. #include <vector>
  11. int main(int argc, char * argv[])
  12. {
  13. Eigen::MatrixXd V,U,C,W,T,M,Omega;
  14. Eigen::MatrixXi F,BE;
  15. igl::read_triangle_mesh(TUTORIAL_SHARED_PATH "/elephant.obj",V,F);
  16. igl::readTGF( TUTORIAL_SHARED_PATH "/elephant.tgf",C,BE);
  17. igl::readDMAT( TUTORIAL_SHARED_PATH "/elephant-weights.dmat",W);
  18. igl::readDMAT( TUTORIAL_SHARED_PATH "/elephant-anim.dmat",T);
  19. // convert weight to piecewise-rigid weights to stress test DDM
  20. for (int i = 0; i < W.rows(); ++i)
  21. {
  22. int maxj;
  23. W.row(i).maxCoeff(&maxj);
  24. for (int j = 0; j < W.cols(); j++)
  25. {
  26. W(i, j) = double(maxj == j);
  27. }
  28. }
  29. igl::lbs_matrix(V,W,M);
  30. int p = 20;
  31. float lambda = 3; // 0 < lambda
  32. float kappa = 1; // 0 < kappa < lambda
  33. float alpha = 0.8; // 0 <= alpha < 1
  34. Eigen::SparseMatrix<double> Wsparse = W.sparseView();
  35. igl::direct_delta_mush_precomputation(V, F,Wsparse, p, lambda, kappa, alpha, Omega);
  36. igl::opengl::glfw::Viewer viewer;
  37. int frame = 0;
  38. const int pr_id = viewer.selected_data_index;
  39. viewer.append_mesh();
  40. const int ddm_id = viewer.selected_data_index;
  41. Eigen::RowVector3d offset(1.1*(V.col(0).maxCoeff()-V.col(0).minCoeff()),0,0);
  42. viewer.callback_pre_draw = [&](igl::opengl::glfw::Viewer &) -> bool
  43. {
  44. if(viewer.core().is_animating)
  45. {
  46. const Eigen::Map<Eigen::MatrixXd> Tf(
  47. T.data()+frame*T.rows(),4*W.cols(),3);
  48. U = (M*Tf).rowwise()-offset;
  49. Eigen::MatrixXd Cf;
  50. Eigen::MatrixXi BEf;
  51. igl::deform_skeleton(C,BE,Tf,Cf,BEf);
  52. viewer.data(pr_id).set_edges(Cf,BEf, Eigen::RowVector3d(1,1,1));
  53. viewer.data(pr_id).set_vertices(U);
  54. viewer.data(pr_id).compute_normals();
  55. {
  56. std::vector<Eigen::Affine3d, Eigen::aligned_allocator<Eigen::Affine3d>>
  57. T_list(BE.rows());
  58. for (int e = 0; e < BE.rows(); e++)
  59. {
  60. T_list[e] = Eigen::Affine3d::Identity();
  61. T_list[e].matrix().block(0, 0, 3, 4) = Tf.block(e*4,0,4,3).transpose();
  62. }
  63. igl::direct_delta_mush(V, F, T_list, Omega, U);
  64. }
  65. U.rowwise() += offset;
  66. viewer.data(ddm_id).set_vertices(U);
  67. viewer.data(ddm_id).compute_normals();
  68. frame++;
  69. if(frame == T.cols())
  70. {
  71. frame = 0;
  72. viewer.core().is_animating = false;
  73. }
  74. }
  75. return false;
  76. };
  77. viewer.callback_key_pressed = [&](igl::opengl::glfw::Viewer &, unsigned int key, int mod)
  78. {
  79. switch(key)
  80. {
  81. case ' ':
  82. viewer.core().is_animating = !viewer.core().is_animating;
  83. return true;
  84. }
  85. return false;
  86. };
  87. for(auto & id : {pr_id,ddm_id})
  88. {
  89. if(id == pr_id)
  90. {
  91. viewer.data(id).set_mesh( (V.rowwise()-offset*1.0).eval() ,F);
  92. viewer.data(id).set_colors(Eigen::RowVector3d(214./255.,170./255.,148./255.));
  93. viewer.data(id).set_edges(C,BE, Eigen::RowVector3d(1,1,1));
  94. }else if(id == ddm_id){
  95. viewer.data(id).set_mesh( (V.rowwise()+offset*1.0).eval() ,F);
  96. viewer.data(id).set_colors(Eigen::RowVector3d(132./255.,214./255.,105./255.));
  97. }
  98. viewer.data(id).show_lines = false;
  99. viewer.data(id).set_face_based(true);
  100. viewer.data(id).show_overlay_depth = false;
  101. }
  102. viewer.core().is_animating = false;
  103. viewer.core().animation_max_fps = 24.;
  104. //viewer.data().set_colors(V,F);
  105. viewer.launch_init();
  106. viewer.core().align_camera_center(V);
  107. viewer.launch_rendering(true);
  108. viewer.launch_shut();
  109. }