SelectionPlugin.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include "SelectionPlugin.h"
  2. #include <imgui/imgui.h>
  3. #include <imgui_impl_glfw.h>
  4. #include <imgui_impl_opengl3.h>
  5. #include <imgui_fonts_droid_sans.h>
  6. #include <GLFW/glfw3.h>
  7. #include "../../../PI.h"
  8. namespace igl{ namespace opengl{ namespace glfw{ namespace imgui{
  9. IGL_INLINE void SelectionPlugin::init(igl::opengl::glfw::Viewer *_viewer)
  10. {
  11. ImGuiMenu::init(_viewer);
  12. std::cout<<R"(
  13. igl::opengl::glfw::imgui::SelectionPlugin usage:
  14. [drag] Draw a 2D selection
  15. l Turn on and toggle between lasso and polygonal lasso tool
  16. M,m Turn on and toggle between rectangular and circular marquee tool
  17. V,v Turn off interactive selection
  18. )";
  19. }
  20. IGL_INLINE bool SelectionPlugin::pre_draw()
  21. {
  22. if(mode == OFF){ return false; }
  23. ImGuiMenu::pre_draw();
  24. return false;
  25. }
  26. IGL_INLINE bool SelectionPlugin::post_draw()
  27. {
  28. if(mode == OFF){ return false; }
  29. ImGuiIO& io = ImGui::GetIO();
  30. float width, height;
  31. float highdpi = 1.0;
  32. {
  33. int fwidth, fheight;
  34. glfwGetFramebufferSize(viewer->window, &fwidth, &fheight);
  35. int iwidth, iheight;
  36. glfwGetWindowSize(viewer->window, &iwidth, &iheight);
  37. highdpi = float(iwidth)/float(fwidth);
  38. // highdpi
  39. width = (float)iwidth;
  40. height = (float)iheight;
  41. }
  42. ImGui::SetNextWindowPos( ImVec2(0,0) );
  43. ImGui::SetNextWindowSize(ImVec2(width,height), ImGuiCond_Always);
  44. ImGui::Begin("testing", nullptr,
  45. ImGuiWindowFlags_NoBackground
  46. | ImGuiWindowFlags_NoTitleBar
  47. | ImGuiWindowFlags_NoResize
  48. | ImGuiWindowFlags_NoMove
  49. | ImGuiWindowFlags_NoScrollbar
  50. | ImGuiWindowFlags_NoSavedSettings
  51. | ImGuiWindowFlags_NoInputs);
  52. ImDrawList* list = ImGui::GetWindowDrawList();
  53. for(int pass = 0;pass<2;pass++)
  54. {
  55. for(auto & p : L)
  56. {
  57. list->PathLineTo({ highdpi*p(0),height-highdpi*p(1) });
  58. }
  59. const bool closed = !(mode==LASSO || mode==POLYGONAL_LASSO) || !(is_down || is_drawing);
  60. if(pass == 0)
  61. {
  62. list->PathStroke(IM_COL32(255, 255, 255, 255), closed, 2);
  63. }else
  64. {
  65. list->PathStroke(IM_COL32(0, 0, 0, 255), closed, 1);
  66. }
  67. }
  68. ImGui::End();
  69. ImGui::Render();
  70. ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
  71. return false;
  72. }
  73. IGL_INLINE bool SelectionPlugin::mouse_down(int button, int modifier)
  74. {
  75. if(mode == OFF || (modifier & IGL_MOD_ALT) ){ return false;}
  76. is_down = true;
  77. has_moved_since_down = false;
  78. if(!is_drawing)
  79. {
  80. L.clear();
  81. is_drawing = true;
  82. }
  83. M.row(0) = xy(viewer);
  84. M.row(1) = M.row(0);
  85. L.emplace_back(M.row(0));
  86. return true;
  87. }
  88. IGL_INLINE bool SelectionPlugin::mouse_up(int button, int modifier)
  89. {
  90. is_down = false;
  91. // are we done? Check first and last lasso point (need at least 3 (2 real
  92. // points + 1 mouse-mouse point))
  93. if(is_drawing &&
  94. (mode!=POLYGONAL_LASSO ||(L.size()>=3&&(L[0]-L[L.size()-1]).norm()<=10.0)))
  95. {
  96. if(callback){ callback();}
  97. is_drawing = false;
  98. }
  99. return false;
  100. }
  101. IGL_INLINE bool SelectionPlugin::mouse_move(int mouse_x, int mouse_y)
  102. {
  103. if(!is_drawing){ return false; }
  104. if(!has_moved_since_down)
  105. {
  106. if(mode == POLYGONAL_LASSO) { L.emplace_back(L[L.size()-1]); }
  107. has_moved_since_down = true;
  108. }
  109. M.row(1) = xy(viewer);
  110. switch(mode)
  111. {
  112. case RECTANGULAR_MARQUEE:
  113. rect(M,L);
  114. break;
  115. case ELLIPTICAL_MARQUEE:
  116. circle(M,L);
  117. break;
  118. case POLYGONAL_LASSO:
  119. // Over write last point
  120. L[L.size()-1] = xy(viewer);
  121. break;
  122. case LASSO:
  123. L.emplace_back(xy(viewer));
  124. break;
  125. default: assert(false);
  126. }
  127. return true;
  128. }
  129. IGL_INLINE bool SelectionPlugin::key_pressed(unsigned int key, int modifiers)
  130. {
  131. Mode old = mode;
  132. if(OFF_KEY.find(char(key)) != std::string::npos)
  133. {
  134. mode = OFF;
  135. }else if(LASSO_KEY.find(char(key)) != std::string::npos)
  136. {
  137. if(mode == LASSO)
  138. {
  139. mode = POLYGONAL_LASSO;
  140. }else/*if(mode == POLYGONAL_LASSO)*/
  141. {
  142. mode = LASSO;
  143. }
  144. }else if(MARQUEE_KEY.find(char(key)) != std::string::npos)
  145. {
  146. if(mode == RECTANGULAR_MARQUEE)
  147. {
  148. mode = ELLIPTICAL_MARQUEE;
  149. }else/*if(mode == ELLIPTICAL_MARQUEE)*/
  150. {
  151. mode = RECTANGULAR_MARQUEE;
  152. }
  153. }
  154. if(old != mode)
  155. {
  156. clear();
  157. if(callback_post_mode_change){ callback_post_mode_change(old); }
  158. return true;
  159. }
  160. return false;
  161. }
  162. IGL_INLINE void SelectionPlugin::clear()
  163. {
  164. M.setZero();
  165. L.clear();
  166. is_drawing = false;
  167. is_down = false;
  168. };
  169. IGL_INLINE void SelectionPlugin::circle(const Eigen::Matrix<float,2,2> & M, std::vector<Eigen::RowVector2f> & L)
  170. {
  171. L.clear();
  172. L.reserve(64);
  173. const float r = (M.row(1)-M.row(0)).norm();
  174. for(float th = 0;th<2.*igl::PI;th+=0.1)
  175. {
  176. L.emplace_back(M(0,0)+r*cos(th),M(0,1)+r*sin(th));
  177. }
  178. }
  179. IGL_INLINE void SelectionPlugin::rect(const Eigen::Matrix<float,2,2> & M, std::vector<Eigen::RowVector2f> & L)
  180. {
  181. L.resize(4);
  182. L[0] = Eigen::RowVector2f(M(0,0),M(0,1));
  183. L[1] = Eigen::RowVector2f(M(1,0),M(0,1));
  184. L[2] = Eigen::RowVector2f(M(1,0),M(1,1));
  185. L[3] = Eigen::RowVector2f(M(0,0),M(1,1));
  186. }
  187. IGL_INLINE Eigen::RowVector2f SelectionPlugin::xy(const Viewer * vr)
  188. {
  189. return Eigen::RowVector2f(
  190. vr->current_mouse_x,
  191. vr->core().viewport(3) - vr->current_mouse_y);
  192. }
  193. }}}}