瀏覽代碼

Merge remote-tracking branch 'upstream/master'

Conflicts:
	include/igl/HalfEdgeIterator.h
	include/igl/comiso/miq.cpp
	include/igl/cut_mesh.cpp
	include/igl/cut_mesh.h
	tutorial/shared/octopus-high.mesh

Former-commit-id: acaa8d8181fd4a371d65c11b9f799cf88f70b1b3
wkevin 9 年之前
父節點
當前提交
278473915f
共有 100 個文件被更改,包括 2423 次插入2112 次删除
  1. 17 0
      .gitignore
  2. 11 1
      .gitmodules
  3. 37 7
      README.md
  4. 1 0
      RELEASE_HISTORY.md
  5. 1 1
      VERSION.txt
  6. 0 326
      documentation/active-set.tex
  7. 0 50
      documentation/implemented-papers.tex
  8. 0 1
      documentation/references.bib.REMOVED.git-id
  9. 3 3
      examples/Makefile.conf
  10. 8 8
      examples/ambient-occlusion/example.cpp
  11. 0 1
      examples/arap/Makefile
  12. 7 7
      examples/arap/example.cpp
  13. 16 16
      examples/beach-balls/BeachBall.cpp
  14. 2 2
      examples/beach-balls/example.cpp
  15. 8 8
      examples/camera/example.cpp
  16. 7 7
      examples/colored-mesh/example.cpp
  17. 1 1
      examples/components/Makefile
  18. 16 16
      examples/components/example.cpp
  19. 19 19
      examples/embree/example.cpp
  20. 16 16
      examples/flare-eyes/example.cpp
  21. 8 8
      examples/intersections/example.cpp
  22. 16 16
      examples/multi-viewport/example.cpp
  23. 1 1
      examples/patches/Makefile
  24. 8 8
      examples/patches/example.cpp
  25. 6 6
      examples/randomly-sample-mesh/example.cpp
  26. 8 8
      examples/rotate-widget/example.cpp
  27. 6 6
      examples/scene-rotation/example.cpp
  28. 1 1
      examples/scene-rotation/trackball.cpp
  29. 6 6
      examples/shadow-mapping/example.cpp
  30. 39 27
      examples/skeleton-builder/example.cpp
  31. 15 14
      examples/skeleton-poser/example.cpp
  32. 10 10
      examples/skeleton/example.cpp
  33. 7 8
      examples/textured-mesh/example.cpp
  34. 1 1
      examples/transparency/Makefile
  35. 12 12
      examples/transparency/example.cpp
  36. 5 5
      examples/upright/example.cpp
  37. 2 2
      google-soc/index.html
  38. 16 7
      include/igl/AABB.h
  39. 1 1
      include/igl/ARAPEnergyType.h
  40. 1 1
      include/igl/HalfEdgeIterator.h
  41. 4 2
      include/igl/arap.cpp
  42. 3 0
      include/igl/arap.h
  43. 7 6
      include/igl/average_onto_vertices.cpp
  44. 1 0
      include/igl/barycenter.cpp
  45. 11 7
      include/igl/barycentric_to_global.cpp
  46. 44 10
      include/igl/biharmonic_coordinates.cpp
  47. 13 0
      include/igl/biharmonic_coordinates.h
  48. 56 28
      include/igl/boolean/mesh_boolean.cpp
  49. 1 1
      include/igl/bounding_box_diagonal.cpp
  50. 3 1
      include/igl/cat.cpp
  51. 2 0
      include/igl/cgal/RemeshSelfIntersectionsParam.h
  52. 166 499
      include/igl/cgal/SelfIntersectMesh.h
  53. 22 0
      include/igl/cgal/assign_scalar.cpp
  54. 31 0
      include/igl/cgal/assign_scalar.h
  55. 237 99
      include/igl/cgal/intersect_other.cpp
  56. 66 16
      include/igl/cgal/intersect_other.h
  57. 1 1
      include/igl/cgal/mesh_to_polyhedron.cpp
  58. 211 0
      include/igl/cgal/order_facets_around_edge.cpp
  59. 53 0
      include/igl/cgal/order_facets_around_edge.h
  60. 78 0
      include/igl/cgal/order_facets_around_edges.cpp
  61. 30 1
      include/igl/cgal/order_facets_around_edges.h
  62. 74 0
      include/igl/cgal/outer_facet.cpp
  63. 55 0
      include/igl/cgal/outer_facet.h
  64. 9 112
      include/igl/cgal/outer_hull.cpp
  65. 0 15
      include/igl/cgal/outer_hull.h
  66. 18 38
      include/igl/cgal/peel_outer_hull_layers.cpp
  67. 3 17
      include/igl/cgal/peel_outer_hull_layers.h
  68. 1 1
      include/igl/cgal/polyhedron_to_mesh.cpp
  69. 96 0
      include/igl/cgal/projected_delaunay.cpp
  70. 43 0
      include/igl/cgal/projected_delaunay.h
  71. 306 0
      include/igl/cgal/remesh_intersections.cpp
  72. 77 0
      include/igl/cgal/remesh_intersections.h
  73. 1 1
      include/igl/cgal/remesh_self_intersections.h
  74. 1 0
      include/igl/colon.cpp
  75. 4 3
      include/igl/comiso/miq.cpp
  76. 0 33
      include/igl/compile_and_link_program.h
  77. 0 38
      include/igl/compile_shader.h
  78. 1 0
      include/igl/components.cpp
  79. 0 63
      include/igl/create_mesh_vbo.h
  80. 0 65
      include/igl/create_shader_program.h
  81. 1 2
      include/igl/cut_mesh.cpp
  82. 0 1
      include/igl/cut_mesh.h
  83. 1 0
      include/igl/cut_mesh_from_singularities.cpp
  84. 0 35
      include/igl/destroy_shader_program.h
  85. 8 6
      include/igl/diag.cpp
  86. 64 0
      include/igl/dijkstra.cpp
  87. 60 0
      include/igl/dijkstra.h
  88. 1 1
      include/igl/directed_edge_orientations.cpp
  89. 1 1
      include/igl/directed_edge_parents.cpp
  90. 1 1
      include/igl/dqs.cpp
  91. 0 58
      include/igl/draw_floor.h
  92. 0 121
      include/igl/draw_mesh.h
  93. 0 45
      include/igl/draw_point.h
  94. 0 36
      include/igl/draw_rectangular_marquee.h
  95. 0 54
      include/igl/draw_skeleton_3d.h
  96. 0 53
      include/igl/draw_skeleton_vector_graphics.h
  97. 156 0
      include/igl/eigs.cpp
  98. 54 0
      include/igl/eigs.h
  99. 7 2
      include/igl/embree/EmbreeIntersector.h
  100. 1 1
      include/igl/embree/ambient_occlusion.cpp

+ 17 - 0
.gitignore

@@ -70,3 +70,20 @@ external/glfw/build
 tutorial/build*
 tutorial/build*
 tutorial/*/*.mexmaci64
 tutorial/*/*.mexmaci64
 external/libpng/build
 external/libpng/build
+external/tinyxml2/build
+optional/build
+lib
+tutorial/XXX_test/CMakeLists.txt
+tutorial/XXX_test/main.cpp
+python/py_igl/todo
+python/build
+python/.idea
+untitled
+Untitled.ipynb
+python/.ipynb_checkpoints
+python/py_igl/todo
+python/__pycache__
+iglhelpers.pyc
+python/build2
+tests/build
+tests/bin

+ 11 - 1
.gitmodules

@@ -1,4 +1,14 @@
 [submodule "external/nanogui"]
 [submodule "external/nanogui"]
 	path = external/nanogui
 	path = external/nanogui
-	url = https://github.com/schuellc/nanogui.git
+url=https://github.com/libigl/nanogui.git
         fetchRecursiveSubmodules = true
         fetchRecursiveSubmodules = true
+        ignore = dirty
+[submodule "external/embree"]
+	path = external/embree
+	url = https://github.com/embree/embree.git
+[submodule "external/pybind11"]
+	path = external/pybind11
+	url = https://github.com/wjakob/pybind11.git
+[submodule "tests/googletest"]
+	path = tests/googletest
+	url = https://github.com/google/googletest.git

+ 37 - 7
README.md

@@ -4,6 +4,12 @@
 
 
 <https://github.com/libigl/libigl/>
 <https://github.com/libigl/libigl/>
 
 
+> Get started with:
+>
+```bash
+git clone --recursive https://github.com/libigl/libigl.git
+```
+
 libigl is a simple C++ geometry processing library. We have a wide
 libigl is a simple C++ geometry processing library. We have a wide
 functionality including construction of sparse discrete differential geometry
 functionality including construction of sparse discrete differential geometry
 operators and finite-elements matrices such as the cotangent Laplacian and
 operators and finite-elements matrices such as the cotangent Laplacian and
@@ -17,7 +23,7 @@ just include igl headers (e.g. `#include <igl/cotmatrix.h>`) and run.  Each
 header file contains a single function (e.g. `igl/cotmatrix.h` contains
 header file contains a single function (e.g. `igl/cotmatrix.h` contains
 `igl::cotmatrix()`). Most are tailored to operate on a generic triangle mesh
 `igl::cotmatrix()`). Most are tailored to operate on a generic triangle mesh
 stored in an n-by-3 matrix of vertex positions V and an m-by-3 matrix of
 stored in an n-by-3 matrix of vertex positions V and an m-by-3 matrix of
-triangle indices F. 
+triangle indices F.
 
 
 _Optionally_ the library may also be [pre-compiled](optional/) into a statically
 _Optionally_ the library may also be [pre-compiled](optional/) into a statically
 linked library, for faster compile times with your projects. This only effects
 linked library, for faster compile times with your projects. This only effects
@@ -31,7 +37,7 @@ conversion table](matlab-to-eigen.html).
 ## Tutorial
 ## Tutorial
 
 
 As of version 1.0, libigl includes an introductory
 As of version 1.0, libigl includes an introductory
-[tutorial](tutorial/tutorial.html) that covers many functionalities.
+[tutorial](http://libigl.github.io/libigl/tutorial/tutorial.html) that covers many functionalities.
 
 
 ## Installation
 ## Installation
 
 
@@ -129,6 +135,25 @@ We hope to fix this, or at least identify which functions are safe (many of
 them probably work just fine). This requires setting up unit testing, which is
 them probably work just fine). This requires setting up unit testing, which is
 a major _todo_ for our development.
 a major _todo_ for our development.
 
 
