Просмотр исходного кода

- viewerdata and meshgl are merged
- meshgl objects are automatically initialized (but manually freed)
- moved the data->meshgl conversion inside viewerdata to keep meshgl generic


Former-commit-id: dc226a581068c3be196863dda8768ea2c9fe5c6c

Daniele Panozzo 8 лет назад
Родитель
Сommit
9080378e27

+ 43 - 264
include/igl/opengl/MeshGL.cpp

@@ -8,9 +8,9 @@
 
 #include "MeshGL.h"
 #include "bind_vertex_attrib_array.h"
-#include "ViewerData.h"
 #include "create_shader_program.h"
 #include "destroy_shader_program.h"
+#include <iostream>
 
 IGL_INLINE void igl::opengl::MeshGL::init_buffers()
 {
@@ -40,257 +40,32 @@ IGL_INLINE void igl::opengl::MeshGL::init_buffers()
   glGenBuffers(1, &vbo_points_V);
   glGenBuffers(1, &vbo_points_V_colors);
 
-  dirty = ViewerData::DIRTY_ALL;
+  dirty = MeshGL::DIRTY_ALL;
 }
 
 IGL_INLINE void igl::opengl::MeshGL::free_buffers()
 {
-  glDeleteVertexArrays(1, &vao_mesh);
-  glDeleteVertexArrays(1, &vao_overlay_lines);
-  glDeleteVertexArrays(1, &vao_overlay_points);
-
-  glDeleteBuffers(1, &vbo_V);
-  glDeleteBuffers(1, &vbo_V_normals);
-  glDeleteBuffers(1, &vbo_V_ambient);
-  glDeleteBuffers(1, &vbo_V_diffuse);
-  glDeleteBuffers(1, &vbo_V_specular);
-  glDeleteBuffers(1, &vbo_V_uv);
-  glDeleteBuffers(1, &vbo_F);
-  glDeleteBuffers(1, &vbo_lines_F);
-  glDeleteBuffers(1, &vbo_lines_V);
-  glDeleteBuffers(1, &vbo_lines_V_colors);
-  glDeleteBuffers(1, &vbo_points_F);
-  glDeleteBuffers(1, &vbo_points_V);
-  glDeleteBuffers(1, &vbo_points_V_colors);
-
-  glDeleteTextures(1, &vbo_tex);
-}
-
-IGL_INLINE void igl::opengl::MeshGL::set_data(
-  const igl::opengl::ViewerData &data, 
-  bool invert_normals)
-{
-  bool per_corner_uv = (data.F_uv.rows() == data.F.rows());
-  bool per_corner_normals = (data.F_normals.rows() == 3 * data.F.rows());
-
-  dirty |= data.dirty;
-
-  // Input:
-  //   X  #F by dim quantity
-  // Output:
-  //   X_vbo  #F*3 by dim scattering per corner
-  const auto per_face = [&data](
-      const Eigen::MatrixXd & X,
-      RowMatrixXf & X_vbo)
-  {
-    X_vbo.resize(data.F.rows()*3,3);
-    for (unsigned i=0; i<data.F.rows();++i)
-      for (unsigned j=0;j<3;++j)
-        X_vbo.row(i*3+j) = X.row(i).cast<float>().head(3);
-  };
-
-  // Input:
-  //   X  #V by dim quantity
-  // Output:
-  //   X_vbo  #F*3 by dim scattering per corner
-  const auto per_corner = [&data](
-      const Eigen::MatrixXd & X,
-      RowMatrixXf & X_vbo)
-  {
-    X_vbo.resize(data.F.rows()*3,3);
-    for (unsigned i=0; i<data.F.rows();++i)
-      for (unsigned j=0;j<3;++j)
-        X_vbo.row(i*3+j) = X.row(data.F(i,j)).cast<float>();
-  };
-
-  if (!data.face_based)
-  {
-    if (!(per_corner_uv || per_corner_normals))
-    {
-      // Vertex positions
-      if (dirty & ViewerData::DIRTY_POSITION)
-        V_vbo = data.V.cast<float>();
-
-      // Vertex normals
-      if (dirty & ViewerData::DIRTY_NORMAL)
-      {
-        V_normals_vbo = data.V_normals.cast<float>();
-        if (invert_normals)
-          V_normals_vbo = -V_normals_vbo;
-      }
-
-      // Per-vertex material settings
-      if (dirty & ViewerData::DIRTY_AMBIENT)
-        V_ambient_vbo = data.V_material_ambient.cast<float>();
-      if (dirty & ViewerData::DIRTY_DIFFUSE)
-        V_diffuse_vbo = data.V_material_diffuse.cast<float>();
-      if (dirty & ViewerData::DIRTY_SPECULAR)
-        V_specular_vbo = data.V_material_specular.cast<float>();
-
-      // Face indices
-      if (dirty & ViewerData::DIRTY_FACE)
-        F_vbo = data.F.cast<unsigned>();
-
-      // Texture coordinates
-      if (dirty & ViewerData::DIRTY_UV)
-        V_uv_vbo = data.V_uv.cast<float>();
-    }
-    else
-    {
-
-      // Per vertex properties with per corner UVs
-      if (dirty & ViewerData::DIRTY_POSITION)
-      {
-        per_corner(data.V,V_vbo);
-      }
-
-      if (dirty & ViewerData::DIRTY_AMBIENT)
-      {
-        V_ambient_vbo.resize(4,data.F.rows()*3);
-        for (unsigned i=0; i<data.F.rows();++i)
-          for (unsigned j=0;j<3;++j)
-            V_ambient_vbo.col (i*3+j) = data.V_material_ambient.row(data.F(i,j)).transpose().cast<float>();
-      }
-      if (dirty & ViewerData::DIRTY_DIFFUSE)
-      {
-        V_diffuse_vbo.resize(4,data.F.rows()*3);
-        for (unsigned i=0; i<data.F.rows();++i)
-          for (unsigned j=0;j<3;++j)
-            V_diffuse_vbo.col (i*3+j) = data.V_material_diffuse.row(data.F(i,j)).transpose().cast<float>();
-      }
-      if (dirty & ViewerData::DIRTY_SPECULAR)
-      {
-        V_specular_vbo.resize(4,data.F.rows()*3);
-        for (unsigned i=0; i<data.F.rows();++i)
-          for (unsigned j=0;j<3;++j)
-            V_specular_vbo.col(i*3+j) = data.V_material_specular.row(data.F(i,j)).transpose().cast<float>();
-      }
-
-      if (dirty & ViewerData::DIRTY_NORMAL)
-      {
-        V_normals_vbo.resize(3,data.F.rows()*3);
-        for (unsigned i=0; i<data.F.rows();++i)
-          for (unsigned j=0;j<3;++j)
-          
-            V_normals_vbo.col (i*3+j) = 
-                         per_corner_normals ?
-               data.F_normals.row(i*3+j).transpose().cast<float>() :
-               data.V_normals.row(data.F(i,j)).transpose().cast<float>();
-
-
-        if (invert_normals)
-          V_normals_vbo = -V_normals_vbo;
-      }
-
-      if (dirty & ViewerData::DIRTY_FACE)
-      {
-        F_vbo.resize(data.F.rows(),3);
-        for (unsigned i=0; i<data.F.rows();++i)
-          F_vbo.row(i) << i*3+0, i*3+1, i*3+2;
-      }
-
-      if (dirty & ViewerData::DIRTY_UV)
-      {
-        V_uv_vbo.resize(data.F.rows()*3,2);
-        for (unsigned i=0; i<data.F.rows();++i)
-          for (unsigned j=0;j<3;++j)
-            V_uv_vbo.row(i*3+j) = 
-              data.V_uv.row(per_corner_uv ? 
-                data.F_uv(i,j) : data.F(i,j)).cast<float>();
-      }
-    }
-  }
-  else
-  {
-    if (dirty & ViewerData::DIRTY_POSITION)
-    {
-      per_corner(data.V,V_vbo);
-    }
-
-    if (dirty & ViewerData::DIRTY_AMBIENT)
-    {
-      per_face(data.F_material_ambient,V_ambient_vbo);
-    }
-    if (dirty & ViewerData::DIRTY_DIFFUSE)
-    {
-      per_face(data.F_material_diffuse,V_diffuse_vbo);
-    }
-    if (dirty & ViewerData::DIRTY_SPECULAR)
-    {
-      per_face(data.F_material_specular,V_specular_vbo);
-    }
-
-    if (dirty & ViewerData::DIRTY_NORMAL)
-    {
-      V_normals_vbo.resize(data.F.rows()*3,3);
-      for (unsigned i=0; i<data.F.rows();++i)
-        for (unsigned j=0;j<3;++j)
-          V_normals_vbo.row(i*3+j) =
-             per_corner_normals ?
-               data.F_normals.row(i*3+j).cast<float>() :
-               data.F_normals.row(i).cast<float>();
-
-      if (invert_normals)
-        V_normals_vbo = -V_normals_vbo;
-    }
-
-    if (dirty & ViewerData::DIRTY_FACE)
-    {
-      F_vbo.resize(data.F.rows(),3);
-      for (unsigned i=0; i<data.F.rows();++i)
-        F_vbo.row(i) << i*3+0, i*3+1, i*3+2;
-    }
-
-    if (dirty & ViewerData::DIRTY_UV)
-    {
-        V_uv_vbo.resize(data.F.rows()*3,2);
-        for (unsigned i=0; i<data.F.rows();++i)
-          for (unsigned j=0;j<3;++j)
-            V_uv_vbo.row(i*3+j) = data.V_uv.row(per_corner_uv ? data.F_uv(i,j) : data.F(i,j)).cast<float>();
-    }
-  }
-
-  if (dirty & ViewerData::DIRTY_TEXTURE)
-  {
-    tex_u = data.texture_R.rows();
-    tex_v = data.texture_R.cols();
-    tex.resize(data.texture_R.size()*4);
-    for (unsigned i=0;i<data.texture_R.size();++i)
-    {
-      tex(i*4+0) = data.texture_R(i);
-      tex(i*4+1) = data.texture_G(i);
-      tex(i*4+2) = data.texture_B(i);
-      tex(i*4+3) = data.texture_A(i);
-    }
-  }
-
-  if (dirty & ViewerData::DIRTY_OVERLAY_LINES)
+  if (is_initialized)
   {
-    lines_V_vbo.resize(data.lines.rows()*2,3);
-    lines_V_colors_vbo.resize(data.lines.rows()*2,3);
-    lines_F_vbo.resize(data.lines.rows()*2,1);
-    for (unsigned i=0; i<data.lines.rows();++i)
-    {
-      lines_V_vbo.row(2*i+0) = data.lines.block<1, 3>(i, 0).cast<float>();
-      lines_V_vbo.row(2*i+1) = data.lines.block<1, 3>(i, 3).cast<float>();
-      lines_V_colors_vbo.row(2*i+0) = data.lines.block<1, 3>(i, 6).cast<float>();
-      lines_V_colors_vbo.row(2*i+1) = data.lines.block<1, 3>(i, 6).cast<float>();
-      lines_F_vbo(2*i+0) = 2*i+0;
-      lines_F_vbo(2*i+1) = 2*i+1;
-    }
-  }
-
-  if (dirty & ViewerData::DIRTY_OVERLAY_POINTS)
-  {
-    points_V_vbo.resize(data.points.rows(),3);
-    points_V_colors_vbo.resize(data.points.rows(),3);
-    points_F_vbo.resize(data.points.rows(),1);
-    for (unsigned i=0; i<data.points.rows();++i)
-    {
-      points_V_vbo.row(i) = data.points.block<1, 3>(i, 0).cast<float>();
-      points_V_colors_vbo.row(i) = data.points.block<1, 3>(i, 3).cast<float>();
-      points_F_vbo(i) = i;
-    }
+    glDeleteVertexArrays(1, &vao_mesh);
+    glDeleteVertexArrays(1, &vao_overlay_lines);
+    glDeleteVertexArrays(1, &vao_overlay_points);
+
+    glDeleteBuffers(1, &vbo_V);
+    glDeleteBuffers(1, &vbo_V_normals);
+    glDeleteBuffers(1, &vbo_V_ambient);
+    glDeleteBuffers(1, &vbo_V_diffuse);
+    glDeleteBuffers(1, &vbo_V_specular);
+    glDeleteBuffers(1, &vbo_V_uv);
+    glDeleteBuffers(1, &vbo_F);
+    glDeleteBuffers(1, &vbo_lines_F);
+    glDeleteBuffers(1, &vbo_lines_V);
+    glDeleteBuffers(1, &vbo_lines_V_colors);
+    glDeleteBuffers(1, &vbo_points_F);
+    glDeleteBuffers(1, &vbo_points_V);
+    glDeleteBuffers(1, &vbo_points_V_colors);
+
+    glDeleteTextures(1, &vbo_tex);
   }
 }
 
