Browse Source

Merge remote-tracking branch 'upstream/master'

Former-commit-id: 1c8ba8049f9da77b7a92e5d7b018d8e30aaa8d4c
Qingnan Zhou 9 years ago
parent
commit
762b04bf78
100 changed files with 3694 additions and 1426 deletions
  1. 9 0
      .gitignore
  2. 3 1
      .gitmodules
  3. 4 4
      README.md
  4. 0 204
      examples/quicklook-mesh/Info.plist
  5. 0 89
      examples/quicklook-mesh/Makefile
  6. 0 41
      examples/quicklook-mesh/README
  7. 0 94
      examples/quicklook-mesh/src/GeneratePreviewForURL.m
  8. 0 164
      examples/quicklook-mesh/src/GenerateThumbnailForURL.m
  9. 0 218
      examples/quicklook-mesh/src/main.c
  10. 0 504
      examples/quicklook-mesh/src/render_to_buffer.cpp
  11. 0 17
      examples/quicklook-mesh/src/render_to_buffer.h
  12. 11 11
      include/igl/AABB.h
  13. 3 1
      include/igl/ConjugateFFSolverData.h
  14. 1 1
      include/igl/EPS.h
  15. 0 1
      include/igl/HalfEdgeIterator.h
  16. 2 2
      include/igl/IndexComparison.h
  17. 4 0
      include/igl/NormalType.h
  18. 3 3
      include/igl/ONE.h
  19. 1 0
      include/igl/Viewport.h
  20. 5 2
      include/igl/WindingNumberMethod.h
  21. 7 3
      include/igl/WindingNumberTree.h
  22. 3 3
      include/igl/ZERO.h
  23. 0 2
      include/igl/active_set.h
  24. 182 0
      include/igl/boolean/CSGTree.h
  25. 17 4
      include/igl/boolean/mesh_boolean.cpp
  26. 48 0
      include/igl/boolean/string_to_mesh_boolean_type.cpp
  27. 41 0
      include/igl/boolean/string_to_mesh_boolean_type.h
  28. 7 0
      include/igl/cgal/assign_scalar.cpp
  29. 3 0
      include/igl/cgal/assign_scalar.h
  30. 17 3
      include/igl/cgal/mesh_to_cgal_triangle_list.cpp
  31. 6 0
      include/igl/cgal/order_facets_around_edge.cpp
  32. 6 0
      include/igl/cgal/order_facets_around_edges.cpp
  33. 9 0
      include/igl/cgal/outer_facet.cpp
  34. 6 0
      include/igl/cgal/projected_delaunay.cpp
  35. 18 1
      include/igl/cgal/remesh_intersections.cpp
  36. 1 0
      include/igl/cgal/remesh_self_intersections.cpp
  37. 0 0
      include/igl/marching_cubes_tables.h
  38. 2 2
      include/igl/parula.cpp
  39. 65 20
      include/igl/serialize.h
  40. 9 10
      include/igl/unique.cpp
  41. 5 9
      include/igl/unique.h
  42. 26 4
      include/igl/viewer/Viewer.cpp
  43. 7 0
      include/igl/viewer/Viewer.h
  44. 5 2
      include/igl/viewer/ViewerCore.cpp
  45. 2 0
      include/igl/viewer/ViewerCore.h
  46. 14 4
      include/igl/viewer/ViewerData.cpp
  47. 2 2
      index.html
  48. 48 0
      python/001_BasicTypes.py
  49. 14 0
      python/101_FileIO.py
  50. 11 0
      python/102_DrawMesh.py
  51. 24 0
      python/102_DrawMeshTCP.py
  52. 40 0
      python/103_Events.py
  53. 24 0
      python/104_Colors.py
  54. 67 0
      python/105_Overlays.py
  55. 48 0
      python/201_Normals.py
  56. 20 0
      python/202_GaussianCurvature.py
  57. 61 0
      python/203_CurvatureDirections.py
  58. 50 0
      python/204_Gradient.py
  59. 108 0
      python/205_Laplacian.py
  60. 34 0
      python/301_Slice.py
  61. 34 0
      python/302_Sort.py
  62. 73 0
      python/303_LaplaceEquation.py
  63. 96 0
      python/304_LinearEqualityConstraints.py
  64. 86 0
      python/305_QuadraticProgramming.py
  65. 56 0
      python/306_EigenDecomposition.py
  66. 154 0
      python/CMakeLists.txt
  67. 159 0
      python/README.md
  68. 51 0
      python/iglhelpers.py
  69. 59 0
      python/matlab/CurvatureDirections.m
  70. 12 0
      python/matlab/t102DrawMesh.m
  71. 409 0
      python/py_doc.cpp
  72. 409 0
      python/py_doc.h
  73. 69 0
      python/py_igl.cpp
  74. 6 0
      python/py_igl/py_SolverStatus.cpp
  75. 48 0
      python/py_igl/py_active_set.cpp
  76. 9 0
      python/py_igl/py_avg_edge_length.cpp
  77. 10 0
      python/py_igl/py_barycenter.cpp
  78. 30 0
      python/py_igl/py_boundary_facets.cpp
  79. 74 0
      python/py_igl/py_colon.cpp
  80. 10 0
      python/py_igl/py_cotmatrix.cpp
  81. 54 0
      python/py_igl/py_doublearea.cpp
  82. 22 0
      python/py_igl/py_eigs.cpp
  83. 9 0
      python/py_igl/py_floor.cpp
  84. 10 0
      python/py_igl/py_gaussian_curvature.cpp
  85. 10 0
      python/py_igl/py_grad.cpp
  86. 9 0
      python/py_igl/py_invert_diag.cpp
  87. 24 0
      python/py_igl/py_jet.cpp
  88. 19 0
      python/py_igl/py_massmatrix.cpp
  89. 73 0
      python/py_igl/py_min_quad_with_fixed.cpp
  90. 24 0
      python/py_igl/py_parula.cpp
  91. 38 0
      python/py_igl/py_per_corner_normals.cpp
  92. 34 0
      python/py_igl/py_per_face_normals.cpp
  93. 55 0
      python/py_igl/py_per_vertex_normals.cpp
  94. 15 0
      python/py_igl/py_principal_curvature.cpp
  95. 10 0
      python/py_igl/py_readDMAT.cpp
  96. 22 0
      python/py_igl/py_readOFF.cpp
  97. 36 0
      python/py_igl/py_read_triangle_mesh.cpp
  98. 11 0
      python/py_igl/py_setdiff.cpp
  99. 155 0
      python/py_igl/py_slice.cpp
  100. 107 0
      python/py_igl/py_slice_into.cpp

+ 9 - 0
.gitignore

@@ -78,5 +78,14 @@ tutorial/XXX_test/main.cpp
 python/py_igl/todo
 python/build
 python/.idea
+untitled
+Untitled.ipynb
+python/.ipynb_checkpoints
+python/py_igl/todo
+python/__pycache__
+iglhelpers.pyc
+python/build2
 tests/build
 tests/bin
+python/build3
+*.pyc

+ 3 - 1
.gitmodules

@@ -3,7 +3,6 @@
 url=https://github.com/libigl/nanogui.git
         fetchRecursiveSubmodules = true
         ignore = dirty
-
 [submodule "external/embree"]
 	path = external/embree
 	url = https://github.com/embree/embree.git
@@ -11,3 +10,6 @@ url=https://github.com/libigl/nanogui.git
 [submodule "external/googletest"]
 	path = external/googletest
 	url = https://github.com/google/googletest.git
+[submodule "external/pybind11"]
+	path = external/pybind11
+	url = https://github.com/wjakob/pybind11.git

+ 4 - 4
README.md

@@ -23,7 +23,7 @@ just include igl headers (e.g. `#include <igl/cotmatrix.h>`) and run.  Each
 header file contains a single function (e.g. `igl/cotmatrix.h` contains
 `igl::cotmatrix()`). Most are tailored to operate on a generic triangle mesh
 stored in an n-by-3 matrix of vertex positions V and an m-by-3 matrix of
-triangle indices F. 
+triangle indices F.
 
 _Optionally_ the library may also be [pre-compiled](optional/) into a statically
 linked library, for faster compile times with your projects. This only effects
@@ -37,7 +37,7 @@ conversion table](matlab-to-eigen.html).
 ## Tutorial
 
 As of version 1.0, libigl includes an introductory
-[tutorial](tutorial/tutorial.html) that covers many functionalities.
+[tutorial](http://libigl.github.io/libigl/tutorial/tutorial.html) that covers many functionalities.
 
 ## Installation
 
@@ -135,7 +135,7 @@ 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.
 
-## Git Submodules 
+## Git Submodules
 Libigl uses git submodules for its _optional_ dependencies,
 in particular, those needed by the OpenGL viewer to run the examples in the
 [tutorial](tutorial/tutorial.html). Git submodules allow use to treat clones of
@@ -192,7 +192,7 @@ few labs/companies/institutions using libigl:
  - ETH Zurich, [Interactive Geometry Lab](http://igl.ethz.ch/) and [Advanced Technologies Lab](http://ait.inf.ethz.ch/), Swizterland
  - George Mason University, [CraGL](http://cs.gmu.edu/~ygingold/), USA
  - [Hong Kong University of Science and Technology](http://www.ust.hk/), USA
- - [National Institute of Informatics](http://www.nii.ac.jp/en/), Japan 
+ - [National Institute of Informatics](http://www.nii.ac.jp/en/), Japan
  - New York University, [Media Research Lab](http://mrl.nyu.edu/), USA
  - NYUPoly, [Game Innovation Lab](http://game.engineering.nyu.edu/), USA
  - [Telecom ParisTech](http://www.telecom-paristech.fr/en/formation-et-innovation-dans-le-numerique.html), Paris, France

+ 0 - 204
examples/quicklook-mesh/Info.plist

@@ -1,204 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>BuildMachineOSBuild</key>
-	<string>13E28</string>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>English</string>
-	<key>CFBundleDocumentTypes</key>
-	<array>
-		<dict>
-			<key>CFBundleTypeRole</key>
-			<string>QLGenerator</string>
-			<key>LSItemContentTypes</key>
-			<array>
-				<string>com.mesh.mesh</string>
-				<string>com.mesh.obj</string>
-				<string>com.mesh.off</string>
-				<string>com.mesh.ply</string>
-				<string>com.mesh.stl</string>
-				<string>com.mesh.wrl</string>
-			</array>
-		</dict>
-	</array>
-	<key>CFBundleExecutable</key>
-	<string>Mesh</string>
-	<key>CFBundleIdentifier</key>
-	<string>com.mesh.quicklook</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleName</key>
-	<string>Mesh</string>
-	<key>CFBundleShortVersionString</key>
-	<string>1.0.2</string>
-	<key>CFBundleVersion</key>
-	<string>1.0</string>
-	<key>CFPlugInDynamicRegisterFunction</key>
-	<string></string>
-	<key>CFPlugInDynamicRegistration</key>
-	<string>NO</string>
-	<key>CFPlugInFactories</key>
-	<dict>
-		<key>8D269336-626C-4F43-903F-D2F6AE5C4976</key>
-		<string>QuickLookGeneratorPluginFactory</string>
-	</dict>
-	<key>CFPlugInTypes</key>
-	<dict>
-		<key>5E2D9680-5022-40FA-B806-43349622E5B9</key>
-		<array>
-			<string>8D269336-626C-4F43-903F-D2F6AE5C4976</string>
-		</array>
-	</dict>
-	<key>CFPlugInUnloadFunction</key>
-	<string></string>
-	<key>DTCompiler</key>
-	<string>com.apple.compilers.llvm.clang.1_0</string>
-	<key>DTPlatformBuild</key>
-	<string>5B1008</string>
-	<key>DTPlatformVersion</key>
-	<string>GM</string>
-	<key>DTSDKBuild</key>
-	<string>13C64</string>
-	<key>DTSDKName</key>
-	<string>macosx10.9</string>
-	<key>DTXcode</key>
-	<string>0511</string>
-	<key>DTXcodeBuild</key>
-	<string>5B1008</string>
-	<key>LSApplicationCategoryType</key>
-	<string></string>
-	<key>NSHumanReadableCopyright</key>
-	<string>Copyright © 2015 Alec Jacobson</string>
-	<key>QLNeedsToBeRunInMainThread</key>
-	<true/>
-	<key>QLPreviewHeight</key>
-	<real>405</real>
-	<key>QLPreviewWidth</key>
-	<real>720</real>
-	<key>QLSupportsConcurrentRequests</key>
-	<true/>
-	<key>QLThumbnailMinimumSize</key>
-	<integer>10</integer>
-	<key>UTExportedTypeDeclarations</key>
-	<array>
-
-		<dict>
-			<key>UTTypeConformsTo</key>
-			<array>
-				<string>public.data</string>
-			</array>
-			<key>UTTypeDescription</key>
-			<string>3d tetrahedral mesh</string>
-			<key>UTTypeIdentifier</key>
-			<string>com.mesh.mesh</string>
-			<key>UTTypeReferenceURL</key>
-			<string>http://www.ann.jussieu.fr/frey/publications/RT-0253.pdf#page=33</string>
-			<key>UTTypeTagSpecification</key>
-			<dict>
-				<key>public.filename-extension</key>
-				<array>
-					<string>mesh</string>
-				</array>
-			</dict>
-		</dict>
-		<dict>
-			<key>UTTypeConformsTo</key>
-			<array>
-				<string>public.data</string>
-			</array>
-			<key>UTTypeDescription</key>
-			<string>3D model format</string>
-			<key>UTTypeIdentifier</key>
-			<string>com.mesh.obj</string>
-			<key>UTTypeReferenceURL</key>
-			<string>http://en.wikipedia.org/wiki/Wavefront_.obj_file#File_format</string>
-			<key>UTTypeTagSpecification</key>
-			<dict>
-				<key>public.filename-extension</key>
-				<array>
-					<string>obj</string>
-				</array>
-			</dict>
-		</dict>
-		<dict>
-			<key>UTTypeConformsTo</key>
-			<array>
-				<string>public.data</string>
-			</array>
-			<key>UTTypeDescription</key>
-			<string>PLY 3D file</string>
-			<key>UTTypeIdentifier</key>
-			<string>com.mesh.ply</string>
-			<key>UTTypeReferenceURL</key>
-			<string>http://en.wikipedia.org/wiki/PLY_%28file_format%29</string>
-			<key>UTTypeTagSpecification</key>
-			<dict>
-				<key>public.filename-extension</key>
-				<array>
-					<string>ply</string>
-				</array>
-			</dict>
-		</dict>
-		<dict>
-			<key>UTTypeConformsTo</key>
-			<array>
-				<string>public.data</string>
-			</array>
-			<key>UTTypeDescription</key>
-			<string>Stereolithography CAD model</string>
-			<key>UTTypeIdentifier</key>
-			<string>com.mesh.stl</string>
-			<key>UTTypeReferenceURL</key>
-			<string>http://en.wikipedia.org/wiki/STL_(file_format)</string>
-			<key>UTTypeTagSpecification</key>
-			<dict>
-				<key>public.filename-extension</key>
-				<array>
-					<string>stl</string>
-				</array>
-			</dict>
-		</dict>
-		<dict>
-			<key>UTTypeConformsTo</key>
-			<array>
-				<string>public.data</string>
-			</array>
-			<key>UTTypeDescription</key>
-			<string>Geomview's polyhedral file format</string>
-			<key>UTTypeIdentifier</key>
-			<string>com.mesh.off</string>
-			<key>UTTypeReferenceURL</key>
-			<string>http://tetgen.berlios.de/fformats.off.html</string>
-			<key>UTTypeTagSpecification</key>
-			<dict>
-				<key>public.filename-extension</key>
-				<array>
-					<string>off</string>
-				</array>
-			</dict>
-		</dict>
-		<dict>
-			<key>UTTypeConformsTo</key>
-			<array>
-				<string>public.data</string>
-			</array>
-			<key>UTTypeDescription</key>
-			<string>Virtual Reality Modeling Language</string>
-			<key>UTTypeIdentifier</key>
-			<string>com.mesh.wrl</string>
-			<key>UTTypeReferenceURL</key>
-			<string>http://en.wikipedia.org/wiki/VRML#WRL_File_Format</string>
-			<key>UTTypeTagSpecification</key>
-			<dict>
-				<key>public.filename-extension</key>
-				<array>
-					<string>wrl</string>
-				</array>
-			</dict>
-		</dict>
-
-	</array>
-</dict>
-</plist>
-

+ 0 - 89
examples/quicklook-mesh/Makefile

@@ -1,89 +0,0 @@
-.PHONY: all, install
-
-# Seems that we unfortunately must use llvm or else we get issues trying to
-# include the Foundation headers
-#CXX=llvm-g++
-#C=llvm-gcc
-CXX=clang++
-C=clang
-#CXX=clang++-mp-3.4
-#C=clang-mp-3.4
-CXXFLAGS += -stdlib=libc++ -std=c++11
-
-#Be sure that libs aren't used
-LIBIGL=../../
-LIBIGL_INC=-I$(LIBIGL)/include
-
-# Do not use the GLU that comes with the macports Mesa:
-# http://www.alecjacobson.com/weblog/?p=2827
-GLU=/usr/local/
-GLU_INC=-I$(GLU)/include
-#GLU_LIB=-L$(GLU)/lib -lGLU
-GLU_LIB=$(GLU)/lib/libGLU.a
-
-MESA=/opt/local/
-MESA_INC=-I$(MESA)/include
-MESA_LIB=-L$(MESA)/lib -lOSMesa -lGL
-
-OBJC_LIB=-lobjc
-
-all: obj Mesh.qlgenerator
-deploy:
-	dylibbundler -od -b -x ./Mesh.qlgenerator/Contents/MacOS/Mesh -d ./Mesh.qlgenerator/Contents/libs -p @loader_path/../libs/
-install:
-	rm -rf /Library/QuickLook/Mesh.qlgenerator
-	cp -R Mesh.qlgenerator /Library/QuickLook/Mesh.qlgenerator
-	qlmanage -r
-	qlmanage -r cache
-
-#CFLAGS += -Wall -g -O0
-# openmp is unfortunately not supported by llvm
-CFLAGS += -O3 -Wall -DNDEBUG -Winvalid-pch -m64 -msse4.2
-OBJCFLAGS += -O3 -Wall -DNDEBUG -Winvalid-pch -m64 -msse4.2
-
-CPP_FILES=$(wildcard src/*.cpp)
-C_FILES=$(wildcard src/*.c)
-M_FILES=$(wildcard src/*.m)
-OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) \
-  $(addprefix obj/,$(notdir $(M_FILES:.m=.o))) \
-  $(addprefix obj/,$(notdir $(C_FILES:.c=.o)))
-
-LIB+=$(LIBIGL_LIB) $(GLU_LIB) $(MESA_LIB) $(OBJC_LIB) -framework Foundation \
-  -framework AppKit -framework QuickLook -lc++
-INC+=$(EIGEN3_INC) $(LIBIGL_INC) $(GLU_INC) $(MESA_INC)
-
-.PHONY:
-
-Mesh.qlgenerator: Mesh.qlgenerator/Contents/MacOS/ \
-  Mesh.qlgenerator/Contents/Resources/ \
-  Mesh.qlgenerator/Contents/MacOS/Mesh \
-  Mesh.qlgenerator/Contents/Info.plist
-
-Mesh.qlgenerator/Contents/Info.plist: Info.plist
-	cp Info.plist Mesh.qlgenerator/Contents/Info.plist
-
-Mesh.qlgenerator/Contents/MacOS/:
-	mkdir -p $@
-
-Mesh.qlgenerator/Contents/Resources/:
-	mkdir -p $@
-
-Mesh.qlgenerator/Contents/MacOS/Mesh: $(OBJ_FILES)
-	${CXX} $(CFLAGS) $(CXXFLAGS) -bundle -o $@ $(OBJ_FILES) $(LIB)
-	#dylibbundler -od -b -x ./Mesh.qlgenerator/Contents/MacOS/Mesh -d ./Mesh.qlgenerator/Contents/libs/
-
-obj:
-	mkdir -p obj
-
-obj/%.o: src/%.cpp src/%.h
-	${CXX} $(CFLAGS) $(CXXFLAGS) -o $@ -c $< $(INC) 
-
-obj/%.o: src/%.m
-	${CXX} $(OBJCFLAGS) -o $@ -c $< $(INC)
-
-obj/%.o: src/%.c
-	${C} $(CFLAGS) -o $@ -c $< $(INC)
-
-clean:
-	rm -f $(OBJ_FILES)
-	rm -rf Mesh.qlgenerator

+ 0 - 41
examples/quicklook-mesh/README

@@ -1,41 +0,0 @@
-This is a small application which builds a "QuickLook generator" for Mac OS.
-This will generate previews (selecting a file in Finder and hitting space) and
-thumbnails ("Cover flow" view in Finder) for .obj, .off and .mesh 3D model
-files.
-
-To build issue:
-
-    make
-
-This will compile the source and build the application in ./Mesh.qlgenerator/
-
-To install issue:
-
-    sudo make install
-
-This will copy the directory ./Mesh.qlgenerator/ into /Library/QuickLook/ and
-reload the Quicklook Manager (so that you see your changes in Finder).
-
-= Dependencies =
-
-Install Mesa3D using macports. 
-
-    sudo port install mesa
-
-Then re-install GLU à la http://www.alecjacobson.com/weblog/?p=2827
-
-= Testing =
-
-After installing you can test previews with:
-
-    /usr/bin/qlmanage -p ../shared/cheburashka.off
-
-and thumbnails with:
-
-    /usr/bin/qlmanage -t ../shared/cheburashka.off
-
-= Note about Mesa =
-
-If things look weird (too far away, blank, etc.) then maybe you should
-reinstall GLU. It seems that the version of GLU that comes with macports' mesa
-is buggy/corrupted.

+ 0 - 94
examples/quicklook-mesh/src/GeneratePreviewForURL.m

@@ -1,94 +0,0 @@
-// Adapted from QuickLook-pfm-master/src/GeneratePreviewForURL.m by Andreas
-// Steinel (https://github.com/lnxbil/quicklook-pfm)
-#import <CoreFoundation/CoreFoundation.h>
-#import <CoreServices/CoreServices.h>
-#import <QuickLook/QuickLook.h>
-#import <Foundation/Foundation.h>
-#import <AppKit/NSImage.h>
-
-#include "render_to_buffer.h"
-
-// Generate a preview of a given file.
-OSStatus GeneratePreviewForURL(
-  void *thisInterface, 
-  QLPreviewRequestRef preview, 
-  CFURLRef url, 
-  CFStringRef contentTypeUTI, 
-  CFDictionaryRef options)
-{
-    if (QLPreviewRequestIsCancelled(preview))
-        return noErr;
-    
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    
-    CFStringRef file = CFURLCopyFileSystemPath(url,kCFURLPOSIXPathStyle);
-    if (QLPreviewRequestIsCancelled(preview))
-        return noErr;
-    // http://stackoverflow.com/a/3797923/148668
-    // Multi-sampling for anti-aliasing.
-    const double MS = 2;
-    const int width = 720;
-    const int height = 405;
-    const int bwidth = MS*width;
-    const int bheight = MS*height;
-    const int bchannels = 4;
-    UInt8 buffer[bwidth * bheight * bchannels];
-
-    const char *cs = CFStringGetCStringPtr( file, CFStringGetSystemEncoding()) ;
-    char cs_buf[1024];
-    // http://stackoverflow.com/a/1609664/148668
-    if(cs == NULL)
-    {
-      CFStringGetCString(
-        file, 
-        cs_buf, 
-        [(NSString*)file length]+1, 
-        kCFStringEncodingUTF8);
-      cs = cs_buf;
-    }
-
-    const float TRANSPARENT_BLACK[4] = {0,0,0,0};
-    render_to_buffer(cs,TRANSPARENT_BLACK,bwidth,bheight,buffer);
-    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
-    CFDataRef rgbData = CFDataCreate(NULL, buffer, bwidth * bheight * 4);
-    CGDataProviderRef provider = CGDataProviderCreateWithCFData(rgbData);
-    // http://forum.sparrow-framework.org/topic/create-uiimage-from-pixel-data-problems
-    CGImageRef image = 
-      CGImageCreate(
-        bwidth, 
-        bheight, 
-        8, 
-        8*4, 
-        bwidth * 4, 
-        colorspace, 
-        kCGBitmapByteOrderDefault|kCGImageAlphaPremultipliedLast, 
-        provider, 
-        NULL, 
-        true, 
-        kCGRenderingIntentDefault); 
-    CFRelease(rgbData);
-    CGDataProviderRelease(provider);
-    CGColorSpaceRelease(colorspace);
-    NSSize size = {width,height};
-
-    if (QLPreviewRequestIsCancelled(preview))
-        return noErr;
-
-    // Draw onto context as textured rectangle
-    CGContextRef cgContext = QLPreviewRequestCreateContext(preview, *(CGSize *)&size, true, NULL);
-    CGRect rect = CGRectMake(0,0, width, height);
-    CGContextDrawImage(cgContext, rect, image);
-    QLPreviewRequestFlushContext(preview, cgContext);
-
-    CFRelease(cgContext);
-    CGImageRelease(image);
-    [pool release];
-    return noErr;
-}
-
-
-void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview)
-{
-    // implement only if supported
-}
-

+ 0 - 164
examples/quicklook-mesh/src/GenerateThumbnailForURL.m

@@ -1,164 +0,0 @@
-// Adapted from QuickLook-pfm-master/src/GenerateThumbnailForURL.m by Andreas
-// Steinel (https://github.com/lnxbil/quicklook-pfm)
-#import <CoreFoundation/CoreFoundation.h>
-#import <CoreServices/CoreServices.h>
-#import <QuickLook/QuickLook.h>
-#import <Foundation/Foundation.h>
-#import <AppKit/NSImage.h>
-
-#include "render_to_buffer.h"
-
-// Creates a bitmap context for ARGB images (not sure if we really need a
-// separate function for this... I think there should be something builtin that
-// works just as well)
-// Taken from https://github.com/lnxbil/quicklook-pfm
-CGContextRef CreateARGBBitmapContext (CGSize size)
-{
-    CGContextRef    context = NULL;
-    CGColorSpaceRef colorSpace;
-    void *          bitmapData;
-    int             bitmapByteCount;
-    int             bitmapBytesPerRow;
-    
-    // Get image width, height. We'll use the entire image.
-    size_t pixelsWide = (size_t) size.width; //CGImageGetWidth(inImage);
-    size_t pixelsHigh = (size_t) size.height; //CGImageGetHeight(inImage);
-    
-    // Declare the number of bytes per row. Each pixel in the bitmap in this
-    // example is represented by 4 bytes; 8 bits each of red, green, blue, and
-    // alpha.
-    bitmapBytesPerRow   = (pixelsWide * 4);
-    bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
-    
-    // Use the generic RGB color space.
-    // FIXME: Das verstehe ich net. Die Doku sagt nicht, dass es Deprecated ist und
-    //        gibt auch keine Auswahlmöglichkeit an :-(
-    colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
-    if (colorSpace == NULL)
-    {
-        NSLog(@"Error allocating color space\n");
-        return NULL;
-    }
-    
-    // Allocate memory for image data. This is the destination in memory
-    // where any drawing to the bitmap context will be rendered.
-    bitmapData = malloc( bitmapByteCount );
-    if (bitmapData == NULL) 
-    {
-        NSLog(@"Memory not allocated!");
-        CGColorSpaceRelease( colorSpace );
-        return NULL;
-    }
-    
-    // Create the bitmap context. We want pre-multiplied ARGB, 8-bits 
-    // per component. Regardless of what the source image format is 
-    // (CMYK, Grayscale, and so on) it will be converted over to the format
-    // specified here by CGBitmapContextCreate.
-    context = CGBitmapContextCreate (bitmapData,
-                                     pixelsWide,
-                                     pixelsHigh,
-                                     8,      // bits per component
-                                     bitmapBytesPerRow,
-                                     colorSpace,
-                                     kCGBitmapByteOrderDefault|kCGImageAlphaPremultipliedLast);
-    if (context == NULL)
-    {
-        free (bitmapData);
-        NSLog(@"Context not created!");
-    }
-    
-    // Make sure and release colorspace before returning
-    CGColorSpaceRelease( colorSpace );
-    
-    return context;
-}
-
-
-
-
-// Generate a thumbnail for a given file
-OSStatus GenerateThumbnailForURL(
-  void *thisInterface, 
-  QLThumbnailRequestRef thumbnail, 
-  CFURLRef url, 
-  CFStringRef contentTypeUTI, 
-  CFDictionaryRef options, 
-  CGSize maxSize)
-{
-    if (QLThumbnailRequestIsCancelled(thumbnail))
-        return noErr;
-    
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    
-    CFStringRef file = CFURLCopyFileSystemPath(url,kCFURLPOSIXPathStyle);
-    
-    if (QLThumbnailRequestIsCancelled(thumbnail))
-        return noErr;
-
-    // raw pixel data memory of 64 * 64 pixel size
-    // http://stackoverflow.com/a/3797923/148668
-    // Multi-sampling for anti-aliasing
-    const double MS = 2;
-    const int width = maxSize.width;
-    // Widescreen aspect ratio
-    const int height = (270./460.)*maxSize.height;
-    const int bwidth = MS*width;
-    const int bheight = MS*height;
-    const int bchannels = 4;
-    UInt8 buffer[bwidth * bheight * bchannels];
-    const char *cs = CFStringGetCStringPtr( file, CFStringGetSystemEncoding()) ;
-    char cs_buf[1024];
-    // http://stackoverflow.com/a/1609664/148668
-    if(cs == NULL)
-    {
-      CFStringGetCString(file, cs_buf, [(NSString*)file length]+1, kCFStringEncodingUTF8);
-      cs = cs_buf;
-    }
-    const float OPAQUE_WHITE[4] = {1,1,1,1};
-    render_to_buffer(cs,OPAQUE_WHITE,bwidth,bheight,buffer);
-    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
-    CFDataRef rgbData = CFDataCreate(NULL, buffer, bwidth * bheight * 4);
-    CGDataProviderRef provider = CGDataProviderCreateWithCFData(rgbData);
-    // http://forum.sparrow-framework.org/topic/create-uiimage-from-pixel-data-problems
-    CGImageRef image = CGImageCreate(
-      bwidth,
-      bheight,
-      8,
-      8*4,
-      bwidth * 4,
-      colorspace,
-      kCGBitmapByteOrderDefault|kCGImageAlphaPremultipliedLast,
-      provider,
-      NULL,
-      true,
-      kCGRenderingIntentDefault); 
-    CFRelease(rgbData);
-    CGDataProviderRelease(provider);
-    CGColorSpaceRelease(colorspace);
-    NSSize size = {width,height};
-    
-    if (QLThumbnailRequestIsCancelled(thumbnail))
-        return noErr;
-
-    // Draw onto context as textured rectangle
-    CGContextRef cgctx = CreateARGBBitmapContext(size);
-    CGRect rect = CGRectMake(0,0, width, height);
-    CGContextClearRect(cgctx,rect);
-    CGContextDrawImage(cgctx, rect, image); 
-    CGImageRef newCGImage = CGBitmapContextCreateImage(cgctx);
-    CGContextRelease(cgctx);
-    
-    QLThumbnailRequestSetImage(thumbnail, newCGImage, NULL);
-    
-    // Releasing image
-    CGImageRelease(newCGImage);
-    [pool release];
-    return noErr;
-}
-
-
-void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail)
-{
-    // implement only if supported
-}
-

+ 0 - 218
examples/quicklook-mesh/src/main.c

@@ -1,218 +0,0 @@
-//==============================================================================
-//
-//	DO NO MODIFY THE CONTENT OF THIS FILE
-//
-//	This file contains the generic CFPlug-in code necessary for your generator
-//	To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c
-//
-//==============================================================================
-
-
-
-
-
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreFoundation/CFPlugInCOM.h>
-#include <CoreServices/CoreServices.h>
-#include <QuickLook/QuickLook.h>
-
-// -----------------------------------------------------------------------------
-//	constants
-// -----------------------------------------------------------------------------
-
-// Don't modify this line
-#define PLUGIN_ID "C00EB589-55DF-45ED-B4B8-8AFFA367CFCF"
-
-//
-// Below is the generic glue code for all plug-ins.
-//
-// You should not have to modify this code aside from changing
-// names if you decide to change the names defined in the Info.plist
-//
-
-
-// -----------------------------------------------------------------------------
-//	typedefs
-// -----------------------------------------------------------------------------
-
-// The thumbnail generation function to be implemented in GenerateThumbnailForURL.c
-OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
-void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
-
-// The preview generation function to be implemented in GeneratePreviewForURL.c
-OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
-void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
-
-// The layout for an instance of QuickLookGeneratorPlugIn
-typedef struct __QuickLookGeneratorPluginType
-{
-    void        *conduitInterface;
-    CFUUIDRef    factoryID;
-    UInt32       refCount;
-} QuickLookGeneratorPluginType;
-
-// -----------------------------------------------------------------------------
-//	prototypes
-// -----------------------------------------------------------------------------
-//	Forward declaration for the IUnknown implementation.
-//
-
-QuickLookGeneratorPluginType  *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID);
-void                         DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance);
-HRESULT                      QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
-void                        *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
-ULONG                        QuickLookGeneratorPluginAddRef(void *thisInstance);
-ULONG                        QuickLookGeneratorPluginRelease(void *thisInstance);
-
-// -----------------------------------------------------------------------------
-//	myInterfaceFtbl	definition
-// -----------------------------------------------------------------------------
-//	The QLGeneratorInterfaceStruct function table.
-//
-static QLGeneratorInterfaceStruct myInterfaceFtbl = {
-    NULL,
-    QuickLookGeneratorQueryInterface,
-    QuickLookGeneratorPluginAddRef,
-    QuickLookGeneratorPluginRelease,
-    NULL,
-    NULL,
-    NULL,
-    NULL
-};
-
-
-// -----------------------------------------------------------------------------
-//	AllocQuickLookGeneratorPluginType
-// -----------------------------------------------------------------------------
-//	Utility function that allocates a new instance.
-//      You can do some initial setup for the generator here if you wish
-//      like allocating globals etc...
-//
-QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID)
-{
-    QuickLookGeneratorPluginType *theNewInstance;
-
-    theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType));
-    memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType));
-
-        /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */
-    theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct));
-    memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct));
-
-        /*  Retain and keep an open instance refcount for each factory. */
-    theNewInstance->factoryID = CFRetain(inFactoryID);
-    CFPlugInAddInstanceForFactory(inFactoryID);
-
-        /* This function returns the IUnknown interface so set the refCount to one. */
-    theNewInstance->refCount = 1;
-    return theNewInstance;
-}
-
-// -----------------------------------------------------------------------------
-//	DeallocQuickLookGeneratorPluginType
-// -----------------------------------------------------------------------------
-//	Utility function that deallocates the instance when
-//	the refCount goes to zero.
-//      In the current implementation generator interfaces are never deallocated
-//      but implement this as this might change in the future
-//
-void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance)
-{
-    CFUUIDRef theFactoryID;
-
-    theFactoryID = thisInstance->factoryID;
-        /* Free the conduitInterface table up */
-    free(thisInstance->conduitInterface);
-
-        /* Free the instance structure */
-    free(thisInstance);
-    if (theFactoryID){
-        CFPlugInRemoveInstanceForFactory(theFactoryID);
-        CFRelease(theFactoryID);
-    }
-}
-
-// -----------------------------------------------------------------------------
-//	QuickLookGeneratorQueryInterface
-// -----------------------------------------------------------------------------
-//	Implementation of the IUnknown QueryInterface function.
-//
-HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
-{
-    CFUUIDRef interfaceID;
-
-    interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
-
-    if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){
-            /* If the Right interface was requested, bump the ref count,
-             * set the ppv parameter equal to the instance, and
-             * return good status.
-             */
-        ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL;
-        ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration;
-        ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL;
-        ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration;
-        ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance);
-        *ppv = thisInstance;
-        CFRelease(interfaceID);
-        return S_OK;
-    }else{
-        /* Requested interface unknown, bail with error. */
-        *ppv = NULL;
-        CFRelease(interfaceID);
-        return E_NOINTERFACE;
-    }
-}
-
-// -----------------------------------------------------------------------------
-// QuickLookGeneratorPluginAddRef
-// -----------------------------------------------------------------------------
-//	Implementation of reference counting for this type. Whenever an interface
-//	is requested, bump the refCount for the instance. NOTE: returning the
-//	refcount is a convention but is not required so don't rely on it.
-//
-ULONG QuickLookGeneratorPluginAddRef(void *thisInstance)
-{
-    ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1;
-    return ((QuickLookGeneratorPluginType*) thisInstance)->refCount;
-}
-
-// -----------------------------------------------------------------------------
-// QuickLookGeneratorPluginRelease
-// -----------------------------------------------------------------------------
-//	When an interface is released, decrement the refCount.
-//	If the refCount goes to zero, deallocate the instance.
-//
-ULONG QuickLookGeneratorPluginRelease(void *thisInstance)
-{
-    ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1;
-    if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){
-        DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance );
-        return 0;
-    }else{
-        return ((QuickLookGeneratorPluginType*) thisInstance )->refCount;
-    }
-}
-
-// -----------------------------------------------------------------------------
-//  QuickLookGeneratorPluginFactory
-// -----------------------------------------------------------------------------
-void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
-{
-    QuickLookGeneratorPluginType *result;
-    CFUUIDRef                 uuid;
-
-        /* If correct type is being requested, allocate an
-         * instance of kQLGeneratorTypeID and return the IUnknown interface.
-         */
-    if (CFEqual(typeID,kQLGeneratorTypeID)){
-        uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
-        result = AllocQuickLookGeneratorPluginType(uuid);
-        CFRelease(uuid);
-        return result;
-    }
-        /* If the requested type is incorrect, return NULL. */
-    return NULL;
-}
-

