浏览代码

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

Conflicts:
	build/Makefile_embree
	include/igl/frustum.cpp
	include/igl/is_border_vertex.cpp
	include/igl/look_at.cpp
	include/igl/ortho.cpp
	include/igl/serialize.cpp

Former-commit-id: 218c9b98add9fcdb3ba6aad9cd57bd4587f4f97c
Olga Diamanti 10 年之前
父节点
当前提交
1d8c478f2a
共有 77 个文件被更改,包括 1269 次插入1740 次删除
  1. 22 0
      README.md
  2. 1 2
      build/Makefile_embree
  3. 0 10
      examples/ambient-occlusion-mex/README
  4. 0 22
      examples/ambient-occlusion-mex/ambient_occlusion.m
  5. 0 9
      examples/ambient-occlusion-mex/compile.m
  6. 0 32
      examples/ambient-occlusion-mex/example.m
  7. 0 51
      examples/ambient-occlusion-mex/mexFunction.cpp
  8. 0 59
      examples/ambient-occlusion-mex/parse_rhs.cpp
  9. 0 27
      examples/ambient-occlusion-mex/parse_rhs.h
  10. 1 4
      examples/ambient-occlusion/Makefile
  11. 1 5
      examples/arap/Makefile
  12. 1 1
      examples/basic_topology/Makefile
  13. 1 4
      examples/colored-mesh/Makefile
  14. 1 1
      examples/embree/Makefile
  15. 1 4
      examples/flare-eyes/Makefile
  16. 0 9
      examples/flare-eyes/example.cpp
  17. 1 4
      examples/intersections/Makefile
  18. 1 1
      examples/multi-viewport/Makefile
  19. 1 1
      examples/patches/Makefile
  20. 1 1
      examples/quicklook-mesh/README
  21. 1 1
      examples/randomly-sample-mesh/Makefile
  22. 1 1
      examples/rotate-widget/Makefile
  23. 1 1
      examples/scene-rotation/Makefile
  24. 1 1
      examples/skeleton-builder/Makefile
  25. 1 1
      examples/skeleton-posing/Makefile
  26. 0 1
      examples/skeleton/example.cpp
  27. 0 7
      examples/textured-mesh/Makefile
  28. 1 1
      examples/transparency/Makefile
  29. 2 2
      google-soc/index.html
  30. 2 0
      include/igl/angles.cpp
  31. 13 6
      include/igl/boundary_loop.cpp
  32. 1 0
      include/igl/cgal/complex_to_mesh.cpp
  33. 1 0
      include/igl/cgal/mesh_to_cgal_triangle_list.cpp
  34. 9 0
      include/igl/cgal/mesh_to_polyhedron.cpp
  35. 1 0
      include/igl/cgal/point_mesh_squared_distance.cpp
  36. 7 0
      include/igl/cgal/polyhedron_to_mesh.cpp
  37. 2 0
      include/igl/cgal/signed_distance.cpp
  38. 2 38
      include/igl/colon.cpp
  39. 1 1
      include/igl/embree/unproject_in_mesh.cpp
  40. 2 0
      include/igl/frustum.cpp
  41. 1 0
      include/igl/grad.cpp
  42. 1 1
      include/igl/is_border_vertex.cpp
  43. 1 0
      include/igl/is_irregular_vertex.cpp
  44. 4 0
      include/igl/list_to_matrix.cpp
  45. 2 0
      include/igl/look_at.cpp
  46. 2 0
      include/igl/matlab/prepare_lhs.cpp
  47. 21 0
      include/igl/null.cpp
  48. 36 0
      include/igl/null.h
  49. 2 0
      include/igl/ortho.cpp
  50. 1 0
      include/igl/outer_facet.cpp
  51. 28 5
      include/igl/outer_hull.cpp
  52. 1 0
      include/igl/parula.h
  53. 1 0
      include/igl/per_edge_normals.cpp
  54. 1 0
      include/igl/png/texture_from_png.h
  55. 3 4
      include/igl/project.cpp
  56. 15 2
      include/igl/readDMAT.cpp
  57. 2 1
      include/igl/readOBJ.cpp
  58. 0 796
      include/igl/serialize.cpp
  59. 844 72
      include/igl/serialize.h
  60. 109 1
      include/igl/slice.cpp
  61. 23 0
      include/igl/slice.h
  62. 1 0
      include/igl/slice_tets.cpp
  63. 2 0
      include/igl/sort.cpp
  64. 1 0
      include/igl/unique_simplices.cpp
  65. 1 0
      include/igl/winding_number.cpp
  66. 12 3
      include/igl/winding_number.h
  67. 0 259
      include/igl/xml/old_version/ReAntTweakBarXMLSerialization.h
  68. 0 49
      include/igl/xml/old_version/XMLSerializable.h
  69. 0 178
      include/igl/xml/old_version/XMLSerialization.h
  70. 0 49
      include/igl/xml/old_version/XMLSerializationTest.h
  71. 0 1
      include/igl/xml/old_version/XMLSerializer.h.REMOVED.git-id
  72. 7 0
      include/igl/xml/serialize_xml.cpp
  73. 23 2
      index.html
  74. 24 8
      matlab-to-eigen.html
  75. 9 0
      tutorial/609_Boolean/CMakeLists.txt
  76. 1 1
      tutorial/CMakeLists.shared
  77. 8 0
      tutorial/cmake/FindLIBIGL.cmake

+ 22 - 0
README.md