@@ -298,20 +73,20 @@ IGL_INLINE void igl::opengl::MeshGL::bind_mesh()
 {
   glBindVertexArray(vao_mesh);
   glUseProgram(shader_mesh);
-  bind_vertex_attrib_array(shader_mesh,"position", vbo_V, V_vbo, dirty & ViewerData::DIRTY_POSITION);
-  bind_vertex_attrib_array(shader_mesh,"normal", vbo_V_normals, V_normals_vbo, dirty & ViewerData::DIRTY_NORMAL);
-  bind_vertex_attrib_array(shader_mesh,"Ka", vbo_V_ambient, V_ambient_vbo, dirty & ViewerData::DIRTY_AMBIENT);
-  bind_vertex_attrib_array(shader_mesh,"Kd", vbo_V_diffuse, V_diffuse_vbo, dirty & ViewerData::DIRTY_DIFFUSE);
-  bind_vertex_attrib_array(shader_mesh,"Ks", vbo_V_specular, V_specular_vbo, dirty & ViewerData::DIRTY_SPECULAR);
-  bind_vertex_attrib_array(shader_mesh,"texcoord", vbo_V_uv, V_uv_vbo, dirty & ViewerData::DIRTY_UV);
+  bind_vertex_attrib_array(shader_mesh,"position", vbo_V, V_vbo, dirty & MeshGL::DIRTY_POSITION);
+  bind_vertex_attrib_array(shader_mesh,"normal", vbo_V_normals, V_normals_vbo, dirty & MeshGL::DIRTY_NORMAL);
+  bind_vertex_attrib_array(shader_mesh,"Ka", vbo_V_ambient, V_ambient_vbo, dirty & MeshGL::DIRTY_AMBIENT);
+  bind_vertex_attrib_array(shader_mesh,"Kd", vbo_V_diffuse, V_diffuse_vbo, dirty & MeshGL::DIRTY_DIFFUSE);
+  bind_vertex_attrib_array(shader_mesh,"Ks", vbo_V_specular, V_specular_vbo, dirty & MeshGL::DIRTY_SPECULAR);
+  bind_vertex_attrib_array(shader_mesh,"texcoord", vbo_V_uv, V_uv_vbo, dirty & MeshGL::DIRTY_UV);
 
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_F);
-  if (dirty & ViewerData::DIRTY_FACE)
+  if (dirty & MeshGL::DIRTY_FACE)
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned)*F_vbo.size(), F_vbo.data(), GL_DYNAMIC_DRAW);
 
   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, vbo_tex);
-  if (dirty & ViewerData::DIRTY_TEXTURE)
+  if (dirty & MeshGL::DIRTY_TEXTURE)
   {
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@@ -321,12 +96,12 @@ IGL_INLINE void igl::opengl::MeshGL::bind_mesh()
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_u, tex_v, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.data());
   }
   glUniform1i(glGetUniformLocation(shader_mesh,"tex"), 0);
-  dirty &= ~ViewerData::DIRTY_MESH;
+  dirty &= ~MeshGL::DIRTY_MESH;
 }
 
 IGL_INLINE void igl::opengl::MeshGL::bind_overlay_lines()
 {
-  bool is_dirty = dirty & ViewerData::DIRTY_OVERLAY_LINES;
+  bool is_dirty = dirty & MeshGL::DIRTY_OVERLAY_LINES;
 
   glBindVertexArray(vao_overlay_lines);
   glUseProgram(shader_overlay_lines);
@@ -337,12 +112,12 @@ IGL_INLINE void igl::opengl::MeshGL::bind_overlay_lines()
   if (is_dirty)
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned)*lines_F_vbo.size(), lines_F_vbo.data(), GL_DYNAMIC_DRAW);
 
-  dirty &= ~ViewerData::DIRTY_OVERLAY_LINES;
+  dirty &= ~MeshGL::DIRTY_OVERLAY_LINES;
 }
 
 IGL_INLINE void igl::opengl::MeshGL::bind_overlay_points()
 {
-  bool is_dirty = dirty & ViewerData::DIRTY_OVERLAY_POINTS;
+  bool is_dirty = dirty & MeshGL::DIRTY_OVERLAY_POINTS;
 
   glBindVertexArray(vao_overlay_points);
   glUseProgram(shader_overlay_points);
@@ -353,7 +128,7 @@ IGL_INLINE void igl::opengl::MeshGL::bind_overlay_points()
   if (is_dirty)
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned)*points_F_vbo.size(), points_F_vbo.data(), GL_DYNAMIC_DRAW);
 
-  dirty &= ~ViewerData::DIRTY_OVERLAY_POINTS;
+  dirty &= ~MeshGL::DIRTY_OVERLAY_POINTS;
 }
 
 IGL_INLINE void igl::opengl::MeshGL::draw_mesh(bool solid)
@@ -525,8 +300,12 @@ IGL_INLINE void igl::opengl::MeshGL::free()
       id = 0;
     }
   };
-  free(shader_mesh);
-  free(shader_overlay_lines);
-  free(shader_overlay_points);
-  free_buffers();
+
+  if (is_initialized)
+  {
+    free(shader_mesh);
+    free(shader_overlay_lines);
+    free(shader_overlay_points);
+    free_buffers();
+  }
 }

+ 18 - 4
include/igl/opengl/MeshGL.h

@@ -13,7 +13,7 @@
 // the data
 
 #include <igl/igl_inline.h>
-#include "ViewerData.h"
+#include <Eigen/Core>
 
 namespace igl
 {
@@ -25,6 +25,23 @@ class MeshGL
 public:
   typedef unsigned int GLuint;
 
+  enum DirtyFlags
+  {
+    DIRTY_NONE           = 0x0000,
+    DIRTY_POSITION       = 0x0001,
+    DIRTY_UV             = 0x0002,
+    DIRTY_NORMAL         = 0x0004,
+    DIRTY_AMBIENT        = 0x0008,
+    DIRTY_DIFFUSE        = 0x0010,
+    DIRTY_SPECULAR       = 0x0020,
+    DIRTY_TEXTURE        = 0x0040,
+    DIRTY_FACE           = 0x0080,
+    DIRTY_MESH           = 0x00FF,
+    DIRTY_OVERLAY_LINES  = 0x0100,
+    DIRTY_OVERLAY_POINTS = 0x0200,
+    DIRTY_ALL            = 0x03FF
+  };
+
   bool is_initialized = false;
   GLuint vao_mesh;
   GLuint vao_overlay_lines;
@@ -83,9 +100,6 @@ public:
   // Create a new set of OpenGL buffer objects
   IGL_INLINE void init_buffers();
 
-  // Update contents from a 'Data' instance
-  IGL_INLINE void set_data(const igl::opengl::ViewerData &data, bool invert_normals);
-
   // Bind the underlying OpenGL buffer objects for subsequent mesh draw calls
   IGL_INLINE void bind_mesh();
 

+ 24 - 26
include/igl/opengl/ViewerCore.cpp

@@ -96,7 +96,6 @@ IGL_INLINE void igl::opengl::ViewerCore::clear_framebuffers()
 
 IGL_INLINE void igl::opengl::ViewerCore::draw(
   ViewerData& data,
-  MeshGL& opengl,
   bool update_matrices)
 {
   using namespace std;
@@ -113,10 +112,10 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
   /* Bind and potentially refresh mesh/line/point data */
   if (data.dirty)
   {
-    opengl.set_data(data, data.invert_normals);
-    data.dirty = ViewerData::DIRTY_NONE;
+    data.updateGL(data, data.invert_normals,data.meshgl);
+    data.dirty = MeshGL::DIRTY_NONE;
   }
-  opengl.bind_mesh();
+  data.meshgl.bind_mesh();
 
   // Initialize uniform
   glViewport(viewport(0), viewport(1), viewport(2), viewport(3));
@@ -163,19 +162,19 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
   }
 
   // Send transformations to the GPU
-  GLint modeli = glGetUniformLocation(opengl.shader_mesh,"model");
-  GLint viewi  = glGetUniformLocation(opengl.shader_mesh,"view");
-  GLint proji  = glGetUniformLocation(opengl.shader_mesh,"proj");
+  GLint modeli = glGetUniformLocation(data.meshgl.shader_mesh,"model");
+  GLint viewi  = glGetUniformLocation(data.meshgl.shader_mesh,"view");
+  GLint proji  = glGetUniformLocation(data.meshgl.shader_mesh,"proj");
   glUniformMatrix4fv(modeli, 1, GL_FALSE, model.data());
   glUniformMatrix4fv(viewi, 1, GL_FALSE, view.data());
   glUniformMatrix4fv(proji, 1, GL_FALSE, proj.data());
 
   // Light parameters
-  GLint specular_exponenti    = glGetUniformLocation(opengl.shader_mesh,"specular_exponent");
-  GLint light_position_worldi = glGetUniformLocation(opengl.shader_mesh,"light_position_world");
-  GLint lighting_factori      = glGetUniformLocation(opengl.shader_mesh,"lighting_factor");
-  GLint fixed_colori          = glGetUniformLocation(opengl.shader_mesh,"fixed_color");
-  GLint texture_factori       = glGetUniformLocation(opengl.shader_mesh,"texture_factor");
+  GLint specular_exponenti    = glGetUniformLocation(data.meshgl.shader_mesh,"specular_exponent");
+  GLint light_position_worldi = glGetUniformLocation(data.meshgl.shader_mesh,"light_position_world");
+  GLint lighting_factori      = glGetUniformLocation(data.meshgl.shader_mesh,"lighting_factor");
+  GLint fixed_colori          = glGetUniformLocation(data.meshgl.shader_mesh,"fixed_color");
+  GLint texture_factori       = glGetUniformLocation(data.meshgl.shader_mesh,"texture_factor");
 
   glUniform1f(specular_exponenti, data.shininess);
   Vector3f rev_light = -1.*light_position;
@@ -190,7 +189,7 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
     {
       // Texture
       glUniform1f(texture_factori, data.show_texture ? 1.0f : 0.0f);
-      opengl.draw_mesh(true);
+      data.meshgl.draw_mesh(true);
       glUniform1f(texture_factori, 0.0f);
     }
 
@@ -202,7 +201,7 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
         data.line_color[0], 
         data.line_color[1],
         data.line_color[2], 1.0f);
