Explorar o código

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

Conflicts:
	include/igl/colon.cpp
	include/igl/slice.cpp

Former-commit-id: 02775f110a14a57b58b4759f18b721597e6f0eb4
Olga Diamanti %!s(int64=9) %!d(string=hai) anos
pai
achega
547f858b3a
Modificáronse 42 ficheiros con 1615 adicións e 938 borrados
  1. 1 1
      include/igl/avg_edge_length.h
  2. 1 1
      include/igl/circulation.cpp
  3. 2 2
      include/igl/collapse_edge.cpp
  4. 1 0
      include/igl/colon.cpp
  5. 1 1
      include/igl/comb_frame_field.h
  6. 1 1
      include/igl/copyleft/comiso/miq.h
  7. 1 1
      include/igl/copyleft/comiso/nrosy.h
  8. 4 2
      include/igl/copyleft/progressive_hulls.cpp
  9. 3 1
      include/igl/copyleft/progressive_hulls.h
  10. 11 4
      include/igl/decimate.cpp
  11. 5 2
      include/igl/decimate.h
  12. 108 0
      include/igl/infinite_cost_stopping_condition.cpp
  13. 85 0
      include/igl/infinite_cost_stopping_condition.h
  14. 1 1
      include/igl/jet.cpp
  15. 1 1
      include/igl/local_basis.h
  16. 1 1
      include/igl/map_vertices_to_circle.h
  17. 1 0
      include/igl/min_quad_with_fixed.cpp
  18. 5 1
      include/igl/parula.cpp
  19. 1 0
      include/igl/per_vertex_normals.cpp
  20. 3 4
      include/igl/principal_curvature.h
  21. 25 13
      include/igl/readOBJ.cpp
  22. 103 0
      include/igl/simplify_polyhedron.cpp
  23. 37 0
      include/igl/simplify_polyhedron.h
  24. 1 0
      include/igl/slice.cpp
  25. 115 4
      include/igl/sort.cpp
  26. 9 0
      include/igl/sort.h
  27. 56 0
      include/igl/viewer/Viewer.cpp
  28. 18 0
      include/igl/viewer/Viewer.h
  29. 15 2
      python/CMakeLists.txt
  30. 632 409
      python/py_doc.cpp
  31. 44 400
      python/py_doc.h
  32. 2 2
      python/py_igl/copyleft/comiso/py_miq.cpp
  33. 2 2
      python/py_igl/copyleft/comiso/py_nrosy.cpp
  34. 2 2
      python/py_igl/py_arap.cpp
  35. 2 2
      python/py_igl/py_doublearea.cpp
  36. 11 3
      python/python_shared.cpp
  37. 7 7
      python/python_shared.h
  38. 126 0
      python/scripts/generate_docstrings.py
  39. 0 68
      python/scripts/mk_py_doc.py
  40. 123 0
      python/scripts/parser.py
  41. 46 0
      python/scripts/python_shared.mako
  42. 2 0
      shared/cmake/CMakeLists.txt

+ 1 - 1
include/igl/avg_edge_length.h

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

+ 1 - 1
include/igl/circulation.cpp

