Browse Source

Merge branch 'pythonwrappers'

Conflicts:
	.gitignore
	.gitmodules
	external/embree

Former-commit-id: 7f626178230d826c406b1b3046c6b982191a5edd
Daniele Panozzo 9 years ago
parent
commit
4b431d288a
41 changed files with 2743 additions and 3 deletions
  1. 5 0
      .gitignore
  2. 3 1
      .gitmodules
  3. 0 1
      include/igl/viewer/Viewer.cpp
  4. 1 1
      include/igl/viewer/ViewerCore.cpp
  5. 48 0
      python/001_BasicTypes.py
  6. 16 0
      python/101_FileIO.py
  7. 11 0
      python/102_DrawMesh.py
  8. 40 0
      python/103_Events.py
  9. 24 0
      python/104_Colors.py
  10. 69 0
      python/105_Overlays.py
  11. 48 0
      python/201_Normals.py
  12. 20 0
      python/202_GaussianCurvature.py
  13. 63 0
      python/203_CurvatureDirections.py
  14. 51 0
      python/204_Gradient.py
  15. 148 0
      python/CMakeLists.txt
  16. 48 0
      python/iglhelpers.py
  17. 68 0
      python/mk_py_doc.py
  18. 409 0
      python/py_doc.cpp
  19. 409 0
      python/py_doc.h
  20. 43 0
      python/py_igl.cpp
  21. 9 0
      python/py_igl/py_avg_edge_length.cpp
  22. 10 0
      python/py_igl/py_barycenter.cpp
  23. 10 0
      python/py_igl/py_cotmatrix.cpp
  24. 10 0
      python/py_igl/py_gaussian_curvature.cpp
  25. 10 0
      python/py_igl/py_grad.cpp
  26. 9 0
      python/py_igl/py_invert_diag.cpp
  27. 23 0
      python/py_igl/py_jet.cpp
  28. 19 0
      python/py_igl/py_massmatrix.cpp
  29. 24 0
      python/py_igl/py_parula.cpp
  30. 38 0
      python/py_igl/py_per_corner_normals.cpp
  31. 34 0
      python/py_igl/py_per_face_normals.cpp
  32. 55 0
      python/py_igl/py_per_vertex_normals.cpp
  33. 15 0
      python/py_igl/py_principal_curvature.cpp
  34. 10 0
      python/py_igl/py_readDMAT.cpp
  35. 22 0
      python/py_igl/py_readOFF.cpp
  36. 36 0
      python/py_igl/py_read_triangle_mesh.cpp
  37. 25 0
      python/py_igl/py_writeOBJ.cpp
  38. 327 0
      python/py_igl_viewer.cpp
  39. 449 0
      python/py_vector.cpp
  40. 61 0
      python/python.cpp
  41. 23 0
      python/python.h

+ 5 - 0
.gitignore

@@ -78,3 +78,8 @@ 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__

+ 3 - 1
.gitmodules

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

+ 0 - 1
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()

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

@@ -481,7 +481,7 @@ IGL_INLINE igl::viewer::ViewerCore::ViewerCore()
   camera_eye << 0, 0, 5;
   camera_center << 0, 0, 0;
   camera_up << 0, 1, 0;
-
+  
   // Default visualization options
   show_faces = true;
   show_lines = true;

+ 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='')
+
+
+
+
+
+
+

+ 16 - 0
python/101_FileIO.py

@@ -0,0 +1,16 @@
+from __future__ import print_function
+import sys, os
+import numpy as np
+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();

+ 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()

+ 69 - 0
python/105_Overlays.py

