Преглед на файлове

Merge branch 'master' of https://github.com/libigl/libigl

Conflicts:
	include/igl/viewer/ViewerCore.cpp

Former-commit-id: e56bb5e6afc40bfad9c9ef8d75a3cbe59bdf27ec
schuellc преди 10 години
родител
ревизия
67a2d9e9ab

+ 3 - 12
examples/scene-rotation/example.cpp

@@ -32,7 +32,6 @@
 
 #ifdef __APPLE__
 #include <GLUT/glut.h>
-#include <Carbon/Carbon.h>
 #else
 #include <GL/glut.h>
 #endif
@@ -483,14 +482,6 @@ void init_relative()
 }
 
 
-KeyMap keyStates ;
-bool IS_KEYDOWN( uint16_t vKey )
-{
-  uint8_t index = vKey / 32 ;
-  uint8_t shift = vKey % 32 ;
-  return keyStates[index].bigEndianValue & (1 << shift) ;
-}
-
 
 void undo()
 {
@@ -519,9 +510,9 @@ void key(unsigned char key, int mouse_x, int mouse_y)
   using namespace std;
   using namespace igl;
   using namespace Eigen;
-  GetKeys(keyStates);
-  const bool command_down = IS_KEYDOWN(kVK_Command);
-  const bool shift_down = IS_KEYDOWN(kVK_Shift);
+  const int mod = glutGetModifiers();
+  const bool command_down = mod | GLUT_ACTIVE_COMMAND;
+  const bool shift_down = mod | GLUT_ACTIVE_SHIFT;
   switch(key)
   {
     // ESC

+ 3 - 12
examples/upright/example.cpp

@@ -34,8 +34,6 @@
 #include <GL/glut.h>
 #endif
 
-#include <Carbon/Carbon.h>
-
 #include <string>
 #include <vector>
 #include <stack>
@@ -347,13 +345,6 @@ bool save()
 }
 
 
-KeyMap keyStates ;
-bool IS_KEYDOWN( uint16_t vKey )
-{
-  uint8_t index = vKey / 32 ;
-  uint8_t shift = vKey % 32 ;
-  return keyStates[index].bigEndianValue & (1 << shift) ;
-}
 
 void undo()
 {
@@ -380,9 +371,9 @@ void redo()
 void key(unsigned char key, int mouse_x, int mouse_y)
 {
   using namespace std;
-  GetKeys(keyStates);
-  const bool command_down = IS_KEYDOWN(kVK_Command);
-  const bool shift_down = IS_KEYDOWN(kVK_Shift);
+  const int mod = glutGetModifiers();
+  const bool command_down = GLUT_ACTIVE_COMMAND & mod;
+  const bool shift_down = GLUT_ACTIVE_SHIFT & mod;
   switch(key)
   {
     // Ctrl-c and esc exit

+ 2 - 0
include/igl/all_edges.cpp

@@ -47,4 +47,6 @@ IGL_INLINE void igl::all_edges(
 // Explicit template specialization
 template void igl::all_edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::all_edges<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
+template void igl::all_edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
+template void igl::all_edges<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 2 - 1
include/igl/doublearea.cpp

@@ -73,12 +73,13 @@ IGL_INLINE void igl::doublearea(
   }
 }
 
+
 template <
   typename DerivedA,
   typename DerivedB,
   typename DerivedC,
   typename DerivedD>
-IGL_INLINE void doublearea(
+IGL_INLINE void igl::doublearea(
   const Eigen::PlainObjectBase<DerivedA> & A,
   const Eigen::PlainObjectBase<DerivedB> & B,
   const Eigen::PlainObjectBase<DerivedC> & C,

+ 21 - 0
include/igl/frustum.cpp

@@ -0,0 +1,21 @@
+#include "frustum.h"
+template < typename DerivedP>
+IGL_INLINE void igl::frustum(
+  const typename DerivedP::Scalar left,
+  const typename DerivedP::Scalar right,
+  const typename DerivedP::Scalar bottom,
+  const typename DerivedP::Scalar top,
+  const typename DerivedP::Scalar nearVal,
+  const typename DerivedP::Scalar farVal,
+  Eigen::PlainObjectBase<DerivedP> & P)
+{
+  P.setConstant(4,4,0.);
+  P(0,0) = (2.0 * nearVal) / (right - left);
+  P(1,1) = (2.0 * nearVal) / (top - bottom);
+  P(0,2) = (right + left) / (right - left);
+  P(1,2) = (top + bottom) / (top - bottom);
+  P(2,2) = -(farVal + nearVal) / (farVal - nearVal);
+  P(3,2) = -1.0;
+  P(2,3) = -(2.0 * farVal * nearVal) / (farVal - nearVal);
+}
+

+ 44 - 0
include/igl/frustum.h

@@ -0,0 +1,44 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_FRUSTUM_H
+#define IGL_FRUSTUM_H
+#include "igl_inline.h"
+
+#include <Eigen/Dense>
+
+namespace igl 
+{
+  // Implementation of the deprecated glFrustum function.
+  //
+  // Inputs:
+  //   left  coordinate of left vertical clipping plane
+  //   right  coordinate of right vertical clipping plane
+  //   bottom  coordinate of bottom vertical clipping plane
+  //   top  coordinate of top vertical clipping plane
+  //   nearVal  distance to near plane
+  //   farVal  distance to far plane
+  // Outputs:
+  //   P  4x4 perspective matrix
+  template < typename DerivedP>
+  IGL_INLINE void frustum(
+    const typename DerivedP::Scalar left,
+    const typename DerivedP::Scalar right,
+    const typename DerivedP::Scalar bottom,
+    const typename DerivedP::Scalar top,
+    const typename DerivedP::Scalar nearVal,
+    const typename DerivedP::Scalar farVal,
+    Eigen::PlainObjectBase<DerivedP> & P);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "frustum.cpp"
+#endif
+
+#endif
+
+

+ 2 - 1
include/igl/internal_angles.cpp

@@ -48,7 +48,7 @@ IGL_INLINE void igl::internal_angles(
   #  define IGL_OMP_MIN_VALUE 1000
   #endif
   #pragma omp parallel for if (m>IGL_OMP_MIN_VALUE)
-  for(long int f = 0;f<m;f++)
+  for(size_t f = 0;f<m;f++)
   {
     for(size_t d = 0;d<3;d++)
     {
@@ -64,4 +64,5 @@ IGL_INLINE void igl::internal_angles(
 // Explicit template specialization
 template void igl::internal_angles<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::internal_angles<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::internal_angles<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 2 - 0
include/igl/list_to_matrix.cpp

@@ -152,4 +152,6 @@ template bool igl::list_to_matrix<int, Eigen::PlainObjectBase<Eigen::Matrix<int,
 template bool igl::list_to_matrix<double, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(std::vector<double, std::allocator<double> > const&, Eigen::Matrix<double, 1, -1, 1, 1, -1>&);
 template bool igl::list_to_matrix<unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > >(std::vector<unsigned long, std::allocator<unsigned long> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template bool igl::list_to_matrix<float, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > >(std::vector<std::vector<float, std::allocator<float> >, std::allocator<std::vector<float, std::allocator<float> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
+template bool igl::list_to_matrix<double, Eigen::Matrix<double, -1, 2, 0, -1, 2> >(std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&, Eigen::Matrix<double, -1, 2, 0, -1, 2>&);
+template bool igl::list_to_matrix<double, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&, Eigen::Matrix<double, -1, 3, 0, -1, 3>&);
 #endif

+ 31 - 0
include/igl/look_at.cpp

@@ -0,0 +1,31 @@
+#include "look_at.h"
+
+template <
+  typename Derivedeye,
+  typename Derivedcenter,
+  typename Derivedup,
+  typename DerivedR>
+IGL_INLINE void igl::look_at(
+  const Eigen::PlainObjectBase<Derivedeye> & eye,
+  const Eigen::PlainObjectBase<Derivedcenter> & center,
+  const Eigen::PlainObjectBase<Derivedup> & up,
+  Eigen::PlainObjectBase<DerivedR> & R)
+{
+  typedef Eigen::Matrix<typename DerivedR::Scalar,3,1> Vector3S;
+  Vector3S f = (center - eye).normalized();
+  Vector3S s = f.cross(up).normalized();
+  Vector3S u = s.cross(f);
+  R = Eigen::Matrix<typename DerivedR::Scalar,4,4>::Identity();
+  R(0,0) = s(0);
+  R(0,1) = s(1);
+  R(0,2) = s(2);
+  R(1,0) = u(0);
+  R(1,1) = u(1);
+  R(1,2) = u(2);
+  R(2,0) =-f(0);
+  R(2,1) =-f(1);
+  R(2,2) =-f(2);
+  R(0,3) =-s.transpose() * eye;
+  R(1,3) =-u.transpose() * eye;
+  R(2,3) = f.transpose() * eye;
+}

+ 42 - 0
include/igl/look_at.h

@@ -0,0 +1,42 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_LOOK_AT_H
+#define IGL_LOOK_AT_H
+#include "igl_inline.h"
+
+#include <Eigen/Dense>
+
+namespace igl 
+{
+  // Implementation of the deprecated gluLookAt function.
+  //
+  // Inputs:
+  //   eye  3-vector of eye position
+  //   center  3-vector of center reference point
+  //   up  3-vector of up vector
+  // Outputs:
+  //   R  4x4 rotation matrix
+  //
+  template <
+    typename Derivedeye,
+    typename Derivedcenter,
+    typename Derivedup,
+    typename DerivedR >
+  IGL_INLINE void look_at(
+    const Eigen::PlainObjectBase<Derivedeye> & eye,
+    const Eigen::PlainObjectBase<Derivedcenter> & center,
+    const Eigen::PlainObjectBase<Derivedup> & up,
+    Eigen::PlainObjectBase<DerivedR> & R);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "look_at.cpp"
+#endif
+
+#endif
+

+ 2 - 0
include/igl/matlab_format.cpp

@@ -119,4 +119,6 @@ template Eigen::WithFormat<Eigen::Matrix<float, 2, 1, 0, 2, 1> > const igl::matl
 template Eigen::WithFormat<Eigen::Matrix<float, 2, 2, 1, 2, 2> > const igl::matlab_format<Eigen::Matrix<float, 2, 2, 1, 2, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 2, 2, 1, 2, 2> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >);
 template Eigen::WithFormat<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const igl::matlab_format<Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >);
 template Eigen::WithFormat<Eigen::Matrix<double, 3, 3, 1, 3, 3> > const igl::matlab_format<Eigen::Matrix<double, 3, 3, 1, 3, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 3, 1, 3, 3> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >);
+template Eigen::WithFormat<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const igl::matlab_format<Eigen::Matrix<double, -1, -1, 1, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >);
+template Eigen::WithFormat<Eigen::Matrix<int, -1, -1, 1, -1, -1> > const igl::matlab_format<Eigen::Matrix<int, -1, -1, 1, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >);
 #endif

+ 20 - 0
include/igl/ortho.cpp

@@ -0,0 +1,20 @@
+#include "ortho.h"
+
+template < typename DerivedP>
+IGL_INLINE void igl::ortho(
+  const typename DerivedP::Scalar left,
+  const typename DerivedP::Scalar right,
+  const typename DerivedP::Scalar bottom,
+  const typename DerivedP::Scalar top,
+  const typename DerivedP::Scalar nearVal,
+  const typename DerivedP::Scalar farVal,
+  Eigen::PlainObjectBase<DerivedP> & P)
+{
+  P.setIdentity();
+  P(0,0) = 2. / (right - left);
+  P(1,1) = 2. / (top - bottom);
+  P(2,2) = - 2./ (farVal - nearVal);
+  P(0,3) = - (right + left) / (right - left);
+  P(1,3) = - (top + bottom) / (top - bottom);
+  P(2,3) = - (farVal + nearVal) / (farVal - nearVal);
+}

+ 42 - 0
include/igl/ortho.h

@@ -0,0 +1,42 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_ORTHO_H
+#define IGL_ORTHO_H
+#include "igl_inline.h"
+
+#include <Eigen/Dense>
+
+namespace igl 
+{
+  // Implementation of the deprecated glOrtho function.
+  //
+  // Inputs:
+  //   left  coordinate of left vertical clipping plane
+  //   right  coordinate of right vertical clipping plane
+  //   bottom  coordinate of bottom vertical clipping plane
+  //   top  coordinate of top vertical clipping plane
+  //   nearVal  distance to near plane
+  //   farVal  distance to far plane
+  // Outputs:
+  //   P  4x4 perspective matrix
+  template < typename DerivedP>
+  IGL_INLINE void ortho(
+    const typename DerivedP::Scalar left,
+    const typename DerivedP::Scalar right,
+    const typename DerivedP::Scalar bottom,
+    const typename DerivedP::Scalar top,
+    const typename DerivedP::Scalar nearVal,
+    const typename DerivedP::Scalar farVal,
+    Eigen::PlainObjectBase<DerivedP> & P);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "ortho.cpp"
+#endif
+
+#endif

+ 46 - 25
include/igl/outer_facet.cpp

@@ -1,6 +1,8 @@
 #include "outer_facet.h"
 #include "sort.h"
 #include "vertex_triangle_adjacency.h"
+#include <iostream>
+#define IGL_OUTER_FACET_DEBUG
 
 template <
   typename DerivedV,
@@ -25,47 +27,66 @@ IGL_INLINE void igl::outer_facet(
     typename Eigen::Matrix<Scalar, DerivedV::RowsAtCompileTime,1> VectorXS;
   // "Direct repair of self-intersecting meshes" [Attene 14]
   const Index mi = I.size();
-  Scalar max_x = -1e26;
+  assert(V.cols() == 3);
+  assert(N.cols() == 3);
   Index max_v = -1;
-  Scalar max_nx = -1e26;
-  for(Index i = 0;i<mi;i++)
+  for(size_t d = 0;d<(size_t)V.cols();d++)
   {
-    const Index f = I(i);
-    const Scalar nx = N(f,0);
-    if(fabs(nx)>0)
+    Scalar max_d = -1e26;
+    Scalar max_nd = -1e26;
+    for(Index i = 0;i<mi;i++)
     {
-      for(Index c = 0;c<3;c++)
+      const Index f = I(i);
+      const Scalar nd = N(f,d);
+      if(fabs(nd)>0)
       {
-        const Index v = F(f,c);
-        if(v == max_v)
+        for(Index c = 0;c<3;c++)
         {
-          if(fabs(nx) > max_nx)
+          const Index v = F(f,c);
+          if(v == max_v)
           {
-            // Just update max face and normal
-            max_f = f;
-            max_nx = fabs(nx);
-            flip = nx<0;
-          }
-        }else
-        {
-          const Scalar x = V(v);
-          if(x>max_x)
+            if(fabs(nd) > max_nd)
+            {
+              // Just update max face and normal
+              max_f = f;
+              max_nd = fabs(nd);
+              flip = nd<0;
+            }
+          }else
           {
-            // update max vertex, face and normal
-            max_v = v;
-            max_x = x;
-            max_f = f;
-            max_nx = fabs(nx);
-            flip = nx<0;
+            const Scalar vd = V(v,d);
+            if(vd>max_d)
+            {
+              // update max vertex, face and normal
+              max_v = v;
+              max_d = vd;
+              max_f = f;
+              max_nd = fabs(nd);
+              flip = nd<0;
+            }
           }
         }
       }
     }
+    if(max_v >= 0)
+    {
+      break;
+    }
+    // if we get here and max_v is still -1 then there were no faces with
+    // |N(d)| > 0
   }
+#ifdef IGL_OUTER_FACET_DEBUG
+  if(max_v <0)
+  {
+    cerr<<"Very degenerate case, no suitable face found."<<endl;
+  }
+#endif
   assert(max_v >=0 && "Very degenerate case, no suitable face found.");
 }
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 template void igl::outer_facet<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
+template void igl::outer_facet<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, unsigned long>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1> > const&, unsigned long&, bool&);
+template void igl::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
 #endif

+ 24 - 17
include/igl/outer_hull.cpp

@@ -64,12 +64,11 @@ IGL_INLINE void igl::outer_hull(
   // uE --> bool, whether needed to flip face to make "consistent" with unique
   //   edge
   VectorXI diIM(3*m);
+  VectorXI dicons(3*m);
   vector<vector<typename DerivedV::Scalar> > di(uE2E.size());
   // For each list of face-edges incide on a unique edge
   for(size_t ui = 0;ui<(size_t)uE.rows();ui++)
   {
-    const typename DerivedF::Scalar ud = uE(ui,1);
-    const typename DerivedF::Scalar us = uE(ui,0);
     // Base normal vector to orient against
     const auto fe0 = uE2E[ui][0];
     const auto & eVp = N.row(fe0%m);
@@ -78,9 +77,9 @@ IGL_INLINE void igl::outer_hull(
     const typename DerivedF::Scalar d = F(fe0%m,((fe0/m)+2)%3);
     const typename DerivedF::Scalar s = F(fe0%m,((fe0/m)+1)%3);
     // Edge vector
-    //const auto & eV = (V.row(ud)-V.row(us)).normalized();
     const auto & eV = (V.row(d)-V.row(s)).normalized();
 
+    vector<bool> cons(uE2E[ui].size());
     // Loop over incident face edges
     for(size_t fei = 0;fei<uE2E[ui].size();fei++)
     {
@@ -88,14 +87,14 @@ IGL_INLINE void igl::outer_hull(
       const auto f = fe % m;
       const auto c = fe / m;
       // source should match destination to be consistent
-      const bool cons = (d == F(f,(c+1)%3));
-      assert(cons ||  (d == F(f,(c+2)%3)));
-      assert(!cons || (s == F(f,(c+2)%3)));
-      assert(!cons || (d == F(f,(c+1)%3)));
+      cons[fei] = (d == F(f,(c+1)%3));
+      assert( cons[fei] ||  (d == F(f,(c+2)%3)));
+      assert(!cons[fei] || (s == F(f,(c+2)%3)));
+      assert(!cons[fei] || (d == F(f,(c+1)%3)));
       // Angle between n and f
       const auto & n = N.row(f);
       di[ui][fei] = M_PI - atan2( eVp.cross(n).dot(eV), eVp.dot(n));
-      if(!cons)
+      if(!cons[fei])
       {
         di[ui][fei] = di[ui][fei] + M_PI;
         if(di[ui][fei]>2.*M_PI)
@@ -113,6 +112,7 @@ IGL_INLINE void igl::outer_hull(
       uE2E[ui][fei] = temp[IM[fei]];
       const auto & fe = uE2E[ui][fei];
       diIM(fe) = fei;
+      dicons(fe) = cons[IM[fei]];
     }
 
   }
@@ -217,15 +217,19 @@ IGL_INLINE void igl::outer_hull(
       const auto & eV = (V.row(fd)-V.row(fs)).normalized();
       // edge valence
       const size_t val = uE2E[EMAP(e)].size();
-      const auto ui = EMAP(e);
-      const auto fe0 = uE2E[ui][0];
-      const auto es = F(fe0%m,((fe0/m)+1)%3);
-      const int e_cons = (fs == es?-1:1);
+
+//#warning "EXPERIMENTAL, DO NOT USE"
+      //// THIS IS WRONG! The first face is---after sorting---no longer the face
+      //// used for orienting the sort.
+      //const auto ui = EMAP(e);
+      //const auto fe0 = uE2E[ui][0];
+      //const auto es = F(fe0%m,((fe0/m)+1)%3);
+      const int e_cons = (dicons(e) ? 1: -1);
       const int nfei = (diIM(e) + val + e_cons*(flip(f)?-1:1))%val;
       const int max_ne_2 = uE2E[EMAP(e)][nfei];
-      // Loop over and find max dihedral angle
+
       int max_ne = -1;
-      // // SAVE THIS OLD IMPLEMENTATION FOR NOW
+      //// Loop over and find max dihedral angle
       //typename DerivedV::Scalar max_di = -1;
       //for(const auto & ne : neighbors)
       //{
@@ -250,10 +254,11 @@ IGL_INLINE void igl::outer_hull(
       //    max_di = ndi;
       //  }
       //}
+
       ////cout<<(max_ne != max_ne_2)<<" =?= "<<e_cons<<endl;
       //if(max_ne != max_ne_2)
       //{
-      //  cout<<(f+1)<<" ---> "<<(max_ne%m)+1<<" != "<<(max_ne_2%m)+1<<" ... "<<e_cons<<endl;
+      //  cout<<(f+1)<<" ---> "<<(max_ne%m)+1<<" != "<<(max_ne_2%m)+1<<" ... "<<e_cons<<" "<<flip(f)<<endl;
       //  typename DerivedV::Scalar max_di = -1;
       //  for(size_t nei = 0;nei<neighbors.size();nei++)
       //  {
@@ -261,7 +266,7 @@ IGL_INLINE void igl::outer_hull(
       //    const int nf = ne%m;
       //    if(nf == f)
       //    {
-      //      cout<<"  "<<(ne%m)+1<<": "<<0<<" "<<di[EMAP[e]][nei]<<" "<<diIM(ne)<<endl;
+      //      cout<<"  "<<(ne%m)+1<<":\t"<<0<<"\t"<<di[EMAP[e]][nei]<<" "<<diIM(ne)<<endl;
       //      continue;
       //    }
       //    // Corner of neighbor
@@ -274,7 +279,7 @@ IGL_INLINE void igl::outer_hull(
       //    const auto & nN = (cons? (flip(f)?-1:1.) : (flip(f)?1.:-1.) )*N.row(nf);
       //    // Angle between n and f
       //    const auto & ndi = M_PI - atan2( fN.cross(nN).dot(eV), fN.dot(nN));
-      //    cout<<"  "<<(ne%m)+1<<": "<<ndi<<" "<<di[EMAP[e]][nei]<<" "<<diIM(ne)<<endl;
+      //    cout<<"  "<<(ne%m)+1<<":\t"<<ndi<<"\t"<<di[EMAP[e]][nei]<<" "<<diIM(ne)<<endl;
       //    if(ndi>=max_di)
       //    {
       //      max_ne = ne;
@@ -426,6 +431,7 @@ IGL_INLINE void igl::outer_hull(
     }
   }
 }
+
 template <
   typename DerivedV,
   typename DerivedF,
@@ -447,4 +453,5 @@ IGL_INLINE void igl::outer_hull(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 template void igl::outer_hull<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
+template void igl::outer_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 1 - 0
include/igl/per_face_normals.cpp

@@ -53,4 +53,5 @@ template void igl::per_face_normals<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Ei
 template void igl::per_face_normals<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::per_face_normals<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
 template void igl::per_face_normals<Eigen::Matrix<float, -1, -1, 1, -1, -1>, Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1>, Eigen::Matrix<float, -1, -1, 1, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 1, -1, -1> >&);
+template void igl::per_face_normals<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
 #endif

+ 2 - 0
include/igl/per_vertex_normals.cpp

@@ -103,4 +103,6 @@ IGL_INLINE void igl::per_vertex_normals(
 // Explicit template specialization
 template void igl::per_vertex_normals<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::per_vertex_normals<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::per_vertex_normals<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
+template void igl::per_vertex_normals<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
 #endif

+ 2 - 0
include/igl/readDMAT.cpp

@@ -206,4 +206,6 @@ template bool igl::readDMAT<Eigen::Matrix<double, 4, 1, 0, 4, 1> >(std::basic_st
 template bool igl::readDMAT<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template bool igl::readDMAT<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template bool igl::readDMAT<Eigen::Matrix<int, -1, 2, 0, -1, 2> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
+template bool igl::readDMAT<Eigen::Matrix<double, -1, -1, 1, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&);
+template bool igl::readDMAT<Eigen::Matrix<int, -1, -1, 1, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1> >&);
 #endif

+ 1 - 0
include/igl/triangle_triangle_adjacency.cpp

@@ -207,4 +207,5 @@ template <
 // Explicit template specialization
 template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long, long, long>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&, bool, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&);
 template void igl::triangle_triangle_adjacency<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, long, long>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&, std::vector<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >, std::allocator<std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > > >&);
 #endif

+ 3 - 0
include/igl/unique_edge_map.cpp

@@ -39,4 +39,7 @@ IGL_INLINE void igl::unique_edge_map(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 template void igl::unique_edge_map<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >&);
+template void igl::unique_edge_map<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > >&);
+template void igl::unique_edge_map<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
+template void igl::unique_edge_map<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
 #endif 

+ 1 - 0
include/igl/view_axis.cpp

@@ -37,6 +37,7 @@ IGL_INLINE void igl::view_axis(Eigen::PlainObjectBase<DerivedV> & V)
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instanciation
 template void igl::view_axis<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
+template void igl::view_axis<Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
 #endif
 
 #endif

+ 4 - 2
include/igl/view_axis.h

@@ -13,6 +13,8 @@
 namespace igl
 {
   // Determines the view axis or depth axis of the current gl matrix
+  // Inputs:
+  //   mv pointer to modelview matrix
   // Outputs:
   //   x  pointer to x-coordinate in scene coordinates of the un-normalized
   //     viewing axis 
@@ -20,11 +22,11 @@ namespace igl
   //     viewing axis 
   //   z  pointer to z-coordinate in scene coordinates of the un-normalized
   //     viewing axis
-  //   mv pointer to modelview matrix
   //
   // Note: View axis is returned *UN-normalized*
-  IGL_INLINE void view_axis(double * x, double * y, double * z);
   IGL_INLINE void view_axis(const double * mv, double * x, double * y, double * z);
+  // Extract mv from current GL state.
+  IGL_INLINE void view_axis(double * x, double * y, double * z);
   template <typename DerivedV>
   IGL_INLINE void view_axis(Eigen::PlainObjectBase<DerivedV> & V);
 };

+ 21 - 100
include/igl/viewer/ViewerCore.cpp

@@ -7,95 +7,14 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 
 #include "ViewerCore.h"
-
-#include <iostream>
-#include <Eigen/Geometry>
-
 #include <igl/quat_to_mat.h>
+#include <igl/look_at.h>
+#include <igl/frustum.h>
+#include <igl/ortho.h>
 #include <igl/massmatrix.h>
-
-IGL_INLINE Eigen::Matrix4f lookAt (
-                        const Eigen::Vector3f& eye,
-                        const Eigen::Vector3f& center,
-                        const Eigen::Vector3f& up)
-{
-  Eigen::Vector3f f = (center - eye).normalized();
-  Eigen::Vector3f s = f.cross(up).normalized();
-  Eigen::Vector3f u = s.cross(f);
-
-  Eigen::Matrix4f Result = Eigen::Matrix4f::Identity();
-  Result(0,0) = s(0);
-  Result(0,1) = s(1);
-  Result(0,2) = s(2);
-  Result(1,0) = u(0);
-  Result(1,1) = u(1);
-  Result(1,2) = u(2);
-  Result(2,0) =-f(0);
-  Result(2,1) =-f(1);
-  Result(2,2) =-f(2);
-  Result(0,3) =-s.transpose() * eye;
-  Result(1,3) =-u.transpose() * eye;
-  Result(2,3) = f.transpose() * eye;
-  return Result;
-}
-
-IGL_INLINE Eigen::Matrix4f ortho(
-                       const float left,
-                       const float right,
-                       const float bottom,
-                       const float top,
-                       const float zNear,
-                       const float zFar
-                       )
-{
-  Eigen::Matrix4f Result = Eigen::Matrix4f::Identity();
-  Result(0,0) = 2.0f / (right - left);
-  Result(1,1) = 2.0f / (top - bottom);
-  Result(2,2) = - 2.0f / (zFar - zNear);
-  Result(0,3) = - (right + left) / (right - left);
-  Result(1,3) = - (top + bottom) / (top - bottom);
-  Result(2,3) = - (zFar + zNear) / (zFar - zNear);
-  return Result;
-}
-
-IGL_INLINE Eigen::Matrix4f frustum(
-                         const float left,
-                         const float right,
-                         const float bottom,
-                         const float top,
-                         const float nearVal,
-                         const float farVal)
-{
-  Eigen::Matrix4f Result = Eigen::Matrix4f::Zero();
-  Result(0,0) = (2.0f * nearVal) / (right - left);
-  Result(1,1) = (2.0f * nearVal) / (top - bottom);
-  Result(0,2) = (right + left) / (right - left);
-  Result(1,2) = (top + bottom) / (top - bottom);
-  Result(2,2) = -(farVal + nearVal) / (farVal - nearVal);
-  Result(3,2) = -1.0f;
-  Result(2,3) = -(2.0f * farVal * nearVal) / (farVal - nearVal);
-  return Result;
-}
-
-IGL_INLINE Eigen::Matrix4f scale(const Eigen::Matrix4f& m,
-                       const Eigen::Vector3f& v)
-{
-  Eigen::Matrix4f Result;
-  Result.col(0) = m.col(0).array() * v(0);
-  Result.col(1) = m.col(1).array() * v(1);
-  Result.col(2) = m.col(2).array() * v(2);
-  Result.col(3) = m.col(3);
-  return Result;
-}
-
-IGL_INLINE Eigen::Matrix4f translate(
-                          const Eigen::Matrix4f& m,
-                          const Eigen::Vector3f& v)
-{
-  Eigen::Matrix4f Result = m;
-  Result.col(3) = m.col(0).array() * v(0) + m.col(1).array() * v(1) + m.col(2).array() * v(2) + m.col(3).array();
-  return Result;
-}
+#include <igl/barycenter.h>
+#include <Eigen/Geometry>
+#include <iostream>
 
 #ifdef ENABLE_SERIALIZATION
 #include <igl/serialize.h>
@@ -193,8 +112,10 @@ IGL_INLINE void igl::ViewerCore::get_scale_and_shift_to_fit_mesh(
   //igl::massmatrix(V,F,igl::MASSMATRIX_TYPE_VORONOI,M);
   //const auto & MV = M*V;
   //Eigen::RowVector3d centroid  = MV.colwise().sum()/M.diagonal().sum();
-  Eigen::RowVector3d min_point = V.colwise().minCoeff();
-  Eigen::RowVector3d max_point = V.colwise().maxCoeff();
+  Eigen::MatrixXd BC;
+  igl::barycenter(V,F,BC);
+  Eigen::RowVector3d min_point = BC.colwise().minCoeff();
+  Eigen::RowVector3d max_point = BC.colwise().maxCoeff();
   Eigen::RowVector3d centroid  = 0.5*(min_point + max_point);
 
   shift = -centroid.cast<float>();
@@ -239,9 +160,7 @@ IGL_INLINE void igl::ViewerCore::draw(ViewerData& data, OpenGL_state& opengl)
   proj  = Eigen::Matrix4f::Identity();
 
   // Set view
-  view = lookAt(Eigen::Vector3f(camera_eye[0], camera_eye[1], camera_eye[2]),
-                Eigen::Vector3f(camera_center[0], camera_center[1], camera_center[2]),
-                Eigen::Vector3f(camera_up[0], camera_up[1], camera_up[2]));
+  look_at( camera_eye, camera_center, camera_up, view);
 
   float width  = viewport(2);
   float height = viewport(3);
@@ -251,13 +170,13 @@ IGL_INLINE void igl::ViewerCore::draw(ViewerData& data, OpenGL_state& opengl)
   {
     float length = (camera_eye - camera_center).norm();
     float h = tan(camera_view_angle/360.0 * M_PI) * (length);
-    proj = ortho(-h*width/height, h*width/height, -h, h, camera_dnear, camera_dfar);
+    ortho(-h*width/height, h*width/height, -h, h, camera_dnear, camera_dfar,proj);
   }
   else
   {
     float fH = tan(camera_view_angle / 360.0 * M_PI) * camera_dnear;
     float fW = fH * (double)width/(double)height;
-    proj = frustum(-fW, fW, -fH, fH, camera_dnear, camera_dfar);
+    frustum(-fW, fW, -fH, fH, camera_dnear, camera_dfar,proj);
   }
   // end projection
 
@@ -269,9 +188,10 @@ IGL_INLINE void igl::ViewerCore::draw(ViewerData& data, OpenGL_state& opengl)
     for (unsigned j=0;j<4;++j)
       model(i,j) = mat[i+4*j];
 
-  model = scale(model, Eigen::Vector3f(camera_zoom,camera_zoom,camera_zoom));
-  model = scale(model, Eigen::Vector3f(model_zoom,model_zoom,model_zoom));
-  model = translate(model, Eigen::Vector3f(model_translation[0],model_translation[1],model_translation[2]));
+  // Why not just use Eigen::Transform<double,3,Projective> for model...?
+  model.topLeftCorner(3,3)*=camera_zoom;
+  model.topLeftCorner(3,3)*=model_zoom;
+  model.col(3).head(3) += model.topLeftCorner(3,3)*model_translation;
 
   // Send transformations to the GPU
   GLint modeli = opengl.shader_mesh.uniform("model");
@@ -449,7 +369,7 @@ IGL_INLINE void igl::ViewerCore::draw_buffer(ViewerData& data,
   viewport = viewport_ori;
   
   // Copy back in the given Eigen matrices
-  GLubyte* pixels;
+  GLubyte* pixels = (GLubyte*)calloc(x*y*4,sizeof(GLubyte));
   glReadPixels
   (
    0, 0,
@@ -458,9 +378,9 @@ IGL_INLINE void igl::ViewerCore::draw_buffer(ViewerData& data,
    );
     
   int count = 0;
-  for (unsigned i=0; i<x; ++i)
+  for (unsigned j=0; j<y; ++j)
   {
-    for (unsigned j=0; j<y; ++j)
+    for (unsigned i=0; i<x; ++i)
     {
       R(i,j) = pixels[count*4+0];
       G(i,j) = pixels[count*4+1];
@@ -471,6 +391,7 @@ IGL_INLINE void igl::ViewerCore::draw_buffer(ViewerData& data,
   }
   
   // Clean up
+  free(pixels);
   glBindFramebuffer(GL_FRAMEBUFFER, 0);
   glDeleteRenderbuffers(1, &rboDepthStencil);
   glDeleteTextures(1, &texColorBuffer);

+ 1 - 1
libigl-logo.ai.REMOVED.git-id

@@ -1 +1 @@
-5c9b812fab266e0514ca0792d6a071e38ab6907c
+f91b6a376761d6f0a5cc97bd4066d17775ba61dc

+ 1 - 1
tutorial/cmake/FindEMBREE.cmake

@@ -44,5 +44,5 @@ IF (EMBREE_FOUND)
    )
    SET(EMBREE_INCLUDE_DIRS ${EMBREE_INCLUDE_DIR} ${EMBREE_INCLUDE_DIR}/embree)
 ELSE (EMBREE_FOUND)
-    message(FATAL_ERROR "could NOT find EMBREE")
+    message(STATUS "could NOT find EMBREE")
 ENDIF (EMBREE_FOUND)