@@ -44,8 +44,8 @@ IGL_INLINE std::vector<int> igl::circulation(
   int ei = e;
   while(true)
   {
-    N.push_back(fi);
     step(ei,fi,ei,fi);
+    N.push_back(fi);
     // back to start?
     if(fi == f0)
     {

+ 2 - 2
include/igl/collapse_edge.cpp

@@ -111,8 +111,8 @@ IGL_INLINE bool igl::collapse_edge(
   // finally, reindex faces and edges incident on d. Do this last so asserts
   // make sense.
   //
-  // Could actually skip first two, since those are always the two collpased
-  // faces.
+  // Could actually skip first and last, since those are always the two
+  // collpased faces.
   for(auto f : nV2Fd)
   {
     for(int v = 0;v<3;v++)

+ 1 - 0
include/igl/colon.cpp

@@ -55,6 +55,7 @@ template void igl::colon<int,long long int,int>(int,long long int,Eigen::Matrix<
 template void igl::colon<int, int, int, int>(int, int, int, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
 template void igl::colon<int, long, long>(int, long, Eigen::Matrix<long, -1, 1, 0, -1, 1>&);
 template void igl::colon<int, double, double, double>(int, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
+template void igl::colon<double, double, double>(double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
 #ifdef WIN32
 template void igl::colon<int, long long,long>(int, long long, class Eigen::Matrix<long,-1,1,0,-1,1> &);
 #endif

+ 1 - 1
include/igl/comb_frame_field.h

@@ -8,7 +8,7 @@
 
 #ifndef IGL_COMB_FRAME_FIELD_H
 #define IGL_COMB_FRAME_FIELD_H
-#include <igl/igl_inline.h>
+#include "igl_inline.h"
 #include <Eigen/Core>
 namespace igl
 {

+ 1 - 1
include/igl/copyleft/comiso/miq.h

@@ -7,7 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_COMISO_MIQ_H
 #define IGL_COMISO_MIQ_H
-#include <igl/igl_inline.h>
+#include "../../igl_inline.h"
 #include <Eigen/Core>
 #include <vector>
 

+ 1 - 1
include/igl/copyleft/comiso/nrosy.h

@@ -12,7 +12,7 @@
 #include <Eigen/Core>
 #include <Eigen/Sparse>
 #include <vector>
-#include <igl/igl_inline.h>
+#include "../../igl_inline.h"
 
 namespace igl
 {

+ 4 - 2
include/igl/copyleft/progressive_hulls.cpp

@@ -14,7 +14,8 @@ IGL_INLINE bool igl::copyleft::progressive_hulls(
   const Eigen::MatrixXi & F,
   const size_t max_m,
   Eigen::MatrixXd & U,
-  Eigen::MatrixXi & G)
+  Eigen::MatrixXi & G,
+  Eigen::VectorXi & J)
 {
   int m = F.rows();
   return decimate(
@@ -23,5 +24,6 @@ IGL_INLINE bool igl::copyleft::progressive_hulls(
     progressive_hulls_cost_and_placement,
     max_faces_stopping_condition(m,max_m),
     U,
-    G);
+    G,
+    J);
 }

+ 3 - 1
include/igl/copyleft/progressive_hulls.h

@@ -26,13 +26,15 @@ namespace igl
     // Outputs:
     //   U  #U by dim list of output vertex posistions (can be same ref as V)
     //   G  #G by 3 list of output face indices into U (can be same ref as G)
+    //   J  #G list of indices into F of birth faces
     // Returns true if m was reached (otherwise #G > m)
     IGL_INLINE bool progressive_hulls(
       const Eigen::MatrixXd & V,
       const Eigen::MatrixXi & F,
       const size_t max_m,
       Eigen::MatrixXd & U,
-      Eigen::MatrixXi & G);
+      Eigen::MatrixXi & G,
+      Eigen::VectorXi & J);
   }
 }
 #ifndef IGL_STATIC_LIBRARY

+ 11 - 4
include/igl/decimate.cpp

@@ -17,7 +17,8 @@ IGL_INLINE bool igl::decimate(
   const Eigen::MatrixXi & F,
   const size_t max_m,
   Eigen::MatrixXd & U,
-  Eigen::MatrixXi & G)
+  Eigen::MatrixXi & G,
+  Eigen::VectorXi & J)
 {
   int m = F.rows();
   const auto & shortest_edge_and_midpoint = [](
@@ -40,7 +41,8 @@ IGL_INLINE bool igl::decimate(
     shortest_edge_and_midpoint,
     max_faces_stopping_condition(m,max_m),
     U,
-    G);
+    G,
+    J);
 }
 
 IGL_INLINE bool igl::decimate(
@@ -72,7 +74,8 @@ IGL_INLINE bool igl::decimate(
       const int,
       const int)> & stopping_condition,
   Eigen::MatrixXd & U,
-  Eigen::MatrixXi & G)
+  Eigen::MatrixXi & G,
+  Eigen::VectorXi & J)
 {
   using namespace Eigen;
   using namespace std;
@@ -132,6 +135,7 @@ IGL_INLINE bool igl::decimate(
   }
   // remove all IGL_COLLAPSE_EDGE_NULL faces
   MatrixXi F2(F.rows(),3);
+  J.resize(F.rows());
   int m = 0;
   for(int f = 0;f<F.rows();f++)
   {
@@ -140,10 +144,13 @@ IGL_INLINE bool igl::decimate(
       F(f,1) != IGL_COLLAPSE_EDGE_NULL || 
       F(f,2) != IGL_COLLAPSE_EDGE_NULL)
     {
-      F2.row(m++) = F.row(f);
+      F2.row(m) = F.row(f);
+      J(m) = f;
+      m++;
     }
   }
   F2.conservativeResize(m,F2.cols());
+  J.conservativeResize(m);
   VectorXi _1;
   remove_unreferenced(V,F2,U,G,_1);
   return clean_finish;

+ 5 - 2
include/igl/decimate.h

@@ -25,13 +25,15 @@ namespace igl
   // Outputs:
   //   U  #U by dim list of output vertex posistions (can be same ref as V)
   //   G  #G by 3 list of output face indices into U (can be same ref as G)
+  //   J  #G list of indices into F of birth face
   // Returns true if m was reached (otherwise #G > m)
   IGL_INLINE bool decimate(
     const Eigen::MatrixXd & V,
     const Eigen::MatrixXi & F,
     const size_t max_m,
     Eigen::MatrixXd & U,
-    Eigen::MatrixXi & G);
+    Eigen::MatrixXi & G,
+    Eigen::VectorXi & J);
   // Inputs:
   //   cost_and_placement  function computing cost of collapsing an edge and 3d
   //     position where it should be placed:
@@ -70,7 +72,8 @@ namespace igl
       const int,
       const int)> & stopping_condition,
     Eigen::MatrixXd & U,
-    Eigen::MatrixXi & G);
+    Eigen::MatrixXi & G,
+    Eigen::VectorXi & J);
 
 }
 

+ 108 - 0
include/igl/infinite_cost_stopping_condition.cpp

@@ -0,0 +1,108 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "infinite_cost_stopping_condition.h"
+
+IGL_INLINE void igl::infinite_cost_stopping_condition(
+  const std::function<void(
+    const int,
+    const Eigen::MatrixXd &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::VectorXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    double &,
+    Eigen::RowVectorXd &)> & cost_and_placement,
+  std::function<bool(
+    const Eigen::MatrixXd &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::VectorXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    const std::set<std::pair<double,int> > &,
+    const std::vector<std::set<std::pair<double,int> >::iterator > &,
+    const Eigen::MatrixXd &,
+    const int,
+    const int,
+    const int,
+    const int,
+    const int)> & stopping_condition)
+{
+  stopping_condition = 
+    [&cost_and_placement]
+    (
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXi & E,
+    const Eigen::VectorXi & EMAP,
+    const Eigen::MatrixXi & EF,
+    const Eigen::MatrixXi & EI,
+    const std::set<std::pair<double,int> > & Q,
+    const std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
+    const Eigen::MatrixXd & C,
+    const int e,
+    const int /*e1*/,
+    const int /*e2*/,
+    const int /*f1*/,
+    const int /*f2*/)->bool
+    {
+      Eigen::RowVectorXd p;
+      double cost;
+      cost_and_placement(e,V,F,E,EMAP,EF,EI,cost,p);
+      return isinf(cost);
+    };
+}
+
+IGL_INLINE 
+  std::function<bool(
+    const Eigen::MatrixXd &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::VectorXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    const std::set<std::pair<double,int> > &,
+    const std::vector<std::set<std::pair<double,int> >::iterator > &,
+    const Eigen::MatrixXd &,
+    const int,
+    const int,
+    const int,
+    const int,
+    const int)> 
+  igl::infinite_cost_stopping_condition(
+    const std::function<void(
+      const int,
+      const Eigen::MatrixXd &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::VectorXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      double &,
+      Eigen::RowVectorXd &)> & cost_and_placement)
+{
+  std::function<bool(
+    const Eigen::MatrixXd &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::VectorXi &,
+    const Eigen::MatrixXi &,
+    const Eigen::MatrixXi &,
+    const std::set<std::pair<double,int> > &,
+    const std::vector<std::set<std::pair<double,int> >::iterator > &,
+    const Eigen::MatrixXd &,
+    const int,
+    const int,
+    const int,
+    const int,
+    const int)> stopping_condition;
+  infinite_cost_stopping_condition(cost_and_placement,stopping_condition);
+  return stopping_condition;
+}
+

+ 85 - 0
include/igl/infinite_cost_stopping_condition.h

@@ -0,0 +1,85 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_INFINITE_COST_STOPPING_CONDITION_H
+#define IGL_INFINITE_COST_STOPPING_CONDITION_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+#include <set>
+#include <functional>
+namespace igl
+{
+  // Stopping condition function compatible with igl::decimate. The output
+  // function handle will return true if cost of next edge is infinite.
+  //
+  // Inputs:
+  //   cost_and_placement  handle being used by igl::collapse_edge
+  // Outputs:
+  //   stopping_condition
+  //
+  IGL_INLINE void infinite_cost_stopping_condition(
+    const std::function<void(
+      const int,
+      const Eigen::MatrixXd &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::VectorXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      double &,
+      Eigen::RowVectorXd &)> & cost_and_placement,
+    std::function<bool(
+      const Eigen::MatrixXd &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::VectorXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      const std::set<std::pair<double,int> > &,
+      const std::vector<std::set<std::pair<double,int> >::iterator > &,
+      const Eigen::MatrixXd &,
+      const int,
+      const int,
+      const int,
+      const int,
+      const int)> & stopping_condition);
+  IGL_INLINE 
+    std::function<bool(
+      const Eigen::MatrixXd &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::VectorXi &,
+      const Eigen::MatrixXi &,
+      const Eigen::MatrixXi &,
+      const std::set<std::pair<double,int> > &,
+      const std::vector<std::set<std::pair<double,int> >::iterator > &,
+      const Eigen::MatrixXd &,
+      const int,
+      const int,
+      const int,
+      const int,
+      const int)> 
+    infinite_cost_stopping_condition(
+      const std::function<void(
+        const int,
+        const Eigen::MatrixXd &,
+        const Eigen::MatrixXi &,
+        const Eigen::MatrixXi &,
+        const Eigen::VectorXi &,
+        const Eigen::MatrixXi &,
+        const Eigen::MatrixXi &,
+        double &,
+        Eigen::RowVectorXd &)> & cost_and_placement);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "infinite_cost_stopping_condition.cpp"
+#endif
+#endif
+
+

+ 1 - 1
include/igl/jet.cpp

@@ -137,5 +137,5 @@ template void igl::jet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<d
 template void igl::jet<float>(float, float&, float&, float&);
 template void igl::jet<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::jet<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-
+template void igl::jet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, double, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 1 - 1
include/igl/local_basis.h

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

+ 1 - 1
include/igl/map_vertices_to_circle.h

@@ -7,7 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_MAP_VERTICES_TO_CIRCLE_H
 #define IGL_MAP_VERTICES_TO_CIRCLE_H
-#include <igl/igl_inline.h>
+#include "igl_inline.h"
 
 #include <Eigen/Dense>
 #include <vector>

+ 1 - 0
include/igl/min_quad_with_fixed.cpp

@@ -575,4 +575,5 @@ template bool igl::min_quad_with_fixed_solve<double, Eigen::Matrix<double, -1, 1
 template bool igl::min_quad_with_fixed<double, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template bool igl::min_quad_with_fixed<double, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template bool igl::min_quad_with_fixed_solve<double, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::min_quad_with_fixed_data<double> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template bool igl::min_quad_with_fixed_solve<double, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::min_quad_with_fixed_data<double> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 5 - 1
include/igl/parula.cpp

@@ -53,14 +53,18 @@ IGL_INLINE void igl::parula(
   Eigen::PlainObjectBase<DerivedC> & C)
 {
   C.resize(Z.rows(),3);
+  double denom = (max_z-min_z);
+  denom = denom==0?1:denom;
   for(int r = 0;r<Z.rows();r++)
   {
-    parula((-min_z+Z(r,0))/(max_z-min_z),C(r,0),C(r,1),C(r,2));
+    parula((-min_z+Z(r,0))/denom,C(r,0),C(r,1),C(r,2));
   }
 }
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
+// generated by autoexplicit.sh
+template void igl::parula<Eigen::Array<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Array<int, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::parula<double>(double, double*);
 template void igl::parula<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::parula<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);

+ 1 - 0
include/igl/per_vertex_normals.cpp

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

+ 3 - 4
include/igl/principal_curvature.h

@@ -12,9 +12,9 @@
 #include <Eigen/Geometry>
 #include <Eigen/Dense>
 
-#include <igl/igl_inline.h>
-#include <igl/cotmatrix.h>
-#include <igl/writeOFF.h>
+#include "igl_inline.h"
+//#include <igl/cotmatrix.h>
+//#include <igl/writeOFF.h>
 
 
 
@@ -42,7 +42,6 @@ namespace igl
   // Efficient Multi-scale Curvature and Crease Estimation
   // Daniele Panozzo, Enrico Puppo, Luigi Rocca
   // GraVisMa, 2010
-
 template <
   typename DerivedV, 
   typename DerivedF,

+ 25 - 13
include/igl/readOBJ.cpp

@@ -122,6 +122,18 @@ IGL_INLINE bool igl::readOBJ(
         TC.push_back(tex);
       }else if(type == f)
       {
+        const auto & shift = [&V](const int i)->int
+        {
+          return i<0 ? i+V.size() : i-1;
+        };
+        const auto & shift_t = [&TC](const int i)->int
+        {
+          return i<0 ? i+TC.size() : i-1;
+        };
+        const auto & shift_n = [&N](const int i)->int
+        {
+          return i<0 ? i+N.size() : i-1;
+        };
         std::vector<Index > f;
         std::vector<Index > ftc;
         std::vector<Index > fn;
@@ -133,23 +145,23 @@ IGL_INLINE bool igl::readOBJ(
           // adjust offset
           l += offset;
           // Process word
-          unsigned int i,it,in;
-          if(sscanf(word,"%u/%u/%u",&i,&it,&in) == 3)
+          long int i,it,in;
+          if(sscanf(word,"%ld/%ld/%ld",&i,&it,&in) == 3)
           {
-            f.push_back(i-1);
-            ftc.push_back(it-1);
-            fn.push_back(in-1);
-          }else if(sscanf(word,"%u/%u",&i,&it) == 2)
+            f.push_back(shift(i));
+            ftc.push_back(shift_t(it));
+            fn.push_back(shift_n(in));
+          }else if(sscanf(word,"%ld/%ld",&i,&it) == 2)
           {
-            f.push_back(i-1);
-            ftc.push_back(it-1);
-          }else if(sscanf(word,"%u//%u",&i,&in) == 2)
+            f.push_back(shift(i));
+            ftc.push_back(shift_t(it));
+          }else if(sscanf(word,"%ld//%ld",&i,&in) == 2)
           {
-            f.push_back(i-1);
-            fn.push_back(in-1);
-          }else if(sscanf(word,"%u",&i) == 1)
+            f.push_back(shift(i));
+            fn.push_back(shift_n(in));
+          }else if(sscanf(word,"%ld",&i) == 1)
           {
-            f.push_back(i-1);
+            f.push_back(shift(i));
           }else
           {
             fprintf(stderr,

+ 103 - 0
include/igl/simplify_polyhedron.cpp

@@ -0,0 +1,103 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "simplify_polyhedron.h"
+#include "decimate.h"
+#include "circulation.h"
+#include "per_face_normals.h"
+#include "infinite_cost_stopping_condition.h"
+#include <functional>
+
+IGL_INLINE void igl::simplify_polyhedron(
+  const Eigen::MatrixXd & OV,
+  const Eigen::MatrixXi & OF,
+  Eigen::MatrixXd & V,
+  Eigen::MatrixXi & F,
+  Eigen::VectorXi & J)
+{
+  // TODO: to generalize to open meshes, 0-cost should keep all incident
+  // boundary edges on their original lines. (for non-manifold meshes,
+  // igl::decimate needs to be generalized)
+
+  Eigen::MatrixXd N;
+  // Function for computing cost of collapsing edge (0 if at least one
+  // direction doesn't change pointset, inf otherwise) and placement (in lowest
+  // cost direction).
+  const auto & perfect= [&N](
+    const int e,
+    const Eigen::MatrixXd & V,
+    const Eigen::MatrixXi & F,
+    const Eigen::MatrixXi & E,
+    const Eigen::VectorXi & EMAP,
+    const Eigen::MatrixXi & EF,
+    const Eigen::MatrixXi & EI,
+    double & cost,
+    Eigen::RowVectorXd & p)
+  {
+    // Function for ocmputing cost (0 or inf) of collapsing edge by placing
+    // vertex at `positive` end of edge.
+    const auto & perfect_directed = [&N](
+      const int e,
+      const bool positive,
+      const Eigen::MatrixXd & V,
+      const Eigen::MatrixXi & F,
+      const Eigen::MatrixXi & E,
+      const Eigen::VectorXi & EMAP,
+      const Eigen::MatrixXi & EF,
+      const Eigen::MatrixXi & EI,
+      double & cost,
+      Eigen::RowVectorXd & p)
+    {
+      const auto vi = E(e,positive);
+      const auto vj = E(e,!positive);
+      p = V.row(vj);
+      std::vector<int> faces = igl::circulation(e,positive,F,E,EMAP,EF,EI);
+      cost = 0;
+      for(auto f : faces)
+      {
+        // Skip the faces being collapsed
+        if(f == EF(e,0) || f == EF(e,1))
+        {
+          continue;
+        }
+        const Eigen::RowVectorXd nbefore = N.row(f);
+        // Face with vi replaced with vj
+        const Eigen::RowVector3i fafter(
+            F(f,0) == vi ? vj : F(f,0),
+            F(f,1) == vi ? vj : F(f,1),
+            F(f,2) == vi ? vj : F(f,2));
+        Eigen::RowVectorXd nafter;
+        igl::per_face_normals(V,fafter,nafter);
+        const double epsilon = 1e-10;
+        // if normal changed then not feasible, break
+        if((nbefore-nafter).norm() > epsilon)
+        {
+          cost = std::numeric_limits<double>::infinity();
+          break;
+        }
+      }
+    }; 
+    p.resize(3);
+    double cost0, cost1;
+    Eigen::RowVectorXd p0, p1;
+    perfect_directed(e,false,V,F,E,EMAP,EF,EI,cost0,p0);
+    perfect_directed(e,true,V,F,E,EMAP,EF,EI,cost1,p1);
+    if(cost0 < cost1)
+    {
+      cost = cost0;
+      p = p0;
+    }else
+    {
+      cost = cost1;
+      p = p1;
+    }
+  };
+  igl::per_face_normals(OV,OF,N);
+  igl::decimate(
+    OV,OF,perfect,igl::infinite_cost_stopping_condition(perfect),V,F,J);
+}
+

+ 37 - 0
include/igl/simplify_polyhedron.h

@@ -0,0 +1,37 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_SIMPLIFY_POLYHEDRON_H
+#define IGL_SIMPLIFY_POLYHEDRON_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  // Simplify a polyhedron represented as a triangle mesh (OV,OF) by collapsing
+  // any edge that doesn't contribute to defining surface's pointset. This
+  // _would_ also make sense for open and non-manifold meshes, but the current
+  // implementation only works with closed manifold surfaces with well defined
+  // triangle normals.
+  //
+  // Inputs:
+  //   OV  #OV by 3 list of input mesh vertex positions
+  //   OF  #OF by 3 list of input mesh triangle indices into OV
+  // Outputs:
+  //   V  #V by 3 list of output mesh vertex positions
+  //   F  #F by 3 list of input mesh triangle indices into V
+  //   J  #F list of indices into OF of birth parents
+  IGL_INLINE void simplify_polyhedron(
+    const Eigen::MatrixXd & OV,
+    const Eigen::MatrixXi & OF,
+    Eigen::MatrixXd & V,
+    Eigen::MatrixXi & F,
+    Eigen::VectorXi & J);
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "simplify_polyhedron.cpp"
+#endif
+#endif

+ 1 - 0
include/igl/slice.cpp

@@ -281,4 +281,5 @@ template void igl::slice<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix
 template void igl::slice<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
 template void igl::slice<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::Matrix<int, -1, -1, 0, -1, -1>&);
 template void igl::slice<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
+template void igl::slice<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 115 - 4
include/igl/sort.cpp

@@ -15,6 +15,8 @@
 #include <cassert>
 #include <algorithm>
 #include <iostream>
+#include <thread>
+#include <functional>
 
 template <typename DerivedX, typename DerivedY, typename DerivedIX>
 IGL_INLINE void igl::sort(
@@ -27,9 +29,14 @@ IGL_INLINE void igl::sort(
   // get number of rows (or columns)
   int num_inner = (dim == 1 ? X.rows() : X.cols() );
   // Special case for swapping
-  if(num_inner == 2)
+  switch(num_inner)
   {
-    return igl::sort2(X,dim,ascending,Y,IX);
+    default:
+      break;
+    case 2:
+      return igl::sort2(X,dim,ascending,Y,IX);
+    case 3:
+      return igl::sort3(X,dim,ascending,Y,IX);
   }
   using namespace Eigen;
   // get number of columns (or rows)
@@ -85,9 +92,14 @@ IGL_INLINE void igl::sort_new(
   // get number of rows (or columns)
   int num_inner = (dim == 1 ? X.rows() : X.cols() );
   // Special case for swapping
-  if(num_inner == 2)
+  switch(num_inner)
   {
-    return igl::sort2(X,dim,ascending,Y,IX);
+    default:
+      break;
+    case 2:
+      return igl::sort2(X,dim,ascending,Y,IX);
+    case 3:
+      return igl::sort3(X,dim,ascending,Y,IX);
   }
   using namespace Eigen;
   // get number of columns (or rows)
@@ -180,6 +192,105 @@ IGL_INLINE void igl::sort2(
   }
 }
 
+template <typename DerivedX, typename DerivedY, typename DerivedIX>
+IGL_INLINE void igl::sort3(
+  const Eigen::PlainObjectBase<DerivedX>& X,
+  const int dim,
+  const bool ascending,
+  Eigen::PlainObjectBase<DerivedY>& Y,
+  Eigen::PlainObjectBase<DerivedIX>& IX)
+{
+  using namespace Eigen;
+  using namespace std;
+  typedef typename Eigen::PlainObjectBase<DerivedY>::Scalar YScalar;
+  Y = X.template cast<YScalar>();
+  // get number of columns (or rows)
+  int num_outer = (dim == 1 ? X.cols() : X.rows() );
+  // get number of rows (or columns)
+  int num_inner = (dim == 1 ? X.rows() : X.cols() );
+  assert(num_inner == 3);(void)num_inner;
+  typedef typename Eigen::PlainObjectBase<DerivedIX>::Scalar Index;
+  IX.resize(X.rows(),X.cols());
+  if(dim==1)
+  {
+    IX.row(0).setConstant(0);// = Eigen::PlainObjectBase<DerivedIX>::Zero(1,IX.cols());
+    IX.row(1).setConstant(1);// = Eigen::PlainObjectBase<DerivedIX>::Ones (1,IX.cols());
+    IX.row(2).setConstant(2);// = Eigen::PlainObjectBase<DerivedIX>::Ones (1,IX.cols());
+  }else
+  {
+    IX.col(0).setConstant(0);// = Eigen::PlainObjectBase<DerivedIX>::Zero(IX.rows(),1);
+    IX.col(1).setConstant(1);// = Eigen::PlainObjectBase<DerivedIX>::Ones (IX.rows(),1);
+    IX.col(2).setConstant(2);// = Eigen::PlainObjectBase<DerivedIX>::Ones (IX.rows(),1);
+  }
+
+  const int n = num_outer;
+  const size_t nthreads = n<8000?1:std::thread::hardware_concurrency();
+  {
+    std::vector<std::thread> threads(nthreads);
+    for(int t = 0;t<nthreads;t++)
+    {
+      threads[t] = std::thread(std::bind(
+        [&X,&Y,&IX,&dim,&ascending](const int bi, const int ei, const int t)
+      {
+        // loop over columns (or rows)
+        for(int i = bi;i<ei;i++)
+        {
+          YScalar & a = (dim==1 ? Y(0,i) : Y(i,0));
+          YScalar & b = (dim==1 ? Y(1,i) : Y(i,1));
+          YScalar & c = (dim==1 ? Y(2,i) : Y(i,2));
+          Index & ai = (dim==1 ? IX(0,i) : IX(i,0));
+          Index & bi = (dim==1 ? IX(1,i) : IX(i,1));
+          Index & ci = (dim==1 ? IX(2,i) : IX(i,2));
+          if(ascending)
+          {
+            // 123 132 213 231 312 321
+            if(a > b)
+            {
+              std::swap(a,b);
+              std::swap(ai,bi);
+            }
+            // 123 132 123 231 132 231
+            if(b > c)
+            {
+              std::swap(b,c);
+              std::swap(bi,ci);
+              // 123 123 123 213 123 213
+              if(a > b)
+              {
+                std::swap(a,b);
+                std::swap(ai,bi);
+              }
+              // 123 123 123 123 123 123
+            }
+          }else
+          {
+            // 123 132 213 231 312 321
+            if(a < b)
+            {
+              std::swap(a,b);
+              std::swap(ai,bi);
+            }
+            // 213 312 213 321 312 321
+            if(b < c)
+            {
+              std::swap(b,c);
+              std::swap(bi,ci);
+              // 231 321 231 321 321 321
+              if(a < b)
+              {
+                std::swap(a,b);
+                std::swap(ai,bi);
+              }
+              // 321 321 321 321 321 321
+            }
+          }
+        }
+      }, t*n/nthreads, (t+1)==nthreads?n:(t+1)*n/nthreads,t));
+    }
+    std::for_each(threads.begin(),threads.end(),[](std::thread& x){x.join();});
+  }
+}
+
 template <class T>
 IGL_INLINE void igl::sort(
   const std::vector<T> & unsorted,

+ 9 - 0
include/igl/sort.h

@@ -53,6 +53,15 @@ namespace igl
     const bool ascending,
     Eigen::PlainObjectBase<DerivedY>& Y,
     Eigen::PlainObjectBase<DerivedIX>& IX);
+  // Special case if size(X,dim) == 3
+  template <typename DerivedX, typename DerivedY, typename DerivedIX>
+  IGL_INLINE void sort3(
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const int dim,
+    const bool ascending,
+    Eigen::PlainObjectBase<DerivedY>& Y,
+    Eigen::PlainObjectBase<DerivedIX>& IX);
+
 
   // Act like matlab's [Y,I] = SORT(X) for std library vectors
   // Templates:

+ 56 - 0
include/igl/viewer/Viewer.cpp

@@ -6,6 +6,8 @@
 // v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 
+// Must defined this before including Viewer.h
+#define IGL_VIEWER_VIEWER_CPP
 #include "Viewer.h"
 
 #ifdef _WIN32
@@ -273,6 +275,33 @@ namespace viewer
 
   IGL_INLINE Viewer::Viewer()
   {
+    // This mess is to help debug problems arising when compiling
+    // libiglviewer.a with(without) IGL_STATIC_LIBRARY defined and including
+    // Viewer.h without(with) IGL_STATIC_LIBRARY defined.
+#ifdef IGL_STATIC_LIBRARY
+    std::cout<<"igl_with_nanogui_defined_consistently: "<<igl_with_nanogui_defined_consistently()<<std::endl;
+    std::cout<<"igl_with_nanogui_defined_at_compile: "<<  igl_with_nanogui_defined_at_compile()  <<std::endl;
+    std::cout<<"igl_with_nanogui_defined_at_include: "<<  igl_with_nanogui_defined_at_include()  <<std::endl;
+    // First try to first assert
+    assert(igl_with_nanogui_defined_consistently() && 
+      "Must compile and include with IGL_VIEWER_WITH_NANOGUI defined consistently");
+#ifdef NDEBUG
+    // Second print warning since it's hopeless that this will run if wrong.
+    if(!igl_with_nanogui_defined_consistently())
+    {
+      std::cerr<<
+        "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<std::endl<<std::endl<<
+        "WARNING: Seems that IGL_WITH_NANOGUI " <<
+        (igl_with_nanogui_defined_at_compile() ? "was" : "was not") <<
+        " defined"<<std::endl<<"during compilation of Viewer.cpp and "<<
+        (igl_with_nanogui_defined_at_include() ? "was" : "was not") <<
+        " defined"<<std::endl<<"during inclusion of Viewer.h"<<std::endl <<
+        "You're about to get some nasty memory errors."<<std::endl<<std::endl<<
+        "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"<<std::endl;
+    }
+#endif
+#endif
+
 #ifdef IGL_VIEWER_WITH_NANOGUI
     ngui = nullptr;
     screen = nullptr;
@@ -318,6 +347,10 @@ namespace viewer
   Z       Snap to canonical view
   [,]     Toggle between rotation control types (e.g. trackball, two-axis
           valuator with fixed up)
+#ifdef IGL_VIEWER_WITH_NANOGUI
+  ;       Toggle vertex labels
+  :       Toggle face labels
+#endif
 
 )");
     std::cout<<usage;
@@ -530,6 +563,14 @@ namespace viewer
         }
         return true;
       }
+#ifdef IGL_VIEWER_WITH_NANOGUI
+      case ';':
+        core.show_vertid = !core.show_vertid;
+        return true;
+      case ':':
+        core.show_faceid = !core.show_faceid;
+        return true;
+#endif
       default: break;//do nothing
     }
     return false;