@@ -0,0 +1,69 @@
+import igl
+import numpy as np
+from iglhelpers import *
+
+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 = p2e(np.matrix(
+[
+[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 = p2e(np.matrix(
+[
+[0, 1],
+[1, 2],
+[2, 3],
+[3, 0],
+[4, 5],
+[5, 6],
+[6, 7],
+[7, 4],
+[0, 4],
+[1, 5],
+[2, 6],
+[7 ,3]
+], dtype='int32'
+))
+
+# 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,p2e(np.array([[1,0,0]], dtype='float64')))
+
+# 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]),
+        p2e(np.array([[1,0,0]], dtype='float64')))
+
+# 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()

+ 63 - 0
python/203_CurvatureDirections.py

@@ -0,0 +1,63 @@
+import igl
+import numpy as np
+from iglhelpers import *
+
+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 = p2e(np.array([[0.8,0.2,0.2]]))
+blue = p2e(np.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();

+ 51 - 0
python/204_Gradient.py

@@ -0,0 +1,51 @@
+import igl
+from iglhelpers import *
+
+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 = p2e(np.array([[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()

+ 148 - 0
python/CMakeLists.txt

@@ -0,0 +1,148 @@
+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")
+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")
+
+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()

+ 48 - 0
python/iglhelpers.py

@@ -0,0 +1,48 @@
+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')

+ 68 - 0
python/mk_py_doc.py

@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+#
+#  Syntax: mkdoc.py <path_of_header_files>
+#
+#  Extract documentation from C++ header files to use it in libiglPython bindings
+#
+
+import os, sys, glob
+
+#http://stackoverflow.com/questions/3207219/how-to-list-all-files-of-a-directory-in-python
+def get_filepaths(directory):
+    """
+    This function will generate the file names in a directory
+    tree by walking the tree either top-down or bottom-up. For each
+    directory in the tree rooted at directory top (including top itself),
+    it yields a 3-tuple (dirpath, dirnames, filenames).
+    """
+    file_paths = []  # List which will store all of the full filepaths.
+
+    # Walk the tree.
+    for root, directories, files in os.walk(directory):
+        for filename in files:
+            # Join the two strings in order to form the full filepath.
+            filepath = os.path.join(root, filename)
+            file_paths.append(filepath)  # Add it to the list.
+
+    return file_paths  # Self-explanatory.
+
+
+if __name__ == '__main__':
+
+    if len(sys.argv) != 2:
+        print('Syntax: %s <path_of_header_files>' % sys.argv[0])
+        exit(-1)
+
+    # Open two files, py_doc.h and py_doc.cpp
+    fh = open('py_doc.h', 'w')
+    fc = open('py_doc.cpp', 'w')
+
+    # List all files in the given folder and subfolders
+    base_path = sys.argv[1]
+    full_file_paths = get_filepaths(base_path)
+
+    # Add all the .h files
+    for f in full_file_paths:
+      if f.endswith(".h"):
+        f_clean = f[len(base_path):]
+        f_clean = f_clean.replace(base_path, "")
+        f_clean = f_clean.replace(".h", "")
+        f_clean = f_clean.replace("/", "_")
+        f_clean = f_clean.replace("\\", "_")
+        f_clean = f_clean.replace(" ", "_")
+        f_clean = f_clean.replace(".", "_")
+
+        #tmp = open(f, 'r', encoding="utf8")
+        tmp_string = f.replace("../include/", "libigl/") # " " # tmp.read()
+        tmp_string = "See " + tmp_string + " for the documentation."
+        #tmp.close()
+
+        h_string = "extern const char *__doc_" + f_clean + ";\n"
+        cpp_string = "const char *__doc_" + f_clean + " = R\"igl_Qu8mg5v7(" + tmp_string + ")igl_Qu8mg5v7\";\n"
+
+        fh.write(h_string)
+        fc.write(cpp_string)
+
+    # Close files
+    fh.close()
+    fc.close()

+ 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;

+ 43 - 0
python/py_igl.cpp

@@ -0,0 +1,43 @@
+#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>
+
+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"
+
+}

+ 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"));

+ 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"));

+ 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"));

+ 23 - 0
python/py_igl/py_jet.cpp

@@ -0,0 +1,23 @@
+m.def("jet", []
+(
+  const Eigen::MatrixXd& Z,
+  const bool normalize,
+  Eigen::MatrixXd& C
+)
+{
+  assert_is_VectorXd("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::VectorXd& Z,
+  const double min_Z,
+  const double max_Z,
+  Eigen::MatrixXd& C
+)
+{
+  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"));

+ 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_VectorXd("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_VectorXd("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_VectorXd("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"));

+ 25 - 0
python/py_igl/py_writeOBJ.cpp

@@ -0,0 +1,25 @@
+m.def("writeOBJ", []
+(
+  const std::string str,
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  const Eigen::MatrixXd& CN,
+  const Eigen::MatrixXi& FN,
+  const Eigen::MatrixXd& TC,
+  const Eigen::MatrixXi& FTC
+)
+{
+  return igl::writeOBJ(str,V,F,CN,FN,TC,FTC);
+}, __doc_igl_writeOBJ,
+py::arg("str"), py::arg("V"), py::arg("F"), py::arg("CN"), py::arg("FN"), py::arg("TC"), py::arg("FTC"));
+
+m.def("writeOBJ", []
+(
+  const std::string str,
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F
+)
+{
+  return igl::writeOBJ(str,V,F);
+}, __doc_igl_writeOBJ,
+py::arg("str"), py::arg("V"), py::arg("F"));

+ 327 - 0
python/py_igl_viewer.cpp

@@ -0,0 +1,327 @@
+#include <Eigen/Dense>
+#include <Eigen/Sparse>
+
+#include "python.h"
+#include <igl/viewer/Viewer.h>
+#include <igl/viewer/ViewerCore.h>
+#include <igl/viewer/ViewerData.h>
+
+void python_export_igl_viewer(py::module &m)
+{
+
+  py::module me = m.def_submodule(
+    "viewer", "Mesh viewer");
+
+/////////////////////// DATA
+
+py::class_<igl::viewer::ViewerData> viewerdata_class(me, "ViewerData");
+
+py::enum_<igl::viewer::ViewerData::DirtyFlags>(viewerdata_class, "DirtyFlags")
+    .value("DIRTY_NONE", igl::viewer::ViewerData::DIRTY_NONE)
+    .value("DIRTY_POSITION", igl::viewer::ViewerData::DIRTY_POSITION)
+    .value("DIRTY_UV", igl::viewer::ViewerData::DIRTY_UV)
+    .value("DIRTY_NORMAL", igl::viewer::ViewerData::DIRTY_NORMAL)
+    .value("DIRTY_AMBIENT", igl::viewer::ViewerData::DIRTY_AMBIENT)
+    .value("DIRTY_DIFFUSE", igl::viewer::ViewerData::DIRTY_DIFFUSE)
+    .value("DIRTY_SPECULAR", igl::viewer::ViewerData::DIRTY_SPECULAR)
+    .value("DIRTY_TEXTURE", igl::viewer::ViewerData::DIRTY_TEXTURE)
+    .value("DIRTY_FACE", igl::viewer::ViewerData::DIRTY_FACE)
+    .value("DIRTY_MESH", igl::viewer::ViewerData::DIRTY_MESH)
+    .value("DIRTY_OVERLAY_LINES", igl::viewer::ViewerData::DIRTY_OVERLAY_LINES)
+    .value("DIRTY_OVERLAY_POINTS", igl::viewer::ViewerData::DIRTY_OVERLAY_POINTS)
+    .value("DIRTY_ALL", igl::viewer::ViewerData::DIRTY_ALL)
+    .export_values();
+
+
+    viewerdata_class
+    .def(py::init<>())
+    .def("set_mesh", &igl::viewer::ViewerData::set_mesh)
+    .def("set_colors", &igl::viewer::ViewerData::set_colors)
+    .def("clear", &igl::viewer::ViewerData::clear)
+    .def("set_face_based", &igl::viewer::ViewerData::set_face_based)
+
+    .def("set_vertices", &igl::viewer::ViewerData::set_vertices)
+    .def("set_normals", &igl::viewer::ViewerData::set_normals)
+
+    .def("set_uv",
+       (void (igl::viewer::ViewerData::*) (const Eigen::MatrixXd &)) &igl::viewer::ViewerData::set_uv
+    )
+
+    .def("set_uv",
+       (void (igl::viewer::ViewerData::*) (const Eigen::MatrixXd &, const Eigen::MatrixXi&)) &igl::viewer::ViewerData::set_uv
+    )
+
+    .def("set_texture", &igl::viewer::ViewerData::set_texture)
+    .def("set_points", &igl::viewer::ViewerData::set_points)
+    .def("add_points", &igl::viewer::ViewerData::add_points)
+    .def("set_edges", &igl::viewer::ViewerData::set_edges)
+    .def("add_edges", &igl::viewer::ViewerData::add_edges)
+
+    .def("add_label", [] (igl::viewer::ViewerData& data, const Eigen::MatrixXd& P,  const std::string& str)
+    {
+      assert_is_VectorXd("P",P);
+      data.add_label(P,str);
+    })
+
+    .def("compute_normals", &igl::viewer::ViewerData::compute_normals)
+
+    .def("uniform_colors", [] (igl::viewer::ViewerData& data, const Eigen::MatrixXd& ambient, const Eigen::MatrixXd& diffuse, const Eigen::MatrixXd& specular)
+    {
+      assert_is_Vector3d("ambient",ambient);
+      assert_is_Vector3d("diffuse",diffuse);
+      assert_is_Vector3d("specular",specular);
+      data.uniform_colors(ambient,diffuse, specular);
+    })
+
+    .def("grid_texture", &igl::viewer::ViewerData::grid_texture)
+
+    .def_readwrite("V", &igl::viewer::ViewerData::V)
+    .def_readwrite("F", &igl::viewer::ViewerData::F)
+
+    .def_readwrite("F_normals", &igl::viewer::ViewerData::F_normals)
+    .def_readwrite("F_material_ambient", &igl::viewer::ViewerData::F_material_ambient)
+    .def_readwrite("F_material_diffuse", &igl::viewer::ViewerData::F_material_diffuse)
+    .def_readwrite("F_material_specular", &igl::viewer::ViewerData::F_material_specular)
+
+    .def_readwrite("V_normals", &igl::viewer::ViewerData::V_normals)
+    .def_readwrite("V_material_ambient", &igl::viewer::ViewerData::V_material_ambient)
+    .def_readwrite("V_material_diffuse", &igl::viewer::ViewerData::V_material_diffuse)
+    .def_readwrite("V_material_specular", &igl::viewer::ViewerData::V_material_specular)
+
+    .def_readwrite("V_uv", &igl::viewer::ViewerData::V_uv)
+    .def_readwrite("F_uv", &igl::viewer::ViewerData::F_uv)
+
+    .def_readwrite("texture_R", &igl::viewer::ViewerData::texture_R)
+    .def_readwrite("texture_G", &igl::viewer::ViewerData::texture_G)
+    .def_readwrite("texture_B", &igl::viewer::ViewerData::texture_B)
+
+    .def_readwrite("lines", &igl::viewer::ViewerData::lines)
+    .def_readwrite("points", &igl::viewer::ViewerData::points)
+    .def_readwrite("labels_positions", &igl::viewer::ViewerData::labels_positions)
+    .def_readwrite("labels_strings", &igl::viewer::ViewerData::labels_strings)
+    .def_readwrite("dirty", &igl::viewer::ViewerData::dirty)
+    .def_readwrite("face_based", &igl::viewer::ViewerData::face_based)
+
+    ;
+
+//////////////////////// CORE
+
+py::class_<igl::viewer::ViewerCore> viewercore_class(me, "ViewerCore");
+
+    py::enum_<igl::viewer::ViewerCore::RotationType>(viewercore_class, "RotationType")
+        .value("ROTATION_TYPE_TRACKBALL", igl::viewer::ViewerCore::ROTATION_TYPE_TRACKBALL)
+        .value("ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP", igl::viewer::ViewerCore::ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP)
+        .value("NUM_ROTATION_TYPES", igl::viewer::ViewerCore::NUM_ROTATION_TYPES)
+        .export_values();
+
+    viewercore_class
+    .def(py::init<>())
+    //.def("align_camera_center", [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& V, const Eigen::MatrixXi& F){return core.align_camera_center(V,F);})
+    .def("init", &igl::viewer::ViewerCore::init)
+    .def("shut", &igl::viewer::ViewerCore::shut)
+    //.def("InitSerialization", &igl::viewer::ViewerCore::InitSerialization)
+    .def("align_camera_center",
+       (void (igl::viewer::ViewerCore::*) (const Eigen::MatrixXd &, const Eigen::MatrixXi &)) &igl::viewer::ViewerCore::align_camera_center
+    )
+
+    .def("align_camera_center",
+       (void (igl::viewer::ViewerCore::*) (const Eigen::MatrixXd &)) &igl::viewer::ViewerCore::align_camera_center
+    )
+
+    .def("clear_framebuffers",&igl::viewer::ViewerCore::clear_framebuffers)
+    .def("draw",&igl::viewer::ViewerCore::draw)
+    .def("draw_buffer",&igl::viewer::ViewerCore::draw_buffer)
+
+    .def_readwrite("textrenderer",&igl::viewer::ViewerCore::textrenderer)
+    .def_readwrite("shininess",&igl::viewer::ViewerCore::shininess)
+
+    .def_property("background_color",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.background_color.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Vector3d("background_color",v);
+      core.background_color = Eigen::Vector3f(v.cast<float>());
+    })
+
+    .def_property("line_color",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.line_color.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Vector3d("line_color",v);
+      core.line_color = Eigen::Vector3f(v.cast<float>());
+    })
+
+    .def_property("light_position",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.light_position.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Vector3d("light_position",v);
+      core.light_position = Eigen::Vector3f(v.cast<float>());
+    })
+
+    .def_readwrite("lighting_factor",&igl::viewer::ViewerCore::lighting_factor)
+
+    .def_readwrite("model_zoom",&igl::viewer::ViewerCore::model_zoom)
+
+    .def_property("model_translation",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.model_translation.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Vector3d("model_translation",v);
+      core.model_translation = Eigen::Vector3f(v.cast<float>());
+    })
+
+    .def_readwrite("model_zoom_uv",&igl::viewer::ViewerCore::model_zoom_uv)
+
+    .def_property("model_translation_uv",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.model_translation_uv.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Vector3d("model_translation_uv",v);
+      core.model_translation_uv = Eigen::Vector3f(v.cast<float>());
+    })
+
+    .def_readwrite("camera_zoom",&igl::viewer::ViewerCore::camera_zoom)
+    .def_readwrite("orthographic",&igl::viewer::ViewerCore::orthographic)
+
+    .def_property("camera_eye",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.camera_eye.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Vector3d("camera_eye",v);
+      core.camera_eye = Eigen::Vector3f(v.cast<float>());
+    })
+
+    .def_property("camera_up",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.camera_up.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Vector3d("camera_up",v);
+      core.camera_up = Eigen::Vector3f(v.cast<float>());
+    })
+
+    .def_property("camera_center",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.camera_center.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Vector3d("camera_center",v);
+      core.camera_center = Eigen::Vector3f(v.cast<float>());
+    })
+
+    .def_readwrite("camera_view_angle",&igl::viewer::ViewerCore::camera_view_angle)
+
+    .def_readwrite("camera_dnear",&igl::viewer::ViewerCore::camera_dnear)
+    .def_readwrite("camera_dfar",&igl::viewer::ViewerCore::camera_dfar)
+
+    .def_readwrite("show_overlay",&igl::viewer::ViewerCore::show_overlay)
+    .def_readwrite("show_overlay_depth",&igl::viewer::ViewerCore::show_overlay_depth)
+    .def_readwrite("show_texture",&igl::viewer::ViewerCore::show_texture)
+    .def_readwrite("show_faces",&igl::viewer::ViewerCore::show_faces)
+
+    .def_readwrite("show_lines",&igl::viewer::ViewerCore::show_lines)
+    .def_readwrite("show_vertid",&igl::viewer::ViewerCore::show_vertid)
+    .def_readwrite("show_faceid",&igl::viewer::ViewerCore::show_faceid)
+    .def_readwrite("invert_normals",&igl::viewer::ViewerCore::invert_normals)
+    .def_readwrite("depth_test",&igl::viewer::ViewerCore::depth_test)
+
+    .def_readwrite("point_size",&igl::viewer::ViewerCore::point_size)
+    .def_readwrite("line_width",&igl::viewer::ViewerCore::line_width)
+
+    .def_readwrite("is_animating",&igl::viewer::ViewerCore::is_animating)
+    .def_readwrite("animation_max_fps",&igl::viewer::ViewerCore::animation_max_fps)
+
+    .def_readwrite("object_scale",&igl::viewer::ViewerCore::object_scale)
+
+    .def_property("viewport",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.viewport.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Vector4d("viewport",v);
+      core.viewport = Eigen::Vector4f(v.cast<float>());
+    })
+
+    .def_property("view",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.view.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Matrix4d("view",v);
+      core.view = Eigen::Matrix4f(v.cast<float>());
+    })
+
+    .def_property("model",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.model.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Matrix4d("model",v);
+      core.model = Eigen::Matrix4f(v.cast<float>());
+    })
+
+    .def_property("proj",
+    [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.proj.cast<double>());},
+    [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v)
+    {
+      assert_is_Matrix4d("proj",v);
+      core.proj = Eigen::Matrix4f(v.cast<float>());
+    })
+
+    .def_readwrite("rotation_type",&igl::viewer::ViewerCore::rotation_type)
+
+    // TODO: wrap this!
+    // Eigen::Quaternionf trackball_angle;
+    ;
+
+///////////////////////// VIEWER
+
+// UI Enumerations
+    py::class_<igl::viewer::Viewer> viewer_class(me, "Viewer");
+
+    py::enum_<igl::viewer::Viewer::MouseButton>(viewer_class, "MouseButton")
+        .value("Left", igl::viewer::Viewer::MouseButton::Left)
+        .value("Middle", igl::viewer::Viewer::MouseButton::Middle)
+        .value("Right", igl::viewer::Viewer::MouseButton::Right)
+        .export_values();
+
+    viewer_class
+    .def(py::init<>())
+    .def_readwrite("data", &igl::viewer::Viewer::data)
+    .def_readwrite("core", &igl::viewer::Viewer::core)
+    .def("launch", &igl::viewer::Viewer::launch, py::arg("resizable") = true, py::arg("fullscreen") = false)
+    .def("init", &igl::viewer::Viewer::init)
+
+    // Scene IO
+    .def("load_scene", [](igl::viewer::Viewer& viewer)
+    {
+      viewer.load_scene();
+    })
+
+    .def("load_scene", [](igl::viewer::Viewer& viewer, std::string str)
+    {
+      viewer.load_scene(str);
+    })
+
+    .def("save_scene", &igl::viewer::Viewer::save_scene)
+
+    // Draw everything
+    .def("draw", &igl::viewer::Viewer::draw)
+
+    // OpenGL context resize
+    .def("resize", &igl::viewer::Viewer::resize)
+
+    // Helper functions
+    .def("snap_to_canonical_quaternion", &igl::viewer::Viewer::snap_to_canonical_quaternion)
+    .def("open_dialog_load_mesh", &igl::viewer::Viewer::open_dialog_load_mesh)
+    .def("open_dialog_save_mesh", &igl::viewer::Viewer::open_dialog_save_mesh)
+
+    // Callbacks
+    .def_readwrite("callback_init", &igl::viewer::Viewer::callback_init)
+    .def_readwrite("callback_pre_draw", &igl::viewer::Viewer::callback_pre_draw)
+    .def_readwrite("callback_post_draw", &igl::viewer::Viewer::callback_post_draw)
+    .def_readwrite("callback_mouse_down", &igl::viewer::Viewer::callback_mouse_down)
+    .def_readwrite("callback_mouse_up", &igl::viewer::Viewer::callback_mouse_up)
+    .def_readwrite("callback_mouse_move", &igl::viewer::Viewer::callback_mouse_move)
+    .def_readwrite("callback_mouse_scroll", &igl::viewer::Viewer::callback_mouse_scroll)
+    .def_readwrite("callback_key_pressed", &igl::viewer::Viewer::callback_key_pressed)
+    .def_readwrite("callback_key_down", &igl::viewer::Viewer::callback_key_down)
+    .def_readwrite("callback_key_up", &igl::viewer::Viewer::callback_key_up)
+    ;
+}