@@ -95,6 +95,28 @@ caution.
 You can keep up to date by cloning a read-only copy of our GitHub
 [repository](https://github.com/libigl).
 
+## Known Issues
+We really heavily on Eigen. Nearly all inputs and outputs are Eigen matrices of
+some kind. However, we currently _only_ support Eigen's default column-major
+ordering. That means, we **do not** expect our code to work for matrices using
+the `Eigen::RowMajor` flag. If you can, change definitions like:
+
+```cpp
+Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::RowMajor> A;
+```
+
+to
+
+```cpp
+Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::ColMajor> A;
+// or simply
+Eigen::Matrix<double, Eigen::Dynamic, 3> A;
+```
+
+We hope to fix this, or at least identify which functions are safe (many of
+them probably work just fine). This requires setting up unit testing, which is
+a major _todo_ for our development.
+
 ## How to contribute
 
 If you are interested in joining development, please fork the repository and

+ 1 - 2
build/Makefile_embree

@@ -28,8 +28,7 @@ INC+=$(EIGEN3_INC)
 #EMBREE=../external/embree
 #EMBREE_INC=-I$(EMBREE)/common -I$(EMBREE)/rtcore/
 EMBREE=../external/embree/
-#EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
-EMBREE_INC=-I$(EMBREE)/include
+EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
 #EMBREE_LIB=-L$(EMBREE)/bin -lrtcore -lsys
 INC+=$(EMBREE_INC)
 

+ 0 - 10
examples/ambient-occlusion-mex/README

@@ -1,10 +0,0 @@
-Small example showing how to build a mex function to call the
-igl/embree/ambient_occlusion function from matlab.
-
-To compile open matlab, `cd` to this directory and issue:
-
-    compile
-
-To run the example, add the IGL_TOOLBOX to your path and issue:
-
-    example

+ 0 - 22
examples/ambient-occlusion-mex/ambient_occlusion.m

@@ -1,22 +0,0 @@
-  % AMBIENT_OCCLUSION Compute ambient occlusion per given point
-  %
-  % S = ambient_occlusion(V,F,P,N,num_samples)
-  %
-  % Inputs:
-  %    V  #V by 3 list of mesh vertex positions
-  %    F  #F by 3 list of mesh triangle facet indices into V
-  %    P  #P by 3 list of origin points
-  %    N  #P by 3 list of origin normals
-  %    num_samples  number of samples
-  % Outputs:
-  %    S  #P list of ambient occlusion values between 1 (fully occluded) and 0
-  %      (not occluded)
-  %
-  % Examples:
-  %   % mesh (V,F), scalar field Z
-  %   AO = ambient_occlusion(V,F,V,per_vertex_normals(V,F),1000);
-  %   tsurf(F,V,'FaceVertexCData', ...
-  %     bsxfun(@times,1-AO, ...
-  %       squeeze(ind2rgb(floor(matrixnormalize(Z)*256),jet(256)))), ...
-  %     fphong,'EdgeColor','none');
-  %

+ 0 - 9
examples/ambient-occlusion-mex/compile.m

@@ -1,9 +0,0 @@
-mex -v -o ambient_occlusion -DMEX -largeArrayDims ...
-  -I/opt/local/include/eigen3 -I/usr/local/igl/libigl/include ...
-  -L/usr/local/igl/libigl/lib -ligl -liglmatlab -liglembree ...
-  CXXFLAGS="\$CXXFLAGS -m64 -msse4.2 -fopenmp" ...
-  -I/usr/local/igl/libigl/external/embree/embree/ ...
-  -I/usr/local/igl/libigl/external/embree/ ...
-  -L/usr/local/igl/libigl/external/embree/build -lembree -lsys ... 
-  mexFunction.cpp parse_rhs.cpp;
-

+ 0 - 32
examples/ambient-occlusion-mex/example.m

@@ -1,32 +0,0 @@
-[V,F] = load_mesh('../shared/cheburashka.off');
-N = per_vertex_normals(V,F);
-S = ambient_occlusion(V,F,V,N,1000);
-L = cotmatrix(V,F);
-M = massmatrix(V,F,'voronoi');
-[EV,~] = eigs(-L,M,15,'sm');
-Z = EV(:,7);
-qZ = round(255*(Z - min(Z))/(max(Z)-min(Z)));
-C = ind2rgb(qZ,jet(256));
-%Z = connected_components(F);
-%C = ind2rgb(Z(:),jet(max(Z)));
-
-nsp = 3;
-fs = 20;
-subplot(nsp,1,1);
-set(tsurf(F,V),'CData',Z,'EdgeColor','none',fphong);
-title('Pseudo-color  ','FontSize',fs);
-axis equal;
-view(2);
-colormap(jet(256));
-
-subplot(nsp,1,2);
-set(tsurf(F,V),'CData',permute(1-[S S S],[1 3 2]),'EdgeColor','none',fphong);
-title('Inverted ambient occlusion  ','FontSize',fs);
-axis equal;
-view(2);
-
-subplot(nsp,1,3);
-set(tsurf(F,V),'CData',bsxfun(@times,1-S,C),'EdgeColor','none',fphong);
-title('Product  ','FontSize',fs);
-axis equal;
-view(2);

+ 0 - 51
examples/ambient-occlusion-mex/mexFunction.cpp

@@ -1,51 +0,0 @@
-#include "parse_rhs.h"
-
-#include <igl/matlab/MexStream.h>
-#include <igl/embree/ambient_occlusion.h>
-
-#include <igl/read_triangle_mesh.h>
-#include <igl/per_vertex_normals.h>
-
-#include <mex.h>
-
-#include <iostream>
-#include <string>
-
-void mexFunction(int nlhs, mxArray *plhs[],
-    int nrhs, const mxArray *prhs[])
-{
-  // This is useful for debugging whether Matlab is caching the mex binary
-  //mexPrintf("%s %s\n",__TIME__,__DATE__);
-  igl::MexStream mout;
-  std::streambuf *outbuf = std::cout.rdbuf(&mout);
-
-  using namespace std;
-  using namespace Eigen;
-  using namespace igl;
-
-  MatrixXd V,P,N;
-  VectorXd S;
-  MatrixXi F;
-  int num_samples;
-  parse_rhs(nrhs,prhs,V,F,P,N,num_samples);
-  // Prepare left-hand side
-  nlhs = 1;
-
-  //read_triangle_mesh("../shared/cheburashka.off",V,F);
-  //P = V;
-  //per_vertex_normals(V,F,N);
-  ambient_occlusion(V,F,P,N,num_samples,S);
-  //MatlabWorkspace mw;
-  //mw.save(V,"V");
-  //mw.save(P,"P");
-  //mw.save(N,"N");
-  //mw.save_index(F,"F");
-  //mw.save(S,"S");
-  //mw.write("out.mat");
-
-  plhs[0] = mxCreateDoubleMatrix(S.rows(),S.cols(), mxREAL);
-  copy(S.data(),S.data()+S.size(),mxGetPr(plhs[0]));
-
-  // Restore the std stream buffer Important!
-  std::cout.rdbuf(outbuf);
-}

+ 0 - 59
examples/ambient-occlusion-mex/parse_rhs.cpp

@@ -1,59 +0,0 @@
-#ifdef MEX
-#include "parse_rhs.h"
-#include <algorithm>
-#include <functional>
-
-void parse_rhs(
-  const int nrhs, 
-  const mxArray *prhs[], 
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F,
-  Eigen::MatrixXd & P,
-  Eigen::MatrixXd & N,
-  int & num_samples)
-{
-  using namespace std;
-  if(nrhs < 5)
-  {
-    mexErrMsgTxt("nrhs < 5");
-  }
-
-  const int dim = mxGetN(prhs[0]);
-  if(dim != 3)
-  {
-    mexErrMsgTxt("Mesh vertex list must be #V by 3 list of vertex positions");
-  }
-  if(dim != (int)mxGetN(prhs[1]))
-  {
-   mexErrMsgTxt("Mesh facet size must be 3");
-  }
-  if(mxGetN(prhs[2]) != dim)
-  {
-    mexErrMsgTxt("Point list must be #P by 3 list of origin locations");
-  }
-  if(mxGetN(prhs[3]) != dim)
-  {
-    mexErrMsgTxt("Normal list must be #P by 3 list of origin normals");
-  }
-  if(mxGetN(prhs[4]) != 1 || mxGetM(prhs[4]) != 1)
-  {
-    mexErrMsgTxt("Number of samples must be scalar.");
-  }
-
-
-  V.resize(mxGetM(prhs[0]),mxGetN(prhs[0]));
-  copy(mxGetPr(prhs[0]),mxGetPr(prhs[0])+V.size(),V.data());
-  F.resize(mxGetM(prhs[1]),mxGetN(prhs[1]));
-  copy(mxGetPr(prhs[1]),mxGetPr(prhs[1])+F.size(),F.data());
-  F.array() -= 1;
-  P.resize(mxGetM(prhs[2]),mxGetN(prhs[2]));
-  copy(mxGetPr(prhs[2]),mxGetPr(prhs[2])+P.size(),P.data());
-  N.resize(mxGetM(prhs[3]),mxGetN(prhs[3]));
-  copy(mxGetPr(prhs[3]),mxGetPr(prhs[3])+N.size(),N.data());
-  if(*mxGetPr(prhs[4]) != (int)*mxGetPr(prhs[4]))
-  {
-    mexErrMsgTxt("Number of samples should be non negative integer.");
-  }
-  num_samples = (int) *mxGetPr(prhs[4]);
-}
-#endif

+ 0 - 27
examples/ambient-occlusion-mex/parse_rhs.h

@@ -1,27 +0,0 @@
-#ifndef PARSE_RHS_H
-#define PARSE_RHS_H
-
-#include <mex.h>
-#include <Eigen/Core>
-// Parse right hand side arguments for a matlab mex function.
-//
-// Inputs:
-//   nrhs  number of right hand side arguments
-//   prhs  pointer to right hand side arguments
-// Outputs:
-//   V  n by dim list of mesh vertex positions
-//   F  m by dim list of mesh face indices
-//   P  #P by 3 list of origin points
-//   N  #P by 3 list of origin normals
-//   num_samples  number of samples
-// Throws matlab errors if dimensions are not sane.
-void parse_rhs(
-  const int nrhs, 
-  const mxArray *prhs[], 
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F,
-  Eigen::MatrixXd & P,
-  Eigen::MatrixXd & N,
-  int & num_samples);
-
-#endif 

+ 1 - 4
examples/ambient-occlusion/Makefile

@@ -14,11 +14,8 @@ LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 
-#EMBREE=$(LIBIGL)/external/embree
-#EMBREE_INC=-I$(EMBREE)/rtcore -I$(EMBREE)/common
-#EMBREE_LIB=-L$(EMBREE)/build -lrtcore -lsys
 EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
+EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
 EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
 
 ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include

+ 1 - 5
examples/arap/Makefile

@@ -15,12 +15,8 @@ LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglpng -liglsvd3x3
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 #CFLAGS+=-DIGL_HEADER_ONLY
 
-
-#EMBREE=$(LIBIGL)/external/embree
-#EMBREE_INC=-I$(EMBREE)/rtcore -I$(EMBREE)/common
-#EMBREE_LIB=-L$(EMBREE)/build -lrtcore -lsys
 EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
+EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
 EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
 
 # YIMAGE Library

+ 1 - 1
examples/basic_topology/Makefile

@@ -7,7 +7,7 @@ include ../../build/Makefile.conf
 igl_lib=../../
 eigen_lib=$(DEFAULT_PREFIX)/include/eigen3/
 
-CFLAGS+=-g
+CFLAGS+=-g -fopenmp
 inc=-I$(igl_lib)/include -I$(eigen_lib)
 lib=-L$(igl_lib)/lib -ligl
 

+ 1 - 4
examples/colored-mesh/Makefile

@@ -14,11 +14,8 @@ LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 
-#EMBREE=$(LIBIGL)/external/embree
-#EMBREE_INC=-I$(EMBREE)/rtcore -I$(EMBREE)/common
-#EMBREE_LIB=-L$(EMBREE)/build -lrtcore -lsys
 EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
+EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
 EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
 
 ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include

+ 1 - 1
examples/embree/Makefile

@@ -17,7 +17,7 @@ LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 
 EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
+EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
 EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
 
 ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include

+ 1 - 4
examples/flare-eyes/Makefile

@@ -10,16 +10,13 @@ all: obj example
 
 LIBIGL=../../
 LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab -liglembree
+LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 
 ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
 ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
 
-MATLAB_INC=-I$(MATLAB)/extern/include/
-MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat -lmex -lstdc++
-
 CARBON_LIB=-framework Carbon
 
 ## Use free glut for mouse scrolling

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

@@ -31,7 +31,6 @@
 
 #ifdef __APPLE__
 #include <GLUT/glut.h>
-#include <Carbon/Carbon.h>
 #else
 #include <GL/glut.h>
 #endif
@@ -525,14 +524,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()
 {
   using namespace std;

+ 1 - 4
examples/intersections/Makefile

@@ -20,11 +20,8 @@ CGAL_FLAGS=-frounding-math -fsignaling-nans
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 
-#EMBREE=$(LIBIGL)/external/embree
-#EMBREE_INC=-I$(EMBREE)/rtcore -I$(EMBREE)/common
-#EMBREE_LIB=-L$(EMBREE)/build -lrtcore -lsys
 EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
+EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
 EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
 
 ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include

+ 1 - 1
examples/multi-viewport/Makefile

@@ -10,7 +10,7 @@ all: example
 LIBIGL=/usr/local/igl/libigl/
 include $(LIBIGL)/build/Makefile.conf
 LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree
+LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 CFLAGS+=-std=c++11 -g -Wno-deprecated-declarations

+ 1 - 1
examples/patches/Makefile

@@ -20,7 +20,7 @@ ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include
 ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit
 
 EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
+EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
 EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
 
 MATLAB_INC=-I$(MATLAB)/extern/include/

+ 1 - 1
examples/quicklook-mesh/README

@@ -32,7 +32,7 @@ After installing you can test previews with:
 
 and thumbnails with:
 
-    /usr/bin/qlmanage -t ../shared/cheburashka.obj
+    /usr/bin/qlmanage -t ../shared/cheburashka.off
 
 = Note about Mesa =
 

+ 1 - 1
examples/randomly-sample-mesh/Makefile

@@ -10,7 +10,7 @@ all: obj example
 
 LIBIGL=../../
 LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab -liglembree
+LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 

+ 1 - 1
examples/rotate-widget/Makefile

@@ -10,7 +10,7 @@ all: obj example
 
 LIBIGL=../../
 LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab -liglembree
+LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 

+ 1 - 1
examples/scene-rotation/Makefile

@@ -10,7 +10,7 @@ all: obj example
 
 LIBIGL=../../
 LIBIGL_INC=-I$(LIBIGL)/include -DIGL_HEADER_ONLY
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab -liglembree
+LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab 
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 

+ 1 - 1
examples/skeleton-builder/Makefile

@@ -22,7 +22,7 @@ TETGEN_LIB=-L$(TETGEN) -ltet
 TETGEN_INC=-I$(TETGEN)
 
 EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
+EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/include
 EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
 
 CARBON_LIB=-framework Carbon

+ 1 - 1
examples/skeleton-posing/Makefile

@@ -10,7 +10,7 @@ all: obj example
 
 LIBIGL=../../
 LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree -liglcgal -ligltetgen -liglbbw -liglmosek
+LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglcgal -ligltetgen -liglbbw -liglmosek
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 

+ 0 - 1
examples/skeleton/example.cpp

@@ -36,7 +36,6 @@
 
 #ifdef __APPLE__
 #include <GLUT/glut.h>
-#include <Carbon/Carbon.h>
 #else
 #include <GL/glut.h>
 #endif

+ 0 - 7
examples/textured-mesh/Makefile

@@ -14,13 +14,6 @@ LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglpng
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 
-#EMBREE=$(LIBIGL)/external/embree
-#EMBREE_INC=-I$(EMBREE)/rtcore -I$(EMBREE)/common
-#EMBREE_LIB=-L$(EMBREE)/build -lrtcore -lsys
-EMBREE=$(LIBIGL)/external/embree
-EMBREE_INC=-I$(EMBREE)/ -I$(EMBREE)/embree
-EMBREE_LIB=-L$(EMBREE)/build -lembree -lsys
-
 # YIMAGE Library
 YIMG=$(LIBIGL)/external/yimg/
 YIMG_LIB=-L$(YIMG) -lyimg -lz -L/opt/local/lib -lpng -bind_at_load

+ 1 - 1
examples/transparency/Makefile

@@ -10,7 +10,7 @@ all: example
 
 LIBIGL=../../
 LIBIGL_INC=-I$(LIBIGL)/include
-LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab -liglembree
+LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglmatlab
 
 EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
 CFLAGS+=-O3 -fopenmp

+ 2 - 2
google-soc/index.html

@@ -18,7 +18,7 @@
 
 <figure>
 <img src="./libigl-logo-python-matlab.jpg" alt="" />
-</figure>
+<figcaption></figcaption></figure>
 
 <p>Libigl is a C++ library, but its functional interface make it very friendly to
 wrapping individual functions for popular scripting languages like Python or
@@ -39,7 +39,7 @@ variety of functions in the library.</p>
 
 <figure>
 <img src="./collapse-split-flip.jpg" alt="" />
-</figure>
+<figcaption></figcaption></figure>
 
 <p>Libigl avoids complicated mesh data-structures to ensure that its interface is
 clean and easy to port into users&#8217; existing projects. Our mesh format is a

+ 2 - 0
include/igl/angles.cpp

@@ -6,6 +6,7 @@
 // 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/.
 #include "angles.h"
+#include <Eigen/Geometry>
 #include <cassert>
 
 template <
@@ -46,4 +47,5 @@ void igl::angles(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
+template void igl::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> >&);
 #endif

+ 13 - 6
include/igl/boundary_loop.cpp

@@ -32,7 +32,7 @@ IGL_INLINE void igl::boundary_loop(
 
   vector<bool> unvisited = is_border_vertex(Vdummy,F);
   set<int> unseen;
-  for (int i = 0; i < unvisited.size(); ++i)
+  for (size_t i = 0; i < unvisited.size(); ++i)
   {
     if (unvisited[i])
       unseen.insert(unseen.end(),i);
@@ -61,7 +61,7 @@ IGL_INLINE void igl::boundary_loop(
 
         if (TT.row(fid).minCoeff() < 0.) // Face contains boundary edge
         {
-          int vLoc;
+          int vLoc = -1;
           if (F(fid,0) == v) vLoc = 0;
           if (F(fid,1) == v) vLoc = 1;
           if (F(fid,2) == v) vLoc = 2;
@@ -105,8 +105,8 @@ IGL_INLINE void igl::boundary_loop(
   boundary_loop(F,Lall);
 
   int idxMax = -1;
-  int maxLen = 0;
-  for (int i = 0; i < Lall.size(); ++i)
+  size_t maxLen = 0;
+  for (size_t i = 0; i < Lall.size(); ++i)
   {
     if (Lall[i].size() > maxLen)
     {
@@ -116,8 +116,10 @@ IGL_INLINE void igl::boundary_loop(
   }
 
   L.resize(Lall[idxMax].size());
-  for (int i = 0; i < Lall[idxMax].size(); ++i)
+  for (size_t i = 0; i < Lall[idxMax].size(); ++i)
+  {
     L[i] = Lall[idxMax][i];
+  }
 }
 
 template <typename DerivedF, typename DerivedL>
@@ -135,6 +137,11 @@ IGL_INLINE void igl::boundary_loop(
   boundary_loop(F,Lvec);
 
   L.resize(Lvec.size());
-  for (int i = 0; i < Lvec.size(); ++i)
+  for (size_t i = 0; i < Lvec.size(); ++i)
     L(i) = Lvec[i];
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+template void igl::boundary_loop<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> >&);
+#endif

+ 1 - 0
include/igl/cgal/complex_to_mesh.cpp

@@ -148,4 +148,5 @@ IGL_INLINE bool igl::complex_to_mesh(
 
 #ifdef IGL_STATIC_LIBRARY
 template bool igl::complex_to_mesh<CGAL::Delaunay_triangulation_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_data_structure_3<CGAL::Surface_mesh_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_vertex_base_3<void> > >, CGAL::Triangulation_cell_base_with_circumcenter_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Surface_mesh_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_cell_base_3<void> > > > >, CGAL::Default>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Complex_2_in_triangulation_3<CGAL::Delaunay_triangulation_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_data_structure_3<CGAL::Surface_mesh_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_vertex_base_3<void> > >, CGAL::Triangulation_cell_base_with_circumcenter_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Surface_mesh_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_cell_base_3<void> > > > >, CGAL::Default>, void> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template bool igl::complex_to_mesh<CGAL::Delaunay_triangulation_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_data_structure_3<CGAL::Surface_mesh_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_vertex_base_3<void> > >, CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Surface_mesh_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_cell_base_3<void> > > >, CGAL::Sequential_tag>, CGAL::Default, CGAL::Default>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Complex_2_in_triangulation_3<CGAL::Delaunay_triangulation_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_data_structure_3<CGAL::Surface_mesh_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_vertex_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_vertex_base_3<void> > >, CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Surface_mesh_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_cell_base_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, CGAL::Triangulation_ds_cell_base_3<void> > > >, CGAL::Sequential_tag>, CGAL::Default, CGAL::Default>, void> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 1 - 0
include/igl/cgal/mesh_to_cgal_triangle_list.cpp

@@ -37,4 +37,5 @@ IGL_INLINE void igl::mesh_to_cgal_triangle_list(
 // Explicit template specialization
 template void igl::mesh_to_cgal_triangle_list<CGAL::Epeck>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
 template void igl::mesh_to_cgal_triangle_list<CGAL::Epick>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
+template void igl::mesh_to_cgal_triangle_list<CGAL::Simple_cartesian<double> >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
 #endif

+ 9 - 0
include/igl/cgal/mesh_to_polyhedron.cpp

@@ -8,6 +8,8 @@
 #include "mesh_to_polyhedron.h"
 #include <CGAL/Polyhedron_3.h>
 #include <CGAL/Polyhedron_incremental_builder_3.h>
+
+
 template <typename Polyhedron>
 IGL_INLINE bool igl::mesh_to_polyhedron(
   const Eigen::MatrixXd & V,
@@ -43,3 +45,10 @@ IGL_INLINE bool igl::mesh_to_polyhedron(
   B.end_surface();
   return poly.is_valid();
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instanciation
+#include <CGAL/Simple_cartesian.h>
+#include <CGAL/Polyhedron_items_with_id_3.h>
+template bool igl::mesh_to_polyhedron<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> >&);
+#endif

+ 1 - 0
include/igl/cgal/point_mesh_squared_distance.cpp

@@ -123,4 +123,5 @@ IGL_INLINE void igl::point_mesh_squared_distance(
 template void igl::point_mesh_squared_distance_precompute<CGAL::Epick>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epick, CGAL::AABB_triangle_primitive<CGAL::Epick, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >::iterator, CGAL::Boolean_tag<false> > > >&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
 template void igl::point_mesh_squared_distance<CGAL::Epeck>( const Eigen::MatrixXd & P, const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, Eigen::VectorXd & sqrD, Eigen::VectorXi & I, Eigen::MatrixXd & C);
 template void igl::point_mesh_squared_distance<CGAL::Epick>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1>&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
+template void igl::point_mesh_squared_distance<CGAL::Simple_cartesian<double> >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1>&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
 #endif

+ 7 - 0
include/igl/cgal/polyhedron_to_mesh.cpp

@@ -55,3 +55,10 @@ IGL_INLINE void igl::polyhedron_to_mesh(
     }
   }
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instanciation
+#include <CGAL/Simple_cartesian.h>
+#include <CGAL/Polyhedron_items_with_id_3.h>
+template void igl::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > >(CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&);
+#endif

+ 2 - 0
include/igl/cgal/signed_distance.cpp

@@ -287,4 +287,6 @@ IGL_INLINE void igl::signed_distance_winding_number(
 template void igl::signed_distance<CGAL::Epick>( const Eigen::MatrixXd & , const Eigen::MatrixXd & , const Eigen::MatrixXi & , const SignedDistanceType , Eigen::VectorXd & , Eigen::VectorXi &, Eigen::MatrixXd & , Eigen::MatrixXd & );
 template CGAL::Epick::FT igl::signed_distance_winding_number<CGAL::Epick>(CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epick, CGAL::AABB_triangle_primitive<CGAL::Epick, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >::iterator, CGAL::Boolean_tag<false> > > > const&, igl::WindingNumberAABB<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, CGAL::Epick::Point_3 const&);
 template CGAL::Epick::FT igl::signed_distance_pseudonormal<CGAL::Epick>(CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Epick, CGAL::AABB_triangle_primitive<CGAL::Epick, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >::iterator, CGAL::Boolean_tag<false> > > > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, CGAL::Epick::Point_3 const&);
+template void igl::signed_distance_pseudonormal<CGAL::Simple_cartesian<double> >(CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> > > > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, CGAL::Simple_cartesian<double>::Point_3 const&, CGAL::Simple_cartesian<double>::FT&, CGAL::Simple_cartesian<double>::FT&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> > > >::Point_and_primitive_id&, Eigen::Matrix<double, 3, 1, 0, 3, 1>&);
+template void igl::signed_distance_winding_number<CGAL::Simple_cartesian<double> >(CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> > > > const&, igl::WindingNumberAABB<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, CGAL::Simple_cartesian<double>::Point_3 const&, CGAL::Simple_cartesian<double>::FT&, CGAL::Simple_cartesian<double>::FT&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> > > >::Point_and_primitive_id&);
 #endif

+ 2 - 38
include/igl/colon.cpp

@@ -16,44 +16,8 @@ IGL_INLINE void igl::colon(
   const H hi, 
   Eigen::Matrix<T,Eigen::Dynamic,1> & I)
 {
-  if(low < hi)
-  {
-    if(step < 0)
-    {
-      I.resize(0);
-      //fprintf(stderr,"WARNING: colon() low(%g)<hi(%g) but step(%g)<0\n",
-      //  (double)low,
-      //  (double)hi,
-      //  (double)step);
-      //assert(false && "low<hi but step<0");
-      return;
-    }
-  }
-  if(low > hi)
-  {
-    if(step > 0)
-    {
-      I.resize(0);
-      //fprintf(stderr,"Error: colon() low(%g)>hi(%g) but step(%g)>0\n",
-      //  (double)low,
-      //  (double)hi,
-      //  (double)step);
-      //assert(false && "low>hi but step<0");
-      return;
-    }
-  }
-  // resize output
-  int n = std::floor(double((hi-low)/step))+1;
-  I.resize(n);
-  int i = 0;
-  T v = (T)low;
-  while((low==hi && (H)v==hi) || (low<hi && (H)v<=hi) || (low>hi && (H)v>=hi))
-  {
-    I(i) = v;
-    v = v + (T)step;
-    i++;
-  }
-  assert(i==n);
+  const int size = ((hi-low)/step)+1;
+  I = Eigen::Matrix<T,Eigen::Dynamic,1>::LinSpaced(size,low,low+step*(size-1));
 }
 
 template <typename L,typename H,typename T>

+ 1 - 1
include/igl/embree/unproject_in_mesh.cpp

@@ -121,5 +121,5 @@ template int igl::unproject_in_mesh<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(doubl
 template int igl::unproject_in_mesh<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(double, double, igl::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
 #  endif
 template int igl::unproject_in_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::Matrix<float, 2, 1, 0, 2, 1> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 1, 0, 4, 1> const&, igl::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
-template int igl::unproject_in_mesh<Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::Matrix<float, 2, 1, 0, 2, 1> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 1, 0, 4, 1> const&, igl::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, std::__1::vector<igl::Hit, std::__1::allocator<igl::Hit> >&);
+template int igl::unproject_in_mesh<Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::Matrix<float, 2, 1, 0, 2, 1> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 1, 0, 4, 1> const&, igl::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, std::vector<igl::Hit, std::allocator<igl::Hit> >&);
 #endif

+ 2 - 0
include/igl/frustum.cpp

@@ -20,5 +20,7 @@ IGL_INLINE void igl::frustum(
 }
 
 #ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+// generated by autoexplicit.sh
 template void igl::frustum<Eigen::Matrix<float, 4, 4, 0, 4, 4> >(Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 4, 0, 4, 4> >&);
 #endif

+ 1 - 0
include/igl/grad.cpp

@@ -106,4 +106,5 @@ IGL_INLINE void igl::grad(const Eigen::PlainObjectBase<DerivedV>&V,
 // template void igl::grad<double, int>(Eigen::Matrix<double, -1, -1, 0, -1,-1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&,Eigen::SparseMatrix<double, 0, int>&);
 template void igl::grad<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::SparseMatrix<Eigen::Matrix<double, -1, 3, 0, -1, 3>::Scalar, 0, int>&);
 //template void igl::grad<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::SparseMatrix<Eigen::Matrix<double, -1, 3, 0, -1, 3>::Scalar, 0, int>&);
+template void igl::grad<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::SparseMatrix<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, 0, int>&);
 #endif

+ 1 - 1
include/igl/is_border_vertex.cpp

@@ -32,5 +32,5 @@ IGL_INLINE std::vector<bool> igl::is_border_vertex(const Eigen::PlainObjectBase<
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 template std::vector<bool, std::allocator<bool> > igl::is_border_vertex<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&);
-template std::__1::vector<bool, std::__1::allocator<bool> > igl::is_border_vertex<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&);
+template std::vector<bool, std::allocator<bool> > igl::is_border_vertex<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&);
 #endif

+ 1 - 0
include/igl/is_irregular_vertex.cpp

@@ -40,4 +40,5 @@ IGL_INLINE std::vector<bool> igl::is_irregular_vertex(const Eigen::PlainObjectBa
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 template std::vector<bool, std::allocator<bool> > igl::is_irregular_vertex<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&);
+template std::vector<bool, std::allocator<bool> > igl::is_irregular_vertex<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&);
 #endif

+ 4 - 0
include/igl/list_to_matrix.cpp

@@ -155,4 +155,8 @@ template bool igl::list_to_matrix<double, 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>&);
+template bool igl::list_to_matrix<double, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> > >(std::vector<double, std::allocator<double> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >&);
+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> >&);
 #endif

+ 2 - 0
include/igl/look_at.cpp

@@ -31,5 +31,7 @@ IGL_INLINE void igl::look_at(
 }
 
 #ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+// generated by autoexplicit.sh
 template void igl::look_at<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 4, 4, 0, 4, 4> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 4, 0, 4, 4> >&);
 #endif

+ 2 - 0
include/igl/matlab/prepare_lhs.cpp

@@ -38,4 +38,6 @@ template void igl::prepare_lhs_index<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Ei
 template void igl::prepare_lhs_index<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, mxArray_tag**);
 template void igl::prepare_lhs_double<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, mxArray_tag**);
 template void igl::prepare_lhs_index<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, mxArray_tag**);
+template void igl::prepare_lhs_logical<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, mxArray_tag**);
+template void igl::prepare_lhs_double<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, mxArray_tag**);
 #endif