@@ -1003,5 +1044,20 @@ namespace viewer
     launch_shut();
     return EXIT_SUCCESS;
   }
+  IGL_INLINE bool Viewer::igl_with_nanogui_defined_at_compile()
+  {
+#ifdef IGL_VIEWER_WITH_NANOGUI
+    return true;
+#else
+    return false;
+#endif
+  }
+  IGL_INLINE bool Viewer::igl_with_nanogui_defined_consistently()
+  {
+    return 
+      igl_with_nanogui_defined_at_compile() == 
+      igl_with_nanogui_defined_at_include();
+  }
 } // end namespace
 }
+

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

@@ -153,10 +153,28 @@ namespace viewer
     void* callback_key_down_data;
     void* callback_key_up_data;
 
+  public:
+
+    static IGL_INLINE bool igl_with_nanogui_defined_at_compile();
+    static IGL_INLINE bool igl_with_nanogui_defined_consistently();
+
   public:
       EIGEN_MAKE_ALIGNED_OPERATOR_NEW
   };
 
+  bool igl_with_nanogui_defined_at_include();
+#ifndef IGL_VIEWER_VIEWER_CPP
+  bool igl_with_nanogui_defined_at_include()
+  {
+    // this must be inlined here.
+#ifdef IGL_VIEWER_WITH_NANOGUI
+    return true;
+#else
+    return false;
+#endif
+  }
+#endif
+
 } // end namespace
 } // end namespace
 

