瀏覽代碼

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

Former-commit-id: b5e840501a0f5d15051115e5f3ed828e5ab3b906
Olga Diamanti 10 年之前
父節點
當前提交
360ab05976

+ 0 - 1
build/Makefile

@@ -9,7 +9,6 @@ $(info Hello, $(IGL_USERNAME)!)
 
 # optimized default settings
 all: LFLAGS +=
-OPTFLAGS+=-O3 -DNDEBUG $(OPENMP)
 #debug: OPTFLAGS= -g -Wall -Werror
 debug: OPTFLAGS= -g -Wall
 debug: DEBUG=debug

+ 12 - 2
build/Makefile.conf

@@ -47,7 +47,7 @@ ifeq ($(IGL_USERNAME),whitinge)
 endif
 
 ifeq ($(IGL_USERNAME),ajx)
-	CFLAGS += -DIGL_STATIC_LIBRARY
+        LIBIGL_USE_STATIC_LIBRARY=1
 	MOSEKPLATFORM=osx64x86
 	MOSEKVERSION=7
 	IGL_WITH_VIEWER=1
@@ -85,6 +85,10 @@ ifeq ($(IGL_USERNAME),alecjaco)
 	OPENMP=-fopenmp
 endif
 
+ifeq ($(IGL_USERNAME),jacobson)
+	CFLAGS+=
+endif
+
 ifeq ($(IGL_USERNAME),sorkineo)
 	MOSEKPLATFORM=osx64x86
 	IGL_WITH_TETGEN=1
@@ -211,7 +215,6 @@ endif
 ifndef LIBIGL
 	LIBIGL=$(THIS_DIR)/../
 endif
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
 LIBIGL_INC=-I$(LIBIGL)/include
 
 ifndef ANTTWEAKBAR_INC
@@ -244,3 +247,10 @@ ifndef YIMG
 	YIMG_LIB=-L$(YIMG) -lyimg -lz -L/usr/X11/lib -L$(DEFAULT_PREFIX)/lib -lpng -bind_at_load
 	YIMG_INC=-I/usr/X11/include -I$(YIMG)
 endif
+
+ifdef LIBIGL_USE_STATIC_LIBRARY
+	CFLAGS += -DIGL_STATIC_LIBRARY
+	LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
+endif
+
+OPTFLAGS+=-O3 -DNDEBUG $(OPENMP)

+ 16 - 0
examples/camera/example.cpp

@@ -26,6 +26,22 @@
 #include <GL/glut.h>
 #endif
 
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
+#define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
+#define GLUT_WHEEL_LEFT  6
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
+#endif
+
 #include <vector>
 #include <stack>
 #include <iostream>

+ 16 - 0
examples/flare-eyes/example.cpp

@@ -35,6 +35,22 @@
 #include <GL/glut.h>
 #endif
 
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
+#define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
+#define GLUT_WHEEL_LEFT  6
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
+#endif
+
 #include <string>
 #include <vector>
 #include <iomanip>

+ 6 - 4
examples/patches/Makefile

@@ -2,7 +2,9 @@
 
 # Shared flags etc.
 include ../../build/Makefile.conf
-LIBIGL_LIB+=-liglembree -liglboost
+ifdef LIBIGL_USE_STATIC_LIBRARY
+	LIBIGL_LIB+=-liglembree -liglboost
+endif
 
 all: obj example
 
