main.cpp 7.3 KB

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