+ 21 - 0
include/igl/null.cpp

@@ -0,0 +1,21 @@
+// 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/.
+#include "null.h"
+#include "EPS.h"
+
+template <typename DerivedA, typename DerivedN>
+IGL_INLINE void igl::null(
+  const Eigen::PlainObjectBase<DerivedA> & A,
+  Eigen::PlainObjectBase<DerivedN> & N)
+{
+  using namespace Eigen;
+  typedef typename DerivedA::Scalar Scalar;
+  JacobiSVD<MatrixXd> svd(A, ComputeFullV);
+  svd.setThreshold(A.cols() * svd.singularValues().maxCoeff() * EPS<Scalar>());
+  N = svd.matrixV().rightCols(A.cols()-svd.rank());
+}

+ 36 - 0
include/igl/null.h

@@ -0,0 +1,36 @@
+// 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_NULL_H
+#define IGL_NULL_H
+#include "igl_inline.h"
+
+#include <Eigen/Dense>
+
+namespace igl 
+{
+  // Like MATLAB's null
+  //
+  // Compute a basis for the null space for the given matrix A: the columns of
+  // the output N form a basis for the space orthogonal to that spanned by the
+  // rows of A.
+  //
+  // Inputs:
+  //   A  m by n matrix
+  // Outputs:
+  //   N  n by r matrix, where r is the row rank of A
+  template <typename DerivedA, typename DerivedN>
+  IGL_INLINE void null(
+    const Eigen::PlainObjectBase<DerivedA> & A,
+    Eigen::PlainObjectBase<DerivedN> & N);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "null.cpp"
+#endif
+
+#endif

+ 2 - 0
include/igl/ortho.cpp

@@ -20,5 +20,7 @@ IGL_INLINE void igl::ortho(
 }
 
 #ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+// generated by autoexplicit.sh
 template void igl::ortho<Eigen::Matrix<float, 4, 4, 0, 4, 4> >(Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::Matrix<float, 4, 4, 0, 4, 4>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 4, 0, 4, 4> >&);
 #endif

+ 1 - 0
include/igl/outer_facet.cpp

@@ -89,4 +89,5 @@ IGL_INLINE void igl::outer_facet(
 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&);
+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, -1, 0, -1, -1>, 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, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
 #endif

+ 28 - 5
include/igl/outer_hull.cpp

@@ -42,6 +42,7 @@ IGL_INLINE void igl::outer_hull(
   typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
   typedef Matrix<typename DerivedG::Scalar,Dynamic,DerivedG::ColsAtCompileTime> MatrixXG;
   typedef Matrix<typename DerivedJ::Scalar,Dynamic,DerivedJ::ColsAtCompileTime> MatrixXJ;
+  typedef Matrix<typename DerivedN::Scalar,1,3> RowVector3N;
   const Index m = F.rows();
 
 #ifdef IGL_OUTER_HULL_DEBUG
@@ -71,7 +72,7 @@ IGL_INLINE void igl::outer_hull(
   {
     // Base normal vector to orient against
     const auto fe0 = uE2E[ui][0];
-    const auto & eVp = N.row(fe0%m);
+    const RowVector3N & eVp = N.row(fe0%m);
     di[ui].resize(uE2E[ui].size());
 
     const typename DerivedF::Scalar d = F(fe0%m,((fe0/m)+2)%3);
@@ -92,7 +93,7 @@ IGL_INLINE void igl::outer_hull(
       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);
+      const RowVector3N & n = N.row(f);
       di[ui][fei] = M_PI - atan2( eVp.cross(n).dot(eV), eVp.dot(n));
       if(!cons[fei])
       {
@@ -173,6 +174,9 @@ IGL_INLINE void igl::outer_hull(
   cout<<"outer facet..."<<endl;
 #endif
     outer_facet(V,F,N,IM,f,f_flip);
+#ifdef IGL_OUTER_HULL_DEBUG
+  cout<<"outer facet: "<<f<<endl;
+#endif
     int FHcount = 0;
     // Q contains list of face edges to continue traversing upong
     queue<int> Q;
@@ -386,8 +390,23 @@ IGL_INLINE void igl::outer_hull(
     MatrixXV q = BC.row(AJ(0));
     // In a perfect world, it's enough to test a single point.
     double w;
+
+    // winding_number_3 expects colmajor
+    const typename DerivedV::Scalar * Vdata;
+    Vdata = V.data();
+    Matrix<
+      typename DerivedV::Scalar,
+      DerivedV::RowsAtCompileTime,
+      DerivedV::ColsAtCompileTime,
+      ColMajor> Vcol;
+    if(DerivedV::IsRowMajor)
+    {
+      // copy to convert to colmajor
+      Vcol = V;
+      Vdata = Vcol.data();
+    }
     winding_number_3(
-      V.data(),V.rows(),
+      Vdata,V.rows(),
       B.data(),B.rows(),
       q.data(),1,&w);
     return fabs(w)>0.5;
@@ -405,8 +424,11 @@ IGL_INLINE void igl::outer_hull(
       {
         continue;
       }
-      keep[id] = keep[id] && 
-        !is_component_inside_other(V,BC,vG[id],vJ[id],vG[oid]);
+      const bool inside = is_component_inside_other(V,BC,vG[id],vJ[id],vG[oid]);
+#ifdef IGL_OUTER_HULL_DEBUG
+      cout<<id<<" is inside "<<oid<<" ? "<<inside<<endl;
+#endif
+      keep[id] = keep[id] && !inside;
     }
     if(keep[id])
     {
@@ -454,4 +476,5 @@ IGL_INLINE void igl::outer_hull(
 // 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> >&);
+template void igl::outer_hull<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::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -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<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
 #endif

+ 1 - 0
include/igl/parula.h

@@ -52,6 +52,7 @@ namespace igl
     const double min_Z,
     const double max_Z,
     Eigen::PlainObjectBase<DerivedC> & C);
+  // adapted from parula.m
   const Eigen::Matrix<float,256,4> PARULA_COLOR_MAP = 
     (Eigen::Matrix<float,256,4>()<<
       0.2081,0.1663,0.5292,1,

+ 1 - 0
include/igl/per_edge_normals.cpp

@@ -108,4 +108,5 @@ IGL_INLINE void igl::per_edge_normals(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instanciation
 template void igl::per_edge_normals<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::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<double, -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> >&);
+template void igl::per_edge_normals<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::Matrix<double, -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&, igl::PerEdgeNormalsWeightingType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -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/png/texture_from_png.h

@@ -8,6 +8,7 @@
 #ifndef IGL_TEXTURE_FROM_PNG_H
 #define IGL_TEXTURE_FROM_PNG_H
 #include "../igl_inline.h"
+#include <Eigen/Core>
 #include <string>
 #include <Eigen/Core>
 

+ 3 - 4
include/igl/project.cpp

@@ -12,6 +12,7 @@
 #include "report_gl_error.h"
 
 #include "OpenGL_convenience.h"
+#include <iostream>
 
 IGL_INLINE int igl::project(
   const double objX,
@@ -139,10 +140,9 @@ Eigen::Matrix<Scalar,3,1> igl::project(
 
 
 #ifdef IGL_STATIC_LIBRARY
-
+// Explicit template instanciations
 #ifndef IGL_NO_OPENGL
 #ifndef IGL_OPENGL_4
-// Explicit template instanciations
 template int igl::project<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
 template Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > igl::project<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
 template int igl::project<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&);
@@ -154,8 +154,7 @@ template Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > igl::proj
 template Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> > igl::project<Eigen::Matrix<double, 2, 1, 0, 2, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> > const&);
 #endif
 template Eigen::Matrix<double, 3, 1, 0, 3, 1> igl::project<double>(Eigen::Matrix<double, 3, 1, 0, 3, 1> const&, Eigen::Matrix<double, 4, 4, 0, 4, 4> const&, Eigen::Matrix<double, 4, 4, 0, 4, 4> const&, Eigen::Matrix<double, 4, 1, 0, 4, 1> const&);
-template Eigen::Matrix<float, 3, 1, 0, 3, 1> igl::project<float>(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 1, 0, 4, 1> const&);
 // template int igl::project(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 1, 0, 4, 1> const&);
 #endif
-
+template Eigen::Matrix<float, 3, 1, 0, 3, 1> igl::project<float>(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 4, 0, 4, 4> const&, Eigen::Matrix<float, 4, 1, 0, 4, 1> const&);
 #endif

+ 15 - 2
include/igl/readDMAT.cpp

@@ -78,8 +78,13 @@ IGL_INLINE bool igl::readDMAT(const std::string file_name,
     return false;
   }
 
-  // Resize output to fit matrix
-  W.resize(num_rows,num_cols);
+  // Resize output to fit matrix, only if non-empty since this will trigger an
+  // error on fixed size matrices before reaching binary data.
+  bool empty = num_rows == 0 || num_cols == 0;
+  if(!empty)
+  {
+    W.resize(num_rows,num_cols);
+  }
 
   // Loop over columns slowly
   for(int j = 0;j < num_cols;j++)
@@ -119,6 +124,14 @@ IGL_INLINE bool igl::readDMAT(const std::string file_name,
         W(i,j) = Wraw[j*num_rows+i];
       }
     }
+  }else
+  {
+    // we skipped resizing before in case there was binary data
+    if(empty)
+    {
+      // This could trigger an error if using fixed size matrices.
+      W.resize(num_rows,num_cols);
+    }
   }
 
   fclose(fp);

+ 2 - 1
include/igl/readOBJ.cpp

@@ -106,7 +106,8 @@ IGL_INLINE bool igl::readOBJ(
         if(count != 2 && count != 3)
         {
           fprintf(stderr,
-                  "Error: readOBJ() vertex on line %d should have 2 or 3 coordinates (%d)",
+                  "Error: readOBJ() texture coords on line %d should have 2 "
+                  "or 3 coordinates (%d)",
                   line_no,count);
           fclose(obj_file);
           return false;

+ 0 - 796
include/igl/serialize.cpp

@@ -1,796 +0,0 @@
-//
-// Copyright (C) 2014 Christian Schüller <schuellchr@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/.
-
-#include "serialize.h"
-
-namespace igl
-{
-  template <typename T>
-  IGL_INLINE bool serialize(const T& obj,const std::string& filename)
-  {
-    return serialize(obj,"obj",filename,true);
-  }
-
-  template <typename T>
-  IGL_INLINE bool serialize(const T& obj,const std::string& objectName,const std::string& filename,bool overwrite)
-  {
-    bool success = false;
-
-    std::vector<char> buffer;
-
-    std::ios_base::openmode mode = std::ios::out | std::ios::binary;
-
-    if(overwrite)
-      mode |= std::ios::trunc;
-    else
-      mode |= std::ios::app;
-
-    std::ofstream file(filename.c_str(),mode);
-
-    if(file.is_open())
-    {
-      serialize(obj,objectName,buffer);
-
-      file.write(&buffer[0],buffer.size());
-
-      file.close();
-
-      success = true;
-    }
-    else
-    {
-      std::cerr << "serialization: file " << filename << " not found!" << std::endl;
-    }
-
-    return success;
-  }
-
-  template <typename T>
-  IGL_INLINE bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer)
-  {
-    // serialize object data
-    size_t size = serialization::getByteSize(obj);
-    std::vector<char> tmp(size);
-    auto it = tmp.begin();
-    serialization::serialize(obj,tmp,it);
-
-    std::string objectType(typeid(obj).name());
-    size_t newObjectSize = tmp.size();
-    size_t newHeaderSize = serialization::getByteSize(objectName) + serialization::getByteSize(objectType) + sizeof(size_t);
-    size_t curSize = buffer.size();
-    size_t newSize = curSize + newHeaderSize + newObjectSize;
-
-    buffer.resize(newSize);
-
-    std::vector<char>::iterator iter = buffer.begin()+curSize;
-
-    // serialize object header (name/type/size)
-    serialization::serialize(objectName,buffer,iter);
-    serialization::serialize(objectType,buffer,iter);
-    serialization::serialize(newObjectSize,buffer,iter);
-
-    // copy serialized data to buffer
-    iter = std::copy(tmp.begin(),tmp.end(),iter);
-
-    return true;
-  }
-
-  template <typename T>
-  IGL_INLINE bool deserialize(T& obj,const std::string& filename)
-  {
-    return deserialize(obj,"obj",filename);
-  }
-
-  template <typename T>
-  IGL_INLINE bool deserialize(T& obj,const std::string& objectName,const std::string& filename)
-  {
-    bool success = false;
-
-    std::ifstream file(filename.c_str(),std::ios::binary);
-
-    if(file.is_open())
-    {
-      file.seekg(0,std::ios::end);
-      std::streamoff size = file.tellg();
-      file.seekg(0,std::ios::beg);
-
-      std::vector<char> buffer(size);
-      file.read(&buffer[0],size);
-
-      deserialize(obj,objectName,buffer);
-      file.close();
-
-      success = true;
-    }
-    else
-    {
-      std::cerr << "serialization: file " << filename << " not found!" << std::endl;
-    }
-
-    return success;
-  }
-
-  template <typename T>
-  IGL_INLINE bool deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer)
-  {
-    bool success = false;
-
-    // find suitable object header
-    auto objectIter = buffer.cend();
-    auto iter = buffer.cbegin();
-    while(iter != buffer.end())
-    {
-      std::string name;
-      std::string type;
-      size_t size;
-      serialization::deserialize(name,iter);
-      serialization::deserialize(type,iter);
-      serialization::deserialize(size,iter);
-
-      if(name == objectName && type == typeid(obj).name())
-      {
-        objectIter = iter;
-        //break; // find first suitable object header
-      }
-
-      iter+=size;
-    }
-
-    if(objectIter != buffer.end())
-    {
-      serialization::deserialize(obj,objectIter);
-      success = true;
-    }
-    else
-    {
-      obj = T();
-    }
-
-    return success;
-  }
-
-  // Wrapper function which combines both, de- and serialization
-  template <typename T>
-  IGL_INLINE bool serializer(bool s,T& obj,std::string& filename)
-  {
-    return s ? serialize(obj,filename) : deserialize(obj,filename);
-  }
-
-  template <typename T>
-  IGL_INLINE bool serializer(bool s,T& obj,std::string& objectName,const std::string& filename,bool overwrite)
-  {
-    return s ? serialize(obj,objectName,filename,overwrite) : deserialize(obj,objectName,filename);
-  }
-
-  template <typename T>
-  IGL_INLINE bool serializer(bool s,T& obj,std::string& objectName,std::vector<char>& buffer)
-  {
-    return s ? serialize(obj,objectName,buffer) : deserialize(obj,objectName,buffer);
-  }
-
-  IGL_INLINE bool Serializable::PreSerialization() const
-  {
-    return true;
-  }
-
-  IGL_INLINE void Serializable::PostSerialization() const
-  {
-  }
-
-  IGL_INLINE bool Serializable::PreDeserialization()
-  {
-    return true;
-  }
-
-  IGL_INLINE void Serializable::PostDeserialization()
-  {
-  }
-
-  IGL_INLINE void Serializable::Serialize(std::vector<char>& buffer) const
-  {
-    if(this->PreSerialization())
-    {
-      if(initialized == false)
-      {
-        objects.clear();
-        (const_cast<Serializable*>(this))->InitSerialization();
-        initialized = true;
-      }
-
-      for(const auto& v : objects)
-      {
-        v->Serialize(buffer);
-      }
-
-      this->PostSerialization();
-    }
-  }
-
-  IGL_INLINE void Serializable::Deserialize(const std::vector<char>& buffer)
-  {
-    if(this->PreDeserialization())
-    {
-      if(initialized == false)
-      {
-        objects.clear();
-        (const_cast<Serializable*>(this))->InitSerialization();
-        initialized = true;
-      }
-
-      for(auto& v : objects)
-      {
-        v->Deserialize(buffer);
-      }
-
-      this->PostDeserialization();
-    }
-  }
-
-  IGL_INLINE Serializable::Serializable()
-  {
-    initialized = false;
-  }
-
-  IGL_INLINE Serializable::Serializable(const Serializable& obj)
-  {
-    initialized = false;
-    objects.clear();
-  }
-
-  IGL_INLINE Serializable::~Serializable()
-  {
-    initialized = false;
-    objects.clear();
-  }
-
-  IGL_INLINE Serializable& Serializable::operator=(const Serializable& obj)
-  {
-    if(this != &obj)
-    {
-      if(initialized)
-      {
-        initialized = false;
-        objects.clear();
-      }
-    }
-    return *this;
-  }
-
-  template <typename T>
-  IGL_INLINE void Serializable::Add(T& obj,std::string name,bool binary)
-  {
-    auto object = new SerializationObject<T>();
-    object->Binary = binary;
-    object->Name = name;
-    object->Object = std::unique_ptr<T>(&obj);
-
-    objects.push_back(object);
-  }
-
-  namespace serialization
-  {
-    // not serializable
-    template <typename T>
-    IGL_INLINE typename std::enable_if<!is_serializable<T>::value,size_t>::type getByteSize(const T& obj)
-    {
-      return sizeof(std::vector<char>::size_type);
-    }
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<!is_serializable<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      // data
-      std::vector<char> tmp;
-      serialize(obj,tmp);
-
-      // size
-      size_t size = buffer.size();
-      serialization::serialize(tmp.size(),buffer,iter);
-      size_t cur = iter - buffer.begin();
-
-      buffer.resize(size+tmp.size());
-      iter = buffer.begin()+cur;
-      iter = std::copy(tmp.begin(),tmp.end(),iter);
-    }
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<!is_serializable<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
-    {
-      std::vector<char>::size_type size;
-      serialization::deserialize(size,iter);
-
-      std::vector<char> tmp;
-      tmp.resize(size);
-      std::copy(iter,iter+size,tmp.begin());
-
-      deserialize(obj,tmp);
-      iter += size;
-    }
-
-    // fundamental types
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value,size_t>::type getByteSize(const T& obj)
-    {
-      return sizeof(T);
-    }
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      //serialization::updateMemoryMap(obj,sizeof(T));
-      const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&obj);
-      iter = std::copy(ptr,ptr+sizeof(T),iter);
-    }
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
-    {
-      uint8_t* ptr = reinterpret_cast<uint8_t*>(&obj);
-      std::copy(iter,iter+sizeof(T),ptr);
-      iter += sizeof(T);
-    }
-
-    // std::string
-
-    IGL_INLINE size_t getByteSize(const std::string& obj)
-    {
-      return getByteSize(obj.length())+obj.length()*sizeof(uint8_t);
-    }
-
-    IGL_INLINE void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      serialization::serialize(obj.length(),buffer,iter);
-      for(const auto& cur : obj)
-      {
-        serialization::serialize(cur,buffer,iter);
-      }
-    }
-
-    IGL_INLINE void deserialize(std::string& obj,std::vector<char>::const_iterator& iter)
-    {
-      size_t size;
-      serialization::deserialize(size,iter);
-
-      std::string str(size,'\0');
-      for(size_t i=0; i<size; ++i)
-      {
-        serialization::deserialize(str.at(i),iter);
-      }
-
-      obj = str;
-    }
-
-    // SerializableBase
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_base_of<SerializableBase,T>::value,size_t>::type getByteSize(const T& obj)
-    {
-      return sizeof(std::vector<char>::size_type);
-    }
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      // data
-      std::vector<char> tmp;
-      obj.Serialize(tmp);
-
-      // size
-      size_t size = buffer.size();
-      serialization::serialize(tmp.size(),buffer,iter);
-      size_t cur = iter - buffer.begin();
-
-      buffer.resize(size+tmp.size());
-      iter = buffer.begin()+cur;
-      iter = std::copy(tmp.begin(),tmp.end(),iter);
-    }
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
-    {
-      std::vector<char>::size_type size;
-      serialization::deserialize(size,iter);
-
-      std::vector<char> tmp;
-      tmp.resize(size);
-      std::copy(iter,iter+size,tmp.begin());
-
-      obj.Deserialize(tmp);
-      iter += size;
-    }
-
-    // STL containers
-
-    // std::pair
-
-    template <typename T1,typename T2>
-    IGL_INLINE size_t getByteSize(const std::pair<T1,T2>& obj)
-    {
-      return getByteSize(obj.first)+getByteSize(obj.second);
-    }
-
-    template <typename T1,typename T2>
-    IGL_INLINE void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      serialization::serialize(obj.first,buffer,iter);
-      serialization::serialize(obj.second,buffer,iter);
-    }
-
-    template <typename T1,typename T2>
-    IGL_INLINE void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter)
-    {
-      serialization::deserialize(obj.first,iter);
-      serialization::deserialize(obj.second,iter);
-    }
-
-    // std::vector
-
-    template <typename T1,typename T2>
-    IGL_INLINE size_t getByteSize(const std::vector<T1,T2>& obj)
-    {
-      return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const T1& cur) { return acc+getByteSize(cur); });
-    }
-
-    template <typename T1,typename T2>
-    IGL_INLINE void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      size_t size = obj.size();
-      serialization::serialize(size,buffer,iter);
-      for(const T1& cur : obj)
-      {
-        serialization::serialize(cur,buffer,iter);
-      }
-    }
-
-    template <typename T1,typename T2>
-    IGL_INLINE void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter)
-    {
-      size_t size;
-      serialization::deserialize(size,iter);
-
-      obj.resize(size);
-      for(T1& v : obj)
-      {
-        serialization::deserialize(v,iter);
-      }
-    }
-
-    template <typename T2>
-    IGL_INLINE void deserialize(std::vector<bool,T2>& obj,std::vector<char>::const_iterator& iter)
-    {
-      size_t size;
-      serialization::deserialize(size,iter);
-
-      obj.resize(size);
-      for(int i=0;i<obj.size();i++)
-      {
-        bool val;
-        serialization::deserialize(val,iter);
-        obj[i] = val;
-      }
-    }
-
-    //std::set
-
-    template <typename T>
-    IGL_INLINE size_t getByteSize(const std::set<T>& obj)
-    {
-      return std::accumulate(obj.begin(),obj.end(),getByteSize(obj.size()),[](const size_t& acc,const T& cur) { return acc+getByteSize(cur); });
-    }
-
-    template <typename T>
-    IGL_INLINE void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      serialization::serialize(obj.size(),buffer,iter);
-      for(const T& cur : obj)
-      {
-        serialization::serialize(cur,buffer,iter);
-      }
-    }
-
-    template <typename T>
-    IGL_INLINE void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter)
-    {
-      size_t size;
-      serialization::deserialize(size,iter);
-
-      obj.clear();
-      for(size_t i=0; i<size; ++i)
-      {
-        T val;
-        serialization::deserialize(val,iter);
-        obj.insert(val);
-      }
-    }
-
-    // std::map
-
-    template <typename T1,typename T2>
-    IGL_INLINE size_t getByteSize(const std::map<T1,T2>& obj)
-    {
-      return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const std::pair<T1,T2>& cur) { return acc+getByteSize(cur); });
-    }
-
-    template <typename T1,typename T2>
-    IGL_INLINE void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      serialization::serialize(obj.size(),buffer,iter);
-      for(const auto& cur : obj)
-      {
-        serialization::serialize(cur,buffer,iter);
-      }
-    }
-
-    template <typename T1,typename T2>
-    IGL_INLINE void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter)
-    {
-      size_t size;
-      serialization::deserialize(size,iter);
-
-      obj.clear();
-      for(size_t i=0; i<size; ++i)
-      {
-        std::pair<T1,T2> pair;
-        serialization::deserialize(pair,iter);
-        obj.insert(pair);
-      }
-    }
-
-    // Eigen types
-    template<typename T,int R,int C,int P,int MR,int MC>
-    IGL_INLINE size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj)
-    {
-      // space for numbers of rows,cols and data
-      return 2*sizeof(typename Eigen::Matrix<T,R,C,P,MR,MC>::Index)+sizeof(T)*obj.rows()*obj.cols();
-    }
-
-    template<typename T,int R,int C,int P,int MR,int MC>
-    IGL_INLINE void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      serialization::serialize(obj.rows(),buffer,iter);
-      serialization::serialize(obj.cols(),buffer,iter);
-      size_t size = sizeof(T)*obj.rows()*obj.cols();
-      auto ptr = reinterpret_cast<const uint8_t*>(obj.data());
-      iter = std::copy(ptr,ptr+size,iter);
-    }
-
-    template<typename T,int R,int C,int P,int MR,int MC>
-    IGL_INLINE void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter)
-    {
-      typename Eigen::Matrix<T,R,C,P,MR,MC>::Index rows,cols;
-      serialization::deserialize(rows,iter);
-      serialization::deserialize(cols,iter);
-      size_t size = sizeof(T)*rows*cols;
-      obj.resize(rows,cols);
-      auto ptr = reinterpret_cast<uint8_t*>(obj.data());
-      std::copy(iter,iter+size,ptr);
-      iter+=size;
-    }
-
-    template<typename T,int P,typename I>
-    IGL_INLINE size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj)
-    {
-      // space for numbers of rows,cols,nonZeros and tripplets with data (rowIdx,colIdx,value)
-      size_t size = sizeof(Eigen::SparseMatrix<T,P,I>::Index);
-      return 3*size+(sizeof(T)+2*size)*obj.nonZeros();
-    }
-
-    template<typename T,int P,typename I>
-    IGL_INLINE void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      serialization::serialize(obj.rows(),buffer,iter);
-      serialization::serialize(obj.cols(),buffer,iter);
-      serialization::serialize(obj.nonZeros(),buffer,iter);
-
-      for(int k=0;k<obj.outerSize();++k)
-      {
-        for(typename Eigen::SparseMatrix<T,P,I>::InnerIterator it(obj,k);it;++it)
-        {
-          serialization::serialize(it.row(),buffer,iter);
-          serialization::serialize(it.col(),buffer,iter);
-          serialization::serialize(it.value(),buffer,iter);
-        }
-      }
-    }
-
-    template<typename T,int P,typename I>
-    IGL_INLINE void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter)
-    {
-      typename Eigen::SparseMatrix<T,P,I>::Index rows,cols,nonZeros;
-      serialization::deserialize(rows,iter);
-      serialization::deserialize(cols,iter);
-      serialization::deserialize(nonZeros,iter);
-
-      obj.resize(rows,cols);
-      obj.setZero();
-
-      std::vector<Eigen::Triplet<T,I> > triplets;
-      for(int i=0;i<nonZeros;i++)
-      {
-        typename Eigen::SparseMatrix<T,P,I>::Index rowId,colId;
-        serialization::deserialize(rowId,iter);
-        serialization::deserialize(colId,iter);
-        T value;
-        serialization::deserialize(value,iter);
-        triplets.push_back(Eigen::Triplet<T,I>(rowId,colId,value));
-      }
-      obj.setFromTriplets(triplets.begin(),triplets.end());
-    }
-
-    // pointers
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj)
-    {
-      size_t size = sizeof(bool);
-
-      if(obj)
-        size += getByteSize(*obj);
-
-      return size;
-    }
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      serialization::serialize(obj == nullptr,buffer,iter);
-
-      if(obj)
-        serialization::serialize(*obj,buffer,iter);
-    }
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
-    {
-      bool isNullPtr;
-      serialization::deserialize(isNullPtr,iter);
-
-      if(isNullPtr)
-      {
-        if(obj)
-        {
-          std::cout << "serialization: possible memory leak in serialization for '" << typeid(obj).name() << "'" << std::endl;
-          obj = nullptr;
-        }
-      }
-      else
-      {
-        if(obj)
-        {
-          std::cout << "serialization: possible memory corruption in deserialization for '" << typeid(obj).name() << "'" << std::endl;
-        }
-        else
-        {
-          obj = new typename std::remove_pointer<T>::type();
-        }
-        serialization::deserialize(*obj,iter);
-      }
-    }
-
-    // std::shared_ptr and std::unique_ptr
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<serialization::is_smart_ptr<T>::value,size_t>::type getByteSize(const T& obj)
-    {
-      return getByteSize(obj.get());
-    }
-
-    template <typename T>
-    IGL_INLINE typename std::enable_if<serialization::is_smart_ptr<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-      serialize(obj.get(),buffer,iter);
-    }
-
-    template <template<typename> class T0,typename T1>
-    IGL_INLINE typename std::enable_if<serialization::is_smart_ptr<T0<T1> >::value>::type deserialize(T0<T1>& obj,std::vector<char>::const_iterator& iter)
-    {
-      bool isNullPtr;
-      serialization::deserialize(isNullPtr,iter);
-
-      if(isNullPtr)
-      {
-        obj.reset();
-      }
-      else
-      {
-        obj = T0<T1>(new T1());
-        serialization::deserialize(*obj,iter);
-      }
-    }
-
-    // std::weak_ptr
-
-    template <typename T>
-    IGL_INLINE size_t getByteSize(const std::weak_ptr<T>& obj)
-    {
-      return sizeof(size_t);
-    }
-
-    template <typename T>
-    IGL_INLINE void serialize(const std::weak_ptr<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
-    {
-
-    }
-
-    template <typename T>
-    IGL_INLINE void deserialize(std::weak_ptr<T>& obj,std::vector<char>::const_iterator& iter)
-    {
-
-    }
-
-    // functions to overload for non-intrusive serialization
-    template <typename T>
-    IGL_INLINE void serialize(const T& obj,std::vector<char>& buffer)
-    {
-      std::cerr << typeid(obj).name() << " is not serializable: derive from igl::Serializable or overload the function igl::serialization::serialize(const T& obj,std::vector<char>& buffer)" << std::endl;
-    }
-
-    template <typename T>
-    IGL_INLINE void deserialize(T& obj,const std::vector<char>& buffer)
-    {
-      std::cerr << typeid(obj).name() << " is not deserializable: derive from igl::Serializable or overload the function igl::serialization::deserialize(T& obj, const std::vector<char>& buffer)" << std::endl;
-    }
-
-    // helper functions
-
-    template <typename T>
-    IGL_INLINE void updateMemoryMap(T& obj,size_t size,std::map<std::uintptr_t,IndexedPointerBase*>& memoryMap)
-    {
-      // check if object is already serialized
-      auto startPtr = new IndexedPointer<T>();
-      startPtr->Object = &obj;
-      auto startBasePtr = static_cast<IndexedPointerBase*>(startPtr);
-      startBasePtr->Type = IndexedPointerBase::BEGIN;
-      auto startAddress = reinterpret_cast<std::uintptr_t>(&obj);
-      auto p = std::pair<std::uintptr_t,IndexedPointerBase*>(startAddress,startBasePtr);
-
-      auto el = memoryMap.insert(p);
-      auto iter = ++el.first; // next elememt
-      if(el.second && (iter == memoryMap.end() || iter->second->Type != IndexedPointerBase::END))
-      {
-        // not yet serialized
-        auto endPtr = new IndexedPointer<T>();
-        auto endBasePtr = static_cast<IndexedPointerBase*>(endPtr);
-        endBasePtr->Type = IndexedPointerBase::END;
-        auto endAddress = reinterpret_cast<std::uintptr_t>(&obj) + size - 1;
-        auto p = std::pair<std::uintptr_t,IndexedPointerBase*>(endAddress,endBasePtr);
-
-        // insert end address
-        memoryMap.insert(el.first,p);
-      }
-      else
-      {
-        // already serialized
-
-        // remove inserted address
-        memoryMap.erase(el.first);
-      }
-    }
-  }
-}
-
-#ifdef IGL_STATIC_LIBRARY
-template bool igl::deserialize<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::Matrix<double, -1, 1, 0, -1, 1>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&);
-template bool igl::deserialize<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::Matrix<double, -1, -1, 0, -1, -1>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&);
-template bool igl::deserialize<Eigen::Matrix<unsigned char, -1, -1, 0, -1, -1> >(Eigen::Matrix<unsigned char, -1, -1, 0, -1, -1>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&);
-template bool igl::deserialize<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::Matrix<int, -1, 1, 0, -1, 1>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&);
-template bool igl::deserialize<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::Matrix<int, -1, -1, 0, -1, -1>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&);
-template bool igl::deserialize<std::__1::vector<bool, std::__1::allocator<bool> > >(std::__1::vector<bool, std::__1::allocator<bool> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&);
-template bool igl::deserialize<bool>(bool&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&);
-template bool igl::deserialize<double>(double&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&);
-template bool igl::deserialize<int>(int&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&);
-template bool igl::serialize<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool);
-template bool igl::serialize<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool);
-template bool igl::serialize<Eigen::Matrix<unsigned char, -1, -1, 0, -1, -1> >(Eigen::Matrix<unsigned char, -1, -1, 0, -1, -1> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool);
-template bool igl::serialize<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool);
-template bool igl::serialize<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool);
-template bool igl::serialize<std::__1::vector<bool, std::__1::allocator<bool> > >(std::__1::vector<bool, std::__1::allocator<bool> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool);
-template bool igl::serialize<bool>(bool const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool);
-template bool igl::serialize<double>(double const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool);
-template bool igl::serialize<int>(int const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool);
-#endif