+ 15 - 2
python/CMakeLists.txt

@@ -139,14 +139,27 @@ elseif (UNIX)
   # .SO file extension on Linux/Mac OS
   set_target_properties(pyigl PROPERTIES SUFFIX ".so")
 
-  # Strip unnecessary sections of the binary on Linux/Mac OS
+  #Enable flag if undefined symbols appear on pyigl module import to get notified about the missing symbols at link time
+  option(CHECK_UNDEFINED        "Check for undefined symbols"    OFF)
+
+  # Strip unnecessary sections of the binary on Linux/Mac OS 
   if(APPLE)
     set_target_properties(pyigl PROPERTIES MACOSX_RPATH ".")
-    set_target_properties(pyigl PROPERTIES LINK_FLAGS "-undefined dynamic_lookup -dead_strip")
+    
+    if (NOT CHECK_UNDEFINED)
+      set_target_properties(pyigl PROPERTIES LINK_FLAGS "-undefined dynamic_lookup -dead_strip")
+    endif()
+
     if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
       add_custom_command(TARGET pyigl POST_BUILD COMMAND strip -u -r ${CMAKE_CURRENT_BINARY_DIR}/../pyigl.so)
     endif()
   else()
+
+    if (CHECK_UNDEFINED)
+      target_link_libraries(pyigl ${PYTHON_LIBRARIES})
+      set_target_properties(pyigl PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
+    endif()
+
     if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
       add_custom_command(TARGET pyigl POST_BUILD COMMAND strip ${CMAKE_CURRENT_BINARY_DIR}/../pyigl.so)
     endif()

+ 632 - 409
python/py_doc.cpp

@@ -1,409 +1,632 @@
-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";
+const char *__doc_igl_principal_curvature = R"igl_Qu8mg5v7(// Compute the principal curvature directions and magnitude of the given triangle mesh
+  //   DerivedV derived from vertex positions matrix type: i.e. MatrixXd
+  //   DerivedF derived from face indices matrix type: i.e. MatrixXi
+  // Inputs:
+  //   V       eigen matrix #V by 3
+  //   F       #F by 3 list of mesh faces (must be triangles)
+  //   radius  controls the size of the neighbourhood used, 1 = average edge lenght
+  //
+  // Outputs:
+  //   PD1 #V by 3 maximal curvature direction for each vertex.
+  //   PD2 #V by 3 minimal curvature direction for each vertex.
+  //   PV1 #V by 1 maximal curvature value for each vertex.
+  //   PV2 #V by 1 minimal curvature value for each vertex.
+  //
+  // See also: average_onto_faces, average_onto_vertices
+  //
+  // This function has been developed by: Nikolas De Giorgis, Luigi Rocca and Enrico Puppo.
+  // The algorithm is based on:
+  // Efficient Multi-scale Curvature and Crease Estimation
+  // Daniele Panozzo, Enrico Puppo, Luigi Rocca
+  // GraVisMa, 2010)igl_Qu8mg5v7";
+const char *__doc_igl_local_basis = R"igl_Qu8mg5v7(// Compute a local orthogonal reference system for each triangle in the given mesh
+  // Templates:
+  //   DerivedV derived from vertex positions matrix type: i.e. MatrixXd
+  //   DerivedF derived from face indices matrix type: i.e. MatrixXi
+  // Inputs:
+  //   V  eigen matrix #V by 3
+  //   F  #F by 3 list of mesh faces (must be triangles)
+  // Outputs:
+  //   B1 eigen matrix #F by 3, each vector is tangent to the triangle
+  //   B2 eigen matrix #F by 3, each vector is tangent to the triangle and perpendicular to B1
+  //   B3 eigen matrix #F by 3, normal of the triangle
+  //
+  // See also: adjacency_matrix)igl_Qu8mg5v7";
+const char *__doc_igl_cotmatrix = R"igl_Qu8mg5v7(// Constructs the cotangent stiffness matrix (discrete laplacian) for a given
+  // mesh (V,F).
+  //
+  // Templates:
+  //   DerivedV  derived type of eigen matrix for V (e.g. derived from
+  //     MatrixXd)
+  //   DerivedF  derived type of eigen matrix for F (e.g. derived from
+  //     MatrixXi)
+  //   Scalar  scalar type for eigen sparse matrix (e.g. double)
+  // Inputs:
+  //   V  #V by dim list of mesh vertex positions
+  //   F  #F by simplex_size list of mesh faces (must be triangles)
+  // Outputs: 
+  //   L  #V by #V cotangent matrix, each row i corresponding to V(i,:)
+  //
+  // See also: adjacency_matrix
+  //
+  // Note: This Laplacian uses the convention that diagonal entries are
+  // **minus** the sum of off-diagonal entries. The diagonal entries are
+  // therefore in general negative and the matrix is **negative** semi-definite
+  // (immediately, -L is **positive** semi-definite)
+  //
+  // Known bugs: off by 1e-16 on regular grid. I think its a problem of
+  // arithmetic order in cotmatrix_entries.h: C(i,e) = (arithmetic)/dblA/4)igl_Qu8mg5v7";
+const char *__doc_igl_floor = R"igl_Qu8mg5v7(// Floor a given matrix to nearest integers 
+  //
+  // Inputs:
+  //   X  m by n matrix of scalars
+  // Outputs:
+  //   Y  m by n matrix of floored integers)igl_Qu8mg5v7";
+const char *__doc_igl_slice = R"igl_Qu8mg5v7(// Act like the matlab X(row_indices,col_indices) operator, where
+  // row_indices, col_indices are non-negative integer indices.
+  // 
+  // Inputs:
+  //   X  m by n matrix
+  //   R  list of row indices
+  //   C  list of column indices
+  // Output:
+  //   Y  #R by #C matrix
+  //
+  // See also: slice_mask)igl_Qu8mg5v7";
+const char *__doc_igl_per_face_normals = R"igl_Qu8mg5v7(// Compute face normals via vertex position list, face list
+  // Inputs:
+  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F  #F by 3 eigen Matrix of face (triangle) indices
+  //   Z  3 vector normal given to faces with degenerate normal.
+  // Output:
+  //   N  #F by 3 eigen Matrix of mesh face (triangle) 3D normals
+  //
+  // Example:
+  //   // Give degenerate faces (1/3,1/3,1/3)^0.5
+  //   per_face_normals(V,F,Vector3d(1,1,1).normalized(),N);)igl_Qu8mg5v7";
+const char *__doc_igl_per_face_normals_stable = R"igl_Qu8mg5v7(// Special version where order of face indices is guaranteed not to effect
+  // output.)igl_Qu8mg5v7";
+const char *__doc_igl_readOFF = R"igl_Qu8mg5v7(// Read a mesh from an ascii obj file, filling in vertex positions, normals
+  // and texture coordinates. Mesh may have faces of any number of degree
+  //
+  // Templates:
+  //   Scalar  type for positions and vectors (will be read as double and cast
+  //     to Scalar)
+  //   Index  type for indices (will be read as int and cast to Index)
+  // Inputs:
+  //  str  path to .obj file
+  // Outputs:
+  //   V  double matrix of vertex positions  #V by 3
+  //   F  #F list of face indices into vertex positions
+  //   TC  double matrix of texture coordinats #TC by 2
+  //   FTC  #F list of face indices into vertex texture coordinates
+  //   N  double matrix of corner normals #N by 3
+  //   FN  #F list of face indices into vertex normals
+  // Returns true on success, false on errors)igl_Qu8mg5v7";
+const char *__doc_igl_per_vertex_normals = R"igl_Qu8mg5v7(// Compute vertex normals via vertex position list, face list
+  // Inputs:
+  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F  #F by 3 eigne Matrix of face (triangle) indices
+  //   weighting  Weighting type
+  // Output:
+  //   N  #V by 3 eigen Matrix of mesh vertex 3D normals)igl_Qu8mg5v7";
+const char *__doc_igl_sortrows = R"igl_Qu8mg5v7(// Act like matlab's [Y,I] = sortrows(X)
+  //
+  // Templates:
+  //   DerivedX derived scalar type, e.g. MatrixXi or MatrixXd
+  //   DerivedI derived integer type, e.g. MatrixXi
+  // Inputs:
+  //   X  m by n matrix whose entries are to be sorted
+  //   ascending  sort ascending (true, matlab default) or descending (false)
+  // Outputs:
+  //   Y  m by n matrix whose entries are sorted (**should not** be same
+  //     reference as X)
+  //   I  m list of indices so that
+  //     Y = X(I,:);)igl_Qu8mg5v7";
+const char *__doc_igl_barycenter = R"igl_Qu8mg5v7(// Computes the barycenter of every simplex
+  //
+  // Inputs:
+  //   V  #V x dim matrix of vertex coordinates
+  //   F  #F x simplex_size  matrix of indices of simplex corners into V
+  // Output:
+  //   BC  #F x dim matrix of 3d vertices
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_jet = R"igl_Qu8mg5v7(// JET like MATLAB's jet
+  //
+  // Inputs:
+  //   m  number of colors 
+  // Outputs:
+  //   J  m by list of RGB colors between 0 and 1
+  //
+//#ifndef IGL_NO_EIGEN
+//  void jet(const int m, Eigen::MatrixXd & J);
+//#endif
+  // Wrapper for directly computing [r,g,b] values for a given factor f between
+  // 0 and 1
+  //
+  // Inputs:
+  //   f  factor determining color value as if 0 was min and 1 was max
+  // Outputs:
+  //   r  red value
+  //   g  green value
+  //   b  blue value)igl_Qu8mg5v7";
+const char *__doc_igl_eigs = R"igl_Qu8mg5v7(See eigs for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_per_corner_normals = R"igl_Qu8mg5v7(// Compute vertex normals via vertex position list, face list
+  // Inputs:
+  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F  #F by 3 eigne Matrix of face (triangle) indices
+  //   corner_threshold  threshold in degrees on sharp angles
+  // Output:
+  //   CN  #F*3 by 3 eigen Matrix of mesh vertex 3D normals, where the normal
+  //     for corner F(i,j) is at CN(i*3+j,:) )igl_Qu8mg5v7";
+const char *__doc_igl_massmatrix = R"igl_Qu8mg5v7(// Constructs the mass (area) matrix for a given mesh (V,F).
+  //
+  // Templates:
+  //   DerivedV  derived type of eigen matrix for V (e.g. derived from
+  //     MatrixXd)
+  //   DerivedF  derived type of eigen matrix for F (e.g. derived from
+  //     MatrixXi)
+  //   Scalar  scalar type for eigen sparse matrix (e.g. double)
+  // Inputs:
+  //   V  #V by dim list of mesh vertex positions
+  //   F  #F by simplex_size list of mesh faces (must be triangles)
+  //   type  one of the following ints:
+  //     MASSMATRIX_TYPE_BARYCENTRIC  barycentric
+  //     MASSMATRIX_TYPE_VORONOI voronoi-hybrid {default}
+  //     MASSMATRIX_TYPE_FULL full {not implemented}
+  // Outputs: 
+  //   M  #V by #V mass matrix
+  //
+  // See also: adjacency_matrix
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_colon = R"igl_Qu8mg5v7(// Colon operator like matlab's colon operator. Enumerats values between low
+  // and hi with step step.
+  // Templates:
+  //   L  should be a eigen matrix primitive type like int or double
+  //   S  should be a eigen matrix primitive type like int or double
+  //   H  should be a eigen matrix primitive type like int or double
+  //   T  should be a eigen matrix primitive type like int or double
+  // Inputs:
+  //   low  starting value if step is valid then this is *always* the first
+  //     element of I
+  //   step  step difference between sequential elements returned in I,
+  //     remember this will be cast to template T at compile time. If low<hi
+  //     then step must be positive. If low>hi then step must be negative.
+  //     Otherwise I will be set to empty.
+  //   hi  ending value, if (hi-low)%step is zero then this will be the last
+  //     element in I. If step is positive there will be no elements greater
+  //     than hi, vice versa if hi<low
+  // Output:
+  //   I  list of values from low to hi with step size step)igl_Qu8mg5v7";
+const char *__doc_igl_rotate_vectors = R"igl_Qu8mg5v7(// Rotate the vectors V by A radiants on the tangent plane spanned by B1 and
+  // B2
+  //
+  // Inputs:
+  //   V     #V by 3 eigen Matrix of vectors
+  //   A     #V eigen vector of rotation angles or a single angle to be applied
+  //     to all vectors
+  //   B1    #V by 3 eigen Matrix of base vector 1
+  //   B2    #V by 3 eigen Matrix of base vector 2
+  //
+  // Output:
+  //   Returns the rotated vectors
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_read_triangle_mesh = R"igl_Qu8mg5v7(// read mesh from an ascii file with automatic detection of file format.
+  // supported: obj, off, stl, wrl, ply, mesh)
+  // 
+  // Templates:
+  //   Scalar  type for positions and vectors (will be read as double and cast
+  //     to Scalar)
+  //   Index  type for indices (will be read as int and cast to Index)
+  // Inputs:
+  //   str  path to file
+  // Outputs:
+  //   V  eigen double matrix #V by 3
+  //   F  eigen int matrix #F by 3
+  // Returns true iff success)igl_Qu8mg5v7";
+const char *__doc_igl_gaussian_curvature = R"igl_Qu8mg5v7(// Compute discrete local integral gaussian curvature (angle deficit, without
+  // averaging by local area).
+  //
+  // Inputs:
+  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F  #F by 3 eigen Matrix of face (triangle) indices
+  // Output:
+  //   K  #V by 1 eigen Matrix of discrete gaussian curvature values
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_avg_edge_length = R"igl_Qu8mg5v7(// Compute the average edge length for the given triangle mesh
+  // Templates:
+  //   DerivedV derived from vertex positions matrix type: i.e. MatrixXd
+  //   DerivedF derived from face indices matrix type: i.e. MatrixXi
+  //   DerivedL derived from edge lengths matrix type: i.e. MatrixXd
+  // Inputs:
+  //   V  eigen matrix #V by 3
+  //   F  #F by simplex-size list of mesh faces (must be simplex)
+  // Outputs:
+  //   l  average edge length
+  //
+  // See also: adjacency_matrix)igl_Qu8mg5v7";
+const char *__doc_igl_lscm = R"igl_Qu8mg5v7(// Compute a Least-squares conformal map parametrization (equivalently
+  // derived in "Intrinsic Parameterizations of Surface Meshes" [Desbrun et al.
+  // 2002] and "Least Squares Conformal Maps for Automatic Texture Atlas
+  // Generation" [Lévy et al. 2002]), though this implementation follows the
+  // derivation in: "Spectral Conformal Parameterization" [Mullen et al. 2008]
+  // (note, this does **not** implement the Eigen-decomposition based method in
+  // [Mullen et al. 2008], which is not equivalent). Input should be a manifold
+  // mesh (also no unreferenced vertices) and "boundary" (fixed vertices) `b`
+  // should contain at least two vertices per connected component.
+  //
+  // Inputs:
+  //   V  #V by 3 list of mesh vertex positions
+  //   F  #F by 3 list of mesh faces (must be triangles)
+  //   b  #b boundary indices into V
+  //   bc #b by 3 list of boundary values
+  // Outputs:
+  //   UV #V by 2 list of 2D mesh vertex positions in UV space
+  // Returns true only on solver success.
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_find_cross_field_singularities = R"igl_Qu8mg5v7(// Inputs:
+  //   V                #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F                #F by 3 eigen Matrix of face (quad) indices
+  //   Handle_MMatch    #F by 3 eigen Matrix containing the integer missmatch of the cross field
+  //                    across all face edges
+  // Output:
+  //   isSingularity    #V by 1 boolean eigen Vector indicating the presence of a singularity on a vertex
+  //   singularityIndex #V by 1 integer eigen Vector containing the singularity indices
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_parula = R"igl_Qu8mg5v7(// PARULA like MATLAB's parula
+  //
+  // Inputs:
+  //   m  number of colors 
+  // Outputs:
+  //   J  m by list of RGB colors between 0 and 1
+  //
+  // Wrapper for directly computing [r,g,b] values for a given factor f between
+  // 0 and 1
+  //
+  // Inputs:
+  //   f  factor determining color value as if 0 was min and 1 was max
+  // Outputs:
+  //   r  red value
+  //   g  green value
+  //   b  blue value)igl_Qu8mg5v7";
+const char *__doc_igl_setdiff = R"igl_Qu8mg5v7(// Set difference of elements of matrices
+  //
+  // Inputs:
+  //   A  m-long vector of indices
+  //   B  n-long vector of indices
+  // Outputs:
+  //   C  (k<=m)-long vector of unique elements appearing in A but not in B
+  //   IA  (k<=m)-long list of indices into A so that C = A(IA)
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_comb_frame_field = R"igl_Qu8mg5v7(// Inputs:
+  //   V            #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F            #F by 4 eigen Matrix of face (quad) indices
+  //   PD1          #F by 3 eigen Matrix of the first per face cross field vector
+  //   PD2          #F by 3 eigen Matrix of the second per face cross field vector
+  //   BIS1_combed  #F by 3 eigen Matrix of the first combed bisector field vector
+  //   BIS2_combed  #F by 3 eigen Matrix of the second combed bisector field vector
+  // Output:
+  //   PD1_combed  #F by 3 eigen Matrix of the first combed cross field vector
+  //   PD2_combed  #F by 3 eigen Matrix of the second combed cross field vector
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_map_vertices_to_circle = R"igl_Qu8mg5v7(// Map the vertices whose indices are in a given boundary loop (bnd) on the
+  // unit circle with spacing proportional to the original boundary edge
+  // lengths.
+  //
+  // Inputs:
+  //   V  #V by dim list of mesh vertex positions
+  //   b  #W list of vertex ids
+  // Outputs:
+  //   UV   #W by 2 list of 2D position on the unit circle for the vertices in b)igl_Qu8mg5v7";
+const char *__doc_igl_writeOBJ = R"igl_Qu8mg5v7(// Write a mesh in an ascii obj file
+  // Inputs:
+  //   str  path to outputfile
+  //   V  #V by 3 mesh vertex positions
+  //   F  #F by 3|4 mesh indices into V
+  //   CN #CN by 3 normal vectors
+  //   FN  #F by 3|4 corner normal indices into CN
+  //   TC  #TC by 2|3 texture coordinates
+  //   FTC #F by 3|4 corner texture coord indices into TC
+  // Returns true on success, false on error)igl_Qu8mg5v7";
+const char *__doc_igl_active_set = R"igl_Qu8mg5v7(// Known Bugs: rows of [Aeq;Aieq] **must** be linearly independent. Should be
+  // using QR decomposition otherwise:
+  //   http://www.okstate.edu/sas/v8/sashtml/ormp/chap5/sect32.htm
+  //
+  // ACTIVE_SET Minimize quadratic energy 
+  //
+  // 0.5*Z'*A*Z + Z'*B + C with constraints
+  //
+  // that Z(known) = Y, optionally also subject to the constraints Aeq*Z = Beq,
+  // and further optionally subject to the linear inequality constraints that
+  // Aieq*Z <= Bieq and constant inequality constraints lx <= x <= ux
+  //
+  // Inputs:
+  //   A  n by n matrix of quadratic coefficients
+  //   B  n by 1 column of linear coefficients
+  //   known  list of indices to known rows in Z
+  //   Y  list of fixed values corresponding to known rows in Z
+  //   Aeq  meq by n list of linear equality constraint coefficients
+  //   Beq  meq by 1 list of linear equality constraint constant values
+  //   Aieq  mieq by n list of linear inequality constraint coefficients
+  //   Bieq  mieq by 1 list of linear inequality constraint constant values
+  //   lx  n by 1 list of lower bounds [] implies -Inf
+  //   ux  n by 1 list of upper bounds [] implies Inf
+  //   params  struct of additional parameters (see below)
+  //   Z  if not empty, is taken to be an n by 1 list of initial guess values
+  //     (see output)
+  // Outputs:
+  //   Z  n by 1 list of solution values
+  // Returns true on success, false on error
+  //
+  // Benchmark: For a harmonic solve on a mesh with 325K facets, matlab 2.2
+  // secs, igl/min_quad_with_fixed.h 7.1 secs
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_boundary_facets = R"igl_Qu8mg5v7(// BOUNDARY_FACETS Determine boundary faces (edges) of tetrahedra (triangles)
+  // stored in T (analogous to qptoolbox's `outline` and `boundary_faces`).
+  //
+  // Templates:
+  //   IntegerT  integer-value: e.g. int
+  //   IntegerF  integer-value: e.g. int
+  // Input:
+  //  T  tetrahedron (triangle) index list, m by 4 (3), where m is the number of tetrahedra
+  // Output:
+  //  F  list of boundary faces, n by 3 (2), where n is the number of boundary faces
+  //
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_compute_frame_field_bisectors = R"igl_Qu8mg5v7(// Compute bisectors of a frame field defined on mesh faces
+  // Inputs:
+  //   V     #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F     #F by 3 eigen Matrix of face (triangle) indices
+  //   B1    #F by 3 eigen Matrix of face (triangle) base vector 1
+  //   B2    #F by 3 eigen Matrix of face (triangle) base vector 2
+  //   PD1   #F by 3 eigen Matrix of the first per face frame field vector
+  //   PD2   #F by 3 eigen Matrix of the second per face frame field vector
+  // Output:
+  //   BIS1  #F by 3 eigen Matrix of the first per face frame field bisector
+  //   BIS2  #F by 3 eigen Matrix of the second per face frame field bisector
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_readOBJ = R"igl_Qu8mg5v7(// Read a mesh from an ascii obj file, filling in vertex positions, normals
+  // and texture coordinates. Mesh may have faces of any number of degree
+  //
+  // Templates:
+  //   Scalar  type for positions and vectors (will be read as double and cast
+  //     to Scalar)
+  //   Index  type for indices (will be read as int and cast to Index)
+  // Inputs:
+  //  str  path to .obj file
+  // Outputs:
+  //   V  double matrix of vertex positions  #V by 3
+  //   TC  double matrix of texture coordinats #TC by 2
+  //   N  double matrix of corner normals #N by 3
+  //   F  #F list of face indices into vertex positions
+  //   FTC  #F list of face indices into vertex texture coordinates
+  //   FN  #F list of face indices into vertex normals
+  // Returns true on success, false on errors)igl_Qu8mg5v7";
+const char *__doc_igl_cut_mesh_from_singularities = R"igl_Qu8mg5v7(// Given a mesh (V,F) and the integer mismatch of a cross field per edge
+  // (MMatch), finds the cut_graph connecting the singularities (seams) and the
+  // degree of the singularities singularity_index
+  //
+  // Input:
+  //   V  #V by 3 list of mesh vertex positions
+  //   F  #F by 3 list of faces
+  //   MMatch  #F by 3 list of per corner integer mismatch
+  // Outputs:
+  //   seams  #F by 3 list of per corner booleans that denotes if an edge is a
+  //     seam or not
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_readDMAT = R"igl_Qu8mg5v7(See readDMAT for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_doublearea = R"igl_Qu8mg5v7(// DOUBLEAREA computes twice the area for each input triangle[quad]
+  //
+  // Templates:
+  //   DerivedV  derived type of eigen matrix for V (e.g. derived from
+  //     MatrixXd)
+  //   DerivedF  derived type of eigen matrix for F (e.g. derived from
+  //     MatrixXi)
+  //   DeriveddblA  derived type of eigen matrix for dblA (e.g. derived from
+  //     MatrixXd)
+  // Inputs:
+  //   V  #V by dim list of mesh vertex positions
+  //   F  #F by simplex_size list of mesh faces (must be triangles or quads)
+  // Outputs:
+  //   dblA  #F list of triangle[quad] double areas (SIGNED only for 2D input)
+  //
+  // Known bug: For dim==3 complexity is O(#V + #F)!! Not just O(#F). This is a big deal
+  // if you have 1million unreferenced vertices and 1 face)igl_Qu8mg5v7";
+const char *__doc_igl_doublearea_single = R"igl_Qu8mg5v7(// Single triangle in 2D!
+  //
+  // This should handle streams of corners not just single corners)igl_Qu8mg5v7";
+const char *__doc_igl_doublearea_quad = R"igl_Qu8mg5v7(// DOUBLEAREA_QUAD computes twice the area for each input quadrilateral
+  //
+  // Inputs:
+  //   V  #V by dim list of mesh vertex positions
+  //   F  #F by simplex_size list of mesh faces (must be quadrilaterals)
+  // Outputs:
+  //   dblA  #F list of quadrilateral double areas
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_min_quad_with_fixed_precompute = R"igl_Qu8mg5v7(// Known Bugs: rows of Aeq **should probably** be linearly independent.
+  // During precomputation, the rows of a Aeq are checked via QR. But in case
+  // they're not then resulting probably will no longer be sparse: it will be
+  // slow.
+  //
+  // MIN_QUAD_WITH_FIXED Minimize quadratic energy 
+  //
+  // 0.5*Z'*A*Z + Z'*B + C with
+  //
+  // constraints that Z(known) = Y, optionally also subject to the constraints
+  // Aeq*Z = Beq
+  //
+  // Templates:
+  //   T  should be a eigen matrix primitive type like int or double
+  // Inputs:
+  //   A  n by n matrix of quadratic coefficients
+  //   known list of indices to known rows in Z
+  //   Y  list of fixed values corresponding to known rows in Z
+  //   Aeq  m by n list of linear equality constraint coefficients
+  //   pd flag specifying whether A(unknown,unknown) is positive definite
+  // Outputs:
+  //   data  factorization struct with all necessary information to solve
+  //     using min_quad_with_fixed_solve
+  // Returns true on success, false on error
+  //
+  // Benchmark: For a harmonic solve on a mesh with 325K facets, matlab 2.2
+  // secs, igl/min_quad_with_fixed.h 7.1 secs
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_min_quad_with_fixed_solve = R"igl_Qu8mg5v7(// Solves a system previously factored using min_quad_with_fixed_precompute
+  //
+  // Template:
+  //   T  type of sparse matrix (e.g. double)
+  //   DerivedY  type of Y (e.g. derived from VectorXd or MatrixXd)
+  //   DerivedZ  type of Z (e.g. derived from VectorXd or MatrixXd)
+  // Inputs:
+  //   data  factorization struct with all necessary precomputation to solve
+  //   B  n by 1 column of linear coefficients
+  //   Y  b by 1 list of constant fixed values
+  //   Beq  m by 1 list of linear equality constraint constant values
+  // Outputs:
+  //   Z  n by cols solution
+  //   sol  #unknowns+#lagrange by cols solution to linear system
+  // Returns true on success, false on error)igl_Qu8mg5v7";
+const char *__doc_igl_min_quad_with_fixed = R"igl_Qu8mg5v7(See min_quad_with_fixed for the documentation.)igl_Qu8mg5v7";
+const char *__doc_igl_unique = R"igl_Qu8mg5v7(// Act like matlab's [C,IA,IC] = unique(X)
+  //
+  // Templates:
+  //   T  comparable type T
+  // Inputs:
+  //   A  #A vector of type T
+  // Outputs:
+  //   C  #C vector of unique entries in A
+  //   IA  #C index vector so that C = A(IA);
+  //   IC  #A index vector so that A = C(IC);)igl_Qu8mg5v7";
+const char *__doc_igl_unique_rows = R"igl_Qu8mg5v7(// Act like matlab's [C,IA,IC] = unique(X,'rows')
+  //
+  // Templates:
+  //   DerivedA derived scalar type, e.g. MatrixXi or MatrixXd
+  //   DerivedIA derived integer type, e.g. MatrixXi
+  //   DerivedIC derived integer type, e.g. MatrixXi
+  // Inputs:
+  //   A  m by n matrix whose entries are to unique'd according to rows
+  // Outputs:
+  //   C  #C vector of unique rows in A
+  //   IA  #C index vector so that C = A(IA,:);
+  //   IC  #A index vector so that A = C(IC,:);)igl_Qu8mg5v7";
+const char *__doc_igl_arap_precomputation = R"igl_Qu8mg5v7(// Compute necessary information to start using an ARAP deformation
+  //
+  // Inputs:
+  //   V  #V by dim list of mesh positions
+  //   F  #F by simplex-size list of triangle|tet indices into V
+  //   dim  dimension being used at solve time. For deformation usually dim =
+  //     V.cols(), for surface parameterization V.cols() = 3 and dim = 2
+  //   b  #b list of "boundary" fixed vertex indices into V
+  // Outputs:
+  //   data  struct containing necessary precomputation)igl_Qu8mg5v7";
+const char *__doc_igl_arap_solve = R"igl_Qu8mg5v7(// Inputs:
+  //   bc  #b by dim list of boundary conditions
+  //   data  struct containing necessary precomputation and parameters
+  //   U  #V by dim initial guess)igl_Qu8mg5v7";
+const char *__doc_igl_cross_field_missmatch = R"igl_Qu8mg5v7(// Inputs:
+  //   V         #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F         #F by 3 eigen Matrix of face (quad) indices
+  //   PD1       #F by 3 eigen Matrix of the first per face cross field vector
+  //   PD2       #F by 3 eigen Matrix of the second per face cross field vector
+  //   isCombed  boolean, specifying whether the field is combed (i.e. matching has been precomputed.
+  //             If not, the field is combed first.
+  // Output:
+  //   Handle_MMatch    #F by 3 eigen Matrix containing the integer missmatch of the cross field
+  //                    across all face edges
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_grad = R"igl_Qu8mg5v7(// Gradient of a scalar function defined on piecewise linear elements (mesh)
+  // is constant on each triangle i,j,k:
+  // grad(Xijk) = (Xj-Xi) * (Vi - Vk)^R90 / 2A + (Xk-Xi) * (Vj - Vi)^R90 / 2A
+  // where Xi is the scalar value at vertex i, Vi is the 3D position of vertex
+  // i, and A is the area of triangle (i,j,k). ^R90 represent a rotation of
+  // 90 degrees
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_slice_into = R"igl_Qu8mg5v7(// Act like the matlab Y(row_indices,col_indices) = X
+  // 
+  // Inputs:
+  //   X  xm by xn rhs matrix
+  //   R  list of row indices
+  //   C  list of column indices
+  //   Y  ym by yn lhs matrix
+  // Output:
+  //   Y  ym by yn lhs matrix, same as input but Y(R,C) = X)igl_Qu8mg5v7";
+const char *__doc_igl_n_polyvector = R"igl_Qu8mg5v7(// Inputs:
+  //   v0, v1         the two #3 by 1 vectors
+  //   normalized     boolean, if false, then the vectors are normalized prior to the calculation
+  // Output:
+  //                  3 by 3 rotation matrix that takes v0 to v1
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_harmonic = R"igl_Qu8mg5v7(// Compute k-harmonic weight functions "coordinates".
+  //
+  //
+  // Inputs:
+  //   V  #V by dim vertex positions
+  //   F  #F by simplex-size list of element indices
+  //   b  #b boundary indices into V
+  //   bc #b by #W list of boundary values
+  //   k  power of harmonic operation (1: harmonic, 2: biharmonic, etc)
+  // Outputs:
+  //   W  #V by #W list of weights
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_boundary_loop = R"igl_Qu8mg5v7(// Compute list of ordered boundary loops for a manifold mesh.
+  //
+  // Templates:
+  //  Index  index type
+  // Inputs:
+  //   F  #V by dim list of mesh faces
+  // Outputs:
+  //   L  list of loops where L[i] = ordered list of boundary vertices in loop i
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_comb_cross_field = R"igl_Qu8mg5v7(// Inputs:
+  //   V          #V by 3 eigen Matrix of mesh vertex 3D positions
+  //   F          #F by 4 eigen Matrix of face (quad) indices
+  //   PD1in      #F by 3 eigen Matrix of the first per face cross field vector
+  //   PD2in      #F by 3 eigen Matrix of the second per face cross field vector
+  // Output:
+  //   PD1out      #F by 3 eigen Matrix of the first combed cross field vector
+  //   PD2out      #F by 3 eigen Matrix of the second combed cross field vector
+  //)igl_Qu8mg5v7";
+const char *__doc_igl_invert_diag = R"igl_Qu8mg5v7(// Templates:
+  //   T  should be a eigen sparse matrix primitive type like int or double
+  // Inputs:
+  //   X  an m by n sparse matrix
+  // Outputs:
+  //   Y  an m by n sparse matrix)igl_Qu8mg5v7";
+const char *__doc_igl_copyleft_comiso_miq = R"igl_Qu8mg5v7(// Inputs:
+    //   V              #V by 3 list of mesh vertex 3D positions
+    //   F              #F by 3 list of faces indices in V
+    //   PD1            #V by 3 first line of the Jacobian per triangle
+    //   PD2            #V by 3 second line of the Jacobian per triangle
+    //                  (optional, if empty it will be a vector in the tangent plane orthogonal to PD1)
+    //   scale          global scaling for the gradient (controls the quads resolution)
+    //   stiffness      weight for the stiffness iterations
+    //   direct_round   greedily round all integer variables at once (greatly improves optimization speed but lowers quality)
+    //   iter           stiffness iterations (0 = no stiffness)
+    //   local_iter     number of local iterations for the integer rounding
+    //   do_round       enables the integer rounding (disabling it could be useful for debugging)
+    //   round_vertices id of additional vertices that should be snapped to integer coordinates
+    //   hard_features  #H by 2 list of pairs of vertices that belongs to edges that should be snapped to integer coordinates
+    //
+    // Output:
+    //   UV             #UV by 2 list of vertices in 2D
+    //   FUV            #FUV by 3 list of face indices in UV
+    //
+    // TODO: rename the parameters name in the cpp consistenly
+    //       improve the handling of hard_features, right now it might fail in difficult cases)igl_Qu8mg5v7";
+const char *__doc_igl_copyleft_comiso_nrosy = R"igl_Qu8mg5v7(// Generate a N-RoSy field from a sparse set of constraints
+    //
+    // Inputs:
+    //   V       #V by 3 list of mesh vertex coordinates
+    //   F       #F by 3 list of mesh faces (must be triangles)
+    //   b       #B by 1 list of constrained face indices
+    //   bc      #B by 3 list of representative vectors for the constrained
+    //     faces
+    //   b_soft  #S by 1 b for soft constraints
+    //   w_soft  #S by 1 weight for the soft constraints (0-1)
+    //   bc_soft #S by 3 bc for soft constraints
+    //   N       the degree of the N-RoSy vector field
+    //   soft    the strenght of the soft contraints w.r.t. smoothness
+    //           (0 -> smoothness only, 1->constraints only)
+    // Outputs:
+    //   R       #F by 3 the representative vectors of the interpolated field
+    //   S       #V by 1 the singularity index for each vertex (0 = regular))igl_Qu8mg5v7";

+ 44 - 400
python/py_doc.h

@@ -1,409 +1,53 @@
-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_principal_curvature;
+extern const char *__doc_igl_local_basis;
+extern const char *__doc_igl_cotmatrix;
+extern const char *__doc_igl_floor;
+extern const char *__doc_igl_slice;
+extern const char *__doc_igl_per_face_normals;
+extern const char *__doc_igl_per_face_normals_stable;
+extern const char *__doc_igl_readOFF;
+extern const char *__doc_igl_per_vertex_normals;
+extern const char *__doc_igl_sortrows;
 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_jet;
+extern const char *__doc_igl_eigs;
+extern const char *__doc_igl_per_corner_normals;
+extern const char *__doc_igl_massmatrix;
 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_rotate_vectors;
+extern const char *__doc_igl_read_triangle_mesh;
+extern const char *__doc_igl_gaussian_curvature;
+extern const char *__doc_igl_avg_edge_length;
+extern const char *__doc_igl_lscm;
+extern const char *__doc_igl_find_cross_field_singularities;
+extern const char *__doc_igl_parula;
+extern const char *__doc_igl_setdiff;
 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_map_vertices_to_circle;
+extern const char *__doc_igl_writeOBJ;
+extern const char *__doc_igl_active_set;
+extern const char *__doc_igl_boundary_facets;
 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_readOBJ;
 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_readDMAT;
 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_doublearea_single;
+extern const char *__doc_igl_doublearea_quad;
+extern const char *__doc_igl_min_quad_with_fixed_precompute;
+extern const char *__doc_igl_min_quad_with_fixed_solve;
+extern const char *__doc_igl_min_quad_with_fixed;
+extern const char *__doc_igl_unique;
+extern const char *__doc_igl_unique_rows;
+extern const char *__doc_igl_arap_precomputation;
+extern const char *__doc_igl_arap_solve;
+extern const char *__doc_igl_cross_field_missmatch;
 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_slice_into;
+extern const char *__doc_igl_n_polyvector;
 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_boundary_loop;
+extern const char *__doc_igl_comb_cross_field;
 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;
+extern const char *__doc_igl_copyleft_comiso_miq;
+extern const char *__doc_igl_copyleft_comiso_nrosy;

+ 2 - 2
python/py_igl/copyleft/comiso/py_miq.cpp

@@ -20,7 +20,7 @@ m.def("miq", []
   std::vector<std::vector<int> > hard_features;
 
   igl::copyleft::comiso::miq(V,F,PD1,PD2,UV,FUV,scale,stiffness,direct_round,iter,local_iter,DoRound, SingularityRound, round_vertices, hard_features);
-}, __doc_igl_comiso_miq,
+}, __doc_igl_copyleft_comiso_miq,
 py::arg("V"), py::arg("F"), py::arg("PD1"), py::arg("PD2"), py::arg("UV"), py::arg("FUV"), py::arg("scale") = 30.0, py::arg("stiffness") = 5.0, py::arg("direct_round") = false, py::arg("iter") = 5, py::arg("local_iter") = 5, py::arg("DoRound") = true, py::arg("SingularityRound") = true
 // , py::arg("round_vertices"), py::arg("hard_features")
 );
@@ -51,7 +51,7 @@ m.def("miq", []
   std::vector<std::vector<int> > hardFeatures;
 
   igl::copyleft::comiso::miq(V,F,PD1_combed,PD2_combed,MMatch,Singular,Seams,UV,FUV,GradientSize,Stiffness,DirectRound,iter,localIter,DoRound, SingularityRound, roundVertices, hardFeatures);
-}, __doc_igl_comiso_miq,
+}, __doc_igl_copyleft_comiso_miq,
 py::arg("V"), py::arg("F"), py::arg("PD1_combed"), py::arg("PD2_combed"),
 py::arg("MMatch"), py::arg("Singular"), py::arg("Seams"),
 py::arg("UV"), py::arg("FUV"), py::arg("GradientSize") = 30.0, py::arg("Stiffness") = 5.0, py::arg("DirectRound") = false, py::arg("iter") = 5, py::arg("localIter") = 5, py::arg("DoRound") = true, py::arg("SingularityRound") = true

