Spaces:
Build error
Build error
Commit
·
b80cc22
1
Parent(s):
44dc438
Delete mesh-master
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- mesh-master/.gitignore +0 -12
- mesh-master/CGAL_LICENSE.pdf +0 -0
- mesh-master/LICENSE.txt +0 -30
- mesh-master/MANIFEST.in +0 -2
- mesh-master/Makefile +0 -48
- mesh-master/README.md +0 -156
- mesh-master/bin/meshviewer +0 -379
- mesh-master/data/unittest/cylinder.obj +0 -38
- mesh-master/data/unittest/cylinder_trans.obj +0 -38
- mesh-master/data/unittest/self_intersecting_cyl.obj +0 -46
- mesh-master/data/unittest/sphere.obj +0 -1278
- mesh-master/data/unittest/sphere.ply +0 -1271
- mesh-master/data/unittest/test_box.obj +0 -50
- mesh-master/data/unittest/test_box.ply +0 -29
- mesh-master/data/unittest/test_box.pp +0 -11
- mesh-master/data/unittest/test_box_le.ply +0 -0
- mesh-master/data/unittest/test_doublebox.obj +0 -64
- mesh-master/doc/Makefile +0 -177
- mesh-master/doc/make.bat +0 -242
- mesh-master/doc/source/conf.py +0 -356
- mesh-master/doc/source/index.rst +0 -193
- mesh-master/doc/source/pages/geometry.rst +0 -29
- mesh-master/doc/source/pages/mesh.rst +0 -31
- mesh-master/doc/source/pages/mesh_viewer.rst +0 -11
- mesh-master/mesh/CMakeLists.txt +0 -99
- mesh-master/mesh/__init__.py +0 -20
- mesh-master/mesh/arcball.py +0 -247
- mesh-master/mesh/cmake/python_helper.cmake +0 -74
- mesh-master/mesh/cmake/thirdparty.cmake +0 -107
- mesh-master/mesh/colors.py +0 -790
- mesh-master/mesh/errors.py +0 -15
- mesh-master/mesh/fonts.py +0 -87
- mesh-master/mesh/geometry/__init__.py +0 -4
- mesh-master/mesh/geometry/barycentric_coordinates_of_projection.py +0 -49
- mesh-master/mesh/geometry/cross_product.py +0 -37
- mesh-master/mesh/geometry/rodrigues.py +0 -125
- mesh-master/mesh/geometry/tri_normals.py +0 -72
- mesh-master/mesh/geometry/triangle_area.py +0 -12
- mesh-master/mesh/geometry/vert_normals.py +0 -34
- mesh-master/mesh/landmarks.py +0 -102
- mesh-master/mesh/lines.py +0 -61
- mesh-master/mesh/mesh.py +0 -492
- mesh-master/mesh/meshviewer.py +0 -1274
- mesh-master/mesh/processing.py +0 -186
- mesh-master/mesh/ressources/Arial.ttf +0 -0
- mesh-master/mesh/search.py +0 -100
- mesh-master/mesh/serialization/__init__.py +0 -4
- mesh-master/mesh/serialization/serialization.py +0 -443
- mesh-master/mesh/sphere.py +0 -74
- mesh-master/mesh/src/AABB_n_tree.h +0 -355
mesh-master/.gitignore
DELETED
@@ -1,12 +0,0 @@
|
|
1 |
-
build/*
|
2 |
-
_build
|
3 |
-
*.pyc
|
4 |
-
temporary_test
|
5 |
-
dist
|
6 |
-
MANIFEST
|
7 |
-
*.xml
|
8 |
-
*.egg-info
|
9 |
-
doc/build
|
10 |
-
.eggs
|
11 |
-
.idea
|
12 |
-
.noseids
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mesh-master/CGAL_LICENSE.pdf
DELETED
Binary file (78.7 kB)
|
|
mesh-master/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-master/MANIFEST.in
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
recursive-include mesh/src *
|
2 |
-
recursive-include mesh/ressources *
|
|
|
|
|
|
mesh-master/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 with the interpreter `which python` (version `python --version | cut -d' ' -f2`)\033[0m"
|
6 |
-
@pip install --upgrade -r requirements.txt && pip list
|
7 |
-
@pip install --no-deps --install-option="--boost-location=$$BOOST_INCLUDE_DIRS" --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_INCLUDE_DIRS 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-master/README.md
DELETED
@@ -1,156 +0,0 @@
|
|
1 |
-
[](
|
3 |
-
https://atlas.is.localnet/bamboo/browse/PS-FMP/latest)
|
4 |
-
|
5 |
-
Perceiving Systems Mesh Package
|
6 |
-
===============================
|
7 |
-
|
8 |
-
This package contains core functions for manipulating meshes and
|
9 |
-
visualizing them. It requires ``Python 3.5+`` and is supported on
|
10 |
-
Linux and macOS operating systems.
|
11 |
-
|
12 |
-
The ``Mesh`` processing libraries support several of our projects such as
|
13 |
-
* [CoMA: Convolutional Mesh Encoders for Generating 3D Faces](http://coma.is.tue.mpg.de/)
|
14 |
-
* [FLAME: Learning a model of facial shape and expression from 4D scans](http://flame.is.tue.mpg.de/)
|
15 |
-
* [MANO: Modeling and Capturing Hands and Bodies Together](http://mano.is.tue.mpg.de/)
|
16 |
-
* [SMPL: A Skinned Multi-Person Linear Model](http://smpl.is.tue.mpg.de/)
|
17 |
-
* [VOCA: Voice Operated Character Animation](https://github.com/TimoBolkart/voca)
|
18 |
-
* [RingNet: 3D Face Shape and Expression Reconstruction from an Image](https://github.com/soubhiksanyal/RingNet)
|
19 |
-
* [Expressive Body Capture: 3D Hands, Face, and Body from a Single Image](https://smpl-x.is.tue.mpg.de/)
|
20 |
-
|
21 |
-
Requirements
|
22 |
-
------------
|
23 |
-
|
24 |
-
You first need to install the `Boost <http://www.boost.org>`_
|
25 |
-
libraries. You can compile your own local version or simply do on
|
26 |
-
Linux
|
27 |
-
|
28 |
-
```
|
29 |
-
$ sudo apt-get install libboost-dev
|
30 |
-
```
|
31 |
-
|
32 |
-
or on macOS
|
33 |
-
|
34 |
-
```
|
35 |
-
$ brew install boost
|
36 |
-
```
|
37 |
-
|
38 |
-
Installation
|
39 |
-
------------
|
40 |
-
|
41 |
-
First, create a dedicated Python virtual environment and activate it:
|
42 |
-
|
43 |
-
```
|
44 |
-
$ python3 -m venv --copies my_venv
|
45 |
-
$ source my_venv/bin/activate
|
46 |
-
```
|
47 |
-
|
48 |
-
You should then compile and install the ``psbody-mesh`` package easily
|
49 |
-
using the Makefile:
|
50 |
-
|
51 |
-
```
|
52 |
-
$ BOOST_INCLUDE_DIRS=/path/to/boost/include make all
|
53 |
-
```
|
54 |
-
|
55 |
-
Testing
|
56 |
-
-------
|
57 |
-
|
58 |
-
To run the tests, simply do:
|
59 |
-
|
60 |
-
```
|
61 |
-
$ make tests
|
62 |
-
```
|
63 |
-
|
64 |
-
Documentation
|
65 |
-
-------------
|
66 |
-
|
67 |
-
A detailed documentation can be compiled using the Makefile:
|
68 |
-
|
69 |
-
```
|
70 |
-
$ make documentation
|
71 |
-
```
|
72 |
-
|
73 |
-
Viewing the Meshes
|
74 |
-
------------------
|
75 |
-
|
76 |
-
Starting from version 0.4 meshviewer ships with `meshviewer` -- a
|
77 |
-
program that allows you to display polygonal meshes produced by `mesh`
|
78 |
-
package.
|
79 |
-
|
80 |
-
### Viewing a mesh on a local machine
|
81 |
-
|
82 |
-
The most straightforward use-case is viewing the mesh on the same
|
83 |
-
machine where it is stored. To do this simply run
|
84 |
-
|
85 |
-
```
|
86 |
-
$ meshviewer view sphere.obj
|
87 |
-
```
|
88 |
-
|
89 |
-
This will create an interactive window with your mesh rendering. You
|
90 |
-
can render more than one mesh in the same window by passing several
|
91 |
-
paths to `view` command
|
92 |
-
|
93 |
-
```
|
94 |
-
$ meshviewer view sphere.obj cylinder.obj
|
95 |
-
```
|
96 |
-
|
97 |
-
This will arrange the subplots horizontally in a row. If you want a
|
98 |
-
grid arrangement, you can specify the grid parameters explicitly
|
99 |
-
|
100 |
-
```
|
101 |
-
$ meshviewer view -nx 2 -ny 2 *.obj
|
102 |
-
```
|
103 |
-
|
104 |
-
### Viewing a mesh from a remote machine
|
105 |
-
|
106 |
-
It is also possible to view a mesh stored on a remote machine. To do
|
107 |
-
this you need mesh to be installed on both the local and the remote
|
108 |
-
machines. You start by opening an empty viewer window listening on a
|
109 |
-
network port
|
110 |
-
|
111 |
-
```
|
112 |
-
(local) $ meshviewer open --port 3000
|
113 |
-
```
|
114 |
-
|
115 |
-
To stream a shape to this viewer you have to either pick a port that
|
116 |
-
is visible from the remote machine or by manually exposing the port
|
117 |
-
when connecting. For example, through SSH port forwarding
|
118 |
-
|
119 |
-
```
|
120 |
-
(local) $ ssh -R 3000:127.0.0.1:3000 user@host
|
121 |
-
```
|
122 |
-
|
123 |
-
Then on a remote machine you use `view` command pointing to the
|
124 |
-
locally forwarded port
|
125 |
-
|
126 |
-
```
|
127 |
-
(remote) $ meshviewer view -p 3000 sphere.obj
|
128 |
-
```
|
129 |
-
|
130 |
-
This should display the remote mesh on your local viewer. In case it
|
131 |
-
does not it might be caused by the network connection being closed
|
132 |
-
before the mesh could be sent. To work around this one can try
|
133 |
-
increasing the timeout up to 1 second
|
134 |
-
|
135 |
-
```
|
136 |
-
(remote) $ meshviewer view -p 3000 --timeout 1 sphere.obj
|
137 |
-
```
|
138 |
-
|
139 |
-
To take a snapshot you should locally run a `snap` command
|
140 |
-
|
141 |
-
```
|
142 |
-
(local) $ meshviewer snap -p 3000 sphere.png
|
143 |
-
```
|
144 |
-
|
145 |
-
License
|
146 |
-
-------
|
147 |
-
|
148 |
-
Please refer for LICENSE.txt for using this software. The software is
|
149 |
-
compiled using CGAL sources following the license in CGAL_LICENSE.pdf
|
150 |
-
|
151 |
-
Acknowledgments
|
152 |
-
---------------
|
153 |
-
|
154 |
-
We thank the external contribution from the following people:
|
155 |
-
* [Kenneth Chaney](https://github.com/k-chaney) ([PR #5](https://github.com/MPI-IS/mesh/pull/5))
|
156 |
-
* [Dávid Komorowicz](https://github.com/Dawars) ([PR #8](https://github.com/MPI-IS/mesh/pull/8))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mesh-master/bin/meshviewer
DELETED
@@ -1,379 +0,0 @@
|
|
1 |
-
#!/usr/bin/env python3
|
2 |
-
|
3 |
-
|
4 |
-
import textwrap
|
5 |
-
|
6 |
-
__doc__ = textwrap.dedent(
|
7 |
-
"""
|
8 |
-
`meshviewer` is a program that allows you to display polygonal
|
9 |
-
meshes produced by `mesh` package.
|
10 |
-
|
11 |
-
Viewing a mesh on a local machine
|
12 |
-
---------------------------------
|
13 |
-
|
14 |
-
The most straightforward use-case is viewing the mesh on the same
|
15 |
-
machine where it is stored. To do this simply run
|
16 |
-
|
17 |
-
```
|
18 |
-
$ meshviewer view sphere.obj
|
19 |
-
```
|
20 |
-
|
21 |
-
This will create an interactive window with your mesh rendering.
|
22 |
-
You can render more than one mesh in the same window by passing
|
23 |
-
several paths to `view` command
|
24 |
-
|
25 |
-
```
|
26 |
-
$ meshviewer view sphere.obj cylinder.obj
|
27 |
-
```
|
28 |
-
|
29 |
-
This will arrange the subplots horizontally in a row. If you want
|
30 |
-
a grid arrangement, you can specify the grid parameters explicitly
|
31 |
-
|
32 |
-
```
|
33 |
-
$ meshviewer view -nx 2 -ny 2 *.obj
|
34 |
-
```
|
35 |
-
|
36 |
-
Viewing a mesh from a remote machine
|
37 |
-
------------------------------------
|
38 |
-
|
39 |
-
It is also possible to view a mesh stored on a remote machine. To
|
40 |
-
do this you need mesh to be installed on both the local and the
|
41 |
-
remote machines. You start by opening an empty viewer window
|
42 |
-
listening on a network port
|
43 |
-
|
44 |
-
```
|
45 |
-
(local) $ meshviewer open --port 3000
|
46 |
-
```
|
47 |
-
|
48 |
-
To stream a shape to this viewer you have to either pick a port
|
49 |
-
that is visible from the remote machine or by manually exposing
|
50 |
-
the port when connecting. For example, through SSH port
|
51 |
-
forwarding
|
52 |
-
|
53 |
-
```
|
54 |
-
(local) $ ssh -R 3000:127.0.0.1:3000 user@host
|
55 |
-
```
|
56 |
-
|
57 |
-
Then on a remote machine you use `view` command pointing to the
|
58 |
-
locally forwarded port
|
59 |
-
|
60 |
-
```
|
61 |
-
(remote) $ meshviewer view -p 3000 sphere.obj
|
62 |
-
```
|
63 |
-
|
64 |
-
This should display the remote mesh on your local viewer. In case it
|
65 |
-
does not it might be caused by the network connection being closed
|
66 |
-
before the mesh could be sent. To work around this one can try
|
67 |
-
increasing the timeout up to 1 second
|
68 |
-
|
69 |
-
```
|
70 |
-
(remote) $ meshviewer view -p 3000 --timeout 1 sphere.obj
|
71 |
-
```
|
72 |
-
|
73 |
-
To take a snapshot you should locally run a `snap` command
|
74 |
-
|
75 |
-
```
|
76 |
-
(local) $ meshviewer snap -p 3000 sphere.png
|
77 |
-
```
|
78 |
-
""")
|
79 |
-
|
80 |
-
|
81 |
-
import argparse
|
82 |
-
import logging
|
83 |
-
import sys
|
84 |
-
import time
|
85 |
-
|
86 |
-
from psbody.mesh.mesh import Mesh
|
87 |
-
from psbody.mesh.meshviewer import (
|
88 |
-
MESH_VIEWER_DEFAULT_TITLE,
|
89 |
-
MESH_VIEWER_DEFAULT_SHAPE,
|
90 |
-
MESH_VIEWER_DEFAULT_WIDTH,
|
91 |
-
MESH_VIEWER_DEFAULT_HEIGHT,
|
92 |
-
ZMQ_HOST,
|
93 |
-
MeshViewerLocal,
|
94 |
-
MeshViewerRemote)
|
95 |
-
|
96 |
-
|
97 |
-
logging.basicConfig(level=logging.INFO)
|
98 |
-
|
99 |
-
|
100 |
-
parser_root = argparse.ArgumentParser(
|
101 |
-
add_help=False,
|
102 |
-
description="View the polygonal meshes, locally and across the network",
|
103 |
-
epilog=__doc__,
|
104 |
-
formatter_class=argparse.RawTextHelpFormatter)
|
105 |
-
|
106 |
-
subparsers = parser_root.add_subparsers(dest="command")
|
107 |
-
subparsers.required = True
|
108 |
-
|
109 |
-
parser_open = subparsers.add_parser("open", add_help=False)
|
110 |
-
parser_open.add_argument(
|
111 |
-
"-p", "--port",
|
112 |
-
help="local port to listen for incoming commands",
|
113 |
-
type=int)
|
114 |
-
|
115 |
-
parser_view = subparsers.add_parser("view", add_help=False)
|
116 |
-
parser_view.add_argument(
|
117 |
-
"-h", "--host",
|
118 |
-
help="remote host",
|
119 |
-
metavar="HOSTNAME",
|
120 |
-
type=str)
|
121 |
-
parser_view.add_argument(
|
122 |
-
"-p", "--port",
|
123 |
-
help="remote port",
|
124 |
-
type=int)
|
125 |
-
parser_view.add_argument(
|
126 |
-
"-ix", "--subwindow-index-horizontal",
|
127 |
-
help="horizontal index of the target subwindow",
|
128 |
-
metavar="INDEX",
|
129 |
-
type=int)
|
130 |
-
parser_view.add_argument(
|
131 |
-
"-iy", "--subwindow-index-vertical",
|
132 |
-
help="vertical index of the target subwindow",
|
133 |
-
metavar="INDEX",
|
134 |
-
type=int)
|
135 |
-
parser_view.add_argument(
|
136 |
-
"--timeout",
|
137 |
-
help="wait for some time after sending the mesh to let it render",
|
138 |
-
metavar="SECONDS",
|
139 |
-
type=float,
|
140 |
-
default=0.5)
|
141 |
-
parser_view.add_argument(
|
142 |
-
"filename",
|
143 |
-
help="path to the mesh file",
|
144 |
-
type=str,
|
145 |
-
nargs="+")
|
146 |
-
|
147 |
-
for parser in parser_open, parser_view:
|
148 |
-
window_options = parser.add_argument_group("window options")
|
149 |
-
window_options.add_argument(
|
150 |
-
"-t", "--title",
|
151 |
-
help="window title",
|
152 |
-
type=str)
|
153 |
-
window_options.add_argument(
|
154 |
-
"-ww", "-wx", "--window-width",
|
155 |
-
help="window width in pixels",
|
156 |
-
metavar="PIXELS",
|
157 |
-
type=int)
|
158 |
-
window_options.add_argument(
|
159 |
-
"-wh", "-wy", "--window-height",
|
160 |
-
help="window height in pixels",
|
161 |
-
metavar="PIXELS",
|
162 |
-
type=int)
|
163 |
-
window_options.add_argument(
|
164 |
-
"-nx", "--subwindow-number-horizontal",
|
165 |
-
help="number of horizontal subwindows",
|
166 |
-
metavar="NUMBER",
|
167 |
-
type=int)
|
168 |
-
window_options.add_argument(
|
169 |
-
"-ny", "--subwindow-number-vertical",
|
170 |
-
help="number of vertical subwindows",
|
171 |
-
metavar="NUMBER",
|
172 |
-
type=int)
|
173 |
-
|
174 |
-
parser_snap = subparsers.add_parser("snap", add_help=False)
|
175 |
-
parser_snap.add_argument(
|
176 |
-
"-h", "--host",
|
177 |
-
help="remote host",
|
178 |
-
type=str)
|
179 |
-
parser_snap.add_argument(
|
180 |
-
"-p", "--port",
|
181 |
-
help="remote port",
|
182 |
-
type=int,
|
183 |
-
required=True)
|
184 |
-
parser_snap.add_argument(
|
185 |
-
"filename",
|
186 |
-
help="path to the output snapshot",
|
187 |
-
type=str)
|
188 |
-
|
189 |
-
|
190 |
-
for p in parser_root, parser_open, parser_view, parser_snap:
|
191 |
-
p.add_argument("--help", action="help")
|
192 |
-
|
193 |
-
|
194 |
-
def dispatch_command(args):
|
195 |
-
"""
|
196 |
-
Performs a sanity check of the passed arguments and then
|
197 |
-
dispatches the appropriate command.
|
198 |
-
"""
|
199 |
-
|
200 |
-
if args.command == "open":
|
201 |
-
start_server(args)
|
202 |
-
return
|
203 |
-
|
204 |
-
if not args.port:
|
205 |
-
client = start_local_client(args)
|
206 |
-
else:
|
207 |
-
client = start_remote_client(args)
|
208 |
-
|
209 |
-
if args.command == "snap":
|
210 |
-
take_snapshot(client, args)
|
211 |
-
|
212 |
-
if args.command == "view":
|
213 |
-
if args.port is not None:
|
214 |
-
# Below is a list of contradicting settings: it futile to
|
215 |
-
# try to change the parameters of a mesh viewer already
|
216 |
-
# running on a remote machine.
|
217 |
-
if args.title is not None:
|
218 |
-
logging.warning(
|
219 |
-
"--title is ignored when working with remote viewer")
|
220 |
-
|
221 |
-
if args.window_width is not None:
|
222 |
-
logging.warning(
|
223 |
-
"--window-width is ignored when working with remote viewer")
|
224 |
-
|
225 |
-
if args.window_height is not None:
|
226 |
-
logging.warning(
|
227 |
-
"--window-height is ignored when working with remote viewer")
|
228 |
-
|
229 |
-
if args.subwindow_number_horizontal is not None:
|
230 |
-
logging.warning(
|
231 |
-
"--subwindow-number-horizontal is ignored when working "
|
232 |
-
"with remote viewer")
|
233 |
-
|
234 |
-
if args.subwindow_number_vertical is not None:
|
235 |
-
logging.warning(
|
236 |
-
"--subwindow-number-vertical is ignored when working "
|
237 |
-
"with remote viewer")
|
238 |
-
|
239 |
-
# This one is a bit different: while it should be
|
240 |
-
# technically possible to stream the mesh in a specific
|
241 |
-
# subwindow, we currently don't support that.
|
242 |
-
if (
|
243 |
-
args.subwindow_index_horizontal is not None or
|
244 |
-
args.subwindow_index_vertical is not None
|
245 |
-
):
|
246 |
-
logging.warning(
|
247 |
-
"unfortunately, drawing to a specific subwindow is not "
|
248 |
-
"supported when working with remote viewer and the first "
|
249 |
-
"subwindow is going to be used instead")
|
250 |
-
|
251 |
-
if (
|
252 |
-
args.subwindow_index_horizontal is not None and
|
253 |
-
args.subwindow_index_vertical is None
|
254 |
-
) or (
|
255 |
-
args.subwindow_index_horizontal is None and
|
256 |
-
args.subwindow_index_vertical is not None
|
257 |
-
):
|
258 |
-
logging.fatal(
|
259 |
-
"you have to specify both horizontal "
|
260 |
-
"and vertical subwindow incides")
|
261 |
-
return
|
262 |
-
|
263 |
-
if (
|
264 |
-
args.subwindow_index_horizontal is not None and
|
265 |
-
args.subwindow_index_vertical is not None
|
266 |
-
):
|
267 |
-
display_single_subwindow(client, args)
|
268 |
-
else:
|
269 |
-
display_multi_subwindows(client, args)
|
270 |
-
|
271 |
-
# Basically, wait for send_pyobj() to actually send everything
|
272 |
-
# before terminating.
|
273 |
-
time.sleep(args.timeout)
|
274 |
-
|
275 |
-
|
276 |
-
def start_server(args):
|
277 |
-
"""
|
278 |
-
Starts a meshviewer window on a local machine.
|
279 |
-
|
280 |
-
This function opens a mesh viewer window that listens for command
|
281 |
-
on a given port.
|
282 |
-
"""
|
283 |
-
server = MeshViewerRemote(
|
284 |
-
titlebar=args.title or MESH_VIEWER_DEFAULT_TITLE,
|
285 |
-
subwins_vert=args.subwindow_number_vertical or MESH_VIEWER_DEFAULT_SHAPE[1],
|
286 |
-
subwins_horz=args.subwindow_number_horizontal or MESH_VIEWER_DEFAULT_SHAPE[0],
|
287 |
-
width=args.window_width or MESH_VIEWER_DEFAULT_WIDTH,
|
288 |
-
height=args.window_height or MESH_VIEWER_DEFAULT_HEIGHT,
|
289 |
-
port=args.port)
|
290 |
-
return server
|
291 |
-
|
292 |
-
|
293 |
-
def start_local_client(args):
|
294 |
-
"""
|
295 |
-
Starts a local meshviewer not connected to anywhere.
|
296 |
-
|
297 |
-
This function internally opens a mesh viewer window listening on a
|
298 |
-
random port.
|
299 |
-
"""
|
300 |
-
client = MeshViewerLocal(
|
301 |
-
titlebar=args.title or MESH_VIEWER_DEFAULT_TITLE,
|
302 |
-
window_width=args.window_width or MESH_VIEWER_DEFAULT_WIDTH,
|
303 |
-
window_height=args.window_height or MESH_VIEWER_DEFAULT_HEIGHT,
|
304 |
-
shape=(
|
305 |
-
args.subwindow_number_vertical or 1,
|
306 |
-
args.subwindow_number_horizontal or len(args.filename),
|
307 |
-
),
|
308 |
-
keepalive=True)
|
309 |
-
return client
|
310 |
-
|
311 |
-
|
312 |
-
def start_remote_client(args):
|
313 |
-
"""
|
314 |
-
Starts a meshviewer client connected to a remote machine.
|
315 |
-
|
316 |
-
This function does not create a new window, but is necessary to
|
317 |
-
stream the mesh to a remote viewer.
|
318 |
-
"""
|
319 |
-
client = MeshViewerLocal(
|
320 |
-
host=args.host or ZMQ_HOST,
|
321 |
-
port=args.port)
|
322 |
-
return client
|
323 |
-
|
324 |
-
|
325 |
-
def display_single_subwindow(client, args):
|
326 |
-
"""
|
327 |
-
Displays a single mesh in a given subwindow.
|
328 |
-
"""
|
329 |
-
ix = args.subwindow_index_horizontal
|
330 |
-
iy = args.subwindow_index_vertical
|
331 |
-
|
332 |
-
try:
|
333 |
-
subwindow = client.get_subwindows()[iy][ix]
|
334 |
-
except IndexError:
|
335 |
-
logging.fatal(
|
336 |
-
"cannot find subwindow ({}, {}). "
|
337 |
-
"The current viewer shape is {}x{} subwindows, "
|
338 |
-
"indexing is zero-based."
|
339 |
-
.format(ix, iy, *client.shape))
|
340 |
-
return
|
341 |
-
|
342 |
-
meshes = [Mesh(filename=filename) for filename in args.filename]
|
343 |
-
subwindow.set_static_meshes(meshes)
|
344 |
-
|
345 |
-
|
346 |
-
def display_multi_subwindows(client, args):
|
347 |
-
"""
|
348 |
-
Displays a list of meshes. One mesh per subwindow.
|
349 |
-
"""
|
350 |
-
grid = client.get_subwindows()
|
351 |
-
|
352 |
-
subwindows = [
|
353 |
-
subwindow
|
354 |
-
for row in grid
|
355 |
-
for subwindow in row
|
356 |
-
]
|
357 |
-
|
358 |
-
if len(subwindows) < len(args.filename):
|
359 |
-
logging.warning(
|
360 |
-
"cannot display {0} meshes in {1} subwindows. "
|
361 |
-
"Taking the first {1}.".format(
|
362 |
-
len(args.filename), len(subwindows)))
|
363 |
-
|
364 |
-
for subwindow, filename in zip(subwindows, args.filename):
|
365 |
-
mesh = Mesh(filename=filename)
|
366 |
-
subwindow.set_static_meshes([mesh])
|
367 |
-
|
368 |
-
|
369 |
-
def take_snapshot(client, args):
|
370 |
-
"""
|
371 |
-
Take snapshot and dump it into a file.
|
372 |
-
"""
|
373 |
-
client.save_snapshot(args.filename)
|
374 |
-
|
375 |
-
|
376 |
-
if __name__ == "__main__":
|
377 |
-
args = parser_root.parse_args()
|
378 |
-
dispatch_command(args)
|
379 |
-
sys.exit(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mesh-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/data/unittest/test_box_le.ply
DELETED
Binary file (422 Bytes)
|
|
mesh-master/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-master/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-master/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-master/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-master/doc/source/index.rst
DELETED
@@ -1,193 +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 |
-
|
25 |
-
This package contains core functions for manipulating Meshes and visualizing them.
|
26 |
-
It requires ``Python 3.5+`` and is supported on Linux and macOS operating systems.
|
27 |
-
|
28 |
-
Getting started
|
29 |
-
===============
|
30 |
-
|
31 |
-
Installation
|
32 |
-
------------
|
33 |
-
|
34 |
-
You can download the latest release of the ``psbody-mesh`` package
|
35 |
-
from the projects `GitHub repository <https://github.com/MPI-IS/mesh>`_.
|
36 |
-
To install, first you should create a dedicated Python virtual
|
37 |
-
environment and activate it:
|
38 |
-
|
39 |
-
.. code::
|
40 |
-
|
41 |
-
$ python3 -m venv --copies my_venv
|
42 |
-
$ source my_venv/bin/activate
|
43 |
-
|
44 |
-
To compile the binary extensions you will need to install the `Boost
|
45 |
-
<http://www.boost.org>`_ libraries. You can compile your own local
|
46 |
-
version or simply do:
|
47 |
-
|
48 |
-
.. code::
|
49 |
-
|
50 |
-
$ sudo apt-get install libboost-dev
|
51 |
-
|
52 |
-
and then compile and install the ``psbody-mesh`` package using the
|
53 |
-
Makefile. If you are using the system-wide ``Boost libraries``:
|
54 |
-
|
55 |
-
.. code::
|
56 |
-
|
57 |
-
$ make all
|
58 |
-
|
59 |
-
or the libraries locally installed:
|
60 |
-
|
61 |
-
.. code::
|
62 |
-
|
63 |
-
$ BOOST_INCLUDE_DIRS=/path/to/boost/include make all
|
64 |
-
|
65 |
-
Testing
|
66 |
-
-------
|
67 |
-
|
68 |
-
To run the tests simply do:
|
69 |
-
|
70 |
-
.. code::
|
71 |
-
|
72 |
-
$ make tests
|
73 |
-
|
74 |
-
Documentation
|
75 |
-
-------------
|
76 |
-
|
77 |
-
A detailed documentation can be compiled using the Makefile:
|
78 |
-
|
79 |
-
.. code::
|
80 |
-
|
81 |
-
$ make documentation
|
82 |
-
|
83 |
-
Loading a mesh
|
84 |
-
--------------
|
85 |
-
|
86 |
-
Loading a :py:class:`Mesh <psbody.mesh.mesh.Mesh>` class from a file is that easy:
|
87 |
-
|
88 |
-
.. code::
|
89 |
-
|
90 |
-
from psbody.mesh import Mesh
|
91 |
-
my_mesh = Mesh(filename='mesh_filename.ply')
|
92 |
-
|
93 |
-
Rendering a mesh
|
94 |
-
----------------
|
95 |
-
|
96 |
-
From a previously loaded mesh ``my_mesh``, it is possible to visualize it inside an interactive window using the
|
97 |
-
:py:class:`MeshViewers <psbody.mesh.meshviewer.MeshViewers>` class:
|
98 |
-
|
99 |
-
.. code::
|
100 |
-
|
101 |
-
from psbody.mesh import MeshViewers
|
102 |
-
|
103 |
-
# creates a grid of 2x2 mesh viewers
|
104 |
-
mvs = MeshViewers(shape=[2, 2])
|
105 |
-
|
106 |
-
# sets the first (top-left) mesh to my_mesh
|
107 |
-
mvs[0][0].set_static_meshes([my_mesh])
|
108 |
-
|
109 |
-
Caching
|
110 |
-
-------
|
111 |
-
|
112 |
-
Some operations make use of caching for performance reasons. The default folder used for caching is
|
113 |
-
|
114 |
-
.. code::
|
115 |
-
|
116 |
-
~/.psbody/mesh_package_cache
|
117 |
-
|
118 |
-
|
119 |
-
If you need to specify the cache folder, define the environment variable ``PSBODY_MESH_CACHE``
|
120 |
-
prior to any loading of the Mesh package:
|
121 |
-
|
122 |
-
.. code::
|
123 |
-
|
124 |
-
export PSBODY_MESH_CACHE="some/folder"
|
125 |
-
python
|
126 |
-
>> from psbody.mesh import Mesh
|
127 |
-
# now uses the specified cache
|
128 |
-
|
129 |
-
Mesh Viewer
|
130 |
-
-----------
|
131 |
-
|
132 |
-
``meshviewer`` is a program that allows you to display polygonal meshes produced by ``mesh`` package.
|
133 |
-
|
134 |
-
Viewing a mesh on a local machine
|
135 |
-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
136 |
-
|
137 |
-
The most straightforward use-case is viewing the mesh on the same machine where it is stored. To do this simply run
|
138 |
-
|
139 |
-
.. code::
|
140 |
-
|
141 |
-
$ meshviewer view sphere.obj
|
142 |
-
|
143 |
-
This will create an interactive window with your mesh rendering. You can render more than one mesh in the same window by passing several paths to ``view`` command
|
144 |
-
|
145 |
-
.. code::
|
146 |
-
|
147 |
-
$ meshviewer view sphere.obj cylinder.obj
|
148 |
-
|
149 |
-
This will arrange the subplots horizontally in a row. If you want a grid arrangement, you can specify the grid parameters explicitly
|
150 |
-
|
151 |
-
.. code::
|
152 |
-
|
153 |
-
$ meshviewer view -nx 2 -ny 2 *.obj
|
154 |
-
|
155 |
-
Viewing a mesh from a remote machine
|
156 |
-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
157 |
-
|
158 |
-
It is also possible to view a mesh stored on a remote machine. To do this you need mesh to be installed on both the local and the remote machines. You start by opening an empty viewer window listening on a network port
|
159 |
-
|
160 |
-
.. code::
|
161 |
-
|
162 |
-
(local) $ meshviewer open --port 3000
|
163 |
-
|
164 |
-
To stream a shape to this viewer you have to either pick a port that is visible from the remote machine or by manually exposing the port when connecting. For example, through SSH port forwarding
|
165 |
-
|
166 |
-
.. code::
|
167 |
-
|
168 |
-
(local) $ ssh -R 3000:127.0.0.1:3000 user@host
|
169 |
-
|
170 |
-
Then on a remote machine you use ``view`` command pointing to the locally forwarded port
|
171 |
-
|
172 |
-
.. code::
|
173 |
-
|
174 |
-
(remote) $ meshviewer view -p 3000 sphere.obj
|
175 |
-
|
176 |
-
This should display the remote mesh on your local viewer. In case it does not it might be caused by the network connection being closed before the mesh could be sent. To work around this one can try increasing the timeout up to 1 second
|
177 |
-
|
178 |
-
.. code::
|
179 |
-
|
180 |
-
(remote) $ meshviewer view -p 3000 --timeout 1 sphere.obj
|
181 |
-
|
182 |
-
To take a snapshot you should locally run a `snap` command
|
183 |
-
|
184 |
-
.. code::
|
185 |
-
|
186 |
-
(local) $ meshviewer snap -p 3000 sphere.png
|
187 |
-
|
188 |
-
Indices and tables
|
189 |
-
==================
|
190 |
-
|
191 |
-
* :ref:`genindex`
|
192 |
-
* :ref:`modindex`
|
193 |
-
* :ref:`search`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mesh-master/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-master/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-master/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-master/mesh/CMakeLists.txt
DELETED
@@ -1,99 +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 |
-
# serialization extensions
|
85 |
-
|
86 |
-
# plyutils
|
87 |
-
python_add_library(TARGET plyutils SOURCES
|
88 |
-
src/plyutils.h
|
89 |
-
src/plyutils.c
|
90 |
-
src/rply.h
|
91 |
-
src/rply.c)
|
92 |
-
set_property(TARGET plyutils PROPERTY FOLDER "SerializationExt/")
|
93 |
-
|
94 |
-
# loadobj
|
95 |
-
python_add_library(TARGET loadobj SOURCES src/py_loadobj.cpp)
|
96 |
-
target_include_directories(loadobj PRIVATE
|
97 |
-
${NUMPY_INCLUDE_PATH}
|
98 |
-
${Boost_INCLUDE_DIRS})
|
99 |
-
set_property(TARGET loadobj PROPERTY FOLDER "SerializationExt/")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mesh-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/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-master/mesh/meshviewer.py
DELETED
@@ -1,1274 +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
|
12 |
-
backend used for visualization 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
|
23 |
-
is usually performed on a forked python process. In case OpenGL is
|
24 |
-
not supported, a `DummyClass`` mesh viewer is returned.
|
25 |
-
|
26 |
-
* ``arguments=title nb_x_axis nb_y_axis width height`` a new window is
|
27 |
-
created
|
28 |
-
|
29 |
-
.. autosummary::
|
30 |
-
|
31 |
-
MeshViewer
|
32 |
-
MeshViewers
|
33 |
-
MeshViewerLocal
|
34 |
-
test_for_opengl
|
35 |
-
"""
|
36 |
-
|
37 |
-
import copy
|
38 |
-
import logging
|
39 |
-
import multiprocessing
|
40 |
-
import os
|
41 |
-
import re
|
42 |
-
import subprocess
|
43 |
-
import sys
|
44 |
-
import tempfile
|
45 |
-
import time
|
46 |
-
import traceback
|
47 |
-
|
48 |
-
import numpy as np
|
49 |
-
from OpenGL import GL, GLU, GLUT
|
50 |
-
from OpenGL.arrays.vbo import VBO
|
51 |
-
from PIL import Image
|
52 |
-
import zmq
|
53 |
-
|
54 |
-
# if this file is processed/run as a python script/standalone, especially from the
|
55 |
-
# internal command
|
56 |
-
if __package__ is not None:
|
57 |
-
from .arcball import (
|
58 |
-
ArcBallT, Matrix3fT, Matrix4fT, Point2fT,
|
59 |
-
Matrix3fMulMatrix3f, Matrix3fSetRotationFromQuat4f,
|
60 |
-
Matrix4fSetRotationFromMatrix3f)
|
61 |
-
from .geometry.tri_normals import TriNormals
|
62 |
-
from .fonts import get_textureid_with_text
|
63 |
-
from .mesh import Mesh
|
64 |
-
|
65 |
-
|
66 |
-
# this block is below the previous one to make my linter happy
|
67 |
-
if __package__ is None:
|
68 |
-
print("this file cannot be executed as a standalone python module")
|
69 |
-
print("python -m psbody.mesh.%s arguments" % (os.path.splitext(os.path.basename(__file__))[0]))
|
70 |
-
sys.exit(-1)
|
71 |
-
|
72 |
-
|
73 |
-
# Default transport and host are such that we can listen for incoming
|
74 |
-
# network connections.
|
75 |
-
ZMQ_TRANSPORT = "tcp"
|
76 |
-
ZMQ_HOST = "0.0.0.0"
|
77 |
-
# The dynamic port range.
|
78 |
-
ZMQ_PORT_MIN = 49152
|
79 |
-
ZMQ_PORT_MAX = 65535
|
80 |
-
|
81 |
-
MESH_VIEWER_DEFAULT_TITLE = "Mesh Viewer"
|
82 |
-
MESH_VIEWER_DEFAULT_SHAPE = (1, 1)
|
83 |
-
MESH_VIEWER_DEFAULT_WIDTH = 1280
|
84 |
-
MESH_VIEWER_DEFAULT_HEIGHT = 960
|
85 |
-
|
86 |
-
|
87 |
-
def _run_self(args, stdin=None, stdout=None, stderr=None):
|
88 |
-
"""Executes this same script module with the given arguments (forking without subprocess dependencies)"""
|
89 |
-
return subprocess.Popen([sys.executable] +
|
90 |
-
['-m'] + ['%s.%s' % (__package__, os.path.splitext(os.path.basename(__file__))[0])] +
|
91 |
-
args,
|
92 |
-
stdin=stdin,
|
93 |
-
stdout=stdout, # if stdout is not None else subprocess.PIPE,
|
94 |
-
stderr=stderr)
|
95 |
-
|
96 |
-
|
97 |
-
def _test_for_opengl():
|
98 |
-
try:
|
99 |
-
# from OpenGL.GLUT import glutInit
|
100 |
-
GLUT.glutInit()
|
101 |
-
except Exception as e:
|
102 |
-
print(e, file=sys.stderr)
|
103 |
-
print('failure')
|
104 |
-
else:
|
105 |
-
print('success')
|
106 |
-
|
107 |
-
|
108 |
-
test_for_opengl_cached = None
|
109 |
-
|
110 |
-
|
111 |
-
def test_for_opengl():
|
112 |
-
"""Tests if opengl is supported.
|
113 |
-
|
114 |
-
.. note:: the result of the test is cached
|
115 |
-
|
116 |
-
"""
|
117 |
-
|
118 |
-
global test_for_opengl_cached
|
119 |
-
if test_for_opengl_cached is None:
|
120 |
-
|
121 |
-
with open(os.devnull) as dev_null, \
|
122 |
-
tempfile.TemporaryFile() as out, \
|
123 |
-
tempfile.TemporaryFile() as err:
|
124 |
-
|
125 |
-
p = _run_self(["TEST_FOR_OPENGL"],
|
126 |
-
stdin=dev_null,
|
127 |
-
stdout=out,
|
128 |
-
stderr=err)
|
129 |
-
p.wait()
|
130 |
-
|
131 |
-
out.seek(0)
|
132 |
-
err.seek(0)
|
133 |
-
|
134 |
-
line = ''.join(out.read().decode())
|
135 |
-
test_for_opengl_cached = 'success' in line
|
136 |
-
if not test_for_opengl_cached:
|
137 |
-
print('OpenGL test failed: ')
|
138 |
-
print('\tstdout:', line)
|
139 |
-
print('\tstderr:', '\n'.join(err.read().decode()))
|
140 |
-
|
141 |
-
return test_for_opengl_cached
|
142 |
-
|
143 |
-
|
144 |
-
class Dummy:
|
145 |
-
|
146 |
-
def __getattr__(self, name):
|
147 |
-
return Dummy()
|
148 |
-
|
149 |
-
def __call__(self, *args, **kwargs):
|
150 |
-
return Dummy()
|
151 |
-
|
152 |
-
def __getitem__(self, key):
|
153 |
-
return Dummy()
|
154 |
-
|
155 |
-
def __setitem__(self, key, value):
|
156 |
-
pass
|
157 |
-
|
158 |
-
|
159 |
-
def MeshViewer(titlebar='Mesh Viewer',
|
160 |
-
static_meshes=None,
|
161 |
-
static_lines=None,
|
162 |
-
uid=None,
|
163 |
-
autorecenter=True,
|
164 |
-
shape=(1, 1),
|
165 |
-
keepalive=True,
|
166 |
-
window_width=1280,
|
167 |
-
window_height=960,
|
168 |
-
snapshot_camera=None):
|
169 |
-
"""Allows visual inspection of geometric primitives.
|
170 |
-
|
171 |
-
Write-only Attributes:
|
172 |
-
|
173 |
-
:param titlebar: string printed in the window titlebar
|
174 |
-
:param static_meshes: list of Mesh objects to be displayed
|
175 |
-
:param static_lines: list of Lines objects to be displayed
|
176 |
-
|
177 |
-
.. note:: `static_meshes` is meant for Meshes that are updated infrequently,
|
178 |
-
`and dynamic_meshes` is for Meshes that are updated frequently
|
179 |
-
(same for `dynamic_lines` vs. `static_lines`).
|
180 |
-
They may be treated differently for performance reasons.
|
181 |
-
|
182 |
-
"""
|
183 |
-
|
184 |
-
if not test_for_opengl():
|
185 |
-
return Dummy()
|
186 |
-
|
187 |
-
mv = MeshViewerLocal(shape=(1, 1),
|
188 |
-
uid=uid,
|
189 |
-
titlebar=titlebar,
|
190 |
-
keepalive=keepalive,
|
191 |
-
window_width=window_width,
|
192 |
-
window_height=window_height)
|
193 |
-
result = mv.get_subwindows()[0][0]
|
194 |
-
result.snapshot_camera = snapshot_camera
|
195 |
-
if static_meshes:
|
196 |
-
result.static_meshes = static_meshes
|
197 |
-
if static_lines:
|
198 |
-
result.static_lines = static_lines
|
199 |
-
result.autorecenter = autorecenter
|
200 |
-
|
201 |
-
return result
|
202 |
-
|
203 |
-
|
204 |
-
def MeshViewers(shape=(1, 1),
|
205 |
-
titlebar="Mesh Viewers",
|
206 |
-
keepalive=True,
|
207 |
-
window_width=1280,
|
208 |
-
window_height=960):
|
209 |
-
"""Allows subplot-style inspection of primitives in multiple subwindows.
|
210 |
-
|
211 |
-
:param shape: a tuple indicating the number of vertical and horizontal windows requested
|
212 |
-
:param titlebar: the title appearing on the created window
|
213 |
-
|
214 |
-
|
215 |
-
Returns: a list of lists of MeshViewer objects: one per window requested.
|
216 |
-
"""
|
217 |
-
|
218 |
-
if not test_for_opengl():
|
219 |
-
return Dummy()
|
220 |
-
|
221 |
-
mv = MeshViewerLocal(shape=shape,
|
222 |
-
titlebar=titlebar,
|
223 |
-
uid=None,
|
224 |
-
keepalive=keepalive,
|
225 |
-
window_width=window_width,
|
226 |
-
window_height=window_height)
|
227 |
-
return mv.get_subwindows()
|
228 |
-
|
229 |
-
|
230 |
-
class MeshSubwindow:
|
231 |
-
|
232 |
-
def __init__(self, parent_window, which_window):
|
233 |
-
self.parent_window = parent_window
|
234 |
-
self.which_window = which_window
|
235 |
-
|
236 |
-
def set_dynamic_meshes(self, list_of_meshes, blocking=False):
|
237 |
-
self.parent_window.set_dynamic_meshes(list_of_meshes, blocking, self.which_window)
|
238 |
-
|
239 |
-
def set_static_meshes(self, list_of_meshes, blocking=False):
|
240 |
-
self.parent_window.set_static_meshes(list_of_meshes, blocking, self.which_window)
|
241 |
-
|
242 |
-
# list_of_model_names_and_parameters should be of form [{'name': scape_model_name, 'parameters': scape_model_parameters}]
|
243 |
-
# here scape_model_name is the filepath of the scape model.
|
244 |
-
def set_dynamic_models(self, list_of_model_names_and_parameters, blocking=False):
|
245 |
-
self.parent_window.set_dynamic_models(list_of_model_names_and_parameters, blocking, self.which_window)
|
246 |
-
|
247 |
-
def set_dynamic_lines(self, list_of_lines, blocking=False):
|
248 |
-
self.parent_window.set_dynamic_lines(list_of_lines, blocking, self.which_window)
|
249 |
-
|
250 |
-
def set_static_lines(self, list_of_lines, blocking=False):
|
251 |
-
self.parent_window.set_static_lines(list_of_lines, blocking=blocking, which_window=self.which_window)
|
252 |
-
|
253 |
-
def set_titlebar(self, titlebar, blocking=False):
|
254 |
-
self.parent_window.set_titlebar(titlebar, blocking, which_window=self.which_window)
|
255 |
-
|
256 |
-
def set_lighting_on(self, lighting_on, blocking=True):
|
257 |
-
self.parent_window.set_lighting_on(lighting_on, blocking=blocking, which_window=self.which_window)
|
258 |
-
|
259 |
-
def set_autorecenter(self, autorecenter, blocking=False):
|
260 |
-
self.parent_window.set_autorecenter(autorecenter, blocking=blocking, which_window=self.which_window)
|
261 |
-
|
262 |
-
def set_background_color(self, background_color, blocking=False):
|
263 |
-
self.parent_window.set_background_color(background_color, blocking=blocking, which_window=self.which_window)
|
264 |
-
|
265 |
-
def save_snapshot(self, path, blocking=False):
|
266 |
-
self.parent_window.save_snapshot(
|
267 |
-
path, blocking=blocking, which_window=self.which_window)
|
268 |
-
|
269 |
-
def get_event(self):
|
270 |
-
return self.parent_window.get_event()
|
271 |
-
|
272 |
-
def get_keypress(self):
|
273 |
-
return self.parent_window.get_keypress()['key']
|
274 |
-
|
275 |
-
def get_mouseclick(self):
|
276 |
-
return self.parent_window.get_mouseclick()
|
277 |
-
|
278 |
-
def close(self):
|
279 |
-
self.parent_window.p.terminate()
|
280 |
-
|
281 |
-
background_color = property(fset=set_background_color, doc="Background color, as 3-element numpy array where 0 <= color <= 1.0.")
|
282 |
-
dynamic_meshes = property(fset=set_dynamic_meshes, doc="List of meshes for dynamic display.")
|
283 |
-
static_meshes = property(fset=set_static_meshes, doc="List of meshes for static display.")
|
284 |
-
dynamic_models = property(fset=set_dynamic_models, doc="List of model names and parameters for dynamic display.")
|
285 |
-
dynamic_lines = property(fset=set_dynamic_lines, doc="List of Lines for dynamic display.")
|
286 |
-
static_lines = property(fset=set_static_lines, doc="List of Lines for static display.")
|
287 |
-
titlebar = property(fset=set_titlebar, doc="Titlebar string.")
|
288 |
-
lighting_on = property(fset=set_lighting_on, doc="Titlebar string.")
|
289 |
-
|
290 |
-
|
291 |
-
class MeshViewerSingle:
|
292 |
-
|
293 |
-
def __init__(self, x1_pct, y1_pct, width_pct, height_pct):
|
294 |
-
assert(width_pct <= 1)
|
295 |
-
assert(height_pct <= 1)
|
296 |
-
self.dynamic_meshes = []
|
297 |
-
self.static_meshes = []
|
298 |
-
self.dynamic_models = []
|
299 |
-
self.dynamic_lines = []
|
300 |
-
self.static_lines = []
|
301 |
-
self.lighting_on = True
|
302 |
-
self.scape_models = {}
|
303 |
-
self.x1_pct = x1_pct
|
304 |
-
self.y1_pct = y1_pct
|
305 |
-
self.width_pct = width_pct
|
306 |
-
self.height_pct = height_pct
|
307 |
-
self.autorecenter = True
|
308 |
-
|
309 |
-
def get_dimensions(self):
|
310 |
-
d = {}
|
311 |
-
d['window_width'] = GLUT.glutGet(GLUT.GLUT_WINDOW_WIDTH)
|
312 |
-
d['window_height'] = GLUT.glutGet(GLUT.GLUT_WINDOW_HEIGHT)
|
313 |
-
d['subwindow_width'] = self.width_pct * d['window_width']
|
314 |
-
d['subwindow_height'] = self.height_pct * d['window_height']
|
315 |
-
d['subwindow_origin_x'] = self.x1_pct * d['window_width']
|
316 |
-
d['subwindow_origin_y'] = self.y1_pct * d['window_height']
|
317 |
-
return d
|
318 |
-
|
319 |
-
def on_draw(self, transform, want_camera=False):
|
320 |
-
|
321 |
-
d = self.get_dimensions()
|
322 |
-
|
323 |
-
GL.glViewport(
|
324 |
-
int(d['subwindow_origin_x']),
|
325 |
-
int(d['subwindow_origin_y']),
|
326 |
-
int(d['subwindow_width']),
|
327 |
-
int(d['subwindow_height']))
|
328 |
-
|
329 |
-
GL.glMatrixMode(GL.GL_PROJECTION)
|
330 |
-
GL.glLoadIdentity()
|
331 |
-
|
332 |
-
fov_degrees = 45.
|
333 |
-
near = 1.0
|
334 |
-
far = 100.
|
335 |
-
ratio = float(d['subwindow_width']) / float(d['subwindow_height'])
|
336 |
-
if d['subwindow_width'] < d['subwindow_height']:
|
337 |
-
xt = np.tan(fov_degrees * np.pi / 180. / 2.0) * near
|
338 |
-
yt = xt / ratio
|
339 |
-
GL.glFrustum(-xt, xt, -yt, yt, near, far)
|
340 |
-
else:
|
341 |
-
GLU.gluPerspective(fov_degrees, ratio, near, far)
|
342 |
-
|
343 |
-
GL.glMatrixMode(GL.GL_MODELVIEW)
|
344 |
-
GL.glLoadIdentity()
|
345 |
-
GL.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_TRUE)
|
346 |
-
|
347 |
-
GL.glTranslatef(0.0, 0.0, -6.0)
|
348 |
-
# GL.glTranslatef(0.0,0.0,-3.5)
|
349 |
-
|
350 |
-
GL.glPushMatrix()
|
351 |
-
GL.glMultMatrixf(transform)
|
352 |
-
GL.glColor3f(1.0, 0.75, 0.75)
|
353 |
-
|
354 |
-
if self.autorecenter:
|
355 |
-
camera = self.draw_primitives_recentered(want_camera=want_camera)
|
356 |
-
else:
|
357 |
-
if hasattr(self, 'current_center') and hasattr(self, 'current_scalefactor'):
|
358 |
-
camera = self.draw_primitives(scalefactor=self.current_scalefactor, center=self.current_center)
|
359 |
-
else:
|
360 |
-
camera = self.draw_primitives(want_camera=want_camera)
|
361 |
-
|
362 |
-
GL.glPopMatrix()
|
363 |
-
|
364 |
-
if want_camera:
|
365 |
-
return camera
|
366 |
-
|
367 |
-
def draw_primitives_recentered(self, want_camera=False):
|
368 |
-
return self.draw_primitives(recenter=True, want_camera=want_camera)
|
369 |
-
|
370 |
-
@staticmethod
|
371 |
-
def set_shaders(m):
|
372 |
-
VERTEX_SHADER = GL.shaders.compileShader("""void main() {
|
373 |
-
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
374 |
-
}""", GL.GL_VERTEX_SHADER)
|
375 |
-
FRAGMENT_SHADER = GL.shaders.compileShader("""void main() {
|
376 |
-
gl_FragColor = vec4( 0, 1, 0, 1 );
|
377 |
-
}""", GL.GL_FRAGMENT_SHADER)
|
378 |
-
m.shaders = GL.shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
|
379 |
-
|
380 |
-
@staticmethod
|
381 |
-
def set_texture(m):
|
382 |
-
texture_data = np.array(m.texture_image, dtype='int8')
|
383 |
-
m.textureID = GL.glGenTextures(1)
|
384 |
-
GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1)
|
385 |
-
GL.glBindTexture(GL.GL_TEXTURE_2D, m.textureID)
|
386 |
-
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, texture_data.shape[1], texture_data.shape[0], 0, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, texture_data.flatten())
|
387 |
-
GL.glHint(GL.GL_GENERATE_MIPMAP_HINT, GL.GL_NICEST) # must be GL_FASTEST, GL.GL_NICEST or GL_DONT_CARE
|
388 |
-
GL.glGenerateMipmap(GL.GL_TEXTURE_2D)
|
389 |
-
|
390 |
-
@staticmethod
|
391 |
-
def draw_mesh(m, lighting_on):
|
392 |
-
|
393 |
-
# Supply vertices
|
394 |
-
GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
|
395 |
-
m.vbo['v'].bind()
|
396 |
-
GL.glVertexPointer(3, GL.GL_FLOAT, 0, m.vbo['v'])
|
397 |
-
m.vbo['v'].unbind()
|
398 |
-
|
399 |
-
# Supply normals
|
400 |
-
if 'vn' in m.vbo.keys():
|
401 |
-
GL.glEnableClientState(GL.GL_NORMAL_ARRAY)
|
402 |
-
m.vbo['vn'].bind()
|
403 |
-
GL.glNormalPointer(GL.GL_FLOAT, 0, m.vbo['vn'])
|
404 |
-
m.vbo['vn'].unbind()
|
405 |
-
else:
|
406 |
-
GL.glDisableClientState(GL.GL_NORMAL_ARRAY)
|
407 |
-
|
408 |
-
# Supply colors
|
409 |
-
if 'vc' in m.vbo.keys():
|
410 |
-
GL.glEnableClientState(GL.GL_COLOR_ARRAY)
|
411 |
-
m.vbo['vc'].bind()
|
412 |
-
GL.glColorPointer(3, GL.GL_FLOAT, 0, m.vbo['vc'])
|
413 |
-
m.vbo['vc'].unbind()
|
414 |
-
else:
|
415 |
-
GL.glDisableClientState(GL.GL_COLOR_ARRAY)
|
416 |
-
|
417 |
-
if ('vt' in m.vbo.keys()) and hasattr(m, 'textureID'):
|
418 |
-
GL.glEnable(GL.GL_TEXTURE_2D)
|
419 |
-
GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST)
|
420 |
-
GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST)
|
421 |
-
GL.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE)
|
422 |
-
GL.glBindTexture(GL.GL_TEXTURE_2D, m.textureID)
|
423 |
-
|
424 |
-
GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY)
|
425 |
-
m.vbo['vt'].bind()
|
426 |
-
GL.glTexCoordPointer(2, GL.GL_FLOAT, 0, m.vbo['vt'])
|
427 |
-
m.vbo['vt'].unbind()
|
428 |
-
else:
|
429 |
-
GL.glDisable(GL.GL_TEXTURE_2D)
|
430 |
-
GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY)
|
431 |
-
|
432 |
-
# Draw
|
433 |
-
if len(m.f) > 0:
|
434 |
-
# ie if it is triangulated
|
435 |
-
if lighting_on:
|
436 |
-
GL.glEnable(GL.GL_LIGHTING)
|
437 |
-
else:
|
438 |
-
GL.glDisable(GL.GL_LIGHTING)
|
439 |
-
GL.glDrawElementsui(GL.GL_TRIANGLES, np.arange(m.f.size, dtype=np.uint32))
|
440 |
-
else:
|
441 |
-
# not triangulated, so disable lighting
|
442 |
-
GL.glDisable(GL.GL_LIGHTING)
|
443 |
-
GL.glPointSize(2)
|
444 |
-
GL.glDrawElementsui(GL.GL_POINTS, np.arange(len(m.v), dtype=np.uint32))
|
445 |
-
if hasattr(m, 'v_to_text'):
|
446 |
-
|
447 |
-
GL.glEnable(GL.GL_TEXTURE_2D)
|
448 |
-
GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
|
449 |
-
GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR)
|
450 |
-
GL.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_DECAL)
|
451 |
-
|
452 |
-
bgcolor = np.array(GL.glGetDoublev(GL.GL_COLOR_CLEAR_VALUE))
|
453 |
-
fgcolor = 1. - bgcolor
|
454 |
-
|
455 |
-
from .lines import Lines
|
456 |
-
sc = float(np.max(np.max(m.v, axis=0) - np.min(m.v, axis=0))) / 10.
|
457 |
-
|
458 |
-
cur_mtx = np.linalg.pinv(GL.glGetFloatv(GL.GL_MODELVIEW_MATRIX).T)
|
459 |
-
xdir = cur_mtx[:3, 0]
|
460 |
-
ydir = cur_mtx[:3, 1]
|
461 |
-
|
462 |
-
GL.glEnable(GL.GL_LINE_SMOOTH)
|
463 |
-
GL.glEnable(GL.GL_BLEND)
|
464 |
-
GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
|
465 |
-
|
466 |
-
for vidx, text in m.v_to_text.items():
|
467 |
-
pos0 = m.v[vidx].copy()
|
468 |
-
pos1 = m.v[vidx].copy()
|
469 |
-
if hasattr(m, 'vn'):
|
470 |
-
pos1 += m.vn[vidx] * sc
|
471 |
-
GL.glLineWidth(5.0)
|
472 |
-
ln = Lines(v=np.vstack((pos0, pos1)), e=np.array([[0, 1]]))
|
473 |
-
GL.glEnable(GL.GL_LIGHTING)
|
474 |
-
GL.glColor3f(1. - 0.8, 1. - 0.8, 1. - 1.00)
|
475 |
-
MeshViewerSingle.draw_lines(ln)
|
476 |
-
|
477 |
-
GL.glDisable(GL.GL_LIGHTING)
|
478 |
-
|
479 |
-
texture_id = get_textureid_with_text(text, bgcolor, fgcolor)
|
480 |
-
GL.glBindTexture(GL.GL_TEXTURE_2D, texture_id)
|
481 |
-
|
482 |
-
GL.glPushMatrix()
|
483 |
-
GL.glTranslatef(pos1[0], pos1[1], pos1[2])
|
484 |
-
|
485 |
-
dx = xdir * .10
|
486 |
-
dy = ydir * .10
|
487 |
-
if False:
|
488 |
-
GL.glBegin(GL.GL_QUADS)
|
489 |
-
|
490 |
-
GL.glTexCoord2f(1., 0.)
|
491 |
-
GL.glVertex3f(*(+dx + dy))
|
492 |
-
|
493 |
-
GL.glTexCoord2f(1., 1.)
|
494 |
-
GL.glVertex3f(*(+dx - dy))
|
495 |
-
|
496 |
-
GL.glTexCoord2f(0., 1.)
|
497 |
-
GL.glVertex3f(*(-dx - dy))
|
498 |
-
|
499 |
-
GL.glTexCoord2f(0., 0.)
|
500 |
-
GL.glVertex3f(*(-dx + dy))
|
501 |
-
|
502 |
-
# gluSphere(quadratic,0.05,32,32)
|
503 |
-
GL.glEnd()
|
504 |
-
else:
|
505 |
-
GL.glBegin(GL.GL_POLYGON)
|
506 |
-
|
507 |
-
for r in np.arange(0, np.pi * 2., .01):
|
508 |
-
GL.glTexCoord2f(np.cos(r) / 2. + .5, np.sin(r) / 2. + .5)
|
509 |
-
GL.glVertex3f(*(dx * np.cos(r) + -dy * np.sin(r)))
|
510 |
-
|
511 |
-
GL.glEnd()
|
512 |
-
GL.glPopMatrix()
|
513 |
-
|
514 |
-
|
515 |
-
@staticmethod
|
516 |
-
def draw_lines(ls):
|
517 |
-
GL.glDisableClientState(GL.GL_NORMAL_ARRAY)
|
518 |
-
GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
|
519 |
-
GL.glLineWidth(3.0)
|
520 |
-
allpts = ls.v[ls.e.flatten()].astype(np.float32)
|
521 |
-
GL.glVertexPointerf(allpts)
|
522 |
-
if hasattr(ls, 'vc') or hasattr(ls, 'ec'):
|
523 |
-
GL.glEnableClientState(GL.GL_COLOR_ARRAY)
|
524 |
-
if hasattr(ls, 'vc'):
|
525 |
-
GL.glColorPointerf(ls.vc[ls.e.flatten()].astype(np.float32))
|
526 |
-
else:
|
527 |
-
clrs = np.ones((ls.e.shape[0] * 2, 3)) * np.repeat(ls.ec, 2, axis=0)
|
528 |
-
GL.glColorPointerf(clrs)
|
529 |
-
else:
|
530 |
-
GL.glDisableClientState(GL.GL_COLOR_ARRAY)
|
531 |
-
|
532 |
-
GL.glDisable(GL.GL_LIGHTING)
|
533 |
-
GL.glDrawElementsui(GL.GL_LINES, np.arange(len(allpts), dtype=np.uint32))
|
534 |
-
|
535 |
-
def draw_primitives(self,
|
536 |
-
scalefactor=1.0,
|
537 |
-
center=[0.0, 0.0, 0.0],
|
538 |
-
recenter=False,
|
539 |
-
want_camera=False):
|
540 |
-
|
541 |
-
# measure the bounding box of all our primitives, so that we can
|
542 |
-
# recenter them in our field of view
|
543 |
-
if recenter:
|
544 |
-
all_meshes = self.static_meshes + self.dynamic_meshes
|
545 |
-
all_lines = self.static_lines + self.dynamic_lines
|
546 |
-
|
547 |
-
if (len(all_meshes) + len(all_lines)) == 0:
|
548 |
-
if want_camera:
|
549 |
-
return {'modelview_matrix': GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX),
|
550 |
-
'projection_matrix': GL.glGetDoublev(GL.GL_PROJECTION_MATRIX),
|
551 |
-
'viewport': GL.glGetIntegerv(GL.GL_VIEWPORT)
|
552 |
-
}
|
553 |
-
else:
|
554 |
-
return None
|
555 |
-
|
556 |
-
for m in all_meshes:
|
557 |
-
m.v = m.v.reshape((-1, 3))
|
558 |
-
|
559 |
-
all_verts = np.concatenate(
|
560 |
-
[m.v[m.f.flatten() if len(m.f) > 0 else np.arange(len(m.v))] for m in all_meshes] +
|
561 |
-
[l.v[l.e.flatten()] for l in all_lines],
|
562 |
-
axis=0)
|
563 |
-
|
564 |
-
maximum = np.max(all_verts, axis=0)
|
565 |
-
minimum = np.min(all_verts, axis=0)
|
566 |
-
center = (maximum + minimum) / 2.
|
567 |
-
scalefactor = (maximum - minimum) / 4.
|
568 |
-
scalefactor = np.max(scalefactor)
|
569 |
-
else:
|
570 |
-
center = np.array(center)
|
571 |
-
# for mesh in self.dynamic_meshes :
|
572 |
-
# if mesh.f : mesh.reset_normals()
|
573 |
-
all_meshes = self.static_meshes + self.dynamic_meshes
|
574 |
-
all_lines = self.static_lines + self.dynamic_lines
|
575 |
-
self.current_center = center
|
576 |
-
self.current_scalefactor = scalefactor
|
577 |
-
|
578 |
-
GL.glMatrixMode(GL.GL_MODELVIEW)
|
579 |
-
GL.glPushMatrix()
|
580 |
-
# uncomment to add a default rotation (useful when automatically snapshoting kinect data
|
581 |
-
# glRotate(220, 0.0, 1.0, 0.0)
|
582 |
-
|
583 |
-
tf = np.identity(4, 'f') / scalefactor
|
584 |
-
tf[:3, 3] = -center / scalefactor
|
585 |
-
tf[3, 3] = 1
|
586 |
-
cur_mtx = GL.glGetFloatv(GL.GL_MODELVIEW_MATRIX).T
|
587 |
-
|
588 |
-
GL.glLoadMatrixf(cur_mtx.dot(tf).T)
|
589 |
-
|
590 |
-
if want_camera:
|
591 |
-
result = {'modelview_matrix': GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX),
|
592 |
-
'projection_matrix': GL.glGetDoublev(GL.GL_PROJECTION_MATRIX),
|
593 |
-
'viewport': GL.glGetIntegerv(GL.GL_VIEWPORT)
|
594 |
-
}
|
595 |
-
else:
|
596 |
-
result = None
|
597 |
-
|
598 |
-
for m in all_meshes:
|
599 |
-
if not hasattr(m, 'vbo'):
|
600 |
-
# Precompute vertex vbo
|
601 |
-
fidxs = m.f.flatten() if len(m.f) > 0 else np.arange(len(m.v))
|
602 |
-
allpts = m.v[fidxs].astype(np.float32).flatten()
|
603 |
-
vbo = VBO(allpts)
|
604 |
-
m.vbo = {'v': vbo}
|
605 |
-
|
606 |
-
# Precompute normals vbo
|
607 |
-
if hasattr(m, 'vn'):
|
608 |
-
ns = m.vn.astype(np.float32)
|
609 |
-
ns = ns[m.f.flatten(), :]
|
610 |
-
m.vbo['vn'] = VBO(ns.flatten())
|
611 |
-
elif hasattr(m, 'f') and m.f.size > 0:
|
612 |
-
ns = TriNormals(m.v, m.f).reshape(-1, 3)
|
613 |
-
ns = np.tile(ns, (1, 3)).reshape(-1, 3).astype(np.float32)
|
614 |
-
m.vbo['vn'] = VBO(ns.flatten())
|
615 |
-
|
616 |
-
# Precompute texture vbo
|
617 |
-
if hasattr(m, 'ft') and (m.ft.size > 0):
|
618 |
-
ftidxs = m.ft.flatten()
|
619 |
-
data = m.vt[ftidxs].astype(np.float32)[:, 0:2]
|
620 |
-
data[:, 1] = 1.0 - 1.0 * data[:, 1]
|
621 |
-
m.vbo['vt'] = VBO(data)
|
622 |
-
|
623 |
-
# Precompute color vbo
|
624 |
-
if hasattr(m, 'vc'):
|
625 |
-
data = m.vc[fidxs].astype(np.float32)
|
626 |
-
m.vbo['vc'] = VBO(data)
|
627 |
-
elif hasattr(m, 'fc'):
|
628 |
-
data = np.tile(m.fc, (1, 3)).reshape(-1, 3).astype(np.float32)
|
629 |
-
m.vbo['vc'] = VBO(data)
|
630 |
-
|
631 |
-
for e in all_lines:
|
632 |
-
self.draw_lines(e)
|
633 |
-
|
634 |
-
for m in all_meshes:
|
635 |
-
if hasattr(m, 'texture_image') and not hasattr(m, 'textureID'):
|
636 |
-
self.set_texture(m)
|
637 |
-
self.draw_mesh(m, self.lighting_on)
|
638 |
-
|
639 |
-
GL.glMatrixMode(GL.GL_MODELVIEW)
|
640 |
-
GL.glPopMatrix()
|
641 |
-
|
642 |
-
return result
|
643 |
-
|
644 |
-
|
645 |
-
class MeshViewerLocal:
|
646 |
-
"""Proxy viewer instance for visual inspection of geometric primitives.
|
647 |
-
|
648 |
-
The class forks another python process holding the display. It communicates
|
649 |
-
the commands with the remote instance seamlessly.
|
650 |
-
|
651 |
-
Write-only attributes:
|
652 |
-
|
653 |
-
:param titlebar: string printed in the window titlebar
|
654 |
-
:param dynamic_meshes: list of Mesh objects to be displayed
|
655 |
-
:param static_meshes: list of Mesh objects to be displayed
|
656 |
-
:param dynamic_lines: list of Lines objects to be displayed
|
657 |
-
:param static_lines: list of Lines objects to be displayed
|
658 |
-
|
659 |
-
.. note::
|
660 |
-
|
661 |
-
`static_meshes` is meant for Meshes that are
|
662 |
-
updated infrequently, and dynamic_meshes is for Meshes
|
663 |
-
that are updated frequently (same for dynamic_lines vs
|
664 |
-
static_lines). They may be treated differently for
|
665 |
-
performance reasons.
|
666 |
-
|
667 |
-
"""
|
668 |
-
|
669 |
-
managed = {}
|
670 |
-
|
671 |
-
def __new__(
|
672 |
-
cls,
|
673 |
-
titlebar=MESH_VIEWER_DEFAULT_TITLE,
|
674 |
-
uid=None,
|
675 |
-
host=ZMQ_HOST,
|
676 |
-
port=None,
|
677 |
-
shape=MESH_VIEWER_DEFAULT_SHAPE,
|
678 |
-
keepalive=False,
|
679 |
-
window_width=MESH_VIEWER_DEFAULT_WIDTH,
|
680 |
-
window_height=MESH_VIEWER_DEFAULT_HEIGHT
|
681 |
-
):
|
682 |
-
|
683 |
-
assert(uid is None or isinstance(uid, str))
|
684 |
-
|
685 |
-
if uid == 'stack':
|
686 |
-
uid = ''.join(traceback.format_list(traceback.extract_stack()))
|
687 |
-
if uid and uid in MeshViewer.managed.keys():
|
688 |
-
return MeshViewer.managed[uid]
|
689 |
-
|
690 |
-
viewer = super(MeshViewerLocal, cls).__new__(cls)
|
691 |
-
|
692 |
-
viewer.remote_host = host
|
693 |
-
viewer.remote_port = port
|
694 |
-
|
695 |
-
viewer.client = zmq.Context.instance().socket(zmq.PUSH)
|
696 |
-
viewer.client.linger = 0
|
697 |
-
|
698 |
-
if viewer.remote_port:
|
699 |
-
addr = "{}://{}:{}".format(
|
700 |
-
ZMQ_TRANSPORT,
|
701 |
-
viewer.remote_host,
|
702 |
-
viewer.remote_port)
|
703 |
-
viewer.client.connect(addr)
|
704 |
-
|
705 |
-
# XXX: Proper shape querying over the network is not
|
706 |
-
# possible as of now. This should be tackled during
|
707 |
-
# refactoring in the future.
|
708 |
-
|
709 |
-
# viewer.shape = viewer.get_window_shape()
|
710 |
-
viewer.shape = (1, 1)
|
711 |
-
|
712 |
-
return viewer
|
713 |
-
|
714 |
-
with open(os.devnull) as dev_null, \
|
715 |
-
tempfile.TemporaryFile() as err:
|
716 |
-
|
717 |
-
viewer.p = _run_self([titlebar, str(shape[0]), str(shape[1]), str(window_width), str(window_height)],
|
718 |
-
stdin=dev_null,
|
719 |
-
stdout=subprocess.PIPE,
|
720 |
-
stderr=err)
|
721 |
-
|
722 |
-
line = viewer.p.stdout.readline().decode()
|
723 |
-
viewer.p.stdout.close()
|
724 |
-
current_port = re.match('<PORT>(.*?)</PORT>', line)
|
725 |
-
if not current_port:
|
726 |
-
raise Exception("MeshViewer remote appears to have failed to launch")
|
727 |
-
current_port = int(current_port.group(1))
|
728 |
-
viewer.client.connect('{}://{}:{}'.format(ZMQ_TRANSPORT, ZMQ_HOST, current_port))
|
729 |
-
|
730 |
-
logging.info(
|
731 |
-
"started remote viewer on port {}".format(current_port))
|
732 |
-
|
733 |
-
if uid:
|
734 |
-
MeshViewerLocal.managed[uid] = viewer
|
735 |
-
viewer.shape = shape
|
736 |
-
viewer.keepalive = keepalive
|
737 |
-
return viewer
|
738 |
-
|
739 |
-
def get_subwindows(self):
|
740 |
-
return [[MeshSubwindow(parent_window=self, which_window=(r, c)) for c in range(self.shape[1])] for r in range(self.shape[0])]
|
741 |
-
|
742 |
-
@staticmethod
|
743 |
-
def _sanitize_meshes(list_of_meshes):
|
744 |
-
lm = []
|
745 |
-
|
746 |
-
# have to copy the meshes for now, because some contain CPython members,
|
747 |
-
# before pushing them on the queue
|
748 |
-
for m in list_of_meshes:
|
749 |
-
if hasattr(m, 'fc'):
|
750 |
-
lm.append(Mesh(v=m.v, f=m.f, fc=m.fc))
|
751 |
-
elif hasattr(m, 'vc'):
|
752 |
-
lm.append(Mesh(v=m.v, f=m.f, vc=m.vc))
|
753 |
-
else:
|
754 |
-
lm.append(Mesh(v=m.v, f=m.f if hasattr(m, 'f') else []))
|
755 |
-
|
756 |
-
if hasattr(m, 'vn'):
|
757 |
-
lm[-1].vn = m.vn
|
758 |
-
if hasattr(m, 'fn'):
|
759 |
-
lm[-1].fn = m.fn
|
760 |
-
|
761 |
-
if hasattr(m, 'v_to_text'):
|
762 |
-
lm[-1].v_to_text = m.v_to_text
|
763 |
-
if hasattr(m, 'texture_filepath') and hasattr(m, 'vt') and hasattr(m, 'ft'):
|
764 |
-
lm[-1].texture_filepath = m.texture_filepath
|
765 |
-
lm[-1].vt = m.vt
|
766 |
-
lm[-1].ft = m.ft
|
767 |
-
|
768 |
-
return lm
|
769 |
-
|
770 |
-
def _send_pyobj(self, label, obj, blocking, which_window):
|
771 |
-
logging.debug("sending a request:")
|
772 |
-
logging.debug("\tlabel = {!r}".format(label))
|
773 |
-
logging.debug("\tobj = {!r}".format(obj))
|
774 |
-
logging.debug("\tblocking = {!r}".format(blocking))
|
775 |
-
logging.debug("\twhich_window = {!r}".format(which_window))
|
776 |
-
|
777 |
-
if blocking:
|
778 |
-
context = zmq.Context.instance()
|
779 |
-
server = context.socket(zmq.PULL)
|
780 |
-
server.linger = 0
|
781 |
-
port = server.bind_to_random_port(
|
782 |
-
"{}://{}".format(ZMQ_TRANSPORT, ZMQ_HOST),
|
783 |
-
min_port=ZMQ_PORT_MIN,
|
784 |
-
max_port=ZMQ_PORT_MAX,
|
785 |
-
max_tries=100000)
|
786 |
-
|
787 |
-
# sending with blocking'
|
788 |
-
self.client.send_pyobj({
|
789 |
-
'label': label,
|
790 |
-
'obj': obj,
|
791 |
-
'port': port,
|
792 |
-
'which_window': which_window
|
793 |
-
})
|
794 |
-
|
795 |
-
task_completion_time = server.recv_pyobj()
|
796 |
-
# task completion time was %.2fs in other process' % (task_completion_time,)
|
797 |
-
server.close()
|
798 |
-
else:
|
799 |
-
# sending nonblocking
|
800 |
-
res = self.client.send_pyobj({
|
801 |
-
'label': label,
|
802 |
-
'obj': obj,
|
803 |
-
'which_window': which_window
|
804 |
-
})
|
805 |
-
|
806 |
-
def _recv_pyobj(self, label, port=None):
|
807 |
-
context = zmq.Context.instance()
|
808 |
-
server = context.socket(zmq.PULL)
|
809 |
-
server.linger = 0
|
810 |
-
|
811 |
-
if not port:
|
812 |
-
port = server.bind_to_random_port(
|
813 |
-
"{}://{}".format(ZMQ_TRANSPORT, ZMQ_HOST),
|
814 |
-
min_port=ZMQ_PORT_MIN,
|
815 |
-
max_port=ZMQ_PORT_MAX,
|
816 |
-
max_tries=100000)
|
817 |
-
|
818 |
-
self._send_pyobj(label, port, blocking=True, which_window=(0, 0))
|
819 |
-
result = server.recv_pyobj()
|
820 |
-
server.close()
|
821 |
-
|
822 |
-
return result
|
823 |
-
|
824 |
-
def set_dynamic_meshes(self, list_of_meshes, blocking=False, which_window=(0, 0)):
|
825 |
-
self._send_pyobj('dynamic_meshes', self._sanitize_meshes(list_of_meshes), blocking, which_window)
|
826 |
-
|
827 |
-
def set_static_meshes(self, list_of_meshes, blocking=False, which_window=(0, 0)):
|
828 |
-
self._send_pyobj('static_meshes', self._sanitize_meshes(list_of_meshes), blocking, which_window)
|
829 |
-
|
830 |
-
# list_of_model_names_and_parameters should be of form [{'name': scape_model_name, 'parameters': scape_model_parameters}]
|
831 |
-
# here scape_model_name is the filepath of the scape model.
|
832 |
-
def set_dynamic_models(self, list_of_model_names_and_parameters, blocking=False, which_window=(0, 0)):
|
833 |
-
self._send_pyobj('dynamic_models', list_of_model_names_and_parameters, blocking, which_window)
|
834 |
-
|
835 |
-
def set_dynamic_lines(self, list_of_lines, blocking=False, which_window=(0, 0)):
|
836 |
-
self._send_pyobj('dynamic_lines', list_of_lines, blocking, which_window)
|
837 |
-
|
838 |
-
def set_static_lines(self, list_of_lines, blocking=False, which_window=(0, 0)):
|
839 |
-
self._send_pyobj('static_lines', list_of_lines, blocking, which_window)
|
840 |
-
|
841 |
-
def set_titlebar(self, titlebar, blocking=False, which_window=(0, 0)):
|
842 |
-
self._send_pyobj('titlebar', titlebar, blocking, which_window)
|
843 |
-
|
844 |
-
def set_lighting_on(self, lighting_on, blocking=False, which_window=(0, 0)):
|
845 |
-
self._send_pyobj('lighting_on', lighting_on, blocking, which_window)
|
846 |
-
|
847 |
-
def set_autorecenter(self, autorecenter, blocking=False, which_window=(0, 0)):
|
848 |
-
self._send_pyobj('autorecenter', autorecenter, blocking, which_window)
|
849 |
-
|
850 |
-
def set_background_color(self, background_color, blocking=False, which_window=(0, 0)):
|
851 |
-
assert(isinstance(background_color, np.ndarray))
|
852 |
-
assert(background_color.size == 3)
|
853 |
-
self._send_pyobj('background_color', background_color.flatten(), blocking, which_window)
|
854 |
-
|
855 |
-
def get_keypress(self):
|
856 |
-
return self._recv_pyobj('get_keypress')
|
857 |
-
|
858 |
-
def get_mouseclick(self):
|
859 |
-
"""Returns a mouse click event.
|
860 |
-
|
861 |
-
.. note::
|
862 |
-
|
863 |
-
the call is blocking the caller until an event is received
|
864 |
-
"""
|
865 |
-
return self._recv_pyobj('get_mouseclick')
|
866 |
-
|
867 |
-
def get_event(self):
|
868 |
-
return self._recv_pyobj('get_event')
|
869 |
-
|
870 |
-
def get_window_shape(self):
|
871 |
-
response = self._recv_pyobj("get_window_shape")
|
872 |
-
return response["shape"]
|
873 |
-
|
874 |
-
background_color = property(fset=set_background_color,
|
875 |
-
doc="Background color, as 3-element numpy array where 0 <= color <= 1.0.")
|
876 |
-
|
877 |
-
dynamic_meshes = property(fset=set_dynamic_meshes,
|
878 |
-
doc="List of meshes for dynamic display.")
|
879 |
-
static_meshes = property(fset=set_static_meshes,
|
880 |
-
doc="List of meshes for static display.")
|
881 |
-
dynamic_models = property(fset=set_dynamic_models,
|
882 |
-
doc="List of model names and parameters for dynamic display.")
|
883 |
-
|
884 |
-
dynamic_lines = property(fset=set_dynamic_lines,
|
885 |
-
doc="List of Lines for dynamic display.")
|
886 |
-
static_lines = property(fset=set_static_lines,
|
887 |
-
doc="List of Lines for static display.")
|
888 |
-
|
889 |
-
titlebar = property(fset=set_titlebar,
|
890 |
-
doc="Titlebar string.")
|
891 |
-
|
892 |
-
def save_snapshot(self, path, blocking=False, which_window=(0, 0), wait_time=1):
|
893 |
-
"""Saves a snapshot of the current window into the specified file
|
894 |
-
|
895 |
-
:param path: filename to which the current window content will be saved
|
896 |
-
:param wait_time: waiting time to save snapshot. Increase it if the image is incomplete
|
897 |
-
"""
|
898 |
-
print('Saving snapshot to %s, please wait...' % path)
|
899 |
-
self._send_pyobj('save_snapshot', path, blocking, which_window)
|
900 |
-
time.sleep(wait_time)
|
901 |
-
|
902 |
-
def __del__(self):
|
903 |
-
if hasattr(self, "p") and not self.keepalive:
|
904 |
-
self.p.terminate()
|
905 |
-
|
906 |
-
|
907 |
-
class MeshViewerRemote:
|
908 |
-
def __init__(
|
909 |
-
self,
|
910 |
-
titlebar=MESH_VIEWER_DEFAULT_TITLE,
|
911 |
-
subwins_vert=MESH_VIEWER_DEFAULT_SHAPE[1],
|
912 |
-
subwins_horz=MESH_VIEWER_DEFAULT_SHAPE[0],
|
913 |
-
width=MESH_VIEWER_DEFAULT_WIDTH,
|
914 |
-
height=MESH_VIEWER_DEFAULT_HEIGHT,
|
915 |
-
port=None
|
916 |
-
):
|
917 |
-
|
918 |
-
context = zmq.Context.instance()
|
919 |
-
self.server = context.socket(zmq.PULL)
|
920 |
-
self.server.linger = 0
|
921 |
-
|
922 |
-
if not port:
|
923 |
-
self.port = self.server.bind_to_random_port(
|
924 |
-
"{}://{}".format(ZMQ_TRANSPORT, ZMQ_HOST),
|
925 |
-
min_port=ZMQ_PORT_MIN,
|
926 |
-
max_port=ZMQ_PORT_MAX,
|
927 |
-
max_tries=100000)
|
928 |
-
else:
|
929 |
-
self.server.bind(
|
930 |
-
"{}://{}:{}".format(ZMQ_TRANSPORT, ZMQ_HOST, port))
|
931 |
-
self.port = port
|
932 |
-
|
933 |
-
logging.debug(
|
934 |
-
"listening for incoming messages on port {}"
|
935 |
-
.format(self.port))
|
936 |
-
|
937 |
-
# Print out our port so that our client can connect to us with it. Flush stdout immediately; otherwise
|
938 |
-
# our client could wait forever.
|
939 |
-
print('<PORT>%d</PORT>\n' % (self.port,))
|
940 |
-
sys.stdout.flush()
|
941 |
-
|
942 |
-
self.arcball = ArcBallT(width, height)
|
943 |
-
self.transform = Matrix4fT()
|
944 |
-
self.lastrot = Matrix3fT()
|
945 |
-
self.thisrot = Matrix3fT()
|
946 |
-
self.isdragging = False
|
947 |
-
self.need_redraw = True
|
948 |
-
|
949 |
-
self.shape = (subwins_vert, subwins_horz)
|
950 |
-
self.mesh_viewers = [
|
951 |
-
[
|
952 |
-
MeshViewerSingle(
|
953 |
-
float(c) / (subwins_horz),
|
954 |
-
float(r) / (subwins_vert),
|
955 |
-
1. / subwins_horz,
|
956 |
-
1. / subwins_vert)
|
957 |
-
for c in range(subwins_horz)
|
958 |
-
]
|
959 |
-
for r in range(subwins_vert)
|
960 |
-
]
|
961 |
-
|
962 |
-
self.tm_for_fps = 0.
|
963 |
-
self.titlebar = titlebar
|
964 |
-
self.activate(width, height)
|
965 |
-
|
966 |
-
def snapshot(self, path, wait_time=0.1):
|
967 |
-
"""
|
968 |
-
Takes a snapshot of the meshviewer window and saves it to disc.
|
969 |
-
|
970 |
-
:param path: path to save the snapshot at.
|
971 |
-
:param wait_time: waiting time to save snapshot. Increase it if the image is incomplete
|
972 |
-
|
973 |
-
.. note:: Requires the Pillow package to be installed.
|
974 |
-
"""
|
975 |
-
self.on_draw()
|
976 |
-
time.sleep(wait_time)
|
977 |
-
|
978 |
-
width = GLUT.glutGet(GLUT.GLUT_WINDOW_WIDTH)
|
979 |
-
height = GLUT.glutGet(GLUT.GLUT_WINDOW_HEIGHT)
|
980 |
-
|
981 |
-
data = (GLU.GLubyte * (3 * width * height))(0)
|
982 |
-
GL.glReadPixels(0, 0, width, height, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, data)
|
983 |
-
image = Image.frombytes(mode="RGB", size=(width, height), data=data)
|
984 |
-
image = image.transpose(Image.FLIP_TOP_BOTTOM)
|
985 |
-
|
986 |
-
# Save image to disk
|
987 |
-
image.save(path)
|
988 |
-
|
989 |
-
def activate(self, width, height):
|
990 |
-
GLUT.glutInit(['mesh_viewer'])
|
991 |
-
GLUT.glutInitDisplayMode(GLUT.GLUT_RGBA | GLUT.GLUT_DOUBLE | GLUT.GLUT_ALPHA | GLUT.GLUT_DEPTH)
|
992 |
-
GLUT.glutInitWindowSize(width, height)
|
993 |
-
GLUT.glutInitWindowPosition(0, 0)
|
994 |
-
self.root_window_id = GLUT.glutCreateWindow(self.titlebar)
|
995 |
-
|
996 |
-
GLUT.glutTimerFunc(100, self.checkQueue, 0)
|
997 |
-
GLUT.glutReshapeFunc(self.on_resize_window)
|
998 |
-
|
999 |
-
GLUT.glutKeyboardFunc(self.on_keypress)
|
1000 |
-
GLUT.glutMouseFunc(self.on_click)
|
1001 |
-
GLUT.glutMotionFunc(self.on_drag)
|
1002 |
-
GLUT.glutDisplayFunc(self.on_draw)
|
1003 |
-
|
1004 |
-
self.init_opengl()
|
1005 |
-
|
1006 |
-
GLUT.glutMainLoop() # won't return until process is killed
|
1007 |
-
|
1008 |
-
def on_drag(self, cursor_x, cursor_y):
|
1009 |
-
""" Mouse cursor is moving
|
1010 |
-
Glut calls this function (when mouse button is down)
|
1011 |
-
and pases the mouse cursor postion in window coords as the mouse moves.
|
1012 |
-
"""
|
1013 |
-
from .geometry.rodrigues import rodrigues
|
1014 |
-
if (self.isdragging):
|
1015 |
-
mouse_pt = Point2fT(cursor_x, cursor_y)
|
1016 |
-
ThisQuat = self.arcball.drag(mouse_pt) # // Update End Vector And Get Rotation As Quaternion
|
1017 |
-
self.thisrot = Matrix3fSetRotationFromQuat4f(ThisQuat) # // Convert Quaternion Into Matrix3fT
|
1018 |
-
# Use correct Linear Algebra matrix multiplication C = A * B
|
1019 |
-
self.thisrot = Matrix3fMulMatrix3f(self.lastrot, self.thisrot) # // Accumulate Last Rotation Into This One
|
1020 |
-
|
1021 |
-
# make sure it is a rotation
|
1022 |
-
self.thisrot = rodrigues(rodrigues(self.thisrot)[0])[0]
|
1023 |
-
self.transform = Matrix4fSetRotationFromMatrix3f(self.transform, self.thisrot) # // Set Our Final Transform's Rotation From This One
|
1024 |
-
GLUT.glutPostRedisplay()
|
1025 |
-
return
|
1026 |
-
|
1027 |
-
# The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)
|
1028 |
-
def on_keypress(self, *args):
|
1029 |
-
key = args[0]
|
1030 |
-
if hasattr(self, 'event_port'):
|
1031 |
-
self.keypress_port = self.event_port
|
1032 |
-
del self.event_port
|
1033 |
-
if hasattr(self, 'keypress_port'):
|
1034 |
-
client = zmq.Context.instance().socket(zmq.PUSH)
|
1035 |
-
client.connect('{}://{}:{}'.format(ZMQ_TRANSPORT, ZMQ_HOST, self.keypress_port))
|
1036 |
-
client.send_pyobj({'event_type': 'keyboard', 'key': key})
|
1037 |
-
del self.keypress_port
|
1038 |
-
|
1039 |
-
def on_click(self, button, button_state, cursor_x, cursor_y):
|
1040 |
-
""" Mouse button clicked.
|
1041 |
-
Glut calls this function when a mouse button is
|
1042 |
-
clicked or released.
|
1043 |
-
"""
|
1044 |
-
|
1045 |
-
self.isdragging = False
|
1046 |
-
|
1047 |
-
if (button == GLUT.GLUT_LEFT_BUTTON and button_state == GLUT.GLUT_UP):
|
1048 |
-
# Left button released
|
1049 |
-
self.lastrot = copy.copy(self.thisrot) # Set Last Static Rotation To Last Dynamic One
|
1050 |
-
|
1051 |
-
elif (button == GLUT.GLUT_LEFT_BUTTON and button_state == GLUT.GLUT_DOWN):
|
1052 |
-
# Left button clicked down
|
1053 |
-
self.lastrot = copy.copy(self.thisrot) # Set Last Static Rotation To Last Dynamic One
|
1054 |
-
self.isdragging = True # // Prepare For Dragging
|
1055 |
-
mouse_pt = Point2fT(cursor_x, cursor_y)
|
1056 |
-
self.arcball.click(mouse_pt) # Update Start Vector And Prepare For Dragging
|
1057 |
-
|
1058 |
-
elif (button == GLUT.GLUT_RIGHT_BUTTON and button_state == GLUT.GLUT_DOWN):
|
1059 |
-
# If a mouse click location was requested, return it to caller
|
1060 |
-
if hasattr(self, 'event_port'):
|
1061 |
-
self.mouseclick_port = self.event_port
|
1062 |
-
del self.event_port
|
1063 |
-
if hasattr(self, 'mouseclick_port'):
|
1064 |
-
self.send_mouseclick_to_caller(cursor_x, cursor_y)
|
1065 |
-
|
1066 |
-
elif (button == GLUT.GLUT_MIDDLE_BUTTON and button_state == GLUT.GLUT_DOWN):
|
1067 |
-
# If a mouse click location was requested, return it to caller
|
1068 |
-
if hasattr(self, 'event_port'):
|
1069 |
-
self.mouseclick_port = self.event_port
|
1070 |
-
del self.event_port
|
1071 |
-
if hasattr(self, 'mouseclick_port'):
|
1072 |
-
self.send_mouseclick_to_caller(cursor_x, cursor_y, button='middle')
|
1073 |
-
|
1074 |
-
GLUT.glutPostRedisplay()
|
1075 |
-
|
1076 |
-
def send_mouseclick_to_caller(self, cursor_x, cursor_y, button='right'):
|
1077 |
-
|
1078 |
-
client = zmq.Context.instance().socket(zmq.PUSH)
|
1079 |
-
client.connect('{}://{}:{}'.format(ZMQ_TRANSPORT, ZMQ_HOST, self.mouseclick_port))
|
1080 |
-
cameras = self.on_draw(want_cameras=True)
|
1081 |
-
|
1082 |
-
window_height = GLUT.glutGet(GLUT.GLUT_WINDOW_HEIGHT)
|
1083 |
-
depth_value = GL.glReadPixels(cursor_x, window_height - cursor_y, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT)
|
1084 |
-
|
1085 |
-
pyobj = {
|
1086 |
-
'event_type': 'mouse_click_%sbutton' % button,
|
1087 |
-
'u': None, 'v': None,
|
1088 |
-
'x': None, 'y': None, 'z': None,
|
1089 |
-
'subwindow_row': None,
|
1090 |
-
'subwindow_col': None
|
1091 |
-
}
|
1092 |
-
|
1093 |
-
for subwin_row, camera_list in enumerate(cameras):
|
1094 |
-
for subwin_col, camera in enumerate(camera_list):
|
1095 |
-
|
1096 |
-
# test for out-of-bounds
|
1097 |
-
if cursor_x < camera['viewport'][0]:
|
1098 |
-
continue
|
1099 |
-
if cursor_x > (camera['viewport'][0] + camera['viewport'][2]):
|
1100 |
-
continue
|
1101 |
-
if window_height - cursor_y < camera['viewport'][1]:
|
1102 |
-
continue
|
1103 |
-
if window_height - cursor_y > (camera['viewport'][1] + camera['viewport'][3]):
|
1104 |
-
continue
|
1105 |
-
|
1106 |
-
xx, yy, zz = GLU.gluUnProject(
|
1107 |
-
cursor_x, window_height - cursor_y, depth_value,
|
1108 |
-
camera['modelview_matrix'],
|
1109 |
-
camera['projection_matrix'],
|
1110 |
-
camera['viewport'])
|
1111 |
-
|
1112 |
-
pyobj = {
|
1113 |
-
'event_type': 'mouse_click_%sbutton' % button,
|
1114 |
-
'u': cursor_x - camera['viewport'][0], 'v': window_height - cursor_y - camera['viewport'][1],
|
1115 |
-
'x': xx, 'y': yy, 'z': zz,
|
1116 |
-
'which_subwindow': (subwin_row, subwin_col)
|
1117 |
-
}
|
1118 |
-
|
1119 |
-
client.send_pyobj(pyobj)
|
1120 |
-
del self.mouseclick_port
|
1121 |
-
|
1122 |
-
def on_draw(self, want_cameras=False):
|
1123 |
-
# sys.stderr.write('fps: %.2e\n' % (1. / (time.time() - self.tm_for_fps)))
|
1124 |
-
self.tm_for_fps = time.time()
|
1125 |
-
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
|
1126 |
-
cameras = []
|
1127 |
-
for mvl in self.mesh_viewers:
|
1128 |
-
cameras.append([])
|
1129 |
-
for mv in mvl:
|
1130 |
-
cameras[-1].append(mv.on_draw(self.transform, want_cameras))
|
1131 |
-
GL.glFlush() # Flush The GL Rendering Pipeline
|
1132 |
-
GLUT.glutSwapBuffers()
|
1133 |
-
self.need_redraw = False
|
1134 |
-
if want_cameras:
|
1135 |
-
return cameras
|
1136 |
-
|
1137 |
-
def on_resize_window(self, Width, Height):
|
1138 |
-
"""Reshape The Window When It's Moved Or Resized"""
|
1139 |
-
self.arcball.setBounds(Width, Height) # //*NEW* Update mouse bounds for arcball
|
1140 |
-
return
|
1141 |
-
|
1142 |
-
def send_window_shape(self, port):
|
1143 |
-
client = zmq.Context.instance().socket(zmq.PUSH)
|
1144 |
-
client.connect('{}://{}:{}'.format(ZMQ_TRANSPORT, ZMQ_HOST, port))
|
1145 |
-
client.send_pyobj({
|
1146 |
-
'event_type': 'window_shape',
|
1147 |
-
'shape': self.shape
|
1148 |
-
})
|
1149 |
-
|
1150 |
-
def handle_request(self, request):
|
1151 |
-
label = request['label']
|
1152 |
-
obj = request['obj']
|
1153 |
-
w = request['which_window']
|
1154 |
-
mv = self.mesh_viewers[w[0]][w[1]]
|
1155 |
-
|
1156 |
-
logging.debug("received a request: {}".format(request))
|
1157 |
-
|
1158 |
-
# Handle each type of request.
|
1159 |
-
# Some requests require a redraw, and
|
1160 |
-
# some don't.
|
1161 |
-
if label == 'dynamic_meshes':
|
1162 |
-
mv.dynamic_meshes = obj
|
1163 |
-
self.need_redraw = True
|
1164 |
-
elif label == 'dynamic_models':
|
1165 |
-
mv.dynamic_models = obj
|
1166 |
-
self.need_redraw = True
|
1167 |
-
elif label == 'static_meshes':
|
1168 |
-
mv.static_meshes = obj
|
1169 |
-
self.need_redraw = True
|
1170 |
-
elif label == 'dynamic_lines':
|
1171 |
-
mv.dynamic_lines = obj
|
1172 |
-
self.need_redraw = True
|
1173 |
-
elif label == 'static_lines':
|
1174 |
-
mv.static_lines = obj
|
1175 |
-
self.need_redraw = True
|
1176 |
-
elif label == 'autorecenter':
|
1177 |
-
mv.autorecenter = obj
|
1178 |
-
self.need_redraw = True
|
1179 |
-
elif label == 'titlebar':
|
1180 |
-
assert(isinstance(obj, str))
|
1181 |
-
self.titlebar = obj
|
1182 |
-
GLUT.glutSetWindowTitle(obj)
|
1183 |
-
elif label == 'lighting_on':
|
1184 |
-
mv.lighting_on = obj
|
1185 |
-
self.need_redraw = True
|
1186 |
-
elif label == 'background_color':
|
1187 |
-
GL.glClearColor(obj[0], obj[1], obj[2], 1.0)
|
1188 |
-
self.need_redraw = True
|
1189 |
-
elif label == 'save_snapshot': # redraws for itself
|
1190 |
-
assert(isinstance(obj, str))
|
1191 |
-
self.snapshot(obj)
|
1192 |
-
elif label == 'get_keypress':
|
1193 |
-
self.keypress_port = obj
|
1194 |
-
elif label == 'get_mouseclick':
|
1195 |
-
self.mouseclick_port = obj
|
1196 |
-
elif label == 'get_event':
|
1197 |
-
self.event_port = obj
|
1198 |
-
elif label == 'get_window_shape':
|
1199 |
-
self.send_window_shape(obj)
|
1200 |
-
else:
|
1201 |
-
return False # can't handle this request string
|
1202 |
-
|
1203 |
-
return True # handled the request string
|
1204 |
-
|
1205 |
-
def checkQueue(self, unused_timer_id):
|
1206 |
-
GLUT.glutTimerFunc(20, self.checkQueue, 0)
|
1207 |
-
|
1208 |
-
try:
|
1209 |
-
request = self.server.recv_pyobj(zmq.NOBLOCK)
|
1210 |
-
except zmq.ZMQError as e:
|
1211 |
-
if e.errno != zmq.EAGAIN:
|
1212 |
-
raise # something wrong besides empty queue
|
1213 |
-
return # empty queue, no problem
|
1214 |
-
|
1215 |
-
if not request:
|
1216 |
-
return
|
1217 |
-
|
1218 |
-
while (request):
|
1219 |
-
task_completion_time = time.time()
|
1220 |
-
if not self.handle_request(request):
|
1221 |
-
raise Exception('Unknown command string: %s' % (request['label']))
|
1222 |
-
task_completion_time = time.time() - task_completion_time
|
1223 |
-
|
1224 |
-
if 'port' in request: # caller wants confirmation
|
1225 |
-
port = request['port']
|
1226 |
-
client = zmq.Context.instance().socket(zmq.PUSH)
|
1227 |
-
client.connect('{}://{}:{}'.format(ZMQ_TRANSPORT, ZMQ_HOST, port))
|
1228 |
-
client.send_pyobj(task_completion_time)
|
1229 |
-
try:
|
1230 |
-
request = self.server.recv_pyobj(zmq.NOBLOCK)
|
1231 |
-
except zmq.ZMQError as e:
|
1232 |
-
if e.errno != zmq.EAGAIN:
|
1233 |
-
raise
|
1234 |
-
request = None
|
1235 |
-
|
1236 |
-
if self.need_redraw:
|
1237 |
-
GLUT.glutPostRedisplay()
|
1238 |
-
|
1239 |
-
def init_opengl(self):
|
1240 |
-
"""A general OpenGL initialization function. Sets all of the initial parameters.
|
1241 |
-
|
1242 |
-
We call this right after our OpenGL window is created.
|
1243 |
-
"""
|
1244 |
-
|
1245 |
-
GL.glClearColor(0.0, 0.0, 0.0, 1.0) # This Will Clear The Background Color To Black
|
1246 |
-
GL.glClearDepth(1.0) # Enables Clearing Of The Depth Buffer
|
1247 |
-
GL.glDepthFunc(GL.GL_LEQUAL) # The Type Of Depth Test To Do
|
1248 |
-
GL.glEnable(GL.GL_DEPTH_TEST) # Enables Depth Testing
|
1249 |
-
GL.glShadeModel(GL.GL_SMOOTH)
|
1250 |
-
GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST) # Really Nice Perspective Calculations
|
1251 |
-
|
1252 |
-
GL.glEnable(GL.GL_LIGHT0)
|
1253 |
-
GL.glEnable(GL.GL_LIGHTING)
|
1254 |
-
|
1255 |
-
GL.glEnable(GL.GL_COLOR_MATERIAL)
|
1256 |
-
GL.glEnable(GL.GL_NORMALIZE) # important since we rescale the modelview matrix
|
1257 |
-
|
1258 |
-
return True
|
1259 |
-
|
1260 |
-
|
1261 |
-
if __name__ == '__main__':
|
1262 |
-
if len(sys.argv) == 2 and sys.argv[1] == 'TEST_FOR_OPENGL':
|
1263 |
-
_test_for_opengl()
|
1264 |
-
|
1265 |
-
elif len(sys.argv) > 2:
|
1266 |
-
m = MeshViewerRemote(titlebar=sys.argv[1],
|
1267 |
-
subwins_vert=int(sys.argv[2]),
|
1268 |
-
subwins_horz=int(sys.argv[3]),
|
1269 |
-
width=int(sys.argv[4]),
|
1270 |
-
height=int(sys.argv[5]))
|
1271 |
-
else:
|
1272 |
-
print("#" * 10)
|
1273 |
-
print('Usage:')
|
1274 |
-
print("python -m %s.%s arguments" % (__package__, os.path.splitext(os.path.basename(__file__))[0]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mesh-master/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-master/mesh/ressources/Arial.ttf
DELETED
Binary file (773 kB)
|
|
mesh-master/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-master/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-master/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-master/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-master/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: */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|