+ 449 - 0
python/py_vector.cpp

@@ -0,0 +1,449 @@
+#include <Eigen/Dense>
+#include <Eigen/Sparse>
+
+#include "python.h"
+
+/// Creates Python bindings for a dynamic Eigen matrix
+template <typename Type>
+py::class_<Type> bind_eigen_2(py::module &m, const char *name,
+                                py::object parent = py::object()) {
+    typedef typename Type::Scalar Scalar;
+
+    /* Many Eigen functions are templated and can't easily be referenced using
+       a function pointer, thus a big portion of the binding code below
+       instantiates Eigen code using small anonymous wrapper functions */
+    py::class_<Type> matrix(m, name, parent);
+
+    matrix
+        /* Constructors */
+        .def(py::init<>())
+        .def(py::init<size_t, size_t>())
+        .def("__init__", [](Type &m, Scalar f) {
+            new (&m) Type(1, 1);
+            m(0, 0) = f;
+        })
+        .def("__init__", [](Type &m, py::buffer b) {
+            py::buffer_info info = b.request();
+            if (info.format != py::format_descriptor<Scalar>::value())
+                throw std::runtime_error("Incompatible buffer format!");
+            if (info.ndim == 1) {
+                new (&m) Type(info.shape[0], 1);
+                memcpy(m.data(), info.ptr, sizeof(Scalar) * m.size());
+            } else if (info.ndim == 2) {
+                if (info.strides[0] == sizeof(Scalar)) {
+                    new (&m) Type(info.shape[0], info.shape[1]);
+                    memcpy(m.data(), info.ptr, sizeof(Scalar) * m.size());
+                } else {
+                    new (&m) Type(info.shape[1], info.shape[0]);
+                    memcpy(m.data(), info.ptr, sizeof(Scalar) * m.size());
+                    m.transposeInPlace();
+                }
+            } else {
+                throw std::runtime_error("Incompatible buffer dimension!");
+            }
+        })
+
+        /* Size query functions */
+        .def("size", [](const Type &m) { return m.size(); })
+        .def("cols", [](const Type &m) { return m.cols(); })
+        .def("rows", [](const Type &m) { return m.rows(); })
+
+        /* Extract rows and colums */
+        .def("col", [](const Type &m, int i) {
+            if (i<0 || i>=m.cols())
+              throw std::runtime_error("Column index out of bound.");
+            return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(m.col(i));
+        })
+        .def("row", [](const Type &m, int i) {
+            if (i<0 || i>=m.rows())
+              throw std::runtime_error("Row index out of bound.");
+            return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(m.row(i));
+        })
+
+
+        /* Initialization */
+        .def("setZero", [](Type &m) { m.setZero(); })
+        .def("setIdentity", [](Type &m) { m.setIdentity(); })
+        .def("setConstant", [](Type &m, Scalar value) { m.setConstant(value); })
+
+        /* Resizing */
+        .def("resize", [](Type &m, size_t s0, size_t s1) { m.resize(s0, s1); })
+        .def("resizeLike", [](Type &m, const Type &m2) { m.resizeLike(m2); })
+        .def("conservativeResize", [](Type &m, size_t s0, size_t s1) { m.conservativeResize(s0, s1); })
+
+
+        .def("mean", [](const Type &m) {return m.mean();})
+
+        /* Component-wise operations */
+        .def("cwiseAbs", &Type::cwiseAbs)
+        .def("cwiseAbs2", &Type::cwiseAbs2)
+        .def("cwiseSqrt", &Type::cwiseSqrt)
+        .def("cwiseInverse", &Type::cwiseInverse)
+        .def("cwiseMin", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseMin(m2); })
+        .def("cwiseMax", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseMax(m2); })
+        .def("cwiseMin", [](const Type &m1, Scalar s) -> Type { return m1.cwiseMin(s); })
+        .def("cwiseMax", [](const Type &m1, Scalar s) -> Type { return m1.cwiseMax(s); })
+        .def("cwiseProduct", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseProduct(m2); })
+        .def("cwiseQuotient", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseQuotient(m2); })
+
+        /* Row and column-wise operations */
+        .def("rowwiseSum", [](const Type &m) {return Type(m.rowwise().sum());} )
+        .def("rowwiseProd", [](const Type &m) {return Type(m.rowwise().prod());} )
+        .def("rowwiseMean", [](const Type &m) {return Type(m.rowwise().mean());} )
+        .def("rowwiseNorm", [](const Type &m) {return Type(m.rowwise().norm());} )
+        .def("rowwiseMinCoeff", [](const Type &m) {return Type(m.rowwise().minCoeff());} )
+        .def("rowwiseMaxCoeff", [](const Type &m) {return Type(m.rowwise().maxCoeff());} )
+
+        .def("colwiseSum", [](const Type &m) {return Type(m.colwise().sum());} )
+        .def("colwiseProd", [](const Type &m) {return Type(m.colwise().prod());} )
+        .def("colwiseMean", [](const Type &m) {return Type(m.colwise().mean());} )
+        .def("colwiseNorm", [](const Type &m) {return Type(m.colwise().norm());} )
+        .def("colwiseMinCoeff", [](const Type &m) {return Type(m.colwise().minCoeff());} )
+        .def("colwiseMaxCoeff", [](const Type &m) {return Type(m.colwise().maxCoeff());} )
+
+        /* Arithmetic operators (def_cast forcefully casts the result back to a
+           Type to avoid type issues with Eigen's crazy expression templates) */
+        .def_cast(-py::self)
+        .def_cast(py::self + py::self)
+        .def_cast(py::self - py::self)
+        .def_cast(py::self * py::self)
+        // .def_cast(py::self - Scalar())
+        // .def_cast(py::self * Scalar())
+        // .def_cast(py::self / Scalar())
+
+        .def("__mul__", []
+        (const Type &a, const Scalar& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(a * b);
+        })
+        .def("__rmul__", [](const Type& a, const Scalar& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(b * a);
+        })
+
+        .def("__add__", []
+        (const Type &a, const Scalar& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(a.array() + b);
+        })
+        .def("__radd__", [](const Type& a, const Scalar& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(b + a.array());
+        })
+
+        .def("__sub__", []
+        (const Type &a, const Scalar& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(a.array() - b);
+        })
+        .def("__rsub__", [](const Type& a, const Scalar& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(b - a.array());
+        })
+
+        .def("__div__", []
+        (const Type &a, const Scalar& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(a / b);
+        })
+
+        .def("__truediv__", []
+        (const Type &a, const Scalar& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(a / b);
+        })
+
+        /* Arithmetic in-place operators */
+        .def_cast(py::self += py::self)
+        .def_cast(py::self -= py::self)
+        .def_cast(py::self *= py::self)
+        // .def_cast(py::self *= Scalar())
+        // .def_cast(py::self /= Scalar())
+
+        /* Comparison operators */
+        .def(py::self == py::self)
+        .def(py::self != py::self)
+
+        .def("transposeInPlace", [](Type &m) { m.transposeInPlace(); })
+        /* Other transformations */
+        .def("transpose", [](Type &m) -> Type { return m.transpose(); })
+        /* Python protocol implementations */
+        .def("__repr__", [](const Type &v) {
+            std::ostringstream oss;
+            oss << v;
+            return oss.str();
+        })
+        .def("__getitem__", [](const Type &m, std::pair<size_t, size_t> i) {
+            if (i.first >= (size_t) m.rows() || i.second >= (size_t) m.cols())
+                throw py::index_error();
+            return m(i.first, i.second);
+         })
+        .def("__setitem__", [](Type &m, std::pair<size_t, size_t> i, Scalar v) {
+            if (i.first >= (size_t) m.rows() || i.second >= (size_t) m.cols())
+                throw py::index_error();
+            m(i.first, i.second) = v;
+         })
+
+        /* Buffer access for interacting with NumPy */
+        .def_buffer([](Type &m) -> py::buffer_info {
+            return py::buffer_info(
+                m.data(),                /* Pointer to buffer */
+                sizeof(Scalar),          /* Size of one scalar */
+                /* Python struct-style format descriptor */
+                py::format_descriptor<Scalar>::value(),
+                2,                       /* Number of dimensions */
+                { (size_t) m.rows(),     /* Buffer dimensions */
+                  (size_t) m.cols() },
+                { sizeof(Scalar),        /* Strides (in bytes) for each index */
+                  sizeof(Scalar) * m.rows() }
+            );
+         })
+
+        /* Static initializers */
+        .def_static("Zero", [](size_t n, size_t m) { return Type(Type::Zero(n, m)); })
+        .def_static("Ones", [](size_t n, size_t m) { return Type(Type::Ones(n, m)); })
+        .def_static("Constant", [](size_t n, size_t m, Scalar value) { return Type(Type::Constant(n, m, value)); })
+        .def_static("Identity", [](size_t n, size_t m) { return Type(Type::Identity(n, m)); })
+        .def("MapMatrix", [](const Type& m, size_t r, size_t c)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(Eigen::Map<const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>>(m.data(),r,c));
+        })
+        ;
+    return matrix;
+}
+
+/// Creates Python bindings for a dynamic Eigen sparse order-2 tensor (i.e. a matrix)
+template <typename Type>
+py::class_<Type> bind_eigen_sparse_2(py::module &m, const char *name,
+                                py::object parent = py::object()) {
+    typedef typename Type::Scalar Scalar;
+
+    /* Many Eigen functions are templated and can't easily be referenced using
+       a function pointer, thus a big portion of the binding code below
+       instantiates Eigen code using small anonymous wrapper functions */
+    py::class_<Type> matrix(m, name, parent);
+
+    matrix
+        /* Constructors */
+        .def(py::init<>())
+        .def(py::init<size_t, size_t>())
+        // .def("__init__", [](Type &m, Scalar f) {
+        //     new (&m) Type(1, 1);
+        //     m(0, 0) = f;
+        // })
+        // .def("__init__", [](Type &m, py::buffer b) {
+        //     py::buffer_info info = b.request();
+        //     if (info.format != py::format_descriptor<Scalar>::value())
+        //         throw std::runtime_error("Incompatible buffer format!");
+        //     if (info.ndim == 1) {
+        //         new (&m) Type(info.shape[0], 1);
+        //         memcpy(m.data(), info.ptr, sizeof(Scalar) * m.size());
+        //     } else if (info.ndim == 2) {
+        //         if (info.strides[0] == sizeof(Scalar)) {
+        //             new (&m) Type(info.shape[0], info.shape[1]);
+        //             memcpy(m.data(), info.ptr, sizeof(Scalar) * m.size());
+        //         } else {
+        //             new (&m) Type(info.shape[1], info.shape[0]);
+        //             memcpy(m.data(), info.ptr, sizeof(Scalar) * m.size());
+        //             m.transposeInPlace();
+        //         }
+        //     } else {
+        //         throw std::runtime_error("Incompatible buffer dimension!");
+        //     }
+        // })
+
+        /* Size query functions */
+        .def("size", [](const Type &m) { return m.size(); })
+        .def("cols", [](const Type &m) { return m.cols(); })
+        .def("rows", [](const Type &m) { return m.rows(); })
+
+        /* Initialization */
+        // .def("setZero", [](Type &m) { m.setZero(); })
+        // .def("setIdentity", [](Type &m) { m.setIdentity(); })
+        // .def("setConstant", [](Type &m, Scalar value) { m.setConstant(value); })
+
+        /* Resizing */
+        // .def("resize", [](Type &m, size_t s0, size_t s1) { m.resize(s0, s1); })
+        // .def("resizeLike", [](Type &m, const Type &m2) { m.resizeLike(m2); })
+        // .def("conservativeResize", [](Type &m, size_t s0, size_t s1) { m.conservativeResize(s0, s1); })
+
+        /* Component-wise operations */
+        // .def("cwiseAbs", &Type::cwiseAbs)
+        // .def("cwiseAbs2", &Type::cwiseAbs2)
+        // .def("cwiseSqrt", &Type::cwiseSqrt)
+        // .def("cwiseInverse", &Type::cwiseInverse)
+        // .def("cwiseMin", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseMin(m2); })
+        // .def("cwiseMax", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseMax(m2); })
+        // .def("cwiseMin", [](const Type &m1, Scalar s) -> Type { return m1.cwiseMin(s); })
+        // .def("cwiseMax", [](const Type &m1, Scalar s) -> Type { return m1.cwiseMax(s); })
+        // .def("cwiseProduct", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseProduct(m2); })
+        // .def("cwiseQuotient", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseQuotient(m2); })
+
+        /* Arithmetic operators (def_cast forcefully casts the result back to a
+           Type to avoid type issues with Eigen's crazy expression templates) */
+        .def_cast(-py::self)
+        .def_cast(py::self + py::self)
+        .def_cast(py::self - py::self)
+        .def_cast(py::self * py::self)
+        .def_cast(py::self * Scalar())
+        // Special case, sparse * dense produces a dense matrix
+        .def("__mul__", []
+        (const Type &a, const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(a * b);
+        })
+        .def("__rmul__", [](const Type& a, const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(b * a);
+        })
+
+        //.def(py::self * Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>())
+//        .def_cast(py::self / Scalar())
+
+        /* Arithmetic in-place operators */
+        // .def_cast(py::self += py::self)
+        // .def_cast(py::self -= py::self)
+        // .def_cast(py::self *= py::self)
+        // .def_cast(py::self *= Scalar())
+        // .def_cast(py::self /= Scalar())
+
+        /* Comparison operators */
+        // .def(py::self == py::self)
+        // .def(py::self != py::self)
+
+        // .def("transposeInPlace", [](Type &m) { m.transposeInPlace(); })
+        // /* Other transformations */
+        // .def("transpose", [](Type &m) -> Type { return m.transpose(); })
+
+        /* Python protocol implementations */
+        .def("__repr__", [](const Type &v) {
+            std::ostringstream oss;
+            oss << v;
+            return oss.str();
+        })
+        // .def("__getitem__", [](const Type &m, std::pair<size_t, size_t> i) {
+        //     if (i.first >= (size_t) m.rows() || i.second >= (size_t) m.cols())
+        //         throw py::index_error();
+        //     return m(i.first, i.second);
+        //  })
+        // .def("__setitem__", [](Type &m, std::pair<size_t, size_t> i, Scalar v) {
+        //     if (i.first >= (size_t) m.rows() || i.second >= (size_t) m.cols())
+        //         throw py::index_error();
+        //     m(i.first, i.second) = v;
+        //  })
+
+        // /* Buffer access for interacting with NumPy */
+        // .def_buffer([](Type &m) -> py::buffer_info {
+        //     return py::buffer_info(
+        //         m.data(),                /* Pointer to buffer */
+        //         sizeof(Scalar),          /* Size of one scalar */
+        //         /* Python struct-style format descriptor */
+        //         py::format_descriptor<Scalar>::value(),
+        //         2,                       /* Number of dimensions */
+        //         { (size_t) m.rows(),     /* Buffer dimensions */
+        //           (size_t) m.cols() },
+        //         { sizeof(Scalar),        /* Strides (in bytes) for each index */
+        //           sizeof(Scalar) * m.rows() }
+        //     );
+        //  })
+
+        /* Static initializers */
+        // .def_static("Zero", [](size_t n, size_t m) { return Type(Type::Zero(n, m)); })
+        // .def_static("Ones", [](size_t n, size_t m) { return Type(Type::Ones(n, m)); })
+        // .def_static("Constant", [](size_t n, size_t m, Scalar value) { return Type(Type::Constant(n, m, value)); })
+        // .def_static("Identity", [](size_t n, size_t m) { return Type(Type::Identity(n, m)); })
+        .def("toCOO",[](const Type& m)
+        {
+          Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> t(m.nonZeros(),3);
+          int count = 0;
+          for (int k=0; k<m.outerSize(); ++k)
+            for (typename Type::InnerIterator it(m,k); it; ++it)
+              t.row(count++) << it.row(), it.col(), it.value();
+          return t;
+        })
+
+        .def("fromCOO",[](Type& m, const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>& t, int rows, int cols)
+        {
+          typedef Eigen::Triplet<Scalar> T;
+          std::vector<T> tripletList;
+          tripletList.reserve(t.rows());
+          for(unsigned i=0;i<t.rows();++i)
+            tripletList.push_back(T(round(t(i,0)),round(t(i,1)),t(i,2)));
+
+          if (rows == -1)
+            rows = t.col(0).maxCoeff()+1;
+
+          if (cols == -1)
+            cols = t.col(1).maxCoeff()+1;
+
+          m.resize(rows,cols);
+          m.setFromTriplets(tripletList.begin(), tripletList.end());
+        }, py::arg("t"), py::arg("rows") = -1, py::arg("cols") = -1)
+
+        ;
+    return matrix;
+}
+
+
+void python_export_vector(py::module &m) {
+
+  py::module me = m.def_submodule(
+    "eigen", "Wrappers for Eigen types");
+
+    /* Bindings for VectorXd */
+    // bind_eigen_1<Eigen::VectorXd> (me, "VectorXd");
+    // py::implicitly_convertible<py::buffer, Eigen::VectorXd>();
+    // py::implicitly_convertible<double, Eigen::VectorXd>();
+
+    /* Bindings for VectorXi */
+    // bind_eigen_1<Eigen::VectorXi> (me, "VectorXi");
+    // py::implicitly_convertible<py::buffer, Eigen::VectorXi>();
+    // py::implicitly_convertible<double, Eigen::VectorXi>();
+
+    /* Bindings for MatrixXd */
+    bind_eigen_2<Eigen::MatrixXd> (me, "MatrixXd");
+    //py::implicitly_convertible<py::buffer, Eigen::MatrixXd>();
+    //py::implicitly_convertible<double, Eigen::MatrixXd>();
+
+    /* Bindings for MatrixXi */
+    bind_eigen_2<Eigen::MatrixXi> (me, "MatrixXi");
+//    py::implicitly_convertible<py::buffer, Eigen::MatrixXi>();
+    //py::implicitly_convertible<double, Eigen::MatrixXi>();
+
+    /* Bindings for MatrixXuc */
+    bind_eigen_2<Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic> > (me, "MatrixXuc");
+    // py::implicitly_convertible<py::buffer, Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic> >();
+    // py::implicitly_convertible<double, Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic> >();
+
+    // /* Bindings for Vector3d */
+    // auto vector3 = bind_eigen_1_3<Eigen::Vector3d>(me, "Vector3d");
+    // vector3
+    //     .def("norm", [](const Eigen::Vector3d &v) { return v.norm(); })
+    //     .def("squaredNorm", [](const Eigen::Vector3d &v) { return v.squaredNorm(); })
+    //     .def("normalize", [](Eigen::Vector3d &v) { v.normalize(); })
+    //     .def("normalized", [](const Eigen::Vector3d &v) -> Eigen::Vector3d { return v.normalized(); })
+    //     .def("dot", [](const Eigen::Vector3d &v1, const Eigen::Vector3d &v2) { return v1.dot(v2); })
+    //     .def("cross", [](const Eigen::Vector3d &v1, const Eigen::Vector3d &v2) -> Eigen::Vector3d { return v1.cross(v2); })
+    //     .def_property("x", [](const Eigen::Vector3d &v) -> double { return v.x(); },
+    //                        [](Eigen::Vector3d &v, double x) { v.x() = x; }, "X coordinate")
+    //     .def_property("y", [](const Eigen::Vector3d &v) -> double { return v.y(); },
+    //                        [](Eigen::Vector3d &v, double y) { v.y() = y; }, "Y coordinate")
+    //     .def_property("z", [](const Eigen::Vector3d &v) -> double { return v.z(); },
+    //                        [](Eigen::Vector3d &v, double z) { v.z() = z; }, "Z coordinate");
+    //
+    // py::implicitly_convertible<py::buffer, Eigen::Vector3d>();
+    // py::implicitly_convertible<double, Eigen::Vector3d>();
+
+    /* Bindings for SparseMatrix<double> */
+    bind_eigen_sparse_2< Eigen::SparseMatrix<double> > (me, "SparseMatrixd");
+
+    /* Bindings for SparseMatrix<int> */
+    bind_eigen_sparse_2< Eigen::SparseMatrix<int> > (me, "SparseMatrixi");
+
+
+
+
+
+
+
+}