+ 844 - 72
include/igl/serialize.h

@@ -1,9 +1,13 @@
+// This file is part of libigl, a simple c++ geometry processing library.
 //
 // Copyright (C) 2014 Christian Schüller <schuellchr@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_SERIALIZE_H
+#define IGL_SERIALIZE_H
+
 // -----------------------------------------------------------------------------
 // Functions to save and load a serialization of fundamental c++ data types to
 // and from a binary file. STL containers, Eigen matrix types and nested data
@@ -18,8 +22,9 @@
 // * cross-platform compatibility (big-, little-endian)
 // -----------------------------------------------------------------------------
 
-#ifndef IGL_SERIALIZE_H
-#define IGL_SERIALIZE_H
+// Known issues: This is not written in libigl-style so it isn't (easily)
+// "dualized" into the static library. 
+//
 
 #include <type_traits>
 #include <iostream>
@@ -69,13 +74,13 @@ namespace igl
   //   buffer     binary serialization
   //
   template <typename T>
-  IGL_INLINE bool serialize(const T& obj,const std::string& filename);
+  inline bool serialize(const T& obj,const std::string& filename);
   template <typename T>
-  IGL_INLINE bool serialize(const T& obj,const std::string& objectName,const std::string& filename,bool overwrite = false);
+  inline bool serialize(const T& obj,const std::string& objectName,const std::string& filename,bool overwrite = false);
   template <typename T>
