Browse Source

Merge remote-tracking branch 'upstream/master'

Thomas Davies 5 years ago
parent
commit
9bc3ffd98f
100 changed files with 3055 additions and 962 deletions
  1. 0 39
      .appveyor.yml
  2. 17 0
      .github/ISSUE_TEMPLATE/bug_report.md
  3. 17 0
      .github/ISSUE_TEMPLATE/compilation.md
  4. 1 0
      .github/ISSUE_TEMPLATE/config.yml
  5. 17 0
      .github/ISSUE_TEMPLATE/feature_request.md
  6. 17 0
      .github/ISSUE_TEMPLATE/question.md
  7. 0 11
      .github/issue_template.md
  8. 3 1
      .github/pull_request_template.md
  9. 150 0
      .github/workflows/continuous.yml
  10. 190 0
      .github/workflows/nightly.yml
  11. 1 0
      .gitignore
  12. 0 81
      .travis.yml
  13. 19 5
      CMakeLists.txt
  14. 5 5
      README.md
  15. 7 0
      cmake/FindMATLAB.cmake
  16. 1 0
      cmake/FindMOSEK.cmake
  17. 540 0
      cmake/HunterGate.cmake
  18. 17 8
      cmake/LibiglDownloadExternal.cmake
  19. 118 0
      cmake/LibiglFolders.cmake
  20. 8 4
      cmake/LibiglWindows.cmake
  21. 8 0
      cmake/libigl-cgal.yml
  22. 80 47
      cmake/libigl.cmake
  23. 27 44
      include/igl/AABB.cpp
  24. 10 6
      include/igl/HalfEdgeIterator.cpp
  25. 6 6
      include/igl/HalfEdgeIterator.h
  26. 7 6
      include/igl/MappingEnergyType.h
  27. 2 2
      include/igl/PI.h
  28. 9 13
      include/igl/SortableRow.h
  29. 2 2
      include/igl/active_set.cpp
  30. 1 1
      include/igl/active_set.h
  31. 0 26
      include/igl/all_edges.cpp
  32. 0 38
      include/igl/all_edges.h
  33. 16 14
      include/igl/ambient_occlusion.cpp
  34. 10 10
      include/igl/ambient_occlusion.h
  35. 15 9
      include/igl/arap_linear_block.cpp
  36. 8 8
      include/igl/arap_linear_block.h
  37. 18 12
      include/igl/arap_rhs.cpp
  38. 10 9
      include/igl/arap_rhs.h
  39. 1 1
      include/igl/average_onto_faces.cpp
  40. 2 2
      include/igl/average_onto_vertices.cpp
  41. 9 9
      include/igl/average_onto_vertices.h
  42. 2 7
      include/igl/barycenter.cpp
  43. 42 0
      include/igl/barycentric_interpolation.cpp
  44. 42 0
      include/igl/barycentric_interpolation.h
  45. 0 44
      include/igl/barycentric_to_global.cpp
  46. 0 42
      include/igl/barycentric_to_global.h
  47. 74 0
      include/igl/bezier.cpp
  48. 51 0
      include/igl/bezier.h
  49. 2 2
      include/igl/bfs.cpp
  50. 1 1
      include/igl/bfs.h
  51. 7 7
      include/igl/bfs_orient.cpp
  52. 2 2
      include/igl/bfs_orient.h
  53. 31 27
      include/igl/biharmonic_coordinates.cpp
  54. 4 4
      include/igl/biharmonic_coordinates.h
  55. 8 8
      include/igl/bijective_composite_harmonic_mapping.cpp
  56. 71 0
      include/igl/blkdiag.cpp
  57. 40 0
      include/igl/blkdiag.h
  58. 364 0
      include/igl/blue_noise.cpp
  59. 49 0
      include/igl/blue_noise.h
  60. 2 2
      include/igl/bone_parents.cpp
  61. 1 1
      include/igl/bone_parents.h
  62. 3 3
      include/igl/boundary_loop.cpp
  63. 2 0
      include/igl/bounding_box.cpp
  64. 4 0
      include/igl/cat.cpp
  65. 1 0
      include/igl/cat.h
  66. 4 0
      include/igl/centroid.cpp
  67. 74 0
      include/igl/circulation.cpp
  68. 14 0
      include/igl/circulation.h
  69. 6 2
      include/igl/circumradius.cpp
  70. 3 3
      include/igl/circumradius.h
  71. 159 180
      include/igl/collapse_edge.cpp
  72. 42 97
      include/igl/collapse_edge.h
  73. 20 19
      include/igl/colon.cpp
  74. 267 4
      include/igl/colormap.cpp
  75. 6 5
      include/igl/colormap.h
  76. 14 14
      include/igl/comb_cross_field.cpp
  77. 4 4
      include/igl/comb_cross_field.h
  78. 8 8
      include/igl/comb_frame_field.cpp
  79. 6 6
      include/igl/comb_frame_field.h
  80. 9 9
      include/igl/comb_line_field.cpp
  81. 3 6
      include/igl/comb_line_field.h
  82. 2 1
      include/igl/combine.cpp
  83. 13 13
      include/igl/compute_frame_field_bisectors.cpp
  84. 10 10
      include/igl/compute_frame_field_bisectors.h
  85. 5 5
      include/igl/connect_boundary_to_infinity.cpp
  86. 4 4
      include/igl/connect_boundary_to_infinity.h
  87. 61 0
      include/igl/connected_components.cpp
  88. 35 0
      include/igl/connected_components.h
  89. 6 0
      include/igl/copyleft/cgal/assign.cpp
  90. 49 0
      include/igl/copyleft/cgal/coplanar.cpp
  91. 26 0
      include/igl/copyleft/cgal/coplanar.h
  92. 2 2
      include/igl/copyleft/cgal/extract_cells.cpp
  93. 2 0
      include/igl/copyleft/cgal/mesh_boolean.cpp
  94. 4 0
      include/igl/copyleft/cgal/mesh_to_cgal_triangle_list.cpp
  95. 2 0
      include/igl/copyleft/cgal/minkowski_sum.cpp
  96. 1 1
      include/igl/copyleft/cgal/orient2D.h
  97. 6 0
      include/igl/copyleft/cgal/remesh_intersections.cpp
  98. 3 0
      include/igl/copyleft/cgal/remesh_self_intersections.cpp
  99. 6 0
      include/igl/copyleft/cgal/resolve_intersections.cpp
  100. 7 0
      include/igl/copyleft/cgal/row_to_point.cpp

+ 0 - 39
.appveyor.yml

@@ -1,39 +0,0 @@
-version: 1.0.{build}
-os: Visual Studio 2017
-platform: x64
-clone_folder: C:\projects\libigl
-shallow_clone: true
-branches:
-  only:
-    - master
-    - dev
-environment:
-  matrix:
-  - CONFIG: Debug
-    BOOST_ROOT: C:/Libraries/boost_1_65_1
-    PYTHON: 37
-  - CONFIG: Release
-    BOOST_ROOT: C:/Libraries/boost_1_65_1
-    PYTHON: 37
-install:
-  - cinstall: python
-build:
-  parallel: true
-build_script:
-  - cd c:\projects\libigl
-  # Tutorials and tests
-  - set PATH=C:\Python%PYTHON%-x64;C:\Python%PYTHON%-x64\Scripts;%PATH%
-  - mkdir build
-  - cd build
-  - cmake -DCMAKE_BUILD_TYPE=%CONFIG%
-      -DLIBIGL_WITH_CGAL=ON
-      -DLIBIGL_WITH_COMISO=OFF
-      -G "Visual Studio 15 2017 Win64"
-      ../
-  - set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
-  - set MSBuildOptions=/v:m /m /p:BuildInParallel=true /p:Configuration=%CONFIG% /logger:%MSBuildLogger%
-  - msbuild %MSBuildOptions% libigl.sln
-
-test_script:
-  - set CTEST_OUTPUT_ON_FAILURE=1
-  - ctest -C %CONFIG% --verbose --output-on-failure -j 2

+ 17 - 0
.github/ISSUE_TEMPLATE/bug_report.md

@@ -0,0 +1,17 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: bug, pending verification
+assignees: ''
+
+---
+
+#### Describe the bug
+
+A clear and concise description of what the bug is.
+
+#### Check all that apply (change to `[x]`)
+- [ ] Windows
+- [ ] macOS
+- [ ] Linux

+ 17 - 0
.github/ISSUE_TEMPLATE/compilation.md

@@ -0,0 +1,17 @@
+---
+name: Compilation issue
+about: Report a problem when compiling the code
+title: ''
+labels: 'compilation'
+assignees: ''
+
+---
+
+#### Describe your question
+
+...
+
+#### Check all that apply (change to `[x]`)
+- [ ] Windows
+- [ ] macOS
+- [ ] Linux

+ 1 - 0
.github/ISSUE_TEMPLATE/config.yml

@@ -0,0 +1 @@
+blank_issues_enabled: false

+ 17 - 0
.github/ISSUE_TEMPLATE/feature_request.md

@@ -0,0 +1,17 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: 'enhancement'
+assignees: ''
+
+---
+
+#### Describe your feature request
+
+...
+
+#### Check all that apply (change to `[x]`)
+- [ ] Windows
+- [ ] macOS
+- [ ] Linux

+ 17 - 0
.github/ISSUE_TEMPLATE/question.md

@@ -0,0 +1,17 @@
+---
+name: Question
+about: Ask question about the tutorial or documentation
+title: ''
+labels: 'question'
+assignees: ''
+
+---
+
+#### Describe your question
+
+...
+
+#### Check all that apply (change to `[x]`)
+- [ ] Windows
+- [ ] macOS
+- [ ] Linux

+ 0 - 11
.github/issue_template.md

@@ -1,11 +0,0 @@
-#### Describe your issue
-
-...
-
-#### Check all that apply (change to `[x]`)
-- [ ] Windows
-- [ ] Mac OS X
-- [ ] Linux
-- [ ] I have tried the `dev` branch and the problem persists
-
-See https://libigl.github.io/CONTRIBUTING/#bugreport for more tips.

+ 3 - 1
.github/pull_request_template.md

@@ -1,8 +1,10 @@
+Fixes # .
+
 [Describe your changes and what you've already done to test it.]
 
+
 #### Check all that apply (change to `[x]`)
 - [ ] All changes meet [libigl style-guidelines](https://libigl.github.io/style-guidelines/).
 - [ ] Adds new .cpp file.
 - [ ] Adds corresponding unit test.
-- [ ] Adds corresponding python binding.
 - [ ] This is a minor change.

+ 150 - 0
.github/workflows/continuous.yml

@@ -0,0 +1,150 @@
+name: Build
+
+on:
+  push:
+    branches:
+      - master
+      - stable
+  pull_request:
+    branches:
+      - master
+      - stable
+
+env:
+  CTEST_OUTPUT_ON_FAILURE: ON
+  CTEST_PARALLEL_LEVEL: 2
+
+jobs:
+  ####################
+  # Linux / macOS
+  ####################
+
+  Unix:
+    name: ${{ matrix.name }} (${{ matrix.config }}, ${{ matrix.static }})
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-18.04, macos-latest]
+        config: [Release]
+        static: [ON, OFF]
+        include:
+          - os: macos-latest
+            name: macOS
+          - os: ubuntu-18.04
+            name: Linux
+    env:
+      LIBIGL_NUM_THREADS: 1  # See https://github.com/libigl/libigl/pull/996
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v1
+        with:
+          fetch-depth: 10
+
+      - name: Dependencies (Linux)
+        if: runner.os == 'Linux'
+        run: |
+            sudo apt-get update
+            sudo apt-get install \
+              libblas-dev \
+              libboost-filesystem-dev \
+              libboost-system-dev \
+              libboost-thread-dev \
+              libglu1-mesa-dev \
+              liblapack-dev \
+              libmpfr-dev \
+              xorg-dev \
+              ccache
+
+      - name: Dependencies (macOS)
+        if: runner.os == 'macOS'
+        run: brew install boost gmp mpfr ccache
+
+      - name: Cache Build
+        id: cache-build
+        uses: actions/cache@v1
+        with:
+          path: ~/.ccache
+          key: ${{ runner.os }}-${{ matrix.config }}-${{ matrix.static }}-cache
+
+      - name: Prepare ccache
+        run: |
+          ccache --max-size=1.0G
+          ccache -V && ccache --show-stats && ccache --zero-stats
+
+      - name: Configure
+        run: |
+          mkdir -p build
+          cd build
+          cmake .. \
+            -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
+            -DCMAKE_BUILD_TYPE=${{ matrix.config }} \
+            -DLIBIGL_USE_STATIC_LIBRARY=${{ matrix.static }} \
+            -DLIBIGL_WITH_CGAL=ON \
+            -DLIBIGL_WITH_COMISO=ON
+
+      - name: Build
+        run: cd build; make -j2; ccache --show-stats
+
+      - name: Tests
+        run: cd build; ctest --verbose
+
+  ####################
+  # Windows
+  ####################
+
+  Windows:
+    runs-on: windows-2019
+    env:
+      CC: cl.exe
+      CXX: cl.exe
+    strategy:
+      fail-fast: false
+      matrix:
+        config: [Release]
+        static: [ON, OFF]
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v1
+        with:
+          fetch-depth: 10
+      - uses: seanmiddleditch/gha-setup-ninja@master
+
+        # https://github.com/actions/cache/issues/101
+      - name: Set env
+        run: |
+          echo "::set-env name=appdata::$($env:LOCALAPPDATA)"
+          echo "::set-env name=BOOST_ROOT::$env:BOOST_ROOT_1_69_0"
+
+      - name: Cache build
+        id: cache-build
+        uses: actions/cache@v1
+        with:
+          path: ${{ env.appdata }}\Mozilla\sccache
+          key: ${{ runner.os }}-${{ matrix.config }}-${{ matrix.static }}-cache
+
+      - name: Prepare sccache
+        run: |
+          Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
+          scoop install sccache --global
+          # Scoop modifies the PATH so we make the modified PATH global.
+          echo "::set-env name=PATH::$env:PATH"
+
+        # We run configure + build in the same step, since they both need to call VsDevCmd
+        # Also, cmd uses ^ to break commands into multiple lines (in powershell this is `)
+      - name: Configure and build
+        shell: cmd
+        run: |
+          call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x64
+          cmake -G Ninja ^
+            -DCMAKE_CXX_COMPILER_LAUNCHER=sccache ^
+            -DCMAKE_BUILD_TYPE=${{ matrix.config }} ^
+            -DLIBIGL_USE_STATIC_LIBRARY=${{ matrix.static }} ^
+            -DLIBIGL_WITH_CGAL=ON ^
+            -DLIBIGL_WITH_COMISO=OFF ^
+            -B build ^
+            -S .
+          cmake --build build
+
+      - name: Tests
+        run: cd build; ctest --verbose

+ 190 - 0
.github/workflows/nightly.yml

@@ -0,0 +1,190 @@
+name: Nightly
+
+on:
+  schedule:
+    - cron:  '0 4 * * *'
+
+env:
+  CTEST_OUTPUT_ON_FAILURE: ON
+  CTEST_PARALLEL_LEVEL: 2
+
+jobs:
+  ####################
+  # Linux / macOS
+  ####################
+
+  # Part of this file is inspired from
+  # https://github.com/onqtam/doctest/blob/dev/.github/workflows/main.yml
+
+  Unix:
+    name: ${{ matrix.name }} (${{ matrix.config }}, Static=${{ matrix.static }})
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        name: [
+          ubuntu-18.04-gcc-7,
+          ubuntu-18.04-gcc-8,
+          ubuntu-18.04-gcc-9,
+          ubuntu-18.04-clang-7,
+          ubuntu-18.04-clang-8,
+          ubuntu-18.04-clang-9,
+          macOS-latest,
+        ]
+        config: [Debug, Release]
+        static: [ON, OFF]
+        include:
+          - name: ubuntu-18.04-gcc-7
+            os: ubuntu-18.04
+            compiler: gcc
+            version: "7"
+
+          - name: ubuntu-18.04-gcc-8
+            os: ubuntu-18.04
+            compiler: gcc
+            version: "8"
+
+          - name: ubuntu-18.04-gcc-9
+            os: ubuntu-18.04
+            compiler: gcc
+            version: "9"
+
+          - name: ubuntu-18.04-clang-7
+            os: ubuntu-18.04
+            compiler: clang
+            version: "7"
+
+          - name: ubuntu-18.04-clang-8
+            os: ubuntu-18.04
+            compiler: clang
+            version: "8"
+
+          - name: ubuntu-18.04-clang-9
+            os: ubuntu-18.04
+            compiler: clang
+            version: "9"
+
+          - name: macOS-latest
+            os: macOS-latest
+
+            # Build tutorials for most configurations
+          - tutorials: ON
+
+            # Except with Debug mode
+          - config: Debug
+            tutorials: OFF
+    env:
+      LIBIGL_NUM_THREADS: 1  # See https://github.com/libigl/libigl/pull/996
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v1
+        with:
+          fetch-depth: 10
+
+      - name: Dependencies (Linux)
+        if: runner.os == 'Linux'
+        run: |
+            # LLVM 9 is not in Bionic's repositories so we add the official LLVM repository.
+            if [ "${{ matrix.compiler }}" = "clang" ] && [ "${{ matrix.version }}" = "9" ]; then
+              sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main"
+            fi
+            sudo apt-get update
+
+            if [ "${{ matrix.compiler }}" = "gcc" ]; then
+              sudo apt-get install -y g++-${{ matrix.version }}
+              echo "::set-env name=CC::gcc-${{ matrix.version }}"
+              echo "::set-env name=CXX::g++-${{ matrix.version }}"
+            else
+              sudo apt-get install -y clang-${{ matrix.version }}
+              echo "::set-env name=CC::clang-${{ matrix.version }}"
+              echo "::set-env name=CXX::clang++-${{ matrix.version }}"
+            fi
+
+            sudo apt-get install \
+              libblas-dev \
+              libboost-filesystem-dev \
+              libboost-system-dev \
+              libboost-thread-dev \
+              libglu1-mesa-dev \
+              liblapack-dev \
+              libmpfr-dev \
+              xorg-dev
+
+      - name: Dependencies (macOS)
+        if: runner.os == 'macOS'
+        run: brew install boost gmp mpfr
+
+      - name: Configure
+        run: |
+          mkdir -p build
+          cd build
+          cmake .. \
+            -DCMAKE_BUILD_TYPE=${{ matrix.config }} \
+            -DLIBIGL_USE_STATIC_LIBRARY=${{ matrix.static }} \
+            -DLIBIGL_BUILD_TUTORIALS=${{ matrix.tutorials }} \
+            -DLIBIGL_WITH_CGAL=ON \
+            -DLIBIGL_WITH_COMISO=ON
+
+      - name: Free Disk Space
+        if: runner.os == 'Linux'
+        run: |
+            sudo swapoff -a
+            sudo apt clean
+            sudo rm -rf /swapfile /usr/share/dotnet /usr/local/lib/android /opt/ghc
+            df -h
+
+      - name: Build
+        run: cd build; make -j2
+
+      - name: Tests
+        run: cd build; ctest --verbose
+
+  ####################
+  # Windows
+  ####################
+
+  Windows:
+    name: Windows (${{ matrix.config }}, Static=${{ matrix.static }})
+    runs-on: windows-2019
+    env:
+      CC: cl.exe
+      CXX: cl.exe
+    strategy:
+      fail-fast: false
+      matrix:
+        config: [Debug, Release]
+        static: [ON, OFF]
+        include:
+          - config: Debug
+            tutorials: OFF
+          - config: Release
+            tutorials: ON
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v1
+        with:
+          fetch-depth: 10
+      - uses: seanmiddleditch/gha-setup-ninja@master
+
+      - name: Set env
+        run: |
+          echo "::set-env name=BOOST_ROOT::$env:BOOST_ROOT_1_69_0"
+
+        # We run configure + build in the same step, since they both need to call VsDevCmd
+        # Also, cmd uses ^ to break commands into multiple lines (in powershell this is `)
+      - name: Configure and build
+        shell: cmd
+        run: |
+          call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x64
+          cmake -G Ninja ^
+            -DCMAKE_BUILD_TYPE=${{ matrix.config }} ^
+            -DLIBIGL_USE_STATIC_LIBRARY=${{ matrix.static }} ^
+            -DLIBIGL_BUILD_TUTORIALS=${{ matrix.tutorials }} ^
+            -DLIBIGL_WITH_CGAL=ON ^
+            -DLIBIGL_WITH_COMISO=OFF ^
+            -B build ^
+            -S .
+          cmake --build build -j 2
+
+      - name: Tests
+        run: cd build; ctest --verbose

+ 1 - 0
.gitignore

@@ -97,3 +97,4 @@ tutorial/cmake-build-debug
 tutorial/data
 tutorial/readme.html
 untitled
+scripts

+ 0 - 81
.travis.yml

@@ -1,81 +0,0 @@
-dist: trusty
-sudo: true
-language: cpp
-cache: ccache
-addons:
-  apt:
-    sources:
-    - ubuntu-toolchain-r-test
-    packages:
-    - g++-7
-    - gcc-7
-    - libblas-dev
-    - libboost-filesystem-dev
-    - libboost-system-dev
-    - libboost-thread-dev
-    - libglu1-mesa-dev
-    - liblapack-dev
-    - libmpfr-dev
-    - libpython3-dev
-    - python3-setuptools
-    - xorg-dev
-  homebrew:
-    packages:
-    - ccache
-matrix:
-  include:
-  - os: linux
-    compiler: gcc # 4.8.4 by default on Trusty
-    env:
-    - MATRIX_EVAL="export CONFIG=Release PYTHON=python3"
-  - os: linux
-    compiler: gcc-7
-    env:
-    - MATRIX_EVAL="export CC=gcc-7 CXX=g++-7 CONFIG=Release PYTHON=python3"
-  - os: linux # same config like above but with -DLIBIGL_USE_STATIC_LIBRARY=OFF to test static and header-only builds
-    compiler: gcc-7
-    env:
-    - MATRIX_EVAL="export CC=gcc-7 CXX=g++-7 CONFIG=Release PYTHON=python3 CMAKE_EXTRA='-DLIBIGL_USE_STATIC_LIBRARY=OFF'"
-  - os: linux
-    compiler: gcc-7
-    env:
-    - MATRIX_EVAL="export CC=gcc-7 CXX=g++-7 CONFIG=Release PYTHON=python3 CMAKE_EXTRA='-DLIBIGL_EIGEN_VERSION=3.3.7'"
-  - os: osx
-    osx_image: xcode10.2
-    compiler: clang
-    env:
-    - MATRIX_EVAL="export CONFIG=Debug PYTHON=python3 LIBIGL_NUM_THREADS=1"
-  - os: osx # same config like above but with -DLIBIGL_USE_STATIC_LIBRARY=OFF to test static and header-only builds
-    osx_image: xcode10.2
-    compiler: clang
-    env:
-    - MATRIX_EVAL="export CONFIG=Debug PYTHON=python3 LIBIGL_NUM_THREADS=1 CMAKE_EXTRA='-DLIBIGL_USE_STATIC_LIBRARY=OFF'"
-  - os: osx
-    osx_image: xcode10.2
-    compiler: clang
-    env:
-    - MATRIX_EVAL="export CONFIG=Debug PYTHON=python3 LIBIGL_NUM_THREADS=1 CMAKE_EXTRA='-DLIBIGL_EIGEN_VERSION=3.3.7'""
-
-install:
-- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PATH="/usr/local/opt/ccache/libexec:$PATH"; fi
-- eval "${MATRIX_EVAL}"
-- ccache --max-size=5.0G
-- ccache -V && ccache --show-stats && ccache --zero-stats
-
-script:
-# Tutorials and tests
-- mkdir build
-- pushd build
-- cmake ${CMAKE_EXTRA}
-    -DCMAKE_BUILD_TYPE=$CONFIG
-    -DLIBIGL_CHECK_UNDEFINED=ON
-    -DLIBIGL_WITH_CGAL=ON
-    ../
-- make -j 2
-- ctest --verbose
-- popd
-- pushd python/tutorial
-- ${PYTHON} 101_FileIO.py
-- popd
-- rm -rf build
-- ccache --show-stats

+ 19 - 5
CMakeLists.txt

@@ -1,4 +1,14 @@
 cmake_minimum_required(VERSION 3.1)
+
+# Toggles the use of the hunter package manager
+option(HUNTER_ENABLED "Enable Hunter package manager support" OFF)
+
+include("cmake/HunterGate.cmake")
+HunterGate(
+	URL "https://github.com/ruslo/hunter/archive/v0.23.171.tar.gz"
+	SHA1 "5d68bcca78eee347239ca5f4d34f4b6c12683154"
+)
+
 project(libigl)
 
 # Detects whether this is a top-level project
@@ -9,10 +19,9 @@ else()
 	set(LIBIGL_TOPLEVEL_PROJECT OFF)
 endif()
 
-# Build tests, tutorials and python bindings
+# Build tests and tutorials
 option(LIBIGL_BUILD_TESTS      "Build libigl unit test"        ${LIBIGL_TOPLEVEL_PROJECT})
 option(LIBIGL_BUILD_TUTORIALS  "Build libigl tutorial"         ${LIBIGL_TOPLEVEL_PROJECT})
-option(LIBIGL_BUILD_PYTHON     "Build libigl python bindings"  ${LIBIGL_TOPLEVEL_PROJECT})
 option(LIBIGL_EXPORT_TARGETS   "Export libigl CMake targets"   ${LIBIGL_TOPLEVEL_PROJECT})
 
 # USE_STATIC_LIBRARY speeds up the generation of multiple binaries,
@@ -32,9 +41,13 @@ option(LIBIGL_WITH_TETGEN            "Use Tetgen"                   ON)
 option(LIBIGL_WITH_TRIANGLE          "Use Triangle"                 ON)
 option(LIBIGL_WITH_PREDICATES        "Use exact predicates"         ON)
 option(LIBIGL_WITH_XML               "Use XML"                      ON)
-option(LIBIGL_WITH_PYTHON            "Use Python"                   ${LIBIGL_BUILD_PYTHON})
+option(LIBIGL_WITH_PYTHON            "Use Python"                   OFF)
 ### End
 
+if(${LIBIGL_WITH_PYTHON})
+	message(FATAL_ERROR "Python binding are in the process of being redone. Please use the master branch or refer to https://github.com/geometryprocessing/libigl-python-bindings for the developement version or https://anaconda.org/conda-forge/igl for the stable version.")
+endif()
+
 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
@@ -55,6 +68,7 @@ if(LIBIGL_BUILD_TESTS)
 	add_subdirectory(tests)
 endif()
 
-if(LIBIGL_WITH_PYTHON)
-	add_subdirectory(python)
+if(LIBIGL_TOPLEVEL_PROJECT)
+	# Set folders for Visual Studio/Xcode
+	igl_set_folders()
 endif()

+ 5 - 5
README.md

@@ -1,8 +1,8 @@
 # libigl - A simple C++ geometry processing library
-[![Build Status](https://travis-ci.org/libigl/libigl.svg?branch=master)](https://travis-ci.org/libigl/libigl)
-[![Build status](https://ci.appveyor.com/api/projects/status/mf3t9rnhco0vhly8/branch/master?svg=true)](https://ci.appveyor.com/project/danielepanozzo/libigl-6hjk1/branch/master)
-![](https://github.com/libigl/libigl-legacy/raw/5ff6387765fa85ca46f1a6222728e35e2b8b8961/libigl-teaser.png)
+[![](https://github.com/libigl/libigl/workflows/Build/badge.svg?event=push)](https://github.com/libigl/libigl/actions?query=workflow%3ABuild+branch%3Amaster+event%3Apush)
+[![](https://github.com/libigl/libigl/workflows/Nightly/badge.svg)](https://github.com/libigl/libigl/actions?query=workflow%3ANightly+branch%3Amaster+event%3Aschedule)
+[![](https://anaconda.org/conda-forge/igl/badges/installer/conda.svg)](https://anaconda.org/conda-forge/igl)
 
-Documentation, tutorial, and instructions at <https://libigl.github.io>.
+![](https://libigl.github.io/libigl-teaser.png)
 
-:exclamation: **On October 15, 2018, a new, cleaned-up history was pushed onto the main libigl repository. To learn more about the consequences of this, and troubleshooting, please read [this page](https://libigl.github.io/rewritten-history/).**
+Documentation, tutorial, and instructions at <https://libigl.github.io>.

+ 7 - 0
cmake/FindMATLAB.cmake

@@ -224,7 +224,14 @@ if(NOT MATLAB_ADDITIONAL_VERSIONS)
   set(MATLAB_ADDITIONAL_VERSIONS)
 endif()
 
+# Is this mapping necessary? It's always causing trouble to need to bump these
+# for each new version.
 set(MATLAB_VERSIONS_MAPPING
+  "R2020b=9.9"
+  "R2020a=9.8"
+  "R2019b=9.7"
+  "R2019a=9.6"
+  "R2018b=9.5"
   "R2018a=9.4"
   "R2017b=9.3"
   "R2017a=9.2"

+ 1 - 0
cmake/FindMOSEK.cmake

@@ -9,6 +9,7 @@
 
 # Hardcoded search paths
 set(SEARCH_PATHS
+  ${CMAKE_SOURCE_DIR}/mosek/9.2/tools/platform/osx64x86/ 
   /usr/local/mosek/7/tools/platform/osx64x86/
   /usr/local/mosek/8/tools/platform/osx64x86/
   /opt/mosek/7/tools/platform/linux64x86/

+ 540 - 0
cmake/HunterGate.cmake

@@ -0,0 +1,540 @@
+# Copyright (c) 2013-2018, Ruslan Baratov
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This is a gate file to Hunter package manager.
+# Include this file using `include` command and add package you need, example:
+#
+#     cmake_minimum_required(VERSION 3.2)
+#
+#     include("cmake/HunterGate.cmake")
+#     HunterGate(
+#         URL "https://github.com/path/to/hunter/archive.tar.gz"
+#         SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
+#     )
+#
+#     project(MyProject)
+#
+#     hunter_add_package(Foo)
+#     hunter_add_package(Boo COMPONENTS Bar Baz)
+#
+# Projects:
+#     * https://github.com/hunter-packages/gate/
+#     * https://github.com/ruslo/hunter
+
+option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
+
+if(HUNTER_ENABLED)
+  if(CMAKE_VERSION VERSION_LESS "3.2")
+    message(
+        FATAL_ERROR
+        "At least CMake version 3.2 required for Hunter dependency management."
+        " Update CMake or set HUNTER_ENABLED to OFF."
+    )
+  endif()
+endif()
+
+include(CMakeParseArguments) # cmake_parse_arguments
+
+option(HUNTER_STATUS_PRINT "Print working status" ON)
+option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
+option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
+
+set(HUNTER_WIKI "https://github.com/ruslo/hunter/wiki")
+
+function(hunter_gate_status_print)
+  if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
+    foreach(print_message ${ARGV})
+      message(STATUS "[hunter] ${print_message}")
+    endforeach()
+  endif()
+endfunction()
+
+function(hunter_gate_status_debug)
+  if(HUNTER_STATUS_DEBUG)
+    foreach(print_message ${ARGV})
+      string(TIMESTAMP timestamp)
+      message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}")
+    endforeach()
+  endif()
+endfunction()
+
+function(hunter_gate_wiki wiki_page)
+  message("------------------------------ WIKI -------------------------------")
+  message("    ${HUNTER_WIKI}/${wiki_page}")
+  message("-------------------------------------------------------------------")
+  message("")
+  message(FATAL_ERROR "")
+endfunction()
+
+function(hunter_gate_internal_error)
+  message("")
+  foreach(print_message ${ARGV})
+    message("[hunter ** INTERNAL **] ${print_message}")
+  endforeach()
+  message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
+  message("")
+  hunter_gate_wiki("error.internal")
+endfunction()
+
+function(hunter_gate_fatal_error)
+  cmake_parse_arguments(hunter "" "WIKI" "" "${ARGV}")
+  string(COMPARE EQUAL "${hunter_WIKI}" "" have_no_wiki)
+  if(have_no_wiki)
+    hunter_gate_internal_error("Expected wiki")
+  endif()
+  message("")
+  foreach(x ${hunter_UNPARSED_ARGUMENTS})
+    message("[hunter ** FATAL ERROR **] ${x}")
+  endforeach()
+  message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
+  message("")
+  hunter_gate_wiki("${hunter_WIKI}")
+endfunction()
+
+function(hunter_gate_user_error)
+  hunter_gate_fatal_error(${ARGV} WIKI "error.incorrect.input.data")
+endfunction()
+
+function(hunter_gate_self root version sha1 result)
+  string(COMPARE EQUAL "${root}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("root is empty")
+  endif()
+
+  string(COMPARE EQUAL "${version}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("version is empty")
+  endif()
+
+  string(COMPARE EQUAL "${sha1}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("sha1 is empty")
+  endif()
+
+  string(SUBSTRING "${sha1}" 0 7 archive_id)
+
+  if(EXISTS "${root}/cmake/Hunter")
+    set(hunter_self "${root}")
+  else()
+    set(
+        hunter_self
+        "${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
+    )
+  endif()
+
+  set("${result}" "${hunter_self}" PARENT_SCOPE)
+endfunction()
+
+# Set HUNTER_GATE_ROOT cmake variable to suitable value.
+function(hunter_gate_detect_root)
+  # Check CMake variable
+  string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty)
+  if(not_empty)
+    set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE)
+    hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable")
+    return()
+  endif()
+
+  # Check environment variable
+  string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty)
+  if(not_empty)
+    set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE)
+    hunter_gate_status_debug("HUNTER_ROOT detected by environment variable")
+    return()
+  endif()
+
+  # Check HOME environment variable
+  string(COMPARE NOTEQUAL "$ENV{HOME}" "" result)
+  if(result)
+    set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE)
+    hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable")
+    return()
+  endif()
+
+  # Check SYSTEMDRIVE and USERPROFILE environment variable (windows only)
+  if(WIN32)
+    string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result)
+    if(result)
+      set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE)
+      hunter_gate_status_debug(
+          "HUNTER_ROOT set using SYSTEMDRIVE environment variable"
+      )
+      return()
+    endif()
+
+    string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result)
+    if(result)
+      set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE)
+      hunter_gate_status_debug(
+          "HUNTER_ROOT set using USERPROFILE environment variable"
+      )
+      return()
+    endif()
+  endif()
+
+  hunter_gate_fatal_error(
+      "Can't detect HUNTER_ROOT"
+      WIKI "error.detect.hunter.root"
+  )
+endfunction()
+
+function(hunter_gate_download dir)
+  string(
+      COMPARE
+      NOTEQUAL
+      "$ENV{HUNTER_DISABLE_AUTOINSTALL}"
+      ""
+      disable_autoinstall
+  )
+  if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL)
+    hunter_gate_fatal_error(
+        "Hunter not found in '${dir}'"
+        "Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'"
+        "Settings:"
+        "  HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
+        "  HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
+        WIKI "error.run.install"
+    )
+  endif()
+  string(COMPARE EQUAL "${dir}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("Empty 'dir' argument")
+  endif()
+
+  string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("HUNTER_GATE_SHA1 empty")
+  endif()
+
+  string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("HUNTER_GATE_URL empty")
+  endif()
+
+  set(done_location "${dir}/DONE")
+  set(sha1_location "${dir}/SHA1")
+
+  set(build_dir "${dir}/Build")
+  set(cmakelists "${dir}/CMakeLists.txt")
+
+  hunter_gate_status_debug("Locking directory: ${dir}")
+  file(LOCK "${dir}" DIRECTORY GUARD FUNCTION)
+  hunter_gate_status_debug("Lock done")
+
+  if(EXISTS "${done_location}")
+    # while waiting for lock other instance can do all the job
+    hunter_gate_status_debug("File '${done_location}' found, skip install")
+    return()
+  endif()
+
+  file(REMOVE_RECURSE "${build_dir}")
+  file(REMOVE_RECURSE "${cmakelists}")
+
+  file(MAKE_DIRECTORY "${build_dir}") # check directory permissions
+
+  # Disabling languages speeds up a little bit, reduces noise in the output
+  # and avoids path too long windows error
+  file(
+      WRITE
+      "${cmakelists}"
+      "cmake_minimum_required(VERSION 3.2)\n"
+      "project(HunterDownload LANGUAGES NONE)\n"
+      "include(ExternalProject)\n"
+      "ExternalProject_Add(\n"
+      "    Hunter\n"
+      "    URL\n"
+      "    \"${HUNTER_GATE_URL}\"\n"
+      "    URL_HASH\n"
+      "    SHA1=${HUNTER_GATE_SHA1}\n"
+      "    DOWNLOAD_DIR\n"
+      "    \"${dir}\"\n"
+      "    TLS_VERIFY\n"
+      "    ${HUNTER_TLS_VERIFY}\n"
+      "    SOURCE_DIR\n"
+      "    \"${dir}/Unpacked\"\n"
+      "    CONFIGURE_COMMAND\n"
+      "    \"\"\n"
+      "    BUILD_COMMAND\n"
+      "    \"\"\n"
+      "    INSTALL_COMMAND\n"
+      "    \"\"\n"
+      ")\n"
+  )
+
+  if(HUNTER_STATUS_DEBUG)
+    set(logging_params "")
+  else()
+    set(logging_params OUTPUT_QUIET)
+  endif()
+
+  hunter_gate_status_debug("Run generate")
+
+  # Need to add toolchain file too.
+  # Otherwise on Visual Studio + MDD this will fail with error:
+  # "Could not find an appropriate version of the Windows 10 SDK installed on this machine"
+  if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
+    get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE)
+    set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}")
+  else()
+    # 'toolchain_arg' can't be empty
+    set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=")
+  endif()
+
+  string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make)
+  if(no_make)
+    set(make_arg "")
+  else()
+    # Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM
+    set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}")
+  endif()
+
+  execute_process(
+      COMMAND
+      "${CMAKE_COMMAND}"
+      "-H${dir}"
+      "-B${build_dir}"
+      "-G${CMAKE_GENERATOR}"
+      "${toolchain_arg}"
+      ${make_arg}
+      WORKING_DIRECTORY "${dir}"
+      RESULT_VARIABLE download_result
+      ${logging_params}
+  )
+
+  if(NOT download_result EQUAL 0)
+    hunter_gate_internal_error(
+        "Configure project failed."
+        "To reproduce the error run: ${CMAKE_COMMAND} -H${dir} -B${build_dir} -G${CMAKE_GENERATOR} ${toolchain_arg} ${make_arg}"
+        "In directory ${dir}"
+    )
+  endif()
+
+  hunter_gate_status_print(
+      "Initializing Hunter workspace (${HUNTER_GATE_SHA1})"
+      "  ${HUNTER_GATE_URL}"
+      "  -> ${dir}"
+  )
+  execute_process(
+      COMMAND "${CMAKE_COMMAND}" --build "${build_dir}"
+      WORKING_DIRECTORY "${dir}"
+      RESULT_VARIABLE download_result
+      ${logging_params}
+  )
+
+  if(NOT download_result EQUAL 0)
+    hunter_gate_internal_error("Build project failed")
+  endif()
+
+  file(REMOVE_RECURSE "${build_dir}")
+  file(REMOVE_RECURSE "${cmakelists}")
+
+  file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}")
+  file(WRITE "${done_location}" "DONE")
+
+  hunter_gate_status_debug("Finished")
+endfunction()
+
+# Must be a macro so master file 'cmake/Hunter' can
+# apply all variables easily just by 'include' command
+# (otherwise PARENT_SCOPE magic needed)
+macro(HunterGate)
+  if(HUNTER_GATE_DONE)
+    # variable HUNTER_GATE_DONE set explicitly for external project
+    # (see `hunter_download`)
+    set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
+  endif()
+
+  # First HunterGate command will init Hunter, others will be ignored
+  get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET)
+
+  if(NOT HUNTER_ENABLED)
+    # Empty function to avoid error "unknown function"
+    function(hunter_add_package)
+    endfunction()
+
+    set(
+        _hunter_gate_disabled_mode_dir
+        "${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode"
+    )
+    if(EXISTS "${_hunter_gate_disabled_mode_dir}")
+      hunter_gate_status_debug(
+          "Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}"
+      )
+      list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}")
+    endif()
+  elseif(_hunter_gate_done)
+    hunter_gate_status_debug("Secondary HunterGate (use old settings)")
+    hunter_gate_self(
+        "${HUNTER_CACHED_ROOT}"
+        "${HUNTER_VERSION}"
+        "${HUNTER_SHA1}"
+        _hunter_self
+    )
+    include("${_hunter_self}/cmake/Hunter")
+  else()
+    set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}")
+
+    string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name)
+    if(_have_project_name)
+      hunter_gate_fatal_error(
+          "Please set HunterGate *before* 'project' command. "
+          "Detected project: ${PROJECT_NAME}"
+          WIKI "error.huntergate.before.project"
+      )
+    endif()
+
+    cmake_parse_arguments(
+        HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV}
+    )
+
+    string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1)
+    string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url)
+    string(
+        COMPARE
+        NOTEQUAL
+        "${HUNTER_GATE_UNPARSED_ARGUMENTS}"
+        ""
+        _have_unparsed
+    )
+    string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global)
+    string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath)
+
+    if(_have_unparsed)
+      hunter_gate_user_error(
+          "HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}"
+      )
+    endif()
+    if(_empty_sha1)
+      hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory")
+    endif()
+    if(_empty_url)
+      hunter_gate_user_error("URL suboption of HunterGate is mandatory")
+    endif()
+    if(_have_global)
+      if(HUNTER_GATE_LOCAL)
+        hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)")
+      endif()
+      if(_have_filepath)
+        hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)")
+      endif()
+    endif()
+    if(HUNTER_GATE_LOCAL)
+      if(_have_global)
+        hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)")
+      endif()
+      if(_have_filepath)
+        hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)")
+      endif()
+    endif()
+    if(_have_filepath)
+      if(_have_global)
+        hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)")
+      endif()
+      if(HUNTER_GATE_LOCAL)
+        hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)")
+      endif()
+    endif()
+
+    hunter_gate_detect_root() # set HUNTER_GATE_ROOT
+
+    # Beautify path, fix probable problems with windows path slashes
+    get_filename_component(
+        HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE
+    )
+    hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}")
+    if(NOT HUNTER_ALLOW_SPACES_IN_PATH)
+      string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces)
+      if(NOT _contain_spaces EQUAL -1)
+        hunter_gate_fatal_error(
+            "HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
+            "Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
+            "(Use at your own risk!)"
+            WIKI "error.spaces.in.hunter.root"
+        )
+      endif()
+    endif()
+
+    string(
+        REGEX
+        MATCH
+        "[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*"
+        HUNTER_GATE_VERSION
+        "${HUNTER_GATE_URL}"
+    )
+    string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty)
+    if(_is_empty)
+      set(HUNTER_GATE_VERSION "unknown")
+    endif()
+
+    hunter_gate_self(
+        "${HUNTER_GATE_ROOT}"
+        "${HUNTER_GATE_VERSION}"
+        "${HUNTER_GATE_SHA1}"
+        _hunter_self
+    )
+
+    set(_master_location "${_hunter_self}/cmake/Hunter")
+    if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter")
+      # Hunter downloaded manually (e.g. by 'git clone')
+      set(_unused "xxxxxxxxxx")
+      set(HUNTER_GATE_SHA1 "${_unused}")
+      set(HUNTER_GATE_VERSION "${_unused}")
+    else()
+      get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
+      set(_done_location "${_archive_id_location}/DONE")
+      set(_sha1_location "${_archive_id_location}/SHA1")
+
+      # Check Hunter already downloaded by HunterGate
+      if(NOT EXISTS "${_done_location}")
+        hunter_gate_download("${_archive_id_location}")
+      endif()
+
+      if(NOT EXISTS "${_done_location}")
+        hunter_gate_internal_error("hunter_gate_download failed")
+      endif()
+
+      if(NOT EXISTS "${_sha1_location}")
+        hunter_gate_internal_error("${_sha1_location} not found")
+      endif()
+      file(READ "${_sha1_location}" _sha1_value)
+      string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal)
+      if(NOT _is_equal)
+        hunter_gate_internal_error(
+            "Short SHA1 collision:"
+            "  ${_sha1_value} (from ${_sha1_location})"
+            "  ${HUNTER_GATE_SHA1} (HunterGate)"
+        )
+      endif()
+      if(NOT EXISTS "${_master_location}")
+        hunter_gate_user_error(
+            "Master file not found:"
+            "  ${_master_location}"
+            "try to update Hunter/HunterGate"
+        )
+      endif()
+    endif()
+    include("${_master_location}")
+    set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
+  endif()
+endmacro()