+ 0 - 504
examples/quicklook-mesh/src/render_to_buffer.cpp

@@ -1,504 +0,0 @@
-// This required to get correct linking with Objective-C files
-extern "C" {
-#include "render_to_buffer.h"
-};
-#include <igl/per_face_normals.h>
-#include <igl/normalize_row_lengths.h>
-#include <igl/get_seconds.h>
-#include <igl/draw_mesh.h>
-#include <igl/draw_floor.h>
-#include <igl/material_colors.h>
-#include <igl/pathinfo.h>
-#include <igl/readOBJ.h>
-#include <igl/readPLY.h>
-#include <igl/readSTL.h>
-#include <igl/readWRL.h>
-#include <igl/polygon_mesh_to_triangle_mesh.h>
-#include <igl/readOFF.h>
-#include <igl/readMESH.h>
-#include <igl/boundary_facets.h>
-#include <igl/barycenter.h>
-#include <igl/doublearea.h>
-#include <igl/EPS.h>
-#include <igl/Camera.h>
-#include <igl/canonical_quaternions.h>
-#include <igl/quat_to_mat.h>
-#include <igl/Viewport.h>
-
-#include <Eigen/Core>
-#include <GL/glu.h>
-
-#include <algorithm>
-
-static int width,height;
-static Eigen::MatrixXd V,N;
-static Eigen::MatrixXi F;
-static Eigen::Vector3d Vmean, Vmax,Vmin;
-//static bool invert = false;
-static float background_color[4] = {0,0,0,1};
-
-// Small viewports struct for keeping track of size and camera info
-#define NUM_VIEWPORTS 6
-class AugViewport : public igl::Viewport
-{
-  public:
-    igl::Camera camera;
-} viewports[NUM_VIEWPORTS];
-
-// Red screen for errors
-void red(const int width, const int height, GLubyte * buffer)
-{
-  for(int h = 0;h<height;h++)
-  {
-    for(int w = 0;w<width;w++)
-    {
-      for(int c = 0;c<4;c++)
-      {
-        if(c == 0 || c==3)
-        {
-          buffer[c+4*w+4*width*h] = 255;
-        }else
-        {
-          buffer[c+4*w+4*width*h] = 0;
-        }
-      }
-    }
-  }
-}
-
-// Initialize the viewport angles and camera rotations
-void init_viewports()
-{
-  using namespace igl;
-  using namespace std;
-  for(auto & vp : viewports)
-  {
-    // Reset. I guess Mac is keeping global variables alive...
-    vp.camera = Camera();
-    vp.camera.push_away(3.);
-    vp.camera.dolly_zoom(10.-vp.camera.m_angle);
-  }
-  // Above view
-  double XZ_PLANE_QUAT_D_FLIP[4];
-  copy(XZ_PLANE_QUAT_D,XZ_PLANE_QUAT_D+4,XZ_PLANE_QUAT_D_FLIP);
-  XZ_PLANE_QUAT_D_FLIP[0] *= -1.0;
-  // Straight on
-  copy(
-    XY_PLANE_QUAT_D,
-    XY_PLANE_QUAT_D+4,
-    viewports[0].camera.m_rotation_conj.coeffs().data());
-  // Left side view
-  copy(
-    CANONICAL_VIEW_QUAT_D[9],
-    CANONICAL_VIEW_QUAT_D[9]+4,
-    viewports[1].camera.m_rotation_conj.coeffs().data());
-  copy(
-    CANONICAL_VIEW_QUAT_D[14],
-    CANONICAL_VIEW_QUAT_D[14]+4,
-    viewports[2].camera.m_rotation_conj.coeffs().data());
-  // Straight on
-  copy(
-    CANONICAL_VIEW_QUAT_D[4],
-    CANONICAL_VIEW_QUAT_D[4]+4,
-    viewports[3].camera.m_rotation_conj.coeffs().data());
-  copy(
-    XZ_PLANE_QUAT_D,
-    XZ_PLANE_QUAT_D+4,
-    viewports[4].camera.m_rotation_conj.coeffs().data());
-  copy(
-    XZ_PLANE_QUAT_D_FLIP,
-    XZ_PLANE_QUAT_D_FLIP+4,
-    viewports[5].camera.m_rotation_conj.coeffs().data());
-}
-
-// Viewports are arranged to see all sides
-//
-// /-----.-----.-----\
-// |  3  |  2  |  1  |
-// -------------------
-// |  4  |           |
-// -------     0     |
-// |  5  |           |
-// \-----.-----------/
-void reshape_viewports()
-{
-  using namespace igl;
-  using namespace std;
-  viewports[0].reshape(1./3.*width,            0,2./3.*width,2./3.*height);
-  viewports[1].reshape(2./3.*width, 2./3.*height,1./3.*width,1./3.*height);
-  viewports[2].reshape(1./3.*width, 2./3.*height,1./3.*width,1./3.*height);
-  viewports[3].reshape(          0, 2./3.*height,1./3.*width,1./3.*height);
-  viewports[4].reshape(          0, 1./3.*height,1./3.*width,1./3.*height);
-  viewports[5].reshape(          0,            0,1./3.*width,1./3.*height);
-  for(auto & vp : viewports)
-  {
-    vp.camera.m_aspect = (double)vp.width/(double)vp.height;
-  }
-}
-
-void reshape(int width, int height)
-{
-  using namespace std;
-  ::width = width;
-  ::height = height;
-  reshape_viewports();
-}
-
-// Simple two-sided, diffuse-only light
-void lights()
-{
-  using namespace std;
-  glEnable(GL_LIGHTING);
-  glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
-  glEnable(GL_LIGHT0);
-  glEnable(GL_LIGHT1);
-  float WHITE[4] =  {0.8,0.8,0.8,1.};
-  float GREY[4] =  {0.4,0.4,0.4,1.};
-  float BLACK[4] =  {0.,0.,0.,1.};
-  float pos[4];
-  float light_pos[4] = {0.1,0.1,1.0,0.0};
-  copy(light_pos,light_pos+4,pos);
-  glLightfv(GL_LIGHT0,GL_AMBIENT,GREY);
-  glLightfv(GL_LIGHT0,GL_DIFFUSE,WHITE);
-  glLightfv(GL_LIGHT0,GL_SPECULAR,BLACK);
-  glLightfv(GL_LIGHT0,GL_POSITION,pos);
-  pos[0] *= -1;
-  pos[1] *= -1;
-  pos[2] *= -1;
-  glLightfv(GL_LIGHT1,GL_AMBIENT,GREY);
-  glLightfv(GL_LIGHT1,GL_DIFFUSE,WHITE);
-  glLightfv(GL_LIGHT1,GL_SPECULAR,BLACK);
-  glLightfv(GL_LIGHT1,GL_POSITION,pos);
-}
-
-// Push scene based on viewport
-void push_scene(const AugViewport & vp)
-{
-  using namespace igl;
-  using namespace std;
-  glMatrixMode(GL_PROJECTION);
-  glPushMatrix();
-  glLoadIdentity();
-  auto & camera = vp.camera;
-  glMultMatrixd(camera.projection().data());
-  glMatrixMode(GL_MODELVIEW);
-  glPushMatrix();
-  glLoadIdentity();
-  // -1 because buffer y-coordinates are flipped
-  gluLookAt(
-    camera.eye()(0), camera.eye()(1), camera.eye()(2),
-    camera.at()(0), camera.at()(1), camera.at()(2),
-    camera.up()(0), -1*camera.up()(1), camera.up()(2));
-}
-// Scale and shift for object so that it fits current view
-void push_object(const AugViewport & vp)
-{
-  using namespace Eigen;
-  glPushMatrix();
-  Matrix3d m = vp.camera.m_rotation_conj.matrix();
-  Vector3d eff_Vmax  = m*Vmax;
-  Vector3d eff_Vmin  = m*Vmin;
-  Vector3d eff_Vmean = m*Vmean;
-  const double dy = fabs(eff_Vmax(1,0)-eff_Vmin(1,0));
-  const double dx = fabs(eff_Vmax(0,0)-eff_Vmin(0,0));
-  //const double dz = fabs(eff_Vmax(2,0)-eff_Vmin(2,0));
-  // Assumes height < width
-  const double sx = dx*(double)height/(double)width;
-  const double sy = dy;
-  const double s = 2./(sy > sx ? sy : sx);
-  glScaled(s,s,s);
-  glTranslated(-Vmean(0,0),-Vmean(1,0),-Vmean(2,0));
-  // Hack. Should really just figure out max scale so that full model fits on
-  // screen with given perspective.
-  //const double dz_off = (dz > 2.*dy && dz > 2.*dx ? dz/2. : 0);
-  //glTranslated(0,0,-dz_off);
-}
-
-void pop_object()
-{
-  glPopMatrix();
-}
-
-void pop_scene()
-{
-  glMatrixMode(GL_PROJECTION);
-  glPopMatrix();
-  glMatrixMode(GL_MODELVIEW);
-  glPopMatrix();
-}
-
-void display()
-{
-  using namespace std;
-  using namespace igl;
-  glClearColor(
-    background_color[0],
-    background_color[1],
-    background_color[2],
-    background_color[3]);
-  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-  glEnable(GL_DEPTH_TEST);
-  glEnable(GL_NORMALIZE);
-  glDisable(GL_CULL_FACE);
-  glCullFace(GL_BACK);
-
-  // "Flash light" attached to camera
-  lights();
-  // Draw for each viewport
-  for(int vp = 0;vp<NUM_VIEWPORTS;vp++)
-  {
-    glViewport(
-      viewports[vp].x,
-      viewports[vp].y,
-      viewports[vp].width,
-      viewports[vp].height);
-    push_scene(viewports[vp]);
-    push_object(viewports[vp]);
-
-    // Draw the mesh, inverted if need be.
-    // Set material properties
-    glDisable(GL_COLOR_MATERIAL);
-    //if(invert)
-    //{
-    //  glFrontFace(GL_CW);
-    //  glMaterialfv(GL_FRONT, GL_AMBIENT,  CYAN_AMBIENT);
-    //  glMaterialfv(GL_FRONT, GL_DIFFUSE,  CYAN_DIFFUSE  );
-    //  glMaterialfv(GL_FRONT, GL_SPECULAR, CYAN_SPECULAR);
-    //  glMaterialf (GL_FRONT, GL_SHININESS, 128);
-    //  glMaterialfv(GL_BACK, GL_AMBIENT,  SILVER_AMBIENT);
-    //  glMaterialfv(GL_BACK, GL_DIFFUSE,  FAST_RED_DIFFUSE);
-    //  glMaterialfv(GL_BACK, GL_SPECULAR, SILVER_SPECULAR);
-    //  glMaterialf (GL_BACK, GL_SHININESS, 128);
-    //}else
-    //{
-      glMaterialfv(GL_FRONT, GL_AMBIENT,  GOLD_AMBIENT);
-      glMaterialfv(GL_FRONT, GL_DIFFUSE,  GOLD_DIFFUSE  );
-      glMaterialfv(GL_FRONT, GL_SPECULAR, GOLD_SPECULAR);
-      glMaterialf (GL_FRONT, GL_SHININESS, 128);
-      glMaterialfv(GL_BACK, GL_AMBIENT,  SILVER_AMBIENT);
-      glMaterialfv(GL_BACK, GL_DIFFUSE,  FAST_GREEN_DIFFUSE  );
-      glMaterialfv(GL_BACK, GL_SPECULAR, SILVER_SPECULAR);
-      glMaterialf (GL_BACK, GL_SHININESS, 128);
-    //}
-    if(F.rows() == 0)
-    {
-      glPointSize(1.+ 20./log10(V.rows()));
-      const bool has_normals = N.rows() == V.rows();
-      glBegin(GL_POINTS);
-      for(int v = 0;v<V.rows();v++)
-      {
-        if(has_normals)
-        {
-          glNormal3d(N(v,0),N(v,1),N(v,2));
-        }
-        glVertex3d(V(v,0),V(v,1),V(v,2));
-      }
-      glEnd();
-    }else
-    {
-      draw_mesh(V,F,N);
-    }
-    //if(invert)
-    //{
-    //  glFrontFace(GL_CCW);
-    //}
-    pop_object();
-
-    // Draw a nice floor unless we're looking from beneath it
-    if(vp != 4)
-    {
-      glPushMatrix();
-      glTranslated(0,-1,0);
-      glScaled(4,4,4);
-      draw_floor();
-      glPopMatrix();
-    }
-
-    pop_scene();
-  }
-
-  // Screen space
-  glDisable(GL_DEPTH_TEST);
-  glDisable(GL_LIGHTING);
-  glViewport(0,0,width,height);
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
-  gluOrtho2D(0,width,0,height);
-  glMatrixMode(GL_MODELVIEW);
-  glLoadIdentity();
-
-  // Draw separation lines between (around) viewports
-  const double BAR_THICKNESS = 3.0;
-  glColor3f(0.5,0.5,0.5);
-  for(int vp = 0;vp<NUM_VIEWPORTS;vp++)
-  {
-    glLineWidth(BAR_THICKNESS);
-    glBegin(GL_LINE_STRIP);
-    glVertex2f(viewports[vp].x,viewports[vp].y);
-    glVertex2f(viewports[vp].x+viewports[vp].width,viewports[vp].y);
-    glVertex2f(viewports[vp].x+viewports[vp].width,viewports[vp].y+viewports[vp].height);
-    glVertex2f(                    viewports[vp].x,viewports[vp].y+viewports[vp].height);
-    glEnd();
-  }
-
-  glFinish();
-}
-
-
-bool render_to_buffer(
-  const char * filename,
-  const float * background_color,
-  const int width,
-  const int height,
-  GLubyte * buffer)
-{
-  using namespace igl;
-  using namespace std;
-  using namespace Eigen;
-  double ts = get_seconds();
-
-  copy(background_color,background_color+4,::background_color);
-
-  // Read and prepare mesh
-  // dirname, basename, extension and filename
-  string d,b,ext,f;
-  pathinfo(filename,d,b,ext,f);
-  // Convert extension to lower case
-  transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
-  vector<vector<double > > vV,vN,vTC;
-  vector<vector<int > > vF,vFTC,vFN;
-  if(ext == "obj")
-  {
-    // Convert extension to lower case
-    if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN))
-    {
-      cerr<<"readOBJ failed."<<endl;
-      red(width,height,buffer);
-      return false;
-    }
-  }else if(ext == "off")
-  {
-    // Convert extension to lower case
-    if(!igl::readOFF(filename,vV,vF,vN))
-    {
-      cerr<<"readOFF failed."<<endl;
-      red(width,height,buffer);
-      return false;
-    }
-  }else if(ext == "wrl")
-  {
-    // Convert extension to lower case
-    if(!igl::readWRL(filename,vV,vF))
-    {
-      red(width,height,buffer);
-      return false;
-    }
-  }else if(ext == "ply")
-  {
-    // Convert extension to lower case
-    if(!igl::readPLY(filename,vV,vF,vN,vTC))
-    {
-      red(width,height,buffer);
-      return false;
-    }
-  }else if(ext == "stl")
-  {
-    // Convert extension to lower case
-    if(!igl::readSTL(filename,vV,vF,vN))
-    {
-      red(width,height,buffer);
-      return false;
-    }
-  }else
-  {
-    // Convert extension to lower case
-    MatrixXi T;
-    if(!igl::readMESH(filename,V,T,F))
-    {
-      red(width,height,buffer);
-      return false;
-    }
-    //if(F.size() > T.size() || F.size() == 0)
-    {
-      boundary_facets(T,F);
-    }
-  }
-  if(vV.size() > 0)
-  {
-    if(!list_to_matrix(vV,V))
-    {
-      cerr<<"list_to_matrix failed."<<endl;
-      red(width,height,buffer);
-      return false;
-    }
-    if(!list_to_matrix(vN,N))
-    {
-      // silently continue
-      N.resize(0,0);
-    }
-    polygon_mesh_to_triangle_mesh(vF,F);
-  }
-  cout<<"IO: "<<(get_seconds()-ts)<<"s"<<endl;
-  ts = get_seconds();
-
-  // Compute already normalized per triangle normals
-  if(N.rows() != V.rows() && N.rows() != F.rows())
-  {
-    per_face_normals(V,F,N);
-  }
-  //Vmean = 0.5*(V.colwise().maxCoeff()+V.colwise().minCoeff());
-  Vmax = V.colwise().maxCoeff();
-  Vmin = V.colwise().minCoeff();
-  Vmean = 0.5*(Vmax + Vmin);
-
-  //// Figure out if normals should be flipped (hopefully this is never a
-  //// bottleneck)
-  //MatrixXd BC;
-  //VectorXd dblA;
-  //barycenter(V,F,BC);
-  //BC.col(0).array() -= Vmean(0,0);
-  //BC.col(1).array() -= Vmean(1,0);
-  //BC.col(2).array() -= Vmean(2,0);
-  //doublearea(V,F,dblA);
-  //VectorXd BCDN = (BC.array() * N.array()).rowwise().sum();
-  //const double tot_dp = dblA.transpose() * BCDN;
-  //invert = tot_dp < 0;
-  //cout<<"Normals: "<<(get_seconds()-ts)<<"s"<<endl;
-  //ts = get_seconds();
-
-  // Initialize MESA
-  OSMesaContext ctx;
-  /* Create an RGBA-mode context */
-#  if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
-  /* specify Z, stencil, accum sizes */
-  ctx = OSMesaCreateContextExt( OSMESA_RGBA, 32, 0, 0, NULL );
-#  else
-  ctx = OSMesaCreateContext( OSMESA_RGBA, NULL );
-#  endif
-  if (!ctx)
-  {
-    fprintf(stderr,"OSMesaCreateContext failed!\n");
-    red(width,height,buffer);
-    return false;
-  }
-
-  /* Bind the buffer to the context and make it current */
-  if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, width, height))
-  {
-    fprintf(stderr,"OSMesaMakeCurrent failed!\n");
-    red(width,height,buffer);
-    return false;
-  }
-
-  // Render
-  init_viewports();
-  reshape(width,height);
-  display();
-  cout<<"Display: "<<(get_seconds()-ts)<<"s"<<endl;
-  ts = get_seconds();
-
-  /* destroy the context */
-  OSMesaDestroyContext( ctx );
-
-  return true;
-}

+ 0 - 17
examples/quicklook-mesh/src/render_to_buffer.h

@@ -1,17 +0,0 @@
-#define GL_GLEXT_PROTOTYPES
-#include <GL/osmesa.h>
-
-// Inputs:
-//   filename   path to mesh
-//   background  background color
-//   width  width of image buffer
-//   height  height of image buffer
-// Outputs:
-//   buffer   width*height*4 buffer of bytes (should already be allocated) RGBA
-// Returns true only only upon success.
-bool render_to_buffer(
-  const char * filename,
-  const float *background_color,
-  const int width,
-  const int height,
-  GLubyte * buffer);

+ 11 - 11
include/igl/AABB.h

@@ -8,18 +8,18 @@
 #ifndef IGL_AABB_H
 #define IGL_AABB_H
 