-  IGL_INLINE bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer);
+  inline bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer);
   template <typename T>
-  IGL_INLINE bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer);
+  inline bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer);
 
   // Deserializes the given data from a file or buffer back to the provided object
   //
@@ -89,31 +94,31 @@ namespace igl
   //   obj        object to load back serialization to
   //
   template <typename T>
-  IGL_INLINE bool deserialize(T& obj,const std::string& filename);
+  inline bool deserialize(T& obj,const std::string& filename);
   template <typename T>
-  IGL_INLINE bool deserialize(T& obj,const std::string& objectName,const std::string& filename);
+  inline bool deserialize(T& obj,const std::string& objectName,const std::string& filename);
   template <typename T>
-  IGL_INLINE bool deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer);
+  inline bool deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer);
 
   // Wrapper to expose both, the de- and serialization as one function
   //
   template <typename T>
-  IGL_INLINE bool serializer(bool serialize,T& obj,std::string& filename);
+  inline bool serializer(bool serialize,T& obj,std::string& filename);
   template <typename T>
-  IGL_INLINE bool serializer(bool serialize,T& obj,std::string& objectName,const std::string& filename,bool overwrite = false);
+  inline bool serializer(bool serialize,T& obj,std::string& objectName,const std::string& filename,bool overwrite = false);
   template <typename T>
-  IGL_INLINE bool serializer(bool serialize,T& obj,std::string& objectName,std::vector<char>& buffer);
+  inline bool serializer(bool serialize,T& obj,std::string& objectName,std::vector<char>& buffer);
 
   // User defined types have to either overload the function igl::serialization::serialize()
   // and igl::serialization::deserialize() for their type (non-intrusive serialization):
   //
   // namespace igl { namespace serialization 
   // {
-  //   IGL_INLINE void serialize(const UserType& obj,std::vector<char>& buffer) {
+  //   inline void serialize(const UserType& obj,std::vector<char>& buffer) {
   //     ::igl::serialize(obj.var,"var",buffer);
   //   }
   //     
-  //   IGL_INLINE void deserialize(UserType& obj,const std::vector<char>& buffer) {
+  //   inline void deserialize(UserType& obj,const std::vector<char>& buffer) {
   //     ::igl::deserialize(obj.var,"var",buffer);
   //   }
   // }}
@@ -170,28 +175,28 @@ namespace igl
   public:
 
     // Override this function to add your member variables which should be serialized
-    IGL_INLINE virtual void InitSerialization() = 0;
+    inline virtual void InitSerialization() = 0;
 
     // Following functions can be overridden to handle the specific events.
     // Return false to prevent the de-/serialization of an object.
-    IGL_INLINE virtual bool PreSerialization() const;
-    IGL_INLINE virtual void PostSerialization() const;
-    IGL_INLINE virtual bool PreDeserialization();
-    IGL_INLINE virtual void PostDeserialization();
+    inline virtual bool PreSerialization() const;
+    inline virtual void PostSerialization() const;
+    inline virtual bool PreDeserialization();
+    inline virtual void PostDeserialization();
 
     // Default implementation of SerializableBase interface
-    IGL_INLINE void Serialize(std::vector<char>& buffer) const override final;
-    IGL_INLINE void Deserialize(const std::vector<char>& buffer) override final;
+    inline void Serialize(std::vector<char>& buffer) const override final;
+    inline void Deserialize(const std::vector<char>& buffer) override final;
 
     // Default constructor, destructor, assignment and copy constructor
-    IGL_INLINE Serializable();
-    IGL_INLINE Serializable(const Serializable& obj);
-    IGL_INLINE ~Serializable();
-    IGL_INLINE Serializable& operator=(const Serializable& obj);
+    inline Serializable();
+    inline Serializable(const Serializable& obj);
+    inline ~Serializable();
+    inline Serializable& operator=(const Serializable& obj);
 
     // Use this function to add your variables which should be serialized
     template <typename T>
-    IGL_INLINE void Add(T& obj,std::string name,bool binary = false);
+    inline void Add(T& obj,std::string name,bool binary = false);
   };
 
   // structure for pointer handling
@@ -245,121 +250,888 @@ namespace igl
 
     // non serializable types
     template <typename T>
-    IGL_INLINE typename std::enable_if<!is_serializable<T>::value,size_t>::type getByteSize(const T& obj);
+    inline typename std::enable_if<!is_serializable<T>::value,size_t>::type getByteSize(const T& obj);
     template <typename T>
-    IGL_INLINE typename std::enable_if<!is_serializable<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline typename std::enable_if<!is_serializable<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <typename T>
-    IGL_INLINE typename std::enable_if<!is_serializable<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
+    inline typename std::enable_if<!is_serializable<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
 
     // fundamental types
     template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value,size_t>::type getByteSize(const T& obj);
+    inline typename std::enable_if<std::is_fundamental<T>::value,size_t>::type getByteSize(const T& obj);
     template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
+    inline typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
 
     // std::string
-    IGL_INLINE size_t getByteSize(const std::string& obj);
-    IGL_INLINE void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
-    IGL_INLINE void deserialize(std::string& obj,std::vector<char>::const_iterator& iter);
+    inline size_t getByteSize(const std::string& obj);
+    inline void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline void deserialize(std::string& obj,std::vector<char>::const_iterator& iter);
 
     // SerializableBase
     template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_base_of<SerializableBase,T>::value,size_t>::type getByteSize(const T& obj);
+    inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value,size_t>::type getByteSize(const T& obj);
     template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);    
+    inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);    
 
     // stl containers
     // std::pair
     template <typename T1,typename T2>
-    IGL_INLINE size_t getByteSize(const std::pair<T1,T2>& obj);
+    inline size_t getByteSize(const std::pair<T1,T2>& obj);
     template <typename T1,typename T2>
-    IGL_INLINE void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <typename T1,typename T2>
-    IGL_INLINE void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter);
+    inline void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter);
 
     // std::vector
     template <typename T1,typename T2>
-    IGL_INLINE size_t getByteSize(const std::vector<T1,T2>& obj);
+    inline size_t getByteSize(const std::vector<T1,T2>& obj);
     template <typename T1,typename T2>
-    IGL_INLINE void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <typename T1,typename T2>
-    IGL_INLINE void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter);
+    inline void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter);
     template <typename T2>
-    IGL_INLINE void deserialize(std::vector<bool,T2>& obj,std::vector<char>::const_iterator& iter);
+    inline void deserialize(std::vector<bool,T2>& obj,std::vector<char>::const_iterator& iter);
 
     // std::set
     template <typename T>
-    IGL_INLINE size_t getByteSize(const std::set<T>& obj);
+    inline size_t getByteSize(const std::set<T>& obj);
     template <typename T>
-    IGL_INLINE void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <typename T>
-    IGL_INLINE void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter);
+    inline void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter);
 
     // std::map
     template <typename T1,typename T2>
-    IGL_INLINE size_t getByteSize(const std::map<T1,T2>& obj);
+    inline size_t getByteSize(const std::map<T1,T2>& obj);
     template <typename T1,typename T2>
-    IGL_INLINE void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <typename T1,typename T2>
-    IGL_INLINE void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter);
+    inline void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter);
 
     // Eigen types
     template<typename T,int R,int C,int P,int MR,int MC>
-    IGL_INLINE size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj);
+    inline size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj);
     template<typename T,int R,int C,int P,int MR,int MC>
-    IGL_INLINE void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template<typename T,int R,int C,int P,int MR,int MC>
-    IGL_INLINE void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter);
+    inline void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter);
 
     template<typename T,int P,typename I>
-    IGL_INLINE size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj);
+    inline size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj);
     template<typename T,int P,typename I>
-    IGL_INLINE void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template<typename T,int P,typename I>
-    IGL_INLINE void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter);
+    inline void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter);
 
     // raw pointers
     template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj);
+    inline typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj);
     template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <typename T>
-    IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
+    inline typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
 
     // std::shared_ptr and std::unique_ptr
     template <typename T>
-    IGL_INLINE typename std::enable_if<serialization::is_smart_ptr<T>::value,size_t>::type getByteSize(const T& obj);
+    inline typename std::enable_if<serialization::is_smart_ptr<T>::value,size_t>::type getByteSize(const T& obj);
     template <typename T>
-    IGL_INLINE typename std::enable_if<serialization::is_smart_ptr<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline typename std::enable_if<serialization::is_smart_ptr<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <template<typename> class T0, typename T1>
-    IGL_INLINE typename std::enable_if<serialization::is_smart_ptr<T0<T1> >::value>::type deserialize(T0<T1>& obj,std::vector<char>::const_iterator& iter);
+    inline typename std::enable_if<serialization::is_smart_ptr<T0<T1> >::value>::type deserialize(T0<T1>& obj,std::vector<char>::const_iterator& iter);
 
     // std::weak_ptr
     template <typename T>
-    IGL_INLINE size_t getByteSize(const std::weak_ptr<T>& obj);
+    inline size_t getByteSize(const std::weak_ptr<T>& obj);
     template <typename T>
-    IGL_INLINE void serialize(const std::weak_ptr<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    inline void serialize(const std::weak_ptr<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
     template <typename T>
-    IGL_INLINE void deserialize(std::weak_ptr<T>& obj,std::vector<char>::const_iterator& iter);
+    inline void deserialize(std::weak_ptr<T>& obj,std::vector<char>::const_iterator& iter);
 
     // functions to overload for non-intrusive serialization
     template <typename T>
-    IGL_INLINE void serialize(const T& obj,std::vector<char>& buffer);
+    inline void serialize(const T& obj,std::vector<char>& buffer);
     template <typename T>
-    IGL_INLINE void deserialize(T& obj,const std::vector<char>& buffer);
+    inline void deserialize(T& obj,const std::vector<char>& buffer);
 
     // helper functions
     template <typename T>
-    IGL_INLINE void updateMemoryMap(T& obj,size_t size);
+    inline void updateMemoryMap(T& obj,size_t size);
   }
 }
 
