ImGuiMenu.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2022 Alec Jacobson <[email protected]>
  4. // Copyright (C) 2018 Jérémie Dumas <[email protected]>
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla Public License
  7. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  8. // obtain one at http://mozilla.org/MPL/2.0/.
  9. ////////////////////////////////////////////////////////////////////////////////
  10. #include "ImGuiMenu.h"
  11. #include "ImGuiHelpers.h"
  12. #include <imgui.h>
  13. #include <iostream>
  14. namespace igl
  15. {
  16. namespace opengl
  17. {
  18. namespace glfw
  19. {
  20. namespace imgui
  21. {
  22. // Is this needed?
  23. IGL_INLINE void ImGuiMenu::init( Viewer *_viewer, ImGuiPlugin *_plugin)
  24. { viewer = _viewer; plugin = _plugin; }
  25. IGL_INLINE void ImGuiMenu::shutdown() { }
  26. IGL_INLINE void ImGuiMenu::draw()
  27. {
  28. // Viewer settings
  29. if (callback_draw_viewer_window) { callback_draw_viewer_window(); }
  30. else { draw_viewer_window(); }
  31. // Other windows
  32. if (callback_draw_custom_window) { callback_draw_custom_window(); }
  33. else { draw_custom_window(); }
  34. }
  35. IGL_INLINE void ImGuiMenu::draw_viewer_window()
  36. {
  37. ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_FirstUseEver);
  38. ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f), ImGuiCond_FirstUseEver);
  39. bool _viewer_menu_visible = true;
  40. ImGui::Begin(
  41. "Viewer", &_viewer_menu_visible,
  42. ImGuiWindowFlags_NoSavedSettings
  43. | ImGuiWindowFlags_AlwaysAutoResize
  44. );
  45. ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.4f);
  46. if (callback_draw_viewer_menu) { callback_draw_viewer_menu(); }
  47. else { draw_viewer_menu(); }
  48. ImGui::PopItemWidth();
  49. ImGui::End();
  50. }
  51. IGL_INLINE void ImGuiMenu::draw_viewer_menu()
  52. {
  53. // Workspace
  54. if (ImGui::CollapsingHeader("Workspace", ImGuiTreeNodeFlags_DefaultOpen))
  55. {
  56. float w = ImGui::GetContentRegionAvail().x;
  57. float p = ImGui::GetStyle().FramePadding.x;
  58. if (ImGui::Button("Load##Workspace", ImVec2((w-p)/2.f, 0)))
  59. {
  60. viewer->load_scene();
  61. }
  62. ImGui::SameLine(0, p);
  63. if (ImGui::Button("Save##Workspace", ImVec2((w-p)/2.f, 0)))
  64. {
  65. viewer->save_scene();
  66. }
  67. }
  68. // Mesh
  69. if (ImGui::CollapsingHeader("Mesh", ImGuiTreeNodeFlags_DefaultOpen))
  70. {
  71. float w = ImGui::GetContentRegionAvail().x;
  72. float p = ImGui::GetStyle().FramePadding.x;
  73. if (ImGui::Button("Load##Mesh", ImVec2((w-p)/2.f, 0)))
  74. {
  75. viewer->open_dialog_load_mesh();
  76. }
  77. ImGui::SameLine(0, p);
  78. if (ImGui::Button("Save##Mesh", ImVec2((w-p)/2.f, 0)))
  79. {
  80. viewer->open_dialog_save_mesh();
  81. }
  82. }
  83. // Viewing options
  84. if (ImGui::CollapsingHeader("Viewing Options", ImGuiTreeNodeFlags_DefaultOpen))
  85. {
  86. if (ImGui::Button("Center object", ImVec2(-1, 0)))
  87. {
  88. viewer->core().align_camera_center(viewer->data().V, viewer->data().F);
  89. }
  90. if (ImGui::Button("Snap canonical view", ImVec2(-1, 0)))
  91. {
  92. viewer->snap_to_canonical_quaternion();
  93. }
  94. // Zoom
  95. ImGui::PushItemWidth(80 * menu_scaling());
  96. ImGui::DragFloat("Zoom", &(viewer->core().camera_zoom), 0.05f, 0.1f, 20.0f);
  97. // Select rotation type
  98. int rotation_type = static_cast<int>(viewer->core().rotation_type);
  99. static Eigen::Quaternionf trackball_angle = Eigen::Quaternionf::Identity();
  100. static bool orthographic = true;
  101. if (ImGui::Combo("Camera Type", &rotation_type, "Trackball\0Two Axes\0002D Mode\0\0"))
  102. {
  103. using RT = igl::opengl::ViewerCore::RotationType;
  104. auto new_type = static_cast<RT>(rotation_type);
  105. if (new_type != viewer->core().rotation_type)
  106. {
  107. if (new_type == RT::ROTATION_TYPE_NO_ROTATION)
  108. {
  109. trackball_angle = viewer->core().trackball_angle;
  110. orthographic = viewer->core().orthographic;
  111. viewer->core().trackball_angle = Eigen::Quaternionf::Identity();
  112. viewer->core().orthographic = true;
  113. }
  114. else if (viewer->core().rotation_type == RT::ROTATION_TYPE_NO_ROTATION)
  115. {
  116. viewer->core().trackball_angle = trackball_angle;
  117. viewer->core().orthographic = orthographic;
  118. }
  119. viewer->core().set_rotation_type(new_type);
  120. }
  121. }
  122. // Orthographic view
  123. ImGui::Checkbox("Orthographic view", &(viewer->core().orthographic));
  124. ImGui::PopItemWidth();
  125. }
  126. // Helper for setting viewport specific mesh options
  127. auto make_checkbox = [&](const char *label, unsigned int &option)
  128. {
  129. return ImGui::Checkbox(label,
  130. [&]() { return viewer->core().is_set(option); },
  131. [&](bool value) { return viewer->core().set(option, value); }
  132. );
  133. };
  134. // Draw options
  135. if (ImGui::CollapsingHeader("Draw Options", ImGuiTreeNodeFlags_DefaultOpen))
  136. {
  137. if (ImGui::Checkbox("Face-based", &(viewer->data().face_based)))
  138. {
  139. viewer->data().dirty = MeshGL::DIRTY_ALL;
  140. }
  141. make_checkbox("Show texture", viewer->data().show_texture);
  142. if (ImGui::Checkbox("Invert normals", &(viewer->data().invert_normals)))
  143. {
  144. viewer->data().dirty |= igl::opengl::MeshGL::DIRTY_NORMAL;
  145. }
  146. make_checkbox("Show overlay", viewer->data().show_overlay);
  147. make_checkbox("Show overlay depth", viewer->data().show_overlay_depth);
  148. ImGui::ColorEdit4("Background", viewer->core().background_color.data(),
  149. ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_PickerHueWheel);
  150. ImGui::ColorEdit4("Line color", viewer->data().line_color.data(),
  151. ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_PickerHueWheel);
  152. ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.3f);
  153. ImGui::DragFloat("Shininess", &(viewer->data().shininess), 0.05f, 0.0f, 100.0f);
  154. ImGui::PopItemWidth();
  155. }
  156. // Overlays
  157. if (ImGui::CollapsingHeader("Overlays", ImGuiTreeNodeFlags_DefaultOpen))
  158. {
  159. make_checkbox("Wireframe", viewer->data().show_lines);
  160. make_checkbox("Fill", viewer->data().show_faces);
  161. make_checkbox("Show vertex labels", viewer->data().show_vertex_labels);
  162. make_checkbox("Show faces labels", viewer->data().show_face_labels);
  163. make_checkbox("Show extra labels", viewer->data().show_custom_labels);
  164. }
  165. }
  166. } // end namespace
  167. } // end namespace
  168. } // end namespace
  169. } // end namespace