+ 17 - 8
cmake/LibiglDownloadExternal.cmake

@@ -51,7 +51,7 @@ endfunction()
 function(igl_download_comiso)
 	igl_download_project(CoMISo
 		GIT_REPOSITORY https://github.com/libigl/CoMISo.git
-		GIT_TAG        1f9618cf9b7bd77370d817976470d59091928606
+		GIT_TAG        d60aa4759fba76b0b793b1efb090b7a771dd7c56
 	)
 endfunction()
 
@@ -64,7 +64,7 @@ function(igl_download_cork)
 endfunction()
 
 ## Eigen
-set(LIBIGL_EIGEN_VERSION 3.2.10 CACHE STRING "Default version of Eigen used by libigl.")
+set(LIBIGL_EIGEN_VERSION 3.3.7 CACHE STRING "Default version of Eigen used by libigl.")
 function(igl_download_eigen)
 	igl_download_project(eigen
 		GIT_REPOSITORY https://github.com/eigenteam/eigen-git-mirror.git
@@ -103,12 +103,21 @@ endfunction()
 function(igl_download_imgui)
 	igl_download_project(imgui
 		GIT_REPOSITORY https://github.com/ocornut/imgui.git
-		GIT_TAG        v1.69
+		GIT_TAG        v1.76
 		${LIBIGL_BRANCH_OPTIONS}
 	)
 	igl_download_project(libigl-imgui
 		GIT_REPOSITORY https://github.com/libigl/libigl-imgui.git
-		GIT_TAG        07ecd3858acc71e70f0f9b2dea20a139bdddf8ae
+		GIT_TAG        99f0643089b19f6daf5b3efd9544a65c9a851966
+	)
+endfunction()
+
+## ImGuizmo
+function(igl_download_imguizmo)
+	igl_download_project(imguizmo
+		GIT_REPOSITORY https://github.com/CedricGuillemet/ImGuizmo.git
+		GIT_TAG        a23567269f6617342bcc112394bdad937b54b2d7
+		${LIBIGL_BRANCH_OPTIONS}
 	)
 endfunction()
 
@@ -156,7 +165,7 @@ endfunction()
 function(igl_download_catch2)
 	igl_download_project(catch2
 		GIT_REPOSITORY https://github.com/catchorg/Catch2.git
-		GIT_TAG        03d122a35c3f5c398c43095a87bc82ed44642516
+		GIT_TAG        v2.11.0
 	)
 endfunction()
 
@@ -164,7 +173,7 @@ endfunction()
 function(igl_download_predicates)
 	igl_download_project(predicates
 		GIT_REPOSITORY https://github.com/libigl/libigl-predicates.git
-		GIT_TAG        4c57c1d3f31646b010d1d58bfbe201e75c2b2ad8
+		GIT_TAG        5a1d2194ec114bff51d5a33230586cafb83adc86
 	)
 endfunction()
 
@@ -175,7 +184,7 @@ function(igl_download_test_data)
 	igl_download_project_aux(test_data
 		"${LIBIGL_EXTERNAL}/../tests/data"
 		GIT_REPOSITORY https://github.com/libigl/libigl-tests-data
-		GIT_TAG        adc66cabf712a0bd68ac182b4e7f8b5ba009c3dd
+		GIT_TAG        b5dddf45e329af685cd107e38770a28cfc18eb15
 	)
 endfunction()
 
@@ -184,7 +193,7 @@ function(igl_download_tutorial_data)
 	igl_download_project_aux(tutorial_data
 		"${LIBIGL_EXTERNAL}/../tutorial/data"
 		GIT_REPOSITORY https://github.com/libigl/libigl-tutorial-data
-		GIT_TAG        5c6a1ea809c043d71e5595775709c15325a7158c
+		GIT_TAG        fb5fa00bc4ede64b36002d703ce541552370b6e9
 	)
 endfunction()
 

+ 118 - 0
cmake/LibiglFolders.cmake

@@ -0,0 +1,118 @@
+# Sort projects inside the solution
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+function(igl_folder_targets FOLDER_NAME)
+    foreach(target IN ITEMS ${ARGN})
+        if(TARGET ${target})
+            get_target_property(TYPE ${target} TYPE)
+            if(NOT (TYPE STREQUAL "INTERFACE_LIBRARY"))
+                set_target_properties(${target} PROPERTIES FOLDER "${FOLDER_NAME}")
+            endif()
+        endif()
+    endforeach()
+endfunction()
+
+function(igl_set_folders)
+
+igl_folder_targets("ThirdParty/Embree"
+    algorithms
+    embree
+    lexers
+    math
+    simd
+    sys
+    tasking
+)
+
+igl_folder_targets("ThirdParty"
+    CoMISo
+    glad
+    glfw
+    imgui
+    predicates
+    tetgen
+    tinyxml2
+    triangle
+)
+
+igl_folder_targets("Libigl"
+    igl
+    igl_comiso
+    igl_embree
+    igl_opengl
+    igl_opengl_glfw
+    igl_opengl_glfw_imgui
+    igl_png
+    igl_predicates
+    igl_stb_image
+    igl_tetgen
+    igl_triangle
+    igl_xml
+)
+
+igl_folder_targets("Unit Tests"
+    libigl_tests
+)
+
+igl_folder_targets("Tutorials"
+    101_FileIO_bin
+    102_DrawMesh_bin
+    103_Events_bin
+    104_Colors_bin
+    105_Overlays_bin
+    106_ViewerMenu_bin
+    107_MultipleMeshes_bin
+    108_MultipleViews_bin
+    201_Normals_bin
+    202_GaussianCurvature_bin
+    203_CurvatureDirections_bin
+    204_Gradient_bin
+    205_Laplacian_bin
+    206_GeodesicDistance_bin
+    301_Slice_bin
+    302_Sort_bin
+    303_LaplaceEquation_bin
+    304_LinearEqualityConstraints_bin
+    305_QuadraticProgramming_bin
+    306_EigenDecomposition_bin
+    401_BiharmonicDeformation_bin
+    402_PolyharmonicDeformation_bin
+    403_BoundedBiharmonicWeights_bin
+    404_DualQuaternionSkinning_bin
+    405_AsRigidAsPossible_bin
+    406_FastAutomaticSkinningTransformations_bin
+    407_BiharmonicCoordinates_bin
+    408_DirectDeltaMush_bin
+    501_HarmonicParam_bin
+    502_LSCMParam_bin
+    503_ARAPParam_bin
+    504_NRosyDesign_bin
+    505_MIQ_bin
+    506_FrameField_bin
+    507_Planarization_bin
+    601_Serialization_bin
+    604_Triangle_bin
+    605_Tetgen_bin
+    606_AmbientOcclusion_bin
+    607_ScreenCapture_bin
+    701_Statistics_bin
+    702_WindingNumber_bin
+    703_Decimation_bin
+    704_SignedDistance_bin
+    705_MarchingCubes_bin
+    706_FacetOrientation_bin
+    707_SweptVolume_bin
+    708_Picking_bin
+    709_SLIM_bin
+    710_SCAF_bin
+    711_Subdivision_bin
+    712_DataSmoothing_bin
+    713_ShapeUp_bin
+    714_MarchingTets_bin
+    715_MeshImplicitFunction_bin
+    716_HeatGeodesics_bin
+    718_IterativeClosestPoint_bin
+    719_ExplodedView_bin
+)
+
+endfunction()

+ 8 - 4
cmake/LibiglWindows.cmake

@@ -1,8 +1,6 @@
 if(MSVC)
-	if("${MSVC_RUNTIME}" STREQUAL "")
-		set(MSVC_RUNTIME "static")
-	endif()
-	if(${MSVC_RUNTIME} STREQUAL "static")
+	option(IGL_STATIC_RUNTIME "Use libigl with the static MSVC runtime." OFF)
+	if(IGL_STATIC_RUNTIME)
 		message(STATUS "MSVC -> forcing use of statically-linked runtime.")
 		foreach(config ${CMAKE_CONFIGURATION_TYPES})
 			string(TOUPPER ${config} config)
@@ -19,4 +17,10 @@ if(MSVC)
 		endforeach()
 		string(REPLACE "/MTd" "/MDd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
 	endif()
+
+	# https://github.com/mozilla/sccache/issues/242
+	if(CMAKE_CXX_COMPILER_LAUNCHER STREQUAL "sccache")
+		string(REGEX REPLACE "/Z[iI7]" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+		set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7")
+	endif()
 endif()

+ 8 - 0
cmake/libigl-cgal.yml

@@ -0,0 +1,8 @@
+# This is a conda environment that can be used to compile libigl with CGAL on Windows
+# Only boost is required to be installed on the system, CGAL is automatically downloaded
+# by CMake and is built with libigl.
+name: libigl-cgal
+channels:
+  - conda-forge
+dependencies:
+  - boost-cpp=1.65.0

+ 80 - 47
cmake/libigl.cmake

@@ -34,10 +34,13 @@ option(LIBIGL_WITH_TETGEN            "Use Tetgen"                   OFF)
 option(LIBIGL_WITH_TRIANGLE          "Use Triangle"                 OFF)
 option(LIBIGL_WITH_PREDICATES        "Use exact predicates"         OFF)
 option(LIBIGL_WITH_XML               "Use XML"                      OFF)
-option(LIBIGL_WITH_PYTHON            "Use Python"                   OFF)
 option(LIBIGL_WITHOUT_COPYLEFT       "Disable Copyleft libraries"   OFF)
 option(LIBIGL_EXPORT_TARGETS         "Export libigl CMake targets"  OFF)
 
+if(LIBIGL_BUILD_PYTHON)
+  message(FATAL_ERROR "Python bindings have been removed in this version. Please use an older version of libigl, or wait for the new bindings to be released.")
+endif()
+
 ################################################################################
 
 ### Configuration
@@ -56,6 +59,9 @@ endif()
 list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
 include(LibiglDownloadExternal)
 
+# Provides igl_set_folders() to set folders for Visual Studio/Xcode
+include(LibiglFolders)
+
 ################################################################################
 ### IGL Common
 ################################################################################
@@ -82,7 +88,7 @@ if(MSVC)
   target_compile_definitions(igl_common INTERFACE -DNOMINMAX)
 endif()
 
-### Set compiler flags for building the tests on Windows with Visual Studio
+# Controls whether to use the static MSVC runtime or not
 include(LibiglWindows)
 
 if(BUILD_SHARED_LIBS)
@@ -90,22 +96,28 @@ if(BUILD_SHARED_LIBS)
   set_target_properties(igl_common PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE ON)
 endif()
 
-if(UNIX)
+if(UNIX AND NOT HUNTER_ENABLED)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
 endif()
 
+if(HUNTER_ENABLED)
+  hunter_add_package(Eigen)
+  find_package(Eigen3 CONFIG REQUIRED)
+endif()
+
 # Eigen
-if(TARGET Eigen3::Eigen)
-  # If an imported target already exists, use it
-  target_link_libraries(igl_common INTERFACE Eigen3::Eigen)
-else()
+if(NOT TARGET Eigen3::Eigen)
   igl_download_eigen()
-  target_include_directories(igl_common SYSTEM INTERFACE
+  add_library(igl_eigen INTERFACE)
+  target_include_directories(igl_eigen SYSTEM INTERFACE
     $<BUILD_INTERFACE:${LIBIGL_EXTERNAL}/eigen>
     $<INSTALL_INTERFACE:include>
   )
+  set_property(TARGET igl_eigen PROPERTY EXPORT_NAME Eigen3::Eigen)
+  add_library(Eigen3::Eigen ALIAS igl_eigen)
 endif()
+target_link_libraries(igl_common INTERFACE Eigen3::Eigen)
 
 # C++11 Thread library
 find_package(Threads REQUIRED)
@@ -140,16 +152,20 @@ function(compile_igl_module module_dir)
   endif()
   if(LIBIGL_USE_STATIC_LIBRARY)
     file(GLOB SOURCES_IGL_${module_name}
-      "${LIBIGL_SOURCE_DIR}/igl/${module_dir}/*.cpp")
+      "${LIBIGL_SOURCE_DIR}/igl/${module_dir}/*.cpp"
+      "${LIBIGL_SOURCE_DIR}/igl/${module_dir}/*.h*"
+    )
     if(NOT LIBIGL_WITHOUT_COPYLEFT)
       file(GLOB COPYLEFT_SOURCES_IGL_${module_name}
-        "${LIBIGL_SOURCE_DIR}/igl/copyleft/${module_dir}/*.cpp")
+        "${LIBIGL_SOURCE_DIR}/igl/copyleft/${module_dir}/*.cpp"
+        "${LIBIGL_SOURCE_DIR}/igl/copyleft/${module_dir}/*.h*"
+      )
       list(APPEND SOURCES_IGL_${module_name} ${COPYLEFT_SOURCES_IGL_${module_name}})
     endif()
     add_library(${module_libname} STATIC ${SOURCES_IGL_${module_name}} ${ARGN})
     if(MSVC)
       # Silencing some compile warnings
-      target_compile_options(${module_libname} PRIVATE 
+      target_compile_options(${module_libname} PRIVATE
         # Type conversion warnings. These can be fixed with some effort and possibly more verbose code.
         /wd4267 # conversion from 'size_t' to 'type', possible loss of data
         /wd4244 # conversion from 'type1' to 'type2', possible loss of data
@@ -162,8 +178,6 @@ function(compile_igl_module module_dir)
         # This one is when using bools in adjacency matrices
         /wd4804 #'+=': unsafe use of type 'bool' in operation
       )
-    else()
-      #target_compile_options(${module_libname} PRIVATE -w) # disable all warnings (not ideal but...)
     endif()
   else()
     add_library(${module_libname} INTERFACE)
@@ -188,14 +202,16 @@ endfunction()
 if(LIBIGL_USE_STATIC_LIBRARY)
   file(GLOB SOURCES_IGL
     "${LIBIGL_SOURCE_DIR}/igl/*.cpp"
-    "${LIBIGL_SOURCE_DIR}/igl/copyleft/*.cpp")
+    "${LIBIGL_SOURCE_DIR}/igl/*.h*"
+    "${LIBIGL_SOURCE_DIR}/igl/copyleft/*.cpp"
+    "${LIBIGL_SOURCE_DIR}/igl/copyleft/*.h*"
+  )
 endif()
 compile_igl_module("core" ${SOURCES_IGL})
 
 ################################################################################
 ### Download the python part ###
 if(LIBIGL_WITH_PYTHON)
-  igl_download_pybind11()
 endif()
 
 ################################################################################
@@ -208,14 +224,12 @@ if(LIBIGL_WITH_CGAL)
     set(CGAL_DIR "${LIBIGL_EXTERNAL}/cgal")
     igl_download_cgal()
     igl_download_cgal_deps()
+    message("BOOST_ROOT: ${BOOST_ROOT}")
     if(EXISTS ${LIBIGL_EXTERNAL}/boost)
       set(BOOST_ROOT "${LIBIGL_EXTERNAL}/boost")
     endif()
-    if(LIBIGL_WITH_PYTHON)
-      option(CGAL_Boost_USE_STATIC_LIBS "Use static Boost libs with CGAL" OFF)
-    else()
-      option(CGAL_Boost_USE_STATIC_LIBS "Use static Boost libs with CGAL" ON)
-    endif()
+    option(CGAL_Boost_USE_STATIC_LIBS "Use static Boost libs with CGAL" ON)
+
     find_package(CGAL CONFIG COMPONENTS Core PATHS ${CGAL_DIR} NO_DEFAULT_PATH)
   endif()
 
@@ -224,7 +238,7 @@ if(LIBIGL_WITH_CGAL)
     compile_igl_module("cgal")
     target_link_libraries(igl_cgal ${IGL_SCOPE} CGAL::CGAL CGAL::CGAL_Core)
   else()
-    set(LIBIGL_WITH_CGAL OFF CACHE BOOL "" FORCE)
+    message(FATAL_ERROR "Could not define CGAL::CGAL and CGAL::CGAL_Core.")
   endif()
 endif()
 
@@ -284,21 +298,20 @@ endif()
 if(LIBIGL_WITH_EMBREE)
   set(EMBREE_DIR "${LIBIGL_EXTERNAL}/embree")
 
-  set(EMBREE_TESTING_INTENSITY 0 CACHE STRING "" FORCE)
-  set(EMBREE_ISPC_SUPPORT OFF CACHE BOOL " " FORCE)
-  set(EMBREE_TASKING_SYSTEM "INTERNAL" CACHE BOOL " " FORCE)
-  set(EMBREE_TUTORIALS OFF CACHE BOOL " " FORCE)
-  set(EMBREE_MAX_ISA "SSE2" CACHE STRING " " FORCE)
-  set(EMBREE_STATIC_LIB ON CACHE BOOL " " FORCE)
-  if(MSVC)
-    set(EMBREE_STATIC_RUNTIME ON CACHE BOOL " " FORCE)
-  endif()
-
   if(NOT TARGET embree)
-    # TODO: Should probably save/restore the CMAKE_CXX_FLAGS_*, since embree seems to be
-    # overriding them on Windows. But well... it works for now.
     igl_download_embree()
-    add_subdirectory("${EMBREE_DIR}" "embree")
+
+    set(EMBREE_TESTING_INTENSITY 0 CACHE STRING "")
+    set(EMBREE_ISPC_SUPPORT OFF CACHE BOOL " ")
+    set(EMBREE_TASKING_SYSTEM "INTERNAL" CACHE BOOL " ")
+    set(EMBREE_TUTORIALS OFF CACHE BOOL " ")
+    set(EMBREE_MAX_ISA "SSE2" CACHE STRING " ")
+    set(EMBREE_STATIC_LIB ON CACHE BOOL " ")
+    if(MSVC)
+      set(EMBREE_STATIC_RUNTIME ${IGL_STATIC_RUNTIME} CACHE BOOL "Use the static version of the C/C++ runtime library.")
+    endif()
+
+    add_subdirectory("${EMBREE_DIR}" "embree" EXCLUDE_FROM_ALL)
   endif()
 
   compile_igl_module("embree")
@@ -359,11 +372,16 @@ if(LIBIGL_WITH_OPENGL_GLFW)
     # GLFW module
     compile_igl_module("opengl/glfw")
     if(NOT TARGET glfw)
-      set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL " " FORCE)
-      set(GLFW_BUILD_TESTS OFF CACHE BOOL " " FORCE)
-      set(GLFW_BUILD_DOCS OFF CACHE BOOL " " FORCE)
-      set(GLFW_INSTALL OFF CACHE BOOL " " FORCE)
       igl_download_glfw()
+      option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF)
+      option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF)
+      option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF)
+      option(GLFW_INSTALL "Generate installation target" OFF)
+      if(IGL_STATIC_RUNTIME)
+        set(USE_MSVC_RUNTIME_LIBRARY_DLL OFF CACHE BOOL "Use MSVC runtime library DLL" FORCE)
+      else()
+        set(USE_MSVC_RUNTIME_LIBRARY_DLL ON CACHE BOOL "Use MSVC runtime library DLL" FORCE)
+      endif()
       add_subdirectory(${LIBIGL_EXTERNAL}/glfw glfw)
     endif()
     target_link_libraries(igl_opengl_glfw ${IGL_SCOPE} igl_opengl glfw)