+## Git Submodules
+Libigl uses git submodules for its _optional_ dependencies,
+in particular, those needed by the OpenGL viewer to run the examples in the
+[tutorial](tutorial/tutorial.html). Git submodules allow use to treat clones of
+other libraries as sub-directories within ours while separating our commits.
+Read the [documentation](http://git-scm.com/docs/git-submodule) for a detailed
+explanation, but essentially our libigl repo stores a hash for each of its
+subrepos containing which version to update to. When a change is introduced in
+a dependencies repo we can incorporate that change by pulling in our sub-repo
+and updating (i.e.  committing) that change to the hash.
+
+When pulling new changes to libigl it's also a good idea to update changes to
+subrepos:
+
+```bash
+git pull
+git submodule update -- recursive
+```
+
 ## How to contribute
 ## How to contribute
 
 
 If you are interested in joining development, please fork the repository and
 If you are interested in joining development, please fork the repository and
@@ -156,6 +181,9 @@ BibTeX entry:
 ```
 ```
 
 
 ## Projects/Universities using libigl
 ## Projects/Universities using libigl
+Libigl is used by many research groups around the world. In 2015, it won the
+Eurographics/ACM Symposium on Geometry Processing software award. Here are a
+few labs/companies/institutions using libigl:
 
 
  - [Spine by Esoteric Software](http://esotericsoftware.com/) is an animation tool dedicated to 2D characters.
  - [Spine by Esoteric Software](http://esotericsoftware.com/) is an animation tool dedicated to 2D characters.
  - Columbia University, [Columbia Computer Graphics Group](http://www.cs.columbia.edu/cg/), USA
  - Columbia University, [Columbia Computer Graphics Group](http://www.cs.columbia.edu/cg/), USA
@@ -164,7 +192,7 @@ BibTeX entry:
  - ETH Zurich, [Interactive Geometry Lab](http://igl.ethz.ch/) and [Advanced Technologies Lab](http://ait.inf.ethz.ch/), Swizterland
  - ETH Zurich, [Interactive Geometry Lab](http://igl.ethz.ch/) and [Advanced Technologies Lab](http://ait.inf.ethz.ch/), Swizterland
  - George Mason University, [CraGL](http://cs.gmu.edu/~ygingold/), USA
  - George Mason University, [CraGL](http://cs.gmu.edu/~ygingold/), USA
  - [Hong Kong University of Science and Technology](http://www.ust.hk/), USA
  - [Hong Kong University of Science and Technology](http://www.ust.hk/), USA
- - [National Institute of Informatics](http://www.nii.ac.jp/en/), Japan 
+ - [National Institute of Informatics](http://www.nii.ac.jp/en/), Japan
  - New York University, [Media Research Lab](http://mrl.nyu.edu/), USA
  - New York University, [Media Research Lab](http://mrl.nyu.edu/), USA
  - NYUPoly, [Game Innovation Lab](http://game.engineering.nyu.edu/), USA
  - NYUPoly, [Game Innovation Lab](http://game.engineering.nyu.edu/), USA
  - [Telecom ParisTech](http://www.telecom-paristech.fr/en/formation-et-innovation-dans-le-numerique.html), Paris, France
  - [Telecom ParisTech](http://www.telecom-paristech.fr/en/formation-et-innovation-dans-le-numerique.html), Paris, France
@@ -182,7 +210,8 @@ Libigl is a group endeavor led by [Alec
 Jacobson](http://www.cs.columbia.edu/~jacobson/) and [Daniele
 Jacobson](http://www.cs.columbia.edu/~jacobson/) and [Daniele
 Panozzo](http://www.inf.ethz.ch/personal/dpanozzo/). Please [contact
 Panozzo](http://www.inf.ethz.ch/personal/dpanozzo/). Please [contact
 us](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com) if you have
 us](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com) if you have
-questions or comments. We are happy to get feedback!
+questions or comments. For troubleshooting, please post an
+[issue](https://github.com/libigl/libigl/issues) on github.
 
 
 If you're using libigl in your projects, quickly [drop us a
 If you're using libigl in your projects, quickly [drop us a
 note](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com). Tell us who you
 note](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com). Tell us who you
@@ -193,7 +222,8 @@ If you find bugs or have problems please use our [github issue tracking
 page](https://github.com/libigl/libigl/issues).
 page](https://github.com/libigl/libigl/issues).
 
 
 ## Copyright
 ## Copyright
-2015 Alec Jacobson, Daniele Panozzo, Olga Diamanti, Christian Schüller, Kenshi
-Takayama, Leo Sacht, Wenzel Jacob, Nico Pietroni, Amir Vaxman
+2015 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan
+Zhou, Nico Pietroni, Stefan Brugger, Kenshi Takayama, Wenzel Jakob, Nikolas De
+Giorgis, Luigi Rocca, Leonardo Sacht, Olga Sorkine-Hornung, and others.
 
 
-![](tutorial/images/libigl-logo.jpg)
+Please see individual files for appropriate copyright notices.

+ 1 - 0
RELEASE_HISTORY.md

@@ -11,6 +11,7 @@ html header:   <script type="text/javascript" src="http://cdn.mathjax.org/mathja
 
 
 Version | Short description
 Version | Short description
 --------|----------------------------------------------------------------------
 --------|----------------------------------------------------------------------
+1.2.1   | Reorganization opengl-dependent functions: opengl and opengl2 extras
 1.2.0   | Reorganization of "extras", rm deprecated funcs, absorb boost & svd3x3
 1.2.0   | Reorganization of "extras", rm deprecated funcs, absorb boost & svd3x3
 1.1.7   | Switch build for static library to cmake.
 1.1.7   | Switch build for static library to cmake.
 1.1.6   | Major boolean robustness fix, drop CGAL dependency for AABB/distances
 1.1.6   | Major boolean robustness fix, drop CGAL dependency for AABB/distances

+ 1 - 1
VERSION.txt

@@ -3,4 +3,4 @@
 # Anyone may increment Minor to indicate a small change.
 # Anyone may increment Minor to indicate a small change.
 # Major indicates a large change or large number of changes (upload to website)
 # Major indicates a large change or large number of changes (upload to website)
 # World indicates a substantial change or release
 # World indicates a substantial change or release
-1.1.7
+1.2.1

+ 0 - 326
documentation/active-set.tex

@@ -1,326 +0,0 @@
-\documentclass[12pt]{diary}
-\title{Active set solver for quadratic programming}
-\author{Alec Jacobson}
-\date{18 September 2013}
-
-\renewcommand{\A}{\mat{A}}
-\renewcommand{\Q}{\mat{Q}}
-\newcommand{\RR}{\mat{R}}
-\newcommand{\Aeq}{\mat{A}_\textrm{eq}}
-\newcommand{\Aieq}{\mat{A}_\textrm{ieq}}
-\newcommand{\beq}{\vc{b}_\textrm{eq}}
-\newcommand{\bieq}{\vc{b}_\textrm{ieq}}
-\newcommand{\lx}{\Bell}
-\newcommand{\ux}{\vc{u}}
-\newcommand{\lameq} {\lambda_\textrm{eq}}
-\newcommand{\lamieq}{\lambda_\textrm{ieq}}
-\newcommand{\lamlu}  {\lambda_\textrm{lu}}
-
-\begin{document}
-
-\begin{pullout}
-\footnotesize
-\emph{Disclaimer: This document rewrites and paraphrases the ideas in
-\url{http://www.math.uh.edu/~rohop/fall_06/Chapter3.pdf},
-\url{http://www.math.uh.edu/~rohop/fall_06/Chapter2.pdf}, and
-\url{http://www.cs.cornell.edu/courses/cs322/2007sp/notes/qr.pdf}. Mostly this
-is to put everything in the same place and use notation compatible with the
-\textsc{libigl} implementation. The ideas and descriptions, however, are not novel.}
-\end{pullout}
-
-Quadratic programming problems (QPs) can be written in general as:
-\begin{align}
-\argmin \limits_\z &
-  \z^\transpose \A \z + \z^\transpose \b + \text{ constant}\\
-\text{subject to } & \Aieq \z ≤ \bieq,
-\end{align}
-where $\z \in \R^n$ is a vector of unknowns,  $\A \in \R^{n \times n}$ is a (in
-our case sparse) matrix of quadratic coefficients, $\b \in \R^n$ is a vector of
-linear coefficients, $\Aieq \in \R^{m_\text{ieq} \times n}$ is a matrix (also
-sparse) linear inequality coefficients and $\bieq \in \R^{m_\text{ieq}}$ is a
-vector of corresponding right-hand sides. Each row in $\Aieq \z ≤ \bieq$
-corresponds to a single linear inequality constraint.
-
-Though representable by the linear inequality constraints above---linear
-\emph{equality} constraints, constant bounds, and constant fixed values appear
-so often that we can write a more practical form
-\begin{align}
-\argmin \limits_\z &
-  \z^\transpose \A \z + \z^\transpose \b + \text{ constant}\\
-\text{subject to } & \z_\text{known} = \y,\\
-                   & \Aeq \z = \beq,\\
-                   & \Aieq \z ≤ \bieq,\\
-                   & \z ≥ \lx,\\
-                   & \z ≤ \ux,
-\end{align}
-where $\z_\text{known} \in \R^{n_\text{known}}$ is a subvector of our unknowns $\z$ which
-are known or fixed to obtain corresponding values $\y \in \R^{n_\text{known}}$,
-$\Aeq \in \R^{m_\text{eq} \times n}$ and $\beq \in \R^{m_\text{eq} \times n}$
-are linear \emph{equality} coefficients and right-hand sides respectively, and
-$\lx, \ux \in \R^n$ are vectors of constant lower and upper bound constraints.
-
-\todo{This notation is unfortunate. Too many bold A's and too many capitals.}
-
-This description exactly matches the prototype used by the
-\texttt{igl::active\_set()} function.
-
-The active set method works by iteratively treating a subset (some rows) of the
-inequality constraints as equality constraints. These are called the ``active
-set'' of constraints. So at any given iterations $i$ we might have a new
-problem:
-\begin{align}
-\argmin \limits_\z &
-  \z^\transpose \A \z + \z^\transpose \b + \text{ constant}\\
-\text{subject to } & \z_\text{known}^i = \y^i,\\
-                   & \Aeq^i \z = \beq^i,
-\end{align}
-where the active rows from 
-$\lx ≤ \z ≤ \ux$ and $\Aieq \z ≤ \bieq$  have been appended into
-$\z_\text{known}^i = \y^i$ and $\Aeq^i \z = \beq^i$ respectively.
-
-This may be optimized by solving a sparse linear system, resulting in the
-current solution $\z^i$. For equality constraint we can also find a
-corresponding Lagrange multiplier value. The active set method works by adding
-to the active set all linear inequality constraints which are violated by the
-previous solution $\z^{i-1}$ before this solve and then after the solve
-removing from the active set any constraints with negative Lagrange multiplier
-values. Let's declare that $\lameq \in \R^{m_\text{eq}}$, $\lamieq \in
-\R^{m_\text{ieq}}$, and $\lamlu \in \R^{n}$ are the Lagrange multipliers
-corresponding to the linear equality, linear inequality and constant bound
-constraints respectively. Then the abridged active set method proceeds as
-follows:
-
-\begin{lstlisting}[keywordstyle=,mathescape]
-while not converged
-  add to active set all rows where $\Aieq \z > \bieq$, $\z < \lx$ or $\z > \ux$
-    $\Aeq^i,\beq^i \leftarrow \Aeq,\beq + \text{active rows of} \Aieq,\bieq$
-    $\z_\text{known}^i,\y^i \leftarrow \z_\text{known},\y + \text{active indices and values of} \lx,\ux$
-  solve problem treating active constraints as equality constraints $\rightarrow \z,\lamieq,\lamlu$
-  remove from active set all rows with $\lamieq < 0$ or $\lamlu < 0$
-end
-\end{lstlisting}
-
-The fixed values constraints of $\z_\text{known}^i = \y^i$ may be enforced by
-substituting $\z_\text{known}^i$ for $\y^i$ in the energy directly during the
-solve.  Corresponding Lagrange multiplier values $\lambda_\text{known}^i$ can
-be recovered after we've found the rest of $\z$.
-
-The linear equality constraints $\Aeq^i \z = \beq^i$ are a little trickier. If
-the rows of 
-$\Aeq^i \in \R^{(<m_\text{eq}+ m_\text{ieq}) \times n}$ are linearly
-independent then it is straightforward how to build a Lagrangian which enforces
-each constraint. This results in solving a system roughly of the form:
-\begin{equation}
-\left(
-\begin{array}{cc}
-\A      & {\Aeq^i}^\transpose \\
-\Aeq^i  & \mat{0}
-\end{array}
-\right)
-\left(
-\begin{array}{l}
-\z\\\lambda^i_\text{eq}
-\end{array}
-\right)
-=
-\left(
-\begin{array}{l}
--\onehalf\b\\
--\beq^i
-\end{array}
-\right)
-\end{equation}
-\todo{Double check. Could be missing a sign or factor of 2 here.}
-
-If the rows of $\Aeq^i$ are linearly dependent then the system matrix above
-will be singular. Because we may always assume that the constraints are not
-contradictory, this system can still be solved. But it will take some care.
-Some linear solvers, e.g.\ \textsc{MATLAB}'s, seem to deal with these OK.
-\textsc{Eigen}'s does not.
-
-Without loss of generality, let us assume that there are no inequality
-constraints and it's the rows of $\Aeq$ which might be linearly dependent.
-Let's also assume we have no fixed or known values. Then the linear system
-above corresponds to the following optimization problem:
-\begin{align}
-\argmin \limits_\z &
-  \z^\transpose \A \z + \z^\transpose \b + \text{ constant}\\
-\text{subject to } & \Aeq \z = \beq.
-\end{align}
-For the sake of cleaner notation, let $m = m_\text{eq}$ so that $\Aeq \in \R^{m
-\times n}$ and $\beq \in \R^m$.
-
-We can construct the null space of the constraints by computing a QR
-decomposition of $\Aeq^\transpose$:
-\begin{equation}
-\Aeq^\transpose \P = \Q \RR =
-\left(\begin{array}{cc}
-\Q_1 & \Q_2
-\end{array}\right)
-\left(\begin{array}{c}
-\RR\\
-\mat{0}
-\end{array}\right)=
-\Q_1 \RR
-\end  {equation}
-where $\P \in \R^{m \times m}$ is a sparse permutation matrix, $\Q \in \R^{n
-\times n}$ is orthonormal, $\RR \in \R^{n \times m}$ is upper triangular. Let
-$r$ be the row rank of $\Aeq$---the number of linearly independent rows---then
-we split $\Q$ and $\RR$ into $\Q_1 \in \R^{n \times r}$, $\Q_2 \in \R^{n \times
-n-r}$, and $\R_1 \in \RR^{r \times m}$.
-
-Notice that 
-\begin{align}
-\Aeq \z &= \beq \\
-\P \P^\transpose \Aeq \z &= \\
-\P \left(\Aeq^\transpose \P\right)^\transpose \z &= \\
-\P\left(\Q\RR\right)^\transpose \z &= \\
-\P \RR^\transpose \Q^\transpose \z &= \\
-\P \RR^\transpose \Q \z &= \\
-\P \left(\RR_1^\transpose \mat{0}\right)
-  \left(\begin{array}{c}
-  \Q_1^\transpose\\
-  \Q_2^\transpose
-  \end{array}\right) \z &=\\
-\P \RR_1^\transpose \Q_1^\transpose \z + \P \0 \Q_2^\transpose \z &= .
-\end{align}
-Here we see that $\Q_1^\transpose \z$ affects this equality but
-$\Q_2^\transpose \z$ does not. Thus
-we say that $\Q_2$ forms a basis that spans the null space of $\Aeq$. That is,
-$\Aeq \Q_2 \w_2 =
-\vc{0},
-\forall \w_2 \in \R^{n-r}$. Let's write 
-\begin{equation}
-\z = \Q_1 \w_1 + \Q_2 \w_2.
-\end{equation}
-We're only interested in solutions $\z$ which satisfy our equality constraints
-$\Aeq \z = \beq$. If we plug in the above then we get
-\begin{align}
-\P \Aeq \left(\Q_1 \w_1 + \Q_2 \w_2\right) &= \beq \\
-\P \Aeq \Q_1 \w_1 &= \beq \\
-\P \left(\RR^\transpose \quad
-\mat{0}\right)\left(\begin{array}{c}\Q_1^\transpose\\
-\Q_2^\transpose\end{array}\right) \Q_1 \w_1 &= \beq \\
-\P \RR^\transpose \Q_1^\transpose \Q_1 \w_1 &= \beq \\
-\P \RR^\transpose \w_1 &= \beq \\
-\w_1 &= {\RR^\transpose}^{-1} \P^\transpose \beq.
-\end{align}
-% P RT Q1T z = Beq
-% RT Q1T z = PT Beq
-% Q1T z = RT \ PT Beq
-% w1 = RT \ PT * Beq
-% z = Q2 w2 + Q1 * w1 
-% z = Q2 w2 + Q1 * RT \ P * Beq
-% z = Q2 w2 + lambda0
-So then
-\begin{align}
-z &= \Q_1 {\RR^\transpose}^{-1} \P^\transpose \beq  + \Q_2 \w_2 \\
-z &= \Q_2 \w_2 + \overline{\w}_1\\
-\end{align}
-where $\overline{\w}_1$ is just collecting the known terms that do not depend on the
-unknowns $\w_2$.
-
-Now, by construction, $\Q_2 \w_2 + \overline{\w}_1$ spans (all) possible solutions
-for $\z$  that satisfy $\Aeq \z = \beq$
-% Let:
-% z = Q2 w2 + Q1 * w1 
-% z = Q2 w2 + Q1 * RT \ P * Beq
-% z = Q2 w2 + lambda0
-% Q2 w2 + lambda0 spans all z such that Aeq z = Beq, we have essentially
-% "factored out" the constraints. We can then simply make this substitution
-% into our original optimization problem, leaving an \emph{unconstrained}
-% quadratic energy optimization
-\begin{align}
-\argmin \limits_{\w_2} & (\Q_2 \w_2 + \overline{\w}_1)^\transpose \A (\Q_2 \w_2 + \overline{\w}_1)  +
-(\Q_2 \w_2 + \overline{\w}_1)^\transpose \b + \textrm{ constant}\\
-&\text{\emph{or equivalently}} \notag\\
-\argmin \limits_{\w_2} & 
-\w_2^\transpose \Q_2^\transpose \A \Q_2 + \w_2^\transpose \left(2\Q_2^\transpose \A
-\Q_2 \overline{\w}_1 + \Q_2^\transpose \b\right) + \textrm{ constant}
-\end{align}
-which is solved with a linear system solve
-\begin{equation}
-\left(\Q_2^\transpose \A \Q_2\right) \w_2 = 
-  -2\Q_2^\transpose \A \Q_2 \overline{\w}_1 + \Q_2^\transpose \b
-\end{equation}
-\todo{I've almost surely lost a sign or factor of 2 here.}
-If $\A$ is semi-positive definite then $\Q_2^\transpose\A\Q_2$ will also be
-semi-positive definite. Thus Cholesky factorization can be used. If $\A$ is
-sparse and $\Aeq$ is sparse and a good column pivoting sparse QR library is
-used then $\Q_2$ will be sparse and so will $\Q_2^\transpose\A\Q_2$.
-
-
-After $\w_2$ is known we can compute the solution $\z$ as 
-\begin{equation}
-\z = \Q_2 \w_2 + \overline{\w}_1.
-\end{equation}
-
-Recovering the Lagrange multipliers $\lameq \in \R^{m}$ corresponding to $\Aeq
-\z = \b$ is a bit trickier. The equation is:
-\begin{align}
-\left(\A\quad \Aeq^\transpose\right)
-\left(\begin{array}{c}
-\z\\
-\lameq
-\end{array}\right) &= -\onehalf\b \\
-\Aeq^\transpose \lameq &= - \A \z - \onehalf\b \\
-\Q_1^\transpose \Aeq^\transpose \lameq &= - \Q_1^\transpose \A \z - \onehalf\Q_1^\transpose \b \\
-% AT P = Q_1 R
-% AT = Q_1 R PT
-%
-% Q1T AT
-% Q1T Q_1 R PT
-% R PT
-& \textrm{\emph{Recall that $\Aeq^\transpose\P = \Q_1\RR$ so then $
-\Q_1^\transpose \Aeq^\transpose = \RR \P^\transpose$}}\notag\\
-\RR \P^\transpose \lameq &= - \Q_1^\transpose \A \z - \onehalf\Q_1^\transpose \b \\
-\lameq &= \P
-\RR^{-1}
-\left(-\Q_1^\transpose \A \z - \onehalf\Q_1^\transpose \b\right).
-\end{align}
-
-\alec{If $r<m$ then I think it is enough to define the permutation matrix as
-rectangular $\P \in \R^{m \times r}$.}
-
-We assumes that there were now known or fixed values. If there are, special
-care only needs to be taken to adjust $\Aeq \z = \beq$ to account for
-substituting $\z_\text{known}$ with $\y$. 
-
-\hr
-\clearpage
-
-The following table describes the translation between the entities described in
-this document and those used in \texttt{igl/active\_set} and
-\texttt{igl/min\_quad\_with\_fixed}.
-\begin{lstlisting}[keywordstyle=,mathescape]
-$\A$: A
-$\b$: B
-$\z$: Z
-$\Aeq$: Aeq
-$\Aieq$: Aieq
-$\beq$: Beq
-$\bieq$: Bieq
-$\lx$: lx
-$\ux$: ux
-$\lamieq$: ~Lambda_Aieq_i
-$\lamlu$: ~Lambda_known_i
-$\P$: AeqTE
-$\Q$: AeqTQ
-$\RR$: AeqTR1
-$\RR^\transpose$: AeqTR1T
-$\Q_1$: AeqTQ1
-$\Q_1^\transpose$: AeqTQ1T
-$\Q_2$: AeqTQ2
-$\Q_2^\transpose$: AeqTQ2T
-$\w_2$: lambda
-$\overline{\w}_1$: lambda_0
-\end{lstlisting}
-
-
-% Resources
-%  http://www.cs.cornell.edu/courses/cs322/2007sp/notes/qr.pdf
-%  http://www.math.uh.edu/~rohop/fall_06/Chapter2.pdf
-%  http://www.math.uh.edu/~rohop/fall_06/Chapter3.pdf
-
-
-\end{document}

+ 0 - 50
documentation/implemented-papers.tex

@@ -1,50 +0,0 @@
-\documentclass[12pt]{diary}
-\immediate\write18{bibtex \jobname}
-
-\title{Papers implemented in \textsc{libigl}}
-\author{Alec Jacobson}
-\date{last revised 22 April 2014}
-
-\begin{document}
-This document serves as a companion reference to better list the references to
-scientific articles implemented within \textsc{libigl}. It will no doubt be
-incomplete.
-
-\paragraph{\texttt{cotmatrix}, \texttt{massmatrix}}
-build discrete operators on triangle and tetrahedral meshes. 
-\cite{Pinkall:1993:CDM,meyer03ddo,Jacobson:THESIS:2013}. For tet meshes, we no
-longer use the ``by the book'' FEM construction \`a la \cite{Sharf:2007vv},
-rather a purely geometric approach \cite{Barth:1994,Xu:1999}.
-
-\paragraph{\texttt{harmonic}} solves a Laplace problem (equivalently
-minimizes the Dirichlet energy) with some simple boundary conditions
-\cite{HarmonicCoodinates07}. There's also an option to solve
-``higher order Laplace problems'' (bi-Laplace, tri-Laplace, etc.)
-\cite{Botsch:2004:AIF,sorkine04lsm,Jacobson:MixedFEM:2010}.
-
-\paragraph{\texttt{bbw/}} implements ``bounded biharmonic
-weights'' \cite{Jacobson:BBW:2011}.
-
-\paragraph{\texttt{svd3x3/arap}} is a generalized implementation
-for solving ``as-rigid-as-possible'' (ARAP) mesh deformation or parameterization
-problems \cite{ARAP_modeling:2007,Liu:2008:ALA,Chao:2010:ASG}.
-
-\paragraph{\texttt{svd3x3/arap\_dof}} implements ``FAST'',
-which is simultaneously a reduced form of ARAP and a method for automatically
-choosing skinning transformations \cite{Jacobson:FAST:2012}.
-
-\paragraph{\texttt{dqs}} implements ``Dual quaternion skinning''
-\cite{Kavan:2008:GSW}.
-
-\paragraph{\texttt{lbs}} implements ``linear blend skinning'', also known as
-``skeletal subspace deformation'', or ``enveloping''. This technique is often
-attributed to \cite{Magnenat-Thalmann:1988:JLD}.
-
-\paragraph{\texttt{winding\_number}} implements ``Generalized Winding Numbers''
-\cite{Jacobson:WN:2013}
-
-\bibliographystyle{acmsiggraph}
-\bibliography{references} 
-
-\end{document}
-__END__

+ 0 - 1
documentation/references.bib.REMOVED.git-id

@@ -1 +0,0 @@
-346cd2c8206ee2c83e7aef50adb832e483320d09

+ 3 - 3
examples/Makefile.conf

@@ -18,7 +18,7 @@ CFLAGS += -std=c++11
 ifeq ($(UNAME), Linux)
 ifeq ($(UNAME), Linux)
 	DEFAULT_PREFIX=/usr/local/
 	DEFAULT_PREFIX=/usr/local/
 else
 else
-	DEFAULT_PREFIX=/opt/local/
+	DEFAULT_PREFIX=/usr/local/
 	# I guess arch only works in Mac OSX
 	# I guess arch only works in Mac OSX
 	AFLAGS+=-arch x86_64 -m64 -march=corei7-avx
 	AFLAGS+=-arch x86_64 -m64 -march=corei7-avx
 endif
 endif
@@ -66,7 +66,7 @@ ifeq ($(IGL_USERNAME),ajx)
 #AFLAGS = -m64 -march="corei7-avx"
 #AFLAGS = -m64 -march="corei7-avx"
 	# msse4.2 is necessary for me to get embree to compile correctly
 	# msse4.2 is necessary for me to get embree to compile correctly
 	AFLAGS=-m64 -msse4.2
 	AFLAGS=-m64 -msse4.2
-	OPENMP=-fopenmp
+	#OPENMP=-fopenmp
 	EIGEN3_INC=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
 	EIGEN3_INC=-I$(DEFAULT_PREFIX)/include/eigen3 -I$(DEFAULT_PREFIX)/include/eigen3/unsupported
 	#EIGEN3_INC=-I/Users/ajx/Documents/eigen -I/Users/ajx/Documents/eigen/unsupported
 	#EIGEN3_INC=-I/Users/ajx/Documents/eigen -I/Users/ajx/Documents/eigen/unsupported
 endif
 endif
@@ -246,7 +246,7 @@ endif
 
 
 ifdef LIBIGL_USE_STATIC_LIBRARY
 ifdef LIBIGL_USE_STATIC_LIBRARY
 	CFLAGS += -DIGL_STATIC_LIBRARY
 	CFLAGS += -DIGL_STATIC_LIBRARY
-	LIBIGL_LIB=-L$(LIBIGL)/lib -ligl
+	LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglopengl2 -liglopengl
 endif
 endif
 
 
 OPTFLAGS+=-O3 -DNDEBUG $(OPENMP)
 OPTFLAGS+=-O3 -DNDEBUG $(OPENMP)

+ 8 - 8
examples/ambient-occlusion/example.cpp

@@ -1,11 +1,11 @@
-#include <igl/OpenGL_convenience.h>
+#include <igl/opengl/OpenGL_convenience.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_vertex_normals.h>
 #include <igl/per_vertex_normals.h>
 #include <igl/normalize_row_lengths.h>
 #include <igl/normalize_row_lengths.h>
-#include <igl/draw_mesh.h>
-#include <igl/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
 #include <igl/quat_to_mat.h>
 #include <igl/quat_to_mat.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/readOBJ.h>
 #include <igl/readOBJ.h>
 #include <igl/readDMAT.h>
 #include <igl/readDMAT.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
@@ -76,7 +76,7 @@ void reshape(int width,int height)
   TwWindowSize(width, height);
   TwWindowSize(width, height);
 }
 }
 
 
-// Set up projection and model view of scene
+// Set up igl::opengl2::projection and model view of scene
 void push_scene()
 void push_scene()
 {
 {
   using namespace igl;
   using namespace igl;
@@ -204,7 +204,7 @@ void display()
   // Draw the model
   // Draw the model
   // Set material properties
   // Set material properties
   glEnable(GL_COLOR_MATERIAL);
   glEnable(GL_COLOR_MATERIAL);
-  draw_mesh(V,F,N,C);
+  igl::opengl2::draw_mesh(V,F,N,C);
 
 
   pop_object();
   pop_object();
 
 
@@ -215,12 +215,12 @@ void display()
   glTranslated(0,floor_offset,0);
   glTranslated(0,floor_offset,0);
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 0 - 1
examples/arap/Makefile

@@ -2,7 +2,6 @@
 
 
 # Shared flags etc.
 # Shared flags etc.
 include ../Makefile.conf
 include ../Makefile.conf
-LIBIGL_LIB+=-liglsvd3x3
 
 
 all: example
 all: example
 
 

+ 7 - 7
examples/arap/example.cpp

@@ -1,12 +1,12 @@
 #include <igl/Camera.h>
 #include <igl/Camera.h>
-#include <igl/OpenGL_convenience.h>
+#include <igl/opengl/OpenGL_convenience.h>
 #include <igl/PI.h>
 #include <igl/PI.h>
 #include <igl/STR.h>
 #include <igl/STR.h>
 #include <igl/arap.h>
 #include <igl/arap.h>
 #include <igl/barycenter.h>
 #include <igl/barycenter.h>
 #include <igl/cotmatrix.h>
 #include <igl/cotmatrix.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/harmonic.h>
 #include <igl/harmonic.h>
 #include <igl/invert_diag.h>
 #include <igl/invert_diag.h>
@@ -27,7 +27,7 @@
 #include <igl/readOBJ.h>
 #include <igl/readOBJ.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -420,7 +420,7 @@ void display()
   //glMaterialf (GL_BACK, GL_SHININESS, 128);
   //glMaterialf (GL_BACK, GL_SHININESS, 128);
   glEnable(GL_COLOR_MATERIAL);
   glEnable(GL_COLOR_MATERIAL);
 
 
-  draw_mesh(U,F,N,C);
+  igl::opengl2::draw_mesh(U,F,N,C);
   glDisable(GL_COLOR_MATERIAL);
   glDisable(GL_COLOR_MATERIAL);
 
 
   pop_object();
   pop_object();
@@ -435,12 +435,12 @@ void display()
   //const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   //const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
 
 
   //draw_floor(GREY,DARK_GREY);
   //draw_floor(GREY,DARK_GREY);
-  draw_floor();
+  igl::opengl2::draw_floor();
   glPopMatrix();
   glPopMatrix();
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 16 - 16
examples/beach-balls/BeachBall.cpp

@@ -1,11 +1,11 @@
 #include "BeachBall.h"
 #include "BeachBall.h"
 
 
 
 
-#include <igl/draw_beach_ball.h>
+#include <igl/opengl2/draw_beach_ball.h>
 #include <igl/quat_to_mat.h>
 #include <igl/quat_to_mat.h>
-#include <igl/unproject_to_zero_plane.h>
-#include <igl/unproject.h>
-#include <igl/project.h>
+#include <igl/opengl2/unproject_to_zero_plane.h>
+#include <igl/opengl2/unproject.h>
+#include <igl/opengl2/project.h>
 #include <igl/quat_mult.h>
 #include <igl/quat_mult.h>
 #include <igl/quat_conjugate.h>
 #include <igl/quat_conjugate.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -76,7 +76,7 @@ void BeachBall::draw()
   glPushMatrix();
   glPushMatrix();
   glScaled(radius,radius,radius);
   glScaled(radius,radius,radius);
   // draw oriented glyph 
   // draw oriented glyph 
-  draw_beach_ball();
+  igl::opengl2::draw_beach_ball();
   // Pop scale
   // Pop scale
   glPopMatrix();
   glPopMatrix();
   // Reset lighting
   // Reset lighting
@@ -93,8 +93,8 @@ bool BeachBall::in(const int x,const int y) const
   push();
   push();
   // Now origin is center of object
   // Now origin is center of object
   double obj[3];
   double obj[3];
-  // Check if unprojected screen point is nearby
-  unproject_to_zero_plane(x,y, &obj[0], &obj[1], &obj[2]);
+  // Check if igl::opengl2::unprojected screen point is nearby
+  igl::opengl2::unproject_to_zero_plane(x,y, &obj[0], &obj[1], &obj[2]);
   bool near = (obj[0]*obj[0] + obj[1]*obj[1] + obj[2]*obj[2])<radius*radius;
   bool near = (obj[0]*obj[0] + obj[1]*obj[1] + obj[2]*obj[2])<radius*radius;
   pop();
   pop();
   popmv();
   popmv();
@@ -136,7 +136,7 @@ bool BeachBall::drag(const int x,const int y)
     pushmv();
     pushmv();
     push();
     push();
     double origin[3];
     double origin[3];
-    project(0,0,0,&origin[0],&origin[1],&origin[2]);
+    igl::opengl2::project(0,0,0,&origin[0],&origin[1],&origin[2]);
     pop();
     pop();
     popmv();
     popmv();
     double rot[4];
     double rot[4];
@@ -193,20 +193,20 @@ bool BeachBall::drag(const int x,const int y)
   }else
   }else
   {
   {
     // We want that origin follows mouse move. First define plane we
     // We want that origin follows mouse move. First define plane we
-    // projecteing screen mouse movement to as perpendicular plan passing
+    // igl::opengl2::projecteing screen mouse movement to as perpendicular plan passing
     // through this origin.
     // through this origin.
     pushmv();
     pushmv();
-    // down_t projected to screen to get depth value
+    // down_t igl::opengl2::projected to screen to get depth value
     double p[3];
     double p[3];
-    project(down_t[0],down_t[1],down_t[2],&p[0],&p[1],&p[2]);
-    // unprojected down_x,down_y with down_t depth
+    igl::opengl2::project(down_t[0],down_t[1],down_t[2],&p[0],&p[1],&p[2]);
+    // igl::opengl2::unprojected down_x,down_y with down_t depth
     double du[3];
     double du[3];
-    unproject(down_x,down_y,p[2],&du[0],&du[1],&du[2]);
-    // unprojected x,y with down_t depth
+    igl::opengl2::unproject(down_x,down_y,p[2],&du[0],&du[1],&du[2]);
+    // igl::opengl2::unprojected x,y with down_t depth
     double u[3];
     double u[3];
-    unproject(x,y,p[2],&u[0], &u[1], &u[2]);
+    igl::opengl2::unproject(x,y,p[2],&u[0], &u[1], &u[2]);
     popmv();
     popmv();
-    // Then move this origin according to project mouse displacment
+    // Then move this origin according to igl::opengl2::project mouse displacment
     t[0] = down_t[0] + (u[0]-du[0]);
     t[0] = down_t[0] + (u[0]-du[0]);
     t[1] = down_t[1] + (u[1]-du[1]);
     t[1] = down_t[1] + (u[1]-du[1]);
     t[2] = down_t[2] + (u[2]-du[2]);
     t[2] = down_t[2] + (u[2]-du[2]);

+ 2 - 2
examples/beach-balls/example.cpp

@@ -1,7 +1,7 @@
 #include "BeachBall.h"
 #include "BeachBall.h"
 
 
 #include <igl/quat_to_mat.h>
 #include <igl/quat_to_mat.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
 #include <igl/canonical_quaternions.h>
 #include <igl/canonical_quaternions.h>
 #include <igl/PI.h>
 #include <igl/PI.h>
@@ -135,7 +135,7 @@ void display()
   //  }
   //  }
   //}
   //}
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
   glutSwapBuffers();
   glutSwapBuffers();
   glutPostRedisplay();
   glutPostRedisplay();
 
 

+ 8 - 8
examples/camera/example.cpp

@@ -2,7 +2,7 @@
 #include <igl/Viewport.h>
 #include <igl/Viewport.h>
 #include <igl/Camera.h>
 #include <igl/Camera.h>
 #include <igl/matlab_format.h>
 #include <igl/matlab_format.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/anttweakbar/ReAntTweakBar.h>
 #include <igl/anttweakbar/ReAntTweakBar.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
 #include <igl/two_axis_valuator_fixed_up.h>
 #include <igl/two_axis_valuator_fixed_up.h>
@@ -10,12 +10,12 @@
 #include <igl/EPS.h>
 #include <igl/EPS.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/material_colors.h>
 #include <igl/material_colors.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
-#include <igl/draw_floor.h>
-#include <igl/project.h>
-#include <igl/unproject.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/project.h>
+#include <igl/opengl2/unproject.h>
 
 
 #include <Eigen/Core>
 #include <Eigen/Core>
 #include <Eigen/Geometry>
 #include <Eigen/Geometry>
@@ -354,7 +354,7 @@ void draw_scene(const igl::Camera & v_camera,
   glMaterialfv(GL_BACK, GL_DIFFUSE,  FAST_GREEN_DIFFUSE  );
   glMaterialfv(GL_BACK, GL_DIFFUSE,  FAST_GREEN_DIFFUSE  );
   glMaterialfv(GL_BACK, GL_SPECULAR, SILVER_SPECULAR);
   glMaterialfv(GL_BACK, GL_SPECULAR, SILVER_SPECULAR);
   glMaterialf (GL_BACK, GL_SHININESS, 128);
   glMaterialf (GL_BACK, GL_SHININESS, 128);
-  draw_mesh(V,F,N);
+  igl::opengl2::draw_mesh(V,F,N);
   glDisable(GL_LIGHTING);
   glDisable(GL_LIGHTING);
   glEnable(GL_COLOR_MATERIAL);
   glEnable(GL_COLOR_MATERIAL);
   //glLineWidth(3.f);
   //glLineWidth(3.f);
@@ -365,7 +365,7 @@ void draw_scene(const igl::Camera & v_camera,
   {
   {
     glPushMatrix();
     glPushMatrix();
     glTranslated(0,-1,0);
     glTranslated(0,-1,0);
-    draw_floor();
+    igl::opengl2::draw_floor();
     glPopMatrix();
     glPopMatrix();
   }
   }
   
   
@@ -383,7 +383,7 @@ void draw_scene(const igl::Camera & v_camera,
   glPopMatrix();
   glPopMatrix();
   glMatrixMode(GL_MODELVIEW);
   glMatrixMode(GL_MODELVIEW);
   glPopMatrix();
   glPopMatrix();
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   if(render_to_texture)
   if(render_to_texture)
   {
   {

+ 7 - 7
examples/colored-mesh/example.cpp

@@ -1,12 +1,12 @@
-#include <igl/OpenGL_convenience.h>
+#include <igl/opengl/OpenGL_convenience.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_vertex_normals.h>
 #include <igl/per_vertex_normals.h>
 #include <igl/two_axis_valuator_fixed_up.h>
 #include <igl/two_axis_valuator_fixed_up.h>
 #include <igl/normalize_row_lengths.h>
 #include <igl/normalize_row_lengths.h>
-#include <igl/draw_mesh.h>
-#include <igl/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
 #include <igl/quat_to_mat.h>
 #include <igl/quat_to_mat.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/readOBJ.h>
 #include <igl/readOBJ.h>
 #include <igl/readDMAT.h>
 #include <igl/readDMAT.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
@@ -258,7 +258,7 @@ void display()
   // Draw the model
   // Draw the model
   // Set material properties
   // Set material properties
   glEnable(GL_COLOR_MATERIAL);
   glEnable(GL_COLOR_MATERIAL);
-  draw_mesh(V,F,N,C);
+  igl::opengl2::draw_mesh(V,F,N,C);
 
 
   pop_object();
   pop_object();
 
 
@@ -269,12 +269,12 @@ void display()
   glTranslated(0,floor_offset,0);
   glTranslated(0,floor_offset,0);
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 1 - 1
examples/components/Makefile

@@ -2,7 +2,7 @@
 
 
 # Shared flags etc.
 # Shared flags etc.
 include ../Makefile.conf
 include ../Makefile.conf
-LIBIGL_LIB+=-liglembree -liglboost
+LIBIGL_LIB+=-liglembree 
 
 
 all: obj example
 all: obj example
 
 

+ 16 - 16
examples/components/example.cpp

@@ -2,16 +2,16 @@
 #include <igl/Camera.h>
 #include <igl/Camera.h>
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
 #include <igl/components.h>
 #include <igl/components.h>
-#include <igl/create_shader_program.h>
-#include <igl/draw_floor.h>
+#include <igl/opengl/create_shader_program.h>
+#include <igl/opengl2/draw_floor.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/hsv_to_rgb.h>
 #include <igl/hsv_to_rgb.h>
-#include <igl/init_render_to_texture.h>
+#include <igl/opengl/init_render_to_texture.h>
 #include <igl/jet.h>
 #include <igl/jet.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
 #include <igl/randperm.h>
 #include <igl/randperm.h>
 #include <igl/read_triangle_mesh.h>
 #include <igl/read_triangle_mesh.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/rgb_to_hsv.h>
 #include <igl/rgb_to_hsv.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
@@ -152,8 +152,8 @@ void reshape(int width, int height)
   // Send the new window size to AntTweakBar
   // Send the new window size to AntTweakBar
   TwWindowSize(width, height);
   TwWindowSize(width, height);
   s.camera.m_aspect = (double)width/(double)height;
   s.camera.m_aspect = (double)width/(double)height;
-  igl::init_render_to_texture(width,height, pick_tex, pick_fbo, pick_dfbo);
-  igl::report_gl_error("init_render_to_texture: ");
+  igl::opengl::init_render_to_texture(width,height, pick_tex, pick_fbo, pick_dfbo);
+  igl::opengl::report_gl_error("init_render_to_texture: ");
   glutPostRedisplay();
   glutPostRedisplay();
 }
 }
 
 
@@ -231,7 +231,7 @@ void draw_mesh(
 
 
     glBindBuffer(GL_ARRAY_BUFFER,sbo);
     glBindBuffer(GL_ARRAY_BUFFER,sbo);
     glBufferData(GL_ARRAY_BUFFER,sizeof(float)*SR.size(),SR.data(),GL_STATIC_DRAW);
     glBufferData(GL_ARRAY_BUFFER,sizeof(float)*SR.size(),SR.data(),GL_STATIC_DRAW);
-    igl::report_gl_error("glBindBuffer: ");
+    igl::opengl::report_gl_error("glBindBuffer: ");
 
 
     scene_dirty = false;
     scene_dirty = false;
   }
   }
@@ -289,11 +289,11 @@ GLuint generate_1d_texture(
   glTexImage1D(GL_TEXTURE_1D, 0, colors.cols(),colors.rows(),
   glTexImage1D(GL_TEXTURE_1D, 0, colors.cols(),colors.rows(),
     0,GL_RGB, GL_UNSIGNED_BYTE,
     0,GL_RGB, GL_UNSIGNED_BYTE,
     colors.data());
     colors.data());
-  igl::report_gl_error("glTexImage1D: ");
+  igl::opengl::report_gl_error("glTexImage1D: ");
   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
-  igl::report_gl_error("texture: ");
+  igl::opengl::report_gl_error("texture: ");
   return tex_id;
   return tex_id;
 }
 }
  
  
@@ -333,7 +333,7 @@ void main()
     colors(id,2) = re;
     colors(id,2) = re;
   }
   }
   tex_id = generate_1d_texture(colors);
   tex_id = generate_1d_texture(colors);
-  return igl::create_shader_program(
+  return igl::opengl::create_shader_program(
     vertex_shader.c_str(), 
     vertex_shader.c_str(), 
     fragment_shader.c_str(),
     fragment_shader.c_str(),
     {{"scalar_in",scalar_loc}}
     {{"scalar_in",scalar_loc}}
@@ -519,12 +519,12 @@ void main()
 
 
     tex_id = generate_1d_texture(colors);
     tex_id = generate_1d_texture(colors);
 
 
-    GLuint prog_id = igl::create_shader_program(
+    GLuint prog_id = igl::opengl::create_shader_program(
       vertex_shader.c_str(), 
       vertex_shader.c_str(), 
       fragment_shader.c_str(),
       fragment_shader.c_str(),
       {{"scalar_in",scalar_loc}}
       {{"scalar_in",scalar_loc}}
       );
       );
-    igl::report_gl_error("create_shader_program: ");
+    igl::opengl::report_gl_error("create_shader_program: ");
     return prog_id;
     return prog_id;
   };
   };
   static GLuint scalar_loc = 1;
   static GLuint scalar_loc = 1;
@@ -547,7 +547,7 @@ void main()
     }else
     }else
     {
     {
       glUseProgram(color_components_prog);
       glUseProgram(color_components_prog);
-      igl::report_gl_error("UseProgram: ");
+      igl::opengl::report_gl_error("UseProgram: ");
       draw_mesh(V,F,N,s.I,scalar_loc);
       draw_mesh(V,F,N,s.I,scalar_loc);
     }
     }
   }
   }
@@ -556,7 +556,7 @@ void main()
 
 
   glPushAttrib(GL_ALL_ATTRIB_BITS);
   glPushAttrib(GL_ALL_ATTRIB_BITS);
   glUseProgram(color_components_prog);
   glUseProgram(color_components_prog);
-    igl::report_gl_error("use: ");
+    igl::opengl::report_gl_error("use: ");
   glUniform1f(glGetUniformLocation(color_components_prog,"cmin"),s.I.minCoeff());
   glUniform1f(glGetUniformLocation(color_components_prog,"cmin"),s.I.minCoeff());
   glUniform1f(glGetUniformLocation(color_components_prog,"cmax"),s.I.maxCoeff());
   glUniform1f(glGetUniformLocation(color_components_prog,"cmax"),s.I.maxCoeff());
   //glUniform1f(glGetUniformLocation(color_components_prog,"cc_selected"),cc_selected);
   //glUniform1f(glGetUniformLocation(color_components_prog,"cc_selected"),cc_selected);
@@ -568,7 +568,7 @@ void main()
   glBindTexture(GL_TEXTURE_1D, s.mask_id);
   glBindTexture(GL_TEXTURE_1D, s.mask_id);
   glUniform1i(glGetUniformLocation(color_components_prog,"selected_mask"),1);
   glUniform1i(glGetUniformLocation(color_components_prog,"selected_mask"),1);
 
 
-    igl::report_gl_error("unif: ");
+    igl::opengl::report_gl_error("unif: ");
   if(fill_visible)
   if(fill_visible)
   {
   {
     glEnable(GL_POLYGON_OFFSET_FILL); // Avoid Stitching!
     glEnable(GL_POLYGON_OFFSET_FILL); // Avoid Stitching!
@@ -585,7 +585,7 @@ void main()
   glTranslated(0,floor_offset,0);
   glTranslated(0,floor_offset,0);
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   pop_scene();
   pop_scene();

+ 19 - 19
examples/embree/example.cpp

@@ -1,13 +1,13 @@
-#include <igl/OpenGL_convenience.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl/OpenGL_convenience.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/normalize_row_lengths.h>
 #include <igl/normalize_row_lengths.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
 #include <igl/quat_to_mat.h>
 #include <igl/quat_to_mat.h>
 #include <igl/read_triangle_mesh.h>
 #include <igl/read_triangle_mesh.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
-#include <igl/unproject.h>
+#include <igl/opengl2/unproject.h>
 #include <igl/embree/EmbreeIntersector.h>
 #include <igl/embree/EmbreeIntersector.h>
 
 
 #ifdef __APPLE__
 #ifdef __APPLE__
@@ -129,7 +129,7 @@ void lights()
   glLightfv(GL_LIGHT1,GL_POSITION,pos);
   glLightfv(GL_LIGHT1,GL_POSITION,pos);
 }
 }
 
 
-// Set up projection and model view of scene
+// Set up igl::opengl2::projection and model view of scene
 void push_scene()
 void push_scene()
 {
 {
   using namespace igl;
   using namespace igl;
@@ -208,7 +208,7 @@ void display()
 
 
   // Draw the model
   // Draw the model
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHTING);
-  draw_mesh(V,F,N,C);
+  igl::opengl2::draw_mesh(V,F,N,C);
 
 
   // Draw all hits
   // Draw all hits
   glBegin(GL_POINTS);
   glBegin(GL_POINTS);
@@ -234,7 +234,7 @@ void display()
   glPushMatrix();
   glPushMatrix();
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHTING);
   glTranslated(0,-1,0);
   glTranslated(0,-1,0);
-  draw_floor();
+  igl::opengl2::draw_floor();
   glPopMatrix();
   glPopMatrix();
 
 
   // draw a transparent "projection screen" show model at time of hit (aka
   // draw a transparent "projection screen" show model at time of hit (aka
@@ -290,7 +290,7 @@ void display()
     glVertex2fv(win_s.data());
     glVertex2fv(win_s.data());
     glEnd();
     glEnd();
   }
   }
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   glutSwapBuffers();
   glutSwapBuffers();
   glutPostRedisplay();
   glutPostRedisplay();
@@ -318,12 +318,12 @@ void mouse_move(int mouse_x, int mouse_y)
   // Unproject mouse at 0 depth and some positive depth
   // Unproject mouse at 0 depth and some positive depth
   win_s = Vector3f(mouse_x,height-mouse_y,0);
   win_s = Vector3f(mouse_x,height-mouse_y,0);
   Vector3f win_d(mouse_x,height-mouse_y,1);
   Vector3f win_d(mouse_x,height-mouse_y,1);
-  unproject(win_s,s);
-  unproject(win_d,d);
+  igl::opengl2::unproject(win_s,s);
+  igl::opengl2::unproject(win_d,d);
   pop_object();
   pop_object();
   pop_scene();
   pop_scene();
-  report_gl_error();
-  // Shoot ray at unprojected mouse in view direction
+  igl::opengl::report_gl_error();
+  // Shoot ray at igl::opengl2::unprojected mouse in view direction
   dir = d-s;
   dir = d-s;
   int num_rays_shot;
   int num_rays_shot;
   ei.intersectRay(s,dir,hits,num_rays_shot);
   ei.intersectRay(s,dir,hits,num_rays_shot);
@@ -365,16 +365,16 @@ void mouse(int glutButton, int glutState, int mouse_x, int mouse_y)
       // Collect "projection screen" locations
       // Collect "projection screen" locations
       push_scene();
       push_scene();
       push_object();
       push_object();
-      // unproject corners of window
+      // igl::opengl2::unproject corners of window
       const double depth = 0.999;
       const double depth = 0.999;
       Vector3d win_NW(    0,height,depth);
       Vector3d win_NW(    0,height,depth);
       Vector3d win_NE(width,height,depth);
       Vector3d win_NE(width,height,depth);
       Vector3d win_SE(width,0,depth);
       Vector3d win_SE(width,0,depth);
       Vector3d win_SW(0,0,depth);
       Vector3d win_SW(0,0,depth);
-      unproject(win_NW,NW);
-      unproject(win_NE,NE);
-      unproject(win_SE,SE);
-      unproject(win_SW,SW);
+      igl::opengl2::unproject(win_NW,NW);
+      igl::opengl2::unproject(win_NE,NE);
+      igl::opengl2::unproject(win_SE,SE);
+      igl::opengl2::unproject(win_SW,SW);
       // render to framebuffer
       // render to framebuffer
       glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id);
       glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id);
       glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, dfbo_id);
       glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, dfbo_id);
@@ -386,7 +386,7 @@ void mouse(int glutButton, int glutState, int mouse_x, int mouse_y)
       glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
       glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
       glEnable(GL_LIGHTING);
       glEnable(GL_LIGHTING);
       glEnable(GL_DEPTH_TEST);
       glEnable(GL_DEPTH_TEST);
-      draw_mesh(V,F,N,C);
+      igl::opengl2::draw_mesh(V,F,N,C);
       pop_object();
       pop_object();
       pop_scene();
       pop_scene();
       glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
       glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

+ 16 - 16
examples/flare-eyes/example.cpp

@@ -2,10 +2,10 @@
 #include <igl/PI.h>
 #include <igl/PI.h>
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
 #include <igl/STR.h>
 #include <igl/STR.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
-#include <igl/lens_flare.h>
+#include <igl/opengl2/lens_flare.h>
 #include <igl/list_to_matrix.h>
 #include <igl/list_to_matrix.h>
 #include <igl/material_colors.h>
 #include <igl/material_colors.h>
 #include <igl/pathinfo.h>
 #include <igl/pathinfo.h>
@@ -16,8 +16,8 @@
 #include <igl/readOBJ.h>
 #include <igl/readOBJ.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/render_to_tga.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/render_to_tga.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -60,7 +60,7 @@
 bool eyes_visible = true;
 bool eyes_visible = true;
 double x=6,y=232,z=61;
 double x=6,y=232,z=61;
 
 
-std::vector<igl::Flare> flares;
+std::vector<igl::opengl2::Flare> flares;
 std::vector<GLuint> shine_ids;
 std::vector<GLuint> shine_ids;
 std::vector<GLuint> flare_ids;
 std::vector<GLuint> flare_ids;
 int shine_tic = 0;
 int shine_tic = 0;
@@ -222,7 +222,7 @@ void draw_flare()
   glScaled(bbd*0.5,bbd*0.5,bbd*0.5);
   glScaled(bbd*0.5,bbd*0.5,bbd*0.5);
   glScaled(0.2,0.2,0.2);
   glScaled(0.2,0.2,0.2);
   Vector3f light(0,0,0);
   Vector3f light(0,0,0);
-  lens_flare_draw(flares,shine_ids,flare_ids,light,1.0,shine_tic);
+  igl::opengl2::lens_flare_draw(flares,shine_ids,flare_ids,light,1.0,shine_tic);
   glPopMatrix();
   glPopMatrix();
 }
 }
 
 
@@ -335,7 +335,7 @@ void display()
     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,  MIDNIGHT_BLUE_DIFFUSE);
     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,  MIDNIGHT_BLUE_DIFFUSE);
     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, SILVER_SPECULAR);
     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, SILVER_SPECULAR);
     glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128);
     glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128);
-    draw_mesh(V,F,N);
+    igl::opengl2::draw_mesh(V,F,N);
     pop_object();
     pop_object();
     // Draw a nice floor
     // Draw a nice floor
     glPushMatrix();
     glPushMatrix();
@@ -344,7 +344,7 @@ void display()
     glTranslated(0,floor_offset,0);
     glTranslated(0,floor_offset,0);
     const float GREY[4] = {0.5,0.5,0.6,1.0};
     const float GREY[4] = {0.5,0.5,0.6,1.0};
     const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
     const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
-    draw_floor(GREY,DARK_GREY);
+    igl::opengl2::draw_floor(GREY,DARK_GREY);
     glPopMatrix();
     glPopMatrix();
 
 
     glEndList();
     glEndList();
@@ -361,13 +361,13 @@ void display()
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   if(render_to_tga_on_next)
   if(render_to_tga_on_next)
   {
   {
     GLint viewport[4];
     GLint viewport[4];
     glGetIntegerv(GL_VIEWPORT,viewport);
     glGetIntegerv(GL_VIEWPORT,viewport);
-    render_to_tga(
+    igl::opengl::render_to_tga(
       STR("./"<< "flare-eyes-" << setw(4) << setfill('0') << render_count++ << ".tga"),
       STR("./"<< "flare-eyes-" << setw(4) << setfill('0') << render_count++ << ".tga"),
       viewport[2],viewport[3],true);
       viewport[2],viewport[3],true);
     //render_to_tga_on_next = false;
     //render_to_tga_on_next = false;
@@ -722,16 +722,16 @@ int main(int argc, char * argv[])
   glutMotionFunc(mouse_drag);
   glutMotionFunc(mouse_drag);
   glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
   glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
   // Init flares
   // Init flares
-  lens_flare_load_textures(shine_ids,flare_ids);
+  igl::opengl2::lens_flare_load_textures(shine_ids,flare_ids);
   const float RED[3] = {1,0,0};
   const float RED[3] = {1,0,0};
   const float GREEN[3] = {0,1,0};
   const float GREEN[3] = {0,1,0};
   const float BLUE[3] = {0,0,1};
   const float BLUE[3] = {0,0,1};
   //lens_flare_create(RED,GREEN,BLUE,flares);
   //lens_flare_create(RED,GREEN,BLUE,flares);
   flares.resize(4);
   flares.resize(4);
-  flares[0] = Flare(-1, 1.0f, 1.*0.1f,  RED, 1.0);
-  flares[1] = Flare(-1, 1.0f, 1.*0.15f, GREEN, 1.0);
-  flares[2] = Flare(-1, 1.0f, 1.*0.35f, BLUE, 1.0);
-  flares[3] = Flare( 2, 1.0f, 1.*0.1f, BLUE, 0.4);
+  flares[0] = igl::opengl2::Flare(-1, 1.0f, 1.*0.1f,  RED, 1.0);
+  flares[1] = igl::opengl2::Flare(-1, 1.0f, 1.*0.15f, GREEN, 1.0);
+  flares[2] = igl::opengl2::Flare(-1, 1.0f, 1.*0.35f, BLUE, 1.0);
+  flares[3] = igl::opengl2::Flare( 2, 1.0f, 1.*0.1f, BLUE, 0.4);
 
 
   glutMainLoop();
   glutMainLoop();
 
 

+ 8 - 8
examples/intersections/example.cpp

@@ -1,9 +1,9 @@
 #include <igl/Camera.h>
 #include <igl/Camera.h>
-#include <igl/OpenGL_convenience.h>
+#include <igl/opengl/OpenGL_convenience.h>
 #include <igl/barycenter.h>
 #include <igl/barycenter.h>
 #include <igl/cat.h>
 #include <igl/cat.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/jet.h>
 #include <igl/jet.h>
 #include <igl/list_to_matrix.h>
 #include <igl/list_to_matrix.h>
@@ -19,7 +19,7 @@
 #include <igl/readOBJ.h>
 #include <igl/readOBJ.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -278,7 +278,7 @@ void display()
     glEnable(GL_POLYGON_OFFSET_FILL); // Avoid Stitching!
     glEnable(GL_POLYGON_OFFSET_FILL); // Avoid Stitching!
     glPolygonOffset(1.0,1);
     glPolygonOffset(1.0,1);
     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-    draw_mesh(V,F,N,C);
+    igl::opengl2::draw_mesh(V,F,N,C);
     glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
     glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
     glDisable(GL_COLOR_MATERIAL);
     glDisable(GL_COLOR_MATERIAL);
     const float black[4] = {0,0,0,1};
     const float black[4] = {0,0,0,1};
@@ -290,7 +290,7 @@ void display()
     glLightfv(GL_LIGHT0, GL_DIFFUSE, black);
     glLightfv(GL_LIGHT0, GL_DIFFUSE, black);
     glLineWidth(1.0);
     glLineWidth(1.0);
     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-    draw_mesh(V,F,N,C);
+    igl::opengl2::draw_mesh(V,F,N,C);
     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     glEnable(GL_COLOR_MATERIAL);
     glEnable(GL_COLOR_MATERIAL);
   };
   };
@@ -312,12 +312,12 @@ void display()
   glTranslated(0,floor_offset,0);
   glTranslated(0,floor_offset,0);
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 16 - 16
examples/multi-viewport/example.cpp

@@ -1,21 +1,21 @@
 #include <igl/Camera.h>
 #include <igl/Camera.h>
 #include <igl/EPS.h>
 #include <igl/EPS.h>
-#include <igl/OpenGL_convenience.h>
+#include <igl/opengl/OpenGL_convenience.h>
 #include <igl/STR.h>
 #include <igl/STR.h>
 #include <igl/Viewport.h>
 #include <igl/Viewport.h>
 #include <igl/canonical_quaternions.h>
 #include <igl/canonical_quaternions.h>
-#include <igl/draw_beach_ball.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_beach_ball.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/normalize_row_lengths.h>
 #include <igl/normalize_row_lengths.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
-#include <igl/project.h>
+#include <igl/opengl2/project.h>
 #include <igl/quat_to_mat.h>
 #include <igl/quat_to_mat.h>
 #include <igl/read_triangle_mesh.h>
 #include <igl/read_triangle_mesh.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
-#include <igl/unproject.h>
-#include <igl/unproject_to_zero_plane.h>
+#include <igl/opengl2/unproject.h>
+#include <igl/opengl2/unproject_to_zero_plane.h>
 
 
 #ifdef __APPLE__
 #ifdef __APPLE__
 #  include <OpenGL/gl.h>
 #  include <OpenGL/gl.h>
@@ -31,7 +31,7 @@
 #include <string>
 #include <string>
 #include <algorithm>
 #include <algorithm>
 #define IGL_HEADER_ONLY
 #define IGL_HEADER_ONLY
-#include <igl/draw_floor.h>
+#include <igl/opengl2/draw_floor.h>
 
 
 #define NUM_VIEWPORTS 4
 #define NUM_VIEWPORTS 4
 class AugViewport : public igl::Viewport
 class AugViewport : public igl::Viewport
@@ -171,7 +171,7 @@ void lights()
   glLightfv(GL_LIGHT1,GL_POSITION,pos);
   glLightfv(GL_LIGHT1,GL_POSITION,pos);
 }
 }
 
 
-// Set up projection and model view of scene
+// Set up igl::opengl2::projection and model view of scene
 void push_scene(const AugViewport & vp)
 void push_scene(const AugViewport & vp)
 {
 {
   using namespace igl;
   using namespace igl;
@@ -246,7 +246,7 @@ void display()
     push_object();
     push_object();
     // Draw the model
     // Draw the model
     glEnable(GL_LIGHTING);
     glEnable(GL_LIGHTING);
-    draw_mesh(V,F,N,C);
+    igl::opengl2::draw_mesh(V,F,N,C);
     pop_object();
     pop_object();
 
 
     // Draw a nice floor
     // Draw a nice floor
@@ -255,11 +255,11 @@ void display()
     glEnable(GL_CULL_FACE);
     glEnable(GL_CULL_FACE);
     glEnable(GL_LIGHTING);
     glEnable(GL_LIGHTING);
     glTranslated(0,-1,0);
     glTranslated(0,-1,0);
-    if(project(Vector3d(0,0,0))(2) - project(Vector3d(0,1,0))(2) > -FLOAT_EPS)
+    if(igl::opengl2::project(Vector3d(0,0,0))(2) - igl::opengl2::project(Vector3d(0,1,0))(2) > -FLOAT_EPS)
     {
     {
-      draw_floor_outline();
+      igl::opengl2::draw_floor_outline();
     }
     }
-    draw_floor();
+    igl::opengl2::draw_floor();
     glPopMatrix();
     glPopMatrix();
     glDisable(GL_CULL_FACE);
     glDisable(GL_CULL_FACE);
 
 
@@ -269,7 +269,7 @@ void display()
       glPushMatrix();
       glPushMatrix();
       glTranslated(ball(0),ball(1),ball(2));
       glTranslated(ball(0),ball(1),ball(2));
       glScaled(0.1,0.1,0.1);
       glScaled(0.1,0.1,0.1);
-      draw_beach_ball();
+      igl::opengl2::draw_beach_ball();
       glPopMatrix();
       glPopMatrix();
     }
     }
 
 
@@ -318,7 +318,7 @@ void display()
   glEnd();
   glEnd();
 
 
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   glutSwapBuffers();
   glutSwapBuffers();
 }
 }
@@ -356,7 +356,7 @@ void mouse_move(int mouse_x, int mouse_y)
         viewports[in_vp].height);
         viewports[in_vp].height);
       push_scene(viewports[in_vp]);
       push_scene(viewports[in_vp]);
       Vector3d screen_ball(mouse_x,height-mouse_y,0);
       Vector3d screen_ball(mouse_x,height-mouse_y,0);
-      unproject_to_zero_plane(screen_ball,ball);
+      igl::opengl2::unproject_to_zero_plane(screen_ball,ball);
       pop_scene();
       pop_scene();
     }
     }
   }
   }

+ 1 - 1
examples/patches/Makefile

@@ -3,7 +3,7 @@
 # Shared flags etc.
 # Shared flags etc.
 include ../Makefile.conf
 include ../Makefile.conf
 ifdef LIBIGL_USE_STATIC_LIBRARY
 ifdef LIBIGL_USE_STATIC_LIBRARY
-	LIBIGL_LIB+=-liglembree -liglboost
+	LIBIGL_LIB+=-liglembree
 endif
 endif
 
 
 all: obj example
 all: obj example

+ 8 - 8
examples/patches/example.cpp

@@ -3,8 +3,8 @@
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
 #include <igl/bfs_orient.h>
 #include <igl/bfs_orient.h>
 #include <igl/components.h>
 #include <igl/components.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/jet.h>
 #include <igl/jet.h>
 #include <igl/list_to_matrix.h>
 #include <igl/list_to_matrix.h>
@@ -21,7 +21,7 @@
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readPLY.h>
 #include <igl/readPLY.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -295,10 +295,10 @@ void display()
     if(fill_visible)
     if(fill_visible)
     {
     {
       glColor3f(0,0,0);
       glColor3f(0,0,0);
-      draw_mesh(V,F,s.N);
+      igl::opengl2::draw_mesh(V,F,s.N);
     }else
     }else
     {
     {
-      draw_mesh(V,F,s.N,s.C);
+      igl::opengl2::draw_mesh(V,F,s.N,s.C);
     }
     }
 
 
     // visualize selected patch
     // visualize selected patch
@@ -338,7 +338,7 @@ void display()
   {
   {
     glEnable(GL_POLYGON_OFFSET_FILL); // Avoid Stitching!
     glEnable(GL_POLYGON_OFFSET_FILL); // Avoid Stitching!
     glPolygonOffset(1.0, 0);
     glPolygonOffset(1.0, 0);
-    draw_mesh(V,F,s.N,s.C);
+    igl::opengl2::draw_mesh(V,F,s.N,s.C);
   }
   }
 
 
   pop_object();
   pop_object();
@@ -350,12 +350,12 @@ void display()
   glTranslated(0,floor_offset,0);
   glTranslated(0,floor_offset,0);
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 6 - 6
examples/randomly-sample-mesh/example.cpp

@@ -1,7 +1,7 @@
 #include <igl/Camera.h>
 #include <igl/Camera.h>
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/list_to_matrix.h>
 #include <igl/list_to_matrix.h>
 #include <igl/material_colors.h>
 #include <igl/material_colors.h>
@@ -14,7 +14,7 @@
 #include <igl/readOBJ.h>
 #include <igl/readOBJ.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -240,7 +240,7 @@ void display()
   glMaterialf (GL_BACK, GL_SHININESS, 128);
   glMaterialf (GL_BACK, GL_SHININESS, 128);
 
 
 
 
-  draw_mesh(V,F,N);
+  igl::opengl2::draw_mesh(V,F,N);
 
 
   glPointSize(3.);
   glPointSize(3.);
   glEnable(GL_POINT_SMOOTH);
   glEnable(GL_POINT_SMOOTH);
@@ -262,12 +262,12 @@ void display()
   glTranslated(0,floor_offset,0);
   glTranslated(0,floor_offset,0);
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 8 - 8
examples/rotate-widget/example.cpp

@@ -1,8 +1,8 @@
 #include <igl/Camera.h>
 #include <igl/Camera.h>
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
-#include <igl/RotateWidget.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/RotateWidget.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/list_to_matrix.h>
 #include <igl/list_to_matrix.h>
 #include <igl/material_colors.h>
 #include <igl/material_colors.h>
@@ -15,7 +15,7 @@
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readTGF.h>
 #include <igl/readTGF.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -63,7 +63,7 @@ Eigen::VectorXi P;
 struct State
 struct State
 {
 {
   igl::Camera camera;
   igl::Camera camera;
-  igl::RotateWidget widget;
+  igl::opengl2::RotateWidget widget;
 } s;
 } s;
 
 
 bool wireframe = false;
 bool wireframe = false;
@@ -251,7 +251,7 @@ void display()
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   push_object();
   push_object();
@@ -272,7 +272,7 @@ void display()
   glTranslated( s.widget.pos(0), s.widget.pos(1), s.widget.pos(2));
   glTranslated( s.widget.pos(0), s.widget.pos(1), s.widget.pos(2));
   glMultMatrixd(Affine3d(s.widget.rot).matrix().data());
   glMultMatrixd(Affine3d(s.widget.rot).matrix().data());
   glTranslated( -s.widget.pos(0), -s.widget.pos(1), -s.widget.pos(2));
   glTranslated( -s.widget.pos(0), -s.widget.pos(1), -s.widget.pos(2));
-  draw_mesh(V,F,N);
+  igl::opengl2::draw_mesh(V,F,N);
   glPopMatrix();
   glPopMatrix();
 
 
   if(widget_on_top)
   if(widget_on_top)
@@ -286,7 +286,7 @@ void display()
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 6 - 6
examples/scene-rotation/example.cpp

@@ -5,8 +5,8 @@
 
 
 #include <igl/Camera.h>
 #include <igl/Camera.h>
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/list_to_matrix.h>
 #include <igl/list_to_matrix.h>
 #include <igl/material_colors.h>
 #include <igl/material_colors.h>
@@ -18,7 +18,7 @@
 #include <igl/readOBJ.h>
 #include <igl/readOBJ.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -262,7 +262,7 @@ void display()
   glMaterialf (GL_BACK, GL_SHININESS, 128);
   glMaterialf (GL_BACK, GL_SHININESS, 128);
 
 
 
 
-  draw_mesh(V,F,N);
+  igl::opengl2::draw_mesh(V,F,N);
   pop_object();
   pop_object();
 
 
   // Draw a nice floor
   // Draw a nice floor
@@ -272,12 +272,12 @@ void display()
   glTranslated(0,floor_offset,0);
   glTranslated(0,floor_offset,0);
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 1 - 1
examples/scene-rotation/trackball.cpp

@@ -177,7 +177,7 @@ trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
     }
     }
 
 
     /*
     /*
-     * First, figure out z-coordinates for projection of P1 and P2 to
+     * First, figure out z-coordinates for igl::opengl2::projection of P1 and P2 to
      * deformed sphere
      * deformed sphere
      */
      */
     vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));
     vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));

+ 6 - 6
examples/shadow-mapping/example.cpp

@@ -3,8 +3,8 @@
 
 
 #include <igl/C_STR.h>
 #include <igl/C_STR.h>
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/jet.h>
 #include <igl/jet.h>
 #include <igl/list_to_matrix.h>
 #include <igl/list_to_matrix.h>
@@ -20,7 +20,7 @@
 #include <igl/readOBJ.h>
 #include <igl/readOBJ.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
 #include <igl/unique_simplices.h>
 #include <igl/unique_simplices.h>
@@ -244,7 +244,7 @@ void push_scene(
   double z_fix = 1.0;
   double z_fix = 1.0;
   // 5 is far enough to see unit "things" well
   // 5 is far enough to see unit "things" well
   const double camera_z = 2;
   const double camera_z = 2;
-  // Test if should be using true orthographic projection
+  // Test if should be using true orthographic igl::opengl2::projection
   if(angle == 0)
   if(angle == 0)
   {
   {
     glOrtho(
     glOrtho(
@@ -377,7 +377,7 @@ void draw_objects()
     glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128);
     glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128);
     glPushMatrix();
     glPushMatrix();
     glMultMatrixd(mesh.a.matrix().data());
     glMultMatrixd(mesh.a.matrix().data());
-    draw_mesh(mesh.V,mesh.F,mesh.N);
+    igl::opengl2::draw_mesh(mesh.V,mesh.F,mesh.N);
     glPopMatrix();
     glPopMatrix();
   }
   }
 
 
@@ -472,7 +472,7 @@ void display()
 
 
   draw_scene();
   draw_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();
   glutPostRedisplay();
   glutPostRedisplay();

+ 39 - 27
examples/skeleton-builder/example.cpp

@@ -6,10 +6,10 @@
 #include <igl/boundary_conditions.h>
 #include <igl/boundary_conditions.h>
 #include <igl/centroid.h>
 #include <igl/centroid.h>
 #include <igl/colon.h>
 #include <igl/colon.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
-#include <igl/draw_skeleton_3d.h>
-#include <igl/draw_skeleton_vector_graphics.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
+#include <igl/opengl2/draw_skeleton_3d.h>
+#include <igl/opengl2/draw_skeleton_vector_graphics.h>
 #include <igl/file_exists.h>
 #include <igl/file_exists.h>
 #include <igl/forward_kinematics.h>
 #include <igl/forward_kinematics.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
@@ -20,21 +20,22 @@
 #include <igl/normalize_row_sums.h>
 #include <igl/normalize_row_sums.h>
 #include <igl/pathinfo.h>
 #include <igl/pathinfo.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
-#include <igl/project.h>
+#include <igl/opengl2/project.h>
 #include <igl/quat_to_mat.h>
 #include <igl/quat_to_mat.h>
 #include <igl/readTGF.h>
 #include <igl/readTGF.h>
 #include <igl/read_triangle_mesh.h>
 #include <igl/read_triangle_mesh.h>
 #include <igl/remove_unreferenced.h>
 #include <igl/remove_unreferenced.h>
-#include <igl/report_gl_error.h>
-#include <igl/right_axis.h>
+#include <igl/opengl/report_gl_error.h>
+#include <igl/opengl2/right_axis.h>
 #include <igl/slice.h>
 #include <igl/slice.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
-#include <igl/sort_triangles.h>
+#include <igl/opengl2/sort_triangles.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
 #include <igl/two_axis_valuator_fixed_up.h>
 #include <igl/two_axis_valuator_fixed_up.h>
 #include <igl/unique.h>
 #include <igl/unique.h>
-#include <igl/unproject.h>
+#include <igl/opengl2/unproject.h>
+#include <igl/opengl2/model_proj_viewport.h>
 #include <igl/writeOBJ.h>
 #include <igl/writeOBJ.h>
 #include <igl/writeOFF.h>
 #include <igl/writeOFF.h>
 #include <igl/writeTGF.h>
 #include <igl/writeTGF.h>
@@ -248,7 +249,7 @@ void sort()
   push_scene();
   push_scene();
   push_object();
   push_object();
   VectorXi I;
   VectorXi I;
-  sort_triangles(V,F,sorted_F,I);
+  igl::opengl2::sort_triangles(V,F,sorted_F,I);
   slice(N,I,1,sorted_N);
   slice(N,I,1,sorted_N);
   pop_object();
   pop_object();
   pop_scene();
   pop_scene();
@@ -301,7 +302,7 @@ void display()
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glEnable(GL_CULL_FACE);
   glEnable(GL_CULL_FACE);
   glCullFace(GL_BACK);
   glCullFace(GL_BACK);
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glDisable(GL_CULL_FACE);
   glDisable(GL_CULL_FACE);
   glPopMatrix();
   glPopMatrix();
 
 
@@ -325,11 +326,11 @@ void display()
             }
             }
           }
           }
         }
         }
-        draw_skeleton_3d(s.C,s.BE,MatrixXd(),colors,bbd*0.5);
+        igl::opengl2::draw_skeleton_3d(s.C,s.BE,MatrixXd(),colors,bbd*0.5);
         break;
         break;
       }
       }
       case SKEL_STYLE_TYPE_VECTOR_GRAPHICS:
       case SKEL_STYLE_TYPE_VECTOR_GRAPHICS:
-        draw_skeleton_vector_graphics(s.C,s.BE);
+        igl::opengl2::draw_skeleton_vector_graphics(s.C,s.BE);
         break;
         break;
     }
     }
   };
   };
@@ -361,7 +362,7 @@ void display()
     glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
     glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
   }
   }
   glLineWidth(1.0);
   glLineWidth(1.0);
-  draw_mesh(V,sorted_F,sorted_N);
+  igl::opengl2::draw_mesh(V,sorted_F,sorted_N);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
 
 
   if(skeleton_on_top)
   if(skeleton_on_top)
@@ -373,7 +374,7 @@ void display()
   pop_object();
   pop_object();
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();
@@ -468,7 +469,7 @@ bool ss_select(
   for(int c = 0;c<C.rows();c++)
   for(int c = 0;c<C.rows();c++)
   {
   {
     const RowVector3d & Cc = C.row(c);
     const RowVector3d & Cc = C.row(c);
-    const auto Pc = project(Cc);
+    const auto Pc = igl::opengl2::project(Cc);
     const double SELECTION_DIST = 18;//pixels
     const double SELECTION_DIST = 18;//pixels
     const double dist = (Pc.head(2)-RowVector2d(mouse_x,height-mouse_y)).norm();
     const double dist = (Pc.head(2)-RowVector2d(mouse_x,height-mouse_y)).norm();
     if(dist < SELECTION_DIST && (accum || dist < min_dist))
     if(dist < SELECTION_DIST && (accum || dist < min_dist))
@@ -662,17 +663,24 @@ void mouse_drag(int mouse_x, int mouse_y)
       down_C = s.C;
       down_C = s.C;
       new_leaf_on_drag = false;
       new_leaf_on_drag = false;
     }
     }
+      Eigen::Matrix4f model,proj;
+      Eigen::Vector4f viewport;
+      igl::opengl2::model_proj_viewport(model,proj,viewport);
+      Eigen::Vector2f pos(mouse_x,height-mouse_y);
     if(new_root_on_drag)
     if(new_root_on_drag)
     {
     {
       // two new nodes
       // two new nodes
       s.C.conservativeResize(s.C.rows()+2,3);
       s.C.conservativeResize(s.C.rows()+2,3);
       const int nc = s.C.rows();
       const int nc = s.C.rows();
       Vector3d obj;
       Vector3d obj;
-      int nhits = igl::embree::unproject_in_mesh(mouse_x,height-mouse_y,ei,obj);
+
+      int nhits = igl::embree::unproject_in_mesh(
+          pos,model,proj,viewport,ei,obj);
+
       if(nhits == 0)
       if(nhits == 0)
       {
       {
-        Vector3d pV_mid = project(Vcen);
-        obj = unproject(Vector3d(mouse_x,height-mouse_y,pV_mid(2)));
+        Vector3d pV_mid = igl::opengl2::project(Vcen);
+        obj = igl::opengl2::unproject(Vector3d(mouse_x,height-mouse_y,pV_mid(2)));
       }
       }
       s.C.row(nc-2) = obj;
       s.C.row(nc-2) = obj;
       s.C.row(nc-1) = obj;
       s.C.row(nc-1) = obj;
@@ -688,21 +696,21 @@ void mouse_drag(int mouse_x, int mouse_y)
     }
     }
     double z = 0;
     double z = 0;
     Vector3d obj,win;
     Vector3d obj,win;
-    int nhits = igl::embree::unproject_in_mesh(mouse_x,height-mouse_y,ei,obj);
-    project(obj,win);
+    int nhits = igl::embree::unproject_in_mesh(pos,model,proj,viewport,ei,obj);
+    igl::opengl2::project(obj,win);
     z = win(2);
     z = win(2);
 
 
     for(int si = 0;si<s.sel.size();si++)
     for(int si = 0;si<s.sel.size();si++)
     {
     {
       const int c = s.sel(si);
       const int c = s.sel(si);
-      Vector3d pc = project((RowVector3d) down_C.row(c));
+      Vector3d pc = igl::opengl2::project((RowVector3d) down_C.row(c));
       pc(0) += mouse_x-down_x;
       pc(0) += mouse_x-down_x;
       pc(1) += (height-mouse_y)-(height-down_y);
       pc(1) += (height-mouse_y)-(height-down_y);
       if(nhits > 0)
       if(nhits > 0)
       {
       {
         pc(2) = z;
         pc(2) = z;
       }
       }
-      s.C.row(c) = unproject(pc);
+      s.C.row(c) = igl::opengl2::unproject(pc);
     }
     }
     pop_object();
     pop_object();
     pop_scene();
     pop_scene();
@@ -762,7 +770,7 @@ void symmetrize()
   push_scene();
   push_scene();
   push_object();
   push_object();
   Vector3d right;
   Vector3d right;
-  right_axis(right.data(),right.data()+1,right.data()+2);
+  igl::opengl2::right_axis(right.data(),right.data()+1,right.data()+2);
   right.normalize();
   right.normalize();
   MatrixXd RC(s.C.rows(),s.C.cols());
   MatrixXd RC(s.C.rows(),s.C.cols());
   MatrixXd old_C = s.C;
   MatrixXd old_C = s.C;
@@ -1014,9 +1022,13 @@ void key(unsigned char key, int mouse_x, int mouse_y)
       push_object();
       push_object();
       for(int c = 0;c<s.C.rows();c++)
       for(int c = 0;c<s.C.rows();c++)
       {
       {
-        Vector3d P = project((Vector3d)s.C.row(c));
+        Vector3d P = igl::opengl2::project((Vector3d)s.C.row(c));
         Vector3d obj;
         Vector3d obj;
-        int nhits = igl::embree::unproject_in_mesh(P(0),P(1),ei,obj);
+        Eigen::Matrix4f model,proj;
+        Eigen::Vector4f viewport;
+        igl::opengl2::model_proj_viewport(model,proj,viewport);
+        Eigen::Vector2f pos(P(0),P(1));
+        int nhits = igl::embree::unproject_in_mesh(pos,model,proj,viewport,ei,obj);
         if(nhits > 0)
         if(nhits > 0)
         {
         {
           s.C.row(c) = obj;
           s.C.row(c) = obj;
@@ -1105,7 +1117,7 @@ int main(int argc, char * argv[])
   cout<<"P,p                    Split \"parent\" bone(s) of selection by creating new node(s)."<<endl;
   cout<<"P,p                    Split \"parent\" bone(s) of selection by creating new node(s)."<<endl;
   cout<<"R,r                    Breadth first search at selection to redirect skeleton into tree."<<endl;
   cout<<"R,r                    Breadth first search at selection to redirect skeleton into tree."<<endl;
   cout<<"S,s                    Save current skeleton to output .tgf file."<<endl;
   cout<<"S,s                    Save current skeleton to output .tgf file."<<endl;
-  cout<<"U,u                    Project then unproject inside mesh (as if dragging each by ε)."<<endl;
+  cout<<"U,u                    Project then igl::opengl2::unproject inside mesh (as if dragging each by ε)."<<endl;
   cout<<"Y,Y                    Symmetrize selection over plane through object centroid and right vector."<<endl;
   cout<<"Y,Y                    Symmetrize selection over plane through object centroid and right vector."<<endl;
   cout<<"Z,z                    Snap to canonical view."<<endl;
   cout<<"Z,z                    Snap to canonical view."<<endl;
   cout<<"⌘ Z                    Undo."<<endl;
   cout<<"⌘ Z                    Undo."<<endl;

+ 15 - 14
examples/skeleton-poser/example.cpp

@@ -1,5 +1,5 @@
 #include <igl/Camera.h>
 #include <igl/Camera.h>
-#include <igl/MouseController.h>
+#include <igl/opengl2/MouseController.h>
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
 #include <igl/STR.h>
 #include <igl/STR.h>
 #include <igl/barycenter.h>
 #include <igl/barycenter.h>
@@ -8,11 +8,11 @@
 #include <igl/boundary_facets.h>
 #include <igl/boundary_facets.h>
 #include <igl/centroid.h>
 #include <igl/centroid.h>
 #include <igl/colon.h>
 #include <igl/colon.h>
-#include <igl/draw_beach_ball.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
-#include <igl/draw_skeleton_3d.h>
-#include <igl/draw_skeleton_vector_graphics.h>
+#include <igl/opengl2/draw_beach_ball.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
+#include <igl/opengl2/draw_skeleton_3d.h>
+#include <igl/opengl2/draw_skeleton_vector_graphics.h>
 #include <igl/forward_kinematics.h>
 #include <igl/forward_kinematics.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/lbs_matrix.h>
 #include <igl/lbs_matrix.h>
@@ -26,7 +26,7 @@
 #include <igl/readTGF.h>
 #include <igl/readTGF.h>
 #include <igl/read_triangle_mesh.h>
 #include <igl/read_triangle_mesh.h>
 #include <igl/remove_unreferenced.h>
 #include <igl/remove_unreferenced.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -97,7 +97,7 @@ Eigen::VectorXi P,RP;
 
 
 struct State
 struct State
 {
 {
-  igl::MouseController mouse;
+  igl::opengl2::MouseController mouse;
   Eigen::MatrixXf colors;
   Eigen::MatrixXf colors;
 } s;
 } s;
 
 
@@ -295,7 +295,7 @@ void display()
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glEnable(GL_CULL_FACE);
   glEnable(GL_CULL_FACE);
   glCullFace(GL_BACK);
   glCullFace(GL_BACK);
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glDisable(GL_CULL_FACE);
   glDisable(GL_CULL_FACE);
   glPopMatrix();
   glPopMatrix();
 
 
@@ -308,11 +308,11 @@ void display()
       default:
       default:
       case SKEL_STYLE_TYPE_3D:
       case SKEL_STYLE_TYPE_3D:
       {
       {
-        draw_skeleton_3d(C,BE,T,s.colors,bbd*0.5);
+        igl::opengl2::draw_skeleton_3d(C,BE,T,s.colors,bbd*0.5);
         break;
         break;
       }
       }
       case SKEL_STYLE_TYPE_VECTOR_GRAPHICS:
       case SKEL_STYLE_TYPE_VECTOR_GRAPHICS:
-        draw_skeleton_vector_graphics(C,BE,T);
+        igl::opengl2::draw_skeleton_vector_graphics(C,BE,T);
         break;
         break;
     }
     }
   };
   };
@@ -359,7 +359,7 @@ void display()
   MatrixXd U = M*T;
   MatrixXd U = M*T;
   MatrixXd UN;
   MatrixXd UN;
   per_face_normals(U,F,UN);
   per_face_normals(U,F,UN);
-  draw_mesh(U,F,UN);
+  igl::opengl2::draw_mesh(U,F,UN);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_DEPTH_TEST);
   draw_skeleton(T);
   draw_skeleton(T);
@@ -375,7 +375,7 @@ void display()
     glScaled(0.1,0.1,0.1);
     glScaled(0.1,0.1,0.1);
     glEnable(GL_POLYGON_OFFSET_FILL);
     glEnable(GL_POLYGON_OFFSET_FILL);
     glPolygonOffset(0,-100000);
     glPolygonOffset(0,-100000);
-    draw_beach_ball();
+    igl::opengl2::draw_beach_ball();
     glDisable(GL_POLYGON_OFFSET_FILL);
     glDisable(GL_POLYGON_OFFSET_FILL);
     glPopMatrix();
     glPopMatrix();
   }
   }
@@ -389,7 +389,7 @@ void display()
   pop_object();
   pop_object();
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();
@@ -459,6 +459,7 @@ void mouse(int glutButton, int glutState, int mouse_x, int mouse_y)
           if(mouse_was_selecting)
           if(mouse_was_selecting)
           {
           {
             s.mouse.set_selection_from_last_drag(C,BE,P,RP);
             s.mouse.set_selection_from_last_drag(C,BE,P,RP);
+            using namespace igl::opengl2;
             MouseController::VectorXb S;
             MouseController::VectorXb S;
             MouseController::propogate_to_descendants_if(
             MouseController::propogate_to_descendants_if(
               s.mouse.selection(),P,S);
               s.mouse.selection(),P,S);

+ 10 - 10
examples/skeleton/example.cpp

@@ -1,10 +1,10 @@
 #include <igl/Camera.h>
 #include <igl/Camera.h>
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
 #include <igl/boundary_conditions.h>
 #include <igl/boundary_conditions.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
-#include <igl/draw_skeleton_3d.h>
-#include <igl/draw_skeleton_vector_graphics.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
+#include <igl/opengl2/draw_skeleton_3d.h>
+#include <igl/opengl2/draw_skeleton_vector_graphics.h>
 #include <igl/forward_kinematics.h>
 #include <igl/forward_kinematics.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/lbs_matrix.h>
 #include <igl/lbs_matrix.h>
@@ -20,7 +20,7 @@
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readTGF.h>
 #include <igl/readTGF.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
@@ -255,7 +255,7 @@ void display()
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float GREY[4] = {0.5,0.5,0.6,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   const float DARK_GREY[4] = {0.2,0.2,0.3,1.0};
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   push_object();
   push_object();
@@ -296,7 +296,7 @@ void display()
   glLineWidth(1.0);
   glLineWidth(1.0);
   MatrixXd U = M*T;
   MatrixXd U = M*T;
   per_face_normals(U,F,N);
   per_face_normals(U,F,N);
-  draw_mesh(U,F,N);
+  igl::opengl2::draw_mesh(U,F,N);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
 
 
   if(skeleton_on_top)
   if(skeleton_on_top)
@@ -308,10 +308,10 @@ void display()
   {
   {
     default:
     default:
     case SKEL_STYLE_TYPE_3D:
     case SKEL_STYLE_TYPE_3D:
-      draw_skeleton_3d(C,BE,T,MAYA_VIOLET,bbd*0.5);
+      igl::opengl2::draw_skeleton_3d(C,BE,T,MAYA_VIOLET,bbd*0.5);
       break;
       break;
     case SKEL_STYLE_TYPE_VECTOR_GRAPHICS:
     case SKEL_STYLE_TYPE_VECTOR_GRAPHICS:
-      draw_skeleton_vector_graphics(C,BE,T);
+      igl::opengl2::draw_skeleton_vector_graphics(C,BE,T);
       break;
       break;
   }
   }
 
 
@@ -319,7 +319,7 @@ void display()
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 7 - 8
examples/textured-mesh/example.cpp

@@ -1,9 +1,9 @@
 #include <igl/Camera.h>
 #include <igl/Camera.h>
-#include <igl/OpenGL_convenience.h>
+#include <igl/opengl/OpenGL_convenience.h>
 #include <igl/STR.h>
 #include <igl/STR.h>
 #include <igl/barycenter.h>
 #include <igl/barycenter.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
 #include <igl/jet.h>
 #include <igl/jet.h>
 #include <igl/list_to_matrix.h>
 #include <igl/list_to_matrix.h>
@@ -20,10 +20,9 @@
 #include <igl/readOBJ.h>
 #include <igl/readOBJ.h>
 #include <igl/readOFF.h>
 #include <igl/readOFF.h>
 #include <igl/readWRL.h>
 #include <igl/readWRL.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_canonical_view_quat.h>
 #include <igl/snap_to_fixed_up.h>
 #include <igl/snap_to_fixed_up.h>
-#include <igl/texture_from_tga.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
 #include <igl/two_axis_valuator_fixed_up.h>
 #include <igl/two_axis_valuator_fixed_up.h>
 #include <igl/anttweakbar/ReAntTweakBar.h>
 #include <igl/anttweakbar/ReAntTweakBar.h>
@@ -287,7 +286,7 @@ void display()
   }
   }
   glMatrixMode(GL_MODELVIEW);
   glMatrixMode(GL_MODELVIEW);
 
 
-  draw_mesh(V,F,N,MatrixXi(),MatrixXd(),TC,TF,MatrixXd(),0,MatrixXi(),0);
+  igl::opengl2::draw_mesh(V,F,N,MatrixXi(),MatrixXd(),TC,TF,MatrixXd(),0,MatrixXi(),0);
 
 
   glMatrixMode(GL_TEXTURE);
   glMatrixMode(GL_TEXTURE);
   glPopMatrix();
   glPopMatrix();
@@ -320,12 +319,12 @@ void display()
   glDisable(GL_POLYGON_OFFSET_FILL);
   glDisable(GL_POLYGON_OFFSET_FILL);
   glDisable(GL_TEXTURE_2D);
   glDisable(GL_TEXTURE_2D);
 
 
-  draw_floor(GREY,DARK_GREY);
+  igl::opengl2::draw_floor(GREY,DARK_GREY);
   glPopMatrix();
   glPopMatrix();
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
 
 
   TwDraw();
   TwDraw();
   glutSwapBuffers();
   glutSwapBuffers();

+ 1 - 1
examples/transparency/Makefile

@@ -7,7 +7,7 @@ all: example
 
 
 .PHONY: example
 .PHONY: example
 
 
-CFLAGS+=-O3 -fopenmp
+CFLAGS+=-O3 
 
 
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC)
 INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)
 LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB)

+ 12 - 12
examples/transparency/example.cpp

@@ -1,8 +1,8 @@
 #include <igl/EPS.h>
 #include <igl/EPS.h>
-#include <igl/OpenGL_convenience.h>
+#include <igl/opengl/OpenGL_convenience.h>
 #include <igl/colon.h>
 #include <igl/colon.h>
-#include <igl/draw_floor.h>
-#include <igl/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
 #include <igl/jet.h>
 #include <igl/jet.h>
 #include <igl/material_colors.h>
 #include <igl/material_colors.h>
 #include <igl/matlab_format.h>
 #include <igl/matlab_format.h>
@@ -10,12 +10,12 @@
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
 #include <igl/quat_to_mat.h>
 #include <igl/quat_to_mat.h>
 #include <igl/read_triangle_mesh.h>
 #include <igl/read_triangle_mesh.h>
-#include <igl/report_gl_error.h>
-#include <igl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
+#include <igl/opengl/report_gl_error.h>
 #include <igl/slice.h>
 #include <igl/slice.h>
-#include <igl/sort_triangles.h>
+#include <igl/opengl2/sort_triangles.h>
 #include <igl/trackball.h>
 #include <igl/trackball.h>
-#include <igl/unproject.h>
+#include <igl/opengl2/unproject.h>
 #include <igl/anttweakbar/ReAntTweakBar.h>
 #include <igl/anttweakbar/ReAntTweakBar.h>
 
 
 #ifdef __APPLE__
 #ifdef __APPLE__
@@ -87,7 +87,7 @@ void lights()
   glLightfv(GL_LIGHT1,GL_POSITION,pos);
   glLightfv(GL_LIGHT1,GL_POSITION,pos);
 }
 }
 
 
-// Set up projection and model view of scene
+// Set up igl::opengl2::projection and model view of scene
 void push_scene()
 void push_scene()
 {
 {
   using namespace igl;
   using namespace igl;
@@ -154,7 +154,7 @@ void mouse(int glutButton, int glutState, int mouse_x, int mouse_y)
       // sort!
       // sort!
       push_scene();
       push_scene();
       push_object();
       push_object();
-      sort_triangles(V,F,sorted_F,I);
+      igl::opengl2::sort_triangles(V,F,sorted_F,I);
       slice(N,I,1,sorted_N);
       slice(N,I,1,sorted_N);
       init_C(I);
       init_C(I);
       pop_object();
       pop_object();
@@ -206,7 +206,7 @@ void display()
   glTranslated(0,-1000*FLOAT_EPS,0);
   glTranslated(0,-1000*FLOAT_EPS,0);
   glEnable(GL_CULL_FACE);
   glEnable(GL_CULL_FACE);
   glCullFace(GL_BACK);
   glCullFace(GL_BACK);
-  draw_floor();
+  igl::opengl2::draw_floor();
   pop_object();
   pop_object();
 
 
   glDisable(GL_CULL_FACE);
   glDisable(GL_CULL_FACE);
@@ -241,12 +241,12 @@ void display()
 
 
   push_object();
   push_object();
   // Draw the model
   // Draw the model
-  draw_mesh(V,sorted_F,sorted_N,C);
+  igl::opengl2::draw_mesh(V,sorted_F,sorted_N,C);
   pop_object();
   pop_object();
 
 
   pop_scene();
   pop_scene();
 
 
-  report_gl_error();
+  igl::opengl::report_gl_error();
   glutSwapBuffers();
   glutSwapBuffers();
   glutPostRedisplay();
   glutPostRedisplay();
 }
 }

+ 5 - 5
examples/upright/example.cpp

@@ -9,8 +9,8 @@
 // lost in the output file.
 // lost in the output file.
 //
 //
 #include <igl/read_triangle_mesh.h>
 #include <igl/read_triangle_mesh.h>
-#include <igl/draw_mesh.h>
-#include <igl/draw_floor.h>
+#include <igl/opengl2/draw_mesh.h>
+#include <igl/opengl2/draw_floor.h>
 #include <igl/pathinfo.h>
 #include <igl/pathinfo.h>
 #include <igl/list_to_matrix.h>
 #include <igl/list_to_matrix.h>
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
@@ -99,7 +99,7 @@ void push_scene()
   double z_fix = 1.0;
   double z_fix = 1.0;
   // 5 is far enough to see unit "things" well
   // 5 is far enough to see unit "things" well
   const double camera_z = 2;
   const double camera_z = 2;
-  // Test if should be using true orthographic projection
+  // Test if should be using true orthographic igl::opengl2::projection
   if(angle == 0)
   if(angle == 0)
   {
   {
     glOrtho(
     glOrtho(
@@ -194,7 +194,7 @@ void display()
   glMaterialf (GL_BACK, GL_SHININESS, 128);
   glMaterialf (GL_BACK, GL_SHININESS, 128);
 
 
 
 
-  draw_mesh(s.V,s.F,s.N);
+  igl::opengl2::draw_mesh(s.V,s.F,s.N);
 
 
   glDisable(GL_LIGHTING);
   glDisable(GL_LIGHTING);
   glPushMatrix();
   glPushMatrix();
@@ -230,7 +230,7 @@ void display()
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHTING);
   glPushMatrix();
   glPushMatrix();
   glTranslated(0,-1,0);
   glTranslated(0,-1,0);
-  draw_floor();
+  igl::opengl2::draw_floor();
   glPopMatrix();
   glPopMatrix();
   pop_scene();
   pop_scene();
 
 

+ 2 - 2
google-soc/index.html

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

+ 16 - 7
include/igl/AABB.h

@@ -484,7 +484,7 @@ inline std::vector<int> igl::AABB<DerivedV,DIM>::find(
   if(is_leaf())
   if(is_leaf())
   {
   {
     // Initialize to some value > -epsilon
     // Initialize to some value > -epsilon
-    Scalar a1=1,a2=1,a3=1,a4=1;
+    Scalar a1=0,a2=0,a3=0,a4=0;
     switch(DIM)
     switch(DIM)
     {
     {
       case 3:
       case 3:
@@ -511,7 +511,6 @@ inline std::vector<int> igl::AABB<DerivedV,DIM>::find(
           // Hack for now to keep templates simple. If becomes bottleneck
           // Hack for now to keep templates simple. If becomes bottleneck
           // consider using std::enable_if_t 
           // consider using std::enable_if_t 
           const Vector2S q2 = q.head(2);
           const Vector2S q2 = q.head(2);
-          Scalar a0 = doublearea_single(V1,V2,V3);
           a1 = doublearea_single(V1,V2,q2);
           a1 = doublearea_single(V1,V2,q2);
           a2 = doublearea_single(V2,V3,q2);
           a2 = doublearea_single(V2,V3,q2);
           a3 = doublearea_single(V3,V1,q2);
           a3 = doublearea_single(V3,V1,q2);
@@ -519,6 +518,12 @@ inline std::vector<int> igl::AABB<DerivedV,DIM>::find(
         }
         }
       default:assert(false);
       default:assert(false);
     }
     }
+    // Normalization is important for correcting sign
+    Scalar sum = a1+a2+a3+a4;
+    a1 /= sum;
+    a2 /= sum;
+    a3 /= sum;
+    a4 /= sum;
     if(
     if(
         a1>=-epsilon && 
         a1>=-epsilon && 
         a2>=-epsilon && 
         a2>=-epsilon && 
@@ -624,7 +629,7 @@ igl::AABB<DerivedV,DIM>::squared_distance(
   using namespace std;
   using namespace std;
   using namespace igl;
   using namespace igl;
   Scalar sqr_d = min_sqr_d;
   Scalar sqr_d = min_sqr_d;
-  assert(DIM == 3 && "Code has only been tested for DIM == 3");
+  //assert(DIM == 3 && "Code has only been tested for DIM == 3");
   assert((Ele.cols() == 3 || Ele.cols() == 2 || Ele.cols() == 1)
   assert((Ele.cols() == 3 || Ele.cols() == 2 || Ele.cols() == 1)
     && "Code has only been tested for simplex sizes 3,2,1");
     && "Code has only been tested for simplex sizes 3,2,1");
 
 
@@ -1007,9 +1012,14 @@ inline void igl::AABB<DerivedV,DIM>::leaf_squared_distance(
       Ele(m_primitive,1) != Ele(m_primitive,2) && 
       Ele(m_primitive,1) != Ele(m_primitive,2) && 
       Ele(m_primitive,2) != Ele(m_primitive,0))
       Ele(m_primitive,2) != Ele(m_primitive,0))
   {
   {
-    const RowVectorDIMS v10 = (V.row(Ele(m_primitive,1))- V.row(Ele(m_primitive,0)));
-    const RowVectorDIMS v20 = (V.row(Ele(m_primitive,2))- V.row(Ele(m_primitive,0)));
-    const RowVectorDIMS n = v10.cross(v20);
+    assert(DIM == 3 && "Only implemented for 3D triangles");
+    typedef Eigen::Matrix<Scalar,1,3> RowVector3S;
+    // can't be const because of annoying DIM template
+    RowVector3S v10(0,0,0);
+    v10.head(DIM) = (V.row(Ele(m_primitive,1))- V.row(Ele(m_primitive,0)));
+    RowVector3S v20(0,0,0);
+    v20.head(DIM) = (V.row(Ele(m_primitive,2))- V.row(Ele(m_primitive,0)));
+    const RowVectorDIMS n = (v10.cross(v20)).head(DIM);
     Scalar n_norm = n.norm();
     Scalar n_norm = n.norm();
     if(n_norm > 0)
     if(n_norm > 0)
     {
     {
@@ -1037,7 +1047,6 @@ inline void igl::AABB<DerivedV,DIM>::leaf_squared_distance(
   }
   }
   const auto & point_point_squared_distance = [&](const RowVectorDIMS & s)
   const auto & point_point_squared_distance = [&](const RowVectorDIMS & s)
   {
   {
-    cout<<"pp"<<endl;
     const Scalar sqr_d_s = (p-s).squaredNorm();
     const Scalar sqr_d_s = (p-s).squaredNorm();
     set_min(p,sqr_d_s,m_primitive,s,sqr_d,i,c);
     set_min(p,sqr_d_s,m_primitive,s,sqr_d,i,c);
   };
   };

+ 1 - 1
include/igl/ARAPEnergyType.h

@@ -22,7 +22,7 @@ namespace igl
   //       deformation" by [Chao et al.  2010], rotations defined at elements
   //       deformation" by [Chao et al.  2010], rotations defined at elements
   //       (triangles or tets) 
   //       (triangles or tets) 
   //     ARAP_ENERGY_TYPE_DEFAULT  Choose one automatically: spokes and rims
   //     ARAP_ENERGY_TYPE_DEFAULT  Choose one automatically: spokes and rims
-  //       for surfaces, elements for planar meshes and test (not fully
+  //       for surfaces, elements for planar meshes and tets (not fully
   //       supported)
   //       supported)
   enum ARAPEnergyType
   enum ARAPEnergyType
   {
   {

+ 1 - 1
include/igl/HalfEdgeIterator.h

@@ -31,7 +31,7 @@ namespace igl
         int _ei,
         int _ei,
         bool _reverse = false
         bool _reverse = false
         )
         )
-    : F(_F), FF(_FF), FFi(_FFi), fi(_fi), ei(_ei), reverse(_reverse)
+    : fi(_fi), ei(_ei), reverse(_reverse), F(_F), FF(_FF), FFi(_FFi)
     {}
     {}
 
 
     // Change Face
     // Change Face

+ 4 - 2
include/igl/arap.cpp

@@ -153,7 +153,8 @@ IGL_INLINE bool igl::arap_precomputation(
     assert(h != 0);
     assert(h != 0);
     SparseMatrix<double> M;
     SparseMatrix<double> M;
     massmatrix(V,F,MASSMATRIX_TYPE_DEFAULT,data.M);
     massmatrix(V,F,MASSMATRIX_TYPE_DEFAULT,data.M);
-    SparseMatrix<double> DQ = 1./(h*h)*data.M;
+    const double dw = (1./data.ym)*(h*h);
+    SparseMatrix<double> DQ = dw * 1./(h*h)*data.M;
     Q += DQ;
     Q += DQ;
     // Dummy external forces
     // Dummy external forces
     data.f_ext = MatrixXd::Zero(n,data.dim);
     data.f_ext = MatrixXd::Zero(n,data.dim);
@@ -268,7 +269,8 @@ IGL_INLINE bool igl::arap_solve(
       // h*data.vel = (V0-Vm1)
       // h*data.vel = (V0-Vm1)
       // -h*data.vel = -V0+Vm1)
       // -h*data.vel = -V0+Vm1)
       // -V0-h*data.vel = -2V0+Vm1
       // -V0-h*data.vel = -2V0+Vm1
-      Dl = 1./(h*h)*data.M*(-U0 - h*data.vel) - data.f_ext;
+      const double dw = (1./data.ym)*(h*h);
+      Dl = dw * (1./(h*h)*data.M*(-U0 - h*data.vel) - data.f_ext);
     }
     }
 
 
     VectorXd Rcol;
     VectorXd Rcol;

+ 3 - 0
include/igl/arap.h

@@ -26,6 +26,7 @@ namespace igl
     // f_ext  #V by dim list of external forces
     // f_ext  #V by dim list of external forces
     // vel  #V by dim list of velocities
     // vel  #V by dim list of velocities
     // h  dynamics time step
     // h  dynamics time step
+    // ym  ~Young's modulus smaller is softer, larger is more rigid/stiff
     // max_iter  maximum inner iterations
     // max_iter  maximum inner iterations
     // K  rhs pre-multiplier
     // K  rhs pre-multiplier
     // M  mass matrix
     // M  mass matrix
@@ -38,6 +39,7 @@ namespace igl
     bool with_dynamics;
     bool with_dynamics;
     Eigen::MatrixXd f_ext,vel;
     Eigen::MatrixXd f_ext,vel;
     double h;
     double h;
+    double ym;
     int max_iter;
     int max_iter;
     Eigen::SparseMatrix<double> K,M;
     Eigen::SparseMatrix<double> K,M;
     Eigen::SparseMatrix<double> CSM;
     Eigen::SparseMatrix<double> CSM;
@@ -51,6 +53,7 @@ namespace igl
         with_dynamics(false),
         with_dynamics(false),
         f_ext(),
         f_ext(),
         h(1),
         h(1),
+        ym(1),
         max_iter(10),
         max_iter(10),
         K(),
         K(),
         CSM(),
         CSM(),

+ 7 - 6
include/igl/average_onto_vertices.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "average_onto_vertices.h"
 #include "average_onto_vertices.h"
 
 
@@ -13,7 +13,7 @@ IGL_INLINE void igl::average_onto_vertices(const Eigen::Matrix<T, Eigen::Dynamic
             const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &S,
             const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &S,
             Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &SV)
             Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &SV)
 {
 {
-  
+
   SV = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>::Zero(V.rows(),S.cols());
   SV = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>::Zero(V.rows(),S.cols());
   Eigen::Matrix<T, Eigen::Dynamic, 1> COUNT = Eigen::Matrix<T, Eigen::Dynamic, 1>::Zero(V.rows());
   Eigen::Matrix<T, Eigen::Dynamic, 1> COUNT = Eigen::Matrix<T, Eigen::Dynamic, 1>::Zero(V.rows());
   for (int i = 0; i <F.rows(); ++i)
   for (int i = 0; i <F.rows(); ++i)
@@ -26,9 +26,10 @@ IGL_INLINE void igl::average_onto_vertices(const Eigen::Matrix<T, Eigen::Dynamic
   }
   }
   for (int i = 0; i <V.rows(); ++i)
   for (int i = 0; i <V.rows(); ++i)
     SV.row(i) /= COUNT[i];
     SV.row(i) /= COUNT[i];
-  
+
 };
 };
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // Explicit template specialization
+template void igl::average_onto_vertices<double, int>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
 #endif
 #endif

+ 1 - 0
include/igl/barycenter.cpp

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

+ 11 - 7
include/igl/barycentric_to_global.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Daniele Panozzo <daniele.panozzo@gmail.com>
 // Copyright (C) 2013 Daniele Panozzo <daniele.panozzo@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/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "barycentric_to_global.h"
 #include "barycentric_to_global.h"
 
 
@@ -15,8 +15,8 @@ namespace igl
 {
 {
   template <typename Scalar, typename Index>
   template <typename Scalar, typename Index>
   IGL_INLINE Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> barycentric_to_global(
   IGL_INLINE Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> barycentric_to_global(
-    const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> & V, 
-    const Eigen::Matrix<Index,Eigen::Dynamic,Eigen::Dynamic>  & F, 
+    const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> & V,
+    const Eigen::Matrix<Index,Eigen::Dynamic,Eigen::Dynamic>  & F,
     const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> & bc)
     const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> & bc)
   {
   {
     Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> R;
     Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> R;
@@ -25,7 +25,7 @@ namespace igl
     for (unsigned i=0; i<R.rows(); ++i)
     for (unsigned i=0; i<R.rows(); ++i)
     {
     {
       unsigned id = round(bc(i,0));
       unsigned id = round(bc(i,0));
-      double u   = bc(i,1);  
+      double u   = bc(i,1);
       double v   = bc(i,2);
       double v   = bc(i,2);
 
 
       if (id != -1)
       if (id != -1)
@@ -38,3 +38,7 @@ namespace igl
     return R;
     return R;
   }
   }
 }
 }
+
+#ifdef IGL_STATIC_LIBRARY
+template Eigen::Matrix<double, -1, -1, 0, -1, -1> igl::barycentric_to_global<double, int>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&);
+#endif

+ 44 - 10
include/igl/biharmonic_coordinates.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
 // 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/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "biharmonic_coordinates.h"
 #include "biharmonic_coordinates.h"
 #include "cotmatrix.h"
 #include "cotmatrix.h"
@@ -23,11 +23,26 @@ IGL_INLINE bool igl::biharmonic_coordinates(
   const Eigen::PlainObjectBase<DerivedT> & T,
   const Eigen::PlainObjectBase<DerivedT> & T,
   const std::vector<std::vector<SType> > & S,
   const std::vector<std::vector<SType> > & S,
   Eigen::PlainObjectBase<DerivedW> & W)
   Eigen::PlainObjectBase<DerivedW> & W)
+{
+  return biharmonic_coordinates(V,T,S,2,W);
+}
+
+template <
+  typename DerivedV,
+  typename DerivedT,
+  typename SType,
+  typename DerivedW>
+IGL_INLINE bool igl::biharmonic_coordinates(
+  const Eigen::PlainObjectBase<DerivedV> & V,
+  const Eigen::PlainObjectBase<DerivedT> & T,
+  const std::vector<std::vector<SType> > & S,
+  const int k,
+  Eigen::PlainObjectBase<DerivedW> & W)
 {
 {
   using namespace Eigen;
   using namespace Eigen;
   using namespace std;
   using namespace std;
   // This is not the most efficient way to build A, but follows "Linear
   // This is not the most efficient way to build A, but follows "Linear
-  // Subspace Design for Real-Time Shape Deformation" [Wang et al. 2015]. 
+  // Subspace Design for Real-Time Shape Deformation" [Wang et al. 2015].
   SparseMatrix<double> A;
   SparseMatrix<double> A;
   {
   {
     SparseMatrix<double> N,Z,L,K,M;
     SparseMatrix<double> N,Z,L,K,M;
@@ -58,12 +73,26 @@ IGL_INLINE bool igl::biharmonic_coordinates(
     cotmatrix(V,T,L);
     cotmatrix(V,T,L);
     K = N+L;
     K = N+L;
     massmatrix(V,T,MASSMATRIX_TYPE_DEFAULT,M);
     massmatrix(V,T,MASSMATRIX_TYPE_DEFAULT,M);
-    DiagonalMatrix<double,Dynamic> Minv = 
+    // normalize
+    M /= ((VectorXd)M.diagonal()).array().abs().maxCoeff();
+    DiagonalMatrix<double,Dynamic> Minv =
       ((VectorXd)M.diagonal().array().inverse()).asDiagonal();
       ((VectorXd)M.diagonal().array().inverse()).asDiagonal();
-    A = K.transpose() * (Minv * K);
+    switch(k)
+    {
+      default:
+        assert(false && "unsupported");
+      case 2:
+        // For C1 smoothness in 2D, one should use bi-harmonic
+        A = K.transpose() * (Minv * K);
+        break;
+      case 3:
+        // For C1 smoothness in 3D, one should use tri-harmonic
+        A = K.transpose() * (Minv * (-L * (Minv * K)));
+        break;
+    }
   }
   }
   // Vertices in point handles
   // Vertices in point handles
-  const size_t mp = 
+  const size_t mp =
     count_if(S.begin(),S.end(),[](const vector<int> & h){return h.size()==1;});
     count_if(S.begin(),S.end(),[](const vector<int> & h){return h.size()==1;});
   // number of region handles
   // number of region handles
   const size_t r = S.size()-mp;
   const size_t r = S.size()-mp;
@@ -110,8 +139,13 @@ IGL_INLINE bool igl::biharmonic_coordinates(
       }
       }
     }
     }
   }
   }
-  // minimize    ½ W' A W' 
+  // minimize    ½ W' A W'
   // subject to  W(b,:) = J
   // subject to  W(b,:) = J
   return min_quad_with_fixed(
   return min_quad_with_fixed(
-    A,VectorXd::Zero(A.rows()).eval(),b,J,{},VectorXd(),true,W);
+    A,VectorXd::Zero(A.rows()).eval(),b,J,SparseMatrix<double>(),VectorXd(),true,W);
 }
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+template bool igl::biharmonic_coordinates<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, 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&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+#endif

+ 13 - 0
include/igl/biharmonic_coordinates.h

@@ -70,6 +70,19 @@ namespace igl
     const Eigen::PlainObjectBase<DerivedT> & T,
     const Eigen::PlainObjectBase<DerivedT> & T,
     const std::vector<std::vector<SType> > & S,
     const std::vector<std::vector<SType> > & S,
     Eigen::PlainObjectBase<DerivedW> & W);
     Eigen::PlainObjectBase<DerivedW> & W);
+  // k  2-->biharmonic, 3-->triharmonic
+  template <
+    typename DerivedV,
+    typename DerivedT,
+    typename SType,
+    typename DerivedW>
+  IGL_INLINE bool biharmonic_coordinates(
+    const Eigen::PlainObjectBase<DerivedV> & V,
+    const Eigen::PlainObjectBase<DerivedT> & T,
+    const std::vector<std::vector<SType> > & S,
+    const int k,
+    Eigen::PlainObjectBase<DerivedW> & W);
+
 };
 };
 #  ifndef IGL_STATIC_LIBRARY
 #  ifndef IGL_STATIC_LIBRARY
 #    include "biharmonic_coordinates.cpp"
 #    include "biharmonic_coordinates.cpp"

+ 56 - 28
include/igl/boolean/mesh_boolean.cpp

@@ -7,13 +7,15 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "mesh_boolean.h"
 #include "mesh_boolean.h"
 #include <igl/per_face_normals.h>
 #include <igl/per_face_normals.h>
+#include <igl/boundary_facets.h>
+#include <igl/exterior_edges.h>
 #include <igl/cgal/peel_outer_hull_layers.h>
 #include <igl/cgal/peel_outer_hull_layers.h>
 #include <igl/cgal/remesh_self_intersections.h>
 #include <igl/cgal/remesh_self_intersections.h>
 #include <igl/remove_unreferenced.h>
 #include <igl/remove_unreferenced.h>
+#include <igl/mod.h>
 #include <igl/unique_simplices.h>
 #include <igl/unique_simplices.h>
-#include <iostream>
-
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <iostream>
 
 
 //#define IGL_MESH_BOOLEAN_DEBUG
 //#define IGL_MESH_BOOLEAN_DEBUG
 
 
@@ -152,7 +154,7 @@ IGL_INLINE void igl::boolean::mesh_boolean(
     MatrixX3I SF;
     MatrixX3I SF;
     MatrixX2I SIF;
     MatrixX2I SIF;
     VectorXI SIM,UIM;
     VectorXI SIM,UIM;
-    RemeshSelfIntersectionsParam params;
+    igl::cgal::RemeshSelfIntersectionsParam params;
     remesh_self_intersections(V,F,params,SV,SF,SIF,J,SIM);
     remesh_self_intersections(V,F,params,SV,SF,SIF,J,SIM);
     for_each(SF.data(),SF.data()+SF.size(),[&SIM](int & a){a=SIM(a);});
     for_each(SF.data(),SF.data()+SF.size(),[&SIM](int & a){a=SIM(a);});
     {
     {
@@ -187,22 +189,17 @@ IGL_INLINE void igl::boolean::mesh_boolean(
     J = CJ;
     J = CJ;
     return;
     return;
   }
   }
-  MatrixX3S N,CN;
-  per_face_normals_stable(V,F,N);
-  CN.resize(CF.rows(),3);
-  for(size_t f = 0;f<(size_t)CN.rows();f++)
-  {
-    CN.row(f) = N.row(CJ(f));
-  }
 
 
 #ifdef IGL_MESH_BOOLEAN_DEBUG
 #ifdef IGL_MESH_BOOLEAN_DEBUG
   cout<<"peel..."<<endl;
   cout<<"peel..."<<endl;
 #endif
 #endif
   Matrix<bool,Dynamic,1> from_A(CF.rows());
   Matrix<bool,Dynamic,1> from_A(CF.rows());
   // peel layers keeping track of odd and even flips
   // peel layers keeping track of odd and even flips
-  Matrix<bool,Dynamic,1> odd;
+  VectorXi I;
   Matrix<bool,Dynamic,1> flip;
   Matrix<bool,Dynamic,1> flip;
-  peel_outer_hull_layers(EV,CF,CN,odd,flip);
+  peel_outer_hull_layers(EV,CF,I,flip);
+  // 0 is "first" iteration, so it's odd
+  Array<bool,Dynamic,1> odd = igl::mod(I,2).array()==0;
 
 
 #ifdef IGL_MESH_BOOLEAN_DEBUG
 #ifdef IGL_MESH_BOOLEAN_DEBUG
   cout<<"categorize..."<<endl;
   cout<<"categorize..."<<endl;
@@ -249,6 +246,14 @@ IGL_INLINE void igl::boolean::mesh_boolean(
     G.row(g) = Gflip[g] ? CF.row(vG[g]).reverse().eval() : CF.row(vG[g]);
     G.row(g) = Gflip[g] ? CF.row(vG[g]).reverse().eval() : CF.row(vG[g]);
     GJ(g) = CJ(vG[g]);
     GJ(g) = CJ(vG[g]);
   }
   }
+#ifdef IGL_MESH_BOOLEAN_DEBUG
+  {
+    MatrixXd O;
+    boundary_facets(FC,O);
+    cout<<"# boundary: "<<O.rows()<<endl;
+  }
+  cout<<"# exterior: "<<exterior_edges(FC).rows()<<endl;
+#endif
 #ifdef IGL_MESH_BOOLEAN_DEBUG
 #ifdef IGL_MESH_BOOLEAN_DEBUG
   cout<<"clean..."<<endl;
   cout<<"clean..."<<endl;
 #endif
 #endif
@@ -262,6 +267,7 @@ IGL_INLINE void igl::boolean::mesh_boolean(
     vector<vector<Index> > uG2G(uG.rows());
     vector<vector<Index> > uG2G(uG.rows());
     // signed counts
     // signed counts
     VectorXi counts = VectorXi::Zero(uG.rows());
     VectorXi counts = VectorXi::Zero(uG.rows());
+    VectorXi ucounts = VectorXi::Zero(uG.rows());
     // loop over all faces
     // loop over all faces
     for(Index g = 0;g<gm;g++)
     for(Index g = 0;g<gm;g++)
     {
     {
@@ -274,6 +280,7 @@ IGL_INLINE void igl::boolean::mesh_boolean(
         (G(g,0) == uG(ug,1) && G(g,1) == uG(ug,2) && G(g,2) == uG(ug,0)) ||
         (G(g,0) == uG(ug,1) && G(g,1) == uG(ug,2) && G(g,2) == uG(ug,0)) ||
         (G(g,0) == uG(ug,2) && G(g,1) == uG(ug,0) && G(g,2) == uG(ug,1));
         (G(g,0) == uG(ug,2) && G(g,1) == uG(ug,0) && G(g,2) == uG(ug,1));
       counts(ug) += consistent ? 1 : -1;
       counts(ug) += consistent ? 1 : -1;
+      ucounts(ug)++;
     }
     }
     MatrixX3I oldG = G;
     MatrixX3I oldG = G;
     // Faces of output vG[i] = j means ith face of output should be jth face in
     // Faces of output vG[i] = j means ith face of output should be jth face in
@@ -283,17 +290,33 @@ IGL_INLINE void igl::boolean::mesh_boolean(
     {
     {
       // if signed occurrences is zero or ±two then keep none
       // if signed occurrences is zero or ±two then keep none
       // else if signed occurrences is ±one then keep just one facet
       // else if signed occurrences is ±one then keep just one facet
-      if(abs(counts(ug)) == 1)
+      switch(abs(counts(ug)))
       {
       {
-        assert(uG2G.size() > 0);
-        vG.push_back(uG2G[ug][0]);
-      }
+        case 1:
+          assert(uG2G[ug].size() > 0);
+          vG.push_back(uG2G[ug][0]);
 #ifdef IGL_MESH_BOOLEAN_DEBUG
 #ifdef IGL_MESH_BOOLEAN_DEBUG
-      else
-      {
-        cout<<"Skipping "<<uG2G.size()<<" facets..."<<endl;
-      }
+          if(abs(ucounts(ug)) != 1)
+          {
+            cout<<"count,ucount of "<<counts(ug)<<","<<ucounts(ug)<<endl;
+          }
+#endif
+          break;
+        case 0:
+#ifdef IGL_MESH_BOOLEAN_DEBUG
+          cout<<"Skipping "<<uG2G[ug].size()<<" facets..."<<endl;
+          if(abs(ucounts(ug)) != 0)
+          {
+            cout<<"count,ucount of "<<counts(ug)<<","<<ucounts(ug)<<endl;
+          }
+#endif
+          break;
+        default:
+#ifdef IGL_MESH_BOOLEAN_DEBUG
+          cout<<"Didn't expect to be here."<<endl;
 #endif
 #endif
+          assert(false && "Shouldn't count be -1/0/1 ?");
+      }
     }
     }
     G.resize(vG.size(),3);
     G.resize(vG.size(),3);
     J.resize(vG.size());
     J.resize(vG.size());
@@ -309,21 +332,26 @@ IGL_INLINE void igl::boolean::mesh_boolean(
   //cerr<<"warning not removing unref"<<endl;
   //cerr<<"warning not removing unref"<<endl;
   //VC = CV;
   //VC = CV;
   //FC = G;
   //FC = G;
+#ifdef IGL_MESH_BOOLEAN_DEBUG
+  {
+    MatrixXd O;
+    boundary_facets(FC,O);
+    cout<<"# boundary: "<<O.rows()<<endl;
+  }
+  cout<<"# exterior: "<<exterior_edges(FC).rows()<<endl;
+#endif
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-
-// This is a hack to discuss
+// This is a hack to discuss. I'm not sure why this _doesn't_ create
+// duplicate symbols.
 #include <igl/remove_unreferenced.cpp>
 #include <igl/remove_unreferenced.cpp>
-
 template void igl::remove_unreferenced<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::remove_unreferenced<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-
 #include <igl/cgal/peel_outer_hull_layers.cpp>
 #include <igl/cgal/peel_outer_hull_layers.cpp>
-template unsigned long igl::cgal::peel_outer_hull_layers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
-
+template unsigned long
+igl::cgal::peel_outer_hull_layers<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
 #include <igl/cgal/outer_hull.cpp>
 #include <igl/cgal/outer_hull.cpp>
-template void igl::cgal::outer_hull<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
-
+template void igl::cgal::outer_hull<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
 // Explicit template specialization
 // Explicit template specialization
 template void igl::boolean::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::boolean::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::boolean::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::boolean::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::boolean::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::boolean::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::boolean::mesh_boolean<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::boolean::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);

+ 1 - 1
include/igl/bounding_box_diagonal.cpp

@@ -22,5 +22,5 @@ IGL_INLINE double igl::bounding_box_diagonal(
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-// Explicit template instanciation
+// Explicit template specialization
 #endif
 #endif

+ 3 - 1
include/igl/cat.cpp

@@ -36,7 +36,9 @@ IGL_INLINE void igl::cat(
     return;
     return;
   }
   }
 
 
-  SparseMatrix<Scalar, RowMajor> dyn_C;
+  // This **must** be DynamicSparseMatrix, otherwise this implementation is
+  // insanely slow
+  DynamicSparseMatrix<Scalar, RowMajor> dyn_C;
   if(dim == 1)
   if(dim == 1)
   {
   {
     assert(A.cols() == B.cols());
     assert(A.cols() == B.cols());

+ 2 - 0
include/igl/cgal/RemeshSelfIntersectionsParam.h

@@ -19,6 +19,8 @@ namespace igl
       bool detect_only;
       bool detect_only;
       bool first_only;
       bool first_only;
       RemeshSelfIntersectionsParam():detect_only(false),first_only(false){};
       RemeshSelfIntersectionsParam():detect_only(false),first_only(false){};
+      RemeshSelfIntersectionsParam(bool _detect_only, bool _first_only):
+        detect_only(_detect_only),first_only(_first_only){};
     };
     };
   }
   }
 }
 }

+ 166 - 499
include/igl/cgal/SelfIntersectMesh.h

@@ -89,13 +89,13 @@ namespace igl
         typedef typename DerivedF::Index Index;
         typedef typename DerivedF::Index Index;
         Index count;
         Index count;
         typedef std::vector<CGAL::Object> ObjectList;
         typedef std::vector<CGAL::Object> ObjectList;
-        std::vector<ObjectList > F_objects;
+        // Using a vector here makes this **not** output sensitive
         Triangles T;
         Triangles T;
         typedef std::vector<Index> IndexList;
         typedef std::vector<Index> IndexList;
         IndexList lIF;
         IndexList lIF;
-        std::vector<bool> offensive;
-        std::vector<Index> offending_index;
-        std::vector<Index> offending;
+        // #F-long list of faces with intersections mapping to the order in
+        // which they were first found
+        std::map<Index,std::pair<Index,ObjectList> > offending;
         // Make a short name for the edge map's key
         // Make a short name for the edge map's key
         typedef std::pair<Index,Index> EMK;
         typedef std::pair<Index,Index> EMK;
         // Make a short name for the type stored at each edge, the edge map's
         // Make a short name for the type stored at each edge, the edge map's
@@ -103,6 +103,7 @@ namespace igl
         typedef std::vector<Index> EMV;
         typedef std::vector<Index> EMV;
         // Make a short name for the edge map
         // Make a short name for the edge map
         typedef std::map<EMK,EMV> EdgeMap;
         typedef std::map<EMK,EMV> EdgeMap;
+        // Maps edges of offending faces to all incident offending faces
         EdgeMap edge2faces;
         EdgeMap edge2faces;
       public:
       public:
         RemeshSelfIntersectionsParam params;
         RemeshSelfIntersectionsParam params;
@@ -139,8 +140,8 @@ namespace igl
         // Inputs:
         // Inputs:
         //   A  triangle in 3D
         //   A  triangle in 3D
         //   B  triangle in 3D
         //   B  triangle in 3D
-        //   fa  index of A in F (and F_objects)
-        //   fb  index of A in F (and F_objects)
+        //   fa  index of A in F (and key into offending)
+        //   fb  index of A in F (and key into offending)
         // Returns true only if A intersects B
         // Returns true only if A intersects B
         //
         //
         inline bool intersect(
         inline bool intersect(
@@ -156,10 +157,10 @@ namespace igl
         // Inputs:
         // Inputs:
         //   A  triangle in 3D
         //   A  triangle in 3D
         //   B  triangle in 3D
         //   B  triangle in 3D
-        //   fa  index of A in F (and F_objects)
-        //   fb  index of B in F (and F_objects)
-        //   va  index of shared vertex in A (and F_objects)
-        //   vb  index of shared vertex in B (and F_objects)
+        //   fa  index of A in F (and key into offending)
+        //   fb  index of B in F (and key into offending)
+        //   va  index of shared vertex in A (and key into offending)
+        //   vb  index of shared vertex in B (and key into offending)
         //// Returns object of intersection (should be Segment or point)
         //// Returns object of intersection (should be Segment or point)
         //   Returns true if intersection (besides shared point)
         //   Returns true if intersection (besides shared point)
         //
         //
@@ -185,7 +186,8 @@ namespace igl
             const Triangle_3 & A,
             const Triangle_3 & A,
             const Triangle_3 & B,
             const Triangle_3 & B,
             const Index fa,
             const Index fa,
-            const Index fb);
+            const Index fb,
+            const std::vector<std::pair<Index,Index> > shared);
   
   
       public:
       public:
         // Callback function called during box self intersections test. Means
         // Callback function called during box self intersections test. Means
@@ -208,22 +210,13 @@ namespace igl
         //   A_objects_3  updated list of intersection objects for A
         //   A_objects_3  updated list of intersection objects for A
         // Outputs:
         // Outputs:
         //   cdt  Contrained delaunay triangulation in projected 2D plane
         //   cdt  Contrained delaunay triangulation in projected 2D plane
-        inline void projected_delaunay(
-            const Triangle_3 & A,
-            const ObjectList & A_objects_3,
-            CDT_plus_2 & cdt);
-        // Getters:
       public:
       public:
+        // Getters:
         //const IndexList& get_lIF() const{ return lIF;}
         //const IndexList& get_lIF() const{ return lIF;}
         static inline void box_intersect_static(
         static inline void box_intersect_static(
           SelfIntersectMesh * SIM, 
           SelfIntersectMesh * SIM, 
           const Box &a, 
           const Box &a, 
           const Box &b);
           const Box &b);
-        // Annoying wrappers to conver from cgal to double or cgal
-        static inline void to_output_type(const typename Kernel::FT & cgal,double & d);
-        static inline void to_output_type(
-          const typename CGAL::Epeck::FT & cgal,
-          CGAL::Epeck::FT & d);
     };
     };
   }
   }
 }
 }
@@ -231,6 +224,7 @@ namespace igl
 // Implementation
 // Implementation
 
 
 #include "mesh_to_cgal_triangle_list.h"
 #include "mesh_to_cgal_triangle_list.h"
+#include "remesh_intersections.h"
 
 
 #include <igl/REDRUM.h>
 #include <igl/REDRUM.h>
 #include <igl/get_seconds.h>
 #include <igl/get_seconds.h>
@@ -322,11 +316,8 @@ inline igl::cgal::SelfIntersectMesh<
   V(V),
   V(V),
   F(F),
   F(F),
   count(0),
   count(0),
-  F_objects(F.rows()),
   T(),
   T(),
   lIF(),
   lIF(),
-  offensive(F.rows(),false),
-  offending_index(F.rows(),-1),
   offending(),
   offending(),
   edge2faces(),
   edge2faces(),
   params(params)
   params(params)
@@ -413,241 +404,7 @@ inline igl::cgal::SelfIntersectMesh<
     return;
     return;
   }
   }
 
 
-  int NF_count = 0;
-  // list of new faces, we'll fix F later
-  vector<
-    typename Eigen::Matrix<typename DerivedFF::Scalar,Dynamic,Dynamic>
-    > NF(offending.size());
-  // list of new vertices
-  typedef vector<Point_3> Point_3List;
-  Point_3List NV;
-  Index NV_count = 0;
-  vector<CDT_plus_2> cdt(offending.size());
-  vector<Plane_3> P(offending.size());
-  // Use map for *all* faces
-  map<typename CDT_plus_2::Vertex_handle,Index> v2i;
-  // Loop over offending triangles
-  const size_t noff = offending.size();
-#ifdef IGL_SELFINTERSECTMESH_DEBUG
-  double t_proj_del = 0;
-#endif
-  // Unfortunately it looks like CGAL has trouble allocating memory when
-  // multiple openmp threads are running. Crashes durring CDT...
-//# pragma omp parallel for if (noff>1000)
-  for(Index o = 0;o<(Index)noff;o++)
-  {
-    // index in F
-    const Index f = offending[o];
-    {
-#ifdef IGL_SELFINTERSECTMESH_DEBUG
-      const double t_before = get_seconds();
-#endif
-      projected_delaunay(T[f],F_objects[f],cdt[o]);
-#ifdef IGL_SELFINTERSECTMESH_DEBUG
-      t_proj_del += (get_seconds()-t_before);
-#endif
-    }
-    // Q: Is this also delaunay in 3D?
-    // A: No, because the projection is affine and delaunay is not affine
-    // invariant.
-    // Q: Then, can't we first get the 2D delaunay triangulation, then lift it
-    // to 3D and flip any offending edges?
-    // Plane of projection (also used by projected_delaunay)
-    P[o] = Plane_3(T[f].vertex(0),T[f].vertex(1),T[f].vertex(2));
-    // Build index map
-    {
-      Index i=0;
-      for(
-        typename CDT_plus_2::Finite_vertices_iterator vit = cdt[o].finite_vertices_begin();
-        vit != cdt[o].finite_vertices_end();
-        ++vit)
-      {
-        if(i<3)
-        {
-          //cout<<T[f].vertex(i)<<
-          //  (T[f].vertex(i) == P[o].to_3d(vit->point())?" == ":" != ")<<
-          //  P[o].to_3d(vit->point())<<endl;
-#ifndef NDEBUG
-          // I want to be sure that the original corners really show up as the
-          // original corners of the CDT. I.e. I don't trust CGAL to maintain
-          // the order
-          assert(T[f].vertex(i) == P[o].to_3d(vit->point()));
-#endif
-          // For first three, use original index in F
-//#   pragma omp critical
-          v2i[vit] = F(f,i);
-        }else
-        {
-          const Point_3 vit_point_3 = P[o].to_3d(vit->point());
-          // First look up each edge's neighbors to see if exact point has
-          // already been added (This makes everything a bit quadratic)
-          bool found = false;
-          for(int e = 0; e<3 && !found;e++)
-          {
-            // Index of F's eth edge in V
-            Index i = F(f,(e+1)%3);
-            Index j = F(f,(e+2)%3);
-            // Be sure that i<j
-            if(i>j)
-            {
-              swap(i,j);
-            }
-            assert(edge2faces.count(EMK(i,j))==1);
-            // loop over neighbors
-            for(
-              typename IndexList::const_iterator nit = edge2faces[EMK(i,j)].begin();
-              nit != edge2faces[EMK(i,j)].end() && !found;
-              nit++)
-            {
-              // don't consider self
-              if(*nit == f)
-              {
-                continue;
-              }
-              // index of neighbor in offending (to find its cdt)
-              Index no = offending_index[*nit];
-              // Loop over vertices of that neighbor's cdt (might not have been
-              // processed yet, but then it's OK because it'll just be empty)
-              for(
-                  typename CDT_plus_2::Finite_vertices_iterator uit = cdt[no].finite_vertices_begin();
-                  uit != cdt[no].finite_vertices_end() && !found;
-                  ++uit)
-              {
-                if(vit_point_3 == P[no].to_3d(uit->point()))
-                {
-                  assert(v2i.count(uit) == 1);
-//#   pragma omp critical
-                  v2i[vit] = v2i[uit];
-                  found = true;
-                }
-              }
-            }
-          }
-          if(!found)
-          {
-//#   pragma omp critical
-            {
-              v2i[vit] = V.rows()+NV_count;
-              NV.push_back(vit_point_3);
-              NV_count++;
-            }
-          }
-        }
-        i++;
-      }
-    }
-    {
-      Index i = 0;
-      // Resize to fit new number of triangles
-      NF[o].resize(cdt[o].number_of_faces(),3);
-//#   pragma omp atomic
-      NF_count+=NF[o].rows();
-      // Append new faces to NF
-      for(
-        typename CDT_plus_2::Finite_faces_iterator fit = cdt[o].finite_faces_begin();
-        fit != cdt[o].finite_faces_end();
-        ++fit)
-      {
-        NF[o](i,0) = v2i[fit->vertex(0)];
-        NF[o](i,1) = v2i[fit->vertex(1)];
-        NF[o](i,2) = v2i[fit->vertex(2)];
-        i++;
-      }
-    }
-  }
-#ifdef IGL_SELFINTERSECTMESH_DEBUG
-  cout<<"CDT: "<<tictoc()<<"  "<<t_proj_del<<endl;
-#endif
-
-  assert(NV_count == (Index)NV.size());
-  // Build output
-#ifndef NDEBUG
-  {
-    Index off_count = 0;
-    for(Index f = 0;f<F.rows();f++)
-    {
-      off_count+= (offensive[f]?1:0);
-    }
-    assert(off_count==(Index)offending.size());
-  }
-#endif
-  // Append faces
-  FF.resize(F.rows()-offending.size()+NF_count,3);
-  J.resize(FF.rows());
-  // First append non-offending original faces
-  // There's an Eigen way to do this in one line but I forget
-  Index off = 0;
-  for(Index f = 0;f<F.rows();f++)
-  {
-    if(!offensive[f])
-    {
-      FF.row(off) = F.row(f);
-      J(off) = f;
-      off++;
-    }
-  }
-  assert(off == (Index)(F.rows()-offending.size()));
-  // Now append replacement faces for offending faces
-  for(Index o = 0;o<(Index)offending.size();o++)
-  {
-    FF.block(off,0,NF[o].rows(),3) = NF[o];
-    J.block(off,0,NF[o].rows(),1).setConstant(offending[o]);
-    off += NF[o].rows();
-  }
-  // Append vertices
-  VV.resize(V.rows()+NV_count,3);
-  VV.block(0,0,V.rows(),3) = V.template cast<typename DerivedVV::Scalar>();
-  {
-    Index i = 0;
-    for(
-      typename Point_3List::const_iterator nvit = NV.begin();
-      nvit != NV.end();
-      nvit++)
-    {
-      for(Index d = 0;d<3;d++)
-      {
-        const Point_3 & p = *nvit;
-        // Don't convert via double if output type is same as Kernel
-        to_output_type(p[d], VV(V.rows()+i,d));
-      }
-      i++;
-    }
-  }
-  IM.resize(VV.rows(),1);
-  map<Point_3,Index> vv2i;
-  // Safe to check for duplicates using double for original vertices: if
-  // incoming reps are different then the points are unique.
-  for(Index v = 0;v<V.rows();v++)
-  {
-    const Point_3 p(V(v,0),V(v,1),V(v,2));
-    if(vv2i.count(p)==0)
-    {
-      vv2i[p] = v;
-    }
-    assert(vv2i.count(p) == 1);
-    IM(v) = vv2i[p];
-  }
-  // Must check for duplicates of new vertices using exact.
-  {
-    Index v = V.rows();
-    for(
-      typename Point_3List::const_iterator nvit = NV.begin();
-      nvit != NV.end();
-      nvit++)
-    {
-      const Point_3 & p = *nvit;
-      if(vv2i.count(p)==0)
-      {
-        vv2i[p] = v;
-      }
-      assert(vv2i.count(p) == 1);
-      IM(v) = vv2i[p];
-      v++;
-    }
-  }
-#ifdef IGL_SELFINTERSECTMESH_DEBUG
-  cout<<"Output + dupes: "<<tictoc()<<endl;
-#endif
+  remesh_intersections(V,F,T,offending,edge2faces,VV,FF,J,IM);
 
 
   // Q: Does this give the same result as TETGEN?
   // Q: Does this give the same result as TETGEN?
   // A: For the cow and beast, yes.
   // A: For the cow and beast, yes.
@@ -659,6 +416,7 @@ inline igl::cgal::SelfIntersectMesh<
   // CGAL implementation on the beast takes 98 seconds but tetgen detection
   // CGAL implementation on the beast takes 98 seconds but tetgen detection
   // takes 14 seconds
   // takes 14 seconds
 
 
+
 }
 }
 
 
 
 
@@ -683,28 +441,16 @@ inline void igl::cgal::SelfIntersectMesh<
 {
 {
   using namespace std;
   using namespace std;
   lIF.push_back(f);
   lIF.push_back(f);
-  if(!offensive[f])
+  if(offending.count(f) == 0)
   {
   {
-    offensive[f]=true;
-    offending_index[f]=offending.size();
-    offending.push_back(f);
-    // Add to edge map
+    // first time marking, initialize with new id and empty list
+    const Index id = offending.size();
+    offending[f] = {id,{}};
     for(Index e = 0; e<3;e++)
     for(Index e = 0; e<3;e++)
     {
     {
-      // Index of F's eth edge in V
-      Index i = F(f,(e+1)%3);
-      Index j = F(f,(e+2)%3);
-      // Be sure that i<j
-      if(i>j)
-      {
-        swap(i,j);
-      }
-      // Create new list if there is no entry
-      if(edge2faces.count(EMK(i,j))==0)
-      {
-        edge2faces[EMK(i,j)] = EMV();
-      }
-      // append to list
+      // append face to edge's list
+      Index i = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+1)%3) : F(f,(e+2)%3);
+      Index j = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+2)%3) : F(f,(e+1)%3);
       edge2faces[EMK(i,j)].push_back(f);
       edge2faces[EMK(i,j)].push_back(f);
     }
     }
   }
   }
@@ -769,14 +515,14 @@ inline bool igl::cgal::SelfIntersectMesh<
   {
   {
     return false;
     return false;
   }
   }
+  count_intersection(fa,fb);
   if(!params.detect_only)
   if(!params.detect_only)
   {
   {
     // Construct intersection
     // Construct intersection
     CGAL::Object result = CGAL::intersection(A,B);
     CGAL::Object result = CGAL::intersection(A,B);
-    F_objects[fa].push_back(result);
-    F_objects[fb].push_back(result);
+    offending[fa].second.push_back(result);
+    offending[fb].second.push_back(result);
   }
   }
-  count_intersection(fa,fb);
   return true;
   return true;
 }
 }
 
 
@@ -858,43 +604,41 @@ inline bool igl::cgal::SelfIntersectMesh<
 
 
   if(CGAL::do_intersect(sa,B))
   if(CGAL::do_intersect(sa,B))
   {
   {
+    // can't put count_intersection(fa,fb) here since we use intersect below
+    // and then it will be counted twice.
+    if(params.detect_only)
+    {
+      count_intersection(fa,fb);
+      return true;
+    }
     CGAL::Object result = CGAL::intersection(sa,B);
     CGAL::Object result = CGAL::intersection(sa,B);
     if(const Point_3 * p = CGAL::object_cast<Point_3 >(&result))
     if(const Point_3 * p = CGAL::object_cast<Point_3 >(&result))
     {
     {
-      if(!params.detect_only)
-      {
-        // Single intersection --> segment from shared point to intersection
-        CGAL::Object seg = CGAL::make_object(Segment_3(
-          A.vertex(va),
-          *p));
-        F_objects[fa].push_back(seg);
-        F_objects[fb].push_back(seg);
-      }
+      // Single intersection --> segment from shared point to intersection
+      CGAL::Object seg = CGAL::make_object(Segment_3(
+        A.vertex(va),
+        *p));
       count_intersection(fa,fb);
       count_intersection(fa,fb);
+      offending[fa].second.push_back(seg);
+      offending[fb].second.push_back(seg);
       return true;
       return true;
     }else if(CGAL::object_cast<Segment_3 >(&result))
     }else if(CGAL::object_cast<Segment_3 >(&result))
     {
     {
       //cerr<<REDRUM("Coplanar at: "<<fa<<" & "<<fb<<" (single shared).")<<endl;
       //cerr<<REDRUM("Coplanar at: "<<fa<<" & "<<fb<<" (single shared).")<<endl;
       // Must be coplanar
       // Must be coplanar
-      if(params.detect_only)
-      {
-        count_intersection(fa,fb);
-      }else
-      {
-        // WRONG:
-        //// Segment intersection --> triangle from shared point to intersection
-        //CGAL::Object tri = CGAL::make_object(Triangle_3(
-        //  A.vertex(va),
-        //  s->vertex(0),
-        //  s->vertex(1)));
-        //F_objects[fa].push_back(tri);
-        //F_objects[fb].push_back(tri);
-        //count_intersection(fa,fb);
-        // Need to do full test. Intersection could be a general poly.
-        bool test = intersect(A,B,fa,fb);
-        ((void)test);
-        assert(test);
-      }
+      // WRONG:
+      //// Segment intersection --> triangle from shared point to intersection
+      //CGAL::Object tri = CGAL::make_object(Triangle_3(
+      //  A.vertex(va),
+      //  s->vertex(0),
+      //  s->vertex(1)));
+      //F_objects[fa].push_back(tri);
+      //F_objects[fb].push_back(tri);
+      //count_intersection(fa,fb);
+      // Need to do full test. Intersection could be a general poly.
+      bool test = intersect(A,B,fa,fb);
+      ((void)test);
+      assert(test && "intersect should agree with do_intersect");
       return true;
       return true;
     }else
     }else
     {
     {
@@ -928,60 +672,122 @@ inline bool igl::cgal::SelfIntersectMesh<
   const Triangle_3 & A,
   const Triangle_3 & A,
   const Triangle_3 & B,
   const Triangle_3 & B,
   const Index fa,
   const Index fa,
-  const Index fb)
+  const Index fb,
+  const std::vector<std::pair<Index,Index> > shared)
 {
 {
   using namespace std;
   using namespace std;
-  // Cheaper way to do this than calling do_intersect?
+
+  // must be co-planar
   if(
   if(
-    // Can only have an intersection if co-planar
-    (A.supporting_plane() == B.supporting_plane() ||
-    A.supporting_plane() == B.supporting_plane().opposite()) &&
-    CGAL::do_intersect(A,B))
+    A.supporting_plane() != B.supporting_plane() &&
+    A.supporting_plane() != B.supporting_plane().opposite())
   {
   {
-    // Construct intersection
-    try
+    return false;
+  }
+  // Since A and B are non-degenerate the intersection must be a polygon
+  // (triangle). Either
+  //   - the vertex of A (B) opposite the shared edge of lies on B (A), or
+  //   - an edge of A intersects and edge of B without sharing a vertex
+
+
+
+  // Determine if the vertex opposite edge (a0,a1) in triangle A lies in
+  // (intersects) triangle B
+  const auto & opposite_point_inside = [](
+    const Triangle_3 & A, const Index a0, const Index a1, const Triangle_3 & B) 
+    -> bool
+  {
+    // get opposite index
+    Index a2 = -1;
+    for(int c = 0;c<3;c++)
     {
     {
-      // This can fail for Epick but not Epeck
-      CGAL::Object result = CGAL::intersection(A,B);
-      if(!result.empty())
+      if(c != a0 && c != a1)
       {
       {
-        if(CGAL::object_cast<Segment_3 >(&result))
-        {
-          // not coplanar
-          return false;
-        } else if(CGAL::object_cast<Point_3 >(&result))
-        {
-          // this "shouldn't" happen but does for inexact
-          return false;
-        } else
-        {
-          if(!params.detect_only)
-          {
-            // Triangle object
-            F_objects[fa].push_back(result);
-            F_objects[fb].push_back(result);
-          }
-          count_intersection(fa,fb);
-          //cerr<<REDRUM("Coplanar at: "<<fa<<" & "<<fb<<" (double shared).")<<endl;
-          return true;
-        }
-      }else
+        a2 = c;
+        break;
+      }
+    }
+    assert(a2 != -1);
+    bool ret = CGAL::do_intersect(A.vertex(a2),B);
+    //cout<<"opposite_point_inside: "<<ret<<endl;
+    return ret;
+  };
+
+  // Determine if edge opposite vertex va in triangle A intersects edge
+  // opposite vertex vb in triangle B.
+  const auto & opposite_edges_intersect = [](
+    const Triangle_3 & A, const Index va,
+    const Triangle_3 & B, const Index vb) -> bool
+  {
+    Segment_3 sa( A.vertex((va+1)%3), A.vertex((va+2)%3));
+    Segment_3 sb( B.vertex((vb+1)%3), B.vertex((vb+2)%3));
+    //cout<<sa<<endl;
+    //cout<<sb<<endl;
+    bool ret = CGAL::do_intersect(sa,sb);
+    //cout<<"opposite_edges_intersect: "<<ret<<endl;
+    return ret;
+  };
+
+
+  if( 
+    !opposite_point_inside(A,shared[0].first,shared[1].first,B) &&
+    !opposite_point_inside(B,shared[0].second,shared[1].second,A) &&
+    !opposite_edges_intersect(A,shared[0].first,B,shared[1].second) && 
+    !opposite_edges_intersect(A,shared[1].first,B,shared[0].second))
+  {
+    return false;
+  }
+
+  // there is an intersection indeed
+  count_intersection(fa,fb);
+  if(params.detect_only)
+  {
+    return true;
+  }
+  // Construct intersection
+  try
+  {
+    // This can fail for Epick but not Epeck
+    CGAL::Object result = CGAL::intersection(A,B);
+    if(!result.empty())
+    {
+      if(CGAL::object_cast<Segment_3 >(&result))
+      {
+        // not coplanar
+        assert(false && 
+          "Co-planar non-degenerate triangles should intersect over triangle");
+        return false;
+      } else if(CGAL::object_cast<Point_3 >(&result))
       {
       {
-        // CGAL::intersection is disagreeing with do_intersect
+        // this "shouldn't" happen but does for inexact
+        assert(false && 
+          "Co-planar non-degenerate triangles should intersect over triangle");
         return false;
         return false;
+      } else
+      {
+        // Triangle object
+        offending[fa].second.push_back(result);
+        offending[fb].second.push_back(result);
+        //cerr<<REDRUM("Coplanar at: "<<fa<<" & "<<fb<<" (double shared).")<<endl;
+        return true;
       }
       }
-    }catch(...)
+    }else
     {
     {
-      // This catches some cgal assertion:
-      //     CGAL error: assertion violation!
-      //     Expression : is_finite(d)
-      //     File       : /opt/local/include/CGAL/GMP/Gmpq_type.h
-      //     Line       : 132
-      //     Explanation: 
-      // But only if NDEBUG is not defined, otherwise there's an uncaught
-      // "Floating point exception: 8" SIGFPE
+      // CGAL::intersection is disagreeing with do_intersect
+      assert(false && "CGAL::intersection should agree with predicate tests");
       return false;
       return false;
     }
     }
+  }catch(...)
+  {
+    // This catches some cgal assertion:
+    //     CGAL error: assertion violation!
+    //     Expression : is_finite(d)
+    //     File       : /opt/local/include/CGAL/GMP/Gmpq_type.h
+    //     Line       : 132
+    //     Explanation: 
+    // But only if NDEBUG is not defined, otherwise there's an uncaught
+    // "Floating point exception: 8" SIGFPE
+    return false;
   }
   }
   // No intersection.
   // No intersection.
   return false;
   return false;
@@ -1030,9 +836,8 @@ inline void igl::cgal::SelfIntersectMesh<
   // Number of geometrically shared vertices (*not* including combinatorially
   // Number of geometrically shared vertices (*not* including combinatorially
   // shared)
   // shared)
   Index geo_shared_vertices = 0;
   Index geo_shared_vertices = 0;
-  // Keep track of shared vertex indices (we only handles single shared
-  // vertices as a special case, so just need last/first/only ones)
-  Index va=-1,vb=-1;
+  // Keep track of shared vertex indices
+  std::vector<std::pair<Index,Index> > shared;
   Index ea,eb;
   Index ea,eb;
   for(ea=0;ea<3;ea++)
   for(ea=0;ea<3;ea++)
   {
   {
@@ -1041,25 +846,25 @@ inline void igl::cgal::SelfIntersectMesh<
       if(F(fa,ea) == F(fb,eb))
       if(F(fa,ea) == F(fb,eb))
       {
       {
         comb_shared_vertices++;
         comb_shared_vertices++;
-        va = ea;
-        vb = eb;
+        shared.emplace_back(ea,eb);
       }else if(A.vertex(ea) == B.vertex(eb))
       }else if(A.vertex(ea) == B.vertex(eb))
       {
       {
         geo_shared_vertices++;
         geo_shared_vertices++;
-        va = ea;
-        vb = eb;
+        shared.emplace_back(ea,eb);
       }
       }
     }
     }
   }
   }
   const Index total_shared_vertices = comb_shared_vertices + geo_shared_vertices;
   const Index total_shared_vertices = comb_shared_vertices + geo_shared_vertices;
   if(comb_shared_vertices== 3)
   if(comb_shared_vertices== 3)
   {
   {
+    assert(shared.size() == 3);
     //// Combinatorially duplicate face, these should be removed by preprocessing
     //// Combinatorially duplicate face, these should be removed by preprocessing
     //cerr<<REDRUM("Facets "<<fa<<" and "<<fb<<" are combinatorial duplicates")<<endl;
     //cerr<<REDRUM("Facets "<<fa<<" and "<<fb<<" are combinatorial duplicates")<<endl;
     goto done;
     goto done;
   }
   }
   if(total_shared_vertices== 3)
   if(total_shared_vertices== 3)
   {
   {
+    assert(shared.size() == 3);
     //// Geometrically duplicate face, these should be removed by preprocessing
     //// Geometrically duplicate face, these should be removed by preprocessing
     //cerr<<REDRUM("Facets "<<fa<<" and "<<fb<<" are geometrical duplicates")<<endl;
     //cerr<<REDRUM("Facets "<<fa<<" and "<<fb<<" are geometrical duplicates")<<endl;
     goto done;
     goto done;
@@ -1081,6 +886,7 @@ inline void igl::cgal::SelfIntersectMesh<
 
 
   if(total_shared_vertices == 2)
   if(total_shared_vertices == 2)
   {
   {
+    assert(shared.size() == 2);
     // Q: What about coplanar?
     // Q: What about coplanar?
     //
     //
     // o    o
     // o    o
@@ -1089,19 +895,17 @@ inline void igl::cgal::SelfIntersectMesh<
     // | /\ |
     // | /\ |
     // |/  \|
     // |/  \|
     // o----o
     // o----o
-    double_shared_vertex(A,B,fa,fb);
+    double_shared_vertex(A,B,fa,fb,shared);
 
 
     goto done;
     goto done;
   }
   }
   assert(total_shared_vertices<=1);
   assert(total_shared_vertices<=1);
   if(total_shared_vertices==1)
   if(total_shared_vertices==1)
   {
   {
-    assert(va>=0 && va<3);
-    assert(vb>=0 && vb<3);
 //#ifndef NDEBUG
 //#ifndef NDEBUG
 //    CGAL::Object result =
 //    CGAL::Object result =
 //#endif
 //#endif
-    single_shared_vertex(A,B,fa,fb,va,vb);
+    single_shared_vertex(A,B,fa,fb,shared[0].first,shared[0].second);
 //#ifndef NDEBUG
 //#ifndef NDEBUG
 //    if(!CGAL::object_cast<Segment_3 >(&result))
 //    if(!CGAL::object_cast<Segment_3 >(&result))
 //    {
 //    {
@@ -1130,142 +934,5 @@ done:
   return;
   return;
 }
 }
 
 
-// Compute 2D delaunay triangulation of a given 3d triangle and a list of
-// intersection objects (points,segments,triangles). CGAL uses an affine
-// projection rather than an isometric projection, so we're not guaranteed
-// that the 2D delaunay triangulation here will be a delaunay triangulation
-// in 3D.
-//
-// Inputs:
-//   A  triangle in 3D
-//   A_objects_3  updated list of intersection objects for A
-// Outputs:
-//   cdt  Contrained delaunay triangulation in projected 2D plane
-template <
-  typename Kernel,
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedVV,
-  typename DerivedFF,
-  typename DerivedIF,
-  typename DerivedJ,
-  typename DerivedIM>
-inline void igl::cgal::SelfIntersectMesh<
-  Kernel,
-  DerivedV,
-  DerivedF,
-  DerivedVV,
-  DerivedFF,
-  DerivedIF,
-  DerivedJ,
-  DerivedIM>::projected_delaunay(
-  const Triangle_3 & A,
-  const ObjectList & A_objects_3,
-  CDT_plus_2 & cdt)
-{
-  using namespace std;
-  // http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Triangulation_2/Chapter_main.html#Section_2D_Triangulations_Constrained_Plus
-  // Plane of triangle A
-  Plane_3 P(A.vertex(0),A.vertex(1),A.vertex(2));
-  // Insert triangle into vertices
-  typename CDT_plus_2::Vertex_handle corners[3];
-  for(Index i = 0;i<3;i++)
-  {
-    corners[i] = cdt.insert(P.to_2d(A.vertex(i)));
-  }
-  // Insert triangle edges as constraints
-  for(Index i = 0;i<3;i++)
-  {
-    cdt.insert_constraint( corners[(i+1)%3], corners[(i+2)%3]);
-  }
-  // Insert constraints for intersection objects
-  for( const auto & obj : A_objects_3)
-  {
-    if(const Segment_3 *iseg = CGAL::object_cast<Segment_3 >(&obj))
-    {
-      // Add segment constraint
-      cdt.insert_constraint(P.to_2d(iseg->vertex(0)),P.to_2d(iseg->vertex(1)));
-    }else if(const Point_3 *ipoint = CGAL::object_cast<Point_3 >(&obj))
-    {
-      // Add point
-      cdt.insert(P.to_2d(*ipoint));
-    } else if(const Triangle_3 *itri = CGAL::object_cast<Triangle_3 >(&obj))
-    {
-      // Add 3 segment constraints
-      cdt.insert_constraint(P.to_2d(itri->vertex(0)),P.to_2d(itri->vertex(1)));
-      cdt.insert_constraint(P.to_2d(itri->vertex(1)),P.to_2d(itri->vertex(2)));
-      cdt.insert_constraint(P.to_2d(itri->vertex(2)),P.to_2d(itri->vertex(0)));
-    } else if(const std::vector<Point_3 > *polyp = 
-        CGAL::object_cast< std::vector<Point_3 > >(&obj))
-    {
-      //cerr<<REDRUM("Poly...")<<endl;
-      const std::vector<Point_3 > & poly = *polyp;
-      const Index m = poly.size();
-      assert(m>=2);
-      for(Index p = 0;p<m;p++)
-      {
-        const Index np = (p+1)%m;
-        cdt.insert_constraint(P.to_2d(poly[p]),P.to_2d(poly[np]));
-      }
-    }else
-    {
-      cerr<<REDRUM("What is this object?!")<<endl;
-      assert(false);
-    }
-  }
-}
-
-template <
-  typename Kernel,
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedVV,
-  typename DerivedFF,
-  typename DerivedIF,
-  typename DerivedJ,
-  typename DerivedIM>
-inline 
-void 
-igl::cgal::SelfIntersectMesh<
-  Kernel,
-  DerivedV,
-  DerivedF,
-  DerivedVV,
-  DerivedFF,
-  DerivedIF,
-  DerivedJ,
-  DerivedIM>::to_output_type(
-    const typename Kernel::FT & cgal,
-    double & d)
-{
-  d = CGAL::to_double(cgal);
-}
-
-template <
-  typename Kernel,
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedVV,
-  typename DerivedFF,
-  typename DerivedIF,
-  typename DerivedJ,
-  typename DerivedIM>
-inline 
-void 
-igl::cgal::SelfIntersectMesh<
-  Kernel,
-  DerivedV,
-  DerivedF,
-  DerivedVV,
-  DerivedFF,
-  DerivedIF,
-  DerivedJ,
-  DerivedIM>::to_output_type(
-    const typename CGAL::Epeck::FT & cgal,
-    CGAL::Epeck::FT & d)
-{
-  d = cgal;
-}
-
 #endif
 #endif
 
 

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

@@ -0,0 +1,22 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "assign_scalar.h"
+
+IGL_INLINE void igl::cgal::assign_scalar(
+  const typename CGAL::Epeck::FT & cgal,
+  CGAL::Epeck::FT & d)
+{
+  d = cgal;
+}
+
+IGL_INLINE void igl::cgal::assign_scalar(
+  const typename CGAL::Epeck::FT & cgal,
+  double & d)
+{
+  d = CGAL::to_double(cgal);
+}

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

@@ -0,0 +1,31 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_CGAL_ASSIGN_SCALAR_H
+#define IGL_CGAL_ASSIGN_SCALAR_H
+#include "../igl_inline.h"
+#include "CGAL_includes.hpp"
+namespace igl
+{
+  namespace cgal
+  {
+    // Inputs:
+    //   cgal  cgal scalar
+    // Outputs:
+    //   d  output scalar
+    IGL_INLINE void assign_scalar(
+      const typename CGAL::Epeck::FT & cgal,
+      CGAL::Epeck::FT & d);
+    IGL_INLINE void assign_scalar(
+      const typename CGAL::Epeck::FT & cgal,
+      double & d);
+  }
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "assign_scalar.cpp"
+#endif
+#endif

+ 237 - 99
include/igl/cgal/intersect_other.cpp

@@ -8,123 +8,261 @@
 #include "intersect_other.h"
 #include "intersect_other.h"
 #include "CGAL_includes.hpp"
 #include "CGAL_includes.hpp"
 #include "mesh_to_cgal_triangle_list.h"
 #include "mesh_to_cgal_triangle_list.h"
+#include "remesh_intersections.h"
 
 
 #ifndef IGL_FIRST_HIT_EXCEPTION
 #ifndef IGL_FIRST_HIT_EXCEPTION
 #define IGL_FIRST_HIT_EXCEPTION 10
 #define IGL_FIRST_HIT_EXCEPTION 10
 #endif
 #endif
 
 
-IGL_INLINE void igl::cgal::intersect_other(
-  const Eigen::MatrixXd & V,
-  const Eigen::MatrixXi & F,
-  const Eigen::MatrixXd & U,
-  const Eigen::MatrixXi & G,
-  const bool first_only,
-  Eigen::MatrixXi & IF)
+// Un-exposed helper functions
+namespace igl
 {
 {
-  using namespace std;
-  using namespace Eigen;
-
-
-  typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
-  // 3D Primitives
-  typedef CGAL::Point_3<Kernel>    Point_3;
-  typedef CGAL::Segment_3<Kernel>  Segment_3; 
-  typedef CGAL::Triangle_3<Kernel> Triangle_3; 
-  typedef CGAL::Plane_3<Kernel>    Plane_3;
-  typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3; 
-  // 2D Primitives
-  typedef CGAL::Point_2<Kernel>    Point_2;
-  typedef CGAL::Segment_2<Kernel>  Segment_2; 
-  typedef CGAL::Triangle_2<Kernel> Triangle_2; 
-  // 2D Constrained Delaunay Triangulation types
-  typedef CGAL::Triangulation_vertex_base_2<Kernel>  TVB_2;
-  typedef CGAL::Constrained_triangulation_face_base_2<Kernel> CTFB_2;
-  typedef CGAL::Triangulation_data_structure_2<TVB_2,CTFB_2> TDS_2;
-  typedef CGAL::Exact_intersections_tag Itag;
-  typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS_2,Itag> 
-    CDT_2;
-  typedef CGAL::Constrained_triangulation_plus_2<CDT_2> CDT_plus_2;
-  // Axis-align boxes for all-pairs self-intersection detection
-  typedef std::vector<Triangle_3> Triangles;
-  typedef typename Triangles::iterator TrianglesIterator;
-  typedef typename Triangles::const_iterator TrianglesConstIterator;
-  typedef 
-    CGAL::Box_intersection_d::Box_with_handle_d<double,3,TrianglesIterator> 
-    Box;
-
-  Triangles TF,TG;
-  // Compute and process self intersections
-  mesh_to_cgal_triangle_list(V,F,TF);
-  mesh_to_cgal_triangle_list(U,G,TG);
-  // http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Box_intersection_d/Chapter_main.html#Section_63.5 
-  // Create the corresponding vector of bounding boxes
-  std::vector<Box> F_boxes,G_boxes;
-  const auto box_up = [](Triangles & T, std::vector<Box> & boxes)
+  namespace cgal
   {
   {
-    boxes.reserve(T.size());
-    for ( 
-      TrianglesIterator tit = T.begin(); 
-      tit != T.end(); 
-      ++tit)
+    template <typename DerivedF>
+    static IGL_INLINE void push_result(
+      const Eigen::PlainObjectBase<DerivedF> & F,
+      const int f,
+      const CGAL::Object & result,
+      std::map<
+        typename DerivedF::Index,
+        std::pair<typename DerivedF::Index,
+          std::vector<CGAL::Object> > > & offending,
+      std::map<
+        std::pair<typename DerivedF::Index,typename DerivedF::Index>,
+        std::vector<typename DerivedF::Index> > & edge2faces)
     {
     {
-      boxes.push_back(Box(tit->bbox(), tit));
-    }
-  };
-  box_up(TF,F_boxes);
-  box_up(TG,G_boxes);
-  std::list<int> lIF;
-  const auto cb = [&](const Box &a, const Box &b)
-  {
-    using namespace std;
-    // index in F and T
-    int fa = a.handle()-TF.begin();
-    int fb = b.handle()-TG.begin();
-    const Triangle_3 & A = *a.handle();
-    const Triangle_3 & B = *b.handle();
-    if(CGAL::do_intersect(A,B))
-    {
-      // There was an intersection
-      lIF.push_back(fa);
-      lIF.push_back(fb);
-      if(first_only)
+      typedef typename DerivedF::Index Index;
+      typedef std::pair<Index,Index> EMK;
+      if(offending.count(f) == 0)
       {
       {
-        throw IGL_FIRST_HIT_EXCEPTION;
+        // first time marking, initialize with new id and empty list
+        Index id = offending.size();
+        offending[f] = {id,{}};
+        for(Index e = 0; e<3;e++)
+        {
+          // append face to edge's list
+          Index i = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+1)%3) : F(f,(e+2)%3);
+          Index j = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+2)%3) : F(f,(e+1)%3);
+          edge2faces[EMK(i,j)].push_back(f);
+        }
       }
       }
+      offending[f].second.push_back(result);
     }
     }
-  };
-  try{
-    CGAL::box_intersection_d(
-      F_boxes.begin(), F_boxes.end(),
-      G_boxes.begin(), G_boxes.end(),
-      cb);
-  }catch(int e)
-  {
-    // Rethrow if not FIRST_HIT_EXCEPTION
-    if(e != IGL_FIRST_HIT_EXCEPTION)
+    template <
+      typename Kernel,
+      typename DerivedVA,
+      typename DerivedFA,
+      typename DerivedVB,
+      typename DerivedFB,
+      typename DerivedIF,
+      typename DerivedVVA,
+      typename DerivedFFA,
+      typename DerivedJA,
+      typename DerivedIMA,
+      typename DerivedVVB,
+      typename DerivedFFB,
+      typename DerivedJB,
+      typename DerivedIMB>
+    static IGL_INLINE bool intersect_other_helper(
+      const Eigen::PlainObjectBase<DerivedVA> & VA,
+      const Eigen::PlainObjectBase<DerivedFA> & FA,
+      const Eigen::PlainObjectBase<DerivedVB> & VB,
+      const Eigen::PlainObjectBase<DerivedFB> & FB,
+      const RemeshSelfIntersectionsParam & params,
+      Eigen::PlainObjectBase<DerivedIF> & IF,
+      Eigen::PlainObjectBase<DerivedVVA> & VVA,
+      Eigen::PlainObjectBase<DerivedFFA> & FFA,
+      Eigen::PlainObjectBase<DerivedJA>  & JA,
+      Eigen::PlainObjectBase<DerivedIMA> & IMA,
+      Eigen::PlainObjectBase<DerivedVVB> & VVB,
+      Eigen::PlainObjectBase<DerivedFFB> & FFB,
+      Eigen::PlainObjectBase<DerivedJB>  & JB,
+      Eigen::PlainObjectBase<DerivedIMB> & IMB)
     {
     {
-      throw e;
+
+      using namespace std;
+      using namespace Eigen;
+
+      typedef typename DerivedFA::Index Index;
+      // 3D Primitives
+      typedef CGAL::Point_3<Kernel>    Point_3;
+      typedef CGAL::Segment_3<Kernel>  Segment_3; 
+      typedef CGAL::Triangle_3<Kernel> Triangle_3; 
+      typedef CGAL::Plane_3<Kernel>    Plane_3;
+      typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3; 
+      // 2D Primitives
+      typedef CGAL::Point_2<Kernel>    Point_2;
+      typedef CGAL::Segment_2<Kernel>  Segment_2; 
+      typedef CGAL::Triangle_2<Kernel> Triangle_2; 
+      // 2D Constrained Delaunay Triangulation types
+      typedef CGAL::Triangulation_vertex_base_2<Kernel>  TVB_2;
+      typedef CGAL::Constrained_triangulation_face_base_2<Kernel> CTAB_2;
+      typedef CGAL::Triangulation_data_structure_2<TVB_2,CTAB_2> TDS_2;
+      typedef CGAL::Exact_intersections_tag Itag;
+      typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS_2,Itag> 
+        CDT_2;
+      typedef CGAL::Constrained_triangulation_plus_2<CDT_2> CDT_plus_2;
+      // Axis-align boxes for all-pairs self-intersection detection
+      typedef std::vector<Triangle_3> Triangles;
+      typedef typename Triangles::iterator TrianglesIterator;
+      typedef typename Triangles::const_iterator TrianglesConstIterator;
+      typedef 
+        CGAL::Box_intersection_d::Box_with_handle_d<double,3,TrianglesIterator> 
+        Box;
+      typedef 
+        std::map<Index,std::pair<Index,std::vector<CGAL::Object> > > 
+        OffendingMap;
+      typedef std::map<std::pair<Index,Index>,std::vector<Index> >  EdgeMap;
+      typedef std::pair<Index,Index> EMK;
+
+      Triangles TA,TB;
+      // Compute and process self intersections
+      mesh_to_cgal_triangle_list(VA,FA,TA);
+      mesh_to_cgal_triangle_list(VB,FB,TB);
+      // http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Box_intersection_d/Chapter_main.html#Section_63.5 
+      // Create the corresponding vector of bounding boxes
+      std::vector<Box> A_boxes,B_boxes;
+      const auto box_up = [](Triangles & T, std::vector<Box> & boxes)
+      {
+        boxes.reserve(T.size());
+        for ( 
+          TrianglesIterator tit = T.begin(); 
+          tit != T.end(); 
+          ++tit)
+        {
+          boxes.push_back(Box(tit->bbox(), tit));
+        }
+      };
+      box_up(TA,A_boxes);
+      box_up(TB,B_boxes);
+      OffendingMap offendingA,offendingB;
+      EdgeMap edge2facesA,edge2facesB;
+
+      std::list<int> lIF;
+      const auto cb = [&](const Box &a, const Box &b)
+      {
+        using namespace std;
+        // index in F and T
+        int fa = a.handle()-TA.begin();
+        int fb = b.handle()-TB.begin();
+        const Triangle_3 & A = *a.handle();
+        const Triangle_3 & B = *b.handle();
+        if(CGAL::do_intersect(A,B))
+        {
+          // There was an intersection
+          lIF.push_back(fa);
+          lIF.push_back(fb);
+          if(params.first_only)
+          {
+            throw IGL_FIRST_HIT_EXCEPTION;
+          }
+          if(!params.detect_only)
+          {
+            CGAL::Object result = CGAL::intersection(A,B);
+
+            push_result(FA,fa,result,offendingA,edge2facesA);
+            push_result(FB,fb,result,offendingB,edge2facesB);
+          }
+        }
+      };
+      try{
+        CGAL::box_intersection_d(
+          A_boxes.begin(), A_boxes.end(),
+          B_boxes.begin(), B_boxes.end(),
+          cb);
+      }catch(int e)
+      {
+        // Rethrow if not FIRST_HIT_EXCEPTION
+        if(e != IGL_FIRST_HIT_EXCEPTION)
+        {
+          throw e;
+        }
+        // Otherwise just fall through
+      }
+
+      // Convert lIF to Eigen matrix
+      assert(lIF.size()%2 == 0);
+      IF.resize(lIF.size()/2,2);
+      {
+        int i=0;
+        for(
+          list<int>::const_iterator ifit = lIF.begin();
+          ifit!=lIF.end();
+          )
+        {
+          IF(i,0) = (*ifit);
+          ifit++; 
+          IF(i,1) = (*ifit);
+          ifit++;
+          i++;
+        }
+      }
+      if(!params.detect_only)
+      {
+        remesh_intersections(VA,FA,TA,offendingA,edge2facesA,VVA,FFA,JA,IMA);
+        remesh_intersections(VB,FB,TB,offendingB,edge2facesB,VVB,FFB,JB,IMB);
+      }
+
+      return IF.rows() > 0;
     }
     }
-    // Otherwise just fall through
   }
   }
+}
 
 
-  // Convert lIF to Eigen matrix
-  assert(lIF.size()%2 == 0);
-  IF.resize(lIF.size()/2,2);
+template <
+  typename DerivedVA,
+  typename DerivedFA,
+  typename DerivedVB,
+  typename DerivedFB,
+  typename DerivedIF,
+  typename DerivedVVA,
+  typename DerivedFFA,
+  typename DerivedJA,
+  typename DerivedIMA,
+  typename DerivedVVB,
+  typename DerivedFFB,
+  typename DerivedJB,
+  typename DerivedIMB>
+IGL_INLINE bool igl::cgal::intersect_other(
+  const Eigen::PlainObjectBase<DerivedVA> & VA,
+  const Eigen::PlainObjectBase<DerivedFA> & FA,
+  const Eigen::PlainObjectBase<DerivedVB> & VB,
+  const Eigen::PlainObjectBase<DerivedFB> & FB,
+  const RemeshSelfIntersectionsParam & params,
+  Eigen::PlainObjectBase<DerivedIF> & IF,
+  Eigen::PlainObjectBase<DerivedVVA> & VVA,
+  Eigen::PlainObjectBase<DerivedFFA> & FFA,
+  Eigen::PlainObjectBase<DerivedJA>  & JA,
+  Eigen::PlainObjectBase<DerivedIMA> & IMA,
+  Eigen::PlainObjectBase<DerivedVVB> & VVB,
+  Eigen::PlainObjectBase<DerivedFFB> & FFB,
+  Eigen::PlainObjectBase<DerivedJB>  & JB,
+  Eigen::PlainObjectBase<DerivedIMB> & IMB)
+{
+  if(params.detect_only)
   {
   {
-    int i=0;
-    for(
-      list<int>::const_iterator ifit = lIF.begin();
-      ifit!=lIF.end();
-      )
-    {
-      IF(i,0) = (*ifit);
-      ifit++; 
-      IF(i,1) = (*ifit);
-      ifit++;
-      i++;
-    }
+    return intersect_other_helper<CGAL::Epick>
+      (VA,FA,VB,FB,params,IF,VVA,FFA,JA,IMA,VVB,FFB,JB,IMB);
+  }else
+  {
+    return intersect_other_helper<CGAL::Epeck>
+      (VA,FA,VB,FB,params,IF,VVA,FFA,JA,IMA,VVB,FFB,JB,IMB);
   }
   }
+}
 
 
+IGL_INLINE bool igl::cgal::intersect_other(
+  const Eigen::MatrixXd & VA,
+  const Eigen::MatrixXi & FA,
+  const Eigen::MatrixXd & VB,
+  const Eigen::MatrixXi & FB,
+  const bool first_only,
+  Eigen::MatrixXi & IF)
+{
+  Eigen::MatrixXd VVA,VVB;
+  Eigen::MatrixXi FFA,FFB;
+  Eigen::VectorXi JA,JB,IMA,IMB;
+  return intersect_other(
+    VA,FA,VB,FB,{true,first_only},IF,VVA,FFA,JA,IMA,VVB,FFB,JB,IMB);
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY

+ 66 - 16
include/igl/cgal/intersect_other.h

@@ -1,13 +1,14 @@
 // This file is part of libigl, a simple c++ geometry processing library.
 // This file is part of libigl, a simple c++ geometry processing library.
 // 
 // 
-// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
 // 
 // 
 // This Source Code Form is subject to the terms of the Mozilla Public License 
 // 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 
 // 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/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_CGAL_INTERSECT_OTHER_H
 #ifndef IGL_CGAL_INTERSECT_OTHER_H
 #define IGL_CGAL_INTERSECT_OTHER_H
 #define IGL_CGAL_INTERSECT_OTHER_H
-#include <igl/igl_inline.h>
+#include "../igl_inline.h"
+#include "RemeshSelfIntersectionsParam.h"
 
 
 #include <Eigen/Dense>
 #include <Eigen/Dense>
 
 
@@ -22,27 +23,76 @@ namespace igl
 {
 {
   namespace cgal
   namespace cgal
   {
   {
-    // INTERSECT Given a triangle mesh (V,F) and another mesh (U,G) find all pairs
-    // of intersecting faces. Note that self-intersections are ignored.
+    // INTERSECT_OTHER Given a triangle mesh (VA,FA) and another mesh (VB,FB)
+    // find all pairs of intersecting faces. Note that self-intersections are
+    // ignored.
     // 
     // 
-    // [VV,FF,IF] = selfintersect(V,F,'ParameterName',ParameterValue, ...)
+    // Inputs:
+    //   VA  #V by 3 list of vertex positions
+    //   FA  #F by 3 list of triangle indices into VA
+    //   VB  #V by 3 list of vertex positions
+    //   FB  #F by 3 list of triangle indices into VB
+    //   params   whether to detect only and then whether to only find first
+    //     intersection
+    // Outputs:
+    //   IF  #intersecting face pairs by 2 list of intersecting face pairs,
+    //     indexing FA and FB
+    //   VVA  #VVA by 3 list of vertex positions
+    //   FFA  #FFA by 3 list of triangle indices into VVA
+    //   JA  #FFA list of indices into FA denoting birth triangle
+    //   IMA  #VVA list of indices into VVA of unique vertices.
+    //   VVB  #VVB by 3 list of vertex positions
+    //   FFB  #FFB by 3 list of triangle indices into VVB
+    //   JB  #FFB list of indices into FB denoting birth triangle
+    //   IMB  #VVB list of indices into VVB of unique vertices.
+    template <
+      typename DerivedVA,
+      typename DerivedFA,
+      typename DerivedVB,
+      typename DerivedFB,
+      typename DerivedIF,
+      typename DerivedVVA,
+      typename DerivedFFA,
+      typename DerivedJA,
+      typename DerivedIMA,
+      typename DerivedVVB,
+      typename DerivedFFB,
+      typename DerivedJB,
+      typename DerivedIMB>
+    IGL_INLINE bool intersect_other(
+      const Eigen::PlainObjectBase<DerivedVA> & VA,
+      const Eigen::PlainObjectBase<DerivedFA> & FA,
+      const Eigen::PlainObjectBase<DerivedVB> & VB,
+      const Eigen::PlainObjectBase<DerivedFB> & FB,
+      const RemeshSelfIntersectionsParam & params,
+      Eigen::PlainObjectBase<DerivedIF> & IF,
+      Eigen::PlainObjectBase<DerivedVVA> & VVA,
+      Eigen::PlainObjectBase<DerivedFFA> & FFA,
+      Eigen::PlainObjectBase<DerivedJA>  & JA,
+      Eigen::PlainObjectBase<DerivedIMA> & IMA,
+      Eigen::PlainObjectBase<DerivedVVB> & VVB,
+      Eigen::PlainObjectBase<DerivedFFB> & FFB,
+      Eigen::PlainObjectBase<DerivedJB>  & JB,
+      Eigen::PlainObjectBase<DerivedIMB> & IMB);
+    // Legacy wrapper for detect only using common types.
     //
     //
     // Inputs:
     // Inputs:
-    //   V  #V by 3 list of vertex positions
-    //   F  #F by 3 list of triangle indices into V
-    //   U  #U by 3 list of vertex positions
-    //   G  #G by 3 list of triangle indices into U
+    //   VA  #V by 3 list of vertex positions
+    //   FA  #F by 3 list of triangle indices into VA
+    //   VB  #V by 3 list of vertex positions
+    //   FB  #F by 3 list of triangle indices into VB
     //   first_only  whether to only detect the first intersection.
     //   first_only  whether to only detect the first intersection.
     // Outputs:
     // Outputs:
     //   IF  #intersecting face pairs by 2 list of intersecting face pairs,
     //   IF  #intersecting face pairs by 2 list of intersecting face pairs,
-    //     indexing F and G
+    //     indexing FA and FB
+    // Returns true if any intersections were found
     //
     //
-    // See also: selfintersect
-    IGL_INLINE void intersect_other(
-      const Eigen::MatrixXd & V,
-      const Eigen::MatrixXi & F,
-      const Eigen::MatrixXd & U,
-      const Eigen::MatrixXi & G,
+    // See also: remesh_self_intersections
+    IGL_INLINE bool intersect_other(
+      const Eigen::MatrixXd & VA,
+      const Eigen::MatrixXi & FA,
+      const Eigen::MatrixXd & VB,
+      const Eigen::MatrixXi & FB,
       const bool first_only,
       const bool first_only,
       Eigen::MatrixXi & IF);
       Eigen::MatrixXi & IF);
   }
   }

+ 1 - 1
include/igl/cgal/mesh_to_polyhedron.cpp

@@ -47,7 +47,7 @@ IGL_INLINE bool igl::cgal::mesh_to_polyhedron(
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-// Explicit template instanciation
+// Explicit template specialization
 #include <CGAL/Simple_cartesian.h>
 #include <CGAL/Simple_cartesian.h>
 #include <CGAL/Polyhedron_items_with_id_3.h>
 #include <CGAL/Polyhedron_items_with_id_3.h>
 template bool igl::cgal::mesh_to_polyhedron<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> >&);
 template bool igl::cgal::mesh_to_polyhedron<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>, CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> >&);

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

@@ -0,0 +1,211 @@
+#include "order_facets_around_edge.h"
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+
+namespace igl {
+    namespace cgal {
+        namespace order_facets_around_edges_helper {
+            template<typename T>
+            std::vector<size_t> index_sort(const std::vector<T>& data) {
+                const size_t len = data.size();
+                std::vector<size_t> order(len);
+                for (size_t i=0; i<len; i++) order[i] = i;
+
+                auto comp = [&](size_t i, size_t j) {
+                    return data[i] < data[j];
+                };
+                std::sort(order.begin(), order.end(), comp);
+                return order;
+            }
+        }
+    }
+}
+
+// adj_faces contains signed index starting from +- 1.
+template<
+    typename DerivedV,
+    typename DerivedF,
+    typename DerivedI >
+void igl::cgal::order_facets_around_edge(
+    const Eigen::PlainObjectBase<DerivedV>& V,
+    const Eigen::PlainObjectBase<DerivedF>& F,
+    size_t s, size_t d, 
+    const std::vector<int>& adj_faces,
+    Eigen::PlainObjectBase<DerivedI>& order) {
+
+    using namespace igl::cgal::order_facets_around_edges_helper;
+
+    // Although we only need exact predicates in the algorithm,
+    // exact constructions are needed to avoid degeneracies due to
+    // casting to double.
+    typedef CGAL::Exact_predicates_exact_constructions_kernel K;
+    typedef K::Point_3 Point_3;
+    typedef K::Plane_3 Plane_3;
+
+    auto get_face_index = [&](int adj_f)->size_t{
+        return abs(adj_f) - 1;
+    };
+
+    auto get_opposite_vertex = [&](size_t fid)->size_t {
+        if (F(fid, 0) != s && F(fid, 0) != d) return F(fid, 0);
+        if (F(fid, 1) != s && F(fid, 1) != d) return F(fid, 1);
+        if (F(fid, 2) != s && F(fid, 2) != d) return F(fid, 2);
+        assert(false);
+        return -1;
+    };
+
+    // Handle base cases
+    if (adj_faces.size() == 0) {
+        order.resize(0, 1);
+        return;
+    } else if (adj_faces.size() == 1) {
+        order.resize(1, 1);
+        order(0, 0) = 0;
+        return;
+    } else if (adj_faces.size() == 2) {
+        const size_t o1 =
+            get_opposite_vertex(get_face_index(adj_faces[0]));
+        const size_t o2 =
+            get_opposite_vertex(get_face_index(adj_faces[1]));
+        const Point_3 ps(V(s, 0), V(s, 1), V(s, 2));
+        const Point_3 pd(V(d, 0), V(d, 1), V(d, 2));
+        const Point_3 p1(V(o1, 0), V(o1, 1), V(o1, 2));
+        const Point_3 p2(V(o2, 0), V(o2, 1), V(o2, 2));
+        order.resize(2, 1);
+        switch (CGAL::orientation(ps, pd, p1, p2)) {
+            case CGAL::POSITIVE:
+                order(0, 0) = 1;
+                order(1, 0) = 0;
+                break;
+            case CGAL::NEGATIVE:
+                order(0, 0) = 0;
+                order(1, 0) = 1;
+                break;
+            case CGAL::COPLANAR:
+                order(0, 0) = adj_faces[0] < adj_faces[1] ? 0:1;
+                order(1, 0) = adj_faces[0] < adj_faces[1] ? 1:0;
+                break;
+            default:
+                assert(false);
+        }
+        return;
+    }
+
+    const size_t num_adj_faces = adj_faces.size();
+    const size_t o = get_opposite_vertex(
+            get_face_index(adj_faces[0]));
+    const Point_3 p_s(V(s, 0), V(s, 1), V(s, 2));
+    const Point_3 p_d(V(d, 0), V(d, 1), V(d, 2));
+    const Point_3 p_o(V(o, 0), V(o, 1), V(o, 2));
+    const Plane_3 separator(p_s, p_d, p_o);
+    assert(!separator.is_degenerate());
+
+    std::vector<Point_3> opposite_vertices;
+    for (size_t i=0; i<num_adj_faces; i++) {
+        const size_t o = get_opposite_vertex(
+                get_face_index(adj_faces[i]));
+        opposite_vertices.emplace_back(
+                V(o, 0), V(o, 1), V(o, 2));
+    }
+
+    std::vector<int> positive_side;
+    std::vector<int> negative_side;
+    std::vector<int> tie_positive_oriented;
+    std::vector<int> tie_negative_oriented;
+
+    std::vector<size_t> positive_side_index;
+    std::vector<size_t> negative_side_index;
+    std::vector<size_t> tie_positive_oriented_index;
+    std::vector<size_t> tie_negative_oriented_index;
+
+    for (size_t i=0; i<num_adj_faces; i++) {
+        const int f = adj_faces[i];
+        const Point_3& p_a = opposite_vertices[i];
+        auto orientation = separator.oriented_side(p_a);
+        switch (orientation) {
+            case CGAL::ON_POSITIVE_SIDE:
+                positive_side.push_back(f);
+                positive_side_index.push_back(i);
+                break;
+            case CGAL::ON_NEGATIVE_SIDE:
+                negative_side.push_back(f);
+                negative_side_index.push_back(i);
+                break;
+            case CGAL::ON_ORIENTED_BOUNDARY:
+                {
+                    const Plane_3 other(p_s, p_d, p_a);
+                    const auto target_dir = separator.orthogonal_direction();
+                    const auto query_dir = other.orthogonal_direction();
+                    if (target_dir == query_dir) {
+                        tie_positive_oriented.push_back(f);
+                        tie_positive_oriented_index.push_back(i);
+                    } else if (target_dir == -query_dir) {
+                        tie_negative_oriented.push_back(f);
+                        tie_negative_oriented_index.push_back(i);
+                    } else {
+                        assert(false);
+                    }
+                }
+                break;
+            default:
+                // Should not be here.
+                assert(false);
+        }
+    }
+
+    Eigen::PlainObjectBase<DerivedI> positive_order, negative_order;
+    order_facets_around_edge(V, F, s, d, positive_side, positive_order);
+    order_facets_around_edge(V, F, s, d, negative_side, negative_order);
+    std::vector<size_t> tie_positive_order =
+        index_sort(tie_positive_oriented);
+    std::vector<size_t> tie_negative_order =
+        index_sort(tie_negative_oriented);
+
+    // Copy results into order vector.
+    const size_t tie_positive_size = tie_positive_oriented.size();
+    const size_t tie_negative_size = tie_negative_oriented.size();
+    const size_t positive_size = positive_order.size();
+    const size_t negative_size = negative_order.size();
+
+    order.resize(tie_positive_size + positive_size +
+            tie_negative_size + negative_size, 1);
+
+    size_t count=0;
+    for (size_t i=0; i<tie_positive_size; i++) {
+        order(count+i, 0) =
+            tie_positive_oriented_index[tie_positive_order[i]];
+    }
+    count += tie_positive_size;
+
+    for (size_t i=0; i<negative_size; i++) {
+        order(count+i, 0) = negative_side_index[negative_order(i, 0)];
+    }
+    count += negative_size;
+
+    for (size_t i=0; i<tie_negative_size; i++) {
+        order(count+i, 0) =
+            tie_negative_oriented_index[tie_negative_order[i]];
+    }
+    count += tie_negative_size;
+
+    for (size_t i=0; i<positive_size; i++) {
+        order(count+i, 0) = positive_side_index[positive_order(i, 0)];
+    }
+    count += positive_size;
+    assert(count == num_adj_faces);
+
+    // Find the correct start point.
+    size_t start_idx = 0;
+    for (size_t i=0; i<num_adj_faces; i++) {
+        const Point_3& p_a = opposite_vertices[order(i, 0)];
+        const Point_3& p_b =
+            opposite_vertices[order((i+1)%num_adj_faces, 0)];
+        if (CGAL::orientation(p_s, p_d, p_a, p_b) == CGAL::POSITIVE) {
+            start_idx = (i+1)%num_adj_faces;
+            break;
+        }
+    }
+    DerivedI circular_order = order;
+    for (size_t i=0; i<num_adj_faces; i++) {
+        order(i, 0) = circular_order((start_idx + i)%num_adj_faces, 0);
+    }
+}

+ 53 - 0
include/igl/cgal/order_facets_around_edge.h

@@ -0,0 +1,53 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Qingnan Zhou <qnzhou@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 ORDER_FACETS_AROUND_EDGE_H
+#define ORDER_FACETS_AROUND_EDGE_H
+#include "../igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+
+namespace igl {
+    namespace cgal {
+        // Given a directed edge, sort its adjacent faces.  Assuming the
+        // directed edge is (s, d).  Sort the adjacent faces clockwise around the
+        // axis (d - s), i.e. left-hand rule.  An adjacent face is consistently
+        // oriented if it contains (d, s) as a directed edge.
+        //
+        // For overlapping faces, break the tie using signed face index, smaller
+        // signed index comes before the larger signed index.  Signed index is
+        // computed as (consistent? 1:-1) * (face_index + 1).
+        //
+        // Inputs:
+        //   V          #V by 3 list of vertices.
+        //   F          #F by 3 list of faces
+        //   s          Index of source vertex.
+        //   d          Index of desination vertex.
+        //   adj_faces  List of adjacent face signed indices.
+        //
+        // Output:
+        //   order      List of face indices that orders adjacent faces around
+        //              edge (s, d) clockwise.
+        template<
+            typename DerivedV,
+            typename DerivedF,
+            typename DerivedI >
+        IGL_INLINE
+        void order_facets_around_edge(
+                const Eigen::PlainObjectBase<DerivedV>& V,
+                const Eigen::PlainObjectBase<DerivedF>& F,
+                size_t s, size_t d, 
+                const std::vector<int>& adj_faces,
+                Eigen::PlainObjectBase<DerivedI>& order);
+    }
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#include "order_facets_around_edge.cpp"
+#endif
+#endif

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

@@ -6,6 +6,7 @@
 // v. 2.0. If a copy of the MPL was not distributed with this file, You can 
 // 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/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "order_facets_around_edges.h"
 #include "order_facets_around_edges.h"
+#include "order_facets_around_edge.h"
 #include "../sort_angles.h"
 #include "../sort_angles.h"
 #include <type_traits>
 #include <type_traits>
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
@@ -252,3 +253,80 @@ igl::cgal::order_facets_around_edges(
         }
         }
     }
     }
 }
 }
+
+template<
+    typename DerivedV,
+    typename DerivedF,
+    typename DerivedE,
+    typename DeriveduE,
+    typename DerivedEMAP,
+    typename uE2EType,
+    typename uE2oEType,
+    typename uE2CType >
+IGL_INLINE void igl::cgal::order_facets_around_edges(
+        const Eigen::PlainObjectBase<DerivedV>& V,
+        const Eigen::PlainObjectBase<DerivedF>& F,
+        const Eigen::PlainObjectBase<DerivedE>& E,
+        const Eigen::PlainObjectBase<DeriveduE>& uE,
+        const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
+        const std::vector<std::vector<uE2EType> >& uE2E,
+        std::vector<std::vector<uE2oEType> >& uE2oE,
+        std::vector<std::vector<uE2CType > >& uE2C ) {
+
+    typedef Eigen::Matrix<typename DerivedV::Scalar, 3, 1> Vector3E;
+    const size_t num_faces = F.rows();
+    const size_t num_undirected_edges = uE.rows();
+
+    auto edge_index_to_face_index = [&](size_t ei) { return ei % num_faces; };
+    auto edge_index_to_corner_index = [&](size_t ei) { return ei / num_faces; };
+
+    uE2oE.resize(num_undirected_edges);
+    uE2C.resize(num_undirected_edges);
+
+    for(size_t ui = 0;ui<num_undirected_edges;ui++)
+    {
+        const auto& adj_edges = uE2E[ui];
+        const size_t edge_valance = adj_edges.size();
+        assert(edge_valance > 0);
+
+        const auto ref_edge = adj_edges[0];
+        const auto ref_face = edge_index_to_face_index(ref_edge);
+
+        const auto ref_corner_o = edge_index_to_corner_index(ref_edge);
+        const auto ref_corner_s = (ref_corner_o+1)%3;
+        const auto ref_corner_d = (ref_corner_o+2)%3;
+
+        const typename DerivedF::Scalar o = F(ref_face, ref_corner_o);
+        const typename DerivedF::Scalar s = F(ref_face, ref_corner_s);
+        const typename DerivedF::Scalar d = F(ref_face, ref_corner_d);
+
+        std::vector<bool> cons(edge_valance);
+        std::vector<int> adj_faces(edge_valance);
+        for (size_t fei=0; fei<edge_valance; fei++) {
+            const auto fe = adj_edges[fei];
+            const auto f = edge_index_to_face_index(fe);
+            const auto c = edge_index_to_corner_index(fe);
+            cons[fei] = (d == F(f, (c+1)%3));
+            adj_faces[fei] = (f+1) * (cons[fei] ? 1:-1);
+
+            assert( cons[fei] ||  (d == F(f,(c+2)%3)));
+            assert(!cons[fei] || (s == F(f,(c+2)%3)));
+            assert(!cons[fei] || (d == F(f,(c+1)%3)));
+        }
+
+        Eigen::VectorXi order;
+        order_facets_around_edge(V, F, s, d, adj_faces, order);
+        assert(order.size() == edge_valance);
+
+        auto& ordered_edges = uE2oE[ui];
+        auto& consistency = uE2C[ui];
+
+        ordered_edges.resize(edge_valance);
+        consistency.resize(edge_valance);
+        for (size_t fei=0; fei<edge_valance; fei++) {
+            ordered_edges[fei] = adj_edges[order[fei]];
+            consistency[fei] = cons[order[fei]];
+        }
+    }
+}
+

+ 30 - 1
include/igl/cgal/order_facets_around_edges.h

@@ -10,12 +10,20 @@
 #include "../igl_inline.h"
 #include "../igl_inline.h"
 #include <Eigen/Core>
 #include <Eigen/Core>
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <vector>
 
 
 namespace igl
 namespace igl
 {
 {
   namespace cgal
   namespace cgal
   {
   {
-    // For each undirected edge, sort its adjacent faces.
+    // For each undirected edge, sort its adjacent faces.  Assuming the
+    // undirected edge is (s, d).  Sort the adjacent faces clockwise around the
+    // axis (d - s), i.e. left-hand rule.  An adjacent face is consistently
+    // oriented if it contains (d, s) as a directed edge.
+    //
+    // For overlapping faces, break the tie using signed face index, smaller
+    // signed index comes before the larger signed index.  Signed index is
+    // computed as (consistent? 1:-1) * index.
     //
     //
     // Inputs:
     // Inputs:
     //   V    #V by 3 list of vertices.
     //   V    #V by 3 list of vertices.
@@ -79,6 +87,27 @@ namespace igl
             const std::vector<std::vector<uE2EType> >& uE2E,
             const std::vector<std::vector<uE2EType> >& uE2E,
             std::vector<std::vector<uE2oEType> >& uE2oE,
             std::vector<std::vector<uE2oEType> >& uE2oE,
             std::vector<std::vector<uE2CType > >& uE2C );
             std::vector<std::vector<uE2CType > >& uE2C );
+
+    // Order faces around each edge. Only exact predicate is used in the algorithm.
+    // Normal is not needed.
+    template<
+        typename DerivedV,
+        typename DerivedF,
+        typename DerivedE,
+        typename DeriveduE,
+        typename DerivedEMAP,
+        typename uE2EType,
+        typename uE2oEType,
+        typename uE2CType >
+    IGL_INLINE void order_facets_around_edges(
+            const Eigen::PlainObjectBase<DerivedV>& V,
+            const Eigen::PlainObjectBase<DerivedF>& F,
+            const Eigen::PlainObjectBase<DerivedE>& E,
+            const Eigen::PlainObjectBase<DeriveduE>& uE,
+            const Eigen::PlainObjectBase<DerivedEMAP>& EMAP,
+            const std::vector<std::vector<uE2EType> >& uE2E,
+            std::vector<std::vector<uE2oEType> >& uE2oE,
+            std::vector<std::vector<uE2CType > >& uE2C );
   }
   }
 }
 }
 
 

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

@@ -0,0 +1,74 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Qingnan Zhou <qnzhou@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 "outer_facet.h"
+#include "../outer_element.h"
+#include "order_facets_around_edge.h"
+#include <algorithm>
+
+template<
+    typename DerivedV,
+    typename DerivedF,
+    typename DerivedI,
+    typename IndexType
+    >
+IGL_INLINE void igl::cgal::outer_facet(
+        const Eigen::PlainObjectBase<DerivedV> & V,
+        const Eigen::PlainObjectBase<DerivedF> & F,
+        const Eigen::PlainObjectBase<DerivedI> & I,
+        IndexType & f,
+        bool & flipped) {
+
+    // Algorithm:
+    //
+    //    1. Find an outer edge (s, d).
+    //
+    //    2. Order adjacent facets around this edge. Because the edge is an
+    //    outer edge, there exists a plane passing through it such that all its
+    //    adjacent facets lie on the same side. The implementation of
+    //    order_facets_around_edge() will find a natural start facet such that
+    //    The first and last facets according to this order are on the outside.
+    //
+    //    3. Because the vertex s is an outer vertex by construction (see
+    //    implemnetation of outer_edge()). The first adjacent facet is facing
+    //    outside (i.e. flipped=false) if it contains directed edge (s, d).  
+    //
+    typedef typename DerivedV::Scalar Scalar; typedef typename DerivedV::Index
+        Index; const size_t INVALID = std::numeric_limits<size_t>::max();
+
+    Index s,d;
+    Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces;
+    outer_edge(V, F, I, s, d, incident_faces);
+    assert(incident_faces.size() > 0);
+
+    auto convert_to_signed_index = [&](size_t fid) -> int{
+        if ((F(fid, 0) == s && F(fid, 1) == d) ||
+            (F(fid, 1) == s && F(fid, 2) == d) ||
+            (F(fid, 2) == s && F(fid, 0) == d) ) {
+            return int(fid+1) * -1;
+        } else {
+            return int(fid+1);
+        }
+    };
+
+    auto signed_index_to_index = [&](int signed_id) -> size_t {
+        return size_t(abs(signed_id) - 1);
+    };
+
+    std::vector<int> adj_faces(incident_faces.size());
+    std::transform(incident_faces.data(),
+            incident_faces.data() + incident_faces.size(),
+            adj_faces.begin(),
+            convert_to_signed_index);
+
+    Eigen::VectorXi order;
+    order_facets_around_edge(V, F, s, d, adj_faces, order);
+
+    f = signed_index_to_index(adj_faces[order[0]]);
+    flipped = adj_faces[order[0]] > 0;
+}

+ 55 - 0
include/igl/cgal/outer_facet.h

@@ -0,0 +1,55 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Qingnan Zhou <qnzhou@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_CGAL_OUTER_FACET_H
+#define IGL_CGAL_OUTER_FACET_H
+#include "../igl_inline.h"
+#include <Eigen/Core>
+
+namespace igl
+{
+    namespace cgal
+    {
+        // Find a facet that is reachable from infinity without crossing any faces.
+        // Such facet is called "outer facet."
+        //
+        // Precondition: The input mesh must have all self-intersection resolved.  I.e
+        // there is no duplicated vertices, no overlapping edge and no intersecting
+        // faces (the only exception is there could be topologically duplicated faces).
+        // See cgal::remesh_self_intersections.h for how to obtain such input.
+        //
+        // This function differ from igl::outer_facet() in the fact this
+        // funciton is more robust because it does not rely on facet normals.
+        //
+        // Inputs:
+        //   V  #V by 3 list of vertex positions
+        //   F  #F by 3 list of triangle indices into V
+        //   I  #I list of facets to consider
+        // Outputs:
+        //   f  Index of the outer facet.
+        //   flipped  true iff the normal of f points inwards.
+        template<
+            typename DerivedV,
+            typename DerivedF,
+            typename DerivedI,
+            typename IndexType
+            >
+        IGL_INLINE void outer_facet(
+                const Eigen::PlainObjectBase<DerivedV> & V,
+                const Eigen::PlainObjectBase<DerivedF> & F,
+                const Eigen::PlainObjectBase<DerivedI> & I,
+                IndexType & f,
+                bool & flipped);
+    }
+
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "outer_facet.cpp"
+#endif
+#endif

+ 9 - 112
include/igl/cgal/outer_hull.cpp

@@ -7,7 +7,7 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "outer_hull.h"
 #include "outer_hull.h"
 #include "order_facets_around_edges.h"
 #include "order_facets_around_edges.h"
-#include "../outer_facet.h"
+#include "outer_facet.h"
 #include "../sortrows.h"
 #include "../sortrows.h"
 #include "../facet_components.h"
 #include "../facet_components.h"
 #include "../winding_number.h"
 #include "../winding_number.h"
@@ -30,14 +30,12 @@
 template <
 template <
   typename DerivedV,
   typename DerivedV,
   typename DerivedF,
   typename DerivedF,
-  typename DerivedN,
   typename DerivedG,
   typename DerivedG,
   typename DerivedJ,
   typename DerivedJ,
   typename Derivedflip>
   typename Derivedflip>
 IGL_INLINE void igl::cgal::outer_hull(
 IGL_INLINE void igl::cgal::outer_hull(
   const Eigen::PlainObjectBase<DerivedV> & V,
   const Eigen::PlainObjectBase<DerivedV> & V,
   const Eigen::PlainObjectBase<DerivedF> & F,
   const Eigen::PlainObjectBase<DerivedF> & F,
-  const Eigen::PlainObjectBase<DerivedN> & N,
   Eigen::PlainObjectBase<DerivedG> & G,
   Eigen::PlainObjectBase<DerivedG> & G,
   Eigen::PlainObjectBase<DerivedJ> & J,
   Eigen::PlainObjectBase<DerivedJ> & J,
   Eigen::PlainObjectBase<Derivedflip> & flip)
   Eigen::PlainObjectBase<Derivedflip> & flip)
@@ -53,7 +51,6 @@ IGL_INLINE void igl::cgal::outer_hull(
   typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
   typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
   typedef Matrix<typename DerivedG::Scalar,Dynamic,DerivedG::ColsAtCompileTime> MatrixXG;
   typedef Matrix<typename DerivedG::Scalar,Dynamic,DerivedG::ColsAtCompileTime> MatrixXG;
   typedef Matrix<typename DerivedJ::Scalar,Dynamic,DerivedJ::ColsAtCompileTime> MatrixXJ;
   typedef Matrix<typename DerivedJ::Scalar,Dynamic,DerivedJ::ColsAtCompileTime> MatrixXJ;
-  typedef Matrix<typename DerivedN::Scalar,1,3> RowVector3N;
   const Index m = F.rows();
   const Index m = F.rows();
 
 
   // UNUSED:
   // UNUSED:
@@ -94,7 +91,7 @@ IGL_INLINE void igl::cgal::outer_hull(
 
 
   std::vector<std::vector<typename DerivedF::Index> > uE2oE;
   std::vector<std::vector<typename DerivedF::Index> > uE2oE;
   std::vector<std::vector<bool> > uE2C;
   std::vector<std::vector<bool> > uE2C;
-  order_facets_around_edges(V, F, N, E, uE, EMAP, uE2E, uE2oE, uE2C);
+  order_facets_around_edges(V, F, E, uE, EMAP, uE2E, uE2oE, uE2C);
   uE2E = uE2oE;
   uE2E = uE2oE;
   VectorXI diIM(3*m);
   VectorXI diIM(3*m);
   for (auto ue : uE2E) {
   for (auto ue : uE2E) {
@@ -160,12 +157,12 @@ IGL_INLINE void igl::cgal::outer_hull(
 #ifdef IGL_OUTER_HULL_DEBUG
 #ifdef IGL_OUTER_HULL_DEBUG
   cout<<"outer facet..."<<endl;
   cout<<"outer facet..."<<endl;
 #endif
 #endif
-    outer_facet(V,F,N,IM,f,f_flip);
+  igl::cgal::outer_facet(V,F,IM,f,f_flip);
 #ifdef IGL_OUTER_HULL_DEBUG
 #ifdef IGL_OUTER_HULL_DEBUG
   cout<<"outer facet: "<<f<<endl;
   cout<<"outer facet: "<<f<<endl;
-  cout << V.row(F(f, 0)) << std::endl;
-  cout << V.row(F(f, 1)) << std::endl;
-  cout << V.row(F(f, 2)) << std::endl;
+  //cout << V.row(F(f, 0)) << std::endl;
+  //cout << V.row(F(f, 1)) << std::endl;
+  //cout << V.row(F(f, 2)) << std::endl;
 #endif
 #endif
     int FHcount = 1;
     int FHcount = 1;
     FH[f] = true;
     FH[f] = true;
@@ -209,9 +206,9 @@ IGL_INLINE void igl::cgal::outer_hull(
       // edge valence
       // edge valence
       const size_t val = uE2E[EMAP(e)].size();
       const size_t val = uE2E[EMAP(e)].size();
 #ifdef IGL_OUTER_HULL_DEBUG
 #ifdef IGL_OUTER_HULL_DEBUG
-      std::cout << "vd: " << V.row(fd) << std::endl;
-      std::cout << "vs: " << V.row(fs) << std::endl;
-      std::cout << "edge: " << V.row(fd) - V.row(fs) << std::endl;
+      //std::cout << "vd: " << V.row(fd) << std::endl;
+      //std::cout << "vs: " << V.row(fs) << std::endl;
+      //std::cout << "edge: " << V.row(fd) - V.row(fs) << std::endl;
       for (size_t i=0; i<val; i++) {
       for (size_t i=0; i<val; i++) {
           if (i == diIM(e)) {
           if (i == diIM(e)) {
               std::cout << "* ";
               std::cout << "* ";
@@ -223,19 +220,6 @@ IGL_INLINE void igl::cgal::outer_hull(
               << uE2E[EMAP(e)][i] % m * (uE2C[EMAP(e)][i] ? 1:-1) << ")" << std::endl;
               << uE2E[EMAP(e)][i] % m * (uE2C[EMAP(e)][i] ? 1:-1) << ")" << std::endl;
       }
       }
 #endif
 #endif
-      //// find overlapping face-edges
-      //const auto & neighbors = uE2E[EMAP(e)];
-      //// normal after possible flipping
-      //const auto & fN = (flip(f)?-1.:1.)*N.row(f);
-      //// Edge vector according to f's (flipped) orientation.
-      ////const auto & eV = (V.row(fd)-V.row(fs)).normalized();
-
-//#warning "EXPERIMENTAL, DO NOT USE"
-      //// THIS IS WRONG! The first face is---after sorting---no longer the face
-      //// used for orienting the sort.
-      //const auto ui = EMAP(e);
-      //const auto fe0 = uE2E[ui][0];
-      //const auto es = F(fe0%m,((fe0/m)+1)%3);
 
 
       // is edge consistent with edge of face used for sorting
       // is edge consistent with edge of face used for sorting
       const int e_cons = (uE2C[EMAP(e)][diIM(e)] ? 1: -1);
       const int e_cons = (uE2C[EMAP(e)][diIM(e)] ? 1: -1);
@@ -245,11 +229,6 @@ IGL_INLINE void igl::cgal::outer_hull(
       {
       {
         const int nfei_new = (diIM(e) + 2*val + e_cons*step*(flip(f)?-1:1))%val;
         const int nfei_new = (diIM(e) + 2*val + e_cons*step*(flip(f)?-1:1))%val;
         const int nf = uE2E[EMAP(e)][nfei_new] % m;
         const int nf = uE2E[EMAP(e)][nfei_new] % m;
-        // Don't consider faces with identical dihedral angles
-        //if ((di[EMAP(e)][diIM(e)].array() != di[EMAP(e)][nfei_new].array()).any())
-        //if((di[EMAP(e)][diIM(e)] != di[EMAP(e)][nfei_new]))
-//#warning "THIS IS HACK, FIX ME"
-//        if( abs(di[EMAP(e)][diIM(e)] - di[EMAP(e)][nfei_new]) < 1e-15 )
         {
         {
 #ifdef IGL_OUTER_HULL_DEBUG
 #ifdef IGL_OUTER_HULL_DEBUG
         //cout<<"Next facet: "<<(f+1)<<" --> "<<(nf+1)<<", |"<<
         //cout<<"Next facet: "<<(f+1)<<" --> "<<(nf+1)<<", |"<<
@@ -281,64 +260,6 @@ IGL_INLINE void igl::cgal::outer_hull(
       }
       }
 
 
       int max_ne = -1;
       int max_ne = -1;
-      //// Loop over and find max dihedral angle
-      //typename DerivedV::Scalar max_di = -1;
-      //for(const auto & ne : neighbors)
-      //{
-      //  const int nf = ne%m;
-      //  if(nf == f)
-      //  {
-      //    continue;
-      //  }
-      //  // Corner of neighbor
-      //  const int nc = ne/m;
-      //  // Is neighbor oriented consistently with (flipped) f?
-      //  //const int ns = F(nf,(nc+1)%3);
-      //  const int nd = F(nf,(nc+2)%3);
-      //  const bool cons = (flip(f)?fd:fs) == nd;
-      //  // Normal after possibly flipping to match flip or orientation of f
-      //  const auto & nN = (cons? (flip(f)?-1:1.) : (flip(f)?1.:-1.) )*N.row(nf);
-      //  // Angle between n and f
-      //  const auto & ndi = M_PI - atan2( fN.cross(nN).dot(eV), fN.dot(nN));
-      //  if(ndi>=max_di)
-      //  {
-      //    max_ne = ne;
-      //    max_di = ndi;
-      //  }
-      //}
-
-      ////cout<<(max_ne != max_ne_2)<<" =?= "<<e_cons<<endl;
-      //if(max_ne != max_ne_2)
-      //{
-      //  cout<<(f+1)<<" ---> "<<(max_ne%m)+1<<" != "<<(max_ne_2%m)+1<<" ... "<<e_cons<<" "<<flip(f)<<endl;
-      //  typename DerivedV::Scalar max_di = -1;
-      //  for(size_t nei = 0;nei<neighbors.size();nei++)
-      //  {
-      //    const auto & ne = neighbors[nei];
-      //    const int nf = ne%m;
-      //    if(nf == f)
-      //    {
-      //      cout<<"  "<<(ne%m)+1<<":\t"<<0<<"\t"<<di[EMAP[e]][nei]<<" "<<diIM(ne)<<endl;
-      //      continue;
-      //    }
-      //    // Corner of neighbor
-      //    const int nc = ne/m;
-      //    // Is neighbor oriented consistently with (flipped) f?
-      //    //const int ns = F(nf,(nc+1)%3);
-      //    const int nd = F(nf,(nc+2)%3);
-      //    const bool cons = (flip(f)?fd:fs) == nd;
-      //    // Normal after possibly flipping to match flip or orientation of f
-      //    const auto & nN = (cons? (flip(f)?-1:1.) : (flip(f)?1.:-1.) )*N.row(nf);
-      //    // Angle between n and f
-      //    const auto & ndi = M_PI - atan2( fN.cross(nN).dot(eV), fN.dot(nN));
-      //    cout<<"  "<<(ne%m)+1<<":\t"<<ndi<<"\t"<<di[EMAP[e]][nei]<<" "<<diIM(ne)<<endl;
-      //    if(ndi>=max_di)
-      //    {
-      //      max_ne = ne;
-      //      max_di = ndi;
-      //    }
-      //  }
-      //}
       if(nfei >= 0)
       if(nfei >= 0)
       {
       {
         max_ne = uE2E[EMAP(e)][nfei];
         max_ne = uE2E[EMAP(e)][nfei];
@@ -513,33 +434,9 @@ IGL_INLINE void igl::cgal::outer_hull(
   }
   }
 }
 }
 
 
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename DerivedG,
-  typename DerivedJ,
-  typename Derivedflip>
-IGL_INLINE void igl::cgal::outer_hull(
-  const Eigen::PlainObjectBase<DerivedV> & V,
-  const Eigen::PlainObjectBase<DerivedF> & F,
-  Eigen::PlainObjectBase<DerivedG> & G,
-  Eigen::PlainObjectBase<DerivedJ> & J,
-  Eigen::PlainObjectBase<Derivedflip> & flip)
-{
-  Eigen::Matrix<typename DerivedV::Scalar,DerivedF::RowsAtCompileTime,3> N;
-  per_face_normals_stable(V,F,N);
-  return outer_hull(V,F,N,G,J,flip);
-}
-
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // Explicit template specialization
-#undef IGL_STATIC_LIBRARY
-#include <igl/barycenter.cpp>
-#include <igl/outer_facet.cpp>
-#include <igl/cgal/order_facets_around_edges.cpp>
-#define IGL_STATIC_LIBRARY
 template void igl::cgal::outer_hull<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
 template void igl::cgal::outer_hull<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
 template void igl::cgal::outer_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::cgal::outer_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
-template void igl::cgal::outer_hull<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
 #endif
 #endif

+ 0 - 15
include/igl/cgal/outer_hull.h

@@ -25,26 +25,11 @@ namespace igl
     // Inputs:
     // Inputs:
     //   V  #V by 3 list of vertex positions
     //   V  #V by 3 list of vertex positions
     //   F  #F by 3 list of triangle indices into V
     //   F  #F by 3 list of triangle indices into V
-    //   N  #F by 3 list of per-face normals
     // Outputs:
     // Outputs:
     //   G  #G by 3 list of output triangle indices into V
     //   G  #G by 3 list of output triangle indices into V
     //   J  #G list of indices into F
     //   J  #G list of indices into F
     //   flip  #F list of whether facet was added to G **and** flipped orientation
     //   flip  #F list of whether facet was added to G **and** flipped orientation
     //     (false for faces not added to G)
     //     (false for faces not added to G)
-    template <
-      typename DerivedV,
-      typename DerivedF,
-      typename DerivedN,
-      typename DerivedG,
-      typename DerivedJ,
-      typename Derivedflip>
-    IGL_INLINE void outer_hull(
-      const Eigen::PlainObjectBase<DerivedV> & V,
-      const Eigen::PlainObjectBase<DerivedF> & F,
-      const Eigen::PlainObjectBase<DerivedN> & N,
-      Eigen::PlainObjectBase<DerivedG> & G,
-      Eigen::PlainObjectBase<DerivedJ> & J,
-      Eigen::PlainObjectBase<Derivedflip> & flip);
     template <
     template <
       typename DerivedV,
       typename DerivedV,
       typename DerivedF,
       typename DerivedF,

+ 18 - 38
include/igl/cgal/peel_outer_hull_layers.cpp

@@ -6,7 +6,6 @@
 // v. 2.0. If a copy of the MPL was not distributed with this file, You can 
 // 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/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "peel_outer_hull_layers.h"
 #include "peel_outer_hull_layers.h"
-#include "../per_face_normals.h"
 #include "outer_hull.h"
 #include "outer_hull.h"
 #include <vector>
 #include <vector>
 #include <iostream>
 #include <iostream>
@@ -17,25 +16,21 @@
 #include "../STR.h"
 #include "../STR.h"
 #endif
 #endif
 
 
-using namespace std;
 template <
 template <
   typename DerivedV,
   typename DerivedV,
   typename DerivedF,
   typename DerivedF,
-  typename DerivedN,
-  typename Derivedodd,
+  typename DerivedI,
   typename Derivedflip>
   typename Derivedflip>
 IGL_INLINE size_t igl::cgal::peel_outer_hull_layers(
 IGL_INLINE size_t igl::cgal::peel_outer_hull_layers(
   const Eigen::PlainObjectBase<DerivedV > & V,
   const Eigen::PlainObjectBase<DerivedV > & V,
   const Eigen::PlainObjectBase<DerivedF > & F,
   const Eigen::PlainObjectBase<DerivedF > & F,
-  const Eigen::PlainObjectBase<DerivedN > & N,
-  Eigen::PlainObjectBase<Derivedodd > & odd,
+  Eigen::PlainObjectBase<DerivedI> & I,
   Eigen::PlainObjectBase<Derivedflip > & flip)
   Eigen::PlainObjectBase<Derivedflip > & flip)
 {
 {
   using namespace Eigen;
   using namespace Eigen;
   using namespace std;
   using namespace std;
   typedef typename DerivedF::Index Index;
   typedef typename DerivedF::Index Index;
   typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
   typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
-  typedef Matrix<typename DerivedN::Scalar,Dynamic,DerivedN::ColsAtCompileTime> MatrixXN;
   typedef Matrix<Index,Dynamic,1> MatrixXI;
   typedef Matrix<Index,Dynamic,1> MatrixXI;
   typedef Matrix<typename Derivedflip::Scalar,Dynamic,Derivedflip::ColsAtCompileTime> MatrixXflip;
   typedef Matrix<typename Derivedflip::Scalar,Dynamic,Derivedflip::ColsAtCompileTime> MatrixXflip;
   const Index m = F.rows();
   const Index m = F.rows();
@@ -52,13 +47,11 @@ IGL_INLINE size_t igl::cgal::peel_outer_hull_layers(
 #endif
 #endif
   // keep track of iteration parity and whether flipped in hull
   // keep track of iteration parity and whether flipped in hull
   MatrixXF Fr = F;
   MatrixXF Fr = F;
-  MatrixXN Nr = N;
-  odd.resize(m,1);
+  I.resize(m,1);
   flip.resize(m,1);
   flip.resize(m,1);
   // Keep track of index map
   // Keep track of index map
   MatrixXI IM = MatrixXI::LinSpaced(m,0,m-1);
   MatrixXI IM = MatrixXI::LinSpaced(m,0,m-1);
   // This is O(n * layers)
   // This is O(n * layers)
-  bool odd_iter = true;
   MatrixXI P(m,1);
   MatrixXI P(m,1);
   Index iter = 0;
   Index iter = 0;
   while(Fr.size() > 0)
   while(Fr.size() > 0)
@@ -69,21 +62,30 @@ IGL_INLINE size_t igl::cgal::peel_outer_hull_layers(
     MatrixXI Jo;
     MatrixXI Jo;
     MatrixXflip flipr;
     MatrixXflip flipr;
 #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
 #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
-  cout<<"calling outer hull..."<<endl;
-  writePLY(STR("outer-hull-input-"<<iter<<".ply"),V,Fr);
-  writeDMAT(STR("outer-hull-input-"<<iter<<".dmat"),Nr);
+  {
+      cout<<"calling outer hull..." << iter <<endl;
+      std::stringstream ss;
+      ss << "outer_hull_" << iter << ".ply";
+      Eigen::MatrixXd vertices(V.rows(), V.cols());
+      std::transform(V.data(), V.data() + V.rows()*V.cols(),
+              vertices.data(),
+              [](typename DerivedV::Scalar val)
+              {return CGAL::to_double(val); });
+      writePLY(ss.str(), vertices, Fr);
+  }
 #endif
 #endif
-    outer_hull(V,Fr,Nr,Fo,Jo,flipr);
+    outer_hull(V,Fr,Fo,Jo,flipr);
 #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
 #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
   writePLY(STR("outer-hull-output-"<<iter<<".ply"),V,Fo);
   writePLY(STR("outer-hull-output-"<<iter<<".ply"),V,Fo);
   cout<<"reindex, flip..."<<endl;
   cout<<"reindex, flip..."<<endl;
 #endif
 #endif
+    assert(Fo.rows() != 0);
     assert(Fo.rows() == Jo.rows());
     assert(Fo.rows() == Jo.rows());
     // all faces in Fo of Fr
     // all faces in Fo of Fr
     vector<bool> in_outer(Fr.rows(),false);
     vector<bool> in_outer(Fr.rows(),false);
     for(Index g = 0;g<Jo.rows();g++)
     for(Index g = 0;g<Jo.rows();g++)
     {
     {
-      odd(IM(Jo(g))) = odd_iter;
+      I(IM(Jo(g))) = iter;
       P(IM(Jo(g))) = iter;
       P(IM(Jo(g))) = iter;
       in_outer[Jo(g)] = true;
       in_outer[Jo(g)] = true;
       flip(IM(Jo(g))) = flipr(Jo(g));
       flip(IM(Jo(g))) = flipr(Jo(g));
@@ -91,10 +93,8 @@ IGL_INLINE size_t igl::cgal::peel_outer_hull_layers(
     // Fr = Fr - Fo
     // Fr = Fr - Fo
     // update IM
     // update IM
     MatrixXF prev_Fr = Fr;
     MatrixXF prev_Fr = Fr;
-    MatrixXN prev_Nr = Nr;
     MatrixXI prev_IM = IM;
     MatrixXI prev_IM = IM;
     Fr.resize(prev_Fr.rows() - Fo.rows(),F.cols());
     Fr.resize(prev_Fr.rows() - Fo.rows(),F.cols());
-    Nr.resize(Fr.rows(),3);
     IM.resize(Fr.rows());
     IM.resize(Fr.rows());
     {
     {
       Index g = 0;
       Index g = 0;
@@ -103,37 +103,17 @@ IGL_INLINE size_t igl::cgal::peel_outer_hull_layers(
         if(!in_outer[f])
         if(!in_outer[f])
         {
         {
           Fr.row(g) = prev_Fr.row(f);
           Fr.row(g) = prev_Fr.row(f);
-          Nr.row(g) = prev_Nr.row(f);
           IM(g) = prev_IM(f);
           IM(g) = prev_IM(f);
           g++;
           g++;
         }
         }
       }
       }
     }
     }
-    odd_iter = !odd_iter;
     iter++;
     iter++;
   }
   }
   return iter;
   return iter;
 }
 }
 
 
-template <
-  typename DerivedV,
-  typename DerivedF,
-  typename Derivedodd,
-  typename Derivedflip>
-IGL_INLINE size_t igl::cgal::peel_outer_hull_layers(
-  const Eigen::PlainObjectBase<DerivedV > & V,
-  const Eigen::PlainObjectBase<DerivedF > & F,
-  Eigen::PlainObjectBase<Derivedodd > & odd,
-  Eigen::PlainObjectBase<Derivedflip > & flip)
-{
-  Eigen::Matrix<typename DerivedV::Scalar,DerivedF::RowsAtCompileTime,3> N;
-  per_face_normals(V,F,N);
-  return peel_outer_hull_layers(V,F,N,odd,flip);
-}
-
-
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // Explicit template specialization
-template size_t igl::cgal::peel_outer_hull_layers<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
-template size_t igl::cgal::peel_outer_hull_layers<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
+template size_t igl::cgal::peel_outer_hull_layers<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif
 #endif

+ 3 - 17
include/igl/cgal/peel_outer_hull_layers.h

@@ -20,34 +20,20 @@ namespace igl
     // Inputs:
     // Inputs:
     //   V  #V by 3 list of vertex positions
     //   V  #V by 3 list of vertex positions
     //   F  #F by 3 list of triangle indices into V
     //   F  #F by 3 list of triangle indices into V
-    //   N  #F by 3 list of per-face normals
     // Outputs:
     // Outputs:
-    //   odd  #F list of whether facet belongs to an odd iteration peel (otherwise
-    //     an even iteration peel)
+    //   I  #F list of which peel Iation a facet belongs 
     //   flip  #F list of whether a facet's orientation was flipped when facet
     //   flip  #F list of whether a facet's orientation was flipped when facet
     //     "peeled" into its associated outer hull layer.
     //     "peeled" into its associated outer hull layer.
     // Returns number of peels
     // Returns number of peels
     template <
     template <
       typename DerivedV,
       typename DerivedV,
       typename DerivedF,
       typename DerivedF,
-      typename DerivedN,
-      typename Derivedodd,
+      typename DerivedI,
       typename Derivedflip>
       typename Derivedflip>
     IGL_INLINE size_t peel_outer_hull_layers(
     IGL_INLINE size_t peel_outer_hull_layers(
       const Eigen::PlainObjectBase<DerivedV > & V,
       const Eigen::PlainObjectBase<DerivedV > & V,
       const Eigen::PlainObjectBase<DerivedF > & F,
       const Eigen::PlainObjectBase<DerivedF > & F,
-      const Eigen::PlainObjectBase<DerivedN > & N,
-      Eigen::PlainObjectBase<Derivedodd > & odd,
-      Eigen::PlainObjectBase<Derivedflip > & flip);
-    template <
-      typename DerivedV,
-      typename DerivedF,
-      typename Derivedodd,
-      typename Derivedflip>
-    IGL_INLINE size_t peel_outer_hull_layers(
-      const Eigen::PlainObjectBase<DerivedV > & V,
-      const Eigen::PlainObjectBase<DerivedF > & F,
-      Eigen::PlainObjectBase<Derivedodd > & odd,
+      Eigen::PlainObjectBase<DerivedI > & I,
       Eigen::PlainObjectBase<Derivedflip > & flip);
       Eigen::PlainObjectBase<Derivedflip > & flip);
   }
   }
 }
 }

+ 1 - 1
include/igl/cgal/polyhedron_to_mesh.cpp

@@ -57,7 +57,7 @@ IGL_INLINE void igl::cgal::polyhedron_to_mesh(
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-// Explicit template instanciation
+// Explicit template specialization
 #include <CGAL/Simple_cartesian.h>
 #include <CGAL/Simple_cartesian.h>
 #include <CGAL/Polyhedron_items_with_id_3.h>
 #include <CGAL/Polyhedron_items_with_id_3.h>
 template void igl::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::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>&);

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

@@ -0,0 +1,96 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "projected_delaunay.h"
+#include "../REDRUM.h"
+#include <iostream>
+#include <cassert>
+
+template <typename Kernel>
+IGL_INLINE void igl::cgal::projected_delaunay(
+  const CGAL::Triangle_3<Kernel> & A,
+  const std::vector<CGAL::Object> & A_objects_3,
+  CGAL::Constrained_triangulation_plus_2<
+    CGAL::Constrained_Delaunay_triangulation_2<
+      Kernel,
+      CGAL::Triangulation_data_structure_2<
+        CGAL::Triangulation_vertex_base_2<Kernel>,
+        CGAL::Constrained_triangulation_face_base_2<Kernel> >,
+      CGAL::Exact_intersections_tag> > & cdt)
+{
+  using namespace std;
+  // 3D Primitives
+  typedef CGAL::Point_3<Kernel>    Point_3;
+  typedef CGAL::Segment_3<Kernel>  Segment_3; 
+  typedef CGAL::Triangle_3<Kernel> Triangle_3; 
+  typedef CGAL::Plane_3<Kernel>    Plane_3;
+  typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3; 
+  typedef CGAL::Point_2<Kernel>    Point_2;
+  typedef CGAL::Segment_2<Kernel>  Segment_2; 
+  typedef CGAL::Triangle_2<Kernel> Triangle_2; 
+  typedef CGAL::Triangulation_vertex_base_2<Kernel>  TVB_2;
+  typedef CGAL::Constrained_triangulation_face_base_2<Kernel> CTFB_2;
+  typedef CGAL::Triangulation_data_structure_2<TVB_2,CTFB_2> TDS_2;
+  typedef CGAL::Exact_intersections_tag Itag;
+  typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS_2,Itag> 
+    CDT_2;
+  typedef CGAL::Constrained_triangulation_plus_2<CDT_2> CDT_plus_2;
+
+  // http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Triangulation_2/Chapter_main.html#Section_2D_Triangulations_Constrained_Plus
+  // Plane of triangle A
+  Plane_3 P(A.vertex(0),A.vertex(1),A.vertex(2));
+  // Insert triangle into vertices
+  typename CDT_plus_2::Vertex_handle corners[3];
+  typedef size_t Index;
+  for(Index i = 0;i<3;i++)
+  {
+    const Point_3 & p3 = A.vertex(i);
+    const Point_2 & p2 = P.to_2d(p3);
+    typename CDT_plus_2::Vertex_handle corner = cdt.insert(p2);
+    corners[i] = corner;
+  }
+  // Insert triangle edges as constraints
+  for(Index i = 0;i<3;i++)
+  {
+    cdt.insert_constraint( corners[(i+1)%3], corners[(i+2)%3]);
+  }
+  // Insert constraints for intersection objects
+  for( const auto & obj : A_objects_3)
+  {
+    if(const Segment_3 *iseg = CGAL::object_cast<Segment_3 >(&obj))
+    {
+      // Add segment constraint
+      cdt.insert_constraint(P.to_2d(iseg->vertex(0)),P.to_2d(iseg->vertex(1)));
+    }else if(const Point_3 *ipoint = CGAL::object_cast<Point_3 >(&obj))
+    {
+      // Add point
+      cdt.insert(P.to_2d(*ipoint));
+    } else if(const Triangle_3 *itri = CGAL::object_cast<Triangle_3 >(&obj))
+    {
+      // Add 3 segment constraints
+      cdt.insert_constraint(P.to_2d(itri->vertex(0)),P.to_2d(itri->vertex(1)));
+      cdt.insert_constraint(P.to_2d(itri->vertex(1)),P.to_2d(itri->vertex(2)));
+      cdt.insert_constraint(P.to_2d(itri->vertex(2)),P.to_2d(itri->vertex(0)));
+    } else if(const std::vector<Point_3 > *polyp = 
+        CGAL::object_cast< std::vector<Point_3 > >(&obj))
+    {
+      //cerr<<REDRUM("Poly...")<<endl;
+      const std::vector<Point_3 > & poly = *polyp;
+      const Index m = poly.size();
+      assert(m>=2);
+      for(Index p = 0;p<m;p++)
+      {
+        const Index np = (p+1)%m;
+        cdt.insert_constraint(P.to_2d(poly[p]),P.to_2d(poly[np]));
+      }
+    }else
+    {
+      cerr<<REDRUM("What is this object?!")<<endl;
+      assert(false);
+    }
+  }
+}

+ 43 - 0
include/igl/cgal/projected_delaunay.h

@@ -0,0 +1,43 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_CGAL_PROJECTED_DELAUNAY_H
+#define IGL_CGAL_PROJECTED_DELAUNAY_H
+#include "../igl_inline.h"
+#include "CGAL_includes.hpp"
+namespace igl
+{
+  namespace cgal
+  {
+    // Compute 2D delaunay triangulation of a given 3d triangle and a list of
+    // intersection objects (points,segments,triangles). CGAL uses an affine
+    // projection rather than an isometric projection, so we're not guaranteed
+    // that the 2D delaunay triangulation here will be a delaunay triangulation
+    // in 3D.
+    //
+    // Inputs:
+    //   A  triangle in 3D
+    //   A_objects_3  updated list of intersection objects for A
+    // Outputs:
+    //   cdt  Contrained delaunay triangulation in projected 2D plane
+    template <typename Kernel>
+    IGL_INLINE void projected_delaunay(
+      const CGAL::Triangle_3<Kernel> & A,
+      const std::vector<CGAL::Object> & A_objects_3,
+      CGAL::Constrained_triangulation_plus_2<
+        CGAL::Constrained_Delaunay_triangulation_2<
+          Kernel,
+          CGAL::Triangulation_data_structure_2<
+            CGAL::Triangulation_vertex_base_2<Kernel>,
+            CGAL::Constrained_triangulation_face_base_2<Kernel> >,
+          CGAL::Exact_intersections_tag> > & cdt);
+  }
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "projected_delaunay.cpp"
+#endif
+#endif

+ 306 - 0
include/igl/cgal/remesh_intersections.cpp

@@ -0,0 +1,306 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#include "remesh_intersections.h"
+#include "SelfIntersectMesh.h"
+#include "assign_scalar.h"
+#include "projected_delaunay.h"
+#include <iostream>
+#include <cassert>
+
+template <
+  typename DerivedV,
+  typename DerivedF,
+  typename Kernel,
+  typename DerivedVV,
+  typename DerivedFF,
+  typename DerivedJ,
+  typename DerivedIM>
+IGL_INLINE void igl::cgal::remesh_intersections(
+  const Eigen::PlainObjectBase<DerivedV> & V,
+  const Eigen::PlainObjectBase<DerivedF> & F,
+  const std::vector<CGAL::Triangle_3<Kernel> > & T,
+  const std::map<
+    typename DerivedF::Index,
+    std::pair<typename DerivedF::Index,
+      std::vector<CGAL::Object> > > & offending,
+  const std::map<
+    std::pair<typename DerivedF::Index,typename DerivedF::Index>,
+    std::vector<typename DerivedF::Index> > & edge2faces,
+  Eigen::PlainObjectBase<DerivedVV> & VV,
+  Eigen::PlainObjectBase<DerivedFF> & FF,
+  Eigen::PlainObjectBase<DerivedJ> & J,
+  Eigen::PlainObjectBase<DerivedIM> & IM)
+{
+  using namespace std;
+  using namespace Eigen;
+  typedef typename DerivedF::Index          Index;
+  typedef CGAL::Point_3<Kernel>    Point_3;
+  typedef CGAL::Segment_3<Kernel>  Segment_3; 
+  typedef CGAL::Triangle_3<Kernel> Triangle_3; 
+  typedef CGAL::Plane_3<Kernel>    Plane_3;
+  typedef CGAL::Point_2<Kernel>    Point_2;
+  typedef CGAL::Segment_2<Kernel>  Segment_2; 
+  typedef CGAL::Triangle_2<Kernel> Triangle_2; 
+  typedef CGAL::Triangulation_vertex_base_2<Kernel>  TVB_2;
+  typedef CGAL::Constrained_triangulation_face_base_2<Kernel> CTFB_2;
+  typedef CGAL::Triangulation_data_structure_2<TVB_2,CTFB_2> TDS_2;
+  typedef CGAL::Exact_intersections_tag Itag;
+  typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,TDS_2,Itag> 
+    CDT_2;
+  typedef CGAL::Constrained_triangulation_plus_2<CDT_2> CDT_plus_2;
+  typedef std::pair<Index,Index> EMK;
+  typedef std::vector<Index> EMV;
+  typedef std::map<EMK,EMV> EdgeMap;
+  typedef std::pair<Index,Index> EMK;
+  typedef std::vector<CGAL::Object> ObjectList;
+  typedef std::vector<Index> IndexList;
+
+  int NF_count = 0;
+  // list of new faces, we'll fix F later
+  vector<
+    typename Eigen::Matrix<typename DerivedFF::Scalar,Dynamic,Dynamic>
+    > NF(offending.size());
+  // list of new vertices
+  typedef vector<Point_3> Point_3List;
+  Point_3List NV;
+  Index NV_count = 0;
+  vector<CDT_plus_2> cdt(offending.size());
+  vector<Plane_3> P(offending.size());
+  // Use map for *all* faces
+  map<typename CDT_plus_2::Vertex_handle,Index> v2i;
+  // Loop over offending triangles
+  const size_t noff = offending.size();
+#ifdef IGL_SELFINTERSECTMESH_DEBUG
+  double t_proj_del = 0;
+#endif
+  // Unfortunately it looks like CGAL has trouble allocating memory when
+  // multiple openmp threads are running. Crashes durring CDT...
+//# pragma omp parallel for if (noff>1000)
+  for(const auto & okv : offending)
+  {
+    // index in F
+    const Index f = okv.first;
+    const Index o = okv.second.first;
+    {
+#ifdef IGL_SELFINTERSECTMESH_DEBUG
+      const double t_before = get_seconds();
+#endif
+      CDT_plus_2 cdt_o;
+      projected_delaunay(T[f],okv.second.second,cdt_o);
+      cdt[o] = cdt_o;
+#ifdef IGL_SELFINTERSECTMESH_DEBUG
+      t_proj_del += (get_seconds()-t_before);
+#endif
+    }
+    // Q: Is this also delaunay in 3D?
+    // A: No, because the projection is affine and delaunay is not affine
+    // invariant.
+    // Q: Then, can't we first get the 2D delaunay triangulation, then lift it
+    // to 3D and flip any offending edges?
+    // Plane of projection (also used by projected_delaunay)
+    P[o] = Plane_3(T[f].vertex(0),T[f].vertex(1),T[f].vertex(2));
+    // Build index map
+    {
+      Index i=0;
+      for(
+        typename CDT_plus_2::Finite_vertices_iterator vit = cdt[o].finite_vertices_begin();
+        vit != cdt[o].finite_vertices_end();
+        ++vit)
+      {
+        if(i<3)
+        {
+          //cout<<T[f].vertex(i)<<
+          //  (T[f].vertex(i) == P[o].to_3d(vit->point())?" == ":" != ")<<
+          //  P[o].to_3d(vit->point())<<endl;
+#ifndef NDEBUG
+          // I want to be sure that the original corners really show up as the
+          // original corners of the CDT. I.e. I don't trust CGAL to maintain
+          // the order
+          assert(T[f].vertex(i) == P[o].to_3d(vit->point()));
+#endif
+          // For first three, use original index in F
+//#   pragma omp critical
+          v2i[vit] = F(f,i);
+        }else
+        {
+          const Point_3 vit_point_3 = P[o].to_3d(vit->point());
+          // First look up each edge's neighbors to see if exact point has
+          // already been added (This makes everything a bit quadratic)
+          bool found = false;
+          for(int e = 0; e<3 && !found;e++)
+          {
+            // Index of F's eth edge in V
+            Index i = F(f,(e+1)%3);
+            Index j = F(f,(e+2)%3);
+            // Be sure that i<j
+            if(i>j)
+            {
+              swap(i,j);
+            }
+            assert(edge2faces.count(EMK(i,j))==1);
+            const EMV & facesij = edge2faces.find(EMK(i,j))->second;
+            // loop over neighbors
+            for(
+              typename IndexList::const_iterator nit = facesij.begin();
+              nit != facesij.end() && !found;
+              nit++)
+            {
+              // don't consider self
+              if(*nit == f)
+              {
+                continue;
+              }
+              // index of neighbor in offending (to find its cdt)
+              assert(offending.count(*nit) == 1);
+              Index no = offending.find(*nit)->second.first;
+              // Loop over vertices of that neighbor's cdt (might not have been
+              // processed yet, but then it's OK because it'll just be empty)
+              for(
+                  typename CDT_plus_2::Finite_vertices_iterator uit = cdt[no].finite_vertices_begin();
+                  uit != cdt[no].finite_vertices_end() && !found;
+                  ++uit)
+              {
+                if(vit_point_3 == P[no].to_3d(uit->point()))
+                {
+                  assert(v2i.count(uit) == 1);
+//#   pragma omp critical
+                  v2i[vit] = v2i[uit];
+                  found = true;
+                }
+              }
+            }
+          }
+          if(!found)
+          {
+//#   pragma omp critical
+            {
+              v2i[vit] = V.rows()+NV_count;
+              NV.push_back(vit_point_3);
+              NV_count++;
+            }
+          }
+        }
+        i++;
+      }
+    }
+    {
+      Index i = 0;
+      // Resize to fit new number of triangles
+      NF[o].resize(cdt[o].number_of_faces(),3);
+//#   pragma omp atomic
+      NF_count+=NF[o].rows();
+      // Append new faces to NF
+      for(
+        typename CDT_plus_2::Finite_faces_iterator fit = cdt[o].finite_faces_begin();
+        fit != cdt[o].finite_faces_end();
+        ++fit)
+      {
+        NF[o](i,0) = v2i[fit->vertex(0)];
+        NF[o](i,1) = v2i[fit->vertex(1)];
+        NF[o](i,2) = v2i[fit->vertex(2)];
+        i++;
+      }
+    }
+  }
+#ifdef IGL_SELFINTERSECTMESH_DEBUG
+  cout<<"CDT: "<<tictoc()<<"  "<<t_proj_del<<endl;
+#endif
+
+  assert(NV_count == (Index)NV.size());
+  // Build output
+#ifndef NDEBUG
+  //{
+  //  Index off_count = 0;
+  //  for(Index f = 0;f<F.rows();f++)
+  //  {
+  //    off_count+= (offensive[f]?1:0);
+  //  }
+  //  assert(off_count==(Index)offending.size());
+  //}
+#endif
+  // Append faces
+  FF.resize(F.rows()-offending.size()+NF_count,3);
+  J.resize(FF.rows());
+  // First append non-offending original faces
+  // There's an Eigen way to do this in one line but I forget
+  Index off = 0;
+  for(Index f = 0;f<F.rows();f++)
+  {
+    if(!offending.count(f))
+    {
+      FF.row(off) = F.row(f);
+      J(off) = f;
+      off++;
+    }
+  }
+  assert(off == (Index)(F.rows()-offending.size()));
+  // Now append replacement faces for offending faces
+  for(const auto & okv : offending)
+  {
+    // index in F
+    const Index f = okv.first;
+    const Index o = okv.second.first;
+    FF.block(off,0,NF[o].rows(),3) = NF[o];
+    J.block(off,0,NF[o].rows(),1).setConstant(f);
+    off += NF[o].rows();
+  }
+  // Append vertices
+  VV.resize(V.rows()+NV_count,3);
+  VV.block(0,0,V.rows(),3) = V.template cast<typename DerivedVV::Scalar>();
+  {
+    Index i = 0;
+    for(
+      typename Point_3List::const_iterator nvit = NV.begin();
+      nvit != NV.end();
+      nvit++)
+    {
+      for(Index d = 0;d<3;d++)
+      {
+        const Point_3 & p = *nvit;
+        // Don't convert via double if output type is same as Kernel
+        assign_scalar(p[d], VV(V.rows()+i,d));
+      }
+      i++;
+    }
+  }
+  IM.resize(VV.rows(),1);
+  map<Point_3,Index> vv2i;
+  // Safe to check for duplicates using double for original vertices: if
+  // incoming reps are different then the points are unique.
+  for(Index v = 0;v<V.rows();v++)
+  {
+    const Point_3 p(V(v,0),V(v,1),V(v,2));
+    if(vv2i.count(p)==0)
+    {
+      vv2i[p] = v;
+    }
+    assert(vv2i.count(p) == 1);
+    IM(v) = vv2i[p];
+  }
+  // Must check for duplicates of new vertices using exact.
+  {
+    Index v = V.rows();
+    for(
+      typename Point_3List::const_iterator nvit = NV.begin();
+      nvit != NV.end();
+      nvit++)
+    {
+      const Point_3 & p = *nvit;
+      if(vv2i.count(p)==0)
+      {
+        vv2i[p] = v;
+      }
+      assert(vv2i.count(p) == 1);
+      IM(v) = vv2i[p];
+      v++;
+    }
+  }
+#ifdef IGL_SELFINTERSECTMESH_DEBUG
+  cout<<"Output + dupes: "<<tictoc()<<endl;
+#endif
+}

+ 77 - 0
include/igl/cgal/remesh_intersections.h

@@ -0,0 +1,77 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_CGAL_REMESH_INTERSECTIONS_H
+#define IGL_CGAL_REMESH_INTERSECTIONS_H
+#include <igl/igl_inline.h>
+
+#include <Eigen/Dense>
+#include "CGAL_includes.hpp"
+
+#ifdef MEX
+#  include <mex.h>
+#  include <cassert>
+#  undef assert
+#  define assert( isOK ) ( (isOK) ? (void)0 : (void) mexErrMsgTxt(C_STR(__FILE__<<":"<<__LINE__<<": failed assertion `"<<#isOK<<"'"<<std::endl) ) )
+#endif
+  
+namespace igl
+{
+  namespace cgal
+  {
+    // Remesh faces according to results of intersection detection and
+    // construction (e.g. from `igl::cgal::intersect_other` or
+    // `igl::cgal::SelfIntersectMesh`)
+    //
+    // Inputs:
+    //   V  #V by 3 list of vertex positions
+    //   F  #F by 3 list of triangle indices into V
+    //   T  #F list of cgal triangles
+    //   offending #offending map taking face indices into F to pairs of order
+    //     of first finding and list of intersection objects from all
+    //     intersections
+    //   edge2faces  #edges <= #offending*3 to incident offending faces 
+    // Outputs:
+    //   VV  #VV by 3 list of vertex positions
+    //   FF  #FF by 3 list of triangle indices into V
+    //   IF  #intersecting face pairs by 2  list of intersecting face pairs,
+    //     indexing F
+    //   J  #FF list of indices into F denoting birth triangle
+    //   IM  #VV list of indices into VV of unique vertices.
+    //
+    template <
+      typename DerivedV,
+      typename DerivedF,
+      typename Kernel,
+      typename DerivedVV,
+      typename DerivedFF,
+      typename DerivedJ,
+      typename DerivedIM>
+    IGL_INLINE void remesh_intersections(
+      const Eigen::PlainObjectBase<DerivedV> & V,
+      const Eigen::PlainObjectBase<DerivedF> & F,
+      const std::vector<CGAL::Triangle_3<Kernel> > & T,
+      const std::map<
+        typename DerivedF::Index,
+        std::pair<typename DerivedF::Index,
+          std::vector<CGAL::Object> > > & offending,
+      const std::map<
+        std::pair<typename DerivedF::Index,typename DerivedF::Index>,
+        std::vector<typename DerivedF::Index> > & edge2faces,
+      Eigen::PlainObjectBase<DerivedVV> & VV,
+      Eigen::PlainObjectBase<DerivedFF> & FF,
+      Eigen::PlainObjectBase<DerivedJ> & J,
+      Eigen::PlainObjectBase<DerivedIM> & IM);
+  }
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "remesh_intersections.cpp"
+#endif
+  
+#endif
+

+ 1 - 1
include/igl/cgal/remesh_self_intersections.h

@@ -37,7 +37,7 @@ namespace igl
     //   params  struct of optional parameters
     //   params  struct of optional parameters
     // Outputs:
     // Outputs:
     //   VV  #VV by 3 list of vertex positions
     //   VV  #VV by 3 list of vertex positions
-    //   FF  #FF by 3 list of triangle indices into V
+    //   FF  #FF by 3 list of triangle indices into VV
     //   IF  #intersecting face pairs by 2  list of intersecting face pairs,
     //   IF  #intersecting face pairs by 2  list of intersecting face pairs,
     //     indexing F
     //     indexing F
     //   J  #FF list of indices into F denoting birth triangle
     //   J  #FF list of indices into F denoting birth triangle

+ 1 - 0
include/igl/colon.cpp

@@ -51,4 +51,5 @@ template void igl::colon<int, int, long, int>(int, int, long, Eigen::Matrix<int,
 template void igl::colon<int, long, int>(int, long, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
 template void igl::colon<int, long, int>(int, long, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
 template void igl::colon<int, int, int>(int, int, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
 template void igl::colon<int, int, int>(int, int, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
 template void igl::colon<int,long long int,int>(int,long long int,Eigen::Matrix<int,-1,1,0,-1,1> &);
 template void igl::colon<int,long long int,int>(int,long long int,Eigen::Matrix<int,-1,1,0,-1,1> &);
+template void igl::colon<int, int, int, int>(int, int, int, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
 #endif
 #endif

+ 4 - 3
include/igl/comiso/miq.cpp

@@ -41,6 +41,7 @@
 #include <iostream>
 #include <iostream>
 #include <igl/matlab_format.h>
 #include <igl/matlab_format.h>
 
 
+#warning "using namespace *; in global scope **must** be removed"
 using namespace std;
 using namespace std;
 using namespace Eigen;
 using namespace Eigen;
 
 
@@ -1581,7 +1582,7 @@ IGL_INLINE void igl::comiso::miq(
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // Explicit template specialization
-template void igl::comiso::miq<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, double, double, bool, int, int, bool, bool, std::__1::vector<int, std::__1::allocator<int> >, std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >);
-template void igl::comiso::miq<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 3, 0, -1, 3> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::Matrix<int, -1, 3, 0, -1, 3> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, double, double, bool, int, int, bool, bool, std::__1::vector<int, std::__1::allocator<int> >, std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >);
-template void igl::comiso::miq<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > 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<int, -1, -1, 0, -1, -1> >&, double, double, bool, int, int, bool, bool, std::__1::vector<int, std::__1::allocator<int> >, std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >);
+template void igl::comiso::miq<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, double, double, bool, int, int, bool, bool, std::vector<int, std::allocator<int> >, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >);
+template void igl::comiso::miq<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 3, 0, -1, 3> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::Matrix<int, -1, 3, 0, -1, 3> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, double, double, bool, int, int, bool, bool, std::vector<int, std::allocator<int> >, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >);
+template void igl::comiso::miq<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > 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<int, -1, -1, 0, -1, -1> >&, double, double, bool, int, int, bool, bool, std::vector<int, std::allocator<int> >, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >);
 #endif
 #endif

+ 0 - 33
include/igl/compile_and_link_program.h

@@ -1,33 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_COMPILE_AND_LINK_PROGRAM_H
-#define IGL_COMPILE_AND_LINK_PROGRAM_H
-#include "igl_inline.h"
-#include "OpenGL_convenience.h"
-namespace igl
-{
-  #ifndef IGL_NO_OPENGL
-
-  // Compile and link very simple vertex/fragment shaders
-  //
-  // Inputs:
-  //   v_str  string of vertex shader contents
-  //   f_str  string of fragment shader contents
-  // Returns id of program
-  //
-  // Known bugs: this seems to duplicate `create_shader_program` with less
-  // functionality.
-  IGL_INLINE GLuint compile_and_link_program(
-    const char * v_str, const char * f_str);
-
-  #endif
-}
-#ifndef IGL_STATIC_LIBRARY
-#  include "compile_and_link_program.cpp"
-#endif
-#endif

+ 0 - 38
include/igl/compile_shader.h

@@ -1,38 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_COMPILE_SHADER_H
-#define IGL_COMPILE_SHADER_H
-#include "OpenGL_convenience.h"
-#include "igl_inline.h"
-namespace igl
-{
-  #ifndef IGL_NO_OPENGL
-  // Compile a shader given type and string of shader code
-  //
-  // Inputs:
-  //   type  either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
-  //   str  contents of shader code
-  // Returns result of glCreateShader (id of shader)
-  //
-  // Example:
-  //     GLuint vid = compile_shader(GL_VERTEX_SHADER,vertex_shader.c_str());
-  //     GLuint fid = compile_shader(GL_FRAGMENT_SHADER,fragment_shader.c_str());
-  //     GLuint prog_id = glCreateProgram();
-  //     glAttachShader(prog_id,vid);
-  //     glAttachShader(prog_id,fid);
-  //     glLinkProgram(prog_id);
-  //
-  // Known bugs: seems to be duplicate of `load_shader`
-  IGL_INLINE GLuint compile_shader(const GLint type, const char * str);
-  #endif
-
-}
-#ifndef IGL_STATIC_LIBRARY
-#  include "compile_shader.cpp"
-#endif
-#endif

+ 1 - 0
include/igl/components.cpp

@@ -88,4 +88,5 @@ IGL_INLINE void igl::components(
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // Explicit template specialization
 template void igl::components<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::components<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::components<int, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<int, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif
 #endif

+ 0 - 63
include/igl/create_mesh_vbo.h

@@ -1,63 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_CREATE_MESH_VBO_H
-#define IGL_CREATE_MESH_VBO_H
-#ifndef IGL_NO_OPENGL
-#include "igl_inline.h"
-// NOTE: It wouldn't be so hard to template this using Eigen's templates
-
-#include <Eigen/Core>
-
-#include "OpenGL_convenience.h"
-
-// Create a VBO (Vertex Buffer Object) for a mesh. Actually two VBOs: one 
-// GL_ARRAY_BUFFER for the vertex positions (V) and one
-// GL_ELEMENT_ARRAY_BUFFER for the triangle indices (F)
-namespace igl
-{
-
-  // Inputs:
-  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
-  //   F  #F by 3 eigne Matrix of face (triangle) indices
-  // Outputs:
-  //   V_vbo_id  buffer id for vertex positions
-  //   F_vbo_id  buffer id for face indices
-  //
-  // NOTE: when using glDrawElements VBOs for V and F using MatrixXd and
-  // MatrixXi will have types GL_DOUBLE and GL_UNSIGNED_INT respectively
-  //
-  IGL_INLINE void create_mesh_vbo(
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & F,
-    GLuint & V_vbo_id,
-    GLuint & F_vbo_id);
-
-  // Inputs:
-  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
-  //   F  #F by 3 eigne Matrix of face (triangle) indices
-  //   N  #V by 3 eigen Matrix of mesh vertex 3D normals
-  // Outputs:
-  //   V_vbo_id  buffer id for vertex positions
-  //   F_vbo_id  buffer id for face indices
-  //   N_vbo_id  buffer id for vertex positions
-  IGL_INLINE void create_mesh_vbo(
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & F,
-    const Eigen::MatrixXd & N,
-    GLuint & V_vbo_id,
-    GLuint & F_vbo_id,
-    GLuint & N_vbo_id);
-
-}
-
-#ifndef IGL_STATIC_LIBRARY
-#  include "create_mesh_vbo.cpp"
-#endif
-
-#endif
-#endif

+ 0 - 65
include/igl/create_shader_program.h

@@ -1,65 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_CREATE_SHADER_PROGRAM_H
-#define IGL_CREATE_SHADER_PROGRAM_H
-
-#ifndef IGL_NO_OPENGL
-#include "igl_inline.h"
-#include <string>
-#include <map>
-
-#include "OpenGL_convenience.h"
-
-namespace igl
-{
-  // Create a shader program with a vertex and fragments shader loading from
-  // source strings and vertex attributes assigned from a map before linking the
-  // shaders to the program, making it ready to use with glUseProgram(id)
-  // Inputs:
-  //   geom_source  string containing source code of geometry shader (can be
-  //     "" to mean use default pass-through)
-  //   vert_source  string containing source code of vertex shader
-  //   frag_source  string containing source code of fragment shader
-  //   attrib  map containing table of vertex attribute strings add their
-  //   correspondingly ids (generated previously using glBindAttribLocation)
-  // Outputs:
-  //   id  index id of created shader, set to 0 on error
-  // Returns true on success, false on error
-  //
-  // Note: Caller is responsible for making sure that current value of id is not
-  // leaking a shader (since it will be overwritten)
-  //
-  // See also: destroy_shader_program
-  IGL_INLINE bool create_shader_program(
-    const std::string &geom_source,
-    const std::string &vert_source,
-    const std::string &frag_source,
-    const std::map<std::string,GLuint> &attrib,
-    GLuint & id);
-  IGL_INLINE bool create_shader_program(
-    const std::string &vert_source,
-    const std::string &frag_source,
-    const std::map<std::string,GLuint> &attrib,
-    GLuint & id);
-  IGL_INLINE GLuint create_shader_program(
-    const std::string & geom_source,
-    const std::string & vert_source,
-    const std::string & frag_source,
-    const std::map<std::string,GLuint> &attrib);
-  IGL_INLINE GLuint create_shader_program(
-    const std::string & vert_source,
-    const std::string & frag_source,
-    const std::map<std::string,GLuint> &attrib);
-}
-
-#ifndef IGL_STATIC_LIBRARY
-#  include "create_shader_program.cpp"
-#endif
-
-#endif
-#endif

+ 1 - 2
include/igl/cut_mesh.cpp

@@ -317,7 +317,6 @@ IGL_INLINE void igl::cut_mesh(
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template specialization
 // Explicit template specialization
-template void igl::cut_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > > const&, std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::__1::vector<bool, std::__1::allocator<bool> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::cut_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<bool, std::allocator<bool> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<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> >&);
 template void igl::cut_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<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> >&);
 #endif
 #endif
-

+ 0 - 1
include/igl/cut_mesh.h

@@ -70,4 +70,3 @@ namespace igl {
 
 
 
 
 #endif /* defined(IGL_CUT_MESH) */
 #endif /* defined(IGL_CUT_MESH) */
-

+ 1 - 0
include/igl/cut_mesh_from_singularities.cpp

@@ -198,6 +198,7 @@ IGL_INLINE void igl::cut_mesh_from_singularities(const Eigen::PlainObjectBase<De
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<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<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<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<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
+template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
 template void igl::cut_mesh_from_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
 #endif
 #endif

+ 0 - 35
include/igl/destroy_shader_program.h

@@ -1,35 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_DESTROY_SHADER_PROGRAM_H
-#define IGL_DESTROY_SHADER_PROGRAM_H
-#ifndef IGL_NO_OPENGL
-#include "igl_inline.h"
-
-#include "OpenGL_convenience.h"
-
-namespace igl
-{
-  // Properly destroy a shader program. Detach and delete each of its shaders
-  // and delete it
-  // Inputs:
-  //   id  index id of created shader, set to 0 on error
-  // Returns true on success, false on error
-  // 
-  // Note: caller is responsible for making sure he doesn't foolishly continue
-  // to use id as if it still contains a program
-  // 
-  // See also: create_shader_program
-  IGL_INLINE bool destroy_shader_program(const GLuint id);
-}
-
-#ifndef IGL_STATIC_LIBRARY
-#  include "destroy_shader_program.cpp"
-#endif
-
-#endif
-#endif

+ 8 - 6
include/igl/diag.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "diag.h"
 #include "diag.h"
 
 
@@ -15,7 +15,7 @@
 
 
 template <typename T>
 template <typename T>
 IGL_INLINE void igl::diag(
 IGL_INLINE void igl::diag(
-  const Eigen::SparseMatrix<T>& X, 
+  const Eigen::SparseMatrix<T>& X,
   Eigen::SparseVector<T>& V)
   Eigen::SparseVector<T>& V)
 {
 {
   assert(false && "Just call X.diagonal().sparseView() directly");
   assert(false && "Just call X.diagonal().sparseView() directly");
@@ -42,7 +42,7 @@ IGL_INLINE void igl::diag(
 
 
 template <typename T,typename DerivedV>
 template <typename T,typename DerivedV>
 IGL_INLINE void igl::diag(
 IGL_INLINE void igl::diag(
-  const Eigen::SparseMatrix<T>& X, 
+  const Eigen::SparseMatrix<T>& X,
   Eigen::MatrixBase<DerivedV> & V)
   Eigen::MatrixBase<DerivedV> & V)
 {
 {
   assert(false && "Just call X.diagonal() directly");
   assert(false && "Just call X.diagonal() directly");
@@ -104,4 +104,6 @@ IGL_INLINE void igl::diag(
 // Explicit template specialization
 // Explicit template specialization
 template void igl::diag<double, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::diag<double, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::diag<double>(Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseVector<double, 0, int>&);
 template void igl::diag<double>(Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseVector<double, 0, int>&);
+template void igl::diag<double, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<double, 0, int>&);
+template void igl::diag<double>(Eigen::SparseVector<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int>&);
 #endif
 #endif

+ 64 - 0
include/igl/dijkstra.cpp

@@ -0,0 +1,64 @@
+#include <igl/dijkstra.h>
+
+template <typename IndexType, typename DerivedD, typename DerivedP>
+IGL_INLINE int igl::dijkstra_compute_paths(const IndexType &source,
+                                           const std::set<IndexType> &targets,
+                                           const std::vector<std::vector<IndexType> >& VV,
+                                           Eigen::PlainObjectBase<DerivedD> &min_distance,
+                                           Eigen::PlainObjectBase<DerivedP> &previous)
+{
+  int numV = VV.size();
+  min_distance.setConstant(numV, 1, std::numeric_limits<typename DerivedD::Scalar>::infinity());
+  min_distance[source] = 0;
+  previous.setConstant(numV, 1, -1);
+  std::set<std::pair<typename DerivedD::Scalar, IndexType> > vertex_queue;
+  vertex_queue.insert(std::make_pair(min_distance[source], source));
+
+  while (!vertex_queue.empty())
+  {
+    typename DerivedD::Scalar dist = vertex_queue.begin()->first;
+    IndexType u = vertex_queue.begin()->second;
+    vertex_queue.erase(vertex_queue.begin());
+
+    if (targets.find(u)!= targets.end())
+      return u;
+
+    // Visit each edge exiting u
+    const std::vector<int> &neighbors = VV[u];
+    for (std::vector<int>::const_iterator neighbor_iter = neighbors.begin();
+         neighbor_iter != neighbors.end();
+         neighbor_iter++)
+    {
+      IndexType v = *neighbor_iter;
+      typename DerivedD::Scalar distance_through_u = dist + 1.;
+      if (distance_through_u < min_distance[v]) {
+        vertex_queue.erase(std::make_pair(min_distance[v], v));
+
+        min_distance[v] = distance_through_u;
+        previous[v] = u;
+        vertex_queue.insert(std::make_pair(min_distance[v], v));
+
+      }
+
+    }
+  }
+  //we should never get here
+  return -1;
+}
+
+template <typename IndexType, typename DerivedP>
+IGL_INLINE void igl::dijkstra_get_shortest_path_to(const IndexType &vertex,
+                                                   const Eigen::PlainObjectBase<DerivedP> &previous,
+                                                   std::vector<IndexType> &path)
+{
+  IndexType source = vertex;
+  path.clear();
+  for ( ; source != -1; source = previous[source])
+    path.push_back(source);
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+template int igl::dijkstra_compute_paths<int, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(int const&, std::set<int, std::less<int>, std::allocator<int> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::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::dijkstra_get_shortest_path_to<int, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(int const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<int, std::allocator<int> >&);
+#endif

+ 60 - 0
include/igl/dijkstra.h

@@ -0,0 +1,60 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2015 Olga Diamanti <olga.diam@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_DIJKSTRA
+#define IGL_DIJKSTRA
+#include "igl_inline.h"
+
+#include <Eigen/Core>
+#include <vector>
+#include <set>
+
+namespace igl {
+
+  // Dijstra's algorithm for shortest paths, with multiple targets.
+  // Adapted from http://rosettacode.org/wiki/Dijkstra%27s_algorithm .
+  //
+  // Inputs:
+  //   source           index of source vertex
+  //   targets          target vector set
+  //   VV               #V list of lists of incident vertices (adjacency list), e.g.
+  //                    as returned by igl::adjacency_list
+  //
+  // Output:
+  //   min_distance     #V by 1 list of the minimum distances from source to all vertices
+  //   previous         #V by 1 list of the previous visited vertices (for each vertex) - used for backtracking
+  //
+  template <typename IndexType, typename DerivedD, typename DerivedP>
+  IGL_INLINE int dijkstra_compute_paths(const IndexType &source,
+                                        const std::set<IndexType> &targets,
+                                        const std::vector<std::vector<IndexType> >& VV,
+                                        Eigen::PlainObjectBase<DerivedD> &min_distance,
+                                        Eigen::PlainObjectBase<DerivedP> &previous);
+
+  // Backtracking after Dijstra's algorithm, to find shortest path.
+  //
+  // Inputs:
+  //   vertex           vertex to which we want the shortest path (from same source as above)
+  //   previous         #V by 1 list of the previous visited vertices (for each vertex) - result of Dijkstra's algorithm
+  //
+  // Output:
+  //   path             #P by 1 list of vertex indices in the shortest path from source to vertex
+  //
+  template <typename IndexType, typename DerivedP>
+  IGL_INLINE void dijkstra_get_shortest_path_to(const IndexType &vertex,
+                                                const Eigen::PlainObjectBase<DerivedP> &previous,
+                                                std::vector<IndexType> &path);
+};
+
+
+#ifndef IGL_STATIC_LIBRARY
+#include "dijkstra.cpp"
+#endif
+
+
+#endif /* defined(IGL_DIJKSTRA) */

+ 1 - 1
include/igl/directed_edge_orientations.cpp

@@ -24,6 +24,6 @@ IGL_INLINE void igl::directed_edge_orientations(
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-// Explicit template instanciation
+// Explicit template specialization
 template void igl::directed_edge_orientations<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&, std::vector<Eigen::Quaternion<double, 0>, Eigen::aligned_allocator<Eigen::Quaternion<double, 0> > >&);
 template void igl::directed_edge_orientations<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&, std::vector<Eigen::Quaternion<double, 0>, Eigen::aligned_allocator<Eigen::Quaternion<double, 0> > >&);
 #endif
 #endif

+ 1 - 1
include/igl/directed_edge_parents.cpp

@@ -29,6 +29,6 @@ IGL_INLINE void igl::directed_edge_parents(
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-// Explicit template instanciation
+// Explicit template specialization
 template void igl::directed_edge_parents<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::directed_edge_parents<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif
 #endif

+ 1 - 1
include/igl/dqs.cpp

@@ -69,6 +69,6 @@ IGL_INLINE void igl::dqs(
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-// Explicit template instanciation
+// Explicit template specialization
 template void igl::dqs<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Quaternion<double, 0>, Eigen::aligned_allocator<Eigen::Quaternion<double, 0> >, Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, std::vector<Eigen::Quaternion<double, 0>, Eigen::aligned_allocator<Eigen::Quaternion<double, 0> > > const&, std::vector<Eigen::Matrix<double, 3, 1, 0, 3, 1>, std::allocator<Eigen::Matrix<double, 3, 1, 0, 3, 1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::dqs<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Quaternion<double, 0>, Eigen::aligned_allocator<Eigen::Quaternion<double, 0> >, Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, std::vector<Eigen::Quaternion<double, 0>, Eigen::aligned_allocator<Eigen::Quaternion<double, 0> > > const&, std::vector<Eigen::Matrix<double, 3, 1, 0, 3, 1>, std::allocator<Eigen::Matrix<double, 3, 1, 0, 3, 1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif
 #endif

+ 0 - 58
include/igl/draw_floor.h

@@ -1,58 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_DRAW_FLOOR_H
-#define IGL_DRAW_FLOOR_H
-#ifndef IGL_NO_OPENGL
-#include "igl_inline.h"
-namespace igl
-{
-  // Draw a checkerboard floor aligned with current (X,Z) plane using OpenGL
-  // calls. side=50 centered at (0,0):
-  //   (-25,-25)-->(-25,25)-->(25,25)-->(25,-25)
-  //
-  // Use glPushMatrix(), glScaled(), glTranslated() to arrange the floor.
-  // 
-  // Inputs:
-  //   colorA  float4 color
-  //   colorB  float4 color
-  //
-  // Example:
-  //   // Draw a nice floor
-  //   glPushMatrix();
-  //   glCullFace(GL_BACK);
-  //   glEnable(GL_CULL_FACE);
-  //   glEnable(GL_LIGHTING);
-  //   glTranslated(0,-1,0);
-  //   if(project(Vector3d(0,0,0))(2) - project(Vector3d(0,1,0))(2) > -FLOAT_EPS)
-  //   {
-  //     draw_floor_outline();
-  //   }
-  //   draw_floor();
-  //   glPopMatrix();
-  //   glDisable(GL_CULL_FACE);
-  //
-  IGL_INLINE void draw_floor(
-    const float * colorA, 
-    const float * colorB, 
-    const int GridSizeX=100, 
-    const int GridSizeY=100);
-  // Wrapper with default colors
-  IGL_INLINE void draw_floor();
-  IGL_INLINE void draw_floor_outline(
-    const float * colorA, 
-    const float * colorB, 
-    const int GridSizeX=100, 
-    const int GridSizeY=100);
-  // Wrapper with default colors
-  IGL_INLINE void draw_floor_outline();
-}
-#ifndef IGL_STATIC_LIBRARY
-#  include "draw_floor.cpp"
-#endif
-#endif
-#endif

+ 0 - 121
include/igl/draw_mesh.h

@@ -1,121 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_DRAW_MESH_H
-#define IGL_DRAW_MESH_H
-#ifndef IGL_NO_OPENGL
-#include "igl_inline.h"
-
-#include <Eigen/Dense>
-
-#include "OpenGL_convenience.h"
-
-namespace igl
-{
-  // Draw OpenGL commands needed to display a mesh with normals
-  //
-  // Inputs:
-  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
-  //   F  #F by 3|4 eigen Matrix of face (triangle/quad) indices
-  //   N  #V|#F by 3 eigen Matrix of 3D normals
-  IGL_INLINE void draw_mesh(
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & F,
-    const Eigen::MatrixXd & N);
-  
-  // Draw OpenGL commands needed to display a mesh with normals and per-vertex
-  // colors
-  //
-  // Inputs:
-  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
-  //   F  #F by 3|4 eigen Matrix of face (triangle/quad) indices
-  //   N  #V|#F by 3 eigen Matrix of 3D normals
-  //   C  #V|#F|1 by 3 eigen Matrix of RGB colors
-  IGL_INLINE void draw_mesh(
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & F,
-    const Eigen::MatrixXd & N,
-    const Eigen::MatrixXd & C);
-  // Inputs:
-  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
-  //   F  #F by 3|4 eigen Matrix of face (triangle/quad) indices
-  //   N  #V|#F by 3 eigen Matrix of 3D normals
-  //   C  #V|#F|1 by 3 eigen Matrix of RGB colors
-  //   TC  #V|#F|1 by 3 eigen Matrix of Texture Coordinates
-  IGL_INLINE void draw_mesh(
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & F,
-    const Eigen::MatrixXd & N,
-    const Eigen::MatrixXd & C,
-    const Eigen::MatrixXd & TC);
-  
-  // Draw OpenGL commands needed to display a mesh with normals, per-vertex
-  // colors and LBS weights
-  //
-  // Inputs:
-  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
-  //   F  #F by 3|4 eigen Matrix of face (triangle/quad) indices
-  //   N  #V by 3 eigen Matrix of mesh vertex 3D normals
-  //   C  #V by 3 eigen Matrix of mesh vertex RGB colors
-  //   TC  #V by 3 eigen Matrix of mesh vertex UC coorindates between 0 and 1
-  //   W  #V by #H eigen Matrix of per mesh vertex, per handle weights
-  //   W_index  Specifies the index of the "weight" vertex attribute: see
-  //     glBindAttribLocation, if W_index is 0 then weights are ignored
-  //   WI  #V by #H eigen Matrix of per mesh vertex, per handle weight ids
-  //   WI_index  Specifies the index of the "weight" vertex attribute: see
-  //     glBindAttribLocation, if WI_index is 0 then weight indices are ignored
-  IGL_INLINE void draw_mesh(
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & F,
-    const Eigen::MatrixXd & N,
-    const Eigen::MatrixXd & C,
-    const Eigen::MatrixXd & TC,
-    const Eigen::MatrixXd & W,
-    const GLuint W_index,
-    const Eigen::MatrixXi & WI,
-    const GLuint WI_index);
-  
-  // Draw OpenGL commands needed to display a mesh with normals, per-vertex
-  // colors and LBS weights
-  //
-  // Inputs:
-  //   V  #V by 3 eigen Matrix of mesh vertex 3D positions
-  //   F  #F by 3|4 eigen Matrix of face (triangle/quad) indices
-  //   N  #V by 3 eigen Matrix of mesh vertex 3D normals
-  //   NF  #F by 3 eigen Matrix of face (triangle/quad) normal indices, <0
-  //     means no normal
-  //   C  #V by 3 eigen Matrix of mesh vertex RGB colors
-  //   TC  #V by 3 eigen Matrix of mesh vertex UC coorindates between 0 and 1
-  //   TF  #F by 3 eigen Matrix of face (triangle/quad) texture indices, <0
-  //     means no texture
-  //   W  #V by #H eigen Matrix of per mesh vertex, per handle weights
-  //   W_index  Specifies the index of the "weight" vertex attribute: see
-  //     glBindAttribLocation, if W_index is 0 then weights are ignored
-  //   WI  #V by #H eigen Matrix of per mesh vertex, per handle weight ids
-  //   WI_index  Specifies the index of the "weight" vertex attribute: see
-  //     glBindAttribLocation, if WI_index is 0 then weight indices are ignored
-  IGL_INLINE void draw_mesh(
-    const Eigen::MatrixXd & V,
-    const Eigen::MatrixXi & F,
-    const Eigen::MatrixXd & N,
-    const Eigen::MatrixXi & NF,
-    const Eigen::MatrixXd & C,
-    const Eigen::MatrixXd & TC,
-    const Eigen::MatrixXi & TF,
-    const Eigen::MatrixXd & W,
-    const GLuint W_index,
-    const Eigen::MatrixXi & WI,
-    const GLuint WI_index);
-
-}
-
-#ifndef IGL_STATIC_LIBRARY
-#  include "draw_mesh.cpp"
-#endif
-
-#endif
-#endif

+ 0 - 45
include/igl/draw_point.h

@@ -1,45 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_DRAW_POINT_H
-#define IGL_DRAW_POINT_H
-#ifndef IGL_NO_OPENGL
-#include "igl_inline.h"
-#include <Eigen/Core>
-namespace igl
-{
-  //double POINT_COLOR[3] = {239./255.,213./255.,46./255.};
-  // Draw a nice looking, colored dot at a given point in 3d.
-  //
-  // Note: expects that GL_CURRENT_COLOR is set with the desired foreground color
-  // 
-  // Inputs:
-  //   x  x-coordinate of point, modelview coordinates
-  //   y  y-coordinate of point, modelview coordinates
-  //   z  z-coordinate of point, modelview coordinates
-  //   requested_r  outer-most radius of dot {7}, measured in screen space pixels
-  //   selected  fills inner circle with black {false}
-  // Asserts that requested_r does not exceed 0.5*GL_POINT_SIZE_MAX
-  IGL_INLINE void draw_point(
-    const double x,
-    const double y,
-    const double z,
-    const double requested_r = 7,
-    const bool selected = false);
-  template <typename DerivedP>
-  IGL_INLINE void draw_point(
-    const Eigen::PlainObjectBase<DerivedP> & P,
-    const double requested_r = 7,
-    const bool selected = false);
-}
-
-#ifndef IGL_STATIC_LIBRARY
-#  include "draw_point.cpp"
-#endif
-
-#endif
-#endif

+ 0 - 36
include/igl/draw_rectangular_marquee.h

@@ -1,36 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_DRAW_RECTANGULAR_MARQUEE_H
-#define IGL_DRAW_RECTANGULAR_MARQUEE_H
-#include "igl_inline.h"
-namespace igl
-{
-  #ifndef IGL_NO_OPENGL
-
-  // Draw a rectangular marquee (selection box) in screen space. This sets up
-  // screen space using current viewport.
-  //
-  // Inputs:
-  //   from_x  x coordinate of from point
-  //   from_y  y coordinate of from point
-  //   to_x  x coordinate of to point
-  //   to_y  y coordinate of to point
-  IGL_INLINE void draw_rectangular_marquee(
-    const int from_x,
-    const int from_y,
-    const int to_x,
-    const int to_y);
-
-    #endif
-}
-
-#ifndef IGL_STATIC_LIBRARY
-#  include "draw_rectangular_marquee.cpp"
-#endif
-
-#endif

+ 0 - 54
include/igl/draw_skeleton_3d.h

@@ -1,54 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_DRAW_SKELETON_3D_H
-#define IGL_DRAW_SKELETON_3D_H
-#include "igl_inline.h"
-#include "material_colors.h"
-#include <Eigen/Core>
-namespace igl
-{
-
-  #ifndef IGL_NO_OPENGL
-
-  // Draw a skeleton
-  //
-  // Inputs:
-  //   C  #C by dim List of joint rest positions
-  //   BE  #BE by 2 list of bone edge indices into C
-  //   T  #BE*(dim+1) by dim  matrix of stacked transposed bone transformations
-  //   color  #BE|1 by 4 list of color
-  //   half_bbd  half bounding box diagonal to determine scaling {1.0}
-  template <
-    typename DerivedC,
-    typename DerivedBE,
-    typename DerivedT,
-    typename Derivedcolor>
-  IGL_INLINE void draw_skeleton_3d(
-    const Eigen::PlainObjectBase<DerivedC> & C,
-    const Eigen::PlainObjectBase<DerivedBE> & BE,
-    const Eigen::PlainObjectBase<DerivedT> & T,
-    const Eigen::PlainObjectBase<Derivedcolor> & color,
-    const double half_bbd=0.5);
-  // Default color
-  template <typename DerivedC, typename DerivedBE, typename DerivedT>
-  IGL_INLINE void draw_skeleton_3d(
-    const Eigen::PlainObjectBase<DerivedC> & C,
-    const Eigen::PlainObjectBase<DerivedBE> & BE,
-    const Eigen::PlainObjectBase<DerivedT> & T);
-  template <typename DerivedC, typename DerivedBE>
-  IGL_INLINE void draw_skeleton_3d(
-    const Eigen::PlainObjectBase<DerivedC> & C,
-    const Eigen::PlainObjectBase<DerivedBE> & BE);
-};
-
-  #endif
-  
-#ifndef IGL_STATIC_LIBRARY
-#  include "draw_skeleton_3d.cpp"
-#endif
-#endif

+ 0 - 53
include/igl/draw_skeleton_vector_graphics.h

@@ -1,53 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla Public License
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can
-// obtain one at http://mozilla.org/MPL/2.0/.
-#ifndef IGL_DRAW_SKELETON_VECTOR_GRAPHICS_H
-#define IGL_DRAW_SKELETON_VECTOR_GRAPHICS_H
-#include "igl_inline.h"
-#include <Eigen/Core>
-
-namespace igl
-{
-  #ifndef IGL_NO_OPENGL
-
-  // Draw a skeleton with a 2D vector graphcis style à la BBW, STBS, Monotonic,
-  // FAST papers.
-  //
-  // Inputs:
-  //   C  #C by dim list of joint positions
-  //   BE #BE by 2 list of bone edge indices into C
-  //  point_color  color of points
-  //  line_color  color of lines
-  IGL_INLINE void draw_skeleton_vector_graphics(
-    const Eigen::MatrixXd & C,
-    const Eigen::MatrixXi & BE,
-    const float * point_color,
-    const float * line_color);
-  // Use default colors (originally from BBW paper)
-  IGL_INLINE void draw_skeleton_vector_graphics(
-    const Eigen::MatrixXd & C,
-    const Eigen::MatrixXi & BE);
-  //   T  #BE*(dim+1) by dim  matrix of stacked transposed bone transformations
-  template <typename DerivedC, typename DerivedBE, typename DerivedT>
-  IGL_INLINE void draw_skeleton_vector_graphics(
-    const Eigen::PlainObjectBase<DerivedC> & C,
-    const Eigen::PlainObjectBase<DerivedBE> & BE,
-    const Eigen::PlainObjectBase<DerivedT> & T,
-    const float * point_color,
-    const float * line_color);
-  template <typename DerivedC, typename DerivedBE, typename DerivedT>
-  IGL_INLINE void draw_skeleton_vector_graphics(
-    const Eigen::PlainObjectBase<DerivedC> & C,
-    const Eigen::PlainObjectBase<DerivedBE> & BE,
-    const Eigen::PlainObjectBase<DerivedT> & T);
-
-    #endif
-}
-#ifndef IGL_STATIC_LIBRARY
-#  include "draw_skeleton_vector_graphics.cpp"
-#endif
-#endif

+ 156 - 0
include/igl/eigs.cpp

@@ -0,0 +1,156 @@
+#include "eigs.h"
+
+#include "read_triangle_mesh.h"
+#include "cotmatrix.h"
+#include "sort.h"
+#include "slice.h"
+#include "massmatrix.h"
+#include <iostream>
+
+template <
+  typename Atype,
+  typename Btype,
+  typename DerivedU,
+  typename DerivedS>
+IGL_INLINE bool igl::eigs(
+  const Eigen::SparseMatrix<Atype> & A,
+  const Eigen::SparseMatrix<Btype> & iB,
+  const size_t k,
+  const EigsType type,
+  Eigen::PlainObjectBase<DerivedU> & sU,
+  Eigen::PlainObjectBase<DerivedS> & sS)
+{
+  using namespace Eigen;
+  using namespace std;
+  const size_t n = A.rows();
+  assert(A.cols() == n && "A should be square.");
+  assert(iB.rows() == n && "B should be match A's dims.");
+  assert(iB.cols() == n && "B should be square.");
+  assert(type == EIGS_TYPE_SM && "Only low frequencies are supported");
+  DerivedU U(n,k);
+  DerivedS S(k,1);
+  typedef Atype Scalar;
+  typedef Eigen::Matrix<typename DerivedU::Scalar,DerivedU::RowsAtCompileTime,1> VectorXS;
+  // Rescale B for better numerics
+  const Scalar rescale = std::abs(iB.diagonal().maxCoeff());
+  const Eigen::SparseMatrix<Btype> B = iB/rescale;
+
+  Scalar tol = 1e-4;
+  Scalar conv = 1e-14;
+  int max_iter = 100;
+  int i = 0;
+  while(true)
+  {
+    // Random initial guess
+    VectorXS y = VectorXS::Random(n,1);
+    Scalar eff_sigma = 0;
+    if(i>0)
+    {
+      eff_sigma = 1e-8+std::abs(S(i-1));
+    }
+    // whether to use rayleigh quotient method
+    bool ray = false;
+    Scalar err = std::numeric_limits<Scalar>::infinity();
+    int iter;
+    Scalar sigma = std::numeric_limits<Scalar>::infinity();
+    VectorXS x;
+    for(iter = 0;iter<max_iter;iter++)
+    {
+      if(i>0 && !ray)
+      {
+        // project-out existing modes
+        for(int j = 0;j<i;j++)
+        {
+          const VectorXS u = U.col(j);
+          y = (y - u*u.dot(B*y)/u.dot(B * u)).eval();
+        }
+      }
+      // normalize
+      x = y/sqrt(y.dot(B*y));
+
+      // current guess at eigen value
+      sigma = x.dot(A*x)/x.dot(B*x);
+      //x *= sigma>0?1.:-1.;
+
+      Scalar err_prev = err;
+      err = (A*x-sigma*B*x).array().abs().maxCoeff();
+      if(err<conv)
+      {
+        break;
+      }
+      if(ray || err<tol)
+      {
+        eff_sigma = sigma;
+        ray = true;
+      }
+
+      Scalar tikhonov = std::abs(eff_sigma)<1e-12?1e-10:0;
+      switch(type)
+      {
+        default:
+          assert(false && "Not supported");
+          break;
+        case EIGS_TYPE_SM:
+        {
+          SimplicialLDLT<SparseMatrix<Scalar> > solver;
+          const SparseMatrix<Scalar> C = A-eff_sigma*B+tikhonov*B;
+          //mw.save(C,"C");
+          //mw.save(eff_sigma,"eff_sigma");
+          //mw.save(tikhonov,"tikhonov");
+          solver.compute(C);
+          switch(solver.info())
+          {
+            case Eigen::Success:
+              break;
+            case Eigen::NumericalIssue:
+              cerr<<"Error: Numerical issue."<<endl;
+              return false;
+            default:
+              cerr<<"Error: Other."<<endl;
+              return false;
+          }
+          const VectorXS rhs = B*x;
+          y = solver.solve(rhs);
+          //mw.save(rhs,"rhs");
+          //mw.save(y,"y");
+          //mw.save(x,"x");
+          //mw.write("eigs.mat");
+          //if(i == 1)
+          //return false;
+          break;
+        }
+      }
+    }
+    if(iter == max_iter)
+    {
+      cerr<<"Failed to converge."<<endl;
+      return false;
+    }
+    if(i==0 || (S.head(i).array()-sigma).abs().maxCoeff()>1e-14)
+    {
+      U.col(i) = x;
+      S(i) = sigma;
+      i++;
+      if(i == k)
+      {
+        break;
+      }
+    }else
+    {
+      // restart with new random guess.
+      cout<<"RESTART!"<<endl;
+    }
+  }
+  // finally sort
+  VectorXi I;
+  igl::sort(S,1,false,sS,I);
+  sU = igl::slice(U,I,2);
+  sS /= rescale;
+  sU /= sqrt(rescale);
+  return true;
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template specialization
+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> >&);
+#endif

+ 54 - 0
include/igl/eigs.h

@@ -0,0 +1,54 @@
+#ifndef IGL_EIGS_H
+#define IGL_EIGS_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <Eigen/Sparse>
+
+namespace igl
+{
+  // Act like MATLAB's eigs function. Compute the first/last k eigen pairs of
+  // the generalized eigen value problem:
+  //
+  //     A u = s B u
+  //
+  // Solutions are approximate and sorted. 
+  //
+  // Ideally one should use ARPACK and the Eigen unsupported ARPACK module.
+  // This implementation does simple, naive power iterations.
+  //
+  // Inputs:
+  //   A  #A by #A symmetric matrix
+  //   B  #A by #A symmetric positive-definite matrix
+  //   k  number of eigen pairs to compute
+  // Outputs:
+  //   sU  #A by k list of sorted eigen vectors (descending)
+  //   sS  k list of sorted eigen values (descending)
+  //
+  // Known issues:
+  //   - only one pair per eigen value is found (no multiples)
+  //   - only the 'sm' small magnitude eigen values are well supported
+  //   
+  enum EigsType
+  {
+    EIGS_TYPE_SM = 0,
+    EIGS_TYPE_LM = 1,
+    NUM_EIGS_TYPES = 2
+  };
+  template <
+    typename Atype,
+    typename Btype,
+    typename DerivedU,
+    typename DerivedS>
+  IGL_INLINE bool eigs(
+    const Eigen::SparseMatrix<Atype> & A,
+    const Eigen::SparseMatrix<Btype> & B,
+    const size_t k,
+    const EigsType type,
+    Eigen::PlainObjectBase<DerivedU> & sU,
+    Eigen::PlainObjectBase<DerivedS> & sS);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#include "eigs.cpp"
+#endif
+#endif

+ 7 - 2
include/igl/embree/EmbreeIntersector.h

@@ -400,8 +400,10 @@ inline bool igl::embree::EmbreeIntersector::intersectBeam(
   else
   else
     bestHit.t = 0;
     bestHit.t = 0;
 
 
-  if(hasHit = (intersectRay(origin,direction,hit,tnear,tfar,mask) && (hit.gid == geoId || geoId == -1)))
+  if((intersectRay(origin,direction,hit,tnear,tfar,mask) && (hit.gid == geoId || geoId == -1)))
+  {
     bestHit = hit;
     bestHit = hit;
+  }
 
 
   // sample points around actual ray (conservative hitcheck)
   // sample points around actual ray (conservative hitcheck)
   const float eps= 1e-5;
   const float eps= 1e-5;
@@ -413,7 +415,10 @@ inline bool igl::embree::EmbreeIntersector::intersectBeam(
 
 
   for(int r=0;r<samples;r++)
   for(int r=0;r<samples;r++)
   {
   {
-    if(intersectRay(origin+offset*eps,direction,hit,tnear,tfar,mask) && ((closestHit && (hit.t < bestHit.t)) || (!closestHit && (hit.t > bestHit.t))) && (hit.gid == geoId || geoId == -1))
+    if(intersectRay(origin+offset*eps,direction,hit,tnear,tfar,mask) && 
+        ((closestHit && (hit.t < bestHit.t)) || 
+           (!closestHit && (hit.t > bestHit.t)))  &&
+        (hit.gid == geoId || geoId == -1))
     {
     {
       bestHit = hit;
       bestHit = hit;
       hasHit = true;
       hasHit = true;

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

@@ -77,7 +77,7 @@ IGL_INLINE void igl::embree::ambient_occlusion(
 }
 }
 
 
 #ifdef IGL_STATIC_LIBRARY
 #ifdef IGL_STATIC_LIBRARY
-// Explicit template instanciation
+// Explicit template specialization
 template void igl::embree::ambient_occlusion<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::embree::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template void igl::embree::ambient_occlusion<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::embree::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template void igl::embree::ambient_occlusion<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(igl::embree::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template void igl::embree::ambient_occlusion<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(igl::embree::EmbreeIntersector const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template void igl::embree::ambient_occlusion<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 template void igl::embree::ambient_occlusion<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);

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