Эх сурвалжийг харах

merge

Former-commit-id: f0a395d616df7eb96e9358f6b3952c0f608bc483
Alec Jacobson 8 жил өмнө
parent
commit
16e7bd3d51
52 өөрчлөгдсөн 532 нэмэгдсэн , 107 устгасан
  1. 4 0
      .travis.yml
  2. 11 7
      README.md
  3. 62 0
      coding-guidelines.html
  4. 42 0
      coding-guidelines.md
  5. 5 4
      include/igl/avg_edge_length.cpp
  6. 2 2
      include/igl/avg_edge_length.h
  7. 1 0
      include/igl/colon.cpp
  8. 72 0
      include/igl/copyleft/cgal/convex_hull.cpp
  9. 56 0
      include/igl/copyleft/cgal/convex_hull.h
  10. 9 4
      include/igl/copyleft/cgal/polyhedron_to_mesh.cpp
  11. 6 3
      include/igl/copyleft/cgal/polyhedron_to_mesh.h
  12. 1 1
      include/igl/dfs.cpp
  13. 1 0
      include/igl/edges.cpp
  14. 2 2
      include/igl/eigs.cpp
  15. 1 1
      include/igl/extract_manifold_patches.cpp
  16. 10 8
      include/igl/ismember.cpp
  17. 4 4
      include/igl/ismember.h
  18. 2 0
      include/igl/list_to_matrix.cpp
  19. 2 0
      include/igl/max_size.cpp
  20. 2 0
      include/igl/min_size.cpp
  21. 2 0
      include/igl/mosek/mosek_linprog.cpp
  22. 2 0
      include/igl/mosek/mosek_quadprog.cpp
  23. 4 0
      include/igl/readPLY.cpp
  24. 1 1
      include/igl/remove_unreferenced.cpp
  25. 3 3
      include/igl/reorder.cpp
  26. 1 1
      include/igl/sort.cpp
  27. 3 0
      include/igl/sortrows.cpp
  28. 3 3
      include/igl/sparse.cpp
  29. 3 1
      include/igl/unique.cpp
  30. 35 11
      include/igl/viewer/Viewer.cpp
  31. 2 1
      include/igl/viewer/Viewer.h
  32. 5 2
      include/igl/viewer/ViewerCore.cpp
  33. 2 1
      include/igl/viewer/ViewerCore.h
  34. 2 2
      include/igl/viewer/ViewerData.cpp
  35. 6 6
      include/igl/viewer/ViewerData.h
  36. 5 0
      include/igl/viewer/ViewerPlugin.h
  37. 63 4
      include/igl/writeWRL.cpp
  38. 19 4
      include/igl/writeWRL.h
  39. 15 10
      index.html
  40. 9 9
      optional/index.html
  41. 3 3
      python/CMakeLists.txt
  42. 8 0
      python/py_doc.cpp
  43. 1 0
      python/py_doc.h
  44. 2 0
      python/py_igl.cpp
  45. 23 0
      python/py_igl/py_writePLY.cpp
  46. 1 0
      python/python_shared.cpp
  47. 3 3
      python/tutorial/101_FileIO.py
  48. 2 2
      python/tutorial/shared.py
  49. 4 1
      scripts/update_gh-pages.sh
  50. 3 1
      shared/cmake/FindMOSEK.cmake
  51. 1 1
      tutorial/tutorial.html.REMOVED.git-id
  52. 1 1
      tutorial/tutorial.md.REMOVED.git-id

+ 4 - 0
.travis.yml

@@ -13,6 +13,8 @@ matrix:
         - cd build
         - cmake -DCMAKE_CXX_COMPILER=g++-4.8 -DCMAKE_C_COMPILER=gcc-4.8 -DLIBIGL_WITH_EMBREE=OFF -DLIBIGL_USE_STATIC_LIBRARY=ON ../
         - make -j 2
+        - cd ../tutorial
+        - python 101_FileIO.py
         - cd ../../
         - cd tutorial
         - mkdir build
@@ -54,6 +56,8 @@ matrix:
         - cd build
         - cmake ../
         - make -j 2
+        - cd ../tutorial
+        - python 101_FileIO.py
         - cd ../../
         - cd tutorial
         - mkdir build

+ 11 - 7
README.md

