Compare commits

...
160 Commits
Author SHA1 Message Date
Jérémie Dumas ed363da1f6 Update .travis.yml
Former-commit-id: 941b40334633a419e095aa62cf69ee4adab63800
2018-10-15 14:55:30 -04:00
Teseo Schneider 15bd0e0996 fixed test
Former-commit-id: 4f840e8649e912c2db1c1c24f4fc39966a7cc0b3
2018-10-15 14:51:18 -04:00
Alec Jacobson 8235ccb3d0 do python last
Former-commit-id: 02b367811edac92ad1acb3a561e5a3615425bc9b
2018-10-15 14:29:59 -04:00
Alec Jacobson 61639328f9 make test --> ctest --verbose
Former-commit-id: b4438c593e008230dc94194936b65b32c3c8605b
2018-10-15 14:27:23 -04:00
teseoch 8ca734ee17 Update .appveyor.yml
removed build of test target on windows

Former-commit-id: 568278dbc3bc0ced682a54775ae8fbd8cd8fb3bd
2018-10-15 14:12:53 -04:00
teseoch 1bfaa60e32 Update .travis.yml
removed verbose tests

Former-commit-id: e13f25477ea07ed146c689beebcb638bdc905ab6
2018-10-15 13:43:54 -04:00
teseoch 67c8d6a141 Update .appveyor.yml
small fix on windows compilation

Former-commit-id: 6dbc01bb8a773ea4b8bf381051654ef4e77ed937
2018-10-15 13:41:56 -04:00
teseoch 971d190108 Update .appveyor.yml
fixed windows compilation

