Browse Source

Turn mesh visualization option into viewport bitmasks.

Jérémie Dumas 6 years ago
parent
commit
5065640657

+ 27 - 5
include/igl/opengl/ViewerCore.cpp

@@ -180,16 +180,16 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
   if (data.V.rows()>0)
   if (data.V.rows()>0)
   {
   {
     // Render fill
     // Render fill
-    if (data.show_faces)
+    if (is_set(data.show_faces))
     {
     {
       // Texture
       // Texture
-      glUniform1f(texture_factori, data.show_texture ? 1.0f : 0.0f);
+      glUniform1f(texture_factori, is_set(data.show_texture) ? 1.0f : 0.0f);
       data.meshgl.draw_mesh(true);
       data.meshgl.draw_mesh(true);
       glUniform1f(texture_factori, 0.0f);
       glUniform1f(texture_factori, 0.0f);
     }
     }
 
 
     // Render wireframe
     // Render wireframe
-    if (data.show_lines)
+    if (is_set(data.show_lines))
     {
     {
       glLineWidth(data.line_width);
       glLineWidth(data.line_width);
       glUniform4f(fixed_colori,
       glUniform4f(fixed_colori,
@@ -201,9 +201,9 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
     }
     }
   }
   }
 
 
-  if (data.show_overlay)
+  if (is_set(data.show_overlay))
   {
   {
-    if (data.show_overlay_depth)
+    if (is_set(data.show_overlay_depth))
       glEnable(GL_DEPTH_TEST);
       glEnable(GL_DEPTH_TEST);
     else
     else
       glDisable(GL_DEPTH_TEST);
       glDisable(GL_DEPTH_TEST);
@@ -352,6 +352,28 @@ IGL_INLINE void igl::opengl::ViewerCore::set_rotation_type(
   }
   }
 }
 }
 
 
+IGL_INLINE void igl::opengl::ViewerCore::set(unsigned int &property_mask, bool value) const
+{
+  if (!value)
+    unset(property_mask);
+  else
+    property_mask |= id;
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::unset(unsigned int &property_mask) const
+{
+  property_mask &= ~id;
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::toggle(unsigned int &property_mask) const
+{
+  property_mask ^= id;
+}
+
+IGL_INLINE bool igl::opengl::ViewerCore::is_set(unsigned int property_mask) const
+{
+  return (property_mask & id);
+}
 
 
 IGL_INLINE igl::opengl::ViewerCore::ViewerCore()
 IGL_INLINE igl::opengl::ViewerCore::ViewerCore()
 {
 {

+ 15 - 2
include/igl/opengl/ViewerCore.h

@@ -37,7 +37,6 @@ public:
   // Serialization code
   // Serialization code
   IGL_INLINE void InitSerialization();
   IGL_INLINE void InitSerialization();
 
 
-
   // ------------------- Camera control functions
   // ------------------- Camera control functions
 
 
   // Adjust the view to see the entire model
   // Adjust the view to see the entire model
@@ -91,10 +90,24 @@ public:
   };
   };
   IGL_INLINE void set_rotation_type(const RotationType & value);
   IGL_INLINE void set_rotation_type(const RotationType & value);
 
 
+  // ------------------- Option helpers
+
+  // Set a ViewerData visualization option for this viewport
+  IGL_INLINE void set(unsigned int &property_mask, bool value = true) const;
+
+  // Unset a ViewerData visualization option for this viewport
+  IGL_INLINE void unset(unsigned int &property_mask) const;
+
+  // Toggle a ViewerData visualization option for this viewport
+  IGL_INLINE void toggle(unsigned int &property_mask) const;
+
+  // Check whether a ViewerData visualization option is set for this viewport
+  IGL_INLINE bool is_set(unsigned int property_mask) const;
+
   // ------------------- Properties
   // ------------------- Properties
 
 
   // Unique identifier
   // Unique identifier
-  int id;
+  unsigned int id = 1u;
 
 
   // Colors
   // Colors
   Eigen::Vector4f background_color;
   Eigen::Vector4f background_color;

+ 10 - 1
include/igl/opengl/ViewerData.cpp

@@ -7,6 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 
 
 #include "ViewerData.h"
 #include "ViewerData.h"
+#include "ViewerCore.h"
 
 
 #include "../per_face_normals.h"
 #include "../per_face_normals.h"
 #include "../material_colors.h"
 #include "../material_colors.h"
@@ -121,6 +122,15 @@ IGL_INLINE void igl::opengl::ViewerData::set_visible(bool value, unsigned int co
   is_visible &= ~core_id;
   is_visible &= ~core_id;
 }
 }
 
 
+IGL_INLINE void igl::opengl::ViewerData::copy_options(const ViewerCore &from, const ViewerCore &to)
+{
+  to.set(show_overlay      , from.is_set(show_overlay)      );
+  to.set(show_overlay_depth, from.is_set(show_overlay_depth));
+  to.set(show_texture      , from.is_set(show_texture)      );
+  to.set(show_faces        , from.is_set(show_faces)        );
+  to.set(show_lines        , from.is_set(show_lines)        );
+}
+
 IGL_INLINE void igl::opengl::ViewerData::set_colors(const Eigen::MatrixXd &C)
 IGL_INLINE void igl::opengl::ViewerData::set_colors(const Eigen::MatrixXd &C)
 {
 {
   using namespace std;
   using namespace std;
@@ -222,7 +232,6 @@ IGL_INLINE void igl::opengl::ViewerData::set_uv(const Eigen::MatrixXd& UV_V, con
   dirty |= MeshGL::DIRTY_UV;
   dirty |= MeshGL::DIRTY_UV;
 }
 }
 
 
-
 IGL_INLINE void igl::opengl::ViewerData::set_texture(
 IGL_INLINE void igl::opengl::ViewerData::set_texture(
   const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& R,
   const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& R,
   const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& G,
   const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& G,

+ 18 - 8
include/igl/opengl/ViewerData.h

@@ -34,6 +34,9 @@ namespace igl
 namespace opengl
 namespace opengl
 {
 {
 
 
+// Forward declaration
+class ViewerCore;
+
 class ViewerData
 class ViewerData
 {
 {
 public:
 public:
@@ -135,6 +138,9 @@ public:
   // Generates a default grid texture
   // Generates a default grid texture
   IGL_INLINE void grid_texture();
   IGL_INLINE void grid_texture();
 
 
+  // Copy visualization options from one viewport to another
+  IGL_INLINE void copy_options(const ViewerCore &from, const ViewerCore &to);
+
   Eigen::MatrixXd V; // Vertices of the current mesh (#V x 3)
   Eigen::MatrixXd V; // Vertices of the current mesh (#V x 3)
   Eigen::MatrixXi F; // Faces of the mesh (#F x 3)
   Eigen::MatrixXi F; // Faces of the mesh (#F x 3)
 
 
@@ -186,16 +192,20 @@ public:
   // Enable per-face or per-vertex properties
   // Enable per-face or per-vertex properties
   bool face_based;
   bool face_based;
 
 
+  // Invert mesh normals
+  bool invert_normals;
+
   // Visualization options
   // Visualization options
+  // Each option is a binary mask specifying on which viewport each option is set.
+  // When using a single viewport, standard boolean can still be used for simplicity.
   unsigned int is_visible;
   unsigned int is_visible;
-  bool show_overlay;
-  bool show_overlay_depth;
-  bool show_texture;
-  bool show_faces;
-  bool show_lines;
-  bool show_vertid;
-  bool show_faceid;
-  bool invert_normals;
+  unsigned int show_overlay;
+  unsigned int show_overlay_depth;
+  unsigned int show_texture;
+  unsigned int show_faces;
+  unsigned int show_lines;
+  bool show_vertid; // shared across viewports for now
+  bool show_faceid; // shared across viewports for now
 
 
   // Point size / line width
   // Point size / line width
   float point_size;
   float point_size;

+ 15 - 2
include/igl/opengl/glfw/Viewer.cpp

@@ -523,7 +523,7 @@ namespace glfw
       case 'L':
       case 'L':
       case 'l':
       case 'l':
       {
       {
-        data().show_lines = !data().show_lines;
+        core().toggle(data().show_lines);
         return true;
         return true;
       }
       }
       case 'O':
       case 'O':
@@ -535,7 +535,7 @@ namespace glfw
       case 'T':
       case 'T':
       case 't':
       case 't':
       {
       {
-        data().show_faces = !data().show_faces;
+        core().toggle(data().show_faces);
         return true;
         return true;
       }
       }
       case 'Z':
       case 'Z':
@@ -560,6 +560,13 @@ namespace glfw
           (selected_data_index + data_list.size() + (unicode_key=='>'?1:-1))%data_list.size();
           (selected_data_index + data_list.size() + (unicode_key=='>'?1:-1))%data_list.size();
         return true;
         return true;
       }
       }
+      case '{':
+      case '}':
+      {
+        selected_core_index =
+          (selected_core_index + core_list.size() + (unicode_key=='}'?1:-1))%core_list.size();
+        return true;
+      }
       case ';':
       case ';':
         data().show_vertid = !data().show_vertid;
         data().show_vertid = !data().show_vertid;
         return true;
         return true;
@@ -1070,8 +1077,14 @@ namespace glfw
     core_list.back().id = next_core_id;
     core_list.back().id = next_core_id;
     next_core_id <<= 1;
     next_core_id <<= 1;
     if (!append_empty)
     if (!append_empty)
+    {
       for (auto &data : data_list)
       for (auto &data : data_list)
+      {
         data.set_visible(true, core_list.back().id);
         data.set_visible(true, core_list.back().id);
+        data.copy_options(core(), core_list.back());
+      }
+    }
+    selected_core_index = core_list.size()-1;
     return core_list.back().id;
     return core_list.back().id;
   }
   }
 
 

+ 9 - 0
include/igl/opengl/glfw/imgui/ImGuiHelpers.h

@@ -101,6 +101,15 @@ inline bool SliderScalar(const char *label, T* value, T min = 0, T max = 0, cons
   return SliderScalar(label, ImGuiDataTypeTraits<T>::value, value, &min, &max, fmt);
   return SliderScalar(label, ImGuiDataTypeTraits<T>::value, value, &min, &max, fmt);
 }
 }
 
 
+template<typename Getter, typename Setter>
+inline bool Checkbox(const char* label, Getter get, Setter set)
+{
+  bool value = get();
+  bool ret = ImGui::Checkbox(label, &value);
+  set(value);
+  return ret;
+}
+
 } // namespace ImGui
 } // namespace ImGui
 
 
 #endif // IGL_OPENGL_GLFW_IMGUI_IMGUIHELPERS_H
 #endif // IGL_OPENGL_GLFW_IMGUI_IMGUIHELPERS_H

+ 15 - 5
include/igl/opengl/glfw/imgui/ImGuiMenu.cpp

@@ -7,6 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 #include "ImGuiMenu.h"
 #include "ImGuiMenu.h"
+#include "ImGuiHelpers.h"
 #include <igl/project.h>
 #include <igl/project.h>
 #include <imgui/imgui.h>
 #include <imgui/imgui.h>
 #include <imgui_impl_glfw.h>
 #include <imgui_impl_glfw.h>
@@ -261,6 +262,15 @@ IGL_INLINE void ImGuiMenu::draw_viewer_menu()
     ImGui::PopItemWidth();
     ImGui::PopItemWidth();
   }
   }
 
 