+ 61 - 0
python/python.cpp

@@ -0,0 +1,61 @@
+#include "python.h"
+#include <sstream>
+#include <string>
+#include <fstream>
+
+void assert_is_VectorXd(const std::string name, const Eigen::MatrixXd& v)
+{
+  if (v.cols() != 1)
+    throw std::runtime_error(name + " must be a column vector.");
+}
+
+void assert_is_RowVectorXd(const std::string name, const Eigen::MatrixXd& v)
+{
+  if (v.rows() != 1)
+    throw std::runtime_error(name + " must be a row vector.");
+}
+
+void assert_is_Vector3d(const std::string name, const Eigen::MatrixXd& v)
+{
+  if ((v.cols() != 1) || (v.rows() != 3))
+    throw std::runtime_error(name + " must be a column vector with 3 entries.");
+}
+
+void assert_is_RowVector3d(const std::string name, const Eigen::MatrixXd& v)
+{
+  if ((v.cols() != 3) || (v.rows() != 1))
+    throw std::runtime_error(name + " must be a row vector with 3 entries.");
+}
+
+void assert_is_Vector4d(const std::string name, const Eigen::MatrixXd& v)
+{
+  if ((v.cols() != 1) || (v.rows() != 4))
+    throw std::runtime_error(name + " must be a column vector with 4 entries.");
+}
+
+void assert_is_RowVector4d(const std::string name, const Eigen::MatrixXd& v)
+{
+  if ((v.cols() != 4) || (v.rows() != 1))
+    throw std::runtime_error(name + " must be a row vector with 4 entries.");
+}
+
+void assert_is_Matrix4d(const std::string name, const Eigen::MatrixXd& v)
+{
+  if ((v.cols() != 4) || (v.rows() != 4))
+    throw std::runtime_error(name + " must be a 4x4 matrix.");
+}
+
+extern void python_export_vector(py::module &);
+extern void python_export_igl(py::module &);
+extern void python_export_igl_viewer(py::module &);
+
+PYTHON_PLUGIN(igl) {
+    py::init_threading();
+    py::module m("igl", "Python wrappers for libigl");
+
+    python_export_vector(m);
+    python_export_igl(m);
+    python_export_igl_viewer(m);
+
+    return m.ptr();
+}

+ 23 - 0
python/python.h

@@ -0,0 +1,23 @@
+#pragma once
+
+#include <pybind/pybind.h>
+#include <pybind/operators.h>
+#include <pybind/complex.h>
+#include <pybind/numpy.h>
+#include <pybind/stl.h>
+#include <pybind/functional.h>
+
+#include "py_doc.h"
+
+#include <Eigen/Dense>
+
+void assert_is_VectorXd(const std::string name, const Eigen::MatrixXd& v);
+void assert_is_RowVectorXd(const std::string name, const Eigen::MatrixXd& v);
+void assert_is_Vector3d(const std::string name, const Eigen::MatrixXd& v);
+void assert_is_RowVector3d(const std::string name, const Eigen::MatrixXd& v);
+void assert_is_Vector4d(const std::string name, const Eigen::MatrixXd& v);
+void assert_is_RowVector4d(const std::string name, const Eigen::MatrixXd& v);
+void assert_is_Matrix4d(const std::string name, const Eigen::MatrixXd& v);
+
+
+namespace py = pybind;