feifeifeiliu commited on
Commit
44dc438
·
1 Parent(s): 4175d46

Delete mesh-fix-MSVC_compilation

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. mesh-fix-MSVC_compilation/.gitattributes +0 -5
  2. mesh-fix-MSVC_compilation/.gitignore +0 -10
  3. mesh-fix-MSVC_compilation/CGAL_LICENSE.pdf +0 -0
  4. mesh-fix-MSVC_compilation/LICENSE.txt +0 -30
  5. mesh-fix-MSVC_compilation/MANIFEST.in +0 -2
  6. mesh-fix-MSVC_compilation/Makefile +0 -48
  7. mesh-fix-MSVC_compilation/README.md +0 -110
  8. mesh-fix-MSVC_compilation/data/unittest/cylinder.obj +0 -38
  9. mesh-fix-MSVC_compilation/data/unittest/cylinder_trans.obj +0 -38
  10. mesh-fix-MSVC_compilation/data/unittest/self_intersecting_cyl.obj +0 -46
  11. mesh-fix-MSVC_compilation/data/unittest/sphere.obj +0 -1278
  12. mesh-fix-MSVC_compilation/data/unittest/sphere.ply +0 -1271
  13. mesh-fix-MSVC_compilation/data/unittest/test_box.obj +0 -50
  14. mesh-fix-MSVC_compilation/data/unittest/test_box.ply +0 -29
  15. mesh-fix-MSVC_compilation/data/unittest/test_box.pp +0 -11
  16. mesh-fix-MSVC_compilation/data/unittest/test_box_le.ply +0 -0
  17. mesh-fix-MSVC_compilation/data/unittest/test_doublebox.obj +0 -64
  18. mesh-fix-MSVC_compilation/doc/Makefile +0 -177
  19. mesh-fix-MSVC_compilation/doc/make.bat +0 -242
  20. mesh-fix-MSVC_compilation/doc/source/conf.py +0 -356
  21. mesh-fix-MSVC_compilation/doc/source/index.rst +0 -163
  22. mesh-fix-MSVC_compilation/doc/source/pages/geometry.rst +0 -29
  23. mesh-fix-MSVC_compilation/doc/source/pages/mesh.rst +0 -31
  24. mesh-fix-MSVC_compilation/doc/source/pages/mesh_viewer.rst +0 -11
  25. mesh-fix-MSVC_compilation/mesh/CMakeLists.txt +0 -114
  26. mesh-fix-MSVC_compilation/mesh/__init__.py +0 -20
  27. mesh-fix-MSVC_compilation/mesh/arcball.py +0 -247
  28. mesh-fix-MSVC_compilation/mesh/cmake/python_helper.cmake +0 -74
  29. mesh-fix-MSVC_compilation/mesh/cmake/thirdparty.cmake +0 -107
  30. mesh-fix-MSVC_compilation/mesh/colors.py +0 -790
  31. mesh-fix-MSVC_compilation/mesh/errors.py +0 -15
  32. mesh-fix-MSVC_compilation/mesh/fonts.py +0 -87
  33. mesh-fix-MSVC_compilation/mesh/geometry/__init__.py +0 -4
  34. mesh-fix-MSVC_compilation/mesh/geometry/barycentric_coordinates_of_projection.py +0 -49
  35. mesh-fix-MSVC_compilation/mesh/geometry/cross_product.py +0 -37
  36. mesh-fix-MSVC_compilation/mesh/geometry/rodrigues.py +0 -125
  37. mesh-fix-MSVC_compilation/mesh/geometry/tri_normals.py +0 -72
  38. mesh-fix-MSVC_compilation/mesh/geometry/triangle_area.py +0 -12
  39. mesh-fix-MSVC_compilation/mesh/geometry/vert_normals.py +0 -34
  40. mesh-fix-MSVC_compilation/mesh/landmarks.py +0 -102
  41. mesh-fix-MSVC_compilation/mesh/lines.py +0 -61
  42. mesh-fix-MSVC_compilation/mesh/mesh.py +0 -492
  43. mesh-fix-MSVC_compilation/mesh/meshviewer.py +0 -1238
  44. mesh-fix-MSVC_compilation/mesh/processing.py +0 -186
  45. mesh-fix-MSVC_compilation/mesh/ressources/Arial.ttf +0 -0
  46. mesh-fix-MSVC_compilation/mesh/search.py +0 -100
  47. mesh-fix-MSVC_compilation/mesh/serialization/__init__.py +0 -4
  48. mesh-fix-MSVC_compilation/mesh/serialization/serialization.py +0 -443
  49. mesh-fix-MSVC_compilation/mesh/sphere.py +0 -74
  50. mesh-fix-MSVC_compilation/mesh/src/AABB_n_tree.h +0 -355
mesh-fix-MSVC_compilation/.gitattributes DELETED
@@ -1,5 +0,0 @@
1
- /data/unittest/* text eol=lf
2
- /data/unittest/*.obj text
3
- /data/unittest/*.pp text
4
- /data/unittest/sphere.ply text
5
- /data/unittest/test_box.ply text
 
 
 
 
 
 
mesh-fix-MSVC_compilation/.gitignore DELETED
@@ -1,10 +0,0 @@
1
- build/*
2
- *.pyc
3
- temporary_test
4
- dist
5
- MANIFEST
6
- *.xml
7
- *.egg-info
8
- doc/build
9
- .eggs
10
- .idea
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/CGAL_LICENSE.pdf DELETED
Binary file (78.7 kB)
 
mesh-fix-MSVC_compilation/LICENSE.txt DELETED
@@ -1,30 +0,0 @@
1
-
2
- Max-Planck grants you a non-exclusive, non-transferable, free of charge right to
3
- use the *psbody-mesh package* on computers owned, leased or otherwise controlled
4
- by you and/or your organization for the sole purpose of performing non-commercial
5
- scientific research.
6
-
7
- Any other use, in particular any use for commercial purposes, is prohibited.
8
- This includes, without limitation, incorporation in a commercial product, use in
9
- a commercial service, or production of other artifacts for commercial purposes
10
- including, for example, web services, movies, television programs, or video
11
- games. The Model may not be reproduced, modified and/or made available in any
12
- form to any third party without MPG’s prior written permission. By using the
13
- Model, you agree not to reverse engineer it.
14
-
15
- You expressly acknowledge and agree that the Model is provided “AS IS”, may
16
- contain errors, and that any use of the Model is at your sole risk. MAX PLANCK
17
- MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE DATA, NEITHER
18
- EXPRESS NOR IMPLIED, AND THE ABSENCE OF ANY LEGAL OR ACTUAL DEFECTS, WHETHER
19
- DISCOVERABLE OR NOT. Specifically, and not to limit the foregoing, Max-Planck
20
- makes no representations or warranties (i) regarding the merchantability or
21
- fitness for a particular purpose of the Model, (ii) that the use of the Model
22
- will not infringe any patents, copyrights or other intellectual property rights
23
- of a third party, and (iii) that the use of the Model will not cause any damage
24
- of any kind to you or a third party.
25
-
26
- Under no circumstances shall Max-Planck be liable for any incidental, special,
27
- indirect or consequential damages arising out of or relating to this license,
28
- including but not limited to, any lost profits, business interruption, loss of
29
- programs or other data, or all other commercial damages or losses, even if
30
- advised of the possibility thereof.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/MANIFEST.in DELETED
@@ -1,2 +0,0 @@
1
- recursive-include mesh/src *
2
- recursive-include mesh/ressources *
 
 
 
mesh-fix-MSVC_compilation/Makefile DELETED
@@ -1,48 +0,0 @@
1
- # Makefile for mesh package
2
- package_name := mesh_package
3
-
4
- all:
5
- @echo "\033[0;36m----- [" ${package_name} "] Installing on the local virtual environment `which python`\033[0m"
6
- @pip install --upgrade -r requirements.txt && pip list
7
- @pip install --no-deps --install-option="--boost-location=$$BOOST_ROOT" --verbose --no-cache-dir .
8
-
9
- import_tests:
10
- @echo "\033[0;33m----- [" ${package_name} "] Performing import tests\033[0m"
11
- @PSBODY_MESH_CACHE=`mktemp -d -t mesh_package.XXXXXXXXXX` python -c "from psbody.mesh.mesh import Mesh"
12
- @python -c "from psbody.mesh.meshviewer import MeshViewers"
13
- @echo "\033[0;33m----- [" ${package_name} "] OK import tests\033[0m"
14
-
15
- unit_tests:
16
- @if test "$(USE_NOSE)" = "" ; then \
17
- echo "\033[0;33m----- [" ${package_name} "] Running tests using unittest, no report file\033[0m" ; \
18
- PSBODY_MESH_CACHE=`mktemp -d -t mesh_package.XXXXXXXXXX` python -m unittest -v ; \
19
- else \
20
- echo "\033[0;33m----- [" ${package_name} "] Running tests using nosetests\033[0m" ; \
21
- pip install nose ; \
22
- PSBODY_MESH_CACHE=`mktemp -d -t mesh_package.XXXXXXXXXX` nosetests -v --with-xunit; \
23
- fi ;
24
-
25
- tests: import_tests unit_tests
26
-
27
- # Creating source distribution
28
- sdist:
29
- @echo "\033[0;33m----- [" ${package_name} "] Creating the source distribution\033[0m"
30
- @python setup.py sdist
31
-
32
- # Creating wheel distribution
33
- wheel:
34
- @echo "\033[0;33m----- [" ${package_name} "] Creating the wheel distribution\033[0m"
35
- @pip install wheel
36
- @python setup.py --verbose build_ext --boost-location=$$BOOST_ROOT bdist_wheel
37
-
38
- # Build documentation
39
- documentation:
40
- @echo "\033[0;33m----- [" ${package_name} "] Building Sphinx documentation\033[0m"
41
- @pip install -U sphinx sphinx_bootstrap_theme
42
- @cd doc && make html
43
-
44
- clean:
45
- @rm -rf build
46
- @rm -rf dist
47
- @rm -rf psbody_mesh.egg-info
48
- @rm -rf *.xml
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/README.md DELETED
@@ -1,110 +0,0 @@
1
- Perceiving Systems Mesh Package
2
- ===============================
3
-
4
- This package contains core functions for manipulating meshes and visualizing them.
5
- It requires ``Python 3.5+`` and is supported on Linux and macOS operating systems.
6
-
7
- The ``Mesh`` processing libraries support several of our projects such as
8
- * [CoMA: Convolutional Mesh Encoders for Generating 3D Faces](http://coma.is.tue.mpg.de/)
9
- * [FLAME: Learning a model of facial shape and expression from 4D scans](http://flame.is.tue.mpg.de/)
10
- * [MANO: Modeling and Capturing Hands and Bodies Together](http://mano.is.tue.mpg.de/)
11
- * [SMPL: A Skinned Multi-Person Linear Model](http://smpl.is.tue.mpg.de/)
12
- * [VOCA: Voice Operated Character Animation](https://github.com/TimoBolkart/voca)
13
- * [RingNet: 3D Face Shape and Expression Reconstruction from an Image](https://github.com/soubhiksanyal/RingNet)
14
-
15
- Requirements
16
- ------------
17
-
18
- You first need to install the `Boost <http://www.boost.org>`_ libraries.
19
- You can compile your own local version.
20
-
21
- On Windows/MSVC, you must download and compile it yourself.
22
-
23
- On Linux you can simply install it via:
24
-
25
- ```
26
- $ sudo apt-get install libboost-dev
27
- ```
28
-
29
- On macOS:
30
-
31
- ```
32
- $ brew install boost
33
- ```
34
-
35
- Installation
36
- ------------
37
-
38
- First, create a dedicated Python virtual environment and activate it:
39
-
40
- ```
41
- $ python3 -m venv --copies my_venv
42
- $ source my_venv/bin/activate
43
- ```
44
-
45
- #### Linux/MacOS
46
- You should then compile and install the ``psbody-mesh`` package using the Makefile.
47
- If you are using the system-wide ``Boost`` libraries:
48
-
49
- ```
50
- $ make all
51
- ```
52
-
53
- or the libraries locally installed:
54
-
55
- ```
56
- $ BOOST_ROOT=/path/to/boost/libraries make all
57
- ```
58
-
59
- #### Windows
60
- Since Makefile and the linux commands in it does not work on Windows, run the command below instead:
61
- (remember to replace <path_to_your_boost> with your path to boost)
62
- ```
63
- pip install --no-deps --install-option="--boost-location=<path_to_your_boost>" --verbose --no-cache-dir .
64
- ```
65
-
66
- Note on MeshViewer: Windows users need a special version of PyOpenGL to use the MeshViewer, because the one automatically installed via PYPI does not include the required DLL.
67
-
68
- please download the unofficial PyOpenGL wheel file from [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl), uninstall the original version and install the new one by commands below:
69
-
70
- ```
71
- pip uninstall pyOpenGL
72
- pip install <the-name-of-your-wheel-file>
73
- ```
74
-
75
- Testing
76
- -------
77
-
78
- To run the tests, simply do:
79
-
80
- #### Linux/MacOS
81
-
82
- ```
83
- $ make tests
84
- ```
85
-
86
- #### Windows
87
-
88
- ```
89
- python -m unittest -v
90
- ```
91
-
92
- Documentation
93
- -------------
94
-
95
- A detailed documentation can be compiled using the Makefile:
96
-
97
- ```
98
- $ make documentation
99
- ```
100
-
101
- License
102
- -------
103
- Please refer for LICENSE.txt for using this software. The software is compiled using CGAL sources following the license in CGAL_LICENSE.pdf
104
-
105
- Acknowledgments
106
- ---------------
107
-
108
- We thank the external contribution from the following people:
109
- * [Kenneth Chaney](https://github.com/k-chaney) ([PR #5](https://github.com/MPI-IS/mesh/pull/5))
110
- * [Dávid Komorowicz](https://github.com/Dawars) ([PR #8](https://github.com/MPI-IS/mesh/pull/8))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/data/unittest/cylinder.obj DELETED
@@ -1,38 +0,0 @@
1
- # Blender v2.61 (sub 0) OBJ File: ''
2
- # www.blender.org
3
- g Cylinder
4
- v 0.000000 -1.000000 -1.000000
5
- v 0.000000 -1.000000 1.000000
6
- v -0.382683 -1.000000 0.923880
7
- v -0.707107 -1.000000 0.707107
8
- v -0.923880 -1.000000 0.382684
9
- v -1.000000 -1.000000 -0.000000
10
- v -0.923879 -1.000000 -0.382684
11
- v -0.707107 -1.000000 -0.707107
12
- v -0.382683 -1.000000 -0.923880
13
- v 0.000001 1.000000 -1.000000
14
- v -0.000002 1.000000 1.000000
15
- v -0.382685 1.000000 0.923879
16
- v -0.707108 1.000000 0.707105
17
- v -0.923880 1.000000 0.382681
18
- v -1.000000 1.000000 -0.000003
19
- v -0.923878 1.000000 -0.382686
20
- v -0.707105 1.000000 -0.707109
21
- v -0.382681 1.000000 -0.923881
22
- s off
23
- f 10 1 18
24
- f 1 9 18
25
- f 8 17 9
26
- f 17 18 9
27
- f 7 16 8
28
- f 16 17 8
29
- f 6 15 7
30
- f 15 16 7
31
- f 5 14 6
32
- f 14 15 6
33
- f 4 13 5
34
- f 13 14 5
35
- f 3 12 4
36
- f 12 13 4
37
- f 2 11 3
38
- f 11 12 3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/data/unittest/cylinder_trans.obj DELETED
@@ -1,38 +0,0 @@
1
- # Blender v2.61 (sub 0) OBJ File: ''
2
- # www.blender.org
3
- g Cylinder
4
- v 1.057678 -1.000000 -1.000000
5
- v 1.057678 -1.000000 1.000000
6
- v 0.674994 -1.000000 0.923880
7
- v 0.350571 -1.000000 0.707107
8
- v 0.133798 -1.000000 0.382684
9
- v 0.057678 -1.000000 -0.000000
10
- v 0.133798 -1.000000 -0.382684
11
- v 0.350571 -1.000000 -0.707107
12
- v 0.674995 -1.000000 -0.923880
13
- v 1.057678 1.000000 -1.000000
14
- v 1.057676 1.000000 1.000000
15
- v 0.674992 1.000000 0.923879
16
- v 0.350569 1.000000 0.707105
17
- v 0.133797 1.000000 0.382681
18
- v 0.057678 1.000000 -0.000003
19
- v 0.133799 1.000000 -0.382686
20
- v 0.350573 1.000000 -0.707109
21
- v 0.674997 1.000000 -0.923881
22
- s off
23
- f 10 1 18
24
- f 1 9 18
25
- f 8 17 9
26
- f 17 18 9
27
- f 7 16 8
28
- f 16 17 8
29
- f 6 15 7
30
- f 15 16 7
31
- f 5 14 6
32
- f 14 15 6
33
- f 4 13 5
34
- f 13 14 5
35
- f 3 12 4
36
- f 12 13 4
37
- f 2 11 3
38
- f 11 12 3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/data/unittest/self_intersecting_cyl.obj DELETED
@@ -1,46 +0,0 @@
1
- # Blender v2.61 (sub 0) OBJ File: ''
2
- # www.blender.org
3
- g Plane
4
- v 0.000000 -0.500000 -1.000000
5
- v 0.707107 -0.500000 -0.707107
6
- v 1.000000 -0.500000 0.000000
7
- v 0.707107 -0.500000 0.707107
8
- v -0.000000 -0.500000 1.000000
9
- v -0.707107 -0.500000 0.707107
10
- v -1.000000 -0.500000 -0.000000
11
- v -0.707107 -0.500000 -0.707107
12
- v -0.000000 0.500000 -1.000000
13
- v 0.707106 0.500000 -0.707107
14
- v 1.000000 0.500000 -0.000001
15
- v 0.707107 0.500000 0.707107
16
- v -0.000000 0.500000 1.000000
17
- v -0.707107 0.500000 0.707107
18
- v -1.000000 0.500000 -0.000001
19
- v -0.707106 0.500000 -0.707107
20
- v 0.000000 -0.500000 0.000000
21
- v 0.000000 -0.835754 0.000000
22
- s off
23
- f 17 1 2
24
- f 18 10 9
25
- f 17 2 3
26
- f 18 11 10
27
- f 17 3 4
28
- f 18 12 11
29
- f 17 4 5
30
- f 18 13 12
31
- f 17 5 6
32
- f 18 14 13
33
- f 17 6 7
34
- f 18 15 14
35
- f 17 7 8
36
- f 18 16 15
37
- f 8 1 17
38
- f 18 9 16
39
- f 1 9 10 2
40
- f 2 10 11 3
41
- f 3 11 12 4
42
- f 4 12 13 5
43
- f 5 13 14 6
44
- f 6 14 15 7
45
- f 7 15 16 8
46
- f 9 1 8 16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/data/unittest/sphere.obj DELETED
@@ -1,1278 +0,0 @@
1
- ####
2
- #
3
- # OBJ File Generated by Meshlab
4
- #
5
- ####
6
- # Object sphere.obj
7
- #
8
- # Vertices: 422
9
- # Faces: 840
10
- #
11
- ####
12
- v 0.000000 0.000000 -127.000000
13
- v 5.000000 25.000000 -125.000000
14
- v 10.000000 24.000000 -125.000000
15
- v 15.000000 21.000000 -125.000000
16
- v 19.000000 17.000000 -125.000000
17
- v 22.000000 13.000000 -125.000000
18
- v 25.000000 8.000000 -125.000000
19
- v 26.000000 2.000000 -125.000000
20
- v 26.000000 -3.000000 -125.000000
21
- v 25.000000 -9.000000 -125.000000
22
- v 22.000000 -14.000000 -125.000000
23
- v 19.000000 -18.000000 -125.000000
24
- v 15.000000 -22.000000 -125.000000
25
- v 10.000000 -25.000000 -125.000000
26
- v 5.000000 -26.000000 -125.000000
27
- v 0.000000 -27.000000 -125.000000
28
- v -6.000000 -26.000000 -125.000000
29
- v -11.000000 -25.000000 -125.000000
30
- v -16.000000 -22.000000 -125.000000
31
- v -20.000000 -18.000000 -125.000000
32
- v -23.000000 -14.000000 -125.000000
33
- v -26.000000 -9.000000 -125.000000
34
- v -27.000000 -3.000000 -125.000000
35
- v -27.000000 2.000000 -125.000000
36
- v -26.000000 8.000000 -125.000000
37
- v -23.000000 13.000000 -125.000000
38
- v -20.000000 17.000000 -125.000000
39
- v -16.000000 21.000000 -125.000000
40
- v -11.000000 24.000000 -125.000000
41
- v -6.000000 25.000000 -125.000000
42
- v -1.000000 26.000000 -125.000000
43
- v 10.000000 50.000000 -117.000000
44
- v 21.000000 47.000000 -117.000000
45
- v 30.000000 41.000000 -117.000000
46
- v 38.000000 34.000000 -117.000000
47
- v 44.000000 25.000000 -117.000000
48
- v 49.000000 15.000000 -117.000000
49
- v 51.000000 5.000000 -117.000000
50
- v 51.000000 -6.000000 -117.000000
51
- v 49.000000 -16.000000 -117.000000
52
- v 44.000000 -26.000000 -117.000000
53
- v 38.000000 -35.000000 -117.000000
54
- v 30.000000 -42.000000 -117.000000
55
- v 21.000000 -48.000000 -117.000000
56
- v 10.000000 -51.000000 -117.000000
57
- v 0.000000 -52.000000 -117.000000
58
- v -11.000000 -51.000000 -117.000000
59
- v -22.000000 -48.000000 -117.000000
60
- v -31.000000 -42.000000 -117.000000
61
- v -39.000000 -35.000000 -117.000000
62
- v -45.000000 -26.000000 -117.000000
63
- v -50.000000 -16.000000 -117.000000
64
- v -52.000000 -6.000000 -117.000000
65
- v -52.000000 5.000000 -117.000000
66
- v -50.000000 15.000000 -117.000000
67
- v -45.000000 25.000000 -117.000000
68
- v -39.000000 34.000000 -117.000000
69
- v -31.000000 41.000000 -117.000000
70
- v -22.000000 47.000000 -117.000000
71
- v -11.000000 50.000000 -117.000000
72
- v -1.000000 51.000000 -117.000000
73
- v 15.000000 73.000000 -103.000000
74
- v 30.000000 68.000000 -103.000000
75
- v 43.000000 60.000000 -103.000000
76
- v 55.000000 49.000000 -103.000000
77
- v 64.000000 37.000000 -103.000000
78
- v 70.000000 23.000000 -103.000000
79
- v 74.000000 7.000000 -103.000000
80
- v 74.000000 -8.000000 -103.000000
81
- v 70.000000 -24.000000 -103.000000
82
- v 64.000000 -38.000000 -103.000000
83
- v 55.000000 -50.000000 -103.000000
84
- v 43.000000 -61.000000 -103.000000
85
- v 30.000000 -69.000000 -103.000000
86
- v 15.000000 -74.000000 -103.000000
87
- v 0.000000 -75.000000 -103.000000
88
- v -16.000000 -74.000000 -103.000000
89
- v -31.000000 -69.000000 -103.000000
90
- v -44.000000 -61.000000 -103.000000
91
- v -56.000000 -50.000000 -103.000000
92
- v -65.000000 -38.000000 -103.000000
93
- v -71.000000 -24.000000 -103.000000
94
- v -75.000000 -8.000000 -103.000000
95
- v -75.000000 7.000000 -103.000000
96
- v -71.000000 23.000000 -103.000000
97
- v -65.000000 37.000000 -103.000000
98
- v -56.000000 49.000000 -103.000000
99
- v -44.000000 60.000000 -103.000000
100
- v -31.000000 68.000000 -103.000000
101
- v -16.000000 73.000000 -103.000000
102
- v -1.000000 74.000000 -103.000000
103
- v 19.000000 92.000000 -85.000000
104
- v 38.000000 86.000000 -85.000000
105
- v 55.000000 76.000000 -85.000000
106
- v 70.000000 63.000000 -85.000000
107
- v 81.000000 47.000000 -85.000000
108
- v 89.000000 29.000000 -85.000000
109
- v 93.000000 9.000000 -85.000000
110
- v 93.000000 -10.000000 -85.000000
111
- v 89.000000 -30.000000 -85.000000
112
- v 81.000000 -48.000000 -85.000000
113
- v 70.000000 -64.000000 -85.000000
114
- v 55.000000 -77.000000 -85.000000
115
- v 38.000000 -87.000000 -85.000000
116
- v 19.000000 -93.000000 -85.000000
117
- v 0.000000 -95.000000 -85.000000
118
- v -20.000000 -93.000000 -85.000000
119
- v -39.000000 -87.000000 -85.000000
120
- v -56.000000 -77.000000 -85.000000
121
- v -71.000000 -64.000000 -85.000000
122
- v -82.000000 -48.000000 -85.000000
123
- v -90.000000 -30.000000 -85.000000
124
- v -94.000000 -10.000000 -85.000000
125
- v -94.000000 9.000000 -85.000000
126
- v -90.000000 29.000000 -85.000000
127
- v -82.000000 47.000000 -85.000000
128
- v -71.000000 63.000000 -85.000000
129
- v -56.000000 76.000000 -85.000000
130
- v -39.000000 86.000000 -85.000000
131
- v -20.000000 92.000000 -85.000000
132
- v -1.000000 94.000000 -85.000000
133
- v 22.000000 107.000000 -64.000000
134
- v 44.000000 100.000000 -64.000000
135
- v 64.000000 88.000000 -64.000000
136
- v 81.000000 73.000000 -64.000000
137
- v 95.000000 54.000000 -64.000000
138
- v 104.000000 33.000000 -64.000000
139
- v 109.000000 11.000000 -64.000000
140
- v 109.000000 -12.000000 -64.000000
141
- v 104.000000 -34.000000 -64.000000
142
- v 95.000000 -55.000000 -64.000000
143
- v 81.000000 -74.000000 -64.000000
144
- v 64.000000 -89.000000 -64.000000
145
- v 44.000000 -101.000000 -64.000000
146
- v 22.000000 -108.000000 -64.000000
147
- v 0.000000 -110.000000 -64.000000
148
- v -23.000000 -108.000000 -64.000000
149
- v -45.000000 -101.000000 -64.000000
150
- v -65.000000 -89.000000 -64.000000
151
- v -82.000000 -74.000000 -64.000000
152
- v -96.000000 -55.000000 -64.000000
153
- v -105.000000 -34.000000 -64.000000
154
- v -110.000000 -12.000000 -64.000000
155
- v -110.000000 11.000000 -64.000000
156
- v -105.000000 33.000000 -64.000000
157
- v -96.000000 54.000000 -64.000000
158
- v -82.000000 73.000000 -64.000000
159
- v -65.000000 88.000000 -64.000000
160
- v -45.000000 100.000000 -64.000000
161
- v -23.000000 107.000000 -64.000000
162
- v -1.000000 109.000000 -64.000000
163
- v 25.000000 118.000000 -40.000000
164
- v 49.000000 110.000000 -40.000000
165
- v 70.000000 97.000000 -40.000000
166
- v 89.000000 80.000000 -40.000000
167
- v 104.000000 60.000000 -40.000000
168
- v 114.000000 37.000000 -40.000000
169
- v 120.000000 12.000000 -40.000000
170
- v 120.000000 -13.000000 -40.000000
171
- v 114.000000 -38.000000 -40.000000
172
- v 104.000000 -61.000000 -40.000000
173
- v 89.000000 -81.000000 -40.000000
174
- v 70.000000 -98.000000 -40.000000
175
- v 49.000000 -111.000000 -40.000000
176
- v 25.000000 -119.000000 -40.000000
177
- v 0.000000 -121.000000 -40.000000
178
- v -26.000000 -119.000000 -40.000000
179
- v -50.000000 -111.000000 -40.000000
180
- v -71.000000 -98.000000 -40.000000
181
- v -90.000000 -81.000000 -40.000000
182
- v -105.000000 -61.000000 -40.000000
183
- v -115.000000 -38.000000 -40.000000
184
- v -121.000000 -13.000000 -40.000000
185
- v -121.000000 12.000000 -40.000000
186
- v -115.000000 37.000000 -40.000000
187
- v -105.000000 60.000000 -40.000000
188
- v -90.000000 80.000000 -40.000000
189
- v -71.000000 97.000000 -40.000000
190
- v -50.000000 110.000000 -40.000000
191
- v -26.000000 118.000000 -40.000000
192
- v -1.000000 120.000000 -40.000000
193
- v 26.000000 123.000000 -14.000000
194
- v 51.000000 115.000000 -14.000000
195
- v 74.000000 102.000000 -14.000000
196
- v 93.000000 84.000000 -14.000000
197
- v 109.000000 63.000000 -14.000000
198
- v 120.000000 39.000000 -14.000000
199
- v 125.000000 13.000000 -14.000000
200
- v 125.000000 -14.000000 -14.000000
201
- v 120.000000 -40.000000 -14.000000
202
- v 109.000000 -64.000000 -14.000000
203
- v 93.000000 -85.000000 -14.000000
204
- v 74.000000 -103.000000 -14.000000
205
- v 51.000000 -116.000000 -14.000000
206
- v 26.000000 -124.000000 -14.000000
207
- v 0.000000 -127.000000 -14.000000
208
- v -27.000000 -124.000000 -14.000000
209
- v -52.000000 -116.000000 -14.000000
210
- v -75.000000 -103.000000 -14.000000
211
- v -94.000000 -85.000000 -14.000000
212
- v -110.000000 -64.000000 -14.000000
213
- v -121.000000 -40.000000 -14.000000
214
- v -126.000000 -14.000000 -14.000000
215
- v -126.000000 13.000000 -14.000000
216
- v -121.000000 39.000000 -14.000000
217
- v -110.000000 63.000000 -14.000000
218
- v -94.000000 84.000000 -14.000000
219
- v -75.000000 102.000000 -14.000000
220
- v -52.000000 115.000000 -14.000000
221
- v -27.000000 123.000000 -14.000000
222
- v -1.000000 126.000000 -14.000000
223
- v 26.000000 123.000000 13.000000
224
- v 51.000000 115.000000 13.000000
225
- v 74.000000 102.000000 13.000000
226
- v 93.000000 84.000000 13.000000
227
- v 109.000000 63.000000 13.000000
228
- v 120.000000 39.000000 13.000000
229
- v 125.000000 13.000000 13.000000
230
- v 125.000000 -14.000000 13.000000
231
- v 120.000000 -40.000000 13.000000
232
- v 109.000000 -64.000000 13.000000
233
- v 93.000000 -85.000000 13.000000
234
- v 74.000000 -103.000000 13.000000
235
- v 51.000000 -116.000000 13.000000
236
- v 26.000000 -124.000000 13.000000
237
- v 0.000000 -127.000000 13.000000
238
- v -27.000000 -124.000000 13.000000
239
- v -52.000000 -116.000000 13.000000
240
- v -75.000000 -103.000000 13.000000
241
- v -94.000000 -85.000000 13.000000
242
- v -110.000000 -64.000000 13.000000
243
- v -121.000000 -40.000000 13.000000
244
- v -126.000000 -14.000000 13.000000
245
- v -126.000000 13.000000 13.000000
246
- v -121.000000 39.000000 13.000000
247
- v -110.000000 63.000000 13.000000
248
- v -94.000000 84.000000 13.000000
249
- v -75.000000 102.000000 13.000000
250
- v -52.000000 115.000000 13.000000
251
- v -27.000000 123.000000 13.000000
252
- v -1.000000 126.000000 13.000000
253
- v 25.000000 118.000000 39.000000
254
- v 49.000000 110.000000 39.000000
255
- v 70.000000 97.000000 39.000000
256
- v 89.000000 80.000000 39.000000
257
- v 104.000000 60.000000 39.000000
258
- v 114.000000 37.000000 39.000000
259
- v 120.000000 12.000000 39.000000
260
- v 120.000000 -13.000000 39.000000
261
- v 114.000000 -38.000000 39.000000
262
- v 104.000000 -61.000000 39.000000
263
- v 89.000000 -81.000000 39.000000
264
- v 70.000000 -98.000000 39.000000
265
- v 49.000000 -111.000000 39.000000
266
- v 25.000000 -119.000000 39.000000
267
- v 0.000000 -121.000000 39.000000
268
- v -26.000000 -119.000000 39.000000
269
- v -50.000000 -111.000000 39.000000
270
- v -71.000000 -98.000000 39.000000
271
- v -90.000000 -81.000000 39.000000
272
- v -105.000000 -61.000000 39.000000
273
- v -115.000000 -38.000000 39.000000
274
- v -121.000000 -13.000000 39.000000
275
- v -121.000000 12.000000 39.000000
276
- v -115.000000 37.000000 39.000000
277
- v -105.000000 60.000000 39.000000
278
- v -90.000000 80.000000 39.000000
279
- v -71.000000 97.000000 39.000000
280
- v -50.000000 110.000000 39.000000
281
- v -26.000000 118.000000 39.000000
282
- v -1.000000 120.000000 39.000000
283
- v 22.000000 107.000000 63.000000
284
- v 44.000000 100.000000 63.000000
285
- v 64.000000 88.000000 63.000000
286
- v 81.000000 73.000000 63.000000
287
- v 95.000000 54.000000 63.000000
288
- v 104.000000 33.000000 63.000000
289
- v 109.000000 11.000000 63.000000
290
- v 109.000000 -12.000000 63.000000
291
- v 104.000000 -34.000000 63.000000
292
- v 95.000000 -55.000000 63.000000
293
- v 81.000000 -74.000000 63.000000
294
- v 64.000000 -89.000000 63.000000
295
- v 44.000000 -101.000000 63.000000
296
- v 22.000000 -108.000000 63.000000
297
- v 0.000000 -110.000000 63.000000
298
- v -23.000000 -108.000000 63.000000
299
- v -45.000000 -101.000000 63.000000
300
- v -65.000000 -89.000000 63.000000
301
- v -82.000000 -74.000000 63.000000
302
- v -96.000000 -55.000000 63.000000
303
- v -105.000000 -34.000000 63.000000
304
- v -110.000000 -12.000000 63.000000
305
- v -110.000000 11.000000 63.000000
306
- v -105.000000 33.000000 63.000000
307
- v -96.000000 54.000000 63.000000
308
- v -82.000000 73.000000 63.000000
309
- v -65.000000 88.000000 63.000000
310
- v -45.000000 100.000000 63.000000
311
- v -23.000000 107.000000 63.000000
312
- v -1.000000 109.000000 63.000000
313
- v 19.000000 92.000000 84.000000
314
- v 38.000000 86.000000 84.000000
315
- v 55.000000 76.000000 84.000000
316
- v 70.000000 63.000000 84.000000
317
- v 81.000000 47.000000 84.000000
318
- v 89.000000 29.000000 84.000000
319
- v 93.000000 9.000000 84.000000
320
- v 93.000000 -10.000000 84.000000
321
- v 89.000000 -30.000000 84.000000
322
- v 81.000000 -48.000000 84.000000
323
- v 70.000000 -64.000000 84.000000
324
- v 55.000000 -77.000000 84.000000
325
- v 38.000000 -87.000000 84.000000
326
- v 19.000000 -93.000000 84.000000
327
- v 0.000000 -95.000000 84.000000
328
- v -20.000000 -93.000000 84.000000
329
- v -39.000000 -87.000000 84.000000
330
- v -56.000000 -77.000000 84.000000
331
- v -71.000000 -64.000000 84.000000
332
- v -82.000000 -48.000000 84.000000
333
- v -90.000000 -30.000000 84.000000
334
- v -94.000000 -10.000000 84.000000
335
- v -94.000000 9.000000 84.000000
336
- v -90.000000 29.000000 84.000000
337
- v -82.000000 47.000000 84.000000
338
- v -71.000000 63.000000 84.000000
339
- v -56.000000 76.000000 84.000000
340
- v -39.000000 86.000000 84.000000
341
- v -20.000000 92.000000 84.000000
342
- v -1.000000 94.000000 84.000000
343
- v 15.000000 73.000000 102.000000
344
- v 30.000000 68.000000 102.000000
345
- v 43.000000 60.000000 102.000000
346
- v 55.000000 49.000000 102.000000
347
- v 64.000000 37.000000 102.000000
348
- v 70.000000 23.000000 102.000000
349
- v 74.000000 7.000000 102.000000
350
- v 74.000000 -8.000000 102.000000
351
- v 70.000000 -24.000000 102.000000
352
- v 64.000000 -38.000000 102.000000
353
- v 55.000000 -50.000000 102.000000
354
- v 43.000000 -61.000000 102.000000
355
- v 30.000000 -69.000000 102.000000
356
- v 15.000000 -74.000000 102.000000
357
- v 0.000000 -75.000000 102.000000
358
- v -16.000000 -74.000000 102.000000
359
- v -31.000000 -69.000000 102.000000
360
- v -44.000000 -61.000000 102.000000
361
- v -56.000000 -50.000000 102.000000
362
- v -65.000000 -38.000000 102.000000
363
- v -71.000000 -24.000000 102.000000
364
- v -75.000000 -8.000000 102.000000
365
- v -75.000000 7.000000 102.000000
366
- v -71.000000 23.000000 102.000000
367
- v -65.000000 37.000000 102.000000
368
- v -56.000000 49.000000 102.000000
369
- v -44.000000 60.000000 102.000000
370
- v -31.000000 68.000000 102.000000
371
- v -16.000000 73.000000 102.000000
372
- v -1.000000 74.000000 102.000000
373
- v 10.000000 50.000000 116.000000
374
- v 21.000000 47.000000 116.000000
375
- v 30.000000 41.000000 116.000000
376
- v 38.000000 34.000000 116.000000
377
- v 44.000000 25.000000 116.000000
378
- v 49.000000 15.000000 116.000000
379
- v 51.000000 5.000000 116.000000
380
- v 51.000000 -6.000000 116.000000
381
- v 49.000000 -16.000000 116.000000
382
- v 44.000000 -26.000000 116.000000
383
- v 38.000000 -35.000000 116.000000
384
- v 30.000000 -42.000000 116.000000
385
- v 21.000000 -48.000000 116.000000
386
- v 10.000000 -51.000000 116.000000
387
- v 0.000000 -52.000000 116.000000
388
- v -11.000000 -51.000000 116.000000
389
- v -22.000000 -48.000000 116.000000
390
- v -31.000000 -42.000000 116.000000
391
- v -39.000000 -35.000000 116.000000
392
- v -45.000000 -26.000000 116.000000
393
- v -50.000000 -16.000000 116.000000
394
- v -52.000000 -6.000000 116.000000
395
- v -52.000000 5.000000 116.000000
396
- v -50.000000 15.000000 116.000000
397
- v -45.000000 25.000000 116.000000
398
- v -39.000000 34.000000 116.000000
399
- v -31.000000 41.000000 116.000000
400
- v -22.000000 47.000000 116.000000
401
- v -11.000000 50.000000 116.000000
402
- v -1.000000 51.000000 116.000000
403
- v 5.000000 25.000000 124.000000
404
- v 10.000000 24.000000 124.000000
405
- v 15.000000 21.000000 124.000000
406
- v 19.000000 17.000000 124.000000
407
- v 22.000000 13.000000 124.000000
408
- v 25.000000 8.000000 124.000000
409
- v 26.000000 2.000000 124.000000
410
- v 26.000000 -3.000000 124.000000
411
- v 25.000000 -9.000000 124.000000
412
- v 22.000000 -14.000000 124.000000
413
- v 19.000000 -18.000000 124.000000
414
- v 15.000000 -22.000000 124.000000
415
- v 10.000000 -25.000000 124.000000
416
- v 5.000000 -26.000000 124.000000
417
- v 0.000000 -27.000000 124.000000
418
- v -6.000000 -26.000000 124.000000
419
- v -11.000000 -25.000000 124.000000
420
- v -16.000000 -22.000000 124.000000
421
- v -20.000000 -18.000000 124.000000
422
- v -23.000000 -14.000000 124.000000
423
- v -26.000000 -9.000000 124.000000
424
- v -27.000000 -3.000000 124.000000
425
- v -27.000000 2.000000 124.000000
426
- v -26.000000 8.000000 124.000000
427
- v -23.000000 13.000000 124.000000
428
- v -20.000000 17.000000 124.000000
429
- v -16.000000 21.000000 124.000000
430
- v -11.000000 24.000000 124.000000
431
- v -6.000000 25.000000 124.000000
432
- v -1.000000 26.000000 124.000000
433
- v 0.000000 0.000000 127.000000
434
- # 422 vertices, 0 vertices normals
435
-
436
- f 1 2 3
437
- f 1 3 4
438
- f 1 4 5
439
- f 1 5 6
440
- f 1 6 7
441
- f 1 7 8
442
- f 1 8 9
443
- f 1 9 10
444
- f 1 10 11
445
- f 1 11 12
446
- f 1 12 13
447
- f 1 13 14
448
- f 1 14 15
449
- f 1 15 16
450
- f 1 16 17
451
- f 1 17 18
452
- f 1 18 19
453
- f 1 19 20
454
- f 1 20 21
455
- f 1 21 22
456
- f 1 22 23
457
- f 1 23 24
458
- f 1 24 25
459
- f 1 25 26
460
- f 1 26 27
461
- f 1 27 28
462
- f 1 28 29
463
- f 1 29 30
464
- f 1 30 31
465
- f 1 31 2
466
- f 2 33 3
467
- f 33 2 32
468
- f 3 34 4
469
- f 34 3 33
470
- f 4 35 5
471
- f 35 4 34
472
- f 5 36 6
473
- f 36 5 35
474
- f 6 37 7
475
- f 37 6 36
476
- f 7 38 8
477
- f 38 7 37
478
- f 8 39 9
479
- f 39 8 38
480
- f 9 40 10
481
- f 40 9 39
482
- f 10 41 11
483
- f 41 10 40
484
- f 11 42 12
485
- f 42 11 41
486
- f 12 43 13
487
- f 43 12 42
488
- f 13 44 14
489
- f 44 13 43
490
- f 14 45 15
491
- f 45 14 44
492
- f 15 46 16
493
- f 46 15 45
494
- f 16 47 17
495
- f 47 16 46
496
- f 17 48 18
497
- f 48 17 47
498
- f 18 49 19
499
- f 49 18 48
500
- f 19 50 20
501
- f 50 19 49
502
- f 20 51 21
503
- f 51 20 50
504
- f 21 52 22
505
- f 52 21 51
506
- f 22 53 23
507
- f 53 22 52
508
- f 23 54 24
509
- f 54 23 53
510
- f 24 55 25
511
- f 55 24 54
512
- f 25 56 26
513
- f 56 25 55
514
- f 26 57 27
515
- f 57 26 56
516
- f 27 58 28
517
- f 58 27 57
518
- f 28 59 29
519
- f 59 28 58
520
- f 29 60 30
521
- f 60 29 59
522
- f 30 61 31
523
- f 61 30 60
524
- f 31 32 2
525
- f 32 31 61
526
- f 32 63 33
527
- f 63 32 62
528
- f 33 64 34
529
- f 64 33 63
530
- f 34 65 35
531
- f 65 34 64
532
- f 35 66 36
533
- f 66 35 65
534
- f 36 67 37
535
- f 67 36 66
536
- f 37 68 38
537
- f 68 37 67
538
- f 38 69 39
539
- f 69 38 68
540
- f 39 70 40
541
- f 70 39 69
542
- f 40 71 41
543
- f 71 40 70
544
- f 41 72 42
545
- f 72 41 71
546
- f 42 73 43
547
- f 73 42 72
548
- f 43 74 44
549
- f 74 43 73
550
- f 44 75 45
551
- f 75 44 74
552
- f 45 76 46
553
- f 76 45 75
554
- f 46 77 47
555
- f 77 46 76
556
- f 47 78 48
557
- f 78 47 77
558
- f 48 79 49
559
- f 79 48 78
560
- f 49 80 50
561
- f 80 49 79
562
- f 50 81 51
563
- f 81 50 80
564
- f 51 82 52
565
- f 82 51 81
566
- f 52 83 53
567
- f 83 52 82
568
- f 53 84 54
569
- f 84 53 83
570
- f 54 85 55
571
- f 85 54 84
572
- f 55 86 56
573
- f 86 55 85
574
- f 56 87 57
575
- f 87 56 86
576
- f 57 88 58
577
- f 88 57 87
578
- f 58 89 59
579
- f 89 58 88
580
- f 59 90 60
581
- f 90 59 89
582
- f 60 91 61
583
- f 91 60 90
584
- f 61 62 32
585
- f 62 61 91
586
- f 62 93 63
587
- f 93 62 92
588
- f 63 94 64
589
- f 94 63 93
590
- f 64 95 65
591
- f 95 64 94
592
- f 65 96 66
593
- f 96 65 95
594
- f 66 97 67
595
- f 97 66 96
596
- f 67 98 68
597
- f 98 67 97
598
- f 68 99 69
599
- f 99 68 98
600
- f 69 100 70
601
- f 100 69 99
602
- f 70 101 71
603
- f 101 70 100
604
- f 71 102 72
605
- f 102 71 101
606
- f 72 103 73
607
- f 103 72 102
608
- f 73 104 74
609
- f 104 73 103
610
- f 74 105 75
611
- f 105 74 104
612
- f 75 106 76
613
- f 106 75 105
614
- f 76 107 77
615
- f 107 76 106
616
- f 77 108 78
617
- f 108 77 107
618
- f 78 109 79
619
- f 109 78 108
620
- f 79 110 80
621
- f 110 79 109
622
- f 80 111 81
623
- f 111 80 110
624
- f 81 112 82
625
- f 112 81 111
626
- f 82 113 83
627
- f 113 82 112
628
- f 83 114 84
629
- f 114 83 113
630
- f 84 115 85
631
- f 115 84 114
632
- f 85 116 86
633
- f 116 85 115
634
- f 86 117 87
635
- f 117 86 116
636
- f 87 118 88
637
- f 118 87 117
638
- f 88 119 89
639
- f 119 88 118
640
- f 89 120 90
641
- f 120 89 119
642
- f 90 121 91
643
- f 121 90 120
644
- f 91 92 62
645
- f 92 91 121
646
- f 92 123 93
647
- f 123 92 122
648
- f 93 124 94
649
- f 124 93 123
650
- f 94 125 95
651
- f 125 94 124
652
- f 95 126 96
653
- f 126 95 125
654
- f 96 127 97
655
- f 127 96 126
656
- f 97 128 98
657
- f 128 97 127
658
- f 98 129 99
659
- f 129 98 128
660
- f 99 130 100
661
- f 130 99 129
662
- f 100 131 101
663
- f 131 100 130
664
- f 101 132 102
665
- f 132 101 131
666
- f 102 133 103
667
- f 133 102 132
668
- f 103 134 104
669
- f 134 103 133
670
- f 104 135 105
671
- f 135 104 134
672
- f 105 136 106
673
- f 136 105 135
674
- f 106 137 107
675
- f 137 106 136
676
- f 107 138 108
677
- f 138 107 137
678
- f 108 139 109
679
- f 139 108 138
680
- f 109 140 110
681
- f 140 109 139
682
- f 110 141 111
683
- f 141 110 140
684
- f 111 142 112
685
- f 142 111 141
686
- f 112 143 113
687
- f 143 112 142
688
- f 113 144 114
689
- f 144 113 143
690
- f 114 145 115
691
- f 145 114 144
692
- f 115 146 116
693
- f 146 115 145
694
- f 116 147 117
695
- f 147 116 146
696
- f 117 148 118
697
- f 148 117 147
698
- f 118 149 119
699
- f 149 118 148
700
- f 119 150 120
701
- f 150 119 149
702
- f 120 151 121
703
- f 151 120 150
704
- f 121 122 92
705
- f 122 121 151
706
- f 122 153 123
707
- f 153 122 152
708
- f 123 154 124
709
- f 154 123 153
710
- f 124 155 125
711
- f 155 124 154
712
- f 125 156 126
713
- f 156 125 155
714
- f 126 157 127
715
- f 157 126 156
716
- f 127 158 128
717
- f 158 127 157
718
- f 128 159 129
719
- f 159 128 158
720
- f 129 160 130
721
- f 160 129 159
722
- f 130 161 131
723
- f 161 130 160
724
- f 131 162 132
725
- f 162 131 161
726
- f 132 163 133
727
- f 163 132 162
728
- f 133 164 134
729
- f 164 133 163
730
- f 134 165 135
731
- f 165 134 164
732
- f 135 166 136
733
- f 166 135 165
734
- f 136 167 137
735
- f 167 136 166
736
- f 137 168 138
737
- f 168 137 167
738
- f 138 169 139
739
- f 169 138 168
740
- f 139 170 140
741
- f 170 139 169
742
- f 140 171 141
743
- f 171 140 170
744
- f 141 172 142
745
- f 172 141 171
746
- f 142 173 143
747
- f 173 142 172
748
- f 143 174 144
749
- f 174 143 173
750
- f 144 175 145
751
- f 175 144 174
752
- f 145 176 146
753
- f 176 145 175
754
- f 146 177 147
755
- f 177 146 176
756
- f 147 178 148
757
- f 178 147 177
758
- f 148 179 149
759
- f 179 148 178
760
- f 149 180 150
761
- f 180 149 179
762
- f 150 181 151
763
- f 181 150 180
764
- f 151 152 122
765
- f 152 151 181
766
- f 152 183 153
767
- f 183 152 182
768
- f 153 184 154
769
- f 184 153 183
770
- f 154 185 155
771
- f 185 154 184
772
- f 155 186 156
773
- f 186 155 185
774
- f 156 187 157
775
- f 187 156 186
776
- f 157 188 158
777
- f 188 157 187
778
- f 158 189 159
779
- f 189 158 188
780
- f 159 190 160
781
- f 190 159 189
782
- f 160 191 161
783
- f 191 160 190
784
- f 161 192 162
785
- f 192 161 191
786
- f 162 193 163
787
- f 193 162 192
788
- f 163 194 164
789
- f 194 163 193
790
- f 164 195 165
791
- f 195 164 194
792
- f 165 196 166
793
- f 196 165 195
794
- f 166 197 167
795
- f 197 166 196
796
- f 167 198 168
797
- f 198 167 197
798
- f 168 199 169
799
- f 199 168 198
800
- f 169 200 170
801
- f 200 169 199
802
- f 170 201 171
803
- f 201 170 200
804
- f 171 202 172
805
- f 202 171 201
806
- f 172 203 173
807
- f 203 172 202
808
- f 173 204 174
809
- f 204 173 203
810
- f 174 205 175
811
- f 205 174 204
812
- f 175 206 176
813
- f 206 175 205
814
- f 176 207 177
815
- f 207 176 206
816
- f 177 208 178
817
- f 208 177 207
818
- f 178 209 179
819
- f 209 178 208
820
- f 179 210 180
821
- f 210 179 209
822
- f 180 211 181
823
- f 211 180 210
824
- f 181 182 152
825
- f 182 181 211
826
- f 182 213 183
827
- f 213 182 212
828
- f 183 214 184
829
- f 214 183 213
830
- f 184 215 185
831
- f 215 184 214
832
- f 185 216 186
833
- f 216 185 215
834
- f 186 217 187
835
- f 217 186 216
836
- f 187 218 188
837
- f 218 187 217
838
- f 188 219 189
839
- f 219 188 218
840
- f 189 220 190
841
- f 220 189 219
842
- f 190 221 191
843
- f 221 190 220
844
- f 191 222 192
845
- f 222 191 221
846
- f 192 223 193
847
- f 223 192 222
848
- f 193 224 194
849
- f 224 193 223
850
- f 194 225 195
851
- f 225 194 224
852
- f 195 226 196
853
- f 226 195 225
854
- f 196 227 197
855
- f 227 196 226
856
- f 197 228 198
857
- f 228 197 227
858
- f 198 229 199
859
- f 229 198 228
860
- f 199 230 200
861
- f 230 199 229
862
- f 200 231 201
863
- f 231 200 230
864
- f 201 232 202
865
- f 232 201 231
866
- f 202 233 203
867
- f 233 202 232
868
- f 203 234 204
869
- f 234 203 233
870
- f 204 235 205
871
- f 235 204 234
872
- f 205 236 206
873
- f 236 205 235
874
- f 206 237 207
875
- f 237 206 236
876
- f 207 238 208
877
- f 238 207 237
878
- f 208 239 209
879
- f 239 208 238
880
- f 209 240 210
881
- f 240 209 239
882
- f 210 241 211
883
- f 241 210 240
884
- f 211 212 182
885
- f 212 211 241
886
- f 212 243 213
887
- f 243 212 242
888
- f 213 244 214
889
- f 244 213 243
890
- f 214 245 215
891
- f 245 214 244
892
- f 215 246 216
893
- f 246 215 245
894
- f 216 247 217
895
- f 247 216 246
896
- f 217 248 218
897
- f 248 217 247
898
- f 218 249 219
899
- f 249 218 248
900
- f 219 250 220
901
- f 250 219 249
902
- f 220 251 221
903
- f 251 220 250
904
- f 221 252 222
905
- f 252 221 251
906
- f 222 253 223
907
- f 253 222 252
908
- f 223 254 224
909
- f 254 223 253
910
- f 224 255 225
911
- f 255 224 254
912
- f 225 256 226
913
- f 256 225 255
914
- f 226 257 227
915
- f 257 226 256
916
- f 227 258 228
917
- f 258 227 257
918
- f 228 259 229
919
- f 259 228 258
920
- f 229 260 230
921
- f 260 229 259
922
- f 230 261 231
923
- f 261 230 260
924
- f 231 262 232
925
- f 262 231 261
926
- f 232 263 233
927
- f 263 232 262
928
- f 233 264 234
929
- f 264 233 263
930
- f 234 265 235
931
- f 265 234 264
932
- f 235 266 236
933
- f 266 235 265
934
- f 236 267 237
935
- f 267 236 266
936
- f 237 268 238
937
- f 268 237 267
938
- f 238 269 239
939
- f 269 238 268
940
- f 239 270 240
941
- f 270 239 269
942
- f 240 271 241
943
- f 271 240 270
944
- f 241 242 212
945
- f 242 241 271
946
- f 242 273 243
947
- f 273 242 272
948
- f 243 274 244
949
- f 274 243 273
950
- f 244 275 245
951
- f 275 244 274
952
- f 245 276 246
953
- f 276 245 275
954
- f 246 277 247
955
- f 277 246 276
956
- f 247 278 248
957
- f 278 247 277
958
- f 248 279 249
959
- f 279 248 278
960
- f 249 280 250
961
- f 280 249 279
962
- f 250 281 251
963
- f 281 250 280
964
- f 251 282 252
965
- f 282 251 281
966
- f 252 283 253
967
- f 283 252 282
968
- f 253 284 254
969
- f 284 253 283
970
- f 254 285 255
971
- f 285 254 284
972
- f 255 286 256
973
- f 286 255 285
974
- f 256 287 257
975
- f 287 256 286
976
- f 257 288 258
977
- f 288 257 287
978
- f 258 289 259
979
- f 289 258 288
980
- f 259 290 260
981
- f 290 259 289
982
- f 260 291 261
983
- f 291 260 290
984
- f 261 292 262
985
- f 292 261 291
986
- f 262 293 263
987
- f 293 262 292
988
- f 263 294 264
989
- f 294 263 293
990
- f 264 295 265
991
- f 295 264 294
992
- f 265 296 266
993
- f 296 265 295
994
- f 266 297 267
995
- f 297 266 296
996
- f 267 298 268
997
- f 298 267 297
998
- f 268 299 269
999
- f 299 268 298
1000
- f 269 300 270
1001
- f 300 269 299
1002
- f 270 301 271
1003
- f 301 270 300
1004
- f 271 272 242
1005
- f 272 271 301
1006
- f 272 303 273
1007
- f 303 272 302
1008
- f 273 304 274
1009
- f 304 273 303
1010
- f 274 305 275
1011
- f 305 274 304
1012
- f 275 306 276
1013
- f 306 275 305
1014
- f 276 307 277
1015
- f 307 276 306
1016
- f 277 308 278
1017
- f 308 277 307
1018
- f 278 309 279
1019
- f 309 278 308
1020
- f 279 310 280
1021
- f 310 279 309
1022
- f 280 311 281
1023
- f 311 280 310
1024
- f 281 312 282
1025
- f 312 281 311
1026
- f 282 313 283
1027
- f 313 282 312
1028
- f 283 314 284
1029
- f 314 283 313
1030
- f 284 315 285
1031
- f 315 284 314
1032
- f 285 316 286
1033
- f 316 285 315
1034
- f 286 317 287
1035
- f 317 286 316
1036
- f 287 318 288
1037
- f 318 287 317
1038
- f 288 319 289
1039
- f 319 288 318
1040
- f 289 320 290
1041
- f 320 289 319
1042
- f 290 321 291
1043
- f 321 290 320
1044
- f 291 322 292
1045
- f 322 291 321
1046
- f 292 323 293
1047
- f 323 292 322
1048
- f 293 324 294
1049
- f 324 293 323
1050
- f 294 325 295
1051
- f 325 294 324
1052
- f 295 326 296
1053
- f 326 295 325
1054
- f 296 327 297
1055
- f 327 296 326
1056
- f 297 328 298
1057
- f 328 297 327
1058
- f 298 329 299
1059
- f 329 298 328
1060
- f 299 330 300
1061
- f 330 299 329
1062
- f 300 331 301
1063
- f 331 300 330
1064
- f 301 302 272
1065
- f 302 301 331
1066
- f 302 333 303
1067
- f 333 302 332
1068
- f 303 334 304
1069
- f 334 303 333
1070
- f 304 335 305
1071
- f 335 304 334
1072
- f 305 336 306
1073
- f 336 305 335
1074
- f 306 337 307
1075
- f 337 306 336
1076
- f 307 338 308
1077
- f 338 307 337
1078
- f 308 339 309
1079
- f 339 308 338
1080
- f 309 340 310
1081
- f 340 309 339
1082
- f 310 341 311
1083
- f 341 310 340
1084
- f 311 342 312
1085
- f 342 311 341
1086
- f 312 343 313
1087
- f 343 312 342
1088
- f 313 344 314
1089
- f 344 313 343
1090
- f 314 345 315
1091
- f 345 314 344
1092
- f 315 346 316
1093
- f 346 315 345
1094
- f 316 347 317
1095
- f 347 316 346
1096
- f 317 348 318
1097
- f 348 317 347
1098
- f 318 349 319
1099
- f 349 318 348
1100
- f 319 350 320
1101
- f 350 319 349
1102
- f 320 351 321
1103
- f 351 320 350
1104
- f 321 352 322
1105
- f 352 321 351
1106
- f 322 353 323
1107
- f 353 322 352
1108
- f 323 354 324
1109
- f 354 323 353
1110
- f 324 355 325
1111
- f 355 324 354
1112
- f 325 356 326
1113
- f 356 325 355
1114
- f 326 357 327
1115
- f 357 326 356
1116
- f 327 358 328
1117
- f 358 327 357
1118
- f 328 359 329
1119
- f 359 328 358
1120
- f 329 360 330
1121
- f 360 329 359
1122
- f 330 361 331
1123
- f 361 330 360
1124
- f 331 332 302
1125
- f 332 331 361
1126
- f 332 363 333
1127
- f 363 332 362
1128
- f 333 364 334
1129
- f 364 333 363
1130
- f 334 365 335
1131
- f 365 334 364
1132
- f 335 366 336
1133
- f 366 335 365
1134
- f 336 367 337
1135
- f 367 336 366
1136
- f 337 368 338
1137
- f 368 337 367
1138
- f 338 369 339
1139
- f 369 338 368
1140
- f 339 370 340
1141
- f 370 339 369
1142
- f 340 371 341
1143
- f 371 340 370
1144
- f 341 372 342
1145
- f 372 341 371
1146
- f 342 373 343
1147
- f 373 342 372
1148
- f 343 374 344
1149
- f 374 343 373
1150
- f 344 375 345
1151
- f 375 344 374
1152
- f 345 376 346
1153
- f 376 345 375
1154
- f 346 377 347
1155
- f 377 346 376
1156
- f 347 378 348
1157
- f 378 347 377
1158
- f 348 379 349
1159
- f 379 348 378
1160
- f 349 380 350
1161
- f 380 349 379
1162
- f 350 381 351
1163
- f 381 350 380
1164
- f 351 382 352
1165
- f 382 351 381
1166
- f 352 383 353
1167
- f 383 352 382
1168
- f 353 384 354
1169
- f 384 353 383
1170
- f 354 385 355
1171
- f 385 354 384
1172
- f 355 386 356
1173
- f 386 355 385
1174
- f 356 387 357
1175
- f 387 356 386
1176
- f 357 388 358
1177
- f 388 357 387
1178
- f 358 389 359
1179
- f 389 358 388
1180
- f 359 390 360
1181
- f 390 359 389
1182
- f 360 391 361
1183
- f 391 360 390
1184
- f 361 362 332
1185
- f 362 361 391
1186
- f 362 393 363
1187
- f 393 362 392
1188
- f 363 394 364
1189
- f 394 363 393
1190
- f 364 395 365
1191
- f 395 364 394
1192
- f 365 396 366
1193
- f 396 365 395
1194
- f 366 397 367
1195
- f 397 366 396
1196
- f 367 398 368
1197
- f 398 367 397
1198
- f 368 399 369
1199
- f 399 368 398
1200
- f 369 400 370
1201
- f 400 369 399
1202
- f 370 401 371
1203
- f 401 370 400
1204
- f 371 402 372
1205
- f 402 371 401
1206
- f 372 403 373
1207
- f 403 372 402
1208
- f 373 404 374
1209
- f 404 373 403
1210
- f 374 405 375
1211
- f 405 374 404
1212
- f 375 406 376
1213
- f 406 375 405
1214
- f 376 407 377
1215
- f 407 376 406
1216
- f 377 408 378
1217
- f 408 377 407
1218
- f 378 409 379
1219
- f 409 378 408
1220
- f 379 410 380
1221
- f 410 379 409
1222
- f 380 411 381
1223
- f 411 380 410
1224
- f 381 412 382
1225
- f 412 381 411
1226
- f 382 413 383
1227
- f 413 382 412
1228
- f 383 414 384
1229
- f 414 383 413
1230
- f 384 415 385
1231
- f 415 384 414
1232
- f 385 416 386
1233
- f 416 385 415
1234
- f 386 417 387
1235
- f 417 386 416
1236
- f 387 418 388
1237
- f 418 387 417
1238
- f 388 419 389
1239
- f 419 388 418
1240
- f 389 420 390
1241
- f 420 389 419
1242
- f 390 421 391
1243
- f 421 390 420
1244
- f 391 392 362
1245
- f 392 391 421
1246
- f 392 422 393
1247
- f 393 422 394
1248
- f 394 422 395
1249
- f 395 422 396
1250
- f 396 422 397
1251
- f 397 422 398
1252
- f 398 422 399
1253
- f 399 422 400
1254
- f 400 422 401
1255
- f 401 422 402
1256
- f 402 422 403
1257
- f 403 422 404
1258
- f 404 422 405
1259
- f 405 422 406
1260
- f 406 422 407
1261
- f 407 422 408
1262
- f 408 422 409
1263
- f 409 422 410
1264
- f 410 422 411
1265
- f 411 422 412
1266
- f 412 422 413
1267
- f 413 422 414
1268
- f 414 422 415
1269
- f 415 422 416
1270
- f 416 422 417
1271
- f 417 422 418
1272
- f 418 422 419
1273
- f 419 422 420
1274
- f 420 422 421
1275
- f 421 422 392
1276
- # 840 faces, 0 coords texture
1277
-
1278
- # End of File
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/data/unittest/sphere.ply DELETED
@@ -1,1271 +0,0 @@
1
- ply
2
- format ascii 1.0
3
- element vertex 422
4
- property float x
5
- property float y
6
- property float z
7
- element face 840
8
- property list uchar int vertex_indices
9
- end_header
10
- 0 0 -127
11
- 5 25 -125
12
- 10 24 -125
13
- 15 21 -125
14
- 19 17 -125
15
- 22 13 -125
16
- 25 8 -125
17
- 26 2 -125
18
- 26 -3 -125
19
- 25 -9 -125
20
- 22 -14 -125
21
- 19 -18 -125
22
- 15 -22 -125
23
- 10 -25 -125
24
- 5 -26 -125
25
- 0 -27 -125
26
- -6 -26 -125
27
- -11 -25 -125
28
- -16 -22 -125
29
- -20 -18 -125
30
- -23 -14 -125
31
- -26 -9 -125
32
- -27 -3 -125
33
- -27 2 -125
34
- -26 8 -125
35
- -23 13 -125
36
- -20 17 -125
37
- -16 21 -125
38
- -11 24 -125
39
- -6 25 -125
40
- -1 26 -125
41
- 10 50 -117
42
- 21 47 -117
43
- 30 41 -117
44
- 38 34 -117
45
- 44 25 -117
46
- 49 15 -117
47
- 51 5 -117
48
- 51 -6 -117
49
- 49 -16 -117
50
- 44 -26 -117
51
- 38 -35 -117
52
- 30 -42 -117
53
- 21 -48 -117
54
- 10 -51 -117
55
- 0 -52 -117
56
- -11 -51 -117
57
- -22 -48 -117
58
- -31 -42 -117
59
- -39 -35 -117
60
- -45 -26 -117
61
- -50 -16 -117
62
- -52 -6 -117
63
- -52 5 -117
64
- -50 15 -117
65
- -45 25 -117
66
- -39 34 -117
67
- -31 41 -117
68
- -22 47 -117
69
- -11 50 -117
70
- -1 51 -117
71
- 15 73 -103
72
- 30 68 -103
73
- 43 60 -103
74
- 55 49 -103
75
- 64 37 -103
76
- 70 23 -103
77
- 74 7 -103
78
- 74 -8 -103
79
- 70 -24 -103
80
- 64 -38 -103
81
- 55 -50 -103
82
- 43 -61 -103
83
- 30 -69 -103
84
- 15 -74 -103
85
- 0 -75 -103
86
- -16 -74 -103
87
- -31 -69 -103
88
- -44 -61 -103
89
- -56 -50 -103
90
- -65 -38 -103
91
- -71 -24 -103
92
- -75 -8 -103
93
- -75 7 -103
94
- -71 23 -103
95
- -65 37 -103
96
- -56 49 -103
97
- -44 60 -103
98
- -31 68 -103
99
- -16 73 -103
100
- -1 74 -103
101
- 19 92 -85
102
- 38 86 -85
103
- 55 76 -85
104
- 70 63 -85
105
- 81 47 -85
106
- 89 29 -85
107
- 93 9 -85
108
- 93 -10 -85
109
- 89 -30 -85
110
- 81 -48 -85
111
- 70 -64 -85
112
- 55 -77 -85
113
- 38 -87 -85
114
- 19 -93 -85
115
- 0 -95 -85
116
- -20 -93 -85
117
- -39 -87 -85
118
- -56 -77 -85
119
- -71 -64 -85
120
- -82 -48 -85
121
- -90 -30 -85
122
- -94 -10 -85
123
- -94 9 -85
124
- -90 29 -85
125
- -82 47 -85
126
- -71 63 -85
127
- -56 76 -85
128
- -39 86 -85
129
- -20 92 -85
130
- -1 94 -85
131
- 22 107 -64
132
- 44 100 -64
133
- 64 88 -64
134
- 81 73 -64
135
- 95 54 -64
136
- 104 33 -64
137
- 109 11 -64
138
- 109 -12 -64
139
- 104 -34 -64
140
- 95 -55 -64
141
- 81 -74 -64
142
- 64 -89 -64
143
- 44 -101 -64
144
- 22 -108 -64
145
- 0 -110 -64
146
- -23 -108 -64
147
- -45 -101 -64
148
- -65 -89 -64
149
- -82 -74 -64
150
- -96 -55 -64
151
- -105 -34 -64
152
- -110 -12 -64
153
- -110 11 -64
154
- -105 33 -64
155
- -96 54 -64
156
- -82 73 -64
157
- -65 88 -64
158
- -45 100 -64
159
- -23 107 -64
160
- -1 109 -64
161
- 25 118 -40
162
- 49 110 -40
163
- 70 97 -40
164
- 89 80 -40
165
- 104 60 -40
166
- 114 37 -40
167
- 120 12 -40
168
- 120 -13 -40
169
- 114 -38 -40
170
- 104 -61 -40
171
- 89 -81 -40
172
- 70 -98 -40
173
- 49 -111 -40
174
- 25 -119 -40
175
- 0 -121 -40
176
- -26 -119 -40
177
- -50 -111 -40
178
- -71 -98 -40
179
- -90 -81 -40
180
- -105 -61 -40
181
- -115 -38 -40
182
- -121 -13 -40
183
- -121 12 -40
184
- -115 37 -40
185
- -105 60 -40
186
- -90 80 -40
187
- -71 97 -40
188
- -50 110 -40
189
- -26 118 -40
190
- -1 120 -40
191
- 26 123 -14
192
- 51 115 -14
193
- 74 102 -14
194
- 93 84 -14
195
- 109 63 -14
196
- 120 39 -14
197
- 125 13 -14
198
- 125 -14 -14
199
- 120 -40 -14
200
- 109 -64 -14
201
- 93 -85 -14
202
- 74 -103 -14
203
- 51 -116 -14
204
- 26 -124 -14
205
- 0 -127 -14
206
- -27 -124 -14
207
- -52 -116 -14
208
- -75 -103 -14
209
- -94 -85 -14
210
- -110 -64 -14
211
- -121 -40 -14
212
- -126 -14 -14
213
- -126 13 -14
214
- -121 39 -14
215
- -110 63 -14
216
- -94 84 -14
217
- -75 102 -14
218
- -52 115 -14
219
- -27 123 -14
220
- -1 126 -14
221
- 26 123 13
222
- 51 115 13
223
- 74 102 13
224
- 93 84 13
225
- 109 63 13
226
- 120 39 13
227
- 125 13 13
228
- 125 -14 13
229
- 120 -40 13
230
- 109 -64 13
231
- 93 -85 13
232
- 74 -103 13
233
- 51 -116 13
234
- 26 -124 13
235
- 0 -127 13
236
- -27 -124 13
237
- -52 -116 13
238
- -75 -103 13
239
- -94 -85 13
240
- -110 -64 13
241
- -121 -40 13
242
- -126 -14 13
243
- -126 13 13
244
- -121 39 13
245
- -110 63 13
246
- -94 84 13
247
- -75 102 13
248
- -52 115 13
249
- -27 123 13
250
- -1 126 13
251
- 25 118 39
252
- 49 110 39
253
- 70 97 39
254
- 89 80 39
255
- 104 60 39
256
- 114 37 39
257
- 120 12 39
258
- 120 -13 39
259
- 114 -38 39
260
- 104 -61 39
261
- 89 -81 39
262
- 70 -98 39
263
- 49 -111 39
264
- 25 -119 39
265
- 0 -121 39
266
- -26 -119 39
267
- -50 -111 39
268
- -71 -98 39
269
- -90 -81 39
270
- -105 -61 39
271
- -115 -38 39
272
- -121 -13 39
273
- -121 12 39
274
- -115 37 39
275
- -105 60 39
276
- -90 80 39
277
- -71 97 39
278
- -50 110 39
279
- -26 118 39
280
- -1 120 39
281
- 22 107 63
282
- 44 100 63
283
- 64 88 63
284
- 81 73 63
285
- 95 54 63
286
- 104 33 63
287
- 109 11 63
288
- 109 -12 63
289
- 104 -34 63
290
- 95 -55 63
291
- 81 -74 63
292
- 64 -89 63
293
- 44 -101 63
294
- 22 -108 63
295
- 0 -110 63
296
- -23 -108 63
297
- -45 -101 63
298
- -65 -89 63
299
- -82 -74 63
300
- -96 -55 63
301
- -105 -34 63
302
- -110 -12 63
303
- -110 11 63
304
- -105 33 63
305
- -96 54 63
306
- -82 73 63
307
- -65 88 63
308
- -45 100 63
309
- -23 107 63
310
- -1 109 63
311
- 19 92 84
312
- 38 86 84
313
- 55 76 84
314
- 70 63 84
315
- 81 47 84
316
- 89 29 84
317
- 93 9 84
318
- 93 -10 84
319
- 89 -30 84
320
- 81 -48 84
321
- 70 -64 84
322
- 55 -77 84
323
- 38 -87 84
324
- 19 -93 84
325
- 0 -95 84
326
- -20 -93 84
327
- -39 -87 84
328
- -56 -77 84
329
- -71 -64 84
330
- -82 -48 84
331
- -90 -30 84
332
- -94 -10 84
333
- -94 9 84
334
- -90 29 84
335
- -82 47 84
336
- -71 63 84
337
- -56 76 84
338
- -39 86 84
339
- -20 92 84
340
- -1 94 84
341
- 15 73 102
342
- 30 68 102
343
- 43 60 102
344
- 55 49 102
345
- 64 37 102
346
- 70 23 102
347
- 74 7 102
348
- 74 -8 102
349
- 70 -24 102
350
- 64 -38 102
351
- 55 -50 102
352
- 43 -61 102
353
- 30 -69 102
354
- 15 -74 102
355
- 0 -75 102
356
- -16 -74 102
357
- -31 -69 102
358
- -44 -61 102
359
- -56 -50 102
360
- -65 -38 102
361
- -71 -24 102
362
- -75 -8 102
363
- -75 7 102
364
- -71 23 102
365
- -65 37 102
366
- -56 49 102
367
- -44 60 102
368
- -31 68 102
369
- -16 73 102
370
- -1 74 102
371
- 10 50 116
372
- 21 47 116
373
- 30 41 116
374
- 38 34 116
375
- 44 25 116
376
- 49 15 116
377
- 51 5 116
378
- 51 -6 116
379
- 49 -16 116
380
- 44 -26 116
381
- 38 -35 116
382
- 30 -42 116
383
- 21 -48 116
384
- 10 -51 116
385
- 0 -52 116
386
- -11 -51 116
387
- -22 -48 116
388
- -31 -42 116
389
- -39 -35 116
390
- -45 -26 116
391
- -50 -16 116
392
- -52 -6 116
393
- -52 5 116
394
- -50 15 116
395
- -45 25 116
396
- -39 34 116
397
- -31 41 116
398
- -22 47 116
399
- -11 50 116
400
- -1 51 116
401
- 5 25 124
402
- 10 24 124
403
- 15 21 124
404
- 19 17 124
405
- 22 13 124
406
- 25 8 124
407
- 26 2 124
408
- 26 -3 124
409
- 25 -9 124
410
- 22 -14 124
411
- 19 -18 124
412
- 15 -22 124
413
- 10 -25 124
414
- 5 -26 124
415
- 0 -27 124
416
- -6 -26 124
417
- -11 -25 124
418
- -16 -22 124
419
- -20 -18 124
420
- -23 -14 124
421
- -26 -9 124
422
- -27 -3 124
423
- -27 2 124
424
- -26 8 124
425
- -23 13 124
426
- -20 17 124
427
- -16 21 124
428
- -11 24 124
429
- -6 25 124
430
- -1 26 124
431
- 0 0 127
432
- 3 0 1 2
433
- 3 0 2 3
434
- 3 0 3 4
435
- 3 0 4 5
436
- 3 0 5 6
437
- 3 0 6 7
438
- 3 0 7 8
439
- 3 0 8 9
440
- 3 0 9 10
441
- 3 0 10 11
442
- 3 0 11 12
443
- 3 0 12 13
444
- 3 0 13 14
445
- 3 0 14 15
446
- 3 0 15 16
447
- 3 0 16 17
448
- 3 0 17 18
449
- 3 0 18 19
450
- 3 0 19 20
451
- 3 0 20 21
452
- 3 0 21 22
453
- 3 0 22 23
454
- 3 0 23 24
455
- 3 0 24 25
456
- 3 0 25 26
457
- 3 0 26 27
458
- 3 0 27 28
459
- 3 0 28 29
460
- 3 0 29 30
461
- 3 0 30 1
462
- 3 1 32 2
463
- 3 32 1 31
464
- 3 2 33 3
465
- 3 33 2 32
466
- 3 3 34 4
467
- 3 34 3 33
468
- 3 4 35 5
469
- 3 35 4 34
470
- 3 5 36 6
471
- 3 36 5 35
472
- 3 6 37 7
473
- 3 37 6 36
474
- 3 7 38 8
475
- 3 38 7 37
476
- 3 8 39 9
477
- 3 39 8 38
478
- 3 9 40 10
479
- 3 40 9 39
480
- 3 10 41 11
481
- 3 41 10 40
482
- 3 11 42 12
483
- 3 42 11 41
484
- 3 12 43 13
485
- 3 43 12 42
486
- 3 13 44 14
487
- 3 44 13 43
488
- 3 14 45 15
489
- 3 45 14 44
490
- 3 15 46 16
491
- 3 46 15 45
492
- 3 16 47 17
493
- 3 47 16 46
494
- 3 17 48 18
495
- 3 48 17 47
496
- 3 18 49 19
497
- 3 49 18 48
498
- 3 19 50 20
499
- 3 50 19 49
500
- 3 20 51 21
501
- 3 51 20 50
502
- 3 21 52 22
503
- 3 52 21 51
504
- 3 22 53 23
505
- 3 53 22 52
506
- 3 23 54 24
507
- 3 54 23 53
508
- 3 24 55 25
509
- 3 55 24 54
510
- 3 25 56 26
511
- 3 56 25 55
512
- 3 26 57 27
513
- 3 57 26 56
514
- 3 27 58 28
515
- 3 58 27 57
516
- 3 28 59 29
517
- 3 59 28 58
518
- 3 29 60 30
519
- 3 60 29 59
520
- 3 30 31 1
521
- 3 31 30 60
522
- 3 31 62 32
523
- 3 62 31 61
524
- 3 32 63 33
525
- 3 63 32 62
526
- 3 33 64 34
527
- 3 64 33 63
528
- 3 34 65 35
529
- 3 65 34 64
530
- 3 35 66 36
531
- 3 66 35 65
532
- 3 36 67 37
533
- 3 67 36 66
534
- 3 37 68 38
535
- 3 68 37 67
536
- 3 38 69 39
537
- 3 69 38 68
538
- 3 39 70 40
539
- 3 70 39 69
540
- 3 40 71 41
541
- 3 71 40 70
542
- 3 41 72 42
543
- 3 72 41 71
544
- 3 42 73 43
545
- 3 73 42 72
546
- 3 43 74 44
547
- 3 74 43 73
548
- 3 44 75 45
549
- 3 75 44 74
550
- 3 45 76 46
551
- 3 76 45 75
552
- 3 46 77 47
553
- 3 77 46 76
554
- 3 47 78 48
555
- 3 78 47 77
556
- 3 48 79 49
557
- 3 79 48 78
558
- 3 49 80 50
559
- 3 80 49 79
560
- 3 50 81 51
561
- 3 81 50 80
562
- 3 51 82 52
563
- 3 82 51 81
564
- 3 52 83 53
565
- 3 83 52 82
566
- 3 53 84 54
567
- 3 84 53 83
568
- 3 54 85 55
569
- 3 85 54 84
570
- 3 55 86 56
571
- 3 86 55 85
572
- 3 56 87 57
573
- 3 87 56 86
574
- 3 57 88 58
575
- 3 88 57 87
576
- 3 58 89 59
577
- 3 89 58 88
578
- 3 59 90 60
579
- 3 90 59 89
580
- 3 60 61 31
581
- 3 61 60 90
582
- 3 61 92 62
583
- 3 92 61 91
584
- 3 62 93 63
585
- 3 93 62 92
586
- 3 63 94 64
587
- 3 94 63 93
588
- 3 64 95 65
589
- 3 95 64 94
590
- 3 65 96 66
591
- 3 96 65 95
592
- 3 66 97 67
593
- 3 97 66 96
594
- 3 67 98 68
595
- 3 98 67 97
596
- 3 68 99 69
597
- 3 99 68 98
598
- 3 69 100 70
599
- 3 100 69 99
600
- 3 70 101 71
601
- 3 101 70 100
602
- 3 71 102 72
603
- 3 102 71 101
604
- 3 72 103 73
605
- 3 103 72 102
606
- 3 73 104 74
607
- 3 104 73 103
608
- 3 74 105 75
609
- 3 105 74 104
610
- 3 75 106 76
611
- 3 106 75 105
612
- 3 76 107 77
613
- 3 107 76 106
614
- 3 77 108 78
615
- 3 108 77 107
616
- 3 78 109 79
617
- 3 109 78 108
618
- 3 79 110 80
619
- 3 110 79 109
620
- 3 80 111 81
621
- 3 111 80 110
622
- 3 81 112 82
623
- 3 112 81 111
624
- 3 82 113 83
625
- 3 113 82 112
626
- 3 83 114 84
627
- 3 114 83 113
628
- 3 84 115 85
629
- 3 115 84 114
630
- 3 85 116 86
631
- 3 116 85 115
632
- 3 86 117 87
633
- 3 117 86 116
634
- 3 87 118 88
635
- 3 118 87 117
636
- 3 88 119 89
637
- 3 119 88 118
638
- 3 89 120 90
639
- 3 120 89 119
640
- 3 90 91 61
641
- 3 91 90 120
642
- 3 91 122 92
643
- 3 122 91 121
644
- 3 92 123 93
645
- 3 123 92 122
646
- 3 93 124 94
647
- 3 124 93 123
648
- 3 94 125 95
649
- 3 125 94 124
650
- 3 95 126 96
651
- 3 126 95 125
652
- 3 96 127 97
653
- 3 127 96 126
654
- 3 97 128 98
655
- 3 128 97 127
656
- 3 98 129 99
657
- 3 129 98 128
658
- 3 99 130 100
659
- 3 130 99 129
660
- 3 100 131 101
661
- 3 131 100 130
662
- 3 101 132 102
663
- 3 132 101 131
664
- 3 102 133 103
665
- 3 133 102 132
666
- 3 103 134 104
667
- 3 134 103 133
668
- 3 104 135 105
669
- 3 135 104 134
670
- 3 105 136 106
671
- 3 136 105 135
672
- 3 106 137 107
673
- 3 137 106 136
674
- 3 107 138 108
675
- 3 138 107 137
676
- 3 108 139 109
677
- 3 139 108 138
678
- 3 109 140 110
679
- 3 140 109 139
680
- 3 110 141 111
681
- 3 141 110 140
682
- 3 111 142 112
683
- 3 142 111 141
684
- 3 112 143 113
685
- 3 143 112 142
686
- 3 113 144 114
687
- 3 144 113 143
688
- 3 114 145 115
689
- 3 145 114 144
690
- 3 115 146 116
691
- 3 146 115 145
692
- 3 116 147 117
693
- 3 147 116 146
694
- 3 117 148 118
695
- 3 148 117 147
696
- 3 118 149 119
697
- 3 149 118 148
698
- 3 119 150 120
699
- 3 150 119 149
700
- 3 120 121 91
701
- 3 121 120 150
702
- 3 121 152 122
703
- 3 152 121 151
704
- 3 122 153 123
705
- 3 153 122 152
706
- 3 123 154 124
707
- 3 154 123 153
708
- 3 124 155 125
709
- 3 155 124 154
710
- 3 125 156 126
711
- 3 156 125 155
712
- 3 126 157 127
713
- 3 157 126 156
714
- 3 127 158 128
715
- 3 158 127 157
716
- 3 128 159 129
717
- 3 159 128 158
718
- 3 129 160 130
719
- 3 160 129 159
720
- 3 130 161 131
721
- 3 161 130 160
722
- 3 131 162 132
723
- 3 162 131 161
724
- 3 132 163 133
725
- 3 163 132 162
726
- 3 133 164 134
727
- 3 164 133 163
728
- 3 134 165 135
729
- 3 165 134 164
730
- 3 135 166 136
731
- 3 166 135 165
732
- 3 136 167 137
733
- 3 167 136 166
734
- 3 137 168 138
735
- 3 168 137 167
736
- 3 138 169 139
737
- 3 169 138 168
738
- 3 139 170 140
739
- 3 170 139 169
740
- 3 140 171 141
741
- 3 171 140 170
742
- 3 141 172 142
743
- 3 172 141 171
744
- 3 142 173 143
745
- 3 173 142 172
746
- 3 143 174 144
747
- 3 174 143 173
748
- 3 144 175 145
749
- 3 175 144 174
750
- 3 145 176 146
751
- 3 176 145 175
752
- 3 146 177 147
753
- 3 177 146 176
754
- 3 147 178 148
755
- 3 178 147 177
756
- 3 148 179 149
757
- 3 179 148 178
758
- 3 149 180 150
759
- 3 180 149 179
760
- 3 150 151 121
761
- 3 151 150 180
762
- 3 151 182 152
763
- 3 182 151 181
764
- 3 152 183 153
765
- 3 183 152 182
766
- 3 153 184 154
767
- 3 184 153 183
768
- 3 154 185 155
769
- 3 185 154 184
770
- 3 155 186 156
771
- 3 186 155 185
772
- 3 156 187 157
773
- 3 187 156 186
774
- 3 157 188 158
775
- 3 188 157 187
776
- 3 158 189 159
777
- 3 189 158 188
778
- 3 159 190 160
779
- 3 190 159 189
780
- 3 160 191 161
781
- 3 191 160 190
782
- 3 161 192 162
783
- 3 192 161 191
784
- 3 162 193 163
785
- 3 193 162 192
786
- 3 163 194 164
787
- 3 194 163 193
788
- 3 164 195 165
789
- 3 195 164 194
790
- 3 165 196 166
791
- 3 196 165 195
792
- 3 166 197 167
793
- 3 197 166 196
794
- 3 167 198 168
795
- 3 198 167 197
796
- 3 168 199 169
797
- 3 199 168 198
798
- 3 169 200 170
799
- 3 200 169 199
800
- 3 170 201 171
801
- 3 201 170 200
802
- 3 171 202 172
803
- 3 202 171 201
804
- 3 172 203 173
805
- 3 203 172 202
806
- 3 173 204 174
807
- 3 204 173 203
808
- 3 174 205 175
809
- 3 205 174 204
810
- 3 175 206 176
811
- 3 206 175 205
812
- 3 176 207 177
813
- 3 207 176 206
814
- 3 177 208 178
815
- 3 208 177 207
816
- 3 178 209 179
817
- 3 209 178 208
818
- 3 179 210 180
819
- 3 210 179 209
820
- 3 180 181 151
821
- 3 181 180 210
822
- 3 181 212 182
823
- 3 212 181 211
824
- 3 182 213 183
825
- 3 213 182 212
826
- 3 183 214 184
827
- 3 214 183 213
828
- 3 184 215 185
829
- 3 215 184 214
830
- 3 185 216 186
831
- 3 216 185 215
832
- 3 186 217 187
833
- 3 217 186 216
834
- 3 187 218 188
835
- 3 218 187 217
836
- 3 188 219 189
837
- 3 219 188 218
838
- 3 189 220 190
839
- 3 220 189 219
840
- 3 190 221 191
841
- 3 221 190 220
842
- 3 191 222 192
843
- 3 222 191 221
844
- 3 192 223 193
845
- 3 223 192 222
846
- 3 193 224 194
847
- 3 224 193 223
848
- 3 194 225 195
849
- 3 225 194 224
850
- 3 195 226 196
851
- 3 226 195 225
852
- 3 196 227 197
853
- 3 227 196 226
854
- 3 197 228 198
855
- 3 228 197 227
856
- 3 198 229 199
857
- 3 229 198 228
858
- 3 199 230 200
859
- 3 230 199 229
860
- 3 200 231 201
861
- 3 231 200 230
862
- 3 201 232 202
863
- 3 232 201 231
864
- 3 202 233 203
865
- 3 233 202 232
866
- 3 203 234 204
867
- 3 234 203 233
868
- 3 204 235 205
869
- 3 235 204 234
870
- 3 205 236 206
871
- 3 236 205 235
872
- 3 206 237 207
873
- 3 237 206 236
874
- 3 207 238 208
875
- 3 238 207 237
876
- 3 208 239 209
877
- 3 239 208 238
878
- 3 209 240 210
879
- 3 240 209 239
880
- 3 210 211 181
881
- 3 211 210 240
882
- 3 211 242 212
883
- 3 242 211 241
884
- 3 212 243 213
885
- 3 243 212 242
886
- 3 213 244 214
887
- 3 244 213 243
888
- 3 214 245 215
889
- 3 245 214 244
890
- 3 215 246 216
891
- 3 246 215 245
892
- 3 216 247 217
893
- 3 247 216 246
894
- 3 217 248 218
895
- 3 248 217 247
896
- 3 218 249 219
897
- 3 249 218 248
898
- 3 219 250 220
899
- 3 250 219 249
900
- 3 220 251 221
901
- 3 251 220 250
902
- 3 221 252 222
903
- 3 252 221 251
904
- 3 222 253 223
905
- 3 253 222 252
906
- 3 223 254 224
907
- 3 254 223 253
908
- 3 224 255 225
909
- 3 255 224 254
910
- 3 225 256 226
911
- 3 256 225 255
912
- 3 226 257 227
913
- 3 257 226 256
914
- 3 227 258 228
915
- 3 258 227 257
916
- 3 228 259 229
917
- 3 259 228 258
918
- 3 229 260 230
919
- 3 260 229 259
920
- 3 230 261 231
921
- 3 261 230 260
922
- 3 231 262 232
923
- 3 262 231 261
924
- 3 232 263 233
925
- 3 263 232 262
926
- 3 233 264 234
927
- 3 264 233 263
928
- 3 234 265 235
929
- 3 265 234 264
930
- 3 235 266 236
931
- 3 266 235 265
932
- 3 236 267 237
933
- 3 267 236 266
934
- 3 237 268 238
935
- 3 268 237 267
936
- 3 238 269 239
937
- 3 269 238 268
938
- 3 239 270 240
939
- 3 270 239 269
940
- 3 240 241 211
941
- 3 241 240 270
942
- 3 241 272 242
943
- 3 272 241 271
944
- 3 242 273 243
945
- 3 273 242 272
946
- 3 243 274 244
947
- 3 274 243 273
948
- 3 244 275 245
949
- 3 275 244 274
950
- 3 245 276 246
951
- 3 276 245 275
952
- 3 246 277 247
953
- 3 277 246 276
954
- 3 247 278 248
955
- 3 278 247 277
956
- 3 248 279 249
957
- 3 279 248 278
958
- 3 249 280 250
959
- 3 280 249 279
960
- 3 250 281 251
961
- 3 281 250 280
962
- 3 251 282 252
963
- 3 282 251 281
964
- 3 252 283 253
965
- 3 283 252 282
966
- 3 253 284 254
967
- 3 284 253 283
968
- 3 254 285 255
969
- 3 285 254 284
970
- 3 255 286 256
971
- 3 286 255 285
972
- 3 256 287 257
973
- 3 287 256 286
974
- 3 257 288 258
975
- 3 288 257 287
976
- 3 258 289 259
977
- 3 289 258 288
978
- 3 259 290 260
979
- 3 290 259 289
980
- 3 260 291 261
981
- 3 291 260 290
982
- 3 261 292 262
983
- 3 292 261 291
984
- 3 262 293 263
985
- 3 293 262 292
986
- 3 263 294 264
987
- 3 294 263 293
988
- 3 264 295 265
989
- 3 295 264 294
990
- 3 265 296 266
991
- 3 296 265 295
992
- 3 266 297 267
993
- 3 297 266 296
994
- 3 267 298 268
995
- 3 298 267 297
996
- 3 268 299 269
997
- 3 299 268 298
998
- 3 269 300 270
999
- 3 300 269 299
1000
- 3 270 271 241
1001
- 3 271 270 300
1002
- 3 271 302 272
1003
- 3 302 271 301
1004
- 3 272 303 273
1005
- 3 303 272 302
1006
- 3 273 304 274
1007
- 3 304 273 303
1008
- 3 274 305 275
1009
- 3 305 274 304
1010
- 3 275 306 276
1011
- 3 306 275 305
1012
- 3 276 307 277
1013
- 3 307 276 306
1014
- 3 277 308 278
1015
- 3 308 277 307
1016
- 3 278 309 279
1017
- 3 309 278 308
1018
- 3 279 310 280
1019
- 3 310 279 309
1020
- 3 280 311 281
1021
- 3 311 280 310
1022
- 3 281 312 282
1023
- 3 312 281 311
1024
- 3 282 313 283
1025
- 3 313 282 312
1026
- 3 283 314 284
1027
- 3 314 283 313
1028
- 3 284 315 285
1029
- 3 315 284 314
1030
- 3 285 316 286
1031
- 3 316 285 315
1032
- 3 286 317 287
1033
- 3 317 286 316
1034
- 3 287 318 288
1035
- 3 318 287 317
1036
- 3 288 319 289
1037
- 3 319 288 318
1038
- 3 289 320 290
1039
- 3 320 289 319
1040
- 3 290 321 291
1041
- 3 321 290 320
1042
- 3 291 322 292
1043
- 3 322 291 321
1044
- 3 292 323 293
1045
- 3 323 292 322
1046
- 3 293 324 294
1047
- 3 324 293 323
1048
- 3 294 325 295
1049
- 3 325 294 324
1050
- 3 295 326 296
1051
- 3 326 295 325
1052
- 3 296 327 297
1053
- 3 327 296 326
1054
- 3 297 328 298
1055
- 3 328 297 327
1056
- 3 298 329 299
1057
- 3 329 298 328
1058
- 3 299 330 300
1059
- 3 330 299 329
1060
- 3 300 301 271
1061
- 3 301 300 330
1062
- 3 301 332 302
1063
- 3 332 301 331
1064
- 3 302 333 303
1065
- 3 333 302 332
1066
- 3 303 334 304
1067
- 3 334 303 333
1068
- 3 304 335 305
1069
- 3 335 304 334
1070
- 3 305 336 306
1071
- 3 336 305 335
1072
- 3 306 337 307
1073
- 3 337 306 336
1074
- 3 307 338 308
1075
- 3 338 307 337
1076
- 3 308 339 309
1077
- 3 339 308 338
1078
- 3 309 340 310
1079
- 3 340 309 339
1080
- 3 310 341 311
1081
- 3 341 310 340
1082
- 3 311 342 312
1083
- 3 342 311 341
1084
- 3 312 343 313
1085
- 3 343 312 342
1086
- 3 313 344 314
1087
- 3 344 313 343
1088
- 3 314 345 315
1089
- 3 345 314 344
1090
- 3 315 346 316
1091
- 3 346 315 345
1092
- 3 316 347 317
1093
- 3 347 316 346
1094
- 3 317 348 318
1095
- 3 348 317 347
1096
- 3 318 349 319
1097
- 3 349 318 348
1098
- 3 319 350 320
1099
- 3 350 319 349
1100
- 3 320 351 321
1101
- 3 351 320 350
1102
- 3 321 352 322
1103
- 3 352 321 351
1104
- 3 322 353 323
1105
- 3 353 322 352
1106
- 3 323 354 324
1107
- 3 354 323 353
1108
- 3 324 355 325
1109
- 3 355 324 354
1110
- 3 325 356 326
1111
- 3 356 325 355
1112
- 3 326 357 327
1113
- 3 357 326 356
1114
- 3 327 358 328
1115
- 3 358 327 357
1116
- 3 328 359 329
1117
- 3 359 328 358
1118
- 3 329 360 330
1119
- 3 360 329 359
1120
- 3 330 331 301
1121
- 3 331 330 360
1122
- 3 331 362 332
1123
- 3 362 331 361
1124
- 3 332 363 333
1125
- 3 363 332 362
1126
- 3 333 364 334
1127
- 3 364 333 363
1128
- 3 334 365 335
1129
- 3 365 334 364
1130
- 3 335 366 336
1131
- 3 366 335 365
1132
- 3 336 367 337
1133
- 3 367 336 366
1134
- 3 337 368 338
1135
- 3 368 337 367
1136
- 3 338 369 339
1137
- 3 369 338 368
1138
- 3 339 370 340
1139
- 3 370 339 369
1140
- 3 340 371 341
1141
- 3 371 340 370
1142
- 3 341 372 342
1143
- 3 372 341 371
1144
- 3 342 373 343
1145
- 3 373 342 372
1146
- 3 343 374 344
1147
- 3 374 343 373
1148
- 3 344 375 345
1149
- 3 375 344 374
1150
- 3 345 376 346
1151
- 3 376 345 375
1152
- 3 346 377 347
1153
- 3 377 346 376
1154
- 3 347 378 348
1155
- 3 378 347 377
1156
- 3 348 379 349
1157
- 3 379 348 378
1158
- 3 349 380 350
1159
- 3 380 349 379
1160
- 3 350 381 351
1161
- 3 381 350 380
1162
- 3 351 382 352
1163
- 3 382 351 381
1164
- 3 352 383 353
1165
- 3 383 352 382
1166
- 3 353 384 354
1167
- 3 384 353 383
1168
- 3 354 385 355
1169
- 3 385 354 384
1170
- 3 355 386 356
1171
- 3 386 355 385
1172
- 3 356 387 357
1173
- 3 387 356 386
1174
- 3 357 388 358
1175
- 3 388 357 387
1176
- 3 358 389 359
1177
- 3 389 358 388
1178
- 3 359 390 360
1179
- 3 390 359 389
1180
- 3 360 361 331
1181
- 3 361 360 390
1182
- 3 361 392 362
1183
- 3 392 361 391
1184
- 3 362 393 363
1185
- 3 393 362 392
1186
- 3 363 394 364
1187
- 3 394 363 393
1188
- 3 364 395 365
1189
- 3 395 364 394
1190
- 3 365 396 366
1191
- 3 396 365 395
1192
- 3 366 397 367
1193
- 3 397 366 396
1194
- 3 367 398 368
1195
- 3 398 367 397
1196
- 3 368 399 369
1197
- 3 399 368 398
1198
- 3 369 400 370
1199
- 3 400 369 399
1200
- 3 370 401 371
1201
- 3 401 370 400
1202
- 3 371 402 372
1203
- 3 402 371 401
1204
- 3 372 403 373
1205
- 3 403 372 402
1206
- 3 373 404 374
1207
- 3 404 373 403
1208
- 3 374 405 375
1209
- 3 405 374 404
1210
- 3 375 406 376
1211
- 3 406 375 405
1212
- 3 376 407 377
1213
- 3 407 376 406
1214
- 3 377 408 378
1215
- 3 408 377 407
1216
- 3 378 409 379
1217
- 3 409 378 408
1218
- 3 379 410 380
1219
- 3 410 379 409
1220
- 3 380 411 381
1221
- 3 411 380 410
1222
- 3 381 412 382
1223
- 3 412 381 411
1224
- 3 382 413 383
1225
- 3 413 382 412
1226
- 3 383 414 384
1227
- 3 414 383 413
1228
- 3 384 415 385
1229
- 3 415 384 414
1230
- 3 385 416 386
1231
- 3 416 385 415
1232
- 3 386 417 387
1233
- 3 417 386 416
1234
- 3 387 418 388
1235
- 3 418 387 417
1236
- 3 388 419 389
1237
- 3 419 388 418
1238
- 3 389 420 390
1239
- 3 420 389 419
1240
- 3 390 391 361
1241
- 3 391 390 420
1242
- 3 391 421 392
1243
- 3 392 421 393
1244
- 3 393 421 394
1245
- 3 394 421 395
1246
- 3 395 421 396
1247
- 3 396 421 397
1248
- 3 397 421 398
1249
- 3 398 421 399
1250
- 3 399 421 400
1251
- 3 400 421 401
1252
- 3 401 421 402
1253
- 3 402 421 403
1254
- 3 403 421 404
1255
- 3 404 421 405
1256
- 3 405 421 406
1257
- 3 406 421 407
1258
- 3 407 421 408
1259
- 3 408 421 409
1260
- 3 409 421 410
1261
- 3 410 421 411
1262
- 3 411 421 412
1263
- 3 412 421 413
1264
- 3 413 421 414
1265
- 3 414 421 415
1266
- 3 415 421 416
1267
- 3 416 421 417
1268
- 3 417 421 418
1269
- 3 418 421 419
1270
- 3 419 421 420
1271
- 3 420 421 391
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/data/unittest/test_box.obj DELETED
@@ -1,50 +0,0 @@
1
- ####
2
- #
3
- # OBJ File Generated by Meshlab
4
- #
5
- ####
6
- # Object test_box.obj
7
- #
8
- # Vertices: 8
9
- # Faces: 12
10
- #
11
- ####
12
- vn 0.577350 0.577350 0.577350
13
- #landmark pospospos
14
- v 0.500000 0.500000 0.500000
15
- vn -0.333333 0.666667 0.666667
16
- v -0.500000 0.500000 0.500000
17
- vn 0.666667 -0.333333 0.666667
18
- v 0.500000 -0.500000 0.500000
19
- vn -0.666667 -0.666667 0.333333
20
- v -0.500000 -0.500000 0.500000
21
- vn 0.666667 0.666667 -0.333333
22
- v 0.500000 0.500000 -0.500000
23
- vn -0.666667 0.333333 -0.666667
24
- v -0.500000 0.500000 -0.500000
25
- vn 0.333333 -0.666667 -0.666667
26
- v 0.500000 -0.500000 -0.500000
27
- vn -0.577350 -0.577350 -0.577350
28
- #landmark negnegneg
29
- v -0.500000 -0.500000 -0.500000
30
- # 8 vertices, 0 vertices normals
31
-
32
- g a
33
- f 1//1 2//2 3//3
34
- f 4//4 3//3 2//2
35
- f 1//1 3//3 5//5
36
- f 7//7 5//5 3//3
37
- f 1//1 5//5 2//2
38
- f 6//6 2//2 5//5
39
- g b
40
- f 8//8 6//6 7//7
41
- g c
42
- f 5//5 7//7 6//6
43
- f 8//8 7//7 4//4
44
- f 3//3 4//4 7//7
45
- g b
46
- f 8//8 4//4 6//6
47
- f 2//2 6//6 4//4
48
- # 12 faces, 0 coords texture
49
-
50
- # End of File
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/data/unittest/test_box.ply DELETED
@@ -1,29 +0,0 @@
1
- ply
2
- format ascii 1.0
3
- element vertex 8
4
- property float x
5
- property float y
6
- property float z
7
- element face 12
8
- property list uchar int vertex_indices
9
- end_header
10
- 0.5 0.5 0.5
11
- -0.5 0.5 0.5
12
- 0.5 -0.5 0.5
13
- -0.5 -0.5 0.5
14
- 0.5 0.5 -0.5
15
- -0.5 0.5 -0.5
16
- 0.5 -0.5 -0.5
17
- -0.5 -0.5 -0.5
18
- 3 0 1 2
19
- 3 3 2 1
20
- 3 0 2 4
21
- 3 6 4 2
22
- 3 0 4 1
23
- 3 5 1 4
24
- 3 7 5 6
25
- 3 4 6 5
26
- 3 7 6 3
27
- 3 2 3 6
28
- 3 7 3 5
29
- 3 1 5 3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/data/unittest/test_box.pp DELETED
@@ -1,11 +0,0 @@
1
- <!DOCTYPE PickedPoints>
2
- <PickedPoints>
3
- <DocumentData>
4
- <DateTime time="23:00:01" date="2012-04-10"/>
5
- <User name="javier"/>
6
- <DataFileName name="test_box.ply"/>
7
- <templateName name=".pickPointsTemplate.pptpl"/>
8
- </DocumentData>
9
- <point x="0.5" y="0.5" z="0.5" active="1" name="pospospos"/>
10
- <point x="-0.5" y="-0.5" z="-0.5" active="1" name="negnegneg"/>
11
- </PickedPoints>
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/data/unittest/test_box_le.ply DELETED
Binary file (422 Bytes)
 
mesh-fix-MSVC_compilation/data/unittest/test_doublebox.obj DELETED
@@ -1,64 +0,0 @@
1
- ####
2
- #
3
- # OBJ File
4
- #
5
- ####
6
- # Object test_doublebox.obj
7
- #
8
- # Vertices: 12
9
- # Faces: 20
10
- #
11
- ####
12
- vn 0.577350 0.577350 0.577350
13
- v 0.500000 0.500000 0.500000
14
- vn -0.333333 0.666667 0.666667
15
- v -0.500000 0.500000 0.500000
16
- vn 0.666667 -0.333333 0.666667
17
- v 0.500000 -0.500000 0.500000
18
- vn -0.666667 -0.666667 0.333333
19
- v -0.500000 -0.500000 0.500000
20
- vn 0.666667 0.666667 -0.333333
21
- v 0.500000 0.500000 -0.500000
22
- vn -0.666667 0.333333 -0.666667
23
- v -0.500000 0.500000 -0.500000
24
- vn 0.333333 -0.666667 -0.666667
25
- v 0.500000 -0.500000 -0.500000
26
- vn -0.577350 -0.577350 -0.577350
27
- v -0.500000 -0.500000 -0.500000
28
-
29
- vn 0.577350 0.577350 0.577350
30
- v 0.500000 0.500000 1.500000
31
- vn -0.333333 0.666667 0.666667
32
- v -0.500000 0.500000 1.500000
33
- vn 0.666667 -0.333333 0.666667
34
- v 0.500000 -0.500000 1.500000
35
- vn -0.666667 -0.666667 0.333333
36
- v -0.500000 -0.500000 1.500000
37
- # 12 vertices, 0 vertices normals
38
-
39
- g box1
40
- f 1//1 3//3 5//5
41
- f 7//7 5//5 3//3
42
- f 1//1 5//5 2//2
43
- f 6//6 2//2 5//5
44
- f 8//8 6//6 7//7
45
- f 5//5 7//7 6//6
46
- f 8//8 7//7 4//4
47
- f 3//3 4//4 7//7
48
- f 8//8 4//4 6//6
49
- f 2//2 6//6 4//4
50
- g box2
51
- f 9//9 10//10 11//11
52
- f 12//12 11//11 10//10
53
- f 9//9 11//11 1//1
54
- f 3//3 1//1 11//11
55
- f 9//9 1//1 10//10
56
- f 2//2 10//10 1//1
57
- f 4//4 3//3 12//12
58
- f 11//11 12//12 3//3
59
- f 4//4 12//12 2//2
60
- f 10//10 2//2 12//12
61
-
62
- # 20 faces, 0 coords texture
63
-
64
- # End of File
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/doc/Makefile DELETED
@@ -1,177 +0,0 @@
1
- # Makefile for Sphinx documentation
2
- #
3
-
4
- # You can set these variables from the command line.
5
- SPHINXOPTS =
6
- SPHINXBUILD = sphinx-build
7
- PAPER =
8
- BUILDDIR = build
9
-
10
- # User-friendly check for sphinx-build
11
- ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12
- $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13
- endif
14
-
15
- # Internal variables.
16
- PAPEROPT_a4 = -D latex_paper_size=a4
17
- PAPEROPT_letter = -D latex_paper_size=letter
18
- ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
19
- # the i18n builder cannot share the environment and doctrees with the others
20
- I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
21
-
22
- .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
23
-
24
- help:
25
- @echo "Please use \`make <target>' where <target> is one of"
26
- @echo " html to make standalone HTML files"
27
- @echo " dirhtml to make HTML files named index.html in directories"
28
- @echo " singlehtml to make a single large HTML file"
29
- @echo " pickle to make pickle files"
30
- @echo " json to make JSON files"
31
- @echo " htmlhelp to make HTML files and a HTML help project"
32
- @echo " qthelp to make HTML files and a qthelp project"
33
- @echo " devhelp to make HTML files and a Devhelp project"
34
- @echo " epub to make an epub"
35
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
36
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
37
- @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
38
- @echo " text to make text files"
39
- @echo " man to make manual pages"
40
- @echo " texinfo to make Texinfo files"
41
- @echo " info to make Texinfo files and run them through makeinfo"
42
- @echo " gettext to make PO message catalogs"
43
- @echo " changes to make an overview of all changed/added/deprecated items"
44
- @echo " xml to make Docutils-native XML files"
45
- @echo " pseudoxml to make pseudoxml-XML files for display purposes"
46
- @echo " linkcheck to check all external links for integrity"
47
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
48
-
49
- clean:
50
- rm -rf $(BUILDDIR)/*
51
-
52
- html:
53
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
54
- @echo
55
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
56
-
57
- dirhtml:
58
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
59
- @echo
60
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
61
-
62
- singlehtml:
63
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
64
- @echo
65
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
66
-
67
- pickle:
68
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
69
- @echo
70
- @echo "Build finished; now you can process the pickle files."
71
-
72
- json:
73
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
74
- @echo
75
- @echo "Build finished; now you can process the JSON files."
76
-
77
- htmlhelp:
78
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
79
- @echo
80
- @echo "Build finished; now you can run HTML Help Workshop with the" \
81
- ".hhp project file in $(BUILDDIR)/htmlhelp."
82
-
83
- qthelp:
84
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
85
- @echo
86
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
87
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
88
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PSBodyMeshPackage.qhcp"
89
- @echo "To view the help file:"
90
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PSBodyMeshPackage.qhc"
91
-
92
- devhelp:
93
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
94
- @echo
95
- @echo "Build finished."
96
- @echo "To view the help file:"
97
- @echo "# mkdir -p $$HOME/.local/share/devhelp/PSBodyMeshPackage"
98
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PSBodyMeshPackage"
99
- @echo "# devhelp"
100
-
101
- epub:
102
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
103
- @echo
104
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
105
-
106
- latex:
107
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
108
- @echo
109
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
110
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
111
- "(use \`make latexpdf' here to do that automatically)."
112
-
113
- latexpdf:
114
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
115
- @echo "Running LaTeX files through pdflatex..."
116
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
117
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
118
-
119
- latexpdfja:
120
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
121
- @echo "Running LaTeX files through platex and dvipdfmx..."
122
- $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
123
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
124
-
125
- text:
126
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
127
- @echo
128
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
129
-
130
- man:
131
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
132
- @echo
133
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
134
-
135
- texinfo:
136
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
137
- @echo
138
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
139
- @echo "Run \`make' in that directory to run these through makeinfo" \
140
- "(use \`make info' here to do that automatically)."
141
-
142
- info:
143
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
144
- @echo "Running Texinfo files through makeinfo..."
145
- make -C $(BUILDDIR)/texinfo info
146
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
147
-
148
- gettext:
149
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
150
- @echo
151
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
152
-
153
- changes:
154
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
155
- @echo
156
- @echo "The overview file is in $(BUILDDIR)/changes."
157
-
158
- linkcheck:
159
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
160
- @echo
161
- @echo "Link check complete; look for any errors in the above output " \
162
- "or in $(BUILDDIR)/linkcheck/output.txt."
163
-
164
- doctest:
165
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
166
- @echo "Testing of doctests in the sources finished, look at the " \
167
- "results in $(BUILDDIR)/doctest/output.txt."
168
-
169
- xml:
170
- $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
171
- @echo
172
- @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
173
-
174
- pseudoxml:
175
- $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
176
- @echo
177
- @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/doc/make.bat DELETED
@@ -1,242 +0,0 @@
1
- @ECHO OFF
2
-
3
- REM Command file for Sphinx documentation
4
-
5
- if "%SPHINXBUILD%" == "" (
6
- set SPHINXBUILD=sphinx-build
7
- )
8
- set BUILDDIR=build
9
- set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
10
- set I18NSPHINXOPTS=%SPHINXOPTS% source
11
- if NOT "%PAPER%" == "" (
12
- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13
- set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14
- )
15
-
16
- if "%1" == "" goto help
17
-
18
- if "%1" == "help" (
19
- :help
20
- echo.Please use `make ^<target^>` where ^<target^> is one of
21
- echo. html to make standalone HTML files
22
- echo. dirhtml to make HTML files named index.html in directories
23
- echo. singlehtml to make a single large HTML file
24
- echo. pickle to make pickle files
25
- echo. json to make JSON files
26
- echo. htmlhelp to make HTML files and a HTML help project
27
- echo. qthelp to make HTML files and a qthelp project
28
- echo. devhelp to make HTML files and a Devhelp project
29
- echo. epub to make an epub
30
- echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31
- echo. text to make text files
32
- echo. man to make manual pages
33
- echo. texinfo to make Texinfo files
34
- echo. gettext to make PO message catalogs
35
- echo. changes to make an overview over all changed/added/deprecated items
36
- echo. xml to make Docutils-native XML files
37
- echo. pseudoxml to make pseudoxml-XML files for display purposes
38
- echo. linkcheck to check all external links for integrity
39
- echo. doctest to run all doctests embedded in the documentation if enabled
40
- goto end
41
- )
42
-
43
- if "%1" == "clean" (
44
- for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
45
- del /q /s %BUILDDIR%\*
46
- goto end
47
- )
48
-
49
-
50
- %SPHINXBUILD% 2> nul
51
- if errorlevel 9009 (
52
- echo.
53
- echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
54
- echo.installed, then set the SPHINXBUILD environment variable to point
55
- echo.to the full path of the 'sphinx-build' executable. Alternatively you
56
- echo.may add the Sphinx directory to PATH.
57
- echo.
58
- echo.If you don't have Sphinx installed, grab it from
59
- echo.http://sphinx-doc.org/
60
- exit /b 1
61
- )
62
-
63
- if "%1" == "html" (
64
- %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
65
- if errorlevel 1 exit /b 1
66
- echo.
67
- echo.Build finished. The HTML pages are in %BUILDDIR%/html.
68
- goto end
69
- )
70
-
71
- if "%1" == "dirhtml" (
72
- %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
73
- if errorlevel 1 exit /b 1
74
- echo.
75
- echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
76
- goto end
77
- )
78
-
79
- if "%1" == "singlehtml" (
80
- %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
81
- if errorlevel 1 exit /b 1
82
- echo.
83
- echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
84
- goto end
85
- )
86
-
87
- if "%1" == "pickle" (
88
- %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
89
- if errorlevel 1 exit /b 1
90
- echo.
91
- echo.Build finished; now you can process the pickle files.
92
- goto end
93
- )
94
-
95
- if "%1" == "json" (
96
- %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
97
- if errorlevel 1 exit /b 1
98
- echo.
99
- echo.Build finished; now you can process the JSON files.
100
- goto end
101
- )
102
-
103
- if "%1" == "htmlhelp" (
104
- %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
105
- if errorlevel 1 exit /b 1
106
- echo.
107
- echo.Build finished; now you can run HTML Help Workshop with the ^
108
- .hhp project file in %BUILDDIR%/htmlhelp.
109
- goto end
110
- )
111
-
112
- if "%1" == "qthelp" (
113
- %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
114
- if errorlevel 1 exit /b 1
115
- echo.
116
- echo.Build finished; now you can run "qcollectiongenerator" with the ^
117
- .qhcp project file in %BUILDDIR%/qthelp, like this:
118
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PSBodyMeshPackage.qhcp
119
- echo.To view the help file:
120
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PSBodyMeshPackage.ghc
121
- goto end
122
- )
123
-
124
- if "%1" == "devhelp" (
125
- %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
126
- if errorlevel 1 exit /b 1
127
- echo.
128
- echo.Build finished.
129
- goto end
130
- )
131
-
132
- if "%1" == "epub" (
133
- %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
134
- if errorlevel 1 exit /b 1
135
- echo.
136
- echo.Build finished. The epub file is in %BUILDDIR%/epub.
137
- goto end
138
- )
139
-
140
- if "%1" == "latex" (
141
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
142
- if errorlevel 1 exit /b 1
143
- echo.
144
- echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
145
- goto end
146
- )
147
-
148
- if "%1" == "latexpdf" (
149
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
150
- cd %BUILDDIR%/latex
151
- make all-pdf
152
- cd %BUILDDIR%/..
153
- echo.
154
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
155
- goto end
156
- )
157
-
158
- if "%1" == "latexpdfja" (
159
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
160
- cd %BUILDDIR%/latex
161
- make all-pdf-ja
162
- cd %BUILDDIR%/..
163
- echo.
164
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
165
- goto end
166
- )
167
-
168
- if "%1" == "text" (
169
- %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
170
- if errorlevel 1 exit /b 1
171
- echo.
172
- echo.Build finished. The text files are in %BUILDDIR%/text.
173
- goto end
174
- )
175
-
176
- if "%1" == "man" (
177
- %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
178
- if errorlevel 1 exit /b 1
179
- echo.
180
- echo.Build finished. The manual pages are in %BUILDDIR%/man.
181
- goto end
182
- )
183
-
184
- if "%1" == "texinfo" (
185
- %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
186
- if errorlevel 1 exit /b 1
187
- echo.
188
- echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
189
- goto end
190
- )
191
-
192
- if "%1" == "gettext" (
193
- %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
194
- if errorlevel 1 exit /b 1
195
- echo.
196
- echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
197
- goto end
198
- )
199
-
200
- if "%1" == "changes" (
201
- %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
202
- if errorlevel 1 exit /b 1
203
- echo.
204
- echo.The overview file is in %BUILDDIR%/changes.
205
- goto end
206
- )
207
-
208
- if "%1" == "linkcheck" (
209
- %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
210
- if errorlevel 1 exit /b 1
211
- echo.
212
- echo.Link check complete; look for any errors in the above output ^
213
- or in %BUILDDIR%/linkcheck/output.txt.
214
- goto end
215
- )
216
-
217
- if "%1" == "doctest" (
218
- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
219
- if errorlevel 1 exit /b 1
220
- echo.
221
- echo.Testing of doctests in the sources finished, look at the ^
222
- results in %BUILDDIR%/doctest/output.txt.
223
- goto end
224
- )
225
-
226
- if "%1" == "xml" (
227
- %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
228
- if errorlevel 1 exit /b 1
229
- echo.
230
- echo.Build finished. The XML files are in %BUILDDIR%/xml.
231
- goto end
232
- )
233
-
234
- if "%1" == "pseudoxml" (
235
- %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
236
- if errorlevel 1 exit /b 1
237
- echo.
238
- echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
239
- goto end
240
- )
241
-
242
- :end
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/doc/source/conf.py DELETED
@@ -1,356 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # PSBody Mesh Package documentation build configuration file, created by
4
- # sphinx-quickstart on Wed Mar 23 07:26:06 2016.
5
- #
6
- # This file is execfile()d with the current directory set to its
7
- # containing dir.
8
- #
9
- # Note that not all possible configuration values are present in this
10
- # autogenerated file.
11
- #
12
- # All configuration values have a default; values that are commented out
13
- # serve to show the default.
14
-
15
- import sys
16
- import os
17
- import sphinx_bootstrap_theme
18
-
19
- root_source_folder = os.path.abspath(
20
- os.path.join(os.path.dirname(__file__),
21
- os.pardir,
22
- os.pardir))
23
- sys.path.insert(0, root_source_folder)
24
-
25
- from mesh.version import __version__
26
-
27
- print(root_source_folder)
28
- print("version {}".format(__version__))
29
-
30
- # If extensions (or modules to document with autodoc) are in another directory,
31
- # add these directories to sys.path here. If the directory is relative to the
32
- # documentation root, use os.path.abspath to make it absolute, like shown here.
33
- # sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)))
34
-
35
- # -- General configuration ------------------------------------------------
36
-
37
- # If your documentation needs a minimal Sphinx version, state it here.
38
- #needs_sphinx = '1.0'
39
-
40
- # Add any Sphinx extension module names here, as strings. They can be
41
- # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
42
- # ones.
43
- extensions = [
44
- 'sphinx.ext.autodoc',
45
- 'sphinx.ext.intersphinx',
46
- 'sphinx.ext.todo',
47
- 'sphinx.ext.coverage',
48
- 'sphinx.ext.mathjax',
49
- 'sphinx.ext.ifconfig',
50
- 'sphinx.ext.viewcode',
51
- 'sphinx.ext.autosummary',
52
- ]
53
-
54
- autoclass_content = 'both'
55
-
56
- # Add any paths that contain templates here, relative to this directory.
57
- templates_path = ['_templates']
58
-
59
- # The suffix of source filenames.
60
- source_suffix = '.rst'
61
-
62
- # The encoding of source files.
63
- #source_encoding = 'utf-8-sig'
64
-
65
- # The master toctree document.
66
- master_doc = 'index'
67
-
68
- # General information about the project.
69
- project = u'PSBody Mesh Package'
70
- copyright = u'2016, Max Planck Institute for Intelligent Systems, PSBody group'
71
-
72
- # The version info for the project you're documenting, acts as replacement for
73
- # |version| and |release|, also used in various other places throughout the
74
- # built documents.
75
-
76
- # The short X.Y version
77
- version = __version__
78
- # The full version, including alpha/beta/rc tags
79
- release = __version__
80
-
81
- # The language for content autogenerated by Sphinx. Refer to documentation
82
- # for a list of supported languages.
83
- #language = None
84
-
85
- # There are two options for replacing |today|: either, you set today to some
86
- # non-false value, then it is used:
87
- #today = ''
88
- # Else, today_fmt is used as the format for a strftime call.
89
- #today_fmt = '%B %d, %Y'
90
-
91
- # List of patterns, relative to source directory, that match files and
92
- # directories to ignore when looking for source files.
93
- exclude_patterns = []
94
-
95
- # The reST default role (used for this markup: `text`) to use for all
96
- # documents.
97
- #default_role = None
98
-
99
- # If true, '()' will be appended to :func: etc. cross-reference text.
100
- #add_function_parentheses = True
101
-
102
- # If true, the current module name will be prepended to all description
103
- # unit titles (such as .. function::).
104
- #add_module_names = True
105
-
106
- # If true, sectionauthor and moduleauthor directives will be shown in the
107
- # output. They are ignored by default.
108
- #show_authors = False
109
-
110
- # The name of the Pygments (syntax highlighting) style to use.
111
- pygments_style = 'sphinx'
112
-
113
- # A list of ignored prefixes for module index sorting.
114
- #modindex_common_prefix = []
115
-
116
- # If true, keep warnings as "system message" paragraphs in the built documents.
117
- #keep_warnings = False
118
-
119
-
120
- # -- Options for HTML output ----------------------------------------------
121
-
122
- # The theme to use for HTML and HTML Help pages. See the documentation for
123
- # a list of builtin themes.
124
- html_theme = 'bootstrap'
125
- html_theme_path = sphinx_bootstrap_theme.get_html_theme_path()
126
-
127
- # Theme options are theme-specific and customize the look and feel of a theme
128
- # further. For a list of options available for each theme, see the
129
- # documentation.
130
- #html_theme_options = {}
131
-
132
- # Add any paths that contain custom themes here, relative to this directory.
133
- #html_theme_path = []
134
-
135
- # The name for this set of Sphinx documents. If None, it defaults to
136
- # "<project> v<release> documentation".
137
- #html_title = None
138
-
139
- # A shorter title for the navigation bar. Default is the same as html_title.
140
- #html_short_title = None
141
-
142
- # The name of an image file (relative to this directory) to place at the top
143
- # of the sidebar.
144
- #html_logo = None
145
-
146
- # The name of an image file (within the static path) to use as favicon of the
147
- # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
148
- # pixels large.
149
- #html_favicon = None
150
-
151
- # Add any paths that contain custom static files (such as style sheets) here,
152
- # relative to this directory. They are copied after the builtin static files,
153
- # so a file named "default.css" will overwrite the builtin "default.css".
154
- html_static_path = ['_static']
155
-
156
- # Add any extra paths that contain custom files (such as robots.txt or
157
- # .htaccess) here, relative to this directory. These files are copied
158
- # directly to the root of the documentation.
159
- #html_extra_path = []
160
-
161
- # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
162
- # using the given strftime format.
163
- #html_last_updated_fmt = '%b %d, %Y'
164
-
165
- # If true, SmartyPants will be used to convert quotes and dashes to
166
- # typographically correct entities.
167
- #html_use_smartypants = True
168
-
169
- # Custom sidebar templates, maps document names to template names.
170
- #html_sidebars = {}
171
-
172
- # Additional templates that should be rendered to pages, maps page names to
173
- # template names.
174
- #html_additional_pages = {}
175
-
176
- # If false, no module index is generated.
177
- #html_domain_indices = True
178
-
179
- # If false, no index is generated.
180
- #html_use_index = True
181
-
182
- # If true, the index is split into individual pages for each letter.
183
- #html_split_index = False
184
-
185
- # If true, links to the reST sources are added to the pages.
186
- #html_show_sourcelink = True
187
-
188
- # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
189
- #html_show_sphinx = True
190
-
191
- # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
192
- #html_show_copyright = True
193
-
194
- # If true, an OpenSearch description file will be output, and all pages will
195
- # contain a <link> tag referring to it. The value of this option must be the
196
- # base URL from which the finished HTML is served.
197
- #html_use_opensearch = ''
198
-
199
- # This is the file name suffix for HTML files (e.g. ".xhtml").
200
- #html_file_suffix = None
201
-
202
- # Output file base name for HTML help builder.
203
- htmlhelp_basename = 'PSBodyMeshPackagedoc'
204
-
205
-
206
- # -- Options for LaTeX output ---------------------------------------------
207
-
208
- latex_elements = {
209
- # The paper size ('letterpaper' or 'a4paper').
210
- #'papersize': 'letterpaper',
211
-
212
- # The font size ('10pt', '11pt' or '12pt').
213
- #'pointsize': '10pt',
214
-
215
- # Additional stuff for the LaTeX preamble.
216
- #'preamble': '',
217
- }
218
-
219
- # Grouping the document tree into LaTeX files. List of tuples
220
- # (source start file, target name, title,
221
- # author, documentclass [howto, manual, or own class]).
222
- latex_documents = [
223
- ('index', 'PSBodyMeshPackage.tex', u'PSBody Mesh Package Documentation',
224
- u'Max Planck Institute for Intelligent Systems, PSBody group', 'manual'),
225
- ]
226
-
227
- # The name of an image file (relative to this directory) to place at the top of
228
- # the title page.
229
- #latex_logo = None
230
-
231
- # For "manual" documents, if this is true, then toplevel headings are parts,
232
- # not chapters.
233
- #latex_use_parts = False
234
-
235
- # If true, show page references after internal links.
236
- #latex_show_pagerefs = False
237
-
238
- # If true, show URL addresses after external links.
239
- #latex_show_urls = False
240
-
241
- # Documents to append as an appendix to all manuals.
242
- #latex_appendices = []
243
-
244
- # If false, no module index is generated.
245
- #latex_domain_indices = True
246
-
247
-
248
- # -- Options for manual page output ---------------------------------------
249
-
250
- # One entry per manual page. List of tuples
251
- # (source start file, name, description, authors, manual section).
252
- man_pages = [
253
- ('index', 'psbodymeshpackage', u'PSBody Mesh Package Documentation',
254
- [u'Max Planck Institute for Intelligent Systems, PSBody group'], 1)
255
- ]
256
-
257
- # If true, show URL addresses after external links.
258
- #man_show_urls = False
259
-
260
-
261
- # -- Options for Texinfo output -------------------------------------------
262
-
263
- # Grouping the document tree into Texinfo files. List of tuples
264
- # (source start file, target name, title, author,
265
- # dir menu entry, description, category)
266
- texinfo_documents = [
267
- ('index', 'PSBodyMeshPackage', u'PSBody Mesh Package Documentation',
268
- u'Max Planck Institute for Intelligent Systems, PSBody group', 'PSBodyMeshPackage', 'One line description of project.',
269
- 'Miscellaneous'),
270
- ]
271
-
272
- # Documents to append as an appendix to all manuals.
273
- #texinfo_appendices = []
274
-
275
- # If false, no module index is generated.
276
- #texinfo_domain_indices = True
277
-
278
- # How to display URL addresses: 'footnote', 'no', or 'inline'.
279
- #texinfo_show_urls = 'footnote'
280
-
281
- # If true, do not generate a @detailmenu in the "Top" node's menu.
282
- #texinfo_no_detailmenu = False
283
-
284
-
285
- # -- Options for Epub output ----------------------------------------------
286
-
287
- # Bibliographic Dublin Core info.
288
- epub_title = u'PSBody Mesh Package'
289
- epub_author = u'Max Planck Institute for Intelligent Systems, PSBody group'
290
- epub_publisher = u'Max Planck Institute for Intelligent Systems, PSBody group'
291
- epub_copyright = u'2016, Max Planck Institute for Intelligent Systems, PSBody group'
292
-
293
- # The basename for the epub file. It defaults to the project name.
294
- #epub_basename = u'PSBody Mesh Package'
295
-
296
- # The HTML theme for the epub output. Since the default themes are not optimized
297
- # for small screen space, using the same theme for HTML and epub output is
298
- # usually not wise. This defaults to 'epub', a theme designed to save visual
299
- # space.
300
- #epub_theme = 'epub'
301
-
302
- # The language of the text. It defaults to the language option
303
- # or en if the language is not set.
304
- #epub_language = ''
305
-
306
- # The scheme of the identifier. Typical schemes are ISBN or URL.
307
- #epub_scheme = ''
308
-
309
- # The unique identifier of the text. This can be a ISBN number
310
- # or the project homepage.
311
- #epub_identifier = ''
312
-
313
- # A unique identification for the text.
314
- #epub_uid = ''
315
-
316
- # A tuple containing the cover image and cover page html template filenames.
317
- #epub_cover = ()
318
-
319
- # A sequence of (type, uri, title) tuples for the guide element of content.opf.
320
- #epub_guide = ()
321
-
322
- # HTML files that should be inserted before the pages created by sphinx.
323
- # The format is a list of tuples containing the path and title.
324
- #epub_pre_files = []
325
-
326
- # HTML files shat should be inserted after the pages created by sphinx.
327
- # The format is a list of tuples containing the path and title.
328
- #epub_post_files = []
329
-
330
- # A list of files that should not be packed into the epub file.
331
- epub_exclude_files = ['search.html']
332
-
333
- # The depth of the table of contents in toc.ncx.
334
- #epub_tocdepth = 3
335
-
336
- # Allow duplicate toc entries.
337
- #epub_tocdup = True
338
-
339
- # Choose between 'default' and 'includehidden'.
340
- #epub_tocscope = 'default'
341
-
342
- # Fix unsupported image types using the PIL.
343
- #epub_fix_images = False
344
-
345
- # Scale large images.
346
- #epub_max_image_width = 0
347
-
348
- # How to display URL addresses: 'footnote', 'no', or 'inline'.
349
- #epub_show_urls = 'inline'
350
-
351
- # If false, no index is generated.
352
- #epub_use_index = True
353
-
354
-
355
- # Example configuration for intersphinx: refer to the Python standard library.
356
- intersphinx_mapping = {'http://docs.python.org/': None}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/doc/source/index.rst DELETED
@@ -1,163 +0,0 @@
1
- .. PSBody Mesh Package documentation master file, created by
2
- sphinx-quickstart on Wed Mar 23 07:26:06 2016.
3
- You can adapt this file completely to your liking, but it should at least
4
- contain the root `toctree` directive.
5
-
6
- Welcome to PSBody Mesh Package's documentation!
7
- ===============================================
8
-
9
- This is the documentation of the Mesh package of the Body Group, Max Planck Institute
10
- for Intelligent Systems, Tübingen, Germany.
11
-
12
- Contents:
13
-
14
- .. toctree::
15
- :maxdepth: 2
16
-
17
- Mesh<pages/mesh>
18
- Mesh Viewer<pages/mesh_viewer>
19
- Geometry<pages/geometry>
20
-
21
-
22
- What is this package about?
23
- ===========================
24
- This package contains core functions for manipulating Meshes and visualizing them.
25
- It requires ``Python 3.5+`` and is supported on Linux and macOS operating systems.
26
-
27
-
28
- Getting started
29
- ===============
30
-
31
- Installation
32
- ------------
33
-
34
-
35
- There are several places where you can download the latest release of the ``psbody-mesh`` package:
36
-
37
- * `Code Doc <https://code.is.localnet/series/3/8/>`_ , the internal documentation center of the MPI-IS
38
- * `GitLab <https://gitlab.tuebingen.mpg.de/ps-body/mesh>`_, the internal repository used for development
39
- * `GitHub <https://github.com/MPI-IS/mesh>`_ for the public release
40
-
41
- ``Code Doc`` contains the wheel and source distributions, and the documentation of the **complete** package.
42
-
43
- ``GitLab`` contains the source code of the **complete** package.
44
-
45
- ``GitHub`` contains the source code of the public, **limited** package.
46
-
47
-
48
- First, create a dedicated Python virtual environment and activate it:
49
-
50
- .. code::
51
-
52
- $ python3 -m venv --copies my_venv
53
- $ source my_venv/bin/activate
54
-
55
- The easiest way to install the ``psbody-mesh`` package is to use the wheel distribution:
56
-
57
- .. code::
58
-
59
- $ pip install psbody_mesh_*.whl
60
-
61
- .. warning::
62
-
63
- Make sure to use to wheel corresponding to your OS and your Python version.
64
-
65
- You can also install the ``psbody-mesh`` package using the source distribution.
66
- For this, you first need to install the `Boost <http://www.boost.org>`_ libraries.
67
- You can compile your own local version or simply do:
68
-
69
- .. code::
70
-
71
- $ sudo apt-get install libboost-dev
72
-
73
- and then install the ``psbody-mesh`` package:
74
-
75
- .. code::
76
-
77
- $ pip install psbody_mesh_*.tar.gz
78
-
79
- As a last option, you can also compile and install the ``psbody-mesh`` package using the Makefile.
80
- If you are using the system-wide ``Boost libraries``:
81
-
82
- .. code::
83
-
84
- $ make all
85
-
86
- or the libraries locally installed:
87
-
88
- .. code::
89
-
90
- $ BOOST_ROOT=/path/to/boost/libraries make all
91
-
92
- Testing
93
- -------
94
-
95
- To run the tests (only available in the **complete** package), simply do:
96
-
97
- .. code::
98
-
99
- $ make tests
100
-
101
- Documentation
102
- -------------
103
-
104
- A detailed documentation can be compiled using the Makefile:
105
-
106
- .. code::
107
-
108
- $ make documentation
109
-
110
- Loading a mesh
111
- --------------
112
-
113
- Loading a :py:class:`Mesh <psbody.mesh.mesh.Mesh>` class from a file is that easy:
114
-
115
- .. code::
116
-
117
- from psbody.mesh import Mesh
118
- my_mesh = Mesh(filename='mesh_filename.ply')
119
-
120
- Rendering a mesh
121
- ----------------
122
-
123
- From a previously loaded mesh ``my_mesh``, it is possible to visualize it inside an interactive window using the
124
- :py:class:`MeshViewers <psbody.mesh.meshviewer.MeshViewers>` class:
125
-
126
- .. code::
127
-
128
- from psbody.mesh import MeshViewers
129
-
130
- # creates a grid of 2x2 mesh viewers
131
- mvs = MeshViewers(shape=[2, 2])
132
-
133
- # sets the first (top-left) mesh to my_mesh
134
- mvs[0][0].set_static_meshes([my_mesh])
135
-
136
- Caching
137
- -------
138
-
139
- Some operations make use of caching for performance reasons. The default folder used for caching is
140
-
141
- .. code::
142
-
143
- ~/.psbody/mesh_package_cache
144
-
145
-
146
- If you need to specify the cache folder, define the environment variable ``PSBODY_MESH_CACHE``
147
- prior to any loading of the Mesh package:
148
-
149
- .. code::
150
-
151
- export PSBODY_MESH_CACHE="some/folder"
152
- python
153
- >> from psbody.mesh import Mesh
154
- # now uses the specified cache
155
-
156
-
157
-
158
- Indices and tables
159
- ==================
160
-
161
- * :ref:`genindex`
162
- * :ref:`modindex`
163
- * :ref:`search`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/doc/source/pages/geometry.rst DELETED
@@ -1,29 +0,0 @@
1
- Geometry
2
- ========
3
-
4
- The geometry subpackage contains some utilities on the geometric entities.
5
-
6
- .. autosummary::
7
-
8
- psbody.mesh.geometry.triangle_area.triangle_area
9
- psbody.mesh.geometry.rodrigues.rodrigues
10
- psbody.mesh.geometry.barycentric_coordinates_of_projection.barycentric_coordinates_of_projection
11
- psbody.mesh.geometry.cross_product.CrossProduct
12
-
13
-
14
- Reference
15
- ---------
16
-
17
- .. automodule:: psbody.mesh.geometry.triangle_area
18
- :members:
19
-
20
- .. automodule:: psbody.mesh.geometry.rodrigues
21
- :members:
22
-
23
- .. automodule:: psbody.mesh.geometry.barycentric_coordinates_of_projection
24
- :members:
25
-
26
- .. automodule:: psbody.mesh.geometry.cross_product
27
- :members:
28
-
29
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/doc/source/pages/mesh.rst DELETED
@@ -1,31 +0,0 @@
1
- Mesh
2
- ====
3
-
4
- The :py:class:`Mesh <psbody.mesh.mesh.Mesh>` class is the core class of the Mesh package.
5
-
6
- Loading and Saving a mesh
7
- -------------------------
8
-
9
- The entry point for loading a mesh is :py:func:`Mesh.load_from_file <psbody.mesh.mesh.Mesh.load_from_file>`.
10
-
11
- Supported file formats:
12
-
13
- * ply
14
- * obj
15
-
16
- Querying meshes
17
- ---------------
18
- Meshes contain functions to query their content efficiently.
19
-
20
- Transforming meshes
21
- -------------------
22
-
23
-
24
- Reference
25
- ---------
26
-
27
- .. automodule:: psbody.mesh.mesh
28
- :members:
29
- :undoc-members:
30
-
31
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/doc/source/pages/mesh_viewer.rst DELETED
@@ -1,11 +0,0 @@
1
- Mesh viewer
2
- ===========
3
-
4
-
5
- Reference
6
- ---------
7
-
8
- .. automodule:: psbody.mesh.meshviewer
9
- :members:
10
- :undoc-members:
11
-
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/CMakeLists.txt DELETED
@@ -1,114 +0,0 @@
1
- # Copyright 2016, Max Planck Society.
2
- # Not licensed
3
- # author Raffi Enficiaud
4
-
5
- cmake_minimum_required (VERSION 2.8.12)
6
- set_property(GLOBAL PROPERTY USE_FOLDERS ON)
7
-
8
- enable_testing()
9
-
10
- project(Mesh)
11
-
12
- add_custom_target(cmake_files SOURCES
13
- cmake/python_helper.cmake
14
- cmake/thirdparty.cmake
15
- src/hijack_python_headers.hpp)
16
-
17
- include(cmake/thirdparty.cmake)
18
- include(cmake/python_helper.cmake)
19
-
20
-
21
- include_directories(${PYTHON_INCLUDE_PATH})
22
-
23
- set(MESHPYTHON_SRC
24
- __init__.py
25
- mesh.py
26
- meshviewer.py
27
- colors.py
28
- search.py
29
- )
30
-
31
- # for convenience
32
- add_custom_target(MeshPython SOURCES ${MESHPYTHON_SRC})
33
-
34
-
35
-
36
-
37
- # aabb_normals
38
- # CGAL_NDEBUG removes calls to logging, warning and error functions that would need
39
- # a link to the CGAL libraries
40
- # CGAL_HAS_NO_THREADS removes the thread safety of the AABB tree with the advantage
41
- # of removing the dependency to boost::thread (and indirectly boost::system compiled library)
42
- # MESH_CGAL_AVOID_COMPILED_VERSION is a define of our own in order to hack a remaining
43
- # log of error without the need to include CGAL generated libraries
44
- # CGAL_NO_AUTOLINK_CGA prevents autolinking on Visual
45
-
46
- set(DEFINES_MESH_EXTENSIONS_WITH_CGAL_WITHOUT_LINK
47
- -DCGAL_NDEBUG=1
48
- -DMESH_CGAL_AVOID_COMPILED_VERSION=1
49
- -DCGAL_HAS_NO_THREADS=1
50
- -DCGAL_NO_AUTOLINK_CGAL=1)
51
-
52
- python_add_library(TARGET aabb_normals SOURCES
53
- src/cgal_error_emulation.hpp
54
- src/AABB_n_tree.h
55
- src/aabb_normals.cpp)
56
- set_property(TARGET aabb_normals PROPERTY FOLDER "GeometryExt/")
57
- target_include_directories(aabb_normals PRIVATE
58
- ${libcgalroot}/include
59
- ${NUMPY_INCLUDE_PATH}
60
- ${Boost_INCLUDE_DIRS})
61
- target_compile_definitions(aabb_normals PRIVATE
62
- ${DEFINES_MESH_EXTENSIONS_WITH_CGAL_WITHOUT_LINK})
63
-
64
-
65
- # spatial search
66
- python_add_library(TARGET spatialsearch SOURCES
67
- src/cgal_error_emulation.hpp
68
- src/nearest_point_triangle_3.h
69
- src/nearest_triangle_normals.hpp
70
- src/nearest_triangle.hpp
71
-
72
- src/spatialsearchmodule.cpp
73
- )
74
- set_property(TARGET spatialsearch PROPERTY FOLDER "GeometryExt/")
75
- target_include_directories(spatialsearch PRIVATE
76
- ${libcgalroot}/include
77
- ${NUMPY_INCLUDE_PATH}
78
- ${Boost_INCLUDE_DIRS})
79
- target_compile_definitions(spatialsearch PRIVATE
80
- ${DEFINES_MESH_EXTENSIONS_WITH_CGAL_WITHOUT_LINK})
81
-
82
-
83
-
84
- # visibility
85
- python_add_library(TARGET visibility SOURCES
86
- src/py_visibility.cpp
87
- src/visibility.cpp
88
- )
89
- target_include_directories(visibility PRIVATE
90
- ${libcgalroot}/include
91
- ${NUMPY_INCLUDE_PATH}
92
- ${Boost_INCLUDE_DIRS})
93
- set_property(TARGET visibility PROPERTY FOLDER "GeometryExt/")
94
- target_compile_definitions(visibility PRIVATE
95
- ${DEFINES_MESH_EXTENSIONS_WITH_CGAL_WITHOUT_LINK})
96
-
97
-
98
- # serialization extensions
99
-
100
- # plyutils
101
- python_add_library(TARGET plyutils SOURCES
102
- src/plyutils.h
103
- src/plyutils.c
104
- src/rply.h
105
- src/rply.c)
106
- set_property(TARGET plyutils PROPERTY FOLDER "SerializationExt/")
107
-
108
- # loadobj
109
- python_add_library(TARGET loadobj SOURCES src/py_loadobj.cpp)
110
- target_include_directories(loadobj PRIVATE
111
- ${NUMPY_INCLUDE_PATH}
112
- ${Boost_INCLUDE_DIRS})
113
- set_property(TARGET loadobj PROPERTY FOLDER "SerializationExt/")
114
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/__init__.py DELETED
@@ -1,20 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2013 Max Planck Society. All rights reserved.
5
-
6
- import os
7
- from os.path import abspath, dirname, expanduser, join
8
-
9
- from .mesh import Mesh
10
- from .meshviewer import MeshViewer, MeshViewers
11
-
12
- texture_path = abspath(join(dirname(__file__), '..', 'data', 'template', 'texture_coordinates'))
13
-
14
- if 'PSBODY_MESH_CACHE' in os.environ:
15
- mesh_package_cache_folder = expanduser(os.environ['PSBODY_MESH_CACHE'])
16
- else:
17
- mesh_package_cache_folder = expanduser('~/.psbody/mesh_package_cache')
18
-
19
- if not os.path.exists(mesh_package_cache_folder):
20
- os.makedirs(mesh_package_cache_folder)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/arcball.py DELETED
@@ -1,247 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
- # Copyright (c) 2012 Max Planck Society. All rights reserved.
4
-
5
- """
6
- Math utilities, vector, matrix types and ArcBall quaternion rotation class
7
- ==========================================================================
8
-
9
- """
10
-
11
- import numpy as Numeric
12
- import copy
13
- from math import sqrt
14
-
15
- # //assuming IEEE-754(GLfloat), which i believe has max precision of 7 bits
16
- Epsilon = 1.0e-5
17
-
18
-
19
- class ArcBallT(object):
20
- def __init__(self, NewWidth, NewHeight):
21
- self.m_StVec = Vector3fT()
22
- self.m_EnVec = Vector3fT()
23
- self.m_AdjustWidth = 1.0
24
- self.m_AdjustHeight = 1.0
25
- self.setBounds(NewWidth, NewHeight)
26
-
27
- def __str__(self):
28
- str_rep = ""
29
- str_rep += "StVec = " + str(self.m_StVec)
30
- str_rep += "\nEnVec = " + str(self.m_EnVec)
31
- str_rep += "\n scale coords %f %f" % (self.m_AdjustWidth, self.m_AdjustHeight)
32
- return str_rep
33
-
34
- def setBounds(self, NewWidth, NewHeight):
35
- # //Set new bounds
36
- assert (NewWidth > 1.0 and NewHeight > 1.0), "Invalid width or height for bounds."
37
- # //Set adjustment factor for width/height
38
- self.m_AdjustWidth = 1.0 / ((NewWidth - 1.0) * 0.5)
39
- self.m_AdjustHeight = 1.0 / ((NewHeight - 1.0) * 0.5)
40
-
41
- def _mapToSphere(self, NewPt):
42
- # Given a new window coordinate, will modify NewVec in place
43
- X = 0
44
- Y = 1
45
- Z = 2
46
-
47
- NewVec = Vector3fT()
48
- # //Copy paramter into temp point
49
- TempPt = copy.copy(NewPt)
50
- # //Adjust point coords and scale down to range of [-1 ... 1]
51
- TempPt[X] = (NewPt[X] * self.m_AdjustWidth) - 1.0
52
- TempPt[Y] = 1.0 - (NewPt[Y] * self.m_AdjustHeight)
53
- # //Compute the square of the length of the vector to the point from the center
54
- length = Numeric.sum(Numeric.dot(TempPt, TempPt))
55
- # //If the point is mapped outside of the sphere... (length > radius squared)
56
- if (length > 1.0):
57
- # //Compute a normalizing factor (radius / sqrt(length))
58
- norm = 1.0 / sqrt(length)
59
-
60
- # //Return the "normalized" vector, a point on the sphere
61
- NewVec[X] = TempPt[X] * norm
62
- NewVec[Y] = TempPt[Y] * norm
63
- NewVec[Z] = 0.0
64
- else: # //Else it's on the inside
65
- # //Return a vector to a point mapped inside the sphere sqrt(radius squared - length)
66
- NewVec[X] = TempPt[X]
67
- NewVec[Y] = TempPt[Y]
68
- NewVec[Z] = sqrt(1.0 - length)
69
-
70
- return NewVec
71
-
72
- def click(self, NewPt):
73
- # Mouse down (Point2fT
74
- self.m_StVec = self._mapToSphere(NewPt)
75
- return
76
-
77
- def drag(self, NewPt):
78
- # Mouse drag, calculate rotation (Point2fT Quat4fT)
79
- """ drag (Point2fT mouse_coord) -> new_quaternion_rotation_vec
80
- """
81
- X = 0
82
- Y = 1
83
- Z = 2
84
- W = 3
85
-
86
- self.m_EnVec = self._mapToSphere(NewPt)
87
-
88
- # //Compute the vector perpendicular to the begin and end vectors
89
- # Perp = Vector3fT ()
90
- Perp = Vector3fCross(self.m_StVec, self.m_EnVec)
91
-
92
- NewRot = Quat4fT()
93
- # Compute the length of the perpendicular vector
94
- if (Vector3fLength(Perp) > Epsilon):
95
- # if its non-zero
96
- # We're ok, so return the perpendicular vector as the transform after all
97
- NewRot[X] = Perp[X]
98
- NewRot[Y] = Perp[Y]
99
- NewRot[Z] = Perp[Z]
100
- # //In the quaternion values, w is cosine (theta / 2), where theta is rotation angle
101
- NewRot[W] = Vector3fDot(self.m_StVec, self.m_EnVec)
102
- else:
103
- # if its zero
104
- # The begin and end vectors coincide, so return a quaternion of zero matrix (no rotation)
105
- NewRot[X] = NewRot[Y] = NewRot[Z] = NewRot[W] = 0.0
106
-
107
- return NewRot
108
-
109
-
110
- def Matrix4fT():
111
- return Numeric.identity(4, 'f')
112
-
113
-
114
- def Matrix3fT():
115
- return Numeric.identity(3, 'f')
116
-
117
-
118
- def Quat4fT():
119
- return Numeric.zeros(4, 'f')
120
-
121
-
122
- def Vector3fT():
123
- return Numeric.zeros(3, 'f')
124
-
125
-
126
- def Point2fT(x=0.0, y=0.0):
127
- pt = Numeric.zeros(2, 'f')
128
- pt[0] = x
129
- pt[1] = y
130
- return pt
131
-
132
-
133
- def Vector3fDot(u, v):
134
- # Dot product of two 3f vectors
135
- dotprod = Numeric.dot(u, v)
136
- return dotprod
137
-
138
-
139
- def Vector3fCross(u, v):
140
- # Cross product of two 3f vectors
141
- X = 0
142
- Y = 1
143
- Z = 2
144
- cross = Numeric.zeros(3, 'f')
145
- cross[X] = (u[Y] * v[Z]) - (u[Z] * v[Y])
146
- cross[Y] = (u[Z] * v[X]) - (u[X] * v[Z])
147
- cross[Z] = (u[X] * v[Y]) - (u[Y] * v[X])
148
- return cross
149
-
150
-
151
- def Vector3fLength(u):
152
- mag_squared = Numeric.sum(Numeric.dot(u, u))
153
- mag = sqrt(mag_squared)
154
- return mag
155
-
156
-
157
- def Matrix3fSetIdentity():
158
- return Numeric.identity(3, 'f')
159
-
160
-
161
- def Matrix3fMulMatrix3f(matrix_a, matrix_b):
162
- return matrix_a.dot(matrix_b)
163
-
164
-
165
- def Matrix4fSVD(NewObj):
166
- X = 0
167
- Y = 1
168
- Z = 2
169
- s = sqrt(((NewObj[X][X] * NewObj[X][X]) + (NewObj[X][Y] * NewObj[X][Y]) + (NewObj[X][Z] * NewObj[X][Z]) +
170
- (NewObj[Y][X] * NewObj[Y][X]) + (NewObj[Y][Y] * NewObj[Y][Y]) + (NewObj[Y][Z] * NewObj[Y][Z]) +
171
- (NewObj[Z][X] * NewObj[Z][X]) + (NewObj[Z][Y] * NewObj[Z][Y]) + (NewObj[Z][Z] * NewObj[Z][Z])) / 3.0)
172
- return s
173
-
174
-
175
- def Matrix4fSetRotationScaleFromMatrix3f(NewObj, three_by_three_matrix):
176
- """Modifies NewObj in-place by replacing its upper 3x3 portion from the
177
- passed in 3x3 matrix.
178
-
179
- :param NewObj: a `Matrix4fT`
180
- """
181
- NewObj[0:3, 0:3] = three_by_three_matrix
182
- return NewObj
183
-
184
-
185
- def Matrix4fSetRotationFromMatrix3f(NewObj, three_by_three_matrix):
186
- """
187
- Sets the rotational component (upper 3x3) of this matrix to the matrix
188
- values in the T precision Matrix3d argument; the other elements of
189
- this matrix are unchanged; a singular value decomposition is performed
190
- on this object's upper 3x3 matrix to factor out the scale, then this
191
- object's upper 3x3 matrix components are replaced by the passed rotation
192
- components, and then the scale is reapplied to the rotational
193
- components.
194
-
195
- :param three_by_three_matrix: T precision 3x3 matrix
196
- """
197
- scale = Matrix4fSVD(NewObj)
198
-
199
- NewObj = Matrix4fSetRotationScaleFromMatrix3f(NewObj, three_by_three_matrix)
200
- scaled_NewObj = NewObj * scale # Matrix4fMulRotationScale(NewObj, scale);
201
- return scaled_NewObj
202
-
203
-
204
- def Matrix3fSetRotationFromQuat4f(q1):
205
- """Converts the H quaternion q1 into a new equivalent 3x3 rotation matrix."""
206
- X = 0
207
- Y = 1
208
- Z = 2
209
- W = 3
210
-
211
- NewObj = Matrix3fT()
212
- n = Numeric.sum(Numeric.dot(q1, q1))
213
- s = 0.0
214
- if (n > 0.0):
215
- s = 2.0 / n
216
-
217
- xs = q1[X] * s
218
- ys = q1[Y] * s
219
- zs = q1[Z] * s
220
-
221
- wx = q1[W] * xs
222
- wy = q1[W] * ys
223
- wz = q1[W] * zs
224
-
225
- xx = q1[X] * xs
226
- xy = q1[X] * ys
227
- xz = q1[X] * zs
228
-
229
- yy = q1[Y] * ys
230
- yz = q1[Y] * zs
231
- zz = q1[Z] * zs
232
-
233
- # This math all comes about by way of algebra, complex math, and trig identities.
234
- # See Lengyel pages 88-92
235
- NewObj[X][X] = 1.0 - (yy + zz)
236
- NewObj[Y][X] = xy - wz
237
- NewObj[Z][X] = xz + wy
238
-
239
- NewObj[X][Y] = xy + wz
240
- NewObj[Y][Y] = 1.0 - (xx + zz)
241
- NewObj[Z][Y] = yz - wx
242
-
243
- NewObj[X][Z] = xz - wy
244
- NewObj[Y][Z] = yz + wx
245
- NewObj[Z][Z] = 1.0 - (xx + yy)
246
-
247
- return NewObj
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/cmake/python_helper.cmake DELETED
@@ -1,74 +0,0 @@
1
- # Copyright 2016, Max Planck Society.
2
- # Not licensed
3
- # author Raffi Enficiaud
4
-
5
- # helper file containing commands easing the declaration of python modules
6
-
7
- include(CMakeParseArguments)
8
-
9
-
10
- #.rst:
11
- # .. command:: python_add_library
12
- #
13
- # Adds a shared library that is meant to be a python extension module.
14
- # The added library links to python library and has the proper extension.
15
- #
16
- # ::
17
- #
18
- # python_add_library(
19
- # TARGET targetname
20
- # SOURCES source_list)
21
- #
22
- # ``targetname`` name of the python extension
23
- # ``source_list`` list of source files for this target.
24
- #
25
- function(python_add_library)
26
-
27
- if("${PYTHON_MODULES_EXTENSIONS}" STREQUAL "")
28
- if("${PYTHON_VERSION}" VERSION_GREATER "2.5")
29
- if(UNIX OR MINGW)
30
- set(PYTHON_MODULES_EXTENSIONS_TEMP ".so")
31
- else()
32
- set(PYTHON_MODULES_EXTENSIONS_TEMP ".pyd")
33
- endif()
34
- else()
35
- if(APPLE)
36
- set(PYTHON_MODULES_EXTENSIONS_TEMP ".so")
37
- else()
38
- set(PYTHON_MODULES_EXTENSIONS_TEMP ${CMAKE_SHARED_LIBRARY_SUFFIX})
39
- endif()
40
- endif()
41
- set(PYTHON_MODULES_EXTENSIONS ${PYTHON_MODULES_EXTENSIONS_TEMP} CACHE STRING "Python modules extension for the current platform")
42
- endif()
43
-
44
-
45
- set(options )
46
- set(oneValueArgs TARGET)
47
- set(multiValueArgs SOURCES)
48
- cmake_parse_arguments(local_python_add_cmd "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
49
-
50
- if("${local_python_add_cmd_TARGET}" STREQUAL "")
51
- message(FATAL_ERROR "python_add_library: the TARGET should be specified")
52
- endif()
53
-
54
- if("${local_python_add_cmd_SOURCES}" STREQUAL "")
55
- message(FATAL_ERROR "python_add_library: at least one source file should be specified")
56
- endif()
57
-
58
- add_library(${local_python_add_cmd_TARGET} SHARED
59
- src/hijack_python_headers.hpp # by default
60
- "${local_python_add_cmd_SOURCES}")
61
- target_include_directories(${local_python_add_cmd_TARGET} PRIVATE ${PYTHON_INCLUDE_PATH})
62
- target_link_libraries(${local_python_add_cmd_TARGET} ${PYTHON_LIBRARY}) # PYTHON_LIBRARIES may contain the debug version of python, which we do not want
63
- set_target_properties(${local_python_add_cmd_TARGET}
64
- PROPERTIES SUFFIX ${PYTHON_MODULES_EXTENSIONS}
65
- PREFIX "")
66
-
67
- if(FALSE)
68
- set_target_properties(${local_python_add_cmd_TARGET}
69
- PROPERTIES
70
- OUTPUT_NAME_DEBUG ${local_python_add_cmd_TARGET}_d
71
- )
72
- endif()
73
-
74
- endfunction(python_add_library)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/cmake/thirdparty.cmake DELETED
@@ -1,107 +0,0 @@
1
- # Copyright 2016, Max Planck Society.
2
- # Not licensed
3
- # author Raffi Enficiaud
4
-
5
- # this file contains all the necessary to link against thirdparty libraries
6
-
7
- # location of the stored thirdparty archives
8
- set(thirdparty_dir ${CMAKE_SOURCE_DIR}/thirdparty)
9
-
10
- # the location where the archives will be deflated, to avoid pollution
11
- # of the source tree
12
- set(thirdparties_deflate_directory ${CMAKE_BINARY_DIR}/external_libs_deflate)
13
- if(NOT EXISTS ${thirdparties_deflate_directory})
14
- file(MAKE_DIRECTORY ${thirdparties_deflate_directory})
15
- endif()
16
-
17
- # this module may be used to find system installed libraries on Linux
18
- if(UNIX AND NOT APPLE)
19
- find_package(PkgConfig)
20
- endif()
21
-
22
-
23
- # Python libraries, required
24
- find_package(PythonLibs REQUIRED)
25
- find_package(PythonInterp REQUIRED)
26
-
27
- # numpy
28
- execute_process(
29
- COMMAND ${PYTHON_EXECUTABLE} -c "import numpy; print(numpy.get_include())"
30
- OUTPUT_VARIABLE NUMPY_INCLUDE_PATH
31
- ERROR_VARIABLE NUMPY_ERROR
32
- OUTPUT_STRIP_TRAILING_WHITESPACE
33
- )
34
- if(NOT (NUMPY_ERROR STREQUAL "") OR (NUMPY_INCLUDE_PATH STREQUAL ""))
35
- message(FATAL_ERROR "[numpy] the following error occured: ${NUMPY_ERROR} - Consider setting PYTHON_ROOT in the environment")
36
- endif()
37
- message(STATUS "[numpy] found headers in ${NUMPY_INCLUDE_PATH}")
38
-
39
-
40
- # cgal
41
- set(CGAL_MAJOR_VERSION 4)
42
- set(CGAL_MINOR_VERSION 7)
43
- set(CGAL_VERSION ${CGAL_MAJOR_VERSION}.${CGAL_MINOR_VERSION})
44
- set(LIBCGAL CGAL-${CGAL_MAJOR_VERSION}.${CGAL_MINOR_VERSION})
45
- set(libcgalroot ${thirdparties_deflate_directory}/${LIBCGAL})
46
-
47
- if(NOT EXISTS ${libcgalroot})
48
- message(STATUS "Untarring ${LIBCGAL}")
49
- execute_process(
50
- COMMAND ${CMAKE_COMMAND} -E tar xzf ${thirdparty_dir}/${LIBCGAL}.tar.gz
51
- WORKING_DIRECTORY ${thirdparties_deflate_directory})
52
- endif()
53
-
54
- if(NOT EXISTS ${libcgalroot}/include/CGAL/compiler_config.h)
55
- message(STATUS "[CGAL] creating empty configuration file for header only compilation")
56
- file(WRITE
57
- ${libcgalroot}/include/CGAL/compiler_config.h
58
- "// automatically generated by mesh cmake")
59
- endif()
60
-
61
-
62
-
63
- # boost (needed by CGAL)
64
- if(NOT BOOST_ROOT)
65
- message(STATUS "[BOOST] Boost root not configured, taking the system boost version")
66
- set(MESH_BOOST_FROM_SYSTEM TRUE)
67
- else()
68
- message(STATUS "[BOOST] Boost root directory set to ${BOOST_ROOT}")
69
- set(MESH_BOOST_FROM_SYSTEM FALSE)
70
- endif()
71
-
72
- if(UNIX AND NOT APPLE AND NOT MESH_BOOST_FROM_SYSTEM)
73
- message(WARNING "[BOOST] you are setting a different boost than the one provided by the system. This option should be taken with care.")
74
- endif()
75
-
76
- set(Boost_ADDITIONAL_VERSIONS
77
- "1.54" "1.54.0" "1.55" "1.55.0" "1.56" "1.56.0" "1.57.0" "1.58" "1.58.0" "1.59" "1.59.0"
78
- "1.60" "1.60.0" "1.61" "1.61.0")
79
-
80
-
81
- add_definitions(-DBOOST_ALL_NO_LIB) # disable auto link
82
- set(Boost_USE_STATIC_LIBS OFF) # linking with static library version (not used because of the header only)
83
- if(NOT Boost_USE_STATIC_LIBS)
84
- # link against dynamic libraries
85
- add_definitions(-DBOOST_ALL_DYN_LINK)
86
- endif()
87
-
88
- # if we are using the system version, we do not want to have the exact version embedded in the rpath/ldd
89
- if(MESH_BOOST_FROM_SYSTEM)
90
- set(Boost_REALPATH OFF)
91
- else()
92
- set(Boost_REALPATH ON)
93
- endif()
94
-
95
- set(Boost_USE_MULTITHREADED ON)
96
- set(Boost_DEBUG ON)
97
- set(Boost_DETAILED_FAILURE_MSG ON)
98
- if(DEFINED BOOST_ROOT)
99
- set(Boost_NO_SYSTEM_PATHS ON)
100
- else()
101
- set(Boost_NO_SYSTEM_PATHS OFF)
102
- endif()
103
- set(Boost_NO_BOOST_CMAKE ON)
104
-
105
- # only the header locations
106
- find_package(Boost 1.59)
107
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/colors.py DELETED
@@ -1,790 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
- # Copyright (c) 2012 Max Planck Society. All rights reserved.
4
- # Created by Matthew Loper on 2012-05-12.
5
-
6
- """
7
- Colors utilities
8
- ================
9
-
10
-
11
- """
12
-
13
- import re
14
- import numpy as np
15
-
16
-
17
- def main():
18
- """Generates code for name_to_rgb dict, assuming an rgb.txt file available (in X11 format)."""
19
- with open('rgb.txt') as fp:
20
-
21
- line = fp.readline()
22
- while line:
23
- reg = re.match('\s*(\d+)\s*(\d+)\s*(\d+)\s*(\w.*\w).*', line)
24
- if reg:
25
- r = int(reg.group(1)) / 255.
26
- g = int(reg.group(2)) / 255.
27
- b = int(reg.group(3)) / 255.
28
- d = reg.group(4)
29
- print("'%s': np.array([%.2f, %.2f, %.2f])," % (d, r, g, b))
30
- line = fp.readline()
31
-
32
-
33
- name_to_rgb = {
34
- 'snow': np.array([1.00, 0.98, 0.98]),
35
- 'ghost white': np.array([0.97, 0.97, 1.00]),
36
- 'GhostWhite': np.array([0.97, 0.97, 1.00]),
37
- 'white smoke': np.array([0.96, 0.96, 0.96]),
38
- 'WhiteSmoke': np.array([0.96, 0.96, 0.96]),
39
- 'gainsboro': np.array([0.86, 0.86, 0.86]),
40
- 'floral white': np.array([1.00, 0.98, 0.94]),
41
- 'FloralWhite': np.array([1.00, 0.98, 0.94]),
42
- 'old lace': np.array([0.99, 0.96, 0.90]),
43
- 'OldLace': np.array([0.99, 0.96, 0.90]),
44
- 'linen': np.array([0.98, 0.94, 0.90]),
45
- 'antique white': np.array([0.98, 0.92, 0.84]),
46
- 'AntiqueWhite': np.array([0.98, 0.92, 0.84]),
47
- 'papaya whip': np.array([1.00, 0.94, 0.84]),
48
- 'PapayaWhip': np.array([1.00, 0.94, 0.84]),
49
- 'blanched almond': np.array([1.00, 0.92, 0.80]),
50
- 'BlanchedAlmond': np.array([1.00, 0.92, 0.80]),
51
- 'bisque': np.array([1.00, 0.89, 0.77]),
52
- 'peach puff': np.array([1.00, 0.85, 0.73]),
53
- 'PeachPuff': np.array([1.00, 0.85, 0.73]),
54
- 'navajo white': np.array([1.00, 0.87, 0.68]),
55
- 'NavajoWhite': np.array([1.00, 0.87, 0.68]),
56
- 'moccasin': np.array([1.00, 0.89, 0.71]),
57
- 'cornsilk': np.array([1.00, 0.97, 0.86]),
58
- 'ivory': np.array([1.00, 1.00, 0.94]),
59
- 'lemon chiffon': np.array([1.00, 0.98, 0.80]),
60
- 'LemonChiffon': np.array([1.00, 0.98, 0.80]),
61
- 'seashell': np.array([1.00, 0.96, 0.93]),
62
- 'honeydew': np.array([0.94, 1.00, 0.94]),
63
- 'mint cream': np.array([0.96, 1.00, 0.98]),
64
- 'MintCream': np.array([0.96, 1.00, 0.98]),
65
- 'azure': np.array([0.94, 1.00, 1.00]),
66
- 'alice blue': np.array([0.94, 0.97, 1.00]),
67
- 'AliceBlue': np.array([0.94, 0.97, 1.00]),
68
- 'lavender': np.array([0.90, 0.90, 0.98]),
69
- 'lavender blush': np.array([1.00, 0.94, 0.96]),
70
- 'LavenderBlush': np.array([1.00, 0.94, 0.96]),
71
- 'misty rose': np.array([1.00, 0.89, 0.88]),
72
- 'MistyRose': np.array([1.00, 0.89, 0.88]),
73
- 'white': np.array([1.00, 1.00, 1.00]),
74
- 'black': np.array([0.00, 0.00, 0.00]),
75
- 'dark slate gray': np.array([0.18, 0.31, 0.31]),
76
- 'DarkSlateGray': np.array([0.18, 0.31, 0.31]),
77
- 'dark slate grey': np.array([0.18, 0.31, 0.31]),
78
- 'DarkSlateGrey': np.array([0.18, 0.31, 0.31]),
79
- 'dim gray': np.array([0.41, 0.41, 0.41]),
80
- 'DimGray': np.array([0.41, 0.41, 0.41]),
81
- 'dim grey': np.array([0.41, 0.41, 0.41]),
82
- 'DimGrey': np.array([0.41, 0.41, 0.41]),
83
- 'slate gray': np.array([0.44, 0.50, 0.56]),
84
- 'SlateGray': np.array([0.44, 0.50, 0.56]),
85
- 'slate grey': np.array([0.44, 0.50, 0.56]),
86
- 'SlateGrey': np.array([0.44, 0.50, 0.56]),
87
- 'light slate gray': np.array([0.47, 0.53, 0.60]),
88
- 'LightSlateGray': np.array([0.47, 0.53, 0.60]),
89
- 'light slate grey': np.array([0.47, 0.53, 0.60]),
90
- 'LightSlateGrey': np.array([0.47, 0.53, 0.60]),
91
- 'gray': np.array([0.75, 0.75, 0.75]),
92
- 'grey': np.array([0.75, 0.75, 0.75]),
93
- 'light grey': np.array([0.83, 0.83, 0.83]),
94
- 'LightGrey': np.array([0.83, 0.83, 0.83]),
95
- 'light gray': np.array([0.83, 0.83, 0.83]),
96
- 'LightGray': np.array([0.83, 0.83, 0.83]),
97
- 'midnight blue': np.array([0.10, 0.10, 0.44]),
98
- 'MidnightBlue': np.array([0.10, 0.10, 0.44]),
99
- 'navy': np.array([0.00, 0.00, 0.50]),
100
- 'navy blue': np.array([0.00, 0.00, 0.50]),
101
- 'NavyBlue': np.array([0.00, 0.00, 0.50]),
102
- 'cornflower blue': np.array([0.39, 0.58, 0.93]),
103
- 'CornflowerBlue': np.array([0.39, 0.58, 0.93]),
104
- 'dark slate blue': np.array([0.28, 0.24, 0.55]),
105
- 'DarkSlateBlue': np.array([0.28, 0.24, 0.55]),
106
- 'slate blue': np.array([0.42, 0.35, 0.80]),
107
- 'SlateBlue': np.array([0.42, 0.35, 0.80]),
108
- 'medium slate blue': np.array([0.48, 0.41, 0.93]),
109
- 'MediumSlateBlue': np.array([0.48, 0.41, 0.93]),
110
- 'light slate blue': np.array([0.52, 0.44, 1.00]),
111
- 'LightSlateBlue': np.array([0.52, 0.44, 1.00]),
112
- 'medium blue': np.array([0.00, 0.00, 0.80]),
113
- 'MediumBlue': np.array([0.00, 0.00, 0.80]),
114
- 'royal blue': np.array([0.25, 0.41, 0.88]),
115
- 'RoyalBlue': np.array([0.25, 0.41, 0.88]),
116
- 'blue': np.array([0.00, 0.00, 1.00]),
117
- 'dodger blue': np.array([0.12, 0.56, 1.00]),
118
- 'DodgerBlue': np.array([0.12, 0.56, 1.00]),
119
- 'deep sky blue': np.array([0.00, 0.75, 1.00]),
120
- 'DeepSkyBlue': np.array([0.00, 0.75, 1.00]),
121
- 'sky blue': np.array([0.53, 0.81, 0.92]),
122
- 'SkyBlue': np.array([0.53, 0.81, 0.92]),
123
- 'light sky blue': np.array([0.53, 0.81, 0.98]),
124
- 'LightSkyBlue': np.array([0.53, 0.81, 0.98]),
125
- 'steel blue': np.array([0.27, 0.51, 0.71]),
126
- 'SteelBlue': np.array([0.27, 0.51, 0.71]),
127
- 'light steel blue': np.array([0.69, 0.77, 0.87]),
128
- 'LightSteelBlue': np.array([0.69, 0.77, 0.87]),
129
- 'light blue': np.array([0.68, 0.85, 0.90]),
130
- 'LightBlue': np.array([0.68, 0.85, 0.90]),
131
- 'powder blue': np.array([0.69, 0.88, 0.90]),
132
- 'PowderBlue': np.array([0.69, 0.88, 0.90]),
133
- 'pale turquoise': np.array([0.69, 0.93, 0.93]),
134
- 'PaleTurquoise': np.array([0.69, 0.93, 0.93]),
135
- 'dark turquoise': np.array([0.00, 0.81, 0.82]),
136
- 'DarkTurquoise': np.array([0.00, 0.81, 0.82]),
137
- 'medium turquoise': np.array([0.28, 0.82, 0.80]),
138
- 'MediumTurquoise': np.array([0.28, 0.82, 0.80]),
139
- 'turquoise': np.array([0.25, 0.88, 0.82]),
140
- 'cyan': np.array([0.00, 1.00, 1.00]),
141
- 'light cyan': np.array([0.88, 1.00, 1.00]),
142
- 'LightCyan': np.array([0.88, 1.00, 1.00]),
143
- 'cadet blue': np.array([0.37, 0.62, 0.63]),
144
- 'CadetBlue': np.array([0.37, 0.62, 0.63]),
145
- 'medium aquamarine': np.array([0.40, 0.80, 0.67]),
146
- 'MediumAquamarine': np.array([0.40, 0.80, 0.67]),
147
- 'aquamarine': np.array([0.50, 1.00, 0.83]),
148
- 'dark green': np.array([0.00, 0.39, 0.00]),
149
- 'DarkGreen': np.array([0.00, 0.39, 0.00]),
150
- 'dark olive green': np.array([0.33, 0.42, 0.18]),
151
- 'DarkOliveGreen': np.array([0.33, 0.42, 0.18]),
152
- 'dark sea green': np.array([0.56, 0.74, 0.56]),
153
- 'DarkSeaGreen': np.array([0.56, 0.74, 0.56]),
154
- 'sea green': np.array([0.18, 0.55, 0.34]),
155
- 'SeaGreen': np.array([0.18, 0.55, 0.34]),
156
- 'medium sea green': np.array([0.24, 0.70, 0.44]),
157
- 'MediumSeaGreen': np.array([0.24, 0.70, 0.44]),
158
- 'light sea green': np.array([0.13, 0.70, 0.67]),
159
- 'LightSeaGreen': np.array([0.13, 0.70, 0.67]),
160
- 'pale green': np.array([0.60, 0.98, 0.60]),
161
- 'PaleGreen': np.array([0.60, 0.98, 0.60]),
162
- 'spring green': np.array([0.00, 1.00, 0.50]),
163
- 'SpringGreen': np.array([0.00, 1.00, 0.50]),
164
- 'lawn green': np.array([0.49, 0.99, 0.00]),
165
- 'LawnGreen': np.array([0.49, 0.99, 0.00]),
166
- 'green': np.array([0.00, 1.00, 0.00]),
167
- 'chartreuse': np.array([0.50, 1.00, 0.00]),
168
- 'medium spring green': np.array([0.00, 0.98, 0.60]),
169
- 'MediumSpringGreen': np.array([0.00, 0.98, 0.60]),
170
- 'green yellow': np.array([0.68, 1.00, 0.18]),
171
- 'GreenYellow': np.array([0.68, 1.00, 0.18]),
172
- 'lime green': np.array([0.20, 0.80, 0.20]),
173
- 'LimeGreen': np.array([0.20, 0.80, 0.20]),
174
- 'yellow green': np.array([0.60, 0.80, 0.20]),
175
- 'YellowGreen': np.array([0.60, 0.80, 0.20]),
176
- 'forest green': np.array([0.13, 0.55, 0.13]),
177
- 'ForestGreen': np.array([0.13, 0.55, 0.13]),
178
- 'olive drab': np.array([0.42, 0.56, 0.14]),
179
- 'OliveDrab': np.array([0.42, 0.56, 0.14]),
180
- 'dark khaki': np.array([0.74, 0.72, 0.42]),
181
- 'DarkKhaki': np.array([0.74, 0.72, 0.42]),
182
- 'khaki': np.array([0.94, 0.90, 0.55]),
183
- 'pale goldenrod': np.array([0.93, 0.91, 0.67]),
184
- 'PaleGoldenrod': np.array([0.93, 0.91, 0.67]),
185
- 'light goldenrod yellow': np.array([0.98, 0.98, 0.82]),
186
- 'LightGoldenrodYellow': np.array([0.98, 0.98, 0.82]),
187
- 'light yellow': np.array([1.00, 1.00, 0.88]),
188
- 'LightYellow': np.array([1.00, 1.00, 0.88]),
189
- 'yellow': np.array([1.00, 1.00, 0.00]),
190
- 'gold': np.array([1.00, 0.84, 0.00]),
191
- 'light goldenrod': np.array([0.93, 0.87, 0.51]),
192
- 'LightGoldenrod': np.array([0.93, 0.87, 0.51]),
193
- 'goldenrod': np.array([0.85, 0.65, 0.13]),
194
- 'dark goldenrod': np.array([0.72, 0.53, 0.04]),
195
- 'DarkGoldenrod': np.array([0.72, 0.53, 0.04]),
196
- 'rosy brown': np.array([0.74, 0.56, 0.56]),
197
- 'RosyBrown': np.array([0.74, 0.56, 0.56]),
198
- 'indian red': np.array([0.80, 0.36, 0.36]),
199
- 'IndianRed': np.array([0.80, 0.36, 0.36]),
200
- 'saddle brown': np.array([0.55, 0.27, 0.07]),
201
- 'SaddleBrown': np.array([0.55, 0.27, 0.07]),
202
- 'sienna': np.array([0.63, 0.32, 0.18]),
203
- 'peru': np.array([0.80, 0.52, 0.25]),
204
- 'burlywood': np.array([0.87, 0.72, 0.53]),
205
- 'beige': np.array([0.96, 0.96, 0.86]),
206
- 'wheat': np.array([0.96, 0.87, 0.70]),
207
- 'sandy brown': np.array([0.96, 0.64, 0.38]),
208
- 'SandyBrown': np.array([0.96, 0.64, 0.38]),
209
- 'tan': np.array([0.82, 0.71, 0.55]),
210
- 'chocolate': np.array([0.82, 0.41, 0.12]),
211
- 'firebrick': np.array([0.70, 0.13, 0.13]),
212
- 'brown': np.array([0.65, 0.16, 0.16]),
213
- 'dark salmon': np.array([0.91, 0.59, 0.48]),
214
- 'DarkSalmon': np.array([0.91, 0.59, 0.48]),
215
- 'salmon': np.array([0.98, 0.50, 0.45]),
216
- 'light salmon': np.array([1.00, 0.63, 0.48]),
217
- 'LightSalmon': np.array([1.00, 0.63, 0.48]),
218
- 'orange': np.array([1.00, 0.65, 0.00]),
219
- 'dark orange': np.array([1.00, 0.55, 0.00]),
220
- 'DarkOrange': np.array([1.00, 0.55, 0.00]),
221
- 'coral': np.array([1.00, 0.50, 0.31]),
222
- 'light coral': np.array([0.94, 0.50, 0.50]),
223
- 'LightCoral': np.array([0.94, 0.50, 0.50]),
224
- 'tomato': np.array([1.00, 0.39, 0.28]),
225
- 'orange red': np.array([1.00, 0.27, 0.00]),
226
- 'OrangeRed': np.array([1.00, 0.27, 0.00]),
227
- 'red': np.array([1.00, 0.00, 0.00]),
228
- 'hot pink': np.array([1.00, 0.41, 0.71]),
229
- 'HotPink': np.array([1.00, 0.41, 0.71]),
230
- 'deep pink': np.array([1.00, 0.08, 0.58]),
231
- 'DeepPink': np.array([1.00, 0.08, 0.58]),
232
- 'pink': np.array([1.00, 0.75, 0.80]),
233
- 'light pink': np.array([1.00, 0.71, 0.76]),
234
- 'LightPink': np.array([1.00, 0.71, 0.76]),
235
- 'pale violet red': np.array([0.86, 0.44, 0.58]),
236
- 'PaleVioletRed': np.array([0.86, 0.44, 0.58]),
237
- 'maroon': np.array([0.69, 0.19, 0.38]),
238
- 'medium violet red': np.array([0.78, 0.08, 0.52]),
239
- 'MediumVioletRed': np.array([0.78, 0.08, 0.52]),
240
- 'violet red': np.array([0.82, 0.13, 0.56]),
241
- 'VioletRed': np.array([0.82, 0.13, 0.56]),
242
- 'magenta': np.array([1.00, 0.00, 1.00]),
243
- 'violet': np.array([0.93, 0.51, 0.93]),
244
- 'plum': np.array([0.87, 0.63, 0.87]),
245
- 'orchid': np.array([0.85, 0.44, 0.84]),
246
- 'medium orchid': np.array([0.73, 0.33, 0.83]),
247
- 'MediumOrchid': np.array([0.73, 0.33, 0.83]),
248
- 'dark orchid': np.array([0.60, 0.20, 0.80]),
249
- 'DarkOrchid': np.array([0.60, 0.20, 0.80]),
250
- 'dark violet': np.array([0.58, 0.00, 0.83]),
251
- 'DarkViolet': np.array([0.58, 0.00, 0.83]),
252
- 'blue violet': np.array([0.54, 0.17, 0.89]),
253
- 'BlueViolet': np.array([0.54, 0.17, 0.89]),
254
- 'purple': np.array([0.63, 0.13, 0.94]),
255
- 'medium purple': np.array([0.58, 0.44, 0.86]),
256
- 'MediumPurple': np.array([0.58, 0.44, 0.86]),
257
- 'thistle': np.array([0.85, 0.75, 0.85]),
258
- 'snow1': np.array([1.00, 0.98, 0.98]),
259
- 'snow2': np.array([0.93, 0.91, 0.91]),
260
- 'snow3': np.array([0.80, 0.79, 0.79]),
261
- 'snow4': np.array([0.55, 0.54, 0.54]),
262
- 'seashell1': np.array([1.00, 0.96, 0.93]),
263
- 'seashell2': np.array([0.93, 0.90, 0.87]),
264
- 'seashell3': np.array([0.80, 0.77, 0.75]),
265
- 'seashell4': np.array([0.55, 0.53, 0.51]),
266
- 'AntiqueWhite1': np.array([1.00, 0.94, 0.86]),
267
- 'AntiqueWhite2': np.array([0.93, 0.87, 0.80]),
268
- 'AntiqueWhite3': np.array([0.80, 0.75, 0.69]),
269
- 'AntiqueWhite4': np.array([0.55, 0.51, 0.47]),
270
- 'bisque1': np.array([1.00, 0.89, 0.77]),
271
- 'bisque2': np.array([0.93, 0.84, 0.72]),
272
- 'bisque3': np.array([0.80, 0.72, 0.62]),
273
- 'bisque4': np.array([0.55, 0.49, 0.42]),
274
- 'PeachPuff1': np.array([1.00, 0.85, 0.73]),
275
- 'PeachPuff2': np.array([0.93, 0.80, 0.68]),
276
- 'PeachPuff3': np.array([0.80, 0.69, 0.58]),
277
- 'PeachPuff4': np.array([0.55, 0.47, 0.40]),
278
- 'NavajoWhite1': np.array([1.00, 0.87, 0.68]),
279
- 'NavajoWhite2': np.array([0.93, 0.81, 0.63]),
280
- 'NavajoWhite3': np.array([0.80, 0.70, 0.55]),
281
- 'NavajoWhite4': np.array([0.55, 0.47, 0.37]),
282
- 'LemonChiffon1': np.array([1.00, 0.98, 0.80]),
283
- 'LemonChiffon2': np.array([0.93, 0.91, 0.75]),
284
- 'LemonChiffon3': np.array([0.80, 0.79, 0.65]),
285
- 'LemonChiffon4': np.array([0.55, 0.54, 0.44]),
286
- 'cornsilk1': np.array([1.00, 0.97, 0.86]),
287
- 'cornsilk2': np.array([0.93, 0.91, 0.80]),
288
- 'cornsilk3': np.array([0.80, 0.78, 0.69]),
289
- 'cornsilk4': np.array([0.55, 0.53, 0.47]),
290
- 'ivory1': np.array([1.00, 1.00, 0.94]),
291
- 'ivory2': np.array([0.93, 0.93, 0.88]),
292
- 'ivory3': np.array([0.80, 0.80, 0.76]),
293
- 'ivory4': np.array([0.55, 0.55, 0.51]),
294
- 'honeydew1': np.array([0.94, 1.00, 0.94]),
295
- 'honeydew2': np.array([0.88, 0.93, 0.88]),
296
- 'honeydew3': np.array([0.76, 0.80, 0.76]),
297
- 'honeydew4': np.array([0.51, 0.55, 0.51]),
298
- 'LavenderBlush1': np.array([1.00, 0.94, 0.96]),
299
- 'LavenderBlush2': np.array([0.93, 0.88, 0.90]),
300
- 'LavenderBlush3': np.array([0.80, 0.76, 0.77]),
301
- 'LavenderBlush4': np.array([0.55, 0.51, 0.53]),
302
- 'MistyRose1': np.array([1.00, 0.89, 0.88]),
303
- 'MistyRose2': np.array([0.93, 0.84, 0.82]),
304
- 'MistyRose3': np.array([0.80, 0.72, 0.71]),
305
- 'MistyRose4': np.array([0.55, 0.49, 0.48]),
306
- 'azure1': np.array([0.94, 1.00, 1.00]),
307
- 'azure2': np.array([0.88, 0.93, 0.93]),
308
- 'azure3': np.array([0.76, 0.80, 0.80]),
309
- 'azure4': np.array([0.51, 0.55, 0.55]),
310
- 'SlateBlue1': np.array([0.51, 0.44, 1.00]),
311
- 'SlateBlue2': np.array([0.48, 0.40, 0.93]),
312
- 'SlateBlue3': np.array([0.41, 0.35, 0.80]),
313
- 'SlateBlue4': np.array([0.28, 0.24, 0.55]),
314
- 'RoyalBlue1': np.array([0.28, 0.46, 1.00]),
315
- 'RoyalBlue2': np.array([0.26, 0.43, 0.93]),
316
- 'RoyalBlue3': np.array([0.23, 0.37, 0.80]),
317
- 'RoyalBlue4': np.array([0.15, 0.25, 0.55]),
318
- 'blue1': np.array([0.00, 0.00, 1.00]),
319
- 'blue2': np.array([0.00, 0.00, 0.93]),
320
- 'blue3': np.array([0.00, 0.00, 0.80]),
321
- 'blue4': np.array([0.00, 0.00, 0.55]),
322
- 'DodgerBlue1': np.array([0.12, 0.56, 1.00]),
323
- 'DodgerBlue2': np.array([0.11, 0.53, 0.93]),
324
- 'DodgerBlue3': np.array([0.09, 0.45, 0.80]),
325
- 'DodgerBlue4': np.array([0.06, 0.31, 0.55]),
326
- 'SteelBlue1': np.array([0.39, 0.72, 1.00]),
327
- 'SteelBlue2': np.array([0.36, 0.67, 0.93]),
328
- 'SteelBlue3': np.array([0.31, 0.58, 0.80]),
329
- 'SteelBlue4': np.array([0.21, 0.39, 0.55]),
330
- 'DeepSkyBlue1': np.array([0.00, 0.75, 1.00]),
331
- 'DeepSkyBlue2': np.array([0.00, 0.70, 0.93]),
332
- 'DeepSkyBlue3': np.array([0.00, 0.60, 0.80]),
333
- 'DeepSkyBlue4': np.array([0.00, 0.41, 0.55]),
334
- 'SkyBlue1': np.array([0.53, 0.81, 1.00]),
335
- 'SkyBlue2': np.array([0.49, 0.75, 0.93]),
336
- 'SkyBlue3': np.array([0.42, 0.65, 0.80]),
337
- 'SkyBlue4': np.array([0.29, 0.44, 0.55]),
338
- 'LightSkyBlue1': np.array([0.69, 0.89, 1.00]),
339
- 'LightSkyBlue2': np.array([0.64, 0.83, 0.93]),
340
- 'LightSkyBlue3': np.array([0.55, 0.71, 0.80]),
341
- 'LightSkyBlue4': np.array([0.38, 0.48, 0.55]),
342
- 'SlateGray1': np.array([0.78, 0.89, 1.00]),
343
- 'SlateGray2': np.array([0.73, 0.83, 0.93]),
344
- 'SlateGray3': np.array([0.62, 0.71, 0.80]),
345
- 'SlateGray4': np.array([0.42, 0.48, 0.55]),
346
- 'LightSteelBlue1': np.array([0.79, 0.88, 1.00]),
347
- 'LightSteelBlue2': np.array([0.74, 0.82, 0.93]),
348
- 'LightSteelBlue3': np.array([0.64, 0.71, 0.80]),
349
- 'LightSteelBlue4': np.array([0.43, 0.48, 0.55]),
350
- 'LightBlue1': np.array([0.75, 0.94, 1.00]),
351
- 'LightBlue2': np.array([0.70, 0.87, 0.93]),
352
- 'LightBlue3': np.array([0.60, 0.75, 0.80]),
353
- 'LightBlue4': np.array([0.41, 0.51, 0.55]),
354
- 'LightCyan1': np.array([0.88, 1.00, 1.00]),
355
- 'LightCyan2': np.array([0.82, 0.93, 0.93]),
356
- 'LightCyan3': np.array([0.71, 0.80, 0.80]),
357
- 'LightCyan4': np.array([0.48, 0.55, 0.55]),
358
- 'PaleTurquoise1': np.array([0.73, 1.00, 1.00]),
359
- 'PaleTurquoise2': np.array([0.68, 0.93, 0.93]),
360
- 'PaleTurquoise3': np.array([0.59, 0.80, 0.80]),
361
- 'PaleTurquoise4': np.array([0.40, 0.55, 0.55]),
362
- 'CadetBlue1': np.array([0.60, 0.96, 1.00]),
363
- 'CadetBlue2': np.array([0.56, 0.90, 0.93]),
364
- 'CadetBlue3': np.array([0.48, 0.77, 0.80]),
365
- 'CadetBlue4': np.array([0.33, 0.53, 0.55]),
366
- 'turquoise1': np.array([0.00, 0.96, 1.00]),
367
- 'turquoise2': np.array([0.00, 0.90, 0.93]),
368
- 'turquoise3': np.array([0.00, 0.77, 0.80]),
369
- 'turquoise4': np.array([0.00, 0.53, 0.55]),
370
- 'cyan1': np.array([0.00, 1.00, 1.00]),
371
- 'cyan2': np.array([0.00, 0.93, 0.93]),
372
- 'cyan3': np.array([0.00, 0.80, 0.80]),
373
- 'cyan4': np.array([0.00, 0.55, 0.55]),
374
- 'DarkSlateGray1': np.array([0.59, 1.00, 1.00]),
375
- 'DarkSlateGray2': np.array([0.55, 0.93, 0.93]),
376
- 'DarkSlateGray3': np.array([0.47, 0.80, 0.80]),
377
- 'DarkSlateGray4': np.array([0.32, 0.55, 0.55]),
378
- 'aquamarine1': np.array([0.50, 1.00, 0.83]),
379
- 'aquamarine2': np.array([0.46, 0.93, 0.78]),
380
- 'aquamarine3': np.array([0.40, 0.80, 0.67]),
381
- 'aquamarine4': np.array([0.27, 0.55, 0.45]),
382
- 'DarkSeaGreen1': np.array([0.76, 1.00, 0.76]),
383
- 'DarkSeaGreen2': np.array([0.71, 0.93, 0.71]),
384
- 'DarkSeaGreen3': np.array([0.61, 0.80, 0.61]),
385
- 'DarkSeaGreen4': np.array([0.41, 0.55, 0.41]),
386
- 'SeaGreen1': np.array([0.33, 1.00, 0.62]),
387
- 'SeaGreen2': np.array([0.31, 0.93, 0.58]),
388
- 'SeaGreen3': np.array([0.26, 0.80, 0.50]),
389
- 'SeaGreen4': np.array([0.18, 0.55, 0.34]),
390
- 'PaleGreen1': np.array([0.60, 1.00, 0.60]),
391
- 'PaleGreen2': np.array([0.56, 0.93, 0.56]),
392
- 'PaleGreen3': np.array([0.49, 0.80, 0.49]),
393
- 'PaleGreen4': np.array([0.33, 0.55, 0.33]),
394
- 'SpringGreen1': np.array([0.00, 1.00, 0.50]),
395
- 'SpringGreen2': np.array([0.00, 0.93, 0.46]),
396
- 'SpringGreen3': np.array([0.00, 0.80, 0.40]),
397
- 'SpringGreen4': np.array([0.00, 0.55, 0.27]),
398
- 'green1': np.array([0.00, 1.00, 0.00]),
399
- 'green2': np.array([0.00, 0.93, 0.00]),
400
- 'green3': np.array([0.00, 0.80, 0.00]),
401
- 'green4': np.array([0.00, 0.55, 0.00]),
402
- 'chartreuse1': np.array([0.50, 1.00, 0.00]),
403
- 'chartreuse2': np.array([0.46, 0.93, 0.00]),
404
- 'chartreuse3': np.array([0.40, 0.80, 0.00]),
405
- 'chartreuse4': np.array([0.27, 0.55, 0.00]),
406
- 'OliveDrab1': np.array([0.75, 1.00, 0.24]),
407
- 'OliveDrab2': np.array([0.70, 0.93, 0.23]),
408
- 'OliveDrab3': np.array([0.60, 0.80, 0.20]),
409
- 'OliveDrab4': np.array([0.41, 0.55, 0.13]),
410
- 'DarkOliveGreen1': np.array([0.79, 1.00, 0.44]),
411
- 'DarkOliveGreen2': np.array([0.74, 0.93, 0.41]),
412
- 'DarkOliveGreen3': np.array([0.64, 0.80, 0.35]),
413
- 'DarkOliveGreen4': np.array([0.43, 0.55, 0.24]),
414
- 'khaki1': np.array([1.00, 0.96, 0.56]),
415
- 'khaki2': np.array([0.93, 0.90, 0.52]),
416
- 'khaki3': np.array([0.80, 0.78, 0.45]),
417
- 'khaki4': np.array([0.55, 0.53, 0.31]),
418
- 'LightGoldenrod1': np.array([1.00, 0.93, 0.55]),
419
- 'LightGoldenrod2': np.array([0.93, 0.86, 0.51]),
420
- 'LightGoldenrod3': np.array([0.80, 0.75, 0.44]),
421
- 'LightGoldenrod4': np.array([0.55, 0.51, 0.30]),
422
- 'LightYellow1': np.array([1.00, 1.00, 0.88]),
423
- 'LightYellow2': np.array([0.93, 0.93, 0.82]),
424
- 'LightYellow3': np.array([0.80, 0.80, 0.71]),
425
- 'LightYellow4': np.array([0.55, 0.55, 0.48]),
426
- 'yellow1': np.array([1.00, 1.00, 0.00]),
427
- 'yellow2': np.array([0.93, 0.93, 0.00]),
428
- 'yellow3': np.array([0.80, 0.80, 0.00]),
429
- 'yellow4': np.array([0.55, 0.55, 0.00]),
430
- 'gold1': np.array([1.00, 0.84, 0.00]),
431
- 'gold2': np.array([0.93, 0.79, 0.00]),
432
- 'gold3': np.array([0.80, 0.68, 0.00]),
433
- 'gold4': np.array([0.55, 0.46, 0.00]),
434
- 'goldenrod1': np.array([1.00, 0.76, 0.15]),
435
- 'goldenrod2': np.array([0.93, 0.71, 0.13]),
436
- 'goldenrod3': np.array([0.80, 0.61, 0.11]),
437
- 'goldenrod4': np.array([0.55, 0.41, 0.08]),
438
- 'DarkGoldenrod1': np.array([1.00, 0.73, 0.06]),
439
- 'DarkGoldenrod2': np.array([0.93, 0.68, 0.05]),
440
- 'DarkGoldenrod3': np.array([0.80, 0.58, 0.05]),
441
- 'DarkGoldenrod4': np.array([0.55, 0.40, 0.03]),
442
- 'RosyBrown1': np.array([1.00, 0.76, 0.76]),
443
- 'RosyBrown2': np.array([0.93, 0.71, 0.71]),
444
- 'RosyBrown3': np.array([0.80, 0.61, 0.61]),
445
- 'RosyBrown4': np.array([0.55, 0.41, 0.41]),
446
- 'IndianRed1': np.array([1.00, 0.42, 0.42]),
447
- 'IndianRed2': np.array([0.93, 0.39, 0.39]),
448
- 'IndianRed3': np.array([0.80, 0.33, 0.33]),
449
- 'IndianRed4': np.array([0.55, 0.23, 0.23]),
450
- 'sienna1': np.array([1.00, 0.51, 0.28]),
451
- 'sienna2': np.array([0.93, 0.47, 0.26]),
452
- 'sienna3': np.array([0.80, 0.41, 0.22]),
453
- 'sienna4': np.array([0.55, 0.28, 0.15]),
454
- 'burlywood1': np.array([1.00, 0.83, 0.61]),
455
- 'burlywood2': np.array([0.93, 0.77, 0.57]),
456
- 'burlywood3': np.array([0.80, 0.67, 0.49]),
457
- 'burlywood4': np.array([0.55, 0.45, 0.33]),
458
- 'wheat1': np.array([1.00, 0.91, 0.73]),
459
- 'wheat2': np.array([0.93, 0.85, 0.68]),
460
- 'wheat3': np.array([0.80, 0.73, 0.59]),
461
- 'wheat4': np.array([0.55, 0.49, 0.40]),
462
- 'tan1': np.array([1.00, 0.65, 0.31]),
463
- 'tan2': np.array([0.93, 0.60, 0.29]),
464
- 'tan3': np.array([0.80, 0.52, 0.25]),
465
- 'tan4': np.array([0.55, 0.35, 0.17]),
466
- 'chocolate1': np.array([1.00, 0.50, 0.14]),
467
- 'chocolate2': np.array([0.93, 0.46, 0.13]),
468
- 'chocolate3': np.array([0.80, 0.40, 0.11]),
469
- 'chocolate4': np.array([0.55, 0.27, 0.07]),
470
- 'firebrick1': np.array([1.00, 0.19, 0.19]),
471
- 'firebrick2': np.array([0.93, 0.17, 0.17]),
472
- 'firebrick3': np.array([0.80, 0.15, 0.15]),
473
- 'firebrick4': np.array([0.55, 0.10, 0.10]),
474
- 'brown1': np.array([1.00, 0.25, 0.25]),
475
- 'brown2': np.array([0.93, 0.23, 0.23]),
476
- 'brown3': np.array([0.80, 0.20, 0.20]),
477
- 'brown4': np.array([0.55, 0.14, 0.14]),
478
- 'salmon1': np.array([1.00, 0.55, 0.41]),
479
- 'salmon2': np.array([0.93, 0.51, 0.38]),
480
- 'salmon3': np.array([0.80, 0.44, 0.33]),
481
- 'salmon4': np.array([0.55, 0.30, 0.22]),
482
- 'LightSalmon1': np.array([1.00, 0.63, 0.48]),
483
- 'LightSalmon2': np.array([0.93, 0.58, 0.45]),
484
- 'LightSalmon3': np.array([0.80, 0.51, 0.38]),
485
- 'LightSalmon4': np.array([0.55, 0.34, 0.26]),
486
- 'orange1': np.array([1.00, 0.65, 0.00]),
487
- 'orange2': np.array([0.93, 0.60, 0.00]),
488
- 'orange3': np.array([0.80, 0.52, 0.00]),
489
- 'orange4': np.array([0.55, 0.35, 0.00]),
490
- 'DarkOrange1': np.array([1.00, 0.50, 0.00]),
491
- 'DarkOrange2': np.array([0.93, 0.46, 0.00]),
492
- 'DarkOrange3': np.array([0.80, 0.40, 0.00]),
493
- 'DarkOrange4': np.array([0.55, 0.27, 0.00]),
494
- 'coral1': np.array([1.00, 0.45, 0.34]),
495
- 'coral2': np.array([0.93, 0.42, 0.31]),
496
- 'coral3': np.array([0.80, 0.36, 0.27]),
497
- 'coral4': np.array([0.55, 0.24, 0.18]),
498
- 'tomato1': np.array([1.00, 0.39, 0.28]),
499
- 'tomato2': np.array([0.93, 0.36, 0.26]),
500
- 'tomato3': np.array([0.80, 0.31, 0.22]),
501
- 'tomato4': np.array([0.55, 0.21, 0.15]),
502
- 'OrangeRed1': np.array([1.00, 0.27, 0.00]),
503
- 'OrangeRed2': np.array([0.93, 0.25, 0.00]),
504
- 'OrangeRed3': np.array([0.80, 0.22, 0.00]),
505
- 'OrangeRed4': np.array([0.55, 0.15, 0.00]),
506
- 'red1': np.array([1.00, 0.00, 0.00]),
507
- 'red2': np.array([0.93, 0.00, 0.00]),
508
- 'red3': np.array([0.80, 0.00, 0.00]),
509
- 'red4': np.array([0.55, 0.00, 0.00]),
510
- 'DeepPink1': np.array([1.00, 0.08, 0.58]),
511
- 'DeepPink2': np.array([0.93, 0.07, 0.54]),
512
- 'DeepPink3': np.array([0.80, 0.06, 0.46]),
513
- 'DeepPink4': np.array([0.55, 0.04, 0.31]),
514
- 'HotPink1': np.array([1.00, 0.43, 0.71]),
515
- 'HotPink2': np.array([0.93, 0.42, 0.65]),
516
- 'HotPink3': np.array([0.80, 0.38, 0.56]),
517
- 'HotPink4': np.array([0.55, 0.23, 0.38]),
518
- 'pink1': np.array([1.00, 0.71, 0.77]),
519
- 'pink2': np.array([0.93, 0.66, 0.72]),
520
- 'pink3': np.array([0.80, 0.57, 0.62]),
521
- 'pink4': np.array([0.55, 0.39, 0.42]),
522
- 'LightPink1': np.array([1.00, 0.68, 0.73]),
523
- 'LightPink2': np.array([0.93, 0.64, 0.68]),
524
- 'LightPink3': np.array([0.80, 0.55, 0.58]),
525
- 'LightPink4': np.array([0.55, 0.37, 0.40]),
526
- 'PaleVioletRed1': np.array([1.00, 0.51, 0.67]),
527
- 'PaleVioletRed2': np.array([0.93, 0.47, 0.62]),
528
- 'PaleVioletRed3': np.array([0.80, 0.41, 0.54]),
529
- 'PaleVioletRed4': np.array([0.55, 0.28, 0.36]),
530
- 'maroon1': np.array([1.00, 0.20, 0.70]),
531
- 'maroon2': np.array([0.93, 0.19, 0.65]),
532
- 'maroon3': np.array([0.80, 0.16, 0.56]),
533
- 'maroon4': np.array([0.55, 0.11, 0.38]),
534
- 'VioletRed1': np.array([1.00, 0.24, 0.59]),
535
- 'VioletRed2': np.array([0.93, 0.23, 0.55]),
536
- 'VioletRed3': np.array([0.80, 0.20, 0.47]),
537
- 'VioletRed4': np.array([0.55, 0.13, 0.32]),
538
- 'magenta1': np.array([1.00, 0.00, 1.00]),
539
- 'magenta2': np.array([0.93, 0.00, 0.93]),
540
- 'magenta3': np.array([0.80, 0.00, 0.80]),
541
- 'magenta4': np.array([0.55, 0.00, 0.55]),
542
- 'orchid1': np.array([1.00, 0.51, 0.98]),
543
- 'orchid2': np.array([0.93, 0.48, 0.91]),
544
- 'orchid3': np.array([0.80, 0.41, 0.79]),
545
- 'orchid4': np.array([0.55, 0.28, 0.54]),
546
- 'plum1': np.array([1.00, 0.73, 1.00]),
547
- 'plum2': np.array([0.93, 0.68, 0.93]),
548
- 'plum3': np.array([0.80, 0.59, 0.80]),
549
- 'plum4': np.array([0.55, 0.40, 0.55]),
550
- 'MediumOrchid1': np.array([0.88, 0.40, 1.00]),
551
- 'MediumOrchid2': np.array([0.82, 0.37, 0.93]),
552
- 'MediumOrchid3': np.array([0.71, 0.32, 0.80]),
553
- 'MediumOrchid4': np.array([0.48, 0.22, 0.55]),
554
- 'DarkOrchid1': np.array([0.75, 0.24, 1.00]),
555
- 'DarkOrchid2': np.array([0.70, 0.23, 0.93]),
556
- 'DarkOrchid3': np.array([0.60, 0.20, 0.80]),
557
- 'DarkOrchid4': np.array([0.41, 0.13, 0.55]),
558
- 'purple1': np.array([0.61, 0.19, 1.00]),
559
- 'purple2': np.array([0.57, 0.17, 0.93]),
560
- 'purple3': np.array([0.49, 0.15, 0.80]),
561
- 'purple4': np.array([0.33, 0.10, 0.55]),
562
- 'MediumPurple1': np.array([0.67, 0.51, 1.00]),
563
- 'MediumPurple2': np.array([0.62, 0.47, 0.93]),
564
- 'MediumPurple3': np.array([0.54, 0.41, 0.80]),
565
- 'MediumPurple4': np.array([0.36, 0.28, 0.55]),
566
- 'thistle1': np.array([1.00, 0.88, 1.00]),
567
- 'thistle2': np.array([0.93, 0.82, 0.93]),
568
- 'thistle3': np.array([0.80, 0.71, 0.80]),
569
- 'thistle4': np.array([0.55, 0.48, 0.55]),
570
- 'gray0': np.array([0.00, 0.00, 0.00]),
571
- 'grey0': np.array([0.00, 0.00, 0.00]),
572
- 'gray1': np.array([0.01, 0.01, 0.01]),
573
- 'grey1': np.array([0.01, 0.01, 0.01]),
574
- 'gray2': np.array([0.02, 0.02, 0.02]),
575
- 'grey2': np.array([0.02, 0.02, 0.02]),
576
- 'gray3': np.array([0.03, 0.03, 0.03]),
577
- 'grey3': np.array([0.03, 0.03, 0.03]),
578
- 'gray4': np.array([0.04, 0.04, 0.04]),
579
- 'grey4': np.array([0.04, 0.04, 0.04]),
580
- 'gray5': np.array([0.05, 0.05, 0.05]),
581
- 'grey5': np.array([0.05, 0.05, 0.05]),
582
- 'gray6': np.array([0.06, 0.06, 0.06]),
583
- 'grey6': np.array([0.06, 0.06, 0.06]),
584
- 'gray7': np.array([0.07, 0.07, 0.07]),
585
- 'grey7': np.array([0.07, 0.07, 0.07]),
586
- 'gray8': np.array([0.08, 0.08, 0.08]),
587
- 'grey8': np.array([0.08, 0.08, 0.08]),
588
- 'gray9': np.array([0.09, 0.09, 0.09]),
589
- 'grey9': np.array([0.09, 0.09, 0.09]),
590
- 'gray10': np.array([0.10, 0.10, 0.10]),
591
- 'grey10': np.array([0.10, 0.10, 0.10]),
592
- 'gray11': np.array([0.11, 0.11, 0.11]),
593
- 'grey11': np.array([0.11, 0.11, 0.11]),
594
- 'gray12': np.array([0.12, 0.12, 0.12]),
595
- 'grey12': np.array([0.12, 0.12, 0.12]),
596
- 'gray13': np.array([0.13, 0.13, 0.13]),
597
- 'grey13': np.array([0.13, 0.13, 0.13]),
598
- 'gray14': np.array([0.14, 0.14, 0.14]),
599
- 'grey14': np.array([0.14, 0.14, 0.14]),
600
- 'gray15': np.array([0.15, 0.15, 0.15]),
601
- 'grey15': np.array([0.15, 0.15, 0.15]),
602
- 'gray16': np.array([0.16, 0.16, 0.16]),
603
- 'grey16': np.array([0.16, 0.16, 0.16]),
604
- 'gray17': np.array([0.17, 0.17, 0.17]),
605
- 'grey17': np.array([0.17, 0.17, 0.17]),
606
- 'gray18': np.array([0.18, 0.18, 0.18]),
607
- 'grey18': np.array([0.18, 0.18, 0.18]),
608
- 'gray19': np.array([0.19, 0.19, 0.19]),
609
- 'grey19': np.array([0.19, 0.19, 0.19]),
610
- 'gray20': np.array([0.20, 0.20, 0.20]),
611
- 'grey20': np.array([0.20, 0.20, 0.20]),
612
- 'gray21': np.array([0.21, 0.21, 0.21]),
613
- 'grey21': np.array([0.21, 0.21, 0.21]),
614
- 'gray22': np.array([0.22, 0.22, 0.22]),
615
- 'grey22': np.array([0.22, 0.22, 0.22]),
616
- 'gray23': np.array([0.23, 0.23, 0.23]),
617
- 'grey23': np.array([0.23, 0.23, 0.23]),
618
- 'gray24': np.array([0.24, 0.24, 0.24]),
619
- 'grey24': np.array([0.24, 0.24, 0.24]),
620
- 'gray25': np.array([0.25, 0.25, 0.25]),
621
- 'grey25': np.array([0.25, 0.25, 0.25]),
622
- 'gray26': np.array([0.26, 0.26, 0.26]),
623
- 'grey26': np.array([0.26, 0.26, 0.26]),
624
- 'gray27': np.array([0.27, 0.27, 0.27]),
625
- 'grey27': np.array([0.27, 0.27, 0.27]),
626
- 'gray28': np.array([0.28, 0.28, 0.28]),
627
- 'grey28': np.array([0.28, 0.28, 0.28]),
628
- 'gray29': np.array([0.29, 0.29, 0.29]),
629
- 'grey29': np.array([0.29, 0.29, 0.29]),
630
- 'gray30': np.array([0.30, 0.30, 0.30]),
631
- 'grey30': np.array([0.30, 0.30, 0.30]),
632
- 'gray31': np.array([0.31, 0.31, 0.31]),
633
- 'grey31': np.array([0.31, 0.31, 0.31]),
634
- 'gray32': np.array([0.32, 0.32, 0.32]),
635
- 'grey32': np.array([0.32, 0.32, 0.32]),
636
- 'gray33': np.array([0.33, 0.33, 0.33]),
637
- 'grey33': np.array([0.33, 0.33, 0.33]),
638
- 'gray34': np.array([0.34, 0.34, 0.34]),
639
- 'grey34': np.array([0.34, 0.34, 0.34]),
640
- 'gray35': np.array([0.35, 0.35, 0.35]),
641
- 'grey35': np.array([0.35, 0.35, 0.35]),
642
- 'gray36': np.array([0.36, 0.36, 0.36]),
643
- 'grey36': np.array([0.36, 0.36, 0.36]),
644
- 'gray37': np.array([0.37, 0.37, 0.37]),
645
- 'grey37': np.array([0.37, 0.37, 0.37]),
646
- 'gray38': np.array([0.38, 0.38, 0.38]),
647
- 'grey38': np.array([0.38, 0.38, 0.38]),
648
- 'gray39': np.array([0.39, 0.39, 0.39]),
649
- 'grey39': np.array([0.39, 0.39, 0.39]),
650
- 'gray40': np.array([0.40, 0.40, 0.40]),
651
- 'grey40': np.array([0.40, 0.40, 0.40]),
652
- 'gray41': np.array([0.41, 0.41, 0.41]),
653
- 'grey41': np.array([0.41, 0.41, 0.41]),
654
- 'gray42': np.array([0.42, 0.42, 0.42]),
655
- 'grey42': np.array([0.42, 0.42, 0.42]),
656
- 'gray43': np.array([0.43, 0.43, 0.43]),
657
- 'grey43': np.array([0.43, 0.43, 0.43]),
658
- 'gray44': np.array([0.44, 0.44, 0.44]),
659
- 'grey44': np.array([0.44, 0.44, 0.44]),
660
- 'gray45': np.array([0.45, 0.45, 0.45]),
661
- 'grey45': np.array([0.45, 0.45, 0.45]),
662
- 'gray46': np.array([0.46, 0.46, 0.46]),
663
- 'grey46': np.array([0.46, 0.46, 0.46]),
664
- 'gray47': np.array([0.47, 0.47, 0.47]),
665
- 'grey47': np.array([0.47, 0.47, 0.47]),
666
- 'gray48': np.array([0.48, 0.48, 0.48]),
667
- 'grey48': np.array([0.48, 0.48, 0.48]),
668
- 'gray49': np.array([0.49, 0.49, 0.49]),
669
- 'grey49': np.array([0.49, 0.49, 0.49]),
670
- 'gray50': np.array([0.50, 0.50, 0.50]),
671
- 'grey50': np.array([0.50, 0.50, 0.50]),
672
- 'gray51': np.array([0.51, 0.51, 0.51]),
673
- 'grey51': np.array([0.51, 0.51, 0.51]),
674
- 'gray52': np.array([0.52, 0.52, 0.52]),
675
- 'grey52': np.array([0.52, 0.52, 0.52]),
676
- 'gray53': np.array([0.53, 0.53, 0.53]),
677
- 'grey53': np.array([0.53, 0.53, 0.53]),
678
- 'gray54': np.array([0.54, 0.54, 0.54]),
679
- 'grey54': np.array([0.54, 0.54, 0.54]),
680
- 'gray55': np.array([0.55, 0.55, 0.55]),
681
- 'grey55': np.array([0.55, 0.55, 0.55]),
682
- 'gray56': np.array([0.56, 0.56, 0.56]),
683
- 'grey56': np.array([0.56, 0.56, 0.56]),
684
- 'gray57': np.array([0.57, 0.57, 0.57]),
685
- 'grey57': np.array([0.57, 0.57, 0.57]),
686
- 'gray58': np.array([0.58, 0.58, 0.58]),
687
- 'grey58': np.array([0.58, 0.58, 0.58]),
688
- 'gray59': np.array([0.59, 0.59, 0.59]),
689
- 'grey59': np.array([0.59, 0.59, 0.59]),
690
- 'gray60': np.array([0.60, 0.60, 0.60]),
691
- 'grey60': np.array([0.60, 0.60, 0.60]),
692
- 'gray61': np.array([0.61, 0.61, 0.61]),
693
- 'grey61': np.array([0.61, 0.61, 0.61]),
694
- 'gray62': np.array([0.62, 0.62, 0.62]),
695
- 'grey62': np.array([0.62, 0.62, 0.62]),
696
- 'gray63': np.array([0.63, 0.63, 0.63]),
697
- 'grey63': np.array([0.63, 0.63, 0.63]),
698
- 'gray64': np.array([0.64, 0.64, 0.64]),
699
- 'grey64': np.array([0.64, 0.64, 0.64]),
700
- 'gray65': np.array([0.65, 0.65, 0.65]),
701
- 'grey65': np.array([0.65, 0.65, 0.65]),
702
- 'gray66': np.array([0.66, 0.66, 0.66]),
703
- 'grey66': np.array([0.66, 0.66, 0.66]),
704
- 'gray67': np.array([0.67, 0.67, 0.67]),
705
- 'grey67': np.array([0.67, 0.67, 0.67]),
706
- 'gray68': np.array([0.68, 0.68, 0.68]),
707
- 'grey68': np.array([0.68, 0.68, 0.68]),
708
- 'gray69': np.array([0.69, 0.69, 0.69]),
709
- 'grey69': np.array([0.69, 0.69, 0.69]),
710
- 'gray70': np.array([0.70, 0.70, 0.70]),
711
- 'grey70': np.array([0.70, 0.70, 0.70]),
712
- 'gray71': np.array([0.71, 0.71, 0.71]),
713
- 'grey71': np.array([0.71, 0.71, 0.71]),
714
- 'gray72': np.array([0.72, 0.72, 0.72]),
715
- 'grey72': np.array([0.72, 0.72, 0.72]),
716
- 'gray73': np.array([0.73, 0.73, 0.73]),
717
- 'grey73': np.array([0.73, 0.73, 0.73]),
718
- 'gray74': np.array([0.74, 0.74, 0.74]),
719
- 'grey74': np.array([0.74, 0.74, 0.74]),
720
- 'gray75': np.array([0.75, 0.75, 0.75]),
721
- 'grey75': np.array([0.75, 0.75, 0.75]),
722
- 'gray76': np.array([0.76, 0.76, 0.76]),
723
- 'grey76': np.array([0.76, 0.76, 0.76]),
724
- 'gray77': np.array([0.77, 0.77, 0.77]),
725
- 'grey77': np.array([0.77, 0.77, 0.77]),
726
- 'gray78': np.array([0.78, 0.78, 0.78]),
727
- 'grey78': np.array([0.78, 0.78, 0.78]),
728
- 'gray79': np.array([0.79, 0.79, 0.79]),
729
- 'grey79': np.array([0.79, 0.79, 0.79]),
730
- 'gray80': np.array([0.80, 0.80, 0.80]),
731
- 'grey80': np.array([0.80, 0.80, 0.80]),
732
- 'gray81': np.array([0.81, 0.81, 0.81]),
733
- 'grey81': np.array([0.81, 0.81, 0.81]),
734
- 'gray82': np.array([0.82, 0.82, 0.82]),
735
- 'grey82': np.array([0.82, 0.82, 0.82]),
736
- 'gray83': np.array([0.83, 0.83, 0.83]),
737
- 'grey83': np.array([0.83, 0.83, 0.83]),
738
- 'gray84': np.array([0.84, 0.84, 0.84]),
739
- 'grey84': np.array([0.84, 0.84, 0.84]),
740
- 'gray85': np.array([0.85, 0.85, 0.85]),
741
- 'grey85': np.array([0.85, 0.85, 0.85]),
742
- 'gray86': np.array([0.86, 0.86, 0.86]),
743
- 'grey86': np.array([0.86, 0.86, 0.86]),
744
- 'gray87': np.array([0.87, 0.87, 0.87]),
745
- 'grey87': np.array([0.87, 0.87, 0.87]),
746
- 'gray88': np.array([0.88, 0.88, 0.88]),
747
- 'grey88': np.array([0.88, 0.88, 0.88]),
748
- 'gray89': np.array([0.89, 0.89, 0.89]),
749
- 'grey89': np.array([0.89, 0.89, 0.89]),
750
- 'gray90': np.array([0.90, 0.90, 0.90]),
751
- 'grey90': np.array([0.90, 0.90, 0.90]),
752
- 'gray91': np.array([0.91, 0.91, 0.91]),
753
- 'grey91': np.array([0.91, 0.91, 0.91]),
754
- 'gray92': np.array([0.92, 0.92, 0.92]),
755
- 'grey92': np.array([0.92, 0.92, 0.92]),
756
- 'gray93': np.array([0.93, 0.93, 0.93]),
757
- 'grey93': np.array([0.93, 0.93, 0.93]),
758
- 'gray94': np.array([0.94, 0.94, 0.94]),
759
- 'grey94': np.array([0.94, 0.94, 0.94]),
760
- 'gray95': np.array([0.95, 0.95, 0.95]),
761
- 'grey95': np.array([0.95, 0.95, 0.95]),
762
- 'gray96': np.array([0.96, 0.96, 0.96]),
763
- 'grey96': np.array([0.96, 0.96, 0.96]),
764
- 'gray97': np.array([0.97, 0.97, 0.97]),
765
- 'grey97': np.array([0.97, 0.97, 0.97]),
766
- 'gray98': np.array([0.98, 0.98, 0.98]),
767
- 'grey98': np.array([0.98, 0.98, 0.98]),
768
- 'gray99': np.array([0.99, 0.99, 0.99]),
769
- 'grey99': np.array([0.99, 0.99, 0.99]),
770
- 'gray100': np.array([1.00, 1.00, 1.00]),
771
- 'grey100': np.array([1.00, 1.00, 1.00]),
772
- 'dark grey': np.array([0.66, 0.66, 0.66]),
773
- 'DarkGrey': np.array([0.66, 0.66, 0.66]),
774
- 'dark gray': np.array([0.66, 0.66, 0.66]),
775
- 'DarkGray': np.array([0.66, 0.66, 0.66]),
776
- 'dark blue': np.array([0.00, 0.00, 0.55]),
777
- 'DarkBlue': np.array([0.00, 0.00, 0.55]),
778
- 'dark cyan': np.array([0.00, 0.55, 0.55]),
779
- 'DarkCyan': np.array([0.00, 0.55, 0.55]),
780
- 'dark magenta': np.array([0.55, 0.00, 0.55]),
781
- 'DarkMagenta': np.array([0.55, 0.00, 0.55]),
782
- 'dark red': np.array([0.55, 0.00, 0.00]),
783
- 'DarkRed': np.array([0.55, 0.00, 0.00]),
784
- 'light green': np.array([0.56, 0.93, 0.56]),
785
- 'LightGreen': np.array([0.56, 0.93, 0.56])
786
- }
787
-
788
-
789
- if __name__ == '__main__':
790
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/errors.py DELETED
@@ -1,15 +0,0 @@
1
- # Copyright (c) 2017 Max Planck Society. All rights reserved.
2
-
3
- """
4
- Error heirarchy for Mesh class
5
- """
6
-
7
-
8
- class MeshError(Exception):
9
- """Base error class for Mesh-related errors"""
10
- pass
11
-
12
-
13
- class SerializationError(MeshError):
14
- """Mesh reading or writing errors"""
15
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/fonts.py DELETED
@@ -1,87 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
- # Copyright (c) 2013 Max Planck Society. All rights reserved.
4
-
5
- import os
6
- import numpy as np
7
- from OpenGL.GL import glPixelStorei, \
8
- glGenTextures, \
9
- glBindTexture, \
10
- glGenerateMipmap, \
11
- glHint, \
12
- glTexImage2D
13
- from OpenGL.GL import GL_UNPACK_ALIGNMENT, \
14
- GL_TEXTURE_2D, \
15
- GL_RGB, \
16
- GL_BGR, \
17
- GL_GENERATE_MIPMAP_HINT, \
18
- GL_NICEST, \
19
- GL_UNSIGNED_BYTE
20
-
21
-
22
- def get_image_with_text(text, fgcolor, bgcolor):
23
- if not hasattr(get_image_with_text, 'cache'):
24
- get_image_with_text.cache = {}
25
-
26
- import zlib
27
- uid = str(zlib.crc32(text)) + str(zlib.crc32(np.array(fgcolor))) + str(zlib.crc32(np.array(bgcolor)))
28
- if uid not in get_image_with_text.cache:
29
- from PIL import ImageFont
30
- from PIL import Image
31
- from PIL import ImageDraw
32
-
33
- font = ImageFont.truetype("/Library/Fonts/Courier New.ttf", 30)
34
-
35
- imsize = (256, 256)
36
-
37
- bgarray = np.asarray(np.zeros((imsize[0], imsize[1], 3)), np.uint8)
38
- bgarray[:, :, 0] += bgcolor[0]
39
- bgarray[:, :, 1] += bgcolor[1]
40
- bgarray[:, :, 2] += bgcolor[2]
41
- img = Image.fromarray(bgarray)
42
- draw = ImageDraw.Draw(img)
43
- w, h = draw.textsize(text, font=font)
44
- text_pos = ((imsize[0] - w) / 2, (imsize[1] - h) / 2)
45
- draw.text(text_pos, text, fill=fgcolor, font=font)
46
- get_image_with_text.cache[uid] = np.array(img.getdata()).reshape(img.size[0], img.size[1], 3) * 255
47
- return get_image_with_text.cache[uid]
48
-
49
-
50
- def get_textureid_with_text(text, fgcolor, bgcolor):
51
- if not hasattr(get_textureid_with_text, 'cache'):
52
- get_textureid_with_text.cache = {}
53
-
54
- import zlib
55
- uid = str(zlib.crc32(text)) + str(zlib.crc32(np.array(fgcolor))) + str(zlib.crc32(np.array(bgcolor)))
56
- if uid not in get_textureid_with_text.cache:
57
- from PIL import ImageFont
58
- from PIL import Image
59
- from PIL import ImageDraw
60
-
61
- font = ImageFont.truetype(os.path.join(os.path.dirname(__file__),
62
- "ressources",
63
- "Arial.ttf"),
64
- 100)
65
-
66
- imsize = (128, 128)
67
-
68
- bgarray = np.asarray(np.zeros((imsize[0], imsize[1], 3)), np.uint8)
69
- bgarray[:, :, 0] += bgcolor[0]
70
- bgarray[:, :, 1] += bgcolor[1]
71
- bgarray[:, :, 2] += bgcolor[2]
72
- img = Image.fromarray(bgarray)
73
- draw = ImageDraw.Draw(img)
74
- w, h = draw.textsize(text, font=font)
75
- text_pos = ((imsize[0] - w) / 2, (imsize[1] - h) / 2)
76
- draw.text(text_pos, text, fill=tuple(np.asarray(fgcolor, np.uint8)), font=font)
77
- texture_data = np.asarray(np.array(img.getdata()).reshape(img.size[0], img.size[1], 3) * 255, np.uint8)
78
-
79
- textureID = glGenTextures(1)
80
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
81
- glBindTexture(GL_TEXTURE_2D, textureID)
82
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_data.shape[1], texture_data.shape[0], 0, GL_BGR, GL_UNSIGNED_BYTE, texture_data.flatten())
83
- glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST) # must be GL_FASTEST, GL_NICEST or GL_DONT_CARE
84
- glGenerateMipmap(GL_TEXTURE_2D)
85
- get_textureid_with_text.cache[uid] = textureID
86
-
87
- return get_textureid_with_text.cache[uid]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/geometry/__init__.py DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2016 Max Planck Society. All rights reserved.
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/geometry/barycentric_coordinates_of_projection.py DELETED
@@ -1,49 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2013 Max Planck Society. All rights reserved.
5
-
6
- from numpy import cross, sum, isscalar, spacing, vstack
7
-
8
-
9
- def barycentric_coordinates_of_projection(p, q, u, v):
10
- """Given a point, gives projected coords of that point to a triangle
11
- in barycentric coordinates.
12
-
13
- See
14
-
15
- **Heidrich**, Computing the Barycentric Coordinates of a Projected Point, JGT 05
16
- at http://www.cs.ubc.ca/~heidrich/Papers/JGT.05.pdf
17
-
18
- :param p: point to project
19
- :param q: a vertex of the triangle to project into
20
- :param u,v: edges of the the triangle such that it has vertices ``q``, ``q+u``, ``q+v``
21
-
22
- :returns: barycentric coordinates of ``p``'s projection in triangle defined by ``q``, ``u``, ``v``
23
- vectorized so ``p``, ``q``, ``u``, ``v`` can all be ``3xN``
24
- """
25
-
26
- p = p.T
27
- q = q.T
28
- u = u.T
29
- v = v.T
30
-
31
- n = cross(u, v, axis=0)
32
- s = sum(n * n, axis=0)
33
-
34
- # If the triangle edges are collinear, cross-product is zero,
35
- # which makes "s" 0, which gives us divide by zero. So we
36
- # make the arbitrary choice to set s to epsv (=numpy.spacing(1)),
37
- # the closest thing to zero
38
- if isscalar(s):
39
- s = s if s else spacing(1)
40
- else:
41
- s[s == 0] = spacing(1)
42
-
43
- oneOver4ASquared = 1.0 / s
44
- w = p - q
45
- b2 = sum(cross(u, w, axis=0) * n, axis=0) * oneOver4ASquared
46
- b1 = sum(cross(w, v, axis=0) * n, axis=0) * oneOver4ASquared
47
- b = vstack((1 - b1 - b2, b1, b2))
48
-
49
- return b.T
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/geometry/cross_product.py DELETED
@@ -1,37 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2012 Max Planck Society. All rights reserved.
5
- # Created by Matthew Loper on 2012-07-20.
6
-
7
- import numpy as np
8
-
9
-
10
- def CrossProduct(a, b):
11
- """Computes the cross product of 2 vectors"""
12
- a = a.reshape(-1, 3)
13
- b = b.reshape(-1, 3)
14
-
15
- a1 = a[:, 0]
16
- a2 = a[:, 1]
17
- a3 = a[:, 2]
18
-
19
- Ax = np.zeros((len(a1), 3, 3))
20
- Ax[:, 0, 1] = -a3
21
- Ax[:, 0, 2] = +a2
22
- Ax[:, 1, 0] = +a3
23
- Ax[:, 1, 2] = -a1
24
- Ax[:, 2, 0] = -a2
25
- Ax[:, 2, 1] = +a1
26
-
27
- return _call_einsum_matvec(Ax, b)
28
-
29
-
30
- def _call_einsum_matvec(m, righthand):
31
- r = righthand.reshape(m.shape[0], 3)
32
- return np.einsum('ijk,ik->ij', m, r).flatten()
33
-
34
-
35
- def _call_einsum_matmat(m, righthand):
36
- r = righthand.reshape(m.shape[0], 3, -1)
37
- return np.einsum('ijk,ikm->ijm', m, r).reshape(-1, r.shape[2])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/geometry/rodrigues.py DELETED
@@ -1,125 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2012 Max Planck Society. All rights reserved.
5
- # Created by Matthew Loper on 2012-07-22.
6
-
7
- import numpy as np
8
-
9
-
10
- def rodrigues(r, calculate_jacobian=True):
11
- """Computes the Rodrigues transform and its derivative
12
-
13
- :param r: either a 3-vector representing the rotation parameter, or a full rotation matrix
14
- :param calculate_jacobian: indicates if the Jacobian of the transform is also required
15
- :returns: If `calculate_jacobian` is `True`, the Jacobian is given as the second element of the returned tuple.
16
- """
17
-
18
- r = np.array(r, dtype=np.double)
19
- eps = np.finfo(np.double).eps
20
-
21
- if np.all(r.shape == (3, 1)) or np.all(r.shape == (1, 3)) or np.all(r.shape == (3,)):
22
- r = r.flatten()
23
- theta = np.linalg.norm(r)
24
- if theta < eps:
25
- r_out = np.eye(3)
26
- if calculate_jacobian:
27
- jac = np.zeros((3, 9))
28
- jac[0, 5] = jac[1, 6] = jac[2, 1] = -1
29
- jac[0, 7] = jac[1, 2] = jac[2, 3] = 1
30
-
31
- else:
32
- c = np.cos(theta)
33
- s = np.sin(theta)
34
- c1 = 1. - c
35
- itheta = 1.0 if theta == 0.0 else 1.0 / theta
36
- r *= itheta
37
- I = np.eye(3)
38
- rrt = np.array([r * r[0], r * r[1], r * r[2]])
39
- _r_x_ = np.array([[0, -r[2], r[1]], [r[2], 0, -r[0]], [-r[1], r[0], 0]])
40
- r_out = c * I + c1 * rrt + s * _r_x_
41
- if calculate_jacobian:
42
- drrt = np.array([[r[0] + r[0], r[1], r[2], r[1], 0, 0, r[2], 0, 0],
43
- [0, r[0], 0, r[0], r[1] + r[1], r[2], 0, r[2], 0],
44
- [0, 0, r[0], 0, 0, r[1], r[0], r[1], r[2] + r[2]]])
45
- d_r_x_ = np.array([[0, 0, 0, 0, 0, -1, 0, 1, 0],
46
- [0, 0, 1, 0, 0, 0, -1, 0, 0],
47
- [0, -1, 0, 1, 0, 0, 0, 0, 0]])
48
- I = np.array([I.flatten(), I.flatten(), I.flatten()])
49
- ri = np.array([[r[0]], [r[1]], [r[2]]])
50
- a0 = -s * ri
51
- a1 = (s - 2 * c1 * itheta) * ri
52
- a2 = np.ones((3, 1)) * c1 * itheta
53
- a3 = (c - s * itheta) * ri
54
- a4 = np.ones((3, 1)) * s * itheta
55
- jac = a0 * I + a1 * rrt.flatten() + a2 * drrt + a3 * _r_x_.flatten() + a4 * d_r_x_
56
- elif np.all(r.shape == (3, 3)):
57
- u, d, v = np.linalg.svd(r)
58
- r = np.dot(u, v)
59
- rx = r[2, 1] - r[1, 2]
60
- ry = r[0, 2] - r[2, 0]
61
- rz = r[1, 0] - r[0, 1]
62
- s = np.linalg.norm(np.array([rx, ry, rz])) * np.sqrt(0.25)
63
- c = np.clip((np.sum(np.diag(r)) - 1) * 0.5, -1, 1)
64
- theta = np.arccos(c)
65
- if s < 1e-5:
66
- if c > 0:
67
- r_out = np.zeros((3, 1))
68
- else:
69
- rx, ry, rz = np.clip(np.sqrt((np.diag(r) + 1) * 0.5), 0, np.inf)
70
- if r[0, 1] < 0:
71
- ry = -ry
72
- if r[0, 2] < 0:
73
- rz = -rz
74
- if np.abs(rx) < np.abs(ry) and np.abs(rx) < np.abs(rz) and ((r[1, 2] > 0) != (ry * rz > 0)):
75
- rz = -rz
76
-
77
- r_out = np.array([[rx, ry, rz]]).T
78
- theta /= np.linalg.norm(r_out)
79
- r_out *= theta
80
- if calculate_jacobian:
81
- jac = np.zeros((9, 3))
82
- if c > 0:
83
- jac[1, 2] = jac[5, 0] = jac[6, 1] = -0.5
84
- jac[2, 1] = jac[3, 2] = jac[7, 0] = 0.5
85
- else:
86
- vth = 1.0 / (2.0 * s)
87
- if calculate_jacobian:
88
- dtheta_dtr = -1. / s
89
- dvth_dtheta = -vth * c / s
90
- d1 = 0.5 * dvth_dtheta * dtheta_dtr
91
- d2 = 0.5 * dtheta_dtr
92
- dvardR = np.array([
93
- [0, 0, 0, 0, 0, 1, 0, -1, 0],
94
- [0, 0, -1, 0, 0, 0, 1, 0, 0],
95
- [0, 1, 0, -1, 0, 0, 0, 0, 0],
96
- [d1, 0, 0, 0, d1, 0, 0, 0, d1],
97
- [d2, 0, 0, 0, d2, 0, 0, 0, d2]])
98
- dvar2dvar = np.array([
99
- [vth, 0, 0, rx, 0],
100
- [0, vth, 0, ry, 0],
101
- [0, 0, vth, rz, 0],
102
- [0, 0, 0, 0, 1]])
103
- domegadvar2 = np.array([
104
- [theta, 0, 0, rx * vth],
105
- [0, theta, 0, ry * vth],
106
- [0, 0, theta, rz * vth]])
107
- jac = np.dot(np.dot(domegadvar2, dvar2dvar), dvardR)
108
- for ii in range(3):
109
- jac[ii] = jac[ii].reshape((3, 3)).T.flatten()
110
- jac = jac.T
111
- vth *= theta
112
- r_out = np.array([[rx, ry, rz]]).T * vth
113
- else:
114
- raise Exception("rodrigues: input matrix must be 1x3, 3x1 or 3x3.")
115
- if calculate_jacobian:
116
- return r_out, jac
117
- else:
118
- return r_out
119
-
120
-
121
- def rodrigues2rotmat(r):
122
- # R = np.zeros((3, 3))
123
- r_skew = np.array([[0, -r[2], r[1]], [r[2], 0, -r[0]], [-r[1], r[0], 0]])
124
- theta = np.linalg.norm(r)
125
- return np.identity(3) + np.sin(theta) * r_skew + (1 - np.cos(theta)) * r_skew.dot(r_skew)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/geometry/tri_normals.py DELETED
@@ -1,72 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2012 Max Planck Society. All rights reserved.
5
- # Created by Matthew Loper on 2012-07-22.
6
-
7
-
8
- """
9
- tri_normals.py
10
-
11
- """
12
-
13
- from ..utils import col
14
- from .cross_product import CrossProduct
15
-
16
- import numpy as np
17
-
18
-
19
- def TriNormals(v, f):
20
- return NormalizedNx3(TriNormalsScaled(v, f))
21
-
22
-
23
- def TriNormalsScaled(v, f):
24
- return CrossProduct(TriEdges(v, f, 1, 0), TriEdges(v, f, 2, 0))
25
-
26
-
27
- def NormalizedNx3(v):
28
- ss = np.sum(v.reshape(-1, 3) ** 2, axis=1)
29
- ss[ss == 0] = 1
30
- s = np.sqrt(ss)
31
-
32
- return (v.reshape(-1, 3) / col(s)).flatten()
33
-
34
-
35
- def TriEdges(v, f, cplus, cminus):
36
- assert(cplus >= 0 and cplus <= 2 and cminus >= 0 and cminus <= 2)
37
- return _edges_for(v, f, cplus, cminus)
38
-
39
-
40
- def _edges_for(v, f, cplus, cminus):
41
- return (
42
- v.reshape(-1, 3)[f[:, cplus], :] -
43
- v.reshape(-1, 3)[f[:, cminus], :]).ravel()
44
-
45
-
46
- def TriToScaledNormal(x, tri):
47
-
48
- v = x.reshape(-1, 3)
49
-
50
- def v_xyz(iV):
51
- return v[tri[:, iV], :]
52
-
53
- return np.cross(v_xyz(1) - v_xyz(0), v_xyz(2) - v_xyz(0))
54
-
55
-
56
- def _bsxfun(oper, a, b):
57
- if a.shape[0] == b.shape[0] or a.shape[1] == b.shape[1]:
58
- return oper(a, b)
59
- elif min(a.shape) == 1 and min(b.shape) == 1:
60
- if a.shape[0] == 1:
61
- return oper(np.tile(a, (b.shape[0], 1)), b)
62
- else:
63
- return oper(np.tile(a, (1, b.shape[1], b)))
64
- else:
65
- raise '_bsxfun failure'
66
-
67
-
68
- def NormalizeRows(x):
69
-
70
- s = (np.sqrt(np.sum(x ** 2, axis=1))).flatten()
71
- s[s == 0] = 1
72
- return _bsxfun(np.divide, x, col(s))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/geometry/triangle_area.py DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2013 Max Planck Society. All rights reserved.
5
-
6
- from .tri_normals import TriToScaledNormal
7
- import numpy as np
8
-
9
-
10
- def triangle_area(v, f):
11
- """Computes the area associated to a set of triangles"""
12
- return (np.sqrt(np.sum(TriToScaledNormal(v, f) ** 2, axis=1)) / 2.).flatten()
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/geometry/vert_normals.py DELETED
@@ -1,34 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2013 Max Planck Society. All rights reserved.
5
- # Created by Matthew Loper on 2013-03-12.
6
-
7
-
8
- import scipy.sparse as sp
9
- import numpy as np
10
- from .tri_normals import NormalizedNx3, TriNormalsScaled
11
- from ..utils import col
12
-
13
-
14
- def MatVecMult(mtx, vec):
15
- return mtx.dot(col(vec)).flatten()
16
-
17
-
18
- def VertNormals(v, f):
19
- return NormalizedNx3(VertNormalsScaled(v, f))
20
-
21
-
22
- def VertNormalsScaled(v, f):
23
- IS = f.flatten()
24
- JS = np.array([range(f.shape[0])] * 3).T.flatten()
25
- data = np.ones(len(JS))
26
-
27
- IS = np.concatenate((IS * 3, IS * 3 + 1, IS * 3 + 2))
28
- JS = np.concatenate((JS * 3, JS * 3 + 1, JS * 3 + 2)) # is this right?
29
- data = np.concatenate((data, data, data))
30
-
31
- faces_by_vertex = sp.csc_matrix((data, (IS, JS)), shape=(v.size, f.size))
32
-
33
- # faces_by_vertex should be 3 x wider...?
34
- return NormalizedNx3(MatVecMult(faces_by_vertex, TriNormalsScaled(v, f)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/landmarks.py DELETED
@@ -1,102 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
- # Copyright (c) 2013 Max Planck Society. All rights reserved.
4
- # Created by Matthew Loper on 2013-02-20.
5
-
6
-
7
- import numpy as np
8
-
9
- """
10
- landmarks.py
11
-
12
- """
13
-
14
-
15
- def landm_xyz_linear_transform(self, ordering=None):
16
- from .utils import col, sparse
17
-
18
- landmark_order = ordering if ordering else self.landm_names
19
- # construct a sparse matrix that converts between the landmark pts and all vertices, with height (# landmarks * 3) and width (# vertices * 3)
20
- if hasattr(self, 'landm_regressors'):
21
- landmark_coefficients = np.hstack([self.landm_regressors[name][1] for name in landmark_order])
22
- landmark_indices = np.hstack([self.landm_regressors[name][0] for name in landmark_order])
23
- column_indices = np.hstack([col(3 * landmark_indices + i) for i in range(3)]).flatten()
24
- row_indices = np.hstack([[3 * index, 3 * index + 1, 3 * index + 2] * len(self.landm_regressors[landmark_order[index]][0]) for index in np.arange(len(landmark_order))])
25
- values = np.hstack([col(landmark_coefficients) for i in range(3)]).flatten()
26
- return sparse(row_indices, column_indices, values, 3 * len(landmark_order), 3 * self.v.shape[0])
27
- elif hasattr(self, 'landm'):
28
- landmark_indices = np.array([self.landm[name] for name in landmark_order])
29
- column_indices = np.hstack(([col(3 * landmark_indices + i) for i in range(3)])).flatten()
30
- row_indices = np.arange(3 * len(landmark_order))
31
- return sparse(row_indices, column_indices, np.ones(len(column_indices)), 3 * len(landmark_order), 3 * self.v.shape[0])
32
- else:
33
- return np.zeros((0, 0))
34
-
35
-
36
- @property
37
- def landm_xyz(self, ordering=None):
38
- landmark_order = ordering if ordering else self.landm_names
39
- landmark_vertex_locations = (self.landm_xyz_linear_transform(landmark_order) * self.v.flatten()).reshape(-1, 3) if landmark_order else np.zeros((0, 0))
40
- if landmark_order:
41
- return dict([(landmark_order[i], xyz) for i, xyz in enumerate(landmark_vertex_locations)])
42
- return {}
43
-
44
-
45
- def recompute_landmark_indices(self, landmark_fname=None, safe_mode=True):
46
- filtered_landmarks = dict(
47
- filter(
48
- lambda e, : e[1] != [0.0, 0.0, 0.0],
49
- self.landm_raw_xyz.items()
50
- ) if (landmark_fname and safe_mode) else self.landm_raw_xyz.items())
51
- if len(filtered_landmarks) != len(self.landm_raw_xyz):
52
- print("WARNING: %d landmarks in file %s are positioned at (0.0, 0.0, 0.0) and were ignored" % (len(self.landm_raw_xyz) - len(filtered_landmarks), landmark_fname))
53
-
54
- self.landm = {}
55
- self.landm_regressors = {}
56
- if filtered_landmarks:
57
- landmark_names = list(filtered_landmarks.keys())
58
- closest_vertices, _ = self.closest_vertices(np.array(list(filtered_landmarks.values())))
59
- self.landm = dict(zip(landmark_names, closest_vertices))
60
- if len(self.f):
61
- face_indices, closest_points = self.closest_faces_and_points(np.array(list(filtered_landmarks.values())))
62
- vertex_indices, coefficients = self.barycentric_coordinates_for_points(closest_points, face_indices)
63
- self.landm_regressors = dict([(name, (vertex_indices[i], coefficients[i])) for i, name in enumerate(landmark_names)])
64
- else:
65
- self.landm_regressors = dict([(name, (np.array([closest_vertices[i]]), np.array([1.0]))) for i, name in enumerate(landmark_names)])
66
-
67
-
68
- def set_landmarks_from_xyz(self, landm_raw_xyz):
69
- self.landm_raw_xyz = landm_raw_xyz if hasattr(landm_raw_xyz, 'keys') else dict((str(i), l) for i, l in enumerate(landm_raw_xyz))
70
- self.recompute_landmark_indices()
71
-
72
-
73
- def is_vertex(x):
74
- return hasattr(x, "__len__") and len(x) == 3
75
-
76
-
77
- def is_index(x):
78
- return isinstance(x, (int, np.int32, np.int64))
79
-
80
-
81
- def set_landmarks_from_raw(self, landmarks):
82
- '''
83
- can accept:
84
- {'name1': [float, float, float], 'name2': [float, float, float], ...}
85
- {'name1': np.array([float, float, float]), 'name2': np.array([float, float, float]), ...}
86
- [[float,float,float],[float,float,float], ...]
87
- np.array([[float,float,float],[float,float,float], ...])
88
- [np.array([float,float,float]),np.array([float,float,float]), ...]
89
- {'name1': int, 'name2': int, ...}
90
- [int,int,int]
91
- np.array([int,int,int])
92
- '''
93
- landmarks = landmarks if hasattr(landmarks, 'keys') else dict((str(i), l) for i, l in enumerate(landmarks))
94
-
95
- if all(is_vertex(x) for x in landmarks.values()):
96
- landmarks = dict((i, np.array(l)) for i, l in landmarks.items())
97
- self.set_landmarks_from_xyz(landmarks)
98
- elif all(is_index(x) for x in landmarks.values()):
99
- self.landm = landmarks
100
- self.recompute_landmark_xyz()
101
- else:
102
- raise Exception("Can't parse landmarks")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/lines.py DELETED
@@ -1,61 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
- # Copyright (c) 2012 Max Planck Society. All rights reserved.
4
-
5
- import numpy as np
6
- from . import colors
7
-
8
-
9
- class Lines(object):
10
- """Collection of 3D lines
11
-
12
- Attributes:
13
- v: Vx3 array of vertices
14
- e: Ex2 array of edges
15
- """
16
-
17
- def __init__(self, v, e, vc=None, ec=None):
18
-
19
- self.v = np.array(v)
20
- self.e = np.array(e)
21
-
22
- if vc is not None:
23
- self.set_vertex_colors(vc)
24
-
25
- if ec is not None:
26
- self.set_edge_colors(ec)
27
-
28
- def colors_like(self, color, arr):
29
- from .utils import row, col
30
- if isinstance(color, str):
31
- color = colors.name_to_rgb[color]
32
- elif isinstance(color, list):
33
- color = np.array(color)
34
-
35
- if color.shape == (arr.shape[0],):
36
- def jet(v):
37
- fourValue = 4 * v
38
- red = min(fourValue - 1.5, -fourValue + 4.5)
39
- green = min(fourValue - 0.5, -fourValue + 3.5)
40
- blue = min(fourValue + 0.5, -fourValue + 2.5)
41
- result = np.array([red, green, blue])
42
- result[result > 1.0] = 1.0
43
- result[result < 0.0] = 0.0
44
- return row(result)
45
- color = col(color)
46
- color = np.concatenate([jet(color[i]) for i in xrange(color.size)], axis=0)
47
-
48
- return np.ones((arr.shape[0], 3)) * color
49
-
50
- def set_vertex_colors(self, vc):
51
- self.vc = self.colors_like(vc, self.v)
52
-
53
- def set_edge_colors(self, ec):
54
- self.ec = self.colors_like(ec, self.e)
55
-
56
- def write_obj(self, filename):
57
- with open(filename, 'w') as fi:
58
- for r in self.v:
59
- fi.write('v %f %f %f\n' % (r[0], r[1], r[2]))
60
- for e in self.e:
61
- fi.write('l %d %d\n' % (e[0] + 1, e[1] + 1))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/mesh.py DELETED
@@ -1,492 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2012 Max Planck Society. All rights reserved.
5
-
6
- """
7
- Mesh module
8
- -----------
9
-
10
- """
11
-
12
-
13
- import os
14
- from functools import reduce
15
-
16
- import numpy as np
17
-
18
- from . import colors
19
- from . import search
20
-
21
- try:
22
- from .serialization import serialization
23
- except ImportError:
24
- pass
25
-
26
- from . import landmarks
27
- from . import texture
28
- from . import processing
29
-
30
-
31
- __all__ = ["Mesh"]
32
-
33
-
34
- class Mesh(object):
35
- """3d Triangulated Mesh class
36
-
37
- Attributes:
38
- v: Vx3 array of vertices
39
- f: Fx3 array of faces
40
-
41
- Optional attributes:
42
- fc: Fx3 array of face colors
43
- vc: Vx3 array of vertex colors
44
- vn: Vx3 array of vertex normals
45
- segm: dictionary of part names to triangle indices
46
-
47
- """
48
- def __init__(self,
49
- v=None,
50
- f=None,
51
- segm=None,
52
- filename=None,
53
- ppfilename=None,
54
- lmrkfilename=None,
55
- basename=None,
56
- vc=None,
57
- fc=None,
58
- vscale=None,
59
- landmarks=None):
60
- """
61
- :param v: vertices
62
- :param f: faces
63
- :param filename: a filename from which a mesh is loaded
64
- """
65
-
66
- if filename is not None:
67
- self.load_from_file(filename)
68
- if hasattr(self, 'f'):
69
- self.f = np.require(self.f, dtype=np.uint32)
70
- self.v = np.require(self.v, dtype=np.float64)
71
- self.filename = filename
72
- if vscale is not None:
73
- self.v *= vscale
74
- if v is not None:
75
- self.v = np.array(v, dtype=np.float64)
76
- if vscale is not None:
77
- self.v *= vscale
78
- if f is not None:
79
- self.f = np.require(f, dtype=np.uint32)
80
-
81
- self.basename = basename
82
- if self.basename is None and filename is not None:
83
- self.basename = os.path.splitext(os.path.basename(filename))[0]
84
-
85
- if segm is not None:
86
- self.segm = segm
87
- if landmarks is not None:
88
- self.set_landmark_indices_from_any(landmarks)
89
- if ppfilename is not None:
90
- self.set_landmark_indices_from_ppfile(ppfilename)
91
- if lmrkfilename is not None:
92
- self.set_landmark_indices_from_lmrkfile(lmrkfilename)
93
-
94
- if vc is not None:
95
- self.set_vertex_colors(vc)
96
-
97
- if fc is not None:
98
- self.set_face_colors(fc)
99
-
100
- def __del__(self):
101
- if hasattr(self, 'textureID'):
102
- from OpenGL.GL import glDeleteTextures
103
- glDeleteTextures([self.textureID])
104
-
105
- def edges_as_lines(self, copy_vertices=False):
106
- from .lines import Lines
107
- edges = self.f[:, [0, 1, 1, 2, 2, 0]].flatten().reshape(-1, 2)
108
- verts = self.v.copy() if copy_vertices else self.v
109
- return Lines(v=verts, e=edges)
110
-
111
- def show(self, mv=None, meshes=[], lines=[]):
112
- from .meshviewer import MeshViewer
113
- from .utils import row
114
-
115
- if mv is None:
116
- mv = MeshViewer(keepalive=True)
117
-
118
- if hasattr(self, 'landm'):
119
- from .sphere import Sphere
120
- sphere = Sphere(np.zeros((3)), 1.).to_mesh()
121
- scalefactor = 1e-2 * np.max(np.max(self.v) - np.min(self.v)) / np.max(np.max(sphere.v) - np.min(sphere.v))
122
- sphere.v = sphere.v * scalefactor
123
- spheres = [Mesh(vc='SteelBlue', f=sphere.f, v=sphere.v + row(np.array(self.landm_raw_xyz[k]))) for k in self.landm.keys()]
124
- mv.set_dynamic_meshes([self] + spheres + meshes, blocking=True)
125
- else:
126
- mv.set_dynamic_meshes([self] + meshes, blocking=True)
127
- mv.set_dynamic_lines(lines)
128
- return mv
129
-
130
- def colors_like(self, color, arr=None):
131
- from .utils import row, col
132
-
133
- if arr is None:
134
- arr = np.zeros(self.v.shape)
135
-
136
- # if arr is single-dim, reshape it
137
- if arr.ndim == 1 or arr.shape[1] == 1:
138
- arr = arr.reshape(-1, 3)
139
-
140
- if isinstance(color, str):
141
- color = colors.name_to_rgb[color]
142
- elif isinstance(color, list):
143
- color = np.array(color)
144
-
145
- if color.shape[0] == arr.shape[0] and color.shape[0] == color.size:
146
- def jet(v):
147
- fourValue = 4 * v
148
- red = min(fourValue - 1.5, -fourValue + 4.5)
149
- green = min(fourValue - 0.5, -fourValue + 3.5)
150
- blue = min(fourValue + 0.5, -fourValue + 2.5)
151
- result = np.array([red, green, blue])
152
- result[result > 1.0] = 1.0
153
- result[result < 0.0] = 0.0
154
- return row(result)
155
- color = col(color)
156
- color = np.concatenate([jet(color[i]) for i in range(color.size)], axis=0)
157
-
158
- return np.ones_like(arr) * color
159
-
160
- def set_vertex_colors(self, vc, vertex_indices=None):
161
- if vertex_indices is not None:
162
- self.vc[vertex_indices] = self.colors_like(vc, self.v[vertex_indices])
163
- else:
164
- self.vc = self.colors_like(vc, self.v)
165
- return self
166
-
167
- def set_vertex_colors_from_weights(self, weights, scale_to_range_1=True, color=True):
168
- # from numpy import ones_like
169
- if weights is None:
170
- return self
171
- if scale_to_range_1:
172
- weights = weights - np.min(weights)
173
- weights = (1.0 - 0.0) * weights / np.max(weights) + 0.0
174
- if color:
175
- from matplotlib import cm
176
- self.vc = cm.jet(weights)[:, :3]
177
- else:
178
- self.vc = np.tile(np.reshape(weights, (len(weights), 1)), (1, 3)) # *ones_like(self.v)
179
- return self
180
-
181
- def scale_vertex_colors(self, weights, w_min=0.0, w_max=1.0):
182
- if weights is None:
183
- return self
184
- weights = weights - np.min(weights)
185
- weights = (w_max - w_min) * weights / np.max(weights) + w_min
186
- self.vc = (weights * self.vc.T).T if weights is not None else self.vc
187
- return self
188
-
189
- def set_face_colors(self, fc):
190
- self.fc = self.colors_like(fc, self.f)
191
- return self
192
-
193
- def faces_by_vertex(self, as_sparse_matrix=False):
194
- import scipy.sparse as sp
195
- if not as_sparse_matrix:
196
- faces_by_vertex = [[] for i in range(len(self.v))]
197
- for i, face in enumerate(self.f):
198
- faces_by_vertex[face[0]].append(i)
199
- faces_by_vertex[face[1]].append(i)
200
- faces_by_vertex[face[2]].append(i)
201
- else:
202
- row = self.f.flatten()
203
- col = np.array([range(self.f.shape[0])] * 3).T.flatten()
204
- data = np.ones(len(col))
205
- faces_by_vertex = sp.csr_matrix((data, (row, col)), shape=(self.v.shape[0], self.f.shape[0]))
206
- return faces_by_vertex
207
-
208
- def estimate_vertex_normals(self, face_to_verts_sparse_matrix=None):
209
- from .geometry.tri_normals import TriNormalsScaled
210
-
211
- face_normals = TriNormalsScaled(self.v, self.f).reshape(-1, 3)
212
- ftov = face_to_verts_sparse_matrix if face_to_verts_sparse_matrix else self.faces_by_vertex(as_sparse_matrix=True)
213
- non_scaled_normals = ftov * face_normals
214
- norms = (np.sum(non_scaled_normals ** 2.0, axis=1) ** 0.5).T
215
- norms[norms == 0] = 1.0
216
- return (non_scaled_normals.T / norms).T
217
-
218
- def barycentric_coordinates_for_points(self, points, face_indices):
219
- from .geometry.barycentric_coordinates_of_projection import barycentric_coordinates_of_projection
220
- vertex_indices = self.f[face_indices.flatten(), :]
221
- tri_vertices = np.array([self.v[vertex_indices[:, 0]], self.v[vertex_indices[:, 1]], self.v[vertex_indices[:, 2]]])
222
- return vertex_indices, barycentric_coordinates_of_projection(points, tri_vertices[0, :], tri_vertices[1, :] - tri_vertices[0, :], tri_vertices[2, :] - tri_vertices[0, :])
223
-
224
- def transfer_segm(self, mesh, exclude_empty_parts=True):
225
- self.segm = {}
226
- if hasattr(mesh, 'segm'):
227
- face_centers = np.array([self.v[face, :].mean(axis=0) for face in self.f])
228
- (closest_faces, closest_points) = mesh.closest_faces_and_points(face_centers)
229
- mesh_parts_by_face = mesh.parts_by_face()
230
- parts_by_face = [mesh_parts_by_face[face] for face in closest_faces.flatten()]
231
- self.segm = dict([(part, []) for part in mesh.segm.keys()])
232
- for face, part in enumerate(parts_by_face):
233
- self.segm[part].append(face)
234
- for part in self.segm.keys():
235
- self.segm[part].sort()
236
- if exclude_empty_parts and not self.segm[part]:
237
- del self.segm[part]
238
-
239
- @property
240
- def verts_by_segm(self):
241
- return dict((segment, sorted(set(self.f[indices].flatten()))) for segment, indices in self.segm.items())
242
-
243
- def parts_by_face(self):
244
- segments_by_face = [''] * len(self.f)
245
- for part in self.segm.keys():
246
- for face in self.segm[part]:
247
- segments_by_face[face] = part
248
- return segments_by_face
249
-
250
- def verts_in_common(self, segments):
251
- """
252
- returns array of all vertex indices common to each segment in segments"""
253
- return sorted(reduce(lambda s0, s1: s0.intersection(s1),
254
- [set(self.verts_by_segm[segm]) for segm in segments]))
255
- # # indices of vertices in the faces of the first segment
256
- # indices = self.verts_by_segm[segments[0]]
257
- # for segment in segments[1:] :
258
- # indices = sorted([index for index in self.verts_by_segm[segment] if index in indices]) # Intersect current segment with current indices
259
- # return sorted(set(indices))
260
-
261
- @property
262
- def joint_names(self):
263
- return self.joint_regressors.keys()
264
-
265
- @property
266
- def joint_xyz(self):
267
- joint_locations = {}
268
- for name in self.joint_names:
269
- joint_locations[name] = self.joint_regressors[name]['offset'] + \
270
- np.sum(self.v[self.joint_regressors[name]['v_indices']].T * self.joint_regressors[name]['coeff'], axis=1)
271
- return joint_locations
272
-
273
- # creates joint_regressors from a list of joint names and a per joint list of vertex indices (e.g. a ring of vertices)
274
- # For the regression coefficients, all vertices for a given joint are given equal weight
275
- def set_joints(self, joint_names, vertex_indices):
276
- self.joint_regressors = {}
277
- for name, indices in zip(joint_names, vertex_indices):
278
- self.joint_regressors[name] = {'v_indices': indices,
279
- 'coeff': [1.0 / len(indices)] * len(indices),
280
- 'offset': np.array([0., 0., 0.])}
281
-
282
- def vertex_visibility(self, camera, normal_threshold=None, omni_directional_camera=False, binary_visiblity=True):
283
-
284
- vis, n_dot_cam = self.vertex_visibility_and_normals(camera, omni_directional_camera)
285
-
286
- if normal_threshold is not None:
287
- vis = np.logical_and(vis, n_dot_cam > normal_threshold)
288
-
289
- return np.squeeze(vis) if binary_visiblity else np.squeeze(vis * n_dot_cam)
290
-
291
- def vertex_visibility_and_normals(self, camera, omni_directional_camera=False):
292
- from .visibility import visibility_compute
293
- arguments = {'v': self.v,
294
- 'f': self.f,
295
- 'cams': np.array([camera.origin.flatten()])}
296
-
297
- if not omni_directional_camera:
298
- arguments['sensors'] = np.array([camera.sensor_axis.flatten()])
299
-
300
- arguments['n'] = self.vn if hasattr(self, 'vn') else self.estimate_vertex_normals()
301
-
302
- return(visibility_compute(**arguments))
303
-
304
- def visibile_mesh(self, camera=[0.0, 0.0, 0.0]):
305
- vis = self.vertex_visibility(camera)
306
- faces_to_keep = filter(lambda face: vis[face[0]] * vis[face[1]] * vis[face[2]], self.f)
307
- vertex_indices_to_keep = np.nonzero(vis)[0]
308
- vertices_to_keep = self.v[vertex_indices_to_keep]
309
- old_to_new_indices = np.zeros(len(vis))
310
- old_to_new_indices[vertex_indices_to_keep] = range(len(vertex_indices_to_keep))
311
- return Mesh(v=vertices_to_keep, f=np.array([old_to_new_indices[face] for face in faces_to_keep]))
312
-
313
- def estimate_circumference(self, plane_normal, plane_distance, partNamesAllowed=None, want_edges=False):
314
- raise Exception('estimate_circumference function has moved to body.mesh.metrics.circumferences')
315
-
316
- # ######################################################
317
- # Processing
318
- def reset_normals(self, face_to_verts_sparse_matrix=None, reset_face_normals=False):
319
- return processing.reset_normals(self, face_to_verts_sparse_matrix, reset_face_normals)
320
-
321
- def reset_face_normals(self):
322
- return processing.reset_face_normals(self)
323
-
324
- def uniquified_mesh(self):
325
- """This function returns a copy of the mesh in which vertices are copied such that
326
- each vertex appears in only one face, and hence has only one texture"""
327
- return processing.uniquified_mesh(self)
328
-
329
- def keep_vertices(self, keep_list):
330
- return processing.keep_vertices(self, keep_list)
331
-
332
- def remove_vertices(self, v_list):
333
- return self.keep_vertices(np.setdiff1d(np.arange(self.v.shape[0]), v_list))
334
-
335
- def point_cloud(self):
336
- return Mesh(v=self.v, f=[], vc=self.vc) if hasattr(self, 'vc') else Mesh(v=self.v, f=[])
337
-
338
- def remove_faces(self, face_indices_to_remove):
339
- return processing.remove_faces(self, face_indices_to_remove)
340
-
341
- def scale_vertices(self, scale_factor):
342
- return processing.scale_vertices(self, scale_factor)
343
-
344
- def rotate_vertices(self, rotation):
345
- return processing.rotate_vertices(self, rotation)
346
-
347
- def translate_vertices(self, translation):
348
- return processing.translate_vertices(self, translation)
349
-
350
- def flip_faces(self):
351
- return processing.flip_faces(self)
352
-
353
- def simplified(self, factor=None, n_verts_desired=None):
354
- from .topology import qslim_decimator
355
- return qslim_decimator(self, factor, n_verts_desired)
356
-
357
- def subdivide_triangles(self):
358
- return processing.subdivide_triangles(self)
359
-
360
- def concatenate_mesh(self, mesh):
361
- return processing.concatenate_mesh(self, mesh)
362
-
363
- # new_ordering specifies the new index of each vertex. If new_ordering[i] = j,
364
- # vertex i should now be the j^th vertex. As such, each entry in new_ordering should be unique.
365
- def reorder_vertices(self, new_ordering, new_normal_ordering=None):
366
- processing.reorder_vertices(self, new_ordering, new_normal_ordering)
367
-
368
- # ######################################################
369
- # Landmark methods
370
-
371
- @property
372
- def landm_names(self):
373
- names = []
374
- if hasattr(self, 'landm_regressors') or hasattr(self, 'landm'):
375
- names = self.landm_regressors.keys() if hasattr(self, 'landm_regressors') else self.landm.keys()
376
- return list(names)
377
-
378
- @property
379
- def landm_xyz(self, ordering=None):
380
- landmark_order = ordering if ordering else self.landm_names
381
- landmark_vertex_locations = (self.landm_xyz_linear_transform(landmark_order) * self.v.flatten()).reshape(-1, 3) if landmark_order else np.zeros((0, 0))
382
- return dict([(landmark_order[i], xyz) for i, xyz in enumerate(landmark_vertex_locations)]) if landmark_order else {}
383
-
384
- def set_landmarks_from_xyz(self, landm_raw_xyz):
385
- self.landm_raw_xyz = landm_raw_xyz if hasattr(landm_raw_xyz, 'keys') else dict((str(i), l) for i, l in enumerate(landm_raw_xyz))
386
- self.recompute_landmark_indices()
387
-
388
- def landm_xyz_linear_transform(self, ordering=None):
389
- return landmarks.landm_xyz_linear_transform(self, ordering)
390
-
391
- def recompute_landmark_xyz(self):
392
- self.landm_raw_xyz = dict((name, self.v[ind]) for name, ind in self.landm.items())
393
-
394
- def recompute_landmark_indices(self, landmark_fname=None, safe_mode=True):
395
- landmarks.recompute_landmark_indices(self, landmark_fname, safe_mode)
396
-
397
- def set_landmarks_from_regressors(self, regressors):
398
- self.landm_regressors = regressors
399
-
400
- def set_landmark_indices_from_any(self, landmark_file_or_values):
401
- serialization.set_landmark_indices_from_any(self, landmark_file_or_values)
402
-
403
- def set_landmarks_from_raw(self, landmark_file_or_values):
404
- landmarks.set_landmarks_from_raw(self, landmark_file_or_values)
405
-
406
- #######################################################
407
- # Texture methods
408
-
409
- @property
410
- def texture_image(self):
411
- if not hasattr(self, '_texture_image'):
412
- self.reload_texture_image()
413
- return self._texture_image
414
-
415
- def set_texture_image(self, path_to_texture):
416
- self.texture_filepath = path_to_texture
417
-
418
- def texture_coordinates_by_vertex(self):
419
- return texture.texture_coordinates_by_vertex(self)
420
-
421
- def reload_texture_image(self):
422
- texture.reload_texture_image(self)
423
-
424
- def transfer_texture(self, mesh_with_texture):
425
- texture.transfer_texture(self, mesh_with_texture)
426
-
427
- def load_texture(self, texture_version):
428
- texture.load_texture(self, texture_version)
429
-
430
- def texture_rgb(self, texture_coordinate):
431
- return texture.texture_rgb(self, texture_coordinate)
432
-
433
- def texture_rgb_vec(self, texture_coordinates):
434
- return texture.texture_rgb_vec(self, texture_coordinates)
435
-
436
- #######################################################
437
- # Search methods
438
-
439
- def compute_aabb_tree(self):
440
- return search.AabbTree(self)
441
-
442
- def compute_aabb_normals_tree(self):
443
- return search.AabbNormalsTree(self)
444
-
445
- def compute_closest_point_tree(self, use_cgal=False):
446
- return search.CGALClosestPointTree(self) if use_cgal else search.ClosestPointTree(self)
447
-
448
- def closest_vertices(self, vertices, use_cgal=False):
449
- return self.compute_closest_point_tree(use_cgal).nearest(vertices)
450
-
451
- def closest_points(self, vertices):
452
- return self.closest_faces_and_points(vertices)[1]
453
-
454
- def closest_faces_and_points(self, vertices):
455
- return self.compute_aabb_tree().nearest(vertices)
456
-
457
- #######################################################
458
- # Serialization methods
459
-
460
- def load_from_file(self, filename):
461
- serialization.load_from_file(self, filename)
462
-
463
- def load_from_ply(self, filename):
464
- serialization.load_from_ply(self, filename)
465
-
466
- def load_from_obj(self, filename):
467
- serialization.load_from_obj(self, filename)
468
-
469
- def write_json(self, filename, header="", footer="", name="", include_faces=True, texture_mode=True):
470
- serialization.write_json(self, filename, header, footer, name, include_faces, texture_mode)
471
-
472
- def write_three_json(self, filename, name=""):
473
- serialization.write_three_json(self, filename, name)
474
-
475
- def write_ply(self, filename, flip_faces=False, ascii=False, little_endian=True, comments=[]):
476
- serialization.write_ply(self, filename, flip_faces, ascii, little_endian, comments)
477
-
478
- def write_mtl(self, path, material_name, texture_name):
479
- """Serializes a material attributes file"""
480
- serialization.write_mtl(self, path, material_name, texture_name)
481
-
482
- def write_obj(self, filename, flip_faces=False, group=False, comments=None):
483
- serialization.write_obj(self, filename, flip_faces, group, comments)
484
-
485
- def load_from_obj_cpp(self, filename):
486
- serialization.load_from_obj_cpp(self, filename)
487
-
488
- def set_landmark_indices_from_ppfile(self, ppfilename):
489
- serialization.set_landmark_indices_from_ppfile(self, ppfilename)
490
-
491
- def set_landmark_indices_from_lmrkfile(self, lmrkfilename):
492
- serialization.set_landmark_indices_from_lmrkfile(self, lmrkfilename)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/meshviewer.py DELETED
@@ -1,1238 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2012 Max Planck Society. All rights reserved.
5
- # Created by Matthew Loper on 2012-05-11.
6
-
7
- """
8
- Mesh visualization and related classes
9
- --------------------------------------
10
-
11
- This module contains the core visualization tools for meshes. The backend used for visualization
12
- is OpenGL.
13
-
14
- The module itself can be run like the following
15
-
16
- .. code::
17
-
18
- python -m psbody.mesh.meshviewer arguments
19
-
20
- The following commands are used
21
-
22
- * ``arguments=TEST_FOR_OPENGL`` a basic OpenGL support is run. This is usually performed
23
- on a forked python process. In case OpenGL is not supported, a `DummyClass``
24
- mesh viewer is returned.
25
- * ``arguments=title nb_x_axis nb_y_axis width height`` a new window is created
26
-
27
- .. autosummary::
28
-
29
- MeshViewer
30
- MeshViewers
31
- MeshViewerLocal
32
- test_for_opengl
33
-
34
- """
35
-
36
- import sys
37
- import os.path
38
- import time
39
- import copy
40
- import numpy as np
41
- import traceback
42
- from multiprocessing import freeze_support
43
-
44
- import zmq
45
- import re
46
- import subprocess
47
- import tempfile
48
-
49
- # this is way too verbose, organize imports better
50
- from OpenGL.GL import glPixelStorei, glMatrixMode, glHint, glTexParameterf, glDisableClientState
51
- from OpenGL.GL import glBindTexture, glEnableClientState, glPointSize, glEnable
52
- from OpenGL.GL import glColor3f, glDisable, glBegin, glEnd, glClearColor, glClearDepth
53
- from OpenGL.GL import glNormalPointer, glLineWidth, glTexCoord2f, glTexCoordPointer
54
- from OpenGL.GL import glViewport, glLightModeli, glLoadIdentity, glTranslatef, glPushMatrix
55
- from OpenGL.GL import glLoadMatrixf, glPopMatrix, glMultMatrixf, glDrawElementsui, glTexEnvf, glGetDoublev
56
- from OpenGL.GL import glGenTextures, glTexImage2D, glFrustum, glGenerateMipmap
57
- from OpenGL.GL import glBlendFunc, glVertex3f, glVertexPointer, glVertexPointerf, glColorPointerf, glColorPointer
58
- from OpenGL.GL import glGetFloatv, glGetIntegerv, glReadPixels
59
- from OpenGL.GL import glClear, glFlush, glDepthFunc, glShadeModel
60
- from OpenGL.GL import GL_TRUE, GL_FLOAT, GL_POINTS, GL_COLOR_ARRAY, GL_NORMAL_ARRAY, GL_LINE_SMOOTH, GL_MODELVIEW_MATRIX
61
- from OpenGL.GL import GL_BLEND, GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_TEXTURE_MAG_FILTER, GL_SMOOTH
62
- from OpenGL.GL import GL_TEXTURE_MIN_FILTER, GL_VIEWPORT, GL_LINEAR, GL_COLOR_MATERIAL, GL_LIGHT0, GL_NORMALIZE
63
- from OpenGL.GL import GL_PROJECTION, GL_MODELVIEW, GL_VERTEX_SHADER, GL_LIGHTING, GL_TEXTURE_COORD_ARRAY
64
- from OpenGL.GL import GL_TEXTURE_ENV, GL_TRIANGLES, GL_LINEAR_MIPMAP_LINEAR, GL_COLOR_CLEAR_VALUE
65
- from OpenGL.GL import GL_FRAGMENT_SHADER, GL_NEAREST, GL_UNPACK_ALIGNMENT, GL_RGB, GL_BGR, GL_DECAL, GL_MODULATE
66
- from OpenGL.GL import GL_UNSIGNED_BYTE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_QUADS, GL_POLYGON, GL_VERTEX_ARRAY, GL_DEPTH_COMPONENT
67
- from OpenGL.GL import GL_LIGHT_MODEL_TWO_SIDE, GL_GENERATE_MIPMAP_HINT, GL_NICEST, GL_LINES, GL_PROJECTION_MATRIX
68
- from OpenGL.GL import GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_LEQUAL, GL_DEPTH_TEST, GL_PERSPECTIVE_CORRECTION_HINT
69
- from OpenGL.GL import shaders
70
-
71
- from OpenGL.GLUT import glutInit, glutDisplayFunc, glutInitDisplayMode, glutInitWindowSize, glutGet, GLUT_WINDOW_WIDTH, GLUT_WINDOW_HEIGHT
72
- from OpenGL.GLUT import glutMainLoop, glutPostRedisplay, glutInitWindowPosition, glutCreateWindow, glutTimerFunc, glutSetWindowTitle
73
- from OpenGL.GLUT import glutReshapeFunc, glutKeyboardFunc, glutMouseFunc, glutMotionFunc, glutSwapBuffers
74
- from OpenGL.GLUT import GLUT_RGBA, GLUT_DOUBLE, GLUT_ALPHA, GLUT_DEPTH
75
- from OpenGL.GLUT import GLUT_LEFT_BUTTON, GLUT_DOWN, GLUT_UP, GLUT_RIGHT_BUTTON, GLUT_MIDDLE_BUTTON
76
- from OpenGL.GLU import gluPerspective, gluUnProject
77
-
78
- import OpenGL.arrays.vbo
79
-
80
- # if this file is processed/run as a python script/standalone, especially from the
81
- # internal command
82
- if __package__ is not None:
83
- from .mesh import Mesh
84
- from .geometry.tri_normals import TriNormals
85
- from .arcball import ArcBallT, Matrix3fT, Matrix4fT, Point2fT, \
86
- Matrix3fMulMatrix3f, Matrix3fSetRotationFromQuat4f, Matrix4fSetRotationFromMatrix3f
87
-
88
- from .fonts import get_textureid_with_text
89
-
90
- # this block is below the previous one to make my linter happy
91
- if __package__ is None:
92
- print("this file cannot be executed as a standalone python module")
93
- print("python -m psbody.mesh.%s arguments" % (os.path.splitext(os.path.basename(__file__))[0]))
94
- sys.exit(-1)
95
-
96
-
97
- def _run_self(args, stdin=None, stdout=None, stderr=None):
98
- """Executes this same script module with the given arguments (forking without subprocess dependencies)"""
99
- return subprocess.Popen([sys.executable] +
100
- ['-m'] + ['%s.%s' % (__package__, os.path.splitext(os.path.basename(__file__))[0])] +
101
- args,
102
- stdin=stdin,
103
- stdout=stdout, # if stdout is not None else subprocess.PIPE,
104
- stderr=stderr)
105
-
106
-
107
- def _test_for_opengl():
108
- try:
109
- # from OpenGL.GLUT import glutInit
110
- glutInit()
111
- except Exception as e:
112
- print(e, file=sys.stderr)
113
- print('failure')
114
- else:
115
- print('success')
116
-
117
-
118
- test_for_opengl_cached = None
119
-
120
-
121
- def test_for_opengl():
122
- """Tests if opengl is supported.
123
-
124
- .. note:: the result of the test is cached
125
-
126
- """
127
-
128
- global test_for_opengl_cached
129
- if test_for_opengl_cached is None:
130
-
131
- with open(os.devnull) as dev_null, \
132
- tempfile.TemporaryFile() as out, \
133
- tempfile.TemporaryFile() as err:
134
-
135
- p = _run_self(["TEST_FOR_OPENGL"],
136
- stdin=dev_null,
137
- stdout=out,
138
- stderr=err)
139
- p.wait()
140
-
141
- out.seek(0)
142
- err.seek(0)
143
-
144
- line = ''.join(out.read().decode())
145
- test_for_opengl_cached = 'success' in line
146
- if not test_for_opengl_cached:
147
- print('OpenGL test failed: ')
148
- print('\tstdout:', line)
149
- print('\tstderr:', '\n'.join(err.read().decode()))
150
-
151
- return test_for_opengl_cached
152
-
153
-
154
- class Dummy(object):
155
-
156
- def __getattr__(self, name):
157
- return Dummy()
158
-
159
- def __call__(self, *args, **kwargs):
160
- return Dummy()
161
-
162
- def __getitem__(self, key):
163
- return Dummy()
164
-
165
- def __setitem__(self, key, value):
166
- pass
167
-
168
-
169
- def MeshViewer(titlebar='Mesh Viewer',
170
- static_meshes=None,
171
- static_lines=None,
172
- uid=None,
173
- autorecenter=True,
174
- shape=(1, 1),
175
- keepalive=False,
176
- window_width=1280,
177
- window_height=960,
178
- snapshot_camera=None):
179
- """Allows visual inspection of geometric primitives.
180
-
181
- Write-only Attributes:
182
-
183
- :param titlebar: string printed in the window titlebar
184
- :param static_meshes: list of Mesh objects to be displayed
185
- :param static_lines: list of Lines objects to be displayed
186
-
187
- .. note:: `static_meshes` is meant for Meshes that are updated infrequently,
188
- `and dynamic_meshes` is for Meshes that are updated frequently
189
- (same for `dynamic_lines` vs. `static_lines`).
190
- They may be treated differently for performance reasons.
191
-
192
- """
193
-
194
- if not test_for_opengl():
195
- return Dummy()
196
-
197
- mv = MeshViewerLocal(shape=(1, 1),
198
- uid=uid,
199
- titlebar=titlebar,
200
- keepalive=keepalive,
201
- window_width=window_width,
202
- window_height=window_height)
203
- result = mv.get_subwindows()[0][0]
204
- result.snapshot_camera = snapshot_camera
205
- if static_meshes:
206
- result.static_meshes = static_meshes
207
- if static_lines:
208
- result.static_lines = static_lines
209
- result.autorecenter = autorecenter
210
-
211
- return result
212
-
213
-
214
- def MeshViewers(shape=(1, 1),
215
- titlebar="Mesh Viewers",
216
- keepalive=False,
217
- window_width=1280,
218
- window_height=960):
219
- """Allows subplot-style inspection of primitives in multiple subwindows.
220
-
221
- :param shape: a tuple indicating the number of vertical and horizontal windows requested
222
- :param titlebar: the title appearing on the created window
223
-
224
-
225
- Returns: a list of lists of MeshViewer objects: one per window requested.
226
- """
227
-
228
- if not test_for_opengl():
229
- return Dummy()
230
-
231
- mv = MeshViewerLocal(shape=shape,
232
- titlebar=titlebar,
233
- uid=None,
234
- keepalive=keepalive,
235
- window_width=window_width,
236
- window_height=window_height)
237
- return mv.get_subwindows()
238
-
239
-
240
- class MeshSubwindow(object):
241
-
242
- def __init__(self, parent_window, which_window):
243
- self.parent_window = parent_window
244
- self.which_window = which_window
245
-
246
- def set_dynamic_meshes(self, list_of_meshes, blocking=False):
247
- self.parent_window.set_dynamic_meshes(list_of_meshes, blocking, self.which_window)
248
-
249
- def set_static_meshes(self, list_of_meshes, blocking=False):
250
- self.parent_window.set_static_meshes(list_of_meshes, blocking, self.which_window)
251
-
252
- # list_of_model_names_and_parameters should be of form [{'name': scape_model_name, 'parameters': scape_model_parameters}]
253
- # here scape_model_name is the filepath of the scape model.
254
- def set_dynamic_models(self, list_of_model_names_and_parameters, blocking=False):
255
- self.parent_window.set_dynamic_models(list_of_model_names_and_parameters, blocking, self.which_window)
256
-
257
- def set_dynamic_lines(self, list_of_lines, blocking=False):
258
- self.parent_window.set_dynamic_lines(list_of_lines, blocking, self.which_window)
259
-
260
- def set_static_lines(self, list_of_lines, blocking=False):
261
- self.parent_window.set_static_lines(list_of_lines, blocking=blocking, which_window=self.which_window)
262
-
263
- def set_titlebar(self, titlebar, blocking=False):
264
- self.parent_window.set_titlebar(titlebar, blocking, which_window=self.which_window)
265
-
266
- def set_lighting_on(self, lighting_on, blocking=True):
267
- self.parent_window.set_lighting_on(lighting_on, blocking=blocking, which_window=self.which_window)
268
-
269
- def set_autorecenter(self, autorecenter, blocking=False):
270
- self.parent_window.set_autorecenter(autorecenter, blocking=blocking, which_window=self.which_window)
271
-
272
- def set_background_color(self, background_color, blocking=False):
273
- self.parent_window.set_background_color(background_color, blocking=blocking, which_window=self.which_window)
274
-
275
- def save_snapshot(self, path, blocking=False):
276
- self.parent_window.save_snapshot(path, blocking=blocking, which_window=self.which_window)
277
-
278
- def get_event(self):
279
- return self.parent_window.get_event()
280
-
281
- def get_keypress(self):
282
- return self.parent_window.get_keypress()['key']
283
-
284
- def get_mouseclick(self):
285
- return self.parent_window.get_mouseclick()
286
-
287
- def close(self):
288
- self.parent_window.p.terminate()
289
-
290
- background_color = property(fset=set_background_color, doc="Background color, as 3-element numpy array where 0 <= color <= 1.0.")
291
- dynamic_meshes = property(fset=set_dynamic_meshes, doc="List of meshes for dynamic display.")
292
- static_meshes = property(fset=set_static_meshes, doc="List of meshes for static display.")
293
- dynamic_models = property(fset=set_dynamic_models, doc="List of model names and parameters for dynamic display.")
294
- dynamic_lines = property(fset=set_dynamic_lines, doc="List of Lines for dynamic display.")
295
- static_lines = property(fset=set_static_lines, doc="List of Lines for static display.")
296
- titlebar = property(fset=set_titlebar, doc="Titlebar string.")
297
- lighting_on = property(fset=set_lighting_on, doc="Titlebar string.")
298
-
299
-
300
- class MeshViewerLocal(object):
301
- """Proxy viewer instance for visual inspection of geometric primitives.
302
-
303
- The lass forks another python process holding the display. It communicates
304
- the commands with the remote instance seemlessly.
305
-
306
- Write-only attributes:
307
-
308
- :param titlebar: string printed in the window titlebar
309
- :param dynamic_meshes: list of Mesh objects to be displayed
310
- :param static_meshes: list of Mesh objects to be displayed
311
- :param dynamic_lines: list of Lines objects to be displayed
312
- :param static_lines: list of Lines objects to be displayed
313
-
314
- .. note::
315
-
316
- `static_meshes` is meant for Meshes that are
317
- updated infrequently, and dynamic_meshes is for Meshes
318
- that are updated frequently (same for dynamic_lines vs
319
- static_lines). They may be treated differently for
320
- performance reasons.
321
-
322
- """
323
-
324
- managed = {}
325
-
326
- def __new__(cls, titlebar, uid, shape, keepalive, window_width, window_height):
327
- assert(uid is None or isinstance(uid, str))
328
-
329
- if uid == 'stack':
330
- uid = ''.join(traceback.format_list(traceback.extract_stack()))
331
- if uid and uid in MeshViewer.managed.keys():
332
- return MeshViewer.managed[uid]
333
-
334
- result = super(MeshViewerLocal, cls).__new__(cls)
335
-
336
- result.client = zmq.Context.instance().socket(zmq.PUSH)
337
- result.client.linger = 0
338
-
339
- with open(os.devnull) as dev_null, \
340
- tempfile.TemporaryFile() as err:
341
-
342
- result.p = _run_self([titlebar, str(shape[0]), str(shape[1]), str(window_width), str(window_height)],
343
- stdin=dev_null,
344
- stdout=subprocess.PIPE,
345
- stderr=err)
346
-
347
- line = result.p.stdout.readline().decode()
348
- result.p.stdout.close()
349
- current_port = re.match('<PORT>(.*?)</PORT>', line)
350
- if not current_port:
351
- raise Exception("MeshViewer remote appears to have failed to launch")
352
- current_port = int(current_port.group(1))
353
- result.client.connect('tcp://127.0.0.1:%d' % (current_port))
354
-
355
- if uid:
356
- MeshViewerLocal.managed[uid] = result
357
- result.shape = shape
358
- result.keepalive = keepalive
359
- return result
360
-
361
- def get_subwindows(self):
362
- return [[MeshSubwindow(parent_window=self, which_window=(r, c)) for c in range(self.shape[1])] for r in range(self.shape[0])]
363
-
364
- @staticmethod
365
- def _sanitize_meshes(list_of_meshes):
366
- lm = []
367
-
368
- # have to copy the meshes for now, because some contain CPython members,
369
- # before pushing them on the queue
370
- for m in list_of_meshes:
371
- if hasattr(m, 'fc'):
372
- lm.append(Mesh(v=m.v, f=m.f, fc=m.fc))
373
- elif hasattr(m, 'vc'):
374
- lm.append(Mesh(v=m.v, f=m.f, vc=m.vc))
375
- else:
376
- lm.append(Mesh(v=m.v, f=m.f if hasattr(m, 'f') else []))
377
-
378
- if hasattr(m, 'vn'):
379
- lm[-1].vn = m.vn
380
- if hasattr(m, 'fn'):
381
- lm[-1].fn = m.fn
382
-
383
- if hasattr(m, 'v_to_text'):
384
- lm[-1].v_to_text = m.v_to_text
385
- if hasattr(m, 'texture_filepath') and hasattr(m, 'vt') and hasattr(m, 'ft'):
386
- lm[-1].texture_filepath = m.texture_filepath
387
- lm[-1].vt = m.vt
388
- lm[-1].ft = m.ft
389
-
390
- return lm
391
-
392
- def _send_pyobj(self, label, obj, blocking, which_window):
393
- if blocking:
394
- context = zmq.Context.instance()
395
- server = context.socket(zmq.PULL)
396
- server.linger = 0
397
- port = server.bind_to_random_port('tcp://127.0.0.1',
398
- min_port=49152,
399
- max_port=65535,
400
- max_tries=100000)
401
- # sending with blocking'
402
- self.client.send_pyobj({'label': label,
403
- 'obj': obj,
404
- 'port': port,
405
- 'which_window': which_window})
406
- task_completion_time = server.recv_pyobj()
407
- # task completion time was %.2fs in other process' % (task_completion_time,)
408
- server.close()
409
- else:
410
- # sending nonblocking
411
- self.client.send_pyobj({'label': label,
412
- 'obj': obj,
413
- 'which_window': which_window})
414
-
415
- def set_dynamic_meshes(self, list_of_meshes, blocking=False, which_window=(0, 0)):
416
- self._send_pyobj('dynamic_meshes', self._sanitize_meshes(list_of_meshes), blocking, which_window)
417
-
418
- def set_static_meshes(self, list_of_meshes, blocking=False, which_window=(0, 0)):
419
- self._send_pyobj('static_meshes', self._sanitize_meshes(list_of_meshes), blocking, which_window)
420
-
421
- # list_of_model_names_and_parameters should be of form [{'name': scape_model_name, 'parameters': scape_model_parameters}]
422
- # here scape_model_name is the filepath of the scape model.
423
- def set_dynamic_models(self, list_of_model_names_and_parameters, blocking=False, which_window=(0, 0)):
424
- self._send_pyobj('dynamic_models', list_of_model_names_and_parameters, blocking, which_window)
425
-
426
- def set_dynamic_lines(self, list_of_lines, blocking=False, which_window=(0, 0)):
427
- self._send_pyobj('dynamic_lines', list_of_lines, blocking, which_window)
428
-
429
- def set_static_lines(self, list_of_lines, blocking=False, which_window=(0, 0)):
430
- self._send_pyobj('static_lines', list_of_lines, blocking, which_window)
431
-
432
- def set_titlebar(self, titlebar, blocking=False, which_window=(0, 0)):
433
- self._send_pyobj('titlebar', titlebar, blocking, which_window)
434
-
435
- def set_lighting_on(self, lighting_on, blocking=False, which_window=(0, 0)):
436
- self._send_pyobj('lighting_on', lighting_on, blocking, which_window)
437
-
438
- def set_autorecenter(self, autorecenter, blocking=False, which_window=(0, 0)):
439
- self._send_pyobj('autorecenter', autorecenter, blocking, which_window)
440
-
441
- def set_background_color(self, background_color, blocking=False, which_window=(0, 0)):
442
- assert(isinstance(background_color, np.ndarray))
443
- assert(background_color.size == 3)
444
- self._send_pyobj('background_color', background_color.flatten(), blocking, which_window)
445
-
446
- def get_keypress(self):
447
- return self.get_ui_event('get_keypress')
448
-
449
- def get_mouseclick(self):
450
- """Returns a mouse click event.
451
-
452
- .. note::
453
-
454
- the call is blocking the caller until an event is received
455
- """
456
- return self.get_ui_event('get_mouseclick')
457
-
458
- def get_event(self):
459
- return self.get_ui_event('get_event')
460
-
461
- def get_ui_event(self, event_id):
462
- context = zmq.Context.instance()
463
- server = context.socket(zmq.PULL)
464
- server.linger = 0
465
- port = server.bind_to_random_port('tcp://127.0.0.1',
466
- min_port=49152,
467
- max_port=65535,
468
- max_tries=100000)
469
- self._send_pyobj(event_id, port, blocking=True, which_window=(0, 0))
470
- result = server.recv_pyobj()
471
- server.close()
472
- return result
473
-
474
- background_color = property(fset=set_background_color,
475
- doc="Background color, as 3-element numpy array where 0 <= color <= 1.0.")
476
-
477
- dynamic_meshes = property(fset=set_dynamic_meshes,
478
- doc="List of meshes for dynamic display.")
479
- static_meshes = property(fset=set_static_meshes,
480
- doc="List of meshes for static display.")
481
- dynamic_models = property(fset=set_dynamic_models,
482
- doc="List of model names and parameters for dynamic display.")
483
-
484
- dynamic_lines = property(fset=set_dynamic_lines,
485
- doc="List of Lines for dynamic display.")
486
- static_lines = property(fset=set_static_lines,
487
- doc="List of Lines for static display.")
488
-
489
- titlebar = property(fset=set_titlebar,
490
- doc="Titlebar string.")
491
-
492
- def save_snapshot(self, path, blocking=False, which_window=(0, 0)):
493
- """Saves a snapshot of the current window into the specified file
494
-
495
- :param path: filename to which the current window content will be saved
496
- """
497
- self._send_pyobj('save_snapshot', path, blocking, which_window)
498
-
499
- def __del__(self):
500
- if not self.keepalive:
501
- self.p.terminate()
502
-
503
-
504
- class MeshViewerSingle(object):
505
-
506
- def __init__(self, x1_pct, y1_pct, width_pct, height_pct):
507
- assert(width_pct <= 1)
508
- assert(height_pct <= 1)
509
- self.dynamic_meshes = []
510
- self.static_meshes = []
511
- self.dynamic_models = []
512
- self.dynamic_lines = []
513
- self.static_lines = []
514
- self.lighting_on = True
515
- self.scape_models = {}
516
- self.x1_pct = x1_pct
517
- self.y1_pct = y1_pct
518
- self.width_pct = width_pct
519
- self.height_pct = height_pct
520
- self.autorecenter = True
521
-
522
- def get_dimensions(self):
523
- d = {}
524
- d['window_width'] = glutGet(GLUT_WINDOW_WIDTH)
525
- d['window_height'] = glutGet(GLUT_WINDOW_HEIGHT)
526
- d['subwindow_width'] = self.width_pct * d['window_width']
527
- d['subwindow_height'] = self.height_pct * d['window_height']
528
- d['subwindow_origin_x'] = self.x1_pct * d['window_width']
529
- d['subwindow_origin_y'] = self.y1_pct * d['window_height']
530
- return d
531
-
532
- def on_draw(self, transform, want_camera=False):
533
-
534
- d = self.get_dimensions()
535
-
536
- glViewport(
537
- int(d['subwindow_origin_x']),
538
- int(d['subwindow_origin_y']),
539
- int(d['subwindow_width']),
540
- int(d['subwindow_height']))
541
-
542
- glMatrixMode(GL_PROJECTION)
543
- glLoadIdentity()
544
-
545
- fov_degrees = 45.
546
- near = 1.0
547
- far = 100.
548
- ratio = float(d['subwindow_width']) / float(d['subwindow_height'])
549
- if d['subwindow_width'] < d['subwindow_height']:
550
- xt = np.tan(fov_degrees * np.pi / 180. / 2.0) * near
551
- yt = xt / ratio
552
- glFrustum(-xt, xt, -yt, yt, near, far)
553
- else:
554
- gluPerspective(fov_degrees, ratio, near, far)
555
-
556
- glMatrixMode(GL_MODELVIEW)
557
- glLoadIdentity()
558
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE)
559
-
560
- glTranslatef(0.0, 0.0, -6.0)
561
- # glTranslatef(0.0,0.0,-3.5)
562
-
563
- glPushMatrix()
564
- glMultMatrixf(transform)
565
- glColor3f(1.0, 0.75, 0.75)
566
-
567
- if self.autorecenter:
568
- camera = self.draw_primitives_recentered(want_camera=want_camera)
569
- else:
570
- if hasattr(self, 'current_center') and hasattr(self, 'current_scalefactor'):
571
- camera = self.draw_primitives(scalefactor=self.current_scalefactor, center=self.current_center)
572
- else:
573
- camera = self.draw_primitives(want_camera=want_camera)
574
-
575
- glPopMatrix()
576
-
577
- if want_camera:
578
- return camera
579
-
580
- def draw_primitives_recentered(self, want_camera=False):
581
- return self.draw_primitives(recenter=True, want_camera=want_camera)
582
-
583
- @staticmethod
584
- def set_shaders(m):
585
- VERTEX_SHADER = shaders.compileShader("""void main() {
586
- gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
587
- }""", GL_VERTEX_SHADER)
588
- FRAGMENT_SHADER = shaders.compileShader("""void main() {
589
- gl_FragColor = vec4( 0, 1, 0, 1 );
590
- }""", GL_FRAGMENT_SHADER)
591
- m.shaders = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
592
-
593
- @staticmethod
594
- def set_texture(m):
595
- texture_data = np.array(m.texture_image, dtype='int8')
596
- m.textureID = glGenTextures(1)
597
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
598
- glBindTexture(GL_TEXTURE_2D, m.textureID)
599
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_data.shape[1], texture_data.shape[0], 0, GL_BGR, GL_UNSIGNED_BYTE, texture_data.flatten())
600
- glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST) # must be GL_FASTEST, GL_NICEST or GL_DONT_CARE
601
- glGenerateMipmap(GL_TEXTURE_2D)
602
-
603
- @staticmethod
604
- def draw_mesh(m, lighting_on):
605
-
606
- # Supply vertices
607
- glEnableClientState(GL_VERTEX_ARRAY)
608
- m.vbo['v'].bind()
609
- glVertexPointer(3, GL_FLOAT, 0, m.vbo['v'])
610
- m.vbo['v'].unbind()
611
-
612
- # Supply normals
613
- if 'vn' in m.vbo.keys():
614
- glEnableClientState(GL_NORMAL_ARRAY)
615
- m.vbo['vn'].bind()
616
- glNormalPointer(GL_FLOAT, 0, m.vbo['vn'])
617
- m.vbo['vn'].unbind()
618
- else:
619
- glDisableClientState(GL_NORMAL_ARRAY)
620
-
621
- # Supply colors
622
- if 'vc' in m.vbo.keys():
623
- glEnableClientState(GL_COLOR_ARRAY)
624
- m.vbo['vc'].bind()
625
- glColorPointer(3, GL_FLOAT, 0, m.vbo['vc'])
626
- m.vbo['vc'].unbind()
627
- else:
628
- glDisableClientState(GL_COLOR_ARRAY)
629
-
630
- if ('vt' in m.vbo.keys()) and hasattr(m, 'textureID'):
631
- glEnable(GL_TEXTURE_2D)
632
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
633
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
634
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
635
- glBindTexture(GL_TEXTURE_2D, m.textureID)
636
-
637
- glEnableClientState(GL_TEXTURE_COORD_ARRAY)
638
- m.vbo['vt'].bind()
639
- glTexCoordPointer(2, GL_FLOAT, 0, m.vbo['vt'])
640
- m.vbo['vt'].unbind()
641
- else:
642
- glDisable(GL_TEXTURE_2D)
643
- glDisableClientState(GL_TEXTURE_COORD_ARRAY)
644
-
645
- # Draw
646
- if len(m.f) > 0:
647
- # ie if it is triangulated
648
- if lighting_on:
649
- glEnable(GL_LIGHTING)
650
- else:
651
- glDisable(GL_LIGHTING)
652
- glDrawElementsui(GL_TRIANGLES, np.arange(m.f.size, dtype=np.uint32))
653
- else:
654
- # not triangulated, so disable lighting
655
- glDisable(GL_LIGHTING)
656
- glPointSize(2)
657
- glDrawElementsui(GL_POINTS, np.arange(len(m.v), dtype=np.uint32))
658
- if hasattr(m, 'v_to_text'):
659
-
660
- glEnable(GL_TEXTURE_2D)
661
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
662
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
663
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
664
-
665
- # glEnable(GL_TEXTURE_GEN_S)
666
- # glEnable(GL_TEXTURE_GEN_T)
667
- # glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR)
668
- # glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR)
669
-
670
- bgcolor = np.array(glGetDoublev(GL_COLOR_CLEAR_VALUE))
671
- fgcolor = 1. - bgcolor
672
-
673
- from .lines import Lines
674
- sc = float(np.max(np.max(m.v, axis=0) - np.min(m.v, axis=0))) / 10.
675
-
676
- cur_mtx = np.linalg.pinv(glGetFloatv(GL_MODELVIEW_MATRIX).T)
677
- xdir = cur_mtx[:3, 0]
678
- ydir = cur_mtx[:3, 1]
679
-
680
- glEnable(GL_LINE_SMOOTH)
681
- glEnable(GL_BLEND)
682
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
683
-
684
- for vidx, text in m.v_to_text.items():
685
- pos0 = m.v[vidx].copy()
686
- pos1 = m.v[vidx].copy()
687
- if hasattr(m, 'vn'):
688
- pos1 += m.vn[vidx] * sc
689
- glLineWidth(5.0)
690
- ln = Lines(v=np.vstack((pos0, pos1)), e=np.array([[0, 1]]))
691
- glEnable(GL_LIGHTING)
692
- glColor3f(1. - 0.8, 1. - 0.8, 1. - 1.00)
693
- MeshViewerSingle.draw_lines(ln)
694
-
695
- glDisable(GL_LIGHTING)
696
-
697
- texture_id = get_textureid_with_text(text, bgcolor, fgcolor)
698
- glBindTexture(GL_TEXTURE_2D, texture_id)
699
-
700
- glPushMatrix()
701
- glTranslatef(pos1[0], pos1[1], pos1[2])
702
-
703
- dx = xdir * .10
704
- dy = ydir * .10
705
- if False:
706
- glBegin(GL_QUADS)
707
-
708
- glTexCoord2f(1., 0.)
709
- glVertex3f(*(+dx + dy))
710
-
711
- glTexCoord2f(1., 1.)
712
- glVertex3f(*(+dx - dy))
713
-
714
- glTexCoord2f(0., 1.)
715
- glVertex3f(*(-dx - dy))
716
-
717
- glTexCoord2f(0., 0.)
718
- glVertex3f(*(-dx + dy))
719
-
720
- # gluSphere(quadratic,0.05,32,32)
721
- glEnd()
722
- else:
723
- glBegin(GL_POLYGON)
724
-
725
- for r in np.arange(0, np.pi * 2., .01):
726
- glTexCoord2f(np.cos(r) / 2. + .5, np.sin(r) / 2. + .5)
727
- glVertex3f(*(dx * np.cos(r) + -dy * np.sin(r)))
728
-
729
- glEnd()
730
- glPopMatrix()
731
-
732
- #
733
- # glColor3f(bgcolor[0], bgcolor[1], bgcolor[2])
734
- # glRasterPos3f(pos1[0], pos1[1], pos1[2])
735
- # # print pos0
736
- # # print pos1
737
- #
738
- #
739
- # for t in text:
740
- # GLUT.glutBitmapCharacter(GLUT.GLUT_BITMAP_HELVETICA_18, ord(t))
741
-
742
- @staticmethod
743
- def draw_lines(ls):
744
- glDisableClientState(GL_NORMAL_ARRAY)
745
- glEnableClientState(GL_VERTEX_ARRAY)
746
- glLineWidth(3.0)
747
- allpts = ls.v[ls.e.flatten()].astype(np.float32)
748
- glVertexPointerf(allpts)
749
- if hasattr(ls, 'vc') or hasattr(ls, 'ec'):
750
- glEnableClientState(GL_COLOR_ARRAY)
751
- if hasattr(ls, 'vc'):
752
- glColorPointerf(ls.vc[ls.e.flatten()].astype(np.float32))
753
- else:
754
- clrs = np.ones((ls.e.shape[0] * 2, 3)) * np.repeat(ls.ec, 2, axis=0)
755
- glColorPointerf(clrs)
756
- else:
757
- glDisableClientState(GL_COLOR_ARRAY)
758
-
759
- glDisable(GL_LIGHTING)
760
- glDrawElementsui(GL_LINES, np.arange(len(allpts), dtype=np.uint32))
761
-
762
- def draw_primitives(self,
763
- scalefactor=1.0,
764
- center=[0.0, 0.0, 0.0],
765
- recenter=False,
766
- want_camera=False):
767
-
768
- # measure the bounding box of all our primitives, so that we can
769
- # recenter them in our field of view
770
- if recenter:
771
- all_meshes = self.static_meshes + self.dynamic_meshes
772
- all_lines = self.static_lines + self.dynamic_lines
773
-
774
- if (len(all_meshes) + len(all_lines)) == 0:
775
- if want_camera:
776
- return {'modelview_matrix': glGetDoublev(GL_MODELVIEW_MATRIX),
777
- 'projection_matrix': glGetDoublev(GL_PROJECTION_MATRIX),
778
- 'viewport': glGetIntegerv(GL_VIEWPORT)
779
- }
780
- else:
781
- return None
782
-
783
- for m in all_meshes:
784
- m.v = m.v.reshape((-1, 3))
785
-
786
- all_verts = np.concatenate(
787
- [m.v[m.f.flatten() if len(m.f) > 0 else np.arange(len(m.v))] for m in all_meshes] +
788
- [l.v[l.e.flatten()] for l in all_lines],
789
- axis=0)
790
-
791
- maximum = np.max(all_verts, axis=0)
792
- minimum = np.min(all_verts, axis=0)
793
- center = (maximum + minimum) / 2.
794
- scalefactor = (maximum - minimum) / 4.
795
- scalefactor = np.max(scalefactor)
796
- else:
797
- center = np.array(center)
798
- # for mesh in self.dynamic_meshes :
799
- # if mesh.f : mesh.reset_normals()
800
- all_meshes = self.static_meshes + self.dynamic_meshes
801
- all_lines = self.static_lines + self.dynamic_lines
802
- self.current_center = center
803
- self.current_scalefactor = scalefactor
804
-
805
- glMatrixMode(GL_MODELVIEW)
806
- glPushMatrix()
807
- # uncomment to add a default rotation (useful when automatically snapshoting kinect data
808
- # glRotate(220, 0.0, 1.0, 0.0)
809
-
810
- tf = np.identity(4, 'f') / scalefactor
811
- tf[:3, 3] = -center / scalefactor
812
- tf[3, 3] = 1
813
- cur_mtx = glGetFloatv(GL_MODELVIEW_MATRIX).T
814
-
815
- glLoadMatrixf(cur_mtx.dot(tf).T)
816
-
817
- if want_camera:
818
- result = {'modelview_matrix': glGetDoublev(GL_MODELVIEW_MATRIX),
819
- 'projection_matrix': glGetDoublev(GL_PROJECTION_MATRIX),
820
- 'viewport': glGetIntegerv(GL_VIEWPORT)
821
- }
822
- else:
823
- result = None
824
-
825
- for m in all_meshes:
826
- if not hasattr(m, 'vbo'):
827
- # Precompute vertex vbo
828
- fidxs = m.f.flatten() if len(m.f) > 0 else np.arange(len(m.v))
829
- allpts = m.v[fidxs].astype(np.float32).flatten()
830
- vbo = OpenGL.arrays.vbo.VBO(allpts)
831
- m.vbo = {'v': vbo}
832
-
833
- # Precompute normals vbo
834
- if hasattr(m, 'vn'):
835
- ns = m.vn.astype(np.float32)
836
- ns = ns[m.f.flatten(), :]
837
- m.vbo['vn'] = OpenGL.arrays.vbo.VBO(ns.flatten())
838
- elif hasattr(m, 'f') and m.f.size > 0:
839
- ns = TriNormals(m.v, m.f).reshape(-1, 3)
840
- ns = np.tile(ns, (1, 3)).reshape(-1, 3).astype(np.float32)
841
- m.vbo['vn'] = OpenGL.arrays.vbo.VBO(ns.flatten())
842
-
843
- # Precompute texture vbo
844
- if hasattr(m, 'ft') and (m.ft.size > 0):
845
- ftidxs = m.ft.flatten()
846
- data = m.vt[ftidxs].astype(np.float32)[:, 0:2]
847
- data[:, 1] = 1.0 - 1.0 * data[:, 1]
848
- m.vbo['vt'] = OpenGL.arrays.vbo.VBO(data)
849
-
850
- # Precompute color vbo
851
- if hasattr(m, 'vc'):
852
- data = m.vc[fidxs].astype(np.float32)
853
- m.vbo['vc'] = OpenGL.arrays.vbo.VBO(data)
854
- elif hasattr(m, 'fc'):
855
- data = np.tile(m.fc, (1, 3)).reshape(-1, 3).astype(np.float32)
856
- m.vbo['vc'] = OpenGL.arrays.vbo.VBO(data)
857
-
858
- for e in all_lines:
859
- self.draw_lines(e)
860
-
861
- for m in all_meshes:
862
- if hasattr(m, 'texture_image') and not hasattr(m, 'textureID'):
863
- self.set_texture(m)
864
- self.draw_mesh(m, self.lighting_on)
865
-
866
- glMatrixMode(GL_MODELVIEW)
867
- glPopMatrix()
868
-
869
- return result
870
-
871
-
872
- class MeshViewerRemote(object):
873
-
874
- def __init__(self,
875
- titlebar='Mesh Viewer',
876
- subwins_vert=1,
877
- subwins_horz=1,
878
- width=100,
879
- height=100):
880
-
881
- context = zmq.Context.instance()
882
- self.server = context.socket(zmq.PULL)
883
- self.server.linger = 0
884
-
885
- # Find a port to use. The standard set of "private" ports is 49152 through 65535, as seen in...
886
- # http://en.wikipedia.org/wiki/Port_(computer_networking)
887
- port = self.server.bind_to_random_port('tcp://127.0.0.1',
888
- min_port=49152,
889
- max_port=65535,
890
- max_tries=100000)
891
-
892
- # Print out our port so that our client can connect to us with it. Flush stdout immediately; otherwise
893
- # our client could wait forever.
894
- print('<PORT>%d</PORT>\n' % (port,))
895
- sys.stdout.flush()
896
-
897
- self.arcball = ArcBallT(width, height)
898
- self.transform = Matrix4fT()
899
- self.lastrot = Matrix3fT()
900
- self.thisrot = Matrix3fT()
901
- self.isdragging = False
902
- self.need_redraw = True
903
-
904
- self.mesh_viewers = [[MeshViewerSingle(float(c) / (subwins_horz),
905
- float(r) / (subwins_vert),
906
- 1. / subwins_horz,
907
- 1. / subwins_vert) for c in range(subwins_horz)] for r in range(subwins_vert)]
908
-
909
- self.tm_for_fps = 0.
910
- self.titlebar = titlebar
911
- self.activate(width, height)
912
-
913
- def snapshot(self, path):
914
- """
915
- Takes a snapshot of the meshviewer window and saves it to disc.
916
-
917
- :param path: path to save the snapshot at.
918
-
919
- .. note:: Requires the Pillow package to be installed.
920
-
921
- """
922
- from PIL import Image
923
- from OpenGL.GLU import GLubyte
924
-
925
- self.on_draw()
926
-
927
- x = 0
928
- y = 0
929
- width = glutGet(GLUT_WINDOW_WIDTH)
930
- height = glutGet(GLUT_WINDOW_HEIGHT)
931
-
932
- data = (GLubyte * (3 * width * height))(0)
933
- glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, data)
934
- image = Image.frombytes(mode="RGB", size=(width, height), data=data)
935
- image = image.transpose(Image.FLIP_TOP_BOTTOM)
936
-
937
- # Save image to disk
938
- image.save(path)
939
-
940
- def activate(self, width, height):
941
- glutInit(['mesh_viewer'])
942
- glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
943
- glutInitWindowSize(width, height)
944
- glutInitWindowPosition(0, 0)
945
- self.root_window_id = glutCreateWindow(self.titlebar)
946
- glutDisplayFunc(self.on_draw)
947
-
948
- glutTimerFunc(100, self.checkQueue, 0)
949
- glutReshapeFunc(self.on_resize_window)
950
-
951
- glutKeyboardFunc(self.on_keypress)
952
- glutMouseFunc(self.on_click)
953
- glutMotionFunc(self.on_drag)
954
-
955
- # for r, lst in enumerate(self.mesh_viewers):
956
- # for c, mv in enumerate(lst):
957
- # mv.glut_window_id = glutCreateSubWindow(self.root_window_id, c*width/len(lst), r*height/len(self.mesh_viewers), width/len(lst), height/len(self.mesh_viewers))
958
-
959
- glutDisplayFunc(self.on_draw)
960
- self.init_opengl()
961
-
962
- glutMainLoop() # won't return until process is killed
963
-
964
- def on_drag(self, cursor_x, cursor_y):
965
- """ Mouse cursor is moving
966
- Glut calls this function (when mouse button is down)
967
- and pases the mouse cursor postion in window coords as the mouse moves.
968
- """
969
- from .geometry.rodrigues import rodrigues
970
- if (self.isdragging):
971
- mouse_pt = Point2fT(cursor_x, cursor_y)
972
- ThisQuat = self.arcball.drag(mouse_pt) # // Update End Vector And Get Rotation As Quaternion
973
- self.thisrot = Matrix3fSetRotationFromQuat4f(ThisQuat) # // Convert Quaternion Into Matrix3fT
974
- # Use correct Linear Algebra matrix multiplication C = A * B
975
- self.thisrot = Matrix3fMulMatrix3f(self.lastrot, self.thisrot) # // Accumulate Last Rotation Into This One
976
-
977
- # make sure it is a rotation
978
- self.thisrot = rodrigues(rodrigues(self.thisrot)[0])[0]
979
- self.transform = Matrix4fSetRotationFromMatrix3f(self.transform, self.thisrot) # // Set Our Final Transform's Rotation From This One
980
- glutPostRedisplay()
981
- return
982
-
983
- # The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)
984
- def on_keypress(self, *args):
985
- key = args[0]
986
- if hasattr(self, 'event_port'):
987
- self.keypress_port = self.event_port
988
- del self.event_port
989
- if hasattr(self, 'keypress_port'):
990
- client = zmq.Context.instance().socket(zmq.PUSH)
991
- client.connect('tcp://127.0.0.1:%d' % (self.keypress_port))
992
- client.send_pyobj({'event_type': 'keyboard', 'key': key})
993
- del self.keypress_port
994
-
995
- def on_click(self, button, button_state, cursor_x, cursor_y):
996
- """ Mouse button clicked.
997
- Glut calls this function when a mouse button is
998
- clicked or released.
999
- """
1000
-
1001
- self.isdragging = False
1002
- # if (button == GLUT_RIGHT_BUTTON and button_state == GLUT_UP):
1003
- # # Right button click
1004
- # self.lastrot = Matrix3fSetIdentity (); # // Reset Rotation
1005
- # self.thisrot = Matrix3fSetIdentity (); # // Reset Rotation
1006
- # self.transform = Matrix4fSetRotationFromMatrix3f (self.transform, self.thisrot); # // Reset Rotation
1007
- if (button == GLUT_LEFT_BUTTON and button_state == GLUT_UP):
1008
- # Left button released
1009
- self.lastrot = copy.copy(self.thisrot) # Set Last Static Rotation To Last Dynamic One
1010
-
1011
- elif (button == GLUT_LEFT_BUTTON and button_state == GLUT_DOWN):
1012
- # Left button clicked down
1013
- self.lastrot = copy.copy(self.thisrot) # Set Last Static Rotation To Last Dynamic One
1014
- self.isdragging = True # // Prepare For Dragging
1015
- mouse_pt = Point2fT(cursor_x, cursor_y)
1016
- self.arcball.click(mouse_pt) # Update Start Vector And Prepare For Dragging
1017
-
1018
- elif (button == GLUT_RIGHT_BUTTON and button_state == GLUT_DOWN):
1019
- # If a mouse click location was requested, return it to caller
1020
- if hasattr(self, 'event_port'):
1021
- self.mouseclick_port = self.event_port
1022
- del self.event_port
1023
- if hasattr(self, 'mouseclick_port'):
1024
- self.send_mouseclick_to_caller(cursor_x, cursor_y)
1025
-
1026
- elif (button == GLUT_MIDDLE_BUTTON and button_state == GLUT_DOWN):
1027
- # If a mouse click location was requested, return it to caller
1028
- if hasattr(self, 'event_port'):
1029
- self.mouseclick_port = self.event_port
1030
- del self.event_port
1031
- if hasattr(self, 'mouseclick_port'):
1032
- self.send_mouseclick_to_caller(cursor_x, cursor_y, button='middle')
1033
-
1034
- glutPostRedisplay()
1035
-
1036
- def send_mouseclick_to_caller(self,
1037
- cursor_x,
1038
- cursor_y,
1039
- button='right'):
1040
-
1041
- client = zmq.Context.instance().socket(zmq.PUSH)
1042
- client.connect('tcp://127.0.0.1:%d' % (self.mouseclick_port))
1043
- cameras = self.on_draw(want_cameras=True)
1044
-
1045
- window_height = glutGet(GLUT_WINDOW_HEIGHT)
1046
- depth_value = glReadPixels(cursor_x, window_height - cursor_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT)
1047
-
1048
- pyobj = {
1049
- 'event_type': 'mouse_click_%sbutton' % button,
1050
- 'u': None, 'v': None,
1051
- 'x': None, 'y': None, 'z': None,
1052
- 'subwindow_row': None,
1053
- 'subwindow_col': None
1054
- }
1055
-
1056
- for subwin_row, camera_list in enumerate(cameras):
1057
- for subwin_col, camera in enumerate(camera_list):
1058
-
1059
- # test for out-of-bounds
1060
- if cursor_x < camera['viewport'][0]:
1061
- continue
1062
- if cursor_x > (camera['viewport'][0] + camera['viewport'][2]):
1063
- continue
1064
- if window_height - cursor_y < camera['viewport'][1]:
1065
- continue
1066
- if window_height - cursor_y > (camera['viewport'][1] + camera['viewport'][3]):
1067
- continue
1068
-
1069
- xx, yy, zz = gluUnProject(
1070
- cursor_x, window_height - cursor_y, depth_value,
1071
- camera['modelview_matrix'],
1072
- camera['projection_matrix'],
1073
- camera['viewport'])
1074
-
1075
- pyobj = {
1076
- 'event_type': 'mouse_click_%sbutton' % button,
1077
- 'u': cursor_x - camera['viewport'][0], 'v': window_height - cursor_y - camera['viewport'][1],
1078
- 'x': xx, 'y': yy, 'z': zz,
1079
- 'which_subwindow': (subwin_row, subwin_col)
1080
- }
1081
-
1082
- client.send_pyobj(pyobj)
1083
- del self.mouseclick_port
1084
-
1085
- def on_draw(self, want_cameras=False):
1086
- # sys.stderr.write('fps: %.2e\n' % (1. / (time.time() - self.tm_for_fps)))
1087
- self.tm_for_fps = time.time()
1088
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
1089
- cameras = []
1090
- for mvl in self.mesh_viewers:
1091
- cameras.append([])
1092
- for mv in mvl:
1093
- cameras[-1].append(mv.on_draw(self.transform, want_cameras))
1094
- glFlush() # Flush The GL Rendering Pipeline
1095
- glutSwapBuffers()
1096
- self.need_redraw = False
1097
- if want_cameras:
1098
- return cameras
1099
-
1100
- def on_resize_window(self, Width, Height):
1101
- """Reshape The Window When It's Moved Or Resized"""
1102
- self.arcball.setBounds(Width, Height) # //*NEW* Update mouse bounds for arcball
1103
- return
1104
-
1105
- def handle_request(self, request):
1106
- label = request['label']
1107
- obj = request['obj']
1108
- w = request['which_window']
1109
- mv = self.mesh_viewers[w[0]][w[1]]
1110
-
1111
- # Handle each type of request.
1112
- # Some requests require a redraw, and
1113
- # some don't.
1114
- if label == 'dynamic_meshes':
1115
- mv.dynamic_meshes = obj
1116
- self.need_redraw = True
1117
- elif label == 'dynamic_models':
1118
- mv.dynamic_models = obj
1119
- self.need_redraw = True
1120
- elif label == 'static_meshes':
1121
- mv.static_meshes = obj
1122
- self.need_redraw = True
1123
- elif label == 'dynamic_lines':
1124
- mv.dynamic_lines = obj
1125
- self.need_redraw = True
1126
- elif label == 'static_lines':
1127
- mv.static_lines = obj
1128
- self.need_redraw = True
1129
- elif label == 'autorecenter':
1130
- mv.autorecenter = obj
1131
- self.need_redraw = True
1132
- elif label == 'titlebar':
1133
- assert(isinstance(obj, str))
1134
- self.titlebar = obj
1135
- glutSetWindowTitle(obj)
1136
- elif label == 'lighting_on':
1137
- mv.lighting_on = obj
1138
- self.need_redraw = True
1139
- elif label == 'background_color':
1140
- glClearColor(obj[0], obj[1], obj[2], 1.0)
1141
- self.need_redraw = True
1142
- elif label == 'save_snapshot': # redraws for itself
1143
- assert(isinstance(obj, str))
1144
- self.snapshot(obj)
1145
- elif label == 'get_keypress':
1146
- self.keypress_port = obj
1147
- elif label == 'get_mouseclick':
1148
- self.mouseclick_port = obj
1149
- elif label == 'get_event':
1150
- self.event_port = obj
1151
- else:
1152
- return False # can't handle this request string
1153
-
1154
- return True # handled the request string
1155
-
1156
- def checkQueue(self, unused_timer_id):
1157
- glutTimerFunc(20, self.checkQueue, 0)
1158
-
1159
- # if True: # spinning
1160
- # w_whole_window = glutGet(GLUT_WINDOW_WIDTH)
1161
- # h_whole_window = glutGet(GLUT_WINDOW_HEIGHT)
1162
- # center_x = w_whole_window/2
1163
- # center_y = h_whole_window/2
1164
- # self.on_click(GLUT_LEFT_BUTTON, GLUT_DOWN, center_x, center_y)
1165
- # self.on_drag(center_x+2, center_y)
1166
-
1167
- try:
1168
- request = self.server.recv_pyobj(zmq.NOBLOCK)
1169
- except zmq.ZMQError as e:
1170
- if e.errno != zmq.EAGAIN:
1171
- raise # something wrong besides empty queue
1172
- return # empty queue, no problem
1173
-
1174
- if not request:
1175
- return
1176
-
1177
- while (request):
1178
- task_completion_time = time.time()
1179
- if not self.handle_request(request):
1180
- raise Exception('Unknown command string: %s' % (request['label']))
1181
- task_completion_time = time.time() - task_completion_time
1182
-
1183
- if 'port' in request: # caller wants confirmation
1184
- port = request['port']
1185
- client = zmq.Context.instance().socket(zmq.PUSH)
1186
- client.connect('tcp://127.0.0.1:%d' % (port))
1187
- client.send_pyobj(task_completion_time)
1188
- try:
1189
- request = self.server.recv_pyobj(zmq.NOBLOCK)
1190
- except zmq.ZMQError as e:
1191
- if e.errno != zmq.EAGAIN:
1192
- raise
1193
- request = None
1194
-
1195
- if self.need_redraw:
1196
- glutPostRedisplay()
1197
-
1198
- def init_opengl(self):
1199
- """A general OpenGL initialization function. Sets all of the initial parameters.
1200
-
1201
- We call this right after our OpenGL window is created.
1202
- """
1203
-
1204
- glClearColor(0.0, 0.0, 0.0, 1.0) # This Will Clear The Background Color To Black
1205
- glClearDepth(1.0) # Enables Clearing Of The Depth Buffer
1206
- glDepthFunc(GL_LEQUAL) # The Type Of Depth Test To Do
1207
- glEnable(GL_DEPTH_TEST) # Enables Depth Testing
1208
- glShadeModel(GL_SMOOTH)
1209
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) # Really Nice Perspective Calculations
1210
-
1211
- glEnable(GL_LIGHT0)
1212
- glEnable(GL_LIGHTING)
1213
-
1214
- glEnable(GL_COLOR_MATERIAL)
1215
- glEnable(GL_NORMALIZE) # important since we rescale the modelview matrix
1216
-
1217
- return True
1218
-
1219
-
1220
- if __name__ == '__main__':
1221
-
1222
- # Windows specific: see http://docs.python.org/2/library/multiprocessing.html#multiprocessing.freeze_support
1223
- freeze_support()
1224
-
1225
- if len(sys.argv) == 2 and sys.argv[1] == 'TEST_FOR_OPENGL':
1226
- _test_for_opengl()
1227
-
1228
- elif len(sys.argv) > 2:
1229
- m = MeshViewerRemote(titlebar=sys.argv[1],
1230
- subwins_vert=int(sys.argv[2]),
1231
- subwins_horz=int(sys.argv[3]),
1232
- width=int(sys.argv[4]),
1233
- height=int(sys.argv[5]))
1234
-
1235
- else:
1236
- print("#" * 10)
1237
- print('Usage:')
1238
- print("python -m %s.%s arguments" % (__package__, os.path.splitext(os.path.basename(__file__))[0]))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/processing.py DELETED
@@ -1,186 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2013 Max Planck Society. All rights reserved.
5
- # Created by Matthew Loper on 2013-02-20.
6
-
7
-
8
- """
9
- Mesh processing backend
10
- =======================
11
-
12
- """
13
-
14
- import numpy as np
15
-
16
-
17
- def reset_normals(self, face_to_verts_sparse_matrix=None, reset_face_normals=False):
18
- self.vn = self.estimate_vertex_normals(face_to_verts_sparse_matrix=None)
19
- if reset_face_normals:
20
- self.fn = self.f.copy()
21
- return self
22
-
23
-
24
- def reset_face_normals(self):
25
- if not hasattr(self, 'vn'):
26
- self.reset_normals()
27
- self.fn = self.f
28
- return self
29
-
30
-
31
- def uniquified_mesh(self):
32
- """This function returns a copy of the mesh in which vertices are copied such that
33
- each vertex appears in only one face, and hence has only one texture"""
34
- from mesh import Mesh
35
- new_mesh = Mesh(v=self.v[self.f.flatten()], f=np.array(range(len(self.f.flatten()))).reshape(-1, 3))
36
-
37
- if not hasattr(self, 'vn'):
38
- self.reset_normals()
39
- new_mesh.vn = self.vn[self.f.flatten()]
40
-
41
- if hasattr(self, 'vt'):
42
- new_mesh.vt = self.vt[self.ft.flatten()]
43
- new_mesh.ft = new_mesh.f.copy()
44
- return new_mesh
45
-
46
-
47
- def keep_vertices(self, keep_list):
48
- trans = dict((v, i) for i, v in enumerate(keep_list))
49
- trans_f = np.array([trans[v] if v in trans else -1 for row in self.f for v in row], dtype=np.uint32).reshape(-1, 3)
50
- if hasattr(self, 'vn') and self.vn.shape[0] == self.vn.shape[0]:
51
- self.vn = self.vn.reshape(-1, 3)[keep_list]
52
- if hasattr(self, 'vc') and self.vc.shape[0] == self.v.shape[0]:
53
- self.vc = self.vc.reshape(-1, 3)[keep_list]
54
- if hasattr(self, 'landm_raw_xyz'):
55
- self.recompute_landmark_indices()
56
-
57
- self.v = self.v.reshape(-1, 3)[keep_list]
58
- self.f = trans_f[(trans_f != np.uint32(-1)).all(axis=1)]
59
- return self
60
-
61
-
62
- def point_cloud(self):
63
- from .mesh import Mesh
64
- return Mesh(v=self.v, f=[], vc=self.vc) if hasattr(self, 'vc') else Mesh(v=self.v, f=[])
65
-
66
-
67
- def remove_faces(self, face_indices_to_remove):
68
-
69
- def arr_replace(arr_in, lookup_dict):
70
- arr_out = arr_in.copy()
71
- for k, v in lookup_dict.iteritems():
72
- arr_out[arr_in == k] = v
73
- return arr_out
74
-
75
- f = np.delete(self.f, face_indices_to_remove, 0)
76
- v2keep = np.unique(f)
77
- self.v = self.v[v2keep]
78
- self.f = arr_replace(f, dict((v, i) for i, v in enumerate(v2keep)))
79
-
80
- if hasattr(self, 'fc'):
81
- self.fc = np.delete(self.fc, face_indices_to_remove, 0)
82
- if hasattr(self, 'vn') and self.vn.shape[0] == self.vn.shape[0]:
83
- self.vn = self.vn.reshape(-1, 3)[v2keep]
84
- if hasattr(self, 'vc') and self.vc.shape[0] == self.v.shape[0]:
85
- self.vc = self.vc.reshape(-1, 3)[v2keep]
86
- if hasattr(self, 'landm_raw_xyz'):
87
- self.recompute_landmark_indices()
88
-
89
- if hasattr(self, 'ft'):
90
- ft = np.delete(self.ft, face_indices_to_remove, 0)
91
- vt2keep = np.unique(ft)
92
- self.vt = self.vt[vt2keep]
93
- self.ft = arr_replace(ft, dict((v, i) for i, v in enumerate(vt2keep)))
94
-
95
- return self
96
-
97
-
98
- def flip_faces(self):
99
- self.f = self.f.copy()
100
- for i in range(len(self.f)):
101
- self.f[i] = self.f[i][::-1]
102
- if hasattr(self, 'ft'):
103
- for i in range(len(self.f)):
104
- self.ft[i] = self.ft[i][::-1]
105
- return self
106
-
107
-
108
- def scale_vertices(self, scale_factor):
109
- self.v *= scale_factor
110
- return self
111
-
112
-
113
- def rotate_vertices(self, rotation_matrix):
114
- import cv2
115
- rotation_matrix = np.matrix(cv2.Rodrigues(np.array(rotation_matrix))[0] if (np.array(rotation_matrix).shape != (3, 3)) else rotation_matrix)
116
- self.v = np.array(self.v * rotation_matrix.T)
117
- return self
118
-
119
-
120
- def translate_vertices(self, translation):
121
- self.v += translation
122
- return self
123
-
124
-
125
- def subdivide_triangles(self):
126
- new_faces = []
127
- new_vertices = self.v.copy()
128
- for face in self.f:
129
- face_vertices = np.array([self.v[face[0], :], self.v[face[1], :], self.v[face[2], :]])
130
- new_vertex = np.mean(face_vertices, axis=0)
131
- new_vertices = np.vstack([new_vertices, new_vertex])
132
- new_vertex_index = len(new_vertices) - 1
133
- if len(new_faces):
134
- new_faces = np.vstack([new_faces, [face[0], face[1], new_vertex_index], [face[1], face[2], new_vertex_index], [face[2], face[0], new_vertex_index]])
135
- else:
136
- new_faces = np.array([[face[0], face[1], new_vertex_index], [face[1], face[2], new_vertex_index], [face[2], face[0], new_vertex_index]])
137
- self.v = new_vertices
138
- self.f = new_faces
139
-
140
- if hasattr(self, 'vt'):
141
- new_ft = []
142
- new_texture_coordinates = self.vt.copy()
143
- for face_texture in self.ft:
144
- face_texture_coordinates = np.array([self.vt[face_texture[0], :], self.vt[face_texture[1], :], self.vt[face_texture[2], :]])
145
- new_texture_coordinate = np.mean(face_texture_coordinates, axis=0)
146
- new_texture_coordinates = np.vstack([new_texture_coordinates, new_texture_coordinate])
147
- new_texture_index = len(new_texture_coordinates) - 1
148
- if len(new_ft):
149
- new_ft = np.vstack([new_ft, [face_texture[0], face_texture[1], new_texture_index], [face_texture[1], face_texture[2], new_texture_index], [face_texture[2], face_texture[0], new_texture_index]])
150
- else:
151
- new_ft = np.array([[face_texture[0], face_texture[1], new_texture_index], [face_texture[1], face_texture[2], new_texture_index], [face_texture[2], face_texture[0], new_texture_index]])
152
- self.vt = new_texture_coordinates
153
- self.ft = new_ft
154
- return self
155
-
156
-
157
- def concatenate_mesh(self, mesh):
158
- if len(self.v) == 0:
159
- self.f = mesh.f.copy()
160
- self.v = mesh.v.copy()
161
- self.vc = mesh.vc.copy() if hasattr(mesh, 'vc') else None
162
- elif len(mesh.v):
163
- self.f = np.concatenate([self.f, mesh.f.copy() + len(self.v)])
164
- self.v = np.concatenate([self.v, mesh.v])
165
- self.vc = np.concatenate([self.vc, mesh.vc]) if (hasattr(mesh, 'vc') and hasattr(self, 'vc')) else None
166
- return self
167
-
168
-
169
- # new_ordering specifies the new index of each vertex. If new_ordering[i] = j,
170
- # vertex i should now be the j^th vertex. As such, each entry in new_ordering should be unique.
171
- def reorder_vertices(self, new_ordering, new_normal_ordering=None):
172
- if new_normal_ordering is None:
173
- new_normal_ordering = new_ordering
174
- inverse_ordering = np.zeros(len(new_ordering), dtype=int)
175
- for i, j in enumerate(new_ordering):
176
- inverse_ordering[j] = i
177
- inverse_normal_ordering = np.zeros(len(new_normal_ordering), dtype=int)
178
- for i, j in enumerate(new_normal_ordering):
179
- inverse_normal_ordering[j] = i
180
- self.v = self.v[inverse_ordering]
181
- if hasattr(self, 'vn'):
182
- self.vn = self.vn[inverse_normal_ordering]
183
- for i in range(len(self.f)):
184
- self.f[i] = np.array([new_ordering[vertex_index] for vertex_index in self.f[i]])
185
- if hasattr(self, 'fn'):
186
- self.fn[i] = np.array([new_normal_ordering[normal_index] for normal_index in self.fn[i]])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/ressources/Arial.ttf DELETED
Binary file (773 kB)
 
mesh-fix-MSVC_compilation/mesh/search.py DELETED
@@ -1,100 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Created by Matthew Loper on 2013-02-20.
5
- # Copyright (c) 2013 MPI. All rights reserved.
6
-
7
- """
8
- Searching and lookup of geometric entities
9
- ==========================================
10
-
11
- """
12
-
13
-
14
- import numpy as np
15
-
16
- __all__ = ['AabbTree', 'AabbNormalsTree', 'ClosestPointTree', 'CGALClosestPointTree']
17
-
18
-
19
- class AabbTree(object):
20
- """Encapsulates an AABB (Axis Aligned Bounding Box) Tree"""
21
- def __init__(self, m):
22
- from . import spatialsearch
23
- # this shit return NULL
24
- self.cpp_handle = spatialsearch.aabbtree_compute(m.v.astype(np.float64).copy(order='C'), m.f.astype(np.uint32).copy(order='C'))
25
-
26
- def nearest(self, v_samples, nearest_part=False):
27
- "nearest_part tells you whether the closest point in triangle abc is in the interior (0), on an edge (ab:1,bc:2,ca:3), or a vertex (a:4,b:5,c:6)"
28
- from . import spatialsearch
29
- f_idxs, f_part, v = spatialsearch.aabbtree_nearest(self.cpp_handle, np.array(v_samples, dtype=np.float64, order='C'))
30
- return (f_idxs, f_part, v) if nearest_part else (f_idxs, v)
31
-
32
- def nearest_alongnormal(self, points, normals):
33
- from . import spatialsearch
34
- distances, f_idxs, v = spatialsearch.aabbtree_nearest_alongnormal(self.cpp_handle,
35
- points.astype(np.float64),
36
- normals.astype(np.float64))
37
- return (distances, f_idxs, v)
38
-
39
- def intersections_indices(self, q_v, q_f):
40
- '''
41
- Given a set of query vertices and faces, the function computes which intersect the mesh
42
- A list with the indices in q_f is returned
43
- @param q_v The query vertices (array of 3xN float values)
44
- @param q_f The query faces (array 3xF integer values)
45
- '''
46
- import spatialsearch
47
- return spatialsearch.aabbtree_intersections_indices(self.cpp_handle,
48
- q_v.astype(np.float64),
49
- q_f.astype(np.uint32))
50
-
51
-
52
- class ClosestPointTree(object):
53
- """Provides nearest neighbor search for a cloud of vertices (i.e. triangles are not used)"""
54
- def __init__(self, m):
55
- from scipy.spatial import KDTree
56
- self.v = m.v
57
- self.kdtree = KDTree(self.v)
58
-
59
- def nearest(self, v_samples):
60
- (distances, indices) = zip(*[self.kdtree.query(v) for v in v_samples])
61
- return (indices, distances)
62
-
63
- def nearest_vertices(self, v_samples):
64
- (distances, indices) = zip(*[self.kdtree.query(v) for v in v_samples])
65
- return self.v[indices]
66
-
67
-
68
- class CGALClosestPointTree(object):
69
- """Encapsulates an AABB (Axis Aligned Bounding Box) Tree """
70
- def __init__(self, m):
71
- from . import spatialsearch
72
- self.v = m.v
73
- n = m.v.shape[0]
74
- faces = np.vstack([np.array(range(n)), np.array(range(n)) + n, np.array(range(n)) + 2 * n]).T
75
- eps = 0.000000000001
76
- self.cpp_handle = spatialsearch.aabbtree_compute(np.vstack([m.v + eps * np.array([1.0, 0.0, 0.0]), m.v + eps * np.array([0.0, 1.0, 0.0]), m.v - eps * np.array([1.0, 1.0, 0.0])]).astype(np.float64).copy(order='C'), faces.astype(np.uint32).copy(order='C'))
77
-
78
- def nearest(self, v_samples):
79
- from . import spatialsearch
80
- f_idxs, f_part, v = spatialsearch.aabbtree_nearest(self.cpp_handle, np.array(v_samples, dtype=np.float64, order='C'))
81
- return (f_idxs.flatten(), (np.sum(((self.v[f_idxs.flatten()] - v_samples) ** 2.0), axis=1) ** 0.5).flatten())
82
-
83
- def nearest_vertices(self, v_samples):
84
- from . import spatialsearch
85
- f_idxs, f_part, v = spatialsearch.aabbtree_nearest(self.cpp_handle, np.array(v_samples, dtype=np.float64, order='C'))
86
- return self.v[f_idxs.flatten()]
87
-
88
-
89
- class AabbNormalsTree(object):
90
- def __init__(self, m):
91
- # the weight of the normals cosine is proportional to the std of the vertices
92
- # the best point can be translated up to 2*eps because of the normals
93
- from . import aabb_normals
94
- eps = 0.1 # np.std(m.v)#0
95
- self.tree_handle = aabb_normals.aabbtree_n_compute(m.v, m.f.astype(np.uint32).copy(), eps)
96
-
97
- def nearest(self, v_samples, n_samples):
98
- from . import aabb_normals
99
- closest_tri, closest_p = aabb_normals.aabbtree_n_nearest(self.tree_handle, v_samples, n_samples)
100
- return (closest_tri, closest_p)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/serialization/__init__.py DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2016 Max Planck Society. All rights reserved.
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/serialization/serialization.py DELETED
@@ -1,443 +0,0 @@
1
- #!/usr/bin/env python
2
- # encoding: utf-8
3
-
4
- # Copyright (c) 2013 Max Planck Society. All rights reserved.
5
- # Created by Matthew Loper on 2013-02-20.
6
-
7
- import re
8
- import os
9
- import sys
10
- import numpy as np
11
-
12
- from ..errors import SerializationError
13
-
14
- """
15
- serialization.py
16
-
17
-
18
- """
19
-
20
- __all__ = ['load_from_obj', 'load_from_obj_cpp', 'write_obj', 'write_mtl',
21
- 'write_json', 'write_three_json',
22
- 'set_landmark_indices_from_ppfile', 'set_landmark_indices_from_lmrkfile',
23
- 'load_from_ply', 'load_from_file']
24
-
25
- # import os.path
26
-
27
-
28
- def load_from_obj(self, filename):
29
- v = []
30
- f = []
31
- ft = []
32
- fn = []
33
- vt = []
34
- vn = []
35
- vc = []
36
- segm = dict()
37
- landm_raw_xyz = dict()
38
- currSegm = ''
39
- currLandm = ''
40
- with open(filename, 'r', buffering=2 ** 10) as fp:
41
- for line in fp:
42
- line = line.split()
43
- if len(line) > 0:
44
- if line[0] == 'v':
45
- v.append([float(x) for x in line[1:4]])
46
- if len(line) == 7:
47
- vc.append([float(x) for x in line[4:]])
48
- if currLandm:
49
- landm_raw_xyz[currLandm] = v[-1]
50
- currLandm = ''
51
- elif line[0] == 'vt':
52
- vt.append([float(x) for x in line[1:]])
53
- elif line[0] == 'vn':
54
- vn.append([float(x) for x in line[1:]])
55
- elif line[0] == 'f':
56
- faces = [x.split('/') for x in line[1:]]
57
- for iV in range(1, len(faces) - 1): # trivially triangulate faces
58
- f.append([int(faces[0][0]), int(faces[iV][0]), int(faces[iV + 1][0])])
59
- if (len(faces[0]) > 1) and faces[0][1]:
60
- ft.append([int(faces[0][1]), int(faces[iV][1]), int(faces[iV + 1][1])])
61
- if (len(faces[0]) > 2) and faces[0][2]:
62
- fn.append([int(faces[0][2]), int(faces[iV][2]), int(faces[iV + 1][2])])
63
- if currSegm:
64
- segm[currSegm].append(len(f) - 1)
65
- elif line[0] == 'g':
66
- currSegm = line[1]
67
- if currSegm not in segm.keys():
68
- segm[currSegm] = []
69
- elif line[0] == '#landmark':
70
- currLandm = line[1]
71
- elif line[0] == 'mtllib':
72
- self.materials_filepath = os.path.join(os.path.dirname(filename), line[1])
73
- self.materials_file = open(self.materials_filepath, 'r').readlines()
74
-
75
- self.v = np.array(v)
76
- self.f = np.array(f) - 1
77
- if vt:
78
- self.vt = np.array(vt)
79
- if vn:
80
- self.vn = np.array(vn)
81
- if vc:
82
- self.vc = np.array(vc)
83
- if ft:
84
- self.ft = np.array(ft) - 1
85
- if fn:
86
- self.fn = np.array(fn) - 1
87
- self.segm = segm
88
- self.landm_raw_xyz = landm_raw_xyz
89
- self.recompute_landmark_indices()
90
-
91
- if hasattr(self, 'materials_file'):
92
- for line in self.materials_file:
93
- if line and line.split() and line.split()[0] == 'map_Ka':
94
- self.texture_filepath = os.path.abspath(os.path.join(os.path.dirname(filename), line.split()[1]))
95
-
96
-
97
- def load_from_obj_cpp(self, filename):
98
- from .loadobj import loadobj
99
- if sys.version_info[:2] == (2, 6):
100
- from OrderedDict import OrderedDict
101
- else:
102
- from collections import OrderedDict
103
-
104
- v, vt, vn, f, ft, fn, mtl_path, landm, segm = loadobj(filename)
105
- if v.size != 0:
106
- self.v = v
107
- if f.size != 0:
108
- self.f = f
109
- if vn.size != 0:
110
- self.vn = vn
111
- if vt.size != 0:
112
- self.vt = vt
113
- if fn.size != 0:
114
- self.fn = fn
115
- if ft.size != 0:
116
- self.ft = ft
117
- if segm:
118
- self.segm = OrderedDict([(k, v if type(v) is list else v.tolist()) for k, v in segm.items()])
119
- if mtl_path:
120
- try:
121
- self.materials_filepath = os.path.join(os.path.dirname(filename), mtl_path.strip())
122
- self.materials_file = file(self.materials_filepath, 'r').readlines()
123
- except:
124
- self.materials_filepath = None
125
- if hasattr(self, 'materials_file'):
126
- for line in self.materials_file:
127
- if line and line.split() and line.split()[0] == 'map_Ka':
128
- self.texture_filepath = os.path.abspath(os.path.join(os.path.dirname(filename), line.split()[1]))
129
- if landm:
130
- self.landm = landm
131
- self.recompute_landmark_xyz()
132
-
133
-
134
- def write_obj(self, filename, flip_faces=False, group=False, comments=None):
135
- if os.path.dirname(filename) and not os.path.exists(os.path.dirname(filename)):
136
- os.makedirs(os.path.dirname(filename))
137
-
138
- ff = -1 if flip_faces else 1
139
-
140
- def write_face_to_obj_file(face_index, obj_file):
141
- vertex_indices = self.f[face_index][::ff] + 1
142
-
143
- if hasattr(self, 'ft'):
144
- texture_indices = self.ft[face_index][::ff] + 1
145
- if not hasattr(self, 'fn'):
146
- self.reset_face_normals()
147
- normal_indices = self.fn[face_index][::ff] + 1
148
- obj_file.write('f %d/%d/%d %d/%d/%d %d/%d/%d\n' % tuple(
149
- np.array([vertex_indices, texture_indices, normal_indices]).T.flatten()))
150
- elif hasattr(self, 'fn'):
151
- normal_indices = self.fn[face_index][::ff] + 1
152
- obj_file.write('f %d//%d %d//%d %d//%d\n' % tuple(np.array([vertex_indices, normal_indices]).T.flatten()))
153
- else:
154
- obj_file.write('f %d %d %d\n' % tuple(vertex_indices))
155
-
156
- with open(filename, 'w') as fi:
157
- if comments is not None:
158
- if isinstance(comments, str):
159
- comments = [comments]
160
- for comment in comments:
161
- for line in comment.split("\n"):
162
- fi.write("# %s\n" % line)
163
-
164
- if hasattr(self, 'texture_filepath'):
165
- outfolder = os.path.dirname(filename)
166
- outbase = os.path.splitext(os.path.basename(filename))[0]
167
- mtlpath = outbase + '.mtl'
168
- fi.write('mtllib %s\n' % mtlpath)
169
- from shutil import copyfile
170
- texture_name = outbase + os.path.splitext(self.texture_filepath)[1]
171
- if os.path.abspath(self.texture_filepath) != os.path.abspath(os.path.join(outfolder, texture_name)):
172
- copyfile(self.texture_filepath, os.path.join(outfolder, texture_name))
173
- self.write_mtl(os.path.join(outfolder, mtlpath), outbase, texture_name)
174
-
175
- for r in self.v:
176
- fi.write('v %f %f %f\n' % (r[0], r[1], r[2]))
177
-
178
- if hasattr(self, 'fn') and hasattr(self, 'vn'):
179
- for r in self.vn:
180
- fi.write('vn %f %f %f\n' % (r[0], r[1], r[2]))
181
-
182
- if hasattr(self, 'ft'):
183
- for r in self.vt:
184
- if len(r) == 3:
185
- fi.write('vt %f %f %f\n' % (r[0], r[1], r[2]))
186
- else:
187
- fi.write('vt %f %f\n' % (r[0], r[1]))
188
- if hasattr(self, 'segm') and self.segm and not group:
189
- for p in self.segm.keys():
190
- fi.write('g %s\n' % p)
191
- for face_index in self.segm[p]:
192
- write_face_to_obj_file(face_index, fi)
193
- else:
194
- if hasattr(self, 'f'):
195
- for face_index in range(len(self.f)):
196
- write_face_to_obj_file(face_index, fi)
197
-
198
-
199
- def write_mtl(self, path, material_name, texture_name):
200
- """Material attribute file serialization"""
201
- with open(path, 'w') as f:
202
- f.write('newmtl %s\n' % material_name)
203
- # copied from another obj, no idea about what it does
204
- f.write('ka 0.329412 0.223529 0.027451\n')
205
- f.write('kd 0.780392 0.568627 0.113725\n')
206
- f.write('ks 0.992157 0.941176 0.807843\n')
207
- f.write('illum 0\n')
208
- f.write('map_Ka %s\n' % texture_name)
209
- f.write('map_Kd %s\n' % texture_name)
210
- f.write('map_Ks %s\n' % texture_name)
211
-
212
-
213
- def write_ply(self, filename, flip_faces=False, ascii=False, little_endian=True, comments=[]):
214
- from psbody.mesh.serialization import plyutils
215
-
216
- if os.path.dirname(filename) and not os.path.exists(os.path.dirname(filename)):
217
- os.makedirs(os.path.dirname(filename))
218
-
219
- ff = -1 if flip_faces else 1
220
-
221
- if isinstance(comments, str):
222
- comments = [comments]
223
- comments = filter(lambda c: len(c) > 0, sum(map(lambda c: c.split("\n"), comments), []))
224
-
225
- plyutils.write(list([list(x) for x in self.v]),
226
- list([list(x[::ff]) for x in self.f] if hasattr(self, 'f') else []),
227
- list([list((x * 255).astype(int)) for x in ([] if not hasattr(self, 'vc') else self.vc)]),
228
- filename, ascii, little_endian, list(comments),
229
- list([list(x) for x in ([] if not hasattr(self, 'vn') else self.vn)]))
230
-
231
-
232
- def write_three_json(self, filename, name=""):
233
- import json
234
-
235
- if os.path.dirname(filename) and not os.path.exists(os.path.dirname(filename)):
236
- os.makedirs(os.path.dirname(filename))
237
-
238
- name = name if name else self.basename
239
- name = name if name else os.path.splitext(os.path.basename(filename))[0]
240
-
241
- metadata = {"formatVersion": 3.1,
242
- "sourceFile": "%s.obj" % name,
243
- "generatedBy": "korper",
244
- "vertices": len(self.v),
245
- "faces": len(self.f),
246
- "normals": len(self.vn),
247
- "colors": 0,
248
- "uvs": len(self.vt),
249
- "materials": 1
250
- }
251
- materials = [{"DbgColor": 15658734,
252
- "DbgIndex": 0,
253
- "DbgName": "defaultMat",
254
- "colorAmbient": [0.0, 0.0, 0.0],
255
- "colorDiffuse": [0.64, 0.64, 0.64],
256
- "colorSpecular": [0.5, 0.5, 0.5],
257
- "illumination": 2,
258
- "opticalDensity": 1.0,
259
- "specularCoef": 96.078431,
260
- "transparency": 1.0
261
- }]
262
-
263
- mesh_data = {"metadata": metadata,
264
- 'scale': 0.35,
265
- "materials": materials,
266
- "morphTargets": [],
267
- "morphColors": [],
268
- "colors": []}
269
- mesh_data["vertices"] = self.v.flatten().tolist()
270
- mesh_data["normals"] = self.vn.flatten().tolist()
271
- mesh_data["uvs"] = [np.array([[vt[0], vt[1]] for vt in self.vt]).flatten().tolist()]
272
- mesh_data["faces"] = np.array([[42, self.f[i][0], self.f[i][1], self.f[i][2], 0, self.ft[i][0], self.ft[i][1],
273
- self.ft[i][2], self.fn[i][0], self.fn[i][1], self.fn[i][2]] for i in
274
- range(len(self.f))]).flatten().tolist()
275
-
276
- json_or_js_file = open(filename, 'w')
277
- json_or_js_file.write(json.dumps(mesh_data, indent=4))
278
- json_or_js_file.close()
279
-
280
-
281
- def write_json(self, filename, header="", footer="", name="", include_faces=True, texture_mode=True):
282
- import json
283
-
284
- if os.path.dirname(filename) and not os.path.exists(os.path.dirname(filename)):
285
- os.makedirs(os.path.dirname(filename))
286
-
287
- name = name if name else self.basename
288
- name = name if name else os.path.splitext(os.path.basename(filename))[0]
289
-
290
- if texture_mode:
291
- vertex_texture_pairs = {}
292
- for face_index in range(len(self.f)):
293
- for i in [0, 1, 2]:
294
- v_index = self.f[face_index][i]
295
- t_index = self.ft[face_index][i]
296
- vertex_texture_pairs[(v_index, t_index)] = []
297
- for face_index in range(len(self.f)):
298
- for i in [0, 1, 2]:
299
- v_index = self.f[face_index][i]
300
- t_index = self.ft[face_index][i]
301
- vertex_texture_pairs[(v_index, t_index)].append((face_index, i))
302
- mesh_data = {'name': name,
303
- 'vertices': [],
304
- 'textures': []
305
- }
306
- for v_index, t_index, faces_entries in vertex_texture_pairs.items():
307
- mesh_data['vertices'].append()
308
-
309
- if include_faces:
310
- mesh_data['faces'] = list([[int(np.asscalar(i)) for i in list(x)] for x in self.f])
311
-
312
- else:
313
- mesh_data = {'name': name,
314
- 'vertices': list([list(x) for x in self.v])
315
- }
316
- if include_faces:
317
- mesh_data['faces'] = list([[int(np.asscalar(i)) for i in list(x)] for x in self.f])
318
-
319
- json_or_js_file = open(filename, 'w')
320
- if os.path.basename(filename).endswith('js'):
321
- json_or_js_file.write(header + '\nmesh = ') if header else json_or_js_file.write('var mesh = ')
322
- json_or_js_file.write(json.dumps(mesh_data, indent=4))
323
- json_or_js_file.write(footer)
324
- else:
325
- json_or_js_file.write(json.dumps(mesh_data, indent=4))
326
- json_or_js_file.close()
327
-
328
-
329
- def set_landmark_indices_from_ppfile(self, ppfilename):
330
- from xml.etree import ElementTree
331
- tree = ElementTree.parse(ppfilename)
332
-
333
- def get_xyz(e):
334
- try:
335
- return [float(e.attrib['x']), float(e.attrib['y']), float(e.attrib['z'])]
336
- except: # may happen if landmarks are just spaces
337
- return [0, 0, 0]
338
-
339
- self.landm_raw_xyz = dict((e.attrib['name'], get_xyz(e)) for e in tree.iter() if e.tag == 'point')
340
- self.recompute_landmark_indices(ppfilename)
341
-
342
-
343
- def set_landmark_indices_from_lmrkfile(self, lmrkfilename):
344
- with open(lmrkfilename, 'r') as lmrkfile:
345
- self.landm_raw_xyz = {}
346
-
347
- for line in lmrkfile.readlines():
348
- if not line.strip():
349
- continue
350
- command = line.split()[0]
351
- data = [float(x) for x in line.split()[1:]]
352
-
353
- if command == '_scale':
354
- selfscale_factor = np.matrix(data)
355
- elif command == '_translate':
356
- self.caesar_translation_vector = np.matrix(data)
357
- elif command == '_rotation':
358
- self.caesar_rotation_matrix = np.matrix(data).reshape(3, 3)
359
- else:
360
- self.landm_raw_xyz[command] = [data[1], data[2], data[0]]
361
- self.recompute_landmark_indices(lmrkfilename)
362
-
363
-
364
- def _is_lmrkfile(filename):
365
- is_lmrk = re.compile('^_scale\s[-\d\.]+\s+_translate(\s[-\d\.]+){3}\s+_rotation(\s[-\d\.]+){9}\s+')
366
- with open(filename) as f:
367
- data = f.read()
368
- res = is_lmrk.match(data)
369
- return res
370
-
371
-
372
- def set_landmark_indices_from_any(self, landmarks):
373
- '''
374
- Sets landmarks given any of:
375
- - ppfile
376
- - ldmk file
377
- - dict of {name:inds} (i.e. mesh.landm)
378
- - dict of {name:xyz} (i.e. mesh.landm_xyz)
379
- - pkl, json, yaml file containing either of the above dicts
380
- '''
381
- import json
382
- import pickle
383
-
384
- try:
385
- path_exists = os.path.exists(landmarks)
386
- except:
387
- path_exists = False
388
- if path_exists:
389
- if re.search(".ya{0,1}ml$", landmarks):
390
- import yaml
391
- with open(landmarks) as f:
392
- self.set_landmarks_from_raw(yaml.load(f, Loader=yaml.FullLoader))
393
- elif re.search(".json$", landmarks):
394
- with open(landmarks) as f:
395
- self.set_landmarks_from_raw(json.load(f))
396
- elif re.search(".pkl$", landmarks):
397
- with open(landmarks, "rb") as f:
398
- self.set_landmarks_from_raw(pickle.load(f))
399
- elif _is_lmrkfile(landmarks):
400
- self.set_landmark_indices_from_lmrkfile(landmarks)
401
- else:
402
- try:
403
- self.set_landmark_indices_from_ppfile(landmarks)
404
- except:
405
- raise Exception("Landmark file %s is of unknown format" % landmarks)
406
- else:
407
- self.set_landmarks_from_raw(landmarks)
408
-
409
-
410
- def load_from_file(self, filename, use_cpp=True):
411
- if re.search(".ply$", filename):
412
- self.load_from_ply(filename)
413
- elif re.search(".obj$", filename):
414
- # XXX experimental cpp obj loader, if problems, switch back to
415
- if use_cpp:
416
- self.load_from_obj_cpp(filename)
417
- else:
418
- self.load_from_obj(filename)
419
-
420
- elif re.search(".bsf$", filename):
421
- self.load_from_bsf(filename)
422
- else:
423
- raise NotImplementedError("Unknown mesh file format.")
424
-
425
-
426
- def load_from_ply(self, filename):
427
- from os.path import abspath, dirname, join
428
-
429
- test_data_folder = abspath(join(dirname(__file__), '..', 'data', 'unittest'))
430
-
431
- from psbody.mesh.serialization import plyutils
432
- try:
433
- res = plyutils.read(filename)
434
- except plyutils.error as e:
435
- raise SerializationError(e)
436
-
437
- self.v = np.array(res['pts']).T.copy()
438
- self.f = np.array(res['tri']).T.copy()
439
-
440
- if 'color' in res:
441
- self.set_vertex_colors(np.array(res['color']).T.copy() / 255)
442
- if 'normals' in res:
443
- self.vn = np.array(res['normals']).T.copy()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/sphere.py DELETED
@@ -1,74 +0,0 @@
1
- import numpy as np
2
- from .mesh import Mesh
3
- from .colors import name_to_rgb
4
-
5
-
6
- __all__ = ['Sphere']
7
-
8
-
9
- class Sphere(object):
10
- def __init__(self, center, radius):
11
- if(center.flatten().shape != (3,)):
12
- raise Exception("Center should have size(1,3) instead of %s" % center.shape)
13
- self.center = center.flatten()
14
- self.radius = radius
15
-
16
- def __str__(self):
17
- return "%s:%s" % (self.center, self.radius)
18
-
19
- def to_mesh(self, color=name_to_rgb['red']):
20
- v = np.array([[0.0000, -1.000, 0.0000], [0.7236, -0.447, 0.5257],
21
- [-0.278, -0.447, 0.8506], [-0.894, -0.447, 0.0000],
22
- [-0.278, -0.447, -0.850], [0.7236, -0.447, -0.525],
23
- [0.2765, 0.4472, 0.8506], [-0.723, 0.4472, 0.5257],
24
- [-0.720, 0.4472, -0.525], [0.2763, 0.4472, -0.850],
25
- [0.8945, 0.4472, 0.0000], [0.0000, 1.0000, 0.0000],
26
- [-0.165, -0.850, 0.4999], [0.4253, -0.850, 0.3090],
27
- [0.2629, -0.525, 0.8090], [0.4253, -0.850, -0.309],
28
- [0.8508, -0.525, 0.0000], [-0.525, -0.850, 0.0000],
29
- [-0.688, -0.525, 0.4999], [-0.162, -0.850, -0.499],
30
- [-0.688, -0.525, -0.499], [0.2628, -0.525, -0.809],
31
- [0.9518, 0.0000, -0.309], [0.9510, 0.0000, 0.3090],
32
- [0.5876, 0.0000, 0.8090], [0.0000, 0.0000, 1.0000],
33
- [-0.588, 0.0000, 0.8090], [-0.951, 0.0000, 0.3090],
34
- [-0.955, 0.0000, -0.309], [-0.587, 0.0000, -0.809],
35
- [0.0000, 0.0000, -1.000], [0.5877, 0.0000, -0.809],
36
- [0.6889, 0.5257, 0.4999], [-0.262, 0.5257, 0.8090],
37
- [-0.854, 0.5257, 0.0000], [-0.262, 0.5257, -0.809],
38
- [0.6889, 0.5257, -0.499], [0.5257, 0.8506, 0.0000],
39
- [0.1626, 0.8506, 0.4999], [-0.425, 0.8506, 0.3090],
40
- [-0.422, 0.8506, -0.309], [0.1624, 0.8506, -0.499]])
41
-
42
- f = np.array([[15, 3, 13], [13, 14, 15], [2, 15, 14], [13, 1, 14], [17, 2, 14], [14, 16, 17],
43
- [6, 17, 16], [14, 1, 16], [19, 4, 18], [18, 13, 19], [3, 19, 13], [18, 1, 13],
44
- [21, 5, 20], [20, 18, 21], [4, 21, 18], [20, 1, 18], [22, 6, 16], [16, 20, 22],
45
- [5, 22, 20], [16, 1, 20], [24, 2, 17], [17, 23, 24], [11, 24, 23], [23, 17, 6],
46
- [26, 3, 15], [15, 25, 26], [7, 26, 25], [25, 15, 2], [28, 4, 19], [19, 27, 28],
47
- [8, 28, 27], [27, 19, 3], [30, 5, 21], [21, 29, 30], [9, 30, 29], [29, 21, 4],
48
- [32, 6, 22], [22, 31, 32], [10, 32, 31], [31, 22, 5], [33, 7, 25], [25, 24, 33],
49
- [11, 33, 24], [24, 25, 2], [34, 8, 27], [27, 26, 34], [7, 34, 26], [26, 27, 3],
50
- [35, 9, 29], [29, 28, 35], [8, 35, 28], [28, 29, 4], [36, 10, 31], [31, 30, 36],
51
- [9, 36, 30], [30, 31, 5], [37, 11, 23], [23, 32, 37], [10, 37, 32], [32, 23, 6],
52
- [39, 7, 33], [33, 38, 39], [12, 39, 38], [38, 33, 11], [40, 8, 34], [34, 39, 40],
53
- [12, 40, 39], [39, 34, 7], [41, 9, 35], [35, 40, 41], [12, 41, 40], [40, 35, 8],
54
- [42, 10, 36], [36, 41, 42], [12, 42, 41], [41, 36, 9], [38, 11, 37], [37, 42, 38],
55
- [12, 38, 42], [42, 37, 10]]) - 1
56
-
57
- return Mesh(v=v * self.radius + self.center, f=f, vc=np.tile(color, (v.shape[0], 1)))
58
-
59
- def has_inside(self, point):
60
- return np.linalg.norm(point - self.center) <= self.radius
61
-
62
- def intersects(self, sphere):
63
- return np.linalg.norm(sphere.center - self.center) < (self.radius + sphere.radius)
64
-
65
- def intersection_vol(self, sphere):
66
- if not self.intersects(sphere):
67
- return 0
68
- d = np.linalg.norm(sphere.center - self.center)
69
- R, r = (self.radius, sphere.radius) if (self.radius > sphere.radius) else (sphere.radius, self.radius)
70
- if R >= (d + r):
71
- return (4 * np.pi * (r ** 3)) / 3
72
-
73
- # http://mathworld.wolfram.com/Sphere-SphereIntersection.html
74
- return (np.pi * (R + r - d) ** 2 * (d ** 2 + 2 * d * r - 3 * r * r + 2 * d * R + 6 * r * R - 3 * R * R)) / (12 * d)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mesh-fix-MSVC_compilation/mesh/src/AABB_n_tree.h DELETED
@@ -1,355 +0,0 @@
1
- // Author(s) : Javier Romero
2
-
3
- #ifndef AABB_N_TREE_H
4
- #define AABB_N_TREE_H
5
-
6
- #include <vector>
7
-
8
- #define CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES 1
9
- #include <CGAL/AABB_tree.h>
10
- #include <CGAL/AABB_traits.h>
11
- #include <CGAL/internal/AABB_tree/nearest_point_triangle_3.h>
12
- #include <CGAL/Simple_cartesian.h>
13
- #include <CGAL/AABB_triangle_primitive.h>
14
-
15
- #include <CGAL/intersections.h>
16
- #include <CGAL/Bbox_3.h>
17
-
18
- #include <boost/cstdint.hpp>
19
- #include <boost/array.hpp>
20
-
21
-
22
- typedef CGAL::Simple_cartesian<double> K;
23
- using boost::uint32_t;
24
- using boost::uint64_t;
25
- using boost::array;
26
- using std::vector;
27
-
28
- typedef K::Point_3 Point;
29
- typedef K::Segment_3 Segment;
30
- typedef K::Triangle_3 Triangle;
31
- typedef K::Vector_3 Normal;
32
- typedef std::pair<Point,Normal> Point_Normal;
33
-
34
- typedef std::vector<Triangle>::iterator Iterator;
35
- typedef CGAL::AABB_triangle_primitive<K,Iterator> Primitive;
36
-
37
-
38
- namespace CGAL {
39
- template<typename FT>
40
- FT dist_point_normal(const Point_Normal& a, const Point_Normal& b, FT eps){
41
- return (sqrt(squared_distance(a.first, b.first)) + eps*(1 - a.second*b.second));
42
- }
43
-
44
- // Adaptation of nearest_point_3 to take into account normals
45
- // product with weight eps
46
- template<typename FT>
47
- Point_Normal nearest_pointnormal_3(const Point_Normal& origin,
48
- const Triangle& triangle,
49
- const Point_Normal& bound,
50
- const FT eps,
51
- const K& k){
52
- // compute normal penalties
53
- const FT dist_n_bound = eps*(1 - origin.second*bound.second);
54
- //const Normal tri_n = unit_normal(triangle[0],triangle[1],triangle[2]);
55
- Normal tri_n = triangle.supporting_plane().orthogonal_direction().vector();
56
- tri_n = tri_n / sqrt(tri_n.squared_length());
57
- const FT dist_n_triangle = eps*(1 - origin.second*tri_n);
58
-
59
- // Distance from origin to bound
60
- const FT dist_bound = sqrt(squared_distance(origin.first,bound.first)) + dist_n_bound;
61
-
62
- // since dist_n_triangle < dist_triangle
63
- if (dist_n_triangle > dist_bound)
64
- return bound;
65
-
66
- // Project origin on triangle supporting plane
67
- const Point_Normal proj = std::make_pair(triangle.supporting_plane().projection(origin.first), tri_n);
68
-
69
- const FT dist_proj = sqrt(squared_distance(origin.first,proj.first)) + dist_n_triangle;
70
-
71
- Point moved_point;
72
- // If point is projected outside, return bound
73
- if ( dist_proj > dist_bound)
74
- return bound;
75
- // If proj is inside triangle, total dist is dist_proj
76
- else if ( CGAL::internal::is_inside_triangle_3<K>(proj.first,triangle,moved_point,k) )
77
- return proj;
78
- // Else return the constructed point (nearest point of triangle from proj)
79
- // if it is closest to origin than bound
80
- else{
81
- const FT dist_moved = sqrt(squared_distance(origin.first, moved_point)) + dist_n_triangle;
82
- return (dist_moved > dist_bound) ? bound : std::make_pair(moved_point, tri_n);
83
- }
84
- }
85
-
86
- // extends AABB_Traits with classes handling points with normals
87
- template <typename GeomTraits, typename AABB_primitive>
88
- class AABB_n_traits:public AABB_traits<GeomTraits,AABB_primitive>{
89
-
90
- public:
91
-
92
- typedef Point_Normal PointNormal;
93
- typedef AABB_n_traits<GeomTraits, AABB_primitive> AT;
94
-
95
- class Do_intersect{
96
- public:
97
- template<typename Query>
98
- bool operator()(const Query& q, const CGAL::Bbox_3& bbox) const{
99
- return CGAL::do_intersect(q, bbox);
100
- }
101
-
102
- template<typename Query>
103
- bool operator()(const Query& q, const AABB_primitive& pr) const{
104
- return GeomTraits().do_intersect_3_object()(q, pr.datum());
105
- }
106
-
107
- bool operator()(const typename GeomTraits::Triangle_3& q, const AABB_primitive& pr) const{
108
-
109
- // if any point is the same, don't consider it'
110
- if(q[0] == pr.datum()[0] || q[0] == pr.datum()[1] ||q[0] == pr.datum()[2] ||
111
- q[1] == pr.datum()[0] || q[1] == pr.datum()[1] ||q[1] == pr.datum()[2] ||
112
- q[2] == pr.datum()[0] || q[2] == pr.datum()[1] ||q[2] == pr.datum()[2])
113
- return false;
114
- else
115
- return CGAL::do_intersect(q, pr.datum());
116
- }
117
- };
118
-
119
- class Closest_point {
120
- typedef typename AT::Point_3 Point;
121
- typedef typename AT::PointNormal PointNormal;
122
- typedef typename AT::Primitive Primitive;
123
- typedef typename AT::FT FT;
124
-
125
- public:
126
-
127
- // for intersection: return the closest point on
128
- // triangle pr or bound to pn
129
- PointNormal operator()(const PointNormal& pn, const Primitive& pr,
130
- const PointNormal& bound, FT eps) const {
131
- return nearest_pointnormal_3(pn, pr.datum(), bound, eps, K());
132
- }
133
-
134
- };
135
-
136
- class Compare_distance {
137
- typedef typename AT::Point_3 Point;
138
- typedef typename AT::PointNormal PointNormal;
139
- typedef typename AT::FT FT;
140
- typedef typename AT::Primitive Primitive;
141
- public:
142
-
143
- // create a sphere that contains all possible results
144
- // (all points closer than current result) and
145
- // check if pr intersects
146
- template <class Solid>
147
- CGAL::Comparison_result operator()(const PointNormal& p, const Solid& pr, const PointNormal& bound, FT eps) const
148
- {
149
- // d_q = ||q - p|| + eps(1 - n_q*n_p) > ||q-p||
150
- // d_q < d_b -> ||q-p|| < d_b
151
- // a sphere containing all q such that ||q-p|| < d_b
152
- // contains all q such that d_q < d_b
153
- FT safe_dist = dist_point_normal(p,bound,eps);
154
- return GeomTraits().do_intersect_3_object()
155
- (GeomTraits().construct_sphere_3_object()
156
- (p.first, safe_dist*safe_dist), pr)?
157
- CGAL::SMALLER : CGAL::LARGER;
158
- }
159
- };
160
-
161
- Closest_point closest_point_object() {return Closest_point();}
162
- Compare_distance compare_distance_object() {return Compare_distance();}
163
- Do_intersect do_intersect_object() {return Do_intersect();}
164
-
165
- };// end of AABB_n_traits
166
-
167
-
168
- /**
169
- * @class Do_intersect_noself_traits
170
- */
171
- template<typename AABBTraits, typename Query>
172
- class Do_intersect_noself_traits
173
- {
174
- typedef typename AABBTraits::FT FT;
175
- typedef typename AABBTraits::Point_3 Point;
176
- typedef typename AABBTraits::Primitive Primitive;
177
- typedef typename AABBTraits::Bounding_box Bounding_box;
178
- typedef typename AABBTraits::Primitive::Id Primitive_id;
179
- typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
180
- typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
181
- typedef ::CGAL::AABB_node<AABBTraits> Node;
182
- typedef typename ::CGAL::AABB_tree<AABBTraits>::size_type size_type;
183
-
184
- public:
185
- Do_intersect_noself_traits()
186
- : m_is_found(false)
187
- {}
188
-
189
- bool go_further() const { return !m_is_found; }
190
-
191
- void intersection(const Query& query, const Primitive& primitive)
192
- {
193
- if( AABBTraits().do_intersect_object()(query, primitive) )
194
- m_is_found = true;
195
- }
196
-
197
- bool do_intersect(const Query& query, const Node& node) const
198
- {
199
- return AABBTraits().do_intersect_object()(query, node.bbox());
200
- }
201
-
202
- bool is_intersection_found() const { return m_is_found; }
203
-
204
- private:
205
- bool m_is_found;
206
- };
207
-
208
- /**
209
- * @class Projection_n_traits
210
- */
211
- template <typename AABBTraits>
212
- class Projection_n_traits
213
- {
214
- typedef typename AABBTraits::FT FT;
215
- typedef typename AABBTraits::Point_3 Point;
216
- typedef typename AABBTraits::PointNormal PointNormal;
217
- typedef typename AABBTraits::Primitive Primitive;
218
- typedef typename AABBTraits::Bounding_box Bounding_box;
219
- typedef typename AABBTraits::Primitive::Id Primitive_id;
220
- typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
221
- typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id;
222
- typedef ::CGAL::AABB_node<AABBTraits> Node;
223
-
224
- public:
225
- Projection_n_traits(const PointNormal& hint,
226
- const typename Primitive::Id& hint_primitive,
227
- const FT eps)
228
- : m_closest_point(hint), m_closest_primitive(hint_primitive), eps(eps) {}
229
-
230
- bool go_further() const { return true; }
231
-
232
- void intersection(const PointNormal& query, const Primitive& primitive)
233
- {
234
- PointNormal new_closest_point = AABBTraits().closest_point_object()
235
- (query, primitive, m_closest_point, eps);
236
- if(new_closest_point.first != m_closest_point.first)
237
- {
238
- m_closest_primitive = primitive.id();
239
- m_closest_point = new_closest_point; // this effectively shrinks the sphere
240
- }
241
- }
242
-
243
- bool do_intersect(const PointNormal& query, const Node& node) const
244
- {
245
- return AABBTraits().compare_distance_object()
246
- (query, node.bbox(), m_closest_point, eps) == CGAL::SMALLER;
247
- }
248
-
249
- Point closest_point() const { return m_closest_point.first; }
250
- Point_and_primitive_id closest_point_and_primitive() const
251
- {
252
- return Point_and_primitive_id(m_closest_point.first, m_closest_primitive);
253
- }
254
-
255
- private:
256
- PointNormal m_closest_point;
257
- typename Primitive::Id m_closest_primitive;
258
- const FT eps;
259
- };
260
-
261
- // Class that extends AABB tree with PointNormal Search
262
- template <typename AABBTraits>
263
- class AABB_n_tree:public AABB_tree<AABBTraits>{
264
- public:
265
- typedef typename AABBTraits::Point_3 Point;
266
- typedef typename AABBTraits::PointNormal PointNormal;
267
- typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id;
268
-
269
- AABB_n_tree():AABB_tree<AABBTraits>(){}
270
-
271
- template<typename ConstPrimitiveIterator>
272
- AABB_n_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,
273
- typename AABBTraits::FT eps):
274
- AABB_tree<AABBTraits>(first, beyond), eps(eps){}
275
-
276
- // XXX The hint is random; that is slow and could be closer (euclideanly) than the best point
277
- Point_and_primitive_id closest_point_and_primitive(const PointNormal& query) const{
278
- // return closest_point_and_primitive(query,best_hint(query.first));
279
- return closest_point_and_primitive(query,this->any_reference_point_and_id());
280
- }
281
-
282
- Point_and_primitive_id closest_point_and_primitive(const PointNormal& query,
283
- const Point_and_primitive_id& hint) const{
284
-
285
- Normal hint_n = (*hint.second).supporting_plane().orthogonal_direction().vector();
286
- PointNormal hint_pn = std::make_pair(hint.first, hint_n/sqrt(hint_n.squared_length()));
287
- // hint_pn = std::make_pair(Point(10000,10000,10000),Normal(0,0,1));
288
- Projection_n_traits<AABBTraits> projection_traits(hint_pn, hint.second, eps);
289
- this->traversal(query, projection_traits);
290
- return projection_traits.closest_point_and_primitive();
291
- }
292
-
293
- template<typename Query>
294
- bool do_intersect(const Query& query) const
295
- {
296
- //using namespace CGAL::internal::AABB_tree;
297
- Do_intersect_noself_traits<AABBTraits, Query> traversal_traits;
298
- this->traversal(query, traversal_traits);
299
- return traversal_traits.is_intersection_found();
300
- }
301
-
302
- typename AABBTraits::FT eps;
303
- };
304
- }
305
-
306
- typedef CGAL::AABB_n_traits<K, Primitive> AABB_n_triangle_traits;
307
- typedef AABB_n_triangle_traits::Point_and_primitive_id Point_and_Primitive_id;
308
- typedef CGAL::AABB_n_tree<AABB_n_triangle_traits> Tree;
309
-
310
- struct TreeAndTri {
311
- TreeAndTri(const array<uint32_t, 3>* p_mesh_tri,
312
- const array<double, 3>* p_mesh_points,
313
- const double eps,
314
- const size_t T,
315
- const size_t P)
316
- {
317
- std::vector<K::Point_3> mesh_points;
318
- mesh_points.reserve(P);
319
- for(size_t pp=0; pp<P; ++pp){
320
- mesh_points.push_back(K::Point_3(p_mesh_points[pp][0],
321
- p_mesh_points[pp][1],
322
- p_mesh_points[pp][2]));
323
- }
324
-
325
- triangles.reserve(T);
326
- for(size_t tt=0; tt<T; ++tt) {
327
- triangles.push_back(K::Triangle_3(mesh_points[p_mesh_tri[tt][0]],
328
- mesh_points[p_mesh_tri[tt][1]],
329
- mesh_points[p_mesh_tri[tt][2]]));
330
- }
331
-
332
- tree.eps = eps;
333
- tree.rebuild(triangles.begin(), triangles.end());
334
- // tree.accelerate_distance_queries();
335
- }
336
-
337
- vector<K::Triangle_3> triangles;
338
- Tree tree;
339
- };
340
-
341
- template<typename T>
342
- boost::uint64_t wrapPointer(T *ptr) {
343
- return reinterpret_cast<uint64_t>(ptr);
344
- }
345
- template<typename T>
346
- T* unwrapPointer(uint64_t ptr) {
347
- return reinterpret_cast<T*>(ptr);
348
- }
349
-
350
- #endif // AABB_N_TREE_H
351
-
352
- /***EMACS SETTINGS***/
353
- /* Local Variables: */
354
- /* tab-width: 2 */
355
- /* End: */