@@ -43,10 +43,14 @@ and Windows with Visual Studio 2015 Community Edition.
 As of version 1.0, libigl includes an introductory
 [tutorial](http://libigl.github.io/libigl/tutorial/tutorial.html) that covers many functionalities.
 
-## libigl example project
+## libigl Example Project
 
 We provide a [blank project example](https://github.com/libigl/libigl-example-project) showing how to use libigl and cmake. Feel free and encouraged to copy or fork this project as a way of starting a new personal project using libigl.
 
+## Coding Guidelines and Tips
+
+libigl follows strict coding guidelines, please take a look [here](http://libigl.github.io/libigl/style-guidelines.html) before submitting your pull requests. We also have a set of [general coding tips](http://libigl.github.io/libigl/coding-guidelines.html) on how to code a geometry processing research project.
+
 ## Installation
 
 Libigl is a **header-only** library. You do **not** need to build anything to
@@ -98,7 +102,7 @@ libigl depends only on the [Eigen](http://eigen.tuxfamily.org) library.
 
 For more information see our [tutorial](tutorial/tutorial.html).
 
-### Optional dependencies
+### Optional Dependencies
 
 Libigl compartmentalizes its **optional** dependences via its directory
 organization in the `include/` folder. All header files located _directly_ in
@@ -106,7 +110,7 @@ the `include/igl/` folder have only stl and Eigen as dependencies. For example,
 all of the headers that depend on CGAL are located in `include/igl/cgal`. For a
 full list of _optional_ dependencies check `optional/CMakeLists.txt`.
 
-### GCC and the optional CGAL dependency
+### GCC and the Optional CGAL Dependency
 The `include/igl/cgal/*.h` headers depend on CGAL. It has come to our attention
 that CGAL does not work properly with GCC 4.8. To the best of our knowledge,
 GCC 4.7 and clang will work correctly.
@@ -162,16 +166,16 @@ git pull
 git submodule update --recursive
 ```
 
-## Unit testing
+## Unit Testing
 
 Libigl maintains [separate
 repository](https://github.com/libigl/libigl-unit-tests) for unit testing.
 
-## How to contribute
+## How to Contribute
 
 If you are interested in joining development, please fork the repository and
 submit a [pull request](https://help.github.com/articles/using-pull-requests/)
-with your changes.
+with your changes. libigl follows strict coding guidelines, please take a look at our  [style guidelines](style-guidelines.html) before submitting your pull requests.
 
 ## License
 libigl is primarily [MPL2](http://www.mozilla.org/MPL/2.0/) licensed
@@ -255,7 +259,7 @@ If you find bugs or have problems please use our [github issue tracking
 page](https://github.com/libigl/libigl/issues).
 
 ## Copyright
-2016 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan
+2017 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan
 Zhou, Sebastian Koch, Amir Vaxman, Nico Pietroni, Stefan Brugger, Kenshi Takayama, Wenzel Jakob, Nikolas De
 Giorgis, Luigi Rocca, Leonardo Sacht, Kevin Walliman, Olga Sorkine-Hornung, and others.
 

+ 62 - 0
coding-guidelines.html

@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta charset="utf-8"/>
+	<title>libigl</title>
+	<meta name="author" content="Alec Jacobson and Daniele Panozzo and others"/>
+	<link type="text/css" rel="stylesheet" href="../tutorial/style.css"/>
+<script type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
+<link rel='stylesheet' href='http://yandex.st/highlightjs/7.3/styles/default.min.css'>
+<script src='http://yandex.st/highlightjs/7.3/highlight.min.js'></script>
+<script>hljs.initHighlightingOnLoad();</script>
+</head>
+<body>
+
+<h1 id="libiglcodingtipsakahowtocodeasiggraphproject">Libigl Coding Tips (aka &#8220;How to code a SIGGRAPH project&#8221;)</h1>
+
+<p>This is a short list of coding tips that will greatly reduce your pain and suffering before (and after) the SIGGRAPH deadline.</p>
+
+<h3 id="1.serializeitall">1. Serialize it all</h3>
+
+<p>The entire state of your application should be serializable, i.e. It should be possible to save it into a binary file and reload it at any point. This drastically simplifies debugging, since you can serialize just before a crash happens and debug from that point without running your complete algorithm again. Serializing all results shown in the paper&#8217;s figures enables quicker editing iterations before (and after) the deadline. It also allows you to share your results with others that wish to compare with your method. An additional tip is to serialize the state of the application on the window close event and automatically reload it when you launch it again.</p>
+
+<h3 id="2.alwaysassert">2. Always assert</h3>
+
+<p>Even if you know what you are doing, always assert, you will be surprised. Assertion is a powerful but underused feature available in all programming languages. It is essential for writing research code since often you will have to implement algorithms that turns out to not be doing what you expect: in these cases it is important to know if the algorithm is flawed or if there is a bug in your implementation. Discarding a good idea because of a coding bug is frustrating and unfortunately common. Assertion is an ideal way to reduce the chances of introducing bugs in your code and, differently from unit testing, requires a very minor programming effort. You should use them extensively.</p>
+
+<h3 id="3.ploteverything">3. Plot everything</h3>
+
+<p>If you can visually plot the results or some intermediate steps of your algorithm, do it, even if you think your implementation is correct! It is a lot easier to find bugs or to get an intuition on an algorithm by looking at a plot than by looking at the code.</p>
+
+<h3 id="4.ifthecompilationtimeafteracodechangeismorethanfivesecondsyouaredoingitwrong">4. If the compilation time after a code change is more than five seconds, you are doing it wrong</h3>
+
+<p>You will change your code hundreds of times every day for months. Let&#8217;s say that you will change it a hundred times a day (which is a very conservative estimate): if the compilation takes one minute, you will waste almost two hours every day, just waiting! What is even worse, is that since it is only 1&#8211;2 minutes at a time, it will not even be sufficient to prepare a coffee. Spend the hour or two that is needed to get your code to compile in a few seconds, you will benefit from it in the same day already, and the time saved over an entire project will be gigantic.</p>
+
+<h3 id="5.commitoftenandwithameaningfuldescription">5. Commit often (and with a meaningful description)</h3>
+
+<p>Use a distributed version control system (git,hg), and keep the repository on a remote host. Commit often and put meaningful comments. This will serve you as an emergency backup and it will always allow you to have a running version of your code whenever your advisor is passing by and asking to see some results. She will be impressed and you will not have to quickly fix your build with your boss breathing down your neck.</p>
+
+<h3 id="6.dependenciesareevilavoidthem">6. Dependencies are evil, avoid them</h3>
+
+<p>Keep your code simple and with minimal external dependencies. Spending a day or two to code something from scratch while avoiding to use third party code is usually an investment that pays off. The more code you have in your algorithm that is not written by you, the harder debugging becomes. In particular, refrain from building your entire project on code that you do not understand to avoid bad surprises just before the deadline. If you must use code written by others, spend the time that is needed to fully understand what it does, and link it statically so that it will be easy to place breakpoints inside it.</p>
+
+<h3 id="7.globalvariablesarenotevilusethem">7. Global variables are not evil, use them</h3>
+
+<p>Global variables are often extremely useful &#8212; if you think you need one, use it. They are indeed dangerous for large projects, but you are not coding one of those, you are coding a prototype to test a research idea. I suggest to keep one single copy of your entire application state in a global variable (or a singleton class) that can be serialized (see tip 1). This variable should include everything rendered on screen and all the temporary data produced by your algorithm. This will allow you to easily access all the data in your project for plotting or debugging purposes.</p>
+
+<h3 id="8.prototypefirst">8. Prototype first</h3>
+
+<p>Don’t preemptively optimize and try to quickly write code that is clean and correct. It is common to try multiple different approaches to solve a new problem before finding the right one. This means that the majority of the code that you will write will not be used at the end of the project. While you should still write high-quality and bug-free code to make sure that your results is correct, you definitely do not want to spend time optimizing it before you are sure that is the right approach. In particular, it is helpful to learn a good prototyping language (Python, matlab) and use it for the early stages of the project and switch to (or mix it with) c++ only after finding a promising direction.</p>
+
+<h3 id="9.avoidexplicitpointers">9. Avoid explicit pointers</h3>
+
+<p>Do yourself a favor, do not use explicit pointers. If you use a language that supports explicit pointers, use them only if you really have to. And even in that case, keep them isolated in a single file and be very careful with them. Writing data inside another variable by accident might not trigger a crash, and simply produce strange artifacts that might convince you that a promising research direction does not work, while the problem lies in a nasty bug in your code. There is no reason to take that risk during prototyping, just avoid them and leave them for the end of the project in case they become necessary to optimize your code.</p>
+
+<h3 id="10.ifyourprogramcrashesfixitnow">10. If your program crashes, fix it now!</h3>
+
+<p>If your program crashes, don&#8217;t close your eyes and move on. Try to make it happen again, debug it and fix it immediately. These bugs are a nightmare to find, and the more code you add on top of a bug will just make it harder to find. If you don&#8217;t fix it, due to Murphy&#8217;s law, it will start to be problematic only a few days before the deadline and you will have no time to fix it at that point.</p>
+
+<p><em>Daniele Panozzo</em></p>
+
+</body>
+</html>

+ 42 - 0
coding-guidelines.md

@@ -0,0 +1,42 @@
+# Libigl Coding Tips (aka "How to code a SIGGRAPH project")
+
+This is a short list of coding tips that will greatly reduce your pain and suffering before (and after) the SIGGRAPH deadline.
+
+
+### 1. Serialize it all
+The entire state of your application should be serializable, i.e. It should be possible to save it into a binary file and reload it at any point. This drastically simplifies debugging, since you can serialize just before a crash happens and debug from that point without running your complete algorithm again. Serializing all results shown in the paper's figures enables quicker editing iterations before (and after) the deadline. It also allows you to share your results with others that wish to compare with your method. An additional tip is to serialize the state of the application on the window close event and automatically reload it when you launch it again.
+
+### 2. Always assert
+Even if you know what you are doing, always assert, you will be surprised. Assertion is a powerful but underused feature available in all programming languages. It is essential for writing research code since often you will have to implement algorithms that turns out to not be doing what you expect: in these cases it is important to know if the algorithm is flawed or if there is a bug in your implementation. Discarding a good idea  because of a coding bug is frustrating and unfortunately common. Assertion is an ideal way to reduce the chances of introducing bugs in your code and, differently from unit testing, requires a very minor programming effort. You should use them extensively.
+
+### 3. Plot everything
+
+If you can visually plot the results or some intermediate steps of your algorithm, do it, even if you think your implementation is correct! It is a lot easier to find bugs or to get an intuition on an algorithm by looking at a plot than by looking at the code.
+
+### 4. If the compilation time after a code change is more than five seconds, you are doing it wrong
+
+You will change your code hundreds of times every day for months. Let's say that you will change it a hundred times a day (which is a  very conservative estimate): if the compilation takes one minute, you will waste almost two hours every day, just waiting! What is even worse, is that since it is only 1-2 minutes at a time, it will not even be sufficient to prepare a coffee. Spend the hour or two that is needed to get your code to compile in a few seconds, you will benefit from it in the same day already, and the time saved over an entire project will be gigantic.
+
+### 5. Commit often (and with a meaningful description)
+
+Use a distributed version control system (git,hg), and keep the repository on a remote host. Commit often and put meaningful comments. This will serve you as an emergency backup and it will always allow you to have a running version of your code whenever your advisor is passing by and asking to see some results. She will be impressed and you will not have to quickly fix your build with your boss breathing down your neck.
+
+### 6. Dependencies are evil, avoid them
+
+Keep your code simple and with minimal external dependencies. Spending a day or two to code something from scratch while avoiding to use third party code is usually an investment that pays off. The more code you have in your algorithm that is not written by you, the harder debugging becomes. In particular, refrain from building your entire project on code that you do not understand to avoid bad surprises just before the deadline. If you must use code written by others, spend the time that is needed to fully understand what it does, and link it statically so that it will be easy to place breakpoints inside it.
+
+### 7. Global variables are not evil, use them
+
+Global variables are often extremely useful --- if you think you need one, use it. They are indeed dangerous for large projects, but you are not coding one of those, you are coding a prototype to test a research idea. I suggest to keep one single copy of your entire application state in a global variable (or a singleton class) that can be serialized (see tip 1). This variable should include everything rendered on screen and all the temporary data produced by your algorithm. This will allow you to easily access all the data in your project for plotting or debugging purposes.
+
+### 8. Prototype first
+Don’t preemptively optimize and try to quickly write code that is clean and correct. It is common to try multiple different approaches to solve a new problem before finding the right one. This means that the majority of the code that you will write will not be used at the end of the project. While you should still write high-quality and bug-free code to make sure that your results is correct, you definitely do not want to spend time optimizing it before you are sure that is the right approach. In particular, it is helpful to learn a good prototyping language (Python, matlab) and use it for the early stages of the project and switch to (or mix it with) c++ only after finding a promising direction.
+
+### 9. Avoid explicit pointers
+Do yourself a favor, do not use explicit pointers. If you use a language that supports explicit pointers, use them only if you really have to. And even in that case, keep them isolated in a single file and be very careful with them. Writing data inside another variable by accident might not trigger a crash, and simply produce strange artifacts that might convince you that a promising research direction does not work, while the problem lies in a nasty bug in your code. There is no reason to take that risk during prototyping, just avoid them and leave them for the end of the project in case they become necessary to optimize your code.
+
+### 10. If your program crashes, fix it now!
+
+If your program crashes, don't close your eyes and move on. Try to make it happen again, debug it and fix it immediately. These bugs are a nightmare to find, and the more code you add on top of a bug will just make it harder to find. If you don't fix it, due to Murphy's law, it will start to be problematic only a few days before the deadline and you will have no time to fix it at that point.
+
+_Daniele Panozzo_

+ 5 - 4
include/igl/avg_edge_length.cpp

@@ -11,12 +11,13 @@
 
 template <typename DerivedV, typename DerivedF>
 IGL_INLINE double igl::avg_edge_length(
-  const Eigen::PlainObjectBase<DerivedV>& V,
-  const Eigen::PlainObjectBase<DerivedF>& F)
+  const Eigen::MatrixBase<DerivedV>& V,
+  const Eigen::MatrixBase<DerivedF>& F)
 {
   double avg = 0;
   long int count = 0;
 
+  // Augh. Technically this is double counting interior edges...
   for (unsigned i=0;i<F.rows();++i)
   {
     for (unsigned j=0;j<F.cols();++j)
@@ -32,7 +33,7 @@ IGL_INLINE double igl::avg_edge_length(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
-template double igl::avg_edge_length<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-template double igl::avg_edge_length<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
+template double igl::avg_edge_length<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
+template double igl::avg_edge_length<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
 // generated by autoexplicit.sh
 #endif

+ 2 - 2
include/igl/avg_edge_length.h

@@ -29,8 +29,8 @@ namespace igl
   // See also: adjacency_matrix
   template <typename DerivedV, typename DerivedF>
   IGL_INLINE double avg_edge_length(
-    const Eigen::PlainObjectBase<DerivedV>& V,
-    const Eigen::PlainObjectBase<DerivedF>& F);
+    const Eigen::MatrixBase<DerivedV>& V,
+    const Eigen::MatrixBase<DerivedF>& F);
 
 }
 

+ 1 - 0
include/igl/colon.cpp

@@ -58,6 +58,7 @@ template void igl::colon<int, long, long>(int, long, Eigen::Matrix<long, -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>&);
 template void igl::colon<double, double, double, double>(double, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
+template void igl::colon<int, int, long>(int, int, Eigen::Matrix<long, -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

+ 72 - 0
include/igl/copyleft/cgal/convex_hull.cpp

@@ -0,0 +1,72 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2017 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 "convex_hull.h"
+#include "../../ismember.h"
+#include "polyhedron_to_mesh.h"
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Polyhedron_3.h>
+#include <CGAL/Surface_mesh.h>
+#include <CGAL/convex_hull_3.h>
+#include <vector>
+
+template <
+  typename DerivedV,
+  typename DerivedW,
+  typename DerivedG>
+IGL_INLINE void igl::copyleft::cgal::convex_hull(
+  const Eigen::MatrixBase<DerivedV> & V,
+  Eigen::PlainObjectBase<DerivedW> & W,
+  Eigen::PlainObjectBase<DerivedG> & G)
+{
+  typedef CGAL::Exact_predicates_inexact_constructions_kernel      K;
+  typedef K::Point_3                                              Point_3;
+  //typedef CGAL::Delaunay_triangulation_3<K>                       Delaunay;
+  //typedef Delaunay::Vertex_handle                                 Vertex_handle;
+  //typedef CGAL::Surface_mesh<Point_3>                             Surface_mesh;
+  typedef CGAL::Polyhedron_3<K>                             Polyhedron_3;
+  std::vector<Point_3> points(V.rows());
+  for(int i = 0;i<V.rows();i++)
+  {
+    points[i] = Point_3(V(i,0),V(i,1),V(i,2));
+  }
+  Polyhedron_3 poly;
+  CGAL::convex_hull_3(points.begin(),points.end(),poly);
+  assert(poly.is_pure_triangle() && "Assuming CGAL outputs a triangle mesh");
+  polyhedron_to_mesh(poly,W,G);
+}
+
+template <
+  typename DerivedV,
+  typename DerivedF>
+IGL_INLINE void igl::copyleft::cgal::convex_hull(
+  const Eigen::MatrixBase<DerivedV> & V,
+  Eigen::PlainObjectBase<DerivedF> & F)
+{
+  Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> W;
+  Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, Eigen::Dynamic> G;
+  convex_hull(V,W,G);
+  // This is a lazy way to reindex into the original mesh
+  Eigen::Matrix<bool,Eigen::Dynamic,1> I;
+  Eigen::VectorXi J;
+  igl::ismember_rows(W,V,I,J);
+  assert(I.all() && "Should find all W in V");
+  F.resizeLike(G);
+  for(int f = 0;f<G.rows();f++)
+  {
+    for(int c = 0;c<3;c++)
+    {
+      F(f,c) = J(G(f,c));
+    }
+  }
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+#endif

+ 56 - 0
include/igl/copyleft/cgal/convex_hull.h

@@ -0,0 +1,56 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2017 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_COPYLEFT_CGAL_CONVEX_HULL_H
+#define IGL_COPYLEFT_CGAL_CONVEX_HULL_H
+#include "../../igl_inline.h"
+#include <Eigen/Core>
+
+namespace igl
+{
+  namespace copyleft
+  {
+    namespace cgal
+    {
+      // Given a set of points (V), compute the convex hull as a triangle mesh (W,G)
+      // 
+      // Inputs:
+      //   V  #V by 3 list of input points
+      // Outputs:
+      //   W  #W by 3 list of convex hull points
+      //   G  #G by 3 list of triangle indices into W
+      template <
+        typename DerivedV,
+        typename DerivedW,
+        typename DerivedG>
+      IGL_INLINE void convex_hull(
+        const Eigen::MatrixBase<DerivedV> & V,
+        Eigen::PlainObjectBase<DerivedW> & W,
+        Eigen::PlainObjectBase<DerivedG> & G);
+      // Given a set of points (V), compute the convex hull as a triangle mesh (F)
+      // over input vertex set (V)
+      // 
+      // Inputs:
+      //   V  #V by 3 list of input points
+      // Outputs:
+      //   F  #F by 3 list of triangle indices into V
+      //
+      template <
+        typename DerivedV,
+        typename DerivedF>
+      IGL_INLINE void convex_hull(
+        const Eigen::MatrixBase<DerivedV> & V,
+        Eigen::PlainObjectBase<DerivedF> & F);
+    }
+  }
+}
+  
+#ifndef IGL_STATIC_LIBRARY
+#  include "convex_hull.cpp"
+#endif
+
+#endif 

+ 9 - 4
include/igl/copyleft/cgal/polyhedron_to_mesh.cpp

@@ -8,11 +8,14 @@
 #include "polyhedron_to_mesh.h"
 #include <CGAL/Polyhedron_3.h>
 
-template <typename Polyhedron>
+template <
+  typename Polyhedron,
+  typename DerivedV,
+  typename DerivedF>
 IGL_INLINE void igl::copyleft::cgal::polyhedron_to_mesh(
   const Polyhedron & poly,
-  Eigen::MatrixXd & V,
-  Eigen::MatrixXi & F)
+  Eigen::PlainObjectBase<DerivedV> & V,
+  Eigen::PlainObjectBase<DerivedF> & F)
 {
   using namespace std;
   V.resize(poly.size_of_vertices(),3);
@@ -59,6 +62,8 @@ IGL_INLINE void igl::copyleft::cgal::polyhedron_to_mesh(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 #include <CGAL/Simple_cartesian.h>
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
 #include <CGAL/Polyhedron_items_with_id_3.h>
-template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > >(CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&);
+template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::__1::allocator<int> >, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::__1::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>,CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::__1::allocator<int> >, Eigen::Matrix<double, -1, -1, 0,-1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>,CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::__1::allocator<int> > const&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0,-1, -1> >&);
 #endif

+ 6 - 3
include/igl/copyleft/cgal/polyhedron_to_mesh.h

@@ -25,11 +25,14 @@ namespace igl
       // Outputs:
       //   V  #V by 3 list of vertex positions
       //   F  #F by 3 list of triangle indices
-      template <typename Polyhedron>
+      template <
+        typename Polyhedron,
+        typename DerivedV,
+        typename DerivedF>
       IGL_INLINE void polyhedron_to_mesh(
         const Polyhedron & poly,
-        Eigen::MatrixXd & V,
-        Eigen::MatrixXi & F);
+        Eigen::PlainObjectBase<DerivedV> & V,
+        Eigen::PlainObjectBase<DerivedF> & F);
     }
   }
 }

+ 1 - 1
include/igl/dfs.cpp

@@ -56,5 +56,5 @@ IGL_INLINE void igl::dfs(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
-template void igl::dfs<int, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, unsigned long, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::dfs<int, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, const size_t, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 1 - 0
include/igl/edges.cpp

@@ -42,4 +42,5 @@ IGL_INLINE void igl::edges(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 template void igl::edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
+template void igl::edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 2 - 2
include/igl/eigs.cpp

@@ -169,8 +169,8 @@ IGL_INLINE bool igl::eigs(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template bool igl::eigs<double, double, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int> const&, unsigned long, igl::EigsType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template bool igl::eigs<double, double, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int> const&, const size_t, igl::EigsType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 #ifdef WIN32
-template bool igl::eigs<double, double, Eigen::Matrix<double,-1,-1,0,-1,-1>, Eigen::Matrix<double,-1,1,0,-1,1> >(Eigen::SparseMatrix<double,0,int> const &,Eigen::SparseMatrix<double,0,int> const &,unsigned long long, igl::EigsType, Eigen::PlainObjectBase< Eigen::Matrix<double,-1,-1,0,-1,-1> > &, Eigen::PlainObjectBase<Eigen::Matrix<double,-1,1,0,-1,1> > &);
+template bool igl::eigs<double, double, Eigen::Matrix<double,-1,-1,0,-1,-1>, Eigen::Matrix<double,-1,1,0,-1,1> >(Eigen::SparseMatrix<double,0,int> const &,Eigen::SparseMatrix<double,0,int> const &, const size_t, igl::EigsType, Eigen::PlainObjectBase< Eigen::Matrix<double,-1,-1,0,-1,-1> > &, Eigen::PlainObjectBase<Eigen::Matrix<double,-1,1,0,-1,1> > &);
 #endif
 #endif

+ 1 - 1
include/igl/extract_manifold_patches.cpp

@@ -92,6 +92,6 @@ IGL_INLINE size_t igl::extract_manifold_patches(
 
 #ifdef IGL_STATIC_LIBRARY
 #ifndef WIN32
-template unsigned long igl::extract_manifold_patches<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template size_t igl::extract_manifold_patches<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, unsigned long, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<std::vector<unsigned long, std::allocator<unsigned long> >, std::allocator<std::vector<unsigned long, std::allocator<unsigned long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif
 #endif

+ 10 - 8
include/igl/ismember.cpp

@@ -18,8 +18,8 @@ template <
   typename DerivedIA,
   typename DerivedLOCB>
 IGL_INLINE void igl::ismember(
-  const Eigen::PlainObjectBase<DerivedA> & A,
-  const Eigen::PlainObjectBase<DerivedB> & B,
+  const Eigen::MatrixBase<DerivedA> & A,
+  const Eigen::MatrixBase<DerivedB> & B,
   Eigen::PlainObjectBase<DerivedIA> & IA,
   Eigen::PlainObjectBase<DerivedLOCB> & LOCB)
 {
@@ -42,8 +42,8 @@ IGL_INLINE void igl::ismember(
   // Get rid of any duplicates
   typedef Matrix<typename DerivedA::Scalar,Dynamic,1> VectorA;
   typedef Matrix<typename DerivedB::Scalar,Dynamic,1> VectorB;
-  const VectorA vA(Eigen::Map<const VectorA>(A.data(), A.cols()*A.rows(),1));
-  const VectorB vB(Eigen::Map<const VectorB>(B.data(), B.cols()*B.rows(),1));
+  const VectorA vA(Eigen::Map<const VectorA>(DerivedA(A).data(), A.cols()*A.rows(),1));
+  const VectorB vB(Eigen::Map<const VectorB>(DerivedB(B).data(), B.cols()*B.rows(),1));
   VectorA uA;
   VectorB uB;
   Eigen::Matrix<typename DerivedA::Index,Dynamic,1> uIA,uIuA,uIB,uIuB;
@@ -97,8 +97,8 @@ template <
   typename DerivedIA,
   typename DerivedLOCB>
 IGL_INLINE void igl::ismember_rows(
-  const Eigen::PlainObjectBase<DerivedA> & A,
-  const Eigen::PlainObjectBase<DerivedB> & B,
+  const Eigen::MatrixBase<DerivedA> & A,
+  const Eigen::MatrixBase<DerivedB> & B,
   Eigen::PlainObjectBase<DerivedIA> & IA,
   Eigen::PlainObjectBase<DerivedLOCB> & LOCB)
 {
@@ -174,6 +174,8 @@ IGL_INLINE void igl::ismember_rows(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template void igl::ismember<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::ismember_rows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Array<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::ismember<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::ismember_rows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Array<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::ismember_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::ismember_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 4 - 4
include/igl/ismember.h

@@ -28,8 +28,8 @@ namespace igl
     typename DerivedIA,
     typename DerivedLOCB>
   IGL_INLINE void ismember(
-    const Eigen::PlainObjectBase<DerivedA> & A,
-    const Eigen::PlainObjectBase<DerivedB> & B,
+    const Eigen::MatrixBase<DerivedA> & A,
+    const Eigen::MatrixBase<DerivedB> & B,
     Eigen::PlainObjectBase<DerivedIA> & IA,
     Eigen::PlainObjectBase<DerivedLOCB> & LOCB);
   template <
@@ -38,8 +38,8 @@ namespace igl
     typename DerivedIA,
     typename DerivedLOCB>
   IGL_INLINE void ismember_rows(
-    const Eigen::PlainObjectBase<DerivedA> & A,
-    const Eigen::PlainObjectBase<DerivedB> & B,
+    const Eigen::MatrixBase<DerivedA> & A,
+    const Eigen::MatrixBase<DerivedB> & B,
     Eigen::PlainObjectBase<DerivedIA> & IA,
     Eigen::PlainObjectBase<DerivedLOCB> & LOCB);
 

+ 2 - 0
include/igl/list_to_matrix.cpp

@@ -119,6 +119,8 @@ IGL_INLINE bool igl::list_to_matrix(const std::vector<T > & V,Eigen::PlainObject
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template bool igl::list_to_matrix<long, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
 template bool igl::list_to_matrix<bool, Eigen::Array<bool, -1, 3, 0, -1, 3> >(std::vector<std::vector<bool, std::allocator<bool> >, std::allocator<std::vector<bool, std::allocator<bool> > > > const&, Eigen::PlainObjectBase<Eigen::Array<bool, -1, 3, 0, -1, 3> >&);
 // generated by autoexplicit.sh
 template bool igl::list_to_matrix<double, Eigen::Matrix<double, -1, -1, 1, -1, -1> >(std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&);

+ 2 - 0
include/igl/max_size.cpp

@@ -27,6 +27,8 @@ IGL_INLINE int igl::max_size(const std::vector<T> & V)
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template int igl::max_size<std::vector<long, std::allocator<long> > >(std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&);
+// generated by autoexplicit.sh
 template int igl::max_size<std::vector<unsigned int, std::allocator<unsigned int> > >(std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > > const&);
 // generated by autoexplicit.sh
 template int igl::max_size<std::vector<int, std::allocator<int> > >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&);

+ 2 - 0
include/igl/min_size.cpp

@@ -33,6 +33,8 @@ IGL_INLINE int igl::min_size(const std::vector<T> & V)
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template int igl::min_size<std::vector<long, std::allocator<long> > >(std::vector<std::vector<long, std::allocator<long> >, std::allocator<std::vector<long, std::allocator<long> > > > const&);
+// generated by autoexplicit.sh
 template int igl::min_size<std::vector<unsigned int, std::allocator<unsigned int> > >(std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > > const&);
 // generated by autoexplicit.sh
 template int igl::min_size<std::vector<int, std::allocator<int> > >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&);

+ 2 - 0
include/igl/mosek/mosek_linprog.cpp

@@ -26,7 +26,9 @@ IGL_INLINE bool igl::mosek::mosek_linprog(
   // Create the MOSEK environment
   mosek_guarded(MSK_makeenv(&env,NULL));
   // initialize mosek environment
+#if MSK_VERSION_MAJOR <= 7
   mosek_guarded(MSK_initenv(env));
+#endif
   const bool ret = mosek_linprog(c,A,lc,uc,lx,ux,env,x);
   MSK_deleteenv(&env);
   return ret;

+ 2 - 0
include/igl/mosek/mosek_quadprog.cpp

@@ -111,7 +111,9 @@ IGL_INLINE bool igl::mosek::mosek_quadprog(
   //}
   //mosek_guarded(MSK_linkfunctoenvstream(env,MSK_STREAM_LOG,NULL,printstr));
   // initialize mosek environment
+#if MSK_VERSION_MAJOR <= 7
   mosek_guarded(MSK_initenv(env));
+#endif
   // Create the optimization task
   mosek_guarded(MSK_maketask(env,m,n,&task));
   verbose("Creating task with %ld linear constraints and %ld variables...\n",m,n);

+ 4 - 0
include/igl/readPLY.cpp

@@ -214,4 +214,8 @@ IGL_INLINE bool igl::readPLY(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 template bool igl::readPLY<double, int, double, double>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&);
+
+template bool igl::readPLY<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>, Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic>, Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>, Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> > &, Eigen::PlainObjectBase<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> > &, Eigen::PlainObjectBase<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> > &);
+
+template bool igl::readPLY<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>, Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> > &, Eigen::PlainObjectBase<Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> > &);
 #endif

+ 1 - 1
include/igl/remove_unreferenced.cpp

@@ -105,7 +105,7 @@ template void igl::remove_unreferenced<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Ei
 // generated by autoexplicit.sh
 template void igl::remove_unreferenced<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
-template void igl::remove_unreferenced<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(unsigned long, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+//template void igl::remove_unreferenced<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(unsigned long, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
 template void igl::remove_unreferenced<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::remove_unreferenced<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);

+ 3 - 3
include/igl/reorder.cpp

@@ -34,8 +34,8 @@ IGL_INLINE void igl::reorder(
 template void igl::reorder<double>(std::vector<double, std::allocator<double> > const&, std::vector<size_t, std::allocator<size_t> > const&, std::vector<double, std::allocator<double> >&);
 template void igl::reorder<int>(std::vector<int, std::allocator<int> > const&, std::vector<size_t, std::allocator<size_t> > const&, std::vector<int, std::allocator<int> >&);
 #  ifndef IGL_NO_EIGEN
-  template void igl::reorder<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > >(std::vector<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > >&);
-  template void igl::reorder<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(std::vector<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > >&);
+  template void igl::reorder<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > >(std::vector<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > > const&, std::vector<size_t, std::allocator<size_t> > const&, std::vector<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > >&);
+  template void igl::reorder<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(std::vector<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > const&, std::vector<size_t, std::allocator<size_t> > const&, std::vector<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<igl::SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > >&);
 #  endif
-template void igl::reorder<long>(std::vector<long, std::allocator<long> > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::vector<long, std::allocator<long> >&);
+template void igl::reorder<long>(std::vector<long, std::allocator<long> > const&, std::vector<size_t, std::allocator<size_t> > const&, std::vector<long, std::allocator<long> >&);
 #endif

+ 1 - 1
include/igl/sort.cpp

@@ -331,7 +331,7 @@ template void igl::sort_new<Eigen::Matrix<int, 1, 6, 1, 1, 6>, Eigen::Matrix<int
 template void igl::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
 template void igl::sort<Eigen::Matrix<double, -1, 4, 0, -1, 4>, Eigen::Matrix<double, -1, 4, 0, -1, 4>, Eigen::Matrix<int, -1, 4, 0, -1, 4> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 4, 0, -1, 4> >&);
 template void igl::sort<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::sort<long>(std::vector<long, std::allocator<long> > const&, bool, std::vector<long, std::allocator<long> >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
+template void igl::sort<long>(std::vector<long, std::allocator<long> > const&, bool, std::vector<long, std::allocator<long> >&, std::vector<size_t, std::allocator<size_t> >&);
 template void igl::sort<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::sort<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::sort<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);

+ 3 - 0
include/igl/sortrows.cpp

@@ -108,6 +108,8 @@ IGL_INLINE void igl::sortrows(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::sortrows<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::sortrows<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
 template void igl::sortrows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
@@ -118,4 +120,5 @@ template void igl::sortrows<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matri
 template void igl::sortrows<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::sortrows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::sortrows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::sortrows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 #endif

+ 3 - 3
include/igl/sparse.cpp

@@ -109,11 +109,11 @@ IGL_INLINE Eigen::SparseMatrix<typename DerivedD::Scalar > igl::sparse(
 // Explicit template instantiation
 // generated by autoexplicit.sh
 #ifndef WIN32
-template void igl::sparse<Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 2, 0, -1, 2> >, bool>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 2, 0, -1, 2> > const&, unsigned long, unsigned long, Eigen::SparseMatrix<bool, 0, int>&);
-template void igl::sparse<Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 3, 0, -1, 3> >, bool>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 3, 0, -1, 3> > const&, unsigned long, unsigned long, Eigen::SparseMatrix<bool, 0, int>&);
+//template void igl::sparse<Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 2, 0, -1, 2> >, bool>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 2, 0, -1, 2> > const&, unsigned long, unsigned long, Eigen::SparseMatrix<bool, 0, int>&);
+//template void igl::sparse<Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 3, 0, -1, 3> >, bool>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 3, 0, -1, 3> > const&, unsigned long, unsigned long, Eigen::SparseMatrix<bool, 0, int>&);
 #if EIGEN_VERSION_AT_LEAST(3,3,0)
 #else
-template void igl::sparse<Eigen::CwiseNullaryOp<Eigen::internal::linspaced_op<int, true>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 1, 0, -1, 1> >, bool>(Eigen::CwiseNullaryOp<Eigen::internal::linspaced_op<int, true>, Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 1, 0, -1, 1> > const&, unsigned long, unsigned long, Eigen::SparseMatrix<bool, 0, int>&);
+//template void igl::sparse<Eigen::CwiseNullaryOp<Eigen::internal::linspaced_op<int, true>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 1, 0, -1, 1> >, bool>(Eigen::CwiseNullaryOp<Eigen::internal::linspaced_op<int, true>, Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<bool>, Eigen::Array<bool, -1, 1, 0, -1, 1> > const&, unsigned long, unsigned long, Eigen::SparseMatrix<bool, 0, int>&);
 #endif
 #endif
 

+ 3 - 1
include/igl/unique.cpp

@@ -275,7 +275,7 @@ template void igl::unique<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<i
 template void igl::unique<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 template void igl::unique<int>(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&);
-template void igl::unique<long>(std::vector<long, std::allocator<long> > const&, std::vector<long, std::allocator<long> >&, std::vector<unsigned long, std::allocator<unsigned long> >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
+template void igl::unique<long>(std::vector<long, std::allocator<long> > const&, std::vector<long, std::allocator<long> >&, std::vector<size_t, std::allocator<size_t> >&, std::vector<size_t, std::allocator<size_t> >&);
 template void igl::unique_rows<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::unique_rows<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::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::unique<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
@@ -293,4 +293,6 @@ template void __cdecl igl::unique_rows<class Eigen::Matrix<int, -1, -1, 0, -1, -
 
 template void igl::unique_rows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 template void igl::unique_rows<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::unique_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
+template void igl::unique_rows<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
 #endif

+ 35 - 11
include/igl/viewer/Viewer.cpp

@@ -154,7 +154,7 @@ static void glfw_window_size(GLFWwindow* window, int width, int height)
   int w = width*highdpi;
   int h = height*highdpi;
 
-  __viewer->resize(w, h);
+  __viewer->post_resize(w, h);
 
   // TODO: repositioning of the nanogui
 }
@@ -278,6 +278,8 @@ namespace viewer
 
   IGL_INLINE Viewer::Viewer()
   {
+    window = nullptr;
+
 #ifdef IGL_VIEWER_WITH_NANOGUI
     ngui = nullptr;
     screen = nullptr;
@@ -322,8 +324,8 @@ namespace viewer
   O,o     Toggle orthographic/perspective projection
   T,t     Toggle filled faces
   Z       Snap to canonical view
-  [,]     Toggle between rotation control types (e.g. trackball, two-axis
-          valuator with fixed up))"
+  [,]     Toggle between rotation control types (trackball, two-axis
+          valuator with fixed up, 2D mode with no rotation))"
 #ifdef IGL_VIEWER_WITH_NANOGUI
 		R"(
   ;       Toggle vertex labels
@@ -537,13 +539,12 @@ namespace viewer
       case ']':
       {
         if(core.rotation_type == ViewerCore::ROTATION_TYPE_TRACKBALL)
-        {
-          core.set_rotation_type(
-            ViewerCore::ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP);
-        }else
-        {
+          core.set_rotation_type(ViewerCore::ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP);
+        else if (core.rotation_type == ViewerCore::ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP)
+          core.set_rotation_type(ViewerCore::ROTATION_TYPE_NO_ROTATION);
+        else
           core.set_rotation_type(ViewerCore::ROTATION_TYPE_TRACKBALL);
-        }
+
         return true;
       }
 #ifdef IGL_VIEWER_WITH_NANOGUI
@@ -626,7 +627,11 @@ namespace viewer
     switch (button)
     {
       case MouseButton::Left:
-        mouse_mode = MouseMode::Rotation;
+        if (core.rotation_type == ViewerCore::ROTATION_TYPE_NO_ROTATION) {
+          mouse_mode = MouseMode::Translation;
+        } else {
+          mouse_mode = MouseMode::Rotation;
+        }
         break;
 
       case MouseButton::Right:
@@ -687,6 +692,8 @@ namespace viewer
           {
             default:
               assert(false && "Unknown rotation type");
+            case ViewerCore::ROTATION_TYPE_NO_ROTATION:
+              break;
             case ViewerCore::ROTATION_TYPE_TRACKBALL:
               igl::trackball(
                 core.viewport(2),
@@ -841,8 +848,21 @@ namespace viewer
   }
 
   IGL_INLINE void Viewer::resize(int w,int h)
+  {
+    if (window) {
+      glfwSetWindowSize(window, w/highdpi, h/highdpi);
+    } else {
+      post_resize(w, h);
+    }
+  }
+
+  IGL_INLINE void Viewer::post_resize(int w,int h)
   {
     core.viewport = Eigen::Vector4f(0,0,w,h);
+    for (unsigned int i = 0; i<plugins.size(); ++i)
+    {
+      plugins[i]->post_resize(w, h);
+    }
   }
 
   IGL_INLINE void Viewer::snap_to_canonical_quaternion()
@@ -895,7 +915,11 @@ namespace viewer
     }
     else
     {
-      window = glfwCreateWindow(1280,800,"libigl viewer",nullptr,nullptr);
+      if (core.viewport.tail<2>().any()) {
+        window = glfwCreateWindow(core.viewport(2),core.viewport(3),"libigl viewer",nullptr,nullptr);
+      } else {
+        window = glfwCreateWindow(1280,800,"libigl viewer",nullptr,nullptr);
+      }
     }
 
     if (!window)

+ 2 - 1
include/igl/viewer/Viewer.h

@@ -119,7 +119,8 @@ namespace viewer
     IGL_INLINE void draw();
 
     // OpenGL context resize
-    IGL_INLINE void resize(int w,int h);
+    IGL_INLINE void resize(int w,int h); // explicitly set window size
+    IGL_INLINE void post_resize(int w,int h); // external resize due to user interaction
 
     // Helper functions
     IGL_INLINE void snap_to_canonical_quaternion();

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

@@ -14,6 +14,7 @@
 #include <igl/ortho.h>
 #include <igl/massmatrix.h>
 #include <igl/barycenter.h>
+#include <igl/PI.h>
 #include <Eigen/Geometry>
 #include <iostream>
 
@@ -135,12 +136,12 @@ IGL_INLINE void igl::viewer::ViewerCore::draw(
     if (orthographic)
     {
       float length = (camera_eye - camera_center).norm();
-      float h = tan(camera_view_angle/360.0 * M_PI) * (length);
+      float h = tan(camera_view_angle/360.0 * igl::PI) * (length);
       ortho(-h*width/height, h*width/height, -h, h, camera_dnear, camera_dfar,proj);
     }
     else
     {
-      float fH = tan(camera_view_angle / 360.0 * M_PI) * camera_dnear;
+      float fH = tan(camera_view_angle / 360.0 * igl::PI) * camera_dnear;
       float fW = fH * (double)width/(double)height;
       frustum(-fW, fW, -fH, fH, camera_dnear, camera_dfar,proj);
     }
@@ -432,6 +433,8 @@ IGL_INLINE igl::viewer::ViewerCore::ViewerCore()
   line_width = 0.5f;
   is_animating = false;
   animation_max_fps = 30.;
+
+  viewport.setZero();
 }
 
 IGL_INLINE void igl::viewer::ViewerCore::init()

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

@@ -88,7 +88,8 @@ public:
   {
     ROTATION_TYPE_TRACKBALL = 0,
     ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP = 1,
-    NUM_ROTATION_TYPES = 2
+    ROTATION_TYPE_NO_ROTATION = 2,
+    NUM_ROTATION_TYPES = 3
   };
   IGL_INLINE void set_rotation_type(const RotationType & value);
 

+ 2 - 2
include/igl/viewer/ViewerData.cpp

@@ -344,7 +344,7 @@ IGL_INLINE void igl::viewer::ViewerData::compute_normals()
   dirty |= DIRTY_NORMAL;
 }
 
-IGL_INLINE void igl::viewer::ViewerData::uniform_colors(Eigen::Vector3d ambient, Eigen::Vector3d diffuse, Eigen::Vector3d specular)
+IGL_INLINE void igl::viewer::ViewerData::uniform_colors(const Eigen::Vector3d& ambient, const Eigen::Vector3d& diffuse, const Eigen::Vector3d& specular)
 {
   Eigen::Vector4d ambient4;
   Eigen::Vector4d diffuse4;
@@ -357,7 +357,7 @@ IGL_INLINE void igl::viewer::ViewerData::uniform_colors(Eigen::Vector3d ambient,
   uniform_colors(ambient4,diffuse4,specular4);
 }
 
-IGL_INLINE void igl::viewer::ViewerData::uniform_colors(Eigen::Vector4d ambient, Eigen::Vector4d diffuse, Eigen::Vector4d specular)
+IGL_INLINE void igl::viewer::ViewerData::uniform_colors(const Eigen::Vector4d& ambient, const Eigen::Vector4d& diffuse, const Eigen::Vector4d& specular)
 {
   V_material_ambient.resize(V.rows(),4);
   V_material_diffuse.resize(V.rows(),4);

+ 6 - 6
include/igl/viewer/ViewerData.h

@@ -123,15 +123,15 @@ public:
 
   // Assigns uniform colors to all faces/vertices
   IGL_INLINE void uniform_colors(
-    Eigen::Vector3d ambient,
-    Eigen::Vector3d diffuse,
-    Eigen::Vector3d specular);
+    const Eigen::Vector3d& diffuse,
+    const Eigen::Vector3d& ambient,
+    const Eigen::Vector3d& specular);
 
   // Assigns uniform colors to all faces/vertices
   IGL_INLINE void uniform_colors(
-    Eigen::Vector4d ambient,
-    Eigen::Vector4d diffuse,
-    Eigen::Vector4d specular);
+    const Eigen::Vector4d& ambient,
+    const Eigen::Vector4d& diffuse,
+    const Eigen::Vector4d& specular);
 
   // Generates a default grid texture
   IGL_INLINE void grid_texture();

+ 5 - 0
include/igl/viewer/ViewerPlugin.h

@@ -96,6 +96,11 @@ public:
     return false;
   }
 
+  // This function is called after the window has been resized
+  IGL_INLINE virtual void post_resize(int w, int h)
+  {
+  }
+
   // This function is called when the mouse button is pressed
   // - button can be GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON or GLUT_RIGHT_BUTTON
   // - modifiers is a bitfield that might one or more of the following bits Preview3D::NO_KEY, Preview3D::SHIFT, Preview3D::CTRL, Preview3D::ALT;

+ 63 - 4
include/igl/writeWRL.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// 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 "writeWRL.h"
 #include <iostream>
@@ -53,6 +53,64 @@ ccw TRUE
   return true;
 }
 
+// write mesh and colors-by-vertex to an ascii off file
+template <typename DerivedV, typename DerivedF, typename DerivedC>
+IGL_INLINE bool igl::writeWRL(
+  const std::string & str,
+  const Eigen::PlainObjectBase<DerivedV> & V,
+  const Eigen::PlainObjectBase<DerivedF> & F,
+  const Eigen::PlainObjectBase<DerivedC> & C)
+{
+  using namespace std;
+  using namespace Eigen;
+  assert(V.cols() == 3 && "V should have 3 columns");
+  assert(F.cols() == 3 && "F should have 3 columns");
+  ofstream s(str);
+  if(!s.is_open())
+  {
+    cerr<<"IOError: writeWRL() could not open "<<str<<endl;
+    return false;
+  }
+  // Append column of -1 to F
+  Matrix<typename DerivedF::Scalar,Dynamic,4> FF(F.rows(),4);
+  FF.leftCols(3) = F;
+  FF.col(3).setConstant(-1);
+
+
+  //Check if RGB values are in the range [0..1] or [0..255]
+  double rgbScale = (C.maxCoeff() <= 1.0)?1.0:1.0/255.0;
+  Eigen::MatrixXd RGB = rgbScale * C;
+
+  s<<R"(
+DEF default Transform {
+translation 0 0 0
+children [
+Shape {
+geometry DEF default-FACES IndexedFaceSet {
+ccw TRUE
+)"<<
+    V.format(
+      IOFormat(
+        FullPrecision,
+        DontAlignCols,
+        " ",",\n","","",
+        "coord DEF default-COORD Coordinate { point [ \n","]\n}\n"))<<
+    FF.format(
+      IOFormat(
+        FullPrecision,
+        DontAlignCols,
+        ",","\n","","",
+        "coordIndex [ \n"," ]\n"))<<
+    RGB.format(
+      IOFormat(
+        FullPrecision,
+        DontAlignCols,
+        ",","\n","","",
+        "colorPerVertex TRUE\ncolor Color { color [ \n"," ] }\n"))<<
+    "}\n}\n]\n}\n";
+  return true;
+}
+
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
@@ -60,4 +118,5 @@ template bool igl::writeWRL<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matri
 // generated by autoexplicit.sh
 template bool igl::writeWRL<Eigen::Matrix<double, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 8, 3, 0, 8, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&);
 template bool igl::writeWRL<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
+template bool igl::writeWRL<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > 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&);
 #endif

+ 19 - 4
include/igl/writeWRL.h

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// 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_WRITE_WRL_H
 #define IGL_WRITE_WRL_H
@@ -24,6 +24,21 @@ namespace igl
     const std::string & str,
     const Eigen::PlainObjectBase<DerivedV> & V,
     const Eigen::PlainObjectBase<DerivedF> & F);
+
+  // Write mesh to a .wrl file
+  //
+  // Inputs:
+  //   str  path to .wrl file
+  //   V  #V by 3 list of vertex positions
+  //   F  #F by 3 list of triangle indices
+  //   C  double matrix of rgb values per vertex #V by 3
+  // Returns true iff succes
+  template <typename DerivedV, typename DerivedF, typename DerivedC>
+  IGL_INLINE bool writeWRL(
+    const std::string & str,
+    const Eigen::PlainObjectBase<DerivedV> & V,
+    const Eigen::PlainObjectBase<DerivedF> & F,
+    const Eigen::PlainObjectBase<DerivedC> & C);
 }
 #ifndef IGL_STATIC_LIBRARY
 #include "writeWRL.cpp"

+ 15 - 10
index.html

@@ -15,7 +15,7 @@
 <h1 id="libigl-asimplecgeometryprocessinglibrary">libigl - A simple C++ geometry processing library</h1>
 
 <p><a href="https://travis-ci.org/libigl/libigl"><img src="https://travis-ci.org/libigl/libigl.svg?branch=master" alt="Build Status" /></a>
-<a href="https://ci.appveyor.com/project/danielepanozzo/libigl-6hjk1"><img src="https://ci.appveyor.com/api/projects/status/mf3t9rnhco0vhly8?svg=true" alt="Build status" /></a>
+<a href="https://ci.appveyor.com/project/danielepanozzo/libigl-6hjk1/branch/master"><img src="https://ci.appveyor.com/api/projects/status/mf3t9rnhco0vhly8/branch/master?svg=true" alt="Build status" /></a>
 <img src="libigl-teaser.png" alt="" /></p>
 
 <p><a href="https://github.com/libigl/libigl/">https://github.com/libigl/libigl/</a></p>
@@ -59,10 +59,14 @@ and Windows with Visual Studio 2015 Community Edition.</p>
 <p>As of version 1.0, libigl includes an introductory
 <a href="http://libigl.github.io/libigl/tutorial/tutorial.html">tutorial</a> that covers many functionalities.</p>
 
-<h2 id="libiglexampleproject">libigl example project</h2>
+<h2 id="libiglexampleproject">libigl Example Project</h2>
 
 <p>We provide a <a href="https://github.com/libigl/libigl-example-project">blank project example</a> showing how to use libigl and cmake. Feel free and encouraged to copy or fork this project as a way of starting a new personal project using libigl.</p>
 
+<h2 id="codingguidelinesandtips">Coding Guidelines and Tips</h2>
+
+<p>libigl follows strict coding guidelines, please take a look <a href="http://libigl.github.io/libigl/style-guidelines.html">here</a> before submitting your pull requests. We also have a set of <a href="http://libigl.github.io/libigl/coding-guidelines.html">general coding tips</a> on how to code a geometry processing research project.</p>
+
 <h2 id="installation">Installation</h2>
 
 <p>Libigl is a <strong>header-only</strong> library. You do <strong>not</strong> need to build anything to
@@ -112,7 +116,7 @@ libigl depends only on the <a href="http://eigen.tuxfamily.org">Eigen</a> librar
 
 <p>For more information see our <a href="tutorial/tutorial.html">tutorial</a>.</p>
 
-<h3 id="optionaldependencies">Optional dependencies</h3>
+<h3 id="optionaldependencies">Optional Dependencies</h3>
 
 <p>Libigl compartmentalizes its <strong>optional</strong> dependences via its directory
 organization in the <code>include/</code> folder. All header files located <em>directly</em> in
@@ -120,7 +124,7 @@ the <code>include/igl/</code> folder have only stl and Eigen as dependencies. Fo
 all of the headers that depend on CGAL are located in <code>include/igl/cgal</code>. For a
 full list of <em>optional</em> dependencies check <code>optional/CMakeLists.txt</code>.</p>
 
-<h3 id="gccandtheoptionalcgaldependency">GCC and the optional CGAL dependency</h3>
+<h3 id="gccandtheoptionalcgaldependency">GCC and the Optional CGAL Dependency</h3>
 
 <p>The <code>include/igl/cgal/*.h</code> headers depend on CGAL. It has come to our attention
 that CGAL does not work properly with GCC 4.8. To the best of our knowledge,
@@ -178,16 +182,16 @@ subrepos:</p>
 git submodule update --recursive
 </code></pre>
 
-<h2 id="unittesting">Unit testing</h2>
+<h2 id="unittesting">Unit Testing</h2>
 
 <p>Libigl maintains <a href="https://github.com/libigl/libigl-unit-tests">separate
 repository</a> for unit testing.</p>
 
-<h2 id="howtocontribute">How to contribute</h2>
+<h2 id="howtocontribute">How to Contribute</h2>
 
 <p>If you are interested in joining development, please fork the repository and
 submit a <a href="https://help.github.com/articles/using-pull-requests/">pull request</a>
-with your changes.</p>
+with your changes. libigl follows strict coding guidelines, please take a look at our <a href="style-guidelines.html">style guidelines</a> before submitting your pull requests.</p>
 
 <h2 id="license">License</h2>
 
@@ -232,7 +236,8 @@ few labs/companies/institutions using libigl:</p>
 <li>ETH Zurich, <a href="http://igl.ethz.ch/">Interactive Geometry Lab</a> and <a href="http://ait.inf.ethz.ch/">Advanced Technologies Lab</a>, Swizterland</li>
 <li>George Mason University, <a href="http://cs.gmu.edu/~ygingold/">CraGL</a>, USA</li>
 <li><a href="http://www.ust.hk/">Hong Kong University of Science and Technology</a>, Hong Kong</li>
-<li>[Inria](Université Grenoble Alpes), France</li>
+<li><a href="https://www.inria.fr/centre/grenoble/">Inria, Université Grenoble Alpes</a>, France</li>
+<li><a href="http://english.jiangnan.edu.cn">Jiangnan university</a>, China</li>
 <li><a href="http://www.nii.ac.jp/en/">National Institute of Informatics</a>, Japan</li>
 <li>New York University, <a href="http://mrl.nyu.edu/">Media Research Lab</a>, USA</li>
 <li>NYUPoly, <a href="http://game.engineering.nyu.edu/">Game Innovation Lab</a>, USA</li>
@@ -257,7 +262,7 @@ few labs/companies/institutions using libigl:</p>
 
 <h2 id="contact">Contact</h2>
 
-<p>Libigl is a group endeavor led by <a href="http://www.cs.columbia.edu/~jacobson/">Alec
+<p>Libigl is a group endeavor led by <a href="http://www.cs.toronto.edu/~jacobson/">Alec
 Jacobson</a> and <a href="http://cs.nyu.edu/~panozzo/">Daniele
 Panozzo</a>. Please <a href="&#109;&#97;&#105;&#108;&#x74;&#111;&#x3a;&#x61;&#x6c;&#101;&#x63;&#x6a;&#x61;&#x63;&#111;&#98;&#115;&#111;&#110;&#64;&#103;&#109;&#x61;&#105;&#108;&#x2e;&#x63;&#x6f;&#x6d;&#44;&#x64;&#x61;&#110;&#105;&#101;&#x6c;&#101;&#x2e;&#x70;&#x61;&#110;&#x6f;&#122;&#x7a;&#x6f;&#64;&#x67;&#x6d;&#x61;&#x69;&#x6c;&#x2e;&#99;&#x6f;&#x6d;">&#99;&#x6f;&#x6e;&#116;&#x61;&#99;&#x74;
 &#117;&#115;</a> if you have
@@ -274,7 +279,7 @@ page</a>.</p>
 
 <h2 id="copyright">Copyright</h2>
 
-<p>2016 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan
+<p>2017 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan
 Zhou, Sebastian Koch, Amir Vaxman, Nico Pietroni, Stefan Brugger, Kenshi Takayama, Wenzel Jakob, Nikolas De
 Giorgis, Luigi Rocca, Leonardo Sacht, Kevin Walliman, Olga Sorkine-Hornung, and others.</p>
 

+ 9 - 9
optional/index.html

@@ -146,12 +146,12 @@ containing Eigen matrices and other standard simple data-structures.</p>
 <pre><code>git archive -prefix=libigl/ -o libigl.zip master
 </code></pre>
 
-<h2 id="explicitspecializationoftemplatedfunctions">Explicit specialization of templated functions</h2>
+<h2 id="explicitinstantiationsoftemplatedfunctions">Explicit instantiations of templated functions</h2>
 
 <p>Special care must be taken by the developers of each function and
 class in the libigl library that uses C++ templates. If this function
 is intended to be compiled into the statically linked libigl library
-then function is only compiled for each <i>explicitly</i> specialized
+then function is only compiled for each <i>explicitly</i> instantiated
 declaration. These should be added at the bottom of the corresponding
 .cpp file surrounded by a</p>
 
@@ -159,8 +159,8 @@ declaration. These should be added at the bottom of the corresponding
 </code></pre>
 
 <p>Of course, a developer may not know ahead of time which
-specializations should be explicitly included in the igl static lib.
-One way to find out is to add one explicit specialization for each
+instantiations should be explicitly included in the igl static lib.
+One way to find out is to add one explicit instantiation for each
 call in one&#8217;s own project. This only ever needs to be done once for
 each template.</p>
 
@@ -168,7 +168,7 @@ each template.</p>
 output.</p>
 
 <p>Supposed for example we have compiled the igl static lib, including the
-cat.h and cat.cpp functions, without any explicit instanciation. Say
+cat.h and cat.cpp functions, without any explicit instantiation. Say
 using the makefile in the <code>libigl</code> directory:</p>
 
 <pre><code>cd $LIBIGL
@@ -193,13 +193,13 @@ all. Just copy the first part in quotes</p>
 </code></pre>
 
 <p>, then append it
-to the list of explicit template specializations at the end of
+to the list of explicit template instantiations at the end of
 <code>cat.cpp</code> after the word
 <strong>template</strong> and followed by a semi-colon.
 Like this:</p>
 
 <pre><code>#ifdef IGL_STATIC_LIBRARY
-// Explicit template specialization
+// Explicit template instantiation
 template Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; igl::cat&lt;Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; &gt;(int, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;, Eigen::Matrix&lt;int, -1, -1, 0, -1, -1&gt; const&amp;);
 #endif
 </code></pre>
@@ -215,7 +215,7 @@ process until no more symbols are undefined.</p>
 
 <p><code>It may be useful to check that you code compiles with
 no errors first using the headers-only version to be sure that all errors are from missing template
-specializations.</code></p>
+instantiations.</code></p>
 
 <p>If you&#8217;re using make then the following command will
 reveal each missing symbol on its own line:</p>
@@ -225,7 +225,7 @@ reveal each missing symbol on its own line:</p>
 
 <p>Alternatively you can use the <code>autoexplicit.sh</code> function
 which (for well organized .h/.cpp pairs in libigl) automatically
-create explicit instanciations from your compiler&#8217;s error messages.
+create explicit instantiations from your compiler&#8217;s error messages.
 Repeat this process until convergence:</p>
 
 <pre><code>cd /to/your/project

+ 3 - 3
python/CMakeLists.txt

@@ -188,7 +188,7 @@ elseif (UNIX)
     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)
+      add_custom_command(TARGET pyigl POST_BUILD COMMAND strip -u -r ${PROJECT_SOURCE_DIR}/pyigl.so)
     endif()
   else()
 
@@ -198,7 +198,7 @@ elseif (UNIX)
     endif()
 
     if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
-      add_custom_command(TARGET pyigl POST_BUILD COMMAND strip ${CMAKE_CURRENT_BINARY_DIR}/../pyigl.so)
+      add_custom_command(TARGET pyigl POST_BUILD COMMAND strip ${PROJECT_SOURCE_DIR}/pyigl.so)
     endif()
   endif()
 endif()
@@ -209,7 +209,7 @@ if (LIBIGL_WITH_PYTHON AND LIBIGL_WITH_NANOGUI)
   add_custom_target(copy ALL)
   add_custom_command(
         TARGET copy
-        COMMAND ${CMAKE_COMMAND} -E copy ${NANOGUI_LIB} ${CMAKE_CURRENT_BINARY_DIR}/../
+        COMMAND ${CMAKE_COMMAND} -E copy ${NANOGUI_LIB} ${PROJECT_SOURCE_DIR}
         )
   add_dependencies(copy pyigl)
 

+ 8 - 0
python/py_doc.cpp

@@ -1410,3 +1410,11 @@ const char *__doc_igl_writeOBJ = R"igl_Qu8mg5v7(// Write a mesh in an ascii obj
   //
   // Known issues: Horrifyingly, this does not have the same order of
   // parameters as readOBJ.)igl_Qu8mg5v7";
+const char *__doc_igl_writePLY = R"igl_Qu8mg5v7(// Write a mesh in an ascii ply file
+  // Inputs:
+  //   str  path to outputfile
+  //   V  #V by 3 mesh vertex positions
+  //   F  #F by 3 mesh indices into V
+  //   N  #V by 3 normal vectors
+  //   UV #V by 2 texture coordinates
+  // Returns true on success, false on error)igl_Qu8mg5v7";

+ 1 - 0
python/py_doc.h

@@ -116,3 +116,4 @@ extern const char *__doc_igl_winding_number_3;
 extern const char *__doc_igl_winding_number_2;
 extern const char *__doc_igl_writeMESH;
 extern const char *__doc_igl_writeOBJ;
+extern const char *__doc_igl_writePLY;

+ 2 - 0
python/py_igl.cpp

@@ -92,6 +92,7 @@
 #include <igl/winding_number.h>
 #include <igl/writeMESH.h>
 #include <igl/writeOBJ.h>
+#include <igl/writePLY.h>
 
 
 void python_export_igl(py::module &m)
@@ -187,5 +188,6 @@ void python_export_igl(py::module &m)
 #include "py_igl/py_winding_number.cpp"
 #include "py_igl/py_writeMESH.cpp"
 #include "py_igl/py_writeOBJ.cpp"
+#include "py_igl/py_writePLY.cpp"
 
 }

+ 23 - 0
python/py_igl/py_writePLY.cpp

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

+ 1 - 0
python/python_shared.cpp

@@ -151,6 +151,7 @@ PYBIND11_PLUGIN(pyigl) {
            winding_number
            writeMESH
            writeOBJ
+           writePLY
 
     )pyigldoc");
 

+ 3 - 3
python/tutorial/101_FileIO.py

@@ -12,9 +12,9 @@ V = igl.eigen.MatrixXd()
 F = igl.eigen.MatrixXi()
 igl.readOFF(TUTORIAL_SHARED_PATH + "cube.off", V, F)
 
-# Print the vertices and faces matrices
-print("Vertices: \n", V, sep='')
-print("Faces: \n", F, sep='')
+# Print the vertices and faces matrices (commented out to make this file compatible with python 2.x and 3.x)
+# print("Vertices: \n", V, sep='')
+# print("Faces: \n", F, sep='')
 
 # Save the mesh in OBJ format
 igl.writeOBJ("cube.obj",V,F)

+ 2 - 2
python/tutorial/shared.py

@@ -1,8 +1,8 @@
 import pyigl as igl
 import sys
+import os
 
-
-TUTORIAL_SHARED_PATH = "../../tutorial/shared/"
+TUTORIAL_SHARED_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../tutorial/shared/")
 
 def check_dependencies(deps):
     available = [hasattr(igl, m) for m in deps]

+ 4 - 1
scripts/update_gh-pages.sh

@@ -16,7 +16,7 @@ echo "$HEADER" \
   | cat - README.md | multimarkdown -o index.html
 
 echo "$HEADER" \
-  | cat - style-guidelines.md | multimarkdown -o style-guidelines.html 
+  | cat - style-guidelines.md | multimarkdown -o style-guidelines.html
 
 HEADER="title: libigl
 author: Alec Jacobson and Daniele Panozzo and others
@@ -32,3 +32,6 @@ echo "$HEADER" \
   | cat - optional/README.md | multimarkdown -o optional/index.html
 
 multimarkdown tutorial/tutorial.md -o tutorial/tutorial.html
+
+echo "$HEADER" \
+  | cat - coding-guidelines.md | multimarkdown -o coding-guidelines.html

+ 3 - 1
shared/cmake/FindMOSEK.cmake

@@ -8,7 +8,9 @@
 #
 
 FIND_PATH(MOSEK_INCLUDE_DIR mosek.h
-  PATHS /usr/local/mosek/7/tools/platform/osx64x86/h/
+  PATHS 
+  /usr/local/mosek/7/tools/platform/osx64x86/h/
+  /usr/local/mosek/8/tools/platform/osx64x86/h/
     )
 
 SET(SEARCH_PATHS "${MOSEK_INCLUDE_DIR}" "${MOSEK_INCLUDE_DIR}/../bin" "${MOSEK_INCLUDE_DIR}/lib")

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

@@ -1 +1 @@
-e433fea7c89195d4086db16774eec2e6a7e8014f
+5ae3f8bf55895f273b2e1417314d6ed544096ea6

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

@@ -1 +1 @@
-fdd2d996ca033c6ca0452fd413e506732eb4de40
+4868a892c78947f78ff6985ff7ea6cc069dd1b4d