Former-commit-id: 9b2a86e98c650fbacd230fe1fef055c8c17d3f99
2018-10-15 13:31:41 -04:00
Francis Williams b2e8d0b3d3 Sparse grid bfs (#942)
* Add a utility function which computes a sparse set of epsilon-sized grid cells surrounding an input surface. The function takes a point on the surface as input and finds all those epsilon grid cells that intersect the surface using a breadth first search over the grid space.

* Add a utility function which computes a sparse set of epsilon-sized grid cells surrounding an input surface. The function takes a point on the surface as input and finds all those epsilon grid cells that intersect the surface using a breadth first search over the grid space.


Former-commit-id: 1dbd225d993a5417c7d3bedc3a6ba354cc256956
2018-10-15 13:17:06 -04:00
Qingnan Zhou ae3df06258 Remove a cgal unit test temporarily. (#943)
Former-commit-id: 8df208b5f1ad712d5fc5003a1fe7534a5a7cca62
2018-10-15 13:04:01 -04:00
Alec Jacobson 75577c62d7 change message
Former-commit-id: bb1a0b6d20
2018-10-15 12:50:15 -04:00
Jérémie Dumas 8895c712b6 Fix position independent code on Linux. (#941)
Former-commit-id: e21aa88a8b
2018-10-15 12:46:03 -04:00
Alec Jacobson 7f852d8aee fix options
Former-commit-id: 8a2d93cf14
2018-10-15 12:41:49 -04:00
Jérémie Dumas d3dd83f11b Set default options based on toplevel project. (#940)
* Enable options based on toplevel CMake call.

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt


Former-commit-id: 86d3564a14
2018-10-15 12:05:43 -04:00
Qingnan Zhou 5977205363 Make boost static lib an option. (#936)
* Migrate unit tests back to the main repo.

* Minor bug fixes and getting unit test migrated.

* Minor cmake bug for unit tests.

* Make CGAL boost static lib an option.

* Update libigl.cmake

change to ON


Former-commit-id: eb3b18002e
2018-10-15 11:46:38 -04:00
Francis Williams 954cd99196 Sparse Voxel Grid (#937)
* Add a utility function which computes a sparse set of epsilon-sized grid cells surrounding an input surface. The function takes a point on the surface as input and finds all those epsilon grid cells that intersect the surface using a breadth first search over the grid space.

* Add a utility function which computes a sparse set of epsilon-sized grid cells surrounding an input surface. The function takes a point on the surface as input and finds all those epsilon grid cells that intersect the surface using a breadth first search over the grid space.


Former-commit-id: 4f030acb67
2018-10-15 11:46:23 -04:00
Qingnan Zhou 883d0a5028 Remove .gitattributes to avoid line ending problem...
Former-commit-id: fa773a79f4
2018-10-15 11:44:39 -04:00
teseoch 036fc21668 update test for verbose (#938)
* fixed unit test

* partial revert of cmake glob

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* changed build dont know if it works

* verbose testing


Former-commit-id: 7a70f449d4
2018-10-15 11:37:04 -04:00
Jérémie Dumas 8035584024 Merge branch 'dev' of github.com:libigl/libigl into dev
Former-commit-id: 024f7cb2ac
2018-10-15 11:28:29 -04:00
Alec Jacobson 72f08a45b8 ignore tests data
Former-commit-id: c45d8a6fda
2018-10-15 11:27:07 -04:00
Alec Jacobson a1e026fbe6 rm tutorial shared
Former-commit-id: 8fd4d1eee9
2018-10-15 11:24:12 -04:00
Jérémie Dumas b672900456 Clean external/ folder.
Former-commit-id: 13c715d56b
2018-10-15 11:17:29 -04:00
teseoch e9fc2a82eb travis and appveyor build test (#935)
* fixed unit test

* partial revert of cmake glob

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* changed build dont know if it works


Former-commit-id: 8502e8d856
2018-10-15 11:05:22 -04:00
Daniele Panozzo 0c831a3fe9 Merge pull request #933 from jdumas/external
Clean external/ folder.

Former-commit-id: bd78e59278
2018-10-15 11:03:16 -04:00
Jérémie Dumas 956c94dfad Merge remote-tracking branch 'origin/dev' into external
Former-commit-id: 9d1dab22c1
2018-10-15 10:51:24 -04:00
Jérémie Dumas 8825f6f94a Hide warning about detached HEAD.
Former-commit-id: 40c3279113
2018-10-15 10:50:15 -04:00
teseoch e4d513a0b7 Teseo (#934)
* fixed unit test

* partial revert of cmake glob

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt


Former-commit-id: 38948329fc
2018-10-15 10:50:01 -04:00
Alec Jacobson 5066b5d253 Create pull_request_template.md (#931)
* Create pull_request_template.md

* Update pull_request_template.md


Former-commit-id: c5dd003a18
2018-10-15 10:46:50 -04:00
Alec Jacobson 99bc7bddb6 Create issue_template.md (#932)
* Create issue_template.md

* Update issue_template.md


Former-commit-id: 207a121296
2018-10-15 10:46:40 -04:00
Daniele Panozzo 14da3a4a9a Merge branch 'dev' of https://github.com/libigl/libigl into dev
Former-commit-id: 65fca1fc2e
2018-10-15 10:31:19 -04:00
Daniele Panozzo ee2599de1a updated cmake files and options
Former-commit-id: 54980dbb68
2018-10-15 10:28:26 -04:00
Jérémie Dumas ba47646bc5 Clean external/ folder.
Former-commit-id: c80df363b7
2018-10-15 10:28:04 -04:00
Teseo Schneider 8ce9abcfc6 fixed template instantiation
Former-commit-id: 4e3654f442
2018-10-15 09:48:55 -04:00
Qingnan Zhou 0bfa95b9d9 Minor cmake bug fix. (#929)
* Migrate unit tests back to the main repo.

* Minor bug fixes and getting unit test migrated.

* Minor cmake bug for unit tests.


Former-commit-id: 7ffcdfe5ff
2018-10-15 09:40:23 -04:00
Qingnan Zhou 10200efa2b Unittests!! (#928)
* Migrate unit tests back to the main repo.

* Minor bug fixes and getting unit test migrated.


Former-commit-id: 823ef3e404
2018-10-15 09:12:38 -04:00
Jérémie Dumas af18599ef7 Fix submodule issue.
Former-commit-id: 7ffb60a73e
2018-10-14 23:39:31 -04:00
Teseo Schneider c722b46cbd Merge branch 'dev' of github.com:libigl/libigl into dev
Former-commit-id: 9527889111
2018-10-14 23:17:28 -04:00
Teseo Schneider 2921ffaff6 Merge branch 'dev' of github.com:libigl/libigl into dev
Former-commit-id: ea8f88578f
2018-10-14 23:17:18 -04:00
Alec Jacobson 76370d4525 ok, maybe one phrase
Former-commit-id: 5db42e6ef7
2018-10-14 23:17:16 -04:00
Teseo Schneider 0787113a1b main cmake inclding only one igl
Former-commit-id: 5ee5360fa0
2018-10-14 23:17:12 -04:00
Alec Jacobson 3f7895d172 simple readme
Former-commit-id: 3a9673ff28
2018-10-14 23:16:02 -04:00
Teseo Schneider ef78023af4 cleanup cmake
Former-commit-id: 3c4d98ce56
2018-10-14 22:48:56 -04:00
Teseo Schneider 242a4485af added download of data and cleaned up cmake
Former-commit-id: b63e31340f
2018-10-14 22:33:37 -04:00
Daniele Panozzo 4ffc570482 docs moved to a separate repo https://github.com/libigl/libigl.github.io
Former-commit-id: e21e99c40e
2018-10-14 21:54:46 -04:00
Daniele Panozzo 4d66545557 scripts folder is now in a separate repo libigl-scripts
Former-commit-id: 41229497f6
2018-10-14 21:51:18 -04:00
Jérémie Dumas 628375d4d2 Merge pull request #927 from jdumas/skinny
Move from submodules to cmake external.

Former-commit-id: 824ab2d754
2018-10-14 21:45:31 -04:00
Jérémie Dumas 340521757c Update cmake.
Former-commit-id: c80da2902f
2018-10-14 21:36:41 -04:00
Jérémie Dumas 76b8ca17d8 Update cmake.
Former-commit-id: 430271682c
2018-10-14 19:46:27 -04:00
Jérémie Dumas 1ef33b03a2 Move from submodules to cmake external.
Former-commit-id: de5e3215de
2018-10-14 19:35:08 -04:00
Francis Williams 0d1d133330 marching tetrahedra documentation (#926)
Former-commit-id: 3bb85d91df
2018-10-14 19:31:17 -04:00
Alec Jacobson 1fe4eb190f Revert "Revert "Marching Tetrahedra (#716)" (#924)" (#925)
This reverts commit 65aa93e9ef [formerly 47634615ce].

Former-commit-id: fd8d66156c
2018-10-14 19:17:01 -04:00
Alec Jacobson 65aa93e9ef Revert "Marching Tetrahedra (#716)" (#924)
This reverts commit 7cb42ce972 [formerly d152b6072e].

Former-commit-id: 47634615ce
2018-10-14 19:16:39 -04:00
Francis Williams 7cb42ce972 Marching Tetrahedra (#716)
* Marching Tetrahedra

* dropping cxx11


Former-commit-id: d152b6072e
2018-10-14 19:14:45 -04:00
Qingnan Zhou c0c396c237 Adds interface for the multi-zone mesh generation capabilities of TetGen (#923)
* Update tetrahedralize.h

* Update tetrahedralize.h

* WIP: adding overload for allowing holes and regions in tetgen mesh

* Update tetrahedralize.h

* Update tetrahedralize.h

* WIP: adding overload for allowing holes and regions in tetgen mesh

* WIP: skeleton code for tetrahedralize supporting holes and regions

* removes comments

* call to overloaded mesh_to_tetgenio()

* overload to allow for holes and regions

* WIP: overload to allow for holes and regions

* fixes typos

* fixed function signature

* adds comments

* adds overload for returning regionID information

* added overload for holes and regions

* added Eigen wrapper

* WIP: add support for neighborlist and point2tet

* WIP: adding point2tet and neighborlist info

* adds support for face to tet list

* WIP: bug fixes, regions, holes

* support for holes, regions, point2tet, face2tet, tet neighbors

* Update tetgen to 1.5.1.


Former-commit-id: b4eaa0dac7
2018-10-14 18:58:58 -04:00
Alec Jacobson 7dc2b11c2a Merge branch 'dev' of github.com:libigl/libigl into dev
Former-commit-id: 6802bb2a4e
2018-10-14 18:43:46 -04:00
Alec Jacobson 3f442b54f3 [bug fix]: uncomment boundary_facets
Former-commit-id: a79f95b7ca
2018-10-14 18:43:42 -04:00
Jérémie Dumas 96c8ea4931 Update .appveyor.yml
Former-commit-id: 6fba5b123a
2018-10-14 18:41:04 -04:00
Alec Jacobson 928cbe67bb Merge branch 'dev' of github.com:libigl/libigl into dev
Former-commit-id: 28dd927d18
2018-10-14 18:12:11 -04:00
Alec Jacobson 9a149ece72 rm stray cout
Former-commit-id: 3253bed881
2018-10-14 18:12:06 -04:00
Jérémie Dumas 76ae819489 Merge pull request #839 from ithron/installable
Make libigl installable using CMake

Former-commit-id: d1d48f2b67
2018-10-14 18:08:41 -04:00
Daniele Panozzo 66ec792368 Merge pull request #819 from vskhitkov/principal_curvature_fix
fix: principal_curvature returns vector of bad vertex indices
Former-commit-id: 20c76ca2a2
2018-10-14 18:05:53 -04:00
Zhongshi 2726464472 Adding 2D version of SCAF for Bijective Maps and a tutorial (#752)
* Add scaf code

Add the tutorial entry

Tutorial entry for SCAF. still need polishing

Put -4 in the energy computation of scaf:SymmD

* 🏫 Insert SCAF to 711

Fixes in tutorial.md

updating tutorial.html

Fix for gcc 4.8

Remove 4.1

Refactoring scaf WIP

Further refactoring WIP

Code Cleaning

* 🔨 Improve SLIM interface

* ♻️ refactor SCAF with less lines

* ♻️ refactor harmonic with boundary

*  Add direct signature for scaf

* 📝 Change tutorial order wip

* 🏫 Timer in SLIM tutorial makes more sense

*  Add direct interface for SLIM

* 🎨 format SCAF code.

* 🐍 Python binding for slim and scaf

* 🐍 expose SLIMData (maybe elevate its status more in the future)

* 👽 🐍 deprecate PYBIND11_PLUGIN

*  harmonic with holes

* ♻️ SCAF, Decouple Initialization to tutorial

* 🏫 SCAF tutorial improvement

* 🏫 Tutorial order; insert scaf

* 🎨 Removing Adjusted_grad

*     🏫 Inserted SCAF, not messing around with tutorials order until the new page is online

* 💚 Fix for static build

* ♻️ Uniform SLIM and SCAF and  python binding canonical

* 🐛 Change in ScafData

* 🍎 Fix namespace for build

*  Introduced Mapping Energy Type to replace adhoc SLIMEnergy

* ♻️ Refactor subroutines from SLIM

* Revert python changes

* leave fill hole outside harmonic

* Revert Python changes

* hole fill

* Minor Fixes for SCAF

SCAF->IGL_SCAF
Topological_hole_fill 
"<igl/XXX>" in slim tutorial


Former-commit-id: 4edf5dede5
2018-10-14 17:55:36 -04:00
Oded Stein 31d419e2c0 Tetrahedral adjacenct functions (#835)
* Add tet_tet_adjacency

* added parallelization of the preprocessing

* Add tet_tet_adjacency

* added parallelization of the preprocessing

* Add tet_tet_adjacency

* added parallelization of the preprocessing

* Add tet_tet_adjacency

* added parallelization of the preprocessing

* Add tet_tet_adjacency

* added parallelization of the preprocessing

* Add tet_tet_adjacency

* added parallelization of the preprocessing

* Add tet_tet_adjacency

* Add tet_tet_adjacency

* added parallelization of the preprocessing

* added parallelization of the preprocessing

* fixed rebasing stuff

* Use template for index type


Former-commit-id: ab3f20c83e
2018-10-14 17:21:31 -04:00
hanxiao 9e10c1b534 Merge branch 'vskhitkov-principal_curvature_fix' into dev
Former-commit-id: b9567ca191
2018-10-14 17:19:46 -04:00
hanxiao 4e739bc528 update tutorial 203
Former-commit-id: cb4a4d111f
2018-10-14 17:14:52 -04:00
hanxiao d3510ceeba Merge branch 'dev' of https://github.com/libigl/libigl into dev
Former-commit-id: f6be209bad
2018-10-14 16:26:40 -04:00
Alec Jacobson 41b4a5e62e Merge pull request #908 from MeshGeometry/master
Added optional weights to Dijkstra's algorithm + some template definitions

Former-commit-id: 8bfa7e9a59
2018-10-14 16:26:34 -04:00
Francis Williams 2de5e29fc9 Merge pull request #575 from fwilliams/sparse_mc
Marching cubes over sparse indexed grids

Former-commit-id: 044b1626d2
2018-10-14 16:25:39 -04:00
Alec Jacobson 93cba2e044 rename
Former-commit-id: 23e9373fdf
2018-10-14 16:24:56 -04:00
Alec Jacobson a38371d231 Merge pull request #809 from evouga/cutmesh
Code to cut meshes into topological disks

Former-commit-id: b72c9a7b96
2018-10-14 16:18:05 -04:00
Alec Jacobson 5e20808faa Update cut_to_disk.cpp
Former-commit-id: d974e22c6f
2018-10-14 16:17:47 -04:00
hanxiao 714658b8d7 Merge branch 'vskhitkov-principal_curvature_fix' into dev
Former-commit-id: ad42bf1d2c
2018-10-14 16:01:47 -04:00
hanxiao 414740aa38 add overload function for principal_curvature
Former-commit-id: 73cb2a97f1
2018-10-14 16:01:22 -04:00
Alec Jacobson 0cdc451a80 Merge pull request #530 from milkpku/comb_cross_field
add while loop for comb_cross_field.cpp, making comb support separated manifold

Former-commit-id: 71e1bb476a
2018-10-14 15:41:56 -04:00
Alec Jacobson 56eee0e3a4 Merge pull request #859 from jdumas/imgui
Update ImGui bindings.

Former-commit-id: 908da7473c
2018-10-14 15:40:58 -04:00
Alec Jacobson 5b534bff4c Merge pull request #857 from jdumas/viewer
Minor fixes to the viewer.

Former-commit-id: 65700c1958
2018-10-14 15:40:29 -04:00
Francis Williams 12b904a5b8 Add isovalue support
Former-commit-id: 1194f8921e
2018-10-14 15:39:27 -04:00
hanxiao bcddf01d77 Merge branch 'principal_curvature_fix' of https://github.com/vskhitkov/libigl into vskhitkov-principal_curvature_fix
Former-commit-id: 4807ce91a3
2018-10-14 15:25:55 -04:00
Francis Williams b0eb3db0aa hide marching cubes internal state in class
Former-commit-id: 32824a591c
2018-10-14 15:22:59 -04:00
Francis Williams 409aee509d Marching cubes over sparse indexed grids
Former-commit-id: 2774fec8f4
2018-10-14 15:18:09 -04:00
Alec Jacobson 0c2b5cec70 Merge pull request #921 from libigl/revert-920-revert-856-master
Revert "Revert "Make avg_edge_length() count interior edges only once.""

Former-commit-id: e874029655
2018-10-14 15:15:07 -04:00
Alec Jacobson 075e95bfd2 Revert "Revert "Make avg_edge_length() count interior edges only once.""
Former-commit-id: 584d437b9a
2018-10-14 15:14:38 -04:00
Alec Jacobson 3e35dc3a76 Merge pull request #920 from libigl/revert-856-master
Revert "Make avg_edge_length() count interior edges only once."

Former-commit-id: e74b183473
2018-10-14 15:13:00 -04:00
Alec Jacobson 7b6ebdc3ea Revert "Make avg_edge_length() count interior edges only once."
Former-commit-id: e797ac9b60
2018-10-14 15:12:42 -04:00
Alec Jacobson c192e28084 Merge pull request #856 from jdumas/master
Make avg_edge_length() count interior edges only once.

Former-commit-id: 05db403158
2018-10-14 15:12:38 -04:00
Daniele Panozzo 59251ca327 mojave opengl fix
Former-commit-id: c271bbf50b
2018-10-14 15:01:54 -04:00
Daniele Panozzo 2a47253152 Merge branch 'comb_cross_field' of https://github.com/milkpku/libigl into dev
Former-commit-id: 300903ae99
2018-10-14 14:50:37 -04:00
hanxiao ef42f203ad Merge branch 'fwilliams-function_rename' into dev
Former-commit-id: aa0bd56830
2018-10-14 14:49:22 -04:00
hanxiao e0849c88da update release history markdown
Former-commit-id: 329f32e6cf
2018-10-14 14:49:08 -04:00
hanxiao c415f21858 Merge branch 'function_rename' of https://github.com/fwilliams/libigl into fwilliams-function_rename
Former-commit-id: 62b9246c73
2018-10-14 14:07:27 -04:00
Qingnan Zhou 4125afe80f Merge branch 'dev' into HEAD
Former-commit-id: 5e99913faa
2018-10-14 14:00:50 -04:00
Alec Jacobson f16ee6d7c5 merge
Former-commit-id: 2829ba2cde
2018-10-14 13:50:15 -04:00
Jérémie Dumas 8847026227 Merge branch 'dev' of github.com:libigl/libigl into dev
Former-commit-id: 1e4efe1606
2018-10-14 13:47:53 -04:00
Jérémie Dumas a6423836aa Add missing template instantiation.
Former-commit-id: bbb1c430af
2018-10-14 13:47:43 -04:00
Alec Jacobson 03653319d1 Merge pull request #612 from breannansmith/obj_load_fix
Fix for a segfault when attempting to load a non-existant obj mesh th…

Former-commit-id: 5cb00f2f68
2018-10-14 12:52:37 -04:00
Alec Jacobson f12ffbd24e Merge pull request #872 from jimmyland/patch-2
fix comments for qslim.h

Former-commit-id: 1b4123f4ff
2018-10-14 12:26:52 -04:00
Alec Jacobson 28801efb8b Merge pull request #878 from jiangzhongshi/patch-5
🐛 Allow empty input in exact_geodesic

Former-commit-id: b32090f7f6
2018-10-14 12:23:53 -04:00
Alec Jacobson 4db3a4c521 Merge pull request #887 from jiangzhongshi/patch-4
📝 fix screen capture tutorial

Former-commit-id: 7f12674a7e
2018-10-14 12:23:16 -04:00
Alec Jacobson 85ffda7ef4 Merge pull request #889 from jimmyland/patch-3
cotmatrix appears to support tetrahedra too

Former-commit-id: bc9ca8b942
2018-10-14 12:20:42 -04:00
Alec Jacobson 2e66247d99 Merge pull request #892 from artoonie/bugfix/enableOuput
fix EnableOutput flag for less verbosity in LIM

Former-commit-id: 16bdbf0fa3
2018-10-14 12:20:08 -04:00
Alec Jacobson 5f428b210e Merge pull request #917 from unclejimbo/fix-redux
Fix redux

Former-commit-id: ae30d97242
2018-10-14 12:18:14 -04:00
unclejimbo 7aed747cd7 remove unneeded include
Former-commit-id: c4c431c08c
2018-10-11 21:35:43 +08:00
unclejimbo 3ef2e16408 fix func_wrap argument type
Former-commit-id: c0340bec3d
2018-10-11 21:35:10 +08:00
Alec Jacobson 45acb3a583 adding explicit FindMATLAB.cmake (from cmake 3.10.2), because cmake 3.12.3's broke our build
Former-commit-id: d68f2f4cc2
2018-10-10 08:49:07 -04:00
Alec Jacobson 42883bb57a add cpature
Former-commit-id: 78ed65659d
2018-09-28 14:51:55 -04:00
Daniel Hambleton c7c906c204 fixed win64 compile
Former-commit-id: 82be337653
2018-09-28 13:05:19 -04:00
zero-impact dd44506bcc Removing nanogui..
Former-commit-id: 25a5c60fb8
2018-09-27 10:25:51 -04:00
zero-impact 4f83e01386 Merge remote-tracking branch 'upstream/master' into merge_branch
Former-commit-id: f92b6355db
2018-09-27 10:13:25 -04:00
zero-impact e2a7dc74dd adding templates
Former-commit-id: 9459a9fd41
2018-09-27 10:06:51 -04:00
Alec Jacobson 8c5e9bd9bd better windows support (hopefully), unix unit tests still pass
Former-commit-id: b517b345ed
2018-09-25 23:56:32 -04:00
Alec Jacobson 855f60f9f6 [bug fix]: dirname building single char string wrong.
Former-commit-id: dc4c3379b4
2018-09-25 23:30:51 -04:00
zero-impact bb730dec7d adding template
Former-commit-id: 3ba94e928e
2018-09-21 13:19:05 -04:00
zero-impact cec9df42aa Added a weights option to dijkstras
Former-commit-id: 34be9cb7a8
2018-09-14 17:51:36 -04:00
Daniel Hambleton 2b666475ec Merge branch 'master' of github.com:MeshGeometry/libigl
Former-commit-id: 274ae444e0
2018-09-14 15:58:23 -04:00
Daniel Hambleton fd8ee231b1 merged
Former-commit-id: 750bcc8e4b
2018-09-14 15:57:02 -04:00
Armin Samii 66696c2222 fix EnableOutput flag for less verbosity in LIM
Former-commit-id: 1ef2f83aee
2018-09-14 10:22:44 -07:00
James Andrews c47b26d73a massmatrix also apparently supports tets?
Former-commit-id: c0c158c4ce
2018-09-12 16:29:51 -07:00
James Andrews db2419a6e3 cotmatrix appears to support tetrahedra too
Former-commit-id: c0c1cb00a3
2018-09-12 16:16:35 -07:00
Zhongshi 2ceac853c3 📝 fix screen capture tutorial
Former-commit-id: 852d2ad1b7
2018-09-07 14:51:50 -04:00
Zhongshi f6c1f0bea1 🐛 Allow empty input in exact_geodesic
Former-commit-id: f914d8a175
2018-08-26 22:47:43 -07:00
James Andrews 1a42b39c93 Update qslim.h
also complete the cut off sentence in the V comment

Former-commit-id: bae373e510
2018-08-15 17:11:54 -07:00
James Andrews a54d558f82 "G can be same ref as G" -> "can be same ref as F"
Former-commit-id: fe87d32fb8
2018-08-15 13:12:55 -07:00
Jérémie Dumas ef81faeac2 Fix stupid mistake.
Former-commit-id: d8dc5963bd
2018-08-07 14:08:56 -04:00
Jérémie Dumas 7117af68b5 Merge remote-tracking branch 'upstream/master' into imgui
Former-commit-id: 52be21257f
2018-08-07 11:59:35 -04:00
Jérémie Dumas 5b13a5c490 Merge remote-tracking branch 'upstream/master' into viewer
Former-commit-id: 2944889f64
2018-08-07 11:59:23 -04:00
Jérémie Dumas c314bf9182 Merge remote-tracking branch 'upstream/master'
Former-commit-id: b4bbe7597b
2018-08-07 11:58:36 -04:00
Jérémie Dumas 58f16f00e7 Fix CMake script.
Former-commit-id: 44c8604698
2018-08-04 12:14:26 -04:00
Jérémie Dumas 621f31e10e Fix CMake script.
Former-commit-id: 3ba5cefe1c
2018-08-03 21:02:48 -04:00
Jérémie Dumas 209b81e56c Update ImGui bindings.
Warnings: potentially breaking changes on the ImGui, may require user to
adapt their UI code.

Former-commit-id: ce723d8c00
2018-08-03 20:56:10 -04:00
Jérémie Dumas 92f2e20fa5 Change priority of callbacks vs plugins in the Viewer (fixes #764).
Former-commit-id: 4087099a66
2018-08-03 17:56:20 -04:00
Jérémie Dumas 9cdf351f6b Fixes #757.
Former-commit-id: b1d576dba7
2018-08-03 17:42:50 -04:00
Jérémie Dumas 7fba338427 avg_edge_length() should count interior edges only once.
Former-commit-id: e68568582c
2018-08-03 17:32:08 -04:00
Stefan Reinhold eb6ffec8d5 Add Eigen3 requirement to package configuration
In package configuration file:
1. Look for Eigen3::Eigen target. If not present:
2. use find_package(Eigen3) to look for Eigen3. On failure:
3. Use pkg_check_modules to look for Eigen3. (Eigen provided a
   pkg-config file).
If neither of the three options succeed, find_package(libigl) will fail
with an error message.


Former-commit-id: e777d220fc
2018-07-24 16:58:58 +02:00
Stefan Reinhold edf08926c5 Fix: installed target not prefixed with igl::
Former-commit-id: d66546f12f
2018-07-24 16:58:22 +02:00
Stefan Reinhold b3fce1689c Check if all required components are available
Former-commit-id: 61db9ead55
2018-07-24 16:18:27 +02:00
Stefan Reinhold de3749fc55 Improve export and installation part
Currently only the core module is supported for export and installation

Former-commit-id: 1de5836307
2018-07-24 16:18:11 +02:00
Francis Williams a9c3b6d50a rename components.[h|cpp] to vertex_components.[h|cpp]
Former-commit-id: 989a144269
2018-07-22 23:25:13 -04:00
Francis Williams 18a1eaf38c we have the functions igl::components() and igl::facet_components() for computing connected components on vertices and faces respectively.
The naming here is super confusing (and someone wasted a couple of hours because they didn't know that facet_components existed).

This change improves discoverability in 2 ways:
1 - More consistent naming by changint `components()` to `vertex_components()` which hints that there may exist a `facet_component()` function.
2 - Reference `facet_components()` in the docs for `vertex_components()` and vice versa


Former-commit-id: 43a7d250f5
2018-07-20 15:20:51 -04:00
Stefan Reinhold 075f884f5f Add missing include of CMakePackageConfigHelpers
Former-commit-id: e98b098db9
2018-07-19 16:55:22 +02:00
Stefan Reinhold 28f59dfe2f Add top level CMakeLists.txt
This file currently acts as a placeholder for optional/CMakeLists.txt to
enable automatic builds. Maybe it's a good idea to move
optional/CMakeLists.txt here.


Former-commit-id: f77e8ba252
2018-07-19 16:50:09 +02:00
Stefan Reinhold 2256dd7264 Add package configuration file
Former-commit-id: 2397ab9df8
2018-07-19 15:58:23 +02:00
Stefan Reinhold eaa2d52f4e Change all CMAKE_SOURCE_DIR to CMAKE_CURRENT_SOURCE_DIR
Former-commit-id: d101477842
2018-07-19 15:30:07 +02:00
Stefan Reinhold 418d98b02e Change export name to igl-export
Former-commit-id: e098761e9a
2018-07-19 15:24:20 +02:00
Stefan Reinhold e8ca66fb7c Prefix CMake variables with LIBIGL_
Former-commit-id: a9645ac7e6
2018-07-19 15:22:02 +02:00
Stefan Reinhold 90ed035285 Change CMake commands to lowercase
Former-commit-id: a2a7169859
2018-07-19 15:20:32 +02:00
Stefan Reinhold 7f305a8532 Exclude embree module from installation
Former-commit-id: 0d0401454f
2018-07-19 14:46:26 +02:00
Stefan Reinhold 87d401b82b Install Eigen dependency in public location
Eigen shoudl not be installed in include/private/Eigen but in
include/Eigen instead so users can include the same Eigen version.


Former-commit-id: 1ec9614235
2018-07-19 13:36:39 +02:00
Stefan Reinhold dc1d3bb46c Make libigl installable using CMake
Installation is currently only supported for the core library. All
optional dependencies do not generate cmake exports, yet.
However, the commands required for installation were added but commented
out, so that as soon as an optional dependency adds cmake exports they
can be installed, too.


Former-commit-id: 28f815f866
2018-07-19 12:59:24 +02:00
vskhitkov da3bd928dd Replace return value by vector of indices of bad vertices
Former-commit-id: 0914f34a91
2018-06-21 19:21:35 +03:00
vskhitkov 86128972f6 Fixed my own fix
Former-commit-id: dca5f4e8a2
2018-06-21 17:07:10 +03:00
vskhitkov dfbc3ee1c1 bugfix: principal_curvature returns boolean instead of segfault
Former-commit-id: 8f6a4c4c07
2018-06-21 16:04:48 +03:00
Daniel Hambleton 576529d8d9 merged upstream
Former-commit-id: 2d9020d881
2018-06-19 13:52:37 -04:00
Alec Jacobson 792c814200 Update cut_to_disk.cpp
move headers to cpp

Former-commit-id: bfa6e9a716
2018-06-14 11:09:51 -04:00
Alec Jacobson 4a3ce8d896 Update cut_to_disk.h
move headers to cpp

Former-commit-id: 697195a764
2018-06-14 11:09:35 -04:00
Alec Jacobson dde2f93dd7 Update cut_to_disk.cpp
Former-commit-id: f077dea827
2018-06-14 11:08:55 -04:00
Alec Jacobson 83db1d2f19 Update cut_to_disk.h
Former-commit-id: 50e8037b31
2018-06-14 11:08:37 -04:00
Etienne Vouga 94dac679eb Code to cut meshes into topological disks
Former-commit-id: 808ffb637a
2018-06-13 19:56:42 -05:00
Alec Jacobson e2e4926241 Merge branch 'master' into obj_load_fix
Former-commit-id: 9b94c4100d
2018-03-19 22:29:44 -04:00
Breannan Smith 8571d5f3a2 Fix for a segfault when attempting to load a non-existant obj mesh through read_triangle_mesh.
Former-commit-id: c0e8e210f8
2017-10-01 21:11:35 -07:00
Like Ma 7c249cb5e2 add while loop for comb_cross_field.cpp, making comb support manifold that
is made up with several separated part


Former-commit-id: 247043cc71
2017-05-11 17:10:12 +08:00
318 changed files with 17057 additions and 88926 deletions
+4 -7
View File
@@ -5,9 +5,7 @@ clone_folder: C:\projects\libigl
branches:
only:
- master
- alecjacobson
- cmake
- cgal
- dev
environment:
BOOST_ROOT: C:/Libraries/boost_1_65_1
install:
@@ -31,11 +29,10 @@ build_script:
# - cd ../tutorial
# - ${PYTHON} 101_FileIO.py
# - cd ../../
# Tutorials
- cd tutorial
# Tutorials and tests
- mkdir build
- cd build
- cmake -DLIBIGL_USE_STATIC_LIBRARY=ON -G "Visual Studio 15 2017 Win64" ../
- cmake -DLIBIGL_BUILD_TESTS=OFF -DLIBIGL_BUILD_TUTORIALS=ON -DLIBIGL_BUILD_PYTHON=OFF -G "Visual Studio 15 2017 Win64" ../
- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
- set MSBuildOptions=/v:m /p:Configuration=Debug /logger:%MSBuildLogger%
- msbuild %MSBuildOptions% libigl_tutorials.sln
- msbuild %MSBuildOptions% libigl.sln
+8
View File
@@ -0,0 +1,8 @@
[Describe your issue]
#### Check all that apply (change to `[x]`)
- [ ] Windows
- [ ] Mac OS X
- [ ] Linux
See <https://libigl.github.io/CONTRIBUTING/#bugreport> for more tips.
+8
View File
@@ -0,0 +1,8 @@
[Describe your changes and what you've already done to test it.]
#### Check all that apply (change to `[x]`)
- [ ] All changes meet [libigl style-guidelines](https://libigl.github.io/style-guidelines/).
- [ ] Adds new .cpp file.
- [ ] Adds corresponding unit test.
- [ ] Adds corresponding python binding.
- [ ] This is a minor change.
+76 -87
View File
@@ -1,110 +1,99 @@
# use glob syntax.
syntax: glob
scripts/change_name.sh
*.a
*.dylib
*.egg-info/
*.exe
*.ilk
*.log
*.o
*.opensdf
*.orig
*.pdb
*.psess
*.pyc
*.sdf
*.so
*.so.[0123456789]
*.so.[0123456789].[0123456789]
*.o
*.a
*.dylib
*~
*CMakeFiles*
example
examples/bbw/bbw_demo_selfcontained/*
examples/bbw/bbw_demo_selfcontained.zip
examples/quicklook-mesh/Mesh.qlgenerator/*
examples/*/*.mexmaci64
examples/*/*.rbr
example_static
example_header_only
example1
external/yimg/.git*
external/tinyxml2/CMakeFiles*
external/tinyxml2/CMakeCache.txt
external/tinyxml2/cmake_install.cmake
external/tinyxml2/Makefile
external/embree/build/*
external/embree/bin/*
external/embree/bin
external/embree/doc/html/*
external/embree/doc/latex/*
external/gmp
external/mpfr
external/boost
external/.cache
external/build
.DS_Store
libigl.zip
*tags
*.exe
*.pdb
*.sdf
*.suo
*.ilk
*.log
*.swo
*.swp
*.tlog
Debug/
Release/
*.orig
*.user
*.vsp
*.opensdf
*.psess
*.swp
*.swo
documentation/*.aux
documentation/*.out
documentation/*.log
*CMakeFiles*
*buildXcode*
*tags
*~
.DS_Store
.idea/
.vs/
.vscode/
/external
Debug/
README.html
Release/
Untitled.ipynb
build
doc.html
documentation/*.aux
documentation/*.log
documentation/*.out
example
example1
example_header_only
example_static
examples/*/*.mexmaci64
examples/*/*.rbr
examples/bbw/bbw_demo
external/medit/rebar.rbr
examples/bbw/bbw_demo_selfcontained.zip
examples/bbw/bbw_demo_selfcontained/*
examples/bbw/examples/*-volume.dmat
examples/bbw/examples/*-volume.mesh
examples/upright/upright
examples/principal_curvature/curvature
examples/quicklook-mesh/Mesh.qlgenerator/*
examples/upright/upright
external/MeshFix/meshfix
external/embree/build/*
external/glew/build
external/glfw/build
external/libpng/build
external/medit/rebar.rbr
external/tetgen/tetgen
external/tinyxml2/build
external/tinyxml2/test
external/tinyxml2/tinyxml2.pc
external/yimg/showpng
README.html
tutorial/readme.html
tutorial/*/build/*
tutorial/*/Makefile
external/glew/build
external/glfw/build
*buildXcode*
tutorial/build*
tutorial/*/*.mexmaci64
external/libpng/build
external/tinyxml2/build
optional/build
iglhelpers.pyc
lib
libigl.zip
optional/build
python/.idea
python/.ipynb_checkpoints
python/__pycache__
python/build
python/build2
python/build3
python/build4
python/builddebug
python/buildstatic
python/py_igl/todo
python/py_igl/todo
python/scripts/generated
scripts/change_name.sh
site/
syntax: glob
tests/bin
tests/build
tests/data
tutorial/*/*.mexmaci64
tutorial/*/Makefile
tutorial/*/build/*
tutorial/.idea
tutorial/XXX_test/CMakeLists.txt
tutorial/XXX_test/main.cpp
python/py_igl/todo
python/build
python/.idea
untitled
Untitled.ipynb
python/.ipynb_checkpoints
python/py_igl/todo
python/__pycache__
iglhelpers.pyc
python/build2
tests/build
tests/bin
python/build3
*.pyc
python/build4
python/scripts/generated
python/builddebug
tutorial/.idea
python/buildstatic
tutorial/build
tutorial/cmake-build-debug
.vscode/
.idea/
site/
*.egg-info/
.vs/
tutorial/data
tutorial/readme.html
untitled
-33
View File
@@ -1,33 +0,0 @@
[submodule "external/embree"]
path = external/embree
url = https://github.com/embree/embree.git
[submodule "external/cgal"]
path = external/cgal
url = https://github.com/CGAL/cgal.git
[submodule "external/tetgen"]
path = external/tetgen
url = https://github.com/libigl/tetgen.git
[submodule "external/triangle"]
path = external/triangle
url = https://github.com/libigl/triangle.git
[submodule "external/tinyxml2"]
path = external/tinyxml2
url = https://github.com/leethomason/tinyxml2.git
[submodule "external/CoMISo"]
path = external/CoMISo
url = https://github.com/libigl/CoMISo.git
[submodule "external/cork"]
path = external/cork
url = https://github.com/libigl/cork.git
[submodule "external/imgui"]
path = external/imgui/imgui
url = https://github.com/ocornut/imgui.git
[submodule "external/glfw"]
path = external/glfw
url = https://github.com/glfw/glfw.git
[submodule "external/eigen"]
path = external/eigen
url = https://github.com/eigenteam/eigen-git-mirror.git
[submodule "external/pybind11"]
path = external/pybind11
url = https://github.com/pybind/pybind11
+5 -10
View File
@@ -57,17 +57,12 @@ install:
- ccache -V && ccache --show-stats && ccache --zero-stats
script:
# Python bindings
- cd python
- ${PYTHON} setup.py develop --user -- -DCMAKE_BUILD_TYPE=${CONFIG} -DLIBIGL_WITH_EMBREE=OFF -DLIBIGL_USE_STATIC_LIBRARY=ON -DCHECK_UNDEFINED=${CHECK_UNDEFINED}
- cd tutorial
- ${PYTHON} 101_FileIO.py
- cd ../../
- rm -rf python/build
# Tutorials
- cd tutorial
# Tutorials and tests
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=$CONFIG -DLIBIGL_USE_STATIC_LIBRARY=ON ../
- cmake -DCMAKE_BUILD_TYPE=$CONFIG -DLIBIGL_BUILD_TESTS=ON -DLIBIGL_BUILD_TUTORIALS=ON ../
- make -j 2
- ctest --verbose
- ccache --show-stats
- cd ../
- rm -rf build
+56
View File
@@ -0,0 +1,56 @@
cmake_minimum_required(VERSION 3.1)
project(libigl)
# Detects whether this is a top-level project
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(LIBIGL_TOPLEVEL_PROJECT ON)
else()
set(LIBIGL_TOPLEVEL_PROJECT OFF)
endif()
# Build tests, tutorials and python bindings
option(LIBIGL_BUILD_TESTS "Build libigl unit test" ${LIBIGL_TOPLEVEL_PROJECT})
option(LIBIGL_BUILD_TUTORIALS "Build libigl tutorial" ${LIBIGL_TOPLEVEL_PROJECT})
option(LIBIGL_BUILD_PYTHON "Build libigl python bindings" ${LIBIGL_TOPLEVEL_PROJECT})
# USE_STATIC_LIBRARY speeds up the generation of multiple binaries,
# at the cost of a longer initial compilation time
# (by default, static build is off since libigl is a header-only library)
option(LIBIGL_USE_STATIC_LIBRARY "Use LibIGL as static library" ON)
# All dependencies that are downloaded as cmake projects and tested on the auto-builds are ON
# (by default, all build options are off)
option(LIBIGL_WITH_COMISO "Use CoMiso" ON)
option(LIBIGL_WITH_EMBREE "Use Embree" ON)
option(LIBIGL_WITH_OPENGL "Use OpenGL" ON)
option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" ON)
option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" ON)
option(LIBIGL_WITH_PNG "Use PNG" ON)
option(LIBIGL_WITH_TETGEN "Use Tetgen" ON)
option(LIBIGL_WITH_TRIANGLE "Use Triangle" ON)
option(LIBIGL_WITH_XML "Use XML" ON)
option(LIBIGL_WITH_PYTHON "Use Python" ${LIBIGL_BUILD_PYTHON})
### End
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
### conditionally compile certain modules depending on libraries found on the system
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
### Adding libIGL: choose the path to your local copy libIGL
include(libigl)
if(LIBIGL_BUILD_TUTORIALS)
add_subdirectory(tutorial)
endif()
if(LIBIGL_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
if(LIBIGL_WITH_PYTHON)
add_subdirectory(python)
endif()
+2 -264
View File
@@ -1,268 +1,6 @@
# libigl - A simple C++ geometry processing library
[![Build Status](https://travis-ci.org/libigl/libigl.svg?branch=master)](https://travis-ci.org/libigl/libigl)
[![Build status](https://ci.appveyor.com/api/projects/status/mf3t9rnhco0vhly8/branch/master?svg=true)](https://ci.appveyor.com/project/danielepanozzo/libigl-6hjk1/branch/master)
![](https://github.com/libigl/libigl/raw/5ff6387765fa85ca46f1a6222728e35e2b8b8961/libigl-teaser.png)
![](https://github.com/libigl/libigl-legacy/raw/5ff6387765fa85ca46f1a6222728e35e2b8b8961/libigl-teaser.png)
<https://github.com/libigl/libigl/>
> Get started with:
>
```bash
git clone --recursive https://github.com/libigl/libigl.git
```
libigl is a simple C++ geometry processing library. We have a wide
functionality including construction of sparse discrete differential geometry
operators and finite-elements matrices such as the cotangent Laplacian and
diagonalized mass matrix, simple facet and edge-based topology data structures,
mesh-viewing utilities for OpenGL and GLSL, and many core functions for matrix
manipulation which make [Eigen](http://eigen.tuxfamily.org) feel a lot more
like MATLAB.
It is **a header-only library**. You do not need to compile anything to use,
just include igl headers (e.g. `#include <igl/cotmatrix.h>`) and run. Each
header file contains a single function (e.g. `igl/cotmatrix.h` contains
`igl::cotmatrix()`). Most are tailored to operate on a generic triangle mesh
stored in an n-by-3 matrix of vertex positions `V` and an m-by-3 matrix of
triangle indices `F`.
_Optionally_ the library may also be [pre-compiled](http://libigl.github.io/libigl/static-library/) into a statically
linked library, for faster compile times with your projects. This only effects
compile time (run-time performance and behavior is identical). If in doubt, use
the header-only default mode: (i.e. just include the headers you want to use).
We use the [Eigen](http://eigen.tuxfamily.org) library heavily in our code. Our
group prototypes a lot in MATLAB, and we have a useful [MATLAB to libigl+Eigen
conversion table](matlab-to-eigen.html).
We regularly test compiling our library on Mac OS X with clang, Linux with gcc
and Windows with Visual Studio 2015 Community Edition.
## Tutorial
As of version 1.0, libigl includes an introductory
[tutorial](http://libigl.github.io/libigl/tutorial) that covers many functionalities.
## libigl Example Project
We provide a [blank project example](https://github.com/libigl/libigl-example-project) showing how to use libigl and cmake. Feel free and encouraged to copy or fork this project as a way of starting a new personal project using libigl.
## Coding Guidelines and Tips
libigl follows strict coding guidelines, please take a look [here](http://libigl.github.io/libigl/style-guidelines) before submitting your pull requests. We also have a set of [general coding tips](http://libigl.github.io/libigl/coding-guidelines) on how to code a geometry processing research project.
## Installation
Libigl is a **header-only** library. You do **not** need to build anything to
install. Simply add `libigl/include` to your include path and include relevant
headers. Here is a small "Hello, World" program:
```cpp
#include <igl/cotmatrix.h>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <iostream>
int main()
{
Eigen::MatrixXd V(4,2);
V<<0,0,
1,0,
1,1,
0,1;
Eigen::MatrixXi F(2,3);
F<<0,1,2,
0,2,3;
Eigen::SparseMatrix<double> L;
igl::cotmatrix(V,F,L);
std::cout<<"Hello, mesh: "<<std::endl<<L*V<<std::endl;
return 0;
}
```
If you save this in `hello.cpp`, then you could compile this with (assuming
Eigen is installed in `/usr/local/include/eigen3`):
```bash
g++ -std=c++11 -I/usr/local/include/eigen3 -I./libigl/include/ hello.cpp -o hello
```
Running `./hello` would then produce
```
Hello, mesh:
0.5 0.5
-0.5 0.5
-0.5 -0.5
0.5 -0.5
```
## Dependencies
Dependencies are on a per-include basis and the majority of the functions in
libigl depends only on the [Eigen](http://eigen.tuxfamily.org) library.
For more information see our [tutorial](http://libigl.github.io/libigl/tutorial).
### Optional Dependencies
Libigl compartmentalizes its **optional** dependences via its directory
organization in the `include/` folder. All header files located _directly_ in
the `include/igl/` folder have only stl and Eigen as dependencies. For example,
all of the headers that depend on CGAL are located in `include/igl/copyleft/cgal`.
For a full list of _optional_ dependencies check `optional/CMakeLists.txt`.
### GCC and the Optional CGAL Dependency
The `include/igl/copyleft/cgal/*.h` headers depend on CGAL. It has come to
our attention that CGAL does not work properly with GCC 4.8. To the best of
our knowledge, GCC 4.7 and clang will work correctly.
### OpenMP and Windows
Some of our functions will take advantage of OpenMP if available. However, it
has come to our attention that Visual Studio + Eigen + OpenMP does not work
properly. Since we use OpenMP only to improve performance, we recommend
avoiding OpenMP on Windows or proceeding with caution.
## Download
You can keep up to date by cloning a read-only copy of our GitHub
[repository](https://github.com/libigl).
## Known Issues
We rely heavily on Eigen. Nearly all inputs and outputs are Eigen matrices of
some kind. However, we currently _only_ officially support Eigen's default
column-major ordering. That means, we **do not** expect our code to work for
matrices using the `Eigen::RowMajor` flag. If you can, change definitions like:
```cpp
Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::RowMajor> A;
```
to
```cpp
Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::ColMajor> A;
// or simply
Eigen::Matrix<double, Eigen::Dynamic, 3> A;
```
We hope to fix this, or at least identify which functions are safe (many of
them probably work just fine). This requires setting up unit testing, which is
a major _todo_ for our development.
## Git Submodules
Libigl uses git submodules for its _optional_ dependencies,
in particular, those needed by the OpenGL viewer to run the examples in the
[tutorial](http://libigl.github.io/libigl/tutorial). Git submodules allow use to treat clones of
other libraries as sub-directories within ours while separating our commits.
Read the [documentation](http://git-scm.com/docs/git-submodule) for a detailed
explanation, but essentially our libigl repo stores a hash for each of its
subrepos containing which version to update to. When a change is introduced in
a dependencies repo we can incorporate that change by pulling in our sub-repo
and updating (i.e. committing) that change to the hash.
When pulling new changes to libigl it's also a good idea to update changes to
subrepos:
```bash
git pull
git submodule update --recursive
```
## Unit Testing
Libigl maintains [separate
repository](https://github.com/libigl/libigl-unit-tests) for unit testing.
## How to Contribute
If you are interested in joining development, please fork the repository and
submit a [pull request](https://help.github.com/articles/using-pull-requests/)
with your changes. libigl follows strict coding guidelines, please take a look at our [style guidelines](http://libigl.github.io/libigl/style-guidelines) before submitting your pull requests.
## License
libigl is primarily [MPL2](http://www.mozilla.org/MPL/2.0/) licensed
([FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html)). Some files contain
third-party code under other licenses. We're currently in the processes of
identifying these and marking appropriately.
## Attribution
If you use libigl in your academic projects, please cite the papers we
implement as appropriate. To cite the library in general, you could use this
BibTeX entry:
```bibtex
@misc{libigl,
title = {{libigl}: A simple {C++} geometry processing library},
author = {Alec Jacobson and Daniele Panozzo and others},
note = {http://libigl.github.io/libigl/},
year = {2017},
}
```
## Projects/Universities using libigl
Libigl is used by many research groups around the world. In 2015, it won the
Eurographics/ACM Symposium on Geometry Processing software award. Here are a
few labs/companies/institutions using libigl:
- [Activision](http://www.activision.com)
- [Adobe Research](http://www.adobe.com/technology/)
- [Electronic Arts, Inc](http://www.ea.com)
- [Epic Games](https://epicgames.com)
- [Google Research](https://research.google.com)
- [Industrial Light and Magic](http://ilm.com)
- [Mesh consultants](http://meshconsultants.ca/), Canada
- [Microsoft Research](https://www.microsoft.com/en-us/research/)
- [Pixar](http://graphics.pixar.com/research/)
- [Spine by Esoteric Software](http://esotericsoftware.com/) is an animation tool dedicated to 2D characters.
- [vvvv toolkit](http://vvvv.org) a multipurpose tookit
- Columbia University, [Columbia Computer Graphics Group](http://www.cs.columbia.edu/cg/), USA
- [Cornell University](http://www.graphics.cornell.edu/), USA
- [Czech Technical University in Prague](http://dcgi.felk.cvut.cz/), Czech
- EPF Lausanne, [Computer Graphics and Geometry Laboratory](http://lgg.epfl.ch/people.php), Switzerland
- ETH Zurich, [Interactive Geometry Lab](http://igl.ethz.ch/) and [Advanced Technologies Lab](http://ait.inf.ethz.ch/), Swizterland
- George Mason University, [CraGL](http://cs.gmu.edu/~ygingold/), USA
- [Hong Kong University of Science and Technology](http://www.ust.hk/), Hong Kong
- [Inria, Université Grenoble Alpes](https://www.inria.fr/centre/grenoble/), France
- [Jiangnan university](http://english.jiangnan.edu.cn), China
- [National Institute of Informatics](http://www.nii.ac.jp/en/), Japan
- New York University, [Media Research Lab](http://mrl.nyu.edu/), USA
- NYUPoly, [Game Innovation Lab](http://game.engineering.nyu.edu/), USA
- [TU Berlin](https://www.cg.tu-berlin.de), Germany
- [TU Delft](http://www.tudelft.nl/en/), Netherlands
- [TU Wien](https://www.tuwien.ac.at/en/tuwien_home/), Austria
- [Telecom ParisTech](http://www.telecom-paristech.fr/en/formation-et-innovation-dans-le-numerique.html), Paris, France
- [UBISOFT](https://www.ubisoft.com/en-us/), USA
- [Utrecht University](http://www.staff.science.uu.nl/~vaxma001/), The Netherlands
- [Universidade Federal de Santa Catarina](http://mtm.ufsc.br/~leo/), Brazil
- [University College London](http://vecg.cs.ucl.ac.uk/), England
- [University of California Berkeley](http://vis.berkeley.edu/), USA
- [University of Cambridge](http://www.cam.ac.uk/), England
- [University of Pennsylvania](http://cg.cis.upenn.edu/), USA
- [University of Texas at Austin](http://www.cs.utexas.edu/users/evouga/), USA
- [University of Toronto](http://dgp.toronto.edu), Canada
- [University of Victoria](https://www.csc.uvic.ca/Research/graphics/), Canada
- [University of Wisconsin-Eau Claire](http://www.uwec.edu/computer-science/), USA
- [Università della Svizzera Italiana](http://www.usi.ch/en), Switzerland
- [Université Toulouse III Paul Sabatier](http://www.univ-tlse3.fr/), France
- [Zhejiang University](http://www.math.zju.edu.cn/cagd/), China
## Contact
Libigl is a group endeavor led by [Alec
Jacobson](http://www.cs.toronto.edu/~jacobson/) and [Daniele
Panozzo](http://cs.nyu.edu/~panozzo/). Please [contact
us](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com) if you have
questions or comments. For troubleshooting, please post an
[issue](https://github.com/libigl/libigl/issues) on github.
If you're using libigl in your projects, quickly [drop us a
note](mailto:alecjacobson@gmail.com,daniele.panozzo@gmail.com). Tell us who you
are and what you're using it for. This helps us apply for funding and justify
spending time maintaining this.
If you find bugs or have problems please use our [github issue tracking
page](https://github.com/libigl/libigl/issues).
## Copyright
2017 Alec Jacobson, Daniele Panozzo, Christian Schüller, Olga Diamanti, Qingnan Zhou, Sebastian Koch, Jeremie Dumas, Amir Vaxman, Nico Pietroni, Stefan Brugger, Kenshi Takayama, Wenzel Jakob, Nikolas De Giorgis, Luigi Rocca, Leonardo Sacht, Kevin Walliman, Olga Sorkine-Hornung, and others.
Please see individual files for appropriate copyright notices.
Documentation, tutorial, and instructions at <https://libigl.github.io>.
-6
View File
@@ -1,6 +0,0 @@
# This file should contain the current version number of libigl
# World.Major.Minor
# Anyone may increment Minor to indicate a small change.
# Major indicates a large change or large number of changes (upload to website)
# World indicates a substantial change or release
1.2.1
File diff suppressed because it is too large Load Diff
+175
View File
@@ -0,0 +1,175 @@
################################################################################
include(DownloadProject)
# With CMake 3.8 and above, we can hide warnings about git being in a
# detached head by passing an extra GIT_CONFIG option
if(NOT (${CMAKE_VERSION} VERSION_LESS "3.8.0"))
set(LIBIGL_EXTRA_OPTIONS "GIT_CONFIG advice.detachedHead=false")
else()
set(LIBIGL_EXTRA_OPTIONS "")
endif()
# Shortcut function
function(igl_download_project name)
download_project(
PROJ ${name}
SOURCE_DIR ${LIBIGL_EXTERNAL}/${name}
DOWNLOAD_DIR ${LIBIGL_EXTERNAL}/.cache/${name}
QUIET
${LIBIGL_EXTRA_OPTIONS}
${ARGN}
)
endfunction()
################################################################################
## CGAL
function(igl_download_cgal)
igl_download_project(cgal
GIT_REPOSITORY https://github.com/CGAL/cgal.git
GIT_TAG f7c3c8212b56c0d6dae63787efc99093f4383415
)
endfunction()
## CoMISo
function(igl_download_comiso)
igl_download_project(CoMISo
GIT_REPOSITORY https://github.com/libigl/CoMISo.git
GIT_TAG fea3ee0ba7d42ee3eca202d484e4fad855e4d6aa
)
endfunction()
## Cork
function(igl_download_cork)
igl_download_project(cork
GIT_REPOSITORY https://github.com/libigl/cork.git
GIT_TAG 27ad8a285838f5a480d856429e39d3d56d4338f9
)
endfunction()
## Eigen
function(igl_download_eigen)
igl_download_project(eigen
URL http://bitbucket.org/eigen/eigen/get/3.2.10.tar.gz
URL_MD5 8ad10ac703a78143a4062c9bda9d8fd3
)
endfunction()
## Embree
function(igl_download_embree)
igl_download_project(embree
URL https://github.com/embree/embree/archive/v2.17.4.tar.gz
URL_MD5 2038f3216b1d626e87453aee72c470e5
# GIT_REPOSITORY https://github.com/embree/embree.git
# GIT_TAG cb61322db3bb7082caed21913ad14869b436fe78
)
endfunction()
## glad
function(igl_download_glad)
igl_download_project(glad
GIT_REPOSITORY https://github.com/libigl/libigl-glad.git
GIT_TAG 71e35fe685a0cc160068a2f2f971c40b82d14af0
)
endfunction()
## GLFW
function(igl_download_glfw)
igl_download_project(glfw
GIT_REPOSITORY https://github.com/glfw/glfw.git
GIT_TAG 58cc4b2c5c2c9a245e09451437dd6f5af4d60c84
)
endfunction()
## ImGui
function(igl_download_imgui)
igl_download_project(imgui
GIT_REPOSITORY https://github.com/ocornut/imgui.git
GIT_TAG bc6ac8b2aee0614debd940e45bc9cd0d9b355c86
)
igl_download_project(libigl-imgui
GIT_REPOSITORY https://github.com/libigl/libigl-imgui.git
GIT_TAG a37e6e59e72fb07bd787dc7e90f72b9e1928dae7
)
endfunction()
## pybind11
function(igl_download_pybind11)
igl_download_project(pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11.git
GIT_TAG 2d0507db43cd5a117f7843e053b17dffca114107
)
endfunction()
## stb_image
function(igl_download_stb)
igl_download_project(stb
GIT_REPOSITORY https://github.com/libigl/libigl-stb.git
GIT_TAG e671ceb3def5e7029a23de14c55dc16301ad4dab
)
endfunction()
## TetGen
function(igl_download_tetgen)
igl_download_project(tetgen
GIT_REPOSITORY https://github.com/libigl/tetgen.git
GIT_TAG d2dcc33cb8551f16e302c8130ce12fa52992cd09
)
endfunction()
## TinyXML
function(igl_download_tinyxml2)
igl_download_project(tinyxml2
GIT_REPOSITORY https://github.com/leethomason/tinyxml2.git
GIT_TAG d175e9de0be0d4db75d0a8cf065599a435a87eb6
)
endfunction()
## Triangle
function(igl_download_triangle)
igl_download_project(triangle
GIT_REPOSITORY https://github.com/libigl/triangle.git
GIT_TAG d6761dd691e2e1318c83bf7773fea88d9437464a
)
endfunction()
## Google test
function(igl_download_googletest)
igl_download_project(googletest
GIT_REPOSITORY https://github.com/google/googletest
GIT_TAG release-1.8.1
)
endfunction()
################################################################################
## Test data
function(igl_download_test_data)
set(IGL_TEST_DATA ${LIBIGL_EXTERNAL}/../tests/data)
download_project(
PROJ test_data
SOURCE_DIR ${IGL_TEST_DATA}
DOWNLOAD_DIR ${LIBIGL_EXTERNAL}/.cache/test_data
QUIET
GIT_REPOSITORY https://github.com/libigl/libigl-tests-data
GIT_TAG c81bb3b3db4cfd78bac6d359d845c45bc1059c9a
${LIBIGL_EXTRA_OPTIONS}
)
endfunction()
## Tutorial data
function(igl_download_tutorial_data)
set(IGL_TUTORIAL_DATA ${LIBIGL_EXTERNAL}/../tutorial/data)
download_project(
PROJ tutorial_data
SOURCE_DIR ${IGL_TUTORIAL_DATA}
DOWNLOAD_DIR ${LIBIGL_EXTERNAL}/.cache/tutorial_data
QUIET
GIT_REPOSITORY https://github.com/libigl/libigl-tutorial-data
GIT_TAG 5c6a1ea809c043d71e5595775709c15325a7158c
${LIBIGL_EXTRA_OPTIONS}
)
endfunction()
+29
View File
@@ -0,0 +1,29 @@
@PACKAGE_INIT@
include(${CMAKE_CURRENT_LIST_DIR}/libigl-export.cmake)
if (TARGET igl::core)
if (NOT TARGET Eigen3::Eigen)
find_package(Eigen3 QUIET)
if (NOT Eigen3_FOUND)
# try with PkgCOnfig
find_package(PkgConfig REQUIRED)
pkg_check_modules(Eigen3 QUIET IMPORTED_TARGET eigen3)
endif()
if (NOT Eigen3_FOUND)
message(FATAL_ERROR "Could not find required dependency Eigen3")
set(libigl_core_FOUND FALSE)
else()
target_link_libraries(igl::core INTERFACE PkgConfig::Eigen3)
set(libigl_core_FOUND TRUE)
endif()
else()
target_link_libraries(igl::core INTERFACE Eigen3::Eigen)
set(libigl_core_FOUND TRUE)
endif()
endif()
check_required_components(libigl)
+146 -74
View File
@@ -11,48 +11,35 @@ if(APPLE)
message(STATUS "Found libtool - ${CMAKE_LIBTOOL}")
get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(lang ${languages})
# Added -c
# Added -c
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY
"${CMAKE_LIBTOOL} -c -static -o <TARGET> <LINK_FLAGS> <OBJECTS> ")
endforeach()
endif()
endif()
### Find packages to populate default options ###
#
# COMPONENTS should match subsequent calls
find_package(Matlab COMPONENTS MEX_COMPILER MX_LIBRARY ENG_LIBRARY) # --> Matlab_FOUND
find_package(MOSEK) # --> MOSEK_FOUND
find_package(OpenGL) # --> OPENGL_FOUND
### Available options ###
option(LIBIGL_USE_STATIC_LIBRARY "Use libigl as static library" ON)
option(LIBIGL_WITH_ANTTWEAKBAR "Use AntTweakBar" OFF)
option(LIBIGL_WITH_CGAL "Use CGAL" ON)
option(LIBIGL_WITH_COMISO "Use CoMiso" ON)
option(LIBIGL_WITH_CORK "Use Cork" OFF)
option(LIBIGL_WITH_EMBREE "Use Embree" OFF)
option(LIBIGL_WITH_LIM "Use LIM" ON)
option(LIBIGL_WITH_MATLAB "Use Matlab" "${Matlab_FOUND}")
option(LIBIGL_WITH_MOSEK "Use MOSEK" "${MOSEK_FOUND}")
option(LIBIGL_WITH_OPENGL "Use OpenGL" "${OPENGL_FOUND}")
option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" "${OPENGL_FOUND}")
option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" OFF)
option(LIBIGL_WITH_PNG "Use PNG" ON)
option(LIBIGL_WITH_TETGEN "Use Tetgen" ON)
option(LIBIGL_WITH_TRIANGLE "Use Triangle" ON)
option(LIBIGL_WITH_VIEWER "Use OpenGL viewer" "${OPENGL_FOUND}")
option(LIBIGL_WITH_XML "Use XML" ON)
option(LIBIGL_WITH_PYTHON "Use Python" OFF)
if(LIBIGL_WITH_VIEWER AND (NOT LIBIGL_WITH_OPENGL_GLFW OR NOT LIBIGL_WITH_OPENGL) )
message(FATAL_ERROR "LIBIGL_WITH_VIEWER=ON requires LIBIGL_WITH_OPENGL_GLFW=ON and LIBIGL_WITH_OPENGL=ON")
endif()
option(LIBIGL_USE_STATIC_LIBRARY "Use libigl as static library" OFF)
option(LIBIGL_WITH_CGAL "Use CGAL" OFF)
option(LIBIGL_WITH_COMISO "Use CoMiso" OFF)
option(LIBIGL_WITH_CORK "Use Cork" OFF)
option(LIBIGL_WITH_EMBREE "Use Embree" OFF)
option(LIBIGL_WITH_MATLAB "Use Matlab" OFF)
option(LIBIGL_WITH_MOSEK "Use MOSEK" OFF)
option(LIBIGL_WITH_OPENGL "Use OpenGL" OFF)
option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" OFF)
option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" OFF)
option(LIBIGL_WITH_PNG "Use PNG" OFF)
option(LIBIGL_WITH_TETGEN "Use Tetgen" OFF)
option(LIBIGL_WITH_TRIANGLE "Use Triangle" OFF)
option(LIBIGL_WITH_XML "Use XML" OFF)
option(LIBIGL_WITH_PYTHON "Use Python" OFF)
option(LIBIGL_WITHOUT_COPYLEFT "Disable Copyleft libraries" OFF)
################################################################################
### Configuration
set(LIBIGL_ROOT "${CMAKE_CURRENT_LIST_DIR}/../..")
set(LIBIGL_ROOT "${CMAKE_CURRENT_LIST_DIR}/..")
set(LIBIGL_SOURCE_DIR "${LIBIGL_ROOT}/include")
set(LIBIGL_EXTERNAL "${LIBIGL_ROOT}/external")
@@ -63,12 +50,21 @@ else()
set(IGL_SCOPE INTERFACE)
endif()
# Download and update 3rdparty libraries
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
include(LibiglDownloadExternal)
################################################################################
### IGL Common
################################################################################
add_library(igl_common INTERFACE)
target_include_directories(igl_common SYSTEM INTERFACE ${LIBIGL_SOURCE_DIR})
target_include_directories(igl_common SYSTEM INTERFACE
$<BUILD_INTERFACE:${LIBIGL_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
# Export igl_common as igl::common
set_property(TARGET igl_common PROPERTY EXPORT_NAME igl::common)
if(LIBIGL_USE_STATIC_LIBRARY)
target_compile_definitions(igl_common INTERFACE -DIGL_STATIC_LIBRARY)
endif()
@@ -81,6 +77,9 @@ target_compile_features(igl_common INTERFACE ${CXX11_FEATURES})
if(MSVC)
# Enable parallel compilation for Visual Studio
target_compile_options(igl_common INTERFACE /MP /bigobj)
if(LIBIGL_WITH_CGAL)
target_compile_options(igl_common INTERFACE "/MD$<$<CONFIG:Debug>:d>")
endif()
endif()
if(BUILD_SHARED_LIBS)
@@ -88,12 +87,21 @@ if(BUILD_SHARED_LIBS)
set_target_properties(igl_common PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE ON)
endif()
if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
endif()
# Eigen
if(TARGET Eigen3::Eigen)
# If an imported target already exists, use it
target_link_libraries(igl_common INTERFACE Eigen3::Eigen)
else()
target_include_directories(igl_common SYSTEM INTERFACE ${LIBIGL_EXTERNAL}/eigen)
igl_download_eigen()
target_include_directories(igl_common SYSTEM INTERFACE
$<BUILD_INTERFACE:${LIBIGL_EXTERNAL}/eigen>
$<INSTALL_INTERFACE:include>
)
endif()
# C++11 Thread library
@@ -102,20 +110,6 @@ target_link_libraries(igl_common INTERFACE ${CMAKE_THREAD_LIBS_INIT})
################################################################################
include(DownloadProject)
# Shortcut function
function(igl_download_project name)
download_project(
PROJ ${name}
SOURCE_DIR ${LIBIGL_EXTERNAL}/${name}
DOWNLOAD_DIR ${LIBIGL_EXTERNAL}/.cache/${name}
${ARGN}
)
endfunction()
################################################################################
## CGAL dependencies on Windows: GMP & MPFR
function(igl_download_cgal_deps)
if(WIN32)
@@ -143,8 +137,12 @@ function(compile_igl_module module_dir)
endif()
if(LIBIGL_USE_STATIC_LIBRARY)
file(GLOB SOURCES_IGL_${module_name}
"${LIBIGL_SOURCE_DIR}/igl/${module_dir}/*.cpp"
"${LIBIGL_SOURCE_DIR}/igl/copyleft/${module_dir}/*.cpp")
"${LIBIGL_SOURCE_DIR}/igl/${module_dir}/*.cpp")
if(NOT LIBIGL_WITHOUT_COPYLEFT)
file(GLOB COPYLEFT_SOURCES_IGL_${module_name}
"${LIBIGL_SOURCE_DIR}/igl/copyleft/${module_dir}/*.cpp")
list(APPEND SOURCES_IGL_${module_name} ${COPYLEFT_SOURCES_IGL_${module_name}})
endif()
add_library(${module_libname} STATIC ${SOURCES_IGL_${module_name}} ${ARGN})
if(MSVC)
target_compile_options(${module_libname} PRIVATE /w) # disable all warnings (not ideal but...)
@@ -163,6 +161,8 @@ function(compile_igl_module module_dir)
# Alias target because it looks nicer
message(STATUS "Creating target: igl::${module_name} (${module_libname})")
add_library(igl::${module_name} ALIAS ${module_libname})
# Export as igl::${module_name}
set_property(TARGET ${module_libname} PROPERTY EXPORT_NAME igl::${module_name})
endfunction()
################################################################################
@@ -177,15 +177,9 @@ endif()
compile_igl_module("core" ${SOURCES_IGL})
################################################################################
## Compile the AntTweakBar part ###
if(LIBIGL_WITH_ANTTWEAKBAR)
set(ANTTWEAKBAR_DIR "${LIBIGL_EXTERNAL}/AntTweakBar")
if(NOT TARGET AntTweakBar)
add_subdirectory("${ANTTWEAKBAR_DIR}" AntTweakBar)
endif()
compile_igl_module("anttweakbar")
target_link_libraries(igl_anttweakbar ${IGL_SCOPE} AntTweakBar)
target_include_directories(igl_anttweakbar ${IGL_SCOPE} "${ANTTWEAKBAR_DIR}/include")
### Download the python part ###
if(LIBIGL_WITH_PYTHON)
igl_download_pybind11()
endif()
################################################################################
@@ -196,11 +190,12 @@ if(LIBIGL_WITH_CGAL)
# `Exact_predicates_exact_constructions_kernel_with_sqrt`
if(NOT TARGET CGAL::CGAL)
set(CGAL_DIR "${LIBIGL_EXTERNAL}/cgal")
igl_download_cgal()
igl_download_cgal_deps()
if(EXISTS ${LIBIGL_EXTERNAL}/boost)
set(BOOST_ROOT "${LIBIGL_EXTERNAL}/boost")
endif()
set(CGAL_Boost_USE_STATIC_LIBS ON CACHE BOOL "" FORCE)
option(CGAL_Boost_USE_STATIC_LIBS "Use static Boost libs with CGAL" ON)
find_package(CGAL CONFIG COMPONENTS Core PATHS ${CGAL_DIR} NO_DEFAULT_PATH)
endif()
@@ -242,6 +237,7 @@ endfunction()
if(LIBIGL_WITH_COMISO)
compile_igl_module("comiso")
if(NOT TARGET CoMISo)
igl_download_comiso()
add_subdirectory("${LIBIGL_EXTERNAL}/CoMISo" CoMISo)
endif()
target_link_libraries(igl_comiso ${IGL_SCOPE} CoMISo)
@@ -254,6 +250,7 @@ if(LIBIGL_WITH_CORK)
if(NOT TARGET cork)
# call this "lib-cork" instead of "cork", otherwise cmake gets confused about
# "cork" executable
igl_download_cork()
add_subdirectory("${CORK_DIR}" "lib-cork")
endif()
compile_igl_module("cork")
@@ -282,6 +279,7 @@ if(LIBIGL_WITH_EMBREE)
endif()
if(NOT TARGET embree)
igl_download_embree()
add_subdirectory("${EMBREE_DIR}" "embree")
endif()
@@ -301,18 +299,6 @@ if(LIBIGL_WITH_EMBREE)
endif()
endif()
################################################################################
### Compile the lim part ###
if(LIBIGL_WITH_LIM)
set(LIM_DIR "${LIBIGL_EXTERNAL}/lim")
if(NOT TARGET lim)
add_subdirectory("${LIM_DIR}" "lim")
endif()
compile_igl_module("lim")
target_link_libraries(igl_lim ${IGL_SCOPE} lim)
target_include_directories(igl_lim ${IGL_SCOPE} ${LIM_DIR})
endif()
################################################################################
### Compile the matlab part ###
if(LIBIGL_WITH_MATLAB)
@@ -343,6 +329,7 @@ if(LIBIGL_WITH_OPENGL)
# glad module
if(NOT TARGET glad)
igl_download_glad()
add_subdirectory(${LIBIGL_EXTERNAL}/glad glad)
endif()
target_link_libraries(igl_opengl ${IGL_SCOPE} glad)
@@ -359,6 +346,7 @@ if(LIBIGL_WITH_OPENGL_GLFW)
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()
add_subdirectory(${LIBIGL_EXTERNAL}/glfw glfw)
endif()
target_link_libraries(igl_opengl_glfw ${IGL_SCOPE} igl_opengl glfw)
@@ -372,7 +360,8 @@ if(LIBIGL_WITH_OPENGL_GLFW_IMGUI)
# ImGui module
compile_igl_module("opengl/glfw/imgui")
if(NOT TARGET imgui)
add_subdirectory(${LIBIGL_EXTERNAL}/imgui 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)
endif()
@@ -384,9 +373,9 @@ if(LIBIGL_WITH_PNG)
# png/ module is anomalous because it also depends on opengl it really should
# be moved into the opengl/ directory and namespace ...
if(TARGET igl_opengl)
set(STB_IMAGE_DIR "${LIBIGL_EXTERNAL}/stb_image")
if(NOT TARGET stb_image)
add_subdirectory("${STB_IMAGE_DIR}" "stb_image")
igl_download_stb()
add_subdirectory(${LIBIGL_EXTERNAL}/stb stb_image)
endif()
compile_igl_module("png" "")
target_link_libraries(igl_png ${IGL_SCOPE} igl_stb_image igl_opengl)
@@ -398,6 +387,7 @@ endif()
if(LIBIGL_WITH_TETGEN)
set(TETGEN_DIR "${LIBIGL_EXTERNAL}/tetgen")
if(NOT TARGET tetgen)
igl_download_tetgen()
add_subdirectory("${TETGEN_DIR}" "tetgen")
endif()
compile_igl_module("tetgen")
@@ -410,6 +400,7 @@ endif()
if(LIBIGL_WITH_TRIANGLE)
set(TRIANGLE_DIR "${LIBIGL_EXTERNAL}/triangle")
if(NOT TARGET triangle)
igl_download_triangle()
add_subdirectory("${TRIANGLE_DIR}" "triangle")
endif()
compile_igl_module("triangle")
@@ -422,7 +413,9 @@ endif()
if(LIBIGL_WITH_XML)
set(TINYXML2_DIR "${LIBIGL_EXTERNAL}/tinyxml2")
if(NOT TARGET tinyxml2)
igl_download_tinyxml2()
add_library(tinyxml2 STATIC ${TINYXML2_DIR}/tinyxml2.cpp ${TINYXML2_DIR}/tinyxml2.h)
target_include_directories(tinyxml2 PUBLIC ${TINYXML2_DIR})
set_target_properties(tinyxml2 PROPERTIES
COMPILE_DEFINITIONS "TINYXML2_EXPORT"
VERSION "3.0.0"
@@ -432,3 +425,82 @@ if(LIBIGL_WITH_XML)
target_link_libraries(igl_xml ${IGL_SCOPE} tinyxml2)
target_include_directories(igl_xml ${IGL_SCOPE} ${TINYXML2_DIR})
endif()
################################################################################
### Install and export all modules
function(install_dir_files dir_name)
if (dir_name STREQUAL "core")
set(subpath "")
else()
set(subpath "/${dir_name}")
endif()
file(GLOB public_headers
${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.h
)
set(files_to_install ${public_headers})
if(NOT LIBIGL_USE_STATIC_LIBRARY)
file(GLOB public_sources
${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.cpp
)
endif()
list(APPEND files_to_install ${public_sources})
install(
FILES ${files_to_install}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/igl${subpath}
)
endfunction()
################################################################################
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
# Install and export core library
install(
TARGETS
igl
igl_common
EXPORT igl-export
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
export(
TARGETS
igl
igl_common
FILE libigl-export.cmake
)
# Install headers for core library
install_dir_files(core)
install_dir_files(copyleft)
# Write package configuration file
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/libigl-config.cmake.in
${CMAKE_BINARY_DIR}/libigl-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/libigl/cmake
)
install(
FILES
${CMAKE_BINARY_DIR}/libigl-config.cmake
DESTINATION
${CMAKE_INSTALL_DATADIR}/libigl/cmake
)
# Write export file
export(EXPORT igl-export
FILE "${CMAKE_BINARY_DIR}/libigl-export.cmake"
)
install(EXPORT igl-export DESTINATION ${CMAKE_INSTALL_DATADIR}/libigl/cmake FILE libigl-export.cmake)
export(PACKAGE libigl)
+26
View File
@@ -0,0 +1,26 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2018 Zhongshi Jiang <jiangzs@nyu.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_MAPPINGENERGYTYPE_H
#define IGL_MAPPINGENERGYTYPE_H
namespace igl
{
// Energy Types used for Parameterization/Mapping.
// Refer to SLIM [Rabinovich et al. 2017] for more details
// Todo: Integrate with ARAPEnergyType
enum MappingEnergyType
{
ARAP,
LOG_ARAP,
SYMMETRIC_DIRICHLET,
CONFORMAL,
EXP_CONFORMAL,
EXP_SYMMETRIC_DIRICHLET
};
}
#endif
File diff suppressed because it is too large Load Diff
@@ -1 +0,0 @@
e8898a8aa8e920ab7c2cd0bfaac5acc2e4991daf
+1
View File
@@ -165,4 +165,5 @@ template void igl::adjacency_list<Eigen::Matrix<int, -1, 2, 0, -1, 2>, int>(Eige
// generated by autoexplicit.sh
template void igl::adjacency_list<Eigen::Matrix<int, -1, -1, 0, -1, -1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, bool);
template void igl::adjacency_list<Eigen::Matrix<int, -1, 3, 0, -1, 3>, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, bool);
template void igl::adjacency_list<class Eigen::Matrix<int, -1, -1, 0, -1, -1>, unsigned int>(class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > const &, class std::vector<class std::vector<unsigned int, class std::allocator<unsigned int> >, class std::allocator<class std::vector<unsigned int, class std::allocator<unsigned int> > > > &, bool);
#endif
+6 -5
View File
@@ -1,9 +1,9 @@
// 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
//
// 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 "adjacency_matrix.h"
@@ -13,7 +13,7 @@
template <typename DerivedF, typename T>
IGL_INLINE void igl::adjacency_matrix(
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedF> & F,
Eigen::SparseMatrix<T>& A)
{
using namespace std;
@@ -71,4 +71,5 @@ IGL_INLINE void igl::adjacency_matrix(
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>&);
template void igl::adjacency_matrix<Eigen::Matrix<int, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<int, 0, int>&);
template void igl::adjacency_matrix<Eigen::Matrix<int, -1, 3, 0, -1, 3>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::SparseMatrix<int, 0, int>&);
#endif
-934
View File
@@ -1,934 +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 "ReAntTweakBar.h"
#include <cstdio>
#include <cstring>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <map>
// GLOBAL WRAPPERS
namespace
{
std::map<
TwType,std::pair<const char *,std::vector<TwEnumVal> >
> ReTw_custom_types;
}
IGL_INLINE TwType igl::anttweakbar::ReTwDefineEnum(
const char *name,
const TwEnumVal *enumValues,
unsigned int nbValues)
{
using namespace std;
// copy enum valus into vector
std::vector<TwEnumVal> enum_vals;
enum_vals.resize(nbValues);
for(unsigned int j = 0; j<nbValues;j++)
{
enum_vals[j] = enumValues[j];
}
TwType type = TwDefineEnum(name,enumValues,nbValues);
ReTw_custom_types[type] =
std::pair<const char *,std::vector<TwEnumVal> >(name,enum_vals);
return type;
}
IGL_INLINE TwType igl::anttweakbar::ReTwDefineEnumFromString(
const char * _Name,
const char * _EnumString)
{
// Taken directly from TwMgr.cpp, just replace TwDefineEnum with
// ReTwDefineEnum
using namespace std;
{
if (_EnumString == NULL)
return ReTwDefineEnum(_Name, NULL, 0);
// split enumString
stringstream EnumStream(_EnumString);
string Label;
vector<string> Labels;
while( getline(EnumStream, Label, ',') ) {
// trim Label
size_t Start = Label.find_first_not_of(" \n\r\t");
size_t End = Label.find_last_not_of(" \n\r\t");
if( Start==string::npos || End==string::npos )
Label = "";
else
Label = Label.substr(Start, (End-Start)+1);
// store Label
Labels.push_back(Label);
}
// create TwEnumVal array
vector<TwEnumVal> Vals(Labels.size());
for( int i=0; i<(int)Labels.size(); i++ )
{
Vals[i].Value = i;
// Wrong:
//Vals[i].Label = Labels[i].c_str();
// Allocate char on heap
// http://stackoverflow.com/a/10050258/148668
char * c_label = new char[Labels[i].length()+1];
std::strcpy(c_label, Labels[i].c_str());
Vals[i].Label = c_label;
}
const TwType type =
ReTwDefineEnum(_Name, Vals.empty() ?
NULL :
&(Vals[0]), (unsigned int)Vals.size());
return type;
}
}
namespace
{
struct ReTwTypeString
{
TwType type;
const char * type_str;
};
#define RETW_NUM_DEFAULT_TYPE_STRINGS 23
ReTwTypeString ReTwDefaultTypeStrings[RETW_NUM_DEFAULT_TYPE_STRINGS] =
{
{TW_TYPE_UNDEF,"TW_TYPE_UNDEF"},
{TW_TYPE_BOOLCPP,"TW_TYPE_BOOLCPP"},
{TW_TYPE_BOOL8,"TW_TYPE_BOOL8"},
{TW_TYPE_BOOL16,"TW_TYPE_BOOL16"},
{TW_TYPE_BOOL32,"TW_TYPE_BOOL32"},
{TW_TYPE_CHAR,"TW_TYPE_CHAR"},
{TW_TYPE_INT8,"TW_TYPE_INT8"},
{TW_TYPE_UINT8,"TW_TYPE_UINT8"},
{TW_TYPE_INT16,"TW_TYPE_INT16"},
{TW_TYPE_UINT16,"TW_TYPE_UINT16"},
{TW_TYPE_INT32,"TW_TYPE_INT32"},
{TW_TYPE_UINT32,"TW_TYPE_UINT32"},
{TW_TYPE_FLOAT,"TW_TYPE_FLOAT"},
{TW_TYPE_DOUBLE,"TW_TYPE_DOUBLE"},
{TW_TYPE_COLOR32,"TW_TYPE_COLOR32"},
{TW_TYPE_COLOR3F,"TW_TYPE_COLOR3F"},
{TW_TYPE_COLOR4F,"TW_TYPE_COLOR4F"},
{TW_TYPE_CDSTRING,"TW_TYPE_CDSTRING"},
{TW_TYPE_STDSTRING,"TW_TYPE_STDSTRING"},
{TW_TYPE_QUAT4F,"TW_TYPE_QUAT4F"},
{TW_TYPE_QUAT4D,"TW_TYPE_QUAT4D"},
{TW_TYPE_DIR3F,"TW_TYPE_DIR3F"},
{TW_TYPE_DIR3D,"TW_TYPE_DIR3D"}
};
}
IGL_INLINE igl::anttweakbar::ReTwBar::ReTwBar():
bar(NULL),
name(),
rw_items(),cb_items()
{
}
IGL_INLINE igl::anttweakbar::ReTwBar::ReTwBar(
const igl::anttweakbar::ReTwBar & that):
bar(that.bar),
name(that.name),
rw_items(that.rw_items),
cb_items(that.cb_items)
{
}
IGL_INLINE igl::anttweakbar::ReTwBar &
igl::anttweakbar::ReTwBar::operator=(const igl::anttweakbar::ReTwBar & that)
{
// check for self assignment
if(this != &that)
{
bar = that.bar;
rw_items = that.rw_items;
cb_items = that.cb_items;
}
return *this;
}
// BAR WRAPPERS
IGL_INLINE void igl::anttweakbar::ReTwBar::TwNewBar(const char * _name)
{
this->bar = ::TwNewBar(_name);
// Alec: This causes trouble (not sure why) in multiple applications
// (medit, puppet) Probably there is some sort of memory corrpution.
// this->name = _name;
// Suspiciously this also fails:
//this->name = "foobar";
}
IGL_INLINE int igl::anttweakbar::ReTwBar::TwAddVarRW(
const char *name,
TwType type,
void *var,
const char *def,
const bool record)
{
int ret = ::TwAddVarRW(this->bar,name,type,var,def);
if(ret && record)
{
rw_items.push_back(ReTwRWItem(name,type,var));
}
return ret;
}
IGL_INLINE int igl::anttweakbar::ReTwBar::TwAddVarCB(
const char *name,
TwType type,
TwSetVarCallback setCallback,
TwGetVarCallback getCallback,
void *clientData,
const char *def,
const bool record)
{
int ret =
::TwAddVarCB(this->bar,name,type,setCallback,getCallback,clientData,def);
if(ret && record)
{
cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
}
return ret;
}
IGL_INLINE int igl::anttweakbar::ReTwBar::TwAddVarRO(
const char *name,
TwType type,
void *var,
const char *def)
{
int ret = ::TwAddVarRO(this->bar,name,type,var,def);
// Read only variables are not recorded
//if(ret)
//{
// rw_items.push_back(ReTwRWItem(name,type,var));
//}
return ret;
}
IGL_INLINE int igl::anttweakbar::ReTwBar::TwAddButton(
const char *name,
TwButtonCallback buttonCallback,
void *clientData,
const char *def)
{
int ret =
::TwAddButton(this->bar,name,buttonCallback,clientData,def);
// buttons are not recorded
//if(ret)
//{
// cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
//}
return ret;
}
IGL_INLINE int igl::anttweakbar::ReTwBar::TwSetParam(
const char *varName,
const char *paramName,
TwParamValueType paramValueType,
unsigned int inValueCount,
const void *inValues)
{
// For now just pass these along
return
::TwSetParam(
this->bar,
varName,
paramName,
paramValueType,
inValueCount,
inValues);
}
IGL_INLINE int igl::anttweakbar::ReTwBar::TwGetParam(
const char *varName,
const char *paramName,
TwParamValueType paramValueType,
unsigned int outValueMaxCount,
void *outValues)
{
return
::TwGetParam(
this->bar,
varName,
paramName,
paramValueType,
outValueMaxCount,
outValues);
}
IGL_INLINE int igl::anttweakbar::ReTwBar::TwRefreshBar()
{
return ::TwRefreshBar(this->bar);
}
IGL_INLINE int igl::anttweakbar::ReTwBar::TwTerminate()
{
//std::cout<<"TwTerminate"<<std::endl;
int r = ::TwTerminate();
//std::cout<<" "<<r<<std::endl;
return r;
}
IGL_INLINE bool igl::anttweakbar::ReTwBar::save(const char *file_name)
{
FILE * fp;
if(file_name == NULL)
{
fp = stdout;
}else
{
fp = fopen(file_name,"w");
}
if(fp == NULL)
{
printf("ERROR: not able to open %s for writing...\n",file_name);
return false;
}
// Print all RW variables
for(
std::vector<ReTwRWItem>::iterator it = rw_items.begin();
it != rw_items.end();
it++)
{
std::string s = (*it).name;
const char * name = s.c_str();
TwType type = (*it).type;
void * var = (*it).var;
fprintf(fp,"%s: %s\n",
name,
get_value_as_string(var,type).c_str());
}
char var[REANTTWEAKBAR_MAX_CB_VAR_SIZE];
// Print all CB variables
for(
std::vector<ReTwCBItem>::iterator it = cb_items.begin();
it != cb_items.end();
it++)
{
const char * name = it->name.c_str();
TwType type = it->type;
//TwSetVarCallback setCallback = it->setCallback;
TwGetVarCallback getCallback = it->getCallback;
void * clientData = it->clientData;
// I'm not sure how to do what I want to do. getCallback needs to be sure
// that it can write to var. So var needs to point to a valid and big
// enough chunk of memory
getCallback(var,clientData);
fprintf(fp,"%s: %s\n",
name,
get_value_as_string(var,type).c_str());
}
fprintf(fp,"\n");
if(file_name != NULL)
{
fclose(fp);
}
// everything succeeded
return true;
}
IGL_INLINE std::string igl::anttweakbar::ReTwBar::get_value_as_string(
void * var,
TwType type)
{
std::stringstream sstr;
switch(type)
{
case TW_TYPE_BOOLCPP:
{
sstr << "TW_TYPE_BOOLCPP" << " ";
sstr << *(static_cast<bool*>(var));
break;
}
case TW_TYPE_QUAT4D:
{
sstr << "TW_TYPE_QUAT4D" << " ";
// Q: Why does casting to double* work? shouldn't I have to cast to
// double**?
double * q = static_cast<double*>(var);
sstr << std::setprecision(15) << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
break;
}
case TW_TYPE_QUAT4F:
{
sstr << "TW_TYPE_QUAT4F" << " ";
// Q: Why does casting to float* work? shouldn't I have to cast to
// float**?
float * q = static_cast<float*>(var);
sstr << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
break;
}
case TW_TYPE_COLOR4F:
{
sstr << "TW_TYPE_COLOR4F" << " ";
float * c = static_cast<float*>(var);
sstr << c[0] << " " << c[1] << " " << c[2] << " " << c[3];
break;
}
case TW_TYPE_COLOR3F:
{
sstr << "TW_TYPE_COLOR3F" << " ";
float * c = static_cast<float*>(var);
sstr << c[0] << " " << c[1] << " " << c[2];
break;
}
case TW_TYPE_DIR3D:
{
sstr << "TW_TYPE_DIR3D" << " ";
double * d = static_cast<double*>(var);
sstr << std::setprecision(15) << d[0] << " " << d[1] << " " << d[2];
break;
}
case TW_TYPE_DIR3F:
{
sstr << "TW_TYPE_DIR3F" << " ";
float * d = static_cast<float*>(var);
sstr << d[0] << " " << d[1] << " " << d[2];
break;
}
case TW_TYPE_BOOL32:
{
sstr << "TW_TYPE_BOOL32" << " ";
sstr << *(static_cast<int*>(var));
break;
}
case TW_TYPE_UINT8:
{
sstr << "TW_TYPE_UINT8" << " ";
// Cast to int so that it's human readable
sstr << (int)*(static_cast<unsigned char*>(var));
break;
}
case TW_TYPE_INT32:
{
sstr << "TW_TYPE_INT32" << " ";
sstr << *(static_cast<int*>(var));
break;
}
case TW_TYPE_UINT32:
{
sstr << "TW_TYPE_UINT32" << " ";
sstr << *(static_cast<unsigned int*>(var));
break;
}
case TW_TYPE_FLOAT:
{
sstr << "TW_TYPE_FLOAT" << " ";
sstr << *(static_cast<float*>(var));
break;
}
case TW_TYPE_DOUBLE:
{
sstr << "TW_TYPE_DOUBLE" << " ";
sstr << std::setprecision(15) << *(static_cast<double*>(var));
break;
}
case TW_TYPE_STDSTRING:
{
sstr << "TW_TYPE_STDSTRING" << " ";
std::string *destPtr = static_cast<std::string *>(var);
sstr << destPtr->c_str();
break;
}
default:
{
using namespace std;
std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::const_iterator iter =
ReTw_custom_types.find(type);
if(iter != ReTw_custom_types.end())
{
sstr << (*iter).second.first << " ";
int enum_val = *(static_cast<int*>(var));
// try find display name for enum value
std::vector<TwEnumVal>::const_iterator eit = (*iter).second.second.begin();
bool found = false;
for(;eit<(*iter).second.second.end();eit++)
{
if(enum_val == eit->Value)
{
sstr << eit->Label;
found = true;
break;
}
}
if(!found)
{
sstr << "ERROR_ENUM_VALUE_NOT_DEFINED";
}
}else
{
sstr << "ERROR_TYPE_NOT_SUPPORTED";
}
break;
}
}
return sstr.str();
}
IGL_INLINE bool igl::anttweakbar::ReTwBar::load(const char *file_name)
{
FILE * fp;
fp = fopen(file_name,"r");
if(fp == NULL)
{
printf("ERROR: not able to open %s for reading...\n",file_name);
return false;
}
// go through file line by line
char line[REANTTWEAKBAR_MAX_LINE];
bool still_comments;
char name[REANTTWEAKBAR_MAX_WORD];
char type_str[REANTTWEAKBAR_MAX_WORD];
char value_str[REANTTWEAKBAR_MAX_WORD];
// line number
int j = 0;
bool finished = false;
while(true)
{
// Eat comments
still_comments = true;
while(still_comments)
{
if(fgets(line,REANTTWEAKBAR_MAX_LINE,fp) == NULL)
{
finished = true;
break;
}
// Blank lines and lines that begin with # are comments
still_comments = (line[0] == '#' || line[0] == '\n');
j++;
}
if(finished)
{
break;
}
sscanf(line,"%[^:]: %s %[^\n]",name,type_str,value_str);
//printf("%s: %s %s\n",name, type_str,value_str);
TwType type;
if(!type_from_string(type_str,type))
{
printf("ERROR: %s type not found... Skipping...\n",type_str);
continue;
}
set_value_from_string(name,type,value_str);
}
fclose(fp);
// everything succeeded
return true;
}
IGL_INLINE bool igl::anttweakbar::ReTwBar::type_from_string(
const char *type_str, TwType & type)
{
// first check default types
for(int j = 0; j < RETW_NUM_DEFAULT_TYPE_STRINGS; j++)
{
if(strcmp(type_str,ReTwDefaultTypeStrings[j].type_str) == 0)
{
type = ReTwDefaultTypeStrings[j].type;
return true;
break;
}
}
// then check custom types
std::map<
TwType,std::pair<const char *,std::vector<TwEnumVal> >
>::const_iterator iter =
ReTw_custom_types.begin();
for(;iter != ReTw_custom_types.end(); iter++)
{
if(strcmp((*iter).second.first,type_str)==0)
{
type = (*iter).first;
return true;
}
}
return false;
}
bool igl::anttweakbar::ReTwBar::set_value_from_string(
const char * name,
TwType type,
const char * value_str)
{
void * value = NULL;
// possible value slots
int i;
float v;
double dv;
float f[4];
double d[4];
bool b;
unsigned int u;
unsigned char uc;
std::string s;
// First try to get value from default types
switch(type)
{
case TW_TYPE_BOOLCPP:
{
int ib;
if(sscanf(value_str," %d",&ib) == 1)
{
b = ib!=0;
value = &b;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
case TW_TYPE_QUAT4D:
//case TW_TYPE_COLOR4D:
{
if(sscanf(value_str," %lf %lf %lf %lf",&d[0],&d[1],&d[2],&d[3]) == 4)
{
value = &d;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
case TW_TYPE_QUAT4F:
case TW_TYPE_COLOR4F:
{
if(sscanf(value_str," %f %f %f %f",&f[0],&f[1],&f[2],&f[3]) == 4)
{
value = &f;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
//case TW_TYPE_COLOR3D:
case TW_TYPE_DIR3D:
{
if(sscanf(value_str," %lf %lf %lf",&d[0],&d[1],&d[2]) == 3)
{
value = &d;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
case TW_TYPE_COLOR3F:
case TW_TYPE_DIR3F:
{
if(sscanf(value_str," %f %f %f",&f[0],&f[1],&f[2]) == 3)
{
value = &f;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
case TW_TYPE_UINT8:
{
if(sscanf(value_str," %d",&i) == 1)
{
// Cast to unsigned char
uc = (unsigned char) i;
value = &uc;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
case TW_TYPE_BOOL32:
case TW_TYPE_INT32:
{
if(sscanf(value_str," %d",&i) == 1)
{
value = &i;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
case TW_TYPE_UINT32:
{
if(sscanf(value_str," %u",&u) == 1)
{
value = &u;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
case TW_TYPE_FLOAT:
{
if(sscanf(value_str," %f",&v) == 1)
{
value = &v;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
case TW_TYPE_DOUBLE:
{
if(sscanf(value_str," %lf",&dv) == 1)
{
value = &dv;
}else
{
printf("ERROR: Bad value format...\n");
return false;
}
break;
}
case TW_TYPE_STDSTRING:
{
s = value_str;
value = &s;
break;
}
default:
// Try to find type in custom enum types
std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::const_iterator iter =
ReTw_custom_types.find(type);
if(iter != ReTw_custom_types.end())
{
std::vector<TwEnumVal>::const_iterator eit = (*iter).second.second.begin();
bool found = false;
for(;eit<(*iter).second.second.end();eit++)
{
if(strcmp(value_str,eit->Label) == 0)
{
i = eit->Value;
value = &i;
found = true;
break;
}
}
if(!found)
{
printf("ERROR_ENUM_VALUE_NOT_DEFINED");
}
}else
{
printf("ERROR_TYPE_NOT_SUPPORTED\n");
}
break;
}
// Find variable based on name
// First look in RW items
bool item_found = false;
for(
std::vector<ReTwRWItem>::iterator it = rw_items.begin();
it != rw_items.end();
it++)
{
if(it->name == name)
{
void * var = it->var;
switch(type)
{
case TW_TYPE_BOOLCPP:
{
bool * bvar = static_cast<bool*>(var);
bool * bvalue = static_cast<bool*>(value);
*bvar = *bvalue;
break;
}
case TW_TYPE_QUAT4D:
//case TW_TYPE_COLOR4D:
{
double * dvar = static_cast<double*>(var);
double * dvalue = static_cast<double*>(value);
dvar[0] = dvalue[0];
dvar[1] = dvalue[1];
dvar[2] = dvalue[2];
dvar[3] = dvalue[3];
break;
}
case TW_TYPE_QUAT4F:
case TW_TYPE_COLOR4F:
{
float * fvar = static_cast<float*>(var);
float * fvalue = static_cast<float*>(value);
fvar[0] = fvalue[0];
fvar[1] = fvalue[1];
fvar[2] = fvalue[2];
fvar[3] = fvalue[3];
break;
}
//case TW_TYPE_COLOR3D:
case TW_TYPE_DIR3D:
{
double * dvar = static_cast<double*>(var);
double * dvalue = static_cast<double*>(value);
dvar[0] = dvalue[0];
dvar[1] = dvalue[1];
dvar[2] = dvalue[2];
break;
}
case TW_TYPE_COLOR3F:
case TW_TYPE_DIR3F:
{
float * fvar = static_cast<float*>(var);
float * fvalue = static_cast<float*>(value);
fvar[0] = fvalue[0];
fvar[1] = fvalue[1];
fvar[2] = fvalue[2];
break;
}
case TW_TYPE_UINT8:
{
unsigned char * ucvar = static_cast<unsigned char*>(var);
unsigned char * ucvalue = static_cast<unsigned char*>(value);
*ucvar = *ucvalue;
break;
}
case TW_TYPE_BOOL32:
case TW_TYPE_INT32:
{
int * ivar = static_cast<int*>(var);
int * ivalue = static_cast<int*>(value);
*ivar = *ivalue;
break;
}
case TW_TYPE_UINT32:
{
unsigned int * uvar = static_cast<unsigned int*>(var);
unsigned int * uvalue = static_cast<unsigned int*>(value);
*uvar = *uvalue;
break;
}
case TW_TYPE_FLOAT:
{
float * fvar = static_cast<float*>(var);
float * fvalue = static_cast<float*>(value);
*fvar = *fvalue;
break;
}
case TW_TYPE_DOUBLE:
{
double * dvar = static_cast<double*>(var);
double * fvalue = static_cast<double*>(value);
*dvar = *fvalue;
break;
}
case TW_TYPE_STDSTRING:
{
std::string * svar = static_cast<std::string*>(var);
std::string * svalue = static_cast<std::string*>(value);
*svar = *svalue;
break;
}
default:
// Try to find type in custom enum types
std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
ReTw_custom_types.find(type);
if(iter != ReTw_custom_types.end())
{
int * ivar = static_cast<int*>(var);
std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
bool found = false;
for(;eit<(*iter).second.second.end();eit++)
{
if(strcmp(value_str,eit->Label) == 0)
{
*ivar = eit->Value;
found = true;
break;
}
}
if(!found)
{
printf("ERROR_ENUM_VALUE_NOT_DEFINED");
}
}else
{
printf("ERROR_TYPE_NOT_SUPPORTED\n");
}
break;
}
item_found = true;
break;
}
}
// Try looking in CB items
if(!item_found)
{
for(
std::vector<ReTwCBItem>::iterator it = cb_items.begin();
it != cb_items.end();
it++)
{
if(it->name==name)
{
it->setCallback(value,it->clientData);
item_found = true;
break;
}
}
}
if(!item_found)
{
printf("ERROR: item '%s' not found\n",name);
}
return true;
}
IGL_INLINE const std::vector<igl::anttweakbar::ReTwRWItem> &
igl::anttweakbar::ReTwBar::get_rw_items()
{
return rw_items;
}
IGL_INLINE const std::vector<igl::anttweakbar::ReTwCBItem> &
igl::anttweakbar::ReTwBar::get_cb_items()
{
return cb_items;
}
-286
View File
@@ -1,286 +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_ANTTWEAKBAR_REANTTWEAKBAR_H
#define IGL_ANTTWEAKBAR_REANTTWEAKBAR_H
#include "../igl_inline.h"
// ReAntTweakBar is a minimal wrapper for the AntTweakBar library that allows
// "bars" to be saved and load from disk. Changing your existing app that uses
// AntTweakBar to use ReAntTweakBar is trivial.
//
// Many (but not all) variable types are supported. I'll try to keep track them
// here:
// TW_TYPE_BOOLCPP
// TW_TYPE_QUAT4F
// TW_TYPE_QUAT4D
// TW_TYPE_COLOR4F
// TW_TYPE_COLOR4D
// TW_TYPE_COLOR3F
// TW_TYPE_DIR3F
// TW_TYPE_DIR3D
// TW_TYPE_BOOL32
// TW_TYPE_INT32
// TW_TYPE_UINT32
// TW_TYPE_FLOAT
// TW_TYPE_DOUBLE
// TW_TYPE_UINT8
// and
// custom TwTypes made with TwDefineEnum
//
// I'm working on adding the rest on an as-needed basis. Adding a new type only
// requires changes in a few places...
//
//
//
// This allows the user to have a non-global, static installation of
// AntTweakBar
#include <AntTweakBar.h>
// Instead of including AntTweakBar.h, just define the necessary types
// Types used:
// - TwType
// - TwEnumVal
// - TwSetVarCallback
// - TwGetVarCallback
// - TwBar
// - TwButtonCallback
#include <vector>
#include <string>
#define REANTTWEAKBAR_MAX_CB_VAR_SIZE 1000
// Max line size for reading files
#define REANTTWEAKBAR_MAX_LINE 1000
#define REANTTWEAKBAR_MAX_WORD 100
namespace igl
{
namespace anttweakbar
{
TwType ReTwDefineEnum(
const char *name,
const TwEnumVal *enumValues,
unsigned int nbValues);
TwType ReTwDefineEnumFromString(const char * name,const char * enumString);
struct ReTwRWItem
{
//const char * name;
std::string name;
TwType type;
void * var;
// Default constructor
IGL_INLINE ReTwRWItem(
const std::string _name,
TwType _type,
void *_var):
name(_name),
type(_type),
var(_var)
{
}
// Shallow copy constructor
// I solemnly swear it's OK to copy var this way
// Q: Is it really?
IGL_INLINE ReTwRWItem(const ReTwRWItem & that):
name(that.name),
type(that.type),
var(that.var)
{
}
// Shallow assignment
// I solemnly swear it's OK to copy var this way
IGL_INLINE ReTwRWItem & operator=(const ReTwRWItem & that)
{
if(this != &that)
{
this->name = that.name;
this->type = that.type;
this->var = that.var;
}
return *this;
}
};
struct ReTwCBItem
{
//const char * name;
std::string name;
TwType type;
TwSetVarCallback setCallback;
TwGetVarCallback getCallback;
void * clientData;
// Default constructor
IGL_INLINE ReTwCBItem(
const std::string _name,
TwType _type,
TwSetVarCallback _setCallback,
TwGetVarCallback _getCallback,
void * _clientData):
name(_name),
type(_type),
setCallback(_setCallback),
getCallback(_getCallback),
clientData(_clientData)
{
}
// Shallow copy
// I solemnly swear it's OK to copy clientData this way
IGL_INLINE ReTwCBItem(const ReTwCBItem & that):
name(that.name),
type(that.type),
setCallback(that.setCallback),
getCallback(that.getCallback),
clientData(that.clientData)
{
}
// Shallow assignment
// I solemnly swear it's OK to copy clientData this way
IGL_INLINE ReTwCBItem & operator=(const ReTwCBItem & that)
{
if(this != &that)
{
name = that.name;
type = that.type;
setCallback = that.setCallback;
getCallback = that.getCallback;
clientData = that.clientData;
}
return *this;
}
};
class ReTwBar
{
// VARIABLES
// Should be private, but seeing as I'm not going to implement all of the
// AntTweakBar public functions right away, I'll expose this so that at
// anytime AntTweakBar functions can be called directly on the bar
public:
TwBar * bar;
std::string name;
protected:
std::vector<ReTwRWItem> rw_items;
std::vector<ReTwCBItem> cb_items;
public:
// Default constructor with explicit initialization
IGL_INLINE ReTwBar();
private:
// Copy constructor does shallow copy
IGL_INLINE ReTwBar(const ReTwBar & that);
// Assignment operator does shallow assignment
IGL_INLINE ReTwBar &operator=(const ReTwBar & that);
// WRAPPERS FOR ANTTWEAKBAR FUNCTIONS
public:
IGL_INLINE void TwNewBar(const char *_name);
IGL_INLINE int TwAddVarRW(
const char *name,
TwType type,
void *var,
const char *def,
const bool record=true);
IGL_INLINE int TwAddVarCB(
const char *name,
TwType type,
TwSetVarCallback setCallback,
TwGetVarCallback getCallback,
void *clientData,
const char *def,
const bool record=true);
// Wrappers for convenience (not recorded, just passed on)
IGL_INLINE int TwAddVarRO(const char *name, TwType type, void *var, const char *def);
IGL_INLINE int TwAddButton(
const char *name,
TwButtonCallback buttonCallback,
void *clientData,
const char *def);
IGL_INLINE int TwSetParam(
const char *varName,
const char *paramName,
TwParamValueType paramValueType,
unsigned int inValueCount,
const void *inValues);
IGL_INLINE int TwGetParam(
const char *varName,
const char *paramName,
TwParamValueType paramValueType,
unsigned int outValueMaxCount,
void *outValues);
IGL_INLINE int TwRefreshBar();
IGL_INLINE int TwTerminate();
// IO FUNCTIONS
public:
// Save current items to file
// Input:
// file_name name of file to save data to, can be null which means print
// to stdout
// Return:
// true only if there were no (fatal) errors
IGL_INLINE bool save(const char *file_name);
std::string get_value_as_string(
void * var,
TwType type);
// Load into current items from file
// Input:
// file_name name of input file to load
// Return:
// true only if there were no (fatal) errors
IGL_INLINE bool load(const char *file_name);
// Get TwType from string
// Input
// type_str string of type
// Output
// type TwType converted from string
// Returns
// true only if string matched a valid type
IGL_INLINE bool type_from_string(const char *type_str, TwType & type);
// I realize that I mix std::string and const char * all over the place.
// What can you do...
IGL_INLINE bool set_value_from_string(
const char * name,
TwType type,
const char * value_str);
IGL_INLINE const std::vector<ReTwRWItem> & get_rw_items();
IGL_INLINE const std::vector<ReTwCBItem> & get_cb_items();
};
}
}
// List of TwBar functions
//TW_API TwBar * TW_CALL TwNewBar(const char *barName);
//TW_API int TW_CALL TwDeleteBar(TwBar *bar);
//TW_API int TW_CALL TwDeleteAllBars();
//TW_API int TW_CALL TwSetTopBar(const TwBar *bar);
//TW_API TwBar * TW_CALL TwGetTopBar();
//TW_API int TW_CALL TwSetBottomBar(const TwBar *bar);
//TW_API TwBar * TW_CALL TwGetBottomBar();
//TW_API const char * TW_CALL TwGetBarName(TwBar *bar);
//TW_API int TW_CALL TwGetBarCount();
//TW_API TwBar * TW_CALL TwGetBarByIndex(int barIndex);
//TW_API TwBar * TW_CALL TwGetBarByName(const char *barName);
//TW_API int TW_CALL TwRefreshBar(TwBar *bar);
//TW_API int TW_CALL TwTerminate();
//
//TW_API int TW_CALL TwAddVarRW(TwBar *bar, const char *name, TwType type, void *var, const char *def);
//TW_API int TW_CALL TwAddVarRO(TwBar *bar, const char *name, TwType type, const void *var, const char *def);
//TW_API int TW_CALL TwAddVarCB(TwBar *bar, const char *name, TwType type, TwSetVarCallback setCallback, TwGetVarCallback getCallback, void *clientData, const char *def);
//TW_API int TW_CALL TwAddButton(TwBar *bar, const char *name, TwButtonCallback callback, void *clientData, const char *def);
//TW_API int TW_CALL TwAddSeparator(TwBar *bar, const char *name, const char *def);
//TW_API int TW_CALL TwRemoveVar(TwBar *bar, const char *name);
//TW_API int TW_CALL TwRemoveAllVars(TwBar *bar);
// Until AntTweakBar dependency folder exists, this is header-only
#ifndef IGL_STATIC_LIBRARY
# include "ReAntTweakBar.cpp"
#endif
#endif
@@ -1,81 +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 "cocoa_key_to_anttweakbar_key.h"
#include <AntTweakBar.h>
IGL_INLINE int igl::anttweakbar::cocoa_key_to_anttweakbar_key(int key)
{
// I've left commented the AntTweakBar key codes that correspond to keys I
// don't have on my keyboard. Please fill this in if you have those keys
switch(key)
{
case 127:
return TW_KEY_BACKSPACE;
case 9:
return TW_KEY_TAB;
//TW_KEY_CLEAR = 0x0c,
case 3://ENTER
case 13:
return TW_KEY_RETURN;
case 27:
return TW_KEY_ESCAPE;
case 32:
return TW_KEY_SPACE;
// IN A GLUT APP 40 is (
//case 40:
case 63272:
return TW_KEY_DELETE;
case 63232:
return TW_KEY_UP;
case 63233:
return TW_KEY_DOWN;
case 63235:
return TW_KEY_RIGHT;
case 63234:
return TW_KEY_LEFT;
//TW_KEY_INSERT,
//TW_KEY_HOME,
//TW_KEY_END,
//TW_KEY_PAGE_UP,
//TW_KEY_PAGE_DOWN,
case 63236:
return TW_KEY_F1;
case 63237:
return TW_KEY_F2;
case 63238:
return TW_KEY_F3;
case 63239:
return TW_KEY_F4;
case 63240:
return TW_KEY_F5;
case 63241:
return TW_KEY_F6;
case 63242:
return TW_KEY_F7;
case 63243:
return TW_KEY_F8;
case 63244:
return TW_KEY_F9;
case 63245:
return TW_KEY_F10;
case 63246:
return TW_KEY_F11;
case 63247:
return TW_KEY_F12;
case 63248:
return TW_KEY_F13;
case 63249:
return TW_KEY_F14;
case 63250:
return TW_KEY_F15;
default:
break;
}
return key;
}
@@ -1,31 +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_ANTTWEAKBAR_COCOA_KEY_TO_ANTTWEAKBAR_KEY_H
#define IGL_ANTTWEAKBAR_COCOA_KEY_TO_ANTTWEAKBAR_KEY_H
#include "../igl_inline.h"
namespace igl
{
namespace anttweakbar
{
// Convert an unsigned char (like that from Cocoa apps) to AntTweakBar key
// code.
// See also: TranslateKey() in TwMgr.cpp in AntTweakBar source
// Inputs:
// key unsigned char key from keyboard
// Returns int of new key code
IGL_INLINE int cocoa_key_to_anttweakbar_key(int key);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "cocoa_key_to_anttweakbar_key.cpp"
#endif
#endif
+14 -14
View File
@@ -1,11 +1,12 @@
// 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
//
// 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 "avg_edge_length.h"
#include "edges.h"
#include <vector>
@@ -14,20 +15,19 @@ IGL_INLINE double igl::avg_edge_length(
const Eigen::MatrixBase<DerivedV>& V,
const Eigen::MatrixBase<DerivedF>& F)
{
double avg = 0;
long int count = 0;
typedef typename DerivedF::Scalar Index;
Eigen::Matrix<Index, Eigen::Dynamic, 2> E;
// Augh. Technically this is double counting interior edges...
for (unsigned i=0;i<F.rows();++i)
igl::edges(F, E);
double avg = 0;
for (unsigned i=0;i<E.rows();++i)
{
for (unsigned j=0;j<F.cols();++j)
{
++count;
avg += (V.row(F(i,j)) - V.row(F(i,(j+1)%F.cols()))).norm();
}
avg += (V.row(E(i,0)) - V.row(E(i,1))).norm();
}
return avg / (double) count;
return avg / (double) E.rows();
}
#ifdef IGL_STATIC_LIBRARY
+5 -5
View File
@@ -1,9 +1,9 @@
// 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
//
// 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_AVERAGEEDGELENGTH_H
#define IGL_AVERAGEEDGELENGTH_H
@@ -13,7 +13,7 @@
#include <string>
#include <vector>
namespace igl
namespace igl
{
// Compute the average edge length for the given triangle mesh
// Templates:
+12 -11
View File
@@ -1,9 +1,9 @@
// 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
//
// 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 "cat.h"
@@ -14,14 +14,14 @@
#include <unsupported/Eigen/SparseExtra>
// Sparse matrices need to be handled carefully. Because C++ does not
// Sparse matrices need to be handled carefully. Because C++ does not
// Template:
// Scalar sparse matrix scalar type, e.g. double
template <typename Scalar>
IGL_INLINE void igl::cat(
const int dim,
const Eigen::SparseMatrix<Scalar> & A,
const Eigen::SparseMatrix<Scalar> & B,
const int dim,
const Eigen::SparseMatrix<Scalar> & A,
const Eigen::SparseMatrix<Scalar> & B,
Eigen::SparseMatrix<Scalar> & C)
{
@@ -108,13 +108,13 @@ IGL_INLINE void igl::cat(
}
C = SparseMatrix<Scalar>(
C = SparseMatrix<Scalar>(
dim == 1 ? A.rows()+B.rows() : A.rows(),
dim == 1 ? A.cols() : A.cols()+B.cols());
C.reserve(A.nonZeros() + B.nonZeros());
C.setFromTriplets(CIJV.begin(),CIJV.end());
#else
C = SparseMatrix<Scalar>(
C = SparseMatrix<Scalar>(
dim == 1 ? A.rows()+B.rows() : A.rows(),
dim == 1 ? A.cols() : A.cols()+B.cols());
Eigen::VectorXi per_col = Eigen::VectorXi::Zero(C.cols());
@@ -189,7 +189,7 @@ IGL_INLINE void igl::cat(
template <typename Derived, class MatC>
IGL_INLINE void igl::cat(
const int dim,
const Eigen::MatrixBase<Derived> & A,
const Eigen::MatrixBase<Derived> & A,
const Eigen::MatrixBase<Derived> & B,
MatC & C)
{
@@ -264,4 +264,5 @@ template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::cat<Eigen::Matrix<int, -1, 1,
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&);
template void igl::cat<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
template void igl::cat<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::Matrix<int, -1, -1, 0, -1, -1>&);
template void igl::cat<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::Matrix<int, -1, 1, 0, -1, 1>&);
#endif
+1
View File
@@ -64,4 +64,5 @@ IGL_INLINE void igl::centroid(
// 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> >&);
#endif
+28 -21
View File
@@ -86,35 +86,42 @@ namespace igl {
std::deque<int> d;
d.push_back(0);
mark(0) = true;
while (!d.empty())
while (!mark.all()) // Stop until all vertices are marked
{
int f0 = d.at(0);
d.pop_front();
for (int k=0; k<3; k++)
int unmarked = 0;
while (mark(unmarked))
unmarked++;
d.push_back(unmarked);
mark(unmarked) = true;
while (!d.empty())
{
int f1 = TT(f0,k);
if (f1==-1) continue;
if (mark(f1)) continue;
int f0 = d.at(0);
d.pop_front();
for (int k=0; k<3; k++)
{
int f1 = TT(f0,k);
if (f1==-1) continue;
if (mark(f1)) continue;
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir0 = PD1out.row(f0);
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir1 = PD1out.row(f1);
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> n0 = N.row(f0);
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> n1 = N.row(f1);
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir0 = PD1out.row(f0);
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir1 = PD1out.row(f1);
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> n0 = N.row(f0);
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> n1 = N.row(f1);
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir0Rot = igl::rotation_matrix_from_directions(n0, n1)*dir0;
dir0Rot.normalize();
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> targD = K_PI_new(dir1,dir0Rot,n1);
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> dir0Rot = igl::rotation_matrix_from_directions(n0, n1)*dir0;
dir0Rot.normalize();
Eigen::Matrix<typename DerivedV::Scalar, 3, 1> targD = K_PI_new(dir1,dir0Rot,n1);
PD1out.row(f1) = targD;
PD2out.row(f1) = n1.cross(targD).normalized();
PD1out.row(f1) = targD;
PD2out.row(f1) = n1.cross(targD).normalized();
mark(f1) = true;
d.push_back(f1);
mark(f1) = true;
d.push_back(f1);
}
}
}
+210 -66
View File
@@ -33,44 +33,45 @@ extern const int edgeTable[256];
extern const int triTable[256][2][17];
extern const int polyTable[8][16];
struct EdgeKey
{
EdgeKey(unsigned i0, unsigned i1) : i0_(i0), i1_(i1) {}
bool operator==(const EdgeKey& _rhs) const
{
return i0_ == _rhs.i0_ && i1_ == _rhs.i1_;
}
unsigned i0_, i1_;
};
struct EdgeHash
{
std::size_t operator()(const EdgeKey& key) const {
std::size_t seed = 0;
seed ^= key.i0_ + 0x9e3779b9 + (seed<<6) + (seed>>2); // Copied from boost::hash_combine
seed ^= key.i1_ + 0x9e3779b9 + (seed<<6) + (seed>>2);
return std::hash<std::size_t>()(seed);
}
};
template <typename Derivedvalues, typename Derivedpoints,typename Derivedvertices, typename DerivedF>
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
class MarchingCubes
{
struct EdgeKey
{
EdgeKey(unsigned i0, unsigned i1) : i0_(i0), i1_(i1) {}
bool operator==(const EdgeKey& _rhs) const
{
return i0_ == _rhs.i0_ && i1_ == _rhs.i1_;
}
unsigned i0_, i1_;
};
struct EdgeHash
{
std::size_t operator()(const EdgeKey& key) const {
std::size_t seed = 0;
seed ^= key.i0_ + 0x9e3779b9 + (seed<<6) + (seed>>2); // Copied from boost::hash_combine
seed ^= key.i1_ + 0x9e3779b9 + (seed<<6) + (seed>>2);
return std::hash<std::size_t>()(seed);
}
};
typedef std::unordered_map<EdgeKey, unsigned, EdgeHash> MyMap;
typedef typename MyMap::const_iterator MyMapIterator;
public:
MarchingCubes(
const Eigen::PlainObjectBase<Derivedvalues> &values,
const Eigen::PlainObjectBase<Derivedpoints> &points,
// Dense index grid version
MarchingCubes(const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
const unsigned x_res,
const unsigned y_res,
const unsigned z_res,
Eigen::PlainObjectBase<Derivedvertices> &vertices,
Eigen::PlainObjectBase<DerivedF> &faces)
const double isovalue,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces)
{
assert(values.cols() == 1);
assert(points.cols() == 3);
@@ -101,7 +102,7 @@ public:
{
unsigned corner[8];
typename DerivedF::Scalar samples[12];
typename DerivedFaces::Scalar samples[12];
unsigned char cubetype(0);
unsigned int i;
@@ -126,7 +127,7 @@ public:
// determine cube type
for (i=0; i<8; ++i)
if (values(corner[i]) > 0.0)
if (values(corner[i]) > isovalue)
cubetype |= (1<<i);
@@ -182,77 +183,220 @@ public:
vertices.conservativeResize(num_vertices, Eigen::NoChange);
faces.conservativeResize(num_faces, Eigen::NoChange);
};
}
static typename DerivedF::Scalar add_vertex(const Eigen::PlainObjectBase<Derivedvalues> &values,
const Eigen::PlainObjectBase<Derivedpoints> &points,
unsigned int i0,
unsigned int i1,
Eigen::PlainObjectBase<Derivedvertices> &vertices,
int &num_vertices,
MyMap &edge2vertex)
// Sparse index grid version
MarchingCubes(const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
const Eigen::MatrixBase<DerivedIndices> &cubes,
const double isovalue,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces)
{
assert(values.cols() == 1);
assert(points.cols() == 3);
assert(cubes.cols() == 8);
if(cubes.rows() == 0)
{
return;
}
faces.resize(10000,3);
int num_faces = 0;
vertices.resize(10000,3);
int num_vertices = 0;
unsigned n_cubes = cubes.rows();
for (unsigned cube_it =0 ; cube_it < n_cubes; ++cube_it)
{
typedef Eigen::Matrix<typename DerivedIndices::Scalar, 1, 8> CubeIndexVector;
typedef typename DerivedFaces::Scalar SampleScalar;
CubeIndexVector cube = cubes.row(cube_it);
SampleScalar samples[12];
unsigned char cubetype(0);
// determine cube type
for (int i=0; i<8; ++i)
{
if (values[cube[i]] > isovalue)
{
cubetype |= (1<<i);
}
}
// trivial reject ?
if (cubetype == 0 || cubetype == 255)
{
continue;
}
// compute samples on cube's edges
if (edgeTable[cubetype]&1)
samples[0] = add_vertex(values, points, cube[0], cube[1], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&2)
samples[1] = add_vertex(values, points, cube[1], cube[2], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&4)
samples[2] = add_vertex(values, points, cube[3], cube[2], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&8)
samples[3] = add_vertex(values, points, cube[0], cube[3], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&16)
samples[4] = add_vertex(values, points, cube[4], cube[5], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&32)
samples[5] = add_vertex(values, points, cube[5], cube[6], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&64)
samples[6] = add_vertex(values, points, cube[7], cube[6], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&128)
samples[7] = add_vertex(values, points, cube[4], cube[7], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&256)
samples[8] = add_vertex(values, points, cube[0], cube[4], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&512)
samples[9] = add_vertex(values, points, cube[1], cube[5], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&1024)
samples[10] = add_vertex(values, points, cube[2], cube[6], vertices, num_vertices, edge2vertex);
if (edgeTable[cubetype]&2048)
samples[11] = add_vertex(values, points, cube[3], cube[7], vertices, num_vertices, edge2vertex);
// connect samples by triangles
for (int i=0; triTable[cubetype][0][i] != -1; i+=3 )
{
num_faces++;
if (num_faces > faces.rows())
{
faces.conservativeResize(faces.rows()+10000, Eigen::NoChange);
}
faces.row(num_faces-1) <<
samples[triTable[cubetype][0][i ]],
samples[triTable[cubetype][0][i+1]],
samples[triTable[cubetype][0][i+2]];
}
}
vertices.conservativeResize(num_vertices, Eigen::NoChange);
faces.conservativeResize(num_faces, Eigen::NoChange);
}
static typename DerivedFaces::Scalar add_vertex(const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
unsigned int i0,
unsigned int i1,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
int &num_vertices,
MyMap &edge2vertex)
{
// find vertex if it has been computed already
MyMapIterator it = edge2vertex.find(EdgeKey(i0, i1));
if (it != edge2vertex.end())
{
return it->second;
;
}
// generate new vertex
const Eigen::Matrix<typename Derivedpoints::Scalar, 1, 3> & p0 = points.row(i0);
const Eigen::Matrix<typename Derivedpoints::Scalar, 1, 3> & p1 = points.row(i1);
typename Derivedvalues::Scalar s0 = fabs(values(i0));
typename Derivedvalues::Scalar s1 = fabs(values(i1));
typename Derivedvalues::Scalar t = s0 / (s0+s1);
const Eigen::Matrix<typename DerivedPoints::Scalar, 1, 3> & p0 = points.row(i0);
const Eigen::Matrix<typename DerivedPoints::Scalar, 1, 3> & p1 = points.row(i1);
typename DerivedValues::Scalar s0 = fabs(values[i0]);
typename DerivedValues::Scalar s1 = fabs(values[i1]);
typename DerivedValues::Scalar t = s0 / (s0+s1);
num_vertices++;
if (num_vertices > vertices.rows())
{
vertices.conservativeResize(vertices.rows()+10000, Eigen::NoChange);
}
// Linear interpolation based on linearly interpolating values
vertices.row(num_vertices-1) = ((1.0f-t)*p0 + t*p1).template cast<typename Derivedvertices::Scalar>();
vertices.row(num_vertices-1) = ((1.0f-t)*p0 + t*p1).template cast<typename DerivedVertices::Scalar>();
edge2vertex[EdgeKey(i0, i1)] = num_vertices-1;
return num_vertices-1;
}
;
// maps an edge to the sample vertex generated on it
MyMap edge2vertex;
};
template <typename Derivedvalues, typename Derivedpoints, typename Derivedvertices, typename DerivedF>
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedFaces>
IGL_INLINE void igl::copyleft::marching_cubes(
const Eigen::PlainObjectBase<Derivedvalues> &values,
const Eigen::PlainObjectBase<Derivedpoints> &points,
const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
const unsigned x_res,
const unsigned y_res,
const unsigned z_res,
Eigen::PlainObjectBase<Derivedvertices> &vertices,
Eigen::PlainObjectBase<DerivedF> &faces)
const double isovalue,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces)
{
MarchingCubes<Derivedvalues, Derivedpoints, Derivedvertices, DerivedF> mc(values,
points,
x_res,
y_res,
z_res,
vertices,
faces);
typedef Eigen::MatrixXi Shim; /* DerivedIndices shim type is unused in this instantiation*/
MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, Shim, DerivedFaces>
mc(values, points, x_res, y_res, z_res, isovalue, vertices, faces);
}
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedFaces>
IGL_INLINE void igl::copyleft::marching_cubes(
const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
const unsigned x_res,
const unsigned y_res,
const unsigned z_res,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces)
{
typedef Eigen::MatrixXi Shim; /* DerivedIndices shim type is unused in this instantiation*/
MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, Shim, DerivedFaces>
mc(values, points, x_res, y_res, z_res, 0.0 /*isovalue*/, vertices, faces);
}
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
IGL_INLINE void igl::copyleft::marching_cubes(
const Eigen::MatrixBase<DerivedValues>& values,
const Eigen::MatrixBase<DerivedPoints>& points,
const Eigen::MatrixBase<DerivedIndices>& indices,
const double isovalue,
Eigen::PlainObjectBase<DerivedVertices>& vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces)
{
MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, DerivedIndices, DerivedFaces> mc(values, points, indices, isovalue, vertices, faces);
}
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
IGL_INLINE void igl::copyleft::marching_cubes(
const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
const Eigen::MatrixBase<DerivedIndices> & indices,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces)
{
MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, DerivedIndices, DerivedFaces> mc(values, points, indices, 0.0 /*isovalue*/, vertices, faces);
}
#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::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<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> >&);
// generated by autoexplicit.sh
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::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<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> >&);
// generated by autoexplicit.sh
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::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<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> >&);
// generated by autoexplicit.sh
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::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<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> >&);
// 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<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -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> >&);
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, -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<double, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -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<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<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
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, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
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, -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<double, -1, -1, 0, -1, -1> >&, const Eigen::MatrixBase<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> >&);
template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -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> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, const Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, const Eigen::MatrixBase<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> >&);
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, 0, -1, 3>, 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<double, -1, -1, 0, -1, -1> >&, const Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, 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<double, -1, 3, 0, -1, 3> >&, const Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
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, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 8, 0, -1, 8>, 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, 8, 0, -1, 8> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
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, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, 3, 0, -1, 3> >(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> >&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
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, -1, 0, -1, -1>,Eigen::Matrix<int, -1, 8, 0, -1, 8>,Eigen::Matrix<int, -1, 3, 0, -1, 3> >(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, 8, 0, -1, 8> >&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>,Eigen::Matrix<double, -1, 3, 0, -1, 3>,Eigen::Matrix<double, -1, 3, 0, -1, 3>,Eigen::Matrix<int, -1, 8, 0, -1, 8>,Eigen::Matrix<int, -1, 3, 0, -1, 3> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&,const Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&,const Eigen::MatrixBase<Eigen::Matrix<int, -1, 8, 0, -1, 8> >&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
#endif
+64 -13
View File
@@ -14,10 +14,10 @@ namespace igl
{
namespace copyleft
{
// marching_cubes( values, points, x_res, y_res, z_res, vertices, faces )
// marching_cubes( values, points, x_res, y_res, z_res, isovalue, vertices, faces )
//
// performs marching cubes reconstruction on the grid defined by values, and
// points, and generates vertices and faces
// performs marching cubes reconstruction on a grid defined by values, and
// points, and generates a mesh defined by vertices and faces
//
// Input:
// values #number_of_grid_points x 1 array -- the scalar values of an
@@ -34,24 +34,75 @@ namespace igl
// xres resolutions of the grid in x dimension
// yres resolutions of the grid in y dimension
// zres resolutions of the grid in z dimension
// isovalue the isovalue of the surface to reconstruct
// Output:
// vertices #V by 3 list of mesh vertex positions
// faces #F by 3 list of mesh triangle indices
//
template <
typename Derivedvalues,
typename Derivedpoints,
typename Derivedvertices,
typename DerivedF>
IGL_INLINE void marching_cubes(
const Eigen::PlainObjectBase<Derivedvalues> &values,
const Eigen::PlainObjectBase<Derivedpoints> &points,
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedFaces>
IGL_INLINE void marching_cubes(
const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
const unsigned x_res,
const unsigned y_res,
const unsigned z_res,
Eigen::PlainObjectBase<Derivedvertices> &vertices,
Eigen::PlainObjectBase<DerivedF> &faces);
const double isovalue,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces);
// Overload of the above function where the isovalue defaults to 0.0
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedFaces>
IGL_INLINE void marching_cubes(
const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
const unsigned x_res,
const unsigned y_res,
const unsigned z_res,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces);
// marching_cubes( values, points, indices, vertices, faces )
//
// Perform marching cubes reconstruction on the sparse grid cells defined by (indices, points).
// The indices parameter is an nx8 dense array of index values into the points and values arrays.
// Each row of indices represents a cube for which to generate vertices and faces over.
//
// Input:
// values #number_of_grid_points x 1 array -- the scalar values of an
// implicit function defined on the grid points (<0 in the inside of the
// surface, 0 on the border, >0 outside)
// points #number_of_grid_points x 3 array -- 3-D positions of the grid
// points, ordered in x,y,z order:
// indices #cubes x 8 array -- one row for each cube where each value is
// the index of a vertex in points and a scalar in values.
// i.e. points[indices[i, j]] = the position of the j'th vertex of the i'th cube
// Output:
// vertices #V by 3 list of mesh vertex positions
// faces #F by 3 list of mesh triangle indices
// Note: The winding direction of the cube indices will affect the output winding of the faces
//
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
IGL_INLINE void marching_cubes(
const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
const Eigen::MatrixBase<DerivedIndices> &indices,
const double isovalue,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces);
// Overload of the above function where the isovalue defaults to 0.0
template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
IGL_INLINE void marching_cubes(
const Eigen::MatrixBase<DerivedValues> &values,
const Eigen::MatrixBase<DerivedPoints> &points,
const Eigen::MatrixBase<DerivedIndices> &indices,
Eigen::PlainObjectBase<DerivedVertices> &vertices,
Eigen::PlainObjectBase<DerivedFaces> &faces);
}
}
#ifndef IGL_STATIC_LIBRARY
@@ -13,6 +13,94 @@
// STL includes
#include <cassert>
IGL_INLINE bool igl::copyleft::tetgen::mesh_to_tetgenio(
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,
tetgenio & in)
{
using namespace std;
in.firstnumber = 0;
in.numberofpoints = V.size();
in.pointlist = new REAL[in.numberofpoints * 3];
//loop over points
for(size_t i = 0; i < (size_t)V.size(); i++)
{
assert(V[i].size() == 3);
in.pointlist[i*3+0] = V[i][0];
in.pointlist[i*3+1] = V[i][1];
in.pointlist[i*3+2] = V[i][2];
}
in.numberoffacets = F.size();
in.facetlist = new tetgenio::facet[in.numberoffacets];
in.facetmarkerlist = new int[in.numberoffacets];
// loop over face
for(size_t i = 0;i < (size_t)F.size(); i++)
{
in.facetmarkerlist[i] = i;
tetgenio::facet * f = &in.facetlist[i];
f->numberofpolygons = 1;
f->polygonlist = new tetgenio::polygon[f->numberofpolygons];
f->numberofholes = 0;
f->holelist = NULL;
tetgenio::polygon * p = &f->polygonlist[0];
p->numberofvertices = F[i].size();
p->vertexlist = new int[p->numberofvertices];
// loop around face
for(int j = 0;j < (int)F[i].size(); j++)
{
p->vertexlist[j] = F[i][j];
}
}
in.numberofholes = H.size();
in.holelist = new double[3 * in.numberofholes];
// loop over holes
for(size_t holeID = 0, nHoles = H.size(); holeID < nHoles; holeID++)
{
in.holelist[holeID * 3 + 0] = H[holeID][0];
in.holelist[holeID * 3 + 1] = H[holeID][1];
in.holelist[holeID * 3 + 2] = H[holeID][2];
}
in.numberofregions = R.size();
in.regionlist = new REAL[ 5 * in.numberofregions];
// loop over regions
for(size_t regionID = 0, nRegions = R.size(); regionID < nRegions; regionID++)
{
in.regionlist[regionID * 5 + 0] = R[regionID][0];
in.regionlist[regionID * 5 + 1] = R[regionID][1];
in.regionlist[regionID * 5 + 2] = R[regionID][2];
in.regionlist[regionID * 5 + 3] = R[regionID][3];
in.regionlist[regionID * 5 + 4] = R[regionID][4];
}
return true;
}
template <typename DerivedV, typename DerivedF, typename DerivedH, typename DerivedR>
IGL_INLINE bool igl::copyleft::tetgen::mesh_to_tetgenio(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedH>& H,
const Eigen::PlainObjectBase<DerivedR>& R,
tetgenio & in)
{
using namespace std;
vector<vector<REAL> > vV, vH, vR;
vector<vector<int> > vF;
matrix_to_list(V,vV);
matrix_to_list(F,vF);
matrix_to_list(H, vH);
matrix_to_list(R, vR);
return mesh_to_tetgenio(vV,vF,vH,vR,in);
}
IGL_INLINE bool igl::copyleft::tetgen::mesh_to_tetgenio(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,
@@ -43,6 +43,38 @@ namespace igl
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
tetgenio & in);
// Load a vertex list and face list into a tetgenio object
// Inputs:
// V #V by 3 vertex position list
// F #F list of polygon face indices into V (0-indexed)
// H #H list of seed point inside each hole
// R #R list of seed point inside each region
// Outputs:
// in tetgenio input object
// Returns true on success, false on error
IGL_INLINE bool mesh_to_tetgenio(
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,
tetgenio & in);
// Wrapper with Eigen types
// Templates:
// DerivedV real-value: i.e. from MatrixXd
// DerivedF integer-value: i.e. from MatrixXi
// DerivedH real-value
// DerivedR real-value
template <typename DerivedV, typename DerivedF, typename DerivedH, typename DerivedR>
IGL_INLINE bool mesh_to_tetgenio(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedH>& H,
const Eigen::PlainObjectBase<DerivedR>& R,
tetgenio& in);
}
}
}
@@ -13,6 +13,120 @@
// 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,
@@ -63,8 +177,6 @@ IGL_INLINE bool igl::copyleft::tetgen::tetgenio_to_tetmesh(
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
@@ -14,6 +14,7 @@
#endif
#include "tetgen.h" // Defined tetgenio, REAL
#include <vector>
#include <unordered_map>
#include <Eigen/Core>
namespace igl
{
@@ -54,7 +55,32 @@ namespace igl
const tetgenio & out,
Eigen::PlainObjectBase<DerivedV>& V,
Eigen::PlainObjectBase<DerivedT>& T);
}
// Extract a tetrahedral mesh from a tetgenio object
// Inputs:
// out tetgenio output object
// Outputs:
// V #V by 3 vertex position list
// T #T by 4 list of tetrahedra indices into V
// F #F by 3 list of marked facets
// R #T list of region IDs for tetrahedra
// N #T by 2 list of neighbors for each tetrahedron
// PT #V list of incident tetrahedron for each vertex
// FT #F by 2 list of tetrahedra sharing each face
// nR number of regions in output mesh
// Returns true on success, false on error
IGL_INLINE bool 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,// region marks for tetrahedrons
std::vector<std::vector<int > > &N, // neighborlist per tet
std::vector<std::vector<int > > &PT, // Point to tet list per point
std::vector<std::vector<int > > &FT, // face to tet list
size_t & nR); // number of regions
}
}
}
+127 -2
View File
@@ -18,6 +18,131 @@
#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::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)
{
using namespace std;
tetgenio in,out;
bool success;
success = mesh_to_tetgenio(V, F, H, R, in);
if(!success)
{
return -1;
}
try
{
char * cswitches = new char[switches.size() + 1];
strcpy(cswitches, switches.c_str());
::tetrahedralize(cswitches, &in, &out);
delete[] cswitches;
}catch(int e)
{
cerr <<"^"<<__FUNCTION__<<": TETGEN CRASHED...KABOOM!!"<<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, TR, TN, PT, FT, numRegions
);
if(!success)
{
return -1;
}
return 0;
}
template <
typename DerivedV,
typename DerivedF,
typename DerivedH,
typename DerivedR,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF,
typename DerivedTR>
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedH>& H,
const Eigen::PlainObjectBase<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)
{
using namespace std;
vector<vector<REAL> > vV, vH, vR, vTV, vTR;
vector<vector<int> > vF,vTT,vTF, vTN, vPT, vFT;
matrix_to_list(V,vV);
matrix_to_list(F,vF);
matrix_to_list(H, vH);
matrix_to_list(R, vR);
int e = tetrahedralize(vV,vF,vH,vR,switches,vTV,vTT,vTF,vTR,vTN,vPT,vFT, numRegions);
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;
}
bool TR_rect = list_to_matrix(vTR, TR);
if(!TR_rect)
{
return 3;
}
bool TN_rect = list_to_matrix(vTN, TN);
if(!TN_rect)
{
return 3;
}
bool PT_rect = list_to_matrix(vPT, PT);
if(!PT_rect)
{
return 3;
}
bool FT_rect = list_to_matrix(vFT, FT);
if(!FT_rect)
{
return 3;
}
}
return e;
}
IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
const std::vector<std::vector<REAL > > & V,
const std::vector<std::vector<int> > & F,
@@ -55,7 +180,7 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
{
return -1;
}
//boundary_facets(TT,TF);
boundary_facets(TT,TF);
return 0;
}
@@ -208,7 +333,7 @@ IGL_INLINE int igl::copyleft::tetgen::tetrahedralize(
for (int i = 0; i < out.numberofpoints; ++i) {
TM[i] = out.pointmarkerlist[i];
}
//boundary_facets(TT,TF);
boundary_facets(TT,TF);
return 0;
}
+77 -1
View File
@@ -123,7 +123,83 @@ 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
// 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
// "" will mesh the convex hull constrained to pass through V (ignores F)
// Outputs:
// 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
// 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
// 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);
// Wrapper with Eigen types
// Templates:
// DerivedV real-value: i.e. from MatrixXd
// DerivedF integer-value: i.e. from MatrixXi
template <
typename DerivedV,
typename DerivedF,
typename DerivedH,
typename DerivedR,
typename DerivedTV,
typename DerivedTT,
typename DerivedTF,
typename DerivedTR>
IGL_INLINE int tetrahedralize(
const Eigen::PlainObjectBase<DerivedV>& V,
const Eigen::PlainObjectBase<DerivedF>& F,
const Eigen::PlainObjectBase<DerivedH>& H,
const Eigen::PlainObjectBase<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);
}
}
}
+1 -1
View File
@@ -32,7 +32,7 @@ namespace igl
// Scalar scalar type for eigen sparse matrix (e.g. double)
// Inputs:
// V #V by dim list of mesh vertex positions
// F #F by simplex_size list of mesh faces (must be triangles)
// F #F by simplex_size list of mesh elements (triangles or tetrahedra)
// Outputs:
// L #V by #V cotangent matrix, each row i corresponding to V(i,:)
//
+336
View File
@@ -0,0 +1,336 @@
#include "cut_to_disk.h"
#include <map>
#include <set>
#include <deque>
#include <algorithm>
namespace igl {
template <typename DerivedF, typename Index>
void cut_to_disk(
const Eigen::MatrixBase<DerivedF> &F,
std::vector<std::vector<Index> > &cuts)
{
cuts.clear();
Index nfaces = F.rows();
if (nfaces == 0)
return;
std::map<std::pair<Index, Index>, std::vector<Index> > edges;
// build edges
for (Index i = 0; i < nfaces; i++)
{
for (int j = 0; j < 3; j++)
{
Index v0 = F(i, j);
Index v1 = F(i, (j + 1) % 3);
std::pair<Index, Index> e;
e.first = std::min(v0, v1);
e.second = std::max(v0, v1);
edges[e].push_back(i);
}
}
int nedges = edges.size();
Eigen::Matrix<Index, -1, -1> edgeVerts(nedges,2);
Eigen::Matrix<Index, -1, -1> edgeFaces(nedges,2);
Eigen::Matrix<Index, -1, -1> faceEdges(nfaces, 3);
std::set<Index> boundaryEdges;
std::map<std::pair<Index, Index>, Index> edgeidx;
Index idx = 0;
for (auto it : edges)
{
edgeidx[it.first] = idx;
edgeVerts(idx, 0) = it.first.first;
edgeVerts(idx, 1) = it.first.second;
edgeFaces(idx, 0) = it.second[0];
if (it.second.size() > 1)
{
edgeFaces(idx, 1) = it.second[1];
}
else
{
edgeFaces(idx, 1) = -1;
boundaryEdges.insert(idx);
}
idx++;
}
for (Index i = 0; i < nfaces; i++)
{
for (int j = 0; j < 3; j++)
{
Index v0 = F(i, j);
Index v1 = F(i, (j + 1) % 3);
std::pair<Index, Index> e;
e.first = std::min(v0, v1);
e.second = std::max(v0, v1);
faceEdges(i, j) = edgeidx[e];
}
}
bool *deleted = new bool[nfaces];
for (Index i = 0; i < nfaces; i++)
deleted[i] = false;
std::set<Index> deletededges;
// loop over faces
for (Index face = 0; face < nfaces; face++)
{
// stop at first undeleted face
if (deleted[face])
continue;
deleted[face] = true;
std::deque<Index> processEdges;
for (int i = 0; i < 3; i++)
{
Index e = faceEdges(face, i);
if (boundaryEdges.count(e))
continue;
int ndeleted = 0;
if (deleted[edgeFaces(e, 0)])
ndeleted++;
if (deleted[edgeFaces(e, 1)])
ndeleted++;
if (ndeleted == 1)
processEdges.push_back(e);
}
// delete all faces adjacent to edges with exactly one adjacent face
while (!processEdges.empty())
{
Index nexte = processEdges.front();
processEdges.pop_front();
Index todelete = nfaces;
if (!deleted[edgeFaces(nexte, 0)])
todelete = edgeFaces(nexte, 0);
if (!deleted[edgeFaces(nexte, 1)])
todelete = edgeFaces(nexte, 1);
if (todelete != nfaces)
{
deletededges.insert(nexte);
deleted[todelete] = true;
for (int i = 0; i < 3; i++)
{
Index e = faceEdges(todelete, i);
if (boundaryEdges.count(e))
continue;
int ndeleted = 0;
if (deleted[edgeFaces(e, 0)])
ndeleted++;
if (deleted[edgeFaces(e, 1)])
ndeleted++;
if (ndeleted == 1)
processEdges.push_back(e);
}
}
}
}
delete[] deleted;
// accumulated non-deleted edges
std::vector<Index> leftedges;
for (Index i = 0; i < nedges; i++)
{
if (!deletededges.count(i))
leftedges.push_back(i);
}
deletededges.clear();
// prune spines
std::map<Index, std::vector<Index> > spinevertedges;
for (Index i : leftedges)
{
spinevertedges[edgeVerts(i, 0)].push_back(i);
spinevertedges[edgeVerts(i, 1)].push_back(i);
}
std::deque<Index> vertsProcess;
std::map<Index, int> spinevertnbs;
for (auto it : spinevertedges)
{
spinevertnbs[it.first] = it.second.size();
if (it.second.size() == 1)
vertsProcess.push_back(it.first);
}
while (!vertsProcess.empty())
{
Index vert = vertsProcess.front();
vertsProcess.pop_front();
for (Index e : spinevertedges[vert])
{
if (!deletededges.count(e))
{
deletededges.insert(e);
for (int j = 0; j < 2; j++)
{
spinevertnbs[edgeVerts(e, j)]--;
if (spinevertnbs[edgeVerts(e, j)] == 1)
{
vertsProcess.push_back(edgeVerts(e, j));
}
}
}
}
}
std::vector<Index> loopedges;
for (Index i : leftedges)
if (!deletededges.count(i))
loopedges.push_back(i);
Index nloopedges = loopedges.size();
if (nloopedges == 0)
return;
std::map<Index, std::vector<Index> > loopvertedges;
for (Index e : loopedges)
{
loopvertedges[edgeVerts(e, 0)].push_back(e);
loopvertedges[edgeVerts(e, 1)].push_back(e);
}
std::set<Index> usededges;
for (Index e : loopedges)
{
// make a cycle or chain starting from this edge
while (!usededges.count(e))
{
std::vector<Index> cycleverts;
std::vector<Index> cycleedges;
cycleverts.push_back(edgeVerts(e, 0));
cycleverts.push_back(edgeVerts(e, 1));
cycleedges.push_back(e);
std::map<Index, Index> cycleidx;
cycleidx[cycleverts[0]] = 0;
cycleidx[cycleverts[1]] = 1;
Index curvert = edgeVerts(e, 1);
Index cure = e;
bool foundcycle = false;
while (curvert != -1 && !foundcycle)
{
Index nextvert = -1;
Index nexte = -1;
for (Index cande : loopvertedges[curvert])
{
if (!usededges.count(cande) && cande != cure)
{
int vidx = 0;
if (curvert == edgeVerts(cande, vidx))
vidx = 1;
nextvert = edgeVerts(cande, vidx);
nexte = cande;
break;
}
}
if (nextvert != -1)
{
auto it = cycleidx.find(nextvert);
if (it != cycleidx.end())
{
// we've hit outselves
std::vector<Index> cut;
for (Index i = it->second; i < cycleverts.size(); i++)
{
cut.push_back(cycleverts[i]);
}
cut.push_back(nextvert);
cuts.push_back(cut);
for (Index i = it->second; i < cycleedges.size(); i++)
{
usededges.insert(cycleedges[i]);
}
usededges.insert(nexte);
foundcycle = true;
}
else
{
cycleidx[nextvert] = cycleverts.size();
cycleverts.push_back(nextvert);
cycleedges.push_back(nexte);
}
}
curvert = nextvert;
cure = nexte;
}
if (!foundcycle)
{
// we've hit a dead end. reverse and try the other direction
std::reverse(cycleverts.begin(), cycleverts.end());
std::reverse(cycleedges.begin(), cycleedges.end());
curvert = cycleverts.back();
cure = cycleedges.back();
while (curvert != -1 && !foundcycle)
{
Index nextvert = -1;
Index nexte = -1;
for (Index cande : loopvertedges[curvert])
{
if (!usededges.count(cande) && cande != cure)
{
int vidx = 0;
if (curvert == edgeVerts(cande, vidx))
vidx = 1;
nextvert = edgeVerts(cande, vidx);
nexte = cande;
break;
}
}
if (nextvert != -1)
{
auto it = cycleidx.find(nextvert);
if (it != cycleidx.end())
{
// we've hit outselves
std::vector<int> cut;
for (Index i = it->second; i < cycleverts.size(); i++)
{
cut.push_back(cycleverts[i]);
}
cut.push_back(nextvert);
cuts.push_back(cut);
for (Index i = it->second; i < cycleedges.size(); i++)
{
usededges.insert(cycleedges[i]);
}
usededges.insert(nexte);
foundcycle = true;
}
else
{
cycleidx[nextvert] = cycleverts.size();
cycleverts.push_back(nextvert);
cycleedges.push_back(nexte);
}
}
curvert = nextvert;
cure = nexte;
}
if (!foundcycle)
{
// we've found a chain
std::vector<Index> cut;
for (Index i = 0; i < cycleverts.size(); i++)
{
cut.push_back(cycleverts[i]);
}
cuts.push_back(cut);
for (Index i = 0; i < cycleedges.size(); i++)
{
usededges.insert(cycleedges[i]);
}
}
}
}
}
}
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::cut_to_disk<Eigen::Matrix<int, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
#endif
+52
View File
@@ -0,0 +1,52 @@
#ifndef IGL_CUT_TO_DISK_H
#define IGL_CUT_TO_DISK_H
#include "igl_inline.h"
#include <Eigen/Core>
#include <vector>
namespace igl
{
// Given a triangle mesh, computes a set of edge cuts sufficient to carve the
// mesh into a topological disk, without disconnecting any connected components.
// Nothing else about the cuts (including number, total length, or smoothness)
// is guaranteed to be optimal.
//
// Simply-connected components without boundary (topological spheres) are left
// untouched (delete any edge if you really want a disk).
// All other connected components are cut into disks. Meshes with boundary are
// supported; boundary edges will be included as cuts.
//
// The cut mesh itself can be materialized using cut_mesh().
//
// Implements the triangle-deletion approach described by Gu et al's
// "Geometry Images."
//
// Template Parameters:
// Index Integrable type large enough to represent the total number of faces
// and edges in the surface represented by F, and all entries of F.
//
// Inputs:
// F #F by 3 list of the faces (must be triangles)
//
// Outputs:
// cuts List of cuts. Each cut is a sequence of vertex indices (where
// pairs of consecutive vertices share a face), is simple, and is either
// a closed loop (in which the first and last indices are identical) or
// an open curve. Cuts are edge-disjoint.
//
template <
typename DerivedF,
typename Index>
IGL_INLINE void cut_to_disk(
const Eigen::MatrixBase<DerivedF> &F,
std::vector<std::vector<Index> > &cuts);
};
#ifndef IGL_STATIC_LIBRARY
#include "cut_to_disk.cpp"
#endif
#endif
+27 -12
View File
@@ -5,14 +5,16 @@
// 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 <igl/dijkstra.h>
#include "dijkstra.h"
template <typename IndexType, typename DerivedD, typename DerivedP>
IGL_INLINE int igl::dijkstra_compute_paths(const IndexType &source,
const std::set<IndexType> &targets,
const std::vector<std::vector<IndexType> >& VV,
Eigen::PlainObjectBase<DerivedD> &min_distance,
Eigen::PlainObjectBase<DerivedP> &previous)
IGL_INLINE int igl::dijkstra(
const IndexType &source,
const std::set<IndexType> &targets,
const std::vector<std::vector<IndexType> >& VV,
const std::vector<double>& weights,
Eigen::PlainObjectBase<DerivedD> &min_distance,
Eigen::PlainObjectBase<DerivedP> &previous)
{
int numV = VV.size();
min_distance.setConstant(numV, 1, std::numeric_limits<typename DerivedD::Scalar>::infinity());
@@ -37,7 +39,7 @@ IGL_INLINE int igl::dijkstra_compute_paths(const IndexType &source,
neighbor_iter++)
{
IndexType v = *neighbor_iter;
typename DerivedD::Scalar distance_through_u = dist + 1.;
typename DerivedD::Scalar distance_through_u = dist + weights[u];
if (distance_through_u < min_distance[v]) {
vertex_queue.erase(std::make_pair(min_distance[v], v));
@@ -53,10 +55,23 @@ IGL_INLINE int igl::dijkstra_compute_paths(const IndexType &source,
return -1;
}
template <typename IndexType, typename DerivedD, typename DerivedP>
IGL_INLINE int igl::dijkstra(
const IndexType &source,
const std::set<IndexType> &targets,
const std::vector<std::vector<IndexType> >& VV,
Eigen::PlainObjectBase<DerivedD> &min_distance,
Eigen::PlainObjectBase<DerivedP> &previous)
{
std::vector<double> weights(VV.size(), 1.0);
return dijkstra(source, targets, VV, weights, min_distance, previous);
}
template <typename IndexType, typename DerivedP>
IGL_INLINE void igl::dijkstra_get_shortest_path_to(const IndexType &vertex,
const Eigen::PlainObjectBase<DerivedP> &previous,
std::vector<IndexType> &path)
IGL_INLINE void igl::dijkstra(
const IndexType &vertex,
const Eigen::MatrixBase<DerivedP> &previous,
std::vector<IndexType> &path)
{
IndexType source = vertex;
path.clear();
@@ -66,6 +81,6 @@ IGL_INLINE void igl::dijkstra_get_shortest_path_to(const IndexType &vertex,
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template int igl::dijkstra_compute_paths<int, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(int const&, std::set<int, std::less<int>, std::allocator<int> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::dijkstra_get_shortest_path_to<int, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(int const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<int, std::allocator<int> >&);
template int igl::dijkstra<int, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(int const&, std::set<int, std::less<int>, std::allocator<int> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::dijkstra<int, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(int const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::vector<int, std::allocator<int> >&);
#endif
+35 -10
View File
@@ -16,7 +16,30 @@
namespace igl {
// Dijstra's algorithm for shortest paths, with multiple targets.
// Dijkstra's algorithm for vertex-weighted shortest paths, with multiple targets.
// Adapted from http://rosettacode.org/wiki/Dijkstra%27s_algorithm .
//
// Inputs:
// source index of source vertex
// targets target vector set
// VV #V list of lists of incident vertices (adjacency list), e.g.
// as returned by igl::adjacency_list
// weights #V list of scalar vertex weights
//
// Output:
// min_distance #V by 1 list of the minimum distances from source to all vertices
// previous #V by 1 list of the previous visited vertices (for each vertex) - used for backtracking
//
template <typename IndexType, typename DerivedD, typename DerivedP>
IGL_INLINE int dijkstra(
const IndexType &source,
const std::set<IndexType> &targets,
const std::vector<std::vector<IndexType> >& VV,
const std::vector<double>& weights,
Eigen::PlainObjectBase<DerivedD> &min_distance,
Eigen::PlainObjectBase<DerivedP> &previous);
// Dijkstra's algorithm for shortest paths, with multiple targets.
// Adapted from http://rosettacode.org/wiki/Dijkstra%27s_algorithm .
//
// Inputs:
@@ -30,13 +53,14 @@ namespace igl {
// previous #V by 1 list of the previous visited vertices (for each vertex) - used for backtracking
//
template <typename IndexType, typename DerivedD, typename DerivedP>
IGL_INLINE int dijkstra_compute_paths(const IndexType &source,
const std::set<IndexType> &targets,
const std::vector<std::vector<IndexType> >& VV,
Eigen::PlainObjectBase<DerivedD> &min_distance,
Eigen::PlainObjectBase<DerivedP> &previous);
IGL_INLINE int dijkstra(
const IndexType &source,
const std::set<IndexType> &targets,
const std::vector<std::vector<IndexType> >& VV,
Eigen::PlainObjectBase<DerivedD> &min_distance,
Eigen::PlainObjectBase<DerivedP> &previous);
// Backtracking after Dijstra's algorithm, to find shortest path.
// Backtracking after Dijkstra's algorithm, to find shortest path.
//
// Inputs:
// vertex vertex to which we want the shortest path (from same source as above)
@@ -46,9 +70,10 @@ namespace igl {
// path #P by 1 list of vertex indices in the shortest path from source to vertex
//
template <typename IndexType, typename DerivedP>
IGL_INLINE void dijkstra_get_shortest_path_to(const IndexType &vertex,
const Eigen::PlainObjectBase<DerivedP> &previous,
std::vector<IndexType> &path);
IGL_INLINE void dijkstra(
const IndexType &vertex,
const Eigen::MatrixBase<DerivedP> &previous,
std::vector<IndexType> &path);
};
+9 -15
View File
@@ -1,5 +1,6 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2018 Alec Jacobson <alecjacobson@gmail.com>
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
@@ -16,31 +17,24 @@ IGL_INLINE std::string igl::dirname(const std::string & path)
{
return std::string("");
}
#if defined (WIN32)
char del('\\');
#else
char del('/');
#endif
// http://stackoverflow.com/questions/5077693/dirnamephp-similar-function-in-c
std::string::const_reverse_iterator last_slash =
std::find(
path.rbegin(),
path.rend(),del);
if( last_slash == path.rend() )
// https://stackoverflow.com/a/3071694/148668
size_t found = path.find_last_of("/\\");
if(found == std::string::npos)
{
// No slashes found
return std::string(".");
}else if(1 == (last_slash.base() - path.begin()))
}else if(found == 0)
{
// Slash is first char
return std::string(&del);
}else if(path.end() == last_slash.base() )
return std::string(path.begin(),path.begin()+1);
}else if(found == path.length()-1)
{
// Slash is last char
std::string redo = std::string(path.begin(),path.end()-1);
return igl::dirname(redo);
}
return std::string(path.begin(),last_slash.base()-1);
// Return everything up to but not including last slash
return std::string(path.begin(),path.begin()+found);
}
+5
View File
@@ -1,5 +1,6 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2018 Alec Jacobson <alecjacobson@gmail.com>
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
@@ -19,6 +20,10 @@ namespace igl
// Returns string containing dirname (see php's dirname)
//
// See also: basename, pathinfo
//
// **Note:** This function will have undefined behavior if **file names** in
// the path contain \ and / characters. This function interprets \ and / as
// file path separators.
IGL_INLINE std::string dirname(const std::string & path);
}
+6 -5
View File
@@ -1,9 +1,9 @@
// 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
//
// 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 "edges.h"
#include "adjacency_matrix.h"
@@ -11,7 +11,7 @@
template <typename DerivedF, typename DerivedE>
IGL_INLINE void igl::edges(
const Eigen::MatrixBase<DerivedF> & F,
const Eigen::MatrixBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedE> & E)
{
// build adjacency matrix
@@ -44,4 +44,5 @@ IGL_INLINE void igl::edges(
// Explicit template instantiation
template void igl::edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
template void igl::edges<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::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> >&);
#endif
File diff suppressed because it is too large Load Diff
@@ -1 +0,0 @@
a0c5a93d2bc144890fbfa8d5e413d4dddc4a2827
+7
View File
@@ -14,6 +14,8 @@ namespace igl
{
// Compute connected components of facets based on edge-edge adjacency.
//
// For connected components on vertices see igl::vertex_components
//
// Inputs:
// F #F by 3 list of triangle indices
// Outputs:
@@ -22,6 +24,11 @@ namespace igl
IGL_INLINE void facet_components(
const Eigen::PlainObjectBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedC> & C);
// Compute connected components of facets based on edge-edge adjacency.
//
// For connected components on vertices see igl::vertex_components
//
// Inputs:
// TT #TT by 3 list of list of adjacency triangles (see
// triangle_triangle_adjacency.h)
+3
View File
@@ -102,4 +102,7 @@ namespace igl {
#ifdef IGL_STATIC_LIBRARY
template void igl::knn<Eigen::Matrix<double, -1, -1, 0, -1, -1>, int, int, Eigen::Matrix<int, -1, 8, 0, -1, 8>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, 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&, int const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 8, 0, -1, 8> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
#endif
-137
View File
@@ -1,137 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2014 Christian Schüller <schuellchr@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 "lim.h"
#include <LIMSolverInterface.h>
IGL_INLINE igl::lim::State igl::lim::lim(
Eigen::Matrix<double,Eigen::Dynamic,3>& vertices,
const Eigen::Matrix<double,Eigen::Dynamic,3>& initialVertices,
const Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic>& elements,
const Eigen::SparseMatrix<double>& constraintMatrix,
const Eigen::Matrix<double,Eigen::Dynamic,1>& constraintTargets,
Energy energyType,
double tolerance,
int maxIteration,
bool findLocalMinima)
{
return (State)ComputeLIM(
vertices,
initialVertices,
elements,
constraintMatrix,
constraintTargets,
(EnergyType)energyType,
tolerance,
maxIteration,
findLocalMinima
);
}
IGL_INLINE igl::lim::State igl::lim::lim(
Eigen::Matrix<double,Eigen::Dynamic,3>& vertices,
const Eigen::Matrix<double,Eigen::Dynamic,3>& initialVertices,
const Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic>& elements,
const Eigen::SparseMatrix<double>& constraintMatrix,
const Eigen::Matrix<double,Eigen::Dynamic,1>& constraintTargets,
Energy energyType,
double tolerance,
int maxIteration,
bool findLocalMinima,
bool enableOuput,
bool enableBarriers,
bool enableAlphaUpdate,
double beta,
double eps)
{
return (State)ComputeLIM(
vertices,
initialVertices,
elements,
constraintMatrix,
constraintTargets,
(EnergyType)energyType,
tolerance,
maxIteration,
findLocalMinima,
enableOuput,
enableBarriers,
enableAlphaUpdate,
beta,
eps
);
}
IGL_INLINE igl::lim::State igl::lim::lim(
Eigen::Matrix<double,Eigen::Dynamic,3>& vertices,
const Eigen::Matrix<double,Eigen::Dynamic,3>& initialVertices,
const Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic>& elements,
const std::vector<int>& borderVertices,
const Eigen::Matrix<double,Eigen::Dynamic,1>& gradients,
const Eigen::SparseMatrix<double>& constraintMatrix,
const Eigen::Matrix<double,Eigen::Dynamic,1>& constraintTargets,
Energy energyType,
double tolerance,
int maxIteration,
bool findLocalMinima)
{
return (State)ComputeLIM(
vertices,
initialVertices,
elements,
borderVertices,
gradients,
constraintMatrix,
constraintTargets,
(EnergyType)energyType,
tolerance,
maxIteration,
findLocalMinima
);
}
IGL_INLINE igl::lim::State igl::lim::lim(
Eigen::Matrix<double,Eigen::Dynamic,3>& vertices,
const Eigen::Matrix<double,Eigen::Dynamic,3>& initialVertices,
const Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic>& elements,
const std::vector<int>& borderVertices,
const Eigen::Matrix<double,Eigen::Dynamic,1>& gradients,
const Eigen::SparseMatrix<double>& constraintMatrix,
const Eigen::Matrix<double,Eigen::Dynamic,1>& constraintTargets,
Energy energyType,
double tolerance,
int maxIteration,
bool findLocalMinima,
bool enableOuput,
bool enableBarriers,
bool enableAlphaUpdate,
double beta,
double eps)
{
return (State)ComputeLIM(
vertices,
initialVertices,
elements,
borderVertices,
gradients,
constraintMatrix,
constraintTargets,
(EnergyType)energyType,
tolerance,
maxIteration,
findLocalMinima,
enableOuput,
enableBarriers,
enableAlphaUpdate,
beta,
eps);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#endif
-133
View File
@@ -1,133 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2014 Christian Schüller <schuellchr@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_LIM_LIM_H
#define IGL_LIM_LIM_H
#include <igl/igl_inline.h>
#include <Eigen/Core>
#include <Eigen/Sparse>
namespace igl
{
namespace lim
{
// Computes a locally injective mapping of a triangle or tet-mesh based on
// a deformation energy subject to some provided linear positional
// constraints Cv-d.
//
// Inputs:
// vertices vx3 matrix containing vertex position of the mesh
// initialVertices vx3 matrix containing vertex position of initial
// rest pose mesh
// elements exd matrix containing vertex indices of all elements
// borderVertices (only needed for 2D LSCM) vector containing indices
// of border vertices
// gradients (only needed for 2D Poisson) vector containing
// partial derivatives of target element gradients
// (structure is: [xx_0, xy_0, xx_1, xy_1, ..., xx_v,
// xy_v, yx_0, yy_0, yx_1, yy_1, ..., yx_v, yy_v]')
// constraintMatrix C: (c)x(v*(d-1)) sparse linear positional constraint
// matrix. X an Y-coordinates are alternatingly stacked
// per row (structure for triangles: [x_1, y_1, x_2,
// y_2, ..., x_v,y_v])
// constraintTargets d: c vector target positions
// energyType type of used energy:
// Dirichlet, Laplacian, Green, ARAP, LSCM, Poisson (only 2D), UniformLaplacian, Identity
// tolerance max squared positional constraints error
// maxIteration max number of iterations
// findLocalMinima iterating until a local minima is found. If not
// enabled only tolerance must be fulfilled.
// enableOutput (optional) enables the output (#iteration / hessian correction / step size / positional constraints / barrier constraints / deformation energy) (default : true)
// enableBarriers (optional) enables the non-flip constraints (default = true)
// enableAlphaUpdate (optional) enables dynamic alpha weight adjustment (default = true)
// beta (optional) steepness factor of barrier slopes (default: ARAP/LSCM = 0.01, Green = 1)
// eps (optional) smallest valid triangle area (default: 1e-5 * smallest triangle)
//
// where:
// v : # vertices
// c : # linear constraints
// e : # elements of mesh
// d : # vertices per element (triangle = 3, tet = 4)
//--------------------------------------------------------------------------
// Output:
// vertices vx3 matrix containing resulting vertex position of the
// mesh
//--------------------------------------------------------------------------
// Return values:
// Succeeded : Successful optimization with fulfilled tolerance
// LocalMinima : Convergenged to a local minima / tolerance not fulfilled
// IterationLimit : Max iteration reached before tolerance was fulfilled
// Infeasible : not feasible -> has inverted elements (decrease eps?)
enum Energy { Dirichlet = 0, Laplacian=1, Green=2, ARAP=3, LSCM=4, Poisson=5, UniformLaplacian=6, Identity=7 };
enum State { Uninitialized = -4, Infeasible = -3, IterationLimit = -2, LocalMinima = -1, Running = 0, Succeeded = 1 };
State lim(
Eigen::Matrix<double,Eigen::Dynamic,3>& vertices,
const Eigen::Matrix<double,Eigen::Dynamic,3>& initialVertices,
const Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic>& elements,
const Eigen::SparseMatrix<double>& constraintMatrix,
const Eigen::Matrix<double,Eigen::Dynamic,1>& constraintTargets,
Energy energyType,
double tolerance,
int maxIteration,
bool findLocalMinima);
State lim(
Eigen::Matrix<double,Eigen::Dynamic,3>& vertices,
const Eigen::Matrix<double,Eigen::Dynamic,3>& initialVertices,
const Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic>& elements,
const Eigen::SparseMatrix<double>& constraintMatrix,
const Eigen::Matrix<double,Eigen::Dynamic,1>& constraintTargets,
Energy energyType,
double tolerance,
int maxIteration,
bool findLocalMinima,
bool enableOuput,
bool enableBarriers,
bool enableAlphaUpdate,
double beta,
double eps);
State lim(
Eigen::Matrix<double,Eigen::Dynamic,3>& vertices,
const Eigen::Matrix<double,Eigen::Dynamic,3>& initialVertices,
const Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic>& elements,
const std::vector<int>& borderVertices,
const Eigen::Matrix<double,Eigen::Dynamic,1>& gradients,
const Eigen::SparseMatrix<double>& constraintMatrix,
const Eigen::Matrix<double,Eigen::Dynamic,1>& constraintTargets,
Energy energyType,
double tolerance,
int maxIteration,
bool findLocalMinima);
State lim(
Eigen::Matrix<double,Eigen::Dynamic,3>& vertices,
const Eigen::Matrix<double,Eigen::Dynamic,3>& initialVertices,
const Eigen::Matrix<int,Eigen::Dynamic,Eigen::Dynamic>& elements,
const std::vector<int>& borderVertices,
const Eigen::Matrix<double,Eigen::Dynamic,1>& gradients,
const Eigen::SparseMatrix<double>& constraintMatrix,
const Eigen::Matrix<double,Eigen::Dynamic,1>& constraintTargets,
Energy energyType,
double tolerance,
int maxIteration,
bool findLocalMinima,
bool enableOuput,
bool enableBarriers,
bool enableAlphaUpdate,
double beta,
double eps);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "lim.cpp"
#endif
#endif
@@ -0,0 +1,141 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2018 Zhongshi Jiang <jiangzs@nyu.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 "mapping_energy_with_jacobians.h"
#include "polar_svd.h"
IGL_INLINE double igl::mapping_energy_with_jacobians(
const Eigen::MatrixXd &Ji,
const Eigen::VectorXd &areas,
igl::MappingEnergyType slim_energy,
double exp_factor){
double energy = 0;
if (Ji.cols() == 4)
{
Eigen::Matrix<double, 2, 2> ji;
for (int i = 0; i < Ji.rows(); i++)
{
ji(0, 0) = Ji(i, 0);
ji(0, 1) = Ji(i, 1);
ji(1, 0) = Ji(i, 2);
ji(1, 1) = Ji(i, 3);
typedef Eigen::Matrix<double, 2, 2> Mat2;
typedef Eigen::Matrix<double, 2, 1> Vec2;
Mat2 ri, ti, ui, vi;
Vec2 sing;
igl::polar_svd(ji, ri, ti, ui, sing, vi);
double s1 = sing(0);
double s2 = sing(1);
switch (slim_energy)
{
case igl::MappingEnergyType::ARAP:
{
energy += areas(i) * (pow(s1 - 1, 2) + pow(s2 - 1, 2));
break;
}
case igl::MappingEnergyType::SYMMETRIC_DIRICHLET:
{
energy += areas(i) * (pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2));
break;
}
case igl::MappingEnergyType::EXP_SYMMETRIC_DIRICHLET:
{
energy += areas(i) * exp(exp_factor * (pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2)));
break;
}
case igl::MappingEnergyType::LOG_ARAP:
{
energy += areas(i) * (pow(log(s1), 2) + pow(log(s2), 2));
break;
}
case igl::MappingEnergyType::CONFORMAL:
{
energy += areas(i) * ((pow(s1, 2) + pow(s2, 2)) / (2 * s1 * s2));
break;
}
case igl::MappingEnergyType::EXP_CONFORMAL:
{
energy += areas(i) * exp(exp_factor * ((pow(s1, 2) + pow(s2, 2)) / (2 * s1 * s2)));
break;
}
}
}
}
else
{
Eigen::Matrix<double, 3, 3> ji;
for (int i = 0; i < Ji.rows(); i++)
{
ji(0, 0) = Ji(i, 0);
ji(0, 1) = Ji(i, 1);
ji(0, 2) = Ji(i, 2);
ji(1, 0) = Ji(i, 3);
ji(1, 1) = Ji(i, 4);
ji(1, 2) = Ji(i, 5);
ji(2, 0) = Ji(i, 6);
ji(2, 1) = Ji(i, 7);
ji(2, 2) = Ji(i, 8);
typedef Eigen::Matrix<double, 3, 3> Mat3;
typedef Eigen::Matrix<double, 3, 1> Vec3;
Mat3 ri, ti, ui, vi;
Vec3 sing;
igl::polar_svd(ji, ri, ti, ui, sing, vi);
double s1 = sing(0);
double s2 = sing(1);
double s3 = sing(2);
switch (slim_energy)
{
case igl::MappingEnergyType::ARAP:
{
energy += areas(i) * (pow(s1 - 1, 2) + pow(s2 - 1, 2) + pow(s3 - 1, 2));
break;
}
case igl::MappingEnergyType::SYMMETRIC_DIRICHLET:
{
energy += areas(i) * (pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2) + pow(s3, 2) + pow(s3, -2));
break;
}
case igl::MappingEnergyType::EXP_SYMMETRIC_DIRICHLET:
{
energy += areas(i) * exp(exp_factor *
(pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2) + pow(s3, 2) + pow(s3, -2)));
break;
}
case igl::MappingEnergyType::LOG_ARAP:
{
energy += areas(i) * (pow(log(s1), 2) + pow(log(std::abs(s2)), 2) + pow(log(std::abs(s3)), 2));
break;
}
case igl::MappingEnergyType::CONFORMAL:
{
energy += areas(i) * ((pow(s1, 2) + pow(s2, 2) + pow(s3, 2)) / (3 * pow(s1 * s2 * s3, 2. / 3.)));
break;
}
case igl::MappingEnergyType::EXP_CONFORMAL:
{
energy += areas(i) * exp((pow(s1, 2) + pow(s2, 2) + pow(s3, 2)) / (3 * pow(s1 * s2 * s3, 2. / 3.)));
break;
}
}
}
}
return energy;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#endif
@@ -0,0 +1,36 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2018 Zhongshi Jiang <jiangzs@nyu.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_MAPPING_ENERGY_WITH_JACOBIANS_H
#define IGL_MAPPING_ENERGY_WITH_JACOBIANS_H
#include "igl_inline.h"
#include <Eigen/Dense>
#include "MappingEnergyType.h"
namespace igl
{
// compute the rotation-invariant energy of a mapping (represented in Jacobians and areas)
// Input:
// Ji: #F by 4 (9 if 3D) entries of jacobians
// areas: #F by 1 face areas
// slim_energy: energy type as in igl::MappingEnergyType
// exp_factor: see igl::MappingEnergyType
//
// Output:
// energy value
IGL_INLINE double mapping_energy_with_jacobians(const Eigen::MatrixXd &Ji,
const Eigen::VectorXd &areas,
igl::MappingEnergyType slim_energy,
double exp_factor);
}
#ifndef IGL_STATIC_LIBRARY
# include "mapping_energy_with_jacobians.cpp"
#endif
#endif
+194
View File
@@ -0,0 +1,194 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2018 Francis Williams <francis@fwilliams.info>
//
// 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 "marching_tets.h"
#include <unordered_map>
#include <vector>
#include <utility>
#include <cstdint>
#include <iostream>
template <typename DerivedTV,
typename DerivedTT,
typename DerivedS,
typename DerivedSV,
typename DerivedSF,
typename DerivedJ,
typename BCType>
void igl::marching_tets(
const Eigen::PlainObjectBase<DerivedTV>& TV,
const Eigen::PlainObjectBase<DerivedTT>& TT,
const Eigen::PlainObjectBase<DerivedS>& isovals,
double isovalue,
Eigen::PlainObjectBase<DerivedSV>& outV,
Eigen::PlainObjectBase<DerivedSF>& outF,
Eigen::PlainObjectBase<DerivedJ>& J,
Eigen::SparseMatrix<BCType>& BC)
{
using namespace std;
// We're hashing edges to deduplicate using 64 bit ints. The upper and lower
// 32 bits of a key are the indices of vertices in the mesh. The implication is
// that you can only have 2^32 vertices which I have deemed sufficient for
// anything reasonable.
const auto make_edge_key = [](const pair<int32_t, int32_t>& p) -> int64_t
{
std::int64_t ret = 0;
ret |= p.first;
ret |= static_cast<std::int64_t>(p.second) << 32;
return ret;
};
const int mt_cell_lookup[16][4] =
{
{ -1, -1, -1, -1 },
{ 0, 2, 1, -1 },
{ 0, 3, 4, -1 },
{ 2, 1, 3, 4 },
{ 5, 3, 1, -1 },
{ 0, 2, 5, 3 },
{ 0, 1, 5, 4 },
{ 2, 5, 4, -1 },
{ 4, 5, 2, -1 },
{ 0, 4, 5, 1 },
{ 0, 3, 5, 2 },
{ 1, 3, 5, -1 },
{ 4, 3, 1, 2 },
{ 0, 4, 3, -1 },
{ 0, 1, 2, -1 },
{ -1, -1, -1, -1 },
};
const int mt_edge_lookup[6][2] =
{
{0, 1},
{0, 2},
{0, 3},
{1, 2},
{1, 3},
{2, 3},
};
// Store the faces and the tet they are in
vector<pair<Eigen::RowVector3i, int>> faces;
// Store the edges in the tet mesh which we add vertices on
// so we can deduplicate
vector<pair<int, int>> edge_table;
assert(TT.cols() == 4 && TT.rows() >= 1);
assert(TV.cols() == 3 && TV.rows() >= 4);
assert(isovals.cols() == 1);
// For each tet
for (int i = 0; i < TT.rows(); i++)
{
uint8_t key = 0;
for (int v = 0; v < 4; v++)
{
const int vid = TT(i, v);
const uint8_t flag = isovals[vid] > isovalue;
key |= flag << v;
}
// This will contain the index in TV of each vertex in the tet
int v_ids[4] = {-1, -1, -1, -1};
// Insert any vertices if the tet intersects the level surface
for (int e = 0; e < 4 && mt_cell_lookup[key][e] != -1; e++)
{
const int tv1_idx = TT(i, mt_edge_lookup[mt_cell_lookup[key][e]][0]);
const int tv2_idx = TT(i, mt_edge_lookup[mt_cell_lookup[key][e]][1]);
const int vertex_id = edge_table.size();
edge_table.push_back(make_pair(min(tv1_idx, tv2_idx), max(tv1_idx, tv2_idx)));
v_ids[e] = vertex_id;
}
// Insert the corresponding faces
if (v_ids[0] != -1)
{
bool is_quad = mt_cell_lookup[key][3] != -1;
if (is_quad)
{
const Eigen::RowVector3i f1(v_ids[0], v_ids[1], v_ids[3]);
const Eigen::RowVector3i f2(v_ids[1], v_ids[2], v_ids[3]);
faces.push_back(make_pair(f1, i));
faces.push_back(make_pair(f2, i));
}
else
{
const Eigen::RowVector3i f(v_ids[0], v_ids[1], v_ids[2]);
faces.push_back(make_pair(f, i));
}
}
}
int num_unique = 0;
outV.resize(edge_table.size(), 3);
outF.resize(faces.size(), 3);
J.resize(faces.size());
// Sparse matrix triplets for BC
vector<Eigen::Triplet<BCType>> bc_triplets;
bc_triplets.reserve(edge_table.size());
// Deduplicate vertices
unordered_map<int64_t, int> emap;
emap.max_load_factor(0.5);
emap.reserve(edge_table.size());
for (int f = 0; f < faces.size(); f++)
{
for (int v = 0; v < 3; v++)
{
const int vi = faces[f].first[v];
const int ti = faces[f].second;
const pair<int32_t, int32_t> edge = edge_table[vi];
const int64_t key = make_edge_key(edge);
auto it = emap.find(key);
if (it == emap.end()) // New unique vertex, insert it
{
// Typedef to make sure we handle floats properly
typedef Eigen::Matrix<typename DerivedTV::Scalar, 1, 3, Eigen::RowMajor, 1, 3> RowVector;
const RowVector v1 = TV.row(edge.first);
const RowVector v2 = TV.row(edge.second);
const double a = fabs(isovals[edge.first] - isovalue);
const double b = fabs(isovals[edge.second] - isovalue);
const double w = a / (a+b);
// Create a casted copy in case BCType is a float and we need to downcast
const BCType bc_w = static_cast<BCType>(w);
bc_triplets.push_back(Eigen::Triplet<BCType>(num_unique, edge.first, 1-bc_w));
bc_triplets.push_back(Eigen::Triplet<BCType>(num_unique, edge.second, bc_w));
// Create a casted copy in case DerivedTV::Scalar is a float and we need to downcast
const typename DerivedTV::Scalar v_w = static_cast<typename DerivedTV::Scalar>(w);
outV.row(num_unique) = (1-v_w)*v1 + v_w*v2;
outF(f, v) = num_unique;
J[f] = ti;
emap.emplace(key, num_unique);
num_unique += 1;
} else {
outF(f, v) = it->second;
}
}
}
outV.conservativeResize(num_unique, 3);
J.conservativeResize(num_unique, 1);
BC.resize(num_unique, TV.rows());
BC.setFromTriplets(bc_triplets.begin(), bc_triplets.end());
}
#ifdef IGL_STATIC_LIBRARY
template void igl::marching_tets<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<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, double>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, double, 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::SparseMatrix<double, 0, int>&);
#endif // IGL_STATIC_LIBRARY
+196
View File
@@ -0,0 +1,196 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2018 Francis Williams <francis@fwilliams.info>
//
// 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_MARCHING_TETS_H
#define IGL_MARCHING_TETS_H
#include "igl_inline.h"
#include <Eigen/Core>
#include <Eigen/Sparse>
namespace igl {
// marching_tets( TV, TT, S, isovalue, SV, SF, J, BC)
//
// performs the marching tetrahedra algorithm on a tet mesh defined by TV and
// TT with scalar values defined at each vertex in TV. The output is a
// triangle mesh approximating the isosurface coresponding to the value
// isovalue.
//
// Input:
// TV #tet_vertices x 3 array -- The vertices of the tetrahedral mesh
// TT #tets x 4 array -- The indexes of each tet in the tetrahedral mesh
// S #tet_vertices x 1 array -- The values defined on each tet vertex
// isovalue scalar -- The isovalue of the level set we want to compute
//
// Output:
// SV #SV x 3 array -- The vertices of the output level surface mesh
// SF #SF x 3 array -- The face indexes of the output level surface mesh
// J #SF list of indices into TT revealing which tet each face comes from
// BC #SV x #TV list of barycentric coordinates so that SV = BC*TV
template <typename DerivedTV,
typename DerivedTT,
typename DerivedS,
typename DerivedSV,
typename DerivedSF,
typename DerivedJ,
typename BCType>
IGL_INLINE void marching_tets(
const Eigen::PlainObjectBase<DerivedTV>& TV,
const Eigen::PlainObjectBase<DerivedTT>& TT,
const Eigen::PlainObjectBase<DerivedS>& S,
double isovalue,
Eigen::PlainObjectBase<DerivedSV>& SV,
Eigen::PlainObjectBase<DerivedSF>& SF,
Eigen::PlainObjectBase<DerivedJ>& J,
Eigen::SparseMatrix<BCType>& BC);
// marching_tets( TV, TT, S, SV, SF, J, BC)
//
// Performs the marching tetrahedra algorithm on a tet mesh defined by TV and
// TT with scalar values defined at each vertex in TV. The output is a
// triangle mesh approximating the isosurface coresponding to an isovalue of 0.
//
// Input:
// TV #tet_vertices x 3 array -- The vertices of the tetrahedral mesh
// TT #tets x 4 array -- The indexes of each tet in the tetrahedral mesh
// S #tet_vertices x 1 array -- The values defined on each tet vertex
// isovalue scalar -- The isovalue of the level set we want to compute
//
// Output:
// SV #SV x 3 array -- The vertices of the output level surface mesh
// SF #SF x 3 array -- The face indexes of the output level surface mesh
// J #SF list of indices into TT revealing which tet each face comes from
// BC #SV x #TV list of barycentric coordinates so that SV = BC*TV
template <typename DerivedTV,
typename DerivedTT,
typename DerivedS,
typename DerivedSV,
typename DerivedSF,
typename DerivedJ,
typename BCType>
IGL_INLINE void marching_tets(
const Eigen::PlainObjectBase<DerivedTV>& TV,
const Eigen::PlainObjectBase<DerivedTT>& TT,
const Eigen::PlainObjectBase<DerivedS>& S,
Eigen::PlainObjectBase<DerivedSV>& SV,
Eigen::PlainObjectBase<DerivedSF>& SF,
Eigen::PlainObjectBase<DerivedJ>& J,
Eigen::SparseMatrix<BCType>& BC) {
return igl::marching_tets(TV, TT, S, 0.0, SV, SF, J, BC);
}
// marching_tets( TV, TT, S, isovalue, SV, SF, J)
//
// performs the marching tetrahedra algorithm on a tet mesh defined by TV and
// TT with scalar values defined at each vertex in TV. The output is a
// triangle mesh approximating the isosurface coresponding to the value
// isovalue.
//
// Input:
// TV #tet_vertices x 3 array -- The vertices of the tetrahedral mesh
// TT #tets x 4 array -- The indexes of each tet in the tetrahedral mesh
// S #tet_vertices x 1 array -- The values defined on each tet vertex
// isovalue scalar -- The isovalue of the level set we want to compute
//
// Output:
// SV #SV x 3 array -- The vertices of the output level surface mesh
// SF #SF x 3 array -- The face indexes of the output level surface mesh
// J #SF list of indices into TT revealing which tet each face comes from
template <typename DerivedTV,
typename DerivedTT,
typename DerivedS,
typename DerivedSV,
typename DerivedSF,
typename DerivedJ>
IGL_INLINE void marching_tets(
const Eigen::PlainObjectBase<DerivedTV>& TV,
const Eigen::PlainObjectBase<DerivedTT>& TT,
const Eigen::PlainObjectBase<DerivedS>& S,
double isovalue,
Eigen::PlainObjectBase<DerivedSV>& SV,
Eigen::PlainObjectBase<DerivedSF>& SF,
Eigen::PlainObjectBase<DerivedJ>& J) {
Eigen::SparseMatrix<double> _BC;
return igl::marching_tets(TV, TT, S, isovalue, SV, SF, J, _BC);
}
// marching_tets( TV, TT, S, isovalue, SV, SF, BC)
//
// performs the marching tetrahedra algorithm on a tet mesh defined by TV and
// TT with scalar values defined at each vertex in TV. The output is a
// triangle mesh approximating the isosurface coresponding to the value
// isovalue.
//
// Input:
// TV #tet_vertices x 3 array -- The vertices of the tetrahedral mesh
// TT #tets x 4 array -- The indexes of each tet in the tetrahedral mesh
// S #tet_vertices x 1 array -- The values defined on each tet vertex
// isovalue scalar -- The isovalue of the level set we want to compute
//
// Output:
// SV #SV x 3 array -- The vertices of the output level surface mesh
// SF #SF x 3 array -- The face indexes of the output level surface mesh
// BC #SV x #TV list of barycentric coordinates so that SV = BC*TV
template <typename DerivedTV,
typename DerivedTT,
typename DerivedS,
typename DerivedSV,
typename DerivedSF,
typename BCType>
IGL_INLINE void marching_tets(
const Eigen::PlainObjectBase<DerivedTV>& TV,
const Eigen::PlainObjectBase<DerivedTT>& TT,
const Eigen::PlainObjectBase<DerivedS>& S,
double isovalue,
Eigen::PlainObjectBase<DerivedSV>& SV,
Eigen::PlainObjectBase<DerivedSF>& SF,
Eigen::SparseMatrix<BCType>& BC) {
Eigen::VectorXi _J;
return igl::marching_tets(TV, TT, S, isovalue, SV, SF, _J, BC);
}
// marching_tets( TV, TT, S, isovalue, SV, SF)
//
// performs the marching tetrahedra algorithm on a tet mesh defined by TV and
// TT with scalar values defined at each vertex in TV. The output is a
// triangle mesh approximating the isosurface coresponding to the value
// isovalue.
//
// Input:
// TV #tet_vertices x 3 array -- The vertices of the tetrahedral mesh
// TT #tets x 4 array -- The indexes of each tet in the tetrahedral mesh
// S #tet_vertices x 1 array -- The values defined on each tet vertex
// isovalue scalar -- The isovalue of the level set we want to compute
//
// Output:
// SV #SV x 3 array -- The vertices of the output level surface mesh
// SF #SF x 3 array -- The face indexes of the output level surface mesh
template <typename DerivedTV,
typename DerivedTT,
typename DerivedS,
typename DerivedSV,
typename DerivedSF>
IGL_INLINE void marching_tets(
const Eigen::PlainObjectBase<DerivedTV>& TV,
const Eigen::PlainObjectBase<DerivedTT>& TT,
const Eigen::PlainObjectBase<DerivedS>& S,
double isovalue,
Eigen::PlainObjectBase<DerivedSV>& SV,
Eigen::PlainObjectBase<DerivedSF>& SF) {
Eigen::VectorXi _J;
Eigen::SparseMatrix<double> _BC;
return igl::marching_tets(TV, TT, S, isovalue, SV, SF, _J, _BC);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "marching_tets.cpp"
#endif
#endif // IGL_MARCHING_TETS_H
+1 -1
View File
@@ -35,7 +35,7 @@ namespace igl
// Scalar scalar type for eigen sparse matrix (e.g. double)
// Inputs:
// V #V by dim list of mesh vertex positions
// F #F by simplex_size list of mesh faces (must be triangles)
// F #F by simplex_size list of mesh elements (triangles or tetrahedra)
// type one of the following ints:
// MASSMATRIX_TYPE_BARYCENTRIC barycentric
// MASSMATRIX_TYPE_VORONOI voronoi-hybrid {default}
+5 -4
View File
@@ -1,9 +1,9 @@
// 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
//
// 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 "median.h"
#include "matrix_to_list.h"
@@ -42,4 +42,5 @@ IGL_INLINE bool igl::median(
template bool igl::median<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1>, -1, 1, true>, float>(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<float, -1, -1, 0, -1, -1>, -1, 1, true> > const&, float&);
// generated by autoexplicit.sh
template bool igl::median<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true>, double>(Eigen::MatrixBase<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true> > const&, double&);
template bool igl::median<Eigen::Matrix<double, -1, 1, 0, -1, 1>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, double&);
#endif
+6 -2
View File
@@ -90,7 +90,7 @@ namespace igl {
std::function< void(const ChildrenType, const int) > helper;
helper = [&helper,&translate_center,&get_octant,&m,
&zero_to_seven,&neg_ones,&P,
&point_indices,&children,&centers,&widths]
&point_indices,&children,&centers,&widths,&MAX_DEPTH]
(const ChildrenType index, const int depth)-> void
{
if(point_indices.at(index).size() > 1 && depth < MAX_DEPTH){
@@ -173,4 +173,8 @@ namespace igl {
}
}
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::octree<Eigen::Matrix<double, -1, -1, 0, -1, -1>, int, Eigen::Matrix<int, -1, 8, 0, -1, 8>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 8, 0, -1, 8> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
#endif
+1 -1
View File
@@ -112,7 +112,7 @@ IGL_INLINE void igl::opengl::ViewerCore::draw(
/* Bind and potentially refresh mesh/line/point data */
if (data.dirty)
{
data.updateGL(data, data.invert_normals,data.meshgl);
data.updateGL(data, data.invert_normals, data.meshgl);
data.dirty = MeshGL::DIRTY_NONE;
}
data.meshgl.bind_mesh();
+41 -38
View File
@@ -145,6 +145,7 @@ namespace glfw
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
#endif
if(fullscreen)
{
@@ -477,10 +478,6 @@ namespace glfw
IGL_INLINE bool Viewer::key_pressed(unsigned int unicode_key,int modifiers)
{
if (callback_key_pressed)
if (callback_key_pressed(*this,unicode_key,modifiers))
return true;
for (unsigned int i = 0; i<plugins.size(); ++i)
{
if (plugins[i]->key_pressed(unicode_key, modifiers))
@@ -489,6 +486,10 @@ namespace glfw
}
}
if (callback_key_pressed)
if (callback_key_pressed(*this,unicode_key,modifiers))
return true;
switch(unicode_key)
{
case 'A':
@@ -563,25 +564,27 @@ namespace glfw
IGL_INLINE bool Viewer::key_down(int key,int modifiers)
{
if (callback_key_down)
if (callback_key_down(*this,key,modifiers))
return true;
for (unsigned int i = 0; i<plugins.size(); ++i)
if (plugins[i]->key_down(key, modifiers))
return true;
if (callback_key_down)
if (callback_key_down(*this,key,modifiers))
return true;
return false;
}
IGL_INLINE bool Viewer::key_up(int key,int modifiers)
{
if (callback_key_up)
if (callback_key_up(*this,key,modifiers))
return true;
for (unsigned int i = 0; i<plugins.size(); ++i)
if (plugins[i]->key_up(key, modifiers))
return true;
if (callback_key_up)
if (callback_key_up(*this,key,modifiers))
return true;
return false;
}
@@ -591,14 +594,14 @@ namespace glfw
down_mouse_x = current_mouse_x;
down_mouse_y = current_mouse_y;
if (callback_mouse_down)
if (callback_mouse_down(*this,static_cast<int>(button),modifier))
return true;
for (unsigned int i = 0; i<plugins.size(); ++i)
if(plugins[i]->mouse_down(static_cast<int>(button),modifier))
return true;
if (callback_mouse_down)
if (callback_mouse_down(*this,static_cast<int>(button),modifier))
return true;
down = true;
down_translation = core.camera_translation;
@@ -651,14 +654,14 @@ namespace glfw
{
down = false;
if (callback_mouse_up)
if (callback_mouse_up(*this,static_cast<int>(button),modifier))
return true;
for (unsigned int i = 0; i<plugins.size(); ++i)
if(plugins[i]->mouse_up(static_cast<int>(button),modifier))
return true;
if (callback_mouse_up)
if (callback_mouse_up(*this,static_cast<int>(button),modifier))
return true;
mouse_mode = MouseMode::None;
return true;
@@ -675,14 +678,14 @@ namespace glfw
current_mouse_x = mouse_x;
current_mouse_y = mouse_y;
if (callback_mouse_move)
if (callback_mouse_move(*this,mouse_x,mouse_y))
return true;
for (unsigned int i = 0; i<plugins.size(); ++i)
if (plugins[i]->mouse_move(mouse_x, mouse_y))
return true;
if (callback_mouse_move)
if (callback_mouse_move(*this,mouse_x,mouse_y))
return true;
if (down)
{
switch (mouse_mode)
@@ -752,14 +755,14 @@ namespace glfw
{
scroll_position += delta_y;
if (callback_mouse_scroll)
if (callback_mouse_scroll(*this,delta_y))
return true;
for (unsigned int i = 0; i<plugins.size(); ++i)
if (plugins[i]->mouse_scroll(delta_y))
return true;
if (callback_mouse_scroll)
if (callback_mouse_scroll(*this,delta_y))
return true;
// Only zoom if there's actually a change
if(delta_y != 0)
{
@@ -821,16 +824,16 @@ namespace glfw
}
core.clear_framebuffers();
if (callback_pre_draw)
for (unsigned int i = 0; i<plugins.size(); ++i)
{
if (callback_pre_draw(*this))
if (plugins[i]->pre_draw())
{
return;
}
}
for (unsigned int i = 0; i<plugins.size(); ++i)
if (callback_pre_draw)
{
if (plugins[i]->pre_draw())
if (callback_pre_draw(*this))
{
return;
}
@@ -839,13 +842,6 @@ namespace glfw
{
core.draw(data_list[i]);
}
if (callback_post_draw)
{
if (callback_post_draw(*this))
{
return;
}
}
for (unsigned int i = 0; i<plugins.size(); ++i)
{
if (plugins[i]->post_draw())
@@ -853,6 +849,13 @@ namespace glfw
break;
}
}
if (callback_post_draw)
{
if (callback_post_draw(*this))
{
return;
}
}
}
IGL_INLINE void Viewer::resize(int w,int h)
+49 -17
View File
@@ -9,11 +9,13 @@
#define IGL_OPENGL_GLFW_IMGUI_IMGUIHELPERS_H
////////////////////////////////////////////////////////////////////////////////
#include "ImGuiTraits.h"
#include <imgui/imgui.h>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
#include <cstddef>
////////////////////////////////////////////////////////////////////////////////
// Extend ImGui by populating its namespace directly
@@ -25,35 +27,35 @@ namespace ImGui
static auto vector_getter = [](void* vec, int idx, const char** out_text)
{
auto& vector = *static_cast<std::vector<std::string>*>(vec);
if (idx < 0 || idx >= static_cast<int>(vector.size())) { return false; }
*out_text = vector.at(idx).c_str();
return true;
auto& vector = *static_cast<std::vector<std::string>*>(vec);
if (idx < 0 || idx >= static_cast<int>(vector.size())) { return false; }
*out_text = vector.at(idx).c_str();
return true;
};
inline bool Combo(const char* label, int* idx, std::vector<std::string>& values)
{
if (values.empty()) { return false; }
return Combo(label, idx, vector_getter,
static_cast<void*>(&values), values.size());
if (values.empty()) { return false; }
return Combo(label, idx, vector_getter,
static_cast<void*>(&values), values.size());
}
inline bool Combo(const char* label, int* idx, std::function<const char *(int)> getter, int items_count)
{
auto func = [](void* data, int i, const char** out_text) {
auto &getter = *reinterpret_cast<std::function<const char *(int)> *>(data);
const char *s = getter(i);
if (s) { *out_text = s; return true; }
else { return false; }
};
return Combo(label, idx, func, reinterpret_cast<void *>(&getter), items_count);
auto func = [](void* data, int i, const char** out_text) {
auto &getter = *reinterpret_cast<std::function<const char *(int)> *>(data);
const char *s = getter(i);
if (s) { *out_text = s; return true; }
else { return false; }
};
return Combo(label, idx, func, reinterpret_cast<void *>(&getter), items_count);
}
inline bool ListBox(const char* label, int* idx, std::vector<std::string>& values)
{
if (values.empty()) { return false; }
return ListBox(label, idx, vector_getter,
static_cast<void*>(&values), values.size());
if (values.empty()) { return false; }
return ListBox(label, idx, vector_getter,
static_cast<void*>(&values), values.size());
}
inline bool InputText(const char* label, std::string &str, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL)
@@ -69,6 +71,36 @@ inline bool InputText(const char* label, std::string &str, ImGuiInputTextFlags f
return false;
}
// template<typename T>
// inline bool DragScalar(const char *label, T* value, void* v, float v_speed, const void* v_min = NULL, const void* v_max = NULL, const char* format = NULL, float power = 1.0f)
// {
// const char *fmt = format;
// if (format == nullptr) {
// fmt = ImGuiDataTypeTraits<T>::format;
// }
// return DragScalar(label, ImGuiDataTypeTraits<T>::value, value, &min, &max, fmt);
// }
// template<typename T>
// inline bool InputScalar(const char *label, T* value, T min = 0, T max = 0, const char* format = nulltptr)
// {
// const char *fmt = format;
// if (format == nullptr) {
// fmt = ImGuiDataTypeTraits<T>::format;
// }
// return InputScalar(label, ImGuiDataTypeTraits<T>::value, value, &min, &max, fmt);
// }
template<typename T>
inline bool SliderScalar(const char *label, T* value, T min = 0, T max = 0, const char* format = "")
{
const char *fmt = format;
if (format == nullptr) {
fmt = ImGuiDataTypeTraits<T>::format;
}
return SliderScalar(label, ImGuiDataTypeTraits<T>::value, value, &min, &max, fmt);
}
} // namespace ImGui
#endif // IGL_OPENGL_GLFW_IMGUI_IMGUIHELPERS_H
+25 -15
View File
@@ -9,7 +9,8 @@
#include "ImGuiMenu.h"
#include <igl/project.h>
#include <imgui/imgui.h>
#include <imgui_impl_glfw_gl3.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <imgui_fonts_droid_sans.h>
#include <GLFW/glfw3.h>
#include <iostream>
@@ -30,11 +31,16 @@ IGL_INLINE void ImGuiMenu::init(igl::opengl::glfw::Viewer *_viewer)
// Setup ImGui binding
if (_viewer)
{
if (context_ == nullptr)
IMGUI_CHECKVERSION();
if (!context_)
{
context_ = ImGui::CreateContext();
// Single global context by default, but can be overridden by the user
static ImGuiContext * __global_context = ImGui::CreateContext();
context_ = __global_context;
}
ImGui_ImplGlfwGL3_Init(viewer->window, false);
const char* glsl_version = "#version 150";
ImGui_ImplGlfw_InitForOpenGL(viewer->window, false);
ImGui_ImplOpenGL3_Init(glsl_version);
ImGui::GetIO().IniFilename = nullptr;
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
@@ -57,9 +63,10 @@ IGL_INLINE void ImGuiMenu::reload_font(int font_size)
IGL_INLINE void ImGuiMenu::shutdown()
{
// Cleanup
ImGui_ImplGlfwGL3_Shutdown();
ImGui::DestroyContext(context_);
context_ = nullptr;
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
// User is responsible for destroying context if a custom context is given
// ImGui::DestroyContext(*context_);
}
IGL_INLINE bool ImGuiMenu::pre_draw()
@@ -71,10 +78,12 @@ IGL_INLINE bool ImGuiMenu::pre_draw()
if (std::abs(scaling - hidpi_scaling_) > 1e-5)
{
reload_font();
ImGui_ImplGlfwGL3_InvalidateDeviceObjects();
ImGui_ImplOpenGL3_DestroyDeviceObjects();
}
ImGui_ImplGlfwGL3_NewFrame();
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
return false;
}
@@ -82,6 +91,7 @@ IGL_INLINE bool ImGuiMenu::post_draw()
{
draw_menu();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
return false;
}
@@ -97,7 +107,7 @@ IGL_INLINE void ImGuiMenu::post_resize(int width, int height)
// Mouse IO
IGL_INLINE bool ImGuiMenu::mouse_down(int button, int modifier)
{
ImGui_ImplGlfwGL3_MouseButtonCallback(viewer->window, button, GLFW_PRESS, modifier);
ImGui_ImplGlfw_MouseButtonCallback(viewer->window, button, GLFW_PRESS, modifier);
return ImGui::GetIO().WantCaptureMouse;
}
@@ -113,26 +123,26 @@ IGL_INLINE bool ImGuiMenu::mouse_move(int mouse_x, int mouse_y)
IGL_INLINE bool ImGuiMenu::mouse_scroll(float delta_y)
{
ImGui_ImplGlfwGL3_ScrollCallback(viewer->window, 0.f, delta_y);
ImGui_ImplGlfw_ScrollCallback(viewer->window, 0.f, delta_y);
return ImGui::GetIO().WantCaptureMouse;
}
// Keyboard IO
IGL_INLINE bool ImGuiMenu::key_pressed(unsigned int key, int modifiers)
{
ImGui_ImplGlfwGL3_CharCallback(nullptr, key);
ImGui_ImplGlfw_CharCallback(nullptr, key);
return ImGui::GetIO().WantCaptureKeyboard;
}
IGL_INLINE bool ImGuiMenu::key_down(int key, int modifiers)
{
ImGui_ImplGlfwGL3_KeyCallback(viewer->window, key, 0, GLFW_PRESS, modifiers);
ImGui_ImplGlfw_KeyCallback(viewer->window, key, 0, GLFW_PRESS, modifiers);
return ImGui::GetIO().WantCaptureKeyboard;
}
IGL_INLINE bool ImGuiMenu::key_up(int key, int modifiers)
{
ImGui_ImplGlfwGL3_KeyCallback(viewer->window, key, 0, GLFW_RELEASE, modifiers);
ImGui_ImplGlfw_KeyCallback(viewer->window, key, 0, GLFW_RELEASE, modifiers);
return ImGui::GetIO().WantCaptureKeyboard;
}
@@ -256,7 +266,7 @@ IGL_INLINE void ImGuiMenu::draw_viewer_menu()
{
if (ImGui::Checkbox("Face-based", &(viewer->data().face_based)))
{
viewer->data().set_face_based(viewer->data().face_based);
viewer->data().dirty = MeshGL::DIRTY_ALL;
}
ImGui::Checkbox("Show texture", &(viewer->data().show_texture));
if (ImGui::Checkbox("Invert normals", &(viewer->data().invert_normals)))
@@ -12,6 +12,7 @@
#include <igl/opengl/glfw/Viewer.h>
#include <igl/opengl/glfw/ViewerPlugin.h>
#include <igl/igl_inline.h>
#include <memory>
////////////////////////////////////////////////////////////////////////////////
// Forward declarations
@@ -0,0 +1,69 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2018 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_OPENGL_GLFW_IMGUI_IMGUITRAITS_H
#define IGL_OPENGL_GLFW_IMGUI_IMGUITRAITS_H
#include <imgui/imgui.h>
// Extend ImGui by populating its namespace directly
namespace ImGui
{
// Infer ImGuiDataType enum based on actual type
template<typename T>
class ImGuiDataTypeTraits
{
static const ImGuiDataType value; // link error
static const char * format;
};
template<>
class ImGuiDataTypeTraits<int>
{
static constexpr ImGuiDataType value = ImGuiDataType_S32;
static constexpr char * format = "%d";
};
template<>
class ImGuiDataTypeTraits<unsigned int>
{
static constexpr ImGuiDataType value = ImGuiDataType_U32;
static constexpr char * format = "%u";
};
template<>
class ImGuiDataTypeTraits<long long>
{
static constexpr ImGuiDataType value = ImGuiDataType_S64;
static constexpr char * format = "%lld";
};
template<>
class ImGuiDataTypeTraits<unsigned long long>
{
static constexpr ImGuiDataType value = ImGuiDataType_U64;
static constexpr char * format = "%llu";
};
template<>
class ImGuiDataTypeTraits<float>
{
static constexpr ImGuiDataType value = ImGuiDataType_Float;
static constexpr char * format = "%.3f";
};
template<>
class ImGuiDataTypeTraits<double>
{
static constexpr ImGuiDataType value = ImGuiDataType_Double;
static constexpr char * format = "%.6f";
};
} // namespace ImGui
#endif // IGL_OPENGL_GLFW_IMGUI_IMGUIHELPERS_H
-691
View File
@@ -1,691 +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_OPENGL2_MOUSECONTROLLER_H
#define IGL_OPENGL2_MOUSECONTROLLER_H
// Needs to be included before others
#include <Eigen/StdVector>
#include "RotateWidget.h"
#include "TranslateWidget.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <vector>
// Class for control a skeletal FK rig with the mouse.
namespace igl
{
namespace opengl2
{
class MouseController
{
public:
typedef Eigen::VectorXi VectorXb;
// Propagate selection to descendants so that selected bones and their
// subtrees are all selected.
//
// Input:
// S #S list of whether selected
// P #S list of bone parents
// Output:
// T #S list of whether selected
static inline void propogate_to_descendants_if(
const VectorXb & S,
const Eigen::VectorXi & P,
VectorXb & T);
// Create a matrix of colors for the selection and their descendants.
//
// Inputs:
// selection #S list of whether a bone is selected
// selected_color color for selected bones
// unselected_color color for unselected bones
// Outputs:
// C #P by 4 list of colors
static inline void color_if(
const VectorXb & S,
const Eigen::Vector4f & selected_color,
const Eigen::Vector4f & unselected_color,
Eigen::MatrixXf & C);
enum WidgetMode
{
WIDGET_MODE_ROTATE = 0,
WIDGET_MODE_TRANSLATE = 1,
NUM_WIDGET_MODES = 2,
};
private:
// m_is_selecting whether currently selecting
// m_selection #m_rotations list of whether a bone is selected
// m_down_x x-coordinate of mouse location at down
// m_down_y y-coordinate 〃
// m_drag_x x-coordinate of mouse location at drag
// m_drag_y y-coordinate 〃
// m_widget rotation widget for selected bone
// m_width width of containing window
// m_height height 〃
// m_rotations list of rotations for each bone
// m_rotations_at_selection list of rotations for each bone at time of
// selection
// m_translations list of translations for each bone
// m_fk_rotations_at_selection list of rotations for each bone at time of
// selection
// m_root_enabled Whether root is enabled
bool m_is_selecting;
VectorXb m_selection;
int m_down_x,m_down_y,m_drag_x,m_drag_y;
int m_width,m_height;
igl::opengl2::RotateWidget m_widget;
igl::opengl2::TranslateWidget m_trans_widget;
Eigen::Quaterniond m_widget_rot_at_selection;
//Eigen::Vector3d m_trans_widget_trans_at_selection;
typedef std::vector<
Eigen::Quaterniond,
Eigen::aligned_allocator<Eigen::Quaterniond> > RotationList;
typedef std::vector< Eigen::Vector3d > TranslationList;
RotationList
m_rotations,
m_rotations_at_selection,
m_fk_rotations_at_selection,
m_parent_rotations_at_selection;
TranslationList
m_translations,
m_translations_at_selection,
m_fk_translations_at_selection;
bool m_root_enabled;
WidgetMode m_widget_mode;
public:
MouseController();
// Returns const reference to m_selection
inline const VectorXb & selection() const{return m_selection;};
// 〃 m_is_selecting
inline const bool & is_selecting() const{return m_is_selecting;}
inline bool is_widget_down() const{return m_widget.is_down();}
inline bool is_trans_widget_down() const{return m_trans_widget.is_down();}
// 〃 m_rotations
inline const RotationList & rotations() const{return m_rotations;}
inline const TranslationList & translations() const{return m_translations;}
// Returns non-const reference to m_root_enabled
inline bool & root_enabled(){ return m_root_enabled;}
inline void reshape(const int w, const int h);
// Process down, drag, up mouse events
//
// Inputs:
// x x-coordinate of mouse click with respect to container
// y y-coordinate 〃
// Returns true if accepted (action taken).
inline bool down(const int x, const int y);
inline bool drag(const int x, const int y);
inline bool up(const int x, const int y);
// Draw selection box and widget
inline void draw() const;
// Set `m_selection` based on the last drag selection and initialize
// widget.
//
// Inputs:
// C #C by dim list of joint positions at rest
// BE #BE by 2 list of bone indices at rest
// P #P list of bone parents
inline void set_selection_from_last_drag(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const Eigen::VectorXi & P,
const Eigen::VectorXi & RP);
// Set from explicit selection
inline void set_selection(
const Eigen::VectorXi & S,
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const Eigen::VectorXi & P,
const Eigen::VectorXi & RP);
// Set size of skeleton
//
// Inputs:
// n number of bones
inline void set_size(const int n);
// Resets m_rotation elements to identity
inline void reset();
inline void reset_selected();
inline void reset_rotations();
inline void reset_selected_rotations();
inline void reset_translations();
inline void reset_selected_translations();
inline bool set_rotations(const RotationList & vQ);
inline bool set_translations(const TranslationList & vT);
// Sets all entries in m_selection to false
inline void clear_selection();
// Returns true iff some element in m_selection is true
inline bool any_selection() const;
inline void set_widget_mode(const WidgetMode & mode);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
}
// Implementation
#include "../line_segment_in_rectangle.h"
#include "draw_rectangular_marquee.h"
#include "project.h"
#include "../forward_kinematics.h"
#include <iostream>
#include <algorithm>
#include <functional>
inline void igl::opengl2::MouseController::propogate_to_descendants_if(
const VectorXb & S,
const Eigen::VectorXi & P,
VectorXb & T)
{
using namespace std;
const int n = S.rows();
assert(P.rows() == n);
// dynamic programming
T = S;
vector<bool> seen(n,false);
// Recursively look up chain and see if ancestor is selected
const function<bool(int)> look_up = [&](int e) -> bool
{
if(e==-1)
{
return false;
}
if(!seen[e])
{
seen[e] = true;
T(e) |= look_up(P(e));
}
return T(e);
};
for(int e = 0;e<n;e++)
{
if(!seen[e])
{
T(e) = look_up(e);
}
}
}
inline void igl::opengl2::MouseController::color_if(
const VectorXb & S,
const Eigen::Vector4f & selected_color,
const Eigen::Vector4f & unselected_color,
Eigen::MatrixXf & C)
{
C.resize(S.rows(),4);
for(int e=0;e<S.rows();e++)
{
C.row(e) = S(e)?selected_color:unselected_color;
}
}
inline igl::opengl2::MouseController::MouseController():
m_is_selecting(false),
m_selection(),
m_down_x(-1),m_down_y(-1),m_drag_x(-1),m_drag_y(-1),
m_width(-1),m_height(-1),
m_widget(),
m_widget_rot_at_selection(),
//m_trans_widget_trans_at_selection(),
m_trans_widget(),
m_rotations(),
m_translations(),
m_rotations_at_selection(),
m_root_enabled(true),
m_widget_mode(WIDGET_MODE_ROTATE)
{
}
inline void igl::opengl2::MouseController::reshape(const int w, const int h)
{
m_width = w;
m_height = h;
}
inline bool igl::opengl2::MouseController::down(const int x, const int y)
{
using namespace std;
m_down_x = m_drag_x =x;
m_down_y = m_drag_y =y;
const bool widget_down = any_selection() &&
(
(m_widget_mode == WIDGET_MODE_ROTATE && m_widget.down(x,m_height-y)) ||
(m_widget_mode == WIDGET_MODE_TRANSLATE &&
m_trans_widget.down(x,m_height-y))
);
if(!widget_down)
{
m_is_selecting = true;
}
return m_is_selecting || widget_down;
}
inline bool igl::opengl2::MouseController::drag(const int x, const int y)
{
using namespace std;
using namespace Eigen;
m_drag_x = x;
m_drag_y = y;
if(m_is_selecting)
{
return m_is_selecting;
}else
{
switch(m_widget_mode)
{
default: // fall through
case WIDGET_MODE_ROTATE:
{
if(!m_widget.drag(x,m_height-y))
{
return false;
}
assert(any_selection());
assert(m_selection.size() == (int)m_rotations.size());
assert(m_selection.size() == (int)m_translations.size());
for(int e = 0;e<m_selection.size();e++)
{
if(m_selection(e))
{
// Let:
// w.θr = w.θ ⋅ w.θ₀*
// w.θr takes (absolute) frame of w.θ₀ to w.θ:
// w.θ = w.θr ⋅ w.θ₀
// Define:
// w.θ₀ = θfk ⋅ θx,
// the absolute rotation of the x axis to the deformed bone at
// selection. Likewise,
// w.θ = θfk' ⋅ θx,
// the current absolute rotation of the x axis to the deformed bone.
// Define recursively:
// θfk = θfk(p) ⋅ Θr,
// then because we're only changeing this relative rotation
// θfk' = θfk(p) ⋅ Θr ⋅ θr* ⋅ θr'
// θfk' = θfk ⋅ θr* ⋅ θr'
// w.θ ⋅ θx* = θfk ⋅ θr* ⋅ θr'
// θr ⋅ θfk* ⋅ w.θ ⋅ θx* = θr'
// θr ⋅ θfk* ⋅ w.θr ⋅ w.θ₀ ⋅ θx* = θr'
// θr ⋅ θfk* ⋅ w.θr ⋅ θfk ⋅θx ⋅ θx* = θr'
// θr ⋅ θfk* ⋅ w.θr ⋅ θfk = θr'
// which I guess is the right multiply change after being changed to
// the bases of θfk, the rotation of the bone relative to its rest
// frame.
//
const Quaterniond & frame = m_fk_rotations_at_selection[e];
m_rotations[e] =
m_rotations_at_selection[e] *
frame.conjugate() *
(m_widget.rot*m_widget_rot_at_selection.conjugate()) *
frame;
}
}
}
case WIDGET_MODE_TRANSLATE:
{
if(!m_trans_widget.drag(x,m_height-y))
{
return false;
}
assert(any_selection());
assert(m_selection.size() == (int)m_rotations.size());
assert(m_selection.size() == (int)m_translations.size());
for(int e = 0;e<m_selection.size();e++)
{
if(m_selection(e))
{
m_translations[e] =
m_translations_at_selection[e] +
m_parent_rotations_at_selection[e].conjugate()*
m_trans_widget.m_trans;
}
}
}
}
return true;
}
}
inline bool igl::opengl2::MouseController::up(const int x, const int y)
{
m_is_selecting = false;
m_widget.up(x,m_height-y);
m_trans_widget.up(x,m_height-y);
return false;
}
inline void igl::opengl2::MouseController::draw() const
{
if(any_selection())
{
switch(m_widget_mode)
{
default:
case WIDGET_MODE_ROTATE:
m_widget.draw();
break;
case WIDGET_MODE_TRANSLATE:
m_trans_widget.draw();
break;
}
}
if(m_is_selecting)
{
// Remember settings
GLboolean dt;
glGetBooleanv(GL_DEPTH_TEST,&dt);
int old_vp[4];
glGetIntegerv(GL_VIEWPORT,old_vp);
// True screen space
glViewport(0,0,m_width,m_height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0,m_width,0,m_height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
draw_rectangular_marquee(
m_down_x,
m_height-m_down_y,
m_drag_x,
m_height-m_drag_y);
// Restore settings
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glViewport(old_vp[0],old_vp[1],old_vp[2],old_vp[3]);
dt?glEnable(GL_DEPTH_TEST):glDisable(GL_DEPTH_TEST);
}
}
inline void igl::opengl2::MouseController::set_selection_from_last_drag(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const Eigen::VectorXi & P,
const Eigen::VectorXi & RP)
{
using namespace Eigen;
using namespace std;
m_rotations_at_selection = m_rotations;
m_translations_at_selection = m_translations;
assert(BE.rows() == P.rows());
m_selection = VectorXb::Zero(BE.rows());
// m_rotation[e] is the relative rotation stored at bone e (as seen by the
// joint traveling with its parent)
// vQ[e] is the absolute rotation of a bone at rest to its current position:
// vQ[e] = vQ[p(e)] * m_rotation[e]
vector<Quaterniond,aligned_allocator<Quaterniond> > vQ;
vector<Vector3d> vT;
forward_kinematics(C,BE,P,m_rotations,m_translations,vQ,vT);
// Loop over deformed bones
for(int e = 0;e<BE.rows();e++)
{
Affine3d a = Affine3d::Identity();
a.translate(vT[e]);
a.rotate(vQ[e]);
Vector3d s = a * (Vector3d)C.row(BE(e,0));
Vector3d d = a * (Vector3d)C.row(BE(e,1));
Vector3d projs = project(s);
Vector3d projd = project(d);
m_selection(e) = line_segment_in_rectangle(
projs.head(2),projd.head(2),
Vector2d(m_down_x,m_height-m_down_y),
Vector2d(m_drag_x,m_height-m_drag_y));
}
return set_selection(m_selection,C,BE,P,RP);
}
inline void igl::opengl2::MouseController::set_selection(
const Eigen::VectorXi & S,
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const Eigen::VectorXi & P,
const Eigen::VectorXi & RP)
{
using namespace Eigen;
using namespace std;
vector<Quaterniond,aligned_allocator<Quaterniond> > & vQ =
m_fk_rotations_at_selection;
vector<Vector3d> & vT = m_fk_translations_at_selection;
forward_kinematics(C,BE,P,m_rotations,m_translations,vQ,vT);
m_parent_rotations_at_selection.resize(
m_rotations.size(),Quaterniond::Identity());
for(size_t r = 0;r<vQ.size();r++)
{
if(P(r)>=0)
{
m_parent_rotations_at_selection[r] = vQ[P(r)];
}
}
if(&m_selection != &S)
{
m_selection = S;
}
assert(m_selection.rows() == BE.rows());
assert(BE.rows() == P.rows());
assert(BE.rows() == RP.rows());
// Zero-out S up a path of ones from e
auto propagate = [&](const int e, const VectorXb & S, VectorXb & N)
{
if(S(e))
{
int f = e;
while(true)
{
int p = P(f);
if(p==-1||!S(p))
{
break;
}
N(f) = false;
f = p;
}
}
};
VectorXb prev_selection = m_selection;
// Combine upward, group rigid parts, repeat
while(true)
{
// Spread selection across rigid pieces
VectorXb SRP(VectorXb::Zero(RP.maxCoeff()+1));
for(int e = 0;e<BE.rows();e++)
{
SRP(RP(e)) |= m_selection(e);
}
for(int e = 0;e<BE.rows();e++)
{
m_selection(e) = SRP(RP(e));
}
// Clear selections below m_selection ancestors
VectorXb new_selection = m_selection;
for(int e = 0;e<P.rows();e++)
{
propagate(e,m_selection,new_selection);
}
m_selection = new_selection;
if(m_selection==prev_selection)
{
break;
}
prev_selection = m_selection;
}
// Now selection should contain just bone roots of m_selection subtrees
if(m_selection.array().any())
{
// Taking average
Vector3d avg_pos(0,0,0);
//m_trans_widget_trans_at_selection.setConstant(0);
m_widget_rot_at_selection.coeffs().setConstant(0);
m_widget.rot.coeffs().array().setConstant(0);
Quaterniond cur_rot(0,0,0,0);
int num_selection = 0;
// Compute average widget for selection
for(int e = 0;e<BE.rows();e++)
{
if(m_selection(e))
{
Vector3d s = C.row(BE(e,0));
Vector3d d = C.row(BE(e,1));
auto b = (d-s).transpose().eval();
{
Affine3d a = Affine3d::Identity();
a.translate(vT[e]);
a.rotate(vQ[e]);
avg_pos += a*s;
}
// Rotation of x axis to this bone
Quaterniond rot_at_bind;
rot_at_bind.setFromTwoVectors(Vector3d(1,0,0),b);
const Quaterniond abs_rot = vQ[e] * rot_at_bind;
m_widget_rot_at_selection.coeffs() += abs_rot.coeffs();
//m_trans_widget_trans_at_selection += vT[e];
num_selection++;
}
}
// Take average
avg_pos.array() /= (double)num_selection;
//m_trans_widget_trans_at_selection.array() /= (double)num_selection;
m_widget_rot_at_selection.coeffs().array() /= (double)num_selection;
m_widget_rot_at_selection.normalize();
m_widget.rot = m_widget_rot_at_selection;
m_widget.pos = avg_pos;
m_trans_widget.m_pos = avg_pos;
//m_trans_widget.m_trans = m_trans_widget_trans_at_selection;
m_trans_widget.m_trans.setConstant(0);
}
m_widget.m_is_enabled = true;
m_trans_widget.m_is_enabled = true;
for(int s = 0;s<m_selection.rows();s++)
{
// a root is selected then disable.
if(!m_root_enabled && m_selection(s) && P(s) == -1)
{
m_widget.m_is_enabled = false;
m_trans_widget.m_is_enabled = false;
break;
}
}
}
inline void igl::opengl2::MouseController::set_size(const int n)
{
using namespace Eigen;
clear_selection();
m_rotations.clear();
m_rotations.resize(n,Quaterniond::Identity());
m_translations.clear();
m_translations.resize(n,Vector3d(0,0,0));
m_selection = VectorXb::Zero(n);
}
inline void igl::opengl2::MouseController::reset()
{
reset_rotations();
reset_translations();
}
inline void igl::opengl2::MouseController::reset_selected()
{
reset_selected_rotations();
reset_selected_translations();
}
inline void igl::opengl2::MouseController::reset_rotations()
{
using namespace Eigen;
using namespace std;
fill(m_rotations.begin(),m_rotations.end(),Quaterniond::Identity());
// cop out. just clear selection
clear_selection();
}
inline void igl::opengl2::MouseController::reset_selected_rotations()
{
using namespace Eigen;
for(int e = 0;e<m_selection.size();e++)
{
if(m_selection(e))
{
m_rotations[e] = Quaterniond::Identity();
}
}
}
inline void igl::opengl2::MouseController::reset_translations()
{
using namespace Eigen;
using namespace std;
fill(m_translations.begin(),m_translations.end(),Vector3d(0,0,0));
// cop out. just clear selection
clear_selection();
}
inline void igl::opengl2::MouseController::reset_selected_translations()
{
using namespace Eigen;
for(int e = 0;e<m_selection.size();e++)
{
if(m_selection(e))
{
m_translations[e] = Vector3d(0,0,0);
}
}
}
inline bool igl::opengl2::MouseController::set_rotations(const RotationList & vQ)
{
if(vQ.size() != m_rotations.size())
{
return false;
}
assert(!any_selection());
m_rotations = vQ;
return true;
}
inline bool igl::opengl2::MouseController::set_translations(const TranslationList & vT)
{
if(vT.size() != m_translations.size())
{
return false;
}
assert(!any_selection());
m_translations = vT;
return true;
}
inline void igl::opengl2::MouseController::clear_selection()
{
m_selection.setConstant(false);
}
inline bool igl::opengl2::MouseController::any_selection() const
{
return m_selection.array().any();
}
inline void igl::opengl2::MouseController::set_widget_mode(const WidgetMode & mode)
{
switch(m_widget_mode)
{
default:
case WIDGET_MODE_TRANSLATE:
m_widget.pos = m_trans_widget.m_pos+m_trans_widget.m_trans;
break;
case WIDGET_MODE_ROTATE:
break;
}
m_widget_mode = mode;
}
#endif
-547
View File
@@ -1,547 +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_OPENGL2_ROTATE_WIDGET_H
#define IGL_OPENGL2_ROTATE_WIDGET_H
#include "../material_colors.h"
#include <Eigen/Geometry>
#include <Eigen/Core>
#include <vector>
namespace igl
{
namespace opengl2
{
// 3D Rotate tool widget similar to Maya's. Works best if field of view angle
// is less than ~25.
class RotateWidget
{
// If a is true then use A else use desaturated A
static inline void glColor4fv(const bool a, const Eigen::Vector4f & A);
public:
inline static Eigen::Quaterniond axis_q(const int a);
inline static Eigen::Vector3d view_direction(const int x, const int y);
inline static Eigen::Vector3d view_direction(const Eigen::Vector3d & pos);
Eigen::Vector3d pos;
Eigen::Quaterniond rot,down_rot;
Eigen::Vector2d down_xy,drag_xy,down_dir;
Eigen::Vector3d udown,udrag;
double outer_radius_on_screen;
double outer_over_inner;
bool m_is_enabled;
enum DownType
{
DOWN_TYPE_X = 0,
DOWN_TYPE_Y = 1,
DOWN_TYPE_Z = 2,
DOWN_TYPE_OUTLINE = 3,
DOWN_TYPE_TRACKBALL = 4,
DOWN_TYPE_NONE = 5,
NUM_DOWN_TYPES = 6
} down_type, selected_type;
inline RotateWidget();
// Vector from origin to mouse click "Unprojected" onto plane with depth of
// origin and scale to so that outer radius is 1
//
// Inputs:
// x mouse x position
// y mouse y position
// Returns vector
inline Eigen::Vector3d unproject_onto(const int x, const int y) const;
// Shoot ray from mouse click to sphere
//
// Inputs:
// x mouse x position
// y mouse y position
// Outputs:
// hit position of hit
// Returns true only if there was a hit
inline bool intersect(
const int x,
const int y,
Eigen::Vector3d & hit) const;
inline double unprojected_inner_radius() const;
inline bool down(const int x, const int y);
inline bool drag(const int x, const int y);
inline bool up(const int x, const int y);
inline bool is_down() const;
inline void draw() const;
inline void draw_guide() const;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
}
// Implementation
#include "../PI.h"
#include "../EPS.h"
#include "../ray_sphere_intersect.h"
#include "../mat_to_quat.h"
#include "../trackball.h"
#include "gl.h"
#include "project.h"
#include "unproject.h"
#include <iostream>
#include <cassert>
inline void igl::opengl2::RotateWidget::glColor4fv(
const bool a,
const Eigen::Vector4f & A)
{
if(a)
{
::glColor4fv(A.data());
}else
{
Eigen::Vector4f B;
const double f = 0.95; // desaturate by 95%
const double L = 0.3*A(0) + 0.6*A(1) + 0.1*A(2);
B.head(3) = A.head(3).array() + f*(L-A.head(3).array());
B(3) = A(3);
::glColor4fv(B.data());
}
}
inline Eigen::Quaterniond igl::opengl2::RotateWidget::axis_q(const int a)
{
assert(a<3 && a>=0);
const Eigen::Quaterniond axes[3] = {
Eigen::Quaterniond(Eigen::AngleAxisd(igl::PI*0.5,Eigen::Vector3d(0,1,0))),
Eigen::Quaterniond(Eigen::AngleAxisd(igl::PI*0.5,Eigen::Vector3d(1,0,0))),
Eigen::Quaterniond::Identity()};
return axes[a];
}
inline Eigen::Vector3d igl::opengl2::RotateWidget::view_direction(const int x, const int y)
{
using namespace Eigen;
const Vector3d win_s(x,y,0), win_d(x,y,1);
const Vector3d s = unproject(win_s);
const Vector3d d = unproject(win_d);
return d-s;
}
inline Eigen::Vector3d igl::opengl2::RotateWidget::view_direction(const Eigen::Vector3d & pos)
{
using namespace Eigen;
const Vector3d ppos = project(pos);
return view_direction(ppos(0),ppos(1));
}
inline igl::opengl2::RotateWidget::RotateWidget():
pos(0,0,0),
rot(Eigen::Quaterniond::Identity()),
down_rot(rot),
down_xy(-1,-1),drag_xy(-1,-1),
outer_radius_on_screen(91.),
outer_over_inner(1.13684210526),
m_is_enabled(true),
down_type(DOWN_TYPE_NONE),
selected_type(DOWN_TYPE_NONE)
{
}
inline Eigen::Vector3d igl::opengl2::RotateWidget::unproject_onto(
const int x,
const int y) const
{
using namespace Eigen;
// KNOWN BUG: This projects to same depths as pos. I think what we actually
// want is The intersection with the plane perpendicular to the view
// direction at pos. If the field of view angle is small then this difference
// is negligible.
//const Vector3d ppos = project(pos);
//const Vector3d uxy = unproject( Vector3d(x,y,ppos(2)));
// http://en.wikipedia.org/wiki/Line-plane_intersection
//
// Hrrmmm. There's still something wrong here if the ball's in the corner of
// the screen. Am I somehow not accounting for perspective correctly?
//
// Q: What about just projecting the circle's equation and solving for the
// distance?
const Vector3d l0 = unproject(Vector3d(x,y,0));
const Vector3d l = unproject(Vector3d(x,y,1))-l0;
const Vector3d n = view_direction(pos);
const double t = (pos-l0).dot(n)/l.dot(n);
const Vector3d uxy = l0+t*l;
return (uxy-pos)/unprojected_inner_radius()*outer_over_inner*outer_over_inner;
}
inline bool igl::opengl2::RotateWidget::intersect(
const int x,
const int y,
Eigen::Vector3d & hit) const
{
using namespace Eigen;
Vector3d view = view_direction(x,y);
const Vector3d ppos = project(pos);
Vector3d uxy = unproject(Vector3d(x,y,ppos(2)));
double t0,t1;
if(!ray_sphere_intersect(uxy,view,pos,unprojected_inner_radius(),t0,t1))
{
return false;
}
hit = uxy+t0*view;
return true;
}
inline double igl::opengl2::RotateWidget::unprojected_inner_radius() const
{
using namespace Eigen;
Vector3d off,ppos,ppos_off,pos_off;
project(pos,ppos);
ppos_off = ppos;
ppos_off(0) += outer_radius_on_screen/outer_over_inner;
unproject(ppos_off,pos_off);
return (pos-pos_off).norm();
}
inline bool igl::opengl2::RotateWidget::down(const int x, const int y)
{
using namespace Eigen;
using namespace std;
if(!m_is_enabled)
{
return false;
}
down_type = DOWN_TYPE_NONE;
selected_type = DOWN_TYPE_NONE;
down_xy = Vector2d(x,y);
drag_xy = down_xy;
down_rot = rot;
Vector3d ppos = project(pos);
const double r = (ppos.head(2) - down_xy).norm();
const double thresh = 3;
if(fabs(r - outer_radius_on_screen)<thresh)
{
udown = unproject_onto(x,y);
udrag = udown;
down_type = DOWN_TYPE_OUTLINE;
selected_type = DOWN_TYPE_OUTLINE;
// project mouse to same depth as pos
return true;
}else if(r < outer_radius_on_screen/outer_over_inner+thresh*0.5)
{
Vector3d hit;
const bool is_hit = intersect(down_xy(0),down_xy(1),hit);
if(!is_hit)
{
//cout<<"~~~!is_hit"<<endl;
}
auto on_meridian = [&](
const Vector3d & hit,
const Quaterniond & rot,
const Quaterniond & m,
Vector3d & pl_hit) -> bool
{
// project onto rotate plane
pl_hit = hit-pos;
pl_hit = (m.conjugate()*rot.conjugate()*pl_hit).eval();
pl_hit(2) = 0;
pl_hit = (rot*m*pl_hit).eval();
pl_hit.normalize();
pl_hit *= unprojected_inner_radius();
pl_hit += pos;
return (project(pl_hit).head(2)-project(hit).head(2)).norm()<2*thresh;
};
udown = (hit-pos).normalized()/outer_radius_on_screen;
udrag = udown;
for(int a = 0;a<3;a++)
{
Vector3d pl_hit;
if(on_meridian(hit,rot,Quaterniond(axis_q(a)),pl_hit))
{
udown = (pl_hit-pos).normalized()/outer_radius_on_screen;
udrag = udown;
down_type = DownType(DOWN_TYPE_X+a);
selected_type = down_type;
{
Vector3d dir3 = axis_q(a).conjugate()*down_rot.conjugate()*(hit-pos);
dir3 = AngleAxisd(-PI*0.5,Vector3d(0,0,1))*dir3;
dir3 = (rot*axis_q(a)*dir3).eval();
down_dir = (project((hit+dir3).eval())-project(hit)).head(2);
down_dir.normalize();
//// flip y because y coordinate is going to be given backwards in
//// drag()
//down_dir(1) *= -1;
}
return true;
}
}
//assert(is_hit);
down_type = DOWN_TYPE_TRACKBALL;
selected_type = DOWN_TYPE_TRACKBALL;
return true;
}else
{
return false;
}
}
inline bool igl::opengl2::RotateWidget::drag(const int x, const int y)
{
using namespace std;
using namespace Eigen;
if(!m_is_enabled)
{
return false;
}
drag_xy = Vector2d(x,y);
switch(down_type)
{
case DOWN_TYPE_NONE:
return false;
default:
{
const Quaterniond & q = axis_q(down_type-DOWN_TYPE_X);
const double dtheta = -(drag_xy - down_xy).dot(down_dir)/
outer_radius_on_screen/outer_over_inner*PI/2.;
Quaterniond dq(AngleAxisd(dtheta,down_rot*q*Vector3d(0,0,1)));
rot = dq * down_rot;
udrag = dq * udown;
return true;
}
case DOWN_TYPE_OUTLINE:
{
Vector3d ppos = project(pos);
// project mouse to same depth as pos
udrag = unproject_onto(x,y);
const Vector2d A = down_xy - ppos.head(2);
const Vector2d B = drag_xy - ppos.head(2);
const double dtheta = atan2(A(0)*B(1)-A(1)*B(0),A(0)*B(0)+A(1)*B(1));
Vector3d n = view_direction(pos).normalized();
Quaterniond dq(AngleAxisd(dtheta,-n));
//Vector3d n = udrag.cross(udown).normalized();
//Quaterniond dq(AngleAxisd(fabs(dtheta),-n));
rot = dq * down_rot;
}
return true;
case DOWN_TYPE_TRACKBALL:
{
Vector3d ppos = project(pos);
const double r = (double)outer_radius_on_screen/outer_over_inner*2.0;
//const int h = w;
Vector4i vp;
glGetIntegerv(GL_VIEWPORT,vp.data());
const int h = vp(3);
Quaterniond dq;
trackball(
r,r,
1,
Quaterniond::Identity(),
double( down_xy(0)-ppos(0) )+r/2.,
double((h-down_xy(1))-(h-ppos(1)))+r/2.,
double( x-ppos(0) )+r/2.,
double( (h-y)-(h-ppos(1)))+r/2.,
dq);
// We've computed change in rotation according to this view:
// R = mv * r, R' = rot * (mv * r)
// But we only want new value for r:
// R' = mv * r'
// mv * r' = rot * (mv * r)
// r' = mv* * rot * mv * r
Matrix4d mv;
glGetDoublev(GL_MODELVIEW_MATRIX,mv.data());
Quaterniond scene_rot;
// Convert modelview matrix to quaternion
mat4_to_quat(mv.data(),scene_rot.coeffs().data());
scene_rot.normalize();
rot = scene_rot.conjugate() * dq * scene_rot * down_rot;
}
return true;
}
}
inline bool igl::opengl2::RotateWidget::up(const int /*x*/, const int /*y*/)
{
// even if disabled process up
down_type = DOWN_TYPE_NONE;
return false;
}
inline bool igl::opengl2::RotateWidget::is_down() const
{
return down_type != DOWN_TYPE_NONE;
}
inline void igl::opengl2::RotateWidget::draw() const
{
using namespace Eigen;
using namespace std;
glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_LINE_BIT);
glDisable(GL_CLIP_PLANE0);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glLineWidth(2.0);
double r = unprojected_inner_radius();
Vector3d view = view_direction(pos).normalized();
auto draw_circle = [&](const bool cull)
{
Vector3d view = view_direction(pos).normalized();
glBegin(GL_LINES);
const double th_step = (2.0*igl::PI/100.0);
for(double th = 0;th<2.0*igl::PI+th_step;th+=th_step)
{
Vector3d a(cos(th),sin(th),0.0);
Vector3d b(cos(th+th_step),sin(th+th_step),0.0);
if(!cull || (0.5*(a+b)).dot(view)<FLOAT_EPS)
{
glVertex3dv(a.data());
glVertex3dv(b.data());
}
}
glEnd();
};
glPushMatrix();
glTranslated(pos(0),pos(1),pos(2));
glScaled(r,r,r);
// Draw outlines
{
glPushMatrix();
glColor4fv(m_is_enabled,MAYA_GREY);
Quaterniond q;
q.setFromTwoVectors(Vector3d(0,0,1),view);
glMultMatrixd(Affine3d(q).matrix().data());
draw_circle(false);
glScaled(outer_over_inner,outer_over_inner,outer_over_inner);
if(selected_type == DOWN_TYPE_OUTLINE)
{
glColor4fv(m_is_enabled,MAYA_YELLOW);
}else
{
glColor4fv(m_is_enabled,MAYA_CYAN);
}
draw_circle(false);
glPopMatrix();
}
// Draw quartiles
{
glPushMatrix();
glMultMatrixd(Affine3d(rot).matrix().data());
if(selected_type == DOWN_TYPE_Z)
{
glColor4fv(m_is_enabled,MAYA_YELLOW);
}else
{
glColor4fv(m_is_enabled,MAYA_BLUE);
}
draw_circle(true);
if(selected_type == DOWN_TYPE_Y)
{
glColor4fv(m_is_enabled,MAYA_YELLOW);
}else
{
glColor4fv(m_is_enabled,MAYA_GREEN);
}
glRotated(90.0,1.0,0.0,0.0);
draw_circle(true);
if(selected_type == DOWN_TYPE_X)
{
glColor4fv(m_is_enabled,MAYA_YELLOW);
}else
{
glColor4fv(m_is_enabled,MAYA_RED);
}
glRotated(90.0,0.0,1.0,0.0);
draw_circle(true);
glPopMatrix();
}
glColor4fv(m_is_enabled,MAYA_GREY);
draw_guide();
glPopMatrix();
glPopAttrib();
};
inline void igl::opengl2::RotateWidget::draw_guide() const
{
using namespace Eigen;
using namespace std;
glPushAttrib(
GL_DEPTH_BUFFER_BIT |
GL_ENABLE_BIT |
GL_POLYGON_BIT |
GL_POINT_BIT |
GL_TRANSFORM_BIT |
GL_STENCIL_BUFFER_BIT |
GL_LIGHTING_BIT);
// http://www.codeproject.com/Articles/23444/A-Simple-OpenGL-Stipple-Polygon-Example-EP_OpenGL_
const GLubyte halftone[] = {
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
switch(down_type)
{
case DOWN_TYPE_NONE:
case DOWN_TYPE_TRACKBALL:
goto finish;
case DOWN_TYPE_OUTLINE:
glScaled(outer_over_inner,outer_over_inner,outer_over_inner);
break;
default:
break;
}
{
const Vector3d nudown(udown.normalized()),
nudrag(udrag.normalized());
glPushMatrix();
glDisable(GL_CULL_FACE);
glDisable(GL_POINT_SMOOTH);
glPointSize(5.);
glBegin(GL_POINTS);
glVertex3dv(nudown.data());
glVertex3d(0,0,0);
glVertex3dv(nudrag.data());
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3dv(nudown.data());
glVertex3d(0,0,0);
glVertex3dv(nudrag.data());
glEnd();
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(halftone);
glBegin(GL_TRIANGLE_FAN);
glVertex3d(0,0,0);
Quaterniond dq = rot * down_rot.conjugate();
//dq.setFromTwoVectors(nudown,nudrag);
for(double t = 0;t<1;t+=0.1)
{
const Vector3d p = Quaterniond::Identity().slerp(t,dq) * nudown;
glVertex3dv(p.data());
}
glVertex3dv(nudrag.data());
glEnd();
glPopMatrix();
}
finish:
glPopAttrib();
}
#endif
-211
View File
@@ -1,211 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_TRANSLATE_WIDGET_H
#define IGL_OPENGL2_TRANSLATE_WIDGET_H
#include "../material_colors.h"
#include <Eigen/Geometry>
#include <Eigen/Core>
#include <vector>
namespace igl
{
namespace opengl2
{
class TranslateWidget
{
public:
// m_pos position of center
// m_trans translation vector
// m_down_xy mouse position on down
// m_drag_xy mouse position on drag
// m_is_enabled whether enabled
Eigen::Vector3d m_pos,m_trans,m_down_trans;
Eigen::Vector2d m_down_xy, m_drag_xy;
bool m_is_enabled;
double m_len;
enum DownType
{
DOWN_TYPE_X = 0,
DOWN_TYPE_Y = 1,
DOWN_TYPE_Z = 2,
DOWN_TYPE_CENTER = 3,
DOWN_TYPE_NONE = 4,
NUM_DOWN_TYPES = 5
} m_down_type, m_selected_type;
inline TranslateWidget(const Eigen::Vector3d & pos = Eigen::Vector3d(0,0,0));
inline bool down(const int x, const int y);
inline bool drag(const int x, const int y);
inline bool up(const int x, const int y);
inline bool is_down() const;
inline void draw() const;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
};
}
}
// Implementation
#include "project.h"
#include "unproject.h"
inline igl::opengl2::TranslateWidget::TranslateWidget(
const Eigen::Vector3d & pos):
m_pos(pos),
m_trans(0,0,0),
m_down_xy(-1,-1),
m_drag_xy(-1,-1),
m_is_enabled(true),
m_len(50),
m_down_type(DOWN_TYPE_NONE),
m_selected_type(DOWN_TYPE_NONE)
{
}
inline bool igl::opengl2::TranslateWidget::down(const int x, const int y)
{
using namespace Eigen;
using namespace std;
if(!m_is_enabled)
{
return false;
}
m_down_trans = m_trans;
m_down_xy = Vector2d(x,y);
m_drag_xy = m_down_xy;
m_down_type = DOWN_TYPE_NONE;
m_selected_type = DOWN_TYPE_NONE;
Vector3d ppos = project((m_pos+m_trans).eval());
const double r = (ppos.head(2) - m_down_xy).norm();
const double center_thresh = 10;
if(r < center_thresh)
{
m_down_type = DOWN_TYPE_CENTER;
m_selected_type = m_down_type;
return true;
}else if(r < m_len)
{
// Might be hit on lines
}
return false;
}
inline bool igl::opengl2::TranslateWidget::drag(const int x, const int y)
{
using namespace std;
using namespace Eigen;
if(!m_is_enabled)
{
return false;
}
m_drag_xy = Vector2d(x,y);
switch(m_down_type)
{
case DOWN_TYPE_NONE:
return false;
default:
{
Vector3d ppos = project((m_pos+m_trans).eval());
Vector3d drag3(m_drag_xy(0),m_drag_xy(1),ppos(2));
Vector3d down3(m_down_xy(0),m_down_xy(1),ppos(2));
m_trans = m_down_trans + unproject(drag3)-unproject(down3);
return true;
}
}
}
inline bool igl::opengl2::TranslateWidget::up(const int /*x*/, const int /*y*/)
{
// even if disabled process up
m_down_type = DOWN_TYPE_NONE;
return false;
}
inline bool igl::opengl2::TranslateWidget::is_down() const
{
return m_down_type != DOWN_TYPE_NONE;
}
inline void igl::opengl2::TranslateWidget::draw() const
{
using namespace Eigen;
using namespace std;
glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_LINE_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glLineWidth(2.0);
auto draw_axes = [&]()
{
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3f(0,1,0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3f(0,0,1);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
};
auto draw_cube = []
{
glBegin(GL_LINES);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glEnd();
};
glPushMatrix();
glTranslated( m_pos(0)+m_trans(0), m_pos(1)+m_trans(1), m_pos(2)+m_trans(2));
{
Vector3d off,ppos,ppos_off,pos_off;
project((m_pos+m_trans).eval(),ppos);
ppos_off = ppos;
ppos_off(0) += m_len;
unproject(ppos_off,pos_off);
const double r = (m_pos+m_trans-pos_off).norm();
glScaled(r,r,r);
}
draw_axes();
glScaled(0.05,0.05,0.05);
if(m_selected_type == DOWN_TYPE_CENTER)
{
glColor3fv(MAYA_YELLOW.data());
}else
{
glColor3fv(MAYA_GREY.data());
}
draw_cube();
glPopMatrix();
glPopAttrib();
}
#endif
-283
View File
@@ -1,283 +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 "draw_beach_ball.h"
#include "gl.h"
// I'm not sure why windows would need it this way:
// http://lists.cairographics.org/archives/cairo/2008-January/012722.html
#ifdef _MSC_VER
#define SAFE_INLINE __inline
#else
#define SAFE_INLINE inline
#endif
#include <vector>
#include <cmath>
#include <iostream>
// Most of this implementation comes from the AntTweakBar source code:
// TwMgr.cpp, TwMgr.h, TwColor.h, TwColor.cpp, TwOpenGL.h and TwOpenGL.cpp
////////////////////////////////////////////////////////////////////////////
// Begin Copied Straight from AntTweakBar
////////////////////////////////////////////////////////////////////////////
enum EArrowParts { ARROW_CONE, ARROW_CONE_CAP, ARROW_CYL, ARROW_CYL_CAP };
template <typename T> SAFE_INLINE const T& TClamp(const T& X, const T& Limit1, const T& Limit2)
{
if( Limit1<Limit2 )
return (X<=Limit1) ? Limit1 : ( (X>=Limit2) ? Limit2 : X );
else
return (X<=Limit2) ? Limit2 : ( (X>=Limit1) ? Limit1 : X );
}
typedef unsigned int color32;
static SAFE_INLINE color32 Color32FromARGBi(int A, int R, int G, int B)
{
return (((color32)TClamp(A, 0, 255))<<24) | (((color32)TClamp(R, 0, 255))<<16) | (((color32)TClamp(G, 0, 255))<<8) | ((color32)TClamp(B, 0, 255));
}
static SAFE_INLINE color32 Color32FromARGBf(float A, float R, float G, float B)
{
return (((color32)TClamp(A*256.0f, 0.0f, 255.0f))<<24) | (((color32)TClamp(R*256.0f, 0.0f, 255.0f))<<16) | (((color32)TClamp(G*256.0f, 0.0f, 255.0f))<<8) | ((color32)TClamp(B*256.0f, 0.0f, 255.0f));
}
static SAFE_INLINE void Color32ToARGBi(color32 Color, int *A, int *R, int *G, int *B)
{
if(A) *A = (Color>>24)&0xff;
if(R) *R = (Color>>16)&0xff;
if(G) *G = (Color>>8)&0xff;
if(B) *B = Color&0xff;
}
static SAFE_INLINE void Color32ToARGBf(color32 Color, float *A, float *R, float *G, float *B)
{
if(A) *A = (1.0f/255.0f)*float((Color>>24)&0xff);
if(R) *R = (1.0f/255.0f)*float((Color>>16)&0xff);
if(G) *G = (1.0f/255.0f)*float((Color>>8)&0xff);
if(B) *B = (1.0f/255.0f)*float(Color&0xff);
}
static color32 ColorBlend(color32 Color1, color32 Color2, float S)
{
float a1, r1, g1, b1, a2, r2, g2, b2;
Color32ToARGBf(Color1, &a1, &r1, &g1, &b1);
Color32ToARGBf(Color2, &a2, &r2, &g2, &b2);
float t = 1.0f-S;
return Color32FromARGBf(t*a1+S*a2, t*r1+S*r2, t*g1+S*g2, t*b1+S*b2);
}
static std::vector<float> s_SphTri;
static std::vector<color32> s_SphCol;
static void CreateSphere()
{
const int SUBDIV = 7;
s_SphTri.clear();
s_SphCol.clear();
const float A[8*3] = { 1,0,0, 0,0,-1, -1,0,0, 0,0,1, 0,0,1, 1,0,0, 0,0,-1, -1,0,0 };
const float B[8*3] = { 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0 };
const float C[8*3] = { 0,0,1, 1,0,0, 0,0,-1, -1,0,0, 1,0,0, 0,0,-1, -1,0,0, 0,0,1 };
//const color32 COL_A[8] = { 0xffff8080, 0xff000080, 0xff800000, 0xff8080ff, 0xff8080ff, 0xffff8080, 0xff000080, 0xff800000 };
//const color32 COL_B[8] = { 0xff80ff80, 0xff80ff80, 0xff80ff80, 0xff80ff80, 0xff008000, 0xff008000, 0xff008000, 0xff008000 };
//const color32 COL_C[8] = { 0xff8080ff, 0xffff8080, 0xff000080, 0xff800000, 0xffff8080, 0xff000080, 0xff800000, 0xff8080ff };
const color32 COL_A[8] = { 0xffffffff, 0xffffff40, 0xff40ff40, 0xff40ffff, 0xffff40ff, 0xffff4040, 0xff404040, 0xff4040ff };
const color32 COL_B[8] = { 0xffffffff, 0xffffff40, 0xff40ff40, 0xff40ffff, 0xffff40ff, 0xffff4040, 0xff404040, 0xff4040ff };
const color32 COL_C[8] = { 0xffffffff, 0xffffff40, 0xff40ff40, 0xff40ffff, 0xffff40ff, 0xffff4040, 0xff404040, 0xff4040ff };
int i, j, k, l;
float xa, ya, za, xb, yb, zb, xc, yc, zc, x, y, z, norm, u[3], v[3];
color32 col;
for( i=0; i<8; ++i )
{
xa = A[3*i+0]; ya = A[3*i+1]; za = A[3*i+2];
xb = B[3*i+0]; yb = B[3*i+1]; zb = B[3*i+2];
xc = C[3*i+0]; yc = C[3*i+1]; zc = C[3*i+2];
for( j=0; j<=SUBDIV; ++j )
for( k=0; k<=2*(SUBDIV-j); ++k )
{
if( k%2==0 )
{
u[0] = ((float)j)/(SUBDIV+1);
v[0] = ((float)(k/2))/(SUBDIV+1);
u[1] = ((float)(j+1))/(SUBDIV+1);
v[1] = ((float)(k/2))/(SUBDIV+1);
u[2] = ((float)j)/(SUBDIV+1);
v[2] = ((float)(k/2+1))/(SUBDIV+1);
}
else
{
u[0] = ((float)j)/(SUBDIV+1);
v[0] = ((float)(k/2+1))/(SUBDIV+1);
u[1] = ((float)(j+1))/(SUBDIV+1);
v[1] = ((float)(k/2))/(SUBDIV+1);
u[2] = ((float)(j+1))/(SUBDIV+1);
v[2] = ((float)(k/2+1))/(SUBDIV+1);
}
for( l=0; l<3; ++l )
{
x = (1.0f-u[l]-v[l])*xa + u[l]*xb + v[l]*xc;
y = (1.0f-u[l]-v[l])*ya + u[l]*yb + v[l]*yc;
z = (1.0f-u[l]-v[l])*za + u[l]*zb + v[l]*zc;
norm = sqrtf(x*x+y*y+z*z);
x /= norm; y /= norm; z /= norm;
s_SphTri.push_back(x); s_SphTri.push_back(y); s_SphTri.push_back(z);
static const float FLOAT_EPS = 1.0e-7f;
if( u[l]+v[l]>FLOAT_EPS )
col = ColorBlend(COL_A[i], ColorBlend(COL_B[i], COL_C[i], v[l]/(u[l]+v[l])), u[l]+v[l]);
else
col = COL_A[i];
//if( (j==0 && k==0) || (j==0 && k==2*SUBDIV) || (j==SUBDIV && k==0) )
// col = 0xffff0000;
s_SphCol.push_back(col);
}
}
}
//s_SphTriProj.clear();
//s_SphTriProj.resize(2*s_SphCol.size(), 0);
//s_SphColLight.clear();
//s_SphColLight.resize(s_SphCol.size(), 0);
}
static std::vector<float> s_ArrowTri[4];
static std::vector<float> s_ArrowNorm[4];
static void CreateArrow()
{
const int SUBDIV = 15;
const float CYL_RADIUS = 0.08f;
const float CONE_RADIUS = 0.16f;
const float CONE_LENGTH = 0.25f;
const float ARROW_BGN = -1.1f;
const float ARROW_END = 1.15f;
int i;
for(i=0; i<4; ++i)
{
s_ArrowTri[i].clear();
s_ArrowNorm[i].clear();
}
float x0, x1, y0, y1, z0, z1, a0, a1, nx, nn;
for(i=0; i<SUBDIV; ++i)
{
static const float FLOAT_PI = 3.14159265358979323846f;
a0 = 2.0f*FLOAT_PI*(float(i))/SUBDIV;
a1 = 2.0f*FLOAT_PI*(float(i+1))/SUBDIV;
x0 = ARROW_BGN;
x1 = ARROW_END-CONE_LENGTH;
y0 = cosf(a0);
z0 = sinf(a0);
y1 = cosf(a1);
z1 = sinf(a1);
s_ArrowTri[ARROW_CYL].push_back(x1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z0);
s_ArrowTri[ARROW_CYL].push_back(x0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z0);
s_ArrowTri[ARROW_CYL].push_back(x0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z1);
s_ArrowTri[ARROW_CYL].push_back(x1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z0);
s_ArrowTri[ARROW_CYL].push_back(x0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z1);
s_ArrowTri[ARROW_CYL].push_back(x1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z1);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y0); s_ArrowNorm[ARROW_CYL].push_back(z0);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y0); s_ArrowNorm[ARROW_CYL].push_back(z0);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y1); s_ArrowNorm[ARROW_CYL].push_back(z1);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y0); s_ArrowNorm[ARROW_CYL].push_back(z0);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y1); s_ArrowNorm[ARROW_CYL].push_back(z1);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y1); s_ArrowNorm[ARROW_CYL].push_back(z1);
s_ArrowTri[ARROW_CYL_CAP].push_back(x0); s_ArrowTri[ARROW_CYL_CAP].push_back(0); s_ArrowTri[ARROW_CYL_CAP].push_back(0);
s_ArrowTri[ARROW_CYL_CAP].push_back(x0); s_ArrowTri[ARROW_CYL_CAP].push_back(CYL_RADIUS*y1); s_ArrowTri[ARROW_CYL_CAP].push_back(CYL_RADIUS*z1);
s_ArrowTri[ARROW_CYL_CAP].push_back(x0); s_ArrowTri[ARROW_CYL_CAP].push_back(CYL_RADIUS*y0); s_ArrowTri[ARROW_CYL_CAP].push_back(CYL_RADIUS*z0);
s_ArrowNorm[ARROW_CYL_CAP].push_back(-1); s_ArrowNorm[ARROW_CYL_CAP].push_back(0); s_ArrowNorm[ARROW_CYL_CAP].push_back(0);
s_ArrowNorm[ARROW_CYL_CAP].push_back(-1); s_ArrowNorm[ARROW_CYL_CAP].push_back(0); s_ArrowNorm[ARROW_CYL_CAP].push_back(0);
s_ArrowNorm[ARROW_CYL_CAP].push_back(-1); s_ArrowNorm[ARROW_CYL_CAP].push_back(0); s_ArrowNorm[ARROW_CYL_CAP].push_back(0);
x0 = ARROW_END-CONE_LENGTH;
x1 = ARROW_END;
nx = CONE_RADIUS/(x1-x0);
nn = 1.0f/sqrtf(nx*nx+1);
s_ArrowTri[ARROW_CONE].push_back(x1); s_ArrowTri[ARROW_CONE].push_back(0); s_ArrowTri[ARROW_CONE].push_back(0);
s_ArrowTri[ARROW_CONE].push_back(x0); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*y0); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*z0);
s_ArrowTri[ARROW_CONE].push_back(x0); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*y1); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*z1);
s_ArrowTri[ARROW_CONE].push_back(x1); s_ArrowTri[ARROW_CONE].push_back(0); s_ArrowTri[ARROW_CONE].push_back(0);
s_ArrowTri[ARROW_CONE].push_back(x0); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*y1); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*z1);
s_ArrowTri[ARROW_CONE].push_back(x1); s_ArrowTri[ARROW_CONE].push_back(0); s_ArrowTri[ARROW_CONE].push_back(0);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y0); s_ArrowNorm[ARROW_CONE].push_back(nn*z0);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y0); s_ArrowNorm[ARROW_CONE].push_back(nn*z0);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y1); s_ArrowNorm[ARROW_CONE].push_back(nn*z1);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y0); s_ArrowNorm[ARROW_CONE].push_back(nn*z0);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y1); s_ArrowNorm[ARROW_CONE].push_back(nn*z1);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y1); s_ArrowNorm[ARROW_CONE].push_back(nn*z1);
s_ArrowTri[ARROW_CONE_CAP].push_back(x0); s_ArrowTri[ARROW_CONE_CAP].push_back(0); s_ArrowTri[ARROW_CONE_CAP].push_back(0);
s_ArrowTri[ARROW_CONE_CAP].push_back(x0); s_ArrowTri[ARROW_CONE_CAP].push_back(CONE_RADIUS*y1); s_ArrowTri[ARROW_CONE_CAP].push_back(CONE_RADIUS*z1);
s_ArrowTri[ARROW_CONE_CAP].push_back(x0); s_ArrowTri[ARROW_CONE_CAP].push_back(CONE_RADIUS*y0); s_ArrowTri[ARROW_CONE_CAP].push_back(CONE_RADIUS*z0);
s_ArrowNorm[ARROW_CONE_CAP].push_back(-1); s_ArrowNorm[ARROW_CONE_CAP].push_back(0); s_ArrowNorm[ARROW_CONE_CAP].push_back(0);
s_ArrowNorm[ARROW_CONE_CAP].push_back(-1); s_ArrowNorm[ARROW_CONE_CAP].push_back(0); s_ArrowNorm[ARROW_CONE_CAP].push_back(0);
s_ArrowNorm[ARROW_CONE_CAP].push_back(-1); s_ArrowNorm[ARROW_CONE_CAP].push_back(0); s_ArrowNorm[ARROW_CONE_CAP].push_back(0);
}
//for(i=0; i<4; ++i)
//{
// s_ArrowTriProj[i].clear();
// s_ArrowTriProj[i].resize(2*(s_ArrowTri[i].size()/3), 0);
// s_ArrowColLight[i].clear();
// s_ArrowColLight[i].resize(s_ArrowTri[i].size()/3, 0);
//}
}
////////////////////////////////////////////////////////////////////////////
// End Copied Straight from AntTweakBar
////////////////////////////////////////////////////////////////////////////
IGL_INLINE void igl::opengl2::draw_beach_ball()
{
using namespace std;
CreateSphere();
// Keep track of opengl settings
int cm;
glGetIntegerv(GL_COLOR_MATERIAL,&cm);
// Draw triangles
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
float mat_ambient[4] = {0.1,0.1,0.1,1.0};
float mat_specular[4] = {0.0,0.0,0.0,1.0};
float mat_shininess = 1;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
glPushMatrix();
glScalef(0.7,0.7,0.7);
glEnable(GL_NORMALIZE);
glBegin(GL_TRIANGLES);
for(int i = 0;i<(int)s_SphCol.size();i++)
{
glNormal3fv(&s_SphTri[i*3]);
glColor4ub(GLubyte(s_SphCol[i]>>16), GLubyte(s_SphCol[i]>>8), GLubyte(s_SphCol[i]), GLubyte(s_SphCol[i]>>24));
glVertex3fv(&s_SphTri[i*3]);
}
glEnd();
glPopMatrix();
CreateArrow();
for(int k = 0;k<3;k++)
{
glPushMatrix();
glColor3f(k==0,k==1,k==2);
glRotatef((k==2?-1.0:1.0)*90,k==0,k==2,k==1);
glBegin(GL_TRIANGLES);
for(int j = 0;j<4;j++)
{
for(int i = 0;i<(int)s_ArrowTri[j].size();i+=3)
{
glNormal3fv(&s_ArrowNorm[j][i]);
glVertex3fv(&s_ArrowTri[j][i]);
}
}
glEnd();
glPopMatrix();
}
(cm ? glEnable(GL_COLOR_MATERIAL):glDisable(GL_COLOR_MATERIAL));
}
-27
View File
@@ -1,27 +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_OPENGL2_DRAW_BEACH_BALL_H
#define IGL_OPENGL2_DRAW_BEACH_BALL_H
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Draw a beach ball icon/glyph (from AntTweakBar) at the current origin
// according to the current orientation: ball has radius 0.75 and axis have
// length 1.15
IGL_INLINE void draw_beach_ball();
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_beach_ball.cpp"
#endif
#endif
-161
View File
@@ -1,161 +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 "draw_floor.h"
#include "gl.h"
IGL_INLINE void igl::opengl2::draw_floor(const float * colorA, const float * colorB,
const int GridSizeX,
const int GridSizeY)
{
const float SizeX = 0.5f*100./(double)GridSizeX;
const float SizeY = 0.5f*100./(double)GridSizeY;
// old settings
int old_lighting=0,old_color_material=0;
glGetIntegerv(GL_LIGHTING,&old_lighting);
glGetIntegerv(GL_COLOR_MATERIAL,&old_color_material);
glDisable(GL_LIGHTING);
glColorMaterial( GL_FRONT, GL_EMISSION);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// Set material
const float black[] = {0.,0.,0.,1.};
glMaterialfv(GL_FRONT, GL_AMBIENT, black);
glMaterialfv(GL_FRONT, GL_DIFFUSE, black);
glMaterialfv(GL_FRONT, GL_SPECULAR, black);
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialf(GL_FRONT, GL_SHININESS,0);
const bool use_lighting = false;
if(use_lighting)
{
glEnable(GL_LIGHTING);
}else
{
glDisable(GL_LIGHTING);
}
glBegin(GL_QUADS);
glNormal3f(0,1,0);
for (int x =-GridSizeX/2;x<GridSizeX/2;++x)
{
for (int y =-GridSizeY/2;y<GridSizeY/2;++y)
{
if ((x+y)&0x00000001) //modulo 2
{
glColor4fv(colorA);
}else
{
glColor4fv(colorB);
}
glVertex3f( x*SizeX,0,(y+1)*SizeY);
glVertex3f((x+1)*SizeX,0,(y+1)*SizeY);
glVertex3f((x+1)*SizeX,0, y*SizeY);
glVertex3f( x*SizeX,0, y*SizeY);
}
}
glEnd();
(old_lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING));
(old_color_material? glEnable(GL_COLOR_MATERIAL) : glDisable(GL_COLOR_MATERIAL));
}
IGL_INLINE void igl::opengl2::draw_floor()
{
const float grey[] = {0.80,0.80,0.80,1.};
const float white[] = {0.95,0.95,0.95,1.};
igl::opengl2::draw_floor(grey,white);
}
IGL_INLINE void igl::opengl2::draw_floor_outline(const float * colorA, const float * colorB,
const int GridSizeX,
const int GridSizeY)
{
const float SizeX = 0.5f*100./(double)GridSizeX;
const float SizeY = 0.5f*100./(double)GridSizeY;
float old_line_width =0;
// old settings
int old_lighting=0,old_color_material=0;
glGetIntegerv(GL_LIGHTING,&old_lighting);
glGetIntegerv(GL_COLOR_MATERIAL,&old_color_material);
glDisable(GL_LIGHTING);
// Set material
const float black[] = {0.,0.,0.,1.};
glMaterialfv(GL_FRONT, GL_AMBIENT, black);
glMaterialfv(GL_FRONT, GL_DIFFUSE, black);
glMaterialfv(GL_FRONT, GL_SPECULAR, black);
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialf(GL_FRONT, GL_SHININESS,0);
const bool use_lighting = false;
if(use_lighting)
{
glEnable(GL_LIGHTING);
}else
{
glDisable(GL_LIGHTING);
}
glLineWidth(2.0f);
glBegin(GL_LINES);
for (int x =-GridSizeX/2;x<=GridSizeX/2;++x)
{
if(x!=(GridSizeX/2))
{
for(int s = -1;s<2;s+=2)
{
int y = s*(GridSizeY/2);
int cy = y==(GridSizeY/2) ? y-1 : y;
if ((x+cy)&0x00000001) //modulo 2
{
glColor4fv(colorA);
//glColor3f(1,0,0);
}else
{
glColor4fv(colorB);
//glColor3f(0,0,1);
}
glVertex3f((x+1)*SizeX,0,y*SizeY);
glVertex3f( x*SizeX,0,y*SizeY);
}
}
if(x==-(GridSizeX/2) || x==(GridSizeX/2))
{
int cx = x==(GridSizeX/2) ? x-1 : x;
for (int y =-GridSizeY/2;y<GridSizeY/2;++y)
{
if ((cx+y)&0x00000001) //modulo 2
{
glColor4fv(colorA);
//glColor3f(1,0,0);
}else
{
glColor4fv(colorB);
//glColor3f(0,0,1);
}
glVertex3f(x*SizeX,0,(y+1)*SizeY);
glVertex3f(x*SizeX,0, y*SizeY);
}
}
}
glEnd();
glGetFloatv(GL_LINE_WIDTH,&old_line_width);
glLineWidth(old_line_width);
(old_lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING));
(old_color_material? glEnable(GL_COLOR_MATERIAL) : glDisable(GL_COLOR_MATERIAL));
}
IGL_INLINE void igl::opengl2::draw_floor_outline()
{
const float grey[] = {0.80,0.80,0.80,1.};
const float white[] = {0.95,0.95,0.95,1.};
igl::opengl2::draw_floor_outline(grey,white);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#endif
-60
View File
@@ -1,60 +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_OPENGL2_DRAW_FLOOR_H
#define IGL_OPENGL2_DRAW_FLOOR_H
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Draw a checkerboard floor aligned with current (X,Z) plane using ../opengl/OpenGL_
// calls. side=50 centered at (0,0):
// (-25,-25)-->(-25,25)-->(25,25)-->(25,-25)
//
// Use glPushMatrix(), glScaled(), glTranslated() to arrange the floor.
//
// Inputs:
// colorA float4 color
// colorB float4 color
//
// Example:
// // Draw a nice floor
// glPushMatrix();
// glCullFace(GL_BACK);
// glEnable(GL_CULL_FACE);
// glEnable(GL_LIGHTING);
// glTranslated(0,-1,0);
// if(project(Vector3d(0,0,0))(2) - project(Vector3d(0,1,0))(2) > -FLOAT_EPS)
// {
// draw_floor_outline();
// }
// draw_floor();
// glPopMatrix();
// glDisable(GL_CULL_FACE);
//
IGL_INLINE void draw_floor(
const float * colorA,
const float * colorB,
const int GridSizeX=100,
const int GridSizeY=100);
// Wrapper with default colors
IGL_INLINE void draw_floor();
IGL_INLINE void draw_floor_outline(
const float * colorA,
const float * colorB,
const int GridSizeX=100,
const int GridSizeY=100);
// Wrapper with default colors
IGL_INLINE void draw_floor_outline();
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_floor.cpp"
#endif
#endif
-278
View File
@@ -1,278 +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 "draw_mesh.h"
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N)
{
using namespace Eigen;
MatrixXd _d;
MatrixXi _i;
return draw_mesh(V,F,N,_i,_d,_d,_i,_d,0,_i,0);
}
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C)
{
using namespace Eigen;
MatrixXd _d;
MatrixXi _i;
return draw_mesh(V,F,N,_i,C,_d,_i,_d,0,_i,0);
}
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC)
{
using namespace Eigen;
MatrixXd _d;
MatrixXi _i;
return draw_mesh(V,F,N,_i,C,TC,_i,_d,0,_i,0);
}
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC,
const Eigen::MatrixXd & W,
const GLuint W_index,
const Eigen::MatrixXi & WI,
const GLuint WI_index)
{
using namespace Eigen;
return draw_mesh(V,F,N,MatrixXi(),C,TC,MatrixXi(),W,W_index,WI,WI_index);
}
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXi & NF,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC,
const Eigen::MatrixXi & TF,
const Eigen::MatrixXd & W,
const GLuint W_index,
const Eigen::MatrixXi & WI,
const GLuint WI_index)
{
using namespace std;
using namespace Eigen;
const int rF = F.rows();
const int cF = F.cols();
const int cC = C.cols();
const int rC = C.rows();
const int cW = W.cols();
const int rW = W.rows();
const int rV = V.rows();
const int rTC = TC.rows();
const int rTF = TF.rows();
const int rNF = NF.rows();
const int rN = N.rows();
if(F.size() > 0)
{
assert(F.maxCoeff() < V.rows());
assert(V.cols() == 3);
assert(rC == rV || rC == rF || rC == rF*3 || rC==1 || C.size() == 0);
assert(C.cols() >= 3 || C.size() == 0);
assert(N.cols() == 3 || N.size() == 0);
assert(TC.cols() == 2 || TC.size() == 0);
assert(cF == 3 || cF == 4);
assert(TF.size() == 0 || TF.cols() == F.cols());
assert(NF.size() == 0 || NF.cols() == NF.cols());
}
if(W.size()>0)
{
assert(W.rows() == V.rows());
assert(WI.rows() == V.rows());
assert(W.cols() == WI.cols());
}
switch(F.cols())
{
default:
case 3:
glBegin(GL_TRIANGLES);
break;
case 4:
glBegin(GL_QUADS);
break;
}
// loop over faces
for(int i = 0; i<rF;i++)
{
// loop over corners of triangle
for(int j = 0;j<cF;j++)
{
int tc = -1;
if(rTF != 0)
{
tc = TF(i,j);
} else if(rTC == 1)
{
tc = 0;
}else if(rTC == rV)
{
tc = F(i,j);
}else if(rTC == rF*cF)
{
tc = i*cF + j;
}else if(rTC == rF)
{
tc = i;
}else
{
assert(TC.size() == 0);
}
// RGB(A)
Matrix<MatrixXd::Scalar,1,Dynamic> color;
if(rC == 1)
{
color = C.row(0);
}else if(rC == rV)
{
color = C.row(F(i,j));
}else if(rC == rF*cF)
{
color = C.row(i*cF+j);
}else if(rC == rF)
{
color = C.row(i);
}else
{
assert(C.size() == 0);
}
int n = -1;
if(rNF != 0)
{
n = NF(i,j); // indexed normals
} else if(rN == 1)
{
n = 0; // uniform normals
}else if(rN == rF)
{
n = i; // face normals
}else if(rN == rV)
{
n = F(i,j); // vertex normals
}else if(rN == rF*cF)
{
n = i*cF + j; // corner normals
}else
{
assert(N.size() == 0);
}
{
if(rW>0 && W_index !=0 && WI_index != 0)
{
int weights_left = cW;
while(weights_left != 0)
{
int pass_size = std::min(4,weights_left);
int weights_already_passed = cW-weights_left;
// Get attribute location of next 4 weights
int pass_W_index = W_index + weights_already_passed/4;
int pass_WI_index = WI_index + weights_already_passed/4;
switch(pass_size)
{
case 1:
glVertexAttrib1d(
pass_W_index,
W(F(i,j),0+weights_already_passed));
glVertexAttrib1d(
pass_WI_index,
WI(F(i,j),0+weights_already_passed));
break;
case 2:
glVertexAttrib2d(
pass_W_index,
W(F(i,j),0+weights_already_passed),
W(F(i,j),1+weights_already_passed));
glVertexAttrib2d(
pass_WI_index,
WI(F(i,j),0+weights_already_passed),
WI(F(i,j),1+weights_already_passed));
break;
case 3:
glVertexAttrib3d(
pass_W_index,
W(F(i,j),0+weights_already_passed),
W(F(i,j),1+weights_already_passed),
W(F(i,j),2+weights_already_passed));
glVertexAttrib3d(
pass_WI_index,
WI(F(i,j),0+weights_already_passed),
WI(F(i,j),1+weights_already_passed),
WI(F(i,j),2+weights_already_passed));
break;
default:
glVertexAttrib4d(
pass_W_index,
W(F(i,j),0+weights_already_passed),
W(F(i,j),1+weights_already_passed),
W(F(i,j),2+weights_already_passed),
W(F(i,j),3+weights_already_passed));
glVertexAttrib4d(
pass_WI_index,
WI(F(i,j),0+weights_already_passed),
WI(F(i,j),1+weights_already_passed),
WI(F(i,j),2+weights_already_passed),
WI(F(i,j),3+weights_already_passed));
break;
}
weights_left -= pass_size;
}
}
if(tc != -1)
{
glTexCoord2d(TC(tc,0),TC(tc,1));
}
if(rC>0)
{
switch(cC)
{
case 3:
glColor3dv(color.data());
break;
case 4:
glColor4dv(color.data());
break;
default:
break;
}
}
if(n != -1)
{
glNormal3d(N(n,0),N(n,1),N(n,2));
}
glVertex3d(V(F(i,j),0),V(F(i,j),1),V(F(i,j),2));
}
}
}
glEnd();
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#endif
-122
View File
@@ -1,122 +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_OPENGL2_DRAW_MESH_H
#define IGL_OPENGL2_DRAW_MESH_H
#include "../igl_inline.h"
#include "gl.h"
#include <Eigen/Dense>
namespace igl
{
namespace opengl2
{
// Draw ../opengl/OpenGL_ commands needed to display a mesh with normals
//
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V|#F by 3 eigen Matrix of 3D normals
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N);
// Draw ../opengl/OpenGL_ commands needed to display a mesh with normals and per-vertex
// colors
//
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V|#F by 3 eigen Matrix of 3D normals
// C #V|#F|1 by 3 eigen Matrix of RGB colors
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C);
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V|#F by 3 eigen Matrix of 3D normals
// C #V|#F|1 by 3 eigen Matrix of RGB colors
// TC #V|#F|1 by 3 eigen Matrix of Texture Coordinates
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC);
// Draw ../opengl/OpenGL_ commands needed to display a mesh with normals, per-vertex
// colors and LBS weights
//
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V by 3 eigen Matrix of mesh vertex 3D normals
// C #V by 3 eigen Matrix of mesh vertex RGB colors
// TC #V by 3 eigen Matrix of mesh vertex UC coorindates between 0 and 1
// W #V by #H eigen Matrix of per mesh vertex, per handle weights
// W_index Specifies the index of the "weight" vertex attribute: see
// glBindAttribLocation, if W_index is 0 then weights are ignored
// WI #V by #H eigen Matrix of per mesh vertex, per handle weight ids
// WI_index Specifies the index of the "weight" vertex attribute: see
// glBindAttribLocation, if WI_index is 0 then weight indices are ignored
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC,
const Eigen::MatrixXd & W,
const GLuint W_index,
const Eigen::MatrixXi & WI,
const GLuint WI_index);
// Draw ../opengl/OpenGL_ commands needed to display a mesh with normals, per-vertex
// colors and LBS weights
//
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V by 3 eigen Matrix of mesh vertex 3D normals
// NF #F by 3 eigen Matrix of face (triangle/quad) normal indices, <0
// means no normal
// C #V by 3 eigen Matrix of mesh vertex RGB colors
// TC #V by 3 eigen Matrix of mesh vertex UC coorindates between 0 and 1
// TF #F by 3 eigen Matrix of face (triangle/quad) texture indices, <0
// means no texture
// W #V by #H eigen Matrix of per mesh vertex, per handle weights
// W_index Specifies the index of the "weight" vertex attribute: see
// glBindAttribLocation, if W_index is 0 then weights are ignored
// WI #V by #H eigen Matrix of per mesh vertex, per handle weight ids
// WI_index Specifies the index of the "weight" vertex attribute: see
// glBindAttribLocation, if WI_index is 0 then weight indices are ignored
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXi & NF,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC,
const Eigen::MatrixXi & TF,
const Eigen::MatrixXd & W,
const GLuint W_index,
const Eigen::MatrixXi & WI,
const GLuint WI_index);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_mesh.cpp"
#endif
#endif
-100
View File
@@ -1,100 +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 "draw_point.h"
// Implementation
#include "gl.h"
#include <cassert>
#include <cmath>
IGL_INLINE void igl::opengl2::draw_point(
const double x,
const double y,
const double z,
const double requested_r,
const bool selected)
{
// Push GL settings
glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT);
float f;
glGetFloatv(GL_POINT_SIZE_MAX,&f);
// THIS IS OVERZEALOUS on Mac OS X: OpenGL reports a smaller point size than
// possible.
//assert(requested_r<=0.5*f);
double r = (requested_r<0.5*f?requested_r:0.5*f);
//glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
// get current color
float color[4];
glGetFloatv(GL_CURRENT_COLOR,color);
double outline_size = (r>7 ? sqrt(r/7.0) : 1.0);
// White outline
glColor4f(1,1,1,color[3]);
glPointSize(2*r);
glBegin(GL_POINTS);
glVertex3d(x,y,z);
glEnd();
// Black outline
glColor4f(0,0,0,color[3]);
glPointSize(2*r-2*outline_size);
glBegin(GL_POINTS);
glVertex3d(x,y,z);
glEnd();
// Foreground
glColor4fv(color);
glPointSize(2*r-4*outline_size);
glBegin(GL_POINTS);
glVertex3d(x,y,z);
glEnd();
// Selection inner circle
if(selected)
{
glColor4f(0,0,0,color[3]);
double selected_size = 2*r-7*outline_size;
selected_size = (selected_size>3?selected_size:3);
glPointSize(selected_size);
glBegin(GL_POINTS);
glVertex3d(x,y,z);
glEnd();
}
// reset color
glColor4fv(color);
// Pop GL settings
glPopAttrib();
}
template <typename DerivedP>
IGL_INLINE void igl::opengl2::draw_point(
const Eigen::PlainObjectBase<DerivedP> & P,
const double requested_r,
const bool selected)
{
switch(P.size())
{
case 2:
return draw_point(P(0),P(1),0,requested_r,selected);
default:
return draw_point(P(0),P(1),P(2),requested_r,selected);
}
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::draw_point<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, double, bool);
template void igl::opengl2::draw_point<Eigen::Matrix<double, 2, 1, 0, 2, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> > const&, double, bool);
#endif
-47
View File
@@ -1,47 +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_OPENGL2_DRAW_POINT_H
#define IGL_OPENGL2_DRAW_POINT_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
//double POINT_COLOR[3] = {239./255.,213./255.,46./255.};
// Draw a nice looking, colored dot at a given point in 3d.
//
// Note: expects that GL_CURRENT_COLOR is set with the desired foreground color
//
// Inputs:
// x x-coordinate of point, modelview coordinates
// y y-coordinate of point, modelview coordinates
// z z-coordinate of point, modelview coordinates
// requested_r outer-most radius of dot {7}, measured in screen space pixels
// selected fills inner circle with black {false}
// Asserts that requested_r does not exceed 0.5*GL_POINT_SIZE_MAX
IGL_INLINE void draw_point(
const double x,
const double y,
const double z,
const double requested_r = 7,
const bool selected = false);
template <typename DerivedP>
IGL_INLINE void draw_point(
const Eigen::PlainObjectBase<DerivedP> & P,
const double requested_r = 7,
const bool selected = false);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_point.cpp"
#endif
#endif
@@ -1,62 +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 "draw_rectangular_marquee.h"
#include "gl.h"
#include "glu.h"
#include "../material_colors.h"
IGL_INLINE void igl::opengl2::draw_rectangular_marquee(
const int from_x,
const int from_y,
const int to_x,
const int to_y)
{
using namespace std;
int l;
glGetIntegerv(GL_LIGHTING,&l);
int s;
glGetIntegerv(GL_LINE_STIPPLE,&s);
double lw;
glGetDoublev(GL_LINE_WIDTH,&lw);
glDisable(GL_LIGHTING);
// Screen space for this viewport
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
const int width = viewport[2];
const int height = viewport[3];
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0,width,0,height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glEnable(GL_LINE_STIPPLE);
glLineStipple(3,0xAAAA);
glLineWidth(1);
glColor4f(0.2,0.2,0.2,1);
glBegin(GL_LINE_STRIP);
glVertex2d(from_x,from_y);
glVertex2d(to_x,from_y);
glVertex2d(to_x,to_y);
glVertex2d(from_x,to_y);
glVertex2d(from_x,from_y);
glEnd();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glLineWidth(lw);
(s ? glEnable(GL_LINE_STIPPLE):glDisable(GL_LINE_STIPPLE));
(l ? glEnable(GL_LIGHTING):glDisable(GL_LIGHTING));
}
@@ -1,35 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_DRAW_RECTANGULAR_MARQUEE_H
#define IGL_OPENGL2_DRAW_RECTANGULAR_MARQUEE_H
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Draw a rectangular marquee (selection box) in screen space. This sets up
// screen space using current viewport.
//
// Inputs:
// from_x x coordinate of from point
// from_y y coordinate of from point
// to_x x coordinate of to point
// to_y y coordinate of to point
IGL_INLINE void draw_rectangular_marquee(
const int from_x,
const int from_y,
const int to_x,
const int to_y);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_rectangular_marquee.cpp"
#endif
#endif
-166
View File
@@ -1,166 +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 "draw_skeleton_3d.h"
#include "../PI.h"
#include "../material_colors.h"
#include "gl.h"
#include <Eigen/Geometry>
#include <iostream>
template <
typename DerivedC,
typename DerivedBE,
typename DerivedT,
typename Derivedcolor>
IGL_INLINE void igl::opengl2::draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T,
const Eigen::PlainObjectBase<Derivedcolor> & color,
const double half_bbd)
{
// Note: Maya's skeleton *does* scale with the mesh suggesting a scale
// parameter. Further, its joint balls are not rotated with the bones.
using namespace Eigen;
using namespace std;
if(color.size() == 0)
{
return draw_skeleton_3d(C,BE,T,MAYA_SEA_GREEN,half_bbd);
}
assert(color.cols() == 4 || color.size() == 4);
if(T.size() == 0)
{
typedef Eigen::Matrix<typename DerivedT::Scalar,Dynamic,Dynamic> Mat;
Mat I = Mat::Identity(C.cols()+1,C.cols());
Mat T = I.replicate(BE.rows(),1);
// insane base case
if(T.size() == 0)
{
return;
}
return draw_skeleton_3d(C,BE,T,color,half_bbd);
}
assert(T.rows() == BE.rows()*(C.cols()+1));
assert(T.cols() == C.cols());
// push old settings
glPushAttrib(GL_LIGHTING_BIT);
glPushAttrib(GL_LINE_BIT);
glDisable(GL_LIGHTING);
glLineWidth(1.0);
auto draw_sphere = [](const double r)
{
auto draw_circle = []()
{
glBegin(GL_LINE_STRIP);
for(double th = 0;th<2.0*igl::PI;th+=(2.0*igl::PI/30.0))
{
glVertex3d(cos(th),sin(th),0.0);
}
glVertex3d(cos(0),sin(0),0.0);
glEnd();
};
glPushMatrix();
glScaled(r,r,r);
draw_circle();
glRotated(90.0,1.0,0.0,0.0);
draw_circle();
glRotated(90.0,0.0,1.0,0.0);
draw_circle();
glPopMatrix();
};
auto draw_pyramid = []()
{
glBegin(GL_LINE_STRIP);
glVertex3d(0, 1,-1);
glVertex3d(0,-1,-1);
glVertex3d(0,-1, 1);
glVertex3d(0, 1, 1);
glVertex3d(0, 1,-1);
glEnd();
glBegin(GL_LINES);
glVertex3d(0, 1,-1);
glVertex3d(1,0,0);
glVertex3d(0,-1,-1);
glVertex3d(1,0,0);
glVertex3d(0,-1, 1);
glVertex3d(1,0,0);
glVertex3d(0, 1, 1);
glVertex3d(1,0,0);
glEnd();
};
// Loop over bones
for(int e = 0;e < BE.rows();e++)
{
// Draw a sphere
auto s = C.row(BE(e,0));
auto d = C.row(BE(e,1));
auto b = (d-s).transpose().eval();
double r = 0.02*half_bbd;
Matrix4d Te = Matrix4d::Identity();
Te.block(0,0,3,4) = T.block(e*4,0,4,3).transpose();
Quaterniond q;
q.setFromTwoVectors(Vector3d(1,0,0),b);
glPushMatrix();
glMultMatrixd(Te.data());
glTranslated(s(0),s(1),s(2));
if(color.size() == 4)
{
glColor4d( color(0), color(1), color(2), color(3));
}else
{
glColor4d( color(e,0), color(e,1), color(e,2), color(e,3));
}
draw_sphere(r);
const double len = b.norm()-2.*r;
if(len>=0)
{
auto u = b.normalized()*r;
glPushMatrix();
glTranslated(u(0),u(1),u(2));
glMultMatrixd(Affine3d(q).matrix().data());
glScaled(b.norm()-2.*r,r,r);
draw_pyramid();
glPopMatrix();
}
glTranslated(b(0),b(1),b(2));
draw_sphere(r);
glPopMatrix();
}
// Reset settings
glPopAttrib();
glPopAttrib();
}
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void igl::opengl2::draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T)
{
return draw_skeleton_3d(C,BE,T,MAYA_SEA_GREEN);
}
template <typename DerivedC, typename DerivedBE>
IGL_INLINE void igl::opengl2::draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE)
{
return draw_skeleton_3d(C,BE,Eigen::MatrixXd(),MAYA_SEA_GREEN);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::draw_skeleton_3d<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
template void igl::opengl2::draw_skeleton_3d<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&);
template void igl::opengl2::draw_skeleton_3d<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<float, 4, 1, 0, 4, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 1, 0, 4, 1> > const&, double);
template void igl::opengl2::draw_skeleton_3d<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<float, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, double);
#endif
-53
View File
@@ -1,53 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_DRAW_SKELETON_3D_H
#define IGL_OPENGL2_DRAW_SKELETON_3D_H
#include "../igl_inline.h"
#include "../material_colors.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
// Draw a skeleton
//
// Inputs:
// C #C by dim List of joint rest positions
// BE #BE by 2 list of bone edge indices into C
// T #BE*(dim+1) by dim matrix of stacked transposed bone transformations
// color #BE|1 by 4 list of color
// half_bbd half bounding box diagonal to determine scaling {1.0}
template <
typename DerivedC,
typename DerivedBE,
typename DerivedT,
typename Derivedcolor>
IGL_INLINE void draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T,
const Eigen::PlainObjectBase<Derivedcolor> & color,
const double half_bbd=0.5);
// Default color
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T);
template <typename DerivedC, typename DerivedBE>
IGL_INLINE void draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_skeleton_3d.cpp"
#endif
#endif
@@ -1,122 +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 "draw_skeleton_vector_graphics.h"
#include "draw_point.h"
#include "gl.h"
#include "../material_colors.h"
IGL_INLINE void igl::opengl2::draw_skeleton_vector_graphics(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE)
{
return draw_skeleton_vector_graphics(C,BE,BBW_POINT_COLOR,BBW_LINE_COLOR);
}
IGL_INLINE void igl::opengl2::draw_skeleton_vector_graphics(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const float * point_color,
const float * line_color)
{
using namespace Eigen;
int old_lighting=0;
double old_line_width=1;
glGetIntegerv(GL_LIGHTING,&old_lighting);
glGetDoublev(GL_LINE_WIDTH,&old_line_width);
int cm;
glGetIntegerv(GL_COLOR_MATERIAL,&cm);
glDisable(GL_LIGHTING);
glDisable(GL_LINE_STIPPLE);
//glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_COLOR_MATERIAL);
glLineWidth(10.0);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
float mat_ambient[4] = {0.1,0.1,0.1,1.0};
float mat_specular[4] = {0.0,0.0,0.0,1.0};
float mat_shininess = 1;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
for(int i = 0;i<3;i++)
{
switch(i)
{
case 0: glColor3fv(WHITE); glLineWidth(10); break;
case 1: glColor3fv(BLACK); glLineWidth( 6); break;
case 2: glColor3fv(line_color); glLineWidth( 4); break;
}
// Loop over bone edges
glBegin(GL_LINES);
for(int e = 0;e<BE.rows();e++)
{
RowVector3d tip = C.row(BE(e,0));
RowVector3d tail = C.row(BE(e,1));
glVertex3dv(tip.data());
glVertex3dv(tail.data());
}
glEnd();
}
glColor3fv(point_color);
for(int i = 0;i<C.rows();i++)
{
RowVector3d p = C.row(i);
draw_point(p(0),p(1),p(2));
}
(cm ? glEnable(GL_COLOR_MATERIAL):glDisable(GL_COLOR_MATERIAL));
//glDisable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_LIGHTING);
(old_lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING));
glLineWidth(old_line_width);
}
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void igl::opengl2::draw_skeleton_vector_graphics(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T)
{
return draw_skeleton_vector_graphics(C,BE,T,BBW_POINT_COLOR,BBW_LINE_COLOR);
}
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void igl::opengl2::draw_skeleton_vector_graphics(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T,
const float * point_color,
const float * line_color)
{
DerivedC CT;
DerivedBE BET;
const int dim = T.cols();
assert(dim == C.cols());
CT.resize(2*BE.rows(),C.cols());
BET.resize(BE.rows(),2);
for(int e = 0;e<BE.rows();e++)
{
BET(e,0) = 2*e;
BET(e,1) = 2*e+1;
const auto & c0 = C.row(BE(e,0));
const auto & c1 = C.row(BE(e,1));
const auto & L = T.block(e*(dim+1),0,dim,dim);
const auto & t = T.block(e*(dim+1)+dim,0,1,dim);
CT.row(2*e) = c0 * L + t;
CT.row(2*e+1) = c1 * L + t;
}
draw_skeleton_vector_graphics(CT,BET,point_color,line_color);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::draw_skeleton_vector_graphics<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&);
#endif
@@ -1,52 +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_OPENGL2_DRAW_SKELETON_VECTOR_GRAPHICS_H
#define IGL_OPENGL2_DRAW_SKELETON_VECTOR_GRAPHICS_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
// Draw a skeleton with a 2D vector graphcis style à la BBW, STBS, Monotonic,
// FAST papers.
//
// Inputs:
// C #C by dim list of joint positions
// BE #BE by 2 list of bone edge indices into C
// point_color color of points
// line_color color of lines
IGL_INLINE void draw_skeleton_vector_graphics(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const float * point_color,
const float * line_color);
// Use default colors (originally from BBW paper)
IGL_INLINE void draw_skeleton_vector_graphics(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE);
// T #BE*(dim+1) by dim matrix of stacked transposed bone transformations
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void draw_skeleton_vector_graphics(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T,
const float * point_color,
const float * line_color);
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void draw_skeleton_vector_graphics(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_skeleton_vector_graphics.cpp"
#endif
#endif
@@ -1 +0,0 @@
0455195ebe076c34d28e9bfa34e2e0ec6b117571
-44
View File
@@ -1,44 +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_OPENGL2_GL_H
#define IGL_OPENGL2_GL_H
#ifdef IGL_OPENGL_GL_H
# error "igl/opengl/gl.h already included"
#endif
// Always use this:
// #include "gl.h"
// Instead of:
// #include <OpenGL/gl.h>
// or
// #include <GL/gl.h>
//
// For now this includes glu, glew and glext (perhaps these should be
// separated)
#ifdef _WIN32
# define NOMINMAX
# include <Windows.h>
# undef DrawText
# undef NOMINMAX
#endif
#ifndef __APPLE__
# define GLEW_STATIC
# include <GL/glew.h>
#endif
#ifdef __APPLE__
# include <OpenGL/gl.h>
# define __gl_h_ /* Prevent inclusion of the old gl.h */
#else
# include <GL/gl.h>
#endif
#endif
-32
View File
@@ -1,32 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL_GLEXT_H
#define IGL_OPENGL_GLEXT_H
#ifdef IGL_OPENGL2_GLEXT_H
# error "igl/opengl2/glext.h already included"
#endif
// Always use this:
// #include "gl.h"
// Instead of:
// #include <OpenGL/glext.h>
// or
// #include <GL/glext.h>
//
#ifdef __APPLE__
# include <OpenGL/glext.h>
#elif _WIN32
// do nothing(?)
#else
# include <GL/glext.h>
#endif
#endif
-30
View File
@@ -1,30 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_GLU_H
#define IGL_OPENGL2_GLU_H
#ifdef IGL_OPENGL_GLU_H
# error "igl/opengl/glu.h already included"
#endif
// Always use this:
// #include "glu.h"
// Instead of:
// #include <OpenGL/glu.h>
// or
// #include <GL/glu.h>
//
#ifdef __APPLE__
# include <OpenGL/glu.h>
#else
# include <GL/glu.h>
#endif
#endif
-195
View File
@@ -1,195 +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 "lens_flare.h"
#include "../C_STR.h"
#include "unproject.h"
#include "project.h"
#include "shine_textures.h"
#include "flare_textures.h"
#include <iostream>
#include <stdint.h>
// http://www.opengl.org/archives/resources/features/KilgardTechniques/LensFlare/glflare.c
IGL_INLINE void igl::opengl2::lens_flare_load_textures(
std::vector<GLuint> & shine_id,
std::vector<GLuint> & flare_id)
{
const auto setup_texture =[](
const uint8_t * texture,
const int width,
const int height,
GLuint texobj,
GLenum minFilter, GLenum maxFilter)
{
glBindTexture(GL_TEXTURE_2D, texobj);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter);
glTexImage2D(GL_TEXTURE_2D, 0, 1, width, height, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, texture);
};
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
shine_id.resize(10);
glGenTextures(10,&shine_id[0]);
for (int i = 0; i < (int)shine_id.size(); i++) {
setup_texture(
SHINE_TEXTURES[i],
SHINE_TEXTURE_WIDTHS[i],
SHINE_TEXTURE_HEIGHTS[i],
shine_id[i], GL_LINEAR, GL_LINEAR);
}
flare_id.resize(6);
glGenTextures(6,&flare_id[0]);
for (int i = 0; i < (int)flare_id.size(); i++) {
setup_texture(
FLARE_TEXTURES[i],
FLARE_TEXTURE_WIDTHS[i],
FLARE_TEXTURE_HEIGHTS[i],
flare_id[i], GL_LINEAR, GL_LINEAR);
}
}
IGL_INLINE void igl::opengl2::lens_flare_create(
const float * A,
const float * B,
const float * C,
std::vector<igl::opengl2::Flare> & flares)
{
using namespace std;
flares.resize(12);
/* Shines */
flares[0] = Flare(-1, 1.0f, 0.1f, C, 1.0);
flares[1] = Flare(-1, 1.0f, 0.15f, B, 1.0);
flares[2] = Flare(-1, 1.0f, 0.35f, A, 1.0);
/* Flares */
flares[3] = Flare(2, 1.3f, 0.04f, A, 0.6);
flares[4] = Flare(3, 1.0f, 0.1f, A, 0.4);
flares[5] = Flare(1, 0.5f, 0.2f, A, 0.3);
flares[6] = Flare(3, 0.2f, 0.05f, A, 0.3);
flares[7] = Flare(0, 0.0f, 0.04f, A, 0.3);
flares[8] = Flare(5, -0.25f, 0.07f, A, 0.5);
flares[9] = Flare(5, -0.4f, 0.02f, A, 0.6);
flares[10] = Flare(5, -0.6f, 0.04f, A, 0.4);
flares[11] = Flare(5, -1.0f, 0.03f, A, 0.2);
}
IGL_INLINE void igl::opengl2::lens_flare_draw(
const std::vector<igl::opengl2::Flare> & flares,
const std::vector<GLuint> & shine_ids,
const std::vector<GLuint> & flare_ids,
const Eigen::Vector3f & light,
const float near_clip,
int & shine_tic)
{
bool ot2 = glIsEnabled(GL_TEXTURE_2D);
bool ob = glIsEnabled(GL_BLEND);
bool odt = glIsEnabled(GL_DEPTH_TEST);
bool ocm = glIsEnabled(GL_COLOR_MATERIAL);
bool ol = glIsEnabled(GL_LIGHTING);
int obsa,obda,odf,odwm;
glGetIntegerv(GL_BLEND_SRC_ALPHA,&obsa);
glGetIntegerv(GL_BLEND_DST_ALPHA,&obda);
glGetIntegerv(GL_DEPTH_FUNC,&odf);
glGetIntegerv(GL_DEPTH_WRITEMASK,&odwm);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
//glDepthFunc(GL_LEQUAL);
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
using namespace Eigen;
using namespace std;
//// view_dir direction from eye to position it is looking at
//const Vector3f view_dir = (at - from).normalized();
//// near_clip distance from eye to near clipping plane along view_dir
//// center position on near clipping plane along viewdir from eye
//const Vector3f center = from + near_clip*view_dir;
Vector3f plight = project(light);
// Orthogonal vectors to view direction at light
Vector3f psx = plight;
psx(0) += 1;
Vector3f psy = plight;
psy(1) += 1;
// axis toward center
int vp[4];
glGetIntegerv(GL_VIEWPORT,vp);
Vector3f center = unproject(Vector3f(0.5*vp[2],0.5*vp[3],plight[2]-1e-3));
//Vector3f center(0,0,1);
Vector3f axis = light-center;
//glLineWidth(4.);
//glColor3f(1,0,0);
//glBegin(GL_LINES);
//glVertex3fv(center.data());
//glVertex3fv(light.data());
//glEnd();
const Vector3f SX = unproject(psx).normalized();
const Vector3f SY = unproject(psy).normalized();
for(int i = 0; i < (int)flares.size(); i++)
{
const Vector3f sx = flares[i].scale * SX;
const Vector3f sy = flares[i].scale * SY;
glColor3fv(flares[i].color);
if (flares[i].type < 0) {
glBindTexture(GL_TEXTURE_2D, shine_ids[shine_tic]);
shine_tic = (shine_tic + 1) % shine_ids.size();
} else
{
glBindTexture(GL_TEXTURE_2D, flare_ids[flares[i].type]);
}
/* position = center + flare[i].loc * axis */
const Vector3f position = center + flares[i].loc * axis;
Vector3f tmp;
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
tmp = position + sx;
tmp = tmp + sy;
glVertex3fv(tmp.data());
glTexCoord2f(1.0, 0.0);
tmp = position - sx;
tmp = tmp + sy;
glVertex3fv(tmp.data());
glTexCoord2f(1.0, 1.0);
tmp = position - sx;
tmp = tmp - sy;
glVertex3fv(tmp.data());
glTexCoord2f(0.0, 1.0);
tmp = position + sx;
tmp = tmp - sy;
glVertex3fv(tmp.data());
glEnd();
}
ot2?glEnable(GL_TEXTURE_2D):glDisable(GL_TEXTURE_2D);
ob?glEnable(GL_BLEND):glDisable(GL_BLEND);
odt?glEnable(GL_DEPTH_TEST):glDisable(GL_DEPTH_TEST);
ocm?glEnable(GL_COLOR_MATERIAL):glDisable(GL_COLOR_MATERIAL);
ol?glEnable(GL_LIGHTING):glDisable(GL_LIGHTING);
glBlendFunc(obsa,obda);
glDepthFunc(odf);
glDepthMask(odwm);
}
-93
View File
@@ -1,93 +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_OPENGL2_LENS_FLARE_H
#define IGL_OPENGL2_LENS_FLARE_H
#include "../igl_inline.h"
#include "gl.h"
#include <Eigen/Core>
#include <vector>
namespace igl
{
namespace opengl2
{
struct Flare{
int type; /* flare texture index, 0..5 */
float scale;
float loc; /* position on axis */
float color[3];
Flare():
type(-1),
scale(0),
loc(0)
{}
Flare(int type, float location, float scale, const float color[3], float colorScale) :
type(type),
scale(scale),
loc(location)
{
this->color[0] = color[0] * colorScale;
this->color[1] = color[1] * colorScale;
this->color[2] = color[2] * colorScale;
}
};
// Initialize shared data for lens flates
//
// Inputs:
// start_id starting texture id location (should have at least id:id+16 free)
// Outputs:
// shine list of texture ids for shines
// flare list of texture ids for flares
IGL_INLINE void lens_flare_load_textures(
std::vector<GLuint> & shine_ids,
std::vector<GLuint> & flare_ids);
// Create a set of lens flares
//
// Inputs:
// A primary color
// B secondary color
// C secondary color
// Outputs:
// flares list of flare objects
IGL_INLINE void lens_flare_create(
const float * A,
const float * B,
const float * C,
std::vector<Flare> & flares);
// Draw lens flares
//
// Inputs:
// flares list of Flare objects
// shine_ids list of shine textures
// flare_ids list of flare texture ids
// light position of light
// near_clip near clipping plane
// shine_tic current "tic" in shine textures
// Outputs:
// shine_tic current "tic" in shine textures
IGL_INLINE void lens_flare_draw(
const std::vector<Flare> & flares,
const std::vector<GLuint> & shine_ids,
const std::vector<GLuint> & flare_ids,
const Eigen::Vector3f & light,
const float near_clip,
int & shine_tic);
}
};
#ifndef IGL_STATIC_LIBRARY
# include "lens_flare.cpp"
#endif
#endif
@@ -1,31 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "model_proj_viewport.h"
#include "gl.h"
template <typename Derivedmodel, typename Derivedproj, typename Derivedviewport>
IGL_INLINE void igl::opengl2::model_proj_viewport(
Eigen::PlainObjectBase<Derivedmodel> & model,
Eigen::PlainObjectBase<Derivedproj> & proj,
Eigen::PlainObjectBase<Derivedviewport> & viewport)
{
Eigen::Matrix4d MV,P;
Eigen::Vector4i VPi;
glGetDoublev(GL_MODELVIEW_MATRIX,MV.data());
glGetDoublev(GL_PROJECTION_MATRIX,P.data());
glGetIntegerv(GL_VIEWPORT,VPi.data());
viewport = VPi.cast<typename Derivedviewport::Scalar>();
model = MV.cast<typename Derivedmodel::Scalar>();
proj = P.cast<typename Derivedproj::Scalar>();
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::model_proj_viewport<Eigen::Matrix<double, 4, 4, 0, 4, 4>, Eigen::Matrix<double, 4, 4, 0, 4, 4>, Eigen::Matrix<double, 4, 1, 0, 4, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 4, 0, 4, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 4, 0, 4, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 1, 0, 4, 1> >&);
template void igl::opengl2::model_proj_viewport<Eigen::Matrix<float, 4, 4, 0, 4, 4>, Eigen::Matrix<float, 4, 4, 0, 4, 4>, Eigen::Matrix<float, 4, 1, 0, 4, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 4, 0, 4, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 4, 0, 4, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 1, 0, 4, 1> >&);
#endif
-33
View File
@@ -1,33 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_MODEL_PROJ_VIEW_H
#define IGL_OPENGL2_MODEL_PROJ_VIEW_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
// Collect the model-view, projection and viewport matrices
//
// Outputs:
// model 4x4 modelview matrix
// proj 4x4 projection matrix
// viewport 4x1 viewport vector
//
template <typename Derivedmodel, typename Derivedproj, typename Derivedviewport>
IGL_INLINE void model_proj_viewport(
Eigen::PlainObjectBase<Derivedmodel> & model,
Eigen::PlainObjectBase<Derivedproj> & proj,
Eigen::PlainObjectBase<Derivedviewport> & viewport);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "model_proj_viewport.cpp"
#endif
#endif
-38
View File
@@ -1,38 +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 "print_gl_get.h"
#include <cstdio>
IGL_INLINE void igl::opengl2::print_gl_get(GLenum pname)
{
double dM[16];
int rows = 4;
int cols = 4;
switch(pname)
{
case GL_MODELVIEW_MATRIX:
case GL_PROJECTION_MATRIX:
{
rows = 4;
cols = 4;
glGetDoublev(pname,dM);
for(int i = 0;i<rows;i++)
{
for(int j = 0;j<cols;j++)
{
printf("%lg ",dM[j*rows+i]);
}
printf("\n");
}
break;
}
default:
fprintf(stderr,"ERROR in print_gl_get(), gl enum not recognized.\n");
}
}
-28
View File
@@ -1,28 +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_OPENGL2_PRINT_GL_GET_H
#define IGL_OPENGL2_PRINT_GL_GET_H
#include "gl.h"
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Prints the value of pname found by issuing glGet*(pname,*)
// Inputs:
// pname enum key to gl parameter
IGL_INLINE void print_gl_get(GLenum pname);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "print_gl_get.cpp"
#endif
#endif
-73
View File
@@ -1,73 +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 "project.h"
#include "../project.h"
#include "gl.h"
#include "glu.h"
#include <iostream>
IGL_INLINE int igl::opengl2::project(
const double objX,
const double objY,
const double objZ,
double* winX,
double* winY,
double* winZ)
{
using namespace std;
// Put model, projection, and viewport matrices into double arrays
double MV[16];
double P[16];
int VP[4];
glGetDoublev(GL_MODELVIEW_MATRIX, MV);
glGetDoublev(GL_PROJECTION_MATRIX, P);
glGetIntegerv(GL_VIEWPORT, VP);
int ret = gluProject(objX,objY,objZ,MV,P,VP,winX,winY,winZ);
return ret;
}
template <typename Derivedobj, typename Derivedwin>
IGL_INLINE int igl::opengl2::project(
const Eigen::PlainObjectBase<Derivedobj> & obj,
Eigen::PlainObjectBase<Derivedwin> & win)
{
assert(obj.size() >= 3);
Eigen::Vector3d dobj(obj(0),obj(1),obj(2));
Eigen::Vector3d dwin;
int ret = igl::opengl2::project(dobj(0),dobj(1),dobj(2),
&dwin.data()[0],
&dwin.data()[1],
&dwin.data()[2]);
win(0) = dwin(0);
win(1) = dwin(1);
win(2) = dwin(2);
return ret;
}
template <typename Derivedobj>
IGL_INLINE Derivedobj igl::opengl2::project(
const Eigen::PlainObjectBase<Derivedobj> & obj)
{
Derivedobj win;
igl::opengl2::project(obj,win);
return win;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template int igl::opengl2::project<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
template int igl::opengl2::project<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&);
template int igl::opengl2::project<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
template Eigen::Matrix<double, 3, 1, 0, 3, 1> igl::opengl2::project<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
template Eigen::Matrix<float, 3, 1, 0, 3, 1> igl::opengl2::project<Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&);
template Eigen::Matrix<double, 1, -1, 1, 1, -1> igl::opengl2::project<Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&);
template Eigen::Matrix<double, 1, 3, 1, 1, 3> igl::opengl2::project<Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&);
template Eigen::Matrix<double, 1, 2, 1, 1, 2> igl::opengl2::project<Eigen::Matrix<double, 1, 2, 1, 1, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&);
template Eigen::Matrix<double, 2, 1, 0, 2, 1> igl::opengl2::project<Eigen::Matrix<double, 2, 1, 0, 2, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> > const&);
#endif
-47
View File
@@ -1,47 +0,0 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_PROJECT_H
#define IGL_OPENGL2_PROJECT_H
#include "../igl_inline.h"
#include <Eigen/Dense>
namespace igl
{
namespace opengl2
{
// Wrapper for gluProject that uses the current GL_MODELVIEW_MATRIX,
// GL_PROJECTION_MATRIX, and GL_VIEWPORT
// Inputs:
// obj* 3D objects' x, y, and z coordinates respectively
// Outputs:
// win* pointers to screen space x, y, and z coordinates respectively
// Returns return value of gluProject call
IGL_INLINE int project(
const double objX,
const double objY,
const double objZ,
double* winX,
double* winY,
double* winZ);
// Eigen wrapper
template <typename Derivedobj, typename Derivedwin>
IGL_INLINE int project(
const Eigen::PlainObjectBase<Derivedobj> & obj,
Eigen::PlainObjectBase<Derivedwin> & win);
// Eigen wrapper with return
template <typename Derivedobj>
IGL_INLINE Derivedobj project(
const Eigen::PlainObjectBase<Derivedobj> & obj);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "project.cpp"
#endif
#endif
-28
View File
@@ -1,28 +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 "right_axis.h"
#include "gl.h"
IGL_INLINE void igl::opengl2::right_axis(double * x, double * y, double * z)
{
double mv[16];
glGetDoublev(GL_MODELVIEW_MATRIX, mv);
igl::opengl2::right_axis(mv,x,y,z);
}
IGL_INLINE void igl::opengl2::right_axis(const double * mv,double * x, double * y, double * z)
{
*x = -mv[0*4+0];
*y = -mv[1*4+0];
*z = -mv[2*4+0];
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#endif
-34
View File
@@ -1,34 +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_OPENGL2_RIGHT_AXIS_H
#define IGL_OPENGL2_RIGHT_AXIS_H
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Determines the right axis or depth axis of the current gl matrix
// Outputs:
// x pointer to x-coordinate in scene coordinates of the un-normalized
// right axis
// y pointer to y-coordinate in scene coordinates of the un-normalized
// right axis
// z pointer to z-coordinate in scene coordinates of the un-normalized
// right axis
// mv pointer to modelview matrix
//
// Note: Right axis is returned *UN-normalized*
IGL_INLINE void right_axis(double * x, double * y, double * z);
IGL_INLINE void right_axis(const double * mv, double * x, double * y, double * z);
}
};
#ifndef IGL_STATIC_LIBRARY
# include "right_axis.cpp"
#endif
#endif
@@ -1 +0,0 @@
05001989d8ff527cd57823f435ec025540ebf18e
-80
View File
@@ -1,80 +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 "sort_triangles.h"
#include "project.h"
#include "../sort_triangles.h"
#include "gl.h"
#include "../sort.h"
#include "../slice.h"
#include "../barycenter.h"
#include <iostream>
template <
typename DerivedV,
typename DerivedF,
typename DerivedFF,
typename DerivedI>
void igl::opengl2::sort_triangles(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedFF> & FF,
Eigen::PlainObjectBase<DerivedI> & I)
{
using namespace Eigen;
using namespace std;
// Put model, projection, and viewport matrices into double arrays
Matrix4d MV;
Matrix4d P;
glGetDoublev(GL_MODELVIEW_MATRIX, MV.data());
glGetDoublev(GL_PROJECTION_MATRIX, P.data());
if(V.cols() == 3)
{
Matrix<typename DerivedV::Scalar, DerivedV::RowsAtCompileTime,4> hV;
hV.resize(V.rows(),4);
hV.block(0,0,V.rows(),V.cols()) = V;
hV.col(3).setConstant(1);
return igl::sort_triangles(hV,F,MV,P,FF,I);
}else
{
return igl::sort_triangles(V,F,MV,P,FF,I);
}
}
template <
typename DerivedV,
typename DerivedF,
typename DerivedFF,
typename DerivedI>
void igl::opengl2::sort_triangles_slow(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedFF> & FF,
Eigen::PlainObjectBase<DerivedI> & I)
{
using namespace Eigen;
using namespace std;
// Barycenter, centroid
Eigen::Matrix<typename DerivedV::Scalar, DerivedF::RowsAtCompileTime,1> D,sD;
Eigen::Matrix<typename DerivedV::Scalar, DerivedF::RowsAtCompileTime,3> BC;
D.resize(F.rows(),3);
barycenter(V,F,BC);
for(int f = 0;f<F.rows();f++)
{
Eigen::Matrix<typename DerivedV::Scalar, 3,1> bc,pbc;
bc = BC.row(f);
project(bc,pbc);
D(f) = pbc(2);
}
sort(D,1,false,sD,I);
slice(F,I,1,FF);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::sort_triangles<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::opengl2::sort_triangles_slow<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#endif

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