-// Implementation of semi-general purpose axis-aligned bounding box hierarchy.
-// The mesh (V,Ele) is stored and managed by the caller and each routine here
-// simply takes it as references (it better not change between calls).
-//
-// It's a little annoying that the Dimension is a template parameter and not
-// picked up at run time from V. This leads to duplicated code for 2d/3d (up to
-// dim).
 #include <Eigen/Core>
 #include <Eigen/Geometry>
 #include <vector>
 namespace igl
 {
+  // Implementation of semi-general purpose axis-aligned bounding box hierarchy.
+  // The mesh (V,Ele) is stored and managed by the caller and each routine here
+  // simply takes it as references (it better not change between calls).
+  //
+  // It's a little annoying that the Dimension is a template parameter and not
+  // picked up at run time from V. This leads to duplicated code for 2d/3d (up to
+  // dim).
   template <typename DerivedV, int DIM>
     class AABB 
     {
@@ -75,9 +75,9 @@ public:
       AABB(AABB&& other):
         // initialize via default constructor
         AABB() 
-    {
-      swap(*this,other);
-    }
+      {
+        swap(*this,other);
+      }
       // Seems like there should have been an elegant solution to this using
       // the copy-swap idiom above:
       inline void deinit()
@@ -719,7 +719,7 @@ inline void igl::AABB<DerivedV,DIM>::squared_distance(
     int Ip;
     sqrD(p) = squared_distance(V,Ele,Pp,Ip,c);
     I(p) = Ip;
-    C.row(p) = c;
+    C.row(p).head(DIM) = c;
   }
 }
 

+ 3 - 1
include/igl/ConjugateFFSolverData.h

@@ -11,7 +11,9 @@
 #include <Eigen/Core>
 #include <Eigen/Sparse>
 
-namespace igl {
+namespace igl 
+{
+  // Data class for the Conjugate Frame Field Solver
   template <typename DerivedV, typename DerivedF>
   class ConjugateFFSolverData
   {

+ 1 - 1
include/igl/EPS.h

@@ -8,9 +8,9 @@
 #ifndef IGL_EPS_H
 #define IGL_EPS_H
 #include "igl_inline.h"
-// Define a standard value for double epsilon
 namespace igl
 {
+  // Define a standard value for double epsilon
   const double DOUBLE_EPS    = 1.0e-14;
   const double DOUBLE_EPS_SQ = 1.0e-28;
   const float FLOAT_EPS    = 1.0e-7;

+ 0 - 1
include/igl/HalfEdgeIterator.h

@@ -5,7 +5,6 @@
 // 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_HALFEDGEITERATOR_H
 #define IGL_HALFEDGEITERATOR_H
 

+ 2 - 2
include/igl/IndexComparison.h

@@ -8,9 +8,9 @@
 #ifndef IGL_INDEXCOMPARISON_H
 #define IGL_INDEXCOMPARISON_H
 #include <iostream>
-// Comparison struct used by sort
-// http://bytes.com/topic/c/answers/132045-sort-get-index
 namespace igl{
+  // Comparison struct used by sort
+  // http://bytes.com/topic/c/answers/132045-sort-get-index
 
   // For use with functions like std::sort
   template<class T> struct IndexLessThan

+ 4 - 0
include/igl/NormalType.h

@@ -10,6 +10,10 @@
 
 namespace igl
 {
+  // PER_VERTEX_NORMALS  Normals computed per vertex based on incident faces
+  // PER_FACE_NORMALS  Normals computed per face
+  // PER_CORNER_NORMALS  Normals computed per corner (aka wedge) based on
+  //   incident faces without sharp edge
   enum NormalType
   {
     PER_VERTEX_NORMALS,

+ 3 - 3
include/igl/ONE.h

@@ -7,11 +7,11 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_ONE_H
 #define IGL_ONE_H
-// Often one needs a reference to a dummy variable containing one as its
-// value, for example when using AntTweakBar's
-// TwSetParam( "3D View", "opened", TW_PARAM_INT32, 1, &INT_ONE);
 namespace igl
 {
+  // Often one needs a reference to a dummy variable containing one as its
+  // value, for example when using AntTweakBar's
+  // TwSetParam( "3D View", "opened", TW_PARAM_INT32, 1, &INT_ONE);
   const char CHAR_ONE = 1;
   const int INT_ONE = 1;
   const unsigned int UNSIGNED_INT_ONE = 1;

+ 1 - 0
include/igl/Viewport.h

@@ -10,6 +10,7 @@
 
 namespace igl
 {
+  // Simple Viewport class for an opengl context. Handles reshaping and mouse.
   struct Viewport
   {
     int x,y,width,height;

+ 5 - 2
include/igl/WindingNumberMethod.h

@@ -9,11 +9,14 @@
 #define IGL_WINDINGNUMBERMETHOD_H
 namespace igl
 {
+  // EXACT_WINDING_NUMBER_METHOD  exact hierarchical evaluation
+  // APPROX_SIMPLE_WINDING_NUMBER_METHOD  poor approximation
+  // APPROX_CACHE_WINDING_NUMBER_METHOD  another poor approximation
   enum WindingNumberMethod
   {
-    EXACT_WINDING_NUMBER_METHOD = 0, // Exact hierarchical evaluation
+    EXACT_WINDING_NUMBER_METHOD = 0,
     APPROX_SIMPLE_WINDING_NUMBER_METHOD = 1,
-    APPROX_CACHE_WINDING_NUMBER_METHOD = 2, // Approximate hierarchical evaluation
+    APPROX_CACHE_WINDING_NUMBER_METHOD = 2,
     NUM_WINDING_NUMBER_METHODS = 3
   };
 }

+ 7 - 3
include/igl/WindingNumberTree.h

@@ -12,9 +12,13 @@
 #include <Eigen/Dense>
 #include "WindingNumberMethod.h"
 
-static Eigen::MatrixXd dummyV;
 namespace igl
 {
+  // This is only need to fill in references, it should never actually be touched
+  // and shouldn't cause race conditions. (This is a hack, but I think it's "safe")
+  static Eigen::MatrixXd dummyV;
+  // Space partitioning tree for computing winding number hierarchically.
+  //
   // Templates:
   //   Point  type for points in space, e.g. Eigen::Vector3d
   template <typename Point>
@@ -146,7 +150,7 @@ template <typename Point>
 inline igl::WindingNumberTree<Point>::WindingNumberTree():
   method(EXACT_WINDING_NUMBER_METHOD),
   parent(NULL),
-  V(dummyV),
+  V(igl::dummyV),
   SV(),
   F(),
   //boundary(igl::boundary_facets<Eigen::MatrixXi,Eigen::MatrixXi>(F))
@@ -162,7 +166,7 @@ inline igl::WindingNumberTree<Point>::WindingNumberTree(
   const Eigen::MatrixXi & _F):
   method(EXACT_WINDING_NUMBER_METHOD),
   parent(NULL),
-  V(dummyV),
+  V(igl::dummyV),
   SV(),
   F(),
   //boundary(igl::boundary_facets<Eigen::MatrixXi,Eigen::MatrixXi>(F))

+ 3 - 3
include/igl/ZERO.h

@@ -7,11 +7,11 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_ZERO_H
 #define IGL_ZERO_H
-// Often one needs a reference to a dummy variable containing zero as its
-// value, for example when using AntTweakBar's
-// TwSetParam( "3D View", "opened", TW_PARAM_INT32, 1, &INT_ZERO);
 namespace igl
 {
+  // Often one needs a reference to a dummy variable containing zero as its
+  // value, for example when using AntTweakBar's
+  // TwSetParam( "3D View", "opened", TW_PARAM_INT32, 1, &INT_ZERO);
   const char CHAR_ZERO = 0;
   const int INT_ZERO = 0;
   const unsigned int UNSIGNED_INT_ZERO = 0;

+ 0 - 2
include/igl/active_set.h

@@ -28,7 +28,6 @@ namespace igl
   // and further optionally subject to the linear inequality constraints that
   // Aieq*Z <= Bieq and constant inequality constraints lx <= x <= ux
   //
-  // Templates:
   // Inputs:
   //   A  n by n matrix of quadratic coefficients
   //   B  n by 1 column of linear coefficients
@@ -50,7 +49,6 @@ namespace igl
   // Benchmark: For a harmonic solve on a mesh with 325K facets, matlab 2.2
   // secs, igl/min_quad_with_fixed.h 7.1 secs
   //
-
   template <
     typename AT, 
     typename DerivedB,

+ 182 - 0
include/igl/boolean/CSGTree.h

@@ -0,0 +1,182 @@
+// 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_BOOLEAN_CSG_TREE_H
+#define IGL_BOOLEAN_CSG_TREE_H
+
+#include <igl/boolean/string_to_mesh_boolean_type.h>
+#include <igl/boolean/MeshBooleanType.h>
+#include <igl/boolean/mesh_boolean.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/number_utils.h>
+
+namespace igl
+{
+  namespace boolean
+  {
+    // Class for defining and computing a constructive solid geometry result
+    // out of a tree of boolean operations on "solid" triangle meshes.
+    //
+    //template <typename DerivedF>
+    class CSGTree
+    {
+      private:
+        typedef CGAL::Epeck::FT ExactScalar;
+        typedef Eigen::Matrix<ExactScalar,Eigen::Dynamic,3> MatrixX3E;
+        //typedef Eigen::PlainObjectBase<DerivedF> POBF;
+        typedef Eigen::MatrixXi POBF;
+        typedef POBF::Index FIndex;
+        typedef Eigen::Matrix<FIndex,Eigen::Dynamic,1> VectorJ;
+        // Resulting mesh
+        MatrixX3E m_V;
+        POBF m_F;
+        VectorJ m_J;
+        // Number of birth faces in A + those in B. I.e. sum of original "leaf"
+        // faces involved in result.
+        size_t m_number_of_birth_faces;
+      public:
+        CSGTree()
+        {
+        }
+        //typedef Eigen::MatrixXd MatrixX3E;
+        //typedef Eigen::MatrixXi POBF;
+        // http://stackoverflow.com/a/3279550/148668
+        CSGTree(const CSGTree & other)
+          :
+          // copy things
+          m_V(other.m_V),
+          // This is an issue if m_F is templated
+          // https://forum.kde.org/viewtopic.php?f=74&t=128414
+          m_F(other.m_F),
+          m_J(other.m_J),
+          m_number_of_birth_faces(other.m_number_of_birth_faces)
+        {
+        }
+        // copy-swap idiom
+        friend void swap(CSGTree& first, CSGTree& second)
+        {
+          using std::swap;
+          // swap things
+          swap(first.m_V,second.m_V);
+          // This is an issue if m_F is templated, similar to
+          // https://forum.kde.org/viewtopic.php?f=74&t=128414
+          swap(first.m_F,second.m_F);
+          swap(first.m_J,second.m_J);
+          swap(first.m_number_of_birth_faces,second.m_number_of_birth_faces);
+        }
+        // Pass-by-value (aka copy)
+        CSGTree& operator=(CSGTree other)
+        {
+          swap(*this,other);
+          return *this;
+        }
+        CSGTree(CSGTree&& other):
+          // initialize via default constructor
+          CSGTree() 
+        {
+          swap(*this,other);
+        }
+        // Construct and compute a boolean operation on existing CSGTree nodes.
+        //
+        // Inputs:
+        //   A  Solid result of previous CSG operation (or identity, see below)
+        //   B  Solid result of previous CSG operation (or identity, see below)
+        //   type  type of mesh boolean to compute 
+        CSGTree(
+          const CSGTree & A,
+          const CSGTree & B,
+          const MeshBooleanType & type)
+        {
+          // conduct boolean operation
+          mesh_boolean(A.V(),A.F(),B.V(),B.F(),type,m_V,m_F,m_J);
+          // reindex m_J
+          std::for_each(m_J.data(),m_J.data()+m_J.size(),
+            [&](typename VectorJ::Scalar & j)
+            {
+              if(j < A.F().rows())
+              {
+                j = A.J()(j);
+              }else
+              {
+                assert(j<(A.F().rows()+B.F().rows()));
+                j = A.number_of_birth_faces()+(B.J()(j-A.F().rows()));
+              }
+            });
+          m_number_of_birth_faces = 
+            A.number_of_birth_faces() + B.number_of_birth_faces();
+        }
+        // Overload using string for type
+        CSGTree(
+          const CSGTree & A,
+          const CSGTree & B,
+          const std::string & s):
+          CSGTree(A,B,string_to_mesh_boolean_type(s))
+        {
+          // do nothing (all done in constructor).
+        }
+        // "Leaf" node with identity operation on assumed "solid" mesh (V,F)
+        //
+        // Inputs:
+        //   V  #V by 3 list of mesh vertices (in any precision, will be
+        //     converted to exact)
+        //   F  #F by 3 list of mesh face indices into V
+        template <typename DerivedV>
+        CSGTree(const Eigen::PlainObjectBase<DerivedV> & V, const POBF & F)//:
+        // Possible Eigen bug:
+        // https://forum.kde.org/viewtopic.php?f=74&t=128414
+          //m_V(V.template cast<ExactScalar>()),m_F(F)
+        {
+          m_V = V.template cast<ExactScalar>();
+          m_F = F;
+          // number of faces
+          m_number_of_birth_faces = m_F.rows();
+          // identity birth index
+          m_J = VectorJ::LinSpaced(
+            m_number_of_birth_faces,0,m_number_of_birth_faces-1);
+        }
+        // Returns reference to resulting mesh vertices m_V in exact scalar
+        // representation
+        const MatrixX3E & V() const
+        {
+          return m_V;
+        }
+        // Returns mesh vertices in the desired output type, casting when
+        // appropriate to floating precision.
+        template <typename DerivedV>
+        Eigen::PlainObjectBase<DerivedV> cast_V() const
+        {
+          Eigen::PlainObjectBase<DerivedV> dV;
+          dV.resize(m_V.rows(),m_V.cols());
+          for(int i = 0;i<m_V.size();i++)
+          {
+            *(dV.data()+i) = CGAL::to_double((*(m_V.data()+i)));
+          }
+          return dV;
+        }
+        // Returns reference to resulting mesh faces m_F
+        const POBF & F() const
+        {
+          return m_F;
+        }
+        // Returns reference to "birth parents" indices into [F1;F2;...;Fn]
+        // where F1, ... , Fn are the face lists of the leaf ("original") input
+        // meshes.
+        const VectorJ & J() const
+        {
+          return m_J;
+        }
+        // The number of leaf faces = #F1 + #F2 + ... + #Fn
+        const size_t & number_of_birth_faces() const
+        {
+          return m_number_of_birth_faces;
+        }
+    };
+  }
+}
+
+
+#endif

+ 17 - 4
include/igl/boolean/mesh_boolean.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 "mesh_boolean.h"
+#include <igl/cgal/assign_scalar.h>
 #include <igl/per_face_normals.h>
 #include <igl/boundary_facets.h>
 #include <igl/exterior_edges.h>
@@ -105,7 +106,7 @@ IGL_INLINE void igl::boolean::mesh_boolean(
   using namespace igl::cgal;
   MeshBooleanType eff_type = type;
   // Concatenate A and B into a single mesh
-  typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
+  typedef CGAL::Epeck Kernel;
   typedef Kernel::FT ExactScalar;
   typedef typename DerivedVC::Scalar Scalar;
   typedef typename DerivedFC::Scalar Index;
@@ -178,7 +179,9 @@ IGL_INLINE void igl::boolean::mesh_boolean(
     CV.resize(EV.rows(), EV.cols());
     std::transform(EV.data(), EV.data() + EV.rows()*EV.cols(),
             CV.data(), [&](ExactScalar val) {
-            return CGAL::to_double(val);
+            Scalar c;
+            assign_scalar(val,c);
+            return c;
             });
   }
 
@@ -248,7 +251,7 @@ IGL_INLINE void igl::boolean::mesh_boolean(
   }
 #ifdef IGL_MESH_BOOLEAN_DEBUG
   {
-    MatrixXd O;
+    MatrixXi O;
     boundary_facets(FC,O);
     cout<<"# boundary: "<<O.rows()<<endl;
   }
@@ -334,7 +337,7 @@ IGL_INLINE void igl::boolean::mesh_boolean(
   //FC = G;
 #ifdef IGL_MESH_BOOLEAN_DEBUG
   {
-    MatrixXd O;
+    MatrixXi O;
     boundary_facets(FC,O);
     cout<<"# boundary: "<<O.rows()<<endl;
   }
@@ -352,7 +355,17 @@ template unsigned long
 igl::cgal::peel_outer_hull_layers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
 #include <igl/cgal/outer_hull.cpp>
 template void igl::cgal::outer_hull<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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> >&);
+#include <igl/slice.cpp>
+template void igl::slice<Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, int, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&);
+#include <igl/barycenter.cpp>
+template void igl::barycenter<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&);
+#include <igl/mod.cpp>
+template Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > igl::mod<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
+#include <igl/outer_element.cpp>
+template void igl::outer_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, long&, long&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 // Explicit template specialization
 template void igl::boolean::mesh_boolean<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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::boolean::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::boolean::mesh_boolean<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<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> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::boolean::MeshBooleanType 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::boolean::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::boolean::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
+
 #endif

+ 48 - 0
include/igl/boolean/string_to_mesh_boolean_type.cpp

@@ -0,0 +1,48 @@
+#include "string_to_mesh_boolean_type.h"
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+IGL_INLINE bool igl::boolean::string_to_mesh_boolean_type( 
+  const std::string & s,
+  MeshBooleanType & type)
+{
+  using namespace std;
+  string eff_s = s;
+  transform(eff_s.begin(), eff_s.end(), eff_s.begin(), ::tolower);
+  const auto & find_any = 
+    [](const vector<string> & haystack, const string & needle)->bool
+  {
+    return find(haystack.begin(), haystack.end(), needle) != haystack.end();
+  };
+  if(find_any({"union","unite","u","∪"},eff_s))
+  {
+    type = MESH_BOOLEAN_TYPE_UNION;
+  }else if(find_any({"intersect","intersection","i","∩"},eff_s))
+  {
+    type = MESH_BOOLEAN_TYPE_INTERSECT;
+  }else if(
+    find_any({"minus","subtract","difference","relative complement","m","\\"},eff_s))
+  {
+    type = MESH_BOOLEAN_TYPE_MINUS;
+  }else if(find_any({"xor","symmetric difference","x","∆"},eff_s))
+  {
+    type = MESH_BOOLEAN_TYPE_XOR;
+  }else if(find_any({"resolve"},eff_s))
+  {
+    type = MESH_BOOLEAN_TYPE_RESOLVE;
+  }else
+  {
+    return false;
+  }
+  return true;
+}
+
+IGL_INLINE igl::boolean::MeshBooleanType igl::boolean::string_to_mesh_boolean_type( 
+  const std::string & s)
+{
+  MeshBooleanType type;
+  const bool ret = string_to_mesh_boolean_type(s,type);
+  assert(ret && "Unknown MeshBooleanType name");
+  return type;
+}

+ 41 - 0
include/igl/boolean/string_to_mesh_boolean_type.h

@@ -0,0 +1,41 @@
+// 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_BOOLEAN_STRING_TO_MESH_BOOLEAN_H
+#define IGL_BOOLEAN_STRING_TO_MESH_BOOLEAN_H
+
+#include <igl/igl_inline.h>
+#include "MeshBooleanType.h"
+#include <string>
+
+namespace igl
+{
+  namespace boolean
+  {
+    // Convert string to boolean type
+    //
+    //  Inputs:
+    //    s  string identifying type, one of the following:
+    //      "union","intersect","minus","xor","resolve"
+    //  Outputs:
+    //    type  type of boolean operation
+    // Returns true only on success
+    //     
+    IGL_INLINE bool string_to_mesh_boolean_type(
+      const std::string & s,
+      MeshBooleanType & type);
+    // Returns type without error handling
+    IGL_INLINE MeshBooleanType string_to_mesh_boolean_type(
+      const std::string & s);
+  }
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "string_to_mesh_boolean_type.cpp"
+#endif
+
+#endif

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

@@ -20,3 +20,10 @@ IGL_INLINE void igl::cgal::assign_scalar(
 {
   d = CGAL::to_double(cgal);
 }
+
+IGL_INLINE void igl::cgal::assign_scalar(
+  const double & c,
+  double & d)
+{
+  d = c;
+}

+ 3 - 0
include/igl/cgal/assign_scalar.h

@@ -23,6 +23,9 @@ namespace igl
     IGL_INLINE void assign_scalar(
       const typename CGAL::Epeck::FT & cgal,
       double & d);
+    IGL_INLINE void assign_scalar(
+      const double & c,
+      double & d);
   }
 }
 #ifndef IGL_STATIC_LIBRARY

+ 17 - 3
include/igl/cgal/mesh_to_cgal_triangle_list.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 "mesh_to_cgal_triangle_list.h"
+#include "assign_scalar.h"
 
 #include <cassert>
 
@@ -22,6 +23,17 @@ IGL_INLINE void igl::cgal::mesh_to_cgal_triangle_list(
   typedef CGAL::Triangle_3<Kernel> Triangle_3; 
   // Must be 3D
   assert(V.cols() == 3);
+  // **Copy** to convert to output type (this is especially/only needed if the
+  // input type DerivedV::Scalar is CGAL::Epeck
+  Eigen::Matrix<
+    typename Kernel::FT,
+    DerivedV::RowsAtCompileTime,
+    DerivedV::ColsAtCompileTime> 
+    KV(V.rows(),V.cols());
+  for(int i = 0;i<V.size();i++)
+  {
+    assign_scalar(*(V.data()+i),*(KV.data()+i));
+  }
   // Must be triangles
   assert(F.cols() == 3);
   T.reserve(F.rows());
@@ -30,9 +42,9 @@ IGL_INLINE void igl::cgal::mesh_to_cgal_triangle_list(
   {
     T.push_back(
       Triangle_3(
-        Point_3( V(F(f,0),0), V(F(f,0),1), V(F(f,0),2)),
-        Point_3( V(F(f,1),0), V(F(f,1),1), V(F(f,1),2)),
-        Point_3( V(F(f,2),0), V(F(f,2),1), V(F(f,2),2))));
+        Point_3( KV(F(f,0),0), KV(F(f,0),1), KV(F(f,0),2)),
+        Point_3( KV(F(f,1),0), KV(F(f,1),1), KV(F(f,1),2)),
+        Point_3( KV(F(f,2),0), KV(F(f,2),1), KV(F(f,2),2))));
   }
 }
 
@@ -42,4 +54,6 @@ template void igl::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3,
 template void igl::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epick>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
 template void igl::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<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::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<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::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epeck>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::__1::vector<CGAL::Triangle_3<CGAL::Epeck>, std::__1::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
+template void igl::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epick>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::__1::vector<CGAL::Triangle_3<CGAL::Epick>, std::__1::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
 #endif

+ 6 - 0
include/igl/cgal/order_facets_around_edge.cpp

@@ -320,3 +320,9 @@ void igl::cgal::order_facets_around_edge(
 }
 
 
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+template void igl::cgal::order_facets_around_edge<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, unsigned long, unsigned long, std::__1::vector<int, std::__1::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::cgal::order_facets_around_edge<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -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&, unsigned long, unsigned long, std::__1::vector<int, std::__1::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::cgal::order_facets_around_edge<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&, unsigned long, unsigned long, std::__1::vector<int, std::__1::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+#endif

+ 6 - 0
include/igl/cgal/order_facets_around_edges.cpp

@@ -330,3 +330,9 @@ IGL_INLINE void igl::cgal::order_facets_around_edges(
     }
 }
 
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+template void igl::cgal::order_facets_around_edges<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long, long, bool>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, std::__1::vector<std::__1::vector<long, std::__1::allocator<long> >, std::__1::allocator<std::__1::vector<long, std::__1::allocator<long> > > > const&, std::__1::vector<std::__1::vector<long, std::__1::allocator<long> >, std::__1::allocator<std::__1::vector<long, std::__1::allocator<long> > > >&, std::__1::vector<std::__1::vector<bool, std::__1::allocator<bool> >, std::__1::allocator<std::__1::vector<bool, std::__1::allocator<bool> > > >&);
+template void igl::cgal::order_facets_around_edges<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long, long, bool>(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, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, std::__1::vector<std::__1::vector<long, std::__1::allocator<long> >, std::__1::allocator<std::__1::vector<long, std::__1::allocator<long> > > > const&, std::__1::vector<std::__1::vector<long, std::__1::allocator<long> >, std::__1::allocator<std::__1::vector<long, std::__1::allocator<long> > > >&, std::__1::vector<std::__1::vector<bool, std::__1::allocator<bool> >, std::__1::allocator<std::__1::vector<bool, std::__1::allocator<bool> > > >&);
+template void igl::cgal::order_facets_around_edges<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, long, long, bool>(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, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, std::__1::vector<std::__1::vector<long, std::__1::allocator<long> >, std::__1::allocator<std::__1::vector<long, std::__1::allocator<long> > > > const&, std::__1::vector<std::__1::vector<long, std::__1::allocator<long> >, std::__1::allocator<std::__1::vector<long, std::__1::allocator<long> > > >&, std::__1::vector<std::__1::vector<bool, std::__1::allocator<bool> >, std::__1::allocator<std::__1::vector<bool, std::__1::allocator<bool> > > >&);
+#endif

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

@@ -79,3 +79,12 @@ IGL_INLINE void igl::cgal::outer_facet(
     f = signed_index_to_index(adj_faces[order[0]]);
     flipped = adj_faces[order[0]] > 0;
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+template void igl::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
+template void igl::cgal::outer_facet<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -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<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
+template void igl::cgal::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<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> > const&, int&, bool&);
+#endif

+ 6 - 0
include/igl/cgal/projected_delaunay.cpp

@@ -94,3 +94,9 @@ IGL_INLINE void igl::cgal::projected_delaunay(
     }
   }
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+template void igl::cgal::projected_delaunay<CGAL::Epeck>(CGAL::Triangle_3<CGAL::Epeck> const&, std::__1::vector<CGAL::Object, std::__1::allocator<CGAL::Object> > const&, CGAL::Constrained_triangulation_plus_2<CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epeck, CGAL::Triangulation_data_structure_2<CGAL::Triangulation_vertex_base_2<CGAL::Epeck, CGAL::Triangulation_ds_vertex_base_2<void> >, CGAL::Constrained_triangulation_face_base_2<CGAL::Epeck, CGAL::Triangulation_face_base_2<CGAL::Epeck, CGAL::Triangulation_ds_face_base_2<void> > > >, CGAL::Exact_intersections_tag> >&);
+template void igl::cgal::projected_delaunay<CGAL::Epick>(CGAL::Triangle_3<CGAL::Epick> const&, std::__1::vector<CGAL::Object, std::__1::allocator<CGAL::Object> > const&, CGAL::Constrained_triangulation_plus_2<CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epick, CGAL::Triangulation_data_structure_2<CGAL::Triangulation_vertex_base_2<CGAL::Epick, CGAL::Triangulation_ds_vertex_base_2<void> >, CGAL::Constrained_triangulation_face_base_2<CGAL::Epick, CGAL::Triangulation_face_base_2<CGAL::Epick, CGAL::Triangulation_ds_face_base_2<void> > > >, CGAL::Exact_intersections_tag> >&);
+#endif

File diff suppressed because it is too large
+ 18 - 1
include/igl/cgal/remesh_intersections.cpp


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

@@ -87,4 +87,5 @@ template void igl::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, 3,
 template void igl::cgal::remesh_self_intersections<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<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -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&, igl::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -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&, igl::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::cgal::remesh_self_intersections<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -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&, igl::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 0 - 0
include/igl/MCTables.hh → include/igl/marching_cubes_tables.h


+ 2 - 2
include/igl/parula.cpp

@@ -21,8 +21,8 @@ IGL_INLINE void igl::parula(const T f, T & r, T & g, T & b)
   const float eff_f = (f>=1.?1.:(f<=0.?0.:f));
   // continuous index into array
   const float ff = eff_f*(PARULA_COLOR_MAP.rows()-1);
-  size_t s = floor(ff);
-  size_t d = ceil(ff);
+  size_t s = std::floor(ff);
+  size_t d = std::ceil(ff);
   const float t = (s==d ? 0. : (ff-s)/float(d-s));
 
   assert(t>=0 && t<=1);

+ 65 - 20
include/igl/serialize.h

@@ -21,7 +21,7 @@
 // -----------------------------------------------------------------------------
 
 // Known issues: This is not written in libigl-style so it isn't (easily)
-// "dualized" into the static library. 
+// "dualized" into the static library.
 //
 
 #include <type_traits>
@@ -45,16 +45,28 @@
 #define SERIALIZE_TYPE(Type,Params) \
 namespace igl { namespace serialization { \
   void _serialization(bool s,Type& obj,std::vector<char>& buffer) {Params} \
-  void serialize(const Type& obj,std::vector<char>& buffer) { \
+  template<> inline void serialize(const Type& obj,std::vector<char>& buffer) { \
     _serialization(true,const_cast<Type&>(obj),buffer); \
     } \
-  void deserialize(Type& obj,const std::vector<char>& buffer) { \
+  template<> inline void deserialize(Type& obj,const std::vector<char>& buffer) { \
     _serialization(false,obj,const_cast<std::vector<char>&>(buffer)); \
     } \
 }}
 
-#define SERIALIZE_MEMBER(Object) ::igl::serializer(s,obj.##Object,std::string(#Object),buffer);
-#define SERIALIZE_MEMBER_NAME(Object,Name) ::igl::serializer(s,obj.##Object,std::string(Name),buffer);
+#define SERIALIZE_TYPE_SOURCE(Type,Params) \
+namespace igl { namespace serialization { \
+  void _serialization(bool s,Type& obj,std::vector<char>& buffer) {Params} \
+  void _serialize(const Type& obj,std::vector<char>& buffer) { \
+    _serialization(true,const_cast<Type&>(obj),buffer); \
+    } \
+  void _deserialize(Type& obj,const std::vector<char>& buffer) { \
+    _serialization(false,obj,const_cast<std::vector<char>&>(buffer)); \
+    } \
+}}
+
+#define SERIALIZE_MEMBER(Object) igl::serializer(s,obj.Object,std::string(#Object),buffer);
+#define SERIALIZE_MEMBER_NAME(Object,Name) igl::serializer(s,obj.Object,std::string(Name),buffer);
+
 
 namespace igl
 {
@@ -101,21 +113,23 @@ namespace igl
   // Wrapper to expose both, the de- and serialization as one function
   //
   template <typename T>
-  inline bool serializer(bool serialize,T& obj,std::string& filename);
+  inline bool serializer(bool serialize,T& obj,const std::string& filename);
   template <typename T>
-  inline bool serializer(bool serialize,T& obj,std::string& objectName,const std::string& filename,bool overwrite = false);
+  inline bool serializer(bool serialize,T& obj,const std::string& objectName,const std::string& filename,bool overwrite = false);
   template <typename T>
-  inline bool serializer(bool serialize,T& obj,std::string& objectName,std::vector<char>& buffer);
+  inline bool serializer(bool serialize,T& obj,const 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 
+  // namespace igl { namespace serialization
   // {
+  //   template<>
   //   inline void serialize(const UserType& obj,std::vector<char>& buffer) {
   //     ::igl::serialize(obj.var,"var",buffer);
   //   }
-  //     
+  //
+  //   template<>
   //   inline void deserialize(UserType& obj,const std::vector<char>& buffer) {
   //     ::igl::deserialize(obj.var,"var",buffer);
   //   }
@@ -281,7 +295,7 @@ namespace igl
     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);
     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);    
+    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
@@ -333,6 +347,13 @@ namespace igl
     template<typename T,int P,typename I>
     inline void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter);
 
+    template<typename T,int P>
+    inline size_t getByteSize(const Eigen::Quaternion<T,P>& obj);
+    template<typename T,int P>
+    inline void serialize(const Eigen::Quaternion<T,P>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
+    template<typename T,int P>
+    inline void deserialize(Eigen::Quaternion<T,P>& obj,std::vector<char>::const_iterator& iter);
+
     // raw pointers
     template <typename T>
     inline typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj);
@@ -521,19 +542,19 @@ namespace igl
 
   // Wrapper function which combines both, de- and serialization
   template <typename T>
-  inline bool serializer(bool s,T& obj,std::string& filename)
+  inline bool serializer(bool s,T& obj,const 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)
+  inline bool serializer(bool s,T& obj,const 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)
+  inline bool serializer(bool s,T& obj,const std::string& objectName,std::vector<char>& buffer)
   {
     return s ? serialize(obj,objectName,buffer) : deserialize(obj,objectName,buffer);
   }
@@ -627,7 +648,7 @@ namespace igl
   }
 
   template <typename T>
-  inline void Serializable::Add(T& obj,std::string name,bool binary)
+  inline void Serializable::Add(T& obj,const std::string name,bool binary)
   {
     auto object = new SerializationObject<T>();
     object->Binary = binary;
@@ -650,7 +671,7 @@ namespace igl
     {
       // data
       std::vector<char> tmp;
-      serialize(obj,tmp);
+      serialize<>(obj,tmp);
 
       // size
       size_t size = buffer.size();
@@ -666,13 +687,13 @@ namespace 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);
+      serialization::deserialize<>(size,iter);
 
       std::vector<char> tmp;
       tmp.resize(size);
       std::copy(iter,iter+size,tmp.begin());
 
-      deserialize(obj,tmp);
+      deserialize<>(obj,tmp);
       iter += size;
     }
 
@@ -1010,6 +1031,30 @@ namespace igl
       obj.setFromTriplets(triplets.begin(),triplets.end());
     }
 
+    template<typename T,int P>
+    inline size_t getByteSize(const Eigen::Quaternion<T,P>& obj)
+    {
+      return sizeof(T)*4;
+    }
+
+    template<typename T,int P>
+    inline void serialize(const Eigen::Quaternion<T,P>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
+    {
+      serialization::serialize(obj.w(),buffer,iter);
+      serialization::serialize(obj.x(),buffer,iter);
+      serialization::serialize(obj.y(),buffer,iter);
+      serialization::serialize(obj.z(),buffer,iter);
+    }
+
+    template<typename T,int P>
+    inline void deserialize(Eigen::Quaternion<T,P>& obj,std::vector<char>::const_iterator& iter)
+    {
+      serialization::deserialize(obj.w(),iter);
+      serialization::deserialize(obj.x(),iter);
+      serialization::deserialize(obj.y(),iter);
+      serialization::deserialize(obj.z(),iter);
+    }
+
     // pointers
 
     template <typename T>
@@ -1115,13 +1160,13 @@ namespace igl
     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;
+      std::cerr << typeid(obj).name() << " is not serializable: derive from igl::Serializable or spezialize the template 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;
+      std::cerr << typeid(obj).name() << " is not deserializable: derive from igl::Serializable or spezialize the template function igl::serialization::deserialize(T& obj, const std::vector<char>& buffer)" << std::endl;
     }
 
     // helper functions

+ 9 - 10
include/igl/unique.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "unique.h"
 #include "sort.h"
@@ -97,9 +97,8 @@ IGL_INLINE void igl::unique(
 
 template <
   typename DerivedA,
-  typename DerivedC,
-  typename DerivedIA,
-  typename DerivedIC>
+  typename DerivedC
+  >
 IGL_INLINE void igl::unique(
     const Eigen::PlainObjectBase<DerivedA> & A,
     Eigen::PlainObjectBase<DerivedC> & C)
@@ -123,7 +122,7 @@ IGL_INLINE void igl::unique(
 //   Eigen::PlainObjectBase<DerivedIC>& IC)
 // {
 //   using namespace std;
-// 
+//
 //   typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
 //   vector<SortableRow<RowVector> > rows;
 //   rows.resize(A.rows());
@@ -134,12 +133,12 @@ IGL_INLINE void igl::unique(
 //     rows[i] = SortableRow<RowVector>(ri);
 //   }
 //   vector<SortableRow<RowVector> > vC;
-// 
+//
 //   // unique on rows
 //   vector<size_t> vIA;
 //   vector<size_t> vIC;
 //   unique(rows,vC,vIA,vIC);
-// 
+//
 //   // Convert to eigen
 //   C.resize(vC.size(),A.cols());
 //   IA.resize(vIA.size(),1);

+ 5 - 9
include/igl/unique.h

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_UNIQUE_H
 #define IGL_UNIQUE_H
@@ -45,9 +45,7 @@ namespace igl
       Eigen::PlainObjectBase<DerivedIC> & IC);
   template <
     typename DerivedA,
-    typename DerivedC,
-    typename DerivedIA,
-    typename DerivedIC>
+    typename DerivedC>
   IGL_INLINE void unique(
       const Eigen::PlainObjectBase<DerivedA> & A,
       Eigen::PlainObjectBase<DerivedC> & C);
@@ -76,5 +74,3 @@ namespace igl
 #endif
 
 #endif
-
-

+ 26 - 4
include/igl/viewer/Viewer.cpp

@@ -279,7 +279,6 @@ namespace viewer
     callback_mouse_scroll_data  = nullptr;
     callback_key_down_data      = nullptr;
     callback_key_up_data        = nullptr;
-
   }
 
   IGL_INLINE void Viewer::init_plugins()
@@ -364,7 +363,9 @@ namespace viewer
                    Eigen::Vector3d(255.0/255.0,228.0/255.0,58.0/255.0),
                    Eigen::Vector3d(255.0/255.0,235.0/255.0,80.0/255.0));
     if (data.V_uv.rows() == 0)
+    {
       data.grid_texture();
+    }
 
     core.align_camera_center(data.V,data.F);
 
@@ -726,10 +727,9 @@ namespace viewer
     this->save_mesh_to_file(fname.c_str());
   }
 
-  IGL_INLINE int Viewer::launch(bool resizable,bool fullscreen)
-  {
-    GLFWwindow* window;
 
+  IGL_INLINE int  Viewer::launch_init(bool resizable,bool fullscreen)
+  {
     glfwSetErrorCallback(glfw_error_callback);
     if (!glfwInit())
       return EXIT_FAILURE;
@@ -818,6 +818,12 @@ namespace viewer
 
     // Initialize IGL viewer
     init();
+    return EXIT_SUCCESS;
+  }
+
+  IGL_INLINE bool Viewer::launch_rendering(bool loop)
+  {
+    // glfwMakeContextCurrent(window);
 
     // Rendering loop
     while (!glfwWindowShouldClose(window))
@@ -841,8 +847,15 @@ namespace viewer
       {
         glfwWaitEvents();
       }
+
+      if (!loop)
+        return !glfwWindowShouldClose(window);
     }
+    return EXIT_SUCCESS;
+  }
 
+  IGL_INLINE void Viewer::launch_shut()
+  {
     opengl.free();
     core.shut();
 
@@ -850,6 +863,15 @@ namespace viewer
 
     glfwDestroyWindow(window);
     glfwTerminate();
+    return;
+  }
+
+  IGL_INLINE int Viewer::launch(bool resizable,bool fullscreen)
+  {
+    // TODO return values are being ignored...
+    launch_init(resizable,fullscreen);
+    launch_rendering(true);
+    launch_shut();
     return EXIT_SUCCESS;
   }
 } // end namespace

+ 7 - 0
include/igl/viewer/Viewer.h

@@ -34,6 +34,8 @@
 
 namespace nanogui { class FormScreen; }
 
+class GLFWwindow;
+
 namespace igl
 {
 namespace viewer
@@ -42,8 +44,13 @@ namespace viewer
   class Viewer
   {
   public:
+    GLFWwindow* window;
 
     IGL_INLINE int launch(bool resizable = true,bool fullscreen = false);
+    IGL_INLINE int launch_init(bool resizable = true,bool fullscreen = false);
+    IGL_INLINE bool launch_rendering(bool loop = true);
+    IGL_INLINE void launch_shut();
+
     IGL_INLINE void init();
 
     // Stores all the viewing options

+ 5 - 2
include/igl/viewer/ViewerCore.cpp

@@ -32,6 +32,7 @@ namespace igl {
       SERIALIZE_MEMBER(lighting_factor);
 
       SERIALIZE_MEMBER(trackball_angle);
+      SERIALIZE_MEMBER(rotation_type);
 
       SERIALIZE_MEMBER(model_zoom);
       SERIALIZE_MEMBER(model_translation);
@@ -39,8 +40,6 @@ namespace igl {
       SERIALIZE_MEMBER(model_zoom_uv);
       SERIALIZE_MEMBER(model_translation_uv);
 
-      SERIALIZE_MEMBER(object_scale);
-
       SERIALIZE_MEMBER(camera_zoom);
       SERIALIZE_MEMBER(orthographic);
       SERIALIZE_MEMBER(camera_view_angle);
@@ -65,17 +64,21 @@ namespace igl {
       SERIALIZE_MEMBER(is_animating);
       SERIALIZE_MEMBER(animation_max_fps);
 
+      SERIALIZE_MEMBER(object_scale);
+
       SERIALIZE_MEMBER(viewport);
       SERIALIZE_MEMBER(view);
       SERIALIZE_MEMBER(model);
       SERIALIZE_MEMBER(proj);
     }
 
+    template<>
     IGL_INLINE void serialize(const igl::viewer::ViewerCore& obj,std::vector<char>& buffer)
     {
       serialization(true,const_cast<igl::viewer::ViewerCore&>(obj),buffer);
     }
 
+    template<>
     IGL_INLINE void deserialize(igl::viewer::ViewerCore& obj,const std::vector<char>& buffer)
     {
       serialization(false,obj,const_cast<std::vector<char>&>(buffer));

+ 2 - 0
include/igl/viewer/ViewerCore.h

@@ -150,6 +150,8 @@ public:
   Eigen::Matrix4f view;
   Eigen::Matrix4f model;
   Eigen::Matrix4f proj;
+  public:
+      EIGEN_MAKE_ALIGNED_OPERATOR_NEW
 };
 
 }

+ 14 - 4
include/igl/viewer/ViewerData.cpp

@@ -46,14 +46,18 @@ namespace igl {
       SERIALIZE_MEMBER(labels_positions);
       SERIALIZE_MEMBER(labels_strings);
 
+      SERIALIZE_MEMBER(dirty);
+
       SERIALIZE_MEMBER(face_based);
     }
 
+    template<>
     IGL_INLINE void serialize(const igl::viewer::ViewerData& obj,std::vector<char>& buffer)
     {
       serialization(true,const_cast<igl::viewer::ViewerData&>(obj),buffer);
     }
 
+    template<>
     IGL_INLINE void deserialize(igl::viewer::ViewerData& obj,const std::vector<char>& buffer)
     {
       serialization(false,obj,const_cast<std::vector<char>&>(buffer));
@@ -114,7 +118,7 @@ IGL_INLINE void igl::viewer::ViewerData::set_mesh(const Eigen::MatrixXd& _V, con
       F = _F;
     }
     else
-      cerr << "ERROR (set_mesh): The new mesh has a different number of vertices/faces. Please clear the mesh before plotting.";
+      cerr << "ERROR (set_mesh): The new mesh has a different number of vertices/faces. Please clear the mesh before plotting."<<endl;
   }
   dirty |= DIRTY_FACE | DIRTY_POSITION;
 }
@@ -140,7 +144,7 @@ IGL_INLINE void igl::viewer::ViewerData::set_normals(const Eigen::MatrixXd& N)
     F_normals = N;
   }
   else
-    cerr << "ERROR (set_normals): Please provide a normal per face, per corner or per vertex.";
+    cerr << "ERROR (set_normals): Please provide a normal per face, per corner or per vertex."<<endl;
   dirty |= DIRTY_NORMAL;
 }
 
@@ -191,7 +195,7 @@ IGL_INLINE void igl::viewer::ViewerData::set_colors(const Eigen::MatrixXd &C)
     F_material_specular = specular(F_material_diffuse);
   }
   else
-    cerr << "ERROR (set_colors): Please provide a single color, or a color per face or per vertex.";
+    cerr << "ERROR (set_colors): Please provide a single color, or a color per face or per vertex."<<endl;;
   dirty |= DIRTY_DIFFUSE;
 
 }
@@ -205,7 +209,7 @@ IGL_INLINE void igl::viewer::ViewerData::set_uv(const Eigen::MatrixXd& UV)
     V_uv = UV;
   }
   else
-    cerr << "ERROR (set_UV): Please provide uv per vertex.";
+    cerr << "ERROR (set_UV): Please provide uv per vertex."<<endl;;
   dirty |= DIRTY_UV;
 }
 
@@ -389,6 +393,12 @@ IGL_INLINE void igl::viewer::ViewerData::uniform_colors(Eigen::Vector3d ambient,
 
 IGL_INLINE void igl::viewer::ViewerData::grid_texture()
 {
+  // Don't do anything for an empty mesh
+  if(V.rows() == 0)
+  {
+    V_uv.resize(V.rows(),2);
+    return;
+  }
   if (V_uv.rows() == 0)
   {
     V_uv = V.block(0, 0, V.rows(), 2);

+ 2 - 2
index.html

@@ -40,7 +40,7 @@ just include igl headers (e.g. <code>#include &lt;igl/cotmatrix.h&gt;</code>) an
 header file contains a single function (e.g. <code>igl/cotmatrix.h</code> contains
 <code>igl::cotmatrix()</code>). Most are tailored to operate on a generic triangle mesh
 stored in an n-by&#8211;3 matrix of vertex positions V and an m-by&#8211;3 matrix of
-triangle indices F. </p>
+triangle indices F.</p>
 
 <p><em>Optionally</em> the library may also be <a href="optional/">pre-compiled</a> into a statically
 linked library, for faster compile times with your projects. This only effects
@@ -54,7 +54,7 @@ conversion table</a>.</p>
 <h2 id="tutorial">Tutorial</h2>
 
 <p>As of version 1.0, libigl includes an introductory
-<a href="tutorial/tutorial.html">tutorial</a> that covers many functionalities.</p>
+<a href="http://libigl.github.io/libigl/tutorial/tutorial.html">tutorial</a> that covers many functionalities.</p>
 
 <h2 id="installation">Installation</h2>
 

+ 48 - 0
python/001_BasicTypes.py

@@ -0,0 +1,48 @@
+from iglhelpers import *
+
+############# Dense Matrix Types #############
+
+# Create a numpy dense array
+# 2 types are supported by the wrappers: float64 and int64
+dense_matrix = np.array( [ (1,2,3), (4,5,6) , (7,8,9) ], dtype='float64')
+
+# libigl wrappers uses Eigen as a matrix type, you can easily convert between numpy and Eigen using
+# the helper function p2e. This operation duplicates the data.
+dense_matrix_eigen = p2e(dense_matrix)
+
+# The Eigen wrappers allows you to do operations directly on this matrix,
+# without having to convert back to numpy
+dense_matrix_eigen_2 = dense_matrix_eigen * dense_matrix_eigen
+
+# You can also inspect the data without converting it ...
+print("Eigen Matrix: \n", dense_matrix_eigen_2, "\n", sep='')
+
+# and access single elements
+print("Eigen Matrix(0,0): ", dense_matrix_eigen_2[0,0], "\n")
+
+# To convert it back to a numpy array, use the helper function e2p
+dense_matrix_2 = e2p(dense_matrix_eigen_2)
+print("Numpy Array: \n", dense_matrix_2, "\n", sep='')
+
+############# Sparse Matrix Types #############
+
+# Sparse matrices are handled in a very similar way
+# 2 types are supported by the wrappers: float64 and int64
+sparse_matrix = sparse.rand(10, 10, 0.1)
+
+# To convert to the eigen forma use p2e
+sparse_matrix_eigen = p2e(sparse_matrix)
+
+# They can directly be used plotted or used in computations
+print("Sparse matrix Eigen: ", sparse_matrix_eigen, sep='')
+
+# And converted back with e2p
+sparse_matrix_2 = e2p(sparse_matrix_eigen)
+print("Sparse matrix Numpy: ", sparse_matrix_2.todense(), sep='')
+
+
+
+
+
+
+

+ 14 - 0
python/101_FileIO.py

@@ -0,0 +1,14 @@
+from __future__ import print_function
+import igl
+
+# Load a mesh in OFF format
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+igl.readOFF("../tutorial/shared/cube.off", V, F)
+
+# Print the vertices and faces matrices
+print("Vertices: \n", V, sep='')
+print("Faces: \n", F, sep='')
+
+# Save the mesh in OBJ format
+igl.writeOBJ("cube.obj",V,F)

+ 11 - 0
python/102_DrawMesh.py

@@ -0,0 +1,11 @@
+import igl
+
+# Load a mesh in OFF format
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+igl.readOFF("../tutorial/shared/beetle.off", V, F)
+
+# Plot the mesh
+viewer = igl.viewer.Viewer();
+viewer.data.set_mesh(V, F);
+viewer.launch();

+ 24 - 0
python/102_DrawMeshTCP.py

@@ -0,0 +1,24 @@
+import igl
+import tcpviewer
+import time
+
+# Load a mesh in OFF format
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+time1 = time.time()
+# igl.read_triangle_mesh("../tutorial/shared/armadillo.obj", V, F)
+igl.readOFF("../tutorial/shared/beetle.off", V, F)
+time2 = time.time()
+
+
+print('Loading mesh (%d vertices) %0.3f ms' % (V.rows(),(time2-time1)*1000.0))
+
+
+# Plot the mesh
+viewer = tcpviewer.TCPViewer()
+viewer.data.set_mesh(V, F)
+viewer.core.align_camera_center(V,F)
+viewer.launch()
+time3 = time.time()
+
+print('Sending to TCP viewer took %0.3f ms' % ((time3-time2)*1000.0))

+ 40 - 0
python/103_Events.py

@@ -0,0 +1,40 @@
+import igl
+
+V1 = igl.eigen.MatrixXd()
+F1 = igl.eigen.MatrixXi()
+
+V2 = igl.eigen.MatrixXd()
+F2 = igl.eigen.MatrixXi()
+
+def key_pressed(viewer, key, modifier):
+    print("Key: ", chr(key))
+
+    if key == ord('1'):
+        # # Clear should be called before drawing the mesh
+        viewer.data.clear();
+        # # Draw_mesh creates or updates the vertices and faces of the displayed mesh.
+        # # If a mesh is already displayed, draw_mesh returns an error if the given V and
+        # # F have size different than the current ones
+        viewer.data.set_mesh(V1, F1);
+        viewer.core.align_camera_center(V1,F1);
+    elif key == ord('2'):
+        viewer.data.clear();
+        viewer.data.set_mesh(V2, F2);
+        viewer.core.align_camera_center(V2,F2);
+    return False
+
+
+#  Load two meshes
+igl.readOFF("../tutorial/shared/bumpy.off", V1, F1);
+igl.readOFF("../tutorial/shared/fertility.off", V2, F2);
+
+print("1 Switch to bump mesh")
+print("2 Switch to fertility mesh")
+
+viewer = igl.viewer.Viewer()
+
+# Register a keyboard callback that allows to switch between
+# the two loaded meshes
+viewer.callback_key_pressed = key_pressed
+viewer.data.set_mesh(V1, F1)
+viewer.launch()

+ 24 - 0
python/104_Colors.py

@@ -0,0 +1,24 @@
+import igl
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+C = igl.eigen.MatrixXd()
+
+# Load a mesh in OFF format
+igl.readOFF("../tutorial/shared/screwdriver.off", V, F)
+
+# Plot the mesh
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+
+# Use the z coordinate as a scalar field over the surface
+Z = V.col(2);
+
+# Compute per-vertex colors
+igl.jet(Z,True,C)
+
+# Add per-vertex colors
+viewer.data.set_colors(C)
+
+# Launch the viewer
+viewer.launch()

+ 67 - 0
python/105_Overlays.py

@@ -0,0 +1,67 @@
+import igl
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+# Load a mesh in OFF format
+igl.readOFF("../tutorial/shared/bunny.off", V, F)
+
+# Find the bounding box
+m = V.colwiseMinCoeff()
+M = V.colwiseMaxCoeff()
+
+
+# Corners of the bounding box
+V_box = igl.eigen.MatrixXd(
+[
+[m[0,0], m[0,1], m[0,2]],
+[M[0,0], m[0,1], m[0,2]],
+[M[0,0], M[0,1], m[0,2]],
+[m[0,0], M[0,1], m[0,2]],
+[m[0,0], m[0,1], M[0,2]],
+[M[0,0], m[0,1], M[0,2]],
+[M[0,0], M[0,1], M[0,2]],
+[m[0,0], M[0,1], M[0,2]]
+]
+)
+
+E_box = igl.eigen.MatrixXi(
+[
+[0, 1],
+[1, 2],
+[2, 3],
+[3, 0],
+[4, 5],
+[5, 6],
+[6, 7],
+[7, 4],
+[0, 4],
+[1, 5],
+[2, 6],
+[7 ,3]
+]
+)
+
+# Plot the mesh
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+
+# Plot the corners of the bounding box as points
+viewer.data.add_points(V_box,igl.eigen.MatrixXd([[1,0,0]]))
+
+# Plot the edges of the bounding box
+for i in range(0,E_box.rows()):
+    viewer.data.add_edges(
+        V_box.row(E_box[i,0]),
+        V_box.row(E_box[i,1]),
+        igl.eigen.MatrixXd([[1,0,0]]))
+
+# Plot labels with the coordinates of bounding box vertices
+l1 = 'x: ' + str(m[0,0]) + ' y: ' + str(m[0,1]) + ' z: ' + str(m[0,2])
+viewer.data.add_label(m.transpose(),l1)
+
+l2 = 'x: ' + str(M[0,0]) + ' y: ' + str(M[0,1]) + ' z: ' + str(M[0,2])
+viewer.data.add_label(M.transpose(),l2);
+
+# Launch the viewer
+viewer.launch();

+ 48 - 0
python/201_Normals.py

@@ -0,0 +1,48 @@
+import igl
+
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+N_vertices = igl.eigen.MatrixXd()
+N_faces = igl.eigen.MatrixXd()
+N_corners = igl.eigen.MatrixXd()
+
+# This function is called every time a keyboard button is pressed
+def key_pressed(viewer, key, modifier):
+    if key == ord('1'):
+      viewer.data.set_normals(N_faces)
+      return True
+    elif key == ord('2'):
+      viewer.data.set_normals(N_vertices)
+      return True
+    elif key == ord('3'):
+      viewer.data.set_normals(N_corners)
+      return True
+    return False
+
+# Load a mesh in OFF format
+igl.readOFF("../tutorial/shared/fandisk.off", V, F);
+
+# Compute per-face normals
+N_faces = igl.eigen.MatrixXd()
+igl.per_face_normals(V,F,N_faces)
+
+# Compute per-vertex normals
+N_vertices = igl.eigen.MatrixXd()
+igl.per_vertex_normals(V,F,igl.PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA,N_vertices)
+
+# Compute per-corner normals, |dihedral angle| > 20 degrees --> crease
+N_corners = igl.eigen.MatrixXd()
+igl.per_corner_normals(V,F,20,N_corners)
+
+# Plot the mesh
+viewer = igl.viewer.Viewer()
+viewer.callback_key_pressed = key_pressed
+viewer.core.show_lines = False
+viewer.data.set_mesh(V, F)
+viewer.data.set_normals(N_faces)
+print("Press '1' for per-face normals.")
+print("Press '2' for per-vertex normals.")
+print("Press '3' for per-corner normals.")
+viewer.launch()

+ 20 - 0
python/202_GaussianCurvature.py

@@ -0,0 +1,20 @@
+import igl
+
+# Load mesh
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+igl.readOFF("../tutorial/shared/bumpy.off",V,F);
+
+# Compute Gaussian curvature
+K = igl.eigen.MatrixXd();
+igl.gaussian_curvature(V,F,K);
+
+# Compute pseudocolor
+C = igl.eigen.MatrixXd();
+igl.jet(K,True,C);
+
+# Plot the mesh with pseudocolors
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+viewer.data.set_colors(C)
+viewer.launch()

+ 61 - 0
python/203_CurvatureDirections.py

@@ -0,0 +1,61 @@
+import igl
+
+V = igl.eigen.MatrixXd();
+F = igl.eigen.MatrixXi();
+igl.read_triangle_mesh("../tutorial/shared/fertility.off", V, F);
+
+# Alternative discrete mean curvature
+HN = igl.eigen.MatrixXd()
+L = igl.eigen.SparseMatrixd()
+M = igl.eigen.SparseMatrixd()
+Minv = igl.eigen.SparseMatrixd()
+
+
+igl.cotmatrix(V,F,L)
+igl.massmatrix(V,F,igl.MASSMATRIX_TYPE_VORONOI,M)
+
+igl.invert_diag(M,Minv)
+
+# Laplace-Beltrami of position
+HN = -Minv*(L*V)
+
+# Extract magnitude as mean curvature
+H = HN.rowwiseNorm()
+
+# Compute curvature directions via quadric fitting
+PD1 = igl.eigen.MatrixXd()
+PD2 = igl.eigen.MatrixXd()
+
+PV1 = igl.eigen.MatrixXd()
+PV2 = igl.eigen.MatrixXd()
+
+igl.principal_curvature(V,F,PD1,PD2,PV1,PV2)
+
+# Mean curvature
+H = 0.5*(PV1+PV2)
+
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+
+# Compute pseudocolor
+C = igl.eigen.MatrixXd()
+igl.parula(H,True,C)
+
+viewer.data.set_colors(C)
+
+# Average edge length for sizing
+avg = igl.avg_edge_length(V,F)
+
+# Draw a blue segment parallel to the minimal curvature direction
+red = igl.eigen.MatrixXd([[0.8,0.2,0.2]])
+blue = igl.eigen.MatrixXd([[0.2,0.2,0.8]])
+
+viewer.data.add_edges(V + PD1*avg, V - PD1*avg, blue)
+
+# Draw a red segment parallel to the maximal curvature direction
+viewer.data.add_edges(V + PD2*avg, V - PD2*avg, red)
+
+# Hide wireframe
+viewer.core.show_lines = False
+
+viewer.launch();

+ 50 - 0
python/204_Gradient.py

@@ -0,0 +1,50 @@
+import igl
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+# Load a mesh in OFF format
+igl.readOFF("../tutorial/shared/cheburashka.off", V, F)
+
+# Read scalar function values from a file, U: #V by 1
+U = igl.eigen.MatrixXd()
+igl.readDMAT("../tutorial/shared/cheburashka-scalar.dmat",U)
+U = U.col(0)
+
+# Compute gradient operator: #F*3 by #V
+G = igl.eigen.SparseMatrixd()
+igl.grad(V,F,G)
+
+# Compute gradient of U
+GU = (G*U).MapMatrix(F.rows(),3)
+
+# Compute gradient magnitude
+GU_mag = GU.rowwiseNorm()
+
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+
+# Compute pseudocolor for original function
+C = igl.eigen.MatrixXd()
+
+igl.jet(U,True,C)
+
+# Or for gradient magnitude
+# igl.jet(GU_mag,True,C)
+
+viewer.data.set_colors(C);
+
+# Average edge length divided by average gradient (for scaling)
+max_size = igl.avg_edge_length(V,F) / GU_mag.mean()
+
+# Draw a black segment in direction of gradient at face barycenters
+BC = igl.eigen.MatrixXd()
+igl.barycenter(V,F,BC)
+
+black = igl.eigen.MatrixXd([[0.0,0.0,0.0]])
+viewer.data.add_edges(BC,BC+max_size*GU, black)
+
+# Hide wireframe
+viewer.core.show_lines = False
+
+viewer.launch()

+ 108 - 0
python/205_Laplacian.py

@@ -0,0 +1,108 @@
+from __future__ import print_function
+import igl
+import math
+
+global V
+global U
+global F
+global L
+
+V = igl.eigen.MatrixXd()
+U = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+L = igl.eigen.SparseMatrixd()
+viewer = igl.viewer.Viewer()
+
+# Load a mesh in OFF format
+igl.readOFF("../tutorial/shared/cow.off", V, F)
+
+# Compute Laplace-Beltrami operator: #V by #V
+igl.cotmatrix(V,F,L)
+
+# Alternative construction of same Laplacian
+G = igl.eigen.SparseMatrixd()
+K = igl.eigen.SparseMatrixd()
+
+# Gradient/Divergence
+igl.grad(V,F,G);
+
+# Diagonal per-triangle "mass matrix"
+dblA = igl.eigen.MatrixXd()
+igl.doublearea(V,F,dblA)
+
+# Place areas along diagonal #dim times
+
+T = (dblA.replicate(3,1)*0.5).asDiagonal() * 1
+
+# Laplacian K built as discrete divergence of gradient or equivalently
+# discrete Dirichelet energy Hessian
+
+temp = -G.transpose()
+K = -G.transpose() * T * G
+print("|K-L|: ",(K-L).norm())
+
+def key_pressed(viewer, key, modifier):
+    global V
+    global U
+    global F
+    global L
+
+    if key == ord('r') or key == ord('R'):
+        U = V;
+    elif key == ord(' '):
+
+        # Recompute just mass matrix on each step
+        M = igl.eigen.SparseMatrixd()
+
+        igl.massmatrix(U,F,igl.MASSMATRIX_TYPE_BARYCENTRIC,M);
+
+        # Solve (M-delta*L) U = M*U
+        S = (M - 0.001*L)
+
+        solver = igl.eigen.SimplicialLLTsparse(S)
+
+        U = solver.solve(M*U)
+
+        # Compute centroid and subtract (also important for numerics)
+        dblA = igl.eigen.MatrixXd()
+        igl.doublearea(U,F,dblA)
+
+        print(dblA.sum())
+
+        area = 0.5*dblA.sum()
+        BC = igl.eigen.MatrixXd()
+        igl.barycenter(U,F,BC)
+        centroid = igl.eigen.MatrixXd([[0.0,0.0,0.0]])
+
+        for i in range(0,BC.rows()):
+            centroid += 0.5*dblA[i,0]/area*BC.row(i)
+
+        U -= centroid.replicate(U.rows(),1)
+
+        # Normalize to unit surface area (important for numerics)
+        U = U / math.sqrt(area)
+    else:
+        return False
+
+    # Send new positions, update normals, recenter
+    viewer.data.set_vertices(U)
+    viewer.data.compute_normals()
+    viewer.core.align_camera_center(U,F)
+    return True
+
+# Use original normals as pseudo-colors
+N = igl.eigen.MatrixXd()
+igl.per_vertex_normals(V,F,N)
+C = N.rowwiseNormalized()*0.5+0.5;
+
+# Initialize smoothing with base mesh
+U = V
+viewer.data.set_mesh(U, F)
+viewer.data.set_colors(C)
+viewer.callback_key_pressed = key_pressed
+
+print("Press [space] to smooth.")
+print("Press [r] to reset.")
+
+viewer.launch()

+ 34 - 0
python/301_Slice.py

@@ -0,0 +1,34 @@
+from __future__ import print_function
+import igl
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+igl.readOFF("../tutorial/shared/decimated-knight.off",V,F)
+
+# 100 random indicies into rows of F
+I = igl.eigen.MatrixXi()
+igl.floor((0.5*(igl.eigen.MatrixXd.Random(100,1)+1.)*F.rows()),I);
+
+# 50 random indicies into rows of I
+J = igl.eigen.MatrixXi()
+igl.floor((0.5*(igl.eigen.MatrixXd.Random(50,1)+1.)*I.rows()),J)
+
+# K = I(J);
+K = igl.eigen.MatrixXi()
+igl.slice(I,J,K)
+
+# default green for all faces
+#C = p2e(np.array([[0.4,0.8,0.3]])).replicate(F.rows(),1)
+C = igl.eigen.MatrixXd([[0.4,0.8,0.3]]).replicate(F.rows(),1)
+
+# Red for each in K
+R = igl.eigen.MatrixXd([[1.0,0.3,0.3]]).replicate(K.rows(),1)
+# C(K,:) = R
+igl.slice_into(R,K,1,C)
+
+# Plot the mesh with pseudocolors
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+viewer.data.set_colors(C)
+viewer.launch()

+ 34 - 0
python/302_Sort.py

@@ -0,0 +1,34 @@
+import igl
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+igl.readOFF("../tutorial/shared/decimated-knight.off",V,F)
+
+# Sort barycenters lexicographically
+BC = igl.eigen.MatrixXd()
+sorted_BC = igl.eigen.MatrixXd()
+
+igl.barycenter(V,F,BC);
+
+I = igl.eigen.MatrixXi()
+J = igl.eigen.MatrixXi()
+
+# sorted_BC = BC(I,:)
+igl.sortrows(BC,True,sorted_BC,I)
+
+# Get sorted "place" from sorted indices
+J.resize(I.rows(),1)
+# J(I) = 1:numel(I)
+
+igl.slice_into(igl.coloni(0,I.size()-1),I,J)
+
+# Pseudo-color based on sorted place
+C = igl.eigen.MatrixXd()
+igl.jet(J.castdouble(),True,C)
+
+# Plot the mesh with pseudocolors
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+viewer.data.set_colors(C)
+viewer.launch()

+ 73 - 0
python/303_LaplaceEquation.py

@@ -0,0 +1,73 @@
+import igl
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+igl.readOFF("../tutorial/shared/camelhead.off",V,F)
+
+# Find boundary edges
+E = igl.eigen.MatrixXi()
+igl.boundary_facets(F,E);
+
+# Find boundary vertices
+b  = igl.eigen.MatrixXi()
+IA = igl.eigen.MatrixXi()
+IC = igl.eigen.MatrixXi()
+
+igl.unique(E,b,IA,IC);
+
+# List of all vertex indices
+vall  = igl.eigen.MatrixXi()
+vin   = igl.eigen.MatrixXi()
+
+igl.coloni(0,V.rows()-1,vall)
+
+# List of interior indices
+igl.setdiff(vall,b,vin,IA)
+
+# Construct and slice up Laplacian
+L = igl.eigen.SparseMatrixd()
+L_in_in = igl.eigen.SparseMatrixd()
+L_in_b = igl.eigen.SparseMatrixd()
+
+igl.cotmatrix(V,F,L)
+igl.slice(L,vin,vin,L_in_in)
+igl.slice(L,vin,b,L_in_b)
+
+# Dirichlet boundary conditions from z-coordinate
+bc = igl.eigen.MatrixXd()
+Z = V.col(2)
+igl.slice(Z,b,bc)
+
+# Solve PDE
+solver = igl.eigen.SimplicialLLTsparse(-L_in_in)
+Z_in = solver.solve(L_in_b*bc)
+
+# slice into solution
+igl.slice_into(Z_in,vin,Z)
+
+# Alternative, short hand
+mqwf = igl.min_quad_with_fixed_data()
+
+# Linear term is 0
+B = igl.eigen.MatrixXd()
+B.setZero(V.rows(),1);
+
+# Empty constraints
+Beq = igl.eigen.MatrixXd()
+Aeq = igl.eigen.SparseMatrixd()
+
+# Our cotmatrix is _negative_ definite, so flip sign
+igl.min_quad_with_fixed_precompute(-L,b,Aeq,True,mqwf)
+igl.min_quad_with_fixed_solve(mqwf,B,bc,Beq,Z)
+
+# Pseudo-color based on solution
+C = igl.eigen.MatrixXd()
+igl.jet(Z,True,C)
+
+# Plot the mesh with pseudocolors
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+viewer.core.show_lines = False
+viewer.data.set_colors(C)
+viewer.launch()

+ 96 - 0
python/304_LinearEqualityConstraints.py

@@ -0,0 +1,96 @@
+import igl
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+igl.readOFF("../tutorial/shared/cheburashka.off",V,F)
+
+# Two fixed points
+# Left hand, left foot
+b = igl.eigen.MatrixXi([[4331],[5957]])
+bc = igl.eigen.MatrixXd([[1],[-1]])
+
+# Construct Laplacian and mass matrix
+L = igl.eigen.SparseMatrixd()
+M = igl.eigen.SparseMatrixd()
+Minv = igl.eigen.SparseMatrixd()
+Q = igl.eigen.SparseMatrixd()
+
+igl.cotmatrix(V,F,L)
+igl.massmatrix(V,F,igl.MASSMATRIX_TYPE_VORONOI,M)
+igl.invert_diag(M,Minv)
+
+# Bi-Laplacian
+Q = L * (Minv * L);
+
+# Zero linear term
+B = igl.eigen.MatrixXd.Zero(V.rows(),1);
+
+Z       = igl.eigen.MatrixXd()
+Z_const = igl.eigen.MatrixXd()
+
+# Alternative, short hand
+mqwf = igl.min_quad_with_fixed_data()
+
+# Empty constraints
+Beq = igl.eigen.MatrixXd()
+Aeq = igl.eigen.SparseMatrixd()
+
+igl.min_quad_with_fixed_precompute(Q,b,Aeq,True,mqwf)
+igl.min_quad_with_fixed_solve(mqwf,B,bc,Beq,Z)
+
+# Constraint forcing difference of two points to be 0
+Aeq = igl.eigen.SparseMatrixd(1,V.rows())
+
+# Right hand, right foot
+Aeq.insert(0,6074,1)
+Aeq.insert(0,6523,-1)
+Aeq.makeCompressed()
+
+Beq = igl.eigen.MatrixXd([[0]])
+igl.min_quad_with_fixed_precompute(Q,b,Aeq,True,mqwf)
+igl.min_quad_with_fixed_solve(mqwf,B,bc,Beq,Z_const)
+
+# Pseudo-color based on solution
+global C
+C = igl.eigen.MatrixXd()
+
+global C_const
+C_const = igl.eigen.MatrixXd()
+
+global toggle
+toggle = True
+
+# Use same color axes
+min_z = min(Z.minCoeff(),Z_const.minCoeff())
+max_z = max(Z.maxCoeff(),Z_const.maxCoeff())
+
+igl.jet(      Z,min_z,max_z,C);
+igl.jet(Z_const,min_z,max_z,C_const);
+
+# Plot the mesh with pseudocolors
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+viewer.core.show_lines = False
+viewer.data.set_colors(C)
+
+def key_down(viewer,key,mode):
+    if key == ord(' '):
+        global toggle
+        global C
+        global C_const
+
+        if toggle:
+            viewer.data.set_colors(C)
+        else:
+            viewer.data.set_colors(C_const)
+
+        toggle = not toggle;
+        return True
+
+    return False
+
+viewer.callback_key_down = key_down
+
+print("Press [space] to toggle between unconstrained and constrained.")
+viewer.launch()

+ 86 - 0
python/305_QuadraticProgramming.py

@@ -0,0 +1,86 @@
+import igl
+
+b = igl.eigen.MatrixXi()
+B = igl.eigen.MatrixXd()
+bc = igl.eigen.MatrixXd()
+lx = igl.eigen.MatrixXd()
+ux = igl.eigen.MatrixXd()
+Beq = igl.eigen.MatrixXd()
+Bieq = igl.eigen.MatrixXd()
+Z = igl.eigen.MatrixXd()
+
+Q = igl.eigen.SparseMatrixd()
+Aeq = igl.eigen.SparseMatrixd()
+Aieq = igl.eigen.SparseMatrixd()
+
+def solve(viewer):
+    global Q,B,b,bc,Aeq,Beq,Aieq,Bieq,lx,ux,Z
+    params = igl.active_set_params()
+    params.max_iter = 8
+
+    igl.active_set(Q,B,b,bc,Aeq,Beq,Aieq,Bieq,lx,ux,params,Z)
+
+    C = igl.eigen.MatrixXd()
+    igl.jet(Z,0,1,C)
+    viewer.data.set_colors(C)
+
+def key_down(viewer, key, mod):
+    global Beq,solve
+    if key == ord('.'):
+         Beq[0,0] = Beq[0,0] * 2.0
+         solve(viewer)
+         return True
+    elif key == ord(','):
+         Beq[0,0] = Beq[0,0] / 2.0
+         solve(viewer)
+         return True
+    elif key == ord(' '):
+         solve(viewer)
+         return True
+    return False;
+
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+igl.readOFF("../tutorial/shared/cheburashka.off",V,F)
+
+# Plot the mesh
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+viewer.core.show_lines = False
+viewer.callback_key_down = key_down
+
+# One fixed point on belly
+b  = igl.eigen.MatrixXi([[2556]])
+bc = igl.eigen.MatrixXd([[1]])
+
+# Construct Laplacian and mass matrix
+L = igl.eigen.SparseMatrixd()
+M = igl.eigen.SparseMatrixd()
+Minv = igl.eigen.SparseMatrixd()
+
+igl.cotmatrix(V,F,L)
+igl.massmatrix(V,F,igl.MASSMATRIX_TYPE_VORONOI,M);
+igl.invert_diag(M,Minv)
+
+# Bi-Laplacian
+Q = L.transpose() * (Minv * L)
+
+# Zero linear term
+B = igl.eigen.MatrixXd.Zero(V.rows(),1)
+
+# Lower and upper bound
+lx = igl.eigen.MatrixXd.Zero(V.rows(),1)
+ux = igl.eigen.MatrixXd.Ones(V.rows(),1)
+
+# Equality constraint constrain solution to sum to 1
+Beq = igl.eigen.MatrixXd([[0.08]])
+Aeq = M.diagonal().transpose().sparseView()
+
+# (Empty inequality constraints)
+solve(viewer)
+print("Press '.' to increase scale and resolve.")
+print("Press ',' to decrease scale and resolve.")
+
+viewer.launch()

+ 56 - 0
python/306_EigenDecomposition.py

@@ -0,0 +1,56 @@
+import igl
+
+V = igl.eigen.MatrixXd()
+U = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+c = 0
+bbd = 1.0
+twod = False
+
+if not igl.read_triangle_mesh("../tutorial/shared/beetle.off",V,F):
+    print("failed to load mesh")
+
+twod = V.col(2).minCoeff() == V.col(2).maxCoeff()
+bbd = (V.colwiseMaxCoeff() - V.colwiseMinCoeff()).norm()
+
+L = igl.eigen.SparseMatrixd()
+M = igl.eigen.SparseMatrixd()
+
+igl.cotmatrix(V,F,L)
+L = -L
+igl.massmatrix(V,F,igl.MASSMATRIX_TYPE_DEFAULT,M)
+k = 5
+
+D = igl.eigen.MatrixXd()
+if not igl.eigs(L,M,k+1,igl.EIGS_TYPE_SM,U,D):
+    print("Eigs failed.")
+
+U = (U-U.minCoeff())/(U.maxCoeff()-U.minCoeff());
+
+viewer = igl.viewer.Viewer()
+
+def key_down(viewer,key,mod):
+    global U, c
+    
+    if key == ord(' '):
+        U = U.rightCols(k)
+
+        # Rescale eigen vectors for visualization
+        Z = bbd*0.5*U.col(c)
+        C = igl.eigen.MatrixXd()
+        igl.parula(U.col(c),False,C)
+        c = (c+1)%U.cols()
+
+        if twod:
+            V.setcol(2,Z)
+
+        viewer.data.set_mesh(V,F)
+        viewer.data.compute_normals()
+        viewer.data.set_colors(C)
+        return True
+
+viewer.callback_key_down = key_down
+viewer.callback_key_down(viewer,ord(' '),0);
+viewer.core.show_lines = False
+viewer.launch()

+ 154 - 0
python/CMakeLists.txt

@@ -0,0 +1,154 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(pybind)
+
+IF(MSVC)
+### Enable parallel compilation for Visual Studio
+  add_definitions(-DEIGEN_DONT_ALIGN)
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
+  SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/../ )
+  SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/../ )
+ENDIF(MSVC)
+
+SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../tutorial/cmake)
+
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+  message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
+  set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
+  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
+    "MinSizeRel" "RelWithDebInfo")
+endif()
+
+find_package(OPENGL REQUIRED)
+
+# Force a specific python version
+# SET(PYTHON_LIBRARIES "D:/Python34/libs/python34.lib")
+# SET(PYTHON_INCLUDE_DIR "D:/Python34/include")
+
+# Force a specific python version
+# SET(PYTHON_LIBRARIES "/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/lib/libpython3.5m.dylib")
+# SET(PYTHON_INCLUDE_DIR "/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/include/python3.5m")
+
+set(Python_ADDITIONAL_VERSIONS 3.4.3 3.5 3.6)
+find_package(PythonLibs REQUIRED)
+find_package(PythonInterp REQUIRED)
+
+string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
+if (UNIX)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+  if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -flto")
+  endif()
+endif()
+
+# Compile with compiler warnings turned on
+if(MSVC)
+  if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
+    string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+  else()
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
+  endif()
+else()
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
+endif()
+
+include_directories(${PYTHON_INCLUDE_DIR} include)
+
+## include pybing
+include_directories(${PROJECT_SOURCE_DIR}/../external/pybind11/include)
+
+## include eigen
+include_directories(${PROJECT_SOURCE_DIR}/../external/nanogui/ext/eigen)
+
+## include libigl
+include_directories(${PROJECT_SOURCE_DIR}/../include)
+
+## include glew
+if(NOT APPLE)
+  find_package(GLEW REQUIRED)
+  include_directories( ${GLEW_INCLUDE_DIR} )
+	set(SHARED_SOURCES ${SHARED_SOURCES} ${GLEW_SOURCES})
+endif(NOT APPLE)
+
+
+# include nanogui and dependencies
+add_subdirectory("../external/nanogui/" "nanogui")
+include_directories("../external/nanogui/include")
+include_directories("../external/nanogui/ext/glfw/include")
+include_directories("../external/nanogui/ext/nanovg/src")
+list(APPEND SHARED_LIBRARIES "nanogui" "glfw" ${OPENGL_LIBRARIES})
+
+
+add_library(igl SHARED
+  python.cpp
+  py_vector.cpp
+  py_igl.cpp
+  py_doc.cpp
+  py_igl_viewer.cpp
+  ${SHARED_SOURCES}
+)
+
+# if(NOT APPLE)
+# 	find_package(GLEW REQUIRED)
+# endif(NOT APPLE)
+
+if(APPLE)
+	set(CMAKE_SHARED_LINKER_FLAGS "-framework OpenGL -framework Cocoa")
+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  -lXcursor -lXinerama ")
+#   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
+# endif(UNIX AND NOT APPLE)
+
+
+set_target_properties(igl PROPERTIES PREFIX "")
+set_target_properties(igl PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
+
+target_link_libraries(igl ${SHARED_LIBRARIES})
+
+if (WIN32)
+  if (MSVC)
+    # Enforce size-based optimization and link time code generation on MSVC (~30% smaller binaries in experiments)
+    set_target_properties(igl PROPERTIES COMPILE_FLAGS "/Os /GL")
+    set_target_properties(igl PROPERTIES LINK_FLAGS "/LTCG")
+  endif()
+
+  # .PYD file extension on Windows
+  set_target_properties(igl PROPERTIES SUFFIX ".pyd")
+
+  # Link against the Python shared library
+  # message(FATAL_ERROR ${PYTHON_LIBRARY})
+  # target_link_libraries(igl ${PYTHON_LIBRARY})
+  target_link_libraries(igl ${PYTHON_LIBRARIES})
+
+
+elseif (UNIX)
+  # It's quite common to have multiple copies of the same Python version
+  # installed on one's system. E.g.: one copy from the OS and another copy
+  # that's statically linked into an application like Blender or Maya.
+  # If we link our plugin library against the OS Python here and import it
+  # into Blender or Maya later on, this will cause segfaults when multiple
+  # conflicting Python instances are active at the same time.
+
+  # Windows does not seem to be affected by this issue. The solution for Linux
+  # and Mac OS is simple: we just don't link against the Python library. The
+  # resulting shared library will have missing symbols, but that's perfectly
+  # fine -- they will be resolved at import time.
+
+  # .SO file extension on Linux/Mac OS
+  set_target_properties(igl PROPERTIES SUFFIX ".so")
+
+  # Strip unnecessary sections of the binary on Linux/Mac OS
+  if(APPLE)
+    set_target_properties(igl PROPERTIES MACOSX_RPATH ".")
+    set_target_properties(igl PROPERTIES LINK_FLAGS "-undefined dynamic_lookup -dead_strip")
+    if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
+      add_custom_command(TARGET igl POST_BUILD COMMAND strip -u -r ${CMAKE_CURRENT_BINARY_DIR}/../igl.so)
+    endif()
+  else()
+    if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
+      add_custom_command(TARGET igl POST_BUILD COMMAND strip ${CMAKE_CURRENT_BINARY_DIR}/../igl.so)
+    endif()
+  endif()
+endif()

+ 159 - 0
python/README.md

@@ -0,0 +1,159 @@
+# Python wrappers for libigl
+
+
+## Work in progress
+<span style="color:#F62217">
+Everything in this folder is currently being developed and it is likely to be
+changed radically in the next couple of months, breaking compatibility between
+different version. We plan to stabilize the python API by the end of 2015.
+</span>
+
+## Introduction
+
+libigl functions can be called natively from python by compiling the wrappers
+in this folder. The wrappers supports both python 2.7 and python 3.5 and are
+generated using [pybind11](https://github.com/wjakob/pybind11).
+
+The generated library will statically link against all dependencies producing a single,
+self-contained binary.
+
+## Installation
+
+The python bindings can be compiled with the following instructions, assuming
+that your terminal is pointing to the root of libigl:
+
+```bash
+cd python
+mkdir build
+cd build; make; cd ..
+```
+
+The cmake script will complain if it is not able to find python. In that case
+you can specify the location of the interpreter by specifying the following
+cmake variables.
+
+MacOSX/Linux:
+
+```cmake
+SET(PYTHON_LIBRARIES "/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/lib/libpython3.5m.dylib")
+SET(PYTHON_INCLUDE_DIR "/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/include/python3.5m")
+```
+
+Windows:
+
+```cmake
+SET(PYTHON_LIBRARIES "C:/Python35/libs/python35.lib")
+SET(PYTHON_INCLUDE_DIR "C:/Python35/include")
+```
+
+## Tutorial
+
+All libigl tutorials will be ported to python and will use the same naming
+scheme. You can find the tutorials in the folder python/tutorials and you can
+launch them with the following commands:
+
+```bash
+cd python
+python 102_DrawMesh.py
+```
+
+## Matrix Representation
+
+TODO: describe in detail the wrapped eigen classes and how to convert them to
+numpy.
+
+## Viewer and callbacks
+
+The igl viewer provides a convenient and efficient way of visualizing 3D
+surfaces in python. It behaves in the same way as the C++ viewer and supports
+native python functions as callbacks. This is a simple example that loads
+two meshes and switches between the two when a key is pressed:
+
+```python
+import igl
+
+V1 = igl.eigen.MatrixXd()
+F1 = igl.eigen.MatrixXi()
+
+V2 = igl.eigen.MatrixXd()
+F2 = igl.eigen.MatrixXi()
+
+def key_pressed(viewer, key, modifier):
+    print("Key: ", chr(key))
+
+    if key == ord('1'):
+        # # Clear should be called before drawing the mesh
+        viewer.data.clear();
+        # # Draw_mesh creates or updates the vertices and faces of the displayed mesh.
+        # # If a mesh is already displayed, draw_mesh returns an error if the given V and
+        # # F have size different than the current ones
+        viewer.data.set_mesh(V1, F1);
+        viewer.core.align_camera_center(V1,F1);
+    elif key == ord('2'):
+        viewer.data.clear();
+        viewer.data.set_mesh(V2, F2);
+        viewer.core.align_camera_center(V2,F2);
+    return False
+
+
+#  Load two meshes
+igl.readOFF("../tutorial/shared/bumpy.off", V1, F1);
+igl.readOFF("../tutorial/shared/fertility.off", V2, F2);
+
+print("1 Switch to bump mesh")
+print("2 Switch to fertility mesh")
+
+viewer = igl.viewer.Viewer()
+
+# Register a keyboard callback that allows to switch between
+# the two loaded meshes
+viewer.callback_key_pressed = key_pressed
+viewer.data.set_mesh(V1, F1)
+viewer.launch()
+```
+
+### Remote viewer
+
+Whe using the viewer from an interactive python shell (iPython), it is
+inconvenient to let the viewer take control of the main thread for rendering
+purposes. We provide a simple wrapper for the viewer that allows to launch
+a remote process and send meshes to it via a TCP/IP socket. For more
+informations on how to use it see the documentation in [tcpviewer.py](tcpviewer.py)
+
+## Matlab
+
+The python wrappers can be natively being used from MATLAB.
+We provide a few examples in the folder python/matlab.
+
+## Documentation
+
+The python functions have exactly the same prototypes as their C++ counterpart.
+To get help for a certain function, please check the documentation in the
+corresponding .h file in libigl/include. We will add a proper docstring
+documentation in the future.
+
+## Known Issues
+
+## Contact
+
+Libigl is a group endeavor led by [Alec
+Jacobson](http://www.cs.columbia.edu/~jacobson/) and [Daniele
+Panozzo](http://www.inf.ethz.ch/personal/dpanozzo/). Please [contact
+us](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com) if you have
+questions or comments. For troubleshooting, please post an
+[issue](https://github.com/libigl/libigl/issues) on github.
+
+If you're using libigl in your projects, quickly [drop us a
+note](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com). Tell us who you
+are and what you're using it for. This helps us apply for funding and justify
+spending time maintaining this.
+
+If you find bugs or have problems please use our [github issue tracking
+page](https://github.com/libigl/libigl/issues).
+
+## Copyright
+2015 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan
+Zhou, Nico Pietroni, Stefan Brugger, Kenshi Takayama, Wenzel Jakob, Nikolas De
+Giorgis, Luigi Rocca, Leonardo Sacht, Olga Sorkine-Hornung, and others.
+
+Please see individual files for appropriate copyright notices.

+ 51 - 0
python/iglhelpers.py

@@ -0,0 +1,51 @@
+import numpy as np
+import scipy.sparse as sparse
+import igl
+
+def p2e(m):
+    if isinstance(m, np.ndarray):
+        if m.dtype.type == np.int32:
+            return igl.eigen.MatrixXi(m)
+        elif m.dtype.type == np.float64:
+            return igl.eigen.MatrixXd(m)
+        raise TypeError("p2e only support dtype float64 or int32")
+    if sparse.issparse(m):
+        # convert in a dense matrix with triples
+        coo = m.tocoo()
+        triplets = np.vstack((coo.row, coo.col, coo.data)).T
+
+        triples_eigen_wrapper = igl.eigen.MatrixXd(triplets)
+
+        if m.dtype.type == np.int32:
+            t = igl.eigen.SparseMatrixi()
+            t.fromcoo(triples_eigen_wrapper)
+            return t
+        elif m.dtype.type == np.float64:
+            t = igl.eigen.SparseMatrixd()
+            t.fromCOO(triples_eigen_wrapper)
+            return t
+
+
+    raise TypeError("p2e only support numpy.array or scipy.sparse")
+
+
+def e2p(m):
+    if isinstance(m, igl.eigen.MatrixXd):
+        return np.array(m, dtype='float64')
+    elif isinstance(m, igl.eigen.MatrixXi):
+        return np.array(m, dtype='int32')
+    elif isinstance(m, igl.eigen.SparseMatrixd):
+        coo = np.array(m.toCOO())
+        I = coo[:, 0]
+        J = coo[:, 1]
+        V = coo[:, 2]
+        return sparse.coo_matrix((V,(I,J)), shape=(m.rows(),m.cols()), dtype='float64')
+    elif isinstance(m, igl.eigen.SparseMatrixi):
+        coo = np.array(m.toCOO())
+        I = coo[:, 0]
+        J = coo[:, 1]
+        V = coo[:, 2]
+        return sparse.coo_matrix((V,(I,J)), shape=(m.rows(),m.cols()), dtype='int32')
+
+def printMatrixSizes(x,xn):
+    print(xn + " (" + str(x.rows()) + "," + str(x.cols()) + ")")

+ 59 - 0
python/matlab/CurvatureDirections.m

@@ -0,0 +1,59 @@
+V = py.igl.eigen.MatrixXd();
+F = py.igl.eigen.MatrixXi();
+py.igl.read_triangle_mesh('../tutorial/shared/fertility.off', V, F);
+
+% Alternative discrete mean curvature
+HN = py.igl.eigen.MatrixXd();
+L = py.igl.eigen.SparseMatrixd();
+M = py.igl.eigen.SparseMatrixd();
+Minv = py.igl.eigen.SparseMatrixd();
+
+
+py.igl.cotmatrix(V,F,L)
+py.igl.massmatrix(V,F,py.igl.MASSMATRIX_TYPE_VORONOI,M)
+
+py.igl.invert_diag(M,Minv)
+
+% Laplace-Beltrami of position
+HN = -Minv*(L*V)
+
+% Extract magnitude as mean curvature
+H = HN.rowwiseNorm()
+
+% Compute curvature directions via quadric fitting
+PD1 = py.igl.eigen.MatrixXd()
+PD2 = py.igl.eigen.MatrixXd()
+
+PV1 = py.igl.eigen.MatrixXd()
+PV2 = py.igl.eigen.MatrixXd()
+
+py.igl.principal_curvature(V,F,PD1,PD2,PV1,PV2)
+
+% Mean curvature
+H = 0.5*(PV1+PV2)
+
+viewer = py.igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+
+% Compute pseudocolor
+C = py.igl.eigen.MatrixXd()
+py.igl.parula(H,true,C)
+
+viewer.data.set_colors(C)
+
+% Average edge length for sizing
+avg = py.igl.avg_edge_length(V,F)
+
+% Draw a blue segment parallel to the minimal curvature direction
+red = py.iglhelpers.p2e(py.numpy.array([[0.8,0.2,0.2]]))
+blue = py.iglhelpers.p2e(py.numpy.array([[0.2,0.2,0.8]]))
+
+viewer.data.add_edges(V + PD1*avg, V - PD1*avg, blue)
+
+% Draw a red segment parallel to the maximal curvature direction
+viewer.data.add_edges(V + PD2*avg, V - PD2*avg, red)
+
+% Hide wireframe
+viewer.core.show_lines = false
+
+viewer.launch()

+ 12 - 0
python/matlab/t102DrawMesh.m

@@ -0,0 +1,12 @@
+% Load a mesh in OFF format
+V = py.igl.eigen.MatrixXd();
+F = py.igl.eigen.MatrixXi();
+py.igl.readOFF('../tutorial/shared/beetle.off', V, F);
+
+V
+
+% Plot the mesh
+viewer = py.tcpviewer.TCPViewer()
+viewer.data.set_mesh(V, F)
+viewer.launch()
+

+ 409 - 0
python/py_doc.cpp

@@ -0,0 +1,409 @@
+const char *__doc_igl_AABB = R"igl_Qu8mg5v7(See igl\AABB.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_active_set = R"igl_Qu8mg5v7(See igl\active_set.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_adjacency_list = R"igl_Qu8mg5v7(See igl\adjacency_list.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_adjacency_matrix = R"igl_Qu8mg5v7(See igl\adjacency_matrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_all_edges = R"igl_Qu8mg5v7(See igl\all_edges.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_all_pairs_distances = R"igl_Qu8mg5v7(See igl\all_pairs_distances.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_angle_bound_frame_fields = R"igl_Qu8mg5v7(See igl\angle_bound_frame_fields.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_angular_distance = R"igl_Qu8mg5v7(See igl\angular_distance.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_any_of = R"igl_Qu8mg5v7(See igl\any_of.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_arap = R"igl_Qu8mg5v7(See igl\arap.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_ARAPEnergyType = R"igl_Qu8mg5v7(See igl\ARAPEnergyType.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_arap_dof = R"igl_Qu8mg5v7(See igl\arap_dof.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_arap_linear_block = R"igl_Qu8mg5v7(See igl\arap_linear_block.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_arap_rhs = R"igl_Qu8mg5v7(See igl\arap_rhs.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_average_onto_faces = R"igl_Qu8mg5v7(See igl\average_onto_faces.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_average_onto_vertices = R"igl_Qu8mg5v7(See igl\average_onto_vertices.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_avg_edge_length = R"igl_Qu8mg5v7(See igl\avg_edge_length.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_axis_angle_to_quat = R"igl_Qu8mg5v7(See igl\axis_angle_to_quat.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_barycenter = R"igl_Qu8mg5v7(See igl\barycenter.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_barycentric_coordinates = R"igl_Qu8mg5v7(See igl\barycentric_coordinates.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_barycentric_to_global = R"igl_Qu8mg5v7(See igl\barycentric_to_global.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_basename = R"igl_Qu8mg5v7(See igl\basename.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_bfs_orient = R"igl_Qu8mg5v7(See igl\bfs_orient.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_biharmonic_coordinates = R"igl_Qu8mg5v7(See igl\biharmonic_coordinates.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_bone_parents = R"igl_Qu8mg5v7(See igl\bone_parents.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_boundary_conditions = R"igl_Qu8mg5v7(See igl\boundary_conditions.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_boundary_facets = R"igl_Qu8mg5v7(See igl\boundary_facets.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_boundary_loop = R"igl_Qu8mg5v7(See igl\boundary_loop.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_bounding_box = R"igl_Qu8mg5v7(See igl\bounding_box.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_bounding_box_diagonal = R"igl_Qu8mg5v7(See igl\bounding_box_diagonal.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_Camera = R"igl_Qu8mg5v7(See igl\Camera.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_canonical_quaternions = R"igl_Qu8mg5v7(See igl\canonical_quaternions.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cat = R"igl_Qu8mg5v7(See igl\cat.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_ceil = R"igl_Qu8mg5v7(See igl\ceil.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_centroid = R"igl_Qu8mg5v7(See igl\centroid.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_circulation = R"igl_Qu8mg5v7(See igl\circulation.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_collapse_edge = R"igl_Qu8mg5v7(See igl\collapse_edge.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_collapse_small_triangles = R"igl_Qu8mg5v7(See igl\collapse_small_triangles.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_colon = R"igl_Qu8mg5v7(See igl\colon.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_columnize = R"igl_Qu8mg5v7(See igl\columnize.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_column_to_quats = R"igl_Qu8mg5v7(See igl\column_to_quats.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_comb_cross_field = R"igl_Qu8mg5v7(See igl\comb_cross_field.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_comb_frame_field = R"igl_Qu8mg5v7(See igl\comb_frame_field.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_comb_line_field = R"igl_Qu8mg5v7(See igl\comb_line_field.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_components = R"igl_Qu8mg5v7(See igl\components.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_compute_frame_field_bisectors = R"igl_Qu8mg5v7(See igl\compute_frame_field_bisectors.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_ConjugateFFSolverData = R"igl_Qu8mg5v7(See igl\ConjugateFFSolverData.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_conjugate_frame_fields = R"igl_Qu8mg5v7(See igl\conjugate_frame_fields.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cotmatrix = R"igl_Qu8mg5v7(See igl\cotmatrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cotmatrix_entries = R"igl_Qu8mg5v7(See igl\cotmatrix_entries.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_covariance_scatter_matrix = R"igl_Qu8mg5v7(See igl\covariance_scatter_matrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cross = R"igl_Qu8mg5v7(See igl\cross.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cross_field_missmatch = R"igl_Qu8mg5v7(See igl\cross_field_missmatch.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_crouzeix_raviart_massmatrix = R"igl_Qu8mg5v7(See igl\crouzeix_raviart_massmatrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cumsum = R"igl_Qu8mg5v7(See igl\cumsum.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cut_mesh = R"igl_Qu8mg5v7(See igl\cut_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cut_mesh_from_singularities = R"igl_Qu8mg5v7(See igl\cut_mesh_from_singularities.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_C_STR = R"igl_Qu8mg5v7(See igl\C_STR.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_dated_copy = R"igl_Qu8mg5v7(See igl\dated_copy.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_decimate = R"igl_Qu8mg5v7(See igl\decimate.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_deform_skeleton = R"igl_Qu8mg5v7(See igl\deform_skeleton.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_deprecated = R"igl_Qu8mg5v7(See igl\deprecated.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_diag = R"igl_Qu8mg5v7(See igl\diag.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_dihedral_angles = R"igl_Qu8mg5v7(See igl\dihedral_angles.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_dijkstra = R"igl_Qu8mg5v7(See igl\dijkstra.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_directed_edge_orientations = R"igl_Qu8mg5v7(See igl\directed_edge_orientations.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_directed_edge_parents = R"igl_Qu8mg5v7(See igl\directed_edge_parents.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_dirname = R"igl_Qu8mg5v7(See igl\dirname.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_dot = R"igl_Qu8mg5v7(See igl\dot.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_dot_row = R"igl_Qu8mg5v7(See igl\dot_row.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_doublearea = R"igl_Qu8mg5v7(See igl\doublearea.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_dqs = R"igl_Qu8mg5v7(See igl\dqs.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_edges = R"igl_Qu8mg5v7(See igl\edges.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_edge_collapse_is_valid = R"igl_Qu8mg5v7(See igl\edge_collapse_is_valid.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_edge_flaps = R"igl_Qu8mg5v7(See igl\edge_flaps.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_edge_lengths = R"igl_Qu8mg5v7(See igl\edge_lengths.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_edge_topology = R"igl_Qu8mg5v7(See igl\edge_topology.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_eigs = R"igl_Qu8mg5v7(See igl\eigs.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_EPS = R"igl_Qu8mg5v7(See igl\EPS.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_example_fun = R"igl_Qu8mg5v7(See igl\example_fun.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_exterior_edges = R"igl_Qu8mg5v7(See igl\exterior_edges.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_faces_first = R"igl_Qu8mg5v7(See igl\faces_first.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_facet_components = R"igl_Qu8mg5v7(See igl\facet_components.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_face_areas = R"igl_Qu8mg5v7(See igl\face_areas.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_face_occurrences = R"igl_Qu8mg5v7(See igl\face_occurrences.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_false_barycentric_subdivision = R"igl_Qu8mg5v7(See igl\false_barycentric_subdivision.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_field_local_global_conversions = R"igl_Qu8mg5v7(See igl\field_local_global_conversions.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_file_contents_as_string = R"igl_Qu8mg5v7(See igl\file_contents_as_string.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_file_dialog_open = R"igl_Qu8mg5v7(See igl\file_dialog_open.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_file_dialog_save = R"igl_Qu8mg5v7(See igl\file_dialog_save.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_file_exists = R"igl_Qu8mg5v7(See igl\file_exists.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_find = R"igl_Qu8mg5v7(See igl\find.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_find_cross_field_singularities = R"igl_Qu8mg5v7(See igl\find_cross_field_singularities.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_fit_plane = R"igl_Qu8mg5v7(See igl\fit_plane.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_fit_rigid = R"igl_Qu8mg5v7(See igl\fit_rigid.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_fit_rotations = R"igl_Qu8mg5v7(See igl\fit_rotations.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_floor = R"igl_Qu8mg5v7(See igl\floor.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_forward_kinematics = R"igl_Qu8mg5v7(See igl\forward_kinematics.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_frame_field_deformer = R"igl_Qu8mg5v7(See igl\frame_field_deformer.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_frame_to_cross_field = R"igl_Qu8mg5v7(See igl\frame_to_cross_field.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_frustum = R"igl_Qu8mg5v7(See igl\frustum.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_full = R"igl_Qu8mg5v7(See igl\full.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_gaussian_curvature = R"igl_Qu8mg5v7(See igl\gaussian_curvature.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_get_seconds = R"igl_Qu8mg5v7(See igl\get_seconds.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_get_seconds_hires = R"igl_Qu8mg5v7(See igl\get_seconds_hires.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_grad = R"igl_Qu8mg5v7(See igl\grad.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_group_sum_matrix = R"igl_Qu8mg5v7(See igl\group_sum_matrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_HalfEdgeIterator = R"igl_Qu8mg5v7(See igl\HalfEdgeIterator.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_harmonic = R"igl_Qu8mg5v7(See igl\harmonic.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_harwell_boeing = R"igl_Qu8mg5v7(See igl\harwell_boeing.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_histc = R"igl_Qu8mg5v7(See igl\histc.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_hsv_to_rgb = R"igl_Qu8mg5v7(See igl\hsv_to_rgb.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_igl_inline = R"igl_Qu8mg5v7(See igl\igl_inline.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_IndexComparison = R"igl_Qu8mg5v7(See igl\IndexComparison.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_integrable_polyvector_fields = R"igl_Qu8mg5v7(See igl\integrable_polyvector_fields.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_internal_angles = R"igl_Qu8mg5v7(See igl\internal_angles.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_intersect = R"igl_Qu8mg5v7(See igl\intersect.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_invert_diag = R"igl_Qu8mg5v7(See igl\invert_diag.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_in_element = R"igl_Qu8mg5v7(See igl\in_element.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_border_vertex = R"igl_Qu8mg5v7(See igl\is_border_vertex.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_boundary_edge = R"igl_Qu8mg5v7(See igl\is_boundary_edge.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_dir = R"igl_Qu8mg5v7(See igl\is_dir.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_edge_manifold = R"igl_Qu8mg5v7(See igl\is_edge_manifold.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_file = R"igl_Qu8mg5v7(See igl\is_file.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_irregular_vertex = R"igl_Qu8mg5v7(See igl\is_irregular_vertex.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_planar = R"igl_Qu8mg5v7(See igl\is_planar.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_readable = R"igl_Qu8mg5v7(See igl\is_readable.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_sparse = R"igl_Qu8mg5v7(See igl\is_sparse.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_symmetric = R"igl_Qu8mg5v7(See igl\is_symmetric.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_vertex_manifold = R"igl_Qu8mg5v7(See igl\is_vertex_manifold.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_is_writable = R"igl_Qu8mg5v7(See igl\is_writable.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_jet = R"igl_Qu8mg5v7(See igl\jet.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_launch_medit = R"igl_Qu8mg5v7(See igl\launch_medit.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_lbs_matrix = R"igl_Qu8mg5v7(See igl\lbs_matrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_limit_faces = R"igl_Qu8mg5v7(See igl\limit_faces.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_line_field_missmatch = R"igl_Qu8mg5v7(See igl\line_field_missmatch.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_line_segment_in_rectangle = R"igl_Qu8mg5v7(See igl\line_segment_in_rectangle.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_linprog = R"igl_Qu8mg5v7(See igl\linprog.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_list_to_matrix = R"igl_Qu8mg5v7(See igl\list_to_matrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_local_basis = R"igl_Qu8mg5v7(See igl\local_basis.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_look_at = R"igl_Qu8mg5v7(See igl\look_at.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_lscm = R"igl_Qu8mg5v7(See igl\lscm.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_lu_lagrange = R"igl_Qu8mg5v7(See igl\lu_lagrange.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_map_vertices_to_circle = R"igl_Qu8mg5v7(See igl\map_vertices_to_circle.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_marching_cubes = R"igl_Qu8mg5v7(See igl\marching_cubes.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_massmatrix = R"igl_Qu8mg5v7(See igl\massmatrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_material_colors = R"igl_Qu8mg5v7(See igl\material_colors.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_matlab_format = R"igl_Qu8mg5v7(See igl\matlab_format.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_matrix_to_list = R"igl_Qu8mg5v7(See igl\matrix_to_list.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_mat_max = R"igl_Qu8mg5v7(See igl\mat_max.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_mat_min = R"igl_Qu8mg5v7(See igl\mat_min.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_mat_to_quat = R"igl_Qu8mg5v7(See igl\mat_to_quat.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_max_size = R"igl_Qu8mg5v7(See igl\max_size.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_median = R"igl_Qu8mg5v7(See igl\median.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_min_quad_dense = R"igl_Qu8mg5v7(See igl\min_quad_dense.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_min_quad_with_fixed = R"igl_Qu8mg5v7(See igl\min_quad_with_fixed.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_min_size = R"igl_Qu8mg5v7(See igl\min_size.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_mod = R"igl_Qu8mg5v7(See igl\mod.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_mode = R"igl_Qu8mg5v7(See igl\mode.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_mvc = R"igl_Qu8mg5v7(See igl\mvc.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_nchoosek = R"igl_Qu8mg5v7(See igl\nchoosek.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_next_filename = R"igl_Qu8mg5v7(See igl\next_filename.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_normalize_quat = R"igl_Qu8mg5v7(See igl\normalize_quat.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_normalize_row_lengths = R"igl_Qu8mg5v7(See igl\normalize_row_lengths.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_normalize_row_sums = R"igl_Qu8mg5v7(See igl\normalize_row_sums.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_NormalType = R"igl_Qu8mg5v7(See igl\NormalType.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_normal_derivative = R"igl_Qu8mg5v7(See igl\normal_derivative.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_null = R"igl_Qu8mg5v7(See igl\null.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_n_polyvector = R"igl_Qu8mg5v7(See igl\n_polyvector.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_n_polyvector_general = R"igl_Qu8mg5v7(See igl\n_polyvector_general.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_ONE = R"igl_Qu8mg5v7(See igl\ONE.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_on_boundary = R"igl_Qu8mg5v7(See igl\on_boundary.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_orientable_patches = R"igl_Qu8mg5v7(See igl\orientable_patches.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_orient_outward = R"igl_Qu8mg5v7(See igl\orient_outward.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_orth = R"igl_Qu8mg5v7(See igl\orth.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_ortho = R"igl_Qu8mg5v7(See igl\ortho.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_outer_facet = R"igl_Qu8mg5v7(See igl\outer_facet.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_parallel_transport_angles = R"igl_Qu8mg5v7(See igl\parallel_transport_angles.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_partition = R"igl_Qu8mg5v7(See igl\partition.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_parula = R"igl_Qu8mg5v7(See igl\parula.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_pathinfo = R"igl_Qu8mg5v7(See igl\pathinfo.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_path_to_executable = R"igl_Qu8mg5v7(See igl\path_to_executable.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_per_corner_normals = R"igl_Qu8mg5v7(See igl\per_corner_normals.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_per_edge_normals = R"igl_Qu8mg5v7(See igl\per_edge_normals.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_per_face_normals = R"igl_Qu8mg5v7(See igl\per_face_normals.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_per_vertex_attribute_smoothing = R"igl_Qu8mg5v7(See igl\per_vertex_attribute_smoothing.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_per_vertex_normals = R"igl_Qu8mg5v7(See igl\per_vertex_normals.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_PI = R"igl_Qu8mg5v7(See igl\PI.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_planarize_quad_mesh = R"igl_Qu8mg5v7(See igl\planarize_quad_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_ply = R"igl_Qu8mg5v7(See igl\ply.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_point_in_circle = R"igl_Qu8mg5v7(See igl\point_in_circle.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_point_in_poly = R"igl_Qu8mg5v7(See igl\point_in_poly.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_point_mesh_squared_distance = R"igl_Qu8mg5v7(See igl\point_mesh_squared_distance.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polar_dec = R"igl_Qu8mg5v7(See igl\polar_dec.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polar_svd = R"igl_Qu8mg5v7(See igl\polar_svd.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polar_svd3x3 = R"igl_Qu8mg5v7(See igl\polar_svd3x3.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polygon_mesh_to_triangle_mesh = R"igl_Qu8mg5v7(See igl\polygon_mesh_to_triangle_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polyroots = R"igl_Qu8mg5v7(See igl\polyroots.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polyvector_field_comb_from_matchings_and_cuts = R"igl_Qu8mg5v7(See igl\polyvector_field_comb_from_matchings_and_cuts.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polyvector_field_cut_mesh_with_singularities = R"igl_Qu8mg5v7(See igl\polyvector_field_cut_mesh_with_singularities.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polyvector_field_matchings = R"igl_Qu8mg5v7(See igl\polyvector_field_matchings.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polyvector_field_poisson_reconstruction = R"igl_Qu8mg5v7(See igl\polyvector_field_poisson_reconstruction.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_polyvector_field_singularities_from_matchings = R"igl_Qu8mg5v7(See igl\polyvector_field_singularities_from_matchings.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_principal_curvature = R"igl_Qu8mg5v7(See igl\principal_curvature.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_print_ijv = R"igl_Qu8mg5v7(See igl\print_ijv.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_print_vector = R"igl_Qu8mg5v7(See igl\print_vector.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_procrustes = R"igl_Qu8mg5v7(See igl\procrustes.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_project = R"igl_Qu8mg5v7(See igl\project.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_project_isometrically_to_plane = R"igl_Qu8mg5v7(See igl\project_isometrically_to_plane.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_project_to_line = R"igl_Qu8mg5v7(See igl\project_to_line.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_project_to_line_segment = R"igl_Qu8mg5v7(See igl\project_to_line_segment.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_pseudonormal_test = R"igl_Qu8mg5v7(See igl\pseudonormal_test.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_quad_planarity = R"igl_Qu8mg5v7(See igl\quad_planarity.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_quats_to_column = R"igl_Qu8mg5v7(See igl\quats_to_column.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_quat_conjugate = R"igl_Qu8mg5v7(See igl\quat_conjugate.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_quat_mult = R"igl_Qu8mg5v7(See igl\quat_mult.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_quat_to_axis_angle = R"igl_Qu8mg5v7(See igl\quat_to_axis_angle.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_quat_to_mat = R"igl_Qu8mg5v7(See igl\quat_to_mat.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_random_dir = R"igl_Qu8mg5v7(See igl\random_dir.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_random_points_on_mesh = R"igl_Qu8mg5v7(See igl\random_points_on_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_random_quaternion = R"igl_Qu8mg5v7(See igl\random_quaternion.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_randperm = R"igl_Qu8mg5v7(See igl\randperm.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_ray_sphere_intersect = R"igl_Qu8mg5v7(See igl\ray_sphere_intersect.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readCSV = R"igl_Qu8mg5v7(See igl\readCSV.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readDMAT = R"igl_Qu8mg5v7(See igl\readDMAT.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readMESH = R"igl_Qu8mg5v7(See igl\readMESH.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readNODE = R"igl_Qu8mg5v7(See igl\readNODE.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readOBJ = R"igl_Qu8mg5v7(See igl\readOBJ.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readOFF = R"igl_Qu8mg5v7(See igl\readOFF.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readPLY = R"igl_Qu8mg5v7(See igl\readPLY.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readSTL = R"igl_Qu8mg5v7(See igl\readSTL.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readTGF = R"igl_Qu8mg5v7(See igl\readTGF.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_readWRL = R"igl_Qu8mg5v7(See igl\readWRL.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_read_triangle_mesh = R"igl_Qu8mg5v7(See igl\read_triangle_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_REDRUM = R"igl_Qu8mg5v7(See igl\REDRUM.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_remove_duplicates = R"igl_Qu8mg5v7(See igl\remove_duplicates.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_remove_duplicate_vertices = R"igl_Qu8mg5v7(See igl\remove_duplicate_vertices.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_remove_unreferenced = R"igl_Qu8mg5v7(See igl\remove_unreferenced.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_reorder = R"igl_Qu8mg5v7(See igl\reorder.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_repdiag = R"igl_Qu8mg5v7(See igl\repdiag.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_repmat = R"igl_Qu8mg5v7(See igl\repmat.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_rgb_to_hsv = R"igl_Qu8mg5v7(See igl\rgb_to_hsv.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_rotate_by_quat = R"igl_Qu8mg5v7(See igl\rotate_by_quat.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_rotate_vectors = R"igl_Qu8mg5v7(See igl\rotate_vectors.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_rotation_matrix_from_directions = R"igl_Qu8mg5v7(See igl\rotation_matrix_from_directions.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_round = R"igl_Qu8mg5v7(See igl\round.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_rows_to_matrix = R"igl_Qu8mg5v7(See igl\rows_to_matrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_sample_edges = R"igl_Qu8mg5v7(See igl\sample_edges.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_serialize = R"igl_Qu8mg5v7(See igl\serialize.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_setdiff = R"igl_Qu8mg5v7(See igl\setdiff.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_signed_distance = R"igl_Qu8mg5v7(See igl\signed_distance.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_slice = R"igl_Qu8mg5v7(See igl\slice.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_slice_into = R"igl_Qu8mg5v7(See igl\slice_into.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_slice_mask = R"igl_Qu8mg5v7(See igl\slice_mask.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_slice_tets = R"igl_Qu8mg5v7(See igl\slice_tets.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_snap_points = R"igl_Qu8mg5v7(See igl\snap_points.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_snap_to_canonical_view_quat = R"igl_Qu8mg5v7(See igl\snap_to_canonical_view_quat.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_snap_to_fixed_up = R"igl_Qu8mg5v7(See igl\snap_to_fixed_up.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_SolverStatus = R"igl_Qu8mg5v7(See igl\SolverStatus.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_sort = R"igl_Qu8mg5v7(See igl\sort.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_SortableRow = R"igl_Qu8mg5v7(See igl\SortableRow.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_sortrows = R"igl_Qu8mg5v7(See igl\sortrows.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_sort_angles = R"igl_Qu8mg5v7(See igl\sort_angles.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_sort_triangles = R"igl_Qu8mg5v7(See igl\sort_triangles.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_sort_vectors_ccw = R"igl_Qu8mg5v7(See igl\sort_vectors_ccw.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_sparse = R"igl_Qu8mg5v7(See igl\sparse.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_speye = R"igl_Qu8mg5v7(See igl\speye.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_stdin_to_temp = R"igl_Qu8mg5v7(See igl\stdin_to_temp.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_STR = R"igl_Qu8mg5v7(See igl\STR.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_sum = R"igl_Qu8mg5v7(See igl\sum.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_svd3x3 = R"igl_Qu8mg5v7(See igl\svd3x3.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_svd3x3_avx = R"igl_Qu8mg5v7(See igl\svd3x3_avx.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_svd3x3_sse = R"igl_Qu8mg5v7(See igl\svd3x3_sse.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_Timer = R"igl_Qu8mg5v7(See igl\Timer.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_trackball = R"igl_Qu8mg5v7(See igl\trackball.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_transpose_blocks = R"igl_Qu8mg5v7(See igl\transpose_blocks.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_triangles_from_strip = R"igl_Qu8mg5v7(See igl\triangles_from_strip.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_triangle_fan = R"igl_Qu8mg5v7(See igl\triangle_fan.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_triangle_triangle_adjacency = R"igl_Qu8mg5v7(See igl\triangle_triangle_adjacency.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_two_axis_valuator_fixed_up = R"igl_Qu8mg5v7(See igl\two_axis_valuator_fixed_up.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_uniformly_sample_two_manifold = R"igl_Qu8mg5v7(See igl\uniformly_sample_two_manifold.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_unique = R"igl_Qu8mg5v7(See igl\unique.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_unique_edge_map = R"igl_Qu8mg5v7(See igl\unique_edge_map.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_unique_simplices = R"igl_Qu8mg5v7(See igl\unique_simplices.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_unproject = R"igl_Qu8mg5v7(See igl\unproject.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_upsample = R"igl_Qu8mg5v7(See igl\upsample.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_vector_area_matrix = R"igl_Qu8mg5v7(See igl\vector_area_matrix.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_verbose = R"igl_Qu8mg5v7(See igl\verbose.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_vertex_triangle_adjacency = R"igl_Qu8mg5v7(See igl\vertex_triangle_adjacency.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_Viewport = R"igl_Qu8mg5v7(See igl\Viewport.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_volume = R"igl_Qu8mg5v7(See igl\volume.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_WindingNumberAABB = R"igl_Qu8mg5v7(See igl\WindingNumberAABB.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_WindingNumberMethod = R"igl_Qu8mg5v7(See igl\WindingNumberMethod.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_WindingNumberTree = R"igl_Qu8mg5v7(See igl\WindingNumberTree.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_winding_number = R"igl_Qu8mg5v7(See igl\winding_number.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_writeDMAT = R"igl_Qu8mg5v7(See igl\writeDMAT.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_writeMESH = R"igl_Qu8mg5v7(See igl\writeMESH.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_writeOBJ = R"igl_Qu8mg5v7(See igl\writeOBJ.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_writeOFF = R"igl_Qu8mg5v7(See igl\writeOFF.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_writePLY = R"igl_Qu8mg5v7(See igl\writePLY.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_writeSTL = R"igl_Qu8mg5v7(See igl\writeSTL.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_writeTGF = R"igl_Qu8mg5v7(See igl\writeTGF.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_writeWRL = R"igl_Qu8mg5v7(See igl\writeWRL.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_write_triangle_mesh = R"igl_Qu8mg5v7(See igl\write_triangle_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_ZERO = R"igl_Qu8mg5v7(See igl\ZERO.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_anttweakbar_cocoa_key_to_anttweakbar_key = R"igl_Qu8mg5v7(See igl\anttweakbar\cocoa_key_to_anttweakbar_key.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_anttweakbar_ReAntTweakBar = R"igl_Qu8mg5v7(See igl\anttweakbar\ReAntTweakBar.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_bbw_bbw = R"igl_Qu8mg5v7(See igl\bbw\bbw.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_boolean_from_cork_mesh = R"igl_Qu8mg5v7(See igl\boolean\from_cork_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_boolean_MeshBooleanType = R"igl_Qu8mg5v7(See igl\boolean\MeshBooleanType.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_boolean_mesh_boolean = R"igl_Qu8mg5v7(See igl\boolean\mesh_boolean.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_boolean_mesh_boolean_cork = R"igl_Qu8mg5v7(See igl\boolean\mesh_boolean_cork.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_boolean_to_cork_mesh = R"igl_Qu8mg5v7(See igl\boolean\to_cork_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_complex_to_mesh = R"igl_Qu8mg5v7(See igl\cgal\complex_to_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_intersect_other = R"igl_Qu8mg5v7(See igl\cgal\intersect_other.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_mesh_to_cgal_triangle_list = R"igl_Qu8mg5v7(See igl\cgal\mesh_to_cgal_triangle_list.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_mesh_to_polyhedron = R"igl_Qu8mg5v7(See igl\cgal\mesh_to_polyhedron.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_order_facets_around_edges = R"igl_Qu8mg5v7(See igl\cgal\order_facets_around_edges.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_outer_hull = R"igl_Qu8mg5v7(See igl\cgal\outer_hull.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_peel_outer_hull_layers = R"igl_Qu8mg5v7(See igl\cgal\peel_outer_hull_layers.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_point_mesh_squared_distance = R"igl_Qu8mg5v7(See igl\cgal\point_mesh_squared_distance.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_polyhedron_to_mesh = R"igl_Qu8mg5v7(See igl\cgal\polyhedron_to_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_RemeshSelfIntersectionsParam = R"igl_Qu8mg5v7(See igl\cgal\RemeshSelfIntersectionsParam.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_remesh_self_intersections = R"igl_Qu8mg5v7(See igl\cgal\remesh_self_intersections.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_SelfIntersectMesh = R"igl_Qu8mg5v7(See igl\cgal\SelfIntersectMesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_cgal_signed_distance_isosurface = R"igl_Qu8mg5v7(See igl\cgal\signed_distance_isosurface.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_comiso_frame_field = R"igl_Qu8mg5v7(See igl\comiso\frame_field.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_comiso_miq = R"igl_Qu8mg5v7(See igl\comiso\miq.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_comiso_nrosy = R"igl_Qu8mg5v7(See igl\comiso\nrosy.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_ambient_occlusion = R"igl_Qu8mg5v7(See igl\embree\ambient_occlusion.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_bone_heat = R"igl_Qu8mg5v7(See igl\embree\bone_heat.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_bone_visible = R"igl_Qu8mg5v7(See igl\embree\bone_visible.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_EmbreeIntersector = R"igl_Qu8mg5v7(See igl\embree\EmbreeIntersector.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_Embree_convenience = R"igl_Qu8mg5v7(See igl\embree\Embree_convenience.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_Hit = R"igl_Qu8mg5v7(See igl\embree\Hit.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_line_mesh_intersection = R"igl_Qu8mg5v7(See igl\embree\line_mesh_intersection.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_reorient_facets_raycast = R"igl_Qu8mg5v7(See igl\embree\reorient_facets_raycast.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_unproject_in_mesh = R"igl_Qu8mg5v7(See igl\embree\unproject_in_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_embree_unproject_onto_mesh = R"igl_Qu8mg5v7(See igl\embree\unproject_onto_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_lim_lim = R"igl_Qu8mg5v7(See igl\lim\lim.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_matlab_matlabinterface = R"igl_Qu8mg5v7(See igl\matlab\matlabinterface.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_matlab_MatlabWorkspace = R"igl_Qu8mg5v7(See igl\matlab\MatlabWorkspace.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_matlab_mexErrMsgTxt = R"igl_Qu8mg5v7(See igl\matlab\mexErrMsgTxt.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_matlab_MexStream = R"igl_Qu8mg5v7(See igl\matlab\MexStream.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_matlab_parse_rhs = R"igl_Qu8mg5v7(See igl\matlab\parse_rhs.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_matlab_prepare_lhs = R"igl_Qu8mg5v7(See igl\matlab\prepare_lhs.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_mosek_mosek_guarded = R"igl_Qu8mg5v7(See igl\mosek\mosek_guarded.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_mosek_mosek_linprog = R"igl_Qu8mg5v7(See igl\mosek\mosek_linprog.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_mosek_mosek_quadprog = R"igl_Qu8mg5v7(See igl\mosek\mosek_quadprog.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_compile_and_link_program = R"igl_Qu8mg5v7(See igl\opengl\compile_and_link_program.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_compile_shader = R"igl_Qu8mg5v7(See igl\opengl\compile_shader.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_create_index_vbo = R"igl_Qu8mg5v7(See igl\opengl\create_index_vbo.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_create_mesh_vbo = R"igl_Qu8mg5v7(See igl\opengl\create_mesh_vbo.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_create_shader_program = R"igl_Qu8mg5v7(See igl\opengl\create_shader_program.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_create_vector_vbo = R"igl_Qu8mg5v7(See igl\opengl\create_vector_vbo.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_destroy_shader_program = R"igl_Qu8mg5v7(See igl\opengl\destroy_shader_program.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_gl_type_size = R"igl_Qu8mg5v7(See igl\opengl\gl_type_size.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_init_render_to_texture = R"igl_Qu8mg5v7(See igl\opengl\init_render_to_texture.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_load_shader = R"igl_Qu8mg5v7(See igl\opengl\load_shader.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_OpenGL_convenience = R"igl_Qu8mg5v7(See igl\opengl\OpenGL_convenience.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_print_program_info_log = R"igl_Qu8mg5v7(See igl\opengl\print_program_info_log.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_print_shader_info_log = R"igl_Qu8mg5v7(See igl\opengl\print_shader_info_log.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_render_to_tga = R"igl_Qu8mg5v7(See igl\opengl\render_to_tga.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_report_gl_error = R"igl_Qu8mg5v7(See igl\opengl\report_gl_error.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_texture_from_tga = R"igl_Qu8mg5v7(See igl\opengl\texture_from_tga.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_tga = R"igl_Qu8mg5v7(See igl\opengl\tga.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl_uniform_type_to_string = R"igl_Qu8mg5v7(See igl\opengl\uniform_type_to_string.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_draw_beach_ball = R"igl_Qu8mg5v7(See igl\opengl2\draw_beach_ball.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_draw_floor = R"igl_Qu8mg5v7(See igl\opengl2\draw_floor.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_draw_mesh = R"igl_Qu8mg5v7(See igl\opengl2\draw_mesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_draw_point = R"igl_Qu8mg5v7(See igl\opengl2\draw_point.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_draw_rectangular_marquee = R"igl_Qu8mg5v7(See igl\opengl2\draw_rectangular_marquee.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_draw_skeleton_3d = R"igl_Qu8mg5v7(See igl\opengl2\draw_skeleton_3d.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_draw_skeleton_vector_graphics = R"igl_Qu8mg5v7(See igl\opengl2\draw_skeleton_vector_graphics.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_flare_textures = R"igl_Qu8mg5v7(See igl\opengl2\flare_textures.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_lens_flare = R"igl_Qu8mg5v7(See igl\opengl2\lens_flare.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_model_proj_viewport = R"igl_Qu8mg5v7(See igl\opengl2\model_proj_viewport.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_MouseController = R"igl_Qu8mg5v7(See igl\opengl2\MouseController.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_print_gl_get = R"igl_Qu8mg5v7(See igl\opengl2\print_gl_get.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_project = R"igl_Qu8mg5v7(See igl\opengl2\project.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_right_axis = R"igl_Qu8mg5v7(See igl\opengl2\right_axis.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_RotateWidget = R"igl_Qu8mg5v7(See igl\opengl2\RotateWidget.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_shine_textures = R"igl_Qu8mg5v7(See igl\opengl2\shine_textures.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_sort_triangles = R"igl_Qu8mg5v7(See igl\opengl2\sort_triangles.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_unproject = R"igl_Qu8mg5v7(See igl\opengl2\unproject.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_unproject_to_zero_plane = R"igl_Qu8mg5v7(See igl\opengl2\unproject_to_zero_plane.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_up_axis = R"igl_Qu8mg5v7(See igl\opengl2\up_axis.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_opengl2_view_axis = R"igl_Qu8mg5v7(See igl\opengl2\view_axis.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_png_render_to_png = R"igl_Qu8mg5v7(See igl\png\render_to_png.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_png_render_to_png_async = R"igl_Qu8mg5v7(See igl\png\render_to_png_async.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_png_texture_from_file = R"igl_Qu8mg5v7(See igl\png\texture_from_file.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_png_texture_from_png = R"igl_Qu8mg5v7(See igl\png\texture_from_png.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_tetgen_cdt = R"igl_Qu8mg5v7(See igl\tetgen\cdt.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_tetgen_mesh_to_tetgenio = R"igl_Qu8mg5v7(See igl\tetgen\mesh_to_tetgenio.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_tetgen_mesh_with_skeleton = R"igl_Qu8mg5v7(See igl\tetgen\mesh_with_skeleton.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_tetgen_read_into_tetgenio = R"igl_Qu8mg5v7(See igl\tetgen\read_into_tetgenio.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_tetgen_tetgenio_to_tetmesh = R"igl_Qu8mg5v7(See igl\tetgen\tetgenio_to_tetmesh.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_tetgen_tetrahedralize = R"igl_Qu8mg5v7(See igl\tetgen\tetrahedralize.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_triangle_triangulate = R"igl_Qu8mg5v7(See igl\triangle\triangulate.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_viewer_OpenGL_shader = R"igl_Qu8mg5v7(See igl\viewer\OpenGL_shader.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_viewer_OpenGL_state = R"igl_Qu8mg5v7(See igl\viewer\OpenGL_state.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_viewer_TextRenderer = R"igl_Qu8mg5v7(See igl\viewer\TextRenderer.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_viewer_TextRenderer_fonts = R"igl_Qu8mg5v7(See igl\viewer\TextRenderer_fonts.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_viewer_Viewer = R"igl_Qu8mg5v7(See igl\viewer\Viewer.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_viewer_ViewerCore = R"igl_Qu8mg5v7(See igl\viewer\ViewerCore.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_viewer_ViewerData = R"igl_Qu8mg5v7(See igl\viewer\ViewerData.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_viewer_ViewerPlugin = R"igl_Qu8mg5v7(See igl\viewer\ViewerPlugin.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_xml_ReAntTweakBarXMLSerialization = R"igl_Qu8mg5v7(See igl\xml\ReAntTweakBarXMLSerialization.h for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_xml_serialize_xml = R"igl_Qu8mg5v7(See igl\xml\serialize_xml.h for the documentation.)igl_Qu8mg5v7";

+ 409 - 0
python/py_doc.h

@@ -0,0 +1,409 @@
+extern const char *__doc_igl_AABB;
+extern const char *__doc_igl_active_set;
+extern const char *__doc_igl_adjacency_list;
+extern const char *__doc_igl_adjacency_matrix;
+extern const char *__doc_igl_all_edges;
+extern const char *__doc_igl_all_pairs_distances;
+extern const char *__doc_igl_angle_bound_frame_fields;
+extern const char *__doc_igl_angular_distance;
+extern const char *__doc_igl_any_of;
+extern const char *__doc_igl_arap;
+extern const char *__doc_igl_ARAPEnergyType;
+extern const char *__doc_igl_arap_dof;
+extern const char *__doc_igl_arap_linear_block;
+extern const char *__doc_igl_arap_rhs;
+extern const char *__doc_igl_average_onto_faces;
+extern const char *__doc_igl_average_onto_vertices;
+extern const char *__doc_igl_avg_edge_length;
+extern const char *__doc_igl_axis_angle_to_quat;
+extern const char *__doc_igl_barycenter;
+extern const char *__doc_igl_barycentric_coordinates;
+extern const char *__doc_igl_barycentric_to_global;
+extern const char *__doc_igl_basename;
+extern const char *__doc_igl_bfs_orient;
+extern const char *__doc_igl_biharmonic_coordinates;
+extern const char *__doc_igl_bone_parents;
+extern const char *__doc_igl_boundary_conditions;
+extern const char *__doc_igl_boundary_facets;
+extern const char *__doc_igl_boundary_loop;
+extern const char *__doc_igl_bounding_box;
+extern const char *__doc_igl_bounding_box_diagonal;
+extern const char *__doc_igl_Camera;
+extern const char *__doc_igl_canonical_quaternions;
+extern const char *__doc_igl_cat;
+extern const char *__doc_igl_ceil;
+extern const char *__doc_igl_centroid;
+extern const char *__doc_igl_circulation;
+extern const char *__doc_igl_collapse_edge;
+extern const char *__doc_igl_collapse_small_triangles;
+extern const char *__doc_igl_colon;
+extern const char *__doc_igl_columnize;
+extern const char *__doc_igl_column_to_quats;
+extern const char *__doc_igl_comb_cross_field;
+extern const char *__doc_igl_comb_frame_field;
+extern const char *__doc_igl_comb_line_field;
+extern const char *__doc_igl_components;
+extern const char *__doc_igl_compute_frame_field_bisectors;
+extern const char *__doc_igl_ConjugateFFSolverData;
+extern const char *__doc_igl_conjugate_frame_fields;
+extern const char *__doc_igl_cotmatrix;
+extern const char *__doc_igl_cotmatrix_entries;
+extern const char *__doc_igl_covariance_scatter_matrix;
+extern const char *__doc_igl_cross;
+extern const char *__doc_igl_cross_field_missmatch;
+extern const char *__doc_igl_crouzeix_raviart_massmatrix;
+extern const char *__doc_igl_cumsum;
+extern const char *__doc_igl_cut_mesh;
+extern const char *__doc_igl_cut_mesh_from_singularities;
+extern const char *__doc_igl_C_STR;
+extern const char *__doc_igl_dated_copy;
+extern const char *__doc_igl_decimate;
+extern const char *__doc_igl_deform_skeleton;
+extern const char *__doc_igl_deprecated;
+extern const char *__doc_igl_diag;
+extern const char *__doc_igl_dihedral_angles;
+extern const char *__doc_igl_dijkstra;
+extern const char *__doc_igl_directed_edge_orientations;
+extern const char *__doc_igl_directed_edge_parents;
+extern const char *__doc_igl_dirname;
+extern const char *__doc_igl_dot;
+extern const char *__doc_igl_dot_row;
+extern const char *__doc_igl_doublearea;
+extern const char *__doc_igl_dqs;
+extern const char *__doc_igl_edges;
+extern const char *__doc_igl_edge_collapse_is_valid;
+extern const char *__doc_igl_edge_flaps;
+extern const char *__doc_igl_edge_lengths;
+extern const char *__doc_igl_edge_topology;
+extern const char *__doc_igl_eigs;
+extern const char *__doc_igl_EPS;
+extern const char *__doc_igl_example_fun;
+extern const char *__doc_igl_exterior_edges;
+extern const char *__doc_igl_faces_first;
+extern const char *__doc_igl_facet_components;
+extern const char *__doc_igl_face_areas;
+extern const char *__doc_igl_face_occurrences;
+extern const char *__doc_igl_false_barycentric_subdivision;
+extern const char *__doc_igl_field_local_global_conversions;
+extern const char *__doc_igl_file_contents_as_string;
+extern const char *__doc_igl_file_dialog_open;
+extern const char *__doc_igl_file_dialog_save;
+extern const char *__doc_igl_file_exists;
+extern const char *__doc_igl_find;
+extern const char *__doc_igl_find_cross_field_singularities;
+extern const char *__doc_igl_fit_plane;
+extern const char *__doc_igl_fit_rigid;
+extern const char *__doc_igl_fit_rotations;
+extern const char *__doc_igl_floor;
+extern const char *__doc_igl_forward_kinematics;
+extern const char *__doc_igl_frame_field_deformer;
+extern const char *__doc_igl_frame_to_cross_field;
+extern const char *__doc_igl_frustum;
+extern const char *__doc_igl_full;
+extern const char *__doc_igl_gaussian_curvature;
+extern const char *__doc_igl_get_seconds;
+extern const char *__doc_igl_get_seconds_hires;
+extern const char *__doc_igl_grad;
+extern const char *__doc_igl_group_sum_matrix;
+extern const char *__doc_igl_HalfEdgeIterator;
+extern const char *__doc_igl_harmonic;
+extern const char *__doc_igl_harwell_boeing;
+extern const char *__doc_igl_histc;
+extern const char *__doc_igl_hsv_to_rgb;
+extern const char *__doc_igl_igl_inline;
+extern const char *__doc_igl_IndexComparison;
+extern const char *__doc_igl_integrable_polyvector_fields;
+extern const char *__doc_igl_internal_angles;
+extern const char *__doc_igl_intersect;
+extern const char *__doc_igl_invert_diag;
+extern const char *__doc_igl_in_element;
+extern const char *__doc_igl_is_border_vertex;
+extern const char *__doc_igl_is_boundary_edge;
+extern const char *__doc_igl_is_dir;
+extern const char *__doc_igl_is_edge_manifold;
+extern const char *__doc_igl_is_file;
+extern const char *__doc_igl_is_irregular_vertex;
+extern const char *__doc_igl_is_planar;
+extern const char *__doc_igl_is_readable;
+extern const char *__doc_igl_is_sparse;
+extern const char *__doc_igl_is_symmetric;
+extern const char *__doc_igl_is_vertex_manifold;
+extern const char *__doc_igl_is_writable;
+extern const char *__doc_igl_jet;
+extern const char *__doc_igl_launch_medit;
+extern const char *__doc_igl_lbs_matrix;
+extern const char *__doc_igl_limit_faces;
+extern const char *__doc_igl_line_field_missmatch;
+extern const char *__doc_igl_line_segment_in_rectangle;
+extern const char *__doc_igl_linprog;
+extern const char *__doc_igl_list_to_matrix;
+extern const char *__doc_igl_local_basis;
+extern const char *__doc_igl_look_at;
+extern const char *__doc_igl_lscm;
+extern const char *__doc_igl_lu_lagrange;
+extern const char *__doc_igl_map_vertices_to_circle;
+extern const char *__doc_igl_marching_cubes;
+extern const char *__doc_igl_massmatrix;
+extern const char *__doc_igl_material_colors;
+extern const char *__doc_igl_matlab_format;
+extern const char *__doc_igl_matrix_to_list;
+extern const char *__doc_igl_mat_max;
+extern const char *__doc_igl_mat_min;
+extern const char *__doc_igl_mat_to_quat;
+extern const char *__doc_igl_max_size;
+extern const char *__doc_igl_median;
+extern const char *__doc_igl_min_quad_dense;
+extern const char *__doc_igl_min_quad_with_fixed;
+extern const char *__doc_igl_min_size;
+extern const char *__doc_igl_mod;
+extern const char *__doc_igl_mode;
+extern const char *__doc_igl_mvc;
+extern const char *__doc_igl_nchoosek;
+extern const char *__doc_igl_next_filename;
+extern const char *__doc_igl_normalize_quat;
+extern const char *__doc_igl_normalize_row_lengths;
+extern const char *__doc_igl_normalize_row_sums;
+extern const char *__doc_igl_NormalType;
+extern const char *__doc_igl_normal_derivative;
+extern const char *__doc_igl_null;
+extern const char *__doc_igl_n_polyvector;
+extern const char *__doc_igl_n_polyvector_general;
+extern const char *__doc_igl_ONE;
+extern const char *__doc_igl_on_boundary;
+extern const char *__doc_igl_orientable_patches;
+extern const char *__doc_igl_orient_outward;
+extern const char *__doc_igl_orth;
+extern const char *__doc_igl_ortho;
+extern const char *__doc_igl_outer_facet;
+extern const char *__doc_igl_parallel_transport_angles;
+extern const char *__doc_igl_partition;
+extern const char *__doc_igl_parula;
+extern const char *__doc_igl_pathinfo;
+extern const char *__doc_igl_path_to_executable;
+extern const char *__doc_igl_per_corner_normals;
+extern const char *__doc_igl_per_edge_normals;
+extern const char *__doc_igl_per_face_normals;
+extern const char *__doc_igl_per_vertex_attribute_smoothing;
+extern const char *__doc_igl_per_vertex_normals;
+extern const char *__doc_igl_PI;
+extern const char *__doc_igl_planarize_quad_mesh;
+extern const char *__doc_igl_ply;
+extern const char *__doc_igl_point_in_circle;
+extern const char *__doc_igl_point_in_poly;
+extern const char *__doc_igl_point_mesh_squared_distance;
+extern const char *__doc_igl_polar_dec;
+extern const char *__doc_igl_polar_svd;
+extern const char *__doc_igl_polar_svd3x3;
+extern const char *__doc_igl_polygon_mesh_to_triangle_mesh;
+extern const char *__doc_igl_polyroots;
+extern const char *__doc_igl_polyvector_field_comb_from_matchings_and_cuts;
+extern const char *__doc_igl_polyvector_field_cut_mesh_with_singularities;
+extern const char *__doc_igl_polyvector_field_matchings;
+extern const char *__doc_igl_polyvector_field_poisson_reconstruction;
+extern const char *__doc_igl_polyvector_field_singularities_from_matchings;
+extern const char *__doc_igl_principal_curvature;
+extern const char *__doc_igl_print_ijv;
+extern const char *__doc_igl_print_vector;
+extern const char *__doc_igl_procrustes;
+extern const char *__doc_igl_project;
+extern const char *__doc_igl_project_isometrically_to_plane;
+extern const char *__doc_igl_project_to_line;
+extern const char *__doc_igl_project_to_line_segment;
+extern const char *__doc_igl_pseudonormal_test;
+extern const char *__doc_igl_quad_planarity;
+extern const char *__doc_igl_quats_to_column;
+extern const char *__doc_igl_quat_conjugate;
+extern const char *__doc_igl_quat_mult;
+extern const char *__doc_igl_quat_to_axis_angle;
+extern const char *__doc_igl_quat_to_mat;
+extern const char *__doc_igl_random_dir;
+extern const char *__doc_igl_random_points_on_mesh;
+extern const char *__doc_igl_random_quaternion;
+extern const char *__doc_igl_randperm;
+extern const char *__doc_igl_ray_sphere_intersect;
+extern const char *__doc_igl_readCSV;
+extern const char *__doc_igl_readDMAT;
+extern const char *__doc_igl_readMESH;
+extern const char *__doc_igl_readNODE;
+extern const char *__doc_igl_readOBJ;
+extern const char *__doc_igl_readOFF;
+extern const char *__doc_igl_readPLY;
+extern const char *__doc_igl_readSTL;
+extern const char *__doc_igl_readTGF;
+extern const char *__doc_igl_readWRL;
+extern const char *__doc_igl_read_triangle_mesh;
+extern const char *__doc_igl_REDRUM;
+extern const char *__doc_igl_remove_duplicates;
+extern const char *__doc_igl_remove_duplicate_vertices;
+extern const char *__doc_igl_remove_unreferenced;
+extern const char *__doc_igl_reorder;
+extern const char *__doc_igl_repdiag;
+extern const char *__doc_igl_repmat;
+extern const char *__doc_igl_rgb_to_hsv;
+extern const char *__doc_igl_rotate_by_quat;
+extern const char *__doc_igl_rotate_vectors;
+extern const char *__doc_igl_rotation_matrix_from_directions;
+extern const char *__doc_igl_round;
+extern const char *__doc_igl_rows_to_matrix;
+extern const char *__doc_igl_sample_edges;
+extern const char *__doc_igl_serialize;
+extern const char *__doc_igl_setdiff;
+extern const char *__doc_igl_signed_distance;
+extern const char *__doc_igl_slice;
+extern const char *__doc_igl_slice_into;
+extern const char *__doc_igl_slice_mask;
+extern const char *__doc_igl_slice_tets;
+extern const char *__doc_igl_snap_points;
+extern const char *__doc_igl_snap_to_canonical_view_quat;
+extern const char *__doc_igl_snap_to_fixed_up;
+extern const char *__doc_igl_SolverStatus;
+extern const char *__doc_igl_sort;
+extern const char *__doc_igl_SortableRow;
+extern const char *__doc_igl_sortrows;
+extern const char *__doc_igl_sort_angles;
+extern const char *__doc_igl_sort_triangles;
+extern const char *__doc_igl_sort_vectors_ccw;
+extern const char *__doc_igl_sparse;
+extern const char *__doc_igl_speye;
+extern const char *__doc_igl_stdin_to_temp;
+extern const char *__doc_igl_STR;
+extern const char *__doc_igl_sum;
+extern const char *__doc_igl_svd3x3;
+extern const char *__doc_igl_svd3x3_avx;
+extern const char *__doc_igl_svd3x3_sse;
+extern const char *__doc_igl_Timer;
+extern const char *__doc_igl_trackball;
+extern const char *__doc_igl_transpose_blocks;
+extern const char *__doc_igl_triangles_from_strip;
+extern const char *__doc_igl_triangle_fan;
+extern const char *__doc_igl_triangle_triangle_adjacency;
+extern const char *__doc_igl_two_axis_valuator_fixed_up;
+extern const char *__doc_igl_uniformly_sample_two_manifold;
+extern const char *__doc_igl_unique;
+extern const char *__doc_igl_unique_edge_map;
+extern const char *__doc_igl_unique_simplices;
+extern const char *__doc_igl_unproject;
+extern const char *__doc_igl_upsample;
+extern const char *__doc_igl_vector_area_matrix;
+extern const char *__doc_igl_verbose;
+extern const char *__doc_igl_vertex_triangle_adjacency;
+extern const char *__doc_igl_Viewport;
+extern const char *__doc_igl_volume;
+extern const char *__doc_igl_WindingNumberAABB;
+extern const char *__doc_igl_WindingNumberMethod;
+extern const char *__doc_igl_WindingNumberTree;
+extern const char *__doc_igl_winding_number;
+extern const char *__doc_igl_writeDMAT;
+extern const char *__doc_igl_writeMESH;
+extern const char *__doc_igl_writeOBJ;
+extern const char *__doc_igl_writeOFF;
+extern const char *__doc_igl_writePLY;
+extern const char *__doc_igl_writeSTL;
+extern const char *__doc_igl_writeTGF;
+extern const char *__doc_igl_writeWRL;
+extern const char *__doc_igl_write_triangle_mesh;
+extern const char *__doc_igl_ZERO;
+extern const char *__doc_igl_anttweakbar_cocoa_key_to_anttweakbar_key;
+extern const char *__doc_igl_anttweakbar_ReAntTweakBar;
+extern const char *__doc_igl_bbw_bbw;
+extern const char *__doc_igl_boolean_from_cork_mesh;
+extern const char *__doc_igl_boolean_MeshBooleanType;
+extern const char *__doc_igl_boolean_mesh_boolean;
+extern const char *__doc_igl_boolean_mesh_boolean_cork;
+extern const char *__doc_igl_boolean_to_cork_mesh;
+extern const char *__doc_igl_cgal_complex_to_mesh;
+extern const char *__doc_igl_cgal_intersect_other;
+extern const char *__doc_igl_cgal_mesh_to_cgal_triangle_list;
+extern const char *__doc_igl_cgal_mesh_to_polyhedron;
+extern const char *__doc_igl_cgal_order_facets_around_edges;
+extern const char *__doc_igl_cgal_outer_hull;
+extern const char *__doc_igl_cgal_peel_outer_hull_layers;
+extern const char *__doc_igl_cgal_point_mesh_squared_distance;
+extern const char *__doc_igl_cgal_polyhedron_to_mesh;
+extern const char *__doc_igl_cgal_RemeshSelfIntersectionsParam;
+extern const char *__doc_igl_cgal_remesh_self_intersections;
+extern const char *__doc_igl_cgal_SelfIntersectMesh;
+extern const char *__doc_igl_cgal_signed_distance_isosurface;
+extern const char *__doc_igl_comiso_frame_field;
+extern const char *__doc_igl_comiso_miq;
+extern const char *__doc_igl_comiso_nrosy;
+extern const char *__doc_igl_embree_ambient_occlusion;
+extern const char *__doc_igl_embree_bone_heat;
+extern const char *__doc_igl_embree_bone_visible;
+extern const char *__doc_igl_embree_EmbreeIntersector;
+extern const char *__doc_igl_embree_Embree_convenience;
+extern const char *__doc_igl_embree_Hit;
+extern const char *__doc_igl_embree_line_mesh_intersection;
+extern const char *__doc_igl_embree_reorient_facets_raycast;
+extern const char *__doc_igl_embree_unproject_in_mesh;
+extern const char *__doc_igl_embree_unproject_onto_mesh;
+extern const char *__doc_igl_lim_lim;
+extern const char *__doc_igl_matlab_matlabinterface;
+extern const char *__doc_igl_matlab_MatlabWorkspace;
+extern const char *__doc_igl_matlab_mexErrMsgTxt;
+extern const char *__doc_igl_matlab_MexStream;
+extern const char *__doc_igl_matlab_parse_rhs;
+extern const char *__doc_igl_matlab_prepare_lhs;
+extern const char *__doc_igl_mosek_mosek_guarded;
+extern const char *__doc_igl_mosek_mosek_linprog;
+extern const char *__doc_igl_mosek_mosek_quadprog;
+extern const char *__doc_igl_opengl_compile_and_link_program;
+extern const char *__doc_igl_opengl_compile_shader;
+extern const char *__doc_igl_opengl_create_index_vbo;
+extern const char *__doc_igl_opengl_create_mesh_vbo;
+extern const char *__doc_igl_opengl_create_shader_program;
+extern const char *__doc_igl_opengl_create_vector_vbo;
+extern const char *__doc_igl_opengl_destroy_shader_program;
+extern const char *__doc_igl_opengl_gl_type_size;
+extern const char *__doc_igl_opengl_init_render_to_texture;
+extern const char *__doc_igl_opengl_load_shader;
+extern const char *__doc_igl_opengl_OpenGL_convenience;
+extern const char *__doc_igl_opengl_print_program_info_log;
+extern const char *__doc_igl_opengl_print_shader_info_log;
+extern const char *__doc_igl_opengl_render_to_tga;
+extern const char *__doc_igl_opengl_report_gl_error;
+extern const char *__doc_igl_opengl_texture_from_tga;
+extern const char *__doc_igl_opengl_tga;
+extern const char *__doc_igl_opengl_uniform_type_to_string;
+extern const char *__doc_igl_opengl2_draw_beach_ball;
+extern const char *__doc_igl_opengl2_draw_floor;
+extern const char *__doc_igl_opengl2_draw_mesh;
+extern const char *__doc_igl_opengl2_draw_point;
+extern const char *__doc_igl_opengl2_draw_rectangular_marquee;
+extern const char *__doc_igl_opengl2_draw_skeleton_3d;
+extern const char *__doc_igl_opengl2_draw_skeleton_vector_graphics;
+extern const char *__doc_igl_opengl2_flare_textures;
+extern const char *__doc_igl_opengl2_lens_flare;
+extern const char *__doc_igl_opengl2_model_proj_viewport;
+extern const char *__doc_igl_opengl2_MouseController;
+extern const char *__doc_igl_opengl2_print_gl_get;
+extern const char *__doc_igl_opengl2_project;
+extern const char *__doc_igl_opengl2_right_axis;
+extern const char *__doc_igl_opengl2_RotateWidget;
+extern const char *__doc_igl_opengl2_shine_textures;
+extern const char *__doc_igl_opengl2_sort_triangles;
+extern const char *__doc_igl_opengl2_unproject;
+extern const char *__doc_igl_opengl2_unproject_to_zero_plane;
+extern const char *__doc_igl_opengl2_up_axis;
+extern const char *__doc_igl_opengl2_view_axis;
+extern const char *__doc_igl_png_render_to_png;
+extern const char *__doc_igl_png_render_to_png_async;
+extern const char *__doc_igl_png_texture_from_file;
+extern const char *__doc_igl_png_texture_from_png;
+extern const char *__doc_igl_tetgen_cdt;
+extern const char *__doc_igl_tetgen_mesh_to_tetgenio;
+extern const char *__doc_igl_tetgen_mesh_with_skeleton;
+extern const char *__doc_igl_tetgen_read_into_tetgenio;
+extern const char *__doc_igl_tetgen_tetgenio_to_tetmesh;
+extern const char *__doc_igl_tetgen_tetrahedralize;
+extern const char *__doc_igl_triangle_triangulate;
+extern const char *__doc_igl_viewer_OpenGL_shader;
+extern const char *__doc_igl_viewer_OpenGL_state;
+extern const char *__doc_igl_viewer_TextRenderer;
+extern const char *__doc_igl_viewer_TextRenderer_fonts;
+extern const char *__doc_igl_viewer_Viewer;
+extern const char *__doc_igl_viewer_ViewerCore;
+extern const char *__doc_igl_viewer_ViewerData;
+extern const char *__doc_igl_viewer_ViewerPlugin;
+extern const char *__doc_igl_xml_ReAntTweakBarXMLSerialization;
+extern const char *__doc_igl_xml_serialize_xml;

+ 69 - 0
python/py_igl.cpp

@@ -0,0 +1,69 @@
+#include <Eigen/Dense>
+
+#include "python.h"
+
+#include <igl/readOFF.h>
+#include <igl/writeOBJ.h>
+#include <igl/per_face_normals.h>
+#include <igl/per_corner_normals.h>
+#include <igl/per_vertex_normals.h>
+#include <igl/gaussian_curvature.h>
+#include <igl/jet.h>
+#include <igl/read_triangle_mesh.h>
+#include <igl/cotmatrix.h>
+#include <igl/massmatrix.h>
+#include <igl/invert_diag.h>
+#include <igl/principal_curvature.h>
+#include <igl/parula.h>
+#include <igl/readDMAT.h>
+#include <igl/grad.h>
+#include <igl/avg_edge_length.h>
+#include <igl/barycenter.h>
+#include <igl/doublearea.h>
+#include <igl/floor.h>
+#include <igl/slice.h>
+#include <igl/slice_into.h>
+#include <igl/sortrows.h>
+#include <igl/colon.h>
+#include <igl/boundary_facets.h>
+#include <igl/unique.h>
+#include <igl/setdiff.h>
+#include <igl/min_quad_with_fixed.h>
+#include <igl/SolverStatus.h>
+#include <igl/active_set.h>
+#include <igl/eigs.h>
+
+void python_export_igl(py::module &m)
+{
+#include "py_igl/py_readOFF.cpp"
+#include "py_igl/py_writeOBJ.cpp"
+#include "py_igl/py_per_face_normals.cpp"
+#include "py_igl/py_per_corner_normals.cpp"
+#include "py_igl/py_per_vertex_normals.cpp"
+#include "py_igl/py_gaussian_curvature.cpp"
+#include "py_igl/py_jet.cpp"
+#include "py_igl/py_read_triangle_mesh.cpp"
+#include "py_igl/py_cotmatrix.cpp"
+#include "py_igl/py_massmatrix.cpp"
+#include "py_igl/py_invert_diag.cpp"
+#include "py_igl/py_principal_curvature.cpp"
+#include "py_igl/py_parula.cpp"
+#include "py_igl/py_readDMAT.cpp"
+#include "py_igl/py_grad.cpp"
+#include "py_igl/py_avg_edge_length.cpp"
+#include "py_igl/py_barycenter.cpp"
+#include "py_igl/py_doublearea.cpp"
+#include "py_igl/py_floor.cpp"
+#include "py_igl/py_slice.cpp"
+#include "py_igl/py_slice_into.cpp"
+#include "py_igl/py_sortrows.cpp"
+#include "py_igl/py_colon.cpp"
+#include "py_igl/py_boundary_facets.cpp"
+#include "py_igl/py_unique.cpp"
+#include "py_igl/py_setdiff.cpp"
+#include "py_igl/py_min_quad_with_fixed.cpp"
+#include "py_igl/py_SolverStatus.cpp"
+#include "py_igl/py_active_set.cpp"
+#include "py_igl/py_eigs.cpp"
+
+}

+ 6 - 0
python/py_igl/py_SolverStatus.cpp

@@ -0,0 +1,6 @@
+py::enum_<igl::SolverStatus>(m, "SolverStatus")
+    .value("SOLVER_STATUS_CONVERGED", igl::SOLVER_STATUS_CONVERGED)
+    .value("SOLVER_STATUS_MAX_ITER", igl::SOLVER_STATUS_MAX_ITER)
+    .value("SOLVER_STATUS_ERROR", igl::SOLVER_STATUS_ERROR)
+    .value("NUM_SOLVER_STATUSES", igl::NUM_SOLVER_STATUSES)
+    .export_values();

+ 48 - 0
python/py_igl/py_active_set.cpp

@@ -0,0 +1,48 @@
+// Wrap the params struct
+py::class_<igl::active_set_params > active_set_params(m, "active_set_params");
+
+active_set_params
+.def("__init__", [](igl::active_set_params &m)
+{
+    new (&m) igl::active_set_params();
+    m.Auu_pd = false;
+    m.max_iter = 100;
+    m.inactive_threshold = igl::DOUBLE_EPS;
+    m.constraint_threshold = igl::DOUBLE_EPS;
+    m.solution_diff_threshold = igl::DOUBLE_EPS;
+})
+.def_readwrite("Auu_pd", &igl::active_set_params::Auu_pd)
+.def_readwrite("max_iter", &igl::active_set_params::max_iter)
+.def_readwrite("inactive_threshold", &igl::active_set_params::inactive_threshold)
+.def_readwrite("constraint_threshold", &igl::active_set_params::constraint_threshold)
+.def_readwrite("solution_diff_threshold", &igl::active_set_params::solution_diff_threshold)
+.def_readwrite("Auu_pd", &igl::active_set_params::Auu_pd)
+;
+
+m.def("active_set", []
+(
+  const Eigen::SparseMatrix<double>& A,
+  const Eigen::MatrixXd& B,
+  const Eigen::MatrixXi& known,
+  const Eigen::MatrixXd& Y,
+  const Eigen::SparseMatrix<double>& Aeq,
+  const Eigen::MatrixXd& Beq,
+  const Eigen::SparseMatrix<double>& Aieq,
+  const Eigen::MatrixXd& Bieq,
+  const Eigen::MatrixXd& lx,
+  const Eigen::MatrixXd& ux,
+  const igl::active_set_params& params,
+  Eigen::MatrixXd& Z
+)
+{
+  assert_is_VectorX("B",B);
+  assert_is_VectorX("known",known);
+  assert_is_VectorX("Y",Y);
+  assert_is_VectorX("Beq",Beq);
+  assert_is_VectorX("Bieq",Bieq);
+  assert_is_VectorX("Z",Z);
+
+  return igl::active_set(A,B,known,Y,Aeq,Eigen::VectorXd(Beq),Aieq,Bieq,lx,ux,params,Z);
+}, __doc_igl_active_set,
+py::arg("A"), py::arg("B"), py::arg("known"), py::arg("Y"), py::arg("Aeq"), py::arg("Beq")
+, py::arg("Aieq"), py::arg("Bieq"), py::arg("lx"), py::arg("ux"), py::arg("params"), py::arg("Z"));

+ 9 - 0
python/py_igl/py_avg_edge_length.cpp

@@ -0,0 +1,9 @@
+m.def("avg_edge_length", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F
+)
+{
+  return igl::avg_edge_length(V,F);
+}, __doc_igl_avg_edge_length,
+py::arg("V"), py::arg("F"));

+ 10 - 0
python/py_igl/py_barycenter.cpp

@@ -0,0 +1,10 @@
+m.def("barycenter", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& BC
+)
+{
+  return igl::barycenter(V,F,BC);
+}, __doc_igl_barycenter,
+py::arg("V"), py::arg("F"), py::arg("BC"));

+ 30 - 0
python/py_igl/py_boundary_facets.cpp

@@ -0,0 +1,30 @@
+m.def("boundary_facets", []
+(
+  const std::vector<std::vector<int> > & T,
+  std::vector<std::vector<int> > & F
+)
+{
+  return igl::boundary_facets(T,F);
+}, __doc_igl_boundary_facets,
+py::arg("T"), py::arg("F"));
+
+m.def("boundary_facets", []
+(
+  const Eigen::MatrixXi& T,
+  Eigen::MatrixXi& F
+)
+{
+  return igl::boundary_facets(T,F);
+}, __doc_igl_boundary_facets,
+py::arg("T"), py::arg("F"));
+
+m.def("boundary_facets", []
+(
+  const Eigen::MatrixXi& T
+)
+{
+  Eigen::MatrixXi F;
+  igl::boundary_facets(T,F);
+  return F;
+}, __doc_igl_boundary_facets,
+py::arg("T"));

+ 74 - 0
python/py_igl/py_colon.cpp

@@ -0,0 +1,74 @@
+m.def("colon", []
+(
+  const double low,
+  const double step,
+  const double high,
+  Eigen::MatrixXd& I
+)
+{
+  Eigen::Matrix<double,Eigen::Dynamic,1> temp;
+  igl::colon<double>(low,step,high,temp);
+  I = temp;
+}, __doc_igl_colon,
+py::arg("low"), py::arg("step"), py::arg("high"), py::arg("I"));
+
+m.def("colon", []
+(
+  const double low,
+  const double high,
+  Eigen::MatrixXd& I
+)
+{
+  Eigen::Matrix<double,Eigen::Dynamic,1> temp;
+  igl::colon<double>(low,high,temp);
+  I = temp;
+}, __doc_igl_colon,
+py::arg("low"), py::arg("high"), py::arg("I"));
+
+m.def("colon", []
+(
+  const double& low,
+  const double& high
+)
+{
+  return Eigen::MatrixXd(igl::colon<double>(low,high));
+}, __doc_igl_colon,
+py::arg("low"), py::arg("high"));
+
+
+m.def("coloni", []
+(
+  const int low,
+  const int step,
+  const int high,
+  Eigen::MatrixXi& I
+)
+{
+  Eigen::Matrix<int,Eigen::Dynamic,1> temp;
+  igl::colon<int>(low,step,high,temp);
+  I = temp;
+}, __doc_igl_colon,
+py::arg("low"), py::arg("step"), py::arg("high"), py::arg("I"));
+
+m.def("coloni", []
+(
+  const int low,
+  const int high,
+  Eigen::MatrixXi& I
+)
+{
+  Eigen::Matrix<int,Eigen::Dynamic,1> temp;
+  igl::colon<int>(low,high,temp);
+  I = temp;
+}, __doc_igl_colon,
+py::arg("low"), py::arg("high"), py::arg("I"));
+
+m.def("coloni", []
+(
+  const int& low,
+  const int& high
+)
+{
+  return Eigen::MatrixXi(igl::colon<int>(low,high));
+}, __doc_igl_colon,
+py::arg("low"), py::arg("high"));

+ 10 - 0
python/py_igl/py_cotmatrix.cpp

@@ -0,0 +1,10 @@
+m.def("cotmatrix", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::SparseMatrix<double>& L
+)
+{
+  return igl::cotmatrix(V,F,L);
+}, __doc_igl_cotmatrix,
+py::arg("V"), py::arg("F"), py::arg("L"));

+ 54 - 0
python/py_igl/py_doublearea.cpp

@@ -0,0 +1,54 @@
+m.def("doublearea", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& dblA
+)
+{
+  return igl::doublearea(V,F,dblA);
+}, __doc_igl_doublearea,
+py::arg("V"), py::arg("F"), py::arg("dblA"));
+
+m.def("doublearea", []
+(
+  const Eigen::MatrixXd& A,
+  const Eigen::MatrixXd& B,
+  const Eigen::MatrixXd& C,
+  Eigen::MatrixXd& D
+)
+{
+  return igl::doublearea(A,B,C,D);
+}, __doc_igl_doublearea,
+py::arg("A"), py::arg("B"), py::arg("C"), py::arg("D"));
+
+m.def("doublearea_single", []
+(
+  const Eigen::MatrixXd& A,
+  const Eigen::MatrixXd& B,
+  const Eigen::MatrixXd& C
+)
+{
+  return igl::doublearea_single(A,B,C);
+}, __doc_igl_doublearea,
+py::arg("A"), py::arg("B"), py::arg("C"));
+
+m.def("doublearea", []
+(
+  const Eigen::MatrixXd& l,
+  Eigen::MatrixXd& dblA
+)
+{
+  return igl::doublearea(l,dblA);
+}, __doc_igl_doublearea,
+py::arg("l"), py::arg("dblA"));
+
+m.def("doublearea_quad", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& dblA
+)
+{
+  return igl::doublearea_quad(V,F,dblA);
+}, __doc_igl_doublearea,
+py::arg("V"), py::arg("F"), py::arg("dblA"));

+ 22 - 0
python/py_igl/py_eigs.cpp

@@ -0,0 +1,22 @@
+py::enum_<igl::EigsType>(m, "EigsType")
+    .value("EIGS_TYPE_SM", igl::EIGS_TYPE_SM)
+    .value("EIGS_TYPE_LM", igl::EIGS_TYPE_LM)
+    .value("NUM_EIGS_TYPES", igl::NUM_EIGS_TYPES)
+    .export_values();
+
+m.def("eigs", []
+(
+  const Eigen::SparseMatrix<double>& A,
+  const Eigen::SparseMatrix<double>& B,
+  const size_t k,
+  const igl::EigsType type,
+  Eigen::MatrixXd& sU,
+  Eigen::MatrixXd& sS
+)
+{
+  Eigen::VectorXd sSt;
+  bool ret = igl::eigs(A,B,k,type,sU,sSt);
+  sS = sSt;
+  return ret;
+}, __doc_igl_eigs,
+py::arg("A"), py::arg("B"), py::arg("k"), py::arg("type"), py::arg("sU"), py::arg("sS"));

+ 9 - 0
python/py_igl/py_floor.cpp

@@ -0,0 +1,9 @@
+m.def("floor", []
+(
+  const Eigen::MatrixXd& X,
+  Eigen::MatrixXi& Y
+)
+{
+  return igl::floor(X,Y);
+}, __doc_igl_floor,
+py::arg("X"), py::arg("Y"));

+ 10 - 0
python/py_igl/py_gaussian_curvature.cpp

@@ -0,0 +1,10 @@
+m.def("gaussian_curvature", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& K
+)
+{
+  return igl::gaussian_curvature(V,F,K);
+}, __doc_igl_gaussian_curvature,
+py::arg("V"), py::arg("F"), py::arg("K"));

+ 10 - 0
python/py_igl/py_grad.cpp

@@ -0,0 +1,10 @@
+m.def("grad", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::SparseMatrix<double>& G
+)
+{
+  return igl::grad(V,F,G);
+}, __doc_igl_grad,
+py::arg("V"), py::arg("F"), py::arg("G"));

+ 9 - 0
python/py_igl/py_invert_diag.cpp

@@ -0,0 +1,9 @@
+m.def("invert_diag", []
+(
+  const Eigen::SparseMatrix<double>& X,
+  Eigen::SparseMatrix<double>& Y
+)
+{
+  return igl::invert_diag(X,Y);
+}, __doc_igl_invert_diag,
+py::arg("X"), py::arg("Y"));

+ 24 - 0
python/py_igl/py_jet.cpp

@@ -0,0 +1,24 @@
+m.def("jet", []
+(
+  const Eigen::MatrixXd& Z,
+  const bool normalize,
+  Eigen::MatrixXd& C
+)
+{
+  assert_is_VectorX("Z",Z);
+  return igl::jet(Z,normalize,C);
+}, __doc_igl_jet,
+py::arg("Z"), py::arg("normalize"), py::arg("C"));
+
+m.def("jet", []
+(
+  const Eigen::MatrixXd& Z,
+  const double min_Z,
+  const double max_Z,
+  Eigen::MatrixXd& C
+)
+{
+  assert_is_VectorX("Z",Z);
+  return igl::jet(Z,min_Z,max_Z,C);
+}, __doc_igl_jet,
+py::arg("Z"), py::arg("min_Z"), py::arg("max_Z"), py::arg("C"));

+ 19 - 0
python/py_igl/py_massmatrix.cpp

@@ -0,0 +1,19 @@
+py::enum_<igl::MassMatrixType>(m, "MassMatrixType")
+    .value("MASSMATRIX_TYPE_BARYCENTRIC", igl::MASSMATRIX_TYPE_BARYCENTRIC)
+    .value("MASSMATRIX_TYPE_VORONOI", igl::MASSMATRIX_TYPE_VORONOI)
+    .value("MASSMATRIX_TYPE_FULL", igl::MASSMATRIX_TYPE_FULL)
+    .value("MASSMATRIX_TYPE_DEFAULT", igl::MASSMATRIX_TYPE_DEFAULT)
+    .value("NUM_MASSMATRIX_TYPE", igl::NUM_MASSMATRIX_TYPE)
+    .export_values();
+
+m.def("massmatrix", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const igl::MassMatrixType type,
+  Eigen::SparseMatrix<double>& M
+)
+{
+  return igl::massmatrix(V,F,type,M);
+}, __doc_igl_massmatrix,
+py::arg("V"), py::arg("F"), py::arg("type"), py::arg("M"));

+ 73 - 0
python/py_igl/py_min_quad_with_fixed.cpp

@@ -0,0 +1,73 @@
+
+// Wrap the data class, no properties are exposed since it is not necessary
+py::class_<igl::min_quad_with_fixed_data<double> > min_quad_with_fixed_data(m, "min_quad_with_fixed_data");
+
+min_quad_with_fixed_data
+.def(py::init<>());
+
+m.def("min_quad_with_fixed_precompute", []
+(
+  const Eigen::SparseMatrix<double>& A,
+  const Eigen::MatrixXi& known,
+  const Eigen::SparseMatrix<double>& Aeq,
+  const bool pd,
+  igl::min_quad_with_fixed_data<double> & data
+)
+{
+  assert_is_VectorX("known",known);
+  return igl::min_quad_with_fixed_precompute(A,known,Aeq,pd,data);
+}, __doc_igl_min_quad_with_fixed,
+py::arg("A"), py::arg("known"), py::arg("Aeq"), py::arg("pd"), py::arg("data"));
+
+m.def("min_quad_with_fixed_solve", []
+(
+  const igl::min_quad_with_fixed_data<double> & data,
+  const Eigen::MatrixXd& B,
+  const Eigen::MatrixXd& Y,
+  const Eigen::MatrixXd & Beq,
+  Eigen::MatrixXd& Z,
+  Eigen::MatrixXd& sol
+)
+{
+  assert_is_VectorX("B",B);
+  assert_is_VectorX("Y",Y);
+  assert_is_VectorX("Beq",Beq);
+  return igl::min_quad_with_fixed_solve(data,B,Y,Beq,Z,sol);
+}, __doc_igl_min_quad_with_fixed,
+py::arg("data"), py::arg("B"), py::arg("Y"), py::arg("Beq"), py::arg("Z"), py::arg("sol"));
+
+m.def("min_quad_with_fixed_solve", []
+(
+  const igl::min_quad_with_fixed_data<double> & data,
+  const Eigen::MatrixXd& B,
+  const Eigen::MatrixXd& Y,
+  const Eigen::MatrixXd & Beq,
+  Eigen::MatrixXd& Z
+)
+{
+  assert_is_VectorX("B",B);
+  assert_is_VectorX("Y",Y);
+  assert_is_VectorX("Beq",Beq);
+  return igl::min_quad_with_fixed_solve(data,B,Y,Beq,Z);
+}, __doc_igl_min_quad_with_fixed,
+py::arg("data"), py::arg("B"), py::arg("Y"), py::arg("Beq"), py::arg("Z"));
+
+m.def("min_quad_with_fixed", []
+(
+  const Eigen::SparseMatrix<double>& A,
+  const Eigen::MatrixXd& B,
+  const Eigen::MatrixXi& known,
+  const Eigen::MatrixXd& Y,
+  const Eigen::SparseMatrix<double>& Aeq,
+  const Eigen::MatrixXd& Beq,
+  const bool pd,
+  Eigen::MatrixXd& Z
+)
+{
+  assert_is_VectorX("B",B);
+  assert_is_VectorX("known",known);
+  assert_is_VectorX("Y",Y);
+  assert_is_VectorX("Beq",Beq);
+  return igl::min_quad_with_fixed(A,B,known,Y,Aeq,Beq,pd,Z);
+}, __doc_igl_min_quad_with_fixed,
+py::arg("A"), py::arg("B"), py::arg("known"), py::arg("Y"), py::arg("Aeq"), py::arg("Beq"), py::arg("pd"), py::arg("Z"));

+ 24 - 0
python/py_igl/py_parula.cpp

@@ -0,0 +1,24 @@
+m.def("parula", []
+(
+  const Eigen::MatrixXd& Z,
+  const bool normalize,
+  Eigen::MatrixXd& C
+)
+{
+  assert_is_VectorX("Z",Z);
+  return igl::parula(Z,normalize,C);
+}, __doc_igl_parula,
+py::arg("Z"), py::arg("normalize"), py::arg("C"));
+
+m.def("parula", []
+(
+  const Eigen::MatrixXd& Z,
+  const double min_Z,
+  const double max_Z,
+  Eigen::MatrixXd& C
+)
+{
+  assert_is_VectorX("Z",Z);
+  return igl::parula(Z,min_Z,max_Z,C);
+}, __doc_igl_parula,
+py::arg("Z"), py::arg("min_Z"), py::arg("max_Z"), py::arg("C"));

+ 38 - 0
python/py_igl/py_per_corner_normals.cpp

@@ -0,0 +1,38 @@
+m.def("per_corner_normals", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const double corner_threshold,
+  Eigen::MatrixXd& CN
+)
+{
+  return igl::per_corner_normals(V,F,corner_threshold,CN);
+}, __doc_igl_per_corner_normals,
+py::arg("V"), py::arg("F"), py::arg("corner_threshold"), py::arg("CN"));
+
+m.def("per_corner_normals", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const Eigen::MatrixXd& FN,
+  const double corner_threshold,
+  Eigen::MatrixXd& CN
+)
+{
+  return igl::per_corner_normals(V,F,FN,corner_threshold,CN);
+}, __doc_igl_per_corner_normals,
+py::arg("V"), py::arg("F"), py::arg("FN"), py::arg("corner_threshold"), py::arg("CN"));
+
+m.def("per_corner_normals", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const Eigen::MatrixXd& FN,
+  const double corner_threshold,
+  const std::vector<std::vector<int> >& VF,
+  Eigen::MatrixXd& CN
+)
+{
+  return igl::per_corner_normals(V,F,FN,VF,corner_threshold,CN);
+}, __doc_igl_per_corner_normals,
+py::arg("V"), py::arg("F"), py::arg("FN"), py::arg("corner_threshold"), py::arg("VF"), py::arg("CN"));

+ 34 - 0
python/py_igl/py_per_face_normals.cpp

@@ -0,0 +1,34 @@
+m.def("per_face_normals", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const Eigen::MatrixXd& Z,
+  Eigen::MatrixXd& N
+)
+{
+  assert_is_VectorX("Z",Z);
+  return igl::per_face_normals(V,F,Z,N);
+}, __doc_igl_per_face_normals,
+py::arg("V"), py::arg("F"), py::arg("Z"), py::arg("N"));
+
+m.def("per_face_normals", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& N
+)
+{
+  return igl::per_face_normals(V,F,N);
+}, __doc_igl_per_face_normals,
+py::arg("V"), py::arg("F"), py::arg("N"));
+
+m.def("per_face_normals_stable", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& N
+)
+{
+  return igl::per_face_normals_stable(V,F,N);
+}, __doc_igl_per_face_normals,
+py::arg("V"), py::arg("F"), py::arg("N"));

+ 55 - 0
python/py_igl/py_per_vertex_normals.cpp

@@ -0,0 +1,55 @@
+py::enum_<igl::PerVertexNormalsWeightingType>(m, "PerVertexNormalsWeightingType")
+    .value("PER_VERTEX_NORMALS_WEIGHTING_TYPE_UNIFORM", igl::PER_VERTEX_NORMALS_WEIGHTING_TYPE_UNIFORM)
+    .value("PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA", igl::PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA)
+    .value("PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE", igl::PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE)
+    .value("PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT", igl::PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT)
+    .value("NUM_PER_VERTEX_NORMALS_WEIGHTING_TYPE", igl::NUM_PER_VERTEX_NORMALS_WEIGHTING_TYPE)
+    .export_values();
+
+m.def("per_vertex_normals", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const igl::PerVertexNormalsWeightingType weighting,
+  Eigen::MatrixXd& N
+)
+{
+  return igl::per_vertex_normals(V,F,weighting,N);
+}, __doc_igl_per_vertex_normals,
+py::arg("V"), py::arg("F"), py::arg("weighting"), py::arg("N"));
+
+m.def("per_vertex_normals", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& N
+)
+{
+  return igl::per_vertex_normals(V,F,N);
+}, __doc_igl_per_vertex_normals,
+py::arg("V"), py::arg("F"), py::arg("N"));
+
+m.def("per_vertex_normals", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const igl::PerVertexNormalsWeightingType weighting,
+  const Eigen::MatrixXd& FN,
+  Eigen::MatrixXd& N
+)
+{
+  return igl::per_vertex_normals(V,F,weighting,FN,N);
+}, __doc_igl_per_vertex_normals,
+py::arg("V"), py::arg("F"), py::arg("weighting"), py::arg("FN"), py::arg("N"));
+
+m.def("per_vertex_normals", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const Eigen::MatrixXd& FN,
+  Eigen::MatrixXd& N
+)
+{
+  return igl::per_vertex_normals(V,F,FN,N);
+}, __doc_igl_per_vertex_normals,
+py::arg("V"), py::arg("F"), py::arg("FN"), py::arg("N"));

+ 15 - 0
python/py_igl/py_principal_curvature.cpp

@@ -0,0 +1,15 @@
+m.def("principal_curvature", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& PD1,
+  Eigen::MatrixXd& PD2,
+  Eigen::MatrixXd& PV1,
+  Eigen::MatrixXd& PV2,
+  unsigned radius,
+  bool useKring
+)
+{
+  return igl::principal_curvature(V,F,PD1,PD2,PV1,PV2,radius,useKring);
+}, __doc_igl_principal_curvature,
+py::arg("V"), py::arg("F"), py::arg("PD1"), py::arg("PD2"), py::arg("PV1"), py::arg("PV2"), py::arg("radius") = 5, py::arg("useKring") = true);

+ 10 - 0
python/py_igl/py_readDMAT.cpp

@@ -0,0 +1,10 @@
+
+m.def("readDMAT", []
+(
+  const std::string str,
+  Eigen::MatrixXd& W
+)
+{
+  return igl::readDMAT(str,W);
+}, __doc_igl_readDMAT,
+py::arg("str"), py::arg("W"));

+ 22 - 0
python/py_igl/py_readOFF.cpp

@@ -0,0 +1,22 @@
+m.def("readOFF", []
+(
+  const std::string str,
+  Eigen::MatrixXd& V,
+  Eigen::MatrixXi& F
+)
+{
+  return igl::readOFF(str,V,F);
+}, __doc_igl_readOFF,
+py::arg("str"), py::arg("V"), py::arg("F"));
+
+m.def("readOFF", []
+(
+  const std::string str,
+  Eigen::MatrixXd& V,
+  Eigen::MatrixXi& F,
+  Eigen::MatrixXd& N
+)
+{
+  return igl::readOFF(str,V,F,N);
+}, __doc_igl_readOFF,
+py::arg("str"), py::arg("V"), py::arg("F"), py::arg("N"));

+ 36 - 0
python/py_igl/py_read_triangle_mesh.cpp

@@ -0,0 +1,36 @@
+m.def("read_triangle_mesh", []
+(
+  const std::string str,
+  std::vector<std::vector<double> >& V,
+  std::vector<std::vector<int> >& F
+)
+{
+  return igl::read_triangle_mesh(str,V,F);
+}, __doc_igl_read_triangle_mesh,
+py::arg("str"), py::arg("V"), py::arg("F"));
+
+m.def("read_triangle_mesh", []
+(
+  const std::string str,
+  Eigen::MatrixXd& V,
+  Eigen::MatrixXi& F
+)
+{
+  return igl::read_triangle_mesh(str,V,F);
+}, __doc_igl_read_triangle_mesh,
+py::arg("str"), py::arg("V"), py::arg("F"));
+
+m.def("read_triangle_mesh", []
+(
+  const std::string str,
+  Eigen::MatrixXd& V,
+  Eigen::MatrixXi& F,
+  std::string & dir,
+  std::string & base,
+  std::string & ext,
+  std::string & name
+)
+{
+  return igl::read_triangle_mesh(str,V,F,dir,base,ext,name);
+}, __doc_igl_read_triangle_mesh,
+py::arg("str"), py::arg("V"), py::arg("F"), py::arg("dir"), py::arg("base"), py::arg("ext"), py::arg("name"));

+ 11 - 0
python/py_igl/py_setdiff.cpp

@@ -0,0 +1,11 @@
+m.def("setdiff", []
+(
+  const Eigen::MatrixXi& A,
+  const Eigen::MatrixXi& B,
+  Eigen::MatrixXi& C,
+  Eigen::MatrixXi& IA
+)
+{
+  return igl::setdiff(A,B,C,IA);
+}, __doc_igl_setdiff,
+py::arg("A"), py::arg("B"), py::arg("C"), py::arg("IA"));

+ 155 - 0
python/py_igl/py_slice.cpp

@@ -0,0 +1,155 @@
+// // Double
+//
+m.def("slice", []
+(
+  const Eigen::SparseMatrix<double>& X,
+  const Eigen::MatrixXi& R,
+  const Eigen::MatrixXi& C,
+  Eigen::SparseMatrix<double>& Y
+)
+{
+  assert_is_VectorX("R",R);
+  assert_is_VectorX("C",C);
+  return igl::slice(X,R,C,Y);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("C"), py::arg("Y"));
+
+m.def("slice", []
+(
+  const Eigen::SparseMatrix<double>& X,
+  const Eigen::MatrixXi& R,
+  const int& dim,
+  Eigen::SparseMatrix<double>& Y
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice(X,R,dim,Y);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("dim"), py::arg("Y"));
+
+m.def("slice", []
+(
+  const Eigen::MatrixXd& X,
+  const Eigen::MatrixXi& R,
+  const Eigen::MatrixXi& C,
+  Eigen::MatrixXd& Y
+)
+{
+  assert_is_VectorX("R",R);
+  assert_is_VectorX("C",C);
+  return igl::slice(X,R,C,Y);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("C"), py::arg("Y"));
+
+m.def("slice", []
+(
+  const Eigen::MatrixXd& X,
+  const Eigen::MatrixXi& R,
+  Eigen::MatrixXd& Y
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice(X,R,Y);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("Y"));
+
+m.def("slice", []
+(
+  const Eigen::MatrixXd& X,
+  const Eigen::MatrixXi& R
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice(X,R);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("A"));
+
+m.def("slice", []
+(
+  const Eigen::MatrixXd& X,
+  const Eigen::MatrixXi& R,
+  const int& dim
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice(X,R,dim);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("dim"));
+
+// int
+m.def("slice", []
+(
+  const Eigen::SparseMatrix<int>& X,
+  const Eigen::MatrixXi& R,
+  const Eigen::MatrixXi& C,
+  Eigen::SparseMatrix<int>& Y
+)
+{
+  assert_is_VectorX("R",R);
+  assert_is_VectorX("C",C);
+  return igl::slice(X,R,C,Y);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("C"), py::arg("Y"));
+
+m.def("slice", []
+(
+  const Eigen::SparseMatrix<int>& X,
+  const Eigen::MatrixXi& R,
+  const int& dim,
+  Eigen::SparseMatrix<int>& Y
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice(X,R,dim,Y);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("dim"), py::arg("Y"));
+
+m.def("slice", []
+(
+  const Eigen::MatrixXi& X,
+  const Eigen::MatrixXi& R,
+  const Eigen::MatrixXi& C,
+  Eigen::MatrixXi& Y
+)
+{
+  assert_is_VectorX("R",R);
+  assert_is_VectorX("C",C);
+  return igl::slice(X,R,C,Y);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("C"), py::arg("Y"));
+
+
+m.def("slice", []
+(
+  const Eigen::MatrixXi& X,
+  const Eigen::MatrixXi& R,
+  Eigen::MatrixXi& Y
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice(X,R,Y);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("Y"));
+
+m.def("slice", []
+(
+  const Eigen::MatrixXi& X,
+  const Eigen::MatrixXi& R
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice(X,R);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"));
+
+m.def("slice", []
+(
+  const Eigen::MatrixXi& X,
+  const Eigen::MatrixXi& R,
+  const int& dim
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice(X,R,dim);
+}, __doc_igl_slice,
+py::arg("X"), py::arg("R"), py::arg("dim"));

+ 107 - 0
python/py_igl/py_slice_into.cpp

@@ -0,0 +1,107 @@
+m.def("slice_into", []
+(
+  const Eigen::SparseMatrix<double>& X,
+  const Eigen::MatrixXi& R,
+  const Eigen::MatrixXi& C,
+  Eigen::SparseMatrix<double>& Y
+)
+{
+  assert_is_VectorX("R",R);
+  assert_is_VectorX("C",C);
+  return igl::slice_into(X,R,C,Y);
+}, __doc_igl_slice_into,
+py::arg("X"), py::arg("R"), py::arg("C"), py::arg("Y"));
+
+m.def("slice_into", []
+(
+  const Eigen::MatrixXd& X,
+  const Eigen::MatrixXi& R,
+  const Eigen::MatrixXi& C,
+  Eigen::MatrixXd& Y
+)
+{
+  assert_is_VectorX("R",R);
+  assert_is_VectorX("C",C);
+  return igl::slice_into(X,R,C,Y);
+}, __doc_igl_slice_into,
+py::arg("X"), py::arg("R"), py::arg("C"), py::arg("Y"));
+
+m.def("slice_into", []
+(
+  const Eigen::MatrixXd& X,
+  const Eigen::MatrixXi& R,
+  const int& dim,
+  Eigen::MatrixXd& Y
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice_into(X,R,dim,Y);
+}, __doc_igl_slice_into,
+py::arg("X"), py::arg("R"), py::arg("dim"), py::arg("Y"));
+
+m.def("slice_into", []
+(
+  const Eigen::MatrixXd& X,
+  const Eigen::MatrixXi& R,
+  Eigen::MatrixXd& Y
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice_into(X,R,Y);
+}, __doc_igl_slice_into,
+py::arg("X"), py::arg("R"), py::arg("Y"));
+
+// int
+
+m.def("slice_into", []
+(
+  const Eigen::SparseMatrix<int>& X,
+  const Eigen::MatrixXi& R,
+  const Eigen::MatrixXi& C,
+  Eigen::SparseMatrix<int>& Y
+)
+{
+  assert_is_VectorX("R",R);
+  assert_is_VectorX("C",C);
+  return igl::slice_into(X,R,C,Y);
+}, __doc_igl_slice_into,
+py::arg("X"), py::arg("R"), py::arg("C"), py::arg("Y"));
+
+m.def("slice_into", []
+(
+  const Eigen::MatrixXi& X,
+  const Eigen::MatrixXi& R,
+  const Eigen::MatrixXi& C,
+  Eigen::MatrixXi& Y
+)
+{
+  assert_is_VectorX("R",R);
+  assert_is_VectorX("C",C);
+  return igl::slice_into(X,R,C,Y);
+}, __doc_igl_slice_into,
+py::arg("X"), py::arg("R"), py::arg("C"), py::arg("Y"));
+
+m.def("slice_into", []
+(
+  const Eigen::MatrixXi& X,
+  const Eigen::MatrixXi& R,
+  const int& dim,
+  Eigen::MatrixXi& Y
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice_into(X,R,dim,Y);
+}, __doc_igl_slice_into,
+py::arg("X"), py::arg("R"), py::arg("dim"), py::arg("Y"));
+
+m.def("slice_into", []
+(
+  const Eigen::MatrixXi& X,
+  const Eigen::MatrixXi& R,
+  Eigen::MatrixXi& Y
+)
+{
+  assert_is_VectorX("R",R);
+  return igl::slice_into(X,R,Y);
+}, __doc_igl_slice_into,
+py::arg("X"), py::arg("R"), py::arg("Y"));

Some files were not shown because too many files changed in this diff