+ 2 - 2
python/py_igl/copyleft/comiso/py_nrosy.cpp

@@ -33,7 +33,7 @@ m.def("nrosy", []
   igl::copyleft::comiso::nrosy(V,F,bt,bc,b_softt,w_softt,bc_soft,N,soft,R,St);
   S = St;
 
-}, __doc_igl_comiso_nrosy,
+}, __doc_igl_copyleft_comiso_nrosy,
 py::arg("V"), py::arg("F"), py::arg("b"), py::arg("bc"), py::arg("b_soft"), py::arg("w_soft"), py::arg("bc_soft"), py::arg("N"), py::arg("soft"), py::arg("R"), py::arg("S"));
 
 m.def("nrosy", []
@@ -56,5 +56,5 @@ m.def("nrosy", []
   Eigen::VectorXd St;
   igl::copyleft::comiso::nrosy(V,F,bt,bc,N,R,St);
   S = St;
-}, __doc_igl_comiso_nrosy,
+}, __doc_igl_copyleft_comiso_nrosy,
 py::arg("V"), py::arg("F"), py::arg("b"), py::arg("bc"), py::arg("N"), py::arg("R"), py::arg("S"));

+ 2 - 2
python/py_igl/py_arap.cpp

@@ -46,7 +46,7 @@ m.def("arap_precomputation", []
     bt = b;
 
   return igl::arap_precomputation(V,F,dim,bt,data);
-}, __doc_igl_arap,
+}, __doc_igl_arap_precomputation,
 py::arg("V"), py::arg("F"), py::arg("dim"), py::arg("b"), py::arg("data"));
 
 m.def("arap_solve", []
@@ -57,5 +57,5 @@ m.def("arap_solve", []
 )
 {
   return igl::arap_solve(bc,data,U);
-}, __doc_igl_arap,
+}, __doc_igl_arap_solve,
 py::arg("bc"), py::arg("data"), py::arg("U"));