+  // Helper for setting viewport specific mesh options
+  auto make_checkbox = [&](const char *label, unsigned int &option)
+  {
+    return ImGui::Checkbox(label,
+      [&]() { return viewer->core().is_set(option); },
+      [&](bool value) { return viewer->core().set(option, value); }
+    );
+  };
+
   // Draw options
   // Draw options
   if (ImGui::CollapsingHeader("Draw Options", ImGuiTreeNodeFlags_DefaultOpen))
   if (ImGui::CollapsingHeader("Draw Options", ImGuiTreeNodeFlags_DefaultOpen))
   {
   {
@@ -268,13 +278,13 @@ IGL_INLINE void ImGuiMenu::draw_viewer_menu()
     {
     {
       viewer->data().dirty = MeshGL::DIRTY_ALL;
       viewer->data().dirty = MeshGL::DIRTY_ALL;
     }
     }
-    ImGui::Checkbox("Show texture", &(viewer->data().show_texture));
+    make_checkbox("Show texture", viewer->data().show_texture);
     if (ImGui::Checkbox("Invert normals", &(viewer->data().invert_normals)))
     if (ImGui::Checkbox("Invert normals", &(viewer->data().invert_normals)))
     {
     {
       viewer->data().dirty |= igl::opengl::MeshGL::DIRTY_NORMAL;
       viewer->data().dirty |= igl::opengl::MeshGL::DIRTY_NORMAL;
     }
     }
-    ImGui::Checkbox("Show overlay", &(viewer->data().show_overlay));
-    ImGui::Checkbox("Show overlay depth", &(viewer->data().show_overlay_depth));
+    make_checkbox("Show overlay", viewer->data().show_overlay);
+    make_checkbox("Show overlay depth", viewer->data().show_overlay_depth);
     ImGui::ColorEdit4("Background", viewer->core().background_color.data(),
     ImGui::ColorEdit4("Background", viewer->core().background_color.data(),
         ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_PickerHueWheel);
         ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_PickerHueWheel);
     ImGui::ColorEdit4("Line color", viewer->data().line_color.data(),
     ImGui::ColorEdit4("Line color", viewer->data().line_color.data(),
@@ -287,8 +297,8 @@ IGL_INLINE void ImGuiMenu::draw_viewer_menu()
   // Overlays
   // Overlays
   if (ImGui::CollapsingHeader("Overlays", ImGuiTreeNodeFlags_DefaultOpen))
   if (ImGui::CollapsingHeader("Overlays", ImGuiTreeNodeFlags_DefaultOpen))
   {
   {
-    ImGui::Checkbox("Wireframe", &(viewer->data().show_lines));
-    ImGui::Checkbox("Fill", &(viewer->data().show_faces));
+    make_checkbox("Wireframe", viewer->data().show_lines);
+    make_checkbox("Fill", viewer->data().show_faces);
     ImGui::Checkbox("Show vertex labels", &(viewer->data().show_vertid));
     ImGui::Checkbox("Show vertex labels", &(viewer->data().show_vertid));
     ImGui::Checkbox("Show faces labels", &(viewer->data().show_faceid));
     ImGui::Checkbox("Show faces labels", &(viewer->data().show_faceid));
   }
   }

+ 0 - 1
tutorial/106_ViewerMenu/main.cpp

@@ -86,7 +86,6 @@ int main(int argc, char *argv[])
         ImGuiWindowFlags_NoSavedSettings
         ImGuiWindowFlags_NoSavedSettings
     );
     );
 
 
-
     // Expose the same variable directly ...
     // Expose the same variable directly ...
     ImGui::PushItemWidth(-80);
     ImGui::PushItemWidth(-80);
     ImGui::DragScalar("double", ImGuiDataType_Double, &doubleVariable, 0.1, 0, 0, "%.4f");
     ImGui::DragScalar("double", ImGuiDataType_Double, &doubleVariable, 0.1, 0, 0, "%.4f");

+ 1 - 1
tutorial/108_MultipleViews/main.cpp

@@ -19,7 +19,7 @@ int main(int argc, char * argv[])
     viewer.core().viewport = Eigen::Vector4f(0, 0, 640, 800);
     viewer.core().viewport = Eigen::Vector4f(0, 0, 640, 800);
     left_view = viewer.core_list[0].id;
     left_view = viewer.core_list[0].id;
     right_view = viewer.append_core(Eigen::Vector4f(640, 0, 640, 800));
     right_view = viewer.append_core(Eigen::Vector4f(640, 0, 640, 800));
-    return true;
+    return false;
   };
   };
 
 
   viewer.callback_key_down = [&](igl::opengl::glfw::Viewer &, unsigned int key, int mod)
   viewer.callback_key_down = [&](igl::opengl::glfw::Viewer &, unsigned int key, int mod)