@@ -380,7 +398,12 @@ if(LIBIGL_WITH_OPENGL_GLFW_IMGUI)
       igl_download_imgui()
       add_subdirectory(${LIBIGL_EXTERNAL}/libigl-imgui imgui)
     endif()
-    target_link_libraries(igl_opengl_glfw_imgui ${IGL_SCOPE} igl_opengl_glfw imgui)
+    if(NOT TARGET imguizmo)
+      igl_download_imguizmo()
+      add_library(imguizmo ${LIBIGL_EXTERNAL}/imguizmo/ImGuizmo.cpp ${LIBIGL_EXTERNAL}/imguizmo/ImGuizmo.h)
+      target_link_libraries(imguizmo PUBLIC imgui)
+    endif()
+    target_link_libraries(igl_opengl_glfw_imgui ${IGL_SCOPE} igl_opengl_glfw imgui imguizmo)
   endif()
 endif()
 
@@ -473,6 +496,7 @@ function(install_dir_files dir_name)
 
   file(GLOB public_headers
     ${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.hpp
   )
 
   set(files_to_install ${public_headers})
@@ -496,21 +520,30 @@ endfunction()
 include(GNUInstallDirs)
 include(CMakePackageConfigHelpers)
 
+if(TARGET igl_eigen)
+  set(IGL_EIGEN igl_eigen)
+else()
+  set(IGL_EIGEN)
+  message(WARNING "Trying to export igl targets while using an imported target for Eigen.")
+endif()
+
 # Install and export core library
 install(
-   TARGETS
-     igl
-     igl_common
-   EXPORT igl-export
-   PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
-   LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-   RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-   ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  TARGETS
+    igl
+    igl_common
+    ${IGL_EIGEN}
+  EXPORT igl-export
+  PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
 )
 export(
   TARGETS
     igl
     igl_common
+    ${IGL_EIGEN}
   FILE libigl-export.cmake
 )
 

+ 27 - 44
include/igl/AABB.cpp

@@ -1024,58 +1024,41 @@ namespace igl
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-// generated by autoexplicit.sh
+template bool igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, igl::Hit&) const;
+template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const;
+template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
+template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
 template double igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&);
-// generated by autoexplicit.sh
-// generated by autoexplicit.sh
 template float igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, float, float, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
-// generated by autoexplicit.sh
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::serialize<Eigen::Matrix<double, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
-// generated by autoexplicit.sh
-template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::serialize<Eigen::Matrix<double, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
-// generated by autoexplicit.sh
+template float igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
 template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<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<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
-// generated by autoexplicit.sh
+template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, 1, -1, false> > const&, bool) const;
+template std::vector<int, std::allocator<int> > igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::find<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, bool) const;
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
 template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<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<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
-// generated by autoexplicit.sh
-template float igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<float, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
-// generated by autoexplicit.sh
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
-// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&);
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::serialize<Eigen::Matrix<double, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
 template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<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<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<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<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
-// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
 template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
-// generated by autoexplicit.sh
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const;
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&);
-// generated by autoexplicit.sh
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<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<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
 template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-// generated by autoexplicit.sh
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::init<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
-template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, double, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
-template bool igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::intersect_ray<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, igl::Hit&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 2, 3, 0, 2, 3>, Eigen::Matrix<double, 2, 1, 0, 2, 1>, Eigen::Matrix<int, 2, 1, 0, 2, 1>, Eigen::Matrix<double, 2, 3, 0, 2, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 2, 1, 0, 2, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
-template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<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<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int);
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::init<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&);
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::serialize<Eigen::Matrix<double, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, int) const;
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
 template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<long, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&) const;
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 2, 3, 0, 2, 3>, Eigen::Matrix<double, 2, 1, 0, 2, 1>, Eigen::Matrix<int, 2, 1, 0, 2, 1>, Eigen::Matrix<double, 2, 3, 0, 2, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 2, 1, 0, 2, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> >&) const;
+template void igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&) const;
+template void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&);
+template void igl::AABB<Eigen::Matrix<float, -1, 3, 0, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&);
+template void igl::AABB<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&);
+template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&) const;
+template double igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 2>::squared_distance<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<double, 1, 2, 1, 1, 2> const&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> >&) const;
 #ifdef WIN32
 template void igl::AABB<class Eigen::Matrix<double,-1,-1,0,-1,-1>,2>::squared_distance<class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,1,0,-1,1>,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::Matrix<double,-1,3,0,-1,3> >(class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,3,0,-1,3> > &)const;
 template void igl::AABB<class Eigen::Matrix<double,-1,-1,0,-1,-1>,3>::squared_distance<class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,-1,0,-1,-1>,class Eigen::Matrix<double,-1,1,0,-1,1>,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::Matrix<double,-1,3,0,-1,3> >(class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<double,-1,-1,0,-1,-1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<double,-1,3,0,-1,3> > &)const;

+ 10 - 6
include/igl/HalfEdgeIterator.cpp

@@ -10,9 +10,9 @@
 
 template <typename DerivedF, typename DerivedFF, typename DerivedFFi>
 IGL_INLINE igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::HalfEdgeIterator(
-    const Eigen::PlainObjectBase<DerivedF>& _F,
-    const Eigen::PlainObjectBase<DerivedFF>& _FF,
-    const Eigen::PlainObjectBase<DerivedFFi>& _FFi,
+    const Eigen::MatrixBase<DerivedF>& _F,
+    const Eigen::MatrixBase<DerivedFF>& _FF,
+    const Eigen::MatrixBase<DerivedFFi>& _FFi,
     int _fi,
     int _ei,
     bool _reverse
@@ -138,8 +138,8 @@ IGL_INLINE bool igl::HalfEdgeIterator<DerivedF,DerivedFF,DerivedFFi>::operator==
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template      igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>   >::HalfEdgeIterator(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> > const&, int, int, bool);
-template igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >::HalfEdgeIterator(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> > const&, int, int, bool);
+template      igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>   >::HalfEdgeIterator(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, int, int, bool);
+template igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >::HalfEdgeIterator(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, int, bool);
 template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::NextFE();
 template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Ei();
 template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Ei();
@@ -147,12 +147,16 @@ template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen:
 template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>   >::Fi();
 template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>  ,Eigen::Matrix<int, -1, 3, 0, -1, 3>   >::NextFE();
 template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Vi();
-template      igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::HalfEdgeIterator(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> > const&, int, int, bool);
+template      igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::HalfEdgeIterator(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, int, bool);
 template int  igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Fi();
 template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::flipE();
+template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >::flipE();
 template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::flipF();
+template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >::flipF();
 template void igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::flipV();
 template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >::operator==(igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template int igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >::Fi();
 template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >::NextFE();
+template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >::isBorder();
+template bool igl::HalfEdgeIterator<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >::isBorder();
 #endif

+ 6 - 6
include/igl/HalfEdgeIterator.h

@@ -49,9 +49,9 @@ namespace igl
   public:
     // Init the HalfEdgeIterator by specifying Face,Edge Index and Orientation
     IGL_INLINE HalfEdgeIterator(
-        const Eigen::PlainObjectBase<DerivedF>& _F,
-        const Eigen::PlainObjectBase<DerivedFF>& _FF,
-        const Eigen::PlainObjectBase<DerivedFFi>& _FFi,
+        const Eigen::MatrixBase<DerivedF>& _F,
+        const Eigen::MatrixBase<DerivedFF>& _FF,
+        const Eigen::MatrixBase<DerivedFFi>& _FFi,
         int _fi,
         int _ei,
         bool _reverse = false
@@ -100,9 +100,9 @@ namespace igl
     bool reverse;
 
     // All the same type? This is likely to break.
-    const Eigen::PlainObjectBase<DerivedF> & F;
-    const Eigen::PlainObjectBase<DerivedFF> & FF;
-    const Eigen::PlainObjectBase<DerivedFFi> & FFi;
+    const Eigen::MatrixBase<DerivedF> & F;
+    const Eigen::MatrixBase<DerivedFF> & FF;
+    const Eigen::MatrixBase<DerivedFFi> & FFi;
   };
 
 }

+ 7 - 6
include/igl/MappingEnergyType.h

@@ -15,12 +15,13 @@ namespace igl
   
   enum MappingEnergyType
   {
-    ARAP,
-    LOG_ARAP,
-    SYMMETRIC_DIRICHLET,
-    CONFORMAL,
-    EXP_CONFORMAL,
-    EXP_SYMMETRIC_DIRICHLET
+    ARAP = 0,
+    LOG_ARAP = 1,
+    SYMMETRIC_DIRICHLET = 2,
+    CONFORMAL = 3,
+    EXP_CONFORMAL = 4,
+    EXP_SYMMETRIC_DIRICHLET = 5,
+    NUM_SLIM_ENERGY_TYPES = 6
   };
 }
 #endif

+ 2 - 2
include/igl/PI.h

@@ -11,9 +11,9 @@ namespace igl
 {
   // Use standard mathematical constants' M_PI if available
 #ifdef M_PI
-  const double PI = M_PI;
+  constexpr double PI = M_PI;
 #else
-  const double PI = 3.1415926535897932384626433832795;
+  constexpr double PI = 3.1415926535897932384626433832795;
 #endif
 }
 #endif

+ 9 - 13
include/igl/SortableRow.h

@@ -1,5 +1,5 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <[email protected]>
 // 
 // This Source Code Form is subject to the terms of the Mozilla Public License 
@@ -26,34 +26,30 @@ namespace igl
       SortableRow(const T & data):data(data){};
       bool operator<(const SortableRow & that) const
       {
-        // Get reference so that I can use parenthesis
-        const SortableRow<T> & THIS = *this;
         // Lexicographical
-        int minc = (THIS.data.size() < that.data.size()? 
-            THIS.data.size() : that.data.size());
+        int minc = (this->data.size() < that.data.size()?
+            this->data.size() : that.data.size());
         // loop over columns
         for(int i = 0;i<minc;i++)
         {
-          if(THIS.data(i) == that.data(i))
+          if(this->data(i) == that.data(i))
           {
             continue;
           }
-          return THIS.data(i) < that.data(i);
+          return this->data(i) < that.data(i);
         }
         // All characters the same, comes done to length
-        return THIS.data.size()<that.data.size();
+        return this->data.size()<that.data.size();
       };
       bool operator==(const SortableRow & that) const
       {
-        // Get reference so that I can use parenthesis
-        const SortableRow<T> & THIS = *this;
-        if(THIS.data.size() != that.data.size())
+        if(this->data.size() != that.data.size())
         {
           return false;
         }
-        for(int i = 0;i<THIS.data.size();i++)
+        for(int i = 0;i<this->data.size();i++)
         {
-          if(THIS.data(i) != that.data(i))
+          if(this->data(i) != that.data(i))
           {
             return false;
           }

+ 2 - 2
include/igl/active_set.cpp

@@ -223,7 +223,7 @@ IGL_INLINE igl::SolverStatus igl::active_set(
     }
     //cout<<matlab_format((known_i.array()+1).eval(),"known_i")<<endl;
     // PREPARE EQUALITY CONSTRAINTS
-    VectorXi as_ieq_list(as_ieq_count,1);
+    Eigen::Matrix<typename DerivedY::Scalar, Eigen::Dynamic, 1> as_ieq_list(as_ieq_count,1);
     // Gather active constraints and resp. rhss
     DerivedBeq Beq_i;
     Beq_i.resize(Beq.rows()+as_ieq_count,1);
@@ -345,7 +345,7 @@ IGL_INLINE igl::SolverStatus igl::active_set(
     {
       if(Lambda_Aieq_i(a) < params.inactive_threshold)
       {
-        as_ieq(as_ieq_list(a)) = FALSE;
+        as_ieq(int(as_ieq_list(a))) = FALSE;
       }
     }
 

+ 1 - 1
include/igl/active_set.h

@@ -18,7 +18,7 @@ namespace igl
   struct active_set_params;
   // Known Bugs: rows of [Aeq;Aieq] **must** be linearly independent. Should be
   // using QR decomposition otherwise:
-  //   http://www.okstate.edu/sas/v8/sashtml/ormp/chap5/sect32.htm
+  // https://v8doc.sas.com/sashtml/ormp/chap5/sect32.htm
   //
   // ACTIVE_SET Minimize quadratic energy 
   //

+ 0 - 26
include/igl/all_edges.cpp

@@ -1,26 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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 "all_edges.h"
-#include "oriented_facets.h"
-
-template <typename DerivedF, typename DerivedE>
-IGL_INLINE void igl::all_edges(
-  const Eigen::MatrixBase<DerivedF> & F,
-  Eigen::PlainObjectBase<DerivedE> & E)
-{
-  return oriented_facets(F,E);
-}
-
-#ifdef IGL_STATIC_LIBRARY
-// Explicit template instantiation
-template void igl::all_edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::all_edges<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
-template void igl::all_edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
-template void igl::all_edges<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
-template void igl::all_edges<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&);
-#endif

+ 0 - 38
include/igl/all_edges.h

@@ -1,38 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// 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_ALL_EDGES_H
-#define IGL_ALL_EDGES_H
-#include "igl_inline.h"
-#include <Eigen/Dense>
-namespace igl
-{
-  // Deprecated: call oriented_facets instead.
-  //
-  // ALL_EDGES Determines all "directed edges" of a given set of simplices. For
-  // a manifold mesh, this computes all of the half-edges
-  //
-  // Inputs:
-  //   F  #F by simplex_size list of "faces"
-  // Outputs:
-  //   E  #E by simplex_size-1  list of edges
-  //
-  // Note: this is not the same as igl::edges because this includes every
-  // directed edge including repeats (meaning interior edges on a surface will
-  // show up once for each direction and non-manifold edges may appear more than
-  // once for each direction).
-  template <typename DerivedF, typename DerivedE>
-  IGL_INLINE void all_edges(
-    const Eigen::MatrixBase<DerivedF> & F,
-    Eigen::PlainObjectBase<DerivedE> & E);
-}
-
-#ifndef IGL_STATIC_LIBRARY
-#  include "all_edges.cpp"
-#endif
-
-#endif

+ 16 - 14
include/igl/ambient_occlusion.cpp

@@ -25,8 +25,8 @@ IGL_INLINE void igl::ambient_occlusion(
       const Eigen::Vector3f&,
       const Eigen::Vector3f&)
       > & shoot_ray,
-  const Eigen::PlainObjectBase<DerivedP> & P,
-  const Eigen::PlainObjectBase<DerivedN> & N,
+  const Eigen::MatrixBase<DerivedP> & P,
+  const Eigen::MatrixBase<DerivedN> & N,
   const int num_samples,
   Eigen::PlainObjectBase<DerivedS> & S)
 {
@@ -69,10 +69,10 @@ template <
   typename DerivedS >
 IGL_INLINE void igl::ambient_occlusion(
   const igl::AABB<DerivedV,DIM> & aabb,
-  const Eigen::PlainObjectBase<DerivedV> & V,
-  const Eigen::PlainObjectBase<DerivedF> & F,
-  const Eigen::PlainObjectBase<DerivedP> & P,
-  const Eigen::PlainObjectBase<DerivedN> & N,
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedF> & F,
+  const Eigen::MatrixBase<DerivedP> & P,
+  const Eigen::MatrixBase<DerivedN> & N,
   const int num_samples,
   Eigen::PlainObjectBase<DerivedS> & S)
 {
@@ -100,10 +100,10 @@ template <
   typename DerivedN,
   typename DerivedS >
 IGL_INLINE void igl::ambient_occlusion(
-  const Eigen::PlainObjectBase<DerivedV> & V,
-  const Eigen::PlainObjectBase<DerivedF> & F,
-  const Eigen::PlainObjectBase<DerivedP> & P,
-  const Eigen::PlainObjectBase<DerivedN> & N,
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedF> & F,
+  const Eigen::MatrixBase<DerivedP> & P,
+  const Eigen::MatrixBase<DerivedN> & N,
   const int num_samples,
   Eigen::PlainObjectBase<DerivedS> & S)
 {
@@ -128,10 +128,12 @@ IGL_INLINE void igl::ambient_occlusion(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
-template void igl::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> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> 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::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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
-template void igl::ambient_occlusion<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template void igl::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> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
-template void igl::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> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> 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::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> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> 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::ambient_occlusion<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::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> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+template void igl::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> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 10 - 10
include/igl/ambient_occlusion.h

@@ -34,8 +34,8 @@ namespace igl
         const Eigen::Vector3f&,
         const Eigen::Vector3f&)
         > & shoot_ray,
-    const Eigen::PlainObjectBase<DerivedP> & P,
-    const Eigen::PlainObjectBase<DerivedN> & N,
+    const Eigen::MatrixBase<DerivedP> & P,
+    const Eigen::MatrixBase<DerivedN> & N,
     const int num_samples,
     Eigen::PlainObjectBase<DerivedS> & S);
   // Inputs:
@@ -49,10 +49,10 @@ namespace igl
     typename DerivedS >
   IGL_INLINE void ambient_occlusion(
     const igl::AABB<DerivedV,DIM> & aabb,
-    const Eigen::PlainObjectBase<DerivedV> & V,
-    const Eigen::PlainObjectBase<DerivedF> & F,
-    const Eigen::PlainObjectBase<DerivedP> & P,
-    const Eigen::PlainObjectBase<DerivedN> & N,
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedF> & F,
+    const Eigen::MatrixBase<DerivedP> & P,
+    const Eigen::MatrixBase<DerivedN> & N,
     const int num_samples,
     Eigen::PlainObjectBase<DerivedS> & S);
   // Inputs:
@@ -65,10 +65,10 @@ namespace igl
     typename DerivedN,
     typename DerivedS >
   IGL_INLINE void ambient_occlusion(
-    const Eigen::PlainObjectBase<DerivedV> & V,
-    const Eigen::PlainObjectBase<DerivedF> & F,
-    const Eigen::PlainObjectBase<DerivedP> & P,
-    const Eigen::PlainObjectBase<DerivedN> & N,
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedF> & F,
+    const Eigen::MatrixBase<DerivedP> & P,
+    const Eigen::MatrixBase<DerivedN> & N,
     const int num_samples,
     Eigen::PlainObjectBase<DerivedS> & S);
 

+ 15 - 9
include/igl/arap_linear_block.cpp

@@ -10,13 +10,13 @@
 #include "cotmatrix_entries.h"
 #include <Eigen/Dense>
 
-template <typename MatV, typename MatF, typename Scalar>
+template <typename MatV, typename MatF, typename MatK>
 IGL_INLINE void igl::arap_linear_block(
   const MatV & V,
   const MatF & F,
   const int d,
   const igl::ARAPEnergyType energy,
-  Eigen::SparseMatrix<Scalar> & Kd)
+  MatK & Kd)
 {
   switch(energy)
   {
@@ -36,13 +36,15 @@ IGL_INLINE void igl::arap_linear_block(
 }
 
 
-template <typename MatV, typename MatF, typename Scalar>
+template <typename MatV, typename MatF, typename MatK>
 IGL_INLINE void igl::arap_linear_block_spokes(
   const MatV & V,
   const MatF & F,
   const int d,
-  Eigen::SparseMatrix<Scalar> & Kd)
+  MatK & Kd)
 {
+  typedef typename MatK::Scalar Scalar;
+
   using namespace std;
   using namespace Eigen;
   // simplex size (3: triangles, 4: tetrahedra)
@@ -101,13 +103,15 @@ IGL_INLINE void igl::arap_linear_block_spokes(
   Kd.makeCompressed();
 }
 
-template <typename MatV, typename MatF, typename Scalar>
+template <typename MatV, typename MatF, typename MatK>
 IGL_INLINE void igl::arap_linear_block_spokes_and_rims(
   const MatV & V,
   const MatF & F,
   const int d,
-  Eigen::SparseMatrix<Scalar> & Kd)
+  MatK & Kd)
 {
+  typedef typename MatK::Scalar Scalar;
+
   using namespace std;
   using namespace Eigen;
   // simplex size (3: triangles, 4: tetrahedra)
@@ -183,13 +187,14 @@ IGL_INLINE void igl::arap_linear_block_spokes_and_rims(
   Kd.makeCompressed();
 }
 
-template <typename MatV, typename MatF, typename Scalar>
+template <typename MatV, typename MatF, typename MatK>
 IGL_INLINE void igl::arap_linear_block_elements(
   const MatV & V,
   const MatF & F,
   const int d,
-  Eigen::SparseMatrix<Scalar> & Kd)
+  MatK & Kd)
 {
+  typedef typename MatK::Scalar Scalar;
   using namespace std;
   using namespace Eigen;
   // simplex size (3: triangles, 4: tetrahedra)
@@ -249,5 +254,6 @@ IGL_INLINE void igl::arap_linear_block_elements(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template IGL_INLINE void igl::arap_linear_block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, int, igl::ARAPEnergyType, Eigen::SparseMatrix<double, 0, int>&);
+template void igl::arap_linear_block<Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, Eigen::SparseMatrix<double, 0, int> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, igl::ARAPEnergyType, Eigen::SparseMatrix<double, 0, int>&);
+template void igl::arap_linear_block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::SparseMatrix<double, 0, int> >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, int, igl::ARAPEnergyType, Eigen::SparseMatrix<double, 0, int>&);
 #endif

+ 8 - 8
include/igl/arap_linear_block.h

@@ -43,32 +43,32 @@ namespace igl
   //   Kd  #V by #V/#F block of the linear constructor matrix corresponding to
   //     coordinate d
   //
-  template <typename MatV, typename MatF, typename Scalar>
+  template <typename MatV, typename MatF, typename MatK>
   IGL_INLINE void arap_linear_block(
     const MatV & V,
     const MatF & F,
     const int d,
     const igl::ARAPEnergyType energy,
-    Eigen::SparseMatrix<Scalar> & Kd);
+    MatK & Kd);
   // Helper functions for each energy type
-  template <typename MatV, typename MatF, typename Scalar>
+  template <typename MatV, typename MatF, typename MatK>
   IGL_INLINE void arap_linear_block_spokes(
     const MatV & V,
     const MatF & F,
     const int d,
-    Eigen::SparseMatrix<Scalar> & Kd);
-  template <typename MatV, typename MatF, typename Scalar>
+    MatK & Kd);
+  template <typename MatV, typename MatF, typename MatK>
   IGL_INLINE void arap_linear_block_spokes_and_rims(
     const MatV & V,
     const MatF & F,
     const int d,
-    Eigen::SparseMatrix<Scalar> & Kd);
-  template <typename MatV, typename MatF, typename Scalar>
+    MatK & Kd);
+  template <typename MatV, typename MatF, typename MatK>
   IGL_INLINE void arap_linear_block_elements(
     const MatV & V,
     const MatF & F,
     const int d,
-    Eigen::SparseMatrix<Scalar> & Kd);
+    MatK & Kd);
 }
 
 #ifndef IGL_STATIC_LIBRARY