+ 2 - 2
python/py_igl/py_doublearea.cpp

@@ -29,7 +29,7 @@ m.def("doublearea_single", []
 )
 {
   return igl::doublearea_single(A,B,C);
-}, __doc_igl_doublearea,
+}, __doc_igl_doublearea_single,
 py::arg("A"), py::arg("B"), py::arg("C"));
 
 m.def("doublearea", []
@@ -50,5 +50,5 @@ m.def("doublearea_quad", []
 )
 {
   return igl::doublearea_quad(V,F,dblA);
-}, __doc_igl_doublearea,
+}, __doc_igl_doublearea_quad,
 py::arg("V"), py::arg("F"), py::arg("dblA"));

+ 11 - 3
python/python_shared.cpp

@@ -14,9 +14,17 @@ extern void python_export_igl_viewer(py::module &);
 extern void python_export_igl_comiso(py::module &);
 #endif
 
-PYTHON_PLUGIN(pyigl) {
-    py::init_threading();
-    py::module m("pyigl", "Python wrappers for libigl");
+PYBIND11_PLUGIN(pyigl) {
+    py::module m("pyigl", R"pyigldoc(
+        Python wrappers for libigl
+        --------------------------
+
+        .. currentmodule:: pyigl
+
+        .. autosummary::
+           :toctree: _generate
+
+    )pyigldoc");
 
     python_export_vector(m);
     python_export_igl(m);

+ 7 - 7
python/python_shared.h

@@ -1,11 +1,11 @@
 #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 <pybind11/pybind11.h>
+#include <pybind11/operators.h>
+#include <pybind11/complex.h>
+#include <pybind11/numpy.h>
+#include <pybind11/stl.h>
+#include <pybind11/functional.h>
 
 #include "py_doc.h"
 
@@ -83,4 +83,4 @@ void assert_is_Matrix4(const std::string name, const Eigen::PlainObjectBase<Scal
 
 
 
-namespace py = pybind;
+namespace py = pybind11;

+ 126 - 0
python/scripts/generate_docstrings.py

@@ -0,0 +1,126 @@
+#!/usr/bin/env python3
+#
+#  Syntax: generate_docstrings.py <path_to_c++_header_files> <path_to_python_files>
+#
+#  Extract documentation from C++ header files to use it in libiglPython bindings
+#
+
+import os, sys, glob
+from joblib import Parallel, delayed
+from multiprocessing import cpu_count
+from mako.template import Template
+from parser import parse
+
+
+# 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.
+
+
+def get_name_from_path(path, basepath, prefix, postfix):
+    f_clean = path[len(basepath):]
+    f_clean = f_clean.replace(basepath, "")
+    f_clean = f_clean.replace(postfix, "")
+    f_clean = f_clean.replace(prefix, "")
+    f_clean = f_clean.replace("/", "_")
+    f_clean = f_clean.replace("\\", "_")
+    f_clean = f_clean.replace(" ", "_")
+    f_clean = f_clean.replace(".", "_")
+    return f_clean
+
+
+if __name__ == '__main__':
+
+    if len(sys.argv) != 3:
+        print('Syntax: %s <path_to_c++_header_files> <path_to_python_files>' % sys.argv[0])
+        exit(-1)
+
+    # List all files in the given folder and subfolders
+    cpp_base_path = sys.argv[1]
+    py_base_path = sys.argv[2]
+    cpp_file_paths = get_filepaths(cpp_base_path)
+    py_file_paths = get_filepaths(py_base_path)
+
+    # Add all the .h filepaths to a dict
+    mapping = {}
+    for f in cpp_file_paths:
+        if f.endswith(".h"):
+            name = get_name_from_path(f, cpp_base_path, "", ".h")
+            mapping[name] = f
+
+    # Add all python binding files to a list
+    implemented_names = []
+    for f in py_file_paths:
+        if f.endswith(".cpp"):
+            name = get_name_from_path(f, py_base_path, "py_", ".cpp")
+            implemented_names.append(name)
+
+    # Create a list of cpp header files for which a python binding file exists
+    files_to_parse = []
+    for n in implemented_names:
+        if n not in mapping:
+            print("No cpp header file for python function %s found." % n)
+            continue
+        files_to_parse.append(mapping[n])
+        # print(mapping[n])
+
+    # Parse c++ header files
+    job_count = cpu_count()
+    dicts = Parallel(n_jobs=job_count)(delayed(parse)(path) for path in files_to_parse)
+
+    hpplines = []
+    cpplines = []
+
+    for idx, n in enumerate(implemented_names):
+        dict = dicts[idx]
+        contained_elements = sum(map(lambda x: len(x), dict.values()))
+        # Check for files that don't contain functions/enums/classes
+        if contained_elements == 0:
+            print("Function %s contains no parseable content in cpp header. Something might be wrong." % n)
+            continue
+        else:
+            names = []
+            namespaces = "_".join(dict["namespaces"])  # Assumption that all entities lie in deepest namespace
+            for f in dict["functions"]:
+                h_string = "extern const char *__doc_" + namespaces + "_" + f.name + ";\n"
+                docu_string = "See " + f.name + " for the documentation."
+                if f.documentation != "":
+                    docu_string = f.documentation
+                cpp_string = "const char *__doc_" + namespaces + "_" + f.name + " = R\"igl_Qu8mg5v7(" + docu_string + ")igl_Qu8mg5v7\";\n"
+
+                if f.name not in names:  # Prevent multiple additions of declarations, TODO: Possible fix is to merge comments and add them to all functions
+                    hpplines.append(h_string)
+                    cpplines.append(cpp_string)
+                names.append(f.name)
+
+    # Change directory to become independent of execution directory
+    path = os.path.dirname(__file__)
+    if path != "":
+        os.chdir(path)
+
+    # Update the two files py_doc.h and py_doc.cpp
+    with open('../py_doc.h', 'w') as fh:
+        fh.writelines(hpplines)
+    with open('../py_doc.cpp', 'w') as fc:
+        fc.writelines(cpplines)
+
+    # Write python_shared_cpp file
+    tpl = Template(filename='python_shared.mako')
+    rendered = tpl.render(functions=implemented_names)
+    with open("../python_shared.cpp", 'w') as fs:
+        fs.write(rendered)

+ 0 - 68
python/scripts/mk_py_doc.py

@@ -1,68 +0,0 @@
-#!/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()

+ 123 - 0
python/scripts/parser.py

@@ -0,0 +1,123 @@
+import sys
+import os
+from threading import Thread
+
+import clang.cindex
+import itertools
+from mako.template import Template
+
+
+def get_annotations(node):
+    return [c.displayname for c in node.get_children()
+            if c.kind == clang.cindex.CursorKind.ANNOTATE_ATTR]
+
+
+class Function(object):
+    def __init__(self, cursor):
+        self.name = cursor.spelling
+        self.annotations = get_annotations(cursor)
+        self.access = cursor.access_specifier
+        #        template_pars = [c.extent for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.TEMPLATE_TYPE_PARAMETER]
+        #        parameter_dec = [c for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.PARM_DECL]
+        #        print(parameter_dec, template_pars)
+        #        print(cursor.get_num_template_arguments(), cursor.get_template_argument_type(0), cursor.get_template_argument_value(0), template_pars, parameter_dec)
+        self.parameters = []
+        self.parnames = []
+        self.documentation = cursor.raw_comment
+
+
+class Enum(object):
+    def __init__(self, cursor):
+        self.name = cursor.spelling
+        self.annotations = get_annotations(cursor)
+        self.access = cursor.access_specifier
+        #        template_pars = [c.extent for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.TEMPLATE_TYPE_PARAMETER]
+        #        parameter_dec = [c for c in cursor.get_children() if c.kind == clang.cindex.CursorKind.PARM_DECL]
+        #        print(parameter_dec, template_pars)
+        #        print(cursor.get_num_template_arguments(), cursor.get_template_argument_type(0), cursor.get_template_argument_value(0), template_pars, parameter_dec)
+        self.parameters = []
+        self.parnames = []
+        self.documentation = cursor.raw_comment
+
+# class Class(object):
+#    def __init__(self, cursor):
+#        self.name = cursor.spelling
+#        self.functions = []
+#        self.annotations = get_annotations(cursor)
+
+#        for c in cursor.get_children():
+#            if (c.kind == clang.cindex.CursorKind.CXX_METHOD and
+#                c.access_specifier == clang.cindex.AccessSpecifier.PUBLIC):
+#                f = Function(c)
+#                self.functions.append(f)
+
+def find_namespace_node(c):
+    if (c.kind == clang.cindex.CursorKind.NAMESPACE and c.spelling == "igl"):
+        return c
+    else:
+        for child_node in c.get_children():
+            return find_namespace_node(child_node)
+
+
+def traverse(c, path, objects):
+    if c.location.file and not c.location.file.name.endswith(path):
+        return
+
+    # print(c.kind, c.spelling)
+
+
+    if c.kind == clang.cindex.CursorKind.TRANSLATION_UNIT or c.kind == clang.cindex.CursorKind.UNEXPOSED_DECL:
+        # Ignore  other cursor kinds
+        pass
+
+    elif c.kind == clang.cindex.CursorKind.NAMESPACE:
+        objects["namespaces"].append(c.spelling)
+        # print("Namespace", c.spelling, c.get_children())
+        pass
+
+    elif c.kind == clang.cindex.CursorKind.FUNCTION_TEMPLATE:
+        # print("Function Template", c.spelling, c.raw_comment)
+        objects["functions"].append(Function(c))
+        return
+
+    elif c.kind == clang.cindex.CursorKind.FUNCTION_DECL:
+        # print("FUNCTION_DECL", c.spelling, c.raw_comment)
+        objects["functions"].append(Function(c))
+        return
+
+    elif c.kind == clang.cindex.CursorKind.ENUM_DECL:
+        # print("ENUM_DECL", c.spelling, c.raw_comment)
+        objects["enums"].append(Enum(c))
+        return
+
+    else:
+        # print("Unknown", c.kind, c.spelling)
+        pass
+
+    for child_node in c.get_children():
+        traverse(child_node, path, objects)
+
+
+def parse(path):
+    index = clang.cindex.Index.create()
+    tu = index.parse(path, ['-x', 'c++', '-std=c++11', '-fparse-all-comments', '-DIGL_STATIC_LIBRARY'])
+    # Clang can't parse files with missing definitions, add static library definition
+    objects = {"functions": [], "enums": [], "namespaces": [], "classes": []}
+    traverse(tu.cursor, path, objects)
+
+    #    tpl = Template(filename='bind.mako')
+    #    rendered = tpl.render(functions=functions)
+
+    #    OUTPUT_DIR = 'generated'
+
+    #    if not os.path.isdir(OUTPUT_DIR): os.mkdir(OUTPUT_DIR)
+
+    #    with open("generated/{}.bind.cc".format(sys.argv[1]), "w") as f:
+    #        f.write(rendered)
+    return objects
+
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        print("Usage: python3 parser.py <headerfile_path>")
+        exit(-1)
+    parse(sys.argv[1])

+ 46 - 0
python/scripts/python_shared.mako

@@ -0,0 +1,46 @@
+#include "python_shared.h"
+#include <sstream>
+#include <string>
+#include <fstream>
+
+extern void python_export_vector(py::module &);
+extern void python_export_igl(py::module &);
+
+#ifdef PY_VIEWER
+extern void python_export_igl_viewer(py::module &);
+#endif
+
+#ifdef PY_COMISO
+extern void python_export_igl_comiso(py::module &);
+#endif
+
+PYBIND11_PLUGIN(pyigl) {
+    py::module m("pyigl", R"pyigldoc(
+        Python wrappers for libigl
+        --------------------------
+
+        .. currentmodule:: pyigl
+
+        .. autosummary::
+           :toctree: _generate
+
+           % for f in functions:
+           ${f}
+           % endfor
+
+    )pyigldoc");
+
+    python_export_vector(m);
+    python_export_igl(m);
+
+
+    #ifdef PY_VIEWER
+    python_export_igl_viewer(m);
+    #endif
+
+    #ifdef PY_COMISO
+    python_export_igl_comiso(m);
+    #endif
+
+    return m.ptr();
+}

+ 2 - 0
shared/cmake/CMakeLists.txt

@@ -115,6 +115,8 @@ if(LIBIGL_WITH_BBW)
   if(LIBIGL_USE_STATIC_LIBRARY)
     CompileIGL_Module("bbw")
     if(LIBIGL_WITH_MOSEK)
+      find_package(MOSEK REQUIRED)
+      list(APPEND LIBIGL_INCLUDE_DIRS ${MOSEK_INCLUDE_DIR})
       target_include_directories(iglbbw PRIVATE ${MOSEK_INCLUDE_DIR})
     else()
       target_compile_definitions(iglbbw PRIVATE -DIGL_NO_MOSEK)