-#ifndef IGL_STATIC_LIBRARY
-  #include "serialize.cpp"
-#endif
+// Always include inlines for these functions
+
+// IMPLEMENTATION
+
+namespace igl
+{
+  template <typename T>
+  inline bool serialize(const T& obj,const std::string& filename)
+  {
+    return serialize(obj,"obj",filename,true);
+  }
+
+  template <typename T>
+  inline bool serialize(const T& obj,const std::string& objectName,const std::string& filename,bool overwrite)
+  {
+    bool success = false;
+
+    std::vector<char> buffer;
+
+    std::ios_base::openmode mode = std::ios::out | std::ios::binary;
+
+    if(overwrite)
+      mode |= std::ios::trunc;
+    else
+      mode |= std::ios::app;
+
+    std::ofstream file(filename.c_str(),mode);
+
+    if(file.is_open())
+    {
+      serialize(obj,objectName,buffer);
+
+      file.write(&buffer[0],buffer.size());
+
+      file.close();
+
+      success = true;
+    }
+    else
+    {
+      std::cerr << "serialization: file " << filename << " not found!" << std::endl;
+    }
+
+    return success;
+  }
+
+  template <typename T>
+  inline bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer)
+  {
+    // serialize object data
+    size_t size = serialization::getByteSize(obj);
+    std::vector<char> tmp(size);
+    auto it = tmp.begin();
+    serialization::serialize(obj,tmp,it);
+
+    std::string objectType(typeid(obj).name());
+    size_t newObjectSize = tmp.size();
+    size_t newHeaderSize = serialization::getByteSize(objectName) + serialization::getByteSize(objectType) + sizeof(size_t);
+    size_t curSize = buffer.size();
+    size_t newSize = curSize + newHeaderSize + newObjectSize;
+
+    buffer.resize(newSize);
+
+    std::vector<char>::iterator iter = buffer.begin()+curSize;
+
+    // serialize object header (name/type/size)
+    serialization::serialize(objectName,buffer,iter);
+    serialization::serialize(objectType,buffer,iter);
+    serialization::serialize(newObjectSize,buffer,iter);
+
+    // copy serialized data to buffer
+    iter = std::copy(tmp.begin(),tmp.end(),iter);
+
+    return true;
+  }
+
+  template <typename T>
+  inline bool deserialize(T& obj,const std::string& filename)
+  {
+    return deserialize(obj,"obj",filename);
+  }
+
+  template <typename T>
+  inline bool deserialize(T& obj,const std::string& objectName,const std::string& filename)
+  {
+    bool success = false;
+
+    std::ifstream file(filename.c_str(),std::ios::binary);
+
+    if(file.is_open())
+    {
+      file.seekg(0,std::ios::end);
+      std::streamoff size = file.tellg();
+      file.seekg(0,std::ios::beg);
+
+      std::vector<char> buffer(size);
+      file.read(&buffer[0],size);
+
+      deserialize(obj,objectName,buffer);
+      file.close();
+
+      success = true;
+    }
+    else
+    {
+      std::cerr << "serialization: file " << filename << " not found!" << std::endl;
+    }
+
+    return success;
+  }
+
+  template <typename T>
+  inline bool deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer)
+  {
+    bool success = false;
+
+    // find suitable object header
+    auto objectIter = buffer.cend();
+    auto iter = buffer.cbegin();
+    while(iter != buffer.end())
+    {
+      std::string name;
+      std::string type;
+      size_t size;
+      serialization::deserialize(name,iter);
+      serialization::deserialize(type,iter);
+      serialization::deserialize(size,iter);
+
+      if(name == objectName && type == typeid(obj).name())
+      {
+        objectIter = iter;
+        //break; // find first suitable object header
+      }
+
+      iter+=size;
+    }
+
+    if(objectIter != buffer.end())
+    {
+      serialization::deserialize(obj,objectIter);
+      success = true;
+    }
+    else
+    {
+      obj = T();
+    }
+
+    return success;
+  }
+
+  // Wrapper function which combines both, de- and serialization
+  template <typename T>
+  inline bool serializer(bool s,T& obj,std::string& filename)
+  {
+    return s ? serialize(obj,filename) : deserialize(obj,filename);
+  }
+
+  template <typename T>
+  inline bool serializer(bool s,T& obj,std::string& objectName,const std::string& filename,bool overwrite)
+  {
+    return s ? serialize(obj,objectName,filename,overwrite) : deserialize(obj,objectName,filename);
+  }
+
+  template <typename T>
+  inline bool serializer(bool s,T& obj,std::string& objectName,std::vector<char>& buffer)
+  {
+    return s ? serialize(obj,objectName,buffer) : deserialize(obj,objectName,buffer);
+  }
+
+  inline bool Serializable::PreSerialization() const
+  {
+    return true;
+  }
+
+  inline void Serializable::PostSerialization() const
+  {
+  }
+
+  inline bool Serializable::PreDeserialization()
+  {
+    return true;
+  }
+
+  inline void Serializable::PostDeserialization()
+  {
+  }
+
+  inline void Serializable::Serialize(std::vector<char>& buffer) const
+  {
+    if(this->PreSerialization())
+    {
+      if(initialized == false)
+      {
+        objects.clear();
+        (const_cast<Serializable*>(this))->InitSerialization();
+        initialized = true;
+      }
+
+      for(const auto& v : objects)
+      {
+        v->Serialize(buffer);
+      }
+
+      this->PostSerialization();
+    }
+  }
+
+  inline void Serializable::Deserialize(const std::vector<char>& buffer)
+  {
+    if(this->PreDeserialization())
+    {
+      if(initialized == false)
+      {
+        objects.clear();
+        (const_cast<Serializable*>(this))->InitSerialization();
+        initialized = true;
+      }
+
+      for(auto& v : objects)
+      {
+        v->Deserialize(buffer);
+      }
+
+      this->PostDeserialization();
+    }
+  }
+
+  inline Serializable::Serializable()
+  {
+    initialized = false;
+  }
+
+  inline Serializable::Serializable(const Serializable& obj)
+  {
+    initialized = false;
+    objects.clear();
+  }
+
+  inline Serializable::~Serializable()
+  {
+    initialized = false;
+    objects.clear();
+  }
+
+  inline Serializable& Serializable::operator=(const Serializable& obj)
+  {
+    if(this != &obj)
+    {
+      if(initialized)
+      {
+        initialized = false;
+        objects.clear();
+      }
+    }
+    return *this;
+  }
+
+  template <typename T>
+  inline void Serializable::Add(T& obj,std::string name,bool binary)
+  {
+    auto object = new SerializationObject<T>();
+    object->Binary = binary;
+    object->Name = name;
+    object->Object = std::unique_ptr<T>(&obj);
+
+    objects.push_back(object);
+  }
+
+  namespace serialization
+  {
+    // not serializable
+    template <typename T>
+    inline typename std::enable_if<!is_serializable<T>::value,size_t>::type getByteSize(const T& obj)
+    {
+      return sizeof(std::vector<char>::size_type);
+    }
+
+    template <typename T>
+    inline typename std::enable_if<!is_serializable<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      // data
+      std::vector<char> tmp;
+      serialize(obj,tmp);
+
+      // size
+      size_t size = buffer.size();
+      serialization::serialize(tmp.size(),buffer,iter);
+      size_t cur = iter - buffer.begin();
+
+      buffer.resize(size+tmp.size());
+      iter = buffer.begin()+cur;
+      iter = std::copy(tmp.begin(),tmp.end(),iter);
+    }
+
+    template <typename T>
+    inline typename std::enable_if<!is_serializable<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
+    {
+      std::vector<char>::size_type size;
+      serialization::deserialize(size,iter);
+
+      std::vector<char> tmp;
+      tmp.resize(size);
+      std::copy(iter,iter+size,tmp.begin());
+
+      deserialize(obj,tmp);
+      iter += size;
+    }
+
+    // fundamental types
+
+    template <typename T>
+    inline typename std::enable_if<std::is_fundamental<T>::value,size_t>::type getByteSize(const T& obj)
+    {
+      return sizeof(T);
+    }
+
+    template <typename T>
+    inline typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      //serialization::updateMemoryMap(obj,sizeof(T));
+      const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&obj);
+      iter = std::copy(ptr,ptr+sizeof(T),iter);
+    }
+
+    template <typename T>
+    inline typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
+    {
+      uint8_t* ptr = reinterpret_cast<uint8_t*>(&obj);
+      std::copy(iter,iter+sizeof(T),ptr);
+      iter += sizeof(T);
+    }
+
+    // std::string
+
+    inline size_t getByteSize(const std::string& obj)
+    {
+      return getByteSize(obj.length())+obj.length()*sizeof(uint8_t);
+    }
+
+    inline void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      serialization::serialize(obj.length(),buffer,iter);
+      for(const auto& cur : obj)
+      {
+        serialization::serialize(cur,buffer,iter);
+      }
+    }
+
+    inline void deserialize(std::string& obj,std::vector<char>::const_iterator& iter)
+    {
+      size_t size;
+      serialization::deserialize(size,iter);
+
+      std::string str(size,'\0');
+      for(size_t i=0; i<size; ++i)
+      {
+        serialization::deserialize(str.at(i),iter);
+      }
+
+      obj = str;
+    }
+
+    // SerializableBase
+
+    template <typename T>
+    inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value,size_t>::type getByteSize(const T& obj)
+    {
+      return sizeof(std::vector<char>::size_type);
+    }
+
+    template <typename T>
+    inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      // data
+      std::vector<char> tmp;
+      obj.Serialize(tmp);
+
+      // size
+      size_t size = buffer.size();
+      serialization::serialize(tmp.size(),buffer,iter);
+      size_t cur = iter - buffer.begin();
+
+      buffer.resize(size+tmp.size());
+      iter = buffer.begin()+cur;
+      iter = std::copy(tmp.begin(),tmp.end(),iter);
+    }
+
+    template <typename T>
+    inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
+    {
+      std::vector<char>::size_type size;
+      serialization::deserialize(size,iter);
+
+      std::vector<char> tmp;
+      tmp.resize(size);
+      std::copy(iter,iter+size,tmp.begin());
+
+      obj.Deserialize(tmp);
+      iter += size;
+    }
+
+    // STL containers
+
+    // std::pair
+
+    template <typename T1,typename T2>
+    inline size_t getByteSize(const std::pair<T1,T2>& obj)
+    {
+      return getByteSize(obj.first)+getByteSize(obj.second);
+    }
+
+    template <typename T1,typename T2>
+    inline void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      serialization::serialize(obj.first,buffer,iter);
+      serialization::serialize(obj.second,buffer,iter);
+    }
+
+    template <typename T1,typename T2>
+    inline void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter)
+    {
+      serialization::deserialize(obj.first,iter);
+      serialization::deserialize(obj.second,iter);
+    }
+
+    // std::vector
+
+    template <typename T1,typename T2>
+    inline size_t getByteSize(const std::vector<T1,T2>& obj)
+    {
+      return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const T1& cur) { return acc+getByteSize(cur); });
+    }
+
+    template <typename T1,typename T2>
+    inline void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      size_t size = obj.size();
+      serialization::serialize(size,buffer,iter);
+      for(const T1& cur : obj)
+      {
+        serialization::serialize(cur,buffer,iter);
+      }
+    }
+
+    template <typename T1,typename T2>
+    inline void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter)
+    {
+      size_t size;
+      serialization::deserialize(size,iter);
+
+      obj.resize(size);
+      for(T1& v : obj)
+      {
+        serialization::deserialize(v,iter);
+      }
+    }
+
+    template <typename T2>
+    inline void deserialize(std::vector<bool,T2>& obj,std::vector<char>::const_iterator& iter)
+    {
+      size_t size;
+      serialization::deserialize(size,iter);
+
+      obj.resize(size);
+      for(int i=0;i<obj.size();i++)
+      {
+        bool val;
+        serialization::deserialize(val,iter);
+        obj[i] = val;
+      }
+    }
+
+    //std::set
+
+    template <typename T>
+    inline size_t getByteSize(const std::set<T>& obj)
+    {
+      return std::accumulate(obj.begin(),obj.end(),getByteSize(obj.size()),[](const size_t& acc,const T& cur) { return acc+getByteSize(cur); });
+    }
+
+    template <typename T>
+    inline void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      serialization::serialize(obj.size(),buffer,iter);
+      for(const T& cur : obj)
+      {
+        serialization::serialize(cur,buffer,iter);
+      }
+    }
+
+    template <typename T>
+    inline void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter)
+    {
+      size_t size;
+      serialization::deserialize(size,iter);
+
+      obj.clear();
+      for(size_t i=0; i<size; ++i)
+      {
+        T val;
+        serialization::deserialize(val,iter);
+        obj.insert(val);
+      }
+    }
+
+    // std::map
+
+    template <typename T1,typename T2>
+    inline size_t getByteSize(const std::map<T1,T2>& obj)
+    {
+      return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const std::pair<T1,T2>& cur) { return acc+getByteSize(cur); });
+    }
+
+    template <typename T1,typename T2>
+    inline void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      serialization::serialize(obj.size(),buffer,iter);
+      for(const auto& cur : obj)
+      {
+        serialization::serialize(cur,buffer,iter);
+      }
+    }
+
+    template <typename T1,typename T2>
+    inline void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter)
+    {
+      size_t size;
+      serialization::deserialize(size,iter);
+
+      obj.clear();
+      for(size_t i=0; i<size; ++i)
+      {
+        std::pair<T1,T2> pair;
+        serialization::deserialize(pair,iter);
+        obj.insert(pair);
+      }
+    }
+
+    // Eigen types
+    template<typename T,int R,int C,int P,int MR,int MC>
+    inline size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj)
+    {
+      // space for numbers of rows,cols and data
+      return 2*sizeof(typename Eigen::Matrix<T,R,C,P,MR,MC>::Index)+sizeof(T)*obj.rows()*obj.cols();
+    }
+
+    template<typename T,int R,int C,int P,int MR,int MC>
+    inline void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      serialization::serialize(obj.rows(),buffer,iter);
+      serialization::serialize(obj.cols(),buffer,iter);
+      size_t size = sizeof(T)*obj.rows()*obj.cols();
+      auto ptr = reinterpret_cast<const uint8_t*>(obj.data());
+      iter = std::copy(ptr,ptr+size,iter);
+    }
+
+    template<typename T,int R,int C,int P,int MR,int MC>
+    inline void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter)
+    {
+      typename Eigen::Matrix<T,R,C,P,MR,MC>::Index rows,cols;
+      serialization::deserialize(rows,iter);
+      serialization::deserialize(cols,iter);
+      size_t size = sizeof(T)*rows*cols;
+      obj.resize(rows,cols);
+      auto ptr = reinterpret_cast<uint8_t*>(obj.data());
+      std::copy(iter,iter+size,ptr);
+      iter+=size;
+    }
+
+    template<typename T,int P,typename I>
+    inline size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj)
+    {
+      // space for numbers of rows,cols,nonZeros and tripplets with data (rowIdx,colIdx,value)
+      size_t size = sizeof(typename Eigen::SparseMatrix<T,P,I>::Index);
+      return 3*size+(sizeof(T)+2*size)*obj.nonZeros();
+    }
+
+    template<typename T,int P,typename I>
+    inline void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      serialization::serialize(obj.rows(),buffer,iter);
+      serialization::serialize(obj.cols(),buffer,iter);
+      serialization::serialize(obj.nonZeros(),buffer,iter);
+
+      for(int k=0;k<obj.outerSize();++k)
+      {
+        for(typename Eigen::SparseMatrix<T,P,I>::InnerIterator it(obj,k);it;++it)
+        {
+          serialization::serialize(it.row(),buffer,iter);
+          serialization::serialize(it.col(),buffer,iter);
+          serialization::serialize(it.value(),buffer,iter);
+        }
+      }
+    }
+
+    template<typename T,int P,typename I>
+    inline void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter)
+    {
+      typename Eigen::SparseMatrix<T,P,I>::Index rows,cols,nonZeros;
+      serialization::deserialize(rows,iter);
+      serialization::deserialize(cols,iter);
+      serialization::deserialize(nonZeros,iter);
+
+      obj.resize(rows,cols);
+      obj.setZero();
+
+      std::vector<Eigen::Triplet<T,I> > triplets;
+      for(int i=0;i<nonZeros;i++)
+      {
+        typename Eigen::SparseMatrix<T,P,I>::Index rowId,colId;
+        serialization::deserialize(rowId,iter);
+        serialization::deserialize(colId,iter);
+        T value;
+        serialization::deserialize(value,iter);
+        triplets.push_back(Eigen::Triplet<T,I>(rowId,colId,value));
+      }
+      obj.setFromTriplets(triplets.begin(),triplets.end());
+    }
+
+    // pointers
+
+    template <typename T>
+    inline typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj)
+    {
+      size_t size = sizeof(bool);
+
+      if(obj)
+        size += getByteSize(*obj);
+
+      return size;
+    }
+
+    template <typename T>
+    inline typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      serialization::serialize(obj == nullptr,buffer,iter);
+
+      if(obj)
+        serialization::serialize(*obj,buffer,iter);
+    }
+
+    template <typename T>
+    inline typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
+    {
+      bool isNullPtr;
+      serialization::deserialize(isNullPtr,iter);
+
+      if(isNullPtr)
+      {
+        if(obj)
+        {
+          std::cout << "serialization: possible memory leak in serialization for '" << typeid(obj).name() << "'" << std::endl;
+          obj = nullptr;
+        }
+      }
+      else
+      {
+        if(obj)
+        {
+          std::cout << "serialization: possible memory corruption in deserialization for '" << typeid(obj).name() << "'" << std::endl;
+        }
+        else
+        {
+          obj = new typename std::remove_pointer<T>::type();
+        }
+        serialization::deserialize(*obj,iter);
+      }
+    }
+
+    // std::shared_ptr and std::unique_ptr
+
+    template <typename T>
+    inline typename std::enable_if<serialization::is_smart_ptr<T>::value,size_t>::type getByteSize(const T& obj)
+    {
+      return getByteSize(obj.get());
+    }
+
+    template <typename T>
+    inline typename std::enable_if<serialization::is_smart_ptr<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      serialize(obj.get(),buffer,iter);
+    }
+
+    template <template<typename> class T0,typename T1>
+    inline typename std::enable_if<serialization::is_smart_ptr<T0<T1> >::value>::type deserialize(T0<T1>& obj,std::vector<char>::const_iterator& iter)
+    {
+      bool isNullPtr;
+      serialization::deserialize(isNullPtr,iter);
+
+      if(isNullPtr)
+      {
+        obj.reset();
+      }
+      else
+      {
+        obj = T0<T1>(new T1());
+        serialization::deserialize(*obj,iter);
+      }
+    }
+
+    // std::weak_ptr
+
+    template <typename T>
+    inline size_t getByteSize(const std::weak_ptr<T>& obj)
+    {
+      return sizeof(size_t);
+    }
+
+    template <typename T>
+    inline void serialize(const std::weak_ptr<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+
+    }
+
+    template <typename T>
+    inline void deserialize(std::weak_ptr<T>& obj,std::vector<char>::const_iterator& iter)
+    {
+
+    }
+
+    // functions to overload for non-intrusive serialization
+    template <typename T>
+    inline void serialize(const T& obj,std::vector<char>& buffer)
+    {
+      std::cerr << typeid(obj).name() << " is not serializable: derive from igl::Serializable or overload the function igl::serialization::serialize(const T& obj,std::vector<char>& buffer)" << std::endl;
+    }
+
+    template <typename T>
+    inline void deserialize(T& obj,const std::vector<char>& buffer)
+    {
+      std::cerr << typeid(obj).name() << " is not deserializable: derive from igl::Serializable or overload the function igl::serialization::deserialize(T& obj, const std::vector<char>& buffer)" << std::endl;
+    }
+
+    // helper functions
+
+    template <typename T>
+    inline void updateMemoryMap(T& obj,size_t size,std::map<std::uintptr_t,IndexedPointerBase*>& memoryMap)
+    {
+      // check if object is already serialized
+      auto startPtr = new IndexedPointer<T>();
+      startPtr->Object = &obj;
+      auto startBasePtr = static_cast<IndexedPointerBase*>(startPtr);
+      startBasePtr->Type = IndexedPointerBase::BEGIN;
+      auto startAddress = reinterpret_cast<std::uintptr_t>(&obj);
+      auto p = std::pair<std::uintptr_t,IndexedPointerBase*>(startAddress,startBasePtr);
+
+      auto el = memoryMap.insert(p);
+      auto iter = ++el.first; // next elememt
+      if(el.second && (iter == memoryMap.end() || iter->second->Type != IndexedPointerBase::END))
+      {
+        // not yet serialized
+        auto endPtr = new IndexedPointer<T>();
+        auto endBasePtr = static_cast<IndexedPointerBase*>(endPtr);
+        endBasePtr->Type = IndexedPointerBase::END;
+        auto endAddress = reinterpret_cast<std::uintptr_t>(&obj) + size - 1;
+        auto p = std::pair<std::uintptr_t,IndexedPointerBase*>(endAddress,endBasePtr);
+
+        // insert end address
+        memoryMap.insert(el.first,p);
+      }
+      else
+      {
+        // already serialized
+
+        // remove inserted address
+        memoryMap.erase(el.first);
+      }
+    }
+  }
+}
 
 #endif

