Compare commits
324
Commits
circulation
...
v2.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e60423e28c | ||
|
|
c96b13b97a | ||
|
|
7a3af9c851 | ||
|
|
e9ff76d9bb | ||
|
|
b56f53beff | ||
|
|
ec9fe116f4 | ||
|
|
22620eb925 | ||
|
|
01086ed865 | ||
|
|
ad0f1e6b5b | ||
|
|
bdd33218a9 | ||
|
|
55f7aa89d9 | ||
|
|
38a1235756 | ||
|
|
6f0233183d | ||
|
|
00bd753289 | ||
|
|
31a9dff085 | ||
|
|
822ffc7684 | ||
|
|
5e2c82dbbc | ||
|
|
747274b792 | ||
|
|
f73dc5c9f5 | ||
|
|
2e988bec2e | ||
|
|
a6550e6849 | ||
|
|
233c1027db | ||
|
|
f7288d5655 | ||
|
|
b36868f15a | ||
|
|
8c4ebeb995 | ||
|
|
1a9bc50125 | ||
|
|
6e81f2555c | ||
|
|
eae92b5060 | ||
|
|
91ae2f6cea | ||
|
|
03448998fb | ||
|
|
4d70f145d4 | ||
|
|
c20c12460d | ||
|
|
86042b0085 | ||
|
|
c371e243da | ||
|
|
d85f0c7537 | ||
|
|
41591d2a49 | ||
|
|
4d8efa03ad | ||
|
|
505cbfa8a6 | ||
|
|
4e61844f27 | ||
|
|
f1017e507d | ||
|
|
bc3f4903e8 | ||
|
|
306e0b5087 | ||
|
|
24a9d0c804 | ||
|
|
70d2abaa53 | ||
|
|
6083cb3a5d | ||
|
|
f7f64f6491 | ||
|
|
780a5fbea5 | ||
|
|
ddf6927ca3 | ||
|
|
7b852d5340 | ||
|
|
7181b99a01 | ||
|
|
fe72a97bcc | ||
|
|
07c5b9c9d3 | ||
|
|
516ff49cff | ||
|
|
87384cf626 | ||
|
|
4d628e75fe | ||
|
|
44f2e1d8be | ||
|
|
a4791538de | ||
|
|
ef289fe39f | ||
|
|
5a68b6e924 | ||
|
|
48c596ba59 | ||
|
|
7e31fdd4bb | ||
|
|
babf491b69 | ||
|
|
a0c6750917 | ||
|
|
61588efa78 | ||
|
|
cef9c6594f | ||
|
|
9de4b6640f | ||
|
|
7ebb86734a | ||
|
|
5b7b50c026 | ||
|
|
148c5f72fc | ||
|
|
aafb6870c7 | ||
|
|
4d026eeef1 | ||
|
|
ea57dfa2ad | ||
|
|
85120e557e | ||
|
|
ad54f2dfe2 | ||
|
|
0ac1d696f8 | ||
|
|
fbfb2d56ad | ||
|
|
858c843971 | ||
|
|
723eb8d74d | ||
|
|
c60a948e7d | ||
|
|
ce32c4aa03 | ||
|
|
e7b3e45577 | ||
|
|
7be097d585 | ||
|
|
c47bb0507b | ||
|
|
b35d97472d | ||
|
|
2ea8312e5e | ||
|
|
f9b716fdf8 | ||
|
|
c608c60a6d | ||
|
|
7250ea7d91 | ||
|
|
e6482a8a42 | ||
|
|
dbba9ca921 | ||
|
|
225edb47b6 | ||
|
|
d14ab658df | ||
|
|
c7b5d0b6e3 | ||
|
|
21b62c5777 | ||
|
|
f06fb13014 | ||
|
|
59b517a4a4 | ||
|
|
efee81b7db | ||
|
|
bd30aa03b9 | ||
|
|
49a0ab8640 | ||
|
|
6e1ed534ce | ||
|
|
2ea66c3350 | ||
|
|
a3ba1f24f8 | ||
|
|
2e05e0f178 | ||
|
|
fbd4ce2399 | ||
|
|
6cde8347be | ||
|
|
645718cf77 | ||
|
|
a956dfd37d | ||
|
|
682e4b9685 | ||
|
|
69b0eccb15 | ||
|
|
03e14c609f | ||
|
|
782b7fc95d | ||
|
|
55817544c2 | ||
|
|
0bb27beb88 | ||
|
|
dbec07d9f5 | ||
|
|
80711ea630 | ||
|
|
c744410fe1 | ||
|
|
e706cc5b8b | ||
|
|
7ed7b06696 | ||
|
|
be9b795a16 | ||
|
|
0264736ed3 | ||
|
|
a8a1216363 | ||
|
|
fb3bd3571e | ||
|
|
d2bc41e99b | ||
|
|
0a92f2cdb2 | ||
|
|
870eb14ec2 | ||
|
|
1e905cba3d | ||
|
|
0e4e79f464 | ||
|
|
a2a1479a88 | ||
|
|
51b3f7093a | ||
|
|
249f37af52 | ||
|
|
63b3669a87 | ||
|
|
9814e81b4b | ||
|
|
c21ad49c38 | ||
|
|
d69073c329 | ||
|
|
8b5b424e8c | ||
|
|
1b745f81ed | ||
|
|
fa7eb0befb | ||
|
|
10c90309a8 | ||
|
|
062e3823c3 | ||
|
|
7b4a19da9d | ||
|
|
8c95d1044e | ||
|
|
9a1ab67df9 | ||
|
|
9921615af2 | ||
|
|
8ea0b8c6dc | ||
|
|
d9864be29e | ||
|
|
28008528b4 | ||
|
|
1ad4556268 | ||
|
|
35ba62b1a0 | ||
|
|
ec24dccc29 | ||
|
|
1fda040670 | ||
|
|
9bc3ffd98f | ||
|
|
af8944c7b6 | ||
|
|
3856ea92ce | ||
|
|
91faf24015 | ||
|
|
28ab0d11de | ||
|
|
5358cc5a36 | ||
|
|
775f2354fa | ||
|
|
9c49b73ade | ||
|
|
d2a4b51e1e | ||
|
|
e608aad744 | ||
|
|
10d2f75572 | ||
|
|
a22ed58dc4 | ||
|
|
4cb640737e | ||
|
|
86c7c7db2e | ||
|
|
21acee15fe | ||
|
|
eef47fe34c | ||
|
|
92dd81bb5d | ||
|
|
b42cfeba49 | ||
|
|
317f0522a8 | ||
|
|
b582ecada9 | ||
|
|
bae087d7eb | ||
|
|
f7067c69e9 | ||
|
|
7db28d5700 | ||
|
|
43da16bbd0 | ||
|
|
1de2627280 | ||
|
|
c183f419e7 | ||
|
|
20924d62f1 | ||
|
|
48051bc889 | ||
|
|
cb59839742 | ||
|
|
4a22178717 | ||
|
|
97bd52fb52 | ||
|
|
c61e28fe5a | ||
|
|
07e2b01a3c | ||
|
|
41454f823d | ||
|
|
1a4ccf65b7 | ||
|
|
98a1a31641 | ||
|
|
dde868d297 | ||
|
|
3b80edbd7c | ||
|
|
7be8dc32af | ||
|
|
abd9f0f365 | ||
|
|
b8ee8b99cf | ||
|
|
45cfc79fed | ||
|
|
015ac35cd1 | ||
|
|
d95f3a410f | ||
|
|
3a110bbf4d | ||
|
|
ac56a694f2 | ||
|
|
a3c3ef1572 | ||
|
|
b03769f26e | ||
|
|
1b53e54815 | ||
|
|
d22414e388 | ||
|
|
005ae90b67 | ||
|
|
39c7d33b4c | ||
|
|
61834f4fa1 | ||
|
|
d3248f0a0f | ||
|
|
7ee863c92f | ||
|
|
58a600aebf | ||
|
|
95a7b15efc | ||
|
|
ae5d163f7d | ||
|
|
8268a3f33b | ||
|
|
e4ab356031 | ||
|
|
762a4ec1f4 | ||
|
|
238d52c90f | ||
|
|
1e78a3473a | ||
|
|
3b0ec3ce63 | ||
|
|
d22f873ef2 | ||
|
|
ce201a7433 | ||
|
|
48a7e8cd02 | ||
|
|
feb71ef502 | ||
|
|
dc01d7e277 | ||
|
|
75a0c4fa2c | ||
|
|
60ffe1b0dc | ||
|
|
0b52794637 | ||
|
|
71e65516ae | ||
|
|
3f67752504 | ||
|
|
95a80d3fa9 | ||
|
|
5f72004d0d | ||
|
|
b0a8fa84e1 | ||
|
|
162f9b8f68 | ||
|
|
32e3edf229 | ||
|
|
f3a201f1e1 | ||
|
|
916a5c217d | ||
|
|
3141dfc26d | ||
|
|
14d6bcec3d | ||
|
|
6eb02be7db | ||
|
|
3da9d323fb | ||
|
|
c7324d3fa6 | ||
|
|
ae903ae468 | ||
|
|
3069260f07 | ||
|
|
1df0987271 | ||
|
|
ce9b23e8b9 | ||
|
|
5c5eddcd55 | ||
|
|
e14a3bd0a1 | ||
|
|
72f0b5844b | ||
|
|
7e70dfbbff | ||
|
|
5b11835be1 | ||
|
|
829eaa54b6 | ||
|
|
d402d94959 | ||
|
|
60ea43092c | ||
|
|
03e65b95ca | ||
|
|
04457f1eae | ||
|
|
29b75796b2 | ||
|
|
6664ffef18 | ||
|
|
7ae4fb1fc1 | ||
|
|
2cd50a8bc8 | ||
|
|
78a212d4ca | ||
|
|
215994dc07 | ||
|
|
e88249f68d | ||
|
|
1f4a27e73c | ||
|
|
f2cc26f284 | ||
|
|
8e35d87991 | ||
|
|
4516d19268 | ||
|
|
80e763d372 | ||
|
|
7798748774 | ||
|
|
1aa35de249 | ||
|
|
5a6e3125f3 | ||
|
|
18c5a9ddf0 | ||
|
|
8f33348c29 | ||
|
|
c47f1dab9b | ||
|
|
6f5fadd154 | ||
|
|
a6ca070009 | ||
|
|
e8b2170dd3 | ||
|
|
b632972487 | ||
|
|
9fa54a0398 | ||
|
|
0c5bb13883 | ||
|
|
651fc234cd | ||
|
|
4ca4f8b341 | ||
|
|
4ab389d462 | ||
|
|
c16bc37fcb | ||
|
|
1ad57f019c | ||
|
|
698c316159 | ||
|
|
faaae91419 | ||
|
|
0f557400f9 | ||
|
|
df5b320f57 | ||
|
|
a90a67bdf2 | ||
|
|
a203de97aa | ||
|
|
4827b40640 | ||
|
|
f029832904 | ||
|
|
7576c3b8ad | ||
|
|
10dc1fd9f8 | ||
|
|
546452da5a | ||
|
|
c1c88fd78b | ||
|
|
c907add524 | ||
|
|
726cd540c3 | ||
|
|
b9093020ab | ||
|
|
021ec6f946 | ||
|
|
b550323ef0 | ||
|
|
5c7298c2fc | ||
|
|
3150c23b62 | ||
|
|
2d7037a945 | ||
|
|
7ed138a23e | ||
|
|
75540e118f | ||
|
|
49afe670d0 | ||
|
|
5239d12eb3 | ||
|
|
01466e5bd6 | ||
|
|
3cb4894eaf | ||
|
|
62b3350271 | ||
|
|
52c6f14ca6 | ||
|
|
4ce917d424 | ||
|
|
26053f696c | ||
|
|
92b25d30a8 | ||
|
|
87bfaeeba8 | ||
|
|
79e7a05b16 | ||
|
|
87b54fc4dc | ||
|
|
d3052ef4c7 | ||
|
|
252017af44 | ||
|
|
e2548f971c | ||
|
|
6983cfd1f4 | ||
|
|
2f570a0e97 | ||
|
|
edb21bef2c | ||
|
|
48e3c72dfe | ||
|
|
d7dd3c2356 | ||
|
|
61878ade62 | ||
|
|
3404ee671b | ||
|
|
21d95881ed |
@@ -1,34 +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
|
||||
- CONFIG: Release
|
||||
BOOST_ROOT: C:/Libraries/boost_1_65_1
|
||||
build:
|
||||
parallel: true
|
||||
build_script:
|
||||
- cd c:\projects\libigl
|
||||
# Tutorials and tests
|
||||
- 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
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: 🐛 Bug Report
|
||||
about: If something isn't working as expected
|
||||
title: ''
|
||||
labels: bug, pending verification
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Describe the bug
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
#### Platform
|
||||
<!-- Check all that apply (change to `[x]`) -->
|
||||
|
||||
- [ ] Windows
|
||||
- [ ] macOS
|
||||
- [ ] Linux
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: 😱 Compilation issue
|
||||
about: Report a problem when compiling the code
|
||||
title: ''
|
||||
labels: 'compilation'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Describe your issue
|
||||
<!-- Be sure to include any log file that may help use diagnose the issue -->
|
||||
|
||||
|
||||
#### Checklist
|
||||
<!-- Check all that apply (change to `[x]`) -->
|
||||
|
||||
- [ ] I have read the [bug report](https://libigl.github.io/bug-report/)
|
||||
- [ ] CMake issue: I have tried with a fresh clone/empty build directory
|
||||
|
||||
#### Platform
|
||||
<!-- Check all that apply (change to `[x]`) -->
|
||||
|
||||
- [ ] Windows
|
||||
- [ ] macOS
|
||||
- [ ] Linux
|
||||
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 🚀 Feature Request
|
||||
url: https://github.com/libigl/libigl/discussions/new?category_id=32617689
|
||||
about: Share ideas for new features
|
||||
- name: ❓ Ask a Question
|
||||
url: https://github.com/libigl/libigl/discussions/new?category_id=32617688
|
||||
about: Ask the community for help
|
||||
@@ -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.
|
||||
@@ -1,8 +1,12 @@
|
||||
[Describe your changes and what you've already done to test it.]
|
||||
Fixes # .
|
||||
|
||||
<!-- Describe your changes and what you've already done to test it. -->
|
||||
|
||||
|
||||
#### Checklist
|
||||
<!-- Check all that apply (change to `[x]`) -->
|
||||
|
||||
#### 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.
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
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 }}, ${{ fromJSON('["Static", "HeaderOnly"]')[matrix.static == 'ON'] }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-latest]
|
||||
config: [Release]
|
||||
static: [ON, OFF]
|
||||
include:
|
||||
- os: macos-latest
|
||||
name: macOS
|
||||
- os: ubuntu-20.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:
|
||||
name: Windows (${{ matrix.config }}, ${{ fromJSON('["Static", "HeaderOnly"]')[matrix.static == 'ON'] }})
|
||||
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
|
||||
|
||||
- name: Set env
|
||||
run: |
|
||||
echo "BOOST_ROOT=$env:BOOST_ROOT_1_72_0" >> ${env:GITHUB_ENV}
|
||||
echo "appdata=$env:LOCALAPPDATA" >> ${env:GITHUB_ENV}
|
||||
|
||||
- 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 it available for the next steps of the job
|
||||
echo "${env:PATH}" >> ${env:GITHUB_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 ^
|
||||
-DCMAKE_JOB_POOLS=pool-linking=1;pool-compilation=2 ^
|
||||
-DCMAKE_JOB_POOL_COMPILE:STRING=pool-compilation ^
|
||||
-DCMAKE_JOB_POOL_LINK:STRING=pool-linking ^
|
||||
-B build ^
|
||||
-S .
|
||||
cmake --build build
|
||||
|
||||
- name: Tests
|
||||
run: cd build; ctest --verbose
|
||||
@@ -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 }}, ${{ fromJSON('["Static", "HeaderOnly"]')[matrix.static == 'ON'] }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
name: [
|
||||
ubuntu-20.04-gcc-8,
|
||||
ubuntu-20.04-gcc-9,
|
||||
ubuntu-20.04-gcc-10,
|
||||
ubuntu-20.04-clang-8,
|
||||
ubuntu-20.04-clang-9,
|
||||
ubuntu-20.04-clang-10,
|
||||
macOS-latest,
|
||||
]
|
||||
config: [Debug, Release]
|
||||
static: [ON, OFF]
|
||||
include:
|
||||
- name: ubuntu-20.04-gcc-8
|
||||
os: ubuntu-20.04
|
||||
compiler: gcc
|
||||
version: "8"
|
||||
|
||||
- name: ubuntu-20.04-gcc-9
|
||||
os: ubuntu-20.04
|
||||
compiler: gcc
|
||||
version: "9"
|
||||
|
||||
- name: ubuntu-20.04-gcc-10
|
||||
os: ubuntu-20.04
|
||||
compiler: gcc
|
||||
version: "10"
|
||||
|
||||
- name: ubuntu-20.04-clang-8
|
||||
os: ubuntu-20.04
|
||||
compiler: clang
|
||||
version: "8"
|
||||
|
||||
- name: ubuntu-20.04-clang-9
|
||||
os: ubuntu-20.04
|
||||
compiler: clang
|
||||
version: "9"
|
||||
|
||||
- name: ubuntu-20.04-clang-10
|
||||
os: ubuntu-20.04
|
||||
compiler: clang
|
||||
version: "10"
|
||||
|
||||
- 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: |
|
||||
sudo apt-get update
|
||||
|
||||
if [ "${{ matrix.compiler }}" = "gcc" ]; then
|
||||
sudo apt-get install -y g++-${{ matrix.version }}
|
||||
echo "CC=gcc-${{ matrix.version }}" >> $GITHUB_ENV
|
||||
echo "CXX=g++-${{ matrix.version }}" >> $GITHUB_ENV
|
||||
else
|
||||
sudo apt-get install -y clang-${{ matrix.version }}
|
||||
echo "CC=clang-${{ matrix.version }}" >> $GITHUB_ENV
|
||||
echo "CXX=clang++-${{ matrix.version }}" >> $GITHUB_ENV
|
||||
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 -j1
|
||||
|
||||
- name: Tests
|
||||
run: cd build; ctest --verbose
|
||||
|
||||
####################
|
||||
# Windows
|
||||
####################
|
||||
|
||||
Windows:
|
||||
name: Windows (${{ matrix.config }}, ${{ fromJSON('["Static", "HeaderOnly"]')[matrix.static == 'ON'] }})
|
||||
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 "BOOST_ROOT=$env:BOOST_ROOT_1_72_0" >> ${env:GITHUB_ENV}
|
||||
|
||||
# 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 ^
|
||||
-DCMAKE_JOB_POOLS=job-pool=1 ^
|
||||
-DCMAKE_JOB_POOL_COMPILE:STRING=job-pool ^
|
||||
-DCMAKE_JOB_POOL_LINK:STRING=job-pool ^
|
||||
-B build ^
|
||||
-S .
|
||||
cd build
|
||||
ninja -j 1 -k 10
|
||||
|
||||
- name: Tests
|
||||
run: cd build; ctest --verbose
|
||||
@@ -97,3 +97,4 @@ tutorial/cmake-build-debug
|
||||
tutorial/data
|
||||
tutorial/readme.html
|
||||
untitled
|
||||
scripts
|
||||
|
||||
-72
@@ -1,72 +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
|
||||
- xorg-dev
|
||||
homebrew:
|
||||
packages:
|
||||
- ccache
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
compiler: gcc # 4.8.4 by default on Trusty
|
||||
env:
|
||||
- MATRIX_EVAL="export CONFIG=Release"
|
||||
- os: linux
|
||||
compiler: gcc-7
|
||||
env:
|
||||
- MATRIX_EVAL="export CC=gcc-7 CXX=g++-7 CONFIG=Release"
|
||||
- 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 CMAKE_EXTRA='-DLIBIGL_USE_STATIC_LIBRARY=OFF'"
|
||||
- os: osx
|
||||
osx_image: xcode10.2
|
||||
compiler: clang
|
||||
env:
|
||||
- MATRIX_EVAL="export CONFIG=Debug 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 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
|
||||
- rm -rf build
|
||||
- ccache --show-stats
|
||||
@@ -1,8 +1,8 @@
|
||||
# libigl - A simple C++ geometry processing library
|
||||
[](https://travis-ci.org/libigl/libigl)
|
||||
[](https://ci.appveyor.com/project/danielepanozzo/libigl-6hjk1/branch/master)
|
||||

|
||||
[](https://github.com/libigl/libigl/actions?query=workflow%3ABuild+branch%3Amaster+event%3Apush)
|
||||
[](https://github.com/libigl/libigl/actions?query=workflow%3ANightly+branch%3Amaster+event%3Aschedule)
|
||||
[](https://anaconda.org/conda-forge/igl)
|
||||
|
||||

|
||||
|
||||
Documentation, tutorial, and instructions at <https://libigl.github.io>.
|
||||
|
||||
: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/).**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Distributed under the OSI-approved MIT License. See accompanying
|
||||
# file LICENSE or https://github.com/Crascit/DownloadProject for details.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.2)
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(${DL_ARGS_PROJ}-download NONE)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
|
||||
# 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/
|
||||
/usr/local/mosek/9.2/tools/platform/osx64x86/
|
||||
/opt/mosek/7/tools/platform/linux64x86/
|
||||
)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -67,7 +67,7 @@ endfunction()
|
||||
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
|
||||
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
|
||||
GIT_TAG ${LIBIGL_EIGEN_VERSION}
|
||||
${LIBIGL_BRANCH_OPTIONS}
|
||||
)
|
||||
@@ -77,7 +77,7 @@ endfunction()
|
||||
function(igl_download_embree)
|
||||
igl_download_project(embree
|
||||
GIT_REPOSITORY https://github.com/embree/embree.git
|
||||
GIT_TAG v3.5.2
|
||||
GIT_TAG v3.12.1
|
||||
${LIBIGL_BRANCH_OPTIONS}
|
||||
)
|
||||
endfunction()
|
||||
@@ -94,7 +94,7 @@ endfunction()
|
||||
function(igl_download_glfw)
|
||||
igl_download_project(glfw
|
||||
GIT_REPOSITORY https://github.com/glfw/glfw.git
|
||||
GIT_TAG 3.3
|
||||
GIT_TAG 3327050ca66ad34426a82c217c2d60ced61526b7
|
||||
${LIBIGL_BRANCH_OPTIONS}
|
||||
)
|
||||
endfunction()
|
||||
@@ -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 61b19489f1ba35934d9114c034b24eb5bff149e7 # 1.81 + patch for #1669
|
||||
${LIBIGL_BRANCH_OPTIONS}
|
||||
)
|
||||
igl_download_project(libigl-imgui
|
||||
GIT_REPOSITORY https://github.com/libigl/libigl-imgui.git
|
||||
GIT_TAG 07ecd3858acc71e70f0f9b2dea20a139bdddf8ae
|
||||
GIT_TAG 7e1053e750b0f4c129b046f4e455243cb7f804f3
|
||||
)
|
||||
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()
|
||||
|
||||
@@ -148,7 +157,7 @@ endfunction()
|
||||
function(igl_download_triangle)
|
||||
igl_download_project(triangle
|
||||
GIT_REPOSITORY https://github.com/libigl/triangle.git
|
||||
GIT_TAG d284c4a843efac043c310f5fa640b17cf7d96170
|
||||
GIT_TAG 5a70326574b34d6a51d9eaf6a9f78813657ee108
|
||||
)
|
||||
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 5a1d2194ec114bff51d5a33230586cafb83adc86
|
||||
GIT_TAG 488242fa2b1f98a9c5bd1441297fb4a99a6a9ae4
|
||||
)
|
||||
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 5994ecdab65aebc6c218c4c6f35e7822acf6fe99
|
||||
GIT_TAG 19cedf96d70702d8b3a83eb27934780c542356fe
|
||||
)
|
||||
endfunction()
|
||||
|
||||
@@ -184,7 +193,6 @@ 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 c1f9ede366d02e3531ecbaec5e3769312f31cccd
|
||||
)
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ igl_folder_targets("Tutorials"
|
||||
405_AsRigidAsPossible_bin
|
||||
406_FastAutomaticSkinningTransformations_bin
|
||||
407_BiharmonicCoordinates_bin
|
||||
408_DirectDeltaMush_bin
|
||||
501_HarmonicParam_bin
|
||||
502_LSCMParam_bin
|
||||
503_ARAPParam_bin
|
||||
@@ -111,6 +112,7 @@ igl_folder_targets("Tutorials"
|
||||
715_MeshImplicitFunction_bin
|
||||
716_HeatGeodesics_bin
|
||||
718_IterativeClosestPoint_bin
|
||||
719_ExplodedView_bin
|
||||
)
|
||||
|
||||
endfunction()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
# OS X requires a Mach-O dynamic library to have a baked "install name", that is used by other modules to link to it. Depending
|
||||
# on how the library is built, the install name is not always an absolute path, nor necessarily the same as the name of the
|
||||
# library file itself. This macro takes as input the name of a target, and a list of libraries that it links to (the output of
|
||||
# FIND_PACKAGE or FIND_LIBRARY calls), and generates a set of custom, post-build commands that, for each linked dylib, changes
|
||||
# the name the target uses to refer to it with a fully-qualified (absolute) version of the library's own install name. This
|
||||
# helps ensure that the target can be used from any location while still being able to locate the linked dynamic libraries.
|
||||
#
|
||||
# Note that this script does NOT handle the case when a linked library itself refers to another library using a non-absolute
|
||||
# name (Boost is a notorious example). To avoid such issues, it is recommended to use a static library instead of a shared one
|
||||
# in a non-standard location. Alternatively, set DYLD_LIBRARY_PATH to include these non-standard locations when running the
|
||||
# program (not recommended).
|
||||
#
|
||||
# Author: Siddhartha Chaudhuri, 2009.
|
||||
#
|
||||
|
||||
# Set the minimum required CMake version
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
# See cmake --help-policy CMP0011 for details on this one
|
||||
IF(POLICY CMP0011)
|
||||
CMAKE_POLICY(SET CMP0011 NEW)
|
||||
ENDIF(POLICY CMP0011)
|
||||
|
||||
# See cmake --help-policy CMP0026 for details on this one
|
||||
IF(POLICY CMP0026)
|
||||
CMAKE_POLICY(SET CMP0026 NEW)
|
||||
ENDIF(POLICY CMP0026)
|
||||
|
||||
# See cmake --help-policy CMP0045 for details on this one
|
||||
IF(POLICY CMP0045)
|
||||
CMAKE_POLICY(SET CMP0045 NEW)
|
||||
ENDIF(POLICY CMP0045)
|
||||
|
||||
MACRO(OSX_FIX_DYLIB_REFERENCES target libraries)
|
||||
|
||||
IF(APPLE)
|
||||
SET(OFIN_${target}_RPATHS )
|
||||
|
||||
FOREACH(OFIN_${target}_Library ${libraries})
|
||||
IF(${OFIN_${target}_Library} MATCHES "[.]dylib$"
|
||||
OR ${OFIN_${target}_Library} MATCHES "[.]framework/.+")
|
||||
|
||||
# Resolve symlinks and get absolute location
|
||||
GET_FILENAME_COMPONENT(OFIN_${target}_LibraryAbsolute ${OFIN_${target}_Library} ABSOLUTE)
|
||||
|
||||
# Get the baked install name of the library
|
||||
EXECUTE_PROCESS(COMMAND otool -D ${OFIN_${target}_LibraryAbsolute}
|
||||
OUTPUT_VARIABLE OFIN_${target}_LibraryInstallNameOutput
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
STRING(REGEX REPLACE "[\r\n]" " " OFIN_${target}_LibraryInstallNameOutput ${OFIN_${target}_LibraryInstallNameOutput})
|
||||
SEPARATE_ARGUMENTS(OFIN_${target}_LibraryInstallNameOutput)
|
||||
LIST(GET OFIN_${target}_LibraryInstallNameOutput 1 OFIN_${target}_LibraryInstallName)
|
||||
|
||||
IF(${OFIN_${target}_LibraryInstallName} MATCHES "^[@]rpath/")
|
||||
|
||||
# Ideally, we want to eliminate the longest common suffix of the install name and the absolute path. Whatever's left
|
||||
# will be the desired rpath. But this is difficult to do (especially if there are naming variations, e.g.
|
||||
# "Versions/Current" vs "Versions/5" is a common culprit). So we'll add various candidate rpaths and hope at least one
|
||||
# is correct.
|
||||
|
||||
# Typically, the rpath to a library within a framework looks like this:
|
||||
# @rpath/A.framework/Versions/5/libFoo.dylib
|
||||
#
|
||||
# Hence, we'll extract for the path unit immediately following the @rpath (in this case A.framework) and then look for
|
||||
# it in the library's actual path. Everything before this location will be put in the rpath.
|
||||
SET(OFIN_${target}_PathPrefix ${OFIN_${target}_LibraryInstallName})
|
||||
SET(OFIN_${target}_RpathFirstChild )
|
||||
WHILE(NOT OFIN_${target}_PathPrefix STREQUAL "@rpath")
|
||||
GET_FILENAME_COMPONENT(OFIN_${target}_RpathFirstChild ${OFIN_${target}_PathPrefix} NAME)
|
||||
GET_FILENAME_COMPONENT(OFIN_${target}_PathPrefix ${OFIN_${target}_PathPrefix} PATH)
|
||||
|
||||
IF(NOT OFIN_${target}_PathPrefix) # should never happen but just in case
|
||||
BREAK()
|
||||
ENDIF(NOT OFIN_${target}_PathPrefix)
|
||||
|
||||
IF(OFIN_${target}_PathPrefix STREQUAL "/") # should never happen but just in case
|
||||
BREAK()
|
||||
ENDIF(OFIN_${target}_PathPrefix STREQUAL "/")
|
||||
ENDWHILE(NOT OFIN_${target}_PathPrefix STREQUAL "@rpath")
|
||||
|
||||
IF(OFIN_${target}_RpathFirstChild)
|
||||
SET(OFIN_${target}_PathPrefix ${OFIN_${target}_LibraryAbsolute})
|
||||
SET(OFIN_${target}_PathUnit )
|
||||
WHILE(NOT OFIN_${target}_PathUnit STREQUAL ${OFIN_${target}_RpathFirstChild})
|
||||
GET_FILENAME_COMPONENT(OFIN_${target}_PathUnit ${OFIN_${target}_PathPrefix} NAME)
|
||||
GET_FILENAME_COMPONENT(OFIN_${target}_PathPrefix ${OFIN_${target}_PathPrefix} PATH)
|
||||
|
||||
IF(NOT OFIN_${target}_PathPrefix)
|
||||
BREAK()
|
||||
ENDIF(NOT OFIN_${target}_PathPrefix)
|
||||
|
||||
IF(OFIN_${target}_PathPrefix STREQUAL "/")
|
||||
BREAK()
|
||||
ENDIF(OFIN_${target}_PathPrefix STREQUAL "/")
|
||||
ENDWHILE(NOT OFIN_${target}_PathUnit STREQUAL ${OFIN_${target}_RpathFirstChild})
|
||||
|
||||
IF(OFIN_${target}_PathPrefix)
|
||||
SET(OFIN_${target}_RPATHS ${OFIN_${target}_RPATHS} "${OFIN_${target}_PathPrefix}")
|
||||
ENDIF(OFIN_${target}_PathPrefix)
|
||||
ENDIF(OFIN_${target}_RpathFirstChild)
|
||||
|
||||
# Add the directory containing the library
|
||||
GET_FILENAME_COMPONENT(OFIN_${target}_LibraryAbsolutePath ${OFIN_${target}_LibraryAbsolute} PATH)
|
||||
SET(OFIN_${target}_RPATHS ${OFIN_${target}_RPATHS} "${OFIN_${target}_LibraryAbsolutePath}")
|
||||
|
||||
# Add paths specified as library search prefixes
|
||||
FOREACH(prefix ${CMAKE_PREFIX_PATH})
|
||||
SET(OFIN_${target}_RPATHS ${OFIN_${target}_RPATHS} "${CMAKE_PREFIX_PATH}")
|
||||
SET(OFIN_${target}_RPATHS ${OFIN_${target}_RPATHS} "${CMAKE_PREFIX_PATH}/lib")
|
||||
ENDFOREACH()
|
||||
|
||||
ELSEIF(NOT ${OFIN_${target}_LibraryInstallName} MATCHES "^[@/]") # just a relative path
|
||||
|
||||
# Replace the unqualified filename, if it appears, with the absolute location, either by directly changing the path or
|
||||
# by editing the rpath
|
||||
|
||||
# -- handle the case when the actual filename is baked in
|
||||
GET_FILENAME_COMPONENT(OFIN_${target}_LibraryFilename ${OFIN_${target}_LibraryAbsolute} NAME)
|
||||
ADD_CUSTOM_COMMAND(TARGET ${target} POST_BUILD
|
||||
COMMAND install_name_tool
|
||||
ARGS -change
|
||||
${OFIN_${target}_LibraryFilename}
|
||||
${OFIN_${target}_LibraryAbsolute}
|
||||
$<TARGET_FILE:${target}>)
|
||||
|
||||
# -- handle the case when the install name is baked in
|
||||
ADD_CUSTOM_COMMAND(TARGET ${target} POST_BUILD
|
||||
COMMAND install_name_tool
|
||||
ARGS -change
|
||||
${OFIN_${target}_LibraryInstallName}
|
||||
${OFIN_${target}_LibraryAbsolute}
|
||||
$<TARGET_FILE:${target}>)
|
||||
ENDIF()
|
||||
|
||||
ENDIF()
|
||||
ENDFOREACH(OFIN_${target}_Library)
|
||||
|
||||
# Add the collected rpaths
|
||||
IF(OFIN_${target}_RPATHS)
|
||||
LIST(REMOVE_DUPLICATES OFIN_${target}_RPATHS)
|
||||
|
||||
FOREACH(rpath ${OFIN_${target}_RPATHS})
|
||||
ADD_CUSTOM_COMMAND(TARGET ${target} POST_BUILD
|
||||
COMMAND bash
|
||||
ARGS -c "install_name_tool -add_rpath '${rpath}' '$<TARGET_FILE:${target}>' > /dev/null 2>&1 || true"
|
||||
VERBATIM)
|
||||
ENDFOREACH()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
ENDMACRO(OSX_FIX_DYLIB_REFERENCES)
|
||||
+32
-22
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
# https://github.com/libigl/libigl/issues/751
|
||||
# http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160425/351643.html
|
||||
@@ -88,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)
|
||||
@@ -178,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)
|
||||
@@ -226,6 +224,7 @@ 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()
|
||||
@@ -239,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()
|
||||
|
||||
@@ -299,20 +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()
|
||||
|
||||
# Note: On macOS, building embree as a static lib can only be done with a single ISA target.
|
||||
set(EMBREE_MAX_ISA "DEFAULT" CACHE STRING "Selects highest ISA to support.")
|
||||
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_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()
|
||||
|
||||
@@ -374,11 +373,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)
|
||||
@@ -395,7 +399,13 @@ 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_compile_features(imguizmo PUBLIC cxx_std_11)
|
||||
target_link_libraries(imguizmo PUBLIC imgui)
|
||||
endif()
|
||||
target_link_libraries(igl_opengl_glfw_imgui ${IGL_SCOPE} igl_opengl_glfw imgui imguizmo)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
+35
-55
@@ -1025,64 +1025,44 @@ namespace igl
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
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;
|
||||
template void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::squared_distance<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, 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, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > 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, 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 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 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>::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;
|
||||
// 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>, 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 void igl::AABB<Eigen::Matrix<double, -1, 3, 1, -1, 3>, 3>::init<Eigen::Matrix<int, -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&);
|
||||
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>::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>::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>::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>::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 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;
|
||||
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;
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
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;
|
||||
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&);
|
||||
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;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Jérémie Dumas <jeremie.dumas@ens-lyon.org>
|
||||
//
|
||||
// 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_FILEENCODING_H
|
||||
#define IGL_FILEENCODING_H
|
||||
|
||||
namespace igl
|
||||
{
|
||||
|
||||
enum class FileEncoding {
|
||||
Binary,
|
||||
Ascii
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+7
-3
@@ -17,9 +17,13 @@ namespace igl
|
||||
struct Hit
|
||||
{
|
||||
int id; // primitive id
|
||||
int gid; // geometry id
|
||||
float u,v; // barycentric coordinates
|
||||
float t; // distance = direction*t to intersection
|
||||
int gid; // geometry id (not used)
|
||||
// barycentric coordinates so that
|
||||
// pos = V.row(F(id,0))*(1-u-v)+V.row(F(id,1))*u+V.row(F(id,2))*v;
|
||||
float u,v;
|
||||
// parametric distance so that
|
||||
// pos = origin + t * dir
|
||||
float t;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,497 @@
|
||||
// based on MSH reader from PyMesh
|
||||
|
||||
// Copyright (c) 2015 Qingnan Zhou <qzhou@adobe.com>
|
||||
// Copyright (C) 2020 Vladimir Fonov <vladimir.fonov@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "MshLoader.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace igl {
|
||||
// helper function
|
||||
void inline _msh_eat_white_space(std::ifstream& fin) {
|
||||
char next = fin.peek();
|
||||
while (next == '\n' || next == ' ' || next == '\t' || next == '\r') {
|
||||
fin.get();
|
||||
next = fin.peek();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE igl::MshLoader::MshLoader(const std::string &filename) {
|
||||
std::ifstream fin(filename, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!fin.is_open()) {
|
||||
std::stringstream err_msg;
|
||||
err_msg << "failed to open file \"" << filename << "\"";
|
||||
throw std::ios_base::failure(err_msg.str());
|
||||
}
|
||||
// Parse header
|
||||
std::string buf;
|
||||
double version;
|
||||
int type;
|
||||
fin >> buf;
|
||||
if (buf != "$MeshFormat") { throw std::runtime_error("Unexpected .msh format"); }
|
||||
|
||||
fin >> version >> type >> m_data_size;
|
||||
m_binary = (type == 1);
|
||||
if(version>2.2 || version<2.0)
|
||||
{
|
||||
// probably unsupported version
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Error: Unsupported file version:" << version << std::endl;
|
||||
throw std::runtime_error(err_msg.str());
|
||||
|
||||
}
|
||||
// Some sanity check.
|
||||
if (m_data_size != 8) {
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Error: data size must be 8 bytes." << std::endl;
|
||||
throw std::runtime_error(err_msg.str());
|
||||
}
|
||||
if (sizeof(int) != 4) {
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Error: code must be compiled with int size 4 bytes." << std::endl;
|
||||
throw std::runtime_error(err_msg.str());
|
||||
}
|
||||
|
||||
// Read in extra info from binary header.
|
||||
if (m_binary) {
|
||||
int one;
|
||||
igl::_msh_eat_white_space(fin);
|
||||
fin.read(reinterpret_cast<char*>(&one), sizeof(int));
|
||||
if (one != 1) {
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Binary msh file " << filename
|
||||
<< " is saved with different endianness than this machine."
|
||||
<< std::endl;
|
||||
throw std::runtime_error(err_msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
fin >> buf;
|
||||
if (buf != "$EndMeshFormat")
|
||||
{
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Unexpected contents in the file header." << std::endl;
|
||||
throw std::runtime_error(err_msg.str());
|
||||
}
|
||||
|
||||
while (!fin.eof()) {
|
||||
buf.clear();
|
||||
fin >> buf;
|
||||
if (buf == "$Nodes") {
|
||||
parse_nodes(fin);
|
||||
fin >> buf;
|
||||
if (buf != "$EndNodes") { throw std::runtime_error("Unexpected tag"); }
|
||||
} else if (buf == "$Elements") {
|
||||
parse_elements(fin);
|
||||
fin >> buf;
|
||||
if (buf != "$EndElements") { throw std::runtime_error("Unexpected tag"); }
|
||||
} else if (buf == "$NodeData") {
|
||||
parse_node_field(fin);
|
||||
fin >> buf;
|
||||
if (buf != "$EndNodeData") { throw std::runtime_error("Unexpected tag"); }
|
||||
} else if (buf == "$ElementData") {
|
||||
parse_element_field(fin);
|
||||
fin >> buf;
|
||||
if (buf != "$EndElementData") { throw std::runtime_error("Unexpected tag"); }
|
||||
} else if (fin.eof()) {
|
||||
break;
|
||||
} else {
|
||||
parse_unknown_field(fin, buf);
|
||||
}
|
||||
}
|
||||
fin.close();
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshLoader::parse_nodes(std::ifstream& fin) {
|
||||
size_t num_nodes;
|
||||
fin >> num_nodes;
|
||||
m_nodes.resize(num_nodes*3);
|
||||
|
||||
if (m_binary) {
|
||||
size_t stride = (4+3*m_data_size);
|
||||
size_t num_bytes = stride * num_nodes;
|
||||
char* data = new char[num_bytes];
|
||||
igl::_msh_eat_white_space(fin);
|
||||
fin.read(data, num_bytes);
|
||||
|
||||
for (size_t i=0; i<num_nodes; i++) {
|
||||
int node_idx;
|
||||
memcpy(&node_idx, data+i*stride, sizeof(int));
|
||||
node_idx-=1;
|
||||
// directly move into vector storage
|
||||
// this works only when m_data_size==sizeof(Float)==sizeof(double)
|
||||
memcpy(&m_nodes[node_idx*3], data+i*stride + 4, m_data_size*3);
|
||||
}
|
||||
delete [] data;
|
||||
} else {
|
||||
int node_idx;
|
||||
for (size_t i=0; i<num_nodes; i++) {
|
||||
fin >> node_idx;
|
||||
node_idx -= 1;
|
||||
// here it's 3D node explicitly
|
||||
fin >> m_nodes[node_idx*3]
|
||||
>> m_nodes[node_idx*3+1]
|
||||
>> m_nodes[node_idx*3+2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshLoader::parse_elements(std::ifstream& fin) {
|
||||
m_elements_tags.resize(2); //hardcoded to have 2 tags
|
||||
size_t num_elements;
|
||||
fin >> num_elements;
|
||||
|
||||
size_t nodes_per_element;
|
||||
|
||||
if (m_binary) {
|
||||
igl::_msh_eat_white_space(fin);
|
||||
int elem_read = 0;
|
||||
while (elem_read < num_elements) {
|
||||
// Parse element header.
|
||||
int elem_type, num_elems, num_tags;
|
||||
fin.read((char*)&elem_type, sizeof(int));
|
||||
fin.read((char*)&num_elems, sizeof(int));
|
||||
fin.read((char*)&num_tags, sizeof(int));
|
||||
nodes_per_element = num_nodes_per_elem_type(elem_type);
|
||||
|
||||
// store node info
|
||||
for (size_t i=0; i<num_elems; i++) {
|
||||
int elem_idx;
|
||||
|
||||
// all elements in the segment share the same elem_type and number of nodes per element
|
||||
m_elements_types.push_back(elem_type);
|
||||
m_elements_lengths.push_back(nodes_per_element);
|
||||
|
||||
fin.read((char*)&elem_idx, sizeof(int));
|
||||
elem_idx -= 1;
|
||||
m_elements_ids.push_back(elem_idx);
|
||||
|
||||
// read first two tags
|
||||
for (size_t j=0; j<num_tags; j++) {
|
||||
int tag;
|
||||
fin.read((char*)&tag, sizeof(int));
|
||||
if(j<2) m_elements_tags[j].push_back(tag);
|
||||
}
|
||||
|
||||
for (size_t j=num_tags; j<2; j++)
|
||||
m_elements_tags[j].push_back(-1); // fill up tags if less then 2
|
||||
|
||||
m_elements_nodes_idx.push_back(m_elements.size());
|
||||
// Element values.
|
||||
for (size_t j=0; j<nodes_per_element; j++) {
|
||||
int idx;
|
||||
fin.read((char*)&idx, sizeof(int));
|
||||
|
||||
m_elements.push_back(idx-1);
|
||||
}
|
||||
}
|
||||
elem_read += num_elems;
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<num_elements; i++) {
|
||||
// Parse per element header
|
||||
int elem_num, elem_type, num_tags;
|
||||
fin >> elem_num >> elem_type >> num_tags;
|
||||
|
||||
// read tags.
|
||||
for (size_t j=0; j<num_tags; j++) {
|
||||
int tag;
|
||||
fin >> tag;
|
||||
if(j<2) m_elements_tags[j].push_back(tag);
|
||||
}
|
||||
for (size_t j=num_tags; j<2; j++)
|
||||
m_elements_tags[j].push_back(-1); // fill up tags if less then 2
|
||||
|
||||
nodes_per_element = num_nodes_per_elem_type(elem_type);
|
||||
m_elements_types.push_back(elem_type);
|
||||
m_elements_lengths.push_back(nodes_per_element);
|
||||
|
||||
elem_num -= 1;
|
||||
m_elements_ids.push_back(elem_num);
|
||||
m_elements_nodes_idx.push_back(m_elements.size());
|
||||
// Parse node idx.
|
||||
for (size_t j=0; j<nodes_per_element; j++) {
|
||||
int idx;
|
||||
fin >> idx;
|
||||
m_elements.push_back(idx-1); // msh index starts from 1.
|
||||
}
|
||||
}
|
||||
}
|
||||
// debug
|
||||
assert(m_elements_types.size() == m_elements_ids.size());
|
||||
assert(m_elements_tags[0].size() == m_elements_ids.size());
|
||||
assert(m_elements_tags[1].size() == m_elements_ids.size());
|
||||
assert(m_elements_lengths.size() == m_elements_ids.size());
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshLoader::parse_node_field( std::ifstream& fin ) {
|
||||
size_t num_string_tags;
|
||||
size_t num_real_tags;
|
||||
size_t num_int_tags;
|
||||
|
||||
fin >> num_string_tags;
|
||||
std::vector<std::string> str_tags(num_string_tags);
|
||||
|
||||
for (size_t i=0; i<num_string_tags; i++) {
|
||||
igl::_msh_eat_white_space(fin);
|
||||
if (fin.peek() == '\"') {
|
||||
// Handle field name between quotes.
|
||||
char buf[128];
|
||||
fin.get(); // remove the quote at the beginning.
|
||||
fin.getline(buf, 128, '\"');
|
||||
str_tags[i] = std::string(buf);
|
||||
} else {
|
||||
fin >> str_tags[i];
|
||||
}
|
||||
}
|
||||
|
||||
fin >> num_real_tags;
|
||||
std::vector<Float> real_tags(num_real_tags);
|
||||
for (size_t i=0; i<num_real_tags; i++)
|
||||
fin >> real_tags[i];
|
||||
|
||||
fin >> num_int_tags;
|
||||
std::vector<int> int_tags(num_int_tags);
|
||||
for (size_t i=0; i<num_int_tags; i++)
|
||||
fin >> int_tags[i];
|
||||
|
||||
if (num_string_tags <= 0 || num_int_tags <= 2) {
|
||||
throw std::runtime_error("Unexpected number of field tags");
|
||||
}
|
||||
std::string fieldname = str_tags[0];
|
||||
int num_components = int_tags[1];
|
||||
int num_entries = int_tags[2];
|
||||
|
||||
std::vector<Float> field( num_entries*num_components );
|
||||
|
||||
if (m_binary) {
|
||||
size_t num_bytes = (num_components * m_data_size + 4) * num_entries;
|
||||
char* data = new char[num_bytes];
|
||||
igl::_msh_eat_white_space(fin);
|
||||
fin.read(data, num_bytes);
|
||||
for (size_t i=0; i<num_entries; i++) {
|
||||
int node_idx;
|
||||
memcpy(&node_idx,&data[i*(4+num_components*m_data_size)],4);
|
||||
|
||||
if(node_idx<1) throw std::runtime_error("Negative or zero index");
|
||||
node_idx -= 1;
|
||||
|
||||
if(node_idx>=num_entries) throw std::runtime_error("Index too big");
|
||||
size_t base_idx = i*(4+num_components*m_data_size) + 4;
|
||||
// TODO: make this work when m_data_size != sizeof(double) ?
|
||||
memcpy(&field[node_idx*num_components], &data[base_idx], num_components*m_data_size);
|
||||
}
|
||||
delete [] data;
|
||||
} else {
|
||||
int node_idx;
|
||||
for (size_t i=0; i<num_entries; i++) {
|
||||
fin >> node_idx;
|
||||
node_idx -= 1;
|
||||
for (size_t j=0; j<num_components; j++) {
|
||||
fin >> field[node_idx*num_components+j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_node_fields_names.push_back(fieldname);
|
||||
m_node_fields.push_back(field);
|
||||
m_node_fields_components.push_back(num_components);
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshLoader::parse_element_field(std::ifstream& fin) {
|
||||
size_t num_string_tags;
|
||||
size_t num_real_tags;
|
||||
size_t num_int_tags;
|
||||
|
||||
fin >> num_string_tags;
|
||||
std::vector<std::string> str_tags(num_string_tags);
|
||||
for (size_t i=0; i<num_string_tags; i++) {
|
||||
igl::_msh_eat_white_space(fin);
|
||||
if (fin.peek() == '\"') {
|
||||
// Handle field name between quoates.
|
||||
char buf[128];
|
||||
fin.get(); // remove the quote at the beginning.
|
||||
fin.getline(buf, 128, '\"');
|
||||
str_tags[i] = buf;
|
||||
} else {
|
||||
fin >> str_tags[i];
|
||||
}
|
||||
}
|
||||
|
||||
fin >> num_real_tags;
|
||||
std::vector<Float> real_tags(num_real_tags);
|
||||
for (size_t i=0; i<num_real_tags; i++)
|
||||
fin >> real_tags[i];
|
||||
|
||||
fin >> num_int_tags;
|
||||
std::vector<int> int_tags(num_int_tags);
|
||||
for (size_t i=0; i<num_int_tags; i++)
|
||||
fin >> int_tags[i];
|
||||
|
||||
if (num_string_tags <= 0 || num_int_tags <= 2) {
|
||||
throw std::runtime_error("Invalid file format");
|
||||
}
|
||||
std::string fieldname = str_tags[0];
|
||||
int num_components = int_tags[1];
|
||||
int num_entries = int_tags[2];
|
||||
std::vector<Float> field(num_entries*num_components);
|
||||
|
||||
if (m_binary) {
|
||||
size_t num_bytes = (num_components * m_data_size + 4) * num_entries;
|
||||
char* data = new char[num_bytes];
|
||||
igl::_msh_eat_white_space(fin);
|
||||
fin.read(data, num_bytes);
|
||||
for (int i=0; i<num_entries; i++) {
|
||||
int elem_idx;
|
||||
// works with sizeof(int)==4
|
||||
memcpy(&elem_idx, &data[i*(4+num_components*m_data_size)],4);
|
||||
elem_idx -= 1;
|
||||
|
||||
// directly copy data into vector storage space
|
||||
memcpy(&field[elem_idx*num_components], &data[i*(4+num_components*m_data_size) + 4], m_data_size*num_components);
|
||||
}
|
||||
delete [] data;
|
||||
} else {
|
||||
int elem_idx;
|
||||
for (size_t i=0; i<num_entries; i++) {
|
||||
fin >> elem_idx;
|
||||
elem_idx -= 1;
|
||||
for (size_t j=0; j<num_components; j++) {
|
||||
fin >> field[elem_idx*num_components+j];
|
||||
}
|
||||
}
|
||||
}
|
||||
m_element_fields_names.push_back(fieldname);
|
||||
m_element_fields.push_back(field);
|
||||
m_element_fields_components.push_back(num_components);
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshLoader::parse_unknown_field(std::ifstream& fin,
|
||||
const std::string& fieldname) {
|
||||
std::cerr << "Warning: \"" << fieldname << "\" not supported yet. Ignored." << std::endl;
|
||||
std::string endmark = fieldname.substr(0,1) + "End"
|
||||
+ fieldname.substr(1,fieldname.size()-1);
|
||||
|
||||
std::string buf("");
|
||||
while (buf != endmark && !fin.eof()) {
|
||||
fin >> buf;
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE int igl::MshLoader::num_nodes_per_elem_type(int elem_type) {
|
||||
int nodes_per_element = 0;
|
||||
switch (elem_type) {
|
||||
case ELEMENT_LINE: // 2-node line
|
||||
nodes_per_element = 2;
|
||||
break;
|
||||
case ELEMENT_TRI:
|
||||
nodes_per_element = 3; // 3-node triangle
|
||||
break;
|
||||
case ELEMENT_QUAD:
|
||||
nodes_per_element = 4; // 5-node quad
|
||||
break;
|
||||
case ELEMENT_TET:
|
||||
nodes_per_element = 4; // 4-node tetrahedra
|
||||
break;
|
||||
case ELEMENT_HEX: // 8-node hexahedron
|
||||
nodes_per_element = 8;
|
||||
break;
|
||||
case ELEMENT_PRISM: // 6-node prism
|
||||
nodes_per_element = 6;
|
||||
break;
|
||||
case ELEMENT_LINE_2ND_ORDER:
|
||||
nodes_per_element = 3;
|
||||
break;
|
||||
case ELEMENT_TRI_2ND_ORDER:
|
||||
nodes_per_element = 6;
|
||||
break;
|
||||
case ELEMENT_QUAD_2ND_ORDER:
|
||||
nodes_per_element = 9;
|
||||
break;
|
||||
case ELEMENT_TET_2ND_ORDER:
|
||||
nodes_per_element = 10;
|
||||
break;
|
||||
case ELEMENT_HEX_2ND_ORDER:
|
||||
nodes_per_element = 27;
|
||||
break;
|
||||
case ELEMENT_PRISM_2ND_ORDER:
|
||||
nodes_per_element = 18;
|
||||
break;
|
||||
case ELEMENT_PYRAMID_2ND_ORDER:
|
||||
nodes_per_element = 14;
|
||||
break;
|
||||
case ELEMENT_POINT: // 1-node point
|
||||
nodes_per_element = 1;
|
||||
break;
|
||||
default:
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Element type (" << elem_type << ") is not supported yet."
|
||||
<< std::endl;
|
||||
throw std::runtime_error(err_msg.str());
|
||||
}
|
||||
return nodes_per_element;
|
||||
}
|
||||
|
||||
|
||||
IGL_INLINE bool igl::MshLoader::is_element_map_identity() const
|
||||
{
|
||||
for(int i=0;i<m_elements_ids.size();i++) {
|
||||
int id=m_elements_ids[i];
|
||||
if (id!=i) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
IGL_INLINE void igl::MshLoader::index_structures(int tag_column)
|
||||
{
|
||||
//cleanup
|
||||
m_structure_index.clear();
|
||||
m_structures.clear();
|
||||
m_structure_length.clear();
|
||||
|
||||
//index structure tags
|
||||
for(auto i=0; i != m_elements_tags[tag_column].size(); ++i )
|
||||
{
|
||||
m_structure_index.insert(
|
||||
std::pair<msh_struct,int>(
|
||||
msh_struct( m_elements_tags[tag_column][i],
|
||||
m_elements_types[i]), i)
|
||||
);
|
||||
}
|
||||
|
||||
// identify unique structures
|
||||
std::vector<StructIndex::value_type> _unique_structs;
|
||||
std::unique_copy(std::begin(m_structure_index),
|
||||
std::end(m_structure_index),
|
||||
std::back_inserter(_unique_structs),
|
||||
[](const StructIndex::value_type &c1, const StructIndex::value_type &c2)
|
||||
{ return c1.first == c2.first; });
|
||||
|
||||
std::for_each( _unique_structs.begin(), _unique_structs.end(),
|
||||
[this](const StructIndex::value_type &n){ this->m_structures.push_back(n.first); });
|
||||
|
||||
for(auto t = m_structures.begin(); t != m_structures.end(); ++t)
|
||||
{
|
||||
// identify all elements corresponding to this tag
|
||||
auto structure_range = m_structure_index.equal_range( *t );
|
||||
int cnt=0;
|
||||
|
||||
for(auto i=structure_range.first; i!=structure_range.second; i++)
|
||||
cnt++;
|
||||
|
||||
m_structure_length.insert( std::pair<msh_struct,int>( *t, cnt));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
// based on MSH reader from PyMesh
|
||||
|
||||
// Copyright (c) 2015 Qingnan Zhou <qzhou@adobe.com>
|
||||
// Copyright (C) 2020 Vladimir Fonov <vladimir.fonov@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_MSH_LOADER_H
|
||||
#define IGL_MSH_LOADER_H
|
||||
#include "igl_inline.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace igl {
|
||||
|
||||
// Class for loading information from .msh file
|
||||
// depends only on c++stl library
|
||||
class MshLoader {
|
||||
public:
|
||||
|
||||
struct msh_struct {
|
||||
int tag,el_type;
|
||||
msh_struct(int _tag=0,int _type=0):
|
||||
tag(_tag),el_type(_type){}
|
||||
bool operator== (const msh_struct& a) const {
|
||||
return this->tag==a.tag &&
|
||||
this->el_type==a.el_type;
|
||||
}
|
||||
|
||||
bool operator< (const msh_struct& a) const {
|
||||
return (this->tag*100+this->el_type) <
|
||||
(a.tag*100+a.el_type);
|
||||
}
|
||||
};
|
||||
|
||||
typedef double Float;
|
||||
|
||||
typedef std::vector<int> IndexVector;
|
||||
typedef std::vector<int> IntVector;
|
||||
typedef std::vector<Float> FloatVector;
|
||||
typedef std::vector<FloatVector> FloatField;
|
||||
typedef std::vector<IntVector> IntField;
|
||||
typedef std::vector<std::string> FieldNames;
|
||||
typedef std::multimap<msh_struct,int> StructIndex;
|
||||
typedef std::vector<msh_struct> StructVector;
|
||||
|
||||
enum {ELEMENT_LINE=1, ELEMENT_TRI=2, ELEMENT_QUAD=3,
|
||||
ELEMENT_TET=4, ELEMENT_HEX=5, ELEMENT_PRISM=6,
|
||||
ELEMENT_PYRAMID=7,
|
||||
// 2nd order elements
|
||||
ELEMENT_LINE_2ND_ORDER=8, ELEMENT_TRI_2ND_ORDER=9,
|
||||
ELEMENT_QUAD_2ND_ORDER=10,ELEMENT_TET_2ND_ORDER=11,
|
||||
ELEMENT_HEX_2ND_ORDER=12, ELEMENT_PRISM_2ND_ORDER=13,
|
||||
ELEMENT_PYRAMID_2ND_ORDER=14,
|
||||
// other elements
|
||||
ELEMENT_POINT=15 };
|
||||
public:
|
||||
MshLoader(const std::string &filename);
|
||||
|
||||
public:
|
||||
|
||||
// get nodes , x,y,z sequentially
|
||||
const FloatVector& get_nodes() const { return m_nodes; }
|
||||
// get elements , identifying nodes that create an element
|
||||
// variable length per element
|
||||
const IndexVector& get_elements() const { return m_elements; }
|
||||
|
||||
// get element types
|
||||
const IntVector& get_elements_types() const { return m_elements_types; }
|
||||
// get element lengths
|
||||
const IntVector& get_elements_lengths() const { return m_elements_lengths; }
|
||||
// get element tags ( physical (0) and elementary (1) )
|
||||
const IntField& get_elements_tags() const { return m_elements_tags; }
|
||||
// get element IDs
|
||||
const IntVector& get_elements_ids() const { return m_elements_ids; }
|
||||
|
||||
// get reverse index from node to element
|
||||
const IndexVector& get_elements_nodes_idx() const { return m_elements_nodes_idx; }
|
||||
|
||||
// get fields assigned per node, all fields and components sequentially
|
||||
const FloatField& get_node_fields() const { return m_node_fields;}
|
||||
// get node field names,
|
||||
const FieldNames& get_node_fields_names() const { return m_node_fields_names;}
|
||||
// get number of node field components
|
||||
const IntVector& get_node_fields_components() const {return m_node_fields_components;}
|
||||
|
||||
int get_node_field_components(size_t c) const
|
||||
{
|
||||
return m_node_fields_components[c];
|
||||
}
|
||||
|
||||
// get fields assigned per element, all fields and components sequentially
|
||||
const FloatField& get_element_fields() const { return m_element_fields;}
|
||||
// get element field names
|
||||
const FieldNames& get_element_fields_names() const { return m_element_fields_names;}
|
||||
// get number of element field components
|
||||
const IntVector& get_element_fields_components() const {return m_element_fields_components;}
|
||||
|
||||
int get_element_field_components(size_t c) const {
|
||||
return m_element_fields_components[c];
|
||||
}
|
||||
// check if field is present at node level
|
||||
bool is_node_field(const std::string& fieldname) const {
|
||||
return (std::find(std::begin(m_node_fields_names),
|
||||
std::end(m_node_fields_names),
|
||||
fieldname) != std::end(m_node_fields_names) );
|
||||
}
|
||||
// check if field is present at element level
|
||||
bool is_element_field(const std::string& fieldname) const {
|
||||
return (std::find(std::begin(m_element_fields_names),
|
||||
std::end(m_element_fields_names),
|
||||
fieldname) != std::end(m_node_fields_names) );
|
||||
}
|
||||
|
||||
// check if all elements have ids assigned sequentially
|
||||
bool is_element_map_identity() const ;
|
||||
|
||||
// create tag index
|
||||
// tag_column: ( physical (0) or elementary (1) ) specifying which tag to use
|
||||
void index_structures(int tag_column);
|
||||
|
||||
// get tag index, call index_structure_tags first
|
||||
const StructIndex& get_structure_index() const
|
||||
{
|
||||
return m_structure_index;
|
||||
}
|
||||
|
||||
// get size of a structure identified by tag and element type
|
||||
const StructIndex& get_structure_length() const
|
||||
{
|
||||
return m_structure_length;
|
||||
}
|
||||
|
||||
//! get list of structures
|
||||
const StructVector& get_structures() const
|
||||
{
|
||||
return m_structures;
|
||||
}
|
||||
|
||||
public:
|
||||
// helper function, calculate number of nodes associated with an element
|
||||
static int num_nodes_per_elem_type(int elem_type);
|
||||
|
||||
private:
|
||||
void parse_nodes(std::ifstream& fin);
|
||||
void parse_elements(std::ifstream& fin);
|
||||
void parse_node_field(std::ifstream& fin);
|
||||
void parse_element_field(std::ifstream& fin);
|
||||
void parse_unknown_field(std::ifstream& fin,
|
||||
const std::string& fieldname);
|
||||
|
||||
private:
|
||||
bool m_binary;
|
||||
size_t m_data_size;
|
||||
|
||||
FloatVector m_nodes; // len x 3 vector
|
||||
|
||||
IndexVector m_elements; // linear array for nodes corresponding to each element
|
||||
IndexVector m_elements_nodes_idx; // element indexes
|
||||
|
||||
IntVector m_elements_ids; // element id's
|
||||
IntVector m_elements_types; // Element types
|
||||
IntVector m_elements_lengths; // Element lengths
|
||||
IntField m_elements_tags; // Element tags, currently 2xtags per element
|
||||
|
||||
FloatField m_node_fields; // Float field defined at each node
|
||||
IntVector m_node_fields_components; // Number of components for node field
|
||||
FieldNames m_node_fields_names; // Node field name
|
||||
|
||||
FloatField m_element_fields; // Float field defined at each element
|
||||
IntVector m_element_fields_components; // Number of components for element field
|
||||
FieldNames m_element_fields_names; // Element field name
|
||||
|
||||
StructIndex m_structure_index; // index tag ids
|
||||
StructVector m_structures; // unique structures
|
||||
StructIndex m_structure_length; // length of structures with consistent element type
|
||||
};
|
||||
|
||||
} //igl
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "MshLoader.cpp"
|
||||
#endif
|
||||
|
||||
#endif //IGL_MSH_LOADER_H
|
||||
@@ -0,0 +1,347 @@
|
||||
// based on MSH writer from PyMesh
|
||||
|
||||
// Copyright (c) 2015 Qingnan Zhou <qzhou@adobe.com>
|
||||
// Copyright (C) 2020 Vladimir Fonov <vladimir.fonov@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "MshSaver.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <exception>
|
||||
|
||||
|
||||
IGL_INLINE igl::MshSaver::MshSaver(const std::string& filename, bool binary) :
|
||||
m_binary(binary), m_num_nodes(0), m_num_elements(0) {
|
||||
if (!m_binary) {
|
||||
fout.open(filename.c_str(), std::fstream::out);
|
||||
} else {
|
||||
fout.open(filename.c_str(), std::fstream::binary);
|
||||
}
|
||||
if (!fout) {
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Error opening " << filename << " to write msh file." << std::endl;
|
||||
throw std::ios_base::failure(err_msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
IGL_INLINE igl::MshSaver::~MshSaver() {
|
||||
fout.close();
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshSaver::save_mesh(
|
||||
const FloatVector& nodes,
|
||||
const IndexVector& elements,
|
||||
const IntVector& element_lengths,
|
||||
const IntVector& element_types,
|
||||
const IntVector& element_tags
|
||||
) {
|
||||
|
||||
save_header();
|
||||
|
||||
save_nodes(nodes);
|
||||
|
||||
save_elements(elements, element_lengths, element_types, element_tags );
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshSaver::save_header() {
|
||||
if (!m_binary) {
|
||||
fout << "$MeshFormat" << std::endl;
|
||||
fout << "2.2 0 " << sizeof(double) << std::endl;
|
||||
fout << "$EndMeshFormat" << std::endl;
|
||||
fout.precision(17);
|
||||
} else {
|
||||
fout << "$MeshFormat" << std::endl;
|
||||
fout << "2.2 1 " << sizeof(double) << std::endl;
|
||||
int one = 1;
|
||||
fout.write((char*)&one, sizeof(int));
|
||||
fout << "\n$EndMeshFormat" << std::endl;
|
||||
}
|
||||
fout.flush();
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshSaver::save_nodes(const FloatVector& nodes) {
|
||||
// Save nodes.
|
||||
// 3D hadrcoded
|
||||
m_num_nodes = nodes.size() / 3;
|
||||
fout << "$Nodes" << std::endl;
|
||||
fout << m_num_nodes << std::endl;
|
||||
if (!m_binary) {
|
||||
for (size_t i=0; i<nodes.size(); i+=3) {
|
||||
//const VectorF& v = nodes.segment(i,m_dim);
|
||||
int node_idx = i/3 + 1;
|
||||
fout << node_idx << " " << nodes[i] << " " << nodes[i+1] << " " << nodes[i+2] << std::endl;
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<nodes.size(); i+=3) {
|
||||
//const VectorF& v = nodes.segment(i,m_dim);
|
||||
int node_idx = i/3 + 1;
|
||||
fout.write((const char*)&node_idx, sizeof(int));
|
||||
fout.write((const char*)&nodes[i], sizeof(Float)*3);
|
||||
}
|
||||
}
|
||||
fout << "$EndNodes" << std::endl;
|
||||
fout.flush();
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshSaver::save_elements(const IndexVector& elements,
|
||||
const IntVector& element_lengths,
|
||||
const IntVector& element_types,
|
||||
const IntVector& element_tags)
|
||||
{
|
||||
|
||||
m_num_elements = element_tags.size();
|
||||
assert(element_lengths.size() == element_types.size() );
|
||||
assert(element_lengths.size() == element_tags.size() );
|
||||
// TODO: sum up all lengths
|
||||
// Save elements.
|
||||
// node inxes are 1-based
|
||||
fout << "$Elements" << std::endl;
|
||||
fout << m_num_elements << std::endl;
|
||||
|
||||
if (m_num_elements > 0) {
|
||||
//int elem_type = el_type;
|
||||
int num_elems = m_num_elements;
|
||||
//int tags = 0;
|
||||
if (!m_binary) {
|
||||
size_t el_ptr=0;
|
||||
for (size_t i=0;i<m_num_elements;++i) {
|
||||
|
||||
int elem_num = (int) i + 1;
|
||||
///VectorI elem = elements.segment(i, nodes_per_element) + VectorI::Ones(nodes_per_element);
|
||||
// hardcoded: duplicate tags (I don't know why)
|
||||
fout << elem_num << " " << element_types[i] << " " << 2 << " "<< element_tags[i] << " "<< element_tags[i] << " ";
|
||||
for (size_t j=0; j<element_lengths[i]; j++) {
|
||||
fout << elements[el_ptr + j] + 1 << " ";
|
||||
}
|
||||
fout << std::endl;
|
||||
el_ptr+=element_lengths[i];
|
||||
}
|
||||
} else {
|
||||
size_t el_ptr=0,i=0;
|
||||
while(i<m_num_elements) {
|
||||
|
||||
// write elements in consistent chunks
|
||||
// TODO: refactor this code to be able to specify different elements
|
||||
// more effeciently
|
||||
|
||||
int elem_type=-1;
|
||||
int elem_len=-1;
|
||||
size_t j=i;
|
||||
for(;j<m_num_elements;++j)
|
||||
{
|
||||
if( elem_type==-1 )
|
||||
{
|
||||
elem_type=element_types[j];
|
||||
elem_len=element_lengths[j];
|
||||
} else if( elem_type!=element_types[j] ||
|
||||
elem_len!=element_lengths[j]) {
|
||||
break; // found the edge of the segment
|
||||
}
|
||||
}
|
||||
|
||||
//hardcoded: 2 tags
|
||||
int num_elems=j-i, num_tags=2;
|
||||
|
||||
fout.write((const char*)& elem_type, sizeof(int));
|
||||
fout.write((const char*)& num_elems, sizeof(int));
|
||||
fout.write((const char*)& num_tags, sizeof(int));
|
||||
|
||||
for(int k=0;k<num_elems; ++k,++i){
|
||||
int elem_num = (int )i + 1;
|
||||
fout.write((const char*)&elem_num, sizeof(int));
|
||||
|
||||
// HACK: hardcoded 2 tags
|
||||
fout.write((const char*)& element_tags[i], sizeof(int));
|
||||
fout.write((const char*)& element_tags[i], sizeof(int));
|
||||
|
||||
for (size_t e=0; e<elem_len; e++) {
|
||||
int _elem = static_cast<int>( elements[el_ptr + e] )+1;
|
||||
fout.write((const char*)&_elem, sizeof(int));
|
||||
}
|
||||
el_ptr+=elem_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fout << "$EndElements" << std::endl;
|
||||
fout.flush();
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshSaver::save_scalar_field(const std::string& fieldname, const FloatVector& field) {
|
||||
assert(field.size() == m_num_nodes);
|
||||
fout << "$NodeData" << std::endl;
|
||||
fout << "1" << std::endl; // num string tags.
|
||||
fout << "\"" << fieldname << "\"" << std::endl;
|
||||
fout << "1" << std::endl; // num real tags.
|
||||
fout << "0.0" << std::endl; // time value.
|
||||
fout << "3" << std::endl; // num int tags.
|
||||
fout << "0" << std::endl; // the time step
|
||||
fout << "1" << std::endl; // 1-component scalar field.
|
||||
fout << m_num_nodes << std::endl; // number of nodes
|
||||
|
||||
if (m_binary) {
|
||||
for (size_t i=0; i<m_num_nodes; i++) {
|
||||
int node_idx = i+1;
|
||||
fout.write((char*)&node_idx, sizeof(int));
|
||||
fout.write((char*)&field[i], sizeof(Float));
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<m_num_nodes; i++) {
|
||||
int node_idx = i+1;
|
||||
fout << node_idx << " " << field[i] << std::endl;
|
||||
}
|
||||
}
|
||||
fout << "$EndNodeData" << std::endl;
|
||||
fout.flush();
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshSaver::save_vector_field(const std::string& fieldname, const FloatVector& field) {
|
||||
assert(field.size() == 3 * m_num_nodes);
|
||||
|
||||
fout << "$NodeData" << std::endl;
|
||||
fout << "1" << std::endl; // num string tags.
|
||||
fout << "\"" << fieldname << "\"" << std::endl;
|
||||
fout << "1" << std::endl; // num real tags.
|
||||
fout << "0.0" << std::endl; // time value.
|
||||
fout << "3" << std::endl; // num int tags.
|
||||
fout << "0" << std::endl; // the time step
|
||||
fout << "3" << std::endl; // 3-component vector field.
|
||||
fout << m_num_nodes << std::endl; // number of nodes
|
||||
|
||||
const Float zero = 0.0;
|
||||
if (m_binary) {
|
||||
for (size_t i=0; i<m_num_nodes; i++) {
|
||||
int node_idx = i+1;
|
||||
fout.write((const char*)&node_idx, sizeof(int));
|
||||
fout.write((const char*)&field[i*3], sizeof(Float)*3);
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<m_num_nodes; i++) {
|
||||
int node_idx = i+1;
|
||||
fout << node_idx
|
||||
<< " " << field[i*3]
|
||||
<< " " << field[i*3+1]
|
||||
<< " " << field[i*3+2]
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
fout << "$EndNodeData" << std::endl;
|
||||
fout.flush();
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshSaver::save_elem_scalar_field(const std::string& fieldname, const FloatVector& field) {
|
||||
assert(field.size() == m_num_elements);
|
||||
fout << "$ElementData" << std::endl;
|
||||
fout << 1 << std::endl; // num string tags.
|
||||
fout << "\"" << fieldname << "\"" << std::endl;
|
||||
fout << "1" << std::endl; // num real tags.
|
||||
fout << "0.0" << std::endl; // time value.
|
||||
fout << "3" << std::endl; // num int tags.
|
||||
fout << "0" << std::endl; // the time step
|
||||
fout << "1" << std::endl; // 1-component scalar field.
|
||||
fout << m_num_elements << std::endl; // number of elements
|
||||
|
||||
if (m_binary) {
|
||||
for (size_t i=0; i<m_num_elements; i++) {
|
||||
int elem_idx = i+1;
|
||||
fout.write((const char*)&elem_idx, sizeof(int));
|
||||
fout.write((const char*)&field[i], sizeof(Float));
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<m_num_elements; i++) {
|
||||
int elem_idx = i+1;
|
||||
fout << elem_idx << " " << field[i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
fout << "$EndElementData" << std::endl;
|
||||
fout.flush();
|
||||
}
|
||||
|
||||
IGL_INLINE void igl::MshSaver::save_elem_vector_field(const std::string& fieldname, const FloatVector& field) {
|
||||
assert(field.size() == m_num_elements * 3);
|
||||
fout << "$ElementData" << std::endl;
|
||||
fout << 1 << std::endl; // num string tags.
|
||||
fout << "\"" << fieldname << "\"" << std::endl;
|
||||
fout << "1" << std::endl; // num real tags.
|
||||
fout << "0.0" << std::endl; // time value.
|
||||
fout << "3" << std::endl; // num int tags.
|
||||
fout << "0" << std::endl; // the time step
|
||||
fout << "3" << std::endl; // 3-component vector field.
|
||||
fout << m_num_elements << std::endl; // number of elements
|
||||
|
||||
const Float zero = 0.0;
|
||||
if (m_binary) {
|
||||
for (size_t i=0; i<m_num_elements; ++i) {
|
||||
int elem_idx = i+1;
|
||||
fout.write((const char*)&elem_idx, sizeof(int));
|
||||
fout.write((const char*)&field[i*3], sizeof(Float) * 3);
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<m_num_elements; ++i) {
|
||||
int elem_idx = i+1;
|
||||
fout << elem_idx
|
||||
<< " " << field[i*3]
|
||||
<< " " << field[i*3+1]
|
||||
<< " " << field[i*3+2]
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
fout << "$EndElementData" << std::endl;
|
||||
fout.flush();
|
||||
}
|
||||
|
||||
|
||||
IGL_INLINE void igl::MshSaver::save_elem_tensor_field(const std::string& fieldname, const FloatVector& field) {
|
||||
assert(field.size() == m_num_elements * 3 * (3 + 1) / 2);
|
||||
fout << "$ElementData" << std::endl;
|
||||
fout << 1 << std::endl; // num string tags.
|
||||
fout << "\"" << fieldname << "\"" << std::endl;
|
||||
fout << "1" << std::endl; // num real tags.
|
||||
fout << "0.0" << std::endl; // time value.
|
||||
fout << "3" << std::endl; // num int tags.
|
||||
fout << "0" << std::endl; // the time step
|
||||
fout << "9" << std::endl; // 9-component tensor field.
|
||||
fout << m_num_elements << std::endl; // number of elements
|
||||
|
||||
const Float zero = 0.0;
|
||||
|
||||
if (m_binary) {
|
||||
for (size_t i=0; i<m_num_elements; i++) {
|
||||
int elem_idx = i+1;
|
||||
fout.write((char*)&elem_idx, sizeof(int));
|
||||
//const VectorF& val = field.segment(i*6, 6);
|
||||
const Float* val = &field[i*6];
|
||||
Float tensor[9] = {
|
||||
val[0], val[5], val[4],
|
||||
val[5], val[1], val[3],
|
||||
val[4], val[3], val[2] };
|
||||
fout.write((char*)tensor, sizeof(Float) * 9);
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<m_num_elements; i++) {
|
||||
int elem_idx = i+1;
|
||||
const Float* val = &field[i*6];
|
||||
fout << elem_idx
|
||||
<< " " << val[0]
|
||||
<< " " << val[5]
|
||||
<< " " << val[4]
|
||||
<< " " << val[5]
|
||||
<< " " << val[1]
|
||||
<< " " << val[3]
|
||||
<< " " << val[4]
|
||||
<< " " << val[3]
|
||||
<< " " << val[2]
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
fout << "$EndElementData" << std::endl;
|
||||
fout.flush();
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// based on MSH writer from PyMesh
|
||||
|
||||
// Copyright (c) 2015 Qingnan Zhou <qzhou@adobe.com>
|
||||
// Copyright (C) 2020 Vladimir Fonov <vladimir.fonov@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_MSH_SAVER_H
|
||||
#define IGL_MSH_SAVER_H
|
||||
#include "igl_inline.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace igl {
|
||||
|
||||
// Class for dumping information to .msh file
|
||||
// depends only on c++stl library
|
||||
// current implementation works only with 3D information
|
||||
class MshSaver {
|
||||
public:
|
||||
typedef double Float;
|
||||
|
||||
typedef std::vector<int> IndexVector;
|
||||
typedef std::vector<int> IntVector;
|
||||
typedef std::vector<Float> FloatVector;
|
||||
typedef std::vector<FloatVector> FloatField;
|
||||
typedef std::vector<IntVector> IntField;
|
||||
typedef std::vector<std::string> FieldNames;
|
||||
|
||||
MshSaver(const std::string& filename, bool binary=true);
|
||||
~MshSaver();
|
||||
|
||||
public:
|
||||
// Only these element types are supported right now
|
||||
enum {ELEMENT_LINE=1, ELEMENT_TRI=2, ELEMENT_QUAD=3,
|
||||
ELEMENT_TET=4, ELEMENT_HEX=5, ELEMENT_PRISM=6 };
|
||||
|
||||
public:
|
||||
// save mesh geometry
|
||||
void save_mesh(
|
||||
const FloatVector& nodes,
|
||||
const IndexVector& elements,
|
||||
const IntVector& element_lengths,
|
||||
const IntVector& element_type,
|
||||
const IntVector& element_tags );
|
||||
|
||||
// save additional fields associated with the mesh
|
||||
|
||||
// add node scalar field
|
||||
void save_scalar_field(const std::string& fieldname, const FloatVector& field);
|
||||
// add node vectot field
|
||||
void save_vector_field(const std::string& fieldname, const FloatVector& field);
|
||||
// add element scalar field
|
||||
void save_elem_scalar_field(const std::string& fieldname, const FloatVector& field);
|
||||
// add element vector field
|
||||
void save_elem_vector_field(const std::string& fieldname, const FloatVector& field);
|
||||
// add element tensor field
|
||||
void save_elem_tensor_field(const std::string& fieldname, const FloatVector& field);
|
||||
|
||||
protected:
|
||||
void save_header();
|
||||
void save_nodes(const FloatVector& nodes);
|
||||
void save_elements(const IndexVector& elements,
|
||||
const IntVector& element_lengths,
|
||||
const IntVector& element_type,
|
||||
const IntVector& element_tags);
|
||||
|
||||
private:
|
||||
bool m_binary;
|
||||
size_t m_num_nodes;
|
||||
size_t m_num_elements;
|
||||
|
||||
std::ofstream fout;
|
||||
};
|
||||
} //igl
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "MshSaver.cpp"
|
||||
#endif
|
||||
|
||||
#endif //MSH_SAVER_H
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
//
|
||||
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -374,4 +374,16 @@ inline typename DerivedV::Scalar
|
||||
return igl::winding_number(BV,PBF,p);
|
||||
}
|
||||
|
||||
// This is a bullshit template because AABB annoyingly needs templates for bad
|
||||
// combinations of 3D V with DIM=2 AABB
|
||||
//
|
||||
// _Define_ as a no-op rather than monkeying around with the proper code above
|
||||
namespace igl
|
||||
{
|
||||
template <> inline igl::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3>,Eigen::Matrix<double, -1, 2, 0, -1, 2>,Eigen::Matrix<int, -1, 2, 0, -1, 2>>::WindingNumberAABB(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2>> & V, const Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2>> & F){};
|
||||
template <> inline void igl::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3>,Eigen::Matrix<double, -1, 2, 0, -1, 2>,Eigen::Matrix<int, -1, 2, 0, -1, 2>>::grow(){};
|
||||
template <> inline void igl::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3>,Eigen::Matrix<double, -1, 2, 0, -1, 2>,Eigen::Matrix<int, -1, 2, 0, -1, 2>>::init(){};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,58 @@ IGL_INLINE void igl::adjacency_matrix(
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DerivedI, typename DerivedC, typename T>
|
||||
IGL_INLINE void igl::adjacency_matrix(
|
||||
const Eigen::MatrixBase<DerivedI> & I,
|
||||
const Eigen::MatrixBase<DerivedC> & C,
|
||||
Eigen::SparseMatrix<T>& A)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace Eigen;
|
||||
|
||||
typedef Triplet<T> IJV;
|
||||
vector<IJV > ijv;
|
||||
ijv.reserve(C(C.size()-1)*2);
|
||||
typedef typename DerivedI::Scalar Index;
|
||||
const Index n = I.maxCoeff()+1;
|
||||
{
|
||||
// loop over polygons
|
||||
for(Index p = 0;p<C.size()-1;p++)
|
||||
{
|
||||
// number of edges
|
||||
const Index np = C(p+1)-C(p);
|
||||
// loop over edges
|
||||
for(Index c = 0;c<np;c++)
|
||||
{
|
||||
const Index i = I(C(p)+c);
|
||||
const Index j = I(C(p)+((c+1)%np));
|
||||
ijv.emplace_back(i,j,1);
|
||||
ijv.emplace_back(j,i,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
A.resize(n,n);
|
||||
A.reserve(6*n);
|
||||
A.setFromTriplets(ijv.begin(),ijv.end());
|
||||
|
||||
// Force all non-zeros to be one
|
||||
|
||||
// Iterate over outside
|
||||
for(int k=0; k<A.outerSize(); ++k)
|
||||
{
|
||||
// Iterate over inside
|
||||
for(typename Eigen::SparseMatrix<T>::InnerIterator it (A,k); it; ++it)
|
||||
{
|
||||
assert(it.value() != 0);
|
||||
A.coeffRef(it.row(),it.col()) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template void igl::adjacency_matrix<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<int, 0, int>& );
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::adjacency_matrix<Eigen::Matrix<int, -1, -1, 0, -1, -1>, bool>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<bool, 0, int>&);
|
||||
template void igl::adjacency_matrix<Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace igl
|
||||
// Inputs:
|
||||
// F #F by dim list of mesh simplices
|
||||
// Outputs:
|
||||
// A max(F) by max(F) adjacency matrix, each row i corresponding to V(i,:)
|
||||
// A max(F)+1 by max(F)+1 adjacency matrix, each row i corresponding to V(i,:)
|
||||
//
|
||||
// Example:
|
||||
// // Mesh in (V,F)
|
||||
@@ -42,6 +42,21 @@ namespace igl
|
||||
IGL_INLINE void adjacency_matrix(
|
||||
const Eigen::MatrixBase<DerivedF> & F,
|
||||
Eigen::SparseMatrix<T>& A);
|
||||
// Constructs an vertex adjacency for a polygon mesh.
|
||||
//
|
||||
// Inputs:
|
||||
// I #I vectorized list of polygon corner indices into rows of some matrix V
|
||||
// C #polygons+1 list of cumulative polygon sizes so that C(i+1)-C(i) =
|
||||
// size of the ith polygon, and so I(C(i)) through I(C(i+1)-1) are the
|
||||
// indices of the ith polygon
|
||||
// Outputs:
|
||||
// A max(I)+1 by max(I)+1 adjacency matrix, each row i corresponding to V(i,:)
|
||||
//
|
||||
template <typename DerivedI, typename DerivedC, typename T>
|
||||
IGL_INLINE void adjacency_matrix(
|
||||
const Eigen::MatrixBase<DerivedI> & I,
|
||||
const Eigen::MatrixBase<DerivedC> & C,
|
||||
Eigen::SparseMatrix<T>& A);
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#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
|
||||
@@ -1,39 +0,0 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_ALL_EDGES_H
|
||||
#define IGL_ALL_EDGES_H
|
||||
#include "igl_inline.h"
|
||||
#include "deprecated.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_DEPRECATED IGL_INLINE void all_edges(
|
||||
const Eigen::MatrixBase<DerivedF> & F,
|
||||
Eigen::PlainObjectBase<DerivedE> & E);
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "all_edges.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -128,6 +128,8 @@ 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<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, -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, 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> >&);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "get_seconds_hires.h"
|
||||
//#include "MKLEigenInterface.h"
|
||||
#include "min_quad_dense.h"
|
||||
#include "kkt_inverse.h"
|
||||
#include "get_seconds.h"
|
||||
#include "columnize.h"
|
||||
|
||||
@@ -543,7 +543,7 @@ IGL_INLINE bool igl::arap_dof_recomputation(
|
||||
#endif
|
||||
|
||||
// Compute dense solve matrix (alternative of matrix factorization)
|
||||
//printf("min_quad_dense_precompute()\n");
|
||||
//printf("kkt_inverse()\n");
|
||||
MatrixXd Qfull(*Q);
|
||||
MatrixXd A_eqfull(A_eq);
|
||||
MatrixXd M_Solve;
|
||||
@@ -552,7 +552,7 @@ IGL_INLINE bool igl::arap_dof_recomputation(
|
||||
bool use_lu = data.effective_dim != 2;
|
||||
//use_lu = false;
|
||||
//printf("use_lu: %s\n",(use_lu?"TRUE":"FALSE"));
|
||||
min_quad_dense_precompute(Qfull, A_eqfull, use_lu,M_Solve);
|
||||
kkt_inverse(Qfull, A_eqfull, use_lu,M_Solve);
|
||||
double timer0_end = get_seconds_hires();
|
||||
verbose("Bob timing: %.20f\n", (timer0_end - timer0_start)*1000.0);
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Oded Stein <oded.stein@columbia.edu>
|
||||
//
|
||||
// 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 "average_from_edges_onto_vertices.h"
|
||||
|
||||
template<typename DerivedF,typename DerivedE,typename DerivedoE,
|
||||
typename DeriveduE,typename DeriveduV>
|
||||
IGL_INLINE void
|
||||
igl::average_from_edges_onto_vertices(
|
||||
const Eigen::MatrixBase<DerivedF> &F,
|
||||
const Eigen::MatrixBase<DerivedE> &E,
|
||||
const Eigen::MatrixBase<DerivedoE> &oE,
|
||||
const Eigen::MatrixBase<DeriveduE> &uE,
|
||||
Eigen::PlainObjectBase<DeriveduV> &uV)
|
||||
{
|
||||
using Scalar = typename DeriveduE::Scalar;
|
||||
using VecX = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
|
||||
using Int = typename DerivedF::Scalar;
|
||||
|
||||
assert(E.rows()==F.rows() && "E does not match dimensions of F.");
|
||||
assert(oE.rows()==F.rows() && "oE does not match dimensions of F.");
|
||||
assert(E.cols()==3 && F.cols()==3 && oE.cols()==3 &&
|
||||
"This method is for triangle meshes.");
|
||||
|
||||
const Int n = F.maxCoeff()+1;
|
||||
|
||||
VecX edgesPerVertex(n);
|
||||
edgesPerVertex.setZero();
|
||||
uV.resize(n,1);
|
||||
uV.setZero();
|
||||
|
||||
for(Eigen::Index i=0; i<F.rows(); ++i) {
|
||||
for(int j=0; j<3; ++j) {
|
||||
if(oE(i,j)<0) {
|
||||
continue;
|
||||
}
|
||||
const Int e = E(i,j);
|
||||
const Int vi=F(i,(j+1)%3), vj=F(i,(j+2)%3);
|
||||
|
||||
//Count vertex valence
|
||||
++edgesPerVertex(vi);
|
||||
++edgesPerVertex(vj);
|
||||
|
||||
//Average uE value onto vertices
|
||||
uV(vi) += uE(e);
|
||||
uV(vj) += uE(e);
|
||||
}
|
||||
}
|
||||
|
||||
//Divide by valence
|
||||
for(Int i=0; i<n; ++i) {
|
||||
const Scalar valence = edgesPerVertex(i);
|
||||
if(valence>0) {
|
||||
uV(i) /= valence;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template void igl::average_from_edges_onto_vertices<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::PartialReduxExpr<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::internal::member_norm<double>, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::PartialReduxExpr<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::internal::member_norm<double>, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
template void igl::average_from_edges_onto_vertices<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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::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> >&);
|
||||
template void igl::average_from_edges_onto_vertices<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<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::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> >&);
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Oded Stein <oded.stein@columbia.edu>
|
||||
//
|
||||
// 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_FROM_EDGES_ONTO_VERTICES_H
|
||||
#define IGL_AVERAGE_FROM_EDGES_ONTO_VERTICES_H
|
||||
#include "igl_inline.h"
|
||||
|
||||
#include <Eigen/Dense>
|
||||
namespace igl
|
||||
{
|
||||
// Move a scalar field defined on edges to vertices by averaging
|
||||
//
|
||||
// Input:
|
||||
// F: triangle mesh connectivity
|
||||
// E, oE: mapping from halfedges to edges and orientation as generated by
|
||||
// orient_halfedges
|
||||
// uE: scalar field defined on edges, one per edge
|
||||
//
|
||||
// Output:
|
||||
// uV: scalar field defined on vertices
|
||||
template<typename DerivedF,typename DerivedE,typename DerivedoE,
|
||||
typename DeriveduE,typename DeriveduV>
|
||||
IGL_INLINE void average_from_edges_onto_vertices(
|
||||
const Eigen::MatrixBase<DerivedF> &F,
|
||||
const Eigen::MatrixBase<DerivedE> &E,
|
||||
const Eigen::MatrixBase<DerivedoE> &oE,
|
||||
const Eigen::MatrixBase<DeriveduE> &uE,
|
||||
Eigen::PlainObjectBase<DeriveduV> &uV);
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "average_from_edges_onto_vertices.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -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)
|
||||
@@ -22,4 +22,6 @@ IGL_INLINE void average_onto_faces(
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::average_onto_faces<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::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> >&);
|
||||
#endif
|
||||
|
||||
@@ -34,18 +34,13 @@ 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, -1, 0, -1, -1>, 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, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
|
||||
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> >&);
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#include "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
|
||||
@@ -0,0 +1,42 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_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
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2013 Daniele Panozzo <daniele.panozzo@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// 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
|
||||
@@ -1,42 +0,0 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2013 Daniele Panozzo <daniele.panozzo@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// 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
|
||||
@@ -0,0 +1,74 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#include "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
|
||||
@@ -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
|
||||
@@ -0,0 +1,71 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#include "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
|
||||
@@ -0,0 +1,40 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_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
|
||||
@@ -0,0 +1,372 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#include "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)
|
||||
{
|
||||
assert(M.count(nk));
|
||||
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();
|
||||
bool was_last = (std::next(miter) == Mvec.end());
|
||||
Mvec.pop_back();
|
||||
if (was_last) {
|
||||
// popping from the vector can invalidate the iterator, if it was
|
||||
// pointing to the last element that was popped. Alternatively,
|
||||
// one could use indices directly...
|
||||
miter = Mvec.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
@@ -0,0 +1,49 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_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
|
||||
@@ -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> >&);
|
||||
|
||||
@@ -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&);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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> >&);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+159
-180
@@ -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;
|
||||
// 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.
|
||||
}
|
||||
std::pair<double,int> p = *(Q.begin());
|
||||
if(p.first == std::numeric_limits<double>::infinity())
|
||||
{
|
||||
// min cost edge is infinite cost
|
||||
return false;
|
||||
}
|
||||
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
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "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
|
||||
@@ -0,0 +1,35 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_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
|
||||
@@ -49,6 +49,14 @@ igl::copyleft::cgal::assign(
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::copyleft::cgal::assign<Eigen::Matrix<double, -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::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<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> >&);
|
||||
|
||||
@@ -96,6 +96,8 @@ IGL_INLINE void igl::copyleft::cgal::convex_hull(
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::copyleft::cgal::convex_hull<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::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
||||
template void igl::copyleft::cgal::convex_hull<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::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
||||
template void igl::copyleft::cgal::convex_hull<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,7 +1,7 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
|
||||
//
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
@@ -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> >&);
|
||||
|
||||
@@ -48,6 +48,12 @@ 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<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, CGAL::Simple_cartesian<double> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
|
||||
// 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> > >&);
|
||||
|
||||
@@ -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<
|
||||
|
||||
@@ -133,7 +133,10 @@ IGL_INLINE void igl::copyleft::cgal::point_mesh_squared_distance(
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Simple_cartesian<double>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, 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::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> > const&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > > 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, 3, 1, -1, 3> >&);
|
||||
template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Epeck, 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::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<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> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
template void igl::copyleft::cgal::point_mesh_squared_distance<CGAL::Epeck, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, 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<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<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<double, -1, -1, 0, -1, -1> >&);
|
||||
template void igl::copyleft::cgal::point_mesh_squared_distance_precompute<CGAL::Simple_cartesian<double>, 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&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> >&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
|
||||
template void igl::copyleft::cgal::point_mesh_squared_distance_precompute<CGAL::Simple_cartesian<double>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, CGAL::AABB_tree<CGAL::AABB_traits<CGAL::Simple_cartesian<double>, CGAL::AABB_triangle_primitive<CGAL::Simple_cartesian<double>, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >::iterator, CGAL::Boolean_tag<false> >, CGAL::Default> >&, std::vector<CGAL::Triangle_3<CGAL::Simple_cartesian<double> >, std::allocator<CGAL::Triangle_3<CGAL::Simple_cartesian<double> > > >&);
|
||||
#endif
|
||||
|
||||
@@ -61,9 +61,11 @@ IGL_INLINE void igl::copyleft::cgal::polyhedron_to_mesh(
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Polyhedron_items_with_id_3.h>
|
||||
template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> >, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
||||
template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> >, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Epick, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
||||
template void igl::copyleft::cgal::polyhedron_to_mesh<CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>,CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> >, Eigen::Matrix<double, -1, -1, 0,-1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>,CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default, std::allocator<int> > const&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0,-1, -1> >&);
|
||||
#endif
|
||||
|
||||
@@ -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>> &);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -204,3 +204,9 @@ IGL_INLINE void igl::copyleft::cgal::snap_rounding(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::copyleft::cgal::snap_rounding<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
|
||||
#endif
|
||||
|
||||
@@ -132,3 +132,11 @@ IGL_INLINE void igl::copyleft::cgal::subdivide_segments(
|
||||
list_to_matrix(vIM,IM);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::copyleft::cgal::subdivide_segments<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<CGAL::Point_2<CGAL::Epeck>, std::allocator<CGAL::Point_2<CGAL::Epeck> > >, std::allocator<std::vector<CGAL::Point_2<CGAL::Epeck>, std::allocator<CGAL::Point_2<CGAL::Epeck> > > > > 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> >&);
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::copyleft::cgal::subdivide_segments<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1>, 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<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<CGAL::Point_2<CGAL::Epeck>, std::allocator<CGAL::Point_2<CGAL::Epeck> > >, std::allocator<std::vector<CGAL::Point_2<CGAL::Epeck>, std::allocator<CGAL::Point_2<CGAL::Epeck> > > > > 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
|
||||
|
||||
@@ -11,4 +11,5 @@
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
#undef IGL_STATIC_LIBRARY
|
||||
#include "../../unique.cpp"
|
||||
template void igl::unique<CGAL::Point_2<CGAL::Epeck> >(std::vector<CGAL::Point_2<CGAL::Epeck>, std::allocator<CGAL::Point_2<CGAL::Epeck> > > const&, std::vector<CGAL::Point_2<CGAL::Epeck>, std::allocator<CGAL::Point_2<CGAL::Epeck> > >&, std::vector<unsigned long, std::allocator<unsigned long> >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../../slice.h"
|
||||
#include "../../PI.h"
|
||||
#include "convex_hull.h"
|
||||
#include "coplanar.h"
|
||||
#include "mesh_boolean.h"
|
||||
#include <Eigen/Geometry>
|
||||
#include <vector>
|
||||
@@ -11,19 +12,22 @@
|
||||
template <
|
||||
typename DerivedWV,
|
||||
typename DerivedWE,
|
||||
typename Derivedth,
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename DerivedJ>
|
||||
IGL_INLINE void igl::copyleft::cgal::wire_mesh(
|
||||
const Eigen::MatrixBase<DerivedWV> & WV,
|
||||
const Eigen::MatrixBase<DerivedWE> & WE,
|
||||
const double th,
|
||||
const Eigen::MatrixBase<Derivedth> & th,
|
||||
const int poly_size,
|
||||
const bool solid,
|
||||
Eigen::PlainObjectBase<DerivedV> & V,
|
||||
Eigen::PlainObjectBase<DerivedF> & F,
|
||||
Eigen::PlainObjectBase<DerivedJ> & J)
|
||||
{
|
||||
assert((th.size()==1 || th.size()==WE.rows()) &&
|
||||
"th should be scalar or size of WE");
|
||||
|
||||
typedef typename DerivedWV::Scalar Scalar;
|
||||
// Canonical polygon to place at each endpoint
|
||||
@@ -87,7 +91,7 @@ IGL_INLINE void igl::copyleft::cgal::wire_mesh(
|
||||
// loop over polygon vertices
|
||||
for(int p = 0;p<PV.rows();p++)
|
||||
{
|
||||
RowVector3S qp = q*(PV.row(p)*th);
|
||||
RowVector3S qp = q*(PV.row(p)*th(e%th.size()));
|
||||
// loop over endpoints
|
||||
for(int c = 0;c<2;c++)
|
||||
{
|
||||
@@ -98,7 +102,8 @@ IGL_INLINE void igl::copyleft::cgal::wire_mesh(
|
||||
// Max out amount at 1/3 of edge length so that there's always some
|
||||
// amount of edge
|
||||
// Zero out if vertex is incident on only one edge
|
||||
Scalar dist = std::min(1.*th,len/3.0) * (nedges[WE(e,c)] > 1);
|
||||
Scalar dist =
|
||||
std::min(1.*th(e%th.size()),len/3.0)*(nedges[WE(e,c)] > 1);
|
||||
// Move to endpoint, offset by amount
|
||||
V.row(index(e,c,p)) =
|
||||
qp+WV.row(WE(e,c)) + dist*dir*uv;
|
||||
@@ -113,6 +118,10 @@ IGL_INLINE void igl::copyleft::cgal::wire_mesh(
|
||||
{
|
||||
MatrixX3S Vv;
|
||||
igl::slice(V,I,1,Vv);
|
||||
if(coplanar(Vv))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Eigen::MatrixXi Fv;
|
||||
convex_hull(Vv,Fv);
|
||||
for(int f = 0;f<Fv.rows();f++)
|
||||
@@ -201,6 +210,26 @@ IGL_INLINE void igl::copyleft::cgal::wire_mesh(
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename DerivedWV,
|
||||
typename DerivedWE,
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename DerivedJ>
|
||||
IGL_INLINE void igl::copyleft::cgal::wire_mesh(
|
||||
const Eigen::MatrixBase<DerivedWV> & WV,
|
||||
const Eigen::MatrixBase<DerivedWE> & WE,
|
||||
const double th,
|
||||
const int poly_size,
|
||||
const bool solid,
|
||||
Eigen::PlainObjectBase<DerivedV> & V,
|
||||
Eigen::PlainObjectBase<DerivedF> & F,
|
||||
Eigen::PlainObjectBase<DerivedJ> & J)
|
||||
{
|
||||
return wire_mesh(
|
||||
WV,WE,(Eigen::VectorXd(1,1)<<th).finished(),poly_size,solid,V,F,J);
|
||||
}
|
||||
|
||||
template <
|
||||
typename DerivedWV,
|
||||
typename DerivedWE,
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace igl
|
||||
// Inputs:
|
||||
// WV #WV by 3 list of vertex positions
|
||||
// WE #WE by 2 list of edge indices into WV
|
||||
// th diameter thickness of wire
|
||||
// th #WE diameter thicknesses of wire edges
|
||||
// poly_size number of sides on each wire (e.g., 4 would produce wires by
|
||||
// connecting rectangular prisms).
|
||||
// solid whether to resolve self-intersections to
|
||||
@@ -26,6 +26,22 @@ namespace igl
|
||||
// output faces J(j) < #WV means the face corresponds to the J(j)th
|
||||
// vertex in WV. J(j) >= #WV means the face corresponds to the
|
||||
// (J(j)-#WV)th edge in WE.
|
||||
template <
|
||||
typename DerivedWV,
|
||||
typename DerivedWE,
|
||||
typename Derivedth,
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename DerivedJ>
|
||||
IGL_INLINE void wire_mesh(
|
||||
const Eigen::MatrixBase<DerivedWV> & WV,
|
||||
const Eigen::MatrixBase<DerivedWE> & WE,
|
||||
const Eigen::MatrixBase<Derivedth> & th,
|
||||
const int poly_size,
|
||||
const bool solid,
|
||||
Eigen::PlainObjectBase<DerivedV> & V,
|
||||
Eigen::PlainObjectBase<DerivedF> & F,
|
||||
Eigen::PlainObjectBase<DerivedJ> & J);
|
||||
template <
|
||||
typename DerivedWV,
|
||||
typename DerivedWE,
|
||||
|
||||
@@ -531,6 +531,8 @@ IGL_INLINE void igl::copyleft::marching_cubes(
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
|
||||
template void igl::copyleft::marching_cubes<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
|
||||
template void igl::copyleft::marching_cubes<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
|
||||
template void igl::copyleft::marching_cubes<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace igl
|
||||
// vertices #V by 3 list of mesh vertex positions
|
||||
// faces #F by 3 list of mesh triangle indices
|
||||
//
|
||||
// See also: igl::marching_cubes
|
||||
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedFaces>
|
||||
IGL_INLINE void marching_cubes(
|
||||
const Eigen::MatrixBase<DerivedValues> &values,
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
#include "offset_surface.h"
|
||||
#include "marching_cubes.h"
|
||||
#include "../voxel_grid.h"
|
||||
#include "../signed_distance.h"
|
||||
#include "../flood_fill.h"
|
||||
#include <cassert>
|
||||
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename isolevelType,
|
||||
typename DerivedSV,
|
||||
typename DerivedSF,
|
||||
typename DerivedGV,
|
||||
typename Derivedside,
|
||||
typename DerivedS>
|
||||
void igl::copyleft::offset_surface(
|
||||
const Eigen::MatrixBase<DerivedV> & V,
|
||||
const Eigen::MatrixBase<DerivedF> & F,
|
||||
const isolevelType isolevel,
|
||||
const typename Derivedside::Scalar s,
|
||||
const SignedDistanceType & signed_distance_type,
|
||||
Eigen::PlainObjectBase<DerivedSV> & SV,
|
||||
Eigen::PlainObjectBase<DerivedSF> & SF,
|
||||
Eigen::PlainObjectBase<DerivedGV> & GV,
|
||||
Eigen::PlainObjectBase<Derivedside> & side,
|
||||
Eigen::PlainObjectBase<DerivedS> & S)
|
||||
{
|
||||
typedef typename DerivedV::Scalar Scalar;
|
||||
typedef typename DerivedF::Scalar Index;
|
||||
{
|
||||
Eigen::AlignedBox<Scalar,3> box;
|
||||
typedef Eigen::Matrix<Scalar,1,3> RowVector3S;
|
||||
assert(V.cols() == 3 && "V must contain positions in 3D");
|
||||
RowVector3S min_ext = V.colwise().minCoeff().array() - isolevel;
|
||||
RowVector3S max_ext = V.colwise().maxCoeff().array() + isolevel;
|
||||
box.extend(min_ext.transpose());
|
||||
box.extend(max_ext.transpose());
|
||||
igl::voxel_grid(box,s,1,GV,side);
|
||||
}
|
||||
|
||||
const Scalar h =
|
||||
(GV.col(0).maxCoeff()-GV.col(0).minCoeff())/((Scalar)(side(0)-1));
|
||||
const Scalar lower_bound = isolevel-sqrt(3.0)*h;
|
||||
const Scalar upper_bound = isolevel+sqrt(3.0)*h;
|
||||
{
|
||||
Eigen::Matrix<Index,Eigen::Dynamic,1> I;
|
||||
Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,3> C,N;
|
||||
igl::signed_distance(
|
||||
GV,V,F,signed_distance_type,lower_bound,upper_bound,S,I,C,N);
|
||||
}
|
||||
igl::flood_fill(side,S);
|
||||
|
||||
DerivedS SS = S.array()-isolevel;
|
||||
igl::copyleft::marching_cubes(SS,GV,side(0),side(1),side(2),SV,SF);
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::copyleft::offset_surface<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, double, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, 1, 3, 1, 1, 3>, 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, 3, 1, -1, 3> > const&, double, Eigen::Matrix<int, 1, 3, 1, 1, 3>::Scalar, igl::SignedDistanceType 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<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
|
||||
template void igl::copyleft::offset_surface<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, float, 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, 3, 1, 1, 3>, 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, 3, 1, -1, 3> > const&, float, Eigen::Matrix<int, 1, 3, 1, 1, 3>::Scalar, igl::SignedDistanceType const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
|
||||
template void igl::copyleft::offset_surface<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>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, 1, 3, 1, 1, 3>, 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&, double, Eigen::Matrix<int, 1, 3, 1, 1, 3>::Scalar, igl::SignedDistanceType 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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef IGL_COPYLEFT_OFFSET_SURFACE_H
|
||||
#define IGL_COPYLEFT_OFFSET_SURFACE_H
|
||||
#include "../igl_inline.h"
|
||||
#include "../signed_distance.h"
|
||||
#include <Eigen/Core>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace copyleft
|
||||
{
|
||||
// Compute a triangulated offset surface using matching cubes on a grid of
|
||||
// signed distance values from the input triangle mesh.
|
||||
//
|
||||
// Inputs:
|
||||
// V #V by 3 list of mesh vertex positions
|
||||
// F #F by 3 list of mesh triangle indices into V
|
||||
// isolevel iso level to extract (signed distance: negative inside)
|
||||
// s number of grid cells along longest side (controls resolution)
|
||||
// signed_distance_type type of signing to use (see
|
||||
// ../signed_distance.h)
|
||||
// Outputs:
|
||||
// SV #SV by 3 list of output surface mesh vertex positions
|
||||
// SF #SF by 3 list of output mesh triangle indices into SV
|
||||
// GV #GV=side(0)*side(1)*side(2) by 3 list of grid cell centers
|
||||
// side list of number of grid cells in x, y, and z directions
|
||||
// S #GV by 3 list of signed distance values _near_ `isolevel` ("far"
|
||||
// from `isolevel` these values are incorrect)
|
||||
//
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename isolevelType,
|
||||
typename DerivedSV,
|
||||
typename DerivedSF,
|
||||
typename DerivedGV,
|
||||
typename Derivedside,
|
||||
typename DerivedS>
|
||||
void offset_surface(
|
||||
const Eigen::MatrixBase<DerivedV> & V,
|
||||
const Eigen::MatrixBase<DerivedF> & F,
|
||||
const isolevelType isolevel,
|
||||
const typename Derivedside::Scalar s,
|
||||
const SignedDistanceType & signed_distance_type,
|
||||
Eigen::PlainObjectBase<DerivedSV> & SV,
|
||||
Eigen::PlainObjectBase<DerivedSF> & SF,
|
||||
Eigen::PlainObjectBase<DerivedGV> & GV,
|
||||
Eigen::PlainObjectBase<Derivedside> & side,
|
||||
Eigen::PlainObjectBase<DerivedS> & S);
|
||||
}
|
||||
}
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "offset_surface.cpp"
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "quadprog.h"
|
||||
#include "../matlab_format.h"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
/*
|
||||
FILE eiquadprog.hh
|
||||
|
||||
@@ -92,6 +95,22 @@ IGL_INLINE bool igl::copyleft::quadprog(
|
||||
{
|
||||
using namespace Eigen;
|
||||
typedef double Scalar;
|
||||
|
||||
|
||||
const auto print_ivector= [](const char* name, const Eigen::MatrixXi & A, int n)
|
||||
{
|
||||
std::cout<<igl::matlab_format(A,name)<<std::endl;
|
||||
};
|
||||
const auto print_matrix = [](const char* name, const Eigen::MatrixXd & A, int n)
|
||||
{
|
||||
std::cout<<igl::matlab_format(A,name)<<std::endl;
|
||||
};
|
||||
|
||||
const auto print_vector = [](const char* name, const Eigen::VectorXd & v, int n)
|
||||
{
|
||||
std::cout<<igl::matlab_format(v,name)<<std::endl;
|
||||
};
|
||||
|
||||
const auto distance = [](Scalar a, Scalar b)->Scalar
|
||||
{
|
||||
Scalar a1, b1, t;
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef IGL_COPYLEFT_SWEPT_VOLUME_H
|
||||
#define IGL_COPYLEFT_SWEPT_VOLUME_H
|
||||
#include "../igl_inline.h"
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Geometry>
|
||||
namespace igl
|
||||
{
|
||||
namespace copyleft
|
||||
{
|
||||
// Compute the surface of the swept volume of a solid object with surface
|
||||
// (V,F) mesh under going rigid motion.
|
||||
//
|
||||
// Inputs:
|
||||
// V #V by 3 list of mesh positions in reference pose
|
||||
// F #F by 3 list of mesh indices into V
|
||||
// transform function handle so that transform(t) returns the rigid
|
||||
// transformation at time t∈[0,1]
|
||||
// steps number of time steps: steps=3 --> t∈{0,0.5,1}
|
||||
// grid_res number of grid cells on the longest side containing the
|
||||
// motion (isolevel+1 cells will also be added on each side as padding)
|
||||
// isolevel distance level to be contoured as swept volume
|
||||
// Outputs:
|
||||
// SV #SV by 3 list of mesh positions of the swept surface
|
||||
// SF #SF by 3 list of mesh faces into SV
|
||||
IGL_INLINE void swept_volume(
|
||||
const Eigen::MatrixXd & V,
|
||||
const Eigen::MatrixXi & F,
|
||||
const std::function<Eigen::Affine3d(const double t)> & transform,
|
||||
const size_t steps,
|
||||
const size_t grid_res,
|
||||
const size_t isolevel,
|
||||
Eigen::MatrixXd & SV,
|
||||
Eigen::MatrixXi & SF);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "swept_volume.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -13,120 +13,6 @@
|
||||
// STL includes
|
||||
#include <iostream>
|
||||
|
||||
IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
|
||||
const tetgenio & out,
|
||||
std::vector<std::vector<REAL > > & V,
|
||||
std::vector<std::vector<int> > & T,
|
||||
std::vector<std::vector<int > > & F,
|
||||
std::vector<std::vector<REAL > >& R,
|
||||
std::vector<std::vector<int > >& N,
|
||||
std::vector<std::vector<int > >& PT,
|
||||
std::vector<std::vector<int > >& FT,
|
||||
size_t & nR )
|
||||
{
|
||||
using namespace std;
|
||||
// process points
|
||||
if(out.pointlist == NULL)
|
||||
{
|
||||
cerr<<"^tetgenio_to_tetmesh Error: point list is NULL\n"<<endl;
|
||||
return false;
|
||||
}
|
||||
V.resize(out.numberofpoints,vector<REAL>(3));
|
||||
// loop over points
|
||||
for(int i = 0;i < out.numberofpoints; i++)
|
||||
{
|
||||
V[i][0] = out.pointlist[i*3+0];
|
||||
V[i][1] = out.pointlist[i*3+1];
|
||||
V[i][2] = out.pointlist[i*3+2];
|
||||
}
|
||||
|
||||
// process tets
|
||||
if(out.tetrahedronlist == NULL)
|
||||
{
|
||||
cerr<<"^tetgenio_to_tetmesh Error: tet list is NULL\n"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// When would this not be 4?
|
||||
assert(out.numberofcorners == 4);
|
||||
T.resize(out.numberoftetrahedra,vector<int>(out.numberofcorners));
|
||||
int min_index = 1e7;
|
||||
int max_index = -1e7;
|
||||
// loop over tetrahedra
|
||||
for(int i = 0; i < out.numberoftetrahedra; i++)
|
||||
{
|
||||
for(int j = 0; j<out.numberofcorners; j++)
|
||||
{
|
||||
int index = out.tetrahedronlist[i * out.numberofcorners + j];
|
||||
T[i][j] = index;
|
||||
min_index = (min_index > index ? index : min_index);
|
||||
max_index = (max_index < index ? index : max_index);
|
||||
}
|
||||
}
|
||||
|
||||
assert(min_index >= 0);
|
||||
assert(max_index >= 0);
|
||||
assert(max_index < (int)V.size());
|
||||
|
||||
cout<<out.numberoftrifaces<<endl;
|
||||
|
||||
// When would this not be 4?
|
||||
F.clear();
|
||||
// loop over tetrahedra
|
||||
for(int i = 0; i < out.numberoftrifaces; i++)
|
||||
{
|
||||
if(out.trifacemarkerlist[i]>=0)
|
||||
{
|
||||
vector<int> face(3);
|
||||
for(int j = 0; j<3; j++)
|
||||
{
|
||||
face[j] = out.trifacelist[i * 3 + j];
|
||||
}
|
||||
F.push_back(face);
|
||||
}
|
||||
}
|
||||
|
||||
R.resize(out.numberoftetrahedra, vector<REAL>(1));
|
||||
unordered_map<REAL, REAL> hashUniqueRegions;
|
||||
for(size_t i = 0; i < out.numberoftetrahedra; i++)
|
||||
{
|
||||
R[i][0] = out.tetrahedronattributelist[i];
|
||||
hashUniqueRegions[R[i][0]] = i;
|
||||
}
|
||||
// extract region marks
|
||||
nR = hashUniqueRegions.size();
|
||||
|
||||
// extract neighbor list
|
||||
N.resize(out.numberoftetrahedra, vector<int>(4));
|
||||
for (size_t i = 0; i < out.numberoftetrahedra; i++)
|
||||
{
|
||||
for (size_t j = 0; j < 4; j++)
|
||||
N[i][j] = out.neighborlist[i * 4 + j];
|
||||
}
|
||||
|
||||
// extract point 2 tetrahedron list
|
||||
PT.resize(out.numberofpoints, vector<int>(1));
|
||||
for (size_t i = 0; i < out.numberofpoints; i++)
|
||||
{
|
||||
PT[i][0] = out.point2tetlist[i];
|
||||
}
|
||||
|
||||
//extract face to tetrahedron list
|
||||
FT.resize(out.numberoftrifaces, vector<int>(2));
|
||||
int triface;
|
||||
|
||||
for (size_t i = 0; i < out.numberoftrifaces; i++)
|
||||
{
|
||||
for (size_t j = 0; j < 2; j++)
|
||||
{
|
||||
FT[i][j] = out.face2tetlist[0];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
|
||||
const tetgenio & out,
|
||||
std::vector<std::vector<REAL > > & V,
|
||||
@@ -196,12 +82,13 @@ IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename DerivedV, typename DerivedT>
|
||||
IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
|
||||
const tetgenio & out,
|
||||
std::vector<std::vector<REAL > > & V,
|
||||
std::vector<std::vector<int> > & T)
|
||||
Eigen::PlainObjectBase<DerivedV>& V,
|
||||
Eigen::PlainObjectBase<DerivedT>& T)
|
||||
{
|
||||
std::vector<std::vector<int> > F;
|
||||
Eigen::Matrix<typename DerivedT::Scalar,Eigen::Dynamic,3> F;
|
||||
return tetgenio_to_tetmesh(out,V,T,F);
|
||||
}
|
||||
|
||||
@@ -242,16 +129,151 @@ IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename DerivedV, typename DerivedT>
|
||||
IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
|
||||
const tetgenio & out,
|
||||
Eigen::PlainObjectBase<DerivedV>& V,
|
||||
Eigen::PlainObjectBase<DerivedT>& T)
|
||||
std::vector<std::vector<REAL > > & V,
|
||||
std::vector<std::vector<int> > & T)
|
||||
{
|
||||
Eigen::Matrix<typename DerivedT::Scalar,Eigen::Dynamic,3> F;
|
||||
std::vector<std::vector<int> > F;
|
||||
return tetgenio_to_tetmesh(out,V,T,F);
|
||||
}
|
||||
|
||||
IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
|
||||
const tetgenio & out,
|
||||
std::vector<std::vector<REAL > > & V,
|
||||
std::vector<std::vector<int> > & T,
|
||||
std::vector<std::vector<int > > & F,
|
||||
std::vector<std::vector<REAL > >& R,
|
||||
std::vector<std::vector<int > >& N,
|
||||
std::vector<std::vector<int > >& PT,
|
||||
std::vector<std::vector<int > >& FT,
|
||||
size_t & nR )
|
||||
{
|
||||
using namespace std;
|
||||
// process points
|
||||
if(out.pointlist == NULL)
|
||||
{
|
||||
cerr<<"^tetgenio_to_tetmesh Error: point list is NULL\n"<<endl;
|
||||
return false;
|
||||
}
|
||||
V.resize(out.numberofpoints,vector<REAL>(3));
|
||||
// loop over points
|
||||
for(int i = 0;i < out.numberofpoints; i++)
|
||||
{
|
||||
V[i][0] = out.pointlist[i*3+0];
|
||||
V[i][1] = out.pointlist[i*3+1];
|
||||
V[i][2] = out.pointlist[i*3+2];
|
||||
}
|
||||
|
||||
// process tets
|
||||
if(out.tetrahedronlist == NULL)
|
||||
{
|
||||
cerr<<"^tetgenio_to_tetmesh Error: tet list is NULL\n"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// When would this not be 4?
|
||||
assert(out.numberofcorners == 4);
|
||||
T.resize(out.numberoftetrahedra,vector<int>(out.numberofcorners));
|
||||
int min_index = 1e7;
|
||||
int max_index = -1e7;
|
||||
// loop over tetrahedra
|
||||
for(int i = 0; i < out.numberoftetrahedra; i++)
|
||||
{
|
||||
for(int j = 0; j<out.numberofcorners; j++)
|
||||
{
|
||||
int index = out.tetrahedronlist[i * out.numberofcorners + j];
|
||||
T[i][j] = index;
|
||||
min_index = (min_index > index ? index : min_index);
|
||||
max_index = (max_index < index ? index : max_index);
|
||||
}
|
||||
}
|
||||
|
||||
assert(min_index >= 0);
|
||||
assert(max_index >= 0);
|
||||
assert(max_index < (int)V.size());
|
||||
|
||||
// When would this not be 4?
|
||||
F.clear();
|
||||
// loop over tetrahedra
|
||||
for(int i = 0; i < out.numberoftrifaces; i++)
|
||||
{
|
||||
if(out.trifacemarkerlist[i]>=0)
|
||||
{
|
||||
vector<int> face(3);
|
||||
for(int j = 0; j<3; j++)
|
||||
{
|
||||
face[j] = out.trifacelist[i * 3 + j];
|
||||
}
|
||||
F.push_back(face);
|
||||
}
|
||||
}
|
||||
|
||||
if(out.tetrahedronattributelist)
|
||||
{
|
||||
R.resize(out.numberoftetrahedra, vector<REAL>(1));
|
||||
unordered_map<REAL, REAL> hashUniqueRegions;
|
||||
for(size_t i = 0; i < out.numberoftetrahedra; i++)
|
||||
{
|
||||
R[i][0] = out.tetrahedronattributelist[i];
|
||||
hashUniqueRegions[R[i][0]] = i;
|
||||
}
|
||||
// extract region marks
|
||||
nR = hashUniqueRegions.size();
|
||||
}else
|
||||
{
|
||||
R.clear();
|
||||
nR = 0;
|
||||
}
|
||||
|
||||
// extract neighbor list
|
||||
if(out.neighborlist)
|
||||
{
|
||||
N.resize(out.numberoftetrahedra, vector<int>(4));
|
||||
for (size_t i = 0; i < out.numberoftetrahedra; i++)
|
||||
{
|
||||
for (size_t j = 0; j < 4; j++)
|
||||
N[i][j] = out.neighborlist[i * 4 + j];
|
||||
}
|
||||
}else
|
||||
{
|
||||
N.clear();
|
||||
}
|
||||
|
||||
// extract point 2 tetrahedron list
|
||||
if(out.point2tetlist)
|
||||
{
|
||||
PT.resize(out.numberofpoints, vector<int>(1));
|
||||
for (size_t i = 0; i < out.numberofpoints; i++)
|
||||
{
|
||||
PT[i][0] = out.point2tetlist[i];
|
||||
}
|
||||
}else
|
||||
{
|
||||
PT.clear();
|
||||
}
|
||||
|
||||
//extract face to tetrahedron list
|
||||
if(out.face2tetlist)
|
||||
{
|
||||
FT.resize(out.numberoftrifaces, vector<int>(2));
|
||||
int triface;
|
||||
for (size_t i = 0; i < out.numberoftrifaces; i++)
|
||||
{
|
||||
for (size_t j = 0; j < 2; j++)
|
||||
{
|
||||
FT[i][j] = out.face2tetlist[0];
|
||||
}
|
||||
}
|
||||
}else
|
||||
{
|
||||
FT.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template bool igl::copyleft::tetgen::tetgenio_to_tetmesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(tetgenio const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace igl
|
||||
std::vector<std::vector<REAL > > & V,
|
||||
std::vector<std::vector<int> > & T,
|
||||
std::vector<std::vector<int> > & F);
|
||||
|
||||
IGL_INLINE bool tetgenio_to_tetmesh(
|
||||
const tetgenio & out,
|
||||
std::vector<std::vector<REAL > > & V,
|
||||
@@ -50,6 +51,7 @@ namespace igl
|
||||
Eigen::PlainObjectBase<DerivedV>& V,
|
||||
Eigen::PlainObjectBase<DerivedT>& T,
|
||||
Eigen::PlainObjectBase<DerivedF>& F);
|
||||
|
||||
template <typename DerivedV, typename DerivedT>
|
||||
IGL_INLINE bool tetgenio_to_tetmesh(
|
||||
const tetgenio & out,
|
||||
|
||||
@@ -18,6 +18,200 @@
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
const std::vector<std::vector<REAL > > & V,
|
||||
const std::vector<std::vector<int> > & F,
|
||||
const std::string switches,
|
||||
std::vector<std::vector<REAL > > & TV,
|
||||
std::vector<std::vector<int > > & TT,
|
||||
std::vector<std::vector<int> > & TF)
|
||||
{
|
||||
using namespace std;
|
||||
tetgenio in,out;
|
||||
bool success;
|
||||
success = mesh_to_tetgenio(V,F,in);
|
||||
if(!success)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
char * cswitches = new char[switches.size() + 1];
|
||||
std::strcpy(cswitches,switches.c_str());
|
||||
::tetrahedralize(cswitches,&in, &out);
|
||||
delete[] cswitches;
|
||||
}catch(int e)
|
||||
{
|
||||
cerr<<"^"<<__FUNCTION__<<": TETGEN CRASHED... KABOOOM!!!"<<endl;
|
||||
return 1;
|
||||
}
|
||||
if(out.numberoftetrahedra == 0)
|
||||
{
|
||||
cerr<<"^"<<__FUNCTION__<<": Tetgen failed to create tets"<<endl;
|
||||
return 2;
|
||||
}
|
||||
success = tetgenio_to_tetmesh(out,TV,TT,TF);
|
||||
if(!success)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
boundary_facets(TT,TF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename DerivedTV,
|
||||
typename DerivedTT,
|
||||
typename DerivedTF>
|
||||
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const std::string switches,
|
||||
Eigen::PlainObjectBase<DerivedTV>& TV,
|
||||
Eigen::PlainObjectBase<DerivedTT>& TT,
|
||||
Eigen::PlainObjectBase<DerivedTF>& TF)
|
||||
{
|
||||
using namespace std;
|
||||
vector<vector<REAL> > vV,vTV;
|
||||
vector<vector<int> > vF,vTT,vTF;
|
||||
matrix_to_list(V,vV);
|
||||
matrix_to_list(F,vF);
|
||||
int e = tetrahedralize(vV,vF,switches,vTV,vTT,vTF);
|
||||
if(e == 0)
|
||||
{
|
||||
bool TV_rect = list_to_matrix(vTV,TV);
|
||||
if(!TV_rect)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
bool TT_rect = list_to_matrix(vTT,TT);
|
||||
if(!TT_rect)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
bool TF_rect = list_to_matrix(vTF,TF);
|
||||
if(!TF_rect)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename DerivedVM,
|
||||
typename DerivedFM,
|
||||
typename DerivedTV,
|
||||
typename DerivedTT,
|
||||
typename DerivedTF,
|
||||
typename DerivedTM>
|
||||
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedVM>& VM,
|
||||
const Eigen::MatrixBase<DerivedFM>& FM,
|
||||
const std::string switches,
|
||||
Eigen::PlainObjectBase<DerivedTV>& TV,
|
||||
Eigen::PlainObjectBase<DerivedTT>& TT,
|
||||
Eigen::PlainObjectBase<DerivedTF>& TF,
|
||||
Eigen::PlainObjectBase<DerivedTM>& TM)
|
||||
{
|
||||
using namespace std;
|
||||
vector<vector<REAL> > vV,vTV;
|
||||
vector<vector<int> > vF,vTT,vTF;
|
||||
vector<int> vTM;
|
||||
|
||||
matrix_to_list(V,vV);
|
||||
matrix_to_list(F,vF);
|
||||
vector<int> vVM = matrix_to_list(VM);
|
||||
vector<int> vFM = matrix_to_list(FM);
|
||||
int e = tetrahedralize(vV,vF,vVM,vFM,switches,vTV,vTT,vTF,vTM);
|
||||
if(e == 0)
|
||||
{
|
||||
bool TV_rect = list_to_matrix(vTV,TV);
|
||||
if(!TV_rect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool TT_rect = list_to_matrix(vTT,TT);
|
||||
if(!TT_rect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool TF_rect = list_to_matrix(vTF,TF);
|
||||
if(!TF_rect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool TM_rect = list_to_matrix(vTM,TM);
|
||||
if(!TM_rect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
const std::vector<std::vector<REAL > > & V,
|
||||
const std::vector<std::vector<int> > & F,
|
||||
const std::vector<int> & VM,
|
||||
const std::vector<int> & FM,
|
||||
const std::string switches,
|
||||
std::vector<std::vector<REAL > > & TV,
|
||||
std::vector<std::vector<int > > & TT,
|
||||
std::vector<std::vector<int> > & TF,
|
||||
std::vector<int> & TM)
|
||||
{
|
||||
using namespace std;
|
||||
tetgenio in,out;
|
||||
bool success;
|
||||
success = mesh_to_tetgenio(V,F,in);
|
||||
if(!success)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
in.pointmarkerlist = new int[VM.size()];
|
||||
for (int i = 0; i < VM.size(); ++i) {
|
||||
in.pointmarkerlist[i] = VM[i];
|
||||
}
|
||||
// These have already been created in mesh_to_tetgenio.
|
||||
// Reset them here.
|
||||
for (int i = 0; i < FM.size(); ++i) {
|
||||
in.facetmarkerlist[i] = FM[i];
|
||||
}
|
||||
try
|
||||
{
|
||||
char * cswitches = new char[switches.size() + 1];
|
||||
std::strcpy(cswitches,switches.c_str());
|
||||
::tetrahedralize(cswitches,&in, &out);
|
||||
delete[] cswitches;
|
||||
}catch(int e)
|
||||
{
|
||||
cerr<<"^"<<__FUNCTION__<<": TETGEN CRASHED... KABOOOM!!!"<<endl;
|
||||
return 1;
|
||||
}
|
||||
if(out.numberoftetrahedra == 0)
|
||||
{
|
||||
cerr<<"^"<<__FUNCTION__<<": Tetgen failed to create tets"<<endl;
|
||||
return 2;
|
||||
}
|
||||
success = tetgenio_to_tetmesh(out,TV,TT,TF);
|
||||
if(!success)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
TM.resize(out.numberofpoints);
|
||||
for (int i = 0; i < out.numberofpoints; ++i) {
|
||||
TM[i] = out.pointmarkerlist[i];
|
||||
}
|
||||
boundary_facets(TT,TF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
const std::vector<std::vector<REAL > > & V,
|
||||
@@ -143,203 +337,10 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
return e;
|
||||
}
|
||||
|
||||
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
const std::vector<std::vector<REAL > > & V,
|
||||
const std::vector<std::vector<int> > & F,
|
||||
const std::string switches,
|
||||
std::vector<std::vector<REAL > > & TV,
|
||||
std::vector<std::vector<int > > & TT,
|
||||
std::vector<std::vector<int> > & TF)
|
||||
{
|
||||
using namespace std;
|
||||
tetgenio in,out;
|
||||
bool success;
|
||||
success = mesh_to_tetgenio(V,F,in);
|
||||
if(!success)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
char * cswitches = new char[switches.size() + 1];
|
||||
std::strcpy(cswitches,switches.c_str());
|
||||
::tetrahedralize(cswitches,&in, &out);
|
||||
delete[] cswitches;
|
||||
}catch(int e)
|
||||
{
|
||||
cerr<<"^"<<__FUNCTION__<<": TETGEN CRASHED... KABOOOM!!!"<<endl;
|
||||
return 1;
|
||||
}
|
||||
if(out.numberoftetrahedra == 0)
|
||||
{
|
||||
cerr<<"^"<<__FUNCTION__<<": Tetgen failed to create tets"<<endl;
|
||||
return 2;
|
||||
}
|
||||
success = tetgenio_to_tetmesh(out,TV,TT,TF);
|
||||
if(!success)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
boundary_facets(TT,TF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename DerivedTV,
|
||||
typename DerivedTT,
|
||||
typename DerivedTF>
|
||||
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const std::string switches,
|
||||
Eigen::PlainObjectBase<DerivedTV>& TV,
|
||||
Eigen::PlainObjectBase<DerivedTT>& TT,
|
||||
Eigen::PlainObjectBase<DerivedTF>& TF)
|
||||
{
|
||||
using namespace std;
|
||||
vector<vector<REAL> > vV,vTV;
|
||||
vector<vector<int> > vF,vTT,vTF;
|
||||
matrix_to_list(V,vV);
|
||||
matrix_to_list(F,vF);
|
||||
int e = tetrahedralize(vV,vF,switches,vTV,vTT,vTF);
|
||||
if(e == 0)
|
||||
{
|
||||
bool TV_rect = list_to_matrix(vTV,TV);
|
||||
if(!TV_rect)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
bool TT_rect = list_to_matrix(vTT,TT);
|
||||
if(!TT_rect)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
bool TF_rect = list_to_matrix(vTF,TF);
|
||||
if(!TF_rect)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename DerivedVM,
|
||||
typename DerivedFM,
|
||||
typename DerivedTV,
|
||||
typename DerivedTT,
|
||||
typename DerivedTF,
|
||||
typename DerivedTM>
|
||||
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedVM>& VM,
|
||||
const Eigen::MatrixBase<DerivedFM>& FM,
|
||||
const std::string switches,
|
||||
Eigen::PlainObjectBase<DerivedTV>& TV,
|
||||
Eigen::PlainObjectBase<DerivedTT>& TT,
|
||||
Eigen::PlainObjectBase<DerivedTF>& TF,
|
||||
Eigen::PlainObjectBase<DerivedTM>& TM)
|
||||
{
|
||||
using namespace std;
|
||||
vector<vector<REAL> > vV,vTV;
|
||||
vector<vector<int> > vF,vTT,vTF;
|
||||
vector<int> vTM;
|
||||
|
||||
matrix_to_list(V,vV);
|
||||
matrix_to_list(F,vF);
|
||||
vector<int> vVM = matrix_to_list(VM);
|
||||
vector<int> vFM = matrix_to_list(FM);
|
||||
int e = tetrahedralize(vV,vF,vVM,vFM,switches,vTV,vTT,vTF,vTM);
|
||||
if(e == 0)
|
||||
{
|
||||
bool TV_rect = list_to_matrix(vTV,TV);
|
||||
if(!TV_rect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool TT_rect = list_to_matrix(vTT,TT);
|
||||
if(!TT_rect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool TF_rect = list_to_matrix(vTF,TF);
|
||||
if(!TF_rect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool TM_rect = list_to_matrix(vTM,TM);
|
||||
if(!TM_rect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
|
||||
const std::vector<std::vector<REAL > > & V,
|
||||
const std::vector<std::vector<int> > & F,
|
||||
const std::vector<int> & VM,
|
||||
const std::vector<int> & FM,
|
||||
const std::string switches,
|
||||
std::vector<std::vector<REAL > > & TV,
|
||||
std::vector<std::vector<int > > & TT,
|
||||
std::vector<std::vector<int> > & TF,
|
||||
std::vector<int> & TM)
|
||||
{
|
||||
using namespace std;
|
||||
tetgenio in,out;
|
||||
bool success;
|
||||
success = mesh_to_tetgenio(V,F,in);
|
||||
if(!success)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
in.pointmarkerlist = new int[VM.size()];
|
||||
for (int i = 0; i < VM.size(); ++i) {
|
||||
in.pointmarkerlist[i] = VM[i];
|
||||
}
|
||||
// These have already been created in mesh_to_tetgenio.
|
||||
// Reset them here.
|
||||
for (int i = 0; i < FM.size(); ++i) {
|
||||
in.facetmarkerlist[i] = FM[i];
|
||||
}
|
||||
try
|
||||
{
|
||||
char * cswitches = new char[switches.size() + 1];
|
||||
std::strcpy(cswitches,switches.c_str());
|
||||
::tetrahedralize(cswitches,&in, &out);
|
||||
delete[] cswitches;
|
||||
}catch(int e)
|
||||
{
|
||||
cerr<<"^"<<__FUNCTION__<<": TETGEN CRASHED... KABOOOM!!!"<<endl;
|
||||
return 1;
|
||||
}
|
||||
if(out.numberoftetrahedra == 0)
|
||||
{
|
||||
cerr<<"^"<<__FUNCTION__<<": Tetgen failed to create tets"<<endl;
|
||||
return 2;
|
||||
}
|
||||
success = tetgenio_to_tetmesh(out,TV,TT,TF);
|
||||
if(!success)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
TM.resize(out.numberofpoints);
|
||||
for (int i = 0; i < out.numberofpoints; ++i) {
|
||||
TM[i] = out.pointmarkerlist[i];
|
||||
}
|
||||
boundary_facets(TT,TF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template int igl::copyleft::tetgen::tetrahedralize<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
||||
template int igl::copyleft::tetgen::tetrahedralize<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<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> >(const 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<int, -1, 1, 0, -1, 1> > &,const Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > &,const std::basic_string<char, std::char_traits<char>, std::allocator<char> >,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 int igl::copyleft::tetgen::tetrahedralize<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<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, -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&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 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 int igl::copyleft::tetgen::tetrahedralize<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::Matrix<int, -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&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, 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<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> >&, unsigned long&);
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef TETLIBRARY
|
||||
#define TETLIBRARY
|
||||
#endif
|
||||
#include "tetgen.h" // Defined REAL
|
||||
#include <tetgen.h> // Defined REAL
|
||||
|
||||
namespace igl
|
||||
{
|
||||
@@ -68,12 +68,12 @@ namespace igl
|
||||
Eigen::PlainObjectBase<DerivedTT>& TT,
|
||||
Eigen::PlainObjectBase<DerivedTF>& TF);
|
||||
|
||||
// Mesh the interior of a surface mesh (V,F) using tetgen
|
||||
// Mesh the interior of a surface mesh (V,F) using tetgen
|
||||
//
|
||||
// Inputs:
|
||||
// V #V by 3 vertex position list
|
||||
// F #F list of polygon face indices into V (0-indexed)
|
||||
// M #V list of markers for vertices
|
||||
// M #V list of markers for vertices
|
||||
// switches string of tetgen options (See tetgen documentation) e.g.
|
||||
// "pq1.414a0.01" tries to mesh the interior of a given surface with
|
||||
// quality and area constraints
|
||||
@@ -82,7 +82,7 @@ namespace igl
|
||||
// TV #V by 3 vertex position list
|
||||
// TT #T by 4 list of tet face indices
|
||||
// TF #F by 3 list of triangle face indices
|
||||
// TM #V list of markers for vertices
|
||||
// TM #V list of markers for vertices
|
||||
// Returns status:
|
||||
// 0 success
|
||||
// 1 tetgen threw exception
|
||||
@@ -92,14 +92,13 @@ namespace igl
|
||||
IGL_INLINE int tetrahedralize(
|
||||
const std::vector<std::vector<REAL > > & V,
|
||||
const std::vector<std::vector<int> > & F,
|
||||
const std::vector<int> & VM,
|
||||
const std::vector<int> & FM,
|
||||
const std::vector<int> & VM,
|
||||
const std::vector<int> & FM,
|
||||
const std::string switches,
|
||||
std::vector<std::vector<REAL > > & TV,
|
||||
std::vector<std::vector<int > > & TT,
|
||||
std::vector<std::vector<int> > & TF,
|
||||
std::vector<int> & TM);
|
||||
|
||||
std::vector<int> & TM);
|
||||
// Wrapper with Eigen types
|
||||
// Templates:
|
||||
// DerivedV real-value: i.e. from MatrixXd
|
||||
@@ -107,8 +106,8 @@ namespace igl
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename DerivedVM,
|
||||
typename DerivedFM,
|
||||
typename DerivedVM,
|
||||
typename DerivedFM,
|
||||
typename DerivedTV,
|
||||
typename DerivedTT,
|
||||
typename DerivedTF,
|
||||
@@ -123,16 +122,13 @@ namespace igl
|
||||
Eigen::PlainObjectBase<DerivedTT>& TT,
|
||||
Eigen::PlainObjectBase<DerivedTF>& TF,
|
||||
Eigen::PlainObjectBase<DerivedTM>& TM);
|
||||
|
||||
|
||||
// Mesh the interior of a surface mesh (V,F) using tetgen
|
||||
//
|
||||
// Inputs:
|
||||
// V #V by 3 vertex position list
|
||||
// F #F list of polygon face indices into V (0-indexed)
|
||||
// H #H by 3 list of seed points inside holes
|
||||
// R #R by 5 list of region attributes
|
||||
|
||||
// R #R by 5 list of region attributes
|
||||
// switches string of tetgen options (See tetgen documentation) e.g.
|
||||
// "pq1.414a0.01" tries to mesh the interior of a given surface with
|
||||
// quality and area constraints
|
||||
@@ -141,64 +137,58 @@ namespace igl
|
||||
// TV #V by 3 vertex position list
|
||||
// TT #T by 4 list of tet face indices
|
||||
// TF #F by 3 list of triangle face indices
|
||||
// TR #T list of region ID for each tetrahedron
|
||||
// TR #T list of region ID for each tetrahedron
|
||||
// TN #T by 4 list of indices neighbors for each tetrahedron
|
||||
// PT #V list of incident tetrahedron for a vertex
|
||||
// FT #F by 2 list of tetrahedrons sharing a triface
|
||||
// FT #F by 2 list of tetrahedrons sharing a triface
|
||||
// numRegions Number of regions in output mesh
|
||||
|
||||
// Returns status:
|
||||
// 0 success
|
||||
// 1 tetgen threw exception
|
||||
// 2 tetgen did not crash but could not create any tets (probably there are
|
||||
// holes, duplicate faces etc.)
|
||||
// -1 other error
|
||||
IGL_INLINE int tetrahedralize(
|
||||
const std::vector<std::vector<REAL> > &V,
|
||||
const std::vector<std::vector<int> > &F,
|
||||
const std::vector<std::vector<REAL> > &H,
|
||||
const std::vector<std::vector<REAL> > &R,
|
||||
|
||||
const std::string switches,
|
||||
|
||||
std::vector<std::vector<REAL > > & TV,
|
||||
std::vector<std::vector<int > > & TT,
|
||||
std::vector<std::vector<int > > & TF,
|
||||
std::vector<std::vector<REAL > > &TR,
|
||||
std::vector<std::vector<int > > &TN,
|
||||
std::vector<std::vector<int > > &PT,
|
||||
std::vector<std::vector<int > > &FT,
|
||||
size_t & numRegions);
|
||||
|
||||
|
||||
IGL_INLINE int tetrahedralize(
|
||||
const std::vector<std::vector<REAL> > &V,
|
||||
const std::vector<std::vector<int> > &F,
|
||||
const std::vector<std::vector<REAL> > &H,
|
||||
const std::vector<std::vector<REAL> > &R,
|
||||
const std::string switches,
|
||||
std::vector<std::vector<REAL > > & TV,
|
||||
std::vector<std::vector<int > > & TT,
|
||||
std::vector<std::vector<int > > & TF,
|
||||
std::vector<std::vector<REAL > > &TR,
|
||||
std::vector<std::vector<int > > &TN,
|
||||
std::vector<std::vector<int > > &PT,
|
||||
std::vector<std::vector<int > > &FT,
|
||||
size_t & numRegions);
|
||||
// Wrapper with Eigen types
|
||||
// Templates:
|
||||
// DerivedV real-value: i.e. from MatrixXd
|
||||
// DerivedF integer-value: i.e. from MatrixXi
|
||||
// DerivedF integer-value: i.e. from MatrixXi
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedF,
|
||||
typename DerivedH,
|
||||
typename DerivedR,
|
||||
typename DerivedTV,
|
||||
typename DerivedTT,
|
||||
typename DerivedTF,
|
||||
typename DerivedTR>
|
||||
typename DerivedF,
|
||||
typename DerivedH,
|
||||
typename DerivedR,
|
||||
typename DerivedTV,
|
||||
typename DerivedTT,
|
||||
typename DerivedTF,
|
||||
typename DerivedTR>
|
||||
IGL_INLINE int tetrahedralize(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedH>& H,
|
||||
const Eigen::MatrixBase<DerivedR>& R,
|
||||
const std::string switches,
|
||||
Eigen::PlainObjectBase<DerivedTV>& TV,
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedH>& H,
|
||||
const Eigen::MatrixBase<DerivedR>& R,
|
||||
const std::string switches,
|
||||
Eigen::PlainObjectBase<DerivedTV>& TV,
|
||||
Eigen::PlainObjectBase<DerivedTT>& TT,
|
||||
Eigen::PlainObjectBase<DerivedTF>& TF,
|
||||
Eigen::PlainObjectBase<DerivedTR>& TR,
|
||||
Eigen::PlainObjectBase<DerivedTT>& TN,
|
||||
Eigen::PlainObjectBase<DerivedTT>& PT,
|
||||
Eigen::PlainObjectBase<DerivedTT>& FT,
|
||||
size_t & numRegions);
|
||||
|
||||
Eigen::PlainObjectBase<DerivedTF>& TF,
|
||||
Eigen::PlainObjectBase<DerivedTR>& TR,
|
||||
Eigen::PlainObjectBase<DerivedTT>& TN,
|
||||
Eigen::PlainObjectBase<DerivedTT>& PT,
|
||||
Eigen::PlainObjectBase<DerivedTT>& FT,
|
||||
size_t & numRegions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,9 +78,153 @@ IGL_INLINE void igl::cotmatrix(
|
||||
L.setFromTriplets(IJV.begin(),IJV.end());
|
||||
}
|
||||
|
||||
#include "massmatrix.h"
|
||||
#include "pinv.h"
|
||||
#include "cotmatrix_entries.h"
|
||||
#include "diag.h"
|
||||
#include "massmatrix.h"
|
||||
#include <Eigen/Geometry>
|
||||
#include <Eigen/QR>
|
||||
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedI,
|
||||
typename DerivedC,
|
||||
typename Scalar>
|
||||
IGL_INLINE void igl::cotmatrix(
|
||||
const Eigen::MatrixBase<DerivedV> & V,
|
||||
const Eigen::MatrixBase<DerivedI> & I,
|
||||
const Eigen::MatrixBase<DerivedC> & C,
|
||||
Eigen::SparseMatrix<Scalar>& L,
|
||||
Eigen::SparseMatrix<Scalar>& M,
|
||||
Eigen::SparseMatrix<Scalar>& P)
|
||||
{
|
||||
typedef Eigen::Matrix<Scalar,1,3> RowVector3S;
|
||||
typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> MatrixXS;
|
||||
typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1> VectorXS;
|
||||
typedef Eigen::Index Index;
|
||||
// number of vertices
|
||||
const Index n = V.rows();
|
||||
// number of polyfaces
|
||||
const Index m = C.size()-1;
|
||||
assert(V.cols() == 2 || V.cols() == 3);
|
||||
std::vector<Eigen::Triplet<Scalar> > Lfijv;
|
||||
std::vector<Eigen::Triplet<Scalar> > Mfijv;
|
||||
std::vector<Eigen::Triplet<Scalar> > Pijv;
|
||||
// loop over vertices; set identity for original vertices
|
||||
for(Index i = 0;i<V.rows();i++) { Pijv.emplace_back(i,i,1); }
|
||||
// loop over faces
|
||||
for(Index p = 0;p<C.size()-1;p++)
|
||||
{
|
||||
// number of faces/vertices in this simple polygon
|
||||
const Index np = C(p+1)-C(p);
|
||||
// Working "local" list of vertices; last vertex is new one
|
||||
// this needs to have 3 columns so Eigen doesn't complain about cross
|
||||
// products below.
|
||||
Eigen::Matrix<Scalar,Eigen::Dynamic,3> X = decltype(X)::Zero(np+1,3);
|
||||
for(Index i = 0;i<np;i++){ X.row(i).head(V.cols()) = V.row(I(C(p)+i)); };
|
||||
// determine weights definig position of inserted vertex
|
||||
{
|
||||
MatrixXS A = decltype(A)::Zero(np+1,np);
|
||||
// My equation (38) would be A w = b.
|
||||
VectorXS b = decltype(b)::Zero(np+1);
|
||||
for(Index k = 0;k<np;k++)
|
||||
{
|
||||
const RowVector3S Xkp1mk = X.row((k+1)%np)-X.row(k);
|
||||
const RowVector3S Xkp1mkck = Xkp1mk.cross(X.row(k));
|
||||
for(Index i = 0;i<np;i++)
|
||||
{
|
||||
b(i) -= 2.*(X.row(i).cross(Xkp1mk)).dot(Xkp1mkck);
|
||||
for(Index j = 0;j<np;j++)
|
||||
{
|
||||
A(i,j) += 2.*(X.row(j).cross(Xkp1mk)).dot(X.row(i).cross(Xkp1mk));
|
||||
}
|
||||
}
|
||||
}
|
||||
A.row(np).setConstant(1);
|
||||
b(np) = 1;
|
||||
const VectorXS w =
|
||||
Eigen::CompleteOrthogonalDecomposition<Eigen::MatrixXd>(A).solve(b);
|
||||
X.row(np) = w.transpose()*X.topRows(np);
|
||||
// scatter w into new row of P
|
||||
for(Index i = 0;i<np;i++) { Pijv.emplace_back(n+p,I(C(p)+i),w(i)); }
|
||||
}
|
||||
// "local" fan of faces. These could be statically cached, but this will
|
||||
// not be the bottleneck.
|
||||
Eigen::MatrixXi F(np,3);
|
||||
for(Index i = 0;i<np;i++)
|
||||
{
|
||||
F(i,0) = i;
|
||||
F(i,1) = (i+1)%np;
|
||||
F(i,2) = np;
|
||||
}
|
||||
// Cotangent contributions
|
||||
MatrixXS K;
|
||||
igl::cotmatrix_entries(X,F,K);
|
||||
// Massmatrix entried
|
||||
VectorXS Mp;
|
||||
{
|
||||
Eigen::SparseMatrix<Scalar> M;
|
||||
igl::massmatrix(X,F,igl::MASSMATRIX_TYPE_DEFAULT,M);
|
||||
Mp = M.diagonal();
|
||||
}
|
||||
// Scatter into fine Laplacian and mass matrices
|
||||
const auto J = [&n,&np,&p,&I,&C](Index i)->Index{return i==np?n+p:I(C(p)+i);};
|
||||
// Should just build Mf as a vector...
|
||||
for(Index i = 0;i<np+1;i++) { Mfijv.emplace_back(J(i),J(i),Mp(i)); }
|
||||
// loop over faces
|
||||
for(Index f = 0;f<np;f++)
|
||||
{
|
||||
for(Index c = 0;c<3;c++)
|
||||
{
|
||||
const Index i = F(f,(c+1)%3);
|
||||
const Index j = F(f,(c+2)%3);
|
||||
// symmetric off-diagonal
|
||||
Lfijv.emplace_back(J(i),J(j),K(f,c));
|
||||
Lfijv.emplace_back(J(j),J(i),K(f,c));
|
||||
// diagonal
|
||||
Lfijv.emplace_back(J(i),J(i),-K(f,c));
|
||||
Lfijv.emplace_back(J(j),J(j),-K(f,c));
|
||||
}
|
||||
}
|
||||
}
|
||||
P.resize(n+m,n);
|
||||
P.setFromTriplets(Pijv.begin(),Pijv.end());
|
||||
Eigen::SparseMatrix<Scalar> Lf(n+m,n+m);
|
||||
Lf.setFromTriplets(Lfijv.begin(),Lfijv.end());
|
||||
Eigen::SparseMatrix<Scalar> Mf(n+m,n+m);
|
||||
Mf.setFromTriplets(Mfijv.begin(),Mfijv.end());
|
||||
L = P.transpose() * Lf * P;
|
||||
// "unlumped" M
|
||||
const Eigen::SparseMatrix<Scalar> PTMP = P.transpose() * Mf * P;
|
||||
// Lump M
|
||||
const VectorXS Mdiag = PTMP * VectorXS::Ones(n,1);
|
||||
igl::diag(Mdiag,M);
|
||||
|
||||
MatrixXS Vf = P*V;
|
||||
Eigen::MatrixXi Ff(I.size(),3);
|
||||
{
|
||||
Index f = 0;
|
||||
for(Index p = 0;p<C.size()-1;p++)
|
||||
{
|
||||
const Index np = C(p+1)-C(p);
|
||||
for(Index c = 0;c<np;c++)
|
||||
{
|
||||
Ff(f,0) = I(C(p)+c);
|
||||
Ff(f,1) = I(C(p)+(c+1)%np);
|
||||
Ff(f,2) = V.rows()+p;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
assert(f == Ff.rows());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::cotmatrix<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, double>(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<int, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<double, 0, int>&, Eigen::SparseMatrix<double, 0, int>&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::cotmatrix<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
template void igl::cotmatrix<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 4, 0, -1, 4>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 4, 0, -1, 4> > const&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
template void igl::cotmatrix<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
|
||||
@@ -48,6 +48,31 @@ namespace igl
|
||||
const Eigen::MatrixBase<DerivedV> & V,
|
||||
const Eigen::MatrixBase<DerivedF> & F,
|
||||
Eigen::SparseMatrix<Scalar>& L);
|
||||
// Cotangent Laplacian (and mass matrix) for polygon meshes according to
|
||||
// "Polygon Laplacian Made Simple" [Bunge et al. 2020]
|
||||
//
|
||||
// Inputs:
|
||||
// V #V by 3 list of mesh vertex positions
|
||||
// I #I vectorized list of polygon corner indices into rows of some matrix V
|
||||
// C #polygons+1 list of cumulative polygon sizes so that C(i+1)-C(i) = size of
|
||||
// the ith polygon, and so I(C(i)) through I(C(i+1)-1) are the indices of
|
||||
// the ith polygon
|
||||
// Outputs:
|
||||
// L #V by #V polygon Laplacian made simple matrix
|
||||
// M #V by #V mass matrix
|
||||
// P #V+#polygons by #V prolongation operator
|
||||
template <
|
||||
typename DerivedV,
|
||||
typename DerivedI,
|
||||
typename DerivedC,
|
||||
typename Scalar>
|
||||
IGL_INLINE void cotmatrix(
|
||||
const Eigen::MatrixBase<DerivedV> & V,
|
||||
const Eigen::MatrixBase<DerivedI> & I,
|
||||
const Eigen::MatrixBase<DerivedC> & C,
|
||||
Eigen::SparseMatrix<Scalar>& L,
|
||||
Eigen::SparseMatrix<Scalar>& M,
|
||||
Eigen::SparseMatrix<Scalar>& P);
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
|
||||
@@ -136,6 +136,8 @@ IGL_INLINE void igl::cotmatrix_entries(
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::cotmatrix_entries<Eigen::Matrix<double, -1, 3, 0, -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, 0, -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::cotmatrix_entries<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::cotmatrix_entries<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Oded Stein <oded.stein@columbia.edu>
|
||||
//
|
||||
// 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 "cr_vector_curvature_correction.h"
|
||||
|
||||
#include "orient_halfedges.h"
|
||||
#include "gaussian_curvature.h"
|
||||
|
||||
#include "squared_edge_lengths.h"
|
||||
#include "doublearea.h"
|
||||
#include "boundary_loop.h"
|
||||
#include "internal_angles.h"
|
||||
|
||||
#include "PI.h"
|
||||
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarK>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_curvature_correction(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K)
|
||||
{
|
||||
Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic>
|
||||
l_sq;
|
||||
squared_edge_lengths(V, F, l_sq);
|
||||
cr_vector_curvature_correction_intrinsic(F, l_sq, E, oE, K);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarK>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_curvature_correction(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
Eigen::PlainObjectBase<DerivedE>& E,
|
||||
Eigen::PlainObjectBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K)
|
||||
{
|
||||
if(E.rows()!=F.rows() || E.cols()!=F.cols() || oE.rows()!=F.rows() ||
|
||||
oE.cols()!=F.cols()) {
|
||||
orient_halfedges(F, E, oE);
|
||||
}
|
||||
|
||||
const Eigen::PlainObjectBase<DerivedE>& cE = E;
|
||||
const Eigen::PlainObjectBase<DerivedOE>& coE = oE;
|
||||
cr_vector_curvature_correction(V, F, cE, coE, K);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarK>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_curvature_correction_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K)
|
||||
{
|
||||
Eigen::Matrix<typename DerivedL_sq::Scalar,Eigen::Dynamic,Eigen::Dynamic>
|
||||
theta;
|
||||
internal_angles_using_squared_edge_lengths(l_sq, theta);
|
||||
|
||||
cr_vector_curvature_correction_intrinsic(F, l_sq, theta, E, oE, K);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename Derivedtheta,
|
||||
typename DerivedE, typename DerivedOE,
|
||||
typename ScalarK>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_curvature_correction_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<Derivedtheta>& theta,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K)
|
||||
{
|
||||
// Compute the angle defect kappa, set it to 0 at the boundary
|
||||
const typename DerivedF::Scalar n = F.maxCoeff() + 1;
|
||||
Eigen::Matrix<typename DerivedL_sq::Scalar,Eigen::Dynamic,1> kappa(n);
|
||||
kappa.setZero();
|
||||
for(Eigen::Index i=0; i<F.rows(); ++i) {
|
||||
for(int j=0; j<3; ++j) {
|
||||
kappa(F(i,j)) -= theta(i,j);
|
||||
}
|
||||
}
|
||||
kappa.array() += 2 * PI;
|
||||
std::vector<std::vector<typename DerivedF::Scalar> > b;
|
||||
boundary_loop(F, b);
|
||||
for(const auto& loop : b) {
|
||||
for(auto v : loop) {
|
||||
kappa(v) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cr_vector_curvature_correction_intrinsic(F, l_sq, theta, kappa, E, oE, K);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename Derivedtheta,
|
||||
typename Derivedkappa, typename DerivedE, typename DerivedOE,
|
||||
typename ScalarK>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_curvature_correction_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<Derivedtheta>& theta,
|
||||
const Eigen::MatrixBase<Derivedkappa>& kappa,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K)
|
||||
{
|
||||
assert(F.cols()==3 && "Faces have three vertices");
|
||||
assert(E.rows()==F.rows() && E.cols()==F.cols() && oE.rows()==F.rows() &&
|
||||
theta.rows()==F.rows() && theta.cols()==F.cols() &&
|
||||
oE.cols()==F.cols() && "Wrong dimension in edge vectors");
|
||||
assert(kappa.rows()==F.maxCoeff()+1 &&
|
||||
"Wrong dimension in theta or kappa");
|
||||
|
||||
const Eigen::Index m = F.rows();
|
||||
const typename DerivedE::Scalar nE = E.maxCoeff() + 1;
|
||||
|
||||
//Divide kappa by the actual angle sum to weigh consistently.
|
||||
Derivedtheta angleSum = Derivedtheta::Zero(kappa.rows(), 1);
|
||||
for(Eigen::Index i=0; i<F.rows(); ++i) {
|
||||
for(int j=0; j<3; ++j) {
|
||||
angleSum(F(i,j)) += theta(i,j);
|
||||
}
|
||||
}
|
||||
const Eigen::Matrix<typename Derivedkappa::Scalar, Eigen::Dynamic, 1>
|
||||
scaledKappa = kappa.array() / angleSum.array();
|
||||
|
||||
std::vector<Eigen::Triplet<ScalarK> > tripletList;
|
||||
tripletList.reserve(10*3*m);
|
||||
for(Eigen::Index f=0; f<m; ++f) {
|
||||
for(int e=0; e<3; ++e) {
|
||||
const ScalarK eij=l_sq(f,e), ejk=l_sq(f,(e+1)%3),
|
||||
eki=l_sq(f,(e+2)%3); //These are squared quantities.
|
||||
const ScalarK lens = sqrt(eij*eki);
|
||||
const ScalarK o = oE(f,e)*oE(f,(e+2)%3);
|
||||
const typename DerivedF::Scalar i=F(f,(e+1)%3), j=F(f,(e+2)%3), k=F(f,e);
|
||||
const ScalarK ki=scaledKappa(i)*theta(f,(e+1)%3),
|
||||
kj=scaledKappa(j)*theta(f,(e+2)%3), kk=scaledKappa(k)*theta(f,e);
|
||||
|
||||
const ScalarK costhetaidiv = (eij-ejk+eki)/(2.*lens);
|
||||
const ScalarK sinthetaidiv = sqrt( (1.-pow(eij-ejk+eki,2)/
|
||||
(4.*eij*eki)) );
|
||||
|
||||
const ScalarK Corrijij = (ki+kj+kk);
|
||||
tripletList.emplace_back(E(f,e), E(f,e), Corrijij);
|
||||
tripletList.emplace_back(E(f,e)+nE, E(f,e)+nE, Corrijij);
|
||||
|
||||
const ScalarK Corrijki = -o*(ki-kj-kk)*costhetaidiv;
|
||||
tripletList.emplace_back(E(f,e), E(f,(e+2)%3), Corrijki);
|
||||
tripletList.emplace_back(E(f,(e+2)%3), E(f,e), Corrijki);
|
||||
tripletList.emplace_back(E(f,e)+nE, E(f,(e+2)%3)+nE, Corrijki);
|
||||
tripletList.emplace_back(E(f,(e+2)%3)+nE, E(f,e)+nE, Corrijki);
|
||||
|
||||
const ScalarK Corrijkiperp = o*(ki-kj-kk)*sinthetaidiv;
|
||||
tripletList.emplace_back(E(f,e), E(f,(e+2)%3)+nE, Corrijkiperp);
|
||||
tripletList.emplace_back(E(f,(e+2)%3)+nE, E(f,e), Corrijkiperp);
|
||||
tripletList.emplace_back(E(f,e)+nE, E(f,(e+2)%3), -Corrijkiperp);
|
||||
tripletList.emplace_back(E(f,(e+2)%3), E(f,e)+nE, -Corrijkiperp);
|
||||
}
|
||||
}
|
||||
|
||||
K.resize(2*nE, 2*nE);
|
||||
K.setFromTriplets(tripletList.begin(), tripletList.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template void igl::cr_vector_curvature_correction_intrinsic<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(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::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
template void igl::cr_vector_curvature_correction<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>, double>(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<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
#endif
|
||||
@@ -0,0 +1,115 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Oded Stein <oded.stein@columbia.edu>
|
||||
//
|
||||
// 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_CR_VECTOR_CURVATURE_CORRECTION_H
|
||||
#define IGL_CR_VECTOR_CURVATURE_CORRECTION_H
|
||||
|
||||
#include "igl_inline.h"
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
|
||||
namespace igl
|
||||
{
|
||||
// Computes the vector Crouzeix-Raviart curvature correction
|
||||
// term of Oded Stein, Alec Jacobson, Max Wardetzky, Eitan
|
||||
// Grinspun, 2020. "A Smoothness Energy without Boundary Distortion for
|
||||
// Curved Surfaces", but using the basis functions by Oded Stein,
|
||||
// Max Wardetzky, Alec Jacobson, Eitan Grinspun, 2020.
|
||||
// "A Simple Discretization of the Vector Dirichlet Energy"
|
||||
//
|
||||
// Inputs:
|
||||
// V, F: input mesh
|
||||
// E: a mapping from each halfedge to each edge, as computed with
|
||||
// orient_halfedges.
|
||||
// will be computed if not provided.
|
||||
// oE: the orientation of each halfedge compared to the orientation of the
|
||||
// actual edge, as computed with orient_halfedges.
|
||||
// will be computed if not provided.
|
||||
//
|
||||
// Outputs:
|
||||
// K: computed curvature correction matrix
|
||||
// E, oE: these are computed if they are not present, as described above
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarK>
|
||||
IGL_INLINE void
|
||||
cr_vector_curvature_correction(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K);
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarK>
|
||||
IGL_INLINE void
|
||||
cr_vector_curvature_correction(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
Eigen::PlainObjectBase<DerivedE>& E,
|
||||
Eigen::PlainObjectBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K);
|
||||
|
||||
|
||||
// Version that uses intrinsic quantities as input
|
||||
//
|
||||
// Inputs:
|
||||
// F: input mesh connectivity
|
||||
// l_sq: squared edge lengths of each halfedge
|
||||
// theta: the tip angles at each halfedge
|
||||
// kappa: the Gaussian curvature at each vertex
|
||||
// E: a mapping from each halfedge to each edge.
|
||||
// oE: the orientation of each halfedge compared to the orientation of the
|
||||
// actual edge.
|
||||
//
|
||||
// Outputs:
|
||||
// K: computed curvature correction matrix
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarK>
|
||||
IGL_INLINE void
|
||||
cr_vector_curvature_correction_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K);
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename Derivedtheta,
|
||||
typename DerivedE, typename DerivedOE,
|
||||
typename ScalarK>
|
||||
IGL_INLINE void
|
||||
cr_vector_curvature_correction_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<Derivedtheta>& theta,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K);
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename Derivedtheta,
|
||||
typename Derivedkappa, typename DerivedE, typename DerivedOE,
|
||||
typename ScalarK>
|
||||
IGL_INLINE void
|
||||
cr_vector_curvature_correction_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<Derivedtheta>& theta,
|
||||
const Eigen::MatrixBase<Derivedkappa>& kappa,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarK>& K);
|
||||
}
|
||||
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "cr_vector_curvature_correction.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,128 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Oded Stein <oded.stein@columbia.edu>
|
||||
//
|
||||
// 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 "cr_vector_laplacian.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "orient_halfedges.h"
|
||||
|
||||
#include "doublearea.h"
|
||||
#include "squared_edge_lengths.h"
|
||||
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarL>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_laplacian(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarL>& L)
|
||||
{
|
||||
Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic>
|
||||
l_sq;
|
||||
squared_edge_lengths(V, F, l_sq);
|
||||
cr_vector_laplacian_intrinsic(F, l_sq, E, oE, L);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarL>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_laplacian(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
Eigen::PlainObjectBase<DerivedE>& E,
|
||||
Eigen::PlainObjectBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarL>& L)
|
||||
{
|
||||
if(E.rows()!=F.rows() || E.cols()!=F.cols() || oE.rows()!=F.rows() ||
|
||||
oE.cols()!=F.cols()) {
|
||||
orient_halfedges(F, E, oE);
|
||||
}
|
||||
|
||||
const Eigen::PlainObjectBase<DerivedE>& cE = E;
|
||||
const Eigen::PlainObjectBase<DerivedOE>& coE = oE;
|
||||
cr_vector_laplacian(V, F, cE, coE, L);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarL>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_laplacian_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarL>& L)
|
||||
{
|
||||
Eigen::Matrix<typename DerivedL_sq::Scalar, Eigen::Dynamic, Eigen::Dynamic>
|
||||
dA;
|
||||
DerivedL_sq l_sqrt = l_sq.array().sqrt().matrix();
|
||||
doublearea(l_sqrt, dA);
|
||||
cr_vector_laplacian_intrinsic(F, l_sq, dA, E, oE, L);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DeriveddA,
|
||||
typename DerivedE, typename DerivedOE, typename ScalarL>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_laplacian_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DeriveddA>& dA,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarL>& L)
|
||||
{
|
||||
assert(F.cols()==3 && "Faces have three vertices");
|
||||
assert(E.rows()==F.rows() && E.cols()==F.cols() && oE.rows()==F.rows() &&
|
||||
oE.cols()==F.cols() && "Wrong dimension in edge vectors");
|
||||
assert(l_sq.rows()==F.rows() && l_sq.cols()==3 && "l_sq dimensions wrong");
|
||||
assert(dA.size()==F.rows() && "dA dimensions wrong");
|
||||
|
||||
const Eigen::Index m = F.rows();
|
||||
const typename DerivedE::Scalar nE = E.maxCoeff() + 1;
|
||||
|
||||
std::vector<Eigen::Triplet<ScalarL> > tripletList;
|
||||
tripletList.reserve(10*3*m);
|
||||
for(Eigen::Index f=0; f<m; ++f) {
|
||||
for(int e=0; e<3; ++e) {
|
||||
const ScalarL eij=l_sq(f,e), ejk=l_sq(f,(e+1)%3),
|
||||
eki=l_sq(f,(e+2)%3); //These are squared quantities.
|
||||
const ScalarL lens = sqrt(eij*eki);
|
||||
const ScalarL o = oE(f,e)*oE(f,(e+2)%3);
|
||||
|
||||
tripletList.emplace_back(E(f,e), E(f,e), 2./dA(f) * eij);
|
||||
tripletList.emplace_back(E(f,e)+nE, E(f,e)+nE, 2./dA(f) * eij);
|
||||
|
||||
const ScalarL Dijki = o * pow(eij-ejk+eki,2)/(2.*lens*dA(f));
|
||||
tripletList.emplace_back(E(f,e), E(f,(e+2)%3), Dijki);
|
||||
tripletList.emplace_back(E(f,(e+2)%3), E(f,e), Dijki);
|
||||
tripletList.emplace_back(E(f,e)+nE, E(f,(e+2)%3)+nE, Dijki);
|
||||
tripletList.emplace_back(E(f,(e+2)%3)+nE, E(f,e)+nE, Dijki);
|
||||
|
||||
const ScalarL Dijkiperp = -o * (eij-ejk+eki)/lens;
|
||||
tripletList.emplace_back(E(f,e), E(f,(e+2)%3)+nE, Dijkiperp);
|
||||
tripletList.emplace_back(E(f,(e+2)%3)+nE, E(f,e), Dijkiperp);
|
||||
tripletList.emplace_back(E(f,e)+nE, E(f,(e+2)%3), -Dijkiperp);
|
||||
tripletList.emplace_back(E(f,(e+2)%3), E(f,e)+nE, -Dijkiperp);
|
||||
}
|
||||
}
|
||||
L.resize(2*nE, 2*nE);
|
||||
L.setFromTriplets(tripletList.begin(), tripletList.end());
|
||||
}
|
||||
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template void igl::cr_vector_laplacian<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>, double>(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<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
template void igl::cr_vector_laplacian_intrinsic<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<int, -1, -1, 0, -1, -1>, double>(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&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Oded Stein <oded.stein@columbia.edu>
|
||||
//
|
||||
// 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_CR_VECTOR_LAPLACIAN_H
|
||||
#define IGL_CR_VECTOR_LAPLACIAN_H
|
||||
|
||||
#include "igl_inline.h"
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
|
||||
namespace igl
|
||||
{
|
||||
// Computes the CR vector Laplacian matrix.
|
||||
// See Oded Stein, Max Wardetzky, Alec Jacobson, Eitan Grinspun, 2020.
|
||||
// "A Simple Discretization of the Vector Dirichlet Energy"
|
||||
//
|
||||
// Inputs:
|
||||
// V, F: input mesh
|
||||
// E: a mapping from each halfedge to each edge, as computed with
|
||||
// orient_halfedges.
|
||||
// will be computed if not provided.
|
||||
// oE: the orientation of each halfedge compared to the orientation of the
|
||||
// actual edge, as computed with orient_halfedges.
|
||||
// will be computed if not provided.
|
||||
//
|
||||
// Outputs:
|
||||
// L: computed Laplacian matrix
|
||||
// E, oE: these are computed if they are not present, as described above
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarL>
|
||||
IGL_INLINE void
|
||||
cr_vector_laplacian(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarL>& L);
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarL>
|
||||
IGL_INLINE void
|
||||
cr_vector_laplacian(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
Eigen::PlainObjectBase<DerivedE>& E,
|
||||
Eigen::PlainObjectBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarL>& L);
|
||||
|
||||
|
||||
// Version that uses intrinsic quantities as input
|
||||
//
|
||||
// Inputs:
|
||||
// F: input mesh connectivity
|
||||
// l_sq: squared edge lengths of each halfedge
|
||||
// dA: double area of each face
|
||||
// E: a mapping from each halfedge to each edge.
|
||||
// oE: the orientation of each halfedge compared to the orientation of the
|
||||
// actual edge.
|
||||
//
|
||||
// Outputs:
|
||||
// L: computed Laplacian matrix
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarL>
|
||||
IGL_INLINE void
|
||||
cr_vector_laplacian_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarL>& L);
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DeriveddA,
|
||||
typename DerivedE, typename DerivedOE, typename ScalarL>
|
||||
IGL_INLINE void
|
||||
cr_vector_laplacian_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DeriveddA>& dA,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarL>& L);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "cr_vector_laplacian.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,112 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Oded Stein <oded.stein@columbia.edu>
|
||||
//
|
||||
// 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 "cr_vector_mass.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "orient_halfedges.h"
|
||||
|
||||
#include "doublearea.h"
|
||||
#include "squared_edge_lengths.h"
|
||||
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarM>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_mass(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarM>& M)
|
||||
{
|
||||
Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic>
|
||||
l_sq;
|
||||
squared_edge_lengths(V, F, l_sq);
|
||||
cr_vector_mass_intrinsic(F, l_sq, E, oE, M);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarM>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_mass(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
Eigen::PlainObjectBase<DerivedE>& E,
|
||||
Eigen::PlainObjectBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarM>& M)
|
||||
{
|
||||
if(E.rows()!=F.rows() || E.cols()!=F.cols() || oE.rows()!=F.rows() ||
|
||||
oE.cols()!=F.cols()) {
|
||||
orient_halfedges(F, E, oE);
|
||||
}
|
||||
|
||||
const Eigen::PlainObjectBase<DerivedE>& cE = E;
|
||||
const Eigen::PlainObjectBase<DerivedOE>& coE = oE;
|
||||
cr_vector_mass(V, F, cE, coE, M);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarM>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_mass_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarM>& M)
|
||||
{
|
||||
Eigen::Matrix<typename DerivedL_sq::Scalar, Eigen::Dynamic, Eigen::Dynamic>
|
||||
dA;
|
||||
DerivedL_sq l_sqrt = l_sq.array().sqrt().matrix();
|
||||
doublearea(l_sqrt, dA);
|
||||
cr_vector_mass_intrinsic(F, l_sq, dA, E, oE, M);
|
||||
}
|
||||
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DeriveddA,
|
||||
typename DerivedE, typename DerivedOE, typename ScalarM>
|
||||
IGL_INLINE void
|
||||
igl::cr_vector_mass_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DeriveddA>& dA,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarM>& M)
|
||||
{
|
||||
assert(F.cols()==3 && "Faces have three vertices");
|
||||
assert(E.rows()==F.rows() && E.cols()==F.cols() && oE.rows()==F.rows() &&
|
||||
oE.cols()==F.cols() && "Wrong dimension in edge vectors");
|
||||
|
||||
const Eigen::Index m = F.rows();
|
||||
const typename DerivedE::Scalar nE = E.maxCoeff() + 1;
|
||||
|
||||
std::vector<Eigen::Triplet<ScalarM> > tripletList;
|
||||
tripletList.reserve(2*3*m);
|
||||
for(Eigen::Index f=0; f<m; ++f) {
|
||||
for(int e=0; e<3; ++e) {
|
||||
const typename DerivedF::Scalar v1=F(f,(e+1)%3), v2=F(f,(e+2)%3);
|
||||
//Scaled
|
||||
const ScalarM entry = dA(f) / 6;
|
||||
tripletList.emplace_back(E(f,e), E(f,e), entry);
|
||||
tripletList.emplace_back(E(f,e)+nE, E(f,e)+nE, entry);
|
||||
}
|
||||
}
|
||||
M.resize(2*nE, 2*nE);
|
||||
M.setFromTriplets(tripletList.begin(), tripletList.end());
|
||||
}
|
||||
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
template void igl::cr_vector_mass<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>, double>(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<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
template void igl::cr_vector_mass_intrinsic<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<int, -1, -1, 0, -1, -1>, double>(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&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2020 Oded Stein <oded.stein@columbia.edu>
|
||||
//
|
||||
// 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_CR_VECTOR_MASS
|
||||
#define IGL_CR_VECTOR_MASS
|
||||
|
||||
#include "igl_inline.h"
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
|
||||
namespace igl
|
||||
{
|
||||
// Computes the CR vector mass matrix, using an arrangement of all parallel
|
||||
// degrees of freedom first, and all perpendicular degrees of freedom next.
|
||||
// See Oded Stein, Max Wardetzky, Alec Jacobson, Eitan Grinspun, 2020.
|
||||
// "A Simple Discretization of the Vector Dirichlet Energy"
|
||||
//
|
||||
// Inputs:
|
||||
// V, F: input mesh
|
||||
// E: a mapping from each halfedge to each edge, as computed with
|
||||
// orient_halfedges.
|
||||
// will be computed if not provided.
|
||||
// oE: the orientation of each halfedge compared to the orientation of the
|
||||
// actual edge, as computed with orient_halfedges.
|
||||
// will be computed if not provided.
|
||||
//
|
||||
// Outputs:
|
||||
// M: computed mass matrix
|
||||
// E, oE: these are computed if they are not present, as described above
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarM>
|
||||
IGL_INLINE void
|
||||
cr_vector_mass(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarM>& M);
|
||||
|
||||
template <typename DerivedV, typename DerivedF, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarM>
|
||||
IGL_INLINE void
|
||||
cr_vector_mass(
|
||||
const Eigen::MatrixBase<DerivedV>& V,
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
Eigen::PlainObjectBase<DerivedE>& E,
|
||||
Eigen::PlainObjectBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarM>& M);
|
||||
|
||||
|
||||
// Version that uses intrinsic quantities as input
|
||||
//
|
||||
// Inputs:
|
||||
// F: input mesh connectivity
|
||||
// l_sq: squared edge lengths of each halfedge
|
||||
// dA: double area of each face
|
||||
// E: a mapping from each halfedge to each edge.
|
||||
// oE: the orientation of each halfedge compared to the orientation of the
|
||||
// actual edge.
|
||||
//
|
||||
// Outputs:
|
||||
// M: computed mass matrix
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DerivedE,
|
||||
typename DerivedOE, typename ScalarM>
|
||||
IGL_INLINE void
|
||||
cr_vector_mass_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarM>& M);
|
||||
|
||||
template <typename DerivedF, typename DerivedL_sq, typename DeriveddA,
|
||||
typename DerivedE, typename DerivedOE, typename ScalarM>
|
||||
IGL_INLINE void
|
||||
cr_vector_mass_intrinsic(
|
||||
const Eigen::MatrixBase<DerivedF>& F,
|
||||
const Eigen::MatrixBase<DerivedL_sq>& l_sq,
|
||||
const Eigen::MatrixBase<DeriveddA>& dA,
|
||||
const Eigen::MatrixBase<DerivedE>& E,
|
||||
const Eigen::MatrixBase<DerivedOE>& oE,
|
||||
Eigen::SparseMatrix<ScalarM>& M);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "cr_vector_mass.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -97,4 +97,5 @@ void igl::crouzeix_raviart_cotmatrix(
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template void igl::crouzeix_raviart_cotmatrix<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>, double>(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<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
template void igl::crouzeix_raviart_cotmatrix<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>, double>(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<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user