-      opengl.draw_mesh(false);
+      data.meshgl.draw_mesh(false);
       glUniform4f(fixed_colori, 0.0f, 0.0f, 0.0f, 0.0f);
     }
 
@@ -242,10 +241,10 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
 
     if (data.lines.rows() > 0)
     {
-      opengl.bind_overlay_lines();
-      modeli = glGetUniformLocation(opengl.shader_overlay_lines,"model");
-      viewi  = glGetUniformLocation(opengl.shader_overlay_lines,"view");
-      proji  = glGetUniformLocation(opengl.shader_overlay_lines,"proj");
+      data.meshgl.bind_overlay_lines();
+      modeli = glGetUniformLocation(data.meshgl.shader_overlay_lines,"model");
+      viewi  = glGetUniformLocation(data.meshgl.shader_overlay_lines,"view");
+      proji  = glGetUniformLocation(data.meshgl.shader_overlay_lines,"proj");
 
       glUniformMatrix4fv(modeli, 1, GL_FALSE, model.data());
       glUniformMatrix4fv(viewi, 1, GL_FALSE, view.data());
@@ -254,22 +253,22 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
       glEnable(GL_LINE_SMOOTH);
       glLineWidth(data.line_width);
 
-      opengl.draw_overlay_lines();
+      data.meshgl.draw_overlay_lines();
     }
 
     if (data.points.rows() > 0)
     {
-      opengl.bind_overlay_points();
-      modeli = glGetUniformLocation(opengl.shader_overlay_points,"model");
-      viewi  = glGetUniformLocation(opengl.shader_overlay_points,"view");
-      proji  = glGetUniformLocation(opengl.shader_overlay_points,"proj");
+      data.meshgl.bind_overlay_points();
+      modeli = glGetUniformLocation(data.meshgl.shader_overlay_points,"model");
+      viewi  = glGetUniformLocation(data.meshgl.shader_overlay_points,"view");
+      proji  = glGetUniformLocation(data.meshgl.shader_overlay_points,"proj");
 
       glUniformMatrix4fv(modeli, 1, GL_FALSE, model.data());
       glUniformMatrix4fv(viewi, 1, GL_FALSE, view.data());
       glUniformMatrix4fv(proji, 1, GL_FALSE, proj.data());
       glPointSize(data.point_size);
 
-      opengl.draw_overlay_points();
+      data.meshgl.draw_overlay_points();
     }
 
 #ifdef IGL_VIEWER_WITH_NANOGUI
@@ -289,7 +288,6 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
 }
 
 IGL_INLINE void igl::opengl::ViewerCore::draw_buffer(ViewerData& data,
-  MeshGL& opengl,
   bool update_matrices,
   Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& R,
   Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& G,
@@ -339,7 +337,7 @@ IGL_INLINE void igl::opengl::ViewerCore::draw_buffer(ViewerData& data,
   viewport << 0,0,x,y;
 
   // Draw
-  draw(data,opengl,update_matrices);
+  draw(data,update_matrices);
 
   // Restore viewport
   viewport = viewport_ori;

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

@@ -75,10 +75,9 @@ public:
   // Draw everything
   //
   // data cannot be const because it is being set to "clean"
-  IGL_INLINE void draw(ViewerData& data, MeshGL& opengl, bool update_matrices = true);
+  IGL_INLINE void draw(ViewerData& data, bool update_matrices = true);
   IGL_INLINE void draw_buffer(
     ViewerData& data,
-    MeshGL& opengl,
     bool update_matrices,
     Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& R,
     Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& G,
@@ -99,7 +98,7 @@ public:
 
 #ifdef IGL_VIEWER_WITH_NANOGUI
   // Text rendering helper
-  TextRenderer textrenderer;
+  glfw::TextRenderer textrenderer;
 #endif
 
 

+ 253 - 17
include/igl/opengl/ViewerData.cpp

@@ -17,7 +17,7 @@
 
 
 IGL_INLINE igl::opengl::ViewerData::ViewerData()
-: dirty(DIRTY_ALL),
+: dirty(MeshGL::DIRTY_ALL),
   show_faces(true),
   show_lines(true),
   invert_normals(false),
@@ -39,7 +39,7 @@ IGL_INLINE void igl::opengl::ViewerData::set_face_based(bool newvalue)
   if (face_based != newvalue)
   {
     face_based = newvalue;
-    dirty = DIRTY_ALL;
+    dirty = MeshGL::DIRTY_ALL;
   }
 }
 
@@ -83,14 +83,14 @@ IGL_INLINE void igl::opengl::ViewerData::set_mesh(
     else
       cerr << "ERROR (set_mesh): The new mesh has a different number of vertices/faces. Please clear the mesh before plotting."<<endl;
   }
-  dirty |= DIRTY_FACE | DIRTY_POSITION;
+  dirty |= MeshGL::DIRTY_FACE | MeshGL::DIRTY_POSITION;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::set_vertices(const Eigen::MatrixXd& _V)
 {
   V = _V;
   assert(F.size() == 0 || F.maxCoeff() < V.rows());
-  dirty |= DIRTY_POSITION;
+  dirty |= MeshGL::DIRTY_POSITION;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::set_normals(const Eigen::MatrixXd& N)
@@ -108,7 +108,7 @@ IGL_INLINE void igl::opengl::ViewerData::set_normals(const Eigen::MatrixXd& N)
   }
   else
     cerr << "ERROR (set_normals): Please provide a normal per face, per corner or per vertex."<<endl;
-  dirty |= DIRTY_NORMAL;
+  dirty |= MeshGL::DIRTY_NORMAL;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::set_colors(const Eigen::MatrixXd &C)
@@ -175,7 +175,7 @@ IGL_INLINE void igl::opengl::ViewerData::set_colors(const Eigen::MatrixXd &C)
   }
   else
     cerr << "ERROR (set_colors): Please provide a single color, or a color per face or per vertex."<<endl;;
-  dirty |= DIRTY_DIFFUSE;
+  dirty |= MeshGL::DIRTY_DIFFUSE;
 
 }
 
@@ -189,7 +189,7 @@ IGL_INLINE void igl::opengl::ViewerData::set_uv(const Eigen::MatrixXd& UV)
   }
   else
     cerr << "ERROR (set_UV): Please provide uv per vertex."<<endl;;
-  dirty |= DIRTY_UV;
+  dirty |= MeshGL::DIRTY_UV;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::set_uv(const Eigen::MatrixXd& UV_V, const Eigen::MatrixXi& UV_F)
@@ -197,7 +197,7 @@ IGL_INLINE void igl::opengl::ViewerData::set_uv(const Eigen::MatrixXd& UV_V, con
   set_face_based(true);
   V_uv = UV_V.block(0,0,UV_V.rows(),2);
   F_uv = UV_F;
-  dirty |= DIRTY_UV;
+  dirty |= MeshGL::DIRTY_UV;
 }
 
 