+ 109 - 1
include/igl/slice.cpp

@@ -143,6 +143,93 @@ 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)
+{
+  int xm = X.rows();
+  int xn = X.cols();
+  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(
   const Eigen::PlainObjectBase<DerivedX> & X,
@@ -173,11 +260,32 @@ IGL_INLINE Eigen::PlainObjectBase<DerivedX> igl::slice(
   const int dim)
 {
   Eigen::PlainObjectBase<DerivedX> Y;
-  // phony column indices
   igl::slice(X,R,dim,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 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

+ 23 - 0
include/igl/slice.h

@@ -47,6 +47,19 @@ namespace igl
     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(
     const Eigen::PlainObjectBase<DerivedX> & X,
     const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
@@ -61,6 +74,16 @@ 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

+ 1 - 0
include/igl/slice_tets.cpp

@@ -218,4 +218,5 @@ IGL_INLINE void igl::slice_tets(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
+template void igl::slice_tets<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 4, 1, 0, 4, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, double>(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, 4, 1, 0, 4, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -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> >&, Eigen::SparseMatrix<double, 0, int>&);
 #endif

+ 2 - 0
include/igl/sort.cpp

@@ -223,4 +223,6 @@ template void igl::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int,
 template void igl::sort<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&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::sort<Eigen::Matrix<double, -1, 1, 0, -1, 1>, 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&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::sort_new<Eigen::Matrix<int, 1, 6, 1, 1, 6>, Eigen::Matrix<int, 1, 6, 1, 1, 6>, Eigen::Matrix<int, 1, 6, 1, 1, 6> >(Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 6, 1, 1, 6> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 6, 1, 1, 6> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 6, 1, 1, 6> >&);
+template void igl::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
+template void igl::sort<Eigen::Matrix<double, -1, 4, 0, -1, 4>, Eigen::Matrix<double, -1, 4, 0, -1, 4>, Eigen::Matrix<int, -1, 4, 0, -1, 4> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 4, 0, -1, 4> >&);
 #endif

+ 1 - 0
include/igl/unique_simplices.cpp

@@ -60,4 +60,5 @@ IGL_INLINE void igl::unique_simplices(
 template void igl::unique_simplices<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<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> >&);
 template void igl::unique_simplices<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
 template void igl::unique_simplices<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
+template void igl::unique_simplices<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> >&);
 #endif

+ 1 - 0
include/igl/winding_number.cpp

@@ -4,6 +4,7 @@
 #include <igl/PI.h>
 #include <cmath>
 
+// IF THIS IS EVER TEMPLATED BE SURE THAT V IS COLMAJOR
 IGL_INLINE void igl::winding_number(
   const Eigen::MatrixXd & V,
   const Eigen::MatrixXi & F,

+ 12 - 3
include/igl/winding_number.h

@@ -16,11 +16,8 @@ namespace igl
   //   dim  dimension of input
   // Inputs:
   //  V  n by 3 list of vertex positions
-  //  n  number of mesh vertices
   //  F  #F by 3 list of triangle indices, minimum index is 0
-  //  m  number of faces
   //  O  no by 3 list of origin positions
-  //  no  number of origins
   // Outputs:
   //  S  no by 1 list of winding numbers
   //
@@ -30,6 +27,18 @@ namespace igl
     const Eigen::MatrixXi & F,
     const Eigen::MatrixXd & O,
     Eigen::VectorXd & W);
+  // Inputs:
+  //   V  pointer to array containing #V by 3 vertex positions along rows,
+  //     given in column major order
+  //   n  number of mesh vertices
+  //   F  pointer to array containing #F by 3 face indices along rows,
+  //     given in column major order
+  //   m  number of faces
+  //   O  pointer to array containing #O by 3 query positions along rows,
+  //     given in column major order
+  //   no  number of origins
+  // Outputs:
+  //   S  no by 1 list of winding numbers
   template <typename DerivedF>
   IGL_INLINE void winding_number_3(
     const double * V,

+ 0 - 259
include/igl/xml/old_version/ReAntTweakBarXMLSerialization.h

@@ -1,259 +0,0 @@
-// 
-// Copyright (C) 2014 Christian Schüller <schuellchr@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_REANTTWEAKBAR_XML_SERIALIZATION_H
-#define IGL_REANTTWEAKBAR_XML_SERIALIZATION_H
-#include "../igl_inline.h"
-#include "XMLSerializer.h"
-
-#undef IGL_HEADER_ONLY
-#include <igl/ReAntTweakBar.h>
-
-// Forward declarations
-namespace igl
-{
-  class ReTwBar;
-};
-namespace tinyxml2
-{
-  class XMLDocument;
-};
-
-namespace igl
-{
-  
-//  namespace
-//  {
-  
-//    IGL_INLINE bool save_ReAntTweakBar(::igl::ReTwBar* bar, const char* file_name);
-//    IGL_INLINE bool save_ReAntTweakBar(::igl::ReTwBar* bar, tinyxml2::XMLDocument* doc);
-//    IGL_INLINE bool load_ReAntTweakBar(::igl::ReTwBar* bar, const char *file_name);
-//    IGL_INLINE bool load_ReAntTweakBar(::igl::ReTwBar* bar, tinyxml2::XMLDocument* doc);
-    
-    
-    IGL_INLINE bool save_ReAntTweakBar(::igl::ReTwBar* bar, const char* file_name)
-    {
-      const char * name_chars = TwGetBarName(bar->bar);
-      std::string name = std::string(name_chars) + "_AntTweakBar";
-      
-      const std::vector< ::igl::ReTwRWItem>& rw_items = bar->get_rw_items();
-      for(std::vector< ::igl::ReTwRWItem>::const_iterator it = rw_items.begin(); it != rw_items.end(); it++)
-      {
-        std::string val = bar->get_value_as_string(it->var,it->type);
-        ::igl::XMLSerializer::SaveObject(val,it->name,name,file_name,false);
-      }
-      
-      char var[REANTTWEAKBAR_MAX_CB_VAR_SIZE];
-      // Print all CB variables
-      const std::vector< ::igl::ReTwCBItem>& cb_items = bar->get_cb_items();
-      for(std::vector< ::igl::ReTwCBItem>::const_iterator it = cb_items.begin(); it != cb_items.end(); it++)
-      {
-        TwType type = it->type;
-        //TwSetVarCallback setCallback = it->setCallback;
-        TwGetVarCallback getCallback = it->getCallback;
-        void * clientData = it->clientData;
-        // I'm not sure how to do what I want to do. getCallback needs to be sure
-        // that it can write to var. So var needs to point to a valid and big
-        // enough chunk of memory
-        getCallback(var,clientData);
-        
-        std::string val = bar->get_value_as_string(var,type);
-        ::igl::XMLSerializer::SaveObject(val,it->name,name,file_name,false);
-      }
-      
-      return true;
-    }
-    
-    IGL_INLINE bool save_ReAntTweakBar(::igl::ReTwBar* bar, tinyxml2::XMLDocument* doc)
-    {
-      std::vector<char**> buffer;
-      
-      const char * name_chars = TwGetBarName(bar->bar);
-      std::string name = std::string(name_chars) + "_AntTweakBar";
-      ::igl::XMLSerializer* s = new ::igl::XMLSerializer(name);
-      
-      const std::vector< ::igl::ReTwRWItem>& rw_items = bar->get_rw_items();
-      for(std::vector< ::igl::ReTwRWItem>::const_iterator it = rw_items.begin(); it != rw_items.end(); it++)
-      {
-        std::string val = bar->get_value_as_string(it->var,it->type);
-        char** cval = new char*; // create char* on heap
-        *cval = new char[val.size()+1];
-        buffer.push_back(cval);
-        strcpy(*cval,val.c_str());
-        s->Add(*cval,it->name);
-      }
-      
-      char var[REANTTWEAKBAR_MAX_CB_VAR_SIZE];
-      // Print all CB variables
-      const std::vector< ::igl::ReTwCBItem>& cb_items = bar->get_cb_items();
-      for(std::vector< ::igl::ReTwCBItem>::const_iterator it = cb_items.begin(); it != cb_items.end(); it++)
-      {
-        TwType type = it->type;
-        //TwSetVarCallback setCallback = it->setCallback;
-        TwGetVarCallback getCallback = it->getCallback;
-        void * clientData = it->clientData;
-        // I'm not sure how to do what I want to do. getCallback needs to be sure
-        // that it can write to var. So var needs to point to a valid and big
-        // enough chunk of memory
-        getCallback(var,clientData);
-        
-        std::string val = bar->get_value_as_string(var,type);
-        char** cval = new char*; // create char* on heap
-        *cval = new char[val.size()+1];
-        buffer.push_back(cval);
-        strcpy(*cval,val.c_str());
-        s->Add(*cval,it->name);
-      }
-      
-      s->SaveToXMLDoc(name,doc);
-      
-      // delete pointer buffers
-      for(unsigned int i=0;i<buffer.size();i++)
-      {
-        delete[] *buffer[i];
-        delete buffer[i];
-      }
-      
-      delete s;
-      
-      return true;
-    }
-    
-    IGL_INLINE bool load_ReAntTweakBar(::igl::ReTwBar* bar, const char *file_name)
-    {
-      char type_str[REANTTWEAKBAR_MAX_WORD];
-      char value_str[REANTTWEAKBAR_MAX_WORD];
-      TwType type;
-      
-      const char * name_chars = TwGetBarName(bar->bar);
-      std::string name = std::string(name_chars) + "_AntTweakBar";
-      
-      const std::vector< ::igl::ReTwRWItem>& rw_items = bar->get_rw_items();
-      for(std::vector< ::igl::ReTwRWItem>::const_iterator it = rw_items.begin(); it != rw_items.end(); it++)
-      {
-        char* val;
-        ::igl::XMLSerializer::LoadObject(val,it->name,name,file_name);
-        sscanf(val,"%s %[^\n]",type_str,value_str);
-        
-        if(!bar->type_from_string(type_str,type))
-        {
-          printf("ERROR: %s type not found... Skipping...\n",type_str);
-          continue;
-        }
-        
-        bar->set_value_from_string(it->name.c_str(),type,value_str);
-        delete[] val;
-      }
-      
-      const std::vector< ::igl::ReTwCBItem>& cb_items = bar->get_cb_items();
-      for(std::vector< ::igl::ReTwCBItem>::const_iterator it = cb_items.begin(); it != cb_items.end(); it++)
-      {
-        char* val;
-        ::igl::XMLSerializer::LoadObject(val,it->name,name,file_name);
-        sscanf(val,"%s %[^\n]",type_str,value_str);
-        
-        if(!bar->type_from_string(type_str,type))
-        {
-          printf("ERROR: %s type not found... Skipping...\n",type_str);
-          continue;
-        }
-        
-        bar->set_value_from_string(it->name.c_str(),type,value_str);
-        delete[] val;
-      }
-      
-      return true;
-    }
-    
-    IGL_INLINE bool load_ReAntTweakBar(::igl::ReTwBar* bar, tinyxml2::XMLDocument* doc)
-    {
-      std::map<std::string,char*> variables;
-      std::map<std::string,char*> cbVariables;
-      
-      const char * name_chars = TwGetBarName(bar->bar);
-      std::string name = std::string(name_chars) + "_AntTweakBar";
-      ::igl::XMLSerializer* s = new ::igl::XMLSerializer(name);
-      
-      std::map<std::string,char*>::iterator iter;
-      const std::vector< ::igl::ReTwRWItem>& rw_items = bar->get_rw_items();
-      for(std::vector< ::igl::ReTwRWItem>::const_iterator it = rw_items.begin(); it != rw_items.end(); it++)
-      {
-        variables[it->name] = NULL;
-        iter = variables.find(it->name);
-        s->Add(iter->second,iter->first);
-      }
-      
-      // Add all CB variables
-      const std::vector< ::igl::ReTwCBItem>& cb_items = bar->get_cb_items();
-      for(std::vector< ::igl::ReTwCBItem>::const_iterator it = cb_items.begin(); it != cb_items.end(); it++)
-      {
-        cbVariables[it->name] = NULL;
-        iter = cbVariables.find(it->name);
-        s->Add(iter->second,iter->first);
-      }
-      
-      s->LoadFromXMLDoc(doc);
-      
-      // Set loaded values
-      char type_str[REANTTWEAKBAR_MAX_WORD];
-      char value_str[REANTTWEAKBAR_MAX_WORD];
-      TwType type;
-      
-      for(iter = variables.begin(); iter != variables.end(); iter++)
-      {
-        if(iter->second == NULL)
-        {
-          printf("ERROR: '%s' entry not found... Skipping...\n",iter->first.c_str());
-          continue;
-        }
-        
-        sscanf(iter->second,"%s %[^\n]",type_str,value_str);
-        
-        if(!bar->type_from_string(type_str,type))
-        {
-          printf("ERROR: Type '%s' of '%s' not found... Skipping...\n",type_str,iter->first.c_str());
-          continue;
-        }
-        
-        bar->set_value_from_string(iter->first.c_str(),type,value_str);
-      }
-      
-      for(iter = cbVariables.begin(); iter != cbVariables.end(); iter++)
-      {
-        if(iter->second == NULL)
-        {
-          printf("ERROR: '%s' entry not found... Skipping...\n",iter->first.c_str());
-          continue;
-        }
-
-        sscanf(iter->second,"%s %[^\n]",type_str,value_str);
-        
-        if(!bar->type_from_string(type_str,type))
-        {
-          printf("ERROR: Type '%s' of '%s' not found... Skipping...\n",type_str,iter->first.c_str());
-          continue;
-        }
-        
-        bar->set_value_from_string(iter->first.c_str(),type,value_str);
-      }
-      
-      // delete buffers
-      for(iter = variables.begin(); iter != variables.end(); iter++)
-        delete[] iter->second;
-      
-      for(iter = cbVariables.begin(); iter != cbVariables.end(); iter++)
-        delete[] iter->second;
-      
-      delete s;
-      
-      return true;
-    }
-    
-//  }
-}
-
-#endif

+ 0 - 49
include/igl/xml/old_version/XMLSerializable.h

@@ -1,49 +0,0 @@
-// 
-// Copyright (C) 2014 Christian Schüller <schuellchr@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/.
-/* ------------------------------------------------------------------------------
- Inherit from this abstract class to have full control over the serialization
- of your user defined class.
- ----------------------------------------------------------------------------*/
-#ifndef IGL_XML_SERIALIZABLE_H
-#define IGL_XML_SERIALIZABLE_H
-
-#include <iostream>
-#include <tinyxml2.h>
-
-namespace igl
-{
-  namespace
-  {
-    class XMLSerializable
-    {
-    public:
-      /**
-      * Default name of serializable object
-      */
-      std::string Name;
-
-      /**
-        * This function gets called if the objects were not found during deserialization.
-        * Initialize your objects as you like.
-        */
-      virtual void Init() = 0;
-      /**
-        * Serialize your stuff within this function.
-        * doc is the current serialization xml file. You can use SaveToXMLDoc to add your objects.
-        */
-      virtual bool Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) = 0;
-
-      /**
-        * Deserialize your stuff within this function.
-        * doc is the current serialization xml file. You can use LoadFromXMLDoc to read out your objects.
-        */
-      virtual bool Deserialize(tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element) = 0;
-    };
-  }
-}
-
-#endif

+ 0 - 178
include/igl/xml/old_version/XMLSerialization.h

@@ -1,178 +0,0 @@
-// 
-// Copyright (C) 2014 Christian Schüller <schuellchr@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/.
-// ------------------------------------------------------------------------------
-// Inherit from this class to have the easiest way to serialize your user defined class.
-// 
-// 1) Pass the default name of your class to the base constructor.
-// 2) Override InitSerialization() and add your variables to serialize like:
-// xmlSerializer->Add(var1,"name1");
-// xmlSerializer->Add(var2,"name2");
-//
-// Workaround for Visual Studio run time debugger inspection problem:
-// Copy and implement all the functions, splitting them into a source and header file.
-// Restrictions on Native C++ Expressions (Anonymous Namespaces):
-// http://msdn.microsoft.com/en-us/library/0888kc6a%28VS.80%29.aspx
-// ----------------------------------------------------------------------------*/
-#ifndef IGL_XML_SERIALIZATION_H
-#define IGL_XML_SERIALIZATION_H
-
-#include <igl/xml/old_version/XMLSerializer.h>
-
-namespace igl
-{
-  namespace
-  {
-    class XMLSerializer;
-
-    class XMLSerialization : public igl::XMLSerializable
-    {
-    public:
-      XMLSerializer* xmlSerializer;
-
-      /**
-       * Default implementation of XMLSerializable interface
-       */
-      virtual void Init();
-      virtual bool Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element);
-      virtual bool Deserialize(tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element);
-
-      /**
-      * Default constructor, destructor, assignment and copy constructor
-      */
-      XMLSerialization(const std::string& name);
-      ~XMLSerialization();
-      XMLSerialization(const XMLSerialization& obj);
-      XMLSerialization& operator=(const XMLSerialization& obj);
-
-      /**
-      * Function which must be overridden in the subclass if you don't use
-      * heap allocations (new) to create new instances.
-      * It will get called if the assignment operator or copy constructor
-      * is involved to update the references to the new copied data structures
-      *
-      * Add in this function all the variables you want to serialize like:
-      * xmlSerializer->Add(var1);
-      * xmlSerializer->Add(var2);
-      * ...
-      */
-      virtual void InitSerialization();
-
-      /**
-       * Following functions can be overwritten to handle the specific events.
-       * Return false to prevent serialization of object.
-       */
-      virtual bool BeforeSerialization();
-      virtual void AfterSerialization();
-      virtual bool BeforeDeserialization();
-      virtual void AfterDeserialization();
-
-    private:
-      void initXMLSerializer();
-    };
-
-    // Implementation
-
-    void XMLSerialization::Init()
-    {
-    }
-
-    bool XMLSerialization::Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element)
-    {
-      bool serialized = false;
-
-      if(this->BeforeSerialization())
-      {
-        if(xmlSerializer==NULL)
-        {
-          xmlSerializer = new XMLSerializer(Name);
-          this->InitSerialization();
-        }
-        serialized = xmlSerializer->SaveGroupToXMLElement(doc,element,Name);
-        this->AfterSerialization();
-      }
-
-      return serialized;
-    }
-
-    bool XMLSerialization::Deserialize(tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element)
-    {
-      bool serialized = false;
-
-      if(this->BeforeDeserialization())
-      {
-        if(xmlSerializer==NULL)
-        {
-          xmlSerializer = new XMLSerializer(Name);
-          this->InitSerialization();
-        }
-        serialized = xmlSerializer->LoadGroupFromXMLElement(Name,doc,element);
-        this->AfterDeserialization();
-      }
-
-      return serialized;
-    }
-
-    void XMLSerialization::InitSerialization()
-    {
-      std::cout<<"You have to override InitSerialization()"<<"\n";
-      //assert(false);
-    }
-
-    XMLSerialization::XMLSerialization(const std::string& name)
-    {
-      Name = name;
-      xmlSerializer = NULL;
-    }
-
-    XMLSerialization::~XMLSerialization()
-    {
-      if(xmlSerializer!=NULL)
-        delete xmlSerializer;
-      xmlSerializer = NULL;
-    }
-
-    XMLSerialization::XMLSerialization(const XMLSerialization& obj)
-    {
-      Name = obj.Name;
-      xmlSerializer = NULL;
-    }
-
-    XMLSerialization& XMLSerialization::operator=(const XMLSerialization& obj)
-    {
-      if(this!=&obj)
-      {
-        Name = obj.Name;
-        if(xmlSerializer!=NULL)
-        {
-          delete xmlSerializer;
-          xmlSerializer = NULL;
-        }
-      }
-      return *this;
-    }
-
-    bool XMLSerialization::BeforeSerialization()
-    {
-      return true;
-    }
-
-    void XMLSerialization::AfterSerialization()
-    {
-    }
-
-    bool XMLSerialization::BeforeDeserialization()
-    {
-      return true;
-    }
-
-    void XMLSerialization::AfterDeserialization()
-    {
-    }
-  }
-}
-
-#endif

+ 0 - 49
include/igl/xml/old_version/XMLSerializationTest.h

@@ -1,49 +0,0 @@
-// 
-// Copyright (C) 2014 Christian Schüller <schuellchr@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/.
-------------------------------------------------------------------------------
- Used to demonstrates howto use the XMLSerialization class.
-----------------------------------------------------------------------------*/
-#ifndef IGL_XML_SERIALIZATION_TEST_H
-#define IGL_XML_SERIALIZATION_TEST_H
-
-#include <igl/xml/XMLSerialization.h>
-
-namespace igl
-{
-
-  class XMLSerializationTest : public ::igl::XMLSerialization
-  {
-  public:
-      
-    int testInt;
-    std::vector<float> testVector;
-      
-    XMLSerializationTest();
-    void InitSerialization();
-      
-    bool Test();
-  };
-
-  XMLSerializerTest::XMLSerializerTest()
-    : XMLSerialization("testObject")
-  {
-  }
-
-  void XMLSerializerTest::InitSerialization()
-  {
-    xmlSerializer->Add(testInt,"testInt");
-    xmlSerializer->Add(testVector,"testVector");
-      
-    testInt = 10;
-      
-    testVector.push_back(1.0001f);
-    testVector.push_back(2.0001f);
-    testVector.push_back(3.0001f);
-  }
-}
-
-#endif

+ 0 - 1
include/igl/xml/old_version/XMLSerializer.h.REMOVED.git-id

@@ -1 +0,0 @@
-172f806cdef073e1613fe0def62c0521976222bd

+ 7 - 0
include/igl/xml/serialize_xml.cpp

@@ -1,3 +1,4 @@
+// This file is part of libigl, a simple c++ geometry processing library.
 //
 // Copyright (C) 2014 Christian Schüller <schuellchr@gmail.com>
 //
@@ -968,3 +969,9 @@ namespace igl
     }
   }
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+template void igl::serialize_xml<std::vector<float, std::allocator<float> > >(std::vector<float, std::allocator<float> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, bool);
+template void igl::deserialize_xml<std::vector<float, std::allocator<float> > >(std::vector<float, std::allocator<float> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&);
+#endif