+ 18 - 12
include/igl/arap_rhs.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "arap_rhs.h"
 #include "arap_linear_block.h"
@@ -12,12 +12,13 @@
 #include "cat.h"
 #include <iostream>
 
+template<typename DerivedV, typename DerivedF, typename DerivedK>
 IGL_INLINE void igl::arap_rhs(
-  const Eigen::MatrixXd & V, 
-  const Eigen::MatrixXi & F,
-  const int dim,
-  const igl::ARAPEnergyType energy,
-  Eigen::SparseMatrix<double>& K)
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedF> & F,
+    const int dim,
+    const igl::ARAPEnergyType energy,
+    Eigen::SparseCompressedBase<DerivedK>& K)
 {
   using namespace std;
   using namespace Eigen;
@@ -48,7 +49,7 @@ IGL_INLINE void igl::arap_rhs(
       return;
   }
 
-  SparseMatrix<double> KX,KY,KZ;
+  DerivedK KX,KY,KZ;
   arap_linear_block(V,F,0,energy,KX);
   arap_linear_block(V,F,1,energy,KY);
   if(Vdim == 2)
@@ -62,7 +63,7 @@ IGL_INLINE void igl::arap_rhs(
       K = cat(2,cat(2,repdiag(KX,dim),repdiag(KY,dim)),repdiag(KZ,dim));
     }else if(dim ==2)
     {
-      SparseMatrix<double> ZZ(KX.rows()*2,KX.cols());
+      DerivedK ZZ(KX.rows()*2,KX.cols());
       K = cat(2,cat(2,
             cat(2,repdiag(KX,dim),ZZ),
             cat(2,repdiag(KY,dim),ZZ)),
@@ -84,6 +85,11 @@ IGL_INLINE void igl::arap_rhs(
      Vdim);
     return;
   }
-  
+
 }
 
+
+
+#ifdef IGL_STATIC_LIBRARY
+template void igl::arap_rhs(const Eigen::MatrixBase<Eigen::MatrixXd> & V, const Eigen::MatrixBase<Eigen::MatrixXi> & F,const int dim, const igl::ARAPEnergyType energy,Eigen::SparseCompressedBase<Eigen::SparseMatrix<double>>& K);
+#endif

+ 10 - 9
include/igl/arap_rhs.h

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_ARAP_RHS_H
 #define IGL_ARAP_RHS_H
@@ -25,16 +25,17 @@ namespace igl
   //   energy  igl::ARAPEnergyType enum value defining which energy is being
   //     used. See igl::ARAPEnergyType.h for valid options and explanations.
   // Outputs:
-  //   K  #V*dim by #(F|V)*dim*dim matrix such that: 
+  //   K  #V*dim by #(F|V)*dim*dim matrix such that:
   //     b = K * reshape(permute(R,[3 1 2]),size(V|F,1)*size(V,2)*size(V,2),1);
-  //   
+  //
   // See also: arap_linear_block
+  template<typename DerivedV, typename DerivedF, typename DerivedK>
   IGL_INLINE void arap_rhs(
-    const Eigen::MatrixXd & V, 
-    const Eigen::MatrixXi & F,
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedF> & F,
     const int dim,
     const igl::ARAPEnergyType energy,
-    Eigen::SparseMatrix<double>& K);
+    Eigen::SparseCompressedBase<DerivedK>& K);
 }
 #ifndef IGL_STATIC_LIBRARY
 #include "arap_rhs.cpp"

+ 1 - 1
include/igl/average_onto_faces.cpp

@@ -8,7 +8,7 @@
 #include "average_onto_faces.h"
 
 template <typename DerivedF, typename DerivedS, typename DerivedSF>
-IGL_INLINE void average_onto_faces(
+IGL_INLINE void igl::average_onto_faces(
   const Eigen::MatrixBase<DerivedF> & F,
   const Eigen::MatrixBase<DerivedS> & S,
   Eigen::PlainObjectBase<DerivedSF> & SF)

+ 2 - 2
include/igl/average_onto_vertices.cpp

@@ -7,11 +7,11 @@
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "average_onto_vertices.h"
 
-template<typename DerivedV,typename DerivedF,typename DerivedS>
+template<typename DerivedV,typename DerivedF,typename DerivedS,typename DerivedSV >
 IGL_INLINE void igl::average_onto_vertices(const Eigen::MatrixBase<DerivedV> &V,
   const Eigen::MatrixBase<DerivedF> &F,
   const Eigen::MatrixBase<DerivedS> &S,
-  Eigen::MatrixBase<DerivedS> &SV)
+  Eigen::PlainObjectBase<DerivedSV> &SV)
 {
   SV = DerivedS::Zero(V.rows(),S.cols());
   Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> COUNT(V.rows());

+ 9 - 9
include/igl/average_onto_vertices.h

@@ -1,31 +1,31 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <[email protected]>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_AVERAGE_ONTO_VERTICES_H
 #define IGL_AVERAGE_ONTO_VERTICES_H
 #include "igl_inline.h"
 
 #include <Eigen/Dense>
-namespace igl 
+namespace igl
 {
-  // average_onto_vertices 
+  // average_onto_vertices
   // Move a scalar field defined on faces to vertices by averaging
   //
   // Input:
   // V,F: mesh
   // S: scalar field defined on faces, Fx1
-  // 
+  //
   // Output:
   // SV: scalar field defined on vertices
-  template<typename DerivedV,typename DerivedF,typename DerivedS>
+  template<typename DerivedV,typename DerivedF,typename DerivedS,typename DerivedSV>
   IGL_INLINE void average_onto_vertices(const Eigen::MatrixBase<DerivedV> &V,
     const Eigen::MatrixBase<DerivedF> &F,
     const Eigen::MatrixBase<DerivedS> &S,
-    Eigen::MatrixBase<DerivedS> &SV);
+    Eigen::PlainObjectBase<DerivedSV> &SV);
 }
 
 #ifndef IGL_STATIC_LIBRARY

+ 2 - 7
include/igl/barycenter.cpp

@@ -33,19 +33,12 @@ IGL_INLINE void igl::barycenter(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-// generated by autoexplicit.sh
 template void igl::barycenter<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-// generated by autoexplicit.sh
 template void igl::barycenter<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
 template void igl::barycenter<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
-// generated by autoexplicit.sh
 template void igl::barycenter<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
-// generated by autoexplicit.sh
 template void igl::barycenter<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
-// generated by autoexplicit.sh
 template void igl::barycenter<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
-// generated by autoexplicit.sh
 template void igl::barycenter<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -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, 4, 0, -1, 4> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> >&);
 template void igl::barycenter<Eigen::Matrix<double, -1, 4, 0, -1, 4>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 4, 0, -1, 4> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> >&);
@@ -56,4 +49,6 @@ template void igl::barycenter<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Mat
 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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&);
 template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 2, 3, 0, 2, 3>, Eigen::Matrix<double, 2, 3, 0, 2, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> >&);
 template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, 2, 3, 0, 2, 3>, Eigen::Matrix<double, 2, 3, 0, 2, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 2, 3, 0, 2, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 3, 0, 2, 3> >&);
+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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&);
+template void igl::barycenter<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
 #endif

+ 42 - 0
include/igl/barycentric_interpolation.cpp