@@ -210,7 +210,7 @@ IGL_INLINE void igl::opengl::ViewerData::set_texture(
   texture_G = G;
   texture_B = B;
   texture_A = Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>::Constant(R.rows(),R.cols(),255);
-  dirty |= DIRTY_TEXTURE;
+  dirty |= MeshGL::DIRTY_TEXTURE;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::set_texture(
@@ -223,7 +223,7 @@ IGL_INLINE void igl::opengl::ViewerData::set_texture(
   texture_G = G;
   texture_B = B;
   texture_A = A;
-  dirty |= DIRTY_TEXTURE;
+  dirty |= MeshGL::DIRTY_TEXTURE;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::set_points(
@@ -253,7 +253,7 @@ IGL_INLINE void igl::opengl::ViewerData::add_points(const Eigen::MatrixXd& P,  c
   for (unsigned i=0; i<P_temp.rows(); ++i)
     points.row(lastid+i) << P_temp.row(i), i<C.rows() ? C.row(i) : C.row(C.rows()-1);
 
-  dirty |= DIRTY_OVERLAY_POINTS;
+  dirty |= MeshGL::DIRTY_OVERLAY_POINTS;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::set_edges(
@@ -276,7 +276,7 @@ IGL_INLINE void igl::opengl::ViewerData::set_edges(
     }
     lines.row(e)<< P.row(E(e,0)), P.row(E(e,1)), color;
   }
-  dirty |= DIRTY_OVERLAY_LINES;
+  dirty |= MeshGL::DIRTY_OVERLAY_LINES;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::add_edges(const Eigen::MatrixXd& P1, const Eigen::MatrixXd& P2, const Eigen::MatrixXd& C)
@@ -302,7 +302,7 @@ IGL_INLINE void igl::opengl::ViewerData::add_edges(const Eigen::MatrixXd& P1, co
   for (unsigned i=0; i<P1_temp.rows(); ++i)
     lines.row(lastid+i) << P1_temp.row(i), P2_temp.row(i), i<C.rows() ? C.row(i) : C.row(C.rows()-1);
 
-  dirty |= DIRTY_OVERLAY_LINES;
+  dirty |= MeshGL::DIRTY_OVERLAY_LINES;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::add_label(const Eigen::VectorXd& P,  const std::string& str)
@@ -355,7 +355,7 @@ IGL_INLINE void igl::opengl::ViewerData::compute_normals()
 {
   igl::per_face_normals(V, F, F_normals);
   igl::per_vertex_normals(V, F, F_normals, V_normals);
-  dirty |= DIRTY_NORMAL;
+  dirty |= MeshGL::DIRTY_NORMAL;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::uniform_colors(
@@ -400,7 +400,7 @@ IGL_INLINE void igl::opengl::ViewerData::uniform_colors(
     F_material_diffuse.row(i) = diffuse;
     F_material_specular.row(i) = specular;
   }
-  dirty |= DIRTY_SPECULAR | DIRTY_DIFFUSE | DIRTY_AMBIENT;
+  dirty |= MeshGL::DIRTY_SPECULAR | MeshGL::DIRTY_DIFFUSE | MeshGL::DIRTY_AMBIENT;
 }
 
 IGL_INLINE void igl::opengl::ViewerData::grid_texture()
@@ -419,7 +419,7 @@ IGL_INLINE void igl::opengl::ViewerData::grid_texture()
     V_uv.col(1) = V_uv.col(1).array() - V_uv.col(1).minCoeff();
     V_uv.col(1) = V_uv.col(1).array() / V_uv.col(1).maxCoeff();
     V_uv = V_uv.array() * 10;
-    dirty |= DIRTY_TEXTURE;
+    dirty |= MeshGL::DIRTY_TEXTURE;
   }
 
   unsigned size = 128;
@@ -438,5 +438,241 @@ IGL_INLINE void igl::opengl::ViewerData::grid_texture()
   texture_G = texture_R;
   texture_B = texture_R;
   texture_A = Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>::Constant(texture_R.rows(),texture_R.cols(),255);
-  dirty |= DIRTY_TEXTURE;
+  dirty |= MeshGL::DIRTY_TEXTURE;
+}
+
+IGL_INLINE void igl::opengl::ViewerData::updateGL(
+  const igl::opengl::ViewerData& data, 
+  const bool invert_normals,
+  igl::opengl::MeshGL& meshgl
+  )
+{
+  if (!meshgl.is_initialized)
+  {
+    std::cerr << "Inizializing meshgl" << std::endl;
+    meshgl.init();
+  }
+
+  bool per_corner_uv = (data.F_uv.rows() == data.F.rows());
+  bool per_corner_normals = (data.F_normals.rows() == 3 * data.F.rows());
+
+  meshgl.dirty |= data.dirty;
+
+  // Input:
+  //   X  #F by dim quantity
+  // Output:
+  //   X_vbo  #F*3 by dim scattering per corner
+  const auto per_face = [&data](
+      const Eigen::MatrixXd & X,
+      MeshGL::RowMatrixXf & X_vbo)
+  {
+    X_vbo.resize(data.F.rows()*3,3);
+    for (unsigned i=0; i<data.F.rows();++i)
+      for (unsigned j=0;j<3;++j)
+        X_vbo.row(i*3+j) = X.row(i).cast<float>().head(3);
+  };
+
+  // Input:
+  //   X  #V by dim quantity
+  // Output:
+  //   X_vbo  #F*3 by dim scattering per corner
+  const auto per_corner = [&data](
+      const Eigen::MatrixXd & X,
+      MeshGL::RowMatrixXf & X_vbo)
+  {
+    X_vbo.resize(data.F.rows()*3,3);
+    for (unsigned i=0; i<data.F.rows();++i)
+      for (unsigned j=0;j<3;++j)
+        X_vbo.row(i*3+j) = X.row(data.F(i,j)).cast<float>();
+  };
+
+  if (!data.face_based)
+  {
+    if (!(per_corner_uv || per_corner_normals))
+    {
+      // Vertex positions
+      if (meshgl.dirty & MeshGL::DIRTY_POSITION)
+        meshgl.V_vbo = data.V.cast<float>();
+
+      // Vertex normals
+      if (meshgl.dirty & MeshGL::DIRTY_NORMAL)
+      {
+        meshgl.V_normals_vbo = data.V_normals.cast<float>();
+        if (invert_normals)
+          meshgl.V_normals_vbo = -meshgl.V_normals_vbo;
+      }
+
+      // Per-vertex material settings
+      if (meshgl.dirty & MeshGL::DIRTY_AMBIENT)
+        meshgl.V_ambient_vbo = data.V_material_ambient.cast<float>();
+      if (meshgl.dirty & MeshGL::DIRTY_DIFFUSE)
+        meshgl.V_diffuse_vbo = data.V_material_diffuse.cast<float>();
+      if (meshgl.dirty & MeshGL::DIRTY_SPECULAR)
+        meshgl.V_specular_vbo = data.V_material_specular.cast<float>();
+
+      // Face indices
+      if (meshgl.dirty & MeshGL::DIRTY_FACE)
+        meshgl.F_vbo = data.F.cast<unsigned>();
+
+      // Texture coordinates
+      if (meshgl.dirty & MeshGL::DIRTY_UV)
+        meshgl.V_uv_vbo = data.V_uv.cast<float>();
+    }
+    else
+    {
+
+      // Per vertex properties with per corner UVs
+      if (meshgl.dirty & MeshGL::DIRTY_POSITION)
+      {
+        per_corner(data.V,meshgl.V_vbo);
+      }
+
+      if (meshgl.dirty & MeshGL::DIRTY_AMBIENT)
+      {
+        meshgl.V_ambient_vbo.resize(4,data.F.rows()*3);
+        for (unsigned i=0; i<data.F.rows();++i)
+          for (unsigned j=0;j<3;++j)
+            meshgl.V_ambient_vbo.col (i*3+j) = data.V_material_ambient.row(data.F(i,j)).transpose().cast<float>();
+      }
+      if (meshgl.dirty & MeshGL::DIRTY_DIFFUSE)
+      {
+        meshgl.V_diffuse_vbo.resize(4,data.F.rows()*3);
+        for (unsigned i=0; i<data.F.rows();++i)
+          for (unsigned j=0;j<3;++j)
+            meshgl.V_diffuse_vbo.col (i*3+j) = data.V_material_diffuse.row(data.F(i,j)).transpose().cast<float>();
+      }
+      if (meshgl.dirty & MeshGL::DIRTY_SPECULAR)
+      {
+        meshgl.V_specular_vbo.resize(4,data.F.rows()*3);
+        for (unsigned i=0; i<data.F.rows();++i)
+          for (unsigned j=0;j<3;++j)
+            meshgl.V_specular_vbo.col(i*3+j) = data.V_material_specular.row(data.F(i,j)).transpose().cast<float>();
+      }
+
+      if (meshgl.dirty & MeshGL::DIRTY_NORMAL)
+      {
+        meshgl.V_normals_vbo.resize(3,data.F.rows()*3);
+        for (unsigned i=0; i<data.F.rows();++i)
+          for (unsigned j=0;j<3;++j)
+          
+            meshgl.V_normals_vbo.col (i*3+j) = 
+                         per_corner_normals ?
+               data.F_normals.row(i*3+j).transpose().cast<float>() :
+               data.V_normals.row(data.F(i,j)).transpose().cast<float>();
+
+
+        if (invert_normals)
+          meshgl.V_normals_vbo = -meshgl.V_normals_vbo;
+      }
+
+      if (meshgl.dirty & MeshGL::DIRTY_FACE)
+      {
+        meshgl.F_vbo.resize(data.F.rows(),3);
+        for (unsigned i=0; i<data.F.rows();++i)
+          meshgl.F_vbo.row(i) << i*3+0, i*3+1, i*3+2;
+      }
+
+      if (meshgl.dirty & MeshGL::DIRTY_UV)
+      {
+        meshgl.V_uv_vbo.resize(data.F.rows()*3,2);
+        for (unsigned i=0; i<data.F.rows();++i)
+          for (unsigned j=0;j<3;++j)
+            meshgl.V_uv_vbo.row(i*3+j) = 
+              data.V_uv.row(per_corner_uv ? 
+                data.F_uv(i,j) : data.F(i,j)).cast<float>();
+      }
+    }
+  }
+  else
+  {
+    if (meshgl.dirty & MeshGL::DIRTY_POSITION)
+    {
+      per_corner(data.V,meshgl.V_vbo);
+    }
+
+    if (meshgl.dirty & MeshGL::DIRTY_AMBIENT)
+    {
+      per_face(data.F_material_ambient,meshgl.V_ambient_vbo);
+    }
+    if (meshgl.dirty & MeshGL::DIRTY_DIFFUSE)
+    {
+      per_face(data.F_material_diffuse,meshgl.V_diffuse_vbo);
+    }
+    if (meshgl.dirty & MeshGL::DIRTY_SPECULAR)
+    {
+      per_face(data.F_material_specular,meshgl.V_specular_vbo);
+    }
+
+    if (meshgl.dirty & MeshGL::DIRTY_NORMAL)
+    {
+      meshgl.V_normals_vbo.resize(data.F.rows()*3,3);
+      for (unsigned i=0; i<data.F.rows();++i)
+        for (unsigned j=0;j<3;++j)
+          meshgl.V_normals_vbo.row(i*3+j) =
+             per_corner_normals ?
+               data.F_normals.row(i*3+j).cast<float>() :
+               data.F_normals.row(i).cast<float>();
+
+      if (invert_normals)
+        meshgl.V_normals_vbo = -meshgl.V_normals_vbo;
+    }
+
+    if (meshgl.dirty & MeshGL::DIRTY_FACE)
+    {
+      meshgl.F_vbo.resize(data.F.rows(),3);
+      for (unsigned i=0; i<data.F.rows();++i)
+        meshgl.F_vbo.row(i) << i*3+0, i*3+1, i*3+2;
+    }
+
+    if (meshgl.dirty & MeshGL::DIRTY_UV)
+    {
+        meshgl.V_uv_vbo.resize(data.F.rows()*3,2);
+        for (unsigned i=0; i<data.F.rows();++i)
+          for (unsigned j=0;j<3;++j)
+            meshgl.V_uv_vbo.row(i*3+j) = data.V_uv.row(per_corner_uv ? data.F_uv(i,j) : data.F(i,j)).cast<float>();
+    }
+  }
+
+  if (meshgl.dirty & MeshGL::DIRTY_TEXTURE)
+  {
+    meshgl.tex_u = data.texture_R.rows();
+    meshgl.tex_v = data.texture_R.cols();
+    meshgl.tex.resize(data.texture_R.size()*4);
+    for (unsigned i=0;i<data.texture_R.size();++i)
+    {
+      meshgl.tex(i*4+0) = data.texture_R(i);
+      meshgl.tex(i*4+1) = data.texture_G(i);
+      meshgl.tex(i*4+2) = data.texture_B(i);
+      meshgl.tex(i*4+3) = data.texture_A(i);
+    }
+  }
+
+  if (meshgl.dirty & MeshGL::DIRTY_OVERLAY_LINES)
+  {
+    meshgl.lines_V_vbo.resize(data.lines.rows()*2,3);
+    meshgl.lines_V_colors_vbo.resize(data.lines.rows()*2,3);
+    meshgl.lines_F_vbo.resize(data.lines.rows()*2,1);
+    for (unsigned i=0; i<data.lines.rows();++i)
+    {
+      meshgl.lines_V_vbo.row(2*i+0) = data.lines.block<1, 3>(i, 0).cast<float>();
+      meshgl.lines_V_vbo.row(2*i+1) = data.lines.block<1, 3>(i, 3).cast<float>();
+      meshgl.lines_V_colors_vbo.row(2*i+0) = data.lines.block<1, 3>(i, 6).cast<float>();
+      meshgl.lines_V_colors_vbo.row(2*i+1) = data.lines.block<1, 3>(i, 6).cast<float>();
+      meshgl.lines_F_vbo(2*i+0) = 2*i+0;
+      meshgl.lines_F_vbo(2*i+1) = 2*i+1;
+    }
+  }
+
+  if (meshgl.dirty & MeshGL::DIRTY_OVERLAY_POINTS)
+  {
+    meshgl.points_V_vbo.resize(data.points.rows(),3);
+    meshgl.points_V_colors_vbo.resize(data.points.rows(),3);
+    meshgl.points_F_vbo.resize(data.points.rows(),1);
+    for (unsigned i=0; i<data.points.rows();++i)
+    {
+      meshgl.points_V_vbo.row(i) = data.points.block<1, 3>(i, 0).cast<float>();
+      meshgl.points_V_colors_vbo.row(i) = data.points.block<1, 3>(i, 3).cast<float>();
+      meshgl.points_F_vbo(i) = i;
+    }
+  }
 }

+ 12 - 19
include/igl/opengl/ViewerData.h

@@ -11,7 +11,8 @@
 #include <cstdint>
 #include <vector>
 #include <Eigen/Core>
-#include <igl/igl_inline.h>
+#include "../igl_inline.h"
+#include "MeshGL.h"
 
 // Alec: This is a mesh class containing a variety of data types (normals,
 // overlays, material colors, etc.)
@@ -29,26 +30,9 @@ class ViewerData
 public:
   ViewerData();
 
-  enum DirtyFlags
-  {
-    DIRTY_NONE           = 0x0000,
-    DIRTY_POSITION       = 0x0001,
-    DIRTY_UV             = 0x0002,
-    DIRTY_NORMAL         = 0x0004,
-    DIRTY_AMBIENT        = 0x0008,
-    DIRTY_DIFFUSE        = 0x0010,
-    DIRTY_SPECULAR       = 0x0020,
-    DIRTY_TEXTURE        = 0x0040,
-    DIRTY_FACE           = 0x0080,
-    DIRTY_MESH           = 0x00FF,
-    DIRTY_OVERLAY_LINES  = 0x0100,
-    DIRTY_OVERLAY_POINTS = 0x0200,
-    DIRTY_ALL            = 0x03FF
-  };
-
   // Empty all fields
   IGL_INLINE void clear();
-
+  
   // Change the visualization mode, invalidating the cache if necessary
   IGL_INLINE void set_face_based(bool newvalue);
 
@@ -204,6 +188,15 @@ public:
   Eigen::Vector4f line_color;
   // Shape material
   float shininess;
+
+  // OpenGL representation of the mesh
+  igl::opengl::MeshGL meshgl;
+
+  // Update contents from a 'Data' instance
+  IGL_INLINE void updateGL(
+    const igl::opengl::ViewerData& data, 
+    const bool invert_normals,
+    igl::opengl::MeshGL& meshgl);
 };
 
 }

+ 6 - 22
include/igl/opengl/glfw/Viewer.cpp

@@ -326,9 +326,9 @@ namespace glfw
 
   IGL_INLINE void Viewer::launch_shut()
   {
-    for(auto & opengl : opengl_state_list)
+    for(auto & data : data_list)
     {
-      opengl.free();
+      data.meshgl.free();
     }
     core.shut();
     shutdown_plugins();
@@ -391,7 +391,7 @@ namespace glfw
 
     ngui->addVariable<bool>("Invert normals",[&](bool checked)
     {
-      this->data().dirty |= ViewerData::DIRTY_NORMAL;
+      this->data().dirty |= MeshGL::DIRTY_NORMAL;
       this->data().invert_normals = checked;
     },[&]()
     {
@@ -444,7 +444,6 @@ namespace glfw
 
   IGL_INLINE Viewer::Viewer():
     data_list(1),
-    opengl_state_list(1),
     selected_data_index(0)
   {
     window = nullptr;
@@ -670,7 +669,7 @@ namespace glfw
       case 'I':
       case 'i':
       {
-        data().dirty |= ViewerData::DIRTY_NORMAL;
+        data().dirty |= MeshGL::DIRTY_NORMAL;
         data().invert_normals = !data().invert_normals;
         return true;
       }
@@ -1016,11 +1015,9 @@ namespace glfw
         return;
       }
     }
-    assert(data_list.size() == opengl_state_list.size());
     for(int i = 0;i<data_list.size();i++)
     {
-      opengl_state_list[i].init();
-      core.draw(data_list[i],opengl_state_list[i]);
+      core.draw(data_list[i]);
     }
     if (callback_post_draw)
     {
@@ -1096,43 +1093,30 @@ namespace glfw
 
   IGL_INLINE void Viewer::append_mesh()
   {
-    assert(data_list.size() == opengl_state_list.size());
     assert(data_list.size() >= 1);
 
     data_list.emplace_back();
-    opengl_state_list.emplace_back();
     selected_data_index = data_list.size()-1;
   }
   IGL_INLINE bool Viewer::erase_mesh(const size_t index)
   {
-    assert(data_list.size() == opengl_state_list.size());
     assert(data_list.size() >= 1);
     if(data_list.size() == 1)
     {
       // Cannot remove last mesh
       return false;
     }
+    data_list[index].meshgl.free();
     data_list.erase(data_list.begin()                 + index);
-    opengl_state_list.erase(opengl_state_list.begin() + index);
     if(selected_data_index >= index && selected_data_index>0)
     {
       selected_data_index--;
     }
     std::cout<<"data: "<<data_list.size()<<std::endl;
-    std::cout<<"opengl_state: "<<opengl_state_list.size()<<std::endl;
     std::cout<<"selected_data_index: "<<selected_data_index<<std::endl;
     return true;
   }
 
-  IGL_INLINE MeshGL& Viewer::selected_opengl_state()
-  {
-    assert(!opengl_state_list.empty() && "opengl_state_list should never be empty");
-    assert(opengl_state_list.size() == data_list.size());
-    assert(
-      (selected_data_index >= 0 && selected_data_index < opengl_state_list.size()) && 
-      "selected_data_index should be in bounds");
-    return opengl_state_list[selected_data_index];
-  }
 } // end namespace
 } // end namespace
 }

+ 0 - 4
include/igl/opengl/glfw/Viewer.h

@@ -84,8 +84,6 @@ namespace glfw
     IGL_INLINE void open_dialog_load_mesh();
     IGL_INLINE void open_dialog_save_mesh();
     IGL_INLINE ViewerData& data();
-    //IGL_INLINE const ViewerData& const_data() const;
-    IGL_INLINE MeshGL& selected_opengl_state();
     // Append a new "slot" for a mesh (i.e., create empty entires at the end of
     // the data_list and opengl_state_list.
     //
@@ -117,8 +115,6 @@ namespace glfw
     // old "data" variable.
     // Stores all the data that should be visualized
     std::vector<ViewerData> data_list;
-    // Stores the vbos indices and opengl related settings
-    std::vector<MeshGL> opengl_state_list;
   public:
     size_t selected_data_index;
     GLFWwindow* window;

+ 0 - 518
shared/cmake/CMakeLists.txt

@@ -1,518 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12)
-project(libigl)
-
-message(DEPRECATION "shared/cmake/CMakeLists.txt is deprecated. Use libigl.cmake instead.")
-
-### Available options ###
-option(LIBIGL_USE_STATIC_LIBRARY    "Use libigl as static library" OFF)
-option(LIBIGL_WITH_ANTTWEAKBAR      "Use AntTweakBar"    OFF)
-option(LIBIGL_WITH_CGAL             "Use CGAL"           OFF)
-option(LIBIGL_WITH_COMISO           "Use CoMiso"         OFF)
-option(LIBIGL_WITH_CORK             "Use Cork"           OFF)
-option(LIBIGL_WITH_EMBREE           "Use Embree"         OFF)
-option(LIBIGL_WITH_LIM              "Use LIM"            OFF)
-option(LIBIGL_WITH_MATLAB           "Use Matlab"         OFF)
-option(LIBIGL_WITH_MOSEK            "Use MOSEK"          OFF)
-option(LIBIGL_WITH_NANOGUI          "Use Nanogui menu"   OFF)
-option(LIBIGL_WITH_OPENGL           "Use OpenGL"         OFF)
-option(LIBIGL_WITH_OPENGL_GLFW      "Use GLFW"           OFF)
-option(LIBIGL_WITH_PNG              "Use PNG"            OFF)
-option(LIBIGL_WITH_TETGEN           "Use Tetgen"         OFF)
-option(LIBIGL_WITH_TRIANGLE         "Use Triangle"       OFF)
-option(LIBIGL_WITH_XML              "Use XML"            OFF)
-option(LIBIGL_WITH_PYTHON           "Use Python"         OFF)
-
-### Compilation configuration ###
-if(MSVC)
-  ### Enable parallel compilation for Visual Studio
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /bigobj")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /w") # disable all warnings (not ideal but...)
-else()
-  #### Libigl requires a modern C++ compiler that supports c++11
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") # disable all warnings (not ideal but...)
-endif()
-set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
-
-### OpenMP ### (OpenMP is disable for now)
-#find_package(OpenMP)
-#if(OPENMP_FOUND AND NOT WIN32)
-#  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
-#  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
-#  list(APPEND LIBIGL_DEFINITIONS "${OpenMP_CXX_FLAGS}")
-#endif()
-
-
-### Compiling libraries based on chosen options ###
-set(LIBIGL_INCLUDE_DIRS "")
-set(LIBIGL_LIBRARIES "")
-set(LIBIGL_EXTRA_LIBRARIES "")
-set(LIBIGL_DEFINITIONS "")
-
-if(LIBIGL_USE_STATIC_LIBRARY)
-  list(APPEND LIBIGL_DEFINITIONS "-DIGL_STATIC_LIBRARY")
-endif()
-
-### macro definition ###
-set(LIBIGL_ROOT "${PROJECT_SOURCE_DIR}/../..")
-set(LIBIGL_SOURCE_DIR "${LIBIGL_ROOT}/include")
-set(LIBIGL_EXTERNAL "${LIBIGL_ROOT}/external")
-
-### Multiple dependencies are buried in Nanogui
-set(NANOGUI_DIR "${LIBIGL_EXTERNAL}/nanogui")
-
-### Eigen ###
-if(NOT EIGEN_INCLUDE_DIR)
-  set(EIGEN_INCLUDE_DIR "${NANOGUI_DIR}/ext/eigen")
-endif()
-list(APPEND LIBIGL_INCLUDE_DIRS "${EIGEN_INCLUDE_DIR}")
-
-macro(CompileIGL_Module module_dir )
-  string(REPLACE "/" "_" module_name "${module_dir}")
-  file(GLOB SOURCES_IGL_${module_name}
-  "${LIBIGL_SOURCE_DIR}/igl/${module_dir}/*.cpp"
-  "${LIBIGL_SOURCE_DIR}/igl/copyleft/${module_dir}/*.cpp"
-  )
-  set(module_lib_name igl_${module_name})
-  add_library(${module_lib_name} STATIC ${SOURCES_IGL_${module_name}})
-  target_include_directories(${module_lib_name} PRIVATE ${EIGEN_INCLUDE_DIR})
-  target_include_directories(${module_lib_name} PRIVATE ${LIBIGL_SOURCE_DIR})
-  target_compile_definitions(${module_lib_name} PRIVATE -DIGL_STATIC_LIBRARY)
-  list(APPEND LIBIGL_LIBRARIES "${module_lib_name}")
-endmacro()
-
-### IGL Common ###
-list(APPEND LIBIGL_INCLUDE_DIRS "${LIBIGL_SOURCE_DIR}")
-if(LIBIGL_USE_STATIC_LIBRARY)
-  file(GLOB SOURCES_IGL
-  "${LIBIGL_SOURCE_DIR}/igl/*.cpp"
-  "${LIBIGL_SOURCE_DIR}/igl/copyleft/*.cpp")
-  add_library(igl STATIC ${SOURCES_IGL})
-  target_include_directories(igl PRIVATE ${EIGEN_INCLUDE_DIR})
-  target_include_directories(igl PRIVATE ${LIBIGL_SOURCE_DIR})
-  target_compile_definitions(igl PRIVATE -DIGL_STATIC_LIBRARY)
-  list(APPEND LIBIGL_LIBRARIES "igl")
-endif()
-
-
-### Compile the AntTweakBar part ###
-if(LIBIGL_WITH_ANTTWEAKBAR)
-  set(ANTTWEAKBAR_DIR "${LIBIGL_EXTERNAL}/AntTweakBar")
-  set(ANTTWEAKBAR_INCLUDE_DIR "${ANTTWEAKBAR_DIR}/include")
-  set(ANTTWEAKBAR_C_SRC_FILES
-    "${ANTTWEAKBAR_DIR}/src/TwEventGLFW.c"
-    "${ANTTWEAKBAR_DIR}/src/TwEventGLUT.c"
-    "${ANTTWEAKBAR_DIR}/src/TwEventSDL.c"
-    "${ANTTWEAKBAR_DIR}/src/TwEventSDL12.c"
-    "${ANTTWEAKBAR_DIR}/src/TwEventSDL13.c"
-    )
-  set(ANTTWEAKBAR_CPP_SRC_FILES
-    "${ANTTWEAKBAR_DIR}/src/LoadOGL.cpp"
-    "${ANTTWEAKBAR_DIR}/src/LoadOGLCore.cpp"
-    "${ANTTWEAKBAR_DIR}/src/TwBar.cpp"
-    "${ANTTWEAKBAR_DIR}/src/TwColors.cpp"
-    "${ANTTWEAKBAR_DIR}/src/TwEventSFML.cpp"
-    "${ANTTWEAKBAR_DIR}/src/TwFonts.cpp"
-    "${ANTTWEAKBAR_DIR}/src/TwMgr.cpp"
-    "${ANTTWEAKBAR_DIR}/src/TwOpenGL.cpp"
-    "${ANTTWEAKBAR_DIR}/src/TwOpenGLCore.cpp"
-    "${ANTTWEAKBAR_DIR}/src/TwPrecomp.cpp"
-    )
-    # These are probably needed for windows/Linux, should append if
-    # windows/Linux
-    #"${ANTTWEAKBAR_DIR}/src/TwEventWin.c"
-    #"${ANTTWEAKBAR_DIR}/src/TwEventX11.c"
-    #"${ANTTWEAKBAR_DIR}/src/TwDirect3D10.cpp"
-    #"${ANTTWEAKBAR_DIR}/src/TwDirect3D11.cpp"
-    #"${ANTTWEAKBAR_DIR}/src/TwDirect3D9.cpp"
-  list(
-    APPEND
-    ANTTWEAKBAR_SRC_FILES
-    "${ANTTWEAKBAR_C_SRC_FILES}"
-    "${ANTTWEAKBAR_CPP_SRC_FILES}")
-  add_library(AntTweakBar STATIC "${ANTTWEAKBAR_SRC_FILES}")
-  target_include_directories(AntTweakBar PUBLIC "${ANTTWEAKBAR_INCLUDE_DIR}")
-  if(APPLE)
-    set_target_properties(
-      AntTweakBar
-      PROPERTIES
-      COMPILE_FLAGS
-      "-fPIC -fno-strict-aliasing -x objective-c++")
-    target_compile_definitions(
-      AntTweakBar PUBLIC _MACOSX __PLACEMENT_NEW_INLINE)
-  endif()
-  list(APPEND LIBIGL_INCLUDE_DIRS "${ANTTWEAKBAR_INCLUDE_DIR}")
-  set(LIBIGL_ANTTWEAKBAR_EXTRA_LIBRARIES "AntTweakBar")
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_ANTTWEAKBAR_EXTRA_LIBRARIES})
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("anttweakbar" "")
-    target_include_directories(igl_anttweakbar PRIVATE ${ANTTWEAKBAR_INCLUDE_DIR})
-  endif()
-endif()
-
-### Compile the cgal parts ###
-if(LIBIGL_WITH_CGAL) # to be cleaned
-  # Core is needed for
-  # `Exact_predicates_exact_constructions_kernel_with_sqrt`
-  find_package(CGAL REQUIRED COMPONENTS Core)
-  # set(Boost_USE_MULTITHREADED      ON)
-  # set(Boost_USE_STATIC_LIBS      ON)
-  #
-  # find_package(BOOST REQUIRED)
-  set(CGAL_DONT_OVERRIDE_CMAKE_FLAGS TRUE CACHE BOOL "CGAL's CMAKE Setup is super annoying ")
-  include(${CGAL_USE_FILE})
-  list(APPEND LIBIGL_INCLUDE_DIRS ${CGAL_3RD_PARTY_INCLUDE_DIRS})
-  list(APPEND LIBIGL_INCLUDE_DIRS ${CGAL_INCLUDE_DIRS})
-  list(APPEND LIBIGL_CGAL_EXTRA_LIBRARIES ${CGAL_3RD_PARTY_LIBRARIES})
-  list(APPEND LIBIGL_CGAL_EXTRA_LIBRARIES ${CGAL_LIBRARIES})
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_CGAL_EXTRA_LIBRARIES})
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("cgal")
-    target_include_directories(igl_cgal PRIVATE
-      ${CGAL_3RD_PARTY_INCLUDE_DIRS}
-      ${CGAL_INCLUDE_DIRS})
-  endif()
-endif()
-
-#Compile CoMISo
-# NOTE: this cmakefile works only with the
-# comiso available here: https://github.com/libigl/CoMISo
-if(LIBIGL_WITH_COMISO)
-  set(COMISO_DIR "${LIBIGL_EXTERNAL}/CoMISo")
-  set(COMISO_INCLUDE_DIRS
-    "${COMISO_DIR}/ext/gmm-4.2/include"
-    "${COMISO_DIR}/../")
-  list(APPEND LIBIGL_INCLUDE_DIRS ${COMISO_INCLUDE_DIRS})
-  #add_definitions(-DINCLUDE_TEMPLATES) (what need this?)
-  list(APPEND LIBIGL_DEFINITIONS "-DINCLUDE_TEMPLATES")
-  if(APPLE)
-    find_library(accelerate_library Accelerate)
-    list(APPEND LIBIGL_COMISO_EXTRA_LIBRARIES "CoMISo" ${accelerate_library})
-  elseif(UNIX)
-    find_package(BLAS REQUIRED)
-    list(APPEND LIBIGL_COMISO_EXTRA_LIBRARIES "CoMISo" ${BLAS_LIBRARIES})
-  endif(APPLE)
-  if(MSVC)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_SCL_SECURE_NO_DEPRECATE")
-    #link_directories("${COMISO_ROOT}/CoMISo/ext/OpenBLAS-v0.2.14-Win64-int64/lib/")
-    list(APPEND LIBIGL_COMISO_EXTRA_LIBRARIES "CoMISo" "${COMISO_DIR}/ext/OpenBLAS-v0.2.14-Win64-int64/lib/libopenblas.dll.a.lib")
-  endif()
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_COMISO_EXTRA_LIBRARIES})
-  add_subdirectory("${COMISO_DIR}" "CoMISo")
-  if(MSVC)
-    # Copy the dll
-    add_custom_target(Copy-CoMISo-DLL ALL       # Adds a post-build event to MyTest
-    COMMAND ${CMAKE_COMMAND} -E copy_if_different
-        "${COMISO_DIR}/ext/OpenBLAS-v0.2.14-Win64-int64/bin/libopenblas.dll"
-        "${CMAKE_CURRENT_BINARY_DIR}/../libopenblas.dll"
-    COMMAND ${CMAKE_COMMAND} -E copy_if_different
-        "${COMISO_DIR}/ext/OpenBLAS-v0.2.14-Win64-int64/bin/libgcc_s_seh-1.dll"
-        "${CMAKE_CURRENT_BINARY_DIR}/../libgcc_s_seh-1.dll"
-    COMMAND ${CMAKE_COMMAND} -E copy_if_different
-        "${COMISO_DIR}/ext/OpenBLAS-v0.2.14-Win64-int64/bin/libgfortran-3.dll"
-        "${CMAKE_CURRENT_BINARY_DIR}/../libgfortran-3.dll"
-    COMMAND ${CMAKE_COMMAND} -E copy_if_different
-        "${COMISO_DIR}/ext/OpenBLAS-v0.2.14-Win64-int64/bin/libquadmath-0.dll"
-        "${CMAKE_CURRENT_BINARY_DIR}/../libquadmath-0.dll")
-  endif()
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("comiso")
-    target_include_directories(igl_comiso PRIVATE ${COMISO_INCLUDE_DIRS})
-    target_compile_definitions(igl_comiso PRIVATE -DINCLUDE_TEMPLATES)
-  endif()
-endif()
-
-### Compile the cork parts ###
-if(LIBIGL_WITH_CORK)
-  set(CORK_DIR "${LIBIGL_EXTERNAL}/cork")
-  set(CORK_INCLUDE_DIR "${CORK_DIR}/src")
-  # call this "lib-cork" instead of "cork", otherwise cmake gets confused about
-  # "cork" executable
-  add_subdirectory("${CORK_DIR}" "lib-cork")
-  list(APPEND LIBIGL_INCLUDE_DIRS "${CORK_INCLUDE_DIR}")
-  list(APPEND LIBIGL_CORK_EXTRA_LIBRARIES "cork")
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_CORK_EXTRA_LIBRARIES})
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("cork")
-    target_include_directories(igl_cork PRIVATE ${CORK_INCLUDE_DIR})
-  endif()
-endif()
-
-### Compile the embree part ###
-if(LIBIGL_WITH_EMBREE)
-  set(EMBREE_DIR "${LIBIGL_EXTERNAL}/embree")
-
-  set(EMBREE_ISPC_SUPPORT OFF CACHE BOOL " " FORCE)
-  set(EMBREE_TASKING_SYSTEM "INTERNAL" CACHE BOOL " " FORCE)
-  set(EMBREE_TUTORIALS OFF CACHE BOOL " " FORCE)
-  set(EMBREE_MAX_ISA NONE CACHE STRINGS " " FORCE)
-
-  # set(ENABLE_INSTALLER OFF CACHE BOOL " " FORCE)
-  if(MSVC)
-    # set(EMBREE_STATIC_RUNTIME OFF CACHE BOOL " " FORCE)
-    set(EMBREE_STATIC_LIB OFF CACHE BOOL " " FORCE)
-  else()
-    set(EMBREE_STATIC_LIB ON CACHE BOOL " " FORCE)
-  endif()
-
-  add_subdirectory("${EMBREE_DIR}" "embree")
-  list(APPEND LIBIGL_INCLUDE_DIRS "${EMBREE_DIR}/include")
-  list(APPEND LIBIGL_EMBREE_EXTRA_LIBRARIES "embree")
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_EMBREE_EXTRA_LIBRARIES})
-
-  if(NOT MSVC)
-		list(APPEND LIBIGL_DEFINITIONS "-DENABLE_STATIC_LIB")
-	endif()
-
-  if(MSVC)
-    add_custom_target(Copy-Embree-DLL ALL        # Adds a post-build event to MyTest
-        COMMAND ${CMAKE_COMMAND} -E copy_if_different  # which executes "cmake - E copy_if_different..."
-            "${CMAKE_BINARY_DIR}/libigl/embree/$<CONFIGURATION>/embree.dll"      # <--this is in-file
-          "${CMAKE_BINARY_DIR}/embree.dll")                 # <--this is out-file path	endif()
-  endif()
-
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("embree" "")
-    target_include_directories(igl_embree PRIVATE ${EMBREE_DIR}/include)
-	if(NOT MSVC)
-		target_compile_definitions(igl_embree PRIVATE -DENABLE_STATIC_LIB)
-	endif()
-  endif()
-endif()
-
-### Compile the lim part ###
-if(LIBIGL_WITH_LIM)
-  set(LIM_DIR "${LIBIGL_EXTERNAL}/lim")
-  add_subdirectory("${LIM_DIR}" "lim")
-  list(APPEND LIBIGL_INCLUDE_DIRS ${LIM_DIR})
-  ## it depends on ligigl, so placing it here solve linking problems
-  #list(APPEND LIBIGL_LIBRARIES "lim")
-  # ^--- Alec: I don't understand this comment. Does lim need to come before
-  # libigl libraries? Why can't lim be placed where it belongs in
-  # LIBIGL_EXTRA_LIBRARIES?
-  set(LIBIGL_LIM_EXTRA_LIBRARIES "lim")
-  list(APPEND LIBIGL_EXTRA_LIBRARIES "${LIBIGL_LIM_EXTRA_LIBRARIES}")
-
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("lim" "")
-    target_include_directories(igl_lim PRIVATE ${LIM_DIR})
-  endif()
-endif()
-
-### Compile the matlab part ###
-if(LIBIGL_WITH_MATLAB)
-  find_package(Matlab REQUIRED)
-  list(APPEND LIBIGL_INCLUDE_DIRS ${Matlab_INCLUDE_DIRS})
-  list(APPEND LIBIGL_MATLAB_EXTRA_LIBRARIES 
-    ${Matlab_MEX_LIBRARY}
-    ${Matlab_MX_LIBRARY}
-    ${Matlab_MAT_LIBRARY}
-    ${Matlab_ENG_LIBRARY}
-    )
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_MATLAB_EXTRA_LIBRARIES})
-
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("matlab" "")
-    target_include_directories(igl_matlab PRIVATE ${Matlab_INCLUDE_DIRS})
-  endif()
-endif()
-
-### Compile the mosek part ###
-if(LIBIGL_WITH_MOSEK)
-  find_package(MOSEK REQUIRED)
-  list(APPEND LIBIGL_INCLUDE_DIRS ${MOSEK_INCLUDE_DIR})
-  list(APPEND LIBIGL_MOSEK_EXTRA_LIBRARIES ${MOSEK_LIBRARIES})
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_MOSEK_EXTRA_LIBRARIES})
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("mosek" "")
-    target_include_directories(igl_mosek PRIVATE ${MOSEK_INCLUDE_DIR})
-  endif()
-else()
-  list(APPEND LIBIGL_DEFINITIONS "-DIGL_NO_MOSEK")
-endif()
-
-### Compile the opengl parts ###
-set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL " " FORCE)
-set(GLFW_BUILD_TESTS OFF CACHE BOOL " " FORCE)
-set(GLFW_BUILD_DOCS OFF CACHE BOOL " " FORCE)
-set(GLFW_BUILD_INSTALL OFF CACHE BOOL " " FORCE)
-if(LIBIGL_WITH_OPENGL)
-  find_package(OpenGL REQUIRED)
-
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("opengl" "")
-    CompileIGL_Module("opengl2" "")
-    if(NOT APPLE)
-      target_include_directories(igl_opengl PRIVATE "${NANOGUI_DIR}/ext/glew/include")
-      target_include_directories(igl_opengl2 PRIVATE "${NANOGUI_DIR}/ext/glew/include")
-    endif()
-  endif()
-  set(LIBIGL_OPENGL_EXTRA_LIBRARIES ${OPENGL_gl_LIBRARY})
-
-  ### GLEW for linux and windows
-  if((UNIX AND NOT APPLE) OR WIN32) ### Compile glew if needed
-    set(GLEW_INSTALL OFF CACHE BOOL " " FORCE)
-    add_subdirectory("${NANOGUI_DIR}/ext/glew" "glew")
-  endif()
-  if(NOT APPLE)
-    list(APPEND LIBIGL_INCLUDE_DIRS "${NANOGUI_DIR}/ext/glew/include")
-    list(APPEND LIBIGL_OPENGL_EXTRA_LIBRARIES "glew")
-  endif()
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_OPENGL_EXTRA_LIBRARIES})
-
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_OPENGL_EXTRA_LIBRARIES})
-
-  if(LIBIGL_WITH_OPENGL_GLFW)
-    set(GLFW_INCLUDE_DIRS "${NANOGUI_DIR}/ext/glfw/include")
-    if(NOT APPLE)
-      list(APPEND GLFW_INCLUDE_DIRS "${NANOGUI_DIR}/ext/glew/include")
-    endif()
-
-    # Note: if add_subdirectory("${NANOGUI_DIR}" "nanogui") runs below it will
-    # add GLFW as a side-effect; in this case, CMake will complain about
-    # duplicates if we add them here.
-    set(LIBIGL_OPENGL_GLFW_EXTRA_LIBRARIES "glfw" ${GLFW_LIBRARIES})
-
-    ### Compile the viewer with NANOGUI support ###
-    if(LIBIGL_WITH_NANOGUI)
-      list(APPEND LIBIGL_DEFINITIONS "-DIGL_VIEWER_WITH_NANOGUI")
-      if (LIBIGL_WITH_PYTHON)
-        set(NANOGUI_BUILD_PYTHON ON CACHE BOOL " " FORCE)
-      else()
-        set(NANOGUI_BUILD_PYTHON OFF CACHE BOOL " " FORCE)
-      endif()
-      set(NANOGUI_BUILD_EXAMPLE OFF CACHE BOOL " " FORCE)
-      set(NANOGUI_BUILD_SHARED  OFF CACHE BOOL " " FORCE)
-      add_subdirectory("${NANOGUI_DIR}" "nanogui")
-      set(NANOGUI_INCLUDE_DIRS
-        "${NANOGUI_DIR}/include"
-        "${NANOGUI_DIR}/ext/nanovg/src")
-      list(APPEND GLFW_INCLUDE_DIRS "${NANOGUI_INCLUDE_DIRS}")
-      list(APPEND LIBIGL_OPENGL_GLFW_EXTRA_LIBRARIES "nanogui" ${NANOGUI_EXTRA_LIBS})
-    else()
-      add_subdirectory("${NANOGUI_DIR}/ext/glfw" "glfw")
-    endif()
-    list(APPEND VIEWER_INCLUDE_DIRS ${GLFW_INCLUDE_DIRS})
-    list(APPEND LIBIGL_INCLUDE_DIRS ${VIEWER_INCLUDE_DIRS})
-    list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_VIEWER_EXTRA_LIBRARIES})
-
-    if(LIBIGL_USE_STATIC_LIBRARY)
-      CompileIGL_Module("opengl/glfw" "")
-      if(LIBIGL_WITH_NANOGUI)
-        target_compile_definitions(igl_opengl_glfw PRIVATE -DIGL_VIEWER_WITH_NANOGUI)
-      endif()
-      target_include_directories(igl_opengl_glfw PRIVATE ${GLFW_INCLUDE_DIRS})
-      target_include_directories(igl_opengl_glfw PRIVATE ${OPENGL_INCLUDE_DIR})
-      if(NOT APPLE)
-        target_include_directories(igl_opengl PRIVATE "${NANOGUI_DIR}/ext/glew/include")
-      endif()
-    endif()
-    list(APPEND LIBIGL_INCLUDE_DIRS ${GLFW_INCLUDE_DIRS})
-    list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_OPENGL_GLFW_EXTRA_LIBRARIES})
-  endif()
-
-endif()
-
-### Compile the png parts ###
-if(LIBIGL_WITH_PNG)
-  if(LIBIGL_WITH_NANOGUI)
-    set(STBI_LOAD OFF CACHE BOOL " " FORCE)
-  endif()
-  set(STB_IMAGE_DIR "${LIBIGL_EXTERNAL}/stb_image")
-  add_subdirectory("${STB_IMAGE_DIR}" "stb_image")
-  list(APPEND LIBIGL_INCLUDE_DIRS ${STB_IMAGE_DIR})
-  list(APPEND LIBIGL_PNG_EXTRA_LIBRARIES "igl_stb_image")
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_PNG_EXTRA_LIBRARIES})
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("png" "")
-    target_link_libraries(igl_png PRIVATE igl_stb_image)
-    target_include_directories(igl_png PRIVATE ${STB_IMAGE_DIR})
-    if(NOT APPLE)
-      target_include_directories(igl_png PRIVATE "${NANOGUI_DIR}/ext/glew/include")
-    endif()
-  endif()
-endif()
-
-### Compile the tetgen part ###
-if(LIBIGL_WITH_TETGEN)
-  set(TETGEN_DIR "${LIBIGL_EXTERNAL}/tetgen")
-  add_subdirectory("${TETGEN_DIR}" "tetgen")
-  list(APPEND LIBIGL_INCLUDE_DIRS ${TETGEN_DIR})
-  list(APPEND LIBIGL_TETGEN_EXTRA_LIBRARIES "tetgen")
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_TETGEN_EXTRA_LIBRARIES})
-
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("tetgen")
-    target_include_directories(igl_tetgen PRIVATE ${TETGEN_DIR})
-  endif()
-endif()
-
-### Compile the triangle part ###
-if(LIBIGL_WITH_TRIANGLE)
-  set(TRIANGLE_DIR "${LIBIGL_EXTERNAL}/triangle")
-  add_subdirectory("${TRIANGLE_DIR}" "triangle")
-  list(APPEND LIBIGL_INCLUDE_DIRS ${TRIANGLE_DIR})
-  list(APPEND LIBIGL_TRIANGLE_EXTRA_LIBRARIES "triangle")
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_TRIANGLE_EXTRA_LIBRARIES})
-
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("triangle" "")
-    target_include_directories(igl_triangle PRIVATE ${TRIANGLE_DIR})
-  endif()
-endif()
-
-### Compile the xml part ###
-if(LIBIGL_WITH_XML)
-  set(TINYXML2_DIR "${LIBIGL_EXTERNAL}/tinyxml2")
-  add_library(tinyxml2 STATIC ${TINYXML2_DIR}/tinyxml2.cpp ${TINYXML2_DIR}/tinyxml2.h)
-  set_target_properties(tinyxml2 PROPERTIES
-          COMPILE_DEFINITIONS "TINYXML2_EXPORT"
-          VERSION "3.0.0"
-          SOVERSION "3")
-  list(APPEND LIBIGL_INCLUDE_DIRS ${TINYXML2_DIR})
-  list(APPEND LIBIGL_XML_EXTRA_LIBRARIES "tinyxml2")
-  list(APPEND LIBIGL_EXTRA_LIBRARIES ${LIBIGL_XML_EXTRA_LIBRARIES})
-  if(LIBIGL_USE_STATIC_LIBRARY)
-    CompileIGL_Module("xml" "")
-    target_include_directories(igl_xml PRIVATE ${TINYXML2_DIR})
-  endif()
-endif()
-
-# Function to print list nicely
-function(print_list title list)
-  message("-- ${title}:")
-  foreach(elt ${list})
-    message("\t ${elt}")
-  endforeach()
-endfunction()
-
-# Pass the list of compiled libraries to the parent if there is one
-if(NOT ${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
-  list(REVERSE LIBIGL_LIBRARIES)
-
-  set(LIBIGL_INCLUDE_DIRS ${LIBIGL_INCLUDE_DIRS} PARENT_SCOPE)
-  set(LIBIGL_LIBRARIES ${LIBIGL_LIBRARIES} PARENT_SCOPE)
-  set(LIBIGL_ANTTWEAKBAR_EXTRA_LIBRARIES ${LIBIGL_ANTTWEAKBAR_EXTRA_LIBRARIES} PARENT_SCOPE)
-  set(LIBIGL_CGAL_EXTRA_LIBRARIES        ${LIBIGL_CGAL_EXTRA_LIBRARIES}        PARENT_SCOPE)
-  set(LIBIGL_COMISO_EXTRA_LIBRARIES      ${LIBIGL_COMISO_EXTRA_LIBRARIES}      PARENT_SCOPE)
-  set(LIBIGL_CORK_EXTRA_LIBRARIES        ${LIBIGL_CORK_EXTRA_LIBRARIES}        PARENT_SCOPE)
-  set(LIBIGL_EMBREE_EXTRA_LIBRARIES      ${LIBIGL_EMBREE_EXTRA_LIBRARIES}      PARENT_SCOPE)
-  set(LIBIGL_LIM_EXTRA_LIBRARIES         ${LIBIGL_LIM_EXTRA_LIBRARIES}         PARENT_SCOPE)
-  set(LIBIGL_MATLAB_EXTRA_LIBRARIES      ${LIBIGL_MATLAB_EXTRA_LIBRARIES}      PARENT_SCOPE)
-  set(LIBIGL_MOSEK_EXTRA_LIBRARIES       ${LIBIGL_MOSEK_EXTRA_LIBRARIES}       PARENT_SCOPE)
-  set(LIBIGL_NANOGUI_EXTRA_LIBRARIES     ${LIBIGL_NANOGUI_EXTRA_LIBRARIES}     PARENT_SCOPE)
-  set(LIBIGL_OPENGL_EXTRA_LIBRARIES      ${LIBIGL_OPENGL_EXTRA_LIBRARIES}     PARENT_SCOPE)
-  set(LIBIGL_OPENGL_GLFW_EXTRA_LIBRARIES ${LIBIGL_OPENGL_GLFW_EXTRA_LIBRARIES} PARENT_SCOPE)
-  set(LIBIGL_PNG_EXTRA_LIBRARIES         ${LIBIGL_PNG_EXTRA_LIBRARIES}         PARENT_SCOPE)
-  set(LIBIGL_TETGEN_EXTRA_LIBRARIES      ${LIBIGL_TETGEN_EXTRA_LIBRARIES}      PARENT_SCOPE)
-  set(LIBIGL_TRIANGLE_EXTRA_LIBRARIES    ${LIBIGL_TRIANGLE_EXTRA_LIBRARIES}    PARENT_SCOPE)
-  set(LIBIGL_XML_EXTRA_LIBRARIES         ${LIBIGL_XML_EXTRA_LIBRARIES}         PARENT_SCOPE)
-  set(LIBIGL_EXTRA_LIBRARIES ${LIBIGL_EXTRA_LIBRARIES} PARENT_SCOPE)
-  set(LIBIGL_DEFINITIONS ${LIBIGL_DEFINITIONS} PARENT_SCOPE)
-
-  ### ligIGL information ###
-  print_list("libigl includes" "${LIBIGL_INCLUDE_DIRS}")
-  print_list("libigl libraries" "${LIBIGL_LIBRARIES}")
-  print_list("libigl extra libraries" "${LIBIGL_EXTRA_LIBRARIES}")
-  print_list("libigl definitions" "${LIBIGL_DEFINITIONS}")
-endif()

+ 2 - 0
shared/cmake/libigl.cmake

@@ -303,6 +303,8 @@ if(LIBIGL_WITH_OPENGL)
     target_include_directories(nanogui PUBLIC
       "${NANOGUI_DIR}/include"
       "${NANOGUI_DIR}/ext/nanovg/src")
+    target_compile_definitions(nanogui ${IGL_SCOPE} -DIGL_VIEWER_WITH_NANOGUI)
+    
   endif()
 
   # GLFW module

+ 1 - 1
tutorial/106_ViewerMenu/CMakeLists.txt

@@ -2,4 +2,4 @@ cmake_minimum_required(VERSION 2.8.12)
 project(106_ViewerMenu)
 
 add_executable(${PROJECT_NAME}_bin main.cpp)
-target_link_libraries(${PROJECT_NAME}_bin igl::core igl::opengl igl::opengl_glfw tutorials)
+target_link_libraries(${PROJECT_NAME}_bin igl::core igl::opengl igl::opengl_glfw nanogui tutorials)

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

@@ -1,13 +1,3 @@
-#ifndef IGL_VIEWER_WITH_NANOGUI
-#include <iostream>
-int main()
-{
-  std::cerr<<
-    "Error: recompile with LIBIGL_VIEWER_WITH_NANOGUI defined."<<std::endl;
-  return EXIT_FAILURE;
-}
-#else
-
 #include <igl/readOFF.h>
 #include <igl/opengl/glfw/Viewer.h>
 #include <nanogui/formhelper.h>
@@ -68,4 +58,3 @@ int main(int argc, char *argv[])
   viewer.data().set_mesh(V, F);
   viewer.launch();
 }
-#endif

+ 1 - 1
tutorial/607_ScreenCapture/main.cpp

@@ -18,7 +18,7 @@ bool key_down(igl::opengl::glfw::Viewer& viewer, unsigned char key, int modifier
 
     // Draw the scene in the buffers
     viewer.core.draw_buffer(
-      viewer.data(),viewer.selected_opengl_state(),false,R,G,B,A);
+      viewer.data(),false,R,G,B,A);
 
     // Save it to a PNG
     igl::png::writePNG(R,G,B,A,"out.png");

+ 3 - 1
tutorial/CMakeLists.txt

@@ -54,7 +54,9 @@ if(TUTORIALS_CHAPTER1)
   add_subdirectory("103_Events")
   add_subdirectory("104_Colors")
   add_subdirectory("105_Overlays")
-  add_subdirectory("106_ViewerMenu")
+  if(LIBIGL_WITH_NANOGUI)
+    add_subdirectory("106_ViewerMenu")
+  endif()
   add_subdirectory("107_MultipleMeshes")
 endif()