@@ -17,16 +19,16 @@ CPP_FILES=$(wildcard ./*.cpp)
 OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) 
 
 example: obj $(OBJ_FILES)
-	g++ $(OPENMP) $(AFLAGS) $(CFLAGS) -o example $(OBJ_FILES) $(LIB)
+	g++ $(OPTFLAGS) $(OPENMP) $(AFLAGS) $(CFLAGS) -o example $(OBJ_FILES) $(LIB)
 
 obj:
 	mkdir -p obj
 
 obj/%.o: %.cpp
-	g++ $(OPENMP) $(AFLAGS) $(CFLAGS) -c $< -o $@ $(INC)
+	g++ $(OPTFLAGS) $(OPENMP) $(AFLAGS) $(CFLAGS) -c $< -o $@ $(INC)
 
 obj/%.o: %.cpp %.h
-	g++ $(OPENMP) $(AFLAGS) $(CFLAGS) -c $< -o $@ $(INC)
+	g++ $(OPTFLAGS) $(OPENMP) $(AFLAGS) $(CFLAGS) -c $< -o $@ $(INC)
 
 clean:
 	rm -f $(OBJ_FILES)

+ 9 - 1
examples/patches/example.cpp

@@ -43,10 +43,18 @@
 
 #ifndef GLUT_WHEEL_UP
 #define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
 #define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
 #define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
 #define GLUT_WHEEL_LEFT  6
-#define GLUT_ACTIVE_COMMAND 1
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
 #endif
 
 #include <ctime>

+ 31 - 3
examples/quicklook-mesh/src/render_to_buffer.cpp

@@ -280,7 +280,24 @@ void display()
       glMaterialfv(GL_BACK, GL_SPECULAR, SILVER_SPECULAR);
       glMaterialf (GL_BACK, GL_SHININESS, 128);
     //}
-    draw_mesh(V,F,N);
+    if(F.rows() == 0)
+    {
+      glPointSize(1.+ 20./log10(V.rows()));
+      const bool has_normals = N.rows() == V.rows();
+      glBegin(GL_POINTS);
+      for(int v = 0;v<V.rows();v++)
+      {
+        if(has_normals)
+        {
+          glNormal3d(N(v,0),N(v,1),N(v,2));
+        }
+        glVertex3d(V(v,0),V(v,1),V(v,2));
+      }
+      glEnd();
+    }else
+    {
+      draw_mesh(V,F,N);
+    }
     //if(invert)
     //{
     //  glFrontFace(GL_CCW);
@@ -355,6 +372,7 @@ bool render_to_buffer(
     // Convert extension to lower case
     if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN))
     {
+      cerr<<"readOBJ failed."<<endl;
       red(width,height,buffer);
       return false;
     }
@@ -363,6 +381,7 @@ bool render_to_buffer(
     // Convert extension to lower case
     if(!igl::readOFF(filename,vV,vF,vN))
     {
+      cerr<<"readOFF failed."<<endl;
       red(width,height,buffer);
       return false;
     }
@@ -408,16 +427,25 @@ bool render_to_buffer(
   {
     if(!list_to_matrix(vV,V))
     {
+      cerr<<"list_to_matrix failed."<<endl;
       red(width,height,buffer);
       return false;
     }
+    if(!list_to_matrix(vN,N))
+    {
+      // silently continue
+      N.resize(0,0);
+    }
     polygon_mesh_to_triangle_mesh(vF,F);
   }
   cout<<"IO: "<<(get_seconds()-ts)<<"s"<<endl;
   ts = get_seconds();
 
-  // Computer already normalized per triangle normals
-  per_face_normals(V,F,N);
+  // Compute already normalized per triangle normals
+  if(N.rows() != V.rows() && N.rows() != F.rows())
+  {
+    per_face_normals(V,F,N);
+  }
   //Vmean = 0.5*(V.colwise().maxCoeff()+V.colwise().minCoeff());
   Vmax = V.colwise().maxCoeff();
   Vmin = V.colwise().minCoeff();

+ 16 - 0
examples/randomly-sample-mesh/example.cpp

@@ -32,6 +32,22 @@
 #include <GL/glut.h>
 #endif
 
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
+#define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
+#define GLUT_WHEEL_LEFT  6
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
+#endif
+
 #include <string>
 #include <vector>
 #include <stack>

+ 16 - 0
examples/rotate-widget/example.cpp

@@ -33,6 +33,22 @@
 # include <GL/glut.h>
 #endif
 
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
+#define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
+#define GLUT_WHEEL_LEFT  6
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
+#endif
+
 #include <string>
 #include <vector>
 #include <list>

+ 16 - 0
examples/scene-rotation/example.cpp

@@ -36,6 +36,22 @@
 #include <GL/glut.h>
 #endif
 
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
+#define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
+#define GLUT_WHEEL_LEFT  6
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
+#endif
+
 #include <string>
 #include <vector>
 #include <stack>

+ 9 - 1
examples/shadow-mapping/example.cpp

@@ -43,10 +43,18 @@
 
 #ifndef GLUT_WHEEL_UP
 #define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
 #define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
 #define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
 #define GLUT_WHEEL_LEFT  6
-#define GLUT_ACTIVE_COMMAND 1
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
 #endif
 
 #include <ctime>

+ 16 - 0
examples/skeleton-builder/example.cpp

@@ -51,6 +51,22 @@
 #include <GL/glut.h>
 #endif
 
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
+#define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
+#define GLUT_WHEEL_LEFT  6
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
+#endif
+
 #include <string>
 #include <vector>
 #include <queue>

+ 16 - 3
examples/skeleton-poser/example.cpp

@@ -49,13 +49,26 @@
 
 #ifdef __APPLE__
 #include <GLUT/glut.h>
-#ifndef GLUT_ACTIVE_COMMAND
-#  define GLUT_ACTIVE_COMMAND 9
-#endif
 #else
 #include <GL/glut.h>
 #endif
 
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
+#define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
+#define GLUT_WHEEL_LEFT  6
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
+#endif
+
 #include <string>
 #include <vector>
 #include <queue>

+ 16 - 0
examples/skeleton/example.cpp

@@ -40,6 +40,22 @@
 #include <GL/glut.h>
 #endif
 
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
+#define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
+#define GLUT_WHEEL_LEFT  6
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
+#endif
+
 #include <string>
 #include <vector>
 #include <stack>

+ 1 - 1
examples/upright/Makefile

@@ -11,7 +11,7 @@ include ../..//build/Makefile.conf
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 
-CFLAGS+=-g
+CFLAGS+=-g $(OPTFLAGS)
 
 upright: upright.o
 	g++ $(OPENMP) $(AFLAGS) $(CFLAGS) -o upright upright.o $(LIB)

+ 28 - 94
examples/upright/example.cpp

@@ -8,13 +8,7 @@
 // normals, texture coordinates, etc. in the input file will be ignored and
 // lost in the output file.
 //
-#include <igl/readOBJ.h>
-#include <igl/writeOBJ.h>
-#include <igl/writeOFF.h>
-#include <igl/readWRL.h>
-#include <igl/polygon_mesh_to_triangle_mesh.h>
-#include <igl/readOFF.h>
-#include <igl/readMESH.h>
+#include <igl/read_triangle_mesh.h>
 #include <igl/draw_mesh.h>
 #include <igl/draw_floor.h>
 #include <igl/pathinfo.h>
@@ -23,6 +17,7 @@
 #include <igl/material_colors.h>
 #include <igl/trackball.h>
 #include <igl/snap_to_canonical_view_quat.h>
+#include <igl/write_triangle_mesh.h>
 #include <igl/REDRUM.h>
 
 #include <Eigen/Core>
@@ -34,6 +29,22 @@
 #include <GL/glut.h>
 #endif
 
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP    3
+#endif
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN  4
+#endif
+#ifndef GLUT_WHEEL_RIGHT
+#define GLUT_WHEEL_RIGHT 5
+#endif
+#ifndef GLUT_WHEEL_LEFT
+#define GLUT_WHEEL_LEFT  6
+#endif
+#ifndef GLUT_ACTIVE_COMMAND
+#define GLUT_ACTIVE_COMMAND 8
+#endif
+
 #include <string>
 #include <vector>
 #include <stack>
@@ -301,47 +312,15 @@ bool save()
   using namespace std;
   using namespace igl;
   using namespace Eigen;
-  // dirname, basename, extension and filename
-  string d,b,ext,f;
-  pathinfo(out_filename,d,b,ext,f);
-  // Convert extension to lower case
-  transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
-  if(ext == "obj")
+  if(write_triangle_mesh(out_filename,s.V,s.F))
   {
-    // Convert extension to lower case
-    if(!igl::writeOBJ(out_filename,s.V,s.F))
-    {
-      return false;
-    }
-  }else if(ext == "off")
+    cout<<GREENGIN("Current baked model written to "+out_filename+".")<<endl;
+    return true;
+  }else
   {
-    // Convert extension to lower case
-    if(!igl::writeOFF(out_filename,s.V,s.F))
-    {
-      return false;
-    }
-  //}else if(ext == "wrl")
-  //{
-  //  // Convert extension to lower case
-  //  if(!igl::readWRL(filename,vV,vF))
-  //  {
-  //    return 1;
-  //  }
-  //}else
-  //{
-  //  // Convert extension to lower case
-  //  MatrixXi T;
-  //  if(!igl::readMESH(filename,V,T,F))
-  //  {
-  //    return 1;
-  //  }
-  //  //if(F.size() > T.size() || F.size() == 0)
-  //  {
-  //    boundary_facets(T,F);
-  //  }
+    cout<<REDRUM("Current baked model failed to write to "+out_filename+".")<<endl;
+    return false;
   }
-  cout<<GREENGIN("Current baked model written to "+out_filename+".")<<endl;
-  return true;
 }
 
 
@@ -455,56 +434,11 @@ int main(int argc, char * argv[])
   // Read and prepare mesh
   string filename = argv[1];
   out_filename = argv[2];
-  // dirname, basename, extension and filename
-  string d,b,ext,f;
-  pathinfo(filename,d,b,ext,f);
-  // Convert extension to lower case
-  transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
-  vector<vector<double > > vV,vN,vTC;
-  vector<vector<int > > vF,vFTC,vFN;
-  if(ext == "obj")
-  {
-    // Convert extension to lower case
-    if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN))
-    {
-      return 1;
-    }
-  }else if(ext == "off")
-  {
-    // Convert extension to lower case
-    if(!igl::readOFF(filename,vV,vF,vN))
-    {
-      return 1;
-    }
-  }else if(ext == "wrl")
+  if(!read_triangle_mesh(filename,s.V,s.F))
   {
-    // Convert extension to lower case
-    if(!igl::readWRL(filename,vV,vF))
-    {
-      return 1;
-    }
-  //}else
-  //{
-  //  // Convert extension to lower case
-  //  MatrixXi T;
-  //  if(!igl::readMESH(filename,V,T,F))
-  //  {
-  //    return 1;
-  //  }
-  //  //if(F.size() > T.size() || F.size() == 0)
-  //  {
-  //    boundary_facets(T,F);
-  //  }
+    cout<<"Failed to read from "<<filename<<"."<<endl;
+    return EXIT_FAILURE;
   }
-  if(vV.size() > 0)
-  {
-    if(!list_to_matrix(vV,s.V))
-    {
-      return 1;
-    }
-    polygon_mesh_to_triangle_mesh(vF,s.F);
-  }
-
   init_relative();
 
   // Init glut
@@ -520,5 +454,5 @@ int main(int argc, char * argv[])
   //glutPassiveMotionFunc(mouse_move);
   glutMainLoop();
 
-  return 0;
+  return EXIT_SUCCESS;
 }

+ 1 - 0
include/igl/OpenGL_convenience.h

@@ -18,6 +18,7 @@
 #if __APPLE__
 #  include <OpenGL/gl.h>
 #  include <OpenGL/glu.h>
+#  include <OpenGL/glext.h>
 #elif defined(_WIN32)
 #    define NOMINMAX
 #    include <Windows.h>

+ 2 - 1
include/igl/false_barycentric_subdivision.h

@@ -19,7 +19,8 @@ namespace igl
   //   F       #F by 3 list of mesh faces (must be triangles)
   // Outputs:
   //   VD      #V + #F by 3 coordinate of the vertices of the dual mesh
-  //           The added vertices are added at the end of VD
+  //           The added vertices are added at the end of VD (should not be
+  //           same references as (V,F)
   //   FD      #F*3 by 3 faces of the dual mesh
   //
   template <typename Scalar, typename Index>

+ 3 - 1
include/igl/is_border_vertex.cpp

@@ -11,7 +11,9 @@
 #include "triangle_triangle_adjacency.h"
 
 template <typename DerivedV, typename DerivedF>
-IGL_INLINE std::vector<bool> igl::is_border_vertex(const Eigen::PlainObjectBase<DerivedV> &V, const Eigen::PlainObjectBase<DerivedF> &F)
+IGL_INLINE std::vector<bool> igl::is_border_vertex(
+    const Eigen::PlainObjectBase<DerivedV> &V, 
+    const Eigen::PlainObjectBase<DerivedF> &F)
 {
   Eigen::PlainObjectBase<DerivedF> FF;
   igl::triangle_triangle_adjacency(V,F,FF);

+ 2 - 1
include/igl/is_border_vertex.h

@@ -22,7 +22,8 @@ namespace igl
   //   F  #F by 3 list of triangle indices
   // Returns #V vector of bools revealing whether vertices are on boundary
   //
-  // Known Bugs: does not depend on V
+  // Known Bugs: - does not depend on V
+  //             - assumes mesh is edge manifold
   // 
   template <typename DerivedV, typename DerivedF>
   IGL_INLINE std::vector<bool> is_border_vertex(

+ 1 - 0
include/igl/list_to_matrix.cpp

@@ -165,4 +165,5 @@ template bool igl::list_to_matrix<double, Eigen::PlainObjectBase<Eigen::Matrix<d
 template bool igl::list_to_matrix<double, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > >(std::vector<double, std::allocator<double> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
 template bool igl::list_to_matrix<double, Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 1, 0, 4, 1> > >(std::vector<double, std::allocator<double> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 1, 0, 4, 1> >&);
 template bool igl::list_to_matrix<double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(std::vector<double, std::allocator<double> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template bool igl::list_to_matrix<int, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::Matrix<int, -1, 2, 0, -1, 2>&);
 #endif

+ 19 - 15
include/igl/min_quad_with_fixed.cpp

@@ -51,18 +51,18 @@ IGL_INLINE bool igl::min_quad_with_fixed_precompute(
   // default is to have 0 linear equality constraints
   if(Aeq.size() != 0)
   {
-    assert(n == Aeq.cols());
+    assert(n == Aeq.cols() && "#Aeq.cols() should match A.rows()");
   }
 
-  assert(A.rows() == n);
-  assert(A.cols() == n);
+  assert(A.rows() == n && "A should be square");
+  assert(A.cols() == n && "A should be square");
 
   // number of known rows
   int kr = known.size();
 
-  assert(kr == 0 || known.minCoeff() >= 0);
-  assert(kr == 0 || known.maxCoeff() < n);
-  assert(neq <= n);
+  assert((kr == 0 || known.minCoeff() >= 0)&& "known indices should be in [0,n)");
+  assert((kr == 0 || known.maxCoeff() < n) && "known indices should be in [0,n)");
+  assert(neq <= n && "Number of equality constraints should be less than DOFs");
 
   // cache known
   data.known = known;
@@ -95,7 +95,7 @@ IGL_INLINE bool igl::min_quad_with_fixed_precompute(
 
   SparseMatrix<T> Auu;
   slice(A,data.unknown,data.unknown,Auu);
-  assert(Auu.size() > 0 && "All DOFs seem to be fixed.");
+  assert(Auu.size() > 0 && "There should be at least one unknown.");
 
   // Positive definiteness is *not* determined, rather it is given as a
   // parameter
@@ -106,7 +106,8 @@ IGL_INLINE bool igl::min_quad_with_fixed_precompute(
     data.Auu_sym = true;
     // This is an annoying assertion unless EPS can be chosen in a nicer way.
     //assert(is_symmetric(Auu,EPS<double>()));
-    assert(is_symmetric(Auu,1.0));
+    assert(is_symmetric(Auu,1.0) && 
+      "Auu should be symmetric if positive definite");
   }else
   {
     // determine if A(unknown,unknown) is symmetric and/or positive definite
@@ -125,8 +126,10 @@ IGL_INLINE bool igl::min_quad_with_fixed_precompute(
 #endif
     // QR decomposition to determine row rank in Aequ
     slice(Aeq,data.unknown,2,data.Aequ);
-    assert(data.Aequ.rows() == neq);
-    assert(data.Aequ.cols() == data.unknown.size());
+    assert(data.Aequ.rows() == neq && 
+      "#Rows in Aequ should match #constraints");
+    assert(data.Aequ.cols() == data.unknown.size() && 
+      "#cols in Aequ should match #unknowns");
     data.AeqTQR.compute(data.Aequ.transpose().eval());
 #ifdef MIN_QUAD_WITH_FIXED_CPP_DEBUG
     cout<<endl<<matlab_format(SparseMatrix<T>(data.Aequ.transpose().eval()),"AeqT")<<endl<<endl;
@@ -146,7 +149,8 @@ IGL_INLINE bool igl::min_quad_with_fixed_precompute(
         return false;
     }
     nc = data.AeqTQR.rank();
-    assert(nc<=neq);
+    assert(nc<=neq && 
+      "Rank of reduced constraints should be <= #original constraints");
     data.Aeq_li = nc == neq;
     //cout<<"data.Aeq_li: "<<data.Aeq_li<<endl;
   }else
@@ -304,10 +308,10 @@ IGL_INLINE bool igl::min_quad_with_fixed_precompute(
     I.setIdentity();
     data.AeqTE = data.AeqTQR.colsPermutation() * I;
     data.AeqTET = data.AeqTQR.colsPermutation().transpose() * I;
-    assert(AeqTR.rows() == neq);
-    assert(AeqTQ.rows() == nu);
-    assert(AeqTQ.cols() == nu);
-    assert(AeqTR.cols() == neq);
+    assert(AeqTR.rows() == nu   && "#rows in AeqTR should match #unknowns");
+    assert(AeqTR.cols() == neq  && "#cols in AeqTR should match #constraints");
+    assert(AeqTQ.rows() == nu && "#rows in AeqTQ should match #unknowns");
+    assert(AeqTQ.cols() == nu && "#cols in AeqTQ should match #unknowns");
     //cout<<"    slice"<<endl;
 #ifdef MIN_QUAD_WITH_FIXED_CPP_DEBUG
     cout<<"    slice"<<endl;

+ 21 - 4
include/igl/pathinfo.h

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 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 
+//
+// 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_PATHINFO_H
 #define IGL_PATHINFO_H
@@ -30,6 +30,23 @@ namespace igl
   //  filename  string containing filename (characters of basename before last
   //    '.')
   //
+  //
+  // Examples:
+  //
+  // input                     | dirname        basename       ext    filename
+  // "/"                       | "/"            ""             ""     ""
+  // "//"                      | "/"            ""             ""     ""
+  // "/foo"                    | "/"            "foo"          ""     "foo"
+  // "/foo/"                   | "/"            "foo"          ""     "foo"
+  // "/foo//"                  | "/"            "foo"          ""     "foo"
+  // "/foo/./"                 | "/foo"         "."            ""     ""
+  // "/foo/bar"                | "/foo"         "bar"          ""     "bar"
+  // "/foo/bar."               | "/foo"         "bar."         ""     "bar"
+  // "/foo/bar.txt"            | "/foo"         "bar.txt"      "txt"  "bar"
+  // "/foo/bar.txt.zip"        | "/foo"         "bar.txt.zip"  "zip"  "bar.txt"
+  // "/foo/bar.dir/"           | "/foo"         "bar.dir"      "dir"  "bar"
+  // "/foo/bar.dir/file"       | "/foo/bar.dir" "file"         ""     "file"
+  // "/foo/bar.dir/file.txt"   | "/foo/bar.dir" "file.txt"     "txt"  "file"
   //  See also: basename, dirname
   IGL_INLINE void pathinfo(
     const std::string & path,

+ 6 - 3
include/igl/readOFF.cpp

@@ -16,6 +16,7 @@ IGL_INLINE bool igl::readOFF(
   std::vector<std::vector<Index > > & F,
   std::vector<std::vector<Scalar > > & N)
 {
+  using namespace std;
   FILE * off_file = fopen(off_file_name.c_str(),"r");                                       
   if(NULL==off_file)
   {
@@ -30,13 +31,15 @@ IGL_INLINE bool igl::readOFF(
   const std::string OFF("OFF");
   const std::string NOFF("NOFF");
   if(fscanf(off_file,"%s\n",header)!=1
-     || !(OFF == header || NOFF == header))
+     || !(
+       string(header).compare(0, OFF.length(), OFF)==0 || 
+       string(header).compare(0,NOFF.length(),NOFF)==0))
   {
     printf("Error: %s's first line should be OFF or NOFF not %s...",off_file_name.c_str(),header);
     fclose(off_file);
     return false; 
   }
-  bool has_normals = NOFF==header;
+  bool has_normals = string(header).compare(0,NOFF.length(),NOFF)==0;
   // Second line is #vertices #faces #edges
   int number_of_vertices;
   int number_of_faces;
@@ -80,7 +83,7 @@ IGL_INLINE bool igl::readOFF(
       }
       i++;
     }else if(
-             fscanf(off_file,"%[#]",&tic_tac_toe)==1)
+        fscanf(off_file,"%[#]",&tic_tac_toe)==1)
     {
       char comment[1000];
       fscanf(off_file,"%[^\n]",comment);

+ 70 - 110
include/igl/slice.cpp

@@ -21,6 +21,71 @@ IGL_INLINE void igl::slice(
   const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
   Eigen::SparseMatrix<T>& Y)
 {
+#if true
+  int xm = X.rows();
+  int xn = X.cols();
+  int ym = R.size();
+  int yn = C.size();
+
+  // special case when R or C is empty
+  if(ym == 0 || yn == 0)
+  {
+    Y.resize(ym,yn);
+    return;
+  }
+
+  assert(R.minCoeff() >= 0);
+  assert(R.maxCoeff() < xm);
+  assert(C.minCoeff() >= 0);
+  assert(C.maxCoeff() < xn);
+
+  // Build reindexing maps for columns and rows, -1 means not in map
+  std::vector<std::vector<int> > RI;
+  RI.resize(xm);
+  for(int i = 0;i<ym;i++)
+  {
+    RI[R(i)].push_back(i);
+  }
+  std::vector<std::vector<int> > CI;
+  CI.resize(xn);
+  // initialize to -1
+  for(int i = 0;i<yn;i++)
+  {
+    CI[C(i)].push_back(i);
+  }
+  // Resize output
+  Eigen::DynamicSparseMatrix<T, Eigen::RowMajor> dyn_Y(ym,yn);
+  // Take a guess at the number of nonzeros (this assumes uniform distribution
+  // not banded or heavily diagonal)
+  dyn_Y.reserve((X.nonZeros()/(X.rows()*X.cols())) * (ym*yn));
+  // Iterate over outside
+  for(int k=0; k<X.outerSize(); ++k)
+  {
+    // Iterate over inside
+    for(typename Eigen::SparseMatrix<T>::InnerIterator it (X,k); it; ++it)
+    {
+      std::vector<int>::iterator rit, cit;
+      for(rit = RI[it.row()].begin();rit != RI[it.row()].end(); rit++)
+      {
+        for(cit = CI[it.col()].begin();cit != CI[it.col()].end(); cit++)
+        {
+          dyn_Y.coeffRef(*rit,*cit) = it.value();
+        }
+      }
+    }
+  }
+  Y = Eigen::SparseMatrix<T>(dyn_Y);
+#else
+
+  // Alec: This is _not_ valid for arbitrary R,C since they don't necessary
+  // representation a strict permutation of the rows and columns: rows or
+  // columns could be removed or replicated. The removal of rows seems to be
+  // handled here (although it's not clear if there is a performance gain when
+  // the #removals >> #remains). If this is sufficiently faster than the
+  // correct code above, one could test whether all entries in R and C are
+  // unique and apply the permutation version if appropriate. 
+  //
+
   int xm = X.rows();
   int xn = X.cols();
   int ym = R.size();
@@ -39,8 +104,8 @@ IGL_INLINE void igl::slice(
   assert(C.maxCoeff() < xn);
 
   // initialize row and col permutation vectors
-  Eigen::VectorXi rowIndexVec = Eigen::VectorXi::LinSpaced(xm,0,xm);
-  Eigen::VectorXi rowPermVec  = Eigen::VectorXi::LinSpaced(xm,0,xm);
+  Eigen::VectorXi rowIndexVec = Eigen::VectorXi::LinSpaced(xm,0,xm-1);
+  Eigen::VectorXi rowPermVec  = Eigen::VectorXi::LinSpaced(xm,0,xm-1);
   for(int i=0;i<ym;i++)
   {
     int pos = rowIndexVec.coeffRef(R(i));
@@ -53,8 +118,8 @@ IGL_INLINE void igl::slice(
   }
   Eigen::PermutationMatrix<Eigen::Dynamic,Eigen::Dynamic,int> rowPerm(rowIndexVec);
 
-  Eigen::VectorXi colIndexVec = Eigen::VectorXi::LinSpaced(xn,0,xn);
-  Eigen::VectorXi colPermVec = Eigen::VectorXi::LinSpaced(xn,0,xn);
+  Eigen::VectorXi colIndexVec = Eigen::VectorXi::LinSpaced(xn,0,xn-1);
+  Eigen::VectorXi colPermVec =  Eigen::VectorXi::LinSpaced(xn,0,xn-1);
   for(int i=0;i<yn;i++)
   {
     int pos = colIndexVec.coeffRef(C(i));
@@ -69,6 +134,7 @@ IGL_INLINE void igl::slice(
 
   Eigen::SparseMatrix<T> M = (rowPerm * X);
   Y = (M * colPerm).block(0,0,ym,yn);
+#endif
 }
 
 template <typename Mat>
@@ -147,90 +213,6 @@ IGL_INLINE void igl::slice(
   }
 }
 
-template <typename DerivedX>
-IGL_INLINE void igl::slice_mask(
-  const Eigen::PlainObjectBase<DerivedX> & X,
-  const Eigen::Array<bool,Eigen::Dynamic,1> & R,
-  const Eigen::Array<bool,Eigen::Dynamic,1> & C,
-  Eigen::PlainObjectBase<DerivedX> & Y)
-{
-  int xm = X.rows();
-  int xn = X.cols();
-  int ym = R.count();
-  int yn = C.count();
-  assert(R.size() == X.rows() && "R.size() should match X.rows()");
-  assert(C.size() == X.cols() && "C.size() should match X.cols()");
-  Y.resize(ym,yn);
-  {
-    int yi = 0;
-    for(int i = 0;i<xm;i++)
-    {
-      if(R(i))
-      {
-        int yj = 0;
-        for(int j = 0;j<xn;j++)
-        {
-          if(C(j))
-          {
-            Y(yi,yj) = X(i,j);
-            yj++;
-          }
-        }
-        yi++;
-      }
-    }
-  }
-}
-
-template <typename DerivedX>
-IGL_INLINE void igl::slice_mask(
-  const Eigen::PlainObjectBase<DerivedX> & X,
-  const Eigen::Array<bool,Eigen::Dynamic,1> & R,
-  const int dim,
-  Eigen::PlainObjectBase<DerivedX> & Y)
-{
-  switch(dim)
-  {
-    case 1:
-    {
-      const int ym = R.count();
-      Y.resize(ym,X.cols());
-      assert(X.rows() == R.size() && "X.rows() should match R.size()");
-      {
-        int yi = 0;
-        for(int i = 0;i<X.rows();i++)
-        {
-          if(R(i))
-          {
-            Y.row(yi++) = X.row(i);
-          }
-        }
-      }
-      return;
-    }
-    case 2:
-    {
-      const auto & C = R;
-      const int yn = C.count();
-      Y.resize(X.rows(),yn);
-      assert(X.cols() == R.size() && "X.cols() should match R.size()");
-      {
-        int yj = 0;
-        for(int j = 0;j<X.cols();j++)
-        {
-          if(C(j))
-          {
-            Y.col(yj++) = X.col(j);
-          }
-        }
-      }
-      return;
-    }
-    default:
-      assert(false && "Unsupported dimension");
-      return;
-  }
-}
 
 template <typename DerivedX>
 IGL_INLINE void igl::slice(
@@ -266,28 +248,6 @@ IGL_INLINE Eigen::PlainObjectBase<DerivedX> igl::slice(
   return Y;
 }
 
-template <typename DerivedX>
-IGL_INLINE Eigen::PlainObjectBase<DerivedX> igl::slice_mask(
-  const Eigen::PlainObjectBase<DerivedX> & X,
-  const Eigen::Array<bool,Eigen::Dynamic,1> & R,
-  const Eigen::Array<bool,Eigen::Dynamic,1> & C)
-{
-  Eigen::PlainObjectBase<DerivedX> Y;
-  igl::slice_mask(X,R,C,Y);
-  return Y;
-}
-
-template <typename DerivedX>
-IGL_INLINE Eigen::PlainObjectBase<DerivedX> igl::slice_mask(
-  const Eigen::PlainObjectBase<DerivedX>& X,
-  const Eigen::Array<bool,Eigen::Dynamic,1> & R,
-  const int dim)
-{
-  Eigen::PlainObjectBase<DerivedX> Y;
-  igl::slice_mask(X,R,dim,Y);
-  return Y;
-}
-
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // generated by autoexplicit.sh

+ 5 - 25
include/igl/slice.h

@@ -9,12 +9,11 @@
 #define IGL_SLICE_H
 #include "igl_inline.h"
 
-#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
 #include <Eigen/Sparse>
-
 namespace igl
 {
-  // Act like the matlab X(row_indices,col_indices) operator
+  // Act like the matlab X(row_indices,col_indices) operator, where
+  // row_indices, col_indices are non-negative integer indices.
   // 
   // Inputs:
   //   X  m by n matrix
@@ -22,6 +21,8 @@ namespace igl
   //   C  list of column indices
   // Output:
   //   Y  #R by #C matrix
+  //
+  // See also: slice_mask
   template <typename T>
   IGL_INLINE void slice(
     const Eigen::SparseMatrix<T>& X,
@@ -46,18 +47,6 @@ namespace igl
     const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
     const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
     Eigen::PlainObjectBase<DerivedX> & Y);
-  template <typename DerivedX>
-  IGL_INLINE void slice_mask(
-    const Eigen::PlainObjectBase<DerivedX> & X,
-    const Eigen::Array<bool,Eigen::Dynamic,1> & R,
-    const Eigen::Array<bool,Eigen::Dynamic,1> & C,
-    Eigen::PlainObjectBase<DerivedX> & Y);
-  template <typename DerivedX>
-  IGL_INLINE void slice_mask(
-    const Eigen::PlainObjectBase<DerivedX> & X,
-    const Eigen::Array<bool,Eigen::Dynamic,1> & R,
-    const int dim,
-    Eigen::PlainObjectBase<DerivedX> & Y);
 
   template <typename DerivedX>
   IGL_INLINE void slice(
@@ -74,16 +63,7 @@ namespace igl
     const Eigen::PlainObjectBase<DerivedX>& X,
     const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
     const int dim);
-  template <typename DerivedX>
-  IGL_INLINE Eigen::PlainObjectBase<DerivedX> slice_mask(
-    const Eigen::PlainObjectBase<DerivedX> & X,
-    const Eigen::Array<bool,Eigen::Dynamic,1> & R,
-    const Eigen::Array<bool,Eigen::Dynamic,1> & C);
-  template <typename DerivedX>
-  IGL_INLINE Eigen::PlainObjectBase<DerivedX> slice_mask(
-    const Eigen::PlainObjectBase<DerivedX> & X,
-    const Eigen::Array<bool,Eigen::Dynamic,1> & R,
-    const int dim);
+
 }
 
 #ifndef IGL_STATIC_LIBRARY

+ 113 - 0
include/igl/slice_mask.cpp

@@ -0,0 +1,113 @@
+#include "slice_mask.h"
+#include <cassert>
+
+template <typename DerivedX>
+IGL_INLINE void igl::slice_mask(
+  const Eigen::PlainObjectBase<DerivedX> & X,
+  const Eigen::Array<bool,Eigen::Dynamic,1> & R,
+  const Eigen::Array<bool,Eigen::Dynamic,1> & C,
+  Eigen::PlainObjectBase<DerivedX> & Y)
+{
+  int xm = X.rows();
+  int xn = X.cols();
+  int ym = R.count();
+  int yn = C.count();
+  assert(R.size() == X.rows() && "R.size() should match X.rows()");
+  assert(C.size() == X.cols() && "C.size() should match X.cols()");
+  Y.resize(ym,yn);
+  {
+    int yi = 0;
+    for(int i = 0;i<xm;i++)
+    {
+      if(R(i))
+      {
+        int yj = 0;
+        for(int j = 0;j<xn;j++)
+        {
+          if(C(j))
+          {
+            Y(yi,yj) = X(i,j);
+            yj++;
+          }
+        }
+        yi++;
+      }
+    }
+  }
+}
+
+template <typename DerivedX>
+IGL_INLINE void igl::slice_mask(
+  const Eigen::PlainObjectBase<DerivedX> & X,
+  const Eigen::Array<bool,Eigen::Dynamic,1> & R,
+  const int dim,
+  Eigen::PlainObjectBase<DerivedX> & Y)
+{
+  switch(dim)
+  {
+    case 1:
+    {
+      const int ym = R.count();
+      Y.resize(ym,X.cols());
+      assert(X.rows() == R.size() && "X.rows() should match R.size()");
+      {
+        int yi = 0;
+        for(int i = 0;i<X.rows();i++)
+        {
+          if(R(i))
+          {
+            Y.row(yi++) = X.row(i);
+          }
+        }
+      }
+      return;
+    }
+    case 2:
+    {
+      const auto & C = R;
+      const int yn = C.count();
+      Y.resize(X.rows(),yn);
+      assert(X.cols() == R.size() && "X.cols() should match R.size()");
+      {
+        int yj = 0;
+        for(int j = 0;j<X.cols();j++)
+        {
+          if(C(j))
+          {
+            Y.col(yj++) = X.col(j);
+          }
+        }
+      }
+      return;
+    }
+    default:
+      assert(false && "Unsupported dimension");
+      return;
+  }
+}
+
+template <typename DerivedX>
+IGL_INLINE Eigen::PlainObjectBase<DerivedX> igl::slice_mask(
+  const Eigen::PlainObjectBase<DerivedX> & X,
+  const Eigen::Array<bool,Eigen::Dynamic,1> & R,
+  const Eigen::Array<bool,Eigen::Dynamic,1> & C)
+{
+  Eigen::PlainObjectBase<DerivedX> Y;
+  igl::slice_mask(X,R,C,Y);
+  return Y;
+}
+
+template <typename DerivedX>
+IGL_INLINE Eigen::PlainObjectBase<DerivedX> igl::slice_mask(
+  const Eigen::PlainObjectBase<DerivedX>& X,
+  const Eigen::Array<bool,Eigen::Dynamic,1> & R,
+  const int dim)
+{
+  Eigen::PlainObjectBase<DerivedX> Y;
+  igl::slice_mask(X,R,dim,Y);
+  return Y;
+}
+
+#ifdef IGL_STATIC_LIBRARY
+template void igl::slice_mask<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Array<bool, -1, 1, 0, -1, 1> const&, int, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+#endif

+ 57 - 0
include/igl/slice_mask.h

@@ -0,0 +1,57 @@
+// 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_SLICE_MASK_H
+#define IGL_SLICE_MASK_H
+#include "igl_inline.h"
+
+#include <Eigen/Sparse>
+namespace igl
+{
+  // Act like the matlab X(row_mask,col_mask) operator, where
+  // row_mask, col_mask are non-negative integer indices.
+  // 
+  // Inputs:
+  //   X  m by n matrix
+  //   R  m list of row bools
+  //   C  n list of column bools
+  // Output:
+  //   Y  #trues-in-R by #trues-in-C matrix
+  //
+  // See also: slice_mask
+  
+  template <typename DerivedX>
+  IGL_INLINE void slice_mask(
+    const Eigen::PlainObjectBase<DerivedX> & X,
+    const Eigen::Array<bool,Eigen::Dynamic,1> & R,
+    const Eigen::Array<bool,Eigen::Dynamic,1> & C,
+    Eigen::PlainObjectBase<DerivedX> & Y);
+  template <typename DerivedX>
+  IGL_INLINE void slice_mask(
+    const Eigen::PlainObjectBase<DerivedX> & X,
+    const Eigen::Array<bool,Eigen::Dynamic,1> & R,
+    const int dim,
+    Eigen::PlainObjectBase<DerivedX> & Y);
+
+  template <typename DerivedX>
+  IGL_INLINE Eigen::PlainObjectBase<DerivedX> slice_mask(
+    const Eigen::PlainObjectBase<DerivedX> & X,
+    const Eigen::Array<bool,Eigen::Dynamic,1> & R,
+    const Eigen::Array<bool,Eigen::Dynamic,1> & C);
+  template <typename DerivedX>
+  IGL_INLINE Eigen::PlainObjectBase<DerivedX> slice_mask(
+    const Eigen::PlainObjectBase<DerivedX> & X,
+    const Eigen::Array<bool,Eigen::Dynamic,1> & R,
+    const int dim);
+}
+
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "slice_mask.cpp"
+#endif
+
+#endif

+ 0 - 2
include/igl/sparse.cpp

@@ -7,10 +7,8 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "sparse.h"
 
-// Bug in unsupported/Eigen/SparseExtra needs iostream first
 #include <iostream>
 #include <vector>
-#include <unsupported/Eigen/SparseExtra>
 
 template <class IndexVector, class ValueVector, typename T>
 IGL_INLINE void igl::sparse(

+ 2 - 2
include/igl/tga.cpp

@@ -60,7 +60,7 @@ typedef struct {
 } RLEstate;
 
 IGL_INLINE static int
-std_fread(RLEstate *rleInfo, unsigned char *buf, size_t datasize, size_t nelems, FILE *fp)
+std_fread(RLEstate * /*rleInfo*/, unsigned char *buf, size_t datasize, size_t nelems, FILE *fp)
 {
   if (_verbose > 1) {
     totbytes += nelems * datasize;
@@ -185,7 +185,7 @@ rle_fread(RLEstate *rleInfo, unsigned char *vbuf, size_t datasize, size_t nelems
 }
 
 IGL_INLINE igl::gliGenericImage *
-igl::gliReadTGA(FILE *fp, char *name, int hflip, int vflip)
+igl::gliReadTGA(FILE *fp, char *name, int /*hflip*/, int vflip)
 {
   igl::TgaHeader tgaHeader;
   igl::TgaFooter tgaFooter;

+ 51 - 30
include/igl/triangle_triangle_adjacency.cpp

@@ -14,9 +14,18 @@
 #include <iostream>
 
 template <typename Scalar, typename Index>
-IGL_INLINE void igl::triangle_triangle_adjacency_preprocess(const Eigen::PlainObjectBase<Scalar>& /*V*/,
-                                   const Eigen::PlainObjectBase<Index>& F,
-                                   std::vector<std::vector<int> >& TTT)
+IGL_INLINE void igl::triangle_triangle_adjacency_preprocess(
+    const Eigen::PlainObjectBase<Scalar>& /*V*/,
+    const Eigen::PlainObjectBase<Index>& F,
+    std::vector<std::vector<int> >& TTT)
+{
+  return triangle_triangle_adjacency_preprocess(F,TTT);
+}
+
+template <typename Index>
+IGL_INLINE void igl::triangle_triangle_adjacency_preprocess(
+    const Eigen::PlainObjectBase<Index>& F,
+    std::vector<std::vector<int> >& TTT)
 {
   for(int f=0;f<F.rows();++f)
     for (int i=0;i<F.cols();++i)
@@ -34,12 +43,13 @@ IGL_INLINE void igl::triangle_triangle_adjacency_preprocess(const Eigen::PlainOb
 }
 
 // Extract the face adjacencies
-template <typename Index>
-IGL_INLINE void igl::triangle_triangle_adjacency_extractTT(const Eigen::PlainObjectBase<Index>& F,
-                                  std::vector<std::vector<int> >& TTT,
-                                  Eigen::PlainObjectBase<Index>& TT)
+template <typename DerivedF, typename DerivedTT>
+IGL_INLINE void igl::triangle_triangle_adjacency_extractTT(
+  const Eigen::PlainObjectBase<DerivedF>& F,
+  std::vector<std::vector<int> >& TTT,
+  Eigen::PlainObjectBase<DerivedTT>& TT)
 {
-  TT = Eigen::PlainObjectBase<Index>::Constant((int)(F.rows()),F.cols(),-1);
+  TT.setConstant((int)(F.rows()),F.cols(),-1);
 
   for(int i=1;i<(int)TTT.size();++i)
   {
@@ -54,12 +64,13 @@ IGL_INLINE void igl::triangle_triangle_adjacency_extractTT(const Eigen::PlainObj
 }
 
 // Extract the face adjacencies indices (needed for fast traversal)
-template <typename Index>
-IGL_INLINE void igl::triangle_triangle_adjacency_extractTTi(const Eigen::PlainObjectBase<Index>& F,
-                                   std::vector<std::vector<int> >& TTT,
-                                   Eigen::PlainObjectBase<Index>& TTi)
+template <typename DerivedF, typename DerivedTTi>
+IGL_INLINE void igl::triangle_triangle_adjacency_extractTTi(
+  const Eigen::PlainObjectBase<DerivedF>& F,
+  std::vector<std::vector<int> >& TTT,
+  Eigen::PlainObjectBase<DerivedTTi>& TTi)
 {
-  TTi = Eigen::PlainObjectBase<Index>::Constant((int)(F.rows()),F.cols(),-1);
+  TTi.setConstant((int)(F.rows()),F.cols(),-1);
 
   for(int i=1;i<(int)TTT.size();++i)
   {
@@ -88,15 +99,29 @@ IGL_INLINE void igl::triangle_triangle_adjacency(const Eigen::PlainObjectBase<Sc
 
 // Compute triangle-triangle adjacency with indices
 template <typename Scalar, typename Index>
-IGL_INLINE void igl::triangle_triangle_adjacency(const Eigen::PlainObjectBase<Scalar>& V,
-                        const Eigen::PlainObjectBase<Index>& F,
-                        Eigen::PlainObjectBase<Index>& TT,
-                        Eigen::PlainObjectBase<Index>& TTi)
+IGL_INLINE void igl::triangle_triangle_adjacency(
+  const Eigen::PlainObjectBase<Scalar>& /*V*/,
+  const Eigen::PlainObjectBase<Index>& F,
+  Eigen::PlainObjectBase<Index>& TT,
+  Eigen::PlainObjectBase<Index>& TTi)
 {
   //assert(igl::is_edge_manifold(V,F));
   std::vector<std::vector<int> > TTT;
+  triangle_triangle_adjacency_preprocess(F,TTT);
+  triangle_triangle_adjacency_extractTT(F,TTT,TT);
+  triangle_triangle_adjacency_extractTTi(F,TTT,TTi);
+}
 
-  triangle_triangle_adjacency_preprocess(V,F,TTT);
+// Compute triangle-triangle adjacency with indices
+template <typename DerivedF, typename DerivedTT, typename DerivedTTi>
+IGL_INLINE void igl::triangle_triangle_adjacency(
+  const Eigen::PlainObjectBase<DerivedF>& F,
+  Eigen::PlainObjectBase<DerivedTT>& TT,
+  Eigen::PlainObjectBase<DerivedTTi>& TTi)
+{
+  //assert(igl::is_edge_manifold(V,F));
+  std::vector<std::vector<int> > TTT;
+  triangle_triangle_adjacency_preprocess(F,TTT);
   triangle_triangle_adjacency_extractTT(F,TTT,TT);
   triangle_triangle_adjacency_extractTTi(F,TTT,TTi);
 }
@@ -193,11 +218,15 @@ template <
       for(const auto & ne : N)
       {
         const Index nf = ne%m;
-        TT[f][c].push_back(nf);
-        if(construct_TTi)
+        // don't add self
+        if(nf != f)
         {
-          const Index nc = ne/m;
-          TTi[f][c].push_back(nc);
+          TT[f][c].push_back(nf);
+          if(construct_TTi)
+          {
+            const Index nc = ne/m;
+            TTi[f][c].push_back(nc);
+          }
         }
       }
     }
@@ -206,12 +235,4 @@ template <
 
 #ifdef IGL_STATIC_LIBRARY
 // 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<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<int, -1, 3, 0, -1, 3> >&);
-template void igl::triangle_triangle_adjacency<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<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
-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> > > > > >&);
-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> >&);
-template void igl::triangle_triangle_adjacency<Eigen::Matrix<double, -1, -1, 0, -1, -1>, long, long>(Eigen::PlainObjectBase<Eigen::Matrix<double, -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> > > > > >&);
-template void igl::triangle_triangle_adjacency<Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > >&, std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > >&);
 #endif

+ 33 - 18
include/igl/triangle_triangle_adjacency.h

@@ -32,32 +32,47 @@ namespace igl
   // Known bug: this should not need to take V as input.
 
   template <typename Scalar, typename Index>
-  IGL_INLINE void triangle_triangle_adjacency(const Eigen::PlainObjectBase<Scalar>& V,
-                     const Eigen::PlainObjectBase<Index>& F,
-                     Eigen::PlainObjectBase<Index>& TT);
+  IGL_INLINE void triangle_triangle_adjacency(
+    const Eigen::PlainObjectBase<Scalar>& V,
+    const Eigen::PlainObjectBase<Index>& F,
+    Eigen::PlainObjectBase<Index>& TT);
   // Compute triangle-triangle adjacency with indices
   template <typename Scalar, typename Index>
-  IGL_INLINE void triangle_triangle_adjacency(const Eigen::PlainObjectBase<Scalar>& V,
-                     const Eigen::PlainObjectBase<Index>& F,
-                     Eigen::PlainObjectBase<Index>& TT,
-                     Eigen::PlainObjectBase<Index>& TTi);
+  IGL_INLINE void triangle_triangle_adjacency(
+    const Eigen::PlainObjectBase<Scalar>& V,
+    const Eigen::PlainObjectBase<Index>& F,
+    Eigen::PlainObjectBase<Index>& TT,
+    Eigen::PlainObjectBase<Index>& TTi);
+
+  template <typename DerivedF, typename DerivedTT, typename DerivedTTi>
+  IGL_INLINE void triangle_triangle_adjacency(
+    const Eigen::PlainObjectBase<DerivedF>& F,
+    Eigen::PlainObjectBase<DerivedTT>& TT,
+    Eigen::PlainObjectBase<DerivedTTi>& TTi);
 
 
   // Preprocessing
   template <typename Scalar, typename Index>
-  IGL_INLINE void triangle_triangle_adjacency_preprocess(const Eigen::PlainObjectBase<Scalar>& V,
-                                const Eigen::PlainObjectBase<Index>& F,
-                                std::vector<std::vector<int> >& TTT);
+  IGL_INLINE void triangle_triangle_adjacency_preprocess(
+    const Eigen::PlainObjectBase<Scalar>& V,
+    const Eigen::PlainObjectBase<Index>& F,
+    std::vector<std::vector<int> >& TTT);
+  template <typename DerivedF>
+  IGL_INLINE void triangle_triangle_adjacency_preprocess(
+    const Eigen::PlainObjectBase<DerivedF>& F,
+    std::vector<std::vector<int> >& TTT);
   // Extract the face adjacencies
-  template <typename Index>
-  IGL_INLINE void triangle_triangle_adjacency_extractTT(const Eigen::PlainObjectBase<Index>& F,
-                               std::vector<std::vector<int> >& TTT,
-                               Eigen::PlainObjectBase<Index>& TT);
+  template <typename DerivedF, typename DerivedTT>
+  IGL_INLINE void triangle_triangle_adjacency_extractTT(
+    const Eigen::PlainObjectBase<DerivedF>& F,
+    std::vector<std::vector<int> >& TTT,
+    Eigen::PlainObjectBase<DerivedTT>& TT);
   // Extract the face adjacencies indices (needed for fast traversal)
-  template <typename Index>
-  IGL_INLINE void triangle_triangle_adjacency_extractTTi(const Eigen::PlainObjectBase<Index>& F,
-                                std::vector<std::vector<int> >& TTT,
-                                Eigen::PlainObjectBase<Index>& TTi);
+  template <typename DerivedF, typename DerivedTTi>
+  IGL_INLINE void triangle_triangle_adjacency_extractTTi(
+    const Eigen::PlainObjectBase<DerivedF>& F,
+    std::vector<std::vector<int> >& TTT,
+    Eigen::PlainObjectBase<DerivedTTi>& TTi);
   // Adjacency list version, which works with non-manifold meshes
   //
   // Inputs:

+ 4 - 3
include/igl/upsample.cpp

@@ -9,7 +9,6 @@
 
 #include "triangle_triangle_adjacency.h"
 
-#include <Eigen/Dense>
 
 template <
   typename DerivedV,
@@ -28,8 +27,10 @@ IGL_INLINE void igl::upsample(
   using namespace std;
   using namespace Eigen;
 
-  Eigen::MatrixXi FF,FFi;
-  triangle_triangle_adjacency(V,F,FF,FFi);
+  Eigen::Matrix<
+    typename DerivedF::Scalar,Eigen::Dynamic,Eigen::Dynamic>
+    FF,FFi;
+  triangle_triangle_adjacency(F,FF,FFi);
 
   // TODO: Cache optimization missing from here, it is a mess
 

+ 3 - 0
include/igl/upsample.h

@@ -30,6 +30,9 @@ namespace igl
   //
   // NOTE: V should not be the same as NV,
   // NOTE: F should not be the same as NF, use other proto
+  //
+  // Known issues:
+  //   - assumes (V,F) is edge-manifold.
   template <
     typename DerivedV, 
     typename DerivedF,

+ 1 - 1
include/igl/viewer/OpenGL_shader.cpp

@@ -33,7 +33,7 @@ IGL_INLINE bool igl::OpenGL_shader::init_from_files(
   const std::string &geometry_shader_filename,
   int geometry_shader_max_vertices)
 {
-  auto file_to_string = [](const std::string &filename)
+  auto file_to_string = [](const std::string &filename)->std::string
   {
     std::ifstream t(filename);
     return std::string((std::istreambuf_iterator<char>(t)),

+ 1 - 1
tutorial/tutorial.md.REMOVED.git-id

@@ -1 +1 @@
-bc88dcbd6ca6506b1df471d68a7c8d353432a105
+4c8471892755633646d65f3b104fa8a5de3660e4