├── test_objs ├── zilla_dif.png ├── aobaker_suzanne.png ├── cube.obj ├── cube2.obj ├── cube_mtl.obj ├── icosphere_posOnly.obj ├── cylinder.obj └── suzanne.obj ├── .gitignore ├── tk_objfile.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── tk_objfile.xcscmblueprint └── project.pbxproj ├── objviewer ├── README.md ├── imgui_impl_glfw_gl3.h ├── imgui_impl_glfw_gl3.cpp └── objviewer.cpp ├── LICENSE.md ├── examples └── example_bbox.cpp ├── README.md └── tk_objfile.h /test_objs/zilla_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeld42/tk_objfile/HEAD/test_objs/zilla_dif.png -------------------------------------------------------------------------------- /test_objs/aobaker_suzanne.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeld42/tk_objfile/HEAD/test_objs/aobaker_suzanne.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | imgui.ini 3 | tk_objfile.xcodeproj/project.xcworkspace/xcuserdata/ 4 | tk_objfile.xcodeproj/xcuserdata/ 5 | Ajax_Jotero_com.obj -------------------------------------------------------------------------------- /tk_objfile.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objviewer/README.md: -------------------------------------------------------------------------------- 1 | # OBJViewer 2 | 3 | This is a craptastic OBJ file viewer based on a hacked up version of 4 | the IMGUI example. In particular, it is missing useful build files, the 5 | xcode project is pretty specific to my setup, so it will probably take 6 | some work to get this to build, but I figured it was better to include 7 | it even though it's not packaged up nicely than to leave it out. 8 | 9 | I need to make a cmakefile or something eventually. Pull requests are 10 | welcome. :) -------------------------------------------------------------------------------- /test_objs/cube.obj: -------------------------------------------------------------------------------- 1 | 2 | # Blender v2.75 (sub 0) OBJ File: '' 3 | # www.blender.org 4 | # this shouldn't be counted if they are in a comment 5 | # vvv vt vvv vn vnv vn vn vn vn vt vt vt vt v v v v v v v 6 | mtllib cube.mtl 7 | 8 | 9 | o Cube 10 | v 1.000000 -1.000000 -1.000000 11 | v 1.000000 -1.000000 1.000000 12 | v -1.000000 -1.000000 1.000000 13 | v -1.000000 -1.000000 -1.000000 14 | 15 | v 1.000000 1.000000 -0.999999 16 | v 0.999999 1.000000 1.000001 17 | v -1.000000 1.000000 1.000000 18 | v -1.000000 001 -1 19 | vn 0.000000 -1.000000 0.000000 20 | vn 0.000000 1.000000 0.000000 21 | vn 1.000000 0.000000 0.000000 22 | vn -0.000000 -0.000000 1.000000 23 | vn -1.000000 -0.000000 -0.000000 24 | vn 0.000000 0.000000 -1.000000 25 | 26 | usemtl Material 27 | s off 28 | 29 | f 1//1 2//1 3//1 4//1 30 | f 5//2 8//2 7//2 6//2 31 | f 1//3 5//3 6//3 2//3 32 | f 2//4 6//4 7//4 3//4 33 | f 3//5 7//5 8//5 4//5 34 | f 5//6 1//6 4//6 8//6 -------------------------------------------------------------------------------- /test_objs/cube2.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib cube2.mtl 4 | o Cube 5 | v 1.000000 -1.000000 -1.000000 6 | v 1.000000 -1.000000 1.000000 7 | v -1.000000 -1.000000 1.000000 8 | v -1.000000 -1.000000 -1.000000 9 | v 1.000000 1.000000 -0.999999 10 | v 0.999999 1.000000 1.000001 11 | v -1.000000 1.000000 1.000000 12 | v -1.000000 1.000000 -1.000000 13 | vt 0.000000 0.666667 14 | vt 0.333333 0.666667 15 | vt 0.333333 1.000000 16 | vt 0.000000 1.000000 17 | vt 0.666667 0.333333 18 | vt 0.666667 0.666667 19 | vt 0.333333 0.333333 20 | vt 0.333333 0.000000 21 | vt 0.666667 0.000000 22 | vt 0.000000 0.333333 23 | vt 0.000000 0.000000 24 | vt 1.000000 0.333333 25 | vt 1.000000 0.000000 26 | vn 0.000000 -1.000000 0.000000 27 | vn 0.000000 1.000000 0.000000 28 | vn 1.000000 0.000000 0.000000 29 | vn -0.000000 -0.000000 1.000000 30 | vn -1.000000 -0.000000 -0.000000 31 | vn 0.000000 0.000000 -1.000000 32 | usemtl Material 33 | s off 34 | f 1/1/1 2/2/1 3/3/1 4/4/1 35 | f 5/5/2 8/6/2 7/2/2 6/7/2 36 | f 1/5/3 5/7/3 6/8/3 2/9/3 37 | f 2/10/4 6/11/4 7/8/4 3/7/4 38 | f 3/12/5 7/5/5 8/9/5 4/13/5 39 | f 5/10/6 1/7/6 4/2/6 8/1/6 40 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Joel Davis (aka Tapnik Software) 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 | 23 | -------------------------------------------------------------------------------- /test_objs/cube_mtl.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib cube2.mtl 4 | o Cube 5 | v 1.000000 -1.000000 -1.000000 6 | v 1.000000 -1.000000 1.000000 7 | v -1.000000 -1.000000 1.000000 8 | v -1.000000 -1.000000 -1.000000 9 | v 1.000000 1.000000 -0.999999 10 | v 0.999999 1.000000 1.000001 11 | v -1.000000 1.000000 1.000000 12 | v -1.000000 1.000000 -1.000000 13 | vt 0.000000 0.666667 14 | vt 0.333333 0.666667 15 | vt 0.333333 1.000000 16 | vt 0.000000 1.000000 17 | vt 0.666667 0.333333 18 | vt 0.666667 0.666667 19 | vt 0.333333 0.333333 20 | vt 0.333333 0.000000 21 | vt 0.666667 0.000000 22 | vt 0.000000 0.333333 23 | vt 0.000000 0.000000 24 | vt 1.000000 0.333333 25 | vt 1.000000 0.000000 26 | vn 0.000000 -1.000000 0.000000 27 | vn 0.000000 1.000000 0.000000 28 | vn 1.000000 0.000000 0.000000 29 | vn -0.000000 -0.000000 1.000000 30 | vn -1.000000 -0.000000 -0.000000 31 | vn 0.000000 0.000000 -1.000000 32 | usemtl mtl.A 33 | s off 34 | usemtl mtl.A 35 | f 1/1/1 2/2/1 3/3/1 4/4/1 36 | 37 | usemtl mtl.B 38 | f 5/5/2 8/6/2 7/2/2 6/7/2 39 | usemtl mtl.A 40 | f 1/5/3 5/7/3 6/8/3 2/9/3 41 | usemtl mtl.C 42 | f 2/10/4 6/11/4 7/8/4 3/7/4 43 | usemtl mtl.A 44 | f 3/12/5 7/5/5 8/9/5 4/13/5 45 | usemtl mtl.D 46 | f 5/10/6 1/7/6 4/2/6 8/1/6 47 | usemtl mtl.E 48 | usemtl mtl.A 49 | -------------------------------------------------------------------------------- /objviewer/imgui_impl_glfw_gl3.h: -------------------------------------------------------------------------------- 1 | // ImGui GLFW binding with OpenGL3 + shaders 2 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 3 | // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). 4 | // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. 5 | // https://github.com/ocornut/imgui 6 | 7 | struct GLFWwindow; 8 | 9 | IMGUI_API bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks); 10 | IMGUI_API void ImGui_ImplGlfwGL3_Shutdown(); 11 | IMGUI_API void ImGui_ImplGlfwGL3_NewFrame(); 12 | 13 | // Use if you want to reset your rendering device without losing ImGui state. 14 | IMGUI_API void ImGui_ImplGlfwGL3_InvalidateDeviceObjects(); 15 | IMGUI_API bool ImGui_ImplGlfwGL3_CreateDeviceObjects(); 16 | 17 | // GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) 18 | // Provided here if you want to chain callbacks. 19 | // You can also handle inputs yourself and use those as a reference. 20 | IMGUI_API void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); 21 | IMGUI_API void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); 22 | IMGUI_API void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); 23 | IMGUI_API void ImGui_ImplGlfwGL3_CharCallback(GLFWwindow* window, unsigned int c); 24 | 25 | // extra helper to get mouse pos 26 | void ImGui_ImplGlfwGL3_GetMousePos( double *mouse_x, double *mouse_y, bool *mousePressed ); -------------------------------------------------------------------------------- /tk_objfile.xcodeproj/project.xcworkspace/xcshareddata/tk_objfile.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "D327893DEF5C2024B4914EDEB7D2DB07DB589146", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "D327893DEF5C2024B4914EDEB7D2DB07DB589146" : 0, 8 | "0C95EEA8FF0C0E695973CB8EA4E7E70E385D606F" : 0 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "870BE4CE-CBEC-4F32-91A1-5250D2406CAF", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "D327893DEF5C2024B4914EDEB7D2DB07DB589146" : "tk_objfile\/", 13 | "0C95EEA8FF0C0E695973CB8EA4E7E70E385D606F" : "..\/Toolkits\/imgui" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "tk_objfile", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "tk_objfile.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/ocornut\/imgui.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "0C95EEA8FF0C0E695973CB8EA4E7E70E385D606F" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:joeld42\/tk_objfile.git", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "D327893DEF5C2024B4914EDEB7D2DB07DB589146" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /test_objs/icosphere_posOnly.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib icosphere_posOnly.mtl 4 | v 0.375610 -0.000055 -0.085226 5 | v 1.099217 0.552725 0.440500 6 | v 0.099222 0.552725 0.765424 7 | v -0.518817 0.552729 -0.085226 8 | v 0.099222 0.552725 -0.935875 9 | v 1.099217 0.552725 -0.610951 10 | v 0.651998 1.447165 0.765424 11 | v -0.347998 1.447164 0.440500 12 | v -0.347998 1.447164 -0.610951 13 | v 0.651998 1.447165 -0.935875 14 | v 1.270036 1.447160 -0.085226 15 | v 0.375610 1.999945 -0.085226 16 | v 0.213154 0.149290 0.414770 17 | v 0.800932 0.149290 0.223786 18 | v 0.638478 0.474207 0.723786 19 | v 1.226257 0.474209 -0.085226 20 | v 0.800932 0.149290 -0.394237 21 | v -0.150120 0.149293 -0.085226 22 | v -0.312580 0.474208 0.414771 23 | v 0.213154 0.149290 -0.585221 24 | v -0.312580 0.474208 -0.585222 25 | v 0.638478 0.474207 -0.894237 26 | v 1.326667 0.999945 0.223787 27 | v 1.326667 0.999945 -0.394238 28 | v 0.375610 0.999945 0.914774 29 | v 0.963395 0.999945 0.723791 30 | v -0.575448 0.999945 0.223787 31 | v -0.212176 0.999945 0.723791 32 | v -0.212176 0.999945 -0.894242 33 | v -0.575448 0.999945 -0.394238 34 | v 0.963395 0.999945 -0.894242 35 | v 0.375610 0.999945 -1.085225 36 | v 1.063799 1.525681 0.414771 37 | v 0.112741 1.525682 0.723786 38 | v -0.475038 1.525681 -0.085226 39 | v 0.112741 1.525682 -0.894237 40 | v 1.063799 1.525681 -0.585222 41 | v 0.538065 1.850599 0.414770 42 | v 0.901339 1.850596 -0.085226 43 | v -0.049713 1.850599 0.223786 44 | v -0.049713 1.850599 -0.394237 45 | v 0.538065 1.850599 -0.585221 46 | usemtl None 47 | s off 48 | f 1 14 13 49 | f 2 14 16 50 | f 1 13 18 51 | f 1 18 20 52 | f 1 20 17 53 | f 2 16 23 54 | f 3 15 25 55 | f 4 19 27 56 | f 5 21 29 57 | f 6 22 31 58 | f 2 23 26 59 | f 3 25 28 60 | f 4 27 30 61 | f 5 29 32 62 | f 6 31 24 63 | f 7 33 38 64 | f 8 34 40 65 | f 9 35 41 66 | f 10 36 42 67 | f 11 37 39 68 | f 39 42 12 69 | f 39 37 42 70 | f 37 10 42 71 | f 42 41 12 72 | f 42 36 41 73 | f 36 9 41 74 | f 41 40 12 75 | f 41 35 40 76 | f 35 8 40 77 | f 40 38 12 78 | f 40 34 38 79 | f 34 7 38 80 | f 38 39 12 81 | f 38 33 39 82 | f 33 11 39 83 | f 24 37 11 84 | f 24 31 37 85 | f 31 10 37 86 | f 32 36 10 87 | f 32 29 36 88 | f 29 9 36 89 | f 30 35 9 90 | f 30 27 35 91 | f 27 8 35 92 | f 28 34 8 93 | f 28 25 34 94 | f 25 7 34 95 | f 26 33 7 96 | f 26 23 33 97 | f 23 11 33 98 | f 31 32 10 99 | f 31 22 32 100 | f 22 5 32 101 | f 29 30 9 102 | f 29 21 30 103 | f 21 4 30 104 | f 27 28 8 105 | f 27 19 28 106 | f 19 3 28 107 | f 25 26 7 108 | f 25 15 26 109 | f 15 2 26 110 | f 23 24 11 111 | f 23 16 24 112 | f 16 6 24 113 | f 17 22 6 114 | f 17 20 22 115 | f 20 5 22 116 | f 20 21 5 117 | f 20 18 21 118 | f 18 4 21 119 | f 18 19 4 120 | f 18 13 19 121 | f 13 3 19 122 | f 16 17 6 123 | f 16 14 17 124 | f 14 1 17 125 | f 13 15 3 126 | f 13 14 15 127 | f 14 2 15 128 | -------------------------------------------------------------------------------- /examples/example_bbox.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #define TK_OBJFILE_IMPLEMENTATION 7 | #include "tk_objfile.h" 8 | 9 | // Note: while tk_objfile doesn't use any cstdlib functions itself, we use them in the example 10 | // code to implement file loading, printing and allocation. 11 | 12 | // Compute the bounding box for an obj, to show how to use the simple "triangle soup" API. 13 | struct BoundingBox { 14 | float minPos[3]; 15 | float maxPos[3]; 16 | }; 17 | 18 | inline float minFloat( float a, float b) 19 | { 20 | if (a < b) return a; 21 | else return b; 22 | } 23 | 24 | inline float maxFloat( float a, float b) 25 | { 26 | if (a >= b) return a; 27 | else return b; 28 | } 29 | 30 | void bboxErrorMessage( size_t lineNum, const char *message, void *userData ) 31 | { 32 | printf("ERROR on line %zu: %s\n", lineNum, message ); 33 | } 34 | 35 | void bboxSwitchMaterial( const char *materialName, size_t numTriangles, void *userData ) 36 | { 37 | printf(">>> Current material: %s (%zu triangles)\n", materialName, numTriangles ); 38 | } 39 | 40 | void bboxProcessTriangle( TK_TriangleVert a, TK_TriangleVert b, TK_TriangleVert c, void *userData ) 41 | { 42 | BoundingBox *bbox = (BoundingBox*)userData; 43 | for (int i=0; i < 3; i++) { 44 | bbox->minPos[i] = minFloat( a.pos[i], bbox->minPos[i] ); 45 | bbox->maxPos[i] = maxFloat( a.pos[i], bbox->maxPos[i] ); 46 | } 47 | } 48 | 49 | void *readEntireFile( const char *filename, size_t *out_filesz ) 50 | { 51 | FILE *fp = fopen( filename, "r" ); 52 | if (!fp) return NULL; 53 | 54 | // Get file size 55 | fseek( fp, 0L, SEEK_END ); 56 | size_t filesz = ftell(fp); 57 | fseek( fp, 0L, SEEK_SET ); 58 | 59 | void *fileData = malloc( filesz ); 60 | if (fileData) 61 | { 62 | size_t result = fread( fileData, filesz, 1, fp ); 63 | 64 | // result is # of chunks read, we're asking for 1, fread 65 | // won't return partial reads, so it's all or nothing. 66 | if (!result) 67 | { 68 | free( fileData); 69 | fileData = NULL; 70 | } 71 | else 72 | { 73 | // read suceeded, set out filesize 74 | *out_filesz = filesz; 75 | } 76 | } 77 | 78 | return fileData; 79 | 80 | } 81 | 82 | int main(int argc, const char * argv[]) 83 | { 84 | // The bounding box that we will fill in 85 | BoundingBox bbox = { { FLT_MAX, FLT_MAX, FLT_MAX }, 86 | { FLT_MIN, FLT_MIN, FLT_MIN } }; 87 | 88 | // Callbacks for API 89 | TK_ObjDelegate objDelegate = {}; 90 | objDelegate.userData = (void*)&bbox; 91 | objDelegate.error = bboxErrorMessage; 92 | 93 | // Read the obj file 94 | if (argc < 2) { 95 | bboxErrorMessage(0, "No .OBJ file specified.", NULL ); 96 | return 1; 97 | } 98 | size_t objFileSize = 0; 99 | void *objFileData = readEntireFile( argv[1], &objFileSize ); 100 | if (!objFileData) { 101 | printf("Could not open .OBJ file '%s'\n", argv[1] ); 102 | } 103 | 104 | // Prepass to determine memory reqs 105 | TK_ParseObj( objFileData, objFileSize, &objDelegate ); 106 | printf("Scratch Mem: %zu\n", objDelegate.scratchMemSize ); 107 | objDelegate.scratchMem = malloc( objDelegate.scratchMemSize ); 108 | 109 | // Parse again with memory 110 | objDelegate.material = bboxSwitchMaterial; 111 | objDelegate.triangle = bboxProcessTriangle; 112 | 113 | TK_ParseObj( objFileData, objFileSize, &objDelegate ); 114 | 115 | printf("Num Verts %zu\n", objDelegate.numVerts); 116 | printf("Num Norms %zu\n", objDelegate.numNorms ); 117 | printf("Num STs %zu\n", objDelegate.numSts ); 118 | 119 | printf("Bounding Box: min [%3.2f %3.2f %3.2f] max [%3.2f %3.2f %3.2f]\n", 120 | bbox.minPos[0], bbox.minPos[1], bbox.minPos[2], 121 | bbox.maxPos[0], bbox.maxPos[1], bbox.maxPos[2] ); 122 | 123 | 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tk_objfile 2 | Single file, header-only .OBJ mesh loader with zero dependancies 3 | 4 | Joel Davis (joeld42@gmail.com) Twitter: @joeld42 5 | 6 | Tapnik Software (www.tapnik.com) 7 | 8 | Note: for backstory about this library read this blog post: 9 | http://www.tapnik.com/blog/tk-objfile.html 10 | 11 | Features: 12 | - Single header implementation, zero dependancies 13 | - No allocations, uses scratch memory passed in by caller 14 | - Reasonably fast -- parses ajax_jotero_com.obj, (50MB, 544k triangles) in 700ms 15 | - Handles multiple materials, useful for OBJs with more than one texture 16 | - Will automatically triangulate convex faces (fan style). 17 | 18 | 19 | Limitations: 20 | - Doesn't handle subobjects or groups (will parse, but groupings are lost) 21 | - Not very well tested 22 | - Crappy examples, no real build system 23 | 24 | 25 | Usage: 26 | ---------- 27 | This file parses an OBJ with a "triangle soup" style API. 28 | 29 | To use, simply include "tk_objfile.h". Exactly one of the including 30 | C or CPP files needs to define TK_OBJFILE_IMPLEMENTATION before including 31 | to generate the implementation. For example: 32 | 33 | ```C 34 | #define TK_OBJFILE_IMPLEMENTATION 35 | #include "tk_objfile.h" 36 | ``` 37 | 38 | Basic usage is to create a TK_ObjDelegate with the callbacks: 39 | 40 | ```C 41 | // Called once for each material that has one or more triangles using it. 42 | void (*material)( const char *mtlName, size_t numTriangles, void *userData ); 43 | 44 | // Called once for each triangle using the material. 45 | void (*triangle)( TK_TriangleVert a, TK_TriangleVert b, TK_TriangleVert c, void *userData ); 46 | 47 | // Will report errors from parsing. 48 | void (*error)( size_t lineNumber, const char *message, void *userData ); 49 | ``` 50 | 51 | All the callbacks are optional. All callbacks pass in a void *userData 52 | from the objDelegate for a convienent way to pass in some context. 53 | 54 | MEMORY: The parser doesn't allocate any memory. Instead, you must pass in 55 | a "scratchMemory" buffer in the objDelegate that is large enough to hold 56 | the results from the parsing and a small amount of working memory. There 57 | are two approaches to this: 58 | 59 | First, you can call TK_ParseObj with 0 for scratchMemSize, and it will 60 | only do a pre-parse and fill in scratchMemSize with how much space it 61 | needs. Then, allocate at least that much space in scratchMem and call 62 | TK_ParseObj again and it will do the actual parse. 63 | 64 | Alternatively, if you know how big the objects you'll be parsing is, 65 | or if you happen to have a large scratch buffer on hand, then you can 66 | just pass that in in the first place. This saves one redundant pre-parse, 67 | but it doesn't really save much time, but it might be simpler. 68 | 69 | Example: 70 | ---- 71 | 72 | Here's a example of how it might be called: 73 | ```C 74 | // Create delegate and assign callbacks 75 | TK_ObjDelegate objDelegate = {}; 76 | objDelegate.error = myCallbackErrorMessage; 77 | objDelegate.material = myCallbackSwitchMaterial; 78 | objDelegate.triangle = myCallbackProcessTriangle; 79 | 80 | // Read the .OBJ file from disk 81 | size_t objFileSize = 0; 82 | void *objFileData = readEntireFile( "cube1.obj", &objFileSize ); 83 | 84 | // Prepass to determine memory requirements 85 | objDelegate.scratchMemSize = 0; 86 | TK_ParseObj( objFileData, objFileSize, &objDelegate ); 87 | 88 | // Allocate scratch memory 89 | objDelegate.scratchMem = malloc( objDelegate.scratchMemSize ); 90 | 91 | // Parse again with memory. This will call material() and 92 | // triangle() callbacks 93 | TK_ParseObj( objFileData, objFileSize, &objDelegate ); 94 | ``` 95 | 96 | Discussion: 97 | ------ 98 | 99 | The "triangle soup" style throws away the index vertex info. Originally I 100 | included an API to preserve the indexed data, but since it's indexed 101 | differently than OpenGL/DX you probably have to reindex it anyways, so 102 | I removed it to keep things simple. In a real world pipeline you might want 103 | to run it through a real triangle stripper or something. 104 | 105 | I still want to add a simple wrapper API that uses cstdlib and just loads 106 | the obj with a single call. 107 | 108 | Examples: 109 | --- 110 | 111 | example_bbox.cpp - Prints the bounding box for an obj file. This is a good 112 | starting point to see how to use it. 113 | 114 | objviewer - Object viewer using IMGUI/glfw. This is a pretty craptastic 115 | viewer, it needs a lot of work, but it's a start. Handles multiple 116 | materials, will tint each material a different color. When loading objects, 117 | if there is a .png image with the same name as the material name, it will 118 | load that as a texture (see hugzilla.obj for an example) 119 | 120 | Contributing: 121 | ------ 122 | 123 | If you would like to contribute, here's some things that would be helpful: 124 | - If you find OBJ files that don't work, please send them to me or create an issue in github 125 | - Improvements in the OBJ viewer are welcome 126 | 127 | 128 | TODO: 129 | ------- 130 | 131 | smaller improvements: 132 | - handle negative indices (old style .LWO) 133 | - add an optional simple one-call wrapper API that uses stdlib 134 | - Add a flag to flip UVs automatically for opengl 135 | - Add a flag to preserve faceIDs, or even an alternate API that preserves faces 136 | - Improve error handling for insuffient scratchmem 137 | 138 | bigger future features: 139 | - Recalculate normals if missing, or if requested 140 | - Support tangents, calculate usable tangents 141 | - Support subobjects ('o' lines) and groups ('g' lines) 142 | -------------------------------------------------------------------------------- /test_objs/cylinder.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib cylinder.mtl 4 | o Cylinder.001 5 | v 0.000000 0.885660 -1.000000 6 | v 0.000000 0.885660 1.000000 7 | v 0.195090 0.866445 -1.000000 8 | v 0.195090 0.866445 1.000000 9 | v 0.382683 0.809539 -1.000000 10 | v 0.382683 0.809539 1.000000 11 | v 0.555570 0.717129 -1.000000 12 | v 0.555570 0.717129 1.000000 13 | v 0.707107 0.592766 -1.000000 14 | v 0.707107 0.592767 1.000000 15 | v 0.831470 0.441230 -1.000000 16 | v 0.831470 0.441230 1.000000 17 | v 0.923880 0.268343 -1.000000 18 | v 0.923880 0.268343 1.000000 19 | v 0.980785 0.080750 -1.000000 20 | v 0.980785 0.080750 1.000000 21 | v 1.000000 -0.114340 -1.000000 22 | v 1.000000 -0.114340 1.000000 23 | v 0.980785 -0.309431 -1.000000 24 | v 0.980785 -0.309430 1.000000 25 | v 0.923880 -0.497024 -1.000000 26 | v 0.923880 -0.497023 1.000000 27 | v 0.831470 -0.669911 -1.000000 28 | v 0.831470 -0.669910 1.000000 29 | v 0.707107 -0.821447 -1.000000 30 | v 0.707107 -0.821447 1.000000 31 | v 0.555570 -0.945810 -1.000000 32 | v 0.555570 -0.945810 1.000000 33 | v 0.382683 -1.038220 -1.000000 34 | v 0.382683 -1.038220 1.000000 35 | v 0.195090 -1.095126 -1.000000 36 | v 0.195090 -1.095126 1.000000 37 | v -0.000000 -1.114340 -1.000000 38 | v -0.000000 -1.114340 1.000000 39 | v -0.195091 -1.095126 -1.000000 40 | v -0.195091 -1.095125 1.000000 41 | v -0.382684 -1.038220 -1.000000 42 | v -0.382684 -1.038220 1.000000 43 | v -0.555571 -0.945810 -1.000000 44 | v -0.555571 -0.945810 1.000000 45 | v -0.707107 -0.821447 -1.000000 46 | v -0.707107 -0.821447 1.000000 47 | v -0.831470 -0.669910 -1.000000 48 | v -0.831470 -0.669910 1.000000 49 | v -0.923880 -0.497023 -1.000000 50 | v -0.923880 -0.497023 1.000000 51 | v -0.980785 -0.309430 -1.000000 52 | v -0.980785 -0.309430 1.000000 53 | v -1.000000 -0.114339 -1.000000 54 | v -1.000000 -0.114339 1.000000 55 | v -0.980785 0.080751 -1.000000 56 | v -0.980785 0.080751 1.000000 57 | v -0.923879 0.268344 -1.000000 58 | v -0.923879 0.268344 1.000000 59 | v -0.831469 0.441231 -1.000000 60 | v -0.831469 0.441231 1.000000 61 | v -0.707106 0.592767 -1.000000 62 | v -0.707106 0.592767 1.000000 63 | v -0.555569 0.717130 -1.000000 64 | v -0.555569 0.717130 1.000000 65 | v -0.382682 0.809540 -1.000000 66 | v -0.382682 0.809540 1.000000 67 | v -0.195089 0.866445 -1.000000 68 | v -0.195089 0.866445 1.000000 69 | v 0.000000 -1.000000 -1.000000 70 | v 0.000000 1.000000 -1.000000 71 | v 0.195090 -1.000000 -0.980785 72 | v 0.195090 1.000000 -0.980785 73 | v 0.382683 -1.000000 -0.923880 74 | v 0.382683 1.000000 -0.923880 75 | v 0.555570 -1.000000 -0.831470 76 | v 0.555570 1.000000 -0.831470 77 | v 0.707107 -1.000000 -0.707107 78 | v 0.707107 1.000000 -0.707107 79 | v 0.831470 -1.000000 -0.555570 80 | v 0.831470 1.000000 -0.555570 81 | v 0.923880 -1.000000 -0.382683 82 | v 0.923880 1.000000 -0.382683 83 | v 0.980785 -1.000000 -0.195090 84 | v 0.980785 1.000000 -0.195090 85 | v 1.000000 -1.000000 -0.000000 86 | v 1.000000 1.000000 -0.000000 87 | v 0.980785 -1.000000 0.195090 88 | v 0.980785 1.000000 0.195090 89 | v 0.923880 -1.000000 0.382683 90 | v 0.923880 1.000000 0.382683 91 | v 0.831470 -1.000000 0.555570 92 | v 0.831470 1.000000 0.555570 93 | v 0.707107 -1.000000 0.707107 94 | v 0.707107 1.000000 0.707107 95 | v 0.555570 -1.000000 0.831470 96 | v 0.555570 1.000000 0.831470 97 | v 0.382683 -1.000000 0.923880 98 | v 0.382683 1.000000 0.923880 99 | v 0.195090 -1.000000 0.980785 100 | v 0.195090 1.000000 0.980785 101 | v -0.000000 -1.000000 1.000000 102 | v -0.000000 1.000000 1.000000 103 | v -0.195091 -1.000000 0.980785 104 | v -0.195091 1.000000 0.980785 105 | v -0.382684 -1.000000 0.923879 106 | v -0.382684 1.000000 0.923879 107 | v -0.555571 -1.000000 0.831469 108 | v -0.555571 1.000000 0.831469 109 | v -0.707107 -1.000000 0.707106 110 | v -0.707107 1.000000 0.707106 111 | v -0.831470 -1.000000 0.555570 112 | v -0.831470 1.000000 0.555570 113 | v -0.923880 -1.000000 0.382683 114 | v -0.923880 1.000000 0.382683 115 | v -0.980785 -1.000000 0.195089 116 | v -0.980785 1.000000 0.195089 117 | v -1.000000 -1.000000 -0.000001 118 | v -1.000000 1.000000 -0.000001 119 | v -0.980785 -1.000000 -0.195091 120 | v -0.980785 1.000000 -0.195091 121 | v -0.923879 -1.000000 -0.382684 122 | v -0.923879 1.000000 -0.382684 123 | v -0.831469 -1.000000 -0.555571 124 | v -0.831469 1.000000 -0.555571 125 | v -0.707106 -1.000000 -0.707108 126 | v -0.707106 1.000000 -0.707108 127 | v -0.555569 -1.000000 -0.831470 128 | v -0.555569 1.000000 -0.831470 129 | v -0.382682 -1.000000 -0.923880 130 | v -0.382682 1.000000 -0.923880 131 | v -0.195089 -1.000000 -0.980786 132 | v -0.195089 1.000000 -0.980786 133 | vn 0.098000 0.995200 -0.000000 134 | vn 0.290300 0.956900 -0.000000 135 | vn 0.471400 0.881900 -0.000000 136 | vn 0.634400 0.773000 -0.000000 137 | vn 0.773000 0.634400 -0.000000 138 | vn 0.881900 0.471400 -0.000000 139 | vn 0.956900 0.290300 -0.000000 140 | vn 0.995200 0.098000 -0.000000 141 | vn 0.995200 -0.098000 0.000000 142 | vn 0.956900 -0.290300 0.000000 143 | vn 0.881900 -0.471400 0.000000 144 | vn 0.773000 -0.634400 0.000000 145 | vn 0.634400 -0.773000 0.000000 146 | vn 0.471400 -0.881900 0.000000 147 | vn 0.290300 -0.956900 0.000000 148 | vn 0.098000 -0.995200 0.000000 149 | vn -0.098000 -0.995200 0.000000 150 | vn -0.290300 -0.956900 0.000000 151 | vn -0.471400 -0.881900 0.000000 152 | vn -0.634400 -0.773000 0.000000 153 | vn -0.773000 -0.634400 0.000000 154 | vn -0.881900 -0.471400 0.000000 155 | vn -0.956900 -0.290300 0.000000 156 | vn -0.995200 -0.098000 0.000000 157 | vn -0.995200 0.098000 -0.000000 158 | vn -0.956900 0.290300 -0.000000 159 | vn -0.881900 0.471400 -0.000000 160 | vn -0.773000 0.634400 -0.000000 161 | vn -0.634400 0.773000 -0.000000 162 | vn -0.471400 0.881900 -0.000000 163 | vn 0.000000 0.000000 1.000000 164 | vn -0.098000 0.995200 -0.000000 165 | vn -0.290300 0.956900 -0.000000 166 | vn 0.000000 -0.000000 -1.000000 167 | vn 0.098000 0.000000 -0.995200 168 | vn 0.290300 0.000000 -0.956900 169 | vn 0.471400 0.000000 -0.881900 170 | vn 0.634400 0.000000 -0.773000 171 | vn 0.773000 0.000000 -0.634400 172 | vn 0.881900 -0.000000 -0.471400 173 | vn 0.956900 0.000000 -0.290300 174 | vn 0.995200 0.000000 -0.098000 175 | vn 0.995200 0.000000 0.098000 176 | vn 0.956900 -0.000000 0.290300 177 | vn 0.881900 -0.000000 0.471400 178 | vn 0.773000 0.000000 0.634400 179 | vn 0.634400 0.000000 0.773000 180 | vn 0.471400 0.000000 0.881900 181 | vn 0.290300 0.000000 0.956900 182 | vn 0.098000 0.000000 0.995200 183 | vn -0.098000 0.000000 0.995200 184 | vn -0.290300 0.000000 0.956900 185 | vn -0.471400 0.000000 0.881900 186 | vn -0.634400 0.000000 0.773000 187 | vn -0.773000 0.000000 0.634400 188 | vn -0.881900 0.000000 0.471400 189 | vn -0.956900 0.000000 0.290300 190 | vn -0.995200 0.000000 0.098000 191 | vn -0.995200 0.000000 -0.098000 192 | vn -0.956900 0.000000 -0.290300 193 | vn -0.881900 0.000000 -0.471400 194 | vn -0.773000 0.000000 -0.634400 195 | vn -0.634400 0.000000 -0.773000 196 | vn -0.471400 0.000000 -0.881900 197 | vn -0.000000 1.000000 0.000000 198 | vn -0.098000 0.000000 -0.995200 199 | vn -0.290300 0.000000 -0.956900 200 | vn -0.000000 -1.000000 -0.000000 201 | usemtl None 202 | s off 203 | f 1//1 2//1 4//1 3//1 204 | f 3//2 4//2 6//2 5//2 205 | f 5//3 6//3 8//3 7//3 206 | f 7//4 8//4 10//4 9//4 207 | f 9//5 10//5 12//5 11//5 208 | f 11//6 12//6 14//6 13//6 209 | f 13//7 14//7 16//7 15//7 210 | f 15//8 16//8 18//8 17//8 211 | f 17//9 18//9 20//9 19//9 212 | f 19//10 20//10 22//10 21//10 213 | f 21//11 22//11 24//11 23//11 214 | f 23//12 24//12 26//12 25//12 215 | f 25//13 26//13 28//13 27//13 216 | f 27//14 28//14 30//14 29//14 217 | f 29//15 30//15 32//15 31//15 218 | f 31//16 32//16 34//16 33//16 219 | f 33//17 34//17 36//17 35//17 220 | f 35//18 36//18 38//18 37//18 221 | f 37//19 38//19 40//19 39//19 222 | f 39//20 40//20 42//20 41//20 223 | f 41//21 42//21 44//21 43//21 224 | f 43//22 44//22 46//22 45//22 225 | f 45//23 46//23 48//23 47//23 226 | f 47//24 48//24 50//24 49//24 227 | f 49//25 50//25 52//25 51//25 228 | f 51//26 52//26 54//26 53//26 229 | f 53//27 54//27 56//27 55//27 230 | f 55//28 56//28 58//28 57//28 231 | f 57//29 58//29 60//29 59//29 232 | f 59//30 60//30 62//30 61//30 233 | f 4//31 2//31 64//31 62//31 60//31 58//31 56//31 54//31 52//31 50//31 48//31 46//31 44//31 42//31 40//31 38//31 36//31 34//31 32//31 30//31 28//31 26//31 24//31 22//31 20//31 18//31 16//31 14//31 12//31 10//31 8//31 6//31 234 | f 63//32 64//32 2//32 1//32 235 | f 61//33 62//33 64//33 63//33 236 | f 1//34 3//34 5//34 7//34 9//34 11//34 13//34 15//34 17//34 19//34 21//34 23//34 25//34 27//34 29//34 31//34 33//34 35//34 37//34 39//34 41//34 43//34 45//34 47//34 49//34 51//34 53//34 55//34 57//34 59//34 61//34 63//34 237 | f 65//35 66//35 68//35 67//35 238 | f 67//36 68//36 70//36 69//36 239 | f 69//37 70//37 72//37 71//37 240 | f 71//38 72//38 74//38 73//38 241 | f 73//39 74//39 76//39 75//39 242 | f 75//40 76//40 78//40 77//40 243 | f 77//41 78//41 80//41 79//41 244 | f 79//42 80//42 82//42 81//42 245 | f 81//43 82//43 84//43 83//43 246 | f 83//44 84//44 86//44 85//44 247 | f 85//45 86//45 88//45 87//45 248 | f 87//46 88//46 90//46 89//46 249 | f 89//47 90//47 92//47 91//47 250 | f 91//48 92//48 94//48 93//48 251 | f 93//49 94//49 96//49 95//49 252 | f 95//50 96//50 98//50 97//50 253 | f 97//51 98//51 100//51 99//51 254 | f 99//52 100//52 102//52 101//52 255 | f 101//53 102//53 104//53 103//53 256 | f 103//54 104//54 106//54 105//54 257 | f 105//55 106//55 108//55 107//55 258 | f 107//56 108//56 110//56 109//56 259 | f 109//57 110//57 112//57 111//57 260 | f 111//58 112//58 114//58 113//58 261 | f 113//59 114//59 116//59 115//59 262 | f 115//60 116//60 118//60 117//60 263 | f 117//61 118//61 120//61 119//61 264 | f 119//62 120//62 122//62 121//62 265 | f 121//63 122//63 124//63 123//63 266 | f 123//64 124//64 126//64 125//64 267 | f 68//65 66//65 128//65 126//65 124//65 122//65 120//65 118//65 116//65 114//65 112//65 110//65 108//65 106//65 104//65 102//65 100//65 98//65 96//65 94//65 92//65 90//65 88//65 86//65 84//65 82//65 80//65 78//65 76//65 74//65 72//65 70//65 268 | f 127//66 128//66 66//66 65//66 269 | f 125//67 126//67 128//67 127//67 270 | f 65//68 67//68 69//68 71//68 73//68 75//68 77//68 79//68 81//68 83//68 85//68 87//68 89//68 91//68 93//68 95//68 97//68 99//68 101//68 103//68 105//68 107//68 109//68 111//68 113//68 115//68 117//68 119//68 121//68 123//68 125//68 127//68 271 | -------------------------------------------------------------------------------- /objviewer/imgui_impl_glfw_gl3.cpp: -------------------------------------------------------------------------------- 1 | // ImGui GLFW binding with OpenGL3 + shaders 2 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 3 | // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). 4 | // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. 5 | // https://github.com/ocornut/imgui 6 | 7 | #include 8 | #include "imgui_impl_glfw_gl3.h" 9 | 10 | // GL3W/GLFW 11 | #include 12 | #include 13 | #ifdef _WIN32 14 | #undef APIENTRY 15 | #define GLFW_EXPOSE_NATIVE_WIN32 16 | #define GLFW_EXPOSE_NATIVE_WGL 17 | #include 18 | #endif 19 | 20 | // Data 21 | static GLFWwindow* g_Window = NULL; 22 | static double g_Time = 0.0f; 23 | static bool g_MousePressed[3] = { false, false, false }; 24 | static float g_MouseWheel = 0.0f; 25 | static GLuint g_FontTexture = 0; 26 | static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; 27 | static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; 28 | static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; 29 | static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; 30 | 31 | // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) 32 | // If text or lines are blurry when integrating ImGui in your engine: 33 | // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) 34 | void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) 35 | { 36 | // Backup GL state 37 | GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); 38 | GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 39 | GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); 40 | GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); 41 | GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); 42 | GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src); 43 | GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); 44 | GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); 45 | GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); 46 | GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); 47 | GLboolean last_enable_blend = glIsEnabled(GL_BLEND); 48 | GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); 49 | GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); 50 | GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); 51 | 52 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled 53 | glEnable(GL_BLEND); 54 | glBlendEquation(GL_FUNC_ADD); 55 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 56 | glDisable(GL_CULL_FACE); 57 | glDisable(GL_DEPTH_TEST); 58 | glEnable(GL_SCISSOR_TEST); 59 | glActiveTexture(GL_TEXTURE0); 60 | 61 | // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) 62 | ImGuiIO& io = ImGui::GetIO(); 63 | int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); 64 | int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); 65 | draw_data->ScaleClipRects(io.DisplayFramebufferScale); 66 | 67 | // Setup viewport, orthographic projection matrix 68 | glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); 69 | const float ortho_projection[4][4] = 70 | { 71 | { 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, 72 | { 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f }, 73 | { 0.0f, 0.0f, -1.0f, 0.0f }, 74 | {-1.0f, 1.0f, 0.0f, 1.0f }, 75 | }; 76 | glUseProgram(g_ShaderHandle); 77 | glUniform1i(g_AttribLocationTex, 0); 78 | glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); 79 | glBindVertexArray(g_VaoHandle); 80 | 81 | for (int n = 0; n < draw_data->CmdListsCount; n++) 82 | { 83 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 84 | const ImDrawIdx* idx_buffer_offset = 0; 85 | 86 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); 87 | glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.size() * sizeof(ImDrawVert), (GLvoid*)&cmd_list->VtxBuffer.front(), GL_STREAM_DRAW); 88 | 89 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); 90 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx), (GLvoid*)&cmd_list->IdxBuffer.front(), GL_STREAM_DRAW); 91 | 92 | for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) 93 | { 94 | if (pcmd->UserCallback) 95 | { 96 | pcmd->UserCallback(cmd_list, pcmd); 97 | } 98 | else 99 | { 100 | glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); 101 | glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); 102 | glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); 103 | } 104 | idx_buffer_offset += pcmd->ElemCount; 105 | } 106 | } 107 | 108 | // Restore modified GL state 109 | glUseProgram(last_program); 110 | glBindTexture(GL_TEXTURE_2D, last_texture); 111 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); 112 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); 113 | glBindVertexArray(last_vertex_array); 114 | glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); 115 | glBlendFunc(last_blend_src, last_blend_dst); 116 | if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); 117 | if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); 118 | if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); 119 | if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); 120 | glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); 121 | } 122 | 123 | static const char* ImGui_ImplGlfwGL3_GetClipboardText() 124 | { 125 | return glfwGetClipboardString(g_Window); 126 | } 127 | 128 | static void ImGui_ImplGlfwGL3_SetClipboardText(const char* text) 129 | { 130 | glfwSetClipboardString(g_Window, text); 131 | } 132 | 133 | void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) 134 | { 135 | if (action == GLFW_PRESS && button >= 0 && button < 3) 136 | g_MousePressed[button] = true; 137 | } 138 | 139 | void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) 140 | { 141 | g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. 142 | } 143 | 144 | void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mods) 145 | { 146 | ImGuiIO& io = ImGui::GetIO(); 147 | if (action == GLFW_PRESS) 148 | io.KeysDown[key] = true; 149 | if (action == GLFW_RELEASE) 150 | io.KeysDown[key] = false; 151 | 152 | (void)mods; // Modifiers are not reliable across systems 153 | io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; 154 | io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; 155 | io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; 156 | } 157 | 158 | void ImGui_ImplGlfwGL3_CharCallback(GLFWwindow*, unsigned int c) 159 | { 160 | ImGuiIO& io = ImGui::GetIO(); 161 | if (c > 0 && c < 0x10000) 162 | io.AddInputCharacter((unsigned short)c); 163 | } 164 | 165 | bool ImGui_ImplGlfwGL3_CreateFontsTexture() 166 | { 167 | // Build texture atlas 168 | ImGuiIO& io = ImGui::GetIO(); 169 | unsigned char* pixels; 170 | int width, height; 171 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. 172 | 173 | // Upload texture to graphics system 174 | GLint last_texture; 175 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 176 | glGenTextures(1, &g_FontTexture); 177 | glBindTexture(GL_TEXTURE_2D, g_FontTexture); 178 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 179 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 180 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 181 | 182 | // Store our identifier 183 | io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; 184 | 185 | // Restore state 186 | glBindTexture(GL_TEXTURE_2D, last_texture); 187 | 188 | return true; 189 | } 190 | 191 | bool ImGui_ImplGlfwGL3_CreateDeviceObjects() 192 | { 193 | // Backup GL state 194 | GLint last_texture, last_array_buffer, last_vertex_array; 195 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 196 | glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); 197 | glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); 198 | 199 | const GLchar *vertex_shader = 200 | "#version 330\n" 201 | "uniform mat4 ProjMtx;\n" 202 | "in vec2 Position;\n" 203 | "in vec2 UV;\n" 204 | "in vec4 Color;\n" 205 | "out vec2 Frag_UV;\n" 206 | "out vec4 Frag_Color;\n" 207 | "void main()\n" 208 | "{\n" 209 | " Frag_UV = UV;\n" 210 | " Frag_Color = Color;\n" 211 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" 212 | "}\n"; 213 | 214 | const GLchar* fragment_shader = 215 | "#version 330\n" 216 | "uniform sampler2D Texture;\n" 217 | "in vec2 Frag_UV;\n" 218 | "in vec4 Frag_Color;\n" 219 | "out vec4 Out_Color;\n" 220 | "void main()\n" 221 | "{\n" 222 | " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" 223 | "}\n"; 224 | 225 | g_ShaderHandle = glCreateProgram(); 226 | g_VertHandle = glCreateShader(GL_VERTEX_SHADER); 227 | g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); 228 | glShaderSource(g_VertHandle, 1, &vertex_shader, 0); 229 | glShaderSource(g_FragHandle, 1, &fragment_shader, 0); 230 | glCompileShader(g_VertHandle); 231 | glCompileShader(g_FragHandle); 232 | glAttachShader(g_ShaderHandle, g_VertHandle); 233 | glAttachShader(g_ShaderHandle, g_FragHandle); 234 | glLinkProgram(g_ShaderHandle); 235 | 236 | g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); 237 | g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); 238 | g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); 239 | g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); 240 | g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); 241 | 242 | glGenBuffers(1, &g_VboHandle); 243 | glGenBuffers(1, &g_ElementsHandle); 244 | 245 | glGenVertexArrays(1, &g_VaoHandle); 246 | glBindVertexArray(g_VaoHandle); 247 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); 248 | glEnableVertexAttribArray(g_AttribLocationPosition); 249 | glEnableVertexAttribArray(g_AttribLocationUV); 250 | glEnableVertexAttribArray(g_AttribLocationColor); 251 | 252 | #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 253 | glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); 254 | glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); 255 | glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); 256 | #undef OFFSETOF 257 | 258 | ImGui_ImplGlfwGL3_CreateFontsTexture(); 259 | 260 | // Restore modified GL state 261 | glBindTexture(GL_TEXTURE_2D, last_texture); 262 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); 263 | glBindVertexArray(last_vertex_array); 264 | 265 | return true; 266 | } 267 | 268 | void ImGui_ImplGlfwGL3_InvalidateDeviceObjects() 269 | { 270 | if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); 271 | if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); 272 | if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); 273 | g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; 274 | 275 | glDetachShader(g_ShaderHandle, g_VertHandle); 276 | glDeleteShader(g_VertHandle); 277 | g_VertHandle = 0; 278 | 279 | glDetachShader(g_ShaderHandle, g_FragHandle); 280 | glDeleteShader(g_FragHandle); 281 | g_FragHandle = 0; 282 | 283 | glDeleteProgram(g_ShaderHandle); 284 | g_ShaderHandle = 0; 285 | 286 | if (g_FontTexture) 287 | { 288 | glDeleteTextures(1, &g_FontTexture); 289 | ImGui::GetIO().Fonts->TexID = 0; 290 | g_FontTexture = 0; 291 | } 292 | } 293 | 294 | bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) 295 | { 296 | g_Window = window; 297 | 298 | ImGuiIO& io = ImGui::GetIO(); 299 | io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 300 | io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; 301 | io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; 302 | io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; 303 | io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; 304 | io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; 305 | io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; 306 | io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; 307 | io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; 308 | io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; 309 | io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; 310 | io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; 311 | io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; 312 | io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; 313 | io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; 314 | io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; 315 | io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; 316 | io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; 317 | io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; 318 | 319 | io.RenderDrawListsFn = ImGui_ImplGlfwGL3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. 320 | io.SetClipboardTextFn = ImGui_ImplGlfwGL3_SetClipboardText; 321 | io.GetClipboardTextFn = ImGui_ImplGlfwGL3_GetClipboardText; 322 | #ifdef _WIN32 323 | io.ImeWindowHandle = glfwGetWin32Window(g_Window); 324 | #endif 325 | 326 | if (install_callbacks) 327 | { 328 | glfwSetMouseButtonCallback(window, ImGui_ImplGlfwGL3_MouseButtonCallback); 329 | glfwSetScrollCallback(window, ImGui_ImplGlfwGL3_ScrollCallback); 330 | glfwSetKeyCallback(window, ImGui_ImplGlfwGL3_KeyCallback); 331 | glfwSetCharCallback(window, ImGui_ImplGlfwGL3_CharCallback); 332 | } 333 | 334 | return true; 335 | } 336 | 337 | void ImGui_ImplGlfwGL3_GetMousePos( double *mouse_x, double *mouse_y, bool *mousePressed ) 338 | { 339 | glfwGetCursorPos(g_Window, mouse_x, mouse_y); 340 | for (int i=0; i < 3; i++) 341 | { 342 | mousePressed[i] = glfwGetMouseButton(g_Window, i ); 343 | } 344 | } 345 | 346 | void ImGui_ImplGlfwGL3_Shutdown() 347 | { 348 | ImGui_ImplGlfwGL3_InvalidateDeviceObjects(); 349 | ImGui::Shutdown(); 350 | } 351 | 352 | void ImGui_ImplGlfwGL3_NewFrame() 353 | { 354 | if (!g_FontTexture) 355 | ImGui_ImplGlfwGL3_CreateDeviceObjects(); 356 | 357 | ImGuiIO& io = ImGui::GetIO(); 358 | 359 | // Setup display size (every frame to accommodate for window resizing) 360 | int w, h; 361 | int display_w, display_h; 362 | glfwGetWindowSize(g_Window, &w, &h); 363 | glfwGetFramebufferSize(g_Window, &display_w, &display_h); 364 | io.DisplaySize = ImVec2((float)w, (float)h); 365 | io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); 366 | 367 | // Setup time step 368 | double current_time = glfwGetTime(); 369 | io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); 370 | g_Time = current_time; 371 | 372 | // Setup inputs 373 | // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) 374 | if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) 375 | { 376 | double mouse_x, mouse_y; 377 | glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); 378 | io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) 379 | } 380 | else 381 | { 382 | io.MousePos = ImVec2(-1,-1); 383 | } 384 | 385 | for (int i = 0; i < 3; i++) 386 | { 387 | io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. 388 | g_MousePressed[i] = false; 389 | } 390 | 391 | io.MouseWheel = g_MouseWheel; 392 | g_MouseWheel = 0.0f; 393 | 394 | // Hide OS mouse cursor if ImGui is drawing it 395 | glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); 396 | 397 | // Start the frame 398 | ImGui::NewFrame(); 399 | } 400 | -------------------------------------------------------------------------------- /tk_objfile.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6D07F8621C308D47009A77ED /* imgui_impl_glfw_gl3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D07F85F1C308D47009A77ED /* imgui_impl_glfw_gl3.cpp */; }; 11 | 6D07F8631C308D47009A77ED /* objviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D07F8611C308D47009A77ED /* objviewer.cpp */; }; 12 | 6D07F8691C3194E0009A77ED /* imgui_demo.o in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D07F8661C3194E0009A77ED /* imgui_demo.o */; }; 13 | 6D07F86A1C3194E0009A77ED /* imgui_draw.o in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D07F8671C3194E0009A77ED /* imgui_draw.o */; }; 14 | 6D07F86B1C3194E0009A77ED /* imgui.o in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D07F8681C3194E0009A77ED /* imgui.o */; }; 15 | 6D07F86D1C31951A009A77ED /* gl3w.o in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D07F86C1C31951A009A77ED /* gl3w.o */; }; 16 | 6D07F86F1C319566009A77ED /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D07F86E1C319566009A77ED /* OpenGL.framework */; }; 17 | 6D07F8711C31956B009A77ED /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D07F8701C31956B009A77ED /* Cocoa.framework */; }; 18 | 6D07F8731C319571009A77ED /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D07F8721C319571009A77ED /* IOKit.framework */; }; 19 | 6D07F8751C31957B009A77ED /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D07F8741C31957B009A77ED /* CoreVideo.framework */; }; 20 | 6DA9E69A1C3071FC0001358A /* example_bbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6DA9E68C1C3071B20001358A /* example_bbox.cpp */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXCopyFilesBuildPhase section */ 24 | 6D07F8541C308BE5009A77ED /* CopyFiles */ = { 25 | isa = PBXCopyFilesBuildPhase; 26 | buildActionMask = 2147483647; 27 | dstPath = /usr/share/man/man1/; 28 | dstSubfolderSpec = 0; 29 | files = ( 30 | ); 31 | runOnlyForDeploymentPostprocessing = 1; 32 | }; 33 | 6DA9E6801C30712A0001358A /* CopyFiles */ = { 34 | isa = PBXCopyFilesBuildPhase; 35 | buildActionMask = 2147483647; 36 | dstPath = /usr/share/man/man1/; 37 | dstSubfolderSpec = 0; 38 | files = ( 39 | ); 40 | runOnlyForDeploymentPostprocessing = 1; 41 | }; 42 | 6DA9E6911C3071EC0001358A /* CopyFiles */ = { 43 | isa = PBXCopyFilesBuildPhase; 44 | buildActionMask = 2147483647; 45 | dstPath = /usr/share/man/man1/; 46 | dstSubfolderSpec = 0; 47 | files = ( 48 | ); 49 | runOnlyForDeploymentPostprocessing = 1; 50 | }; 51 | /* End PBXCopyFilesBuildPhase section */ 52 | 53 | /* Begin PBXFileReference section */ 54 | 6D07F8561C308BE5009A77ED /* objviewer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = objviewer; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 6D07F85F1C308D47009A77ED /* imgui_impl_glfw_gl3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw_gl3.cpp; sourceTree = ""; }; 56 | 6D07F8601C308D47009A77ED /* imgui_impl_glfw_gl3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw_gl3.h; sourceTree = ""; }; 57 | 6D07F8611C308D47009A77ED /* objviewer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = objviewer.cpp; sourceTree = ""; }; 58 | 6D07F8661C3194E0009A77ED /* imgui_demo.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; name = imgui_demo.o; path = ../../../Toolkits/imgui/imgui_demo.o; sourceTree = ""; }; 59 | 6D07F8671C3194E0009A77ED /* imgui_draw.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; name = imgui_draw.o; path = ../../../Toolkits/imgui/imgui_draw.o; sourceTree = ""; }; 60 | 6D07F8681C3194E0009A77ED /* imgui.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; name = imgui.o; path = ../../../Toolkits/imgui/imgui.o; sourceTree = ""; }; 61 | 6D07F86C1C31951A009A77ED /* gl3w.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; name = gl3w.o; path = ../../../Toolkits/imgui/examples/libs/gl3w/GL/gl3w.o; sourceTree = ""; }; 62 | 6D07F86E1C319566009A77ED /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 63 | 6D07F8701C31956B009A77ED /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 64 | 6D07F8721C319571009A77ED /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 65 | 6D07F8741C31957B009A77ED /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; 66 | 6DA9E6821C30712A0001358A /* tk_objfile */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tk_objfile; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | 6DA9E68C1C3071B20001358A /* example_bbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = example_bbox.cpp; path = examples/example_bbox.cpp; sourceTree = SOURCE_ROOT; }; 68 | 6DA9E68E1C3071BE0001358A /* tk_objfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tk_objfile.h; sourceTree = ""; }; 69 | 6DA9E6931C3071EC0001358A /* example_bbox */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = example_bbox; sourceTree = BUILT_PRODUCTS_DIR; }; 70 | /* End PBXFileReference section */ 71 | 72 | /* Begin PBXFrameworksBuildPhase section */ 73 | 6D07F8531C308BE5009A77ED /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | 6D07F8751C31957B009A77ED /* CoreVideo.framework in Frameworks */, 78 | 6D07F8731C319571009A77ED /* IOKit.framework in Frameworks */, 79 | 6D07F8711C31956B009A77ED /* Cocoa.framework in Frameworks */, 80 | 6D07F86F1C319566009A77ED /* OpenGL.framework in Frameworks */, 81 | 6D07F86D1C31951A009A77ED /* gl3w.o in Frameworks */, 82 | 6D07F86B1C3194E0009A77ED /* imgui.o in Frameworks */, 83 | 6D07F8691C3194E0009A77ED /* imgui_demo.o in Frameworks */, 84 | 6D07F86A1C3194E0009A77ED /* imgui_draw.o in Frameworks */, 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | 6DA9E67F1C30712A0001358A /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | 6DA9E6901C3071EC0001358A /* Frameworks */ = { 96 | isa = PBXFrameworksBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | /* End PBXFrameworksBuildPhase section */ 103 | 104 | /* Begin PBXGroup section */ 105 | 6D07F8571C308BE5009A77ED /* objviewer */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 6D07F8761C31A447009A77ED /* frameworks */, 109 | 6D07F8651C319145009A77ED /* imgui */, 110 | 6D07F85F1C308D47009A77ED /* imgui_impl_glfw_gl3.cpp */, 111 | 6D07F8601C308D47009A77ED /* imgui_impl_glfw_gl3.h */, 112 | 6D07F8611C308D47009A77ED /* objviewer.cpp */, 113 | ); 114 | path = objviewer; 115 | sourceTree = ""; 116 | }; 117 | 6D07F8651C319145009A77ED /* imgui */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 6D07F86C1C31951A009A77ED /* gl3w.o */, 121 | 6D07F8661C3194E0009A77ED /* imgui_demo.o */, 122 | 6D07F8671C3194E0009A77ED /* imgui_draw.o */, 123 | 6D07F8681C3194E0009A77ED /* imgui.o */, 124 | ); 125 | name = imgui; 126 | sourceTree = ""; 127 | }; 128 | 6D07F8761C31A447009A77ED /* frameworks */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 6D07F8741C31957B009A77ED /* CoreVideo.framework */, 132 | 6D07F8721C319571009A77ED /* IOKit.framework */, 133 | 6D07F8701C31956B009A77ED /* Cocoa.framework */, 134 | 6D07F86E1C319566009A77ED /* OpenGL.framework */, 135 | ); 136 | name = frameworks; 137 | sourceTree = ""; 138 | }; 139 | 6DA9E6791C30712A0001358A = { 140 | isa = PBXGroup; 141 | children = ( 142 | 6DA9E68E1C3071BE0001358A /* tk_objfile.h */, 143 | 6DA9E6841C30712A0001358A /* examples */, 144 | 6D07F8571C308BE5009A77ED /* objviewer */, 145 | 6DA9E6831C30712A0001358A /* Products */, 146 | ); 147 | sourceTree = ""; 148 | }; 149 | 6DA9E6831C30712A0001358A /* Products */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 6DA9E6821C30712A0001358A /* tk_objfile */, 153 | 6DA9E6931C3071EC0001358A /* example_bbox */, 154 | 6D07F8561C308BE5009A77ED /* objviewer */, 155 | ); 156 | name = Products; 157 | sourceTree = ""; 158 | }; 159 | 6DA9E6841C30712A0001358A /* examples */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 6DA9E68C1C3071B20001358A /* example_bbox.cpp */, 163 | ); 164 | name = examples; 165 | path = tk_objfile; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXNativeTarget section */ 171 | 6D07F8551C308BE5009A77ED /* objviewer */ = { 172 | isa = PBXNativeTarget; 173 | buildConfigurationList = 6D07F85C1C308BE5009A77ED /* Build configuration list for PBXNativeTarget "objviewer" */; 174 | buildPhases = ( 175 | 6D07F8521C308BE5009A77ED /* Sources */, 176 | 6D07F8531C308BE5009A77ED /* Frameworks */, 177 | 6D07F8541C308BE5009A77ED /* CopyFiles */, 178 | ); 179 | buildRules = ( 180 | ); 181 | dependencies = ( 182 | ); 183 | name = objviewer; 184 | productName = objviewer; 185 | productReference = 6D07F8561C308BE5009A77ED /* objviewer */; 186 | productType = "com.apple.product-type.tool"; 187 | }; 188 | 6DA9E6811C30712A0001358A /* tk_objfile */ = { 189 | isa = PBXNativeTarget; 190 | buildConfigurationList = 6DA9E6891C30712A0001358A /* Build configuration list for PBXNativeTarget "tk_objfile" */; 191 | buildPhases = ( 192 | 6DA9E67E1C30712A0001358A /* Sources */, 193 | 6DA9E67F1C30712A0001358A /* Frameworks */, 194 | 6DA9E6801C30712A0001358A /* CopyFiles */, 195 | ); 196 | buildRules = ( 197 | ); 198 | dependencies = ( 199 | ); 200 | name = tk_objfile; 201 | productName = tk_objfile; 202 | productReference = 6DA9E6821C30712A0001358A /* tk_objfile */; 203 | productType = "com.apple.product-type.tool"; 204 | }; 205 | 6DA9E6921C3071EC0001358A /* example_bbox */ = { 206 | isa = PBXNativeTarget; 207 | buildConfigurationList = 6DA9E6971C3071EC0001358A /* Build configuration list for PBXNativeTarget "example_bbox" */; 208 | buildPhases = ( 209 | 6DA9E68F1C3071EC0001358A /* Sources */, 210 | 6DA9E6901C3071EC0001358A /* Frameworks */, 211 | 6DA9E6911C3071EC0001358A /* CopyFiles */, 212 | ); 213 | buildRules = ( 214 | ); 215 | dependencies = ( 216 | ); 217 | name = example_bbox; 218 | productName = example_bbox; 219 | productReference = 6DA9E6931C3071EC0001358A /* example_bbox */; 220 | productType = "com.apple.product-type.tool"; 221 | }; 222 | /* End PBXNativeTarget section */ 223 | 224 | /* Begin PBXProject section */ 225 | 6DA9E67A1C30712A0001358A /* Project object */ = { 226 | isa = PBXProject; 227 | attributes = { 228 | LastUpgradeCheck = 0720; 229 | ORGANIZATIONNAME = "Joel Davis"; 230 | TargetAttributes = { 231 | 6D07F8551C308BE5009A77ED = { 232 | CreatedOnToolsVersion = 7.2; 233 | }; 234 | 6DA9E6811C30712A0001358A = { 235 | CreatedOnToolsVersion = 7.2; 236 | }; 237 | 6DA9E6921C3071EC0001358A = { 238 | CreatedOnToolsVersion = 7.2; 239 | }; 240 | }; 241 | }; 242 | buildConfigurationList = 6DA9E67D1C30712A0001358A /* Build configuration list for PBXProject "tk_objfile" */; 243 | compatibilityVersion = "Xcode 3.2"; 244 | developmentRegion = English; 245 | hasScannedForEncodings = 0; 246 | knownRegions = ( 247 | en, 248 | ); 249 | mainGroup = 6DA9E6791C30712A0001358A; 250 | productRefGroup = 6DA9E6831C30712A0001358A /* Products */; 251 | projectDirPath = ""; 252 | projectRoot = ""; 253 | targets = ( 254 | 6DA9E6811C30712A0001358A /* tk_objfile */, 255 | 6DA9E6921C3071EC0001358A /* example_bbox */, 256 | 6D07F8551C308BE5009A77ED /* objviewer */, 257 | ); 258 | }; 259 | /* End PBXProject section */ 260 | 261 | /* Begin PBXSourcesBuildPhase section */ 262 | 6D07F8521C308BE5009A77ED /* Sources */ = { 263 | isa = PBXSourcesBuildPhase; 264 | buildActionMask = 2147483647; 265 | files = ( 266 | 6D07F8621C308D47009A77ED /* imgui_impl_glfw_gl3.cpp in Sources */, 267 | 6D07F8631C308D47009A77ED /* objviewer.cpp in Sources */, 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | 6DA9E67E1C30712A0001358A /* Sources */ = { 272 | isa = PBXSourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | 6DA9E68F1C3071EC0001358A /* Sources */ = { 279 | isa = PBXSourcesBuildPhase; 280 | buildActionMask = 2147483647; 281 | files = ( 282 | 6DA9E69A1C3071FC0001358A /* example_bbox.cpp in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXSourcesBuildPhase section */ 287 | 288 | /* Begin XCBuildConfiguration section */ 289 | 6D07F85A1C308BE5009A77ED /* Debug */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | FRAMEWORK_SEARCH_PATHS = ""; 293 | HEADER_SEARCH_PATHS = ( 294 | "${HOME}/Toolkits/imgui", 295 | "${HOME}/Toolkits/imgui/examples/libs/gl3w/", 296 | "${HOME}/Toolkits/imgui/examples/libs/glfw/include", 297 | "${HOME}/Toolkits/stb", 298 | ); 299 | LIBRARY_SEARCH_PATHS = /usr/local/lib; 300 | OTHER_LDFLAGS = "-lglfw3"; 301 | PRODUCT_NAME = "$(TARGET_NAME)"; 302 | }; 303 | name = Debug; 304 | }; 305 | 6D07F85B1C308BE5009A77ED /* Release */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | FRAMEWORK_SEARCH_PATHS = ""; 309 | HEADER_SEARCH_PATHS = ( 310 | "${HOME}/Toolkits/imgui", 311 | "${HOME}/Toolkits/imgui/examples/libs/gl3w/", 312 | "${HOME}/Toolkits/imgui/examples/libs/glfw/include", 313 | "${HOME}/Toolkits/stb", 314 | ); 315 | LIBRARY_SEARCH_PATHS = /usr/local/lib; 316 | OTHER_LDFLAGS = "-lglfw3"; 317 | PRODUCT_NAME = "$(TARGET_NAME)"; 318 | }; 319 | name = Release; 320 | }; 321 | 6DA9E6871C30712A0001358A /* Debug */ = { 322 | isa = XCBuildConfiguration; 323 | buildSettings = { 324 | ALWAYS_SEARCH_USER_PATHS = NO; 325 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 326 | CLANG_CXX_LIBRARY = "libc++"; 327 | CLANG_ENABLE_MODULES = YES; 328 | CLANG_ENABLE_OBJC_ARC = YES; 329 | CLANG_WARN_BOOL_CONVERSION = YES; 330 | CLANG_WARN_CONSTANT_CONVERSION = YES; 331 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 332 | CLANG_WARN_EMPTY_BODY = YES; 333 | CLANG_WARN_ENUM_CONVERSION = YES; 334 | CLANG_WARN_INT_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN_UNREACHABLE_CODE = YES; 337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 338 | CODE_SIGN_IDENTITY = "-"; 339 | COPY_PHASE_STRIP = NO; 340 | DEBUG_INFORMATION_FORMAT = dwarf; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | ENABLE_TESTABILITY = YES; 343 | GCC_C_LANGUAGE_STANDARD = gnu99; 344 | GCC_DYNAMIC_NO_PIC = NO; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_OPTIMIZATION_LEVEL = 0; 347 | GCC_PREPROCESSOR_DEFINITIONS = ( 348 | "DEBUG=1", 349 | "$(inherited)", 350 | ); 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | MACOSX_DEPLOYMENT_TARGET = 10.10; 358 | MTL_ENABLE_DEBUG_INFO = YES; 359 | ONLY_ACTIVE_ARCH = YES; 360 | SDKROOT = macosx; 361 | }; 362 | name = Debug; 363 | }; 364 | 6DA9E6881C30712A0001358A /* Release */ = { 365 | isa = XCBuildConfiguration; 366 | buildSettings = { 367 | ALWAYS_SEARCH_USER_PATHS = NO; 368 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 369 | CLANG_CXX_LIBRARY = "libc++"; 370 | CLANG_ENABLE_MODULES = YES; 371 | CLANG_ENABLE_OBJC_ARC = YES; 372 | CLANG_WARN_BOOL_CONVERSION = YES; 373 | CLANG_WARN_CONSTANT_CONVERSION = YES; 374 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 375 | CLANG_WARN_EMPTY_BODY = YES; 376 | CLANG_WARN_ENUM_CONVERSION = YES; 377 | CLANG_WARN_INT_CONVERSION = YES; 378 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 379 | CLANG_WARN_UNREACHABLE_CODE = YES; 380 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 381 | CODE_SIGN_IDENTITY = "-"; 382 | COPY_PHASE_STRIP = NO; 383 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 384 | ENABLE_NS_ASSERTIONS = NO; 385 | ENABLE_STRICT_OBJC_MSGSEND = YES; 386 | GCC_C_LANGUAGE_STANDARD = gnu99; 387 | GCC_NO_COMMON_BLOCKS = YES; 388 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 389 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 390 | GCC_WARN_UNDECLARED_SELECTOR = YES; 391 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 392 | GCC_WARN_UNUSED_FUNCTION = YES; 393 | GCC_WARN_UNUSED_VARIABLE = YES; 394 | MACOSX_DEPLOYMENT_TARGET = 10.10; 395 | MTL_ENABLE_DEBUG_INFO = NO; 396 | SDKROOT = macosx; 397 | }; 398 | name = Release; 399 | }; 400 | 6DA9E68A1C30712A0001358A /* Debug */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | PRODUCT_NAME = "$(TARGET_NAME)"; 404 | }; 405 | name = Debug; 406 | }; 407 | 6DA9E68B1C30712A0001358A /* Release */ = { 408 | isa = XCBuildConfiguration; 409 | buildSettings = { 410 | PRODUCT_NAME = "$(TARGET_NAME)"; 411 | }; 412 | name = Release; 413 | }; 414 | 6DA9E6981C3071EC0001358A /* Debug */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | PRODUCT_NAME = "$(TARGET_NAME)"; 418 | }; 419 | name = Debug; 420 | }; 421 | 6DA9E6991C3071EC0001358A /* Release */ = { 422 | isa = XCBuildConfiguration; 423 | buildSettings = { 424 | PRODUCT_NAME = "$(TARGET_NAME)"; 425 | }; 426 | name = Release; 427 | }; 428 | /* End XCBuildConfiguration section */ 429 | 430 | /* Begin XCConfigurationList section */ 431 | 6D07F85C1C308BE5009A77ED /* Build configuration list for PBXNativeTarget "objviewer" */ = { 432 | isa = XCConfigurationList; 433 | buildConfigurations = ( 434 | 6D07F85A1C308BE5009A77ED /* Debug */, 435 | 6D07F85B1C308BE5009A77ED /* Release */, 436 | ); 437 | defaultConfigurationIsVisible = 0; 438 | defaultConfigurationName = Release; 439 | }; 440 | 6DA9E67D1C30712A0001358A /* Build configuration list for PBXProject "tk_objfile" */ = { 441 | isa = XCConfigurationList; 442 | buildConfigurations = ( 443 | 6DA9E6871C30712A0001358A /* Debug */, 444 | 6DA9E6881C30712A0001358A /* Release */, 445 | ); 446 | defaultConfigurationIsVisible = 0; 447 | defaultConfigurationName = Release; 448 | }; 449 | 6DA9E6891C30712A0001358A /* Build configuration list for PBXNativeTarget "tk_objfile" */ = { 450 | isa = XCConfigurationList; 451 | buildConfigurations = ( 452 | 6DA9E68A1C30712A0001358A /* Debug */, 453 | 6DA9E68B1C30712A0001358A /* Release */, 454 | ); 455 | defaultConfigurationIsVisible = 0; 456 | defaultConfigurationName = Release; 457 | }; 458 | 6DA9E6971C3071EC0001358A /* Build configuration list for PBXNativeTarget "example_bbox" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | 6DA9E6981C3071EC0001358A /* Debug */, 462 | 6DA9E6991C3071EC0001358A /* Release */, 463 | ); 464 | defaultConfigurationIsVisible = 0; 465 | defaultConfigurationName = Release; 466 | }; 467 | /* End XCConfigurationList section */ 468 | }; 469 | rootObject = 6DA9E67A1C30712A0001358A /* Project object */; 470 | } 471 | -------------------------------------------------------------------------------- /tk_objfile.h: -------------------------------------------------------------------------------- 1 | // 2 | // tk_objfile.h 3 | // tk_objfile 4 | // 5 | // Created by Joel Davis on 12/5/15. 6 | // Copyright © 2015 Joel Davis. All rights reserved. 7 | // 8 | 9 | #ifndef TK_OBJFILE_H_INCLUDED 10 | #define TK_OBJFILE_H_INCLUDED 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | // TK_TriangleVert -- Simple triangle vert struct. 17 | typedef struct 18 | { 19 | float pos[3]; 20 | float st[2]; 21 | float nrm[3]; 22 | } TK_TriangleVert; 23 | 24 | // TK_Triangle -- A triangle 25 | typedef struct { 26 | TK_TriangleVert vertA; 27 | TK_TriangleVert vertB; 28 | TK_TriangleVert vertC; 29 | } TK_Triangle; 30 | 31 | // TKObjDelegate -- Callbacks for the OBJ format parser. All callbacks are optional. 32 | // 33 | // Scratch Memory -- The parser needs some scratch memory to do its work and to store the results. 34 | // You must fill this in before you call the parser, as it doesn't do any allocations. 35 | // If you call the parser with scratchMemory pointer of NULL, it will only do the pre-pass to 36 | // determine how much memory it wants. It will fill in the scratchMemorySize, you may allocate 37 | // it however you wish, and then call the parser again to do the actual parsing. 38 | typedef struct 39 | { 40 | void (*error)( size_t lineNumber, const char *message, void *userData ); 41 | 42 | // "Triangle Soup" API -- calls triangles one at a time, grouped by material 43 | void (*material)( const char *mtlName, size_t numTriangles, void *userData ); 44 | void (*triangle)( TK_TriangleVert a, TK_TriangleVert b, TK_TriangleVert c, void *userData ); 45 | 46 | // Scratch memory needed by parser. 47 | // If scratchMemSize is 0, results will not be returned but it will be 48 | // filled in with the required scratchMemSize 49 | void *scratchMem; 50 | size_t scratchMemSize; 51 | 52 | // arbitrary user data passed through to callbacks 53 | void *userData; 54 | 55 | // stats used during parsing. 56 | size_t currentLineNumber; 57 | size_t numVerts; 58 | size_t numNorms; 59 | size_t numSts; 60 | size_t numFaces; 61 | size_t numTriangles; 62 | 63 | } TK_ObjDelegate; 64 | 65 | 66 | // TK_ParseObj -- Parse an obj file into triangle soup. 67 | // 68 | // Parse the obj formatted data and call delegate methods for each triangle. 69 | // TODO:(jbd) Add a SimpleParse that just packs the triangles into a list for convienance 70 | void TK_ParseObj( void *objFileData, size_t objFileSize, TK_ObjDelegate *objDelegate ); 71 | 72 | 73 | #ifdef __cplusplus 74 | } // extern "C" 75 | #endif 76 | 77 | // ========================================================= 78 | // IMPLEMENTATION 79 | // ========================================================= 80 | #ifdef TK_OBJFILE_IMPLEMENTATION 81 | 82 | // NOTE: This uses a custom version of strtof (which is probably not as good). A few 83 | // people have told me that this is silly, there's no reason to avoid strtof or atof 84 | // from the cstdlib. They're probably right, there's no real compelling reason to avoid 85 | // the C stdlib, but since I'm doing this mostly for my own exercise I want to keep to 86 | // the "zero dependancies, from scratch" philosophy. 87 | // 88 | // However, if you prefer to use the stdlib strtof, you can simply add: 89 | // #define TK_STRTOF strtof 90 | // before you include tk_objfile and it will happily use that instead (or define 91 | // it to be your own implementation). 92 | #ifndef TK_STRTOF 93 | #define TK_STRTOF TKimpl_stringToFloat 94 | #endif 95 | 96 | // Implementation types (TKimpl_*) are internal, and may 97 | // change without warning between versions. 98 | 99 | typedef struct { 100 | ssize_t posIndex; 101 | ssize_t stIndex; 102 | ssize_t normIndex; 103 | } TKimpl_IndexedVert; 104 | 105 | typedef struct { 106 | TKimpl_IndexedVert vertA; 107 | TKimpl_IndexedVert vertB; 108 | TKimpl_IndexedVert vertC; 109 | } TKimpl_IndexedTriangle; 110 | 111 | // TKimpl_Material 112 | typedef struct { 113 | char *mtlName; // not 0-delimited, be careful 114 | size_t numTriangles; 115 | TKimpl_IndexedTriangle *triangles; 116 | } TKimpl_Material; 117 | 118 | // Maximum number of unique materials in an obj file 119 | #define TKIMPL_MAX_UNIQUE_MTLS (100) 120 | 121 | // Maximum length of a material name 122 | #define TKIMPL_MAX_MATERIAL_NAME (256) 123 | 124 | typedef struct { 125 | 126 | // vertex list from obj 127 | size_t numVertPos; 128 | size_t numVertSt; 129 | size_t numVertNrm; 130 | 131 | float *vertPos; 132 | float *vertSt; 133 | float *vertNrm; 134 | 135 | TKimpl_Material *materials; 136 | size_t numMaterials; 137 | 138 | } TKimpl_Geometry; 139 | 140 | // TKImpl_ParseType 141 | typedef enum { 142 | TKimpl_ParseTypeCountOnly, 143 | TKimpl_ParseTypeFull, 144 | } TKimpl_ParseType; 145 | 146 | // TKImpl_MemArena 147 | typedef struct { 148 | void *base; 149 | uint8_t *top; 150 | size_t remaining; 151 | } TKImpl_MemArena; 152 | 153 | void *TKImpl_PushSize( TKImpl_MemArena *arena, size_t structSize ) 154 | { 155 | if (structSize > arena->remaining) { 156 | return NULL; 157 | } 158 | 159 | void *result = (void*)arena->top; 160 | arena->top += structSize; 161 | arena->remaining -= structSize; 162 | 163 | 164 | return result; 165 | } 166 | 167 | #define TKImpl_PushStruct(arena,T) (T*)TKImpl_PushSize(arena,sizeof(T)) 168 | #define TKImpl_PushStructArray(arena,T,num) (T*)TKImpl_PushSize(arena,sizeof(T)*num) 169 | 170 | 171 | int TKimpl_isIdentifier( char ch ) { 172 | if (ch=='\0'||ch==' '||ch=='\n'||ch=='\t'||ch=='\r') return 0; 173 | return 1; 174 | } 175 | 176 | // FIXME:(jbd) Remove this debug crap 177 | char *TKimpl_printMtl( char *mtlName ) 178 | { 179 | static char buff[256]; 180 | char *ch2 = buff; 181 | for (char *ch=mtlName; TKimpl_isIdentifier( *ch ); ch++) { 182 | *ch2++ = *ch; 183 | } 184 | *ch2 = '\0'; 185 | return buff; 186 | } 187 | 188 | char *TKimpl_printToken( char *token, char *endtoken) 189 | { 190 | static char buff[256]; 191 | char *ch2 = buff; 192 | for (char *ch=token; ch < endtoken; ch++) { 193 | *ch2++ = *ch; 194 | } 195 | *ch2 = '\0'; 196 | return buff; 197 | 198 | } 199 | 200 | char *TKimpl_stringDelimMtlName( char *dest, char *mtlName, size_t maxLen ) 201 | { 202 | char *ch2 = dest; 203 | for (char *ch=mtlName; TKimpl_isIdentifier( *ch ); ch++) { 204 | *ch2++ = *ch; 205 | if (ch2-dest >= (maxLen-1)) break; 206 | } 207 | *ch2 = '\0'; 208 | return dest; 209 | } 210 | 211 | void TKimpl_nextToken( char **out_token, char **out_endtoken, char *endline ) 212 | { 213 | char *token = *out_token; 214 | char *endtoken = *out_endtoken; 215 | 216 | while (((*endtoken=='\n')||(*endtoken == ' ')) && (endtoken < endline)) { 217 | endtoken++; 218 | } 219 | token = endtoken; 220 | if (token >= endline) { 221 | *out_token = NULL; 222 | *out_endtoken = NULL; 223 | return; 224 | } 225 | 226 | while ((endtoken < endline) && (*endtoken != ' ')) { 227 | endtoken++; 228 | } 229 | 230 | *out_token = token; 231 | *out_endtoken = endtoken; 232 | } 233 | 234 | long TKimpl_parseIndex( char *token, char *endtoken ) 235 | { 236 | long result = 0; 237 | long sign = 1; 238 | for (char *ch = token; ch < endtoken; ch++) { 239 | if (*ch=='-') { 240 | sign = -1; 241 | } else if ((*ch>='0')&&(*ch<='9')) { 242 | int val = *ch - '0'; 243 | result = (result * 10) + val; 244 | } 245 | } 246 | return sign * result; 247 | } 248 | 249 | void TKimpl_parseFaceIndices( char *token, char *endtoken, 250 | ssize_t *pndx, ssize_t *stndx, ssize_t *nndx) 251 | { 252 | // count slashes and find numeric tokens 253 | int numSlash = 0; 254 | char *numberDelim[4]; 255 | long number[3]; 256 | numberDelim[0] = token; 257 | for (char *ch = token; ch < endtoken; ch++) { 258 | if (*ch=='/') { 259 | numSlash++; 260 | numberDelim[numSlash] = ch+1; 261 | } 262 | if (numSlash>=2) break; 263 | } 264 | numberDelim[numSlash+1] = endtoken+1; 265 | 266 | // Parse the slash-delimted groups into indexes 267 | for (int i=0; i < numSlash+1; i++) { 268 | number[i] = TKimpl_parseIndex( numberDelim[i], numberDelim[i+1]-1 ); 269 | if (number[i]>0) number[i]--; // OBJ file indices are 1-based 270 | } 271 | 272 | // decide which lists indexes represent based on number of slashes 273 | if (pndx) { 274 | // first number is always pos 275 | *pndx = number[0]; 276 | } 277 | 278 | if (numSlash==0) { 279 | // No slashes, pos only 280 | if (stndx) *stndx = 0; 281 | if (nndx) *nndx = 0; 282 | } else if (numSlash==1) { 283 | // one slash, pos/st 284 | if (nndx) *nndx = 0; 285 | if (stndx) *stndx = number[1]; 286 | } else if (numSlash==2) { 287 | // two slash, pos/st/nrm 288 | if (stndx) *stndx = number[1]; 289 | if (nndx) *nndx = number[2]; 290 | } 291 | } 292 | 293 | int TKimpl_compareToken( const char *target, char *token, char *endtoken ) 294 | { 295 | while (token < endtoken) 296 | { 297 | if (*target++ != *token++) return 0; 298 | } 299 | return 1; 300 | } 301 | 302 | void TKimpl_copyString( char *dest, const char *src ) 303 | { 304 | do { 305 | *dest++ = *src++; 306 | } while (*src); 307 | *dest='\0'; 308 | } 309 | 310 | 311 | int TKimpl_compareMtlName( char *mtlA, char *mtlB ) 312 | { 313 | while (TKimpl_isIdentifier(*mtlA) && TKimpl_isIdentifier(*mtlB)) 314 | { 315 | if (*mtlA != *mtlB) return 0; 316 | mtlA++; 317 | mtlB++; 318 | } 319 | 320 | return 1; 321 | } 322 | 323 | 324 | void TKimpl_memoryError( TK_ObjDelegate *objDelegate ) 325 | { 326 | if (objDelegate->error) { 327 | objDelegate->error( objDelegate->currentLineNumber, "Not enough scratch memory.", 328 | objDelegate->userData ); 329 | } 330 | } 331 | 332 | 333 | int TKimpl_isFloatChar( char ch ) 334 | { 335 | if ( ((ch>='0')&&(ch<='9')) || (ch=='-') || (ch=='.')) return 1; 336 | else return 0; 337 | } 338 | 339 | float TKimpl_stringToFloat( char *str, char **str_end ) 340 | { 341 | char *ch = str; 342 | float value = 0.0; 343 | float mag= 0.1; 344 | float sign = 1.0; 345 | int inDecimal = 0; 346 | while (TKimpl_isFloatChar(*ch)) { 347 | 348 | if (*ch=='-') { 349 | sign = -1.0; 350 | } else if (*ch=='.') { 351 | inDecimal = 1; 352 | } else if ((*ch>='0') && (*ch<='9')) { 353 | float digitValue = (float)((*ch)-'0'); 354 | if (inDecimal) { 355 | value = (value + digitValue*mag); 356 | mag /= 10.0; 357 | } else { 358 | value = (value*10.0) + digitValue; 359 | } 360 | } 361 | ch++; 362 | } 363 | if (str_end) *str_end = ch; 364 | return sign * value; 365 | } 366 | 367 | // Return 1 on success, 0 on failure 368 | int TKimpl_parseFloat( TK_ObjDelegate *objDelegate, char *token, char *endtoken, float *out_result ) 369 | { 370 | if ((!token) || (!endtoken)) 371 | { 372 | // Token or endtoken is NULL 373 | if (objDelegate->error) { 374 | objDelegate->error( objDelegate->currentLineNumber, "Expected float.", 375 | objDelegate->userData ); 376 | } 377 | return 0; 378 | } 379 | else 380 | { 381 | char *endt = NULL; 382 | float value = 0.0; 383 | value = TK_STRTOF(token, &endt); 384 | if (endt != endtoken) { 385 | if (objDelegate->error) { 386 | objDelegate->error( objDelegate->currentLineNumber, "Could not parse float.", 387 | objDelegate->userData ); 388 | } 389 | return 0; 390 | } 391 | *out_result = value; 392 | } 393 | return 1; 394 | } 395 | 396 | 397 | void TKimpl_ParseObjPass( void *objFileData, size_t objFileSize, 398 | TKimpl_Geometry *geom, 399 | TKimpl_Material *uniqueMtls, size_t *numUniqueMtls, 400 | TK_ObjDelegate *objDelegate, TKimpl_ParseType parseType ) 401 | { 402 | // Make default material 403 | TKimpl_Material *currMtl = NULL; 404 | if (parseType == TKimpl_ParseTypeCountOnly) 405 | { 406 | uniqueMtls[0].mtlName = (char *)"mtl.default "; // trailing space is intentional 407 | uniqueMtls[0].numTriangles = 0; 408 | (*numUniqueMtls)++; 409 | } 410 | currMtl = &uniqueMtls[0]; 411 | 412 | // Reset the delegate state 413 | objDelegate->currentLineNumber = 1; 414 | 415 | // Split file into lines 416 | char *start = (char*)objFileData; 417 | char *line = start; 418 | char *endline = line; 419 | 420 | while (line - start < objFileSize) 421 | { 422 | // Advance to the next endline 423 | do { 424 | endline++; 425 | } while ((*endline) && (*endline!='\n') && (endline - start < objFileSize)); 426 | 427 | // skip leading whitespace 428 | while ( ((*line==' ') || (*line=='\t')) && (line != endline)) { 429 | line++; 430 | } 431 | 432 | // Skip Comments 433 | if (line[0]!='#') 434 | { 435 | char *token, *endtoken; 436 | token = line; 437 | endtoken = line; 438 | while (token) 439 | { 440 | TKimpl_nextToken( &token, &endtoken, endline); 441 | if (!token) break; 442 | 443 | // Handle tokens... 444 | if (TKimpl_compareToken("v", token, endtoken)) 445 | { 446 | if (parseType==TKimpl_ParseTypeCountOnly) 447 | { 448 | // Just count the vert 449 | objDelegate->numVerts++; 450 | } 451 | else 452 | { 453 | // v X Y Z -- vertex position 454 | float *vertPos = geom->vertPos + (geom->numVertPos*3); 455 | 456 | TKimpl_nextToken( &token, &endtoken, endline); 457 | if (!TKimpl_parseFloat( objDelegate, token, endtoken, &(vertPos[0]) )) { 458 | return; 459 | } 460 | 461 | TKimpl_nextToken( &token, &endtoken, endline); 462 | if (!TKimpl_parseFloat( objDelegate, token, endtoken, &(vertPos[1]) )) { 463 | return; 464 | } 465 | 466 | TKimpl_nextToken( &token, &endtoken, endline); 467 | if (!TKimpl_parseFloat( objDelegate, token, endtoken, &(vertPos[2]) )) { 468 | return; 469 | } 470 | 471 | geom->numVertPos++; 472 | } 473 | 474 | } else if (TKimpl_compareToken("vn", token, endtoken)) { 475 | 476 | if (parseType==TKimpl_ParseTypeCountOnly) 477 | { 478 | objDelegate->numNorms++; 479 | } 480 | else 481 | { 482 | // vn X Y Z -- vertex normal 483 | float *vertNrm = geom->vertNrm + (geom->numVertNrm*3); 484 | 485 | TKimpl_nextToken( &token, &endtoken, endline); 486 | if (!TKimpl_parseFloat( objDelegate, token, endtoken, &(vertNrm[0]) )) { 487 | return; 488 | } 489 | 490 | TKimpl_nextToken( &token, &endtoken, endline); 491 | if (!TKimpl_parseFloat( objDelegate, token, endtoken, &(vertNrm[1]) )) { 492 | return; 493 | } 494 | 495 | TKimpl_nextToken( &token, &endtoken, endline); 496 | if (!TKimpl_parseFloat( objDelegate, token, endtoken, &(vertNrm[2]) )) { 497 | return; 498 | } 499 | 500 | geom->numVertNrm++; 501 | } 502 | } else if (TKimpl_compareToken("vt", token, endtoken)) { 503 | 504 | if (parseType==TKimpl_ParseTypeCountOnly) 505 | { 506 | objDelegate->numSts++; 507 | } 508 | else 509 | { 510 | // vn S T -- vertex texture coord 511 | float *vertSt = geom->vertSt + (geom->numVertSt*2); 512 | 513 | TKimpl_nextToken( &token, &endtoken, endline); 514 | if (!TKimpl_parseFloat( objDelegate, token, endtoken, &(vertSt[0]) )) { 515 | return; 516 | } 517 | 518 | TKimpl_nextToken( &token, &endtoken, endline); 519 | if (!TKimpl_parseFloat( objDelegate, token, endtoken, &(vertSt[1]) )) { 520 | return; 521 | } 522 | 523 | geom->numVertSt++; 524 | } 525 | } else if (TKimpl_compareToken("usemtl", token, endtoken)) { 526 | 527 | // usemtl, is this an existing mtl group or a new one? 528 | TKimpl_nextToken( &token, &endtoken, endline); 529 | 530 | TKimpl_Material *useMtl = NULL; 531 | for (int i=1; i < *numUniqueMtls; i++) { 532 | if (TKimpl_compareMtlName( uniqueMtls[i].mtlName, token )) { 533 | useMtl = &uniqueMtls[i]; 534 | break; 535 | } 536 | } 537 | if ((!useMtl) && (parseType==TKimpl_ParseTypeCountOnly)) { 538 | //assert( *numUniqueMtls < TKIMPL_MAX_UNIQUE_MTLS ); 539 | useMtl = &uniqueMtls[(*numUniqueMtls)++]; 540 | useMtl->numTriangles = 0; 541 | useMtl->mtlName = token; 542 | } 543 | currMtl = useMtl; 544 | 545 | } else if (TKimpl_compareToken("f", token, endtoken)) { 546 | TKimpl_IndexedTriangle tri; 547 | TKimpl_IndexedVert vert; 548 | int count = 0; 549 | do { 550 | TKimpl_nextToken( &token, &endtoken, endline ); 551 | if (token) { 552 | if (parseType==TKimpl_ParseTypeFull) 553 | { 554 | TKimpl_parseFaceIndices(token, endtoken, 555 | &(vert.posIndex), 556 | &(vert.stIndex), 557 | &(vert.normIndex) ); 558 | 559 | if (vert.posIndex < 0) { 560 | vert.posIndex = geom->numVertPos + vert.posIndex; 561 | } 562 | 563 | if (vert.stIndex < 0) { 564 | vert.stIndex = geom->numVertSt + vert.stIndex; 565 | } 566 | 567 | if (vert.normIndex < 0) { 568 | vert.normIndex = geom->numVertNrm + vert.normIndex; 569 | } 570 | 571 | if (count==0) { 572 | tri.vertA = vert; 573 | } else if (count==1) { 574 | tri.vertB = vert; 575 | } else if (count >= 3) { 576 | tri.vertB = tri.vertC; 577 | } 578 | 579 | if (count >= 2) { 580 | tri.vertC = vert; 581 | currMtl->triangles[ currMtl->numTriangles++ ] = tri; 582 | } 583 | } 584 | 585 | count++; 586 | } 587 | } while (token); 588 | 589 | if ((count > 2) && (parseType==TKimpl_ParseTypeCountOnly)) { 590 | int triCount = count-2; 591 | currMtl->numTriangles += triCount; 592 | objDelegate->numFaces += 1; 593 | objDelegate->numTriangles += triCount; 594 | } 595 | } 596 | } 597 | } 598 | 599 | // next nonblank line 600 | do { 601 | line = ++endline; 602 | objDelegate->currentLineNumber++; 603 | } while (*endline=='\n'); 604 | } 605 | } 606 | 607 | void TKimpl_GetIndexedTriangle( TK_Triangle *tri, TKimpl_Geometry *geom, TKimpl_IndexedTriangle ndxTri ) 608 | { 609 | tri->vertA.pos[0] = geom->vertPos[ndxTri.vertA.posIndex*3 + 0]; 610 | tri->vertA.pos[1] = geom->vertPos[ndxTri.vertA.posIndex*3 + 1]; 611 | tri->vertA.pos[2] = geom->vertPos[ndxTri.vertA.posIndex*3 + 2]; 612 | tri->vertA.nrm[0] = geom->vertNrm[ndxTri.vertA.normIndex*3 + 0]; 613 | tri->vertA.nrm[1] = geom->vertNrm[ndxTri.vertA.normIndex*3 + 1]; 614 | tri->vertA.nrm[2] = geom->vertNrm[ndxTri.vertA.normIndex*3 + 2]; 615 | tri->vertA.st[0] = geom->vertSt[ndxTri.vertA.stIndex*2 + 0]; 616 | tri->vertA.st[1] = geom->vertSt[ndxTri.vertA.stIndex*2 + 1]; 617 | 618 | tri->vertB.pos[0] = geom->vertPos[ndxTri.vertB.posIndex*3 + 0]; 619 | tri->vertB.pos[1] = geom->vertPos[ndxTri.vertB.posIndex*3 + 1]; 620 | tri->vertB.pos[2] = geom->vertPos[ndxTri.vertB.posIndex*3 + 2]; 621 | tri->vertB.nrm[0] = geom->vertNrm[ndxTri.vertB.normIndex*3 + 0]; 622 | tri->vertB.nrm[1] = geom->vertNrm[ndxTri.vertB.normIndex*3 + 1]; 623 | tri->vertB.nrm[2] = geom->vertNrm[ndxTri.vertB.normIndex*3 + 2]; 624 | tri->vertB.st[0] = geom->vertSt[ndxTri.vertB.stIndex*2 + 0]; 625 | tri->vertB.st[1] = geom->vertSt[ndxTri.vertB.stIndex*2 + 1]; 626 | 627 | tri->vertC.pos[0] = geom->vertPos[ndxTri.vertC.posIndex*3 + 0]; 628 | tri->vertC.pos[1] = geom->vertPos[ndxTri.vertC.posIndex*3 + 1]; 629 | tri->vertC.pos[2] = geom->vertPos[ndxTri.vertC.posIndex*3 + 2]; 630 | tri->vertC.nrm[0] = geom->vertNrm[ndxTri.vertC.normIndex*3 + 0]; 631 | tri->vertC.nrm[1] = geom->vertNrm[ndxTri.vertC.normIndex*3 + 1]; 632 | tri->vertC.nrm[2] = geom->vertNrm[ndxTri.vertC.normIndex*3 + 2]; 633 | tri->vertC.st[0] = geom->vertSt[ndxTri.vertC.stIndex*2 + 0]; 634 | tri->vertC.st[1] = geom->vertSt[ndxTri.vertC.stIndex*2 + 1]; 635 | } 636 | 637 | void TK_ParseObj( void *objFileData, size_t objFileSize, TK_ObjDelegate *objDelegate ) 638 | { 639 | TKimpl_Material uniqueMtls[TKIMPL_MAX_UNIQUE_MTLS]; 640 | size_t numUniqueMtls = 0; 641 | 642 | // pre-pass, count how many verts, nrms and sts there are 643 | objDelegate->numVerts=0; 644 | objDelegate->numSts=0; 645 | objDelegate->numNorms=0; 646 | objDelegate->numFaces=0; 647 | objDelegate->numTriangles=0; 648 | 649 | // First pass, just count verts and unique materials... 650 | TKimpl_ParseObjPass( objFileData, objFileSize, NULL, 651 | uniqueMtls, &numUniqueMtls, 652 | objDelegate, TKimpl_ParseTypeCountOnly ); 653 | 654 | // Make sure we reserve space for at least a single 655 | // st and normal, if they are not present in the obj 656 | if (!objDelegate->numSts) objDelegate->numSts = 1; 657 | if (!objDelegate->numNorms) objDelegate->numNorms = 1; 658 | 659 | size_t totalTriangleCount = 0; 660 | for (int i=0; i < numUniqueMtls; i++) { 661 | totalTriangleCount += uniqueMtls[i].numTriangles; 662 | } 663 | 664 | // Calculate scratchMemSize 665 | size_t requiredScratchMem = 666 | sizeof(TKImpl_MemArena) + 667 | sizeof(TKimpl_Geometry) + 668 | sizeof(float)*3*objDelegate->numVerts + 669 | sizeof(float)*3*objDelegate->numNorms + 670 | sizeof(float)*2*objDelegate->numSts + 671 | sizeof(TKimpl_Material) * numUniqueMtls + 672 | sizeof(TKimpl_IndexedTriangle) * totalTriangleCount; 673 | 674 | // If no scratchMem, just stop now after the prepass 675 | if (!objDelegate->scratchMem) { 676 | objDelegate->scratchMemSize = requiredScratchMem; 677 | return; 678 | } 679 | else if (objDelegate->scratchMemSize < requiredScratchMem) { 680 | TKimpl_memoryError( objDelegate ); 681 | return; 682 | } 683 | 684 | // Initialize our mem arena 685 | TKImpl_MemArena *arena = (TKImpl_MemArena *)objDelegate->scratchMem; 686 | arena->base = arena+1; 687 | arena->top = (uint8_t*)arena->base; 688 | arena->remaining = objDelegate->scratchMemSize - sizeof(TKImpl_MemArena); 689 | 690 | // Allocate our geom 691 | TKimpl_Geometry *geom = TKImpl_PushStruct(arena, TKimpl_Geometry); 692 | 693 | // Allocate vertex data lists 694 | geom->numVertPos = 0; 695 | geom->vertPos = (float*)TKImpl_PushSize(arena, sizeof(float)*3*objDelegate->numVerts); 696 | 697 | geom->numVertNrm = 0; 698 | geom->vertNrm = (float*)TKImpl_PushSize(arena, sizeof(float)*3*objDelegate->numNorms); 699 | 700 | geom->numVertSt = 0; 701 | geom->vertSt = (float*)TKImpl_PushSize(arena, sizeof(float)*2*objDelegate->numSts); 702 | 703 | geom->materials = TKImpl_PushStructArray(arena, TKimpl_Material, numUniqueMtls ); 704 | geom->numMaterials = numUniqueMtls; 705 | 706 | for (int i = 0; i < numUniqueMtls; i++) { 707 | geom->materials[i].mtlName = uniqueMtls[i].mtlName; 708 | geom->materials[i].triangles = TKImpl_PushStructArray( arena, TKimpl_IndexedTriangle, 709 | uniqueMtls[i].numTriangles ); 710 | geom->materials[i].numTriangles = 0; 711 | } 712 | 713 | // Now space is allocated for all the data, parse again and store 714 | TKimpl_ParseObjPass( objFileData, objFileSize, geom, 715 | geom->materials, &(geom->numMaterials), 716 | objDelegate, TKimpl_ParseTypeFull ); 717 | 718 | // If we have no STs or Norms, push a default one 719 | if (geom->numVertSt==0) { 720 | geom->vertSt[0] = 0.0; 721 | geom->vertSt[1] = 0.0; 722 | } 723 | 724 | if (geom->numVertNrm==0) { 725 | geom->vertNrm[0] = 0.0; 726 | geom->vertNrm[1] = 1.0; 727 | geom->vertNrm[2] = 0.0; 728 | } 729 | 730 | 731 | // Now go through the results with the "triangle soup" API 732 | if ((objDelegate->triangle) || (objDelegate->material)) { 733 | for (int mi=0; mi < geom->numMaterials; mi++) { 734 | if (geom->materials[mi].numTriangles > 0) { 735 | if (objDelegate->material) { 736 | // Copy the mtlName into a nice 0-terminated string 737 | char mtlName[TKIMPL_MAX_MATERIAL_NAME]; 738 | TKimpl_stringDelimMtlName(mtlName, geom->materials[mi].mtlName, 739 | TKIMPL_MAX_MATERIAL_NAME ); 740 | 741 | // emit the material name 742 | objDelegate->material( mtlName, 743 | geom->materials[mi].numTriangles, 744 | objDelegate->userData ); 745 | } 746 | // Now emit all the triangles for the material 747 | if (objDelegate->triangle) 748 | { 749 | for (size_t ti=0; ti < geom->materials[mi].numTriangles; ti++) { 750 | TK_Triangle tri = {}; 751 | 752 | TKimpl_GetIndexedTriangle( &tri, geom, geom->materials[mi].triangles[ti] ); 753 | objDelegate->triangle( tri.vertA, tri.vertB, tri.vertC, objDelegate->userData ); 754 | } 755 | } 756 | } 757 | } 758 | } 759 | } 760 | 761 | 762 | #endif // TK_OBJFILE_IMPLEMENTATION 763 | 764 | #endif 765 | -------------------------------------------------------------------------------- /objviewer/objviewer.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include "imgui_impl_glfw_gl3.h" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #if __APPLE__ 16 | #include 17 | #endif 18 | 19 | #define STB_IMAGE_IMPLEMENTATION 20 | #include "stb_image.h" 21 | 22 | #define TK_OBJFILE_IMPLEMENTATION 23 | #include "tk_objfile.h" 24 | 25 | #define offset_d(i,f) (long(&(i)->f) - long(i)) 26 | #define offset_s(t,f) offset_d((t*)1000, f) 27 | 28 | #define DEG2RAD(x) (x*M_PI/180.0) 29 | 30 | enum 31 | { 32 | VertexAttrib_POSITION, 33 | VertexAttrib_TEXCOORD, 34 | VertexAttrib_NORMAL, 35 | // VertexAttrib_TANGENT, 36 | // VertexAttrib_BITANGENT, 37 | // VertexAttrib_COLOR, 38 | VertexAttrib_COUNT 39 | }; 40 | 41 | float g_materialColors[100 * 3]; 42 | 43 | #define deg_to_rad(x) (x * (M_PI/180.0f)) 44 | 45 | 46 | void glCheckError(const char* file, unsigned int line ) 47 | { 48 | // Get the last error 49 | GLenum errorCode = glGetError(); 50 | 51 | if (errorCode != GL_NO_ERROR) 52 | { 53 | const char *error = "Unknown error"; 54 | const char *description = "No description"; 55 | 56 | // Decode the error code 57 | switch (errorCode) 58 | { 59 | case GL_INVALID_ENUM: 60 | { 61 | error = "GL_INVALID_ENUM"; 62 | description = "An unacceptable value has been specified for an enumerated argument."; 63 | break; 64 | } 65 | 66 | case GL_INVALID_VALUE: 67 | { 68 | error = "GL_INVALID_VALUE"; 69 | description = "A numeric argument is out of range."; 70 | break; 71 | } 72 | 73 | case GL_INVALID_OPERATION: 74 | { 75 | error = "GL_INVALID_OPERATION"; 76 | description = "The specified operation is not allowed in the current state."; 77 | break; 78 | } 79 | 80 | case GL_STACK_OVERFLOW: 81 | { 82 | error = "GL_STACK_OVERFLOW"; 83 | description = "This command would cause a stack overflow."; 84 | break; 85 | } 86 | 87 | case GL_STACK_UNDERFLOW: 88 | { 89 | error = "GL_STACK_UNDERFLOW"; 90 | description = "This command would cause a stack underflow."; 91 | break; 92 | } 93 | 94 | case GL_OUT_OF_MEMORY: 95 | { 96 | error = "GL_OUT_OF_MEMORY"; 97 | description = "There is not enough memory left to execute the command."; 98 | break; 99 | } 100 | 101 | case GL_INVALID_FRAMEBUFFER_OPERATION: 102 | { 103 | error = "GL_INVALID_FRAMEBUFFER_OPERATION"; 104 | description = "The object bound to FRAMEBUFFER_BINDING is not \"framebuffer complete\"."; 105 | break; 106 | } 107 | } 108 | 109 | // Log the error 110 | printf(" GL ERROR %s:%d -- %s (%s)\n", file, line, error, description ); 111 | printf("...\n"); 112 | } 113 | } 114 | 115 | #define CHECKGL glCheckError( __FILE__, __LINE__) 116 | 117 | void matrixFrustumf2(float *mat, GLfloat left, GLfloat right, GLfloat bottom, 118 | GLfloat top, GLfloat znear, GLfloat zfar) 119 | { 120 | float temp, temp2, temp3, temp4; 121 | temp = 2.0f * znear; 122 | temp2 = right - left; 123 | temp3 = top - bottom; 124 | temp4 = zfar - znear; 125 | mat[0] = temp / temp2; 126 | mat[1] = 0.0f; 127 | mat[2] = 0.0f; 128 | mat[3] = 0.0f; 129 | 130 | mat[4] = 0.0f; 131 | mat[5] = temp / temp3; 132 | mat[6] = 0.0f; 133 | mat[7] = 0.0f; 134 | 135 | mat[8] = (right + left) / temp2; 136 | mat[9] = (top + bottom) / temp3; 137 | mat[10] = ((-zfar - znear) / temp4); 138 | mat[11] = -1.0f; 139 | 140 | mat[12] = 0.0f; 141 | mat[13] = 0.0f; 142 | mat[14] = ((-temp * zfar) / temp4); 143 | mat[15] = 0.0f; 144 | } 145 | 146 | void matrixPerspectivef2(float *mat, GLfloat fovyInDegrees, 147 | GLfloat aspectRatio, GLfloat znear, GLfloat zfar) 148 | { 149 | float ymax, xmax; 150 | ymax = znear * tanf(fovyInDegrees * 3.14f / 360.0f); 151 | xmax = ymax * aspectRatio; 152 | matrixFrustumf2(mat, -xmax, xmax, -ymax, ymax, znear, zfar); 153 | } 154 | 155 | void matrixDbgPrint( char *message, float *m ) 156 | { 157 | printf("%10s: %3.2f %3.2f %3.2f %3.2f\n" 158 | " %3.2f %3.2f %3.2f %3.2f\n" 159 | " %3.2f %3.2f %3.2f %3.2f\n" 160 | " %3.2f %3.2f %3.2f %3.2f\n", 161 | message, 162 | m[0], m[1], m[2], m[3], 163 | m[4], m[5], m[6], m[7], 164 | m[8], m[9], m[10], m[11], 165 | m[12], m[13], m[14], m[15] ); 166 | 167 | } 168 | 169 | void matrixMultiply(float *mOut, float *mA, float *mB) 170 | { 171 | mOut[ 0] = mA[ 0]*mB[ 0] + mA[ 1]*mB[ 4] + mA[ 2]*mB[ 8] + mA[ 3]*mB[12]; 172 | mOut[ 1] = mA[ 0]*mB[ 1] + mA[ 1]*mB[ 5] + mA[ 2]*mB[ 9] + mA[ 3]*mB[13]; 173 | mOut[ 2] = mA[ 0]*mB[ 2] + mA[ 1]*mB[ 6] + mA[ 2]*mB[10] + mA[ 3]*mB[14]; 174 | mOut[ 3] = mA[ 0]*mB[ 3] + mA[ 1]*mB[ 7] + mA[ 2]*mB[11] + mA[ 3]*mB[15]; 175 | 176 | mOut[ 4] = mA[ 4]*mB[ 0] + mA[ 5]*mB[ 4] + mA[ 6]*mB[ 8] + mA[ 7]*mB[12]; 177 | mOut[ 5] = mA[ 4]*mB[ 1] + mA[ 5]*mB[ 5] + mA[ 6]*mB[ 9] + mA[ 7]*mB[13]; 178 | mOut[ 6] = mA[ 4]*mB[ 2] + mA[ 5]*mB[ 6] + mA[ 6]*mB[10] + mA[ 7]*mB[14]; 179 | mOut[ 7] = mA[ 4]*mB[ 3] + mA[ 5]*mB[ 7] + mA[ 6]*mB[11] + mA[ 7]*mB[15]; 180 | 181 | mOut[ 8] = mA[ 8]*mB[ 0] + mA[ 9]*mB[ 4] + mA[10]*mB[ 8] + mA[11]*mB[12]; 182 | mOut[ 9] = mA[ 8]*mB[ 1] + mA[ 9]*mB[ 5] + mA[10]*mB[ 9] + mA[11]*mB[13]; 183 | mOut[10] = mA[ 8]*mB[ 2] + mA[ 9]*mB[ 6] + mA[10]*mB[10] + mA[11]*mB[14]; 184 | mOut[11] = mA[ 8]*mB[ 3] + mA[ 9]*mB[ 7] + mA[10]*mB[11] + mA[11]*mB[15]; 185 | 186 | mOut[12] = mA[12]*mB[ 0] + mA[13]*mB[ 4] + mA[14]*mB[ 8] + mA[15]*mB[12]; 187 | mOut[13] = mA[12]*mB[ 1] + mA[13]*mB[ 5] + mA[14]*mB[ 9] + mA[15]*mB[13]; 188 | mOut[14] = mA[12]*mB[ 2] + mA[13]*mB[ 6] + mA[14]*mB[10] + mA[15]*mB[14]; 189 | mOut[15] = mA[12]*mB[ 3] + mA[13]*mB[ 7] + mA[14]*mB[11] + mA[15]*mB[15]; 190 | } 191 | 192 | void matrixTranslation(float *mOut, 193 | float fX, 194 | float fY, 195 | float fZ) 196 | { 197 | mOut[ 0]=1.0f; mOut[ 4]=0.0f; mOut[ 8]=0.0f; mOut[12]=fX; 198 | mOut[ 1]=0.0f; mOut[ 5]=1.0f; mOut[ 9]=0.0f; mOut[13]=fY; 199 | mOut[ 2]=0.0f; mOut[ 6]=0.0f; mOut[10]=1.0f; mOut[14]=fZ; 200 | mOut[ 3]=0.0f; mOut[ 7]=0.0f; mOut[11]=0.0f; mOut[15]=1.0f; 201 | } 202 | 203 | inline void vec3SetXYZ( float *vec, float x, float y, float z) 204 | { 205 | vec[0] = x; 206 | vec[1] = y; 207 | vec[2] = z; 208 | } 209 | 210 | void vec3CrossProduct( float *vOut, float *v1, float *v2) 211 | { 212 | 213 | /* Perform calculation on a dummy VECTOR (result) */ 214 | vOut[0] = v1[1] * v2[2] - v1[2] * v2[1]; 215 | vOut[1] = v1[2] * v2[0] - v1[0] * v2[2]; 216 | vOut[2] = v1[0] * v2[1] - v1[1] * v2[0]; 217 | } 218 | 219 | void vec3Normalize(float *vOut, float *vIn) 220 | { 221 | float f; 222 | double temp; 223 | 224 | temp = (double)(vIn[0] * vIn[0] + vIn[1] * vIn[1] + vIn[2] * vIn[2]); 225 | temp = 1.0 / sqrt(temp); 226 | f = (float)temp; 227 | 228 | vOut[0] = vIn[0] * f; 229 | vOut[1] = vIn[1] * f; 230 | vOut[2] = vIn[2] * f; 231 | } 232 | 233 | void matrixLookAtLH(float *mOut, 234 | float *vEye, 235 | float *vAt, 236 | float *vUp) 237 | { 238 | float f[3], f2[3], vUpActual[3], s[3], u[3]; 239 | float t[16]; 240 | float mLookDir[16]; 241 | 242 | f2[0] = vEye[0] - vAt[0]; 243 | f2[1] = vEye[1] - vAt[1]; 244 | f2[2] = vEye[2] - vAt[2]; 245 | 246 | vec3Normalize(f, f2); 247 | vec3Normalize(vUpActual, vUp); 248 | vec3CrossProduct(s, f, vUpActual); 249 | vec3CrossProduct(u, s, f); 250 | 251 | mLookDir[ 0] = s[0]; 252 | mLookDir[ 1] = u[0]; 253 | mLookDir[ 2] = -f[0]; 254 | mLookDir[ 3] = 0; 255 | 256 | mLookDir[ 4] = s[1]; 257 | mLookDir[ 5] = u[1]; 258 | mLookDir[ 6] = -f[1]; 259 | mLookDir[ 7] = 0; 260 | 261 | mLookDir[ 8] = s[2]; 262 | mLookDir[ 9] = u[2]; 263 | mLookDir[10] = -f[2]; 264 | mLookDir[11] = 0; 265 | 266 | mLookDir[12] = 0; 267 | mLookDir[13] = 0; 268 | mLookDir[14] = 0; 269 | mLookDir[15] = 1; 270 | 271 | matrixTranslation(t, -vEye[0], -vEye[1], -vEye[2]); 272 | matrixMultiply(mOut, t, mLookDir); 273 | } 274 | 275 | void matrixLookAtRH(float *mOut, 276 | float *vEye, 277 | float *vAt, 278 | float *vUp) 279 | { 280 | float f2[3], f[3], vUpActual[3], s[3], u[3]; 281 | float t[16]; 282 | float mLookDir[16]; 283 | 284 | f2[0] = vAt[0] - vEye[0]; 285 | f2[1] = vAt[1] - vEye[1]; 286 | f2[2] = vAt[2] - vEye[2]; 287 | 288 | vec3Normalize(f, f2); 289 | vec3Normalize(vUpActual, vUp); 290 | vec3CrossProduct(s, f, vUpActual); 291 | vec3CrossProduct(u, s, f); 292 | 293 | mLookDir[ 0] = s[0]; 294 | mLookDir[ 1] = u[0]; 295 | mLookDir[ 2] = -f[0]; 296 | mLookDir[ 3] = 0; 297 | 298 | mLookDir[ 4] = s[1]; 299 | mLookDir[ 5] = u[1]; 300 | mLookDir[ 6] = -f[1]; 301 | mLookDir[ 7] = 0; 302 | 303 | mLookDir[ 8] = s[2]; 304 | mLookDir[ 9] = u[2]; 305 | mLookDir[10] = -f[2]; 306 | mLookDir[11] = 0; 307 | 308 | mLookDir[12] = 0; 309 | mLookDir[13] = 0; 310 | mLookDir[14] = 0; 311 | mLookDir[15] = 1; 312 | 313 | matrixTranslation(t, -vEye[0], -vEye[1], -vEye[2]); 314 | matrixMultiply(mOut, t, mLookDir); 315 | } 316 | 317 | enum 318 | { 319 | Uniform_PROJMATRIX, 320 | Uniform_TINTCOLOR, 321 | Uniform_LIGHTDIR, 322 | 323 | Uniform_COUNT 324 | }; 325 | 326 | struct ObjDrawBuffer 327 | { 328 | TK_TriangleVert *buffer; 329 | 330 | size_t vertCapacity; 331 | size_t vertUsed; 332 | 333 | GLuint vbo; 334 | GLuint vao; 335 | }; 336 | 337 | 338 | typedef struct ObjMeshGroupStruct 339 | { 340 | char *mtlName; 341 | float mtlColor[3]; 342 | GLuint texId; 343 | 344 | ObjDrawBuffer drawbuffer; 345 | ObjMeshGroupStruct *next; 346 | 347 | } ObjMeshGroup; 348 | 349 | GLuint textureForMaterial( ObjMeshGroup *group ); 350 | 351 | struct ObjDisplayOptions 352 | { 353 | bool wireFrame; 354 | }; 355 | 356 | // ================================ 357 | // ObjMesh 358 | // ================================ 359 | struct ObjMesh 360 | { 361 | // General info 362 | TK_ObjDelegate *objDelegate; 363 | char *objFilename; 364 | 365 | // Obj geometry 366 | ObjMeshGroup *rootGroup; 367 | ObjMeshGroup *currentGroup; 368 | size_t groupCount; 369 | 370 | // Camera 371 | float objCenter[3]; 372 | float camPos[3]; 373 | float lightDir[3]; 374 | float camAngle, camTilt, camRadius; 375 | size_t totalNumTriangles; 376 | 377 | // Obj shader 378 | int shaderHandle, vsHandle, fsHandle; 379 | int attrib[VertexAttrib_COUNT]; 380 | int uniform[Uniform_COUNT]; 381 | 382 | // GUI stuff 383 | ObjDisplayOptions displayOpts; 384 | bool showInspector; 385 | }; 386 | 387 | size_t ObjDrawBuffer_PushVert( ObjDrawBuffer *buff, TK_TriangleVert vert ) 388 | { 389 | // Can't add to a buffer anymore once you draw it 390 | assert( buff->vbo == 0); 391 | 392 | // Make sure we have enough space for the new vert 393 | assert( buff->buffer ); 394 | assert( buff->vertUsed < buff->vertCapacity ); 395 | 396 | // Now we have space, add the vert 397 | size_t vertIndex = buff->vertUsed++; 398 | TK_TriangleVert *destVert = buff->buffer + vertIndex; 399 | memcpy( destVert, &vert, sizeof(TK_TriangleVert)); 400 | 401 | // Flip ST vertically 402 | destVert->st[1] = 1.0-destVert->st[1]; 403 | 404 | return vertIndex; 405 | } 406 | 407 | void ObjMesh_addGroup( ObjMesh *mesh, ObjMeshGroup *group) 408 | { 409 | group->next = mesh->rootGroup; 410 | mesh->rootGroup = group; 411 | mesh->groupCount++; 412 | } 413 | 414 | void ObjMesh_renderGroup( ObjMesh *mesh, ObjMeshGroup *group ) 415 | { 416 | if (group->drawbuffer.vbo == 0) { 417 | 418 | glGenBuffers( 1, &(group->drawbuffer.vbo) ); 419 | CHECKGL; 420 | 421 | glBindBuffer( GL_ARRAY_BUFFER, group->drawbuffer.vbo ); 422 | CHECKGL; 423 | 424 | glBufferData( GL_ARRAY_BUFFER, group->drawbuffer.vertUsed * sizeof( TK_TriangleVert ), 425 | group->drawbuffer.buffer, GL_STATIC_DRAW ); 426 | CHECKGL; 427 | 428 | glGenVertexArrays(1, &(group->drawbuffer.vao)); 429 | CHECKGL; 430 | 431 | glBindVertexArray(group->drawbuffer.vao); 432 | CHECKGL; 433 | 434 | // Also load the texture 435 | group->texId = textureForMaterial( group ); 436 | CHECKGL; 437 | 438 | } else { 439 | glBindVertexArray(group->drawbuffer.vao); 440 | CHECKGL; 441 | 442 | glBindBuffer( GL_ARRAY_BUFFER, group->drawbuffer.vbo ); 443 | CHECKGL; 444 | 445 | } 446 | 447 | // bind texture for this group 448 | glBindTexture( GL_TEXTURE_2D, group->texId ); 449 | 450 | // Bind vertex attributes 451 | glEnableVertexAttribArray( mesh->attrib[VertexAttrib_POSITION] ); 452 | CHECKGL; 453 | 454 | glVertexAttribPointer( mesh->attrib[VertexAttrib_POSITION], 3, GL_FLOAT, GL_FALSE, 455 | sizeof(TK_TriangleVert), (void*)offset_s( TK_TriangleVert, pos) ); 456 | CHECKGL; 457 | 458 | glEnableVertexAttribArray( mesh->attrib[VertexAttrib_TEXCOORD] ); 459 | glVertexAttribPointer( mesh->attrib[VertexAttrib_TEXCOORD], 2, GL_FLOAT, GL_FALSE, 460 | sizeof(TK_TriangleVert), (void*)offset_s( TK_TriangleVert, st ) ); 461 | CHECKGL; 462 | 463 | glEnableVertexAttribArray( mesh->attrib[VertexAttrib_NORMAL] ); 464 | glVertexAttribPointer( mesh->attrib[VertexAttrib_NORMAL], 3, GL_FLOAT, GL_FALSE, 465 | sizeof(TK_TriangleVert), (void*)offset_s( TK_TriangleVert, nrm ) ); 466 | CHECKGL; 467 | 468 | // Draw it! 469 | // printf("Drawing %d verts (%d tris)\n", 470 | // (GLsizei)group->drawbuffer.vertUsed, 471 | // (GLsizei)group->drawbuffer.vertUsed / 3 ); 472 | 473 | glDrawArrays(GL_TRIANGLES, 0, (GLsizei)group->drawbuffer.vertUsed ); 474 | // glPointSize( 15.0 ); 475 | // glDrawArrays( GL_POINTS, 0, (GLsizei)group->drawbuffer.vertUsed ); 476 | CHECKGL; 477 | } 478 | 479 | void checkShaderLog( int shader, int shaderType, const GLchar *shaderText ) 480 | { 481 | GLint logLength=0; 482 | glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logLength ); 483 | if (logLength > 0) 484 | { 485 | char *log = (char *)malloc(logLength); 486 | glGetShaderInfoLog( shader, logLength, NULL, log ); 487 | printf("--------------------------\n%s\n\n", shaderText ); 488 | printf("Error compiling %s shader:\n%s\n-------\n", 489 | (shaderType==GL_VERTEX_SHADER)?"Vertex":"Fragment", 490 | log ); 491 | free(log); 492 | } else { 493 | printf( "%s shader compiled successfully...\n", 494 | (shaderType==GL_VERTEX_SHADER)?"Vertex":"Fragment" ); 495 | } 496 | } 497 | 498 | void ObjMesh_setupShader( ObjMesh *mesh ) 499 | { 500 | const GLchar *vertex_shader = 501 | "#version 330\n" 502 | "uniform mat4 ProjMtx;\n" 503 | "uniform vec3 TintColor;\n" 504 | "uniform vec3 LightDir;\n" 505 | "in vec3 Position;\n" 506 | "in vec2 TexCoord;\n" 507 | "in vec3 Normal;\n" 508 | "out vec2 Frag_UV;\n" 509 | "out vec4 Frag_Color;\n" 510 | "void main()\n" 511 | "{\n" 512 | " Frag_UV = TexCoord;\n" 513 | " float light = clamp( dot( Normal, LightDir ), 0.2, 1.0);" 514 | " Frag_Color = light * vec4( TintColor, 1.0);\n" 515 | " gl_Position = ProjMtx * vec4(Position,1);\n" 516 | "}\n"; 517 | 518 | const GLchar* fragment_shader = 519 | "#version 330\n" 520 | "uniform sampler2D Texture;\n" 521 | "in vec2 Frag_UV;\n" 522 | "in vec4 Frag_Color;\n" 523 | "out vec4 Out_Color;\n" 524 | "void main()\n" 525 | "{\n" 526 | " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" 527 | // " Out_Color = vec4( Frag_UV.x, 0.0, Frag_UV.y, 1.0);" 528 | // " Out_Color = Frag_Color;\n" 529 | "}\n"; 530 | 531 | mesh->shaderHandle = glCreateProgram(); 532 | mesh->vsHandle = glCreateShader(GL_VERTEX_SHADER); 533 | mesh->fsHandle = glCreateShader(GL_FRAGMENT_SHADER); 534 | CHECKGL; 535 | 536 | glShaderSource(mesh->vsHandle, 1, &vertex_shader, 0); 537 | CHECKGL; 538 | 539 | glShaderSource(mesh->fsHandle, 1, &fragment_shader, 0); 540 | CHECKGL; 541 | 542 | glCompileShader(mesh->vsHandle); 543 | checkShaderLog( mesh->vsHandle, GL_VERTEX_SHADER, vertex_shader ); 544 | CHECKGL; 545 | 546 | glCompileShader(mesh->fsHandle); 547 | checkShaderLog( mesh->fsHandle, GL_FRAGMENT_SHADER, fragment_shader ); 548 | CHECKGL; 549 | 550 | glAttachShader(mesh->shaderHandle, mesh->vsHandle); 551 | CHECKGL; 552 | 553 | glAttachShader(mesh->shaderHandle, mesh->fsHandle); 554 | CHECKGL; 555 | 556 | glLinkProgram(mesh->shaderHandle); 557 | CHECKGL; 558 | 559 | mesh->uniform[Uniform_PROJMATRIX] = glGetUniformLocation( mesh->shaderHandle, "ProjMtx"); 560 | printf("Uniform ProjMatrix %d\n", mesh->uniform[Uniform_PROJMATRIX]); 561 | 562 | mesh->uniform[Uniform_TINTCOLOR] = glGetUniformLocation( mesh->shaderHandle, "TintColor"); 563 | printf("Uniform TintColor %d\n", mesh->uniform[Uniform_TINTCOLOR]); 564 | 565 | mesh->uniform[Uniform_LIGHTDIR] = glGetUniformLocation( mesh->shaderHandle, "LightDir"); 566 | printf("Uniform LightDIr %d\n", mesh->uniform[Uniform_LIGHTDIR]); 567 | 568 | mesh->attrib[VertexAttrib_POSITION] = glGetAttribLocation( mesh->shaderHandle, "Position"); 569 | printf("Position Attrib %d\n",mesh->attrib[VertexAttrib_POSITION] ); 570 | 571 | mesh->attrib[VertexAttrib_TEXCOORD] = glGetAttribLocation( mesh->shaderHandle, "TexCoord" ); 572 | printf("TexCoord Attrib %d\n",mesh->attrib[VertexAttrib_TEXCOORD] ); 573 | 574 | mesh->attrib[VertexAttrib_NORMAL] = glGetAttribLocation( mesh->shaderHandle, "Normal" ); 575 | printf("Normal Attrib %d\n",mesh->attrib[VertexAttrib_NORMAL] ); 576 | 577 | // g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); 578 | // g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); 579 | // g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); 580 | // g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); 581 | // g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); 582 | 583 | glEnable( GL_DEPTH_TEST ); 584 | 585 | } 586 | 587 | void ObjMesh_update( ObjMesh *mesh ) 588 | { 589 | static bool mousePressed[3]; 590 | static bool lastMousePressed[3]; 591 | double mouseX, mouseY; 592 | static bool dragging; 593 | static float startAngle; 594 | static double startX; 595 | 596 | ImGui_ImplGlfwGL3_GetMousePos(&mouseX, &mouseY, mousePressed ); 597 | 598 | //printf("Mouse pos %f %f\n", mouseX, mouseY ); 599 | if ((!dragging) && (mousePressed[0])) { 600 | dragging = true; 601 | startAngle = mesh->camAngle; 602 | startX = mouseX; 603 | } 604 | 605 | if (dragging) { 606 | mesh->camAngle = startAngle + (mouseX - startX) * 0.5; 607 | } 608 | 609 | if ((dragging) && (!mousePressed[0])) { 610 | dragging = false; 611 | } 612 | 613 | // update camPos based on camAngle 614 | float angRad = DEG2RAD( mesh->camAngle ); 615 | vec3SetXYZ( mesh->camPos, 616 | mesh->objCenter[0] + cos( angRad ) * mesh->camRadius, 617 | mesh->objCenter[1], 618 | mesh->objCenter[2] + sin(angRad) * mesh->camRadius ); 619 | 620 | vec3SetXYZ( mesh->lightDir, cos( angRad), 0.0, sin(angRad) ); 621 | 622 | for (int i=0; i < 3; i++) { 623 | lastMousePressed[i] = mousePressed[i]; 624 | } 625 | } 626 | 627 | void ObjMesh_renderAll( ObjMesh *mesh ) 628 | { 629 | 630 | if (!mesh->shaderHandle) { 631 | ObjMesh_setupShader( mesh ); 632 | CHECKGL; 633 | } 634 | 635 | 636 | ImGuiIO& io = ImGui::GetIO(); 637 | int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); 638 | int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); 639 | 640 | // Setup viewport, projection matrix 641 | glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); 642 | 643 | float proj[16]; 644 | float modelview[16]; 645 | 646 | float modelViewProj[16]; 647 | 648 | matrixPerspectivef2(proj, 50.0, (float)fb_width/(float)fb_height, 0.01, 1000.0 ); 649 | // matrixTranslation( modelview, 0.0, 0.0, -1.5 ); 650 | float vUp[3] = { 0.0, 1.0, 0.0 }; 651 | // vec3SetXYZ( mesh->camPos, 0, 0, 1.5 ); 652 | 653 | // static float ang = 0.0; 654 | // float radius = 2.5; 655 | // vec3SetXYZ( mesh->camPos, cos(ang)*radius, 0.0, sin(ang)*radius ); 656 | // ang += 0.01; 657 | 658 | // vec3SetXYZ( mesh->objCenter, 0, 0, 0 ); 659 | matrixLookAtRH( modelview, mesh->camPos, mesh->objCenter, vUp ); 660 | 661 | matrixMultiply( modelViewProj, modelview, proj ); 662 | // matrixDbgPrint( "modelview", modelview ); 663 | 664 | glUseProgram( mesh->shaderHandle ); 665 | glUniformMatrix4fv( mesh->uniform[Uniform_PROJMATRIX], 1, GL_FALSE, modelViewProj ); 666 | CHECKGL; 667 | 668 | glUniform3fv( mesh->uniform[Uniform_LIGHTDIR], 1, mesh->lightDir); 669 | CHECKGL; 670 | 671 | for (ObjMeshGroup *group = mesh->rootGroup; 672 | group; group = group->next ) { 673 | 674 | glUniform3fv( mesh->uniform[Uniform_TINTCOLOR], 1, group->mtlColor ); 675 | CHECKGL; 676 | 677 | ObjMesh_renderGroup( mesh, group ); 678 | CHECKGL; 679 | } 680 | 681 | } 682 | 683 | GLuint textureForMaterial( ObjMeshGroup *group ) 684 | { 685 | int w=0; 686 | int h=0; 687 | int origDepth=3; 688 | uint8_t *texData=NULL; 689 | 690 | // see if there is an image with the group name 691 | char texfile[4096]; 692 | sprintf( texfile, "%s.png", group->mtlName ); 693 | printf("Looking for texture %s\n", texfile ); 694 | FILE *fpTex = fopen( texfile, "r" ); 695 | if (fpTex) { 696 | printf("File exists, will load...\n"); 697 | fclose(fpTex); 698 | 699 | texData = stbi_load(texfile, &w, &h, &origDepth, 3 ); 700 | } 701 | 702 | // Did not load a texture, generate a simple checkerboard 703 | if ((w==0)||(h==0)) 704 | { 705 | printf("generating texture...\n"); 706 | w = 32; 707 | h = 32; 708 | texData = (uint8_t*)malloc( w*h*3*sizeof(uint8_t) ); 709 | for (int j=0; j < h; j++) 710 | { 711 | for (int i=0; i < w; i++) 712 | { 713 | uint8_t p = ((i%2)==(j%2))?0xff:0x80; 714 | 715 | size_t ndx = ((j*w)+i) * 3; 716 | texData[ndx+0] = p; 717 | texData[ndx+1] = p; 718 | texData[ndx+2] = p; 719 | } 720 | } 721 | } 722 | 723 | GLuint textureId; 724 | glGenTextures( 1, &textureId ); 725 | glBindTexture( GL_TEXTURE_2D, textureId ); 726 | 727 | // FIXME: make settable 728 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); 729 | glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); 730 | 731 | glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 732 | w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, texData ); 733 | 734 | return textureId; 735 | 736 | } 737 | 738 | void *readEntireFile( const char *filename, size_t *out_filesz ) 739 | { 740 | FILE *fp = fopen( filename, "r" ); 741 | if (!fp) return NULL; 742 | 743 | // Get file size 744 | fseek( fp, 0L, SEEK_END ); 745 | size_t filesz = ftell(fp); 746 | fseek( fp, 0L, SEEK_SET ); 747 | 748 | void *fileData = malloc( filesz ); 749 | if (fileData) 750 | { 751 | size_t result = fread( fileData, filesz, 1, fp ); 752 | 753 | // result is # of chunks read, we're asking for 1, fread 754 | // won't return partial reads, so it's all or nothing. 755 | if (!result) 756 | { 757 | free( fileData); 758 | fileData = NULL; 759 | } 760 | else 761 | { 762 | // read suceeded, set out filesize 763 | *out_filesz = filesz; 764 | } 765 | } 766 | 767 | return fileData; 768 | 769 | } 770 | 771 | // FIXME: have a single error callback 772 | static void error_callback(int error, const char* description) 773 | { 774 | fprintf(stderr, "Error %d: %s\n", error, description); 775 | } 776 | 777 | void objviewerErrorMessage( size_t lineNum, const char *message, void *userData ) 778 | { 779 | printf("ERROR on line %zu: %s\n", lineNum, message ); 780 | } 781 | 782 | void objviewerMaterial( const char *materialName, size_t numTriangles, void *userData ) 783 | { 784 | ObjMesh *mesh = (ObjMesh*)userData; 785 | static float *currMaterialColor = g_materialColors; 786 | 787 | ObjMeshGroup *group = (ObjMeshGroup*)malloc(sizeof(ObjMeshGroup)); 788 | memset( group, 0, sizeof(ObjMeshGroup)); 789 | 790 | // Set up the material 791 | group->mtlName = strdup( materialName ); 792 | group->drawbuffer.buffer = (TK_TriangleVert*)malloc( sizeof(TK_TriangleVert)*numTriangles*3 ); 793 | group->drawbuffer.vertCapacity = numTriangles*3; 794 | group->drawbuffer.vertUsed = 0; 795 | vec3SetXYZ( group->mtlColor, *currMaterialColor, *(currMaterialColor+1), *(currMaterialColor+2) ); 796 | currMaterialColor += 3; 797 | 798 | ObjMesh_addGroup( mesh, group ); 799 | 800 | mesh->currentGroup = group; 801 | mesh->totalNumTriangles += numTriangles; 802 | } 803 | 804 | void objviewerTriangle( TK_TriangleVert a, TK_TriangleVert b, TK_TriangleVert c, void *userData ) 805 | { 806 | ObjMesh *mesh = (ObjMesh*)userData; 807 | ObjMeshGroup *group = mesh->currentGroup; 808 | assert(group); 809 | 810 | // Add the triangle to the current material group 811 | ObjDrawBuffer_PushVert( &group->drawbuffer, a ); 812 | ObjDrawBuffer_PushVert( &group->drawbuffer, b ); 813 | ObjDrawBuffer_PushVert( &group->drawbuffer, c ); 814 | 815 | // Add to the centeroid 816 | for (int i=0; i < 3; i++) 817 | { 818 | mesh->objCenter[i] += a.pos[i]; 819 | mesh->objCenter[i] += b.pos[i]; 820 | mesh->objCenter[i] += c.pos[i]; 821 | } 822 | } 823 | 824 | void objviewerFinished( ObjMesh *mesh ) 825 | { 826 | double centeroidDivisor = mesh->totalNumTriangles * 3; 827 | mesh->objCenter[0] /= centeroidDivisor; 828 | mesh->objCenter[1] /= centeroidDivisor; 829 | mesh->objCenter[2] /= centeroidDivisor; 830 | 831 | printf("CENTEROID: %f %f %f\n", 832 | mesh->objCenter[0], 833 | mesh->objCenter[1], 834 | mesh->objCenter[2] ); 835 | } 836 | 837 | void initMaterialColors() 838 | { 839 | // set up the first few by hand 840 | vec3SetXYZ( g_materialColors+0, 0.8, 0.8, 1.0 ); 841 | vec3SetXYZ( g_materialColors+3, 0.8, 1.0, 0.8 ); 842 | vec3SetXYZ( g_materialColors+6, 1.0, 1.0, 0.5 ); 843 | vec3SetXYZ( g_materialColors+9, 1.0, 0.0, 0.5 ); 844 | vec3SetXYZ( g_materialColors+12, 1.0, 0.4, 1.0 ); 845 | vec3SetXYZ( g_materialColors+15, 1.0, 0.7, 0.2 ); 846 | vec3SetXYZ( g_materialColors+18, 0.3, 0.7, 0.7 ); 847 | vec3SetXYZ( g_materialColors+21, 0.2, 0.5, 0.2 ); 848 | vec3SetXYZ( g_materialColors+24, 0.5, 0.2, 0.2 ); 849 | vec3SetXYZ( g_materialColors+27, 0.4, 1.0, 0.8 ); 850 | 851 | // pick random colors for the rest 852 | for (float *clr = g_materialColors+30; clr < g_materialColors+300; clr++ ) 853 | { 854 | *clr = (float)rand() / (float)RAND_MAX; 855 | } 856 | } 857 | 858 | int main(int argc, char *argv[]) 859 | { 860 | // Load OBJ file 861 | if (argc < 2) { 862 | printf("USAGE: objviewer \n"); 863 | exit(1); 864 | } 865 | 866 | size_t objFileSize = 0; 867 | void *objFileData = readEntireFile( argv[1], &objFileSize ); 868 | if (!objFileData) { 869 | printf("Could not open OBJ file '%s'\n", argv[1] ); 870 | } 871 | 872 | 873 | // Set up our mesh data 874 | ObjMesh theMesh = {}; 875 | TK_ObjDelegate objDelegate = {}; 876 | objDelegate.userData = (void*)&theMesh; 877 | objDelegate.error = objviewerErrorMessage; 878 | objDelegate.material = objviewerMaterial; 879 | objDelegate.triangle = objviewerTriangle; 880 | 881 | initMaterialColors(); 882 | 883 | // Extract filename from OBJ path 884 | char *objFilename = strrchr( argv[1], '/'); 885 | if (objFilename!=NULL) { 886 | objFilename = objFilename+1; 887 | } else { 888 | objFilename = argv[1]; 889 | } 890 | theMesh.objFilename = strdup( objFilename ); 891 | theMesh.showInspector = true; 892 | theMesh.objDelegate = &objDelegate; 893 | 894 | #if __APPLE__ 895 | CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent(); 896 | #endif 897 | // Prepass to determine memory reqs 898 | TK_ParseObj( objFileData, objFileSize, &objDelegate ); 899 | printf("Scratch Mem: %zu\n", objDelegate.scratchMemSize ); 900 | objDelegate.scratchMem = malloc( objDelegate.scratchMemSize ); 901 | 902 | // Parse again with memory 903 | TK_ParseObj( objFileData, objFileSize, &objDelegate ); 904 | 905 | #if __APPLE__ 906 | CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent(); 907 | printf("Parse Time: %fms\n", (endTime - startTime) *1000); 908 | #endif 909 | 910 | objviewerFinished( &theMesh ); 911 | 912 | // Setup window 913 | glfwSetErrorCallback(error_callback); 914 | if (!glfwInit()) 915 | return 1; 916 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 917 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 918 | glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 919 | #if __APPLE__ 920 | glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 921 | #endif 922 | GLFWwindow* window = glfwCreateWindow(800, 600, "OBJ Viewer", NULL, NULL); 923 | glfwMakeContextCurrent(window); 924 | gl3wInit(); 925 | 926 | // Setup ImGui binding 927 | ImGui_ImplGlfwGL3_Init(window, true); 928 | 929 | // bool show_test_window = true; 930 | bool show_test_window = false; 931 | ImVec4 clear_color = ImColor(25, 25, 40); 932 | theMesh.camRadius = 5.0; 933 | 934 | // Main loop 935 | while (!glfwWindowShouldClose(window)) 936 | { 937 | glfwPollEvents(); 938 | ImGui_ImplGlfwGL3_NewFrame(); 939 | 940 | // Show OBJ file inspector 941 | if (theMesh.showInspector) 942 | { 943 | ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); 944 | ImGui::Begin( theMesh.objFilename, &theMesh.showInspector ); 945 | 946 | if (ImGui::CollapsingHeader("Statistics")) 947 | { 948 | ImGui::BulletText( "Memory: %ld", theMesh.objDelegate->scratchMemSize ); 949 | ImGui::BulletText( "Faces: %ld", theMesh.objDelegate->numFaces ); 950 | ImGui::BulletText( "Triangles: %ld", theMesh.objDelegate->numTriangles ); 951 | ImGui::BulletText( "Verts: %ld", theMesh.objDelegate->numVerts ); 952 | ImGui::BulletText( "Materials: %ld", theMesh.groupCount ); 953 | ImGui::Separator(); 954 | } 955 | if (ImGui::CollapsingHeader("Camera")) 956 | { 957 | ImGui::SliderFloat("Zoom", &theMesh.camRadius, 0.1, 30.0, "%.01f"); 958 | } 959 | if (ImGui::CollapsingHeader("Materials")) 960 | { 961 | for (ObjMeshGroup *mtl = theMesh.rootGroup; mtl; mtl = mtl->next ) 962 | { 963 | ImGui::Text( "%s", mtl->mtlName ); 964 | ImGui::Text( "Triangles: %zu\n", mtl->drawbuffer.vertUsed / 3 ); 965 | ImGui::ColorEdit3("Tint Color", mtl->mtlColor); 966 | ImGui::Separator(); 967 | } 968 | } 969 | 970 | ImGui::End(); 971 | 972 | } 973 | 974 | // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() 975 | if (show_test_window) 976 | { 977 | ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); 978 | ImGui::ShowTestWindow(&show_test_window); 979 | } 980 | 981 | // Update 982 | ObjMesh_update( &theMesh ); 983 | 984 | // Rendering 985 | int display_w, display_h; 986 | glfwGetFramebufferSize(window, &display_w, &display_h); 987 | glViewport(0, 0, display_w, display_h); 988 | glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); 989 | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 990 | 991 | ObjMesh_renderAll( &theMesh ); 992 | 993 | ImGui::Render(); 994 | glfwSwapBuffers(window); 995 | } 996 | 997 | // Cleanup 998 | ImGui_ImplGlfwGL3_Shutdown(); 999 | glfwTerminate(); 1000 | 1001 | return 0; 1002 | } 1003 | -------------------------------------------------------------------------------- /test_objs/suzanne.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib suzanne.mtl 4 | o Suzanne 5 | v 0.437500 0.164062 0.765625 6 | v -0.437500 0.164062 0.765625 7 | v 0.500000 0.093750 0.687500 8 | v -0.500000 0.093750 0.687500 9 | v 0.546875 0.054688 0.578125 10 | v -0.546875 0.054688 0.578125 11 | v 0.351562 -0.023438 0.617188 12 | v -0.351562 -0.023438 0.617188 13 | v 0.351562 0.031250 0.718750 14 | v -0.351562 0.031250 0.718750 15 | v 0.351562 0.132812 0.781250 16 | v -0.351562 0.132812 0.781250 17 | v 0.273438 0.164062 0.796875 18 | v -0.273438 0.164062 0.796875 19 | v 0.203125 0.093750 0.742188 20 | v -0.203125 0.093750 0.742188 21 | v 0.156250 0.054688 0.648438 22 | v -0.156250 0.054688 0.648438 23 | v 0.078125 0.242188 0.656250 24 | v -0.078125 0.242188 0.656250 25 | v 0.140625 0.242188 0.742188 26 | v -0.140625 0.242188 0.742188 27 | v 0.242188 0.242188 0.796875 28 | v -0.242188 0.242188 0.796875 29 | v 0.273438 0.328125 0.796875 30 | v -0.273438 0.328125 0.796875 31 | v 0.203125 0.390625 0.742188 32 | v -0.203125 0.390625 0.742188 33 | v 0.156250 0.437500 0.648438 34 | v -0.156250 0.437500 0.648438 35 | v 0.351562 0.515625 0.617188 36 | v -0.351562 0.515625 0.617188 37 | v 0.351562 0.453125 0.718750 38 | v -0.351562 0.453125 0.718750 39 | v 0.351562 0.359375 0.781250 40 | v -0.351562 0.359375 0.781250 41 | v 0.437500 0.328125 0.765625 42 | v -0.437500 0.328125 0.765625 43 | v 0.500000 0.390625 0.687500 44 | v -0.500000 0.390625 0.687500 45 | v 0.546875 0.437500 0.578125 46 | v -0.546875 0.437500 0.578125 47 | v 0.625000 0.242188 0.562500 48 | v -0.625000 0.242188 0.562500 49 | v 0.562500 0.242188 0.671875 50 | v -0.562500 0.242188 0.671875 51 | v 0.468750 0.242188 0.757812 52 | v -0.468750 0.242188 0.757812 53 | v 0.476562 0.242188 0.773438 54 | v -0.476562 0.242188 0.773438 55 | v 0.445312 0.335938 0.781250 56 | v -0.445312 0.335938 0.781250 57 | v 0.351562 0.375000 0.804688 58 | v -0.351562 0.375000 0.804688 59 | v 0.265625 0.335938 0.820312 60 | v -0.265625 0.335938 0.820312 61 | v 0.226562 0.242188 0.820312 62 | v -0.226562 0.242188 0.820312 63 | v 0.265625 0.156250 0.820312 64 | v -0.265625 0.156250 0.820312 65 | v 0.351562 0.242188 0.828125 66 | v -0.351562 0.242188 0.828125 67 | v 0.351562 0.117188 0.804688 68 | v -0.351562 0.117188 0.804688 69 | v 0.445312 0.156250 0.781250 70 | v -0.445312 0.156250 0.781250 71 | v 0.000000 0.429688 0.742188 72 | v 0.000000 0.351562 0.820312 73 | v 0.000000 -0.679688 0.734375 74 | v 0.000000 -0.320312 0.781250 75 | v 0.000000 -0.187500 0.796875 76 | v 0.000000 -0.773438 0.718750 77 | v 0.000000 0.406250 0.601562 78 | v 0.000000 0.570312 0.570312 79 | v 0.000000 0.898438 -0.546875 80 | v 0.000000 0.562500 -0.851562 81 | v 0.000000 0.070312 -0.828125 82 | v 0.000000 -0.382812 -0.351562 83 | v 0.203125 -0.187500 0.562500 84 | v -0.203125 -0.187500 0.562500 85 | v 0.312500 -0.437500 0.570312 86 | v -0.312500 -0.437500 0.570312 87 | v 0.351562 -0.695312 0.570312 88 | v -0.351562 -0.695312 0.570312 89 | v 0.367188 -0.890625 0.531250 90 | v -0.367188 -0.890625 0.531250 91 | v 0.328125 -0.945312 0.523438 92 | v -0.328125 -0.945312 0.523438 93 | v 0.179688 -0.968750 0.554688 94 | v -0.179688 -0.968750 0.554688 95 | v 0.000000 -0.984375 0.578125 96 | v 0.437500 -0.140625 0.531250 97 | v -0.437500 -0.140625 0.531250 98 | v 0.632812 -0.039062 0.539062 99 | v -0.632812 -0.039062 0.539062 100 | v 0.828125 0.148438 0.445312 101 | v -0.828125 0.148438 0.445312 102 | v 0.859375 0.429688 0.593750 103 | v -0.859375 0.429688 0.593750 104 | v 0.710938 0.484375 0.625000 105 | v -0.710938 0.484375 0.625000 106 | v 0.492188 0.601562 0.687500 107 | v -0.492188 0.601562 0.687500 108 | v 0.320312 0.757812 0.734375 109 | v -0.320312 0.757812 0.734375 110 | v 0.156250 0.718750 0.757812 111 | v -0.156250 0.718750 0.757812 112 | v 0.062500 0.492188 0.750000 113 | v -0.062500 0.492188 0.750000 114 | v 0.164062 0.414062 0.773438 115 | v -0.164062 0.414062 0.773438 116 | v 0.125000 0.304688 0.765625 117 | v -0.125000 0.304688 0.765625 118 | v 0.203125 0.093750 0.742188 119 | v -0.203125 0.093750 0.742188 120 | v 0.375000 0.015625 0.703125 121 | v -0.375000 0.015625 0.703125 122 | v 0.492188 0.062500 0.671875 123 | v -0.492188 0.062500 0.671875 124 | v 0.625000 0.187500 0.648438 125 | v -0.625000 0.187500 0.648438 126 | v 0.640625 0.296875 0.648438 127 | v -0.640625 0.296875 0.648438 128 | v 0.601562 0.375000 0.664062 129 | v -0.601562 0.375000 0.664062 130 | v 0.429688 0.437500 0.718750 131 | v -0.429688 0.437500 0.718750 132 | v 0.250000 0.468750 0.757812 133 | v -0.250000 0.468750 0.757812 134 | v 0.000000 -0.765625 0.734375 135 | v 0.109375 -0.718750 0.734375 136 | v -0.109375 -0.718750 0.734375 137 | v 0.117188 -0.835938 0.710938 138 | v -0.117188 -0.835938 0.710938 139 | v 0.062500 -0.882812 0.695312 140 | v -0.062500 -0.882812 0.695312 141 | v 0.000000 -0.890625 0.687500 142 | v 0.000000 -0.195312 0.750000 143 | v 0.000000 -0.140625 0.742188 144 | v 0.101562 -0.148438 0.742188 145 | v -0.101562 -0.148438 0.742188 146 | v 0.125000 -0.226562 0.750000 147 | v -0.125000 -0.226562 0.750000 148 | v 0.085938 -0.289062 0.742188 149 | v -0.085938 -0.289062 0.742188 150 | v 0.398438 -0.046875 0.671875 151 | v -0.398438 -0.046875 0.671875 152 | v 0.617188 0.054688 0.625000 153 | v -0.617188 0.054688 0.625000 154 | v 0.726562 0.203125 0.601562 155 | v -0.726562 0.203125 0.601562 156 | v 0.742188 0.375000 0.656250 157 | v -0.742188 0.375000 0.656250 158 | v 0.687500 0.414062 0.726562 159 | v -0.687500 0.414062 0.726562 160 | v 0.437500 0.546875 0.796875 161 | v -0.437500 0.546875 0.796875 162 | v 0.312500 0.640625 0.835938 163 | v -0.312500 0.640625 0.835938 164 | v 0.203125 0.617188 0.851562 165 | v -0.203125 0.617188 0.851562 166 | v 0.101562 0.429688 0.843750 167 | v -0.101562 0.429688 0.843750 168 | v 0.125000 -0.101562 0.812500 169 | v -0.125000 -0.101562 0.812500 170 | v 0.210938 -0.445312 0.710938 171 | v -0.210938 -0.445312 0.710938 172 | v 0.250000 -0.703125 0.687500 173 | v -0.250000 -0.703125 0.687500 174 | v 0.265625 -0.820312 0.664062 175 | v -0.265625 -0.820312 0.664062 176 | v 0.234375 -0.914062 0.632812 177 | v -0.234375 -0.914062 0.632812 178 | v 0.164062 -0.929688 0.632812 179 | v -0.164062 -0.929688 0.632812 180 | v 0.000000 -0.945312 0.640625 181 | v 0.000000 0.046875 0.726562 182 | v 0.000000 0.210938 0.765625 183 | v 0.328125 0.476562 0.742188 184 | v -0.328125 0.476562 0.742188 185 | v 0.164062 0.140625 0.750000 186 | v -0.164062 0.140625 0.750000 187 | v 0.132812 0.210938 0.757812 188 | v -0.132812 0.210938 0.757812 189 | v 0.117188 -0.687500 0.734375 190 | v -0.117188 -0.687500 0.734375 191 | v 0.078125 -0.445312 0.750000 192 | v -0.078125 -0.445312 0.750000 193 | v 0.000000 -0.445312 0.750000 194 | v 0.000000 -0.328125 0.742188 195 | v 0.093750 -0.273438 0.781250 196 | v -0.093750 -0.273438 0.781250 197 | v 0.132812 -0.226562 0.796875 198 | v -0.132812 -0.226562 0.796875 199 | v 0.109375 -0.132812 0.781250 200 | v -0.109375 -0.132812 0.781250 201 | v 0.039062 -0.125000 0.781250 202 | v -0.039062 -0.125000 0.781250 203 | v 0.000000 -0.203125 0.828125 204 | v 0.046875 -0.148438 0.812500 205 | v -0.046875 -0.148438 0.812500 206 | v 0.093750 -0.156250 0.812500 207 | v -0.093750 -0.156250 0.812500 208 | v 0.109375 -0.226562 0.828125 209 | v -0.109375 -0.226562 0.828125 210 | v 0.078125 -0.250000 0.804688 211 | v -0.078125 -0.250000 0.804688 212 | v 0.000000 -0.289062 0.804688 213 | v 0.257812 -0.312500 0.554688 214 | v -0.257812 -0.312500 0.554688 215 | v 0.164062 -0.242188 0.710938 216 | v -0.164062 -0.242188 0.710938 217 | v 0.179688 -0.312500 0.710938 218 | v -0.179688 -0.312500 0.710938 219 | v 0.234375 -0.250000 0.554688 220 | v -0.234375 -0.250000 0.554688 221 | v 0.000000 -0.875000 0.687500 222 | v 0.046875 -0.867188 0.687500 223 | v -0.046875 -0.867188 0.687500 224 | v 0.093750 -0.820312 0.710938 225 | v -0.093750 -0.820312 0.710938 226 | v 0.093750 -0.742188 0.726562 227 | v -0.093750 -0.742188 0.726562 228 | v 0.000000 -0.781250 0.656250 229 | v 0.093750 -0.750000 0.664062 230 | v -0.093750 -0.750000 0.664062 231 | v 0.093750 -0.812500 0.640625 232 | v -0.093750 -0.812500 0.640625 233 | v 0.046875 -0.851562 0.632812 234 | v -0.046875 -0.851562 0.632812 235 | v 0.000000 -0.859375 0.632812 236 | v 0.171875 0.218750 0.781250 237 | v -0.171875 0.218750 0.781250 238 | v 0.187500 0.156250 0.773438 239 | v -0.187500 0.156250 0.773438 240 | v 0.335938 0.429688 0.757812 241 | v -0.335938 0.429688 0.757812 242 | v 0.273438 0.421875 0.773438 243 | v -0.273438 0.421875 0.773438 244 | v 0.421875 0.398438 0.773438 245 | v -0.421875 0.398438 0.773438 246 | v 0.562500 0.351562 0.695312 247 | v -0.562500 0.351562 0.695312 248 | v 0.585938 0.289062 0.687500 249 | v -0.585938 0.289062 0.687500 250 | v 0.578125 0.195312 0.679688 251 | v -0.578125 0.195312 0.679688 252 | v 0.476562 0.101562 0.718750 253 | v -0.476562 0.101562 0.718750 254 | v 0.375000 0.062500 0.742188 255 | v -0.375000 0.062500 0.742188 256 | v 0.226562 0.109375 0.781250 257 | v -0.226562 0.109375 0.781250 258 | v 0.179688 0.296875 0.781250 259 | v -0.179688 0.296875 0.781250 260 | v 0.210938 0.375000 0.781250 261 | v -0.210938 0.375000 0.781250 262 | v 0.234375 0.359375 0.757812 263 | v -0.234375 0.359375 0.757812 264 | v 0.195312 0.296875 0.757812 265 | v -0.195312 0.296875 0.757812 266 | v 0.242188 0.125000 0.757812 267 | v -0.242188 0.125000 0.757812 268 | v 0.375000 0.085938 0.726562 269 | v -0.375000 0.085938 0.726562 270 | v 0.460938 0.117188 0.703125 271 | v -0.460938 0.117188 0.703125 272 | v 0.546875 0.210938 0.671875 273 | v -0.546875 0.210938 0.671875 274 | v 0.554688 0.281250 0.671875 275 | v -0.554688 0.281250 0.671875 276 | v 0.531250 0.335938 0.679688 277 | v -0.531250 0.335938 0.679688 278 | v 0.414062 0.390625 0.750000 279 | v -0.414062 0.390625 0.750000 280 | v 0.281250 0.398438 0.765625 281 | v -0.281250 0.398438 0.765625 282 | v 0.335938 0.406250 0.750000 283 | v -0.335938 0.406250 0.750000 284 | v 0.203125 0.171875 0.750000 285 | v -0.203125 0.171875 0.750000 286 | v 0.195312 0.226562 0.750000 287 | v -0.195312 0.226562 0.750000 288 | v 0.109375 0.460938 0.609375 289 | v -0.109375 0.460938 0.609375 290 | v 0.195312 0.664062 0.617188 291 | v -0.195312 0.664062 0.617188 292 | v 0.335938 0.687500 0.593750 293 | v -0.335938 0.687500 0.593750 294 | v 0.484375 0.554688 0.554688 295 | v -0.484375 0.554688 0.554688 296 | v 0.679688 0.453125 0.492188 297 | v -0.679688 0.453125 0.492188 298 | v 0.796875 0.406250 0.460938 299 | v -0.796875 0.406250 0.460938 300 | v 0.773438 0.164062 0.375000 301 | v -0.773438 0.164062 0.375000 302 | v 0.601562 0.000000 0.414062 303 | v -0.601562 0.000000 0.414062 304 | v 0.437500 -0.093750 0.468750 305 | v -0.437500 -0.093750 0.468750 306 | v 0.000000 0.898438 0.289062 307 | v 0.000000 0.984375 -0.078125 308 | v 0.000000 -0.195312 -0.671875 309 | v 0.000000 -0.460938 0.187500 310 | v 0.000000 -0.976562 0.460938 311 | v 0.000000 -0.804688 0.343750 312 | v 0.000000 -0.570312 0.320312 313 | v 0.000000 -0.484375 0.281250 314 | v 0.851562 0.234375 0.054688 315 | v -0.851562 0.234375 0.054688 316 | v 0.859375 0.320312 -0.046875 317 | v -0.859375 0.320312 -0.046875 318 | v 0.773438 0.265625 -0.437500 319 | v -0.773438 0.265625 -0.437500 320 | v 0.460938 0.437500 -0.703125 321 | v -0.460938 0.437500 -0.703125 322 | v 0.734375 -0.046875 0.070312 323 | v -0.734375 -0.046875 0.070312 324 | v 0.593750 -0.125000 -0.164062 325 | v -0.593750 -0.125000 -0.164062 326 | v 0.640625 -0.007812 -0.429688 327 | v -0.640625 -0.007812 -0.429688 328 | v 0.335938 0.054688 -0.664062 329 | v -0.335938 0.054688 -0.664062 330 | v 0.234375 -0.351562 0.406250 331 | v -0.234375 -0.351562 0.406250 332 | v 0.179688 -0.414062 0.257812 333 | v -0.179688 -0.414062 0.257812 334 | v 0.289062 -0.710938 0.382812 335 | v -0.289062 -0.710938 0.382812 336 | v 0.250000 -0.500000 0.390625 337 | v -0.250000 -0.500000 0.390625 338 | v 0.328125 -0.914062 0.398438 339 | v -0.328125 -0.914062 0.398438 340 | v 0.140625 -0.757812 0.367188 341 | v -0.140625 -0.757812 0.367188 342 | v 0.125000 -0.539062 0.359375 343 | v -0.125000 -0.539062 0.359375 344 | v 0.164062 -0.945312 0.437500 345 | v -0.164062 -0.945312 0.437500 346 | v 0.218750 -0.281250 0.429688 347 | v -0.218750 -0.281250 0.429688 348 | v 0.210938 -0.226562 0.468750 349 | v -0.210938 -0.226562 0.468750 350 | v 0.203125 -0.171875 0.500000 351 | v -0.203125 -0.171875 0.500000 352 | v 0.210938 -0.390625 0.164062 353 | v -0.210938 -0.390625 0.164062 354 | v 0.296875 -0.312500 -0.265625 355 | v -0.296875 -0.312500 -0.265625 356 | v 0.343750 -0.148438 -0.539062 357 | v -0.343750 -0.148438 -0.539062 358 | v 0.453125 0.867188 -0.382812 359 | v -0.453125 0.867188 -0.382812 360 | v 0.453125 0.929688 -0.070312 361 | v -0.453125 0.929688 -0.070312 362 | v 0.453125 0.851562 0.234375 363 | v -0.453125 0.851562 0.234375 364 | v 0.460938 0.523438 0.429688 365 | v -0.460938 0.523438 0.429688 366 | v 0.726562 0.406250 0.335938 367 | v -0.726562 0.406250 0.335938 368 | v 0.632812 0.453125 0.281250 369 | v -0.632812 0.453125 0.281250 370 | v 0.640625 0.703125 0.054688 371 | v -0.640625 0.703125 0.054688 372 | v 0.796875 0.562500 0.125000 373 | v -0.796875 0.562500 0.125000 374 | v 0.796875 0.617188 -0.117188 375 | v -0.796875 0.617188 -0.117188 376 | v 0.640625 0.750000 -0.195312 377 | v -0.640625 0.750000 -0.195312 378 | v 0.640625 0.679688 -0.445312 379 | v -0.640625 0.679688 -0.445312 380 | v 0.796875 0.539062 -0.359375 381 | v -0.796875 0.539062 -0.359375 382 | v 0.617188 0.328125 -0.585938 383 | v -0.617188 0.328125 -0.585938 384 | v 0.484375 0.023438 -0.546875 385 | v -0.484375 0.023438 -0.546875 386 | v 0.820312 0.328125 -0.203125 387 | v -0.820312 0.328125 -0.203125 388 | v 0.406250 -0.171875 0.148438 389 | v -0.406250 -0.171875 0.148438 390 | v 0.429688 -0.195312 -0.210938 391 | v -0.429688 -0.195312 -0.210938 392 | v 0.890625 0.406250 -0.234375 393 | v -0.890625 0.406250 -0.234375 394 | v 0.773438 -0.140625 -0.125000 395 | v -0.773438 -0.140625 -0.125000 396 | v 1.039062 -0.101562 -0.328125 397 | v -1.039062 -0.101562 -0.328125 398 | v 1.281250 0.054688 -0.429688 399 | v -1.281250 0.054688 -0.429688 400 | v 1.351562 0.320312 -0.421875 401 | v -1.351562 0.320312 -0.421875 402 | v 1.234375 0.507812 -0.421875 403 | v -1.234375 0.507812 -0.421875 404 | v 1.023438 0.476562 -0.312500 405 | v -1.023438 0.476562 -0.312500 406 | v 1.015625 0.414062 -0.289062 407 | v -1.015625 0.414062 -0.289062 408 | v 1.187500 0.437500 -0.390625 409 | v -1.187500 0.437500 -0.390625 410 | v 1.265625 0.289062 -0.406250 411 | v -1.265625 0.289062 -0.406250 412 | v 1.210938 0.078125 -0.406250 413 | v -1.210938 0.078125 -0.406250 414 | v 1.031250 -0.039062 -0.304688 415 | v -1.031250 -0.039062 -0.304688 416 | v 0.828125 -0.070312 -0.132812 417 | v -0.828125 -0.070312 -0.132812 418 | v 0.921875 0.359375 -0.218750 419 | v -0.921875 0.359375 -0.218750 420 | v 0.945312 0.304688 -0.289062 421 | v -0.945312 0.304688 -0.289062 422 | v 0.882812 -0.023438 -0.210938 423 | v -0.882812 -0.023438 -0.210938 424 | v 1.039062 0.000000 -0.367188 425 | v -1.039062 0.000000 -0.367188 426 | v 1.187500 0.093750 -0.445312 427 | v -1.187500 0.093750 -0.445312 428 | v 1.234375 0.250000 -0.445312 429 | v -1.234375 0.250000 -0.445312 430 | v 1.171875 0.359375 -0.437500 431 | v -1.171875 0.359375 -0.437500 432 | v 1.023438 0.343750 -0.359375 433 | v -1.023438 0.343750 -0.359375 434 | v 0.843750 0.289062 -0.210938 435 | v -0.843750 0.289062 -0.210938 436 | v 0.835938 0.171875 -0.273438 437 | v -0.835938 0.171875 -0.273438 438 | v 0.757812 0.093750 -0.273438 439 | v -0.757812 0.093750 -0.273438 440 | v 0.820312 0.085938 -0.273438 441 | v -0.820312 0.085938 -0.273438 442 | v 0.843750 0.015625 -0.273438 443 | v -0.843750 0.015625 -0.273438 444 | v 0.812500 -0.015625 -0.273438 445 | v -0.812500 -0.015625 -0.273438 446 | v 0.726562 0.000000 -0.070312 447 | v -0.726562 0.000000 -0.070312 448 | v 0.718750 -0.023438 -0.171875 449 | v -0.718750 -0.023438 -0.171875 450 | v 0.718750 0.039062 -0.187500 451 | v -0.718750 0.039062 -0.187500 452 | v 0.796875 0.203125 -0.210938 453 | v -0.796875 0.203125 -0.210938 454 | v 0.890625 0.242188 -0.265625 455 | v -0.890625 0.242188 -0.265625 456 | v 0.890625 0.234375 -0.320312 457 | v -0.890625 0.234375 -0.320312 458 | v 0.812500 -0.015625 -0.320312 459 | v -0.812500 -0.015625 -0.320312 460 | v 0.851562 0.015625 -0.320312 461 | v -0.851562 0.015625 -0.320312 462 | v 0.828125 0.078125 -0.320312 463 | v -0.828125 0.078125 -0.320312 464 | v 0.765625 0.093750 -0.320312 465 | v -0.765625 0.093750 -0.320312 466 | v 0.843750 0.171875 -0.320312 467 | v -0.843750 0.171875 -0.320312 468 | v 1.039062 0.328125 -0.414062 469 | v -1.039062 0.328125 -0.414062 470 | v 1.187500 0.343750 -0.484375 471 | v -1.187500 0.343750 -0.484375 472 | v 1.257812 0.242188 -0.492188 473 | v -1.257812 0.242188 -0.492188 474 | v 1.210938 0.085938 -0.484375 475 | v -1.210938 0.085938 -0.484375 476 | v 1.046875 0.000000 -0.421875 477 | v -1.046875 0.000000 -0.421875 478 | v 0.882812 -0.015625 -0.265625 479 | v -0.882812 -0.015625 -0.265625 480 | v 0.953125 0.289062 -0.343750 481 | v -0.953125 0.289062 -0.343750 482 | v 0.890625 0.109375 -0.328125 483 | v -0.890625 0.109375 -0.328125 484 | v 0.937500 0.062500 -0.335938 485 | v -0.937500 0.062500 -0.335938 486 | v 1.000000 0.125000 -0.367188 487 | v -1.000000 0.125000 -0.367188 488 | v 0.960938 0.171875 -0.351562 489 | v -0.960938 0.171875 -0.351562 490 | v 1.015625 0.234375 -0.375000 491 | v -1.015625 0.234375 -0.375000 492 | v 1.054688 0.187500 -0.382812 493 | v -1.054688 0.187500 -0.382812 494 | v 1.109375 0.210938 -0.390625 495 | v -1.109375 0.210938 -0.390625 496 | v 1.085938 0.273438 -0.390625 497 | v -1.085938 0.273438 -0.390625 498 | v 1.023438 0.437500 -0.484375 499 | v -1.023438 0.437500 -0.484375 500 | v 1.250000 0.468750 -0.546875 501 | v -1.250000 0.468750 -0.546875 502 | v 1.367188 0.296875 -0.500000 503 | v -1.367188 0.296875 -0.500000 504 | v 1.312500 0.054688 -0.531250 505 | v -1.312500 0.054688 -0.531250 506 | v 1.039062 -0.085938 -0.492188 507 | v -1.039062 -0.085938 -0.492188 508 | v 0.789062 -0.125000 -0.328125 509 | v -0.789062 -0.125000 -0.328125 510 | v 0.859375 0.382812 -0.382812 511 | v -0.859375 0.382812 -0.382812 512 | vt 0.346058 0.879550 513 | vt 0.359549 0.893545 514 | vt 0.344782 0.915205 515 | vt 0.318469 0.888918 516 | vt 0.678893 0.865619 517 | vt 0.653037 0.876085 518 | vt 0.644139 0.861550 519 | vt 0.662193 0.837300 520 | vt 0.326709 0.928670 521 | vt 0.294099 0.895370 522 | vt 0.706043 0.853882 523 | vt 0.684150 0.818493 524 | vt 0.221755 0.973066 525 | vt 0.221355 0.937233 526 | vt 0.244163 0.930613 527 | vt 0.244163 0.977001 528 | vt 0.706043 0.904814 529 | vt 0.679033 0.904707 530 | vt 0.380265 0.892022 531 | vt 0.381782 0.914417 532 | vt 0.652896 0.898116 533 | vt 0.256486 0.869625 534 | vt 0.253470 0.889109 535 | vt 0.229346 0.889234 536 | vt 0.236024 0.851999 537 | vt 0.663147 0.931387 538 | vt 0.644139 0.912482 539 | vt 0.202854 0.888182 540 | vt 0.211901 0.839785 541 | vt 0.685638 0.940336 542 | vt 0.234732 0.922695 543 | vt 0.211255 0.930613 544 | vt 0.706043 0.902256 545 | vt 0.728136 0.897546 546 | vt 0.750625 0.925666 547 | vt 0.733392 0.937807 548 | vt 0.256486 0.906421 549 | vt 0.754288 0.889495 550 | vt 0.765802 0.904430 551 | vt 0.954110 0.281946 552 | vt 0.953449 0.261359 553 | vt 0.969854 0.258959 554 | vt 0.971376 0.295777 555 | vt 0.730110 0.859203 556 | vt 0.754465 0.867700 557 | vt 0.994170 0.255157 558 | vt 0.994170 0.303164 559 | vt 0.706939 0.852104 560 | vt 0.969213 0.224904 561 | vt 0.993387 0.211103 562 | vt 0.736178 0.818493 563 | vt 0.752152 0.832960 564 | vt 0.380114 0.841850 565 | vt 0.360876 0.842621 566 | vt 0.345679 0.822427 567 | vt 0.381782 0.821670 568 | vt 0.765802 0.854241 569 | vt 0.345509 0.857771 570 | vt 0.319377 0.850471 571 | vt 0.176722 0.887922 572 | vt 0.198602 0.887341 573 | vt 0.202854 0.906431 574 | vt 0.184740 0.922514 575 | vt 0.293948 0.845198 576 | vt 0.328673 0.809202 577 | vt 0.148470 0.887555 578 | vt 0.158696 0.932289 579 | vt 0.150573 0.839785 580 | vt 0.177381 0.851079 581 | vt 0.199373 0.866786 582 | vt 0.573410 0.860015 583 | vt 0.569462 0.878059 584 | vt 0.564967 0.878511 585 | vt 0.569434 0.859397 586 | vt 0.201788 0.887816 587 | vt 0.202854 0.865837 588 | vt 0.573410 0.899298 589 | vt 0.567658 0.902707 590 | vt 0.363865 0.968914 591 | vt 0.370509 0.968238 592 | vt 0.378997 0.984272 593 | vt 0.375020 0.986153 594 | vt 0.953863 0.243670 595 | vt 0.948410 0.261566 596 | vt 0.948542 0.241271 597 | vt 0.363627 0.946107 598 | vt 0.369501 0.947864 599 | vt 0.949353 0.284759 600 | vt 0.373893 0.928670 601 | vt 0.378997 0.932862 602 | vt 0.751338 0.262292 603 | vt 0.743551 0.280760 604 | vt 0.738608 0.279814 605 | vt 0.746521 0.258765 606 | vt 0.564967 0.838571 607 | vt 0.570894 0.837982 608 | vt 0.574198 0.856187 609 | vt 0.568529 0.859397 610 | vt 0.751338 0.299142 611 | vt 0.746269 0.300776 612 | vt 0.568012 0.817099 613 | vt 0.574198 0.819130 614 | vt 0.767634 0.838018 615 | vt 0.768998 0.818228 616 | vt 0.773079 0.818912 617 | vt 0.773079 0.841600 618 | vt 0.935643 0.168593 619 | vt 0.939742 0.168803 620 | vt 0.946726 0.186399 621 | vt 0.941827 0.188492 622 | vt 0.768736 0.799487 623 | vt 0.772786 0.798830 624 | vt 0.943712 0.148301 625 | vt 0.946726 0.149975 626 | vt 0.782982 0.283682 627 | vt 0.766535 0.311226 628 | vt 0.752774 0.295174 629 | vt 0.181084 0.973036 630 | vt 0.172354 0.956989 631 | vt 0.196059 0.944864 632 | vt 0.790301 0.311226 633 | vt 0.175023 0.932290 634 | vt 0.805417 0.294750 635 | vt 0.837487 0.312013 636 | vt 0.819748 0.310540 637 | vt 0.831274 0.284196 638 | vt 0.806013 0.272258 639 | vt 0.806013 0.294627 640 | vt 0.791027 0.255192 641 | vt 0.806948 0.270434 642 | vt 0.769655 0.254469 643 | vt 0.819122 0.254469 644 | vt 0.752146 0.271668 645 | vt 0.837487 0.255260 646 | vt 0.196059 0.976246 647 | vt 0.940033 0.121952 648 | vt 0.919968 0.125130 649 | vt 0.913479 0.092659 650 | vt 0.930212 0.087902 651 | vt 0.904505 0.057002 652 | vt 0.923098 0.047336 653 | vt 0.948410 0.148301 654 | vt 0.920742 0.138968 655 | vt 0.898652 0.041642 656 | vt 0.917484 0.012045 657 | vt 0.432084 0.620140 658 | vt 0.398643 0.638688 659 | vt 0.392496 0.619240 660 | vt 0.423037 0.609629 661 | vt 0.876748 0.033918 662 | vt 0.905456 0.002104 663 | vt 0.431214 0.665351 664 | vt 0.396835 0.666133 665 | vt 0.854541 0.033953 666 | vt 0.867953 0.000000 667 | vt 0.432084 0.727110 668 | vt 0.395063 0.727374 669 | vt 0.018251 0.777787 670 | vt 0.059522 0.744148 671 | vt 0.071486 0.781226 672 | vt 0.026775 0.810579 673 | vt 0.155255 0.342004 674 | vt 0.197515 0.320972 675 | vt 0.217806 0.343091 676 | vt 0.178676 0.389757 677 | vt 0.702398 0.752437 678 | vt 0.743520 0.752142 679 | vt 0.731751 0.806816 680 | vt 0.668265 0.818493 681 | vt 0.610159 0.258765 682 | vt 0.645986 0.269040 683 | vt 0.645967 0.299481 684 | vt 0.610636 0.299481 685 | vt 0.709658 0.694323 686 | vt 0.738920 0.700076 687 | vt 0.774029 0.538026 688 | vt 0.741746 0.597376 689 | vt 0.725481 0.561383 690 | vt 0.753019 0.529426 691 | vt 0.701137 0.653949 692 | vt 0.743520 0.635838 693 | vt 0.681790 0.600007 694 | vt 0.688052 0.566402 695 | vt 0.669805 0.631987 696 | vt 0.680982 0.600007 697 | vt 0.660641 0.568751 698 | vt 0.676877 0.549054 699 | vt 0.106153 0.396516 700 | vt 0.108864 0.424404 701 | vt 0.074917 0.426767 702 | vt 0.087065 0.409474 703 | vt 0.621376 0.522530 704 | vt 0.632241 0.496305 705 | vt 0.171316 0.391336 706 | vt 0.166105 0.419716 707 | vt 0.575830 0.489488 708 | vt 0.603738 0.470771 709 | vt 0.208812 0.389757 710 | vt 0.221968 0.421004 711 | vt 0.575010 0.451530 712 | vt 0.602596 0.445588 713 | vt 0.090492 0.877429 714 | vt 0.058309 0.869591 715 | vt 0.074831 0.838905 716 | vt 0.101890 0.857445 717 | vt 0.028239 0.838905 718 | vt 0.024924 0.894741 719 | vt 0.000000 0.899324 720 | vt 0.001834 0.849448 721 | vt 0.101890 0.926979 722 | vt 0.076639 0.925076 723 | vt 0.026240 0.915784 724 | vt 0.005420 0.929331 725 | vt 0.095497 0.957250 726 | vt 0.075543 0.946071 727 | vt 0.645344 0.437002 728 | vt 0.637902 0.458878 729 | vt 0.639042 0.416958 730 | vt 0.575010 0.719869 731 | vt 0.614138 0.725314 732 | vt 0.613672 0.749797 733 | vt 0.594895 0.762469 734 | vt 0.640686 0.476956 735 | vt 0.580512 0.694150 736 | vt 0.620053 0.707881 737 | vt 0.746608 0.668881 738 | vt 0.771846 0.686516 739 | vt 0.773896 0.724742 740 | vt 0.743520 0.694151 741 | vt 0.605951 0.678264 742 | vt 0.634479 0.690854 743 | vt 0.749233 0.626089 744 | vt 0.773896 0.618430 745 | vt 0.648494 0.640324 746 | vt 0.661386 0.661293 747 | vt 0.743789 0.606806 748 | vt 0.762864 0.600007 749 | vt 0.676081 0.661913 750 | vt 0.723534 0.534588 751 | vt 0.699512 0.542918 752 | vt 0.688925 0.677824 753 | vt 0.744273 0.498956 754 | vt 0.693381 0.720338 755 | vt 0.748252 0.469291 756 | vt 0.763477 0.474701 757 | vt 0.687353 0.750732 758 | vt 0.720428 0.433467 759 | vt 0.761349 0.400315 760 | vt 0.714334 0.312273 761 | vt 0.745932 0.349357 762 | vt 0.695375 0.350661 763 | vt 0.702000 0.316418 764 | vt 0.707436 0.426817 765 | vt 0.718361 0.391645 766 | vt 0.687200 0.359935 767 | vt 0.650252 0.395261 768 | vt 0.667797 0.424787 769 | vt 0.604231 0.792054 770 | vt 0.626898 0.770395 771 | vt 0.681505 0.394897 772 | vt 0.689571 0.422862 773 | vt 0.632440 0.807158 774 | vt 0.640476 0.779470 775 | vt 0.673190 0.368719 776 | vt 0.897179 0.108419 777 | vt 0.896802 0.094990 778 | vt 0.891289 0.082465 779 | vt 0.889541 0.119156 780 | vt 0.878496 0.070493 781 | vt 0.362075 0.668652 782 | vt 0.362275 0.641605 783 | vt 0.855921 0.068906 784 | vt 0.363331 0.733289 785 | vt 0.364762 0.675497 786 | vt 0.316534 0.687458 787 | vt 0.331179 0.741262 788 | vt 0.308253 0.748903 789 | vt 0.293948 0.691649 790 | vt 0.850473 0.065762 791 | vt 0.371218 0.769284 792 | vt 0.352184 0.764614 793 | vt 0.347255 0.737275 794 | vt 0.335850 0.778055 795 | vt 0.340918 0.683289 796 | vt 0.337948 0.663367 797 | vt 0.317062 0.679815 798 | vt 0.574198 0.815027 799 | vt 0.563149 0.817099 800 | vt 0.565556 0.802414 801 | vt 0.574114 0.797870 802 | vt 0.311528 0.951588 803 | vt 0.300805 0.941251 804 | vt 0.309349 0.939058 805 | vt 0.321081 0.951148 806 | vt 0.406952 0.958161 807 | vt 0.396837 0.958347 808 | vt 0.401589 0.942671 809 | vt 0.411781 0.944279 810 | vt 0.689933 0.940336 811 | vt 0.687878 0.961729 812 | vt 0.679229 0.961368 813 | vt 0.679528 0.943164 814 | vt 0.411781 0.980262 815 | vt 0.399942 0.973925 816 | vt 0.889983 0.590918 817 | vt 0.889673 0.576369 818 | vt 0.899839 0.569139 819 | vt 0.899839 0.590431 820 | vt 0.273051 0.660174 821 | vt 0.283873 0.659358 822 | vt 0.283494 0.677244 823 | vt 0.271964 0.670700 824 | vt 0.644139 0.963585 825 | vt 0.660853 0.967830 826 | vt 0.661592 0.972875 827 | vt 0.648791 0.975579 828 | vt 0.574198 0.776751 829 | vt 0.565463 0.778667 830 | vt 0.328632 0.972161 831 | vt 0.320423 0.974814 832 | vt 0.314862 0.991378 833 | vt 0.306768 0.988322 834 | vt 0.311402 0.974519 835 | vt 0.303990 0.955164 836 | vt 0.290821 0.654948 837 | vt 0.290821 0.672490 838 | vt 0.649872 0.957651 839 | vt 0.665169 0.963774 840 | vt 0.732844 0.944450 841 | vt 0.739864 0.944945 842 | vt 0.739370 0.955253 843 | vt 0.731238 0.959624 844 | vt 0.695863 0.958498 845 | vt 0.698412 0.966732 846 | vt 0.691688 0.973353 847 | vt 0.755298 0.962241 848 | vt 0.751985 0.969957 849 | vt 0.698412 0.942594 850 | vt 0.556374 0.813604 851 | vt 0.561449 0.804019 852 | vt 0.295618 0.948792 853 | vt 0.755298 0.937807 854 | vt 0.649357 0.947680 855 | vt 0.665169 0.940336 856 | vt 0.293948 0.970337 857 | vt 0.299507 0.995213 858 | vt 0.989693 0.432309 859 | vt 0.980723 0.452721 860 | vt 0.960318 0.448801 861 | vt 0.975083 0.406109 862 | vt 0.756965 0.359968 863 | vt 0.761443 0.381037 864 | vt 0.984316 0.468060 865 | vt 0.989693 0.478660 866 | vt 0.774029 0.346391 867 | vt 0.773491 0.350622 868 | vt 0.380535 0.781606 869 | vt 0.393222 0.759757 870 | vt 0.392436 0.776854 871 | vt 0.328632 0.930351 872 | vt 0.318068 0.928670 873 | vt 0.319272 0.778097 874 | vt 0.426911 0.759223 875 | vt 0.083642 0.727700 876 | vt 0.098949 0.765588 877 | vt 0.424248 0.774908 878 | vt 0.096321 0.719102 879 | vt 0.111152 0.756806 880 | vt 0.419096 0.790819 881 | vt 0.377808 0.809202 882 | vt 0.107535 0.682403 883 | vt 0.122971 0.745664 884 | vt 0.866230 0.114325 885 | vt 0.868695 0.093898 886 | vt 0.872561 0.092614 887 | vt 0.870601 0.111389 888 | vt 0.861765 0.072459 889 | vt 0.885897 0.113529 890 | vt 0.220217 0.981111 891 | vt 0.221355 0.987916 892 | vt 0.202854 0.969144 893 | vt 0.208563 0.967722 894 | vt 0.895201 0.103582 895 | vt 0.203636 0.951600 896 | vt 0.209123 0.951079 897 | vt 0.211264 0.939439 898 | vt 0.219944 0.930613 899 | vt 0.221355 0.935339 900 | vt 0.213914 0.941952 901 | vt 0.757008 0.977426 902 | vt 0.757584 0.968822 903 | vt 0.771072 0.968822 904 | vt 0.770496 0.977426 905 | vt 0.890379 0.962624 906 | vt 0.900372 0.962428 907 | vt 0.904226 0.972551 908 | vt 0.894234 0.972746 909 | vt 0.755298 0.952228 910 | vt 0.771857 0.954372 911 | vt 0.890459 0.948040 912 | vt 0.904226 0.946164 913 | vt 0.756714 0.937807 914 | vt 0.770491 0.942289 915 | vt 0.745952 0.813056 916 | vt 0.743520 0.798830 917 | vt 0.756681 0.798935 918 | vt 0.756681 0.815692 919 | vt 0.904226 0.971450 920 | vt 0.904226 0.950040 921 | vt 0.918059 0.946164 922 | vt 0.918059 0.967574 923 | vt 0.884214 0.086335 924 | vt 0.873418 0.066181 925 | vt 0.165476 0.954581 926 | vt 0.148470 0.950423 927 | vt 0.150284 0.940606 928 | vt 0.172354 0.936107 929 | vt 0.150284 0.960580 930 | vt 0.172354 0.976054 931 | vt 0.158976 0.932290 932 | vt 0.424943 0.822774 933 | vt 0.430452 0.809202 934 | vt 0.430452 0.835782 935 | vt 0.274602 0.638669 936 | vt 0.271964 0.621961 937 | vt 0.280415 0.621601 938 | vt 0.284425 0.634398 939 | vt 0.682559 0.353213 940 | vt 0.669370 0.358445 941 | vt 0.281808 0.654948 942 | vt 0.290967 0.645130 943 | vt 0.652380 0.373829 944 | vt 0.651041 0.360528 945 | vt 0.673203 0.433780 946 | vt 0.657283 0.443825 947 | vt 0.625109 0.370119 948 | vt 0.631267 0.357834 949 | vt 0.271964 0.607526 950 | vt 0.283375 0.608018 951 | vt 0.690983 0.342152 952 | vt 0.280221 0.563575 953 | vt 0.290967 0.572956 954 | vt 0.673869 0.746151 955 | vt 0.661562 0.778141 956 | vt 0.653115 0.772326 957 | vt 0.735133 0.492249 958 | vt 0.738167 0.467030 959 | vt 0.678575 0.720071 960 | vt 0.719357 0.521828 961 | vt 0.679536 0.687312 962 | vt 0.698546 0.526937 963 | vt 0.666723 0.675000 964 | vt 0.679505 0.536845 965 | vt 0.682948 0.524207 966 | vt 0.564147 0.669520 967 | vt 0.572002 0.674428 968 | vt 0.567099 0.694335 969 | vt 0.559424 0.683846 970 | vt 0.655499 0.498499 971 | vt 0.664813 0.488817 972 | vt 0.555429 0.633718 973 | vt 0.570670 0.633422 974 | vt 0.652125 0.474557 975 | vt 0.564074 0.616998 976 | vt 0.572002 0.609629 977 | vt 0.650305 0.459663 978 | vt 0.616579 0.348193 979 | vt 0.607067 0.356962 980 | vt 0.600216 0.343192 981 | vt 0.610691 0.337607 982 | vt 0.661924 0.450547 983 | vt 0.656016 0.461046 984 | vt 0.974029 0.856784 985 | vt 0.967186 0.861781 986 | vt 0.962361 0.843831 987 | vt 0.967277 0.843792 988 | vt 0.657355 0.474347 989 | vt 0.964651 0.828898 990 | vt 0.969507 0.830521 991 | vt 0.556955 0.712738 992 | vt 0.569005 0.694335 993 | vt 0.572002 0.698504 994 | vt 0.562871 0.714100 995 | vt 0.966900 0.814331 996 | vt 0.972371 0.815288 997 | vt 0.556374 0.748583 998 | vt 0.564385 0.746749 999 | vt 0.989441 0.783908 1000 | vt 0.994393 0.791017 1001 | vt 0.558884 0.762837 1002 | vt 0.566383 0.759775 1003 | vt 0.293886 0.556846 1004 | vt 0.287785 0.563575 1005 | vt 0.278455 0.552539 1006 | vt 0.285292 0.547486 1007 | vt 0.567501 0.776751 1008 | vt 0.572002 0.769520 1009 | vt 0.271964 0.531559 1010 | vt 0.280114 0.531597 1011 | vt 0.713736 0.517086 1012 | vt 0.730351 0.491586 1013 | vt 0.277456 0.501247 1014 | vt 0.283609 0.502841 1015 | vt 0.732563 0.469919 1016 | vt 0.289889 0.482528 1017 | vt 0.293886 0.487420 1018 | vt 0.718927 0.434513 1019 | vt 0.715948 0.441113 1020 | vt 0.148464 0.895770 1021 | vt 0.143656 0.899448 1022 | vt 0.135570 0.866897 1023 | vt 0.141940 0.867282 1024 | vt 0.705685 0.429650 1025 | vt 0.702706 0.436249 1026 | vt 0.139387 0.852749 1027 | vt 0.145757 0.853134 1028 | vt 0.673793 0.439644 1029 | vt 0.982761 0.870672 1030 | vt 0.978237 0.875401 1031 | vt 0.690569 0.428512 1032 | vt 0.689731 0.437230 1033 | vt 0.994393 0.876476 1034 | vt 0.989470 0.884032 1035 | vt 0.140609 0.838905 1036 | vt 0.148464 0.842149 1037 | vt 0.055572 0.894671 1038 | vt 0.058309 0.921428 1039 | vt 0.522074 0.852057 1040 | vt 0.486695 0.849184 1041 | vt 0.489208 0.828620 1042 | vt 0.520430 0.822953 1043 | vt 0.058309 0.844316 1044 | vt 0.508881 0.894777 1045 | vt 0.472011 0.896389 1046 | vt 0.831366 0.254469 1047 | vt 0.808268 0.234163 1048 | vt 0.831447 0.204948 1049 | vt 0.850473 0.224260 1050 | vt 0.522074 0.925736 1051 | vt 0.485558 0.934035 1052 | vt 0.791717 0.180509 1053 | vt 0.816867 0.159097 1054 | vt 0.151728 0.446781 1055 | vt 0.199527 0.448069 1056 | vt 0.769578 0.124229 1057 | vt 0.798199 0.108533 1058 | vt 0.100768 0.452706 1059 | vt 0.752146 0.091089 1060 | vt 0.785647 0.081045 1061 | vt 0.072959 0.455813 1062 | vt 0.788268 0.035810 1063 | vt 0.808943 0.037819 1064 | vt 0.975825 0.069854 1065 | vt 0.957345 0.061872 1066 | vt 0.976292 0.000000 1067 | vt 0.997482 0.018730 1068 | vt 0.293948 0.257642 1069 | vt 0.244721 0.304389 1070 | vt 0.232768 0.275226 1071 | vt 0.280200 0.243409 1072 | vt 0.973103 0.123734 1073 | vt 0.948410 0.121360 1074 | vt 0.197924 0.303010 1075 | vt 0.977593 0.162987 1076 | vt 0.963610 0.169110 1077 | vt 0.044793 0.337236 1078 | vt 0.052918 0.320348 1079 | vt 0.090144 0.300898 1080 | vt 0.073642 0.337232 1081 | vt 0.148788 0.809684 1082 | vt 0.158289 0.769889 1083 | vt 0.180190 0.767382 1084 | vt 0.181628 0.799112 1085 | vt 0.233700 0.752538 1086 | vt 0.170802 0.747741 1087 | vt 0.219015 0.729321 1088 | vt 0.231194 0.787113 1089 | vt 0.280429 0.751288 1090 | vt 0.264669 0.717598 1091 | vt 0.278877 0.785022 1092 | vt 0.958661 0.624496 1093 | vt 0.964491 0.592120 1094 | vt 0.991309 0.598511 1095 | vt 0.986462 0.631076 1096 | vt 0.948410 0.075036 1097 | vt 0.939492 0.036953 1098 | vt 0.956570 0.653562 1099 | vt 0.985189 0.664315 1100 | vt 0.731238 0.947640 1101 | vt 0.731238 0.976086 1102 | vt 0.707909 0.968462 1103 | vt 0.706043 0.937807 1104 | vt 0.952377 0.668853 1105 | vt 0.991309 0.693638 1106 | vt 0.276156 0.817250 1107 | vt 0.292417 0.827015 1108 | vt 0.282617 0.839785 1109 | vt 0.228440 0.822540 1110 | vt 0.381782 0.845289 1111 | vt 0.390614 0.809202 1112 | vt 0.424943 0.831070 1113 | vt 0.424943 0.869444 1114 | vt 0.057921 0.838905 1115 | vt 0.000000 0.838292 1116 | vt 0.094050 0.812614 1117 | vt 0.203406 0.703746 1118 | vt 0.159103 0.727917 1119 | vt 0.180755 0.830658 1120 | vt 0.247739 0.682403 1121 | vt 0.122376 0.323917 1122 | vt 0.102814 0.334788 1123 | vt 0.148470 0.839785 1124 | vt 0.382093 0.889844 1125 | vt 0.421293 0.895842 1126 | vt 0.116829 0.793676 1127 | vt 0.390623 0.914942 1128 | vt 0.418041 0.911354 1129 | vt 0.411167 0.925120 1130 | vt 0.392899 0.927794 1131 | vt 0.129772 0.767479 1132 | vt 0.126068 0.780792 1133 | vt 0.395034 0.942671 1134 | vt 0.405665 0.938008 1135 | vt 0.134623 0.755595 1136 | vt 0.151322 0.327166 1137 | vt 0.997482 0.210695 1138 | vt 0.988021 0.211103 1139 | vt 0.021646 0.029243 1140 | vt 0.091108 0.051740 1141 | vt 0.076388 0.098274 1142 | vt 0.000000 0.088986 1143 | vt 0.379259 0.389335 1144 | vt 0.404370 0.438031 1145 | vt 0.343005 0.502271 1146 | vt 0.308106 0.440711 1147 | vt 0.072537 0.174700 1148 | vt 0.005230 0.175770 1149 | vt 0.359376 0.337920 1150 | vt 0.294601 0.374142 1151 | vt 0.089418 0.277346 1152 | vt 0.047019 0.298090 1153 | vt 0.667446 0.207918 1154 | vt 0.752146 0.190211 1155 | vt 0.747887 0.258765 1156 | vt 0.649825 0.257583 1157 | vt 0.648407 0.215069 1158 | vt 0.633712 0.258765 1159 | vt 0.131847 0.322515 1160 | vt 0.148470 0.838905 1161 | vt 0.134042 0.820281 1162 | vt 0.214672 0.201388 1163 | vt 0.271621 0.165102 1164 | vt 0.701956 0.061640 1165 | vt 0.617737 0.072639 1166 | vt 0.625794 0.017586 1167 | vt 0.689096 0.000000 1168 | vt 0.421772 0.587055 1169 | vt 0.333564 0.609629 1170 | vt 0.293948 0.525180 1171 | vt 0.485072 0.490053 1172 | vt 0.580029 0.183312 1173 | vt 0.516317 0.260663 1174 | vt 0.482973 0.214953 1175 | vt 0.538605 0.128320 1176 | vt 0.185452 0.615518 1177 | vt 0.189319 0.540635 1178 | vt 0.270030 0.534352 1179 | vt 0.263961 0.624024 1180 | vt 0.427229 0.169711 1181 | vt 0.456168 0.060367 1182 | vt 0.524285 0.000000 1183 | vt 0.580029 0.045242 1184 | vt 0.314022 0.129003 1185 | vt 0.360275 0.019417 1186 | vt 0.570612 0.527578 1187 | vt 0.492527 0.609629 1188 | vt 0.818604 0.076568 1189 | vt 0.842262 0.090705 1190 | vt 0.076666 0.484759 1191 | vt 0.096004 0.501089 1192 | vt 0.861471 0.560932 1193 | vt 0.872572 0.578064 1194 | vt 0.821606 0.604353 1195 | vt 0.790281 0.570262 1196 | vt 0.080730 0.543251 1197 | vt 0.124868 0.570063 1198 | vt 0.447189 0.271055 1199 | vt 0.419631 0.312273 1200 | vt 0.392007 0.276025 1201 | vt 0.417228 0.233747 1202 | vt 0.076384 0.602257 1203 | vt 0.118738 0.630307 1204 | vt 0.344320 0.241303 1205 | vt 0.369564 0.197787 1206 | vt 0.049243 0.652029 1207 | vt 0.092495 0.682403 1208 | vt 0.293948 0.228567 1209 | vt 0.298130 0.176757 1210 | vt 0.567636 0.478821 1211 | vt 0.499182 0.438621 1212 | vt 0.522568 0.391578 1213 | vt 0.575010 0.425609 1214 | vt 0.157006 0.682403 1215 | vt 0.774029 0.505081 1216 | vt 0.860422 0.506464 1217 | vt 0.142875 0.473252 1218 | vt 0.842878 0.143191 1219 | vt 0.873354 0.393183 1220 | vt 0.781265 0.401718 1221 | vt 0.802783 0.314181 1222 | vt 0.889673 0.312273 1223 | vt 0.988418 0.586251 1224 | vt 0.947299 0.561290 1225 | vt 0.949920 0.529176 1226 | vt 0.988418 0.500232 1227 | vt 0.822256 0.986645 1228 | vt 0.820025 0.958373 1229 | vt 0.856736 0.920904 1230 | vt 0.856736 1.000000 1231 | vt 0.773079 0.724742 1232 | vt 0.773079 0.798830 1233 | vt 0.743520 0.790945 1234 | vt 0.757961 0.729082 1235 | vt 0.196309 0.430216 1236 | vt 0.229659 0.447430 1237 | vt 0.711700 0.287975 1238 | vt 0.704349 0.264478 1239 | vt 0.738608 0.258765 1240 | vt 0.738608 0.295880 1241 | vt 0.850473 0.000000 1242 | vt 0.012029 0.536111 1243 | vt 0.030116 0.458714 1244 | vt 0.889673 0.641181 1245 | vt 0.863537 0.647748 1246 | vt 0.019821 0.565185 1247 | vt 0.350885 0.301482 1248 | vt 0.333097 0.271097 1249 | vt 0.018300 0.601596 1250 | vt 0.774029 0.920904 1251 | vt 0.820025 0.942700 1252 | vt 0.820025 0.998443 1253 | vt 0.779069 0.978069 1254 | vt 0.001479 0.650976 1255 | vt 0.116145 0.169102 1256 | vt 0.150616 0.244071 1257 | vt 0.742673 0.147102 1258 | vt 0.667881 0.140156 1259 | vt 0.157651 0.165235 1260 | vt 0.742139 0.104802 1261 | vt 0.600629 0.115945 1262 | vt 0.141966 0.325670 1263 | vt 0.605717 0.185019 1264 | vt 0.592109 0.177927 1265 | vt 0.842959 0.254469 1266 | vt 0.850228 0.309143 1267 | vt 0.837487 0.309143 1268 | vt 0.580029 0.171011 1269 | vt 0.214965 0.060661 1270 | vt 0.155752 0.095154 1271 | vt 0.122784 0.073609 1272 | vt 0.183286 0.029354 1273 | vt 0.429896 0.400660 1274 | vt 0.456705 0.362277 1275 | vt 0.161172 0.000000 1276 | vt 0.403151 0.334246 1277 | vt 0.444028 0.319550 1278 | vt 0.434566 0.769565 1279 | vt 0.432084 0.729277 1280 | vt 0.445106 0.727840 1281 | vt 0.446082 0.758571 1282 | vt 0.512765 0.967639 1283 | vt 0.499708 0.963458 1284 | vt 0.503045 0.934035 1285 | vt 0.512765 0.946371 1286 | vt 0.463179 0.803267 1287 | vt 0.454773 0.822953 1288 | vt 0.137051 0.936933 1289 | vt 0.135570 0.900092 1290 | vt 0.148169 0.899448 1291 | vt 0.148169 0.941613 1292 | vt 0.503102 0.802451 1293 | vt 0.507028 0.822953 1294 | vt 0.458367 0.870686 1295 | vt 0.436168 0.842601 1296 | vt 0.438013 0.822953 1297 | vt 0.472011 0.857347 1298 | vt 0.540022 0.769345 1299 | vt 0.553486 0.781899 1300 | vt 0.459306 0.922520 1301 | vt 0.472011 0.922635 1302 | vt 0.541268 0.712862 1303 | vt 0.555429 0.709990 1304 | vt 0.931627 0.387197 1305 | vt 0.928729 0.442008 1306 | vt 0.920559 0.456380 1307 | vt 0.918101 0.384845 1308 | vt 0.520892 0.653728 1309 | vt 0.528789 0.635330 1310 | vt 0.960318 0.330553 1311 | vt 0.951834 0.312273 1312 | vt 0.535243 0.725714 1313 | vt 0.519029 0.677550 1314 | vt 0.016508 0.975660 1315 | vt 0.013999 0.929331 1316 | vt 0.026668 0.940633 1317 | vt 0.026668 0.994311 1318 | vt 0.979865 0.936588 1319 | vt 0.969774 0.938538 1320 | vt 0.975349 0.896029 1321 | vt 0.988116 0.884032 1322 | vt 0.433792 0.952840 1323 | vt 0.449273 0.920179 1324 | vt 0.441573 0.962978 1325 | vt 0.988116 0.983137 1326 | vt 0.976318 0.973901 1327 | vt 0.449851 0.881334 1328 | vt 0.396837 0.984432 1329 | vt 0.381782 0.970838 1330 | vt 0.383153 0.942671 1331 | vt 0.396837 0.946898 1332 | vt 0.432084 0.860946 1333 | vt 0.462662 0.760182 1334 | vt 0.478210 0.797177 1335 | vt 0.914443 0.290601 1336 | vt 0.909821 0.250817 1337 | vt 0.930957 0.240639 1338 | vt 0.935643 0.288316 1339 | vt 0.460307 0.733958 1340 | vt 0.906305 0.225393 1341 | vt 0.923429 0.211956 1342 | vt 0.191691 0.148246 1343 | vt 0.206159 0.167154 1344 | vt 0.745664 0.066798 1345 | vt 0.724272 0.059709 1346 | vt 0.505191 0.609629 1347 | vt 0.499118 0.643973 1348 | vt 0.655217 0.258765 1349 | vt 0.673385 0.268829 1350 | vt 0.673385 0.311226 1351 | vt 0.645986 0.286588 1352 | vt 0.274936 0.134614 1353 | vt 0.271964 0.399970 1354 | vt 0.293948 0.389757 1355 | vt 0.293948 0.462422 1356 | vt 0.276854 0.482528 1357 | vt 0.439348 0.704564 1358 | vt 0.450255 0.705283 1359 | vt 0.510466 0.991679 1360 | vt 0.502310 0.987189 1361 | vt 0.889180 0.936324 1362 | vt 0.886482 0.946528 1363 | vt 0.864189 0.945067 1364 | vt 0.863826 0.920904 1365 | vt 0.000000 0.970042 1366 | vt 0.001267 0.999858 1367 | vt 0.935791 0.822445 1368 | vt 0.916575 0.791871 1369 | vt 0.929628 0.783908 1370 | vt 0.939066 0.813609 1371 | vt 0.679229 0.985988 1372 | vt 0.670350 0.985422 1373 | vt 0.665169 0.949687 1374 | vt 0.674705 0.953644 1375 | vt 0.910095 0.814337 1376 | vt 0.918418 0.825070 1377 | vt 0.472539 0.958823 1378 | vt 0.494262 0.934035 1379 | vt 0.499708 0.956567 1380 | vt 0.488988 0.958940 1381 | vt 0.228308 0.102294 1382 | vt 0.232287 0.114065 1383 | vt 0.198849 0.138679 1384 | vt 0.204521 0.113340 1385 | vt 0.855895 0.163535 1386 | vt 0.887161 0.184339 1387 | vt 0.876472 0.200073 1388 | vt 0.856414 0.183774 1389 | vt 0.462413 0.687430 1390 | vt 0.474497 0.698029 1391 | vt 0.466329 0.714644 1392 | vt 0.905796 0.194695 1393 | vt 0.894257 0.210635 1394 | vt 0.251986 0.103534 1395 | vt 0.254296 0.102260 1396 | vt 0.007554 0.600510 1397 | vt 0.000000 0.594837 1398 | vt 0.866547 0.148301 1399 | vt 0.935643 0.175547 1400 | vt 0.574462 0.932212 1401 | vt 0.564967 0.923888 1402 | vt 0.574462 0.902707 1403 | vt 0.263341 0.081169 1404 | vt 0.247893 0.094660 1405 | vt 0.241467 0.083824 1406 | vt 0.257122 0.070790 1407 | vt 0.885206 0.218066 1408 | vt 0.896618 0.234223 1409 | vt 0.225024 0.092013 1410 | vt 0.870531 0.208056 1411 | vt 0.201236 0.103059 1412 | vt 0.850473 0.191757 1413 | vt 0.704573 0.310832 1414 | vt 0.704349 0.296631 1415 | vt 0.714742 0.295880 1416 | vt 0.714047 0.310832 1417 | vt 0.487018 0.970130 1418 | vt 0.499179 0.967873 1419 | vt 0.937126 0.829272 1420 | vt 0.921405 0.831125 1421 | vt 0.472011 0.970130 1422 | vt 0.610381 0.310248 1423 | vt 0.610159 0.299715 1424 | vt 0.621069 0.299481 1425 | vt 0.621069 0.311335 1426 | vt 0.679229 0.945549 1427 | vt 0.668607 0.940336 1428 | vt 0.877803 0.952730 1429 | vt 0.856736 0.951403 1430 | vt 0.126015 0.954835 1431 | vt 0.135570 0.959560 1432 | vt 0.122754 0.969325 1433 | vt 0.113665 0.965748 1434 | vt 0.274834 0.059092 1435 | vt 0.269909 0.048390 1436 | vt 0.900820 0.261161 1437 | vt 0.293948 0.034786 1438 | vt 0.289787 0.025743 1439 | vt 0.906547 0.299867 1440 | vt 0.036850 0.965406 1441 | vt 0.048922 0.992938 1442 | vt 0.040468 0.990298 1443 | vt 0.026668 0.964300 1444 | vt 0.946902 0.217482 1445 | vt 0.936143 0.223060 1446 | vt 0.935643 0.194083 1447 | vt 0.946902 0.188492 1448 | vt 0.048922 0.930700 1449 | vt 0.039653 0.929331 1450 | vt 0.126014 0.838905 1451 | vt 0.135570 0.846960 1452 | vt 0.113426 0.868037 1453 | vt 0.105385 0.860578 1454 | vt 0.962361 0.942653 1455 | vt 0.963509 0.900347 1456 | vt 0.112300 0.912458 1457 | vt 0.101890 0.906609 1458 | vt 0.889180 0.983454 1459 | vt 0.881860 0.991814 1460 | vt 0.936550 0.851512 1461 | vt 0.921549 0.846611 1462 | vt 0.970225 0.344225 1463 | vt 0.975596 0.323711 1464 | vt 0.987958 0.332168 1465 | vt 0.983268 0.346671 1466 | vt 0.930334 0.872776 1467 | vt 0.916084 0.868415 1468 | vt 0.972440 0.363834 1469 | vt 0.983390 0.367652 1470 | vt 0.923118 0.890806 1471 | vt 0.908951 0.887343 1472 | vt 0.974173 0.382859 1473 | vt 0.985981 0.386414 1474 | vt 0.924080 0.904083 1475 | vt 0.908359 0.905936 1476 | vt 0.969635 0.394779 1477 | vt 0.981997 0.403237 1478 | vt 0.892040 0.905399 1479 | vt 0.890379 0.877643 1480 | vt 1.000000 0.388901 1481 | vt 0.999557 0.406108 1482 | vt 0.895026 0.858048 1483 | vt 0.888444 0.249841 1484 | vt 0.876397 0.235083 1485 | vt 0.903243 0.843253 1486 | vt 0.998476 0.352064 1487 | vt 0.999726 0.370503 1488 | vt 0.911430 0.821163 1489 | vt 1.000000 0.326242 1490 | vt 0.411781 0.943089 1491 | vt 0.430103 0.942671 1492 | vt 0.430103 0.970894 1493 | vt 0.419030 0.952211 1494 | vt 0.960318 0.324089 1495 | vt 0.977440 0.312273 1496 | vt 0.962361 0.875355 1497 | vt 0.946487 0.825654 1498 | vt 0.267013 0.933402 1499 | vt 0.264069 0.912692 1500 | vt 0.292746 0.910223 1501 | vt 0.264965 0.956247 1502 | vt 0.962361 0.921218 1503 | vt 0.258163 0.894617 1504 | vt 0.292746 0.863897 1505 | vt 0.934398 0.946163 1506 | vt 0.256486 0.880441 1507 | vt 0.271681 0.839785 1508 | vt 0.905328 0.942346 1509 | vt 0.704349 0.292481 1510 | vt 0.690905 0.299185 1511 | vt 0.679688 0.274541 1512 | vt 0.704349 0.258765 1513 | vt 0.673385 0.302956 1514 | vt 0.932828 0.721718 1515 | vt 0.952377 0.783908 1516 | vt 0.909942 0.762286 1517 | vt 0.897519 0.705594 1518 | vt 0.916013 0.329570 1519 | vt 0.889673 0.396392 1520 | vt 0.936731 0.651471 1521 | vt 0.917369 0.638551 1522 | vt 0.901387 0.469335 1523 | vt 0.952377 0.596860 1524 | vt 0.936057 0.592120 1525 | vt 0.960318 0.494109 1526 | vt 0.942203 0.500232 1527 | vt 0.523874 0.907122 1528 | vt 0.522074 0.859522 1529 | vt 0.537284 0.848573 1530 | vt 0.549369 0.891105 1531 | vt 0.610159 0.312158 1532 | vt 0.590964 0.309883 1533 | vt 0.580029 0.258765 1534 | vt 0.610159 0.261383 1535 | vt 0.527972 0.948207 1536 | vt 0.564569 0.932163 1537 | vt 0.799049 0.920904 1538 | vt 0.774029 0.902861 1539 | vt 0.778547 0.845992 1540 | vt 0.812589 0.866962 1541 | vt 0.947299 0.529068 1542 | vt 0.941010 0.565242 1543 | vt 0.901371 0.569139 1544 | vt 0.911109 0.530052 1545 | vt 0.787400 0.807517 1546 | vt 0.817911 0.819723 1547 | vt 0.897519 0.729227 1548 | vt 0.776129 0.719522 1549 | vt 0.774029 0.647748 1550 | vt 0.889602 0.682084 1551 | vt 0.890379 0.783908 1552 | vt 0.890379 0.855797 1553 | vt 0.896052 0.783908 1554 | vt 0.797107 0.783908 1555 | vt 0.591036 0.914734 1556 | vt 0.603948 0.818493 1557 | vt 0.644139 0.832771 1558 | vt 0.644139 0.954420 1559 | vt 0.564569 0.822953 1560 | vt 0.575010 0.858494 1561 | vt 0.889673 0.500232 1562 | vt 0.947299 0.503035 1563 | vt 0.799829 0.787255 1564 | vt 0.851587 0.806273 1565 | vt 0.250813 0.057005 1566 | vt 0.173962 0.122294 1567 | vt 0.467433 0.312273 1568 | vt 0.558640 0.393985 1569 | vt 0.332227 0.947254 1570 | vt 0.363627 0.928670 1571 | vt 0.363627 0.976907 1572 | vt 0.328632 0.989575 1573 | vt 0.952377 0.723812 1574 | vt 0.992317 0.693638 1575 | vt 0.992317 0.762112 1576 | vt 0.960747 0.771616 1577 | vn 0.665000 -0.200800 0.719400 1578 | vn -0.665000 -0.200800 0.719400 1579 | vn 0.829400 -0.303600 0.468900 1580 | vn -0.829400 -0.303600 0.468900 1581 | vn 0.415500 -0.793300 0.444900 1582 | vn -0.415500 -0.793300 0.444900 1583 | vn 0.360000 -0.508900 0.782000 1584 | vn -0.360000 -0.508900 0.782000 1585 | vn -0.078700 -0.539400 0.838400 1586 | vn 0.078700 -0.539400 0.838400 1587 | vn -0.269600 -0.841300 0.468500 1588 | vn 0.269600 -0.841300 0.468500 1589 | vn -0.770700 -0.335200 0.542000 1590 | vn 0.770700 -0.335200 0.542000 1591 | vn -0.468900 -0.194000 0.861700 1592 | vn 0.468900 -0.194000 0.861700 1593 | vn -0.476700 0.190700 0.858100 1594 | vn 0.476700 0.190700 0.858100 1595 | vn -0.767200 0.326400 0.552100 1596 | vn 0.767200 0.326400 0.552100 1597 | vn -0.251900 0.817300 0.518200 1598 | vn 0.251900 0.817300 0.518200 1599 | vn -0.094900 0.569600 0.816400 1600 | vn 0.094900 0.569600 0.816400 1601 | vn 0.366700 0.537000 0.759700 1602 | vn -0.366700 0.537000 0.759700 1603 | vn 0.414100 0.767200 0.489800 1604 | vn -0.414100 0.767200 0.489800 1605 | vn 0.827700 0.295200 0.477100 1606 | vn -0.827700 0.295200 0.477100 1607 | vn 0.671300 0.197100 0.714500 1608 | vn -0.671300 0.197100 0.714500 1609 | vn 0.811100 0.324400 -0.486700 1610 | vn -0.811100 0.324400 -0.486700 1611 | vn 0.205200 0.820600 -0.533400 1612 | vn -0.205200 0.820600 -0.533400 1613 | vn -0.422300 0.780600 -0.460700 1614 | vn 0.422300 0.780600 -0.460700 1615 | vn -0.824100 0.322500 -0.465800 1616 | vn 0.824100 0.322500 -0.465800 1617 | vn -0.813700 -0.348700 -0.465000 1618 | vn 0.813700 -0.348700 -0.465000 1619 | vn -0.422300 -0.780600 -0.460700 1620 | vn 0.422300 -0.780600 -0.460700 1621 | vn 0.205200 -0.820600 -0.533400 1622 | vn -0.205200 -0.820600 -0.533400 1623 | vn 0.799500 -0.351000 -0.487500 1624 | vn -0.799500 -0.351000 -0.487500 1625 | vn 0.400000 -0.062300 0.914400 1626 | vn -0.400000 -0.062300 0.914400 1627 | vn 0.306900 -0.175400 0.935400 1628 | vn -0.306900 -0.175400 0.935400 1629 | vn 0.094500 -0.183500 0.978500 1630 | vn -0.094500 -0.183500 0.978500 1631 | vn -0.062400 -0.028300 0.997700 1632 | vn 0.062400 -0.028300 0.997700 1633 | vn -0.062400 0.026000 0.997700 1634 | vn 0.062400 0.026000 0.997700 1635 | vn 0.099600 0.172900 0.979900 1636 | vn -0.099600 0.172900 0.979900 1637 | vn 0.303600 0.165600 0.938300 1638 | vn -0.303600 0.165600 0.938300 1639 | vn 0.400200 0.057200 0.914700 1640 | vn -0.400200 0.057200 0.914700 1641 | vn 0.123100 -0.861600 0.492400 1642 | vn -0.123100 -0.861600 0.492400 1643 | vn 0.219000 -0.864700 0.452000 1644 | vn -0.219000 -0.864700 0.452000 1645 | vn 0.590200 -0.455000 0.666800 1646 | vn -0.590200 -0.455000 0.666800 1647 | vn 0.768900 -0.050600 0.637400 1648 | vn -0.768900 -0.050600 0.637400 1649 | vn 0.779600 0.090000 0.619700 1650 | vn -0.779600 0.090000 0.619700 1651 | vn 0.324100 -0.818800 0.473900 1652 | vn -0.324100 -0.818800 0.473900 1653 | vn 0.385700 -0.662900 0.641700 1654 | vn -0.385700 -0.662900 0.641700 1655 | vn 0.689500 -0.419300 0.590600 1656 | vn -0.689500 -0.419300 0.590600 1657 | vn 0.658800 -0.363400 0.658800 1658 | vn -0.658800 -0.363400 0.658800 1659 | vn 0.546500 0.370700 0.750900 1660 | vn -0.546500 0.370700 0.750900 1661 | vn 0.506400 0.646400 0.570600 1662 | vn -0.506400 0.646400 0.570600 1663 | vn 0.609200 0.516700 0.601500 1664 | vn -0.609200 0.516700 0.601500 1665 | vn -0.044100 0.661000 0.749100 1666 | vn 0.044100 0.661000 0.749100 1667 | vn -0.724600 0.318700 0.611000 1668 | vn 0.724600 0.318700 0.611000 1669 | vn -0.588000 0.555400 0.588000 1670 | vn 0.588000 0.555400 0.588000 1671 | vn 0.536100 -0.390900 0.748200 1672 | vn -0.536100 -0.390900 0.748200 1673 | vn 0.220700 -0.469000 0.855200 1674 | vn -0.220700 -0.469000 0.855200 1675 | vn -0.079400 -0.532100 0.842900 1676 | vn 0.079400 -0.532100 0.842900 1677 | vn -0.082500 -0.657500 0.749000 1678 | vn 0.082500 -0.657500 0.749000 1679 | vn 0.045700 -0.566700 0.822600 1680 | vn -0.045700 -0.566700 0.822600 1681 | vn 0.278400 -0.213000 0.936500 1682 | vn -0.278400 -0.213000 0.936500 1683 | vn 0.381300 -0.182400 0.906300 1684 | vn -0.381300 -0.182400 0.906300 1685 | vn 0.335700 -0.287800 0.896900 1686 | vn -0.335700 -0.287800 0.896900 1687 | vn 0.376200 0.060300 0.924600 1688 | vn -0.376200 0.060300 0.924600 1689 | vn -0.135200 0.268000 0.953900 1690 | vn 0.135200 0.268000 0.953900 1691 | vn 0.396100 -0.432100 0.810200 1692 | vn -0.396100 -0.432100 0.810200 1693 | vn 0.185600 -0.247400 0.951000 1694 | vn -0.185600 -0.247400 0.951000 1695 | vn 0.009900 -0.194800 0.980800 1696 | vn -0.009900 -0.194800 0.980800 1697 | vn 0.072100 -0.696600 0.713800 1698 | vn -0.072100 -0.696600 0.713800 1699 | vn 0.186300 -0.572300 0.798600 1700 | vn -0.186300 -0.572300 0.798600 1701 | vn 0.315700 -0.270800 0.909400 1702 | vn -0.315700 -0.270800 0.909400 1703 | vn 0.306300 -0.026500 0.951600 1704 | vn -0.306300 -0.026500 0.951600 1705 | vn 0.326600 -0.130600 0.936100 1706 | vn -0.326600 -0.130600 0.936100 1707 | vn -0.013700 0.057400 0.998300 1708 | vn 0.013700 0.057400 0.998300 1709 | vn -0.002600 -0.065600 0.997800 1710 | vn 0.002600 -0.065600 0.997800 1711 | vn 0.000000 0.000000 1.000000 1712 | vn 0.817400 -0.574400 -0.044200 1713 | vn -0.817400 -0.574400 -0.044200 1714 | vn 0.949400 0.229700 -0.214400 1715 | vn -0.949400 0.229700 -0.214400 1716 | vn 0.082500 0.907300 -0.412400 1717 | vn -0.082500 0.907300 -0.412400 1718 | vn -0.883600 0.355500 0.304700 1719 | vn 0.883600 0.355500 0.304700 1720 | vn 0.420700 -0.879700 0.221800 1721 | vn -0.420700 -0.879700 0.221800 1722 | vn 0.287300 -0.574700 0.766300 1723 | vn -0.287300 -0.574700 0.766300 1724 | vn -0.654200 0.601900 0.458000 1725 | vn 0.654200 0.601900 0.458000 1726 | vn 0.105200 0.789200 0.605100 1727 | vn -0.105200 0.789200 0.605100 1728 | vn 0.758200 0.291600 0.583200 1729 | vn -0.758200 0.291600 0.583200 1730 | vn 0.388900 -0.713000 0.583400 1731 | vn -0.388900 -0.713000 0.583400 1732 | vn 0.046300 0.231400 0.971800 1733 | vn -0.046300 0.231400 0.971800 1734 | vn 0.033500 -0.401800 0.915100 1735 | vn -0.033500 -0.401800 0.915100 1736 | vn -0.445200 -0.161000 0.880900 1737 | vn 0.445200 -0.161000 0.880900 1738 | vn -0.218200 -0.436400 0.872900 1739 | vn 0.218200 -0.436400 0.872900 1740 | vn 0.434100 -0.129000 0.891600 1741 | vn -0.434100 -0.129000 0.891600 1742 | vn 0.300800 0.050100 0.952400 1743 | vn -0.300800 0.050100 0.952400 1744 | vn 0.812300 0.301000 0.499600 1745 | vn -0.812300 0.301000 0.499600 1746 | vn 0.875300 0.257400 0.409300 1747 | vn -0.875300 0.257400 0.409300 1748 | vn 0.938500 0.160100 0.306000 1749 | vn -0.938500 0.160100 0.306000 1750 | vn 0.223700 -0.653900 0.722700 1751 | vn -0.223700 -0.653900 0.722700 1752 | vn -0.153600 -0.199700 0.967700 1753 | vn 0.153600 -0.199700 0.967700 1754 | vn -0.273300 -0.102500 0.956500 1755 | vn 0.273300 -0.102500 0.956500 1756 | vn -0.097600 0.195200 0.975900 1757 | vn 0.097600 0.195200 0.975900 1758 | vn -0.158200 0.949400 0.271300 1759 | vn 0.158200 0.949400 0.271300 1760 | vn -0.693400 0.708200 0.132800 1761 | vn 0.693400 0.708200 0.132800 1762 | vn -1.000000 0.000000 0.000000 1763 | vn 1.000000 0.000000 0.000000 1764 | vn 0.305100 -0.945000 0.118100 1765 | vn -0.305100 -0.945000 0.118100 1766 | vn 0.029800 -0.298100 0.954100 1767 | vn -0.029800 -0.298100 0.954100 1768 | vn 0.135300 -0.347900 0.927700 1769 | vn -0.135300 -0.347900 0.927700 1770 | vn -0.508500 -0.275500 0.815800 1771 | vn 0.508500 -0.275500 0.815800 1772 | vn -0.384300 -0.041900 0.922300 1773 | vn 0.384300 -0.041900 0.922300 1774 | vn -0.208300 0.037400 0.977400 1775 | vn 0.208300 0.037400 0.977400 1776 | vn -0.572100 -0.476700 0.667400 1777 | vn 0.572100 -0.476700 0.667400 1778 | vn -0.136900 -0.753100 0.643500 1779 | vn 0.136900 -0.753100 0.643500 1780 | vn 0.408800 -0.607100 0.681400 1781 | vn -0.408800 -0.607100 0.681400 1782 | vn 0.574000 -0.413000 0.707000 1783 | vn -0.574000 -0.413000 0.707000 1784 | vn 0.566500 -0.096800 0.818300 1785 | vn -0.566500 -0.096800 0.818300 1786 | vn 0.570300 0.118000 0.812900 1787 | vn -0.570300 0.118000 0.812900 1788 | vn 0.482300 0.562100 0.671900 1789 | vn -0.482300 0.562100 0.671900 1790 | vn 0.260400 0.611400 0.747300 1791 | vn -0.260400 0.611400 0.747300 1792 | vn 0.164000 0.360700 0.918200 1793 | vn -0.164000 0.360700 0.918200 1794 | vn -0.017800 0.249500 0.968200 1795 | vn 0.017800 0.249500 0.968200 1796 | vn 0.327300 -0.416600 0.848100 1797 | vn -0.327300 -0.416600 0.848100 1798 | vn 0.281100 -0.261000 0.923500 1799 | vn -0.281100 -0.261000 0.923500 1800 | vn -0.254200 -0.651400 0.714900 1801 | vn 0.254200 -0.651400 0.714900 1802 | vn -0.026000 -0.845500 0.533300 1803 | vn 0.026000 -0.845500 0.533300 1804 | vn -0.351800 -0.260600 0.899100 1805 | vn 0.351800 -0.260600 0.899100 1806 | vn -0.352300 -0.011000 0.935800 1807 | vn 0.352300 -0.011000 0.935800 1808 | vn -0.131700 0.460800 0.877700 1809 | vn 0.131700 0.460800 0.877700 1810 | vn -0.034200 0.615900 0.787000 1811 | vn 0.034200 0.615900 0.787000 1812 | vn 0.360300 0.583600 0.727700 1813 | vn -0.360300 0.583600 0.727700 1814 | vn 0.498800 0.530000 0.685800 1815 | vn -0.498800 0.530000 0.685800 1816 | vn 0.666700 -0.333300 0.666700 1817 | vn -0.666700 -0.333300 0.666700 1818 | vn 0.816500 -0.073100 0.572700 1819 | vn -0.816500 -0.073100 0.572700 1820 | vn 0.784000 0.116100 0.609800 1821 | vn -0.784000 0.116100 0.609800 1822 | vn -0.530600 0.811100 -0.246100 1823 | vn 0.530600 0.811100 -0.246100 1824 | vn -0.851100 0.369500 -0.373000 1825 | vn 0.851100 0.369500 -0.373000 1826 | vn -0.244600 0.867500 -0.433100 1827 | vn 0.244600 0.867500 -0.433100 1828 | vn 0.592400 0.746500 -0.303000 1829 | vn -0.592400 0.746500 -0.303000 1830 | vn 0.368500 0.875800 -0.311800 1831 | vn -0.368500 0.875800 -0.311800 1832 | vn 0.282100 0.915100 -0.288000 1833 | vn -0.282100 0.915100 -0.288000 1834 | vn 0.856100 0.134000 -0.499100 1835 | vn -0.856100 0.134000 -0.499100 1836 | vn 0.534200 -0.723300 -0.437600 1837 | vn -0.534200 -0.723300 -0.437600 1838 | vn 0.384900 -0.813100 -0.436800 1839 | vn -0.384900 -0.813100 -0.436800 1840 | vn 0.233500 -0.580600 -0.780000 1841 | vn -0.233500 -0.580600 -0.780000 1842 | vn 0.244900 -0.058300 -0.967800 1843 | vn -0.244900 -0.058300 -0.967800 1844 | vn 0.116300 -0.453500 -0.883700 1845 | vn -0.116300 -0.453500 -0.883700 1846 | vn 0.115200 -0.983600 -0.138800 1847 | vn -0.115200 -0.983600 -0.138800 1848 | vn 0.118400 -0.966900 -0.226000 1849 | vn -0.118400 -0.966900 -0.226000 1850 | vn 0.959700 -0.008500 -0.280800 1851 | vn -0.959700 -0.008500 -0.280800 1852 | vn 0.931900 0.162900 -0.324200 1853 | vn -0.931900 0.162900 -0.324200 1854 | vn 0.162600 0.020700 -0.986500 1855 | vn -0.162600 0.020700 -0.986500 1856 | vn -0.018800 -0.217700 -0.975800 1857 | vn 0.018800 -0.217700 -0.975800 1858 | vn 0.753800 -0.292600 -0.588400 1859 | vn -0.753800 -0.292600 -0.588400 1860 | vn 0.919600 0.137900 -0.367800 1861 | vn -0.919600 0.137900 -0.367800 1862 | vn 0.929700 0.312700 -0.194400 1863 | vn -0.929700 0.312700 -0.194400 1864 | vn 0.912000 0.337600 -0.232900 1865 | vn -0.912000 0.337600 -0.232900 1866 | vn 0.940700 0.333800 -0.060700 1867 | vn -0.940700 0.333800 -0.060700 1868 | vn 0.176100 -0.880500 -0.440200 1869 | vn -0.176100 -0.880500 -0.440200 1870 | vn 0.370800 -0.473300 -0.799100 1871 | vn -0.370800 -0.473300 -0.799100 1872 | vn 0.310700 -0.828400 -0.466000 1873 | vn -0.310700 -0.828400 -0.466000 1874 | vn 0.279300 -0.951500 -0.128700 1875 | vn -0.279300 -0.951500 -0.128700 1876 | vn 0.313900 -0.932100 -0.180700 1877 | vn -0.313900 -0.932100 -0.180700 1878 | vn 0.976200 -0.208300 -0.060900 1879 | vn -0.976200 -0.208300 -0.060900 1880 | vn 0.826700 -0.506600 0.244700 1881 | vn -0.826700 -0.506600 0.244700 1882 | vn 0.344900 -0.115800 -0.931500 1883 | vn -0.344900 -0.115800 -0.931500 1884 | vn 0.120300 0.964400 0.235500 1885 | vn -0.120300 0.964400 0.235500 1886 | vn 0.127500 0.974400 -0.185100 1887 | vn -0.127500 0.974400 -0.185100 1888 | vn 0.349200 0.594700 -0.724100 1889 | vn -0.349200 0.594700 -0.724100 1890 | vn 0.415300 0.898100 -0.144900 1891 | vn -0.415300 0.898100 -0.144900 1892 | vn 0.184500 0.703600 0.686300 1893 | vn -0.184500 0.703600 0.686300 1894 | vn 0.605600 0.779400 0.160800 1895 | vn -0.605600 0.779400 0.160800 1896 | vn 0.703300 0.680600 -0.205300 1897 | vn -0.703300 0.680600 -0.205300 1898 | vn 0.667900 0.200700 -0.716600 1899 | vn -0.667900 0.200700 -0.716600 1900 | vn 0.494800 0.434200 -0.752800 1901 | vn -0.494800 0.434200 -0.752800 1902 | vn 0.642300 0.745900 -0.176100 1903 | vn -0.642300 0.745900 -0.176100 1904 | vn 0.718200 0.678800 0.153000 1905 | vn -0.718200 0.678800 0.153000 1906 | vn 0.738800 0.397200 0.544400 1907 | vn -0.738800 0.397200 0.544400 1908 | vn 0.342800 0.926100 -0.157900 1909 | vn -0.342800 0.926100 -0.157900 1910 | vn 0.227000 0.574000 0.786700 1911 | vn -0.227000 0.574000 0.786700 1912 | vn -0.172200 0.104600 -0.979500 1913 | vn 0.172200 0.104600 -0.979500 1914 | vn 0.042500 0.915000 0.401300 1915 | vn -0.042500 0.915000 0.401300 1916 | vn -0.161600 0.184700 0.969400 1917 | vn 0.161600 0.184700 0.969400 1918 | vn 0.979100 0.197300 0.048300 1919 | vn -0.979100 0.197300 0.048300 1920 | vn 0.947000 0.091800 0.307900 1921 | vn -0.947000 0.091800 0.307900 1922 | vn 0.979400 0.190500 -0.066100 1923 | vn -0.979400 0.190500 -0.066100 1924 | vn 0.993800 0.031200 -0.107000 1925 | vn -0.993800 0.031200 -0.107000 1926 | vn 0.711600 -0.700800 0.050100 1927 | vn -0.711600 -0.700800 0.050100 1928 | vn 0.372200 -0.924300 0.084700 1929 | vn -0.372200 -0.924300 0.084700 1930 | vn 0.446500 -0.864400 0.231000 1931 | vn -0.446500 -0.864400 0.231000 1932 | vn 0.606600 -0.757800 0.240500 1933 | vn -0.606600 -0.757800 0.240500 1934 | vn 0.732500 -0.636800 0.240700 1935 | vn -0.732500 -0.636800 0.240700 1936 | vn 0.263700 -0.449900 0.853300 1937 | vn -0.263700 -0.449900 0.853300 1938 | vn 0.556800 -0.318100 -0.767300 1939 | vn -0.556800 -0.318100 -0.767300 1940 | vn 0.500400 -0.280700 -0.819000 1941 | vn -0.500400 -0.280700 -0.819000 1942 | vn 0.319000 -0.849400 -0.420500 1943 | vn -0.319000 -0.849400 -0.420500 1944 | vn 0.719800 -0.635600 -0.279300 1945 | vn -0.719800 -0.635600 -0.279300 1946 | vn 0.497200 -0.440800 -0.747300 1947 | vn -0.497200 -0.440800 -0.747300 1948 | vn 0.350600 0.380700 0.855700 1949 | vn -0.350600 0.380700 0.855700 1950 | vn 0.456600 0.171500 0.873000 1951 | vn -0.456600 0.171500 0.873000 1952 | vn 0.258300 0.105500 0.960300 1953 | vn -0.258300 0.105500 0.960300 1954 | vn 0.245500 -0.080200 0.966100 1955 | vn -0.245500 -0.080200 0.966100 1956 | vn 0.464300 -0.059900 0.883700 1957 | vn -0.464300 -0.059900 0.883700 1958 | vn 0.622500 -0.304500 0.721000 1959 | vn -0.622500 -0.304500 0.721000 1960 | vn 0.450000 0.659000 0.602700 1961 | vn -0.450000 0.659000 0.602700 1962 | vn -0.266700 0.830900 0.488400 1963 | vn 0.266700 0.830900 0.488400 1964 | vn -0.828400 0.229100 0.511100 1965 | vn 0.828400 0.229100 0.511100 1966 | vn -0.525100 -0.356600 0.772700 1967 | vn 0.525100 -0.356600 0.772700 1968 | vn 0.454600 -0.566500 0.687300 1969 | vn -0.454600 -0.566500 0.687300 1970 | vn 0.699600 -0.449700 0.555200 1971 | vn -0.699600 -0.449700 0.555200 1972 | vn 0.722000 -0.682700 -0.112600 1973 | vn -0.722000 -0.682700 -0.112600 1974 | vn -0.191900 0.286000 0.938800 1975 | vn 0.191900 0.286000 0.938800 1976 | vn 0.904800 -0.373400 -0.204700 1977 | vn -0.904800 -0.373400 -0.204700 1978 | vn 0.103400 0.155100 0.982500 1979 | vn -0.103400 0.155100 0.982500 1980 | vn 0.084100 0.931800 0.353000 1981 | vn -0.084100 0.931800 0.353000 1982 | vn 0.644600 -0.088300 0.759400 1983 | vn -0.644600 -0.088300 0.759400 1984 | vn 0.430900 0.474000 0.767800 1985 | vn -0.430900 0.474000 0.767800 1986 | vn 0.803200 -0.484700 0.346200 1987 | vn -0.803200 -0.484700 0.346200 1988 | vn 0.581100 -0.412800 0.701400 1989 | vn -0.581100 -0.412800 0.701400 1990 | vn 0.591000 -0.430500 0.682200 1991 | vn -0.591000 -0.430500 0.682200 1992 | vn 0.981800 -0.180400 -0.059100 1993 | vn -0.981800 -0.180400 -0.059100 1994 | vn 0.910500 -0.396500 -0.117500 1995 | vn -0.910500 -0.396500 -0.117500 1996 | vn 0.997200 -0.018100 -0.072500 1997 | vn -0.997200 -0.018100 -0.072500 1998 | vn 0.731300 -0.654300 0.192500 1999 | vn -0.731300 -0.654300 0.192500 2000 | vn 0.786700 -0.607900 0.107300 2001 | vn -0.786700 -0.607900 0.107300 2002 | vn 0.702200 -0.702200 0.117000 2003 | vn -0.702200 -0.702200 0.117000 2004 | vn 0.184000 0.981600 -0.051100 2005 | vn -0.184000 0.981600 -0.051100 2006 | vn 0.935200 0.330100 0.128400 2007 | vn -0.935200 0.330100 0.128400 2008 | vn 0.663300 -0.746300 0.055300 2009 | vn -0.663300 -0.746300 0.055300 2010 | vn -0.008500 0.997000 0.076700 2011 | vn 0.008500 0.997000 0.076700 2012 | vn 0.623700 -0.706100 0.335400 2013 | vn -0.623700 -0.706100 0.335400 2014 | vn 0.273300 -0.892500 0.358700 2015 | vn -0.273300 -0.892500 0.358700 2016 | vn -0.832800 -0.508000 -0.220000 2017 | vn 0.832800 -0.508000 -0.220000 2018 | vn -0.833900 0.237700 -0.498100 2019 | vn 0.833900 0.237700 -0.498100 2020 | vn -0.565500 0.784700 -0.253900 2021 | vn 0.565500 0.784700 -0.253900 2022 | vn -0.056000 0.996200 0.067200 2023 | vn 0.056000 0.996200 0.067200 2024 | vn 0.144500 0.022200 0.989300 2025 | vn -0.144500 0.022200 0.989300 2026 | vn 0.327500 0.064500 0.942700 2027 | vn -0.327500 0.064500 0.942700 2028 | vn 0.312700 0.023200 0.949600 2029 | vn -0.312700 0.023200 0.949600 2030 | vn 0.171000 0.027400 0.984900 2031 | vn -0.171000 0.027400 0.984900 2032 | vn 0.348700 0.284900 0.892900 2033 | vn -0.348700 0.284900 0.892900 2034 | vn 0.400600 -0.034300 0.915600 2035 | vn -0.400600 -0.034300 0.915600 2036 | vn 0.257200 -0.060300 0.964500 2037 | vn -0.257200 -0.060300 0.964500 2038 | vn 0.063700 -0.010600 0.997900 2039 | vn -0.063700 -0.010600 0.997900 2040 | vn -0.363700 0.703900 0.610100 2041 | vn 0.363700 0.703900 0.610100 2042 | vn 0.629900 0.035500 0.775900 2043 | vn -0.629900 0.035500 0.775900 2044 | vn 0.447200 -0.200200 0.871700 2045 | vn -0.447200 -0.200200 0.871700 2046 | vn 0.507200 -0.214100 0.834800 2047 | vn -0.507200 -0.214100 0.834800 2048 | vn 0.525800 0.261900 0.809300 2049 | vn -0.525800 0.261900 0.809300 2050 | vn 0.298000 0.580200 0.758000 2051 | vn -0.298000 0.580200 0.758000 2052 | vn 0.093000 -0.992400 -0.080500 2053 | vn -0.093000 -0.992400 -0.080500 2054 | vn 0.500600 -0.865700 0.008000 2055 | vn -0.500600 -0.865700 0.008000 2056 | vn 0.928500 -0.249700 0.274800 2057 | vn -0.928500 -0.249700 0.274800 2058 | vn 0.839300 0.542400 -0.037800 2059 | vn -0.839300 0.542400 -0.037800 2060 | vn -0.235500 0.936700 -0.258900 2061 | vn 0.235500 0.936700 -0.258900 2062 | vn -0.449900 0.883800 -0.128500 2063 | vn 0.449900 0.883800 -0.128500 2064 | vn -0.538400 -0.009800 -0.842700 2065 | vn 0.538400 -0.009800 -0.842700 2066 | vn -0.191000 -0.024100 -0.981300 2067 | vn 0.191000 -0.024100 -0.981300 2068 | vn 0.404600 0.026600 -0.914100 2069 | vn -0.404600 0.026600 -0.914100 2070 | vn -0.781900 0.623100 0.019700 2071 | vn 0.781900 0.623100 0.019700 2072 | vn 0.542800 -0.206300 -0.814200 2073 | vn -0.542800 -0.206300 -0.814200 2074 | vn -0.247400 -0.923100 -0.294500 2075 | vn 0.247400 -0.923100 -0.294500 2076 | usemtl None 2077 | s off 2078 | f 47/1/1 1/2/1 3/3/1 45/4/1 2079 | f 4/5/2 2/6/2 48/7/2 46/8/2 2080 | f 45/4/3 3/3/3 5/9/3 43/10/3 2081 | f 6/11/4 4/5/4 46/8/4 44/12/4 2082 | f 3/13/5 9/14/5 7/15/5 5/16/5 2083 | f 8/17/6 10/18/6 4/5/6 6/11/6 2084 | f 1/2/7 11/19/7 9/20/7 3/3/7 2085 | f 10/18/8 12/21/8 2/6/8 4/5/8 2086 | f 11/22/9 13/23/9 15/24/9 9/25/9 2087 | f 16/26/10 14/27/10 12/21/10 10/18/10 2088 | f 9/25/11 15/24/11 17/28/11 7/29/11 2089 | f 18/30/12 16/26/12 10/18/12 8/17/12 2090 | f 15/24/13 21/31/13 19/32/13 17/28/13 2091 | f 20/33/14 22/34/14 16/35/14 18/36/14 2092 | f 13/23/15 23/37/15 21/31/15 15/24/15 2093 | f 22/34/16 24/38/16 14/39/16 16/35/16 2094 | f 23/40/17 25/41/17 27/42/17 21/43/17 2095 | f 28/44/18 26/45/18 24/38/18 22/34/18 2096 | f 21/43/19 27/42/19 29/46/19 19/47/19 2097 | f 30/48/20 28/44/20 22/34/20 20/33/20 2098 | f 27/42/21 33/49/21 31/50/21 29/46/21 2099 | f 32/51/22 34/52/22 28/44/22 30/48/22 2100 | f 25/53/23 35/54/23 33/55/23 27/56/23 2101 | f 34/52/24 36/57/24 26/45/24 28/44/24 2102 | f 35/54/25 37/58/25 39/59/25 33/55/25 2103 | f 40/60/26 38/61/26 36/62/26 34/63/26 2104 | f 33/55/27 39/59/27 41/64/27 31/65/27 2105 | f 42/66/28 40/60/28 34/63/28 32/67/28 2106 | f 39/59/29 45/4/29 43/10/29 41/64/29 2107 | f 44/68/30 46/69/30 40/60/30 42/66/30 2108 | f 37/58/31 47/1/31 45/4/31 39/59/31 2109 | f 46/69/32 48/70/32 38/61/32 40/60/32 2110 | f 47/71/33 37/72/33 51/73/33 49/74/33 2111 | f 52/75/34 38/61/34 48/70/34 50/76/34 2112 | f 37/72/35 35/77/35 53/78/35 51/73/35 2113 | f 54/79/36 36/80/36 38/81/36 52/82/36 2114 | f 35/83/37 25/41/37 55/84/37 53/85/37 2115 | f 56/86/38 26/87/38 36/80/38 54/79/38 2116 | f 25/41/39 23/40/39 57/88/39 55/84/39 2117 | f 58/89/40 24/90/40 26/87/40 56/86/40 2118 | f 23/91/41 13/92/41 59/93/41 57/94/41 2119 | f 60/95/42 14/96/42 24/97/42 58/98/42 2120 | f 13/92/43 11/99/43 63/100/43 59/93/43 2121 | f 64/101/44 12/102/44 14/96/44 60/95/44 2122 | f 11/103/45 1/104/45 65/105/45 63/106/45 2123 | f 66/107/46 2/108/46 12/109/46 64/110/46 2124 | f 1/104/47 47/111/47 49/112/47 65/105/47 2125 | f 50/113/48 48/114/48 2/108/48 66/107/48 2126 | f 61/115/49 65/116/49 49/117/49 2127 | f 50/118/50 66/119/50 62/120/50 2128 | f 63/121/51 65/116/51 61/115/51 2129 | f 62/120/52 66/119/52 64/122/52 2130 | f 61/115/53 59/123/53 63/121/53 2131 | f 64/124/54 60/125/54 62/126/54 2132 | f 61/115/55 57/127/55 59/123/55 2133 | f 60/125/56 58/128/56 62/126/56 2134 | f 61/115/57 55/129/57 57/127/57 2135 | f 58/128/58 56/130/58 62/126/58 2136 | f 61/115/59 53/131/59 55/129/59 2137 | f 56/130/60 54/132/60 62/126/60 2138 | f 61/115/61 51/133/61 53/131/61 2139 | f 54/132/62 52/134/62 62/126/62 2140 | f 61/115/63 49/117/63 51/133/63 2141 | f 52/135/64 50/118/64 62/120/64 2142 | f 89/136/65 174/137/65 176/138/65 91/139/65 2143 | f 176/138/66 175/140/66 90/141/66 91/139/66 2144 | f 87/142/67 172/143/67 174/137/67 89/136/67 2145 | f 175/140/68 173/144/68 88/145/68 90/141/68 2146 | f 85/146/69 170/147/69 172/148/69 87/149/69 2147 | f 173/144/70 171/150/70 86/151/70 88/145/70 2148 | f 83/152/71 168/153/71 170/147/71 85/146/71 2149 | f 171/150/72 169/154/72 84/155/72 86/151/72 2150 | f 81/156/73 166/157/73 168/153/73 83/152/73 2151 | f 169/158/74 167/159/74 82/160/74 84/161/74 2152 | f 79/162/75 92/163/75 146/164/75 164/165/75 2153 | f 147/166/76 93/167/76 80/168/76 165/169/76 2154 | f 92/170/77 94/171/77 148/172/77 146/173/77 2155 | f 149/174/78 95/175/78 93/167/78 147/166/78 2156 | f 94/176/79 96/177/79 150/178/79 148/179/79 2157 | f 151/180/80 97/181/80 95/175/80 149/174/80 2158 | f 96/177/81 98/182/81 152/183/81 150/178/81 2159 | f 153/184/82 99/185/82 97/181/82 151/180/82 2160 | f 98/182/83 100/186/83 154/187/83 152/183/83 2161 | f 155/188/84 101/189/84 99/190/84 153/191/84 2162 | f 100/186/85 102/192/85 156/193/85 154/187/85 2163 | f 157/194/86 103/195/86 101/189/86 155/188/86 2164 | f 102/192/87 104/196/87 158/197/87 156/193/87 2165 | f 159/198/88 105/199/88 103/195/88 157/194/88 2166 | f 104/196/89 106/200/89 160/201/89 158/197/89 2167 | f 161/202/90 107/203/90 105/204/90 159/205/90 2168 | f 106/206/91 108/207/91 162/208/91 160/209/91 2169 | f 163/210/92 109/211/92 107/203/92 161/202/92 2170 | f 108/207/93 67/212/93 68/213/93 162/208/93 2171 | f 68/214/94 67/215/94 109/211/94 163/210/94 2172 | f 110/216/95 128/217/95 160/201/95 162/218/95 2173 | f 161/219/96 129/220/96 111/221/96 163/222/96 2174 | f 128/217/97 179/223/97 158/197/97 160/201/97 2175 | f 159/224/98 180/225/98 129/220/98 161/219/98 2176 | f 126/226/99 156/227/99 158/228/99 179/229/99 2177 | f 159/224/100 157/230/100 127/231/100 180/225/100 2178 | f 124/232/101 154/233/101 156/227/101 126/226/101 2179 | f 157/230/102 155/234/102 125/235/102 127/231/102 2180 | f 122/236/103 152/237/103 154/233/103 124/232/103 2181 | f 155/234/104 153/184/104 123/238/104 125/235/104 2182 | f 120/239/105 150/178/105 152/183/105 122/240/105 2183 | f 153/184/106 151/180/106 121/241/106 123/238/106 2184 | f 118/242/107 148/179/107 150/178/107 120/239/107 2185 | f 151/180/108 149/174/108 119/243/108 121/241/108 2186 | f 116/244/109 146/245/109 148/179/109 118/242/109 2187 | f 149/174/110 147/166/110 117/246/110 119/243/110 2188 | f 114/247/111 164/248/111 146/245/111 116/244/111 2189 | f 147/249/112 165/250/112 115/251/112 117/252/112 2190 | f 114/247/113 181/253/113 177/254/113 164/248/113 2191 | f 177/254/114 182/255/114 115/251/114 165/250/114 2192 | f 110/216/115 162/218/115 68/256/115 112/257/115 2193 | f 68/258/116 163/222/116 111/221/116 113/259/116 2194 | f 112/257/117 68/256/117 178/260/117 183/261/117 2195 | f 178/262/118 68/258/118 113/259/118 184/263/118 2196 | f 177/254/119 181/253/119 183/261/119 178/260/119 2197 | f 184/264/120 182/255/120 177/254/120 178/260/120 2198 | f 135/265/121 137/266/121 176/138/121 174/137/121 2199 | f 176/138/122 137/266/122 136/267/122 175/140/122 2200 | f 133/268/123 135/265/123 174/137/123 172/143/123 2201 | f 175/140/124 136/267/124 134/269/124 173/144/124 2202 | f 131/270/125 133/271/125 172/148/125 170/147/125 2203 | f 173/144/126 134/269/126 132/272/126 171/150/126 2204 | f 166/157/127 187/273/127 185/274/127 168/153/127 2205 | f 186/275/128 188/276/128 167/277/128 169/278/128 2206 | f 131/270/129 170/147/129 168/153/129 185/274/129 2207 | f 169/154/130 171/150/130 132/272/130 186/279/130 2208 | f 144/280/131 190/281/131 189/282/131 187/273/131 2209 | f 189/282/132 190/281/132 145/283/132 188/276/132 2210 | f 185/274/133 187/273/133 189/282/133 69/284/133 2211 | f 189/282/134 188/276/134 186/275/134 69/284/134 2212 | f 130/285/135 131/270/135 185/274/135 69/284/135 2213 | f 186/275/135 132/286/135 130/285/135 69/284/135 2214 | f 142/287/136 193/288/136 191/289/136 144/290/136 2215 | f 192/291/137 194/292/137 143/293/137 145/294/137 2216 | f 140/295/138 195/296/138 193/297/138 142/298/138 2217 | f 194/299/139 196/300/139 141/301/139 143/302/139 2218 | f 139/303/140 197/304/140 195/296/140 140/295/140 2219 | f 196/305/141 198/306/141 139/307/141 141/308/141 2220 | f 138/309/142 71/310/142 197/311/142 139/312/142 2221 | f 198/313/143 71/314/143 138/315/143 139/316/143 2222 | f 190/317/144 144/290/144 191/289/144 70/318/144 2223 | f 192/291/145 145/294/145 190/319/145 70/320/145 2224 | f 70/320/146 191/321/146 206/322/146 208/323/146 2225 | f 207/324/147 192/291/147 70/320/147 208/323/147 2226 | f 71/310/148 199/325/148 200/326/148 197/311/148 2227 | f 201/327/149 199/328/149 71/314/149 198/313/149 2228 | f 197/329/150 200/330/150 202/331/150 195/332/150 2229 | f 203/333/151 201/334/151 198/335/151 196/300/151 2230 | f 195/332/152 202/331/152 204/336/152 193/337/152 2231 | f 205/338/153 203/333/153 196/300/153 194/299/153 2232 | f 193/288/154 204/339/154 206/340/154 191/289/154 2233 | f 207/324/155 205/341/155 194/292/155 192/291/155 2234 | f 199/342/156 204/336/156 202/331/156 200/330/156 2235 | f 203/343/157 205/344/157 199/328/157 201/327/157 2236 | f 199/345/158 208/323/158 206/322/158 204/346/158 2237 | f 207/324/159 208/323/159 199/345/159 205/341/159 2238 | f 139/347/160 140/348/160 164/349/160 177/350/160 2239 | f 165/250/161 141/351/161 139/352/161 177/254/161 2240 | f 140/348/162 142/353/162 211/354/162 164/349/162 2241 | f 212/355/163 143/356/163 141/351/163 165/250/163 2242 | f 142/357/164 144/280/164 213/358/164 211/359/164 2243 | f 214/360/165 145/294/165 143/293/165 212/361/165 2244 | f 144/280/166 187/273/166 166/157/166 213/358/166 2245 | f 167/277/167 188/276/167 145/283/167 214/362/167 2246 | f 81/156/168 209/363/168 213/358/168 166/157/168 2247 | f 214/364/169 210/365/169 82/160/169 167/159/169 2248 | f 209/363/170 215/366/170 211/359/170 213/358/170 2249 | f 212/367/171 216/368/171 210/365/171 214/364/171 2250 | f 79/369/172 164/370/172 211/359/172 215/366/172 2251 | f 212/367/173 165/371/173 80/372/173 216/368/173 2252 | f 131/373/174 130/374/174 72/375/174 222/376/174 2253 | f 72/375/175 130/374/175 132/272/175 223/377/175 2254 | f 133/268/176 131/373/176 222/376/176 220/378/176 2255 | f 223/379/177 132/380/177 134/381/177 221/382/177 2256 | f 135/265/178 133/268/178 220/378/178 218/383/178 2257 | f 221/382/179 134/381/179 136/384/179 219/385/179 2258 | f 137/386/180 135/387/180 218/388/180 217/389/180 2259 | f 219/385/181 136/384/181 137/386/181 217/389/181 2260 | f 217/390/182 218/391/182 229/392/182 231/393/182 2261 | f 230/394/183 219/395/183 217/396/183 231/397/183 2262 | f 218/391/184 220/398/184 227/399/184 229/392/184 2263 | f 228/400/185 221/401/185 219/395/185 230/394/185 2264 | f 220/398/186 222/402/186 225/403/186 227/399/186 2265 | f 226/404/187 223/405/187 221/406/187 228/407/187 2266 | f 222/408/188 72/409/188 224/410/188 225/411/188 2267 | f 224/412/189 72/375/189 223/377/189 226/413/189 2268 | f 224/414/190 231/415/190 229/416/190 225/417/190 2269 | f 230/418/191 231/415/191 224/414/191 226/419/191 2270 | f 225/417/192 229/416/192 227/420/192 2271 | f 228/421/193 230/422/193 226/423/193 2272 | f 183/424/194 181/425/194 234/426/194 232/427/194 2273 | f 235/428/195 182/255/195 184/264/195 233/429/195 2274 | f 112/430/196 183/424/196 232/427/196 254/431/196 2275 | f 233/429/197 184/264/197 113/432/197 255/433/197 2276 | f 110/216/198 112/257/198 254/434/198 256/435/198 2277 | f 255/433/199 113/432/199 111/436/199 257/437/199 2278 | f 181/425/200 114/438/200 252/439/200 234/426/200 2279 | f 253/440/201 115/251/201 182/255/201 235/428/201 2280 | f 114/438/202 116/441/202 250/442/202 252/439/202 2281 | f 251/443/203 117/246/203 115/444/203 253/445/203 2282 | f 116/244/204 118/242/204 248/446/204 250/447/204 2283 | f 249/448/205 119/243/205 117/246/205 251/443/205 2284 | f 118/242/206 120/239/206 246/449/206 248/446/206 2285 | f 247/450/207 121/241/207 119/243/207 249/448/207 2286 | f 120/239/208 122/240/208 244/451/208 246/449/208 2287 | f 245/452/209 123/238/209 121/241/209 247/450/209 2288 | f 122/240/210 124/453/210 242/454/210 244/451/210 2289 | f 243/455/211 125/456/211 123/457/211 245/458/211 2290 | f 124/453/212 126/459/212 240/460/212 242/454/212 2291 | f 241/461/213 127/462/213 125/456/213 243/455/213 2292 | f 126/459/214 179/223/214 236/463/214 240/460/214 2293 | f 237/464/215 180/465/215 127/462/215 241/461/215 2294 | f 179/223/216 128/217/216 238/466/216 236/463/216 2295 | f 239/467/217 129/468/217 180/469/217 237/470/217 2296 | f 128/217/218 110/216/218 256/435/218 238/466/218 2297 | f 257/437/219 111/436/219 129/468/219 239/467/219 2298 | f 238/466/220 256/435/220 258/471/220 276/472/220 2299 | f 259/473/221 257/474/221 239/475/221 277/476/221 2300 | f 236/463/222 238/466/222 276/472/222 278/477/222 2301 | f 277/476/223 239/475/223 237/478/223 279/479/223 2302 | f 240/480/224 236/481/224 278/482/224 274/483/224 2303 | f 279/479/225 237/478/225 241/484/225 275/485/225 2304 | f 242/486/226 240/480/226 274/483/226 272/487/226 2305 | f 275/485/227 241/484/227 243/488/227 273/489/227 2306 | f 244/490/228 242/486/228 272/487/228 270/491/228 2307 | f 273/492/229 243/493/229 245/494/229 271/495/229 2308 | f 246/496/230 244/490/230 270/491/230 268/497/230 2309 | f 271/495/231 245/494/231 247/498/231 269/499/231 2310 | f 248/446/232 246/449/232 268/500/232 266/501/232 2311 | f 269/499/233 247/498/233 249/502/233 267/503/233 2312 | f 250/447/234 248/446/234 266/501/234 264/504/234 2313 | f 267/503/235 249/502/235 251/505/235 265/506/235 2314 | f 252/507/236 250/447/236 264/504/236 262/508/236 2315 | f 265/509/237 251/510/237 253/511/237 263/512/237 2316 | f 234/513/238 252/507/238 262/508/238 280/514/238 2317 | f 263/512/239 253/511/239 235/515/239 281/516/239 2318 | f 256/435/240 254/434/240 260/517/240 258/471/240 2319 | f 261/518/241 255/519/241 257/474/241 259/473/241 2320 | f 254/434/242 232/520/242 282/521/242 260/517/242 2321 | f 283/522/243 233/523/243 255/519/243 261/518/243 2322 | f 232/520/244 234/513/244 280/514/244 282/521/244 2323 | f 281/516/245 235/515/245 233/524/245 283/525/245 2324 | f 67/212/246 108/207/246 284/526/246 73/527/246 2325 | f 285/528/247 109/529/247 67/530/247 73/531/247 2326 | f 108/207/248 106/206/248 286/532/248 284/526/248 2327 | f 287/533/249 107/534/249 109/529/249 285/528/249 2328 | f 106/535/250 104/536/250 288/537/250 286/538/250 2329 | f 289/539/251 105/540/251 107/534/251 287/533/251 2330 | f 104/536/252 102/541/252 290/542/252 288/537/252 2331 | f 291/543/253 103/195/253 105/199/253 289/544/253 2332 | f 102/541/254 100/545/254 292/546/254 290/542/254 2333 | f 293/547/255 101/189/255 103/195/255 291/543/255 2334 | f 100/545/256 98/548/256 294/549/256 292/546/256 2335 | f 295/550/257 99/190/257 101/189/257 293/547/257 2336 | f 98/548/258 96/551/258 296/552/258 294/549/258 2337 | f 297/553/259 97/554/259 99/555/259 295/556/259 2338 | f 96/557/260 94/558/260 298/559/260 296/560/260 2339 | f 299/561/261 95/562/261 97/554/261 297/553/261 2340 | f 94/558/262 92/163/262 300/563/262 298/559/262 2341 | f 301/564/263 93/565/263 95/562/263 299/561/263 2342 | f 308/566/264 309/567/264 328/568/264 338/569/264 2343 | f 329/570/265 309/571/265 308/572/265 339/573/265 2344 | f 307/574/266 308/572/266 338/575/266 336/576/266 2345 | f 339/573/267 308/572/267 307/574/267 337/577/267 2346 | f 306/578/268 307/574/268 336/576/268 340/579/268 2347 | f 337/577/269 307/574/269 306/578/269 341/580/269 2348 | f 89/581/270 91/582/270 306/583/270 340/584/270 2349 | f 306/585/271 91/139/271 90/141/271 341/586/271 2350 | f 87/587/272 89/581/272 340/584/272 334/588/272 2351 | f 341/589/273 90/590/273 88/591/273 335/592/273 2352 | f 85/593/274 87/587/274 334/588/274 330/594/274 2353 | f 335/595/275 88/596/275 86/597/275 331/598/275 2354 | f 83/599/276 85/600/276 330/601/276 332/602/276 2355 | f 331/603/277 86/604/277 84/161/277 333/605/277 2356 | f 330/606/278 336/576/278 338/575/278 332/607/278 2357 | f 339/573/279 337/577/279 331/598/279 333/608/279 2358 | f 330/606/280 334/609/280 340/579/280 336/576/280 2359 | f 341/580/281 335/595/281 331/598/281 337/577/281 2360 | f 326/610/282 332/611/282 338/569/282 328/568/282 2361 | f 339/573/283 333/608/283 327/612/283 329/570/283 2362 | f 81/613/284 83/599/284 332/602/284 326/614/284 2363 | f 333/605/285 84/161/285 82/160/285 327/615/285 2364 | f 209/616/286 342/617/286 344/618/286 215/619/286 2365 | f 345/620/287 343/621/287 210/365/287 216/368/287 2366 | f 81/613/288 326/614/288 342/617/288 209/616/288 2367 | f 343/621/289 327/615/289 82/160/289 210/365/289 2368 | f 79/622/290 215/619/290 344/618/290 346/623/290 2369 | f 345/620/291 216/368/291 80/372/291 347/624/291 2370 | f 79/162/292 346/625/292 300/563/292 92/163/292 2371 | f 301/564/293 347/626/293 80/627/293 93/565/293 2372 | f 77/628/294 324/629/294 352/630/294 304/631/294 2373 | f 353/632/295 325/633/295 77/634/295 304/635/295 2374 | f 304/631/296 352/630/296 350/636/296 78/637/296 2375 | f 351/638/297 353/632/297 304/635/297 78/639/297 2376 | f 78/637/298 350/636/298 348/640/298 305/641/298 2377 | f 349/642/299 351/643/299 78/644/299 305/645/299 2378 | f 305/641/300 348/640/300 328/568/300 309/567/300 2379 | f 329/646/301 349/642/301 305/645/301 309/647/301 2380 | f 326/610/302 328/568/302 348/640/302 342/648/302 2381 | f 349/649/303 329/650/303 327/615/303 343/621/303 2382 | f 296/560/304 298/559/304 318/651/304 310/652/304 2383 | f 319/653/305 299/654/305 297/655/305 311/656/305 2384 | f 76/657/306 316/658/306 324/659/306 77/634/306 2385 | f 325/633/307 317/660/307 76/657/307 77/634/307 2386 | f 302/661/308 358/662/308 356/663/308 303/664/308 2387 | f 357/665/309 359/666/309 302/667/309 303/668/309 2388 | f 303/664/310 356/663/310 354/669/310 75/670/310 2389 | f 355/671/311 357/672/311 303/664/311 75/670/311 2390 | f 75/670/312 354/669/312 316/673/312 76/674/312 2391 | f 317/660/313 355/675/313 75/676/313 76/657/313 2392 | f 292/546/314 294/549/314 362/677/314 364/678/314 2393 | f 363/679/315 295/550/315 293/547/315 365/680/315 2394 | f 364/681/316 362/682/316 368/683/316 366/684/316 2395 | f 369/685/317 363/679/317 365/680/317 367/686/317 2396 | f 366/687/318 368/688/318 370/689/318 372/690/318 2397 | f 371/691/319 369/685/319 367/686/319 373/692/319 2398 | f 372/690/320 370/689/320 376/693/320 374/694/320 2399 | f 377/695/321 371/691/321 373/692/321 375/696/321 2400 | f 314/697/322 378/698/322 374/694/322 376/693/322 2401 | f 375/699/323 379/700/323 315/701/323 377/702/323 2402 | f 316/673/324 354/669/324 374/694/324 378/698/324 2403 | f 375/699/325 355/675/325 317/660/325 379/700/325 2404 | f 354/669/326 356/663/326 372/690/326 374/694/326 2405 | f 373/692/327 357/665/327 355/703/327 375/696/327 2406 | f 356/663/328 358/662/328 366/687/328 372/690/328 2407 | f 367/686/329 359/666/329 357/665/329 373/692/329 2408 | f 358/704/330 360/705/330 364/681/330 366/684/330 2409 | f 365/680/331 361/706/331 359/666/331 367/686/331 2410 | f 290/542/332 292/546/332 364/678/332 360/707/332 2411 | f 365/680/333 293/547/333 291/543/333 361/706/333 2412 | f 74/708/334 360/705/334 358/704/334 302/709/334 2413 | f 359/710/335 361/711/335 74/708/335 302/709/335 2414 | f 284/712/336 286/713/336 288/714/336 290/715/336 2415 | f 289/716/337 287/717/337 285/718/337 291/719/337 2416 | f 284/720/338 290/721/338 360/722/338 74/723/338 2417 | f 361/706/339 291/543/339 285/724/339 74/725/339 2418 | f 73/726/340 284/727/340 74/728/340 2419 | f 74/728/341 285/729/341 73/726/341 2420 | f 294/549/342 296/552/342 310/730/342 362/677/342 2421 | f 311/731/343 297/732/343 295/550/343 363/679/343 2422 | f 310/733/344 312/734/344 368/683/344 362/682/344 2423 | f 369/685/345 313/735/345 311/731/345 363/679/345 2424 | f 312/736/346 382/737/346 370/689/346 368/688/346 2425 | f 371/691/347 383/738/347 313/735/347 369/685/347 2426 | f 314/739/348 376/740/348 370/741/348 382/742/348 2427 | f 371/691/349 377/695/349 315/743/349 383/738/349 2428 | f 348/640/350 350/636/350 386/744/350 384/745/350 2429 | f 387/746/351 351/643/351 349/642/351 385/747/351 2430 | f 318/651/352 384/745/352 386/744/352 320/748/352 2431 | f 387/746/353 385/747/353 319/653/353 321/749/353 2432 | f 298/559/354 300/563/354 384/745/354 318/651/354 2433 | f 385/747/355 301/750/355 299/654/355 319/653/355 2434 | f 300/563/356 344/751/356 342/648/356 384/745/356 2435 | f 343/752/357 345/753/357 301/750/357 385/747/357 2436 | f 342/648/358 348/640/358 384/745/358 2437 | f 385/747/359 349/642/359 343/752/359 2438 | f 300/754/360 346/755/360 344/756/360 2439 | f 345/753/361 347/757/361 301/750/361 2440 | f 314/758/362 322/759/362 380/760/362 378/761/362 2441 | f 381/762/363 323/763/363 315/701/363 379/700/363 2442 | f 316/764/364 378/761/364 380/760/364 324/629/364 2443 | f 381/762/365 379/700/365 317/660/365 325/633/365 2444 | f 320/748/366 386/744/366 380/760/366 322/759/366 2445 | f 381/762/367 387/765/367 321/766/367 323/763/367 2446 | f 350/636/368 352/630/368 380/760/368 386/744/368 2447 | f 381/762/369 353/632/369 351/638/369 387/765/369 2448 | f 324/629/370 380/760/370 352/630/370 2449 | f 353/632/371 381/762/371 325/633/371 2450 | f 400/767/372 388/768/372 414/769/372 402/770/372 2451 | f 415/771/373 389/772/373 401/773/373 403/774/373 2452 | f 400/767/374 402/770/374 404/775/374 398/776/374 2453 | f 405/777/375 403/778/375 401/779/375 399/780/375 2454 | f 398/776/376 404/775/376 406/781/376 396/782/376 2455 | f 407/783/377 405/784/377 399/785/377 397/786/377 2456 | f 396/782/378 406/781/378 408/787/378 394/788/378 2457 | f 409/789/379 407/783/379 397/786/379 395/790/379 2458 | f 394/788/380 408/787/380 410/791/380 392/792/380 2459 | f 411/793/381 409/794/381 395/795/381 393/796/381 2460 | f 392/792/382 410/791/382 412/797/382 390/798/382 2461 | f 413/799/383 411/793/383 393/796/383 391/800/383 2462 | f 410/791/384 420/801/384 418/802/384 412/797/384 2463 | f 419/803/385 421/804/385 411/805/385 413/806/385 2464 | f 408/807/386 422/808/386 420/809/386 410/810/386 2465 | f 421/811/387 423/812/387 409/789/387 411/813/387 2466 | f 406/814/388 424/815/388 422/808/388 408/807/388 2467 | f 423/812/389 425/816/389 407/783/389 409/789/389 2468 | f 404/817/390 426/818/390 424/819/390 406/820/390 2469 | f 425/816/391 427/821/391 405/784/391 407/783/391 2470 | f 402/770/392 428/822/392 426/823/392 404/775/392 2471 | f 427/824/393 429/825/393 403/826/393 405/827/393 2472 | f 402/770/394 414/769/394 416/828/394 428/822/394 2473 | f 417/829/395 415/830/395 403/826/395 429/825/395 2474 | f 318/651/396 320/748/396 444/831/396 442/832/396 2475 | f 445/833/397 321/749/397 319/653/397 443/834/397 2476 | f 320/835/398 390/798/398 412/797/398 444/836/398 2477 | f 413/837/399 391/838/399 321/839/399 445/840/399 2478 | f 310/652/400 318/651/400 442/832/400 312/841/400 2479 | f 443/842/401 319/843/401 311/844/401 313/845/401 2480 | f 382/846/402 430/847/402 414/769/402 388/768/402 2481 | f 415/771/403 431/848/403 383/849/403 389/772/403 2482 | f 412/850/404 418/851/404 440/852/404 444/853/404 2483 | f 441/854/405 419/803/405 413/806/405 445/855/405 2484 | f 438/856/406 446/857/406 444/858/406 440/859/406 2485 | f 445/860/407 447/861/407 439/862/407 441/863/407 2486 | f 434/864/408 446/857/408 438/856/408 436/865/408 2487 | f 439/866/409 447/867/409 435/868/409 437/869/409 2488 | f 432/870/410 448/871/410 446/872/410 434/873/410 2489 | f 447/874/411 449/875/411 433/876/411 435/877/411 2490 | f 430/847/412 448/878/412 432/879/412 450/880/412 2491 | f 433/876/413 449/875/413 431/881/413 451/882/413 2492 | f 414/769/414 430/847/414 450/880/414 416/828/414 2493 | f 451/882/415 431/881/415 415/830/415 417/829/415 2494 | f 312/841/416 448/871/416 430/883/416 382/884/416 2495 | f 431/885/417 449/886/417 313/735/417 383/738/417 2496 | f 312/841/418 442/832/418 446/872/418 448/871/418 2497 | f 447/874/419 443/887/419 313/888/419 449/875/419 2498 | f 442/832/420 444/831/420 446/872/420 2499 | f 447/889/421 445/890/421 443/891/421 2500 | f 416/892/422 450/893/422 452/894/422 476/895/422 2501 | f 453/896/423 451/882/423 417/829/423 477/897/423 2502 | f 450/893/424 432/870/424 462/898/424 452/894/424 2503 | f 463/899/425 433/876/425 451/882/425 453/896/425 2504 | f 432/870/426 434/873/426 460/900/426 462/898/426 2505 | f 461/901/427 435/877/427 433/876/427 463/899/427 2506 | f 434/902/428 436/903/428 458/904/428 460/905/428 2507 | f 459/906/429 437/869/429 435/868/429 461/907/429 2508 | f 436/865/430 438/856/430 456/908/430 458/909/430 2509 | f 457/910/431 439/866/431 437/869/431 459/906/431 2510 | f 438/911/432 440/912/432 454/913/432 456/914/432 2511 | f 455/915/433 441/863/433 439/862/433 457/916/433 2512 | f 440/852/434 418/851/434 474/917/434 454/918/434 2513 | f 475/919/435 419/920/435 441/921/435 455/922/435 2514 | f 428/923/436 416/892/436 476/895/436 464/924/436 2515 | f 477/897/437 417/829/437 429/825/437 465/925/437 2516 | f 426/926/438 428/923/438 464/924/438 466/927/438 2517 | f 465/925/439 429/825/439 427/824/439 467/928/439 2518 | f 424/929/440 426/930/440 466/931/440 468/932/440 2519 | f 467/933/441 427/934/441 425/935/441 469/936/441 2520 | f 422/937/442 424/929/442 468/932/442 470/938/442 2521 | f 469/939/443 425/940/443 423/941/443 471/942/443 2522 | f 420/809/444 422/808/444 470/943/444 472/944/444 2523 | f 471/942/445 423/941/445 421/945/445 473/946/445 2524 | f 418/851/446 420/947/446 472/948/446 474/917/446 2525 | f 473/946/447 421/945/447 419/920/447 475/919/447 2526 | f 458/909/448 456/908/448 480/949/448 478/950/448 2527 | f 481/951/449 457/952/449 459/953/449 479/954/449 2528 | f 478/950/450 480/949/450 482/955/450 484/956/450 2529 | f 483/957/451 481/951/451 479/954/451 485/958/451 2530 | f 484/956/452 482/955/452 488/959/452 486/960/452 2531 | f 489/961/453 483/957/453 485/958/453 487/962/453 2532 | f 486/960/454 488/959/454 490/963/454 492/964/454 2533 | f 491/965/455 489/961/455 487/962/455 493/966/455 2534 | f 464/967/456 476/968/456 486/960/456 492/964/456 2535 | f 487/962/457 477/969/457 465/970/457 493/966/457 2536 | f 452/971/458 484/956/458 486/960/458 476/968/458 2537 | f 487/972/459 485/973/459 453/896/459 477/897/459 2538 | f 452/971/460 462/974/460 478/950/460 484/956/460 2539 | f 479/954/461 463/975/461 453/976/461 485/958/461 2540 | f 458/909/462 478/950/462 462/974/462 460/977/462 2541 | f 463/975/463 479/954/463 459/953/463 461/978/463 2542 | f 454/979/464 474/980/464 480/981/464 456/982/464 2543 | f 481/951/465 475/983/465 455/984/465 457/952/465 2544 | f 472/985/466 482/955/466 480/949/466 474/986/466 2545 | f 481/987/467 483/988/467 473/989/467 475/990/467 2546 | f 470/991/468 488/959/468 482/955/468 472/985/468 2547 | f 483/988/469 489/992/469 471/993/469 473/989/469 2548 | f 468/994/470 490/963/470 488/959/470 470/991/470 2549 | f 489/992/471 491/995/471 469/996/471 471/993/471 2550 | f 466/997/472 492/964/472 490/963/472 468/994/472 2551 | f 491/998/473 493/999/473 467/1000/473 469/1001/473 2552 | f 464/967/474 492/964/474 466/997/474 2553 | f 467/1000/475 493/999/475 465/1002/475 2554 | f 392/1003/476 390/1004/476 504/1005/476 502/1006/476 2555 | f 505/1007/477 391/800/477 393/796/477 503/1008/477 2556 | f 394/1009/478 392/1003/478 502/1006/478 500/1010/478 2557 | f 503/1008/479 393/796/479 395/795/479 501/1011/479 2558 | f 396/1012/480 394/1009/480 500/1010/480 498/1013/480 2559 | f 501/1011/481 395/795/481 397/1014/481 499/1015/481 2560 | f 398/1016/482 396/1017/482 498/1018/482 496/1019/482 2561 | f 499/1020/483 397/1021/483 399/1022/483 497/1023/483 2562 | f 400/1024/484 398/1016/484 496/1019/484 494/1025/484 2563 | f 497/1026/485 399/1027/485 401/1028/485 495/1029/485 2564 | f 388/1030/486 400/1031/486 494/1032/486 506/1033/486 2565 | f 495/1029/487 401/1028/487 389/1034/487 507/1035/487 2566 | f 494/1036/488 502/1037/488 504/1038/488 506/1039/488 2567 | f 505/1040/489 503/1041/489 495/1029/489 507/1035/489 2568 | f 494/1036/490 496/1042/490 500/1043/490 502/1037/490 2569 | f 501/1044/491 497/1045/491 495/1046/491 503/1047/491 2570 | f 496/1019/492 498/1018/492 500/1048/492 2571 | f 501/1044/493 499/1049/493 497/1045/493 2572 | f 314/1050/494 382/1051/494 388/1030/494 506/1033/494 2573 | f 389/1034/495 383/1052/495 315/1053/495 507/1035/495 2574 | f 314/758/496 506/1054/496 504/1055/496 322/759/496 2575 | f 505/1056/497 507/1057/497 315/701/497 323/763/497 2576 | f 320/1058/498 322/1059/498 504/1060/498 390/1061/498 2577 | f 505/1062/499 323/1063/499 321/1064/499 391/1065/499 2578 | --------------------------------------------------------------------------------