├── .gitignore ├── LICENSE ├── README.md ├── collided_mesh.obj ├── cymesh ├── __init__.pxd ├── __init__.py ├── collisions │ ├── __init__.pxd │ ├── __init__.py │ ├── findCollisions.pxd │ ├── findCollisions.pyx │ ├── tri_intersection.pxd │ ├── tri_intersection.pyx │ └── triangle_triangle_intersection.h ├── mesh.pxd ├── mesh.pyx ├── operators │ ├── __init__.pxd │ ├── __init__.py │ ├── relax.pxd │ └── relax.pyx ├── shape_features.pyx ├── structures.pxd ├── structures.pyx ├── subdivision │ ├── __init__.pxd │ ├── __init__.py │ ├── sqrt3.pxd │ └── sqrt3.pyx ├── vector3D.pxd └── view.py ├── demo.py ├── demo_collisions.py ├── demo_shape_features.py ├── my_mesh.obj ├── setup.py ├── test ├── __init__.py ├── mesh_with_intersections.obj ├── test_collisions.py ├── test_mesh.py └── test_tri_intersection.py ├── time_load.py └── triangulated_sphere_2.obj /.gitignore: -------------------------------------------------------------------------------- 1 | build/* 2 | __pycache__ 3 | *.c 4 | *.so 5 | *.html 6 | dist/ 7 | cymesh.egg-info/ 8 | *.DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Joel Simon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CyMesh 2 | 3 | A Half-Edge mesh implemented in cython. The mesh is intended for dynamic manipulation. Splitting edges, fliping edges and calculating normals and curvatures are all supported. 4 | 5 | Currently only supports tri-meshes. 6 | 7 | TODO: 8 | 9 | * support n-gon meshes and have a tri-mesh subclass 10 | 11 | ## INSTALL 12 | Requires cython and pygame/pyopengl for viewing. 13 | 14 | ``` 15 | git clone https://github.com/Sloth6/cymesh 16 | cd cymesh 17 | python setup.py build_ext --inplace 18 | python demo.py 19 | ``` 20 | 21 | To install locally. 22 | 23 | ``` 24 | python setup.py install 25 | ``` 26 | 27 | ## Demo 28 | Here is all the code in demo.py for creating a mesh from an .obj file and viewing it. Mesh's can also be created from a list of polygons. 29 | 30 | ```python 31 | from random import random 32 | from cymesh.mesh import Mesh 33 | from cymesh.view import Viewer 34 | 35 | mesh = Mesh.from_obj('triangulated_sphere_2.obj') 36 | 37 | # Add noise to mesh. 38 | for vert in mesh.verts: 39 | vert.p[0] += random() * .1 40 | vert.p[1] += random() * .1 41 | vert.p[2] += random() * .1 42 | 43 | # If not given a max length, all edges are split. 44 | mesh.splitEdges() 45 | 46 | # Flip edges which will become shorter. 47 | mesh.shortenEdges() 48 | 49 | # Normals and curvature updates must be called after making changes to mesh. 50 | mesh.calculateNormals() 51 | mesh.calculateCurvature() 52 | 53 | # We can write our new object to a file. 54 | mesh.writeObj('my_mesh.obj') 55 | 56 | # We can also export the mesh to a dict of numpy arrays. 57 | export = mesh.export() 58 | print(export.keys()) 59 | # > dict_keys(['faces', 'vertice_normals', 'face_normals', 'vert_data', 'vertices', 'curvature', 'edges']) 60 | 61 | # Each vert has a dictionary 'data' attribute to add additional information. 62 | # Colors can be passed to the viewer by adding a color to data. 63 | for vert in mesh.verts: 64 | vert.data['color'] = (random(), random(), random()) 65 | 66 | # View the mesh with pyopengl. 67 | view = Viewer() 68 | view.startDraw() 69 | view.drawMesh(mesh, edges=True) 70 | view.endDraw() 71 | view.mainLoop() 72 | 73 | ``` 74 | 75 | ## Interface 76 | 77 | ### Mesh 78 | 79 | ``` 80 | Attributes: 81 | readonly list verts 82 | readonly list faces 83 | readonly list edges 84 | readonly list halfs 85 | 86 | Methods: 87 | void shortenEdges() 88 | int splitEdges(double max_edge_length=0.0) 89 | double volume() 90 | void calculateNormals() 91 | void calculateCurvature() 92 | list getNearby(Vert v, int n) 93 | Vert splitEdge(Edge e) 94 | tuple boundingBox(self) 95 | ``` 96 | 97 | ### Vert 98 | 99 | ``` 100 | Attributes: 101 | readonly unsigned int id 102 | public double p[3] 103 | readonly double normal[3] 104 | readonly double curvature 105 | readonly HalfEdge he 106 | public dict data 107 | 108 | Methods: 109 | list faces() 110 | list neighbors() 111 | ``` 112 | 113 | ### Edge 114 | 115 | ``` 116 | Attributes: 117 | readonly unsigned int id 118 | 119 | Methods: 120 | double length() 121 | tuple vertices() 122 | bint isBoundary() 123 | void flip() 124 | ``` 125 | 126 | ### Face 127 | 128 | ``` 129 | Attributes: 130 | readonly unsigned int id 131 | readonly double normal[3] 132 | 133 | Methods: 134 | list vertices() 135 | list edges() 136 | ``` 137 | -------------------------------------------------------------------------------- /cymesh/__init__.pxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/cymesh/8efd9e9f166f75b5a3f2b4b15c1fe8ce461e0107/cymesh/__init__.pxd -------------------------------------------------------------------------------- /cymesh/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/cymesh/8efd9e9f166f75b5a3f2b4b15c1fe8ce461e0107/cymesh/__init__.py -------------------------------------------------------------------------------- /cymesh/collisions/__init__.pxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/cymesh/8efd9e9f166f75b5a3f2b4b15c1fe8ce461e0107/cymesh/collisions/__init__.pxd -------------------------------------------------------------------------------- /cymesh/collisions/__init__.py: -------------------------------------------------------------------------------- 1 | # from cymesh.findCollisions import findCollisions 2 | -------------------------------------------------------------------------------- /cymesh/collisions/findCollisions.pxd: -------------------------------------------------------------------------------- 1 | from cymesh.mesh cimport Mesh 2 | 3 | cdef inline bint bbox_intersect(double[:] a, double[:] b): 4 | return (a[0] < b[1] and a[1] > b[0]) and \ 5 | (a[2] < b[3] and a[3] > b[2]) and \ 6 | (a[4] < b[5] and a[5] > b[4]) 7 | 8 | # Singly linked list structure. 9 | cdef struct Node: 10 | int value 11 | Node *next 12 | 13 | cpdef int[:] findCollisions(Mesh mesh) except * 14 | -------------------------------------------------------------------------------- /cymesh/collisions/findCollisions.pyx: -------------------------------------------------------------------------------- 1 | # cython: boundscheck=False 2 | # cython: wraparound=False 3 | # cython: initializedcheck=False 4 | # cython: nonecheck=False 5 | # cython: cdivision=True 6 | from __future__ import print_function 7 | from libc.math cimport floor, fmin, fmax, fabs 8 | from cymesh.mesh cimport Mesh 9 | from cymesh.structures cimport Vert, Face, Edge 10 | from cymesh.collisions.tri_intersection cimport tri_tri_intersection 11 | from cymem.cymem cimport Pool 12 | 13 | import numpy as np 14 | cimport numpy as np 15 | 16 | cpdef int[:] findCollisions(Mesh mesh) except *: 17 | cdef Pool mem = Pool() 18 | 19 | cdef Edge edge 20 | cdef Face face 21 | cdef Node *node_a 22 | cdef Vert v1, v2, v3, v4, v5, v6 23 | cdef int nx, ny, nz, ix, iy, iz, fid, fid_a, fid_b, i, nynx 24 | cdef int dz, dy, dx, x_start, x_end, y_start, y_end, z_start, z_end 25 | cdef int vid1, vid2, vid3, vid4, vid5, vid6 26 | cdef int[:,:] face_vertices = np.zeros((len(mesh.faces), 3), dtype='i') 27 | cdef double[:,::1] vertices = np.zeros((len(mesh.verts), 3)) 28 | cdef double[::1] vp1, vp2, vp3, vp4, vp5, vp6 29 | cdef double center_x, center_y, center_z, min_x, min_y, min_z, maxd 30 | cdef int[:,:] face_idx = np.zeros((len(mesh.faces), 3), dtype='i') 31 | cdef int[:] collided_faces = np.zeros(len(mesh.faces), dtype='i') 32 | cdef int[:] collided = np.zeros(len(mesh.verts), dtype='i') 33 | cdef double[:] bbox_a = np.zeros(6) 34 | cdef double[:] bbox_b = np.zeros(6) 35 | 36 | ############################################################################ 37 | # Find the smallest value to offset everything by. prevents negative indexes. 38 | # Dimension size is the largest edge distance in any one dimension. 39 | 40 | min_x = mesh.verts[0].p[0] 41 | min_y = mesh.verts[0].p[1] 42 | min_z = mesh.verts[0].p[2] 43 | maxd = 0 44 | 45 | for edge in mesh.edges: 46 | v1 = edge.he.vert 47 | v2 = edge.he.twin.vert 48 | maxd = fmax(maxd, fabs(v1.p[0] - v2.p[0])) 49 | maxd = fmax(maxd, fabs(v1.p[1] - v2.p[1])) 50 | maxd = fmax(maxd, fabs(v1.p[2] - v2.p[2])) 51 | 52 | for v1 in mesh.verts: 53 | min_x = fmin(v1.p[0], min_x) 54 | min_y = fmin(v1.p[1], min_y) 55 | min_z = fmin(v1.p[2], min_z) 56 | 57 | for v1 in mesh.verts: 58 | assert v1.p[1] >= min_y, (v1.p[1], min_y) 59 | 60 | ############################################################################ 61 | # Calculate grid size and then create. 62 | 63 | cdef double[:] bbox = mesh.boundingBox() 64 | nx = ((bbox[1] - bbox[0]) / maxd) + 1 65 | ny = ((bbox[3] - bbox[2]) / maxd) + 1 66 | nz = ((bbox[5] - bbox[4]) / maxd) + 1 67 | nynx = ny*nx 68 | 69 | cdef Node **grid = mem.alloc((nx*ny*nz), sizeof(Node *)) 70 | for i in range((nx*ny*nz)): 71 | grid[i] = NULL 72 | 73 | ############################################################################ 74 | # Initialize all data buffers 75 | 76 | for v1 in mesh.verts: 77 | vertices[v1.id, 0] = v1.p[0] 78 | vertices[v1.id, 1] = v1.p[1] 79 | vertices[v1.id, 2] = v1.p[2] 80 | 81 | for face in mesh.faces: 82 | fid = face.id 83 | 84 | v1 = face.he.vert 85 | v2 = face.he.next.vert 86 | v3 = face.he.next.next.vert 87 | 88 | # Compute index bin of face center. 89 | center_x = (v1.p[0] + v2.p[0] + v3.p[0]) / 3.0 90 | center_y = (v1.p[1] + v2.p[1] + v3.p[1]) / 3.0 91 | center_z = (v1.p[2] + v2.p[2] + v3.p[2]) / 3.0 92 | 93 | face_idx[fid, 0] = ((center_x - min_x) / maxd) 94 | face_idx[fid, 1] = ((center_y - min_y) / maxd) 95 | face_idx[fid, 2] = ((center_z - min_z) / maxd) 96 | 97 | # Store face indices. 98 | face_vertices[fid, 0] = v1.id 99 | face_vertices[fid, 1] = v2.id 100 | face_vertices[fid, 2] = v3.id 101 | 102 | # Prepend node to linked list. 103 | i = face_idx[fid, 0] + face_idx[fid, 1]*nx + face_idx[fid, 2]*(nynx) 104 | 105 | if i < 0 or i >= nx*ny*nz: 106 | print(i, nx, ny, nz) 107 | print(list(face_idx[fid])) 108 | print(center_x, center_y, center_z) 109 | print(min_x, min_y, min_z) 110 | print(list(v1.p)) 111 | print(list(v2.p)) 112 | print(list(v3.p)) 113 | assert False 114 | 115 | node_a = mem.alloc(1, sizeof(Node)) 116 | node_a.value = fid 117 | node_a.next = grid[i] 118 | grid[i] = node_a 119 | 120 | ############################################################################ 121 | cdef size_t n_faces = len(mesh.faces) 122 | 123 | for fid in range(n_faces): 124 | if collided_faces[fid]: 125 | continue 126 | 127 | ix = face_idx[fid, 0] 128 | iy = face_idx[fid, 1] 129 | iz = face_idx[fid, 2] 130 | 131 | vid1 = face_vertices[fid, 0] 132 | vid2 = face_vertices[fid, 1] 133 | vid3 = face_vertices[fid, 2] 134 | 135 | vp1 = vertices[vid1] 136 | vp2 = vertices[vid2] 137 | vp3 = vertices[vid3] 138 | 139 | bbox_a[0] = min(vp1[0], vp2[0], vp3[0]) 140 | bbox_a[1] = max(vp1[0], vp2[0], vp3[0]) 141 | bbox_a[2] = min(vp1[1], vp2[1], vp3[1]) 142 | bbox_a[3] = max(vp1[1], vp2[1], vp3[1]) 143 | bbox_a[4] = min(vp1[2], vp2[2], vp3[2]) 144 | bbox_a[5] = max(vp1[2], vp2[2], vp3[2]) 145 | 146 | for dz in range(max(iz-1, 0), min(iz+1, nz)): 147 | for dy in range(max(iy-1, 0), min(iy+1, ny)): 148 | for dx in range(max(ix-1, 0), min(ix+1, nx)): 149 | 150 | node_a = grid[dx + dy*nx + dz*(nynx)] 151 | 152 | while node_a != NULL: 153 | fid_b = node_a.value 154 | node_a = node_a.next 155 | 156 | vid4 = face_vertices[fid_b, 0] 157 | vid5 = face_vertices[fid_b, 1] 158 | vid6 = face_vertices[fid_b, 2] 159 | 160 | # Connected faces cannot collide. 161 | if vid1 == vid4 or vid1 == vid5 or vid1 == vid6: 162 | continue 163 | 164 | elif vid2 == vid4 or vid2 == vid5 or vid2 == vid6: 165 | continue 166 | 167 | elif vid3 == vid4 or vid3 == vid5 or vid3 == vid6: 168 | continue 169 | 170 | else: 171 | vp4 = vertices[vid4] 172 | vp5 = vertices[vid5] 173 | vp6 = vertices[vid6] 174 | 175 | bbox_b[0] = min(vp4[0], vp5[0], vp6[0]) 176 | bbox_b[1] = max(vp4[0], vp5[0], vp6[0]) 177 | bbox_b[2] = min(vp4[1], vp5[1], vp6[1]) 178 | bbox_b[3] = max(vp4[1], vp5[1], vp6[1]) 179 | bbox_b[4] = min(vp4[2], vp5[2], vp6[2]) 180 | bbox_b[5] = max(vp4[2], vp5[2], vp6[2]) 181 | 182 | if not bbox_intersect(bbox_a, bbox_b): 183 | continue 184 | 185 | if tri_tri_intersection(vp1, vp2, vp3, vp4, vp5, vp6): 186 | # print('Found Collision') 187 | # print('\t', fid, fid_b) 188 | # print('\t', vid1, vid2, vid3) 189 | # print('\t', vid4, vid5, vid6) 190 | # print(list(bbox_a)) 191 | # print(list(bbox_b)) 192 | collided_faces[fid] = 1 193 | collided_faces[fid_b] = 1 194 | # collided[vid1] = 1 195 | # collided[vid2] = 1 196 | # collided[vid3] = 1 197 | # collided[vid4] = 1 198 | # collided[vid5] = 1 199 | # collided[vid6] = 1 200 | 201 | for fid in range(n_faces): 202 | if collided_faces[fid]: 203 | collided[face_vertices[fid, 0]] = 1 204 | collided[face_vertices[fid, 1]] = 1 205 | collided[face_vertices[fid, 2]] = 1 206 | 207 | return collided 208 | -------------------------------------------------------------------------------- /cymesh/collisions/tri_intersection.pxd: -------------------------------------------------------------------------------- 1 | cdef extern from 'triangle_triangle_intersection.h': 2 | int tri_tri_intersection_test_3d(double p1[3], double q1[3], double r1[3], 3 | double p2[3], double q2[3], double r2[3], 4 | int * coplanar, 5 | double source[3],double target[3]) 6 | 7 | cpdef int tri_tri_intersection(double[::1] P1, double[::1] P2, 8 | double[::1] P3, double[::1] Q1, 9 | double[::1] Q2, double[::1] Q3) except -1 10 | -------------------------------------------------------------------------------- /cymesh/collisions/tri_intersection.pyx: -------------------------------------------------------------------------------- 1 | cpdef int tri_tri_intersection(double[::1] P1, double[::1] P2, 2 | double[::1] P3, double[::1] Q1, 3 | double[::1] Q2, double[::1] Q3) except -1: 4 | cdef int coplanar = 0 5 | cdef double source[3] 6 | cdef double target[3] 7 | 8 | return tri_tri_intersection_test_3d(&P1[0], &P2[0], &P3[0], &Q1[0], &Q2[0], 9 | &Q3[0], &coplanar, source, target) 10 | -------------------------------------------------------------------------------- /cymesh/collisions/triangle_triangle_intersection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Triangle-Triangle Overlap Test Routines 3 | * July, 2002 4 | * Updated December 2003 5 | * 6 | * This file contains C implementation of algorithms for 7 | * performing two and three-dimensional triangle-triangle intersection test 8 | * The algorithms and underlying theory are described in 9 | * 10 | * "Fast and Robust Triangle-Triangle Overlap Test 11 | * Using Orientation Predicates" P. Guigue - O. Devillers 12 | * 13 | * Journal of Graphics Tools, 8(1), 2003 14 | * 15 | * Several geometric predicates are defined. Their parameters are all 16 | * points. Each point is an array of two or three double precision 17 | * floating point numbers. The geometric predicates implemented in 18 | * this file are: 19 | * 20 | * int tri_tri_overlap_test_3d(p1,q1,r1,p2,q2,r2) 21 | * int tri_tri_overlap_test_2d(p1,q1,r1,p2,q2,r2) 22 | * 23 | * int tri_tri_intersection_test_3d(p1,q1,r1,p2,q2,r2, 24 | * coplanar,source,target) 25 | * 26 | * is a version that computes the segment of intersection when 27 | * the triangles overlap (and are not coplanar) 28 | * 29 | * each function returns 1 if the triangles (including their 30 | * boundary) intersect, otherwise 0 31 | * 32 | * 33 | * Other information are available from the Web page 34 | * http://www.acm.org/jgt/papers/GuigueDevillers03/ 35 | * 36 | */ 37 | 38 | // modified by Aaron to better detect coplanarity 39 | 40 | #define ZERO_TEST(x) (x == 0) 41 | //#define ZERO_TEST(x) ((x) > -0.001 && (x) < .001) 42 | 43 | /* function prototype */ 44 | 45 | int tri_tri_overlap_test_3d(double p1[3], double q1[3], double r1[3], 46 | double p2[3], double q2[3], double r2[3]); 47 | 48 | 49 | int coplanar_tri_tri3d(double p1[3], double q1[3], double r1[3], 50 | double p2[3], double q2[3], double r2[3], 51 | double N1[3], double N2[3]); 52 | 53 | 54 | int tri_tri_overlap_test_2d(double p1[2], double q1[2], double r1[2], 55 | double p2[2], double q2[2], double r2[2]); 56 | 57 | 58 | int tri_tri_intersection_test_3d(double p1[3], double q1[3], double r1[3], 59 | double p2[3], double q2[3], double r2[3], 60 | int * coplanar, 61 | double source[3],double target[3]); 62 | 63 | /* coplanar returns whether the triangles are coplanar 64 | * source and target are the endpoints of the segment of 65 | * intersection if it exists) 66 | */ 67 | 68 | 69 | /* some 3D macros */ 70 | 71 | #define CROSS(dest,v1,v2) \ 72 | dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ 73 | dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ 74 | dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; 75 | 76 | #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) 77 | 78 | 79 | 80 | #define SUB(dest,v1,v2) dest[0]=v1[0]-v2[0]; \ 81 | dest[1]=v1[1]-v2[1]; \ 82 | dest[2]=v1[2]-v2[2]; 83 | 84 | 85 | #define SCALAR(dest,alpha,v) dest[0] = alpha * v[0]; \ 86 | dest[1] = alpha * v[1]; \ 87 | dest[2] = alpha * v[2]; 88 | 89 | 90 | 91 | #define CHECK_MIN_MAX(p1,q1,r1,p2,q2,r2) {\ 92 | SUB(v1,p2,q1)\ 93 | SUB(v2,p1,q1)\ 94 | CROSS(N1,v1,v2)\ 95 | SUB(v1,q2,q1)\ 96 | if (DOT(v1,N1) > 0.0f) return 0;\ 97 | SUB(v1,p2,p1)\ 98 | SUB(v2,r1,p1)\ 99 | CROSS(N1,v1,v2)\ 100 | SUB(v1,r2,p1) \ 101 | if (DOT(v1,N1) > 0.0f) return 0;\ 102 | else return 1; } 103 | 104 | 105 | 106 | /* Permutation in a canonical form of T2's vertices */ 107 | 108 | #define TRI_TRI_3D(p1,q1,r1,p2,q2,r2,dp2,dq2,dr2) { \ 109 | if (dp2 > 0.0f) { \ 110 | if (dq2 > 0.0f) CHECK_MIN_MAX(p1,r1,q1,r2,p2,q2) \ 111 | else if (dr2 > 0.0f) CHECK_MIN_MAX(p1,r1,q1,q2,r2,p2)\ 112 | else CHECK_MIN_MAX(p1,q1,r1,p2,q2,r2) }\ 113 | else if (dp2 < 0.0f) { \ 114 | if (dq2 < 0.0f) CHECK_MIN_MAX(p1,q1,r1,r2,p2,q2)\ 115 | else if (dr2 < 0.0f) CHECK_MIN_MAX(p1,q1,r1,q2,r2,p2)\ 116 | else CHECK_MIN_MAX(p1,r1,q1,p2,q2,r2)\ 117 | } else { \ 118 | if (dq2 < 0.0f) { \ 119 | if (dr2 >= 0.0f) CHECK_MIN_MAX(p1,r1,q1,q2,r2,p2)\ 120 | else CHECK_MIN_MAX(p1,q1,r1,p2,q2,r2)\ 121 | } \ 122 | else if (dq2 > 0.0f) { \ 123 | if (dr2 > 0.0f) CHECK_MIN_MAX(p1,r1,q1,p2,q2,r2)\ 124 | else CHECK_MIN_MAX(p1,q1,r1,q2,r2,p2)\ 125 | } \ 126 | else { \ 127 | if (dr2 > 0.0f) CHECK_MIN_MAX(p1,q1,r1,r2,p2,q2)\ 128 | else if (dr2 < 0.0f) CHECK_MIN_MAX(p1,r1,q1,r2,p2,q2)\ 129 | else return coplanar_tri_tri3d(p1,q1,r1,p2,q2,r2,N1,N2);\ 130 | }}} 131 | 132 | 133 | 134 | /* 135 | * 136 | * Three-dimensional Triangle-Triangle Overlap Test 137 | * 138 | */ 139 | 140 | 141 | int tri_tri_overlap_test_3d(double p1[3], double q1[3], double r1[3], 142 | 143 | double p2[3], double q2[3], double r2[3]) 144 | { 145 | double dp1, dq1, dr1, dp2, dq2, dr2; 146 | double v1[3], v2[3]; 147 | double N1[3], N2[3]; 148 | 149 | /* Compute distance signs of p1, q1 and r1 to the plane of 150 | triangle(p2,q2,r2) */ 151 | 152 | 153 | SUB(v1,p2,r2) 154 | SUB(v2,q2,r2) 155 | CROSS(N2,v1,v2) 156 | 157 | SUB(v1,p1,r2) 158 | dp1 = DOT(v1,N2); 159 | SUB(v1,q1,r2) 160 | dq1 = DOT(v1,N2); 161 | SUB(v1,r1,r2) 162 | dr1 = DOT(v1,N2); 163 | 164 | if (((dp1 * dq1) > 0.0f) && ((dp1 * dr1) > 0.0f)) return 0; 165 | 166 | /* Compute distance signs of p2, q2 and r2 to the plane of 167 | triangle(p1,q1,r1) */ 168 | 169 | 170 | SUB(v1,q1,p1) 171 | SUB(v2,r1,p1) 172 | CROSS(N1,v1,v2) 173 | 174 | SUB(v1,p2,r1) 175 | dp2 = DOT(v1,N1); 176 | SUB(v1,q2,r1) 177 | dq2 = DOT(v1,N1); 178 | SUB(v1,r2,r1) 179 | dr2 = DOT(v1,N1); 180 | 181 | if (((dp2 * dq2) > 0.0f) && ((dp2 * dr2) > 0.0f)) return 0; 182 | 183 | /* Permutation in a canonical form of T1's vertices */ 184 | 185 | 186 | 187 | 188 | if (dp1 > 0.0f) { 189 | if (dq1 > 0.0f) TRI_TRI_3D(r1,p1,q1,p2,r2,q2,dp2,dr2,dq2) 190 | else if (dr1 > 0.0f) TRI_TRI_3D(q1,r1,p1,p2,r2,q2,dp2,dr2,dq2) 191 | else TRI_TRI_3D(p1,q1,r1,p2,q2,r2,dp2,dq2,dr2) 192 | } else if (dp1 < 0.0f) { 193 | if (dq1 < 0.0f) TRI_TRI_3D(r1,p1,q1,p2,q2,r2,dp2,dq2,dr2) 194 | else if (dr1 < 0.0f) TRI_TRI_3D(q1,r1,p1,p2,q2,r2,dp2,dq2,dr2) 195 | else TRI_TRI_3D(p1,q1,r1,p2,r2,q2,dp2,dr2,dq2) 196 | } else { 197 | if (dq1 < 0.0f) { 198 | if (dr1 >= 0.0f) TRI_TRI_3D(q1,r1,p1,p2,r2,q2,dp2,dr2,dq2) 199 | else TRI_TRI_3D(p1,q1,r1,p2,q2,r2,dp2,dq2,dr2) 200 | } 201 | else if (dq1 > 0.0f) { 202 | if (dr1 > 0.0f) TRI_TRI_3D(p1,q1,r1,p2,r2,q2,dp2,dr2,dq2) 203 | else TRI_TRI_3D(q1,r1,p1,p2,q2,r2,dp2,dq2,dr2) 204 | } 205 | else { 206 | if (dr1 > 0.0f) TRI_TRI_3D(r1,p1,q1,p2,q2,r2,dp2,dq2,dr2) 207 | else if (dr1 < 0.0f) TRI_TRI_3D(r1,p1,q1,p2,r2,q2,dp2,dr2,dq2) 208 | else return coplanar_tri_tri3d(p1,q1,r1,p2,q2,r2,N1,N2); 209 | } 210 | } 211 | }; 212 | 213 | 214 | 215 | int coplanar_tri_tri3d(double p1[3], double q1[3], double r1[3], 216 | double p2[3], double q2[3], double r2[3], 217 | double normal_1[3], double normal_2[3]){ 218 | 219 | double P1[2],Q1[2],R1[2]; 220 | double P2[2],Q2[2],R2[2]; 221 | 222 | double n_x, n_y, n_z; 223 | 224 | n_x = ((normal_1[0]<0)?-normal_1[0]:normal_1[0]); 225 | n_y = ((normal_1[1]<0)?-normal_1[1]:normal_1[1]); 226 | n_z = ((normal_1[2]<0)?-normal_1[2]:normal_1[2]); 227 | 228 | 229 | /* Projection of the triangles in 3D onto 2D such that the area of 230 | the projection is maximized. */ 231 | 232 | 233 | if (( n_x > n_z ) && ( n_x >= n_y )) { 234 | // Project onto plane YZ 235 | 236 | P1[0] = q1[2]; P1[1] = q1[1]; 237 | Q1[0] = p1[2]; Q1[1] = p1[1]; 238 | R1[0] = r1[2]; R1[1] = r1[1]; 239 | 240 | P2[0] = q2[2]; P2[1] = q2[1]; 241 | Q2[0] = p2[2]; Q2[1] = p2[1]; 242 | R2[0] = r2[2]; R2[1] = r2[1]; 243 | 244 | } else if (( n_y > n_z ) && ( n_y >= n_x )) { 245 | // Project onto plane XZ 246 | 247 | P1[0] = q1[0]; P1[1] = q1[2]; 248 | Q1[0] = p1[0]; Q1[1] = p1[2]; 249 | R1[0] = r1[0]; R1[1] = r1[2]; 250 | 251 | P2[0] = q2[0]; P2[1] = q2[2]; 252 | Q2[0] = p2[0]; Q2[1] = p2[2]; 253 | R2[0] = r2[0]; R2[1] = r2[2]; 254 | 255 | } else { 256 | // Project onto plane XY 257 | 258 | P1[0] = p1[0]; P1[1] = p1[1]; 259 | Q1[0] = q1[0]; Q1[1] = q1[1]; 260 | R1[0] = r1[0]; R1[1] = r1[1]; 261 | 262 | P2[0] = p2[0]; P2[1] = p2[1]; 263 | Q2[0] = q2[0]; Q2[1] = q2[1]; 264 | R2[0] = r2[0]; R2[1] = r2[1]; 265 | } 266 | 267 | return tri_tri_overlap_test_2d(P1,Q1,R1,P2,Q2,R2); 268 | 269 | }; 270 | 271 | 272 | 273 | /* 274 | * 275 | * Three-dimensional Triangle-Triangle Intersection 276 | * 277 | */ 278 | 279 | /* 280 | This macro is called when the triangles surely intersect 281 | It constructs the segment of intersection of the two triangles 282 | if they are not coplanar. 283 | */ 284 | 285 | #define CONSTRUCT_INTERSECTION(p1,q1,r1,p2,q2,r2) { \ 286 | SUB(v1,q1,p1) \ 287 | SUB(v2,r2,p1) \ 288 | CROSS(N,v1,v2) \ 289 | SUB(v,p2,p1) \ 290 | if (DOT(v,N) > 0.0f) {\ 291 | SUB(v1,r1,p1) \ 292 | CROSS(N,v1,v2) \ 293 | if (DOT(v,N) <= 0.0f) { \ 294 | SUB(v2,q2,p1) \ 295 | CROSS(N,v1,v2) \ 296 | if (DOT(v,N) > 0.0f) { \ 297 | SUB(v1,p1,p2) \ 298 | SUB(v2,p1,r1) \ 299 | alpha = DOT(v1,N2) / DOT(v2,N2); \ 300 | SCALAR(v1,alpha,v2) \ 301 | SUB(source,p1,v1) \ 302 | SUB(v1,p2,p1) \ 303 | SUB(v2,p2,r2) \ 304 | alpha = DOT(v1,N1) / DOT(v2,N1); \ 305 | SCALAR(v1,alpha,v2) \ 306 | SUB(target,p2,v1) \ 307 | return 1; \ 308 | } else { \ 309 | SUB(v1,p2,p1) \ 310 | SUB(v2,p2,q2) \ 311 | alpha = DOT(v1,N1) / DOT(v2,N1); \ 312 | SCALAR(v1,alpha,v2) \ 313 | SUB(source,p2,v1) \ 314 | SUB(v1,p2,p1) \ 315 | SUB(v2,p2,r2) \ 316 | alpha = DOT(v1,N1) / DOT(v2,N1); \ 317 | SCALAR(v1,alpha,v2) \ 318 | SUB(target,p2,v1) \ 319 | return 1; \ 320 | } \ 321 | } else { \ 322 | return 0; \ 323 | } \ 324 | } else { \ 325 | SUB(v2,q2,p1) \ 326 | CROSS(N,v1,v2) \ 327 | if (DOT(v,N) < 0.0f) { \ 328 | return 0; \ 329 | } else { \ 330 | SUB(v1,r1,p1) \ 331 | CROSS(N,v1,v2) \ 332 | if (DOT(v,N) >= 0.0f) { \ 333 | SUB(v1,p1,p2) \ 334 | SUB(v2,p1,r1) \ 335 | alpha = DOT(v1,N2) / DOT(v2,N2); \ 336 | SCALAR(v1,alpha,v2) \ 337 | SUB(source,p1,v1) \ 338 | SUB(v1,p1,p2) \ 339 | SUB(v2,p1,q1) \ 340 | alpha = DOT(v1,N2) / DOT(v2,N2); \ 341 | SCALAR(v1,alpha,v2) \ 342 | SUB(target,p1,v1) \ 343 | return 1; \ 344 | } else { \ 345 | SUB(v1,p2,p1) \ 346 | SUB(v2,p2,q2) \ 347 | alpha = DOT(v1,N1) / DOT(v2,N1); \ 348 | SCALAR(v1,alpha,v2) \ 349 | SUB(source,p2,v1) \ 350 | SUB(v1,p1,p2) \ 351 | SUB(v2,p1,q1) \ 352 | alpha = DOT(v1,N2) / DOT(v2,N2); \ 353 | SCALAR(v1,alpha,v2) \ 354 | SUB(target,p1,v1) \ 355 | return 1; \ 356 | }}}} 357 | 358 | 359 | 360 | #define TRI_TRI_INTER_3D(p1,q1,r1,p2,q2,r2,dp2,dq2,dr2) { \ 361 | if (dp2 > 0.0f) { \ 362 | if (dq2 > 0.0f) CONSTRUCT_INTERSECTION(p1,r1,q1,r2,p2,q2) \ 363 | else if (dr2 > 0.0f) CONSTRUCT_INTERSECTION(p1,r1,q1,q2,r2,p2)\ 364 | else CONSTRUCT_INTERSECTION(p1,q1,r1,p2,q2,r2) }\ 365 | else if (dp2 < 0.0f) { \ 366 | if (dq2 < 0.0f) CONSTRUCT_INTERSECTION(p1,q1,r1,r2,p2,q2)\ 367 | else if (dr2 < 0.0f) CONSTRUCT_INTERSECTION(p1,q1,r1,q2,r2,p2)\ 368 | else CONSTRUCT_INTERSECTION(p1,r1,q1,p2,q2,r2)\ 369 | } else { \ 370 | if (dq2 < 0.0f) { \ 371 | if (dr2 >= 0.0f) CONSTRUCT_INTERSECTION(p1,r1,q1,q2,r2,p2)\ 372 | else CONSTRUCT_INTERSECTION(p1,q1,r1,p2,q2,r2)\ 373 | } \ 374 | else if (dq2 > 0.0f) { \ 375 | if (dr2 > 0.0f) CONSTRUCT_INTERSECTION(p1,r1,q1,p2,q2,r2)\ 376 | else CONSTRUCT_INTERSECTION(p1,q1,r1,q2,r2,p2)\ 377 | } \ 378 | else { \ 379 | if (dr2 > 0.0f) CONSTRUCT_INTERSECTION(p1,q1,r1,r2,p2,q2)\ 380 | else if (dr2 < 0.0f) CONSTRUCT_INTERSECTION(p1,r1,q1,r2,p2,q2)\ 381 | else { \ 382 | *coplanar = 1; \ 383 | return coplanar_tri_tri3d(p1,q1,r1,p2,q2,r2,N1,N2);\ 384 | } \ 385 | }} } 386 | 387 | 388 | /* 389 | The following version computes the segment of intersection of the 390 | two triangles if it exists. 391 | coplanar returns whether the triangles are coplanar 392 | source and target are the endpoints of the line segment of intersection 393 | */ 394 | 395 | int tri_tri_intersection_test_3d(double p1[3], double q1[3], double r1[3], 396 | double p2[3], double q2[3], double r2[3], 397 | int * coplanar, 398 | double source[3], double target[3] ) 399 | 400 | { 401 | double dp1, dq1, dr1, dp2, dq2, dr2; 402 | double v1[3], v2[3], v[3]; 403 | double N1[3], N2[3], N[3]; 404 | double alpha; 405 | 406 | // Compute distance signs of p1, q1 and r1 407 | // to the plane of triangle(p2,q2,r2) 408 | 409 | 410 | SUB(v1,p2,r2) 411 | SUB(v2,q2,r2) 412 | CROSS(N2,v1,v2) 413 | 414 | SUB(v1,p1,r2) 415 | dp1 = DOT(v1,N2); 416 | SUB(v1,q1,r2) 417 | dq1 = DOT(v1,N2); 418 | SUB(v1,r1,r2) 419 | dr1 = DOT(v1,N2); 420 | 421 | if (((dp1 * dq1) > 0.0f) && ((dp1 * dr1) > 0.0f)) return 0; 422 | 423 | // Compute distance signs of p2, q2 and r2 424 | // to the plane of triangle(p1,q1,r1) 425 | 426 | 427 | SUB(v1,q1,p1) 428 | SUB(v2,r1,p1) 429 | CROSS(N1,v1,v2) 430 | 431 | SUB(v1,p2,r1) 432 | dp2 = DOT(v1,N1); 433 | SUB(v1,q2,r1) 434 | dq2 = DOT(v1,N1); 435 | SUB(v1,r2,r1) 436 | dr2 = DOT(v1,N1); 437 | 438 | if (((dp2 * dq2) > 0.0f) && ((dp2 * dr2) > 0.0f)) return 0; 439 | 440 | // Permutation in a canonical form of T1's vertices 441 | 442 | 443 | // printf("d1 = [%f %f %f], d2 = [%f %f %f]\n", dp1, dq1, dr1, dp2, dq2, dr2); 444 | /* 445 | // added by Aaron 446 | if (ZERO_TEST(dp1) || ZERO_TEST(dq1) ||ZERO_TEST(dr1) ||ZERO_TEST(dp2) ||ZERO_TEST(dq2) ||ZERO_TEST(dr2)) 447 | { 448 | coplanar = 1; 449 | return 0; 450 | } 451 | */ 452 | 453 | 454 | if (dp1 > 0.0f) { 455 | if (dq1 > 0.0f) TRI_TRI_INTER_3D(r1,p1,q1,p2,r2,q2,dp2,dr2,dq2) 456 | else if (dr1 > 0.0f) TRI_TRI_INTER_3D(q1,r1,p1,p2,r2,q2,dp2,dr2,dq2) 457 | 458 | else TRI_TRI_INTER_3D(p1,q1,r1,p2,q2,r2,dp2,dq2,dr2) 459 | } else if (dp1 < 0.0f) { 460 | if (dq1 < 0.0f) TRI_TRI_INTER_3D(r1,p1,q1,p2,q2,r2,dp2,dq2,dr2) 461 | else if (dr1 < 0.0f) TRI_TRI_INTER_3D(q1,r1,p1,p2,q2,r2,dp2,dq2,dr2) 462 | else TRI_TRI_INTER_3D(p1,q1,r1,p2,r2,q2,dp2,dr2,dq2) 463 | } else { 464 | if (dq1 < 0.0f) { 465 | if (dr1 >= 0.0f) TRI_TRI_INTER_3D(q1,r1,p1,p2,r2,q2,dp2,dr2,dq2) 466 | else TRI_TRI_INTER_3D(p1,q1,r1,p2,q2,r2,dp2,dq2,dr2) 467 | } 468 | else if (dq1 > 0.0f) { 469 | if (dr1 > 0.0f) TRI_TRI_INTER_3D(p1,q1,r1,p2,r2,q2,dp2,dr2,dq2) 470 | else TRI_TRI_INTER_3D(q1,r1,p1,p2,q2,r2,dp2,dq2,dr2) 471 | } 472 | else { 473 | if (dr1 > 0.0f) TRI_TRI_INTER_3D(r1,p1,q1,p2,q2,r2,dp2,dq2,dr2) 474 | else if (dr1 < 0.0f) TRI_TRI_INTER_3D(r1,p1,q1,p2,r2,q2,dp2,dr2,dq2) 475 | else { 476 | // triangles are co-planar 477 | 478 | *coplanar = 1; 479 | return coplanar_tri_tri3d(p1,q1,r1,p2,q2,r2,N1,N2); 480 | } 481 | } 482 | } 483 | }; 484 | 485 | 486 | 487 | 488 | 489 | /* 490 | * 491 | * Two dimensional Triangle-Triangle Overlap Test 492 | * 493 | */ 494 | 495 | 496 | /* some 2D macros */ 497 | 498 | #define ORIENT_2D(a, b, c) ((a[0]-c[0])*(b[1]-c[1])-(a[1]-c[1])*(b[0]-c[0])) 499 | 500 | 501 | #define INTERSECTION_TEST_VERTEX(P1, Q1, R1, P2, Q2, R2) {\ 502 | if (ORIENT_2D(R2,P2,Q1) >= 0.0f)\ 503 | if (ORIENT_2D(R2,Q2,Q1) <= 0.0f)\ 504 | if (ORIENT_2D(P1,P2,Q1) > 0.0f) {\ 505 | if (ORIENT_2D(P1,Q2,Q1) <= 0.0f) return 1; \ 506 | else return 0;} else {\ 507 | if (ORIENT_2D(P1,P2,R1) >= 0.0f)\ 508 | if (ORIENT_2D(Q1,R1,P2) >= 0.0f) return 1; \ 509 | else return 0;\ 510 | else return 0;}\ 511 | else \ 512 | if (ORIENT_2D(P1,Q2,Q1) <= 0.0f)\ 513 | if (ORIENT_2D(R2,Q2,R1) <= 0.0f)\ 514 | if (ORIENT_2D(Q1,R1,Q2) >= 0.0f) return 1; \ 515 | else return 0;\ 516 | else return 0;\ 517 | else return 0;\ 518 | else\ 519 | if (ORIENT_2D(R2,P2,R1) >= 0.0f) \ 520 | if (ORIENT_2D(Q1,R1,R2) >= 0.0f)\ 521 | if (ORIENT_2D(P1,P2,R1) >= 0.0f) return 1;\ 522 | else return 0;\ 523 | else \ 524 | if (ORIENT_2D(Q1,R1,Q2) >= 0.0f) {\ 525 | if (ORIENT_2D(R2,R1,Q2) >= 0.0f) return 1; \ 526 | else return 0; }\ 527 | else return 0; \ 528 | else return 0; \ 529 | }; 530 | 531 | 532 | 533 | #define INTERSECTION_TEST_EDGE(P1, Q1, R1, P2, Q2, R2) { \ 534 | if (ORIENT_2D(R2,P2,Q1) >= 0.0f) {\ 535 | if (ORIENT_2D(P1,P2,Q1) >= 0.0f) { \ 536 | if (ORIENT_2D(P1,Q1,R2) >= 0.0f) return 1; \ 537 | else return 0;} else { \ 538 | if (ORIENT_2D(Q1,R1,P2) >= 0.0f){ \ 539 | if (ORIENT_2D(R1,P1,P2) >= 0.0f) return 1; else return 0;} \ 540 | else return 0; } \ 541 | } else {\ 542 | if (ORIENT_2D(R2,P2,R1) >= 0.0f) {\ 543 | if (ORIENT_2D(P1,P2,R1) >= 0.0f) {\ 544 | if (ORIENT_2D(P1,R1,R2) >= 0.0f) return 1; \ 545 | else {\ 546 | if (ORIENT_2D(Q1,R1,R2) >= 0.0f) return 1; else return 0;}}\ 547 | else return 0; }\ 548 | else return 0; }} 549 | 550 | 551 | 552 | int ccw_tri_tri_intersection_2d(double p1[2], double q1[2], double r1[2], 553 | double p2[2], double q2[2], double r2[2]) { 554 | if ( ORIENT_2D(p2,q2,p1) >= 0.0f ) { 555 | if ( ORIENT_2D(q2,r2,p1) >= 0.0f ) { 556 | if ( ORIENT_2D(r2,p2,p1) >= 0.0f ) return 1; 557 | else INTERSECTION_TEST_EDGE(p1,q1,r1,p2,q2,r2) 558 | } else { 559 | if ( ORIENT_2D(r2,p2,p1) >= 0.0f ) 560 | INTERSECTION_TEST_EDGE(p1,q1,r1,r2,p2,q2) 561 | else INTERSECTION_TEST_VERTEX(p1,q1,r1,p2,q2,r2)}} 562 | else { 563 | if ( ORIENT_2D(q2,r2,p1) >= 0.0f ) { 564 | if ( ORIENT_2D(r2,p2,p1) >= 0.0f ) 565 | INTERSECTION_TEST_EDGE(p1,q1,r1,q2,r2,p2) 566 | else INTERSECTION_TEST_VERTEX(p1,q1,r1,q2,r2,p2)} 567 | else INTERSECTION_TEST_VERTEX(p1,q1,r1,r2,p2,q2)} 568 | }; 569 | 570 | 571 | int tri_tri_overlap_test_2d(double p1[2], double q1[2], double r1[2], 572 | double p2[2], double q2[2], double r2[2]) { 573 | if ( ORIENT_2D(p1,q1,r1) < 0.0f ) 574 | if ( ORIENT_2D(p2,q2,r2) < 0.0f ) 575 | return ccw_tri_tri_intersection_2d(p1,r1,q1,p2,r2,q2); 576 | else 577 | return ccw_tri_tri_intersection_2d(p1,r1,q1,p2,q2,r2); 578 | else 579 | if ( ORIENT_2D(p2,q2,r2) < 0.0f ) 580 | return ccw_tri_tri_intersection_2d(p1,q1,r1,p2,r2,q2); 581 | else 582 | return ccw_tri_tri_intersection_2d(p1,q1,r1,p2,q2,r2); 583 | 584 | }; 585 | -------------------------------------------------------------------------------- /cymesh/mesh.pxd: -------------------------------------------------------------------------------- 1 | from structures cimport Vert, Edge, Face, HalfEdge 2 | 3 | cdef inline double signed_triangle_volume(double[:] p1, double[:] p2, double[:] p3): 4 | cdef double v321 = p3[0] * p2[1] * p1[2] 5 | cdef double v231 = p2[0] * p3[1] * p1[2] 6 | cdef double v312 = p3[0] * p1[1] * p2[2] 7 | cdef double v132 = p1[0] * p3[1] * p2[2] 8 | cdef double v213 = p2[0] * p1[1] * p3[2] 9 | cdef double v123 = p1[0] * p2[1] * p3[2] 10 | return (1./6.0) * (-v321 + v231 + v312 - v132 - v213 + v123) 11 | 12 | cdef class Mesh: 13 | cdef readonly list verts 14 | cdef readonly list faces 15 | cdef readonly list edges 16 | cdef readonly list halfs 17 | 18 | # Object constructor methods. 19 | cpdef Vert _vert(self, double x, double y, double z, HalfEdge he=*) 20 | cpdef Edge _edge(self, HalfEdge he=*) 21 | cpdef Face _face(self, HalfEdge he=*) 22 | cpdef HalfEdge _half(self, HalfEdge twin=*, HalfEdge next=*, 23 | Vert vert=*, Edge edge=*, Face face=*) 24 | 25 | # Public methods. 26 | cpdef void shortenEdges(self) 27 | cpdef int splitEdges(self, double max_edge_length=*) except -1 28 | cpdef double volume(self) 29 | cpdef double surfaceArea(self) 30 | cpdef void calculateNormals(self) 31 | cpdef void calculateDefect(self) except * 32 | cpdef void calculateCurvature(self) except * 33 | # cpdef list getNearby(self, Vert v, int n) 34 | cpdef list getRings(self, Vert v, int n) 35 | cpdef tuple splitEdge(self, Edge e) 36 | cpdef double[:] boundingBox(self) 37 | cpdef void writeObj(self, str path) 38 | -------------------------------------------------------------------------------- /cymesh/mesh.pyx: -------------------------------------------------------------------------------- 1 | # cython: boundscheck=False 2 | # cython: wraparound=True 3 | # cython: initializedcheck=False 4 | # cython: nonecheck=False 5 | # cython: cdivision=True 6 | from libc.math cimport M_PI 7 | from libc.stdlib cimport atof, atoi 8 | import copy 9 | import numpy as np 10 | cimport numpy as np 11 | from vector3D cimport vcross, dot, vadd, vsub, vdivf, vdist, inormalized, vmultf, vangle, norm 12 | 13 | cdef class Mesh: 14 | """ A half edge data structure for tri-meshes. 15 | """ 16 | def __init__(self, raw_points, raw_polygons): 17 | self.verts = [] 18 | self.faces = [] 19 | self.edges = [] 20 | self.halfs = [] 21 | 22 | # Objects for construction. 23 | cdef int nv = len(raw_points) 24 | cdef int nf = len(raw_polygons) 25 | cdef HalfEdge he, h_ba, h_ab, twin 26 | cdef Face face 27 | cdef dict pair_to_half = {} # (i,j) tuple -> half edge 28 | cdef dict he_boundary = {} # Create boundary edges. 29 | cdef int n_halfs = 0 30 | cdef int a, b, i 31 | 32 | cdef list verts = [] 33 | cdef list halfs = [] 34 | cdef list p, poly 35 | 36 | """ Build half-edge data structure. 37 | """ 38 | # Create Vert objects. 39 | for p in raw_points: 40 | verts.append(self._vert(p[0], p[1], p[2], he=None)) 41 | 42 | # Create Face objects. 43 | for poly in raw_polygons: 44 | if len(poly) != 3: 45 | raise ValueError('Only Triangular Meshes Accepted.') 46 | 47 | face = self._face() 48 | face_half_edges = [] 49 | 50 | # Create half-edge for each edge. 51 | for i, a in enumerate(poly): 52 | b = poly[ (i+1) % len(poly) ] 53 | pair_ab = (verts[a].id, verts[b].id) 54 | pair_ba = (verts[b].id, verts[a].id) 55 | 56 | h_ab = self._half(face=face, vert=verts[a], twin=None, next=None, edge=None) 57 | halfs.append(h_ab) 58 | 59 | pair_to_half[pair_ab] = len(halfs)-1 60 | face_half_edges.append(len(halfs)-1) 61 | 62 | # Link to twin if it exists. 63 | if pair_ba in pair_to_half: 64 | h_ba = halfs[pair_to_half[pair_ba]] 65 | h_ba.twin = h_ab 66 | h_ab.twin = h_ba 67 | h_ab.edge = h_ba.edge 68 | else: 69 | edge = self._edge(h_ab) 70 | h_ab.edge = edge 71 | 72 | # Link them together via their 'next' pointers. 73 | for i, he_id in enumerate(face_half_edges): 74 | he = halfs[he_id] 75 | he.next = halfs[face_half_edges[(i+1) % len(poly)]] 76 | 77 | for (a, b) in pair_to_half: 78 | if (b, a) not in pair_to_half: 79 | twin = halfs[pair_to_half[(a, b)]] 80 | h_ba = self._half(vert=verts[b], twin=twin, next=None, edge=twin.edge, face=None) 81 | 82 | halfs.append(h_ba) 83 | he_boundary[b] = (len(halfs)-1, a) 84 | 85 | cdef int start, end 86 | # Link external boundary edges. 87 | for start, (he_id, end) in he_boundary.items(): 88 | he = halfs[he_id] 89 | he.next = halfs[he_boundary[end][0]] 90 | 91 | @classmethod 92 | def parse_obj(cls, filename): 93 | cdef list points = [] 94 | cdef list faces = [] 95 | cdef list face 96 | 97 | with open(filename, 'r') as f: 98 | for line in f: 99 | if len(line) < 2 or line[ 0 ] == '#': 100 | continue 101 | 102 | values = line.split() 103 | 104 | if values[0] == 'v': 105 | points.append([ float(values[1]), float(values[2]),\ 106 | float(values[3]) ]) 107 | elif values[0] == 'f': 108 | face = [ int(values[1].split('/')[0])-1, 109 | int(values[2].split('/')[0])-1, 110 | int(values[3].split('/')[0])-1 ] 111 | faces.append(face) 112 | return points, faces 113 | 114 | @classmethod 115 | def from_obj(cls, filename): 116 | points, faces = Mesh.parse_obj(filename) 117 | return cls(points, faces) 118 | 119 | # Constructor functions. 120 | cpdef Vert _vert(self, double x, double y, double z, HalfEdge he=None): 121 | cdef Vert vert = Vert(len(self.verts), x, y, z, he) 122 | self.verts.append(vert) 123 | return vert 124 | 125 | cpdef Edge _edge(self, HalfEdge he=None): 126 | cdef Edge edge = Edge(len(self.edges), he) 127 | self.edges.append(edge) 128 | return edge 129 | 130 | cpdef Face _face(self, HalfEdge he=None): 131 | cdef Face face = Face(len(self.faces), he) 132 | self.faces.append(face) 133 | return face 134 | 135 | cpdef HalfEdge _half(self, HalfEdge twin=None, HalfEdge next=None, \ 136 | Vert vert=None, Edge edge=None, Face face=None): 137 | cdef HalfEdge he = HalfEdge(len(self.halfs), twin, next, vert, edge, face) 138 | 139 | if twin: 140 | twin.twin = he 141 | if vert: 142 | vert.he = he 143 | if edge: 144 | edge.he = he 145 | if face: 146 | face.he = he 147 | 148 | self.halfs.append(he) 149 | 150 | return he 151 | 152 | # Mesh modifying 153 | cpdef void shortenEdges(self): 154 | cdef: 155 | double d 156 | double epsilon = .01 157 | Vert v1, v2 158 | Edge edge 159 | 160 | for edge in self.edges: 161 | # Select Opposite Edges. 162 | v1 = edge.he.next.next.vert 163 | v2 = edge.he.twin.next.next.vert 164 | d = vdist(v1.p, v2.p) 165 | 166 | if edge.length() - d > epsilon: 167 | edge.flip() 168 | 169 | cpdef int splitEdges(self, double max_edge_length=0.0) except -1: 170 | """ Split all edges whose lenghths are greater than given limit. 171 | """ 172 | cdef int n = 0 173 | cdef Edge edge 174 | 175 | # Copy list to avoid editing in place. 176 | for edge in list(self.edges): 177 | if edge.length() >= max_edge_length: 178 | self.splitEdge(edge) 179 | n += 1 180 | 181 | return n 182 | 183 | # Mesh calculation 184 | cpdef void calculateNormals(self): 185 | cdef: 186 | Face face 187 | Vert va, vb, vc 188 | double[:] vab = np.zeros(3) 189 | double[:] vbc = np.zeros(3) 190 | 191 | """ Initialize vert norm values to 0. """ 192 | for va in self.verts: 193 | vmultf(va.normal, va.normal, 0) 194 | 195 | """ Calculate face normals. """ 196 | for face in self.faces: 197 | va = face.he.vert 198 | vb = face.he.next.vert 199 | vc = face.he.next.next.vert 200 | vsub(vab, vb.p, va.p) 201 | vsub(vbc, vc.p, vb.p) 202 | vcross(face.normal, vab, vbc) 203 | inormalized(face.normal) 204 | 205 | """ Add face normal to all adjacent verts. """ 206 | for face in self.faces: 207 | va = face.he.vert 208 | vb = face.he.next.vert 209 | vc = face.he.next.next.vert 210 | vadd(va.normal, va.normal, face.normal) 211 | vadd(vb.normal, vb.normal, face.normal) 212 | vadd(vc.normal, vc.normal, face.normal) 213 | 214 | """ Normalize normals to unit length. """ 215 | for va in self.verts: 216 | inormalized(va.normal) 217 | 218 | # node = self.faces 219 | # for i in range(self.n_faces): 220 | # face = node.data 221 | # inormalized(&face.normal) 222 | # node = node.next 223 | 224 | cpdef void calculateDefect(self) except *: 225 | cdef int n, i, n_neighbors 226 | cdef double angle_sum 227 | cdef Vert vert, neighbor_a, neighbor_b 228 | cdef double[:] p12 = np.zeros(3) 229 | cdef double[:] p13 = np.zeros(3) 230 | 231 | cdef HalfEdge h, start, h_twin 232 | 233 | for vert in self.verts: 234 | angle_sum = 0 235 | n_neighbors = 0 236 | h = vert.he 237 | start = h 238 | 239 | while True: 240 | h_twin = h.twin 241 | 242 | neighbor_a = h_twin.vert 243 | neighbor_b = h_twin.next.twin.vert 244 | 245 | vsub(p12, neighbor_a.p, vert.p) 246 | vsub(p13, neighbor_b.p, vert.p) 247 | angle_sum += abs(vangle(p12, p13)) 248 | 249 | h = h_twin.next 250 | n_neighbors += 1 251 | if h is start: 252 | break 253 | 254 | vert.defect = 2*M_PI - angle_sum 255 | 256 | cpdef void calculateCurvature(self) except *: 257 | # https://computergraphics.stackexchange.com/questions/1718/what-is-the-simplest-way-to-compute-principal-curvature-for-a-mesh-triangle 258 | cdef: 259 | Edge edge 260 | Vert v1, v2 261 | double n 262 | double[:] ndiff = np.zeros(3) 263 | double[:] pdiff = np.zeros(3) 264 | double curvature 265 | 266 | for edge in self.edges: 267 | v1, v2 = edge.vertices() 268 | vsub(ndiff, v1.normal, v2.normal) 269 | vsub(pdiff, v1.p, v2.p) 270 | curvature = dot(ndiff, pdiff) / norm(pdiff) 271 | edge.curvature = curvature 272 | 273 | for v1 in self.verts: 274 | curvature = 0 275 | n = 0.0 276 | for edge in v1.edges(): 277 | curvature += edge.curvature 278 | n += 1.0 279 | v1.curvature = curvature / n 280 | 281 | cpdef double volume(self): 282 | # https://stackoverflow.com/a/1568551/2175411 283 | cdef double v = 0 284 | cdef Vert v1, v2, v3 285 | cdef Face face 286 | 287 | for face in self.faces: 288 | v1, v2, v3 = face.vertices() 289 | v += signed_triangle_volume(v1.p, v2.p, v3.p) 290 | 291 | return abs(v) 292 | 293 | cpdef double surfaceArea(self): 294 | cdef Face face 295 | cdef double area = 0 296 | for face in self.faces: 297 | area += face.area() 298 | return area 299 | 300 | # cpdef list getNearby(self, Vert v, int n): 301 | # if n < 1: 302 | # raise ValueError('n must be > 0.') 303 | 304 | # cdef Vert v1, v2 305 | # cdef set vseen = set([v]) 306 | # cdef list vopen = [v] 307 | # cdef list next_open 308 | # cdef int i 309 | 310 | # for i in range(n): 311 | # next_open = [] 312 | # for v1 in vopen: 313 | # for v2 in v1.neighbors(): 314 | # if v2 not in vseen: 315 | # next_open.append(v2) 316 | # vseen.add(v2) 317 | # vopen = next_open 318 | 319 | # return list(vseen) 320 | 321 | cpdef list getRings(self, Vert v, int n): 322 | if n < 1: 323 | raise ValueError('n must be > 0.') 324 | 325 | cdef Vert v1, v2 326 | cdef set vseen = set([v]) 327 | cdef list vopen = [v] 328 | cdef list next_open 329 | cdef int i 330 | cdef list result = [] 331 | 332 | for i in range(n): 333 | next_open = [] 334 | for v1 in vopen: 335 | for v2 in v1.neighbors(): 336 | if v2 not in vseen: 337 | next_open.append(v2) 338 | vseen.add(v2) 339 | result.append((i, v2)) 340 | vopen = next_open 341 | 342 | return result 343 | 344 | cpdef tuple splitEdge(self, Edge e): 345 | """ Split an external or internal edge and return new vertex. 346 | """ 347 | cdef Face other_face, f_nbc, f_anc, f_dna, f_dbn 348 | cdef HalfEdge h_ab, h_ba, h_bc, h_ca, h_cn, h_nc, h_an, h_na, h_bn 349 | cdef HalfEdge h_ad, h_db, h_dn, h_nd 350 | cdef Edge e_an, e_nb, e_cn, e_nd 351 | cdef Vert v_a, v_b, v_c, v_n 352 | cdef double x, y, z 353 | 354 | if e.he.face is None: 355 | e.he = e.he.twin 356 | 357 | other_face = e.he.twin.face 358 | 359 | # Three half edges that make up triangle. 360 | h_ab = e.he 361 | h_ba = h_ab.twin 362 | h_bc = e.he.next 363 | h_ca = e.he.next.next 364 | 365 | # Three vertices of triangle. 366 | v_a = h_ab.vert 367 | v_b = h_bc.vert 368 | v_c = h_ca.vert 369 | 370 | # New vertex. 371 | x = (v_a.p[0] + v_b.p[0]) / 2.0 372 | y = (v_a.p[1] + v_b.p[1]) / 2.0 373 | z = (v_a.p[2] + v_b.p[2]) / 2.0 374 | v_n = self._vert(x, y, z) 375 | 376 | # Create new face. 377 | f_nbc = self._face() 378 | f_anc = h_ab.face 379 | 380 | # Create two new edges. 381 | e_an = e 382 | e_nb = self._edge() 383 | e_cn = self._edge() # The interior edge that splits triangle. 384 | 385 | # Create twin half edges on both sides of new interior edge. 386 | h_cn = self._half(twin=None, next=None, vert=v_c, edge=e_cn, face=f_nbc) 387 | h_nc = self._half(twin=h_cn, next=h_ca, vert=v_n, edge=e_cn, face=f_anc) 388 | 389 | # Half edges that border new split edges. 390 | h_an = h_ab 391 | h_an.face = f_anc 392 | h_bn = h_ba 393 | h_bn.edge = e_nb 394 | h_nb = self._half(twin=h_bn, next=h_bc, vert=v_n, edge=e_nb, face=f_nbc) 395 | h_na = self._half(twin=h_an, next=h_ba.next, vert=v_n, edge=e_an, face=None) 396 | h_bc.face = f_nbc 397 | h_bc.next = h_cn 398 | h_ca.next = h_an 399 | h_an.next = h_nc 400 | h_cn.next = h_nb 401 | h_bn.next = h_na 402 | h_bn.twin = h_nb 403 | 404 | if other_face is not None: 405 | h_ad = h_na.next 406 | h_db = h_ad.next 407 | v_d = h_db.vert 408 | # Create new faces 409 | f_dna = other_face 410 | f_dbn = self._face() 411 | # Create new edge 412 | e_nd = self._edge() 413 | # Create twin half edges on both sides of new interior edge. 414 | h_dn = self._half(twin=None, next=h_na, vert=v_d, edge=e_nd, face=f_dna) 415 | h_nd = self._half(twin=h_dn, next=h_db, vert=v_n, edge=e_nd, face=f_dbn) 416 | h_bn.next = h_nd 417 | h_bn.face = f_dbn 418 | h_na.face = f_dna 419 | h_dn.next = h_na 420 | h_db.face = f_dbn 421 | h_db.next = h_bn 422 | h_ad.face = f_dna 423 | h_ad.next = h_dn 424 | v_b.he = h_bn 425 | 426 | return v_n, e_an, e_nb 427 | 428 | cpdef double[:] boundingBox(self): 429 | cdef Vert v = self.verts[0] 430 | cdef double[:] bbox = np.zeros(6) 431 | 432 | bbox[0:2] = v.p[0]#, v.p[0]] 433 | bbox[2:2] = v.p[1]#, v.p[1]] 434 | bbox[4:6] = v.p[2]#, v.p[2]] 435 | 436 | for v in self.verts: 437 | bbox[0] = min(bbox[0], v.p[0]) 438 | bbox[1] = max(bbox[1], v.p[0]) 439 | 440 | bbox[2] = min(bbox[2], v.p[1]) 441 | bbox[3] = max(bbox[3], v.p[1]) 442 | 443 | bbox[4] = min(bbox[4], v.p[2]) 444 | bbox[5] = max(bbox[5], v.p[2]) 445 | 446 | return bbox 447 | 448 | cpdef void writeObj(self, str path): 449 | self.calculateNormals() 450 | with open(path, 'w+') as out: 451 | out.write('# Created by cymesh.\n') 452 | id_to_idx = {} 453 | 454 | for i, vert in enumerate(self.verts): 455 | id_to_idx[vert.id] = i 456 | if 'color' in vert.data: 457 | r, g, b = vert.data['color'] 458 | out.write('v %f %f %f %f %f %f\n' % \ 459 | (vert.p[0], vert.p[1], vert.p[2], r, g, b)) 460 | else: 461 | out.write('v %f %f %f\n' % (vert.p[0], vert.p[1], vert.p[2])) 462 | 463 | for i, vert in enumerate(self.verts): 464 | id_to_idx[vert.id] = i 465 | out.write('vn %f %f %f\n' % \ 466 | (vert.normal[0], vert.normal[1], vert.normal[2])) 467 | 468 | for face in self.faces: 469 | v1, v2, v3 = face.vertices() 470 | id1 = id_to_idx[v1.id] + 1 471 | id2 = id_to_idx[v2.id] + 1 472 | id3 = id_to_idx[v3.id] + 1 473 | out.write('f %i//%i %i//%i %i//%i\n' % (id1,id1,id2,id2,id3,id3)) 474 | 475 | # Query 476 | def export(self): 477 | """ Return mesh as numpy arrays. 478 | """ 479 | cdef: 480 | Vert v1, v2, v3 481 | Edge edge 482 | Face face 483 | dict vid_to_idx = {} 484 | 485 | self.calculateNormals() 486 | self.calculateCurvature() 487 | 488 | verts = np.zeros((len(self.verts), 3)) 489 | vert_normals = np.zeros((len(self.verts), 3)) 490 | curvature = np.zeros(len(self.verts)) 491 | 492 | edges = np.zeros((len(self.edges), 2), dtype='i') 493 | faces = np.zeros((len(self.faces), 3), dtype='i') 494 | face_normals = np.zeros((len(self.faces), 3)) 495 | vert_data = {} 496 | 497 | for i, v in enumerate(self.verts): 498 | verts[i] = v.p 499 | vid_to_idx[v.id] = i 500 | vert_normals[i] = v.normal 501 | curvature[i] = v.curvature 502 | vert_data[i] = copy.copy(v.data) 503 | 504 | for i, edge in enumerate(self.edges): 505 | v1, v2 = edge.vertices() 506 | edges[i, 0] = vid_to_idx[v1.id] 507 | edges[i, 1] = vid_to_idx[v2.id] 508 | 509 | for i, face in enumerate(self.faces): 510 | v1, v2, v3 = face.vertices() 511 | faces[i, 0] = vid_to_idx[v1.id] 512 | faces[i, 1] = vid_to_idx[v2.id] 513 | faces[i, 2] = vid_to_idx[v3.id] 514 | face_normals[i] = face.normal 515 | 516 | return {'vertices': verts, 'edges':edges, 'faces':faces, 517 | 'vertice_normals': vert_normals, 'face_normals':face_normals, 518 | 'curvature': curvature, 'vert_data': vert_data} 519 | -------------------------------------------------------------------------------- /cymesh/operators/__init__.pxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/cymesh/8efd9e9f166f75b5a3f2b4b15c1fe8ce461e0107/cymesh/operators/__init__.pxd -------------------------------------------------------------------------------- /cymesh/operators/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/cymesh/8efd9e9f166f75b5a3f2b4b15c1fe8ce461e0107/cymesh/operators/__init__.py -------------------------------------------------------------------------------- /cymesh/operators/relax.pxd: -------------------------------------------------------------------------------- 1 | from cymesh.mesh cimport Mesh 2 | from cymesh.structures cimport Vert 3 | cpdef void relax_vert_cotangent(Vert vert, double[:] p) except * 4 | cpdef void relax_mesh_cotangent(Mesh mesh) except * 5 | cpdef void relax_mesh(Mesh mesh) except * 6 | -------------------------------------------------------------------------------- /cymesh/operators/relax.pyx: -------------------------------------------------------------------------------- 1 | # cython: boundscheck=False 2 | # cython: wraparound=True 3 | # cython: initializedcheck=False 4 | # cython: nonecheck=False 5 | # cython: cdivision=True 6 | 7 | from cymesh.mesh cimport Mesh 8 | from cymesh.structures cimport Vert, HalfEdge 9 | from cymesh.vector3D cimport vadd, vsub, dot, norm, vcross 10 | import numpy as np 11 | cimport numpy as np 12 | 13 | cpdef void relax_vert_cotangent(Vert vert, double[:] p) except *: 14 | cdef double mean_x, mean_y, mean_z, cotan1, cotan2, total_angle, weight 15 | cdef int n_neighbors 16 | cdef int j = 0 17 | cdef double[:] outer_curr 18 | cdef double[:] outer_next 19 | cdef double[:] outer_prev 20 | cdef double[:] v1 = np.zeros(3) 21 | cdef double[:] v2 = np.zeros(3) 22 | cdef double[:] v3 = np.zeros(3) 23 | cdef double[:] v4 = np.zeros(3) 24 | cdef double[:] vtemp = np.zeros(3) 25 | 26 | mean_x = 0 27 | mean_y = 0 28 | mean_z = 0 29 | n_neighbors = 0 30 | total = 0 31 | 32 | neighbors = vert.neighbors() 33 | n_neighbors = len(neighbors) 34 | 35 | for j in range(n_neighbors): 36 | outer_curr = neighbors[j].p 37 | outer_next = neighbors[(j+1) % n_neighbors].p 38 | outer_prev = neighbors[j-1].p # cython:wraparound is set to True 39 | 40 | vsub(v1, vert.p, outer_prev) 41 | vsub(v2, outer_curr, outer_prev) 42 | 43 | vsub(v3, vert.p, outer_next) 44 | vsub(v4, outer_curr, outer_next) 45 | 46 | vcross(vtemp, v1, v2) 47 | cotan1 = dot(v1, v2) / norm(vtemp) 48 | 49 | vcross(vtemp, v3, v4) 50 | cotan2 = dot(v3, v4) / norm(vtemp) 51 | 52 | weight = (cotan1 + cotan2) * .5 53 | 54 | mean_x += outer_curr[0] * weight 55 | mean_y += outer_curr[1] * weight 56 | mean_z += outer_curr[2] * weight 57 | 58 | total += weight 59 | 60 | p[0] = mean_x / total 61 | p[1] = mean_y / total 62 | p[2] = mean_z / total 63 | 64 | 65 | cpdef void relax_mesh_cotangent(Mesh mesh) except *: 66 | # Move vertexes towards their neighbors average with cotangent weights. 67 | cdef Vert vert 68 | cdef double mean_x, mean_y, mean_z, cotan1, cotan2, total_angle, weight 69 | cdef int n_neighbors 70 | cdef double[:,:] old_p = np.zeros((len(mesh.verts), 3)) 71 | cdef double[:,:] next_p = np.zeros((len(mesh.verts), 3)) 72 | cdef int i = 0 73 | cdef int j =0 74 | cdef double[:] outer_curr 75 | cdef double[:] outer_next 76 | cdef double[:] outer_prev 77 | cdef double[:] v1 = np.zeros(3) 78 | cdef double[:] v2 = np.zeros(3) 79 | cdef double[:] v3 = np.zeros(3) 80 | cdef double[:] v4 = np.zeros(3) 81 | cdef double[:] vtemp = np.zeros(3) 82 | 83 | for vert in mesh.verts: 84 | mean_x = 0 85 | mean_y = 0 86 | mean_z = 0 87 | n_neighbors = 0 88 | total = 0 89 | 90 | old_p[i,:] = vert.p 91 | 92 | neighbors = vert.neighbors() 93 | n_neighbors = len(neighbors) 94 | 95 | # http://rodolphe-vaillant.fr/?e=69 96 | for j in range(n_neighbors): 97 | outer_curr = neighbors[j].p 98 | outer_next = neighbors[(j+1) % n_neighbors].p 99 | outer_prev = neighbors[j-1].p # cython:wraparound is set to True 100 | 101 | vsub(v1, vert.p, outer_prev) 102 | vsub(v2, outer_curr, outer_prev) 103 | 104 | vsub(v3, vert.p, outer_next) 105 | vsub(v4, outer_curr, outer_next) 106 | 107 | vcross(vtemp, v1, v2) 108 | cotan1 = dot(v1, v2) / norm(vtemp) 109 | 110 | vcross(vtemp, v3, v4) 111 | cotan2 = dot(v3, v4) / norm(vtemp) 112 | 113 | weight = (cotan1 + cotan2) * .5 114 | 115 | mean_x += outer_curr[0] * weight 116 | mean_y += outer_curr[1] * weight 117 | mean_z += outer_curr[2] * weight 118 | 119 | total += weight 120 | 121 | next_p[i, 0] = mean_x / total 122 | next_p[i, 1] = mean_y / total 123 | next_p[i, 2] = mean_z / total 124 | i += 1 125 | 126 | i = 0 127 | for vert in mesh.verts: 128 | vert.p[0] = next_p[i, 0] 129 | vert.p[1] = next_p[i, 1] 130 | vert.p[2] = next_p[i, 2] 131 | i += 1 132 | 133 | mesh.calculateNormals() 134 | 135 | # # Project back by moving to the projection of old position onto new normal vector. 136 | cdef double[:] a, p 137 | cdef double[:] ab = np.zeros(3) 138 | cdef double[:] ap = np.zeros(3) 139 | cdef double[:] b = np.zeros(3) 140 | cdef double c 141 | i = 0 142 | for vert in mesh.verts: 143 | p = old_p[i] 144 | a = vert.p 145 | vadd(b, a, vert.normal) 146 | 147 | # https://gamedev.stackexchange.com/questions/72528/how-can-i-project-a-3d-point-onto-a-3d-line 148 | vsub(ap, p, a) 149 | vsub(ab, b, a) 150 | c = dot(ap, ab) / dot(ab, ab) 151 | vert.p[0] = a[0] + c * ab[0] 152 | vert.p[1] = a[1] + c * ab[1] 153 | vert.p[2] = a[2] + c * ab[2] 154 | i += 1 155 | 156 | cpdef void relax_mesh(Mesh mesh) except *: 157 | # Move vertexes towards their neighbors average 158 | cdef Vert vert 159 | cdef double mean_x, mean_y, mean_z 160 | cdef HalfEdge h, start, h_twin 161 | cdef int n_neighbors 162 | cdef double[:,:] old_p = np.zeros((len(mesh.verts), 3)) 163 | cdef int i = 0 164 | 165 | for vert in mesh.verts: 166 | mean_x = 0 167 | mean_y = 0 168 | mean_z = 0 169 | n_neighbors = 0 170 | 171 | old_p[i,:] = vert.p 172 | 173 | # Iterate the neighbors 174 | h = vert.he 175 | start = h 176 | while True: 177 | h_twin = h.twin 178 | 179 | mean_x += h_twin.vert.p[0] 180 | mean_y += h_twin.vert.p[1] 181 | mean_z += h_twin.vert.p[2] 182 | n_neighbors += 1 183 | 184 | h = h_twin.next 185 | if h is start: 186 | break 187 | 188 | assert n_neighbors > 0 189 | vert.p[0] = mean_x / n_neighbors 190 | vert.p[1] = mean_y / n_neighbors 191 | vert.p[2] = mean_z / n_neighbors 192 | i += 1 193 | 194 | mesh.calculateNormals() 195 | 196 | # Project back by moving to the proejction of old position onto new normal vector. 197 | cdef double[:] a, p 198 | cdef double[:] ab = np.zeros(3) 199 | cdef double[:] ap = np.zeros(3) 200 | cdef double[:] b = np.zeros(3) 201 | cdef double c 202 | 203 | i = 0 204 | for vert in mesh.verts: 205 | a = vert.p 206 | 207 | vadd(b, a, vert.normal) 208 | p = old_p[i] 209 | vsub(ap, p, a) 210 | vsub(ab, b, a) 211 | 212 | # https://gamedev.stackexchange.com/questions/72528/how-can-i-project-a-3d-point-onto-a-3d-line 213 | c = dot(ap, ab) / dot(ab, ab) 214 | 215 | vert.p[0] = a[0] + c * ab[0] 216 | vert.p[1] = a[1] + c * ab[1] 217 | vert.p[2] = a[2] + c * ab[2] 218 | i += 1 219 | 220 | -------------------------------------------------------------------------------- /cymesh/shape_features.pyx: -------------------------------------------------------------------------------- 1 | # cython: boundscheck=False 2 | # cython: wraparound=True 3 | # cython: initializedcheck=False 4 | # cython: nonecheck=False 5 | # cython: cdivision=True 6 | from libc.math cimport sqrt 7 | from libc.stdlib cimport rand, srand, RAND_MAX 8 | 9 | import numpy as np 10 | cimport numpy as np 11 | 12 | from cymesh.vector3D cimport vdist, vangle, vsub 13 | from cymesh.mesh cimport Mesh 14 | from cymesh.structures cimport Vert 15 | 16 | ctypedef double (*vert_metric)(Vert, Vert) 17 | 18 | cdef double[:] create_features(vert_metric metric, Mesh mesh, tuple hrange, \ 19 | int n_points, int n_bins, int rseed) except *: 20 | cdef int i, j, n, n_verts 21 | cdef double mean_value, rms, hmin, hmax 22 | cdef double[:] values = np.zeros(n_points) 23 | cdef double values_sqr = 0 24 | 25 | srand(rseed) 26 | 27 | if hrange is not None: 28 | hmin = hrange[0] 29 | hmax = hrange[1] 30 | 31 | n_verts = len(mesh.verts) 32 | n = 0 33 | 34 | while n < n_points: 35 | i = rand() % (n_verts-1) 36 | j = rand() % (n_verts-1) 37 | if i != j: 38 | values[n] = metric(mesh.verts[i], mesh.verts[j]) 39 | values_sqr += values[n] * values[n] 40 | n += 1 41 | 42 | rms = sqrt(values_sqr / n_points) # Normalize by the root-mean-square. 43 | 44 | for i in range(n_points): 45 | values[i] /= rms 46 | if hrange is not None: 47 | values[i] = max(hmin, values[i]) 48 | values[i] = min(hmax, values[i]) 49 | 50 | return np.histogram(values, bins=n_bins, density=True)[0] 51 | 52 | cdef double d2_metric(Vert a, Vert b): 53 | return vdist(a.p, b.p) 54 | 55 | cdef double a2_metric(Vert a, Vert b): 56 | return vangle(a.normal, b.normal) 57 | 58 | cpdef double[:] d2_features(Mesh mesh, tuple hrange=(0.0, 3.0), int n_points=1024, 59 | int n_bins=64, int rseed=123) except *: 60 | """ 3D Shape features from 'Matching 3D Models with Shape Distributions' 61 | Paper pdf: https://graphics.stanford.edu/courses/cs468-01-fall/Papers/osada_funkhouser_chazelle_dobkin.pdf 62 | Returns a feature vector of size 'bins' from arbitrary sized mesh. 63 | """ 64 | return create_features(d2_metric, mesh, hrange, n_points, n_bins, rseed) 65 | 66 | cpdef double[:] a2_features(Mesh mesh, tuple hrange=(0.0, 3.0), int n_points=1024, 67 | int n_bins=64, int rseed=123) except *: 68 | """ Similar to d2 features but use the angle between the normal directions. 69 | """ 70 | mesh.calculateNormals() 71 | return create_features(a2_metric, mesh, hrange, n_points, n_bins, rseed) 72 | 73 | 74 | cpdef double[:] a3_features(Mesh mesh, tuple hrange=(0.0, 3.0), int n_points=1024, 75 | int n_bins=64, int rseed=123) except *: 76 | """ Similar to d2 features but use the angle between the normal directions. 77 | """ 78 | cdef int i, j, k, n, n_verts 79 | cdef double mean_value, rms, hmin, hmax 80 | cdef double[:] values = np.zeros(n_points) 81 | cdef double[:] tmp_a = np.zeros(3) 82 | cdef double[:] tmp_b = np.zeros(3) 83 | cdef double values_sqr = 0 84 | 85 | srand(rseed) 86 | 87 | n = 0 88 | n_verts = len(mesh.verts) 89 | 90 | if hrange is not None: 91 | hmin = hrange[0] 92 | hmax = hrange[1] 93 | 94 | while n < n_points: 95 | i = rand() % (n_verts-1) 96 | j = rand() % (n_verts-1) 97 | k = rand() % (n_verts-1) 98 | if i != k and i != j and j != k: 99 | vsub(tmp_a, mesh.verts[i].p, mesh.verts[j].p) 100 | vsub(tmp_b, mesh.verts[k].p, mesh.verts[j].p) 101 | values[n] = vangle(tmp_a, tmp_b) 102 | values_sqr += values[n] * values[n] 103 | n += 1 104 | 105 | rms = sqrt(values_sqr / n_points) # Normalize by the root-mean-square. 106 | 107 | for i in range(n_points): 108 | values[i] /= rms 109 | if hrange is not None: 110 | values[i] = max(hmin, values[i]) 111 | values[i] = min(hmax, values[i]) 112 | 113 | return np.histogram(values, bins=n_bins, density=True)[0] -------------------------------------------------------------------------------- /cymesh/structures.pxd: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | 3 | cdef class Vert: 4 | cdef public unsigned int id 5 | cdef public double[::1] normal 6 | cdef public double curvature 7 | cdef public double defect 8 | cdef public HalfEdge he 9 | cdef public double[::1] p 10 | cdef public dict data 11 | 12 | cpdef list faces(self) 13 | cpdef list neighbors(self) 14 | cpdef list edges(self) 15 | 16 | cdef class Edge: 17 | cdef public unsigned int id 18 | cdef public HalfEdge he 19 | cdef public dict data 20 | cdef double curvature # Value used in computing vert curvature. 21 | 22 | cpdef double length(self) 23 | cpdef tuple vertices(self) 24 | cpdef tuple oppositeVertices(self) 25 | cpdef bint isBoundary(self) 26 | cpdef void flip(self) 27 | 28 | cdef class Face: 29 | cdef public unsigned int id 30 | cdef public double[:] normal 31 | cdef public HalfEdge he 32 | 33 | # Used for adaptive mesh refinement algorithm. 34 | cdef public unsigned int generation 35 | cdef public Face mate 36 | 37 | cpdef list vertices(self) 38 | cpdef list edges(self) 39 | cpdef double area(self) 40 | cpdef double[:] midpoint(self) 41 | 42 | cdef class HalfEdge: 43 | cdef public unsigned int id 44 | cdef public HalfEdge twin 45 | cdef public HalfEdge next 46 | cdef public Vert vert 47 | cdef public Edge edge 48 | cdef public Face face 49 | -------------------------------------------------------------------------------- /cymesh/structures.pyx: -------------------------------------------------------------------------------- 1 | # cython: boundscheck=False 2 | # cython: wraparound=True 3 | # cython: initializedcheck=False 4 | # cython: nonecheck=False 5 | # cython: cdivision=True 6 | from libc.math cimport sqrt 7 | from vector3D cimport vdist 8 | cimport numpy as np 9 | import numpy as np 10 | 11 | cdef class Vert: 12 | def __init__(self, id, x, y, z, he): 13 | self.id = id 14 | self.p = np.array([x, y, z]) 15 | self.he = he 16 | self.normal = np.zeros(3) 17 | self.curvature = 0 18 | self.defect = 0 19 | self.data = dict() 20 | 21 | cpdef list faces(self): 22 | """ Return a list of faces which contain this vert. 23 | """ 24 | cdef list result = [] 25 | cdef HalfEdge h, start, h_twin 26 | 27 | h = self.he 28 | start = h 29 | 30 | while True: 31 | result.append(h.face) 32 | h_twin = h.twin 33 | h = h_twin.next 34 | if h is start: 35 | break 36 | 37 | return result 38 | 39 | cpdef list edges(self): 40 | """ Return a list of vertexes directly connected to this one. 41 | """ 42 | cdef list result = [] 43 | cdef HalfEdge h, start, h_twin 44 | 45 | h = self.he 46 | start = h 47 | 48 | while True: 49 | h_twin = h.twin 50 | result.append(h_twin.edge) 51 | h = h_twin.next 52 | 53 | if h is start: 54 | break 55 | 56 | return result 57 | 58 | cpdef list neighbors(self): 59 | """ Return a list of vertexes directly connected to this one. 60 | """ 61 | cdef list result = [] 62 | cdef HalfEdge h, start, h_twin 63 | 64 | h = self.he 65 | start = h 66 | 67 | while True: 68 | h_twin = h.twin 69 | result.append(h_twin.vert) 70 | h = h_twin.next 71 | 72 | if h is start: 73 | break 74 | 75 | return result 76 | 77 | cdef class Edge: 78 | def __init__(self, id, he): 79 | self.id = id 80 | self.he = he 81 | self.data = dict() 82 | 83 | cpdef double length(self): 84 | cdef double[:] p1 = self.he.vert.p 85 | cdef double[:] p2 = self.he.twin.vert.p 86 | return vdist(p1, p2) 87 | 88 | cpdef tuple vertices(self): 89 | return (self.he.vert, self.he.twin.vert) 90 | 91 | cpdef tuple oppositeVertices(self): 92 | cdef HalfEdge he1, he2, he11, he12, he22 93 | 94 | if self.isBoundary(): 95 | return None 96 | 97 | # Defining variables 98 | he1 = self.he 99 | he2 = he1.twin 100 | 101 | he11 = he1.next 102 | he12 = he11.next 103 | he21 = he2.next 104 | he22 = he21.next 105 | 106 | return (he12.vert, he22.vert) 107 | 108 | cpdef bint isBoundary(self): 109 | return self.he.face is None or self.he.twin.face is None 110 | 111 | cpdef void flip(self): 112 | # Edge operations 113 | cdef HalfEdge he1, he2, he11, he12, he22 114 | cdef Vert v1, v2, v3, v4 115 | cdef Face f1, f2 116 | 117 | # http://mrl.nyu.edu/~dzorin/cg05/lecture11.pdf 118 | if self.isBoundary(): 119 | return 120 | 121 | # Defining variables 122 | he1 = self.he 123 | he2 = he1.twin 124 | f1, f2 = he1.face, he2.face 125 | he11 = he1.next 126 | he12 = he11.next 127 | he21 = he2.next 128 | he22 = he21.next 129 | v1, v2 = he1.vert, he2.vert 130 | v3, v4 = he12.vert, he22.vert 131 | 132 | if v3 in v4.neighbors(): 133 | return 134 | 135 | # TODO: find out why this happens. 136 | if v3 is v4:# assert(v3 != v4) 137 | return 138 | 139 | # Logic 140 | he1.next = he22 141 | he1.vert = v3 142 | he2.next = he12 143 | he2.vert = v4 144 | he11.next = he1 145 | he12.next = he21 146 | he12.face = f2 147 | he21.next = he2 148 | he22.next = he11 149 | he22.face = f1 150 | 151 | if f2.he is he22: 152 | f2.he = he12 153 | if f1.he is he12: 154 | f1.he = he22 155 | if v1.he is he1: 156 | v1.he = he21 157 | if v2.he is he2: 158 | v2.he = he11 159 | 160 | cdef class Face: 161 | def __init__(self, id, he): 162 | self.id = id 163 | self.he = he 164 | self.normal = np.zeros(3) 165 | self.mate = None 166 | self.generation = 0 167 | 168 | cpdef list vertices(self): 169 | return [self.he.vert, self.he.next.vert, self.he.next.next.vert] 170 | # cdef list result = [] 171 | # cdef HalfEdge h = self.he 172 | # cdef HalfEdge start = h 173 | 174 | # while True: 175 | # result.append(h.vert) 176 | # h = h.next 177 | # if h == start: break 178 | 179 | # return result 180 | 181 | cpdef list edges(self): 182 | cdef list result = [] 183 | cdef HalfEdge h = self.he 184 | cdef HalfEdge start = h 185 | 186 | while True: 187 | result.append(h.edge) 188 | h = h 189 | if h == start: break 190 | 191 | return result 192 | 193 | cpdef double area(self): 194 | """ Area of 3D triangle. 195 | http://www.iquilezles.org/blog/?p=1579 196 | """ 197 | cdef double[:] p1 = self.he.vert.p 198 | cdef double[:] p2 = self.he.next.vert.p 199 | cdef double[:] p3 = self.he.next.next.vert.p 200 | cdef double a, b, c, d 201 | 202 | a = (p1[0] - p2[0])**2 + (p1[1] - p2[1])**2 + (p1[2] - p2[2])**2 # 1-2 203 | b = (p3[0] - p2[0])**2 + (p3[1] - p2[1])**2 + (p3[2] - p2[2])**2 # 2-3 204 | c = (p1[0] - p3[0])**2 + (p1[1] - p3[1])**2 + (p1[2] - p3[2])**2 # 1-3 205 | d = 2*a*b + 2*b*c + 2*c*a - a*a - b*b - c*c 206 | if d <= 0: 207 | return 0.0 208 | return sqrt(d * .0625) # (.0625 = 1/16) 209 | 210 | cpdef double[:] midpoint(self): 211 | cdef double[:] p1 = self.he.vert.p 212 | cdef double[:] p2 = self.he.next.vert.p 213 | cdef double[:] p3 = self.he.next.next.vert.p 214 | cdef double[:] m = np.zeros(3) 215 | m[0] = (p1[0] + p2[0] + p3[0]) / 3.0 216 | m[1] = (p1[1] + p2[1] + p3[1]) / 3.0 217 | m[2] = (p1[2] + p2[2] + p3[2]) / 3.0 218 | return m 219 | 220 | cdef class HalfEdge: 221 | def __init__(self, id, twin, next, vert, edge, face): 222 | self.id = id 223 | self.twin = twin 224 | self.next = next 225 | self.vert = vert 226 | self.edge = edge 227 | self.face = face 228 | 229 | -------------------------------------------------------------------------------- /cymesh/subdivision/__init__.pxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/cymesh/8efd9e9f166f75b5a3f2b4b15c1fe8ce461e0107/cymesh/subdivision/__init__.pxd -------------------------------------------------------------------------------- /cymesh/subdivision/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/cymesh/8efd9e9f166f75b5a3f2b4b15c1fe8ce461e0107/cymesh/subdivision/__init__.py -------------------------------------------------------------------------------- /cymesh/subdivision/sqrt3.pxd: -------------------------------------------------------------------------------- 1 | from cymesh.mesh cimport Mesh 2 | from cymesh.structures cimport Vert, Face, Edge, HalfEdge 3 | 4 | cpdef void split(Mesh mesh, Face f1, int max_vertices=?, int depth=?) except * 5 | cpdef void divide_adaptive(Mesh mesh, double max_face_area) except * 6 | -------------------------------------------------------------------------------- /cymesh/subdivision/sqrt3.pyx: -------------------------------------------------------------------------------- 1 | # cython: boundscheck=False 2 | # cython: wraparound=True 3 | # cython: initializedcheck=False 4 | # cython: nonecheck=False 5 | # cython: cdivision=True 6 | 7 | from cymesh.mesh cimport Mesh 8 | from cymesh.structures cimport Vert, Face, Edge, HalfEdge 9 | 10 | cpdef void split(Mesh mesh, Face f1, int max_vertices=-1, int depth=0) except *: 11 | """ Root(3) subdivision, insert one vertex inside the face. 12 | http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.43.1955&rep=rep1&type=pdf 13 | """ 14 | cdef int generation = f1.generation 15 | cdef double[:] midp 16 | cdef Vert v1, v2, v3, v4 17 | cdef HalfEdge he1, he2, he3, he11, he12, he21, he22, he31, he32 18 | cdef Face f2, f3 19 | cdef Edge e12, e23, e13 20 | 21 | if depth > 6: # Stupid hack to prevent 0-area faces: TODO - figure out why. 22 | f1.generation += 1 23 | return 24 | 25 | if max_vertices != -1 and len(mesh.verts) == max_vertices: 26 | return 27 | 28 | generation = f1.generation 29 | 30 | if generation % 2 == 0: 31 | midp = f1.midpoint() 32 | v4 = mesh._vert(midp[0], midp[1], midp[2]) 33 | he1 = f1.he 34 | he2 = f1.he.next 35 | he3 = f1.he.next.next 36 | 37 | v1 = he1.vert 38 | v2 = he2.vert 39 | v3 = he3.vert 40 | 41 | f2 = mesh._face() 42 | f3 = mesh._face() 43 | 44 | # Create three new edges. 45 | e12 = mesh._edge() 46 | e23 = mesh._edge() 47 | e13 = mesh._edge() 48 | 49 | # Create two new half-edges for each face. 50 | he11 = mesh._half(vert=v2, face=f1, edge=e12, next=None, twin=None) 51 | he12 = mesh._half(vert=v4, face=f1, edge=e13, next=he1, twin=None) 52 | 53 | he21 = mesh._half(vert=v3, face=f2, edge=e23, next=None, twin=None) 54 | he22 = mesh._half(vert=v4, face=f2, edge=e12, next=he2, twin=None) 55 | 56 | he31 = mesh._half(vert=v1, face=f3, edge=e13, next=None, twin=None) 57 | he32 = mesh._half(vert=v4, face=f3, edge=e23, next=he3, twin=None) 58 | 59 | # Set half edge twins and nexts. 60 | he1.next = he11 61 | he11.next = he12 62 | he11.twin = he22 63 | he12.twin = he31 64 | 65 | he2.next = he21 66 | he21.next = he22 67 | he21.twin = he32 68 | he22.twin = he11 69 | 70 | he3.next = he31 71 | he31.next = he32 72 | he31.twin = he12 73 | he32.twin = he21 74 | 75 | # Connect old to faces. 76 | he2.face = f2 77 | he3.face = f3 78 | 79 | #Connect elements ot half-edges 80 | f2.he = he2 81 | f3.he = he3 82 | e12.he = he11 83 | e23.he = he21 84 | e13.he = he31 85 | v4.he = he12 86 | 87 | # Adaptive Refinement Logic. 88 | f1.generation = generation + 1 89 | f2.generation = generation + 1 90 | f3.generation = generation + 1 91 | 92 | f1.mate = he1.twin.face 93 | f2.mate = he2.twin.face 94 | f3.mate = he3.twin.face 95 | 96 | assert f1.area() > 0 97 | assert f2.area() > 0 98 | assert f3.area() > 0 99 | 100 | if f1.mate.generation == f1.generation: 101 | he1.edge.flip() 102 | f1.generation += 1 103 | f1.mate.generation += 1 104 | 105 | if f2.mate.generation == f2.generation: 106 | he2.edge.flip() 107 | f2.generation += 1 108 | f2.mate.generation += 1 109 | 110 | if f3.mate.generation == f3.generation: 111 | he3.edge.flip() 112 | f3.generation += 1 113 | f3.mate.generation += 1 114 | else: 115 | assert f1.mate is not None 116 | else: 117 | if f1.mate.generation == f1.generation - 2: 118 | split(mesh, f1.mate, max_vertices, depth+1) 119 | 120 | split(mesh, f1.mate, max_vertices, depth+1) 121 | 122 | cpdef void divide_adaptive(Mesh mesh, double max_face_area) except *: 123 | cdef Face face 124 | cdef list to_divide = [] 125 | 126 | for face in mesh.faces: 127 | if face.area() > max_face_area: 128 | to_divide.append(face) 129 | 130 | for face in to_divide: 131 | split(mesh, face) 132 | -------------------------------------------------------------------------------- /cymesh/vector3D.pxd: -------------------------------------------------------------------------------- 1 | # cython: boundscheck=False 2 | # cython: wraparound=True 3 | # cython: initializedcheck=False 4 | # cython: nonecheck=False 5 | # cython: cdivision=True 6 | from libc.math cimport sqrt, acos 7 | 8 | cdef inline void vadd(double[:] target, double[:] a, double[:] b): 9 | target[0] = a[0] + b[0] 10 | target[1] = a[1] + b[1] 11 | target[2] = a[2] + b[2] 12 | 13 | cdef inline void vsub(double[:] target, double[:] a, double[:] b): 14 | target[0] = a[0] - b[0] 15 | target[1] = a[1] - b[1] 16 | target[2] = a[2] - b[2] 17 | 18 | cdef inline void vmultf(double[:] target, double[:] a, double f): 19 | target[0] = a[0] * f 20 | target[1] = a[1] * f 21 | target[2] = a[2] * f 22 | 23 | cdef inline void vdivf(double[:] target, double[:] a, double f) except *: 24 | if f == 0.0: 25 | raise ZeroDivisionError() 26 | target[0] = a[0] / f 27 | target[1] = a[1] / f 28 | target[2] = a[2] / f 29 | 30 | cdef inline void vcross(double[:] target, double[:] a, double[:] b): 31 | target[0] = a[1] * b[2] - a[2] * b[1] 32 | target[1] = a[2] * b[0] - a[0] * b[2] 33 | target[2] = a[0] * b[1] - a[1] * b[0] 34 | 35 | cdef inline double dot(double[:] a, double[:] b): 36 | return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] 37 | 38 | cdef inline double vdist(double[:] a, double[:] b): 39 | """ Euclidian distance between two 3D vectors. 40 | Faster than numpy.linalg.norm. 41 | """ 42 | cdef double x = a[0] - b[0] 43 | cdef double y = a[1] - b[1] 44 | cdef double z = a[2] - b[2] 45 | return sqrt(x*x + y*y + z*z) 46 | 47 | cdef inline void vset(double[:] a, double[:] b): 48 | a[0] = b[0] 49 | a[1] = b[1] 50 | a[2] = b[2] 51 | 52 | cdef inline void inormalized(double[:] a): 53 | cdef double d = sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]) 54 | if d == 0.0: 55 | return 56 | a[0] /= d 57 | a[1] /= d 58 | a[2] /= d 59 | 60 | cdef inline double vangle(double[:] a, double[:] b): 61 | return acos(dot(a, b) / (sqrt(dot(a, a)) * sqrt(dot(b, b)))) 62 | 63 | cdef inline double norm(double[:] a): 64 | return sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]) 65 | 66 | -------------------------------------------------------------------------------- /cymesh/view.py: -------------------------------------------------------------------------------- 1 | # Modified version of http://www.pygame.org/wiki/OBJFileLoader 2 | # LMB + move: rotate 3 | # RMB + move: pan 4 | # Scroll wheel: zoom in/out 5 | import sys, pygame, math 6 | from pygame.locals import * 7 | from pygame.constants import * 8 | from OpenGL.GL import * 9 | from OpenGL.GLU import * 10 | from OpenGL.GLUT import * 11 | import numpy as np 12 | from OpenGL.arrays import vbo 13 | from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, \ 14 | glBindVertexArray 15 | class Viewer(object): 16 | def __init__(self, view_size=(800, 600)): 17 | self.on = True 18 | self.draw_grid = False 19 | pygame.init() 20 | glutInit() 21 | viewport = view_size 22 | 23 | hx = viewport[0]/2 24 | hy = viewport[1]/2 25 | self.surface = pygame.display.set_mode(viewport, OPENGL | DOUBLEBUF) 26 | 27 | glLightfv(GL_LIGHT0, GL_POSITION, (-40, 200, 100, 0.0)) 28 | glLightfv(GL_LIGHT0, GL_AMBIENT, (0.2, 0.2, 0.2, 1.0)) 29 | glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.5, 0.5, 0.5, 1.0)) 30 | glEnable(GL_LIGHT0) 31 | glEnable(GL_LIGHTING) 32 | glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE) 33 | glEnable(GL_COLOR_MATERIAL) 34 | # glClearColor(0.4, 0.4, 0.4, 0.0) 35 | glClearColor(1.0, 1.0, 1.0, 0.0) 36 | 37 | glEnable(GL_DEPTH_TEST) 38 | glShadeModel(GL_SMOOTH) 39 | 40 | # glCullFace(GL_BACK) 41 | # glDisable( GL_CULL_FACE ) 42 | # glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE ) 43 | 44 | self.clock = pygame.time.Clock() 45 | 46 | glMatrixMode(GL_PROJECTION) 47 | glLoadIdentity() 48 | width, height = viewport 49 | gluPerspective(90.0, width/float(height), 1, 100.0) 50 | glEnable(GL_DEPTH_TEST) 51 | glMatrixMode(GL_MODELVIEW) 52 | 53 | # Transparancy? 54 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 55 | glEnable(GL_BLEND) 56 | 57 | glTranslated(-15, -15, -15) 58 | # make_plane(5) 59 | 60 | self.rx, self.ry = (0,0) 61 | self.tx, self.ty = (0,0) 62 | self.zpos = 10 63 | 64 | self.gl_lists = [] 65 | 66 | def startDraw(self): 67 | self.gl_list = glGenLists(1) 68 | glNewList(self.gl_list, GL_COMPILE) 69 | 70 | def endDraw(self): 71 | glEndList() 72 | # self.gl_lists.append(self.gl_list) 73 | # self.gl_list = None 74 | 75 | def drawMesh(self, mesh, edges=True): 76 | mesh = mesh.export() 77 | 78 | vert_colors = np.ones_like(mesh['vertices']) 79 | 80 | for vid, data in mesh['vert_data'].items(): 81 | if 'color' in data: 82 | vert_colors[vid] = data['color'] 83 | 84 | vertices = mesh['vertices'].flatten() 85 | normals = mesh['vertice_normals'].flatten() 86 | findices = mesh['faces'].astype('uint32').flatten() 87 | eindices = mesh['edges'].astype('uint32').flatten() 88 | 89 | fcolors = vert_colors.flatten() 90 | ecolors = np.zeros_like(vert_colors).flatten() + .5 91 | 92 | # then convert to OpenGL / ctypes arrays: 93 | fvertices = (GLfloat * len(vertices))(*vertices) 94 | evertices = (GLfloat * len(vertices))(*vertices*1.001) 95 | normals = (GLfloat * len(normals))(*normals) 96 | findices = (GLuint * len(findices))(*findices) 97 | eindices = (GLuint * len(eindices))(*eindices) 98 | fcolors = (GLfloat * len(fcolors))(*fcolors) 99 | ecolors = (GLfloat * len(ecolors))(*ecolors) 100 | 101 | glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT) 102 | glEnableClientState(GL_VERTEX_ARRAY) 103 | glEnableClientState(GL_NORMAL_ARRAY) 104 | glEnableClientState(GL_COLOR_ARRAY) 105 | glVertexPointer(3, GL_FLOAT, 0, fvertices) 106 | glNormalPointer(GL_FLOAT, 0, normals) 107 | glColorPointer(3, GL_FLOAT, 0, fcolors) 108 | glDrawElements(GL_TRIANGLES, len(findices), GL_UNSIGNED_INT, findices) 109 | 110 | if edges: 111 | glColorPointer(3, GL_FLOAT, 0, ecolors) 112 | glVertexPointer(3, GL_FLOAT, 0, evertices) 113 | glDrawElements(GL_LINES, len(eindices), GL_UNSIGNED_INT, eindices) 114 | 115 | glPopClientAttrib() 116 | 117 | def handle_input(self, e): 118 | if e.type == QUIT: 119 | self.on = False 120 | 121 | elif e.type == KEYDOWN and e.key == K_ESCAPE: 122 | self.on = False 123 | 124 | elif e.type == MOUSEBUTTONDOWN: 125 | if e.button == 4: self.zpos = max(1, self.zpos-1) 126 | elif e.button == 5: self.zpos += 1 127 | elif e.button == 1: self.rotate = True 128 | # elif e.button == 3: self.move = True 129 | 130 | elif e.type == MOUSEBUTTONUP: 131 | if e.button == 1: self.rotate = False 132 | # elif e.button == 3: self.move = False 133 | 134 | elif e.type == MOUSEMOTION: 135 | i, j = e.rel 136 | if self.rotate: 137 | self.rx += i 138 | self.ry += j 139 | if self.move: 140 | self.tx += i 141 | self.ty -= j 142 | 143 | # if e.type == KEYDOWN: 144 | # if e.key == K_g: 145 | # self.draw_grid = not self.draw_grid 146 | # elif e.key == K_s: 147 | # print('save!') 148 | # pygame.image.save(self.surface, 'render.jpg') 149 | 150 | def step(self, i): 151 | pass 152 | 153 | def mainLoop(self): 154 | self.rotate = False 155 | self.move = False 156 | i = 0 157 | 158 | while self.on: 159 | self.clock.tick(15) 160 | self.step(i) 161 | 162 | # for raw_input('') 163 | for e in pygame.event.get(): 164 | self.handle_input(e) 165 | 166 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 167 | glLoadIdentity() 168 | 169 | # RENDER OBJECT 170 | glTranslate(self.tx/20., self.ty/20., - self.zpos) 171 | glRotate(self.ry, 1, 0, 0) 172 | glRotate(self.rx, 0, 1, 0) 173 | 174 | glCallList(self.gl_list) 175 | 176 | pygame.display.flip() 177 | i += 1 178 | 179 | class AnimationViewer(Viewer): 180 | def __init__(self, view_size=(800, 600)): 181 | super(AnimationViewer, self).__init__(view_size) 182 | self.frames = [] 183 | self.frame = 0 184 | self.animation_playing = True 185 | 186 | def startFrame(self): 187 | self.startDraw() 188 | 189 | def endFrame(self): 190 | self.endDraw() 191 | self.frames.append(self.gl_list) 192 | 193 | def handle_input(self, e): 194 | super(AnimationViewer, self).handle_input(e) 195 | 196 | if e.type == MOUSEBUTTONDOWN: 197 | # print(e.button) 198 | if e.button == 3: 199 | # self.animation_playing = not self.animation_playing 200 | self.frame = 0 201 | 202 | # if e.type == KEYDOWN: 203 | # if e.key == K_RIGHT: 204 | # if self.frame < self.n_frames - 1: 205 | # self.frame += 1 206 | # self.gl_lists = self.view_lists[self.view][self.frame] 207 | 208 | # elif e.key == K_LEFT: 209 | # if self.frame > 0: 210 | # self.frame -= 1 211 | # self.gl_lists = self.view_lists[self.view][self.frame] 212 | 213 | # elif e.key == K_r: 214 | # self.frame = 0 215 | # self.gl_lists = self.view_lists[self.view][self.frame] 216 | 217 | # elif e.key == K_SPACE: 218 | # self.animation_playing = not self.animation_playing 219 | 220 | # elif e.key == K_1: 221 | # self.view = 0 222 | # elif e.key == K_2: 223 | # self.view = 1 224 | # elif e.key == K_3: 225 | # self.view = 2 226 | # self.gl_lists = self.view_lists[self.view][self.frame] 227 | 228 | def step(self, i): 229 | if self.animation_playing: 230 | self.rx += 1 231 | # self.zpos += .25 232 | 233 | if self.animation_playing and self.frame < (len(self.frames) - 1): 234 | self.frame += 1 235 | 236 | # if self.frame == len(self.frames): 237 | # self.frame = 0 238 | 239 | self.gl_list = self.frames[self.frame] 240 | 241 | -------------------------------------------------------------------------------- /demo.py: -------------------------------------------------------------------------------- 1 | from random import random 2 | from cymesh.mesh import Mesh 3 | from cymesh.view import Viewer 4 | 5 | mesh = Mesh.from_obj('triangulated_sphere_2.obj') 6 | 7 | # Add noise to mesh. 8 | for vert in mesh.verts: 9 | vert.p[0] += random() * .2 10 | vert.p[1] += random() * .2 11 | vert.p[2] += random() * .2 12 | 13 | # If not given a max length, all edges are split. 14 | mesh.splitEdges() 15 | 16 | # Flip edges which will become shorter. 17 | mesh.shortenEdges() 18 | 19 | # Normals and curvature updates must be called after making changes to mesh. 20 | mesh.calculateNormals() 21 | mesh.calculateCurvature() 22 | 23 | # We can write our new object to a file. 24 | mesh.writeObj('my_mesh.obj') 25 | 26 | # We can also export the mesh to a dict of numpy arrays. 27 | export = mesh.export() 28 | print(export.keys()) 29 | # > dict_keys(['faces', 'vertice_normals', 'face_normals', 'vert_data', 'vertices', 'curvature', 'edges']) 30 | 31 | # Each vert has a dictionary 'data' attribute to add additional information. 32 | # Colors can be passed to the viewer by adding a color to data. 33 | for vert in mesh.verts: 34 | if vert.curvature > 0: 35 | vert.data['color'] = (2*vert.curvature, 0.0, 0.0) 36 | else: 37 | vert.data['color'] = (0.0, -2 * vert.curvature, 0.0) 38 | 39 | # View the mesh with pyopengl. 40 | view = Viewer() 41 | view.startDraw() 42 | view.drawMesh(mesh, edges=False) 43 | view.endDraw() 44 | view.mainLoop() 45 | -------------------------------------------------------------------------------- /demo_collisions.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | 3 | import time 4 | from random import random, choice, seed 5 | import numpy as np 6 | 7 | from cymesh.mesh import Mesh 8 | from cymesh.view import Viewer 9 | from cymesh.collisions.findCollisions import findCollisions 10 | 11 | from cymesh.subdivision.sqrt3 import divide_adaptive 12 | from cymesh.operators.relax import relax_mesh 13 | 14 | seed(1234) 15 | 16 | mesh = Mesh.from_obj('triangulated_sphere_2.obj') 17 | print('loaded mesh') 18 | 19 | max_area = max(f.area() for f in mesh.faces) * 1.5 20 | start = time.time() 21 | 22 | for i in range(10): 23 | print(i, 'n_verts:', len(mesh.verts)) 24 | 25 | mesh.calculateNormals() 26 | mesh.calculateCurvature() 27 | 28 | for vert in mesh.verts: 29 | vert.data['old_p'] = np.copy(vert.p) 30 | 31 | if vert.data.get('collided', False): 32 | continue 33 | 34 | dist = random() * .4 35 | vert.p[0] += dist * vert.normal[0] 36 | vert.p[1] += dist * vert.normal[1] 37 | vert.p[2] += dist * vert.normal[2] 38 | 39 | collisions = findCollisions(mesh) 40 | print('n_collisions:', sum(collisions)) 41 | 42 | for vi, collided in enumerate(collisions): 43 | if collided: 44 | vert = mesh.verts[vi] 45 | vert.data['collided'] = True 46 | vert.p[:] = vert.data['old_p'] 47 | 48 | divide_adaptive(mesh, max_area) 49 | relax_mesh(mesh) 50 | 51 | print('finished in ', time.time() - start) 52 | 53 | mesh.writeObj('collided_mesh.obj') 54 | 55 | v = Viewer((800, 800)) 56 | v.startDraw() 57 | v.drawMesh(mesh) 58 | v.endDraw() 59 | v.mainLoop() 60 | 61 | -------------------------------------------------------------------------------- /demo_shape_features.py: -------------------------------------------------------------------------------- 1 | import time 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from cymesh.mesh import Mesh 5 | from cymesh.shape_features import d2_features, a2_features, a3_features 6 | mesh = Mesh.from_obj('my_mesh.obj') 7 | 8 | t1 = time.time() 9 | plt.plot(d2_features(mesh, n_points=2028*5, n_bins=32, hrange=(0.0, 3.0)), label='d2') 10 | plt.plot(a2_features(mesh, n_points=2028*5, n_bins=32, hrange=(0.0, 3.0)), label='a2') 11 | plt.plot(a3_features(mesh, n_points=2028*5, n_bins=32, hrange=(0.0, 3.0)), label='a3') 12 | 13 | print('Finished in', time.time() - t1) 14 | 15 | plt.legend() 16 | plt.show() -------------------------------------------------------------------------------- /my_mesh.obj: -------------------------------------------------------------------------------- 1 | # Created by cymesh. 2 | v 0.890853 0.056981 -0.283989 3 | v 0.813118 0.096662 0.458369 4 | v -0.581932 0.161787 0.442992 5 | v -0.641626 0.032751 -0.295289 6 | v 0.044459 -0.367455 0.698227 7 | v 0.180404 0.593015 0.830748 8 | v 0.044033 0.426001 -0.636239 9 | v 0.047584 -0.365344 -0.700427 10 | v -0.226892 -0.606502 0.037535 11 | v 0.467486 -0.584639 0.002620 12 | v 0.447706 0.712627 -0.011079 13 | v -0.245866 0.692959 0.008753 14 | v 0.187188 0.835695 0.117450 15 | v -0.049109 0.877963 0.051936 16 | v -0.027279 -0.698891 0.120424 17 | v 0.222974 -0.662006 0.167320 18 | v -0.052994 -0.545050 -0.336079 19 | v -0.159649 -0.631480 -0.186571 20 | v -0.220764 0.667698 -0.096156 21 | v -0.074381 0.677399 -0.429623 22 | v -0.371861 0.234753 -0.528140 23 | v -0.203829 0.372736 -0.588237 24 | v -0.055128 -0.258045 -0.548495 25 | v -0.441088 0.007507 -0.527668 26 | v -0.001572 0.679408 0.591956 27 | v -0.231116 0.770135 0.390003 28 | v -0.138831 -0.481707 0.233006 29 | v -0.039507 -0.442823 0.552037 30 | v -0.456362 -0.071771 0.712095 31 | v -0.191886 -0.152055 0.753705 32 | v -0.170778 0.357116 0.791240 33 | v -0.388719 0.275725 0.586285 34 | v -0.365773 0.676453 -0.159748 35 | v -0.577049 0.406559 -0.236530 36 | v -0.524704 0.299075 0.318292 37 | v -0.375253 0.598283 0.216663 38 | v -0.599490 0.002485 0.323360 39 | v -0.727823 0.034605 -0.178497 40 | v -0.537561 -0.401966 0.276702 41 | v -0.606471 -0.238859 0.411914 42 | v -0.553700 -0.098706 -0.324253 43 | v -0.397476 -0.467516 -0.078471 44 | v 0.373808 0.717079 0.411221 45 | v 0.262721 0.634891 0.554391 46 | v 0.200326 -0.450602 0.636546 47 | v 0.425239 -0.483774 0.350289 48 | v 0.096614 0.210968 0.802724 49 | v 0.057018 -0.016633 0.770576 50 | v 0.660184 0.156142 0.685416 51 | v 0.275337 0.440488 0.692272 52 | v 0.444594 -0.224165 0.695572 53 | v 0.644760 -0.060596 0.713070 54 | v 0.405013 -0.537898 -0.169065 55 | v 0.335305 -0.373474 -0.335060 56 | v 0.333276 0.590145 -0.393351 57 | v 0.483264 0.849545 -0.110950 58 | v 0.431868 0.436163 -0.530773 59 | v 0.681964 0.160391 -0.529816 60 | v 0.073947 -0.013886 -0.603812 61 | v 0.042426 0.246895 -0.597485 62 | v 0.629192 -0.046597 -0.428296 63 | v 0.431509 -0.315525 -0.625145 64 | v 0.664950 0.663580 0.136940 65 | v 0.875037 0.401873 0.356861 66 | v 0.745762 0.389472 -0.235668 67 | v 0.647957 0.672276 -0.060237 68 | v 0.852680 0.193881 -0.121525 69 | v 0.840918 0.134158 0.334618 70 | v 0.712157 -0.447489 -0.033256 71 | v 0.848537 -0.168312 -0.247988 72 | v 0.779498 -0.063056 0.302509 73 | v 0.679857 -0.397204 0.148508 74 | v 0.104877 -0.657773 -0.168432 75 | v 0.195763 0.816446 -0.149072 76 | v 0.197849 0.913021 0.306686 77 | v 0.046479 -0.615442 0.269619 78 | v -0.233137 -0.335208 -0.313068 79 | v -0.420313 0.530645 -0.279101 80 | v -0.209436 0.028713 -0.584818 81 | v -0.253865 0.465350 0.431214 82 | v -0.262742 -0.400129 0.493568 83 | v -0.064060 0.042010 0.847573 84 | v -0.567357 0.283460 0.170506 85 | v -0.632884 -0.212902 0.062260 86 | v 0.501369 0.511784 0.587358 87 | v 0.605280 -0.402282 0.530860 88 | v 0.336371 0.194580 0.783596 89 | v 0.644761 -0.313948 -0.466061 90 | v 0.601635 0.565109 -0.442021 91 | v 0.407439 0.048052 -0.732231 92 | v 0.758003 0.468896 0.090394 93 | v 0.884174 -0.259861 0.116001 94 | v 0.796308 0.016803 0.380439 95 | v 0.810208 0.035551 0.318564 96 | v 0.827018 0.115410 0.396493 97 | v 0.818307 0.223226 -0.259828 98 | v 0.799221 0.291677 -0.178596 99 | v 0.871767 0.125431 -0.202757 100 | v 0.760023 0.005192 -0.356143 101 | v 0.655578 0.056897 -0.479056 102 | v 0.786409 0.108686 -0.406903 103 | v 0.713863 0.274931 -0.382742 104 | v 0.869695 -0.055666 -0.265989 105 | v 0.738864 -0.107455 -0.338142 106 | v 0.244526 -0.295810 0.696899 107 | v 0.250806 -0.120399 0.733074 108 | v 0.050738 -0.192044 0.734401 109 | v 0.573672 -0.490922 0.075564 110 | v 0.552548 -0.440489 0.249398 111 | v 0.446363 -0.534206 0.176455 112 | v 0.844078 0.249268 0.407615 113 | v 0.767611 0.279008 0.521139 114 | v 0.736651 0.126402 0.571893 115 | v -0.597663 -0.032977 -0.309771 116 | v -0.640761 -0.032050 -0.251375 117 | v -0.684725 0.033678 -0.236893 118 | v -0.553318 0.230431 0.380642 119 | v -0.562097 0.150780 0.320826 120 | v -0.590711 0.082136 0.383176 121 | v -0.067434 -0.084344 0.762141 122 | v -0.073714 -0.259755 0.725966 123 | v -0.594201 -0.038536 0.427453 124 | v -0.531416 -0.155315 0.562004 125 | v -0.519147 0.045008 0.577544 126 | v 0.089416 0.636211 0.711352 127 | v -0.086175 0.518262 0.691598 128 | v 0.004813 0.475065 0.810994 129 | v 0.043229 0.336448 -0.616862 130 | v -0.080702 0.309815 -0.592861 131 | v -0.079898 0.399368 -0.612238 132 | v -0.609338 0.219655 -0.265910 133 | v -0.474455 0.320656 -0.382335 134 | v -0.506744 0.133752 -0.411715 135 | v -0.541357 0.020129 -0.411479 136 | v -0.497394 -0.045599 -0.425961 137 | v 0.002476 -0.405139 0.625132 138 | v 0.080410 -0.446712 0.594292 139 | v 0.122392 -0.409028 0.667386 140 | v 0.221563 0.613953 0.692569 141 | v 0.130575 0.657150 0.573173 142 | v -0.015174 0.551700 -0.532931 143 | v 0.129447 0.633772 -0.411487 144 | v 0.188654 0.508073 -0.514795 145 | v 0.191445 -0.369409 -0.517744 146 | v 0.141155 -0.459262 -0.335569 147 | v -0.002705 -0.455197 -0.518253 148 | v -0.093464 -0.665185 -0.033074 149 | v -0.127086 -0.652696 0.078980 150 | v -0.193271 -0.618991 -0.074518 151 | v 0.313993 -0.599952 -0.000873 152 | v 0.436250 -0.561269 -0.083222 153 | v 0.345230 -0.623322 0.084970 154 | v 0.163925 -0.659889 -0.000556 155 | v 0.254945 -0.597835 -0.168749 156 | v 0.038799 -0.678332 -0.024004 157 | v 0.097847 -0.680448 0.143872 158 | v -0.027386 -0.644626 -0.177502 159 | v 0.025941 -0.601411 -0.252255 160 | v -0.106322 -0.588265 -0.261325 161 | v 0.220091 -0.515623 -0.251746 162 | v 0.370159 -0.455686 -0.252062 163 | v 0.335226 0.842620 0.003250 164 | v 0.317447 0.774161 0.053185 165 | v 0.465485 0.781086 -0.061014 166 | v -0.134936 0.772831 -0.022110 167 | v -0.233315 0.680328 -0.043702 168 | v -0.147488 0.785461 0.030344 169 | v 0.073327 0.847205 -0.048568 170 | v -0.012500 0.742072 -0.122614 171 | v 0.191476 0.826071 -0.015811 172 | v 0.069040 0.856829 0.084693 173 | v 0.339513 0.832996 -0.130011 174 | v 0.264519 0.703296 -0.271211 175 | v 0.408270 0.719845 -0.252150 176 | v 0.060691 0.746923 -0.289348 177 | v -0.147572 0.672549 -0.262890 178 | v -0.140113 0.824049 0.220969 179 | v -0.238491 0.731547 0.199378 180 | v 0.280498 0.776387 0.264335 181 | v 0.410757 0.714853 0.200071 182 | v 0.192519 0.874358 0.212068 183 | v 0.285829 0.815050 0.358953 184 | v 0.074370 0.895492 0.179311 185 | v -0.016634 0.841578 0.348344 186 | v 0.098139 0.796215 0.449321 187 | v -0.116344 0.724772 0.490979 188 | v 0.230285 0.773956 0.430538 189 | v 0.318265 0.675985 0.482806 190 | v 0.324107 -0.572890 0.258804 191 | v -0.083055 -0.590299 0.176715 192 | v -0.182862 -0.544104 0.135271 193 | v 0.009600 -0.657166 0.195021 194 | v -0.046176 -0.548574 0.251313 195 | v 0.134726 -0.638724 0.218469 196 | v 0.235859 -0.549608 0.309954 197 | v 0.123402 -0.533022 0.453082 198 | v 0.312783 -0.467188 0.493417 199 | v 0.003486 -0.529132 0.410828 200 | v -0.089169 -0.462265 0.392522 201 | v -0.278563 -0.549498 -0.132521 202 | v -0.312184 -0.537009 -0.020468 203 | v -0.054061 -0.401547 -0.442287 204 | v -0.003772 -0.311694 -0.624461 205 | v -0.143066 -0.440129 -0.324574 206 | v -0.144133 -0.296626 -0.430782 207 | v -0.196393 -0.483344 -0.249820 208 | v -0.315307 -0.401362 -0.195770 209 | v -0.393418 -0.216957 -0.318661 210 | v -0.475588 -0.283111 -0.201362 211 | v -0.337113 -0.163850 -0.420368 212 | v -0.248108 -0.125269 -0.538082 213 | v -0.139105 0.525067 -0.508930 214 | v -0.293269 0.672075 -0.127952 215 | v -0.305820 0.684706 -0.075497 216 | v -0.320538 0.599172 -0.187629 217 | v -0.393043 0.603549 -0.219424 218 | v -0.247347 0.604022 -0.354362 219 | v -0.312071 0.451690 -0.433669 220 | v -0.396087 0.382699 -0.403621 221 | v -0.287845 0.303744 -0.558188 222 | v -0.498681 0.468602 -0.257816 223 | v -0.471411 0.541506 -0.198139 224 | v -0.406474 0.121130 -0.527904 225 | v 0.009409 -0.135965 -0.576154 226 | v 0.060766 -0.189615 -0.652120 227 | v -0.132282 -0.114666 -0.566656 228 | v -0.067745 0.007413 -0.594315 229 | v -0.325262 0.018110 -0.556243 230 | v -0.290649 0.131733 -0.556479 231 | v -0.206633 0.200724 -0.586527 232 | v -0.083505 0.137804 -0.591151 233 | v 0.058186 0.116504 -0.600649 234 | v -0.456712 0.287400 0.452289 235 | v -0.485326 0.218756 0.514639 236 | v -0.303185 0.684209 0.303333 237 | v -0.310560 0.645621 0.112708 238 | v -0.314559 0.531816 0.323939 239 | v -0.242491 0.617742 0.410609 240 | v -0.389285 0.382213 0.374753 241 | v -0.449979 0.448679 0.267478 242 | v -0.321292 0.370537 0.508750 243 | v -0.212322 0.411233 0.611227 244 | v -0.279749 0.316421 0.688762 245 | v -0.127718 0.572379 0.511585 246 | v -0.115697 -0.297439 0.652871 247 | v -0.338196 -0.441836 0.254854 248 | v -0.382227 -0.504234 0.157118 249 | v -0.200786 -0.440918 0.363287 250 | v -0.400151 -0.401047 0.385135 251 | v -0.151124 -0.421476 0.522802 252 | v -0.227314 -0.276092 0.623636 253 | v -0.359552 -0.235950 0.602831 254 | v -0.324124 -0.111913 0.732900 255 | v -0.434606 -0.319494 0.452741 256 | v -0.572016 -0.320412 0.344308 257 | v -0.422541 0.101977 0.649190 258 | v -0.037082 0.284042 0.796982 259 | v 0.138509 0.401991 0.816736 260 | v -0.117419 0.199563 0.819406 261 | v 0.016277 0.126489 0.825148 262 | v -0.226390 0.158867 0.716929 263 | v -0.260211 -0.014881 0.779834 264 | v -0.127973 -0.055022 0.800639 265 | v -0.003521 0.012688 0.809075 266 | v 0.076816 0.097167 0.786650 267 | v -0.652436 0.220582 -0.207514 268 | v -0.370513 0.637368 0.028458 269 | v -0.466565 0.479956 0.005379 270 | v -0.471305 0.440872 0.193585 271 | v -0.572203 0.345010 -0.033012 272 | v -0.647590 0.159033 -0.003996 273 | v -0.583424 0.142972 0.246933 274 | v -0.663657 0.018545 0.072431 275 | v -0.546031 0.291268 0.244399 276 | v -0.602980 -0.118187 0.367637 277 | v -0.467519 -0.434741 0.099115 278 | v -0.585223 -0.307434 0.169481 279 | v -0.515180 -0.340209 -0.008105 280 | v -0.619678 -0.225880 0.237087 281 | v -0.616187 -0.105209 0.192810 282 | v -0.680354 -0.089148 -0.058119 283 | v -0.593292 -0.155804 -0.130996 284 | v 0.269029 0.537690 0.623331 285 | v 0.227871 0.516752 0.761510 286 | v 0.519379 0.690330 0.274080 287 | v 0.556328 0.688104 0.062931 288 | v 0.437589 0.614432 0.499289 289 | v 0.583159 0.587682 0.362149 290 | v 0.382045 0.573338 0.570874 291 | v 0.388353 0.476136 0.639815 292 | v 0.580777 0.333963 0.636387 293 | v 0.467761 0.298315 0.688844 294 | v 0.688203 0.456829 0.472109 295 | v 0.769993 0.532727 0.246901 296 | v 0.322460 -0.337383 0.666059 297 | v 0.712129 -0.061826 0.507790 298 | v 0.728939 0.018033 0.585720 299 | v 0.625020 -0.231439 0.621965 300 | v 0.692389 -0.232669 0.416685 301 | v 0.524937 -0.313224 0.613216 302 | v 0.544677 -0.142381 0.704321 303 | v 0.402803 -0.426442 0.583703 304 | v 0.515260 -0.443028 0.440574 305 | v 0.642569 -0.399743 0.339684 306 | v 0.729678 -0.230130 0.225508 307 | v 0.185976 0.325728 0.747498 308 | v 0.652472 0.047773 0.699243 309 | v 0.498278 0.175361 0.734506 310 | v 0.490565 0.066992 0.748333 311 | v 0.305854 0.317534 0.737934 312 | v 0.216493 0.202774 0.793160 313 | v 0.196694 0.088973 0.777086 314 | v 0.390482 -0.014793 0.739584 315 | v 0.383407 -0.344499 -0.480103 316 | v 0.239547 -0.340434 -0.662786 317 | v 0.558585 -0.492694 -0.101161 318 | v 0.589821 -0.516064 -0.015318 319 | v 0.524887 -0.425923 -0.317563 320 | v 0.678459 -0.380718 -0.249658 321 | v 0.490033 -0.343711 -0.400560 322 | v 0.538135 -0.314736 -0.545603 323 | v 0.636977 -0.180272 -0.447178 324 | v 0.530350 -0.181061 -0.526721 325 | v 0.746649 -0.241130 -0.357025 326 | v 0.780347 -0.307901 -0.140622 327 | v 0.565610 0.760910 -0.085593 328 | v 0.547831 0.692452 -0.035658 329 | v 0.382572 0.513154 -0.462062 330 | v 0.237950 0.431082 -0.583506 331 | v 0.467455 0.577627 -0.417686 332 | v 0.516751 0.500636 -0.486397 333 | v 0.542449 0.707327 -0.276485 334 | v 0.624796 0.618693 -0.251129 335 | v 0.673698 0.477290 -0.338844 336 | v 0.696859 0.530874 -0.147952 337 | v 0.641800 0.362750 -0.485918 338 | v 0.556916 0.298277 -0.530294 339 | v 0.237147 0.341529 -0.564129 340 | v 0.252728 -0.164706 -0.614479 341 | v 0.240693 0.017083 -0.668022 342 | v 0.419474 -0.133737 -0.678688 343 | v 0.224932 0.147473 -0.664858 344 | v 0.419653 0.242107 -0.631502 345 | v 0.544702 0.104221 -0.631024 346 | v 0.518315 0.000727 -0.580264 347 | v 0.857977 0.268016 0.345739 348 | v 0.656453 0.667928 0.038352 349 | v 0.711476 0.566238 0.113667 350 | v 0.702980 0.570586 0.015078 351 | v 0.816520 0.435385 0.223627 352 | v 0.799460 0.301527 0.212506 353 | v 0.805342 0.331389 -0.015566 354 | v 0.846799 0.164020 0.106546 355 | v 0.751882 0.429184 -0.072637 356 | v 0.850609 0.012785 -0.184757 357 | v 0.696007 -0.422346 0.057626 358 | v 0.798166 -0.353675 0.041372 359 | v 0.782016 -0.328533 0.132254 360 | v 0.866356 -0.214087 -0.065994 361 | v 0.868427 -0.032990 -0.002762 362 | v 0.862546 -0.062852 0.225309 363 | v 0.831836 -0.161459 0.209255 364 | vn 0.953723 -0.027400 -0.299436 365 | vn 0.906474 -0.194752 0.374669 366 | vn -0.935330 0.281097 0.214808 367 | vn -0.779305 -0.077207 -0.621870 368 | vn -0.155705 -0.529780 0.833720 369 | vn 0.353280 0.465776 0.811324 370 | vn 0.051091 0.345105 -0.937172 371 | vn -0.291711 -0.533186 -0.794114 372 | vn -0.472382 -0.864428 0.172100 373 | vn 0.373612 -0.927523 -0.010702 374 | vn 0.426970 0.782526 0.453155 375 | vn -0.487643 0.866105 -0.109844 376 | vn 0.412007 0.891700 -0.187407 377 | vn -0.268244 0.929356 -0.253657 378 | vn -0.257617 -0.928828 0.266294 379 | vn 0.219484 -0.948586 0.228061 380 | vn -0.292385 -0.707062 -0.643875 381 | vn -0.429477 -0.811185 -0.396899 382 | vn -0.171326 0.906532 -0.385807 383 | vn -0.212827 0.800314 -0.560538 384 | vn -0.557813 0.251897 -0.790818 385 | vn -0.346050 0.238987 -0.907267 386 | vn -0.644315 -0.230723 -0.729126 387 | vn -0.569287 -0.220756 -0.791946 388 | vn -0.305145 0.732694 0.608314 389 | vn -0.639451 0.684584 0.349923 390 | vn -0.380364 -0.817528 0.432401 391 | vn -0.345448 -0.807070 0.478856 392 | vn -0.576847 -0.162798 0.800465 393 | vn -0.188505 -0.494936 0.848236 394 | vn -0.523917 0.315401 0.791222 395 | vn -0.643056 0.485240 0.592470 396 | vn -0.337413 0.877304 -0.341307 397 | vn -0.805123 0.459879 -0.374551 398 | vn -0.813092 0.502097 0.294585 399 | vn -0.772855 0.601548 0.202077 400 | vn -0.987332 0.109957 0.114392 401 | vn -0.985922 -0.049348 -0.159756 402 | vn -0.556470 -0.813441 0.169278 403 | vn -0.888963 -0.305772 0.340952 404 | vn -0.663657 -0.539078 -0.518608 405 | vn -0.659266 -0.664960 -0.350994 406 | vn 0.466345 0.814080 0.346115 407 | vn 0.386451 0.702265 0.597896 408 | vn 0.091890 -0.752370 0.652300 409 | vn 0.326941 -0.892750 0.310011 410 | vn 0.208349 -0.030080 0.977592 411 | vn 0.167451 -0.254015 0.952595 412 | vn 0.602281 0.201974 0.772311 413 | vn 0.538440 0.229245 0.810882 414 | vn 0.188117 -0.353089 0.916482 415 | vn 0.625101 -0.242314 0.741979 416 | vn 0.242774 -0.862338 -0.444335 417 | vn 0.139456 -0.845747 -0.515038 418 | vn 0.078746 0.721231 -0.688204 419 | vn 0.248678 0.968563 -0.006641 420 | vn 0.178700 0.404014 -0.897128 421 | vn 0.674473 0.071484 -0.734830 422 | vn -0.245546 0.003410 -0.969379 423 | vn -0.072698 0.006182 -0.997335 424 | vn 0.656954 -0.175064 -0.733324 425 | vn 0.346800 -0.454340 -0.820552 426 | vn 0.588058 0.800936 0.112644 427 | vn 0.961128 0.240928 0.134856 428 | vn 0.883188 0.393712 -0.254892 429 | vn 0.756641 0.653178 0.029219 430 | vn 0.974768 0.222940 -0.011166 431 | vn 0.986881 -0.094868 0.130639 432 | vn 0.608380 -0.786500 -0.106264 433 | vn 0.900552 -0.258433 -0.349598 434 | vn 0.807335 -0.375895 0.454877 435 | vn 0.585481 -0.736355 0.339106 436 | vn 0.165664 -0.892898 -0.418675 437 | vn -0.065995 0.919372 -0.387814 438 | vn 0.348384 0.914891 0.203971 439 | vn -0.160424 -0.857609 0.488643 440 | vn -0.538215 -0.549558 -0.638992 441 | vn -0.469063 0.641943 -0.606539 442 | vn -0.173967 -0.081981 -0.981333 443 | vn -0.689506 0.494103 0.529568 444 | vn -0.332952 -0.788085 0.517750 445 | vn -0.102421 -0.107130 0.988956 446 | vn -0.891475 0.412656 0.187049 447 | vn -0.931026 -0.363007 -0.037633 448 | vn 0.407663 0.619589 0.670761 449 | vn 0.572613 -0.673076 0.468063 450 | vn 0.185734 0.110564 0.976360 451 | vn 0.500647 -0.602784 -0.621292 452 | vn 0.516904 0.577334 -0.632056 453 | vn 0.231365 -0.008952 -0.972826 454 | vn 0.920188 0.350345 -0.174680 455 | vn 0.824606 -0.420168 0.378791 456 | vn 0.910341 -0.370866 0.183677 457 | vn 0.869410 -0.330556 0.367232 458 | vn 0.959354 -0.244147 0.141534 459 | vn 0.860694 0.417860 -0.290858 460 | vn 0.900485 0.413326 -0.135238 461 | vn 0.982855 0.154324 0.100893 462 | vn 0.555441 -0.356490 -0.751266 463 | vn 0.602057 -0.470056 -0.645426 464 | vn 0.753536 -0.038026 -0.656305 465 | vn 0.831709 0.335961 -0.442030 466 | vn 0.866057 -0.233325 -0.442160 467 | vn 0.619192 -0.045442 -0.783924 468 | vn 0.119158 -0.315303 0.941481 469 | vn 0.085779 -0.193059 0.977430 470 | vn 0.061941 -0.203717 0.977068 471 | vn 0.504234 -0.808173 0.304311 472 | vn 0.441154 -0.879313 0.179421 473 | vn 0.487270 -0.821045 0.297411 474 | vn 0.946674 -0.089074 0.309637 475 | vn 0.741069 0.206344 0.638936 476 | vn 0.830965 0.013595 0.556158 477 | vn -0.734868 -0.365677 -0.571183 478 | vn -0.749388 -0.479038 -0.457100 479 | vn -0.804610 -0.016782 -0.593566 480 | vn -0.840533 0.511786 0.177708 481 | vn -0.969622 0.244568 0.004469 482 | vn -0.987522 0.148408 -0.052686 483 | vn 0.147565 -0.384741 0.911153 484 | vn -0.168778 -0.415406 0.893841 485 | vn -0.971562 0.041422 0.233132 486 | vn -0.743205 -0.353193 0.568244 487 | vn -0.811897 0.196777 0.549639 488 | vn -0.166137 0.879994 0.444983 489 | vn -0.617562 0.621935 0.481470 490 | vn -0.315679 0.320368 0.893147 491 | vn 0.060816 -0.211608 -0.975461 492 | vn -0.093054 -0.109360 -0.989637 493 | vn -0.223427 0.175647 -0.958764 494 | vn -0.755815 0.227107 -0.614138 495 | vn -0.652308 0.356369 -0.668950 496 | vn -0.727313 0.223180 -0.649004 497 | vn -0.757535 -0.131107 -0.639493 498 | vn -0.606420 -0.515879 -0.605082 499 | vn -0.316603 -0.756714 0.571968 500 | vn -0.205550 -0.837531 0.506252 501 | vn -0.075618 -0.681638 0.727771 502 | vn 0.632649 0.715293 0.296834 503 | vn 0.211316 0.855161 0.473334 504 | vn -0.032047 0.625563 -0.779515 505 | vn 0.213766 0.727868 -0.651546 506 | vn 0.187152 0.695999 -0.693224 507 | vn 0.272535 -0.932911 -0.235375 508 | vn 0.344559 -0.776653 -0.527342 509 | vn -0.461173 -0.738659 -0.491632 510 | vn -0.276778 -0.956642 -0.090720 511 | vn -0.514327 -0.766930 0.383778 512 | vn -0.523401 -0.849803 -0.062330 513 | vn 0.217826 -0.948039 -0.231894 514 | vn 0.291070 -0.890977 -0.348481 515 | vn 0.340439 -0.938033 0.064780 516 | vn 0.264215 -0.958729 -0.105022 517 | vn 0.327901 -0.823429 -0.463082 518 | vn 0.036701 -0.991559 -0.124355 519 | vn 0.103814 -0.972053 0.210560 520 | vn -0.067979 -0.931126 -0.358307 521 | vn 0.122580 -0.766300 -0.630681 522 | vn -0.343051 -0.686214 -0.641425 523 | vn 0.269568 -0.640138 -0.719414 524 | vn 0.096245 -0.686660 -0.720580 525 | vn 0.298533 0.803294 0.515360 526 | vn 0.402641 0.860132 0.313134 527 | vn 0.308808 0.632020 0.710766 528 | vn -0.481685 0.732284 -0.481394 529 | vn 0.145580 0.969221 -0.198539 530 | vn -0.646681 0.735194 -0.203209 531 | vn -0.076182 0.923688 -0.375496 532 | vn -0.353280 0.851125 -0.388303 533 | vn 0.093016 0.993960 0.058242 534 | vn 0.224216 0.955375 -0.192318 535 | vn 0.006734 0.968696 -0.248157 536 | vn 0.112680 0.759736 -0.640394 537 | vn -0.022398 0.742175 -0.669831 538 | vn -0.069708 0.918893 -0.388300 539 | vn -0.397997 0.905309 -0.148372 540 | vn -0.492293 0.870339 0.012560 541 | vn -0.685702 0.718115 -0.118839 542 | vn 0.670459 0.730281 -0.131047 543 | vn 0.331969 0.942060 0.048160 544 | vn 0.551095 0.761113 -0.342053 545 | vn 0.662676 0.714613 0.224028 546 | vn 0.029927 0.985892 -0.164685 547 | vn -0.231279 0.904003 0.359568 548 | vn 0.025454 0.764632 0.643965 549 | vn -0.430981 0.531992 0.728862 550 | vn 0.294047 0.673013 0.678667 551 | vn 0.311653 0.699337 0.643272 552 | vn 0.344646 -0.833819 0.431237 553 | vn -0.535190 -0.588850 0.605662 554 | vn -0.397419 -0.665963 0.631310 555 | vn -0.266161 -0.779223 0.567424 556 | vn -0.580156 -0.681973 0.445344 557 | vn 0.082621 -0.845573 0.527427 558 | vn 0.193732 -0.853584 0.483593 559 | vn 0.031358 -0.916580 0.398620 560 | vn 0.216690 -0.935620 0.278676 561 | vn -0.406236 -0.829485 0.383311 562 | vn -0.424578 -0.873378 0.238633 563 | vn -0.636528 -0.657764 -0.402714 564 | vn -0.592546 -0.805536 -0.000662 565 | vn -0.738390 -0.404725 -0.539424 566 | vn -0.837982 -0.030694 -0.544834 567 | vn -0.609724 -0.452036 -0.651076 568 | vn -0.557696 -0.565959 -0.607178 569 | vn -0.598907 -0.435495 -0.672052 570 | vn -0.523109 -0.531523 -0.666213 571 | vn -0.448606 -0.637670 -0.626203 572 | vn -0.624455 -0.598753 -0.501548 573 | vn -0.472554 -0.655559 -0.589012 574 | vn -0.345084 -0.436384 -0.830955 575 | vn -0.398522 0.551031 -0.733175 576 | vn 0.281665 0.798261 -0.532394 577 | vn -0.030030 0.996636 -0.076260 578 | vn 0.025662 0.786431 -0.617145 579 | vn -0.146061 0.658765 -0.738034 580 | vn -0.504330 0.750166 -0.427670 581 | vn -0.563369 0.506109 -0.653046 582 | vn -0.583667 0.464801 -0.665802 583 | vn -0.492679 0.235053 -0.837865 584 | vn -0.590139 0.539332 -0.600714 585 | vn -0.742465 0.638690 -0.202042 586 | vn -0.457546 0.137562 -0.878481 587 | vn -0.374966 -0.011787 -0.926963 588 | vn -0.389077 0.271200 -0.880381 589 | vn -0.140438 -0.198437 -0.970000 590 | vn -0.078481 -0.078961 -0.993784 591 | vn -0.234827 -0.050793 -0.970709 592 | vn -0.290046 0.034437 -0.956393 593 | vn -0.190181 -0.006657 -0.981726 594 | vn -0.053336 0.003591 -0.998570 595 | vn -0.212612 -0.001992 -0.977135 596 | vn -0.630229 0.677710 0.378840 597 | vn -0.686017 0.506878 0.521972 598 | vn -0.859297 0.402904 0.315084 599 | vn -0.555257 0.831029 0.032874 600 | vn -0.719516 0.329578 0.611290 601 | vn -0.729677 0.144822 0.668280 602 | vn -0.594382 0.621980 0.509756 603 | vn -0.739568 0.516143 0.432013 604 | vn -0.596739 0.717768 0.358764 605 | vn -0.665573 0.658364 0.351524 606 | vn -0.697223 0.438052 0.567442 607 | vn -0.707414 0.392260 0.587960 608 | vn -0.394090 -0.654229 0.645506 609 | vn -0.223253 -0.935808 0.272801 610 | vn -0.567625 -0.711374 0.414427 611 | vn -0.200034 -0.958135 0.204852 612 | vn -0.323401 -0.849415 0.417020 613 | vn -0.282339 -0.838836 0.465445 614 | vn -0.306379 -0.645819 0.699321 615 | vn -0.380993 -0.657358 0.650173 616 | vn -0.283848 -0.516290 0.808007 617 | vn -0.453717 -0.668936 0.588783 618 | vn -0.736156 -0.588346 0.334549 619 | vn -0.549474 0.376922 0.745660 620 | vn -0.004088 0.070899 0.997475 621 | vn 0.397740 -0.153582 0.904553 622 | vn -0.246790 0.088934 0.964979 623 | vn 0.271119 -0.002322 0.962543 624 | vn -0.571539 0.114476 0.812551 625 | vn -0.325057 -0.005263 0.945680 626 | vn 0.054339 -0.463570 0.884393 627 | vn 0.356565 -0.382794 0.852250 628 | vn 0.305999 -0.185138 0.933857 629 | vn -0.912520 0.332791 -0.237818 630 | vn -0.562044 0.812533 0.154583 631 | vn -0.833291 0.537186 0.130603 632 | vn -0.853594 0.498860 0.150051 633 | vn -0.859326 0.483502 0.166686 634 | vn -0.926617 0.319522 0.198210 635 | vn -0.937125 0.243290 0.250213 636 | vn -0.968067 0.026744 0.249262 637 | vn -0.902659 0.368956 0.221534 638 | vn -0.995432 0.056919 0.076653 639 | vn -0.610732 -0.790255 -0.050040 640 | vn -0.851693 -0.518166 -0.078252 641 | vn -0.776231 -0.575934 -0.256449 642 | vn -0.981039 -0.184145 0.060440 643 | vn -0.989416 -0.020700 0.143621 644 | vn -0.887990 -0.446736 -0.109096 645 | vn -0.754921 -0.570616 -0.323250 646 | vn 0.615734 0.482039 0.623306 647 | vn 0.865810 0.092421 0.491763 648 | vn 0.392059 0.887237 0.243103 649 | vn 0.203607 0.978721 0.025477 650 | vn 0.419829 0.727014 0.543318 651 | vn 0.517456 0.736269 0.436058 652 | vn 0.237295 0.652682 0.719512 653 | vn 0.249701 0.467310 0.848098 654 | vn 0.413760 0.412558 0.811541 655 | vn 0.300128 0.388348 0.871269 656 | vn 0.537365 0.613614 0.578548 657 | vn 0.760835 0.647474 0.043682 658 | vn 0.224312 -0.465195 0.856317 659 | vn 0.880347 -0.374455 0.291157 660 | vn 0.868079 -0.180106 0.462603 661 | vn 0.626726 -0.421812 0.655202 662 | vn 0.919715 -0.311501 0.238937 663 | vn 0.290759 -0.494918 0.818850 664 | vn 0.170836 -0.309140 0.935547 665 | vn 0.242882 -0.782983 0.572666 666 | vn 0.273183 -0.949228 0.156007 667 | vn 0.700442 -0.702266 0.127294 668 | vn 0.698737 -0.460621 0.547353 669 | vn 0.368842 0.153914 0.916660 670 | vn 0.599391 0.059194 0.798265 671 | vn 0.303246 0.247869 0.920110 672 | vn 0.187128 -0.045064 0.981301 673 | vn 0.200577 0.381236 0.902456 674 | vn 0.089682 0.165829 0.982068 675 | vn 0.078491 -0.164425 0.983262 676 | vn 0.080121 -0.185180 0.979433 677 | vn 0.138994 -0.978949 -0.149464 678 | vn 0.228891 -0.536606 -0.812196 679 | vn 0.403927 -0.844691 -0.351199 680 | vn 0.484919 -0.873907 -0.033752 681 | vn 0.094440 -0.830036 -0.549655 682 | vn 0.585570 -0.744412 -0.320871 683 | vn 0.018176 -0.925743 -0.377716 684 | vn 0.492027 -0.574780 -0.653863 685 | vn 0.633494 0.144272 -0.760178 686 | vn 0.699116 0.009421 -0.714946 687 | vn 0.785157 -0.250569 -0.566343 688 | vn 0.773828 -0.577732 -0.259647 689 | vn 0.641147 0.691105 0.333623 690 | vn 0.283510 0.837178 0.467713 691 | vn 0.043472 0.680571 -0.731391 692 | vn 0.244118 0.289315 -0.925583 693 | vn -0.065332 0.693850 -0.717150 694 | vn 0.107571 0.463688 -0.879444 695 | vn 0.387819 0.763116 -0.516962 696 | vn 0.809883 0.531802 -0.247540 697 | vn 0.880963 0.353962 -0.314032 698 | vn 0.889706 0.419471 -0.180188 699 | vn 0.636810 0.282060 -0.717575 700 | vn 0.364083 0.327160 -0.872015 701 | vn 0.101438 0.138521 -0.985151 702 | vn -0.076048 -0.019641 -0.996911 703 | vn -0.329682 -0.155569 -0.931187 704 | vn 0.293860 -0.252106 -0.922003 705 | vn -0.223900 0.230669 -0.946922 706 | vn 0.187674 0.443187 -0.876564 707 | vn 0.603440 -0.039629 -0.796423 708 | vn 0.723406 -0.300771 -0.621466 709 | vn 0.985292 -0.115077 -0.126317 710 | vn 0.611764 0.790839 -0.017845 711 | vn 0.880526 0.453684 -0.137275 712 | vn 0.903121 0.418936 -0.094148 713 | vn 0.914499 0.201089 -0.351076 714 | vn 0.971785 0.078410 -0.222454 715 | vn 0.935844 0.350493 -0.036745 716 | vn 0.981240 0.186276 0.049693 717 | vn 0.904869 0.404541 -0.132512 718 | vn 0.986664 -0.063602 0.149829 719 | vn 0.531747 -0.787227 0.312278 720 | vn 0.716584 -0.695791 0.048807 721 | vn 0.534796 -0.675406 0.507759 722 | vn 0.944943 -0.283302 -0.163773 723 | vn 0.998114 0.054853 -0.027557 724 | vn 0.876766 -0.156125 0.454869 725 | vn 0.550156 -0.401357 0.732285 726 | f 94//94 68//68 95//95 727 | f 98//98 96//96 67//67 728 | f 100//100 58//58 101//101 729 | f 96//96 101//101 102//102 730 | f 103//103 99//99 1//1 731 | f 106//106 48//48 107//107 732 | f 109//109 46//46 110//110 733 | f 112//112 49//49 113//113 734 | f 115//115 38//38 116//116 735 | f 118//118 37//37 119//119 736 | f 120//120 107//107 48//48 737 | f 123//123 29//29 124//124 738 | f 126//126 31//31 127//127 739 | f 129//129 22//22 130//130 740 | f 132//132 21//21 133//133 741 | f 134//134 114//114 4//4 742 | f 137//137 45//45 138//138 743 | f 139//139 125//125 6//6 744 | f 142//142 55//55 143//143 745 | f 145//145 17//17 146//146 746 | f 149//149 147//147 9//9 747 | f 152//152 150//150 10//10 748 | f 153//153 150//150 16//16 749 | f 156//156 153//153 16//16 750 | f 157//157 147//147 18//18 751 | f 159//159 157//157 18//18 752 | f 160//160 154//154 73//73 753 | f 145//145 160//160 158//158 754 | f 164//164 162//162 11//11 755 | f 167//167 165//165 12//12 756 | f 168//168 165//165 14//14 757 | f 171//171 168//168 14//14 758 | f 164//164 56//56 172//172 759 | f 174//174 172//172 56//56 760 | f 175//175 169//169 74//74 761 | f 142//142 175//175 173//173 762 | f 178//178 167//167 12//12 763 | f 179//179 163//163 13//13 764 | f 181//181 179//179 13//13 765 | f 183//183 171//171 14//14 766 | f 184//184 177//177 26//26 767 | f 186//186 184//184 26//26 768 | f 187//187 182//182 75//75 769 | f 140//140 187//187 185//185 770 | f 189//189 110//110 46//46 771 | f 190//190 148//148 15//15 772 | f 192//192 190//190 15//15 773 | f 194//194 156//156 16//16 774 | f 195//195 189//189 46//46 775 | f 197//197 195//195 46//46 776 | f 198//198 193//193 76//76 777 | f 137//137 198//198 196//196 778 | f 201//201 149//149 9//9 779 | f 202//202 146//146 17//17 780 | f 204//204 202//202 17//17 781 | f 206//206 159//159 18//18 782 | f 207//207 200//200 42//42 783 | f 209//209 207//207 42//42 784 | f 210//210 205//205 77//77 785 | f 135//135 210//210 208//208 786 | f 212//212 130//130 22//22 787 | f 19//19 214//214 166//166 788 | f 215//215 213//213 19//19 789 | f 217//217 176//176 20//20 790 | f 218//218 212//212 22//22 791 | f 220//220 218//218 22//22 792 | f 78//78 222//222 216//216 793 | f 132//132 221//221 219//219 794 | f 223//223 133//133 21//21 795 | f 23//23 225//225 203//203 796 | f 226//226 224//224 23//23 797 | f 228//228 211//211 24//24 798 | f 229//229 223//223 21//21 799 | f 230//230 220//220 22//22 800 | f 231//231 227//227 79//79 801 | f 129//129 231//231 230//230 802 | f 234//234 117//117 3//3 803 | f 236//236 178//178 12//12 804 | f 237//237 235//235 36//36 805 | f 240//240 237//237 36//36 806 | f 241//241 233//233 32//32 807 | f 243//243 241//241 32//32 808 | f 186//186 238//238 244//244 809 | f 126//126 244//244 242//242 810 | f 245//245 121//121 30//30 811 | f 246//246 191//191 27//27 812 | f 248//248 246//246 27//27 813 | f 250//250 199//199 28//28 814 | f 251//251 245//245 30//30 815 | f 253//253 251//251 30//30 816 | f 254//254 249//249 81//81 817 | f 123//123 254//254 252//252 818 | f 256//256 124//124 29//29 819 | f 257//257 127//127 31//31 820 | f 259//259 257//257 31//31 821 | f 261//261 243//243 32//32 822 | f 262//262 256//256 29//29 823 | f 30//30 262//262 253//253 824 | f 264//264 260//260 82//82 825 | f 120//120 264//264 263//263 826 | f 266//266 116//116 38//38 827 | f 267//267 214//214 33//33 828 | f 268//268 267//267 33//33 829 | f 270//270 222//222 34//34 830 | f 271//271 266//266 38//38 831 | f 273//273 271//271 38//38 832 | f 240//240 269//269 274//274 833 | f 118//118 274//274 272//272 834 | f 37//37 122//122 119//119 835 | f 201//201 246//246 276//276 836 | f 277//277 276//276 39//39 837 | f 279//279 255//255 40//40 838 | f 280//280 275//275 37//37 839 | f 281//281 273//273 38//38 840 | f 209//209 278//278 282//282 841 | f 115//115 282//282 281//281 842 | f 284//284 139//139 6//6 843 | f 285//285 180//180 43//43 844 | f 287//287 285//285 43//43 845 | f 289//289 188//188 44//44 846 | f 290//290 283//283 50//50 847 | f 292//292 290//290 310//310 848 | f 293//293 288//288 85//85 849 | f 112//112 293//293 291//291 850 | f 105//105 138//138 45//45 851 | f 2//2 296//296 93//93 852 | f 298//298 296//296 52//52 853 | f 301//301 298//298 52//52 854 | f 302//302 295//295 45//45 855 | f 303//303 197//197 46//46 856 | f 304//304 299//299 86//86 857 | f 109//109 304//304 303//303 858 | f 306//306 258//258 47//47 859 | f 307//307 113//113 49//49 860 | f 308//308 307//307 49//49 861 | f 290//290 50//50 310//310 862 | f 311//311 306//306 47//47 863 | f 312//312 265//265 48//48 864 | f 301//301 309//309 313//313 865 | f 106//106 313//313 312//312 866 | f 315//315 144//144 8//8 867 | f 316//316 151//151 53//53 868 | f 318//318 316//316 53//53 869 | f 54//54 318//318 161//161 870 | f 321//321 314//314 62//62 871 | f 323//323 321//321 62//62 872 | f 324//324 319//319 88//88 873 | f 104//104 324//324 322//322 874 | f 327//327 164//164 11//11 875 | f 328//328 143//143 55//55 876 | f 330//330 328//328 55//55 877 | f 332//332 174//174 56//56 878 | f 333//333 326//326 66//66 879 | f 335//335 333//333 66//66 880 | f 336//336 331//331 89//89 881 | f 102//102 336//336 334//334 882 | f 128//128 329//329 338//338 883 | f 339//339 225//225 59//59 884 | f 340//340 339//339 59//59 885 | f 342//342 232//232 60//60 886 | f 343//343 338//338 57//57 887 | f 344//344 337//337 58//58 888 | f 323//323 341//341 345//345 889 | f 100//100 345//345 344//344 890 | f 68//68 111//111 95//95 891 | f 347//347 286//286 63//63 892 | f 348//348 347//347 63//63 893 | f 350//350 294//294 64//64 894 | f 351//351 346//346 68//68 895 | f 353//353 351//351 68//68 896 | f 335//335 349//349 354//354 897 | f 97//97 354//354 352//352 898 | f 355//355 98//98 67//67 899 | f 108//108 317//317 356//356 900 | f 357//357 356//356 69//69 901 | f 359//359 325//325 70//70 902 | f 360//360 355//355 67//67 903 | f 361//361 353//353 68//68 904 | f 305//305 358//358 92//92 905 | f 361//361 71//71 362//362 906 | f 94//94 93//93 71//71 907 | f 297//297 52//52 296//296 908 | f 95//95 93//93 94//94 909 | f 94//94 361//361 68//68 910 | f 95//95 2//2 93//93 911 | f 95//95 111//111 2//2 912 | f 97//97 96//96 65//65 913 | f 101//101 58//58 102//102 914 | f 97//97 67//67 96//96 915 | f 97//97 352//352 67//67 916 | f 98//98 1//1 96//96 917 | f 1//1 355//355 103//103 918 | f 100//100 99//99 61//61 919 | f 103//103 70//70 104//104 920 | f 101//101 99//99 100//100 921 | f 100//100 344//344 58//58 922 | f 101//101 1//1 99//99 923 | f 101//101 96//96 1//1 924 | f 102//102 65//65 96//96 925 | f 102//102 334//334 65//65 926 | f 104//104 99//99 103//103 927 | f 355//355 70//70 103//103 928 | f 104//104 61//61 99//99 929 | f 104//104 322//322 61//61 930 | f 106//106 105//105 51//51 931 | f 295//295 105//105 45//45 932 | f 107//107 105//105 106//106 933 | f 106//106 312//312 48//48 934 | f 107//107 5//5 105//105 935 | f 120//120 30//30 121//121 936 | f 109//109 108//108 72//72 937 | f 317//317 69//69 356//356 938 | f 110//110 108//108 109//109 939 | f 109//109 303//303 46//46 940 | f 110//110 10//10 108//108 941 | f 110//110 152//152 10//10 942 | f 112//112 111//111 64//64 943 | f 346//346 64//64 111//111 944 | f 112//112 2//2 111//111 945 | f 112//112 291//291 49//49 946 | f 113//113 2//2 112//112 947 | f 113//113 297//297 2//2 948 | f 115//115 114//114 41//41 949 | f 134//134 24//24 135//135 950 | f 115//115 4//4 114//114 951 | f 115//115 281//281 38//38 952 | f 116//116 4//4 115//115 953 | f 116//116 131//131 4//4 954 | f 118//118 117//117 35//35 955 | f 234//234 32//32 233//233 956 | f 118//118 3//3 117//117 957 | f 118//118 272//272 37//37 958 | f 119//119 3//3 118//118 959 | f 119//119 122//122 3//3 960 | f 121//121 107//107 120//120 961 | f 120//120 263//263 30//30 962 | f 121//121 5//5 107//107 963 | f 5//5 245//245 136//136 964 | f 123//123 122//122 40//40 965 | f 275//275 40//40 122//122 966 | f 124//124 122//122 123//123 967 | f 123//123 252//252 29//29 968 | f 124//124 3//3 122//122 969 | f 124//124 234//234 3//3 970 | f 126//126 125//125 25//25 971 | f 139//139 44//44 140//140 972 | f 127//127 125//125 126//126 973 | f 126//126 242//242 31//31 974 | f 127//127 6//6 125//125 975 | f 257//257 47//47 258//258 976 | f 129//129 128//128 60//60 977 | f 329//329 57//57 338//338 978 | f 130//130 128//128 129//129 979 | f 129//129 230//230 22//22 980 | f 130//130 7//7 128//128 981 | f 130//130 141//141 7//7 982 | f 132//132 131//131 34//34 983 | f 266//266 34//34 131//131 984 | f 133//133 131//131 132//132 985 | f 132//132 219//219 21//21 986 | f 133//133 4//4 131//131 987 | f 133//133 134//134 4//4 988 | f 135//135 114//114 134//134 989 | f 134//134 133//133 24//24 990 | f 135//135 41//41 114//114 991 | f 135//135 208//208 41//41 992 | f 137//137 136//136 28//28 993 | f 245//245 28//28 136//136 994 | f 138//138 136//136 137//137 995 | f 137//137 196//196 45//45 996 | f 138//138 5//5 136//136 997 | f 138//138 105//105 5//5 998 | f 140//140 125//125 139//139 999 | f 284//284 50//50 283//283 1000 | f 140//140 25//25 125//125 1001 | f 140//140 185//185 25//25 1002 | f 142//142 141//141 20//20 1003 | f 212//212 20//20 141//141 1004 | f 143//143 141//141 142//142 1005 | f 142//142 173//173 55//55 1006 | f 143//143 7//7 141//141 1007 | f 328//328 57//57 329//329 1008 | f 145//145 144//144 54//54 1009 | f 315//315 62//62 314//314 1010 | f 146//146 144//144 145//145 1011 | f 145//145 158//158 17//17 1012 | f 146//146 8//8 144//144 1013 | f 203//203 146//146 23//23 1014 | f 148//148 147//147 15//15 1015 | f 147//147 155//155 15//15 1016 | f 148//148 9//9 147//147 1017 | f 190//190 27//27 191//191 1018 | f 149//149 18//18 147//147 1019 | f 201//201 42//42 200//200 1020 | f 151//151 150//150 53//53 1021 | f 153//153 73//73 154//154 1022 | f 151//151 10//10 150//150 1023 | f 316//316 69//69 317//317 1024 | f 152//152 16//16 150//150 1025 | f 189//189 16//16 152//152 1026 | f 154//154 150//150 153//153 1027 | f 156//156 15//15 155//155 1028 | f 154//154 53//53 150//150 1029 | f 160//160 54//54 161//161 1030 | f 155//155 73//73 153//153 1031 | f 157//157 73//73 155//155 1032 | f 155//155 153//153 156//156 1033 | f 156//156 192//192 15//15 1034 | f 155//155 147//147 157//157 1035 | f 159//159 17//17 158//158 1036 | f 158//158 73//73 157//157 1037 | f 160//160 73//73 158//158 1038 | f 158//158 157//157 159//159 1039 | f 159//159 204//204 17//17 1040 | f 161//161 154//154 160//160 1041 | f 160//160 145//145 54//54 1042 | f 161//161 53//53 154//154 1043 | f 161//161 318//318 53//53 1044 | f 170//170 13//13 163//163 1045 | f 162//162 170//170 163//163 1046 | f 163//163 11//11 162//162 1047 | f 179//179 43//43 180//180 1048 | f 172//172 162//162 164//164 1049 | f 327//327 66//66 326//326 1050 | f 19//19 12//12 165//165 1051 | f 168//168 74//74 169//169 1052 | f 166//166 12//12 19//19 1053 | f 213//213 33//33 214//214 1054 | f 167//167 14//14 165//165 1055 | f 178//178 26//26 177//177 1056 | f 169//169 165//165 168//168 1057 | f 171//171 13//13 170//170 1058 | f 169//169 19//19 165//165 1059 | f 175//175 20//20 176//176 1060 | f 170//170 74//74 168//168 1061 | f 172//172 74//74 170//170 1062 | f 170//170 168//168 171//171 1063 | f 13//13 183//183 181//181 1064 | f 170//170 162//162 172//172 1065 | f 174//174 55//55 173//173 1066 | f 173//173 74//74 172//172 1067 | f 175//175 74//74 173//173 1068 | f 173//173 172//172 174//174 1069 | f 174//174 330//330 55//55 1070 | f 176//176 169//169 175//175 1071 | f 175//175 142//142 20//20 1072 | f 176//176 19//19 169//169 1073 | f 176//176 215//215 19//19 1074 | f 177//177 14//14 167//167 1075 | f 177//177 183//183 14//14 1076 | f 177//177 167//167 178//178 1077 | f 235//235 178//178 36//36 1078 | f 180//180 163//163 179//179 1079 | f 182//182 179//179 75//75 1080 | f 180//180 11//11 163//163 1081 | f 285//285 63//63 286//286 1082 | f 181//181 75//75 179//179 1083 | f 183//183 75//75 181//181 1084 | f 182//182 43//43 179//179 1085 | f 187//187 44//44 188//188 1086 | f 183//183 13//13 171//171 1087 | f 184//184 75//75 183//183 1088 | f 183//183 177//177 184//184 1089 | f 186//186 25//25 185//185 1090 | f 185//185 75//75 184//184 1091 | f 187//187 75//75 185//185 1092 | f 185//185 184//184 186//186 1093 | f 238//238 80//80 244//244 1094 | f 187//187 43//43 182//182 1095 | f 187//187 140//140 44//44 1096 | f 188//188 43//43 187//187 1097 | f 188//188 287//287 43//43 1098 | f 152//152 110//110 189//189 1099 | f 16//16 195//195 194//194 1100 | f 191//191 148//148 190//190 1101 | f 192//192 76//76 193//193 1102 | f 191//191 9//9 148//148 1103 | f 247//247 191//191 201//201 1104 | f 193//193 190//190 192//192 1105 | f 194//194 76//76 192//192 1106 | f 193//193 27//27 190//190 1107 | f 198//198 28//28 199//199 1108 | f 192//192 156//156 194//194 1109 | f 195//195 76//76 194//194 1110 | f 195//195 16//16 189//189 1111 | f 197//197 45//45 196//196 1112 | f 196//196 76//76 195//195 1113 | f 198//198 76//76 196//196 1114 | f 196//196 195//195 197//197 1115 | f 197//197 302//302 45//45 1116 | f 199//199 193//193 198//198 1117 | f 198//198 137//137 28//28 1118 | f 199//199 27//27 193//193 1119 | f 199//199 248//248 27//27 1120 | f 200//200 18//18 149//149 1121 | f 200//200 206//206 18//18 1122 | f 200//200 149//149 201//201 1123 | f 246//246 39//39 276//276 1124 | f 202//202 23//23 146//146 1125 | f 204//204 77//77 205//205 1126 | f 203//203 8//8 146//146 1127 | f 224//224 59//59 225//225 1128 | f 205//205 202//202 204//204 1129 | f 206//206 77//77 204//204 1130 | f 205//205 23//23 202//202 1131 | f 210//210 24//24 211//211 1132 | f 204//204 159//159 206//206 1133 | f 207//207 77//77 206//206 1134 | f 206//206 200//200 207//207 1135 | f 209//209 41//41 208//208 1136 | f 208//208 77//77 207//207 1137 | f 210//210 77//77 208//208 1138 | f 208//208 207//207 209//209 1139 | f 278//278 84//84 282//282 1140 | f 211//211 205//205 210//210 1141 | f 210//210 135//135 24//24 1142 | f 211//211 23//23 205//205 1143 | f 211//211 226//226 23//23 1144 | f 141//141 130//130 212//212 1145 | f 212//212 217//217 20//20 1146 | f 19//19 213//213 214//214 1147 | f 215//215 78//78 216//216 1148 | f 214//214 12//12 166//166 1149 | f 12//12 267//267 236//236 1150 | f 215//215 33//33 213//213 1151 | f 217//217 78//78 215//215 1152 | f 216//216 33//33 215//215 1153 | f 221//221 34//34 222//222 1154 | f 215//215 176//176 217//217 1155 | f 218//218 78//78 217//217 1156 | f 217//217 212//212 218//218 1157 | f 220//220 21//21 219//219 1158 | f 219//219 78//78 218//218 1159 | f 221//221 78//78 219//219 1160 | f 219//219 218//218 220//220 1161 | f 220//220 229//229 21//21 1162 | f 78//78 221//221 222//222 1163 | f 221//221 132//132 34//34 1164 | f 222//222 33//33 216//216 1165 | f 222//222 268//268 33//33 1166 | f 223//223 24//24 133//133 1167 | f 223//223 228//228 24//24 1168 | f 23//23 224//224 225//225 1169 | f 226//226 79//79 227//227 1170 | f 225//225 8//8 203//203 1171 | f 225//225 315//315 8//8 1172 | f 227//227 224//224 226//226 1173 | f 226//226 211//211 79//79 1174 | f 227//227 59//59 224//224 1175 | f 231//231 60//60 232//232 1176 | f 228//228 79//79 211//211 1177 | f 229//229 79//79 228//228 1178 | f 228//228 223//223 229//229 1179 | f 230//230 79//79 229//229 1180 | f 229//229 220//220 230//230 1181 | f 231//231 79//79 230//230 1182 | f 232//232 227//227 231//231 1183 | f 231//231 129//129 60//60 1184 | f 232//232 59//59 227//227 1185 | f 232//232 340//340 59//59 1186 | f 233//233 35//35 117//117 1187 | f 233//233 239//239 35//35 1188 | f 233//233 117//117 234//234 1189 | f 256//256 32//32 234//234 1190 | f 235//235 26//26 178//178 1191 | f 237//237 80//80 238//238 1192 | f 236//236 36//36 178//178 1193 | f 267//267 36//36 236//236 1194 | f 238//238 235//235 237//237 1195 | f 240//240 35//35 239//239 1196 | f 238//238 26//26 235//235 1197 | f 238//238 186//186 26//26 1198 | f 239//239 80//80 237//237 1199 | f 241//241 80//80 239//239 1200 | f 239//239 237//237 240//240 1201 | f 269//269 83//83 274//274 1202 | f 239//239 233//233 241//241 1203 | f 243//243 31//31 242//242 1204 | f 242//242 80//80 241//241 1205 | f 244//244 80//80 242//242 1206 | f 242//242 241//241 243//243 1207 | f 31//31 261//261 259//259 1208 | f 244//244 25//25 186//186 1209 | f 244//244 126//126 25//25 1210 | f 245//245 5//5 121//121 1211 | f 245//245 250//250 28//28 1212 | f 201//201 191//191 246//246 1213 | f 248//248 81//81 249//249 1214 | f 247//247 9//9 191//191 1215 | f 247//247 201//201 9//9 1216 | f 249//249 246//246 248//248 1217 | f 250//250 81//81 248//248 1218 | f 249//249 39//39 246//246 1219 | f 254//254 40//40 255//255 1220 | f 248//248 199//199 250//250 1221 | f 251//251 81//81 250//250 1222 | f 250//250 245//245 251//251 1223 | f 253//253 29//29 252//252 1224 | f 252//252 81//81 251//251 1225 | f 254//254 81//81 252//252 1226 | f 252//252 251//251 253//253 1227 | f 253//253 262//262 29//29 1228 | f 255//255 249//249 254//254 1229 | f 254//254 123//123 40//40 1230 | f 255//255 39//39 249//249 1231 | f 255//255 277//277 39//39 1232 | f 234//234 124//124 256//256 1233 | f 256//256 261//261 32//32 1234 | f 258//258 127//127 257//257 1235 | f 259//259 82//82 260//260 1236 | f 258//258 6//6 127//127 1237 | f 258//258 284//284 6//6 1238 | f 260//260 257//257 259//259 1239 | f 261//261 82//82 259//259 1240 | f 260//260 47//47 257//257 1241 | f 264//264 48//48 265//265 1242 | f 261//261 31//31 243//243 1243 | f 262//262 82//82 261//261 1244 | f 261//261 256//256 262//262 1245 | f 263//263 82//82 262//262 1246 | f 30//30 263//263 262//262 1247 | f 264//264 82//82 263//263 1248 | f 265//265 260//260 264//264 1249 | f 264//264 120//120 48//48 1250 | f 265//265 47//47 260//260 1251 | f 47//47 312//312 311//311 1252 | f 131//131 116//116 266//266 1253 | f 266//266 270//270 34//34 1254 | f 267//267 12//12 214//214 1255 | f 268//268 83//83 269//269 1256 | f 268//268 36//36 267//267 1257 | f 270//270 83//83 268//268 1258 | f 269//269 36//36 268//268 1259 | f 269//269 240//240 36//36 1260 | f 268//268 222//222 270//270 1261 | f 271//271 83//83 270//270 1262 | f 270//270 266//266 271//271 1263 | f 273//273 37//37 272//272 1264 | f 272//272 83//83 271//271 1265 | f 274//274 83//83 272//272 1266 | f 272//272 271//271 273//273 1267 | f 273//273 280//280 37//37 1268 | f 274//274 35//35 240//240 1269 | f 274//274 118//118 35//35 1270 | f 37//37 275//275 122//122 1271 | f 275//275 279//279 40//40 1272 | f 276//276 42//42 201//201 1273 | f 277//277 84//84 278//278 1274 | f 278//278 276//276 277//277 1275 | f 279//279 84//84 277//277 1276 | f 278//278 42//42 276//276 1277 | f 278//278 209//209 42//42 1278 | f 277//277 255//255 279//279 1279 | f 280//280 84//84 279//279 1280 | f 279//279 275//275 280//280 1281 | f 280//280 273//273 84//84 1282 | f 281//281 84//84 273//273 1283 | f 282//282 84//84 281//281 1284 | f 282//282 41//41 209//209 1285 | f 282//282 115//115 41//41 1286 | f 283//283 44//44 139//139 1287 | f 283//283 289//289 44//44 1288 | f 283//283 139//139 284//284 1289 | f 284//284 258//258 50//50 1290 | f 286//286 180//180 285//285 1291 | f 287//287 85//85 288//288 1292 | f 286//286 11//11 180//180 1293 | f 286//286 327//327 11//11 1294 | f 288//288 285//285 287//287 1295 | f 289//289 85//85 287//287 1296 | f 288//288 63//63 285//285 1297 | f 293//293 64//64 294//294 1298 | f 287//287 188//188 289//289 1299 | f 290//290 85//85 289//289 1300 | f 289//289 283//283 290//290 1301 | f 291//291 308//308 49//49 1302 | f 291//291 85//85 290//290 1303 | f 293//293 85//85 291//291 1304 | f 291//291 290//290 292//292 1305 | f 292//292 308//308 291//291 1306 | f 294//294 288//288 293//293 1307 | f 293//293 112//112 64//64 1308 | f 294//294 63//63 288//288 1309 | f 294//294 348//348 63//63 1310 | f 295//295 51//51 105//105 1311 | f 295//295 300//300 51//51 1312 | f 296//296 71//71 93//93 1313 | f 298//298 86//86 299//299 1314 | f 2//2 297//297 296//296 1315 | f 307//307 52//52 297//297 1316 | f 299//299 296//296 298//298 1317 | f 300//300 298//298 51//51 1318 | f 299//299 71//71 296//296 1319 | f 304//304 72//72 305//305 1320 | f 300//300 86//86 298//298 1321 | f 302//302 86//86 300//300 1322 | f 301//301 51//51 298//298 1323 | f 309//309 87//87 313//313 1324 | f 300//300 295//295 302//302 1325 | f 303//303 86//86 302//302 1326 | f 302//302 197//197 303//303 1327 | f 304//304 86//86 303//303 1328 | f 305//305 299//299 304//304 1329 | f 304//304 109//109 72//72 1330 | f 305//305 71//71 299//299 1331 | f 362//362 305//305 92//92 1332 | f 306//306 50//50 258//258 1333 | f 306//306 310//310 50//50 1334 | f 297//297 113//113 307//307 1335 | f 308//308 87//87 309//309 1336 | f 309//309 307//307 308//308 1337 | f 308//308 292//292 87//87 1338 | f 309//309 52//52 307//307 1339 | f 309//309 301//301 52//52 1340 | f 310//310 87//87 292//292 1341 | f 311//311 87//87 310//310 1342 | f 310//310 306//306 311//311 1343 | f 312//312 87//87 311//311 1344 | f 312//312 47//47 265//265 1345 | f 313//313 87//87 312//312 1346 | f 313//313 51//51 301//301 1347 | f 313//313 106//106 51//51 1348 | f 314//314 54//54 144//144 1349 | f 314//314 320//320 54//54 1350 | f 314//314 144//144 315//315 1351 | f 339//339 62//62 315//315 1352 | f 317//317 151//151 316//316 1353 | f 318//318 88//88 319//319 1354 | f 317//317 10//10 151//151 1355 | f 317//317 108//108 10//10 1356 | f 319//319 316//316 318//318 1357 | f 320//320 88//88 318//318 1358 | f 319//319 69//69 316//316 1359 | f 324//324 70//70 325//325 1360 | f 54//54 320//320 318//318 1361 | f 321//321 88//88 320//320 1362 | f 320//320 314//314 321//321 1363 | f 323//323 61//61 322//322 1364 | f 322//322 88//88 321//321 1365 | f 324//324 88//88 322//322 1366 | f 322//322 321//321 323//323 1367 | f 341//341 90//90 345//345 1368 | f 325//325 319//319 324//324 1369 | f 324//324 104//104 70//70 1370 | f 325//325 69//69 319//319 1371 | f 325//325 357//357 69//69 1372 | f 326//326 56//56 164//164 1373 | f 326//326 332//332 56//56 1374 | f 326//326 164//164 327//327 1375 | f 347//347 66//66 327//327 1376 | f 329//329 143//143 328//328 1377 | f 330//330 89//89 331//331 1378 | f 329//329 7//7 143//143 1379 | f 329//329 128//128 7//7 1380 | f 331//331 328//328 330//330 1381 | f 332//332 89//89 330//330 1382 | f 331//331 57//57 328//328 1383 | f 336//336 58//58 337//337 1384 | f 330//330 174//174 332//332 1385 | f 333//333 89//89 332//332 1386 | f 332//332 326//326 333//333 1387 | f 335//335 65//65 334//334 1388 | f 334//334 89//89 333//333 1389 | f 336//336 89//89 334//334 1390 | f 334//334 333//333 335//335 1391 | f 349//349 91//91 354//354 1392 | f 337//337 331//331 336//336 1393 | f 336//336 102//102 58//58 1394 | f 337//337 57//57 331//331 1395 | f 337//337 343//343 57//57 1396 | f 338//338 60//60 128//128 1397 | f 338//338 342//342 60//60 1398 | f 315//315 225//225 339//339 1399 | f 340//340 90//90 341//341 1400 | f 341//341 339//339 340//340 1401 | f 342//342 90//90 340//340 1402 | f 341//341 62//62 339//339 1403 | f 341//341 323//323 62//62 1404 | f 340//340 232//232 342//342 1405 | f 343//343 90//90 342//342 1406 | f 342//342 338//338 343//343 1407 | f 344//344 90//90 343//343 1408 | f 343//343 337//337 344//344 1409 | f 345//345 90//90 344//344 1410 | f 345//345 61//61 323//323 1411 | f 345//345 100//100 61//61 1412 | f 68//68 346//346 111//111 1413 | f 64//64 351//351 350//350 1414 | f 327//327 286//286 347//347 1415 | f 348//348 91//91 349//349 1416 | f 349//349 347//347 348//348 1417 | f 348//348 294//294 91//91 1418 | f 349//349 66//66 347//347 1419 | f 349//349 335//335 66//66 1420 | f 350//350 91//91 294//294 1421 | f 351//351 91//91 350//350 1422 | f 351//351 64//64 346//346 1423 | f 353//353 67//67 352//352 1424 | f 352//352 91//91 351//351 1425 | f 354//354 91//91 352//352 1426 | f 352//352 351//351 353//353 1427 | f 353//353 360//360 67//67 1428 | f 354//354 65//65 335//335 1429 | f 354//354 97//97 65//65 1430 | f 355//355 1//1 98//98 1431 | f 355//355 359//359 70//70 1432 | f 356//356 72//72 108//108 1433 | f 357//357 92//92 358//358 1434 | f 358//358 356//356 357//357 1435 | f 359//359 92//92 357//357 1436 | f 358//358 72//72 356//356 1437 | f 358//358 305//305 72//72 1438 | f 357//357 325//325 359//359 1439 | f 360//360 92//92 359//359 1440 | f 359//359 355//355 360//360 1441 | f 361//361 92//92 360//360 1442 | f 360//360 353//353 361//361 1443 | f 362//362 92//92 361//361 1444 | f 362//362 71//71 305//305 1445 | f 71//71 361//361 94//94 1446 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import numpy 4 | from setuptools import setup, find_packages 5 | from Cython.Build import cythonize 6 | 7 | def find_pyx(path='.'): 8 | pyx_files = [] 9 | for root, dirs, filenames in os.walk(path): 10 | for fname in filenames: 11 | if fname.endswith('.pyx'): 12 | pyx_files.append(os.path.join(root, fname)) 13 | return pyx_files 14 | 15 | print(find_packages()) 16 | 17 | setup( 18 | name = "cymesh", 19 | version = '1.0.0', 20 | author = 'joelsimon.net', 21 | author_email='joelsimon6@gmail.com', 22 | install_requires = ['numpy', 'cython'], 23 | license = 'MIT', 24 | include_dirs = [numpy.get_include()], 25 | 26 | packages = find_packages(), 27 | ext_modules = cythonize( 28 | find_pyx(), 29 | include_path = [numpy.get_include()], 30 | ), 31 | include_package_data = True, 32 | package_data = { 33 | 'cymesh': ['*.pxd'], 34 | }, 35 | ) 36 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joel-simon/cymesh/8efd9e9f166f75b5a3f2b4b15c1fe8ce461e0107/test/__init__.py -------------------------------------------------------------------------------- /test/mesh_with_intersections.obj: -------------------------------------------------------------------------------- 1 | # Created by cymesh. 2 | v 0.720050 0.050100 -0.472693 3 | v 0.635749 0.006790 0.347067 4 | v -0.595538 0.022320 0.354128 5 | v -0.655141 0.074348 -0.520961 6 | v -0.036387 -0.296520 0.764902 7 | v 0.079212 0.391938 0.771751 8 | v 0.054176 0.428488 -0.629080 9 | v 0.023105 -0.429707 -0.613590 10 | v -0.415493 -0.731495 -0.138813 11 | v 0.485419 -0.715324 -0.027345 12 | v 0.545949 0.761257 0.070554 13 | v -0.488385 0.763617 -0.097416 14 | v 0.207975 0.870678 -0.030273 15 | v -0.140188 0.758718 -0.096000 16 | v -0.158503 -0.708679 -0.116916 17 | v 0.237262 -0.873151 0.016535 18 | v -0.239222 -0.660560 -0.481406 19 | v -0.195369 -0.608491 -0.298551 20 | v -0.220699 0.788435 -0.288797 21 | v -0.053696 0.660561 -0.418482 22 | v -0.577152 0.045184 -0.618452 23 | v -0.161420 0.217922 -0.769203 24 | v -0.172174 -0.255268 -0.651449 25 | v -0.503827 -0.250550 -0.613223 26 | v -0.096086 0.553902 0.422465 27 | v -0.184771 0.683146 0.189606 28 | v -0.391637 -0.755155 0.320844 29 | v -0.196948 -0.488112 0.520620 30 | v -0.516699 -0.191641 0.509901 31 | v -0.327887 -0.236546 0.688757 32 | v -0.328536 0.274228 0.634951 33 | v -0.602223 0.197946 0.647606 34 | v -0.643023 0.618481 -0.109321 35 | v -0.743918 0.177438 -0.342956 36 | v -0.524395 0.165234 0.245009 37 | v -0.610036 0.541833 0.207682 38 | v -0.632530 0.039175 0.189158 39 | v -0.691889 -0.118163 -0.226134 40 | v -0.533010 -0.392815 0.097328 41 | v -0.650694 -0.275758 0.414996 42 | v -0.661670 -0.286969 -0.252691 43 | v -0.513085 -0.621600 -0.131423 44 | v 0.249145 0.711106 0.133369 45 | v 0.106410 0.499758 0.608065 46 | v 0.093175 -0.681535 0.388646 47 | v 0.325519 -0.735429 0.144541 48 | v 0.084050 0.160894 0.658732 49 | v 0.067666 -0.117932 0.673608 50 | v 0.429471 0.097410 0.596441 51 | v 0.203256 0.325320 0.762847 52 | v 0.389462 -0.287807 0.701552 53 | v 0.448764 -0.245519 0.565037 54 | v 0.436053 -0.706549 -0.187606 55 | v 0.204758 -0.665866 -0.440966 56 | v 0.221433 0.487521 -0.613617 57 | v 0.293344 0.773539 -0.288734 58 | v 0.306299 0.201254 -0.745522 59 | v 0.563687 0.257111 -0.504921 60 | v -0.099690 -0.271758 -0.806141 61 | v 0.087138 0.203459 -0.803661 62 | v 0.650758 -0.207973 -0.531216 63 | v 0.174573 -0.244007 -0.596979 64 | v 0.583296 0.540528 0.190590 65 | v 0.767664 0.210738 0.214924 66 | v 0.790379 0.370442 -0.431658 67 | v 0.486170 0.414173 -0.253246 68 | v 0.780621 -0.034092 -0.174707 69 | v 0.710529 0.120418 0.034417 70 | v 0.484540 -0.528223 -0.285938 71 | v 0.805274 -0.342580 -0.243017 72 | v 0.710724 -0.175170 0.280572 73 | v 0.662683 -0.422633 0.224962 74 | v -0.029544 -0.720632 -0.258989 75 | v 0.046012 0.677482 -0.313908 76 | v -0.006661 0.705866 0.332150 77 | v 0.108822 -0.668220 0.186928 78 | v -0.321631 -0.553148 -0.477697 79 | v -0.484732 0.441108 -0.353058 80 | v -0.138251 0.064817 -0.819131 81 | v -0.373120 0.515671 0.466141 82 | v -0.430239 -0.337531 0.525309 83 | v -0.142494 -0.034720 0.642089 84 | v -0.774762 0.288559 -0.144606 85 | v -0.691989 -0.221039 -0.085296 86 | v 0.527760 0.466039 0.470453 87 | v 0.461860 -0.334976 0.423615 88 | v 0.233366 -0.034912 0.767133 89 | v 0.561256 -0.324512 -0.462239 90 | v 0.471158 0.561601 -0.536619 91 | v 0.354680 0.104051 -0.706976 92 | v 0.703369 0.224502 0.010530 93 | v 0.761565 -0.167249 -0.044489 94 | v 0.678505 -0.155892 0.238306 95 | v 0.632514 -0.058850 0.231106 96 | v 0.765328 0.058770 0.283404 97 | v 0.817578 0.029683 -0.280360 98 | v 0.622919 0.095244 -0.248986 99 | v 0.708005 -0.057924 -0.231893 100 | v 0.568147 -0.053687 -0.401462 101 | v 0.615353 0.048891 -0.465155 102 | v 0.735785 0.129339 -0.423268 103 | v 0.551122 0.262360 -0.499566 104 | v 0.761280 -0.146299 -0.337908 105 | v 0.639801 -0.242561 -0.498741 106 | v 0.067725 -0.304392 0.644602 107 | v 0.112793 -0.285233 0.761871 108 | v 0.007344 -0.207759 0.665771 109 | v 0.514906 -0.684160 0.093044 110 | v 0.350438 -0.664481 0.204878 111 | v 0.267622 -0.663103 0.050942 112 | v 0.745792 0.182940 0.308676 113 | v 0.618910 0.260035 0.491479 114 | v 0.678568 0.017664 0.461332 115 | v -0.555746 -0.012552 -0.391493 116 | v -0.573773 -0.227119 -0.185927 117 | v -0.598841 -0.115482 -0.235857 118 | v -0.642490 0.184740 0.410990 119 | v -0.642039 0.034477 0.243209 120 | v -0.650075 -0.087303 0.388627 121 | v -0.106043 -0.177357 0.705539 122 | v -0.042838 -0.436586 0.711019 123 | v -0.579752 -0.168975 0.253580 124 | v -0.604321 -0.182709 0.398955 125 | v -0.457373 -0.157054 0.346892 126 | v -0.026316 0.443606 0.684606 127 | v -0.233834 0.317247 0.667273 128 | v 0.017164 0.378194 0.569105 129 | v 0.076257 0.222343 -0.691157 130 | v -0.069284 0.284093 -0.657421 131 | v -0.165948 0.332530 -0.731895 132 | v -0.753654 0.209791 -0.379774 133 | v -0.574593 0.077285 -0.497090 134 | v -0.604613 0.174436 -0.453159 135 | v -0.453785 -0.152911 -0.542399 136 | v -0.664068 -0.321890 -0.535323 137 | v -0.066231 -0.591261 0.536335 138 | v 0.001967 -0.473195 0.398183 139 | v 0.074314 -0.616083 0.528434 140 | v 0.148822 0.443180 0.518365 141 | v 0.127746 0.495966 0.475732 142 | v -0.095642 0.517032 -0.607906 143 | v -0.098387 0.496119 -0.515745 144 | v 0.058676 0.405818 -0.718056 145 | v 0.213271 -0.456361 -0.576821 146 | v 0.090815 -0.590807 -0.445643 147 | v -0.073283 -0.477471 -0.598201 148 | v -0.282756 -0.608035 -0.053643 149 | v -0.173933 -0.804136 0.052753 150 | v -0.351466 -0.610975 -0.245829 151 | v 0.346478 -0.593501 -0.085400 152 | v 0.379581 -0.774978 -0.023598 153 | v 0.206049 -0.662459 0.012753 154 | v 0.119196 -0.731280 -0.232012 155 | v 0.268292 -0.651448 -0.328192 156 | v -0.100309 -0.772443 -0.183577 157 | v 0.125851 -0.759816 -0.087262 158 | v -0.134676 -0.726324 -0.205168 159 | v -0.037788 -0.612027 -0.475629 160 | v -0.296473 -0.732101 -0.451640 161 | v 0.116867 -0.543379 -0.415146 162 | v 0.352111 -0.612631 -0.419533 163 | v 0.286870 0.676494 -0.186554 164 | v 0.318317 0.799139 0.039526 165 | v 0.450789 0.682545 -0.197300 166 | v -0.180726 0.733743 -0.112478 167 | v -0.223035 0.616944 -0.114855 168 | v -0.296479 0.672797 -0.008465 169 | v -0.062480 0.855935 -0.038033 170 | v -0.245528 0.637692 -0.177599 171 | v 0.056867 0.690459 -0.176468 172 | v 0.021276 0.725189 0.068857 173 | v 0.086706 0.573336 -0.179178 174 | v 0.151437 0.702169 -0.310989 175 | v 0.212805 0.506031 -0.326034 176 | v -0.006560 0.548097 -0.338295 177 | v -0.196514 0.549375 -0.359933 178 | v -0.302734 0.590488 0.037478 179 | v -0.317248 0.721056 0.141171 180 | v 0.195149 0.818106 0.016820 181 | v 0.400664 0.689591 0.199203 182 | v 0.038586 0.682207 0.048773 183 | v 0.243073 0.808528 0.197588 184 | v 0.055591 0.681438 0.107005 185 | v -0.171159 0.747510 0.117709 186 | v -0.121346 0.569362 0.488952 187 | v -0.216148 0.501434 0.243671 188 | v 0.029415 0.542590 0.379660 189 | v 0.170697 0.616752 0.398645 190 | v 0.244644 -0.771577 0.078715 191 | v -0.250109 -0.596364 0.173912 192 | v -0.255999 -0.567886 0.170534 193 | v -0.180567 -0.710823 0.207876 194 | v -0.083662 -0.786607 0.286636 195 | v 0.135372 -0.696518 0.127299 196 | v 0.200617 -0.815338 0.117316 197 | v 0.112036 -0.740721 0.450308 198 | v 0.227938 -0.623298 0.381341 199 | v -0.124428 -0.581020 0.247427 200 | v -0.334729 -0.605491 0.338836 201 | v -0.387044 -0.535267 -0.121974 202 | v -0.572876 -0.598810 -0.165984 203 | v -0.225389 -0.561657 -0.586797 204 | v -0.212197 -0.267025 -0.584568 205 | v -0.273520 -0.506930 -0.437525 206 | v -0.347033 -0.291701 -0.524381 207 | v -0.468292 -0.468507 -0.483997 208 | v -0.514916 -0.599466 -0.397990 209 | v -0.532103 -0.341915 -0.371742 210 | v -0.531286 -0.491964 -0.366936 211 | v -0.431516 -0.361859 -0.632839 212 | v -0.266430 -0.217778 -0.520418 213 | v -0.120823 0.513882 -0.660938 214 | v -0.412251 0.634760 -0.243888 215 | v -0.384628 0.471489 -0.089153 216 | v -0.350737 0.617922 -0.446011 217 | v -0.475291 0.421705 -0.251327 218 | v -0.155728 0.513306 -0.387921 219 | v -0.314792 0.256870 -0.542762 220 | v -0.561674 0.331844 -0.455043 221 | v -0.305819 0.335778 -0.593245 222 | v -0.415141 0.329932 -0.310553 223 | v -0.563173 0.406958 -0.300493 224 | v -0.549897 -0.073101 -0.639362 225 | v -0.088973 -0.199897 -0.773160 226 | v 0.034426 -0.265418 -0.715426 227 | v -0.328770 -0.151862 -0.634094 228 | v -0.228271 -0.098438 -0.742514 229 | v -0.459018 -0.049946 -0.581213 230 | v -0.459514 0.111159 -0.778016 231 | v -0.189389 0.257736 -0.634779 232 | v -0.238576 0.110272 -0.797051 233 | v 0.042237 -0.009968 -0.755564 234 | v -0.563947 0.201608 0.437805 235 | v -0.598858 0.129544 0.480178 236 | v -0.345735 0.510709 0.070286 237 | v -0.593115 0.517947 0.109063 238 | v -0.539013 0.412095 0.278605 239 | v -0.283077 0.445341 0.210778 240 | v -0.530847 0.390712 0.271549 241 | v -0.552469 0.490068 0.293830 242 | v -0.341714 0.355559 0.596111 243 | v -0.216296 0.323808 0.533675 244 | v -0.397571 0.254660 0.531022 245 | v -0.183048 0.574788 0.518116 246 | v -0.073192 -0.553889 0.647521 247 | v -0.403232 -0.701156 0.097619 248 | v -0.521876 -0.533004 -0.033580 249 | v -0.389023 -0.667861 0.372410 250 | v -0.397048 -0.560251 0.347678 251 | v -0.355709 -0.449369 0.441293 252 | v -0.403961 -0.288911 0.493697 253 | v -0.394748 -0.308161 0.549022 254 | v -0.452997 -0.181057 0.714648 255 | v -0.623734 -0.391036 0.474143 256 | v -0.604763 -0.458893 0.234807 257 | v -0.568179 -0.091715 0.594130 258 | v -0.137304 0.233863 0.756382 259 | v 0.066243 0.227447 0.595349 260 | v -0.253928 0.205322 0.586382 261 | v -0.080952 0.121347 0.749471 262 | v -0.353881 -0.025296 0.560899 263 | v -0.441792 -0.153813 0.632718 264 | v -0.236231 -0.069196 0.768484 265 | v -0.169674 0.020684 0.752406 266 | v 0.108746 0.121645 0.734625 267 | v -0.574183 0.229338 -0.235243 268 | v -0.510002 0.583487 0.060532 269 | v -0.557648 0.322051 -0.129972 270 | v -0.646166 0.320781 0.139277 271 | v -0.691597 0.338926 -0.234473 272 | v -0.774570 0.078610 -0.202890 273 | v -0.594317 0.137741 -0.019802 274 | v -0.761772 0.073900 0.085097 275 | v -0.640520 0.327637 0.043496 276 | v -0.606541 -0.243355 0.313983 277 | v -0.561791 -0.474743 -0.059231 278 | v -0.700332 -0.486847 0.017656 279 | v -0.610509 -0.492821 -0.119963 280 | v -0.767222 -0.315967 0.071482 281 | v -0.806796 -0.157130 -0.033040 282 | v -0.641927 -0.123004 -0.111222 283 | v -0.550079 -0.205245 -0.220280 284 | v 0.231165 0.556518 0.647625 285 | v 0.164231 0.319214 0.676050 286 | v 0.409497 0.712368 0.206693 287 | v 0.529415 0.686606 -0.029615 288 | v 0.335548 0.526463 0.381435 289 | v 0.446905 0.433185 0.191197 290 | v 0.205652 0.625769 0.541608 291 | v 0.311001 0.401107 0.600554 292 | v 0.488802 0.324140 0.439069 293 | v 0.421178 0.213940 0.557575 294 | v 0.491270 0.362016 0.260026 295 | v 0.685042 0.474515 0.103988 296 | v 0.274171 -0.336371 0.674068 297 | v 0.669163 -0.316944 0.428157 298 | v 0.621645 -0.113399 0.372709 299 | v 0.619309 -0.219970 0.458914 300 | v 0.474973 -0.236928 0.457174 301 | v 0.492317 -0.302531 0.417300 302 | v 0.503323 -0.229067 0.640902 303 | v 0.235241 -0.396956 0.556719 304 | v 0.357727 -0.501550 0.401907 305 | v 0.512622 -0.553006 0.201605 306 | v 0.754593 -0.342110 0.202228 307 | v 0.078796 0.260433 0.694852 308 | v 0.453305 -0.032864 0.547109 309 | v 0.500075 -0.018708 0.615544 310 | v 0.298478 -0.027904 0.670609 311 | v 0.214617 0.228149 0.703921 312 | v 0.172753 0.148357 0.746229 313 | v 0.135118 -0.029909 0.817840 314 | v 0.173663 -0.039060 0.629453 315 | v 0.274384 -0.415092 -0.528911 316 | v 0.226770 -0.454285 -0.798103 317 | v 0.531020 -0.554150 -0.226583 318 | v 0.484838 -0.698419 -0.079873 319 | v 0.453590 -0.438501 -0.440962 320 | v 0.460341 -0.383800 -0.325838 321 | v 0.416232 -0.542381 -0.466471 322 | v 0.447549 -0.295406 -0.531045 323 | v 0.579975 -0.352499 -0.462715 324 | v 0.416326 -0.161537 -0.580707 325 | v 0.529541 -0.247602 -0.409204 326 | v 0.604610 -0.442983 -0.231650 327 | v 0.525939 0.501780 -0.284622 328 | v 0.416434 0.589564 -0.036420 329 | v 0.235123 0.502566 -0.703299 330 | v 0.115373 0.409825 -0.754198 331 | v 0.198948 0.434816 -0.551473 332 | v 0.474149 0.429700 -0.697705 333 | v 0.395890 0.541324 -0.388998 334 | v 0.519725 0.416965 -0.422094 335 | v 0.589475 0.257001 -0.379928 336 | v 0.608905 0.489518 -0.364340 337 | v 0.582089 0.338688 -0.555610 338 | v 0.457036 0.133717 -0.562880 339 | v 0.264304 0.204178 -0.823329 340 | v 0.223485 -0.133809 -0.680592 341 | v 0.242955 -0.023488 -0.666462 342 | v 0.232275 -0.197513 -0.709856 343 | v 0.247547 -0.013137 -0.646379 344 | v 0.242092 0.134071 -0.719877 345 | v 0.451696 0.040479 -0.647774 346 | v 0.363123 -0.189140 -0.624137 347 | v 0.681938 0.208616 0.268325 348 | v 0.536532 0.551346 -0.143380 349 | v 0.677421 0.425330 0.028053 350 | v 0.643158 0.315631 0.005501 351 | v 0.597130 0.378149 0.248689 352 | v 0.859139 0.231932 0.150455 353 | v 0.846192 0.113470 -0.096471 354 | v 0.835608 0.056917 -0.081278 355 | v 0.706822 0.375889 -0.194533 356 | v 0.705113 -0.066374 -0.218833 357 | v 0.571441 -0.611720 -0.051810 358 | v 0.564430 -0.356872 -0.059884 359 | v 0.788633 -0.384311 0.070202 360 | v 0.754181 -0.275083 -0.197717 361 | v 0.803137 -0.103853 -0.008971 362 | v 0.825296 -0.118895 -0.010017 363 | v 0.744565 -0.321550 0.041616 364 | vn 0.633746 -0.166873 -0.755327 365 | vn 0.885500 -0.299581 0.355164 366 | vn -0.201056 -0.498522 0.843239 367 | vn -0.527776 -0.342229 -0.777388 368 | vn 0.653857 -0.160259 0.739451 369 | vn -0.174792 -0.174482 0.969022 370 | vn -0.322481 -0.452503 -0.831413 371 | vn -0.291878 -0.548596 -0.783485 372 | vn -0.513319 -0.854027 0.084514 373 | vn 0.334201 -0.894796 0.296057 374 | vn 0.682018 0.731271 0.009702 375 | vn -0.146652 0.801000 -0.580424 376 | vn 0.025739 0.971035 0.237546 377 | vn -0.448736 0.393372 0.802430 378 | vn -0.373670 -0.910755 0.175773 379 | vn 0.301272 -0.881211 0.364284 380 | vn -0.320107 -0.292263 -0.901173 381 | vn -0.808487 -0.579678 0.101595 382 | vn 0.281610 0.955693 -0.085719 383 | vn 0.608122 0.622858 -0.492175 384 | vn -0.814319 0.338254 -0.471667 385 | vn 0.182856 -0.876434 0.445452 386 | vn -0.256048 -0.683496 -0.683574 387 | vn -0.139521 0.250050 -0.958128 388 | vn 0.080336 0.518668 0.851193 389 | vn -0.463043 0.544628 0.699265 390 | vn -0.085348 -0.992232 -0.090502 391 | vn -0.193850 -0.975412 0.104850 392 | vn -0.941836 -0.087265 0.324546 393 | vn -0.251248 -0.508270 0.823733 394 | vn -0.651373 0.090632 0.753325 395 | vn -0.497096 0.168631 0.851152 396 | vn -0.509515 0.817295 -0.269115 397 | vn 0.026186 0.531145 -0.846876 398 | vn -0.793795 0.525534 0.306109 399 | vn 0.206977 0.950159 0.233148 400 | vn -0.965401 0.108202 0.237261 401 | vn -0.651159 -0.512385 -0.559869 402 | vn -0.453990 -0.875456 0.165738 403 | vn -0.968346 0.194059 0.156991 404 | vn -0.792844 -0.552240 0.257739 405 | vn -0.784508 -0.567735 0.249447 406 | vn 0.664623 0.702778 0.253730 407 | vn -0.890967 -0.003486 0.454055 408 | vn 0.593731 -0.370452 0.714317 409 | vn 0.762009 -0.646649 0.034458 410 | vn -0.281185 0.520099 0.806493 411 | vn -0.353986 -0.073877 0.932328 412 | vn 0.731201 0.229537 0.642384 413 | vn 0.120422 0.199664 0.972437 414 | vn 0.292105 -0.497863 0.816583 415 | vn 0.626911 0.731321 0.268614 416 | vn 0.221426 -0.910150 -0.350140 417 | vn 0.175863 -0.911146 -0.372674 418 | vn 0.661969 0.698634 -0.271491 419 | vn -0.020616 0.904784 -0.425370 420 | vn 0.564585 -0.153610 -0.810955 421 | vn 0.759453 0.416730 -0.499567 422 | vn 0.232567 -0.452606 -0.860848 423 | vn 0.136306 0.388475 -0.911322 424 | vn 0.897579 -0.423562 -0.122260 425 | vn 0.513736 -0.369106 -0.774491 426 | vn 0.785843 0.502983 0.359803 427 | vn 0.605045 0.140709 -0.783659 428 | vn 0.683136 0.720958 -0.116382 429 | vn 0.635377 0.768424 -0.076296 430 | vn 0.768695 -0.312827 -0.557896 431 | vn 0.848965 -0.315484 0.423943 432 | vn 0.879398 -0.474870 0.034030 433 | vn 0.889724 -0.456151 0.017808 434 | vn 0.686220 0.238707 0.687110 435 | vn 0.716235 -0.559418 0.417204 436 | vn 0.007716 -0.795131 -0.606388 437 | vn 0.194438 0.804266 -0.561560 438 | vn 0.061382 0.772756 0.631728 439 | vn -0.451555 -0.891324 0.040499 440 | vn 0.270024 -0.590645 -0.760412 441 | vn -0.829936 0.256533 -0.495376 442 | vn -0.692452 -0.340695 -0.635953 443 | vn -0.443524 0.660917 0.605372 444 | vn 0.237114 -0.622971 0.745442 445 | vn -0.738998 0.581018 0.341029 446 | vn -0.885635 0.235269 0.400373 447 | vn -0.704176 -0.150181 -0.693961 448 | vn 0.867701 0.456914 0.195765 449 | vn 0.668153 -0.195179 0.717967 450 | vn 0.388745 -0.610717 0.689857 451 | vn 0.383236 -0.727618 0.568949 452 | vn 0.589375 0.805355 -0.063560 453 | vn -0.089169 0.242817 -0.965965 454 | vn 0.740352 0.658018 -0.137446 455 | vn 0.881928 -0.424939 -0.204033 456 | vn 0.683562 0.156151 0.712993 457 | vn 0.990115 -0.113547 0.082330 458 | vn 0.986933 -0.091228 -0.132815 459 | vn 0.973382 0.148065 0.174942 460 | vn 0.968933 0.227267 -0.097565 461 | vn 0.986805 -0.161403 -0.012806 462 | vn 0.794672 -0.016061 -0.606826 463 | vn 0.745816 -0.151391 -0.648722 464 | vn 0.662879 0.477194 -0.576955 465 | vn 0.724071 0.673772 0.147487 466 | vn 0.937604 0.161059 -0.308154 467 | vn 0.946851 -0.274476 -0.167740 468 | vn 0.092056 -0.466645 0.879641 469 | vn -0.309999 -0.307272 0.899714 470 | vn -0.252617 0.016493 0.967426 471 | vn 0.536356 -0.824634 0.179727 472 | vn 0.623406 -0.746700 0.231958 473 | vn 0.412994 -0.843747 -0.342821 474 | vn 0.972311 -0.201902 0.117671 475 | vn 0.576272 0.592427 0.562975 476 | vn 0.808094 -0.309484 0.501203 477 | vn -0.938326 -0.137073 -0.317420 478 | vn -0.470136 -0.880646 -0.058612 479 | vn -0.625397 -0.522267 -0.579755 480 | vn -0.766538 0.557476 0.318810 481 | vn -0.984521 0.152739 -0.085955 482 | vn -0.375863 -0.360161 0.853822 483 | vn 0.203065 -0.147068 0.968058 484 | vn 0.334707 -0.162292 0.928242 485 | vn -0.458421 0.469059 0.754873 486 | vn -0.608419 0.586071 0.535114 487 | vn -0.964411 0.154135 0.214835 488 | vn 0.085733 0.587940 0.804348 489 | vn -0.228590 0.196302 0.953526 490 | vn -0.110760 -0.497445 0.860395 491 | vn -0.408850 0.390861 -0.824664 492 | vn 0.190992 0.413863 -0.890078 493 | vn 0.573235 -0.088785 -0.814567 494 | vn -0.182452 -0.039485 0.982422 495 | vn 0.032873 0.750505 0.660047 496 | vn -0.509032 0.574024 -0.641391 497 | vn -0.945027 0.104494 -0.309847 498 | vn -0.788908 -0.151778 -0.595473 499 | vn 0.221259 -0.968525 -0.114031 500 | vn -0.376333 -0.924619 -0.058767 501 | vn 0.011574 -0.810655 0.585409 502 | vn -0.018066 0.514251 0.857449 503 | vn -0.495287 0.163405 0.853223 504 | vn 0.910861 0.112040 -0.397214 505 | vn 0.438494 0.826092 -0.353970 506 | vn -0.368331 0.911255 -0.184245 507 | vn 0.205153 -0.789683 -0.578198 508 | vn -0.316253 -0.946811 -0.059439 509 | vn 0.097936 -0.470635 -0.876876 510 | vn -0.451025 -0.865825 -0.216617 511 | vn -0.079479 -0.887510 -0.453882 512 | vn 0.183913 -0.102428 -0.977591 513 | vn -0.043264 -0.974595 -0.219756 514 | vn 0.110621 -0.925181 -0.363046 515 | vn 0.701790 -0.711637 0.032620 516 | vn 0.141736 -0.912090 -0.384712 517 | vn -0.050024 -0.929349 -0.365799 518 | vn -0.316227 -0.936913 -0.148976 519 | vn -0.293963 -0.945951 0.136976 520 | vn -0.536838 -0.791541 -0.292008 521 | vn 0.183486 -0.944929 -0.271001 522 | vn -0.489076 -0.595338 -0.637478 523 | vn -0.069389 -0.957340 0.280509 524 | vn 0.402798 -0.904085 -0.142773 525 | vn 0.065206 0.933264 -0.353222 526 | vn 0.176722 0.976424 0.123962 527 | vn 0.673401 0.727719 -0.130216 528 | vn -0.737447 0.610660 -0.288559 529 | vn -0.610047 0.791555 -0.035835 530 | vn 0.278305 0.960428 -0.011180 531 | vn 0.118461 0.990705 0.066858 532 | vn 0.251111 0.617428 -0.745470 533 | vn 0.460588 0.704686 -0.539701 534 | vn 0.066503 0.695483 0.715458 535 | vn 0.232944 0.972104 0.027391 536 | vn 0.222266 0.972991 -0.062343 537 | vn 0.567700 0.653231 -0.501006 538 | vn -0.096222 0.840914 -0.532546 539 | vn 0.456261 0.805324 -0.378523 540 | vn 0.216246 0.971057 0.101420 541 | vn 0.448791 0.621097 0.642514 542 | vn -0.073377 0.824685 0.560813 543 | vn 0.068761 0.934961 0.348023 544 | vn -0.144016 0.774711 0.615697 545 | vn 0.226747 0.862378 0.452647 546 | vn -0.007544 0.995859 0.090602 547 | vn -0.252947 0.966525 0.042986 548 | vn -0.294144 0.229552 0.927785 549 | vn -0.592534 0.658934 0.463367 550 | vn -0.030827 0.656407 0.753777 551 | vn 0.056711 0.928909 0.365939 552 | vn 0.605195 -0.560978 -0.564838 553 | vn -0.775116 -0.535720 -0.334961 554 | vn -0.479187 -0.832948 -0.276727 555 | vn -0.312086 -0.940632 0.133470 556 | vn -0.015840 -0.527110 0.849649 557 | vn -0.453158 -0.869202 0.197826 558 | vn -0.164607 -0.973781 -0.157021 559 | vn -0.285165 -0.548319 0.786147 560 | vn 0.442851 -0.513513 0.734975 561 | vn 0.041422 -0.609051 0.792049 562 | vn 0.351780 -0.404956 0.843956 563 | vn 0.394375 -0.226992 -0.890474 564 | vn -0.985402 0.154052 -0.072466 565 | vn -0.441734 -0.442765 -0.780276 566 | vn 0.285716 -0.561072 -0.776894 567 | vn -0.623933 -0.301802 -0.720849 568 | vn 0.039531 -0.218733 -0.974984 569 | vn -0.018081 -0.837940 0.545462 570 | vn -0.464297 -0.656816 -0.594155 571 | vn -0.690655 -0.549365 -0.470313 572 | vn -0.950358 -0.251266 -0.183534 573 | vn 0.134499 -0.614988 -0.776981 574 | vn -0.134304 -0.422656 -0.896284 575 | vn -0.487715 0.778248 -0.395555 576 | vn -0.622810 0.768403 0.147187 577 | vn 0.161597 0.978292 0.129738 578 | vn -0.345379 0.660092 -0.667077 579 | vn -0.627394 0.492795 -0.602935 580 | vn -0.434008 0.530508 -0.728147 581 | vn -0.193893 0.940000 -0.280723 582 | vn -0.838315 0.487177 0.244717 583 | vn -0.178761 0.957798 -0.225093 584 | vn -0.870670 0.279823 -0.404516 585 | vn -0.311413 0.683708 -0.659973 586 | vn -0.783877 -0.529392 -0.324472 587 | vn -0.322430 -0.938388 0.124364 588 | vn -0.372676 -0.572932 -0.729974 589 | vn -0.640378 -0.521110 -0.564235 590 | vn -0.592733 -0.268440 -0.759347 591 | vn 0.013333 -0.519533 -0.854346 592 | vn -0.281383 0.122949 -0.951687 593 | vn -0.484277 -0.354629 -0.799821 594 | vn -0.159458 0.327890 -0.931161 595 | vn 0.203896 0.052585 -0.977579 596 | vn -0.737417 0.667031 0.106236 597 | vn -0.976431 -0.076951 0.201647 598 | vn -0.156941 0.571060 0.805767 599 | vn 0.133409 0.066681 0.988815 600 | vn 0.001017 0.995591 0.093790 601 | vn -0.485829 0.856367 0.174944 602 | vn -0.893392 0.092593 0.439633 603 | vn -0.078796 -0.624454 0.777077 604 | vn -0.272717 0.311809 0.910165 605 | vn -0.402121 0.614578 0.678670 606 | vn 0.010726 -0.240253 0.970651 607 | vn -0.392631 0.894803 0.212526 608 | vn -0.324223 -0.827744 0.457952 609 | vn -0.821438 -0.560027 -0.107749 610 | vn -0.722123 -0.594766 0.353260 611 | vn -0.414340 -0.443162 0.794940 612 | vn -0.773871 -0.614771 0.152250 613 | vn 0.214423 -0.616749 0.757392 614 | vn 0.271141 -0.730667 0.626584 615 | vn -0.079523 -0.618352 0.781867 616 | vn -0.552888 0.022732 0.832945 617 | vn -0.526785 -0.355338 0.772161 618 | vn -0.584660 -0.808579 0.066118 619 | vn -0.851323 -0.252543 0.459860 620 | vn 0.050281 0.215213 0.975272 621 | vn -0.480081 0.258444 0.838289 622 | vn -0.560110 -0.378993 0.736642 623 | vn -0.431053 0.283058 0.856780 624 | vn -0.060701 0.220031 0.973602 625 | vn -0.510367 0.654661 0.557624 626 | vn -0.396633 0.419612 0.816461 627 | vn -0.198771 0.164339 0.966169 628 | vn -0.291148 0.379926 0.878003 629 | vn -0.353685 -0.406942 -0.842203 630 | vn -0.718699 0.319208 0.617720 631 | vn -0.753542 0.619661 0.219531 632 | vn -0.973162 0.116330 -0.198551 633 | vn -0.731942 0.656865 -0.181077 634 | vn -0.847095 0.132831 -0.514574 635 | vn -0.905305 0.274525 0.324129 636 | vn -0.930437 0.298939 0.211949 637 | vn -0.662495 -0.563037 0.494055 638 | vn -0.914273 0.296115 0.276444 639 | vn -0.378636 -0.816895 0.435106 640 | vn -0.389905 -0.919250 -0.054343 641 | vn -0.828625 -0.508369 -0.234397 642 | vn -0.987054 -0.153433 0.046713 643 | vn -0.991275 -0.013182 -0.131152 644 | vn -0.843787 -0.248236 -0.475818 645 | vn -0.624000 -0.742639 -0.243130 646 | vn -0.153525 0.401268 0.903003 647 | vn -0.603728 0.608442 0.515084 648 | vn 0.386884 0.820125 0.421563 649 | vn 0.238143 0.850067 -0.469759 650 | vn 0.465860 0.865640 0.183418 651 | vn 0.690369 0.376389 0.617837 652 | vn 0.214455 0.934272 0.284859 653 | vn 0.730706 0.231431 0.642269 654 | vn 0.695715 0.307733 0.649062 655 | vn 0.751265 0.121613 0.648700 656 | vn 0.698832 0.643543 0.312229 657 | vn 0.652756 0.331023 0.681420 658 | vn 0.427088 -0.708009 0.562423 659 | vn 0.230903 0.376263 0.897279 660 | vn 0.874861 -0.030853 0.483390 661 | vn -0.714057 0.687179 -0.133822 662 | vn 0.612626 -0.618818 0.491684 663 | vn 0.421269 -0.742081 0.521390 664 | vn 0.634606 0.011139 0.772755 665 | vn 0.579157 -0.582550 0.570274 666 | vn 0.538055 -0.580955 0.610727 667 | vn 0.590621 -0.258850 0.764306 668 | vn 0.835277 0.068160 0.545588 669 | vn -0.723401 0.285438 0.628662 670 | vn 0.708492 -0.340764 0.617995 671 | vn 0.760732 -0.641237 0.100513 672 | vn 0.357934 -0.850575 0.385235 673 | vn 0.344846 0.070498 0.936008 674 | vn -0.099810 0.362152 0.926760 675 | vn -0.257455 -0.147205 0.955012 676 | vn 0.341965 -0.466593 0.815691 677 | vn 0.545721 -0.359996 -0.756697 678 | vn 0.576047 -0.599322 -0.555862 679 | vn 0.894759 -0.444267 -0.045083 680 | vn 0.701621 -0.660790 -0.266616 681 | vn 0.895314 -0.441308 0.060499 682 | vn 0.902024 -0.412962 -0.125759 683 | vn 0.599352 -0.600779 -0.529001 684 | vn 0.179955 -0.410267 -0.894034 685 | vn 0.231127 -0.966526 -0.111392 686 | vn 0.049529 -0.898294 -0.436595 687 | vn 0.331387 -0.942372 -0.046029 688 | vn 0.565499 -0.812694 -0.140496 689 | vn 0.947529 0.291477 -0.131266 690 | vn 0.564638 0.638959 -0.522414 691 | vn 0.206133 0.795574 -0.569711 692 | vn -0.230296 0.182291 -0.955894 693 | vn 0.376994 0.917777 -0.124746 694 | vn 0.549084 0.386215 -0.741178 695 | vn 0.193400 0.883096 -0.427478 696 | vn 0.802792 0.573087 -0.164606 697 | vn 0.758607 0.417611 -0.500117 698 | vn 0.123009 0.959612 -0.253009 699 | vn 0.982510 -0.020379 -0.185093 700 | vn 0.564379 -0.129201 -0.815342 701 | vn 0.583429 0.122211 -0.802917 702 | vn 0.023468 0.010806 -0.999666 703 | vn -0.225046 0.424381 -0.877072 704 | vn -0.617238 -0.309203 -0.723471 705 | vn 0.263147 0.100870 -0.959468 706 | vn 0.850141 -0.086889 -0.519337 707 | vn 0.540108 0.379953 -0.750946 708 | vn 0.466010 -0.570126 -0.676603 709 | vn 0.778175 -0.503486 -0.375428 710 | vn 0.586870 0.489095 -0.645267 711 | vn 0.866696 0.285953 -0.408742 712 | vn 0.741190 0.625409 -0.243928 713 | vn 0.950497 0.009950 -0.310573 714 | vn 0.936661 0.072110 0.342734 715 | vn 0.877671 0.245165 -0.411809 716 | vn 0.899555 -0.434585 -0.044001 717 | vn 0.837983 0.512685 0.186920 718 | vn 0.991885 -0.126466 -0.013081 719 | vn 0.834694 -0.484377 -0.262041 720 | vn 0.801321 -0.579212 -0.149662 721 | vn 0.973594 -0.225937 -0.032678 722 | vn 0.779384 -0.397541 0.484275 723 | vn 0.718798 -0.367736 -0.590000 724 | vn 0.980361 -0.013878 -0.196724 725 | vn 0.944775 0.286042 0.159937 726 | f 94//94 68//68 95//95 727 | f 97//97 67//67 98//98 728 | f 100//100 58//58 101//101 729 | f 96//96 101//101 102//102 730 | f 103//103 99//99 1//1 731 | f 106//106 48//48 107//107 732 | f 109//109 46//46 110//110 733 | f 112//112 49//49 113//113 734 | f 115//115 38//38 116//116 735 | f 118//118 37//37 119//119 736 | f 120//120 107//107 48//48 737 | f 123//123 29//29 124//124 738 | f 126//126 31//31 127//127 739 | f 129//129 22//22 130//130 740 | f 132//132 21//21 133//133 741 | f 134//134 114//114 4//4 742 | f 137//137 45//45 138//138 743 | f 139//139 125//125 6//6 744 | f 142//142 55//55 143//143 745 | f 145//145 17//17 146//146 746 | f 148//148 9//9 149//149 747 | f 151//151 10//10 152//152 748 | f 153//153 150//150 16//16 749 | f 156//156 153//153 16//16 750 | f 157//157 147//147 18//18 751 | f 159//159 157//157 18//18 752 | f 160//160 154//154 73//73 753 | f 145//145 160//160 158//158 754 | f 163//163 11//11 164//164 755 | f 166//166 12//12 167//167 756 | f 168//168 165//165 14//14 757 | f 171//171 168//168 14//14 758 | f 172//172 162//162 56//56 759 | f 174//174 172//172 56//56 760 | f 175//175 169//169 74//74 761 | f 142//142 175//175 173//173 762 | f 178//178 167//167 12//12 763 | f 179//179 163//163 13//13 764 | f 181//181 179//179 13//13 765 | f 183//183 171//171 14//14 766 | f 184//184 177//177 26//26 767 | f 186//186 184//184 26//26 768 | f 187//187 182//182 75//75 769 | f 140//140 187//187 185//185 770 | f 189//189 110//110 46//46 771 | f 190//190 148//148 15//15 772 | f 192//192 190//190 15//15 773 | f 194//194 156//156 16//16 774 | f 195//195 189//189 46//46 775 | f 197//197 195//195 46//46 776 | f 198//198 193//193 76//76 777 | f 137//137 198//198 196//196 778 | f 201//201 149//149 9//9 779 | f 202//202 146//146 17//17 780 | f 204//204 202//202 17//17 781 | f 206//206 159//159 18//18 782 | f 207//207 200//200 42//42 783 | f 209//209 207//207 42//42 784 | f 210//210 205//205 77//77 785 | f 135//135 210//210 208//208 786 | f 212//212 130//130 22//22 787 | f 213//213 166//166 19//19 788 | f 215//215 213//213 19//19 789 | f 217//217 176//176 20//20 790 | f 218//218 212//212 22//22 791 | f 220//220 218//218 22//22 792 | f 221//221 216//216 78//78 793 | f 132//132 221//221 219//219 794 | f 223//223 133//133 21//21 795 | f 224//224 203//203 23//23 796 | f 226//226 224//224 23//23 797 | f 228//228 211//211 24//24 798 | f 229//229 223//223 21//21 799 | f 230//230 220//220 22//22 800 | f 231//231 227//227 79//79 801 | f 129//129 231//231 230//230 802 | f 234//234 117//117 3//3 803 | f 236//236 178//178 12//12 804 | f 237//237 235//235 36//36 805 | f 240//240 237//237 36//36 806 | f 241//241 233//233 32//32 807 | f 243//243 241//241 32//32 808 | f 186//186 238//238 244//244 809 | f 126//126 244//244 242//242 810 | f 245//245 121//121 30//30 811 | f 246//246 191//191 27//27 812 | f 248//248 246//246 27//27 813 | f 250//250 199//199 28//28 814 | f 251//251 245//245 30//30 815 | f 253//253 251//251 30//30 816 | f 254//254 249//249 81//81 817 | f 123//123 254//254 252//252 818 | f 256//256 124//124 29//29 819 | f 257//257 127//127 31//31 820 | f 259//259 257//257 31//31 821 | f 261//261 243//243 32//32 822 | f 262//262 256//256 29//29 823 | f 263//263 253//253 30//30 824 | f 264//264 260//260 82//82 825 | f 120//120 264//264 263//263 826 | f 266//266 116//116 38//38 827 | f 267//267 214//214 33//33 828 | f 268//268 267//267 33//33 829 | f 270//270 222//222 34//34 830 | f 271//271 266//266 38//38 831 | f 273//273 271//271 38//38 832 | f 240//240 269//269 274//274 833 | f 118//118 274//274 272//272 834 | f 275//275 119//119 37//37 835 | f 201//201 247//247 276//276 836 | f 277//277 276//276 39//39 837 | f 279//279 255//255 40//40 838 | f 280//280 275//275 37//37 839 | f 281//281 273//273 38//38 840 | f 209//209 278//278 282//282 841 | f 115//115 282//282 281//281 842 | f 284//284 139//139 6//6 843 | f 285//285 180//180 43//43 844 | f 287//287 285//285 43//43 845 | f 289//289 188//188 44//44 846 | f 290//290 283//283 50//50 847 | f 292//292 290//290 50//50 848 | f 293//293 288//288 85//85 849 | f 112//112 293//293 291//291 850 | f 105//105 138//138 295//295 851 | f 297//297 93//93 2//2 852 | f 298//298 296//296 52//52 853 | f 301//301 298//298 52//52 854 | f 302//302 295//295 45//45 855 | f 303//303 197//197 46//46 856 | f 304//304 299//299 86//86 857 | f 109//109 304//304 303//303 858 | f 306//306 258//258 47//47 859 | f 307//307 113//113 49//49 860 | f 308//308 307//307 49//49 861 | f 310//310 292//292 50//50 862 | f 311//311 306//306 47//47 863 | f 312//312 265//265 48//48 864 | f 301//301 309//309 313//313 865 | f 106//106 313//313 312//312 866 | f 315//315 144//144 8//8 867 | f 316//316 151//151 53//53 868 | f 318//318 316//316 53//53 869 | f 320//320 161//161 54//54 870 | f 321//321 314//314 62//62 871 | f 323//323 321//321 62//62 872 | f 324//324 319//319 88//88 873 | f 104//104 324//324 322//322 874 | f 327//327 164//164 11//11 875 | f 328//328 143//143 55//55 876 | f 330//330 328//328 55//55 877 | f 332//332 174//174 56//56 878 | f 333//333 326//326 66//66 879 | f 335//335 333//333 66//66 880 | f 336//336 331//331 89//89 881 | f 102//102 336//336 334//334 882 | f 128//128 329//329 338//338 883 | f 339//339 225//225 59//59 884 | f 340//340 339//339 59//59 885 | f 342//342 232//232 60//60 886 | f 343//343 338//338 57//57 887 | f 344//344 337//337 58//58 888 | f 323//323 341//341 345//345 889 | f 100//100 345//345 344//344 890 | f 346//346 95//95 68//68 891 | f 347//347 286//286 63//63 892 | f 348//348 347//347 63//63 893 | f 350//350 294//294 64//64 894 | f 351//351 346//346 68//68 895 | f 353//353 351//351 68//68 896 | f 335//335 349//349 354//354 897 | f 97//97 354//354 352//352 898 | f 355//355 98//98 67//67 899 | f 108//108 317//317 356//356 900 | f 357//357 356//356 69//69 901 | f 359//359 325//325 70//70 902 | f 360//360 355//355 67//67 903 | f 361//361 353//353 68//68 904 | f 305//305 358//358 362//362 905 | f 94//94 362//362 361//361 906 | f 94//94 93//93 71//71 907 | f 297//297 52//52 296//296 908 | f 95//95 93//93 94//94 909 | f 94//94 361//361 68//68 910 | f 95//95 2//2 93//93 911 | f 95//95 111//111 2//2 912 | f 97//97 96//96 65//65 913 | f 101//101 58//58 102//102 914 | f 98//98 96//96 97//97 915 | f 97//97 352//352 67//67 916 | f 98//98 1//1 96//96 917 | f 98//98 103//103 1//1 918 | f 100//100 99//99 61//61 919 | f 103//103 70//70 104//104 920 | f 101//101 99//99 100//100 921 | f 100//100 344//344 58//58 922 | f 101//101 1//1 99//99 923 | f 101//101 96//96 1//1 924 | f 102//102 65//65 96//96 925 | f 102//102 334//334 65//65 926 | f 104//104 99//99 103//103 927 | f 355//355 70//70 103//103 928 | f 104//104 61//61 99//99 929 | f 104//104 322//322 61//61 930 | f 106//106 105//105 51//51 931 | f 138//138 45//45 295//295 932 | f 107//107 105//105 106//106 933 | f 106//106 312//312 48//48 934 | f 107//107 5//5 105//105 935 | f 120//120 30//30 121//121 936 | f 109//109 108//108 72//72 937 | f 317//317 69//69 356//356 938 | f 110//110 108//108 109//109 939 | f 109//109 303//303 46//46 940 | f 110//110 10//10 108//108 941 | f 110//110 152//152 10//10 942 | f 112//112 111//111 64//64 943 | f 346//346 64//64 111//111 944 | f 113//113 111//111 112//112 945 | f 112//112 291//291 49//49 946 | f 113//113 2//2 111//111 947 | f 113//113 297//297 2//2 948 | f 115//115 114//114 41//41 949 | f 134//134 24//24 135//135 950 | f 116//116 114//114 115//115 951 | f 115//115 281//281 38//38 952 | f 116//116 4//4 114//114 953 | f 116//116 131//131 4//4 954 | f 118//118 117//117 35//35 955 | f 234//234 32//32 233//233 956 | f 119//119 117//117 118//118 957 | f 118//118 272//272 37//37 958 | f 119//119 3//3 117//117 959 | f 119//119 122//122 3//3 960 | f 121//121 107//107 120//120 961 | f 120//120 263//263 30//30 962 | f 121//121 5//5 107//107 963 | f 121//121 136//136 5//5 964 | f 123//123 122//122 40//40 965 | f 275//275 40//40 122//122 966 | f 124//124 122//122 123//123 967 | f 123//123 252//252 29//29 968 | f 124//124 3//3 122//122 969 | f 124//124 234//234 3//3 970 | f 126//126 125//125 25//25 971 | f 139//139 44//44 140//140 972 | f 127//127 125//125 126//126 973 | f 126//126 242//242 31//31 974 | f 127//127 6//6 125//125 975 | f 257//257 47//47 258//258 976 | f 129//129 128//128 60//60 977 | f 329//329 57//57 338//338 978 | f 130//130 128//128 129//129 979 | f 129//129 230//230 22//22 980 | f 130//130 7//7 128//128 981 | f 130//130 141//141 7//7 982 | f 132//132 131//131 34//34 983 | f 266//266 34//34 131//131 984 | f 133//133 131//131 132//132 985 | f 132//132 219//219 21//21 986 | f 133//133 4//4 131//131 987 | f 133//133 134//134 4//4 988 | f 135//135 114//114 134//134 989 | f 223//223 24//24 134//134 990 | f 135//135 41//41 114//114 991 | f 135//135 208//208 41//41 992 | f 137//137 136//136 28//28 993 | f 245//245 28//28 136//136 994 | f 138//138 136//136 137//137 995 | f 137//137 196//196 45//45 996 | f 138//138 5//5 136//136 997 | f 138//138 105//105 5//5 998 | f 140//140 125//125 139//139 999 | f 284//284 50//50 283//283 1000 | f 140//140 25//25 125//125 1001 | f 140//140 185//185 25//25 1002 | f 142//142 141//141 20//20 1003 | f 212//212 20//20 141//141 1004 | f 143//143 141//141 142//142 1005 | f 142//142 173//173 55//55 1006 | f 143//143 7//7 141//141 1007 | f 328//328 57//57 329//329 1008 | f 145//145 144//144 54//54 1009 | f 315//315 62//62 314//314 1010 | f 146//146 144//144 145//145 1011 | f 145//145 158//158 17//17 1012 | f 146//146 8//8 144//144 1013 | f 202//202 23//23 203//203 1014 | f 148//148 147//147 15//15 1015 | f 147//147 155//155 15//15 1016 | f 149//149 147//147 148//148 1017 | f 190//190 27//27 191//191 1018 | f 149//149 18//18 147//147 1019 | f 201//201 42//42 200//200 1020 | f 151//151 150//150 53//53 1021 | f 153//153 73//73 154//154 1022 | f 152//152 150//150 151//151 1023 | f 316//316 69//69 317//317 1024 | f 152//152 16//16 150//150 1025 | f 189//189 16//16 152//152 1026 | f 154//154 150//150 153//153 1027 | f 156//156 15//15 155//155 1028 | f 154//154 53//53 150//150 1029 | f 160//160 54//54 161//161 1030 | f 155//155 73//73 153//153 1031 | f 157//157 73//73 155//155 1032 | f 155//155 153//153 156//156 1033 | f 156//156 192//192 15//15 1034 | f 155//155 147//147 157//157 1035 | f 159//159 17//17 158//158 1036 | f 158//158 73//73 157//157 1037 | f 160//160 73//73 158//158 1038 | f 158//158 157//157 159//159 1039 | f 159//159 204//204 17//17 1040 | f 161//161 154//154 160//160 1041 | f 160//160 145//145 54//54 1042 | f 161//161 53//53 154//154 1043 | f 161//161 318//318 53//53 1044 | f 163//163 162//162 13//13 1045 | f 162//162 170//170 13//13 1046 | f 164//164 162//162 163//163 1047 | f 179//179 43//43 180//180 1048 | f 164//164 56//56 162//162 1049 | f 327//327 66//66 326//326 1050 | f 166//166 165//165 19//19 1051 | f 168//168 74//74 169//169 1052 | f 167//167 165//165 166//166 1053 | f 213//213 33//33 214//214 1054 | f 167//167 14//14 165//165 1055 | f 178//178 26//26 177//177 1056 | f 169//169 165//165 168//168 1057 | f 171//171 13//13 170//170 1058 | f 169//169 19//19 165//165 1059 | f 175//175 20//20 176//176 1060 | f 170//170 74//74 168//168 1061 | f 172//172 74//74 170//170 1062 | f 170//170 168//168 171//171 1063 | f 171//171 181//181 13//13 1064 | f 170//170 162//162 172//172 1065 | f 174//174 55//55 173//173 1066 | f 173//173 74//74 172//172 1067 | f 175//175 74//74 173//173 1068 | f 173//173 172//172 174//174 1069 | f 174//174 330//330 55//55 1070 | f 176//176 169//169 175//175 1071 | f 175//175 142//142 20//20 1072 | f 176//176 19//19 169//169 1073 | f 176//176 215//215 19//19 1074 | f 177//177 14//14 167//167 1075 | f 177//177 183//183 14//14 1076 | f 177//177 167//167 178//178 1077 | f 236//236 36//36 235//235 1078 | f 180//180 163//163 179//179 1079 | f 181//181 75//75 182//182 1080 | f 180//180 11//11 163//163 1081 | f 285//285 63//63 286//286 1082 | f 182//182 179//179 181//181 1083 | f 183//183 75//75 181//181 1084 | f 182//182 43//43 179//179 1085 | f 187//187 44//44 188//188 1086 | f 181//181 171//171 183//183 1087 | f 184//184 75//75 183//183 1088 | f 183//183 177//177 184//184 1089 | f 186//186 25//25 185//185 1090 | f 185//185 75//75 184//184 1091 | f 187//187 75//75 185//185 1092 | f 185//185 184//184 186//186 1093 | f 238//238 80//80 244//244 1094 | f 188//188 182//182 187//187 1095 | f 187//187 140//140 44//44 1096 | f 188//188 43//43 182//182 1097 | f 188//188 287//287 43//43 1098 | f 152//152 110//110 189//189 1099 | f 189//189 194//194 16//16 1100 | f 191//191 148//148 190//190 1101 | f 192//192 76//76 193//193 1102 | f 191//191 9//9 148//148 1103 | f 246//246 39//39 247//247 1104 | f 193//193 190//190 192//192 1105 | f 194//194 76//76 192//192 1106 | f 193//193 27//27 190//190 1107 | f 198//198 28//28 199//199 1108 | f 192//192 156//156 194//194 1109 | f 195//195 76//76 194//194 1110 | f 194//194 189//189 195//195 1111 | f 197//197 45//45 196//196 1112 | f 196//196 76//76 195//195 1113 | f 198//198 76//76 196//196 1114 | f 196//196 195//195 197//197 1115 | f 197//197 302//302 45//45 1116 | f 199//199 193//193 198//198 1117 | f 198//198 137//137 28//28 1118 | f 199//199 27//27 193//193 1119 | f 199//199 248//248 27//27 1120 | f 200//200 18//18 149//149 1121 | f 200//200 206//206 18//18 1122 | f 200//200 149//149 201//201 1123 | f 247//247 39//39 276//276 1124 | f 203//203 146//146 202//202 1125 | f 204//204 77//77 205//205 1126 | f 203//203 8//8 146//146 1127 | f 224//224 59//59 225//225 1128 | f 205//205 202//202 204//204 1129 | f 206//206 77//77 204//204 1130 | f 205//205 23//23 202//202 1131 | f 210//210 24//24 211//211 1132 | f 204//204 159//159 206//206 1133 | f 207//207 77//77 206//206 1134 | f 206//206 200//200 207//207 1135 | f 209//209 41//41 208//208 1136 | f 208//208 77//77 207//207 1137 | f 210//210 77//77 208//208 1138 | f 208//208 207//207 209//209 1139 | f 278//278 84//84 282//282 1140 | f 211//211 205//205 210//210 1141 | f 210//210 135//135 24//24 1142 | f 211//211 23//23 205//205 1143 | f 211//211 226//226 23//23 1144 | f 141//141 130//130 212//212 1145 | f 212//212 217//217 20//20 1146 | f 214//214 166//166 213//213 1147 | f 215//215 78//78 216//216 1148 | f 214//214 12//12 166//166 1149 | f 214//214 236//236 12//12 1150 | f 216//216 213//213 215//215 1151 | f 217//217 78//78 215//215 1152 | f 216//216 33//33 213//213 1153 | f 221//221 34//34 222//222 1154 | f 215//215 176//176 217//217 1155 | f 218//218 78//78 217//217 1156 | f 217//217 212//212 218//218 1157 | f 220//220 21//21 219//219 1158 | f 219//219 78//78 218//218 1159 | f 221//221 78//78 219//219 1160 | f 219//219 218//218 220//220 1161 | f 220//220 229//229 21//21 1162 | f 222//222 216//216 221//221 1163 | f 221//221 132//132 34//34 1164 | f 222//222 33//33 216//216 1165 | f 222//222 268//268 33//33 1166 | f 134//134 133//133 223//223 1167 | f 223//223 228//228 24//24 1168 | f 225//225 203//203 224//224 1169 | f 226//226 79//79 227//227 1170 | f 225//225 8//8 203//203 1171 | f 225//225 315//315 8//8 1172 | f 227//227 224//224 226//226 1173 | f 228//228 79//79 226//226 1174 | f 227//227 59//59 224//224 1175 | f 231//231 60//60 232//232 1176 | f 226//226 211//211 228//228 1177 | f 229//229 79//79 228//228 1178 | f 228//228 223//223 229//229 1179 | f 230//230 79//79 229//229 1180 | f 229//229 220//220 230//230 1181 | f 231//231 79//79 230//230 1182 | f 232//232 227//227 231//231 1183 | f 231//231 129//129 60//60 1184 | f 232//232 59//59 227//227 1185 | f 232//232 340//340 59//59 1186 | f 233//233 35//35 117//117 1187 | f 233//233 239//239 35//35 1188 | f 233//233 117//117 234//234 1189 | f 256//256 32//32 234//234 1190 | f 235//235 26//26 178//178 1191 | f 237//237 80//80 238//238 1192 | f 235//235 178//178 236//236 1193 | f 267//267 36//36 236//236 1194 | f 238//238 235//235 237//237 1195 | f 240//240 35//35 239//239 1196 | f 238//238 26//26 235//235 1197 | f 238//238 186//186 26//26 1198 | f 239//239 80//80 237//237 1199 | f 241//241 80//80 239//239 1200 | f 239//239 237//237 240//240 1201 | f 269//269 83//83 274//274 1202 | f 239//239 233//233 241//241 1203 | f 243//243 31//31 242//242 1204 | f 242//242 80//80 241//241 1205 | f 244//244 80//80 242//242 1206 | f 242//242 241//241 243//243 1207 | f 243//243 259//259 31//31 1208 | f 244//244 25//25 186//186 1209 | f 244//244 126//126 25//25 1210 | f 136//136 121//121 245//245 1211 | f 245//245 250//250 28//28 1212 | f 247//247 191//191 246//246 1213 | f 248//248 81//81 249//249 1214 | f 247//247 9//9 191//191 1215 | f 247//247 201//201 9//9 1216 | f 249//249 246//246 248//248 1217 | f 250//250 81//81 248//248 1218 | f 249//249 39//39 246//246 1219 | f 254//254 40//40 255//255 1220 | f 248//248 199//199 250//250 1221 | f 251//251 81//81 250//250 1222 | f 250//250 245//245 251//251 1223 | f 253//253 29//29 252//252 1224 | f 252//252 81//81 251//251 1225 | f 254//254 81//81 252//252 1226 | f 252//252 251//251 253//253 1227 | f 253//253 262//262 29//29 1228 | f 255//255 249//249 254//254 1229 | f 254//254 123//123 40//40 1230 | f 255//255 39//39 249//249 1231 | f 255//255 277//277 39//39 1232 | f 234//234 124//124 256//256 1233 | f 256//256 261//261 32//32 1234 | f 258//258 127//127 257//257 1235 | f 259//259 82//82 260//260 1236 | f 258//258 6//6 127//127 1237 | f 258//258 284//284 6//6 1238 | f 260//260 257//257 259//259 1239 | f 261//261 82//82 259//259 1240 | f 260//260 47//47 257//257 1241 | f 264//264 48//48 265//265 1242 | f 259//259 243//243 261//261 1243 | f 262//262 82//82 261//261 1244 | f 261//261 256//256 262//262 1245 | f 263//263 82//82 262//262 1246 | f 262//262 253//253 263//263 1247 | f 264//264 82//82 263//263 1248 | f 265//265 260//260 264//264 1249 | f 264//264 120//120 48//48 1250 | f 265//265 47//47 260//260 1251 | f 265//265 311//311 47//47 1252 | f 131//131 116//116 266//266 1253 | f 266//266 270//270 34//34 1254 | f 236//236 214//214 267//267 1255 | f 268//268 83//83 269//269 1256 | f 269//269 267//267 268//268 1257 | f 270//270 83//83 268//268 1258 | f 269//269 36//36 267//267 1259 | f 269//269 240//240 36//36 1260 | f 268//268 222//222 270//270 1261 | f 271//271 83//83 270//270 1262 | f 270//270 266//266 271//271 1263 | f 273//273 37//37 272//272 1264 | f 272//272 83//83 271//271 1265 | f 274//274 83//83 272//272 1266 | f 272//272 271//271 273//273 1267 | f 273//273 280//280 37//37 1268 | f 274//274 35//35 240//240 1269 | f 274//274 118//118 35//35 1270 | f 122//122 119//119 275//275 1271 | f 275//275 279//279 40//40 1272 | f 276//276 42//42 201//201 1273 | f 277//277 84//84 278//278 1274 | f 278//278 276//276 277//277 1275 | f 279//279 84//84 277//277 1276 | f 278//278 42//42 276//276 1277 | f 278//278 209//209 42//42 1278 | f 277//277 255//255 279//279 1279 | f 280//280 84//84 279//279 1280 | f 279//279 275//275 280//280 1281 | f 281//281 84//84 280//280 1282 | f 280//280 273//273 281//281 1283 | f 282//282 84//84 281//281 1284 | f 282//282 41//41 209//209 1285 | f 282//282 115//115 41//41 1286 | f 283//283 44//44 139//139 1287 | f 283//283 289//289 44//44 1288 | f 283//283 139//139 284//284 1289 | f 306//306 50//50 284//284 1290 | f 286//286 180//180 285//285 1291 | f 287//287 85//85 288//288 1292 | f 286//286 11//11 180//180 1293 | f 286//286 327//327 11//11 1294 | f 288//288 285//285 287//287 1295 | f 289//289 85//85 287//287 1296 | f 288//288 63//63 285//285 1297 | f 293//293 64//64 294//294 1298 | f 287//287 188//188 289//289 1299 | f 290//290 85//85 289//289 1300 | f 289//289 283//283 290//290 1301 | f 292//292 49//49 291//291 1302 | f 291//291 85//85 290//290 1303 | f 293//293 85//85 291//291 1304 | f 291//291 290//290 292//292 1305 | f 292//292 308//308 49//49 1306 | f 294//294 288//288 293//293 1307 | f 293//293 112//112 64//64 1308 | f 294//294 63//63 288//288 1309 | f 294//294 348//348 63//63 1310 | f 295//295 51//51 105//105 1311 | f 295//295 300//300 51//51 1312 | f 296//296 71//71 93//93 1313 | f 298//298 86//86 299//299 1314 | f 296//296 93//93 297//297 1315 | f 307//307 52//52 297//297 1316 | f 299//299 296//296 298//298 1317 | f 301//301 51//51 300//300 1318 | f 299//299 71//71 296//296 1319 | f 304//304 72//72 305//305 1320 | f 300//300 86//86 298//298 1321 | f 302//302 86//86 300//300 1322 | f 300//300 298//298 301//301 1323 | f 309//309 87//87 313//313 1324 | f 300//300 295//295 302//302 1325 | f 303//303 86//86 302//302 1326 | f 302//302 197//197 303//303 1327 | f 304//304 86//86 303//303 1328 | f 305//305 299//299 304//304 1329 | f 304//304 109//109 72//72 1330 | f 305//305 71//71 299//299 1331 | f 358//358 92//92 362//362 1332 | f 284//284 258//258 306//306 1333 | f 306//306 310//310 50//50 1334 | f 297//297 113//113 307//307 1335 | f 308//308 87//87 309//309 1336 | f 309//309 307//307 308//308 1337 | f 310//310 87//87 308//308 1338 | f 309//309 52//52 307//307 1339 | f 309//309 301//301 52//52 1340 | f 308//308 292//292 310//310 1341 | f 311//311 87//87 310//310 1342 | f 310//310 306//306 311//311 1343 | f 312//312 87//87 311//311 1344 | f 311//311 265//265 312//312 1345 | f 313//313 87//87 312//312 1346 | f 313//313 51//51 301//301 1347 | f 313//313 106//106 51//51 1348 | f 314//314 54//54 144//144 1349 | f 314//314 320//320 54//54 1350 | f 314//314 144//144 315//315 1351 | f 339//339 62//62 315//315 1352 | f 317//317 151//151 316//316 1353 | f 318//318 88//88 319//319 1354 | f 317//317 10//10 151//151 1355 | f 317//317 108//108 10//10 1356 | f 319//319 316//316 318//318 1357 | f 320//320 88//88 318//318 1358 | f 319//319 69//69 316//316 1359 | f 324//324 70//70 325//325 1360 | f 318//318 161//161 320//320 1361 | f 321//321 88//88 320//320 1362 | f 320//320 314//314 321//321 1363 | f 323//323 61//61 322//322 1364 | f 322//322 88//88 321//321 1365 | f 324//324 88//88 322//322 1366 | f 322//322 321//321 323//323 1367 | f 341//341 90//90 345//345 1368 | f 325//325 319//319 324//324 1369 | f 324//324 104//104 70//70 1370 | f 325//325 69//69 319//319 1371 | f 325//325 357//357 69//69 1372 | f 326//326 56//56 164//164 1373 | f 326//326 332//332 56//56 1374 | f 326//326 164//164 327//327 1375 | f 347//347 66//66 327//327 1376 | f 329//329 143//143 328//328 1377 | f 330//330 89//89 331//331 1378 | f 329//329 7//7 143//143 1379 | f 329//329 128//128 7//7 1380 | f 331//331 328//328 330//330 1381 | f 332//332 89//89 330//330 1382 | f 331//331 57//57 328//328 1383 | f 336//336 58//58 337//337 1384 | f 330//330 174//174 332//332 1385 | f 333//333 89//89 332//332 1386 | f 332//332 326//326 333//333 1387 | f 335//335 65//65 334//334 1388 | f 334//334 89//89 333//333 1389 | f 336//336 89//89 334//334 1390 | f 334//334 333//333 335//335 1391 | f 349//349 91//91 354//354 1392 | f 337//337 331//331 336//336 1393 | f 336//336 102//102 58//58 1394 | f 337//337 57//57 331//331 1395 | f 337//337 343//343 57//57 1396 | f 338//338 60//60 128//128 1397 | f 338//338 342//342 60//60 1398 | f 315//315 225//225 339//339 1399 | f 340//340 90//90 341//341 1400 | f 341//341 339//339 340//340 1401 | f 342//342 90//90 340//340 1402 | f 341//341 62//62 339//339 1403 | f 341//341 323//323 62//62 1404 | f 340//340 232//232 342//342 1405 | f 343//343 90//90 342//342 1406 | f 342//342 338//338 343//343 1407 | f 344//344 90//90 343//343 1408 | f 343//343 337//337 344//344 1409 | f 345//345 90//90 344//344 1410 | f 345//345 61//61 323//323 1411 | f 345//345 100//100 61//61 1412 | f 111//111 95//95 346//346 1413 | f 346//346 350//350 64//64 1414 | f 327//327 286//286 347//347 1415 | f 348//348 91//91 349//349 1416 | f 349//349 347//347 348//348 1417 | f 350//350 91//91 348//348 1418 | f 349//349 66//66 347//347 1419 | f 349//349 335//335 66//66 1420 | f 348//348 294//294 350//350 1421 | f 351//351 91//91 350//350 1422 | f 350//350 346//346 351//351 1423 | f 353//353 67//67 352//352 1424 | f 352//352 91//91 351//351 1425 | f 354//354 91//91 352//352 1426 | f 352//352 351//351 353//353 1427 | f 353//353 360//360 67//67 1428 | f 354//354 65//65 335//335 1429 | f 354//354 97//97 65//65 1430 | f 103//103 98//98 355//355 1431 | f 355//355 359//359 70//70 1432 | f 356//356 72//72 108//108 1433 | f 357//357 92//92 358//358 1434 | f 358//358 356//356 357//357 1435 | f 359//359 92//92 357//357 1436 | f 358//358 72//72 356//356 1437 | f 358//358 305//305 72//72 1438 | f 357//357 325//325 359//359 1439 | f 360//360 92//92 359//359 1440 | f 359//359 355//355 360//360 1441 | f 361//361 92//92 360//360 1442 | f 360//360 353//353 361//361 1443 | f 362//362 92//92 361//361 1444 | f 362//362 71//71 305//305 1445 | f 362//362 94//94 71//71 1446 | -------------------------------------------------------------------------------- /test/test_collisions.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | 4 | from cymesh.mesh import Mesh 5 | from cymesh.collisions.tri_intersection import tri_tri_intersection 6 | from cymesh.collisions.findCollisions import findCollisions 7 | 8 | def brute_force_collisions(mesh): 9 | collided = np.zeros(len(mesh.verts), dtype='uint8') 10 | 11 | print(collided.shape) 12 | 13 | for face1 in mesh.faces: 14 | v1, v2, v3 = face1.vertices() 15 | for face2 in mesh.faces: 16 | v4, v5, v6 = face2.vertices() 17 | 18 | if v1.id == v4.id or v1.id == v5.id or v1.id == v6.id: 19 | continue 20 | 21 | elif v2.id == v4.id or v2.id == v5.id or v2.id == v6.id: 22 | continue 23 | 24 | elif v3.id == v4.id or v3.id == v5.id or v3.id == v6.id: 25 | continue 26 | 27 | if tri_tri_intersection(v1.p, v2.p, v3.p, v4.p, v5.p, v6.p): 28 | collided[v1.id] = 1 29 | collided[v2.id] = 1 30 | collided[v3.id] = 1 31 | collided[v4.id] = 1 32 | collided[v5.id] = 1 33 | collided[v6.id] = 1 34 | 35 | return collided 36 | 37 | class TestRandomlyDistribute(unittest.TestCase): 38 | def test(self): 39 | mesh = Mesh.from_obj('test/mesh_with_intersections.obj') 40 | 41 | brute_collisions = brute_force_collisions(mesh) 42 | speed_collisions = findCollisions(mesh) 43 | 44 | print(sum(brute_collisions)) 45 | print(sum(speed_collisions)) 46 | 47 | self.assertTrue((brute_collisions == speed_collisions).all()) 48 | 49 | if __name__ == '__main__': 50 | unittest.main() 51 | -------------------------------------------------------------------------------- /test/test_mesh.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import random 3 | from cymesh.mesh import Mesh 4 | 5 | class TestRandomlyDistribute(unittest.TestCase): 6 | def valdiate_mesh(self, mesh): 7 | fids = [face.id for face in mesh.faces] 8 | vids = [vert.id for vert in mesh.verts] 9 | eids = [edge.id for edge in mesh.edges] 10 | hids = [half.id for half in mesh.halfs] 11 | 12 | self.assertTrue(len(fids) == len(set(fids))) 13 | self.assertTrue(len(vids) == len(set(vids))) 14 | self.assertTrue(len(eids) == len(set(eids))) 15 | self.assertTrue(len(hids) == len(set(hids))) 16 | 17 | for vert in mesh.verts: 18 | self.assertTrue(mesh.verts[vert.id] is vert) 19 | self.assertTrue(vert.he is not None) 20 | 21 | for edge in mesh.edges: 22 | self.assertTrue(mesh.edges[edge.id] is edge) 23 | self.assertTrue(edge.he is not None) 24 | 25 | for face in mesh.faces: 26 | self.assertTrue(mesh.faces[face.id] is face) 27 | self.assertTrue(face.he is not None) 28 | 29 | for he in mesh.halfs: 30 | self.assertTrue(mesh.halfs[he.id] is he) 31 | self.assertTrue(he.twin is not None) 32 | self.assertTrue(he.next is not None) 33 | self.assertTrue(he.vert is not None) 34 | self.assertTrue(he.edge is not None) 35 | self.assertTrue(he.face is not None) 36 | 37 | for vert in mesh.verts: 38 | vert_faces = set(vert.faces()) 39 | vert_neighbors = set(vert.neighbors()) 40 | 41 | self.assertTrue(len(vert_faces) > 2) 42 | self.assertTrue(len(vert_neighbors) > 2) 43 | 44 | for face in mesh.faces: 45 | if face in vert_faces: 46 | self.assertTrue(vert in face.vertices()) 47 | else: 48 | self.assertTrue(vert not in face.vertices()) 49 | 50 | for vert2 in mesh.verts: 51 | if vert2 in vert_neighbors: 52 | self.assertTrue(vert in vert2.neighbors()) 53 | else: 54 | self.assertTrue(vert not in vert2.neighbors()) 55 | 56 | for face in mesh.faces: 57 | face_vertices = set(face.vertices()) 58 | self.assertTrue(len(face_vertices) > 0) 59 | 60 | for vert in mesh.verts: 61 | if vert in face_vertices: 62 | self.assertTrue(face in vert.faces()) 63 | else: 64 | self.assertTrue(face not in vert.faces()) 65 | 66 | def test_from_obj(self): 67 | mesh = Mesh.from_obj('triangulated_sphere_2.obj') 68 | self.valdiate_mesh(mesh) 69 | 70 | def test_split_edges(self): 71 | mesh = Mesh.from_obj('triangulated_sphere_2.obj') 72 | mesh.splitEdges() 73 | self.valdiate_mesh(mesh) 74 | 75 | def test_flip_edges(self): 76 | mesh = Mesh.from_obj('triangulated_sphere_2.obj') 77 | mesh.splitEdges() 78 | mesh.shortenEdges() 79 | self.valdiate_mesh(mesh) 80 | 81 | def test_sudivisions(self): 82 | mesh = Mesh.from_obj('triangulated_sphere_2.obj') 83 | for _ in range(2): 84 | mesh.splitEdges() 85 | mesh.shortenEdges() 86 | self.valdiate_mesh(mesh) 87 | 88 | 89 | def test_modify(self): 90 | mesh = Mesh.from_obj('triangulated_sphere_2.obj') 91 | for _ in range(1): 92 | for v in mesh.verts: 93 | v.p[0] += (random.random()-.5) * .2 94 | v.p[1] += (random.random()-.5) * .2 95 | v.p[2] += (random.random()-.5) * .2 96 | mesh.splitEdges() 97 | mesh.shortenEdges() 98 | self.valdiate_mesh(mesh) 99 | 100 | if __name__ == '__main__': 101 | unittest.main() 102 | -------------------------------------------------------------------------------- /test/test_tri_intersection.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | from cymesh.collisions.tri_intersection import tri_tri_intersection 4 | 5 | def intersect(tri_a, tri_b): 6 | tri_a = np.array(tri_a) 7 | tri_b = np.array(tri_b) 8 | return tri_tri_intersection(tri_a[0], tri_a[1], tri_a[2], 9 | tri_b[0], tri_b[1], tri_b[2],) 10 | class TestRandomlyDistribute(unittest.TestCase): 11 | def test_intersecting_1(self): 12 | inter_tri_a = [[-2.086964, 1.219437, -0.480749], 13 | [0.105598, -1.323423, 0.293974], 14 | [0.105598, 1.219437, -0.480749]] 15 | 16 | inter_tri_b = [[-3.696262, 0.634013, -1.157567], 17 | [0.716440, -0.634013, 1.178764], 18 | [-1.503700, 0.634013, -1.157567]] 19 | 20 | self.assertTrue(intersect(inter_tri_a, inter_tri_b)) 21 | 22 | def test_non_intersecting_1(self): 23 | non_inter_tri_a = [[-1.152708, 0.000000, -1.318530], 24 | [1.039854, -0.000000, 1.339728], 25 | [1.039854, 0.000000, -1.318530]] 26 | 27 | non_inter_tri_b = [[-3.696262, 0.000000, -1.318530], 28 | [0.716440, -0.000000, 1.339728], 29 | [-1.503700, 0.000000, -1.318530]] 30 | 31 | self.assertFalse(intersect(non_inter_tri_a, non_inter_tri_b)) 32 | 33 | def test_non_intersecting_2(self): 34 | non_inter_tri_a = [[-0.543499, 0.512505, -0.022], 35 | [-0.4708595, 0.596209, -0.098856], 36 | [-0.543499, 0.512505, -0.175722]] 37 | 38 | non_inter_tri_b = [[-0.48288, 0.4783765, 0.2770005], 39 | [-0.419127, 0.589371, 0.179248], 40 | [-0.543499, 0.512505, 0.131742]] 41 | 42 | self.assertFalse(intersect(non_inter_tri_a, non_inter_tri_b)) 43 | 44 | if __name__ == '__main__': 45 | unittest.main() 46 | -------------------------------------------------------------------------------- /time_load.py: -------------------------------------------------------------------------------- 1 | import time 2 | from cymesh.mesh import Mesh 3 | 4 | start = time.time() 5 | mesh = Mesh.from_obj('/Users/joelsimon/Projects/coral_growth_all/outputs/batch24/1RLV__February_16_2018_14_38/12/0/80.coral.obj') 6 | print(time.time() - start) 7 | -------------------------------------------------------------------------------- /triangulated_sphere_2.obj: -------------------------------------------------------------------------------- 1 | # This file uses centimeters as units for non-parametric coordinates. 2 | 3 | v 0.701903 -0.000000 -0.442199 4 | v 0.701903 -0.000000 0.398220 5 | v -0.657923 0.000000 0.398220 6 | v -0.657923 0.000000 -0.442199 7 | v 0.021990 -0.420209 0.657923 8 | v 0.021990 0.420209 0.657923 9 | v 0.021990 0.420209 -0.701903 10 | v 0.021990 -0.420209 -0.701903 11 | v -0.398220 -0.679913 -0.021990 12 | v 0.442199 -0.679913 -0.021990 13 | v 0.442199 0.679913 -0.021990 14 | v -0.398220 0.679913 -0.021990 15 | v 0.185003 0.761248 -0.021990 16 | v -0.141023 0.761248 -0.021990 17 | v -0.141023 -0.761248 -0.021990 18 | v 0.185003 -0.761248 -0.021990 19 | v -0.131742 -0.565489 -0.534494 20 | v -0.294755 -0.666237 -0.270734 21 | v -0.294755 0.666237 -0.270734 22 | v -0.131742 0.565489 -0.534494 23 | v -0.490515 0.153732 -0.587479 24 | v -0.226754 0.316745 -0.688227 25 | v -0.226754 -0.316745 -0.688227 26 | v -0.490515 -0.153732 -0.587479 27 | v -0.131742 0.565489 0.490515 28 | v -0.294755 0.666237 0.226754 29 | v -0.294755 -0.666237 0.226754 30 | v -0.131742 -0.565489 0.490515 31 | v -0.490515 -0.153732 0.543499 32 | v -0.226754 -0.316745 0.644247 33 | v -0.226754 0.316745 0.644247 34 | v -0.490515 0.153732 0.543499 35 | v -0.543499 0.512505 -0.175722 36 | v -0.644247 0.248744 -0.338735 37 | v -0.644247 0.248744 0.294755 38 | v -0.543499 0.512505 0.131742 39 | v -0.739259 0.000000 0.141023 40 | v -0.739259 -0.000000 -0.185003 41 | v -0.543499 -0.512505 0.131742 42 | v -0.644247 -0.248744 0.294755 43 | v -0.644247 -0.248744 -0.338735 44 | v -0.543499 -0.512505 -0.175722 45 | v 0.338735 0.666237 0.226754 46 | v 0.175722 0.565489 0.490515 47 | v 0.175722 -0.565489 0.490515 48 | v 0.338735 -0.666237 0.226754 49 | v 0.021990 0.163013 0.739259 50 | v 0.021990 -0.163013 0.739259 51 | v 0.534494 0.153732 0.543499 52 | v 0.270734 0.316745 0.644247 53 | v 0.270734 -0.316745 0.644247 54 | v 0.534495 -0.153732 0.543499 55 | v 0.338735 -0.666237 -0.270734 56 | v 0.175722 -0.565489 -0.534494 57 | v 0.175722 0.565489 -0.534494 58 | v 0.338735 0.666237 -0.270734 59 | v 0.270734 0.316745 -0.688227 60 | v 0.534494 0.153732 -0.587479 61 | v 0.021990 -0.163013 -0.783238 62 | v 0.021990 0.163013 -0.783238 63 | v 0.534494 -0.153732 -0.587479 64 | v 0.270734 -0.316745 -0.688227 65 | v 0.587479 0.512505 0.131742 66 | v 0.688227 0.248744 0.294755 67 | v 0.688227 0.248744 -0.338735 68 | v 0.587479 0.512505 -0.175722 69 | v 0.783238 0.000000 -0.185003 70 | v 0.783238 0.000000 0.141023 71 | v 0.587479 -0.512505 -0.175722 72 | v 0.688227 -0.248744 -0.338735 73 | v 0.688227 -0.248744 0.294755 74 | v 0.587479 -0.512505 0.131742 75 | v 0.021990 -0.718809 -0.296550 76 | v 0.021990 0.718809 -0.296550 77 | v 0.021990 0.718809 0.252571 78 | v 0.021990 -0.718809 0.252571 79 | v -0.422259 -0.444248 -0.466238 80 | v -0.422259 0.444248 -0.466238 81 | v -0.252571 -0.000000 -0.740799 82 | v -0.422259 0.444248 0.422259 83 | v -0.422259 -0.444248 0.422259 84 | v -0.252571 0.000000 0.696819 85 | v -0.696819 0.274561 -0.021990 86 | v -0.696819 -0.274561 -0.021990 87 | v 0.466238 0.444248 0.422259 88 | v 0.466238 -0.444248 0.422259 89 | v 0.296550 -0.000000 0.696819 90 | v 0.466238 -0.444248 -0.466238 91 | v 0.466238 0.444248 -0.466238 92 | v 0.296550 -0.000000 -0.740799 93 | v 0.740799 0.274561 -0.021990 94 | v 0.740799 -0.274561 -0.021990 95 | vt 0.181818 0.250000 96 | vt 0.363636 0.250000 97 | vt 0.545455 0.250000 98 | vt 0.727273 0.250000 99 | vt 0.909091 0.250000 100 | vt 0.090909 0.416667 101 | vt 0.272727 0.416667 102 | vt 0.454545 0.416667 103 | vt 0.636364 0.416667 104 | vt 0.818182 0.416667 105 | vt 1.000000 0.416667 106 | vt 0.000000 0.583333 107 | vt 0.181818 0.583333 108 | vt 0.363636 0.583333 109 | vt 0.545455 0.583333 110 | vt 0.727273 0.583333 111 | vt 0.909091 0.583333 112 | vt 0.090909 0.750000 113 | vt 0.272727 0.750000 114 | vt 0.454545 0.750000 115 | vt 0.636364 0.750000 116 | vt 0.818182 0.750000 117 | vt 0.848485 0.361111 118 | vt 0.787879 0.361111 119 | vt 0.878788 0.305556 120 | vt 0.757576 0.305556 121 | vt 0.333333 0.638889 122 | vt 0.393939 0.638889 123 | vt 0.303030 0.694444 124 | vt 0.424242 0.694444 125 | vt 0.484848 0.583333 126 | vt 0.424242 0.583333 127 | vt 0.575758 0.305556 128 | vt 0.696970 0.305556 129 | vt 0.606061 0.361111 130 | vt 0.666667 0.361111 131 | vt 0.515152 0.416667 132 | vt 0.575758 0.416667 133 | vt 0.515152 0.527778 134 | vt 0.484848 0.472222 135 | vt 0.121212 0.361111 136 | vt 0.969697 0.361111 137 | vt 0.151515 0.305556 138 | vt 0.939394 0.305556 139 | vt 0.303030 0.583333 140 | vt 0.242424 0.583333 141 | vt 0.242424 0.472222 142 | vt 0.212121 0.527778 143 | vt 0.151515 0.416667 144 | vt 0.212121 0.416667 145 | vt 0.393939 0.305556 146 | vt 0.515152 0.305556 147 | vt 0.424242 0.361111 148 | vt 0.484848 0.361111 149 | vt 0.303030 0.361111 150 | vt 0.242424 0.361111 151 | vt 0.333333 0.305556 152 | vt 0.212121 0.305556 153 | vt 0.333333 0.416667 154 | vt 0.393939 0.416667 155 | vt 0.333333 0.527778 156 | vt 0.303030 0.472222 157 | vt 0.424242 0.472222 158 | vt 0.393939 0.527778 159 | vt 0.878788 0.416667 160 | vt 0.939394 0.416667 161 | vt 0.151515 0.638889 162 | vt 0.212121 0.638889 163 | vt 0.121212 0.694444 164 | vt 0.242424 0.694444 165 | vt 0.121212 0.472222 166 | vt 0.151515 0.527778 167 | vt 0.030303 0.527778 168 | vt 0.939394 0.527778 169 | vt 0.060606 0.472222 170 | vt 0.969697 0.472222 171 | vt 0.121212 0.583333 172 | vt 0.060606 0.583333 173 | vt 0.606061 0.694444 174 | vt 0.484848 0.694444 175 | vt 0.575758 0.638889 176 | vt 0.515152 0.638889 177 | vt 0.696970 0.416667 178 | vt 0.757576 0.416667 179 | vt 0.666667 0.472222 180 | vt 0.696970 0.527778 181 | vt 0.575758 0.527778 182 | vt 0.606061 0.472222 183 | vt 0.666667 0.583333 184 | vt 0.606061 0.583333 185 | vt 0.848485 0.472222 186 | vt 0.878788 0.527778 187 | vt 0.757576 0.527778 188 | vt 0.787879 0.472222 189 | vt 0.787879 0.583333 190 | vt 0.848485 0.583333 191 | vt 0.787879 0.694444 192 | vt 0.666667 0.694444 193 | vt 0.757576 0.638889 194 | vt 0.696970 0.638889 195 | vt 0.878788 0.638889 196 | vt 0.030303 0.638889 197 | vt 0.848485 0.694444 198 | vt 0.060606 0.694444 199 | vt 0.454545 0.638889 200 | vt 0.727273 0.361111 201 | vt 0.909091 0.361111 202 | vt 0.272727 0.638889 203 | vt 0.454545 0.527778 204 | vt 0.545455 0.361111 205 | vt 0.545455 0.472222 206 | vt 0.181818 0.361111 207 | vt 0.272727 0.527778 208 | vt 0.181818 0.472222 209 | vt 0.363636 0.361111 210 | vt 0.363636 0.472222 211 | vt 0.909091 0.472222 212 | vt 0.090909 0.638889 213 | vt 0.090909 0.527778 214 | vt 0.636364 0.638889 215 | vt 0.727273 0.472222 216 | vt 0.636364 0.527778 217 | vt 0.818182 0.527778 218 | vt 0.818182 0.638889 219 | f 2/17 71/101 68/96 220 | f 1/16 65/93 67/95 221 | f 1/16 61/89 58/86 222 | f 1/16 58/86 65/93 223 | f 1/16 70/100 61/89 224 | f 5/13 51/77 48/72 225 | f 10/18 72/104 46/69 226 | f 2/17 64/92 49/74 227 | f 4/8 41/63 38/60 228 | f 3/7 35/55 37/59 229 | f 5/13 48/72 30/48 230 | f 3/7 40/62 29/47 231 | f 6/6 25/41 31/49 232 | f 7/9 60/88 22/38 233 | f 4/8 34/54 21/37 234 | f 4/8 24/40 41/63 235 | f 5/13 28/46 45/68 236 | f 6/11 44/66 25/42 237 | f 7/9 20/36 55/83 238 | f 8/15 54/82 17/31 239 | f 18/32 15/28 9/14 240 | f 16/30 53/80 10/20 241 | f 16/30 73/105 53/80 242 | f 15/28 73/105 16/30 243 | f 18/32 73/105 15/28 244 | f 17/31 73/105 18/32 245 | f 73/105 54/82 53/80 246 | f 17/31 54/82 73/105 247 | f 56/84 13/24 11/10 248 | f 14/26 19/34 12/4 249 | f 14/26 74/106 19/34 250 | f 13/24 74/106 14/26 251 | f 56/84 74/106 13/24 252 | f 55/83 74/106 56/84 253 | f 74/106 20/36 19/34 254 | f 55/83 20/36 74/106 255 | f 26/44 14/25 12/5 256 | f 13/23 43/65 11/10 257 | f 13/23 75/107 43/65 258 | f 14/25 75/107 13/23 259 | f 26/44 75/107 14/25 260 | f 25/42 75/107 26/44 261 | f 75/107 44/66 43/65 262 | f 25/42 44/66 75/107 263 | f 46/70 16/29 10/19 264 | f 15/27 27/45 9/14 265 | f 15/27 76/108 27/45 266 | f 16/29 76/108 15/27 267 | f 46/70 76/108 16/29 268 | f 45/68 76/108 46/70 269 | f 76/108 28/46 27/45 270 | f 45/68 28/46 76/108 271 | f 42/64 18/32 9/14 272 | f 17/31 23/39 8/15 273 | f 17/31 77/109 23/39 274 | f 18/32 77/109 17/31 275 | f 42/64 77/109 18/32 276 | f 41/63 77/109 42/64 277 | f 77/109 24/40 23/39 278 | f 41/63 24/40 77/109 279 | f 22/38 20/35 7/9 280 | f 19/33 33/52 12/3 281 | f 19/33 78/110 33/52 282 | f 20/35 78/110 19/33 283 | f 22/38 78/110 20/35 284 | f 21/37 78/110 22/38 285 | f 78/110 34/54 33/52 286 | f 21/37 34/54 78/110 287 | f 21/37 24/40 4/8 288 | f 23/39 59/87 8/15 289 | f 23/39 79/111 59/87 290 | f 24/40 79/111 23/39 291 | f 21/37 79/111 24/40 292 | f 22/38 79/111 21/37 293 | f 79/111 60/88 59/87 294 | f 22/38 60/88 79/111 295 | f 32/50 35/56 3/7 296 | f 36/58 26/43 12/1 297 | f 36/58 80/112 26/43 298 | f 35/56 80/112 36/58 299 | f 32/50 80/112 35/56 300 | f 31/49 80/112 32/50 301 | f 80/112 25/41 26/43 302 | f 31/49 25/41 80/112 303 | f 30/48 28/46 5/13 304 | f 27/45 39/61 9/14 305 | f 27/45 81/113 39/61 306 | f 28/46 81/113 27/45 307 | f 30/48 81/113 28/46 308 | f 29/47 81/113 30/48 309 | f 81/113 40/62 39/61 310 | f 29/47 40/62 81/113 311 | f 29/47 32/50 3/7 312 | f 31/49 47/71 6/6 313 | f 31/49 82/114 47/71 314 | f 32/50 82/114 31/49 315 | f 29/47 82/114 32/50 316 | f 30/48 82/114 29/47 317 | f 82/114 48/72 47/71 318 | f 30/48 48/72 82/114 319 | f 38/60 34/53 4/8 320 | f 33/51 36/57 12/2 321 | f 33/51 83/115 36/57 322 | f 34/53 83/115 33/51 323 | f 38/60 83/115 34/53 324 | f 37/59 83/115 38/60 325 | f 83/115 35/55 36/57 326 | f 37/59 35/55 83/115 327 | f 37/59 40/62 3/7 328 | f 39/61 42/64 9/14 329 | f 39/61 84/116 42/64 330 | f 40/62 84/116 39/61 331 | f 37/59 84/116 40/62 332 | f 38/60 84/116 37/59 333 | f 84/116 41/63 42/64 334 | f 38/60 41/63 84/116 335 | f 50/76 44/66 6/11 336 | f 43/65 63/91 11/10 337 | f 43/65 85/117 63/91 338 | f 44/66 85/117 43/65 339 | f 50/76 85/117 44/66 340 | f 49/74 85/117 50/76 341 | f 85/117 64/92 63/91 342 | f 49/74 64/92 85/117 343 | f 45/67 51/77 5/13 344 | f 52/78 71/102 2/12 345 | f 52/78 86/118 71/102 346 | f 51/77 86/118 52/78 347 | f 45/67 86/118 51/77 348 | f 46/69 86/118 45/67 349 | f 86/118 72/104 71/102 350 | f 46/69 72/104 86/118 351 | f 47/71 50/75 6/6 352 | f 49/73 52/78 2/12 353 | f 49/73 87/119 52/78 354 | f 50/75 87/119 49/73 355 | f 47/71 87/119 50/75 356 | f 48/72 87/119 47/71 357 | f 87/119 51/77 52/78 358 | f 48/72 51/77 87/119 359 | f 62/90 54/81 8/15 360 | f 53/79 69/98 10/21 361 | f 53/79 88/120 69/98 362 | f 54/81 88/120 53/79 363 | f 62/90 88/120 54/81 364 | f 61/89 88/120 62/90 365 | f 88/120 70/100 69/98 366 | f 61/89 70/100 88/120 367 | f 66/94 56/84 11/10 368 | f 55/83 57/85 7/9 369 | f 55/83 89/121 57/85 370 | f 56/84 89/121 55/83 371 | f 66/94 89/121 56/84 372 | f 65/93 89/121 66/94 373 | f 89/121 58/86 57/85 374 | f 65/93 58/86 89/121 375 | f 57/85 60/88 7/9 376 | f 59/87 62/90 8/15 377 | f 59/87 90/122 62/90 378 | f 60/88 90/122 59/87 379 | f 57/85 90/122 60/88 380 | f 58/86 90/122 57/85 381 | f 90/122 61/89 62/90 382 | f 58/86 61/89 90/122 383 | f 68/96 64/92 2/17 384 | f 63/91 66/94 11/10 385 | f 63/91 91/123 66/94 386 | f 64/92 91/123 63/91 387 | f 68/96 91/123 64/92 388 | f 67/95 91/123 68/96 389 | f 91/123 65/93 66/94 390 | f 67/95 65/93 91/123 391 | f 67/95 70/99 1/16 392 | f 69/97 72/103 10/22 393 | f 69/97 92/124 72/103 394 | f 70/99 92/124 69/97 395 | f 67/95 92/124 70/99 396 | f 68/96 92/124 67/95 397 | f 92/124 71/101 72/103 398 | f 68/96 71/101 92/124 399 | --------------------------------------------------------------------------------