@@ -0,0 +1,42 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2020 Alec Jacobson <[email protected]>
+// 
+// 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 "barycentric_interpolation.h"
+#include "parallel_for.h"
+
+template <
+  typename DerivedD,
+  typename DerivedF,
+  typename DerivedB,
+  typename DerivedI,
+  typename DerivedX>
+IGL_INLINE void igl::barycentric_interpolation(
+  const Eigen::MatrixBase<DerivedD> & D,
+  const Eigen::MatrixBase<DerivedF> & F,
+  const Eigen::MatrixBase<DerivedB> & B,
+  const Eigen::MatrixBase<DerivedI> & I,
+  Eigen::PlainObjectBase<DerivedX> & X)
+{
+  assert(B.rows() == I.size());
+  assert(F.cols() == B.cols());
+  X.setZero(B.rows(),D.cols());
+  // should use parallel_for
+  //for(int i = 0;i<X.rows();i++)
+  parallel_for(X.rows(),[&X,&B,&D,&F,&I](const int i)
+  {
+    for(int j = 0;j<F.cols();j++)
+    {
+      X.row(i) += B(i,j) * D.row(F(I(i),j));
+    }
+  },1000);
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::barycentric_interpolation<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+#endif

+ 42 - 0
include/igl/barycentric_interpolation.h

@@ -0,0 +1,42 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2020 Alec Jacobson <[email protected]>
+// 
+// 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_BARYCENTRIC_INTERPOLATION_H
+#define IGL_BARYCENTRIC_INTERPOLATION_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  // Interpolate data on a triangle mesh using barycentric coordinates 
+  //
+  // Inputs:
+  //   D  #D by dim list of per-vertex data
+  //   F  #F by 3 list of triangle indices
+  //   B  #X by 3 list of barycentric corodinates
+  //   I  #X list of triangle indices
+  // Outputs:
+  //   X  #X by dim list of interpolated data
+  template <
+    typename DerivedD,
+    typename DerivedF,
+    typename DerivedB,
+    typename DerivedI,
+    typename DerivedX>
+  IGL_INLINE void barycentric_interpolation(
+    const Eigen::MatrixBase<DerivedD> & D,
+    const Eigen::MatrixBase<DerivedF> & F,
+    const Eigen::MatrixBase<DerivedB> & B,
+    const Eigen::MatrixBase<DerivedI> & I,
+    Eigen::PlainObjectBase<DerivedX> & X);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "barycentric_interpolation.cpp"
+#endif
+
+#endif
+

+ 0 - 44
include/igl/barycentric_to_global.cpp

@@ -1,44 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-//
-// Copyright (C) 2013 Daniele Panozzo <[email protected]>
-//
-// 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 "barycentric_to_global.h"
-
-// For error printing
-#include <cstdio>
-#include <vector>
-
-namespace igl
-{
-  template <typename Scalar, typename Index>
-  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> & bc)
-  {
-    Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> R;
-    R.resize(bc.rows(),3);
-
-    for (unsigned i=0; i<R.rows(); ++i)
-    {
-      unsigned id = round(bc(i,0));
-      double u   = bc(i,1);
-      double v   = bc(i,2);
-
-      if (id != -1)
-        R.row(i) = V.row(F(id,0)) +
-                  ((V.row(F(id,1)) - V.row(F(id,0))) * u +
-                   (V.row(F(id,2)) - V.row(F(id,0))) * v  );
-      else
-        R.row(i) << 0,0,0;
-    }
-    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

+ 0 - 42
include/igl/barycentric_to_global.h

@@ -1,42 +0,0 @@
-// This file is part of libigl, a simple c++ geometry processing library.
-// 
-// Copyright (C) 2013 Daniele Panozzo <[email protected]>
-// 
-// 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_BARYCENTRIC2GLOBAL_H
-#define IGL_BARYCENTRIC2GLOBAL_H
-#include <igl/igl_inline.h>
-
-#include <Eigen/Dense>
-#include <Eigen/Sparse>
-
-namespace igl 
-{
-  // Converts barycentric coordinates in the embree form to 3D coordinates
-  // Embree stores barycentric coordinates as triples: fid, bc1, bc2
-  // fid is the id of a face, bc1 is the displacement of the point wrt the 
-  // first vertex v0 and the edge v1-v0. Similarly, bc2 is the displacement
-  // wrt v2-v0.
-  // 
-  // Input:
-  // V:  #Vx3 Vertices of the mesh
-  // F:  #Fxe Faces of the mesh
-  // bc: #Xx3 Barycentric coordinates, one row per point
-  //
-  // Output:
-  // #X: #Xx3 3D coordinates of all points in bc
-  template <typename Scalar, typename Index>
-  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>  & bc);
-}
-
-#ifndef IGL_STATIC_LIBRARY
-#  include "barycentric_to_global.cpp"
-#endif
-
-#endif

+ 74 - 0
include/igl/bezier.cpp

@@ -0,0 +1,74 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2020 Alec Jacobson <[email protected]>
+// 
+// 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 "bezier.h"
+#include <cassert>
+
+// Adapted from main.c accompanying
+// An Algorithm for Automatically Fitting Digitized Curves
+// by Philip J. Schneider
+// from "Graphics Gems", Academic Press, 1990
+template <typename DerivedV, typename DerivedP>
+IGL_INLINE void igl::bezier(
+  const Eigen::MatrixBase<DerivedV> & V,
+  const typename DerivedV::Scalar t,
+  Eigen::PlainObjectBase<DerivedP> & P)
+{
+  // working local copy
+  DerivedV Vtemp = V;
+  int degree = Vtemp.rows()-1;
+  /* Triangle computation	*/
+  for (int i = 1; i <= degree; i++)
+  {	
+    for (int j = 0; j <= degree-i; j++) 
+    {
+      Vtemp.row(j) = ((1.0 - t) * Vtemp.row(j) + t * Vtemp.row(j+1)).eval();
+    }
+  }
+  P = Vtemp.row(0);
+}
+
+template <typename DerivedV, typename DerivedT, typename DerivedP>
+IGL_INLINE void igl::bezier(
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedT> & T,
+  Eigen::PlainObjectBase<DerivedP> & P)
+{
+  P.resize(T.size(),V.cols());
+  for(int i = 0;i<T.size();i++)
+  {
+    Eigen::Matrix<typename DerivedV::Scalar,1,DerivedV::ColsAtCompileTime> Pi;
+    bezier(V,T(i),Pi);
+    P.row(i) = Pi;
+  }
+}
+
+template <typename VMat, typename DerivedT, typename DerivedP>
+IGL_INLINE void igl::bezier(
+  const std::vector<VMat> & spline,
+  const Eigen::MatrixBase<DerivedT> & T,
+  Eigen::PlainObjectBase<DerivedP> & P)
+{
+  if(spline.size() == 0) return;
+  const int m = T.rows();
+  const int dim = spline[0].cols();
+  P.resize(m*spline.size(),dim);
+  for(int c = 0;c<spline.size();c++)
+  {
+    assert(dim == spline[c].cols() && "All curves must have same dimension");
+    DerivedP Pc;
+    bezier(spline[c],T,Pc);
+    P.block(m*c,0,m,dim) = Pc;
+  }
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+template void igl::bezier<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::bezier<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::bezier<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> >&);
+#endif

+ 51 - 0
include/igl/bezier.h

@@ -0,0 +1,51 @@
+#ifndef BEZIER_H
+#define BEZIER_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+namespace igl
+{
+  // Evaluate a polynomial Bezier Curve.
+  //
+  // Inputs:
+  //   V  #V by dim list of Bezier control points
+  //   t  evaluation parameter within [0,1]
+  // Outputs:
+  //   P  1 by dim output point 
+  template <typename DerivedV, typename DerivedP>
+  IGL_INLINE void bezier(
+    const Eigen::MatrixBase<DerivedV> & V,
+    const typename DerivedV::Scalar t,
+    Eigen::PlainObjectBase<DerivedP> & P);
+  // Evaluate a polynomial Bezier Curve.
+  //
+  // Inputs:
+  //   V  #V by dim list of Bezier control points
+  //   T  #T evaluation parameters within [0,1]
+  // Outputs:
+  //   P  #T  by dim output points
+  template <typename DerivedV, typename DerivedT, typename DerivedP>
+  IGL_INLINE void bezier(
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedT> & T,
+    Eigen::PlainObjectBase<DerivedP> & P);
+  // Evaluate a polynomial Bezier spline with a fixed parameter set for each
+  // sub-curve
+  //
+  // Inputs:
+  //   spline #curves list of lists of Bezier control points
+  //   T  #T evaluation parameters within [0,1] to use for each spline
+  // Outputs:
+  //   P  #curves*#T  by dim output points
+  template <typename VMat, typename DerivedT, typename DerivedP>
+  IGL_INLINE void bezier(
+    const std::vector<VMat> & spline,
+    const Eigen::MatrixBase<DerivedT> & T,
+    Eigen::PlainObjectBase<DerivedP> & P);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "bezier.cpp"
+#endif
+
+#endif 

+ 2 - 2
include/igl/bfs.cpp

@@ -59,7 +59,7 @@ template <
   typename DType,
   typename PType>
 IGL_INLINE void igl::bfs(
-  const Eigen::SparseMatrix<AType> & A,
+  const Eigen::SparseCompressedBase<AType> & A,
   const size_t s,
   std::vector<DType> & D,
   std::vector<PType> & P)
@@ -83,7 +83,7 @@ IGL_INLINE void igl::bfs(
     D.push_back(f);
     P[f] = p;
     seen[f] = true;
-    for(typename Eigen::SparseMatrix<AType>::InnerIterator it (A,f); it; ++it)
+    for(typename AType::InnerIterator it (A,f); it; ++it)
     {
       if(it.value()) Q.push({it.index(),f});
     }

+ 1 - 1
include/igl/bfs.h

@@ -42,7 +42,7 @@ namespace igl
     typename DType,
     typename PType>
   IGL_INLINE void bfs(
-    const Eigen::SparseMatrix<AType> & A,
+    const Eigen::SparseCompressedBase<AType> & A,
     const size_t s,
     std::vector<DType> & D,
     std::vector<PType> & P);

+ 7 - 7
include/igl/bfs_orient.cpp

@@ -12,13 +12,13 @@
 
 template <typename DerivedF, typename DerivedFF, typename DerivedC>
 IGL_INLINE void igl::bfs_orient(
-  const Eigen::PlainObjectBase<DerivedF> & F,
+  const Eigen::MatrixBase<DerivedF> & F,
   Eigen::PlainObjectBase<DerivedFF> & FF,
   Eigen::PlainObjectBase<DerivedC> & C)
 {
   using namespace Eigen;
   using namespace std;
-  SparseMatrix<int> A;
+  SparseMatrix<typename DerivedF::Scalar> A;
   orientable_patches(F,C,A);
 
   // number of faces
@@ -30,7 +30,7 @@ IGL_INLINE void igl::bfs_orient(
   // Edge sets
   const int ES[3][2] = {{1,2},{2,0},{0,1}};
 
-  if(&FF != &F)
+  if(((void*)&FF) != ((void*)&F))
   {
     FF = F;
   }
@@ -38,7 +38,7 @@ IGL_INLINE void igl::bfs_orient(
 #pragma omp parallel for
   for(int c = 0;c<num_cc;c++)
   {
-    queue<int> Q;
+    queue<typename DerivedF::Scalar> Q;
     // find first member of patch c
     for(int f = 0;f<FF.rows();f++)
     {
@@ -51,7 +51,7 @@ IGL_INLINE void igl::bfs_orient(
     assert(!Q.empty());
     while(!Q.empty())
     {
-      const int f = Q.front();
+      const typename DerivedF::Scalar f = Q.front();
       Q.pop();
       if(seen(f) > 0)
       {
@@ -59,7 +59,7 @@ IGL_INLINE void igl::bfs_orient(
       }
       seen(f)++;
       // loop over neighbors of f
-      for(typename SparseMatrix<int>::InnerIterator it (A,f); it; ++it)
+      for(typename SparseMatrix<typename DerivedF::Scalar>::InnerIterator it (A,f); it; ++it)
       {
         // might be some lingering zeros, and skip self-adjacency
         if(it.value() != 0 && it.row() != f)
@@ -96,5 +96,5 @@ IGL_INLINE void igl::bfs_orient(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template void igl::bfs_orient<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<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::bfs_orient<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::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 2 - 2
include/igl/bfs_orient.h

@@ -25,10 +25,10 @@ namespace igl
   //
   template <typename DerivedF, typename DerivedFF, typename DerivedC>
   IGL_INLINE void bfs_orient(
-    const Eigen::PlainObjectBase<DerivedF> & F,
+    const Eigen::MatrixBase<DerivedF> & F,
     Eigen::PlainObjectBase<DerivedFF> & FF,
     Eigen::PlainObjectBase<DerivedC> & C);
-};
+}
 #ifndef IGL_STATIC_LIBRARY
 #  include "bfs_orient.cpp"
 #endif

+ 31 - 27
include/igl/biharmonic_coordinates.cpp

@@ -22,8 +22,8 @@ template <
   typename SType,
   typename DerivedW>
 IGL_INLINE bool igl::biharmonic_coordinates(
-  const Eigen::PlainObjectBase<DerivedV> & V,
-  const Eigen::PlainObjectBase<DerivedT> & T,
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedT> & T,
   const std::vector<std::vector<SType> > & S,
   Eigen::PlainObjectBase<DerivedW> & W)
 {
@@ -36,32 +36,36 @@ template <
   typename SType,
   typename DerivedW>
 IGL_INLINE bool igl::biharmonic_coordinates(
-  const Eigen::PlainObjectBase<DerivedV> & V,
-  const Eigen::PlainObjectBase<DerivedT> & T,
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedT> & T,
   const std::vector<std::vector<SType> > & S,
   const int k,
   Eigen::PlainObjectBase<DerivedW> & W)
 {
   using namespace Eigen;
   using namespace std;
+
+  typedef typename DerivedV::Scalar Scalar;
+  typedef typename DerivedT::Scalar Integer;
+
   // This is not the most efficient way to build A, but follows "Linear
   // Subspace Design for Real-Time Shape Deformation" [Wang et al. 2015].
-  SparseMatrix<double> A;
+  SparseMatrix<Scalar> A;
   {
-    DiagonalMatrix<double,Dynamic> Minv;
-    SparseMatrix<double> L,K;
+    DiagonalMatrix<Scalar, Dynamic> Minv;
+    SparseMatrix<Scalar> L, K;
     Array<bool,Dynamic,Dynamic> C;
     {
       Array<bool,Dynamic,1> I;
       on_boundary(T,I,C);
     }
-#ifdef false 
+#ifdef false
     // Version described in paper is "wrong"
     // http://www.cs.toronto.edu/~jacobson/images/error-in-linear-subspace-design-for-real-time-shape-deformation-2017-wang-et-al.pdf
-    SparseMatrix<double> N,Z,M;
+    SparseMatrix<Scalar> N, Z, M;
     normal_derivative(V,T,N);
     {
-      std::vector<Triplet<double> >ZIJV;
+      std::vector<Triplet<Scalar>> ZIJV;
       for(int t =0;t<T.rows();t++)
       {
         for(int f =0;f<T.cols();f++)
@@ -84,37 +88,37 @@ IGL_INLINE bool igl::biharmonic_coordinates(
     K = N+L;
     massmatrix(V,T,MASSMATRIX_TYPE_DEFAULT,M);
     // normalize
-    M /= ((VectorXd)M.diagonal()).array().abs().maxCoeff();
+    M /= ((Matrix<Scalar, Dynamic, 1>)M.diagonal()).array().abs().maxCoeff();
     Minv =
-      ((VectorXd)M.diagonal().array().inverse()).asDiagonal();
+      ((Matrix<Scalar, Dynamic, 1>)M.diagonal().array().inverse()).asDiagonal();
 #else
-    Eigen::SparseMatrix<double> M;
-    Eigen::MatrixXi E;
-    Eigen::VectorXi EMAP;
+    Eigen::SparseMatrix<Scalar> M;
+    Eigen::Matrix<Integer, Dynamic, Dynamic> E;
+    Eigen::Matrix<Integer, Dynamic, 1> EMAP;
     crouzeix_raviart_massmatrix(V,T,M,E,EMAP);
     crouzeix_raviart_cotmatrix(V,T,E,EMAP,L);
     // Ad  #E by #V facet-vertex incidence matrix
-    Eigen::SparseMatrix<double> Ad(E.rows(),V.rows());
+    Eigen::SparseMatrix<Scalar> Ad(E.rows(),V.rows());
     {
-      std::vector<Eigen::Triplet<double> > AIJV(E.size());
+      std::vector<Eigen::Triplet<Scalar>> AIJV(E.size());
       for(int e = 0;e<E.rows();e++)
       {
         for(int c = 0;c<E.cols();c++)
         {
-          AIJV[e+c*E.rows()] = Eigen::Triplet<double>(e,E(e,c),1);
+          AIJV[e + c * E.rows()] = Eigen::Triplet<Scalar>(e, E(e, c), 1);
         }
       }
       Ad.setFromTriplets(AIJV.begin(),AIJV.end());
     }
     // Degrees
-    Eigen::VectorXd De;
+    Eigen::Matrix<Scalar, Dynamic, 1> De;
     sum(Ad,2,De);
-    Eigen::DiagonalMatrix<double,Eigen::Dynamic> De_diag = 
+    Eigen::DiagonalMatrix<Scalar,Eigen::Dynamic> De_diag =
       De.array().inverse().matrix().asDiagonal();
     K = L*(De_diag*Ad);
     // normalize
-    M /= ((VectorXd)M.diagonal()).array().abs().maxCoeff();
-    Minv = ((VectorXd)M.diagonal().array().inverse()).asDiagonal();
+    M /= ((Matrix<Scalar, Dynamic, 1>)M.diagonal()).array().abs().maxCoeff();
+    Minv = ((Matrix<Scalar, Dynamic, 1>)M.diagonal().array().inverse()).asDiagonal();
     // kill boundary edges
     for(int f = 0;f<T.rows();f++)
     {
@@ -159,9 +163,9 @@ IGL_INLINE bool igl::biharmonic_coordinates(
   }
   const size_t dim = T.cols()-1;
   // Might as well be dense... I think...
-  MatrixXd J = MatrixXd::Zero(mp+mr,mp+r*(dim+1));
-  VectorXi b(mp+mr);
-  MatrixXd H(mp+r*(dim+1),dim);
+  Matrix<Scalar, Dynamic, Dynamic> J = Matrix<Scalar, Dynamic, Dynamic>::Zero(mp+mr,mp+r*(dim+1));
+  Matrix<Integer, Dynamic, 1> b(mp+mr);
+  Matrix<Scalar, Dynamic, Dynamic> H(mp+r*(dim+1),dim);
   {
     int v = 0;
     int c = 0;
@@ -194,10 +198,10 @@ IGL_INLINE bool igl::biharmonic_coordinates(
   // minimize    ½ W' A W'
   // subject to  W(b,:) = J
   return min_quad_with_fixed(
-    A,VectorXd::Zero(A.rows()).eval(),b,J,SparseMatrix<double>(),VectorXd(),true,W);
+    A,Matrix<Scalar, Dynamic, 1>::Zero(A.rows()).eval(),b,J,SparseMatrix<Scalar>(),Matrix<Scalar, Dynamic, 1>(),true,W);
 }
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-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> >&);
+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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<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

+ 4 - 4
include/igl/biharmonic_coordinates.h

@@ -66,8 +66,8 @@ namespace igl
     typename SType,
     typename DerivedW>
   IGL_INLINE bool biharmonic_coordinates(
-    const Eigen::PlainObjectBase<DerivedV> & V,
-    const Eigen::PlainObjectBase<DerivedT> & T,
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedT> & T,
     const std::vector<std::vector<SType> > & S,
     Eigen::PlainObjectBase<DerivedW> & W);
   // k  2-->biharmonic, 3-->triharmonic
@@ -77,8 +77,8 @@ namespace igl
     typename SType,
     typename DerivedW>
   IGL_INLINE bool biharmonic_coordinates(
-    const Eigen::PlainObjectBase<DerivedV> & V,
-    const Eigen::PlainObjectBase<DerivedT> & T,
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedT> & T,
     const std::vector<std::vector<SType> > & S,
     const int k,
     Eigen::PlainObjectBase<DerivedW> & W);

+ 8 - 8
include/igl/bijective_composite_harmonic_mapping.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2017 Alec Jacobson <[email protected]>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "bijective_composite_harmonic_mapping.h"
 
@@ -51,11 +51,11 @@ IGL_INLINE bool igl::bijective_composite_harmonic_mapping(
   assert(F.cols() == 3 && "F should contain triangles");
   int tries = 0;
   int nsteps = min_steps;
-  Derivedbc bc0;
+  Eigen::Matrix<typename Derivedbc::Scalar, Eigen::Dynamic, Eigen::Dynamic> bc0;
   slice(V,b,1,bc0);
 
   // It's difficult to check for flips "robustly" in the sense that the input
-  // mesh might not have positive/consistent sign to begin with. 
+  // mesh might not have positive/consistent sign to begin with.
 
   while(nsteps<=max_steps)
   {
@@ -71,7 +71,7 @@ IGL_INLINE bool igl::bijective_composite_harmonic_mapping(
       // of the boundary conditions. Something like "Homotopic Morphing of
       // Planar Curves" [Dym et al. 2015] but also handling multiple connected
       // components.
-      Derivedbc bct = bc0 + t*(bc - bc0);
+      Eigen::Matrix<typename Derivedbc::Scalar, Eigen::Dynamic, Eigen::Dynamic> bct = bc0 + t * (bc - bc0);
       // Compute dsicrete harmonic map using metric of previous step
       for(int iter = 0;iter<num_inner_iters;iter++)
       {
@@ -82,7 +82,7 @@ IGL_INLINE bool igl::bijective_composite_harmonic_mapping(
         //mw.save_index(b,"b");
         //mw.save(bct,"bct");
         //mw.write("numerical.mat");
-        harmonic(DerivedU(U),F,b,bct,1,U);
+        harmonic(Eigen::Matrix<typename DerivedU::Scalar, Eigen::Dynamic, Eigen::Dynamic>(U), F, b, bct, 1, U);
         igl::slice(U,b,1,bct);
         nans = (U.array() != U.array()).count();
         if(test_for_flips)

+ 71 - 0
include/igl/blkdiag.cpp

@@ -0,0 +1,71 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2020 Alec Jacobson <[email protected]>
+// 
+// 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 "blkdiag.h"
+
+template <typename Scalar>
+IGL_INLINE void igl::blkdiag(
+  const std::vector<Eigen::SparseMatrix<Scalar>> & L, 
+  Eigen::SparseMatrix<Scalar> & Y)
+{
+  int nr = 0;
+  int nc = 0;
+  int nnz = 0;
+  for(const auto & A : L)
+  {
+    nr += A.rows();
+    nc += A.cols();
+  }
+  Y.resize(nr,nc);
+  {
+    int i = 0;
+    int j = 0;
+    for(const auto & A : L)
+    {
+      for(int k = 0;k<A.outerSize();++k)
+      {
+        for(typename Eigen::SparseMatrix<Scalar>::InnerIterator it(A,k);it;++it)
+        {
+           Y.insert(i+it.row(),j+k) = it.value();
+        }
+      }
+      i += A.rows();
+      j += A.cols();
+    }
+  }
+}
+
+template <typename DerivedY>
+IGL_INLINE void igl::blkdiag(
+  const std::vector<DerivedY> & L, 
+  Eigen::PlainObjectBase<DerivedY> & Y)
+{
+  int nr = 0;
+  int nc = 0;
+  for(const auto & A : L)
+  {
+    nr += A.rows();
+    nc += A.cols();
+  }
+  Y.setZero(nr,nc);
+  {
+    int i = 0;
+    int j = 0;
+    for(const auto & A : L)
+    {
+      Y.block(i,j,A.rows(),A.cols()) = A;
+      i += A.rows();
+      j += A.cols();
+    }
+  }
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// explicit template instantiations
+template void igl::blkdiag<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::blkdiag<double>(std::vector<Eigen::SparseMatrix<double, 0, int>, std::allocator<Eigen::SparseMatrix<double, 0, int> > > const&, Eigen::SparseMatrix<double, 0, int>&);
+#endif

+ 40 - 0
include/igl/blkdiag.h

@@ -0,0 +1,40 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2020 Alec Jacobson <[email protected]>
+// 
+// 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_BLKDIAG_H
+#define IGL_BLKDIAG_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <Eigen/Sparse>
+#include <vector>
+
+namespace igl
+{
+  // Given a list of matrices place them along the diagonal as blocks of the
+  // output matrix. Like matlab's blkdiag.
+  //
+  // Inputs:
+  //   L  list of matrices {A,B, ...}
+  // Outputs:
+  //   Y  A.rows()+B.rows()+... by A.cols()+B.cols()+... block diagonal
+  //
+  // See also: cat, repdiag
+  template <typename Scalar>
+  IGL_INLINE void blkdiag(
+    const std::vector<Eigen::SparseMatrix<Scalar>> & L, 
+    Eigen::SparseMatrix<Scalar> & Y);
+  template <typename DerivedY>
+  IGL_INLINE void blkdiag(
+    const std::vector<DerivedY> & L, 
+    Eigen::PlainObjectBase<DerivedY> & Y);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "blkdiag.cpp"
+#endif
+
+#endif

+ 364 - 0
include/igl/blue_noise.cpp

@@ -0,0 +1,364 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2020 Alec Jacobson <[email protected]>
+// 
+// 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 "blue_noise.h"
+#include "doublearea.h"
+#include "random_points_on_mesh.h"
+#include "slice.h"
+#include "sortrows.h"
+#include "PI.h"
+#include "get_seconds.h"
+#include <unordered_map>
+#include <algorithm>
+#include <vector>
+
+namespace igl
+{
+  // It is very important that we use 64bit keys to avoid out of bounds (easy to
+  // get to happen with dense samplings (e.g., r = 0.0005*bbd)
+  typedef int64_t BlueNoiseKeyType;
+}
+
+// Helper functions
+namespace igl
+{
+  // Should probably find and replace with less generic name
+  //
+  // Map 3D subscripts (x,y,z) to unique index (return value)
+  //
+  // Inputs:
+  //   w  side length of w×w×w integer cube lattice
+  //   x  subscript along x direction
+  //   y  subscript along y direction
+  //   z  subscript along z direction
+  // Returns index value
+  //
+  inline BlueNoiseKeyType blue_noise_key(
+    const BlueNoiseKeyType w, // pass by copy --> int64_t so that multiplication is OK
+    const BlueNoiseKeyType x, // pass by copy --> int64_t so that multiplication is OK
+    const BlueNoiseKeyType y, // pass by copy --> int64_t so that multiplication is OK
+    const BlueNoiseKeyType z) // pass by copy --> int64_t so that multiplication is OK
+  {
+    return x+w*(y+w*z);
+  }
+  // Determine if a query candidate at position X.row(i) is too close to already
+  // selected sites (stored in S).
+  //
+  // Inputs:
+  //   X  #X by 3 list of raw candidate positions
+  //   Xs  #Xs by 3 list of corresponding integer cell subscripts
+  //   i  index of candidate in question
+  //   S   map from cell index to index into X of selected candidate (or -1 if
+  //     cell is currently empty)
+  //   rr  Poisson disk radius squared
+  //   w  side length of w×w×w integer cube lattice (into which Xs subscripts)
+  template <
+    typename DerivedX,
+    typename DerivedXs>
+  inline bool blue_noise_far_enough(
+    const Eigen::MatrixBase<DerivedX> & X,
+    const Eigen::MatrixBase<DerivedXs> & Xs,
+    const std::unordered_map<BlueNoiseKeyType,int> & S,
+    const double & rr,
+    const int & w,
+    const int i)
+  {
+    const int xi = Xs(i,0);
+    const int yi = Xs(i,1);
+    const int zi = Xs(i,2);
+    BlueNoiseKeyType k = blue_noise_key(w,xi,yi,zi);
+    int g = 2; // ceil(r/s)
+    for(int x = std::max(xi-g,0);x<=std::min(xi+g,w-1);x++)
+    for(int y = std::max(yi-g,0);y<=std::min(yi+g,w-1);y++)
+    for(int z = std::max(zi-g,0);z<=std::min(zi+g,w-1);z++)
+    {
+      if(x!=xi || y!=yi || z!=zi)
+      {
+        const BlueNoiseKeyType nk = blue_noise_key(w,x,y,z);
+        // have already selected from this cell
+        const auto Siter = S.find(nk);
+        if(Siter !=S.end() && Siter->second >= 0)
+        {
+          const int ni = Siter->second;
+          // too close
+          if( (X.row(i)-X.row(ni)).squaredNorm() < rr)
+          {
+            return false;
+          }
+        }
+      }
+    }
+    return true;
+  }
+  // Try to activate a candidate in a given cell
+  //
+  // Inputs:
+  //   X  #X by 3 list of raw candidate positions
+  //   Xs  #Xs by 3 list of corresponding integer cell subscripts
+  //   rr  Poisson disk radius squared
+  //   w  side length of w×w×w integer cube lattice (into which Xs subscripts)
+  //   nk  index of cell in which we'd like to activate a candidate
+  //   M   map from cell index to list of candidates
+  //   S   map from cell index to index into X of selected candidate (or -1 if
+  //     cell is currently empty)
+  //   active   list of indices into X of active candidates
+  // Outputs:
+  //   M  visited candidates deemed too close to already selected points are
+  //      removed
+  //   S  updated to reflect activated point (if successful)
+  //   active   updated to reflect activated point (if successful)
+  // Returns true iff activation was successful
+  template <
+    typename DerivedX,
+    typename DerivedXs>
+  inline bool activate(
+    const Eigen::MatrixBase<DerivedX> & X,
+    const Eigen::MatrixBase<DerivedXs> & Xs,
+    const double & rr,
+    const int & i,
+    const int & w,
+    const BlueNoiseKeyType & nk,
+    std::unordered_map<BlueNoiseKeyType,std::vector<int> > & M,
+    std::unordered_map<BlueNoiseKeyType,int> & S,
+    std::vector<int> & active)
+  {
+    auto & Mvec = M.find(nk)->second;
+    auto miter = Mvec.begin();
+    while(miter != Mvec.end())
+    {
+      const int mi = *miter;
+      // mi is our candidate sample. Is it far enough from all existing
+      // samples?
+      if(i>=0 && (X.row(i)-X.row(mi)).squaredNorm() > 4.*rr)
+      {
+        // too far skip (reject)
+       miter++;
+      } else if(blue_noise_far_enough(X,Xs,S,rr,w,mi))
+      {
+        active.push_back(mi);
+        S.find(nk)->second = mi;
+        //printf("  found %d\n",mi);
+        return true;
+      }else
+      {
+        // remove forever (instead of incrementing we swap and eat from the
+        // back)
+        //std::swap(*miter,Mvec.back());
+        *miter = Mvec.back();
+        Mvec.pop_back();
+      }
+    }
+    return false;
+  }
+
+  template <
+    typename DerivedX,
+    typename DerivedXs>
+  inline bool step(
+    const Eigen::MatrixBase<DerivedX> & X,
+    const Eigen::MatrixBase<DerivedXs> & Xs,
+    const double & rr,
+    const int & w,
+    std::unordered_map<BlueNoiseKeyType,std::vector<int> > & M,
+    std::unordered_map<BlueNoiseKeyType,int> & S,
+    std::vector<int> & active,
+    std::vector<int> & collected
+    )
+  {
+    //considered.clear();
+    if(active.size() == 0) return false;
+    // random entry
+    const int e = rand() % active.size();
+    const int i = active[e];
+    //printf("%d\n",i);
+    const int xi = Xs(i,0);
+    const int yi = Xs(i,1);
+    const int zi = Xs(i,2);
+    //printf("%d %d %d - %g %g %g\n",xi,yi,zi,X(i,0),X(i,1),X(i,2));
+    // cell indices of neighbors
+    int g = 4;
+    std::vector<BlueNoiseKeyType> N;N.reserve((1+g*1)^3-1);
+    for(int x = std::max(xi-g,0);x<=std::min(xi+g,w-1);x++)
+    for(int y = std::max(yi-g,0);y<=std::min(yi+g,w-1);y++)
+    for(int z = std::max(zi-g,0);z<=std::min(zi+g,w-1);z++)
+    {
+      if(x!=xi || y!=yi || z!=zi)
+      {
+        //printf("  %d %d %d\n",x,y,z);
+        const BlueNoiseKeyType nk = blue_noise_key(w,x,y,z);
+        // haven't yet selected from this cell?
+        const auto Siter = S.find(nk);
+        if(Siter !=S.end() && Siter->second < 0)
+        {
+          assert(M.find(nk) != M.end());
+          N.emplace_back(nk);
+        }
+      }
+    }
+        //printf("  --------\n");
+    // randomize order: this might be a little paranoid...
+    std::random_shuffle(std::begin(N), std::end(N));
+    bool found = false;
+    for(const BlueNoiseKeyType & nk : N)
+    {
+      assert(M.find(nk) != M.end());
+      if(activate(X,Xs,rr,i,w,nk,M,S,active))
+      {
+        found = true;
+        break;
+      }
+    }
+    if(!found)
+    {
+      // remove i from active list
+      // https://stackoverflow.com/a/60765833/148668
+      collected.push_back(i);
+      //printf("  before: "); for(const int j : active) { printf("%d ",j); } printf("\n");
+      std::swap(active[e], active.back());
+      //printf("  after : "); for(const int j : active) { printf("%d ",j); } printf("\n");
+      active.pop_back();
+      //printf("  removed %d\n",i);
+    }
+    //printf("  active: "); for(const int j : active) { printf("%d ",j); } printf("\n");
+    return true;
+  }
+}
+
+template <
+  typename DerivedV,
+  typename DerivedF,
+  typename DerivedB,
+  typename DerivedFI,
+  typename DerivedP>
+IGL_INLINE void igl::blue_noise(
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedF> & F,
+    const typename DerivedV::Scalar r,
+    Eigen::PlainObjectBase<DerivedB> & B,
+    Eigen::PlainObjectBase<DerivedFI> & FI,
+    Eigen::PlainObjectBase<DerivedP> & P)
+{
+  typedef typename DerivedV::Scalar Scalar;
+  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1> VectorXS;
+  // float+RowMajor is faster...
+  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,3,Eigen::RowMajor> MatrixX3S;
+  assert(V.cols() == 3 && "Only 3D embeddings allowed");
+  // minimum radius
+  const Scalar min_r = r;
+  // cell size based on 3D distance
+  // It works reasonably well (but is probably biased to use s=2*r/√3 here and
+  // g=1 in the outer loop below.
+  //
+  // One thing to try would be to store a list in S (rather than a single point)
+  // or equivalently a mask over M and just use M as a generic spatial hash
+  // (with arbitrary size) and then tune its size (being careful to make g a
+  // function of r and s; and removing the `if S=-1 checks`)
+  const Scalar s = r/sqrt(3.0);
+
+  const double area = 
+    [&](){Eigen::VectorXd A;igl::doublearea(V,F,A);return A.array().sum()/2;}();
+  // Circle packing in the plane has igl::PI*sqrt(3)/6 efficiency
+  const double expected_number_of_points = 
+    area * (igl::PI * sqrt(3.0) / 6.0) / (igl::PI * min_r * min_r / 4.0);
+
+  // Make a uniform random sampling with 30*expected_number_of_points.
+  const int nx = 30.0*expected_number_of_points;
+  MatrixX3S X,XB;
+  Eigen::VectorXi XFI;
+  igl::random_points_on_mesh(nx,V,F,XB,XFI,X);
+
+  // Rescale so that s = 1
+  Eigen::Matrix<int,Eigen::Dynamic,3,Eigen::RowMajor> Xs = 
+    ((X.rowwise()-X.colwise().minCoeff())/s).template cast<int>();
+  const int w = Xs.maxCoeff()+1;
+  {
+    Eigen::VectorXi I;
+    igl::sortrows(decltype(Xs)(Xs),true,Xs,I);
+    igl::slice(decltype(X)(X),I,1,X);
+    // These two could be spun off in their own thread.
+    igl::slice(decltype(XB)(XB),I,1,XB);
+    igl::slice(decltype(XFI)(XFI),I,1,XFI);
+  }
+  // Initialization
+  std::unordered_map<BlueNoiseKeyType,std::vector<int> > M;
+  std::unordered_map<BlueNoiseKeyType, int > S;
+  // attempted to seed
+  std::unordered_map<BlueNoiseKeyType, int > A;
+  // Q: Too many?
+  // A: Seems to help though.
+  M.reserve(Xs.rows());
+  S.reserve(Xs.rows());
+  for(int i = 0;i<Xs.rows();i++)
+  {
+    BlueNoiseKeyType k = blue_noise_key(w,Xs(i,0),Xs(i,1),Xs(i,2)); 
+    const auto Miter = M.find(k);
+    if(Miter  == M.end())
+    {
+      M.insert({k,{i}});
+    }else
+    {
+      Miter->second.push_back(i);
+    }
+    S.emplace(k,-1);
+    A.emplace(k,false);
+  }
+
+  std::vector<int> active;
+  // precompute r²
+  // Q: is this necessary? 
+  const double rr = r*r;
+  std::vector<int> collected;
+  collected.reserve(2.0*expected_number_of_points);
+
+  auto Mouter = M.begin();
+  // Just take the first point as the initial seed
+  const auto initialize = [&]()->bool
+  {
+    while(true)
+    {
+      if(Mouter == M.end())
+      {
+        return false;
+      }
+      const BlueNoiseKeyType k = Mouter->first;
+      // Haven't placed in this cell yet
+      if(S[k]<0)
+      {
+        if(activate(X,Xs,rr,-1,w,k,M,S,active)) return true;
+      }
+      Mouter++;
+    }
+    assert(false && "should not be reachable.");
+  };
+
+  // important if mesh contains many connected components
+  while(initialize())
+  {
+    while(active.size()>0)
+    {
+      step(X,Xs,rr,w,M,S,active,collected);
+    }
+  }
+  {
+    const int n = collected.size();
+    P.resize(n,3);
+    B.resize(n,3);
+    FI.resize(n);
+    for(int i = 0;i<n;i++)
+    {
+      const int c = collected[i];
+      P.row(i) = X.row(c).template cast<typename DerivedP::Scalar>();
+      B.row(i) = XB.row(c).template cast<typename DerivedB::Scalar>();
+      FI(i) = XFI(c);
+    }
+  }
+}
+
+#ifdef IGL_STATIC_LIBRARY
+template void igl::blue_noise<Eigen::Matrix<float, -1, 3, 1, -1, 3>, 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::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<float, -1, 3, 1, -1, 3>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::blue_noise<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+#endif

+ 49 - 0
include/igl/blue_noise.h

@@ -0,0 +1,49 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2020 Alec Jacobson <[email protected]>
+// 
+// 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_BLUE_NOISE_H
+#define IGL_BLUE_NOISE_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  // "Fast Poisson Disk Sampling in Arbitrary Dimensions" [Bridson 2007]
+  //
+  // For very dense samplings this is faster than (up to 2x) cyCodeBase's
+  // implementation of "Sample Elimination for Generating Poisson Disk Sample
+  // Sets" [Yuksel 2015]. YMMV
+  //
+  // Inputs:
+  //   V  #V by dim list of mesh vertex positions
+  //   F  #F by 3 list of mesh triangle indices into rows of V
+  //   r  Poisson disk radius (evaluated according to Euclidean distance on V)
+  // Outputs:
+  //   B  #P by 3 list of barycentric coordinates, ith row are coordinates of
+  //     ith sampled point in face FI(i)
+  //   FI  #P list of indices into F 
+  //   P  #P by dim list of sample positions.
+  // See also: random_points_on_mesh
+  template <
+    typename DerivedV,
+    typename DerivedF,
+    typename DerivedB,
+    typename DerivedFI,
+    typename DerivedP>
+  IGL_INLINE void blue_noise(
+      const Eigen::MatrixBase<DerivedV> & V,
+      const Eigen::MatrixBase<DerivedF> & F,
+      const typename DerivedV::Scalar r,
+      Eigen::PlainObjectBase<DerivedB> & B,
+      Eigen::PlainObjectBase<DerivedFI> & FI,
+      Eigen::PlainObjectBase<DerivedP> & P);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "blue_noise.cpp"
+#endif
+
+#endif

+ 2 - 2
include/igl/bone_parents.cpp

@@ -9,7 +9,7 @@
 
 template <typename DerivedBE, typename DerivedP>
 IGL_INLINE void igl::bone_parents(
-  const Eigen::PlainObjectBase<DerivedBE>& BE,
+  const Eigen::MatrixBase<DerivedBE>& BE,
   Eigen::PlainObjectBase<DerivedP>& P)
 {
   P.resize(BE.rows(),1);
@@ -28,5 +28,5 @@ IGL_INLINE void igl::bone_parents(
 }
 
 #ifdef IGL_STATIC_LIBRARY
-template void igl::bone_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::bone_parents<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 1 - 1
include/igl/bone_parents.h

@@ -20,7 +20,7 @@ namespace igl
   //
   template <typename DerivedBE, typename DerivedP>
   IGL_INLINE void bone_parents(
-    const Eigen::PlainObjectBase<DerivedBE>& BE,
+    const Eigen::MatrixBase<DerivedBE>& BE,
     Eigen::PlainObjectBase<DerivedP>& P);
 }
 

+ 3 - 3
include/igl/boundary_loop.cpp

@@ -24,12 +24,12 @@ IGL_INLINE void igl::boundary_loop(
     return;
 
   VectorXd Vdummy(F.maxCoeff()+1,1);
-  DerivedF TT,TTi;
+  Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, Eigen::Dynamic> TT,TTi;
   vector<std::vector<int> > VF, VFi;
   triangle_triangle_adjacency(F,TT,TTi);
   vertex_triangle_adjacency(Vdummy,F,VF,VFi);
 
-  vector<bool> unvisited = is_border_vertex(Vdummy,F);
+  vector<bool> unvisited = is_border_vertex(F);
   set<int> unseen;
   for (size_t i = 0; i < unvisited.size(); ++i)
   {
@@ -142,7 +142,7 @@ IGL_INLINE void igl::boundary_loop(
   vector<int> Lvec;
   boundary_loop(F,Lvec);
 
-  L.resize(Lvec.size());
+  L.resize(Lvec.size(), 1);
   for (size_t i = 0; i < Lvec.size(); ++i)
     L(i) = Lvec[i];
 }

+ 2 - 0
include/igl/bounding_box.cpp

@@ -93,6 +93,8 @@ IGL_INLINE void igl::bounding_box(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::bounding_box<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
 template void igl::bounding_box<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 // generated by autoexplicit.sh
 template void igl::bounding_box<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::Matrix<double, -1, -1, 1, -1, -1>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);

+ 4 - 0
include/igl/cat.cpp

@@ -313,6 +313,8 @@ IGL_INLINE void igl::cat(const int dim, const std::vector<T> & A, Eigen::PlainOb
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::cat<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<float, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<float, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
 template Eigen::Matrix<double, -1, -1, 0, -1, -1> igl::cat<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&);
 // generated by autoexplicit.sh
 template Eigen::SparseMatrix<double, 0, int> igl::cat<Eigen::SparseMatrix<double, 0, int> >(int, Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int> const&);
@@ -333,4 +335,6 @@ template void igl::cat<Eigen::Matrix<int, 1, 3, 1, 1, 3>, Eigen::Matrix<int, -1,
 template void igl::cat<Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, 3, 1, 0, 3, 1>, std::allocator<Eigen::Matrix<int, 3, 1, 0, 3, 1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::cat<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<double, 1, 3, 1, 1, 3>, std::allocator<Eigen::Matrix<double, 1, 3, 1, 1, 3> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 template void igl::cat<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, 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::cat<Eigen::Matrix<int, 1, -1, 1, 1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<int, 1, -1, 1, 1, -1>, std::allocator<Eigen::Matrix<int, 1, -1, 1, 1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::cat<Eigen::Matrix<double, 1, 2, 1, 1, 2>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, std::vector<Eigen::Matrix<double, 1, 2, 1, 1, 2>, std::allocator<Eigen::Matrix<double, 1, 2, 1, 1, 2> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 1 - 0
include/igl/cat.h

@@ -12,6 +12,7 @@
 #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
 #include <Eigen/Sparse>
 #include <Eigen/Dense>
+#include <vector>
 
 namespace igl
 {

+ 4 - 0
include/igl/centroid.cpp

@@ -62,6 +62,10 @@ IGL_INLINE void igl::centroid(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::centroid<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 3, 1, 0, 3, 1>, float>(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&, float&);
+// generated by autoexplicit.sh
+template void igl::centroid<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&);
+// generated by autoexplicit.sh
 template void igl::centroid<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> >&);
 template void igl::centroid<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
 template void igl::centroid<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);

+ 74 - 0
include/igl/circulation.cpp

@@ -67,3 +67,77 @@ IGL_INLINE void igl::circulation(
   std::vector<int> N = circulation(e,ccw,EMAP,EF,EI);
   igl::list_to_matrix(N,vN);
 }
+
+IGL_INLINE void igl::circulation(
+  const int e,
+  const bool ccw,
+  const Eigen::MatrixXi & F,
+  const Eigen::VectorXi & EMAP,
+  const Eigen::MatrixXi & EF,
+  const Eigen::MatrixXi & EI,
+  /*std::vector<int> & Ne,*/
+  std::vector<int> & Nv,
+  std::vector<int> & Nf)
+{
+  //
+  // for e --> (bf) and ccw=true
+  //
+  //     c---d
+  //    / \ / \
+  //   a---b-e-f
+  //    \ / \ /
+  //     g---h
+  //
+  //  // (might start with {bhf} depending on edge)
+  //  Ne = […] -> [fd db dc cb ca ab ag gb gh hb hf fb]
+  //              {upto cylic order}
+  //  Nf = […] -> [{bfd}, {bdc}, {bca}, {bag}, {bgh}, {bhf}]
+  //  Nv = [d c a g h f]
+  //
+  // prepare output
+  //Ne.clear();Ne.reserve(2*10);
+  Nv.clear();Nv.reserve(10);
+  Nf.clear();Nf.reserve(10);
+  const int m = EMAP.size()/3;
+  assert(m*3 == EMAP.size());
+  const auto & step = [&](
+    const int e, 
+    const int ff,
+    int & ne, 
+    //int & re,
+    int & rv,
+    int & nf)
+  {
+    assert((EF(e,1) == ff || EF(e,0) == ff) && "e should touch ff");
+    //const int fside = EF(e,1)==ff?1:0;
+    const int nside = EF(e,0)==ff?1:0;
+    const int nv = EI(e,nside);
+    // get next face
+    nf = EF(e,nside);
+    // get next edge 
+    const int dir = ccw?-1:1;
+    rv = F(nf,nv);
+    ne = EMAP(nf+m*((nv+dir+3)%3));
+    //re = EMAP(nf+m*((nv+2*dir+3)%3));
+  };
+  // Always start with first face (ccw in step will be sure to turn right
+  // direction)
+  const int f0 = EF(e,0);
+  int fi = f0;
+  int ei = e;
+  while(true)
+  {
+    int re,rv;
+    step(ei,fi,ei/*,re*/,rv,fi);
+    Nf.push_back(fi);
+    //Ne.push_back(re);
+    //Ne.push_back(ei);
+    Nv.push_back(rv);
+    // back to start?
+    if(fi == f0)
+    {
+      assert(ei == e);
+      break;
+    }
+  }
+}

+ 14 - 0
include/igl/circulation.h

@@ -43,6 +43,20 @@ namespace igl
     const Eigen::MatrixXi & EF,
     const Eigen::MatrixXi & EI,
     Eigen::VectorXi & vN);
+  // Outputs:
+  ////   Ne  2*#Nf list of indices into E of "next" rim-spoke-rim-spoke-...
+  //   Nv  #Nv list of "next" vertex indices
+  //   Nf  #Nf list of face indices
+  IGL_INLINE void circulation(
+    const int e,
+    const bool ccw,
+    const Eigen::MatrixXi & F,
+    const Eigen::VectorXi & EMAP,
+    const Eigen::MatrixXi & EF,
+    const Eigen::MatrixXi & EI,
+    /*std::vector<int> & Ne,*/
+    std::vector<int> & Nv,
+    std::vector<int> & Nf);
 }
 
 #ifndef IGL_STATIC_LIBRARY

+ 6 - 2
include/igl/circumradius.cpp

@@ -13,8 +13,8 @@ template <
   typename DerivedF,
   typename DerivedR>
 IGL_INLINE void igl::circumradius(
-  const Eigen::PlainObjectBase<DerivedV> & V, 
-  const Eigen::PlainObjectBase<DerivedF> & F,
+  const Eigen::MatrixBase<DerivedV> & V, 
+  const Eigen::MatrixBase<DerivedF> & F,
   Eigen::PlainObjectBase<DerivedR> & R)
 {
   Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,3> l;
@@ -24,3 +24,7 @@ IGL_INLINE void igl::circumradius(
   // use formula: R=abc/(4*area) to compute the circum radius
   R = l.col(0).array() * l.col(1).array() * l.col(2).array() / (2.0*A.array());
 }
+
+#ifdef IGL_STATIC_LIBRARY
+template void igl::circumradius<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+#endif

+ 3 - 3
include/igl/circumradius.h

@@ -17,15 +17,15 @@ namespace igl
   //   V  #V by dim list of mesh vertex positions
   //   F  #F by 3 list of triangle indices into V
   // Outputs:
-  //   R  #F list of circumradii
+  //   R  #F list of circumradius
   //
   template <
     typename DerivedV, 
     typename DerivedF,
     typename DerivedR>
   IGL_INLINE void circumradius(
-    const Eigen::PlainObjectBase<DerivedV> & V, 
-    const Eigen::PlainObjectBase<DerivedF> & F,
+    const Eigen::MatrixBase<DerivedV> & V, 
+    const Eigen::MatrixBase<DerivedF> & F,
     Eigen::PlainObjectBase<DerivedR> & R);
 }
 #ifndef IGL_STATIC_LIBRARY

+ 159 - 180
include/igl/collapse_edge.cpp

@@ -8,6 +8,7 @@
 #include "collapse_edge.h"
 #include "circulation.h"
 #include "edge_collapse_is_valid.h"
+#include "decimate_trivial_callbacks.h"
 #include <vector>
 
 IGL_INLINE bool igl::collapse_edge(
@@ -19,6 +20,32 @@ IGL_INLINE bool igl::collapse_edge(
   Eigen::VectorXi & EMAP,
   Eigen::MatrixXi & EF,
   Eigen::MatrixXi & EI,
+  int & e1,
+  int & e2,
+  int & f1,
+  int & f2)
+{
+  std::vector<int> /*Nse,*/Nsf,Nsv;
+  circulation(e, true,F,EMAP,EF,EI,/*Nse,*/Nsv,Nsf);
+  std::vector<int> /*Nde,*/Ndf,Ndv;
+  circulation(e, false,F,EMAP,EF,EI,/*Nde,*/Ndv,Ndf);
+  return collapse_edge(
+    e,p,Nsv,Nsf,Ndv,Ndf,V,F,E,EMAP,EF,EI,e1,e2,f1,f2);
+}
+
+IGL_INLINE bool igl::collapse_edge(
+  const int e,
+  const Eigen::RowVectorXd & p,
+  /*const*/ std::vector<int> & Nsv,
+  const std::vector<int> & Nsf,
+  /*const*/ std::vector<int> & Ndv,
+  const std::vector<int> & Ndf,
+  Eigen::MatrixXd & V,
+  Eigen::MatrixXi & F,
+  Eigen::MatrixXi & E,
+  Eigen::VectorXi & EMAP,
+  Eigen::MatrixXi & EF,
+  Eigen::MatrixXi & EI,
   int & a_e1,
   int & a_e2,
   int & a_f1,
@@ -34,17 +61,19 @@ IGL_INLINE bool igl::collapse_edge(
   const int s = eflip?E(e,1):E(e,0);
   const int d = eflip?E(e,0):E(e,1);
 
-  if(!edge_collapse_is_valid(e,F,E,EMAP,EF,EI))
+  if(!edge_collapse_is_valid(Nsv,Ndv))
   {
     return false;
   }
 
+  // OVERLOAD: caller may have just computed this
+  //
   // Important to grab neighbors of d before monkeying with edges
-  const std::vector<int> nV2Fd = circulation(e,!eflip,EMAP,EF,EI);
+  const std::vector<int> & nV2Fd = (!eflip ? Nsf : Ndf);
 
   // The following implementation strongly relies on s<d
   assert(s<d && "s should be less than d");
-  // move source and destination to midpoint
+  // move source and destination to placement
   V.row(s) = p;
   V.row(d) = p;
 
@@ -112,31 +141,40 @@ IGL_INLINE bool igl::collapse_edge(
   // make sense.
   //
   // Could actually skip first and last, since those are always the two
-  // collpased faces.
-  for(auto f : nV2Fd)
+  // collpased faces. Nah, this is handled by (F(f,v) == d)
+  //
+  // Don't attempt to use Nde,Nse here because EMAP has changed
   {
-    for(int v = 0;v<3;v++)
+    int p1 = -1;
+    for(auto f : nV2Fd)
     {
-      if(F(f,v) == d)
+      for(int v = 0;v<3;v++)
       {
-        const int flip1 = (EF(EMAP(f+m*((v+1)%3)),0)==f)?1:0;
-        const int flip2 = (EF(EMAP(f+m*((v+2)%3)),0)==f)?0:1;
-        assert(
-          E(EMAP(f+m*((v+1)%3)),flip1) == d ||
-          E(EMAP(f+m*((v+1)%3)),flip1) == s);
-        E(EMAP(f+m*((v+1)%3)),flip1) = s;
-        assert(
-          E(EMAP(f+m*((v+2)%3)),flip2) == d ||
-          E(EMAP(f+m*((v+2)%3)),flip2) == s);
-        E(EMAP(f+m*((v+2)%3)),flip2) = s;
-        F(f,v) = s;
-        break;
+        if(F(f,v) == d)
+        {
+          const int e1 = EMAP(f+m*((v+1)%3));
+          const int flip1 = (EF(e1,0)==f)?1:0;
+          assert( E(e1,flip1) == d || E(e1,flip1) == s);
+          E(e1,flip1) = s;
+          const int e2 = EMAP(f+m*((v+2)%3));
+          // Skip if we just handled this edge (claim: this will be all except
+          // for the first non-trivial face)
+          if(e2 != p1)
+          {
+            const int flip2 = (EF(e2,0)==f)?0:1;
+            assert( E(e2,flip2) == d || E(e2,flip2) == s);
+            E(e2,flip2) = s;
+          }
+
+          F(f,v) = s;
+          p1 = e1;
+          break;
+        }
       }
     }
   }
   // Finally, "remove" this edge and its information
   kill_edge(e);
-
   return true;
 }
 
@@ -155,168 +193,61 @@ IGL_INLINE bool igl::collapse_edge(
 }
 
 IGL_INLINE bool igl::collapse_edge(
-  const std::function<void(
-    const int,
-    const Eigen::MatrixXd &,
-    const Eigen::MatrixXi &,
-    const Eigen::MatrixXi &,
-    const Eigen::VectorXi &,
-    const Eigen::MatrixXi &,
-    const Eigen::MatrixXi &,
-    double &,
-    Eigen::RowVectorXd &)> & cost_and_placement,
+  const decimate_cost_and_placement_callback & cost_and_placement,
   Eigen::MatrixXd & V,
   Eigen::MatrixXi & F,
   Eigen::MatrixXi & E,
   Eigen::VectorXi & EMAP,
   Eigen::MatrixXi & EF,
   Eigen::MatrixXi & EI,
-  std::set<std::pair<double,int> > & Q,
-  std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
+  igl::min_heap< std::tuple<double,int,int> > & Q,
+  Eigen::VectorXi & EQ,
   Eigen::MatrixXd & C)
 {
   int e,e1,e2,f1,f2;
-  const auto always_try = [](
-    const Eigen::MatrixXd &                                         ,/*V*/
-    const Eigen::MatrixXi &                                         ,/*F*/
-    const Eigen::MatrixXi &                                         ,/*E*/
-    const Eigen::VectorXi &                                         ,/*EMAP*/
-    const Eigen::MatrixXi &                                         ,/*EF*/
-    const Eigen::MatrixXi &                                         ,/*EI*/
-    const std::set<std::pair<double,int> > &                        ,/*Q*/
-    const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
-    const Eigen::MatrixXd &                                         ,/*C*/
-    const int                                                        /*e*/
-    ) -> bool { return true;};
-  const auto never_care = [](
-    const Eigen::MatrixXd &                                         ,   /*V*/
-    const Eigen::MatrixXi &                                         ,   /*F*/
-    const Eigen::MatrixXi &                                         ,   /*E*/
-    const Eigen::VectorXi &                                         ,/*EMAP*/
-    const Eigen::MatrixXi &                                         ,  /*EF*/
-    const Eigen::MatrixXi &                                         ,  /*EI*/
-    const std::set<std::pair<double,int> > &                        ,   /*Q*/
-    const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
-    const Eigen::MatrixXd &                                         ,   /*C*/
-    const int                                                       ,   /*e*/
-    const int                                                       ,  /*e1*/
-    const int                                                       ,  /*e2*/
-    const int                                                       ,  /*f1*/
-    const int                                                       ,  /*f2*/
-    const bool                                                  /*collapsed*/
-    )-> void { };
+  decimate_pre_collapse_callback always_try;
+  decimate_post_collapse_callback never_care;
+  decimate_trivial_callbacks(always_try,never_care);
   return 
     collapse_edge(
       cost_and_placement,always_try,never_care,
-      V,F,E,EMAP,EF,EI,Q,Qit,C,e,e1,e2,f1,f2);
+      V,F,E,EMAP,EF,EI,Q,EQ,C,e,e1,e2,f1,f2);
 }
 
 IGL_INLINE bool igl::collapse_edge(
-  const std::function<void(
-    const int,
-    const Eigen::MatrixXd &,
-    const Eigen::MatrixXi &,
-    const Eigen::MatrixXi &,
-    const Eigen::VectorXi &,
-    const Eigen::MatrixXi &,
-    const Eigen::MatrixXi &,
-    double &,
-    Eigen::RowVectorXd &)> & cost_and_placement,
-  const std::function<bool(
-    const Eigen::MatrixXd &                                         ,/*V*/
-    const Eigen::MatrixXi &                                         ,/*F*/
-    const Eigen::MatrixXi &                                         ,/*E*/
-    const Eigen::VectorXi &                                         ,/*EMAP*/
-    const Eigen::MatrixXi &                                         ,/*EF*/
-    const Eigen::MatrixXi &                                         ,/*EI*/
-    const std::set<std::pair<double,int> > &                        ,/*Q*/
-    const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
-    const Eigen::MatrixXd &                                         ,/*C*/
-    const int                                                        /*e*/
-    )> & pre_collapse,
-  const std::function<void(
-    const Eigen::MatrixXd &                                         ,   /*V*/
-    const Eigen::MatrixXi &                                         ,   /*F*/
-    const Eigen::MatrixXi &                                         ,   /*E*/
-    const Eigen::VectorXi &                                         ,/*EMAP*/
-    const Eigen::MatrixXi &                                         ,  /*EF*/
-    const Eigen::MatrixXi &                                         ,  /*EI*/
-    const std::set<std::pair<double,int> > &                        ,   /*Q*/
-    const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
-    const Eigen::MatrixXd &                                         ,   /*C*/
-    const int                                                       ,   /*e*/
-    const int                                                       ,  /*e1*/
-    const int                                                       ,  /*e2*/
-    const int                                                       ,  /*f1*/
-    const int                                                       ,  /*f2*/
-    const bool                                                  /*collapsed*/
-    )> & post_collapse,
+  const decimate_cost_and_placement_callback & cost_and_placement,
+  const decimate_pre_collapse_callback       & pre_collapse,
+  const decimate_post_collapse_callback      & post_collapse,
   Eigen::MatrixXd & V,
   Eigen::MatrixXi & F,
   Eigen::MatrixXi & E,
   Eigen::VectorXi & EMAP,
   Eigen::MatrixXi & EF,
   Eigen::MatrixXi & EI,
-  std::set<std::pair<double,int> > & Q,
-  std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
+  igl::min_heap< std::tuple<double,int,int> > & Q,
+  Eigen::VectorXi & EQ,
   Eigen::MatrixXd & C)
 {
   int e,e1,e2,f1,f2;
   return 
     collapse_edge(
       cost_and_placement,pre_collapse,post_collapse,
-      V,F,E,EMAP,EF,EI,Q,Qit,C,e,e1,e2,f1,f2);
+      V,F,E,EMAP,EF,EI,Q,EQ,C,e,e1,e2,f1,f2);
 }
 
 
 IGL_INLINE bool igl::collapse_edge(
-  const std::function<void(
-    const int,
-    const Eigen::MatrixXd &,
-    const Eigen::MatrixXi &,
-    const Eigen::MatrixXi &,
-    const Eigen::VectorXi &,
-    const Eigen::MatrixXi &,
-    const Eigen::MatrixXi &,
-    double &,
-    Eigen::RowVectorXd &)> & cost_and_placement,
-  const std::function<bool(
-    const Eigen::MatrixXd &                                         ,/*V*/
-    const Eigen::MatrixXi &                                         ,/*F*/
-    const Eigen::MatrixXi &                                         ,/*E*/
-    const Eigen::VectorXi &                                         ,/*EMAP*/
-    const Eigen::MatrixXi &                                         ,/*EF*/
-    const Eigen::MatrixXi &                                         ,/*EI*/
-    const std::set<std::pair<double,int> > &                        ,/*Q*/
-    const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
-    const Eigen::MatrixXd &                                         ,/*C*/
-    const int                                                        /*e*/
-    )> & pre_collapse,
-  const std::function<void(
-    const Eigen::MatrixXd &                                         ,   /*V*/
-    const Eigen::MatrixXi &                                         ,   /*F*/
-    const Eigen::MatrixXi &                                         ,   /*E*/
-    const Eigen::VectorXi &                                         ,/*EMAP*/
-    const Eigen::MatrixXi &                                         ,  /*EF*/
-    const Eigen::MatrixXi &                                         ,  /*EI*/
-    const std::set<std::pair<double,int> > &                        ,   /*Q*/
-    const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
-    const Eigen::MatrixXd &                                         ,   /*C*/
-    const int                                                       ,   /*e*/
-    const int                                                       ,  /*e1*/
-    const int                                                       ,  /*e2*/
-    const int                                                       ,  /*f1*/
-    const int                                                       ,  /*f2*/
-    const bool                                                  /*collapsed*/
-    )> & post_collapse,
+  const decimate_cost_and_placement_callback & cost_and_placement,
+  const decimate_pre_collapse_callback       & pre_collapse,
+  const decimate_post_collapse_callback      & post_collapse,
   Eigen::MatrixXd & V,
   Eigen::MatrixXi & F,
   Eigen::MatrixXi & E,
   Eigen::VectorXi & EMAP,
   Eigen::MatrixXi & EF,
   Eigen::MatrixXi & EI,
-  std::set<std::pair<double,int> > & Q,
-  std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
+  igl::min_heap< std::tuple<double,int,int> > & Q,
+  Eigen::VectorXi & EQ,
   Eigen::MatrixXd & C,
   int & e,
   int & e1,
@@ -325,43 +256,82 @@ IGL_INLINE bool igl::collapse_edge(
   int & f2)
 {
   using namespace Eigen;
-  if(Q.empty())
+  using namespace igl;
+  std::tuple<double,int,int> p;
+  while(true)
   {
-    // no edges to collapse
-    return false;
-  }
-  std::pair<double,int> p = *(Q.begin());
-  if(p.first == std::numeric_limits<double>::infinity())
-  {
-    // min cost edge is infinite cost
-    return false;
+    // Check if Q is empty
+    if(Q.empty())
+    {
+      // no edges to collapse
+      e = -1;
+      return false;
+    }
+    // pop from Q
+    p = Q.top();
+    if(std::get<0>(p) == std::numeric_limits<double>::infinity())
+    {
+      e = -1;
+      // min cost edge is infinite cost
+      return false;
+    }
+    Q.pop();
+    e = std::get<1>(p);
+    // Check if matches timestamp
+    if(std::get<2>(p) == EQ(e))
+    {
+      break;
+    }
+    // must be stale or dead.
+    assert(std::get<2>(p)  < EQ(e) || EQ(e) == -1);
+    // try again.
   }
-  Q.erase(Q.begin());
-  e = p.second;
-  Qit[e] = Q.end();
-  std::vector<int> N  = circulation(e, true,EMAP,EF,EI);
-  std::vector<int> Nd = circulation(e,false,EMAP,EF,EI);
-  N.insert(N.begin(),Nd.begin(),Nd.end());
+
+  // Why is this computed up here?
+  // If we just need original face neighbors of edge, could we gather that more
+  // directly than gathering face neighbors of each vertex?
+  std::vector<int> /*Nse,*/Nsf,Nsv;
+  circulation(e, true,F,EMAP,EF,EI,/*Nse,*/Nsv,Nsf);
+  std::vector<int> /*Nde,*/Ndf,Ndv;
+  circulation(e, false,F,EMAP,EF,EI,/*Nde,*/Ndv,Ndf);
+
+
   bool collapsed = true;
-  if(pre_collapse(V,F,E,EMAP,EF,EI,Q,Qit,C,e))
+  if(pre_collapse(V,F,E,EMAP,EF,EI,Q,EQ,C,e))
   {
-    collapsed = collapse_edge(e,C.row(e),V,F,E,EMAP,EF,EI,e1,e2,f1,f2);
+    collapsed = collapse_edge(
+      e,C.row(e),
+      Nsv,Nsf,Ndv,Ndf,
+      V,F,E,EMAP,EF,EI,e1,e2,f1,f2);
   }else
   {
     // Aborted by pre collapse callback
     collapsed = false;
   }
-  post_collapse(V,F,E,EMAP,EF,EI,Q,Qit,C,e,e1,e2,f1,f2,collapsed);
+  post_collapse(V,F,E,EMAP,EF,EI,Q,EQ,C,e,e1,e2,f1,f2,collapsed);
   if(collapsed)
   {
-    // Erase the two, other collapsed edges
-    Q.erase(Qit[e1]);
-    Qit[e1] = Q.end();
-    Q.erase(Qit[e2]);
-    Qit[e2] = Q.end();
+    // Erase the two, other collapsed edges by marking their timestamps as -1
+    EQ(e1) = -1;
+    EQ(e2) = -1;
+    // TODO: visits edges multiple times, ~150% more updates than should
+    //
     // update local neighbors
     // loop over original face neighbors
-    for(auto n : N)
+    //
+    // Can't use previous computed Nse and Nde because those refer to EMAP
+    // before it was changed...
+    std::vector<int> Nf;
+    Nf.reserve( Nsf.size() + Ndf.size() ); // preallocate memory
+    Nf.insert( Nf.end(), Nsf.begin(), Nsf.end() );
+    Nf.insert( Nf.end(), Ndf.begin(), Ndf.end() );
+    // https://stackoverflow.com/a/1041939/148668
+    std::sort( Nf.begin(), Nf.end() );
+    Nf.erase( std::unique( Nf.begin(), Nf.end() ), Nf.end() );
+    // Collect all edges that must be updated
+    std::vector<int> Ne;
+    Ne.reserve(3*Nf.size());
+    for(auto & n : Nf)
     {
       if(F(n,0) != IGL_COLLAPSE_EDGE_NULL ||
           F(n,1) != IGL_COLLAPSE_EDGE_NULL ||
@@ -371,24 +341,33 @@ IGL_INLINE bool igl::collapse_edge(
         {
           // get edge id
           const int ei = EMAP(v*F.rows()+n);
-          // erase old entry
-          Q.erase(Qit[ei]);
-          // compute cost and potential placement
-          double cost;
-          RowVectorXd place;
-          cost_and_placement(ei,V,F,E,EMAP,EF,EI,cost,place);
-          // Replace in queue
-          Qit[ei] = Q.insert(std::pair<double,int>(cost,ei)).first;
-          C.row(ei) = place;
+          Ne.push_back(ei);
         }
       }
     }
+    // Only process edge once
+    std::sort( Ne.begin(), Ne.end() );
+    Ne.erase( std::unique( Ne.begin(), Ne.end() ), Ne.end() );
+    for(auto & ei : Ne)
+    {
+       // compute cost and potential placement
+       double cost;
+       RowVectorXd place;
+       cost_and_placement(ei,V,F,E,EMAP,EF,EI,cost,place);
+       // Increment timestamp
+       EQ(ei)++;
+       // Replace in queue
+       Q.emplace(cost,ei,EQ(ei));
+       C.row(ei) = place;
+    }
   }else
   {
     // reinsert with infinite weight (the provided cost function must **not**
     // have given this un-collapsable edge inf cost already)
-    p.first = std::numeric_limits<double>::infinity();
-    Qit[e] = Q.insert(p).first;
+    // Increment timestamp
+    EQ(e)++;
+    // Replace in queue
+    Q.emplace(std::numeric_limits<double>::infinity(),e,EQ(e));
   }
   return collapsed;
 }

+ 42 - 97
include/igl/collapse_edge.h

@@ -8,6 +8,8 @@
 #ifndef IGL_COLLAPSE_EDGE_H
 #define IGL_COLLAPSE_EDGE_H
 #include "igl_inline.h"
+#include "min_heap.h"
+#include "decimate_callback_types.h"
 #include <Eigen/Core>
 #include <vector>
 #include <set>
@@ -55,6 +57,24 @@ namespace igl
     int & e2,
     int & f1,
     int & f2);
+  // Inputs:
+  IGL_INLINE bool collapse_edge(
+    const int e,
+    const Eigen::RowVectorXd & p,
+    /*const*/ std::vector<int> & Nsv,
+    const std::vector<int> & Nsf,
+    /*const*/ std::vector<int> & Ndv,
+    const std::vector<int> & Ndf,
+    Eigen::MatrixXd & V,
+    Eigen::MatrixXi & F,
+    Eigen::MatrixXi & E,
+    Eigen::VectorXi & EMAP,
+    Eigen::MatrixXi & EF,
+    Eigen::MatrixXi & EI,
+    int & e1,
+    int & e2,
+    int & f1,
+    int & f2);
   IGL_INLINE bool collapse_edge(
     const int e,
     const Eigen::RowVectorXd & p,
@@ -73,28 +93,19 @@ namespace igl
   //     **If the edges is collapsed** then this function will be called on all
   //     edges of all faces previously incident on the endpoints of the
   //     collapsed edge.
-  //   Q  queue containing pairs of costs and edge indices
-  //   Qit  list of iterators so that Qit[e] --> iterator of edge e in Q
+  //   Q  queue containing pairs of costs and edge indices and insertion "time"
+  //   EQ  #E list of "time" of last time pushed into Q
   //   C  #E by dim list of stored placements
   IGL_INLINE bool collapse_edge(
-    const std::function<void(
-      const int,
-      const Eigen::MatrixXd &,
-      const Eigen::MatrixXi &,
-      const Eigen::MatrixXi &,
-      const Eigen::VectorXi &,
-      const Eigen::MatrixXi &,
-      const Eigen::MatrixXi &,
-      double &,
-      Eigen::RowVectorXd &)> & cost_and_placement,
+    const decimate_cost_and_placement_callback & cost_and_placement,
     Eigen::MatrixXd & V,
     Eigen::MatrixXi & F,
     Eigen::MatrixXi & E,
     Eigen::VectorXi & EMAP,
     Eigen::MatrixXi & EF,
     Eigen::MatrixXi & EI,
-    std::set<std::pair<double,int> > & Q,
-    std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
+    igl::min_heap< std::tuple<double,int,int> > & Q,
+    Eigen::VectorXi & EQ,
     Eigen::MatrixXd & C);
   // Inputs:
   //   pre_collapse  callback called with index of edge whose collapse is about
@@ -105,103 +116,37 @@ namespace igl
   //   post_collapse  callback called with index of edge whose collapse was
   //     just attempted and a flag revealing whether this was successful.
   IGL_INLINE bool collapse_edge(
-    const std::function<void(
-      const int,
-      const Eigen::MatrixXd &,
-      const Eigen::MatrixXi &,
-      const Eigen::MatrixXi &,
-      const Eigen::VectorXi &,
-      const Eigen::MatrixXi &,
-      const Eigen::MatrixXi &,
-      double &,
-      Eigen::RowVectorXd &)> & cost_and_placement,
-    const std::function<bool(
-      const Eigen::MatrixXd &                                         ,/*V*/
-      const Eigen::MatrixXi &                                         ,/*F*/
-      const Eigen::MatrixXi &                                         ,/*E*/
-      const Eigen::VectorXi &                                         ,/*EMAP*/
-      const Eigen::MatrixXi &                                         ,/*EF*/
-      const Eigen::MatrixXi &                                         ,/*EI*/
-      const std::set<std::pair<double,int> > &                        ,/*Q*/
-      const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
-      const Eigen::MatrixXd &                                         ,/*C*/
-      const int                                                        /*e*/
-      )> & pre_collapse,
-    const std::function<void(
-      const Eigen::MatrixXd &                                         ,   /*V*/
-      const Eigen::MatrixXi &                                         ,   /*F*/
-      const Eigen::MatrixXi &                                         ,   /*E*/
-      const Eigen::VectorXi &                                         ,/*EMAP*/
-      const Eigen::MatrixXi &                                         ,  /*EF*/
-      const Eigen::MatrixXi &                                         ,  /*EI*/
-      const std::set<std::pair<double,int> > &                        ,   /*Q*/
-      const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
-      const Eigen::MatrixXd &                                         ,   /*C*/
-      const int                                                       ,   /*e*/
-      const int                                                       ,  /*e1*/
-      const int                                                       ,  /*e2*/
-      const int                                                       ,  /*f1*/
-      const int                                                       ,  /*f2*/
-      const bool                                                  /*collapsed*/
-      )> & post_collapse,
+    const decimate_cost_and_placement_callback & cost_and_placement,
+    const decimate_pre_collapse_callback       & pre_collapse,
+    const decimate_post_collapse_callback      & post_collapse,
     Eigen::MatrixXd & V,
     Eigen::MatrixXi & F,
     Eigen::MatrixXi & E,
     Eigen::VectorXi & EMAP,
     Eigen::MatrixXi & EF,
     Eigen::MatrixXi & EI,
-    std::set<std::pair<double,int> > & Q,
-    std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
+    igl::min_heap< std::tuple<double,int,int> > & Q,
+    Eigen::VectorXi & EQ,
     Eigen::MatrixXd & C);
-
+  // Outputs:
+  //   e  index into E of attempted collapsed edge. Set to -1 if Q is empty or
+  //     contains only infinite cost edges.
+  //   e1  index into E of edge collpased on left.
+  //   e2  index into E of edge collpased on right.
+  //   f1  index into F of face collpased on left.
+  //   f2  index into F of face collpased on right.
   IGL_INLINE bool collapse_edge(
-    const std::function<void(
-      const int,
-      const Eigen::MatrixXd &,
-      const Eigen::MatrixXi &,
-      const Eigen::MatrixXi &,
-      const Eigen::VectorXi &,
-      const Eigen::MatrixXi &,
-      const Eigen::MatrixXi &,
-      double &,
-      Eigen::RowVectorXd &)> & cost_and_placement,
-    const std::function<bool(
-      const Eigen::MatrixXd &                                         ,/*V*/
-      const Eigen::MatrixXi &                                         ,/*F*/
-      const Eigen::MatrixXi &                                         ,/*E*/
-      const Eigen::VectorXi &                                         ,/*EMAP*/
-      const Eigen::MatrixXi &                                         ,/*EF*/
-      const Eigen::MatrixXi &                                         ,/*EI*/
-      const std::set<std::pair<double,int> > &                        ,/*Q*/
-      const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
-      const Eigen::MatrixXd &                                         ,/*C*/
-      const int                                                        /*e*/
-      )> & pre_collapse,
-    const std::function<void(
-      const Eigen::MatrixXd &                                         ,   /*V*/
-      const Eigen::MatrixXi &                                         ,   /*F*/
-      const Eigen::MatrixXi &                                         ,   /*E*/
-      const Eigen::VectorXi &                                         ,/*EMAP*/
-      const Eigen::MatrixXi &                                         ,  /*EF*/
-      const Eigen::MatrixXi &                                         ,  /*EI*/
-      const std::set<std::pair<double,int> > &                        ,   /*Q*/
-      const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
-      const Eigen::MatrixXd &                                         ,   /*C*/
-      const int                                                       ,   /*e*/
-      const int                                                       ,  /*e1*/
-      const int                                                       ,  /*e2*/
-      const int                                                       ,  /*f1*/
-      const int                                                       ,  /*f2*/
-      const bool                                                  /*collapsed*/
-      )> & post_collapse,
+    const decimate_cost_and_placement_callback & cost_and_placement,
+    const decimate_pre_collapse_callback       & pre_collapse,
+    const decimate_post_collapse_callback      & post_collapse,
     Eigen::MatrixXd & V,
     Eigen::MatrixXi & F,
     Eigen::MatrixXi & E,
     Eigen::VectorXi & EMAP,
     Eigen::MatrixXi & EF,
     Eigen::MatrixXi & EI,
-    std::set<std::pair<double,int> > & Q,
-    std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
+    igl::min_heap< std::tuple<double,int,int> > & Q,
+    Eigen::VectorXi & EQ,
     Eigen::MatrixXd & C,
     int & e,
     int & e1,

+ 20 - 19
include/igl/colon.cpp

@@ -17,7 +17,7 @@ IGL_INLINE void igl::colon(
   const H hi,
   Eigen::Matrix<T,Eigen::Dynamic,1> & I)
 {
-  const int size = ((hi-low)/step)+1;
+  const H size = ((hi-low)/step)+1;
   I = igl::LinSpaced<Eigen::Matrix<T,Eigen::Dynamic,1> >(size,low,low+step*(size-1));
 }
 
@@ -43,26 +43,27 @@ IGL_INLINE Eigen::Matrix<T,Eigen::Dynamic,1> igl::colon(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
-template Eigen::Matrix<int,-1,1,0,-1,1> igl::colon<int,int,int>(int, int);
-template Eigen::Matrix<int,-1,1,0,-1,1> igl::colon<int,int,long>(int,long);
-template Eigen::Matrix<int,-1,1,0,-1,1> igl::colon<int,int,long long int>(int,long long int);
+template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::colon<int, int, int>(int, int);
+template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::colon<int, int, long>(int, long);
+template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::colon<int, int, long long int>(int, long long int);
 template Eigen::Matrix<double, -1, 1, 0, -1, 1> igl::colon<double, double, double>(double, double);
+template void igl::colon<int, long, double>(int, long, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
 // generated by autoexplicit.sh
-template void igl::colon<int, long, int, int>(int, long, int, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
-template void igl::colon<int, int, long, int>(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,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>&);
-template void igl::colon<int, long, long>(int, long, Eigen::Matrix<long, -1, 1, 0, -1, 1>&);
-template void igl::colon<int, double, double, double>(int, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
-template void igl::colon<double, double, double>(double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
-template void igl::colon<double, double, double, double>(double, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
-template void igl::colon<int, int, long>(int, int, Eigen::Matrix<long, -1, 1, 0, -1, 1>&);
-template void igl::colon<int, long, double>(int, long, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
+template void igl::colon<int, long, int, int>(int, long, int, Eigen::Matrix<int, -1, 1, 0, -1, 1> &);
+template void igl::colon<int, int, long, int>(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, 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> &);
+template void igl::colon<int, long, long>(int, long, Eigen::Matrix<long, -1, 1, 0, -1, 1> &);
+template void igl::colon<int, double, double, double>(int, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
+template void igl::colon<double, double, double>(double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
+template void igl::colon<double, double, double, double>(double, double, double, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
+template void igl::colon<int, int, long>(int, int, Eigen::Matrix<long, -1, 1, 0, -1, 1> &);
+template void igl::colon<int, int, double>(int, int, Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
 #ifdef WIN32
-template void igl::colon<int, long long,long>(int, long long, class Eigen::Matrix<long,-1,1,0,-1,1> &);
+template void igl::colon<int, __int64, double>(int, __int64, class Eigen::Matrix<double, -1, 1, 0, -1, 1> &);
+template void igl::colon<int, long long, long>(int, long long, class Eigen::Matrix<long, -1, 1, 0, -1, 1> &);
 template void igl::colon<int, __int64, __int64>(int, __int64, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> &);
-template void igl::colon<int,__int64,double>(int,__int64,class Eigen::Matrix<double,-1,1,0,-1,1> &);
-#endif
 #endif
+#endif

+ 267 - 4
include/igl/colormap.cpp

@@ -6,7 +6,6 @@
 // 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 "colormap.h"
-#include "jet.h"
 #include <algorithm>
 
 // One of the new matplotlib colormaps by Nathaniel J.Smith, Stefan van der Walt, and (in the case of viridis) Eric Firing.
@@ -14,6 +13,266 @@
 
 namespace igl
 {
+
+static double turbo_cm[256][3] = {
+  {0.18995,0.07176,0.23217},
+  {0.19483,0.08339,0.26149},
+  {0.19956,0.09498,0.29024},
+  {0.20415,0.10652,0.31844},
+  {0.20860,0.11802,0.34607},
+  {0.21291,0.12947,0.37314},
+  {0.21708,0.14087,0.39964},
+  {0.22111,0.15223,0.42558},
+  {0.22500,0.16354,0.45096},
+  {0.22875,0.17481,0.47578},
+  {0.23236,0.18603,0.50004},
+  {0.23582,0.19720,0.52373},
+  {0.23915,0.20833,0.54686},
+  {0.24234,0.21941,0.56942},
+  {0.24539,0.23044,0.59142},
+  {0.24830,0.24143,0.61286},
+  {0.25107,0.25237,0.63374},
+  {0.25369,0.26327,0.65406},
+  {0.25618,0.27412,0.67381},
+  {0.25853,0.28492,0.69300},
+  {0.26074,0.29568,0.71162},
+  {0.26280,0.30639,0.72968},
+  {0.26473,0.31706,0.74718},
+  {0.26652,0.32768,0.76412},
+  {0.26816,0.33825,0.78050},
+  {0.26967,0.34878,0.79631},
+  {0.27103,0.35926,0.81156},
+  {0.27226,0.36970,0.82624},
+  {0.27334,0.38008,0.84037},
+  {0.27429,0.39043,0.85393},
+  {0.27509,0.40072,0.86692},
+  {0.27576,0.41097,0.87936},
+  {0.27628,0.42118,0.89123},
+  {0.27667,0.43134,0.90254},
+  {0.27691,0.44145,0.91328},
+  {0.27701,0.45152,0.92347},
+  {0.27698,0.46153,0.93309},
+  {0.27680,0.47151,0.94214},
+  {0.27648,0.48144,0.95064},
+  {0.27603,0.49132,0.95857},
+  {0.27543,0.50115,0.96594},
+  {0.27469,0.51094,0.97275},
+  {0.27381,0.52069,0.97899},
+  {0.27273,0.53040,0.98461},
+  {0.27106,0.54015,0.98930},
+  {0.26878,0.54995,0.99303},
+  {0.26592,0.55979,0.99583},
+  {0.26252,0.56967,0.99773},
+  {0.25862,0.57958,0.99876},
+  {0.25425,0.58950,0.99896},
+  {0.24946,0.59943,0.99835},
+  {0.24427,0.60937,0.99697},
+  {0.23874,0.61931,0.99485},
+  {0.23288,0.62923,0.99202},
+  {0.22676,0.63913,0.98851},
+  {0.22039,0.64901,0.98436},
+  {0.21382,0.65886,0.97959},
+  {0.20708,0.66866,0.97423},
+  {0.20021,0.67842,0.96833},
+  {0.19326,0.68812,0.96190},
+  {0.18625,0.69775,0.95498},
+  {0.17923,0.70732,0.94761},
+  {0.17223,0.71680,0.93981},
+  {0.16529,0.72620,0.93161},
+  {0.15844,0.73551,0.92305},
+  {0.15173,0.74472,0.91416},
+  {0.14519,0.75381,0.90496},
+  {0.13886,0.76279,0.89550},
+  {0.13278,0.77165,0.88580},
+  {0.12698,0.78037,0.87590},
+  {0.12151,0.78896,0.86581},
+  {0.11639,0.79740,0.85559},
+  {0.11167,0.80569,0.84525},
+  {0.10738,0.81381,0.83484},
+  {0.10357,0.82177,0.82437},
+  {0.10026,0.82955,0.81389},
+  {0.09750,0.83714,0.80342},
+  {0.09532,0.84455,0.79299},
+  {0.09377,0.85175,0.78264},
+  {0.09287,0.85875,0.77240},
+  {0.09267,0.86554,0.76230},
+  {0.09320,0.87211,0.75237},
+  {0.09451,0.87844,0.74265},
+  {0.09662,0.88454,0.73316},
+  {0.09958,0.89040,0.72393},
+  {0.10342,0.89600,0.71500},
+  {0.10815,0.90142,0.70599},
+  {0.11374,0.90673,0.69651},
+  {0.12014,0.91193,0.68660},
+  {0.12733,0.91701,0.67627},
+  {0.13526,0.92197,0.66556},
+  {0.14391,0.92680,0.65448},
+  {0.15323,0.93151,0.64308},
+  {0.16319,0.93609,0.63137},
+  {0.17377,0.94053,0.61938},
+  {0.18491,0.94484,0.60713},
+  {0.19659,0.94901,0.59466},
+  {0.20877,0.95304,0.58199},
+  {0.22142,0.95692,0.56914},
+  {0.23449,0.96065,0.55614},
+  {0.24797,0.96423,0.54303},
+  {0.26180,0.96765,0.52981},
+  {0.27597,0.97092,0.51653},
+  {0.29042,0.97403,0.50321},
+  {0.30513,0.97697,0.48987},
+  {0.32006,0.97974,0.47654},
+  {0.33517,0.98234,0.46325},
+  {0.35043,0.98477,0.45002},
+  {0.36581,0.98702,0.43688},
+  {0.38127,0.98909,0.42386},
+  {0.39678,0.99098,0.41098},
+  {0.41229,0.99268,0.39826},
+  {0.42778,0.99419,0.38575},
+  {0.44321,0.99551,0.37345},
+  {0.45854,0.99663,0.36140},
+  {0.47375,0.99755,0.34963},
+  {0.48879,0.99828,0.33816},
+  {0.50362,0.99879,0.32701},
+  {0.51822,0.99910,0.31622},
+  {0.53255,0.99919,0.30581},
+  {0.54658,0.99907,0.29581},
+  {0.56026,0.99873,0.28623},
+  {0.57357,0.99817,0.27712},
+  {0.58646,0.99739,0.26849},
+  {0.59891,0.99638,0.26038},
+  {0.61088,0.99514,0.25280},
+  {0.62233,0.99366,0.24579},
+  {0.63323,0.99195,0.23937},
+  {0.64362,0.98999,0.23356},
+  {0.65394,0.98775,0.22835},
+  {0.66428,0.98524,0.22370},
+  {0.67462,0.98246,0.21960},
+  {0.68494,0.97941,0.21602},
+  {0.69525,0.97610,0.21294},
+  {0.70553,0.97255,0.21032},
+  {0.71577,0.96875,0.20815},
+  {0.72596,0.96470,0.20640},
+  {0.73610,0.96043,0.20504},
+  {0.74617,0.95593,0.20406},
+  {0.75617,0.95121,0.20343},
+  {0.76608,0.94627,0.20311},
+  {0.77591,0.94113,0.20310},
+  {0.78563,0.93579,0.20336},
+  {0.79524,0.93025,0.20386},
+  {0.80473,0.92452,0.20459},
+  {0.81410,0.91861,0.20552},
+  {0.82333,0.91253,0.20663},
+  {0.83241,0.90627,0.20788},
+  {0.84133,0.89986,0.20926},
+  {0.85010,0.89328,0.21074},
+  {0.85868,0.88655,0.21230},
+  {0.86709,0.87968,0.21391},
+  {0.87530,0.87267,0.21555},
+  {0.88331,0.86553,0.21719},
+  {0.89112,0.85826,0.21880},
+  {0.89870,0.85087,0.22038},
+  {0.90605,0.84337,0.22188},
+  {0.91317,0.83576,0.22328},
+  {0.92004,0.82806,0.22456},
+  {0.92666,0.82025,0.22570},
+  {0.93301,0.81236,0.22667},
+  {0.93909,0.80439,0.22744},
+  {0.94489,0.79634,0.22800},
+  {0.95039,0.78823,0.22831},
+  {0.95560,0.78005,0.22836},
+  {0.96049,0.77181,0.22811},
+  {0.96507,0.76352,0.22754},
+  {0.96931,0.75519,0.22663},
+  {0.97323,0.74682,0.22536},
+  {0.97679,0.73842,0.22369},
+  {0.98000,0.73000,0.22161},
+  {0.98289,0.72140,0.21918},
+  {0.98549,0.71250,0.21650},
+  {0.98781,0.70330,0.21358},
+  {0.98986,0.69382,0.21043},
+  {0.99163,0.68408,0.20706},
+  {0.99314,0.67408,0.20348},
+  {0.99438,0.66386,0.19971},
+  {0.99535,0.65341,0.19577},
+  {0.99607,0.64277,0.19165},
+  {0.99654,0.63193,0.18738},
+  {0.99675,0.62093,0.18297},
+  {0.99672,0.60977,0.17842},
+  {0.99644,0.59846,0.17376},
+  {0.99593,0.58703,0.16899},
+  {0.99517,0.57549,0.16412},
+  {0.99419,0.56386,0.15918},
+  {0.99297,0.55214,0.15417},
+  {0.99153,0.54036,0.14910},
+  {0.98987,0.52854,0.14398},
+  {0.98799,0.51667,0.13883},
+  {0.98590,0.50479,0.13367},
+  {0.98360,0.49291,0.12849},
+  {0.98108,0.48104,0.12332},
+  {0.97837,0.46920,0.11817},
+  {0.97545,0.45740,0.11305},
+  {0.97234,0.44565,0.10797},
+  {0.96904,0.43399,0.10294},
+  {0.96555,0.42241,0.09798},
+  {0.96187,0.41093,0.09310},
+  {0.95801,0.39958,0.08831},
+  {0.95398,0.38836,0.08362},
+  {0.94977,0.37729,0.07905},
+  {0.94538,0.36638,0.07461},
+  {0.94084,0.35566,0.07031},
+  {0.93612,0.34513,0.06616},
+  {0.93125,0.33482,0.06218},
+  {0.92623,0.32473,0.05837},
+  {0.92105,0.31489,0.05475},
+  {0.91572,0.30530,0.05134},
+  {0.91024,0.29599,0.04814},
+  {0.90463,0.28696,0.04516},
+  {0.89888,0.27824,0.04243},
+  {0.89298,0.26981,0.03993},
+  {0.88691,0.26152,0.03753},
+  {0.88066,0.25334,0.03521},
+  {0.87422,0.24526,0.03297},
+  {0.86760,0.23730,0.03082},
+  {0.86079,0.22945,0.02875},
+  {0.85380,0.22170,0.02677},
+  {0.84662,0.21407,0.02487},
+  {0.83926,0.20654,0.02305},
+  {0.83172,0.19912,0.02131},
+  {0.82399,0.19182,0.01966},
+  {0.81608,0.18462,0.01809},
+  {0.80799,0.17753,0.01660},
+  {0.79971,0.17055,0.01520},
+  {0.79125,0.16368,0.01387},
+  {0.78260,0.15693,0.01264},
+  {0.77377,0.15028,0.01148},
+  {0.76476,0.14374,0.01041},
+  {0.75556,0.13731,0.00942},
+  {0.74617,0.13098,0.00851},
+  {0.73661,0.12477,0.00769},
+  {0.72686,0.11867,0.00695},
+  {0.71692,0.11268,0.00629},
+  {0.70680,0.10680,0.00571},
+  {0.69650,0.10102,0.00522},
+  {0.68602,0.09536,0.00481},
+  {0.67535,0.08980,0.00449},
+  {0.66449,0.08436,0.00424},
+  {0.65345,0.07902,0.00408},
+  {0.64223,0.07380,0.00401},
+  {0.63082,0.06868,0.00401},
+  {0.61923,0.06367,0.00410},
+  {0.60746,0.05878,0.00427},
+  {0.59550,0.05399,0.00453},
+  {0.58336,0.04931,0.00486},
+  {0.57103,0.04474,0.00529},
+  {0.55852,0.04028,0.00579},
+  {0.54583,0.03593,0.00638},
+  {0.53295,0.03169,0.00705},
+  {0.51989,0.02756,0.00780},
+  {0.50664,0.02354,0.00863},
+  {0.49321,0.01963,0.00955},
+  {0.47960,0.01583,0.01055}
+};
+
 static double inferno_cm[256][3] = {
   { 0.001462, 0.000466, 0.013866 },
   { 0.002267, 0.001270, 0.018570 },
@@ -1320,13 +1579,16 @@ template <typename T>
 IGL_INLINE void igl::colormap(
   const ColorMapType cm, const T x_in, T & r, T & g, T & b)
 {
-  switch (cm) 
+  switch (cm)
   {
     case COLOR_MAP_TYPE_INFERNO:
       colormap(inferno_cm, x_in, r, g, b);
       break;
     case COLOR_MAP_TYPE_JET:
-      jet(x_in, r, g, b);
+      // jet is bad so we use turbo instead
+      // https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html
+    case COLOR_MAP_TYPE_TURBO:
+      colormap(turbo_cm, x_in, r, g, b);
       break;
     case COLOR_MAP_TYPE_MAGMA:
       colormap(magma_cm, x_in, r, g, b);
@@ -1340,7 +1602,7 @@ IGL_INLINE void igl::colormap(
     case COLOR_MAP_TYPE_VIRIDIS:
       colormap(viridis_cm, x_in, r, g, b);
       break;
-    default: 
+    default:
       throw std::invalid_argument("igl::colormap(): Selected colormap is unsupported!");
       break;
   }
@@ -1431,4 +1693,5 @@ template void igl::colormap<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matri
 template void igl::colormap<Eigen::Array<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Array<int, -1, 1, 0, -1, 1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 
 template void igl::colormap<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(igl::ColorMapType, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
+template void igl::colormap<float>(igl::ColorMapType, float, float&, float&, float&);
 #endif

+ 6 - 5
include/igl/colormap.h

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2017 Joe Graus <[email protected]>, Alec Jacobson <[email protected]>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 
 #ifndef IGL_COLORMAP_H
@@ -22,7 +22,8 @@ namespace igl {
     COLOR_MAP_TYPE_PARULA = 3,
     COLOR_MAP_TYPE_PLASMA = 4,
     COLOR_MAP_TYPE_VIRIDIS = 5,
-    NUM_COLOR_MAP_TYPES = 6
+    COLOR_MAP_TYPE_TURBO = 6,
+    NUM_COLOR_MAP_TYPES = 7
   };
   // Comput [r,g,b] values of the selected colormap for
   // a given factor f between 0 and 1

+ 14 - 14
include/igl/comb_cross_field.cpp

@@ -23,10 +23,10 @@ namespace igl {
   {
   public:
 
-    const Eigen::PlainObjectBase<DerivedV> &V;
-    const Eigen::PlainObjectBase<DerivedF> &F;
-    const Eigen::PlainObjectBase<DerivedV> &PD1;
-    const Eigen::PlainObjectBase<DerivedV> &PD2;
+    const Eigen::MatrixBase<DerivedV> &V;
+    const Eigen::MatrixBase<DerivedF> &F;
+    const Eigen::MatrixBase<DerivedV> &PD1;
+    const Eigen::MatrixBase<DerivedV> &PD2;
     DerivedV N;
 
   private:
@@ -61,10 +61,10 @@ namespace igl {
 
 
   public:
-    inline Comb(const Eigen::PlainObjectBase<DerivedV> &_V,
-         const Eigen::PlainObjectBase<DerivedF> &_F,
-         const Eigen::PlainObjectBase<DerivedV> &_PD1,
-         const Eigen::PlainObjectBase<DerivedV> &_PD2
+    inline Comb(const Eigen::MatrixBase<DerivedV> &_V,
+         const Eigen::MatrixBase<DerivedF> &_F,
+         const Eigen::MatrixBase<DerivedV> &_PD1,
+         const Eigen::MatrixBase<DerivedV> &_PD2
          ):
     V(_V),
     F(_F),
@@ -137,10 +137,10 @@ namespace igl {
   };
 }
 template <typename DerivedV, typename DerivedF>
-IGL_INLINE void igl::comb_cross_field(const Eigen::PlainObjectBase<DerivedV> &V,
-                                      const Eigen::PlainObjectBase<DerivedF> &F,
-                                      const Eigen::PlainObjectBase<DerivedV> &PD1,
-                                      const Eigen::PlainObjectBase<DerivedV> &PD2,
+IGL_INLINE void igl::comb_cross_field(const Eigen::MatrixBase<DerivedV> &V,
+                                      const Eigen::MatrixBase<DerivedF> &F,
+                                      const Eigen::MatrixBase<DerivedV> &PD1,
+                                      const Eigen::MatrixBase<DerivedV> &PD2,
                                       Eigen::PlainObjectBase<DerivedV> &PD1out,
                                       Eigen::PlainObjectBase<DerivedV> &PD2out)
 {
@@ -150,6 +150,6 @@ IGL_INLINE void igl::comb_cross_field(const Eigen::PlainObjectBase<DerivedV> &V,
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template void igl::comb_cross_field<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::comb_cross_field<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<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::comb_cross_field<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
+template void igl::comb_cross_field<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 4 - 4
include/igl/comb_cross_field.h

@@ -27,10 +27,10 @@ namespace igl
   
   
   template <typename DerivedV, typename DerivedF>
-  IGL_INLINE void comb_cross_field(const Eigen::PlainObjectBase<DerivedV> &V,
-                                   const Eigen::PlainObjectBase<DerivedF> &F,
-                                   const Eigen::PlainObjectBase<DerivedV> &PD1in,
-                                   const Eigen::PlainObjectBase<DerivedV> &PD2in,
+  IGL_INLINE void comb_cross_field(const Eigen::MatrixBase<DerivedV> &V,
+                                   const Eigen::MatrixBase<DerivedF> &F,
+                                   const Eigen::MatrixBase<DerivedV> &PD1in,
+                                   const Eigen::MatrixBase<DerivedV> &PD2in,
                                    Eigen::PlainObjectBase<DerivedV> &PD1out,
                                    Eigen::PlainObjectBase<DerivedV> &PD2out);
 }

+ 8 - 8
include/igl/comb_frame_field.cpp

@@ -16,12 +16,12 @@
 #include "PI.h"
 
 template <typename DerivedV, typename DerivedF, typename DerivedP>
-IGL_INLINE void igl::comb_frame_field(const Eigen::PlainObjectBase<DerivedV> &V,
-                                      const Eigen::PlainObjectBase<DerivedF> &F,
-                                      const Eigen::PlainObjectBase<DerivedP> &PD1,
-                                      const Eigen::PlainObjectBase<DerivedP> &PD2,
-                                      const Eigen::PlainObjectBase<DerivedP> &BIS1_combed,
-                                      const Eigen::PlainObjectBase<DerivedP> &BIS2_combed,
+IGL_INLINE void igl::comb_frame_field(const Eigen::MatrixBase<DerivedV> &V,
+                                      const Eigen::MatrixBase<DerivedF> &F,
+                                      const Eigen::MatrixBase<DerivedP> &PD1,
+                                      const Eigen::MatrixBase<DerivedP> &PD2,
+                                      const Eigen::MatrixBase<DerivedP> &BIS1_combed,
+                                      const Eigen::MatrixBase<DerivedP> &BIS2_combed,
                                       Eigen::PlainObjectBase<DerivedP> &PD1_combed,
                                       Eigen::PlainObjectBase<DerivedP> &PD2_combed)
 {
@@ -73,6 +73,6 @@ IGL_INLINE void igl::comb_frame_field(const Eigen::PlainObjectBase<DerivedV> &V,
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template void igl::comb_frame_field<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> > 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, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::comb_frame_field<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> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::comb_frame_field<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::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
+template void igl::comb_frame_field<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 6 - 6
include/igl/comb_frame_field.h

@@ -31,12 +31,12 @@ namespace igl
 
 
   template <typename DerivedV, typename DerivedF, typename DerivedP>
-  IGL_INLINE void comb_frame_field(const Eigen::PlainObjectBase<DerivedV> &V,
-                                        const Eigen::PlainObjectBase<DerivedF> &F,
-                                        const Eigen::PlainObjectBase<DerivedP> &PD1,
-                                        const Eigen::PlainObjectBase<DerivedP> &PD2,
-                                        const Eigen::PlainObjectBase<DerivedP> &BIS1_combed,
-                                        const Eigen::PlainObjectBase<DerivedP> &BIS2_combed,
+  IGL_INLINE void comb_frame_field(const Eigen::MatrixBase<DerivedV> &V,
+                                        const Eigen::MatrixBase<DerivedF> &F,
+                                        const Eigen::MatrixBase<DerivedP> &PD1,
+                                        const Eigen::MatrixBase<DerivedP> &PD2,
+                                        const Eigen::MatrixBase<DerivedP> &BIS1_combed,
+                                        const Eigen::MatrixBase<DerivedP> &BIS2_combed,
                                         Eigen::PlainObjectBase<DerivedP> &PD1_combed,
                                         Eigen::PlainObjectBase<DerivedP> &PD2_combed);
 }

+ 9 - 9
include/igl/comb_line_field.cpp

@@ -22,9 +22,9 @@ class CombLine
 {
 public:
 
-    const Eigen::PlainObjectBase<DerivedV> &V;
-    const Eigen::PlainObjectBase<DerivedF> &F;
-    const Eigen::PlainObjectBase<DerivedV> &PD1;
+    const Eigen::MatrixBase<DerivedV> &V;
+    const Eigen::MatrixBase<DerivedF> &F;
+    const Eigen::MatrixBase<DerivedV> &PD1;
     DerivedV N;
 
 private:
@@ -57,9 +57,9 @@ private:
 
 public:
 
-    inline CombLine(const Eigen::PlainObjectBase<DerivedV> &_V,
-                    const Eigen::PlainObjectBase<DerivedF> &_F,
-                    const Eigen::PlainObjectBase<DerivedV> &_PD1):
+    inline CombLine(const Eigen::MatrixBase<DerivedV> &_V,
+                    const Eigen::MatrixBase<DerivedF> &_F,
+                    const Eigen::MatrixBase<DerivedV> &_PD1):
         V(_V),
         F(_F),
         PD1(_PD1)
@@ -118,9 +118,9 @@ public:
 }
 
 template <typename DerivedV, typename DerivedF>
-IGL_INLINE void igl::comb_line_field(const Eigen::PlainObjectBase<DerivedV> &V,
-                                     const Eigen::PlainObjectBase<DerivedF> &F,
-                                     const Eigen::PlainObjectBase<DerivedV> &PD1,
+IGL_INLINE void igl::comb_line_field(const Eigen::MatrixBase<DerivedV> &V,
+                                     const Eigen::MatrixBase<DerivedF> &F,
+                                     const Eigen::MatrixBase<DerivedV> &PD1,
                                      Eigen::PlainObjectBase<DerivedV> &PD1out)
 {
     igl::CombLine<DerivedV, DerivedF> cmb(V, F, PD1);

+ 3 - 6
include/igl/comb_line_field.h

@@ -19,17 +19,14 @@ namespace igl
   //   V          #V by 3 eigen Matrix of mesh vertex 3D positions
   //   F          #F by 4 eigen Matrix of face (quad) indices
   //   PD1in      #F by 3 eigen Matrix of the first per face cross field vector
-  //   PD2in      #F by 3 eigen Matrix of the second per face cross field vector
   // Output:
   //   PD1out      #F by 3 eigen Matrix of the first combed cross field vector
-  //   PD2out      #F by 3 eigen Matrix of the second combed cross field vector
-  //
 
 
   template <typename DerivedV, typename DerivedF>
-  IGL_INLINE void comb_line_field(const Eigen::PlainObjectBase<DerivedV> &V,
-                                  const Eigen::PlainObjectBase<DerivedF> &F,
-                                  const Eigen::PlainObjectBase<DerivedV> &PD1in,
+  IGL_INLINE void comb_line_field(const Eigen::MatrixBase<DerivedV> &V,
+                                  const Eigen::MatrixBase<DerivedF> &F,
+                                  const Eigen::MatrixBase<DerivedV> &PD1in,
                                   Eigen::PlainObjectBase<DerivedV> &PD1out);
 }
 #ifndef IGL_STATIC_LIBRARY

+ 2 - 1
include/igl/combine.cpp

@@ -88,11 +88,12 @@ IGL_INLINE void igl::combine(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::combine<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::vector<Eigen::Matrix<float, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<float, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::combine<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<unsigned long, -1, 1, 0, -1, 1>, Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >&);
 template void igl::combine<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(std::vector<Eigen::Matrix<double, -1, 3, 1, -1, 3>, std::allocator<Eigen::Matrix<double, -1, 3, 1, -1, 3> > > const&, std::vector<Eigen::Matrix<int, -1, 3, 1, -1, 3>, std::allocator<Eigen::Matrix<int, -1, 3, 1, -1, 3> > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
 template void igl::combine<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> >(std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1> > > const&, std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>, std::allocator<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> >&);
 #ifdef WIN32
 template void igl::combine<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<unsigned __int64,-1,1,0,-1,1>,Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> >(class std::vector<Eigen::Matrix<double,-1,-1,0,-1,-1>,class std::allocator<Eigen::Matrix<double,-1,-1,0,-1,-1> > > const &,class std::vector<Eigen::Matrix<int,-1,-1,0,-1,-1>,class std::allocator<Eigen::Matrix<int,-1,-1,0,-1,-1> > > const &,Eigen::PlainObjectBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > &,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > &,Eigen::PlainObjectBase<Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> > &,Eigen::PlainObjectBase<Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> > &);
-template void igl::combine<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<unsigned __int64,-1,1,0,-1,1>,Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> >(class std::vector<Eigen::Matrix<double,-1,-1,0,-1,-1>,class std::allocator<Eigen::Matrix<double,-1,-1,0,-1,-1> > > const &,class std::vector<Eigen::Matrix<int,-1,-1,0,-1,-1>,class std::allocator<Eigen::Matrix<int,-1,-1,0,-1,-1> > > const &,Eigen::PlainObjectBase<Eigen::Matrix<double,-1,-1,0,-1,-1> > &,Eigen::PlainObjectBase<Eigen::Matrix<int,-1,-1,0,-1,-1> > &,Eigen::PlainObjectBase<Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> > &,Eigen::PlainObjectBase<Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> > &);
 #endif
 #endif

+ 13 - 13
include/igl/compute_frame_field_bisectors.cpp

@@ -17,12 +17,12 @@
 
 template <typename DerivedV, typename DerivedF>
 IGL_INLINE void igl::compute_frame_field_bisectors(
-  const Eigen::PlainObjectBase<DerivedV>& V,
-  const Eigen::PlainObjectBase<DerivedF>& F,
-  const Eigen::PlainObjectBase<DerivedV>& B1,
-  const Eigen::PlainObjectBase<DerivedV>& B2,
-  const Eigen::PlainObjectBase<DerivedV>& PD1,
-  const Eigen::PlainObjectBase<DerivedV>& PD2,
+  const Eigen::MatrixBase<DerivedV>& V,
+  const Eigen::MatrixBase<DerivedF>& F,
+  const Eigen::MatrixBase<DerivedV>& B1,
+  const Eigen::MatrixBase<DerivedV>& B2,
+  const Eigen::MatrixBase<DerivedV>& PD1,
+  const Eigen::MatrixBase<DerivedV>& PD2,
   Eigen::PlainObjectBase<DerivedV>& BIS1,
   Eigen::PlainObjectBase<DerivedV>& BIS2)
 {
@@ -64,10 +64,10 @@ IGL_INLINE void igl::compute_frame_field_bisectors(
 
 template <typename DerivedV, typename DerivedF>
 IGL_INLINE void igl::compute_frame_field_bisectors(
-                                                   const Eigen::PlainObjectBase<DerivedV>& V,
-                                                   const Eigen::PlainObjectBase<DerivedF>& F,
-                                                   const Eigen::PlainObjectBase<DerivedV>& PD1,
-                                                   const Eigen::PlainObjectBase<DerivedV>& PD2,
+                                                   const Eigen::MatrixBase<DerivedV>& V,
+                                                   const Eigen::MatrixBase<DerivedF>& F,
+                                                   const Eigen::MatrixBase<DerivedV>& PD1,
+                                                   const Eigen::MatrixBase<DerivedV>& PD2,
                                                    Eigen::PlainObjectBase<DerivedV>& BIS1,
                                                    Eigen::PlainObjectBase<DerivedV>& BIS2)
 {
@@ -80,7 +80,7 @@ IGL_INLINE void igl::compute_frame_field_bisectors(
 
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
-template void igl::compute_frame_field_bisectors<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
-template void igl::compute_frame_field_bisectors<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<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::compute_frame_field_bisectors<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<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::compute_frame_field_bisectors<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
+template void igl::compute_frame_field_bisectors<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::compute_frame_field_bisectors<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 #endif

+ 10 - 10
include/igl/compute_frame_field_bisectors.h

@@ -26,22 +26,22 @@ namespace igl
   //
   template <typename DerivedV, typename DerivedF>
   IGL_INLINE void compute_frame_field_bisectors(
-                                                const Eigen::PlainObjectBase<DerivedV>& V,
-                                                const Eigen::PlainObjectBase<DerivedF>& F,
-                                                const Eigen::PlainObjectBase<DerivedV>& B1,
-                                                const Eigen::PlainObjectBase<DerivedV>& B2,
-                                                const Eigen::PlainObjectBase<DerivedV>& PD1,
-                                                const Eigen::PlainObjectBase<DerivedV>& PD2,
+                                                const Eigen::MatrixBase<DerivedV>& V,
+                                                const Eigen::MatrixBase<DerivedF>& F,
+                                                const Eigen::MatrixBase<DerivedV>& B1,
+                                                const Eigen::MatrixBase<DerivedV>& B2,
+                                                const Eigen::MatrixBase<DerivedV>& PD1,
+                                                const Eigen::MatrixBase<DerivedV>& PD2,
                                                 Eigen::PlainObjectBase<DerivedV>& BIS1,
                                                 Eigen::PlainObjectBase<DerivedV>& BIS2);
 
   // Wrapper without given basis vectors.
   template <typename DerivedV, typename DerivedF>
   IGL_INLINE void compute_frame_field_bisectors(
-                                                const Eigen::PlainObjectBase<DerivedV>& V,
-                                                const Eigen::PlainObjectBase<DerivedF>& F,
-                                                const Eigen::PlainObjectBase<DerivedV>& PD1,
-                                                const Eigen::PlainObjectBase<DerivedV>& PD2,
+                                                const Eigen::MatrixBase<DerivedV>& V,
+                                                const Eigen::MatrixBase<DerivedF>& F,
+                                                const Eigen::MatrixBase<DerivedV>& PD1,
+                                                const Eigen::MatrixBase<DerivedV>& PD2,
                                                 Eigen::PlainObjectBase<DerivedV>& BIS1,
                                                 Eigen::PlainObjectBase<DerivedV>& BIS2);
 }

+ 5 - 5
include/igl/connect_boundary_to_infinity.cpp

@@ -10,14 +10,14 @@
 
 template <typename DerivedF, typename DerivedFO>
 IGL_INLINE void igl::connect_boundary_to_infinity(
-  const Eigen::PlainObjectBase<DerivedF> & F,
+  const Eigen::MatrixBase<DerivedF> & F,
   Eigen::PlainObjectBase<DerivedFO> & FO)
 {
   return connect_boundary_to_infinity(F,F.maxCoeff(),FO);
 }
 template <typename DerivedF, typename DerivedFO>
 IGL_INLINE void igl::connect_boundary_to_infinity(
-  const Eigen::PlainObjectBase<DerivedF> & F,
+  const Eigen::MatrixBase<DerivedF> & F,
   const typename DerivedF::Scalar inf_index,
   Eigen::PlainObjectBase<DerivedFO> & FO)
 {
@@ -37,8 +37,8 @@ template <
   typename DerivedVO, 
   typename DerivedFO>
 IGL_INLINE void igl::connect_boundary_to_infinity(
-  const Eigen::PlainObjectBase<DerivedV> & V,
-  const Eigen::PlainObjectBase<DerivedF> & F,
+  const Eigen::MatrixBase<DerivedV> & V,
+  const Eigen::MatrixBase<DerivedF> & F,
   Eigen::PlainObjectBase<DerivedVO> & VO,
   Eigen::PlainObjectBase<DerivedFO> & FO)
 {
@@ -51,5 +51,5 @@ IGL_INLINE void igl::connect_boundary_to_infinity(
 }
 
 #ifdef IGL_STATIC_LIBRARY
-template void igl::connect_boundary_to_infinity<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::connect_boundary_to_infinity<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 #endif

+ 4 - 4
include/igl/connect_boundary_to_infinity.h

@@ -22,13 +22,13 @@ namespace igl
   //     edge-manifold).
   template <typename DerivedF, typename DerivedFO>
   IGL_INLINE void connect_boundary_to_infinity(
-    const Eigen::PlainObjectBase<DerivedF> & F,
+    const Eigen::MatrixBase<DerivedF> & F,
     Eigen::PlainObjectBase<DerivedFO> & FO);
   // Inputs:
   //   inf_index  index of point at infinity (usually V.rows() or F.maxCoeff())
   template <typename DerivedF, typename DerivedFO>
   IGL_INLINE void connect_boundary_to_infinity(
-    const Eigen::PlainObjectBase<DerivedF> & F,
+    const Eigen::MatrixBase<DerivedF> & F,
     const typename DerivedF::Scalar inf_index,
     Eigen::PlainObjectBase<DerivedFO> & FO);
   // Inputs:
@@ -45,8 +45,8 @@ namespace igl
     typename DerivedVO, 
     typename DerivedFO>
   IGL_INLINE void connect_boundary_to_infinity(
-    const Eigen::PlainObjectBase<DerivedV> & V,
-    const Eigen::PlainObjectBase<DerivedF> & F,
+    const Eigen::MatrixBase<DerivedV> & V,
+    const Eigen::MatrixBase<DerivedF> & F,
     Eigen::PlainObjectBase<DerivedVO> & VO,
     Eigen::PlainObjectBase<DerivedFO> & FO);
 }

+ 61 - 0
include/igl/connected_components.cpp

@@ -0,0 +1,61 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2020 Alec Jacobson <[email protected]>
+//
+// 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 "connected_components.h"
+#include <queue>
+
+template < typename Atype, typename DerivedC, typename DerivedK>
+IGL_INLINE int igl::connected_components(
+  const Eigen::SparseMatrix<Atype> & A,
+  Eigen::PlainObjectBase<DerivedC> & C,
+  Eigen::PlainObjectBase<DerivedK> & K)
+{
+  typedef typename Eigen::SparseMatrix<Atype>::Index Index;
+  const auto m = A.rows();
+  assert(A.cols() == A.rows() && "A should be square");
+  // 1.1 sec
+  // m  means not yet visited
+  C.setConstant(m,1,m);
+  // Could use amortized dynamic array but didn't see real win.
+  K.setZero(m,1);
+  typename DerivedC::Scalar c = 0;
+  for(Eigen::Index f = 0;f<m;f++)
+  {
+    // already seen
+    if(C(f)<m) continue;
+    // start bfs
+    std::queue<Index> Q;
+    Q.push(f);
+    while(!Q.empty())
+    {
+      const Index g = Q.front();
+      Q.pop();
+      // already seen
+      if(C(g)<m) continue;
+      // see it
+      C(g) = c;
+      K(c)++;
+      for(typename Eigen::SparseMatrix<Atype>::InnerIterator it (A,g); it; ++it)
+      {
+        const Index n = it.index();
+        // already seen
+        if(C(n)<m) continue;
+        Q.push(n);
+      }
+    }
+    c++;
+  }
+  K.conservativeResize(c,1);
+  return c;
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template int igl::connected_components<int, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<int, 0, int> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+#endif

+ 35 - 0
include/igl/connected_components.h

@@ -0,0 +1,35 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2020 Alec Jacobson <[email protected]>
+//
+// 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_CONNECTED_COMPONENTS_H
+#define IGL_CONNECTED_COMPONENTS_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <Eigen/Sparse>
+namespace igl
+{
+  // Determine the connected components of a graph described by the input
+  // adjacency matrix (similar to MATLAB's graphconncomp).
+  //
+  // Inputs:
+  //    A  #A by #A adjacency matrix (treated as describing an undirected graph)
+  // Outputs:
+  //    C  #A list of component indices into [0,#K-1]
+  //    K  #K list of sizes of each component
+  // Returns number of connected components
+  template < typename Atype, typename DerivedC, typename DerivedK>
+  IGL_INLINE int connected_components(
+    const Eigen::SparseMatrix<Atype> & A,
+    Eigen::PlainObjectBase<DerivedC> & C,
+    Eigen::PlainObjectBase<DerivedK> & K);
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "connected_components.cpp"
+#endif
+
+#endif

+ 6 - 0
include/igl/copyleft/cgal/assign.cpp

@@ -49,6 +49,12 @@ igl::copyleft::cgal::assign(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::assign<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::assign<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
 // generated by autoexplicit.sh
 template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&);

+ 49 - 0
include/igl/copyleft/cgal/coplanar.cpp

@@ -0,0 +1,49 @@
+#include "coplanar.h"
+#include "row_to_point.h"
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Point_3.h>
+
+template <typename DerivedV>
+IGL_INLINE bool igl::copyleft::cgal::coplanar(
+  const Eigen::MatrixBase<DerivedV> & V)
+{
+  // 3 points in 3D are always coplanar
+  if(V.rows() < 4){ return true; }
+  // spanning points found so far
+  std::vector<CGAL::Point_3<CGAL::Epick> > p;
+  for(int i = 0;i<V.rows();i++)
+  {
+    const CGAL::Point_3<CGAL::Epick> pi(V(i,0), V(i,1), V(i,2));
+    switch(p.size())
+    {
+      case 0:
+        p.push_back(pi);
+        break;
+      case 1:
+        if(p[0] != pi)
+        {
+          p.push_back(pi);
+        }
+        break;
+      case 2:
+        if(!CGAL::collinear(p[0],p[1],pi))
+        {
+          p.push_back(pi);
+        }
+        break;
+      case 3:
+        if(!CGAL::coplanar(p[0],p[1],p[2],pi))
+        {
+          return false;
+        }
+        break;
+    }
+  }
+  return true;
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template bool igl::copyleft::cgal::coplanar<Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&);
+#endif

+ 26 - 0
include/igl/copyleft/cgal/coplanar.h

@@ -0,0 +1,26 @@
+#ifndef IGL_COPYLEFT_CGAL_COPLANAR_H
+#define IGL_COPYLEFT_CGAL_COPLANAR_H
+#include "../../igl_inline.h"
+#include <Eigen/Core>
+namespace igl
+{
+  namespace copyleft
+  {
+    namespace cgal
+    {
+      // Test whether all points are on same plane.
+      //
+      // Inputs:
+      //   V  #V by 3 list of 3D vertex positions
+      // Returns true if all points lie on the same plane
+      template <typename DerivedV>
+      IGL_INLINE bool coplanar(
+        const Eigen::MatrixBase<DerivedV> & V);
+    }
+  }
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "coplanar.cpp"
+#endif
+
+#endif

+ 2 - 2
include/igl/copyleft/cgal/extract_cells.cpp

@@ -1,7 +1,7 @@
 // This file is part of libigl, a simple c++ geometry processing library.
 //
 // Copyright (C) 2015 Qingnan Zhou <[email protected]>
-//
+// 
 // 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/.
@@ -200,7 +200,7 @@ IGL_INLINE size_t igl::copyleft::cgal::extract_cells(
     DerivedV bbox_max(num_components, 3);
     // Assuming our mesh (in exact numbers) fits in the range of double.
     bbox_min.setConstant(std::numeric_limits<double>::max());
-    bbox_max.setConstant(std::numeric_limits<double>::min());
+    bbox_max.setConstant(std::numeric_limits<double>::lowest());
     // Loop over faces
     for (size_t i=0; i<num_faces; i++)
     {

+ 2 - 0
include/igl/copyleft/cgal/mesh_boolean.cpp

@@ -435,6 +435,8 @@ IGL_INLINE bool igl::copyleft::cgal::mesh_boolean(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+// generated by autoexplicit.sh
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3>, Eigen::Matrix<int, 12, 3, 0, 12, 3>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 8, 3, 0, 8, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, 12, 3, 0, 12, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
 template bool igl::copyleft::cgal::mesh_boolean<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::MeshBooleanType const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);

+ 4 - 0
include/igl/copyleft/cgal/mesh_to_cgal_triangle_list.cpp

@@ -48,6 +48,10 @@ IGL_INLINE void igl::copyleft::cgal::mesh_to_cgal_triangle_list(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epick>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > >&);
 // generated by autoexplicit.sh
 template void igl::copyleft::cgal::mesh_to_cgal_triangle_list<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epeck>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > >&);

+ 2 - 0
include/igl/copyleft/cgal/minkowski_sum.cpp

@@ -382,6 +382,8 @@ IGL_INLINE void igl::copyleft::cgal::minkowski_sum(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::minkowski_sum<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, 3, 1, double, 3, 1, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, bool, 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> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::minkowski_sum<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Lazy_exact_nt<CGAL::Gmpq>, 3, 1, CGAL::Lazy_exact_nt<CGAL::Gmpq>, 3, 1, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 3, 1, 1, 3> const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, 1, 3, 1, 1, 3> const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
 template void igl::copyleft::cgal::minkowski_sum<

+ 1 - 1
include/igl/copyleft/cgal/orient2D.h

@@ -21,7 +21,7 @@ namespace igl
       //   pa,pb,pc   2D points.
       // Output:
       //   1 if pa,pb,pc are counterclockwise oriented.
-      //   0 if pa,pb,pc are counterclockwise oriented.
+      //   0 if pa,pb,pc are collinear.
       //  -1 if pa,pb,pc are clockwise oriented.
       template <typename Scalar>
       IGL_INLINE short orient2D(

+ 6 - 0
include/igl/copyleft/cgal/remesh_intersections.cpp

@@ -483,6 +483,10 @@ IGL_INLINE void igl::copyleft::cgal::remesh_intersections(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epick, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&, std::map<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Epeck, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > > const&, std::map<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epick, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&, std::map<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 // generated by autoexplicit.sh
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, CGAL::Epeck, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > > const&, std::map<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Index, CGAL::Object> > > > > > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
@@ -527,6 +531,8 @@ template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<double, -1
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epeck, 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::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epeck>, std::allocator<CGAL::Triangle_3<CGAL::Epeck> > > const&, std::map<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object> > > > > > const&, bool, 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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::copyleft::cgal::remesh_intersections<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, CGAL::Epick, 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::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<CGAL::Triangle_3<CGAL::Epick>, std::allocator<CGAL::Triangle_3<CGAL::Epick> > > const&, std::map<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object> > >, std::less<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index const, std::vector<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object>, std::allocator<std::pair<Eigen::Matrix<int, -1, 3, 0, -1, 3>::Index, CGAL::Object> > > > > > const&, bool, 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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #ifdef WIN32
+template void igl::copyleft::cgal::remesh_intersections<class Eigen::Matrix<float,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,-1,0,-1,-1>,class CGAL::Epeck,class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>,-1,-1,0,-1,-1>,class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::Matrix<int,-1,1,0,-1,1> >(class Eigen::MatrixBase<class Eigen::Matrix<float,-1,3,0,-1,3> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class std::vector<class CGAL::Triangle_3<class CGAL::Epeck>,class std::allocator<class CGAL::Triangle_3<class CGAL::Epeck> > > const &,class std::map<__int64,class std::vector<struct std::pair<__int64,class CGAL::Object>,class std::allocator<struct std::pair<__int64,class CGAL::Object> > >,struct std::less<__int64>,class std::allocator<struct std::pair<__int64 const ,class std::vector<struct std::pair<__int64,class CGAL::Object>,class std::allocator<struct std::pair<__int64,class CGAL::Object> > > > > > const &,bool,class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>,-1,-1,0,-1,-1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,1,0,-1,1> > &);
+template void igl::copyleft::cgal::remesh_intersections<class Eigen::Matrix<float,-1,3,0,-1,3>,class Eigen::Matrix<int,-1,-1,0,-1,-1>,class CGAL::Epick,class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>,-1,-1,0,-1,-1>,class Eigen::Matrix<int,-1,-1,0,-1,-1>,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::Matrix<int,-1,1,0,-1,1> >(class Eigen::MatrixBase<class Eigen::Matrix<float,-1,3,0,-1,3> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > const &,class std::vector<class CGAL::Triangle_3<class CGAL::Epick>,class std::allocator<class CGAL::Triangle_3<class CGAL::Epick> > > const &,class std::map<__int64,class std::vector<struct std::pair<__int64,class CGAL::Object>,class std::allocator<struct std::pair<__int64,class CGAL::Object> > >,struct std::less<__int64>,class std::allocator<struct std::pair<__int64 const ,class std::vector<struct std::pair<__int64,class CGAL::Object>,class std::allocator<struct std::pair<__int64,class CGAL::Object> > > > > > const &,bool,class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>,-1,-1,0,-1,-1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,-1,0,-1,-1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,1,0,-1,1> > &);
 template void igl::copyleft::cgal::remesh_intersections<class Eigen::Matrix<double, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class CGAL::Epeck, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::MatrixBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3>> const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class std::vector<class CGAL::Triangle_3<class CGAL::Epeck>, class std::allocator<class CGAL::Triangle_3<class CGAL::Epeck>>> const &, class std::map<__int64, class std::vector<struct std::pair<__int64, class CGAL::Object>, class std::allocator<struct std::pair<__int64, class CGAL::Object>>>, struct std::less<__int64>, class std::allocator<struct std::pair<__int64 const, class std::vector<struct std::pair<__int64, class CGAL::Object>, class std::allocator<struct std::pair<__int64, class CGAL::Object>>>>>> const &, bool, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
 template void igl::copyleft::cgal::remesh_intersections<class Eigen::Matrix<double, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class CGAL::Epick, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::MatrixBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3>> const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class std::vector<class CGAL::Triangle_3<class CGAL::Epick>, class std::allocator<class CGAL::Triangle_3<class CGAL::Epick>>> const &, class std::map<__int64, class std::vector<struct std::pair<__int64, class CGAL::Object>, class std::allocator<struct std::pair<__int64, class CGAL::Object>>>, struct std::less<__int64>, class std::allocator<struct std::pair<__int64 const, class std::vector<struct std::pair<__int64, class CGAL::Object>, class std::allocator<struct std::pair<__int64, class CGAL::Object>>>>>> const &, bool, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
 template void igl::copyleft::cgal::remesh_intersections<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class CGAL::Epeck, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::MatrixBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>> const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, class std::vector<class CGAL::Triangle_3<class CGAL::Epeck>, class std::allocator<class CGAL::Triangle_3<class CGAL::Epeck>>> const &, class std::map<__int64, class std::vector<struct std::pair<__int64, class CGAL::Object>, class std::allocator<struct std::pair<__int64, class CGAL::Object>>>, struct std::less<__int64>, class std::allocator<struct std::pair<__int64 const, class std::vector<struct std::pair<__int64, class CGAL::Object>, class std::allocator<struct std::pair<__int64, class CGAL::Object>>>>>> const &, bool, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);

+ 3 - 0
include/igl/copyleft/cgal/remesh_self_intersections.cpp

@@ -83,6 +83,8 @@ IGL_INLINE void igl::copyleft::cgal::remesh_self_intersections(
 #ifdef IGL_STATIC_LIBRARY
 // Explicit template instantiation
 // generated by autoexplicit.sh
+template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, 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::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, 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> >&);
 // generated by autoexplicit.sh
 template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -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::MatrixBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
@@ -104,6 +106,7 @@ template void igl::copyleft::cgal::remesh_self_intersections<Eigen::Matrix<doubl
 template void igl::copyleft::cgal::remesh_self_intersections<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::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::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam 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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #ifdef WIN32
 template void igl::copyleft::cgal::remesh_self_intersections<class Eigen::Matrix<double, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::MatrixBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3>> const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, struct igl::copyleft::cgal::RemeshSelfIntersectionsParam const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
+template void igl::copyleft::cgal::remesh_self_intersections<class Eigen::Matrix< float, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1> >(class Eigen::MatrixBase<class Eigen::Matrix< float, -1, 3, 0, -1, 3> > const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > const &, struct igl::copyleft::cgal::RemeshSelfIntersectionsParam const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1> > &);
 template void igl::copyleft::cgal::remesh_self_intersections<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<int, -1, 1, 0, -1, 1>>(class Eigen::MatrixBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, 3, 0, -1, 3>> const &, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> const &, struct igl::copyleft::cgal::RemeshSelfIntersectionsParam const &, class Eigen::PlainObjectBase<class Eigen::Matrix<class CGAL::Lazy_exact_nt<class CGAL::Gmpq>, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>> &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, 1, 0, -1, 1>> &);
 #endif
 #endif

+ 6 - 0
include/igl/copyleft/cgal/resolve_intersections.cpp

@@ -88,3 +88,9 @@ IGL_INLINE void igl::copyleft::cgal::resolve_intersections(
 
   subdivide_segments(V,E,steiner,VI,EI,J,IM);
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template void igl::copyleft::cgal::resolve_intersections<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+#endif

+ 7 - 0
include/igl/copyleft/cgal/row_to_point.cpp

@@ -16,3 +16,10 @@ IGL_INLINE CGAL::Point_2<Kernel> igl::copyleft::cgal::row_to_point(
 {
   return CGAL::Point_2<Kernel>(V(i,0),V(i,1));
 }
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+template CGAL::Point_2<CGAL::Epeck> igl::copyleft::cgal::row_to_point<CGAL::Epeck, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>::Index const&);
+#endif

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