main.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #include <igl/unproject_onto_mesh.h>
  2. #include <igl/viewer/Viewer.h>
  3. #include <igl/readDMAT.h>
  4. #include <igl/jet.h>
  5. #include <hedra/polygonal_read_OFF.h>
  6. #include <hedra/triangulate_mesh.h>
  7. #include <hedra/polygonal_edge_topology.h>
  8. #include <hedra/point_spheres.h>
  9. #include <hedra/scalar2RGB.h>
  10. #include <hedra/LMSolver.h>
  11. #include <hedra/EigenSolverWrapper.h>
  12. #include <hedra/DiscreteShellsTraits.h>
  13. #include <Eigen/SparseCholesky>
  14. #include <hedra/check_traits.h>
  15. std::vector<int> Handles;
  16. std::vector<Eigen::RowVector3d> HandlePoses;
  17. int CurrentHandle;
  18. Eigen::MatrixXd VOrig, V;
  19. Eigen::MatrixXi F, T;
  20. Eigen::VectorXi D, TF;
  21. Eigen::MatrixXi EV, EF, FE, EFi;
  22. Eigen::MatrixXd FEs;
  23. Eigen::VectorXi innerEdges;
  24. Eigen::Vector3d spans;
  25. bool Editing=false;
  26. bool ChoosingHandleMode=false;
  27. double CurrWinZ;
  28. typedef hedra::optimization::EigenSolverWrapper<Eigen::SimplicialLLT<Eigen::SparseMatrix<double> > > LinearSolver;
  29. hedra::optimization::DiscreteShellsTraits dst;
  30. LinearSolver esw;
  31. hedra::optimization::LMSolver<LinearSolver, hedra::optimization::DiscreteShellsTraits> lmSolver;
  32. bool UpdateCurrentView(igl::viewer::Viewer & viewer)
  33. {
  34. using namespace Eigen;
  35. using namespace std;
  36. MatrixXd sphereV;
  37. MatrixXi sphereT;
  38. MatrixXd sphereTC;
  39. Eigen::MatrixXd bc(Handles.size(),V.cols());
  40. for (int i=0;i<Handles.size();i++)
  41. bc.row(i)=HandlePoses[i].transpose();
  42. double sphereRadius=spans.sum()/200.0;
  43. MatrixXd sphereGreens(Handles.size(),3);
  44. sphereGreens.col(0).setZero();
  45. sphereGreens.col(1).setOnes();
  46. sphereGreens.col(2).setZero();
  47. hedra::point_spheres(bc, sphereRadius, sphereGreens, 10, false, sphereV, sphereT, sphereTC);
  48. Eigen::MatrixXd bigV(V.rows()+sphereV.rows(),3);
  49. Eigen::MatrixXi bigT(T.rows()+sphereT.rows(),3);
  50. if (sphereV.rows()!=0){
  51. bigV<<V, sphereV;
  52. bigT<<T, sphereT+Eigen::MatrixXi::Constant(sphereT.rows(), sphereT.cols(), V.rows());
  53. } else{
  54. bigV<<V;
  55. bigT<<T;
  56. }
  57. viewer.core.show_lines=false;
  58. Eigen::MatrixXd OrigEdgeColors(EV.rows(),3);
  59. OrigEdgeColors.col(0)=Eigen::VectorXd::Constant(EV.rows(),0.0);
  60. OrigEdgeColors.col(1)=Eigen::VectorXd::Constant(EV.rows(),0.0);
  61. OrigEdgeColors.col(2)=Eigen::VectorXd::Constant(EV.rows(),0.0);
  62. viewer.data.clear();
  63. viewer.data.set_mesh(bigV,bigT);
  64. viewer.data.compute_normals();
  65. viewer.data.set_edges(V,EV,OrigEdgeColors);
  66. return true;
  67. }
  68. bool mouse_move(igl::viewer::Viewer& viewer, int mouse_x, int mouse_y)
  69. {
  70. if (!Editing)
  71. return false;
  72. double x = viewer.current_mouse_x;
  73. double y = viewer.core.viewport(3) - viewer.current_mouse_y;
  74. Eigen::RowVector3f NewPos=igl::unproject<float>(Eigen::Vector3f(x,y,CurrWinZ),
  75. viewer.core.view * viewer.core.model,
  76. viewer.core.proj,
  77. viewer.core.viewport);
  78. HandlePoses[HandlePoses.size()-1]=NewPos.cast<double>();
  79. Eigen::RowVector3d Diff=HandlePoses[HandlePoses.size()-1]-VOrig.row(Handles[HandlePoses.size()-1]);
  80. Eigen::MatrixXd bc(Handles.size(),V.cols());
  81. for (int i=0;i<Handles.size();i++)
  82. bc.row(i)=HandlePoses[i].transpose();
  83. dst.qh=bc;
  84. lmSolver.solve(true);
  85. V=dst.fullSolution;
  86. UpdateCurrentView(viewer);
  87. return true;
  88. }
  89. bool mouse_up(igl::viewer::Viewer& viewer, int button, int modifier)
  90. {
  91. if (((igl::viewer::Viewer::MouseButton)button==igl::viewer::Viewer::MouseButton::Left))
  92. return false;
  93. Editing=false;
  94. return true;
  95. }
  96. bool mouse_down(igl::viewer::Viewer& viewer, int button, int modifier)
  97. {
  98. if (((igl::viewer::Viewer::MouseButton)button==igl::viewer::Viewer::MouseButton::Left))
  99. return false;
  100. int vid, fid;
  101. Eigen::Vector3f bc;
  102. double x = viewer.current_mouse_x;
  103. double y = viewer.core.viewport(3) - viewer.current_mouse_y;
  104. if (!ChoosingHandleMode){
  105. Editing=true;
  106. return false;
  107. }
  108. if(igl::unproject_onto_mesh(Eigen::Vector2f(x,y), viewer.core.view * viewer.core.model,
  109. viewer.core.proj, viewer.core.viewport, V, F, fid, bc))
  110. {
  111. //add the closest vertex to the handles
  112. Eigen::MatrixXf::Index maxRow, maxCol;
  113. bc.maxCoeff(&maxRow);
  114. int CurrVertex=F(fid, maxRow);
  115. bool Found=false;
  116. for (int i=0;i<Handles.size();i++)
  117. if (Handles[i]==CurrVertex){
  118. CurrVertex=Handles[i];
  119. Found=true;
  120. }
  121. if (!Found){
  122. Handles.push_back(CurrVertex);
  123. HandlePoses.push_back(V.row(CurrVertex));
  124. }
  125. Eigen::Vector3f WinCoords=igl::project<float>(V.row(CurrVertex).cast<float>(),
  126. viewer.core.view * viewer.core.model,
  127. viewer.core.proj,
  128. viewer.core.viewport);
  129. CurrWinZ=WinCoords(2);
  130. std::cout<<"Choosing Vertex :"<<CurrVertex<<std::endl;
  131. Eigen::VectorXi b(Handles.size());
  132. for (int i=0;i<Handles.size();i++)
  133. b(i)=Handles[i];
  134. dst.init(VOrig, T, b, EV, EF, EFi,innerEdges);
  135. lmSolver.init(&esw, &dst, 250, 10e-6);
  136. UpdateCurrentView(viewer);
  137. }
  138. return true;
  139. }
  140. bool key_up(igl::viewer::Viewer& viewer, unsigned char key, int modifiers)
  141. {
  142. switch(key)
  143. {
  144. case '1': ChoosingHandleMode=false;
  145. break;
  146. }
  147. return false;
  148. }
  149. bool key_down(igl::viewer::Viewer& viewer, unsigned char key, int modifiers)
  150. {
  151. switch(key)
  152. {
  153. case '1': ChoosingHandleMode=true;
  154. break;
  155. }
  156. return false;
  157. }
  158. int main(int argc, char *argv[])
  159. {
  160. // Load a mesh in OFF format
  161. using namespace std;
  162. using namespace Eigen;
  163. hedra::polygonal_read_OFF(DATA_PATH "/moomoo.off", V, D, F);
  164. hedra::triangulate_mesh(D, F, T, TF);
  165. VectorXi DT=VectorXi::Constant(T.rows(),3);
  166. hedra::polygonal_edge_topology(DT, T, EV, FE, EF,EFi,FEs,innerEdges);
  167. spans=V.colwise().maxCoeff()-V.colwise().minCoeff();
  168. VOrig=V;
  169. igl::viewer::Viewer viewer;
  170. viewer.callback_mouse_down = &mouse_down;
  171. viewer.callback_mouse_move = &mouse_move;
  172. viewer.callback_mouse_up=&mouse_up;
  173. viewer.callback_key_down=&key_down;
  174. viewer.callback_key_up=&key_up;
  175. viewer.core.background_color<<0.75,0.75,0.75,1.0;
  176. UpdateCurrentView(viewer);
  177. viewer.launch();
  178. cout<<"press 1+right button to select new handles"<<endl;
  179. cout<<"press the right button and drag the edit the mesh"<<endl;
  180. }