+ 23 - 2
index.html

@@ -16,7 +16,7 @@
 
 <figure>
 <img src="libigl-teaser.png" alt="" />
-</figure>
+<figcaption></figcaption></figure>
 
 <p><a href="https://github.com/libigl/libigl/">https://github.com/libigl/libigl/</a></p>
 
@@ -113,6 +113,27 @@ caution.</p>
 <p>You can keep up to date by cloning a read-only copy of our GitHub
 <a href="https://github.com/libigl">repository</a>.</p>
 
+<h2 id="knownissues">Known Issues</h2>
+
+<p>We really heavily on Eigen. Nearly all inputs and outputs are Eigen matrices of
+some kind. However, we currently <em>only</em> support Eigen&#8217;s default column-major
+ordering. That means, we <strong>do not</strong> expect our code to work for matrices using
+the <code>Eigen::RowMajor</code> flag. If you can, change definitions like:</p>
+
+<pre><code class="cpp">Eigen::Matrix&lt;double, Eigen::Dynamic, 3, Eigen::RowMajor&gt; A;
+</code></pre>
+
+<p>to</p>
+
+<pre><code class="cpp">Eigen::Matrix&lt;double, Eigen::Dynamic, 3, Eigen::ColMajor&gt; A;
+// or simply
+Eigen::Matrix&lt;double, Eigen::Dynamic, 3&gt; A;
+</code></pre>
+
+<p>We hope to fix this, or at least identify which functions are safe (many of
+them probably work just fine). This requires setting up unit testing, which is
+a major <em>todo</em> for our development.</p>
+
 <h2 id="howtocontribute">How to contribute</h2>
 
 <p>If you are interested in joining development, please fork the repository and
@@ -163,7 +184,7 @@ Takayama, Leo Sacht, Wenzel Jacob, Nico Pietroni, Amir Vaxman</p>
 
 <figure>
 <img src="tutorial/images/libigl-logo.jpg" alt="" />
-</figure>
+<figcaption></figcaption></figure>
 
 </body>
 </html>

+ 24 - 8
matlab-to-eigen.html

@@ -142,14 +142,18 @@
 
       <tr class=d1>
         <td><pre><code>B = repmat(A,i,j)</code></pre></td>
-        <td><pre><code>igl::repmat(A,i,j,B)</code></pre></td>
-        <td>So far igl::repmat is only implemented for dense matrices.
+        <td><pre><code>igl::repmat(A,i,j,B);
+B = A.replicate(i,j);</code></pre></td>
+        <td>igl::repmat is also implemented for Sparse Matrices.
         </td>
       </tr>
 
       <tr class=d0>
         <td><pre><code>I = low:step:hi</code></pre></td>
-        <td><pre><code>igl::colon(low,step,hi,I)</code></pre></td>
+        <td><pre><code>igl::colon(low,step,hi,I);
+// or
+const int size = ((hi-low)/step)+1;
+I = VectorXiLinSpaced(size,low,low+step*(size-1));</code></pre></td>
         <td>IGL version should be templated enough to handle same situations as
         matlab's colon. The matlab keyword <b>end</b> does not correspond in
         the C++ version. You'll have to use M.size(),M.rows() or whatever.
@@ -209,7 +213,7 @@ A = IM(A);
         <td><pre><code>B = A.unaryExpr(bind1st(mem_fun( 
   static_cast&lt;VectorXi::Scalar&amp;(VectorXi::*)(VectorXi::Index)&gt;
   (&amp;VectorXi::operator())), &amp;IM)).eval();
-
+// or
 for_each(A.data(),A.data()+A.size(),[&amp;IM](int &amp; a){a=IM(a);});
   </code></pre></td>
         <td>Where IM is an "index map" column vector and A is an arbitrary
@@ -234,19 +238,31 @@ A.setFromTriplets(IJV);
       </tr>
 
       <tr class=d1>
-        <td><pre><code>IP = I(P==0);</code></pre></td>
-        <td><pre><code>VectorXi IP = I;
+        <td><pre><code>I=1:10;
+...
+IP = I(P==0);</code></pre></td>
+        <td><pre><code>I = VectorXi::LinSpaced(10,0,9);
+...
+VectorXi IP = I;
 IP.conservativeResize(stable_partition(
   IP.data(), 
   IP.data()+IP.size(), 
   [&amp;P](int i){return P(i)==0;})-IP.data());
         </code></pre></td>
-        <td>Where I and P are vectors. <i>Requires C++11 and <code>#include &lt;algorithm&gt;</code></i></td>
+        <td>Where I is a vector of increasing indices from 0 to n, and P is a vector. <i>Requires C++11 and <code>#include &lt;algorithm&gt;</code></i></td>
       </tr>
 
       <tr class=d0>
+        <td><pre><code>B = A(R&lt;2,C&gt;1);</code></pre>
+        <td><pre><code>B = igl::slice_mask(A,R.array()&lt;2,C.array()&gt;1);</code></pre>
+        <td>Where </td>
+      </tr>
+
+      <tr class=d1>
         <td><pre><code>a = any(A(:))</code></pre></td>
-        <td><pre><code>bool a = any_of(A.data(),A.data()+A.size(),[](bool a){ return a;});</code></pre></td>
+        <td><pre><code><del>bool a = any_of(A.data(),A.data()+A.size(),[](bool a){ return a;});</del>
+bool a = A.array().any();
+        </code></pre></td>
         <td>Casts <code>Matrix::Scalar<code> to <code>bool</code>.</td>
       </tr>
 

+ 9 - 0
tutorial/609_Boolean/CMakeLists.txt

@@ -3,6 +3,15 @@ project(609_Boolean)
 
 find_package(CGAL REQUIRED)
 include(${CGAL_USE_FILE})
+# CGAL's monkeying with all of the flags. Rather than change the CGAL_USE_FILE
+# just get ride of this flag.
+# http://stackoverflow.com/a/18234926/148668
+macro(remove_cxx_flag flag)
+  string(REPLACE "${flag}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+endmacro()
+remove_cxx_flag("-stdlib=libc++")
+
+# This is absolutely necessary for Exact Construction
 
 # for some reason must come after cgal include. I think that it's overwriting
 # come flags like CXX_FLAGS

+ 1 - 1
tutorial/CMakeLists.shared

@@ -32,7 +32,7 @@ if(APPLE)
 endif (APPLE) #APPLE
 
 if(UNIX AND NOT APPLE)
-  set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lGL -lGLU -lrt -lX11 -lXxf86vm -lXrandr -lpthread -lXi")
+  set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lGL -lGLU -lrt -lX11 -lXxf86vm -lXrandr -lpthread -lXi  -lXcursor -lXinerama ")
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
 endif(UNIX AND NOT APPLE)
 

+ 8 - 0
tutorial/cmake/FindLIBIGL.cmake

@@ -145,6 +145,14 @@ if(LIBIGL_USE_STATIC_LIBRARY)
   else(OPENMP_FOUND)
     set(LIBIGL_FOUND false)
   endif(OPENMP_FOUND)
+
+  FIND_LIBRARY( LIBIGLXML_LIBRARY NAMES iglxml PATHS ${LIBIGL_LIB_DIRS})
+  if(NOT LIBIGLXML_LIBRARY)
+    set(LIBIGL_FOUND FALSE)
+    message(FATAL_ERROR "could NOT find libiglxml")
+  endif(NOT LIBIGLXML_LIBRARY)
+  set(LIBIGL_LIBRARIES ${LIBIGL_LIBRARIES}  ${LIBIGLXML_LIBRARY})
+
 endif(LIBIGL_USE_STATIC_LIBRARY)