diff --git a/A4/.gitignore b/A4/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/A4/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/A4/CMakeLists.txt b/A4/CMakeLists.txt new file mode 100644 index 0000000..a21deb5 --- /dev/null +++ b/A4/CMakeLists.txt @@ -0,0 +1,127 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +# Name of the project +PROJECT(A4) + +# FOR LAB MACHINES ONLY! +# DO NOT EDIT +SET(DEF_DIR_GLM "C:\\c++\\glm") +SET(DEF_DIR_GLFW "C:\\c++\\glfw-3.2.1") +SET(DEF_DIR_GLEW "C:\\c++\\glew-2.0.0") + +# Is this the solution? +# Override with `cmake -DSOL=ON ..` +OPTION(SOL "Solution" OFF) + +# Use glob to get the list of all source files. +# We don't really need to include header and resource files to build, but it's +# nice to have them also show up in IDEs. +IF(${SOL}) + FILE(GLOB_RECURSE SOURCES "src0/*.cpp") + FILE(GLOB_RECURSE HEADERS "src0/*.h") + FILE(GLOB_RECURSE GLSL "resources0/*.glsl") +ELSE() + FILE(GLOB_RECURSE SOURCES "src/*.cpp") + FILE(GLOB_RECURSE HEADERS "src/*.h") + FILE(GLOB_RECURSE GLSL "resources/*.glsl") +ENDIF() + +# Set the executable. +ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCES} ${HEADERS} ${GLSL}) + +# Get the GLM environment variable. Since GLM is a header-only library, we +# just need to add it to the include directory. +SET(GLM_INCLUDE_DIR "$ENV{GLM_INCLUDE_DIR}") +IF(NOT GLM_INCLUDE_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLM_INCLUDE_DIR to the root directory of your GLM installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLM in ${DEF_DIR_GLM}") + IF(IS_DIRECTORY ${DEF_DIR_GLM}) + MESSAGE(STATUS "Found!") + SET(GLM_INCLUDE_DIR ${DEF_DIR_GLM}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +INCLUDE_DIRECTORIES(${GLM_INCLUDE_DIR}) + +# Get the GLFW environment variable. There should be a CMakeLists.txt in the +# specified directory. +SET(GLFW_DIR "$ENV{GLFW_DIR}") +IF(NOT GLFW_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLFW_DIR to the root directory of your GLFW installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLFW in ${DEF_DIR_GLFW}") + IF(IS_DIRECTORY ${DEF_DIR_GLFW}) + MESSAGE(STATUS "Found!") + SET(GLFW_DIR ${DEF_DIR_GLFW}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +OPTION(GLFW_BUILD_EXAMPLES "GLFW_BUILD_EXAMPLES" OFF) +OPTION(GLFW_BUILD_TESTS "GLFW_BUILD_TESTS" OFF) +OPTION(GLFW_BUILD_DOCS "GLFW_BUILD_DOCS" OFF) +IF(CMAKE_BUILD_TYPE MATCHES Release) + ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/release) +ELSE() + ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/debug) +ENDIF() +INCLUDE_DIRECTORIES(${GLFW_DIR}/include) +TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} glfw ${GLFW_LIBRARIES}) + +# Get the GLEW environment variable. +SET(GLEW_DIR "$ENV{GLEW_DIR}") +IF(NOT GLEW_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLEW_DIR to the root directory of your GLEW installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLEW in ${DEF_DIR_GLEW}") + IF(IS_DIRECTORY ${DEF_DIR_GLEW}) + MESSAGE(STATUS "Found!") + SET(GLEW_DIR ${DEF_DIR_GLEW}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +INCLUDE_DIRECTORIES(${GLEW_DIR}/include) +IF(WIN32) + # With prebuilt binaries + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/Release/Win32/glew32s.lib) +ELSE() + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/libGLEW.a) +ENDIF() + +# OS specific options and libraries +IF(WIN32) + # c++11 is enabled by default. + # -Wall produces way too many warnings. + # -pedantic is not supported. + # Disable warning 4996. + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996") + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} opengl32.lib) +ELSE() + # Enable all pedantic warnings. + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic") + IF(APPLE) + # Add required frameworks for GLFW. + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo") + ELSE() + #Link the Linux OpenGL library + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "GL") + ENDIF() +ENDIF() diff --git a/A4/README.txt b/A4/README.txt new file mode 100644 index 0000000..880295f --- /dev/null +++ b/A4/README.txt @@ -0,0 +1,7 @@ +Alexander Huddleston + +I downloaded the code from the lab pages and worked from there. + +I added a large flat cube as a "ground" but didn't texture it because I was tired of looking at a white abyss and thought this would make it look a little bit better. + +I didn't notice you implemented a "toggle key" functionality in the main and instead coded if statements in the char callback to do what I wanted. The functionality remains the same, but I thought it was worth noting. diff --git a/A4/resources/.frag.glsl b/A4/resources/.frag.glsl new file mode 100644 index 0000000..8b8b1de --- /dev/null +++ b/A4/resources/.frag.glsl @@ -0,0 +1,17 @@ +#version 120 + +uniform vec3 lightPos; +uniform vec3 ka; +uniform vec3 kd; +uniform vec3 ks; +uniform float s; + +varying vec3 n; // passed from the vertex shader +varying vec3 p; // passed from the vertex shader + +void main() +{ + n = normalize(normal); + vec3 color = 0.5 * (n + 1.0); + gl_FragColor = vec4(color.r, color.g, color.b, 1.0); +} diff --git a/A4/resources/.vert.glsl b/A4/resources/.vert.glsl new file mode 100644 index 0000000..ac83524 --- /dev/null +++ b/A4/resources/.vert.glsl @@ -0,0 +1,17 @@ +#version 120 + +uniform mat4 P; +uniform mat4 MV; + +attribute vec4 aPos; // in object space +attribute vec3 aNor; // in object space + +varying vec3 p; // passed to fragment shader +varying vec3 n; // passed to fragment shader + +void main() +{ + ugl_Position = P * MV * aPos; + p = MV * aPos; + n = MV * aNor; +} diff --git a/A4/resources/bunny.obj b/A4/resources/bunny.obj new file mode 100644 index 0000000..de3f190 --- /dev/null +++ b/A4/resources/bunny.obj @@ -0,0 +1,9977 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +v -0.865619 1.424919 0.084327 +v -0.896984 1.397126 0.137748 +v -0.894910 1.439258 0.124885 +v -0.863675 1.090654 0.119807 +v -0.859114 1.096879 0.076583 +v -0.870559 1.056276 0.097651 +v -0.263037 1.251888 0.173930 +v -0.273832 1.232426 0.216589 +v -0.258513 1.218295 0.260797 +v -0.727772 1.785447 -0.482088 +v -0.720838 1.749985 -0.419303 +v -0.677382 1.772887 -0.503759 +v -0.313589 1.214098 0.259711 +v -0.285960 1.190116 0.298882 +v -0.609024 0.434295 0.426785 +v -0.569010 0.454370 0.432370 +v -0.603813 0.459214 0.400887 +v -0.017977 1.311728 0.163607 +v -0.080841 1.303054 0.168723 +v -0.034102 1.303196 0.217544 +v -0.560108 1.538166 0.253693 +v -0.566276 1.527061 0.296291 +v -0.544542 1.529770 0.225052 +v -0.837366 0.767718 0.089586 +v -0.848639 0.783921 0.164620 +v -0.862046 0.809307 0.105354 +v -0.686026 1.499228 -0.400513 +v -0.694130 1.512185 -0.445385 +v -0.667007 1.523678 -0.452664 +v -0.888126 0.877655 0.142266 +v -0.896123 0.915999 0.178123 +v -0.893987 0.895390 0.116456 +v 0.584400 0.702008 0.177796 +v 0.573451 0.694827 0.211535 +v 0.583924 0.667412 0.219795 +v -0.336740 1.777445 -0.081799 +v -0.395199 1.738585 -0.075752 +v -0.355263 1.759556 -0.048676 +v -0.089889 1.295227 0.220268 +v -0.812574 0.730252 0.071021 +v -0.837405 0.772403 0.046673 +v -0.703597 1.690699 -0.261442 +v -0.727592 1.696591 -0.270134 +v -0.694385 1.647993 -0.172187 +v -0.638757 1.614009 -0.200642 +v -0.649590 1.585202 -0.125953 +v -0.633084 1.566061 -0.138388 +v -0.643710 1.729621 -0.492256 +v -0.665466 1.717112 -0.421277 +v -0.639263 1.679244 -0.407304 +v -0.506872 0.359359 -0.123808 +v -0.478720 0.341363 -0.154182 +v -0.514998 0.337291 -0.120825 +v -0.679838 1.697478 -0.316275 +v -0.709198 1.713669 -0.327637 +v -0.658081 1.676434 -0.305586 +v -0.691360 1.724784 -0.390133 +v -0.693726 1.606178 -0.091905 +v -0.708636 1.613653 -0.097324 +v -0.671322 1.570945 -0.062032 +v -0.726526 1.656792 -0.182125 +v -0.294283 0.931666 -0.249318 +v -0.330484 0.959586 -0.234264 +v -0.281229 0.993224 -0.235801 +v -0.152271 1.278488 0.215452 +v -0.201106 1.250454 0.235883 +v -0.162313 1.238294 0.295770 +v -0.929895 1.309231 0.199193 +v -0.905494 1.351187 0.216806 +v -0.922326 1.319540 0.154307 +v -0.078163 1.282121 -0.019430 +v -0.134939 1.288244 0.059691 +v -0.031074 1.307290 0.056429 +v -0.709618 0.343457 -0.007837 +v -0.703852 0.374503 -0.009319 +v -0.687962 0.351177 -0.052067 +v -0.917151 1.170996 0.308094 +v -0.927365 1.207309 0.326928 +v -0.924992 1.213150 0.292562 +v -0.843354 0.807299 0.221805 +v -0.860345 0.826457 0.195427 +v -0.107365 1.299029 0.109938 +v -0.056009 1.307667 0.105161 +v -0.374165 0.476821 -0.171473 +v -0.376138 0.495348 -0.116261 +v -0.355627 0.493999 -0.128650 +v -0.766552 1.550977 0.079687 +v -0.790400 1.553745 0.151418 +v -0.736967 1.561301 0.143598 +v -0.679454 1.149360 -0.095107 +v -0.708723 1.161164 -0.079564 +v -0.673908 1.188969 -0.087301 +v -0.893190 0.995470 0.134181 +v -0.874051 1.059399 0.136459 +v -0.030471 1.291945 -0.010688 +v -0.883609 1.499671 0.260442 +v -0.832990 1.496077 0.337409 +v -0.865377 1.515480 0.258754 +v -0.012189 0.962017 0.538159 +v 0.040479 0.958174 0.529368 +v 0.030802 0.983074 0.505357 +v -0.814967 1.547310 0.196974 +v -0.770043 1.552128 0.245348 +v -0.942971 1.261774 0.192247 +v -0.932812 1.269109 0.135050 +v 0.023930 1.316271 0.119551 +v -0.741082 1.735573 -0.379868 +v -0.234595 1.261539 0.166138 +v -0.812642 1.538117 0.258979 +v -0.817192 1.525015 0.296561 +v 0.009684 1.306430 0.025866 +v 0.035766 1.313898 0.072086 +v -0.821915 0.756102 0.165426 +v -0.816275 0.734706 0.111617 +v -0.672166 1.617134 -0.137337 +v -0.633133 1.650326 -0.328951 +v -0.900093 1.327808 0.059221 +v -0.887462 1.362558 0.071478 +v -0.874391 1.337488 0.023975 +v 0.065112 1.300252 0.009288 +v 0.113480 0.982438 -0.230242 +v 0.152357 0.949779 -0.244371 +v 0.104643 0.961805 -0.258990 +v -0.689402 1.565278 -0.019716 +v -0.722233 1.589674 -0.054242 +v -0.108662 1.269170 0.275755 +v -0.744886 1.564944 -0.025954 +v -0.737481 1.553925 0.023492 +v 0.024919 1.298356 0.248471 +v -0.042439 1.291490 0.258292 +v -0.015539 1.275472 0.292329 +v -0.886313 0.948812 0.079338 +v -0.894955 0.956324 0.142348 +v -0.888923 0.992091 0.095703 +v -0.754058 1.683907 -0.267930 +v -0.884692 1.112429 0.126792 +v -0.905579 1.127599 0.161410 +v -0.905939 1.137309 0.102768 +v -0.065865 1.264172 0.302264 +v -0.046019 1.242854 0.334720 +v -0.507183 1.527630 0.118167 +v -0.502423 1.577375 0.093945 +v -0.524202 1.531010 0.129274 +v -0.931765 1.182102 0.233624 +v -0.942436 1.220743 0.235685 +v -0.936442 1.178938 0.186621 +v -0.809005 1.255871 0.521554 +v -0.790038 1.285055 0.531494 +v -0.814555 1.301221 0.521177 +v -0.770567 1.319347 0.524625 +v -0.797790 1.344889 0.509903 +v -0.714483 1.810530 -0.554785 +v -0.741587 1.798728 -0.507947 +v -0.703815 1.807118 -0.531726 +v -0.789356 1.481723 0.394631 +v -0.789317 1.509306 0.351519 +v -0.473112 1.629604 0.060741 +v -0.518397 1.606204 0.071422 +v -0.572648 1.550625 0.193225 +v -0.922690 1.147516 0.170174 +v -0.780815 1.235194 0.521370 +v -0.784365 1.392801 0.483294 +v -0.772561 1.456585 0.431230 +v -0.809450 1.390357 0.473591 +v -0.595756 1.547240 0.263733 +v -0.600528 1.528035 0.328877 +v -0.742941 1.635685 -0.155342 +v -0.312179 0.438475 0.497809 +v -0.311729 0.402943 0.513125 +v -0.264720 0.450345 0.512195 +v -0.915565 1.319626 0.106382 +v -0.528317 0.702989 -0.148649 +v -0.550659 0.780892 -0.197555 +v -0.510255 0.757051 -0.181869 +v -0.639209 1.277424 -0.085494 +v -0.705951 1.299483 -0.087629 +v -0.684664 1.349815 -0.083360 +v -0.564730 1.577841 0.081787 +v -0.576845 1.556170 0.129831 +v -0.546424 1.552296 0.126124 +v -0.757182 1.252273 0.530873 +v -0.759832 1.382080 0.492166 +v 0.435148 0.915199 -0.026468 +v 0.414389 0.923651 -0.074587 +v 0.411181 0.974913 -0.039757 +v -0.861804 0.825722 0.063639 +v -0.867764 0.843449 0.124190 +v -0.256611 1.256267 0.045538 +v -0.235069 1.267201 0.109969 +v -0.890862 0.923771 0.105699 +v -0.943804 1.218392 0.179044 +v -0.644570 1.534289 -0.051180 +v 0.077390 1.314750 0.116830 +v 0.059106 1.314093 0.168238 +v -0.740339 1.440689 0.449950 +v -0.525136 0.475779 0.148584 +v -0.502905 0.490989 0.171648 +v -0.508873 0.527279 0.144558 +v 0.084211 1.309099 0.062755 +v -0.765658 1.167404 0.514894 +v -0.738801 1.209164 0.533958 +v -0.726659 1.300558 0.516682 +v -0.744718 1.350747 0.506889 +v -0.148243 0.872889 -0.383171 +v -0.130990 0.907760 -0.366593 +v -0.093570 0.854237 -0.381125 +v -0.399380 1.492285 0.016017 +v -0.369928 1.506393 -0.020372 +v -0.351005 1.520344 -0.001328 +v -0.923319 1.252389 0.091590 +v -0.883992 1.389900 0.106407 +v -0.867947 1.385069 0.045576 +v -0.383364 0.545035 -0.109053 +v -0.386236 0.583033 -0.115057 +v -0.352626 0.552849 -0.105451 +v -0.322579 0.881926 -0.251309 +v -0.367563 0.886634 -0.238688 +v -0.730011 1.182671 0.530346 +v -0.752605 1.493861 0.391760 +v -0.725671 1.475323 0.417141 +v -0.870414 1.305893 0.009116 +v -0.895597 1.285167 0.045458 +v -0.880914 0.877416 0.048490 +v -0.610843 1.338619 -0.072249 +v -0.651561 1.403454 -0.076848 +v -0.615304 1.403763 -0.062734 +v -0.708314 1.225442 0.532749 +v -0.726470 1.409894 0.469767 +v -0.748982 1.145886 0.507765 +v -0.722539 1.153955 0.516703 +v -0.615694 1.708488 -0.616791 +v -0.615176 1.751745 -0.606317 +v -0.609654 1.700211 -0.608394 +v -0.872652 0.921100 0.042059 +v -0.309802 1.663466 -0.162411 +v -0.234558 1.682473 -0.188229 +v -0.285356 1.620848 -0.147860 +v 0.430151 0.976910 0.010258 +v 0.412588 1.036108 0.026761 +v 0.432182 0.994867 0.050153 +v 0.503181 0.527864 -0.034166 +v 0.528542 0.518987 -0.006207 +v 0.514338 0.484852 0.010401 +v -0.340704 1.614897 -0.137869 +v -0.656969 1.456163 -0.189747 +v -0.636167 1.480137 -0.201702 +v -0.628968 1.469478 -0.130986 +v 0.037667 1.124055 0.414947 +v 0.066533 1.167356 0.387164 +v 0.008090 1.163332 0.401676 +v 0.459418 0.481388 -0.038716 +v 0.407514 1.055473 0.075074 +v 0.428790 1.009378 0.094753 +v 0.545499 0.560446 -0.006616 +v -0.531988 1.367290 -0.016580 +v -0.503648 1.371576 0.019526 +v -0.505394 1.333666 -0.010872 +v -0.162731 1.284451 0.166836 +v 0.036232 1.307679 0.211686 +v -0.693685 0.952428 0.421290 +v -0.704569 1.009878 0.397941 +v -0.734402 0.954126 0.402107 +v -0.701128 1.179035 0.527142 +v 0.013773 0.523027 0.531490 +v 0.020657 0.501047 0.522902 +v 0.036285 0.531986 0.534227 +v -0.687008 1.446354 0.430417 +v 0.495757 0.438159 0.145830 +v 0.427191 0.399771 0.089322 +v 0.466933 0.424653 0.065650 +v 0.573065 0.599446 0.018886 +v 0.574217 0.560122 0.040246 +v 0.449602 0.809426 0.006112 +v 0.455112 0.869530 0.038866 +v 0.462527 0.773739 0.069141 +v -0.600678 0.414195 0.229533 +v -0.553528 0.429362 0.191355 +v -0.611257 0.377900 0.197109 +v -0.863964 1.047936 0.059821 +v -0.843142 1.095726 0.037097 +v -0.834897 1.072473 0.007579 +v -0.751150 0.665570 0.102441 +v -0.771684 0.698264 0.050606 +v -0.745304 0.666807 0.046953 +v -0.672320 0.991739 0.415939 +v -0.676910 1.073414 0.380185 +v -0.721420 1.053668 0.375232 +v -0.693824 1.086578 0.375078 +v -0.066211 0.904152 0.568798 +v -0.012439 0.890932 0.565521 +v -0.056222 0.932350 0.558936 +v 0.094076 0.903280 0.542141 +v 0.134144 0.930737 0.514678 +v 0.095105 0.954839 0.509106 +v 0.064598 0.602974 0.547800 +v 0.026645 0.627000 0.565252 +v 0.032514 0.598286 0.554643 +v -0.681451 1.274868 0.501490 +v -0.683693 1.228929 0.524379 +v 0.468345 0.743541 0.101395 +v 0.462809 0.787020 0.147863 +v -0.918220 1.274735 0.364587 +v -0.903369 1.311983 0.381388 +v -0.903770 1.325249 0.310827 +v -0.885859 1.460587 0.098780 +v -0.856097 1.471251 0.065981 +v -0.007816 1.282292 -0.032490 +v 0.043156 1.278256 0.286469 +v -0.649846 1.037155 0.406478 +v -0.647316 1.541007 -0.404648 +v -0.652837 1.559245 -0.498659 +v -0.630699 1.589747 -0.429518 +v 0.003770 0.449358 0.465199 +v -0.006336 0.471931 0.491369 +v -0.070013 0.464165 0.474856 +v 0.073430 1.209819 0.359735 +v 0.060412 1.249436 0.326529 +v 0.034831 1.200263 0.369120 +v -0.497474 1.411252 0.052938 +v -0.480236 1.442665 0.042499 +v -0.484686 1.455961 0.083662 +v -0.942377 1.261542 0.222015 +v -0.498964 1.467086 -0.018614 +v -0.443418 1.511381 -0.056860 +v -0.437557 1.477341 -0.021433 +v 0.447178 0.948027 0.120247 +v 0.451338 0.936307 0.062337 +v 0.459185 0.870362 0.084236 +v -0.141697 1.276789 0.013081 +v -0.882842 0.868691 0.081029 +v 0.123194 1.290377 0.013336 +v -0.149302 0.386435 0.293783 +v -0.181599 0.393223 0.394029 +v -0.208143 0.384010 0.278684 +v 0.080724 0.515741 0.517736 +v 0.092232 0.441251 0.450574 +v 0.059862 0.466891 0.490736 +v 0.049305 0.419827 0.457234 +v 0.607788 0.616466 0.104640 +v 0.598372 0.664232 0.085140 +v 0.600787 0.681293 0.114545 +v 0.552579 0.514163 0.032063 +v -0.644003 1.583440 -0.542563 +v -0.642495 1.604502 -0.570414 +v -0.619459 1.647924 -0.566476 +v -0.682824 0.923768 0.423887 +v -0.679028 0.878172 0.435270 +v -0.655924 0.910424 0.440921 +v 0.168328 1.033749 0.452873 +v 0.206573 1.041683 0.430047 +v 0.150050 1.072690 0.418120 +v 0.035078 0.863395 0.570483 +v 0.047990 0.916548 0.547152 +v 0.078153 0.550507 0.527503 +v 0.051982 0.570180 0.534235 +v -0.676765 1.415032 0.438682 +v -0.656918 1.496182 0.381610 +v 0.442038 0.852043 -0.021170 +v 0.446311 0.841784 0.008267 +v 0.421069 0.815332 -0.066691 +v -0.307713 1.256407 0.165948 +v 0.136776 1.296726 0.069328 +v 0.193204 1.273835 0.112963 +v 0.192627 1.268939 0.055552 +v -0.639398 0.786218 0.420835 +v -0.649922 0.845509 0.441201 +v -0.704912 0.818182 0.406099 +v -0.699373 0.860769 0.421757 +v -0.640280 0.978387 0.425653 +v 0.432644 0.758105 -0.038844 +v 0.456200 0.746844 0.026074 +v -0.004402 0.583434 0.544834 +v -0.008548 0.605935 0.558248 +v -0.043083 0.614186 0.556885 +v 0.096509 1.010878 0.473731 +v 0.051450 1.016390 0.454230 +v 0.071936 0.988595 0.484195 +v 0.041934 0.729152 0.562987 +v 0.076963 0.723756 0.560622 +v 0.055681 0.763971 0.563272 +v -0.249391 1.703113 -0.113297 +v -0.315821 1.664185 -0.057320 +v -0.303514 1.644816 -0.053291 +v -0.046247 0.577596 0.539907 +v -0.043091 0.544675 0.539083 +v -0.243664 1.769327 -0.117196 +v -0.300716 1.725832 -0.063597 +v -0.301344 1.701132 -0.073591 +v -0.514585 0.558782 0.159004 +v -0.544637 0.553575 0.103268 +v -0.452255 1.293546 0.203775 +v -0.465485 1.332077 0.168897 +v -0.477656 1.330197 0.228740 +v -0.837022 1.222638 -0.037301 +v -0.792375 1.205542 -0.056745 +v -0.824716 1.162413 -0.023236 +v -0.624332 0.840353 0.442031 +v -0.626151 0.911269 0.450907 +v -0.590588 1.004126 0.427251 +v 0.433155 0.521455 0.324921 +v 0.437854 0.488037 0.313434 +v 0.477358 0.527510 0.307973 +v -0.194089 1.704110 -0.209948 +v -0.146559 1.745654 -0.259727 +v -0.138955 1.678717 -0.218972 +v -0.014985 0.559255 0.546308 +v -0.620960 1.638832 -0.583859 +v 0.340239 1.135388 0.245953 +v 0.333739 1.122789 0.277881 +v 0.375530 1.068529 0.263035 +v -0.601171 0.955529 0.441838 +v -0.606525 1.046720 0.409064 +v -0.637824 1.103727 0.375798 +v 0.384973 0.480624 0.317375 +v 0.379928 0.497932 0.319020 +v 0.355154 0.504496 0.314398 +v -0.562151 1.413921 -0.028027 +v -0.530434 1.409255 -0.004741 +v -0.894808 1.383998 0.250615 +v -0.907955 1.385523 0.205626 +v -0.902417 1.357599 0.141492 +v -0.205426 1.197952 0.330037 +v 0.254570 0.394839 -0.040251 +v 0.290078 0.373582 -0.002747 +v 0.221929 0.367753 -0.020919 +v -0.621261 0.628454 -0.045202 +v -0.595207 0.610403 -0.023754 +v -0.646442 0.617232 0.002255 +v -0.589222 0.775455 0.429614 +v -0.598672 0.805405 0.432771 +v -0.594986 0.888455 0.451093 +v -0.589974 0.920307 0.453353 +v 0.097163 1.052351 0.436038 +v -0.579817 1.094315 0.379977 +v 0.076406 0.864272 0.561179 +v -0.685439 1.751301 -0.571879 +v -0.660702 1.655782 -0.586441 +v -0.676845 1.653363 -0.554664 +v -0.578619 0.839444 0.441860 +v -0.566237 0.963222 0.436679 +v -0.591959 1.132080 0.362347 +v -0.002426 0.545360 0.546412 +v -0.038450 0.847878 0.571980 +v -0.748528 1.499311 -0.277529 +v -0.745775 1.516404 -0.286480 +v -0.731102 1.484717 -0.287484 +v 0.423130 0.590991 0.308484 +v 0.406359 0.615749 0.298413 +v 0.386863 0.564506 0.311889 +v 0.042516 1.052374 0.425636 +v -0.657666 0.364695 -0.072073 +v -0.684706 0.374777 -0.049557 +v -0.666349 0.404303 -0.050181 +v -0.569310 0.881015 0.446929 +v 0.106297 0.467118 0.464720 +v -0.465496 0.676521 0.396358 +v -0.477145 0.619445 0.367058 +v -0.444894 0.610777 0.395453 +v -0.691037 1.555948 0.016371 +v -0.319517 1.251839 0.194006 +v -0.540881 0.397812 -0.105447 +v -0.623743 0.401461 -0.074040 +v -0.507512 0.431096 -0.100187 +v -0.590000 0.737515 0.411971 +v -0.551114 0.746878 0.419398 +v -0.556237 0.921874 0.450550 +v -0.553090 1.036539 0.415167 +v 0.052930 0.680060 0.556705 +v 0.052848 1.094366 0.416750 +v 0.011760 1.093253 0.426628 +v -0.623456 1.474550 -0.076600 +v -0.619962 1.476148 -0.043257 +v -0.630566 1.434165 -0.074907 +v 0.119783 1.040363 0.453963 +v -0.026844 0.512474 0.531868 +v 0.024095 1.001678 0.469381 +v -0.710482 1.516109 -0.446792 +v -0.696056 1.549076 -0.501886 +v -0.669163 1.227891 -0.089077 +v -0.618976 1.229707 -0.087725 +v -0.552383 0.819994 0.449848 +v -0.549969 1.077420 0.394246 +v -0.001042 0.768819 0.581908 +v -0.020578 0.809983 0.575539 +v -0.059406 0.790382 0.579698 +v 0.605949 0.616772 0.155916 +v 0.607290 0.658066 0.139748 +v 0.600936 0.656934 0.185333 +v -0.528021 0.413199 0.461698 +v -0.571805 0.409188 0.463013 +v -0.364521 1.219987 0.276707 +v -0.307702 1.159731 0.328588 +v -0.650598 1.345210 -0.080900 +v -0.658107 1.435912 -0.125854 +v -0.682146 1.439093 -0.149841 +v -0.548769 0.702823 0.388282 +v -0.540004 0.805684 0.446015 +v -0.536167 0.853468 0.453325 +v -0.549942 0.996408 0.429552 +v -0.542014 1.145173 0.348440 +v 0.456369 0.574026 0.319922 +v 0.407755 0.545575 0.320147 +v 0.214417 0.913550 0.480434 +v 0.206393 0.966025 0.469710 +v 0.169735 0.971066 0.474409 +v -0.527224 0.447228 0.441433 +v 0.372496 0.375099 0.148158 +v 0.356060 0.365266 0.098155 +v -0.551741 0.483839 0.385178 +v -0.597105 0.365358 -0.094949 +v -0.531213 0.779124 0.433349 +v -0.529356 0.909135 0.445689 +v -0.078037 0.501693 0.509887 +v 0.132430 0.967382 0.487502 +v 0.134871 1.007642 0.474543 +v 0.461836 0.619101 0.302234 +v 0.460866 0.664739 0.268090 +v 0.209252 0.863114 0.494331 +v 0.178694 0.908986 0.487130 +v 0.429158 0.667077 0.269947 +v 0.430231 0.637958 0.280392 +v 0.457192 0.694894 0.235494 +v 0.529880 0.477477 0.050420 +v 0.569080 0.515781 0.072538 +v 0.567306 0.505157 0.106271 +v 0.203192 1.004196 0.457605 +v -0.409172 0.461218 -0.179426 +v -0.374202 0.454285 -0.242268 +v -0.421505 0.433440 -0.215087 +v -0.509804 1.348661 0.275850 +v -0.476566 1.307752 0.255236 +v -0.085308 0.601594 0.553090 +v -0.126196 0.616350 0.544241 +v -0.119876 0.574932 0.527524 +v -0.289509 0.392859 0.533091 +v -0.297487 0.365398 0.524933 +v -0.500270 0.813113 0.442642 +v -0.519010 0.954576 0.439377 +v -0.519964 0.997078 0.427166 +v -0.507494 1.092868 0.382976 +v -0.497974 1.134210 0.351179 +v -0.057500 0.654890 0.561734 +v -0.001129 0.692882 0.565798 +v -0.050025 0.696550 0.568925 +v 0.201313 1.073278 0.403239 +v 0.196592 1.123622 0.375453 +v 0.151372 1.157149 0.370320 +v 0.392187 1.066925 0.204502 +v 0.371765 1.106440 0.188113 +v -0.507457 0.761484 0.431376 +v -0.514957 1.049674 0.403472 +v 0.027381 0.791057 0.567192 +v 0.089404 1.071064 0.412434 +v -0.526556 0.484942 0.387312 +v -0.491866 0.464112 0.411700 +v -0.497544 0.497383 0.370371 +v -0.490008 0.862217 0.453521 +v -0.503722 0.888447 0.451880 +v -0.488090 0.910839 0.444567 +v 0.129813 1.136637 0.383030 +v -0.001225 0.932011 0.553984 +v -0.021452 1.114329 0.424366 +v -0.618959 1.542425 -0.190186 +v -0.621651 1.566685 -0.178377 +v -0.622785 1.516660 -0.146727 +v -0.499603 0.431019 0.444627 +v 0.591199 0.631288 0.215618 +v -0.677514 1.460521 -0.233333 +v -0.688669 1.472334 -0.287398 +v -0.664679 1.487154 -0.315793 +v -0.491873 1.045201 0.403014 +v 0.466612 0.547192 0.319768 +v -0.773827 1.534660 0.308950 +v -0.752693 1.523295 0.343741 +v -0.539930 1.449866 -0.011093 +v -0.502714 1.433656 0.015153 +v -0.725397 0.353993 0.070299 +v -0.720160 0.375727 0.039789 +v -0.714981 0.344530 0.042027 +v -0.486180 0.964527 0.441831 +v -0.475904 1.008118 0.423492 +v 0.348384 0.431534 0.289543 +v 0.324340 0.453340 0.303168 +v -0.029935 0.721864 0.581672 +v -0.063735 0.721843 0.579730 +v -0.035439 0.426598 0.475415 +v -0.065174 0.450362 0.475028 +v -0.149812 0.425714 0.514045 +v -0.473789 0.484567 0.391268 +v -0.466862 0.545707 0.375874 +v -0.503993 0.518313 0.340374 +v -0.474018 0.755503 0.426302 +v -0.494959 0.734363 0.416736 +v -0.474969 1.063566 0.401657 +v -0.459667 1.090514 0.387541 +v -0.661781 1.421835 -0.093766 +v -0.637554 1.442888 -0.113957 +v -0.440717 0.510582 0.389778 +v -0.453765 0.823835 0.432821 +v -0.456811 0.849880 0.441595 +v -0.445146 0.948604 0.429725 +v -0.454116 0.910021 0.432528 +v -0.914905 1.454318 0.222772 +v -0.908501 1.462561 0.148091 +v -0.917576 1.433459 0.177907 +v 0.091007 0.484745 0.493532 +v -0.437200 1.682274 0.023425 +v -0.445904 0.437980 0.426855 +v -0.444341 0.876545 0.434776 +v -0.458516 1.207298 0.276651 +v -0.490201 1.177129 0.315814 +v -0.110968 1.820232 -0.280424 +v -0.102445 1.789583 -0.295388 +v -0.121720 1.812510 -0.290611 +v 0.000268 1.044673 0.437759 +v -0.674477 1.550768 -0.515942 +v -0.667137 1.535882 -0.490971 +v -0.466535 1.591782 0.078019 +v -0.902057 1.494777 0.130351 +v -0.875112 1.506150 0.101525 +v -0.436865 0.471545 0.402863 +v -0.685042 1.673202 -0.239595 +v 0.338645 0.786567 -0.176325 +v 0.307306 0.819690 -0.200404 +v 0.337484 0.836441 -0.186304 +v -0.449895 0.715773 0.419293 +v -0.450556 0.787963 0.423413 +v -0.439909 0.994255 0.423834 +v -0.442432 1.043172 0.413400 +v -0.429144 1.183599 0.306451 +v -0.198189 1.650949 -0.176090 +v -0.157232 1.631234 -0.163965 +v -0.314496 1.546046 -0.076802 +v -0.282188 1.575814 -0.109995 +v -0.242656 1.568769 -0.078509 +v -0.453013 1.569506 0.072037 +v -0.437239 1.619137 0.057714 +v -0.427402 0.769953 0.428041 +v -0.414912 1.122477 0.358735 +v -0.403421 1.166955 0.324602 +v -0.494226 1.428352 0.089729 +v -0.511083 1.452022 0.142795 +v 0.528019 0.465399 0.104277 +v 0.485100 0.617808 0.303473 +v -0.419793 0.696300 0.418249 +v -0.419961 0.810837 0.424562 +v -0.423245 1.073728 0.394565 +v -0.642308 1.487781 -0.258997 +v 0.069545 0.647001 0.555992 +v 0.002537 0.657412 0.565693 +v -0.415037 1.674851 0.032766 +v -0.501687 0.534623 0.162554 +v -0.418791 0.561644 0.397967 +v -0.420564 0.867115 0.425346 +v -0.414608 0.985448 0.417786 +v -0.922809 1.276205 0.297517 +v -0.624254 1.636664 -0.496673 +v -0.009496 1.014111 0.442901 +v -0.412449 0.430989 0.421296 +v -0.389799 0.579963 0.401514 +v -0.391856 0.630745 0.413829 +v -0.395176 0.781278 0.429186 +v -0.619544 1.686532 -0.526211 +v -0.628326 0.451827 0.346229 +v -0.594144 0.472780 0.341724 +v -0.038982 1.056617 0.440472 +v -0.093936 1.074281 0.434546 +v -0.078047 1.051662 0.438255 +v -0.389338 0.463643 0.403648 +v -0.381441 0.505996 0.393022 +v -0.383409 0.688438 0.418465 +v -0.393579 0.836314 0.435024 +v -0.394303 0.895976 0.431779 +v -0.397382 1.021536 0.405744 +v -0.486636 1.363852 0.068064 +v -0.484343 1.375497 0.132450 +v -0.089830 1.692645 -0.226835 +v -0.104828 1.666829 -0.217461 +v -0.097846 1.692849 -0.247566 +v -0.313581 1.536220 -0.046739 +v -0.294602 1.555026 -0.011914 +v -0.366584 0.750873 0.420070 +v -0.362989 0.956956 0.435803 +v -0.389789 1.068304 0.382477 +v -0.354537 1.124477 0.350554 +v -0.380502 1.152707 0.331786 +v -0.363093 1.187694 0.306740 +v -0.406522 1.226651 0.262903 +v -0.853298 1.533991 0.203783 +v -0.868249 1.528078 0.155215 +v -0.888754 1.516944 0.200866 +v -0.408023 1.643606 0.037449 +v -0.378573 1.701010 0.014236 +v -0.372779 1.728907 -0.008662 +v -0.031959 1.191252 0.383496 +v 0.000309 1.231575 0.347497 +v -0.064292 1.220109 0.357409 +v -0.391797 0.424067 0.414761 +v 0.595580 0.630993 0.059471 +v 0.595316 0.605046 0.058397 +v -0.369962 1.689930 0.013257 +v -0.352183 0.685598 0.413815 +v -0.365055 0.811523 0.431623 +v -0.367449 0.860837 0.436129 +v -0.367449 0.888869 0.433121 +v -0.356422 0.926174 0.442385 +v -0.359315 0.998099 0.423358 +v -0.362256 1.063424 0.386449 +v 0.000219 0.734960 0.576967 +v 0.414140 1.028422 0.165789 +v 0.435477 0.973894 0.173147 +v 0.199681 0.348440 -0.018985 +v 0.204148 0.355676 -0.037807 +v -0.361513 0.465051 0.407409 +v -0.343032 0.505201 0.382860 +v -0.343858 0.540960 0.380603 +v -0.344487 0.607805 0.395440 +v -0.330642 0.766548 0.412779 +v -0.321612 1.089650 0.381027 +v 0.098020 1.100399 0.399454 +v 0.083873 1.133622 0.397926 +v -0.032479 0.757107 0.587147 +v -0.366472 1.664013 -0.002816 +v -0.350226 0.828882 0.429128 +v -0.330585 0.861855 0.425604 +v -0.332389 0.885736 0.436971 +v -0.335821 1.038391 0.407380 +v -0.343932 1.723669 -0.009821 +v -0.291773 1.761996 -0.056241 +v -0.533230 1.527352 0.162139 +v -0.553690 1.544248 0.161607 +v -0.326899 0.677297 0.401244 +v -0.332443 0.822666 0.418522 +v -0.088692 0.954003 0.544460 +v -0.058623 0.973502 0.527437 +v -0.318350 0.907230 0.441735 +v -0.074442 1.169342 0.392839 +v -0.075520 1.118381 0.420397 +v -0.306148 0.544126 0.366943 +v -0.302725 0.624747 0.379822 +v -0.292417 0.942904 0.448212 +v -0.308676 0.969147 0.446514 +v -0.720836 1.496555 -0.392658 +v -0.723030 1.518670 -0.415443 +v -0.929073 1.230702 0.365232 +v -0.308006 0.800684 0.417981 +v -0.291512 1.019737 0.426331 +v 0.523273 0.643271 0.282819 +v 0.504000 0.672925 0.268515 +v 0.216211 0.376572 -0.047022 +v -0.292454 0.695515 0.393690 +v -0.292556 0.751692 0.411864 +v -0.299820 0.854023 0.437451 +v -0.292419 0.904534 0.442366 +v -0.283421 0.977827 0.437613 +v 0.455982 0.881517 0.131241 +v 0.446356 0.927943 0.178321 +v 0.342581 0.519308 0.327579 +v -0.068964 0.844329 0.571686 +v -0.325972 1.749873 -0.025953 +v -0.299962 1.781114 -0.052358 +v -0.275385 0.799648 0.476972 +v -0.273959 0.841083 0.487457 +v 0.577446 0.641584 0.026278 +v 0.583731 0.680676 0.057248 +v 0.107746 1.307916 0.143418 +v -0.280014 0.610754 0.374712 +v -0.280542 0.545510 0.367869 +v 0.401948 1.023160 -0.020048 +v 0.374187 1.085082 0.003397 +v 0.109155 1.263363 0.298570 +v 0.101452 1.222168 0.347190 +v 0.463517 0.740795 0.183543 +v 0.455420 0.833384 0.197009 +v -0.647969 1.521062 -0.361855 +v -0.632749 1.524573 -0.322217 +v -0.277200 0.505021 0.433407 +v -0.298429 0.467823 0.477469 +v -0.264689 0.478164 0.493226 +v -0.270463 0.670144 0.396722 +v -0.256226 0.987134 0.442109 +v -0.249016 1.121114 0.375603 +v -0.258693 1.042670 0.422076 +v -0.004658 1.198366 -0.136106 +v 0.008482 1.167002 -0.173371 +v -0.018733 1.159391 -0.171694 +v 0.012556 0.838456 0.574464 +v -0.685354 1.392937 -0.078046 +v -0.622631 1.521993 -0.225789 +v -0.258671 0.566892 0.391822 +v -0.253532 0.625672 0.406422 +v -0.240789 0.679067 0.451784 +v -0.926543 1.208402 0.416297 +v -0.931898 1.201992 0.379137 +v -0.922408 1.181684 0.412017 +v 0.363850 0.569965 0.336015 +v -0.265614 0.932895 0.449754 +v -0.211268 1.093229 0.407153 +v -0.249298 1.159277 0.340947 +v -0.227493 0.498839 0.466055 +v -0.555305 1.490553 -0.019602 +v -0.500767 1.499765 -0.036419 +v 0.497601 0.702352 0.237320 +v 0.086784 1.289457 0.261569 +v 0.157997 1.290142 0.132369 +v -0.243799 0.958664 0.444345 +v -0.224919 0.465136 0.518853 +v -0.229494 0.510206 0.439265 +v -0.247876 0.526062 0.408398 +v -0.639539 1.469473 0.384842 +v -0.228702 1.028473 0.435448 +v -0.184713 1.596772 -0.111695 +v -0.142225 1.616743 -0.133490 +v -0.243646 1.809684 -0.098312 +v -0.264679 1.810425 -0.080811 +v -0.241069 1.838089 -0.115447 +v -0.261775 0.424989 0.533152 +v -0.218670 0.440229 0.532438 +v -0.223658 0.480736 0.501265 +v -0.155133 1.043613 0.429194 +v -0.151196 0.999300 0.445003 +v -0.115997 1.010781 0.441917 +v -0.881303 0.975405 0.056788 +v -0.352071 1.250522 0.216357 +v -0.183831 1.854366 -0.171363 +v -0.152107 1.846364 -0.220572 +v -0.172707 1.869960 -0.199775 +v -0.223620 0.982076 0.447660 +v 0.112121 0.665841 0.539822 +v -0.670703 1.807268 -0.566186 +v -0.523127 0.510853 0.244857 +v -0.521306 0.563030 0.266725 +v -0.509161 0.538136 0.197531 +v -0.208817 1.140953 0.378730 +v -0.602536 1.433910 -0.037906 +v 0.167710 0.886447 0.505230 +v 0.180453 0.836232 0.512859 +v -0.198758 0.516077 0.461420 +v -0.215889 0.568369 0.454671 +v -0.384934 0.728399 -0.175022 +v -0.352630 0.710677 -0.180118 +v -0.353857 0.668174 -0.154348 +v 0.163292 1.225189 0.313754 +v 0.138138 1.232219 0.325026 +v 0.165740 1.189015 0.350423 +v -0.202182 1.021439 0.437012 +v 0.508013 0.573081 0.300014 +v 0.504123 0.603126 0.302451 +v -0.175335 0.479642 0.488296 +v -0.913098 1.484859 0.162701 +v -0.910037 1.488572 0.215071 +v -0.900121 1.508334 0.157528 +v 0.167152 1.268985 0.002233 +v -0.529987 0.491690 0.339676 +v -0.572765 0.472996 0.298900 +v -0.448429 1.462939 0.017115 +v -0.180579 1.050392 0.428028 +v -0.369318 0.371074 -0.297142 +v -0.405419 0.388860 -0.273649 +v -0.339573 0.410251 -0.296602 +v 0.101139 0.764681 0.552568 +v 0.081848 0.807562 0.553745 +v -0.155101 0.452831 0.506530 +v -0.180021 0.499178 0.469480 +v -0.169113 0.518435 0.484593 +v -0.290472 1.255634 0.077618 +v 0.095078 1.304186 0.207150 +v -0.704132 1.412920 -0.084591 +v -0.224137 0.832835 0.555907 +v -0.205806 0.795725 0.560139 +v -0.191353 0.834748 0.572174 +v -0.073157 0.739196 0.579717 +v 0.157606 0.932036 0.499393 +v -0.166833 0.872667 0.567412 +v -0.200222 0.880321 0.555894 +v -0.188705 0.989732 0.444893 +v -0.166926 1.156855 0.378532 +v 0.296650 0.715068 -0.212823 +v 0.263218 0.702407 -0.238787 +v 0.254729 0.740945 -0.249385 +v 0.061508 0.834062 0.564635 +v -0.422335 1.721157 -0.041800 +v -0.177955 0.774862 0.560873 +v -0.169932 0.825558 0.575239 +v -0.162492 0.542921 0.503069 +v -0.183400 0.574900 0.497630 +v -0.174206 0.696595 0.540895 +v -0.152422 0.709099 0.550048 +v -0.152411 0.918217 0.558173 +v -0.193214 0.921239 0.538207 +v 0.139064 1.279084 0.251103 +v -0.115586 0.338954 -0.210543 +v -0.133711 0.343616 -0.190237 +v -0.236715 0.336310 -0.232178 +v -0.151800 1.080775 0.423504 +v -0.139916 1.196257 0.362516 +v -0.133734 0.478924 0.478839 +v -0.157159 0.608230 0.523655 +v -0.143547 0.544282 0.507103 +v -0.147460 0.655839 0.537309 +v -0.145578 0.765822 0.564933 +v -0.152456 0.829408 0.569346 +v -0.136261 0.897879 0.566744 +v -0.143940 0.945876 0.539935 +v -0.831594 1.467428 0.030758 +v -0.827325 1.419686 0.012529 +v 0.132262 1.295807 0.196896 +v -0.129534 1.159358 0.389202 +v -0.123952 1.226473 0.335883 +v 0.487491 0.452650 0.023024 +v 0.433421 0.716761 -0.022304 +v -0.137749 0.708879 0.546956 +v -0.124060 0.852226 0.572678 +v -0.121935 0.494703 0.494845 +v -0.118660 0.731837 0.562501 +v -0.113787 0.798771 0.576989 +v -0.128198 1.045710 0.434657 +v -0.116086 1.098371 0.424753 +v 0.247661 1.108111 0.367284 +v -0.104465 0.536860 0.519586 +v -0.102829 0.689263 0.552896 +v -0.099440 0.763431 0.573886 +v -0.112138 0.923664 0.561053 +v -0.108726 0.888268 0.566655 +v 0.446930 0.926886 0.022467 +v -0.076323 1.030453 0.437107 +v -0.381178 0.763901 -0.186443 +v -0.565603 0.483555 0.366071 +v -0.113879 0.647424 0.549180 +v -0.084981 0.839905 0.576052 +v -0.075347 1.002130 0.474887 +v -0.158628 0.970216 0.501394 +v -0.062546 1.012165 0.443220 +v -0.881946 1.031463 0.175090 +v 0.150482 0.457558 0.437939 +v 0.147443 0.427169 0.445103 +v 0.109362 0.860273 0.547327 +v -0.206167 1.823759 -0.142991 +v -0.460763 1.681972 0.007375 +v 0.301687 1.004869 0.394047 +v 0.261109 1.008899 0.417333 +v 0.288147 0.967127 0.422577 +v -0.313557 1.580989 0.019129 +v -0.253736 1.584001 -0.014801 +v -0.262918 1.596338 -0.005184 +v 0.104060 0.591624 0.524844 +v 0.099912 0.627353 0.540093 +v -0.153064 0.352464 0.501338 +v -0.094780 0.359776 0.494342 +v -0.177275 0.362895 0.522223 +v 0.244117 0.980169 0.446874 +v 0.237801 0.952229 0.463473 +v 0.547150 0.646972 0.269797 +v 0.539440 0.613915 0.282685 +v 0.171768 0.730662 0.518266 +v 0.181098 0.758066 0.524883 +v 0.140743 0.766517 0.542214 +v 0.544516 0.583429 0.276530 +v 0.399069 0.643613 0.316867 +v 0.375192 0.610627 0.343660 +v 0.437662 0.883900 -0.035709 +v -0.394947 0.375516 0.428709 +v -0.433237 0.362864 0.440424 +v 0.568206 0.636911 0.252861 +v 0.518237 0.532767 0.279270 +v -0.391610 1.571888 -0.105805 +v -0.336196 1.569147 -0.110248 +v 0.140552 0.525239 0.485939 +v 0.194212 0.513213 0.447989 +v 0.192046 0.551665 0.477222 +v 0.266373 0.476071 -0.164277 +v 0.245671 0.441301 -0.108208 +v 0.220401 0.449925 -0.175285 +v 0.270207 0.613457 -0.222921 +v 0.309404 0.605181 -0.181327 +v 0.306628 0.573004 -0.165184 +v -0.233436 1.610345 -0.031862 +v -0.292649 1.614042 -0.021039 +v 0.145215 0.613829 0.505009 +v 0.165683 0.662699 0.510099 +v 0.129196 0.642036 0.524412 +v -0.504927 1.415990 0.162918 +v -0.476728 0.361167 -0.133012 +v -0.711354 1.381765 0.478540 +v 0.149048 0.563504 0.495228 +v 0.117454 0.566783 0.519141 +v -0.493499 1.491352 0.112741 +v -0.235743 0.370369 0.541448 +v -0.269407 0.361840 0.533519 +v -0.229340 0.356329 0.528655 +v -0.697606 1.344285 0.482652 +v 0.335255 1.096621 -0.069895 +v 0.379551 1.048871 -0.032032 +v 0.366959 1.037284 -0.079621 +v -0.662994 1.233712 0.506159 +v -0.576354 0.504255 0.046108 +v -0.560675 0.534706 0.073718 +v -0.570694 0.544244 0.023396 +v 0.201531 1.184972 0.342713 +v 0.341264 0.970540 0.375904 +v 0.292500 1.065193 0.365903 +v 0.287344 1.036005 0.380353 +v 0.177748 0.582438 0.488647 +v -0.370771 1.598637 0.016097 +v -0.688765 1.102217 0.390046 +v -0.238543 1.616453 -0.145042 +v 0.559573 0.531474 0.231977 +v 0.517038 0.488574 0.241480 +v -0.786095 0.696569 0.118108 +v -0.668172 1.195152 0.514902 +v -0.667024 1.321060 0.454810 +v -0.352032 1.649355 -0.026810 +v -0.653983 1.175195 0.487356 +v -0.680900 1.164705 0.511512 +v -0.675044 1.142409 0.480361 +v -0.328000 1.594870 0.021963 +v -0.642050 1.224389 0.480084 +v 0.448725 0.755167 0.231553 +v 0.451370 0.446254 0.255165 +v 0.490157 0.445736 0.206595 +v -0.629906 1.199946 0.452356 +v -0.643482 1.262809 0.466502 +v 0.576794 0.613930 0.242018 +v 0.566718 0.569708 0.242919 +v 0.381029 0.656784 0.351325 +v 0.359718 0.666696 0.377814 +v 0.353418 0.616300 0.376060 +v 0.387855 0.949543 0.325202 +v 0.392915 1.012597 0.275505 +v 0.367584 0.991955 0.328377 +v -0.364250 0.936307 -0.235346 +v -0.392279 0.991846 -0.219127 +v -0.655999 1.132950 0.423187 +v -0.690872 1.120501 0.453201 +v -0.636028 1.157145 0.425723 +v -0.654245 1.401128 0.413090 +v 0.592385 0.563628 0.094531 +v 0.564127 0.676599 0.239693 +v 0.384462 0.756494 0.350507 +v 0.369751 0.798765 0.371984 +v 0.354720 0.730767 0.384823 +v 0.287793 0.825532 0.445274 +v 0.284233 0.880111 0.442342 +v 0.258729 0.884823 0.466553 +v 0.545372 0.687967 0.245177 +v -0.633666 1.303707 0.416700 +v 0.231839 0.586544 0.458711 +v 0.246721 0.636945 0.452046 +v 0.219024 0.608760 0.472824 +v 0.361438 0.844392 0.379369 +v 0.384136 0.874899 0.351859 +v 0.344046 0.869328 0.405743 +v -0.615112 1.237356 0.430627 +v -0.217911 1.065804 -0.223270 +v -0.169534 1.066926 -0.220030 +v -0.199876 1.027831 -0.233929 +v 0.178974 0.795165 0.527595 +v -0.128937 1.787904 -0.226247 +v -0.110919 1.799208 -0.259964 +v -0.642874 1.346362 0.399457 +v 0.125345 0.895939 0.533946 +v 0.201270 0.638513 0.479197 +v 0.480748 0.489700 0.281655 +v -0.197117 1.682914 -0.130209 +v -0.114474 1.713106 -0.196030 +v -0.158154 1.750494 -0.186541 +v -0.637129 1.127425 0.380068 +v 0.422099 0.788615 0.291872 +v -0.627631 1.377801 0.366786 +v -0.388647 1.033399 -0.206414 +v -0.332023 1.057832 -0.206476 +v 0.398997 0.702948 0.327200 +v 0.269968 0.513178 0.387521 +v 0.312863 0.528638 0.369136 +v 0.289526 0.561252 0.403890 +v 0.194873 0.408093 0.426411 +v 0.216914 0.401615 0.408465 +v 0.226252 0.436217 0.409046 +v 0.258218 0.463266 0.382772 +v 0.189280 0.442496 0.430098 +v 0.216327 0.481273 0.406944 +v 0.272687 0.445478 0.361525 +v 0.245624 0.483696 -0.196728 +v -0.610960 1.170165 0.396540 +v -0.593754 1.199824 0.405483 +v -0.599371 1.272619 0.407713 +v -0.611289 1.317833 0.389159 +v -0.621456 1.359977 0.367010 +v -0.624419 1.408478 0.369659 +v 0.242862 0.549586 0.430869 +v -0.612957 1.451999 0.371379 +v -0.379877 1.075145 -0.199757 +v -0.573353 1.234010 0.402315 +v -0.564643 0.376831 0.468196 +v -0.509647 0.383123 0.462861 +v -0.329774 0.663652 -0.183855 +v 0.195371 0.600038 0.485761 +v -0.162575 1.603125 -0.096926 +v -0.212169 1.588794 -0.046923 +v -0.215921 1.576344 -0.068623 +v -0.132534 1.662715 -0.141203 +v -0.109868 1.662120 -0.160475 +v -0.677506 1.573483 -0.539821 +v -0.655095 1.585733 -0.556002 +v -0.570314 1.156201 0.364949 +v -0.228765 1.739281 -0.134311 +v -0.179690 1.807803 -0.181034 +v 0.167434 0.484390 0.436786 +v 0.234693 1.165626 0.335373 +v -0.569165 1.262351 0.394266 +v -0.582595 1.409949 0.324407 +v -0.600104 1.428446 0.354497 +v -0.591297 1.503971 0.344896 +v -0.416653 1.499614 0.045405 +v -0.165309 1.632500 -0.092475 +v -0.226016 1.625045 -0.060717 +v -0.178916 1.611380 -0.067072 +v -0.558599 1.177431 0.372535 +v -0.547258 1.207126 0.374515 +v -0.555169 1.295607 0.365985 +v -0.582031 1.327097 0.369187 +v -0.560328 1.373108 0.319706 +v -0.582986 1.388550 0.329375 +v -0.586033 1.463724 0.338088 +v 0.563052 0.677699 0.026525 +v -0.392694 1.520523 -0.066204 +v -0.541726 1.233792 0.375765 +v -0.501266 0.709331 0.394810 +v -0.452091 0.388391 0.445038 +v -0.265809 1.556769 -0.041963 +v -0.199263 1.648974 -0.099900 +v -0.521662 1.501366 0.174488 +v 0.185966 0.352939 -0.086782 +v 0.241087 0.844926 0.482923 +v 0.252716 0.787249 0.480266 +v 0.132347 0.384531 0.445015 +v -0.532167 1.322198 0.329784 +v -0.568023 1.451467 0.317403 +v -0.457543 0.352070 0.435181 +v -0.544037 0.350073 0.448746 +v -0.534258 0.345600 0.427824 +v 0.218860 0.539276 0.451025 +v -0.513169 0.482707 -0.079310 +v -0.463852 0.474909 -0.100860 +v -0.519416 1.256599 0.345879 +v -0.560701 1.500071 0.298677 +v -0.495795 0.360965 0.459554 +v 0.144240 0.800855 0.537556 +v 0.288105 0.433523 0.321577 +v 0.330446 1.076625 0.319162 +v 0.290631 1.114960 0.338058 +v 0.362944 0.712207 0.371146 +v 0.333639 0.670548 0.397295 +v 0.209919 0.693354 0.490036 +v 0.226875 0.751492 0.493125 +v 0.233868 0.700760 0.470126 +v -0.522773 1.177508 0.337695 +v -0.547315 1.426723 0.289805 +v 0.428311 0.855560 0.278738 +v -0.711690 1.474016 -0.275909 +v -0.717236 1.461744 -0.215678 +v 0.217409 0.802506 0.504254 +v -0.496658 1.206380 0.321633 +v -0.549107 1.466231 0.284390 +v -0.345080 1.544747 0.016505 +v 0.300517 0.621696 0.415458 +v 0.293629 0.665098 0.422894 +v -0.220478 1.834859 -0.120950 +v -0.511036 0.730720 -0.162430 +v 0.329786 0.735007 0.404865 +v 0.297417 0.706471 0.416539 +v 0.373268 0.402095 -0.008585 +v 0.437796 0.445307 -0.012622 +v 0.432934 0.418641 0.020634 +v -0.601458 0.412020 0.442938 +v -0.530782 1.375469 0.282665 +v -0.097015 1.673886 -0.193602 +v -0.111837 1.645000 -0.161517 +v 0.324116 0.937361 0.408903 +v 0.391084 1.082907 0.131423 +v 0.330404 0.617738 0.397814 +v -0.185276 1.765320 -0.170435 +v -0.290096 0.512653 -0.221758 +v -0.255283 0.514727 -0.268847 +v -0.260495 0.476925 -0.261495 +v -0.495368 1.249134 0.317785 +v -0.495078 1.294950 0.302593 +v 0.131891 0.842112 0.530658 +v 0.289824 0.740885 0.434473 +v 0.288271 0.921334 0.439201 +v 0.308850 0.789995 0.433888 +v 0.259036 0.755360 0.464167 +v 0.335738 0.585153 0.383110 +v 0.327565 0.889691 0.422155 +v 0.304450 0.849596 0.430111 +v -0.538318 1.498169 0.250666 +v -0.911888 1.158889 0.247056 +v -0.469888 1.260080 0.269855 +v 0.238558 1.061662 0.393781 +v 0.270139 0.599528 0.434544 +v -0.910443 1.419986 0.217297 +v -0.909497 1.389537 0.173712 +v 0.261087 0.680076 0.439027 +v 0.256585 0.705504 0.445399 +v -0.478435 1.221506 0.288332 +v -0.017343 0.394768 0.472629 +v 0.236780 0.514744 0.410533 +v 0.254642 0.540297 -0.216910 +v 0.290630 0.552106 -0.180421 +v 0.267755 0.514235 -0.202341 +v -0.570941 0.459965 0.268653 +v -0.624641 0.437220 0.284933 +v -0.386705 1.607020 -0.123577 +v 0.410654 0.904607 0.298886 +v -0.735044 0.938833 -0.147517 +v -0.756432 0.994404 -0.119276 +v -0.725986 0.977627 -0.144345 +v 0.237531 0.346707 0.039885 +v 0.290866 0.358000 0.035631 +v 0.352517 0.908368 0.391839 +v 0.581774 0.528213 0.151824 +v 0.597981 0.568402 0.133427 +v 0.330301 0.837816 0.416369 +v -0.372925 1.644906 -0.136270 +v -0.335409 0.363426 0.490900 +v -0.351460 0.385859 0.477327 +v -0.368986 0.359246 0.447942 +v -0.866747 0.826650 0.151744 +v 0.421561 0.697176 0.283182 +v 0.048689 0.379624 0.458676 +v -0.578226 0.695380 -0.144165 +v -0.516735 0.668507 -0.121203 +v -0.517042 0.376204 -0.117634 +v -0.470801 0.407007 -0.118698 +v -0.708877 1.440462 -0.149085 +v 0.485127 0.717982 0.060005 +v 0.396048 0.449395 0.299924 +v -0.225421 0.406158 0.539860 +v -0.256474 0.388607 0.541614 +v 0.422966 0.454358 0.290409 +v 0.196360 0.382340 -0.125077 +v 0.219775 0.428553 -0.145362 +v 0.216970 0.404273 -0.094629 +v -0.860615 0.799311 0.144408 +v -0.132203 1.839719 -0.275194 +v -0.137085 1.849115 -0.255495 +v 0.118070 0.709210 0.542405 +v -0.639385 1.526270 0.344811 +v 0.590921 0.579570 0.202701 +v 0.565202 0.511799 0.199406 +v 0.588260 0.555038 0.186479 +v 0.571803 0.711077 0.080308 +v 0.564552 0.699515 0.049192 +v 0.537352 0.720273 0.068010 +v 0.565249 0.501257 0.155645 +v 0.583746 0.711864 0.130728 +v 0.598867 0.685130 0.161716 +v -0.637311 1.657704 -0.601036 +v -0.623592 1.754483 -0.614860 +v -0.630212 1.781095 -0.603935 +v -0.176180 0.389112 0.524034 +v -0.167175 0.336116 -0.246254 +v -0.782173 1.687397 -0.335642 +v -0.754295 1.709560 -0.328799 +v -0.208911 1.859534 -0.150373 +v 0.312988 0.759074 0.426991 +v -0.460949 1.529685 0.090030 +v -0.333598 1.698640 -0.154490 +v -0.245399 1.800586 -0.187269 +v -0.271135 1.733216 -0.185389 +v -0.802943 0.717024 0.159953 +v -0.448823 1.505296 0.076452 +v -0.614070 1.726882 -0.582657 +v -0.625417 1.767946 -0.578218 +v -0.625142 1.721312 -0.527881 +v 0.249756 0.426446 -0.070170 +v -0.288615 0.353967 0.173500 +v -0.348346 0.347214 0.345782 +v -0.298032 0.342870 0.163531 +v -0.316939 1.026127 -0.223523 +v 0.217473 1.211846 0.308788 +v 0.190679 1.214492 0.319685 +v 0.152633 0.715719 0.527174 +v -0.627445 1.639753 -0.593983 +v -0.882062 0.944857 0.237440 +v -0.887605 0.970374 0.210791 +v -0.888264 0.904833 0.212047 +v -0.308930 0.474090 -0.249540 +v 0.444501 0.818469 0.245529 +v 0.408248 0.951702 0.286579 +v -0.737957 1.089563 0.392173 +v 0.451614 0.710304 0.225307 +v -0.455699 1.466361 0.056514 +v -0.418041 1.558208 0.064548 +v -0.427642 1.572749 0.052016 +v -0.441112 0.928840 -0.223732 +v -0.510791 0.938928 -0.217617 +v -0.511396 0.966176 -0.220951 +v -0.114404 0.376408 0.502757 +v -0.104240 0.384886 0.062293 +v -0.165564 0.382865 0.102158 +v -0.142517 0.386480 -0.043030 +v -0.523690 1.468291 0.189347 +v -0.315358 0.447404 -0.280794 +v 0.383359 0.388308 0.030938 +v -0.073775 0.389884 0.489295 +v -0.416014 1.597800 0.035375 +v 0.407215 0.784755 -0.082130 +v -0.377768 1.555195 0.043701 +v -0.835609 1.525594 0.076807 +v -0.788761 1.534701 0.039876 +v -0.832120 1.507213 0.042129 +v 0.414774 0.855094 -0.091575 +v -0.713953 1.246885 -0.085944 +v -0.367521 1.580207 0.041862 +v -0.092489 1.772585 -0.282702 +v -0.095837 1.742610 -0.283907 +v -0.378854 1.619972 0.002469 +v -0.610805 1.683377 -0.591920 +v -0.283987 1.807065 -0.078469 +v -0.728232 1.451060 -0.156547 +v -0.349983 0.523316 -0.103474 +v -0.434653 1.245115 0.225189 +v -0.760033 1.636134 -0.180211 +v -0.769039 1.670803 -0.269313 +v -0.774095 1.626052 -0.207546 +v -0.134690 1.629936 -0.120000 +v -0.407506 0.492851 -0.112862 +v -0.154515 1.859760 -0.247958 +v -0.880896 1.113548 0.185162 +v -0.467556 1.328429 0.081213 +v -0.515957 0.844221 -0.216009 +v -0.526758 0.882207 -0.218863 +v -0.489848 0.907318 -0.218172 +v -0.878293 1.435146 0.357077 +v -0.894082 1.435282 0.309248 +v -0.891103 1.385139 0.376588 +v -0.637571 1.591218 -0.501557 +v -0.869911 0.864447 0.224210 +v -0.893851 0.990240 0.175218 +v -0.623726 1.531304 -0.289971 +v -0.620593 1.569781 -0.337846 +v -0.615914 1.568157 -0.259456 +v -0.617687 1.606796 -0.340463 +v -0.618797 1.600045 -0.258062 +v -0.920196 1.161153 0.358427 +v -0.603184 0.384430 0.452460 +v -0.629283 0.390617 0.427077 +v -0.620019 0.364350 0.439189 +v -0.852366 1.107736 0.245377 +v -0.861615 1.083859 0.182449 +v -0.601135 0.355504 0.449076 +v -0.178705 0.382039 0.202432 +v -0.257981 0.378650 0.199815 +v -0.852702 1.055177 0.232910 +v -0.841234 1.083205 0.247310 +v -0.935758 1.247463 0.262133 +v -0.926014 1.301865 0.251836 +v -0.432268 0.462636 -0.117717 +v -0.912820 1.331190 0.246887 +v -0.623119 1.637111 -0.406240 +v -0.893132 1.365301 0.304588 +v 0.558590 0.629102 0.006904 +v -0.926747 1.170195 0.118895 +v 0.242519 0.564575 -0.242548 +v 0.350477 0.409739 0.269704 +v 0.289484 0.391600 0.272348 +v 0.335841 0.383039 0.229287 +v -0.336564 0.343441 0.369141 +v -0.419132 0.344677 0.332000 +v 0.301453 0.862840 -0.204081 +v 0.353588 0.874389 -0.171090 +v -0.092296 1.731446 -0.241976 +v -0.086960 1.729159 -0.267087 +v -0.930398 1.202642 0.112168 +v -0.922377 1.248852 0.407866 +v -0.897713 1.290486 0.430230 +v -0.544734 0.459375 0.236126 +v -0.628296 1.518948 -0.092373 +v 0.185057 0.382941 -0.171365 +v -0.518300 0.485687 0.216470 +v -0.326057 0.612646 -0.154530 +v 0.166386 0.381961 -0.198849 +v 0.139503 0.348800 -0.186129 +v 0.008800 0.992349 -0.243557 +v 0.069832 0.977301 -0.248003 +v 0.026040 0.969427 -0.284070 +v 0.378147 0.796982 -0.132896 +v 0.383020 0.845491 -0.144788 +v 0.365239 0.819917 -0.162296 +v 0.326004 0.537075 -0.110061 +v 0.357067 0.560830 -0.089993 +v 0.332056 0.510206 -0.072382 +v 0.120092 0.359619 -0.217357 +v -0.867230 0.999172 0.035537 +v 0.373786 0.730934 -0.126354 +v 0.349818 0.677408 -0.156832 +v 0.335054 0.728099 -0.170348 +v -0.264167 0.446740 -0.282097 +v -0.851063 0.851766 0.256795 +v -0.883665 1.136186 0.058228 +v -0.526254 0.504346 0.290468 +v -0.880011 0.866264 0.154667 +v 0.410733 0.887243 -0.097879 +v 0.386482 0.901533 -0.125497 +v -0.066397 1.022221 -0.235193 +v -0.085370 0.999212 -0.243511 +v -0.124299 1.028601 -0.238225 +v -0.612980 0.339002 -0.093217 +v -0.637159 0.337769 -0.080066 +v 0.281477 0.787854 -0.224324 +v 0.306849 0.757269 -0.207781 +v 0.389971 0.970882 -0.077799 +v 0.354074 0.981888 -0.120090 +v 0.366840 1.009957 -0.098486 +v -0.529098 0.570431 0.209884 +v -0.895779 1.207831 0.035229 +v -0.901995 1.165751 0.056755 +v 0.355381 0.760630 -0.144347 +v -0.874265 0.954695 0.040313 +v 0.347459 0.632613 -0.146467 +v 0.381111 0.648118 -0.111420 +v 0.249907 0.658973 -0.235683 +v 0.292165 0.678503 -0.204186 +v 0.282048 0.643913 -0.206980 +v -0.908217 1.227690 0.060999 +v -0.417355 1.268760 -0.041742 +v -0.421215 1.282511 0.010752 +v -0.370538 1.271509 0.003548 +v -0.043822 1.264075 -0.069495 +v 0.035641 1.276488 -0.044672 +v -0.023850 1.229053 -0.103824 +v -0.114525 1.722063 -0.268450 +v -0.109067 1.764930 -0.292463 +v -0.117034 0.973557 0.515921 +v 0.202503 0.370332 0.393272 +v 0.236821 0.397625 0.371488 +v -0.896073 1.397110 0.293086 +v -0.896411 1.384192 0.341418 +v 0.370272 0.939496 -0.116740 +v 0.297400 0.525384 -0.162249 +v 0.297407 0.503247 -0.139909 +v -0.907585 1.422337 0.260082 +v 0.172098 0.352594 -0.146852 +v -0.714337 0.775735 0.380608 +v -0.655454 0.744304 0.391681 +v -0.177662 1.857234 -0.230493 +v -0.248333 0.958580 -0.251621 +v -0.190475 0.965621 -0.275799 +v -0.257811 0.937782 -0.283882 +v 0.402816 0.726371 -0.092881 +v 0.399096 0.681717 -0.095698 +v -0.797906 1.035166 -0.066275 +v -0.746838 1.078610 -0.090477 +v 0.407062 0.644753 -0.055920 +v 0.359151 0.599164 -0.119665 +v 0.284549 0.480674 -0.128472 +v 0.292078 0.474502 -0.085082 +v -0.112434 1.645751 -0.182408 +v -0.776935 1.736797 -0.414786 +v -0.786996 1.731391 -0.427204 +v 0.388294 0.598398 -0.064252 +v 0.166885 0.369766 0.430006 +v 0.222916 0.370533 0.331010 +v 0.191282 0.356406 0.366423 +v -0.610517 0.443922 0.124219 +v -0.578530 0.464445 0.110626 +v -0.505952 0.499233 0.191741 +v -0.053486 0.338290 -0.226004 +v 0.014086 0.347820 -0.232652 +v 0.064844 0.342930 -0.208549 +v 0.388386 0.578083 -0.052585 +v 0.384634 0.549348 -0.061822 +v -0.392070 0.815364 -0.205710 +v -0.357498 0.772484 -0.193740 +v -0.654728 0.456276 0.045575 +v -0.622494 0.465401 0.071904 +v -0.577131 0.487178 0.072765 +v -0.911608 1.414436 0.156739 +v -0.713028 1.132536 0.494445 +v -0.651714 0.372895 0.259538 +v -0.644158 0.412838 0.282435 +v -0.630870 0.396142 0.251816 +v -0.197067 0.929173 -0.346369 +v -0.187722 0.898380 -0.369917 +v -0.232857 0.894680 -0.360272 +v 0.344002 1.050300 -0.102249 +v 0.330813 1.027338 -0.127872 +v -0.780220 0.709952 0.213222 +v 0.434225 0.918604 0.245385 +v -0.800504 1.167040 0.487625 +v -0.788491 1.186737 0.506229 +v -0.157822 1.007296 -0.237241 +v -0.058904 0.347906 -0.242245 +v -0.031837 0.362299 0.478731 +v 0.232458 0.627925 -0.250480 +v -0.381195 0.641623 -0.138291 +v -0.415582 0.697740 -0.167741 +v 0.249890 0.381046 0.294296 +v -0.171422 0.980575 -0.249243 +v -0.626819 1.674409 -0.457139 +v -0.519040 0.461001 0.194213 +v -0.523898 0.454491 0.176863 +v 0.417725 0.695680 -0.061596 +v -0.491046 1.366688 0.193141 +v -0.100909 0.982297 -0.277313 +v -0.030870 0.984025 -0.274032 +v -0.082085 0.967774 -0.308098 +v 0.203568 0.436624 -0.204563 +v 0.529064 0.652305 -0.005111 +v 0.531241 0.590124 -0.028854 +v 0.500008 0.616121 -0.034650 +v 0.319093 0.646571 -0.184734 +v -0.894308 1.473055 0.276950 +v 0.367300 1.111676 0.038671 +v 0.172528 0.443356 -0.230672 +v -0.085065 0.390290 -0.130008 +v -0.192888 0.387626 -0.142026 +v -0.111132 0.382903 -0.156464 +v -0.393432 0.354402 0.424926 +v -0.407604 0.346682 0.404925 +v -0.862271 1.146684 0.022102 +v -0.424660 0.341891 -0.272606 +v -0.389211 0.337674 -0.290426 +v -0.732425 1.523133 -0.357035 +v -0.740844 1.498774 -0.326100 +v -0.838907 0.807895 0.022952 +v -0.358749 0.347760 -0.308452 +v 0.413188 0.994967 0.242758 +v 0.038249 0.361292 -0.238781 +v -0.533420 1.440120 0.242614 +v 0.022544 0.364115 -0.147840 +v 0.082741 0.356452 -0.126487 +v 0.044523 0.377052 -0.129576 +v -0.624253 0.418857 0.146468 +v -0.017359 0.922442 -0.343104 +v -0.064120 0.928762 -0.348176 +v -0.008245 0.951651 -0.320563 +v 0.420807 0.634806 -0.025405 +v 0.443265 0.908181 0.220975 +v 0.541142 0.477731 0.174840 +v -0.387911 0.852327 -0.219176 +v -0.354702 0.801961 -0.223259 +v -0.521159 1.417991 0.205103 +v -0.514927 1.379639 0.236622 +v -0.815428 0.779507 0.267273 +v -0.835398 0.811696 0.270141 +v -0.817395 0.768613 0.233136 +v -0.419336 0.884634 -0.221263 +v -0.365534 0.853162 -0.225762 +v 0.526631 0.476736 0.212013 +v -0.259640 0.334870 -0.263211 +v -0.332411 0.335788 -0.267194 +v -0.331644 0.336065 -0.297219 +v 0.191201 0.471678 -0.221147 +v -0.635418 1.633211 -0.259130 +v -0.347079 0.840359 -0.243022 +v -0.681924 1.743983 -0.453658 +v -0.641242 1.795363 -0.587304 +v -0.647938 1.788528 -0.558832 +v -0.647604 1.531159 -0.020371 +v -0.726184 1.436813 -0.109871 +v -0.765956 1.775323 -0.471180 +v -0.453345 1.289149 0.015819 +v -0.450775 1.312444 0.111458 +v 0.568476 0.720172 0.171394 +v 0.543594 0.714673 0.213813 +v -0.730191 1.560210 0.224194 +v -0.725055 1.545953 0.295889 +v -0.259196 1.827283 -0.135411 +v -0.620994 1.540670 0.308374 +v -0.678186 1.545435 0.302337 +v 0.558885 0.725793 0.106697 +v 0.549194 0.731616 0.152236 +v 0.540165 0.728838 0.186780 +v 0.507817 0.721552 0.206802 +v -0.340229 1.759708 -0.037271 +v 0.515371 0.734967 0.126987 +v 0.505228 0.733979 0.161669 +v 0.517462 0.728972 0.090648 +v 0.482069 0.726986 0.169946 +v -0.341511 1.744280 -0.133125 +v 0.474469 0.736914 0.124300 +v -0.327157 1.089663 -0.189414 +v -0.621162 1.560079 0.180344 +v -0.318288 1.263911 0.100134 +v -0.609232 0.386218 0.224689 +v -0.849704 1.532231 0.126545 +v -0.611210 1.556966 0.225171 +v -0.657397 1.556534 0.260176 +v -0.400811 1.262838 0.196073 +v -0.353017 1.254781 -0.031543 +v -0.337615 1.261788 0.017133 +v -0.305435 1.247789 0.010984 +v -0.707315 1.556996 0.069058 +v -0.437932 1.695551 -0.073026 +v -0.660960 1.553253 0.071562 +v -0.677805 1.561445 0.142763 +v -0.616417 1.558204 0.110998 +v -0.362236 1.277752 0.098502 +v -0.429306 1.292844 0.092701 +v -0.375385 1.274413 0.153209 +v -0.666052 1.647738 -0.206707 +v -0.376065 1.242260 0.243136 +v -0.925950 1.194383 0.268030 +v -0.635381 0.435240 0.379740 +v -0.512433 0.642392 0.342581 +v -0.513079 0.605217 0.314349 +v -0.753909 1.795282 -0.524020 +v -0.775872 1.771788 -0.502211 +v -0.430456 1.278512 0.168423 +v -0.442863 1.260663 0.207952 +v -0.695406 1.530853 0.338657 +v -0.595824 1.562334 0.079210 +v -0.650474 1.799915 -0.597586 +v -0.685312 1.563004 0.209977 +v -0.653203 1.539032 0.009139 +v -0.020517 1.009347 0.456259 +v -0.755369 1.597706 -0.104386 +v -0.631173 1.542544 0.029731 +v -0.275970 1.697982 -0.181704 +v -0.891465 1.365050 0.259528 +v -0.702223 1.514352 0.367189 +v -0.604836 1.556798 0.043344 +v -0.645587 0.396399 0.394115 +v -0.654885 0.409378 0.353155 +v -0.668041 0.373777 0.332963 +v -0.254117 1.247253 0.001289 +v -0.391896 1.282819 0.050347 +v -0.647926 0.417245 0.316169 +v 0.303004 1.155365 0.286850 +v -0.258099 0.888896 -0.350822 +v -0.269641 0.845128 -0.363617 +v -0.291645 0.853934 -0.336668 +v 0.361020 1.126610 0.104918 +v -0.862527 1.010685 0.254138 +v -0.874055 1.020521 0.220204 +v 0.335683 1.152372 0.217984 +v -0.791299 1.673657 -0.355062 +v 0.336635 1.157421 0.171813 +v -0.433098 0.556568 -0.114021 +v -0.413623 0.616373 -0.128138 +v -0.575206 1.587760 0.041621 +v 0.343259 1.119331 -0.022406 +v 0.265792 1.170244 0.308680 +v 0.261481 1.201473 0.273080 +v -0.671565 0.419729 0.102409 +v -0.673065 0.441768 0.075958 +v 0.148016 0.990409 -0.228429 +v 0.135335 1.025539 -0.215793 +v 0.186607 1.003078 -0.221273 +v 0.328773 1.169146 0.092958 +v 0.304446 1.188644 0.208218 +v 0.286757 1.195960 0.245459 +v 0.328199 1.165563 0.044459 +v 0.292531 1.205770 0.122993 +v 0.264881 1.223029 0.203981 +v 0.308357 1.155423 -0.031785 +v 0.315019 1.172517 0.016855 +v -0.852698 1.026779 0.013936 +v -0.677877 1.808889 -0.581910 +v -0.681362 1.800611 -0.588160 +v 0.291306 1.202744 0.061118 +v 0.233371 1.235345 0.248742 +v -0.472901 1.305535 0.016909 +v -0.910787 1.150604 0.401418 +v 0.203588 1.244875 0.259064 +v -0.021514 0.994374 0.498498 +v 0.253435 1.237475 0.099819 +v 0.240003 1.246876 0.155180 +v 0.215035 1.256399 0.212526 +v 0.168311 1.248715 0.284256 +v 0.257259 1.212270 -0.000361 +v 0.242466 1.237776 0.048765 +v 0.190122 1.273620 0.177866 +v 0.169816 1.271500 0.229315 +v 0.210698 1.249776 0.010998 +v -0.417718 1.039671 -0.208329 +v -0.851489 1.396552 0.024809 +v -0.324919 0.571963 -0.121047 +v -0.341082 0.614666 -0.130531 +v -0.572196 0.570005 0.049176 +v -0.231229 0.945159 0.473589 +v -0.651466 0.359456 0.397751 +v -0.785977 1.744157 -0.466076 +v -0.554366 0.594202 0.230190 +v -0.581676 0.599852 0.226061 +v -0.182239 0.974946 0.468480 +v -0.323321 0.486728 0.425240 +v -0.344539 0.445640 0.454230 +v -0.320436 0.504618 0.393415 +v -0.291748 0.522645 0.376373 +v -0.721450 0.915564 0.414948 +v -0.517058 0.524708 -0.074047 +v -0.464712 0.513043 -0.098300 +v -0.390882 1.687202 -0.119247 +v -0.203215 0.939996 0.515886 +v -0.262732 0.776312 0.483562 +v -0.239444 0.788001 0.535347 +v -0.272291 0.879915 0.479097 +v -0.581052 0.664660 -0.100443 +v -0.274126 0.732694 0.426414 +v -0.241876 0.722691 0.476811 +v -0.497634 0.562412 0.336243 +v -0.254392 0.906779 0.488523 +v -0.565721 1.248028 -0.071886 +v -0.216927 0.382660 0.045101 +v -0.277909 0.380629 0.079376 +v -0.320742 0.383234 -0.004211 +v -0.305578 0.886259 -0.275507 +v -0.228516 0.906350 0.522805 +v -0.741135 0.994425 0.383377 +v -0.202684 0.622668 0.482121 +v -0.375015 0.427367 0.429884 +v -0.698556 1.002789 -0.148478 +v -0.239883 0.859956 0.537164 +v -0.485800 1.668921 -0.025256 +v -0.214811 0.741945 0.528577 +v -0.773783 1.576427 -0.141336 +v -0.764239 1.573628 -0.090354 +v -0.838825 1.333146 0.491136 +v -0.375011 0.402219 0.442966 +v -0.249820 0.817776 0.534211 +v -0.640672 0.901722 -0.188555 +v -0.641148 0.955099 -0.181146 +v -0.609599 0.941730 -0.190157 +v -0.694810 0.856565 -0.171984 +v -0.692014 0.930392 -0.164861 +v -0.670692 0.911446 -0.174259 +v -0.550472 0.527676 -0.039461 +v -0.526264 0.600438 -0.089567 +v -0.529785 0.595538 0.262119 +v -0.560014 0.618307 0.279312 +v -0.343340 0.409236 0.484258 +v -0.518874 0.533247 0.287056 +v -0.314878 0.469302 0.452532 +v -0.547073 0.634616 0.316706 +v -0.200181 0.675693 0.515654 +v -0.769873 1.536937 -0.022971 +v -0.838375 1.392786 0.448939 +v -0.822277 1.451377 0.406001 +v 0.256203 1.188072 -0.050331 +v -0.824039 1.218656 0.493650 +v -0.838036 1.256110 0.504405 +v -0.863891 1.216847 0.484125 +v -0.663920 0.377123 0.296220 +v -0.835778 1.205262 0.491775 +v -0.841508 1.295501 0.504837 +v -0.861536 1.273561 0.485640 +v -0.345026 0.761300 -0.223731 +v -0.776450 0.822149 0.357977 +v -0.764407 0.775111 0.337483 +v -0.712065 0.386086 0.007722 +v -0.724740 0.362559 0.015533 +v 0.313523 0.426493 -0.046745 +v 0.353499 0.412571 -0.028075 +v -0.772160 0.855949 0.374208 +v -0.851760 1.170681 0.481394 +v -0.866051 1.322681 0.467830 +v -0.750974 0.900736 0.395810 +v -0.637573 1.025114 -0.174844 +v -0.657286 1.070982 -0.143177 +v -0.605108 1.074845 -0.170423 +v -0.800698 0.905861 0.345931 +v -0.887637 1.194494 0.465601 +v -0.827110 1.164897 0.485186 +v -0.666429 1.604088 -0.568427 +v -0.559282 0.359173 0.463761 +v -0.237300 1.018616 -0.238364 +v -0.217305 0.984110 -0.243068 +v -0.716936 0.394610 0.060145 +v -0.696372 0.418813 0.031826 +v -0.825065 1.276549 -0.046796 +v -0.834485 1.339330 -0.016873 +v -0.806511 1.311985 -0.044398 +v -0.869906 1.381233 0.423166 +v 0.198385 0.965189 -0.227859 +v 0.239112 0.980217 -0.208073 +v 0.230880 0.939987 -0.222107 +v -0.658857 0.350251 0.294165 +v -0.532884 0.519258 0.117304 +v -0.797393 1.360685 -0.041482 +v -0.717522 0.367894 0.086967 +v -0.711659 0.393663 0.081142 +v -0.699973 0.420731 0.066898 +v -0.882521 1.269273 0.461413 +v -0.338970 0.570253 -0.110476 +v -0.328755 0.516776 -0.108886 +v -0.653521 0.992946 -0.168201 +v -0.667270 0.358958 0.338494 +v -0.789083 0.948309 0.354355 +v -0.652971 0.347790 0.337443 +v -0.869704 0.889121 0.248799 +v -0.863471 0.917221 0.268111 +v -0.858563 0.970254 0.274150 +v -0.690003 0.384677 0.107689 +v -0.569964 1.574171 0.006025 +v -0.692090 0.354548 0.120421 +v -0.838122 0.863377 0.292233 +v -0.837988 1.029069 0.280383 +v -0.670064 0.632929 -0.017494 +v -0.757294 1.035403 0.360710 +v -0.672534 0.381422 0.135340 +v -0.834181 0.941274 0.308985 +v -0.428190 1.622018 -0.103375 +v -0.576769 0.862583 -0.210983 +v -0.555226 0.819276 -0.213538 +v -0.803793 0.978007 0.336458 +v 0.017324 0.344597 -0.166079 +v -0.422768 0.949826 -0.225624 +v 0.214436 1.227383 -0.029317 +v -0.859860 1.467090 0.348271 +v -0.641608 0.359008 0.176876 +v -0.812214 0.810032 0.312559 +v -0.817040 1.016723 0.309397 +v -0.186857 1.868963 -0.202487 +v -0.536442 0.493582 0.122019 +v -0.859188 1.426341 0.398498 +v -0.637546 0.382501 0.165935 +v -0.810338 0.846982 0.331064 +v -0.791267 1.061988 0.320507 +v -0.772089 1.071589 0.347383 +v -0.027873 1.057753 -0.224590 +v -0.032078 1.096210 -0.215238 +v 0.025822 1.074758 -0.206060 +v -0.743148 1.376174 -0.066699 +v -0.785789 1.405013 -0.046031 +v -0.758293 1.424461 -0.058090 +v -0.790026 0.763393 0.292481 +v -0.317141 0.351115 -0.306590 +v -0.265689 0.346958 -0.291137 +v -0.063935 1.052447 -0.228419 +v -0.911321 1.228210 0.441152 +v -0.455306 0.985109 -0.217295 +v -0.518153 1.639258 0.017489 +v -0.289311 0.792476 -0.350498 +v -0.260820 0.761913 -0.367802 +v -0.261201 0.711775 -0.354515 +v -0.793348 1.256065 -0.061176 +v 0.095887 0.342072 -0.154240 +v 0.062813 0.341658 -0.187642 +v -0.627867 1.127419 -0.136054 +v -0.777215 1.135589 0.481560 +v 0.018527 1.130336 -0.197943 +v -0.885635 1.162453 0.453929 +v -0.272332 0.805710 -0.366207 +v 0.289903 0.446979 -0.061863 +v -0.634289 1.718539 -0.614121 +v 0.163870 1.140235 -0.154969 +v 0.217130 1.095634 -0.150811 +v 0.167326 1.099123 -0.170200 +v -0.083563 1.137360 -0.182398 +v -0.123544 1.155677 -0.164869 +v -0.066878 1.174721 -0.153593 +v -0.655936 1.766571 -0.605047 +v -0.053608 1.128940 -0.196133 +v -0.078240 1.092411 -0.221857 +v -0.091087 1.114167 -0.205432 +v 0.072130 1.272196 -0.052073 +v 0.094136 1.212190 -0.129378 +v 0.064155 1.179018 -0.162827 +v 0.044652 1.204404 -0.139314 +v 0.530564 0.697088 0.031292 +v 0.073447 0.945096 -0.296832 +v 0.242497 1.026615 -0.183138 +v 0.287231 0.979432 -0.174973 +v -0.701217 1.688263 -0.511736 +v -0.598312 0.428423 -0.066469 +v -0.740044 1.781852 -0.539163 +v -0.724555 1.761068 -0.535354 +v -0.254456 0.602086 -0.308647 +v -0.220432 0.536120 -0.301356 +v -0.697805 1.593857 -0.494182 +v -0.683826 1.598025 -0.542088 +v -0.745510 1.721874 -0.475510 +v -0.711565 1.633513 -0.453605 +v -0.771531 1.737868 -0.478676 +v -0.735026 1.687194 -0.447918 +v -0.713515 1.572709 -0.421831 +v -0.710573 1.547689 -0.457785 +v -0.742266 1.643701 -0.382403 +v -0.311334 0.496073 -0.194069 +v -0.776967 1.702789 -0.431179 +v -0.790877 1.704449 -0.413731 +v -0.728962 1.583496 -0.341094 +v -0.776772 1.661099 -0.367773 +v -0.735484 1.612082 -0.352884 +v 0.044630 1.242729 -0.094291 +v 0.129339 1.188725 -0.139794 +v 0.116208 1.154897 -0.163857 +v -0.602553 0.447496 -0.041316 +v -0.661224 0.423413 -0.027539 +v -0.718116 1.486132 -0.346395 +v -0.733866 1.546342 -0.299438 +v -0.293311 1.147623 -0.158446 +v -0.337154 1.115157 -0.180784 +v -0.295706 1.171387 -0.136755 +v 0.251308 0.345469 0.110126 +v 0.208979 0.359371 0.087849 +v 0.213247 0.346240 0.056444 +v 0.104736 0.347426 -0.112629 +v 0.119662 0.343354 -0.059571 +v 0.074147 0.346592 -0.030117 +v -0.151658 1.179807 -0.144655 +v -0.125018 1.063441 -0.223602 +v -0.265403 0.650840 -0.316649 +v -0.290875 0.729246 -0.333545 +v -0.309788 0.770209 -0.328165 +v -0.312257 0.804131 -0.321823 +v -0.785778 1.642064 -0.318258 +v 0.347429 0.922741 -0.156546 +v 0.315554 0.924847 -0.182043 +v -0.286807 0.682835 -0.306102 +v -0.311840 0.739895 -0.303399 +v -0.233702 0.933928 -0.320318 +v -0.277084 0.900813 -0.319114 +v -0.307341 0.854276 -0.305067 +v -0.756407 1.593040 -0.269084 +v 0.071346 1.146823 -0.183456 +v 0.105066 1.008770 -0.221095 +v 0.062723 0.999104 -0.222969 +v 0.071030 1.019116 -0.212310 +v -0.303249 0.676947 -0.276549 +v -0.332110 0.768732 -0.277084 +v -0.325906 0.819427 -0.291002 +v -0.786407 1.638724 -0.283878 +v -0.284257 0.621996 -0.279385 +v -0.332587 0.796217 -0.271460 +v -0.742302 1.565268 -0.251671 +v -0.290548 0.610841 -0.249182 +v -0.326066 0.719556 -0.248666 +v -0.782003 1.607321 -0.239997 +v -0.006731 1.011987 -0.228578 +v -0.275459 0.540216 -0.251474 +v -0.310669 0.650589 -0.227511 +v -0.442159 0.361315 -0.242522 +v -0.455329 0.347365 -0.213632 +v -0.422969 0.362919 -0.272536 +v -0.410515 0.415286 -0.240610 +v -0.381503 0.424666 -0.268940 +v -0.296471 0.581043 -0.213113 +v -0.812687 1.087944 0.294407 +v -0.457521 1.634075 -0.081780 +v -0.486400 1.647248 -0.050591 +v -0.760414 1.566307 -0.214205 +v -0.306039 0.380385 -0.301238 +v -0.068478 0.364445 -0.251771 +v 0.032222 0.387084 0.258988 +v 0.052497 0.395071 0.332712 +v -0.026442 0.387271 0.251313 +v -0.759178 1.499769 -0.168420 +v 0.134731 1.242989 -0.068361 +v 0.094116 1.235029 -0.098291 +v -0.449930 0.390170 -0.210978 +v -0.341905 0.475140 -0.223015 +v -0.340162 0.721013 -0.208231 +v -0.345886 0.447450 -0.271229 +v -0.736793 1.478599 -0.202363 +v -0.758047 1.513448 -0.198812 +v -0.749823 1.540779 -0.189744 +v -0.749241 1.527301 -0.193974 +v -0.161317 1.829885 -0.260372 +v -0.184057 1.784306 -0.242196 +v -0.214163 1.797766 -0.217325 +v -0.464626 0.368003 -0.177787 +v -0.148462 0.350709 -0.260719 +v -0.772067 1.563995 -0.189725 +v -0.232988 1.832431 -0.179230 +v -0.440313 0.419491 -0.179940 +v -0.302714 0.521061 -0.176761 +v -0.308094 0.569980 -0.178350 +v -0.568107 0.338739 -0.111663 +v -0.776504 1.565801 -0.165991 +v 0.291027 1.024751 -0.157684 +v 0.319129 0.998701 -0.146210 +v -0.278902 1.044070 -0.228309 +v -0.746100 1.472781 -0.141724 +v -0.451865 0.424534 -0.141936 +v -0.312895 0.552086 -0.143878 +v 0.259415 1.157635 -0.082194 +v 0.266662 1.126861 -0.105095 +v 0.204615 1.151537 -0.131038 +v -0.469123 0.346272 0.397397 +v -0.776188 0.739991 -0.053263 +v -0.742914 0.748084 -0.093538 +v -0.720716 0.715382 -0.074714 +v -0.838178 1.110909 0.285245 +v -0.754277 1.520121 -0.143937 +v -0.469906 0.388924 -0.140169 +v -0.313831 0.517913 -0.138868 +v 0.043714 1.039190 -0.215151 +v -0.104112 0.945923 -0.337848 +v -0.150781 0.938634 -0.343173 +v 0.283222 1.084796 -0.126234 +v 0.253192 1.093173 -0.135796 +v -0.765378 1.534487 -0.128987 +v -0.732631 0.799838 -0.137499 +v -0.769758 0.829359 -0.114506 +v -0.739454 0.843749 -0.151545 +v -0.338324 0.351688 0.469579 +v -0.172244 0.952141 -0.320853 +v -0.327484 1.775987 -0.116274 +v 0.116693 1.272015 -0.031851 +v 0.039735 0.382086 -0.037963 +v 0.023262 0.353482 0.023246 +v -0.008114 0.374242 0.047722 +v -0.764813 1.482741 -0.089376 +v -0.777706 0.878448 -0.116948 +v -0.800436 0.920802 -0.094198 +v -0.760467 0.910372 -0.136431 +v -0.787516 0.952403 -0.106007 +v -0.282124 1.111686 -0.180019 +v -0.769229 1.535139 -0.090785 +v -0.797237 0.842267 -0.087608 +v -0.814149 0.971003 -0.068746 +v -0.758629 1.507130 -0.090209 +v -0.130349 1.100286 -0.201612 +v -0.807283 0.882042 -0.078003 +v -0.261606 1.230999 -0.044735 +v -0.328217 1.230050 -0.059088 +v -0.213995 0.347951 -0.279588 +v -0.249541 0.374411 -0.291527 +v 0.162243 0.864804 -0.289520 +v 0.130970 0.911265 -0.292698 +v 0.167472 0.901140 -0.271272 +v -0.168038 0.397538 -0.275653 +v -0.829428 0.932917 -0.061856 +v 0.158001 1.199656 -0.114156 +v -0.746388 1.439848 -0.071504 +v 0.190766 0.918706 -0.248902 +v 0.226740 0.866061 -0.249255 +v 0.488059 0.684578 0.016953 +v -0.237569 0.385858 -0.110933 +v -0.080981 0.890701 -0.365522 +v -0.771349 1.515123 -0.055823 +v -0.218824 1.108742 -0.196953 +v -0.272540 1.074745 -0.212797 +v -0.792859 0.800488 -0.070125 +v -0.832725 0.894767 -0.056503 +v -0.195235 0.385052 -0.045434 +v -0.175879 1.149132 -0.172050 +v -0.236002 1.151382 -0.155774 +v -0.183207 1.196863 -0.111106 +v 0.074553 1.119679 -0.195542 +v -0.556740 0.569839 -0.033510 +v -0.540665 0.599593 -0.075992 +v -0.749015 0.704193 -0.022854 +v -0.827764 0.834309 -0.043687 +v -0.169704 1.111979 -0.195864 +v -0.773884 1.465643 -0.043543 +v -0.568979 0.496556 -0.015319 +v -0.805760 0.766078 -0.029879 +v -0.823540 0.808763 -0.024039 +v -0.849649 0.899625 -0.030068 +v -0.841668 0.977568 -0.032762 +v -0.809591 1.092667 -0.020190 +v -0.760513 1.110383 -0.062722 +v -0.585159 0.477313 0.002125 +v -0.070761 1.224012 -0.113644 +v -0.669788 0.676390 -0.068094 +v -0.720285 0.670466 -0.007225 +v -0.831094 1.026544 -0.032933 +v -0.812063 1.120509 -0.008830 +v -0.782252 1.496248 -0.025019 +v -0.511214 1.637412 -0.026640 +v -0.632420 0.455497 0.004843 +v -0.544207 0.478365 -0.059187 +v -0.574916 0.595302 -0.010786 +v -0.561479 0.619215 -0.057541 +v -0.790612 0.737243 -0.008452 +v -0.850422 0.838178 -0.000776 +v -0.856130 0.962771 -0.006651 +v -0.807679 1.430140 -0.015313 +v -0.864548 0.869405 0.009167 +v -0.857776 0.917014 -0.000470 +v -0.120830 1.221923 -0.097121 +v -0.303071 0.339954 0.147064 +v -0.540569 1.567160 -0.024866 +v -0.692421 0.414741 0.001929 +v -0.673152 0.440340 0.015742 +v -0.872404 1.196721 -0.001781 +v -0.880646 1.249676 0.005741 +v -0.856321 1.246109 -0.027336 +v -0.864430 1.276744 -0.014864 +v 0.258551 0.896107 -0.227018 +v 0.287911 0.911573 -0.203702 +v -0.800664 1.503965 0.006052 +v -0.820635 0.759937 0.017616 +v 0.309752 1.079025 -0.110584 +v -0.554737 1.605021 0.013764 +v -0.798588 0.727550 0.030420 +v 0.263480 0.845622 -0.231517 +v 0.075447 0.916822 -0.316431 +v 0.117275 0.880108 -0.308601 +v 0.305301 1.122121 -0.081860 +v -0.090179 1.252803 -0.077912 +v -0.196162 1.210920 -0.095488 +v 0.218150 1.177053 -0.100153 +v 0.426353 0.607975 -0.034584 +v 0.184009 1.214551 -0.076804 +v 0.136991 0.939142 -0.264277 +v 0.444085 0.697589 0.009477 +v 0.163635 0.343948 0.022949 +v 0.153228 0.362397 0.036629 +v 0.140143 0.357038 0.038879 +v 0.038149 0.390245 -0.080827 +v -0.013897 0.386514 0.023967 +v 0.179048 1.062771 -0.177292 +v 0.190169 1.040145 -0.193331 +v 0.173729 1.024604 -0.214877 +v -0.210005 1.231364 -0.061190 +v -0.358851 1.204004 -0.106405 +v -0.361250 1.228669 -0.082928 +v 0.457694 0.646288 -0.012166 +v -0.049613 0.393649 0.367022 +v -0.021999 1.121588 -0.196586 +v 0.459973 0.698144 0.030143 +v 0.461340 0.592788 -0.047770 +v -0.352833 0.341798 0.227449 +v -0.162404 1.251218 -0.036499 +v -0.619936 1.502806 -0.016297 +v -0.611140 1.530521 0.009999 +v -0.346923 0.338287 0.124386 +v -0.373144 0.336330 0.045725 +v -0.594667 1.474396 -0.018885 +v -0.586981 1.513732 -0.006580 +v -0.254259 0.414210 -0.292048 +v -0.277621 1.206854 -0.090153 +v -0.121305 1.257257 -0.052008 +v 0.396935 0.456586 -0.045274 +v -0.569923 1.431186 -0.022403 +v -0.561792 1.377441 -0.040674 +v -0.568960 1.339874 -0.056270 +v -0.500957 1.099092 -0.185045 +v -0.478594 1.116273 -0.174821 +v -0.455901 1.085383 -0.187967 +v -0.003084 0.354625 0.082607 +v -0.601273 1.204139 -0.093791 +v -0.543883 1.340492 -0.039920 +v -0.336235 1.184043 -0.119275 +v 0.125178 1.047538 -0.199159 +v -0.535901 1.243745 -0.073470 +v -0.523144 1.215965 -0.107980 +v -0.555781 1.156769 -0.146460 +v -0.604585 1.175565 -0.113546 +v -0.132803 0.376996 -0.263918 +v 0.024960 0.898576 -0.336284 +v -0.521243 1.292983 -0.041187 +v -0.507929 1.271649 -0.048183 +v -0.565443 1.285094 -0.062014 +v -0.489821 1.298065 -0.013229 +v -0.499068 1.178833 -0.144025 +v -0.480697 1.249303 -0.084076 +v -0.489844 1.148052 -0.159667 +v -0.477436 1.206443 -0.128130 +v -0.450826 1.221845 -0.115694 +v -0.464595 1.272395 -0.048843 +v -0.446974 1.179154 -0.147258 +v -0.421481 1.240963 -0.095602 +v -0.424595 1.139248 -0.161880 +v -0.416817 1.257511 -0.070193 +v -0.758241 1.079490 0.371288 +v 0.038064 1.094433 -0.202038 +v -0.402517 1.182753 -0.136741 +v 0.113474 0.362130 0.446523 +v -0.398428 1.215611 -0.115703 +v -0.382257 1.246552 -0.073257 +v 0.500065 0.580958 -0.046212 +v -0.366651 0.353042 0.230320 +v 0.099445 1.091972 -0.194728 +v -0.372182 1.159424 -0.151730 +v -0.374030 1.115077 -0.182433 +v 0.237060 0.802404 -0.254501 +v -0.382796 0.354290 0.243806 +v -0.770256 1.139676 -0.046168 +v -0.709172 1.075485 -0.114966 +v -0.737904 1.201666 -0.078851 +v -0.759961 1.171413 -0.065577 +v -0.752726 1.268010 -0.080241 +v -0.768901 1.304191 -0.069570 +v 0.475747 0.529436 -0.051300 +v -0.523252 1.061481 -0.192712 +v -0.551398 1.105160 -0.176727 +v 0.444732 0.532930 -0.063328 +v 0.443313 0.558180 -0.060363 +v 0.436732 0.501622 -0.059843 +v -0.479574 0.725430 -0.161070 +v 0.223400 0.584922 -0.260141 +v -0.679148 0.801363 -0.171282 +v -0.448539 1.574603 -0.086731 +v -0.590420 0.990322 -0.192229 +v -0.696084 0.723229 -0.109344 +v -0.643926 0.731163 -0.153353 +v -0.644807 0.701874 -0.122617 +v -0.503424 1.554620 -0.051927 +v -0.701776 0.756633 -0.138392 +v 0.368909 0.473532 -0.061057 +v -0.578468 1.043350 -0.185257 +v -0.548133 0.981025 -0.214254 +v -0.582324 0.956904 -0.206160 +v 0.386637 0.516967 -0.066910 +v -0.579895 0.740179 -0.175223 +v -0.642669 0.335625 -0.051253 +v -0.721462 1.348643 -0.077592 +v -0.625818 0.863945 -0.191693 +v -0.552653 1.021668 -0.198971 +v -0.545763 0.915630 -0.220987 +v -0.582656 0.909264 -0.209487 +v -0.442311 0.776641 -0.190266 +v -0.539945 0.646387 -0.093255 +v 0.336274 0.487177 -0.063905 +v -0.638362 0.817046 -0.189088 +v -0.489447 0.790864 -0.195757 +v -0.461242 1.050637 -0.204576 +v -0.506479 0.823094 -0.213659 +v -0.456432 1.546695 -0.072969 +v -0.448642 0.819979 -0.204735 +v -0.638523 0.655723 -0.069393 +v -0.489529 0.562811 -0.102209 +v -0.466503 0.598410 -0.121358 +v -0.484515 0.647941 -0.130299 +v -0.450084 0.627239 -0.133904 +v -0.418955 0.336683 0.269400 +v -0.603554 0.797666 -0.193755 +v -0.450788 0.872611 -0.218655 +v -0.443540 0.733722 -0.178744 +v 0.133599 0.393774 -0.224963 +v -0.034356 0.870179 -0.364610 +v -0.656099 0.758600 -0.167500 +v 0.228320 0.670826 -0.262975 +v 0.221044 0.726926 -0.269001 +v -0.509110 1.007457 -0.216194 +v 0.202845 0.513492 -0.248954 +v -0.457626 0.694453 -0.159288 +v 0.193050 0.790179 -0.277440 +v 0.199725 0.544097 -0.271082 +v 0.195204 0.620648 -0.272925 +v 0.196187 0.670074 -0.283561 +v 0.177581 0.701385 -0.294047 +v 0.157197 0.737564 -0.297478 +v 0.156783 0.511693 -0.263978 +v 0.151103 0.598198 -0.286457 +v 0.168421 0.555557 -0.282846 +v -0.211004 0.865877 -0.378490 +v 0.145191 0.645956 -0.298557 +v 0.155324 0.765870 -0.296069 +v -0.888278 1.135917 0.238737 +v 0.139640 0.455792 -0.247065 +v 0.122541 0.834567 -0.307716 +v -0.014089 0.361931 0.129446 +v -0.036954 0.381728 0.130468 +v 0.133761 0.486303 -0.265515 +v 0.107110 0.546876 -0.297675 +v 0.115741 0.748606 -0.313838 +v 0.114713 0.675814 -0.309012 +v 0.122752 0.699340 -0.315531 +v 0.106962 0.798892 -0.320096 +v 0.106377 0.441616 -0.249262 +v 0.081686 0.450530 -0.251787 +v 0.101498 0.492585 -0.277506 +v 0.103124 0.575865 -0.299952 +v 0.076270 0.620983 -0.311358 +v 0.097413 0.631814 -0.311414 +v 0.051821 0.415363 -0.240657 +v 0.062881 0.654164 -0.325630 +v 0.043919 0.386744 -0.241703 +v 0.054265 0.682480 -0.327305 +v 0.064980 0.707919 -0.335253 +v 0.087503 0.743016 -0.333982 +v 0.073335 0.852700 -0.328294 +v 0.066510 0.881445 -0.329458 +v 0.059436 0.509767 -0.291194 +v 0.053975 0.583826 -0.309038 +v 0.076016 0.794359 -0.337145 +v 0.068342 0.550102 -0.305611 +v 0.048214 0.737640 -0.345524 +v 0.049502 0.780273 -0.344097 +v 0.043843 0.458067 -0.267890 +v 0.037309 0.481280 -0.290260 +v 0.033102 0.604568 -0.324811 +v 0.018550 0.846928 -0.348385 +v 0.007583 0.704345 -0.344625 +v 0.012868 0.503837 -0.303574 +v 0.005928 0.528680 -0.305138 +v 0.021425 0.555028 -0.313344 +v -0.002283 0.433949 -0.251244 +v -0.002086 0.789414 -0.357821 +v -0.009629 0.453782 -0.273083 +v -0.011827 0.594924 -0.333609 +v -0.008661 0.645596 -0.344909 +v -0.045918 0.384046 -0.254129 +v -0.017033 0.478192 -0.299289 +v -0.022529 0.739213 -0.358872 +v -0.004271 0.829474 -0.363806 +v -0.044084 0.666192 -0.348702 +v -0.079469 0.414899 -0.259113 +v -0.036481 0.518690 -0.314579 +v -0.044102 0.827945 -0.374672 +v -0.052326 0.556890 -0.328402 +v -0.053433 0.782646 -0.374769 +v -0.059251 0.695156 -0.359335 +v -0.081088 0.434391 -0.261401 +v -0.087947 0.470569 -0.298816 +v -0.061353 0.602568 -0.346958 +v -0.073835 0.747996 -0.372238 +v -0.200863 0.380645 -0.172208 +v -0.082506 0.451487 -0.284411 +v -0.081798 0.498458 -0.310714 +v -0.085264 0.640017 -0.358505 +v -0.094246 0.553992 -0.336540 +v -0.106036 0.536029 -0.334033 +v -0.092015 0.595101 -0.344371 +v -0.085992 0.793387 -0.379052 +v -0.105386 0.679992 -0.365170 +v -0.100020 0.726715 -0.376614 +v -0.147316 0.776408 -0.384907 +v -0.112040 0.827133 -0.384896 +v -0.137538 0.518651 -0.322435 +v -0.123182 0.593964 -0.352685 +v -0.132360 0.692928 -0.379175 +v -0.265805 0.377426 0.157053 +v -0.149815 0.358782 -0.179924 +v -0.136911 1.791471 -0.281264 +v -0.173624 0.432374 -0.276652 +v -0.157484 0.450439 -0.278778 +v -0.144669 0.631360 -0.368659 +v -0.309847 0.381919 0.323901 +v -0.160188 0.742888 -0.388644 +v -0.158584 0.811656 -0.391856 +v -0.670783 0.338401 -0.061688 +v -0.171843 0.482105 -0.297419 +v -0.168119 0.612752 -0.359293 +v 0.388831 0.410330 0.249766 +v -0.179761 0.706138 -0.384439 +v 0.094293 0.360304 0.045275 +v 0.039678 0.342002 0.049755 +v 0.095485 0.342326 0.017162 +v -0.193022 0.582248 -0.339197 +v -0.177394 0.662608 -0.376573 +v -0.185021 0.833439 -0.390107 +v -0.211629 1.749185 -0.219771 +v -0.627918 0.345968 0.235056 +v -0.643003 0.350864 0.242721 +v -0.202253 0.770952 -0.390443 +v -0.212008 0.466571 -0.279513 +v -0.219113 0.671448 -0.365357 +v -0.696855 0.344788 0.097984 +v -0.230360 0.727785 -0.380726 +v -0.232001 0.765685 -0.383865 +v -0.231815 0.816870 -0.383291 +v -0.804691 1.135796 0.466435 +v -0.597122 0.631653 0.287892 +v 0.143227 0.344255 0.215932 +v 0.154490 0.348524 0.369849 +v 0.131970 0.348358 0.316310 +v 0.085288 0.348880 0.362651 +v 0.122242 0.351775 0.426206 +v -0.164714 0.348128 0.436847 +v 0.032907 0.358335 0.460246 +v 0.049172 0.339971 0.091666 +v 0.031492 0.341253 0.117622 +v -0.180315 0.348600 0.492648 +v -0.286576 0.350834 0.505494 +v 0.222529 0.365833 0.139797 +v 0.214998 0.358071 0.181694 +v 0.174901 0.346463 0.220409 +v 0.448765 0.412310 0.160083 +v -0.014104 0.369999 0.169820 +v 0.017024 0.363109 0.211796 +v -0.010974 0.381478 0.204270 +v 0.028888 0.346363 0.188498 +v 0.009171 0.348034 0.156347 +v 0.412613 0.405851 0.207519 +v -0.263231 0.346580 0.434735 +v -0.095064 0.383526 0.155707 +v -0.023474 0.359031 -0.159297 +v 0.239308 0.348167 0.177392 +v 0.100874 0.370477 0.308225 +v -0.081306 0.350083 0.475024 +v -0.028262 0.348853 0.456114 +v 0.200812 0.351727 0.280188 +v 0.132792 0.343795 0.214237 +v -0.642122 0.349926 0.394019 +v 0.064553 0.381652 -0.101649 +v 0.298590 0.349801 0.098349 +v -0.031105 0.389462 -0.027794 +v -0.094309 0.388877 -0.074849 +v 0.089808 0.376394 0.339008 +v 0.083833 0.347487 0.240573 +v -0.799405 1.091668 0.341198 +v -0.852296 1.120071 0.304170 +v -0.574341 0.576835 0.087260 +v 0.164393 0.356351 0.412810 +v 0.049318 0.348148 0.434621 +v 0.062194 0.351341 0.065493 +v -0.889795 1.145087 0.284460 +v 0.323692 0.358160 0.070246 +v 0.282486 0.350464 0.160167 +v 0.090016 0.368909 0.284822 +v 0.235895 0.358906 0.253377 +v -0.898226 1.138720 0.328453 +v -0.357116 0.358916 0.155029 +v -0.902540 1.136631 0.377202 +v 0.075208 0.367334 -0.067614 +v -0.856447 1.113172 0.342348 +v 0.158705 0.344162 -0.029666 +v 0.140554 0.344834 -0.144957 +v -0.877735 1.118141 0.371443 +v -0.011390 0.391768 -0.103814 +v -0.873599 1.124831 0.420495 +v -0.024719 0.384088 -0.141590 +v -0.648113 0.345306 0.155084 +v -0.898039 1.149811 0.427717 +v -0.847470 1.107835 0.394884 +v -0.112898 0.395292 0.388441 +v 0.334758 0.364473 0.162670 +v -0.020406 0.340539 -0.193311 +v -0.808945 1.096722 0.379102 +v -0.827619 1.116234 0.442215 +v -0.843413 1.138801 0.465135 +v 0.069064 0.390043 0.295485 +v 0.044817 0.371178 0.247553 +v -0.784498 1.098883 0.425179 +v 0.298685 0.362488 0.198722 +v -0.233200 0.391695 0.384733 +v -0.759508 0.681706 0.181180 +v -0.695388 0.630748 0.035758 +v -0.770396 0.719670 0.264051 +v -0.711130 0.627515 0.087996 +v -0.728014 0.643826 0.120891 +v -0.727901 0.643999 0.152060 +v -0.751653 1.115428 0.467072 +v 0.066606 0.352047 0.243159 +v -0.729164 0.650574 0.187946 +v -0.717221 0.670230 0.249598 +v -0.741076 0.695860 0.272644 +v -0.720361 1.110792 0.453614 +v -0.644798 0.606515 0.042343 +v -0.685435 0.610905 0.105578 +v -0.703258 0.633678 0.198092 +v -0.743628 0.724370 0.314301 +v -0.590022 0.592346 0.026141 +v -0.690662 0.337176 -0.001976 +v -0.685112 0.612146 0.153541 +v -0.612418 0.590074 0.080917 +v -0.645612 0.594841 0.130617 +v -0.666333 0.610017 0.181012 +v -0.696555 0.687284 0.311279 +v -0.648256 0.335059 0.028223 +v -0.668390 0.621705 0.215769 +v -0.708595 0.715101 0.338951 +v -0.713055 0.738990 0.359698 +v -0.673308 0.338464 0.087266 +v -0.670330 0.651460 0.272929 +v 0.081044 0.348429 0.181346 +v -0.559652 0.335299 -0.091246 +v -0.586041 0.334622 -0.002167 +v -0.611494 0.588344 0.165394 +v -0.660807 0.702027 0.355529 +v -0.617774 0.340179 0.169006 +v -0.585814 0.578015 0.134295 +v -0.622257 0.602652 0.204493 +v -0.633664 0.627903 0.256476 +v -0.636650 0.660478 0.318281 +v -0.527301 0.334979 -0.018117 +v -0.576806 0.336227 0.140403 +v -0.582260 0.666073 0.350503 +v -0.605693 0.711545 0.386538 +v -0.475216 0.336227 -0.128046 +v -0.442658 0.336637 -0.219144 +v -0.394819 0.336182 -0.236125 +v -0.450584 0.336005 -0.125275 +v -0.532105 0.335853 0.139870 +v -0.620190 0.343432 0.318833 +v -0.463802 0.336052 -0.008943 +v -0.470597 0.335019 0.035646 +v -0.540190 0.333099 0.158480 +v -0.557406 0.341280 0.266744 +v -0.541854 0.673227 0.369356 +v -0.410915 0.340060 -0.119975 +v -0.513509 0.336457 0.080329 +v -0.456759 0.337036 0.064300 +v -0.471043 0.355495 0.080804 +v -0.578894 0.344196 0.362658 +v -0.612634 0.346904 0.419949 +v -0.351991 0.338352 -0.205083 +v -0.412710 0.338554 -0.018801 +v -0.369705 0.356804 -0.150078 +v -0.396703 0.361740 -0.073398 +v -0.511766 0.680619 0.373983 +v -0.315898 0.355923 -0.192041 +v -0.334073 0.375770 -0.161582 +v -0.380666 0.385186 -0.073080 +v -0.273161 0.339101 -0.213537 +v -0.392220 0.363262 0.107899 +v -0.468708 0.344441 0.305131 +v -0.518477 0.344703 0.346352 +v -0.260754 0.359186 -0.194052 +v -0.307548 0.386398 -0.140508 +v -0.331634 0.381954 -0.005252 +v -0.278515 0.384043 -0.172104 +v -0.386393 0.339373 0.085507 +v -0.550398 0.573097 0.169909 +vn -0.865300 0.093700 -0.492400 +vn -0.900800 -0.025200 -0.433500 +vn -0.862600 -0.125800 -0.489900 +vn -0.974700 -0.212700 -0.068700 +vn -0.924600 -0.267000 -0.271700 +vn -0.957300 0.247700 -0.148800 +vn -0.138100 0.957800 0.252000 +vn -0.088100 0.920300 0.381100 +vn -0.223200 0.877500 0.424500 +vn 0.146500 0.871200 0.468600 +vn 0.335600 0.853700 0.398100 +vn 0.525700 0.705000 0.476000 +vn 0.117100 0.854200 0.506500 +vn -0.203200 0.774500 0.599000 +vn -0.611500 0.510700 0.604300 +vn -0.207300 0.716000 0.666600 +vn -0.538800 0.758300 0.366900 +vn -0.088200 0.993300 0.074500 +vn -0.172900 0.982400 0.070200 +vn -0.091700 0.977100 0.191800 +vn 0.553500 0.804500 0.215600 +vn 0.668000 0.616700 0.416400 +vn 0.769000 0.617100 0.166600 +vn -0.849500 -0.527300 -0.015700 +vn -0.814400 -0.563800 0.137300 +vn -0.942800 -0.327100 -0.063700 +vn 0.350300 -0.902400 -0.250800 +vn 0.034100 -0.918000 -0.395100 +vn 0.609000 -0.763800 -0.213700 +vn -0.915700 -0.398100 0.054200 +vn -0.991000 -0.093000 0.095700 +vn -0.989000 -0.128800 -0.072500 +vn 0.755100 0.589800 0.286100 +vn 0.666600 0.601000 0.440900 +vn 0.831600 0.291500 0.472600 +vn -0.504300 0.861900 0.053200 +vn -0.612200 0.753000 -0.241100 +vn -0.429700 0.848700 0.308300 +vn -0.204800 0.951400 0.229800 +vn -0.764100 -0.634100 -0.118300 +vn -0.868000 -0.441100 -0.227900 +vn 0.255000 0.900000 0.353400 +vn -0.129400 0.918500 0.373600 +vn 0.301200 0.859900 0.412000 +vn 0.800000 0.537700 0.266000 +vn 0.760300 0.542800 0.356800 +vn 0.854700 0.429300 0.291800 +vn 0.755800 0.544700 0.363500 +vn 0.655600 0.698400 0.286900 +vn 0.855800 0.486300 0.176400 +vn -0.354900 0.244300 -0.902400 +vn -0.713800 -0.522100 -0.466800 +vn -0.245800 -0.757000 -0.605400 +vn 0.519700 0.819000 0.243100 +vn 0.257300 0.918500 0.300400 +vn 0.693000 0.687200 0.218100 +vn 0.492200 0.825600 0.275600 +vn 0.304400 0.754600 0.581200 +vn 0.109300 0.870100 0.480500 +vn 0.635900 0.689600 0.346400 +vn -0.150800 0.893000 0.424000 +vn -0.426100 0.399700 -0.811600 +vn -0.166600 0.196100 -0.966300 +vn -0.154800 0.203400 -0.966800 +vn -0.308600 0.909100 0.279500 +vn -0.333600 0.872900 0.356100 +vn -0.319700 0.817900 0.478300 +vn -0.926000 0.377600 0.003800 +vn -0.956400 0.267800 0.116800 +vn -0.927600 0.364100 -0.083200 +vn -0.177700 0.930000 -0.321800 +vn -0.213500 0.966300 -0.143600 +vn -0.132600 0.981400 -0.138800 +vn -0.752500 -0.574200 -0.322500 +vn -0.810600 0.280500 -0.514000 +vn -0.768300 -0.165100 -0.618400 +vn -0.899700 -0.430100 -0.074000 +vn -0.994700 -0.067500 -0.077900 +vn -0.990000 -0.094700 0.104100 +vn -0.865200 -0.437900 0.244000 +vn -0.923900 -0.340800 0.174000 +vn -0.203700 0.978300 -0.036900 +vn -0.142300 0.989000 -0.040200 +vn -0.331600 0.905500 -0.264700 +vn -0.179000 0.626100 -0.758900 +vn -0.320100 0.873500 -0.366600 +vn -0.236400 0.963800 -0.122800 +vn -0.225500 0.973300 -0.042900 +vn -0.085500 0.995600 -0.038400 +vn -0.393300 0.342600 -0.853100 +vn -0.344100 0.020600 -0.938700 +vn -0.160000 0.067900 -0.984800 +vn -0.984300 0.165200 -0.061400 +vn -0.950400 0.310600 -0.015300 +vn -0.082900 0.940400 -0.329700 +vn -0.684700 0.642700 0.343600 +vn -0.482800 0.747600 0.456000 +vn -0.504700 0.808300 0.303100 +vn 0.093700 0.644100 0.759100 +vn 0.257500 0.583300 0.770300 +vn 0.154300 0.786600 0.597800 +vn -0.263600 0.963000 0.055100 +vn -0.179600 0.969900 0.164000 +vn -0.986700 0.151000 -0.060000 +vn -0.970000 0.149900 -0.191500 +vn -0.037400 0.999300 -0.006500 +vn -0.192000 0.892800 0.407400 +vn -0.288300 0.940800 0.178100 +vn -0.308900 0.924800 0.221900 +vn -0.369600 0.861700 0.347600 +vn -0.038100 0.968600 -0.245800 +vn 0.004800 0.993700 -0.111500 +vn -0.800700 -0.582500 0.139700 +vn -0.834500 -0.550000 0.032800 +vn 0.589100 0.710700 0.384600 +vn 0.874100 0.472000 0.114500 +vn -0.875400 0.268200 -0.402100 +vn -0.870600 0.401000 -0.284900 +vn -0.779800 0.263200 -0.568000 +vn 0.093300 0.945900 -0.310700 +vn 0.096700 0.538900 -0.836800 +vn 0.286800 0.508700 -0.811700 +vn 0.291100 0.743500 -0.602000 +vn 0.494400 0.816800 0.297200 +vn -0.157100 0.879900 0.448400 +vn -0.259700 0.865500 0.428200 +vn -0.623200 0.726600 0.289100 +vn -0.258200 0.962200 0.086600 +vn 0.006600 0.938800 0.344200 +vn -0.111400 0.921800 0.371400 +vn -0.030400 0.846500 0.531500 +vn -0.973500 -0.041700 -0.224800 +vn -0.999200 0.010400 -0.037400 +vn -0.971400 0.147400 -0.186200 +vn -0.514800 0.782200 0.350900 +vn -0.690900 -0.720500 -0.058900 +vn -0.679500 -0.730700 0.066500 +vn -0.791800 -0.564800 -0.232400 +vn -0.148000 0.833000 0.533100 +vn -0.063800 0.767800 0.637500 +vn 0.615400 0.337400 0.712300 +vn 0.190700 0.518900 0.833200 +vn 0.557600 0.623700 0.547700 +vn -0.886700 -0.413000 0.208000 +vn -0.981100 -0.112000 0.157700 +vn -0.949200 -0.314400 0.015100 +vn -0.386500 -0.309400 0.868800 +vn -0.152000 0.046800 0.987200 +vn -0.412800 0.188000 0.891200 +vn 0.051100 0.295200 0.954000 +vn -0.275500 0.442900 0.853200 +vn -0.419800 0.826200 -0.375700 +vn -0.221600 0.930900 0.290300 +vn 0.204100 0.918100 0.339600 +vn -0.332500 0.750800 0.570800 +vn -0.301900 0.825800 0.476300 +vn 0.007600 0.540600 0.841200 +vn -0.206000 0.699700 0.684100 +vn 0.344900 0.934300 0.089800 +vn -0.825300 -0.562900 0.043700 +vn -0.351800 -0.238000 0.905300 +vn -0.202600 0.579700 0.789200 +vn -0.232100 0.690100 0.685500 +vn -0.434300 0.558700 0.706500 +vn 0.234800 0.947600 0.216400 +vn 0.349900 0.776500 0.523900 +vn -0.455000 0.784500 0.421200 +vn -0.518900 0.478600 0.708300 +vn -0.595700 0.200800 0.777700 +vn -0.373800 0.524900 0.764600 +vn -0.929600 0.308200 -0.202000 +vn 0.047100 -0.573300 -0.818000 +vn -0.037200 -0.432100 -0.901100 +vn 0.076600 -0.491600 -0.867500 +vn 0.135900 0.085500 -0.987000 +vn -0.099000 0.061600 -0.993200 +vn -0.025000 0.112400 -0.993300 +vn -0.380700 0.825200 0.417200 +vn 0.084800 0.978600 0.187200 +vn 0.266000 0.810000 0.522500 +vn -0.058800 0.023000 0.998000 +vn 0.035600 0.516200 0.855700 +vn 0.925200 0.211800 -0.314900 +vn 0.838300 0.282400 -0.466400 +vn 0.863200 0.309200 -0.399100 +vn -0.912900 -0.372400 -0.167100 +vn -0.943800 -0.330400 0.010600 +vn -0.208800 0.963200 -0.169300 +vn -0.246100 0.969200 0.010300 +vn -0.986600 0.025500 -0.160900 +vn -0.994400 -0.066400 -0.081900 +vn 0.844000 0.499200 0.195800 +vn 0.137100 0.990300 -0.020200 +vn 0.061700 0.993100 0.099700 +vn 0.046900 0.636000 0.770200 +vn -0.664300 0.529300 0.527700 +vn -0.948600 0.278800 0.149600 +vn -0.857200 -0.028500 0.514100 +vn 0.158400 0.977100 -0.141600 +vn -0.405100 -0.386000 0.828800 +vn -0.143600 -0.094900 0.985000 +vn 0.344000 0.262000 0.901600 +vn 0.249200 0.388700 0.887000 +vn 0.033300 0.287100 -0.957300 +vn 0.047200 0.482800 -0.874400 +vn 0.144200 0.192100 -0.970700 +vn 0.534000 -0.786900 0.309100 +vn 0.463500 -0.884900 -0.044200 +vn 0.563200 -0.750900 0.344800 +vn -0.933100 0.064100 -0.353900 +vn -0.911600 0.269400 -0.310300 +vn -0.846900 0.365200 -0.386500 +vn 0.115100 -0.027900 -0.993000 +vn 0.047800 -0.281600 -0.958300 +vn -0.037600 -0.137900 -0.989700 +vn -0.575300 0.276300 -0.769900 +vn -0.292000 -0.080800 -0.953000 +vn -0.081100 -0.276500 0.957600 +vn -0.137200 0.804600 0.577700 +vn 0.052400 0.714200 0.698000 +vn -0.792600 0.225800 -0.566300 +vn -0.871700 0.089700 -0.481700 +vn -0.953600 -0.128300 -0.272400 +vn 0.298900 0.113700 -0.947500 +vn 0.267300 -0.178600 -0.946900 +vn 0.490600 0.168100 -0.855000 +vn 0.211800 0.099000 0.972300 +vn 0.234600 0.518700 0.822100 +vn -0.215000 -0.639900 0.737800 +vn 0.046400 -0.577700 0.814900 +vn 0.392300 -0.094700 -0.914900 +vn 0.923000 0.281800 -0.261900 +vn 0.890900 -0.166500 -0.422500 +vn -0.947800 0.019100 -0.318100 +vn -0.292800 -0.239700 -0.925600 +vn -0.209400 -0.423300 -0.881400 +vn -0.077100 -0.530900 -0.843900 +vn 0.918300 0.295600 -0.263200 +vn 0.877800 0.434700 -0.201200 +vn 0.937500 0.330900 -0.107900 +vn 0.567600 -0.330000 -0.754300 +vn 0.668000 -0.425400 -0.610600 +vn 0.619800 -0.603400 -0.501600 +vn -0.180300 -0.397100 -0.899900 +vn 0.453500 -0.859800 -0.234600 +vn 0.821700 -0.546000 -0.163100 +vn 0.931200 -0.326700 -0.161700 +vn 0.198700 0.308300 0.930300 +vn 0.190900 0.474900 0.859100 +vn 0.066600 0.500200 0.863300 +vn 0.450300 -0.543400 -0.708400 +vn 0.876700 0.479300 -0.039600 +vn 0.929700 0.368000 0.016700 +vn 0.749400 -0.236000 -0.618700 +vn 0.671700 0.291700 -0.680900 +vn 0.855600 0.234600 -0.461300 +vn 0.686100 0.366900 -0.628200 +vn -0.264000 0.959300 0.099900 +vn 0.013500 0.979200 0.202300 +vn -0.205700 0.158500 0.965700 +vn -0.371700 0.316400 0.872700 +vn -0.537400 0.198100 0.819700 +vn 0.247200 -0.291400 0.924100 +vn 0.328100 -0.234900 0.914900 +vn 0.070900 -0.560900 0.824800 +vn 0.052500 -0.172200 0.983600 +vn 0.394000 0.500800 0.770700 +vn 0.567400 -0.822200 0.044900 +vn 0.457100 -0.886800 -0.067000 +vn 0.533200 -0.830400 -0.161400 +vn 0.816600 -0.082400 -0.571300 +vn 0.868100 -0.290400 -0.402500 +vn 0.962000 0.018600 -0.272500 +vn 0.985300 0.054000 -0.161800 +vn 0.992400 0.050200 -0.112200 +vn -0.642500 0.592100 -0.486400 +vn -0.593200 0.803000 0.057400 +vn -0.749300 0.627600 0.211400 +vn -0.925100 0.229400 -0.302500 +vn -0.861300 -0.098900 -0.498300 +vn -0.844400 0.303900 -0.441100 +vn -0.703700 -0.709400 -0.038900 +vn -0.698000 -0.686600 -0.203200 +vn -0.695200 -0.685100 -0.217400 +vn -0.245400 0.264100 0.932700 +vn -0.206600 0.323900 0.923200 +vn -0.245900 0.021300 0.969000 +vn 0.093700 -0.301900 0.948700 +vn 0.018700 0.205600 0.978400 +vn 0.086700 0.214500 0.972800 +vn 0.036700 0.423800 0.905000 +vn 0.258100 0.405900 0.876700 +vn 0.375000 0.464200 0.802400 +vn 0.242900 0.595600 0.765600 +vn 0.316900 -0.343200 0.884200 +vn 0.110900 -0.134600 0.984600 +vn 0.115500 -0.434300 0.893300 +vn 0.577800 0.355400 0.734700 +vn 0.429200 0.180900 0.884900 +vn 0.918500 0.386700 -0.082100 +vn 0.993200 0.105000 0.050600 +vn -0.960600 0.272300 0.055500 +vn -0.958000 0.254900 0.131300 +vn -0.944000 0.319700 0.081700 +vn -0.819400 -0.032400 -0.572300 +vn -0.796100 0.059300 -0.602200 +vn -0.003700 0.909600 -0.415300 +vn 0.038400 0.853000 0.520400 +vn -0.221400 0.368600 0.902800 +vn 0.835500 -0.518800 -0.181000 +vn 0.795100 -0.559900 -0.233100 +vn 0.957500 -0.268300 -0.106000 +vn 0.057300 -0.445700 0.893300 +vn -0.070200 -0.738900 0.670100 +vn -0.006300 -0.359200 0.933200 +vn 0.083300 0.584400 0.807200 +vn 0.068700 0.747000 0.661200 +vn 0.087600 0.604800 0.791500 +vn 0.981400 -0.108300 -0.158500 +vn 0.702200 -0.711600 0.022700 +vn 0.827600 -0.383000 0.410300 +vn -0.983200 0.153600 0.098700 +vn -0.008100 -0.595000 -0.803600 +vn -0.097300 -0.599400 -0.794500 +vn 0.248300 -0.841000 -0.480700 +vn 0.973000 0.225400 0.049100 +vn 0.977500 0.200800 -0.064800 +vn 0.996300 0.083700 -0.020400 +vn -0.219100 0.937300 -0.270800 +vn -0.928700 -0.363700 -0.072400 +vn 0.277400 0.917400 -0.285300 +vn 0.024200 -0.997900 0.060300 +vn 0.025400 -0.996700 0.077000 +vn 0.016400 -0.998000 0.060000 +vn 0.321800 -0.402400 0.857000 +vn 0.213600 -0.283900 0.934700 +vn 0.140700 -0.707100 0.692900 +vn 0.170200 0.016300 0.985300 +vn 0.990500 -0.070000 -0.118100 +vn 0.943400 0.211700 -0.255400 +vn 0.917600 0.370900 -0.142900 +vn 0.783300 -0.465200 -0.412200 +vn 0.737400 -0.607700 -0.294900 +vn 0.445200 -0.607800 -0.657500 +vn 0.963700 -0.260600 0.057800 +vn -0.314700 0.129100 0.940300 +vn -0.443900 0.008100 0.896000 +vn -0.349600 0.161000 0.922900 +vn 0.218500 0.583100 0.782400 +vn 0.391200 0.598800 0.698800 +vn 0.091100 0.612800 0.785000 +vn 0.140500 0.182500 0.973100 +vn 0.227400 0.391900 0.891400 +vn 0.244300 -0.157300 0.956800 +vn 0.207900 -0.256600 0.943800 +vn 0.653700 0.273400 0.705600 +vn 0.279500 0.606500 0.744300 +vn 0.959000 -0.023100 -0.282500 +vn 0.971800 0.039200 -0.232400 +vn 0.892600 -0.094300 -0.440700 +vn 0.167200 0.960500 0.222400 +vn 0.334100 0.936000 -0.111100 +vn 0.460500 0.887100 -0.031400 +vn 0.456000 0.879200 -0.137600 +vn -0.282600 -0.376800 0.882100 +vn -0.242500 -0.222700 0.944200 +vn -0.460000 -0.325200 0.826200 +vn -0.470700 -0.148200 0.869700 +vn -0.219200 0.257800 0.941000 +vn 0.913300 -0.044100 -0.404800 +vn 0.936300 0.064300 -0.345300 +vn -0.017800 -0.277300 0.960600 +vn -0.083000 -0.379500 0.921400 +vn -0.054400 -0.274800 0.960000 +vn -0.088600 0.527800 0.844700 +vn -0.139300 0.696700 0.703600 +vn 0.105900 0.657300 0.746100 +vn 0.156400 -0.083300 0.984200 +vn 0.219300 -0.075800 0.972700 +vn 0.161300 0.021500 0.986700 +vn 0.518800 0.276300 0.808900 +vn 0.532700 0.284400 0.797100 +vn 0.344500 0.587100 0.732500 +vn -0.080800 -0.275400 0.957900 +vn -0.237300 -0.186800 0.953300 +vn 0.741000 -0.179700 0.647000 +vn 0.761300 -0.274100 0.587500 +vn 0.703400 -0.077300 0.706600 +vn -0.695500 -0.690100 0.200300 +vn -0.800800 -0.447600 0.397900 +vn 0.864900 0.389100 0.317000 +vn 0.855400 0.504200 0.118200 +vn 0.827400 0.486800 0.279900 +vn -0.518900 -0.174400 -0.836800 +vn -0.438600 -0.172900 -0.881900 +vn -0.548600 -0.363800 -0.752700 +vn -0.059200 -0.243000 0.968200 +vn -0.209300 0.117600 0.970700 +vn -0.068000 0.312700 0.947400 +vn 0.113600 -0.109300 0.987500 +vn 0.347200 -0.464700 0.814500 +vn 0.504500 -0.330400 0.797700 +vn -0.342300 -0.431700 -0.834500 +vn -0.523800 -0.344000 -0.779300 +vn -0.293600 -0.623000 -0.725000 +vn -0.174700 0.051200 0.983300 +vn 0.870400 -0.448900 -0.202300 +vn 0.774400 0.565600 0.283300 +vn 0.733900 0.501500 0.458100 +vn 0.820000 0.427700 0.380400 +vn -0.090400 0.301900 0.949000 +vn -0.069300 0.434100 0.898200 +vn 0.103800 0.132200 0.985700 +vn -0.025800 -0.301200 0.953200 +vn -0.152800 -0.056000 0.986700 +vn 0.138300 -0.201800 0.969600 +vn 0.483000 0.284800 -0.828000 +vn 0.630800 0.059400 -0.773600 +vn -0.974200 -0.162800 0.156200 +vn -0.988200 -0.071800 0.135400 +vn -0.948300 0.270700 -0.165500 +vn -0.318700 0.712700 0.624800 +vn 0.335400 -0.665500 -0.666700 +vn 0.229400 -0.829700 -0.508800 +vn 0.483600 -0.779800 -0.397500 +vn -0.292900 -0.803900 -0.517700 +vn -0.303700 -0.860700 -0.408600 +vn -0.319700 -0.906700 -0.274900 +vn -0.174400 -0.331100 0.927300 +vn -0.184700 -0.216600 0.958600 +vn 0.016100 -0.120600 0.992600 +vn 0.001400 0.126600 0.991900 +vn -0.138800 0.718300 0.681800 +vn 0.002300 0.502500 0.864600 +vn 0.293400 0.138300 0.945900 +vn -0.719400 -0.221700 -0.658200 +vn -0.702600 -0.160100 -0.693300 +vn -0.904300 -0.095600 -0.416100 +vn -0.150800 -0.114000 0.982000 +vn 0.044800 0.258100 0.965100 +vn 0.275000 -0.037800 0.960700 +vn 0.095400 -0.206500 0.973800 +vn 0.004000 0.107700 0.994100 +vn -0.882000 -0.350800 -0.314600 +vn -0.981800 0.071800 -0.175800 +vn -0.638400 -0.755000 -0.149400 +vn -0.114600 0.370400 0.921800 +vn 0.556500 0.142700 0.818500 +vn 0.281000 0.027500 0.959300 +vn 0.057200 0.388700 0.919600 +vn -0.469600 0.134700 -0.872500 +vn -0.745000 0.306600 -0.592300 +vn -0.591300 0.546900 -0.592600 +vn 0.016400 -0.065300 0.997700 +vn 0.420800 -0.569400 0.706200 +vn -0.437400 -0.317500 0.841400 +vn -0.712400 -0.165200 0.682000 +vn -0.494400 -0.117900 0.861200 +vn 0.248700 0.963700 0.096800 +vn 0.375600 0.858100 0.350100 +vn -0.272700 0.325500 -0.905300 +vn -0.364900 0.420200 -0.830800 +vn -0.315100 0.347500 -0.883100 +vn -0.164300 -0.527800 0.833200 +vn -0.058500 -0.488100 0.870800 +vn 0.183600 0.159800 0.969900 +vn 0.042100 0.415100 0.908800 +vn 0.177900 -0.039900 0.983200 +vn 0.258100 0.188000 0.947600 +vn 0.149000 0.205500 0.967200 +vn 0.995000 -0.067000 -0.074500 +vn 0.876500 0.300100 -0.376400 +vn 0.807600 -0.229300 -0.543300 +vn -0.040200 0.664400 0.746200 +vn -0.127900 -0.524100 0.842000 +vn -0.064800 0.879700 0.471100 +vn -0.630400 -0.620300 -0.466700 +vn -0.722200 -0.469000 -0.508300 +vn -0.058300 0.024200 -0.998000 +vn 0.107200 0.203200 -0.973200 +vn -0.123600 -0.146700 0.981400 +vn -0.026500 0.509600 0.860000 +vn 0.296000 0.048500 0.953900 +vn 0.067400 0.101200 0.992600 +vn -0.042000 0.091900 0.994900 +vn 0.987100 -0.094900 0.129100 +vn 0.991300 0.129900 0.021100 +vn 0.951800 0.141700 0.272100 +vn 0.132300 0.333500 0.933400 +vn -0.240900 0.346300 0.906600 +vn 0.074200 0.776000 0.626400 +vn -0.081300 0.673900 0.734300 +vn 0.145100 0.087600 -0.985500 +vn 0.317000 -0.897500 -0.306500 +vn 0.022000 -0.939600 -0.341600 +vn -0.059800 -0.575500 0.815500 +vn 0.044200 -0.307900 0.950400 +vn -0.070700 -0.030100 0.997000 +vn 0.024700 0.283900 0.958500 +vn 0.279800 0.281000 0.918000 +vn 0.083000 0.213100 0.973500 +vn -0.146200 0.164900 0.975400 +vn 0.275500 0.210100 0.938000 +vn 0.242000 0.261500 0.934400 +vn 0.236200 0.242900 0.940800 +vn 0.075100 0.672100 0.736600 +vn 0.374400 -0.918700 0.125600 +vn 0.349200 -0.936400 -0.033800 +vn -0.173600 0.935400 0.308100 +vn -0.347100 0.216900 -0.912400 +vn -0.012300 -0.340700 0.940100 +vn 0.026300 0.140500 0.989700 +vn -0.186400 -0.566400 0.802700 +vn 0.231500 0.462200 0.856000 +vn 0.120000 0.403300 0.907200 +vn -0.139000 0.495700 0.857300 +vn -0.065900 0.628500 0.775000 +vn 0.352300 0.242400 0.903900 +vn 0.422600 0.256900 0.869100 +vn 0.568500 0.212000 0.794800 +vn 0.120200 0.432100 0.893800 +vn 0.299300 0.714300 0.632500 +vn 0.676000 -0.691800 -0.253900 +vn 0.846700 -0.485700 -0.217000 +vn 0.814000 -0.575100 -0.081300 +vn 0.354700 0.423600 0.833500 +vn -0.567600 0.771800 -0.286700 +vn -0.463600 0.753000 -0.466900 +vn -0.698300 0.577900 -0.422300 +vn 0.771100 0.483700 0.414000 +vn 0.855700 0.355900 0.375500 +vn -0.148400 -0.286400 0.946500 +vn -0.376800 -0.207800 0.902700 +vn -0.369900 -0.342400 0.863600 +vn -0.454800 0.104500 0.884400 +vn -0.477700 -0.473500 0.740000 +vn 0.142500 -0.226800 0.963400 +vn -0.050100 0.173900 0.983500 +vn 0.017600 0.348000 0.937300 +vn -0.010400 0.522300 0.852700 +vn 0.056000 0.628800 0.775600 +vn -0.130700 -0.099100 0.986400 +vn 0.123000 -0.156900 0.979900 +vn -0.088300 -0.323100 0.942200 +vn 0.300500 0.534500 0.789900 +vn 0.280200 0.475800 0.833600 +vn 0.204400 0.446800 0.870900 +vn 0.881800 0.440500 0.168500 +vn 0.836100 0.536900 0.112700 +vn -0.018200 -0.343900 0.938800 +vn 0.094400 0.428500 0.898600 +vn 0.242500 -0.000200 0.970100 +vn 0.040800 0.535300 0.843700 +vn -0.060200 0.902400 0.426600 +vn 0.089800 0.727900 0.679700 +vn -0.421500 0.675400 0.605000 +vn 0.180400 -0.037600 0.982800 +vn 0.040800 0.174800 0.983700 +vn 0.180400 0.133600 0.974500 +vn 0.130800 0.397200 0.908400 +vn 0.157100 0.367400 0.916700 +vn 0.018400 0.341500 0.939700 +vn 0.998400 -0.035000 0.044200 +vn 0.952900 0.249200 0.172700 +vn 0.998300 -0.036100 0.046200 +vn 0.253500 0.477800 0.841100 +vn 0.918000 0.009700 0.396400 +vn 0.175800 -0.954000 -0.242800 +vn 0.063600 -0.973700 -0.218700 +vn 0.527700 -0.814400 -0.241300 +vn -0.088000 0.420400 0.903000 +vn 0.340600 -0.085500 0.936300 +vn -0.216100 0.914900 0.341000 +vn -0.150100 0.877900 0.454600 +vn 0.246200 -0.144100 -0.958400 +vn 0.625100 -0.506100 -0.594200 +vn -0.924300 -0.347000 0.158400 +vn -0.977100 0.209000 -0.040900 +vn -0.660000 -0.751200 0.006100 +vn 0.112900 0.208600 0.971400 +vn 0.028200 0.326300 0.944900 +vn 0.084400 -0.573600 0.814800 +vn 0.316000 -0.475700 0.820900 +vn 0.075700 -0.281000 0.956700 +vn -0.181700 -0.282100 0.942000 +vn 0.263200 0.201800 0.943400 +vn 0.212500 0.232300 0.949100 +vn 0.317000 0.169900 0.933000 +vn -0.174700 0.599600 0.780900 +vn -0.628300 0.061000 0.775500 +vn -0.798600 0.407000 0.443400 +vn 0.095300 -0.258600 0.961200 +vn 0.127800 -0.613300 0.779400 +vn -0.137500 0.405700 0.903600 +vn 0.014100 0.561900 0.827100 +vn 0.282700 -0.787900 -0.547000 +vn 0.692600 -0.662300 -0.285700 +vn -0.215200 0.141900 0.966200 +vn 0.274100 -0.189000 0.942900 +vn 0.367100 -0.131300 0.920800 +vn 0.285900 0.078700 0.955000 +vn 0.304500 0.063000 0.950400 +vn -0.988400 0.060500 0.139200 +vn -0.951100 -0.020500 -0.308200 +vn -0.998100 -0.000200 -0.060700 +vn 0.398200 -0.574500 0.715000 +vn -0.240700 0.726800 0.643200 +vn 0.191000 0.475400 0.858800 +vn 0.383300 0.127900 0.914700 +vn 0.316900 0.580800 0.749700 +vn 0.522300 0.329800 0.786400 +vn 0.799200 0.546000 -0.251100 +vn 0.545500 0.251400 -0.799500 +vn -0.119500 0.301300 -0.946000 +vn 0.153400 0.128300 0.979800 +vn 0.087000 -0.810600 -0.579000 +vn 0.434400 -0.797400 -0.418800 +vn 0.375400 0.302000 0.876200 +vn -0.845900 0.357200 -0.395900 +vn -0.700900 0.538700 -0.467400 +vn 0.002800 0.440200 0.897900 +vn 0.472200 0.819900 0.323500 +vn 0.705000 -0.131400 -0.696900 +vn 0.561500 0.008600 -0.827400 +vn 0.548400 -0.023100 -0.835900 +vn -0.194300 -0.273200 0.942100 +vn 0.136300 -0.111600 0.984300 +vn 0.173700 0.161900 0.971400 +vn 0.158200 0.340800 0.926700 +vn -0.065600 0.720300 0.690500 +vn -0.145200 -0.588800 -0.795100 +vn -0.001900 -0.807600 -0.589600 +vn 0.253100 -0.861400 -0.440300 +vn 0.142800 -0.758000 -0.636400 +vn 0.278500 -0.919300 -0.277800 +vn 0.536500 0.250800 0.805700 +vn 0.377200 0.226100 0.898100 +vn -0.103000 -0.030900 0.994200 +vn 0.064300 0.601200 0.796500 +vn 0.017500 0.641600 0.766900 +vn 0.992100 -0.034300 0.120200 +vn 0.947900 0.076900 0.309000 +vn 0.657600 -0.749400 -0.077100 +vn 0.127300 0.351300 0.927500 +vn -0.123600 -0.161700 0.979100 +vn -0.079000 -0.042300 0.996000 +vn 0.206900 0.444300 0.871600 +vn 0.732400 -0.655500 -0.184000 +vn 0.290300 -0.037300 0.956200 +vn 0.029200 -0.003500 0.999500 +vn 0.111600 0.464600 0.878500 +vn -0.965800 -0.221800 0.134100 +vn -0.136100 -0.117600 0.983700 +vn 0.030300 0.027400 0.999100 +vn 0.074200 0.207300 0.975400 +vn -0.965700 0.210700 0.151900 +vn 0.981800 -0.188500 -0.021400 +vn -0.011200 0.648100 0.761500 +vn 0.264100 0.318900 0.910200 +vn 0.143100 -0.187800 0.971700 +vn 0.042800 -0.169400 0.984600 +vn 0.007100 -0.101400 0.994800 +vn 0.992100 0.047500 0.115600 +vn -0.684800 0.728300 -0.025400 +vn -0.448000 0.890700 -0.077000 +vn 0.026300 0.078300 0.996600 +vn -0.083400 0.204800 0.975200 +vn -0.174400 -0.010000 0.984600 +vn -0.028300 0.304700 0.952000 +vn 0.101700 0.138600 0.985100 +vn 0.058500 -0.065900 0.996100 +vn -0.158900 -0.039700 0.986500 +vn -0.229900 0.035700 0.972500 +vn 0.014800 0.367600 0.929800 +vn 0.935700 0.300600 -0.184500 +vn 0.935200 0.349200 0.057800 +vn 0.976000 -0.217700 -0.008600 +vn 0.391800 -0.775400 -0.495100 +vn 0.358200 -0.681700 -0.637900 +vn 0.409100 -0.910200 -0.065100 +vn 0.480500 -0.713100 0.510500 +vn 0.170700 -0.120300 0.977900 +vn -0.236500 0.188400 0.953200 +vn 0.190100 0.396000 0.898300 +vn -0.012000 0.567200 0.823500 +vn 0.073100 0.578900 0.812100 +vn -0.000500 0.655000 0.755600 +vn -0.104100 0.801800 0.588400 +vn -0.377900 0.920100 0.102400 +vn -0.441400 0.892200 -0.095800 +vn -0.609500 0.783400 0.121100 +vn 0.580600 0.027600 0.813700 +vn 0.281600 0.484000 0.828500 +vn -0.115000 0.708400 0.696400 +vn -0.024000 0.578500 0.815300 +vn 0.031600 0.702700 0.710800 +vn -0.102800 0.679800 0.726100 +vn -0.135300 0.359900 0.923100 +vn 0.928300 0.082900 -0.362400 +vn 0.926900 -0.134200 -0.350500 +vn 0.623200 0.035700 0.781200 +vn 0.280100 -0.113900 0.953200 +vn 0.201700 -0.128800 0.970900 +vn 0.112400 0.022200 0.993400 +vn -0.031500 -0.094000 0.995100 +vn -0.189200 0.003600 0.981900 +vn -0.205900 0.378800 0.902200 +vn -0.131000 0.491000 0.861200 +vn 0.285300 -0.154300 0.945900 +vn 0.911700 0.394800 0.113900 +vn 0.940800 0.308900 0.139500 +vn 0.345200 -0.927300 -0.144400 +vn 0.673600 -0.705800 -0.219200 +vn -0.373900 0.530300 0.760800 +vn 0.039500 0.412100 0.910300 +vn 0.331700 -0.058700 0.941500 +vn 0.337700 -0.197100 0.920300 +vn 0.146900 -0.142600 0.978800 +vn -0.177000 0.532700 0.827500 +vn 0.185500 0.301500 0.935200 +vn 0.279900 0.302700 0.911100 +vn 0.024800 0.026200 0.999300 +vn 0.767100 -0.208900 0.606600 +vn 0.358900 -0.149300 0.921400 +vn -0.103500 -0.262900 0.959300 +vn -0.146500 -0.267400 0.952400 +vn -0.194200 0.474300 0.858600 +vn 0.510000 0.142700 0.848200 +vn 0.719700 -0.083700 0.689100 +vn 0.751600 0.624800 0.211300 +vn 0.488300 0.858700 0.155600 +vn 0.359200 -0.162500 0.919000 +vn 0.167700 -0.158000 0.973100 +vn -0.088100 0.638800 0.764200 +vn -0.046000 0.774600 0.630800 +vn -0.051500 -0.165500 0.984800 +vn -0.104800 0.518400 0.848600 +vn -0.069200 0.406800 0.910900 +vn 0.124800 0.085500 0.988500 +vn 0.250500 -0.191200 0.949000 +vn -0.019000 0.051800 0.998500 +vn -0.034200 0.204400 0.978300 +vn -0.521300 -0.800400 -0.295800 +vn -0.956900 -0.130200 -0.259400 +vn -0.984200 0.171100 -0.044800 +vn -0.481200 -0.193700 0.854900 +vn -0.139800 0.403500 0.904200 +vn 0.304500 0.399900 0.864400 +vn 0.051400 0.635000 0.770800 +vn 0.670300 -0.643100 -0.370300 +vn -0.097800 -0.241300 0.965500 +vn -0.481200 -0.308300 0.820600 +vn -0.657200 -0.111200 0.745400 +vn -0.389900 0.039600 0.920000 +vn 0.028100 0.226300 0.973600 +vn 0.991900 0.112200 0.059400 +vn 0.974600 0.186700 0.123300 +vn 0.618000 -0.376400 0.690200 +vn 0.117100 0.098600 0.988200 +vn 0.338200 0.402000 0.850900 +vn 0.297700 0.545600 0.783300 +vn -0.867200 -0.213800 0.449800 +vn -0.878400 0.042000 0.476000 +vn 0.779800 0.159700 -0.605300 +vn 0.825800 0.397200 -0.400300 +vn 0.255700 0.966000 0.037700 +vn -0.348700 -0.157200 0.923900 +vn -0.405800 0.167900 0.898400 +vn 0.843200 0.403300 -0.355400 +vn 0.810000 0.506500 -0.295600 +vn 0.211500 0.806200 0.552400 +vn 0.176200 0.620200 0.764400 +vn 0.909500 0.287200 0.300500 +vn 0.984000 0.075400 0.161200 +vn 0.729000 -0.633100 -0.260200 +vn 0.845600 -0.487400 -0.217700 +vn -0.314400 0.842300 0.437700 +vn -0.507200 0.704600 0.496200 +vn -0.315700 0.733300 0.602100 +vn -0.662800 -0.250000 0.705700 +vn -0.173900 0.155900 0.972300 +vn -0.259600 0.569900 0.779600 +vn -0.222800 0.440000 0.869900 +vn -0.114400 0.714200 -0.690500 +vn -0.114100 0.624900 -0.772300 +vn -0.148800 0.608200 -0.779700 +vn 0.077900 0.028700 0.996500 +vn -0.011200 -0.083300 -0.996500 +vn 0.961100 -0.267700 -0.067300 +vn -0.773300 -0.028800 0.633400 +vn -0.793900 -0.143200 0.590800 +vn -0.820900 -0.275400 0.500300 +vn -0.933300 -0.038100 0.357000 +vn -0.995800 -0.083000 0.039600 +vn -0.894500 -0.296000 0.334800 +vn 0.717900 -0.330100 0.612900 +vn -0.402200 0.358000 0.842600 +vn -0.212700 0.461400 0.861300 +vn -0.276900 0.645300 0.711900 +vn -0.159200 0.846600 0.507800 +vn -0.191700 -0.095600 -0.976800 +vn -0.241600 -0.397200 -0.885300 +vn -0.044600 0.791900 0.608900 +vn 0.145000 0.905500 0.398800 +vn 0.379200 0.925200 0.013200 +vn -0.401600 0.354200 0.844500 +vn -0.024100 0.619700 0.784500 +vn -0.367300 0.771500 0.519500 +vn -0.618000 0.471400 0.629200 +vn 0.547700 0.249800 0.798500 +vn -0.116500 0.333200 0.935600 +vn 0.238500 -0.899300 -0.366600 +vn 0.505200 -0.849700 -0.150900 +vn 0.710400 0.033700 0.702900 +vn 0.318900 0.479100 0.817700 +vn -0.124100 0.850700 0.510800 +vn -0.293300 0.392400 0.871700 +vn 0.103400 0.347700 0.931900 +vn 0.012100 0.817600 0.575700 +vn -0.063300 0.234100 0.970100 +vn -0.168400 0.642700 0.747400 +vn -0.108100 0.603400 0.790000 +vn -0.947400 0.096700 -0.305100 +vn 0.187800 0.900200 0.392900 +vn 0.756100 0.286500 0.588400 +vn 0.812900 0.375600 0.445100 +vn 0.462400 0.868600 0.177900 +vn -0.163600 0.364900 0.916500 +vn 0.416400 -0.124000 0.900700 +vn 0.342100 0.914000 0.218000 +vn -0.959900 0.220300 -0.173500 +vn -0.988100 -0.108200 0.109200 +vn -0.954400 -0.241900 -0.174500 +vn -0.275300 0.569900 0.774200 +vn 0.590600 0.321200 -0.740300 +vn 0.583200 0.215500 0.783200 +vn 0.380700 0.259500 0.887500 +vn -0.517900 0.161000 0.840100 +vn -0.778300 -0.127600 0.614700 +vn -0.113700 -0.328600 -0.937600 +vn -0.630900 -0.354400 -0.690100 +vn -0.473300 -0.411600 -0.778800 +vn 0.314600 0.703600 0.637100 +vn 0.323100 0.692300 0.645200 +vn 0.237300 0.543900 0.804800 +vn 0.028300 0.265300 0.963700 +vn 0.481800 -0.095900 0.871000 +vn 0.254600 0.066100 0.964800 +vn 0.157300 0.710200 0.686200 +vn -0.974700 0.191500 -0.114800 +vn -0.892100 0.416700 0.174300 +vn -0.725200 0.678900 -0.114600 +vn 0.391500 0.857700 -0.333200 +vn -0.459900 0.874900 0.151900 +vn -0.483900 0.846700 -0.221100 +vn 0.536100 -0.844000 0.012900 +vn -0.048100 0.304200 0.951400 +vn -0.327300 0.232000 -0.916000 +vn -0.588400 0.403800 -0.700500 +vn -0.185600 0.312300 -0.931700 +vn 0.284100 0.029400 0.958300 +vn 0.323300 -0.004600 0.946300 +vn 0.274700 0.481300 0.832400 +vn -0.261500 0.215300 0.940900 +vn -0.497700 -0.359500 0.789300 +vn 0.027600 0.995200 -0.093500 +vn 0.178700 0.963000 0.201800 +vn -0.230800 -0.607100 -0.760400 +vn -0.545700 0.042300 0.836900 +vn -0.388000 -0.267400 0.882000 +vn -0.284100 0.045600 0.957700 +vn -0.242000 -0.082000 0.966800 +vn 0.544200 0.347600 0.763500 +vn -0.151200 0.194100 0.969200 +vn -0.413400 0.326400 0.850000 +vn -0.129000 0.529200 0.838600 +vn -0.270200 0.557200 0.785200 +vn 0.696300 -0.159400 -0.699800 +vn 0.643600 -0.156200 -0.749300 +vn 0.567600 0.011400 -0.823100 +vn 0.277400 -0.079700 0.957400 +vn -0.583400 0.810400 0.053400 +vn -0.243400 -0.253200 0.936300 +vn 0.092300 -0.103300 0.990300 +vn -0.389800 -0.398300 0.830300 +vn -0.680300 -0.193900 0.706800 +vn -0.412700 -0.274000 0.868700 +vn -0.036800 -0.250300 0.967400 +vn -0.232200 0.440500 0.867200 +vn -0.418400 0.519200 0.745200 +vn 0.337900 0.874200 0.348600 +vn -0.006200 -0.990400 0.138000 +vn -0.069800 -0.857200 0.510100 +vn 0.002800 -0.995100 0.099100 +vn -0.162300 0.309800 0.936800 +vn -0.255700 0.632300 0.731300 +vn -0.017200 0.061900 0.997900 +vn -0.530400 -0.233300 0.815000 +vn -0.290700 -0.359900 0.886500 +vn -0.279400 -0.149200 0.948500 +vn -0.191400 -0.185400 0.963800 +vn 0.023600 -0.025600 0.999400 +vn -0.065600 0.206800 0.976200 +vn -0.238000 0.667000 0.705900 +vn -0.808500 0.143700 -0.570700 +vn -0.794400 0.228200 -0.562900 +vn 0.326900 0.932000 0.156600 +vn -0.194300 0.505800 0.840400 +vn -0.260200 0.753900 0.603300 +vn 0.555500 -0.733600 -0.391400 +vn 0.928100 -0.127000 -0.350000 +vn -0.075700 -0.255200 0.963900 +vn -0.070500 0.093200 0.993100 +vn -0.263500 -0.526900 0.808000 +vn -0.307100 -0.274000 0.911300 +vn -0.142600 -0.047900 0.988600 +vn -0.136000 0.155600 0.978400 +vn -0.161900 0.362700 0.917700 +vn 0.370000 0.468400 0.802200 +vn -0.271900 -0.362700 0.891400 +vn -0.278100 -0.187800 0.942000 +vn -0.199500 -0.113200 0.973300 +vn -0.083100 0.390300 0.916900 +vn -0.026200 0.151400 0.988100 +vn 0.962400 0.179800 -0.203700 +vn -0.039000 0.137200 0.989700 +vn -0.039700 -0.308600 -0.950300 +vn -0.306500 0.948100 0.084900 +vn -0.274500 -0.026500 0.961200 +vn 0.052100 0.108400 0.992700 +vn -0.088200 0.913100 0.398100 +vn -0.309900 0.818800 0.483300 +vn -0.024200 0.715100 0.698500 +vn -0.939900 0.306300 0.150800 +vn 0.356200 -0.043400 0.933400 +vn 0.249900 0.030600 0.967800 +vn 0.479600 0.004000 0.877500 +vn 0.792700 -0.147000 0.591600 +vn -0.480700 0.801800 0.355000 +vn 0.591600 0.475300 0.651200 +vn 0.481000 0.471700 0.738900 +vn 0.457800 0.342000 0.820600 +vn 0.440400 -0.161100 0.883200 +vn 0.557500 -0.447600 0.699100 +vn 0.440400 0.306600 0.843800 +vn 0.394300 -0.184000 0.900400 +vn 0.454400 -0.222700 0.862500 +vn 0.095600 -0.896200 0.433200 +vn 0.260300 -0.507500 0.821300 +vn 0.238100 -0.542100 0.805900 +vn 0.519200 0.399100 0.755700 +vn 0.433900 0.274600 0.858100 +vn 0.530600 0.323600 0.783400 +vn 0.576000 0.079600 0.813600 +vn 0.420400 -0.233600 0.876700 +vn 0.434600 -0.174500 0.883500 +vn 0.304300 -0.068800 0.950100 +vn 0.679500 -0.174100 0.712700 +vn 0.860200 -0.114900 0.496800 +vn 0.797900 -0.256800 0.545300 +vn 0.945100 0.073900 -0.318300 +vn -0.251600 0.031300 0.967300 +vn 0.264600 -0.304800 0.914900 +vn 0.757600 0.132200 0.639200 +vn 0.626400 -0.383100 0.678800 +vn -0.188000 -0.495200 -0.848200 +vn -0.001000 -0.631800 -0.775100 +vn 0.450800 -0.449400 0.771200 +vn 0.460600 -0.605500 0.649000 +vn 0.446500 -0.342300 0.826700 +vn 0.649400 -0.650700 -0.393500 +vn 0.662200 -0.688700 -0.295100 +vn 0.707800 -0.559700 -0.431000 +vn 0.691800 -0.014500 -0.721900 +vn 0.677200 -0.273500 -0.683000 +vn 0.754100 -0.298400 -0.585000 +vn 0.428900 0.555800 0.712100 +vn 0.180300 0.791500 0.584000 +vn 0.481400 -0.177000 0.858400 +vn 0.494000 -0.220600 0.841000 +vn 0.504500 -0.237800 0.830000 +vn 0.905100 0.343500 0.250400 +vn -0.654400 0.450400 -0.607300 +vn 0.454600 0.368200 0.811000 +vn 0.439800 -0.223400 0.869900 +vn 0.435500 -0.172700 0.883400 +vn 0.807200 -0.054000 0.587800 +vn 0.078900 -0.333100 0.939600 +vn -0.195000 -0.606100 0.771100 +vn 0.065500 -0.842200 0.535200 +vn 0.622800 0.278500 0.731100 +vn 0.718200 0.516600 -0.466200 +vn 0.791400 0.497000 -0.355800 +vn 0.796700 0.411700 -0.442500 +vn 0.705000 0.211400 0.676900 +vn -0.967500 0.240700 0.077500 +vn -0.906200 0.110500 0.408200 +vn -0.994600 0.082900 -0.061500 +vn 0.343100 0.537100 0.770600 +vn 0.702800 0.344300 0.622500 +vn 0.531100 0.390100 0.752100 +vn 0.476500 0.421300 0.771600 +vn 0.333200 -0.127700 0.934100 +vn 0.167600 0.723900 0.669100 +vn 0.313900 -0.797100 0.515800 +vn 0.028100 -0.703900 -0.709700 +vn 0.759800 -0.414700 0.500700 +vn 0.609900 -0.608400 0.507700 +vn -0.702900 -0.711100 -0.017200 +vn 0.641100 -0.138900 0.754700 +vn 0.774500 0.301100 0.556300 +vn 0.673000 0.083400 0.734900 +vn 0.796200 -0.354500 0.490200 +vn 0.488700 -0.508300 0.709000 +vn 0.562700 -0.691900 0.452400 +vn 0.219400 0.629000 0.745700 +vn 0.842500 0.040300 0.537100 +vn 0.935700 0.000600 0.352800 +vn 0.473100 -0.748500 0.464600 +vn 0.531700 -0.793600 0.295900 +vn 0.847700 -0.213300 0.485600 +vn 0.779200 0.326100 0.535100 +vn 0.836400 -0.064300 0.544300 +vn 0.800800 -0.254300 0.542200 +vn 0.812900 -0.093100 0.574900 +vn 0.685900 -0.024600 0.727300 +vn 0.729600 -0.192800 0.656100 +vn 0.816000 0.245600 0.523200 +vn 0.835400 0.335600 0.435300 +vn 0.758600 0.350000 0.549500 +vn -0.091500 0.126300 -0.987700 +vn -0.085200 0.233400 -0.968600 +vn 0.605000 -0.726600 0.325500 +vn 0.409700 -0.848400 0.335000 +vn 0.756000 -0.521300 0.395700 +vn 0.823500 0.084200 0.561000 +vn 0.930700 -0.324800 -0.168200 +vn 0.631500 0.447700 0.633000 +vn 0.808200 -0.034600 0.587800 +vn 0.768000 -0.020000 0.640100 +vn 0.706700 -0.060700 0.704900 +vn 0.625000 0.093100 0.775000 +vn 0.625300 0.033100 0.779600 +vn 0.550100 0.119700 0.826400 +vn 0.335400 0.646300 0.685400 +vn 0.693400 0.391100 0.605100 +vn 0.590200 -0.214200 0.778300 +vn 0.546900 -0.000800 0.837200 +vn 0.548800 -0.045600 0.834700 +vn 0.773800 -0.015100 0.633200 +vn 0.831800 0.062200 0.551500 +vn 0.751800 -0.027400 0.658800 +vn 0.743400 0.129600 0.656100 +vn -0.002400 0.419500 -0.907700 +vn 0.000500 0.390700 -0.920500 +vn 0.038700 0.274700 -0.960800 +vn 0.412200 0.131700 0.901500 +vn 0.731500 0.300000 0.612300 +vn 0.863600 0.342500 0.369800 +vn 0.794000 0.262900 0.548100 +vn 0.462600 0.224100 0.857700 +vn 0.513000 -0.084700 0.854200 +vn 0.545500 -0.570000 0.614400 +vn 0.376300 0.526900 0.762000 +vn 0.649000 0.423000 0.632300 +vn 0.554900 0.294700 0.777900 +vn 0.481700 -0.480300 0.733000 +vn 0.878200 -0.014700 0.478000 +vn 0.759200 0.068900 0.647200 +vn 0.002400 0.236400 -0.971600 +vn -0.139800 0.412100 -0.900300 +vn 0.843300 -0.041900 0.535800 +vn 0.477500 -0.333000 0.813000 +vn 0.619100 -0.394600 0.678900 +vn 0.538000 -0.374300 0.755200 +vn 0.461000 -0.157400 0.873300 +vn 0.666800 -0.379200 0.641500 +vn 0.611600 -0.018400 0.790900 +vn 0.590900 -0.188900 0.784300 +vn 0.385500 0.125500 0.914100 +vn 0.491700 -0.132100 0.860700 +vn 0.725900 -0.408500 0.553300 +vn 0.521300 -0.605900 -0.600900 +vn 0.582100 -0.521000 0.624100 +vn 0.599800 -0.341900 0.723400 +vn 0.508900 0.337400 0.791900 +vn 0.508700 0.462600 0.726100 +vn 0.611100 0.365500 0.702000 +vn 0.740300 -0.127300 0.660100 +vn 0.596000 -0.416000 0.686800 +vn 0.591400 -0.025100 0.806000 +vn -0.020700 0.323600 -0.946000 +vn 0.578700 -0.031600 0.814900 +vn -0.142900 -0.082200 0.986300 +vn 0.192500 0.075700 0.978400 +vn -0.847000 -0.312300 -0.430100 +vn 0.290700 0.001400 0.956800 +vn 0.708900 -0.644200 0.287100 +vn 0.606600 -0.468800 0.642000 +vn 0.451100 -0.887800 0.091600 +vn 0.541300 0.485200 0.686700 +vn 0.790300 0.145100 0.595300 +vn -0.489000 -0.542300 -0.683200 +vn 0.148900 -0.723500 -0.674000 +vn 0.441900 -0.423200 0.790900 +vn 0.633900 0.050200 0.771800 +vn 0.738600 0.040800 0.672900 +vn 0.466600 -0.442400 0.765900 +vn 0.440400 0.522600 0.730000 +vn 0.571400 0.271700 0.774400 +vn 0.688600 0.020800 0.724800 +vn 0.741400 -0.188300 0.644000 +vn 0.634500 0.338800 0.694700 +vn 0.584600 -0.565300 0.581900 +vn 0.536600 0.455300 0.710400 +vn 0.252800 0.776900 0.576600 +vn 0.669600 0.094100 0.736700 +vn 0.553700 -0.421100 0.718300 +vn 0.644000 -0.234900 0.728000 +vn 0.616900 0.353700 0.703100 +vn 0.444600 0.512500 0.734600 +vn 0.615000 0.363900 0.699500 +vn 0.550500 0.222000 0.804800 +vn 0.790300 -0.010300 0.612600 +vn 0.538400 0.478300 -0.693700 +vn 0.063800 -0.718300 -0.692700 +vn 0.701600 0.021900 0.712200 +vn -0.203000 -0.518100 0.830800 +vn 0.307600 0.169500 0.936300 +vn 0.449400 -0.863000 0.230500 +vn 0.267800 0.693300 0.669000 +vn 0.927500 0.254200 0.274000 +vn 0.578800 -0.795100 -0.181200 +vn 0.533100 0.131400 0.835800 +vn 0.620100 -0.061300 0.782100 +vn 0.247800 -0.111500 0.962400 +vn 0.664300 0.408100 0.626200 +vn 0.778200 -0.008000 0.627900 +vn 0.113000 -0.907500 0.404400 +vn 0.009500 -0.923300 0.384000 +vn 0.018300 -0.991400 0.129500 +vn 0.592800 -0.438600 0.675400 +vn -0.471500 0.167300 -0.865800 +vn -0.328900 0.221200 -0.918100 +vn 0.736000 0.179700 0.652600 +vn 0.859300 0.152100 0.488300 +vn 0.188200 -0.484700 0.854200 +vn 0.259300 0.193400 0.946200 +vn 0.670700 -0.566500 0.478700 +vn 0.706300 0.408700 0.578000 +vn 0.570900 0.481600 0.664900 +vn 0.759100 -0.053200 0.648800 +vn 0.573000 -0.028800 0.819100 +vn 0.580800 -0.223300 0.782800 +vn 0.599800 -0.172600 0.781300 +vn 0.700200 -0.261100 0.664400 +vn 0.613200 -0.165900 0.772200 +vn 0.848200 0.131300 0.513100 +vn 0.898100 0.072800 0.433700 +vn -0.272400 -0.943200 -0.190000 +vn -0.434800 -0.873800 -0.217400 +vn 0.513900 0.077100 0.854400 +vn 0.777100 -0.015300 0.629200 +vn 0.901000 0.086700 0.425000 +vn 0.506100 -0.467200 0.725000 +vn 0.543300 -0.128000 0.829700 +vn 0.521000 0.026500 0.853100 +vn 0.608500 0.283900 0.741000 +vn 0.104500 -0.543700 -0.832700 +vn 0.602200 -0.119100 0.789400 +vn 0.512600 -0.115300 0.850800 +vn 0.337600 -0.770500 -0.540700 +vn 0.427800 -0.690300 -0.583500 +vn 0.472200 -0.794300 -0.382200 +vn -0.531800 0.374000 0.759700 +vn 0.807900 0.369000 0.459500 +vn 0.973300 -0.093000 0.209900 +vn 0.863400 -0.416900 0.284100 +vn 0.618700 0.296600 0.727400 +vn 0.860500 0.507900 0.038600 +vn 0.580800 -0.140300 0.801800 +vn 0.573800 0.140400 0.806900 +vn -0.811500 0.305700 -0.497900 +vn -0.662900 -0.206400 -0.719700 +vn -0.358700 0.368500 -0.857600 +vn 0.820700 0.095700 0.563200 +vn 0.792700 0.309300 0.525300 +vn 0.435700 0.097100 0.894800 +vn 0.557600 -0.274100 0.783500 +vn 0.543000 0.192000 0.817500 +vn 0.639200 -0.051600 0.767300 +vn 0.643000 -0.251900 0.723300 +vn 0.646700 -0.331600 0.686800 +vn 0.560200 0.058500 0.826300 +vn 0.532200 0.049700 0.845100 +vn 0.933000 0.208200 0.293400 +vn -0.755800 -0.633200 0.166700 +vn 0.844600 0.234400 0.481400 +vn 0.384400 0.450700 0.805700 +vn 0.585000 -0.180100 0.790700 +vn -0.976800 -0.175500 0.122900 +vn -0.985700 -0.133000 -0.103000 +vn 0.605900 0.003600 0.795500 +vn 0.643600 -0.204600 0.737500 +vn 0.758800 0.153100 0.633000 +vn 0.254600 0.040800 0.966200 +vn 0.523000 -0.476600 0.706600 +vn 0.681200 -0.211400 -0.700900 +vn 0.763400 -0.109300 -0.636600 +vn 0.689100 -0.319500 -0.650300 +vn -0.507000 0.751500 -0.421900 +vn -0.617800 0.702800 -0.352700 +vn -0.334700 -0.271200 -0.902400 +vn 0.872500 0.139200 0.468300 +vn -0.461700 0.142900 -0.875400 +vn -0.577600 0.269600 -0.770500 +vn -0.437200 0.242300 -0.866100 +vn 0.134000 -0.978000 -0.159500 +vn 0.215800 -0.935500 -0.279800 +vn 0.760700 0.178600 0.624000 +vn 0.898800 -0.436100 0.042900 +vn 0.956100 -0.292900 0.001800 +vn 0.635800 -0.021400 0.771500 +vn -0.426900 -0.065400 -0.901900 +vn -0.600400 -0.456800 0.656400 +vn -0.757600 0.023000 0.652300 +vn -0.645400 -0.338600 0.684700 +vn -0.994400 -0.053100 0.091600 +vn 0.866100 -0.026000 0.499100 +vn 0.178800 -0.015600 0.983800 +vn -0.131200 -0.681800 -0.719600 +vn -0.282100 -0.547100 -0.788100 +vn -0.240000 0.239000 -0.940900 +vn -0.578900 0.367700 -0.727700 +vn -0.265900 -0.943200 -0.199200 +vn 0.398100 0.792100 -0.462600 +vn 0.194300 -0.630300 0.751700 +vn 0.133500 0.105600 0.985400 +vn -0.141900 0.012900 0.989800 +vn 0.418800 -0.689100 0.591400 +vn 0.826700 -0.521700 -0.210500 +vn 0.800100 -0.525200 -0.289700 +vn 0.776600 -0.564300 -0.280100 +vn -0.868700 -0.495100 -0.012500 +vn 0.077300 0.709600 -0.700300 +vn 0.676600 0.733500 0.065100 +vn 0.409100 -0.092200 0.907800 +vn 0.131900 0.822900 0.552600 +vn 0.925000 -0.202500 0.321500 +vn 0.796000 -0.527200 0.297200 +vn 0.921500 -0.320900 0.218700 +vn 0.626000 0.721900 -0.295000 +vn 0.501000 0.691800 -0.520100 +vn 0.181800 0.895700 -0.405800 +vn 0.787900 -0.613400 0.054500 +vn 0.717200 0.695500 -0.043000 +vn 0.905600 0.395200 0.153800 +vn -0.193500 -0.284000 -0.939100 +vn 0.289000 0.256700 -0.922300 +vn 0.558700 0.578700 -0.594000 +vn 0.312300 -0.024100 0.949600 +vn 0.089000 -0.960200 -0.264500 +vn -0.823700 0.495700 0.275400 +vn -0.514700 0.802100 0.302900 +vn 0.008800 0.932200 0.361700 +vn 0.606100 -0.160500 0.779000 +vn 0.552600 0.052800 0.831700 +vn -0.494000 0.105700 -0.863000 +vn -0.624500 0.337500 -0.704300 +vn -0.508700 0.071800 -0.857900 +vn -0.794300 -0.588700 0.149800 +vn 0.617800 -0.290300 0.730700 +vn 0.977700 0.145900 0.150900 +vn 0.875900 0.422300 0.233300 +vn 0.918500 0.292000 0.266500 +vn 0.574100 -0.637900 -0.513300 +vn 0.716700 -0.664800 0.210800 +vn 0.213100 -0.976900 -0.018600 +vn 0.385900 -0.913600 0.128300 +vn -0.210400 0.270300 -0.939500 +vn 0.438200 0.702300 0.561000 +vn 0.246300 0.717000 0.652000 +vn 0.450500 -0.146400 0.880700 +vn 0.325500 -0.504000 -0.800000 +vn -0.920900 0.044800 0.387200 +vn -0.958100 0.116600 0.261700 +vn -0.948500 -0.189400 0.253700 +vn -0.288500 0.737600 -0.610500 +vn 0.943100 0.028400 0.331400 +vn 0.873900 0.234400 0.425900 +vn 0.051500 -0.827600 0.558900 +vn 0.809600 0.334400 0.482400 +vn 0.656100 -0.641000 0.398300 +vn 0.366800 0.307000 0.878200 +vn 0.369100 0.540600 0.755900 +vn -0.120900 -0.011700 -0.992600 +vn -0.046800 -0.016400 -0.998700 +vn -0.107000 0.001400 -0.994200 +vn 0.319300 -0.050800 0.946300 +vn 0.017100 -0.999600 -0.022500 +vn 0.017100 -0.999800 -0.012600 +vn 0.028800 -0.999300 -0.024000 +vn 0.972000 0.064900 0.225800 +vn -0.132400 0.592300 -0.794700 +vn 0.377400 -0.882000 -0.282100 +vn 0.282500 -0.024500 0.958900 +vn 0.601200 0.128200 0.788700 +vn 0.833400 -0.072300 -0.547900 +vn 0.524000 -0.218900 0.823100 +vn -0.485900 0.809700 -0.328800 +vn -0.474800 0.841900 -0.256600 +vn -0.680200 0.471800 -0.560900 +vn 0.893100 -0.057800 -0.446100 +vn -0.103800 -0.036800 -0.993900 +vn 0.285600 0.375600 0.881700 +vn 0.956400 0.211700 -0.201100 +vn 0.402000 -0.353700 -0.844500 +vn 0.578000 0.260800 0.773200 +vn 0.992200 -0.123900 -0.007400 +vn -0.254700 0.800400 0.542600 +vn -0.629200 -0.777100 0.014400 +vn -0.029500 0.162100 -0.986300 +vn 0.306400 0.809100 0.501500 +vn -0.710900 0.617300 0.336800 +vn -0.737000 0.603000 0.305200 +vn -0.921900 0.321200 0.216400 +vn 0.836400 -0.142200 0.529300 +vn -0.148400 0.148200 -0.977700 +vn 0.039200 0.925400 -0.376900 +vn -0.711200 -0.682300 0.169100 +vn 0.850300 0.505100 -0.147400 +vn -0.023300 -0.074400 -0.996900 +vn -0.022900 -0.080000 -0.996500 +vn -0.028200 -0.032800 -0.999100 +vn -0.811700 0.439300 0.384800 +vn -0.956300 0.164800 0.241300 +vn -0.917600 0.270200 0.291500 +vn 0.933100 -0.348500 -0.088600 +vn -0.894300 -0.372100 0.248500 +vn -0.980800 0.133300 0.142500 +vn 0.941300 -0.320400 -0.106300 +vn 0.969100 -0.203300 -0.139400 +vn 0.999300 -0.036700 0.003500 +vn 0.993900 0.106900 -0.027800 +vn 0.955600 0.274200 0.107500 +vn -0.898300 -0.436400 -0.050500 +vn -0.524400 0.047900 0.850100 +vn -0.770200 0.208300 0.602800 +vn -0.655000 -0.323500 0.682800 +vn -0.734300 -0.610300 0.297000 +vn -0.974700 -0.108000 0.195400 +vn -0.380800 -0.588900 0.712900 +vn 0.030100 -0.999400 0.016700 +vn 0.032000 -0.999200 0.022100 +vn -0.889600 0.292100 0.351000 +vn -0.895400 -0.070500 0.439500 +vn -0.964200 0.058400 0.258600 +vn -0.910600 0.358100 0.206100 +vn -0.511300 0.555200 -0.656000 +vn -0.865900 0.473900 0.160300 +vn 0.992300 0.121900 0.020700 +vn -0.997500 0.062700 -0.032000 +vn 0.640600 0.189600 -0.744000 +vn -0.926700 -0.296800 -0.230300 +vn 0.671600 -0.225500 -0.705700 +vn 0.240000 -0.765500 0.596900 +vn 0.383200 -0.764000 0.519000 +vn 0.277900 -0.893700 0.352100 +vn -0.015900 -0.999300 0.034300 +vn -0.010700 -0.997900 0.063000 +vn 0.531000 0.099800 -0.841500 +vn 0.633400 0.168300 -0.755300 +vn 0.898200 0.261500 0.353300 +vn 0.926800 -0.201700 -0.316800 +vn -0.951200 -0.087200 -0.295900 +vn -0.937300 0.244000 0.248800 +vn -0.865200 0.278700 0.416800 +vn -0.662900 0.638500 -0.390900 +vn 0.957200 0.245600 0.153100 +vn 0.753100 -0.558500 -0.347500 +vn -0.855300 0.330900 -0.398700 +vn -0.863000 -0.315600 -0.394500 +vn 0.589500 -0.549500 -0.592000 +vn 0.366300 -0.866200 -0.339900 +vn 0.143600 0.801100 -0.581000 +vn 0.186600 0.804500 -0.563900 +vn 0.200800 0.835000 -0.512200 +vn 0.799400 -0.264500 -0.539300 +vn 0.796000 -0.022900 -0.604800 +vn 0.721100 -0.160000 -0.674100 +vn 0.761300 -0.463900 -0.453000 +vn 0.712300 -0.402900 -0.574700 +vn 0.460900 -0.431900 -0.775300 +vn 0.321700 -0.621800 -0.714000 +vn -0.912700 0.204700 -0.353500 +vn 0.753700 0.051200 -0.655200 +vn 0.727800 -0.061100 -0.683000 +vn 0.746500 -0.053500 -0.663100 +vn -0.004800 0.412500 -0.910900 +vn -0.878500 -0.323000 0.351900 +vn -0.735300 -0.520100 -0.434600 +vn -0.838400 0.543900 0.033600 +vn -0.840200 -0.533600 0.096400 +vn 0.856400 0.137900 -0.497500 +vn 0.739200 0.294900 -0.605500 +vn 0.107700 0.219000 -0.969700 +vn 0.008400 0.634100 -0.773200 +vn -0.099400 0.265900 -0.958800 +vn -0.364200 -0.583400 -0.725900 +vn -0.288200 -0.682100 -0.672000 +vn 0.601000 0.087000 -0.794500 +vn 0.681400 -0.015500 -0.731700 +vn 0.790700 0.275300 -0.546700 +vn 0.689700 0.190300 -0.698600 +vn 0.768700 0.260400 -0.584200 +vn -0.680400 -0.719400 0.139600 +vn -0.885900 -0.052000 -0.460900 +vn -0.845600 -0.295500 -0.444600 +vn 0.785000 -0.099900 -0.611400 +vn -0.940900 -0.046400 -0.335400 +vn 0.748400 -0.214900 -0.627400 +vn 0.813200 -0.222700 -0.537600 +vn 0.688000 -0.141800 -0.711700 +vn 0.642800 -0.136800 -0.753700 +vn 0.622600 -0.039100 -0.781500 +vn -0.895100 0.012600 -0.445600 +vn 0.179300 0.933200 -0.311400 +vn 0.171100 0.968600 -0.180400 +vn 0.273800 0.940500 -0.201400 +vn -0.021300 0.828800 -0.559100 +vn 0.001800 0.870900 -0.491500 +vn 0.015200 0.716800 -0.697100 +vn -0.300900 -0.534000 -0.790100 +vn -0.162500 -0.249600 -0.954600 +vn -0.183800 0.820800 0.540800 +vn 0.597100 -0.707700 0.377500 +vn 0.726100 -0.587300 0.357600 +vn -0.993100 -0.095900 0.067800 +vn -0.995900 0.079200 0.042800 +vn 0.696800 0.357100 -0.622000 +vn 0.824800 -0.310800 -0.472400 +vn 0.805800 -0.491600 -0.330100 +vn -0.976400 -0.134300 0.168700 +vn 0.562200 -0.798900 -0.213400 +vn -0.487000 -0.415200 0.768400 +vn -0.344200 -0.511200 0.787500 +vn -0.557700 0.628000 -0.542700 +vn -0.250300 0.623000 -0.741000 +vn -0.239500 0.901500 -0.360500 +vn -0.502800 0.760200 -0.411300 +vn 0.825600 0.004900 -0.564200 +vn 0.846500 -0.134400 -0.515100 +vn -0.683400 0.285800 -0.671700 +vn -0.547600 0.365600 -0.752600 +vn 0.878400 -0.227900 -0.420000 +vn 0.769000 -0.343500 -0.539100 +vn 0.719600 -0.650700 -0.242500 +vn 0.670900 -0.607900 -0.424600 +vn 0.538500 -0.789100 -0.295400 +vn -0.585300 0.710100 0.391300 +vn -0.892100 0.415800 0.176600 +vn 0.836300 -0.292700 -0.463500 +vn 0.416300 -0.511200 0.751900 +vn 0.572000 -0.796700 0.195000 +vn 0.392800 -0.907400 0.149200 +vn -0.391300 0.782000 0.485100 +vn -0.450000 0.766300 0.458500 +vn -0.959700 0.116800 -0.255600 +vn 0.023300 -0.962800 -0.269100 +vn 0.115200 -0.761000 -0.638400 +vn 0.111600 -0.936600 -0.332000 +vn 0.600500 0.029400 -0.799100 +vn 0.313800 0.097000 -0.944500 +vn -0.238900 -0.340500 -0.909400 +vn -0.609600 -0.342700 -0.714800 +vn -0.477200 0.878400 -0.027100 +vn -0.396400 0.860000 0.321200 +vn -0.704600 0.631400 0.323700 +vn -0.927900 -0.150400 -0.341200 +vn 0.182400 -0.789000 0.586700 +vn -0.861000 0.168200 -0.479900 +vn -0.786800 0.510900 -0.346200 +vn -0.683000 0.416200 -0.600200 +vn -0.212800 0.699500 -0.682200 +vn -0.124400 0.470400 -0.873600 +vn -0.335800 0.498400 -0.799300 +vn 0.665900 0.441500 -0.601300 +vn 0.607000 0.336900 -0.719700 +vn -0.717600 -0.656000 0.233900 +vn 0.926100 0.184800 0.328900 +vn -0.352200 -0.400300 0.846000 +vn -0.663400 -0.177700 0.726800 +vn -0.009900 0.332100 -0.943200 +vn -0.426700 -0.716400 -0.552000 +vn 0.239100 -0.444300 0.863300 +vn 0.605400 -0.021100 -0.795600 +vn -0.027800 -0.405300 -0.913800 +vn 0.001700 -0.376900 -0.926200 +vn 0.562200 -0.757700 0.331300 +vn -0.118000 0.688800 -0.715200 +vn 0.922500 0.341000 0.180800 +vn -0.807400 0.547000 -0.221000 +vn -0.652200 0.704000 0.280800 +vn 0.917500 -0.146800 -0.369700 +vn 0.847300 0.473500 0.240300 +vn -0.092400 0.903400 -0.418700 +vn 0.080300 0.891700 -0.445300 +vn 0.005900 0.848400 -0.529300 +vn 0.772500 -0.280900 -0.569500 +vn 0.303300 0.484600 -0.820500 +vn 0.596000 0.059100 -0.800800 +vn 0.190800 0.448100 -0.873300 +vn 0.645000 -0.113300 -0.755700 +vn -0.851100 0.399200 0.340900 +vn 0.807900 0.568300 -0.155800 +vn 0.475700 -0.236500 -0.847200 +vn -0.006000 -0.989600 0.143600 +vn 0.004900 -0.994900 0.100800 +vn -0.076400 -0.815700 0.573300 +vn -0.083900 -0.797000 0.598100 +vn 0.039200 -0.983500 0.176400 +vn -0.668100 -0.430800 -0.606700 +vn -0.573400 -0.565600 -0.592700 +vn -0.317300 -0.678200 -0.662800 +vn -0.973300 0.174900 -0.148700 +vn -0.904900 -0.398600 -0.149000 +vn -0.864400 -0.394500 -0.311600 +vn -0.175200 -0.323600 -0.929800 +vn 0.905200 0.320000 0.279600 +vn 0.185200 -0.456100 -0.870400 +vn 0.958200 0.120200 0.259700 +vn -0.232000 -0.627100 0.743600 +vn -0.405500 -0.814000 0.416000 +vn -0.280100 -0.791600 0.543100 +vn -0.505700 0.635600 0.583300 +vn 0.257900 0.433100 -0.863600 +vn 0.120200 0.515100 -0.848600 +vn 0.191200 0.686900 -0.701100 +vn 0.610100 0.118900 -0.783300 +vn 0.961000 0.160400 0.225100 +vn 0.678500 -0.722900 0.130700 +vn -0.289800 -0.269200 -0.918400 +vn -0.782700 -0.260700 -0.565100 +vn 0.922700 0.270800 0.274200 +vn 0.830500 0.458500 0.316100 +vn -0.756000 -0.575900 0.311000 +vn -0.863900 -0.386000 0.323500 +vn -0.795200 -0.562100 0.227200 +vn -0.164300 -0.207800 -0.964300 +vn -0.512900 -0.243100 -0.823300 +vn 0.630100 -0.688500 0.359100 +vn 0.056900 -0.982800 -0.175700 +vn -0.034800 -0.999100 -0.025100 +vn -0.076200 -0.904900 -0.418600 +vn 0.528500 -0.384500 -0.756900 +vn 0.811000 0.548800 0.202600 +vn -0.775100 -0.006800 -0.631700 +vn 0.559700 0.733800 0.385000 +vn 0.659200 0.747300 0.083400 +vn 0.641100 0.656100 0.398100 +vn 0.701200 0.710600 -0.057100 +vn -0.586900 -0.741800 -0.324500 +vn -0.510400 0.795700 0.326000 +vn 0.393500 0.879800 -0.266500 +vn 0.744300 0.667200 -0.026600 +vn 0.561000 0.796800 0.224300 +vn 0.306600 0.802500 0.511900 +vn -0.088300 0.990300 0.106900 +vn -0.076500 0.955800 0.283700 +vn -0.588100 0.799000 -0.124800 +vn 0.146100 0.935900 0.320500 +vn -0.000100 0.951700 0.307000 +vn 0.372300 0.914900 -0.156100 +vn 0.285700 0.957500 0.038700 +vn 0.207300 0.933400 0.292700 +vn -0.091900 0.907900 0.409000 +vn -0.222700 0.796000 0.562700 +vn 0.064100 0.996900 -0.043800 +vn -0.135200 0.986400 0.093200 +vn 0.058000 0.967000 -0.247900 +vn 0.216900 0.939700 0.264400 +vn -0.617900 0.422200 -0.663200 +vn 0.642400 0.765900 -0.028300 +vn 0.019300 0.413000 -0.910500 +vn 0.096800 0.995100 0.020000 +vn 0.263900 0.964100 -0.028900 +vn -0.840400 0.428400 -0.331900 +vn -0.419000 0.890400 -0.177800 +vn 0.161700 0.981000 0.107100 +vn 0.039200 0.980700 0.191600 +vn 0.045300 0.911300 0.409200 +vn 0.343800 0.876700 -0.336300 +vn 0.346300 0.924700 -0.158200 +vn 0.176500 0.961800 -0.209000 +vn -0.013000 0.998900 -0.045200 +vn -0.681000 0.526700 -0.508800 +vn 0.093200 0.987400 -0.128000 +vn 0.019200 0.998600 -0.049300 +vn -0.024700 0.999100 -0.034100 +vn 0.261100 0.965200 0.012800 +vn 0.404700 0.913900 -0.029400 +vn 0.177400 0.961300 0.210500 +vn 0.606100 0.727400 0.321700 +vn 0.045400 0.878800 0.474900 +vn -0.935800 -0.303900 0.178800 +vn -0.783100 0.520200 0.340600 +vn -0.457000 -0.596000 0.660300 +vn -0.888300 -0.179700 0.422500 +vn -0.705700 0.619200 -0.344200 +vn -0.916300 0.147100 -0.372400 +vn 0.517500 0.798600 0.307100 +vn 0.697100 0.572000 0.432200 +vn -0.025000 0.901100 0.432800 +vn -0.388000 0.915000 0.110200 +vn 0.176100 0.756300 -0.630000 +vn 0.005200 0.998500 0.054600 +vn 0.226800 0.952400 -0.203700 +vn 0.007700 0.943700 0.330700 +vn -0.710500 0.612100 0.347100 +vn -0.007500 0.930800 -0.365500 +vn -0.360500 -0.167200 -0.917600 +vn -0.986600 0.120500 0.110000 +vn 0.005600 0.821600 0.569900 +vn -0.558800 0.801000 -0.214800 +vn -0.879700 0.281000 0.383500 +vn -0.917800 0.378500 0.119700 +vn -0.989400 0.136500 0.049400 +vn -0.130400 0.954400 -0.268400 +vn 0.223900 0.970000 -0.094500 +vn -0.852400 0.507700 -0.124600 +vn 0.650900 0.592600 0.474400 +vn -0.520300 0.493900 -0.696600 +vn -0.552900 0.222800 -0.802900 +vn -0.777600 0.292700 -0.556400 +vn 0.813200 0.581800 -0.013900 +vn -0.849400 0.253400 0.462900 +vn -0.901500 0.305800 0.306200 +vn 0.760300 0.622200 0.186500 +vn -0.990200 -0.136000 -0.030600 +vn 0.771600 0.634100 0.049400 +vn -0.081600 -0.190300 -0.978300 +vn 0.041400 -0.337700 -0.940300 +vn -0.681100 0.732000 0.017000 +vn 0.762400 0.569900 -0.306500 +vn 0.535500 0.606200 0.588000 +vn 0.568100 0.712200 0.412300 +vn -0.593700 0.565200 0.572700 +vn -0.553800 0.771800 0.312500 +vn 0.048400 0.336500 -0.940400 +vn 0.014200 0.506700 -0.862000 +vn 0.233700 0.338100 -0.911600 +vn 0.748100 0.662900 -0.028000 +vn 0.697300 0.705000 0.129200 +vn 0.621300 0.728800 0.287800 +vn 0.751700 0.643800 -0.143300 +vn 0.673500 0.739200 0.006700 +vn 0.609800 0.780300 0.138900 +vn 0.654100 0.652600 -0.382300 +vn 0.720000 0.644200 -0.257900 +vn -0.895800 0.236700 -0.376100 +vn -0.077400 0.921500 -0.380500 +vn -0.491300 0.300100 -0.817600 +vn 0.645000 0.754400 -0.121200 +vn 0.516000 0.796900 0.314200 +vn 0.703400 0.584200 -0.404900 +vn -0.798100 -0.561800 0.217700 +vn 0.389500 0.841200 0.374900 +vn 0.031000 0.875300 0.482600 +vn 0.577500 0.814600 -0.053100 +vn 0.558600 0.828300 0.041700 +vn 0.470700 0.861700 0.189300 +vn 0.352400 0.802700 0.481000 +vn 0.572200 0.761400 -0.304600 +vn 0.561400 0.810900 -0.164700 +vn 0.431200 0.897200 0.095200 +vn 0.399100 0.876600 0.268800 +vn 0.490300 0.823800 -0.284500 +vn 0.019600 0.221000 -0.975100 +vn -0.739600 0.396000 -0.544200 +vn -0.776400 -0.241500 -0.582100 +vn -0.473200 -0.435200 -0.766000 +vn -0.844100 -0.536100 -0.010000 +vn -0.543000 0.644100 0.538800 +vn -0.855900 -0.324100 0.403000 +vn -0.974000 -0.005600 -0.226400 +vn -0.326500 -0.822700 0.465300 +vn -0.267300 -0.893100 0.361900 +vn -0.369200 0.801000 0.471200 +vn -0.490700 0.730700 0.474500 +vn -0.658400 0.528900 0.535400 +vn -0.349000 0.800100 0.487800 +vn -0.274300 0.648700 0.709900 +vn -0.420600 0.029200 0.906700 +vn -0.584500 -0.079300 -0.807500 +vn -0.327300 -0.075500 -0.941900 +vn -0.584900 0.239900 -0.774800 +vn -0.476700 0.679100 0.558200 +vn -0.814400 -0.360300 0.454800 +vn -0.686500 -0.332600 0.646500 +vn -0.813600 0.237700 0.530500 +vn -0.191600 -0.761900 -0.618700 +vn -0.802900 -0.320900 0.502300 +vn -0.805400 -0.325700 0.495300 +vn -0.849400 0.036000 0.526400 +vn -0.725500 0.445100 0.524800 +vn 0.156400 0.351800 -0.922900 +vn 0.020000 -0.999500 -0.021600 +vn 0.024600 -0.999300 -0.028900 +vn 0.048500 -0.998600 -0.020400 +vn -0.780100 0.447600 -0.437000 +vn -0.626000 0.460400 0.629300 +vn -0.546600 0.246700 0.800300 +vn -0.764700 -0.193600 0.614600 +vn -0.675000 0.435400 0.595700 +vn -0.416100 0.256200 -0.872500 +vn -0.694000 0.248800 0.675600 +vn -0.684900 0.710000 -0.163800 +vn -0.639900 -0.342000 0.688100 +vn -0.978100 0.119700 0.170300 +vn -0.914300 0.346000 0.210400 +vn -0.600000 0.375700 0.706200 +vn -0.724600 0.276000 0.631500 +vn -0.776600 -0.073100 0.625700 +vn -0.254600 0.068300 -0.964600 +vn -0.267700 0.194700 -0.943600 +vn -0.377500 0.111900 -0.919200 +vn -0.366600 -0.005000 -0.930400 +vn -0.346000 0.127900 -0.929400 +vn -0.359600 0.110400 -0.926500 +vn -0.786400 0.000000 -0.617700 +vn -0.624000 -0.243900 -0.742400 +vn -0.727700 -0.583000 0.361200 +vn -0.285600 -0.855700 0.431600 +vn -0.780500 0.231200 0.580800 +vn -0.977200 0.124200 0.172300 +vn -0.503000 0.717600 0.481700 +vn -0.231000 -0.827800 0.511200 +vn -0.616700 -0.374100 0.692600 +vn -0.836700 0.546000 -0.041400 +vn -0.577200 0.518700 0.630700 +vn -0.474500 0.651500 0.591900 +vn 0.538300 0.702200 -0.465900 +vn -0.280600 -0.259600 0.924000 +vn -0.503200 -0.174900 0.846200 +vn -0.506900 -0.074100 0.858800 +vn -0.968200 0.137700 -0.208700 +vn -0.160500 -0.088200 0.983100 +vn -0.654200 0.141800 0.742900 +vn -0.718100 0.070600 0.692300 +vn -0.929800 -0.231400 -0.286100 +vn -0.631000 -0.339900 0.697400 +vn -0.633000 -0.482300 0.605500 +vn -0.840400 0.408900 -0.355600 +vn -0.982000 -0.040300 -0.184700 +vn 0.175500 -0.549000 -0.817200 +vn 0.230000 -0.643900 -0.729600 +vn -0.641600 -0.161500 0.749800 +vn -0.370000 -0.332300 0.867600 +vn -0.753700 0.281900 0.593700 +vn -0.610800 -0.015100 0.791700 +vn -0.377100 0.191200 -0.906200 +vn -0.445500 0.340800 -0.827800 +vn -0.334900 0.329000 -0.882900 +vn -0.742300 -0.004700 0.670100 +vn -0.666700 -0.146100 0.730800 +vn -0.121600 -0.379900 0.917000 +vn -0.507500 -0.369300 -0.778400 +vn -0.060900 -0.581700 0.811100 +vn -0.036800 0.195600 -0.980000 +vn -0.068100 0.293900 -0.953400 +vn -0.930200 0.366600 0.015900 +vn -0.772800 0.621100 -0.130600 +vn -0.473100 0.148000 -0.868500 +vn -0.645500 0.270800 -0.714100 +vn -0.508000 0.203800 -0.836900 +vn -0.765700 0.390900 0.510800 +vn 0.284700 0.298800 -0.910800 +vn 0.435300 0.318600 -0.842000 +vn 0.406000 0.285700 -0.868000 +vn -0.717300 -0.679900 -0.152400 +vn -0.780000 0.125600 0.613100 +vn -0.586100 0.169300 -0.792300 +vn -0.873400 0.127400 0.470000 +vn -0.796700 0.402100 0.451200 +vn -0.738500 0.648100 0.185700 +vn -0.764100 0.151200 0.627100 +vn -0.308500 -0.275600 -0.910400 +vn -0.581700 0.391400 -0.713000 +vn -0.363400 0.090300 -0.927200 +vn -0.910500 -0.393400 0.127100 +vn -0.677800 0.106800 0.727400 +vn -0.382600 -0.921300 0.068600 +vn -0.881900 -0.224500 0.414600 +vn -0.844500 -0.076800 0.530000 +vn -0.825800 0.122600 0.550500 +vn -0.705700 0.373600 0.601900 +vn -0.706600 0.452300 -0.544100 +vn -0.740400 -0.289900 0.606400 +vn -0.839400 -0.170400 0.516100 +vn -0.775400 0.268600 0.571400 +vn -0.465700 -0.783100 -0.412100 +vn -0.604000 0.087600 0.792100 +vn -0.692700 0.377100 0.614700 +vn -0.768400 0.023700 0.639500 +vn -0.525300 0.001900 -0.850900 +vn -0.279900 -0.042300 -0.959100 +vn -0.131900 -0.205800 -0.969700 +vn -0.691700 0.162900 0.703500 +vn -0.098000 -0.889700 0.445900 +vn -0.129300 0.117000 -0.984600 +vn 0.459800 0.774800 -0.433900 +vn -0.634100 0.622300 0.458900 +vn -0.799000 -0.146600 0.583200 +vn -0.760800 -0.389100 0.519300 +vn -0.725500 0.218200 0.652600 +vn -0.368900 0.896400 -0.245500 +vn -0.711200 0.394700 0.581700 +vn -0.657100 0.538200 0.527700 +vn -0.609100 0.481300 0.630300 +vn -0.779600 -0.153100 0.607200 +vn -0.769500 0.071200 0.634600 +vn -0.752400 -0.359800 0.551700 +vn 0.154200 0.215400 -0.964300 +vn 0.180700 0.407500 -0.895100 +vn 0.139300 0.276800 -0.950800 +vn -0.357600 0.072400 -0.931000 +vn -0.597100 0.098300 -0.796100 +vn -0.520100 -0.015300 -0.854000 +vn -0.717100 -0.555200 0.421400 +vn 0.098500 -0.218600 -0.970800 +vn 0.226900 -0.590800 -0.774200 +vn 0.046100 0.211500 -0.976300 +vn -0.802900 0.092200 0.588800 +vn -0.009000 0.140600 -0.990000 +vn -0.606200 0.774300 0.181500 +vn -0.698500 -0.029200 -0.715000 +vn -0.565800 -0.147400 -0.811200 +vn -0.603900 -0.300800 -0.738100 +vn -0.421600 -0.003100 -0.906800 +vn -0.054400 -0.993600 0.098800 +vn 0.016800 -0.999800 -0.007100 +vn -0.382100 0.440900 -0.812200 +vn -0.357000 -0.638100 0.682100 +vn -0.024700 0.352800 -0.935300 +vn -0.629400 -0.444100 0.637700 +vn -0.567500 0.016000 -0.823200 +vn 0.334300 -0.509200 -0.793000 +vn -0.357800 -0.073400 -0.930900 +vn 0.330200 0.431100 -0.839700 +vn 0.358600 0.429900 -0.828600 +vn 0.329600 0.318200 -0.888900 +vn -0.089100 0.660500 -0.745500 +vn -0.028700 0.598700 -0.800400 +vn -0.038700 0.635700 -0.771000 +vn -0.443600 0.069400 -0.893500 +vn 0.119200 0.838600 -0.531400 +vn -0.051700 0.384600 -0.921600 +vn -0.199200 0.629000 -0.751500 +vn 0.109400 0.858500 -0.501000 +vn 0.162700 0.716500 -0.678400 +vn 0.108200 0.611900 -0.783500 +vn -0.045400 0.729300 -0.682700 +vn 0.142500 0.734200 -0.663800 +vn 0.306500 0.678800 -0.667300 +vn 0.391400 0.449800 -0.802800 +vn 0.555400 0.322900 -0.766300 +vn -0.861100 -0.286100 -0.420200 +vn -0.384800 0.590000 -0.709800 +vn -0.660100 -0.192300 -0.726100 +vn -0.651100 -0.517100 -0.555600 +vn -0.651800 -0.307500 -0.693200 +vn -0.462900 -0.366600 -0.807100 +vn -0.960300 0.009600 -0.278800 +vn -0.888800 -0.085600 -0.450200 +vn -0.450800 -0.655700 -0.605600 +vn -0.938500 -0.158900 -0.306400 +vn -0.525300 -0.607500 -0.595800 +vn -0.648100 -0.579300 -0.494400 +vn -0.982300 0.044800 -0.182000 +vn -0.965600 0.018100 -0.259300 +vn -0.718000 -0.572600 -0.395700 +vn -0.628100 0.751700 -0.200900 +vn -0.563700 -0.651500 -0.507800 +vn -0.938000 -0.271800 -0.215200 +vn -0.963700 -0.177800 -0.199200 +vn -0.642100 -0.656200 -0.396300 +vn -0.867800 -0.404400 -0.288700 +vn -0.019700 0.790200 -0.612600 +vn 0.280900 0.592500 -0.755000 +vn 0.272600 0.471000 -0.838900 +vn -0.486300 0.715500 -0.501600 +vn -0.546000 0.693000 -0.470700 +vn -0.299300 -0.935000 -0.190200 +vn -0.980300 0.132900 -0.145700 +vn -0.033900 0.612700 -0.789600 +vn 0.044400 0.486100 -0.872700 +vn -0.050300 0.723500 -0.688500 +vn -0.141400 -0.987900 0.063800 +vn -0.403100 -0.869900 0.284200 +vn -0.165200 -0.971600 0.169200 +vn -0.763200 -0.625500 0.162000 +vn -0.036000 -0.999100 -0.020300 +vn -0.370300 -0.899100 -0.233300 +vn -0.114400 0.725800 -0.678300 +vn -0.091600 0.377300 -0.921500 +vn -0.706700 -0.305700 -0.638000 +vn -0.732200 -0.282500 -0.619700 +vn -0.808000 -0.132200 -0.574100 +vn -0.846800 0.100400 -0.522300 +vn -0.897100 -0.393900 -0.200000 +vn 0.600800 0.475900 -0.642300 +vn 0.563700 0.324200 -0.759700 +vn -0.783800 -0.363000 -0.503700 +vn -0.863500 -0.295400 -0.408700 +vn -0.395600 0.779500 -0.485700 +vn -0.688100 0.568700 -0.450600 +vn -0.853700 0.336600 -0.397200 +vn -0.714000 -0.622100 -0.321100 +vn 0.178500 0.492000 -0.852000 +vn -0.054700 0.385400 -0.921100 +vn 0.126300 0.560800 -0.818200 +vn 0.124400 0.334800 -0.934000 +vn -0.865000 -0.300600 -0.401700 +vn -0.924800 -0.146600 -0.350900 +vn -0.890900 0.149200 -0.429000 +vn -0.995200 0.057200 0.079500 +vn -0.846500 -0.275500 -0.455500 +vn -0.931300 0.019000 -0.363600 +vn -0.903700 -0.345700 -0.252300 +vn -0.908100 -0.259800 -0.328400 +vn -0.910200 -0.276400 -0.308500 +vn -0.957600 -0.275500 -0.084000 +vn 0.127300 0.403000 -0.906300 +vn -0.815500 -0.139600 -0.561700 +vn -0.907300 -0.279800 -0.313800 +vn -0.860200 0.170900 -0.480500 +vn -0.889600 -0.298400 -0.345700 +vn -0.668900 0.234000 -0.705500 +vn -0.675800 0.489100 -0.551300 +vn -0.524100 0.527300 -0.668800 +vn -0.924100 -0.159800 -0.347000 +vn -0.793800 -0.442100 0.417500 +vn -0.615000 0.168900 -0.770200 +vn -0.695500 0.385800 -0.606100 +vn -0.705100 -0.612200 -0.357800 +vn 0.057300 0.138700 -0.988600 +vn 0.111800 -0.427700 -0.896900 +vn -0.254600 -0.914900 0.313000 +vn -0.159600 -0.986700 0.032000 +vn -0.003800 -0.997400 0.071400 +vn -0.975100 -0.207800 -0.077300 +vn 0.314000 0.794500 -0.519800 +vn 0.177400 0.797300 -0.576900 +vn -0.860900 0.361600 -0.357900 +vn -0.393600 0.854800 -0.338200 +vn -0.892800 -0.254600 -0.371400 +vn -0.320000 0.667300 -0.672400 +vn -0.750500 -0.643100 -0.151800 +vn -0.982900 0.166900 -0.077400 +vn -0.897600 -0.355100 -0.261200 +vn -0.956000 0.284100 -0.072500 +vn -0.612000 0.234200 -0.755400 +vn -0.605800 -0.060500 -0.793300 +vn -0.653800 0.176400 -0.735800 +vn -0.921700 0.265300 -0.282900 +vn 0.191300 -0.533900 -0.823600 +vn -0.810100 -0.526000 -0.259100 +vn -0.665400 0.594000 -0.452000 +vn -0.826300 0.504000 -0.251300 +vn -0.950600 0.173300 -0.257400 +vn -0.943900 -0.153900 -0.292200 +vn -0.257900 -0.537200 -0.803000 +vn -0.973800 -0.227500 0.002400 +vn 0.496000 0.361600 -0.789400 +vn 0.607100 0.193600 -0.770600 +vn -0.163500 0.327500 -0.930600 +vn -0.780600 -0.601600 -0.169400 +vn -0.809100 0.506700 -0.297600 +vn -0.941800 -0.117100 -0.315000 +vn 0.528600 0.617400 -0.582500 +vn 0.464100 0.545000 -0.698200 +vn 0.417900 0.502900 -0.756600 +vn 0.018600 -0.997300 0.070100 +vn -0.664800 -0.579900 -0.470800 +vn -0.602300 -0.524600 -0.601600 +vn -0.509700 -0.701200 -0.498500 +vn -0.608400 -0.770500 0.190100 +vn -0.986000 -0.126000 -0.109100 +vn -0.914400 0.290500 -0.281900 +vn -0.841800 0.396300 -0.366400 +vn 0.163900 0.244800 -0.955600 +vn 0.004400 0.720100 -0.693800 +vn -0.059400 0.714100 -0.697400 +vn 0.457800 0.496900 -0.737200 +vn 0.370700 0.521100 -0.768700 +vn -0.922700 -0.369900 -0.108100 +vn -0.600200 -0.364100 -0.712100 +vn -0.713900 -0.275900 -0.643600 +vn -0.565600 -0.142200 -0.812300 +vn -0.284400 -0.910800 0.299100 +vn -0.168200 0.863800 -0.474900 +vn -0.640400 0.677000 -0.362700 +vn 0.266300 0.853100 -0.448500 +vn -0.471600 -0.831300 -0.294200 +vn -0.549600 -0.770100 -0.323800 +vn -0.679000 -0.684700 -0.264600 +vn -0.948000 -0.191000 -0.254500 +vn -0.743200 -0.083400 -0.663900 +vn -0.741100 -0.022600 -0.671000 +vn -0.602500 0.057100 -0.796000 +vn -0.685800 0.176000 -0.706200 +vn -0.086500 0.560900 -0.823300 +vn -0.992300 -0.114700 -0.045400 +vn -0.860100 -0.197200 -0.470400 +vn -0.738800 0.212300 -0.639600 +vn -0.979700 -0.027500 -0.198400 +vn -0.090200 0.540300 -0.836600 +vn -0.752500 -0.149800 -0.641300 +vn -0.048300 0.928800 -0.367400 +vn 0.236300 0.846900 -0.476200 +vn 0.195600 -0.574600 -0.794700 +vn 0.206700 -0.061100 -0.976500 +vn 0.467400 0.165400 -0.868400 +vn 0.461400 0.433500 -0.774000 +vn 0.492700 0.412300 -0.766300 +vn 0.211100 -0.088000 -0.973500 +vn -0.800700 0.074000 -0.594400 +vn 0.354600 0.683900 -0.637600 +vn -0.705300 -0.425400 -0.567100 +vn 0.385400 0.382300 -0.839800 +vn 0.476800 0.214600 -0.852400 +vn 0.016000 0.681400 -0.731700 +vn 0.015100 -0.999800 -0.010700 +vn 0.154100 0.347800 -0.924800 +vn -0.978400 0.095700 -0.183000 +vn -0.090800 0.576800 -0.811800 +vn -0.171200 0.542500 -0.822400 +vn -0.751400 -0.332900 -0.569700 +vn -0.783300 -0.117100 -0.610400 +vn 0.022900 -0.999500 -0.022900 +vn -0.063800 0.635900 -0.769100 +vn -0.088600 0.674300 -0.733100 +vn -0.104300 0.778500 -0.618900 +vn 0.190500 0.274100 -0.942600 +vn -0.900400 -0.161300 -0.404100 +vn -0.672400 -0.325100 -0.665000 +vn -0.609900 -0.706000 -0.359900 +vn -0.793600 -0.298900 -0.529900 +vn 0.006200 0.516600 -0.856200 +vn -0.839000 -0.037500 -0.542800 +vn -0.866400 0.359300 -0.346800 +vn -0.809400 -0.429900 -0.399900 +vn -0.835900 -0.397500 -0.378500 +vn -0.898000 -0.046400 -0.437500 +vn -0.843800 0.158000 -0.512800 +vn -0.755100 0.283300 -0.591200 +vn -0.598100 0.312800 -0.737800 +vn -0.674700 0.717600 -0.172400 +vn -0.047900 0.697800 -0.714700 +vn -0.488100 -0.691200 -0.532900 +vn -0.589900 -0.701700 -0.399400 +vn -0.799300 0.245900 -0.548200 +vn -0.708100 -0.143100 -0.691400 +vn -0.878700 0.190900 -0.437400 +vn -0.735800 0.469500 -0.487900 +vn -0.414900 0.845700 -0.335700 +vn -0.577600 0.356000 -0.734600 +vn -0.656300 -0.675300 -0.336400 +vn -0.545700 -0.568400 -0.615600 +vn -0.693500 -0.662400 -0.283300 +vn -0.859200 -0.374600 -0.348500 +vn -0.915600 0.085800 -0.392700 +vn -0.788000 0.154600 -0.595900 +vn -0.912800 -0.140500 -0.383400 +vn -0.950300 0.021100 -0.310600 +vn -0.227600 0.764400 -0.603200 +vn 0.067500 -0.996800 0.043800 +vn -0.617200 0.171700 -0.767800 +vn -0.735100 0.541100 -0.408500 +vn -0.579500 0.780900 -0.233000 +vn -0.728500 -0.241000 -0.641200 +vn -0.863000 0.043400 -0.503400 +vn -0.668300 -0.020400 -0.743600 +vn -0.751000 0.188600 -0.632800 +vn 0.457100 0.248900 -0.853800 +vn 0.507900 0.273200 -0.816900 +vn -0.762300 0.406800 -0.503300 +vn -0.823000 -0.487600 -0.291300 +vn 0.556100 0.488600 -0.672300 +vn -0.753900 0.611800 -0.239400 +vn -0.683500 -0.683800 -0.255400 +vn 0.544000 0.105100 -0.832500 +vn 0.325000 0.408200 -0.853100 +vn 0.407300 0.153000 -0.900400 +vn 0.581400 0.581400 -0.569100 +vn -0.212500 0.798200 -0.563600 +vn -0.001100 0.799600 -0.600500 +vn 0.472600 0.636000 -0.610000 +vn 0.049500 0.420100 -0.906100 +vn 0.399700 0.758500 -0.514700 +vn 0.440700 0.608900 -0.659500 +vn 0.828900 0.109000 -0.548700 +vn -0.051300 -0.951100 0.304400 +vn -0.013900 -0.643800 0.765100 +vn 0.072500 -0.734400 0.674800 +vn -0.239600 -0.970800 -0.006000 +vn -0.241600 -0.956500 -0.163300 +vn 0.255200 0.451900 -0.854700 +vn 0.239100 0.658600 -0.713500 +vn 0.134200 0.568400 -0.811700 +vn -0.120500 0.879300 -0.460700 +vn 0.296100 0.671800 -0.678900 +vn 0.350100 0.690300 -0.633200 +vn 0.104000 0.526600 -0.843700 +vn 0.023100 -0.997200 0.070400 +vn 0.039300 0.516400 -0.855400 +vn 0.535000 0.424800 -0.730200 +vn -0.008400 0.411500 -0.911400 +vn -0.232600 -0.969500 -0.076600 +vn -0.219800 0.876900 -0.427500 +vn 0.557100 0.579700 -0.594700 +vn -0.298100 0.614700 -0.730200 +vn -0.260900 -0.955400 0.137900 +vn -0.001400 -0.999500 0.032400 +vn 0.327700 0.313600 -0.891200 +vn -0.369100 0.258600 -0.892700 +vn 0.121000 0.169100 -0.978100 +vn -0.015200 0.827800 -0.560900 +vn -0.267800 0.849400 -0.454800 +vn 0.277400 -0.554400 -0.784600 +vn 0.293600 0.345400 -0.891300 +vn 0.561700 0.270100 -0.781900 +vn 0.433500 0.189700 -0.880900 +vn -0.028500 0.351100 -0.935900 +vn 0.053000 0.436000 -0.898300 +vn -0.042300 0.416300 -0.908200 +vn -0.574400 -0.808600 -0.127100 +vn -0.125600 0.441200 -0.888600 +vn 0.575300 0.291800 -0.764100 +vn 0.093300 0.726000 -0.681300 +vn 0.143100 0.418800 -0.896700 +vn -0.099100 0.678300 -0.728000 +vn -0.204000 0.670800 -0.713000 +vn -0.233600 0.528300 -0.816300 +vn -0.322000 0.560300 -0.763100 +vn 0.174000 -0.190700 -0.966100 +vn 0.289000 0.283500 -0.914300 +vn 0.474700 0.382900 -0.792500 +vn 0.121800 0.682600 -0.720500 +vn 0.320600 0.193400 -0.927200 +vn 0.541100 0.613600 -0.575000 +vn -0.134000 0.520400 -0.843300 +vn -0.089400 0.771000 -0.630500 +vn -0.045200 0.438100 -0.897800 +vn -0.095200 0.641900 -0.760800 +vn -0.000300 0.666900 -0.745100 +vn 0.085200 0.883800 -0.460000 +vn 0.061000 0.486500 -0.871500 +vn 0.105700 0.760900 -0.640200 +vn -0.006600 0.465000 -0.885300 +vn 0.149000 0.871000 -0.468200 +vn -0.429600 -0.699200 0.571400 +vn 0.064600 0.140000 -0.988000 +vn 0.134900 0.552700 -0.822400 +vn 0.205400 -0.537500 0.817800 +vn 0.224900 0.610000 -0.759800 +vn 0.292000 0.810300 -0.508000 +vn 0.354300 0.098500 -0.929900 +vn -0.646200 -0.629800 -0.431000 +vn 0.227100 0.218400 -0.949100 +vn 0.093200 0.616500 -0.781800 +vn -0.022400 0.483500 -0.875000 +vn 0.513600 0.094600 -0.852700 +vn -0.532700 -0.201300 -0.822000 +vn -0.564000 -0.091300 -0.820700 +vn -0.463000 0.355400 -0.812000 +vn -0.262900 -0.110900 -0.958400 +vn -0.384900 -0.278000 -0.880100 +vn -0.305100 0.016800 -0.952100 +vn -0.412300 0.136600 -0.900700 +vn 0.432400 -0.238400 -0.869500 +vn -0.151600 0.299900 -0.941800 +vn -0.213200 0.381700 -0.899300 +vn 0.192000 -0.031400 -0.980900 +vn 0.048300 0.256000 -0.965500 +vn 0.260100 -0.315600 -0.912500 +vn -0.189200 -0.416600 -0.889200 +vn 0.521500 -0.018600 -0.853000 +vn -0.405500 -0.241300 -0.881600 +vn -0.425100 -0.221600 -0.877600 +vn -0.368700 0.180200 -0.911900 +vn -0.479100 -0.665500 -0.572300 +vn -0.319600 -0.601200 -0.732400 +vn -0.363600 -0.703000 -0.611200 +vn -0.501900 -0.101000 -0.859000 +vn -0.516300 -0.489100 -0.703000 +vn 0.122400 -0.315800 -0.940900 +vn -0.245700 0.230000 -0.941600 +vn -0.256600 0.182700 -0.949000 +vn -0.437700 0.147800 -0.886900 +vn 0.067000 -0.020300 -0.997500 +vn -0.093100 -0.492700 -0.865200 +vn -0.026600 -0.998400 -0.050500 +vn -0.231300 0.144800 -0.962000 +vn -0.285700 0.003200 -0.958300 +vn -0.288900 0.287400 -0.913200 +vn -0.123100 0.017100 -0.992200 +vn -0.464300 0.000300 -0.885600 +vn -0.050300 -0.341300 -0.938600 +vn -0.408100 -0.523100 -0.748200 +vn 0.118400 -0.218800 -0.968500 +vn -0.256600 -0.125300 -0.958300 +vn 0.068500 -0.427000 -0.901600 +vn -0.060400 0.358400 -0.931600 +vn 0.061600 -0.279900 -0.958000 +vn -0.331200 -0.379500 -0.863900 +vn 0.027900 -0.301400 -0.953100 +vn -0.356900 -0.721500 -0.593200 +vn -0.399900 -0.261600 -0.878400 +vn -0.249100 -0.298200 -0.921400 +vn -0.402100 -0.315400 -0.859600 +vn -0.107900 -0.313600 -0.943400 +vn -0.029600 -0.999000 0.034900 +vn -0.240100 -0.251600 -0.937600 +vn -0.011700 -0.141400 -0.989900 +vn -0.179300 -0.284100 -0.941900 +vn 0.328100 -0.358300 -0.874100 +vn 0.248700 0.254100 -0.934600 +vn -0.344200 -0.414900 -0.842200 +vn 0.607000 -0.128400 -0.784200 +vn 0.478100 0.035100 -0.877600 +vn -0.107600 0.237200 -0.965500 +vn 0.425200 -0.495500 -0.757400 +vn -0.261400 -0.363500 -0.894100 +vn 0.435600 0.053600 -0.898500 +vn 0.384900 -0.327200 -0.863000 +vn 0.421500 -0.114600 -0.899500 +vn 0.453700 -0.113800 -0.883800 +vn 0.407000 0.017100 -0.913200 +vn 0.392300 0.093400 -0.915000 +vn 0.345000 -0.421000 -0.838900 +vn 0.306700 -0.080300 -0.948400 +vn 0.292800 -0.183700 -0.938400 +vn -0.219300 0.288200 -0.932100 +vn 0.306400 -0.173600 -0.935900 +vn 0.416200 0.031200 -0.908700 +vn -0.639900 -0.746600 0.181700 +vn 0.307900 -0.352700 -0.883600 +vn 0.417400 0.069000 -0.906100 +vn -0.577000 -0.815800 0.038500 +vn -0.346700 -0.937900 0.005100 +vn 0.315700 -0.386000 -0.866800 +vn 0.237300 -0.219600 -0.946300 +vn 0.454400 -0.000400 -0.890800 +vn 0.203900 -0.205500 -0.957200 +vn 0.303600 -0.098400 -0.947700 +vn 0.461900 0.073600 -0.883800 +vn 0.096700 -0.247800 -0.963900 +vn 0.096000 -0.425700 -0.899700 +vn 0.186400 -0.456400 -0.870000 +vn 0.242900 -0.060700 -0.968100 +vn 0.271000 -0.248400 -0.929900 +vn 0.335300 -0.443100 -0.831400 +vn 0.110200 -0.192100 -0.975100 +vn 0.289100 -0.096500 -0.952400 +vn 0.164300 -0.080100 -0.983100 +vn 0.241400 -0.169900 -0.955400 +vn 0.267600 -0.258200 -0.928300 +vn 0.472500 -0.143100 -0.869600 +vn 0.355000 0.103600 -0.929100 +vn 0.278300 0.124300 -0.952400 +vn 0.203700 -0.349700 -0.914500 +vn 0.256700 -0.209700 -0.943400 +vn 0.361100 0.076700 -0.929300 +vn -0.042500 -0.214100 -0.975900 +vn 0.233900 -0.107900 -0.966200 +vn 0.255900 0.029800 -0.966200 +vn 0.212700 -0.634000 -0.743500 +vn 0.335600 -0.484600 -0.807800 +vn 0.295000 -0.229100 -0.927600 +vn 0.359700 0.139800 -0.922500 +vn 0.211300 -0.235700 -0.948500 +vn 0.211400 -0.175800 -0.961400 +vn 0.206100 -0.202600 -0.957300 +vn 0.213300 -0.303200 -0.928700 +vn 0.123800 -0.454200 -0.882300 +vn 0.296700 -0.044400 -0.953900 +vn 0.121500 -0.713600 -0.690000 +vn 0.222000 -0.266900 -0.937800 +vn 0.222300 -0.050800 -0.973600 +vn 0.125200 -0.126400 -0.984000 +vn 0.117300 -0.514600 -0.849400 +vn 0.228200 -0.155200 -0.961100 +vn 0.415400 0.034700 -0.909000 +vn 0.235800 -0.062200 -0.969800 +vn 0.142300 -0.074200 -0.987000 +vn 0.154100 -0.306700 -0.939200 +vn 0.227200 0.040600 -0.973000 +vn 0.165700 -0.281700 -0.945100 +vn 0.206600 -0.100800 -0.973200 +vn 0.224300 -0.175600 -0.958600 +vn 0.111000 -0.467400 -0.877000 +vn 0.006100 -0.513000 -0.858400 +vn 0.112300 -0.288000 -0.951000 +vn 0.188500 -0.144400 -0.971400 +vn -0.071900 -0.813500 0.577100 +vn 0.030600 -0.712100 -0.701400 +vn 0.083100 -0.435000 -0.896500 +vn 0.180400 -0.163500 -0.969900 +vn 0.200700 -0.235400 -0.950900 +vn 0.032900 -0.380000 -0.924400 +vn 0.160000 -0.281600 -0.946100 +vn 0.123800 -0.080800 -0.989000 +vn 0.255400 -0.171000 -0.951600 +vn 0.265600 -0.140100 -0.953800 +vn 0.123500 -0.038300 -0.991600 +vn 0.122800 0.009700 -0.992400 +vn -0.111300 -0.443100 -0.889500 +vn 0.104200 -0.321400 -0.941200 +vn 0.204200 -0.185300 -0.961200 +vn 0.859100 -0.507900 -0.063300 +vn -0.115700 -0.604600 0.788000 +vn -0.560300 -0.093800 -0.823000 +vn 0.116600 -0.044800 -0.992200 +vn 0.000800 -0.404300 -0.914600 +vn 0.068400 -0.282900 -0.956700 +vn 0.444100 -0.882500 0.154800 +vn 0.093800 -0.038800 -0.994800 +vn -0.044400 -0.104300 -0.993500 +vn -0.430700 -0.699100 -0.570700 +vn -0.189400 -0.467800 -0.863300 +vn -0.168300 -0.375000 -0.911600 +vn 0.351900 -0.833200 0.426400 +vn -0.072700 -0.177600 -0.981400 +vn 0.194600 -0.855200 0.480400 +vn -0.084800 -0.995000 -0.052000 +vn 0.039900 -0.977000 0.209600 +vn -0.343800 -0.393200 -0.852700 +vn -0.141800 -0.254200 -0.956700 +vn -0.078100 0.118000 -0.989900 +vn -0.492000 -0.151500 -0.857300 +vn -0.571200 -0.795500 -0.202300 +vn -0.754500 -0.441400 -0.485600 +vn -0.086900 -0.040400 -0.995400 +vn -0.182900 -0.134500 -0.973900 +vn -0.420200 -0.325700 -0.846900 +vn -0.424400 -0.862800 0.274600 +vn -0.345700 -0.195200 -0.917800 +vn -0.323300 -0.066100 -0.944000 +vn -0.288600 0.098600 -0.952300 +vn -0.286800 -0.543000 0.789200 +vn -0.243100 -0.860600 0.447500 +vn 0.050400 -0.997800 0.042600 +vn 0.105500 -0.991800 0.072100 +vn -0.207500 -0.978200 -0.001700 +vn -0.171500 -0.982500 -0.072200 +vn 0.137200 -0.940200 0.311800 +vn 0.013800 -0.999800 0.015700 +vn 0.177200 -0.560800 0.808700 +vn 0.034600 -0.999000 -0.029400 +vn -0.177700 -0.983800 0.022500 +vn 0.035300 -0.979000 0.200800 +vn -0.156400 -0.946200 0.283200 +vn -0.477100 -0.878200 -0.032700 +vn -0.191100 -0.909700 -0.368600 +vn 0.041800 -0.999100 0.008500 +vn 0.460300 -0.880200 0.115600 +vn -0.667500 -0.702700 0.246200 +vn -0.525400 -0.730900 0.435500 +vn -0.365400 -0.903700 0.222900 +vn -0.297600 -0.932200 0.205700 +vn -0.434100 -0.894000 0.110300 +vn 0.404600 -0.874300 0.268100 +vn -0.021500 -0.998300 0.054400 +vn 0.006600 -0.999900 0.004600 +vn -0.123400 -0.623400 0.772100 +vn -0.122900 -0.991400 -0.044900 +vn -0.634800 -0.771000 0.049700 +vn 0.088200 -0.948200 0.305200 +vn 0.062800 -0.958500 0.278000 +vn 0.227100 -0.968800 0.099100 +vn -0.025200 -0.999300 0.027800 +vn -0.430200 -0.873600 0.227600 +vn -0.441200 -0.888500 0.126500 +vn 0.183400 -0.982800 -0.021400 +vn 0.002000 -0.999300 -0.037800 +vn 0.031100 -0.999200 -0.022300 +vn -0.820500 -0.529000 -0.216500 +vn -0.154400 -0.968600 0.194700 +vn -0.490700 -0.860200 0.138800 +vn -0.483700 -0.870400 -0.091100 +vn -0.466600 -0.881200 0.076000 +vn 0.323600 -0.875700 0.358300 +vn 0.056700 -0.998400 0.002100 +vn 0.389800 -0.920800 -0.011300 +vn -0.624700 -0.780900 0.003400 +vn 0.260800 -0.951500 -0.163000 +vn 0.173200 -0.978500 0.112100 +vn -0.601500 -0.680600 0.418300 +vn 0.335200 -0.914800 0.225200 +vn -0.651000 -0.737500 -0.179600 +vn -0.892100 -0.451800 0.007400 +vn -0.698000 -0.714700 0.045800 +vn -0.663000 -0.703700 -0.255400 +vn -0.383600 -0.912900 -0.139300 +vn 0.068500 -0.997500 -0.013700 +vn 0.147700 -0.987400 -0.056600 +vn -0.472800 -0.881100 -0.007200 +vn -0.056800 -0.992400 0.109000 +vn -0.486800 -0.799800 0.351100 +vn -0.119400 -0.831400 0.542700 +vn -0.407000 -0.816600 0.409100 +vn -0.688200 -0.559800 0.461500 +vn -0.313100 -0.941000 0.128300 +vn 0.019000 -0.996100 0.085900 +vn 0.294000 -0.941200 0.166200 +vn 0.004000 -0.994400 0.105400 +vn -0.288100 -0.953400 0.089800 +vn -0.260600 -0.838200 0.479100 +vn -0.300400 -0.651100 0.696900 +vn -0.363600 -0.903800 0.225600 +vn -0.487600 -0.701600 0.519500 +vn -0.130200 -0.934100 0.332500 +vn 0.265400 -0.928300 0.260300 +vn 0.031400 -0.997000 0.070600 +vn -0.674100 -0.715500 0.183200 +vn -0.514500 -0.819600 -0.251800 +vn -0.705800 -0.628700 0.326400 +vn -0.582900 -0.806900 -0.095500 +vn -0.687900 -0.725800 0.006600 +vn -0.662700 -0.745200 0.073800 +vn -0.082600 -0.863000 0.498300 +vn -0.335100 -0.840100 0.426400 +vn -0.644600 -0.613200 0.456600 +vn -0.559700 -0.757600 0.335800 +vn -0.583800 -0.733800 0.347200 +vn 0.162800 -0.919900 0.356800 +vn -0.341000 -0.919300 -0.196400 +vn -0.447700 -0.892100 -0.060000 +vn -0.548900 -0.786800 0.282300 +vn -0.613500 -0.613700 0.496800 +vn -0.446900 -0.861500 -0.240900 +vn -0.185500 -0.982200 -0.028000 +vn -0.474800 -0.873000 0.111700 +vn -0.338600 -0.935800 -0.097800 +vn -0.317500 -0.948100 0.014500 +vn -0.361500 -0.904200 0.227500 +vn -0.458800 -0.749400 0.477300 +vn -0.035600 -0.999200 0.014700 +vn -0.380700 -0.856500 0.348500 +vn -0.475800 -0.668900 0.571200 +vn -0.494700 -0.532900 0.686500 +vn -0.134600 -0.987200 0.084800 +vn -0.423000 -0.803600 0.418600 +vn 0.234700 -0.971700 -0.026500 +vn -0.027900 -0.997200 -0.069000 +vn -0.003500 -1.000000 -0.006200 +vn -0.272500 -0.943400 0.188700 +vn -0.345900 -0.669500 0.657400 +vn -0.234300 -0.965000 0.117600 +vn -0.224800 -0.974200 0.018100 +vn -0.262800 -0.912900 0.312100 +vn -0.296900 -0.864200 0.406100 +vn -0.317800 -0.792000 0.521200 +vn 0.009800 -0.999900 -0.002300 +vn -0.041600 -0.998700 0.029100 +vn -0.232300 -0.750000 0.619300 +vn -0.236400 -0.629000 0.740500 +vn -0.050900 -0.996200 -0.069800 +vn -0.380700 -0.908700 -0.171500 +vn -0.020100 -0.999600 -0.016400 +vn 0.038600 -0.999200 0.009600 +vn 0.061100 -0.997800 -0.026100 +vn -0.080400 -0.996600 0.017900 +vn 0.027800 -0.999500 -0.017800 +vn -0.045400 -0.997200 0.059200 +vn -0.142500 -0.982700 0.118700 +vn -0.016900 -0.999000 0.042100 +vn -0.089600 -0.642700 0.760900 +vn 0.310800 -0.943500 0.114700 +vn 0.166700 -0.980300 0.105800 +vn -0.016900 -0.929500 0.368400 +vn 0.140400 -0.727700 0.671300 +vn -0.005700 -0.999500 0.029800 +vn -0.261800 -0.926300 0.270900 +vn 0.122600 -0.968400 0.217400 +vn 0.133200 -0.990500 -0.033300 +vn 0.542000 -0.738200 0.401600 +vn 0.778200 -0.610100 0.148600 +vn -0.190500 -0.571300 0.798300 +vn 0.189400 -0.734000 0.652200 +vn 0.370000 -0.799400 0.473200 +vn 0.389400 -0.904900 0.172000 +vn 0.020400 -0.888300 0.458800 +vn -0.402700 -0.710600 0.577000 +vn -0.019100 -0.995800 0.089600 +vn 0.015800 -0.999600 0.023700 +vn -0.024200 -0.663200 0.748000 +vn 0.092700 -0.989200 0.113800 +vn 0.070900 -0.997300 -0.020100 +vn 0.058300 -0.889400 0.453300 +vn -0.186800 -0.922800 0.337000 +vn -0.335400 -0.925500 0.175800 +s 1 +f 1//1 2//2 3//3 +f 4//4 5//5 6//6 +f 7//7 8//8 9//9 +f 10//10 11//11 12//12 +f 9//9 13//13 14//14 +f 15//15 16//16 17//17 +f 18//18 19//19 20//20 +f 21//21 22//22 23//23 +f 24//24 25//25 26//26 +f 27//27 28//28 29//29 +f 30//30 31//31 32//32 +f 33//33 34//34 35//35 +f 36//36 37//37 38//38 +f 19//19 39//39 20//20 +f 40//40 24//24 41//41 +f 42//42 43//43 44//44 +f 45//45 46//46 47//47 +f 48//48 49//49 50//50 +f 51//51 52//52 53//53 +f 54//54 55//55 42//42 +f 56//56 57//57 54//54 +f 58//58 59//59 60//60 +f 44//44 43//43 61//61 +f 62//62 63//63 64//64 +f 55//55 43//43 42//42 +f 65//65 66//66 67//67 +f 68//68 69//69 70//70 +f 71//71 72//72 73//73 +f 74//74 75//75 76//76 +f 77//77 78//78 79//79 +f 80//80 81//81 25//25 +f 82//82 83//83 73//73 +f 72//72 82//82 73//73 +f 84//84 85//85 86//86 +f 8//8 13//13 9//9 +f 87//87 88//88 89//89 +f 90//90 91//91 92//92 +f 93//93 94//94 6//6 +f 71//71 73//73 95//95 +f 96//96 97//97 98//98 +f 99//99 100//100 101//101 +f 49//49 57//57 56//56 +f 88//88 102//102 103//103 +f 104//104 68//68 105//105 +f 83//83 106//106 73//73 +f 106//106 83//83 18//18 +f 10//10 107//107 11//11 +f 108//108 7//7 66//66 +f 109//109 98//98 110//110 +f 111//111 73//73 112//112 +f 113//113 24//24 114//114 +f 115//115 60//60 46//46 +f 116//116 50//50 56//56 +f 46//46 60//60 47//47 +f 117//117 118//118 119//119 +f 111//111 112//112 120//120 +f 121//121 122//122 123//123 +f 124//124 59//59 125//125 +f 114//114 24//24 40//40 +f 39//39 65//65 126//126 +f 125//125 127//127 128//128 +f 129//129 130//130 131//131 +f 132//132 133//133 134//134 +f 43//43 135//135 61//61 +f 136//136 137//137 138//138 +f 131//131 139//139 140//140 +f 141//141 142//142 143//143 +f 115//115 58//58 60//60 +f 144//144 145//145 146//146 +f 147//147 148//148 149//149 +f 148//148 150//150 149//149 +f 150//150 151//151 149//149 +f 152//152 153//153 154//154 +f 97//97 155//155 156//156 +f 142//142 157//157 158//158 +f 23//23 159//159 21//21 +f 138//138 137//137 160//160 +f 59//59 124//124 60//60 +f 147//147 161//161 148//148 +f 162//162 163//163 164//164 +f 22//22 165//165 166//166 +f 61//61 135//135 167//167 +f 168//168 169//169 170//170 +f 171//171 118//118 117//117 +f 172//172 173//173 174//174 +f 175//175 176//176 177//177 +f 178//178 179//179 180//180 +f 181//181 148//148 161//161 +f 181//181 150//150 148//148 +f 182//182 162//162 151//151 +f 183//183 184//184 185//185 +f 186//186 26//26 187//187 +f 188//188 189//189 72//72 +f 50//50 49//49 56//56 +f 31//31 133//133 190//190 +f 104//104 105//105 191//191 +f 60//60 192//192 47//47 +f 193//193 106//106 194//194 +f 150//150 182//182 151//151 +f 195//195 163//163 162//162 +f 182//182 195//195 162//162 +f 196//196 197//197 198//198 +f 126//126 65//65 67//67 +f 154//154 10//10 12//12 +f 21//21 165//165 22//22 +f 199//199 112//112 193//193 +f 131//131 130//130 139//139 +f 200//200 201//201 161//161 +f 181//181 202//202 150//150 +f 150//150 203//203 182//182 +f 204//204 205//205 206//206 +f 207//207 208//208 209//209 +f 41//41 26//26 186//186 +f 68//68 70//70 105//105 +f 171//171 117//117 210//210 +f 211//211 1//1 212//212 +f 213//213 214//214 215//215 +f 216//216 217//217 63//63 +f 200//200 218//218 201//201 +f 150//150 202//202 203//203 +f 219//219 163//163 220//220 +f 221//221 222//222 117//117 +f 223//223 32//32 190//190 +f 224//224 225//225 226//226 +f 201//201 227//227 181//181 +f 227//227 202//202 181//181 +f 203//203 228//228 182//182 +f 195//195 220//220 163//163 +f 229//229 230//230 218//218 +f 231//231 232//232 233//233 +f 20//20 39//39 130//130 +f 234//234 190//190 132//132 +f 235//235 236//236 237//237 +f 182//182 228//228 195//195 +f 238//238 239//239 240//240 +f 241//241 242//242 243//243 +f 244//244 235//235 237//237 +f 39//39 126//126 130//130 +f 245//245 246//246 247//247 +f 218//218 227//227 201//201 +f 248//248 249//249 250//250 +f 251//251 241//241 243//243 +f 240//240 252//252 253//253 +f 241//241 254//254 242//242 +f 255//255 256//256 257//257 +f 82//82 258//258 19//19 +f 18//18 20//20 259//259 +f 260//260 261//261 262//262 +f 263//263 218//218 230//230 +f 263//263 227//227 218//218 +f 264//264 265//265 266//266 +f 228//228 267//267 195//195 +f 268//268 269//269 270//270 +f 254//254 271//271 272//272 +f 273//273 274//274 275//275 +f 276//276 277//277 278//278 +f 279//279 280//280 281//281 +f 4//4 136//136 5//5 +f 282//282 283//283 284//284 +f 285//285 261//261 260//260 +f 261//261 286//286 287//287 +f 286//286 288//288 287//287 +f 289//289 290//290 291//291 +f 292//292 293//293 294//294 +f 295//295 296//296 297//297 +f 298//298 227//227 299//299 +f 300//300 275//275 301//301 +f 302//302 303//303 304//304 +f 1//1 305//305 306//306 +f 307//307 95//95 111//111 +f 129//129 131//131 308//308 +f 309//309 286//286 261//261 +f 310//310 311//311 312//312 +f 313//313 314//314 315//315 +f 316//316 317//317 318//318 +f 319//319 320//320 321//321 +f 322//322 104//104 191//191 +f 323//323 324//324 325//325 +f 326//326 327//327 253//253 +f 145//145 322//322 191//191 +f 327//327 326//326 328//328 +f 113//113 25//25 24//24 +f 66//66 7//7 9//9 +f 188//188 72//72 329//329 +f 187//187 330//330 186//186 +f 120//120 199//199 331//331 +f 285//285 309//309 261//261 +f 332//332 333//333 334//334 +f 335//335 266//266 265//265 +f 336//336 337//337 313//313 +f 337//337 314//314 313//313 +f 336//336 313//313 338//338 +f 339//339 340//340 341//341 +f 254//254 272//272 342//342 +f 343//343 344//344 345//345 +f 242//242 342//342 243//243 +f 106//106 18//18 194//194 +f 346//346 347//347 348//348 +f 260//260 346//346 285//285 +f 349//349 350//350 351//351 +f 352//352 292//292 353//353 +f 354//354 355//355 266//266 +f 267//267 356//356 357//357 +f 358//358 359//359 273//273 +f 360//360 358//358 273//273 +f 189//189 108//108 258//258 +f 82//82 72//72 189//189 +f 7//7 361//361 8//8 +f 73//73 111//111 95//95 +f 362//362 363//363 364//364 +f 365//365 366//366 367//367 +f 368//368 366//366 347//347 +f 347//347 366//366 348//348 +f 369//369 346//346 348//348 +f 369//369 285//285 346//346 +f 369//369 309//309 285//285 +f 353//353 294//294 100//100 +f 292//292 294//294 353//353 +f 370//370 273//273 371//371 +f 372//372 373//373 374//374 +f 375//375 376//376 377//377 +f 335//335 354//354 266//266 +f 378//378 379//379 380//380 +f 381//381 382//382 383//383 +f 361//361 13//13 8//8 +f 372//372 384//384 385//385 +f 295//295 297//297 355//355 +f 386//386 387//387 388//388 +f 198//198 389//389 390//390 +f 391//391 392//392 393//393 +f 190//190 133//133 132//132 +f 394//394 395//395 396//396 +f 365//365 397//397 366//366 +f 366//366 398//398 348//348 +f 399//399 309//309 369//369 +f 400//400 401//401 402//402 +f 403//403 404//404 405//405 +f 406//406 372//372 385//385 +f 344//344 407//407 345//345 +f 408//408 409//409 410//410 +f 411//411 369//369 348//348 +f 398//398 411//411 348//348 +f 412//412 309//309 399//399 +f 412//412 413//413 309//309 +f 414//414 415//415 416//416 +f 335//335 265//265 337//337 +f 417//417 418//418 255//255 +f 69//69 419//419 420//420 +f 70//70 69//69 421//421 +f 9//9 14//14 422//422 +f 423//423 424//424 425//425 +f 426//426 427//427 428//428 +f 429//429 430//430 365//365 +f 430//430 397//397 365//365 +f 397//397 431//431 366//366 +f 366//366 431//431 398//398 +f 431//431 432//432 398//398 +f 411//411 399//399 369//369 +f 100//100 294//294 101//101 +f 433//433 376//376 375//375 +f 371//371 273//273 275//275 +f 434//434 413//413 412//412 +f 352//352 435//435 292//292 +f 66//66 9//9 67//67 +f 436//436 437//437 438//438 +f 439//439 397//397 430//430 +f 439//439 431//431 397//397 +f 398//398 432//432 411//411 +f 411//411 440//440 399//399 +f 413//413 434//434 441//441 +f 264//264 442//442 265//265 +f 352//352 290//290 443//443 +f 444//444 445//445 446//446 +f 447//447 448//448 449//449 +f 433//433 450//450 376//376 +f 451//451 452//452 453//453 +f 439//439 454//454 431//431 +f 455//455 337//337 336//336 +f 456//456 457//457 458//458 +f 124//124 125//125 459//459 +f 361//361 460//460 13//13 +f 461//461 462//462 463//463 +f 464//464 465//465 429//429 +f 432//432 466//466 411//411 +f 467//467 412//412 399//399 +f 467//467 434//434 412//412 +f 468//468 379//379 378//378 +f 450//450 469//469 470//470 +f 471//471 472//472 473//473 +f 474//474 349//349 351//351 +f 475//475 442//442 385//385 +f 101//101 376//376 476//476 +f 477//477 478//478 28//28 +f 479//479 175//175 480//480 +f 429//429 481//481 430//430 +f 430//430 481//481 439//439 +f 466//466 440//440 411//411 +f 482//482 434//434 467//467 +f 373//373 296//296 374//374 +f 483//483 484//484 485//485 +f 486//486 487//487 488//488 +f 442//442 406//406 385//385 +f 489//489 16//16 490//490 +f 491//491 492//492 13//13 +f 225//225 224//224 493//493 +f 494//494 495//495 245//245 +f 464//464 496//496 465//465 +f 465//465 497//497 429//429 +f 429//429 497//497 481//481 +f 481//481 498//498 439//439 +f 439//439 498//498 454//454 +f 454//454 466//466 431//431 +f 466//466 432//432 431//431 +f 440//440 499//499 399//399 +f 399//399 499//499 467//467 +f 434//434 500//500 441//441 +f 372//372 297//297 373//373 +f 501//501 447//447 502//502 +f 503//503 504//504 505//505 +f 489//489 506//506 16//16 +f 269//269 507//507 508//508 +f 17//17 16//16 509//509 +f 510//510 451//451 462//462 +f 511//511 497//497 465//465 +f 512//512 466//466 454//454 +f 466//466 512//512 440//440 +f 513//513 475//475 385//385 +f 514//514 505//505 515//515 +f 515//515 349//349 474//474 +f 516//516 517//517 447//447 +f 518//518 503//503 519//519 +f 517//517 520//520 521//521 +f 517//517 522//522 520//520 +f 523//523 524//524 525//525 +f 526//526 350//350 349//349 +f 527//527 528//528 529//529 +f 393//393 530//530 531//531 +f 532//532 533//533 534//534 +f 535//535 169//169 536//536 +f 497//497 537//537 481//481 +f 537//537 498//498 481//481 +f 512//512 454//454 498//498 +f 512//512 538//538 440//440 +f 440//440 538//538 499//499 +f 538//538 539//539 499//499 +f 539//539 467//467 499//499 +f 482//482 540//540 434//434 +f 540//540 541//541 500//500 +f 434//434 540//540 500//500 +f 414//414 400//400 415//415 +f 542//542 543//543 544//544 +f 545//545 546//546 547//547 +f 513//513 314//314 475//475 +f 519//519 503//503 505//505 +f 548//548 549//549 408//408 +f 465//465 550//550 511//511 +f 467//467 551//551 482//482 +f 551//551 540//540 482//482 +f 375//375 515//515 474//474 +f 378//378 380//380 552//552 +f 351//351 553//553 433//433 +f 352//352 353//353 290//290 +f 554//554 555//555 556//556 +f 550//550 537//537 511//511 +f 537//537 497//497 511//511 +f 557//557 498//498 537//537 +f 558//558 512//512 498//498 +f 559//559 538//538 512//512 +f 551//551 467//467 539//539 +f 351//351 547//547 560//560 +f 342//342 272//272 524//524 +f 290//290 353//353 561//561 +f 470//470 248//248 562//562 +f 563//563 564//564 565//565 +f 566//566 555//555 506//506 +f 567//567 488//488 35//35 +f 568//568 569//569 570//570 +f 557//557 558//558 498//498 +f 512//512 558//558 559//559 +f 551//551 571//571 540//540 +f 562//562 248//248 250//250 +f 502//502 449//449 416//416 +f 415//415 502//502 416//416 +f 572//572 501//501 400//400 +f 402//402 572//572 400//400 +f 501//501 516//516 447//447 +f 573//573 156//156 574//574 +f 73//73 106//106 112//112 +f 575//575 323//323 576//576 +f 577//577 578//578 579//579 +f 538//538 580//580 539//539 +f 580//580 581//581 539//539 +f 581//581 571//571 551//551 +f 539//539 581//581 551//551 +f 314//314 337//337 265//265 +f 582//582 414//414 583//583 +f 291//291 561//561 99//99 +f 544//544 584//584 585//585 +f 474//474 433//433 375//375 +f 586//586 587//587 588//588 +f 589//589 556//556 555//555 +f 590//590 591//591 556//556 +f 120//120 112//112 199//199 +f 592//592 550//550 593//593 +f 592//592 537//537 550//550 +f 557//557 559//559 558//558 +f 580//580 538//538 559//559 +f 594//594 540//540 571//571 +f 595//595 541//541 540//540 +f 473//473 596//596 597//597 +f 250//250 249//249 318//318 +f 589//589 598//598 556//556 +f 598//598 590//590 556//556 +f 83//83 19//19 18//18 +f 599//599 537//537 592//592 +f 600//600 557//557 537//537 +f 601//601 559//559 602//602 +f 601//601 580//580 559//559 +f 603//603 604//604 605//605 +f 455//455 606//606 337//337 +f 607//607 158//158 157//157 +f 566//566 608//608 555//555 +f 130//130 126//126 139//139 +f 599//599 600//600 537//537 +f 600//600 609//609 557//557 +f 557//557 609//609 559//559 +f 609//609 602//602 559//559 +f 580//580 601//601 581//581 +f 581//581 594//594 571//571 +f 541//541 610//610 611//611 +f 612//612 613//613 614//614 +f 615//615 450//450 470//470 +f 561//561 353//353 100//100 +f 28//28 616//616 617//617 +f 561//561 100//100 99//99 +f 142//142 618//618 157//157 +f 619//619 620//620 305//305 +f 608//608 621//621 589//589 +f 555//555 608//608 589//589 +f 621//621 598//598 589//589 +f 622//622 42//42 44//44 +f 623//623 624//624 625//625 +f 626//626 627//627 592//592 +f 627//627 599//599 592//592 +f 601//601 628//628 581//581 +f 629//629 594//594 581//581 +f 629//629 595//595 594//594 +f 594//594 595//595 540//540 +f 630//630 610//610 541//541 +f 631//631 405//405 632//632 +f 633//633 634//634 635//635 +f 636//636 637//637 618//618 +f 351//351 545//545 547//547 +f 118//118 212//212 119//119 +f 626//626 638//638 627//627 +f 628//628 629//629 581//581 +f 595//595 639//639 541//541 +f 639//639 640//640 541//541 +f 640//640 630//630 541//541 +f 641//641 321//321 642//642 +f 523//523 643//643 270//270 +f 501//501 644//644 516//516 +f 373//373 297//297 296//296 +f 604//604 619//619 305//305 +f 193//193 112//112 106//106 +f 194//194 18//18 259//259 +f 456//456 645//645 626//626 +f 645//645 638//638 626//626 +f 638//638 646//646 627//627 +f 646//646 599//599 627//627 +f 629//629 647//647 595//595 +f 595//595 647//647 639//639 +f 245//245 568//568 648//648 +f 649//649 468//468 650//650 +f 637//637 651//651 157//157 +f 618//618 637//637 157//157 +f 651//651 607//607 157//157 +f 198//198 197//197 652//652 +f 653//653 645//645 458//458 +f 654//654 599//599 646//646 +f 654//654 600//600 599//599 +f 654//654 609//609 600//600 +f 609//609 654//654 602//602 +f 628//628 655//655 629//629 +f 629//629 655//655 647//647 +f 79//79 78//78 656//656 +f 343//343 345//345 657//657 +f 658//658 450//450 615//615 +f 376//376 658//658 476//476 +f 542//542 650//650 543//543 +f 608//608 659//659 621//621 +f 660//660 661//661 653//653 +f 653//653 661//661 645//645 +f 645//645 662//662 638//638 +f 654//654 655//655 601//601 +f 602//602 654//654 601//601 +f 601//601 655//655 628//628 +f 657//657 345//345 663//663 +f 664//664 17//17 665//665 +f 666//666 667//667 668//668 +f 351//351 560//560 553//553 +f 659//659 669//669 621//621 +f 621//621 669//669 598//598 +f 670//670 653//653 598//598 +f 661//661 671//671 645//645 +f 646//646 672//672 654//654 +f 672//672 673//673 654//654 +f 673//673 655//655 654//654 +f 655//655 674//674 647//647 +f 675//675 641//641 676//676 +f 414//414 416//416 583//583 +f 376//376 450//450 658//658 +f 677//677 678//678 679//679 +f 208//208 680//680 681//681 +f 669//669 670//670 598//598 +f 645//645 682//682 662//662 +f 662//662 646//646 638//638 +f 662//662 672//672 646//646 +f 683//683 655//655 673//673 +f 683//683 674//674 655//655 +f 674//674 684//684 647//647 +f 684//684 685//685 647//647 +f 647//647 685//685 639//639 +f 639//639 686//686 640//640 +f 687//687 688//688 630//630 +f 689//689 690//690 691//691 +f 544//544 543//543 584//584 +f 692//692 693//693 651//651 +f 694//694 607//607 693//693 +f 695//695 696//696 697//697 +f 31//31 190//190 32//32 +f 698//698 669//669 659//659 +f 670//670 660//660 653//653 +f 671//671 682//682 645//645 +f 699//699 339//339 700//700 +f 692//692 701//701 693//693 +f 661//661 702//702 671//671 +f 662//662 703//703 672//672 +f 703//703 704//704 672//672 +f 672//672 704//704 673//673 +f 704//704 705//705 673//673 +f 705//705 706//706 673//673 +f 706//706 683//683 673//673 +f 707//707 674//674 683//683 +f 707//707 708//708 674//674 +f 708//708 684//684 674//674 +f 708//708 685//685 684//684 +f 685//685 686//686 639//639 +f 543//543 709//709 584//584 +f 253//253 710//710 711//711 +f 425//425 712//712 713//713 +f 211//211 212//212 118//118 +f 714//714 715//715 670//670 +f 716//716 660//660 670//670 +f 717//717 661//661 660//660 +f 717//717 702//702 661//661 +f 703//703 662//662 682//682 +f 718//718 703//703 682//682 +f 719//719 685//685 708//708 +f 687//687 640//640 686//686 +f 442//442 372//372 406//406 +f 720//720 560//560 721//721 +f 709//709 722//722 584//584 +f 723//723 701//701 692//692 +f 670//670 669//669 714//714 +f 715//715 716//716 670//670 +f 702//702 682//682 671//671 +f 724//724 704//704 703//703 +f 704//704 725//725 705//705 +f 705//705 726//726 706//706 +f 727//727 708//708 707//707 +f 686//686 685//685 687//687 +f 585//585 584//584 722//722 +f 606//606 335//335 337//337 +f 701//701 728//728 694//694 +f 693//693 701//701 694//694 +f 201//201 181//181 161//161 +f 728//728 387//387 729//729 +f 730//730 731//731 23//23 +f 716//716 717//717 660//660 +f 717//717 732//732 702//702 +f 733//733 703//703 718//718 +f 733//733 724//724 703//703 +f 724//724 725//725 704//704 +f 725//725 726//726 705//705 +f 734//734 99//99 735//735 +f 514//514 515//515 375//375 +f 733//733 725//725 724//724 +f 726//726 736//736 706//706 +f 727//727 719//719 708//708 +f 492//492 687//687 685//685 +f 317//317 696//696 318//318 +f 101//101 377//377 376//376 +f 587//587 313//313 315//315 +f 562//562 737//737 738//738 +f 28//28 617//617 29//29 +f 294//294 514//514 377//377 +f 24//24 26//26 41//41 +f 259//259 20//20 129//129 +f 20//20 130//130 129//129 +f 716//716 715//715 739//739 +f 740//740 717//717 716//716 +f 732//732 718//718 702//702 +f 718//718 682//682 702//702 +f 736//736 741//741 706//706 +f 706//706 741//741 683//683 +f 742//742 707//707 683//683 +f 743//743 744//744 477//477 +f 745//745 302//302 78//78 +f 740//740 732//732 717//717 +f 746//746 733//733 718//718 +f 746//746 725//725 733//733 +f 741//741 742//742 683//683 +f 742//742 747//747 707//707 +f 747//747 727//727 707//707 +f 748//748 749//749 644//644 +f 290//290 561//561 291//291 +f 713//713 750//750 425//425 +f 330//330 32//32 223//223 +f 739//739 740//740 716//716 +f 740//740 751//751 732//732 +f 751//751 718//718 732//732 +f 751//751 752//752 718//718 +f 718//718 752//752 746//746 +f 746//746 753//753 725//725 +f 753//753 754//754 726//726 +f 725//725 753//753 726//726 +f 726//726 754//754 736//736 +f 742//742 755//755 747//747 +f 747//747 719//719 727//727 +f 492//492 685//685 719//719 +f 756//756 326//326 757//757 +f 416//416 758//758 583//583 +f 709//709 552//552 483//483 +f 443//443 289//289 759//759 +f 760//760 729//729 761//761 +f 762//762 763//763 753//753 +f 736//736 754//754 741//741 +f 699//699 764//764 765//765 +f 483//483 552//552 484//484 +f 474//474 351//351 433//433 +f 377//377 514//514 375//375 +f 560//560 720//720 553//553 +f 2//2 1//1 211//211 +f 5//5 136//136 138//138 +f 766//766 193//193 194//194 +f 767//767 740//740 739//739 +f 768//768 767//767 739//739 +f 767//767 751//751 740//740 +f 331//331 362//362 364//364 +f 102//102 689//689 109//109 +f 741//741 755//755 742//742 +f 239//239 769//769 770//770 +f 771//771 317//317 772//772 +f 468//468 378//378 543//543 +f 666//666 562//562 738//738 +f 631//631 403//403 405//405 +f 65//65 108//108 66//66 +f 773//773 301//301 774//774 +f 570//570 775//775 776//776 +f 777//777 778//778 779//779 +f 767//767 780//780 751//751 +f 751//751 780//780 752//752 +f 781//781 747//747 755//755 +f 782//782 719//719 747//747 +f 783//783 782//782 747//747 +f 782//782 492//492 719//719 +f 784//784 785//785 786//786 +f 552//552 787//787 484//484 +f 225//225 493//493 788//788 +f 293//293 514//514 294//294 +f 475//475 265//265 442//442 +f 789//789 247//247 246//246 +f 790//790 767//767 768//768 +f 791//791 792//792 780//780 +f 793//793 794//794 795//795 +f 317//317 131//131 696//696 +f 449//449 448//448 796//796 +f 797//797 741//741 754//754 +f 741//741 797//797 755//755 +f 798//798 782//782 783//783 +f 799//799 492//492 782//782 +f 799//799 14//14 492//492 +f 515//515 504//504 526//526 +f 470//470 469//469 248//248 +f 266//266 355//355 264//264 +f 667//667 666//666 738//738 +f 505//505 504//504 515//515 +f 800//800 777//777 779//779 +f 801//801 802//802 323//323 +f 802//802 324//324 323//323 +f 522//522 517//517 803//803 +f 804//804 129//129 308//308 +f 362//362 766//766 805//805 +f 806//806 755//755 797//797 +f 755//755 806//806 781//781 +f 783//783 747//747 781//781 +f 799//799 422//422 14//14 +f 720//720 469//469 553//553 +f 355//355 372//372 442//442 +f 250//250 318//318 695//695 +f 468//468 543//543 650//650 +f 542//542 296//296 650//650 +f 553//553 469//469 450//450 +f 807//807 779//779 170//170 +f 800//800 808//808 777//777 +f 808//808 809//809 777//777 +f 42//42 622//622 54//54 +f 356//356 810//810 357//357 +f 811//811 783//783 781//781 +f 339//339 699//699 340//340 +f 812//812 632//632 813//813 +f 729//729 386//386 814//814 +f 815//815 814//814 816//816 +f 433//433 553//553 450//450 +f 807//807 170//170 817//817 +f 818//818 807//807 817//817 +f 819//819 779//779 807//807 +f 819//819 800//800 779//779 +f 820//820 821//821 822//822 +f 199//199 193//193 362//362 +f 132//132 134//134 823//823 +f 94//94 4//4 6//6 +f 13//13 824//824 491//491 +f 825//825 826//826 827//827 +f 781//781 828//828 811//811 +f 829//829 379//379 468//468 +f 722//722 483//483 485//485 +f 378//378 552//552 709//709 +f 154//154 12//12 830//830 +f 247//247 789//789 563//563 +f 317//317 308//308 131//131 +f 831//831 832//832 833//833 +f 811//811 798//798 783//783 +f 834//834 782//782 798//798 +f 835//835 226//226 473//473 +f 562//562 250//250 695//695 +f 519//519 836//836 837//837 +f 447//447 521//521 448//448 +f 472//472 835//835 473//473 +f 838//838 809//809 808//808 +f 809//809 838//838 839//839 +f 199//199 362//362 331//331 +f 193//193 766//766 362//362 +f 840//840 841//841 842//842 +f 54//54 622//622 56//56 +f 843//843 844//844 845//845 +f 846//846 811//811 828//828 +f 847//847 848//848 644//644 +f 641//641 319//319 321//321 +f 807//807 849//849 819//819 +f 819//819 849//849 800//800 +f 838//838 808//808 800//800 +f 850//850 851//851 852//852 +f 131//131 140//140 696//696 +f 331//331 364//364 853//853 +f 665//665 854//854 855//855 +f 856//856 325//325 208//208 +f 846//846 857//857 811//811 +f 857//857 798//798 811//811 +f 422//422 799//799 782//782 +f 834//834 422//422 782//782 +f 858//858 859//859 860//860 +f 695//695 318//318 696//696 +f 483//483 722//722 709//709 +f 380//380 861//861 862//862 +f 294//294 377//377 101//101 +f 807//807 863//863 849//849 +f 849//849 864//864 800//800 +f 864//864 838//838 800//800 +f 838//838 865//865 839//839 +f 189//189 866//866 108//108 +f 766//766 194//194 867//867 +f 868//868 494//494 596//596 +f 869//869 870//870 871//871 +f 749//749 517//517 516//516 +f 562//562 695//695 737//737 +f 585//585 722//722 872//872 +f 505//505 514//514 873//873 +f 179//179 159//159 731//731 +f 871//871 874//874 875//875 +f 804//804 308//308 771//771 +f 876//876 857//857 846//846 +f 877//877 834//834 798//798 +f 877//877 422//422 834//834 +f 878//878 879//879 880//880 +f 291//291 99//99 734//734 +f 862//862 881//881 552//552 +f 37//37 882//882 38//38 +f 864//864 865//865 838//838 +f 194//194 259//259 867//867 +f 259//259 129//129 804//804 +f 883//883 884//884 871//871 +f 870//870 883//883 871//871 +f 884//884 874//874 871//871 +f 362//362 805//805 363//363 +f 370//370 360//360 273//273 +f 351//351 350//350 545//545 +f 435//435 352//352 881//881 +f 862//862 552//552 380//380 +f 865//865 885//885 886//886 +f 887//887 888//888 883//883 +f 889//889 875//875 874//874 +f 889//889 890//890 875//875 +f 891//891 867//867 804//804 +f 892//892 893//893 894//894 +f 895//895 857//857 820//820 +f 895//895 798//798 857//857 +f 896//896 422//422 877//877 +f 896//896 67//67 422//422 +f 355//355 297//297 372//372 +f 400//400 502//502 415//415 +f 649//649 650//650 296//296 +f 338//338 313//313 587//587 +f 897//897 865//865 864//864 +f 849//849 897//897 864//864 +f 898//898 886//886 885//885 +f 885//885 899//899 898//898 +f 900//900 888//888 887//887 +f 888//888 901//901 883//883 +f 901//901 902//902 883//883 +f 902//902 884//884 883//883 +f 902//902 874//874 884//884 +f 903//903 889//889 874//874 +f 889//889 904//904 890//890 +f 1//1 905//905 906//906 +f 766//766 907//907 805//805 +f 908//908 877//877 798//798 +f 909//909 67//67 896//896 +f 910//910 523//523 270//270 +f 370//370 371//371 911//911 +f 517//517 521//521 447//447 +f 865//865 899//899 885//885 +f 912//912 901//901 888//888 +f 902//902 913//913 874//874 +f 821//821 820//820 857//857 +f 908//908 896//896 877//877 +f 378//378 709//709 543//543 +f 586//586 338//338 587//587 +f 400//400 501//501 502//502 +f 863//863 897//897 849//849 +f 897//897 914//914 865//865 +f 865//865 914//914 899//899 +f 616//616 343//343 311//311 +f 900//900 912//912 888//888 +f 912//912 915//915 901//901 +f 901//901 916//916 902//902 +f 916//916 913//913 902//902 +f 903//903 874//874 913//913 +f 771//771 308//308 317//317 +f 917//917 895//895 820//820 +f 917//917 918//918 895//895 +f 908//908 798//798 895//895 +f 918//918 908//908 895//895 +f 126//126 67//67 909//909 +f 545//545 919//919 546//546 +f 644//644 749//749 516//516 +f 447//447 449//449 502//502 +f 914//914 920//920 899//899 +f 920//920 534//534 899//899 +f 900//900 921//921 912//912 +f 921//921 915//915 912//912 +f 915//915 922//922 901//901 +f 901//901 922//922 916//916 +f 923//923 889//889 903//903 +f 923//923 904//904 889//889 +f 328//328 274//274 327//327 +f 484//484 443//443 485//485 +f 126//126 909//909 139//139 +f 355//355 442//442 264//264 +f 374//374 296//296 542//542 +f 787//787 443//443 484//484 +f 249//249 316//316 318//318 +f 648//648 570//570 776//776 +f 914//914 513//513 920//920 +f 867//867 259//259 804//804 +f 867//867 907//907 766//766 +f 913//913 924//924 903//903 +f 924//924 923//923 903//903 +f 925//925 240//240 327//327 +f 926//926 917//917 822//822 +f 926//926 667//667 917//917 +f 667//667 918//918 917//917 +f 697//697 909//909 896//896 +f 604//604 603//603 850//850 +f 863//863 587//587 897//897 +f 840//840 927//927 841//841 +f 734//734 904//904 923//923 +f 738//738 908//908 918//918 +f 737//737 896//896 908//908 +f 737//737 697//697 896//896 +f 384//384 372//372 374//374 +f 314//314 265//265 475//475 +f 787//787 352//352 443//443 +f 316//316 772//772 317//317 +f 587//587 315//315 897//897 +f 897//897 315//315 914//914 +f 854//854 928//928 509//509 +f 533//533 532//532 929//929 +f 542//542 921//921 929//929 +f 915//915 872//872 922//922 +f 922//922 485//485 916//916 +f 916//916 930//930 913//913 +f 930//930 924//924 913//913 +f 668//668 667//667 926//926 +f 738//738 737//737 908//908 +f 271//271 700//700 272//272 +f 881//881 352//352 787//787 +f 881//881 787//787 552//552 +f 315//315 513//513 914//914 +f 920//920 532//532 534//534 +f 921//921 585//585 915//915 +f 915//915 585//585 872//872 +f 485//485 930//930 916//916 +f 289//289 924//924 930//930 +f 289//289 923//923 924//924 +f 291//291 734//734 923//923 +f 931//931 822//822 932//932 +f 738//738 918//918 667//667 +f 140//140 909//909 697//697 +f 140//140 139//139 909//909 +f 848//848 748//748 644//644 +f 588//588 587//587 863//863 +f 532//532 542//542 929//929 +f 759//759 289//289 930//930 +f 923//923 289//289 291//291 +f 575//575 418//418 417//417 +f 933//933 822//822 931//931 +f 737//737 695//695 697//697 +f 699//699 765//765 340//340 +f 829//829 468//468 649//649 +f 315//315 314//314 513//513 +f 513//513 385//385 920//920 +f 920//920 384//384 532//532 +f 532//532 374//374 542//542 +f 921//921 544//544 585//585 +f 485//485 759//759 930//930 +f 743//743 28//28 27//27 +f 443//443 290//290 289//289 +f 920//920 385//385 384//384 +f 384//384 374//374 532//532 +f 542//542 544//544 921//921 +f 872//872 722//722 922//922 +f 722//722 485//485 922//922 +f 485//485 443//443 759//759 +f 93//93 934//934 94//94 +f 935//935 336//336 936//936 +f 615//615 470//470 562//562 +f 862//862 937//937 881//881 +f 938//938 814//814 386//386 +f 881//881 937//937 435//435 +f 607//607 694//694 939//939 +f 940//940 941//941 942//942 +f 943//943 944//944 945//945 +f 946//946 947//947 295//295 +f 948//948 949//949 950//950 +f 951//951 526//526 952//952 +f 226//226 225//225 473//473 +f 953//953 748//748 954//954 +f 955//955 956//956 957//957 +f 958//958 954//954 847//847 +f 448//448 959//959 960//960 +f 961//961 274//274 358//358 +f 962//962 659//659 963//963 +f 964//964 954//954 958//958 +f 958//958 847//847 965//965 +f 966//966 244//244 967//967 +f 968//968 969//969 970//970 +f 692//692 637//637 636//636 +f 952//952 526//526 504//504 +f 971//971 972//972 973//973 +f 974//974 975//975 976//976 +f 273//273 359//359 274//274 +f 977//977 978//978 945//945 +f 979//979 980//980 981//981 +f 641//641 982//982 676//676 +f 52//52 51//51 983//983 +f 202//202 984//984 203//203 +f 249//249 721//721 560//560 +f 968//968 985//985 986//986 +f 321//321 987//987 642//642 +f 988//988 989//989 990//990 +f 202//202 298//298 991//991 +f 991//991 984//984 202//202 +f 992//992 993//993 994//994 +f 299//299 995//995 298//298 +f 996//996 997//997 998//998 +f 999//999 845//845 546//546 +f 1000//1000 1001//1001 1002//1002 +f 970//970 1003//1003 985//985 +f 978//978 383//383 1004//1004 +f 413//413 1005//1005 288//288 +f 1006//1006 631//631 632//632 +f 1007//1007 965//965 1008//1008 +f 40//40 283//283 1009//1009 +f 1010//1010 995//995 299//299 +f 298//298 1011//1011 991//991 +f 448//448 521//521 520//520 +f 986//986 985//985 979//979 +f 383//383 382//382 1012//1012 +f 1013//1013 1014//1014 1015//1015 +f 1013//1013 1010//1010 1014//1014 +f 991//991 356//356 984//984 +f 978//978 1004//1004 1016//1016 +f 1017//1017 995//995 1010//1010 +f 991//991 1011//1011 356//356 +f 773//773 774//774 1018//1018 +f 1008//1008 1019//1019 1020//1020 +f 1021//1021 1010//1010 1013//1013 +f 1021//1021 1017//1017 1010//1010 +f 1017//1017 1022//1022 995//995 +f 995//995 1022//1022 298//298 +f 298//298 1022//1022 1011//1011 +f 1023//1023 958//958 1024//1024 +f 1023//1023 964//964 958//958 +f 1025//1025 1026//1026 1027//1027 +f 1028//1028 1029//1029 1030//1030 +f 546//546 845//845 547//547 +f 1031//1031 1032//1032 63//63 +f 1033//1033 1015//1015 1034//1034 +f 1035//1035 1013//1013 1015//1015 +f 1011//1011 1036//1036 356//356 +f 700//700 339//339 1037//1037 +f 964//964 1038//1038 953//953 +f 1039//1039 1040//1040 1041//1041 +f 1042//1042 1043//1043 1044//1044 +f 954//954 748//748 848//848 +f 953//953 1038//1038 1045//1045 +f 1033//1033 1035//1035 1015//1015 +f 1021//1021 1013//1013 1035//1035 +f 1022//1022 1046//1046 1011//1011 +f 1047//1047 1048//1048 1049//1049 +f 1050//1050 1051//1051 1052//1052 +f 1017//1017 1053//1053 1022//1022 +f 1036//1036 810//810 356//356 +f 1054//1054 1055//1055 1056//1056 +f 402//402 965//965 847//847 +f 956//956 1057//1057 957//957 +f 826//826 1058//1058 1059//1059 +f 847//847 954//954 848//848 +f 1017//1017 1021//1021 1053//1053 +f 1046//1046 1060//1060 1011//1011 +f 1011//1011 1060//1060 1036//1036 +f 1061//1061 292//292 435//435 +f 979//979 1062//1062 980//980 +f 1008//1008 965//965 1063//1063 +f 1064//1064 1065//1065 1066//1066 +f 1067//1067 1033//1033 1005//1005 +f 413//413 1067//1067 1005//1005 +f 1053//1053 1046//1046 1022//1022 +f 1068//1068 1051//1051 1039//1039 +f 1035//1035 1033//1033 1067//1067 +f 1060//1060 1069//1069 1036//1036 +f 1032//1032 1070//1070 1071//1071 +f 959//959 1072//1072 1025//1025 +f 1073//1073 1074//1074 1075//1075 +f 1076//1076 1077//1077 1078//1078 +f 1078//1078 1079//1079 1080//1080 +f 1079//1079 1081//1081 1080//1080 +f 1082//1082 1074//1074 1079//1079 +f 1083//1083 971//971 973//973 +f 1084//1084 1021//1021 1035//1035 +f 1084//1084 1085//1085 1021//1021 +f 1085//1085 1053//1053 1021//1021 +f 1053//1053 1086//1086 1046//1046 +f 1086//1086 1087//1087 1046//1046 +f 1046//1046 1087//1087 1060//1060 +f 1087//1087 1088//1088 1060//1060 +f 1060//1060 1088//1088 1069//1069 +f 1069//1069 1089//1089 1036//1036 +f 1089//1089 810//810 1036//1036 +f 1073//1073 1075//1075 1090//1090 +f 959//959 1025//1025 960//960 +f 910//910 243//243 523//523 +f 1074//1074 1073//1073 1079//1079 +f 1067//1067 1084//1084 1035//1035 +f 1091//1091 810//810 1089//1089 +f 1071//1071 1070//1070 1092//1092 +f 350//350 941//941 545//545 +f 504//504 503//503 952//952 +f 1085//1085 1093//1093 1053//1053 +f 1093//1093 1086//1086 1053//1053 +f 155//155 163//163 219//219 +f 1094//1094 489//489 490//490 +f 1095//1095 489//489 1094//1094 +f 251//251 243//243 910//910 +f 842//842 841//841 1096//1096 +f 951//951 941//941 350//350 +f 1097//1097 1062//1062 1003//1003 +f 1062//1062 979//979 1003//1003 +f 1098//1098 1099//1099 1100//1100 +f 1101//1101 1102//1102 1065//1065 +f 1103//1103 1104//1104 616//616 +f 441//441 1105//1105 1084//1084 +f 1067//1067 441//441 1084//1084 +f 1084//1084 1105//1105 1085//1085 +f 1106//1106 1107//1107 386//386 +f 969//969 968//968 1108//1108 +f 844//844 772//772 845//845 +f 845//845 772//772 547//547 +f 836//836 873//873 1061//1061 +f 1109//1109 999//999 546//546 +f 1110//1110 1086//1086 1093//1093 +f 1111//1111 1089//1089 1069//1069 +f 1111//1111 1112//1112 1089//1089 +f 1112//1112 1091//1091 1089//1089 +f 1091//1091 1113//1113 810//810 +f 576//576 325//325 856//856 +f 856//856 207//207 1114//1114 +f 1115//1115 1116//1116 1117//1117 +f 1105//1105 1118//1118 1085//1085 +f 1118//1118 1119//1119 1085//1085 +f 1085//1085 1119//1119 1093//1093 +f 1110//1110 1120//1120 1086//1086 +f 1121//1121 1087//1087 1086//1086 +f 1120//1120 1121//1121 1086//1086 +f 1122//1122 1087//1087 1121//1121 +f 1122//1122 1088//1088 1087//1087 +f 1123//1123 1069//1069 1088//1088 +f 1122//1122 1123//1123 1088//1088 +f 1069//1069 1123//1123 1111//1111 +f 1124//1124 1091//1091 1112//1112 +f 1091//1091 1124//1124 1113//1113 +f 764//764 1125//1125 765//765 +f 1126//1126 967//967 634//634 +f 1127//1127 1093//1093 1119//1119 +f 1093//1093 1127//1127 1110//1110 +f 1111//1111 1124//1124 1112//1112 +f 1128//1128 593//593 465//465 +f 566//566 489//489 1095//1095 +f 566//566 506//506 489//489 +f 608//608 566//566 1129//1129 +f 1100//1100 1099//1099 1130//1130 +f 1115//1115 1131//1131 1116//1116 +f 23//23 1132//1132 730//730 +f 1127//1127 1120//1120 1110//1110 +f 1120//1120 1122//1122 1121//1121 +f 1133//1133 713//713 712//712 +f 357//357 1113//1113 166//166 +f 1042//1042 1134//1134 1135//1135 +f 524//524 1037//1037 525//525 +f 518//518 1134//1134 503//503 +f 1136//1136 1076//1076 1080//1080 +f 1098//1098 1117//1117 1099//1099 +f 1120//1120 1137//1137 1122//1122 +f 1111//1111 1138//1138 1124//1124 +f 1139//1139 1140//1140 1141//1141 +f 342//342 524//524 523//523 +f 227//227 298//298 202//202 +f 1101//1101 1064//1064 1131//1131 +f 1061//1061 873//873 293//293 +f 240//240 239//239 252//252 +f 1142//1142 1047//1047 970//970 +f 463//463 1143//1143 1144//1144 +f 1049//1049 1062//1062 1097//1097 +f 1127//1127 1145//1145 1120//1120 +f 1138//1138 1146//1146 1124//1124 +f 1147//1147 1129//1129 1095//1095 +f 1057//1057 1148//1148 957//957 +f 836//836 519//519 873//873 +f 1149//1149 758//758 1082//1082 +f 1150//1150 409//409 1151//1151 +f 1152//1152 1041//1041 1153//1153 +f 1154//1154 1155//1155 956//956 +f 1062//1062 1156//1156 1154//1154 +f 1157//1157 1118//1118 1105//1105 +f 500//500 1157//1157 1105//1105 +f 1157//1157 1119//1119 1118//1118 +f 1123//1123 1122//1122 1111//1111 +f 1158//1158 1138//1138 1111//1111 +f 1147//1147 963//963 1129//1129 +f 263//263 1014//1014 1010//1010 +f 1159//1159 1051//1051 1068//1068 +f 1160//1160 1161//1161 446//446 +f 1047//1047 1049//1049 1097//1097 +f 970//970 1047//1047 1097//1097 +f 1134//1134 518//518 1162//1162 +f 1163//1163 1127//1127 1119//1119 +f 1127//1127 1163//1163 1145//1145 +f 1158//1158 1164//1164 1138//1138 +f 1138//1138 1164//1164 1146//1146 +f 681//681 1165//1165 209//209 +f 1166//1166 1153//1153 1167//1167 +f 382//382 388//388 1012//1012 +f 697//697 696//696 140//140 +f 873//873 514//514 293//293 +f 386//386 729//729 387//387 +f 935//935 1081//1081 1108//1108 +f 1162//1162 518//518 837//837 +f 349//349 515//515 526//526 +f 1064//1064 1066//1066 381//381 +f 938//938 825//825 1168//1168 +f 70//70 421//421 171//171 +f 1163//1163 1119//1119 1157//1157 +f 1145//1145 1137//1137 1120//1120 +f 1122//1122 1158//1158 1111//1111 +f 1169//1169 172//172 174//174 +f 1027//1027 1026//1026 1153//1153 +f 1153//1153 1170//1170 1171//1171 +f 1167//1167 1153//1153 1171//1171 +f 1172//1172 1173//1173 1174//1174 +f 1175//1175 490//490 16//16 +f 519//519 505//505 873//873 +f 1044//1044 952//952 503//503 +f 611//611 1157//1157 500//500 +f 1137//1137 1176//1176 1122//1122 +f 1177//1177 1102//1102 1178//1178 +f 942//942 1179//1179 940//940 +f 1154//1154 955//955 980//980 +f 253//253 1180//1180 710//710 +f 756//756 774//774 301//301 +f 1181//1181 1027//1027 1153//1153 +f 955//955 1154//1154 956//956 +f 1062//1062 1154//1154 980//980 +f 1044//1044 503//503 1134//1134 +f 938//938 1168//1168 814//814 +f 325//325 1126//1126 633//633 +f 1182//1182 1107//1107 1106//1106 +f 1183//1183 1184//1184 1185//1185 +f 1163//1163 1186//1186 1145//1145 +f 1186//1186 1187//1187 1145//1145 +f 1145//1145 1187//1187 1137//1137 +f 1137//1137 530//530 1176//1176 +f 1122//1122 1176//1176 1158//1158 +f 1165//1165 681//681 943//943 +f 1188//1188 1061//1061 937//937 +f 1171//1171 1170//1170 1189//1189 +f 1179//1179 942//942 1190//1190 +f 1182//1182 1066//1066 1107//1107 +f 1191//1191 1135//1135 1192//1192 +f 611//611 1163//1163 1157//1157 +f 1187//1187 530//530 1137//1137 +f 1117//1117 977//977 1099//1099 +f 1027//1027 1181//1181 1193//1193 +f 1194//1194 1179//1179 1190//1190 +f 1042//1042 1195//1195 1043//1043 +f 951//951 350//350 526//526 +f 968//968 970//970 985//985 +f 1196//1196 1146//1146 1164//1164 +f 160//160 1197//1197 144//144 +f 227//227 263//263 1010//1010 +f 1186//1186 1198//1198 1187//1187 +f 422//422 67//67 9//9 +f 1001//1001 1199//1199 1002//1002 +f 29//29 617//617 311//311 +f 1001//1001 919//919 1199//1199 +f 1047//1047 1200//1200 1048//1048 +f 1201//1201 605//605 1202//1202 +f 1190//1190 952//952 1044//1044 +f 1191//1191 1042//1042 1135//1135 +f 1203//1203 1171//1171 1204//1204 +f 1167//1167 1171//1171 1203//1203 +f 611//611 1205//1205 1163//1163 +f 1163//1163 1205//1205 1186//1186 +f 1187//1187 531//531 530//530 +f 586//586 1206//1206 338//338 +f 1081//1081 1073//1073 1207//1207 +f 1150//1150 410//410 409//409 +f 1207//1207 1073//1073 1090//1090 +f 836//836 1061//1061 1188//1188 +f 1195//1195 1190//1190 1043//1043 +f 1179//1179 1000//1000 940//940 +f 960//960 1027//1027 796//796 +f 826//826 825//825 1107//1107 +f 1042//1042 1044//1044 1134//1134 +f 1208//1208 1209//1209 1210//1210 +f 775//775 310//310 776//776 +f 1205//1205 1198//1198 1186//1186 +f 855//855 1211//1211 1212//1212 +f 966//966 1213//1213 244//244 +f 606//606 968//968 335//335 +f 381//381 388//388 382//382 +f 141//141 618//618 142//142 +f 758//758 1074//1074 1082//1082 +f 946//946 979//979 981//981 +f 1051//1051 1214//1214 1028//1028 +f 1204//1204 1189//1189 1192//1192 +f 1204//1204 1171//1171 1189//1189 +f 1215//1215 1216//1216 1217//1217 +f 1198//1198 531//531 1187//1187 +f 1218//1218 424//424 1219//1219 +f 936//936 336//336 338//338 +f 203//203 984//984 228//228 +f 1136//1136 936//936 338//338 +f 1039//1039 1051//1051 1040//1040 +f 1152//1152 1039//1039 1041//1041 +f 1218//1218 712//712 425//425 +f 935//935 1108//1108 455//455 +f 1064//1064 381//381 383//383 +f 1220//1220 1030//1030 1000//1000 +f 984//984 267//267 228//228 +f 1221//1221 1037//1037 1222//1222 +f 861//861 380//380 379//379 +f 1130//1130 944//944 681//681 +f 1223//1223 1195//1195 1191//1191 +f 1155//1155 1162//1162 956//956 +f 1213//1213 1224//1224 244//244 +f 1225//1225 1226//1226 1227//1227 +f 1063//1063 401//401 1019//1019 +f 1205//1205 611//611 610//610 +f 26//26 1228//1228 187//187 +f 1229//1229 1068//1068 1072//1072 +f 1206//1206 1230//1230 338//338 +f 1195//1195 1223//1223 1190//1190 +f 957//957 1148//1148 861//861 +f 964//964 35//35 1038//1038 +f 1001//1001 1150//1150 1151//1151 +f 1075//1075 1166//1166 1200//1200 +f 1231//1231 172//172 1232//1232 +f 1075//1075 1200//1200 1047//1047 +f 1079//1079 1073//1073 1081//1081 +f 448//448 960//960 796//796 +f 486//486 339//339 487//487 +f 339//339 341//341 487//487 +f 274//274 328//328 275//275 +f 681//681 944//944 943//943 +f 1030//1030 410//410 1150//1150 +f 1100//1100 635//635 812//812 +f 796//796 758//758 449//449 +f 1220//1220 1000//1000 1179//1179 +f 1233//1233 463//463 1234//1234 +f 1131//1131 383//383 978//978 +f 1166//1166 1167//1167 1200//1200 +f 495//495 1235//1235 245//245 +f 1000//1000 1002//1002 940//940 +f 1066//1066 1182//1182 1106//1106 +f 301//301 275//275 328//328 +f 300//300 1236//1236 371//371 +f 1041//1041 1040//1040 1170//1170 +f 582//582 1237//1237 414//414 +f 988//988 1238//1238 1239//1239 +f 1239//1239 1238//1238 817//817 +f 1238//1238 818//818 817//817 +f 1019//1019 401//401 1240//1240 +f 1241//1241 1242//1242 1243//1243 +f 945//945 978//978 1016//1016 +f 1188//1188 862//862 861//861 +f 81//81 1228//1228 1244//1244 +f 1245//1245 1246//1246 612//612 +f 1247//1247 861//861 379//379 +f 1099//1099 977//977 945//945 +f 1063//1063 402//402 401//401 +f 166//166 1248//1248 357//357 +f 1024//1024 1007//1007 1249//1249 +f 547//547 772//772 249//249 +f 1192//1192 1189//1189 1191//1191 +f 1064//1064 383//383 1131//1131 +f 567//567 964//964 1023//1023 +f 942//942 941//941 1190//1190 +f 1250//1250 1251//1251 1007//1007 +f 388//388 723//723 1012//1012 +f 1252//1252 1253//1253 1254//1254 +f 1255//1255 525//525 1221//1221 +f 1256//1256 1257//1257 341//341 +f 231//231 233//233 1258//1258 +f 749//749 748//748 1045//1045 +f 141//141 1132//1132 987//987 +f 987//987 1132//1132 642//642 +f 143//143 1132//1132 141//141 +f 1259//1259 1260//1260 232//232 +f 1261//1261 588//588 1238//1238 +f 892//892 894//894 1262//1262 +f 1263//1263 1264//1264 107//107 +f 293//293 292//292 1061//1061 +f 238//238 769//769 239//239 +f 986//986 354//354 335//335 +f 825//825 1265//1265 1168//1168 +f 388//388 387//387 723//723 +f 1040//1040 1223//1223 1191//1191 +f 1065//1065 1064//1064 1101//1101 +f 1178//1178 1102//1102 1101//1101 +f 772//772 316//316 249//249 +f 988//988 1261//1261 1238//1238 +f 1148//1148 1188//1188 861//861 +f 1018//1018 1068//1068 1229//1229 +f 1170//1170 1266//1266 1189//1189 +f 1170//1170 1191//1191 1266//1266 +f 272//272 700//700 1037//1037 +f 520//520 1229//1229 448//448 +f 1267//1267 141//141 987//987 +f 588//588 863//863 818//818 +f 1116//1116 1131//1131 978//978 +f 1051//1051 1220//1220 1052//1052 +f 862//862 1188//1188 937//937 +f 1040//1040 1191//1191 1170//1170 +f 1194//1194 1220//1220 1179//1179 +f 1008//1008 1250//1250 1007//1007 +f 675//675 256//256 319//319 +f 272//272 1037//1037 524//524 +f 946//946 981//981 947//947 +f 63//63 217//217 1031//1031 +f 1268//1268 1269//1269 1270//1270 +f 1249//1249 1023//1023 1024//1024 +f 1023//1023 1249//1249 567//567 +f 964//964 567//567 35//35 +f 933//933 926//926 822//822 +f 1000//1000 1030//1030 1150//1150 +f 114//114 1271//1271 113//113 +f 1072//1072 1026//1026 1025//1025 +f 1072//1072 1039//1039 1152//1152 +f 1272//1272 987//987 321//321 +f 1267//1267 618//618 141//141 +f 993//993 770//770 769//769 +f 251//251 910//910 1173//1173 +f 487//487 341//341 1257//1257 +f 572//572 847//847 501//501 +f 1075//1075 1193//1193 1181//1181 +f 1273//1273 1274//1274 1275//1275 +f 354//354 986//986 946//946 +f 423//423 750//750 1276//1276 +f 1126//1126 966//966 967//967 +f 1272//1272 1267//1267 987//987 +f 1267//1267 636//636 618//618 +f 27//27 310//310 775//775 +f 238//238 183//183 185//185 +f 1277//1277 1278//1278 1279//1279 +f 837//837 1188//1188 1148//1148 +f 402//402 847//847 572//572 +f 242//242 254//254 342//342 +f 63//63 1032//1032 1280//1280 +f 1072//1072 1068//1068 1039//1039 +f 1074//1074 1193//1193 1075//1075 +f 1026//1026 1072//1072 1152//1152 +f 981//981 829//829 947//947 +f 999//999 1281//1281 1282//1282 +f 919//919 1109//1109 546//546 +f 981//981 980//980 829//829 +f 1191//1191 1195//1195 1042//1042 +f 336//336 935//935 455//455 +f 413//413 441//441 1067//1067 +f 907//907 867//867 891//891 +f 1108//1108 968//968 455//455 +f 979//979 946//946 986//986 +f 641//641 642//642 982//982 +f 270//270 643//643 268//268 +f 1247//1247 1283//1283 861//861 +f 1050//1050 1052//1052 1223//1223 +f 1284//1284 233//233 407//407 +f 969//969 1142//1142 970//970 +f 1285//1285 1286//1286 1287//1287 +f 1288//1288 1183//1183 1185//1185 +f 985//985 1003//1003 979//979 +f 1289//1289 1068//1068 1018//1018 +f 1028//1028 1290//1290 1029//1029 +f 943//943 945//945 1016//1016 +f 286//286 309//309 413//413 +f 1116//1116 978//978 977//977 +f 1247//1247 379//379 829//829 +f 1220//1220 1194//1194 1052//1052 +f 1107//1107 825//825 938//938 +f 1283//1283 957//957 861//861 +f 1214//1214 1290//1290 1028//1028 +f 610//610 1198//1198 1205//1205 +f 1066//1066 1106//1106 381//381 +f 1291//1291 288//288 1005//1005 +f 960//960 1025//1025 1027//1027 +f 1018//1018 1292//1292 773//773 +f 1293//1293 1114//1114 1272//1272 +f 1294//1294 636//636 1267//1267 +f 1294//1294 1295//1295 636//636 +f 1296//1296 1297//1297 1298//1298 +f 185//185 769//769 238//238 +f 1261//1261 1299//1299 588//588 +f 387//387 728//728 723//723 +f 1151//1151 919//919 1001//1001 +f 1153//1153 1041//1041 1170//1170 +f 1204//1204 1192//1192 1156//1156 +f 1190//1190 951//951 952//952 +f 1082//1082 1078//1078 1077//1077 +f 1300//1300 1301//1301 1302//1302 +f 925//925 183//183 238//238 +f 344//344 1258//1258 1284//1284 +f 1283//1283 955//955 957//957 +f 1057//1057 837//837 1148//1148 +f 1090//1090 1075//1075 1047//1047 +f 1080//1080 935//935 936//936 +f 642//642 1132//1132 1303//1303 +f 1304//1304 1288//1288 1185//1185 +f 1051//1051 1050//1050 1040//1040 +f 1029//1029 410//410 1030//1030 +f 836//836 1188//1188 837//837 +f 243//243 342//342 523//523 +f 1293//1293 320//320 856//856 +f 1174//1174 270//270 1305//1305 +f 1299//1299 1306//1306 588//588 +f 1099//1099 945//945 944//944 +f 1189//1189 1266//1266 1191//1191 +f 1090//1090 1142//1142 1207//1207 +f 1136//1136 1080//1080 936//936 +f 1135//1135 1134//1134 1162//1162 +f 1052//1052 1194//1194 1223//1223 +f 1051//1051 1028//1028 1220//1220 +f 253//253 252//252 1180//1180 +f 1267//1267 1272//1272 1294//1294 +f 1307//1307 692//692 636//636 +f 1295//1295 1307//1307 636//636 +f 644//644 501//501 847//847 +f 1308//1308 360//360 370//370 +f 1051//1051 1159//1159 1214//1214 +f 980//980 1283//1283 1247//1247 +f 1166//1166 1181//1181 1153//1153 +f 1075//1075 1181//1181 1166//1166 +f 941//941 1199//1199 545//545 +f 1220//1220 1028//1028 1030//1030 +f 965//965 402//402 1063//1063 +f 1309//1309 1294//1294 1272//1272 +f 1237//1237 1240//1240 401//401 +f 271//271 764//764 700//700 +f 1310//1310 1311//1311 1312//1312 +f 692//692 651//651 637//637 +f 980//980 955//955 1283//1283 +f 1173//1173 910//910 1174//1174 +f 856//856 1114//1114 1293//1293 +f 360//360 1313//1313 358//358 +f 1309//1309 1272//1272 1114//1114 +f 1313//1313 961//961 358//358 +f 479//479 1314//1314 175//175 +f 1081//1081 1207//1207 1108//1108 +f 1207//1207 969//969 1108//1108 +f 926//926 666//666 668//668 +f 455//455 968//968 606//606 +f 1315//1315 1295//1295 1294//1294 +f 1004//1004 1307//1307 1295//1295 +f 1315//1315 1004//1004 1295//1295 +f 335//335 968//968 986//986 +f 1206//1206 586//586 588//588 +f 1306//1306 1206//1206 588//588 +f 937//937 1061//1061 435//435 +f 1101//1101 1131//1131 1115//1115 +f 956//956 1162//1162 1057//1057 +f 1090//1090 1047//1047 1142//1142 +f 1207//1207 1142//1142 969//969 +f 1192//1192 1155//1155 1156//1156 +f 1190//1190 941//941 951//951 +f 764//764 699//699 700//700 +f 1155//1155 1135//1135 1162//1162 +f 1200//1200 1167//1167 1048//1048 +f 448//448 1229//1229 959//959 +f 1223//1223 1194//1194 1190//1190 +f 1006//1006 632//632 812//812 +f 1114//1114 1165//1165 1309//1309 +f 1309//1309 1315//1315 1294//1294 +f 959//959 1229//1229 1072//1072 +f 1316//1316 1317//1317 613//613 +f 701//701 723//723 728//728 +f 1261//1261 988//988 950//950 +f 1151//1151 1109//1109 919//919 +f 275//275 300//300 371//371 +f 1204//1204 1156//1156 1062//1062 +f 812//812 813//813 1098//1098 +f 295//295 649//649 296//296 +f 1000//1000 1150//1150 1001//1001 +f 721//721 249//249 248//248 +f 321//321 320//320 1293//1293 +f 1318//1318 1307//1307 1004//1004 +f 1318//1318 692//692 1307//1307 +f 1318//1318 723//723 692//692 +f 1319//1319 1273//1273 663//663 +f 598//598 458//458 590//590 +f 953//953 1045//1045 748//748 +f 815//815 1320//1320 729//729 +f 818//818 863//863 807//807 +f 1048//1048 1204//1204 1062//1062 +f 1048//1048 1062//1062 1049//1049 +f 1117//1117 1116//1116 977//977 +f 1156//1156 1155//1155 1154//1154 +f 954//954 964//964 953//953 +f 796//796 1027//1027 1193//1193 +f 209//209 1165//1165 1114//1114 +f 1161//1161 1235//1235 1321//1321 +f 213//213 1322//1322 85//85 +f 1007//1007 1024//1024 965//965 +f 583//583 758//758 1149//1149 +f 1106//1106 386//386 388//388 +f 381//381 1106//1106 388//388 +f 1323//1323 610//610 688//688 +f 1324//1324 1325//1325 1326//1326 +f 1044//1044 1043//1043 1190//1190 +f 758//758 796//796 1074//1074 +f 1066//1066 1058//1058 1107//1107 +f 1115//1115 1327//1327 1101//1101 +f 1328//1328 213//213 85//85 +f 829//829 980//980 1247//1247 +f 1024//1024 958//958 965//965 +f 1065//1065 1058//1058 1066//1066 +f 1162//1162 837//837 1057//1057 +f 1080//1080 1081//1081 935//935 +f 1246//1246 1329//1329 826//826 +f 1048//1048 1203//1203 1204//1204 +f 555//555 554//554 16//16 +f 796//796 1193//1193 1074//1074 +f 1016//1016 1004//1004 1315//1315 +f 1318//1318 1012//1012 723//723 +f 1330//1330 136//136 4//4 +f 1331//1331 675//675 676//676 +f 1192//1192 1135//1135 1155//1155 +f 1107//1107 938//938 386//386 +f 1153//1153 1026//1026 1152//1152 +f 1040//1040 1050//1050 1223//1223 +f 1107//1107 1058//1058 826//826 +f 469//469 720//720 721//721 +f 1165//1165 943//943 1315//1315 +f 1309//1309 1165//1165 1315//1315 +f 943//943 1016//1016 1315//1315 +f 1332//1332 1333//1333 1334//1334 +f 288//288 286//286 413//413 +f 940//940 1002//1002 941//941 +f 1002//1002 1199//1199 941//941 +f 1076//1076 1078//1078 1080//1080 +f 729//729 1320//1320 761//761 +f 1003//1003 970//970 1097//1097 +f 566//566 1095//1095 1129//1129 +f 1167//1167 1203//1203 1048//1048 +f 658//658 926//926 933//933 +f 1335//1335 1336//1336 1337//1337 +f 383//383 1318//1318 1004//1004 +f 383//383 1012//1012 1318//1318 +f 545//545 1199//1199 919//919 +f 1338//1338 312//312 311//311 +f 1082//1082 1079//1079 1078//1078 +f 961//961 183//183 925//925 +f 80//80 1339//1339 81//81 +f 1340//1340 934//934 93//93 +f 1340//1340 93//93 133//133 +f 1341//1341 1342//1342 1343//1343 +f 1341//1341 1343//1343 789//789 +f 1344//1344 116//116 1345//1345 +f 1098//1098 1100//1100 812//812 +f 77//77 1346//1346 78//78 +f 421//421 118//118 171//171 +f 1347//1347 1348//1348 1349//1349 +f 1350//1350 1330//1330 1351//1351 +f 1349//1349 1352//1352 1094//1094 +f 133//133 93//93 134//134 +f 1353//1353 334//334 1354//1354 +f 1355//1355 1356//1356 1351//1351 +f 145//145 1357//1357 322//322 +f 322//322 1358//1358 68//68 +f 85//85 84//84 527//527 +f 1359//1359 85//85 527//527 +f 1305//1305 1172//1172 1174//1174 +f 68//68 1358//1358 1360//1360 +f 1361//1361 116//116 1344//1344 +f 304//304 303//303 1362//1362 +f 1363//1363 764//764 271//271 +f 160//160 146//146 1364//1364 +f 419//419 1201//1201 420//420 +f 1365//1365 974//974 976//976 +f 1366//1366 1367//1367 1368//1368 +f 1369//1369 1370//1370 1278//1278 +f 625//625 1371//1371 1372//1372 +f 1316//1316 1373//1373 1374//1374 +f 210//210 1375//1375 105//105 +f 1364//1364 146//146 191//191 +f 96//96 98//98 691//691 +f 851//851 96//96 691//691 +f 576//576 319//319 256//256 +f 303//303 1376//1376 1377//1377 +f 1374//1374 677//677 679//679 +f 1211//1211 1378//1378 276//276 +f 1339//1339 1287//1287 30//30 +f 310//310 1342//1342 776//776 +f 565//565 1379//1379 471//471 +f 1380//1380 1242//1242 1241//1241 +f 1378//1378 831//831 1381//1381 +f 237//237 1006//1006 634//634 +f 5//5 280//280 279//279 +f 1065//1065 1373//1373 1059//1059 +f 842//842 1096//1096 1382//1382 +f 1383//1383 1380//1380 1384//1384 +f 232//232 1274//1274 1273//1273 +f 1385//1385 1386//1386 1387//1387 +f 1388//1388 1389//1389 360//360 +f 1390//1390 1389//1389 1388//1388 +f 225//225 788//788 868//868 +f 1391//1391 1392//1392 1393//1393 +f 616//616 28//28 478//478 +f 813//813 1327//1327 1098//1098 +f 1394//1394 1383//1383 1384//1384 +f 1345//1345 564//564 563//563 +f 1345//1345 45//45 564//564 +f 134//134 1395//1395 823//823 +f 1396//1396 1397//1397 1398//1398 +f 320//320 576//576 856//856 +f 1177//1177 678//678 677//677 +f 1374//1374 1373//1373 677//677 +f 1399//1399 1304//1304 1185//1185 +f 1400//1400 1339//1339 80//80 +f 5//5 138//138 1401//1401 +f 247//247 563//563 565//565 +f 1365//1365 976//976 1208//1208 +f 854//854 591//591 1402//1402 +f 1339//1339 30//30 1403//1403 +f 1313//1313 1389//1389 1404//1404 +f 495//495 494//494 868//868 +f 312//312 1342//1342 310//310 +f 1404//1404 1405//1405 184//184 +f 1406//1406 1407//1407 1408//1408 +f 1361//1361 50//50 116//116 +f 523//523 525//525 643//643 +f 510//510 1409//1409 1410//1410 +f 973//973 972//972 1242//1242 +f 880//880 1411//1411 1412//1412 +f 690//690 852//852 691//691 +f 1373//1373 1065//1065 1177//1177 +f 1412//1412 878//878 880//880 +f 1413//1413 1414//1414 1415//1415 +f 1242//1242 972//972 1243//1243 +f 652//652 833//833 1416//1416 +f 1367//1367 582//582 583//583 +f 1364//1364 1375//1375 1417//1417 +f 1401//1401 138//138 1418//1418 +f 1419//1419 1388//1388 1308//1308 +f 312//312 1344//1344 1342//1342 +f 132//132 823//823 1420//1420 +f 1421//1421 1397//1397 1422//1422 +f 1423//1423 1424//1424 1425//1425 +f 1375//1375 210//210 1426//1426 +f 138//138 1364//1364 1418//1418 +f 1364//1364 191//191 1375//1375 +f 1356//1356 1350//1350 1351//1351 +f 1427//1427 1428//1428 1429//1429 +f 1430//1430 1431//1431 1432//1432 +f 1433//1433 1434//1434 1317//1317 +f 623//623 1390//1390 1388//1388 +f 904//904 734//734 1435//1435 +f 1436//1436 1437//1437 1077//1077 +f 1396//1396 1398//1398 1419//1419 +f 407//407 1319//1319 345//345 +f 1438//1438 1439//1439 1336//1336 +f 1419//1419 1308//1308 1396//1396 +f 1413//1413 1440//1440 1414//1414 +f 1361//1361 1344//1344 312//312 +f 634//634 1006//1006 812//812 +f 1178//1178 1101//1101 1327//1327 +f 358//358 274//274 359//359 +f 1389//1389 1313//1313 360//360 +f 1376//1376 303//303 302//302 +f 971//971 1441//1441 1442//1442 +f 1443//1443 1336//1336 603//603 +f 1444//1444 1384//1384 1380//1380 +f 564//564 47//47 1379//1379 +f 365//365 1445//1445 1446//1446 +f 1447//1447 827//827 1329//1329 +f 78//78 794//794 745//745 +f 1448//1448 1449//1449 1450//1450 +f 1397//1397 1396//1396 1451//1451 +f 1452//1452 1397//1397 1451//1451 +f 659//659 608//608 1129//1129 +f 1077//1077 1437//1437 1082//1082 +f 421//421 211//211 118//118 +f 1216//1216 1453//1453 1454//1454 +f 1422//1422 1452//1452 1455//1455 +f 210//210 117//117 222//222 +f 134//134 279//279 1395//1395 +f 1391//1391 1456//1456 1392//1392 +f 971//971 1442//1442 1457//1457 +f 1442//1442 1391//1391 1458//1458 +f 565//565 564//564 1379//1379 +f 1273//1273 1319//1319 233//233 +f 1459//1459 1178//1178 813//813 +f 81//81 1339//1339 187//187 +f 677//677 1373//1373 1177//1177 +f 789//789 1343//1343 563//563 +f 190//190 234//234 223//223 +f 1460//1460 1461//1461 1263//1263 +f 186//186 330//330 223//223 +f 620//620 1312//1312 306//306 +f 1422//1422 1455//1455 1462//1462 +f 1076//1076 1463//1463 1077//1077 +f 1457//1457 1442//1442 1458//1458 +f 1464//1464 1436//1436 1465//1465 +f 975//975 1456//1456 976//976 +f 1209//1209 976//976 1441//1441 +f 1466//1466 277//277 1467//1467 +f 134//134 6//6 279//279 +f 1468//1468 833//833 652//652 +f 1457//1457 1458//1458 972//972 +f 500//500 541//541 611//611 +f 1130//1130 680//680 635//635 +f 197//197 1468//1468 652//652 +f 1343//1343 1345//1345 563//563 +f 1339//1339 1403//1403 187//187 +f 1469//1469 1470//1470 1471//1471 +f 793//793 1376//1376 745//745 +f 975//975 1421//1421 1456//1456 +f 1472//1472 1473//1473 1392//1392 +f 927//927 1474//1474 1475//1475 +f 1476//1476 1477//1477 1478//1478 +f 605//605 604//604 1479//1479 +f 1034//1034 1015//1015 1480//1480 +f 813//813 1178//1178 1327//1327 +f 405//405 679//679 678//678 +f 1481//1481 1482//1482 1483//1483 +f 1//1 3//3 305//305 +f 623//623 1388//1388 1419//1419 +f 1479//1479 604//604 3//3 +f 1437//1437 1149//1149 1082//1082 +f 1484//1484 1485//1485 1486//1486 +f 1487//1487 1415//1415 1488//1488 +f 1473//1473 1393//1393 1392//1392 +f 1413//1413 1415//1415 185//185 +f 64//64 63//63 1280//1280 +f 1489//1489 113//113 1271//1271 +f 1159//1159 1490//1490 1214//1214 +f 1491//1491 200//200 1492//1492 +f 1407//1407 1493//1493 1408//1408 +f 1469//1469 1494//1494 1470//1470 +f 1397//1397 1452//1452 1422//1422 +f 1495//1495 1206//1206 1306//1306 +f 1418//1418 1364//1364 1417//1417 +f 1496//1496 1423//1423 1425//1425 +f 1497//1497 1498//1498 840//840 +f 1437//1437 1499//1499 1149//1149 +f 1059//1059 612//612 1246//1246 +f 1407//1407 1500//1500 1493//1493 +f 1501//1501 50//50 1361//1361 +f 389//389 652//652 1416//1416 +f 972//972 1458//1458 1276//1276 +f 1502//1502 1503//1503 277//277 +f 1452//1452 1451//1451 1504//1504 +f 1451//1451 1308//1308 370//370 +f 675//675 319//319 641//641 +f 1375//1375 1426//1426 1417//1417 +f 842//842 1497//1497 840//840 +f 975//975 974//974 1425//1425 +f 676//676 982//982 1505//1505 +f 961//961 1404//1404 184//184 +f 1415//1415 994//994 185//185 +f 1452//1452 1504//1504 1455//1455 +f 1506//1506 1507//1507 1508//1508 +f 1503//1503 197//197 196//196 +f 196//196 1467//1467 277//277 +f 1208//1208 976//976 1209//1209 +f 274//274 961//961 925//925 +f 196//196 277//277 1503//1503 +f 280//280 5//5 1401//1401 +f 1383//1383 1509//1509 1380//1380 +f 1510//1510 1511//1511 1512//1512 +f 975//975 1425//1425 1513//1513 +f 327//327 240//240 253//253 +f 657//657 1361//1361 312//312 +f 878//878 1412//1412 1398//1398 +f 1398//1398 623//623 1419//1419 +f 1201//1201 1443//1443 603//603 +f 603//603 1514//1514 851//851 +f 1501//1501 48//48 50//50 +f 1514//1514 96//96 851//851 +f 1293//1293 1272//1272 321//321 +f 239//239 770//770 1515//1515 +f 449//449 758//758 416//416 +f 1316//1316 1059//1059 1373//1373 +f 1516//1516 1509//1509 1383//1383 +f 1517//1517 1518//1518 1519//1519 +f 1369//1369 1520//1520 1521//1521 +f 1412//1412 623//623 1398//1398 +f 1243//1243 1276//1276 750//750 +f 1241//1241 1243//1243 750//750 +f 1241//1241 750//750 1133//1133 +f 565//565 471//471 247//247 +f 664//664 855//855 1212//1212 +f 961//961 184//184 183//183 +f 1144//1144 1328//1328 1359//1359 +f 1456//1456 1462//1462 1392//1392 +f 1424//1424 1398//1398 1397//1397 +f 1394//1394 1384//1384 1471//1471 +f 1388//1388 360//360 1308//1308 +f 274//274 925//925 327//327 +f 1401//1401 1418//1418 1522//1522 +f 1523//1523 858//858 1524//1524 +f 6//6 5//5 279//279 +f 1425//1425 1424//1424 1513//1513 +f 878//878 1398//1398 1424//1424 +f 852//852 619//619 850//850 +f 345//345 1319//1319 663//663 +f 1525//1525 1526//1526 445//445 +f 1412//1412 624//624 623//623 +f 663//663 1501//1501 1361//1361 +f 657//657 663//663 1361//1361 +f 41//41 186//186 1527//1527 +f 1381//1381 1468//1468 1502//1502 +f 2//2 1479//1479 3//3 +f 3//3 604//604 305//305 +f 905//905 1//1 306//306 +f 971//971 1457//1457 972//972 +f 1451//1451 370//370 1504//1504 +f 271//271 1511//1511 1363//1363 +f 774//774 1289//1289 1018//1018 +f 306//306 1312//1312 905//905 +f 1313//1313 1404//1404 961//961 +f 1243//1243 972//972 1276//1276 +f 1210//1210 1209//1209 1441//1441 +f 1343//1343 1342//1342 1344//1344 +f 1115//1115 1117//1117 1098//1098 +f 1338//1338 657//657 312//312 +f 1210//1210 1441//1441 971//971 +f 1528//1528 1524//1524 858//858 +f 795//795 794//794 1346//1346 +f 1509//1509 1242//1242 1380//1380 +f 1441//1441 1391//1391 1442//1442 +f 568//568 570//570 648//648 +f 1529//1529 1029//1029 1290//1290 +f 1421//1421 1422//1422 1456//1456 +f 1471//1471 1470//1470 1530//1530 +f 185//185 994//994 769//769 +f 1513//1513 1424//1424 1397//1397 +f 1531//1531 1164//1164 1158//1158 +f 1396//1396 1308//1308 1451//1451 +f 1532//1532 1533//1533 1534//1534 +f 234//234 132//132 1420//1420 +f 1490//1490 1290//1290 1214//1214 +f 1490//1490 1529//1529 1290//1290 +f 1529//1529 410//410 1029//1029 +f 1515//1515 252//252 239//239 +f 1471//1471 1530//1530 1394//1394 +f 1535//1535 277//277 1466//1466 +f 1273//1273 1275//1275 663//663 +f 1133//1133 750//750 713//713 +f 967//967 237//237 634//634 +f 1536//1536 1537//1537 1538//1538 +f 1441//1441 976//976 1391//1391 +f 1455//1455 1539//1539 1462//1462 +f 1275//1275 1501//1501 663//663 +f 1202//1202 1479//1479 2//2 +f 1275//1275 48//48 1501//1501 +f 1531//1531 1196//1196 1164//1164 +f 1433//1433 1317//1317 679//679 +f 1462//1462 1539//1539 1472//1472 +f 1434//1434 613//613 1317//1317 +f 1456//1456 1422//1422 1462//1462 +f 1509//1509 973//973 1242//1242 +f 1513//1513 1397//1397 1421//1421 +f 421//421 1202//1202 2//2 +f 1540//1540 1159//1159 1289//1289 +f 1540//1540 1490//1490 1159//1159 +f 1540//1540 1529//1529 1490//1490 +f 548//548 410//410 1529//1529 +f 1541//1541 643//643 1255//1255 +f 1474//1474 1542//1542 1543//1543 +f 1544//1544 1176//1176 1545//1545 +f 1544//1544 1531//1531 1176//1176 +f 525//525 1037//1037 1221//1221 +f 209//209 1114//1114 207//207 +f 976//976 1456//1456 1391//1391 +f 975//975 1513//1513 1421//1421 +f 421//421 69//69 1202//1202 +f 1546//1546 1547//1547 1548//1548 +f 69//69 420//420 1202//1202 +f 711//711 1529//1529 1540//1540 +f 710//710 548//548 1529//1529 +f 1531//1531 1303//1303 1196//1196 +f 1303//1303 1132//1132 1196//1196 +f 1504//1504 911//911 1455//1455 +f 1547//1547 80//80 1548//1548 +f 1545//1545 530//530 1505//1505 +f 27//27 570//570 569//569 +f 1547//1547 1400//1400 80//80 +f 774//774 1540//1540 1289//1289 +f 711//711 710//710 1529//1529 +f 253//253 711//711 326//326 +f 1549//1549 217//217 1550//1550 +f 1542//1542 1549//1549 1550//1550 +f 35//35 488//488 1257//1257 +f 614//614 1245//1245 612//612 +f 518//518 519//519 837//837 +f 1007//1007 1251//1251 1249//1249 +f 1177//1177 1459//1459 678//678 +f 295//295 355//355 946//946 +f 1059//1059 1058//1058 1065//1065 +f 311//311 343//343 1338//1338 +f 757//757 711//711 1540//1540 +f 613//613 1434//1434 614//614 +f 1504//1504 370//370 911//911 +f 982//982 1544//1544 1545//1545 +f 925//925 238//238 240//240 +f 1020//1020 1541//1541 1551//1551 +f 1551//1551 1541//1541 1250//1250 +f 1249//1249 486//486 567//567 +f 269//269 1305//1305 270//270 +f 757//757 1540//1540 774//774 +f 643//643 525//525 1255//1255 +f 81//81 1244//1244 25//25 +f 305//305 620//620 306//306 +f 1552//1552 1553//1553 1554//1554 +f 1474//1474 1543//1543 1475//1475 +f 944//944 1130//1130 1099//1099 +f 982//982 1545//1545 1505//1505 +f 642//642 1531//1531 1544//1544 +f 1531//1531 642//642 1303//1303 +f 1531//1531 1158//1158 1176//1176 +f 1250//1250 1221//1221 1251//1251 +f 567//567 486//486 488//488 +f 1555//1555 973//973 1509//1509 +f 268//268 643//643 1541//1541 +f 328//328 756//756 301//301 +f 1174//1174 910//910 270//270 +f 116//116 1556//1556 1345//1345 +f 803//803 517//517 749//749 +f 1541//1541 1255//1255 1250//1250 +f 1250//1250 1255//1255 1221//1221 +f 756//756 328//328 326//326 +f 554//554 854//854 509//509 +f 1222//1222 339//339 486//486 +f 1343//1343 1344//1344 1345//1345 +f 982//982 642//642 1544//1544 +f 1550//1550 217//217 1557//1557 +f 1221//1221 1222//1222 1251//1251 +f 1251//1251 486//486 1249//1249 +f 487//487 1257//1257 488//488 +f 756//756 757//757 774//774 +f 326//326 711//711 757//757 +f 710//710 1180//1180 548//548 +f 1180//1180 549//549 548//548 +f 1037//1037 339//339 1222//1222 +f 676//676 1505//1505 392//392 +f 1251//1251 1222//1222 486//486 +f 11//11 1558//1558 12//12 +f 1559//1559 1560//1560 1274//1274 +f 11//11 107//107 55//55 +f 60//60 124//124 1561//1561 +f 963//963 1147//1147 1139//1139 +f 1562//1562 495//495 868//868 +f 1563//1563 1460//1460 107//107 +f 23//23 22//22 1196//1196 +f 192//192 60//60 1561//1561 +f 10//10 1563//1563 107//107 +f 1379//1379 192//192 472//472 +f 598//598 653//653 458//458 +f 1560//1560 48//48 1274//1274 +f 1045//1045 1038//1038 34//34 +f 1560//1560 12//12 48//48 +f 1556//1556 45//45 1345//1345 +f 1564//1564 1331//1331 1565//1565 +f 765//765 1256//1256 341//341 +f 810//810 1113//1113 357//357 +f 1256//1256 1566//1566 33//33 +f 1567//1567 34//34 33//33 +f 1566//1566 1567//1567 33//33 +f 1567//1567 1045//1045 34//34 +f 1568//1568 103//103 1569//1569 +f 1570//1570 36//36 38//38 +f 170//170 169//169 817//817 +f 765//765 1252//1252 1256//1256 +f 401//401 414//414 1237//1237 +f 1571//1571 1572//1572 1248//1248 +f 45//45 115//115 46//46 +f 1252//1252 1573//1573 1256//1256 +f 1573//1573 1574//1574 1256//1256 +f 1256//1256 1574//1574 1566//1566 +f 1574//1574 1575//1575 1566//1566 +f 1566//1566 1575//1575 1567//1567 +f 1257//1257 1256//1256 33//33 +f 418//418 576//576 256//256 +f 1575//1575 1576//1576 1567//1567 +f 459//459 125//125 128//128 +f 1577//1577 760//760 761//761 +f 1567//1567 1576//1576 803//803 +f 1254//1254 1573//1573 1252//1252 +f 1578//1578 1574//1574 1573//1573 +f 1574//1574 1579//1579 1575//1575 +f 1575//1575 1579//1579 1576//1576 +f 1569//1569 573//573 574//574 +f 1580//1580 1578//1578 1573//1573 +f 1579//1579 1574//1574 1578//1578 +f 1579//1579 1581//1581 1576//1576 +f 1576//1576 522//522 803//803 +f 39//39 258//258 65//65 +f 1311//1311 87//87 128//128 +f 1581//1581 522//522 1576//1576 +f 1292//1292 1229//1229 522//522 +f 1292//1292 522//522 1581//1581 +f 1581//1581 1579//1579 1578//1578 +f 773//773 1292//1292 1581//1581 +f 845//845 999//999 1282//1282 +f 22//22 1146//1146 1196//1196 +f 689//689 98//98 109//109 +f 1438//1438 1336//1336 1443//1443 +f 1268//1268 1582//1582 1269//1269 +f 137//137 136//136 1330//1330 +f 1583//1583 1578//1578 1580//1580 +f 1236//1236 1583//1583 1580//1580 +f 1583//1583 1581//1581 1578//1578 +f 1581//1581 1583//1583 773//773 +f 133//133 31//31 1286//1286 +f 729//729 760//760 728//728 +f 1351//1351 1330//1330 4//4 +f 105//105 171//171 210//210 +f 1571//1571 1248//1248 166//166 +f 934//934 1351//1351 94//94 +f 1351//1351 4//4 94//94 +f 1092//1092 1584//1584 1071//1071 +f 300//300 301//301 1583//1583 +f 1583//1583 301//301 773//773 +f 1146//1146 22//22 1113//1113 +f 1577//1577 38//38 694//694 +f 1585//1585 159//159 179//179 +f 731//731 159//159 23//23 +f 166//166 1113//1113 22//22 +f 868//868 596//596 225//225 +f 866//866 1586//1586 7//7 +f 1274//1274 1260//1260 1559//1559 +f 61//61 125//125 59//59 +f 574//574 156//156 155//155 +f 1410//1410 451//451 510//510 +f 1381//1381 831//831 1468//1468 +f 1483//1483 276//276 1587//1587 +f 158//158 178//178 180//180 +f 1588//1588 87//87 1311//1311 +f 1588//1588 88//88 87//87 +f 159//159 1585//1585 1589//1589 +f 1589//1589 1590//1590 165//165 +f 1568//1568 1569//1569 1572//1572 +f 1588//1588 690//690 102//102 +f 88//88 1588//1588 102//102 +f 690//690 689//689 102//102 +f 1591//1591 1323//1323 688//688 +f 1558//1558 49//49 48//48 +f 165//165 1590//1590 1571//1571 +f 689//689 691//691 98//98 +f 82//82 189//189 258//258 +f 88//88 103//103 1568//1568 +f 1592//1592 1593//1593 1594//1594 +f 459//459 128//128 1595//1595 +f 107//107 1264//1264 43//43 +f 882//882 37//37 1596//1596 +f 83//83 82//82 19//19 +f 1597//1597 1598//1598 1599//1599 +f 57//57 11//11 55//55 +f 1559//1559 830//830 1560//1560 +f 1600//1600 1601//1601 1602//1602 +f 1571//1571 1590//1590 1572//1572 +f 1556//1556 56//56 45//45 +f 56//56 1603//1603 45//45 +f 1603//1603 115//115 45//45 +f 1603//1603 44//44 115//115 +f 44//44 58//58 115//115 +f 824//824 1591//1591 1604//1604 +f 1605//1605 145//145 144//144 +f 1593//1593 1586//1586 1594//1594 +f 613//613 612//612 1059//1059 +f 12//12 1558//1558 48//48 +f 1606//1606 17//17 664//664 +f 457//457 1607//1607 1608//1608 +f 1310//1310 1588//1588 1311//1311 +f 1609//1609 1610//1610 1563//1563 +f 87//87 89//89 1595//1595 +f 1600//1600 1586//1586 1593//1593 +f 1611//1611 392//392 391//391 +f 48//48 1275//1275 1274//1274 +f 142//142 158//158 180//180 +f 1602//1602 1611//1611 1591//1591 +f 1612//1612 391//391 1198//1198 +f 1281//1281 999//999 1109//1109 +f 103//103 573//573 1569//1569 +f 459//459 1595//1595 1597//1597 +f 1609//1609 153//153 152//152 +f 829//829 649//649 947//947 +f 391//391 393//393 531//531 +f 531//531 1198//1198 391//391 +f 341//341 340//340 765//765 +f 1357//1357 656//656 322//322 +f 1572//1572 1613//1613 1248//1248 +f 574//574 155//155 219//219 +f 19//19 258//258 39//39 +f 391//391 1612//1612 1611//1611 +f 178//178 1614//1614 179//179 +f 1590//1590 1568//1568 1572//1572 +f 1244//1244 1228//1228 26//26 +f 1615//1615 830//830 1559//1559 +f 1569//1569 574//574 1613//1613 +f 1616//1616 1568//1568 1590//1590 +f 89//89 1598//1598 1595//1595 +f 1601//1601 1611//1611 1602//1602 +f 322//322 656//656 1358//1358 +f 1600//1600 1602//1602 361//361 +f 1561//1561 459//459 1617//1617 +f 1599//1599 1585//1585 179//179 +f 1600//1600 361//361 1586//1586 +f 180//180 143//143 142//142 +f 165//165 1571//1571 166//166 +f 933//933 1618//1618 658//658 +f 1598//1598 1616//1616 1585//1585 +f 44//44 59//59 58//58 +f 68//68 1360//1360 69//69 +f 361//361 1602//1602 460//460 +f 1594//1594 1586//1586 866//866 +f 491//491 1604//1604 688//688 +f 491//491 688//688 687//687 +f 103//103 102//102 109//109 +f 180//180 730//730 143//143 +f 159//159 165//165 21//21 +f 329//329 72//72 71//71 +f 167//167 1619//1619 125//125 +f 1620//1620 1597//1597 1599//1599 +f 1268//1268 1621//1621 235//235 +f 180//180 731//731 730//730 +f 1565//1565 392//392 1611//1611 +f 1601//1601 1565//1565 1611//1611 +f 69//69 1622//1622 419//419 +f 110//110 97//97 156//156 +f 615//615 562//562 666//666 +f 460//460 1602//1602 824//824 +f 1602//1602 1591//1591 824//824 +f 419//419 1443//1443 1201//1201 +f 1623//1623 219//219 220//220 +f 1620//1620 1599//1599 1624//1624 +f 1625//1625 1626//1626 1627//1627 +f 789//789 648//648 1341//1341 +f 1611//1611 1612//1612 1323//1323 +f 89//89 88//88 1568//1568 +f 1594//1594 866//866 1628//1628 +f 1428//1428 1601//1601 1629//1629 +f 89//89 1568//1568 1616//1616 +f 664//664 1212//1212 1630//1630 +f 104//104 322//322 68//68 +f 1591//1591 1611//1611 1323//1323 +f 227//227 1010//1010 299//299 +f 409//409 1631//1631 1151//1151 +f 1632//1632 1633//1633 1634//1634 +f 125//125 61//61 167//167 +f 1613//1613 574//574 1623//1623 +f 1623//1623 574//574 219//219 +f 258//258 108//108 65//65 +f 1565//1565 1331//1331 392//392 +f 564//564 45//45 47//47 +f 1289//1289 1159//1159 1068//1068 +f 108//108 866//866 7//7 +f 128//128 87//87 1595//1595 +f 1613//1613 1623//1623 1248//1248 +f 252//252 1635//1635 1180//1180 +f 814//814 1168//1168 816//816 +f 180//180 179//179 731//731 +f 1246//1246 826//826 1059//1059 +f 1614//1614 1599//1599 179//179 +f 1636//1636 1355//1355 1637//1637 +f 1515//1515 1635//1635 252//252 +f 500//500 1105//1105 441//441 +f 1180//1180 1635//1635 549//549 +f 549//549 1638//1638 408//408 +f 1591//1591 688//688 1604//1604 +f 1561//1561 124//124 459//459 +f 1639//1639 1263//1263 1461//1461 +f 1585//1585 1616//1616 1589//1589 +f 830//830 12//12 1560//1560 +f 1598//1598 89//89 1616//1616 +f 824//824 1604//1604 491//491 +f 1599//1599 1598//1598 1585//1585 +f 1310//1310 620//620 1588//1588 +f 1635//1635 1640//1640 549//549 +f 549//549 1640//1640 1638//1638 +f 1331//1331 676//676 392//392 +f 1589//1589 1616//1616 1590//1590 +f 852//852 1588//1588 620//620 +f 1588//1588 852//852 690//690 +f 1435//1435 734//734 735//735 +f 652//652 389//389 198//198 +f 1429//1429 1629//1629 1593//1593 +f 1629//1629 1600//1600 1593//1593 +f 103//103 109//109 573//573 +f 11//11 57//57 1558//1558 +f 154//154 153//153 10//10 +f 1572//1572 1569//1569 1613//1613 +f 320//320 319//319 576//576 +f 1631//1631 409//409 408//408 +f 214//214 1641//1641 1642//1642 +f 1593//1593 1592//1592 1429//1429 +f 1612//1612 1198//1198 1323//1323 +f 1198//1198 610//610 1323//1323 +f 109//109 110//110 573//573 +f 816//816 1320//1320 815//815 +f 1624//1624 1599//1599 1614//1614 +f 1643//1643 1624//1624 1614//1614 +f 1644//1644 1515//1515 770//770 +f 1645//1645 1151//1151 1631//1631 +f 1646//1646 1645//1645 1631//1631 +f 1647//1647 1535//1535 1648//1648 +f 221//221 117//117 119//119 +f 1649//1649 1650//1650 1651//1651 +f 38//38 761//761 1320//1320 +f 573//573 110//110 156//156 +f 1595//1595 1598//1598 1597//1597 +f 1635//1635 1652//1652 1640//1640 +f 1640//1640 1653//1653 1638//1638 +f 1638//1638 1653//1653 408//408 +f 1653//1653 1654//1654 408//408 +f 1654//1654 1631//1631 408//408 +f 1654//1654 1646//1646 1631//1631 +f 1482//1482 276//276 1483//1483 +f 816//816 1570//1570 1320//1320 +f 1629//1629 1601//1601 1600//1600 +f 1558//1558 57//57 49//49 +f 116//116 56//56 1556//1556 +f 1515//1515 1655//1655 1635//1635 +f 459//459 1597//1597 1617//1617 +f 1655//1655 1652//1652 1635//1635 +f 1652//1652 1656//1656 1640//1640 +f 1640//1640 1656//1656 1653//1653 +f 622//622 44//44 1603//1603 +f 1657//1657 1654//1654 1653//1653 +f 43//43 1264//1264 135//135 +f 1482//1482 1212//1212 276//276 +f 1658//1658 1659//1659 1655//1655 +f 1515//1515 1658//1658 1655//1655 +f 1655//1655 1656//1656 1652//1652 +f 1656//1656 1657//1657 1653//1653 +f 1644//1644 1658//1658 1515//1515 +f 107//107 43//43 55//55 +f 460//460 824//824 13//13 +f 492//492 491//491 687//687 +f 279//279 1660//1660 1395//1395 +f 1657//1657 1646//1646 1654//1654 +f 1428//1428 1629//1629 1429//1429 +f 1505//1505 530//530 393//393 +f 188//188 329//329 1628//1628 +f 1212//1212 1211//1211 276//276 +f 248//248 469//469 721//721 +f 152//152 1661//1661 1662//1662 +f 904//904 1435//1435 932//932 +f 1659//1659 1663//1663 1655//1655 +f 1655//1655 1663//1663 1656//1656 +f 1281//1281 1645//1645 1646//1646 +f 535//535 989//989 1239//1239 +f 159//159 1589//1589 165//165 +f 1664//1664 1646//1646 1657//1657 +f 1664//1664 1281//1281 1646//1646 +f 1564//1564 1665//1665 1331//1331 +f 220//220 195//195 357//357 +f 1666//1666 795//795 1346//1346 +f 1542//1542 1550//1550 1543//1543 +f 1667//1667 1281//1281 1664//1664 +f 866//866 188//188 1628//1628 +f 1643//1643 1614//1614 178//178 +f 1402//1402 831//831 1378//1378 +f 476//476 1668//1668 101//101 +f 1663//1663 1669//1669 1656//1656 +f 1656//1656 1670//1670 1657//1657 +f 1671//1671 1664//1664 1657//1657 +f 1667//1667 1672//1672 1281//1281 +f 1281//1281 1672//1672 1282//1282 +f 1618//1618 476//476 658//658 +f 1623//1623 220//220 357//357 +f 1658//1658 1673//1673 1659//1659 +f 1659//1659 1673//1673 1663//1663 +f 1673//1673 1674//1674 1663//1663 +f 1656//1656 1669//1669 1670//1670 +f 1670//1670 1671//1671 1657//1657 +f 735//735 99//99 1668//1668 +f 1564//1564 1601//1601 1428//1428 +f 355//355 354//354 946//946 +f 7//7 1586//1586 361//361 +f 476//476 1618//1618 1668//1668 +f 1248//1248 1623//1623 357//357 +f 622//622 1603//1603 56//56 +f 1663//1663 1674//1674 1669//1669 +f 1671//1671 1667//1667 1664//1664 +f 1672//1672 843//843 1282//1282 +f 1346//1346 794//794 78//78 +f 1618//1618 931//931 1668//1668 +f 153//153 1609//1609 1563//1563 +f 1476//1476 1648//1648 1477//1477 +f 44//44 61//61 59//59 +f 789//789 246//246 648//648 +f 617//617 616//616 311//311 +f 1670//1670 1675//1675 1671//1671 +f 93//93 6//6 134//134 +f 815//815 729//729 814//814 +f 153//153 1563//1563 10//10 +f 855//855 854//854 1402//1402 +f 210//210 222//222 1426//1426 +f 1674//1674 364//364 1669//1669 +f 1676//1676 1672//1672 1667//1667 +f 1672//1672 844//844 843//843 +f 1601//1601 1564//1564 1565//1565 +f 1570//1570 38//38 1320//1320 +f 687//687 630//630 640//640 +f 364//364 363//363 1669//1669 +f 1669//1669 363//363 1670//1670 +f 1670//1670 363//363 1675//1675 +f 1671//1671 1676//1676 1667//1667 +f 931//931 1435//1435 735//735 +f 1668//1668 931//931 735//735 +f 1113//1113 1124//1124 1146//1146 +f 1673//1673 1677//1677 1674//1674 +f 1675//1675 1676//1676 1671//1671 +f 891//891 1672//1672 1676//1676 +f 1672//1672 771//771 844//844 +f 844//844 771//771 772//772 +f 25//25 1244//1244 26//26 +f 47//47 192//192 1379//1379 +f 146//146 145//145 191//191 +f 927//927 1475//1475 841//841 +f 1678//1678 1092//1092 1070//1070 +f 363//363 805//805 1675//1675 +f 1672//1672 891//891 771//771 +f 932//932 822//822 821//821 +f 38//38 1577//1577 761//761 +f 1677//1677 364//364 1674//1674 +f 1675//1675 907//907 1676//1676 +f 907//907 891//891 1676//1676 +f 688//688 610//610 630//630 +f 931//931 932//932 1435//1435 +f 1661//1661 152//152 830//830 +f 866//866 189//189 188//188 +f 891//891 804//804 771//771 +f 247//247 473//473 597//597 +f 410//410 548//548 408//408 +f 1563//1563 1461//1461 1460//1460 +f 1//1 906//906 1679//1679 +f 805//805 907//907 1675//1675 +f 392//392 1505//1505 393//393 +f 57//57 55//55 54//54 +f 607//607 651//651 693//693 +f 1680//1680 1681//1681 1382//1382 +f 1403//1403 30//30 187//187 +f 390//390 1682//1682 997//997 +f 212//212 1//1 1679//1679 +f 853//853 364//364 1677//1677 +f 35//35 34//34 1038//1038 +f 806//806 1683//1683 828//828 +f 1322//1322 213//213 215//215 +f 1348//1348 1625//1625 1684//1684 +f 15//15 17//17 1625//1625 +f 1685//1685 1461//1461 1563//1563 +f 1416//1416 1686//1686 1687//1687 +f 17//17 1606//1606 1625//1625 +f 1348//1348 15//15 1625//1625 +f 592//592 593//593 1128//1128 +f 1688//1688 932//932 821//821 +f 1689//1689 714//714 1690//1690 +f 1691//1691 777//777 1692//1692 +f 768//768 739//739 1692//1692 +f 1693//1693 346//346 260//260 +f 1377//1377 1337//1337 303//303 +f 917//917 820//820 822//822 +f 1143//1143 1694//1694 1695//1695 +f 1224//1224 1696//1696 1268//1268 +f 890//890 904//904 1697//1697 +f 1175//1175 16//16 15//15 +f 900//900 929//929 921//921 +f 1698//1698 1699//1699 762//762 +f 1700//1700 797//797 754//754 +f 1701//1701 1231//1231 1232//1232 +f 762//762 753//753 746//746 +f 780//780 1702//1702 752//752 +f 1325//1325 135//135 1263//1263 +f 792//792 1703//1703 1702//1702 +f 1704//1704 457//457 1608//1608 +f 135//135 1264//1264 1263//1263 +f 446//446 445//445 1526//1526 +f 535//535 817//817 169//169 +f 1619//1619 167//167 1324//1324 +f 1700//1700 1705//1705 797//797 +f 480//480 175//175 1706//1706 +f 214//214 1497//1497 1681//1681 +f 615//615 926//926 658//658 +f 1707//1707 1708//1708 1709//1709 +f 216//216 62//62 1710//1710 +f 596//596 473//473 225//225 +f 590//590 458//458 457//457 +f 1711//1711 875//875 890//890 +f 287//287 1712//1712 261//261 +f 898//898 887//887 1713//1713 +f 493//493 177//177 788//788 +f 1196//1196 1132//1132 23//23 +f 1690//1690 714//714 1714//1714 +f 1217//1217 1216//1216 1715//1715 +f 1704//1704 590//590 457//457 +f 135//135 1325//1325 1324//1324 +f 1716//1716 1705//1705 1700//1700 +f 1702//1702 1703//1703 1698//1698 +f 1717//1717 939//939 882//882 +f 1718//1718 1699//1699 1698//1698 +f 1697//1697 1683//1683 1711//1711 +f 678//678 1459//1459 632//632 +f 1619//1619 1326//1326 1719//1719 +f 1720//1720 1619//1619 1719//1719 +f 149//149 151//151 1721//1721 +f 1722//1722 1714//1714 698//698 +f 1718//1718 883//883 870//870 +f 762//762 1723//1723 763//763 +f 1724//1724 1725//1725 1726//1726 +f 235//235 1224//1224 1268//1268 +f 1702//1702 1698//1698 762//762 +f 1727//1727 1728//1728 1729//1729 +f 1694//1694 1730//1730 1731//1731 +f 790//790 839//839 791//791 +f 1702//1702 780//780 792//792 +f 534//534 533//533 898//898 +f 1683//1683 876//876 828//828 +f 1348//1348 1175//1175 15//15 +f 1416//1416 832//832 1732//1732 +f 1416//1416 1732//1732 1686//1686 +f 1733//1733 1687//1687 1686//1686 +f 1732//1732 1733//1733 1686//1686 +f 1226//1226 169//169 1734//1734 +f 1347//1347 1175//1175 1348//1348 +f 1716//1716 875//875 1711//1711 +f 1704//1704 1735//1735 1402//1402 +f 898//898 533//533 900//900 +f 38//38 939//939 694//694 +f 898//898 900//900 887//887 +f 963//963 659//659 1129//1129 +f 648//648 776//776 1341//1341 +f 1688//1688 821//821 876//876 +f 1690//1690 1736//1736 1689//1689 +f 232//232 1260//1260 1274//1274 +f 1688//1688 876//876 1683//1683 +f 591//591 1704//1704 1402//1402 +f 1711//1711 1683//1683 1705//1705 +f 870//870 869//869 1699//1699 +f 1464//1464 1499//1499 1437//1437 +f 876//876 846//846 828//828 +f 597//597 245//245 247//247 +f 1683//1683 797//797 1705//1705 +f 1094//1094 490//490 1347//1347 +f 634//634 812//812 635//635 +f 1607//1607 1737//1737 1732//1732 +f 1626//1626 1630//1630 1627//1627 +f 1347//1347 490//490 1175//1175 +f 1699//1699 869//869 1723//1723 +f 869//869 875//875 1716//1716 +f 887//887 1718//1718 1738//1738 +f 714//714 669//669 698//698 +f 950//950 1299//1299 1261//1261 +f 832//832 1608//1608 1732//1732 +f 127//127 1720//1720 1739//1739 +f 347//347 346//346 368//368 +f 1740//1740 164//164 1741//1741 +f 1741//1741 163//163 155//155 +f 366//366 368//368 367//367 +f 1160//1160 569//569 1161//1161 +f 127//127 125//125 1619//1619 +f 1658//1658 1742//1742 1673//1673 +f 1326//1326 1619//1619 1324//1324 +f 1691//1691 715//715 714//714 +f 1743//1743 1744//1744 1745//1745 +f 869//869 871//871 875//875 +f 809//809 839//839 790//790 +f 262//262 261//261 1712//1712 +f 665//665 17//17 928//928 +f 794//794 793//793 745//745 +f 1690//1690 1714//1714 1722//1722 +f 1729//1729 1728//1728 1725//1725 +f 1630//1630 1746//1746 1627//1627 +f 865//865 886//886 839//839 +f 456//456 458//458 645//645 +f 1747//1747 1743//1743 1745//1745 +f 762//762 1699//1699 1723//1723 +f 1748//1748 149//149 1721//1721 +f 1748//1748 1749//1749 1744//1744 +f 928//928 854//854 665//665 +f 887//887 1738//1738 1713//1713 +f 1227//1227 1226//1226 962//962 +f 1543//1543 1750//1750 1475//1475 +f 1445//1445 1751//1751 1752//1752 +f 898//898 1713//1713 886//886 +f 1226//1226 1722//1722 962//962 +f 578//578 1753//1753 1754//1754 +f 1621//1621 1268//1268 1270//1270 +f 424//424 1755//1755 1756//1756 +f 367//367 368//368 1757//1757 +f 1747//1747 1745//1745 1758//1758 +f 887//887 883//883 1718//1718 +f 1721//1721 1759//1759 1749//1749 +f 1748//1748 1721//1721 1749//1749 +f 1693//1693 262//262 1760//1760 +f 1045//1045 1567//1567 749//749 +f 1703//1703 1738//1738 1718//1718 +f 168//168 778//778 1690//1690 +f 1761//1761 1762//1762 1763//1763 +f 367//367 1757//1757 1751//1751 +f 1760//1760 1764//1764 1757//1757 +f 1758//1758 1745//1745 1765//1765 +f 1743//1743 1747//1747 1766//1766 +f 161//161 1744//1744 1743//1743 +f 456//456 1607//1607 457//457 +f 1767//1767 437//437 1258//1258 +f 1147//1147 1768//1768 1140//1140 +f 1769//1769 1770//1770 64//64 +f 579//579 578//578 1754//1754 +f 1771//1771 1772//1772 578//578 +f 1703//1703 1718//1718 1698//1698 +f 1773//1773 1774//1774 1775//1775 +f 1721//1721 1740//1740 1776//1776 +f 1746//1746 1482//1482 1481//1481 +f 1777//1777 1778//1778 1779//1779 +f 1780//1780 1746//1746 1481//1481 +f 1767//1767 1258//1258 344//344 +f 1297//1297 1296//1296 1334//1334 +f 1781//1781 198//198 390//390 +f 1782//1782 1774//1774 906//906 +f 1783//1783 1771//1771 578//578 +f 1327//1327 1115//1115 1098//1098 +f 367//367 1751//1751 1445//1445 +f 1744//1744 1749//1749 1745//1745 +f 368//368 1693//1693 1760//1760 +f 509//509 928//928 17//17 +f 1697//1697 904//904 932//932 +f 1784//1784 1771//1771 1783//1783 +f 1784//1784 1785//1785 1771//1771 +f 1785//1785 1772//1772 1771//1771 +f 962//962 698//698 659//659 +f 1765//1765 1745//1745 1786//1786 +f 1785//1785 1648//1648 1476//1476 +f 214//214 1642//1642 1497//1497 +f 1126//1126 634//634 633//633 +f 926//926 615//615 666//666 +f 161//161 1743//1743 1491//1491 +f 1787//1787 1680//1680 1788//1788 +f 1749//1749 1759//1759 1786//1786 +f 1721//1721 1776//1776 1759//1759 +f 1065//1065 1102//1102 1177//1177 +f 1636//1636 1637//1637 1286//1286 +f 1725//1725 1728//1728 1789//1789 +f 870//870 1699//1699 1718//1718 +f 763//763 1700//1700 753//753 +f 1790//1790 1627//1627 1746//1746 +f 1791//1791 262//262 1712//1712 +f 1792//1792 1684//1684 1790//1790 +f 1689//1689 777//777 1691//1691 +f 1784//1784 1647//1647 1785//1785 +f 1647//1647 1648//1648 1785//1785 +f 149//149 1748//1748 1744//1744 +f 1793//1793 1794//1794 1287//1287 +f 1287//1287 1794//1794 1285//1285 +f 1795//1795 1286//1286 1285//1285 +f 1795//1795 1636//1636 1286//1286 +f 1689//1689 1736//1736 777//777 +f 752//752 1702//1702 746//746 +f 1721//1721 164//164 1740//1740 +f 208//208 207//207 856//856 +f 1745//1745 1749//1749 1786//1786 +f 1336//1336 1514//1514 603//603 +f 777//777 809//809 1692//1692 +f 1783//1783 1796//1796 1784//1784 +f 1796//1796 1647//1647 1784//1784 +f 698//698 1714//1714 714//714 +f 168//168 779//779 778//778 +f 1624//1624 1643//1643 1797//1797 +f 346//346 1693//1693 368//368 +f 1720//1720 127//127 1619//1619 +f 1630//1630 1482//1482 1746//1746 +f 1798//1798 1796//1796 1783//1783 +f 1734//1734 1690//1690 1226//1226 +f 164//164 163//163 1741//1741 +f 778//778 1736//1736 1690//1690 +f 1317//1317 1374//1374 679//679 +f 1794//1794 1795//1795 1285//1285 +f 840//840 1474//1474 927//927 +f 1625//1625 1606//1606 1626//1626 +f 1735//1735 1704//1704 1608//1608 +f 1737//1737 1733//1733 1732//1732 +f 262//262 1791//1791 1760//1760 +f 1702//1702 762//762 746//746 +f 754//754 753//753 1700//1700 +f 1322//1322 1787//1787 1788//1788 +f 1400//1400 1799//1799 1793//1793 +f 1799//1799 1794//1794 1793//1793 +f 1800//1800 1636//1636 1795//1795 +f 1801//1801 426//426 428//428 +f 790//790 791//791 767//767 +f 1712//1712 287//287 1802//1802 +f 1803//1803 1647//1647 1796//1796 +f 1734//1734 169//169 168//168 +f 1794//1794 1804//1804 1795//1795 +f 1800//1800 1355//1355 1636//1636 +f 1716//1716 1700//1700 763//763 +f 962//962 963//963 1520//1520 +f 167//167 135//135 1324//1324 +f 1492//1492 161//161 1491//1491 +f 168//168 1690//1690 1734//1734 +f 1224//1224 1805//1805 1696//1696 +f 122//122 1649//1649 1777//1777 +f 1764//1764 1760//1760 1791//1791 +f 168//168 170//170 779//779 +f 839//839 886//886 1713//1713 +f 680//680 325//325 633//633 +f 1806//1806 1332//1332 1807//1807 +f 1791//1791 1712//1712 1808//1808 +f 1808//1808 1712//1712 1802//1802 +f 1535//1535 1647//1647 1803//1803 +f 1723//1723 1716//1716 763//763 +f 1533//1533 1532//1532 1809//1809 +f 1296//1296 1031//1031 217//217 +f 1224//1224 235//235 244//244 +f 1799//1799 1400//1400 1547//1547 +f 1799//1799 1764//1764 1794//1794 +f 1794//1794 1764//1764 1804//1804 +f 839//839 1713//1713 791//791 +f 1176//1176 530//530 1545//1545 +f 1810//1810 1032//1032 1031//1031 +f 1677//1677 1673//1673 1811//1811 +f 1697//1697 1688//1688 1683//1683 +f 1812//1812 96//96 1514//1514 +f 1813//1813 1803//1803 1798//1798 +f 1263//1263 1326//1326 1325//1325 +f 1477//1477 1467//1467 1478//1478 +f 1547//1547 1814//1814 1799//1799 +f 1804//1804 1808//1808 1795//1795 +f 1808//1808 1800//1800 1795//1795 +f 1808//1808 1815//1815 1800//1800 +f 869//869 1716//1716 1723//1723 +f 792//792 1738//1738 1703//1703 +f 1689//1689 1691//1691 714//714 +f 62//62 64//64 1448//1448 +f 1816//1816 1265//1265 827//827 +f 147//147 149//149 1744//1744 +f 198//198 1781//1781 1817//1817 +f 1818//1818 1740//1740 1741//1741 +f 1776//1776 1740//1740 1818//1818 +f 1335//1335 1514//1514 1336//1336 +f 1335//1335 1812//1812 1514//1514 +f 97//97 96//96 1812//1812 +f 1342//1342 1341//1341 776//776 +f 1813//1813 1819//1819 1803//1803 +f 1803//1803 1819//1819 1535//1535 +f 1466//1466 1467//1467 1477//1477 +f 1716//1716 1711//1711 1705//1705 +f 451//451 453//453 462//462 +f 1814//1814 1820//1820 1799//1799 +f 1820//1820 1764//1764 1799//1799 +f 1815//1815 1821//1821 1800//1800 +f 196//196 198//198 1817//1817 +f 1802//1802 1822//1822 1821//1821 +f 110//110 98//98 97//97 +f 1823//1823 1824//1824 1825//1825 +f 1826//1826 1827//1827 1828//1828 +f 1625//1625 1627//1627 1790//1790 +f 1713//1713 1738//1738 792//792 +f 368//368 1760//1760 1757//1757 +f 1711//1711 890//890 1697//1697 +f 1547//1547 1829//1829 1814//1814 +f 1830//1830 1831//1831 1554//1554 +f 216//216 63//63 62//62 +f 1406//1406 1408//1408 1832//1832 +f 962//962 1722//1722 698//698 +f 1833//1833 1376//1376 793//793 +f 1032//1032 1834//1834 1678//1678 +f 791//791 1713//1713 792//792 +f 1239//1239 817//817 535//535 +f 178//178 1835//1835 1643//1643 +f 778//778 777//777 1736//1736 +f 1817//1817 1478//1478 1467//1467 +f 1781//1781 997//997 1478//1478 +f 1817//1817 1781//1781 1478//1478 +f 390//390 997//997 1781//1781 +f 1836//1836 1837//1837 1838//1838 +f 1764//1764 1791//1791 1804//1804 +f 1804//1804 1791//1791 1808//1808 +f 394//394 1773//1773 1839//1839 +f 233//233 1319//1319 407//407 +f 1833//1833 1377//1377 1376//1376 +f 1840//1840 1841//1841 1471//1471 +f 1776//1776 1335//1335 1337//1337 +f 1818//1818 1812//1812 1335//1335 +f 1476//1476 1772//1772 1785//1785 +f 879//879 1424//1424 1423//1423 +f 1813//1813 278//278 1819//1819 +f 278//278 1535//1535 1819//1819 +f 1763//1763 1762//1762 1842//1842 +f 1752//1752 1751//1751 1814//1814 +f 1814//1814 1751//1751 1820//1820 +f 795//795 1765//1765 793//793 +f 793//793 1765//1765 1833//1833 +f 1776//1776 1337//1337 1377//1377 +f 1818//1818 1335//1335 1776//1776 +f 1812//1812 1741//1741 97//97 +f 1697//1697 932//932 1688//1688 +f 1692//1692 809//809 768//768 +f 715//715 1692//1692 739//739 +f 178//178 939//939 1835//1835 +f 797//797 1683//1683 806//806 +f 1843//1843 200//200 1491//1491 +f 768//768 809//809 790//790 +f 29//29 311//311 310//310 +f 196//196 1817//1817 1467//1467 +f 1721//1721 151//151 164//164 +f 1844//1844 786//786 785//785 +f 1808//1808 1802//1802 1815//1815 +f 1815//1815 1802//1802 1821//1821 +f 1845//1845 1765//1765 795//795 +f 1786//1786 1377//1377 1833//1833 +f 1741//1741 1812//1812 1818//1818 +f 27//27 29//29 310//310 +f 147//147 1744//1744 161//161 +f 178//178 158//158 939//939 +f 1109//1109 1151//1151 1645//1645 +f 1280//1280 1032//1032 1071//1071 +f 1787//1787 1681//1681 1680//1680 +f 216//216 1557//1557 217//217 +f 1846//1846 1836//1836 1633//1633 +f 1751//1751 1757//1757 1820//1820 +f 1820//1820 1757//1757 1764//1764 +f 1458//1458 1847//1847 1276//1276 +f 806//806 828//828 781//781 +f 1226//1226 1690//1690 1722//1722 +f 1587//1587 276//276 278//278 +f 38//38 882//882 939//939 +f 97//97 1741//1741 155//155 +f 1765//1765 1786//1786 1833//1833 +f 1786//1786 1759//1759 1377//1377 +f 1759//1759 1776//1776 1377//1377 +f 1258//1258 1848//1848 231//231 +f 1849//1849 1850//1850 1851//1851 +f 1852//1852 1853//1853 1854//1854 +f 1260//1260 1259//1259 1855//1855 +f 1856//1856 1857//1857 1858//1858 +f 95//95 307//307 1430//1430 +f 120//120 1859//1859 1431//1431 +f 1860//1860 1861//1861 1862//1862 +f 200//200 229//229 218//218 +f 1253//1253 1125//1125 1863//1863 +f 123//123 1864//1864 1386//1386 +f 1865//1865 1866//1866 1778//1778 +f 929//929 900//900 533//533 +f 831//831 1735//1735 832//832 +f 438//438 1867//1867 436//436 +f 1868//1868 463//463 462//462 +f 152//152 1662//1662 1869//1869 +f 436//436 1870//1870 1869//1869 +f 1184//1184 1871//1871 1872//1872 +f 423//423 425//425 750//750 +f 436//436 1867//1867 1870//1870 +f 1610//1610 1609//1609 1869//1869 +f 1873//1873 1874//1874 478//478 +f 1870//1870 1875//1875 1869//1869 +f 1873//1873 1876//1876 438//438 +f 1874//1874 1873//1873 438//438 +f 438//438 1876//1876 1867//1867 +f 1877//1877 1610//1610 1869//1869 +f 1875//1875 1877//1877 1869//1869 +f 1867//1867 1878//1878 1870//1870 +f 1870//1870 1878//1878 1875//1875 +f 745//745 1376//1376 302//302 +f 1879//1879 1873//1873 1880//1880 +f 1877//1877 1685//1685 1610//1610 +f 1563//1563 1610//1610 1685//1685 +f 1873//1873 1879//1879 1876//1876 +f 1876//1876 1881//1881 1867//1867 +f 1867//1867 1881//1881 1878//1878 +f 86//86 1882//1882 84//84 +f 1875//1875 1883//1883 1877//1877 +f 1877//1877 1883//1883 1685//1685 +f 1883//1883 1884//1884 1685//1685 +f 1879//1879 1885//1885 1876//1876 +f 1878//1878 1883//1883 1875//1875 +f 303//303 1439//1439 1362//1362 +f 1879//1879 1880//1880 744//744 +f 1886//1886 1884//1884 1883//1883 +f 1878//1878 1886//1886 1883//1883 +f 1793//1793 1287//1287 1339//1339 +f 1525//1525 1879//1879 744//744 +f 1885//1885 1887//1887 1876//1876 +f 1876//1876 1887//1887 1881//1881 +f 1382//1382 1681//1681 842//842 +f 1881//1881 1886//1886 1878//1878 +f 1888//1888 1860//1860 1862//1862 +f 1626//1626 1606//1606 664//664 +f 743//743 1526//1526 744//744 +f 1639//1639 1461//1461 1884//1884 +f 1886//1886 1639//1639 1884//1884 +f 996//996 1478//1478 997//997 +f 1889//1889 1890//1890 1860//1860 +f 1891//1891 1868//1868 1892//1892 +f 1202//1202 605//605 1479//1479 +f 1893//1893 1526//1526 743//743 +f 1894//1894 1879//1879 1525//1525 +f 1894//1894 1885//1885 1879//1879 +f 1895//1895 1896//1896 1897//1897 +f 1898//1898 1899//1899 1900//1900 +f 1526//1526 1525//1525 744//744 +f 1901//1901 1902//1902 1903//1903 +f 1854//1854 1853//1853 1904//1904 +f 1905//1905 1832//1832 1408//1408 +f 1906//1906 1907//1907 1838//1838 +f 1907//1907 1908//1908 1836//1836 +f 1908//1908 1909//1909 1836//1836 +f 1909//1909 1634//1634 1836//1836 +f 445//445 1894//1894 1525//1525 +f 1886//1886 1910//1910 1639//1639 +f 1440//1440 1911//1911 1912//1912 +f 1906//1906 1913//1913 1907//1907 +f 1907//1907 1914//1914 1908//1908 +f 1915//1915 1632//1632 1916//1916 +f 1917//1917 1634//1634 1909//1909 +f 1918//1918 1886//1886 1881//1881 +f 1887//1887 1918//1918 1881//1881 +f 1910//1910 1263//1263 1639//1639 +f 1890//1890 1919//1919 1861//1861 +f 1920//1920 1921//1921 1922//1922 +f 1316//1316 613//613 1059//1059 +f 1923//1923 1914//1914 1907//1907 +f 1913//1913 1923//1923 1907//1907 +f 1914//1914 1924//1924 1908//1908 +f 1924//1924 1925//1925 1909//1909 +f 1908//1908 1924//1924 1909//1909 +f 1710//1710 1916//1916 1634//1634 +f 1917//1917 1710//1710 1634//1634 +f 1910//1910 1926//1926 1263//1263 +f 1920//1920 121//121 1921//1921 +f 1888//1888 784//784 1432//1432 +f 1871//1871 1927//1927 1906//1906 +f 1924//1924 1928//1928 1925//1925 +f 1925//1925 1917//1917 1909//1909 +f 816//816 1168//1168 1265//1265 +f 1918//1918 1910//1910 1886//1886 +f 664//664 665//665 855//855 +f 77//77 1605//1605 1197//1197 +f 1921//1921 121//121 1386//1386 +f 1860//1860 1890//1890 1861//1861 +f 1927//1927 1923//1923 1906//1906 +f 1906//1906 1923//1923 1913//1913 +f 1710//1710 1917//1917 1925//1925 +f 1287//1287 1286//1286 31//31 +f 1929//1929 1918//1918 1887//1887 +f 1885//1885 1929//1929 1887//1887 +f 1888//1888 1862//1862 784//784 +f 1184//1184 1930//1930 1927//1927 +f 1871//1871 1184//1184 1927//1927 +f 1923//1923 1931//1931 1914//1914 +f 1710//1710 1450//1450 1916//1916 +f 1918//1918 1932//1932 1910//1910 +f 1910//1910 1932//1932 1926//1926 +f 1468//1468 831//831 833//833 +f 1630//1630 1212//1212 1482//1482 +f 1362//1362 1438//1438 419//419 +f 99//99 101//101 1668//1668 +f 288//288 1291//1291 287//287 +f 1921//1921 1385//1385 1933//1933 +f 1934//1934 1930//1930 1184//1184 +f 1927//1927 1935//1935 1923//1923 +f 1914//1914 1931//1931 1924//1924 +f 1894//1894 1929//1929 1885//1885 +f 1793//1793 1339//1339 1400//1400 +f 857//857 876//876 821//821 +f 1936//1936 1523//1523 1937//1937 +f 1936//1936 859//859 1938//1938 +f 1936//1936 1939//1939 859//859 +f 1939//1939 1940//1940 859//859 +f 1800//1800 1821//1821 1356//1356 +f 1934//1934 1941//1941 1930//1930 +f 1927//1927 1930//1930 1935//1935 +f 1928//1928 1557//1557 1925//1925 +f 216//216 1710//1710 1925//1925 +f 1557//1557 216//216 1925//1925 +f 1355//1355 1800//1800 1356//1356 +f 1821//1821 1942//1942 1356//1356 +f 1926//1926 1326//1326 1263//1263 +f 1942//1942 1350//1350 1356//1356 +f 1935//1935 1931//1931 1923//1923 +f 1931//1931 1750//1750 1924//1924 +f 1924//1924 1543//1543 1928//1928 +f 1543//1543 1557//1557 1928//1928 +f 1943//1943 1944//1944 1596//1596 +f 1918//1918 1945//1945 1932//1932 +f 1932//1932 1326//1326 1926//1926 +f 1946//1946 858//858 860//860 +f 1184//1184 1183//1183 1934//1934 +f 1924//1924 1750//1750 1543//1543 +f 1379//1379 472//472 471//471 +f 1469//1469 1947//1947 1494//1494 +f 1948//1948 1949//1949 1950//1950 +f 446//446 1951//1951 444//444 +f 444//444 1951//1951 445//445 +f 1859//1859 1952//1952 1953//1953 +f 1824//1824 1857//1857 1856//1856 +f 1954//1954 1939//1939 1936//1936 +f 1954//1954 529//529 1939//1939 +f 1882//1882 1183//1183 1955//1955 +f 1934//1934 1183//1183 1941//1941 +f 1941//1941 1935//1935 1930//1930 +f 1931//1931 1956//1956 1750//1750 +f 1957//1957 1288//1288 1304//1304 +f 79//79 145//145 1605//1605 +f 79//79 1357//1357 145//145 +f 1161//1161 1958//1958 446//446 +f 446//446 1958//1958 1951//1951 +f 1951//1951 1959//1959 445//445 +f 1959//1959 1894//1894 445//445 +f 1894//1894 1960//1960 1929//1929 +f 1937//1937 1954//1954 1936//1936 +f 1935//1935 1956//1956 1931//1931 +f 1961//1961 1894//1894 1959//1959 +f 1961//1961 1960//1960 1894//1894 +f 1929//1929 1945//1945 1918//1918 +f 1962//1962 1963//1963 1964//1964 +f 1648//1648 1466//1466 1477//1477 +f 1937//1937 1965//1965 1954//1954 +f 1469//1469 1262//1262 1966//1966 +f 84//84 1882//1882 1955//1955 +f 1935//1935 1096//1096 1956//1956 +f 1750//1750 1956//1956 1475//1475 +f 77//77 79//79 1605//1605 +f 1960//1960 1945//1945 1929//1929 +f 1945//1945 1967//1967 1932//1932 +f 1968//1968 1447//1447 1964//1964 +f 1269//1269 1968//1968 1964//1964 +f 1969//1969 529//529 1954//1954 +f 1970//1970 1183//1183 1882//1882 +f 1183//1183 1971//1971 1941//1941 +f 51//51 1972//1972 510//510 +f 405//405 678//678 632//632 +f 1211//1211 1402//1402 1378//1378 +f 831//831 1402//1402 1735//1735 +f 1973//1973 1719//1719 1932//1932 +f 1967//1967 1973//1973 1932//1932 +f 1932//1932 1719//1719 1326//1326 +f 1969//1969 1954//1954 1965//1965 +f 1969//1969 527//527 529//529 +f 1183//1183 1970//1970 1971//1971 +f 1096//1096 841//841 1956//1956 +f 1960//1960 1967//1967 1945//1945 +f 656//656 302//302 304//304 +f 1971//1971 1382//1382 1941//1941 +f 1941//1941 1382//1382 1935//1935 +f 1935//1935 1382//1382 1096//1096 +f 1974//1974 1975//1975 1866//1866 +f 64//64 1280//1280 1976//1976 +f 304//304 1362//1362 1622//1622 +f 1622//1622 1362//1362 419//419 +f 1358//1358 656//656 1360//1360 +f 1958//1958 1977//1977 1951//1951 +f 1608//1608 832//832 1735//1735 +f 855//855 1402//1402 1211//1211 +f 1978//1978 1969//1969 1965//1965 +f 1970//1970 1979//1979 1971//1971 +f 1980//1980 1981//1981 1982//1982 +f 1521//1521 1139//1139 1983//1983 +f 1626//1626 664//664 1630//1630 +f 1984//1984 1985//1985 1986//1986 +f 1942//1942 1987//1987 1350//1350 +f 1988//1988 1959//1959 1951//1951 +f 1959//1959 1988//1988 1961//1961 +f 578//578 1772//1772 1753//1753 +f 78//78 302//302 656//656 +f 1197//1197 1605//1605 144//144 +f 983//983 1989//1989 1965//1965 +f 1989//1989 1978//1978 1965//1965 +f 1978//1978 527//527 1969//1969 +f 852//852 851//851 691//691 +f 1990//1990 1970//1970 1882//1882 +f 1990//1990 1979//1979 1970//1970 +f 1991//1991 1922//1922 1921//1921 +f 1992//1992 205//205 1993//1993 +f 1378//1378 1381//1381 1502//1502 +f 1502//1502 1468//1468 197//197 +f 1502//1502 197//197 1503//1503 +f 1378//1378 1502//1502 277//277 +f 1378//1378 277//277 276//276 +f 1988//1988 1967//1967 1960//1960 +f 1961//1961 1988//1988 1960//1960 +f 1821//1821 1822//1822 1942//1942 +f 14//14 13//13 492//492 +f 603//603 851//851 850//850 +f 1269//1269 1582//1582 1968//1968 +f 1979//1979 1382//1382 1971//1971 +f 1981//1981 1994//1994 1995//1995 +f 1573//1573 1254//1254 1580//1580 +f 1982//1982 1981//1981 1850//1850 +f 832//832 1416//1416 833//833 +f 852//852 620//620 619//619 +f 510//510 462//462 461//461 +f 1988//1988 1996//1996 1967//1967 +f 1967//1967 1996//1996 1973//1973 +f 79//79 656//656 1357//1357 +f 605//605 1201//1201 603//603 +f 86//86 1990//1990 1882//1882 +f 1788//1788 1680//1680 1990//1990 +f 1979//1979 1680//1680 1382//1382 +f 1995//1995 1865//1865 1850//1850 +f 1997//1997 1998//1998 1999//1999 +f 2000//2000 1520//1520 1369//1369 +f 1449//1449 1506//1506 2001//2001 +f 850//850 619//619 604//604 +f 2//2 211//211 421//421 +f 1235//1235 1977//1977 1321//1321 +f 1360//1360 304//304 69//69 +f 1139//1139 1520//1520 963//963 +f 2002//2002 1570//1570 1968//1968 +f 1234//1234 1978//1978 1989//1989 +f 1978//1978 1359//1359 527//527 +f 1417//1417 1426//1426 222//222 +f 69//69 304//304 1622//1622 +f 2003//2003 1952//1952 1859//1859 +f 2004//2004 2005//2005 2006//2006 +f 70//70 171//171 105//105 +f 1977//1977 2007//2007 1951//1951 +f 1719//1719 1973//1973 1996//1996 +f 1292//1292 1018//1018 1229//1229 +f 1438//1438 1443//1443 419//419 +f 420//420 1201//1201 1202//1202 +f 267//267 357//357 195//195 +f 1466//1466 1648//1648 1535//1535 +f 607//607 939//939 158//158 +f 1245//1245 614//614 1962//1962 +f 2008//2008 2009//2009 2010//2010 +f 2010//2010 2009//2009 2011//2011 +f 1104//1104 344//344 343//343 +f 2012//2012 1896//1896 1895//1895 +f 1562//1562 1977//1977 1235//1235 +f 1996//1996 2013//2013 1719//1719 +f 1312//1312 620//620 1310//1310 +f 1692//1692 715//715 1691//1691 +f 1362//1362 1439//1439 1438//1438 +f 331//331 2003//2003 1859//1859 +f 1998//1998 2014//2014 2008//2008 +f 2011//2011 2015//2015 1216//1216 +f 1994//1994 1488//1488 1974//1974 +f 330//330 30//30 32//32 +f 1951//1951 2016//2016 1988//1988 +f 1988//1988 2016//2016 1996//1996 +f 30//30 1287//1287 31//31 +f 144//144 146//146 160//160 +f 1852//1852 2017//2017 1853//1853 +f 2018//2018 2009//2009 2008//2008 +f 2015//2015 1453//1453 1216//1216 +f 1594//1594 2019//2019 2020//2020 +f 1375//1375 191//191 105//105 +f 934//934 1355//1355 1351//1351 +f 1562//1562 2007//2007 1977//1977 +f 2016//2016 1951//1951 2007//2007 +f 2016//2016 2013//2013 1996//1996 +f 2002//2002 36//36 1570//1570 +f 1596//1596 1582//1582 1696//1696 +f 37//37 2002//2002 1582//1582 +f 2021//2021 1831//1831 2022//2022 +f 81//81 187//187 1228//1228 +f 1286//1286 1340//1340 133//133 +f 1953//1953 1952//1952 1860//1860 +f 2023//2023 2024//2024 2025//2025 +f 1966//1966 2021//2021 2026//2026 +f 2027//2027 2011//2011 2009//2009 +f 2028//2028 1849//1849 1889//1889 +f 1562//1562 2029//2029 2007//2007 +f 1340//1340 1286//1286 934//934 +f 37//37 1582//1582 1596//1596 +f 2013//2013 1720//1720 1719//1719 +f 1637//1637 1355//1355 934//934 +f 1414//1414 1440//1440 1866//1866 +f 2030//2030 2031//2031 2025//2025 +f 2012//2012 1584//1584 1896//1896 +f 2014//2014 2018//2018 2008//2008 +f 2015//2015 2011//2011 2027//2027 +f 1863//1863 1510//1510 2032//2032 +f 1707//1707 1709//1709 2033//2033 +f 205//205 2034//2034 206//206 +f 2016//2016 2035//2035 2013//2013 +f 1286//1286 1637//1637 934//934 +f 138//138 160//160 1364//1364 +f 1507//1507 1387//1387 1538//1538 +f 338//338 1230//1230 1136//1136 +f 2012//2012 2036//2036 2037//2037 +f 2038//2038 2018//2018 2014//2014 +f 2018//2018 2039//2039 2009//2009 +f 2009//2009 2039//2039 2027//2027 +f 2040//2040 1707//1707 2033//2033 +f 2041//2041 2036//2036 2042//2042 +f 2043//2043 1904//1904 2042//2042 +f 1493//1493 1500//1500 1056//1056 +f 205//205 1537//1537 2034//2034 +f 1431//1431 1888//1888 1432//1432 +f 1919//1919 1890//1890 2044//2044 +f 1407//1407 1507//1507 1506//1506 +f 278//278 277//277 1535//1535 +f 1852//1852 1858//1858 2017//2017 +f 1730//1730 2045//2045 1731//1731 +f 1731//1731 2045//2045 2046//2046 +f 1986//1986 2047//2047 1984//1984 +f 2038//2038 2048//2048 2018//2018 +f 1448//1448 1500//1500 1449//1449 +f 1853//1853 2017//2017 2049//2049 +f 784//784 1862//1862 785//785 +f 2029//2029 868//868 1828//1828 +f 2029//2029 2050//2050 2007//2007 +f 2035//2035 2016//2016 2007//2007 +f 1543//1543 1550//1550 1557//1557 +f 187//187 30//30 330//330 +f 1868//1868 1891//1891 2051//2051 +f 1984//1984 2052//2052 2038//2038 +f 2053//2053 2048//2048 2038//2038 +f 2048//2048 2039//2039 2018//2018 +f 2054//2054 2027//2027 2039//2039 +f 2027//2027 2055//2055 2015//2015 +f 2055//2055 1453//1453 2015//2015 +f 2056//2056 2057//2057 1453//1453 +f 185//185 184//184 1413//1413 +f 2022//2022 1831//1831 1830//1830 +f 1407//1407 1385//1385 1507//1507 +f 2029//2029 1828//1828 2050//2050 +f 2035//2035 1739//1739 1720//1720 +f 2013//2013 2035//2035 1720//1720 +f 1717//1717 882//882 1596//1596 +f 2058//2058 2051//2051 1891//1891 +f 1432//1432 1854//1854 2059//2059 +f 2060//2060 2061//2061 1986//1986 +f 1986//1986 2061//2061 2047//2047 +f 2038//2038 2052//2052 2053//2053 +f 2048//2048 2054//2054 2039//2039 +f 2054//2054 2055//2055 2027//2027 +f 2062//2062 1453//1453 2055//2055 +f 2063//2063 2057//2057 2056//2056 +f 1769//1769 1056//1056 1770//1770 +f 1500//1500 1448//1448 1770//1770 +f 1385//1385 1407//1407 1933//1933 +f 1827//1827 2050//2050 1828//1828 +f 2050//2050 2064//2064 2007//2007 +f 2007//2007 2064//2064 2035//2035 +f 1717//1717 1596//1596 1944//1944 +f 2065//2065 1717//1717 1944//1944 +f 2066//2066 1891//1891 1892//1892 +f 2051//2051 1730//1730 2067//2067 +f 2045//2045 2068//2068 2069//2069 +f 1801//1801 2061//2061 2060//2060 +f 2047//2047 2070//2070 1984//1984 +f 1984//1984 2070//2070 2052//2052 +f 2053//2053 2071//2071 2048//2048 +f 2048//2048 2071//2071 2054//2054 +f 2072//2072 2055//2055 2054//2054 +f 2056//2056 1453//1453 2062//2062 +f 853//853 2003//2003 331//331 +f 1500//1500 1770//1770 1056//1056 +f 2073//2073 1827//1827 1782//1782 +f 2073//2073 2050//2050 1827//1827 +f 1739//1739 2035//2035 2064//2064 +f 427//427 2069//2069 2068//2068 +f 825//825 827//827 1265//1265 +f 770//770 993//993 992//992 +f 1955//1955 1183//1183 1288//1288 +f 1518//1518 2040//2040 2033//2033 +f 2071//2071 2074//2074 2054//2054 +f 2075//2075 2072//2072 2054//2054 +f 2055//2055 1660//1660 2062//2062 +f 1660//1660 281//281 2062//2062 +f 281//281 2056//2056 2062//2062 +f 2076//2076 2059//2059 1904//1904 +f 1279//1279 1278//1278 2077//2077 +f 906//906 2073//2073 1782//1782 +f 2073//2073 2064//2064 2050//2050 +f 2065//2065 1944//1944 2078//2078 +f 2079//2079 1892//1892 75//75 +f 2079//2079 2080//2080 1892//1892 +f 2080//2080 2066//2066 1892//1892 +f 1891//1891 2066//2066 2058//2058 +f 2051//2051 2045//2045 1730//1730 +f 2052//2052 1527//1527 2053//2053 +f 2072//2072 1660//1660 2055//2055 +f 2081//2081 2082//2082 2083//2083 +f 2082//2082 2084//2084 2083//2083 +f 2085//2085 2086//2086 1371//1371 +f 1774//1774 1782//1782 1775//1775 +f 2087//2087 2064//2064 2073//2073 +f 1797//1797 2065//2065 2078//2078 +f 1753//1753 2079//2079 75//75 +f 998//998 2045//2045 2051//2051 +f 2070//2070 2088//2088 2052//2052 +f 2052//2052 2088//2088 1527//1527 +f 2053//2053 1527//1527 2071//2071 +f 2074//2074 2075//2075 2054//2054 +f 2063//2063 1522//1522 396//396 +f 2081//2081 396//396 1522//1522 +f 2081//2081 1417//1417 2082//2082 +f 119//119 1774//1774 221//221 +f 2089//2089 1488//1488 1994//1994 +f 905//905 2087//2087 2073//2073 +f 2087//2087 1739//1739 2064//2064 +f 2090//2090 2065//2065 1797//1797 +f 2090//2090 1717//1717 2065//2065 +f 2090//2090 1835//1835 1717//1717 +f 1772//1772 2079//2079 1753//1753 +f 1439//1439 1337//1337 1336//1336 +f 127//127 1739//1739 128//128 +f 1772//1772 2080//2080 2079//2079 +f 998//998 1682//1682 2045//2045 +f 2045//2045 1682//1682 2068//2068 +f 283//283 2091//2091 2070//2070 +f 2047//2047 283//283 2070//2070 +f 2070//2070 2091//2091 2088//2088 +f 2088//2088 41//41 1527//1527 +f 234//234 2075//2075 2074//2074 +f 2075//2075 1420//1420 2072//2072 +f 1395//1395 1660//1660 2072//2072 +f 281//281 280//280 2056//2056 +f 280//280 2063//2063 2056//2056 +f 222//222 2084//2084 2082//2082 +f 222//222 221//221 2084//2084 +f 119//119 1679//1679 1774//1774 +f 1679//1679 906//906 1774//1774 +f 906//906 905//905 2073//2073 +f 1311//1311 1739//1739 2087//2087 +f 996//996 2051//2051 2058//2058 +f 996//996 998//998 2051//2051 +f 2075//2075 234//234 1420//1420 +f 280//280 1522//1522 2063//2063 +f 905//905 1312//1312 2087//2087 +f 1312//1312 1311//1311 2087//2087 +f 2085//2085 2092//2092 2031//2031 +f 1497//1497 842//842 1681//1681 +f 37//37 36//36 2002//2002 +f 1476//1476 2080//2080 1772//1772 +f 1476//1476 2066//2066 2080//2080 +f 1476//1476 2058//2058 2066//2066 +f 1788//1788 85//85 1322//1322 +f 2091//2091 41//41 2088//2088 +f 2071//2071 223//223 2074//2074 +f 223//223 234//234 2074//2074 +f 1420//1420 823//823 2072//2072 +f 823//823 1395//1395 2072//2072 +f 279//279 281//281 1660//1660 +f 1417//1417 222//222 2082//2082 +f 212//212 1679//1679 119//119 +f 200//200 161//161 1492//1492 +f 656//656 304//304 1360//1360 +f 1643//1643 1835//1835 2090//2090 +f 303//303 1337//1337 1439//1439 +f 1478//1478 2058//2058 1476//1476 +f 2058//2058 1478//1478 996//996 +f 997//997 1682//1682 998//998 +f 214//214 1681//1681 1787//1787 +f 214//214 1787//1787 215//215 +f 215//215 1787//1787 1322//1322 +f 283//283 2047//2047 284//284 +f 1527//1527 186//186 2071//2071 +f 2071//2071 186//186 223//223 +f 280//280 1401//1401 1522//1522 +f 1522//1522 1418//1418 2081//2081 +f 1418//1418 1417//1417 2081//2081 +f 1864//1864 2024//2024 2093//2093 +f 2024//2024 2094//2094 2093//2093 +f 1981//1981 2095//2095 1994//1994 +f 879//879 878//878 1424//1424 +f 1779//1779 2031//2031 2030//2030 +f 2096//2096 1430//1430 2059//2059 +f 1260//1260 1615//1615 1559//1559 +f 2097//2097 2043//2043 1897//1897 +f 2012//2012 2037//2037 1071//1071 +f 570//570 27//27 775//775 +f 1432//1432 784//784 786//786 +f 1507//1507 1385//1385 1387//1387 +f 1450//1450 1449//1449 1915//1915 +f 1658//1658 1980//1980 1742//1742 +f 1980//1980 2098//2098 1742//1742 +f 231//231 1848//1848 1259//1259 +f 232//232 231//231 1259//1259 +f 84//84 1955//1955 527//527 +f 1500//1500 1407//1407 1506//1506 +f 1777//1777 1779//1779 2030//2030 +f 2099//2099 1472//1472 1539//1539 +f 827//827 826//826 1329//1329 +f 1273//1273 233//233 232//232 +f 1235//1235 568//568 245//245 +f 1742//1742 2098//2098 2100//2100 +f 2025//2025 2024//2024 2101//2101 +f 2086//2086 2085//2085 1779//1779 +f 1905//1905 1055//1055 2049//2049 +f 911//911 371//371 2102//2102 +f 2103//2103 2104//2104 2105//2105 +f 1405//1405 1440//1440 184//184 +f 2102//2102 1539//1539 911//911 +f 1911//1911 1405//1405 1372//1372 +f 1440//1440 1405//1405 1911//1911 +f 2106//2106 2004//2004 2107//2107 +f 1425//1425 974//974 1496//1496 +f 1865//1865 2108//2108 1850//1850 +f 2109//2109 1865//1865 2110//2110 +f 2111//2111 2097//2097 1897//1897 +f 95//95 1430//1430 71//71 +f 2100//2100 2028//2028 1952//1952 +f 2025//2025 2031//2031 2023//2023 +f 1994//1994 1974//1974 1865//1865 +f 2098//2098 2028//2028 2100//2100 +f 1658//1658 2095//2095 1980//1980 +f 1912//1912 2086//2086 1779//1779 +f 1865//1865 1778//1778 1651//1651 +f 1851//1851 1850//1850 2108//2108 +f 1387//1387 1864//1864 1538//1538 +f 2030//2030 2025//2025 122//122 +f 2020//2020 2112//2112 2113//2113 +f 2102//2102 2114//2114 1539//1539 +f 2114//2114 2099//2099 1539//1539 +f 1855//1855 1615//1615 1260//1260 +f 1415//1415 1414//1414 1488//1488 +f 1288//1288 528//528 1955//1955 +f 854//854 556//556 591//591 +f 528//528 1939//1939 529//529 +f 1949//1949 2115//2115 1950//1950 +f 2028//2028 2098//2098 1982//1982 +f 1651//1651 1778//1778 1777//1777 +f 1488//1488 1414//1414 1975//1975 +f 1694//1694 1143//1143 2067//2067 +f 780//780 767//767 791//791 +f 994//994 1487//1487 992//992 +f 1778//1778 1912//1912 1779//1779 +f 623//623 625//625 1390//1390 +f 1359//1359 1328//1328 85//85 +f 992//992 2095//2095 1658//1658 +f 1852//1852 1856//1856 1858//1858 +f 1506//1506 1508//1508 2001//2001 +f 1824//1824 2116//2116 1825//1825 +f 122//122 2025//2025 2101//2101 +f 2117//2117 2114//2114 2102//2102 +f 307//307 1431//1431 1430//1430 +f 2114//2114 2118//2118 2099//2099 +f 2095//2095 2089//2089 1994//1994 +f 1387//1387 1386//1386 1864//1864 +f 2077//2077 1278//1278 2119//2119 +f 2095//2095 1981//1981 1980//1980 +f 2120//2120 2043//2043 2097//2097 +f 2049//2049 1055//1055 2036//2036 +f 1250//1250 1008//1008 1551//1551 +f 111//111 120//120 307//307 +f 1500//1500 1506//1506 1449//1449 +f 1125//1125 764//764 1363//1363 +f 1982//1982 1849//1849 2028//2028 +f 1865//1865 1974//1974 1866//1866 +f 1995//1995 1994//1994 1865//1865 +f 371//371 2117//2117 2102//2102 +f 1811//1811 1952//1952 853//853 +f 1946//1946 2022//2022 1830//1830 +f 254//254 1511//1511 271//271 +f 1597//1597 1620//1620 1617//1617 +f 1620//1620 1561//1561 1617//1617 +f 2116//2116 1824//1824 1856//1856 +f 2032//2032 2114//2114 2117//2117 +f 1904//1904 2041//2041 2042//2042 +f 1430//1430 1432//1432 2059//2059 +f 1253//1253 765//765 1125//1125 +f 154//154 830//830 152//152 +f 1643//1643 2090//2090 1797//1797 +f 2121//2121 1561//1561 1620//1620 +f 2122//2122 2121//2121 1620//1620 +f 2121//2121 472//472 1561//1561 +f 2101//2101 2024//2024 1864//1864 +f 2028//2028 1860//1860 1952//1952 +f 2028//2028 1889//1889 1860//1860 +f 2077//2077 2119//2119 2123//2123 +f 1399//1399 860//860 1304//1304 +f 1233//1233 51//51 510//510 +f 2036//2036 1054//1054 2037//2037 +f 2077//2077 2123//2123 2124//2124 +f 786//786 2116//2116 1854//1854 +f 477//477 1880//1880 478//478 +f 1620//1620 1624//1624 2122//2122 +f 2122//2122 2125//2125 2121//2121 +f 2121//2121 2125//2125 472//472 +f 1864//1864 2093//2093 1538//1538 +f 1537//1537 205//205 1992//1992 +f 1624//1624 1797//1797 2122//2122 +f 1797//1797 2126//2126 2122//2122 +f 2126//2126 2125//2125 2122//2122 +f 2125//2125 835//835 472//472 +f 860//860 2127//2127 1946//1946 +f 1890//1890 1849//1849 1851//1851 +f 527//527 1955//1955 528//528 +f 1304//1304 860//860 1957//1957 +f 2078//2078 2126//2126 1797//1797 +f 417//417 226//226 835//835 +f 1628//1628 2111//2111 2019//2019 +f 2019//2019 2111//2111 2128//2128 +f 2129//2129 71//71 2096//2096 +f 1054//1054 2036//2036 1055//1055 +f 1372//1372 1389//1389 1390//1390 +f 1830//1830 1528//1528 858//858 +f 1508//1508 1538//1538 1992//1992 +f 2012//2012 1071//1071 1584//1584 +f 1432//1432 786//786 1854//1854 +f 1854//1854 2116//2116 1852//1852 +f 1172//1172 2130//2130 1173//1173 +f 2125//2125 2131//2131 835//835 +f 835//835 2131//2131 417//417 +f 1933//1933 1406//1406 1823//1823 +f 1853//1853 2041//2041 1904//1904 +f 2120//2120 2129//2129 2043//2043 +f 1848//1848 1258//1258 437//437 +f 237//237 967//967 244//244 +f 1338//1338 343//343 657//657 +f 371//371 1236//1236 2117//2117 +f 2129//2129 2096//2096 2076//2076 +f 1853//1853 2049//2049 2041//2041 +f 1172//1172 424//424 1756//1756 +f 1897//1897 2043//2043 2042//2042 +f 62//62 1448//1448 1450//1450 +f 2042//2042 2036//2036 2012//2012 +f 344//344 1284//1284 407//407 +f 205//205 204//204 1485//1485 +f 260//260 262//262 1693//1693 +f 1862//1862 1861//1861 785//785 +f 1919//1919 1844//1844 785//785 +f 1861//1861 1919//1919 785//785 +f 417//417 2132//2132 226//226 +f 226//226 2132//2132 2133//2133 +f 2134//2134 2135//2135 2136//2136 +f 418//418 575//575 576//576 +f 1863//1863 1125//1125 1510//1510 +f 1974//1974 1488//1488 1975//1975 +f 2005//2005 2137//2137 2006//2006 +f 1852//1852 2116//2116 1856//1856 +f 1993//1993 1485//1485 1484//1484 +f 1580//1580 1254//1254 1236//1236 +f 205//205 1485//1485 1993//1993 +f 681//681 680//680 1130//1130 +f 1512//1512 2118//2118 2114//2114 +f 911//911 1539//1539 1455//1455 +f 1849//1849 1890//1890 1889//1889 +f 1253//1253 1863//1863 1254//1254 +f 405//405 1433//1433 679//679 +f 1915//1915 2001//2001 1484//1484 +f 1706//1706 2138//2138 480//480 +f 853//853 1952//1952 2003//2003 +f 71//71 1430//1430 2096//2096 +f 575//575 2131//2131 2125//2125 +f 1462//1462 1472//1472 1392//1392 +f 2132//2132 255//255 2139//2139 +f 2128//2128 2111//2111 1897//1897 +f 2140//2140 2128//2128 1897//1897 +f 2141//2141 2109//2109 1650//1650 +f 1229//1229 520//520 522//522 +f 2022//2022 1946//1946 2127//2127 +f 1859//1859 1953//1953 1888//1888 +f 1487//1487 994//994 1415//1415 +f 2142//2142 2138//2138 1706//1706 +f 2142//2142 2143//2143 2138//2138 +f 2143//2143 2144//2144 2145//2145 +f 2138//2138 2143//2143 2145//2145 +f 1389//1389 1405//1405 1404//1404 +f 556//556 854//854 554//554 +f 1957//1957 860//860 1940//1940 +f 1816//1816 827//827 1447//1447 +f 1811//1811 2100//2100 1952//1952 +f 2146//2146 1947//1947 1966//1966 +f 1865//1865 2109//2109 2108//2108 +f 1484//1484 1486//1486 1915//1915 +f 2001//2001 1993//1993 1484//1484 +f 2147//2147 1536//1536 1538//1538 +f 2129//2129 2076//2076 2043//2043 +f 192//192 1561//1561 472//472 +f 1594//1594 2020//2020 1592//1592 +f 1386//1386 121//121 123//123 +f 2139//2139 2148//2148 2133//2133 +f 2149//2149 1706//1706 2150//2150 +f 2148//2148 2149//2149 2150//2150 +f 2149//2149 2142//2142 1706//1706 +f 528//528 1957//1957 1940//1940 +f 1486//1486 1632//1632 1915//1915 +f 1583//1583 1236//1236 300//300 +f 122//122 2101//2101 123//123 +f 2117//2117 1236//1236 2032//2032 +f 255//255 257//257 2139//2139 +f 257//257 2151//2151 2139//2139 +f 2139//2139 2151//2151 2148//2148 +f 2152//2152 2144//2144 2143//2143 +f 1788//1788 1990//1990 86//86 +f 770//770 992//992 1644//1644 +f 1372//1372 1371//1371 1912//1912 +f 1866//1866 1912//1912 1778//1778 +f 2149//2149 2153//2153 2142//2142 +f 2153//2153 2143//2143 2142//2142 +f 2154//2154 2144//2144 2152//2152 +f 1537//1537 1992//1992 1538//1538 +f 1236//1236 1254//1254 1863//1863 +f 2042//2042 2012//2012 1895//1895 +f 2155//2155 2152//2152 2143//2143 +f 2043//2043 2076//2076 1904//1904 +f 256//256 1665//1665 257//257 +f 1665//1665 2151//2151 257//257 +f 2156//2156 2155//2155 2143//2143 +f 2135//2135 2134//2134 2154//2154 +f 1508//1508 1992//1992 1993//1993 +f 1940//1940 1939//1939 528//528 +f 675//675 1665//1665 256//256 +f 2151//2151 2157//2157 2149//2149 +f 2148//2148 2151//2151 2149//2149 +f 2149//2149 2157//2157 2153//2153 +f 2143//2143 2153//2153 2156//2156 +f 329//329 71//71 2129//2129 +f 2017//2017 1905//1905 2049//2049 +f 2158//2158 2152//2152 2155//2155 +f 1510//1510 1363//1363 1511//1511 +f 329//329 2129//2129 2120//2120 +f 307//307 120//120 1431//1431 +f 1510//1510 1125//1125 1363//1363 +f 1372//1372 1405//1405 1389//1389 +f 2096//2096 2059//2059 2076//2076 +f 1331//1331 1665//1665 675//675 +f 1564//1564 2157//2157 2151//2151 +f 2158//2158 2154//2154 2152//2152 +f 1564//1564 2151//2151 1665//1665 +f 2157//2157 2159//2159 2153//2153 +f 2153//2153 2159//2159 2156//2156 +f 2156//2156 2158//2158 2155//2155 +f 2160//2160 2154//2154 2158//2158 +f 2001//2001 1508//1508 1993//1993 +f 329//329 2120//2120 1628//1628 +f 120//120 331//331 1859//1859 +f 1975//1975 1414//1414 1866//1866 +f 2002//2002 1968//1968 1582//1582 +f 1564//1564 1427//1427 2157//2157 +f 1427//1427 2161//2161 2157//2157 +f 2157//2157 2161//2161 2159//2159 +f 2160//2160 2135//2135 2154//2154 +f 2160//2160 2136//2136 2135//2135 +f 2162//2162 287//287 1291//1291 +f 2041//2041 2049//2049 2036//2036 +f 1252//1252 765//765 1253//1253 +f 1431//1431 1859//1859 1888//1888 +f 575//575 2125//2125 801//801 +f 1811//1811 1742//1742 2100//2100 +f 1825//1825 2116//2116 2163//2163 +f 2042//2042 1895//1895 1897//1897 +f 534//534 898//898 899//899 +f 1844//1844 2163//2163 2116//2116 +f 1564//1564 1428//1428 1427//1427 +f 2164//2164 2158//2158 2156//2156 +f 208//208 325//325 680//680 +f 1136//1136 2165//2165 1463//1463 +f 1777//1777 2030//2030 122//122 +f 2089//2089 1487//1487 1488//1488 +f 1844//1844 2116//2116 786//786 +f 2159//2159 2166//2166 2156//2156 +f 2166//2166 2164//2164 2156//2156 +f 2164//2164 2160//2160 2158//2158 +f 1897//1897 1896//1896 2140//2140 +f 1507//1507 1538//1538 1508//1508 +f 2098//2098 1980//1980 1982//1982 +f 1677//1677 1811//1811 853//853 +f 1673//1673 1742//1742 1811//1811 +f 803//803 749//749 1567//1567 +f 2161//2161 2167//2167 2159//2159 +f 1920//1920 1922//1922 1650//1650 +f 1512//1512 1511//1511 2168//2168 +f 2109//2109 2110//2110 1650//1650 +f 2109//2109 2141//2141 2108//2108 +f 1865//1865 1651//1651 2110//2110 +f 992//992 1487//1487 2089//2089 +f 1449//1449 2001//2001 1915//1915 +f 1890//1890 1851//1851 2044//2044 +f 1911//1911 1372//1372 1912//1912 +f 2123//2123 2119//2119 2169//2169 +f 2020//2020 2128//2128 2140//2140 +f 2095//2095 992//992 2089//2089 +f 2044//2044 1851//1851 2170//2170 +f 2020//2020 2140//2140 2112//2112 +f 528//528 1288//1288 1957//1957 +f 1968//1968 1570//1570 1265//1265 +f 1866//1866 1440//1440 1912//1912 +f 1816//1816 1447//1447 1968//1968 +f 1385//1385 1921//1921 1386//1386 +f 2044//2044 1844//1844 1919//1919 +f 1953//1953 1860//1860 1888//1888 +f 596//596 494//494 597//597 +f 2159//2159 2167//2167 2166//2166 +f 2171//2171 2160//2160 2164//2164 +f 2171//2171 2172//2172 2160//2160 +f 2172//2172 2136//2136 2160//2160 +f 2172//2172 1092//1092 2136//2136 +f 2111//2111 2120//2120 2097//2097 +f 1628//1628 2120//2120 2111//2111 +f 1982//1982 1850//1850 1849//1849 +f 1236//1236 1863//1863 2032//2032 +f 1943//1943 1596//1596 1696//1696 +f 1411//1411 2173//2173 2092//2092 +f 1779//1779 2085//2085 2031//2031 +f 1427//1427 1429//1429 1592//1592 +f 1427//1427 2167//2167 2161//2161 +f 2112//2112 2166//2166 2167//2167 +f 2113//2113 2112//2112 2167//2167 +f 2112//2112 2164//2164 2166//2166 +f 2112//2112 2140//2140 2164//2164 +f 2140//2140 2171//2171 2164//2164 +f 2059//2059 1854//1854 1904//1904 +f 123//123 2101//2101 1864//1864 +f 1868//1868 2051//2051 2067//2067 +f 1510//1510 2114//2114 2032//2032 +f 1644//1644 992//992 1658//1658 +f 1233//1233 510//510 461//461 +f 1427//1427 1592//1592 2167//2167 +f 1896//1896 2172//2172 2171//2171 +f 1981//1981 1995//1995 1850//1850 +f 2019//2019 2128//2128 2020//2020 +f 1510//1510 1512//1512 2114//2114 +f 1130//1130 635//635 1100//1100 +f 1968//1968 1265//1265 1816//1816 +f 2169//2169 2119//2119 2174//2174 +f 2020//2020 2167//2167 1592//1592 +f 2020//2020 2113//2113 2167//2167 +f 2172//2172 1896//1896 1092//1092 +f 1447//1447 1329//1329 1962//1962 +f 931//931 1618//1618 933//933 +f 2023//2023 2031//2031 2173//2173 +f 2140//2140 1896//1896 2171//2171 +f 1946//1946 1830//1830 858//858 +f 1920//1920 1649//1649 121//121 +f 2011//2011 1216//1216 1215//1215 +f 1835//1835 939//939 1717//1717 +f 1453//1453 2057//2057 1454//1454 +f 1728//1728 1715//1715 1789//1789 +f 90//90 2057//2057 91//91 +f 1454//1454 2057//2057 90//90 +f 2175//2175 2057//2057 2063//2063 +f 1842//1842 90//90 2145//2145 +f 2176//2176 90//90 1842//1842 +f 395//395 2177//2177 2178//2178 +f 16//16 506//506 555//555 +f 1830//1830 1554//1554 1528//1528 +f 395//395 1839//1839 2177//2177 +f 1839//1839 2179//2179 2177//2177 +f 241//241 1511//1511 254//254 +f 2179//2179 1839//1839 2180//2180 +f 2181//2181 2168//2168 1511//1511 +f 241//241 2181//2181 1511//1511 +f 2182//2182 2183//2183 2134//2134 +f 2180//2180 1782//1782 1826//1826 +f 2181//2181 2184//2184 2168//2168 +f 2184//2184 2185//2185 2168//2168 +f 463//463 1868//1868 2067//2067 +f 251//251 2186//2186 241//241 +f 241//241 2186//2186 2181//2181 +f 172//172 2187//2187 1232//1232 +f 1365//1365 2188//2188 974//974 +f 1997//1997 1999//1999 2189//2189 +f 2190//2190 1213//1213 966//966 +f 1103//1103 616//616 478//478 +f 1552//1552 2021//2021 1262//1262 +f 1990//1990 1680//1680 1979//1979 +f 2186//2186 2184//2184 2181//2181 +f 1836//1836 1838//1838 1907//1907 +f 1837//1837 1836//1836 1846//1846 +f 1789//1789 2191//2191 1726//1726 +f 2192//2192 2193//2193 2194//2194 +f 2078//2078 2195//2195 801//801 +f 1985//1985 2196//2196 2192//2192 +f 1986//1986 1985//1985 2192//2192 +f 1173//1173 2130//2130 251//251 +f 2130//2130 2197//2197 2186//2186 +f 251//251 2130//2130 2186//2186 +f 2185//2185 2099//2099 2118//2118 +f 1986//1986 2192//2192 2060//2060 +f 1985//1985 1997//1997 2196//2196 +f 2198//2198 1763//1763 2183//2183 +f 2199//2199 2200//2200 2191//2191 +f 2154//2154 2183//2183 2144//2144 +f 394//394 396//396 2081//2081 +f 2197//2197 2201//2201 2186//2186 +f 2186//2186 2201//2201 2184//2184 +f 2201//2201 1473//1473 2185//2185 +f 2184//2184 2201//2201 2185//2185 +f 2021//2021 1552//1552 1831//1831 +f 1554//1554 1831//1831 1552//1552 +f 172//172 1231//1231 2202//2202 +f 1826//1826 868//868 788//788 +f 1410//1410 1409//1409 2203//2203 +f 1962//1962 1964//1964 1447//1447 +f 1857//1857 2017//2017 1858//1858 +f 2185//2185 1473//1473 2099//2099 +f 1473//1473 1472//1472 2099//2099 +f 2179//2179 176//176 1314//1314 +f 2179//2179 2180//2180 176//176 +f 176//176 2180//2180 2204//2204 +f 396//396 2178//2178 2175//2175 +f 396//396 395//395 2178//2178 +f 1724//1724 1726//1726 2205//2205 +f 175//175 493//493 224//224 +f 1450//1450 1915//1915 1916//1916 +f 1789//1789 1761//1761 2191//2191 +f 2177//2177 92//92 91//91 +f 1172//1172 1756//1756 2130//2130 +f 1839//1839 1775//1775 2180//2180 +f 1725//1725 1789//1789 1726//1726 +f 1997//1997 2189//2189 2196//2196 +f 2187//2187 172//172 1169//1169 +f 175//175 2150//2150 1706//1706 +f 175//175 224//224 2150//2150 +f 2180//2180 1775//1775 1782//1782 +f 1756//1756 1755//1755 2130//2130 +f 1755//1755 2197//2197 2130//2130 +f 1958//1958 1161//1161 1321//1321 +f 2176//2176 1454//1454 90//90 +f 1641//1641 213//213 1328//1328 +f 213//213 1641//1641 214//214 +f 2191//2191 2198//2198 2206//2206 +f 2199//2199 2191//2191 2206//2206 +f 2207//2207 2200//2200 2199//2199 +f 224//224 226//226 2133//2133 +f 2208//2208 2207//2207 1806//1806 +f 2208//2208 2200//2200 2207//2207 +f 840//840 2209//2209 1474//1474 +f 2069//2069 1731//1731 2046//2046 +f 2069//2069 2210//2210 1731//1731 +f 1782//1782 1827//1827 1826//1826 +f 2197//2197 2211//2211 2201//2201 +f 1393//1393 1473//1473 2201//2201 +f 2211//2211 1393//1393 2201//2201 +f 1493//1493 1905//1905 1408//1408 +f 172//172 2202//2202 173//173 +f 1615//1615 1855//1855 1662//1662 +f 1390//1390 625//625 1372//1372 +f 1493//1493 1056//1056 1055//1055 +f 2207//2207 1297//1297 1334//1334 +f 1333//1333 2207//2207 1334//1334 +f 2189//2189 1727//1727 2212//2212 +f 1857//1857 1823//1823 1832//1832 +f 174//174 173//173 2213//2213 +f 424//424 1172//1172 1219//1219 +f 2214//2214 2182//2182 2136//2136 +f 2215//2215 1807//1807 1332//1332 +f 1727//1727 2010//2010 1215//1215 +f 1755//1755 1847//1847 2197//2197 +f 2197//2197 1847//1847 2211//2211 +f 801//801 2126//2126 2078//2078 +f 173//173 1807//1807 2215//2215 +f 624//624 1371//1371 625//625 +f 2136//2136 2182//2182 2134//2134 +f 1847//1847 1393//1393 2211//2211 +f 1956//1956 841//841 1475//1475 +f 1727//1727 1215//1215 1728//1728 +f 1371//1371 2086//2086 1912//1912 +f 2175//2175 2178//2178 91//91 +f 1806//1806 1333//1333 1332//1332 +f 2216//2216 966//966 324//324 +f 1701//1701 1232//1232 2210//2210 +f 2057//2057 2175//2175 91//91 +f 1584//1584 1092//1092 1896//1896 +f 1999//1999 2008//2008 2010//2010 +f 868//868 2029//2029 1562//1562 +f 2213//2213 2215//2215 2217//2217 +f 2213//2213 2209//2209 2187//2187 +f 1132//1132 143//143 730//730 +f 1985//1985 2038//2038 1997//1997 +f 2218//2218 1801//1801 2060//2060 +f 1126//1126 324//324 966//966 +f 1743//1743 1766//1766 1491//1491 +f 2219//2219 1641//1641 1695//1695 +f 1701//1701 2210//2210 2069//2069 +f 426//426 1701//1701 2069//2069 +f 1806//1806 2207//2207 1333//1333 +f 255//255 2132//2132 417//417 +f 624//624 2092//2092 1371//1371 +f 1520//1520 1139//1139 1521//1521 +f 2220//2220 2221//2221 2222//2222 +f 2119//2119 1278//1278 2223//2223 +f 1999//1999 1727//1727 2189//2189 +f 426//426 2069//2069 427//427 +f 2224//2224 173//173 2202//2202 +f 974//974 2188//2188 1496//1496 +f 1334//1334 1296//1296 2225//2225 +f 2195//2195 2190//2190 2216//2216 +f 2177//2177 479//479 92//92 +f 424//424 423//423 1755//1755 +f 423//423 1847//1847 1755//1755 +f 1731//1731 2210//2210 2221//2221 +f 471//471 473//473 247//247 +f 2187//2187 2209//2209 2226//2226 +f 1857//1857 1824//1824 1823//1823 +f 177//177 493//493 175//175 +f 1731//1731 2219//2219 1694//1694 +f 2227//2227 1516//1516 1383//1383 +f 1537//1537 1536//1536 2228//2228 +f 2177//2177 1314//1314 479//479 +f 1210//1210 971//971 1083//1083 +f 1278//1278 1370//1370 2223//2223 +f 2173//2173 1411//1411 880//880 +f 2092//2092 2085//2085 1371//1371 +f 2229//2229 2224//2224 2202//2202 +f 2207//2207 2199//2199 1297//1297 +f 2199//2199 1298//1298 1297//1297 +f 1423//1423 2230//2230 879//879 +f 2231//2231 2173//2173 880//880 +f 1678//1678 2232//2232 2214//2214 +f 1715//1715 1762//1762 1761//1761 +f 2196//2196 2189//2189 2229//2229 +f 1461//1461 1685//1685 1884//1884 +f 1083//1083 2233//2233 1210//1210 +f 2233//2233 1208//1208 1210//1210 +f 1916//1916 1632//1632 1634//1634 +f 1496//1496 2230//2230 1423//1423 +f 2230//2230 880//880 879//879 +f 1538//1538 2093//2093 2147//2147 +f 1810//1810 1834//1834 1032//1032 +f 1834//1834 2232//2232 1678//1678 +f 1874//1874 438//438 1767//1767 +f 2219//2219 2220//2220 1641//1641 +f 2234//2234 2187//2187 2226//2226 +f 2233//2233 1365//1365 1208//1208 +f 2230//2230 2231//2231 880//880 +f 2231//2231 2235//2235 2173//2173 +f 2196//2196 2229//2229 2193//2193 +f 1314//1314 176//176 175//175 +f 801//801 323//323 575//575 +f 1083//1083 1555//1555 2233//2233 +f 2233//2233 2236//2236 1365//1365 +f 1365//1365 2236//2236 2188//2188 +f 2188//2188 2237//2237 1496//1496 +f 2237//2237 2238//2238 2230//2230 +f 1496//1496 2237//2237 2230//2230 +f 2230//2230 2238//2238 2231//2231 +f 2238//2238 2239//2239 2231//2231 +f 2239//2239 2240//2240 2231//2231 +f 2240//2240 2235//2235 2231//2231 +f 1641//1641 2222//2222 1642//1642 +f 1369//1369 1521//1521 1370//1370 +f 2221//2221 2234//2234 2222//2222 +f 2218//2218 1701//1701 426//426 +f 2182//2182 2198//2198 2183//2183 +f 1763//1763 1842//1842 2144//2144 +f 1555//1555 2241//2241 2233//2233 +f 2188//2188 2242//2242 2237//2237 +f 2173//2173 2235//2235 2023//2023 +f 128//128 1739//1739 1311//1311 +f 446//446 1526//1526 1893//1893 +f 983//983 51//51 1234//1234 +f 1169//1169 174//174 2187//2187 +f 453//453 75//75 1892//1892 +f 1726//1726 2200//2200 2208//2208 +f 2233//2233 2243//2243 2236//2236 +f 2236//2236 2243//2243 2188//2188 +f 2243//2243 2242//2242 2188//2188 +f 1695//1695 1641//1641 1328//1328 +f 2217//2217 2225//2225 1474//1474 +f 1649//1649 1651//1651 1777//1777 +f 1486//1486 1485//1485 2244//2244 +f 463//463 2067//2067 1143//1143 +f 2237//2237 2245//2245 2238//2238 +f 2240//2240 2246//2246 2235//2235 +f 1411//1411 624//624 1412//1412 +f 1144//1144 1695//1695 1328//1328 +f 1642//1642 2234//2234 1498//1498 +f 2217//2217 1474//1474 2209//2209 +f 1232//1232 2187//2187 2221//2221 +f 1330//1330 1350//1350 2247//2247 +f 2218//2218 1231//1231 1701//1701 +f 2233//2233 2241//2241 2243//2243 +f 2234//2234 2226//2226 1498//1498 +f 2226//2226 2209//2209 1498//1498 +f 2209//2209 2213//2213 2217//2217 +f 2227//2227 2248//2248 1516//1516 +f 1516//1516 2248//2248 1555//1555 +f 1555//1555 2248//2248 2241//2241 +f 2242//2242 2245//2245 2237//2237 +f 2238//2238 2245//2245 2239//2239 +f 2249//2249 2023//2023 2235//2235 +f 1450//1450 1710//1710 62//62 +f 2094//2094 2024//2024 2023//2023 +f 2118//2118 2168//2168 2185//2185 +f 1649//1649 122//122 121//121 +f 1998//1998 1997//1997 2038//2038 +f 2137//2137 2250//2250 2251//2251 +f 1805//1805 1943//1943 1696//1696 +f 2193//2193 2202//2202 1231//1231 +f 177//177 2204//2204 788//788 +f 2248//2248 2252//2252 2241//2241 +f 2241//2241 2253//2253 2243//2243 +f 2253//2253 2242//2242 2243//2243 +f 2254//2254 2246//2246 2240//2240 +f 2179//2179 1314//1314 2177//2177 +f 1233//1233 461//461 463//463 +f 1031//1031 1296//1296 1810//1810 +f 2063//2063 396//396 2175//2175 +f 1383//1383 1394//1394 2227//2227 +f 2255//2255 2256//2256 2245//2245 +f 2245//2245 2256//2256 2239//2239 +f 2256//2256 2240//2240 2239//2239 +f 2246//2246 2257//2257 2235//2235 +f 2257//2257 2249//2249 2235//2235 +f 2249//2249 2094//2094 2023//2023 +f 1805//1805 1213//1213 2190//2190 +f 453//453 1892//1892 1868//1868 +f 2232//2232 2206//2206 2182//2182 +f 1517//1517 1302//1302 1518//1518 +f 2227//2227 2258//2258 2248//2248 +f 2248//2248 2259//2259 2252//2252 +f 2252//2252 2260//2260 2241//2241 +f 2253//2253 2261//2261 2242//2242 +f 2242//2242 2262//2262 2245//2245 +f 343//343 616//616 1104//1104 +f 1234//1234 1989//1989 983//983 +f 2092//2092 624//624 1411//1411 +f 2248//2248 2258//2258 2259//2259 +f 2259//2259 2260//2260 2252//2252 +f 2241//2241 2260//2260 2253//2253 +f 2242//2242 2261//2261 2262//2262 +f 2262//2262 2263//2263 2245//2245 +f 2245//2245 2263//2263 2255//2255 +f 2254//2254 2240//2240 2256//2256 +f 2254//2254 2257//2257 2246//2246 +f 1092//1092 2214//2214 2136//2136 +f 1298//1298 2199//2199 2232//2232 +f 2199//2199 2206//2206 2232//2232 +f 208//208 681//681 209//209 +f 2227//2227 2264//2264 2258//2258 +f 2263//2263 2265//2265 2255//2255 +f 2222//2222 2234//2234 1642//1642 +f 1770//1770 1448//1448 64//64 +f 1944//1944 1943//1943 2078//2078 +f 1530//1530 2266//2266 2227//2227 +f 2259//2259 2258//2258 2264//2264 +f 2267//2267 2255//2255 2265//2265 +f 2267//2267 2268//2268 2256//2256 +f 2255//2255 2267//2267 2256//2256 +f 2268//2268 2269//2269 2254//2254 +f 2256//2256 2268//2268 2254//2254 +f 2254//2254 2269//2269 2257//2257 +f 2257//2257 2270//2270 2249//2249 +f 2270//2270 2094//2094 2249//2249 +f 1296//1296 1834//1834 1810//1810 +f 2225//2225 1296//1296 1549//1549 +f 1259//1259 1848//1848 1855//1855 +f 592//592 456//456 626//626 +f 1938//1938 859//859 858//858 +f 1991//1991 2170//2170 2141//2141 +f 973//973 1555//1555 1083//1083 +f 1773//1773 2084//2084 1774//1774 +f 2094//2094 2271//2271 2093//2093 +f 2260//2260 2272//2272 2253//2253 +f 2261//2261 2273//2273 2262//2262 +f 2269//2269 2274//2274 2257//2257 +f 2274//2274 2270//2270 2257//2257 +f 2094//2094 2270//2270 2271//2271 +f 1521//1521 1983//1983 1370//1370 +f 1805//1805 1224//1224 1213//1213 +f 1789//1789 1715//1715 1761//1761 +f 1474//1474 1549//1549 1542//1542 +f 1922//1922 1991//1991 2141//2141 +f 1459//1459 813//813 632//632 +f 2204//2204 2180//2180 1826//1826 +f 1216//1216 1454//1454 2176//2176 +f 2189//2189 2212//2212 2224//2224 +f 1715//1715 1216//1216 2176//2176 +f 2227//2227 2266//2266 2264//2264 +f 2259//2259 2272//2272 2260//2260 +f 2272//2272 2275//2275 2253//2253 +f 2253//2253 2275//2275 2261//2261 +f 2268//2268 2276//2276 2269//2269 +f 2276//2276 2277//2277 2269//2269 +f 2269//2269 2277//2277 2274//2274 +f 1359//1359 463//463 1144//1144 +f 1234//1234 463//463 1359//1359 +f 1762//1762 2176//2176 1842//1842 +f 1825//1825 2170//2170 1991//1991 +f 2183//2183 2154//2154 2134//2134 +f 1839//1839 1773//1773 1775//1775 +f 2259//2259 2278//2278 2272//2272 +f 2263//2263 2262//2262 2265//2265 +f 1641//1641 2220//2220 2222//2222 +f 2163//2163 2170//2170 1825//1825 +f 2163//2163 2044//2044 2170//2170 +f 2195//2195 2078//2078 1943//1943 +f 569//569 568//568 1161//1161 +f 2278//2278 2279//2279 2272//2272 +f 2272//2272 2273//2273 2275//2275 +f 2273//2273 2261//2261 2275//2275 +f 2273//2273 2280//2280 2262//2262 +f 2277//2277 2281//2281 2274//2274 +f 2281//2281 2270//2270 2274//2274 +f 1549//1549 1296//1296 217//217 +f 1851//1851 2108//2108 2170//2170 +f 2178//2178 2177//2177 91//91 +f 2219//2219 2221//2221 2220//2220 +f 2280//2280 2265//2265 2262//2262 +f 2267//2267 2282//2282 2268//2268 +f 2268//2268 2282//2282 2276//2276 +f 2147//2147 2271//2271 2270//2270 +f 2281//2281 2147//2147 2270//2270 +f 2067//2067 1730//1730 1694//1694 +f 1933//1933 1991//1991 1921//1921 +f 801//801 2195//2195 802//802 +f 53//53 1972//1972 51//51 +f 1874//1874 1103//1103 478//478 +f 2279//2279 2283//2283 2272//2272 +f 2283//2283 2284//2284 2272//2272 +f 2284//2284 2285//2285 2272//2272 +f 2272//2272 2285//2285 2273//2273 +f 2285//2285 2280//2280 2273//2273 +f 1296//1296 1298//1298 1834//1834 +f 1844//1844 2044//2044 2163//2163 +f 1922//1922 2141//2141 1650//1650 +f 1806//1806 1726//1726 2208//2208 +f 437//437 1767//1767 438//438 +f 2264//2264 2286//2286 2259//2259 +f 2259//2259 2286//2286 2278//2278 +f 2276//2276 2287//2287 2277//2277 +f 2277//2277 2287//2287 2281//2281 +f 2288//2288 2278//2278 2286//2286 +f 2278//2278 2288//2288 2279//2279 +f 2285//2285 2289//2289 2280//2280 +f 2289//2289 2290//2290 2265//2265 +f 2280//2280 2289//2289 2265//2265 +f 2290//2290 2267//2267 2265//2265 +f 174//174 2213//2213 2187//2187 +f 1143//1143 1695//1695 1144//1144 +f 1530//1530 2291//2291 2266//2266 +f 2288//2288 2292//2292 2279//2279 +f 2279//2279 2292//2292 2283//2283 +f 2284//2284 2289//2289 2285//2285 +f 2282//2282 2293//2293 2276//2276 +f 2287//2287 2294//2294 2281//2281 +f 2195//2195 1943//1943 1805//1805 +f 1276//1276 1847//1847 423//423 +f 1823//1823 1991//1991 1933//1933 +f 2224//2224 1807//1807 173//173 +f 2204//2204 1826//1826 788//788 +f 1470//1470 1947//1947 1530//1530 +f 1530//1530 1947//1947 2291//2291 +f 2295//2295 2267//2267 2290//2290 +f 2267//2267 2295//2295 2282//2282 +f 2276//2276 2293//2293 2287//2287 +f 2228//2228 2147//2147 2281//2281 +f 1823//1823 1825//1825 1991//1991 +f 2133//2133 2148//2148 2150//2150 +f 2131//2131 575//575 417//417 +f 2291//2291 2296//2296 2266//2266 +f 2296//2296 2264//2264 2266//2266 +f 2292//2292 2297//2297 2283//2283 +f 2284//2284 2297//2297 2289//2289 +f 2287//2287 2298//2298 2294//2294 +f 2228//2228 2281//2281 2294//2294 +f 2229//2229 2189//2189 2224//2224 +f 2216//2216 2190//2190 966//966 +f 1836//1836 1634//1634 1633//1633 +f 1470//1470 1494//1494 1947//1947 +f 2264//2264 2296//2296 2286//2286 +f 2283//2283 2297//2297 2284//2284 +f 2297//2297 2299//2299 2289//2289 +f 2293//2293 2300//2300 2287//2287 +f 2300//2300 2298//2298 2287//2287 +f 2298//2298 2228//2228 2294//2294 +f 2083//2083 2084//2084 1773//1773 +f 2217//2217 2215//2215 2225//2225 +f 2200//2200 1726//1726 2191//2191 +f 2282//2282 2301//2301 2293//2293 +f 1280//1280 1071//1071 1976//1976 +f 1976//1976 1071//1071 2037//2037 +f 2195//2195 1805//1805 2190//2190 +f 2083//2083 1773//1773 394//394 +f 176//176 2204//2204 177//177 +f 2296//2296 2302//2302 2286//2286 +f 2286//2286 2302//2302 2288//2288 +f 2292//2292 2303//2303 2297//2297 +f 2299//2299 2304//2304 2289//2289 +f 2289//2289 2304//2304 2290//2290 +f 2295//2295 2301//2301 2282//2282 +f 2293//2293 2305//2305 2300//2300 +f 1133//1133 1444//1444 1241//1241 +f 2034//2034 1537//1537 2228//2228 +f 2081//2081 2083//2083 394//394 +f 1519//1519 1518//1518 2306//2306 +f 2221//2221 2187//2187 2234//2234 +f 2302//2302 2307//2307 2288//2288 +f 2307//2307 2303//2303 2292//2292 +f 2288//2288 2307//2307 2292//2292 +f 2303//2303 2308//2308 2297//2297 +f 2304//2304 2309//2309 2290//2290 +f 2309//2309 2295//2295 2290//2290 +f 2108//2108 2141//2141 2170//2170 +f 51//51 1233//1233 1234//1234 +f 1678//1678 2214//2214 1092//1092 +f 2297//2297 2310//2310 2299//2299 +f 2301//2301 2305//2305 2293//2293 +f 206//206 2228//2228 2298//2298 +f 206//206 2034//2034 2228//2228 +f 1826//1826 1828//1828 868//868 +f 437//437 1855//1855 1848//1848 +f 2308//2308 2311//2311 2297//2297 +f 2297//2297 2311//2311 2310//2310 +f 2299//2299 2312//2312 2304//2304 +f 2305//2305 2313//2313 2300//2300 +f 2313//2313 2298//2298 2300//2300 +f 1731//1731 2221//2221 2219//2219 +f 1832//1832 1905//1905 1857//1857 +f 1985//1985 1984//1984 2038//2038 +f 2195//2195 2216//2216 802//802 +f 2183//2183 1763//1763 2144//2144 +f 75//75 452//452 76//76 +f 2144//2144 1842//1842 2145//2145 +f 2312//2312 2309//2309 2304//2304 +f 2309//2309 2314//2314 2301//2301 +f 2295//2295 2309//2309 2301//2301 +f 2314//2314 2315//2315 2305//2305 +f 2301//2301 2314//2314 2305//2305 +f 2021//2021 1966//1966 1262//1262 +f 452//452 451//451 76//76 +f 1761//1761 2198//2198 2191//2191 +f 1947//1947 2146//2146 2291//2291 +f 2291//2291 2146//2146 2296//2296 +f 2299//2299 2310//2310 2312//2312 +f 2315//2315 2316//2316 2305//2305 +f 2305//2305 2316//2316 2313//2313 +f 2313//2313 2317//2317 2298//2298 +f 2298//2298 2317//2317 206//206 +f 2060//2060 2194//2194 2218//2218 +f 1332//1332 1334//1334 2225//2225 +f 2210//2210 1232//1232 2221//2221 +f 2147//2147 2228//2228 1536//1536 +f 2308//2308 2318//2318 2311//2311 +f 2312//2312 2319//2319 2309//2309 +f 2316//2316 2317//2317 2313//2313 +f 2198//2198 1761//1761 1763//1763 +f 1245//1245 1329//1329 1246//1246 +f 1965//1965 52//52 983//983 +f 1965//1965 1937//1937 52//52 +f 510//510 1972//1972 1409//1409 +f 233//233 1284//1284 1258//1258 +f 1407//1407 1406//1406 1933//1933 +f 2310//2310 2319//2319 2312//2312 +f 2314//2314 2320//2320 2315//2315 +f 1354//1354 2321//2321 1708//1708 +f 1806//1806 2205//2205 1726//1726 +f 1555//1555 1509//1509 1516//1516 +f 1332//1332 2225//2225 2215//2215 +f 494//494 245//245 597//597 +f 2322//2322 1519//1519 2306//2306 +f 1938//1938 1523//1523 1936//1936 +f 1434//1434 1433//1433 404//404 +f 404//404 2323//2323 1434//1434 +f 1474//1474 2225//2225 1549//1549 +f 2146//2146 2026//2026 2296//2296 +f 2296//2296 2324//2324 2302//2302 +f 2325//2325 2307//2307 2302//2302 +f 2324//2324 2325//2325 2302//2302 +f 2325//2325 2303//2303 2307//2307 +f 2303//2303 2318//2318 2308//2308 +f 2311//2311 2319//2319 2310//2310 +f 2319//2319 2326//2326 2309//2309 +f 2317//2317 204//204 206//206 +f 994//994 993//993 769//769 +f 1868//1868 462//462 453//453 +f 1095//1095 1768//1768 1147//1147 +f 1650//1650 1649//1649 1920//1920 +f 1715//1715 2176//2176 1762//1762 +f 1054//1054 1976//1976 2037//2037 +f 2321//2321 2327//2327 1277//1277 +f 2133//2133 2132//2132 2139//2139 +f 2296//2296 2026//2026 2324//2324 +f 2326//2326 2320//2320 2314//2314 +f 2309//2309 2326//2326 2314//2314 +f 2320//2320 2328//2328 2315//2315 +f 2315//2315 2328//2328 2316//2316 +f 2316//2316 2329//2329 2317//2317 +f 1873//1873 478//478 1880//1880 +f 2212//2212 2205//2205 2224//2224 +f 1268//1268 1696//1696 1582//1582 +f 1801//1801 2218//2218 426//426 +f 2330//2330 1410//1410 2203//2203 +f 1410//1410 2330//2330 451//451 +f 2327//2327 1278//1278 1277//1277 +f 1433//1433 405//405 404//404 +f 1434//1434 2323//2323 614//614 +f 1999//1999 1998//1998 2008//2008 +f 1227//1227 962//962 1520//1520 +f 2331//2331 2303//2303 2325//2325 +f 2331//2331 2318//2318 2303//2303 +f 2311//2311 2318//2318 2319//2319 +f 2318//2318 2332//2332 2319//2319 +f 2319//2319 2332//2332 2326//2326 +f 2329//2329 204//204 2317//2317 +f 2205//2205 1806//1806 2224//2224 +f 1728//1728 1217//1217 1715//1715 +f 1493//1493 1055//1055 1905//1905 +f 614//614 2323//2323 1962//1962 +f 1215//1215 1217//1217 1728//1728 +f 74//74 1754//1754 75//75 +f 2333//2333 1237//1237 1366//1366 +f 2092//2092 2173//2173 2031//2031 +f 1874//1874 1767//1767 1103//1103 +f 2326//2326 2334//2334 2320//2320 +f 2320//2320 2334//2334 2328//2328 +f 2206//2206 2198//2198 2182//2182 +f 1694//1694 2219//2219 1695//1695 +f 2232//2232 2182//2182 2214//2214 +f 436//436 1855//1855 437//437 +f 2335//2335 2336//2336 2337//2337 +f 1963//1963 2323//2323 404//404 +f 2146//2146 1966//1966 2026//2026 +f 2331//2331 2338//2338 2318//2318 +f 2338//2338 2332//2332 2318//2318 +f 2326//2326 2339//2339 2334//2334 +f 2340//2340 204//204 2329//2329 +f 2192//2192 2194//2194 2060//2060 +f 75//75 1754//1754 1753//1753 +f 1727//1727 2205//2205 2212//2212 +f 680//680 633//633 635//635 +f 2341//2341 1963//1963 404//404 +f 1963//1963 1962//1962 2323//2323 +f 1329//1329 1245//1245 1962//1962 +f 2332//2332 2339//2339 2326//2326 +f 2340//2340 2244//2244 204//204 +f 2244//2244 1485//1485 204//204 +f 2194//2194 2193//2193 1231//1231 +f 394//394 1839//1839 395//395 +f 221//221 1774//1774 2084//2084 +f 2194//2194 1231//1231 2218//2218 +f 2342//2342 2343//2343 278//278 +f 1872//1872 2338//2338 2331//2331 +f 2334//2334 2344//2344 2328//2328 +f 2316//2316 2340//2340 2329//2329 +f 2229//2229 2202//2202 2193//2193 +f 1727//1727 1724//1724 2205//2205 +f 1298//1298 2232//2232 1834//1834 +f 1642//1642 1498//1498 1497//1497 +f 1469//1469 892//892 1262//1262 +f 1727//1727 1729//1729 1724//1724 +f 2345//2345 2325//2325 2324//2324 +f 2345//2345 2331//2331 2325//2325 +f 2332//2332 2346//2346 2339//2339 +f 2346//2346 2334//2334 2339//2339 +f 2328//2328 2344//2344 2316//2316 +f 2316//2316 2344//2344 2340//2340 +f 2127//2127 860//860 1399//1399 +f 1798//1798 577//577 2347//2347 +f 1458//1458 1393//1393 1847//1847 +f 1458//1458 1391//1391 1393//1393 +f 1814//1814 1829//1829 1752//1752 +f 236//236 403//403 631//631 +f 2341//2341 404//404 403//403 +f 2026//2026 2127//2127 2324//2324 +f 2345//2345 1872//1872 2331//2331 +f 2346//2346 2332//2332 2338//2338 +f 2045//2045 2069//2069 2046//2046 +f 173//173 2215//2215 2213//2213 +f 1103//1103 1767//1767 1104//1104 +f 452//452 75//75 453//453 +f 1481//1481 1483//1483 1587//1587 +f 1964//1964 1963//1963 2341//2341 +f 1523//1523 1938//1938 858//858 +f 2026//2026 2022//2022 2127//2127 +f 1399//1399 2324//2324 2127//2127 +f 1399//1399 2345//2345 2324//2324 +f 2346//2346 2348//2348 2334//2334 +f 2349//2349 2344//2344 2334//2334 +f 2348//2348 2349//2349 2334//2334 +f 2349//2349 2350//2350 2344//2344 +f 2350//2350 2340//2340 2344//2344 +f 2340//2340 2350//2350 2244//2244 +f 1724//1724 1729//1729 1725//1725 +f 2192//2192 2196//2196 2193//2193 +f 2343//2343 1481//1481 1587//1587 +f 1587//1587 278//278 2343//2343 +f 1678//1678 1070//1070 1032//1032 +f 2021//2021 2022//2022 2026//2026 +f 1872//1872 2346//2346 2338//2338 +f 554//554 509//509 16//16 +f 2271//2271 2147//2147 2093//2093 +f 1769//1769 1054//1054 1056//1056 +f 152//152 1869//1869 1609//1609 +f 224//224 2133//2133 2150//2150 +f 1399//1399 1185//1185 2345//2345 +f 1184//1184 1872//1872 2345//2345 +f 1871//1871 2346//2346 1872//1872 +f 1871//1871 1906//1906 2346//2346 +f 1838//1838 2346//2346 1906//1906 +f 1838//1838 2348//2348 2346//2346 +f 479//479 480//480 2138//2138 +f 1769//1769 1976//1976 1054//1054 +f 1651//1651 1650//1650 2110//2110 +f 1621//1621 403//403 236//236 +f 1621//1621 2341//2341 403//403 +f 2351//2351 1491//1491 1766//1766 +f 2352//2352 1687//1687 1733//1733 +f 1185//1185 1184//1184 2345//2345 +f 86//86 85//85 1788//1788 +f 1234//1234 1359//1359 1978//1978 +f 1838//1838 1837//1837 2348//2348 +f 1837//1837 2349//2349 2348//2348 +f 2350//2350 1633//1633 2244//2244 +f 1633//1633 1486//1486 2244//2244 +f 1321//1321 1977//1977 1958//1958 +f 90//90 2138//2138 2145//2145 +f 90//90 92//92 2138//2138 +f 1238//1238 588//588 818//818 +f 1998//1998 2038//2038 2014//2014 +f 1302//1302 2040//2040 1518//1518 +f 237//237 631//631 1006//1006 +f 237//237 236//236 631//631 +f 235//235 1621//1621 236//236 +f 1270//1270 2341//2341 1621//1621 +f 1270//1270 1269//1269 1964//1964 +f 2341//2341 1270//1270 1964//1964 +f 2011//2011 1215//1215 2010//2010 +f 2224//2224 1806//1806 1807//1807 +f 1846//1846 2349//2349 1837//1837 +f 324//324 802//802 2216//2216 +f 92//92 479//479 2138//2138 +f 1498//1498 2209//2209 840//840 +f 1840//1840 1533//1533 1809//1809 +f 2174//2174 2119//2119 2223//2223 +f 1406//1406 1832//1832 1823//1823 +f 801//801 2125//2125 2126//2126 +f 1846//1846 2350//2350 2349//2349 +f 2350//2350 1846//1846 1633//1633 +f 1633//1633 1632//1632 1486//1486 +f 1999//1999 2010//2010 1727//1727 +f 64//64 1976//1976 1769//1769 +f 2353//2353 2354//2354 2355//2355 +f 2354//2354 2356//2356 2355//2355 +f 2357//2357 2358//2358 2356//2356 +f 2354//2354 2357//2357 2356//2356 +f 2165//2165 1136//1136 2359//2359 +f 2360//2360 2361//2361 2336//2336 +f 2362//2362 990//990 2363//2363 +f 2364//2364 2365//2365 2366//2366 +f 268//268 2367//2367 269//269 +f 2368//2368 2369//2369 2370//2370 +f 2361//2361 2371//2371 2372//2372 +f 2367//2367 2373//2373 507//507 +f 2250//2250 2372//2372 2368//2368 +f 2374//2374 2000//2000 1369//1369 +f 2375//2375 1301//1301 1300//1300 +f 2322//2322 2376//2376 1519//1519 +f 2364//2364 2377//2377 2365//2365 +f 2378//2378 2355//2355 2356//2356 +f 1495//1495 2379//2379 2380//2380 +f 2365//2365 2377//2377 2366//2366 +f 744//744 1880//1880 477//477 +f 2377//2377 2381//2381 2366//2366 +f 2353//2353 2355//2355 2382//2382 +f 1802//1802 287//287 2162//2162 +f 477//477 28//28 743//743 +f 1684//1684 1792//1792 2383//2383 +f 365//365 1446//1446 464//464 +f 1380//1380 1241//1241 1444//1444 +f 1019//1019 2333//2333 2373//2373 +f 569//569 1893//1893 27//27 +f 2362//2362 2363//2363 2374//2374 +f 1160//1160 446//446 1893//1893 +f 569//569 1160//1160 1893//1893 +f 1534//1534 1533//1533 2384//2384 +f 2385//2385 1218//1218 1219//1219 +f 2385//2385 1898//1898 1218//1218 +f 1898//1898 2377//2377 2364//2364 +f 1551//1551 1008//1008 1020//1020 +f 1767//1767 344//344 1104//1104 +f 1495//1495 949//949 2379//2379 +f 2381//2381 2354//2354 2353//2353 +f 424//424 1218//1218 425//425 +f 2386//2386 2387//2387 1517//1517 +f 2378//2378 2356//2356 2388//2388 +f 2105//2105 2335//2335 2337//2337 +f 2360//2360 2371//2371 2361//2361 +f 2355//2355 2389//2389 2382//2382 +f 949//949 1299//1299 950//950 +f 2355//2355 2378//2378 2389//2389 +f 2380//2380 2379//2379 2358//2358 +f 2368//2368 2370//2370 2251//2251 +f 1987//1987 2390//2390 2391//2391 +f 390//390 2392//2392 1682//1682 +f 1218//1218 1900//1900 2103//2103 +f 2359//2359 1136//1136 1230//1230 +f 989//989 535//535 536//536 +f 137//137 1330//1330 160//160 +f 324//324 1126//1126 325//325 +f 1282//1282 843//843 845//845 +f 418//418 256//256 255//255 +f 1330//1330 2247//2247 1197//1197 +f 2393//2393 2357//2357 2354//2354 +f 2393//2393 1463//1463 2357//2357 +f 2357//2357 1463//1463 2165//2165 +f 2394//2394 2165//2165 2359//2359 +f 2357//2357 2165//2165 2394//2394 +f 2370//2370 1950//1950 2251//2251 +f 949//949 948//948 2379//2379 +f 2366//2366 2381//2381 2353//2353 +f 2335//2335 2395//2395 2336//2336 +f 2396//2396 77//77 1197//1197 +f 2397//2397 2385//2385 1219//1219 +f 2385//2385 2398//2398 1898//1898 +f 2398//2398 2377//2377 1898//1898 +f 2389//2389 2378//2378 2399//2399 +f 2398//2398 2400//2400 2377//2377 +f 2400//2400 2381//2381 2377//2377 +f 2104//2104 1900//1900 1899//1899 +f 1330//1330 1197//1197 160//160 +f 2247//2247 2396//2396 1197//1197 +f 77//77 2396//2396 2401//2401 +f 1465//1465 2354//2354 2381//2381 +f 1465//1465 2393//2393 2354//2354 +f 1218//1218 2103//2103 712//712 +f 1240//1240 1237//1237 2333//2333 +f 2123//2123 2169//2169 2402//2402 +f 2006//2006 2137//2137 2251//2251 +f 1019//1019 1240//1240 2333//2333 +f 949//949 1495//1495 1306//1306 +f 2107//2107 1300//1300 2386//2386 +f 2247//2247 1350//1350 2396//2396 +f 1666//1666 1346//1346 2403//2403 +f 2005//2005 2336//2336 2137//2137 +f 2004//2004 1903//1903 2005//2005 +f 2404//2404 1903//1903 2004//2004 +f 1533//1533 1901//1901 2384//2384 +f 2061//2061 284//284 2047//2047 +f 1350//1350 1987//1987 2396//2396 +f 2396//2396 1987//1987 2391//2391 +f 2391//2391 2405//2405 2396//2396 +f 2396//2396 2405//2405 2401//2401 +f 2359//2359 2380//2380 2394//2394 +f 1901//1901 2404//2404 2384//2384 +f 2107//2107 2386//2386 2106//2106 +f 2406//2406 1902//1902 2407//2407 +f 2405//2405 2408//2408 2401//2401 +f 2401//2401 2408//2408 2403//2403 +f 1464//1464 2381//2381 2400//2400 +f 1464//1464 1465//1465 2381//2381 +f 1140//1140 1139//1139 1147//1147 +f 2106//2106 2386//2386 2409//2409 +f 2106//2106 2409//2409 1534//1534 +f 2251//2251 2375//2375 2107//2107 +f 1384//1384 2407//2407 1471//1471 +f 2407//2407 1840//1840 1471//1471 +f 2408//2408 2410//2410 2403//2403 +f 2403//2403 2410//2410 1666//1666 +f 1900//1900 2104//2104 2103//2103 +f 35//35 1257//1257 33//33 +f 2409//2409 1517//1517 2411//2411 +f 1798//1798 2412//2412 1813//1813 +f 2410//2410 2413//2413 1666//1666 +f 2103//2103 2337//2337 1902//1902 +f 2373//2373 2333//2333 1368//1368 +f 2333//2333 1366//1366 1368//1368 +f 2409//2409 2386//2386 1517//1517 +f 2376//2376 1532//1532 2411//2411 +f 988//988 1239//1239 989//989 +f 2405//2405 2414//2414 2408//2408 +f 2408//2408 2414//2414 2410//2410 +f 2415//2415 333//333 332//332 +f 2386//2386 1300//1300 2387//2387 +f 1950//1950 1353//1353 2375//2375 +f 1845//1845 2413//2413 2410//2410 +f 1758//1758 1765//1765 1845//1845 +f 2337//2337 2103//2103 2105//2105 +f 1570//1570 816//816 1265//1265 +f 1520//1520 2000//2000 1227//1227 +f 2391//2391 2390//2390 2405//2405 +f 576//576 323//323 325//325 +f 2373//2373 1368//1368 2416//2416 +f 1305//1305 1219//1219 1172//1172 +f 760//760 1577//1577 694//694 +f 728//728 760//760 694//694 +f 113//113 1548//1548 25//25 +f 1758//1758 1766//1766 1747//1747 +f 1548//1548 80//80 25//25 +f 1809//1809 893//893 2417//2417 +f 2363//2363 536//536 1225//1225 +f 1301//1301 1353//1353 1707//1707 +f 2390//2390 2418//2418 2405//2405 +f 2418//2418 2414//2414 2405//2405 +f 2414//2414 2419//2419 2410//2410 +f 2420//2420 1845//1845 2410//2410 +f 2420//2420 1758//1758 1845//1845 +f 2399//2399 2421//2421 1948//1948 +f 1305//1305 2397//2397 1219//1219 +f 2421//2421 1949//1949 1948//1948 +f 1746//1746 1780//1780 1790//1790 +f 1440//1440 1413//1413 184//184 +f 1445//1445 365//365 367//367 +f 893//893 2376//2376 2322//2322 +f 332//332 334//334 1353//1353 +f 2410//2410 2419//2419 2420//2420 +f 2373//2373 2416//2416 507//507 +f 984//984 356//356 267//267 +f 1014//1014 263//263 230//230 +f 1480//1480 1014//1014 230//230 +f 2411//2411 1517//1517 1519//1519 +f 2376//2376 2411//2411 1519//1519 +f 2422//2422 2370//2370 2369//2369 +f 1301//1301 1707//1707 1302//1302 +f 2417//2417 893//893 892//892 +f 1822//1822 2390//2390 1942//1942 +f 1480//1480 1015//1015 1014//1014 +f 795//795 1666//1666 2413//2413 +f 2403//2403 1346//1346 2401//2401 +f 893//893 1809//1809 2376//2376 +f 2417//2417 892//892 1469//1469 +f 2423//2423 2414//2414 2418//2418 +f 2423//2423 2419//2419 2414//2414 +f 2420//2420 1766//1766 1758//1758 +f 1346//1346 77//77 2401//2401 +f 2424//2424 2400//2400 2398//2398 +f 2424//2424 1499//1499 2400//2400 +f 2395//2395 2360//2360 2336//2336 +f 1463//1463 1076//1076 1136//1136 +f 1684//1684 1349//1349 1348//1348 +f 1546//1546 1829//1829 1547//1547 +f 2419//2419 2351//2351 2420//2420 +f 2420//2420 2351//2351 1766//1766 +f 245//245 648//648 246//246 +f 334//334 2425//2425 1354//1354 +f 2375//2375 1300//1300 2107//2107 +f 1499//1499 1464//1464 2400//2400 +f 295//295 947//947 649//649 +f 1009//1009 1271//1271 114//114 +f 283//283 282//282 1009//1009 +f 1271//1271 2426//2426 1489//1489 +f 1548//1548 1829//1829 1546//1546 +f 1353//1353 1354//1354 1707//1707 +f 989//989 536//536 2363//2363 +f 2162//2162 2418//2418 2390//2390 +f 2162//2162 2423//2423 2418//2418 +f 2061//2061 2427//2427 284//284 +f 2425//2425 2327//2327 1354//1354 +f 1109//1109 1645//1645 1281//1281 +f 282//282 2426//2426 1009//1009 +f 113//113 1489//1489 1548//1548 +f 1950//1950 332//332 1353//1353 +f 2162//2162 2390//2390 1822//1822 +f 990//990 989//989 2363//2363 +f 1436//1436 2393//2393 1465//1465 +f 1436//1436 1463//1463 2393//2393 +f 1489//1489 2428//2428 1548//1548 +f 2428//2428 1829//1829 1548//1548 +f 1226//1226 1225//1225 169//169 +f 1291//1291 2423//2423 2162//2162 +f 2419//2419 1843//1843 2351//2351 +f 1843//1843 1491//1491 2351//2351 +f 2379//2379 2362//2362 2358//2358 +f 2372//2372 2371//2371 2369//2369 +f 1436//1436 1464//1464 1437//1437 +f 284//284 2429//2429 282//282 +f 2430//2430 2431//2431 282//282 +f 282//282 2431//2431 2426//2426 +f 1235//1235 495//495 1562//1562 +f 1732//1732 1608//1608 1607//1607 +f 1802//1802 2162//2162 1822//1822 +f 2432//2432 2419//2419 2423//2423 +f 2419//2419 2432//2432 1843//1843 +f 2362//2362 2374//2374 2358//2358 +f 2421//2421 2378//2378 2388//2388 +f 2336//2336 2361//2361 2137//2137 +f 2427//2427 2429//2429 284//284 +f 2429//2429 2430//2430 282//282 +f 2367//2367 507//507 269//269 +f 1133//1133 2407//2407 1444//1444 +f 1869//1869 1662//1662 436//436 +f 2432//2432 2423//2423 1291//1291 +f 2250//2250 2368//2368 2251//2251 +f 2433//2433 2389//2389 2399//2399 +f 2431//2431 2434//2434 2426//2426 +f 2337//2337 2336//2336 1903//1903 +f 229//229 200//200 1843//1843 +f 1801//1801 428//428 2427//2427 +f 2426//2426 2435//2435 1489//1489 +f 2435//2435 2436//2436 1489//1489 +f 1489//1489 2436//2436 2428//2428 +f 1512//1512 2168//2168 2118//2118 +f 1020//1020 2373//2373 2367//2367 +f 268//268 1020//1020 2367//2367 +f 2347//2347 577//577 579//579 +f 2437//2437 2432//2432 1291//1291 +f 2432//2432 229//229 1843//1843 +f 1803//1803 1796//1796 1798//1798 +f 74//74 579//579 1754//1754 +f 428//428 2438//2438 2427//2427 +f 2438//2438 2439//2439 2427//2427 +f 2427//2427 2439//2439 2429//2429 +f 2429//2429 2431//2431 2430//2430 +f 2431//2431 2440//2440 2434//2434 +f 2436//2436 2441//2441 2428//2428 +f 2441//2441 1829//1829 2428//2428 +f 2441//2441 1752//1752 1829//1829 +f 1682//1682 2442//2442 2068//2068 +f 107//107 1460//1460 1263//1263 +f 2330//2330 2443//2443 74//74 +f 76//76 2330//2330 74//74 +f 2429//2429 2439//2439 2431//2431 +f 2439//2439 2444//2444 2431//2431 +f 2431//2431 2444//2444 2440//2440 +f 1840//1840 1809//1809 1841//1841 +f 2384//2384 2404//2404 2106//2106 +f 1005//1005 2437//2437 1291//1291 +f 2437//2437 1480//1480 2432//2432 +f 2432//2432 1480//1480 229//229 +f 1374//1374 1317//1317 1316//1316 +f 74//74 2443//2443 579//579 +f 1367//1367 1499//1499 2424//2424 +f 2440//2440 2435//2435 2426//2426 +f 2434//2434 2440//2440 2426//2426 +f 1471//1471 2417//2417 1469//1469 +f 2106//2106 2404//2404 2004//2004 +f 1798//1798 1783//1783 577//577 +f 1034//1034 2437//2437 1005//1005 +f 1480//1480 230//230 229//229 +f 2389//2389 2371//2371 2360//2360 +f 2203//2203 2443//2443 2330//2330 +f 2438//2438 2445//2445 2439//2439 +f 2446//2446 2444//2444 2439//2439 +f 2444//2444 2447//2447 2440//2440 +f 2435//2435 2448//2448 2436//2436 +f 2436//2436 2448//2448 2441//2441 +f 2363//2363 1225//1225 2000//2000 +f 2387//2387 1300//1300 1302//1302 +f 1302//1302 1707//1707 2040//2040 +f 1034//1034 1480//1480 2437//2437 +f 2433//2433 2369//2369 2371//2371 +f 2433//2433 2422//2422 2369//2369 +f 2203//2203 2449//2449 2443//2443 +f 1177//1177 1178//1178 1459//1459 +f 1235//1235 1161//1161 568//568 +f 2445//2445 2446//2446 2439//2439 +f 2447//2447 2450//2450 2440//2440 +f 2448//2448 2451//2451 2441//2441 +f 2452//2452 1752//1752 2441//2441 +f 2451//2451 2452//2452 2441//2441 +f 1752//1752 2452//2452 1445//1445 +f 1790//1790 1684//1684 1625//1625 +f 578//578 577//577 1783//1783 +f 1033//1033 1034//1034 1005//1005 +f 1230//1230 1206//1206 2359//2359 +f 1225//1225 536//536 169//169 +f 2389//2389 2433//2433 2371//2371 +f 1020//1020 1019//1019 2373//2373 +f 2453//2453 579//579 2443//2443 +f 2449//2449 2453//2453 2443//2443 +f 2453//2453 2347//2347 579//579 +f 1436//1436 1077//1077 1463//1463 +f 2435//2435 2454//2454 2448//2448 +f 2382//2382 2389//2389 2455//2455 +f 278//278 1813//1813 2342//2342 +f 427//427 2438//2438 428//428 +f 2446//2446 2447//2447 2444//2444 +f 2440//2440 2450//2450 2454//2454 +f 2440//2440 2454//2454 2435//2435 +f 1149//1149 1367//1367 583//583 +f 1354//1354 2327//2327 2321//2321 +f 2107//2107 2004//2004 2006//2006 +f 2068//2068 2442//2442 2438//2438 +f 427//427 2068//2068 2438//2438 +f 2438//2438 2442//2442 2445//2445 +f 2452//2452 1446//1446 1445//1445 +f 1905//1905 2017//2017 1857//1857 +f 1662//1662 1661//1661 1615//1615 +f 2416//2416 2398//2398 2385//2385 +f 2416//2416 2424//2424 2398//2398 +f 1972//1972 2456//2456 1409//1409 +f 2457//2457 2203//2203 1409//1409 +f 2456//2456 2457//2457 1409//1409 +f 2457//2457 2449//2449 2203//2203 +f 2412//2412 2347//2347 2453//2453 +f 2347//2347 2412//2412 1798//1798 +f 40//40 41//41 2091//2091 +f 2445//2445 2442//2442 1682//1682 +f 2446//2446 2458//2458 2447//2447 +f 2459//2459 2452//2452 2451//2451 +f 2459//2459 1446//1446 2452//2452 +f 1349//1349 1094//1094 1347//1347 +f 2460//2460 2453//2453 2449//2449 +f 1682//1682 2392//2392 2445//2445 +f 2461//2461 2458//2458 2446//2446 +f 2458//2458 2462//2462 2447//2447 +f 2447//2447 2462//2462 2450//2450 +f 2448//2448 2459//2459 2451//2451 +f 1534//1534 2384//2384 2106//2106 +f 2399//2399 2378//2378 2421//2421 +f 2357//2357 2394//2394 2358//2358 +f 1899//1899 1898//1898 2364//2364 +f 2460//2460 2412//2412 2453//2453 +f 2399//2399 2422//2422 2433//2433 +f 1987//1987 1942//1942 2390//2390 +f 1594//1594 1628//1628 2019//2019 +f 2445//2445 2461//2461 2446//2446 +f 2463//2463 2450//2450 2462//2462 +f 2450//2450 2463//2463 2454//2454 +f 2464//2464 2459//2459 2448//2448 +f 2361//2361 2372//2372 2250//2250 +f 2137//2137 2361//2361 2250//2250 +f 1541//1541 1020//1020 268//268 +f 2463//2463 2464//2464 2454//2454 +f 2454//2454 2464//2464 2448//2448 +f 1366//1366 1237//1237 582//582 +f 53//53 2456//2456 1972//1972 +f 2392//2392 2461//2461 2445//2445 +f 2091//2091 283//283 40//40 +f 2455//2455 2389//2389 2360//2360 +f 1305//1305 508//508 2397//2397 +f 508//508 2385//2385 2397//2397 +f 591//591 590//590 1704//1704 +f 2465//2465 2457//2457 2456//2456 +f 2466//2466 2449//2449 2457//2457 +f 2466//2466 2460//2460 2449//2449 +f 508//508 2416//2416 2385//2385 +f 1366//1366 582//582 1367//1367 +f 76//76 451//451 2330//2330 +f 1687//1687 2462//2462 2458//2458 +f 1687//1687 2463//2463 2462//2462 +f 1306//1306 1299//1299 949//949 +f 2387//2387 1302//1302 1517//1517 +f 249//249 560//560 547//547 +f 1687//1687 2352//2352 2463//2463 +f 2352//2352 2464//2464 2463//2463 +f 2467//2467 2468//2468 2459//2459 +f 2459//2459 2468//2468 1446//1446 +f 1149//1149 1499//1499 1367//1367 +f 2465//2465 2456//2456 53//53 +f 830//830 1615//1615 1661//1661 +f 2464//2464 2467//2467 2459//2459 +f 333//333 2425//2425 334//334 +f 1227//1227 2000//2000 1225//1225 +f 1966//1966 1947//1947 1469//1469 +f 52//52 2469//2469 53//53 +f 2469//2469 2465//2465 53//53 +f 2412//2412 2460//2460 1813//1813 +f 2460//2460 2342//2342 1813//1813 +f 1481//1481 2343//2343 1780//1780 +f 401//401 400//400 414//414 +f 162//162 164//164 151//151 +f 1948//1948 1950//1950 2370//2370 +f 1523//1523 2470//2470 1937//1937 +f 2470//2470 2469//2469 1937//1937 +f 1937//1937 2469//2469 52//52 +f 2342//2342 1792//1792 1780//1780 +f 1780//1780 1792//1792 1790//1790 +f 2467//2467 2464//2464 2352//2352 +f 2468//2468 464//464 1446//1446 +f 1902//1902 2337//2337 1903//1903 +f 2107//2107 2006//2006 2251//2251 +f 1524//1524 2471//2471 1523//1523 +f 2471//2471 2470//2470 1523//1523 +f 2471//2471 2472//2472 2470//2470 +f 2472//2472 2469//2469 2470//2470 +f 2473//2473 2457//2457 2465//2465 +f 2473//2473 2466//2466 2457//2457 +f 2460//2460 2474//2474 2342//2342 +f 743//743 27//27 1893//1893 +f 1534//1534 2409//2409 2411//2411 +f 2469//2469 2475//2475 2465//2465 +f 2475//2475 2476//2476 2465//2465 +f 2473//2473 2477//2477 2466//2466 +f 2466//2466 2478//2478 2460//2460 +f 2478//2478 2474//2474 2460//2460 +f 2474//2474 1792//1792 2342//2342 +f 1733//1733 1737//1737 2352//2352 +f 1737//1737 2467//2467 2352//2352 +f 496//496 464//464 2468//2468 +f 2472//2472 2475//2475 2469//2469 +f 2467//2467 2479//2479 2468//2468 +f 2479//2479 496//496 2468//2468 +f 1218//1218 1898//1898 1900//1900 +f 1528//1528 1553//1553 1524//1524 +f 1553//1553 2471//2471 1524//1524 +f 2471//2471 2480//2480 2472//2472 +f 2465//2465 2481//2481 2473//2473 +f 2474//2474 2383//2383 1792//1792 +f 1008//1008 1063//1063 1019//1019 +f 1532//1532 1534//1534 2411//2411 +f 1554//1554 1553//1553 1528//1528 +f 2482//2482 2465//2465 2476//2476 +f 2482//2482 2481//2481 2465//2465 +f 2483//2483 2473//2473 2481//2481 +f 2477//2477 2223//2223 2466//2466 +f 2223//2223 2478//2478 2466//2466 +f 2478//2478 2484//2484 2474//2474 +f 2383//2383 1349//1349 1684//1684 +f 2483//2483 2481//2481 2482//2482 +f 2485//2485 2383//2383 2474//2474 +f 2426//2426 1271//1271 1009//1009 +f 1607//1607 2467//2467 1737//1737 +f 1809//1809 1532//1532 2376//2376 +f 2486//2486 2480//2480 2471//2471 +f 2475//2475 2472//2472 2480//2480 +f 2487//2487 2475//2475 2480//2480 +f 2485//2485 1349//1349 2383//2383 +f 507//507 2416//2416 508//508 +f 1607//1607 2479//2479 2467//2467 +f 1841//1841 1809//1809 2417//2417 +f 2251//2251 1950//1950 2375//2375 +f 2379//2379 948//948 2362//2362 +f 2488//2488 2480//2480 2486//2486 +f 2488//2488 2489//2489 2480//2480 +f 2489//2489 2487//2487 2480//2480 +f 2484//2484 2485//2485 2474//2474 +f 2485//2485 1352//1352 1349//1349 +f 859//859 1940//1940 860//860 +f 40//40 1009//1009 114//114 +f 2479//2479 2490//2490 496//496 +f 496//496 1128//1128 465//465 +f 2380//2380 2359//2359 1495//1495 +f 1368//1368 1367//1367 2424//2424 +f 2486//2486 2471//2471 1553//1553 +f 1141//1141 2485//2485 2484//2484 +f 436//436 1662//1662 1855//1855 +f 2427//2427 2061//2061 1801//1801 +f 1607//1607 2490//2490 2479//2479 +f 2490//2490 1128//1128 496//496 +f 465//465 593//593 550//550 +f 2491//2491 2488//2488 2486//2486 +f 2491//2491 2492//2492 2488//2488 +f 2492//2492 2493//2493 2488//2488 +f 2493//2493 2489//2489 2488//2488 +f 2124//2124 2476//2476 2475//2475 +f 2413//2413 1845//1845 795//795 +f 2359//2359 1206//1206 1495//1495 +f 1607//1607 456//456 2490//2490 +f 456//456 1128//1128 2490//2490 +f 1841//1841 2417//2417 1471//1471 +f 1901//1901 1533//1533 1840//1840 +f 894//894 2486//2486 1553//1553 +f 1140//1140 1352//1352 2485//2485 +f 2407//2407 1902//1902 1840//1840 +f 2394//2394 2380//2380 2358//2358 +f 1133//1133 712//712 2407//2407 +f 2343//2343 2342//2342 1780//1780 +f 2494//2494 2486//2486 894//894 +f 2494//2494 2491//2491 2486//2486 +f 2124//2124 2482//2482 2476//2476 +f 2482//2482 2495//2495 2483//2483 +f 2496//2496 2478//2478 2223//2223 +f 2496//2496 2497//2497 2478//2478 +f 2497//2497 2484//2484 2478//2478 +f 1140//1140 2485//2485 1141//1141 +f 1768//1768 1352//1352 1140//1140 +f 1352//1352 1768//1768 1094//1094 +f 712//712 2406//2406 2407//2407 +f 1707//1707 1354//1354 1708//1708 +f 456//456 592//592 1128//1128 +f 948//948 950//950 2362//2362 +f 950//950 990//990 2362//2362 +f 1552//1552 894//894 1553//1553 +f 2498//2498 2491//2491 2494//2494 +f 2499//2499 2493//2493 2492//2492 +f 2499//2499 2500//2500 2493//2493 +f 2124//2124 2475//2475 2487//2487 +f 2497//2497 1141//1141 2484//2484 +f 269//269 508//508 1305//1305 +f 2388//2388 1949//1949 2421//2421 +f 1950//1950 2115//2115 332//332 +f 2227//2227 1394//1394 1530//1530 +f 2501//2501 2492//2492 2491//2491 +f 2501//2501 2499//2499 2492//2492 +f 1709//1709 2500//2500 2499//2499 +f 2502//2502 2482//2482 2124//2124 +f 2502//2502 2495//2495 2482//2482 +f 429//429 365//365 464//464 +f 2416//2416 1368//1368 2424//2424 +f 712//712 2103//2103 2406//2406 +f 2491//2491 2498//2498 2501//2501 +f 1903//1903 2336//2336 2005//2005 +f 2399//2399 1948//1948 2422//2422 +f 2372//2372 2369//2369 2368//2368 +f 1902//1902 1901//1901 1840//1840 +f 1901//1901 1903//1903 2404//2404 +f 2033//2033 2499//2499 2501//2501 +f 1983//1983 2497//2497 2496//2496 +f 2406//2406 2103//2103 1902//1902 +f 2498//2498 2306//2306 2501//2501 +f 2033//2033 1709//1709 2499//2499 +f 1983//1983 1141//1141 2497//2497 +f 2422//2422 1948//1948 2370//2370 +f 2115//2115 2415//2415 332//332 +f 990//990 950//950 988//988 +f 1518//1518 2501//2501 2306//2306 +f 1518//1518 2033//2033 2501//2501 +f 2124//2124 2123//2123 2502//2502 +f 2502//2502 2123//2123 2495//2495 +f 1370//1370 1983//1983 2496//2496 +f 1262//1262 894//894 1552//1552 +f 2498//2498 2322//2322 2306//2306 +f 1139//1139 1141//1141 1983//1983 +f 1094//1094 1768//1768 1095//1095 +f 2363//2363 2000//2000 2374//2374 +f 1444//1444 2407//2407 1384//1384 +f 2375//2375 1353//1353 1301//1301 +f 893//893 2494//2494 894//894 +f 893//893 2322//2322 2498//2498 +f 2494//2494 893//893 2498//2498 +f 2123//2123 2402//2402 2495//2495 +f 1370//1370 2496//2496 2223//2223 +f 1687//1687 2458//2458 2503//2503 +f 2458//2458 2461//2461 2503//2503 +f 2461//2461 2392//2392 2503//2503 +f 2392//2392 390//390 2503//2503 +f 390//390 389//389 2503//2503 +f 389//389 1416//1416 2503//2503 +f 1416//1416 1687//1687 2503//2503 diff --git a/A4/resources/cube.obj b/A4/resources/cube.obj new file mode 100644 index 0000000..e81edd5 --- /dev/null +++ b/A4/resources/cube.obj @@ -0,0 +1,29 @@ +# Blender v2.71 (sub 0) OBJ File: '' +# www.blender.org +v 0.500000 0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 1.000000 +vn 1.000000 -0.000000 -0.000000 +vn -0.000000 -1.000000 -0.000000 +vn -1.000000 0.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +s off +f 2//1 3//1 4//1 +f 8//2 7//2 6//2 +f 1//3 5//3 6//3 +f 2//4 6//4 7//4 +f 7//5 8//5 4//5 +f 1//6 4//6 8//6 +f 1//1 2//1 4//1 +f 5//2 8//2 6//2 +f 2//3 1//3 6//3 +f 3//4 2//4 7//4 +f 3//5 7//5 4//5 +f 5//6 1//6 8//6 diff --git a/A4/resources/frag.glsl b/A4/resources/frag.glsl new file mode 100644 index 0000000..ff05fa8 --- /dev/null +++ b/A4/resources/frag.glsl @@ -0,0 +1,37 @@ +#version 120 + +uniform mat4 MVL; +uniform vec3 lightPos1; +uniform vec3 lightPos2; +uniform vec3 ka; +uniform vec3 kd; +uniform vec3 ks; +uniform float s; +uniform float i1; +uniform float i2; + +varying vec3 color; // passed from the vertex shader +varying vec4 p; +varying vec4 n; + +void main() +{ + vec4 normal = normalize(n); + vec3 norm = vec3(normal.x, normal.y, normal.z); + + vec4 npos = normalize(p); + vec3 pos = vec3(npos.x, npos.y, npos.z); + + vec3 lightnorm = vec3(MVL[3].x, MVL[3].y, MVL[3].z); + + vec3 light = lightnorm - vec3(p.x, p.y, p.z); + vec3 lnorm = normalize(vec3(light.x,light.y,light.z)); + float temp = dot(lnorm, norm); + vec3 cd = kd*max(0, temp); + + vec3 h = normalize(lnorm - pos); + vec3 cs = ks*pow(max(0, dot(h, norm)), s); + + vec4 c = vec4(ka.r + cd.r + cs.r, ka.g + cd.g + cs.g, ka.b + cd.b + cs.b, 1.0); + gl_FragColor = c; +} diff --git a/A4/resources/sil.glsl b/A4/resources/sil.glsl new file mode 100644 index 0000000..ba512f1 --- /dev/null +++ b/A4/resources/sil.glsl @@ -0,0 +1,20 @@ +#version 120 + +varying vec4 p; +varying vec4 n; + +void main() +{ + vec4 normal = normalize(n); + vec3 norm = vec3(normal.x, normal.y, normal.z); + + vec4 npos = normalize(p); + vec3 pos = vec3(npos.x, npos.y, npos.z); + + float product = dot(norm, pos); + + if(product <= 0.3 && product >= -0.3) + gl_FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f); + else + gl_FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); +} diff --git a/A4/resources/sphere.obj b/A4/resources/sphere.obj new file mode 100644 index 0000000..698f5ce --- /dev/null +++ b/A4/resources/sphere.obj @@ -0,0 +1,204 @@ +#### +# +# OBJ File Generated by LightWave3D +# LightWave3D OBJ Export v2.2 +# +#### +# +# Vertices: 62 +# Points: 0 +# Lines: 0 +# Faces: 120 +# Materials: 1 +# +#### + +# Vertex list + +v 0 -0.5 -0 +v 0.25 -0.433013 -0 +v 0.216506 -0.433013 -0.125 +v 0.125 -0.433013 -0.216506 +v 0 -0.433013 -0.25 +v -0.125 -0.433013 -0.216506 +v -0.216506 -0.433013 -0.125 +v -0.25 -0.433013 -0 +v -0.216506 -0.433013 0.125 +v -0.125 -0.433013 0.216506 +v 0 -0.433013 0.25 +v 0.125 -0.433013 0.216506 +v 0.216506 -0.433013 0.125 +v 0.433013 -0.25 -0 +v 0.375 -0.25 -0.216506 +v 0.216506 -0.25 -0.375 +v 0 -0.25 -0.433013 +v -0.216506 -0.25 -0.375 +v -0.375 -0.25 -0.216506 +v -0.433013 -0.25 -0 +v -0.375 -0.25 0.216506 +v -0.216506 -0.25 0.375 +v 0 -0.25 0.433013 +v 0.216506 -0.25 0.375 +v 0.375 -0.25 0.216506 +v 0.5 2.55171e-12 -0 +v 0.433013 2.55171e-12 -0.25 +v 0.25 2.55171e-12 -0.433013 +v 0 2.55171e-12 -0.5 +v -0.25 2.55171e-12 -0.433013 +v -0.433013 2.55171e-12 -0.25 +v -0.5 2.55171e-12 -0 +v -0.433013 2.55171e-12 0.25 +v -0.25 2.55171e-12 0.433013 +v 0 2.55171e-12 0.5 +v 0.25 2.55171e-12 0.433013 +v 0.433013 2.55171e-12 0.25 +v 0.433013 0.25 -0 +v 0.375 0.25 -0.216506 +v 0.216506 0.25 -0.375 +v 0 0.25 -0.433013 +v -0.216506 0.25 -0.375 +v -0.375 0.25 -0.216506 +v -0.433013 0.25 -0 +v -0.375 0.25 0.216506 +v -0.216506 0.25 0.375 +v 0 0.25 0.433013 +v 0.216506 0.25 0.375 +v 0.375 0.25 0.216506 +v 0.25 0.433013 -0 +v 0.216506 0.433013 -0.125 +v 0.125 0.433013 -0.216506 +v 0 0.433013 -0.25 +v -0.125 0.433013 -0.216506 +v -0.216506 0.433013 -0.125 +v -0.25 0.433013 -0 +v -0.216506 0.433013 0.125 +v -0.125 0.433013 0.216506 +v 0 0.433013 0.25 +v 0.125 0.433013 0.216506 +v 0.216506 0.433013 0.125 +v 5.10341e-12 0.5 -0 + +# Face list + +f 3 2 1 +f 4 3 1 +f 5 4 1 +f 6 5 1 +f 7 6 1 +f 8 7 1 +f 9 8 1 +f 10 9 1 +f 11 10 1 +f 12 11 1 +f 13 12 1 +f 2 13 1 +f 3 14 2 +f 15 14 3 +f 4 15 3 +f 16 15 4 +f 17 16 4 +f 5 17 4 +f 17 5 6 +f 18 17 6 +f 18 6 7 +f 19 18 7 +f 20 7 8 +f 20 19 7 +f 20 8 9 +f 21 20 9 +f 21 9 10 +f 22 21 10 +f 23 10 11 +f 23 22 10 +f 12 23 11 +f 24 23 12 +f 13 24 12 +f 25 24 13 +f 14 25 13 +f 2 14 13 +f 15 26 14 +f 27 26 15 +f 28 27 15 +f 16 28 15 +f 29 28 16 +f 17 29 16 +f 29 17 18 +f 30 29 18 +f 31 18 19 +f 31 30 18 +f 32 19 20 +f 32 31 19 +f 32 20 21 +f 33 32 21 +f 34 21 22 +f 34 33 21 +f 35 22 23 +f 35 34 22 +f 24 35 23 +f 36 35 24 +f 37 36 24 +f 25 37 24 +f 26 37 25 +f 14 26 25 +f 39 38 26 +f 27 39 26 +f 28 39 27 +f 40 39 28 +f 29 40 28 +f 41 40 29 +f 42 29 30 +f 42 41 29 +f 43 30 31 +f 43 42 30 +f 43 31 32 +f 44 43 32 +f 45 32 33 +f 45 44 32 +f 45 33 34 +f 46 45 34 +f 46 34 35 +f 47 46 35 +f 48 47 35 +f 36 48 35 +f 49 48 36 +f 37 49 36 +f 26 49 37 +f 38 49 26 +f 39 50 38 +f 51 50 39 +f 40 51 39 +f 52 51 40 +f 53 52 40 +f 41 53 40 +f 53 41 42 +f 54 53 42 +f 55 42 43 +f 55 54 42 +f 56 43 44 +f 56 55 43 +f 56 44 45 +f 57 56 45 +f 58 45 46 +f 58 57 45 +f 58 46 47 +f 59 58 47 +f 60 59 47 +f 48 60 47 +f 49 60 48 +f 61 60 49 +f 50 61 49 +f 38 50 49 +f 51 62 50 +f 52 62 51 +f 53 62 52 +f 62 53 54 +f 62 54 55 +f 62 55 56 +f 62 56 57 +f 62 57 58 +f 62 58 59 +f 60 62 59 +f 61 62 60 +f 50 62 61 + +# End of file diff --git a/A4/resources/teapot.obj b/A4/resources/teapot.obj new file mode 100644 index 0000000..6fed453 --- /dev/null +++ b/A4/resources/teapot.obj @@ -0,0 +1,5049 @@ +# Blender v2.65 (sub 0) OBJ File +# www.blender.org +o teapot.005 +v -0.498530 0.712498 -0.039883 +v -0.501666 0.699221 -0.063813 +v -0.501255 0.717792 0.000000 +v -0.624036 0.711938 -0.039883 +v -0.526706 0.651362 -0.039883 +v -0.508714 0.682112 -0.071712 +v -0.622039 0.698704 -0.063813 +v -0.624834 0.717232 0.000000 +v -0.498530 0.712498 0.039883 +v -0.638129 0.287158 0.000000 +v -0.517593 0.664661 -0.063813 +v -0.534329 0.646030 0.000000 +v -0.614850 0.651067 -0.039883 +v -0.616848 0.664299 -0.063813 +v -0.619445 0.681503 -0.071790 +v -0.741245 0.707456 -0.039883 +v -0.744483 0.712577 0.000000 +v -0.624036 0.711938 0.039883 +v -0.501667 0.699221 0.063813 +v -0.622039 0.698704 0.063813 +v -0.712095 0.661370 -0.063813 +v -0.733150 0.694655 -0.063813 +v -0.741245 0.707456 0.039883 +v -0.733150 0.694655 0.063813 +v -0.631184 0.277569 -0.039883 +v -0.526706 0.651362 0.039883 +v -0.614053 0.645774 0.000000 +v -0.704000 0.648569 -0.039883 +v -0.722621 0.678012 -0.071790 +v -0.832523 0.695296 -0.039883 +v -0.837545 0.699948 0.000000 +v -0.832523 0.695296 0.039883 +v -0.619445 0.681503 0.071790 +v -0.508714 0.682112 0.071712 +v -0.722621 0.678012 0.071790 +v -0.517593 0.664661 0.063813 +v -0.619922 0.238069 -0.071790 +v -0.624826 0.259599 -0.063813 +v -0.710066 0.328372 0.000000 +v -0.614850 0.651067 0.039883 +v -0.787321 0.653419 -0.063813 +v -0.803644 0.668539 -0.071790 +v -0.819967 0.683663 -0.063813 +v -0.819967 0.683663 0.063813 +v -0.803644 0.668539 0.071790 +v -0.711425 0.307332 -0.063813 +v -0.615553 0.216807 -0.063813 +v -0.712688 0.287795 -0.071790 +v -0.631184 0.277569 0.039883 +v -0.710455 0.322361 -0.039883 +v -0.710455 0.322361 0.039883 +v -0.700762 0.643448 0.000000 +v -0.774766 0.641786 -0.039883 +v -0.897800 0.671612 -0.039883 +v -0.904015 0.675354 0.000000 +v -0.897800 0.671612 0.039883 +v -0.882265 0.662257 0.063813 +v -0.712095 0.661370 0.063813 +v -0.787321 0.653419 0.063813 +v -0.608884 0.198682 -0.039883 +v -0.624828 0.259599 0.063813 +v -0.766936 0.377559 0.000000 +v -0.769651 0.372307 0.039883 +v -0.616848 0.664299 0.063813 +v -0.704000 0.648569 0.039883 +v -0.841868 0.637931 -0.063813 +v -0.862065 0.650094 -0.071790 +v -0.882265 0.662257 -0.063813 +v -0.862065 0.650094 0.071790 +v -0.841868 0.637931 0.063813 +v -0.611709 0.194244 0.000000 +v -0.776434 0.359177 -0.063813 +v -0.769651 0.372307 -0.039883 +v -0.713952 0.268259 -0.063813 +v -0.711425 0.307332 0.063813 +v -0.776434 0.359177 0.063813 +v -0.769743 0.637131 0.000000 +v -0.826329 0.628576 -0.039883 +v -0.937016 0.632565 -0.039883 +v -0.943899 0.634805 0.000000 +v -0.937016 0.632565 0.039883 +v -0.919812 0.626965 0.063813 +v -0.897443 0.619684 0.071790 +v -0.774766 0.641786 0.039883 +v -0.826329 0.628576 0.039883 +v -0.714922 0.253231 -0.039883 +v -0.608883 0.198681 0.039883 +v -0.715311 0.247220 0.000000 +v -0.785253 0.342107 -0.071790 +v -0.619922 0.238069 0.071790 +v -0.712688 0.287795 0.071790 +v -0.809626 0.430737 0.000000 +v -0.814205 0.426194 0.039883 +v -0.825653 0.414838 0.063813 +v -0.875076 0.612403 -0.063813 +v -0.897443 0.619684 -0.071790 +v -0.919812 0.626965 -0.063813 +v -0.875076 0.612403 0.063813 +v -0.857869 0.606800 0.039883 +v -0.794072 0.325038 -0.063813 +v -0.800855 0.311909 -0.039883 +v -0.825653 0.414838 -0.063813 +v -0.814205 0.426194 -0.039883 +v -0.615480 0.216617 0.063578 +v -0.785253 0.342107 0.071790 +v -0.840534 0.400078 0.071790 +v -0.820114 0.624834 0.000000 +v -0.857869 0.606800 -0.039883 +v -0.950104 0.574316 -0.039883 +v -0.957194 0.574316 0.000000 +v -0.950104 0.574316 0.039883 +v -0.932377 0.574316 0.063813 +v -0.909334 0.574316 0.071790 +v -0.886292 0.574316 0.063813 +v -0.850987 0.604560 0.000000 +v -0.714922 0.253231 0.039883 +v -0.803571 0.306656 0.000000 +v -0.840534 0.400078 -0.071790 +v -0.713952 0.268259 0.063813 +v -0.794072 0.325038 0.063813 +v -0.839022 0.483916 0.000000 +v -0.844976 0.480304 0.039883 +v -0.859854 0.471278 0.063813 +v -0.879202 0.459542 0.071790 +v -0.886292 0.574316 -0.063813 +v -0.909334 0.574316 -0.071790 +v -0.932377 0.574316 -0.063813 +v -0.868564 0.574316 0.039883 +v -0.861474 0.574316 0.000000 +v -0.855419 0.385315 -0.063813 +v -0.866867 0.373960 -0.039883 +v -0.859854 0.471278 -0.063813 +v -0.844976 0.480304 -0.039883 +v -0.855419 0.385315 0.063813 +v -0.898547 0.447807 0.063813 +v -0.868564 0.574316 -0.039883 +v -0.941014 0.505765 -0.039883 +v -0.947813 0.503580 0.000000 +v -0.941014 0.505765 0.039883 +v -0.924011 0.511234 0.063813 +v -0.901913 0.518343 0.071790 +v -0.879811 0.525448 0.063813 +v -0.862808 0.530917 0.039883 +v -0.800855 0.311909 0.039883 +v -0.871445 0.369416 0.000000 +v -0.879202 0.459542 -0.071790 +v -0.866867 0.373960 0.039883 +v -0.856009 0.533103 0.000000 +v -0.879811 0.525448 -0.063813 +v -0.901913 0.518343 -0.071790 +v -0.924011 0.511234 -0.063813 +v -0.862808 0.530917 -0.039883 +v -0.898547 0.447807 -0.063813 +v -0.913428 0.438781 -0.039883 +v -0.913428 0.438781 0.039883 +v -0.919378 0.435169 0.000000 +v 0.600960 0.444810 0.085753 +v 0.605956 0.463769 0.000000 +v 0.600959 0.444810 -0.085753 +v 0.656890 0.471064 0.000000 +v 0.661223 0.454734 -0.083705 +v 0.730696 0.501576 -0.073611 +v 0.661223 0.454734 0.083705 +v 0.605101 0.399712 -0.137265 +v 0.746455 0.470391 -0.117778 +v 0.724395 0.514048 0.000000 +v 0.605100 0.399712 0.137265 +v 0.672055 0.413907 -0.133928 +v 0.613258 0.341675 -0.154354 +v 0.786583 0.544847 -0.096783 +v 0.768856 0.565896 -0.060489 +v 0.672055 0.413907 0.133928 +v 0.730696 0.501576 0.073611 +v 0.686135 0.360830 -0.150669 +v 0.809626 0.517481 -0.108881 +v 0.766935 0.429850 -0.132501 +v 0.761767 0.574316 0.000000 +v 0.613258 0.341675 0.154354 +v 0.813417 0.626247 -0.075788 +v 0.839021 0.611098 -0.085261 +v 0.793721 0.637899 -0.047367 +v 0.686135 0.360830 0.150669 +v 0.768856 0.565896 0.060489 +v 0.746455 0.470391 0.117778 +v 0.619427 0.283145 -0.137236 +v 0.864627 0.595949 -0.075788 +v 0.832669 0.490118 -0.096783 +v 0.787419 0.389310 -0.117778 +v 0.785843 0.642561 0.000000 +v 0.619427 0.283145 0.137236 +v 0.700219 0.307756 -0.133928 +v 0.847933 0.703560 -0.059638 +v 0.879938 0.698065 -0.067092 +v 0.911944 0.692571 -0.059638 +v 0.823314 0.707784 -0.037273 +v 0.766935 0.429850 0.132501 +v 0.793721 0.637899 0.047367 +v 0.786583 0.544847 0.096783 +v 0.700219 0.307756 0.133928 +v 0.617684 0.235930 -0.085941 +v 0.936563 0.688344 -0.037273 +v 0.884319 0.584297 -0.047367 +v 0.850396 0.469070 -0.060489 +v 0.803175 0.358128 -0.073611 +v 0.813468 0.709475 0.000000 +v 0.617684 0.235930 0.085941 +v 0.625577 0.219883 0.000000 +v 0.711051 0.266929 -0.083705 +v 0.911107 0.765755 -0.053178 +v 0.957193 0.765755 -0.059825 +v 1.003279 0.765755 -0.053178 +v 1.038733 0.765755 -0.033236 +v 0.875654 0.765755 -0.033236 +v 0.809626 0.517481 0.108881 +v 0.787419 0.389310 0.117778 +v 0.823314 0.707784 0.037273 +v 0.813417 0.626247 0.075788 +v 0.711051 0.266929 0.083705 +v 0.715384 0.250599 0.000000 +v 1.052913 0.765755 0.000000 +v 0.946409 0.686653 0.000000 +v 0.892200 0.579635 0.000000 +v 0.857486 0.460650 0.000000 +v 0.809479 0.345652 0.000000 +v 0.861474 0.765755 0.000000 +v 0.929990 0.776479 -0.051602 +v 0.979075 0.777181 -0.058052 +v 1.028157 0.777879 -0.051602 +v 1.065915 0.778419 -0.032251 +v 1.081016 0.778632 0.000000 +v 0.892235 0.775943 -0.032251 +v 0.839021 0.611098 0.085261 +v 0.832669 0.490118 0.096783 +v 0.803175 0.358128 0.073611 +v 0.875654 0.765755 0.033236 +v 0.847933 0.703560 0.059638 +v 1.065915 0.778419 0.032174 +v 1.038733 0.765755 0.033236 +v 0.936563 0.688344 0.037273 +v 0.884319 0.584297 0.047367 +v 0.850396 0.469070 0.060489 +v 0.877131 0.775726 0.000000 +v 0.943713 0.783087 -0.047663 +v 0.992645 0.784366 -0.053621 +v 1.041577 0.785649 -0.047663 +v 1.079216 0.786631 -0.029789 +v 1.094273 0.787027 0.000000 +v 1.079216 0.786631 0.029174 +v 0.906073 0.782101 -0.029789 +v 0.879938 0.698065 0.067092 +v 0.864627 0.595949 0.075788 +v 0.892235 0.775943 0.032236 +v 0.911107 0.765755 0.053178 +v 1.041577 0.785649 0.046875 +v 1.028157 0.777879 0.051503 +v 1.003279 0.765755 0.053178 +v 0.911944 0.692571 0.059638 +v 0.891016 0.781708 0.000000 +v 0.951249 0.785448 -0.042542 +v 0.997575 0.787068 -0.047860 +v 1.043903 0.788686 -0.042542 +v 1.079539 0.789934 -0.026589 +v 1.093795 0.790431 0.000000 +v 1.079539 0.789934 0.024511 +v 1.043903 0.788686 0.039883 +v 0.915613 0.784200 -0.026589 +v 0.957193 0.765755 0.059825 +v 0.906073 0.782101 0.029666 +v 0.929990 0.776479 0.051553 +v 0.997575 0.787068 0.045616 +v 0.992645 0.784366 0.052956 +v 0.979075 0.777181 0.057969 +v 0.901357 0.783702 0.000000 +v 0.951569 0.783431 -0.037421 +v 0.993532 0.785033 -0.042099 +v 1.035492 0.786631 -0.037421 +v 1.067772 0.787863 -0.023388 +v 1.080684 0.788354 0.000000 +v 1.067772 0.787863 0.018464 +v 1.035492 0.786631 0.031119 +v 0.993532 0.785033 0.036781 +v 0.919292 0.782200 -0.023388 +v 0.915613 0.784200 0.026173 +v 0.943713 0.783087 0.047269 +v 0.951569 0.783431 0.034270 +v 0.951249 0.785448 0.041213 +v 0.906379 0.781708 0.000000 +v 0.943653 0.776909 -0.033482 +v 0.980182 0.778010 -0.037667 +v 1.016712 0.779111 -0.033482 +v 1.044812 0.779957 -0.020926 +v 1.056052 0.780295 0.000000 +v 1.044812 0.779957 0.011310 +v 1.016712 0.779111 0.021172 +v 0.980182 0.778010 0.027281 +v 0.943653 0.776909 0.027327 +v 0.915553 0.776064 -0.020926 +v 0.919292 0.782200 0.022403 +v 0.915553 0.776064 0.019003 +v 0.904312 0.775726 0.000000 +v 0.926468 0.765755 -0.031906 +v 0.957193 0.765755 -0.035895 +v 0.987920 0.765755 -0.031906 +v 1.011552 0.765755 -0.019942 +v 1.021006 0.765755 0.000000 +v 1.011552 0.765755 0.003324 +v 0.987920 0.765755 0.010635 +v 0.957193 0.765755 0.017947 +v 0.926468 0.765755 0.021271 +v 0.902834 0.765755 0.016618 +v 0.902834 0.765755 -0.019942 +v 0.893380 0.765755 0.000000 +v 0.886428 0.750924 -0.019014 +v 0.908324 0.750924 -0.030099 +v 0.936793 0.750924 -0.033795 +v 0.965261 0.750924 -0.030099 +v 0.987158 0.750924 -0.019014 +v 0.995918 0.750924 -0.000537 +v 0.987158 0.750924 0.002542 +v 0.965261 0.750924 0.009317 +v 0.936793 0.750924 0.016092 +v 0.908324 0.750924 0.019171 +v 0.886428 0.750924 0.014860 +v 0.877668 0.750924 -0.000537 +v 0.936793 0.750924 -0.007312 +v 0.440746 0.783205 0.000000 +v 0.446690 0.765755 0.000000 +v 0.430973 0.765755 0.119945 +v 0.425236 0.783205 0.118348 +v 0.425236 0.783205 -0.118348 +v 0.453011 0.750009 0.000000 +v 0.437073 0.750009 0.121642 +v 0.441668 0.793673 0.000000 +v 0.386470 0.765755 0.226985 +v 0.430973 0.765755 -0.119945 +v 0.426127 0.793673 -0.118596 +v 0.437073 0.750009 -0.121642 +v 0.426127 0.793673 0.118596 +v 0.381327 0.783205 0.223964 +v 0.381327 0.783205 -0.223964 +v 0.382124 0.793673 -0.224433 +v 0.317150 0.765755 0.317150 +v 0.391939 0.750009 0.230197 +v 0.321638 0.750009 0.321639 +v 0.386470 0.765755 -0.226985 +v 0.391939 0.750009 -0.230197 +v 0.447686 0.797164 0.000000 +v 0.431936 0.797164 -0.120212 +v 0.387332 0.797164 -0.227491 +v 0.230197 0.750009 0.391940 +v 0.226984 0.765755 0.386470 +v 0.317150 0.765755 -0.317150 +v 0.321638 0.750009 -0.321639 +v 0.431936 0.797164 0.120212 +v 0.382124 0.793673 0.224433 +v 0.312929 0.783205 0.312929 +v 0.313584 0.793673 -0.313584 +v 0.312929 0.783205 -0.312929 +v 0.317858 0.797164 -0.317858 +v 0.121642 0.750009 0.437072 +v 0.119944 0.765755 0.430973 +v 0.226984 0.765755 -0.386470 +v 0.230197 0.750009 -0.391940 +v 0.457031 0.793673 0.000000 +v 0.440950 0.793673 -0.122721 +v 0.395416 0.793673 -0.232239 +v 0.324491 0.793673 -0.324492 +v -0.000000 0.750009 0.453012 +v -0.000000 0.765755 0.446690 +v 0.223963 0.783205 0.381327 +v 0.223963 0.783205 -0.381327 +v 0.119944 0.765755 -0.430973 +v 0.121642 0.750009 -0.437072 +v 0.440950 0.793673 0.122721 +v 0.387332 0.797164 0.227491 +v 0.313584 0.793673 0.313584 +v 0.227491 0.797164 -0.387332 +v 0.224433 0.793673 -0.382125 +v 0.232239 0.793673 -0.395417 +v -0.119945 0.765755 0.430973 +v -0.121642 0.750009 0.437072 +v 0.118348 0.783205 0.425237 +v 0.118348 0.783205 -0.425237 +v -0.000000 0.750009 -0.453012 +v -0.000000 0.765755 -0.446690 +v 0.467924 0.783205 0.000000 +v 0.451460 0.783205 -0.125646 +v 0.404842 0.783205 -0.237775 +v 0.332226 0.783205 -0.332226 +v 0.237775 0.783205 -0.404842 +v -0.226985 0.765755 0.386470 +v -0.000000 0.783205 0.440746 +v 0.224433 0.793673 0.382125 +v 0.118596 0.793673 -0.426127 +v -0.000000 0.783205 -0.440746 +v -0.119945 0.765755 -0.430973 +v -0.121642 0.750009 -0.437072 +v 0.451460 0.783205 0.125646 +v 0.395416 0.793673 0.232239 +v 0.317858 0.797164 0.317858 +v 0.122721 0.793673 -0.440950 +v 0.120212 0.797164 -0.431937 +v 0.125646 0.783205 -0.451460 +v -0.317150 0.765755 0.317150 +v -0.230198 0.750009 0.391939 +v -0.321639 0.750009 0.321639 +v -0.118348 0.783205 0.425237 +v 0.118596 0.793673 0.426127 +v -0.000000 0.793673 -0.441668 +v -0.118348 0.783205 -0.425237 +v -0.226985 0.765755 -0.386470 +v 0.478596 0.765755 0.000000 +v 0.461756 0.765755 -0.128512 +v 0.414076 0.765755 -0.243198 +v 0.339803 0.765755 -0.339804 +v 0.243198 0.765755 -0.414076 +v 0.128512 0.765755 -0.461757 +v -0.391940 0.750009 0.230197 +v -0.386470 0.765755 0.226985 +v -0.223964 0.783205 0.381327 +v -0.000000 0.793673 0.441668 +v 0.227491 0.797164 0.387332 +v -0.000000 0.797164 -0.447686 +v -0.118596 0.793673 -0.426127 +v -0.223964 0.783205 -0.381327 +v -0.317150 0.765755 -0.317150 +v -0.230198 0.750009 -0.391939 +v -0.321639 0.750009 -0.321639 +v 0.461756 0.765755 0.128512 +v 0.404842 0.783205 0.237775 +v 0.324491 0.793673 0.324492 +v -0.000000 0.783205 -0.467924 +v -0.000000 0.793673 -0.457031 +v -0.000000 0.765755 -0.478597 +v -0.437073 0.750009 0.121642 +v -0.430974 0.765755 0.119945 +v -0.312929 0.783205 0.312929 +v -0.118596 0.793673 0.426127 +v 0.120212 0.797164 0.431937 +v -0.120212 0.797164 -0.431937 +v -0.224433 0.793673 -0.382125 +v -0.312929 0.783205 -0.312929 +v -0.386470 0.765755 -0.226985 +v -0.391940 0.750009 -0.230197 +v 0.518110 0.682112 0.000000 +v 0.499881 0.682112 -0.139122 +v 0.448260 0.682112 -0.263277 +v 0.367859 0.682112 -0.367859 +v 0.263277 0.682112 -0.448260 +v 0.139122 0.682112 -0.499882 +v -0.000000 0.682112 -0.518110 +v -0.453012 0.750009 0.000000 +v -0.446690 0.765755 0.000000 +v -0.381327 0.783205 0.223964 +v -0.224433 0.793673 0.382125 +v -0.000000 0.797164 0.447686 +v 0.232239 0.793673 0.395417 +v -0.122721 0.793673 -0.440950 +v -0.227491 0.797164 -0.387332 +v -0.313584 0.793673 -0.313584 +v -0.381327 0.783205 -0.223964 +v -0.430974 0.765755 -0.119945 +v 0.499881 0.682112 0.139122 +v 0.414076 0.765755 0.243198 +v 0.332226 0.783205 0.332226 +v -0.128513 0.765755 -0.461757 +v -0.125646 0.783205 -0.451460 +v -0.139123 0.682112 -0.499882 +v -0.437073 0.750009 -0.121642 +v -0.425237 0.783205 0.118348 +v -0.313584 0.793673 0.313584 +v -0.120212 0.797164 0.431937 +v 0.122721 0.793673 0.440950 +v -0.232240 0.793673 -0.395417 +v -0.317859 0.797164 -0.317858 +v -0.382125 0.793673 -0.224433 +v -0.425237 0.783205 -0.118348 +v 0.555408 0.599133 0.000000 +v 0.535865 0.599133 -0.149137 +v 0.480530 0.599133 -0.282230 +v 0.394341 0.599133 -0.394341 +v 0.282230 0.599133 -0.480530 +v 0.149137 0.599133 -0.535866 +v -0.000000 0.599133 -0.555408 +v -0.149138 0.599133 -0.535866 +v -0.440746 0.783205 0.000000 +v -0.382125 0.793673 0.224433 +v -0.227491 0.797164 0.387332 +v -0.000000 0.793673 0.457031 +v 0.237775 0.783205 0.404842 +v -0.237775 0.783205 -0.404842 +v -0.324492 0.793673 -0.324492 +v -0.387332 0.797164 -0.227491 +v -0.426127 0.793673 -0.118596 +v 0.535865 0.599133 0.149137 +v 0.448260 0.682112 0.263277 +v 0.339803 0.765755 0.339804 +v -0.263278 0.682112 -0.448260 +v -0.243198 0.765755 -0.414076 +v -0.282230 0.599133 -0.480530 +v -0.426127 0.793673 0.118596 +v -0.317859 0.797164 0.317858 +v -0.122721 0.793673 0.440950 +v 0.125646 0.783205 0.451460 +v -0.332226 0.783205 -0.332226 +v -0.395417 0.793673 -0.232239 +v -0.431937 0.797164 -0.120212 +v -0.441668 0.793673 0.000000 +v 0.588275 0.517481 0.000000 +v 0.567578 0.517481 -0.157963 +v 0.508969 0.517485 -0.298931 +v 0.417675 0.517481 -0.417675 +v 0.298931 0.517485 -0.508969 +v 0.157963 0.517485 -0.567578 +v -0.000000 0.517481 -0.588275 +v -0.157963 0.517481 -0.567578 +v -0.298931 0.517485 -0.508969 +v -0.387332 0.797164 0.227491 +v -0.232240 0.793673 0.395417 +v -0.000000 0.783205 0.467924 +v 0.243198 0.765755 0.414076 +v -0.339804 0.765755 -0.339804 +v -0.404842 0.783205 -0.237775 +v -0.440950 0.793673 -0.122721 +v -0.447686 0.797164 0.000000 +v 0.567578 0.517485 0.157963 +v 0.480530 0.599133 0.282230 +v 0.367859 0.682112 0.367859 +v -0.394341 0.599133 -0.394341 +v -0.367859 0.682112 -0.367859 +v -0.417675 0.517481 -0.417675 +v -0.431937 0.797164 0.120212 +v -0.324492 0.793673 0.324492 +v -0.125646 0.783205 0.451460 +v 0.128512 0.765755 0.461757 +v -0.414076 0.765755 -0.243198 +v -0.451461 0.783205 -0.125646 +v -0.457031 0.793673 0.000000 +v 0.592873 0.437827 -0.165003 +v 0.531651 0.437827 -0.312254 +v 0.436292 0.437827 -0.436292 +v 0.312254 0.437827 -0.531651 +v 0.165003 0.437827 -0.592873 +v -0.000000 0.437827 -0.614496 +v -0.165004 0.437827 -0.592873 +v -0.312255 0.437827 -0.531651 +v -0.436292 0.437827 -0.436292 +v -0.395417 0.793673 0.232239 +v -0.237775 0.783205 0.404842 +v -0.000000 0.765755 0.478597 +v 0.263277 0.682112 0.448260 +v -0.448260 0.682112 -0.263277 +v -0.461757 0.765755 -0.128512 +v -0.467924 0.783205 0.000000 +v -0.440950 0.793673 0.122721 +v 0.592873 0.437827 0.165003 +v 0.508969 0.517485 0.298931 +v 0.394341 0.599133 0.394341 +v -0.508969 0.517485 -0.298931 +v -0.480530 0.599133 -0.282230 +v -0.531651 0.437827 -0.312254 +v -0.332226 0.783205 0.332226 +v -0.128513 0.765755 0.461757 +v 0.139122 0.682112 0.499882 +v -0.499882 0.682112 -0.139122 +v -0.478597 0.765755 0.000000 +v -0.451461 0.783205 0.125646 +v 0.546669 0.360830 -0.321075 +v 0.448614 0.360830 -0.448614 +v 0.321074 0.360830 -0.546669 +v 0.169664 0.360830 -0.609621 +v -0.000000 0.360830 -0.631850 +v -0.169664 0.360830 -0.609621 +v -0.321075 0.360830 -0.546669 +v -0.448615 0.360830 -0.448614 +v -0.546669 0.360830 -0.321075 +v -0.404842 0.783205 0.237775 +v -0.243198 0.765755 0.414076 +v -0.000000 0.682112 0.518110 +v 0.282230 0.599133 0.480530 +v -0.535866 0.599133 -0.149137 +v -0.461757 0.765755 0.128512 +v 0.531651 0.437827 0.312254 +v 0.417675 0.517481 0.417675 +v 0.609621 0.360830 -0.169664 +v -0.592873 0.437827 -0.165003 +v -0.567578 0.517485 -0.157963 +v -0.609621 0.360830 -0.169664 +v -0.339804 0.765755 0.339804 +v -0.139123 0.682112 0.499882 +v 0.149137 0.599133 0.535866 +v -0.555408 0.599133 0.000000 +v -0.499882 0.682112 0.139122 +v -0.414076 0.765755 0.243198 +v 0.609621 0.360830 0.169664 +v 0.552100 0.287158 -0.324265 +v 0.453072 0.287158 -0.453072 +v 0.324265 0.287158 -0.552100 +v 0.171349 0.287158 -0.615677 +v -0.000000 0.287158 -0.638129 +v -0.171350 0.287158 -0.615677 +v -0.324265 0.287158 -0.552100 +v -0.453072 0.287158 -0.453072 +v -0.552100 0.287158 -0.324265 +v -0.615677 0.287158 -0.171349 +v -0.263278 0.682112 0.448260 +v -0.000000 0.599133 0.555408 +v 0.298931 0.517485 0.508969 +v -0.588275 0.517481 0.000000 +v -0.448260 0.682112 0.263277 +v 0.546669 0.360830 0.321075 +v 0.436292 0.437827 0.436292 +v 0.615677 0.287158 -0.171349 +v -0.631850 0.360830 0.000000 +v -0.614496 0.437827 0.000000 +v -0.367859 0.682112 0.367859 +v -0.149138 0.599133 0.535866 +v 0.157963 0.517481 0.567578 +v -0.567578 0.517481 0.157963 +v -0.480530 0.599133 0.282230 +v 0.615677 0.287158 0.171349 +v 0.541877 0.221240 -0.318259 +v 0.444680 0.221240 -0.444680 +v 0.318259 0.221240 -0.541877 +v 0.168176 0.221240 -0.604276 +v -0.000000 0.221240 -0.626311 +v -0.168177 0.221240 -0.604276 +v -0.318259 0.221240 -0.541877 +v -0.444680 0.221240 -0.444680 +v -0.541877 0.221240 -0.318259 +v -0.604277 0.221240 -0.168176 +v -0.282230 0.599133 0.480530 +v -0.000000 0.517481 0.588275 +v 0.312254 0.437827 0.531651 +v -0.592873 0.437827 0.165003 +v -0.535866 0.599133 0.149137 +v -0.394341 0.599133 0.394341 +v 0.552100 0.287158 0.324265 +v 0.448614 0.360830 0.448614 +v 0.604276 0.221240 -0.168176 +v -0.615677 0.287158 0.171349 +v -0.609621 0.360830 0.169664 +v -0.157963 0.517485 0.567578 +v 0.165003 0.437827 0.592873 +v -0.531651 0.437827 0.312254 +v -0.508969 0.517485 0.298931 +v -0.417675 0.517481 0.417675 +v 0.604276 0.221240 0.168176 +v 0.516317 0.166623 -0.303247 +v 0.423705 0.166623 -0.423705 +v 0.303247 0.166623 -0.516317 +v 0.160243 0.166623 -0.575771 +v -0.000000 0.166623 -0.596769 +v -0.160244 0.166623 -0.575771 +v -0.303247 0.166623 -0.516317 +v -0.423705 0.166623 -0.423705 +v -0.516317 0.166623 -0.303247 +v -0.575771 0.166623 -0.160243 +v -0.298931 0.517485 0.508969 +v -0.000000 0.437827 0.614496 +v 0.321074 0.360830 0.546669 +v -0.546669 0.360830 0.321075 +v 0.541877 0.221240 0.318259 +v 0.453072 0.287158 0.453072 +v 0.575771 0.166623 -0.160243 +v -0.596769 0.166623 0.000000 +v -0.604277 0.221240 0.168176 +v -0.552100 0.287158 0.324265 +v -0.165004 0.437827 0.592873 +v 0.169664 0.360830 0.609621 +v -0.448615 0.360830 0.448614 +v -0.436292 0.437827 0.436292 +v -0.312255 0.437827 0.531651 +v 0.575771 0.166623 0.160243 +v 0.483086 0.122640 -0.283731 +v 0.396438 0.122640 -0.396438 +v 0.283731 0.122640 -0.483086 +v 0.149931 0.122640 -0.538718 +v -0.000000 0.122640 -0.558363 +v -0.149931 0.122640 -0.538718 +v -0.283731 0.122640 -0.483086 +v -0.396438 0.122640 -0.396438 +v -0.483087 0.122640 -0.283731 +v -0.538718 0.122640 -0.149931 +v -0.558363 0.122640 0.000000 +v -0.541877 0.221240 0.318259 +v -0.000000 0.360830 0.631850 +v 0.324265 0.287158 0.552100 +v -0.453072 0.287158 0.453072 +v 0.516317 0.166623 0.303247 +v 0.596768 0.166623 0.000000 +v 0.444680 0.221240 0.444680 +v 0.538718 0.122640 -0.149931 +v -0.538718 0.122640 0.149931 +v -0.516317 0.166623 0.303247 +v -0.444680 0.221240 0.444680 +v -0.169664 0.360830 0.609621 +v 0.171349 0.287158 0.615677 +v -0.324265 0.287158 0.552100 +v -0.321075 0.360830 0.546669 +v 0.538718 0.122640 0.149931 +v 0.558363 0.122640 0.000000 +v 0.449858 0.088629 -0.264215 +v 0.369171 0.088629 -0.369171 +v 0.264215 0.088629 -0.449859 +v 0.139618 0.088629 -0.501662 +v -0.000000 0.088629 -0.519957 +v -0.139618 0.088629 -0.501662 +v -0.264215 0.088629 -0.449859 +v -0.369171 0.088629 -0.369171 +v -0.449859 0.088629 -0.264215 +v -0.501662 0.088629 -0.139618 +v -0.519957 0.088629 0.000000 +v -0.501662 0.088629 0.139618 +v -0.575771 0.166623 0.160243 +v -0.423705 0.166623 0.423705 +v -0.000000 0.287158 0.638129 +v 0.318259 0.221240 0.541877 +v -0.318259 0.221240 0.541877 +v 0.483086 0.122640 0.283731 +v 0.423705 0.166623 0.423705 +v 0.501662 0.088629 -0.139618 +v -0.449859 0.088629 0.264215 +v -0.483087 0.122640 0.283731 +v -0.396438 0.122640 0.396438 +v -0.303247 0.166623 0.516317 +v -0.171350 0.287158 0.615677 +v 0.168176 0.221240 0.604276 +v -0.168177 0.221240 0.604276 +v 0.501662 0.088629 0.139618 +v 0.519957 0.088629 0.000000 +v 0.424299 0.063924 -0.249203 +v 0.348195 0.063924 -0.348195 +v 0.249203 0.063924 -0.424298 +v 0.131685 0.063924 -0.473160 +v -0.000000 0.063924 -0.490415 +v -0.131686 0.063924 -0.473160 +v -0.249203 0.063924 -0.424298 +v -0.348196 0.063924 -0.348195 +v -0.424299 0.063924 -0.249203 +v -0.473160 0.063924 -0.131685 +v -0.490415 0.063924 0.000000 +v -0.473160 0.063924 0.131685 +v -0.424299 0.063924 0.249203 +v -0.283731 0.122640 0.483086 +v -0.000000 0.221240 0.626311 +v 0.303247 0.166623 0.516317 +v -0.160244 0.166623 0.575771 +v 0.449858 0.088629 0.264215 +v 0.396438 0.122640 0.396438 +v 0.473160 0.063924 -0.131685 +v -0.348196 0.063924 0.348195 +v -0.369171 0.088629 0.369171 +v -0.264215 0.088629 0.449859 +v -0.149931 0.122640 0.538718 +v 0.160243 0.166623 0.575771 +v -0.000000 0.166623 0.596769 +v 0.473160 0.063924 0.131685 +v 0.490415 0.063924 0.000000 +v 0.414076 0.047860 -0.243198 +v 0.339803 0.047860 -0.339804 +v 0.243198 0.047860 -0.414076 +v 0.128512 0.047860 -0.461757 +v -0.000000 0.047860 -0.478597 +v -0.128513 0.047860 -0.461757 +v -0.243198 0.047860 -0.414076 +v -0.339804 0.047860 -0.339804 +v -0.414076 0.047860 -0.243198 +v -0.461757 0.047860 -0.128512 +v -0.478597 0.047860 0.000000 +v -0.461757 0.047860 0.128512 +v -0.414076 0.047860 0.243198 +v -0.339804 0.047860 0.339804 +v -0.139618 0.088629 0.501662 +v 0.283731 0.122640 0.483086 +v -0.000000 0.122640 0.558363 +v 0.424299 0.063924 0.249203 +v 0.369171 0.088629 0.369171 +v 0.461756 0.047860 -0.128512 +v -0.243198 0.047860 0.414076 +v -0.249203 0.063924 0.424298 +v -0.131686 0.063924 0.473160 +v -0.000000 0.088629 0.519957 +v 0.149931 0.122640 0.538718 +v 0.461756 0.047860 0.128512 +v 0.478596 0.047860 0.000000 +v 0.410719 0.036005 -0.241228 +v 0.337050 0.036005 -0.337050 +v 0.241227 0.036005 -0.410719 +v 0.127471 0.036005 -0.458017 +v -0.000000 0.036005 -0.474720 +v -0.127471 0.036005 -0.458017 +v -0.241228 0.036005 -0.410719 +v -0.337051 0.036005 -0.337050 +v -0.410719 0.036005 -0.241228 +v -0.458017 0.036005 -0.127471 +v -0.474721 0.036005 0.000000 +v -0.458017 0.036005 0.127471 +v -0.410719 0.036005 0.241228 +v -0.337051 0.036005 0.337050 +v -0.241228 0.036005 0.410719 +v -0.000000 0.063924 0.490415 +v 0.264215 0.088629 0.449859 +v 0.139618 0.088629 0.501662 +v 0.414076 0.047860 0.243198 +v 0.348195 0.063924 0.348195 +v 0.458017 0.036005 -0.127471 +v -0.127471 0.036005 0.458017 +v -0.128513 0.047860 0.461757 +v -0.000000 0.047860 0.478597 +v 0.131685 0.063924 0.473160 +v 0.458017 0.036005 0.127471 +v 0.474720 0.036005 0.000000 +v 0.394137 0.024816 -0.231489 +v 0.323442 0.024816 -0.323442 +v 0.231489 0.024816 -0.394137 +v 0.122324 0.024816 -0.439524 +v -0.000000 0.024816 -0.455554 +v -0.122325 0.024816 -0.439524 +v -0.231489 0.024816 -0.394137 +v -0.323442 0.024816 -0.323442 +v -0.394137 0.024816 -0.231489 +v -0.439524 0.024816 -0.122325 +v -0.455554 0.024816 0.000000 +v -0.439524 0.024816 0.122325 +v -0.394137 0.024816 0.231489 +v -0.323442 0.024816 0.323442 +v -0.231489 0.024816 0.394137 +v -0.122325 0.024816 0.439524 +v 0.128512 0.047860 0.461757 +v 0.249203 0.063924 0.424298 +v 0.410719 0.036005 0.241228 +v 0.339803 0.047860 0.339804 +v 0.439524 0.024816 -0.122325 +v -0.000000 0.036005 0.474720 +v -0.000000 0.024816 0.455554 +v 0.127471 0.036005 0.458017 +v 0.243198 0.047860 0.414076 +v 0.439524 0.024816 0.122325 +v 0.455554 0.024816 0.000000 +v 0.354551 0.014956 -0.208238 +v 0.290957 0.014956 -0.290957 +v 0.208238 0.014956 -0.354551 +v 0.110038 0.014956 -0.395378 +v -0.000000 0.014956 -0.409797 +v -0.110038 0.014956 -0.395378 +v -0.208239 0.014956 -0.354551 +v -0.290957 0.014956 -0.290957 +v -0.354551 0.014956 -0.208238 +v -0.395378 0.014956 -0.110038 +v -0.409797 0.014956 0.000000 +v -0.395378 0.014956 0.110038 +v -0.354551 0.014956 0.208238 +v -0.290957 0.014956 0.290957 +v -0.208239 0.014956 0.354551 +v -0.110038 0.014956 0.395378 +v -0.000000 0.014956 0.409797 +v 0.241227 0.036005 0.410719 +v 0.337050 0.036005 0.337050 +v 0.394137 0.024816 0.231489 +v 0.395378 0.014956 -0.110038 +v 0.122324 0.024816 0.439524 +v 0.110038 0.014956 0.395378 +v 0.231489 0.024816 0.394137 +v 0.395378 0.014956 0.110038 +v 0.409797 0.014956 0.000000 +v 0.282184 0.007090 -0.165735 +v 0.231570 0.007090 -0.231570 +v 0.165735 0.007090 -0.282185 +v 0.087579 0.007090 -0.314679 +v -0.000000 0.007090 -0.326154 +v -0.087579 0.007090 -0.314679 +v -0.165735 0.007090 -0.282185 +v -0.231570 0.007090 -0.231570 +v -0.282184 0.007090 -0.165735 +v -0.314679 0.007090 -0.087579 +v -0.326155 0.007090 0.000000 +v -0.314679 0.007090 0.087579 +v -0.282184 0.007090 0.165735 +v -0.231570 0.007090 0.231570 +v -0.165735 0.007090 0.282185 +v -0.087579 0.007090 0.314679 +v -0.000000 0.007090 0.326154 +v 0.087579 0.007090 0.314679 +v 0.323442 0.024816 0.323442 +v 0.354551 0.014956 0.208238 +v 0.314679 0.007090 -0.087579 +v 0.208238 0.014956 0.354551 +v 0.165735 0.007090 0.282185 +v 0.290957 0.014956 0.290957 +v 0.314679 0.007090 0.087579 +v 0.326154 0.007090 0.000000 +v 0.167259 0.001883 -0.098236 +v 0.137258 0.001883 -0.137259 +v 0.098236 0.001883 -0.167259 +v 0.051910 0.001883 -0.186520 +v -0.000000 0.001883 -0.193322 +v -0.051911 0.001883 -0.186520 +v -0.098237 0.001883 -0.167259 +v -0.137259 0.001883 -0.137259 +v -0.167259 0.001883 -0.098236 +v -0.186520 0.001883 -0.051911 +v -0.193323 0.001883 0.000000 +v -0.186520 0.001883 0.051911 +v -0.167259 0.001883 0.098236 +v -0.137259 0.001883 0.137259 +v -0.098237 0.001883 0.167259 +v -0.051911 0.001883 0.186520 +v -0.000000 0.001883 0.193322 +v 0.051910 0.001883 0.186520 +v 0.098236 0.001883 0.167259 +v 0.282184 0.007090 0.165735 +v 0.186520 0.001883 -0.051911 +v 0.231570 0.007090 0.231570 +v 0.137258 0.001883 0.137259 +v 0.186520 0.001883 0.051911 +v 0.193322 0.001883 0.000000 +v -0.000000 0.000000 0.000000 +v 0.167259 0.001883 0.098236 +v 0.063813 0.861474 0.000000 +v 0.054654 0.888729 0.000000 +v 0.052734 0.888729 0.014691 +v 0.061568 0.861474 0.017135 +v 0.061568 0.861474 -0.017135 +v 0.072979 0.919969 0.020357 +v 0.111968 0.841089 0.000000 +v 0.047296 0.888729 0.027792 +v 0.052734 0.888729 -0.014691 +v 0.108028 0.841089 -0.030065 +v 0.075630 0.919969 0.000000 +v 0.065466 0.919969 0.038494 +v 0.108028 0.841089 0.030065 +v 0.055210 0.861474 0.032427 +v 0.055210 0.861474 -0.032427 +v 0.096873 0.841089 -0.056896 +v 0.100064 0.951211 0.027927 +v 0.089769 0.951211 0.052799 +v 0.183167 0.826023 0.000000 +v 0.176722 0.826023 -0.049184 +v 0.038821 0.888729 0.038821 +v 0.053751 0.919969 0.053751 +v 0.047296 0.888729 -0.027792 +v 0.072979 0.919969 -0.020357 +v 0.158473 0.826023 -0.093076 +v 0.103696 0.951211 0.000000 +v 0.073714 0.951211 0.073714 +v 0.176722 0.826023 0.049184 +v 0.096873 0.841089 0.056896 +v 0.045307 0.861474 0.045307 +v 0.079497 0.841089 -0.079497 +v 0.045307 0.861474 -0.045307 +v 0.130048 0.826023 -0.130048 +v 0.111754 0.978466 0.031195 +v 0.100259 0.978466 0.058974 +v 0.082330 0.978466 0.082330 +v 0.263228 0.813615 0.000000 +v 0.253966 0.813615 -0.070682 +v 0.227741 0.813615 -0.133759 +v 0.027792 0.888729 0.047296 +v 0.038494 0.919969 0.065466 +v 0.052799 0.951211 0.089769 +v 0.038821 0.888729 -0.038821 +v 0.065466 0.919969 -0.038494 +v 0.100064 0.951211 -0.027927 +v 0.186892 0.813615 -0.186892 +v 0.115809 0.978466 0.000000 +v 0.058974 0.978466 0.100259 +v 0.253966 0.813615 0.070682 +v 0.158473 0.826023 0.093076 +v 0.079497 0.841089 0.079497 +v 0.032426 0.861474 0.055210 +v 0.093076 0.826023 -0.158473 +v 0.056896 0.841089 -0.096873 +v 0.032426 0.861474 -0.055210 +v 0.133759 0.813615 -0.227741 +v 0.085811 0.997741 0.023955 +v 0.076985 0.997741 0.045285 +v 0.063219 0.997741 0.063219 +v 0.045285 0.997741 0.076986 +v 0.337972 0.801206 0.000000 +v 0.326081 0.801206 -0.090752 +v 0.292408 0.801206 -0.171740 +v 0.239960 0.801206 -0.239960 +v 0.014691 0.888729 0.052735 +v 0.020357 0.919969 0.072979 +v 0.027927 0.951211 0.100064 +v 0.031195 0.978466 0.111754 +v 0.027792 0.888729 -0.047296 +v 0.053751 0.919969 -0.053751 +v 0.089769 0.951211 -0.052799 +v 0.111754 0.978466 -0.031195 +v 0.171740 0.801206 -0.292408 +v 0.088924 0.997741 0.000000 +v 0.023955 0.997741 0.085811 +v 0.326081 0.801206 0.090752 +v 0.227741 0.813615 0.133759 +v 0.130048 0.826023 0.130048 +v 0.056896 0.841089 0.096873 +v 0.017135 0.861474 0.061568 +v 0.070682 0.813615 -0.253966 +v 0.049184 0.826023 -0.176722 +v 0.030065 0.841089 -0.108029 +v 0.017135 0.861474 -0.061568 +v 0.090752 0.801206 -0.326081 +v -0.000000 1.005054 0.000000 +v 0.393218 0.786140 0.000000 +v 0.379380 0.786140 -0.105586 +v 0.340206 0.786140 -0.199813 +v 0.279184 0.786140 -0.279184 +v 0.199813 0.786140 -0.340206 +v -0.000000 0.888729 0.054654 +v -0.000000 0.919969 0.075630 +v -0.000000 0.951211 0.103696 +v -0.000000 0.978466 0.115809 +v -0.000000 0.997741 0.088925 +v 0.014691 0.888729 -0.052735 +v 0.038494 0.919969 -0.065466 +v 0.073714 0.951211 -0.073714 +v 0.100259 0.978466 -0.058974 +v 0.085811 0.997741 -0.023955 +v 0.105586 0.786140 -0.379381 +v 0.379380 0.786140 0.105586 +v 0.292408 0.801206 0.171740 +v 0.186892 0.813615 0.186892 +v 0.093076 0.826023 0.158473 +v 0.030065 0.841089 0.108029 +v -0.000000 0.861474 0.063813 +v -0.000000 0.801206 -0.337972 +v -0.000000 0.813615 -0.263228 +v -0.000000 0.826023 -0.183167 +v -0.000000 0.841089 -0.111968 +v -0.000000 0.861474 -0.063813 +v -0.000000 0.786140 -0.393218 +v 0.076985 0.997741 -0.045285 +v -0.023955 0.997741 0.085811 +v 0.414784 0.765755 0.000000 +v 0.400190 0.765755 -0.111377 +v 0.358865 0.765755 -0.210772 +v 0.294497 0.765755 -0.294497 +v 0.210772 0.765755 -0.358865 +v 0.111377 0.765755 -0.400190 +v -0.014691 0.888729 0.052735 +v -0.020357 0.919969 0.072979 +v -0.027927 0.951211 0.100064 +v -0.031195 0.978466 0.111754 +v -0.000000 0.888729 -0.054654 +v 0.020357 0.919969 -0.072979 +v 0.052799 0.951211 -0.089769 +v 0.082330 0.978466 -0.082330 +v -0.000000 0.765755 -0.414784 +v 0.063219 0.997741 -0.063219 +v -0.045285 0.997741 0.076986 +v 0.400190 0.765755 0.111377 +v 0.340206 0.786140 0.199813 +v 0.239960 0.801206 0.239960 +v 0.133759 0.813615 0.227741 +v 0.049184 0.826023 0.176722 +v -0.000000 0.841089 0.111968 +v -0.017135 0.861474 0.061568 +v -0.105586 0.786140 -0.379381 +v -0.090752 0.801206 -0.326081 +v -0.070682 0.813615 -0.253966 +v -0.049184 0.826023 -0.176722 +v -0.030066 0.841089 -0.108029 +v -0.017135 0.861474 -0.061568 +v -0.111377 0.765755 -0.400190 +v 0.045285 0.997741 -0.076986 +v -0.063220 0.997741 0.063219 +v 0.414952 0.750806 0.115486 +v 0.430085 0.750806 0.000000 +v 0.414952 0.750806 -0.115486 +v 0.372103 0.750806 -0.218547 +v 0.305360 0.750806 -0.305360 +v 0.218547 0.750806 -0.372103 +v 0.115486 0.750806 -0.414952 +v -0.000000 0.750806 -0.430085 +v -0.027793 0.888729 0.047296 +v -0.038494 0.919969 0.065466 +v -0.052799 0.951211 0.089769 +v -0.058974 0.978466 0.100259 +v -0.014691 0.888729 -0.052735 +v -0.000000 0.919969 -0.075630 +v 0.027927 0.951211 -0.100064 +v 0.058974 0.978466 -0.100259 +v -0.115486 0.750806 -0.414952 +v 0.023955 0.997741 -0.085811 +v -0.076986 0.997741 0.045285 +v 0.372103 0.750806 0.218547 +v 0.358865 0.765755 0.210772 +v 0.279184 0.786140 0.279184 +v 0.171740 0.801206 0.292408 +v 0.070682 0.813615 0.253966 +v -0.000000 0.826023 0.183167 +v -0.030066 0.841089 0.108029 +v -0.032427 0.861474 0.055210 +v -0.210772 0.765755 -0.358865 +v -0.199813 0.786140 -0.340206 +v -0.171740 0.801206 -0.292408 +v -0.133759 0.813615 -0.227741 +v -0.093076 0.826023 -0.158473 +v -0.056896 0.841089 -0.096873 +v -0.032427 0.861474 -0.055210 +v -0.218547 0.750806 -0.372103 +v 0.031195 0.978466 -0.111754 +v -0.000000 0.997741 -0.088925 +v -0.082331 0.978466 0.082330 +v -0.085811 0.997741 0.023955 +v 0.305360 0.750806 0.305360 +v 0.294497 0.765755 0.294497 +v -0.038821 0.888729 0.038821 +v -0.053751 0.919969 0.053751 +v -0.073714 0.951211 0.073714 +v -0.027793 0.888729 -0.047296 +v -0.020357 0.919969 -0.072979 +v -0.000000 0.951211 -0.103696 +v -0.305360 0.750806 -0.305360 +v -0.294497 0.765755 -0.294497 +v -0.000000 0.978466 -0.115809 +v -0.023955 0.997741 -0.085811 +v -0.100259 0.978466 0.058974 +v -0.088925 0.997741 0.000000 +v 0.210772 0.765755 0.358865 +v 0.218547 0.750806 0.372103 +v 0.199813 0.786140 0.340206 +v 0.090752 0.801206 0.326081 +v -0.000000 0.813615 0.263228 +v -0.049184 0.826023 0.176722 +v -0.056896 0.841089 0.096873 +v -0.045307 0.861474 0.045307 +v -0.279185 0.786140 -0.279184 +v -0.239960 0.801206 -0.239960 +v -0.186892 0.813615 -0.186892 +v -0.130049 0.826023 -0.130048 +v -0.079497 0.841089 -0.079497 +v -0.045307 0.861474 -0.045307 +v -0.372103 0.750806 -0.218547 +v -0.358865 0.765755 -0.210772 +v -0.031195 0.978466 -0.111754 +v -0.045285 0.997741 -0.076986 +v -0.111754 0.978466 0.031195 +v -0.085811 0.997741 -0.023955 +v 0.111377 0.765755 0.400190 +v 0.115486 0.750806 0.414952 +v -0.047296 0.888729 0.027792 +v -0.065466 0.919969 0.038494 +v -0.089770 0.951211 0.052799 +v -0.038821 0.888729 -0.038821 +v -0.038494 0.919969 -0.065466 +v -0.027927 0.951211 -0.100064 +v -0.414952 0.750806 -0.115486 +v -0.400190 0.765755 -0.111377 +v -0.058974 0.978466 -0.100259 +v -0.063220 0.997741 -0.063219 +v -0.115809 0.978466 0.000000 +v -0.076986 0.997741 -0.045285 +v 0.105586 0.786140 0.379381 +v -0.000000 0.765755 0.414784 +v -0.000000 0.750806 0.430085 +v -0.000000 0.801206 0.337972 +v -0.070682 0.813615 0.253966 +v -0.093076 0.826023 0.158473 +v -0.079497 0.841089 0.079497 +v -0.055210 0.861474 0.032427 +v -0.340206 0.786140 -0.199813 +v -0.292408 0.801206 -0.171740 +v -0.227741 0.813615 -0.133759 +v -0.158473 0.826023 -0.093076 +v -0.096873 0.841089 -0.056896 +v -0.055210 0.861474 -0.032427 +v -0.430085 0.750806 0.000000 +v -0.414784 0.765755 0.000000 +v -0.052799 0.951211 -0.089769 +v -0.082331 0.978466 -0.082330 +v -0.100064 0.951211 0.027927 +v -0.111754 0.978466 -0.031195 +v -0.000000 0.786140 0.393218 +v -0.115486 0.750806 0.414952 +v -0.111377 0.765755 0.400190 +v -0.052735 0.888729 0.014691 +v -0.072979 0.919969 0.020357 +v -0.047296 0.888729 -0.027792 +v -0.053751 0.919969 -0.053751 +v -0.414952 0.750806 0.115486 +v -0.400190 0.765755 0.111377 +v -0.379381 0.786140 -0.105586 +v -0.073714 0.951211 -0.073714 +v -0.100259 0.978466 -0.058974 +v -0.103696 0.951211 0.000000 +v -0.105586 0.786140 0.379381 +v -0.218547 0.750806 0.372103 +v -0.210772 0.765755 0.358865 +v -0.090752 0.801206 0.326081 +v -0.133759 0.813615 0.227741 +v -0.130049 0.826023 0.130048 +v -0.096873 0.841089 0.056896 +v -0.061568 0.861474 0.017135 +v -0.326081 0.801206 -0.090752 +v -0.253966 0.813615 -0.070682 +v -0.176722 0.826023 -0.049184 +v -0.108029 0.841089 -0.030065 +v -0.061568 0.861474 -0.017135 +v -0.372103 0.750806 0.218547 +v -0.358865 0.765755 0.210772 +v -0.393219 0.786140 0.000000 +v -0.089770 0.951211 -0.052799 +v -0.100064 0.951211 -0.027927 +v -0.199813 0.786140 0.340206 +v -0.305360 0.750806 0.305360 +v -0.294497 0.765755 0.294497 +v -0.054655 0.888729 0.000000 +v -0.075630 0.919969 0.000000 +v -0.052735 0.888729 -0.014691 +v -0.065466 0.919969 -0.038494 +v -0.379381 0.786140 0.105586 +v -0.171740 0.801206 0.292408 +v -0.279185 0.786140 0.279184 +v -0.186892 0.813615 0.186892 +v -0.158473 0.826023 0.093076 +v -0.108029 0.841089 0.030065 +v -0.063813 0.861474 0.000000 +v -0.337972 0.801206 0.000000 +v -0.263228 0.813615 0.000000 +v -0.183167 0.826023 0.000000 +v -0.111968 0.841089 0.000000 +v -0.340206 0.786140 0.199813 +v -0.072979 0.919969 -0.020357 +v -0.239960 0.801206 0.239960 +v -0.326081 0.801206 0.090752 +v -0.292408 0.801206 0.171740 +v -0.227741 0.813615 0.133759 +v -0.176722 0.826023 0.049184 +v -0.253966 0.813615 0.070682 +v -0.526706 0.651362 -0.039883 +v -0.534329 0.646030 0.000000 +v -0.619922 0.238069 -0.071790 +v -0.624826 0.259599 -0.063813 +v -0.638129 0.287158 0.000000 +v -0.631184 0.277569 0.039883 +v -0.501666 0.699221 -0.063813 +v -0.508714 0.682112 -0.071712 +v -0.611709 0.194244 0.000000 +v -0.608883 0.198681 0.039883 +v -0.517593 0.664661 0.063813 +v -0.508714 0.682112 0.071712 +v -0.631184 0.277569 -0.039883 +v -0.624828 0.259599 0.063813 +v -0.615480 0.216617 0.063578 +v -0.615553 0.216807 -0.063813 +v -0.517593 0.664661 -0.063813 +v -0.498530 0.712498 -0.039883 +v -0.619922 0.238069 0.071790 +v -0.526706 0.651362 0.039883 +v -0.608884 0.198682 -0.039883 +v 0.605100 0.399712 0.137265 +v 0.613258 0.341675 0.154354 +v 0.605956 0.463769 0.000000 +v 0.600959 0.444810 -0.085753 +v 0.613258 0.341675 -0.154354 +v 0.605101 0.399712 -0.137265 +v 0.600960 0.444810 0.085753 +v 0.121642 0.750009 -0.437072 +v -0.000000 0.750009 -0.453012 +v 0.453011 0.750009 0.000000 +v 0.437073 0.750009 -0.121642 +v -0.453012 0.750009 0.000000 +v -0.437073 0.750009 -0.121642 +v -0.230198 0.750009 0.391939 +v -0.321639 0.750009 0.321639 +v -0.391940 0.750009 0.230197 +v -0.437073 0.750009 0.121642 +v 0.121642 0.750009 0.437072 +v -0.000000 0.750009 0.453012 +v -0.121642 0.750009 0.437072 +v 0.437073 0.750009 0.121642 +v 0.391939 0.750009 0.230197 +v 0.321638 0.750009 -0.321639 +v 0.230197 0.750009 -0.391940 +v -0.121642 0.750009 -0.437072 +v 0.391939 0.750009 -0.230197 +v 0.321638 0.750009 0.321639 +v 0.230197 0.750009 0.391940 +v -0.230198 0.750009 -0.391939 +v -0.501255 0.717792 0.000000 +v 0.617684 0.235930 0.085941 +v 0.625577 0.219883 0.000000 +v -0.321639 0.750009 -0.321639 +v -0.391940 0.750009 -0.230197 +v -0.498530 0.712498 0.039883 +v -0.501667 0.699221 0.063813 +v 0.617684 0.235930 -0.085941 +v 0.619427 0.283145 -0.137236 +v 0.619427 0.283145 0.137236 +vn -0.901883 0.415418 0.118168 +vn -0.905637 0.407056 0.118656 +vn -0.877041 0.418744 0.235298 +vn 0.058443 -0.998260 0.000732 +vn 0.015107 -0.999878 0.000183 +vn 0.014557 -0.949278 0.314035 +vn 0.056703 -0.947539 0.314524 +vn 0.162053 -0.986755 0.002014 +vn 0.157933 -0.933592 0.321604 +vn 0.392376 -0.919767 0.004334 +vn 0.378307 -0.856655 0.350688 +vn 0.783776 -0.620991 0.005249 +vn 0.726829 -0.553880 0.406079 +vn 0.994812 -0.101627 0.001984 +vn 0.908139 -0.082766 0.410321 +vn 0.003082 -0.939787 0.341685 +vn 0.002167 -0.619495 0.784967 +vn 0.011536 -0.679403 0.733634 +vn 0.044679 -0.675588 0.735923 +vn 0.123325 -0.652272 0.747856 +vn 0.275399 -0.556871 0.783593 +vn 0.460067 -0.316263 0.829615 +vn 0.563036 -0.041200 0.825373 +vn -0.000427 0.122166 0.992492 +vn 0.000397 0.003632 0.999969 +vn 0.002869 0.011841 0.999908 +vn 0.004852 0.029298 0.999542 +vn -0.008179 0.053499 0.998505 +vn -0.046510 0.041536 0.998047 +vn -0.039155 0.003113 0.999207 +vn -0.850551 0.473769 -0.228217 +vn -0.897885 0.424177 -0.117649 +vn -0.880886 0.473281 0.000000 +vn -0.013611 0.682394 0.730827 +vn -0.053896 0.680441 0.730796 +vn -0.147557 0.656789 0.739464 +vn -0.325968 0.560564 0.761223 +vn -0.537645 0.315806 0.781762 +vn -0.611530 0.029939 0.790613 +vn -0.904172 0.427137 0.000000 +vn -0.897885 0.424146 0.117618 +vn -0.020112 0.949461 0.313150 +vn -0.081820 0.945433 0.315287 +vn -0.227699 0.916379 0.329173 +vn -0.504196 0.785302 0.359203 +vn -0.810633 0.443220 0.382611 +vn -0.921232 0.039705 0.386944 +vn -0.020569 0.949400 -0.313334 +vn -0.021729 0.999756 -0.000092 +vn -0.004242 0.950468 -0.310770 +vn -0.088260 0.996094 -0.000488 +vn -0.246895 0.969024 -0.001343 +vn -0.549730 0.835322 -0.002350 +vn -0.880673 0.473647 -0.001984 +vn -0.999084 0.042146 -0.000610 +vn -0.877041 0.418744 -0.235298 +vn -0.920286 0.391156 0.000000 +vn -0.905637 0.407056 -0.118656 +vn -0.083132 0.945006 -0.316202 +vn -0.230201 0.914823 -0.331797 +vn -0.505570 0.782800 -0.362743 +vn -0.808710 0.444960 -0.384625 +vn -0.920835 0.042055 -0.387646 +vn -0.897885 0.424146 -0.117618 +vn -0.901883 0.415448 -0.118168 +vn -0.014161 0.682394 -0.730796 +vn -0.055361 0.680074 -0.731010 +vn -0.150029 0.655660 -0.739982 +vn -0.327616 0.560594 -0.760491 +vn -0.537431 0.320933 -0.779809 +vn -0.611988 0.033387 -0.790155 +vn 0.015168 -0.949339 -0.313852 +vn 0.011902 -0.679403 -0.733634 +vn 0.003265 -0.939817 -0.341594 +vn 0.000183 0.004212 -0.999969 +vn 0.003510 0.014008 -0.999878 +vn 0.005921 0.035951 -0.999329 +vn -0.010132 0.064333 -0.997864 +vn -0.051576 0.048463 -0.997467 +vn -0.041597 0.003998 -0.999115 +vn 0.003082 -0.620106 -0.784478 +vn -0.000031 0.122440 -0.992462 +vn -0.897885 0.424177 0.117649 +vn 0.046449 -0.674398 -0.736869 +vn 0.125980 -0.648946 -0.750298 +vn 0.275430 -0.552477 -0.786676 +vn 0.455519 -0.320536 -0.830500 +vn 0.561693 -0.046480 -0.826014 +vn -0.888668 0.391644 0.238441 +vn 0.058046 -0.947630 -0.314005 +vn 0.159948 -0.933836 -0.319865 +vn 0.380169 -0.857753 -0.345927 +vn 0.725547 -0.560930 -0.398602 +vn 0.908597 -0.089236 -0.407971 +vn 0.003235 -0.999969 0.000031 +vn 0.973144 0.230110 0.000824 +vn 0.890896 0.211737 0.401776 +vn 0.912900 0.408094 0.002533 +vn 0.836970 0.380932 0.392834 +vn 0.829035 0.559160 0.003784 +vn 0.764519 0.528550 0.368969 +vn 0.718650 0.695334 0.003937 +vn 0.668294 0.663717 0.335917 +vn 0.579577 0.814905 0.002838 +vn 0.542650 0.779687 0.312357 +vn 0.495163 0.868770 0.002258 +vn 0.458052 0.820643 0.341624 +vn 0.561205 0.137028 0.816218 +vn 0.532029 0.253456 0.807886 +vn 0.497543 0.363445 0.787591 +vn 0.449538 0.472060 0.758293 +vn 0.373669 0.563555 0.736686 +vn 0.289041 0.531114 0.796442 +vn -0.023225 -0.005249 0.999695 +vn -0.016785 -0.010254 0.999786 +vn -0.011444 -0.012940 0.999847 +vn -0.009796 -0.013276 0.999847 +vn -0.014801 -0.013916 0.999786 +vn -0.089755 -0.176122 0.980255 +vn -0.585772 -0.152379 0.795984 +vn -0.538896 -0.288766 0.791314 +vn -0.484146 -0.407910 0.774071 +vn -0.424635 -0.509781 0.748161 +vn -0.355907 -0.584765 0.728935 +vn -0.889828 -0.237159 0.389782 +vn -0.808740 -0.446852 0.382366 +vn -0.702475 -0.613269 0.361095 +vn -0.590625 -0.734855 0.333293 +vn -0.483291 -0.816767 0.315104 +vn -0.912076 0.409955 0.000000 +vn -0.965606 -0.259987 -0.000458 +vn -0.872433 -0.488693 -0.001465 +vn -0.748436 -0.663167 -0.002197 +vn -0.621601 -0.783288 -0.002136 +vn -0.507065 -0.861873 -0.001251 +vn -0.438215 -0.854366 0.279183 +vn -0.456130 -0.889889 -0.000732 +vn -0.889126 -0.238868 -0.390332 +vn -0.807001 -0.448531 -0.384075 +vn -0.700980 -0.613392 -0.363750 +vn -0.590442 -0.733757 -0.336039 +vn -0.484787 -0.815332 -0.316477 +vn -0.440962 -0.852931 -0.279305 +vn -0.359691 -0.584185 -0.727531 +vn -0.358074 -0.682241 -0.637410 +vn -0.585467 -0.154668 -0.795770 +vn -0.538499 -0.291696 -0.790490 +vn -0.484512 -0.409772 -0.772851 +vn -0.426496 -0.510056 -0.746910 +vn -0.909543 -0.399274 -0.115207 +vn -0.971191 -0.204688 -0.121891 +vn -0.912931 -0.326609 -0.244606 +vn -0.020478 -0.017853 -0.999603 +vn -0.024537 -0.005737 -0.999664 +vn -0.020844 -0.012207 -0.999695 +vn -0.017548 -0.016846 -0.999695 +vn -0.016724 -0.018097 -0.999695 +vn -0.909116 -0.400311 0.115055 +vn -0.873775 -0.472610 0.114475 +vn -0.795892 -0.566485 0.213538 +vn -0.353069 -0.684103 0.638203 +vn 0.559679 0.139714 -0.816828 +vn 0.528581 0.255501 -0.809473 +vn 0.494217 0.362987 -0.789911 +vn 0.449049 0.469283 -0.760308 +vn 0.378246 0.560869 -0.736412 +vn -0.091983 -0.174383 -0.980346 +vn 0.295267 0.530625 -0.794488 +vn 0.890500 0.214759 -0.401044 +vn 0.836634 0.384075 -0.390515 +vn 0.765191 0.530198 -0.365123 +vn 0.671041 0.663228 -0.331339 +vn 0.547929 0.777642 -0.308206 +vn 0.464522 0.818842 -0.337199 +vn 0.931486 0.265572 -0.248543 +vn 0.939543 0.342357 0.000000 +vn 0.947539 0.295114 -0.122684 +vn -0.351421 0.936186 0.001953 +vn -0.144444 0.989502 0.003174 +vn -0.126743 0.878811 0.459975 +vn -0.716758 0.697287 -0.000946 +vn -0.299997 0.838313 0.455214 +vn -0.621876 0.660207 0.421155 +vn -0.901822 0.432081 -0.004517 +vn -0.807031 0.443434 0.389904 +vn -0.930204 0.366863 -0.008484 +vn -0.824549 0.383312 0.416059 +vn -0.850673 0.525529 -0.011628 +vn -0.722465 0.508988 0.467910 +vn -0.668447 0.743645 -0.011139 +vn -0.531449 0.686514 0.496170 +vn -0.116459 0.505448 0.854946 +vn -0.258400 0.470656 0.843593 +vn -0.407605 0.396985 0.822321 +vn -0.450270 0.352367 0.820399 +vn -0.385876 0.395734 0.833338 +vn -0.270669 0.487838 0.829890 +vn 0.141606 -0.001190 0.989898 +vn -0.067690 0.525346 0.848170 +vn 0.989593 0.100253 0.103122 +vn 0.970244 0.213324 0.114475 +vn 0.960418 0.152654 0.232917 +vn 0.241829 0.092502 0.965880 +vn 0.209296 0.170660 0.962828 +vn 0.096194 0.178625 0.979186 +vn 0.009552 0.154332 0.987945 +vn -0.000122 0.151952 0.988372 +vn 0.361248 -0.477279 0.801019 +vn 0.607929 -0.282540 0.741997 +vn 0.679220 -0.106754 0.726096 +vn 0.583911 -0.078524 0.807978 +vn 0.402722 -0.205237 0.891995 +vn 0.279519 -0.338694 0.898404 +vn 0.488601 -0.768700 0.412671 +vn 0.784570 -0.501511 0.364544 +vn 0.893918 -0.279611 0.350291 +vn 0.861415 -0.285287 0.420179 +vn 0.679373 -0.540452 0.496323 +vn 0.458327 -0.754540 0.469588 +vn 0.524155 -0.851588 -0.000153 +vn 0.827143 -0.561968 0.001679 +vn 0.943205 -0.332133 0.003479 +vn 0.933256 -0.359081 0.005737 +vn 0.756859 -0.653493 0.006470 +vn 0.492843 -0.870083 0.004120 +vn 0.322489 -0.946562 -0.001129 +vn 0.912839 -0.326609 0.244942 +vn 0.824396 -0.565996 0.000000 +vn 0.894162 -0.447676 0.000000 +vn 0.486557 -0.770501 -0.411756 +vn 0.783990 -0.504074 -0.362285 +vn 0.895199 -0.281899 -0.345134 +vn 0.863735 -0.289010 -0.412824 +vn 0.682119 -0.544267 -0.488296 +vn 0.461928 -0.758202 -0.460128 +vn 0.357463 -0.479141 -0.801599 +vn 0.605884 -0.285867 -0.742393 +vn 0.679739 -0.108646 -0.725333 +vn 0.583636 -0.077883 -0.808222 +vn 0.401440 -0.199225 -0.893918 +vn 0.281961 -0.330638 -0.900632 +vn 0.135228 -0.002380 -0.990783 +vn 0.235755 0.091128 -0.967498 +vn 0.200720 0.170629 -0.964660 +vn 0.086123 0.184576 -0.979003 +vn 0.000671 0.174322 -0.984680 +vn -0.007141 0.169012 -0.985565 +vn 0.966613 -0.042848 -0.252602 +vn 0.960418 0.152654 -0.232917 +vn 0.989593 0.100223 -0.103092 +vn -0.119297 0.503342 -0.855770 +vn -0.261269 0.472793 -0.841517 +vn -0.414075 0.399792 -0.817713 +vn -0.459700 0.357036 -0.813105 +vn -0.394024 0.408490 -0.823298 +vn -0.277871 0.487381 -0.827754 +vn -0.072207 0.520127 -0.851009 +vn -0.298654 0.840297 -0.452376 +vn -0.617512 0.663961 -0.421613 +vn -0.801324 0.450209 -0.393872 +vn -0.819422 0.389691 -0.420270 +vn -0.721274 0.506912 -0.471969 +vn -0.538347 0.670644 -0.510239 +vn -0.482009 0.876125 -0.005127 +vn -0.394635 0.815363 0.423536 +vn -0.321909 0.946745 -0.002594 +vn -0.255287 0.921995 0.291086 +vn 0.004242 0.999969 0.000397 +vn -0.002960 0.999939 -0.010102 +vn 0.853450 0.521073 -0.007050 +vn 0.392041 0.688986 -0.609546 +vn 0.805170 -0.592517 -0.023621 +vn 0.588763 -0.206122 -0.781579 +vn 0.681478 -0.731040 -0.033296 +vn 0.485031 -0.441237 -0.754967 +vn -0.206824 0.638203 0.741539 +vn -0.129490 0.862056 0.489944 +vn -0.033418 0.999176 0.022340 +vn 0.047700 0.864040 -0.501114 +vn 0.099307 0.538743 -0.836573 +vn 0.053560 0.251839 -0.966277 +vn 0.020112 0.322611 0.946287 +vn 0.021943 0.748894 0.662282 +vn -0.025941 0.995605 0.089908 +vn -0.059175 0.930876 -0.360424 +vn -0.080172 0.784448 -0.614948 +vn -0.142582 0.557604 -0.817743 +vn 0.281747 -0.174993 0.943388 +vn 0.303903 0.444136 0.842830 +vn 0.034333 0.983764 0.175970 +vn -0.113865 0.956420 -0.268777 +vn -0.155339 0.858852 -0.488021 +vn -0.207404 0.641865 -0.738182 +vn 0.467238 -0.683187 0.561144 +vn 0.699515 0.004364 0.714560 +vn 0.355296 0.891934 0.279641 +vn -0.170354 0.971465 -0.164861 +vn -0.245552 0.901181 -0.357097 +vn -0.248726 0.651082 -0.717063 +vn 0.494430 -0.869167 0.006317 +vn 0.933134 -0.358898 0.019868 +vn 0.703146 0.710685 0.021790 +vn -0.203650 0.978942 -0.012574 +vn -0.326456 0.942869 -0.066073 +vn -0.397595 0.857082 -0.327525 +vn 0.460616 -0.712546 -0.529221 +vn 0.695486 -0.098544 -0.711722 +vn 0.397534 0.853816 -0.336070 +vn -0.198248 0.963439 0.180151 +vn -0.306833 0.888516 0.341075 +vn -0.393689 0.807672 0.438887 +vn 0.276559 -0.211951 -0.937315 +vn 0.294626 0.366161 -0.882656 +vn 0.046632 0.973235 -0.224982 +vn -0.146733 0.912168 0.382611 +vn -0.202643 0.700797 0.683950 +vn -0.232673 0.506485 0.830226 +vn 0.011689 0.309397 -0.950835 +vn 0.013245 0.708640 -0.705435 +vn -0.027589 0.995758 -0.087680 +vn -0.047395 0.829371 0.556658 +vn -0.015259 0.386608 0.922086 +vn 0.004639 0.119510 0.992798 +vn -0.211035 0.631001 -0.746513 +vn -0.138768 0.848781 -0.510147 +vn -0.024995 0.999664 -0.001190 +vn 0.120426 0.724570 0.678579 +vn 0.260750 0.006531 0.965361 +vn 0.272500 -0.255898 0.927488 +vn -0.395581 0.809961 -0.432905 +vn -0.258827 0.918851 -0.297800 +vn 0.004730 0.999878 0.013031 +vn 0.466628 0.599780 0.649983 +vn 0.621937 -0.400861 0.672628 +vn 0.551042 -0.592181 0.587878 +vn 0.649068 0.384991 -0.656087 +vn 0.055971 0.691214 0.720450 +vn -0.115940 0.804590 0.582354 +vn -0.262185 0.897946 0.353435 +vn -0.341655 0.885006 -0.316263 +vn -0.081423 0.793085 -0.603626 +vn -0.155675 0.857753 -0.489883 +vn 0.728690 0.365978 0.578784 +vn 0.318674 0.539384 0.779382 +vn 0.953551 0.300150 -0.024415 +vn -0.133976 0.836818 -0.530808 +vn 0.095401 0.667959 -0.738029 +vn 0.000000 0.999969 0.000000 +vn -0.992523 -0.122013 0.000000 +vn -0.937346 -0.348338 0.000000 +vn -0.905148 -0.348827 -0.242836 +vn -0.958617 -0.122227 -0.257057 +vn -0.832057 0.554674 0.000000 +vn -0.803217 0.555376 -0.215339 +vn -0.048616 0.998810 0.000000 +vn -0.046236 0.998840 -0.012726 +vn 0.544267 0.838893 0.000000 +vn 0.525376 0.839106 0.140843 +vn 0.783471 0.621387 0.000000 +vn 0.756371 0.621845 0.202918 +vn 0.880886 0.473281 0.000000 +vn 0.850551 0.473769 0.228217 +vn -0.810907 -0.349376 -0.469375 +vn -0.859004 -0.122410 -0.497085 +vn -0.719657 0.555559 -0.416425 +vn -0.041749 0.998810 -0.024415 +vn 0.470077 0.839625 0.272011 +vn 0.677236 0.622608 0.391980 +vn 0.761803 0.474471 0.440962 +vn -0.662465 -0.349620 -0.662465 +vn -0.701773 -0.122440 -0.701773 +vn -0.587878 0.555650 -0.587878 +vn -0.034272 0.998810 -0.034272 +vn 0.383831 0.839808 0.383831 +vn 0.553148 0.622913 0.553148 +vn 0.622303 0.474776 0.622303 +vn -0.469375 -0.349376 -0.810907 +vn -0.497085 -0.122379 -0.859004 +vn -0.416425 0.555559 -0.719657 +vn -0.024415 0.998810 -0.041749 +vn 0.272011 0.839625 0.470077 +vn 0.391980 0.622608 0.677236 +vn 0.440962 0.474471 0.761834 +vn -0.242836 -0.348827 -0.905148 +vn -0.257057 -0.122227 -0.958617 +vn -0.215339 0.555376 -0.803217 +vn -0.012726 0.998840 -0.046205 +vn 0.140843 0.839106 0.525376 +vn 0.202918 0.621845 0.756371 +vn 0.228217 0.473769 0.850551 +vn 0.000000 -0.348338 -0.937346 +vn 0.000000 -0.122013 -0.992523 +vn 0.000000 0.554674 -0.832057 +vn 0.000000 0.998810 -0.048616 +vn 0.000000 0.838893 0.544267 +vn 0.000000 0.621387 0.783471 +vn 0.000000 0.473281 0.880886 +vn 0.242836 -0.348827 -0.905148 +vn 0.257057 -0.122227 -0.958617 +vn 0.215308 0.555376 -0.803217 +vn 0.012726 0.998840 -0.046205 +vn -0.140843 0.839106 0.525376 +vn -0.202918 0.621845 0.756340 +vn -0.228217 0.473769 0.850551 +vn 0.469375 -0.349376 -0.810907 +vn 0.497085 -0.122379 -0.859004 +vn 0.416425 0.555559 -0.719657 +vn 0.024415 0.998810 -0.041749 +vn -0.272011 0.839625 0.470077 +vn -0.391980 0.622608 0.677236 +vn -0.440962 0.474502 0.761803 +vn 0.662465 -0.349620 -0.662465 +vn 0.701773 -0.122471 -0.701773 +vn 0.587878 0.555650 -0.587878 +vn 0.034272 0.998810 -0.034272 +vn -0.383831 0.839808 0.383831 +vn -0.553148 0.622913 0.553148 +vn -0.622303 0.474776 0.622303 +vn 0.810907 -0.349406 -0.469375 +vn 0.859004 -0.122379 -0.497085 +vn 0.719657 0.555559 -0.416425 +vn 0.041749 0.998810 -0.024415 +vn -0.470077 0.839625 0.272011 +vn -0.677236 0.622608 0.391980 +vn -0.761803 0.474471 0.440962 +vn 0.905148 -0.348827 -0.242836 +vn 0.958617 -0.122227 -0.257057 +vn 0.803217 0.555376 -0.215339 +vn 0.046205 0.998840 -0.012726 +vn -0.525376 0.839106 0.140843 +vn -0.756340 0.621876 0.202918 +vn -0.850551 0.473769 0.228217 +vn 0.937346 -0.348338 0.000000 +vn 0.992523 -0.122013 0.000000 +vn 0.832026 0.554674 0.000000 +vn 0.048616 0.998810 0.000000 +vn -0.544267 0.838893 0.000000 +vn -0.783471 0.621387 0.000000 +vn 0.905148 -0.348827 0.242836 +vn 0.958617 -0.122227 0.257057 +vn 0.803217 0.555376 0.215308 +vn 0.046205 0.998840 0.012726 +vn -0.525376 0.839106 -0.140843 +vn -0.756340 0.621876 -0.202918 +vn 0.810907 -0.349406 0.469375 +vn 0.859004 -0.122379 0.497085 +vn 0.719657 0.555559 0.416425 +vn 0.041749 0.998810 0.024415 +vn -0.470077 0.839625 -0.272011 +vn -0.677236 0.622608 -0.391980 +vn -0.761803 0.474471 -0.440962 +vn 0.662465 -0.349620 0.662465 +vn 0.701773 -0.122471 0.701773 +vn 0.587878 0.555650 0.587878 +vn 0.034272 0.998810 0.034272 +vn -0.383831 0.839808 -0.383831 +vn -0.553148 0.622913 -0.553148 +vn -0.622303 0.474776 -0.622303 +vn 0.469375 -0.349376 0.810907 +vn 0.497085 -0.122379 0.859004 +vn 0.416425 0.555559 0.719657 +vn 0.024415 0.998810 0.041749 +vn -0.272011 0.839625 -0.470077 +vn -0.391980 0.622608 -0.677236 +vn -0.440962 0.474471 -0.761803 +vn 0.242836 -0.348827 0.905148 +vn 0.257057 -0.122227 0.958617 +vn 0.215339 0.555376 0.803217 +vn 0.012726 0.998840 0.046205 +vn -0.140843 0.839106 -0.525376 +vn -0.202918 0.621845 -0.756371 +vn -0.228217 0.473769 -0.850551 +vn 0.000000 -0.348338 0.937346 +vn 0.000000 -0.122013 0.992523 +vn 0.000000 0.554674 0.832057 +vn 0.000000 0.998810 0.048616 +vn 0.000000 0.838893 -0.544267 +vn 0.000000 0.621387 -0.783471 +vn 0.000000 0.473281 -0.880886 +vn -0.242836 -0.348827 0.905148 +vn -0.257057 -0.122227 0.958617 +vn -0.215308 0.555376 0.803217 +vn -0.012726 0.998840 0.046205 +vn 0.140843 0.839106 -0.525376 +vn 0.202918 0.621845 -0.756371 +vn 0.228217 0.473769 -0.850551 +vn -0.469375 -0.349376 0.810907 +vn -0.497085 -0.122379 0.859004 +vn -0.416425 0.555559 0.719657 +vn -0.024415 0.998810 0.041749 +vn 0.272011 0.839625 -0.470077 +vn 0.391980 0.622608 -0.677236 +vn 0.440962 0.474471 -0.761803 +vn -0.662465 -0.349620 0.662465 +vn -0.701773 -0.122440 0.701773 +vn -0.587878 0.555650 0.587878 +vn -0.034272 0.998810 0.034272 +vn 0.383831 0.839808 -0.383831 +vn 0.553148 0.622913 -0.553148 +vn 0.622303 0.474776 -0.622303 +vn -0.810907 -0.349376 0.469375 +vn -0.859004 -0.122410 0.497085 +vn -0.719657 0.555528 0.416425 +vn -0.041749 0.998810 0.024415 +vn 0.470077 0.839625 -0.272011 +vn 0.677236 0.622639 -0.391980 +vn 0.761803 0.474471 -0.440962 +vn -0.905148 -0.348827 0.242836 +vn -0.958617 -0.122227 0.257057 +vn -0.803217 0.555376 0.215339 +vn -0.046236 0.998840 0.012726 +vn 0.525376 0.839106 -0.140843 +vn 0.756371 0.621845 -0.202918 +vn 0.850551 0.473769 -0.228217 +vn 0.908292 0.418256 0.000000 +vn 0.877041 0.418744 0.235298 +vn 0.920286 0.391156 0.000000 +vn 0.888668 0.391644 0.238441 +vn 0.907315 0.342753 0.243446 +vn 0.785638 0.419416 0.454756 +vn 0.796075 0.392285 0.460799 +vn 0.812830 0.343333 0.470504 +vn 0.931486 0.265542 0.248543 +vn 0.834162 0.266366 0.482864 +vn 0.855312 0.152379 0.495132 +vn 0.966613 -0.042848 0.252602 +vn 0.864498 -0.045808 0.500504 +vn 0.641804 0.419691 0.641804 +vn 0.650349 0.392499 0.650349 +vn 0.664052 0.343577 0.664052 +vn 0.681509 0.266579 0.681509 +vn 0.698813 0.152501 0.698813 +vn 0.706351 -0.045869 0.706351 +vn 0.454756 0.419416 0.785638 +vn 0.460799 0.392285 0.796075 +vn 0.470504 0.343333 0.812830 +vn 0.482864 0.266366 0.834162 +vn 0.495132 0.152409 0.855312 +vn 0.500504 -0.045808 0.864498 +vn 0.235298 0.418744 0.877041 +vn 0.238441 0.391644 0.888668 +vn 0.243446 0.342753 0.907315 +vn 0.249855 0.265908 0.931028 +vn 0.256172 0.152104 0.954558 +vn 0.258980 -0.045717 0.964782 +vn 0.000000 0.418256 0.908292 +vn 0.000000 0.391156 0.920286 +vn 0.000000 0.342357 0.939543 +vn 0.000000 0.265542 0.964080 +vn 0.000000 0.151891 0.988372 +vn 0.000000 -0.045656 0.998932 +vn -0.235298 0.418744 0.877041 +vn -0.238441 0.391644 0.888668 +vn -0.243446 0.342753 0.907315 +vn -0.249855 0.265877 0.931028 +vn -0.256172 0.152104 0.954558 +vn -0.258980 -0.045717 0.964782 +vn -0.454756 0.419416 0.785638 +vn -0.460799 0.392285 0.796075 +vn -0.470504 0.343333 0.812830 +vn -0.482864 0.266366 0.834162 +vn -0.495132 0.152379 0.855312 +vn -0.500504 -0.045808 0.864498 +vn -0.641804 0.419691 0.641804 +vn -0.650349 0.392499 0.650349 +vn -0.664052 0.343577 0.664052 +vn -0.681509 0.266579 0.681509 +vn -0.698813 0.152501 0.698813 +vn -0.706351 -0.045869 0.706351 +vn -0.785638 0.419416 0.454756 +vn -0.796075 0.392285 0.460799 +vn -0.812830 0.343364 0.470504 +vn -0.834162 0.266366 0.482864 +vn -0.855312 0.152379 0.495132 +vn -0.864498 -0.045808 0.500504 +vn -0.907315 0.342753 0.243446 +vn -0.931028 0.265908 0.249855 +vn -0.954558 0.152104 0.256172 +vn -0.964782 -0.045717 0.258980 +vn -0.939543 0.342357 0.000000 +vn -0.964080 0.265542 0.000000 +vn -0.988372 0.151891 0.000000 +vn -0.888668 0.391644 -0.238441 +vn -0.907315 0.342753 -0.243446 +vn -0.931028 0.265877 -0.249855 +vn -0.954558 0.152104 -0.256172 +vn -0.785638 0.419416 -0.454756 +vn -0.796075 0.392285 -0.460799 +vn -0.812830 0.343333 -0.470504 +vn -0.834162 0.266366 -0.482864 +vn -0.855312 0.152379 -0.495132 +vn -0.964782 -0.045717 -0.258980 +vn -0.864498 -0.045808 -0.500504 +vn -0.641804 0.419691 -0.641804 +vn -0.650349 0.392499 -0.650349 +vn -0.664052 0.343577 -0.664052 +vn -0.681509 0.266579 -0.681509 +vn -0.698813 0.152501 -0.698813 +vn -0.706351 -0.045869 -0.706351 +vn -0.454756 0.419416 -0.785638 +vn -0.460799 0.392285 -0.796075 +vn -0.470504 0.343333 -0.812830 +vn -0.482864 0.266366 -0.834162 +vn -0.495132 0.152379 -0.855312 +vn -0.500504 -0.045808 -0.864498 +vn -0.235298 0.418744 -0.877041 +vn -0.238441 0.391644 -0.888668 +vn -0.243446 0.342753 -0.907315 +vn -0.249855 0.265908 -0.931028 +vn -0.256172 0.152104 -0.954558 +vn -0.258980 -0.045717 -0.964782 +vn 0.000000 0.418256 -0.908292 +vn 0.000000 0.391156 -0.920286 +vn 0.000000 0.342357 -0.939543 +vn 0.000000 0.265542 -0.964080 +vn 0.000000 0.151891 -0.988372 +vn 0.000000 -0.045656 -0.998932 +vn 0.235298 0.418744 -0.877041 +vn 0.238441 0.391644 -0.888668 +vn 0.243446 0.342753 -0.907315 +vn 0.249855 0.265877 -0.931028 +vn 0.256172 0.152104 -0.954558 +vn 0.258980 -0.045717 -0.964782 +vn 0.454756 0.419416 -0.785638 +vn 0.460799 0.392285 -0.796075 +vn 0.470504 0.343333 -0.812830 +vn 0.482864 0.266366 -0.834162 +vn 0.495132 0.152379 -0.855312 +vn 0.500504 -0.045808 -0.864498 +vn 0.641804 0.419691 -0.641804 +vn 0.650349 0.392499 -0.650349 +vn 0.664052 0.343577 -0.664052 +vn 0.681509 0.266579 -0.681509 +vn 0.698813 0.152501 -0.698813 +vn 0.706351 -0.045869 -0.706351 +vn 0.785638 0.419416 -0.454756 +vn 0.796075 0.392285 -0.460799 +vn 0.812830 0.343364 -0.470504 +vn 0.834162 0.266366 -0.482864 +vn 0.855312 0.152379 -0.495132 +vn 0.864498 -0.045808 -0.500504 +vn 0.877041 0.418744 -0.235298 +vn 0.888668 0.391644 -0.238441 +vn 0.907315 0.342753 -0.243446 +vn 0.795892 -0.566485 0.213538 +vn 0.712180 -0.701987 0.000000 +vn 0.687399 -0.702445 0.184393 +vn 0.652974 -0.757347 0.000000 +vn 0.630146 -0.757805 0.169012 +vn 0.724021 -0.689749 0.000000 +vn 0.698752 -0.690329 0.187414 +vn 0.886410 -0.462874 0.000000 +vn 0.855861 -0.463454 0.229530 +vn 0.817774 -0.327158 0.473434 +vn 0.712729 -0.567248 0.412549 +vn 0.615345 -0.703146 0.356151 +vn 0.564043 -0.758446 0.326456 +vn 0.625660 -0.690939 0.362102 +vn 0.766625 -0.464125 0.443678 +vn 0.668111 -0.327403 0.668111 +vn 0.582171 -0.567522 0.582171 +vn 0.502579 -0.703421 0.502579 +vn 0.460646 -0.758660 0.460646 +vn 0.510971 -0.691183 0.510971 +vn 0.626209 -0.464370 0.626240 +vn 0.473434 -0.327158 0.817774 +vn 0.412549 -0.567248 0.712729 +vn 0.356151 -0.703146 0.615375 +vn 0.326456 -0.758446 0.564043 +vn 0.362102 -0.690939 0.625660 +vn 0.443678 -0.464125 0.766625 +vn 0.245003 -0.326609 0.912839 +vn 0.213538 -0.566485 0.795892 +vn 0.184393 -0.702445 0.687399 +vn 0.169012 -0.757805 0.630146 +vn 0.187414 -0.690329 0.698752 +vn 0.229530 -0.463454 0.855831 +vn 0.000000 -0.326243 0.945250 +vn 0.000000 -0.565996 0.824396 +vn 0.000000 -0.701987 0.712180 +vn 0.000000 -0.757347 0.652974 +vn 0.000000 -0.689749 0.724021 +vn 0.000000 -0.462905 0.886380 +vn -0.245003 -0.326609 0.912839 +vn -0.213538 -0.566485 0.795892 +vn -0.184393 -0.702445 0.687399 +vn -0.169012 -0.757805 0.630146 +vn -0.187414 -0.690329 0.698752 +vn -0.229530 -0.463454 0.855861 +vn -0.473434 -0.327158 0.817774 +vn -0.412549 -0.567248 0.712729 +vn -0.356151 -0.703146 0.615375 +vn -0.326456 -0.758446 0.564043 +vn -0.362102 -0.690939 0.625660 +vn -0.443678 -0.464125 0.766625 +vn -0.668111 -0.327403 0.668111 +vn -0.582171 -0.567522 0.582171 +vn -0.502579 -0.703421 0.502579 +vn -0.460646 -0.758660 0.460646 +vn -0.510971 -0.691183 0.510971 +vn -0.626209 -0.464370 0.626209 +vn -0.817774 -0.327158 0.473434 +vn -0.712729 -0.567248 0.412549 +vn -0.615375 -0.703146 0.356151 +vn -0.564043 -0.758446 0.326456 +vn -0.625660 -0.690939 0.362102 +vn -0.766625 -0.464125 0.443678 +vn -0.912931 -0.326609 0.244575 +vn -0.687399 -0.702445 0.184393 +vn -0.630146 -0.757805 0.169012 +vn -0.698752 -0.690329 0.187414 +vn -0.855831 -0.463485 0.229530 +vn -0.824396 -0.565996 0.000000 +vn -0.712180 -0.701987 0.000000 +vn -0.652974 -0.757347 0.000000 +vn -0.724021 -0.689749 0.000000 +vn -0.886410 -0.462874 0.000000 +vn -0.795892 -0.566485 -0.213538 +vn -0.687399 -0.702445 -0.184393 +vn -0.630146 -0.757805 -0.169012 +vn -0.698752 -0.690329 -0.187414 +vn -0.855831 -0.463454 -0.229530 +vn -0.817774 -0.327158 -0.473434 +vn -0.712729 -0.567217 -0.412549 +vn -0.615375 -0.703146 -0.356151 +vn -0.564043 -0.758446 -0.326456 +vn -0.625660 -0.690939 -0.362102 +vn -0.766625 -0.464125 -0.443678 +vn -0.668111 -0.327403 -0.668111 +vn -0.582171 -0.567522 -0.582171 +vn -0.502579 -0.703421 -0.502579 +vn -0.460646 -0.758660 -0.460646 +vn -0.510971 -0.691183 -0.510971 +vn -0.626209 -0.464370 -0.626209 +vn -0.473434 -0.327158 -0.817774 +vn -0.412549 -0.567248 -0.712729 +vn -0.356151 -0.703146 -0.615375 +vn -0.326456 -0.758446 -0.564043 +vn -0.362102 -0.690939 -0.625660 +vn -0.443678 -0.464125 -0.766625 +vn -0.245003 -0.326609 -0.912839 +vn -0.213538 -0.566485 -0.795892 +vn -0.184393 -0.702445 -0.687399 +vn -0.169012 -0.757805 -0.630146 +vn -0.187414 -0.690329 -0.698752 +vn -0.229530 -0.463454 -0.855831 +vn 0.000000 -0.326243 -0.945250 +vn 0.000000 -0.565996 -0.824396 +vn 0.000000 -0.701987 -0.712180 +vn 0.000000 -0.757347 -0.652974 +vn 0.000000 -0.689749 -0.724021 +vn 0.000000 -0.462905 -0.886380 +vn 0.245003 -0.326609 -0.912839 +vn 0.213538 -0.566485 -0.795892 +vn 0.184393 -0.702445 -0.687399 +vn 0.169012 -0.757805 -0.630146 +vn 0.187445 -0.690329 -0.698752 +vn 0.229530 -0.463454 -0.855861 +vn 0.473434 -0.327158 -0.817774 +vn 0.412549 -0.567248 -0.712729 +vn 0.356151 -0.703146 -0.615375 +vn 0.326456 -0.758446 -0.564043 +vn 0.362102 -0.690939 -0.625660 +vn 0.443678 -0.464125 -0.766625 +vn 0.668111 -0.327403 -0.668111 +vn 0.582171 -0.567522 -0.582171 +vn 0.502579 -0.703421 -0.502579 +vn 0.460646 -0.758660 -0.460646 +vn 0.510971 -0.691183 -0.510971 +vn 0.626209 -0.464370 -0.626209 +vn 0.817774 -0.327158 -0.473434 +vn 0.712729 -0.567248 -0.412549 +vn 0.615375 -0.703146 -0.356151 +vn 0.564043 -0.758446 -0.326456 +vn 0.625660 -0.690939 -0.362102 +vn 0.766625 -0.464125 -0.443678 +vn 0.912839 -0.326609 -0.244942 +vn 0.795892 -0.566485 -0.213538 +vn 0.687399 -0.702445 -0.184393 +vn 0.630146 -0.757805 -0.169012 +vn 0.698752 -0.690329 -0.187414 +vn 0.855861 -0.463454 -0.229530 +vn 0.025666 -0.999664 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.024781 -0.999664 -0.006623 +vn 0.068667 -0.997620 0.000000 +vn 0.066256 -0.997620 -0.017731 +vn 0.157170 -0.987548 0.000000 +vn 0.151677 -0.987579 -0.040620 +vn 0.373150 -0.927763 0.000000 +vn 0.360118 -0.927885 -0.096469 +vn 0.789148 -0.614154 0.000000 +vn 0.762017 -0.614399 -0.204505 +vn 0.022156 -0.999664 -0.012787 +vn 0.059236 -0.997650 -0.034272 +vn 0.135624 -0.987640 -0.078463 +vn 0.322153 -0.928129 -0.186377 +vn 0.682333 -0.615131 -0.394971 +vn 0.018067 -0.999664 -0.018067 +vn 0.048341 -0.997650 -0.048341 +vn 0.110691 -0.987640 -0.110691 +vn 0.262947 -0.928251 -0.262947 +vn 0.557329 -0.615375 -0.557329 +vn 0.012787 -0.999664 -0.022156 +vn 0.034272 -0.997650 -0.059236 +vn 0.078463 -0.987640 -0.135624 +vn 0.186377 -0.928129 -0.322153 +vn 0.394971 -0.615131 -0.682302 +vn 0.006623 -0.999664 -0.024781 +vn 0.017731 -0.997620 -0.066256 +vn 0.040620 -0.987579 -0.151677 +vn 0.096469 -0.927885 -0.360118 +vn 0.204474 -0.614399 -0.762017 +vn 0.000000 -0.999664 -0.025666 +vn 0.000000 -0.997620 -0.068667 +vn 0.000000 -0.987548 -0.157170 +vn 0.000000 -0.927763 -0.373150 +vn 0.000000 -0.614154 -0.789148 +vn -0.006623 -0.999664 -0.024781 +vn -0.017731 -0.997620 -0.066256 +vn -0.040620 -0.987579 -0.151677 +vn -0.096469 -0.927885 -0.360118 +vn -0.204474 -0.614399 -0.762017 +vn -0.012787 -0.999664 -0.022156 +vn -0.034272 -0.997650 -0.059236 +vn -0.078463 -0.987640 -0.135624 +vn -0.186377 -0.928129 -0.322153 +vn -0.394971 -0.615131 -0.682333 +vn -0.018067 -0.999664 -0.018067 +vn -0.048341 -0.997650 -0.048341 +vn -0.110691 -0.987640 -0.110691 +vn -0.262947 -0.928251 -0.262947 +vn -0.557329 -0.615375 -0.557329 +vn -0.022156 -0.999664 -0.012787 +vn -0.059236 -0.997650 -0.034272 +vn -0.135624 -0.987640 -0.078463 +vn -0.322153 -0.928129 -0.186377 +vn -0.682302 -0.615131 -0.394971 +vn -0.024781 -0.999664 -0.006623 +vn -0.066256 -0.997620 -0.017731 +vn -0.151677 -0.987579 -0.040620 +vn -0.360118 -0.927885 -0.096469 +vn -0.762017 -0.614399 -0.204474 +vn -0.025666 -0.999664 0.000000 +vn -0.068667 -0.997620 0.000000 +vn -0.157170 -0.987548 0.000000 +vn -0.373150 -0.927763 0.000000 +vn -0.789148 -0.614154 0.000000 +vn -0.024781 -0.999664 0.006623 +vn -0.066256 -0.997620 0.017731 +vn -0.151677 -0.987579 0.040620 +vn -0.360149 -0.927885 0.096469 +vn -0.762017 -0.614399 0.204474 +vn -0.022156 -0.999664 0.012787 +vn -0.059236 -0.997650 0.034272 +vn -0.135624 -0.987640 0.078463 +vn -0.322153 -0.928129 0.186377 +vn -0.682333 -0.615131 0.394971 +vn -0.018067 -0.999664 0.018067 +vn -0.048341 -0.997650 0.048341 +vn -0.110691 -0.987640 0.110691 +vn -0.262947 -0.928251 0.262947 +vn -0.557329 -0.615375 0.557329 +vn -0.012787 -0.999664 0.022156 +vn -0.034272 -0.997650 0.059236 +vn -0.078463 -0.987640 0.135624 +vn -0.186377 -0.928129 0.322153 +vn -0.394971 -0.615131 0.682302 +vn -0.006623 -0.999664 0.024781 +vn -0.017731 -0.997620 0.066256 +vn -0.040620 -0.987579 0.151677 +vn -0.096469 -0.927885 0.360118 +vn -0.204474 -0.614399 0.762017 +vn 0.000000 -0.999664 0.025666 +vn 0.000000 -0.997620 0.068667 +vn 0.000000 -0.987548 0.157170 +vn 0.000000 -0.927763 0.373150 +vn 0.000000 -0.614154 0.789148 +vn 0.006623 -0.999664 0.024781 +vn 0.017731 -0.997620 0.066256 +vn 0.040620 -0.987579 0.151677 +vn 0.096469 -0.927885 0.360149 +vn 0.204474 -0.614399 0.762017 +vn 0.012787 -0.999664 0.022156 +vn 0.034272 -0.997650 0.059236 +vn 0.078463 -0.987640 0.135624 +vn 0.186377 -0.928129 0.322153 +vn 0.394971 -0.615131 0.682333 +vn 0.018067 -0.999664 0.018067 +vn 0.048341 -0.997650 0.048341 +vn 0.110691 -0.987640 0.110691 +vn 0.262947 -0.928251 0.262947 +vn 0.557329 -0.615375 0.557329 +vn 0.022156 -0.999664 0.012787 +vn 0.059236 -0.997650 0.034272 +vn 0.135624 -0.987640 0.078463 +vn 0.322153 -0.928129 0.186346 +vn 0.682302 -0.615131 0.394971 +vn 0.024781 -0.999664 0.006623 +vn 0.066256 -0.997620 0.017731 +vn 0.151677 -0.987579 0.040620 +vn 0.360118 -0.927885 0.096469 +vn 0.762017 -0.614399 0.204474 +vn 0.464827 -0.373638 -0.802667 +vn 0.655812 -0.373882 -0.655812 +vn 0.000000 -0.372539 0.927976 +vn -0.240699 -0.373028 0.896023 +vn -0.802667 -0.373608 0.464827 +vn 0.896023 -0.372997 -0.240699 +vn -0.927976 -0.372539 0.000000 +vn 0.927976 -0.372539 0.000000 +vn 0.717063 0.696982 0.000000 +vn 0.990387 -0.138310 -0.000061 +vn 0.956694 -0.138737 0.255806 +vn 0.692129 0.697470 0.185583 +vn 0.857326 -0.139317 0.495529 +vn 0.620045 0.697653 0.358837 +vn 0.700125 -0.139531 0.700217 +vn 0.506516 0.697714 0.506546 +vn 0.495468 -0.139286 0.857356 +vn 0.358776 0.697714 0.620014 +vn 0.255867 -0.138737 0.956694 +vn 0.185583 0.697531 0.692068 +vn 0.000061 -0.138310 0.990387 +vn 0.000000 0.696982 0.717063 +vn -0.255806 -0.138737 0.956694 +vn -0.185583 0.697470 0.692129 +vn -0.495529 -0.139317 0.857326 +vn -0.358837 0.697653 0.620045 +vn -0.700217 -0.139531 0.700156 +vn -0.506546 0.697714 0.506516 +vn -0.857356 -0.139286 0.495468 +vn -0.620014 0.697714 0.358776 +vn -0.956694 -0.138737 0.255867 +vn -0.692068 0.697531 0.185583 +vn -0.990387 -0.138310 0.000061 +vn -0.717063 0.696982 0.000000 +vn -0.956694 -0.138737 -0.255806 +vn -0.692129 0.697470 -0.185583 +vn -0.857326 -0.139317 -0.495529 +vn -0.620045 0.697653 -0.358837 +vn -0.700125 -0.139531 -0.700217 +vn -0.506516 0.697714 -0.506546 +vn -0.495468 -0.139286 -0.857356 +vn -0.358776 0.697714 -0.620014 +vn -0.255867 -0.138737 -0.956694 +vn -0.185583 0.697531 -0.692068 +vn -0.000061 -0.138310 -0.990387 +vn 0.000000 0.696982 -0.717063 +vn 0.255806 -0.138737 -0.956694 +vn 0.185583 0.697470 -0.692129 +vn 0.495529 -0.139317 -0.857326 +vn 0.358837 0.697653 -0.620045 +vn 0.700217 -0.139531 -0.700156 +vn 0.506546 0.697714 -0.506516 +vn 0.857356 -0.139286 -0.495468 +vn 0.620014 0.697714 -0.358776 +vn 0.956694 -0.138737 -0.255867 +vn 0.692068 0.697531 -0.185583 +vn 0.292520 0.956236 0.000000 +vn 0.282083 0.956389 0.075686 +vn 0.177953 0.984008 0.000000 +vn 0.171606 0.984069 0.046022 +vn 0.158879 0.987274 0.000000 +vn 0.153264 0.987304 0.041078 +vn 0.217719 0.975982 0.000000 +vn 0.210059 0.976043 0.056276 +vn 0.504715 0.863277 0.000000 +vn 0.487197 0.863460 0.130558 +vn 0.693258 0.720664 0.000000 +vn 0.669057 0.721183 0.179449 +vn 0.252388 0.956511 0.146092 +vn 0.153508 0.984130 0.088839 +vn 0.137059 0.987365 0.079318 +vn 0.187872 0.976135 0.108676 +vn 0.435926 0.863887 0.252205 +vn 0.598956 0.721824 0.346660 +vn 0.206091 0.956572 0.206091 +vn 0.125340 0.984161 0.125340 +vn 0.111911 0.987396 0.111911 +vn 0.153356 0.976196 0.153356 +vn 0.355907 0.864071 0.355907 +vn 0.489151 0.722098 0.489151 +vn 0.146092 0.956511 0.252388 +vn 0.088839 0.984130 0.153508 +vn 0.079318 0.987365 0.137059 +vn 0.108676 0.976135 0.187872 +vn 0.252205 0.863887 0.435926 +vn 0.346660 0.721824 0.598956 +vn 0.075686 0.956389 0.282083 +vn 0.046022 0.984069 0.171606 +vn 0.041078 0.987304 0.153264 +vn 0.056276 0.976043 0.210059 +vn 0.130558 0.863460 0.487197 +vn 0.179449 0.721183 0.669057 +vn 0.000000 0.956236 0.292520 +vn 0.000000 0.984008 0.177953 +vn 0.000000 0.987274 0.158879 +vn 0.000000 0.975982 0.217719 +vn 0.000000 0.863277 0.504715 +vn 0.000000 0.720664 0.693258 +vn -0.075686 0.956389 0.282083 +vn -0.046022 0.984069 0.171606 +vn -0.041078 0.987304 0.153264 +vn -0.056276 0.976043 0.210059 +vn -0.130558 0.863460 0.487197 +vn -0.179449 0.721183 0.669057 +vn -0.146092 0.956511 0.252388 +vn -0.088839 0.984130 0.153508 +vn -0.079318 0.987365 0.137059 +vn -0.108676 0.976135 0.187872 +vn -0.252205 0.863887 0.435926 +vn -0.346660 0.721824 0.598956 +vn -0.206091 0.956572 0.206091 +vn -0.125340 0.984161 0.125340 +vn -0.111911 0.987396 0.111911 +vn -0.153356 0.976196 0.153356 +vn -0.355907 0.864071 0.355907 +vn -0.489151 0.722098 0.489151 +vn -0.252388 0.956511 0.146092 +vn -0.153508 0.984130 0.088839 +vn -0.137059 0.987365 0.079318 +vn -0.187872 0.976135 0.108676 +vn -0.435926 0.863887 0.252205 +vn -0.598956 0.721824 0.346660 +vn -0.282083 0.956389 0.075686 +vn -0.171606 0.984069 0.046022 +vn -0.153264 0.987304 0.041078 +vn -0.210059 0.976043 0.056276 +vn -0.487197 0.863460 0.130558 +vn -0.669057 0.721183 0.179449 +vn -0.292520 0.956236 0.000000 +vn -0.177953 0.984008 0.000000 +vn -0.158879 0.987274 0.000000 +vn -0.217719 0.975982 0.000000 +vn -0.504715 0.863277 0.000000 +vn -0.693258 0.720664 0.000000 +vn -0.282083 0.956389 -0.075686 +vn -0.171606 0.984069 -0.046022 +vn -0.153264 0.987304 -0.041078 +vn -0.210059 0.976043 -0.056276 +vn -0.487197 0.863460 -0.130558 +vn -0.669057 0.721183 -0.179449 +vn -0.252388 0.956511 -0.146092 +vn -0.153508 0.984130 -0.088839 +vn -0.137059 0.987365 -0.079318 +vn -0.187872 0.976135 -0.108676 +vn -0.435926 0.863887 -0.252205 +vn -0.598956 0.721824 -0.346660 +vn -0.206091 0.956572 -0.206091 +vn -0.125340 0.984161 -0.125340 +vn -0.111911 0.987396 -0.111911 +vn -0.153356 0.976196 -0.153356 +vn -0.355907 0.864071 -0.355907 +vn -0.489151 0.722098 -0.489151 +vn -0.146092 0.956511 -0.252388 +vn -0.088839 0.984130 -0.153508 +vn -0.079318 0.987365 -0.137059 +vn -0.108676 0.976135 -0.187872 +vn -0.252205 0.863887 -0.435926 +vn -0.346660 0.721824 -0.598956 +vn -0.075686 0.956389 -0.282083 +vn -0.046022 0.984069 -0.171606 +vn -0.041078 0.987304 -0.153264 +vn -0.056276 0.976043 -0.210059 +vn -0.130558 0.863460 -0.487197 +vn -0.179449 0.721183 -0.669057 +vn 0.000000 0.956236 -0.292520 +vn 0.000000 0.984008 -0.177953 +vn 0.000000 0.987274 -0.158879 +vn 0.000000 0.975982 -0.217719 +vn 0.000000 0.863277 -0.504715 +vn 0.000000 0.720664 -0.693258 +vn 0.075686 0.956389 -0.282083 +vn 0.046022 0.984069 -0.171606 +vn 0.041078 0.987304 -0.153264 +vn 0.056276 0.976043 -0.210059 +vn 0.130558 0.863460 -0.487197 +vn 0.179449 0.721183 -0.669057 +vn 0.146092 0.956511 -0.252388 +vn 0.088839 0.984130 -0.153508 +vn 0.079318 0.987365 -0.137059 +vn 0.108676 0.976135 -0.187872 +vn 0.252205 0.863887 -0.435926 +vn 0.346660 0.721824 -0.598956 +vn 0.206091 0.956572 -0.206091 +vn 0.125340 0.984161 -0.125340 +vn 0.111911 0.987396 -0.111911 +vn 0.153356 0.976196 -0.153356 +vn 0.355907 0.864071 -0.355907 +vn 0.489151 0.722098 -0.489151 +vn 0.252388 0.956511 -0.146092 +vn 0.153508 0.984130 -0.088839 +vn 0.137059 0.987365 -0.079318 +vn 0.187872 0.976135 -0.108676 +vn 0.435926 0.863887 -0.252205 +vn 0.598956 0.721824 -0.346660 +vn 0.282083 0.956389 -0.075686 +vn 0.171606 0.984069 -0.046022 +vn 0.153264 0.987304 -0.041078 +vn 0.210059 0.976043 -0.056276 +vn 0.487197 0.863460 -0.130558 +vn 0.669057 0.721183 -0.179449 +vn 0.363842 0.931455 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.351451 0.931516 0.093509 +vn 0.968261 0.249916 0.000000 +vn 0.935423 0.249763 0.250130 +vn 0.842860 -0.538102 0.000000 +vn 0.813959 -0.538713 0.217292 +vn 0.786767 -0.617206 -0.000031 +vn 0.759514 -0.618000 0.202857 +vn 0.314432 0.931791 0.181280 +vn 0.838404 0.249855 0.484359 +vn 0.729026 -0.539720 0.420911 +vn 0.680013 -0.619068 0.392743 +vn 0.256386 0.931913 0.256417 +vn 0.684652 0.249886 0.684652 +vn 0.595050 -0.540147 0.595050 +vn 0.555010 -0.619526 0.555040 +vn 0.181280 0.931791 0.314432 +vn 0.484359 0.249825 0.838404 +vn 0.420881 -0.539720 0.729026 +vn 0.392712 -0.619098 0.680013 +vn 0.093509 0.931516 0.351451 +vn 0.250160 0.249763 0.935423 +vn 0.217322 -0.538713 0.813959 +vn 0.202887 -0.618030 0.759484 +vn 0.000000 0.931455 0.363842 +vn 0.000000 0.249916 0.968261 +vn 0.000000 -0.538102 0.842860 +vn 0.000031 -0.617206 0.786767 +vn -0.093509 0.931516 0.351451 +vn -0.250130 0.249763 0.935423 +vn -0.217292 -0.538682 0.813959 +vn -0.202857 -0.618000 0.759514 +vn -0.181280 0.931791 0.314432 +vn -0.484359 0.249855 0.838404 +vn -0.420911 -0.539720 0.729026 +vn -0.392743 -0.619068 0.680013 +vn -0.256417 0.931913 0.256386 +vn -0.684652 0.249886 0.684652 +vn -0.595050 -0.540147 0.595050 +vn -0.555040 -0.619526 0.555010 +vn -0.314432 0.931791 0.181280 +vn -0.838404 0.249825 0.484359 +vn -0.729026 -0.539720 0.420881 +vn -0.680013 -0.619098 0.392712 +vn -0.351451 0.931516 0.093509 +vn -0.935423 0.249763 0.250160 +vn -0.813959 -0.538713 0.217292 +vn -0.759484 -0.618030 0.202887 +vn -0.363842 0.931455 0.000000 +vn -0.968261 0.249916 0.000000 +vn -0.842860 -0.538102 0.000000 +vn -0.786767 -0.617206 0.000031 +vn -0.351451 0.931516 -0.093509 +vn -0.935423 0.249763 -0.250130 +vn -0.813959 -0.538713 -0.217292 +vn -0.759514 -0.618000 -0.202857 +vn -0.314432 0.931791 -0.181280 +vn -0.838404 0.249855 -0.484359 +vn -0.729026 -0.539720 -0.420911 +vn -0.680013 -0.619068 -0.392743 +vn -0.256386 0.931913 -0.256417 +vn -0.684652 0.249886 -0.684652 +vn -0.595050 -0.540147 -0.595050 +vn -0.555010 -0.619526 -0.555040 +vn -0.181280 0.931791 -0.314432 +vn -0.484359 0.249825 -0.838404 +vn -0.420881 -0.539720 -0.729026 +vn -0.392712 -0.619098 -0.680013 +vn -0.093509 0.931516 -0.351451 +vn -0.250160 0.249763 -0.935423 +vn -0.217322 -0.538713 -0.813959 +vn -0.202887 -0.618030 -0.759484 +vn 0.000000 0.931455 -0.363842 +vn 0.000000 0.249916 -0.968261 +vn 0.000000 -0.538102 -0.842860 +vn -0.000031 -0.617206 -0.786767 +vn 0.093509 0.931516 -0.351451 +vn 0.250130 0.249763 -0.935423 +vn 0.217292 -0.538682 -0.813959 +vn 0.202857 -0.618000 -0.759514 +vn 0.181280 0.931791 -0.314432 +vn 0.484359 0.249855 -0.838404 +vn 0.420911 -0.539720 -0.729026 +vn 0.392743 -0.619068 -0.680013 +vn 0.256417 0.931913 -0.256386 +vn 0.684652 0.249886 -0.684652 +vn 0.595050 -0.540147 -0.595050 +vn 0.555040 -0.619526 -0.555010 +vn 0.314432 0.931791 -0.181280 +vn 0.838404 0.249825 -0.484359 +vn 0.729026 -0.539720 -0.420881 +vn 0.680013 -0.619098 -0.392712 +vn 0.351451 0.931516 -0.093509 +vn 0.935423 0.249763 -0.250160 +vn 0.813959 -0.538713 -0.217292 +vn 0.759484 -0.618030 -0.202887 +vn -0.354198 0.930296 -0.095187 +vn 0.095187 0.930296 0.354198 +vn 0.354198 0.930296 0.095187 +vn 0.183721 0.930387 0.317179 +vn -0.183721 0.930387 -0.317179 +vn -0.367443 0.930021 0.000000 +vn -0.183721 0.930387 0.317179 +vn 0.367412 0.930021 0.000000 +vn -0.317179 0.930387 0.183721 +vn -0.095187 0.930296 -0.354198 +vn 0.000000 0.930021 -0.367443 +vn -0.354198 0.930296 0.095187 +vn 0.095187 0.930296 -0.354198 +vn 0.000000 0.930021 0.367443 +vn -0.317179 0.930387 -0.183721 +vn 0.317179 0.930387 -0.183721 +vn -0.095187 0.930296 0.354198 +vn 0.317179 0.930387 0.183721 +vn 0.354198 0.930296 -0.095187 +vn 0.183721 0.930387 -0.317179 +vn -0.034730 0.999390 0.000000 +vn 0.033479 0.999390 -0.009003 +vn 0.034730 0.999390 0.000000 +vn 0.009003 0.999390 -0.033479 +vn 0.000000 0.999390 -0.034730 +vn -0.259163 0.930387 0.259163 +vn -0.017335 0.999390 0.029939 +vn 0.947539 0.295083 0.122654 +vn -0.004486 0.999969 0.000000 +vn -0.004151 0.950468 0.310739 +vn -0.003021 0.719291 0.694662 +vn -0.998688 0.050722 0.000000 +vn -0.003143 0.719321 -0.694632 +vn 0.970214 0.213324 -0.114505 +vn -0.136235 0.879482 -0.455947 +vn 0.949858 0.312662 0.000000 +vn 0.055757 -0.017579 -0.998260 +vn 0.201300 -0.540880 -0.816645 +vn 0.974456 -0.186071 -0.125645 +vn 0.988098 -0.096286 0.119938 +vn 0.974456 -0.186041 0.125614 +vn -0.879574 -0.475723 0.000000 +vn -0.873775 -0.472610 -0.114475 +vn 0.988067 -0.096286 -0.119938 +vn 0.295480 -0.855464 -0.425214 +vn -0.976196 -0.174993 -0.127903 +vn -0.971007 -0.205725 0.121677 +vn -0.976196 -0.174963 0.127903 +vn -0.976196 -0.174993 0.127903 +vn 0.896054 -0.372997 0.240699 +vn -0.802667 -0.373638 -0.464827 +vn -0.655812 -0.373852 -0.655812 +vn -0.240699 -0.373028 -0.896023 +vn -0.464827 -0.373638 -0.802667 +vn -0.896023 -0.373028 0.240699 +vn 0.000000 -0.372539 -0.927976 +vn -0.655812 -0.373852 0.655812 +vn 0.240699 -0.373028 0.896023 +vn -0.896023 -0.373028 -0.240699 +vn 0.802667 -0.373638 -0.464827 +vn 0.655812 -0.373882 0.655812 +vn 0.464827 -0.373638 0.802667 +vn -0.464827 -0.373638 0.802667 +vn 0.240699 -0.373028 -0.896023 +vn 0.802667 -0.373638 0.464827 +vn -0.033479 0.999390 0.009003 +vn -0.259163 0.930387 -0.259163 +vn -0.024445 0.999390 -0.024445 +vn -0.029939 0.999390 -0.017335 +vn 0.259163 0.930387 -0.259163 +vn 0.024445 0.999390 -0.024445 +vn 0.017335 0.999390 -0.029939 +vn 0.029939 0.999390 -0.017335 +vn 0.033479 0.999390 0.009003 +vn -0.009003 0.999390 0.033479 +vn 0.000000 0.999390 0.034730 +vn -0.017335 0.999390 -0.029939 +vn 0.259163 0.930387 0.259163 +vn 0.029939 0.999390 0.017335 +vn -0.009003 0.999390 -0.033479 +vn 0.024445 0.999390 0.024445 +vn 0.017335 0.999390 0.029939 +vn 0.009003 0.999390 0.033479 +vn -0.033479 0.999390 -0.009003 +vn -0.024445 0.999390 0.024445 +vn -0.029939 0.999390 0.017335 +vn 0.055757 -0.017579 0.998260 +vn 0.294198 -0.855403 0.426252 +vn 0.201300 -0.540880 0.816614 +s 1 +f 34//1 1243//2 593//3 +f 52//4 27//5 40//6 +f 52//4 40//6 65//7 +f 77//8 52//4 65//7 +f 77//8 65//7 84//9 +f 107//10 77//8 84//9 +f 107//10 84//9 85//11 +f 115//12 107//10 85//11 +f 115//12 85//11 99//13 +f 129//14 115//12 99//13 +f 129//14 99//13 128//15 +f 1252//16 36//17 40//6 +f 65//7 40//6 64//18 +f 65//7 64//18 58//19 +f 84//9 65//7 58//19 +f 84//9 58//19 59//20 +f 85//11 84//9 59//20 +f 85//11 59//20 70//21 +f 99//13 85//11 70//21 +f 99//13 70//21 98//22 +f 128//15 99//13 98//22 +f 128//15 98//22 114//23 +f 1244//24 33//25 64//18 +f 58//19 64//18 33//25 +f 58//19 33//25 35//26 +f 59//20 58//19 35//26 +f 59//20 35//26 45//27 +f 70//21 59//20 45//27 +f 70//21 45//27 69//28 +f 98//22 70//21 69//28 +f 98//22 69//28 83//29 +f 114//23 98//22 83//29 +f 114//23 83//29 113//30 +f 553//31 1//32 566//33 +f 35//26 33//25 20//34 +f 35//26 20//34 24//35 +f 45//27 35//26 24//35 +f 45//27 24//35 44//36 +f 69//28 45//27 44//36 +f 69//28 44//36 57//37 +f 83//29 69//28 57//37 +f 83//29 57//37 82//38 +f 113//30 83//29 82//38 +f 113//30 82//38 112//39 +f 566//33 1283//40 9//41 +f 24//35 20//34 18//42 +f 24//35 18//42 23//43 +f 44//36 24//35 23//43 +f 44//36 23//43 32//44 +f 57//37 44//36 32//44 +f 57//37 32//44 56//45 +f 82//38 57//37 56//45 +f 82//38 56//45 81//46 +f 112//39 82//38 81//46 +f 112//39 81//46 111//47 +f 4//48 8//49 1250//50 +f 23//43 18//42 8//49 +f 23//43 8//49 17//51 +f 32//44 23//43 17//51 +f 32//44 17//51 31//52 +f 56//45 32//44 31//52 +f 56//45 31//52 55//53 +f 81//46 56//45 55//53 +f 81//46 55//53 80//54 +f 111//47 81//46 80//54 +f 111//47 80//54 110//55 +f 565//56 592//57 1233//58 +f 17//51 8//49 4//48 +f 17//51 4//48 16//59 +f 31//52 17//51 16//59 +f 31//52 16//59 30//60 +f 55//53 31//52 30//60 +f 55//53 30//60 54//61 +f 80//54 55//53 54//61 +f 80//54 54//61 79//62 +f 110//55 80//54 79//62 +f 110//55 79//62 109//63 +f 1//32 565//56 2//64 +f 6//65 2//64 565//56 +f 16//59 4//48 7//66 +f 16//59 7//66 22//67 +f 30//60 16//59 22//67 +f 30//60 22//67 43//68 +f 54//61 30//60 43//68 +f 54//61 43//68 68//69 +f 79//62 54//61 68//69 +f 79//62 68//69 97//70 +f 109//63 79//62 97//70 +f 109//63 97//70 127//71 +f 565//56 1233//58 1249//58 +f 13//72 14//73 5//74 +f 22//67 7//66 15//75 +f 22//67 15//75 29//76 +f 43//68 22//67 29//76 +f 43//68 29//76 42//77 +f 68//69 43//68 42//77 +f 68//69 42//77 67//78 +f 97//70 68//69 67//78 +f 97//70 67//78 96//79 +f 127//71 97//70 96//79 +f 127//71 96//79 126//80 +f 11//81 15//75 1240//82 +f 1289//83 34//1 593//3 +f 29//76 15//75 14//73 +f 29//76 14//73 21//84 +f 42//77 29//76 21//84 +f 42//77 21//84 41//85 +f 67//78 42//77 41//85 +f 67//78 41//85 66//86 +f 96//79 67//78 66//86 +f 96//79 66//86 95//87 +f 126//80 96//79 95//87 +f 126//80 95//87 125//88 +f 636//89 1243//2 26//2 +f 636//89 26//2 592//57 +f 21//84 14//73 13//72 +f 21//84 13//72 28//90 +f 41//85 21//84 28//90 +f 41//85 28//90 53//91 +f 66//86 41//85 53//91 +f 66//86 53//91 78//92 +f 95//87 66//86 78//92 +f 95//87 78//92 108//93 +f 125//88 95//87 108//93 +f 125//88 108//93 136//94 +f 12//95 13//72 5//74 +f 28//90 13//72 27//5 +f 28//90 27//5 52//4 +f 53//91 28//90 52//4 +f 53//91 52//4 77//8 +f 78//92 53//91 77//8 +f 78//92 77//8 107//10 +f 108//93 78//92 107//10 +f 108//93 107//10 115//12 +f 136//94 108//93 115//12 +f 136//94 115//12 129//14 +f 148//96 129//14 128//15 +f 148//96 128//15 143//97 +f 121//98 148//96 143//97 +f 121//98 143//97 122//99 +f 92//100 121//98 122//99 +f 92//100 122//99 93//101 +f 62//102 92//100 93//101 +f 62//102 93//101 63//103 +f 39//104 62//102 63//103 +f 39//104 63//103 51//105 +f 10//106 39//104 51//105 +f 10//106 51//105 49//107 +f 143//97 128//15 114//23 +f 143//97 114//23 142//108 +f 122//99 143//97 142//108 +f 122//99 142//108 123//109 +f 93//101 122//99 123//109 +f 93//101 123//109 94//110 +f 63//103 93//101 94//110 +f 63//103 94//110 76//111 +f 51//105 63//103 76//111 +f 51//105 76//111 75//112 +f 49//107 51//105 75//112 +f 49//107 75//112 61//113 +f 142//108 114//23 113//30 +f 142//108 113//30 141//114 +f 123//109 142//108 141//114 +f 123//109 141//114 124//115 +f 94//110 123//109 124//115 +f 94//110 124//115 106//116 +f 76//111 94//110 106//116 +f 76//111 106//116 105//117 +f 75//112 76//111 105//117 +f 75//112 105//117 91//118 +f 61//113 75//112 91//118 +f 61//113 91//118 90//119 +f 141//114 113//30 112//39 +f 141//114 112//39 140//120 +f 124//115 141//114 140//120 +f 124//115 140//120 135//121 +f 106//116 124//115 135//121 +f 106//116 135//121 134//122 +f 105//117 106//116 134//122 +f 105//117 134//122 120//123 +f 91//118 105//117 120//123 +f 91//118 120//123 119//124 +f 90//119 91//118 119//124 +f 140//120 112//39 111//47 +f 140//120 111//47 139//125 +f 135//121 140//120 139//125 +f 135//121 139//125 155//126 +f 134//122 135//121 155//126 +f 134//122 155//126 147//127 +f 120//123 134//122 147//127 +f 120//123 147//127 144//128 +f 119//124 120//123 144//128 +f 119//124 144//128 116//129 +f 26//2 1234//130 592//57 +f 139//125 111//47 110//55 +f 139//125 110//55 138//131 +f 155//126 139//125 138//131 +f 155//126 138//131 156//132 +f 147//127 155//126 156//132 +f 147//127 156//132 145//133 +f 144//128 147//127 145//133 +f 144//128 145//133 117//134 +f 116//129 144//128 117//134 +f 116//129 117//134 88//135 +f 27//5 13//72 12//95 +f 1242//136 88//135 71//137 +f 138//131 110//55 109//63 +f 138//131 109//63 137//138 +f 156//132 138//131 137//138 +f 156//132 137//138 154//139 +f 145//133 156//132 154//139 +f 145//133 154//139 131//140 +f 117//134 145//133 131//140 +f 117//134 131//140 101//141 +f 88//135 117//134 101//141 +f 88//135 101//141 86//142 +f 60//143 74//144 1248//145 +f 137//138 109//63 127//71 +f 137//138 127//71 151//146 +f 154//139 137//138 151//146 +f 154//139 151//146 153//147 +f 131//140 154//139 153//147 +f 131//140 153//147 130//148 +f 101//141 131//140 130//148 +f 101//141 130//148 100//149 +f 86//142 101//141 100//149 +f 86//142 100//149 74//144 +f 47//150 1235//151 631//152 +f 74//144 48//153 1248//145 +f 151//146 127//71 126//80 +f 151//146 126//80 150//154 +f 153//147 151//146 150//154 +f 153//147 150//154 146//155 +f 130//148 153//147 146//155 +f 130//148 146//155 118//156 +f 100//149 130//148 118//156 +f 100//149 118//156 89//157 +f 74//144 100//149 89//157 +f 74//144 89//157 48//153 +f 1247//158 87//159 715//160 +f 104//161 116//129 1242//136 +f 150//154 126//80 125//88 +f 150//154 125//88 149//162 +f 146//155 150//154 149//162 +f 146//155 149//162 132//163 +f 118//156 146//155 132//163 +f 118//156 132//163 102//164 +f 89//157 118//156 102//164 +f 89//157 102//164 72//165 +f 48//153 89//157 72//165 +f 48//153 72//165 46//166 +f 37//167 48//153 46//166 +f 37//167 46//166 38//168 +f 149//162 125//88 136//94 +f 149//162 136//94 152//169 +f 132//163 149//162 152//169 +f 132//163 152//169 133//170 +f 102//164 132//163 133//170 +f 102//164 133//170 103//171 +f 72//165 102//164 103//171 +f 72//165 103//171 73//172 +f 46//166 72//165 73//172 +f 46//166 73//172 50//173 +f 38//168 46//166 50//173 +f 38//168 50//173 25//174 +f 152//169 136//94 129//14 +f 152//169 129//14 148//96 +f 133//170 152//169 148//96 +f 133//170 148//96 121//98 +f 103//171 133//170 121//98 +f 103//171 121//98 92//100 +f 73//172 103//171 92//100 +f 73//172 92//100 62//102 +f 50//173 73//172 62//102 +f 50//173 62//102 39//104 +f 25//174 50//173 39//104 +f 39//104 10//106 25//174 +f 539//175 509//176 159//177 +f 160//178 158//179 157//180 +f 166//181 160//178 163//182 +f 166//181 163//182 173//183 +f 177//184 166//181 173//183 +f 177//184 173//183 183//185 +f 189//186 177//184 183//185 +f 189//186 183//185 197//187 +f 205//188 189//186 197//187 +f 205//188 197//187 216//189 +f 225//190 205//188 216//189 +f 225//190 216//189 235//191 +f 173//183 163//182 172//192 +f 173//183 172//192 184//193 +f 183//185 173//183 184//193 +f 183//185 184//193 198//194 +f 197//187 183//185 198//194 +f 197//187 198//194 217//195 +f 216//189 197//187 217//195 +f 216//189 217//195 236//196 +f 235//191 216//189 236//196 +f 235//191 236//196 253//197 +f 182//198 172//192 1254//199 +f 1255//200 167//201 595//202 +f 184//193 172//192 182//198 +f 184//193 182//198 196//203 +f 198//194 184//193 196//203 +f 198//194 196//203 214//204 +f 217//195 198//194 214//204 +f 217//195 214//204 232//205 +f 236//196 217//195 232//205 +f 236//196 232//205 250//206 +f 253//197 236//196 250//206 +f 253//197 250//206 267//207 +f 196//203 182//198 199//208 +f 196//203 199//208 215//209 +f 214//204 196//203 215//209 +f 214//204 215//209 233//210 +f 232//205 214//204 233//210 +f 232//205 233//210 251//211 +f 250//206 232//205 251//211 +f 250//206 251//211 257//212 +f 267//207 250//206 257//212 +f 267//207 257//212 256//213 +f 215//209 199//208 218//214 +f 215//209 218//214 234//215 +f 233//210 215//209 234//215 +f 233//210 234//215 241//216 +f 251//211 233//210 241//216 +f 251//211 241//216 240//217 +f 257//212 251//211 240//217 +f 257//212 240//217 239//218 +f 256//213 257//212 239//218 +f 256//213 239//218 238//219 +f 234//215 218//214 219//220 +f 234//215 219//220 224//221 +f 241//216 234//215 224//221 +f 241//216 224//221 223//222 +f 240//217 241//216 223//222 +f 240//217 223//222 222//223 +f 239//218 240//217 222//223 +f 239//218 222//223 221//224 +f 238//219 239//218 221//224 +f 238//219 221//224 220//225 +f 219//220 218//214 1285//226 +f 648//227 691//228 207//229 +f 224//221 219//220 208//230 +f 224//221 208//230 204//231 +f 223//222 224//221 204//231 +f 223//222 204//231 203//232 +f 222//223 223//222 203//232 +f 222//223 203//232 202//233 +f 221//224 222//223 202//233 +f 221//224 202//233 201//234 +f 220//225 221//224 201//234 +f 220//225 201//234 212//235 +f 204//231 208//230 191//236 +f 204//231 191//236 188//237 +f 203//232 204//231 188//237 +f 203//232 188//237 187//238 +f 202//233 203//232 187//238 +f 202//233 187//238 186//239 +f 201//234 202//233 186//239 +f 201//234 186//239 194//240 +f 212//235 201//234 194//240 +f 212//235 194//240 211//241 +f 188//237 191//236 174//242 +f 188//237 174//242 176//243 +f 187//238 188//237 176//243 +f 187//238 176//243 175//244 +f 186//239 187//238 175//244 +f 186//239 175//244 180//245 +f 194//240 186//239 180//245 +f 194//240 180//245 193//246 +f 211//241 194//240 193//246 +f 211//241 193//246 210//247 +f 613//248 585//249 1258//250 +f 176//243 174//242 168//251 +f 176//243 168//251 165//252 +f 175//244 176//243 165//252 +f 175//244 165//252 170//253 +f 180//245 175//244 170//253 +f 180//245 170//253 179//254 +f 193//246 180//245 179//254 +f 193//246 179//254 192//255 +f 210//247 193//246 192//255 +f 210//247 192//255 209//256 +f 168//251 174//242 164//257 +f 165//252 168//251 161//258 +f 165//252 161//258 162//259 +f 170//253 165//252 162//259 +f 170//253 162//259 171//260 +f 179//254 170//253 171//260 +f 179//254 171//260 181//261 +f 192//255 179//254 181//261 +f 192//255 181//261 195//262 +f 209//256 192//255 195//262 +f 209//256 195//262 213//263 +f 160//178 161//258 158//179 +f 161//258 160//178 162//259 +f 162//259 160//178 166//181 +f 171//260 162//259 166//181 +f 171//260 166//181 177//184 +f 181//261 171//260 177//184 +f 181//261 177//184 189//186 +f 195//262 181//261 189//186 +f 195//262 189//186 205//188 +f 213//263 195//262 205//188 +f 213//263 205//188 225//190 +f 242//264 225//190 235//191 +f 242//264 235//191 252//265 +f 258//266 242//264 252//265 +f 258//266 252//265 268//267 +f 273//268 258//266 268//267 +f 273//268 268//267 283//269 +f 287//270 273//268 283//269 +f 287//270 283//269 298//271 +f 300//272 287//270 298//271 +f 300//272 298//271 299//273 +f 312//274 300//272 299//273 +f 312//274 299//273 310//275 +f 252//265 235//191 253//197 +f 252//265 253//197 269//276 +f 268//267 252//265 269//276 +f 268//267 269//276 284//277 +f 283//269 268//267 284//277 +f 283//269 284//277 286//278 +f 298//271 283//269 286//278 +f 298//271 286//278 285//279 +f 299//273 298//271 285//279 +f 299//273 285//279 296//280 +f 310//275 299//273 296//280 +f 310//275 296//280 309//281 +f 269//276 253//197 267//207 +f 269//276 267//207 272//282 +f 284//277 269//276 272//282 +f 284//277 272//282 271//283 +f 286//278 284//277 271//283 +f 286//278 271//283 270//284 +f 285//279 286//278 270//284 +f 285//279 270//284 281//285 +f 296//280 285//279 281//285 +f 296//280 281//285 295//286 +f 309//281 296//280 295//286 +f 309//281 295//286 308//287 +f 272//282 267//207 256//213 +f 272//282 256//213 255//288 +f 271//283 272//282 255//288 +f 271//283 255//288 254//289 +f 270//284 271//283 254//289 +f 270//284 254//289 265//290 +f 281//285 270//284 265//290 +f 281//285 265//290 280//291 +f 295//286 281//285 280//291 +f 295//286 280//291 294//292 +f 308//287 295//286 294//292 +f 308//287 294//292 307//293 +f 255//288 256//213 238//219 +f 255//288 238//219 237//294 +f 254//289 255//288 237//294 +f 254//289 237//294 248//295 +f 265//290 254//289 248//295 +f 265//290 248//295 264//296 +f 280//291 265//290 264//296 +f 280//291 264//296 279//297 +f 294//292 280//291 279//297 +f 294//292 279//297 293//298 +f 307//293 294//292 293//298 +f 307//293 293//298 306//299 +f 237//294 238//219 220//225 +f 237//294 220//225 230//300 +f 248//295 237//294 230//300 +f 248//295 230//300 247//301 +f 264//296 248//295 247//301 +f 264//296 247//301 263//302 +f 279//297 264//296 263//302 +f 279//297 263//302 278//303 +f 293//298 279//297 278//303 +f 293//298 278//303 292//304 +f 306//299 293//298 292//304 +f 306//299 292//304 305//305 +f 230//300 220//225 212//235 +f 230//300 212//235 229//306 +f 247//301 230//300 229//306 +f 247//301 229//306 246//307 +f 263//302 247//301 246//307 +f 263//302 246//307 262//308 +f 278//303 263//302 262//308 +f 278//303 262//308 277//309 +f 292//304 278//303 277//309 +f 292//304 277//309 291//310 +f 305//305 292//304 291//310 +f 305//305 291//310 304//311 +f 229//306 212//235 211//241 +f 229//306 211//241 228//312 +f 246//307 229//306 228//312 +f 246//307 228//312 245//313 +f 262//308 246//307 245//313 +f 262//308 245//313 261//314 +f 277//309 262//308 261//314 +f 277//309 261//314 276//315 +f 291//310 277//309 276//315 +f 291//310 276//315 290//316 +f 304//311 291//310 290//316 +f 304//311 290//316 303//317 +f 228//312 211//241 210//247 +f 228//312 210//247 227//318 +f 245//313 228//312 227//318 +f 245//313 227//318 244//319 +f 261//314 245//313 244//319 +f 261//314 244//319 260//320 +f 276//315 261//314 260//320 +f 276//315 260//320 275//321 +f 290//316 276//315 275//321 +f 290//316 275//321 289//322 +f 303//317 290//316 289//322 +f 303//317 289//322 302//323 +f 227//318 210//247 209//256 +f 227//318 209//256 226//324 +f 244//319 227//318 226//324 +f 244//319 226//324 243//325 +f 260//320 244//319 243//325 +f 260//320 243//325 259//326 +f 275//321 260//320 259//326 +f 275//321 259//326 274//327 +f 289//322 275//321 274//327 +f 289//322 274//327 288//328 +f 302//323 289//322 288//328 +f 302//323 288//328 301//329 +f 226//324 209//256 213//263 +f 226//324 213//263 231//330 +f 243//325 226//324 231//330 +f 243//325 231//330 249//331 +f 259//326 243//325 249//331 +f 259//326 249//331 266//332 +f 274//327 259//326 266//332 +f 274//327 266//332 282//333 +f 288//328 274//327 282//333 +f 288//328 282//333 297//334 +f 301//329 288//328 297//334 +f 301//329 297//334 311//335 +f 231//330 213//263 225//190 +f 231//330 225//190 242//264 +f 249//331 231//330 242//264 +f 249//331 242//264 258//266 +f 266//332 249//331 258//266 +f 266//332 258//266 273//268 +f 282//333 266//332 273//268 +f 282//333 273//268 287//270 +f 297//334 282//333 287//270 +f 297//334 287//270 300//272 +f 311//335 297//334 300//272 +f 311//335 300//272 312//274 +f 312//274 310//275 323//336 +f 302//323 315//337 316//338 +f 304//311 317//339 318//340 +f 303//317 316//338 317//339 +f 309//281 308//287 321//341 +f 307//293 306//299 319//342 +f 311//335 313//343 314//344 +f 301//329 314//344 315//337 +f 312//274 324//345 313//343 +f 306//299 305//305 318//340 +f 308//287 307//293 320//346 +f 310//275 309//281 322//347 +f 322//347 321//341 325//348 +f 314//344 313//343 325//348 +f 323//336 322//347 325//348 +f 319//342 318//340 325//348 +f 315//337 314//344 325//348 +f 321//341 320//346 325//348 +f 324//345 323//336 325//348 +f 320//346 319//342 325//348 +f 317//339 316//338 325//348 +f 316//338 315//337 325//348 +f 313//343 324//345 325//348 +f 318//340 317//339 325//348 +f 326//349 327//350 328//351 +f 326//349 328//351 329//352 +f 333//353 326//349 329//352 +f 333//353 329//352 338//354 +f 347//355 333//353 338//354 +f 347//355 338//354 354//356 +f 364//357 347//355 354//356 +f 364//357 354//356 374//358 +f 386//359 364//357 374//358 +f 386//359 374//358 398//360 +f 412//361 386//359 398//360 +f 412//361 398//360 429//362 +f 329//352 328//351 334//363 +f 329//352 334//363 339//364 +f 338//354 329//352 339//364 +f 338//354 339//364 355//365 +f 354//356 338//354 355//365 +f 354//356 355//365 375//366 +f 374//358 354//356 375//366 +f 374//358 375//366 399//367 +f 398//360 374//358 399//367 +f 398//360 399//367 430//368 +f 429//362 398//360 430//368 +f 429//362 430//368 464//369 +f 339//364 334//363 342//370 +f 339//364 342//370 356//371 +f 355//365 339//364 356//371 +f 355//365 356//371 376//372 +f 375//366 355//365 376//372 +f 375//366 376//372 400//373 +f 399//367 375//366 400//373 +f 399//367 400//373 431//374 +f 430//368 399//367 431//374 +f 430//368 431//374 465//375 +f 464//369 430//368 465//375 +f 464//369 465//375 497//376 +f 356//371 342//370 351//377 +f 356//371 351//377 370//378 +f 376//372 356//371 370//378 +f 376//372 370//378 393//379 +f 400//373 376//372 393//379 +f 400//373 393//379 422//380 +f 431//374 400//373 422//380 +f 431//374 422//380 457//381 +f 465//375 431//374 457//381 +f 465//375 457//381 490//382 +f 497//376 465//375 490//382 +f 497//376 490//382 521//383 +f 370//378 351//377 361//384 +f 370//378 361//384 382//385 +f 393//379 370//378 382//385 +f 393//379 382//385 408//386 +f 422//380 393//379 408//386 +f 422//380 408//386 439//387 +f 457//381 422//380 439//387 +f 457//381 439//387 473//388 +f 490//382 457//381 473//388 +f 490//382 473//388 504//389 +f 521//383 490//382 504//389 +f 521//383 504//389 535//390 +f 382//385 361//384 369//391 +f 382//385 369//391 392//392 +f 408//386 382//385 392//392 +f 408//386 392//392 421//393 +f 439//387 408//386 421//393 +f 439//387 421//393 456//394 +f 473//388 439//387 456//394 +f 473//388 456//394 489//395 +f 504//389 473//388 489//395 +f 504//389 489//395 520//396 +f 535//390 504//389 520//396 +f 535//390 520//396 550//397 +f 392//392 369//391 380//398 +f 392//392 380//398 407//399 +f 421//393 392//392 407//399 +f 421//393 407//399 438//400 +f 456//394 421//393 438//400 +f 456//394 438//400 472//401 +f 489//395 456//394 472//401 +f 489//395 472//401 503//402 +f 520//396 489//395 503//402 +f 520//396 503//402 534//403 +f 550//397 520//396 534//403 +f 550//397 534//403 563//404 +f 407//399 380//398 391//405 +f 407//399 391//405 420//406 +f 438//400 407//399 420//406 +f 438//400 420//406 455//407 +f 472//401 438//400 455//407 +f 472//401 455//407 488//408 +f 503//402 472//401 488//408 +f 503//402 488//408 519//409 +f 534//403 503//402 519//409 +f 534//403 519//409 549//410 +f 563//404 534//403 549//410 +f 563//404 549//410 578//411 +f 420//406 391//405 404//412 +f 420//406 404//412 437//413 +f 455//407 420//406 437//413 +f 455//407 437//413 471//414 +f 488//408 455//407 471//414 +f 488//408 471//414 502//415 +f 519//409 488//408 502//415 +f 519//409 502//415 533//416 +f 549//410 519//409 533//416 +f 549//410 533//416 562//417 +f 578//411 549//410 562//417 +f 578//411 562//417 589//418 +f 437//413 404//412 419//419 +f 437//413 419//419 454//420 +f 471//414 437//413 454//420 +f 471//414 454//420 487//421 +f 502//415 471//414 487//421 +f 502//415 487//421 518//422 +f 533//416 502//415 518//422 +f 533//416 518//422 548//423 +f 562//417 533//416 548//423 +f 562//417 548//423 577//424 +f 589//418 562//417 577//424 +f 589//418 577//424 594//425 +f 454//420 419//419 436//426 +f 454//420 436//426 470//427 +f 487//421 454//420 470//427 +f 487//421 470//427 501//428 +f 518//422 487//421 501//428 +f 518//422 501//428 532//429 +f 548//423 518//422 532//429 +f 548//423 532//429 555//430 +f 577//424 548//423 555//430 +f 577//424 555//430 567//431 +f 594//425 577//424 567//431 +f 594//425 567//431 582//432 +f 470//427 436//426 453//433 +f 470//427 453//433 486//434 +f 501//428 470//427 486//434 +f 501//428 486//434 508//435 +f 532//429 501//428 508//435 +f 532//429 508//435 525//436 +f 555//430 532//429 525//436 +f 555//430 525//436 538//437 +f 567//431 555//430 538//437 +f 567//431 538//437 554//438 +f 582//432 567//431 554//438 +f 582//432 554//438 566//33 +f 486//434 453//433 462//439 +f 486//434 462//439 477//440 +f 508//435 486//434 477//440 +f 508//435 477//440 494//441 +f 525//436 508//435 494//441 +f 525//436 494//441 507//442 +f 538//437 525//436 507//442 +f 538//437 507//442 524//443 +f 554//438 538//437 524//443 +f 554//438 524//443 537//444 +f 566//33 554//438 537//444 +f 566//33 537//444 553//31 +f 477//440 462//439 443//445 +f 477//440 443//445 461//446 +f 494//441 477//440 461//446 +f 494//441 461//446 476//447 +f 507//442 494//441 476//447 +f 507//442 476//447 493//448 +f 524//443 507//442 493//448 +f 524//443 493//448 506//449 +f 537//444 524//443 506//449 +f 537//444 506//449 523//450 +f 553//31 537//444 523//450 +f 553//31 523//450 536//451 +f 461//446 443//445 426//452 +f 461//446 426//452 442//453 +f 476//447 461//446 442//453 +f 476//447 442//453 460//454 +f 493//448 476//447 460//454 +f 493//448 460//454 475//455 +f 506//449 493//448 475//455 +f 506//449 475//455 492//456 +f 523//450 506//449 492//456 +f 523//450 492//456 505//457 +f 536//451 523//450 505//457 +f 536//451 505//457 522//458 +f 442//453 426//452 411//459 +f 442//453 411//459 425//460 +f 460//454 442//453 425//460 +f 460//454 425//460 441//461 +f 475//455 460//454 441//461 +f 475//455 441//461 459//462 +f 492//456 475//455 459//462 +f 492//456 459//462 474//463 +f 505//457 492//456 474//463 +f 505//457 474//463 491//464 +f 522//458 505//457 491//464 +f 522//458 491//464 499//465 +f 425//460 411//459 396//466 +f 425//460 396//466 410//467 +f 441//461 425//460 410//467 +f 441//461 410//467 424//468 +f 459//462 441//461 424//468 +f 459//462 424//468 440//469 +f 474//463 459//462 440//469 +f 474//463 440//469 458//470 +f 491//464 474//463 458//470 +f 491//464 458//470 467//471 +f 499//465 491//464 467//471 +f 499//465 467//471 466//472 +f 410//467 396//466 385//473 +f 410//467 385//473 395//474 +f 424//468 410//467 395//474 +f 424//468 395//474 409//475 +f 440//469 424//468 409//475 +f 440//469 409//475 423//476 +f 458//470 440//469 423//476 +f 458//470 423//476 433//477 +f 467//471 458//470 433//477 +f 467//471 433//477 432//478 +f 466//472 467//471 432//478 +f 466//472 432//478 434//479 +f 395//474 385//473 372//480 +f 395//474 372//480 383//481 +f 409//475 395//474 383//481 +f 409//475 383//481 394//482 +f 423//476 409//475 394//482 +f 423//476 394//482 402//483 +f 433//477 423//476 402//483 +f 433//477 402//483 401//484 +f 432//478 433//477 401//484 +f 432//478 401//484 403//485 +f 434//479 432//478 403//485 +f 434//479 403//485 417//486 +f 383//481 372//480 362//487 +f 383//481 362//487 371//488 +f 394//482 383//481 371//488 +f 394//482 371//488 378//489 +f 402//483 394//482 378//489 +f 402//483 378//489 377//490 +f 401//484 402//483 377//490 +f 401//484 377//490 379//491 +f 403//485 401//484 379//491 +f 403//485 379//491 390//492 +f 417//486 403//485 390//492 +f 417//486 390//492 416//493 +f 371//488 362//487 352//494 +f 371//488 352//494 358//495 +f 378//489 371//488 358//495 +f 378//489 358//495 357//496 +f 377//490 378//489 357//496 +f 377//490 357//496 359//497 +f 379//491 377//490 359//497 +f 379//491 359//497 367//498 +f 390//492 379//491 367//498 +f 390//492 367//498 389//499 +f 416//493 390//492 389//499 +f 416//493 389//499 415//500 +f 358//495 352//494 345//501 +f 358//495 345//501 340//502 +f 357//496 358//495 340//502 +f 357//496 340//502 341//503 +f 359//497 357//496 341//503 +f 359//497 341//503 349//504 +f 367//498 359//497 349//504 +f 367//498 349//504 366//505 +f 389//499 367//498 366//505 +f 389//499 366//505 388//506 +f 415//500 389//499 388//506 +f 415//500 388//506 414//507 +f 340//502 345//501 335//508 +f 340//502 335//508 330//509 +f 341//503 340//502 330//509 +f 341//503 330//509 336//510 +f 349//504 341//503 336//510 +f 349//504 336//510 348//511 +f 366//505 349//504 348//511 +f 366//505 348//511 365//512 +f 388//506 366//505 365//512 +f 388//506 365//512 387//513 +f 414//507 388//506 387//513 +f 414//507 387//513 413//514 +f 330//509 335//508 327//350 +f 327//350 326//349 330//509 +f 330//509 326//349 336//510 +f 336//510 326//349 333//353 +f 348//511 336//510 333//353 +f 348//511 333//353 347//355 +f 365//512 348//511 347//355 +f 365//512 347//355 364//357 +f 387//513 365//512 364//357 +f 387//513 364//357 386//359 +f 413//514 387//513 386//359 +f 413//514 386//359 412//361 +f 445//515 412//361 429//362 +f 445//515 429//362 463//516 +f 478//517 445//515 463//516 +f 478//517 463//516 495//518 +f 509//176 478//517 495//518 +f 509//176 495//518 526//519 +f 463//516 429//362 464//369 +f 463//516 464//369 496//520 +f 495//518 463//516 496//520 +f 495//518 496//520 527//521 +f 526//519 495//518 527//521 +f 526//519 527//521 557//522 +f 556//523 526//519 557//522 +f 556//523 557//522 583//524 +f 595//202 556//523 583//524 +f 595//202 583//524 611//525 +f 621//526 595//202 611//525 +f 621//526 611//525 638//527 +f 496//520 464//369 497//376 +f 496//520 497//376 528//528 +f 527//521 496//520 528//528 +f 527//521 528//528 558//529 +f 557//522 527//521 558//529 +f 557//522 558//529 584//530 +f 583//524 557//522 584//530 +f 583//524 584//530 612//531 +f 611//525 583//524 612//531 +f 611//525 612//531 639//532 +f 638//527 611//525 639//532 +f 638//527 639//532 664//533 +f 528//528 497//376 521//383 +f 528//528 521//383 551//534 +f 558//529 528//528 551//534 +f 558//529 551//534 580//535 +f 584//530 558//529 580//535 +f 584//530 580//535 608//536 +f 612//531 584//530 608//536 +f 612//531 608//536 634//537 +f 639//532 612//531 634//537 +f 639//532 634//537 661//538 +f 664//533 639//532 661//538 +f 664//533 661//538 688//539 +f 551//534 521//383 535//390 +f 551//534 535//390 564//540 +f 580//535 551//534 564//540 +f 580//535 564//540 591//541 +f 608//536 580//535 591//541 +f 608//536 591//541 618//542 +f 634//537 608//536 618//542 +f 634//537 618//542 644//543 +f 661//538 634//537 644//543 +f 661//538 644//543 670//544 +f 688//539 661//538 670//544 +f 688//539 670//544 698//545 +f 564//540 535//390 550//397 +f 564//540 550//397 579//546 +f 591//541 564//540 579//546 +f 591//541 579//546 607//547 +f 618//542 591//541 607//547 +f 618//542 607//547 633//548 +f 644//543 618//542 633//548 +f 644//543 633//548 660//549 +f 670//544 644//543 660//549 +f 670//544 660//549 687//550 +f 698//545 670//544 687//550 +f 698//545 687//550 717//551 +f 579//546 550//397 563//404 +f 579//546 563//404 590//552 +f 607//547 579//546 590//552 +f 607//547 590//552 617//553 +f 633//548 607//547 617//553 +f 633//548 617//553 643//554 +f 660//549 633//548 643//554 +f 660//549 643//554 669//555 +f 687//550 660//549 669//555 +f 687//550 669//555 697//556 +f 717//551 687//550 697//556 +f 717//551 697//556 727//557 +f 590//552 563//404 578//411 +f 590//552 578//411 606//558 +f 617//553 590//552 606//558 +f 617//553 606//558 632//559 +f 643//554 617//553 632//559 +f 643//554 632//559 659//560 +f 669//555 643//554 659//560 +f 669//555 659//560 673//561 +f 697//556 669//555 673//561 +f 697//556 673//561 700//562 +f 727//557 697//556 700//562 +f 727//557 700//562 699//563 +f 606//558 578//411 589//418 +f 606//558 589//418 616//564 +f 632//559 606//558 616//564 +f 632//559 616//564 637//565 +f 659//560 632//559 637//565 +f 659//560 637//565 647//566 +f 673//561 659//560 647//566 +f 673//561 647//566 672//567 +f 700//562 673//561 672//567 +f 700//562 672//567 671//568 +f 699//563 700//562 671//568 +f 699//563 671//568 689//569 +f 616//564 589//418 594//425 +f 616//564 594//425 610//570 +f 637//565 616//564 610//570 +f 637//565 610//570 620//571 +f 647//566 637//565 620//571 +f 647//566 620//571 646//572 +f 672//567 647//566 646//572 +f 672//567 646//572 645//573 +f 671//568 672//567 645//573 +f 671//568 645//573 662//574 +f 689//569 671//568 662//574 +f 689//569 662//574 668//575 +f 610//570 594//425 582//432 +f 610//570 582//432 593//3 +f 620//571 610//570 593//3 +f 620//571 593//3 636//89 +f 646//572 620//571 636//89 +f 646//572 636//89 619//576 +f 645//573 646//572 619//576 +f 645//573 619//576 635//577 +f 662//574 645//573 635//577 +f 662//574 635//577 642//578 +f 668//575 662//574 642//578 +f 668//575 642//578 641//579 +f 593//3 582//432 566//33 +f 619//576 636//89 592//57 +f 619//576 592//57 609//580 +f 635//577 619//576 609//580 +f 635//577 609//580 615//581 +f 642//578 635//577 615//581 +f 642//578 615//581 614//582 +f 641//579 642//578 614//582 +f 592//57 565//56 581//583 +f 609//580 592//57 581//583 +f 609//580 581//583 587//584 +f 615//581 609//580 587//584 +f 615//581 587//584 586//585 +f 614//582 615//581 586//585 +f 614//582 586//585 588//586 +f 565//56 553//31 536//451 +f 565//56 536//451 552//587 +f 581//583 565//56 552//587 +f 581//583 552//587 560//588 +f 587//584 581//583 560//588 +f 587//584 560//588 559//589 +f 586//585 587//584 559//589 +f 586//585 559//589 561//590 +f 588//586 586//585 561//590 +f 588//586 561//590 576//591 +f 605//592 588//586 576//591 +f 605//592 576//591 604//593 +f 552//587 536//451 522//458 +f 552//587 522//458 530//594 +f 560//588 552//587 530//594 +f 560//588 530//594 529//595 +f 559//589 560//588 529//595 +f 559//589 529//595 531//596 +f 561//590 559//589 531//596 +f 561//590 531//596 547//597 +f 576//591 561//590 547//597 +f 576//591 547//597 575//598 +f 604//593 576//591 575//598 +f 604//593 575//598 603//599 +f 530//594 522//458 499//465 +f 530//594 499//465 498//600 +f 529//595 530//594 498//600 +f 529//595 498//600 500//601 +f 531//596 529//595 500//601 +f 531//596 500//601 517//602 +f 547//597 531//596 517//602 +f 547//597 517//602 546//603 +f 575//598 547//597 546//603 +f 575//598 546//603 574//604 +f 603//599 575//598 574//604 +f 603//599 574//604 602//605 +f 498//600 499//465 466//472 +f 498//600 466//472 468//606 +f 500//601 498//600 468//606 +f 500//601 468//606 485//607 +f 517//602 500//601 485//607 +f 517//602 485//607 516//608 +f 546//603 517//602 516//608 +f 546//603 516//608 545//609 +f 574//604 546//603 545//609 +f 574//604 545//609 573//610 +f 602//605 574//604 573//610 +f 602//605 573//610 601//611 +f 468//606 466//472 434//479 +f 468//606 434//479 451//612 +f 485//607 468//606 451//612 +f 485//607 451//612 484//613 +f 516//608 485//607 484//613 +f 516//608 484//613 515//614 +f 545//609 516//608 515//614 +f 545//609 515//614 544//615 +f 573//610 545//609 544//615 +f 573//610 544//615 572//616 +f 601//611 573//610 572//616 +f 601//611 572//616 600//617 +f 451//612 434//479 417//486 +f 451//612 417//486 450//618 +f 484//613 451//612 450//618 +f 484//613 450//618 483//619 +f 515//614 484//613 483//619 +f 515//614 483//619 514//620 +f 544//615 515//614 514//620 +f 544//615 514//620 543//621 +f 572//616 544//615 543//621 +f 572//616 543//621 571//622 +f 600//617 572//616 571//622 +f 600//617 571//622 599//623 +f 450//618 417//486 416//493 +f 450//618 416//493 449//624 +f 483//619 450//618 449//624 +f 483//619 449//624 482//625 +f 514//620 483//619 482//625 +f 514//620 482//625 513//626 +f 543//621 514//620 513//626 +f 543//621 513//626 542//627 +f 571//622 543//621 542//627 +f 571//622 542//627 570//628 +f 599//623 571//622 570//628 +f 599//623 570//628 598//629 +f 449//624 416//493 415//500 +f 449//624 415//500 448//630 +f 482//625 449//624 448//630 +f 482//625 448//630 481//631 +f 513//626 482//625 481//631 +f 513//626 481//631 512//632 +f 542//627 513//626 512//632 +f 542//627 512//632 541//633 +f 570//628 542//627 541//633 +f 570//628 541//633 569//634 +f 598//629 570//628 569//634 +f 598//629 569//634 597//635 +f 448//630 415//500 414//507 +f 448//630 414//507 447//636 +f 481//631 448//630 447//636 +f 481//631 447//636 480//637 +f 512//632 481//631 480//637 +f 512//632 480//637 511//638 +f 541//633 512//632 511//638 +f 541//633 511//638 540//639 +f 569//634 541//633 540//639 +f 569//634 540//639 568//640 +f 597//635 569//634 568//640 +f 597//635 568//640 596//641 +f 447//636 414//507 413//514 +f 447//636 413//514 446//642 +f 480//637 447//636 446//642 +f 480//637 446//642 479//643 +f 511//638 480//637 479//643 +f 511//638 479//643 510//644 +f 540//639 511//638 510//644 +f 540//639 510//644 539//175 +f 568//640 540//639 539//175 +f 568//640 539//175 585//249 +f 596//641 568//640 585//249 +f 596//641 585//249 613//248 +f 446//642 413//514 412//361 +f 446//642 412//361 445//515 +f 479//643 446//642 445//515 +f 479//643 445//515 478//517 +f 510//644 479//643 478//517 +f 510//644 478//517 509//176 +f 539//175 510//644 509//176 +f 691//228 648//227 674//645 +f 702//646 691//228 674//645 +f 702//646 674//645 701//647 +f 731//648 702//646 701//647 +f 731//648 701//647 730//649 +f 759//650 731//648 730//649 +f 759//650 730//649 758//651 +f 786//652 759//650 758//651 +f 786//652 758//651 785//653 +f 648//227 621//526 638//527 +f 648//227 638//527 663//654 +f 674//645 648//227 663//654 +f 674//645 663//654 690//655 +f 701//647 674//645 690//655 +f 701//647 690//655 720//656 +f 730//649 701//647 720//656 +f 730//649 720//656 749//657 +f 758//651 730//649 749//657 +f 758//651 749//657 777//658 +f 785//653 758//651 777//658 +f 785//653 777//658 805//659 +f 663//654 638//527 664//533 +f 663//654 664//533 692//660 +f 690//655 663//654 692//660 +f 690//655 692//660 721//661 +f 720//656 690//655 721//661 +f 720//656 721//661 750//662 +f 749//657 720//656 750//662 +f 749//657 750//662 778//663 +f 777//658 749//657 778//663 +f 777//658 778//663 806//664 +f 805//659 777//658 806//664 +f 805//659 806//664 833//665 +f 692//660 664//533 688//539 +f 692//660 688//539 718//666 +f 721//661 692//660 718//666 +f 721//661 718//666 747//667 +f 750//662 721//661 747//667 +f 750//662 747//667 775//668 +f 778//663 750//662 775//668 +f 778//663 775//668 803//669 +f 806//664 778//663 803//669 +f 806//664 803//669 831//670 +f 833//665 806//664 831//670 +f 833//665 831//670 838//671 +f 718//666 688//539 698//545 +f 718//666 698//545 728//672 +f 747//667 718//666 728//672 +f 747//667 728//672 756//673 +f 775//668 747//667 756//673 +f 775//668 756//673 784//674 +f 803//669 775//668 784//674 +f 803//669 784//674 804//675 +f 831//670 803//669 804//675 +f 831//670 804//675 811//676 +f 838//671 831//670 811//676 +f 838//671 811//676 830//677 +f 728//672 698//545 717//551 +f 728//672 717//551 746//678 +f 756//673 728//672 746//678 +f 756//673 746//678 757//679 +f 784//674 756//673 757//679 +f 784//674 757//679 776//680 +f 804//675 784//674 776//680 +f 804//675 776//680 783//681 +f 811//676 804//675 783//681 +f 811//676 783//681 802//682 +f 830//677 811//676 802//682 +f 830//677 802//682 810//683 +f 746//678 717//551 727//557 +f 746//678 727//557 729//684 +f 757//679 746//678 729//684 +f 757//679 729//684 748//685 +f 776//680 757//679 748//685 +f 776//680 748//685 755//686 +f 783//681 776//680 755//686 +f 783//681 755//686 774//687 +f 802//682 783//681 774//687 +f 802//682 774//687 782//688 +f 810//683 802//682 782//688 +f 810//683 782//688 809//689 +f 729//684 727//557 699//563 +f 729//684 699//563 719//690 +f 748//685 729//684 719//690 +f 748//685 719//690 726//691 +f 755//686 748//685 726//691 +f 755//686 726//691 745//692 +f 774//687 755//686 745//692 +f 774//687 745//692 754//693 +f 782//688 774//687 754//693 +f 782//688 754//693 781//694 +f 809//689 782//688 781//694 +f 809//689 781//694 780//695 +f 719//690 699//563 689//569 +f 719//690 689//569 696//696 +f 726//691 719//690 696//696 +f 726//691 696//696 716//697 +f 745//692 726//691 716//697 +f 745//692 716//697 725//698 +f 754//693 745//692 725//698 +f 754//693 725//698 753//699 +f 781//694 754//693 753//699 +f 781//694 753//699 752//700 +f 780//695 781//694 752//700 +f 780//695 752//700 773//701 +f 696//696 689//569 668//575 +f 696//696 668//575 686//702 +f 716//697 696//696 686//702 +f 716//697 686//702 695//703 +f 725//698 716//697 695//703 +f 725//698 695//703 724//704 +f 753//699 725//698 724//704 +f 753//699 724//704 723//705 +f 752//700 753//699 723//705 +f 752//700 723//705 744//706 +f 773//701 752//700 744//706 +f 773//701 744//706 772//707 +f 686//702 668//575 641//579 +f 686//702 641//579 667//708 +f 695//703 686//702 667//708 +f 695//703 667//708 715//160 +f 724//704 695//703 715//160 +f 724//704 715//160 694//709 +f 723//705 724//704 694//709 +f 723//705 694//709 714//710 +f 744//706 723//705 714//710 +f 744//706 714//710 743//711 +f 772//707 744//706 743//711 +f 772//707 743//711 771//712 +f 694//709 715//160 666//713 +f 694//709 666//713 685//714 +f 714//710 694//709 685//714 +f 714//710 685//714 713//715 +f 743//711 714//710 713//715 +f 743//711 713//715 742//716 +f 771//712 743//711 742//716 +f 771//712 742//716 770//717 +f 666//713 631//152 658//718 +f 685//714 666//713 658//718 +f 685//714 658//718 684//719 +f 713//715 685//714 684//719 +f 713//715 684//719 712//720 +f 742//716 713//715 712//720 +f 742//716 712//720 741//721 +f 770//717 742//716 741//721 +f 770//717 741//721 769//722 +f 631//152 605//592 604//593 +f 631//152 604//593 630//723 +f 658//718 631//152 630//723 +f 658//718 630//723 657//724 +f 684//719 658//718 657//724 +f 684//719 657//724 683//725 +f 712//720 684//719 683//725 +f 712//720 683//725 711//726 +f 741//721 712//720 711//726 +f 741//721 711//726 740//727 +f 769//722 741//721 740//727 +f 769//722 740//727 768//728 +f 630//723 604//593 603//599 +f 630//723 603//599 629//729 +f 657//724 630//723 629//729 +f 657//724 629//729 656//730 +f 683//725 657//724 656//730 +f 683//725 656//730 682//731 +f 711//726 683//725 682//731 +f 711//726 682//731 710//732 +f 740//727 711//726 710//732 +f 740//727 710//732 739//733 +f 768//728 740//727 739//733 +f 768//728 739//733 767//734 +f 629//729 603//599 602//605 +f 629//729 602//605 628//735 +f 656//730 629//729 628//735 +f 656//730 628//735 655//736 +f 682//731 656//730 655//736 +f 682//731 655//736 681//737 +f 710//732 682//731 681//737 +f 710//732 681//737 709//738 +f 739//733 710//732 709//738 +f 739//733 709//738 738//739 +f 767//734 739//733 738//739 +f 767//734 738//739 766//740 +f 628//735 602//605 601//611 +f 628//735 601//611 627//741 +f 655//736 628//735 627//741 +f 655//736 627//741 654//742 +f 681//737 655//736 654//742 +f 681//737 654//742 680//743 +f 709//738 681//737 680//743 +f 709//738 680//743 708//744 +f 738//739 709//738 708//744 +f 738//739 708//744 737//745 +f 766//740 738//739 737//745 +f 766//740 737//745 765//746 +f 627//741 601//611 600//617 +f 627//741 600//617 626//747 +f 654//742 627//741 626//747 +f 654//742 626//747 653//748 +f 680//743 654//742 653//748 +f 680//743 653//748 679//749 +f 708//744 680//743 679//749 +f 708//744 679//749 707//750 +f 737//745 708//744 707//750 +f 737//745 707//750 736//751 +f 765//746 737//745 736//751 +f 765//746 736//751 764//752 +f 626//747 600//617 599//623 +f 626//747 599//623 625//753 +f 653//748 626//747 625//753 +f 653//748 625//753 652//754 +f 679//749 653//748 652//754 +f 679//749 652//754 678//755 +f 707//750 679//749 678//755 +f 707//750 678//755 706//756 +f 736//751 707//750 706//756 +f 736//751 706//756 735//757 +f 764//752 736//751 735//757 +f 764//752 735//757 763//758 +f 625//753 599//623 598//629 +f 625//753 598//629 624//759 +f 652//754 625//753 624//759 +f 652//754 624//759 651//760 +f 678//755 652//754 651//760 +f 678//755 651//760 677//761 +f 706//756 678//755 677//761 +f 706//756 677//761 705//762 +f 735//757 706//756 705//762 +f 735//757 705//762 734//763 +f 763//758 735//757 734//763 +f 763//758 734//763 762//764 +f 624//759 598//629 597//635 +f 624//759 597//635 623//765 +f 651//760 624//759 623//765 +f 651//760 623//765 650//766 +f 677//761 651//760 650//766 +f 677//761 650//766 676//767 +f 705//762 677//761 676//767 +f 705//762 676//767 704//768 +f 734//763 705//762 704//768 +f 734//763 704//768 733//769 +f 762//764 734//763 733//769 +f 762//764 733//769 761//770 +f 623//765 597//635 596//641 +f 623//765 596//641 622//771 +f 650//766 623//765 622//771 +f 650//766 622//771 649//772 +f 676//767 650//766 649//772 +f 676//767 649//772 675//773 +f 704//768 676//767 675//773 +f 704//768 675//773 703//774 +f 733//769 704//768 703//774 +f 733//769 703//774 732//775 +f 761//770 733//769 732//775 +f 761//770 732//775 760//776 +f 622//771 596//641 613//248 +f 622//771 613//248 640//777 +f 649//772 622//771 640//777 +f 649//772 640//777 665//778 +f 675//773 649//772 665//778 +f 675//773 665//778 693//779 +f 703//774 675//773 693//779 +f 703//774 693//779 722//780 +f 732//775 703//774 722//780 +f 732//775 722//780 751//781 +f 760//776 732//775 751//781 +f 760//776 751//781 779//782 +f 693//779 665//778 691//228 +f 693//779 691//228 702//646 +f 722//780 693//779 702//646 +f 722//780 702//646 731//648 +f 751//781 722//780 731//648 +f 751//781 731//648 759//650 +f 779//782 751//781 759//650 +f 779//782 759//650 786//652 +f 917//783 918//784 913//785 +f 892//786 917//783 913//785 +f 892//786 913//785 887//787 +f 866//788 892//786 887//787 +f 866//788 887//787 861//789 +f 840//790 866//788 861//789 +f 840//790 861//789 834//791 +f 813//792 840//790 834//791 +f 813//792 834//791 807//793 +f 786//652 813//792 807//793 +f 786//652 807//793 779//782 +f 913//785 918//784 893//794 +f 887//787 913//785 893//794 +f 887//787 893//794 867//795 +f 861//789 887//787 867//795 +f 861//789 867//795 841//796 +f 834//791 861//789 841//796 +f 834//791 841//796 814//797 +f 807//793 834//791 814//797 +f 807//793 814//797 787//798 +f 779//782 807//793 787//798 +f 779//782 787//798 760//776 +f 893//794 918//784 894//799 +f 867//795 893//794 894//799 +f 867//795 894//799 868//800 +f 841//796 867//795 868//800 +f 841//796 868//800 842//801 +f 814//797 841//796 842//801 +f 814//797 842//801 815//802 +f 787//798 814//797 815//802 +f 787//798 815//802 788//803 +f 760//776 787//798 788//803 +f 760//776 788//803 761//770 +f 894//799 918//784 895//804 +f 868//800 894//799 895//804 +f 868//800 895//804 869//805 +f 842//801 868//800 869//805 +f 842//801 869//805 843//806 +f 815//802 842//801 843//806 +f 815//802 843//806 816//807 +f 788//803 815//802 816//807 +f 788//803 816//807 789//808 +f 761//770 788//803 789//808 +f 761//770 789//808 762//764 +f 895//804 918//784 896//809 +f 869//805 895//804 896//809 +f 869//805 896//809 870//810 +f 843//806 869//805 870//810 +f 843//806 870//810 844//811 +f 816//807 843//806 844//811 +f 816//807 844//811 817//812 +f 789//808 816//807 817//812 +f 789//808 817//812 790//813 +f 762//764 789//808 790//813 +f 762//764 790//813 763//758 +f 896//809 918//784 897//814 +f 870//810 896//809 897//814 +f 870//810 897//814 871//815 +f 844//811 870//810 871//815 +f 844//811 871//815 845//816 +f 817//812 844//811 845//816 +f 817//812 845//816 818//817 +f 790//813 817//812 818//817 +f 790//813 818//817 791//818 +f 763//758 790//813 791//818 +f 763//758 791//818 764//752 +f 897//814 918//784 898//819 +f 871//815 897//814 898//819 +f 871//815 898//819 872//820 +f 845//816 871//815 872//820 +f 845//816 872//820 846//821 +f 818//817 845//816 846//821 +f 818//817 846//821 819//822 +f 791//818 818//817 819//822 +f 791//818 819//822 792//823 +f 764//752 791//818 792//823 +f 764//752 792//823 765//746 +f 898//819 918//784 899//824 +f 872//820 898//819 899//824 +f 872//820 899//824 873//825 +f 846//821 872//820 873//825 +f 846//821 873//825 847//826 +f 819//822 846//821 847//826 +f 819//822 847//826 820//827 +f 792//823 819//822 820//827 +f 792//823 820//827 793//828 +f 765//746 792//823 793//828 +f 765//746 793//828 766//740 +f 899//824 918//784 900//829 +f 873//825 899//824 900//829 +f 873//825 900//829 874//830 +f 847//826 873//825 874//830 +f 847//826 874//830 848//831 +f 820//827 847//826 848//831 +f 820//827 848//831 821//832 +f 793//828 820//827 821//832 +f 793//828 821//832 794//833 +f 766//740 793//828 794//833 +f 766//740 794//833 767//734 +f 900//829 918//784 901//834 +f 874//830 900//829 901//834 +f 874//830 901//834 875//835 +f 848//831 874//830 875//835 +f 848//831 875//835 849//836 +f 821//832 848//831 849//836 +f 821//832 849//836 822//837 +f 794//833 821//832 822//837 +f 794//833 822//837 795//838 +f 767//734 794//833 795//838 +f 767//734 795//838 768//728 +f 901//834 918//784 902//839 +f 875//835 901//834 902//839 +f 875//835 902//839 876//840 +f 849//836 875//835 876//840 +f 849//836 876//840 850//841 +f 822//837 849//836 850//841 +f 822//837 850//841 823//842 +f 795//838 822//837 823//842 +f 795//838 823//842 796//843 +f 768//728 795//838 796//843 +f 768//728 796//843 769//722 +f 902//839 918//784 903//844 +f 876//840 902//839 903//844 +f 876//840 903//844 877//845 +f 850//841 876//840 877//845 +f 850//841 877//845 851//846 +f 823//842 850//841 851//846 +f 823//842 851//846 824//847 +f 796//843 823//842 824//847 +f 796//843 824//847 797//848 +f 769//722 796//843 797//848 +f 769//722 797//848 770//717 +f 903//844 918//784 904//849 +f 877//845 903//844 904//849 +f 877//845 904//849 878//850 +f 851//846 877//845 878//850 +f 851//846 878//850 852//851 +f 824//847 851//846 852//851 +f 824//847 852//851 825//852 +f 797//848 824//847 825//852 +f 797//848 825//852 798//853 +f 770//717 797//848 798//853 +f 770//717 798//853 771//712 +f 904//849 918//784 905//854 +f 878//850 904//849 905//854 +f 878//850 905//854 879//855 +f 852//851 878//850 879//855 +f 852//851 879//855 853//856 +f 825//852 852//851 853//856 +f 825//852 853//856 826//857 +f 798//853 825//852 826//857 +f 798//853 826//857 799//858 +f 771//712 798//853 799//858 +f 771//712 799//858 772//707 +f 905//854 918//784 906//859 +f 879//855 905//854 906//859 +f 879//855 906//859 880//860 +f 853//856 879//855 880//860 +f 853//856 880//860 854//861 +f 826//857 853//856 854//861 +f 826//857 854//861 827//862 +f 799//858 826//857 827//862 +f 799//858 827//862 800//863 +f 772//707 799//858 800//863 +f 772//707 800//863 773//701 +f 906//859 918//784 907//864 +f 880//860 906//859 907//864 +f 880//860 907//864 881//865 +f 854//861 880//860 881//865 +f 854//861 881//865 855//866 +f 827//862 854//861 855//866 +f 827//862 855//866 828//867 +f 800//863 827//862 828//867 +f 800//863 828//867 801//868 +f 773//701 800//863 801//868 +f 773//701 801//868 780//695 +f 907//864 918//784 908//869 +f 881//865 907//864 908//869 +f 881//865 908//869 882//870 +f 855//866 881//865 882//870 +f 855//866 882//870 856//871 +f 828//867 855//866 856//871 +f 828//867 856//871 829//872 +f 801//868 828//867 829//872 +f 801//868 829//872 808//873 +f 780//695 801//868 808//873 +f 780//695 808//873 809//689 +f 908//869 918//784 909//874 +f 882//870 908//869 909//874 +f 882//870 909//874 883//875 +f 856//871 882//870 883//875 +f 856//871 883//875 857//876 +f 829//872 856//871 857//876 +f 829//872 857//876 836//877 +f 808//873 829//872 836//877 +f 808//873 836//877 835//878 +f 809//689 808//873 835//878 +f 809//689 835//878 810//683 +f 909//874 918//784 910//879 +f 883//875 909//874 910//879 +f 883//875 910//879 884//880 +f 857//876 883//875 884//880 +f 857//876 884//880 863//881 +f 836//877 857//876 863//881 +f 836//877 863//881 862//882 +f 835//878 836//877 862//882 +f 835//878 862//882 837//883 +f 810//683 835//878 837//883 +f 810//683 837//883 830//677 +f 910//879 918//784 911//884 +f 884//880 910//879 911//884 +f 884//880 911//884 889//885 +f 863//881 884//880 889//885 +f 863//881 889//885 888//886 +f 862//882 863//881 888//886 +f 862//882 888//886 864//887 +f 837//883 862//882 864//887 +f 837//883 864//887 858//888 +f 830//677 837//883 858//888 +f 830//677 858//888 838//671 +f 911//884 918//784 915//889 +f 889//885 911//884 915//889 +f 889//885 915//889 914//890 +f 888//886 889//885 914//890 +f 888//886 914//890 890//891 +f 864//887 888//886 890//891 +f 864//887 890//891 885//892 +f 858//888 864//887 885//892 +f 858//888 885//892 859//893 +f 838//671 858//888 859//893 +f 838//671 859//893 833//665 +f 915//889 918//784 919//894 +f 914//890 915//889 919//894 +f 914//890 919//894 912//895 +f 890//891 914//890 912//895 +f 890//891 912//895 886//896 +f 885//892 890//891 886//896 +f 885//892 886//896 860//897 +f 859//893 885//892 860//897 +f 859//893 860//897 832//898 +f 833//665 859//893 832//898 +f 833//665 832//898 805//659 +f 919//894 918//784 916//899 +f 912//895 919//894 916//899 +f 912//895 916//899 891//900 +f 886//896 912//895 891//900 +f 886//896 891//900 865//901 +f 860//897 886//896 865//901 +f 860//897 865//901 839//902 +f 832//898 860//897 839//902 +f 832//898 839//902 812//903 +f 805//659 832//898 812//903 +f 805//659 812//903 785//653 +f 916//899 918//784 917//783 +f 891//900 916//899 917//783 +f 891//900 917//783 892//786 +f 865//901 891//900 892//786 +f 865//901 892//786 866//788 +f 839//902 865//901 866//788 +f 839//902 866//788 840//790 +f 812//903 839//902 840//790 +f 812//903 840//790 813//792 +f 785//653 812//903 813//792 +f 785//653 813//792 786//652 +f 404//412 1267//904 1268//905 +f 384//906 373//907 372//480 +f 346//908 345//501 352//494 +f 435//909 436//426 419//419 +f 331//910 327//350 335//508 +f 462//439 453//433 1265//911 +f 920//912 921//913 922//914 +f 920//912 922//914 923//915 +f 923//915 922//914 927//916 +f 923//915 927//916 933//917 +f 933//917 927//916 940//918 +f 933//917 940//918 949//919 +f 949//919 940//918 959//920 +f 949//919 959//920 971//921 +f 971//921 959//920 984//922 +f 971//921 984//922 999//923 +f 999//923 984//922 1011//924 +f 999//923 1011//924 1027//925 +f 1027//925 1011//924 1042//926 +f 1027//925 1042//926 1059//927 +f 1059//927 1042//926 1077//928 +f 1059//927 1077//928 1095//929 +f 1095//929 1077//928 1110//930 +f 1095//929 1110//930 1129//931 +f 1129//931 1110//930 1144//932 +f 1129//931 1144//932 1163//933 +f 1163//933 1144//932 1179//934 +f 1163//933 1179//934 1196//935 +f 1196//935 1179//934 1210//936 +f 1196//935 1210//936 1220//937 +f 1220//937 1210//936 1212//938 +f 1220//937 1212//938 1201//939 +f 1201//939 1212//938 1181//940 +f 1201//939 1181//940 1169//941 +f 1169//941 1181//940 1147//942 +f 1169//941 1147//942 1135//943 +f 1135//943 1147//942 1113//944 +f 1135//943 1113//944 1102//945 +f 1102//945 1113//944 1081//946 +f 1102//945 1081//946 1065//947 +f 1065//947 1081//946 1046//948 +f 1065//947 1046//948 1032//949 +f 1032//949 1046//948 1016//950 +f 1032//949 1016//950 1003//951 +f 1003//951 1016//950 988//952 +f 1003//951 988//952 974//953 +f 974//953 988//952 962//954 +f 974//953 962//954 951//955 +f 951//955 962//954 942//956 +f 951//955 942//956 934//957 +f 934//957 942//956 928//958 +f 934//957 928//958 924//959 +f 924//959 928//958 921//913 +f 921//913 920//912 924//959 +f 926//960 920//912 923//915 +f 926//960 923//915 932//961 +f 938//962 926//960 932//961 +f 938//962 932//961 947//963 +f 956//964 938//962 947//963 +f 956//964 947//963 968//965 +f 980//966 956//964 968//965 +f 980//966 968//965 995//967 +f 1006//968 980//966 995//967 +f 1006//968 995//967 1022//969 +f 1036//970 1006//968 1022//969 +f 1036//970 1022//969 1053//971 +f 932//961 923//915 933//917 +f 932//961 933//917 948//972 +f 947//963 932//961 948//972 +f 947//963 948//972 969//973 +f 968//965 947//963 969//973 +f 968//965 969//973 996//974 +f 995//967 968//965 996//974 +f 995//967 996//974 1023//975 +f 1022//969 995//967 1023//975 +f 1022//969 1023//975 1054//976 +f 1053//971 1022//969 1054//976 +f 1053//971 1054//976 1089//977 +f 948//972 933//917 949//919 +f 948//972 949//919 970//978 +f 969//973 948//972 970//978 +f 969//973 970//978 997//979 +f 996//974 969//973 997//979 +f 996//974 997//979 1024//980 +f 1023//975 996//974 1024//980 +f 1023//975 1024//980 1055//981 +f 1054//976 1023//975 1055//981 +f 1054//976 1055//981 1090//982 +f 1089//977 1054//976 1090//982 +f 1089//977 1090//982 1109//983 +f 970//978 949//919 971//921 +f 970//978 971//921 998//984 +f 997//979 970//978 998//984 +f 997//979 998//984 1025//985 +f 1024//980 997//979 1025//985 +f 1024//980 1025//985 1056//986 +f 1055//981 1024//980 1056//986 +f 1055//981 1056//986 1091//987 +f 1090//982 1055//981 1091//987 +f 1090//982 1091//987 1124//988 +f 1109//983 1090//982 1124//988 +f 1109//983 1124//988 1122//989 +f 998//984 971//921 999//923 +f 998//984 999//923 1026//990 +f 1025//985 998//984 1026//990 +f 1025//985 1026//990 1057//991 +f 1056//986 1025//985 1057//991 +f 1056//986 1057//991 1092//992 +f 1091//987 1056//986 1092//992 +f 1091//987 1092//992 1125//993 +f 1124//988 1091//987 1125//993 +f 1124//988 1125//993 1156//994 +f 1122//989 1124//988 1156//994 +f 1122//989 1156//994 1142//995 +f 1026//990 999//923 1027//925 +f 1026//990 1027//925 1058//996 +f 1057//991 1026//990 1058//996 +f 1057//991 1058//996 1093//997 +f 1092//992 1057//991 1093//997 +f 1092//992 1093//997 1126//998 +f 1125//993 1092//992 1126//998 +f 1125//993 1126//998 1159//999 +f 1156//994 1125//993 1159//999 +f 1156//994 1159//999 1176//1000 +f 1142//995 1156//994 1176//1000 +f 1142//995 1176//1000 1157//1001 +f 1058//996 1027//925 1059//927 +f 1058//996 1059//927 1094//1002 +f 1093//997 1058//996 1094//1002 +f 1093//997 1094//1002 1127//1003 +f 1126//998 1093//997 1127//1003 +f 1126//998 1127//1003 1160//1004 +f 1159//999 1126//998 1160//1004 +f 1159//999 1160//1004 1192//1005 +f 1176//1000 1159//999 1192//1005 +f 1176//1000 1192//1005 1189//1006 +f 1157//1001 1176//1000 1189//1006 +f 1157//1001 1189//1006 1178//1007 +f 1094//1002 1059//927 1095//929 +f 1094//1002 1095//929 1128//1008 +f 1127//1003 1094//1002 1128//1008 +f 1127//1003 1128//1008 1161//1009 +f 1160//1004 1127//1003 1161//1009 +f 1160//1004 1161//1009 1193//1010 +f 1192//1005 1160//1004 1193//1010 +f 1192//1005 1193//1010 1215//1011 +f 1189//1006 1192//1005 1215//1011 +f 1189//1006 1215//1011 1207//1012 +f 1178//1007 1189//1006 1207//1012 +f 1178//1007 1207//1012 1191//1013 +f 1128//1008 1095//929 1129//931 +f 1128//1008 1129//931 1162//1014 +f 1161//1009 1128//1008 1162//1014 +f 1161//1009 1162//1014 1194//1015 +f 1193//1010 1161//1009 1194//1015 +f 1193//1010 1194//1015 1217//1016 +f 1215//1011 1193//1010 1217//1016 +f 1215//1011 1217//1016 1227//1017 +f 1207//1012 1215//1011 1227//1017 +f 1207//1012 1227//1017 1216//1018 +f 1191//1013 1207//1012 1216//1018 +f 1191//1013 1216//1018 1209//1019 +f 1162//1014 1129//931 1163//933 +f 1162//1014 1163//933 1195//1020 +f 1194//1015 1162//1014 1195//1020 +f 1194//1015 1195//1020 1218//1021 +f 1217//1016 1194//1015 1218//1021 +f 1217//1016 1218//1021 1230//1022 +f 1227//1017 1217//1016 1230//1022 +f 1227//1017 1230//1022 1229//1023 +f 1216//1018 1227//1017 1229//1023 +f 1216//1018 1229//1023 1225//1024 +f 1209//1019 1216//1018 1225//1024 +f 1209//1019 1225//1024 1203//1025 +f 1195//1020 1163//933 1196//935 +f 1195//1020 1196//935 1219//1026 +f 1218//1021 1195//1020 1219//1026 +f 1218//1021 1219//1026 1231//1027 +f 1230//1022 1218//1021 1231//1027 +f 1230//1022 1231//1027 1232//1028 +f 1229//1023 1230//1022 1232//1028 +f 1229//1023 1232//1028 1228//1029 +f 1225//1024 1229//1023 1228//1029 +f 1225//1024 1228//1029 1214//1030 +f 1203//1025 1225//1024 1214//1030 +f 1203//1025 1214//1030 1184//1031 +f 1219//1026 1196//935 1220//937 +f 1219//1026 1220//937 1224//1032 +f 1231//1027 1219//1026 1224//1032 +f 1231//1027 1224//1032 1223//1033 +f 1232//1028 1231//1027 1223//1033 +f 1232//1028 1223//1033 1222//1034 +f 1228//1029 1232//1028 1222//1034 +f 1228//1029 1222//1034 1221//1035 +f 1214//1030 1228//1029 1221//1035 +f 1214//1030 1221//1035 1204//1036 +f 1184//1031 1214//1030 1204//1036 +f 1184//1031 1204//1036 1171//1037 +f 1224//1032 1220//937 1201//939 +f 1224//1032 1201//939 1200//1038 +f 1223//1033 1224//1032 1200//1038 +f 1223//1033 1200//1038 1199//1039 +f 1222//1034 1223//1033 1199//1039 +f 1222//1034 1199//1039 1198//1040 +f 1221//1035 1222//1034 1198//1040 +f 1221//1035 1198//1040 1197//1041 +f 1204//1036 1221//1035 1197//1041 +f 1204//1036 1197//1041 1185//1042 +f 1171//1037 1204//1036 1185//1042 +f 1171//1037 1185//1042 1151//1043 +f 1200//1038 1201//939 1169//941 +f 1200//1038 1169//941 1168//1044 +f 1199//1039 1200//1038 1168//1044 +f 1199//1039 1168//1044 1167//1045 +f 1198//1040 1199//1039 1167//1045 +f 1198//1040 1167//1045 1166//1046 +f 1197//1041 1198//1040 1166//1046 +f 1197//1041 1166//1046 1165//1047 +f 1185//1042 1197//1041 1165//1047 +f 1185//1042 1165//1047 1164//1048 +f 1151//1043 1185//1042 1164//1048 +f 1151//1043 1164//1048 1137//1049 +f 1168//1044 1169//941 1135//943 +f 1168//1044 1135//943 1134//1050 +f 1167//1045 1168//1044 1134//1050 +f 1167//1045 1134//1050 1133//1051 +f 1166//1046 1167//1045 1133//1051 +f 1166//1046 1133//1051 1132//1052 +f 1165//1047 1166//1046 1132//1052 +f 1165//1047 1132//1052 1131//1053 +f 1164//1048 1165//1047 1131//1053 +f 1164//1048 1131//1053 1130//1054 +f 1137//1049 1164//1048 1130//1054 +f 1137//1049 1130//1054 1117//1055 +f 1134//1050 1135//943 1102//945 +f 1134//1050 1102//945 1101//1056 +f 1133//1051 1134//1050 1101//1056 +f 1133//1051 1101//1056 1100//1057 +f 1132//1052 1133//1051 1100//1057 +f 1132//1052 1100//1057 1099//1058 +f 1131//1053 1132//1052 1099//1058 +f 1131//1053 1099//1058 1098//1059 +f 1130//1054 1131//1053 1098//1059 +f 1130//1054 1098//1059 1097//1060 +f 1117//1055 1130//1054 1097//1060 +f 1117//1055 1097//1060 1096//1061 +f 1101//1056 1102//945 1065//947 +f 1101//1056 1065//947 1064//1062 +f 1100//1057 1101//1056 1064//1062 +f 1100//1057 1064//1062 1063//1063 +f 1099//1058 1100//1057 1063//1063 +f 1099//1058 1063//1063 1062//1064 +f 1098//1059 1099//1058 1062//1064 +f 1098//1059 1062//1064 1061//1065 +f 1097//1060 1098//1059 1061//1065 +f 1097//1060 1061//1065 1060//1066 +f 1096//1061 1097//1060 1060//1066 +f 1096//1061 1060//1066 1066//1067 +f 1064//1062 1065//947 1032//949 +f 1064//1062 1032//949 1031//1068 +f 1063//1063 1064//1062 1031//1068 +f 1063//1063 1031//1068 1030//1069 +f 1062//1064 1063//1063 1030//1069 +f 1062//1064 1030//1069 1029//1070 +f 1061//1065 1062//1064 1029//1070 +f 1061//1065 1029//1070 1028//1071 +f 1060//1066 1061//1065 1028//1071 +f 1060//1066 1028//1071 1033//1072 +f 1066//1067 1060//1066 1033//1072 +f 1066//1067 1033//1072 1050//1073 +f 1031//1068 1032//949 1003//951 +f 1031//1068 1003//951 1002//1074 +f 1030//1069 1031//1068 1002//1074 +f 1030//1069 1002//1074 1001//1075 +f 1029//1070 1030//1069 1001//1075 +f 1029//1070 1001//1075 1000//1076 +f 1028//1071 1029//1070 1000//1076 +f 1028//1071 1000//1076 1004//1077 +f 1033//1072 1028//1071 1004//1077 +f 1033//1072 1004//1077 1021//1078 +f 1050//1073 1033//1072 1021//1078 +f 1050//1073 1021//1078 1041//1079 +f 1002//1074 1003//951 974//953 +f 1002//1074 974//953 973//1080 +f 1001//1075 1002//1074 973//1080 +f 1001//1075 973//1080 972//1081 +f 1000//1076 1001//1075 972//1081 +f 1000//1076 972//1081 975//1082 +f 1004//1077 1000//1076 975//1082 +f 1004//1077 975//1082 992//1083 +f 1021//1078 1004//1077 992//1083 +f 1021//1078 992//1083 1010//1084 +f 1041//1079 1021//1078 1010//1084 +f 1041//1079 1010//1084 1040//1085 +f 973//1080 974//953 951//955 +f 973//1080 951//955 950//1086 +f 972//1081 973//1080 950//1086 +f 972//1081 950//1086 952//1087 +f 975//1082 972//1081 952//1087 +f 975//1082 952//1087 965//1088 +f 992//1083 975//1082 965//1088 +f 992//1083 965//1088 983//1089 +f 1010//1084 992//1083 983//1089 +f 1010//1084 983//1089 1009//1090 +f 1040//1085 1010//1084 1009//1090 +f 1040//1085 1009//1090 1039//1091 +f 950//1086 951//955 934//957 +f 950//1086 934//957 935//1092 +f 952//1087 950//1086 935//1092 +f 952//1087 935//1092 944//1093 +f 965//1088 952//1087 944//1093 +f 965//1088 944//1093 958//1094 +f 983//1089 965//1088 958//1094 +f 983//1089 958//1094 982//1095 +f 1009//1090 983//1089 982//1095 +f 1009//1090 982//1095 1008//1096 +f 1039//1091 1009//1090 1008//1096 +f 1039//1091 1008//1096 1038//1097 +f 935//1092 934//957 924//959 +f 935//1092 924//959 929//1098 +f 944//1093 935//1092 929//1098 +f 944//1093 929//1098 939//1099 +f 958//1094 944//1093 939//1099 +f 958//1094 939//1099 957//1100 +f 982//1095 958//1094 957//1100 +f 982//1095 957//1100 981//1101 +f 1008//1096 982//1095 981//1101 +f 1008//1096 981//1101 1007//1102 +f 1038//1097 1008//1096 1007//1102 +f 1038//1097 1007//1102 1037//1103 +f 924//959 920//912 929//1098 +f 929//1098 920//912 926//960 +f 939//1099 929//1098 926//960 +f 939//1099 926//960 938//962 +f 957//1100 939//1099 938//962 +f 957//1100 938//962 956//964 +f 981//1101 957//1100 956//964 +f 981//1101 956//964 980//966 +f 1007//1102 981//1101 980//966 +f 1007//1102 980//966 1006//968 +f 1037//1103 1007//1102 1006//968 +f 1037//1103 1006//968 1036//970 +f 993//1104 1005//1105 976//1106 +f 966//1107 993//1104 976//1106 +f 966//1107 976//1106 953//1108 +f 945//1109 966//1107 953//1108 +f 945//1109 953//1108 936//1110 +f 930//1111 945//1109 936//1110 +f 930//1111 936//1110 925//1112 +f 921//913 930//1111 925//1112 +f 921//913 925//1112 922//914 +f 976//1106 1005//1105 977//1113 +f 953//1108 976//1106 977//1113 +f 953//1108 977//1113 954//1114 +f 936//1110 953//1108 954//1114 +f 936//1110 954//1114 937//1115 +f 925//1112 936//1110 937//1115 +f 925//1112 937//1115 931//1116 +f 922//914 925//1112 931//1116 +f 922//914 931//1116 927//916 +f 977//1113 1005//1105 978//1117 +f 954//1114 977//1113 978//1117 +f 954//1114 978//1117 955//1118 +f 937//1115 954//1114 955//1118 +f 937//1115 955//1118 946//1119 +f 931//1116 937//1115 946//1119 +f 931//1116 946//1119 941//1120 +f 927//916 931//1116 941//1120 +f 927//916 941//1120 940//918 +f 978//1117 1005//1105 979//1121 +f 955//1118 978//1117 979//1121 +f 955//1118 979//1121 967//1122 +f 946//1119 955//1118 967//1122 +f 946//1119 967//1122 961//1123 +f 941//1120 946//1119 961//1123 +f 941//1120 961//1123 960//1124 +f 940//918 941//1120 960//1124 +f 940//918 960//1124 959//920 +f 979//1121 1005//1105 994//1125 +f 967//1122 979//1121 994//1125 +f 967//1122 994//1125 987//1126 +f 961//1123 967//1122 987//1126 +f 961//1123 987//1126 986//1127 +f 960//1124 961//1123 986//1127 +f 960//1124 986//1127 985//1128 +f 959//920 960//1124 985//1128 +f 959//920 985//1128 984//922 +f 994//1125 1005//1105 1015//1129 +f 987//1126 994//1125 1015//1129 +f 987//1126 1015//1129 1014//1130 +f 986//1127 987//1126 1014//1130 +f 986//1127 1014//1130 1013//1131 +f 985//1128 986//1127 1013//1131 +f 985//1128 1013//1131 1012//1132 +f 984//922 985//1128 1012//1132 +f 984//922 1012//1132 1011//924 +f 1015//1129 1005//1105 1035//1133 +f 1014//1130 1015//1129 1035//1133 +f 1014//1130 1035//1133 1045//1134 +f 1013//1131 1014//1130 1045//1134 +f 1013//1131 1045//1134 1044//1135 +f 1012//1132 1013//1131 1044//1135 +f 1012//1132 1044//1135 1043//1136 +f 1011//924 1012//1132 1043//1136 +f 1011//924 1043//1136 1042//926 +f 1035//1133 1005//1105 1052//1137 +f 1045//1134 1035//1133 1052//1137 +f 1045//1134 1052//1137 1080//1138 +f 1044//1135 1045//1134 1080//1138 +f 1044//1135 1080//1138 1079//1139 +f 1043//1136 1044//1135 1079//1139 +f 1043//1136 1079//1139 1078//1140 +f 1042//926 1043//1136 1078//1140 +f 1042//926 1078//1140 1077//928 +f 1052//1137 1005//1105 1068//1141 +f 1080//1138 1052//1137 1068//1141 +f 1080//1138 1068//1141 1106//1142 +f 1079//1139 1080//1138 1106//1142 +f 1079//1139 1106//1142 1112//1143 +f 1078//1140 1079//1139 1112//1143 +f 1078//1140 1112//1143 1111//1144 +f 1077//928 1078//1140 1111//1144 +f 1077//928 1111//1144 1110//930 +f 1068//1141 1005//1105 1087//1145 +f 1106//1142 1068//1141 1087//1145 +f 1106//1142 1087//1145 1120//1146 +f 1112//1143 1106//1142 1120//1146 +f 1112//1143 1120//1146 1146//1147 +f 1111//1144 1112//1143 1146//1147 +f 1111//1144 1146//1147 1145//1148 +f 1110//930 1111//1144 1145//1148 +f 1110//930 1145//1148 1144//932 +f 1087//1145 1005//1105 1107//1149 +f 1120//1146 1087//1145 1107//1149 +f 1120//1146 1107//1149 1140//1150 +f 1146//1147 1120//1146 1140//1150 +f 1146//1147 1140//1150 1174//1151 +f 1145//1148 1146//1147 1174//1151 +f 1145//1148 1174//1151 1180//1152 +f 1144//932 1145//1148 1180//1152 +f 1144//932 1180//1152 1179//934 +f 1107//1149 1005//1105 1121//1153 +f 1140//1150 1107//1149 1121//1153 +f 1140//1150 1121//1153 1154//1154 +f 1174//1151 1140//1150 1154//1154 +f 1174//1151 1154//1154 1188//1155 +f 1180//1152 1174//1151 1188//1155 +f 1180//1152 1188//1155 1211//1156 +f 1179//934 1180//1152 1211//1156 +f 1179//934 1211//1156 1210//936 +f 1121//1153 1005//1105 1141//1157 +f 1154//1154 1121//1153 1141//1157 +f 1154//1154 1141//1157 1175//1158 +f 1188//1155 1154//1154 1175//1158 +f 1188//1155 1175//1158 1206//1159 +f 1211//1156 1188//1155 1206//1159 +f 1211//1156 1206//1159 1226//1160 +f 1210//936 1211//1156 1226//1160 +f 1210//936 1226//1160 1212//938 +f 1141//1157 1005//1105 1155//1161 +f 1175//1158 1141//1157 1155//1161 +f 1175//1158 1155//1161 1187//1162 +f 1206//1159 1175//1158 1187//1162 +f 1206//1159 1187//1162 1205//1163 +f 1226//1160 1206//1159 1205//1163 +f 1226//1160 1205//1163 1213//1164 +f 1212//938 1226//1160 1213//1164 +f 1212//938 1213//1164 1181//940 +f 1155//1161 1005//1105 1153//1165 +f 1187//1162 1155//1161 1153//1165 +f 1187//1162 1153//1165 1173//1166 +f 1205//1163 1187//1162 1173//1166 +f 1205//1163 1173//1166 1186//1167 +f 1213//1164 1205//1163 1186//1167 +f 1213//1164 1186//1167 1182//1168 +f 1181//940 1213//1164 1182//1168 +f 1181//940 1182//1168 1147//942 +f 1153//1165 1005//1105 1139//1169 +f 1173//1166 1153//1165 1139//1169 +f 1173//1166 1139//1169 1152//1170 +f 1186//1167 1173//1166 1152//1170 +f 1186//1167 1152//1170 1172//1171 +f 1182//1168 1186//1167 1172//1171 +f 1182//1168 1172//1171 1148//1172 +f 1147//942 1182//1168 1148//1172 +f 1147//942 1148//1172 1113//944 +f 1139//1169 1005//1105 1119//1173 +f 1152//1170 1139//1169 1119//1173 +f 1152//1170 1119//1173 1138//1174 +f 1172//1171 1152//1170 1138//1174 +f 1172//1171 1138//1174 1149//1175 +f 1148//1172 1172//1171 1149//1175 +f 1148//1172 1149//1175 1114//1176 +f 1113//944 1148//1172 1114//1176 +f 1113//944 1114//1176 1081//946 +f 1119//1173 1005//1105 1105//1177 +f 1138//1174 1119//1173 1105//1177 +f 1138//1174 1105//1177 1118//1178 +f 1149//1175 1138//1174 1118//1178 +f 1149//1175 1118//1178 1115//1179 +f 1114//1176 1149//1175 1115//1179 +f 1114//1176 1115//1179 1082//1180 +f 1081//946 1114//1176 1082//1180 +f 1081//946 1082//1180 1046//948 +f 1105//1177 1005//1105 1086//1181 +f 1118//1178 1105//1177 1086//1181 +f 1118//1178 1086//1181 1104//1182 +f 1115//1179 1118//1178 1104//1182 +f 1115//1179 1104//1182 1083//1183 +f 1082//1180 1115//1179 1083//1183 +f 1082//1180 1083//1183 1047//1184 +f 1046//948 1082//1180 1047//1184 +f 1046//948 1047//1184 1016//950 +f 1086//1181 1005//1105 1067//1185 +f 1104//1182 1086//1181 1067//1185 +f 1104//1182 1067//1185 1084//1186 +f 1083//1183 1104//1182 1084//1186 +f 1083//1183 1084//1186 1048//1187 +f 1047//1184 1083//1183 1048//1187 +f 1047//1184 1048//1187 1017//1188 +f 1016//950 1047//1184 1017//1188 +f 1016//950 1017//1188 988//952 +f 1067//1185 1005//1105 1051//1189 +f 1084//1186 1067//1185 1051//1189 +f 1084//1186 1051//1189 1049//1190 +f 1048//1187 1084//1186 1049//1190 +f 1048//1187 1049//1190 1018//1191 +f 1017//1188 1048//1187 1018//1191 +f 1017//1188 1018//1191 989//1192 +f 988//952 1017//1188 989//1192 +f 988//952 989//1192 962//954 +f 1051//1189 1005//1105 1034//1193 +f 1049//1190 1051//1189 1034//1193 +f 1049//1190 1034//1193 1019//1194 +f 1018//1191 1049//1190 1019//1194 +f 1018//1191 1019//1194 990//1195 +f 989//1192 1018//1191 990//1195 +f 989//1192 990//1195 963//1196 +f 962//954 989//1192 963//1196 +f 962//954 963//1196 942//956 +f 1034//1193 1005//1105 1020//1197 +f 1019//1194 1034//1193 1020//1197 +f 1019//1194 1020//1197 991//1198 +f 990//1195 1019//1194 991//1198 +f 990//1195 991//1198 964//1199 +f 963//1196 990//1195 964//1199 +f 963//1196 964//1199 943//1200 +f 942//956 963//1196 943//1200 +f 942//956 943//1200 928//958 +f 1020//1197 1005//1105 993//1104 +f 991//1198 1020//1197 993//1104 +f 991//1198 993//1104 966//1107 +f 964//1199 991//1198 966//1107 +f 964//1199 966//1107 945//1109 +f 943//1200 964//1199 945//1109 +f 943//1200 945//1109 930//1111 +f 928//958 943//1200 930//1111 +f 928//958 930//1111 921//913 +f 1151//1043 1137//1049 1150//1201 +f 1142//995 1143//1202 1122//989 +f 1053//971 1089//977 1069//1203 +f 1122//989 1123//1204 1109//983 +f 1096//1061 1103//1205 1117//1055 +f 1171//1037 1170//1206 1184//1031 +f 1191//1013 1209//1019 1190//1207 +f 1036//970 1053//971 1070//1208 +f 1036//970 1070//1208 1037//1103 +f 1203//1025 1202//1209 1209//1019 +f 1066//1067 1085//1210 1096//1061 +f 1050//1073 1076//1211 1066//1067 +f 1184//1031 1183//1212 1203//1025 +f 1041//1079 1040//1085 1075//1213 +f 1171//1037 1151//1043 1170//1206 +f 1157//1001 1158//1214 1142//995 +f 1137//1049 1117//1055 1136//1215 +f 1038//1097 1072//1216 1039//1091 +f 1178//1007 1191//1013 1177//1217 +f 1089//977 1109//983 1088//1218 +f 1037//1103 1071//1219 1038//1097 +f 1050//1073 1041//1079 1076//1211 +f 1157//1001 1178//1007 1158//1214 +f 1040//1085 1039//1091 1074//1220 +f 1170//1206 1150//1201 452//1221 +f 1264//1222 1071//1219 1263//1223 +f 1261//1224 1262//1225 1076//1211 +f 1085//1210 1076//1211 1262//1225 +f 1190//1207 1208//1226 405//1227 +f 509//176 526//519 1260//1228 +f 1260//1228 526//519 556//523 +f 167//201 556//523 595//202 +f 595//202 621//526 1255//200 +f 172//192 163//182 1254//199 +f 8//49 18//42 3//1229 +f 3//1229 18//42 1288//1230 +f 15//75 7//66 1240//82 +f 1250//50 8//49 3//1229 +f 1//32 1283//40 566//33 +f 593//3 566//33 9//41 +f 19//1231 20//34 33//25 +f 1243//2 636//89 593//3 +f 64//18 40//6 36//17 +f 1244//24 64//18 36//17 +f 641//579 614//582 1237//1232 +f 1250//50 1239//1233 4//48 +f 7//66 4//48 1239//1233 +f 5//74 14//73 11//81 +f 1240//82 7//66 1239//1233 +f 1//32 553//31 565//56 +f 593//3 9//41 1289//83 +f 18//42 20//34 1288//1230 +f 40//6 27//5 1252//16 +f 1249//58 6//65 565//56 +f 14//73 15//75 11//81 +f 592//57 1234//130 1233//58 +f 1237//1232 614//582 588//586 +f 1237//1232 588//586 605//592 +f 539//175 159//177 1259//1234 +f 164//257 1257//1235 168//251 +f 509//176 1256//1236 159//177 +f 1258//250 585//249 1259//1234 +f 169//1237 164//257 174//242 +f 191//236 208//230 185//1238 +f 1290//1239 207//229 640//777 +f 621//526 1292//1240 1255//200 +f 163//182 160//178 157//180 +f 1284//1241 1292//1240 648//227 +f 1252//16 27//5 12//95 +f 119//124 116//129 104//161 +f 116//129 88//135 1242//136 +f 87//159 666//713 715//160 +f 87//159 1241//1242 666//713 +f 1253//1243 47//150 631//152 +f 631//152 666//713 1253//1243 +f 86//142 74//144 60//143 +f 640//777 1291//1244 1290//1239 +f 1291//1244 640//777 613//248 +f 208//230 219//220 200//1245 +f 665//778 640//777 207//229 +f 1285//226 200//1245 219//220 +f 648//227 207//229 1284//1241 +f 691//228 665//778 207//229 +f 605//592 1236//1246 1245//1246 +f 1235//151 605//592 631//152 +f 1248//145 48//153 37//167 +f 667//708 1251//1247 1247//158 +f 605//592 1235//151 1236//1246 +f 641//579 1238//1248 1246//1249 +f 641//579 1237//1232 1238//1248 +f 404//412 391//405 1267//904 +f 1265//911 453//433 436//426 +f 328//351 327//350 331//910 +f 443//445 462//439 469//1250 +f 342//370 1275//1251 344//1252 +f 342//370 334//363 1275//1251 +f 372//480 385//473 384//906 +f 351//377 1271//1253 361//384 +f 351//377 350//1254 1271//1253 +f 337//1255 335//508 345//501 +f 384//906 385//473 396//466 +f 361//384 368//1256 369//391 +f 361//384 1271//1253 368//1256 +f 352//494 1276//1257 346//908 +f 397//1258 396//466 411//459 +f 342//370 350//1254 351//377 +f 342//370 344//1252 350//1254 +f 380//398 369//391 368//1256 +f 334//363 328//351 332//1259 +f 404//412 418//1260 419//419 +f 404//412 1268//905 418//1260 +f 426//452 1286//1261 1282//1262 +f 1282//1262 411//459 426//452 +f 352//494 362//487 1277//1263 +f 1277//1263 1276//1257 352//494 +f 391//405 380//398 381//1264 +f 426//452 443//445 444//1265 +f 444//1265 1286//1261 426//452 +f 362//487 372//480 373//907 +f 373//907 1277//1263 362//487 +f 1202//1209 1183//1212 1270//1266 +f 1116//1267 428//1268 1136//1215 +f 428//1268 1287//1269 1136//1215 +f 1073//1270 353//1271 1074//1220 +f 353//1271 363//1272 1074//1220 +f 353//1271 1073//1270 1279//1273 +f 1070//1208 1069//1203 1263//1223 +f 1274//1274 1069//1203 1088//1218 +f 1177//1217 1273//1275 1272//1276 +f 1272//1276 1158//1214 1177//1217 +f 428//1268 1116//1267 427//1277 +f 1088//1218 1108//1278 343//1279 +f 1103//1205 1085//1210 1278//1280 +f 1108//1278 1123//1204 1280//1281 +f 1123//1204 1281//1282 1280//1281 +f 1143//1202 1158//1214 360//1283 +f 1158//1214 1272//1276 360//1283 +f 1075//1213 1261//1224 1076//1211 +f 1085//1210 1262//1225 1278//1280 +f 1123//1204 1143//1202 1281//1282 +f 1143//1202 360//1283 1281//1282 +f 1074//1220 363//1272 1075//1213 +f 363//1272 1261//1224 1075//1213 +f 1270//1266 1183//1212 452//1221 +f 1266//1284 1150//1201 1136//1215 +f 1273//1275 1177//1217 1190//1207 +f 1208//1226 1202//1209 406//1285 +f 1202//1209 1269//1286 406//1285 +f 1072//1216 1071//1219 1264//1222 +f 1241//1242 1253//1243 666//713 +f 71//137 86//142 60//143 +f 88//135 86//142 71//137 +f 1245//1246 1237//1232 605//592 +f 119//124 104//161 90//119 +f 667//708 1246//1249 1251//1247 +f 621//526 648//227 1292//1240 +f 208//230 200//1245 185//1238 +f 174//242 191//236 169//1237 +f 1258//250 1291//1244 613//248 +f 1244//24 19//1231 33//25 +f 1288//1230 20//34 19//1231 +f 199//208 182//198 178//1287 +f 206//1288 218//214 190//1289 +f 1260//1228 556//523 167//201 +f 157//180 1254//199 163//182 +f 178//1287 182//198 1254//199 +f 218//214 206//1288 1285//226 +f 161//258 1257//1235 158//179 +f 324//345 312//274 323//336 +f 303//317 302//323 316//338 +f 305//305 304//311 318//340 +f 304//311 303//317 317//339 +f 322//347 309//281 321//341 +f 320//346 307//293 319//342 +f 301//329 311//335 314//344 +f 302//323 301//329 315//337 +f 311//335 312//274 313//343 +f 319//342 306//299 318//340 +f 321//341 308//287 320//346 +f 323//336 310//275 322//347 +f 418//1260 435//909 419//419 +f 337//1255 331//910 335//508 +f 469//1250 462//439 1265//911 +f 1137//1049 1136//1215 1150//1201 +f 1143//1202 1123//1204 1122//989 +f 1089//977 1088//1218 1069//1203 +f 1123//1204 1108//1278 1109//983 +f 1103//1205 1116//1267 1117//1055 +f 1170//1206 1183//1212 1184//1031 +f 1209//1019 1208//1226 1190//1207 +f 1053//971 1069//1203 1070//1208 +f 1070//1208 1071//1219 1037//1103 +f 1202//1209 1208//1226 1209//1019 +f 1085//1210 1103//1205 1096//1061 +f 1076//1211 1085//1210 1066//1067 +f 1183//1212 1202//1209 1203//1025 +f 1040//1085 1074//1220 1075//1213 +f 1151//1043 1150//1201 1170//1206 +f 1158//1214 1143//1202 1142//995 +f 1117//1055 1116//1267 1136//1215 +f 1072//1216 1073//1270 1039//1091 +f 1191//1013 1190//1207 1177//1217 +f 1109//983 1108//1278 1088//1218 +f 1071//1219 1072//1216 1038//1097 +f 1041//1079 1075//1213 1076//1211 +f 1178//1007 1177//1217 1158//1214 +f 1039//1091 1073//1270 1074//1220 +f 1150//1201 1266//1284 452//1221 +f 1071//1219 1070//1208 1263//1223 +f 1208//1226 406//1285 405//1227 +f 1256//1236 509//176 1260//1228 +f 1257//1235 161//258 168//251 +f 585//249 539//175 1259//1234 +f 715//160 667//708 1247//158 +f 667//708 641//579 1246//1249 +f 435//909 1265//911 436//426 +f 332//1259 328//351 331//910 +f 444//1265 443//445 469//1250 +f 346//908 337//1255 345//501 +f 397//1258 384//906 396//466 +f 1282//1262 397//1258 411//459 +f 381//1264 380//398 368//1256 +f 1275//1251 334//363 332//1259 +f 1267//904 391//405 381//1264 +f 1269//1286 1202//1209 1270//1266 +f 1073//1270 1072//1216 1279//1273 +f 1069//1203 1274//1274 1263//1223 +f 343//1279 1274//1274 1088//1218 +f 1116//1267 1103//1205 427//1277 +f 1108//1278 1280//1281 343//1279 +f 427//1277 1103//1205 1278//1280 +f 1183//1212 1170//1206 452//1221 +f 1287//1269 1266//1284 1136//1215 +f 405//1227 1273//1275 1190//1207 +f 1279//1273 1072//1216 1264//1222 +f 191//236 185//1238 169//1237 +f 190//1289 199//208 178//1287 +f 218//214 199//208 190//1289 diff --git a/A4/resources/vert.glsl b/A4/resources/vert.glsl new file mode 100644 index 0000000..ab647c8 --- /dev/null +++ b/A4/resources/vert.glsl @@ -0,0 +1,24 @@ +#version 120 + +uniform mat4 P; +uniform mat4 MV; +uniform mat4 MVL; +uniform vec3 lightPos1; +uniform vec3 lightPos2; +uniform float i1; +uniform float i2; + +attribute vec4 aPos; // in object space +attribute vec3 aNor; // in object space + +varying vec3 color; // Pass to fragment shader +varying vec4 p; +varying vec4 n; + +void main() +{ + gl_Position = P * MV * aPos; + p = MV * aPos; + n = MV * vec4(aNor, 0.0); + color = vec3(0.5, 0.5, 0.5); +} diff --git a/A4/shadow8t4.zip b/A4/shadow8t4.zip new file mode 100644 index 0000000..d0b1376 Binary files /dev/null and b/A4/shadow8t4.zip differ diff --git a/A4/shadow8t4/shadow8t4/CMakeLists.txt b/A4/shadow8t4/shadow8t4/CMakeLists.txt new file mode 100644 index 0000000..a21deb5 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/CMakeLists.txt @@ -0,0 +1,127 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +# Name of the project +PROJECT(A4) + +# FOR LAB MACHINES ONLY! +# DO NOT EDIT +SET(DEF_DIR_GLM "C:\\c++\\glm") +SET(DEF_DIR_GLFW "C:\\c++\\glfw-3.2.1") +SET(DEF_DIR_GLEW "C:\\c++\\glew-2.0.0") + +# Is this the solution? +# Override with `cmake -DSOL=ON ..` +OPTION(SOL "Solution" OFF) + +# Use glob to get the list of all source files. +# We don't really need to include header and resource files to build, but it's +# nice to have them also show up in IDEs. +IF(${SOL}) + FILE(GLOB_RECURSE SOURCES "src0/*.cpp") + FILE(GLOB_RECURSE HEADERS "src0/*.h") + FILE(GLOB_RECURSE GLSL "resources0/*.glsl") +ELSE() + FILE(GLOB_RECURSE SOURCES "src/*.cpp") + FILE(GLOB_RECURSE HEADERS "src/*.h") + FILE(GLOB_RECURSE GLSL "resources/*.glsl") +ENDIF() + +# Set the executable. +ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCES} ${HEADERS} ${GLSL}) + +# Get the GLM environment variable. Since GLM is a header-only library, we +# just need to add it to the include directory. +SET(GLM_INCLUDE_DIR "$ENV{GLM_INCLUDE_DIR}") +IF(NOT GLM_INCLUDE_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLM_INCLUDE_DIR to the root directory of your GLM installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLM in ${DEF_DIR_GLM}") + IF(IS_DIRECTORY ${DEF_DIR_GLM}) + MESSAGE(STATUS "Found!") + SET(GLM_INCLUDE_DIR ${DEF_DIR_GLM}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +INCLUDE_DIRECTORIES(${GLM_INCLUDE_DIR}) + +# Get the GLFW environment variable. There should be a CMakeLists.txt in the +# specified directory. +SET(GLFW_DIR "$ENV{GLFW_DIR}") +IF(NOT GLFW_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLFW_DIR to the root directory of your GLFW installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLFW in ${DEF_DIR_GLFW}") + IF(IS_DIRECTORY ${DEF_DIR_GLFW}) + MESSAGE(STATUS "Found!") + SET(GLFW_DIR ${DEF_DIR_GLFW}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +OPTION(GLFW_BUILD_EXAMPLES "GLFW_BUILD_EXAMPLES" OFF) +OPTION(GLFW_BUILD_TESTS "GLFW_BUILD_TESTS" OFF) +OPTION(GLFW_BUILD_DOCS "GLFW_BUILD_DOCS" OFF) +IF(CMAKE_BUILD_TYPE MATCHES Release) + ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/release) +ELSE() + ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/debug) +ENDIF() +INCLUDE_DIRECTORIES(${GLFW_DIR}/include) +TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} glfw ${GLFW_LIBRARIES}) + +# Get the GLEW environment variable. +SET(GLEW_DIR "$ENV{GLEW_DIR}") +IF(NOT GLEW_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLEW_DIR to the root directory of your GLEW installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLEW in ${DEF_DIR_GLEW}") + IF(IS_DIRECTORY ${DEF_DIR_GLEW}) + MESSAGE(STATUS "Found!") + SET(GLEW_DIR ${DEF_DIR_GLEW}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +INCLUDE_DIRECTORIES(${GLEW_DIR}/include) +IF(WIN32) + # With prebuilt binaries + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/Release/Win32/glew32s.lib) +ELSE() + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/libGLEW.a) +ENDIF() + +# OS specific options and libraries +IF(WIN32) + # c++11 is enabled by default. + # -Wall produces way too many warnings. + # -pedantic is not supported. + # Disable warning 4996. + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996") + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} opengl32.lib) +ELSE() + # Enable all pedantic warnings. + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic") + IF(APPLE) + # Add required frameworks for GLFW. + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo") + ELSE() + #Link the Linux OpenGL library + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "GL") + ENDIF() +ENDIF() diff --git a/A4/shadow8t4/shadow8t4/README.txt b/A4/shadow8t4/shadow8t4/README.txt new file mode 100644 index 0000000..880295f --- /dev/null +++ b/A4/shadow8t4/shadow8t4/README.txt @@ -0,0 +1,7 @@ +Alexander Huddleston + +I downloaded the code from the lab pages and worked from there. + +I added a large flat cube as a "ground" but didn't texture it because I was tired of looking at a white abyss and thought this would make it look a little bit better. + +I didn't notice you implemented a "toggle key" functionality in the main and instead coded if statements in the char callback to do what I wanted. The functionality remains the same, but I thought it was worth noting. diff --git a/A4/shadow8t4/shadow8t4/resources/.frag.glsl b/A4/shadow8t4/shadow8t4/resources/.frag.glsl new file mode 100644 index 0000000..8b8b1de --- /dev/null +++ b/A4/shadow8t4/shadow8t4/resources/.frag.glsl @@ -0,0 +1,17 @@ +#version 120 + +uniform vec3 lightPos; +uniform vec3 ka; +uniform vec3 kd; +uniform vec3 ks; +uniform float s; + +varying vec3 n; // passed from the vertex shader +varying vec3 p; // passed from the vertex shader + +void main() +{ + n = normalize(normal); + vec3 color = 0.5 * (n + 1.0); + gl_FragColor = vec4(color.r, color.g, color.b, 1.0); +} diff --git a/A4/shadow8t4/shadow8t4/resources/.vert.glsl b/A4/shadow8t4/shadow8t4/resources/.vert.glsl new file mode 100644 index 0000000..ac83524 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/resources/.vert.glsl @@ -0,0 +1,17 @@ +#version 120 + +uniform mat4 P; +uniform mat4 MV; + +attribute vec4 aPos; // in object space +attribute vec3 aNor; // in object space + +varying vec3 p; // passed to fragment shader +varying vec3 n; // passed to fragment shader + +void main() +{ + ugl_Position = P * MV * aPos; + p = MV * aPos; + n = MV * aNor; +} diff --git a/A4/shadow8t4/shadow8t4/resources/bunny.obj b/A4/shadow8t4/shadow8t4/resources/bunny.obj new file mode 100644 index 0000000..de3f190 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/resources/bunny.obj @@ -0,0 +1,9977 @@ +# Blender v2.72 (sub 0) OBJ File: '' +# www.blender.org +v -0.865619 1.424919 0.084327 +v -0.896984 1.397126 0.137748 +v -0.894910 1.439258 0.124885 +v -0.863675 1.090654 0.119807 +v -0.859114 1.096879 0.076583 +v -0.870559 1.056276 0.097651 +v -0.263037 1.251888 0.173930 +v -0.273832 1.232426 0.216589 +v -0.258513 1.218295 0.260797 +v -0.727772 1.785447 -0.482088 +v -0.720838 1.749985 -0.419303 +v -0.677382 1.772887 -0.503759 +v -0.313589 1.214098 0.259711 +v -0.285960 1.190116 0.298882 +v -0.609024 0.434295 0.426785 +v -0.569010 0.454370 0.432370 +v -0.603813 0.459214 0.400887 +v -0.017977 1.311728 0.163607 +v -0.080841 1.303054 0.168723 +v -0.034102 1.303196 0.217544 +v -0.560108 1.538166 0.253693 +v -0.566276 1.527061 0.296291 +v -0.544542 1.529770 0.225052 +v -0.837366 0.767718 0.089586 +v -0.848639 0.783921 0.164620 +v -0.862046 0.809307 0.105354 +v -0.686026 1.499228 -0.400513 +v -0.694130 1.512185 -0.445385 +v -0.667007 1.523678 -0.452664 +v -0.888126 0.877655 0.142266 +v -0.896123 0.915999 0.178123 +v -0.893987 0.895390 0.116456 +v 0.584400 0.702008 0.177796 +v 0.573451 0.694827 0.211535 +v 0.583924 0.667412 0.219795 +v -0.336740 1.777445 -0.081799 +v -0.395199 1.738585 -0.075752 +v -0.355263 1.759556 -0.048676 +v -0.089889 1.295227 0.220268 +v -0.812574 0.730252 0.071021 +v -0.837405 0.772403 0.046673 +v -0.703597 1.690699 -0.261442 +v -0.727592 1.696591 -0.270134 +v -0.694385 1.647993 -0.172187 +v -0.638757 1.614009 -0.200642 +v -0.649590 1.585202 -0.125953 +v -0.633084 1.566061 -0.138388 +v -0.643710 1.729621 -0.492256 +v -0.665466 1.717112 -0.421277 +v -0.639263 1.679244 -0.407304 +v -0.506872 0.359359 -0.123808 +v -0.478720 0.341363 -0.154182 +v -0.514998 0.337291 -0.120825 +v -0.679838 1.697478 -0.316275 +v -0.709198 1.713669 -0.327637 +v -0.658081 1.676434 -0.305586 +v -0.691360 1.724784 -0.390133 +v -0.693726 1.606178 -0.091905 +v -0.708636 1.613653 -0.097324 +v -0.671322 1.570945 -0.062032 +v -0.726526 1.656792 -0.182125 +v -0.294283 0.931666 -0.249318 +v -0.330484 0.959586 -0.234264 +v -0.281229 0.993224 -0.235801 +v -0.152271 1.278488 0.215452 +v -0.201106 1.250454 0.235883 +v -0.162313 1.238294 0.295770 +v -0.929895 1.309231 0.199193 +v -0.905494 1.351187 0.216806 +v -0.922326 1.319540 0.154307 +v -0.078163 1.282121 -0.019430 +v -0.134939 1.288244 0.059691 +v -0.031074 1.307290 0.056429 +v -0.709618 0.343457 -0.007837 +v -0.703852 0.374503 -0.009319 +v -0.687962 0.351177 -0.052067 +v -0.917151 1.170996 0.308094 +v -0.927365 1.207309 0.326928 +v -0.924992 1.213150 0.292562 +v -0.843354 0.807299 0.221805 +v -0.860345 0.826457 0.195427 +v -0.107365 1.299029 0.109938 +v -0.056009 1.307667 0.105161 +v -0.374165 0.476821 -0.171473 +v -0.376138 0.495348 -0.116261 +v -0.355627 0.493999 -0.128650 +v -0.766552 1.550977 0.079687 +v -0.790400 1.553745 0.151418 +v -0.736967 1.561301 0.143598 +v -0.679454 1.149360 -0.095107 +v -0.708723 1.161164 -0.079564 +v -0.673908 1.188969 -0.087301 +v -0.893190 0.995470 0.134181 +v -0.874051 1.059399 0.136459 +v -0.030471 1.291945 -0.010688 +v -0.883609 1.499671 0.260442 +v -0.832990 1.496077 0.337409 +v -0.865377 1.515480 0.258754 +v -0.012189 0.962017 0.538159 +v 0.040479 0.958174 0.529368 +v 0.030802 0.983074 0.505357 +v -0.814967 1.547310 0.196974 +v -0.770043 1.552128 0.245348 +v -0.942971 1.261774 0.192247 +v -0.932812 1.269109 0.135050 +v 0.023930 1.316271 0.119551 +v -0.741082 1.735573 -0.379868 +v -0.234595 1.261539 0.166138 +v -0.812642 1.538117 0.258979 +v -0.817192 1.525015 0.296561 +v 0.009684 1.306430 0.025866 +v 0.035766 1.313898 0.072086 +v -0.821915 0.756102 0.165426 +v -0.816275 0.734706 0.111617 +v -0.672166 1.617134 -0.137337 +v -0.633133 1.650326 -0.328951 +v -0.900093 1.327808 0.059221 +v -0.887462 1.362558 0.071478 +v -0.874391 1.337488 0.023975 +v 0.065112 1.300252 0.009288 +v 0.113480 0.982438 -0.230242 +v 0.152357 0.949779 -0.244371 +v 0.104643 0.961805 -0.258990 +v -0.689402 1.565278 -0.019716 +v -0.722233 1.589674 -0.054242 +v -0.108662 1.269170 0.275755 +v -0.744886 1.564944 -0.025954 +v -0.737481 1.553925 0.023492 +v 0.024919 1.298356 0.248471 +v -0.042439 1.291490 0.258292 +v -0.015539 1.275472 0.292329 +v -0.886313 0.948812 0.079338 +v -0.894955 0.956324 0.142348 +v -0.888923 0.992091 0.095703 +v -0.754058 1.683907 -0.267930 +v -0.884692 1.112429 0.126792 +v -0.905579 1.127599 0.161410 +v -0.905939 1.137309 0.102768 +v -0.065865 1.264172 0.302264 +v -0.046019 1.242854 0.334720 +v -0.507183 1.527630 0.118167 +v -0.502423 1.577375 0.093945 +v -0.524202 1.531010 0.129274 +v -0.931765 1.182102 0.233624 +v -0.942436 1.220743 0.235685 +v -0.936442 1.178938 0.186621 +v -0.809005 1.255871 0.521554 +v -0.790038 1.285055 0.531494 +v -0.814555 1.301221 0.521177 +v -0.770567 1.319347 0.524625 +v -0.797790 1.344889 0.509903 +v -0.714483 1.810530 -0.554785 +v -0.741587 1.798728 -0.507947 +v -0.703815 1.807118 -0.531726 +v -0.789356 1.481723 0.394631 +v -0.789317 1.509306 0.351519 +v -0.473112 1.629604 0.060741 +v -0.518397 1.606204 0.071422 +v -0.572648 1.550625 0.193225 +v -0.922690 1.147516 0.170174 +v -0.780815 1.235194 0.521370 +v -0.784365 1.392801 0.483294 +v -0.772561 1.456585 0.431230 +v -0.809450 1.390357 0.473591 +v -0.595756 1.547240 0.263733 +v -0.600528 1.528035 0.328877 +v -0.742941 1.635685 -0.155342 +v -0.312179 0.438475 0.497809 +v -0.311729 0.402943 0.513125 +v -0.264720 0.450345 0.512195 +v -0.915565 1.319626 0.106382 +v -0.528317 0.702989 -0.148649 +v -0.550659 0.780892 -0.197555 +v -0.510255 0.757051 -0.181869 +v -0.639209 1.277424 -0.085494 +v -0.705951 1.299483 -0.087629 +v -0.684664 1.349815 -0.083360 +v -0.564730 1.577841 0.081787 +v -0.576845 1.556170 0.129831 +v -0.546424 1.552296 0.126124 +v -0.757182 1.252273 0.530873 +v -0.759832 1.382080 0.492166 +v 0.435148 0.915199 -0.026468 +v 0.414389 0.923651 -0.074587 +v 0.411181 0.974913 -0.039757 +v -0.861804 0.825722 0.063639 +v -0.867764 0.843449 0.124190 +v -0.256611 1.256267 0.045538 +v -0.235069 1.267201 0.109969 +v -0.890862 0.923771 0.105699 +v -0.943804 1.218392 0.179044 +v -0.644570 1.534289 -0.051180 +v 0.077390 1.314750 0.116830 +v 0.059106 1.314093 0.168238 +v -0.740339 1.440689 0.449950 +v -0.525136 0.475779 0.148584 +v -0.502905 0.490989 0.171648 +v -0.508873 0.527279 0.144558 +v 0.084211 1.309099 0.062755 +v -0.765658 1.167404 0.514894 +v -0.738801 1.209164 0.533958 +v -0.726659 1.300558 0.516682 +v -0.744718 1.350747 0.506889 +v -0.148243 0.872889 -0.383171 +v -0.130990 0.907760 -0.366593 +v -0.093570 0.854237 -0.381125 +v -0.399380 1.492285 0.016017 +v -0.369928 1.506393 -0.020372 +v -0.351005 1.520344 -0.001328 +v -0.923319 1.252389 0.091590 +v -0.883992 1.389900 0.106407 +v -0.867947 1.385069 0.045576 +v -0.383364 0.545035 -0.109053 +v -0.386236 0.583033 -0.115057 +v -0.352626 0.552849 -0.105451 +v -0.322579 0.881926 -0.251309 +v -0.367563 0.886634 -0.238688 +v -0.730011 1.182671 0.530346 +v -0.752605 1.493861 0.391760 +v -0.725671 1.475323 0.417141 +v -0.870414 1.305893 0.009116 +v -0.895597 1.285167 0.045458 +v -0.880914 0.877416 0.048490 +v -0.610843 1.338619 -0.072249 +v -0.651561 1.403454 -0.076848 +v -0.615304 1.403763 -0.062734 +v -0.708314 1.225442 0.532749 +v -0.726470 1.409894 0.469767 +v -0.748982 1.145886 0.507765 +v -0.722539 1.153955 0.516703 +v -0.615694 1.708488 -0.616791 +v -0.615176 1.751745 -0.606317 +v -0.609654 1.700211 -0.608394 +v -0.872652 0.921100 0.042059 +v -0.309802 1.663466 -0.162411 +v -0.234558 1.682473 -0.188229 +v -0.285356 1.620848 -0.147860 +v 0.430151 0.976910 0.010258 +v 0.412588 1.036108 0.026761 +v 0.432182 0.994867 0.050153 +v 0.503181 0.527864 -0.034166 +v 0.528542 0.518987 -0.006207 +v 0.514338 0.484852 0.010401 +v -0.340704 1.614897 -0.137869 +v -0.656969 1.456163 -0.189747 +v -0.636167 1.480137 -0.201702 +v -0.628968 1.469478 -0.130986 +v 0.037667 1.124055 0.414947 +v 0.066533 1.167356 0.387164 +v 0.008090 1.163332 0.401676 +v 0.459418 0.481388 -0.038716 +v 0.407514 1.055473 0.075074 +v 0.428790 1.009378 0.094753 +v 0.545499 0.560446 -0.006616 +v -0.531988 1.367290 -0.016580 +v -0.503648 1.371576 0.019526 +v -0.505394 1.333666 -0.010872 +v -0.162731 1.284451 0.166836 +v 0.036232 1.307679 0.211686 +v -0.693685 0.952428 0.421290 +v -0.704569 1.009878 0.397941 +v -0.734402 0.954126 0.402107 +v -0.701128 1.179035 0.527142 +v 0.013773 0.523027 0.531490 +v 0.020657 0.501047 0.522902 +v 0.036285 0.531986 0.534227 +v -0.687008 1.446354 0.430417 +v 0.495757 0.438159 0.145830 +v 0.427191 0.399771 0.089322 +v 0.466933 0.424653 0.065650 +v 0.573065 0.599446 0.018886 +v 0.574217 0.560122 0.040246 +v 0.449602 0.809426 0.006112 +v 0.455112 0.869530 0.038866 +v 0.462527 0.773739 0.069141 +v -0.600678 0.414195 0.229533 +v -0.553528 0.429362 0.191355 +v -0.611257 0.377900 0.197109 +v -0.863964 1.047936 0.059821 +v -0.843142 1.095726 0.037097 +v -0.834897 1.072473 0.007579 +v -0.751150 0.665570 0.102441 +v -0.771684 0.698264 0.050606 +v -0.745304 0.666807 0.046953 +v -0.672320 0.991739 0.415939 +v -0.676910 1.073414 0.380185 +v -0.721420 1.053668 0.375232 +v -0.693824 1.086578 0.375078 +v -0.066211 0.904152 0.568798 +v -0.012439 0.890932 0.565521 +v -0.056222 0.932350 0.558936 +v 0.094076 0.903280 0.542141 +v 0.134144 0.930737 0.514678 +v 0.095105 0.954839 0.509106 +v 0.064598 0.602974 0.547800 +v 0.026645 0.627000 0.565252 +v 0.032514 0.598286 0.554643 +v -0.681451 1.274868 0.501490 +v -0.683693 1.228929 0.524379 +v 0.468345 0.743541 0.101395 +v 0.462809 0.787020 0.147863 +v -0.918220 1.274735 0.364587 +v -0.903369 1.311983 0.381388 +v -0.903770 1.325249 0.310827 +v -0.885859 1.460587 0.098780 +v -0.856097 1.471251 0.065981 +v -0.007816 1.282292 -0.032490 +v 0.043156 1.278256 0.286469 +v -0.649846 1.037155 0.406478 +v -0.647316 1.541007 -0.404648 +v -0.652837 1.559245 -0.498659 +v -0.630699 1.589747 -0.429518 +v 0.003770 0.449358 0.465199 +v -0.006336 0.471931 0.491369 +v -0.070013 0.464165 0.474856 +v 0.073430 1.209819 0.359735 +v 0.060412 1.249436 0.326529 +v 0.034831 1.200263 0.369120 +v -0.497474 1.411252 0.052938 +v -0.480236 1.442665 0.042499 +v -0.484686 1.455961 0.083662 +v -0.942377 1.261542 0.222015 +v -0.498964 1.467086 -0.018614 +v -0.443418 1.511381 -0.056860 +v -0.437557 1.477341 -0.021433 +v 0.447178 0.948027 0.120247 +v 0.451338 0.936307 0.062337 +v 0.459185 0.870362 0.084236 +v -0.141697 1.276789 0.013081 +v -0.882842 0.868691 0.081029 +v 0.123194 1.290377 0.013336 +v -0.149302 0.386435 0.293783 +v -0.181599 0.393223 0.394029 +v -0.208143 0.384010 0.278684 +v 0.080724 0.515741 0.517736 +v 0.092232 0.441251 0.450574 +v 0.059862 0.466891 0.490736 +v 0.049305 0.419827 0.457234 +v 0.607788 0.616466 0.104640 +v 0.598372 0.664232 0.085140 +v 0.600787 0.681293 0.114545 +v 0.552579 0.514163 0.032063 +v -0.644003 1.583440 -0.542563 +v -0.642495 1.604502 -0.570414 +v -0.619459 1.647924 -0.566476 +v -0.682824 0.923768 0.423887 +v -0.679028 0.878172 0.435270 +v -0.655924 0.910424 0.440921 +v 0.168328 1.033749 0.452873 +v 0.206573 1.041683 0.430047 +v 0.150050 1.072690 0.418120 +v 0.035078 0.863395 0.570483 +v 0.047990 0.916548 0.547152 +v 0.078153 0.550507 0.527503 +v 0.051982 0.570180 0.534235 +v -0.676765 1.415032 0.438682 +v -0.656918 1.496182 0.381610 +v 0.442038 0.852043 -0.021170 +v 0.446311 0.841784 0.008267 +v 0.421069 0.815332 -0.066691 +v -0.307713 1.256407 0.165948 +v 0.136776 1.296726 0.069328 +v 0.193204 1.273835 0.112963 +v 0.192627 1.268939 0.055552 +v -0.639398 0.786218 0.420835 +v -0.649922 0.845509 0.441201 +v -0.704912 0.818182 0.406099 +v -0.699373 0.860769 0.421757 +v -0.640280 0.978387 0.425653 +v 0.432644 0.758105 -0.038844 +v 0.456200 0.746844 0.026074 +v -0.004402 0.583434 0.544834 +v -0.008548 0.605935 0.558248 +v -0.043083 0.614186 0.556885 +v 0.096509 1.010878 0.473731 +v 0.051450 1.016390 0.454230 +v 0.071936 0.988595 0.484195 +v 0.041934 0.729152 0.562987 +v 0.076963 0.723756 0.560622 +v 0.055681 0.763971 0.563272 +v -0.249391 1.703113 -0.113297 +v -0.315821 1.664185 -0.057320 +v -0.303514 1.644816 -0.053291 +v -0.046247 0.577596 0.539907 +v -0.043091 0.544675 0.539083 +v -0.243664 1.769327 -0.117196 +v -0.300716 1.725832 -0.063597 +v -0.301344 1.701132 -0.073591 +v -0.514585 0.558782 0.159004 +v -0.544637 0.553575 0.103268 +v -0.452255 1.293546 0.203775 +v -0.465485 1.332077 0.168897 +v -0.477656 1.330197 0.228740 +v -0.837022 1.222638 -0.037301 +v -0.792375 1.205542 -0.056745 +v -0.824716 1.162413 -0.023236 +v -0.624332 0.840353 0.442031 +v -0.626151 0.911269 0.450907 +v -0.590588 1.004126 0.427251 +v 0.433155 0.521455 0.324921 +v 0.437854 0.488037 0.313434 +v 0.477358 0.527510 0.307973 +v -0.194089 1.704110 -0.209948 +v -0.146559 1.745654 -0.259727 +v -0.138955 1.678717 -0.218972 +v -0.014985 0.559255 0.546308 +v -0.620960 1.638832 -0.583859 +v 0.340239 1.135388 0.245953 +v 0.333739 1.122789 0.277881 +v 0.375530 1.068529 0.263035 +v -0.601171 0.955529 0.441838 +v -0.606525 1.046720 0.409064 +v -0.637824 1.103727 0.375798 +v 0.384973 0.480624 0.317375 +v 0.379928 0.497932 0.319020 +v 0.355154 0.504496 0.314398 +v -0.562151 1.413921 -0.028027 +v -0.530434 1.409255 -0.004741 +v -0.894808 1.383998 0.250615 +v -0.907955 1.385523 0.205626 +v -0.902417 1.357599 0.141492 +v -0.205426 1.197952 0.330037 +v 0.254570 0.394839 -0.040251 +v 0.290078 0.373582 -0.002747 +v 0.221929 0.367753 -0.020919 +v -0.621261 0.628454 -0.045202 +v -0.595207 0.610403 -0.023754 +v -0.646442 0.617232 0.002255 +v -0.589222 0.775455 0.429614 +v -0.598672 0.805405 0.432771 +v -0.594986 0.888455 0.451093 +v -0.589974 0.920307 0.453353 +v 0.097163 1.052351 0.436038 +v -0.579817 1.094315 0.379977 +v 0.076406 0.864272 0.561179 +v -0.685439 1.751301 -0.571879 +v -0.660702 1.655782 -0.586441 +v -0.676845 1.653363 -0.554664 +v -0.578619 0.839444 0.441860 +v -0.566237 0.963222 0.436679 +v -0.591959 1.132080 0.362347 +v -0.002426 0.545360 0.546412 +v -0.038450 0.847878 0.571980 +v -0.748528 1.499311 -0.277529 +v -0.745775 1.516404 -0.286480 +v -0.731102 1.484717 -0.287484 +v 0.423130 0.590991 0.308484 +v 0.406359 0.615749 0.298413 +v 0.386863 0.564506 0.311889 +v 0.042516 1.052374 0.425636 +v -0.657666 0.364695 -0.072073 +v -0.684706 0.374777 -0.049557 +v -0.666349 0.404303 -0.050181 +v -0.569310 0.881015 0.446929 +v 0.106297 0.467118 0.464720 +v -0.465496 0.676521 0.396358 +v -0.477145 0.619445 0.367058 +v -0.444894 0.610777 0.395453 +v -0.691037 1.555948 0.016371 +v -0.319517 1.251839 0.194006 +v -0.540881 0.397812 -0.105447 +v -0.623743 0.401461 -0.074040 +v -0.507512 0.431096 -0.100187 +v -0.590000 0.737515 0.411971 +v -0.551114 0.746878 0.419398 +v -0.556237 0.921874 0.450550 +v -0.553090 1.036539 0.415167 +v 0.052930 0.680060 0.556705 +v 0.052848 1.094366 0.416750 +v 0.011760 1.093253 0.426628 +v -0.623456 1.474550 -0.076600 +v -0.619962 1.476148 -0.043257 +v -0.630566 1.434165 -0.074907 +v 0.119783 1.040363 0.453963 +v -0.026844 0.512474 0.531868 +v 0.024095 1.001678 0.469381 +v -0.710482 1.516109 -0.446792 +v -0.696056 1.549076 -0.501886 +v -0.669163 1.227891 -0.089077 +v -0.618976 1.229707 -0.087725 +v -0.552383 0.819994 0.449848 +v -0.549969 1.077420 0.394246 +v -0.001042 0.768819 0.581908 +v -0.020578 0.809983 0.575539 +v -0.059406 0.790382 0.579698 +v 0.605949 0.616772 0.155916 +v 0.607290 0.658066 0.139748 +v 0.600936 0.656934 0.185333 +v -0.528021 0.413199 0.461698 +v -0.571805 0.409188 0.463013 +v -0.364521 1.219987 0.276707 +v -0.307702 1.159731 0.328588 +v -0.650598 1.345210 -0.080900 +v -0.658107 1.435912 -0.125854 +v -0.682146 1.439093 -0.149841 +v -0.548769 0.702823 0.388282 +v -0.540004 0.805684 0.446015 +v -0.536167 0.853468 0.453325 +v -0.549942 0.996408 0.429552 +v -0.542014 1.145173 0.348440 +v 0.456369 0.574026 0.319922 +v 0.407755 0.545575 0.320147 +v 0.214417 0.913550 0.480434 +v 0.206393 0.966025 0.469710 +v 0.169735 0.971066 0.474409 +v -0.527224 0.447228 0.441433 +v 0.372496 0.375099 0.148158 +v 0.356060 0.365266 0.098155 +v -0.551741 0.483839 0.385178 +v -0.597105 0.365358 -0.094949 +v -0.531213 0.779124 0.433349 +v -0.529356 0.909135 0.445689 +v -0.078037 0.501693 0.509887 +v 0.132430 0.967382 0.487502 +v 0.134871 1.007642 0.474543 +v 0.461836 0.619101 0.302234 +v 0.460866 0.664739 0.268090 +v 0.209252 0.863114 0.494331 +v 0.178694 0.908986 0.487130 +v 0.429158 0.667077 0.269947 +v 0.430231 0.637958 0.280392 +v 0.457192 0.694894 0.235494 +v 0.529880 0.477477 0.050420 +v 0.569080 0.515781 0.072538 +v 0.567306 0.505157 0.106271 +v 0.203192 1.004196 0.457605 +v -0.409172 0.461218 -0.179426 +v -0.374202 0.454285 -0.242268 +v -0.421505 0.433440 -0.215087 +v -0.509804 1.348661 0.275850 +v -0.476566 1.307752 0.255236 +v -0.085308 0.601594 0.553090 +v -0.126196 0.616350 0.544241 +v -0.119876 0.574932 0.527524 +v -0.289509 0.392859 0.533091 +v -0.297487 0.365398 0.524933 +v -0.500270 0.813113 0.442642 +v -0.519010 0.954576 0.439377 +v -0.519964 0.997078 0.427166 +v -0.507494 1.092868 0.382976 +v -0.497974 1.134210 0.351179 +v -0.057500 0.654890 0.561734 +v -0.001129 0.692882 0.565798 +v -0.050025 0.696550 0.568925 +v 0.201313 1.073278 0.403239 +v 0.196592 1.123622 0.375453 +v 0.151372 1.157149 0.370320 +v 0.392187 1.066925 0.204502 +v 0.371765 1.106440 0.188113 +v -0.507457 0.761484 0.431376 +v -0.514957 1.049674 0.403472 +v 0.027381 0.791057 0.567192 +v 0.089404 1.071064 0.412434 +v -0.526556 0.484942 0.387312 +v -0.491866 0.464112 0.411700 +v -0.497544 0.497383 0.370371 +v -0.490008 0.862217 0.453521 +v -0.503722 0.888447 0.451880 +v -0.488090 0.910839 0.444567 +v 0.129813 1.136637 0.383030 +v -0.001225 0.932011 0.553984 +v -0.021452 1.114329 0.424366 +v -0.618959 1.542425 -0.190186 +v -0.621651 1.566685 -0.178377 +v -0.622785 1.516660 -0.146727 +v -0.499603 0.431019 0.444627 +v 0.591199 0.631288 0.215618 +v -0.677514 1.460521 -0.233333 +v -0.688669 1.472334 -0.287398 +v -0.664679 1.487154 -0.315793 +v -0.491873 1.045201 0.403014 +v 0.466612 0.547192 0.319768 +v -0.773827 1.534660 0.308950 +v -0.752693 1.523295 0.343741 +v -0.539930 1.449866 -0.011093 +v -0.502714 1.433656 0.015153 +v -0.725397 0.353993 0.070299 +v -0.720160 0.375727 0.039789 +v -0.714981 0.344530 0.042027 +v -0.486180 0.964527 0.441831 +v -0.475904 1.008118 0.423492 +v 0.348384 0.431534 0.289543 +v 0.324340 0.453340 0.303168 +v -0.029935 0.721864 0.581672 +v -0.063735 0.721843 0.579730 +v -0.035439 0.426598 0.475415 +v -0.065174 0.450362 0.475028 +v -0.149812 0.425714 0.514045 +v -0.473789 0.484567 0.391268 +v -0.466862 0.545707 0.375874 +v -0.503993 0.518313 0.340374 +v -0.474018 0.755503 0.426302 +v -0.494959 0.734363 0.416736 +v -0.474969 1.063566 0.401657 +v -0.459667 1.090514 0.387541 +v -0.661781 1.421835 -0.093766 +v -0.637554 1.442888 -0.113957 +v -0.440717 0.510582 0.389778 +v -0.453765 0.823835 0.432821 +v -0.456811 0.849880 0.441595 +v -0.445146 0.948604 0.429725 +v -0.454116 0.910021 0.432528 +v -0.914905 1.454318 0.222772 +v -0.908501 1.462561 0.148091 +v -0.917576 1.433459 0.177907 +v 0.091007 0.484745 0.493532 +v -0.437200 1.682274 0.023425 +v -0.445904 0.437980 0.426855 +v -0.444341 0.876545 0.434776 +v -0.458516 1.207298 0.276651 +v -0.490201 1.177129 0.315814 +v -0.110968 1.820232 -0.280424 +v -0.102445 1.789583 -0.295388 +v -0.121720 1.812510 -0.290611 +v 0.000268 1.044673 0.437759 +v -0.674477 1.550768 -0.515942 +v -0.667137 1.535882 -0.490971 +v -0.466535 1.591782 0.078019 +v -0.902057 1.494777 0.130351 +v -0.875112 1.506150 0.101525 +v -0.436865 0.471545 0.402863 +v -0.685042 1.673202 -0.239595 +v 0.338645 0.786567 -0.176325 +v 0.307306 0.819690 -0.200404 +v 0.337484 0.836441 -0.186304 +v -0.449895 0.715773 0.419293 +v -0.450556 0.787963 0.423413 +v -0.439909 0.994255 0.423834 +v -0.442432 1.043172 0.413400 +v -0.429144 1.183599 0.306451 +v -0.198189 1.650949 -0.176090 +v -0.157232 1.631234 -0.163965 +v -0.314496 1.546046 -0.076802 +v -0.282188 1.575814 -0.109995 +v -0.242656 1.568769 -0.078509 +v -0.453013 1.569506 0.072037 +v -0.437239 1.619137 0.057714 +v -0.427402 0.769953 0.428041 +v -0.414912 1.122477 0.358735 +v -0.403421 1.166955 0.324602 +v -0.494226 1.428352 0.089729 +v -0.511083 1.452022 0.142795 +v 0.528019 0.465399 0.104277 +v 0.485100 0.617808 0.303473 +v -0.419793 0.696300 0.418249 +v -0.419961 0.810837 0.424562 +v -0.423245 1.073728 0.394565 +v -0.642308 1.487781 -0.258997 +v 0.069545 0.647001 0.555992 +v 0.002537 0.657412 0.565693 +v -0.415037 1.674851 0.032766 +v -0.501687 0.534623 0.162554 +v -0.418791 0.561644 0.397967 +v -0.420564 0.867115 0.425346 +v -0.414608 0.985448 0.417786 +v -0.922809 1.276205 0.297517 +v -0.624254 1.636664 -0.496673 +v -0.009496 1.014111 0.442901 +v -0.412449 0.430989 0.421296 +v -0.389799 0.579963 0.401514 +v -0.391856 0.630745 0.413829 +v -0.395176 0.781278 0.429186 +v -0.619544 1.686532 -0.526211 +v -0.628326 0.451827 0.346229 +v -0.594144 0.472780 0.341724 +v -0.038982 1.056617 0.440472 +v -0.093936 1.074281 0.434546 +v -0.078047 1.051662 0.438255 +v -0.389338 0.463643 0.403648 +v -0.381441 0.505996 0.393022 +v -0.383409 0.688438 0.418465 +v -0.393579 0.836314 0.435024 +v -0.394303 0.895976 0.431779 +v -0.397382 1.021536 0.405744 +v -0.486636 1.363852 0.068064 +v -0.484343 1.375497 0.132450 +v -0.089830 1.692645 -0.226835 +v -0.104828 1.666829 -0.217461 +v -0.097846 1.692849 -0.247566 +v -0.313581 1.536220 -0.046739 +v -0.294602 1.555026 -0.011914 +v -0.366584 0.750873 0.420070 +v -0.362989 0.956956 0.435803 +v -0.389789 1.068304 0.382477 +v -0.354537 1.124477 0.350554 +v -0.380502 1.152707 0.331786 +v -0.363093 1.187694 0.306740 +v -0.406522 1.226651 0.262903 +v -0.853298 1.533991 0.203783 +v -0.868249 1.528078 0.155215 +v -0.888754 1.516944 0.200866 +v -0.408023 1.643606 0.037449 +v -0.378573 1.701010 0.014236 +v -0.372779 1.728907 -0.008662 +v -0.031959 1.191252 0.383496 +v 0.000309 1.231575 0.347497 +v -0.064292 1.220109 0.357409 +v -0.391797 0.424067 0.414761 +v 0.595580 0.630993 0.059471 +v 0.595316 0.605046 0.058397 +v -0.369962 1.689930 0.013257 +v -0.352183 0.685598 0.413815 +v -0.365055 0.811523 0.431623 +v -0.367449 0.860837 0.436129 +v -0.367449 0.888869 0.433121 +v -0.356422 0.926174 0.442385 +v -0.359315 0.998099 0.423358 +v -0.362256 1.063424 0.386449 +v 0.000219 0.734960 0.576967 +v 0.414140 1.028422 0.165789 +v 0.435477 0.973894 0.173147 +v 0.199681 0.348440 -0.018985 +v 0.204148 0.355676 -0.037807 +v -0.361513 0.465051 0.407409 +v -0.343032 0.505201 0.382860 +v -0.343858 0.540960 0.380603 +v -0.344487 0.607805 0.395440 +v -0.330642 0.766548 0.412779 +v -0.321612 1.089650 0.381027 +v 0.098020 1.100399 0.399454 +v 0.083873 1.133622 0.397926 +v -0.032479 0.757107 0.587147 +v -0.366472 1.664013 -0.002816 +v -0.350226 0.828882 0.429128 +v -0.330585 0.861855 0.425604 +v -0.332389 0.885736 0.436971 +v -0.335821 1.038391 0.407380 +v -0.343932 1.723669 -0.009821 +v -0.291773 1.761996 -0.056241 +v -0.533230 1.527352 0.162139 +v -0.553690 1.544248 0.161607 +v -0.326899 0.677297 0.401244 +v -0.332443 0.822666 0.418522 +v -0.088692 0.954003 0.544460 +v -0.058623 0.973502 0.527437 +v -0.318350 0.907230 0.441735 +v -0.074442 1.169342 0.392839 +v -0.075520 1.118381 0.420397 +v -0.306148 0.544126 0.366943 +v -0.302725 0.624747 0.379822 +v -0.292417 0.942904 0.448212 +v -0.308676 0.969147 0.446514 +v -0.720836 1.496555 -0.392658 +v -0.723030 1.518670 -0.415443 +v -0.929073 1.230702 0.365232 +v -0.308006 0.800684 0.417981 +v -0.291512 1.019737 0.426331 +v 0.523273 0.643271 0.282819 +v 0.504000 0.672925 0.268515 +v 0.216211 0.376572 -0.047022 +v -0.292454 0.695515 0.393690 +v -0.292556 0.751692 0.411864 +v -0.299820 0.854023 0.437451 +v -0.292419 0.904534 0.442366 +v -0.283421 0.977827 0.437613 +v 0.455982 0.881517 0.131241 +v 0.446356 0.927943 0.178321 +v 0.342581 0.519308 0.327579 +v -0.068964 0.844329 0.571686 +v -0.325972 1.749873 -0.025953 +v -0.299962 1.781114 -0.052358 +v -0.275385 0.799648 0.476972 +v -0.273959 0.841083 0.487457 +v 0.577446 0.641584 0.026278 +v 0.583731 0.680676 0.057248 +v 0.107746 1.307916 0.143418 +v -0.280014 0.610754 0.374712 +v -0.280542 0.545510 0.367869 +v 0.401948 1.023160 -0.020048 +v 0.374187 1.085082 0.003397 +v 0.109155 1.263363 0.298570 +v 0.101452 1.222168 0.347190 +v 0.463517 0.740795 0.183543 +v 0.455420 0.833384 0.197009 +v -0.647969 1.521062 -0.361855 +v -0.632749 1.524573 -0.322217 +v -0.277200 0.505021 0.433407 +v -0.298429 0.467823 0.477469 +v -0.264689 0.478164 0.493226 +v -0.270463 0.670144 0.396722 +v -0.256226 0.987134 0.442109 +v -0.249016 1.121114 0.375603 +v -0.258693 1.042670 0.422076 +v -0.004658 1.198366 -0.136106 +v 0.008482 1.167002 -0.173371 +v -0.018733 1.159391 -0.171694 +v 0.012556 0.838456 0.574464 +v -0.685354 1.392937 -0.078046 +v -0.622631 1.521993 -0.225789 +v -0.258671 0.566892 0.391822 +v -0.253532 0.625672 0.406422 +v -0.240789 0.679067 0.451784 +v -0.926543 1.208402 0.416297 +v -0.931898 1.201992 0.379137 +v -0.922408 1.181684 0.412017 +v 0.363850 0.569965 0.336015 +v -0.265614 0.932895 0.449754 +v -0.211268 1.093229 0.407153 +v -0.249298 1.159277 0.340947 +v -0.227493 0.498839 0.466055 +v -0.555305 1.490553 -0.019602 +v -0.500767 1.499765 -0.036419 +v 0.497601 0.702352 0.237320 +v 0.086784 1.289457 0.261569 +v 0.157997 1.290142 0.132369 +v -0.243799 0.958664 0.444345 +v -0.224919 0.465136 0.518853 +v -0.229494 0.510206 0.439265 +v -0.247876 0.526062 0.408398 +v -0.639539 1.469473 0.384842 +v -0.228702 1.028473 0.435448 +v -0.184713 1.596772 -0.111695 +v -0.142225 1.616743 -0.133490 +v -0.243646 1.809684 -0.098312 +v -0.264679 1.810425 -0.080811 +v -0.241069 1.838089 -0.115447 +v -0.261775 0.424989 0.533152 +v -0.218670 0.440229 0.532438 +v -0.223658 0.480736 0.501265 +v -0.155133 1.043613 0.429194 +v -0.151196 0.999300 0.445003 +v -0.115997 1.010781 0.441917 +v -0.881303 0.975405 0.056788 +v -0.352071 1.250522 0.216357 +v -0.183831 1.854366 -0.171363 +v -0.152107 1.846364 -0.220572 +v -0.172707 1.869960 -0.199775 +v -0.223620 0.982076 0.447660 +v 0.112121 0.665841 0.539822 +v -0.670703 1.807268 -0.566186 +v -0.523127 0.510853 0.244857 +v -0.521306 0.563030 0.266725 +v -0.509161 0.538136 0.197531 +v -0.208817 1.140953 0.378730 +v -0.602536 1.433910 -0.037906 +v 0.167710 0.886447 0.505230 +v 0.180453 0.836232 0.512859 +v -0.198758 0.516077 0.461420 +v -0.215889 0.568369 0.454671 +v -0.384934 0.728399 -0.175022 +v -0.352630 0.710677 -0.180118 +v -0.353857 0.668174 -0.154348 +v 0.163292 1.225189 0.313754 +v 0.138138 1.232219 0.325026 +v 0.165740 1.189015 0.350423 +v -0.202182 1.021439 0.437012 +v 0.508013 0.573081 0.300014 +v 0.504123 0.603126 0.302451 +v -0.175335 0.479642 0.488296 +v -0.913098 1.484859 0.162701 +v -0.910037 1.488572 0.215071 +v -0.900121 1.508334 0.157528 +v 0.167152 1.268985 0.002233 +v -0.529987 0.491690 0.339676 +v -0.572765 0.472996 0.298900 +v -0.448429 1.462939 0.017115 +v -0.180579 1.050392 0.428028 +v -0.369318 0.371074 -0.297142 +v -0.405419 0.388860 -0.273649 +v -0.339573 0.410251 -0.296602 +v 0.101139 0.764681 0.552568 +v 0.081848 0.807562 0.553745 +v -0.155101 0.452831 0.506530 +v -0.180021 0.499178 0.469480 +v -0.169113 0.518435 0.484593 +v -0.290472 1.255634 0.077618 +v 0.095078 1.304186 0.207150 +v -0.704132 1.412920 -0.084591 +v -0.224137 0.832835 0.555907 +v -0.205806 0.795725 0.560139 +v -0.191353 0.834748 0.572174 +v -0.073157 0.739196 0.579717 +v 0.157606 0.932036 0.499393 +v -0.166833 0.872667 0.567412 +v -0.200222 0.880321 0.555894 +v -0.188705 0.989732 0.444893 +v -0.166926 1.156855 0.378532 +v 0.296650 0.715068 -0.212823 +v 0.263218 0.702407 -0.238787 +v 0.254729 0.740945 -0.249385 +v 0.061508 0.834062 0.564635 +v -0.422335 1.721157 -0.041800 +v -0.177955 0.774862 0.560873 +v -0.169932 0.825558 0.575239 +v -0.162492 0.542921 0.503069 +v -0.183400 0.574900 0.497630 +v -0.174206 0.696595 0.540895 +v -0.152422 0.709099 0.550048 +v -0.152411 0.918217 0.558173 +v -0.193214 0.921239 0.538207 +v 0.139064 1.279084 0.251103 +v -0.115586 0.338954 -0.210543 +v -0.133711 0.343616 -0.190237 +v -0.236715 0.336310 -0.232178 +v -0.151800 1.080775 0.423504 +v -0.139916 1.196257 0.362516 +v -0.133734 0.478924 0.478839 +v -0.157159 0.608230 0.523655 +v -0.143547 0.544282 0.507103 +v -0.147460 0.655839 0.537309 +v -0.145578 0.765822 0.564933 +v -0.152456 0.829408 0.569346 +v -0.136261 0.897879 0.566744 +v -0.143940 0.945876 0.539935 +v -0.831594 1.467428 0.030758 +v -0.827325 1.419686 0.012529 +v 0.132262 1.295807 0.196896 +v -0.129534 1.159358 0.389202 +v -0.123952 1.226473 0.335883 +v 0.487491 0.452650 0.023024 +v 0.433421 0.716761 -0.022304 +v -0.137749 0.708879 0.546956 +v -0.124060 0.852226 0.572678 +v -0.121935 0.494703 0.494845 +v -0.118660 0.731837 0.562501 +v -0.113787 0.798771 0.576989 +v -0.128198 1.045710 0.434657 +v -0.116086 1.098371 0.424753 +v 0.247661 1.108111 0.367284 +v -0.104465 0.536860 0.519586 +v -0.102829 0.689263 0.552896 +v -0.099440 0.763431 0.573886 +v -0.112138 0.923664 0.561053 +v -0.108726 0.888268 0.566655 +v 0.446930 0.926886 0.022467 +v -0.076323 1.030453 0.437107 +v -0.381178 0.763901 -0.186443 +v -0.565603 0.483555 0.366071 +v -0.113879 0.647424 0.549180 +v -0.084981 0.839905 0.576052 +v -0.075347 1.002130 0.474887 +v -0.158628 0.970216 0.501394 +v -0.062546 1.012165 0.443220 +v -0.881946 1.031463 0.175090 +v 0.150482 0.457558 0.437939 +v 0.147443 0.427169 0.445103 +v 0.109362 0.860273 0.547327 +v -0.206167 1.823759 -0.142991 +v -0.460763 1.681972 0.007375 +v 0.301687 1.004869 0.394047 +v 0.261109 1.008899 0.417333 +v 0.288147 0.967127 0.422577 +v -0.313557 1.580989 0.019129 +v -0.253736 1.584001 -0.014801 +v -0.262918 1.596338 -0.005184 +v 0.104060 0.591624 0.524844 +v 0.099912 0.627353 0.540093 +v -0.153064 0.352464 0.501338 +v -0.094780 0.359776 0.494342 +v -0.177275 0.362895 0.522223 +v 0.244117 0.980169 0.446874 +v 0.237801 0.952229 0.463473 +v 0.547150 0.646972 0.269797 +v 0.539440 0.613915 0.282685 +v 0.171768 0.730662 0.518266 +v 0.181098 0.758066 0.524883 +v 0.140743 0.766517 0.542214 +v 0.544516 0.583429 0.276530 +v 0.399069 0.643613 0.316867 +v 0.375192 0.610627 0.343660 +v 0.437662 0.883900 -0.035709 +v -0.394947 0.375516 0.428709 +v -0.433237 0.362864 0.440424 +v 0.568206 0.636911 0.252861 +v 0.518237 0.532767 0.279270 +v -0.391610 1.571888 -0.105805 +v -0.336196 1.569147 -0.110248 +v 0.140552 0.525239 0.485939 +v 0.194212 0.513213 0.447989 +v 0.192046 0.551665 0.477222 +v 0.266373 0.476071 -0.164277 +v 0.245671 0.441301 -0.108208 +v 0.220401 0.449925 -0.175285 +v 0.270207 0.613457 -0.222921 +v 0.309404 0.605181 -0.181327 +v 0.306628 0.573004 -0.165184 +v -0.233436 1.610345 -0.031862 +v -0.292649 1.614042 -0.021039 +v 0.145215 0.613829 0.505009 +v 0.165683 0.662699 0.510099 +v 0.129196 0.642036 0.524412 +v -0.504927 1.415990 0.162918 +v -0.476728 0.361167 -0.133012 +v -0.711354 1.381765 0.478540 +v 0.149048 0.563504 0.495228 +v 0.117454 0.566783 0.519141 +v -0.493499 1.491352 0.112741 +v -0.235743 0.370369 0.541448 +v -0.269407 0.361840 0.533519 +v -0.229340 0.356329 0.528655 +v -0.697606 1.344285 0.482652 +v 0.335255 1.096621 -0.069895 +v 0.379551 1.048871 -0.032032 +v 0.366959 1.037284 -0.079621 +v -0.662994 1.233712 0.506159 +v -0.576354 0.504255 0.046108 +v -0.560675 0.534706 0.073718 +v -0.570694 0.544244 0.023396 +v 0.201531 1.184972 0.342713 +v 0.341264 0.970540 0.375904 +v 0.292500 1.065193 0.365903 +v 0.287344 1.036005 0.380353 +v 0.177748 0.582438 0.488647 +v -0.370771 1.598637 0.016097 +v -0.688765 1.102217 0.390046 +v -0.238543 1.616453 -0.145042 +v 0.559573 0.531474 0.231977 +v 0.517038 0.488574 0.241480 +v -0.786095 0.696569 0.118108 +v -0.668172 1.195152 0.514902 +v -0.667024 1.321060 0.454810 +v -0.352032 1.649355 -0.026810 +v -0.653983 1.175195 0.487356 +v -0.680900 1.164705 0.511512 +v -0.675044 1.142409 0.480361 +v -0.328000 1.594870 0.021963 +v -0.642050 1.224389 0.480084 +v 0.448725 0.755167 0.231553 +v 0.451370 0.446254 0.255165 +v 0.490157 0.445736 0.206595 +v -0.629906 1.199946 0.452356 +v -0.643482 1.262809 0.466502 +v 0.576794 0.613930 0.242018 +v 0.566718 0.569708 0.242919 +v 0.381029 0.656784 0.351325 +v 0.359718 0.666696 0.377814 +v 0.353418 0.616300 0.376060 +v 0.387855 0.949543 0.325202 +v 0.392915 1.012597 0.275505 +v 0.367584 0.991955 0.328377 +v -0.364250 0.936307 -0.235346 +v -0.392279 0.991846 -0.219127 +v -0.655999 1.132950 0.423187 +v -0.690872 1.120501 0.453201 +v -0.636028 1.157145 0.425723 +v -0.654245 1.401128 0.413090 +v 0.592385 0.563628 0.094531 +v 0.564127 0.676599 0.239693 +v 0.384462 0.756494 0.350507 +v 0.369751 0.798765 0.371984 +v 0.354720 0.730767 0.384823 +v 0.287793 0.825532 0.445274 +v 0.284233 0.880111 0.442342 +v 0.258729 0.884823 0.466553 +v 0.545372 0.687967 0.245177 +v -0.633666 1.303707 0.416700 +v 0.231839 0.586544 0.458711 +v 0.246721 0.636945 0.452046 +v 0.219024 0.608760 0.472824 +v 0.361438 0.844392 0.379369 +v 0.384136 0.874899 0.351859 +v 0.344046 0.869328 0.405743 +v -0.615112 1.237356 0.430627 +v -0.217911 1.065804 -0.223270 +v -0.169534 1.066926 -0.220030 +v -0.199876 1.027831 -0.233929 +v 0.178974 0.795165 0.527595 +v -0.128937 1.787904 -0.226247 +v -0.110919 1.799208 -0.259964 +v -0.642874 1.346362 0.399457 +v 0.125345 0.895939 0.533946 +v 0.201270 0.638513 0.479197 +v 0.480748 0.489700 0.281655 +v -0.197117 1.682914 -0.130209 +v -0.114474 1.713106 -0.196030 +v -0.158154 1.750494 -0.186541 +v -0.637129 1.127425 0.380068 +v 0.422099 0.788615 0.291872 +v -0.627631 1.377801 0.366786 +v -0.388647 1.033399 -0.206414 +v -0.332023 1.057832 -0.206476 +v 0.398997 0.702948 0.327200 +v 0.269968 0.513178 0.387521 +v 0.312863 0.528638 0.369136 +v 0.289526 0.561252 0.403890 +v 0.194873 0.408093 0.426411 +v 0.216914 0.401615 0.408465 +v 0.226252 0.436217 0.409046 +v 0.258218 0.463266 0.382772 +v 0.189280 0.442496 0.430098 +v 0.216327 0.481273 0.406944 +v 0.272687 0.445478 0.361525 +v 0.245624 0.483696 -0.196728 +v -0.610960 1.170165 0.396540 +v -0.593754 1.199824 0.405483 +v -0.599371 1.272619 0.407713 +v -0.611289 1.317833 0.389159 +v -0.621456 1.359977 0.367010 +v -0.624419 1.408478 0.369659 +v 0.242862 0.549586 0.430869 +v -0.612957 1.451999 0.371379 +v -0.379877 1.075145 -0.199757 +v -0.573353 1.234010 0.402315 +v -0.564643 0.376831 0.468196 +v -0.509647 0.383123 0.462861 +v -0.329774 0.663652 -0.183855 +v 0.195371 0.600038 0.485761 +v -0.162575 1.603125 -0.096926 +v -0.212169 1.588794 -0.046923 +v -0.215921 1.576344 -0.068623 +v -0.132534 1.662715 -0.141203 +v -0.109868 1.662120 -0.160475 +v -0.677506 1.573483 -0.539821 +v -0.655095 1.585733 -0.556002 +v -0.570314 1.156201 0.364949 +v -0.228765 1.739281 -0.134311 +v -0.179690 1.807803 -0.181034 +v 0.167434 0.484390 0.436786 +v 0.234693 1.165626 0.335373 +v -0.569165 1.262351 0.394266 +v -0.582595 1.409949 0.324407 +v -0.600104 1.428446 0.354497 +v -0.591297 1.503971 0.344896 +v -0.416653 1.499614 0.045405 +v -0.165309 1.632500 -0.092475 +v -0.226016 1.625045 -0.060717 +v -0.178916 1.611380 -0.067072 +v -0.558599 1.177431 0.372535 +v -0.547258 1.207126 0.374515 +v -0.555169 1.295607 0.365985 +v -0.582031 1.327097 0.369187 +v -0.560328 1.373108 0.319706 +v -0.582986 1.388550 0.329375 +v -0.586033 1.463724 0.338088 +v 0.563052 0.677699 0.026525 +v -0.392694 1.520523 -0.066204 +v -0.541726 1.233792 0.375765 +v -0.501266 0.709331 0.394810 +v -0.452091 0.388391 0.445038 +v -0.265809 1.556769 -0.041963 +v -0.199263 1.648974 -0.099900 +v -0.521662 1.501366 0.174488 +v 0.185966 0.352939 -0.086782 +v 0.241087 0.844926 0.482923 +v 0.252716 0.787249 0.480266 +v 0.132347 0.384531 0.445015 +v -0.532167 1.322198 0.329784 +v -0.568023 1.451467 0.317403 +v -0.457543 0.352070 0.435181 +v -0.544037 0.350073 0.448746 +v -0.534258 0.345600 0.427824 +v 0.218860 0.539276 0.451025 +v -0.513169 0.482707 -0.079310 +v -0.463852 0.474909 -0.100860 +v -0.519416 1.256599 0.345879 +v -0.560701 1.500071 0.298677 +v -0.495795 0.360965 0.459554 +v 0.144240 0.800855 0.537556 +v 0.288105 0.433523 0.321577 +v 0.330446 1.076625 0.319162 +v 0.290631 1.114960 0.338058 +v 0.362944 0.712207 0.371146 +v 0.333639 0.670548 0.397295 +v 0.209919 0.693354 0.490036 +v 0.226875 0.751492 0.493125 +v 0.233868 0.700760 0.470126 +v -0.522773 1.177508 0.337695 +v -0.547315 1.426723 0.289805 +v 0.428311 0.855560 0.278738 +v -0.711690 1.474016 -0.275909 +v -0.717236 1.461744 -0.215678 +v 0.217409 0.802506 0.504254 +v -0.496658 1.206380 0.321633 +v -0.549107 1.466231 0.284390 +v -0.345080 1.544747 0.016505 +v 0.300517 0.621696 0.415458 +v 0.293629 0.665098 0.422894 +v -0.220478 1.834859 -0.120950 +v -0.511036 0.730720 -0.162430 +v 0.329786 0.735007 0.404865 +v 0.297417 0.706471 0.416539 +v 0.373268 0.402095 -0.008585 +v 0.437796 0.445307 -0.012622 +v 0.432934 0.418641 0.020634 +v -0.601458 0.412020 0.442938 +v -0.530782 1.375469 0.282665 +v -0.097015 1.673886 -0.193602 +v -0.111837 1.645000 -0.161517 +v 0.324116 0.937361 0.408903 +v 0.391084 1.082907 0.131423 +v 0.330404 0.617738 0.397814 +v -0.185276 1.765320 -0.170435 +v -0.290096 0.512653 -0.221758 +v -0.255283 0.514727 -0.268847 +v -0.260495 0.476925 -0.261495 +v -0.495368 1.249134 0.317785 +v -0.495078 1.294950 0.302593 +v 0.131891 0.842112 0.530658 +v 0.289824 0.740885 0.434473 +v 0.288271 0.921334 0.439201 +v 0.308850 0.789995 0.433888 +v 0.259036 0.755360 0.464167 +v 0.335738 0.585153 0.383110 +v 0.327565 0.889691 0.422155 +v 0.304450 0.849596 0.430111 +v -0.538318 1.498169 0.250666 +v -0.911888 1.158889 0.247056 +v -0.469888 1.260080 0.269855 +v 0.238558 1.061662 0.393781 +v 0.270139 0.599528 0.434544 +v -0.910443 1.419986 0.217297 +v -0.909497 1.389537 0.173712 +v 0.261087 0.680076 0.439027 +v 0.256585 0.705504 0.445399 +v -0.478435 1.221506 0.288332 +v -0.017343 0.394768 0.472629 +v 0.236780 0.514744 0.410533 +v 0.254642 0.540297 -0.216910 +v 0.290630 0.552106 -0.180421 +v 0.267755 0.514235 -0.202341 +v -0.570941 0.459965 0.268653 +v -0.624641 0.437220 0.284933 +v -0.386705 1.607020 -0.123577 +v 0.410654 0.904607 0.298886 +v -0.735044 0.938833 -0.147517 +v -0.756432 0.994404 -0.119276 +v -0.725986 0.977627 -0.144345 +v 0.237531 0.346707 0.039885 +v 0.290866 0.358000 0.035631 +v 0.352517 0.908368 0.391839 +v 0.581774 0.528213 0.151824 +v 0.597981 0.568402 0.133427 +v 0.330301 0.837816 0.416369 +v -0.372925 1.644906 -0.136270 +v -0.335409 0.363426 0.490900 +v -0.351460 0.385859 0.477327 +v -0.368986 0.359246 0.447942 +v -0.866747 0.826650 0.151744 +v 0.421561 0.697176 0.283182 +v 0.048689 0.379624 0.458676 +v -0.578226 0.695380 -0.144165 +v -0.516735 0.668507 -0.121203 +v -0.517042 0.376204 -0.117634 +v -0.470801 0.407007 -0.118698 +v -0.708877 1.440462 -0.149085 +v 0.485127 0.717982 0.060005 +v 0.396048 0.449395 0.299924 +v -0.225421 0.406158 0.539860 +v -0.256474 0.388607 0.541614 +v 0.422966 0.454358 0.290409 +v 0.196360 0.382340 -0.125077 +v 0.219775 0.428553 -0.145362 +v 0.216970 0.404273 -0.094629 +v -0.860615 0.799311 0.144408 +v -0.132203 1.839719 -0.275194 +v -0.137085 1.849115 -0.255495 +v 0.118070 0.709210 0.542405 +v -0.639385 1.526270 0.344811 +v 0.590921 0.579570 0.202701 +v 0.565202 0.511799 0.199406 +v 0.588260 0.555038 0.186479 +v 0.571803 0.711077 0.080308 +v 0.564552 0.699515 0.049192 +v 0.537352 0.720273 0.068010 +v 0.565249 0.501257 0.155645 +v 0.583746 0.711864 0.130728 +v 0.598867 0.685130 0.161716 +v -0.637311 1.657704 -0.601036 +v -0.623592 1.754483 -0.614860 +v -0.630212 1.781095 -0.603935 +v -0.176180 0.389112 0.524034 +v -0.167175 0.336116 -0.246254 +v -0.782173 1.687397 -0.335642 +v -0.754295 1.709560 -0.328799 +v -0.208911 1.859534 -0.150373 +v 0.312988 0.759074 0.426991 +v -0.460949 1.529685 0.090030 +v -0.333598 1.698640 -0.154490 +v -0.245399 1.800586 -0.187269 +v -0.271135 1.733216 -0.185389 +v -0.802943 0.717024 0.159953 +v -0.448823 1.505296 0.076452 +v -0.614070 1.726882 -0.582657 +v -0.625417 1.767946 -0.578218 +v -0.625142 1.721312 -0.527881 +v 0.249756 0.426446 -0.070170 +v -0.288615 0.353967 0.173500 +v -0.348346 0.347214 0.345782 +v -0.298032 0.342870 0.163531 +v -0.316939 1.026127 -0.223523 +v 0.217473 1.211846 0.308788 +v 0.190679 1.214492 0.319685 +v 0.152633 0.715719 0.527174 +v -0.627445 1.639753 -0.593983 +v -0.882062 0.944857 0.237440 +v -0.887605 0.970374 0.210791 +v -0.888264 0.904833 0.212047 +v -0.308930 0.474090 -0.249540 +v 0.444501 0.818469 0.245529 +v 0.408248 0.951702 0.286579 +v -0.737957 1.089563 0.392173 +v 0.451614 0.710304 0.225307 +v -0.455699 1.466361 0.056514 +v -0.418041 1.558208 0.064548 +v -0.427642 1.572749 0.052016 +v -0.441112 0.928840 -0.223732 +v -0.510791 0.938928 -0.217617 +v -0.511396 0.966176 -0.220951 +v -0.114404 0.376408 0.502757 +v -0.104240 0.384886 0.062293 +v -0.165564 0.382865 0.102158 +v -0.142517 0.386480 -0.043030 +v -0.523690 1.468291 0.189347 +v -0.315358 0.447404 -0.280794 +v 0.383359 0.388308 0.030938 +v -0.073775 0.389884 0.489295 +v -0.416014 1.597800 0.035375 +v 0.407215 0.784755 -0.082130 +v -0.377768 1.555195 0.043701 +v -0.835609 1.525594 0.076807 +v -0.788761 1.534701 0.039876 +v -0.832120 1.507213 0.042129 +v 0.414774 0.855094 -0.091575 +v -0.713953 1.246885 -0.085944 +v -0.367521 1.580207 0.041862 +v -0.092489 1.772585 -0.282702 +v -0.095837 1.742610 -0.283907 +v -0.378854 1.619972 0.002469 +v -0.610805 1.683377 -0.591920 +v -0.283987 1.807065 -0.078469 +v -0.728232 1.451060 -0.156547 +v -0.349983 0.523316 -0.103474 +v -0.434653 1.245115 0.225189 +v -0.760033 1.636134 -0.180211 +v -0.769039 1.670803 -0.269313 +v -0.774095 1.626052 -0.207546 +v -0.134690 1.629936 -0.120000 +v -0.407506 0.492851 -0.112862 +v -0.154515 1.859760 -0.247958 +v -0.880896 1.113548 0.185162 +v -0.467556 1.328429 0.081213 +v -0.515957 0.844221 -0.216009 +v -0.526758 0.882207 -0.218863 +v -0.489848 0.907318 -0.218172 +v -0.878293 1.435146 0.357077 +v -0.894082 1.435282 0.309248 +v -0.891103 1.385139 0.376588 +v -0.637571 1.591218 -0.501557 +v -0.869911 0.864447 0.224210 +v -0.893851 0.990240 0.175218 +v -0.623726 1.531304 -0.289971 +v -0.620593 1.569781 -0.337846 +v -0.615914 1.568157 -0.259456 +v -0.617687 1.606796 -0.340463 +v -0.618797 1.600045 -0.258062 +v -0.920196 1.161153 0.358427 +v -0.603184 0.384430 0.452460 +v -0.629283 0.390617 0.427077 +v -0.620019 0.364350 0.439189 +v -0.852366 1.107736 0.245377 +v -0.861615 1.083859 0.182449 +v -0.601135 0.355504 0.449076 +v -0.178705 0.382039 0.202432 +v -0.257981 0.378650 0.199815 +v -0.852702 1.055177 0.232910 +v -0.841234 1.083205 0.247310 +v -0.935758 1.247463 0.262133 +v -0.926014 1.301865 0.251836 +v -0.432268 0.462636 -0.117717 +v -0.912820 1.331190 0.246887 +v -0.623119 1.637111 -0.406240 +v -0.893132 1.365301 0.304588 +v 0.558590 0.629102 0.006904 +v -0.926747 1.170195 0.118895 +v 0.242519 0.564575 -0.242548 +v 0.350477 0.409739 0.269704 +v 0.289484 0.391600 0.272348 +v 0.335841 0.383039 0.229287 +v -0.336564 0.343441 0.369141 +v -0.419132 0.344677 0.332000 +v 0.301453 0.862840 -0.204081 +v 0.353588 0.874389 -0.171090 +v -0.092296 1.731446 -0.241976 +v -0.086960 1.729159 -0.267087 +v -0.930398 1.202642 0.112168 +v -0.922377 1.248852 0.407866 +v -0.897713 1.290486 0.430230 +v -0.544734 0.459375 0.236126 +v -0.628296 1.518948 -0.092373 +v 0.185057 0.382941 -0.171365 +v -0.518300 0.485687 0.216470 +v -0.326057 0.612646 -0.154530 +v 0.166386 0.381961 -0.198849 +v 0.139503 0.348800 -0.186129 +v 0.008800 0.992349 -0.243557 +v 0.069832 0.977301 -0.248003 +v 0.026040 0.969427 -0.284070 +v 0.378147 0.796982 -0.132896 +v 0.383020 0.845491 -0.144788 +v 0.365239 0.819917 -0.162296 +v 0.326004 0.537075 -0.110061 +v 0.357067 0.560830 -0.089993 +v 0.332056 0.510206 -0.072382 +v 0.120092 0.359619 -0.217357 +v -0.867230 0.999172 0.035537 +v 0.373786 0.730934 -0.126354 +v 0.349818 0.677408 -0.156832 +v 0.335054 0.728099 -0.170348 +v -0.264167 0.446740 -0.282097 +v -0.851063 0.851766 0.256795 +v -0.883665 1.136186 0.058228 +v -0.526254 0.504346 0.290468 +v -0.880011 0.866264 0.154667 +v 0.410733 0.887243 -0.097879 +v 0.386482 0.901533 -0.125497 +v -0.066397 1.022221 -0.235193 +v -0.085370 0.999212 -0.243511 +v -0.124299 1.028601 -0.238225 +v -0.612980 0.339002 -0.093217 +v -0.637159 0.337769 -0.080066 +v 0.281477 0.787854 -0.224324 +v 0.306849 0.757269 -0.207781 +v 0.389971 0.970882 -0.077799 +v 0.354074 0.981888 -0.120090 +v 0.366840 1.009957 -0.098486 +v -0.529098 0.570431 0.209884 +v -0.895779 1.207831 0.035229 +v -0.901995 1.165751 0.056755 +v 0.355381 0.760630 -0.144347 +v -0.874265 0.954695 0.040313 +v 0.347459 0.632613 -0.146467 +v 0.381111 0.648118 -0.111420 +v 0.249907 0.658973 -0.235683 +v 0.292165 0.678503 -0.204186 +v 0.282048 0.643913 -0.206980 +v -0.908217 1.227690 0.060999 +v -0.417355 1.268760 -0.041742 +v -0.421215 1.282511 0.010752 +v -0.370538 1.271509 0.003548 +v -0.043822 1.264075 -0.069495 +v 0.035641 1.276488 -0.044672 +v -0.023850 1.229053 -0.103824 +v -0.114525 1.722063 -0.268450 +v -0.109067 1.764930 -0.292463 +v -0.117034 0.973557 0.515921 +v 0.202503 0.370332 0.393272 +v 0.236821 0.397625 0.371488 +v -0.896073 1.397110 0.293086 +v -0.896411 1.384192 0.341418 +v 0.370272 0.939496 -0.116740 +v 0.297400 0.525384 -0.162249 +v 0.297407 0.503247 -0.139909 +v -0.907585 1.422337 0.260082 +v 0.172098 0.352594 -0.146852 +v -0.714337 0.775735 0.380608 +v -0.655454 0.744304 0.391681 +v -0.177662 1.857234 -0.230493 +v -0.248333 0.958580 -0.251621 +v -0.190475 0.965621 -0.275799 +v -0.257811 0.937782 -0.283882 +v 0.402816 0.726371 -0.092881 +v 0.399096 0.681717 -0.095698 +v -0.797906 1.035166 -0.066275 +v -0.746838 1.078610 -0.090477 +v 0.407062 0.644753 -0.055920 +v 0.359151 0.599164 -0.119665 +v 0.284549 0.480674 -0.128472 +v 0.292078 0.474502 -0.085082 +v -0.112434 1.645751 -0.182408 +v -0.776935 1.736797 -0.414786 +v -0.786996 1.731391 -0.427204 +v 0.388294 0.598398 -0.064252 +v 0.166885 0.369766 0.430006 +v 0.222916 0.370533 0.331010 +v 0.191282 0.356406 0.366423 +v -0.610517 0.443922 0.124219 +v -0.578530 0.464445 0.110626 +v -0.505952 0.499233 0.191741 +v -0.053486 0.338290 -0.226004 +v 0.014086 0.347820 -0.232652 +v 0.064844 0.342930 -0.208549 +v 0.388386 0.578083 -0.052585 +v 0.384634 0.549348 -0.061822 +v -0.392070 0.815364 -0.205710 +v -0.357498 0.772484 -0.193740 +v -0.654728 0.456276 0.045575 +v -0.622494 0.465401 0.071904 +v -0.577131 0.487178 0.072765 +v -0.911608 1.414436 0.156739 +v -0.713028 1.132536 0.494445 +v -0.651714 0.372895 0.259538 +v -0.644158 0.412838 0.282435 +v -0.630870 0.396142 0.251816 +v -0.197067 0.929173 -0.346369 +v -0.187722 0.898380 -0.369917 +v -0.232857 0.894680 -0.360272 +v 0.344002 1.050300 -0.102249 +v 0.330813 1.027338 -0.127872 +v -0.780220 0.709952 0.213222 +v 0.434225 0.918604 0.245385 +v -0.800504 1.167040 0.487625 +v -0.788491 1.186737 0.506229 +v -0.157822 1.007296 -0.237241 +v -0.058904 0.347906 -0.242245 +v -0.031837 0.362299 0.478731 +v 0.232458 0.627925 -0.250480 +v -0.381195 0.641623 -0.138291 +v -0.415582 0.697740 -0.167741 +v 0.249890 0.381046 0.294296 +v -0.171422 0.980575 -0.249243 +v -0.626819 1.674409 -0.457139 +v -0.519040 0.461001 0.194213 +v -0.523898 0.454491 0.176863 +v 0.417725 0.695680 -0.061596 +v -0.491046 1.366688 0.193141 +v -0.100909 0.982297 -0.277313 +v -0.030870 0.984025 -0.274032 +v -0.082085 0.967774 -0.308098 +v 0.203568 0.436624 -0.204563 +v 0.529064 0.652305 -0.005111 +v 0.531241 0.590124 -0.028854 +v 0.500008 0.616121 -0.034650 +v 0.319093 0.646571 -0.184734 +v -0.894308 1.473055 0.276950 +v 0.367300 1.111676 0.038671 +v 0.172528 0.443356 -0.230672 +v -0.085065 0.390290 -0.130008 +v -0.192888 0.387626 -0.142026 +v -0.111132 0.382903 -0.156464 +v -0.393432 0.354402 0.424926 +v -0.407604 0.346682 0.404925 +v -0.862271 1.146684 0.022102 +v -0.424660 0.341891 -0.272606 +v -0.389211 0.337674 -0.290426 +v -0.732425 1.523133 -0.357035 +v -0.740844 1.498774 -0.326100 +v -0.838907 0.807895 0.022952 +v -0.358749 0.347760 -0.308452 +v 0.413188 0.994967 0.242758 +v 0.038249 0.361292 -0.238781 +v -0.533420 1.440120 0.242614 +v 0.022544 0.364115 -0.147840 +v 0.082741 0.356452 -0.126487 +v 0.044523 0.377052 -0.129576 +v -0.624253 0.418857 0.146468 +v -0.017359 0.922442 -0.343104 +v -0.064120 0.928762 -0.348176 +v -0.008245 0.951651 -0.320563 +v 0.420807 0.634806 -0.025405 +v 0.443265 0.908181 0.220975 +v 0.541142 0.477731 0.174840 +v -0.387911 0.852327 -0.219176 +v -0.354702 0.801961 -0.223259 +v -0.521159 1.417991 0.205103 +v -0.514927 1.379639 0.236622 +v -0.815428 0.779507 0.267273 +v -0.835398 0.811696 0.270141 +v -0.817395 0.768613 0.233136 +v -0.419336 0.884634 -0.221263 +v -0.365534 0.853162 -0.225762 +v 0.526631 0.476736 0.212013 +v -0.259640 0.334870 -0.263211 +v -0.332411 0.335788 -0.267194 +v -0.331644 0.336065 -0.297219 +v 0.191201 0.471678 -0.221147 +v -0.635418 1.633211 -0.259130 +v -0.347079 0.840359 -0.243022 +v -0.681924 1.743983 -0.453658 +v -0.641242 1.795363 -0.587304 +v -0.647938 1.788528 -0.558832 +v -0.647604 1.531159 -0.020371 +v -0.726184 1.436813 -0.109871 +v -0.765956 1.775323 -0.471180 +v -0.453345 1.289149 0.015819 +v -0.450775 1.312444 0.111458 +v 0.568476 0.720172 0.171394 +v 0.543594 0.714673 0.213813 +v -0.730191 1.560210 0.224194 +v -0.725055 1.545953 0.295889 +v -0.259196 1.827283 -0.135411 +v -0.620994 1.540670 0.308374 +v -0.678186 1.545435 0.302337 +v 0.558885 0.725793 0.106697 +v 0.549194 0.731616 0.152236 +v 0.540165 0.728838 0.186780 +v 0.507817 0.721552 0.206802 +v -0.340229 1.759708 -0.037271 +v 0.515371 0.734967 0.126987 +v 0.505228 0.733979 0.161669 +v 0.517462 0.728972 0.090648 +v 0.482069 0.726986 0.169946 +v -0.341511 1.744280 -0.133125 +v 0.474469 0.736914 0.124300 +v -0.327157 1.089663 -0.189414 +v -0.621162 1.560079 0.180344 +v -0.318288 1.263911 0.100134 +v -0.609232 0.386218 0.224689 +v -0.849704 1.532231 0.126545 +v -0.611210 1.556966 0.225171 +v -0.657397 1.556534 0.260176 +v -0.400811 1.262838 0.196073 +v -0.353017 1.254781 -0.031543 +v -0.337615 1.261788 0.017133 +v -0.305435 1.247789 0.010984 +v -0.707315 1.556996 0.069058 +v -0.437932 1.695551 -0.073026 +v -0.660960 1.553253 0.071562 +v -0.677805 1.561445 0.142763 +v -0.616417 1.558204 0.110998 +v -0.362236 1.277752 0.098502 +v -0.429306 1.292844 0.092701 +v -0.375385 1.274413 0.153209 +v -0.666052 1.647738 -0.206707 +v -0.376065 1.242260 0.243136 +v -0.925950 1.194383 0.268030 +v -0.635381 0.435240 0.379740 +v -0.512433 0.642392 0.342581 +v -0.513079 0.605217 0.314349 +v -0.753909 1.795282 -0.524020 +v -0.775872 1.771788 -0.502211 +v -0.430456 1.278512 0.168423 +v -0.442863 1.260663 0.207952 +v -0.695406 1.530853 0.338657 +v -0.595824 1.562334 0.079210 +v -0.650474 1.799915 -0.597586 +v -0.685312 1.563004 0.209977 +v -0.653203 1.539032 0.009139 +v -0.020517 1.009347 0.456259 +v -0.755369 1.597706 -0.104386 +v -0.631173 1.542544 0.029731 +v -0.275970 1.697982 -0.181704 +v -0.891465 1.365050 0.259528 +v -0.702223 1.514352 0.367189 +v -0.604836 1.556798 0.043344 +v -0.645587 0.396399 0.394115 +v -0.654885 0.409378 0.353155 +v -0.668041 0.373777 0.332963 +v -0.254117 1.247253 0.001289 +v -0.391896 1.282819 0.050347 +v -0.647926 0.417245 0.316169 +v 0.303004 1.155365 0.286850 +v -0.258099 0.888896 -0.350822 +v -0.269641 0.845128 -0.363617 +v -0.291645 0.853934 -0.336668 +v 0.361020 1.126610 0.104918 +v -0.862527 1.010685 0.254138 +v -0.874055 1.020521 0.220204 +v 0.335683 1.152372 0.217984 +v -0.791299 1.673657 -0.355062 +v 0.336635 1.157421 0.171813 +v -0.433098 0.556568 -0.114021 +v -0.413623 0.616373 -0.128138 +v -0.575206 1.587760 0.041621 +v 0.343259 1.119331 -0.022406 +v 0.265792 1.170244 0.308680 +v 0.261481 1.201473 0.273080 +v -0.671565 0.419729 0.102409 +v -0.673065 0.441768 0.075958 +v 0.148016 0.990409 -0.228429 +v 0.135335 1.025539 -0.215793 +v 0.186607 1.003078 -0.221273 +v 0.328773 1.169146 0.092958 +v 0.304446 1.188644 0.208218 +v 0.286757 1.195960 0.245459 +v 0.328199 1.165563 0.044459 +v 0.292531 1.205770 0.122993 +v 0.264881 1.223029 0.203981 +v 0.308357 1.155423 -0.031785 +v 0.315019 1.172517 0.016855 +v -0.852698 1.026779 0.013936 +v -0.677877 1.808889 -0.581910 +v -0.681362 1.800611 -0.588160 +v 0.291306 1.202744 0.061118 +v 0.233371 1.235345 0.248742 +v -0.472901 1.305535 0.016909 +v -0.910787 1.150604 0.401418 +v 0.203588 1.244875 0.259064 +v -0.021514 0.994374 0.498498 +v 0.253435 1.237475 0.099819 +v 0.240003 1.246876 0.155180 +v 0.215035 1.256399 0.212526 +v 0.168311 1.248715 0.284256 +v 0.257259 1.212270 -0.000361 +v 0.242466 1.237776 0.048765 +v 0.190122 1.273620 0.177866 +v 0.169816 1.271500 0.229315 +v 0.210698 1.249776 0.010998 +v -0.417718 1.039671 -0.208329 +v -0.851489 1.396552 0.024809 +v -0.324919 0.571963 -0.121047 +v -0.341082 0.614666 -0.130531 +v -0.572196 0.570005 0.049176 +v -0.231229 0.945159 0.473589 +v -0.651466 0.359456 0.397751 +v -0.785977 1.744157 -0.466076 +v -0.554366 0.594202 0.230190 +v -0.581676 0.599852 0.226061 +v -0.182239 0.974946 0.468480 +v -0.323321 0.486728 0.425240 +v -0.344539 0.445640 0.454230 +v -0.320436 0.504618 0.393415 +v -0.291748 0.522645 0.376373 +v -0.721450 0.915564 0.414948 +v -0.517058 0.524708 -0.074047 +v -0.464712 0.513043 -0.098300 +v -0.390882 1.687202 -0.119247 +v -0.203215 0.939996 0.515886 +v -0.262732 0.776312 0.483562 +v -0.239444 0.788001 0.535347 +v -0.272291 0.879915 0.479097 +v -0.581052 0.664660 -0.100443 +v -0.274126 0.732694 0.426414 +v -0.241876 0.722691 0.476811 +v -0.497634 0.562412 0.336243 +v -0.254392 0.906779 0.488523 +v -0.565721 1.248028 -0.071886 +v -0.216927 0.382660 0.045101 +v -0.277909 0.380629 0.079376 +v -0.320742 0.383234 -0.004211 +v -0.305578 0.886259 -0.275507 +v -0.228516 0.906350 0.522805 +v -0.741135 0.994425 0.383377 +v -0.202684 0.622668 0.482121 +v -0.375015 0.427367 0.429884 +v -0.698556 1.002789 -0.148478 +v -0.239883 0.859956 0.537164 +v -0.485800 1.668921 -0.025256 +v -0.214811 0.741945 0.528577 +v -0.773783 1.576427 -0.141336 +v -0.764239 1.573628 -0.090354 +v -0.838825 1.333146 0.491136 +v -0.375011 0.402219 0.442966 +v -0.249820 0.817776 0.534211 +v -0.640672 0.901722 -0.188555 +v -0.641148 0.955099 -0.181146 +v -0.609599 0.941730 -0.190157 +v -0.694810 0.856565 -0.171984 +v -0.692014 0.930392 -0.164861 +v -0.670692 0.911446 -0.174259 +v -0.550472 0.527676 -0.039461 +v -0.526264 0.600438 -0.089567 +v -0.529785 0.595538 0.262119 +v -0.560014 0.618307 0.279312 +v -0.343340 0.409236 0.484258 +v -0.518874 0.533247 0.287056 +v -0.314878 0.469302 0.452532 +v -0.547073 0.634616 0.316706 +v -0.200181 0.675693 0.515654 +v -0.769873 1.536937 -0.022971 +v -0.838375 1.392786 0.448939 +v -0.822277 1.451377 0.406001 +v 0.256203 1.188072 -0.050331 +v -0.824039 1.218656 0.493650 +v -0.838036 1.256110 0.504405 +v -0.863891 1.216847 0.484125 +v -0.663920 0.377123 0.296220 +v -0.835778 1.205262 0.491775 +v -0.841508 1.295501 0.504837 +v -0.861536 1.273561 0.485640 +v -0.345026 0.761300 -0.223731 +v -0.776450 0.822149 0.357977 +v -0.764407 0.775111 0.337483 +v -0.712065 0.386086 0.007722 +v -0.724740 0.362559 0.015533 +v 0.313523 0.426493 -0.046745 +v 0.353499 0.412571 -0.028075 +v -0.772160 0.855949 0.374208 +v -0.851760 1.170681 0.481394 +v -0.866051 1.322681 0.467830 +v -0.750974 0.900736 0.395810 +v -0.637573 1.025114 -0.174844 +v -0.657286 1.070982 -0.143177 +v -0.605108 1.074845 -0.170423 +v -0.800698 0.905861 0.345931 +v -0.887637 1.194494 0.465601 +v -0.827110 1.164897 0.485186 +v -0.666429 1.604088 -0.568427 +v -0.559282 0.359173 0.463761 +v -0.237300 1.018616 -0.238364 +v -0.217305 0.984110 -0.243068 +v -0.716936 0.394610 0.060145 +v -0.696372 0.418813 0.031826 +v -0.825065 1.276549 -0.046796 +v -0.834485 1.339330 -0.016873 +v -0.806511 1.311985 -0.044398 +v -0.869906 1.381233 0.423166 +v 0.198385 0.965189 -0.227859 +v 0.239112 0.980217 -0.208073 +v 0.230880 0.939987 -0.222107 +v -0.658857 0.350251 0.294165 +v -0.532884 0.519258 0.117304 +v -0.797393 1.360685 -0.041482 +v -0.717522 0.367894 0.086967 +v -0.711659 0.393663 0.081142 +v -0.699973 0.420731 0.066898 +v -0.882521 1.269273 0.461413 +v -0.338970 0.570253 -0.110476 +v -0.328755 0.516776 -0.108886 +v -0.653521 0.992946 -0.168201 +v -0.667270 0.358958 0.338494 +v -0.789083 0.948309 0.354355 +v -0.652971 0.347790 0.337443 +v -0.869704 0.889121 0.248799 +v -0.863471 0.917221 0.268111 +v -0.858563 0.970254 0.274150 +v -0.690003 0.384677 0.107689 +v -0.569964 1.574171 0.006025 +v -0.692090 0.354548 0.120421 +v -0.838122 0.863377 0.292233 +v -0.837988 1.029069 0.280383 +v -0.670064 0.632929 -0.017494 +v -0.757294 1.035403 0.360710 +v -0.672534 0.381422 0.135340 +v -0.834181 0.941274 0.308985 +v -0.428190 1.622018 -0.103375 +v -0.576769 0.862583 -0.210983 +v -0.555226 0.819276 -0.213538 +v -0.803793 0.978007 0.336458 +v 0.017324 0.344597 -0.166079 +v -0.422768 0.949826 -0.225624 +v 0.214436 1.227383 -0.029317 +v -0.859860 1.467090 0.348271 +v -0.641608 0.359008 0.176876 +v -0.812214 0.810032 0.312559 +v -0.817040 1.016723 0.309397 +v -0.186857 1.868963 -0.202487 +v -0.536442 0.493582 0.122019 +v -0.859188 1.426341 0.398498 +v -0.637546 0.382501 0.165935 +v -0.810338 0.846982 0.331064 +v -0.791267 1.061988 0.320507 +v -0.772089 1.071589 0.347383 +v -0.027873 1.057753 -0.224590 +v -0.032078 1.096210 -0.215238 +v 0.025822 1.074758 -0.206060 +v -0.743148 1.376174 -0.066699 +v -0.785789 1.405013 -0.046031 +v -0.758293 1.424461 -0.058090 +v -0.790026 0.763393 0.292481 +v -0.317141 0.351115 -0.306590 +v -0.265689 0.346958 -0.291137 +v -0.063935 1.052447 -0.228419 +v -0.911321 1.228210 0.441152 +v -0.455306 0.985109 -0.217295 +v -0.518153 1.639258 0.017489 +v -0.289311 0.792476 -0.350498 +v -0.260820 0.761913 -0.367802 +v -0.261201 0.711775 -0.354515 +v -0.793348 1.256065 -0.061176 +v 0.095887 0.342072 -0.154240 +v 0.062813 0.341658 -0.187642 +v -0.627867 1.127419 -0.136054 +v -0.777215 1.135589 0.481560 +v 0.018527 1.130336 -0.197943 +v -0.885635 1.162453 0.453929 +v -0.272332 0.805710 -0.366207 +v 0.289903 0.446979 -0.061863 +v -0.634289 1.718539 -0.614121 +v 0.163870 1.140235 -0.154969 +v 0.217130 1.095634 -0.150811 +v 0.167326 1.099123 -0.170200 +v -0.083563 1.137360 -0.182398 +v -0.123544 1.155677 -0.164869 +v -0.066878 1.174721 -0.153593 +v -0.655936 1.766571 -0.605047 +v -0.053608 1.128940 -0.196133 +v -0.078240 1.092411 -0.221857 +v -0.091087 1.114167 -0.205432 +v 0.072130 1.272196 -0.052073 +v 0.094136 1.212190 -0.129378 +v 0.064155 1.179018 -0.162827 +v 0.044652 1.204404 -0.139314 +v 0.530564 0.697088 0.031292 +v 0.073447 0.945096 -0.296832 +v 0.242497 1.026615 -0.183138 +v 0.287231 0.979432 -0.174973 +v -0.701217 1.688263 -0.511736 +v -0.598312 0.428423 -0.066469 +v -0.740044 1.781852 -0.539163 +v -0.724555 1.761068 -0.535354 +v -0.254456 0.602086 -0.308647 +v -0.220432 0.536120 -0.301356 +v -0.697805 1.593857 -0.494182 +v -0.683826 1.598025 -0.542088 +v -0.745510 1.721874 -0.475510 +v -0.711565 1.633513 -0.453605 +v -0.771531 1.737868 -0.478676 +v -0.735026 1.687194 -0.447918 +v -0.713515 1.572709 -0.421831 +v -0.710573 1.547689 -0.457785 +v -0.742266 1.643701 -0.382403 +v -0.311334 0.496073 -0.194069 +v -0.776967 1.702789 -0.431179 +v -0.790877 1.704449 -0.413731 +v -0.728962 1.583496 -0.341094 +v -0.776772 1.661099 -0.367773 +v -0.735484 1.612082 -0.352884 +v 0.044630 1.242729 -0.094291 +v 0.129339 1.188725 -0.139794 +v 0.116208 1.154897 -0.163857 +v -0.602553 0.447496 -0.041316 +v -0.661224 0.423413 -0.027539 +v -0.718116 1.486132 -0.346395 +v -0.733866 1.546342 -0.299438 +v -0.293311 1.147623 -0.158446 +v -0.337154 1.115157 -0.180784 +v -0.295706 1.171387 -0.136755 +v 0.251308 0.345469 0.110126 +v 0.208979 0.359371 0.087849 +v 0.213247 0.346240 0.056444 +v 0.104736 0.347426 -0.112629 +v 0.119662 0.343354 -0.059571 +v 0.074147 0.346592 -0.030117 +v -0.151658 1.179807 -0.144655 +v -0.125018 1.063441 -0.223602 +v -0.265403 0.650840 -0.316649 +v -0.290875 0.729246 -0.333545 +v -0.309788 0.770209 -0.328165 +v -0.312257 0.804131 -0.321823 +v -0.785778 1.642064 -0.318258 +v 0.347429 0.922741 -0.156546 +v 0.315554 0.924847 -0.182043 +v -0.286807 0.682835 -0.306102 +v -0.311840 0.739895 -0.303399 +v -0.233702 0.933928 -0.320318 +v -0.277084 0.900813 -0.319114 +v -0.307341 0.854276 -0.305067 +v -0.756407 1.593040 -0.269084 +v 0.071346 1.146823 -0.183456 +v 0.105066 1.008770 -0.221095 +v 0.062723 0.999104 -0.222969 +v 0.071030 1.019116 -0.212310 +v -0.303249 0.676947 -0.276549 +v -0.332110 0.768732 -0.277084 +v -0.325906 0.819427 -0.291002 +v -0.786407 1.638724 -0.283878 +v -0.284257 0.621996 -0.279385 +v -0.332587 0.796217 -0.271460 +v -0.742302 1.565268 -0.251671 +v -0.290548 0.610841 -0.249182 +v -0.326066 0.719556 -0.248666 +v -0.782003 1.607321 -0.239997 +v -0.006731 1.011987 -0.228578 +v -0.275459 0.540216 -0.251474 +v -0.310669 0.650589 -0.227511 +v -0.442159 0.361315 -0.242522 +v -0.455329 0.347365 -0.213632 +v -0.422969 0.362919 -0.272536 +v -0.410515 0.415286 -0.240610 +v -0.381503 0.424666 -0.268940 +v -0.296471 0.581043 -0.213113 +v -0.812687 1.087944 0.294407 +v -0.457521 1.634075 -0.081780 +v -0.486400 1.647248 -0.050591 +v -0.760414 1.566307 -0.214205 +v -0.306039 0.380385 -0.301238 +v -0.068478 0.364445 -0.251771 +v 0.032222 0.387084 0.258988 +v 0.052497 0.395071 0.332712 +v -0.026442 0.387271 0.251313 +v -0.759178 1.499769 -0.168420 +v 0.134731 1.242989 -0.068361 +v 0.094116 1.235029 -0.098291 +v -0.449930 0.390170 -0.210978 +v -0.341905 0.475140 -0.223015 +v -0.340162 0.721013 -0.208231 +v -0.345886 0.447450 -0.271229 +v -0.736793 1.478599 -0.202363 +v -0.758047 1.513448 -0.198812 +v -0.749823 1.540779 -0.189744 +v -0.749241 1.527301 -0.193974 +v -0.161317 1.829885 -0.260372 +v -0.184057 1.784306 -0.242196 +v -0.214163 1.797766 -0.217325 +v -0.464626 0.368003 -0.177787 +v -0.148462 0.350709 -0.260719 +v -0.772067 1.563995 -0.189725 +v -0.232988 1.832431 -0.179230 +v -0.440313 0.419491 -0.179940 +v -0.302714 0.521061 -0.176761 +v -0.308094 0.569980 -0.178350 +v -0.568107 0.338739 -0.111663 +v -0.776504 1.565801 -0.165991 +v 0.291027 1.024751 -0.157684 +v 0.319129 0.998701 -0.146210 +v -0.278902 1.044070 -0.228309 +v -0.746100 1.472781 -0.141724 +v -0.451865 0.424534 -0.141936 +v -0.312895 0.552086 -0.143878 +v 0.259415 1.157635 -0.082194 +v 0.266662 1.126861 -0.105095 +v 0.204615 1.151537 -0.131038 +v -0.469123 0.346272 0.397397 +v -0.776188 0.739991 -0.053263 +v -0.742914 0.748084 -0.093538 +v -0.720716 0.715382 -0.074714 +v -0.838178 1.110909 0.285245 +v -0.754277 1.520121 -0.143937 +v -0.469906 0.388924 -0.140169 +v -0.313831 0.517913 -0.138868 +v 0.043714 1.039190 -0.215151 +v -0.104112 0.945923 -0.337848 +v -0.150781 0.938634 -0.343173 +v 0.283222 1.084796 -0.126234 +v 0.253192 1.093173 -0.135796 +v -0.765378 1.534487 -0.128987 +v -0.732631 0.799838 -0.137499 +v -0.769758 0.829359 -0.114506 +v -0.739454 0.843749 -0.151545 +v -0.338324 0.351688 0.469579 +v -0.172244 0.952141 -0.320853 +v -0.327484 1.775987 -0.116274 +v 0.116693 1.272015 -0.031851 +v 0.039735 0.382086 -0.037963 +v 0.023262 0.353482 0.023246 +v -0.008114 0.374242 0.047722 +v -0.764813 1.482741 -0.089376 +v -0.777706 0.878448 -0.116948 +v -0.800436 0.920802 -0.094198 +v -0.760467 0.910372 -0.136431 +v -0.787516 0.952403 -0.106007 +v -0.282124 1.111686 -0.180019 +v -0.769229 1.535139 -0.090785 +v -0.797237 0.842267 -0.087608 +v -0.814149 0.971003 -0.068746 +v -0.758629 1.507130 -0.090209 +v -0.130349 1.100286 -0.201612 +v -0.807283 0.882042 -0.078003 +v -0.261606 1.230999 -0.044735 +v -0.328217 1.230050 -0.059088 +v -0.213995 0.347951 -0.279588 +v -0.249541 0.374411 -0.291527 +v 0.162243 0.864804 -0.289520 +v 0.130970 0.911265 -0.292698 +v 0.167472 0.901140 -0.271272 +v -0.168038 0.397538 -0.275653 +v -0.829428 0.932917 -0.061856 +v 0.158001 1.199656 -0.114156 +v -0.746388 1.439848 -0.071504 +v 0.190766 0.918706 -0.248902 +v 0.226740 0.866061 -0.249255 +v 0.488059 0.684578 0.016953 +v -0.237569 0.385858 -0.110933 +v -0.080981 0.890701 -0.365522 +v -0.771349 1.515123 -0.055823 +v -0.218824 1.108742 -0.196953 +v -0.272540 1.074745 -0.212797 +v -0.792859 0.800488 -0.070125 +v -0.832725 0.894767 -0.056503 +v -0.195235 0.385052 -0.045434 +v -0.175879 1.149132 -0.172050 +v -0.236002 1.151382 -0.155774 +v -0.183207 1.196863 -0.111106 +v 0.074553 1.119679 -0.195542 +v -0.556740 0.569839 -0.033510 +v -0.540665 0.599593 -0.075992 +v -0.749015 0.704193 -0.022854 +v -0.827764 0.834309 -0.043687 +v -0.169704 1.111979 -0.195864 +v -0.773884 1.465643 -0.043543 +v -0.568979 0.496556 -0.015319 +v -0.805760 0.766078 -0.029879 +v -0.823540 0.808763 -0.024039 +v -0.849649 0.899625 -0.030068 +v -0.841668 0.977568 -0.032762 +v -0.809591 1.092667 -0.020190 +v -0.760513 1.110383 -0.062722 +v -0.585159 0.477313 0.002125 +v -0.070761 1.224012 -0.113644 +v -0.669788 0.676390 -0.068094 +v -0.720285 0.670466 -0.007225 +v -0.831094 1.026544 -0.032933 +v -0.812063 1.120509 -0.008830 +v -0.782252 1.496248 -0.025019 +v -0.511214 1.637412 -0.026640 +v -0.632420 0.455497 0.004843 +v -0.544207 0.478365 -0.059187 +v -0.574916 0.595302 -0.010786 +v -0.561479 0.619215 -0.057541 +v -0.790612 0.737243 -0.008452 +v -0.850422 0.838178 -0.000776 +v -0.856130 0.962771 -0.006651 +v -0.807679 1.430140 -0.015313 +v -0.864548 0.869405 0.009167 +v -0.857776 0.917014 -0.000470 +v -0.120830 1.221923 -0.097121 +v -0.303071 0.339954 0.147064 +v -0.540569 1.567160 -0.024866 +v -0.692421 0.414741 0.001929 +v -0.673152 0.440340 0.015742 +v -0.872404 1.196721 -0.001781 +v -0.880646 1.249676 0.005741 +v -0.856321 1.246109 -0.027336 +v -0.864430 1.276744 -0.014864 +v 0.258551 0.896107 -0.227018 +v 0.287911 0.911573 -0.203702 +v -0.800664 1.503965 0.006052 +v -0.820635 0.759937 0.017616 +v 0.309752 1.079025 -0.110584 +v -0.554737 1.605021 0.013764 +v -0.798588 0.727550 0.030420 +v 0.263480 0.845622 -0.231517 +v 0.075447 0.916822 -0.316431 +v 0.117275 0.880108 -0.308601 +v 0.305301 1.122121 -0.081860 +v -0.090179 1.252803 -0.077912 +v -0.196162 1.210920 -0.095488 +v 0.218150 1.177053 -0.100153 +v 0.426353 0.607975 -0.034584 +v 0.184009 1.214551 -0.076804 +v 0.136991 0.939142 -0.264277 +v 0.444085 0.697589 0.009477 +v 0.163635 0.343948 0.022949 +v 0.153228 0.362397 0.036629 +v 0.140143 0.357038 0.038879 +v 0.038149 0.390245 -0.080827 +v -0.013897 0.386514 0.023967 +v 0.179048 1.062771 -0.177292 +v 0.190169 1.040145 -0.193331 +v 0.173729 1.024604 -0.214877 +v -0.210005 1.231364 -0.061190 +v -0.358851 1.204004 -0.106405 +v -0.361250 1.228669 -0.082928 +v 0.457694 0.646288 -0.012166 +v -0.049613 0.393649 0.367022 +v -0.021999 1.121588 -0.196586 +v 0.459973 0.698144 0.030143 +v 0.461340 0.592788 -0.047770 +v -0.352833 0.341798 0.227449 +v -0.162404 1.251218 -0.036499 +v -0.619936 1.502806 -0.016297 +v -0.611140 1.530521 0.009999 +v -0.346923 0.338287 0.124386 +v -0.373144 0.336330 0.045725 +v -0.594667 1.474396 -0.018885 +v -0.586981 1.513732 -0.006580 +v -0.254259 0.414210 -0.292048 +v -0.277621 1.206854 -0.090153 +v -0.121305 1.257257 -0.052008 +v 0.396935 0.456586 -0.045274 +v -0.569923 1.431186 -0.022403 +v -0.561792 1.377441 -0.040674 +v -0.568960 1.339874 -0.056270 +v -0.500957 1.099092 -0.185045 +v -0.478594 1.116273 -0.174821 +v -0.455901 1.085383 -0.187967 +v -0.003084 0.354625 0.082607 +v -0.601273 1.204139 -0.093791 +v -0.543883 1.340492 -0.039920 +v -0.336235 1.184043 -0.119275 +v 0.125178 1.047538 -0.199159 +v -0.535901 1.243745 -0.073470 +v -0.523144 1.215965 -0.107980 +v -0.555781 1.156769 -0.146460 +v -0.604585 1.175565 -0.113546 +v -0.132803 0.376996 -0.263918 +v 0.024960 0.898576 -0.336284 +v -0.521243 1.292983 -0.041187 +v -0.507929 1.271649 -0.048183 +v -0.565443 1.285094 -0.062014 +v -0.489821 1.298065 -0.013229 +v -0.499068 1.178833 -0.144025 +v -0.480697 1.249303 -0.084076 +v -0.489844 1.148052 -0.159667 +v -0.477436 1.206443 -0.128130 +v -0.450826 1.221845 -0.115694 +v -0.464595 1.272395 -0.048843 +v -0.446974 1.179154 -0.147258 +v -0.421481 1.240963 -0.095602 +v -0.424595 1.139248 -0.161880 +v -0.416817 1.257511 -0.070193 +v -0.758241 1.079490 0.371288 +v 0.038064 1.094433 -0.202038 +v -0.402517 1.182753 -0.136741 +v 0.113474 0.362130 0.446523 +v -0.398428 1.215611 -0.115703 +v -0.382257 1.246552 -0.073257 +v 0.500065 0.580958 -0.046212 +v -0.366651 0.353042 0.230320 +v 0.099445 1.091972 -0.194728 +v -0.372182 1.159424 -0.151730 +v -0.374030 1.115077 -0.182433 +v 0.237060 0.802404 -0.254501 +v -0.382796 0.354290 0.243806 +v -0.770256 1.139676 -0.046168 +v -0.709172 1.075485 -0.114966 +v -0.737904 1.201666 -0.078851 +v -0.759961 1.171413 -0.065577 +v -0.752726 1.268010 -0.080241 +v -0.768901 1.304191 -0.069570 +v 0.475747 0.529436 -0.051300 +v -0.523252 1.061481 -0.192712 +v -0.551398 1.105160 -0.176727 +v 0.444732 0.532930 -0.063328 +v 0.443313 0.558180 -0.060363 +v 0.436732 0.501622 -0.059843 +v -0.479574 0.725430 -0.161070 +v 0.223400 0.584922 -0.260141 +v -0.679148 0.801363 -0.171282 +v -0.448539 1.574603 -0.086731 +v -0.590420 0.990322 -0.192229 +v -0.696084 0.723229 -0.109344 +v -0.643926 0.731163 -0.153353 +v -0.644807 0.701874 -0.122617 +v -0.503424 1.554620 -0.051927 +v -0.701776 0.756633 -0.138392 +v 0.368909 0.473532 -0.061057 +v -0.578468 1.043350 -0.185257 +v -0.548133 0.981025 -0.214254 +v -0.582324 0.956904 -0.206160 +v 0.386637 0.516967 -0.066910 +v -0.579895 0.740179 -0.175223 +v -0.642669 0.335625 -0.051253 +v -0.721462 1.348643 -0.077592 +v -0.625818 0.863945 -0.191693 +v -0.552653 1.021668 -0.198971 +v -0.545763 0.915630 -0.220987 +v -0.582656 0.909264 -0.209487 +v -0.442311 0.776641 -0.190266 +v -0.539945 0.646387 -0.093255 +v 0.336274 0.487177 -0.063905 +v -0.638362 0.817046 -0.189088 +v -0.489447 0.790864 -0.195757 +v -0.461242 1.050637 -0.204576 +v -0.506479 0.823094 -0.213659 +v -0.456432 1.546695 -0.072969 +v -0.448642 0.819979 -0.204735 +v -0.638523 0.655723 -0.069393 +v -0.489529 0.562811 -0.102209 +v -0.466503 0.598410 -0.121358 +v -0.484515 0.647941 -0.130299 +v -0.450084 0.627239 -0.133904 +v -0.418955 0.336683 0.269400 +v -0.603554 0.797666 -0.193755 +v -0.450788 0.872611 -0.218655 +v -0.443540 0.733722 -0.178744 +v 0.133599 0.393774 -0.224963 +v -0.034356 0.870179 -0.364610 +v -0.656099 0.758600 -0.167500 +v 0.228320 0.670826 -0.262975 +v 0.221044 0.726926 -0.269001 +v -0.509110 1.007457 -0.216194 +v 0.202845 0.513492 -0.248954 +v -0.457626 0.694453 -0.159288 +v 0.193050 0.790179 -0.277440 +v 0.199725 0.544097 -0.271082 +v 0.195204 0.620648 -0.272925 +v 0.196187 0.670074 -0.283561 +v 0.177581 0.701385 -0.294047 +v 0.157197 0.737564 -0.297478 +v 0.156783 0.511693 -0.263978 +v 0.151103 0.598198 -0.286457 +v 0.168421 0.555557 -0.282846 +v -0.211004 0.865877 -0.378490 +v 0.145191 0.645956 -0.298557 +v 0.155324 0.765870 -0.296069 +v -0.888278 1.135917 0.238737 +v 0.139640 0.455792 -0.247065 +v 0.122541 0.834567 -0.307716 +v -0.014089 0.361931 0.129446 +v -0.036954 0.381728 0.130468 +v 0.133761 0.486303 -0.265515 +v 0.107110 0.546876 -0.297675 +v 0.115741 0.748606 -0.313838 +v 0.114713 0.675814 -0.309012 +v 0.122752 0.699340 -0.315531 +v 0.106962 0.798892 -0.320096 +v 0.106377 0.441616 -0.249262 +v 0.081686 0.450530 -0.251787 +v 0.101498 0.492585 -0.277506 +v 0.103124 0.575865 -0.299952 +v 0.076270 0.620983 -0.311358 +v 0.097413 0.631814 -0.311414 +v 0.051821 0.415363 -0.240657 +v 0.062881 0.654164 -0.325630 +v 0.043919 0.386744 -0.241703 +v 0.054265 0.682480 -0.327305 +v 0.064980 0.707919 -0.335253 +v 0.087503 0.743016 -0.333982 +v 0.073335 0.852700 -0.328294 +v 0.066510 0.881445 -0.329458 +v 0.059436 0.509767 -0.291194 +v 0.053975 0.583826 -0.309038 +v 0.076016 0.794359 -0.337145 +v 0.068342 0.550102 -0.305611 +v 0.048214 0.737640 -0.345524 +v 0.049502 0.780273 -0.344097 +v 0.043843 0.458067 -0.267890 +v 0.037309 0.481280 -0.290260 +v 0.033102 0.604568 -0.324811 +v 0.018550 0.846928 -0.348385 +v 0.007583 0.704345 -0.344625 +v 0.012868 0.503837 -0.303574 +v 0.005928 0.528680 -0.305138 +v 0.021425 0.555028 -0.313344 +v -0.002283 0.433949 -0.251244 +v -0.002086 0.789414 -0.357821 +v -0.009629 0.453782 -0.273083 +v -0.011827 0.594924 -0.333609 +v -0.008661 0.645596 -0.344909 +v -0.045918 0.384046 -0.254129 +v -0.017033 0.478192 -0.299289 +v -0.022529 0.739213 -0.358872 +v -0.004271 0.829474 -0.363806 +v -0.044084 0.666192 -0.348702 +v -0.079469 0.414899 -0.259113 +v -0.036481 0.518690 -0.314579 +v -0.044102 0.827945 -0.374672 +v -0.052326 0.556890 -0.328402 +v -0.053433 0.782646 -0.374769 +v -0.059251 0.695156 -0.359335 +v -0.081088 0.434391 -0.261401 +v -0.087947 0.470569 -0.298816 +v -0.061353 0.602568 -0.346958 +v -0.073835 0.747996 -0.372238 +v -0.200863 0.380645 -0.172208 +v -0.082506 0.451487 -0.284411 +v -0.081798 0.498458 -0.310714 +v -0.085264 0.640017 -0.358505 +v -0.094246 0.553992 -0.336540 +v -0.106036 0.536029 -0.334033 +v -0.092015 0.595101 -0.344371 +v -0.085992 0.793387 -0.379052 +v -0.105386 0.679992 -0.365170 +v -0.100020 0.726715 -0.376614 +v -0.147316 0.776408 -0.384907 +v -0.112040 0.827133 -0.384896 +v -0.137538 0.518651 -0.322435 +v -0.123182 0.593964 -0.352685 +v -0.132360 0.692928 -0.379175 +v -0.265805 0.377426 0.157053 +v -0.149815 0.358782 -0.179924 +v -0.136911 1.791471 -0.281264 +v -0.173624 0.432374 -0.276652 +v -0.157484 0.450439 -0.278778 +v -0.144669 0.631360 -0.368659 +v -0.309847 0.381919 0.323901 +v -0.160188 0.742888 -0.388644 +v -0.158584 0.811656 -0.391856 +v -0.670783 0.338401 -0.061688 +v -0.171843 0.482105 -0.297419 +v -0.168119 0.612752 -0.359293 +v 0.388831 0.410330 0.249766 +v -0.179761 0.706138 -0.384439 +v 0.094293 0.360304 0.045275 +v 0.039678 0.342002 0.049755 +v 0.095485 0.342326 0.017162 +v -0.193022 0.582248 -0.339197 +v -0.177394 0.662608 -0.376573 +v -0.185021 0.833439 -0.390107 +v -0.211629 1.749185 -0.219771 +v -0.627918 0.345968 0.235056 +v -0.643003 0.350864 0.242721 +v -0.202253 0.770952 -0.390443 +v -0.212008 0.466571 -0.279513 +v -0.219113 0.671448 -0.365357 +v -0.696855 0.344788 0.097984 +v -0.230360 0.727785 -0.380726 +v -0.232001 0.765685 -0.383865 +v -0.231815 0.816870 -0.383291 +v -0.804691 1.135796 0.466435 +v -0.597122 0.631653 0.287892 +v 0.143227 0.344255 0.215932 +v 0.154490 0.348524 0.369849 +v 0.131970 0.348358 0.316310 +v 0.085288 0.348880 0.362651 +v 0.122242 0.351775 0.426206 +v -0.164714 0.348128 0.436847 +v 0.032907 0.358335 0.460246 +v 0.049172 0.339971 0.091666 +v 0.031492 0.341253 0.117622 +v -0.180315 0.348600 0.492648 +v -0.286576 0.350834 0.505494 +v 0.222529 0.365833 0.139797 +v 0.214998 0.358071 0.181694 +v 0.174901 0.346463 0.220409 +v 0.448765 0.412310 0.160083 +v -0.014104 0.369999 0.169820 +v 0.017024 0.363109 0.211796 +v -0.010974 0.381478 0.204270 +v 0.028888 0.346363 0.188498 +v 0.009171 0.348034 0.156347 +v 0.412613 0.405851 0.207519 +v -0.263231 0.346580 0.434735 +v -0.095064 0.383526 0.155707 +v -0.023474 0.359031 -0.159297 +v 0.239308 0.348167 0.177392 +v 0.100874 0.370477 0.308225 +v -0.081306 0.350083 0.475024 +v -0.028262 0.348853 0.456114 +v 0.200812 0.351727 0.280188 +v 0.132792 0.343795 0.214237 +v -0.642122 0.349926 0.394019 +v 0.064553 0.381652 -0.101649 +v 0.298590 0.349801 0.098349 +v -0.031105 0.389462 -0.027794 +v -0.094309 0.388877 -0.074849 +v 0.089808 0.376394 0.339008 +v 0.083833 0.347487 0.240573 +v -0.799405 1.091668 0.341198 +v -0.852296 1.120071 0.304170 +v -0.574341 0.576835 0.087260 +v 0.164393 0.356351 0.412810 +v 0.049318 0.348148 0.434621 +v 0.062194 0.351341 0.065493 +v -0.889795 1.145087 0.284460 +v 0.323692 0.358160 0.070246 +v 0.282486 0.350464 0.160167 +v 0.090016 0.368909 0.284822 +v 0.235895 0.358906 0.253377 +v -0.898226 1.138720 0.328453 +v -0.357116 0.358916 0.155029 +v -0.902540 1.136631 0.377202 +v 0.075208 0.367334 -0.067614 +v -0.856447 1.113172 0.342348 +v 0.158705 0.344162 -0.029666 +v 0.140554 0.344834 -0.144957 +v -0.877735 1.118141 0.371443 +v -0.011390 0.391768 -0.103814 +v -0.873599 1.124831 0.420495 +v -0.024719 0.384088 -0.141590 +v -0.648113 0.345306 0.155084 +v -0.898039 1.149811 0.427717 +v -0.847470 1.107835 0.394884 +v -0.112898 0.395292 0.388441 +v 0.334758 0.364473 0.162670 +v -0.020406 0.340539 -0.193311 +v -0.808945 1.096722 0.379102 +v -0.827619 1.116234 0.442215 +v -0.843413 1.138801 0.465135 +v 0.069064 0.390043 0.295485 +v 0.044817 0.371178 0.247553 +v -0.784498 1.098883 0.425179 +v 0.298685 0.362488 0.198722 +v -0.233200 0.391695 0.384733 +v -0.759508 0.681706 0.181180 +v -0.695388 0.630748 0.035758 +v -0.770396 0.719670 0.264051 +v -0.711130 0.627515 0.087996 +v -0.728014 0.643826 0.120891 +v -0.727901 0.643999 0.152060 +v -0.751653 1.115428 0.467072 +v 0.066606 0.352047 0.243159 +v -0.729164 0.650574 0.187946 +v -0.717221 0.670230 0.249598 +v -0.741076 0.695860 0.272644 +v -0.720361 1.110792 0.453614 +v -0.644798 0.606515 0.042343 +v -0.685435 0.610905 0.105578 +v -0.703258 0.633678 0.198092 +v -0.743628 0.724370 0.314301 +v -0.590022 0.592346 0.026141 +v -0.690662 0.337176 -0.001976 +v -0.685112 0.612146 0.153541 +v -0.612418 0.590074 0.080917 +v -0.645612 0.594841 0.130617 +v -0.666333 0.610017 0.181012 +v -0.696555 0.687284 0.311279 +v -0.648256 0.335059 0.028223 +v -0.668390 0.621705 0.215769 +v -0.708595 0.715101 0.338951 +v -0.713055 0.738990 0.359698 +v -0.673308 0.338464 0.087266 +v -0.670330 0.651460 0.272929 +v 0.081044 0.348429 0.181346 +v -0.559652 0.335299 -0.091246 +v -0.586041 0.334622 -0.002167 +v -0.611494 0.588344 0.165394 +v -0.660807 0.702027 0.355529 +v -0.617774 0.340179 0.169006 +v -0.585814 0.578015 0.134295 +v -0.622257 0.602652 0.204493 +v -0.633664 0.627903 0.256476 +v -0.636650 0.660478 0.318281 +v -0.527301 0.334979 -0.018117 +v -0.576806 0.336227 0.140403 +v -0.582260 0.666073 0.350503 +v -0.605693 0.711545 0.386538 +v -0.475216 0.336227 -0.128046 +v -0.442658 0.336637 -0.219144 +v -0.394819 0.336182 -0.236125 +v -0.450584 0.336005 -0.125275 +v -0.532105 0.335853 0.139870 +v -0.620190 0.343432 0.318833 +v -0.463802 0.336052 -0.008943 +v -0.470597 0.335019 0.035646 +v -0.540190 0.333099 0.158480 +v -0.557406 0.341280 0.266744 +v -0.541854 0.673227 0.369356 +v -0.410915 0.340060 -0.119975 +v -0.513509 0.336457 0.080329 +v -0.456759 0.337036 0.064300 +v -0.471043 0.355495 0.080804 +v -0.578894 0.344196 0.362658 +v -0.612634 0.346904 0.419949 +v -0.351991 0.338352 -0.205083 +v -0.412710 0.338554 -0.018801 +v -0.369705 0.356804 -0.150078 +v -0.396703 0.361740 -0.073398 +v -0.511766 0.680619 0.373983 +v -0.315898 0.355923 -0.192041 +v -0.334073 0.375770 -0.161582 +v -0.380666 0.385186 -0.073080 +v -0.273161 0.339101 -0.213537 +v -0.392220 0.363262 0.107899 +v -0.468708 0.344441 0.305131 +v -0.518477 0.344703 0.346352 +v -0.260754 0.359186 -0.194052 +v -0.307548 0.386398 -0.140508 +v -0.331634 0.381954 -0.005252 +v -0.278515 0.384043 -0.172104 +v -0.386393 0.339373 0.085507 +v -0.550398 0.573097 0.169909 +vn -0.865300 0.093700 -0.492400 +vn -0.900800 -0.025200 -0.433500 +vn -0.862600 -0.125800 -0.489900 +vn -0.974700 -0.212700 -0.068700 +vn -0.924600 -0.267000 -0.271700 +vn -0.957300 0.247700 -0.148800 +vn -0.138100 0.957800 0.252000 +vn -0.088100 0.920300 0.381100 +vn -0.223200 0.877500 0.424500 +vn 0.146500 0.871200 0.468600 +vn 0.335600 0.853700 0.398100 +vn 0.525700 0.705000 0.476000 +vn 0.117100 0.854200 0.506500 +vn -0.203200 0.774500 0.599000 +vn -0.611500 0.510700 0.604300 +vn -0.207300 0.716000 0.666600 +vn -0.538800 0.758300 0.366900 +vn -0.088200 0.993300 0.074500 +vn -0.172900 0.982400 0.070200 +vn -0.091700 0.977100 0.191800 +vn 0.553500 0.804500 0.215600 +vn 0.668000 0.616700 0.416400 +vn 0.769000 0.617100 0.166600 +vn -0.849500 -0.527300 -0.015700 +vn -0.814400 -0.563800 0.137300 +vn -0.942800 -0.327100 -0.063700 +vn 0.350300 -0.902400 -0.250800 +vn 0.034100 -0.918000 -0.395100 +vn 0.609000 -0.763800 -0.213700 +vn -0.915700 -0.398100 0.054200 +vn -0.991000 -0.093000 0.095700 +vn -0.989000 -0.128800 -0.072500 +vn 0.755100 0.589800 0.286100 +vn 0.666600 0.601000 0.440900 +vn 0.831600 0.291500 0.472600 +vn -0.504300 0.861900 0.053200 +vn -0.612200 0.753000 -0.241100 +vn -0.429700 0.848700 0.308300 +vn -0.204800 0.951400 0.229800 +vn -0.764100 -0.634100 -0.118300 +vn -0.868000 -0.441100 -0.227900 +vn 0.255000 0.900000 0.353400 +vn -0.129400 0.918500 0.373600 +vn 0.301200 0.859900 0.412000 +vn 0.800000 0.537700 0.266000 +vn 0.760300 0.542800 0.356800 +vn 0.854700 0.429300 0.291800 +vn 0.755800 0.544700 0.363500 +vn 0.655600 0.698400 0.286900 +vn 0.855800 0.486300 0.176400 +vn -0.354900 0.244300 -0.902400 +vn -0.713800 -0.522100 -0.466800 +vn -0.245800 -0.757000 -0.605400 +vn 0.519700 0.819000 0.243100 +vn 0.257300 0.918500 0.300400 +vn 0.693000 0.687200 0.218100 +vn 0.492200 0.825600 0.275600 +vn 0.304400 0.754600 0.581200 +vn 0.109300 0.870100 0.480500 +vn 0.635900 0.689600 0.346400 +vn -0.150800 0.893000 0.424000 +vn -0.426100 0.399700 -0.811600 +vn -0.166600 0.196100 -0.966300 +vn -0.154800 0.203400 -0.966800 +vn -0.308600 0.909100 0.279500 +vn -0.333600 0.872900 0.356100 +vn -0.319700 0.817900 0.478300 +vn -0.926000 0.377600 0.003800 +vn -0.956400 0.267800 0.116800 +vn -0.927600 0.364100 -0.083200 +vn -0.177700 0.930000 -0.321800 +vn -0.213500 0.966300 -0.143600 +vn -0.132600 0.981400 -0.138800 +vn -0.752500 -0.574200 -0.322500 +vn -0.810600 0.280500 -0.514000 +vn -0.768300 -0.165100 -0.618400 +vn -0.899700 -0.430100 -0.074000 +vn -0.994700 -0.067500 -0.077900 +vn -0.990000 -0.094700 0.104100 +vn -0.865200 -0.437900 0.244000 +vn -0.923900 -0.340800 0.174000 +vn -0.203700 0.978300 -0.036900 +vn -0.142300 0.989000 -0.040200 +vn -0.331600 0.905500 -0.264700 +vn -0.179000 0.626100 -0.758900 +vn -0.320100 0.873500 -0.366600 +vn -0.236400 0.963800 -0.122800 +vn -0.225500 0.973300 -0.042900 +vn -0.085500 0.995600 -0.038400 +vn -0.393300 0.342600 -0.853100 +vn -0.344100 0.020600 -0.938700 +vn -0.160000 0.067900 -0.984800 +vn -0.984300 0.165200 -0.061400 +vn -0.950400 0.310600 -0.015300 +vn -0.082900 0.940400 -0.329700 +vn -0.684700 0.642700 0.343600 +vn -0.482800 0.747600 0.456000 +vn -0.504700 0.808300 0.303100 +vn 0.093700 0.644100 0.759100 +vn 0.257500 0.583300 0.770300 +vn 0.154300 0.786600 0.597800 +vn -0.263600 0.963000 0.055100 +vn -0.179600 0.969900 0.164000 +vn -0.986700 0.151000 -0.060000 +vn -0.970000 0.149900 -0.191500 +vn -0.037400 0.999300 -0.006500 +vn -0.192000 0.892800 0.407400 +vn -0.288300 0.940800 0.178100 +vn -0.308900 0.924800 0.221900 +vn -0.369600 0.861700 0.347600 +vn -0.038100 0.968600 -0.245800 +vn 0.004800 0.993700 -0.111500 +vn -0.800700 -0.582500 0.139700 +vn -0.834500 -0.550000 0.032800 +vn 0.589100 0.710700 0.384600 +vn 0.874100 0.472000 0.114500 +vn -0.875400 0.268200 -0.402100 +vn -0.870600 0.401000 -0.284900 +vn -0.779800 0.263200 -0.568000 +vn 0.093300 0.945900 -0.310700 +vn 0.096700 0.538900 -0.836800 +vn 0.286800 0.508700 -0.811700 +vn 0.291100 0.743500 -0.602000 +vn 0.494400 0.816800 0.297200 +vn -0.157100 0.879900 0.448400 +vn -0.259700 0.865500 0.428200 +vn -0.623200 0.726600 0.289100 +vn -0.258200 0.962200 0.086600 +vn 0.006600 0.938800 0.344200 +vn -0.111400 0.921800 0.371400 +vn -0.030400 0.846500 0.531500 +vn -0.973500 -0.041700 -0.224800 +vn -0.999200 0.010400 -0.037400 +vn -0.971400 0.147400 -0.186200 +vn -0.514800 0.782200 0.350900 +vn -0.690900 -0.720500 -0.058900 +vn -0.679500 -0.730700 0.066500 +vn -0.791800 -0.564800 -0.232400 +vn -0.148000 0.833000 0.533100 +vn -0.063800 0.767800 0.637500 +vn 0.615400 0.337400 0.712300 +vn 0.190700 0.518900 0.833200 +vn 0.557600 0.623700 0.547700 +vn -0.886700 -0.413000 0.208000 +vn -0.981100 -0.112000 0.157700 +vn -0.949200 -0.314400 0.015100 +vn -0.386500 -0.309400 0.868800 +vn -0.152000 0.046800 0.987200 +vn -0.412800 0.188000 0.891200 +vn 0.051100 0.295200 0.954000 +vn -0.275500 0.442900 0.853200 +vn -0.419800 0.826200 -0.375700 +vn -0.221600 0.930900 0.290300 +vn 0.204100 0.918100 0.339600 +vn -0.332500 0.750800 0.570800 +vn -0.301900 0.825800 0.476300 +vn 0.007600 0.540600 0.841200 +vn -0.206000 0.699700 0.684100 +vn 0.344900 0.934300 0.089800 +vn -0.825300 -0.562900 0.043700 +vn -0.351800 -0.238000 0.905300 +vn -0.202600 0.579700 0.789200 +vn -0.232100 0.690100 0.685500 +vn -0.434300 0.558700 0.706500 +vn 0.234800 0.947600 0.216400 +vn 0.349900 0.776500 0.523900 +vn -0.455000 0.784500 0.421200 +vn -0.518900 0.478600 0.708300 +vn -0.595700 0.200800 0.777700 +vn -0.373800 0.524900 0.764600 +vn -0.929600 0.308200 -0.202000 +vn 0.047100 -0.573300 -0.818000 +vn -0.037200 -0.432100 -0.901100 +vn 0.076600 -0.491600 -0.867500 +vn 0.135900 0.085500 -0.987000 +vn -0.099000 0.061600 -0.993200 +vn -0.025000 0.112400 -0.993300 +vn -0.380700 0.825200 0.417200 +vn 0.084800 0.978600 0.187200 +vn 0.266000 0.810000 0.522500 +vn -0.058800 0.023000 0.998000 +vn 0.035600 0.516200 0.855700 +vn 0.925200 0.211800 -0.314900 +vn 0.838300 0.282400 -0.466400 +vn 0.863200 0.309200 -0.399100 +vn -0.912900 -0.372400 -0.167100 +vn -0.943800 -0.330400 0.010600 +vn -0.208800 0.963200 -0.169300 +vn -0.246100 0.969200 0.010300 +vn -0.986600 0.025500 -0.160900 +vn -0.994400 -0.066400 -0.081900 +vn 0.844000 0.499200 0.195800 +vn 0.137100 0.990300 -0.020200 +vn 0.061700 0.993100 0.099700 +vn 0.046900 0.636000 0.770200 +vn -0.664300 0.529300 0.527700 +vn -0.948600 0.278800 0.149600 +vn -0.857200 -0.028500 0.514100 +vn 0.158400 0.977100 -0.141600 +vn -0.405100 -0.386000 0.828800 +vn -0.143600 -0.094900 0.985000 +vn 0.344000 0.262000 0.901600 +vn 0.249200 0.388700 0.887000 +vn 0.033300 0.287100 -0.957300 +vn 0.047200 0.482800 -0.874400 +vn 0.144200 0.192100 -0.970700 +vn 0.534000 -0.786900 0.309100 +vn 0.463500 -0.884900 -0.044200 +vn 0.563200 -0.750900 0.344800 +vn -0.933100 0.064100 -0.353900 +vn -0.911600 0.269400 -0.310300 +vn -0.846900 0.365200 -0.386500 +vn 0.115100 -0.027900 -0.993000 +vn 0.047800 -0.281600 -0.958300 +vn -0.037600 -0.137900 -0.989700 +vn -0.575300 0.276300 -0.769900 +vn -0.292000 -0.080800 -0.953000 +vn -0.081100 -0.276500 0.957600 +vn -0.137200 0.804600 0.577700 +vn 0.052400 0.714200 0.698000 +vn -0.792600 0.225800 -0.566300 +vn -0.871700 0.089700 -0.481700 +vn -0.953600 -0.128300 -0.272400 +vn 0.298900 0.113700 -0.947500 +vn 0.267300 -0.178600 -0.946900 +vn 0.490600 0.168100 -0.855000 +vn 0.211800 0.099000 0.972300 +vn 0.234600 0.518700 0.822100 +vn -0.215000 -0.639900 0.737800 +vn 0.046400 -0.577700 0.814900 +vn 0.392300 -0.094700 -0.914900 +vn 0.923000 0.281800 -0.261900 +vn 0.890900 -0.166500 -0.422500 +vn -0.947800 0.019100 -0.318100 +vn -0.292800 -0.239700 -0.925600 +vn -0.209400 -0.423300 -0.881400 +vn -0.077100 -0.530900 -0.843900 +vn 0.918300 0.295600 -0.263200 +vn 0.877800 0.434700 -0.201200 +vn 0.937500 0.330900 -0.107900 +vn 0.567600 -0.330000 -0.754300 +vn 0.668000 -0.425400 -0.610600 +vn 0.619800 -0.603400 -0.501600 +vn -0.180300 -0.397100 -0.899900 +vn 0.453500 -0.859800 -0.234600 +vn 0.821700 -0.546000 -0.163100 +vn 0.931200 -0.326700 -0.161700 +vn 0.198700 0.308300 0.930300 +vn 0.190900 0.474900 0.859100 +vn 0.066600 0.500200 0.863300 +vn 0.450300 -0.543400 -0.708400 +vn 0.876700 0.479300 -0.039600 +vn 0.929700 0.368000 0.016700 +vn 0.749400 -0.236000 -0.618700 +vn 0.671700 0.291700 -0.680900 +vn 0.855600 0.234600 -0.461300 +vn 0.686100 0.366900 -0.628200 +vn -0.264000 0.959300 0.099900 +vn 0.013500 0.979200 0.202300 +vn -0.205700 0.158500 0.965700 +vn -0.371700 0.316400 0.872700 +vn -0.537400 0.198100 0.819700 +vn 0.247200 -0.291400 0.924100 +vn 0.328100 -0.234900 0.914900 +vn 0.070900 -0.560900 0.824800 +vn 0.052500 -0.172200 0.983600 +vn 0.394000 0.500800 0.770700 +vn 0.567400 -0.822200 0.044900 +vn 0.457100 -0.886800 -0.067000 +vn 0.533200 -0.830400 -0.161400 +vn 0.816600 -0.082400 -0.571300 +vn 0.868100 -0.290400 -0.402500 +vn 0.962000 0.018600 -0.272500 +vn 0.985300 0.054000 -0.161800 +vn 0.992400 0.050200 -0.112200 +vn -0.642500 0.592100 -0.486400 +vn -0.593200 0.803000 0.057400 +vn -0.749300 0.627600 0.211400 +vn -0.925100 0.229400 -0.302500 +vn -0.861300 -0.098900 -0.498300 +vn -0.844400 0.303900 -0.441100 +vn -0.703700 -0.709400 -0.038900 +vn -0.698000 -0.686600 -0.203200 +vn -0.695200 -0.685100 -0.217400 +vn -0.245400 0.264100 0.932700 +vn -0.206600 0.323900 0.923200 +vn -0.245900 0.021300 0.969000 +vn 0.093700 -0.301900 0.948700 +vn 0.018700 0.205600 0.978400 +vn 0.086700 0.214500 0.972800 +vn 0.036700 0.423800 0.905000 +vn 0.258100 0.405900 0.876700 +vn 0.375000 0.464200 0.802400 +vn 0.242900 0.595600 0.765600 +vn 0.316900 -0.343200 0.884200 +vn 0.110900 -0.134600 0.984600 +vn 0.115500 -0.434300 0.893300 +vn 0.577800 0.355400 0.734700 +vn 0.429200 0.180900 0.884900 +vn 0.918500 0.386700 -0.082100 +vn 0.993200 0.105000 0.050600 +vn -0.960600 0.272300 0.055500 +vn -0.958000 0.254900 0.131300 +vn -0.944000 0.319700 0.081700 +vn -0.819400 -0.032400 -0.572300 +vn -0.796100 0.059300 -0.602200 +vn -0.003700 0.909600 -0.415300 +vn 0.038400 0.853000 0.520400 +vn -0.221400 0.368600 0.902800 +vn 0.835500 -0.518800 -0.181000 +vn 0.795100 -0.559900 -0.233100 +vn 0.957500 -0.268300 -0.106000 +vn 0.057300 -0.445700 0.893300 +vn -0.070200 -0.738900 0.670100 +vn -0.006300 -0.359200 0.933200 +vn 0.083300 0.584400 0.807200 +vn 0.068700 0.747000 0.661200 +vn 0.087600 0.604800 0.791500 +vn 0.981400 -0.108300 -0.158500 +vn 0.702200 -0.711600 0.022700 +vn 0.827600 -0.383000 0.410300 +vn -0.983200 0.153600 0.098700 +vn -0.008100 -0.595000 -0.803600 +vn -0.097300 -0.599400 -0.794500 +vn 0.248300 -0.841000 -0.480700 +vn 0.973000 0.225400 0.049100 +vn 0.977500 0.200800 -0.064800 +vn 0.996300 0.083700 -0.020400 +vn -0.219100 0.937300 -0.270800 +vn -0.928700 -0.363700 -0.072400 +vn 0.277400 0.917400 -0.285300 +vn 0.024200 -0.997900 0.060300 +vn 0.025400 -0.996700 0.077000 +vn 0.016400 -0.998000 0.060000 +vn 0.321800 -0.402400 0.857000 +vn 0.213600 -0.283900 0.934700 +vn 0.140700 -0.707100 0.692900 +vn 0.170200 0.016300 0.985300 +vn 0.990500 -0.070000 -0.118100 +vn 0.943400 0.211700 -0.255400 +vn 0.917600 0.370900 -0.142900 +vn 0.783300 -0.465200 -0.412200 +vn 0.737400 -0.607700 -0.294900 +vn 0.445200 -0.607800 -0.657500 +vn 0.963700 -0.260600 0.057800 +vn -0.314700 0.129100 0.940300 +vn -0.443900 0.008100 0.896000 +vn -0.349600 0.161000 0.922900 +vn 0.218500 0.583100 0.782400 +vn 0.391200 0.598800 0.698800 +vn 0.091100 0.612800 0.785000 +vn 0.140500 0.182500 0.973100 +vn 0.227400 0.391900 0.891400 +vn 0.244300 -0.157300 0.956800 +vn 0.207900 -0.256600 0.943800 +vn 0.653700 0.273400 0.705600 +vn 0.279500 0.606500 0.744300 +vn 0.959000 -0.023100 -0.282500 +vn 0.971800 0.039200 -0.232400 +vn 0.892600 -0.094300 -0.440700 +vn 0.167200 0.960500 0.222400 +vn 0.334100 0.936000 -0.111100 +vn 0.460500 0.887100 -0.031400 +vn 0.456000 0.879200 -0.137600 +vn -0.282600 -0.376800 0.882100 +vn -0.242500 -0.222700 0.944200 +vn -0.460000 -0.325200 0.826200 +vn -0.470700 -0.148200 0.869700 +vn -0.219200 0.257800 0.941000 +vn 0.913300 -0.044100 -0.404800 +vn 0.936300 0.064300 -0.345300 +vn -0.017800 -0.277300 0.960600 +vn -0.083000 -0.379500 0.921400 +vn -0.054400 -0.274800 0.960000 +vn -0.088600 0.527800 0.844700 +vn -0.139300 0.696700 0.703600 +vn 0.105900 0.657300 0.746100 +vn 0.156400 -0.083300 0.984200 +vn 0.219300 -0.075800 0.972700 +vn 0.161300 0.021500 0.986700 +vn 0.518800 0.276300 0.808900 +vn 0.532700 0.284400 0.797100 +vn 0.344500 0.587100 0.732500 +vn -0.080800 -0.275400 0.957900 +vn -0.237300 -0.186800 0.953300 +vn 0.741000 -0.179700 0.647000 +vn 0.761300 -0.274100 0.587500 +vn 0.703400 -0.077300 0.706600 +vn -0.695500 -0.690100 0.200300 +vn -0.800800 -0.447600 0.397900 +vn 0.864900 0.389100 0.317000 +vn 0.855400 0.504200 0.118200 +vn 0.827400 0.486800 0.279900 +vn -0.518900 -0.174400 -0.836800 +vn -0.438600 -0.172900 -0.881900 +vn -0.548600 -0.363800 -0.752700 +vn -0.059200 -0.243000 0.968200 +vn -0.209300 0.117600 0.970700 +vn -0.068000 0.312700 0.947400 +vn 0.113600 -0.109300 0.987500 +vn 0.347200 -0.464700 0.814500 +vn 0.504500 -0.330400 0.797700 +vn -0.342300 -0.431700 -0.834500 +vn -0.523800 -0.344000 -0.779300 +vn -0.293600 -0.623000 -0.725000 +vn -0.174700 0.051200 0.983300 +vn 0.870400 -0.448900 -0.202300 +vn 0.774400 0.565600 0.283300 +vn 0.733900 0.501500 0.458100 +vn 0.820000 0.427700 0.380400 +vn -0.090400 0.301900 0.949000 +vn -0.069300 0.434100 0.898200 +vn 0.103800 0.132200 0.985700 +vn -0.025800 -0.301200 0.953200 +vn -0.152800 -0.056000 0.986700 +vn 0.138300 -0.201800 0.969600 +vn 0.483000 0.284800 -0.828000 +vn 0.630800 0.059400 -0.773600 +vn -0.974200 -0.162800 0.156200 +vn -0.988200 -0.071800 0.135400 +vn -0.948300 0.270700 -0.165500 +vn -0.318700 0.712700 0.624800 +vn 0.335400 -0.665500 -0.666700 +vn 0.229400 -0.829700 -0.508800 +vn 0.483600 -0.779800 -0.397500 +vn -0.292900 -0.803900 -0.517700 +vn -0.303700 -0.860700 -0.408600 +vn -0.319700 -0.906700 -0.274900 +vn -0.174400 -0.331100 0.927300 +vn -0.184700 -0.216600 0.958600 +vn 0.016100 -0.120600 0.992600 +vn 0.001400 0.126600 0.991900 +vn -0.138800 0.718300 0.681800 +vn 0.002300 0.502500 0.864600 +vn 0.293400 0.138300 0.945900 +vn -0.719400 -0.221700 -0.658200 +vn -0.702600 -0.160100 -0.693300 +vn -0.904300 -0.095600 -0.416100 +vn -0.150800 -0.114000 0.982000 +vn 0.044800 0.258100 0.965100 +vn 0.275000 -0.037800 0.960700 +vn 0.095400 -0.206500 0.973800 +vn 0.004000 0.107700 0.994100 +vn -0.882000 -0.350800 -0.314600 +vn -0.981800 0.071800 -0.175800 +vn -0.638400 -0.755000 -0.149400 +vn -0.114600 0.370400 0.921800 +vn 0.556500 0.142700 0.818500 +vn 0.281000 0.027500 0.959300 +vn 0.057200 0.388700 0.919600 +vn -0.469600 0.134700 -0.872500 +vn -0.745000 0.306600 -0.592300 +vn -0.591300 0.546900 -0.592600 +vn 0.016400 -0.065300 0.997700 +vn 0.420800 -0.569400 0.706200 +vn -0.437400 -0.317500 0.841400 +vn -0.712400 -0.165200 0.682000 +vn -0.494400 -0.117900 0.861200 +vn 0.248700 0.963700 0.096800 +vn 0.375600 0.858100 0.350100 +vn -0.272700 0.325500 -0.905300 +vn -0.364900 0.420200 -0.830800 +vn -0.315100 0.347500 -0.883100 +vn -0.164300 -0.527800 0.833200 +vn -0.058500 -0.488100 0.870800 +vn 0.183600 0.159800 0.969900 +vn 0.042100 0.415100 0.908800 +vn 0.177900 -0.039900 0.983200 +vn 0.258100 0.188000 0.947600 +vn 0.149000 0.205500 0.967200 +vn 0.995000 -0.067000 -0.074500 +vn 0.876500 0.300100 -0.376400 +vn 0.807600 -0.229300 -0.543300 +vn -0.040200 0.664400 0.746200 +vn -0.127900 -0.524100 0.842000 +vn -0.064800 0.879700 0.471100 +vn -0.630400 -0.620300 -0.466700 +vn -0.722200 -0.469000 -0.508300 +vn -0.058300 0.024200 -0.998000 +vn 0.107200 0.203200 -0.973200 +vn -0.123600 -0.146700 0.981400 +vn -0.026500 0.509600 0.860000 +vn 0.296000 0.048500 0.953900 +vn 0.067400 0.101200 0.992600 +vn -0.042000 0.091900 0.994900 +vn 0.987100 -0.094900 0.129100 +vn 0.991300 0.129900 0.021100 +vn 0.951800 0.141700 0.272100 +vn 0.132300 0.333500 0.933400 +vn -0.240900 0.346300 0.906600 +vn 0.074200 0.776000 0.626400 +vn -0.081300 0.673900 0.734300 +vn 0.145100 0.087600 -0.985500 +vn 0.317000 -0.897500 -0.306500 +vn 0.022000 -0.939600 -0.341600 +vn -0.059800 -0.575500 0.815500 +vn 0.044200 -0.307900 0.950400 +vn -0.070700 -0.030100 0.997000 +vn 0.024700 0.283900 0.958500 +vn 0.279800 0.281000 0.918000 +vn 0.083000 0.213100 0.973500 +vn -0.146200 0.164900 0.975400 +vn 0.275500 0.210100 0.938000 +vn 0.242000 0.261500 0.934400 +vn 0.236200 0.242900 0.940800 +vn 0.075100 0.672100 0.736600 +vn 0.374400 -0.918700 0.125600 +vn 0.349200 -0.936400 -0.033800 +vn -0.173600 0.935400 0.308100 +vn -0.347100 0.216900 -0.912400 +vn -0.012300 -0.340700 0.940100 +vn 0.026300 0.140500 0.989700 +vn -0.186400 -0.566400 0.802700 +vn 0.231500 0.462200 0.856000 +vn 0.120000 0.403300 0.907200 +vn -0.139000 0.495700 0.857300 +vn -0.065900 0.628500 0.775000 +vn 0.352300 0.242400 0.903900 +vn 0.422600 0.256900 0.869100 +vn 0.568500 0.212000 0.794800 +vn 0.120200 0.432100 0.893800 +vn 0.299300 0.714300 0.632500 +vn 0.676000 -0.691800 -0.253900 +vn 0.846700 -0.485700 -0.217000 +vn 0.814000 -0.575100 -0.081300 +vn 0.354700 0.423600 0.833500 +vn -0.567600 0.771800 -0.286700 +vn -0.463600 0.753000 -0.466900 +vn -0.698300 0.577900 -0.422300 +vn 0.771100 0.483700 0.414000 +vn 0.855700 0.355900 0.375500 +vn -0.148400 -0.286400 0.946500 +vn -0.376800 -0.207800 0.902700 +vn -0.369900 -0.342400 0.863600 +vn -0.454800 0.104500 0.884400 +vn -0.477700 -0.473500 0.740000 +vn 0.142500 -0.226800 0.963400 +vn -0.050100 0.173900 0.983500 +vn 0.017600 0.348000 0.937300 +vn -0.010400 0.522300 0.852700 +vn 0.056000 0.628800 0.775600 +vn -0.130700 -0.099100 0.986400 +vn 0.123000 -0.156900 0.979900 +vn -0.088300 -0.323100 0.942200 +vn 0.300500 0.534500 0.789900 +vn 0.280200 0.475800 0.833600 +vn 0.204400 0.446800 0.870900 +vn 0.881800 0.440500 0.168500 +vn 0.836100 0.536900 0.112700 +vn -0.018200 -0.343900 0.938800 +vn 0.094400 0.428500 0.898600 +vn 0.242500 -0.000200 0.970100 +vn 0.040800 0.535300 0.843700 +vn -0.060200 0.902400 0.426600 +vn 0.089800 0.727900 0.679700 +vn -0.421500 0.675400 0.605000 +vn 0.180400 -0.037600 0.982800 +vn 0.040800 0.174800 0.983700 +vn 0.180400 0.133600 0.974500 +vn 0.130800 0.397200 0.908400 +vn 0.157100 0.367400 0.916700 +vn 0.018400 0.341500 0.939700 +vn 0.998400 -0.035000 0.044200 +vn 0.952900 0.249200 0.172700 +vn 0.998300 -0.036100 0.046200 +vn 0.253500 0.477800 0.841100 +vn 0.918000 0.009700 0.396400 +vn 0.175800 -0.954000 -0.242800 +vn 0.063600 -0.973700 -0.218700 +vn 0.527700 -0.814400 -0.241300 +vn -0.088000 0.420400 0.903000 +vn 0.340600 -0.085500 0.936300 +vn -0.216100 0.914900 0.341000 +vn -0.150100 0.877900 0.454600 +vn 0.246200 -0.144100 -0.958400 +vn 0.625100 -0.506100 -0.594200 +vn -0.924300 -0.347000 0.158400 +vn -0.977100 0.209000 -0.040900 +vn -0.660000 -0.751200 0.006100 +vn 0.112900 0.208600 0.971400 +vn 0.028200 0.326300 0.944900 +vn 0.084400 -0.573600 0.814800 +vn 0.316000 -0.475700 0.820900 +vn 0.075700 -0.281000 0.956700 +vn -0.181700 -0.282100 0.942000 +vn 0.263200 0.201800 0.943400 +vn 0.212500 0.232300 0.949100 +vn 0.317000 0.169900 0.933000 +vn -0.174700 0.599600 0.780900 +vn -0.628300 0.061000 0.775500 +vn -0.798600 0.407000 0.443400 +vn 0.095300 -0.258600 0.961200 +vn 0.127800 -0.613300 0.779400 +vn -0.137500 0.405700 0.903600 +vn 0.014100 0.561900 0.827100 +vn 0.282700 -0.787900 -0.547000 +vn 0.692600 -0.662300 -0.285700 +vn -0.215200 0.141900 0.966200 +vn 0.274100 -0.189000 0.942900 +vn 0.367100 -0.131300 0.920800 +vn 0.285900 0.078700 0.955000 +vn 0.304500 0.063000 0.950400 +vn -0.988400 0.060500 0.139200 +vn -0.951100 -0.020500 -0.308200 +vn -0.998100 -0.000200 -0.060700 +vn 0.398200 -0.574500 0.715000 +vn -0.240700 0.726800 0.643200 +vn 0.191000 0.475400 0.858800 +vn 0.383300 0.127900 0.914700 +vn 0.316900 0.580800 0.749700 +vn 0.522300 0.329800 0.786400 +vn 0.799200 0.546000 -0.251100 +vn 0.545500 0.251400 -0.799500 +vn -0.119500 0.301300 -0.946000 +vn 0.153400 0.128300 0.979800 +vn 0.087000 -0.810600 -0.579000 +vn 0.434400 -0.797400 -0.418800 +vn 0.375400 0.302000 0.876200 +vn -0.845900 0.357200 -0.395900 +vn -0.700900 0.538700 -0.467400 +vn 0.002800 0.440200 0.897900 +vn 0.472200 0.819900 0.323500 +vn 0.705000 -0.131400 -0.696900 +vn 0.561500 0.008600 -0.827400 +vn 0.548400 -0.023100 -0.835900 +vn -0.194300 -0.273200 0.942100 +vn 0.136300 -0.111600 0.984300 +vn 0.173700 0.161900 0.971400 +vn 0.158200 0.340800 0.926700 +vn -0.065600 0.720300 0.690500 +vn -0.145200 -0.588800 -0.795100 +vn -0.001900 -0.807600 -0.589600 +vn 0.253100 -0.861400 -0.440300 +vn 0.142800 -0.758000 -0.636400 +vn 0.278500 -0.919300 -0.277800 +vn 0.536500 0.250800 0.805700 +vn 0.377200 0.226100 0.898100 +vn -0.103000 -0.030900 0.994200 +vn 0.064300 0.601200 0.796500 +vn 0.017500 0.641600 0.766900 +vn 0.992100 -0.034300 0.120200 +vn 0.947900 0.076900 0.309000 +vn 0.657600 -0.749400 -0.077100 +vn 0.127300 0.351300 0.927500 +vn -0.123600 -0.161700 0.979100 +vn -0.079000 -0.042300 0.996000 +vn 0.206900 0.444300 0.871600 +vn 0.732400 -0.655500 -0.184000 +vn 0.290300 -0.037300 0.956200 +vn 0.029200 -0.003500 0.999500 +vn 0.111600 0.464600 0.878500 +vn -0.965800 -0.221800 0.134100 +vn -0.136100 -0.117600 0.983700 +vn 0.030300 0.027400 0.999100 +vn 0.074200 0.207300 0.975400 +vn -0.965700 0.210700 0.151900 +vn 0.981800 -0.188500 -0.021400 +vn -0.011200 0.648100 0.761500 +vn 0.264100 0.318900 0.910200 +vn 0.143100 -0.187800 0.971700 +vn 0.042800 -0.169400 0.984600 +vn 0.007100 -0.101400 0.994800 +vn 0.992100 0.047500 0.115600 +vn -0.684800 0.728300 -0.025400 +vn -0.448000 0.890700 -0.077000 +vn 0.026300 0.078300 0.996600 +vn -0.083400 0.204800 0.975200 +vn -0.174400 -0.010000 0.984600 +vn -0.028300 0.304700 0.952000 +vn 0.101700 0.138600 0.985100 +vn 0.058500 -0.065900 0.996100 +vn -0.158900 -0.039700 0.986500 +vn -0.229900 0.035700 0.972500 +vn 0.014800 0.367600 0.929800 +vn 0.935700 0.300600 -0.184500 +vn 0.935200 0.349200 0.057800 +vn 0.976000 -0.217700 -0.008600 +vn 0.391800 -0.775400 -0.495100 +vn 0.358200 -0.681700 -0.637900 +vn 0.409100 -0.910200 -0.065100 +vn 0.480500 -0.713100 0.510500 +vn 0.170700 -0.120300 0.977900 +vn -0.236500 0.188400 0.953200 +vn 0.190100 0.396000 0.898300 +vn -0.012000 0.567200 0.823500 +vn 0.073100 0.578900 0.812100 +vn -0.000500 0.655000 0.755600 +vn -0.104100 0.801800 0.588400 +vn -0.377900 0.920100 0.102400 +vn -0.441400 0.892200 -0.095800 +vn -0.609500 0.783400 0.121100 +vn 0.580600 0.027600 0.813700 +vn 0.281600 0.484000 0.828500 +vn -0.115000 0.708400 0.696400 +vn -0.024000 0.578500 0.815300 +vn 0.031600 0.702700 0.710800 +vn -0.102800 0.679800 0.726100 +vn -0.135300 0.359900 0.923100 +vn 0.928300 0.082900 -0.362400 +vn 0.926900 -0.134200 -0.350500 +vn 0.623200 0.035700 0.781200 +vn 0.280100 -0.113900 0.953200 +vn 0.201700 -0.128800 0.970900 +vn 0.112400 0.022200 0.993400 +vn -0.031500 -0.094000 0.995100 +vn -0.189200 0.003600 0.981900 +vn -0.205900 0.378800 0.902200 +vn -0.131000 0.491000 0.861200 +vn 0.285300 -0.154300 0.945900 +vn 0.911700 0.394800 0.113900 +vn 0.940800 0.308900 0.139500 +vn 0.345200 -0.927300 -0.144400 +vn 0.673600 -0.705800 -0.219200 +vn -0.373900 0.530300 0.760800 +vn 0.039500 0.412100 0.910300 +vn 0.331700 -0.058700 0.941500 +vn 0.337700 -0.197100 0.920300 +vn 0.146900 -0.142600 0.978800 +vn -0.177000 0.532700 0.827500 +vn 0.185500 0.301500 0.935200 +vn 0.279900 0.302700 0.911100 +vn 0.024800 0.026200 0.999300 +vn 0.767100 -0.208900 0.606600 +vn 0.358900 -0.149300 0.921400 +vn -0.103500 -0.262900 0.959300 +vn -0.146500 -0.267400 0.952400 +vn -0.194200 0.474300 0.858600 +vn 0.510000 0.142700 0.848200 +vn 0.719700 -0.083700 0.689100 +vn 0.751600 0.624800 0.211300 +vn 0.488300 0.858700 0.155600 +vn 0.359200 -0.162500 0.919000 +vn 0.167700 -0.158000 0.973100 +vn -0.088100 0.638800 0.764200 +vn -0.046000 0.774600 0.630800 +vn -0.051500 -0.165500 0.984800 +vn -0.104800 0.518400 0.848600 +vn -0.069200 0.406800 0.910900 +vn 0.124800 0.085500 0.988500 +vn 0.250500 -0.191200 0.949000 +vn -0.019000 0.051800 0.998500 +vn -0.034200 0.204400 0.978300 +vn -0.521300 -0.800400 -0.295800 +vn -0.956900 -0.130200 -0.259400 +vn -0.984200 0.171100 -0.044800 +vn -0.481200 -0.193700 0.854900 +vn -0.139800 0.403500 0.904200 +vn 0.304500 0.399900 0.864400 +vn 0.051400 0.635000 0.770800 +vn 0.670300 -0.643100 -0.370300 +vn -0.097800 -0.241300 0.965500 +vn -0.481200 -0.308300 0.820600 +vn -0.657200 -0.111200 0.745400 +vn -0.389900 0.039600 0.920000 +vn 0.028100 0.226300 0.973600 +vn 0.991900 0.112200 0.059400 +vn 0.974600 0.186700 0.123300 +vn 0.618000 -0.376400 0.690200 +vn 0.117100 0.098600 0.988200 +vn 0.338200 0.402000 0.850900 +vn 0.297700 0.545600 0.783300 +vn -0.867200 -0.213800 0.449800 +vn -0.878400 0.042000 0.476000 +vn 0.779800 0.159700 -0.605300 +vn 0.825800 0.397200 -0.400300 +vn 0.255700 0.966000 0.037700 +vn -0.348700 -0.157200 0.923900 +vn -0.405800 0.167900 0.898400 +vn 0.843200 0.403300 -0.355400 +vn 0.810000 0.506500 -0.295600 +vn 0.211500 0.806200 0.552400 +vn 0.176200 0.620200 0.764400 +vn 0.909500 0.287200 0.300500 +vn 0.984000 0.075400 0.161200 +vn 0.729000 -0.633100 -0.260200 +vn 0.845600 -0.487400 -0.217700 +vn -0.314400 0.842300 0.437700 +vn -0.507200 0.704600 0.496200 +vn -0.315700 0.733300 0.602100 +vn -0.662800 -0.250000 0.705700 +vn -0.173900 0.155900 0.972300 +vn -0.259600 0.569900 0.779600 +vn -0.222800 0.440000 0.869900 +vn -0.114400 0.714200 -0.690500 +vn -0.114100 0.624900 -0.772300 +vn -0.148800 0.608200 -0.779700 +vn 0.077900 0.028700 0.996500 +vn -0.011200 -0.083300 -0.996500 +vn 0.961100 -0.267700 -0.067300 +vn -0.773300 -0.028800 0.633400 +vn -0.793900 -0.143200 0.590800 +vn -0.820900 -0.275400 0.500300 +vn -0.933300 -0.038100 0.357000 +vn -0.995800 -0.083000 0.039600 +vn -0.894500 -0.296000 0.334800 +vn 0.717900 -0.330100 0.612900 +vn -0.402200 0.358000 0.842600 +vn -0.212700 0.461400 0.861300 +vn -0.276900 0.645300 0.711900 +vn -0.159200 0.846600 0.507800 +vn -0.191700 -0.095600 -0.976800 +vn -0.241600 -0.397200 -0.885300 +vn -0.044600 0.791900 0.608900 +vn 0.145000 0.905500 0.398800 +vn 0.379200 0.925200 0.013200 +vn -0.401600 0.354200 0.844500 +vn -0.024100 0.619700 0.784500 +vn -0.367300 0.771500 0.519500 +vn -0.618000 0.471400 0.629200 +vn 0.547700 0.249800 0.798500 +vn -0.116500 0.333200 0.935600 +vn 0.238500 -0.899300 -0.366600 +vn 0.505200 -0.849700 -0.150900 +vn 0.710400 0.033700 0.702900 +vn 0.318900 0.479100 0.817700 +vn -0.124100 0.850700 0.510800 +vn -0.293300 0.392400 0.871700 +vn 0.103400 0.347700 0.931900 +vn 0.012100 0.817600 0.575700 +vn -0.063300 0.234100 0.970100 +vn -0.168400 0.642700 0.747400 +vn -0.108100 0.603400 0.790000 +vn -0.947400 0.096700 -0.305100 +vn 0.187800 0.900200 0.392900 +vn 0.756100 0.286500 0.588400 +vn 0.812900 0.375600 0.445100 +vn 0.462400 0.868600 0.177900 +vn -0.163600 0.364900 0.916500 +vn 0.416400 -0.124000 0.900700 +vn 0.342100 0.914000 0.218000 +vn -0.959900 0.220300 -0.173500 +vn -0.988100 -0.108200 0.109200 +vn -0.954400 -0.241900 -0.174500 +vn -0.275300 0.569900 0.774200 +vn 0.590600 0.321200 -0.740300 +vn 0.583200 0.215500 0.783200 +vn 0.380700 0.259500 0.887500 +vn -0.517900 0.161000 0.840100 +vn -0.778300 -0.127600 0.614700 +vn -0.113700 -0.328600 -0.937600 +vn -0.630900 -0.354400 -0.690100 +vn -0.473300 -0.411600 -0.778800 +vn 0.314600 0.703600 0.637100 +vn 0.323100 0.692300 0.645200 +vn 0.237300 0.543900 0.804800 +vn 0.028300 0.265300 0.963700 +vn 0.481800 -0.095900 0.871000 +vn 0.254600 0.066100 0.964800 +vn 0.157300 0.710200 0.686200 +vn -0.974700 0.191500 -0.114800 +vn -0.892100 0.416700 0.174300 +vn -0.725200 0.678900 -0.114600 +vn 0.391500 0.857700 -0.333200 +vn -0.459900 0.874900 0.151900 +vn -0.483900 0.846700 -0.221100 +vn 0.536100 -0.844000 0.012900 +vn -0.048100 0.304200 0.951400 +vn -0.327300 0.232000 -0.916000 +vn -0.588400 0.403800 -0.700500 +vn -0.185600 0.312300 -0.931700 +vn 0.284100 0.029400 0.958300 +vn 0.323300 -0.004600 0.946300 +vn 0.274700 0.481300 0.832400 +vn -0.261500 0.215300 0.940900 +vn -0.497700 -0.359500 0.789300 +vn 0.027600 0.995200 -0.093500 +vn 0.178700 0.963000 0.201800 +vn -0.230800 -0.607100 -0.760400 +vn -0.545700 0.042300 0.836900 +vn -0.388000 -0.267400 0.882000 +vn -0.284100 0.045600 0.957700 +vn -0.242000 -0.082000 0.966800 +vn 0.544200 0.347600 0.763500 +vn -0.151200 0.194100 0.969200 +vn -0.413400 0.326400 0.850000 +vn -0.129000 0.529200 0.838600 +vn -0.270200 0.557200 0.785200 +vn 0.696300 -0.159400 -0.699800 +vn 0.643600 -0.156200 -0.749300 +vn 0.567600 0.011400 -0.823100 +vn 0.277400 -0.079700 0.957400 +vn -0.583400 0.810400 0.053400 +vn -0.243400 -0.253200 0.936300 +vn 0.092300 -0.103300 0.990300 +vn -0.389800 -0.398300 0.830300 +vn -0.680300 -0.193900 0.706800 +vn -0.412700 -0.274000 0.868700 +vn -0.036800 -0.250300 0.967400 +vn -0.232200 0.440500 0.867200 +vn -0.418400 0.519200 0.745200 +vn 0.337900 0.874200 0.348600 +vn -0.006200 -0.990400 0.138000 +vn -0.069800 -0.857200 0.510100 +vn 0.002800 -0.995100 0.099100 +vn -0.162300 0.309800 0.936800 +vn -0.255700 0.632300 0.731300 +vn -0.017200 0.061900 0.997900 +vn -0.530400 -0.233300 0.815000 +vn -0.290700 -0.359900 0.886500 +vn -0.279400 -0.149200 0.948500 +vn -0.191400 -0.185400 0.963800 +vn 0.023600 -0.025600 0.999400 +vn -0.065600 0.206800 0.976200 +vn -0.238000 0.667000 0.705900 +vn -0.808500 0.143700 -0.570700 +vn -0.794400 0.228200 -0.562900 +vn 0.326900 0.932000 0.156600 +vn -0.194300 0.505800 0.840400 +vn -0.260200 0.753900 0.603300 +vn 0.555500 -0.733600 -0.391400 +vn 0.928100 -0.127000 -0.350000 +vn -0.075700 -0.255200 0.963900 +vn -0.070500 0.093200 0.993100 +vn -0.263500 -0.526900 0.808000 +vn -0.307100 -0.274000 0.911300 +vn -0.142600 -0.047900 0.988600 +vn -0.136000 0.155600 0.978400 +vn -0.161900 0.362700 0.917700 +vn 0.370000 0.468400 0.802200 +vn -0.271900 -0.362700 0.891400 +vn -0.278100 -0.187800 0.942000 +vn -0.199500 -0.113200 0.973300 +vn -0.083100 0.390300 0.916900 +vn -0.026200 0.151400 0.988100 +vn 0.962400 0.179800 -0.203700 +vn -0.039000 0.137200 0.989700 +vn -0.039700 -0.308600 -0.950300 +vn -0.306500 0.948100 0.084900 +vn -0.274500 -0.026500 0.961200 +vn 0.052100 0.108400 0.992700 +vn -0.088200 0.913100 0.398100 +vn -0.309900 0.818800 0.483300 +vn -0.024200 0.715100 0.698500 +vn -0.939900 0.306300 0.150800 +vn 0.356200 -0.043400 0.933400 +vn 0.249900 0.030600 0.967800 +vn 0.479600 0.004000 0.877500 +vn 0.792700 -0.147000 0.591600 +vn -0.480700 0.801800 0.355000 +vn 0.591600 0.475300 0.651200 +vn 0.481000 0.471700 0.738900 +vn 0.457800 0.342000 0.820600 +vn 0.440400 -0.161100 0.883200 +vn 0.557500 -0.447600 0.699100 +vn 0.440400 0.306600 0.843800 +vn 0.394300 -0.184000 0.900400 +vn 0.454400 -0.222700 0.862500 +vn 0.095600 -0.896200 0.433200 +vn 0.260300 -0.507500 0.821300 +vn 0.238100 -0.542100 0.805900 +vn 0.519200 0.399100 0.755700 +vn 0.433900 0.274600 0.858100 +vn 0.530600 0.323600 0.783400 +vn 0.576000 0.079600 0.813600 +vn 0.420400 -0.233600 0.876700 +vn 0.434600 -0.174500 0.883500 +vn 0.304300 -0.068800 0.950100 +vn 0.679500 -0.174100 0.712700 +vn 0.860200 -0.114900 0.496800 +vn 0.797900 -0.256800 0.545300 +vn 0.945100 0.073900 -0.318300 +vn -0.251600 0.031300 0.967300 +vn 0.264600 -0.304800 0.914900 +vn 0.757600 0.132200 0.639200 +vn 0.626400 -0.383100 0.678800 +vn -0.188000 -0.495200 -0.848200 +vn -0.001000 -0.631800 -0.775100 +vn 0.450800 -0.449400 0.771200 +vn 0.460600 -0.605500 0.649000 +vn 0.446500 -0.342300 0.826700 +vn 0.649400 -0.650700 -0.393500 +vn 0.662200 -0.688700 -0.295100 +vn 0.707800 -0.559700 -0.431000 +vn 0.691800 -0.014500 -0.721900 +vn 0.677200 -0.273500 -0.683000 +vn 0.754100 -0.298400 -0.585000 +vn 0.428900 0.555800 0.712100 +vn 0.180300 0.791500 0.584000 +vn 0.481400 -0.177000 0.858400 +vn 0.494000 -0.220600 0.841000 +vn 0.504500 -0.237800 0.830000 +vn 0.905100 0.343500 0.250400 +vn -0.654400 0.450400 -0.607300 +vn 0.454600 0.368200 0.811000 +vn 0.439800 -0.223400 0.869900 +vn 0.435500 -0.172700 0.883400 +vn 0.807200 -0.054000 0.587800 +vn 0.078900 -0.333100 0.939600 +vn -0.195000 -0.606100 0.771100 +vn 0.065500 -0.842200 0.535200 +vn 0.622800 0.278500 0.731100 +vn 0.718200 0.516600 -0.466200 +vn 0.791400 0.497000 -0.355800 +vn 0.796700 0.411700 -0.442500 +vn 0.705000 0.211400 0.676900 +vn -0.967500 0.240700 0.077500 +vn -0.906200 0.110500 0.408200 +vn -0.994600 0.082900 -0.061500 +vn 0.343100 0.537100 0.770600 +vn 0.702800 0.344300 0.622500 +vn 0.531100 0.390100 0.752100 +vn 0.476500 0.421300 0.771600 +vn 0.333200 -0.127700 0.934100 +vn 0.167600 0.723900 0.669100 +vn 0.313900 -0.797100 0.515800 +vn 0.028100 -0.703900 -0.709700 +vn 0.759800 -0.414700 0.500700 +vn 0.609900 -0.608400 0.507700 +vn -0.702900 -0.711100 -0.017200 +vn 0.641100 -0.138900 0.754700 +vn 0.774500 0.301100 0.556300 +vn 0.673000 0.083400 0.734900 +vn 0.796200 -0.354500 0.490200 +vn 0.488700 -0.508300 0.709000 +vn 0.562700 -0.691900 0.452400 +vn 0.219400 0.629000 0.745700 +vn 0.842500 0.040300 0.537100 +vn 0.935700 0.000600 0.352800 +vn 0.473100 -0.748500 0.464600 +vn 0.531700 -0.793600 0.295900 +vn 0.847700 -0.213300 0.485600 +vn 0.779200 0.326100 0.535100 +vn 0.836400 -0.064300 0.544300 +vn 0.800800 -0.254300 0.542200 +vn 0.812900 -0.093100 0.574900 +vn 0.685900 -0.024600 0.727300 +vn 0.729600 -0.192800 0.656100 +vn 0.816000 0.245600 0.523200 +vn 0.835400 0.335600 0.435300 +vn 0.758600 0.350000 0.549500 +vn -0.091500 0.126300 -0.987700 +vn -0.085200 0.233400 -0.968600 +vn 0.605000 -0.726600 0.325500 +vn 0.409700 -0.848400 0.335000 +vn 0.756000 -0.521300 0.395700 +vn 0.823500 0.084200 0.561000 +vn 0.930700 -0.324800 -0.168200 +vn 0.631500 0.447700 0.633000 +vn 0.808200 -0.034600 0.587800 +vn 0.768000 -0.020000 0.640100 +vn 0.706700 -0.060700 0.704900 +vn 0.625000 0.093100 0.775000 +vn 0.625300 0.033100 0.779600 +vn 0.550100 0.119700 0.826400 +vn 0.335400 0.646300 0.685400 +vn 0.693400 0.391100 0.605100 +vn 0.590200 -0.214200 0.778300 +vn 0.546900 -0.000800 0.837200 +vn 0.548800 -0.045600 0.834700 +vn 0.773800 -0.015100 0.633200 +vn 0.831800 0.062200 0.551500 +vn 0.751800 -0.027400 0.658800 +vn 0.743400 0.129600 0.656100 +vn -0.002400 0.419500 -0.907700 +vn 0.000500 0.390700 -0.920500 +vn 0.038700 0.274700 -0.960800 +vn 0.412200 0.131700 0.901500 +vn 0.731500 0.300000 0.612300 +vn 0.863600 0.342500 0.369800 +vn 0.794000 0.262900 0.548100 +vn 0.462600 0.224100 0.857700 +vn 0.513000 -0.084700 0.854200 +vn 0.545500 -0.570000 0.614400 +vn 0.376300 0.526900 0.762000 +vn 0.649000 0.423000 0.632300 +vn 0.554900 0.294700 0.777900 +vn 0.481700 -0.480300 0.733000 +vn 0.878200 -0.014700 0.478000 +vn 0.759200 0.068900 0.647200 +vn 0.002400 0.236400 -0.971600 +vn -0.139800 0.412100 -0.900300 +vn 0.843300 -0.041900 0.535800 +vn 0.477500 -0.333000 0.813000 +vn 0.619100 -0.394600 0.678900 +vn 0.538000 -0.374300 0.755200 +vn 0.461000 -0.157400 0.873300 +vn 0.666800 -0.379200 0.641500 +vn 0.611600 -0.018400 0.790900 +vn 0.590900 -0.188900 0.784300 +vn 0.385500 0.125500 0.914100 +vn 0.491700 -0.132100 0.860700 +vn 0.725900 -0.408500 0.553300 +vn 0.521300 -0.605900 -0.600900 +vn 0.582100 -0.521000 0.624100 +vn 0.599800 -0.341900 0.723400 +vn 0.508900 0.337400 0.791900 +vn 0.508700 0.462600 0.726100 +vn 0.611100 0.365500 0.702000 +vn 0.740300 -0.127300 0.660100 +vn 0.596000 -0.416000 0.686800 +vn 0.591400 -0.025100 0.806000 +vn -0.020700 0.323600 -0.946000 +vn 0.578700 -0.031600 0.814900 +vn -0.142900 -0.082200 0.986300 +vn 0.192500 0.075700 0.978400 +vn -0.847000 -0.312300 -0.430100 +vn 0.290700 0.001400 0.956800 +vn 0.708900 -0.644200 0.287100 +vn 0.606600 -0.468800 0.642000 +vn 0.451100 -0.887800 0.091600 +vn 0.541300 0.485200 0.686700 +vn 0.790300 0.145100 0.595300 +vn -0.489000 -0.542300 -0.683200 +vn 0.148900 -0.723500 -0.674000 +vn 0.441900 -0.423200 0.790900 +vn 0.633900 0.050200 0.771800 +vn 0.738600 0.040800 0.672900 +vn 0.466600 -0.442400 0.765900 +vn 0.440400 0.522600 0.730000 +vn 0.571400 0.271700 0.774400 +vn 0.688600 0.020800 0.724800 +vn 0.741400 -0.188300 0.644000 +vn 0.634500 0.338800 0.694700 +vn 0.584600 -0.565300 0.581900 +vn 0.536600 0.455300 0.710400 +vn 0.252800 0.776900 0.576600 +vn 0.669600 0.094100 0.736700 +vn 0.553700 -0.421100 0.718300 +vn 0.644000 -0.234900 0.728000 +vn 0.616900 0.353700 0.703100 +vn 0.444600 0.512500 0.734600 +vn 0.615000 0.363900 0.699500 +vn 0.550500 0.222000 0.804800 +vn 0.790300 -0.010300 0.612600 +vn 0.538400 0.478300 -0.693700 +vn 0.063800 -0.718300 -0.692700 +vn 0.701600 0.021900 0.712200 +vn -0.203000 -0.518100 0.830800 +vn 0.307600 0.169500 0.936300 +vn 0.449400 -0.863000 0.230500 +vn 0.267800 0.693300 0.669000 +vn 0.927500 0.254200 0.274000 +vn 0.578800 -0.795100 -0.181200 +vn 0.533100 0.131400 0.835800 +vn 0.620100 -0.061300 0.782100 +vn 0.247800 -0.111500 0.962400 +vn 0.664300 0.408100 0.626200 +vn 0.778200 -0.008000 0.627900 +vn 0.113000 -0.907500 0.404400 +vn 0.009500 -0.923300 0.384000 +vn 0.018300 -0.991400 0.129500 +vn 0.592800 -0.438600 0.675400 +vn -0.471500 0.167300 -0.865800 +vn -0.328900 0.221200 -0.918100 +vn 0.736000 0.179700 0.652600 +vn 0.859300 0.152100 0.488300 +vn 0.188200 -0.484700 0.854200 +vn 0.259300 0.193400 0.946200 +vn 0.670700 -0.566500 0.478700 +vn 0.706300 0.408700 0.578000 +vn 0.570900 0.481600 0.664900 +vn 0.759100 -0.053200 0.648800 +vn 0.573000 -0.028800 0.819100 +vn 0.580800 -0.223300 0.782800 +vn 0.599800 -0.172600 0.781300 +vn 0.700200 -0.261100 0.664400 +vn 0.613200 -0.165900 0.772200 +vn 0.848200 0.131300 0.513100 +vn 0.898100 0.072800 0.433700 +vn -0.272400 -0.943200 -0.190000 +vn -0.434800 -0.873800 -0.217400 +vn 0.513900 0.077100 0.854400 +vn 0.777100 -0.015300 0.629200 +vn 0.901000 0.086700 0.425000 +vn 0.506100 -0.467200 0.725000 +vn 0.543300 -0.128000 0.829700 +vn 0.521000 0.026500 0.853100 +vn 0.608500 0.283900 0.741000 +vn 0.104500 -0.543700 -0.832700 +vn 0.602200 -0.119100 0.789400 +vn 0.512600 -0.115300 0.850800 +vn 0.337600 -0.770500 -0.540700 +vn 0.427800 -0.690300 -0.583500 +vn 0.472200 -0.794300 -0.382200 +vn -0.531800 0.374000 0.759700 +vn 0.807900 0.369000 0.459500 +vn 0.973300 -0.093000 0.209900 +vn 0.863400 -0.416900 0.284100 +vn 0.618700 0.296600 0.727400 +vn 0.860500 0.507900 0.038600 +vn 0.580800 -0.140300 0.801800 +vn 0.573800 0.140400 0.806900 +vn -0.811500 0.305700 -0.497900 +vn -0.662900 -0.206400 -0.719700 +vn -0.358700 0.368500 -0.857600 +vn 0.820700 0.095700 0.563200 +vn 0.792700 0.309300 0.525300 +vn 0.435700 0.097100 0.894800 +vn 0.557600 -0.274100 0.783500 +vn 0.543000 0.192000 0.817500 +vn 0.639200 -0.051600 0.767300 +vn 0.643000 -0.251900 0.723300 +vn 0.646700 -0.331600 0.686800 +vn 0.560200 0.058500 0.826300 +vn 0.532200 0.049700 0.845100 +vn 0.933000 0.208200 0.293400 +vn -0.755800 -0.633200 0.166700 +vn 0.844600 0.234400 0.481400 +vn 0.384400 0.450700 0.805700 +vn 0.585000 -0.180100 0.790700 +vn -0.976800 -0.175500 0.122900 +vn -0.985700 -0.133000 -0.103000 +vn 0.605900 0.003600 0.795500 +vn 0.643600 -0.204600 0.737500 +vn 0.758800 0.153100 0.633000 +vn 0.254600 0.040800 0.966200 +vn 0.523000 -0.476600 0.706600 +vn 0.681200 -0.211400 -0.700900 +vn 0.763400 -0.109300 -0.636600 +vn 0.689100 -0.319500 -0.650300 +vn -0.507000 0.751500 -0.421900 +vn -0.617800 0.702800 -0.352700 +vn -0.334700 -0.271200 -0.902400 +vn 0.872500 0.139200 0.468300 +vn -0.461700 0.142900 -0.875400 +vn -0.577600 0.269600 -0.770500 +vn -0.437200 0.242300 -0.866100 +vn 0.134000 -0.978000 -0.159500 +vn 0.215800 -0.935500 -0.279800 +vn 0.760700 0.178600 0.624000 +vn 0.898800 -0.436100 0.042900 +vn 0.956100 -0.292900 0.001800 +vn 0.635800 -0.021400 0.771500 +vn -0.426900 -0.065400 -0.901900 +vn -0.600400 -0.456800 0.656400 +vn -0.757600 0.023000 0.652300 +vn -0.645400 -0.338600 0.684700 +vn -0.994400 -0.053100 0.091600 +vn 0.866100 -0.026000 0.499100 +vn 0.178800 -0.015600 0.983800 +vn -0.131200 -0.681800 -0.719600 +vn -0.282100 -0.547100 -0.788100 +vn -0.240000 0.239000 -0.940900 +vn -0.578900 0.367700 -0.727700 +vn -0.265900 -0.943200 -0.199200 +vn 0.398100 0.792100 -0.462600 +vn 0.194300 -0.630300 0.751700 +vn 0.133500 0.105600 0.985400 +vn -0.141900 0.012900 0.989800 +vn 0.418800 -0.689100 0.591400 +vn 0.826700 -0.521700 -0.210500 +vn 0.800100 -0.525200 -0.289700 +vn 0.776600 -0.564300 -0.280100 +vn -0.868700 -0.495100 -0.012500 +vn 0.077300 0.709600 -0.700300 +vn 0.676600 0.733500 0.065100 +vn 0.409100 -0.092200 0.907800 +vn 0.131900 0.822900 0.552600 +vn 0.925000 -0.202500 0.321500 +vn 0.796000 -0.527200 0.297200 +vn 0.921500 -0.320900 0.218700 +vn 0.626000 0.721900 -0.295000 +vn 0.501000 0.691800 -0.520100 +vn 0.181800 0.895700 -0.405800 +vn 0.787900 -0.613400 0.054500 +vn 0.717200 0.695500 -0.043000 +vn 0.905600 0.395200 0.153800 +vn -0.193500 -0.284000 -0.939100 +vn 0.289000 0.256700 -0.922300 +vn 0.558700 0.578700 -0.594000 +vn 0.312300 -0.024100 0.949600 +vn 0.089000 -0.960200 -0.264500 +vn -0.823700 0.495700 0.275400 +vn -0.514700 0.802100 0.302900 +vn 0.008800 0.932200 0.361700 +vn 0.606100 -0.160500 0.779000 +vn 0.552600 0.052800 0.831700 +vn -0.494000 0.105700 -0.863000 +vn -0.624500 0.337500 -0.704300 +vn -0.508700 0.071800 -0.857900 +vn -0.794300 -0.588700 0.149800 +vn 0.617800 -0.290300 0.730700 +vn 0.977700 0.145900 0.150900 +vn 0.875900 0.422300 0.233300 +vn 0.918500 0.292000 0.266500 +vn 0.574100 -0.637900 -0.513300 +vn 0.716700 -0.664800 0.210800 +vn 0.213100 -0.976900 -0.018600 +vn 0.385900 -0.913600 0.128300 +vn -0.210400 0.270300 -0.939500 +vn 0.438200 0.702300 0.561000 +vn 0.246300 0.717000 0.652000 +vn 0.450500 -0.146400 0.880700 +vn 0.325500 -0.504000 -0.800000 +vn -0.920900 0.044800 0.387200 +vn -0.958100 0.116600 0.261700 +vn -0.948500 -0.189400 0.253700 +vn -0.288500 0.737600 -0.610500 +vn 0.943100 0.028400 0.331400 +vn 0.873900 0.234400 0.425900 +vn 0.051500 -0.827600 0.558900 +vn 0.809600 0.334400 0.482400 +vn 0.656100 -0.641000 0.398300 +vn 0.366800 0.307000 0.878200 +vn 0.369100 0.540600 0.755900 +vn -0.120900 -0.011700 -0.992600 +vn -0.046800 -0.016400 -0.998700 +vn -0.107000 0.001400 -0.994200 +vn 0.319300 -0.050800 0.946300 +vn 0.017100 -0.999600 -0.022500 +vn 0.017100 -0.999800 -0.012600 +vn 0.028800 -0.999300 -0.024000 +vn 0.972000 0.064900 0.225800 +vn -0.132400 0.592300 -0.794700 +vn 0.377400 -0.882000 -0.282100 +vn 0.282500 -0.024500 0.958900 +vn 0.601200 0.128200 0.788700 +vn 0.833400 -0.072300 -0.547900 +vn 0.524000 -0.218900 0.823100 +vn -0.485900 0.809700 -0.328800 +vn -0.474800 0.841900 -0.256600 +vn -0.680200 0.471800 -0.560900 +vn 0.893100 -0.057800 -0.446100 +vn -0.103800 -0.036800 -0.993900 +vn 0.285600 0.375600 0.881700 +vn 0.956400 0.211700 -0.201100 +vn 0.402000 -0.353700 -0.844500 +vn 0.578000 0.260800 0.773200 +vn 0.992200 -0.123900 -0.007400 +vn -0.254700 0.800400 0.542600 +vn -0.629200 -0.777100 0.014400 +vn -0.029500 0.162100 -0.986300 +vn 0.306400 0.809100 0.501500 +vn -0.710900 0.617300 0.336800 +vn -0.737000 0.603000 0.305200 +vn -0.921900 0.321200 0.216400 +vn 0.836400 -0.142200 0.529300 +vn -0.148400 0.148200 -0.977700 +vn 0.039200 0.925400 -0.376900 +vn -0.711200 -0.682300 0.169100 +vn 0.850300 0.505100 -0.147400 +vn -0.023300 -0.074400 -0.996900 +vn -0.022900 -0.080000 -0.996500 +vn -0.028200 -0.032800 -0.999100 +vn -0.811700 0.439300 0.384800 +vn -0.956300 0.164800 0.241300 +vn -0.917600 0.270200 0.291500 +vn 0.933100 -0.348500 -0.088600 +vn -0.894300 -0.372100 0.248500 +vn -0.980800 0.133300 0.142500 +vn 0.941300 -0.320400 -0.106300 +vn 0.969100 -0.203300 -0.139400 +vn 0.999300 -0.036700 0.003500 +vn 0.993900 0.106900 -0.027800 +vn 0.955600 0.274200 0.107500 +vn -0.898300 -0.436400 -0.050500 +vn -0.524400 0.047900 0.850100 +vn -0.770200 0.208300 0.602800 +vn -0.655000 -0.323500 0.682800 +vn -0.734300 -0.610300 0.297000 +vn -0.974700 -0.108000 0.195400 +vn -0.380800 -0.588900 0.712900 +vn 0.030100 -0.999400 0.016700 +vn 0.032000 -0.999200 0.022100 +vn -0.889600 0.292100 0.351000 +vn -0.895400 -0.070500 0.439500 +vn -0.964200 0.058400 0.258600 +vn -0.910600 0.358100 0.206100 +vn -0.511300 0.555200 -0.656000 +vn -0.865900 0.473900 0.160300 +vn 0.992300 0.121900 0.020700 +vn -0.997500 0.062700 -0.032000 +vn 0.640600 0.189600 -0.744000 +vn -0.926700 -0.296800 -0.230300 +vn 0.671600 -0.225500 -0.705700 +vn 0.240000 -0.765500 0.596900 +vn 0.383200 -0.764000 0.519000 +vn 0.277900 -0.893700 0.352100 +vn -0.015900 -0.999300 0.034300 +vn -0.010700 -0.997900 0.063000 +vn 0.531000 0.099800 -0.841500 +vn 0.633400 0.168300 -0.755300 +vn 0.898200 0.261500 0.353300 +vn 0.926800 -0.201700 -0.316800 +vn -0.951200 -0.087200 -0.295900 +vn -0.937300 0.244000 0.248800 +vn -0.865200 0.278700 0.416800 +vn -0.662900 0.638500 -0.390900 +vn 0.957200 0.245600 0.153100 +vn 0.753100 -0.558500 -0.347500 +vn -0.855300 0.330900 -0.398700 +vn -0.863000 -0.315600 -0.394500 +vn 0.589500 -0.549500 -0.592000 +vn 0.366300 -0.866200 -0.339900 +vn 0.143600 0.801100 -0.581000 +vn 0.186600 0.804500 -0.563900 +vn 0.200800 0.835000 -0.512200 +vn 0.799400 -0.264500 -0.539300 +vn 0.796000 -0.022900 -0.604800 +vn 0.721100 -0.160000 -0.674100 +vn 0.761300 -0.463900 -0.453000 +vn 0.712300 -0.402900 -0.574700 +vn 0.460900 -0.431900 -0.775300 +vn 0.321700 -0.621800 -0.714000 +vn -0.912700 0.204700 -0.353500 +vn 0.753700 0.051200 -0.655200 +vn 0.727800 -0.061100 -0.683000 +vn 0.746500 -0.053500 -0.663100 +vn -0.004800 0.412500 -0.910900 +vn -0.878500 -0.323000 0.351900 +vn -0.735300 -0.520100 -0.434600 +vn -0.838400 0.543900 0.033600 +vn -0.840200 -0.533600 0.096400 +vn 0.856400 0.137900 -0.497500 +vn 0.739200 0.294900 -0.605500 +vn 0.107700 0.219000 -0.969700 +vn 0.008400 0.634100 -0.773200 +vn -0.099400 0.265900 -0.958800 +vn -0.364200 -0.583400 -0.725900 +vn -0.288200 -0.682100 -0.672000 +vn 0.601000 0.087000 -0.794500 +vn 0.681400 -0.015500 -0.731700 +vn 0.790700 0.275300 -0.546700 +vn 0.689700 0.190300 -0.698600 +vn 0.768700 0.260400 -0.584200 +vn -0.680400 -0.719400 0.139600 +vn -0.885900 -0.052000 -0.460900 +vn -0.845600 -0.295500 -0.444600 +vn 0.785000 -0.099900 -0.611400 +vn -0.940900 -0.046400 -0.335400 +vn 0.748400 -0.214900 -0.627400 +vn 0.813200 -0.222700 -0.537600 +vn 0.688000 -0.141800 -0.711700 +vn 0.642800 -0.136800 -0.753700 +vn 0.622600 -0.039100 -0.781500 +vn -0.895100 0.012600 -0.445600 +vn 0.179300 0.933200 -0.311400 +vn 0.171100 0.968600 -0.180400 +vn 0.273800 0.940500 -0.201400 +vn -0.021300 0.828800 -0.559100 +vn 0.001800 0.870900 -0.491500 +vn 0.015200 0.716800 -0.697100 +vn -0.300900 -0.534000 -0.790100 +vn -0.162500 -0.249600 -0.954600 +vn -0.183800 0.820800 0.540800 +vn 0.597100 -0.707700 0.377500 +vn 0.726100 -0.587300 0.357600 +vn -0.993100 -0.095900 0.067800 +vn -0.995900 0.079200 0.042800 +vn 0.696800 0.357100 -0.622000 +vn 0.824800 -0.310800 -0.472400 +vn 0.805800 -0.491600 -0.330100 +vn -0.976400 -0.134300 0.168700 +vn 0.562200 -0.798900 -0.213400 +vn -0.487000 -0.415200 0.768400 +vn -0.344200 -0.511200 0.787500 +vn -0.557700 0.628000 -0.542700 +vn -0.250300 0.623000 -0.741000 +vn -0.239500 0.901500 -0.360500 +vn -0.502800 0.760200 -0.411300 +vn 0.825600 0.004900 -0.564200 +vn 0.846500 -0.134400 -0.515100 +vn -0.683400 0.285800 -0.671700 +vn -0.547600 0.365600 -0.752600 +vn 0.878400 -0.227900 -0.420000 +vn 0.769000 -0.343500 -0.539100 +vn 0.719600 -0.650700 -0.242500 +vn 0.670900 -0.607900 -0.424600 +vn 0.538500 -0.789100 -0.295400 +vn -0.585300 0.710100 0.391300 +vn -0.892100 0.415800 0.176600 +vn 0.836300 -0.292700 -0.463500 +vn 0.416300 -0.511200 0.751900 +vn 0.572000 -0.796700 0.195000 +vn 0.392800 -0.907400 0.149200 +vn -0.391300 0.782000 0.485100 +vn -0.450000 0.766300 0.458500 +vn -0.959700 0.116800 -0.255600 +vn 0.023300 -0.962800 -0.269100 +vn 0.115200 -0.761000 -0.638400 +vn 0.111600 -0.936600 -0.332000 +vn 0.600500 0.029400 -0.799100 +vn 0.313800 0.097000 -0.944500 +vn -0.238900 -0.340500 -0.909400 +vn -0.609600 -0.342700 -0.714800 +vn -0.477200 0.878400 -0.027100 +vn -0.396400 0.860000 0.321200 +vn -0.704600 0.631400 0.323700 +vn -0.927900 -0.150400 -0.341200 +vn 0.182400 -0.789000 0.586700 +vn -0.861000 0.168200 -0.479900 +vn -0.786800 0.510900 -0.346200 +vn -0.683000 0.416200 -0.600200 +vn -0.212800 0.699500 -0.682200 +vn -0.124400 0.470400 -0.873600 +vn -0.335800 0.498400 -0.799300 +vn 0.665900 0.441500 -0.601300 +vn 0.607000 0.336900 -0.719700 +vn -0.717600 -0.656000 0.233900 +vn 0.926100 0.184800 0.328900 +vn -0.352200 -0.400300 0.846000 +vn -0.663400 -0.177700 0.726800 +vn -0.009900 0.332100 -0.943200 +vn -0.426700 -0.716400 -0.552000 +vn 0.239100 -0.444300 0.863300 +vn 0.605400 -0.021100 -0.795600 +vn -0.027800 -0.405300 -0.913800 +vn 0.001700 -0.376900 -0.926200 +vn 0.562200 -0.757700 0.331300 +vn -0.118000 0.688800 -0.715200 +vn 0.922500 0.341000 0.180800 +vn -0.807400 0.547000 -0.221000 +vn -0.652200 0.704000 0.280800 +vn 0.917500 -0.146800 -0.369700 +vn 0.847300 0.473500 0.240300 +vn -0.092400 0.903400 -0.418700 +vn 0.080300 0.891700 -0.445300 +vn 0.005900 0.848400 -0.529300 +vn 0.772500 -0.280900 -0.569500 +vn 0.303300 0.484600 -0.820500 +vn 0.596000 0.059100 -0.800800 +vn 0.190800 0.448100 -0.873300 +vn 0.645000 -0.113300 -0.755700 +vn -0.851100 0.399200 0.340900 +vn 0.807900 0.568300 -0.155800 +vn 0.475700 -0.236500 -0.847200 +vn -0.006000 -0.989600 0.143600 +vn 0.004900 -0.994900 0.100800 +vn -0.076400 -0.815700 0.573300 +vn -0.083900 -0.797000 0.598100 +vn 0.039200 -0.983500 0.176400 +vn -0.668100 -0.430800 -0.606700 +vn -0.573400 -0.565600 -0.592700 +vn -0.317300 -0.678200 -0.662800 +vn -0.973300 0.174900 -0.148700 +vn -0.904900 -0.398600 -0.149000 +vn -0.864400 -0.394500 -0.311600 +vn -0.175200 -0.323600 -0.929800 +vn 0.905200 0.320000 0.279600 +vn 0.185200 -0.456100 -0.870400 +vn 0.958200 0.120200 0.259700 +vn -0.232000 -0.627100 0.743600 +vn -0.405500 -0.814000 0.416000 +vn -0.280100 -0.791600 0.543100 +vn -0.505700 0.635600 0.583300 +vn 0.257900 0.433100 -0.863600 +vn 0.120200 0.515100 -0.848600 +vn 0.191200 0.686900 -0.701100 +vn 0.610100 0.118900 -0.783300 +vn 0.961000 0.160400 0.225100 +vn 0.678500 -0.722900 0.130700 +vn -0.289800 -0.269200 -0.918400 +vn -0.782700 -0.260700 -0.565100 +vn 0.922700 0.270800 0.274200 +vn 0.830500 0.458500 0.316100 +vn -0.756000 -0.575900 0.311000 +vn -0.863900 -0.386000 0.323500 +vn -0.795200 -0.562100 0.227200 +vn -0.164300 -0.207800 -0.964300 +vn -0.512900 -0.243100 -0.823300 +vn 0.630100 -0.688500 0.359100 +vn 0.056900 -0.982800 -0.175700 +vn -0.034800 -0.999100 -0.025100 +vn -0.076200 -0.904900 -0.418600 +vn 0.528500 -0.384500 -0.756900 +vn 0.811000 0.548800 0.202600 +vn -0.775100 -0.006800 -0.631700 +vn 0.559700 0.733800 0.385000 +vn 0.659200 0.747300 0.083400 +vn 0.641100 0.656100 0.398100 +vn 0.701200 0.710600 -0.057100 +vn -0.586900 -0.741800 -0.324500 +vn -0.510400 0.795700 0.326000 +vn 0.393500 0.879800 -0.266500 +vn 0.744300 0.667200 -0.026600 +vn 0.561000 0.796800 0.224300 +vn 0.306600 0.802500 0.511900 +vn -0.088300 0.990300 0.106900 +vn -0.076500 0.955800 0.283700 +vn -0.588100 0.799000 -0.124800 +vn 0.146100 0.935900 0.320500 +vn -0.000100 0.951700 0.307000 +vn 0.372300 0.914900 -0.156100 +vn 0.285700 0.957500 0.038700 +vn 0.207300 0.933400 0.292700 +vn -0.091900 0.907900 0.409000 +vn -0.222700 0.796000 0.562700 +vn 0.064100 0.996900 -0.043800 +vn -0.135200 0.986400 0.093200 +vn 0.058000 0.967000 -0.247900 +vn 0.216900 0.939700 0.264400 +vn -0.617900 0.422200 -0.663200 +vn 0.642400 0.765900 -0.028300 +vn 0.019300 0.413000 -0.910500 +vn 0.096800 0.995100 0.020000 +vn 0.263900 0.964100 -0.028900 +vn -0.840400 0.428400 -0.331900 +vn -0.419000 0.890400 -0.177800 +vn 0.161700 0.981000 0.107100 +vn 0.039200 0.980700 0.191600 +vn 0.045300 0.911300 0.409200 +vn 0.343800 0.876700 -0.336300 +vn 0.346300 0.924700 -0.158200 +vn 0.176500 0.961800 -0.209000 +vn -0.013000 0.998900 -0.045200 +vn -0.681000 0.526700 -0.508800 +vn 0.093200 0.987400 -0.128000 +vn 0.019200 0.998600 -0.049300 +vn -0.024700 0.999100 -0.034100 +vn 0.261100 0.965200 0.012800 +vn 0.404700 0.913900 -0.029400 +vn 0.177400 0.961300 0.210500 +vn 0.606100 0.727400 0.321700 +vn 0.045400 0.878800 0.474900 +vn -0.935800 -0.303900 0.178800 +vn -0.783100 0.520200 0.340600 +vn -0.457000 -0.596000 0.660300 +vn -0.888300 -0.179700 0.422500 +vn -0.705700 0.619200 -0.344200 +vn -0.916300 0.147100 -0.372400 +vn 0.517500 0.798600 0.307100 +vn 0.697100 0.572000 0.432200 +vn -0.025000 0.901100 0.432800 +vn -0.388000 0.915000 0.110200 +vn 0.176100 0.756300 -0.630000 +vn 0.005200 0.998500 0.054600 +vn 0.226800 0.952400 -0.203700 +vn 0.007700 0.943700 0.330700 +vn -0.710500 0.612100 0.347100 +vn -0.007500 0.930800 -0.365500 +vn -0.360500 -0.167200 -0.917600 +vn -0.986600 0.120500 0.110000 +vn 0.005600 0.821600 0.569900 +vn -0.558800 0.801000 -0.214800 +vn -0.879700 0.281000 0.383500 +vn -0.917800 0.378500 0.119700 +vn -0.989400 0.136500 0.049400 +vn -0.130400 0.954400 -0.268400 +vn 0.223900 0.970000 -0.094500 +vn -0.852400 0.507700 -0.124600 +vn 0.650900 0.592600 0.474400 +vn -0.520300 0.493900 -0.696600 +vn -0.552900 0.222800 -0.802900 +vn -0.777600 0.292700 -0.556400 +vn 0.813200 0.581800 -0.013900 +vn -0.849400 0.253400 0.462900 +vn -0.901500 0.305800 0.306200 +vn 0.760300 0.622200 0.186500 +vn -0.990200 -0.136000 -0.030600 +vn 0.771600 0.634100 0.049400 +vn -0.081600 -0.190300 -0.978300 +vn 0.041400 -0.337700 -0.940300 +vn -0.681100 0.732000 0.017000 +vn 0.762400 0.569900 -0.306500 +vn 0.535500 0.606200 0.588000 +vn 0.568100 0.712200 0.412300 +vn -0.593700 0.565200 0.572700 +vn -0.553800 0.771800 0.312500 +vn 0.048400 0.336500 -0.940400 +vn 0.014200 0.506700 -0.862000 +vn 0.233700 0.338100 -0.911600 +vn 0.748100 0.662900 -0.028000 +vn 0.697300 0.705000 0.129200 +vn 0.621300 0.728800 0.287800 +vn 0.751700 0.643800 -0.143300 +vn 0.673500 0.739200 0.006700 +vn 0.609800 0.780300 0.138900 +vn 0.654100 0.652600 -0.382300 +vn 0.720000 0.644200 -0.257900 +vn -0.895800 0.236700 -0.376100 +vn -0.077400 0.921500 -0.380500 +vn -0.491300 0.300100 -0.817600 +vn 0.645000 0.754400 -0.121200 +vn 0.516000 0.796900 0.314200 +vn 0.703400 0.584200 -0.404900 +vn -0.798100 -0.561800 0.217700 +vn 0.389500 0.841200 0.374900 +vn 0.031000 0.875300 0.482600 +vn 0.577500 0.814600 -0.053100 +vn 0.558600 0.828300 0.041700 +vn 0.470700 0.861700 0.189300 +vn 0.352400 0.802700 0.481000 +vn 0.572200 0.761400 -0.304600 +vn 0.561400 0.810900 -0.164700 +vn 0.431200 0.897200 0.095200 +vn 0.399100 0.876600 0.268800 +vn 0.490300 0.823800 -0.284500 +vn 0.019600 0.221000 -0.975100 +vn -0.739600 0.396000 -0.544200 +vn -0.776400 -0.241500 -0.582100 +vn -0.473200 -0.435200 -0.766000 +vn -0.844100 -0.536100 -0.010000 +vn -0.543000 0.644100 0.538800 +vn -0.855900 -0.324100 0.403000 +vn -0.974000 -0.005600 -0.226400 +vn -0.326500 -0.822700 0.465300 +vn -0.267300 -0.893100 0.361900 +vn -0.369200 0.801000 0.471200 +vn -0.490700 0.730700 0.474500 +vn -0.658400 0.528900 0.535400 +vn -0.349000 0.800100 0.487800 +vn -0.274300 0.648700 0.709900 +vn -0.420600 0.029200 0.906700 +vn -0.584500 -0.079300 -0.807500 +vn -0.327300 -0.075500 -0.941900 +vn -0.584900 0.239900 -0.774800 +vn -0.476700 0.679100 0.558200 +vn -0.814400 -0.360300 0.454800 +vn -0.686500 -0.332600 0.646500 +vn -0.813600 0.237700 0.530500 +vn -0.191600 -0.761900 -0.618700 +vn -0.802900 -0.320900 0.502300 +vn -0.805400 -0.325700 0.495300 +vn -0.849400 0.036000 0.526400 +vn -0.725500 0.445100 0.524800 +vn 0.156400 0.351800 -0.922900 +vn 0.020000 -0.999500 -0.021600 +vn 0.024600 -0.999300 -0.028900 +vn 0.048500 -0.998600 -0.020400 +vn -0.780100 0.447600 -0.437000 +vn -0.626000 0.460400 0.629300 +vn -0.546600 0.246700 0.800300 +vn -0.764700 -0.193600 0.614600 +vn -0.675000 0.435400 0.595700 +vn -0.416100 0.256200 -0.872500 +vn -0.694000 0.248800 0.675600 +vn -0.684900 0.710000 -0.163800 +vn -0.639900 -0.342000 0.688100 +vn -0.978100 0.119700 0.170300 +vn -0.914300 0.346000 0.210400 +vn -0.600000 0.375700 0.706200 +vn -0.724600 0.276000 0.631500 +vn -0.776600 -0.073100 0.625700 +vn -0.254600 0.068300 -0.964600 +vn -0.267700 0.194700 -0.943600 +vn -0.377500 0.111900 -0.919200 +vn -0.366600 -0.005000 -0.930400 +vn -0.346000 0.127900 -0.929400 +vn -0.359600 0.110400 -0.926500 +vn -0.786400 0.000000 -0.617700 +vn -0.624000 -0.243900 -0.742400 +vn -0.727700 -0.583000 0.361200 +vn -0.285600 -0.855700 0.431600 +vn -0.780500 0.231200 0.580800 +vn -0.977200 0.124200 0.172300 +vn -0.503000 0.717600 0.481700 +vn -0.231000 -0.827800 0.511200 +vn -0.616700 -0.374100 0.692600 +vn -0.836700 0.546000 -0.041400 +vn -0.577200 0.518700 0.630700 +vn -0.474500 0.651500 0.591900 +vn 0.538300 0.702200 -0.465900 +vn -0.280600 -0.259600 0.924000 +vn -0.503200 -0.174900 0.846200 +vn -0.506900 -0.074100 0.858800 +vn -0.968200 0.137700 -0.208700 +vn -0.160500 -0.088200 0.983100 +vn -0.654200 0.141800 0.742900 +vn -0.718100 0.070600 0.692300 +vn -0.929800 -0.231400 -0.286100 +vn -0.631000 -0.339900 0.697400 +vn -0.633000 -0.482300 0.605500 +vn -0.840400 0.408900 -0.355600 +vn -0.982000 -0.040300 -0.184700 +vn 0.175500 -0.549000 -0.817200 +vn 0.230000 -0.643900 -0.729600 +vn -0.641600 -0.161500 0.749800 +vn -0.370000 -0.332300 0.867600 +vn -0.753700 0.281900 0.593700 +vn -0.610800 -0.015100 0.791700 +vn -0.377100 0.191200 -0.906200 +vn -0.445500 0.340800 -0.827800 +vn -0.334900 0.329000 -0.882900 +vn -0.742300 -0.004700 0.670100 +vn -0.666700 -0.146100 0.730800 +vn -0.121600 -0.379900 0.917000 +vn -0.507500 -0.369300 -0.778400 +vn -0.060900 -0.581700 0.811100 +vn -0.036800 0.195600 -0.980000 +vn -0.068100 0.293900 -0.953400 +vn -0.930200 0.366600 0.015900 +vn -0.772800 0.621100 -0.130600 +vn -0.473100 0.148000 -0.868500 +vn -0.645500 0.270800 -0.714100 +vn -0.508000 0.203800 -0.836900 +vn -0.765700 0.390900 0.510800 +vn 0.284700 0.298800 -0.910800 +vn 0.435300 0.318600 -0.842000 +vn 0.406000 0.285700 -0.868000 +vn -0.717300 -0.679900 -0.152400 +vn -0.780000 0.125600 0.613100 +vn -0.586100 0.169300 -0.792300 +vn -0.873400 0.127400 0.470000 +vn -0.796700 0.402100 0.451200 +vn -0.738500 0.648100 0.185700 +vn -0.764100 0.151200 0.627100 +vn -0.308500 -0.275600 -0.910400 +vn -0.581700 0.391400 -0.713000 +vn -0.363400 0.090300 -0.927200 +vn -0.910500 -0.393400 0.127100 +vn -0.677800 0.106800 0.727400 +vn -0.382600 -0.921300 0.068600 +vn -0.881900 -0.224500 0.414600 +vn -0.844500 -0.076800 0.530000 +vn -0.825800 0.122600 0.550500 +vn -0.705700 0.373600 0.601900 +vn -0.706600 0.452300 -0.544100 +vn -0.740400 -0.289900 0.606400 +vn -0.839400 -0.170400 0.516100 +vn -0.775400 0.268600 0.571400 +vn -0.465700 -0.783100 -0.412100 +vn -0.604000 0.087600 0.792100 +vn -0.692700 0.377100 0.614700 +vn -0.768400 0.023700 0.639500 +vn -0.525300 0.001900 -0.850900 +vn -0.279900 -0.042300 -0.959100 +vn -0.131900 -0.205800 -0.969700 +vn -0.691700 0.162900 0.703500 +vn -0.098000 -0.889700 0.445900 +vn -0.129300 0.117000 -0.984600 +vn 0.459800 0.774800 -0.433900 +vn -0.634100 0.622300 0.458900 +vn -0.799000 -0.146600 0.583200 +vn -0.760800 -0.389100 0.519300 +vn -0.725500 0.218200 0.652600 +vn -0.368900 0.896400 -0.245500 +vn -0.711200 0.394700 0.581700 +vn -0.657100 0.538200 0.527700 +vn -0.609100 0.481300 0.630300 +vn -0.779600 -0.153100 0.607200 +vn -0.769500 0.071200 0.634600 +vn -0.752400 -0.359800 0.551700 +vn 0.154200 0.215400 -0.964300 +vn 0.180700 0.407500 -0.895100 +vn 0.139300 0.276800 -0.950800 +vn -0.357600 0.072400 -0.931000 +vn -0.597100 0.098300 -0.796100 +vn -0.520100 -0.015300 -0.854000 +vn -0.717100 -0.555200 0.421400 +vn 0.098500 -0.218600 -0.970800 +vn 0.226900 -0.590800 -0.774200 +vn 0.046100 0.211500 -0.976300 +vn -0.802900 0.092200 0.588800 +vn -0.009000 0.140600 -0.990000 +vn -0.606200 0.774300 0.181500 +vn -0.698500 -0.029200 -0.715000 +vn -0.565800 -0.147400 -0.811200 +vn -0.603900 -0.300800 -0.738100 +vn -0.421600 -0.003100 -0.906800 +vn -0.054400 -0.993600 0.098800 +vn 0.016800 -0.999800 -0.007100 +vn -0.382100 0.440900 -0.812200 +vn -0.357000 -0.638100 0.682100 +vn -0.024700 0.352800 -0.935300 +vn -0.629400 -0.444100 0.637700 +vn -0.567500 0.016000 -0.823200 +vn 0.334300 -0.509200 -0.793000 +vn -0.357800 -0.073400 -0.930900 +vn 0.330200 0.431100 -0.839700 +vn 0.358600 0.429900 -0.828600 +vn 0.329600 0.318200 -0.888900 +vn -0.089100 0.660500 -0.745500 +vn -0.028700 0.598700 -0.800400 +vn -0.038700 0.635700 -0.771000 +vn -0.443600 0.069400 -0.893500 +vn 0.119200 0.838600 -0.531400 +vn -0.051700 0.384600 -0.921600 +vn -0.199200 0.629000 -0.751500 +vn 0.109400 0.858500 -0.501000 +vn 0.162700 0.716500 -0.678400 +vn 0.108200 0.611900 -0.783500 +vn -0.045400 0.729300 -0.682700 +vn 0.142500 0.734200 -0.663800 +vn 0.306500 0.678800 -0.667300 +vn 0.391400 0.449800 -0.802800 +vn 0.555400 0.322900 -0.766300 +vn -0.861100 -0.286100 -0.420200 +vn -0.384800 0.590000 -0.709800 +vn -0.660100 -0.192300 -0.726100 +vn -0.651100 -0.517100 -0.555600 +vn -0.651800 -0.307500 -0.693200 +vn -0.462900 -0.366600 -0.807100 +vn -0.960300 0.009600 -0.278800 +vn -0.888800 -0.085600 -0.450200 +vn -0.450800 -0.655700 -0.605600 +vn -0.938500 -0.158900 -0.306400 +vn -0.525300 -0.607500 -0.595800 +vn -0.648100 -0.579300 -0.494400 +vn -0.982300 0.044800 -0.182000 +vn -0.965600 0.018100 -0.259300 +vn -0.718000 -0.572600 -0.395700 +vn -0.628100 0.751700 -0.200900 +vn -0.563700 -0.651500 -0.507800 +vn -0.938000 -0.271800 -0.215200 +vn -0.963700 -0.177800 -0.199200 +vn -0.642100 -0.656200 -0.396300 +vn -0.867800 -0.404400 -0.288700 +vn -0.019700 0.790200 -0.612600 +vn 0.280900 0.592500 -0.755000 +vn 0.272600 0.471000 -0.838900 +vn -0.486300 0.715500 -0.501600 +vn -0.546000 0.693000 -0.470700 +vn -0.299300 -0.935000 -0.190200 +vn -0.980300 0.132900 -0.145700 +vn -0.033900 0.612700 -0.789600 +vn 0.044400 0.486100 -0.872700 +vn -0.050300 0.723500 -0.688500 +vn -0.141400 -0.987900 0.063800 +vn -0.403100 -0.869900 0.284200 +vn -0.165200 -0.971600 0.169200 +vn -0.763200 -0.625500 0.162000 +vn -0.036000 -0.999100 -0.020300 +vn -0.370300 -0.899100 -0.233300 +vn -0.114400 0.725800 -0.678300 +vn -0.091600 0.377300 -0.921500 +vn -0.706700 -0.305700 -0.638000 +vn -0.732200 -0.282500 -0.619700 +vn -0.808000 -0.132200 -0.574100 +vn -0.846800 0.100400 -0.522300 +vn -0.897100 -0.393900 -0.200000 +vn 0.600800 0.475900 -0.642300 +vn 0.563700 0.324200 -0.759700 +vn -0.783800 -0.363000 -0.503700 +vn -0.863500 -0.295400 -0.408700 +vn -0.395600 0.779500 -0.485700 +vn -0.688100 0.568700 -0.450600 +vn -0.853700 0.336600 -0.397200 +vn -0.714000 -0.622100 -0.321100 +vn 0.178500 0.492000 -0.852000 +vn -0.054700 0.385400 -0.921100 +vn 0.126300 0.560800 -0.818200 +vn 0.124400 0.334800 -0.934000 +vn -0.865000 -0.300600 -0.401700 +vn -0.924800 -0.146600 -0.350900 +vn -0.890900 0.149200 -0.429000 +vn -0.995200 0.057200 0.079500 +vn -0.846500 -0.275500 -0.455500 +vn -0.931300 0.019000 -0.363600 +vn -0.903700 -0.345700 -0.252300 +vn -0.908100 -0.259800 -0.328400 +vn -0.910200 -0.276400 -0.308500 +vn -0.957600 -0.275500 -0.084000 +vn 0.127300 0.403000 -0.906300 +vn -0.815500 -0.139600 -0.561700 +vn -0.907300 -0.279800 -0.313800 +vn -0.860200 0.170900 -0.480500 +vn -0.889600 -0.298400 -0.345700 +vn -0.668900 0.234000 -0.705500 +vn -0.675800 0.489100 -0.551300 +vn -0.524100 0.527300 -0.668800 +vn -0.924100 -0.159800 -0.347000 +vn -0.793800 -0.442100 0.417500 +vn -0.615000 0.168900 -0.770200 +vn -0.695500 0.385800 -0.606100 +vn -0.705100 -0.612200 -0.357800 +vn 0.057300 0.138700 -0.988600 +vn 0.111800 -0.427700 -0.896900 +vn -0.254600 -0.914900 0.313000 +vn -0.159600 -0.986700 0.032000 +vn -0.003800 -0.997400 0.071400 +vn -0.975100 -0.207800 -0.077300 +vn 0.314000 0.794500 -0.519800 +vn 0.177400 0.797300 -0.576900 +vn -0.860900 0.361600 -0.357900 +vn -0.393600 0.854800 -0.338200 +vn -0.892800 -0.254600 -0.371400 +vn -0.320000 0.667300 -0.672400 +vn -0.750500 -0.643100 -0.151800 +vn -0.982900 0.166900 -0.077400 +vn -0.897600 -0.355100 -0.261200 +vn -0.956000 0.284100 -0.072500 +vn -0.612000 0.234200 -0.755400 +vn -0.605800 -0.060500 -0.793300 +vn -0.653800 0.176400 -0.735800 +vn -0.921700 0.265300 -0.282900 +vn 0.191300 -0.533900 -0.823600 +vn -0.810100 -0.526000 -0.259100 +vn -0.665400 0.594000 -0.452000 +vn -0.826300 0.504000 -0.251300 +vn -0.950600 0.173300 -0.257400 +vn -0.943900 -0.153900 -0.292200 +vn -0.257900 -0.537200 -0.803000 +vn -0.973800 -0.227500 0.002400 +vn 0.496000 0.361600 -0.789400 +vn 0.607100 0.193600 -0.770600 +vn -0.163500 0.327500 -0.930600 +vn -0.780600 -0.601600 -0.169400 +vn -0.809100 0.506700 -0.297600 +vn -0.941800 -0.117100 -0.315000 +vn 0.528600 0.617400 -0.582500 +vn 0.464100 0.545000 -0.698200 +vn 0.417900 0.502900 -0.756600 +vn 0.018600 -0.997300 0.070100 +vn -0.664800 -0.579900 -0.470800 +vn -0.602300 -0.524600 -0.601600 +vn -0.509700 -0.701200 -0.498500 +vn -0.608400 -0.770500 0.190100 +vn -0.986000 -0.126000 -0.109100 +vn -0.914400 0.290500 -0.281900 +vn -0.841800 0.396300 -0.366400 +vn 0.163900 0.244800 -0.955600 +vn 0.004400 0.720100 -0.693800 +vn -0.059400 0.714100 -0.697400 +vn 0.457800 0.496900 -0.737200 +vn 0.370700 0.521100 -0.768700 +vn -0.922700 -0.369900 -0.108100 +vn -0.600200 -0.364100 -0.712100 +vn -0.713900 -0.275900 -0.643600 +vn -0.565600 -0.142200 -0.812300 +vn -0.284400 -0.910800 0.299100 +vn -0.168200 0.863800 -0.474900 +vn -0.640400 0.677000 -0.362700 +vn 0.266300 0.853100 -0.448500 +vn -0.471600 -0.831300 -0.294200 +vn -0.549600 -0.770100 -0.323800 +vn -0.679000 -0.684700 -0.264600 +vn -0.948000 -0.191000 -0.254500 +vn -0.743200 -0.083400 -0.663900 +vn -0.741100 -0.022600 -0.671000 +vn -0.602500 0.057100 -0.796000 +vn -0.685800 0.176000 -0.706200 +vn -0.086500 0.560900 -0.823300 +vn -0.992300 -0.114700 -0.045400 +vn -0.860100 -0.197200 -0.470400 +vn -0.738800 0.212300 -0.639600 +vn -0.979700 -0.027500 -0.198400 +vn -0.090200 0.540300 -0.836600 +vn -0.752500 -0.149800 -0.641300 +vn -0.048300 0.928800 -0.367400 +vn 0.236300 0.846900 -0.476200 +vn 0.195600 -0.574600 -0.794700 +vn 0.206700 -0.061100 -0.976500 +vn 0.467400 0.165400 -0.868400 +vn 0.461400 0.433500 -0.774000 +vn 0.492700 0.412300 -0.766300 +vn 0.211100 -0.088000 -0.973500 +vn -0.800700 0.074000 -0.594400 +vn 0.354600 0.683900 -0.637600 +vn -0.705300 -0.425400 -0.567100 +vn 0.385400 0.382300 -0.839800 +vn 0.476800 0.214600 -0.852400 +vn 0.016000 0.681400 -0.731700 +vn 0.015100 -0.999800 -0.010700 +vn 0.154100 0.347800 -0.924800 +vn -0.978400 0.095700 -0.183000 +vn -0.090800 0.576800 -0.811800 +vn -0.171200 0.542500 -0.822400 +vn -0.751400 -0.332900 -0.569700 +vn -0.783300 -0.117100 -0.610400 +vn 0.022900 -0.999500 -0.022900 +vn -0.063800 0.635900 -0.769100 +vn -0.088600 0.674300 -0.733100 +vn -0.104300 0.778500 -0.618900 +vn 0.190500 0.274100 -0.942600 +vn -0.900400 -0.161300 -0.404100 +vn -0.672400 -0.325100 -0.665000 +vn -0.609900 -0.706000 -0.359900 +vn -0.793600 -0.298900 -0.529900 +vn 0.006200 0.516600 -0.856200 +vn -0.839000 -0.037500 -0.542800 +vn -0.866400 0.359300 -0.346800 +vn -0.809400 -0.429900 -0.399900 +vn -0.835900 -0.397500 -0.378500 +vn -0.898000 -0.046400 -0.437500 +vn -0.843800 0.158000 -0.512800 +vn -0.755100 0.283300 -0.591200 +vn -0.598100 0.312800 -0.737800 +vn -0.674700 0.717600 -0.172400 +vn -0.047900 0.697800 -0.714700 +vn -0.488100 -0.691200 -0.532900 +vn -0.589900 -0.701700 -0.399400 +vn -0.799300 0.245900 -0.548200 +vn -0.708100 -0.143100 -0.691400 +vn -0.878700 0.190900 -0.437400 +vn -0.735800 0.469500 -0.487900 +vn -0.414900 0.845700 -0.335700 +vn -0.577600 0.356000 -0.734600 +vn -0.656300 -0.675300 -0.336400 +vn -0.545700 -0.568400 -0.615600 +vn -0.693500 -0.662400 -0.283300 +vn -0.859200 -0.374600 -0.348500 +vn -0.915600 0.085800 -0.392700 +vn -0.788000 0.154600 -0.595900 +vn -0.912800 -0.140500 -0.383400 +vn -0.950300 0.021100 -0.310600 +vn -0.227600 0.764400 -0.603200 +vn 0.067500 -0.996800 0.043800 +vn -0.617200 0.171700 -0.767800 +vn -0.735100 0.541100 -0.408500 +vn -0.579500 0.780900 -0.233000 +vn -0.728500 -0.241000 -0.641200 +vn -0.863000 0.043400 -0.503400 +vn -0.668300 -0.020400 -0.743600 +vn -0.751000 0.188600 -0.632800 +vn 0.457100 0.248900 -0.853800 +vn 0.507900 0.273200 -0.816900 +vn -0.762300 0.406800 -0.503300 +vn -0.823000 -0.487600 -0.291300 +vn 0.556100 0.488600 -0.672300 +vn -0.753900 0.611800 -0.239400 +vn -0.683500 -0.683800 -0.255400 +vn 0.544000 0.105100 -0.832500 +vn 0.325000 0.408200 -0.853100 +vn 0.407300 0.153000 -0.900400 +vn 0.581400 0.581400 -0.569100 +vn -0.212500 0.798200 -0.563600 +vn -0.001100 0.799600 -0.600500 +vn 0.472600 0.636000 -0.610000 +vn 0.049500 0.420100 -0.906100 +vn 0.399700 0.758500 -0.514700 +vn 0.440700 0.608900 -0.659500 +vn 0.828900 0.109000 -0.548700 +vn -0.051300 -0.951100 0.304400 +vn -0.013900 -0.643800 0.765100 +vn 0.072500 -0.734400 0.674800 +vn -0.239600 -0.970800 -0.006000 +vn -0.241600 -0.956500 -0.163300 +vn 0.255200 0.451900 -0.854700 +vn 0.239100 0.658600 -0.713500 +vn 0.134200 0.568400 -0.811700 +vn -0.120500 0.879300 -0.460700 +vn 0.296100 0.671800 -0.678900 +vn 0.350100 0.690300 -0.633200 +vn 0.104000 0.526600 -0.843700 +vn 0.023100 -0.997200 0.070400 +vn 0.039300 0.516400 -0.855400 +vn 0.535000 0.424800 -0.730200 +vn -0.008400 0.411500 -0.911400 +vn -0.232600 -0.969500 -0.076600 +vn -0.219800 0.876900 -0.427500 +vn 0.557100 0.579700 -0.594700 +vn -0.298100 0.614700 -0.730200 +vn -0.260900 -0.955400 0.137900 +vn -0.001400 -0.999500 0.032400 +vn 0.327700 0.313600 -0.891200 +vn -0.369100 0.258600 -0.892700 +vn 0.121000 0.169100 -0.978100 +vn -0.015200 0.827800 -0.560900 +vn -0.267800 0.849400 -0.454800 +vn 0.277400 -0.554400 -0.784600 +vn 0.293600 0.345400 -0.891300 +vn 0.561700 0.270100 -0.781900 +vn 0.433500 0.189700 -0.880900 +vn -0.028500 0.351100 -0.935900 +vn 0.053000 0.436000 -0.898300 +vn -0.042300 0.416300 -0.908200 +vn -0.574400 -0.808600 -0.127100 +vn -0.125600 0.441200 -0.888600 +vn 0.575300 0.291800 -0.764100 +vn 0.093300 0.726000 -0.681300 +vn 0.143100 0.418800 -0.896700 +vn -0.099100 0.678300 -0.728000 +vn -0.204000 0.670800 -0.713000 +vn -0.233600 0.528300 -0.816300 +vn -0.322000 0.560300 -0.763100 +vn 0.174000 -0.190700 -0.966100 +vn 0.289000 0.283500 -0.914300 +vn 0.474700 0.382900 -0.792500 +vn 0.121800 0.682600 -0.720500 +vn 0.320600 0.193400 -0.927200 +vn 0.541100 0.613600 -0.575000 +vn -0.134000 0.520400 -0.843300 +vn -0.089400 0.771000 -0.630500 +vn -0.045200 0.438100 -0.897800 +vn -0.095200 0.641900 -0.760800 +vn -0.000300 0.666900 -0.745100 +vn 0.085200 0.883800 -0.460000 +vn 0.061000 0.486500 -0.871500 +vn 0.105700 0.760900 -0.640200 +vn -0.006600 0.465000 -0.885300 +vn 0.149000 0.871000 -0.468200 +vn -0.429600 -0.699200 0.571400 +vn 0.064600 0.140000 -0.988000 +vn 0.134900 0.552700 -0.822400 +vn 0.205400 -0.537500 0.817800 +vn 0.224900 0.610000 -0.759800 +vn 0.292000 0.810300 -0.508000 +vn 0.354300 0.098500 -0.929900 +vn -0.646200 -0.629800 -0.431000 +vn 0.227100 0.218400 -0.949100 +vn 0.093200 0.616500 -0.781800 +vn -0.022400 0.483500 -0.875000 +vn 0.513600 0.094600 -0.852700 +vn -0.532700 -0.201300 -0.822000 +vn -0.564000 -0.091300 -0.820700 +vn -0.463000 0.355400 -0.812000 +vn -0.262900 -0.110900 -0.958400 +vn -0.384900 -0.278000 -0.880100 +vn -0.305100 0.016800 -0.952100 +vn -0.412300 0.136600 -0.900700 +vn 0.432400 -0.238400 -0.869500 +vn -0.151600 0.299900 -0.941800 +vn -0.213200 0.381700 -0.899300 +vn 0.192000 -0.031400 -0.980900 +vn 0.048300 0.256000 -0.965500 +vn 0.260100 -0.315600 -0.912500 +vn -0.189200 -0.416600 -0.889200 +vn 0.521500 -0.018600 -0.853000 +vn -0.405500 -0.241300 -0.881600 +vn -0.425100 -0.221600 -0.877600 +vn -0.368700 0.180200 -0.911900 +vn -0.479100 -0.665500 -0.572300 +vn -0.319600 -0.601200 -0.732400 +vn -0.363600 -0.703000 -0.611200 +vn -0.501900 -0.101000 -0.859000 +vn -0.516300 -0.489100 -0.703000 +vn 0.122400 -0.315800 -0.940900 +vn -0.245700 0.230000 -0.941600 +vn -0.256600 0.182700 -0.949000 +vn -0.437700 0.147800 -0.886900 +vn 0.067000 -0.020300 -0.997500 +vn -0.093100 -0.492700 -0.865200 +vn -0.026600 -0.998400 -0.050500 +vn -0.231300 0.144800 -0.962000 +vn -0.285700 0.003200 -0.958300 +vn -0.288900 0.287400 -0.913200 +vn -0.123100 0.017100 -0.992200 +vn -0.464300 0.000300 -0.885600 +vn -0.050300 -0.341300 -0.938600 +vn -0.408100 -0.523100 -0.748200 +vn 0.118400 -0.218800 -0.968500 +vn -0.256600 -0.125300 -0.958300 +vn 0.068500 -0.427000 -0.901600 +vn -0.060400 0.358400 -0.931600 +vn 0.061600 -0.279900 -0.958000 +vn -0.331200 -0.379500 -0.863900 +vn 0.027900 -0.301400 -0.953100 +vn -0.356900 -0.721500 -0.593200 +vn -0.399900 -0.261600 -0.878400 +vn -0.249100 -0.298200 -0.921400 +vn -0.402100 -0.315400 -0.859600 +vn -0.107900 -0.313600 -0.943400 +vn -0.029600 -0.999000 0.034900 +vn -0.240100 -0.251600 -0.937600 +vn -0.011700 -0.141400 -0.989900 +vn -0.179300 -0.284100 -0.941900 +vn 0.328100 -0.358300 -0.874100 +vn 0.248700 0.254100 -0.934600 +vn -0.344200 -0.414900 -0.842200 +vn 0.607000 -0.128400 -0.784200 +vn 0.478100 0.035100 -0.877600 +vn -0.107600 0.237200 -0.965500 +vn 0.425200 -0.495500 -0.757400 +vn -0.261400 -0.363500 -0.894100 +vn 0.435600 0.053600 -0.898500 +vn 0.384900 -0.327200 -0.863000 +vn 0.421500 -0.114600 -0.899500 +vn 0.453700 -0.113800 -0.883800 +vn 0.407000 0.017100 -0.913200 +vn 0.392300 0.093400 -0.915000 +vn 0.345000 -0.421000 -0.838900 +vn 0.306700 -0.080300 -0.948400 +vn 0.292800 -0.183700 -0.938400 +vn -0.219300 0.288200 -0.932100 +vn 0.306400 -0.173600 -0.935900 +vn 0.416200 0.031200 -0.908700 +vn -0.639900 -0.746600 0.181700 +vn 0.307900 -0.352700 -0.883600 +vn 0.417400 0.069000 -0.906100 +vn -0.577000 -0.815800 0.038500 +vn -0.346700 -0.937900 0.005100 +vn 0.315700 -0.386000 -0.866800 +vn 0.237300 -0.219600 -0.946300 +vn 0.454400 -0.000400 -0.890800 +vn 0.203900 -0.205500 -0.957200 +vn 0.303600 -0.098400 -0.947700 +vn 0.461900 0.073600 -0.883800 +vn 0.096700 -0.247800 -0.963900 +vn 0.096000 -0.425700 -0.899700 +vn 0.186400 -0.456400 -0.870000 +vn 0.242900 -0.060700 -0.968100 +vn 0.271000 -0.248400 -0.929900 +vn 0.335300 -0.443100 -0.831400 +vn 0.110200 -0.192100 -0.975100 +vn 0.289100 -0.096500 -0.952400 +vn 0.164300 -0.080100 -0.983100 +vn 0.241400 -0.169900 -0.955400 +vn 0.267600 -0.258200 -0.928300 +vn 0.472500 -0.143100 -0.869600 +vn 0.355000 0.103600 -0.929100 +vn 0.278300 0.124300 -0.952400 +vn 0.203700 -0.349700 -0.914500 +vn 0.256700 -0.209700 -0.943400 +vn 0.361100 0.076700 -0.929300 +vn -0.042500 -0.214100 -0.975900 +vn 0.233900 -0.107900 -0.966200 +vn 0.255900 0.029800 -0.966200 +vn 0.212700 -0.634000 -0.743500 +vn 0.335600 -0.484600 -0.807800 +vn 0.295000 -0.229100 -0.927600 +vn 0.359700 0.139800 -0.922500 +vn 0.211300 -0.235700 -0.948500 +vn 0.211400 -0.175800 -0.961400 +vn 0.206100 -0.202600 -0.957300 +vn 0.213300 -0.303200 -0.928700 +vn 0.123800 -0.454200 -0.882300 +vn 0.296700 -0.044400 -0.953900 +vn 0.121500 -0.713600 -0.690000 +vn 0.222000 -0.266900 -0.937800 +vn 0.222300 -0.050800 -0.973600 +vn 0.125200 -0.126400 -0.984000 +vn 0.117300 -0.514600 -0.849400 +vn 0.228200 -0.155200 -0.961100 +vn 0.415400 0.034700 -0.909000 +vn 0.235800 -0.062200 -0.969800 +vn 0.142300 -0.074200 -0.987000 +vn 0.154100 -0.306700 -0.939200 +vn 0.227200 0.040600 -0.973000 +vn 0.165700 -0.281700 -0.945100 +vn 0.206600 -0.100800 -0.973200 +vn 0.224300 -0.175600 -0.958600 +vn 0.111000 -0.467400 -0.877000 +vn 0.006100 -0.513000 -0.858400 +vn 0.112300 -0.288000 -0.951000 +vn 0.188500 -0.144400 -0.971400 +vn -0.071900 -0.813500 0.577100 +vn 0.030600 -0.712100 -0.701400 +vn 0.083100 -0.435000 -0.896500 +vn 0.180400 -0.163500 -0.969900 +vn 0.200700 -0.235400 -0.950900 +vn 0.032900 -0.380000 -0.924400 +vn 0.160000 -0.281600 -0.946100 +vn 0.123800 -0.080800 -0.989000 +vn 0.255400 -0.171000 -0.951600 +vn 0.265600 -0.140100 -0.953800 +vn 0.123500 -0.038300 -0.991600 +vn 0.122800 0.009700 -0.992400 +vn -0.111300 -0.443100 -0.889500 +vn 0.104200 -0.321400 -0.941200 +vn 0.204200 -0.185300 -0.961200 +vn 0.859100 -0.507900 -0.063300 +vn -0.115700 -0.604600 0.788000 +vn -0.560300 -0.093800 -0.823000 +vn 0.116600 -0.044800 -0.992200 +vn 0.000800 -0.404300 -0.914600 +vn 0.068400 -0.282900 -0.956700 +vn 0.444100 -0.882500 0.154800 +vn 0.093800 -0.038800 -0.994800 +vn -0.044400 -0.104300 -0.993500 +vn -0.430700 -0.699100 -0.570700 +vn -0.189400 -0.467800 -0.863300 +vn -0.168300 -0.375000 -0.911600 +vn 0.351900 -0.833200 0.426400 +vn -0.072700 -0.177600 -0.981400 +vn 0.194600 -0.855200 0.480400 +vn -0.084800 -0.995000 -0.052000 +vn 0.039900 -0.977000 0.209600 +vn -0.343800 -0.393200 -0.852700 +vn -0.141800 -0.254200 -0.956700 +vn -0.078100 0.118000 -0.989900 +vn -0.492000 -0.151500 -0.857300 +vn -0.571200 -0.795500 -0.202300 +vn -0.754500 -0.441400 -0.485600 +vn -0.086900 -0.040400 -0.995400 +vn -0.182900 -0.134500 -0.973900 +vn -0.420200 -0.325700 -0.846900 +vn -0.424400 -0.862800 0.274600 +vn -0.345700 -0.195200 -0.917800 +vn -0.323300 -0.066100 -0.944000 +vn -0.288600 0.098600 -0.952300 +vn -0.286800 -0.543000 0.789200 +vn -0.243100 -0.860600 0.447500 +vn 0.050400 -0.997800 0.042600 +vn 0.105500 -0.991800 0.072100 +vn -0.207500 -0.978200 -0.001700 +vn -0.171500 -0.982500 -0.072200 +vn 0.137200 -0.940200 0.311800 +vn 0.013800 -0.999800 0.015700 +vn 0.177200 -0.560800 0.808700 +vn 0.034600 -0.999000 -0.029400 +vn -0.177700 -0.983800 0.022500 +vn 0.035300 -0.979000 0.200800 +vn -0.156400 -0.946200 0.283200 +vn -0.477100 -0.878200 -0.032700 +vn -0.191100 -0.909700 -0.368600 +vn 0.041800 -0.999100 0.008500 +vn 0.460300 -0.880200 0.115600 +vn -0.667500 -0.702700 0.246200 +vn -0.525400 -0.730900 0.435500 +vn -0.365400 -0.903700 0.222900 +vn -0.297600 -0.932200 0.205700 +vn -0.434100 -0.894000 0.110300 +vn 0.404600 -0.874300 0.268100 +vn -0.021500 -0.998300 0.054400 +vn 0.006600 -0.999900 0.004600 +vn -0.123400 -0.623400 0.772100 +vn -0.122900 -0.991400 -0.044900 +vn -0.634800 -0.771000 0.049700 +vn 0.088200 -0.948200 0.305200 +vn 0.062800 -0.958500 0.278000 +vn 0.227100 -0.968800 0.099100 +vn -0.025200 -0.999300 0.027800 +vn -0.430200 -0.873600 0.227600 +vn -0.441200 -0.888500 0.126500 +vn 0.183400 -0.982800 -0.021400 +vn 0.002000 -0.999300 -0.037800 +vn 0.031100 -0.999200 -0.022300 +vn -0.820500 -0.529000 -0.216500 +vn -0.154400 -0.968600 0.194700 +vn -0.490700 -0.860200 0.138800 +vn -0.483700 -0.870400 -0.091100 +vn -0.466600 -0.881200 0.076000 +vn 0.323600 -0.875700 0.358300 +vn 0.056700 -0.998400 0.002100 +vn 0.389800 -0.920800 -0.011300 +vn -0.624700 -0.780900 0.003400 +vn 0.260800 -0.951500 -0.163000 +vn 0.173200 -0.978500 0.112100 +vn -0.601500 -0.680600 0.418300 +vn 0.335200 -0.914800 0.225200 +vn -0.651000 -0.737500 -0.179600 +vn -0.892100 -0.451800 0.007400 +vn -0.698000 -0.714700 0.045800 +vn -0.663000 -0.703700 -0.255400 +vn -0.383600 -0.912900 -0.139300 +vn 0.068500 -0.997500 -0.013700 +vn 0.147700 -0.987400 -0.056600 +vn -0.472800 -0.881100 -0.007200 +vn -0.056800 -0.992400 0.109000 +vn -0.486800 -0.799800 0.351100 +vn -0.119400 -0.831400 0.542700 +vn -0.407000 -0.816600 0.409100 +vn -0.688200 -0.559800 0.461500 +vn -0.313100 -0.941000 0.128300 +vn 0.019000 -0.996100 0.085900 +vn 0.294000 -0.941200 0.166200 +vn 0.004000 -0.994400 0.105400 +vn -0.288100 -0.953400 0.089800 +vn -0.260600 -0.838200 0.479100 +vn -0.300400 -0.651100 0.696900 +vn -0.363600 -0.903800 0.225600 +vn -0.487600 -0.701600 0.519500 +vn -0.130200 -0.934100 0.332500 +vn 0.265400 -0.928300 0.260300 +vn 0.031400 -0.997000 0.070600 +vn -0.674100 -0.715500 0.183200 +vn -0.514500 -0.819600 -0.251800 +vn -0.705800 -0.628700 0.326400 +vn -0.582900 -0.806900 -0.095500 +vn -0.687900 -0.725800 0.006600 +vn -0.662700 -0.745200 0.073800 +vn -0.082600 -0.863000 0.498300 +vn -0.335100 -0.840100 0.426400 +vn -0.644600 -0.613200 0.456600 +vn -0.559700 -0.757600 0.335800 +vn -0.583800 -0.733800 0.347200 +vn 0.162800 -0.919900 0.356800 +vn -0.341000 -0.919300 -0.196400 +vn -0.447700 -0.892100 -0.060000 +vn -0.548900 -0.786800 0.282300 +vn -0.613500 -0.613700 0.496800 +vn -0.446900 -0.861500 -0.240900 +vn -0.185500 -0.982200 -0.028000 +vn -0.474800 -0.873000 0.111700 +vn -0.338600 -0.935800 -0.097800 +vn -0.317500 -0.948100 0.014500 +vn -0.361500 -0.904200 0.227500 +vn -0.458800 -0.749400 0.477300 +vn -0.035600 -0.999200 0.014700 +vn -0.380700 -0.856500 0.348500 +vn -0.475800 -0.668900 0.571200 +vn -0.494700 -0.532900 0.686500 +vn -0.134600 -0.987200 0.084800 +vn -0.423000 -0.803600 0.418600 +vn 0.234700 -0.971700 -0.026500 +vn -0.027900 -0.997200 -0.069000 +vn -0.003500 -1.000000 -0.006200 +vn -0.272500 -0.943400 0.188700 +vn -0.345900 -0.669500 0.657400 +vn -0.234300 -0.965000 0.117600 +vn -0.224800 -0.974200 0.018100 +vn -0.262800 -0.912900 0.312100 +vn -0.296900 -0.864200 0.406100 +vn -0.317800 -0.792000 0.521200 +vn 0.009800 -0.999900 -0.002300 +vn -0.041600 -0.998700 0.029100 +vn -0.232300 -0.750000 0.619300 +vn -0.236400 -0.629000 0.740500 +vn -0.050900 -0.996200 -0.069800 +vn -0.380700 -0.908700 -0.171500 +vn -0.020100 -0.999600 -0.016400 +vn 0.038600 -0.999200 0.009600 +vn 0.061100 -0.997800 -0.026100 +vn -0.080400 -0.996600 0.017900 +vn 0.027800 -0.999500 -0.017800 +vn -0.045400 -0.997200 0.059200 +vn -0.142500 -0.982700 0.118700 +vn -0.016900 -0.999000 0.042100 +vn -0.089600 -0.642700 0.760900 +vn 0.310800 -0.943500 0.114700 +vn 0.166700 -0.980300 0.105800 +vn -0.016900 -0.929500 0.368400 +vn 0.140400 -0.727700 0.671300 +vn -0.005700 -0.999500 0.029800 +vn -0.261800 -0.926300 0.270900 +vn 0.122600 -0.968400 0.217400 +vn 0.133200 -0.990500 -0.033300 +vn 0.542000 -0.738200 0.401600 +vn 0.778200 -0.610100 0.148600 +vn -0.190500 -0.571300 0.798300 +vn 0.189400 -0.734000 0.652200 +vn 0.370000 -0.799400 0.473200 +vn 0.389400 -0.904900 0.172000 +vn 0.020400 -0.888300 0.458800 +vn -0.402700 -0.710600 0.577000 +vn -0.019100 -0.995800 0.089600 +vn 0.015800 -0.999600 0.023700 +vn -0.024200 -0.663200 0.748000 +vn 0.092700 -0.989200 0.113800 +vn 0.070900 -0.997300 -0.020100 +vn 0.058300 -0.889400 0.453300 +vn -0.186800 -0.922800 0.337000 +vn -0.335400 -0.925500 0.175800 +s 1 +f 1//1 2//2 3//3 +f 4//4 5//5 6//6 +f 7//7 8//8 9//9 +f 10//10 11//11 12//12 +f 9//9 13//13 14//14 +f 15//15 16//16 17//17 +f 18//18 19//19 20//20 +f 21//21 22//22 23//23 +f 24//24 25//25 26//26 +f 27//27 28//28 29//29 +f 30//30 31//31 32//32 +f 33//33 34//34 35//35 +f 36//36 37//37 38//38 +f 19//19 39//39 20//20 +f 40//40 24//24 41//41 +f 42//42 43//43 44//44 +f 45//45 46//46 47//47 +f 48//48 49//49 50//50 +f 51//51 52//52 53//53 +f 54//54 55//55 42//42 +f 56//56 57//57 54//54 +f 58//58 59//59 60//60 +f 44//44 43//43 61//61 +f 62//62 63//63 64//64 +f 55//55 43//43 42//42 +f 65//65 66//66 67//67 +f 68//68 69//69 70//70 +f 71//71 72//72 73//73 +f 74//74 75//75 76//76 +f 77//77 78//78 79//79 +f 80//80 81//81 25//25 +f 82//82 83//83 73//73 +f 72//72 82//82 73//73 +f 84//84 85//85 86//86 +f 8//8 13//13 9//9 +f 87//87 88//88 89//89 +f 90//90 91//91 92//92 +f 93//93 94//94 6//6 +f 71//71 73//73 95//95 +f 96//96 97//97 98//98 +f 99//99 100//100 101//101 +f 49//49 57//57 56//56 +f 88//88 102//102 103//103 +f 104//104 68//68 105//105 +f 83//83 106//106 73//73 +f 106//106 83//83 18//18 +f 10//10 107//107 11//11 +f 108//108 7//7 66//66 +f 109//109 98//98 110//110 +f 111//111 73//73 112//112 +f 113//113 24//24 114//114 +f 115//115 60//60 46//46 +f 116//116 50//50 56//56 +f 46//46 60//60 47//47 +f 117//117 118//118 119//119 +f 111//111 112//112 120//120 +f 121//121 122//122 123//123 +f 124//124 59//59 125//125 +f 114//114 24//24 40//40 +f 39//39 65//65 126//126 +f 125//125 127//127 128//128 +f 129//129 130//130 131//131 +f 132//132 133//133 134//134 +f 43//43 135//135 61//61 +f 136//136 137//137 138//138 +f 131//131 139//139 140//140 +f 141//141 142//142 143//143 +f 115//115 58//58 60//60 +f 144//144 145//145 146//146 +f 147//147 148//148 149//149 +f 148//148 150//150 149//149 +f 150//150 151//151 149//149 +f 152//152 153//153 154//154 +f 97//97 155//155 156//156 +f 142//142 157//157 158//158 +f 23//23 159//159 21//21 +f 138//138 137//137 160//160 +f 59//59 124//124 60//60 +f 147//147 161//161 148//148 +f 162//162 163//163 164//164 +f 22//22 165//165 166//166 +f 61//61 135//135 167//167 +f 168//168 169//169 170//170 +f 171//171 118//118 117//117 +f 172//172 173//173 174//174 +f 175//175 176//176 177//177 +f 178//178 179//179 180//180 +f 181//181 148//148 161//161 +f 181//181 150//150 148//148 +f 182//182 162//162 151//151 +f 183//183 184//184 185//185 +f 186//186 26//26 187//187 +f 188//188 189//189 72//72 +f 50//50 49//49 56//56 +f 31//31 133//133 190//190 +f 104//104 105//105 191//191 +f 60//60 192//192 47//47 +f 193//193 106//106 194//194 +f 150//150 182//182 151//151 +f 195//195 163//163 162//162 +f 182//182 195//195 162//162 +f 196//196 197//197 198//198 +f 126//126 65//65 67//67 +f 154//154 10//10 12//12 +f 21//21 165//165 22//22 +f 199//199 112//112 193//193 +f 131//131 130//130 139//139 +f 200//200 201//201 161//161 +f 181//181 202//202 150//150 +f 150//150 203//203 182//182 +f 204//204 205//205 206//206 +f 207//207 208//208 209//209 +f 41//41 26//26 186//186 +f 68//68 70//70 105//105 +f 171//171 117//117 210//210 +f 211//211 1//1 212//212 +f 213//213 214//214 215//215 +f 216//216 217//217 63//63 +f 200//200 218//218 201//201 +f 150//150 202//202 203//203 +f 219//219 163//163 220//220 +f 221//221 222//222 117//117 +f 223//223 32//32 190//190 +f 224//224 225//225 226//226 +f 201//201 227//227 181//181 +f 227//227 202//202 181//181 +f 203//203 228//228 182//182 +f 195//195 220//220 163//163 +f 229//229 230//230 218//218 +f 231//231 232//232 233//233 +f 20//20 39//39 130//130 +f 234//234 190//190 132//132 +f 235//235 236//236 237//237 +f 182//182 228//228 195//195 +f 238//238 239//239 240//240 +f 241//241 242//242 243//243 +f 244//244 235//235 237//237 +f 39//39 126//126 130//130 +f 245//245 246//246 247//247 +f 218//218 227//227 201//201 +f 248//248 249//249 250//250 +f 251//251 241//241 243//243 +f 240//240 252//252 253//253 +f 241//241 254//254 242//242 +f 255//255 256//256 257//257 +f 82//82 258//258 19//19 +f 18//18 20//20 259//259 +f 260//260 261//261 262//262 +f 263//263 218//218 230//230 +f 263//263 227//227 218//218 +f 264//264 265//265 266//266 +f 228//228 267//267 195//195 +f 268//268 269//269 270//270 +f 254//254 271//271 272//272 +f 273//273 274//274 275//275 +f 276//276 277//277 278//278 +f 279//279 280//280 281//281 +f 4//4 136//136 5//5 +f 282//282 283//283 284//284 +f 285//285 261//261 260//260 +f 261//261 286//286 287//287 +f 286//286 288//288 287//287 +f 289//289 290//290 291//291 +f 292//292 293//293 294//294 +f 295//295 296//296 297//297 +f 298//298 227//227 299//299 +f 300//300 275//275 301//301 +f 302//302 303//303 304//304 +f 1//1 305//305 306//306 +f 307//307 95//95 111//111 +f 129//129 131//131 308//308 +f 309//309 286//286 261//261 +f 310//310 311//311 312//312 +f 313//313 314//314 315//315 +f 316//316 317//317 318//318 +f 319//319 320//320 321//321 +f 322//322 104//104 191//191 +f 323//323 324//324 325//325 +f 326//326 327//327 253//253 +f 145//145 322//322 191//191 +f 327//327 326//326 328//328 +f 113//113 25//25 24//24 +f 66//66 7//7 9//9 +f 188//188 72//72 329//329 +f 187//187 330//330 186//186 +f 120//120 199//199 331//331 +f 285//285 309//309 261//261 +f 332//332 333//333 334//334 +f 335//335 266//266 265//265 +f 336//336 337//337 313//313 +f 337//337 314//314 313//313 +f 336//336 313//313 338//338 +f 339//339 340//340 341//341 +f 254//254 272//272 342//342 +f 343//343 344//344 345//345 +f 242//242 342//342 243//243 +f 106//106 18//18 194//194 +f 346//346 347//347 348//348 +f 260//260 346//346 285//285 +f 349//349 350//350 351//351 +f 352//352 292//292 353//353 +f 354//354 355//355 266//266 +f 267//267 356//356 357//357 +f 358//358 359//359 273//273 +f 360//360 358//358 273//273 +f 189//189 108//108 258//258 +f 82//82 72//72 189//189 +f 7//7 361//361 8//8 +f 73//73 111//111 95//95 +f 362//362 363//363 364//364 +f 365//365 366//366 367//367 +f 368//368 366//366 347//347 +f 347//347 366//366 348//348 +f 369//369 346//346 348//348 +f 369//369 285//285 346//346 +f 369//369 309//309 285//285 +f 353//353 294//294 100//100 +f 292//292 294//294 353//353 +f 370//370 273//273 371//371 +f 372//372 373//373 374//374 +f 375//375 376//376 377//377 +f 335//335 354//354 266//266 +f 378//378 379//379 380//380 +f 381//381 382//382 383//383 +f 361//361 13//13 8//8 +f 372//372 384//384 385//385 +f 295//295 297//297 355//355 +f 386//386 387//387 388//388 +f 198//198 389//389 390//390 +f 391//391 392//392 393//393 +f 190//190 133//133 132//132 +f 394//394 395//395 396//396 +f 365//365 397//397 366//366 +f 366//366 398//398 348//348 +f 399//399 309//309 369//369 +f 400//400 401//401 402//402 +f 403//403 404//404 405//405 +f 406//406 372//372 385//385 +f 344//344 407//407 345//345 +f 408//408 409//409 410//410 +f 411//411 369//369 348//348 +f 398//398 411//411 348//348 +f 412//412 309//309 399//399 +f 412//412 413//413 309//309 +f 414//414 415//415 416//416 +f 335//335 265//265 337//337 +f 417//417 418//418 255//255 +f 69//69 419//419 420//420 +f 70//70 69//69 421//421 +f 9//9 14//14 422//422 +f 423//423 424//424 425//425 +f 426//426 427//427 428//428 +f 429//429 430//430 365//365 +f 430//430 397//397 365//365 +f 397//397 431//431 366//366 +f 366//366 431//431 398//398 +f 431//431 432//432 398//398 +f 411//411 399//399 369//369 +f 100//100 294//294 101//101 +f 433//433 376//376 375//375 +f 371//371 273//273 275//275 +f 434//434 413//413 412//412 +f 352//352 435//435 292//292 +f 66//66 9//9 67//67 +f 436//436 437//437 438//438 +f 439//439 397//397 430//430 +f 439//439 431//431 397//397 +f 398//398 432//432 411//411 +f 411//411 440//440 399//399 +f 413//413 434//434 441//441 +f 264//264 442//442 265//265 +f 352//352 290//290 443//443 +f 444//444 445//445 446//446 +f 447//447 448//448 449//449 +f 433//433 450//450 376//376 +f 451//451 452//452 453//453 +f 439//439 454//454 431//431 +f 455//455 337//337 336//336 +f 456//456 457//457 458//458 +f 124//124 125//125 459//459 +f 361//361 460//460 13//13 +f 461//461 462//462 463//463 +f 464//464 465//465 429//429 +f 432//432 466//466 411//411 +f 467//467 412//412 399//399 +f 467//467 434//434 412//412 +f 468//468 379//379 378//378 +f 450//450 469//469 470//470 +f 471//471 472//472 473//473 +f 474//474 349//349 351//351 +f 475//475 442//442 385//385 +f 101//101 376//376 476//476 +f 477//477 478//478 28//28 +f 479//479 175//175 480//480 +f 429//429 481//481 430//430 +f 430//430 481//481 439//439 +f 466//466 440//440 411//411 +f 482//482 434//434 467//467 +f 373//373 296//296 374//374 +f 483//483 484//484 485//485 +f 486//486 487//487 488//488 +f 442//442 406//406 385//385 +f 489//489 16//16 490//490 +f 491//491 492//492 13//13 +f 225//225 224//224 493//493 +f 494//494 495//495 245//245 +f 464//464 496//496 465//465 +f 465//465 497//497 429//429 +f 429//429 497//497 481//481 +f 481//481 498//498 439//439 +f 439//439 498//498 454//454 +f 454//454 466//466 431//431 +f 466//466 432//432 431//431 +f 440//440 499//499 399//399 +f 399//399 499//499 467//467 +f 434//434 500//500 441//441 +f 372//372 297//297 373//373 +f 501//501 447//447 502//502 +f 503//503 504//504 505//505 +f 489//489 506//506 16//16 +f 269//269 507//507 508//508 +f 17//17 16//16 509//509 +f 510//510 451//451 462//462 +f 511//511 497//497 465//465 +f 512//512 466//466 454//454 +f 466//466 512//512 440//440 +f 513//513 475//475 385//385 +f 514//514 505//505 515//515 +f 515//515 349//349 474//474 +f 516//516 517//517 447//447 +f 518//518 503//503 519//519 +f 517//517 520//520 521//521 +f 517//517 522//522 520//520 +f 523//523 524//524 525//525 +f 526//526 350//350 349//349 +f 527//527 528//528 529//529 +f 393//393 530//530 531//531 +f 532//532 533//533 534//534 +f 535//535 169//169 536//536 +f 497//497 537//537 481//481 +f 537//537 498//498 481//481 +f 512//512 454//454 498//498 +f 512//512 538//538 440//440 +f 440//440 538//538 499//499 +f 538//538 539//539 499//499 +f 539//539 467//467 499//499 +f 482//482 540//540 434//434 +f 540//540 541//541 500//500 +f 434//434 540//540 500//500 +f 414//414 400//400 415//415 +f 542//542 543//543 544//544 +f 545//545 546//546 547//547 +f 513//513 314//314 475//475 +f 519//519 503//503 505//505 +f 548//548 549//549 408//408 +f 465//465 550//550 511//511 +f 467//467 551//551 482//482 +f 551//551 540//540 482//482 +f 375//375 515//515 474//474 +f 378//378 380//380 552//552 +f 351//351 553//553 433//433 +f 352//352 353//353 290//290 +f 554//554 555//555 556//556 +f 550//550 537//537 511//511 +f 537//537 497//497 511//511 +f 557//557 498//498 537//537 +f 558//558 512//512 498//498 +f 559//559 538//538 512//512 +f 551//551 467//467 539//539 +f 351//351 547//547 560//560 +f 342//342 272//272 524//524 +f 290//290 353//353 561//561 +f 470//470 248//248 562//562 +f 563//563 564//564 565//565 +f 566//566 555//555 506//506 +f 567//567 488//488 35//35 +f 568//568 569//569 570//570 +f 557//557 558//558 498//498 +f 512//512 558//558 559//559 +f 551//551 571//571 540//540 +f 562//562 248//248 250//250 +f 502//502 449//449 416//416 +f 415//415 502//502 416//416 +f 572//572 501//501 400//400 +f 402//402 572//572 400//400 +f 501//501 516//516 447//447 +f 573//573 156//156 574//574 +f 73//73 106//106 112//112 +f 575//575 323//323 576//576 +f 577//577 578//578 579//579 +f 538//538 580//580 539//539 +f 580//580 581//581 539//539 +f 581//581 571//571 551//551 +f 539//539 581//581 551//551 +f 314//314 337//337 265//265 +f 582//582 414//414 583//583 +f 291//291 561//561 99//99 +f 544//544 584//584 585//585 +f 474//474 433//433 375//375 +f 586//586 587//587 588//588 +f 589//589 556//556 555//555 +f 590//590 591//591 556//556 +f 120//120 112//112 199//199 +f 592//592 550//550 593//593 +f 592//592 537//537 550//550 +f 557//557 559//559 558//558 +f 580//580 538//538 559//559 +f 594//594 540//540 571//571 +f 595//595 541//541 540//540 +f 473//473 596//596 597//597 +f 250//250 249//249 318//318 +f 589//589 598//598 556//556 +f 598//598 590//590 556//556 +f 83//83 19//19 18//18 +f 599//599 537//537 592//592 +f 600//600 557//557 537//537 +f 601//601 559//559 602//602 +f 601//601 580//580 559//559 +f 603//603 604//604 605//605 +f 455//455 606//606 337//337 +f 607//607 158//158 157//157 +f 566//566 608//608 555//555 +f 130//130 126//126 139//139 +f 599//599 600//600 537//537 +f 600//600 609//609 557//557 +f 557//557 609//609 559//559 +f 609//609 602//602 559//559 +f 580//580 601//601 581//581 +f 581//581 594//594 571//571 +f 541//541 610//610 611//611 +f 612//612 613//613 614//614 +f 615//615 450//450 470//470 +f 561//561 353//353 100//100 +f 28//28 616//616 617//617 +f 561//561 100//100 99//99 +f 142//142 618//618 157//157 +f 619//619 620//620 305//305 +f 608//608 621//621 589//589 +f 555//555 608//608 589//589 +f 621//621 598//598 589//589 +f 622//622 42//42 44//44 +f 623//623 624//624 625//625 +f 626//626 627//627 592//592 +f 627//627 599//599 592//592 +f 601//601 628//628 581//581 +f 629//629 594//594 581//581 +f 629//629 595//595 594//594 +f 594//594 595//595 540//540 +f 630//630 610//610 541//541 +f 631//631 405//405 632//632 +f 633//633 634//634 635//635 +f 636//636 637//637 618//618 +f 351//351 545//545 547//547 +f 118//118 212//212 119//119 +f 626//626 638//638 627//627 +f 628//628 629//629 581//581 +f 595//595 639//639 541//541 +f 639//639 640//640 541//541 +f 640//640 630//630 541//541 +f 641//641 321//321 642//642 +f 523//523 643//643 270//270 +f 501//501 644//644 516//516 +f 373//373 297//297 296//296 +f 604//604 619//619 305//305 +f 193//193 112//112 106//106 +f 194//194 18//18 259//259 +f 456//456 645//645 626//626 +f 645//645 638//638 626//626 +f 638//638 646//646 627//627 +f 646//646 599//599 627//627 +f 629//629 647//647 595//595 +f 595//595 647//647 639//639 +f 245//245 568//568 648//648 +f 649//649 468//468 650//650 +f 637//637 651//651 157//157 +f 618//618 637//637 157//157 +f 651//651 607//607 157//157 +f 198//198 197//197 652//652 +f 653//653 645//645 458//458 +f 654//654 599//599 646//646 +f 654//654 600//600 599//599 +f 654//654 609//609 600//600 +f 609//609 654//654 602//602 +f 628//628 655//655 629//629 +f 629//629 655//655 647//647 +f 79//79 78//78 656//656 +f 343//343 345//345 657//657 +f 658//658 450//450 615//615 +f 376//376 658//658 476//476 +f 542//542 650//650 543//543 +f 608//608 659//659 621//621 +f 660//660 661//661 653//653 +f 653//653 661//661 645//645 +f 645//645 662//662 638//638 +f 654//654 655//655 601//601 +f 602//602 654//654 601//601 +f 601//601 655//655 628//628 +f 657//657 345//345 663//663 +f 664//664 17//17 665//665 +f 666//666 667//667 668//668 +f 351//351 560//560 553//553 +f 659//659 669//669 621//621 +f 621//621 669//669 598//598 +f 670//670 653//653 598//598 +f 661//661 671//671 645//645 +f 646//646 672//672 654//654 +f 672//672 673//673 654//654 +f 673//673 655//655 654//654 +f 655//655 674//674 647//647 +f 675//675 641//641 676//676 +f 414//414 416//416 583//583 +f 376//376 450//450 658//658 +f 677//677 678//678 679//679 +f 208//208 680//680 681//681 +f 669//669 670//670 598//598 +f 645//645 682//682 662//662 +f 662//662 646//646 638//638 +f 662//662 672//672 646//646 +f 683//683 655//655 673//673 +f 683//683 674//674 655//655 +f 674//674 684//684 647//647 +f 684//684 685//685 647//647 +f 647//647 685//685 639//639 +f 639//639 686//686 640//640 +f 687//687 688//688 630//630 +f 689//689 690//690 691//691 +f 544//544 543//543 584//584 +f 692//692 693//693 651//651 +f 694//694 607//607 693//693 +f 695//695 696//696 697//697 +f 31//31 190//190 32//32 +f 698//698 669//669 659//659 +f 670//670 660//660 653//653 +f 671//671 682//682 645//645 +f 699//699 339//339 700//700 +f 692//692 701//701 693//693 +f 661//661 702//702 671//671 +f 662//662 703//703 672//672 +f 703//703 704//704 672//672 +f 672//672 704//704 673//673 +f 704//704 705//705 673//673 +f 705//705 706//706 673//673 +f 706//706 683//683 673//673 +f 707//707 674//674 683//683 +f 707//707 708//708 674//674 +f 708//708 684//684 674//674 +f 708//708 685//685 684//684 +f 685//685 686//686 639//639 +f 543//543 709//709 584//584 +f 253//253 710//710 711//711 +f 425//425 712//712 713//713 +f 211//211 212//212 118//118 +f 714//714 715//715 670//670 +f 716//716 660//660 670//670 +f 717//717 661//661 660//660 +f 717//717 702//702 661//661 +f 703//703 662//662 682//682 +f 718//718 703//703 682//682 +f 719//719 685//685 708//708 +f 687//687 640//640 686//686 +f 442//442 372//372 406//406 +f 720//720 560//560 721//721 +f 709//709 722//722 584//584 +f 723//723 701//701 692//692 +f 670//670 669//669 714//714 +f 715//715 716//716 670//670 +f 702//702 682//682 671//671 +f 724//724 704//704 703//703 +f 704//704 725//725 705//705 +f 705//705 726//726 706//706 +f 727//727 708//708 707//707 +f 686//686 685//685 687//687 +f 585//585 584//584 722//722 +f 606//606 335//335 337//337 +f 701//701 728//728 694//694 +f 693//693 701//701 694//694 +f 201//201 181//181 161//161 +f 728//728 387//387 729//729 +f 730//730 731//731 23//23 +f 716//716 717//717 660//660 +f 717//717 732//732 702//702 +f 733//733 703//703 718//718 +f 733//733 724//724 703//703 +f 724//724 725//725 704//704 +f 725//725 726//726 705//705 +f 734//734 99//99 735//735 +f 514//514 515//515 375//375 +f 733//733 725//725 724//724 +f 726//726 736//736 706//706 +f 727//727 719//719 708//708 +f 492//492 687//687 685//685 +f 317//317 696//696 318//318 +f 101//101 377//377 376//376 +f 587//587 313//313 315//315 +f 562//562 737//737 738//738 +f 28//28 617//617 29//29 +f 294//294 514//514 377//377 +f 24//24 26//26 41//41 +f 259//259 20//20 129//129 +f 20//20 130//130 129//129 +f 716//716 715//715 739//739 +f 740//740 717//717 716//716 +f 732//732 718//718 702//702 +f 718//718 682//682 702//702 +f 736//736 741//741 706//706 +f 706//706 741//741 683//683 +f 742//742 707//707 683//683 +f 743//743 744//744 477//477 +f 745//745 302//302 78//78 +f 740//740 732//732 717//717 +f 746//746 733//733 718//718 +f 746//746 725//725 733//733 +f 741//741 742//742 683//683 +f 742//742 747//747 707//707 +f 747//747 727//727 707//707 +f 748//748 749//749 644//644 +f 290//290 561//561 291//291 +f 713//713 750//750 425//425 +f 330//330 32//32 223//223 +f 739//739 740//740 716//716 +f 740//740 751//751 732//732 +f 751//751 718//718 732//732 +f 751//751 752//752 718//718 +f 718//718 752//752 746//746 +f 746//746 753//753 725//725 +f 753//753 754//754 726//726 +f 725//725 753//753 726//726 +f 726//726 754//754 736//736 +f 742//742 755//755 747//747 +f 747//747 719//719 727//727 +f 492//492 685//685 719//719 +f 756//756 326//326 757//757 +f 416//416 758//758 583//583 +f 709//709 552//552 483//483 +f 443//443 289//289 759//759 +f 760//760 729//729 761//761 +f 762//762 763//763 753//753 +f 736//736 754//754 741//741 +f 699//699 764//764 765//765 +f 483//483 552//552 484//484 +f 474//474 351//351 433//433 +f 377//377 514//514 375//375 +f 560//560 720//720 553//553 +f 2//2 1//1 211//211 +f 5//5 136//136 138//138 +f 766//766 193//193 194//194 +f 767//767 740//740 739//739 +f 768//768 767//767 739//739 +f 767//767 751//751 740//740 +f 331//331 362//362 364//364 +f 102//102 689//689 109//109 +f 741//741 755//755 742//742 +f 239//239 769//769 770//770 +f 771//771 317//317 772//772 +f 468//468 378//378 543//543 +f 666//666 562//562 738//738 +f 631//631 403//403 405//405 +f 65//65 108//108 66//66 +f 773//773 301//301 774//774 +f 570//570 775//775 776//776 +f 777//777 778//778 779//779 +f 767//767 780//780 751//751 +f 751//751 780//780 752//752 +f 781//781 747//747 755//755 +f 782//782 719//719 747//747 +f 783//783 782//782 747//747 +f 782//782 492//492 719//719 +f 784//784 785//785 786//786 +f 552//552 787//787 484//484 +f 225//225 493//493 788//788 +f 293//293 514//514 294//294 +f 475//475 265//265 442//442 +f 789//789 247//247 246//246 +f 790//790 767//767 768//768 +f 791//791 792//792 780//780 +f 793//793 794//794 795//795 +f 317//317 131//131 696//696 +f 449//449 448//448 796//796 +f 797//797 741//741 754//754 +f 741//741 797//797 755//755 +f 798//798 782//782 783//783 +f 799//799 492//492 782//782 +f 799//799 14//14 492//492 +f 515//515 504//504 526//526 +f 470//470 469//469 248//248 +f 266//266 355//355 264//264 +f 667//667 666//666 738//738 +f 505//505 504//504 515//515 +f 800//800 777//777 779//779 +f 801//801 802//802 323//323 +f 802//802 324//324 323//323 +f 522//522 517//517 803//803 +f 804//804 129//129 308//308 +f 362//362 766//766 805//805 +f 806//806 755//755 797//797 +f 755//755 806//806 781//781 +f 783//783 747//747 781//781 +f 799//799 422//422 14//14 +f 720//720 469//469 553//553 +f 355//355 372//372 442//442 +f 250//250 318//318 695//695 +f 468//468 543//543 650//650 +f 542//542 296//296 650//650 +f 553//553 469//469 450//450 +f 807//807 779//779 170//170 +f 800//800 808//808 777//777 +f 808//808 809//809 777//777 +f 42//42 622//622 54//54 +f 356//356 810//810 357//357 +f 811//811 783//783 781//781 +f 339//339 699//699 340//340 +f 812//812 632//632 813//813 +f 729//729 386//386 814//814 +f 815//815 814//814 816//816 +f 433//433 553//553 450//450 +f 807//807 170//170 817//817 +f 818//818 807//807 817//817 +f 819//819 779//779 807//807 +f 819//819 800//800 779//779 +f 820//820 821//821 822//822 +f 199//199 193//193 362//362 +f 132//132 134//134 823//823 +f 94//94 4//4 6//6 +f 13//13 824//824 491//491 +f 825//825 826//826 827//827 +f 781//781 828//828 811//811 +f 829//829 379//379 468//468 +f 722//722 483//483 485//485 +f 378//378 552//552 709//709 +f 154//154 12//12 830//830 +f 247//247 789//789 563//563 +f 317//317 308//308 131//131 +f 831//831 832//832 833//833 +f 811//811 798//798 783//783 +f 834//834 782//782 798//798 +f 835//835 226//226 473//473 +f 562//562 250//250 695//695 +f 519//519 836//836 837//837 +f 447//447 521//521 448//448 +f 472//472 835//835 473//473 +f 838//838 809//809 808//808 +f 809//809 838//838 839//839 +f 199//199 362//362 331//331 +f 193//193 766//766 362//362 +f 840//840 841//841 842//842 +f 54//54 622//622 56//56 +f 843//843 844//844 845//845 +f 846//846 811//811 828//828 +f 847//847 848//848 644//644 +f 641//641 319//319 321//321 +f 807//807 849//849 819//819 +f 819//819 849//849 800//800 +f 838//838 808//808 800//800 +f 850//850 851//851 852//852 +f 131//131 140//140 696//696 +f 331//331 364//364 853//853 +f 665//665 854//854 855//855 +f 856//856 325//325 208//208 +f 846//846 857//857 811//811 +f 857//857 798//798 811//811 +f 422//422 799//799 782//782 +f 834//834 422//422 782//782 +f 858//858 859//859 860//860 +f 695//695 318//318 696//696 +f 483//483 722//722 709//709 +f 380//380 861//861 862//862 +f 294//294 377//377 101//101 +f 807//807 863//863 849//849 +f 849//849 864//864 800//800 +f 864//864 838//838 800//800 +f 838//838 865//865 839//839 +f 189//189 866//866 108//108 +f 766//766 194//194 867//867 +f 868//868 494//494 596//596 +f 869//869 870//870 871//871 +f 749//749 517//517 516//516 +f 562//562 695//695 737//737 +f 585//585 722//722 872//872 +f 505//505 514//514 873//873 +f 179//179 159//159 731//731 +f 871//871 874//874 875//875 +f 804//804 308//308 771//771 +f 876//876 857//857 846//846 +f 877//877 834//834 798//798 +f 877//877 422//422 834//834 +f 878//878 879//879 880//880 +f 291//291 99//99 734//734 +f 862//862 881//881 552//552 +f 37//37 882//882 38//38 +f 864//864 865//865 838//838 +f 194//194 259//259 867//867 +f 259//259 129//129 804//804 +f 883//883 884//884 871//871 +f 870//870 883//883 871//871 +f 884//884 874//874 871//871 +f 362//362 805//805 363//363 +f 370//370 360//360 273//273 +f 351//351 350//350 545//545 +f 435//435 352//352 881//881 +f 862//862 552//552 380//380 +f 865//865 885//885 886//886 +f 887//887 888//888 883//883 +f 889//889 875//875 874//874 +f 889//889 890//890 875//875 +f 891//891 867//867 804//804 +f 892//892 893//893 894//894 +f 895//895 857//857 820//820 +f 895//895 798//798 857//857 +f 896//896 422//422 877//877 +f 896//896 67//67 422//422 +f 355//355 297//297 372//372 +f 400//400 502//502 415//415 +f 649//649 650//650 296//296 +f 338//338 313//313 587//587 +f 897//897 865//865 864//864 +f 849//849 897//897 864//864 +f 898//898 886//886 885//885 +f 885//885 899//899 898//898 +f 900//900 888//888 887//887 +f 888//888 901//901 883//883 +f 901//901 902//902 883//883 +f 902//902 884//884 883//883 +f 902//902 874//874 884//884 +f 903//903 889//889 874//874 +f 889//889 904//904 890//890 +f 1//1 905//905 906//906 +f 766//766 907//907 805//805 +f 908//908 877//877 798//798 +f 909//909 67//67 896//896 +f 910//910 523//523 270//270 +f 370//370 371//371 911//911 +f 517//517 521//521 447//447 +f 865//865 899//899 885//885 +f 912//912 901//901 888//888 +f 902//902 913//913 874//874 +f 821//821 820//820 857//857 +f 908//908 896//896 877//877 +f 378//378 709//709 543//543 +f 586//586 338//338 587//587 +f 400//400 501//501 502//502 +f 863//863 897//897 849//849 +f 897//897 914//914 865//865 +f 865//865 914//914 899//899 +f 616//616 343//343 311//311 +f 900//900 912//912 888//888 +f 912//912 915//915 901//901 +f 901//901 916//916 902//902 +f 916//916 913//913 902//902 +f 903//903 874//874 913//913 +f 771//771 308//308 317//317 +f 917//917 895//895 820//820 +f 917//917 918//918 895//895 +f 908//908 798//798 895//895 +f 918//918 908//908 895//895 +f 126//126 67//67 909//909 +f 545//545 919//919 546//546 +f 644//644 749//749 516//516 +f 447//447 449//449 502//502 +f 914//914 920//920 899//899 +f 920//920 534//534 899//899 +f 900//900 921//921 912//912 +f 921//921 915//915 912//912 +f 915//915 922//922 901//901 +f 901//901 922//922 916//916 +f 923//923 889//889 903//903 +f 923//923 904//904 889//889 +f 328//328 274//274 327//327 +f 484//484 443//443 485//485 +f 126//126 909//909 139//139 +f 355//355 442//442 264//264 +f 374//374 296//296 542//542 +f 787//787 443//443 484//484 +f 249//249 316//316 318//318 +f 648//648 570//570 776//776 +f 914//914 513//513 920//920 +f 867//867 259//259 804//804 +f 867//867 907//907 766//766 +f 913//913 924//924 903//903 +f 924//924 923//923 903//903 +f 925//925 240//240 327//327 +f 926//926 917//917 822//822 +f 926//926 667//667 917//917 +f 667//667 918//918 917//917 +f 697//697 909//909 896//896 +f 604//604 603//603 850//850 +f 863//863 587//587 897//897 +f 840//840 927//927 841//841 +f 734//734 904//904 923//923 +f 738//738 908//908 918//918 +f 737//737 896//896 908//908 +f 737//737 697//697 896//896 +f 384//384 372//372 374//374 +f 314//314 265//265 475//475 +f 787//787 352//352 443//443 +f 316//316 772//772 317//317 +f 587//587 315//315 897//897 +f 897//897 315//315 914//914 +f 854//854 928//928 509//509 +f 533//533 532//532 929//929 +f 542//542 921//921 929//929 +f 915//915 872//872 922//922 +f 922//922 485//485 916//916 +f 916//916 930//930 913//913 +f 930//930 924//924 913//913 +f 668//668 667//667 926//926 +f 738//738 737//737 908//908 +f 271//271 700//700 272//272 +f 881//881 352//352 787//787 +f 881//881 787//787 552//552 +f 315//315 513//513 914//914 +f 920//920 532//532 534//534 +f 921//921 585//585 915//915 +f 915//915 585//585 872//872 +f 485//485 930//930 916//916 +f 289//289 924//924 930//930 +f 289//289 923//923 924//924 +f 291//291 734//734 923//923 +f 931//931 822//822 932//932 +f 738//738 918//918 667//667 +f 140//140 909//909 697//697 +f 140//140 139//139 909//909 +f 848//848 748//748 644//644 +f 588//588 587//587 863//863 +f 532//532 542//542 929//929 +f 759//759 289//289 930//930 +f 923//923 289//289 291//291 +f 575//575 418//418 417//417 +f 933//933 822//822 931//931 +f 737//737 695//695 697//697 +f 699//699 765//765 340//340 +f 829//829 468//468 649//649 +f 315//315 314//314 513//513 +f 513//513 385//385 920//920 +f 920//920 384//384 532//532 +f 532//532 374//374 542//542 +f 921//921 544//544 585//585 +f 485//485 759//759 930//930 +f 743//743 28//28 27//27 +f 443//443 290//290 289//289 +f 920//920 385//385 384//384 +f 384//384 374//374 532//532 +f 542//542 544//544 921//921 +f 872//872 722//722 922//922 +f 722//722 485//485 922//922 +f 485//485 443//443 759//759 +f 93//93 934//934 94//94 +f 935//935 336//336 936//936 +f 615//615 470//470 562//562 +f 862//862 937//937 881//881 +f 938//938 814//814 386//386 +f 881//881 937//937 435//435 +f 607//607 694//694 939//939 +f 940//940 941//941 942//942 +f 943//943 944//944 945//945 +f 946//946 947//947 295//295 +f 948//948 949//949 950//950 +f 951//951 526//526 952//952 +f 226//226 225//225 473//473 +f 953//953 748//748 954//954 +f 955//955 956//956 957//957 +f 958//958 954//954 847//847 +f 448//448 959//959 960//960 +f 961//961 274//274 358//358 +f 962//962 659//659 963//963 +f 964//964 954//954 958//958 +f 958//958 847//847 965//965 +f 966//966 244//244 967//967 +f 968//968 969//969 970//970 +f 692//692 637//637 636//636 +f 952//952 526//526 504//504 +f 971//971 972//972 973//973 +f 974//974 975//975 976//976 +f 273//273 359//359 274//274 +f 977//977 978//978 945//945 +f 979//979 980//980 981//981 +f 641//641 982//982 676//676 +f 52//52 51//51 983//983 +f 202//202 984//984 203//203 +f 249//249 721//721 560//560 +f 968//968 985//985 986//986 +f 321//321 987//987 642//642 +f 988//988 989//989 990//990 +f 202//202 298//298 991//991 +f 991//991 984//984 202//202 +f 992//992 993//993 994//994 +f 299//299 995//995 298//298 +f 996//996 997//997 998//998 +f 999//999 845//845 546//546 +f 1000//1000 1001//1001 1002//1002 +f 970//970 1003//1003 985//985 +f 978//978 383//383 1004//1004 +f 413//413 1005//1005 288//288 +f 1006//1006 631//631 632//632 +f 1007//1007 965//965 1008//1008 +f 40//40 283//283 1009//1009 +f 1010//1010 995//995 299//299 +f 298//298 1011//1011 991//991 +f 448//448 521//521 520//520 +f 986//986 985//985 979//979 +f 383//383 382//382 1012//1012 +f 1013//1013 1014//1014 1015//1015 +f 1013//1013 1010//1010 1014//1014 +f 991//991 356//356 984//984 +f 978//978 1004//1004 1016//1016 +f 1017//1017 995//995 1010//1010 +f 991//991 1011//1011 356//356 +f 773//773 774//774 1018//1018 +f 1008//1008 1019//1019 1020//1020 +f 1021//1021 1010//1010 1013//1013 +f 1021//1021 1017//1017 1010//1010 +f 1017//1017 1022//1022 995//995 +f 995//995 1022//1022 298//298 +f 298//298 1022//1022 1011//1011 +f 1023//1023 958//958 1024//1024 +f 1023//1023 964//964 958//958 +f 1025//1025 1026//1026 1027//1027 +f 1028//1028 1029//1029 1030//1030 +f 546//546 845//845 547//547 +f 1031//1031 1032//1032 63//63 +f 1033//1033 1015//1015 1034//1034 +f 1035//1035 1013//1013 1015//1015 +f 1011//1011 1036//1036 356//356 +f 700//700 339//339 1037//1037 +f 964//964 1038//1038 953//953 +f 1039//1039 1040//1040 1041//1041 +f 1042//1042 1043//1043 1044//1044 +f 954//954 748//748 848//848 +f 953//953 1038//1038 1045//1045 +f 1033//1033 1035//1035 1015//1015 +f 1021//1021 1013//1013 1035//1035 +f 1022//1022 1046//1046 1011//1011 +f 1047//1047 1048//1048 1049//1049 +f 1050//1050 1051//1051 1052//1052 +f 1017//1017 1053//1053 1022//1022 +f 1036//1036 810//810 356//356 +f 1054//1054 1055//1055 1056//1056 +f 402//402 965//965 847//847 +f 956//956 1057//1057 957//957 +f 826//826 1058//1058 1059//1059 +f 847//847 954//954 848//848 +f 1017//1017 1021//1021 1053//1053 +f 1046//1046 1060//1060 1011//1011 +f 1011//1011 1060//1060 1036//1036 +f 1061//1061 292//292 435//435 +f 979//979 1062//1062 980//980 +f 1008//1008 965//965 1063//1063 +f 1064//1064 1065//1065 1066//1066 +f 1067//1067 1033//1033 1005//1005 +f 413//413 1067//1067 1005//1005 +f 1053//1053 1046//1046 1022//1022 +f 1068//1068 1051//1051 1039//1039 +f 1035//1035 1033//1033 1067//1067 +f 1060//1060 1069//1069 1036//1036 +f 1032//1032 1070//1070 1071//1071 +f 959//959 1072//1072 1025//1025 +f 1073//1073 1074//1074 1075//1075 +f 1076//1076 1077//1077 1078//1078 +f 1078//1078 1079//1079 1080//1080 +f 1079//1079 1081//1081 1080//1080 +f 1082//1082 1074//1074 1079//1079 +f 1083//1083 971//971 973//973 +f 1084//1084 1021//1021 1035//1035 +f 1084//1084 1085//1085 1021//1021 +f 1085//1085 1053//1053 1021//1021 +f 1053//1053 1086//1086 1046//1046 +f 1086//1086 1087//1087 1046//1046 +f 1046//1046 1087//1087 1060//1060 +f 1087//1087 1088//1088 1060//1060 +f 1060//1060 1088//1088 1069//1069 +f 1069//1069 1089//1089 1036//1036 +f 1089//1089 810//810 1036//1036 +f 1073//1073 1075//1075 1090//1090 +f 959//959 1025//1025 960//960 +f 910//910 243//243 523//523 +f 1074//1074 1073//1073 1079//1079 +f 1067//1067 1084//1084 1035//1035 +f 1091//1091 810//810 1089//1089 +f 1071//1071 1070//1070 1092//1092 +f 350//350 941//941 545//545 +f 504//504 503//503 952//952 +f 1085//1085 1093//1093 1053//1053 +f 1093//1093 1086//1086 1053//1053 +f 155//155 163//163 219//219 +f 1094//1094 489//489 490//490 +f 1095//1095 489//489 1094//1094 +f 251//251 243//243 910//910 +f 842//842 841//841 1096//1096 +f 951//951 941//941 350//350 +f 1097//1097 1062//1062 1003//1003 +f 1062//1062 979//979 1003//1003 +f 1098//1098 1099//1099 1100//1100 +f 1101//1101 1102//1102 1065//1065 +f 1103//1103 1104//1104 616//616 +f 441//441 1105//1105 1084//1084 +f 1067//1067 441//441 1084//1084 +f 1084//1084 1105//1105 1085//1085 +f 1106//1106 1107//1107 386//386 +f 969//969 968//968 1108//1108 +f 844//844 772//772 845//845 +f 845//845 772//772 547//547 +f 836//836 873//873 1061//1061 +f 1109//1109 999//999 546//546 +f 1110//1110 1086//1086 1093//1093 +f 1111//1111 1089//1089 1069//1069 +f 1111//1111 1112//1112 1089//1089 +f 1112//1112 1091//1091 1089//1089 +f 1091//1091 1113//1113 810//810 +f 576//576 325//325 856//856 +f 856//856 207//207 1114//1114 +f 1115//1115 1116//1116 1117//1117 +f 1105//1105 1118//1118 1085//1085 +f 1118//1118 1119//1119 1085//1085 +f 1085//1085 1119//1119 1093//1093 +f 1110//1110 1120//1120 1086//1086 +f 1121//1121 1087//1087 1086//1086 +f 1120//1120 1121//1121 1086//1086 +f 1122//1122 1087//1087 1121//1121 +f 1122//1122 1088//1088 1087//1087 +f 1123//1123 1069//1069 1088//1088 +f 1122//1122 1123//1123 1088//1088 +f 1069//1069 1123//1123 1111//1111 +f 1124//1124 1091//1091 1112//1112 +f 1091//1091 1124//1124 1113//1113 +f 764//764 1125//1125 765//765 +f 1126//1126 967//967 634//634 +f 1127//1127 1093//1093 1119//1119 +f 1093//1093 1127//1127 1110//1110 +f 1111//1111 1124//1124 1112//1112 +f 1128//1128 593//593 465//465 +f 566//566 489//489 1095//1095 +f 566//566 506//506 489//489 +f 608//608 566//566 1129//1129 +f 1100//1100 1099//1099 1130//1130 +f 1115//1115 1131//1131 1116//1116 +f 23//23 1132//1132 730//730 +f 1127//1127 1120//1120 1110//1110 +f 1120//1120 1122//1122 1121//1121 +f 1133//1133 713//713 712//712 +f 357//357 1113//1113 166//166 +f 1042//1042 1134//1134 1135//1135 +f 524//524 1037//1037 525//525 +f 518//518 1134//1134 503//503 +f 1136//1136 1076//1076 1080//1080 +f 1098//1098 1117//1117 1099//1099 +f 1120//1120 1137//1137 1122//1122 +f 1111//1111 1138//1138 1124//1124 +f 1139//1139 1140//1140 1141//1141 +f 342//342 524//524 523//523 +f 227//227 298//298 202//202 +f 1101//1101 1064//1064 1131//1131 +f 1061//1061 873//873 293//293 +f 240//240 239//239 252//252 +f 1142//1142 1047//1047 970//970 +f 463//463 1143//1143 1144//1144 +f 1049//1049 1062//1062 1097//1097 +f 1127//1127 1145//1145 1120//1120 +f 1138//1138 1146//1146 1124//1124 +f 1147//1147 1129//1129 1095//1095 +f 1057//1057 1148//1148 957//957 +f 836//836 519//519 873//873 +f 1149//1149 758//758 1082//1082 +f 1150//1150 409//409 1151//1151 +f 1152//1152 1041//1041 1153//1153 +f 1154//1154 1155//1155 956//956 +f 1062//1062 1156//1156 1154//1154 +f 1157//1157 1118//1118 1105//1105 +f 500//500 1157//1157 1105//1105 +f 1157//1157 1119//1119 1118//1118 +f 1123//1123 1122//1122 1111//1111 +f 1158//1158 1138//1138 1111//1111 +f 1147//1147 963//963 1129//1129 +f 263//263 1014//1014 1010//1010 +f 1159//1159 1051//1051 1068//1068 +f 1160//1160 1161//1161 446//446 +f 1047//1047 1049//1049 1097//1097 +f 970//970 1047//1047 1097//1097 +f 1134//1134 518//518 1162//1162 +f 1163//1163 1127//1127 1119//1119 +f 1127//1127 1163//1163 1145//1145 +f 1158//1158 1164//1164 1138//1138 +f 1138//1138 1164//1164 1146//1146 +f 681//681 1165//1165 209//209 +f 1166//1166 1153//1153 1167//1167 +f 382//382 388//388 1012//1012 +f 697//697 696//696 140//140 +f 873//873 514//514 293//293 +f 386//386 729//729 387//387 +f 935//935 1081//1081 1108//1108 +f 1162//1162 518//518 837//837 +f 349//349 515//515 526//526 +f 1064//1064 1066//1066 381//381 +f 938//938 825//825 1168//1168 +f 70//70 421//421 171//171 +f 1163//1163 1119//1119 1157//1157 +f 1145//1145 1137//1137 1120//1120 +f 1122//1122 1158//1158 1111//1111 +f 1169//1169 172//172 174//174 +f 1027//1027 1026//1026 1153//1153 +f 1153//1153 1170//1170 1171//1171 +f 1167//1167 1153//1153 1171//1171 +f 1172//1172 1173//1173 1174//1174 +f 1175//1175 490//490 16//16 +f 519//519 505//505 873//873 +f 1044//1044 952//952 503//503 +f 611//611 1157//1157 500//500 +f 1137//1137 1176//1176 1122//1122 +f 1177//1177 1102//1102 1178//1178 +f 942//942 1179//1179 940//940 +f 1154//1154 955//955 980//980 +f 253//253 1180//1180 710//710 +f 756//756 774//774 301//301 +f 1181//1181 1027//1027 1153//1153 +f 955//955 1154//1154 956//956 +f 1062//1062 1154//1154 980//980 +f 1044//1044 503//503 1134//1134 +f 938//938 1168//1168 814//814 +f 325//325 1126//1126 633//633 +f 1182//1182 1107//1107 1106//1106 +f 1183//1183 1184//1184 1185//1185 +f 1163//1163 1186//1186 1145//1145 +f 1186//1186 1187//1187 1145//1145 +f 1145//1145 1187//1187 1137//1137 +f 1137//1137 530//530 1176//1176 +f 1122//1122 1176//1176 1158//1158 +f 1165//1165 681//681 943//943 +f 1188//1188 1061//1061 937//937 +f 1171//1171 1170//1170 1189//1189 +f 1179//1179 942//942 1190//1190 +f 1182//1182 1066//1066 1107//1107 +f 1191//1191 1135//1135 1192//1192 +f 611//611 1163//1163 1157//1157 +f 1187//1187 530//530 1137//1137 +f 1117//1117 977//977 1099//1099 +f 1027//1027 1181//1181 1193//1193 +f 1194//1194 1179//1179 1190//1190 +f 1042//1042 1195//1195 1043//1043 +f 951//951 350//350 526//526 +f 968//968 970//970 985//985 +f 1196//1196 1146//1146 1164//1164 +f 160//160 1197//1197 144//144 +f 227//227 263//263 1010//1010 +f 1186//1186 1198//1198 1187//1187 +f 422//422 67//67 9//9 +f 1001//1001 1199//1199 1002//1002 +f 29//29 617//617 311//311 +f 1001//1001 919//919 1199//1199 +f 1047//1047 1200//1200 1048//1048 +f 1201//1201 605//605 1202//1202 +f 1190//1190 952//952 1044//1044 +f 1191//1191 1042//1042 1135//1135 +f 1203//1203 1171//1171 1204//1204 +f 1167//1167 1171//1171 1203//1203 +f 611//611 1205//1205 1163//1163 +f 1163//1163 1205//1205 1186//1186 +f 1187//1187 531//531 530//530 +f 586//586 1206//1206 338//338 +f 1081//1081 1073//1073 1207//1207 +f 1150//1150 410//410 409//409 +f 1207//1207 1073//1073 1090//1090 +f 836//836 1061//1061 1188//1188 +f 1195//1195 1190//1190 1043//1043 +f 1179//1179 1000//1000 940//940 +f 960//960 1027//1027 796//796 +f 826//826 825//825 1107//1107 +f 1042//1042 1044//1044 1134//1134 +f 1208//1208 1209//1209 1210//1210 +f 775//775 310//310 776//776 +f 1205//1205 1198//1198 1186//1186 +f 855//855 1211//1211 1212//1212 +f 966//966 1213//1213 244//244 +f 606//606 968//968 335//335 +f 381//381 388//388 382//382 +f 141//141 618//618 142//142 +f 758//758 1074//1074 1082//1082 +f 946//946 979//979 981//981 +f 1051//1051 1214//1214 1028//1028 +f 1204//1204 1189//1189 1192//1192 +f 1204//1204 1171//1171 1189//1189 +f 1215//1215 1216//1216 1217//1217 +f 1198//1198 531//531 1187//1187 +f 1218//1218 424//424 1219//1219 +f 936//936 336//336 338//338 +f 203//203 984//984 228//228 +f 1136//1136 936//936 338//338 +f 1039//1039 1051//1051 1040//1040 +f 1152//1152 1039//1039 1041//1041 +f 1218//1218 712//712 425//425 +f 935//935 1108//1108 455//455 +f 1064//1064 381//381 383//383 +f 1220//1220 1030//1030 1000//1000 +f 984//984 267//267 228//228 +f 1221//1221 1037//1037 1222//1222 +f 861//861 380//380 379//379 +f 1130//1130 944//944 681//681 +f 1223//1223 1195//1195 1191//1191 +f 1155//1155 1162//1162 956//956 +f 1213//1213 1224//1224 244//244 +f 1225//1225 1226//1226 1227//1227 +f 1063//1063 401//401 1019//1019 +f 1205//1205 611//611 610//610 +f 26//26 1228//1228 187//187 +f 1229//1229 1068//1068 1072//1072 +f 1206//1206 1230//1230 338//338 +f 1195//1195 1223//1223 1190//1190 +f 957//957 1148//1148 861//861 +f 964//964 35//35 1038//1038 +f 1001//1001 1150//1150 1151//1151 +f 1075//1075 1166//1166 1200//1200 +f 1231//1231 172//172 1232//1232 +f 1075//1075 1200//1200 1047//1047 +f 1079//1079 1073//1073 1081//1081 +f 448//448 960//960 796//796 +f 486//486 339//339 487//487 +f 339//339 341//341 487//487 +f 274//274 328//328 275//275 +f 681//681 944//944 943//943 +f 1030//1030 410//410 1150//1150 +f 1100//1100 635//635 812//812 +f 796//796 758//758 449//449 +f 1220//1220 1000//1000 1179//1179 +f 1233//1233 463//463 1234//1234 +f 1131//1131 383//383 978//978 +f 1166//1166 1167//1167 1200//1200 +f 495//495 1235//1235 245//245 +f 1000//1000 1002//1002 940//940 +f 1066//1066 1182//1182 1106//1106 +f 301//301 275//275 328//328 +f 300//300 1236//1236 371//371 +f 1041//1041 1040//1040 1170//1170 +f 582//582 1237//1237 414//414 +f 988//988 1238//1238 1239//1239 +f 1239//1239 1238//1238 817//817 +f 1238//1238 818//818 817//817 +f 1019//1019 401//401 1240//1240 +f 1241//1241 1242//1242 1243//1243 +f 945//945 978//978 1016//1016 +f 1188//1188 862//862 861//861 +f 81//81 1228//1228 1244//1244 +f 1245//1245 1246//1246 612//612 +f 1247//1247 861//861 379//379 +f 1099//1099 977//977 945//945 +f 1063//1063 402//402 401//401 +f 166//166 1248//1248 357//357 +f 1024//1024 1007//1007 1249//1249 +f 547//547 772//772 249//249 +f 1192//1192 1189//1189 1191//1191 +f 1064//1064 383//383 1131//1131 +f 567//567 964//964 1023//1023 +f 942//942 941//941 1190//1190 +f 1250//1250 1251//1251 1007//1007 +f 388//388 723//723 1012//1012 +f 1252//1252 1253//1253 1254//1254 +f 1255//1255 525//525 1221//1221 +f 1256//1256 1257//1257 341//341 +f 231//231 233//233 1258//1258 +f 749//749 748//748 1045//1045 +f 141//141 1132//1132 987//987 +f 987//987 1132//1132 642//642 +f 143//143 1132//1132 141//141 +f 1259//1259 1260//1260 232//232 +f 1261//1261 588//588 1238//1238 +f 892//892 894//894 1262//1262 +f 1263//1263 1264//1264 107//107 +f 293//293 292//292 1061//1061 +f 238//238 769//769 239//239 +f 986//986 354//354 335//335 +f 825//825 1265//1265 1168//1168 +f 388//388 387//387 723//723 +f 1040//1040 1223//1223 1191//1191 +f 1065//1065 1064//1064 1101//1101 +f 1178//1178 1102//1102 1101//1101 +f 772//772 316//316 249//249 +f 988//988 1261//1261 1238//1238 +f 1148//1148 1188//1188 861//861 +f 1018//1018 1068//1068 1229//1229 +f 1170//1170 1266//1266 1189//1189 +f 1170//1170 1191//1191 1266//1266 +f 272//272 700//700 1037//1037 +f 520//520 1229//1229 448//448 +f 1267//1267 141//141 987//987 +f 588//588 863//863 818//818 +f 1116//1116 1131//1131 978//978 +f 1051//1051 1220//1220 1052//1052 +f 862//862 1188//1188 937//937 +f 1040//1040 1191//1191 1170//1170 +f 1194//1194 1220//1220 1179//1179 +f 1008//1008 1250//1250 1007//1007 +f 675//675 256//256 319//319 +f 272//272 1037//1037 524//524 +f 946//946 981//981 947//947 +f 63//63 217//217 1031//1031 +f 1268//1268 1269//1269 1270//1270 +f 1249//1249 1023//1023 1024//1024 +f 1023//1023 1249//1249 567//567 +f 964//964 567//567 35//35 +f 933//933 926//926 822//822 +f 1000//1000 1030//1030 1150//1150 +f 114//114 1271//1271 113//113 +f 1072//1072 1026//1026 1025//1025 +f 1072//1072 1039//1039 1152//1152 +f 1272//1272 987//987 321//321 +f 1267//1267 618//618 141//141 +f 993//993 770//770 769//769 +f 251//251 910//910 1173//1173 +f 487//487 341//341 1257//1257 +f 572//572 847//847 501//501 +f 1075//1075 1193//1193 1181//1181 +f 1273//1273 1274//1274 1275//1275 +f 354//354 986//986 946//946 +f 423//423 750//750 1276//1276 +f 1126//1126 966//966 967//967 +f 1272//1272 1267//1267 987//987 +f 1267//1267 636//636 618//618 +f 27//27 310//310 775//775 +f 238//238 183//183 185//185 +f 1277//1277 1278//1278 1279//1279 +f 837//837 1188//1188 1148//1148 +f 402//402 847//847 572//572 +f 242//242 254//254 342//342 +f 63//63 1032//1032 1280//1280 +f 1072//1072 1068//1068 1039//1039 +f 1074//1074 1193//1193 1075//1075 +f 1026//1026 1072//1072 1152//1152 +f 981//981 829//829 947//947 +f 999//999 1281//1281 1282//1282 +f 919//919 1109//1109 546//546 +f 981//981 980//980 829//829 +f 1191//1191 1195//1195 1042//1042 +f 336//336 935//935 455//455 +f 413//413 441//441 1067//1067 +f 907//907 867//867 891//891 +f 1108//1108 968//968 455//455 +f 979//979 946//946 986//986 +f 641//641 642//642 982//982 +f 270//270 643//643 268//268 +f 1247//1247 1283//1283 861//861 +f 1050//1050 1052//1052 1223//1223 +f 1284//1284 233//233 407//407 +f 969//969 1142//1142 970//970 +f 1285//1285 1286//1286 1287//1287 +f 1288//1288 1183//1183 1185//1185 +f 985//985 1003//1003 979//979 +f 1289//1289 1068//1068 1018//1018 +f 1028//1028 1290//1290 1029//1029 +f 943//943 945//945 1016//1016 +f 286//286 309//309 413//413 +f 1116//1116 978//978 977//977 +f 1247//1247 379//379 829//829 +f 1220//1220 1194//1194 1052//1052 +f 1107//1107 825//825 938//938 +f 1283//1283 957//957 861//861 +f 1214//1214 1290//1290 1028//1028 +f 610//610 1198//1198 1205//1205 +f 1066//1066 1106//1106 381//381 +f 1291//1291 288//288 1005//1005 +f 960//960 1025//1025 1027//1027 +f 1018//1018 1292//1292 773//773 +f 1293//1293 1114//1114 1272//1272 +f 1294//1294 636//636 1267//1267 +f 1294//1294 1295//1295 636//636 +f 1296//1296 1297//1297 1298//1298 +f 185//185 769//769 238//238 +f 1261//1261 1299//1299 588//588 +f 387//387 728//728 723//723 +f 1151//1151 919//919 1001//1001 +f 1153//1153 1041//1041 1170//1170 +f 1204//1204 1192//1192 1156//1156 +f 1190//1190 951//951 952//952 +f 1082//1082 1078//1078 1077//1077 +f 1300//1300 1301//1301 1302//1302 +f 925//925 183//183 238//238 +f 344//344 1258//1258 1284//1284 +f 1283//1283 955//955 957//957 +f 1057//1057 837//837 1148//1148 +f 1090//1090 1075//1075 1047//1047 +f 1080//1080 935//935 936//936 +f 642//642 1132//1132 1303//1303 +f 1304//1304 1288//1288 1185//1185 +f 1051//1051 1050//1050 1040//1040 +f 1029//1029 410//410 1030//1030 +f 836//836 1188//1188 837//837 +f 243//243 342//342 523//523 +f 1293//1293 320//320 856//856 +f 1174//1174 270//270 1305//1305 +f 1299//1299 1306//1306 588//588 +f 1099//1099 945//945 944//944 +f 1189//1189 1266//1266 1191//1191 +f 1090//1090 1142//1142 1207//1207 +f 1136//1136 1080//1080 936//936 +f 1135//1135 1134//1134 1162//1162 +f 1052//1052 1194//1194 1223//1223 +f 1051//1051 1028//1028 1220//1220 +f 253//253 252//252 1180//1180 +f 1267//1267 1272//1272 1294//1294 +f 1307//1307 692//692 636//636 +f 1295//1295 1307//1307 636//636 +f 644//644 501//501 847//847 +f 1308//1308 360//360 370//370 +f 1051//1051 1159//1159 1214//1214 +f 980//980 1283//1283 1247//1247 +f 1166//1166 1181//1181 1153//1153 +f 1075//1075 1181//1181 1166//1166 +f 941//941 1199//1199 545//545 +f 1220//1220 1028//1028 1030//1030 +f 965//965 402//402 1063//1063 +f 1309//1309 1294//1294 1272//1272 +f 1237//1237 1240//1240 401//401 +f 271//271 764//764 700//700 +f 1310//1310 1311//1311 1312//1312 +f 692//692 651//651 637//637 +f 980//980 955//955 1283//1283 +f 1173//1173 910//910 1174//1174 +f 856//856 1114//1114 1293//1293 +f 360//360 1313//1313 358//358 +f 1309//1309 1272//1272 1114//1114 +f 1313//1313 961//961 358//358 +f 479//479 1314//1314 175//175 +f 1081//1081 1207//1207 1108//1108 +f 1207//1207 969//969 1108//1108 +f 926//926 666//666 668//668 +f 455//455 968//968 606//606 +f 1315//1315 1295//1295 1294//1294 +f 1004//1004 1307//1307 1295//1295 +f 1315//1315 1004//1004 1295//1295 +f 335//335 968//968 986//986 +f 1206//1206 586//586 588//588 +f 1306//1306 1206//1206 588//588 +f 937//937 1061//1061 435//435 +f 1101//1101 1131//1131 1115//1115 +f 956//956 1162//1162 1057//1057 +f 1090//1090 1047//1047 1142//1142 +f 1207//1207 1142//1142 969//969 +f 1192//1192 1155//1155 1156//1156 +f 1190//1190 941//941 951//951 +f 764//764 699//699 700//700 +f 1155//1155 1135//1135 1162//1162 +f 1200//1200 1167//1167 1048//1048 +f 448//448 1229//1229 959//959 +f 1223//1223 1194//1194 1190//1190 +f 1006//1006 632//632 812//812 +f 1114//1114 1165//1165 1309//1309 +f 1309//1309 1315//1315 1294//1294 +f 959//959 1229//1229 1072//1072 +f 1316//1316 1317//1317 613//613 +f 701//701 723//723 728//728 +f 1261//1261 988//988 950//950 +f 1151//1151 1109//1109 919//919 +f 275//275 300//300 371//371 +f 1204//1204 1156//1156 1062//1062 +f 812//812 813//813 1098//1098 +f 295//295 649//649 296//296 +f 1000//1000 1150//1150 1001//1001 +f 721//721 249//249 248//248 +f 321//321 320//320 1293//1293 +f 1318//1318 1307//1307 1004//1004 +f 1318//1318 692//692 1307//1307 +f 1318//1318 723//723 692//692 +f 1319//1319 1273//1273 663//663 +f 598//598 458//458 590//590 +f 953//953 1045//1045 748//748 +f 815//815 1320//1320 729//729 +f 818//818 863//863 807//807 +f 1048//1048 1204//1204 1062//1062 +f 1048//1048 1062//1062 1049//1049 +f 1117//1117 1116//1116 977//977 +f 1156//1156 1155//1155 1154//1154 +f 954//954 964//964 953//953 +f 796//796 1027//1027 1193//1193 +f 209//209 1165//1165 1114//1114 +f 1161//1161 1235//1235 1321//1321 +f 213//213 1322//1322 85//85 +f 1007//1007 1024//1024 965//965 +f 583//583 758//758 1149//1149 +f 1106//1106 386//386 388//388 +f 381//381 1106//1106 388//388 +f 1323//1323 610//610 688//688 +f 1324//1324 1325//1325 1326//1326 +f 1044//1044 1043//1043 1190//1190 +f 758//758 796//796 1074//1074 +f 1066//1066 1058//1058 1107//1107 +f 1115//1115 1327//1327 1101//1101 +f 1328//1328 213//213 85//85 +f 829//829 980//980 1247//1247 +f 1024//1024 958//958 965//965 +f 1065//1065 1058//1058 1066//1066 +f 1162//1162 837//837 1057//1057 +f 1080//1080 1081//1081 935//935 +f 1246//1246 1329//1329 826//826 +f 1048//1048 1203//1203 1204//1204 +f 555//555 554//554 16//16 +f 796//796 1193//1193 1074//1074 +f 1016//1016 1004//1004 1315//1315 +f 1318//1318 1012//1012 723//723 +f 1330//1330 136//136 4//4 +f 1331//1331 675//675 676//676 +f 1192//1192 1135//1135 1155//1155 +f 1107//1107 938//938 386//386 +f 1153//1153 1026//1026 1152//1152 +f 1040//1040 1050//1050 1223//1223 +f 1107//1107 1058//1058 826//826 +f 469//469 720//720 721//721 +f 1165//1165 943//943 1315//1315 +f 1309//1309 1165//1165 1315//1315 +f 943//943 1016//1016 1315//1315 +f 1332//1332 1333//1333 1334//1334 +f 288//288 286//286 413//413 +f 940//940 1002//1002 941//941 +f 1002//1002 1199//1199 941//941 +f 1076//1076 1078//1078 1080//1080 +f 729//729 1320//1320 761//761 +f 1003//1003 970//970 1097//1097 +f 566//566 1095//1095 1129//1129 +f 1167//1167 1203//1203 1048//1048 +f 658//658 926//926 933//933 +f 1335//1335 1336//1336 1337//1337 +f 383//383 1318//1318 1004//1004 +f 383//383 1012//1012 1318//1318 +f 545//545 1199//1199 919//919 +f 1338//1338 312//312 311//311 +f 1082//1082 1079//1079 1078//1078 +f 961//961 183//183 925//925 +f 80//80 1339//1339 81//81 +f 1340//1340 934//934 93//93 +f 1340//1340 93//93 133//133 +f 1341//1341 1342//1342 1343//1343 +f 1341//1341 1343//1343 789//789 +f 1344//1344 116//116 1345//1345 +f 1098//1098 1100//1100 812//812 +f 77//77 1346//1346 78//78 +f 421//421 118//118 171//171 +f 1347//1347 1348//1348 1349//1349 +f 1350//1350 1330//1330 1351//1351 +f 1349//1349 1352//1352 1094//1094 +f 133//133 93//93 134//134 +f 1353//1353 334//334 1354//1354 +f 1355//1355 1356//1356 1351//1351 +f 145//145 1357//1357 322//322 +f 322//322 1358//1358 68//68 +f 85//85 84//84 527//527 +f 1359//1359 85//85 527//527 +f 1305//1305 1172//1172 1174//1174 +f 68//68 1358//1358 1360//1360 +f 1361//1361 116//116 1344//1344 +f 304//304 303//303 1362//1362 +f 1363//1363 764//764 271//271 +f 160//160 146//146 1364//1364 +f 419//419 1201//1201 420//420 +f 1365//1365 974//974 976//976 +f 1366//1366 1367//1367 1368//1368 +f 1369//1369 1370//1370 1278//1278 +f 625//625 1371//1371 1372//1372 +f 1316//1316 1373//1373 1374//1374 +f 210//210 1375//1375 105//105 +f 1364//1364 146//146 191//191 +f 96//96 98//98 691//691 +f 851//851 96//96 691//691 +f 576//576 319//319 256//256 +f 303//303 1376//1376 1377//1377 +f 1374//1374 677//677 679//679 +f 1211//1211 1378//1378 276//276 +f 1339//1339 1287//1287 30//30 +f 310//310 1342//1342 776//776 +f 565//565 1379//1379 471//471 +f 1380//1380 1242//1242 1241//1241 +f 1378//1378 831//831 1381//1381 +f 237//237 1006//1006 634//634 +f 5//5 280//280 279//279 +f 1065//1065 1373//1373 1059//1059 +f 842//842 1096//1096 1382//1382 +f 1383//1383 1380//1380 1384//1384 +f 232//232 1274//1274 1273//1273 +f 1385//1385 1386//1386 1387//1387 +f 1388//1388 1389//1389 360//360 +f 1390//1390 1389//1389 1388//1388 +f 225//225 788//788 868//868 +f 1391//1391 1392//1392 1393//1393 +f 616//616 28//28 478//478 +f 813//813 1327//1327 1098//1098 +f 1394//1394 1383//1383 1384//1384 +f 1345//1345 564//564 563//563 +f 1345//1345 45//45 564//564 +f 134//134 1395//1395 823//823 +f 1396//1396 1397//1397 1398//1398 +f 320//320 576//576 856//856 +f 1177//1177 678//678 677//677 +f 1374//1374 1373//1373 677//677 +f 1399//1399 1304//1304 1185//1185 +f 1400//1400 1339//1339 80//80 +f 5//5 138//138 1401//1401 +f 247//247 563//563 565//565 +f 1365//1365 976//976 1208//1208 +f 854//854 591//591 1402//1402 +f 1339//1339 30//30 1403//1403 +f 1313//1313 1389//1389 1404//1404 +f 495//495 494//494 868//868 +f 312//312 1342//1342 310//310 +f 1404//1404 1405//1405 184//184 +f 1406//1406 1407//1407 1408//1408 +f 1361//1361 50//50 116//116 +f 523//523 525//525 643//643 +f 510//510 1409//1409 1410//1410 +f 973//973 972//972 1242//1242 +f 880//880 1411//1411 1412//1412 +f 690//690 852//852 691//691 +f 1373//1373 1065//1065 1177//1177 +f 1412//1412 878//878 880//880 +f 1413//1413 1414//1414 1415//1415 +f 1242//1242 972//972 1243//1243 +f 652//652 833//833 1416//1416 +f 1367//1367 582//582 583//583 +f 1364//1364 1375//1375 1417//1417 +f 1401//1401 138//138 1418//1418 +f 1419//1419 1388//1388 1308//1308 +f 312//312 1344//1344 1342//1342 +f 132//132 823//823 1420//1420 +f 1421//1421 1397//1397 1422//1422 +f 1423//1423 1424//1424 1425//1425 +f 1375//1375 210//210 1426//1426 +f 138//138 1364//1364 1418//1418 +f 1364//1364 191//191 1375//1375 +f 1356//1356 1350//1350 1351//1351 +f 1427//1427 1428//1428 1429//1429 +f 1430//1430 1431//1431 1432//1432 +f 1433//1433 1434//1434 1317//1317 +f 623//623 1390//1390 1388//1388 +f 904//904 734//734 1435//1435 +f 1436//1436 1437//1437 1077//1077 +f 1396//1396 1398//1398 1419//1419 +f 407//407 1319//1319 345//345 +f 1438//1438 1439//1439 1336//1336 +f 1419//1419 1308//1308 1396//1396 +f 1413//1413 1440//1440 1414//1414 +f 1361//1361 1344//1344 312//312 +f 634//634 1006//1006 812//812 +f 1178//1178 1101//1101 1327//1327 +f 358//358 274//274 359//359 +f 1389//1389 1313//1313 360//360 +f 1376//1376 303//303 302//302 +f 971//971 1441//1441 1442//1442 +f 1443//1443 1336//1336 603//603 +f 1444//1444 1384//1384 1380//1380 +f 564//564 47//47 1379//1379 +f 365//365 1445//1445 1446//1446 +f 1447//1447 827//827 1329//1329 +f 78//78 794//794 745//745 +f 1448//1448 1449//1449 1450//1450 +f 1397//1397 1396//1396 1451//1451 +f 1452//1452 1397//1397 1451//1451 +f 659//659 608//608 1129//1129 +f 1077//1077 1437//1437 1082//1082 +f 421//421 211//211 118//118 +f 1216//1216 1453//1453 1454//1454 +f 1422//1422 1452//1452 1455//1455 +f 210//210 117//117 222//222 +f 134//134 279//279 1395//1395 +f 1391//1391 1456//1456 1392//1392 +f 971//971 1442//1442 1457//1457 +f 1442//1442 1391//1391 1458//1458 +f 565//565 564//564 1379//1379 +f 1273//1273 1319//1319 233//233 +f 1459//1459 1178//1178 813//813 +f 81//81 1339//1339 187//187 +f 677//677 1373//1373 1177//1177 +f 789//789 1343//1343 563//563 +f 190//190 234//234 223//223 +f 1460//1460 1461//1461 1263//1263 +f 186//186 330//330 223//223 +f 620//620 1312//1312 306//306 +f 1422//1422 1455//1455 1462//1462 +f 1076//1076 1463//1463 1077//1077 +f 1457//1457 1442//1442 1458//1458 +f 1464//1464 1436//1436 1465//1465 +f 975//975 1456//1456 976//976 +f 1209//1209 976//976 1441//1441 +f 1466//1466 277//277 1467//1467 +f 134//134 6//6 279//279 +f 1468//1468 833//833 652//652 +f 1457//1457 1458//1458 972//972 +f 500//500 541//541 611//611 +f 1130//1130 680//680 635//635 +f 197//197 1468//1468 652//652 +f 1343//1343 1345//1345 563//563 +f 1339//1339 1403//1403 187//187 +f 1469//1469 1470//1470 1471//1471 +f 793//793 1376//1376 745//745 +f 975//975 1421//1421 1456//1456 +f 1472//1472 1473//1473 1392//1392 +f 927//927 1474//1474 1475//1475 +f 1476//1476 1477//1477 1478//1478 +f 605//605 604//604 1479//1479 +f 1034//1034 1015//1015 1480//1480 +f 813//813 1178//1178 1327//1327 +f 405//405 679//679 678//678 +f 1481//1481 1482//1482 1483//1483 +f 1//1 3//3 305//305 +f 623//623 1388//1388 1419//1419 +f 1479//1479 604//604 3//3 +f 1437//1437 1149//1149 1082//1082 +f 1484//1484 1485//1485 1486//1486 +f 1487//1487 1415//1415 1488//1488 +f 1473//1473 1393//1393 1392//1392 +f 1413//1413 1415//1415 185//185 +f 64//64 63//63 1280//1280 +f 1489//1489 113//113 1271//1271 +f 1159//1159 1490//1490 1214//1214 +f 1491//1491 200//200 1492//1492 +f 1407//1407 1493//1493 1408//1408 +f 1469//1469 1494//1494 1470//1470 +f 1397//1397 1452//1452 1422//1422 +f 1495//1495 1206//1206 1306//1306 +f 1418//1418 1364//1364 1417//1417 +f 1496//1496 1423//1423 1425//1425 +f 1497//1497 1498//1498 840//840 +f 1437//1437 1499//1499 1149//1149 +f 1059//1059 612//612 1246//1246 +f 1407//1407 1500//1500 1493//1493 +f 1501//1501 50//50 1361//1361 +f 389//389 652//652 1416//1416 +f 972//972 1458//1458 1276//1276 +f 1502//1502 1503//1503 277//277 +f 1452//1452 1451//1451 1504//1504 +f 1451//1451 1308//1308 370//370 +f 675//675 319//319 641//641 +f 1375//1375 1426//1426 1417//1417 +f 842//842 1497//1497 840//840 +f 975//975 974//974 1425//1425 +f 676//676 982//982 1505//1505 +f 961//961 1404//1404 184//184 +f 1415//1415 994//994 185//185 +f 1452//1452 1504//1504 1455//1455 +f 1506//1506 1507//1507 1508//1508 +f 1503//1503 197//197 196//196 +f 196//196 1467//1467 277//277 +f 1208//1208 976//976 1209//1209 +f 274//274 961//961 925//925 +f 196//196 277//277 1503//1503 +f 280//280 5//5 1401//1401 +f 1383//1383 1509//1509 1380//1380 +f 1510//1510 1511//1511 1512//1512 +f 975//975 1425//1425 1513//1513 +f 327//327 240//240 253//253 +f 657//657 1361//1361 312//312 +f 878//878 1412//1412 1398//1398 +f 1398//1398 623//623 1419//1419 +f 1201//1201 1443//1443 603//603 +f 603//603 1514//1514 851//851 +f 1501//1501 48//48 50//50 +f 1514//1514 96//96 851//851 +f 1293//1293 1272//1272 321//321 +f 239//239 770//770 1515//1515 +f 449//449 758//758 416//416 +f 1316//1316 1059//1059 1373//1373 +f 1516//1516 1509//1509 1383//1383 +f 1517//1517 1518//1518 1519//1519 +f 1369//1369 1520//1520 1521//1521 +f 1412//1412 623//623 1398//1398 +f 1243//1243 1276//1276 750//750 +f 1241//1241 1243//1243 750//750 +f 1241//1241 750//750 1133//1133 +f 565//565 471//471 247//247 +f 664//664 855//855 1212//1212 +f 961//961 184//184 183//183 +f 1144//1144 1328//1328 1359//1359 +f 1456//1456 1462//1462 1392//1392 +f 1424//1424 1398//1398 1397//1397 +f 1394//1394 1384//1384 1471//1471 +f 1388//1388 360//360 1308//1308 +f 274//274 925//925 327//327 +f 1401//1401 1418//1418 1522//1522 +f 1523//1523 858//858 1524//1524 +f 6//6 5//5 279//279 +f 1425//1425 1424//1424 1513//1513 +f 878//878 1398//1398 1424//1424 +f 852//852 619//619 850//850 +f 345//345 1319//1319 663//663 +f 1525//1525 1526//1526 445//445 +f 1412//1412 624//624 623//623 +f 663//663 1501//1501 1361//1361 +f 657//657 663//663 1361//1361 +f 41//41 186//186 1527//1527 +f 1381//1381 1468//1468 1502//1502 +f 2//2 1479//1479 3//3 +f 3//3 604//604 305//305 +f 905//905 1//1 306//306 +f 971//971 1457//1457 972//972 +f 1451//1451 370//370 1504//1504 +f 271//271 1511//1511 1363//1363 +f 774//774 1289//1289 1018//1018 +f 306//306 1312//1312 905//905 +f 1313//1313 1404//1404 961//961 +f 1243//1243 972//972 1276//1276 +f 1210//1210 1209//1209 1441//1441 +f 1343//1343 1342//1342 1344//1344 +f 1115//1115 1117//1117 1098//1098 +f 1338//1338 657//657 312//312 +f 1210//1210 1441//1441 971//971 +f 1528//1528 1524//1524 858//858 +f 795//795 794//794 1346//1346 +f 1509//1509 1242//1242 1380//1380 +f 1441//1441 1391//1391 1442//1442 +f 568//568 570//570 648//648 +f 1529//1529 1029//1029 1290//1290 +f 1421//1421 1422//1422 1456//1456 +f 1471//1471 1470//1470 1530//1530 +f 185//185 994//994 769//769 +f 1513//1513 1424//1424 1397//1397 +f 1531//1531 1164//1164 1158//1158 +f 1396//1396 1308//1308 1451//1451 +f 1532//1532 1533//1533 1534//1534 +f 234//234 132//132 1420//1420 +f 1490//1490 1290//1290 1214//1214 +f 1490//1490 1529//1529 1290//1290 +f 1529//1529 410//410 1029//1029 +f 1515//1515 252//252 239//239 +f 1471//1471 1530//1530 1394//1394 +f 1535//1535 277//277 1466//1466 +f 1273//1273 1275//1275 663//663 +f 1133//1133 750//750 713//713 +f 967//967 237//237 634//634 +f 1536//1536 1537//1537 1538//1538 +f 1441//1441 976//976 1391//1391 +f 1455//1455 1539//1539 1462//1462 +f 1275//1275 1501//1501 663//663 +f 1202//1202 1479//1479 2//2 +f 1275//1275 48//48 1501//1501 +f 1531//1531 1196//1196 1164//1164 +f 1433//1433 1317//1317 679//679 +f 1462//1462 1539//1539 1472//1472 +f 1434//1434 613//613 1317//1317 +f 1456//1456 1422//1422 1462//1462 +f 1509//1509 973//973 1242//1242 +f 1513//1513 1397//1397 1421//1421 +f 421//421 1202//1202 2//2 +f 1540//1540 1159//1159 1289//1289 +f 1540//1540 1490//1490 1159//1159 +f 1540//1540 1529//1529 1490//1490 +f 548//548 410//410 1529//1529 +f 1541//1541 643//643 1255//1255 +f 1474//1474 1542//1542 1543//1543 +f 1544//1544 1176//1176 1545//1545 +f 1544//1544 1531//1531 1176//1176 +f 525//525 1037//1037 1221//1221 +f 209//209 1114//1114 207//207 +f 976//976 1456//1456 1391//1391 +f 975//975 1513//1513 1421//1421 +f 421//421 69//69 1202//1202 +f 1546//1546 1547//1547 1548//1548 +f 69//69 420//420 1202//1202 +f 711//711 1529//1529 1540//1540 +f 710//710 548//548 1529//1529 +f 1531//1531 1303//1303 1196//1196 +f 1303//1303 1132//1132 1196//1196 +f 1504//1504 911//911 1455//1455 +f 1547//1547 80//80 1548//1548 +f 1545//1545 530//530 1505//1505 +f 27//27 570//570 569//569 +f 1547//1547 1400//1400 80//80 +f 774//774 1540//1540 1289//1289 +f 711//711 710//710 1529//1529 +f 253//253 711//711 326//326 +f 1549//1549 217//217 1550//1550 +f 1542//1542 1549//1549 1550//1550 +f 35//35 488//488 1257//1257 +f 614//614 1245//1245 612//612 +f 518//518 519//519 837//837 +f 1007//1007 1251//1251 1249//1249 +f 1177//1177 1459//1459 678//678 +f 295//295 355//355 946//946 +f 1059//1059 1058//1058 1065//1065 +f 311//311 343//343 1338//1338 +f 757//757 711//711 1540//1540 +f 613//613 1434//1434 614//614 +f 1504//1504 370//370 911//911 +f 982//982 1544//1544 1545//1545 +f 925//925 238//238 240//240 +f 1020//1020 1541//1541 1551//1551 +f 1551//1551 1541//1541 1250//1250 +f 1249//1249 486//486 567//567 +f 269//269 1305//1305 270//270 +f 757//757 1540//1540 774//774 +f 643//643 525//525 1255//1255 +f 81//81 1244//1244 25//25 +f 305//305 620//620 306//306 +f 1552//1552 1553//1553 1554//1554 +f 1474//1474 1543//1543 1475//1475 +f 944//944 1130//1130 1099//1099 +f 982//982 1545//1545 1505//1505 +f 642//642 1531//1531 1544//1544 +f 1531//1531 642//642 1303//1303 +f 1531//1531 1158//1158 1176//1176 +f 1250//1250 1221//1221 1251//1251 +f 567//567 486//486 488//488 +f 1555//1555 973//973 1509//1509 +f 268//268 643//643 1541//1541 +f 328//328 756//756 301//301 +f 1174//1174 910//910 270//270 +f 116//116 1556//1556 1345//1345 +f 803//803 517//517 749//749 +f 1541//1541 1255//1255 1250//1250 +f 1250//1250 1255//1255 1221//1221 +f 756//756 328//328 326//326 +f 554//554 854//854 509//509 +f 1222//1222 339//339 486//486 +f 1343//1343 1344//1344 1345//1345 +f 982//982 642//642 1544//1544 +f 1550//1550 217//217 1557//1557 +f 1221//1221 1222//1222 1251//1251 +f 1251//1251 486//486 1249//1249 +f 487//487 1257//1257 488//488 +f 756//756 757//757 774//774 +f 326//326 711//711 757//757 +f 710//710 1180//1180 548//548 +f 1180//1180 549//549 548//548 +f 1037//1037 339//339 1222//1222 +f 676//676 1505//1505 392//392 +f 1251//1251 1222//1222 486//486 +f 11//11 1558//1558 12//12 +f 1559//1559 1560//1560 1274//1274 +f 11//11 107//107 55//55 +f 60//60 124//124 1561//1561 +f 963//963 1147//1147 1139//1139 +f 1562//1562 495//495 868//868 +f 1563//1563 1460//1460 107//107 +f 23//23 22//22 1196//1196 +f 192//192 60//60 1561//1561 +f 10//10 1563//1563 107//107 +f 1379//1379 192//192 472//472 +f 598//598 653//653 458//458 +f 1560//1560 48//48 1274//1274 +f 1045//1045 1038//1038 34//34 +f 1560//1560 12//12 48//48 +f 1556//1556 45//45 1345//1345 +f 1564//1564 1331//1331 1565//1565 +f 765//765 1256//1256 341//341 +f 810//810 1113//1113 357//357 +f 1256//1256 1566//1566 33//33 +f 1567//1567 34//34 33//33 +f 1566//1566 1567//1567 33//33 +f 1567//1567 1045//1045 34//34 +f 1568//1568 103//103 1569//1569 +f 1570//1570 36//36 38//38 +f 170//170 169//169 817//817 +f 765//765 1252//1252 1256//1256 +f 401//401 414//414 1237//1237 +f 1571//1571 1572//1572 1248//1248 +f 45//45 115//115 46//46 +f 1252//1252 1573//1573 1256//1256 +f 1573//1573 1574//1574 1256//1256 +f 1256//1256 1574//1574 1566//1566 +f 1574//1574 1575//1575 1566//1566 +f 1566//1566 1575//1575 1567//1567 +f 1257//1257 1256//1256 33//33 +f 418//418 576//576 256//256 +f 1575//1575 1576//1576 1567//1567 +f 459//459 125//125 128//128 +f 1577//1577 760//760 761//761 +f 1567//1567 1576//1576 803//803 +f 1254//1254 1573//1573 1252//1252 +f 1578//1578 1574//1574 1573//1573 +f 1574//1574 1579//1579 1575//1575 +f 1575//1575 1579//1579 1576//1576 +f 1569//1569 573//573 574//574 +f 1580//1580 1578//1578 1573//1573 +f 1579//1579 1574//1574 1578//1578 +f 1579//1579 1581//1581 1576//1576 +f 1576//1576 522//522 803//803 +f 39//39 258//258 65//65 +f 1311//1311 87//87 128//128 +f 1581//1581 522//522 1576//1576 +f 1292//1292 1229//1229 522//522 +f 1292//1292 522//522 1581//1581 +f 1581//1581 1579//1579 1578//1578 +f 773//773 1292//1292 1581//1581 +f 845//845 999//999 1282//1282 +f 22//22 1146//1146 1196//1196 +f 689//689 98//98 109//109 +f 1438//1438 1336//1336 1443//1443 +f 1268//1268 1582//1582 1269//1269 +f 137//137 136//136 1330//1330 +f 1583//1583 1578//1578 1580//1580 +f 1236//1236 1583//1583 1580//1580 +f 1583//1583 1581//1581 1578//1578 +f 1581//1581 1583//1583 773//773 +f 133//133 31//31 1286//1286 +f 729//729 760//760 728//728 +f 1351//1351 1330//1330 4//4 +f 105//105 171//171 210//210 +f 1571//1571 1248//1248 166//166 +f 934//934 1351//1351 94//94 +f 1351//1351 4//4 94//94 +f 1092//1092 1584//1584 1071//1071 +f 300//300 301//301 1583//1583 +f 1583//1583 301//301 773//773 +f 1146//1146 22//22 1113//1113 +f 1577//1577 38//38 694//694 +f 1585//1585 159//159 179//179 +f 731//731 159//159 23//23 +f 166//166 1113//1113 22//22 +f 868//868 596//596 225//225 +f 866//866 1586//1586 7//7 +f 1274//1274 1260//1260 1559//1559 +f 61//61 125//125 59//59 +f 574//574 156//156 155//155 +f 1410//1410 451//451 510//510 +f 1381//1381 831//831 1468//1468 +f 1483//1483 276//276 1587//1587 +f 158//158 178//178 180//180 +f 1588//1588 87//87 1311//1311 +f 1588//1588 88//88 87//87 +f 159//159 1585//1585 1589//1589 +f 1589//1589 1590//1590 165//165 +f 1568//1568 1569//1569 1572//1572 +f 1588//1588 690//690 102//102 +f 88//88 1588//1588 102//102 +f 690//690 689//689 102//102 +f 1591//1591 1323//1323 688//688 +f 1558//1558 49//49 48//48 +f 165//165 1590//1590 1571//1571 +f 689//689 691//691 98//98 +f 82//82 189//189 258//258 +f 88//88 103//103 1568//1568 +f 1592//1592 1593//1593 1594//1594 +f 459//459 128//128 1595//1595 +f 107//107 1264//1264 43//43 +f 882//882 37//37 1596//1596 +f 83//83 82//82 19//19 +f 1597//1597 1598//1598 1599//1599 +f 57//57 11//11 55//55 +f 1559//1559 830//830 1560//1560 +f 1600//1600 1601//1601 1602//1602 +f 1571//1571 1590//1590 1572//1572 +f 1556//1556 56//56 45//45 +f 56//56 1603//1603 45//45 +f 1603//1603 115//115 45//45 +f 1603//1603 44//44 115//115 +f 44//44 58//58 115//115 +f 824//824 1591//1591 1604//1604 +f 1605//1605 145//145 144//144 +f 1593//1593 1586//1586 1594//1594 +f 613//613 612//612 1059//1059 +f 12//12 1558//1558 48//48 +f 1606//1606 17//17 664//664 +f 457//457 1607//1607 1608//1608 +f 1310//1310 1588//1588 1311//1311 +f 1609//1609 1610//1610 1563//1563 +f 87//87 89//89 1595//1595 +f 1600//1600 1586//1586 1593//1593 +f 1611//1611 392//392 391//391 +f 48//48 1275//1275 1274//1274 +f 142//142 158//158 180//180 +f 1602//1602 1611//1611 1591//1591 +f 1612//1612 391//391 1198//1198 +f 1281//1281 999//999 1109//1109 +f 103//103 573//573 1569//1569 +f 459//459 1595//1595 1597//1597 +f 1609//1609 153//153 152//152 +f 829//829 649//649 947//947 +f 391//391 393//393 531//531 +f 531//531 1198//1198 391//391 +f 341//341 340//340 765//765 +f 1357//1357 656//656 322//322 +f 1572//1572 1613//1613 1248//1248 +f 574//574 155//155 219//219 +f 19//19 258//258 39//39 +f 391//391 1612//1612 1611//1611 +f 178//178 1614//1614 179//179 +f 1590//1590 1568//1568 1572//1572 +f 1244//1244 1228//1228 26//26 +f 1615//1615 830//830 1559//1559 +f 1569//1569 574//574 1613//1613 +f 1616//1616 1568//1568 1590//1590 +f 89//89 1598//1598 1595//1595 +f 1601//1601 1611//1611 1602//1602 +f 322//322 656//656 1358//1358 +f 1600//1600 1602//1602 361//361 +f 1561//1561 459//459 1617//1617 +f 1599//1599 1585//1585 179//179 +f 1600//1600 361//361 1586//1586 +f 180//180 143//143 142//142 +f 165//165 1571//1571 166//166 +f 933//933 1618//1618 658//658 +f 1598//1598 1616//1616 1585//1585 +f 44//44 59//59 58//58 +f 68//68 1360//1360 69//69 +f 361//361 1602//1602 460//460 +f 1594//1594 1586//1586 866//866 +f 491//491 1604//1604 688//688 +f 491//491 688//688 687//687 +f 103//103 102//102 109//109 +f 180//180 730//730 143//143 +f 159//159 165//165 21//21 +f 329//329 72//72 71//71 +f 167//167 1619//1619 125//125 +f 1620//1620 1597//1597 1599//1599 +f 1268//1268 1621//1621 235//235 +f 180//180 731//731 730//730 +f 1565//1565 392//392 1611//1611 +f 1601//1601 1565//1565 1611//1611 +f 69//69 1622//1622 419//419 +f 110//110 97//97 156//156 +f 615//615 562//562 666//666 +f 460//460 1602//1602 824//824 +f 1602//1602 1591//1591 824//824 +f 419//419 1443//1443 1201//1201 +f 1623//1623 219//219 220//220 +f 1620//1620 1599//1599 1624//1624 +f 1625//1625 1626//1626 1627//1627 +f 789//789 648//648 1341//1341 +f 1611//1611 1612//1612 1323//1323 +f 89//89 88//88 1568//1568 +f 1594//1594 866//866 1628//1628 +f 1428//1428 1601//1601 1629//1629 +f 89//89 1568//1568 1616//1616 +f 664//664 1212//1212 1630//1630 +f 104//104 322//322 68//68 +f 1591//1591 1611//1611 1323//1323 +f 227//227 1010//1010 299//299 +f 409//409 1631//1631 1151//1151 +f 1632//1632 1633//1633 1634//1634 +f 125//125 61//61 167//167 +f 1613//1613 574//574 1623//1623 +f 1623//1623 574//574 219//219 +f 258//258 108//108 65//65 +f 1565//1565 1331//1331 392//392 +f 564//564 45//45 47//47 +f 1289//1289 1159//1159 1068//1068 +f 108//108 866//866 7//7 +f 128//128 87//87 1595//1595 +f 1613//1613 1623//1623 1248//1248 +f 252//252 1635//1635 1180//1180 +f 814//814 1168//1168 816//816 +f 180//180 179//179 731//731 +f 1246//1246 826//826 1059//1059 +f 1614//1614 1599//1599 179//179 +f 1636//1636 1355//1355 1637//1637 +f 1515//1515 1635//1635 252//252 +f 500//500 1105//1105 441//441 +f 1180//1180 1635//1635 549//549 +f 549//549 1638//1638 408//408 +f 1591//1591 688//688 1604//1604 +f 1561//1561 124//124 459//459 +f 1639//1639 1263//1263 1461//1461 +f 1585//1585 1616//1616 1589//1589 +f 830//830 12//12 1560//1560 +f 1598//1598 89//89 1616//1616 +f 824//824 1604//1604 491//491 +f 1599//1599 1598//1598 1585//1585 +f 1310//1310 620//620 1588//1588 +f 1635//1635 1640//1640 549//549 +f 549//549 1640//1640 1638//1638 +f 1331//1331 676//676 392//392 +f 1589//1589 1616//1616 1590//1590 +f 852//852 1588//1588 620//620 +f 1588//1588 852//852 690//690 +f 1435//1435 734//734 735//735 +f 652//652 389//389 198//198 +f 1429//1429 1629//1629 1593//1593 +f 1629//1629 1600//1600 1593//1593 +f 103//103 109//109 573//573 +f 11//11 57//57 1558//1558 +f 154//154 153//153 10//10 +f 1572//1572 1569//1569 1613//1613 +f 320//320 319//319 576//576 +f 1631//1631 409//409 408//408 +f 214//214 1641//1641 1642//1642 +f 1593//1593 1592//1592 1429//1429 +f 1612//1612 1198//1198 1323//1323 +f 1198//1198 610//610 1323//1323 +f 109//109 110//110 573//573 +f 816//816 1320//1320 815//815 +f 1624//1624 1599//1599 1614//1614 +f 1643//1643 1624//1624 1614//1614 +f 1644//1644 1515//1515 770//770 +f 1645//1645 1151//1151 1631//1631 +f 1646//1646 1645//1645 1631//1631 +f 1647//1647 1535//1535 1648//1648 +f 221//221 117//117 119//119 +f 1649//1649 1650//1650 1651//1651 +f 38//38 761//761 1320//1320 +f 573//573 110//110 156//156 +f 1595//1595 1598//1598 1597//1597 +f 1635//1635 1652//1652 1640//1640 +f 1640//1640 1653//1653 1638//1638 +f 1638//1638 1653//1653 408//408 +f 1653//1653 1654//1654 408//408 +f 1654//1654 1631//1631 408//408 +f 1654//1654 1646//1646 1631//1631 +f 1482//1482 276//276 1483//1483 +f 816//816 1570//1570 1320//1320 +f 1629//1629 1601//1601 1600//1600 +f 1558//1558 57//57 49//49 +f 116//116 56//56 1556//1556 +f 1515//1515 1655//1655 1635//1635 +f 459//459 1597//1597 1617//1617 +f 1655//1655 1652//1652 1635//1635 +f 1652//1652 1656//1656 1640//1640 +f 1640//1640 1656//1656 1653//1653 +f 622//622 44//44 1603//1603 +f 1657//1657 1654//1654 1653//1653 +f 43//43 1264//1264 135//135 +f 1482//1482 1212//1212 276//276 +f 1658//1658 1659//1659 1655//1655 +f 1515//1515 1658//1658 1655//1655 +f 1655//1655 1656//1656 1652//1652 +f 1656//1656 1657//1657 1653//1653 +f 1644//1644 1658//1658 1515//1515 +f 107//107 43//43 55//55 +f 460//460 824//824 13//13 +f 492//492 491//491 687//687 +f 279//279 1660//1660 1395//1395 +f 1657//1657 1646//1646 1654//1654 +f 1428//1428 1629//1629 1429//1429 +f 1505//1505 530//530 393//393 +f 188//188 329//329 1628//1628 +f 1212//1212 1211//1211 276//276 +f 248//248 469//469 721//721 +f 152//152 1661//1661 1662//1662 +f 904//904 1435//1435 932//932 +f 1659//1659 1663//1663 1655//1655 +f 1655//1655 1663//1663 1656//1656 +f 1281//1281 1645//1645 1646//1646 +f 535//535 989//989 1239//1239 +f 159//159 1589//1589 165//165 +f 1664//1664 1646//1646 1657//1657 +f 1664//1664 1281//1281 1646//1646 +f 1564//1564 1665//1665 1331//1331 +f 220//220 195//195 357//357 +f 1666//1666 795//795 1346//1346 +f 1542//1542 1550//1550 1543//1543 +f 1667//1667 1281//1281 1664//1664 +f 866//866 188//188 1628//1628 +f 1643//1643 1614//1614 178//178 +f 1402//1402 831//831 1378//1378 +f 476//476 1668//1668 101//101 +f 1663//1663 1669//1669 1656//1656 +f 1656//1656 1670//1670 1657//1657 +f 1671//1671 1664//1664 1657//1657 +f 1667//1667 1672//1672 1281//1281 +f 1281//1281 1672//1672 1282//1282 +f 1618//1618 476//476 658//658 +f 1623//1623 220//220 357//357 +f 1658//1658 1673//1673 1659//1659 +f 1659//1659 1673//1673 1663//1663 +f 1673//1673 1674//1674 1663//1663 +f 1656//1656 1669//1669 1670//1670 +f 1670//1670 1671//1671 1657//1657 +f 735//735 99//99 1668//1668 +f 1564//1564 1601//1601 1428//1428 +f 355//355 354//354 946//946 +f 7//7 1586//1586 361//361 +f 476//476 1618//1618 1668//1668 +f 1248//1248 1623//1623 357//357 +f 622//622 1603//1603 56//56 +f 1663//1663 1674//1674 1669//1669 +f 1671//1671 1667//1667 1664//1664 +f 1672//1672 843//843 1282//1282 +f 1346//1346 794//794 78//78 +f 1618//1618 931//931 1668//1668 +f 153//153 1609//1609 1563//1563 +f 1476//1476 1648//1648 1477//1477 +f 44//44 61//61 59//59 +f 789//789 246//246 648//648 +f 617//617 616//616 311//311 +f 1670//1670 1675//1675 1671//1671 +f 93//93 6//6 134//134 +f 815//815 729//729 814//814 +f 153//153 1563//1563 10//10 +f 855//855 854//854 1402//1402 +f 210//210 222//222 1426//1426 +f 1674//1674 364//364 1669//1669 +f 1676//1676 1672//1672 1667//1667 +f 1672//1672 844//844 843//843 +f 1601//1601 1564//1564 1565//1565 +f 1570//1570 38//38 1320//1320 +f 687//687 630//630 640//640 +f 364//364 363//363 1669//1669 +f 1669//1669 363//363 1670//1670 +f 1670//1670 363//363 1675//1675 +f 1671//1671 1676//1676 1667//1667 +f 931//931 1435//1435 735//735 +f 1668//1668 931//931 735//735 +f 1113//1113 1124//1124 1146//1146 +f 1673//1673 1677//1677 1674//1674 +f 1675//1675 1676//1676 1671//1671 +f 891//891 1672//1672 1676//1676 +f 1672//1672 771//771 844//844 +f 844//844 771//771 772//772 +f 25//25 1244//1244 26//26 +f 47//47 192//192 1379//1379 +f 146//146 145//145 191//191 +f 927//927 1475//1475 841//841 +f 1678//1678 1092//1092 1070//1070 +f 363//363 805//805 1675//1675 +f 1672//1672 891//891 771//771 +f 932//932 822//822 821//821 +f 38//38 1577//1577 761//761 +f 1677//1677 364//364 1674//1674 +f 1675//1675 907//907 1676//1676 +f 907//907 891//891 1676//1676 +f 688//688 610//610 630//630 +f 931//931 932//932 1435//1435 +f 1661//1661 152//152 830//830 +f 866//866 189//189 188//188 +f 891//891 804//804 771//771 +f 247//247 473//473 597//597 +f 410//410 548//548 408//408 +f 1563//1563 1461//1461 1460//1460 +f 1//1 906//906 1679//1679 +f 805//805 907//907 1675//1675 +f 392//392 1505//1505 393//393 +f 57//57 55//55 54//54 +f 607//607 651//651 693//693 +f 1680//1680 1681//1681 1382//1382 +f 1403//1403 30//30 187//187 +f 390//390 1682//1682 997//997 +f 212//212 1//1 1679//1679 +f 853//853 364//364 1677//1677 +f 35//35 34//34 1038//1038 +f 806//806 1683//1683 828//828 +f 1322//1322 213//213 215//215 +f 1348//1348 1625//1625 1684//1684 +f 15//15 17//17 1625//1625 +f 1685//1685 1461//1461 1563//1563 +f 1416//1416 1686//1686 1687//1687 +f 17//17 1606//1606 1625//1625 +f 1348//1348 15//15 1625//1625 +f 592//592 593//593 1128//1128 +f 1688//1688 932//932 821//821 +f 1689//1689 714//714 1690//1690 +f 1691//1691 777//777 1692//1692 +f 768//768 739//739 1692//1692 +f 1693//1693 346//346 260//260 +f 1377//1377 1337//1337 303//303 +f 917//917 820//820 822//822 +f 1143//1143 1694//1694 1695//1695 +f 1224//1224 1696//1696 1268//1268 +f 890//890 904//904 1697//1697 +f 1175//1175 16//16 15//15 +f 900//900 929//929 921//921 +f 1698//1698 1699//1699 762//762 +f 1700//1700 797//797 754//754 +f 1701//1701 1231//1231 1232//1232 +f 762//762 753//753 746//746 +f 780//780 1702//1702 752//752 +f 1325//1325 135//135 1263//1263 +f 792//792 1703//1703 1702//1702 +f 1704//1704 457//457 1608//1608 +f 135//135 1264//1264 1263//1263 +f 446//446 445//445 1526//1526 +f 535//535 817//817 169//169 +f 1619//1619 167//167 1324//1324 +f 1700//1700 1705//1705 797//797 +f 480//480 175//175 1706//1706 +f 214//214 1497//1497 1681//1681 +f 615//615 926//926 658//658 +f 1707//1707 1708//1708 1709//1709 +f 216//216 62//62 1710//1710 +f 596//596 473//473 225//225 +f 590//590 458//458 457//457 +f 1711//1711 875//875 890//890 +f 287//287 1712//1712 261//261 +f 898//898 887//887 1713//1713 +f 493//493 177//177 788//788 +f 1196//1196 1132//1132 23//23 +f 1690//1690 714//714 1714//1714 +f 1217//1217 1216//1216 1715//1715 +f 1704//1704 590//590 457//457 +f 135//135 1325//1325 1324//1324 +f 1716//1716 1705//1705 1700//1700 +f 1702//1702 1703//1703 1698//1698 +f 1717//1717 939//939 882//882 +f 1718//1718 1699//1699 1698//1698 +f 1697//1697 1683//1683 1711//1711 +f 678//678 1459//1459 632//632 +f 1619//1619 1326//1326 1719//1719 +f 1720//1720 1619//1619 1719//1719 +f 149//149 151//151 1721//1721 +f 1722//1722 1714//1714 698//698 +f 1718//1718 883//883 870//870 +f 762//762 1723//1723 763//763 +f 1724//1724 1725//1725 1726//1726 +f 235//235 1224//1224 1268//1268 +f 1702//1702 1698//1698 762//762 +f 1727//1727 1728//1728 1729//1729 +f 1694//1694 1730//1730 1731//1731 +f 790//790 839//839 791//791 +f 1702//1702 780//780 792//792 +f 534//534 533//533 898//898 +f 1683//1683 876//876 828//828 +f 1348//1348 1175//1175 15//15 +f 1416//1416 832//832 1732//1732 +f 1416//1416 1732//1732 1686//1686 +f 1733//1733 1687//1687 1686//1686 +f 1732//1732 1733//1733 1686//1686 +f 1226//1226 169//169 1734//1734 +f 1347//1347 1175//1175 1348//1348 +f 1716//1716 875//875 1711//1711 +f 1704//1704 1735//1735 1402//1402 +f 898//898 533//533 900//900 +f 38//38 939//939 694//694 +f 898//898 900//900 887//887 +f 963//963 659//659 1129//1129 +f 648//648 776//776 1341//1341 +f 1688//1688 821//821 876//876 +f 1690//1690 1736//1736 1689//1689 +f 232//232 1260//1260 1274//1274 +f 1688//1688 876//876 1683//1683 +f 591//591 1704//1704 1402//1402 +f 1711//1711 1683//1683 1705//1705 +f 870//870 869//869 1699//1699 +f 1464//1464 1499//1499 1437//1437 +f 876//876 846//846 828//828 +f 597//597 245//245 247//247 +f 1683//1683 797//797 1705//1705 +f 1094//1094 490//490 1347//1347 +f 634//634 812//812 635//635 +f 1607//1607 1737//1737 1732//1732 +f 1626//1626 1630//1630 1627//1627 +f 1347//1347 490//490 1175//1175 +f 1699//1699 869//869 1723//1723 +f 869//869 875//875 1716//1716 +f 887//887 1718//1718 1738//1738 +f 714//714 669//669 698//698 +f 950//950 1299//1299 1261//1261 +f 832//832 1608//1608 1732//1732 +f 127//127 1720//1720 1739//1739 +f 347//347 346//346 368//368 +f 1740//1740 164//164 1741//1741 +f 1741//1741 163//163 155//155 +f 366//366 368//368 367//367 +f 1160//1160 569//569 1161//1161 +f 127//127 125//125 1619//1619 +f 1658//1658 1742//1742 1673//1673 +f 1326//1326 1619//1619 1324//1324 +f 1691//1691 715//715 714//714 +f 1743//1743 1744//1744 1745//1745 +f 869//869 871//871 875//875 +f 809//809 839//839 790//790 +f 262//262 261//261 1712//1712 +f 665//665 17//17 928//928 +f 794//794 793//793 745//745 +f 1690//1690 1714//1714 1722//1722 +f 1729//1729 1728//1728 1725//1725 +f 1630//1630 1746//1746 1627//1627 +f 865//865 886//886 839//839 +f 456//456 458//458 645//645 +f 1747//1747 1743//1743 1745//1745 +f 762//762 1699//1699 1723//1723 +f 1748//1748 149//149 1721//1721 +f 1748//1748 1749//1749 1744//1744 +f 928//928 854//854 665//665 +f 887//887 1738//1738 1713//1713 +f 1227//1227 1226//1226 962//962 +f 1543//1543 1750//1750 1475//1475 +f 1445//1445 1751//1751 1752//1752 +f 898//898 1713//1713 886//886 +f 1226//1226 1722//1722 962//962 +f 578//578 1753//1753 1754//1754 +f 1621//1621 1268//1268 1270//1270 +f 424//424 1755//1755 1756//1756 +f 367//367 368//368 1757//1757 +f 1747//1747 1745//1745 1758//1758 +f 887//887 883//883 1718//1718 +f 1721//1721 1759//1759 1749//1749 +f 1748//1748 1721//1721 1749//1749 +f 1693//1693 262//262 1760//1760 +f 1045//1045 1567//1567 749//749 +f 1703//1703 1738//1738 1718//1718 +f 168//168 778//778 1690//1690 +f 1761//1761 1762//1762 1763//1763 +f 367//367 1757//1757 1751//1751 +f 1760//1760 1764//1764 1757//1757 +f 1758//1758 1745//1745 1765//1765 +f 1743//1743 1747//1747 1766//1766 +f 161//161 1744//1744 1743//1743 +f 456//456 1607//1607 457//457 +f 1767//1767 437//437 1258//1258 +f 1147//1147 1768//1768 1140//1140 +f 1769//1769 1770//1770 64//64 +f 579//579 578//578 1754//1754 +f 1771//1771 1772//1772 578//578 +f 1703//1703 1718//1718 1698//1698 +f 1773//1773 1774//1774 1775//1775 +f 1721//1721 1740//1740 1776//1776 +f 1746//1746 1482//1482 1481//1481 +f 1777//1777 1778//1778 1779//1779 +f 1780//1780 1746//1746 1481//1481 +f 1767//1767 1258//1258 344//344 +f 1297//1297 1296//1296 1334//1334 +f 1781//1781 198//198 390//390 +f 1782//1782 1774//1774 906//906 +f 1783//1783 1771//1771 578//578 +f 1327//1327 1115//1115 1098//1098 +f 367//367 1751//1751 1445//1445 +f 1744//1744 1749//1749 1745//1745 +f 368//368 1693//1693 1760//1760 +f 509//509 928//928 17//17 +f 1697//1697 904//904 932//932 +f 1784//1784 1771//1771 1783//1783 +f 1784//1784 1785//1785 1771//1771 +f 1785//1785 1772//1772 1771//1771 +f 962//962 698//698 659//659 +f 1765//1765 1745//1745 1786//1786 +f 1785//1785 1648//1648 1476//1476 +f 214//214 1642//1642 1497//1497 +f 1126//1126 634//634 633//633 +f 926//926 615//615 666//666 +f 161//161 1743//1743 1491//1491 +f 1787//1787 1680//1680 1788//1788 +f 1749//1749 1759//1759 1786//1786 +f 1721//1721 1776//1776 1759//1759 +f 1065//1065 1102//1102 1177//1177 +f 1636//1636 1637//1637 1286//1286 +f 1725//1725 1728//1728 1789//1789 +f 870//870 1699//1699 1718//1718 +f 763//763 1700//1700 753//753 +f 1790//1790 1627//1627 1746//1746 +f 1791//1791 262//262 1712//1712 +f 1792//1792 1684//1684 1790//1790 +f 1689//1689 777//777 1691//1691 +f 1784//1784 1647//1647 1785//1785 +f 1647//1647 1648//1648 1785//1785 +f 149//149 1748//1748 1744//1744 +f 1793//1793 1794//1794 1287//1287 +f 1287//1287 1794//1794 1285//1285 +f 1795//1795 1286//1286 1285//1285 +f 1795//1795 1636//1636 1286//1286 +f 1689//1689 1736//1736 777//777 +f 752//752 1702//1702 746//746 +f 1721//1721 164//164 1740//1740 +f 208//208 207//207 856//856 +f 1745//1745 1749//1749 1786//1786 +f 1336//1336 1514//1514 603//603 +f 777//777 809//809 1692//1692 +f 1783//1783 1796//1796 1784//1784 +f 1796//1796 1647//1647 1784//1784 +f 698//698 1714//1714 714//714 +f 168//168 779//779 778//778 +f 1624//1624 1643//1643 1797//1797 +f 346//346 1693//1693 368//368 +f 1720//1720 127//127 1619//1619 +f 1630//1630 1482//1482 1746//1746 +f 1798//1798 1796//1796 1783//1783 +f 1734//1734 1690//1690 1226//1226 +f 164//164 163//163 1741//1741 +f 778//778 1736//1736 1690//1690 +f 1317//1317 1374//1374 679//679 +f 1794//1794 1795//1795 1285//1285 +f 840//840 1474//1474 927//927 +f 1625//1625 1606//1606 1626//1626 +f 1735//1735 1704//1704 1608//1608 +f 1737//1737 1733//1733 1732//1732 +f 262//262 1791//1791 1760//1760 +f 1702//1702 762//762 746//746 +f 754//754 753//753 1700//1700 +f 1322//1322 1787//1787 1788//1788 +f 1400//1400 1799//1799 1793//1793 +f 1799//1799 1794//1794 1793//1793 +f 1800//1800 1636//1636 1795//1795 +f 1801//1801 426//426 428//428 +f 790//790 791//791 767//767 +f 1712//1712 287//287 1802//1802 +f 1803//1803 1647//1647 1796//1796 +f 1734//1734 169//169 168//168 +f 1794//1794 1804//1804 1795//1795 +f 1800//1800 1355//1355 1636//1636 +f 1716//1716 1700//1700 763//763 +f 962//962 963//963 1520//1520 +f 167//167 135//135 1324//1324 +f 1492//1492 161//161 1491//1491 +f 168//168 1690//1690 1734//1734 +f 1224//1224 1805//1805 1696//1696 +f 122//122 1649//1649 1777//1777 +f 1764//1764 1760//1760 1791//1791 +f 168//168 170//170 779//779 +f 839//839 886//886 1713//1713 +f 680//680 325//325 633//633 +f 1806//1806 1332//1332 1807//1807 +f 1791//1791 1712//1712 1808//1808 +f 1808//1808 1712//1712 1802//1802 +f 1535//1535 1647//1647 1803//1803 +f 1723//1723 1716//1716 763//763 +f 1533//1533 1532//1532 1809//1809 +f 1296//1296 1031//1031 217//217 +f 1224//1224 235//235 244//244 +f 1799//1799 1400//1400 1547//1547 +f 1799//1799 1764//1764 1794//1794 +f 1794//1794 1764//1764 1804//1804 +f 839//839 1713//1713 791//791 +f 1176//1176 530//530 1545//1545 +f 1810//1810 1032//1032 1031//1031 +f 1677//1677 1673//1673 1811//1811 +f 1697//1697 1688//1688 1683//1683 +f 1812//1812 96//96 1514//1514 +f 1813//1813 1803//1803 1798//1798 +f 1263//1263 1326//1326 1325//1325 +f 1477//1477 1467//1467 1478//1478 +f 1547//1547 1814//1814 1799//1799 +f 1804//1804 1808//1808 1795//1795 +f 1808//1808 1800//1800 1795//1795 +f 1808//1808 1815//1815 1800//1800 +f 869//869 1716//1716 1723//1723 +f 792//792 1738//1738 1703//1703 +f 1689//1689 1691//1691 714//714 +f 62//62 64//64 1448//1448 +f 1816//1816 1265//1265 827//827 +f 147//147 149//149 1744//1744 +f 198//198 1781//1781 1817//1817 +f 1818//1818 1740//1740 1741//1741 +f 1776//1776 1740//1740 1818//1818 +f 1335//1335 1514//1514 1336//1336 +f 1335//1335 1812//1812 1514//1514 +f 97//97 96//96 1812//1812 +f 1342//1342 1341//1341 776//776 +f 1813//1813 1819//1819 1803//1803 +f 1803//1803 1819//1819 1535//1535 +f 1466//1466 1467//1467 1477//1477 +f 1716//1716 1711//1711 1705//1705 +f 451//451 453//453 462//462 +f 1814//1814 1820//1820 1799//1799 +f 1820//1820 1764//1764 1799//1799 +f 1815//1815 1821//1821 1800//1800 +f 196//196 198//198 1817//1817 +f 1802//1802 1822//1822 1821//1821 +f 110//110 98//98 97//97 +f 1823//1823 1824//1824 1825//1825 +f 1826//1826 1827//1827 1828//1828 +f 1625//1625 1627//1627 1790//1790 +f 1713//1713 1738//1738 792//792 +f 368//368 1760//1760 1757//1757 +f 1711//1711 890//890 1697//1697 +f 1547//1547 1829//1829 1814//1814 +f 1830//1830 1831//1831 1554//1554 +f 216//216 63//63 62//62 +f 1406//1406 1408//1408 1832//1832 +f 962//962 1722//1722 698//698 +f 1833//1833 1376//1376 793//793 +f 1032//1032 1834//1834 1678//1678 +f 791//791 1713//1713 792//792 +f 1239//1239 817//817 535//535 +f 178//178 1835//1835 1643//1643 +f 778//778 777//777 1736//1736 +f 1817//1817 1478//1478 1467//1467 +f 1781//1781 997//997 1478//1478 +f 1817//1817 1781//1781 1478//1478 +f 390//390 997//997 1781//1781 +f 1836//1836 1837//1837 1838//1838 +f 1764//1764 1791//1791 1804//1804 +f 1804//1804 1791//1791 1808//1808 +f 394//394 1773//1773 1839//1839 +f 233//233 1319//1319 407//407 +f 1833//1833 1377//1377 1376//1376 +f 1840//1840 1841//1841 1471//1471 +f 1776//1776 1335//1335 1337//1337 +f 1818//1818 1812//1812 1335//1335 +f 1476//1476 1772//1772 1785//1785 +f 879//879 1424//1424 1423//1423 +f 1813//1813 278//278 1819//1819 +f 278//278 1535//1535 1819//1819 +f 1763//1763 1762//1762 1842//1842 +f 1752//1752 1751//1751 1814//1814 +f 1814//1814 1751//1751 1820//1820 +f 795//795 1765//1765 793//793 +f 793//793 1765//1765 1833//1833 +f 1776//1776 1337//1337 1377//1377 +f 1818//1818 1335//1335 1776//1776 +f 1812//1812 1741//1741 97//97 +f 1697//1697 932//932 1688//1688 +f 1692//1692 809//809 768//768 +f 715//715 1692//1692 739//739 +f 178//178 939//939 1835//1835 +f 797//797 1683//1683 806//806 +f 1843//1843 200//200 1491//1491 +f 768//768 809//809 790//790 +f 29//29 311//311 310//310 +f 196//196 1817//1817 1467//1467 +f 1721//1721 151//151 164//164 +f 1844//1844 786//786 785//785 +f 1808//1808 1802//1802 1815//1815 +f 1815//1815 1802//1802 1821//1821 +f 1845//1845 1765//1765 795//795 +f 1786//1786 1377//1377 1833//1833 +f 1741//1741 1812//1812 1818//1818 +f 27//27 29//29 310//310 +f 147//147 1744//1744 161//161 +f 178//178 158//158 939//939 +f 1109//1109 1151//1151 1645//1645 +f 1280//1280 1032//1032 1071//1071 +f 1787//1787 1681//1681 1680//1680 +f 216//216 1557//1557 217//217 +f 1846//1846 1836//1836 1633//1633 +f 1751//1751 1757//1757 1820//1820 +f 1820//1820 1757//1757 1764//1764 +f 1458//1458 1847//1847 1276//1276 +f 806//806 828//828 781//781 +f 1226//1226 1690//1690 1722//1722 +f 1587//1587 276//276 278//278 +f 38//38 882//882 939//939 +f 97//97 1741//1741 155//155 +f 1765//1765 1786//1786 1833//1833 +f 1786//1786 1759//1759 1377//1377 +f 1759//1759 1776//1776 1377//1377 +f 1258//1258 1848//1848 231//231 +f 1849//1849 1850//1850 1851//1851 +f 1852//1852 1853//1853 1854//1854 +f 1260//1260 1259//1259 1855//1855 +f 1856//1856 1857//1857 1858//1858 +f 95//95 307//307 1430//1430 +f 120//120 1859//1859 1431//1431 +f 1860//1860 1861//1861 1862//1862 +f 200//200 229//229 218//218 +f 1253//1253 1125//1125 1863//1863 +f 123//123 1864//1864 1386//1386 +f 1865//1865 1866//1866 1778//1778 +f 929//929 900//900 533//533 +f 831//831 1735//1735 832//832 +f 438//438 1867//1867 436//436 +f 1868//1868 463//463 462//462 +f 152//152 1662//1662 1869//1869 +f 436//436 1870//1870 1869//1869 +f 1184//1184 1871//1871 1872//1872 +f 423//423 425//425 750//750 +f 436//436 1867//1867 1870//1870 +f 1610//1610 1609//1609 1869//1869 +f 1873//1873 1874//1874 478//478 +f 1870//1870 1875//1875 1869//1869 +f 1873//1873 1876//1876 438//438 +f 1874//1874 1873//1873 438//438 +f 438//438 1876//1876 1867//1867 +f 1877//1877 1610//1610 1869//1869 +f 1875//1875 1877//1877 1869//1869 +f 1867//1867 1878//1878 1870//1870 +f 1870//1870 1878//1878 1875//1875 +f 745//745 1376//1376 302//302 +f 1879//1879 1873//1873 1880//1880 +f 1877//1877 1685//1685 1610//1610 +f 1563//1563 1610//1610 1685//1685 +f 1873//1873 1879//1879 1876//1876 +f 1876//1876 1881//1881 1867//1867 +f 1867//1867 1881//1881 1878//1878 +f 86//86 1882//1882 84//84 +f 1875//1875 1883//1883 1877//1877 +f 1877//1877 1883//1883 1685//1685 +f 1883//1883 1884//1884 1685//1685 +f 1879//1879 1885//1885 1876//1876 +f 1878//1878 1883//1883 1875//1875 +f 303//303 1439//1439 1362//1362 +f 1879//1879 1880//1880 744//744 +f 1886//1886 1884//1884 1883//1883 +f 1878//1878 1886//1886 1883//1883 +f 1793//1793 1287//1287 1339//1339 +f 1525//1525 1879//1879 744//744 +f 1885//1885 1887//1887 1876//1876 +f 1876//1876 1887//1887 1881//1881 +f 1382//1382 1681//1681 842//842 +f 1881//1881 1886//1886 1878//1878 +f 1888//1888 1860//1860 1862//1862 +f 1626//1626 1606//1606 664//664 +f 743//743 1526//1526 744//744 +f 1639//1639 1461//1461 1884//1884 +f 1886//1886 1639//1639 1884//1884 +f 996//996 1478//1478 997//997 +f 1889//1889 1890//1890 1860//1860 +f 1891//1891 1868//1868 1892//1892 +f 1202//1202 605//605 1479//1479 +f 1893//1893 1526//1526 743//743 +f 1894//1894 1879//1879 1525//1525 +f 1894//1894 1885//1885 1879//1879 +f 1895//1895 1896//1896 1897//1897 +f 1898//1898 1899//1899 1900//1900 +f 1526//1526 1525//1525 744//744 +f 1901//1901 1902//1902 1903//1903 +f 1854//1854 1853//1853 1904//1904 +f 1905//1905 1832//1832 1408//1408 +f 1906//1906 1907//1907 1838//1838 +f 1907//1907 1908//1908 1836//1836 +f 1908//1908 1909//1909 1836//1836 +f 1909//1909 1634//1634 1836//1836 +f 445//445 1894//1894 1525//1525 +f 1886//1886 1910//1910 1639//1639 +f 1440//1440 1911//1911 1912//1912 +f 1906//1906 1913//1913 1907//1907 +f 1907//1907 1914//1914 1908//1908 +f 1915//1915 1632//1632 1916//1916 +f 1917//1917 1634//1634 1909//1909 +f 1918//1918 1886//1886 1881//1881 +f 1887//1887 1918//1918 1881//1881 +f 1910//1910 1263//1263 1639//1639 +f 1890//1890 1919//1919 1861//1861 +f 1920//1920 1921//1921 1922//1922 +f 1316//1316 613//613 1059//1059 +f 1923//1923 1914//1914 1907//1907 +f 1913//1913 1923//1923 1907//1907 +f 1914//1914 1924//1924 1908//1908 +f 1924//1924 1925//1925 1909//1909 +f 1908//1908 1924//1924 1909//1909 +f 1710//1710 1916//1916 1634//1634 +f 1917//1917 1710//1710 1634//1634 +f 1910//1910 1926//1926 1263//1263 +f 1920//1920 121//121 1921//1921 +f 1888//1888 784//784 1432//1432 +f 1871//1871 1927//1927 1906//1906 +f 1924//1924 1928//1928 1925//1925 +f 1925//1925 1917//1917 1909//1909 +f 816//816 1168//1168 1265//1265 +f 1918//1918 1910//1910 1886//1886 +f 664//664 665//665 855//855 +f 77//77 1605//1605 1197//1197 +f 1921//1921 121//121 1386//1386 +f 1860//1860 1890//1890 1861//1861 +f 1927//1927 1923//1923 1906//1906 +f 1906//1906 1923//1923 1913//1913 +f 1710//1710 1917//1917 1925//1925 +f 1287//1287 1286//1286 31//31 +f 1929//1929 1918//1918 1887//1887 +f 1885//1885 1929//1929 1887//1887 +f 1888//1888 1862//1862 784//784 +f 1184//1184 1930//1930 1927//1927 +f 1871//1871 1184//1184 1927//1927 +f 1923//1923 1931//1931 1914//1914 +f 1710//1710 1450//1450 1916//1916 +f 1918//1918 1932//1932 1910//1910 +f 1910//1910 1932//1932 1926//1926 +f 1468//1468 831//831 833//833 +f 1630//1630 1212//1212 1482//1482 +f 1362//1362 1438//1438 419//419 +f 99//99 101//101 1668//1668 +f 288//288 1291//1291 287//287 +f 1921//1921 1385//1385 1933//1933 +f 1934//1934 1930//1930 1184//1184 +f 1927//1927 1935//1935 1923//1923 +f 1914//1914 1931//1931 1924//1924 +f 1894//1894 1929//1929 1885//1885 +f 1793//1793 1339//1339 1400//1400 +f 857//857 876//876 821//821 +f 1936//1936 1523//1523 1937//1937 +f 1936//1936 859//859 1938//1938 +f 1936//1936 1939//1939 859//859 +f 1939//1939 1940//1940 859//859 +f 1800//1800 1821//1821 1356//1356 +f 1934//1934 1941//1941 1930//1930 +f 1927//1927 1930//1930 1935//1935 +f 1928//1928 1557//1557 1925//1925 +f 216//216 1710//1710 1925//1925 +f 1557//1557 216//216 1925//1925 +f 1355//1355 1800//1800 1356//1356 +f 1821//1821 1942//1942 1356//1356 +f 1926//1926 1326//1326 1263//1263 +f 1942//1942 1350//1350 1356//1356 +f 1935//1935 1931//1931 1923//1923 +f 1931//1931 1750//1750 1924//1924 +f 1924//1924 1543//1543 1928//1928 +f 1543//1543 1557//1557 1928//1928 +f 1943//1943 1944//1944 1596//1596 +f 1918//1918 1945//1945 1932//1932 +f 1932//1932 1326//1326 1926//1926 +f 1946//1946 858//858 860//860 +f 1184//1184 1183//1183 1934//1934 +f 1924//1924 1750//1750 1543//1543 +f 1379//1379 472//472 471//471 +f 1469//1469 1947//1947 1494//1494 +f 1948//1948 1949//1949 1950//1950 +f 446//446 1951//1951 444//444 +f 444//444 1951//1951 445//445 +f 1859//1859 1952//1952 1953//1953 +f 1824//1824 1857//1857 1856//1856 +f 1954//1954 1939//1939 1936//1936 +f 1954//1954 529//529 1939//1939 +f 1882//1882 1183//1183 1955//1955 +f 1934//1934 1183//1183 1941//1941 +f 1941//1941 1935//1935 1930//1930 +f 1931//1931 1956//1956 1750//1750 +f 1957//1957 1288//1288 1304//1304 +f 79//79 145//145 1605//1605 +f 79//79 1357//1357 145//145 +f 1161//1161 1958//1958 446//446 +f 446//446 1958//1958 1951//1951 +f 1951//1951 1959//1959 445//445 +f 1959//1959 1894//1894 445//445 +f 1894//1894 1960//1960 1929//1929 +f 1937//1937 1954//1954 1936//1936 +f 1935//1935 1956//1956 1931//1931 +f 1961//1961 1894//1894 1959//1959 +f 1961//1961 1960//1960 1894//1894 +f 1929//1929 1945//1945 1918//1918 +f 1962//1962 1963//1963 1964//1964 +f 1648//1648 1466//1466 1477//1477 +f 1937//1937 1965//1965 1954//1954 +f 1469//1469 1262//1262 1966//1966 +f 84//84 1882//1882 1955//1955 +f 1935//1935 1096//1096 1956//1956 +f 1750//1750 1956//1956 1475//1475 +f 77//77 79//79 1605//1605 +f 1960//1960 1945//1945 1929//1929 +f 1945//1945 1967//1967 1932//1932 +f 1968//1968 1447//1447 1964//1964 +f 1269//1269 1968//1968 1964//1964 +f 1969//1969 529//529 1954//1954 +f 1970//1970 1183//1183 1882//1882 +f 1183//1183 1971//1971 1941//1941 +f 51//51 1972//1972 510//510 +f 405//405 678//678 632//632 +f 1211//1211 1402//1402 1378//1378 +f 831//831 1402//1402 1735//1735 +f 1973//1973 1719//1719 1932//1932 +f 1967//1967 1973//1973 1932//1932 +f 1932//1932 1719//1719 1326//1326 +f 1969//1969 1954//1954 1965//1965 +f 1969//1969 527//527 529//529 +f 1183//1183 1970//1970 1971//1971 +f 1096//1096 841//841 1956//1956 +f 1960//1960 1967//1967 1945//1945 +f 656//656 302//302 304//304 +f 1971//1971 1382//1382 1941//1941 +f 1941//1941 1382//1382 1935//1935 +f 1935//1935 1382//1382 1096//1096 +f 1974//1974 1975//1975 1866//1866 +f 64//64 1280//1280 1976//1976 +f 304//304 1362//1362 1622//1622 +f 1622//1622 1362//1362 419//419 +f 1358//1358 656//656 1360//1360 +f 1958//1958 1977//1977 1951//1951 +f 1608//1608 832//832 1735//1735 +f 855//855 1402//1402 1211//1211 +f 1978//1978 1969//1969 1965//1965 +f 1970//1970 1979//1979 1971//1971 +f 1980//1980 1981//1981 1982//1982 +f 1521//1521 1139//1139 1983//1983 +f 1626//1626 664//664 1630//1630 +f 1984//1984 1985//1985 1986//1986 +f 1942//1942 1987//1987 1350//1350 +f 1988//1988 1959//1959 1951//1951 +f 1959//1959 1988//1988 1961//1961 +f 578//578 1772//1772 1753//1753 +f 78//78 302//302 656//656 +f 1197//1197 1605//1605 144//144 +f 983//983 1989//1989 1965//1965 +f 1989//1989 1978//1978 1965//1965 +f 1978//1978 527//527 1969//1969 +f 852//852 851//851 691//691 +f 1990//1990 1970//1970 1882//1882 +f 1990//1990 1979//1979 1970//1970 +f 1991//1991 1922//1922 1921//1921 +f 1992//1992 205//205 1993//1993 +f 1378//1378 1381//1381 1502//1502 +f 1502//1502 1468//1468 197//197 +f 1502//1502 197//197 1503//1503 +f 1378//1378 1502//1502 277//277 +f 1378//1378 277//277 276//276 +f 1988//1988 1967//1967 1960//1960 +f 1961//1961 1988//1988 1960//1960 +f 1821//1821 1822//1822 1942//1942 +f 14//14 13//13 492//492 +f 603//603 851//851 850//850 +f 1269//1269 1582//1582 1968//1968 +f 1979//1979 1382//1382 1971//1971 +f 1981//1981 1994//1994 1995//1995 +f 1573//1573 1254//1254 1580//1580 +f 1982//1982 1981//1981 1850//1850 +f 832//832 1416//1416 833//833 +f 852//852 620//620 619//619 +f 510//510 462//462 461//461 +f 1988//1988 1996//1996 1967//1967 +f 1967//1967 1996//1996 1973//1973 +f 79//79 656//656 1357//1357 +f 605//605 1201//1201 603//603 +f 86//86 1990//1990 1882//1882 +f 1788//1788 1680//1680 1990//1990 +f 1979//1979 1680//1680 1382//1382 +f 1995//1995 1865//1865 1850//1850 +f 1997//1997 1998//1998 1999//1999 +f 2000//2000 1520//1520 1369//1369 +f 1449//1449 1506//1506 2001//2001 +f 850//850 619//619 604//604 +f 2//2 211//211 421//421 +f 1235//1235 1977//1977 1321//1321 +f 1360//1360 304//304 69//69 +f 1139//1139 1520//1520 963//963 +f 2002//2002 1570//1570 1968//1968 +f 1234//1234 1978//1978 1989//1989 +f 1978//1978 1359//1359 527//527 +f 1417//1417 1426//1426 222//222 +f 69//69 304//304 1622//1622 +f 2003//2003 1952//1952 1859//1859 +f 2004//2004 2005//2005 2006//2006 +f 70//70 171//171 105//105 +f 1977//1977 2007//2007 1951//1951 +f 1719//1719 1973//1973 1996//1996 +f 1292//1292 1018//1018 1229//1229 +f 1438//1438 1443//1443 419//419 +f 420//420 1201//1201 1202//1202 +f 267//267 357//357 195//195 +f 1466//1466 1648//1648 1535//1535 +f 607//607 939//939 158//158 +f 1245//1245 614//614 1962//1962 +f 2008//2008 2009//2009 2010//2010 +f 2010//2010 2009//2009 2011//2011 +f 1104//1104 344//344 343//343 +f 2012//2012 1896//1896 1895//1895 +f 1562//1562 1977//1977 1235//1235 +f 1996//1996 2013//2013 1719//1719 +f 1312//1312 620//620 1310//1310 +f 1692//1692 715//715 1691//1691 +f 1362//1362 1439//1439 1438//1438 +f 331//331 2003//2003 1859//1859 +f 1998//1998 2014//2014 2008//2008 +f 2011//2011 2015//2015 1216//1216 +f 1994//1994 1488//1488 1974//1974 +f 330//330 30//30 32//32 +f 1951//1951 2016//2016 1988//1988 +f 1988//1988 2016//2016 1996//1996 +f 30//30 1287//1287 31//31 +f 144//144 146//146 160//160 +f 1852//1852 2017//2017 1853//1853 +f 2018//2018 2009//2009 2008//2008 +f 2015//2015 1453//1453 1216//1216 +f 1594//1594 2019//2019 2020//2020 +f 1375//1375 191//191 105//105 +f 934//934 1355//1355 1351//1351 +f 1562//1562 2007//2007 1977//1977 +f 2016//2016 1951//1951 2007//2007 +f 2016//2016 2013//2013 1996//1996 +f 2002//2002 36//36 1570//1570 +f 1596//1596 1582//1582 1696//1696 +f 37//37 2002//2002 1582//1582 +f 2021//2021 1831//1831 2022//2022 +f 81//81 187//187 1228//1228 +f 1286//1286 1340//1340 133//133 +f 1953//1953 1952//1952 1860//1860 +f 2023//2023 2024//2024 2025//2025 +f 1966//1966 2021//2021 2026//2026 +f 2027//2027 2011//2011 2009//2009 +f 2028//2028 1849//1849 1889//1889 +f 1562//1562 2029//2029 2007//2007 +f 1340//1340 1286//1286 934//934 +f 37//37 1582//1582 1596//1596 +f 2013//2013 1720//1720 1719//1719 +f 1637//1637 1355//1355 934//934 +f 1414//1414 1440//1440 1866//1866 +f 2030//2030 2031//2031 2025//2025 +f 2012//2012 1584//1584 1896//1896 +f 2014//2014 2018//2018 2008//2008 +f 2015//2015 2011//2011 2027//2027 +f 1863//1863 1510//1510 2032//2032 +f 1707//1707 1709//1709 2033//2033 +f 205//205 2034//2034 206//206 +f 2016//2016 2035//2035 2013//2013 +f 1286//1286 1637//1637 934//934 +f 138//138 160//160 1364//1364 +f 1507//1507 1387//1387 1538//1538 +f 338//338 1230//1230 1136//1136 +f 2012//2012 2036//2036 2037//2037 +f 2038//2038 2018//2018 2014//2014 +f 2018//2018 2039//2039 2009//2009 +f 2009//2009 2039//2039 2027//2027 +f 2040//2040 1707//1707 2033//2033 +f 2041//2041 2036//2036 2042//2042 +f 2043//2043 1904//1904 2042//2042 +f 1493//1493 1500//1500 1056//1056 +f 205//205 1537//1537 2034//2034 +f 1431//1431 1888//1888 1432//1432 +f 1919//1919 1890//1890 2044//2044 +f 1407//1407 1507//1507 1506//1506 +f 278//278 277//277 1535//1535 +f 1852//1852 1858//1858 2017//2017 +f 1730//1730 2045//2045 1731//1731 +f 1731//1731 2045//2045 2046//2046 +f 1986//1986 2047//2047 1984//1984 +f 2038//2038 2048//2048 2018//2018 +f 1448//1448 1500//1500 1449//1449 +f 1853//1853 2017//2017 2049//2049 +f 784//784 1862//1862 785//785 +f 2029//2029 868//868 1828//1828 +f 2029//2029 2050//2050 2007//2007 +f 2035//2035 2016//2016 2007//2007 +f 1543//1543 1550//1550 1557//1557 +f 187//187 30//30 330//330 +f 1868//1868 1891//1891 2051//2051 +f 1984//1984 2052//2052 2038//2038 +f 2053//2053 2048//2048 2038//2038 +f 2048//2048 2039//2039 2018//2018 +f 2054//2054 2027//2027 2039//2039 +f 2027//2027 2055//2055 2015//2015 +f 2055//2055 1453//1453 2015//2015 +f 2056//2056 2057//2057 1453//1453 +f 185//185 184//184 1413//1413 +f 2022//2022 1831//1831 1830//1830 +f 1407//1407 1385//1385 1507//1507 +f 2029//2029 1828//1828 2050//2050 +f 2035//2035 1739//1739 1720//1720 +f 2013//2013 2035//2035 1720//1720 +f 1717//1717 882//882 1596//1596 +f 2058//2058 2051//2051 1891//1891 +f 1432//1432 1854//1854 2059//2059 +f 2060//2060 2061//2061 1986//1986 +f 1986//1986 2061//2061 2047//2047 +f 2038//2038 2052//2052 2053//2053 +f 2048//2048 2054//2054 2039//2039 +f 2054//2054 2055//2055 2027//2027 +f 2062//2062 1453//1453 2055//2055 +f 2063//2063 2057//2057 2056//2056 +f 1769//1769 1056//1056 1770//1770 +f 1500//1500 1448//1448 1770//1770 +f 1385//1385 1407//1407 1933//1933 +f 1827//1827 2050//2050 1828//1828 +f 2050//2050 2064//2064 2007//2007 +f 2007//2007 2064//2064 2035//2035 +f 1717//1717 1596//1596 1944//1944 +f 2065//2065 1717//1717 1944//1944 +f 2066//2066 1891//1891 1892//1892 +f 2051//2051 1730//1730 2067//2067 +f 2045//2045 2068//2068 2069//2069 +f 1801//1801 2061//2061 2060//2060 +f 2047//2047 2070//2070 1984//1984 +f 1984//1984 2070//2070 2052//2052 +f 2053//2053 2071//2071 2048//2048 +f 2048//2048 2071//2071 2054//2054 +f 2072//2072 2055//2055 2054//2054 +f 2056//2056 1453//1453 2062//2062 +f 853//853 2003//2003 331//331 +f 1500//1500 1770//1770 1056//1056 +f 2073//2073 1827//1827 1782//1782 +f 2073//2073 2050//2050 1827//1827 +f 1739//1739 2035//2035 2064//2064 +f 427//427 2069//2069 2068//2068 +f 825//825 827//827 1265//1265 +f 770//770 993//993 992//992 +f 1955//1955 1183//1183 1288//1288 +f 1518//1518 2040//2040 2033//2033 +f 2071//2071 2074//2074 2054//2054 +f 2075//2075 2072//2072 2054//2054 +f 2055//2055 1660//1660 2062//2062 +f 1660//1660 281//281 2062//2062 +f 281//281 2056//2056 2062//2062 +f 2076//2076 2059//2059 1904//1904 +f 1279//1279 1278//1278 2077//2077 +f 906//906 2073//2073 1782//1782 +f 2073//2073 2064//2064 2050//2050 +f 2065//2065 1944//1944 2078//2078 +f 2079//2079 1892//1892 75//75 +f 2079//2079 2080//2080 1892//1892 +f 2080//2080 2066//2066 1892//1892 +f 1891//1891 2066//2066 2058//2058 +f 2051//2051 2045//2045 1730//1730 +f 2052//2052 1527//1527 2053//2053 +f 2072//2072 1660//1660 2055//2055 +f 2081//2081 2082//2082 2083//2083 +f 2082//2082 2084//2084 2083//2083 +f 2085//2085 2086//2086 1371//1371 +f 1774//1774 1782//1782 1775//1775 +f 2087//2087 2064//2064 2073//2073 +f 1797//1797 2065//2065 2078//2078 +f 1753//1753 2079//2079 75//75 +f 998//998 2045//2045 2051//2051 +f 2070//2070 2088//2088 2052//2052 +f 2052//2052 2088//2088 1527//1527 +f 2053//2053 1527//1527 2071//2071 +f 2074//2074 2075//2075 2054//2054 +f 2063//2063 1522//1522 396//396 +f 2081//2081 396//396 1522//1522 +f 2081//2081 1417//1417 2082//2082 +f 119//119 1774//1774 221//221 +f 2089//2089 1488//1488 1994//1994 +f 905//905 2087//2087 2073//2073 +f 2087//2087 1739//1739 2064//2064 +f 2090//2090 2065//2065 1797//1797 +f 2090//2090 1717//1717 2065//2065 +f 2090//2090 1835//1835 1717//1717 +f 1772//1772 2079//2079 1753//1753 +f 1439//1439 1337//1337 1336//1336 +f 127//127 1739//1739 128//128 +f 1772//1772 2080//2080 2079//2079 +f 998//998 1682//1682 2045//2045 +f 2045//2045 1682//1682 2068//2068 +f 283//283 2091//2091 2070//2070 +f 2047//2047 283//283 2070//2070 +f 2070//2070 2091//2091 2088//2088 +f 2088//2088 41//41 1527//1527 +f 234//234 2075//2075 2074//2074 +f 2075//2075 1420//1420 2072//2072 +f 1395//1395 1660//1660 2072//2072 +f 281//281 280//280 2056//2056 +f 280//280 2063//2063 2056//2056 +f 222//222 2084//2084 2082//2082 +f 222//222 221//221 2084//2084 +f 119//119 1679//1679 1774//1774 +f 1679//1679 906//906 1774//1774 +f 906//906 905//905 2073//2073 +f 1311//1311 1739//1739 2087//2087 +f 996//996 2051//2051 2058//2058 +f 996//996 998//998 2051//2051 +f 2075//2075 234//234 1420//1420 +f 280//280 1522//1522 2063//2063 +f 905//905 1312//1312 2087//2087 +f 1312//1312 1311//1311 2087//2087 +f 2085//2085 2092//2092 2031//2031 +f 1497//1497 842//842 1681//1681 +f 37//37 36//36 2002//2002 +f 1476//1476 2080//2080 1772//1772 +f 1476//1476 2066//2066 2080//2080 +f 1476//1476 2058//2058 2066//2066 +f 1788//1788 85//85 1322//1322 +f 2091//2091 41//41 2088//2088 +f 2071//2071 223//223 2074//2074 +f 223//223 234//234 2074//2074 +f 1420//1420 823//823 2072//2072 +f 823//823 1395//1395 2072//2072 +f 279//279 281//281 1660//1660 +f 1417//1417 222//222 2082//2082 +f 212//212 1679//1679 119//119 +f 200//200 161//161 1492//1492 +f 656//656 304//304 1360//1360 +f 1643//1643 1835//1835 2090//2090 +f 303//303 1337//1337 1439//1439 +f 1478//1478 2058//2058 1476//1476 +f 2058//2058 1478//1478 996//996 +f 997//997 1682//1682 998//998 +f 214//214 1681//1681 1787//1787 +f 214//214 1787//1787 215//215 +f 215//215 1787//1787 1322//1322 +f 283//283 2047//2047 284//284 +f 1527//1527 186//186 2071//2071 +f 2071//2071 186//186 223//223 +f 280//280 1401//1401 1522//1522 +f 1522//1522 1418//1418 2081//2081 +f 1418//1418 1417//1417 2081//2081 +f 1864//1864 2024//2024 2093//2093 +f 2024//2024 2094//2094 2093//2093 +f 1981//1981 2095//2095 1994//1994 +f 879//879 878//878 1424//1424 +f 1779//1779 2031//2031 2030//2030 +f 2096//2096 1430//1430 2059//2059 +f 1260//1260 1615//1615 1559//1559 +f 2097//2097 2043//2043 1897//1897 +f 2012//2012 2037//2037 1071//1071 +f 570//570 27//27 775//775 +f 1432//1432 784//784 786//786 +f 1507//1507 1385//1385 1387//1387 +f 1450//1450 1449//1449 1915//1915 +f 1658//1658 1980//1980 1742//1742 +f 1980//1980 2098//2098 1742//1742 +f 231//231 1848//1848 1259//1259 +f 232//232 231//231 1259//1259 +f 84//84 1955//1955 527//527 +f 1500//1500 1407//1407 1506//1506 +f 1777//1777 1779//1779 2030//2030 +f 2099//2099 1472//1472 1539//1539 +f 827//827 826//826 1329//1329 +f 1273//1273 233//233 232//232 +f 1235//1235 568//568 245//245 +f 1742//1742 2098//2098 2100//2100 +f 2025//2025 2024//2024 2101//2101 +f 2086//2086 2085//2085 1779//1779 +f 1905//1905 1055//1055 2049//2049 +f 911//911 371//371 2102//2102 +f 2103//2103 2104//2104 2105//2105 +f 1405//1405 1440//1440 184//184 +f 2102//2102 1539//1539 911//911 +f 1911//1911 1405//1405 1372//1372 +f 1440//1440 1405//1405 1911//1911 +f 2106//2106 2004//2004 2107//2107 +f 1425//1425 974//974 1496//1496 +f 1865//1865 2108//2108 1850//1850 +f 2109//2109 1865//1865 2110//2110 +f 2111//2111 2097//2097 1897//1897 +f 95//95 1430//1430 71//71 +f 2100//2100 2028//2028 1952//1952 +f 2025//2025 2031//2031 2023//2023 +f 1994//1994 1974//1974 1865//1865 +f 2098//2098 2028//2028 2100//2100 +f 1658//1658 2095//2095 1980//1980 +f 1912//1912 2086//2086 1779//1779 +f 1865//1865 1778//1778 1651//1651 +f 1851//1851 1850//1850 2108//2108 +f 1387//1387 1864//1864 1538//1538 +f 2030//2030 2025//2025 122//122 +f 2020//2020 2112//2112 2113//2113 +f 2102//2102 2114//2114 1539//1539 +f 2114//2114 2099//2099 1539//1539 +f 1855//1855 1615//1615 1260//1260 +f 1415//1415 1414//1414 1488//1488 +f 1288//1288 528//528 1955//1955 +f 854//854 556//556 591//591 +f 528//528 1939//1939 529//529 +f 1949//1949 2115//2115 1950//1950 +f 2028//2028 2098//2098 1982//1982 +f 1651//1651 1778//1778 1777//1777 +f 1488//1488 1414//1414 1975//1975 +f 1694//1694 1143//1143 2067//2067 +f 780//780 767//767 791//791 +f 994//994 1487//1487 992//992 +f 1778//1778 1912//1912 1779//1779 +f 623//623 625//625 1390//1390 +f 1359//1359 1328//1328 85//85 +f 992//992 2095//2095 1658//1658 +f 1852//1852 1856//1856 1858//1858 +f 1506//1506 1508//1508 2001//2001 +f 1824//1824 2116//2116 1825//1825 +f 122//122 2025//2025 2101//2101 +f 2117//2117 2114//2114 2102//2102 +f 307//307 1431//1431 1430//1430 +f 2114//2114 2118//2118 2099//2099 +f 2095//2095 2089//2089 1994//1994 +f 1387//1387 1386//1386 1864//1864 +f 2077//2077 1278//1278 2119//2119 +f 2095//2095 1981//1981 1980//1980 +f 2120//2120 2043//2043 2097//2097 +f 2049//2049 1055//1055 2036//2036 +f 1250//1250 1008//1008 1551//1551 +f 111//111 120//120 307//307 +f 1500//1500 1506//1506 1449//1449 +f 1125//1125 764//764 1363//1363 +f 1982//1982 1849//1849 2028//2028 +f 1865//1865 1974//1974 1866//1866 +f 1995//1995 1994//1994 1865//1865 +f 371//371 2117//2117 2102//2102 +f 1811//1811 1952//1952 853//853 +f 1946//1946 2022//2022 1830//1830 +f 254//254 1511//1511 271//271 +f 1597//1597 1620//1620 1617//1617 +f 1620//1620 1561//1561 1617//1617 +f 2116//2116 1824//1824 1856//1856 +f 2032//2032 2114//2114 2117//2117 +f 1904//1904 2041//2041 2042//2042 +f 1430//1430 1432//1432 2059//2059 +f 1253//1253 765//765 1125//1125 +f 154//154 830//830 152//152 +f 1643//1643 2090//2090 1797//1797 +f 2121//2121 1561//1561 1620//1620 +f 2122//2122 2121//2121 1620//1620 +f 2121//2121 472//472 1561//1561 +f 2101//2101 2024//2024 1864//1864 +f 2028//2028 1860//1860 1952//1952 +f 2028//2028 1889//1889 1860//1860 +f 2077//2077 2119//2119 2123//2123 +f 1399//1399 860//860 1304//1304 +f 1233//1233 51//51 510//510 +f 2036//2036 1054//1054 2037//2037 +f 2077//2077 2123//2123 2124//2124 +f 786//786 2116//2116 1854//1854 +f 477//477 1880//1880 478//478 +f 1620//1620 1624//1624 2122//2122 +f 2122//2122 2125//2125 2121//2121 +f 2121//2121 2125//2125 472//472 +f 1864//1864 2093//2093 1538//1538 +f 1537//1537 205//205 1992//1992 +f 1624//1624 1797//1797 2122//2122 +f 1797//1797 2126//2126 2122//2122 +f 2126//2126 2125//2125 2122//2122 +f 2125//2125 835//835 472//472 +f 860//860 2127//2127 1946//1946 +f 1890//1890 1849//1849 1851//1851 +f 527//527 1955//1955 528//528 +f 1304//1304 860//860 1957//1957 +f 2078//2078 2126//2126 1797//1797 +f 417//417 226//226 835//835 +f 1628//1628 2111//2111 2019//2019 +f 2019//2019 2111//2111 2128//2128 +f 2129//2129 71//71 2096//2096 +f 1054//1054 2036//2036 1055//1055 +f 1372//1372 1389//1389 1390//1390 +f 1830//1830 1528//1528 858//858 +f 1508//1508 1538//1538 1992//1992 +f 2012//2012 1071//1071 1584//1584 +f 1432//1432 786//786 1854//1854 +f 1854//1854 2116//2116 1852//1852 +f 1172//1172 2130//2130 1173//1173 +f 2125//2125 2131//2131 835//835 +f 835//835 2131//2131 417//417 +f 1933//1933 1406//1406 1823//1823 +f 1853//1853 2041//2041 1904//1904 +f 2120//2120 2129//2129 2043//2043 +f 1848//1848 1258//1258 437//437 +f 237//237 967//967 244//244 +f 1338//1338 343//343 657//657 +f 371//371 1236//1236 2117//2117 +f 2129//2129 2096//2096 2076//2076 +f 1853//1853 2049//2049 2041//2041 +f 1172//1172 424//424 1756//1756 +f 1897//1897 2043//2043 2042//2042 +f 62//62 1448//1448 1450//1450 +f 2042//2042 2036//2036 2012//2012 +f 344//344 1284//1284 407//407 +f 205//205 204//204 1485//1485 +f 260//260 262//262 1693//1693 +f 1862//1862 1861//1861 785//785 +f 1919//1919 1844//1844 785//785 +f 1861//1861 1919//1919 785//785 +f 417//417 2132//2132 226//226 +f 226//226 2132//2132 2133//2133 +f 2134//2134 2135//2135 2136//2136 +f 418//418 575//575 576//576 +f 1863//1863 1125//1125 1510//1510 +f 1974//1974 1488//1488 1975//1975 +f 2005//2005 2137//2137 2006//2006 +f 1852//1852 2116//2116 1856//1856 +f 1993//1993 1485//1485 1484//1484 +f 1580//1580 1254//1254 1236//1236 +f 205//205 1485//1485 1993//1993 +f 681//681 680//680 1130//1130 +f 1512//1512 2118//2118 2114//2114 +f 911//911 1539//1539 1455//1455 +f 1849//1849 1890//1890 1889//1889 +f 1253//1253 1863//1863 1254//1254 +f 405//405 1433//1433 679//679 +f 1915//1915 2001//2001 1484//1484 +f 1706//1706 2138//2138 480//480 +f 853//853 1952//1952 2003//2003 +f 71//71 1430//1430 2096//2096 +f 575//575 2131//2131 2125//2125 +f 1462//1462 1472//1472 1392//1392 +f 2132//2132 255//255 2139//2139 +f 2128//2128 2111//2111 1897//1897 +f 2140//2140 2128//2128 1897//1897 +f 2141//2141 2109//2109 1650//1650 +f 1229//1229 520//520 522//522 +f 2022//2022 1946//1946 2127//2127 +f 1859//1859 1953//1953 1888//1888 +f 1487//1487 994//994 1415//1415 +f 2142//2142 2138//2138 1706//1706 +f 2142//2142 2143//2143 2138//2138 +f 2143//2143 2144//2144 2145//2145 +f 2138//2138 2143//2143 2145//2145 +f 1389//1389 1405//1405 1404//1404 +f 556//556 854//854 554//554 +f 1957//1957 860//860 1940//1940 +f 1816//1816 827//827 1447//1447 +f 1811//1811 2100//2100 1952//1952 +f 2146//2146 1947//1947 1966//1966 +f 1865//1865 2109//2109 2108//2108 +f 1484//1484 1486//1486 1915//1915 +f 2001//2001 1993//1993 1484//1484 +f 2147//2147 1536//1536 1538//1538 +f 2129//2129 2076//2076 2043//2043 +f 192//192 1561//1561 472//472 +f 1594//1594 2020//2020 1592//1592 +f 1386//1386 121//121 123//123 +f 2139//2139 2148//2148 2133//2133 +f 2149//2149 1706//1706 2150//2150 +f 2148//2148 2149//2149 2150//2150 +f 2149//2149 2142//2142 1706//1706 +f 528//528 1957//1957 1940//1940 +f 1486//1486 1632//1632 1915//1915 +f 1583//1583 1236//1236 300//300 +f 122//122 2101//2101 123//123 +f 2117//2117 1236//1236 2032//2032 +f 255//255 257//257 2139//2139 +f 257//257 2151//2151 2139//2139 +f 2139//2139 2151//2151 2148//2148 +f 2152//2152 2144//2144 2143//2143 +f 1788//1788 1990//1990 86//86 +f 770//770 992//992 1644//1644 +f 1372//1372 1371//1371 1912//1912 +f 1866//1866 1912//1912 1778//1778 +f 2149//2149 2153//2153 2142//2142 +f 2153//2153 2143//2143 2142//2142 +f 2154//2154 2144//2144 2152//2152 +f 1537//1537 1992//1992 1538//1538 +f 1236//1236 1254//1254 1863//1863 +f 2042//2042 2012//2012 1895//1895 +f 2155//2155 2152//2152 2143//2143 +f 2043//2043 2076//2076 1904//1904 +f 256//256 1665//1665 257//257 +f 1665//1665 2151//2151 257//257 +f 2156//2156 2155//2155 2143//2143 +f 2135//2135 2134//2134 2154//2154 +f 1508//1508 1992//1992 1993//1993 +f 1940//1940 1939//1939 528//528 +f 675//675 1665//1665 256//256 +f 2151//2151 2157//2157 2149//2149 +f 2148//2148 2151//2151 2149//2149 +f 2149//2149 2157//2157 2153//2153 +f 2143//2143 2153//2153 2156//2156 +f 329//329 71//71 2129//2129 +f 2017//2017 1905//1905 2049//2049 +f 2158//2158 2152//2152 2155//2155 +f 1510//1510 1363//1363 1511//1511 +f 329//329 2129//2129 2120//2120 +f 307//307 120//120 1431//1431 +f 1510//1510 1125//1125 1363//1363 +f 1372//1372 1405//1405 1389//1389 +f 2096//2096 2059//2059 2076//2076 +f 1331//1331 1665//1665 675//675 +f 1564//1564 2157//2157 2151//2151 +f 2158//2158 2154//2154 2152//2152 +f 1564//1564 2151//2151 1665//1665 +f 2157//2157 2159//2159 2153//2153 +f 2153//2153 2159//2159 2156//2156 +f 2156//2156 2158//2158 2155//2155 +f 2160//2160 2154//2154 2158//2158 +f 2001//2001 1508//1508 1993//1993 +f 329//329 2120//2120 1628//1628 +f 120//120 331//331 1859//1859 +f 1975//1975 1414//1414 1866//1866 +f 2002//2002 1968//1968 1582//1582 +f 1564//1564 1427//1427 2157//2157 +f 1427//1427 2161//2161 2157//2157 +f 2157//2157 2161//2161 2159//2159 +f 2160//2160 2135//2135 2154//2154 +f 2160//2160 2136//2136 2135//2135 +f 2162//2162 287//287 1291//1291 +f 2041//2041 2049//2049 2036//2036 +f 1252//1252 765//765 1253//1253 +f 1431//1431 1859//1859 1888//1888 +f 575//575 2125//2125 801//801 +f 1811//1811 1742//1742 2100//2100 +f 1825//1825 2116//2116 2163//2163 +f 2042//2042 1895//1895 1897//1897 +f 534//534 898//898 899//899 +f 1844//1844 2163//2163 2116//2116 +f 1564//1564 1428//1428 1427//1427 +f 2164//2164 2158//2158 2156//2156 +f 208//208 325//325 680//680 +f 1136//1136 2165//2165 1463//1463 +f 1777//1777 2030//2030 122//122 +f 2089//2089 1487//1487 1488//1488 +f 1844//1844 2116//2116 786//786 +f 2159//2159 2166//2166 2156//2156 +f 2166//2166 2164//2164 2156//2156 +f 2164//2164 2160//2160 2158//2158 +f 1897//1897 1896//1896 2140//2140 +f 1507//1507 1538//1538 1508//1508 +f 2098//2098 1980//1980 1982//1982 +f 1677//1677 1811//1811 853//853 +f 1673//1673 1742//1742 1811//1811 +f 803//803 749//749 1567//1567 +f 2161//2161 2167//2167 2159//2159 +f 1920//1920 1922//1922 1650//1650 +f 1512//1512 1511//1511 2168//2168 +f 2109//2109 2110//2110 1650//1650 +f 2109//2109 2141//2141 2108//2108 +f 1865//1865 1651//1651 2110//2110 +f 992//992 1487//1487 2089//2089 +f 1449//1449 2001//2001 1915//1915 +f 1890//1890 1851//1851 2044//2044 +f 1911//1911 1372//1372 1912//1912 +f 2123//2123 2119//2119 2169//2169 +f 2020//2020 2128//2128 2140//2140 +f 2095//2095 992//992 2089//2089 +f 2044//2044 1851//1851 2170//2170 +f 2020//2020 2140//2140 2112//2112 +f 528//528 1288//1288 1957//1957 +f 1968//1968 1570//1570 1265//1265 +f 1866//1866 1440//1440 1912//1912 +f 1816//1816 1447//1447 1968//1968 +f 1385//1385 1921//1921 1386//1386 +f 2044//2044 1844//1844 1919//1919 +f 1953//1953 1860//1860 1888//1888 +f 596//596 494//494 597//597 +f 2159//2159 2167//2167 2166//2166 +f 2171//2171 2160//2160 2164//2164 +f 2171//2171 2172//2172 2160//2160 +f 2172//2172 2136//2136 2160//2160 +f 2172//2172 1092//1092 2136//2136 +f 2111//2111 2120//2120 2097//2097 +f 1628//1628 2120//2120 2111//2111 +f 1982//1982 1850//1850 1849//1849 +f 1236//1236 1863//1863 2032//2032 +f 1943//1943 1596//1596 1696//1696 +f 1411//1411 2173//2173 2092//2092 +f 1779//1779 2085//2085 2031//2031 +f 1427//1427 1429//1429 1592//1592 +f 1427//1427 2167//2167 2161//2161 +f 2112//2112 2166//2166 2167//2167 +f 2113//2113 2112//2112 2167//2167 +f 2112//2112 2164//2164 2166//2166 +f 2112//2112 2140//2140 2164//2164 +f 2140//2140 2171//2171 2164//2164 +f 2059//2059 1854//1854 1904//1904 +f 123//123 2101//2101 1864//1864 +f 1868//1868 2051//2051 2067//2067 +f 1510//1510 2114//2114 2032//2032 +f 1644//1644 992//992 1658//1658 +f 1233//1233 510//510 461//461 +f 1427//1427 1592//1592 2167//2167 +f 1896//1896 2172//2172 2171//2171 +f 1981//1981 1995//1995 1850//1850 +f 2019//2019 2128//2128 2020//2020 +f 1510//1510 1512//1512 2114//2114 +f 1130//1130 635//635 1100//1100 +f 1968//1968 1265//1265 1816//1816 +f 2169//2169 2119//2119 2174//2174 +f 2020//2020 2167//2167 1592//1592 +f 2020//2020 2113//2113 2167//2167 +f 2172//2172 1896//1896 1092//1092 +f 1447//1447 1329//1329 1962//1962 +f 931//931 1618//1618 933//933 +f 2023//2023 2031//2031 2173//2173 +f 2140//2140 1896//1896 2171//2171 +f 1946//1946 1830//1830 858//858 +f 1920//1920 1649//1649 121//121 +f 2011//2011 1216//1216 1215//1215 +f 1835//1835 939//939 1717//1717 +f 1453//1453 2057//2057 1454//1454 +f 1728//1728 1715//1715 1789//1789 +f 90//90 2057//2057 91//91 +f 1454//1454 2057//2057 90//90 +f 2175//2175 2057//2057 2063//2063 +f 1842//1842 90//90 2145//2145 +f 2176//2176 90//90 1842//1842 +f 395//395 2177//2177 2178//2178 +f 16//16 506//506 555//555 +f 1830//1830 1554//1554 1528//1528 +f 395//395 1839//1839 2177//2177 +f 1839//1839 2179//2179 2177//2177 +f 241//241 1511//1511 254//254 +f 2179//2179 1839//1839 2180//2180 +f 2181//2181 2168//2168 1511//1511 +f 241//241 2181//2181 1511//1511 +f 2182//2182 2183//2183 2134//2134 +f 2180//2180 1782//1782 1826//1826 +f 2181//2181 2184//2184 2168//2168 +f 2184//2184 2185//2185 2168//2168 +f 463//463 1868//1868 2067//2067 +f 251//251 2186//2186 241//241 +f 241//241 2186//2186 2181//2181 +f 172//172 2187//2187 1232//1232 +f 1365//1365 2188//2188 974//974 +f 1997//1997 1999//1999 2189//2189 +f 2190//2190 1213//1213 966//966 +f 1103//1103 616//616 478//478 +f 1552//1552 2021//2021 1262//1262 +f 1990//1990 1680//1680 1979//1979 +f 2186//2186 2184//2184 2181//2181 +f 1836//1836 1838//1838 1907//1907 +f 1837//1837 1836//1836 1846//1846 +f 1789//1789 2191//2191 1726//1726 +f 2192//2192 2193//2193 2194//2194 +f 2078//2078 2195//2195 801//801 +f 1985//1985 2196//2196 2192//2192 +f 1986//1986 1985//1985 2192//2192 +f 1173//1173 2130//2130 251//251 +f 2130//2130 2197//2197 2186//2186 +f 251//251 2130//2130 2186//2186 +f 2185//2185 2099//2099 2118//2118 +f 1986//1986 2192//2192 2060//2060 +f 1985//1985 1997//1997 2196//2196 +f 2198//2198 1763//1763 2183//2183 +f 2199//2199 2200//2200 2191//2191 +f 2154//2154 2183//2183 2144//2144 +f 394//394 396//396 2081//2081 +f 2197//2197 2201//2201 2186//2186 +f 2186//2186 2201//2201 2184//2184 +f 2201//2201 1473//1473 2185//2185 +f 2184//2184 2201//2201 2185//2185 +f 2021//2021 1552//1552 1831//1831 +f 1554//1554 1831//1831 1552//1552 +f 172//172 1231//1231 2202//2202 +f 1826//1826 868//868 788//788 +f 1410//1410 1409//1409 2203//2203 +f 1962//1962 1964//1964 1447//1447 +f 1857//1857 2017//2017 1858//1858 +f 2185//2185 1473//1473 2099//2099 +f 1473//1473 1472//1472 2099//2099 +f 2179//2179 176//176 1314//1314 +f 2179//2179 2180//2180 176//176 +f 176//176 2180//2180 2204//2204 +f 396//396 2178//2178 2175//2175 +f 396//396 395//395 2178//2178 +f 1724//1724 1726//1726 2205//2205 +f 175//175 493//493 224//224 +f 1450//1450 1915//1915 1916//1916 +f 1789//1789 1761//1761 2191//2191 +f 2177//2177 92//92 91//91 +f 1172//1172 1756//1756 2130//2130 +f 1839//1839 1775//1775 2180//2180 +f 1725//1725 1789//1789 1726//1726 +f 1997//1997 2189//2189 2196//2196 +f 2187//2187 172//172 1169//1169 +f 175//175 2150//2150 1706//1706 +f 175//175 224//224 2150//2150 +f 2180//2180 1775//1775 1782//1782 +f 1756//1756 1755//1755 2130//2130 +f 1755//1755 2197//2197 2130//2130 +f 1958//1958 1161//1161 1321//1321 +f 2176//2176 1454//1454 90//90 +f 1641//1641 213//213 1328//1328 +f 213//213 1641//1641 214//214 +f 2191//2191 2198//2198 2206//2206 +f 2199//2199 2191//2191 2206//2206 +f 2207//2207 2200//2200 2199//2199 +f 224//224 226//226 2133//2133 +f 2208//2208 2207//2207 1806//1806 +f 2208//2208 2200//2200 2207//2207 +f 840//840 2209//2209 1474//1474 +f 2069//2069 1731//1731 2046//2046 +f 2069//2069 2210//2210 1731//1731 +f 1782//1782 1827//1827 1826//1826 +f 2197//2197 2211//2211 2201//2201 +f 1393//1393 1473//1473 2201//2201 +f 2211//2211 1393//1393 2201//2201 +f 1493//1493 1905//1905 1408//1408 +f 172//172 2202//2202 173//173 +f 1615//1615 1855//1855 1662//1662 +f 1390//1390 625//625 1372//1372 +f 1493//1493 1056//1056 1055//1055 +f 2207//2207 1297//1297 1334//1334 +f 1333//1333 2207//2207 1334//1334 +f 2189//2189 1727//1727 2212//2212 +f 1857//1857 1823//1823 1832//1832 +f 174//174 173//173 2213//2213 +f 424//424 1172//1172 1219//1219 +f 2214//2214 2182//2182 2136//2136 +f 2215//2215 1807//1807 1332//1332 +f 1727//1727 2010//2010 1215//1215 +f 1755//1755 1847//1847 2197//2197 +f 2197//2197 1847//1847 2211//2211 +f 801//801 2126//2126 2078//2078 +f 173//173 1807//1807 2215//2215 +f 624//624 1371//1371 625//625 +f 2136//2136 2182//2182 2134//2134 +f 1847//1847 1393//1393 2211//2211 +f 1956//1956 841//841 1475//1475 +f 1727//1727 1215//1215 1728//1728 +f 1371//1371 2086//2086 1912//1912 +f 2175//2175 2178//2178 91//91 +f 1806//1806 1333//1333 1332//1332 +f 2216//2216 966//966 324//324 +f 1701//1701 1232//1232 2210//2210 +f 2057//2057 2175//2175 91//91 +f 1584//1584 1092//1092 1896//1896 +f 1999//1999 2008//2008 2010//2010 +f 868//868 2029//2029 1562//1562 +f 2213//2213 2215//2215 2217//2217 +f 2213//2213 2209//2209 2187//2187 +f 1132//1132 143//143 730//730 +f 1985//1985 2038//2038 1997//1997 +f 2218//2218 1801//1801 2060//2060 +f 1126//1126 324//324 966//966 +f 1743//1743 1766//1766 1491//1491 +f 2219//2219 1641//1641 1695//1695 +f 1701//1701 2210//2210 2069//2069 +f 426//426 1701//1701 2069//2069 +f 1806//1806 2207//2207 1333//1333 +f 255//255 2132//2132 417//417 +f 624//624 2092//2092 1371//1371 +f 1520//1520 1139//1139 1521//1521 +f 2220//2220 2221//2221 2222//2222 +f 2119//2119 1278//1278 2223//2223 +f 1999//1999 1727//1727 2189//2189 +f 426//426 2069//2069 427//427 +f 2224//2224 173//173 2202//2202 +f 974//974 2188//2188 1496//1496 +f 1334//1334 1296//1296 2225//2225 +f 2195//2195 2190//2190 2216//2216 +f 2177//2177 479//479 92//92 +f 424//424 423//423 1755//1755 +f 423//423 1847//1847 1755//1755 +f 1731//1731 2210//2210 2221//2221 +f 471//471 473//473 247//247 +f 2187//2187 2209//2209 2226//2226 +f 1857//1857 1824//1824 1823//1823 +f 177//177 493//493 175//175 +f 1731//1731 2219//2219 1694//1694 +f 2227//2227 1516//1516 1383//1383 +f 1537//1537 1536//1536 2228//2228 +f 2177//2177 1314//1314 479//479 +f 1210//1210 971//971 1083//1083 +f 1278//1278 1370//1370 2223//2223 +f 2173//2173 1411//1411 880//880 +f 2092//2092 2085//2085 1371//1371 +f 2229//2229 2224//2224 2202//2202 +f 2207//2207 2199//2199 1297//1297 +f 2199//2199 1298//1298 1297//1297 +f 1423//1423 2230//2230 879//879 +f 2231//2231 2173//2173 880//880 +f 1678//1678 2232//2232 2214//2214 +f 1715//1715 1762//1762 1761//1761 +f 2196//2196 2189//2189 2229//2229 +f 1461//1461 1685//1685 1884//1884 +f 1083//1083 2233//2233 1210//1210 +f 2233//2233 1208//1208 1210//1210 +f 1916//1916 1632//1632 1634//1634 +f 1496//1496 2230//2230 1423//1423 +f 2230//2230 880//880 879//879 +f 1538//1538 2093//2093 2147//2147 +f 1810//1810 1834//1834 1032//1032 +f 1834//1834 2232//2232 1678//1678 +f 1874//1874 438//438 1767//1767 +f 2219//2219 2220//2220 1641//1641 +f 2234//2234 2187//2187 2226//2226 +f 2233//2233 1365//1365 1208//1208 +f 2230//2230 2231//2231 880//880 +f 2231//2231 2235//2235 2173//2173 +f 2196//2196 2229//2229 2193//2193 +f 1314//1314 176//176 175//175 +f 801//801 323//323 575//575 +f 1083//1083 1555//1555 2233//2233 +f 2233//2233 2236//2236 1365//1365 +f 1365//1365 2236//2236 2188//2188 +f 2188//2188 2237//2237 1496//1496 +f 2237//2237 2238//2238 2230//2230 +f 1496//1496 2237//2237 2230//2230 +f 2230//2230 2238//2238 2231//2231 +f 2238//2238 2239//2239 2231//2231 +f 2239//2239 2240//2240 2231//2231 +f 2240//2240 2235//2235 2231//2231 +f 1641//1641 2222//2222 1642//1642 +f 1369//1369 1521//1521 1370//1370 +f 2221//2221 2234//2234 2222//2222 +f 2218//2218 1701//1701 426//426 +f 2182//2182 2198//2198 2183//2183 +f 1763//1763 1842//1842 2144//2144 +f 1555//1555 2241//2241 2233//2233 +f 2188//2188 2242//2242 2237//2237 +f 2173//2173 2235//2235 2023//2023 +f 128//128 1739//1739 1311//1311 +f 446//446 1526//1526 1893//1893 +f 983//983 51//51 1234//1234 +f 1169//1169 174//174 2187//2187 +f 453//453 75//75 1892//1892 +f 1726//1726 2200//2200 2208//2208 +f 2233//2233 2243//2243 2236//2236 +f 2236//2236 2243//2243 2188//2188 +f 2243//2243 2242//2242 2188//2188 +f 1695//1695 1641//1641 1328//1328 +f 2217//2217 2225//2225 1474//1474 +f 1649//1649 1651//1651 1777//1777 +f 1486//1486 1485//1485 2244//2244 +f 463//463 2067//2067 1143//1143 +f 2237//2237 2245//2245 2238//2238 +f 2240//2240 2246//2246 2235//2235 +f 1411//1411 624//624 1412//1412 +f 1144//1144 1695//1695 1328//1328 +f 1642//1642 2234//2234 1498//1498 +f 2217//2217 1474//1474 2209//2209 +f 1232//1232 2187//2187 2221//2221 +f 1330//1330 1350//1350 2247//2247 +f 2218//2218 1231//1231 1701//1701 +f 2233//2233 2241//2241 2243//2243 +f 2234//2234 2226//2226 1498//1498 +f 2226//2226 2209//2209 1498//1498 +f 2209//2209 2213//2213 2217//2217 +f 2227//2227 2248//2248 1516//1516 +f 1516//1516 2248//2248 1555//1555 +f 1555//1555 2248//2248 2241//2241 +f 2242//2242 2245//2245 2237//2237 +f 2238//2238 2245//2245 2239//2239 +f 2249//2249 2023//2023 2235//2235 +f 1450//1450 1710//1710 62//62 +f 2094//2094 2024//2024 2023//2023 +f 2118//2118 2168//2168 2185//2185 +f 1649//1649 122//122 121//121 +f 1998//1998 1997//1997 2038//2038 +f 2137//2137 2250//2250 2251//2251 +f 1805//1805 1943//1943 1696//1696 +f 2193//2193 2202//2202 1231//1231 +f 177//177 2204//2204 788//788 +f 2248//2248 2252//2252 2241//2241 +f 2241//2241 2253//2253 2243//2243 +f 2253//2253 2242//2242 2243//2243 +f 2254//2254 2246//2246 2240//2240 +f 2179//2179 1314//1314 2177//2177 +f 1233//1233 461//461 463//463 +f 1031//1031 1296//1296 1810//1810 +f 2063//2063 396//396 2175//2175 +f 1383//1383 1394//1394 2227//2227 +f 2255//2255 2256//2256 2245//2245 +f 2245//2245 2256//2256 2239//2239 +f 2256//2256 2240//2240 2239//2239 +f 2246//2246 2257//2257 2235//2235 +f 2257//2257 2249//2249 2235//2235 +f 2249//2249 2094//2094 2023//2023 +f 1805//1805 1213//1213 2190//2190 +f 453//453 1892//1892 1868//1868 +f 2232//2232 2206//2206 2182//2182 +f 1517//1517 1302//1302 1518//1518 +f 2227//2227 2258//2258 2248//2248 +f 2248//2248 2259//2259 2252//2252 +f 2252//2252 2260//2260 2241//2241 +f 2253//2253 2261//2261 2242//2242 +f 2242//2242 2262//2262 2245//2245 +f 343//343 616//616 1104//1104 +f 1234//1234 1989//1989 983//983 +f 2092//2092 624//624 1411//1411 +f 2248//2248 2258//2258 2259//2259 +f 2259//2259 2260//2260 2252//2252 +f 2241//2241 2260//2260 2253//2253 +f 2242//2242 2261//2261 2262//2262 +f 2262//2262 2263//2263 2245//2245 +f 2245//2245 2263//2263 2255//2255 +f 2254//2254 2240//2240 2256//2256 +f 2254//2254 2257//2257 2246//2246 +f 1092//1092 2214//2214 2136//2136 +f 1298//1298 2199//2199 2232//2232 +f 2199//2199 2206//2206 2232//2232 +f 208//208 681//681 209//209 +f 2227//2227 2264//2264 2258//2258 +f 2263//2263 2265//2265 2255//2255 +f 2222//2222 2234//2234 1642//1642 +f 1770//1770 1448//1448 64//64 +f 1944//1944 1943//1943 2078//2078 +f 1530//1530 2266//2266 2227//2227 +f 2259//2259 2258//2258 2264//2264 +f 2267//2267 2255//2255 2265//2265 +f 2267//2267 2268//2268 2256//2256 +f 2255//2255 2267//2267 2256//2256 +f 2268//2268 2269//2269 2254//2254 +f 2256//2256 2268//2268 2254//2254 +f 2254//2254 2269//2269 2257//2257 +f 2257//2257 2270//2270 2249//2249 +f 2270//2270 2094//2094 2249//2249 +f 1296//1296 1834//1834 1810//1810 +f 2225//2225 1296//1296 1549//1549 +f 1259//1259 1848//1848 1855//1855 +f 592//592 456//456 626//626 +f 1938//1938 859//859 858//858 +f 1991//1991 2170//2170 2141//2141 +f 973//973 1555//1555 1083//1083 +f 1773//1773 2084//2084 1774//1774 +f 2094//2094 2271//2271 2093//2093 +f 2260//2260 2272//2272 2253//2253 +f 2261//2261 2273//2273 2262//2262 +f 2269//2269 2274//2274 2257//2257 +f 2274//2274 2270//2270 2257//2257 +f 2094//2094 2270//2270 2271//2271 +f 1521//1521 1983//1983 1370//1370 +f 1805//1805 1224//1224 1213//1213 +f 1789//1789 1715//1715 1761//1761 +f 1474//1474 1549//1549 1542//1542 +f 1922//1922 1991//1991 2141//2141 +f 1459//1459 813//813 632//632 +f 2204//2204 2180//2180 1826//1826 +f 1216//1216 1454//1454 2176//2176 +f 2189//2189 2212//2212 2224//2224 +f 1715//1715 1216//1216 2176//2176 +f 2227//2227 2266//2266 2264//2264 +f 2259//2259 2272//2272 2260//2260 +f 2272//2272 2275//2275 2253//2253 +f 2253//2253 2275//2275 2261//2261 +f 2268//2268 2276//2276 2269//2269 +f 2276//2276 2277//2277 2269//2269 +f 2269//2269 2277//2277 2274//2274 +f 1359//1359 463//463 1144//1144 +f 1234//1234 463//463 1359//1359 +f 1762//1762 2176//2176 1842//1842 +f 1825//1825 2170//2170 1991//1991 +f 2183//2183 2154//2154 2134//2134 +f 1839//1839 1773//1773 1775//1775 +f 2259//2259 2278//2278 2272//2272 +f 2263//2263 2262//2262 2265//2265 +f 1641//1641 2220//2220 2222//2222 +f 2163//2163 2170//2170 1825//1825 +f 2163//2163 2044//2044 2170//2170 +f 2195//2195 2078//2078 1943//1943 +f 569//569 568//568 1161//1161 +f 2278//2278 2279//2279 2272//2272 +f 2272//2272 2273//2273 2275//2275 +f 2273//2273 2261//2261 2275//2275 +f 2273//2273 2280//2280 2262//2262 +f 2277//2277 2281//2281 2274//2274 +f 2281//2281 2270//2270 2274//2274 +f 1549//1549 1296//1296 217//217 +f 1851//1851 2108//2108 2170//2170 +f 2178//2178 2177//2177 91//91 +f 2219//2219 2221//2221 2220//2220 +f 2280//2280 2265//2265 2262//2262 +f 2267//2267 2282//2282 2268//2268 +f 2268//2268 2282//2282 2276//2276 +f 2147//2147 2271//2271 2270//2270 +f 2281//2281 2147//2147 2270//2270 +f 2067//2067 1730//1730 1694//1694 +f 1933//1933 1991//1991 1921//1921 +f 801//801 2195//2195 802//802 +f 53//53 1972//1972 51//51 +f 1874//1874 1103//1103 478//478 +f 2279//2279 2283//2283 2272//2272 +f 2283//2283 2284//2284 2272//2272 +f 2284//2284 2285//2285 2272//2272 +f 2272//2272 2285//2285 2273//2273 +f 2285//2285 2280//2280 2273//2273 +f 1296//1296 1298//1298 1834//1834 +f 1844//1844 2044//2044 2163//2163 +f 1922//1922 2141//2141 1650//1650 +f 1806//1806 1726//1726 2208//2208 +f 437//437 1767//1767 438//438 +f 2264//2264 2286//2286 2259//2259 +f 2259//2259 2286//2286 2278//2278 +f 2276//2276 2287//2287 2277//2277 +f 2277//2277 2287//2287 2281//2281 +f 2288//2288 2278//2278 2286//2286 +f 2278//2278 2288//2288 2279//2279 +f 2285//2285 2289//2289 2280//2280 +f 2289//2289 2290//2290 2265//2265 +f 2280//2280 2289//2289 2265//2265 +f 2290//2290 2267//2267 2265//2265 +f 174//174 2213//2213 2187//2187 +f 1143//1143 1695//1695 1144//1144 +f 1530//1530 2291//2291 2266//2266 +f 2288//2288 2292//2292 2279//2279 +f 2279//2279 2292//2292 2283//2283 +f 2284//2284 2289//2289 2285//2285 +f 2282//2282 2293//2293 2276//2276 +f 2287//2287 2294//2294 2281//2281 +f 2195//2195 1943//1943 1805//1805 +f 1276//1276 1847//1847 423//423 +f 1823//1823 1991//1991 1933//1933 +f 2224//2224 1807//1807 173//173 +f 2204//2204 1826//1826 788//788 +f 1470//1470 1947//1947 1530//1530 +f 1530//1530 1947//1947 2291//2291 +f 2295//2295 2267//2267 2290//2290 +f 2267//2267 2295//2295 2282//2282 +f 2276//2276 2293//2293 2287//2287 +f 2228//2228 2147//2147 2281//2281 +f 1823//1823 1825//1825 1991//1991 +f 2133//2133 2148//2148 2150//2150 +f 2131//2131 575//575 417//417 +f 2291//2291 2296//2296 2266//2266 +f 2296//2296 2264//2264 2266//2266 +f 2292//2292 2297//2297 2283//2283 +f 2284//2284 2297//2297 2289//2289 +f 2287//2287 2298//2298 2294//2294 +f 2228//2228 2281//2281 2294//2294 +f 2229//2229 2189//2189 2224//2224 +f 2216//2216 2190//2190 966//966 +f 1836//1836 1634//1634 1633//1633 +f 1470//1470 1494//1494 1947//1947 +f 2264//2264 2296//2296 2286//2286 +f 2283//2283 2297//2297 2284//2284 +f 2297//2297 2299//2299 2289//2289 +f 2293//2293 2300//2300 2287//2287 +f 2300//2300 2298//2298 2287//2287 +f 2298//2298 2228//2228 2294//2294 +f 2083//2083 2084//2084 1773//1773 +f 2217//2217 2215//2215 2225//2225 +f 2200//2200 1726//1726 2191//2191 +f 2282//2282 2301//2301 2293//2293 +f 1280//1280 1071//1071 1976//1976 +f 1976//1976 1071//1071 2037//2037 +f 2195//2195 1805//1805 2190//2190 +f 2083//2083 1773//1773 394//394 +f 176//176 2204//2204 177//177 +f 2296//2296 2302//2302 2286//2286 +f 2286//2286 2302//2302 2288//2288 +f 2292//2292 2303//2303 2297//2297 +f 2299//2299 2304//2304 2289//2289 +f 2289//2289 2304//2304 2290//2290 +f 2295//2295 2301//2301 2282//2282 +f 2293//2293 2305//2305 2300//2300 +f 1133//1133 1444//1444 1241//1241 +f 2034//2034 1537//1537 2228//2228 +f 2081//2081 2083//2083 394//394 +f 1519//1519 1518//1518 2306//2306 +f 2221//2221 2187//2187 2234//2234 +f 2302//2302 2307//2307 2288//2288 +f 2307//2307 2303//2303 2292//2292 +f 2288//2288 2307//2307 2292//2292 +f 2303//2303 2308//2308 2297//2297 +f 2304//2304 2309//2309 2290//2290 +f 2309//2309 2295//2295 2290//2290 +f 2108//2108 2141//2141 2170//2170 +f 51//51 1233//1233 1234//1234 +f 1678//1678 2214//2214 1092//1092 +f 2297//2297 2310//2310 2299//2299 +f 2301//2301 2305//2305 2293//2293 +f 206//206 2228//2228 2298//2298 +f 206//206 2034//2034 2228//2228 +f 1826//1826 1828//1828 868//868 +f 437//437 1855//1855 1848//1848 +f 2308//2308 2311//2311 2297//2297 +f 2297//2297 2311//2311 2310//2310 +f 2299//2299 2312//2312 2304//2304 +f 2305//2305 2313//2313 2300//2300 +f 2313//2313 2298//2298 2300//2300 +f 1731//1731 2221//2221 2219//2219 +f 1832//1832 1905//1905 1857//1857 +f 1985//1985 1984//1984 2038//2038 +f 2195//2195 2216//2216 802//802 +f 2183//2183 1763//1763 2144//2144 +f 75//75 452//452 76//76 +f 2144//2144 1842//1842 2145//2145 +f 2312//2312 2309//2309 2304//2304 +f 2309//2309 2314//2314 2301//2301 +f 2295//2295 2309//2309 2301//2301 +f 2314//2314 2315//2315 2305//2305 +f 2301//2301 2314//2314 2305//2305 +f 2021//2021 1966//1966 1262//1262 +f 452//452 451//451 76//76 +f 1761//1761 2198//2198 2191//2191 +f 1947//1947 2146//2146 2291//2291 +f 2291//2291 2146//2146 2296//2296 +f 2299//2299 2310//2310 2312//2312 +f 2315//2315 2316//2316 2305//2305 +f 2305//2305 2316//2316 2313//2313 +f 2313//2313 2317//2317 2298//2298 +f 2298//2298 2317//2317 206//206 +f 2060//2060 2194//2194 2218//2218 +f 1332//1332 1334//1334 2225//2225 +f 2210//2210 1232//1232 2221//2221 +f 2147//2147 2228//2228 1536//1536 +f 2308//2308 2318//2318 2311//2311 +f 2312//2312 2319//2319 2309//2309 +f 2316//2316 2317//2317 2313//2313 +f 2198//2198 1761//1761 1763//1763 +f 1245//1245 1329//1329 1246//1246 +f 1965//1965 52//52 983//983 +f 1965//1965 1937//1937 52//52 +f 510//510 1972//1972 1409//1409 +f 233//233 1284//1284 1258//1258 +f 1407//1407 1406//1406 1933//1933 +f 2310//2310 2319//2319 2312//2312 +f 2314//2314 2320//2320 2315//2315 +f 1354//1354 2321//2321 1708//1708 +f 1806//1806 2205//2205 1726//1726 +f 1555//1555 1509//1509 1516//1516 +f 1332//1332 2225//2225 2215//2215 +f 494//494 245//245 597//597 +f 2322//2322 1519//1519 2306//2306 +f 1938//1938 1523//1523 1936//1936 +f 1434//1434 1433//1433 404//404 +f 404//404 2323//2323 1434//1434 +f 1474//1474 2225//2225 1549//1549 +f 2146//2146 2026//2026 2296//2296 +f 2296//2296 2324//2324 2302//2302 +f 2325//2325 2307//2307 2302//2302 +f 2324//2324 2325//2325 2302//2302 +f 2325//2325 2303//2303 2307//2307 +f 2303//2303 2318//2318 2308//2308 +f 2311//2311 2319//2319 2310//2310 +f 2319//2319 2326//2326 2309//2309 +f 2317//2317 204//204 206//206 +f 994//994 993//993 769//769 +f 1868//1868 462//462 453//453 +f 1095//1095 1768//1768 1147//1147 +f 1650//1650 1649//1649 1920//1920 +f 1715//1715 2176//2176 1762//1762 +f 1054//1054 1976//1976 2037//2037 +f 2321//2321 2327//2327 1277//1277 +f 2133//2133 2132//2132 2139//2139 +f 2296//2296 2026//2026 2324//2324 +f 2326//2326 2320//2320 2314//2314 +f 2309//2309 2326//2326 2314//2314 +f 2320//2320 2328//2328 2315//2315 +f 2315//2315 2328//2328 2316//2316 +f 2316//2316 2329//2329 2317//2317 +f 1873//1873 478//478 1880//1880 +f 2212//2212 2205//2205 2224//2224 +f 1268//1268 1696//1696 1582//1582 +f 1801//1801 2218//2218 426//426 +f 2330//2330 1410//1410 2203//2203 +f 1410//1410 2330//2330 451//451 +f 2327//2327 1278//1278 1277//1277 +f 1433//1433 405//405 404//404 +f 1434//1434 2323//2323 614//614 +f 1999//1999 1998//1998 2008//2008 +f 1227//1227 962//962 1520//1520 +f 2331//2331 2303//2303 2325//2325 +f 2331//2331 2318//2318 2303//2303 +f 2311//2311 2318//2318 2319//2319 +f 2318//2318 2332//2332 2319//2319 +f 2319//2319 2332//2332 2326//2326 +f 2329//2329 204//204 2317//2317 +f 2205//2205 1806//1806 2224//2224 +f 1728//1728 1217//1217 1715//1715 +f 1493//1493 1055//1055 1905//1905 +f 614//614 2323//2323 1962//1962 +f 1215//1215 1217//1217 1728//1728 +f 74//74 1754//1754 75//75 +f 2333//2333 1237//1237 1366//1366 +f 2092//2092 2173//2173 2031//2031 +f 1874//1874 1767//1767 1103//1103 +f 2326//2326 2334//2334 2320//2320 +f 2320//2320 2334//2334 2328//2328 +f 2206//2206 2198//2198 2182//2182 +f 1694//1694 2219//2219 1695//1695 +f 2232//2232 2182//2182 2214//2214 +f 436//436 1855//1855 437//437 +f 2335//2335 2336//2336 2337//2337 +f 1963//1963 2323//2323 404//404 +f 2146//2146 1966//1966 2026//2026 +f 2331//2331 2338//2338 2318//2318 +f 2338//2338 2332//2332 2318//2318 +f 2326//2326 2339//2339 2334//2334 +f 2340//2340 204//204 2329//2329 +f 2192//2192 2194//2194 2060//2060 +f 75//75 1754//1754 1753//1753 +f 1727//1727 2205//2205 2212//2212 +f 680//680 633//633 635//635 +f 2341//2341 1963//1963 404//404 +f 1963//1963 1962//1962 2323//2323 +f 1329//1329 1245//1245 1962//1962 +f 2332//2332 2339//2339 2326//2326 +f 2340//2340 2244//2244 204//204 +f 2244//2244 1485//1485 204//204 +f 2194//2194 2193//2193 1231//1231 +f 394//394 1839//1839 395//395 +f 221//221 1774//1774 2084//2084 +f 2194//2194 1231//1231 2218//2218 +f 2342//2342 2343//2343 278//278 +f 1872//1872 2338//2338 2331//2331 +f 2334//2334 2344//2344 2328//2328 +f 2316//2316 2340//2340 2329//2329 +f 2229//2229 2202//2202 2193//2193 +f 1727//1727 1724//1724 2205//2205 +f 1298//1298 2232//2232 1834//1834 +f 1642//1642 1498//1498 1497//1497 +f 1469//1469 892//892 1262//1262 +f 1727//1727 1729//1729 1724//1724 +f 2345//2345 2325//2325 2324//2324 +f 2345//2345 2331//2331 2325//2325 +f 2332//2332 2346//2346 2339//2339 +f 2346//2346 2334//2334 2339//2339 +f 2328//2328 2344//2344 2316//2316 +f 2316//2316 2344//2344 2340//2340 +f 2127//2127 860//860 1399//1399 +f 1798//1798 577//577 2347//2347 +f 1458//1458 1393//1393 1847//1847 +f 1458//1458 1391//1391 1393//1393 +f 1814//1814 1829//1829 1752//1752 +f 236//236 403//403 631//631 +f 2341//2341 404//404 403//403 +f 2026//2026 2127//2127 2324//2324 +f 2345//2345 1872//1872 2331//2331 +f 2346//2346 2332//2332 2338//2338 +f 2045//2045 2069//2069 2046//2046 +f 173//173 2215//2215 2213//2213 +f 1103//1103 1767//1767 1104//1104 +f 452//452 75//75 453//453 +f 1481//1481 1483//1483 1587//1587 +f 1964//1964 1963//1963 2341//2341 +f 1523//1523 1938//1938 858//858 +f 2026//2026 2022//2022 2127//2127 +f 1399//1399 2324//2324 2127//2127 +f 1399//1399 2345//2345 2324//2324 +f 2346//2346 2348//2348 2334//2334 +f 2349//2349 2344//2344 2334//2334 +f 2348//2348 2349//2349 2334//2334 +f 2349//2349 2350//2350 2344//2344 +f 2350//2350 2340//2340 2344//2344 +f 2340//2340 2350//2350 2244//2244 +f 1724//1724 1729//1729 1725//1725 +f 2192//2192 2196//2196 2193//2193 +f 2343//2343 1481//1481 1587//1587 +f 1587//1587 278//278 2343//2343 +f 1678//1678 1070//1070 1032//1032 +f 2021//2021 2022//2022 2026//2026 +f 1872//1872 2346//2346 2338//2338 +f 554//554 509//509 16//16 +f 2271//2271 2147//2147 2093//2093 +f 1769//1769 1054//1054 1056//1056 +f 152//152 1869//1869 1609//1609 +f 224//224 2133//2133 2150//2150 +f 1399//1399 1185//1185 2345//2345 +f 1184//1184 1872//1872 2345//2345 +f 1871//1871 2346//2346 1872//1872 +f 1871//1871 1906//1906 2346//2346 +f 1838//1838 2346//2346 1906//1906 +f 1838//1838 2348//2348 2346//2346 +f 479//479 480//480 2138//2138 +f 1769//1769 1976//1976 1054//1054 +f 1651//1651 1650//1650 2110//2110 +f 1621//1621 403//403 236//236 +f 1621//1621 2341//2341 403//403 +f 2351//2351 1491//1491 1766//1766 +f 2352//2352 1687//1687 1733//1733 +f 1185//1185 1184//1184 2345//2345 +f 86//86 85//85 1788//1788 +f 1234//1234 1359//1359 1978//1978 +f 1838//1838 1837//1837 2348//2348 +f 1837//1837 2349//2349 2348//2348 +f 2350//2350 1633//1633 2244//2244 +f 1633//1633 1486//1486 2244//2244 +f 1321//1321 1977//1977 1958//1958 +f 90//90 2138//2138 2145//2145 +f 90//90 92//92 2138//2138 +f 1238//1238 588//588 818//818 +f 1998//1998 2038//2038 2014//2014 +f 1302//1302 2040//2040 1518//1518 +f 237//237 631//631 1006//1006 +f 237//237 236//236 631//631 +f 235//235 1621//1621 236//236 +f 1270//1270 2341//2341 1621//1621 +f 1270//1270 1269//1269 1964//1964 +f 2341//2341 1270//1270 1964//1964 +f 2011//2011 1215//1215 2010//2010 +f 2224//2224 1806//1806 1807//1807 +f 1846//1846 2349//2349 1837//1837 +f 324//324 802//802 2216//2216 +f 92//92 479//479 2138//2138 +f 1498//1498 2209//2209 840//840 +f 1840//1840 1533//1533 1809//1809 +f 2174//2174 2119//2119 2223//2223 +f 1406//1406 1832//1832 1823//1823 +f 801//801 2125//2125 2126//2126 +f 1846//1846 2350//2350 2349//2349 +f 2350//2350 1846//1846 1633//1633 +f 1633//1633 1632//1632 1486//1486 +f 1999//1999 2010//2010 1727//1727 +f 64//64 1976//1976 1769//1769 +f 2353//2353 2354//2354 2355//2355 +f 2354//2354 2356//2356 2355//2355 +f 2357//2357 2358//2358 2356//2356 +f 2354//2354 2357//2357 2356//2356 +f 2165//2165 1136//1136 2359//2359 +f 2360//2360 2361//2361 2336//2336 +f 2362//2362 990//990 2363//2363 +f 2364//2364 2365//2365 2366//2366 +f 268//268 2367//2367 269//269 +f 2368//2368 2369//2369 2370//2370 +f 2361//2361 2371//2371 2372//2372 +f 2367//2367 2373//2373 507//507 +f 2250//2250 2372//2372 2368//2368 +f 2374//2374 2000//2000 1369//1369 +f 2375//2375 1301//1301 1300//1300 +f 2322//2322 2376//2376 1519//1519 +f 2364//2364 2377//2377 2365//2365 +f 2378//2378 2355//2355 2356//2356 +f 1495//1495 2379//2379 2380//2380 +f 2365//2365 2377//2377 2366//2366 +f 744//744 1880//1880 477//477 +f 2377//2377 2381//2381 2366//2366 +f 2353//2353 2355//2355 2382//2382 +f 1802//1802 287//287 2162//2162 +f 477//477 28//28 743//743 +f 1684//1684 1792//1792 2383//2383 +f 365//365 1446//1446 464//464 +f 1380//1380 1241//1241 1444//1444 +f 1019//1019 2333//2333 2373//2373 +f 569//569 1893//1893 27//27 +f 2362//2362 2363//2363 2374//2374 +f 1160//1160 446//446 1893//1893 +f 569//569 1160//1160 1893//1893 +f 1534//1534 1533//1533 2384//2384 +f 2385//2385 1218//1218 1219//1219 +f 2385//2385 1898//1898 1218//1218 +f 1898//1898 2377//2377 2364//2364 +f 1551//1551 1008//1008 1020//1020 +f 1767//1767 344//344 1104//1104 +f 1495//1495 949//949 2379//2379 +f 2381//2381 2354//2354 2353//2353 +f 424//424 1218//1218 425//425 +f 2386//2386 2387//2387 1517//1517 +f 2378//2378 2356//2356 2388//2388 +f 2105//2105 2335//2335 2337//2337 +f 2360//2360 2371//2371 2361//2361 +f 2355//2355 2389//2389 2382//2382 +f 949//949 1299//1299 950//950 +f 2355//2355 2378//2378 2389//2389 +f 2380//2380 2379//2379 2358//2358 +f 2368//2368 2370//2370 2251//2251 +f 1987//1987 2390//2390 2391//2391 +f 390//390 2392//2392 1682//1682 +f 1218//1218 1900//1900 2103//2103 +f 2359//2359 1136//1136 1230//1230 +f 989//989 535//535 536//536 +f 137//137 1330//1330 160//160 +f 324//324 1126//1126 325//325 +f 1282//1282 843//843 845//845 +f 418//418 256//256 255//255 +f 1330//1330 2247//2247 1197//1197 +f 2393//2393 2357//2357 2354//2354 +f 2393//2393 1463//1463 2357//2357 +f 2357//2357 1463//1463 2165//2165 +f 2394//2394 2165//2165 2359//2359 +f 2357//2357 2165//2165 2394//2394 +f 2370//2370 1950//1950 2251//2251 +f 949//949 948//948 2379//2379 +f 2366//2366 2381//2381 2353//2353 +f 2335//2335 2395//2395 2336//2336 +f 2396//2396 77//77 1197//1197 +f 2397//2397 2385//2385 1219//1219 +f 2385//2385 2398//2398 1898//1898 +f 2398//2398 2377//2377 1898//1898 +f 2389//2389 2378//2378 2399//2399 +f 2398//2398 2400//2400 2377//2377 +f 2400//2400 2381//2381 2377//2377 +f 2104//2104 1900//1900 1899//1899 +f 1330//1330 1197//1197 160//160 +f 2247//2247 2396//2396 1197//1197 +f 77//77 2396//2396 2401//2401 +f 1465//1465 2354//2354 2381//2381 +f 1465//1465 2393//2393 2354//2354 +f 1218//1218 2103//2103 712//712 +f 1240//1240 1237//1237 2333//2333 +f 2123//2123 2169//2169 2402//2402 +f 2006//2006 2137//2137 2251//2251 +f 1019//1019 1240//1240 2333//2333 +f 949//949 1495//1495 1306//1306 +f 2107//2107 1300//1300 2386//2386 +f 2247//2247 1350//1350 2396//2396 +f 1666//1666 1346//1346 2403//2403 +f 2005//2005 2336//2336 2137//2137 +f 2004//2004 1903//1903 2005//2005 +f 2404//2404 1903//1903 2004//2004 +f 1533//1533 1901//1901 2384//2384 +f 2061//2061 284//284 2047//2047 +f 1350//1350 1987//1987 2396//2396 +f 2396//2396 1987//1987 2391//2391 +f 2391//2391 2405//2405 2396//2396 +f 2396//2396 2405//2405 2401//2401 +f 2359//2359 2380//2380 2394//2394 +f 1901//1901 2404//2404 2384//2384 +f 2107//2107 2386//2386 2106//2106 +f 2406//2406 1902//1902 2407//2407 +f 2405//2405 2408//2408 2401//2401 +f 2401//2401 2408//2408 2403//2403 +f 1464//1464 2381//2381 2400//2400 +f 1464//1464 1465//1465 2381//2381 +f 1140//1140 1139//1139 1147//1147 +f 2106//2106 2386//2386 2409//2409 +f 2106//2106 2409//2409 1534//1534 +f 2251//2251 2375//2375 2107//2107 +f 1384//1384 2407//2407 1471//1471 +f 2407//2407 1840//1840 1471//1471 +f 2408//2408 2410//2410 2403//2403 +f 2403//2403 2410//2410 1666//1666 +f 1900//1900 2104//2104 2103//2103 +f 35//35 1257//1257 33//33 +f 2409//2409 1517//1517 2411//2411 +f 1798//1798 2412//2412 1813//1813 +f 2410//2410 2413//2413 1666//1666 +f 2103//2103 2337//2337 1902//1902 +f 2373//2373 2333//2333 1368//1368 +f 2333//2333 1366//1366 1368//1368 +f 2409//2409 2386//2386 1517//1517 +f 2376//2376 1532//1532 2411//2411 +f 988//988 1239//1239 989//989 +f 2405//2405 2414//2414 2408//2408 +f 2408//2408 2414//2414 2410//2410 +f 2415//2415 333//333 332//332 +f 2386//2386 1300//1300 2387//2387 +f 1950//1950 1353//1353 2375//2375 +f 1845//1845 2413//2413 2410//2410 +f 1758//1758 1765//1765 1845//1845 +f 2337//2337 2103//2103 2105//2105 +f 1570//1570 816//816 1265//1265 +f 1520//1520 2000//2000 1227//1227 +f 2391//2391 2390//2390 2405//2405 +f 576//576 323//323 325//325 +f 2373//2373 1368//1368 2416//2416 +f 1305//1305 1219//1219 1172//1172 +f 760//760 1577//1577 694//694 +f 728//728 760//760 694//694 +f 113//113 1548//1548 25//25 +f 1758//1758 1766//1766 1747//1747 +f 1548//1548 80//80 25//25 +f 1809//1809 893//893 2417//2417 +f 2363//2363 536//536 1225//1225 +f 1301//1301 1353//1353 1707//1707 +f 2390//2390 2418//2418 2405//2405 +f 2418//2418 2414//2414 2405//2405 +f 2414//2414 2419//2419 2410//2410 +f 2420//2420 1845//1845 2410//2410 +f 2420//2420 1758//1758 1845//1845 +f 2399//2399 2421//2421 1948//1948 +f 1305//1305 2397//2397 1219//1219 +f 2421//2421 1949//1949 1948//1948 +f 1746//1746 1780//1780 1790//1790 +f 1440//1440 1413//1413 184//184 +f 1445//1445 365//365 367//367 +f 893//893 2376//2376 2322//2322 +f 332//332 334//334 1353//1353 +f 2410//2410 2419//2419 2420//2420 +f 2373//2373 2416//2416 507//507 +f 984//984 356//356 267//267 +f 1014//1014 263//263 230//230 +f 1480//1480 1014//1014 230//230 +f 2411//2411 1517//1517 1519//1519 +f 2376//2376 2411//2411 1519//1519 +f 2422//2422 2370//2370 2369//2369 +f 1301//1301 1707//1707 1302//1302 +f 2417//2417 893//893 892//892 +f 1822//1822 2390//2390 1942//1942 +f 1480//1480 1015//1015 1014//1014 +f 795//795 1666//1666 2413//2413 +f 2403//2403 1346//1346 2401//2401 +f 893//893 1809//1809 2376//2376 +f 2417//2417 892//892 1469//1469 +f 2423//2423 2414//2414 2418//2418 +f 2423//2423 2419//2419 2414//2414 +f 2420//2420 1766//1766 1758//1758 +f 1346//1346 77//77 2401//2401 +f 2424//2424 2400//2400 2398//2398 +f 2424//2424 1499//1499 2400//2400 +f 2395//2395 2360//2360 2336//2336 +f 1463//1463 1076//1076 1136//1136 +f 1684//1684 1349//1349 1348//1348 +f 1546//1546 1829//1829 1547//1547 +f 2419//2419 2351//2351 2420//2420 +f 2420//2420 2351//2351 1766//1766 +f 245//245 648//648 246//246 +f 334//334 2425//2425 1354//1354 +f 2375//2375 1300//1300 2107//2107 +f 1499//1499 1464//1464 2400//2400 +f 295//295 947//947 649//649 +f 1009//1009 1271//1271 114//114 +f 283//283 282//282 1009//1009 +f 1271//1271 2426//2426 1489//1489 +f 1548//1548 1829//1829 1546//1546 +f 1353//1353 1354//1354 1707//1707 +f 989//989 536//536 2363//2363 +f 2162//2162 2418//2418 2390//2390 +f 2162//2162 2423//2423 2418//2418 +f 2061//2061 2427//2427 284//284 +f 2425//2425 2327//2327 1354//1354 +f 1109//1109 1645//1645 1281//1281 +f 282//282 2426//2426 1009//1009 +f 113//113 1489//1489 1548//1548 +f 1950//1950 332//332 1353//1353 +f 2162//2162 2390//2390 1822//1822 +f 990//990 989//989 2363//2363 +f 1436//1436 2393//2393 1465//1465 +f 1436//1436 1463//1463 2393//2393 +f 1489//1489 2428//2428 1548//1548 +f 2428//2428 1829//1829 1548//1548 +f 1226//1226 1225//1225 169//169 +f 1291//1291 2423//2423 2162//2162 +f 2419//2419 1843//1843 2351//2351 +f 1843//1843 1491//1491 2351//2351 +f 2379//2379 2362//2362 2358//2358 +f 2372//2372 2371//2371 2369//2369 +f 1436//1436 1464//1464 1437//1437 +f 284//284 2429//2429 282//282 +f 2430//2430 2431//2431 282//282 +f 282//282 2431//2431 2426//2426 +f 1235//1235 495//495 1562//1562 +f 1732//1732 1608//1608 1607//1607 +f 1802//1802 2162//2162 1822//1822 +f 2432//2432 2419//2419 2423//2423 +f 2419//2419 2432//2432 1843//1843 +f 2362//2362 2374//2374 2358//2358 +f 2421//2421 2378//2378 2388//2388 +f 2336//2336 2361//2361 2137//2137 +f 2427//2427 2429//2429 284//284 +f 2429//2429 2430//2430 282//282 +f 2367//2367 507//507 269//269 +f 1133//1133 2407//2407 1444//1444 +f 1869//1869 1662//1662 436//436 +f 2432//2432 2423//2423 1291//1291 +f 2250//2250 2368//2368 2251//2251 +f 2433//2433 2389//2389 2399//2399 +f 2431//2431 2434//2434 2426//2426 +f 2337//2337 2336//2336 1903//1903 +f 229//229 200//200 1843//1843 +f 1801//1801 428//428 2427//2427 +f 2426//2426 2435//2435 1489//1489 +f 2435//2435 2436//2436 1489//1489 +f 1489//1489 2436//2436 2428//2428 +f 1512//1512 2168//2168 2118//2118 +f 1020//1020 2373//2373 2367//2367 +f 268//268 1020//1020 2367//2367 +f 2347//2347 577//577 579//579 +f 2437//2437 2432//2432 1291//1291 +f 2432//2432 229//229 1843//1843 +f 1803//1803 1796//1796 1798//1798 +f 74//74 579//579 1754//1754 +f 428//428 2438//2438 2427//2427 +f 2438//2438 2439//2439 2427//2427 +f 2427//2427 2439//2439 2429//2429 +f 2429//2429 2431//2431 2430//2430 +f 2431//2431 2440//2440 2434//2434 +f 2436//2436 2441//2441 2428//2428 +f 2441//2441 1829//1829 2428//2428 +f 2441//2441 1752//1752 1829//1829 +f 1682//1682 2442//2442 2068//2068 +f 107//107 1460//1460 1263//1263 +f 2330//2330 2443//2443 74//74 +f 76//76 2330//2330 74//74 +f 2429//2429 2439//2439 2431//2431 +f 2439//2439 2444//2444 2431//2431 +f 2431//2431 2444//2444 2440//2440 +f 1840//1840 1809//1809 1841//1841 +f 2384//2384 2404//2404 2106//2106 +f 1005//1005 2437//2437 1291//1291 +f 2437//2437 1480//1480 2432//2432 +f 2432//2432 1480//1480 229//229 +f 1374//1374 1317//1317 1316//1316 +f 74//74 2443//2443 579//579 +f 1367//1367 1499//1499 2424//2424 +f 2440//2440 2435//2435 2426//2426 +f 2434//2434 2440//2440 2426//2426 +f 1471//1471 2417//2417 1469//1469 +f 2106//2106 2404//2404 2004//2004 +f 1798//1798 1783//1783 577//577 +f 1034//1034 2437//2437 1005//1005 +f 1480//1480 230//230 229//229 +f 2389//2389 2371//2371 2360//2360 +f 2203//2203 2443//2443 2330//2330 +f 2438//2438 2445//2445 2439//2439 +f 2446//2446 2444//2444 2439//2439 +f 2444//2444 2447//2447 2440//2440 +f 2435//2435 2448//2448 2436//2436 +f 2436//2436 2448//2448 2441//2441 +f 2363//2363 1225//1225 2000//2000 +f 2387//2387 1300//1300 1302//1302 +f 1302//1302 1707//1707 2040//2040 +f 1034//1034 1480//1480 2437//2437 +f 2433//2433 2369//2369 2371//2371 +f 2433//2433 2422//2422 2369//2369 +f 2203//2203 2449//2449 2443//2443 +f 1177//1177 1178//1178 1459//1459 +f 1235//1235 1161//1161 568//568 +f 2445//2445 2446//2446 2439//2439 +f 2447//2447 2450//2450 2440//2440 +f 2448//2448 2451//2451 2441//2441 +f 2452//2452 1752//1752 2441//2441 +f 2451//2451 2452//2452 2441//2441 +f 1752//1752 2452//2452 1445//1445 +f 1790//1790 1684//1684 1625//1625 +f 578//578 577//577 1783//1783 +f 1033//1033 1034//1034 1005//1005 +f 1230//1230 1206//1206 2359//2359 +f 1225//1225 536//536 169//169 +f 2389//2389 2433//2433 2371//2371 +f 1020//1020 1019//1019 2373//2373 +f 2453//2453 579//579 2443//2443 +f 2449//2449 2453//2453 2443//2443 +f 2453//2453 2347//2347 579//579 +f 1436//1436 1077//1077 1463//1463 +f 2435//2435 2454//2454 2448//2448 +f 2382//2382 2389//2389 2455//2455 +f 278//278 1813//1813 2342//2342 +f 427//427 2438//2438 428//428 +f 2446//2446 2447//2447 2444//2444 +f 2440//2440 2450//2450 2454//2454 +f 2440//2440 2454//2454 2435//2435 +f 1149//1149 1367//1367 583//583 +f 1354//1354 2327//2327 2321//2321 +f 2107//2107 2004//2004 2006//2006 +f 2068//2068 2442//2442 2438//2438 +f 427//427 2068//2068 2438//2438 +f 2438//2438 2442//2442 2445//2445 +f 2452//2452 1446//1446 1445//1445 +f 1905//1905 2017//2017 1857//1857 +f 1662//1662 1661//1661 1615//1615 +f 2416//2416 2398//2398 2385//2385 +f 2416//2416 2424//2424 2398//2398 +f 1972//1972 2456//2456 1409//1409 +f 2457//2457 2203//2203 1409//1409 +f 2456//2456 2457//2457 1409//1409 +f 2457//2457 2449//2449 2203//2203 +f 2412//2412 2347//2347 2453//2453 +f 2347//2347 2412//2412 1798//1798 +f 40//40 41//41 2091//2091 +f 2445//2445 2442//2442 1682//1682 +f 2446//2446 2458//2458 2447//2447 +f 2459//2459 2452//2452 2451//2451 +f 2459//2459 1446//1446 2452//2452 +f 1349//1349 1094//1094 1347//1347 +f 2460//2460 2453//2453 2449//2449 +f 1682//1682 2392//2392 2445//2445 +f 2461//2461 2458//2458 2446//2446 +f 2458//2458 2462//2462 2447//2447 +f 2447//2447 2462//2462 2450//2450 +f 2448//2448 2459//2459 2451//2451 +f 1534//1534 2384//2384 2106//2106 +f 2399//2399 2378//2378 2421//2421 +f 2357//2357 2394//2394 2358//2358 +f 1899//1899 1898//1898 2364//2364 +f 2460//2460 2412//2412 2453//2453 +f 2399//2399 2422//2422 2433//2433 +f 1987//1987 1942//1942 2390//2390 +f 1594//1594 1628//1628 2019//2019 +f 2445//2445 2461//2461 2446//2446 +f 2463//2463 2450//2450 2462//2462 +f 2450//2450 2463//2463 2454//2454 +f 2464//2464 2459//2459 2448//2448 +f 2361//2361 2372//2372 2250//2250 +f 2137//2137 2361//2361 2250//2250 +f 1541//1541 1020//1020 268//268 +f 2463//2463 2464//2464 2454//2454 +f 2454//2454 2464//2464 2448//2448 +f 1366//1366 1237//1237 582//582 +f 53//53 2456//2456 1972//1972 +f 2392//2392 2461//2461 2445//2445 +f 2091//2091 283//283 40//40 +f 2455//2455 2389//2389 2360//2360 +f 1305//1305 508//508 2397//2397 +f 508//508 2385//2385 2397//2397 +f 591//591 590//590 1704//1704 +f 2465//2465 2457//2457 2456//2456 +f 2466//2466 2449//2449 2457//2457 +f 2466//2466 2460//2460 2449//2449 +f 508//508 2416//2416 2385//2385 +f 1366//1366 582//582 1367//1367 +f 76//76 451//451 2330//2330 +f 1687//1687 2462//2462 2458//2458 +f 1687//1687 2463//2463 2462//2462 +f 1306//1306 1299//1299 949//949 +f 2387//2387 1302//1302 1517//1517 +f 249//249 560//560 547//547 +f 1687//1687 2352//2352 2463//2463 +f 2352//2352 2464//2464 2463//2463 +f 2467//2467 2468//2468 2459//2459 +f 2459//2459 2468//2468 1446//1446 +f 1149//1149 1499//1499 1367//1367 +f 2465//2465 2456//2456 53//53 +f 830//830 1615//1615 1661//1661 +f 2464//2464 2467//2467 2459//2459 +f 333//333 2425//2425 334//334 +f 1227//1227 2000//2000 1225//1225 +f 1966//1966 1947//1947 1469//1469 +f 52//52 2469//2469 53//53 +f 2469//2469 2465//2465 53//53 +f 2412//2412 2460//2460 1813//1813 +f 2460//2460 2342//2342 1813//1813 +f 1481//1481 2343//2343 1780//1780 +f 401//401 400//400 414//414 +f 162//162 164//164 151//151 +f 1948//1948 1950//1950 2370//2370 +f 1523//1523 2470//2470 1937//1937 +f 2470//2470 2469//2469 1937//1937 +f 1937//1937 2469//2469 52//52 +f 2342//2342 1792//1792 1780//1780 +f 1780//1780 1792//1792 1790//1790 +f 2467//2467 2464//2464 2352//2352 +f 2468//2468 464//464 1446//1446 +f 1902//1902 2337//2337 1903//1903 +f 2107//2107 2006//2006 2251//2251 +f 1524//1524 2471//2471 1523//1523 +f 2471//2471 2470//2470 1523//1523 +f 2471//2471 2472//2472 2470//2470 +f 2472//2472 2469//2469 2470//2470 +f 2473//2473 2457//2457 2465//2465 +f 2473//2473 2466//2466 2457//2457 +f 2460//2460 2474//2474 2342//2342 +f 743//743 27//27 1893//1893 +f 1534//1534 2409//2409 2411//2411 +f 2469//2469 2475//2475 2465//2465 +f 2475//2475 2476//2476 2465//2465 +f 2473//2473 2477//2477 2466//2466 +f 2466//2466 2478//2478 2460//2460 +f 2478//2478 2474//2474 2460//2460 +f 2474//2474 1792//1792 2342//2342 +f 1733//1733 1737//1737 2352//2352 +f 1737//1737 2467//2467 2352//2352 +f 496//496 464//464 2468//2468 +f 2472//2472 2475//2475 2469//2469 +f 2467//2467 2479//2479 2468//2468 +f 2479//2479 496//496 2468//2468 +f 1218//1218 1898//1898 1900//1900 +f 1528//1528 1553//1553 1524//1524 +f 1553//1553 2471//2471 1524//1524 +f 2471//2471 2480//2480 2472//2472 +f 2465//2465 2481//2481 2473//2473 +f 2474//2474 2383//2383 1792//1792 +f 1008//1008 1063//1063 1019//1019 +f 1532//1532 1534//1534 2411//2411 +f 1554//1554 1553//1553 1528//1528 +f 2482//2482 2465//2465 2476//2476 +f 2482//2482 2481//2481 2465//2465 +f 2483//2483 2473//2473 2481//2481 +f 2477//2477 2223//2223 2466//2466 +f 2223//2223 2478//2478 2466//2466 +f 2478//2478 2484//2484 2474//2474 +f 2383//2383 1349//1349 1684//1684 +f 2483//2483 2481//2481 2482//2482 +f 2485//2485 2383//2383 2474//2474 +f 2426//2426 1271//1271 1009//1009 +f 1607//1607 2467//2467 1737//1737 +f 1809//1809 1532//1532 2376//2376 +f 2486//2486 2480//2480 2471//2471 +f 2475//2475 2472//2472 2480//2480 +f 2487//2487 2475//2475 2480//2480 +f 2485//2485 1349//1349 2383//2383 +f 507//507 2416//2416 508//508 +f 1607//1607 2479//2479 2467//2467 +f 1841//1841 1809//1809 2417//2417 +f 2251//2251 1950//1950 2375//2375 +f 2379//2379 948//948 2362//2362 +f 2488//2488 2480//2480 2486//2486 +f 2488//2488 2489//2489 2480//2480 +f 2489//2489 2487//2487 2480//2480 +f 2484//2484 2485//2485 2474//2474 +f 2485//2485 1352//1352 1349//1349 +f 859//859 1940//1940 860//860 +f 40//40 1009//1009 114//114 +f 2479//2479 2490//2490 496//496 +f 496//496 1128//1128 465//465 +f 2380//2380 2359//2359 1495//1495 +f 1368//1368 1367//1367 2424//2424 +f 2486//2486 2471//2471 1553//1553 +f 1141//1141 2485//2485 2484//2484 +f 436//436 1662//1662 1855//1855 +f 2427//2427 2061//2061 1801//1801 +f 1607//1607 2490//2490 2479//2479 +f 2490//2490 1128//1128 496//496 +f 465//465 593//593 550//550 +f 2491//2491 2488//2488 2486//2486 +f 2491//2491 2492//2492 2488//2488 +f 2492//2492 2493//2493 2488//2488 +f 2493//2493 2489//2489 2488//2488 +f 2124//2124 2476//2476 2475//2475 +f 2413//2413 1845//1845 795//795 +f 2359//2359 1206//1206 1495//1495 +f 1607//1607 456//456 2490//2490 +f 456//456 1128//1128 2490//2490 +f 1841//1841 2417//2417 1471//1471 +f 1901//1901 1533//1533 1840//1840 +f 894//894 2486//2486 1553//1553 +f 1140//1140 1352//1352 2485//2485 +f 2407//2407 1902//1902 1840//1840 +f 2394//2394 2380//2380 2358//2358 +f 1133//1133 712//712 2407//2407 +f 2343//2343 2342//2342 1780//1780 +f 2494//2494 2486//2486 894//894 +f 2494//2494 2491//2491 2486//2486 +f 2124//2124 2482//2482 2476//2476 +f 2482//2482 2495//2495 2483//2483 +f 2496//2496 2478//2478 2223//2223 +f 2496//2496 2497//2497 2478//2478 +f 2497//2497 2484//2484 2478//2478 +f 1140//1140 2485//2485 1141//1141 +f 1768//1768 1352//1352 1140//1140 +f 1352//1352 1768//1768 1094//1094 +f 712//712 2406//2406 2407//2407 +f 1707//1707 1354//1354 1708//1708 +f 456//456 592//592 1128//1128 +f 948//948 950//950 2362//2362 +f 950//950 990//990 2362//2362 +f 1552//1552 894//894 1553//1553 +f 2498//2498 2491//2491 2494//2494 +f 2499//2499 2493//2493 2492//2492 +f 2499//2499 2500//2500 2493//2493 +f 2124//2124 2475//2475 2487//2487 +f 2497//2497 1141//1141 2484//2484 +f 269//269 508//508 1305//1305 +f 2388//2388 1949//1949 2421//2421 +f 1950//1950 2115//2115 332//332 +f 2227//2227 1394//1394 1530//1530 +f 2501//2501 2492//2492 2491//2491 +f 2501//2501 2499//2499 2492//2492 +f 1709//1709 2500//2500 2499//2499 +f 2502//2502 2482//2482 2124//2124 +f 2502//2502 2495//2495 2482//2482 +f 429//429 365//365 464//464 +f 2416//2416 1368//1368 2424//2424 +f 712//712 2103//2103 2406//2406 +f 2491//2491 2498//2498 2501//2501 +f 1903//1903 2336//2336 2005//2005 +f 2399//2399 1948//1948 2422//2422 +f 2372//2372 2369//2369 2368//2368 +f 1902//1902 1901//1901 1840//1840 +f 1901//1901 1903//1903 2404//2404 +f 2033//2033 2499//2499 2501//2501 +f 1983//1983 2497//2497 2496//2496 +f 2406//2406 2103//2103 1902//1902 +f 2498//2498 2306//2306 2501//2501 +f 2033//2033 1709//1709 2499//2499 +f 1983//1983 1141//1141 2497//2497 +f 2422//2422 1948//1948 2370//2370 +f 2115//2115 2415//2415 332//332 +f 990//990 950//950 988//988 +f 1518//1518 2501//2501 2306//2306 +f 1518//1518 2033//2033 2501//2501 +f 2124//2124 2123//2123 2502//2502 +f 2502//2502 2123//2123 2495//2495 +f 1370//1370 1983//1983 2496//2496 +f 1262//1262 894//894 1552//1552 +f 2498//2498 2322//2322 2306//2306 +f 1139//1139 1141//1141 1983//1983 +f 1094//1094 1768//1768 1095//1095 +f 2363//2363 2000//2000 2374//2374 +f 1444//1444 2407//2407 1384//1384 +f 2375//2375 1353//1353 1301//1301 +f 893//893 2494//2494 894//894 +f 893//893 2322//2322 2498//2498 +f 2494//2494 893//893 2498//2498 +f 2123//2123 2402//2402 2495//2495 +f 1370//1370 2496//2496 2223//2223 +f 1687//1687 2458//2458 2503//2503 +f 2458//2458 2461//2461 2503//2503 +f 2461//2461 2392//2392 2503//2503 +f 2392//2392 390//390 2503//2503 +f 390//390 389//389 2503//2503 +f 389//389 1416//1416 2503//2503 +f 1416//1416 1687//1687 2503//2503 diff --git a/A4/shadow8t4/shadow8t4/resources/cube.obj b/A4/shadow8t4/shadow8t4/resources/cube.obj new file mode 100644 index 0000000..e81edd5 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/resources/cube.obj @@ -0,0 +1,29 @@ +# Blender v2.71 (sub 0) OBJ File: '' +# www.blender.org +v 0.500000 0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 1.000000 +vn 1.000000 -0.000000 -0.000000 +vn -0.000000 -1.000000 -0.000000 +vn -1.000000 0.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +s off +f 2//1 3//1 4//1 +f 8//2 7//2 6//2 +f 1//3 5//3 6//3 +f 2//4 6//4 7//4 +f 7//5 8//5 4//5 +f 1//6 4//6 8//6 +f 1//1 2//1 4//1 +f 5//2 8//2 6//2 +f 2//3 1//3 6//3 +f 3//4 2//4 7//4 +f 3//5 7//5 4//5 +f 5//6 1//6 8//6 diff --git a/A4/shadow8t4/shadow8t4/resources/frag.glsl b/A4/shadow8t4/shadow8t4/resources/frag.glsl new file mode 100644 index 0000000..ff05fa8 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/resources/frag.glsl @@ -0,0 +1,37 @@ +#version 120 + +uniform mat4 MVL; +uniform vec3 lightPos1; +uniform vec3 lightPos2; +uniform vec3 ka; +uniform vec3 kd; +uniform vec3 ks; +uniform float s; +uniform float i1; +uniform float i2; + +varying vec3 color; // passed from the vertex shader +varying vec4 p; +varying vec4 n; + +void main() +{ + vec4 normal = normalize(n); + vec3 norm = vec3(normal.x, normal.y, normal.z); + + vec4 npos = normalize(p); + vec3 pos = vec3(npos.x, npos.y, npos.z); + + vec3 lightnorm = vec3(MVL[3].x, MVL[3].y, MVL[3].z); + + vec3 light = lightnorm - vec3(p.x, p.y, p.z); + vec3 lnorm = normalize(vec3(light.x,light.y,light.z)); + float temp = dot(lnorm, norm); + vec3 cd = kd*max(0, temp); + + vec3 h = normalize(lnorm - pos); + vec3 cs = ks*pow(max(0, dot(h, norm)), s); + + vec4 c = vec4(ka.r + cd.r + cs.r, ka.g + cd.g + cs.g, ka.b + cd.b + cs.b, 1.0); + gl_FragColor = c; +} diff --git a/A4/shadow8t4/shadow8t4/resources/sil.glsl b/A4/shadow8t4/shadow8t4/resources/sil.glsl new file mode 100644 index 0000000..ba512f1 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/resources/sil.glsl @@ -0,0 +1,20 @@ +#version 120 + +varying vec4 p; +varying vec4 n; + +void main() +{ + vec4 normal = normalize(n); + vec3 norm = vec3(normal.x, normal.y, normal.z); + + vec4 npos = normalize(p); + vec3 pos = vec3(npos.x, npos.y, npos.z); + + float product = dot(norm, pos); + + if(product <= 0.3 && product >= -0.3) + gl_FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f); + else + gl_FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); +} diff --git a/A4/shadow8t4/shadow8t4/resources/sphere.obj b/A4/shadow8t4/shadow8t4/resources/sphere.obj new file mode 100644 index 0000000..698f5ce --- /dev/null +++ b/A4/shadow8t4/shadow8t4/resources/sphere.obj @@ -0,0 +1,204 @@ +#### +# +# OBJ File Generated by LightWave3D +# LightWave3D OBJ Export v2.2 +# +#### +# +# Vertices: 62 +# Points: 0 +# Lines: 0 +# Faces: 120 +# Materials: 1 +# +#### + +# Vertex list + +v 0 -0.5 -0 +v 0.25 -0.433013 -0 +v 0.216506 -0.433013 -0.125 +v 0.125 -0.433013 -0.216506 +v 0 -0.433013 -0.25 +v -0.125 -0.433013 -0.216506 +v -0.216506 -0.433013 -0.125 +v -0.25 -0.433013 -0 +v -0.216506 -0.433013 0.125 +v -0.125 -0.433013 0.216506 +v 0 -0.433013 0.25 +v 0.125 -0.433013 0.216506 +v 0.216506 -0.433013 0.125 +v 0.433013 -0.25 -0 +v 0.375 -0.25 -0.216506 +v 0.216506 -0.25 -0.375 +v 0 -0.25 -0.433013 +v -0.216506 -0.25 -0.375 +v -0.375 -0.25 -0.216506 +v -0.433013 -0.25 -0 +v -0.375 -0.25 0.216506 +v -0.216506 -0.25 0.375 +v 0 -0.25 0.433013 +v 0.216506 -0.25 0.375 +v 0.375 -0.25 0.216506 +v 0.5 2.55171e-12 -0 +v 0.433013 2.55171e-12 -0.25 +v 0.25 2.55171e-12 -0.433013 +v 0 2.55171e-12 -0.5 +v -0.25 2.55171e-12 -0.433013 +v -0.433013 2.55171e-12 -0.25 +v -0.5 2.55171e-12 -0 +v -0.433013 2.55171e-12 0.25 +v -0.25 2.55171e-12 0.433013 +v 0 2.55171e-12 0.5 +v 0.25 2.55171e-12 0.433013 +v 0.433013 2.55171e-12 0.25 +v 0.433013 0.25 -0 +v 0.375 0.25 -0.216506 +v 0.216506 0.25 -0.375 +v 0 0.25 -0.433013 +v -0.216506 0.25 -0.375 +v -0.375 0.25 -0.216506 +v -0.433013 0.25 -0 +v -0.375 0.25 0.216506 +v -0.216506 0.25 0.375 +v 0 0.25 0.433013 +v 0.216506 0.25 0.375 +v 0.375 0.25 0.216506 +v 0.25 0.433013 -0 +v 0.216506 0.433013 -0.125 +v 0.125 0.433013 -0.216506 +v 0 0.433013 -0.25 +v -0.125 0.433013 -0.216506 +v -0.216506 0.433013 -0.125 +v -0.25 0.433013 -0 +v -0.216506 0.433013 0.125 +v -0.125 0.433013 0.216506 +v 0 0.433013 0.25 +v 0.125 0.433013 0.216506 +v 0.216506 0.433013 0.125 +v 5.10341e-12 0.5 -0 + +# Face list + +f 3 2 1 +f 4 3 1 +f 5 4 1 +f 6 5 1 +f 7 6 1 +f 8 7 1 +f 9 8 1 +f 10 9 1 +f 11 10 1 +f 12 11 1 +f 13 12 1 +f 2 13 1 +f 3 14 2 +f 15 14 3 +f 4 15 3 +f 16 15 4 +f 17 16 4 +f 5 17 4 +f 17 5 6 +f 18 17 6 +f 18 6 7 +f 19 18 7 +f 20 7 8 +f 20 19 7 +f 20 8 9 +f 21 20 9 +f 21 9 10 +f 22 21 10 +f 23 10 11 +f 23 22 10 +f 12 23 11 +f 24 23 12 +f 13 24 12 +f 25 24 13 +f 14 25 13 +f 2 14 13 +f 15 26 14 +f 27 26 15 +f 28 27 15 +f 16 28 15 +f 29 28 16 +f 17 29 16 +f 29 17 18 +f 30 29 18 +f 31 18 19 +f 31 30 18 +f 32 19 20 +f 32 31 19 +f 32 20 21 +f 33 32 21 +f 34 21 22 +f 34 33 21 +f 35 22 23 +f 35 34 22 +f 24 35 23 +f 36 35 24 +f 37 36 24 +f 25 37 24 +f 26 37 25 +f 14 26 25 +f 39 38 26 +f 27 39 26 +f 28 39 27 +f 40 39 28 +f 29 40 28 +f 41 40 29 +f 42 29 30 +f 42 41 29 +f 43 30 31 +f 43 42 30 +f 43 31 32 +f 44 43 32 +f 45 32 33 +f 45 44 32 +f 45 33 34 +f 46 45 34 +f 46 34 35 +f 47 46 35 +f 48 47 35 +f 36 48 35 +f 49 48 36 +f 37 49 36 +f 26 49 37 +f 38 49 26 +f 39 50 38 +f 51 50 39 +f 40 51 39 +f 52 51 40 +f 53 52 40 +f 41 53 40 +f 53 41 42 +f 54 53 42 +f 55 42 43 +f 55 54 42 +f 56 43 44 +f 56 55 43 +f 56 44 45 +f 57 56 45 +f 58 45 46 +f 58 57 45 +f 58 46 47 +f 59 58 47 +f 60 59 47 +f 48 60 47 +f 49 60 48 +f 61 60 49 +f 50 61 49 +f 38 50 49 +f 51 62 50 +f 52 62 51 +f 53 62 52 +f 62 53 54 +f 62 54 55 +f 62 55 56 +f 62 56 57 +f 62 57 58 +f 62 58 59 +f 60 62 59 +f 61 62 60 +f 50 62 61 + +# End of file diff --git a/A4/shadow8t4/shadow8t4/resources/teapot.obj b/A4/shadow8t4/shadow8t4/resources/teapot.obj new file mode 100644 index 0000000..6fed453 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/resources/teapot.obj @@ -0,0 +1,5049 @@ +# Blender v2.65 (sub 0) OBJ File +# www.blender.org +o teapot.005 +v -0.498530 0.712498 -0.039883 +v -0.501666 0.699221 -0.063813 +v -0.501255 0.717792 0.000000 +v -0.624036 0.711938 -0.039883 +v -0.526706 0.651362 -0.039883 +v -0.508714 0.682112 -0.071712 +v -0.622039 0.698704 -0.063813 +v -0.624834 0.717232 0.000000 +v -0.498530 0.712498 0.039883 +v -0.638129 0.287158 0.000000 +v -0.517593 0.664661 -0.063813 +v -0.534329 0.646030 0.000000 +v -0.614850 0.651067 -0.039883 +v -0.616848 0.664299 -0.063813 +v -0.619445 0.681503 -0.071790 +v -0.741245 0.707456 -0.039883 +v -0.744483 0.712577 0.000000 +v -0.624036 0.711938 0.039883 +v -0.501667 0.699221 0.063813 +v -0.622039 0.698704 0.063813 +v -0.712095 0.661370 -0.063813 +v -0.733150 0.694655 -0.063813 +v -0.741245 0.707456 0.039883 +v -0.733150 0.694655 0.063813 +v -0.631184 0.277569 -0.039883 +v -0.526706 0.651362 0.039883 +v -0.614053 0.645774 0.000000 +v -0.704000 0.648569 -0.039883 +v -0.722621 0.678012 -0.071790 +v -0.832523 0.695296 -0.039883 +v -0.837545 0.699948 0.000000 +v -0.832523 0.695296 0.039883 +v -0.619445 0.681503 0.071790 +v -0.508714 0.682112 0.071712 +v -0.722621 0.678012 0.071790 +v -0.517593 0.664661 0.063813 +v -0.619922 0.238069 -0.071790 +v -0.624826 0.259599 -0.063813 +v -0.710066 0.328372 0.000000 +v -0.614850 0.651067 0.039883 +v -0.787321 0.653419 -0.063813 +v -0.803644 0.668539 -0.071790 +v -0.819967 0.683663 -0.063813 +v -0.819967 0.683663 0.063813 +v -0.803644 0.668539 0.071790 +v -0.711425 0.307332 -0.063813 +v -0.615553 0.216807 -0.063813 +v -0.712688 0.287795 -0.071790 +v -0.631184 0.277569 0.039883 +v -0.710455 0.322361 -0.039883 +v -0.710455 0.322361 0.039883 +v -0.700762 0.643448 0.000000 +v -0.774766 0.641786 -0.039883 +v -0.897800 0.671612 -0.039883 +v -0.904015 0.675354 0.000000 +v -0.897800 0.671612 0.039883 +v -0.882265 0.662257 0.063813 +v -0.712095 0.661370 0.063813 +v -0.787321 0.653419 0.063813 +v -0.608884 0.198682 -0.039883 +v -0.624828 0.259599 0.063813 +v -0.766936 0.377559 0.000000 +v -0.769651 0.372307 0.039883 +v -0.616848 0.664299 0.063813 +v -0.704000 0.648569 0.039883 +v -0.841868 0.637931 -0.063813 +v -0.862065 0.650094 -0.071790 +v -0.882265 0.662257 -0.063813 +v -0.862065 0.650094 0.071790 +v -0.841868 0.637931 0.063813 +v -0.611709 0.194244 0.000000 +v -0.776434 0.359177 -0.063813 +v -0.769651 0.372307 -0.039883 +v -0.713952 0.268259 -0.063813 +v -0.711425 0.307332 0.063813 +v -0.776434 0.359177 0.063813 +v -0.769743 0.637131 0.000000 +v -0.826329 0.628576 -0.039883 +v -0.937016 0.632565 -0.039883 +v -0.943899 0.634805 0.000000 +v -0.937016 0.632565 0.039883 +v -0.919812 0.626965 0.063813 +v -0.897443 0.619684 0.071790 +v -0.774766 0.641786 0.039883 +v -0.826329 0.628576 0.039883 +v -0.714922 0.253231 -0.039883 +v -0.608883 0.198681 0.039883 +v -0.715311 0.247220 0.000000 +v -0.785253 0.342107 -0.071790 +v -0.619922 0.238069 0.071790 +v -0.712688 0.287795 0.071790 +v -0.809626 0.430737 0.000000 +v -0.814205 0.426194 0.039883 +v -0.825653 0.414838 0.063813 +v -0.875076 0.612403 -0.063813 +v -0.897443 0.619684 -0.071790 +v -0.919812 0.626965 -0.063813 +v -0.875076 0.612403 0.063813 +v -0.857869 0.606800 0.039883 +v -0.794072 0.325038 -0.063813 +v -0.800855 0.311909 -0.039883 +v -0.825653 0.414838 -0.063813 +v -0.814205 0.426194 -0.039883 +v -0.615480 0.216617 0.063578 +v -0.785253 0.342107 0.071790 +v -0.840534 0.400078 0.071790 +v -0.820114 0.624834 0.000000 +v -0.857869 0.606800 -0.039883 +v -0.950104 0.574316 -0.039883 +v -0.957194 0.574316 0.000000 +v -0.950104 0.574316 0.039883 +v -0.932377 0.574316 0.063813 +v -0.909334 0.574316 0.071790 +v -0.886292 0.574316 0.063813 +v -0.850987 0.604560 0.000000 +v -0.714922 0.253231 0.039883 +v -0.803571 0.306656 0.000000 +v -0.840534 0.400078 -0.071790 +v -0.713952 0.268259 0.063813 +v -0.794072 0.325038 0.063813 +v -0.839022 0.483916 0.000000 +v -0.844976 0.480304 0.039883 +v -0.859854 0.471278 0.063813 +v -0.879202 0.459542 0.071790 +v -0.886292 0.574316 -0.063813 +v -0.909334 0.574316 -0.071790 +v -0.932377 0.574316 -0.063813 +v -0.868564 0.574316 0.039883 +v -0.861474 0.574316 0.000000 +v -0.855419 0.385315 -0.063813 +v -0.866867 0.373960 -0.039883 +v -0.859854 0.471278 -0.063813 +v -0.844976 0.480304 -0.039883 +v -0.855419 0.385315 0.063813 +v -0.898547 0.447807 0.063813 +v -0.868564 0.574316 -0.039883 +v -0.941014 0.505765 -0.039883 +v -0.947813 0.503580 0.000000 +v -0.941014 0.505765 0.039883 +v -0.924011 0.511234 0.063813 +v -0.901913 0.518343 0.071790 +v -0.879811 0.525448 0.063813 +v -0.862808 0.530917 0.039883 +v -0.800855 0.311909 0.039883 +v -0.871445 0.369416 0.000000 +v -0.879202 0.459542 -0.071790 +v -0.866867 0.373960 0.039883 +v -0.856009 0.533103 0.000000 +v -0.879811 0.525448 -0.063813 +v -0.901913 0.518343 -0.071790 +v -0.924011 0.511234 -0.063813 +v -0.862808 0.530917 -0.039883 +v -0.898547 0.447807 -0.063813 +v -0.913428 0.438781 -0.039883 +v -0.913428 0.438781 0.039883 +v -0.919378 0.435169 0.000000 +v 0.600960 0.444810 0.085753 +v 0.605956 0.463769 0.000000 +v 0.600959 0.444810 -0.085753 +v 0.656890 0.471064 0.000000 +v 0.661223 0.454734 -0.083705 +v 0.730696 0.501576 -0.073611 +v 0.661223 0.454734 0.083705 +v 0.605101 0.399712 -0.137265 +v 0.746455 0.470391 -0.117778 +v 0.724395 0.514048 0.000000 +v 0.605100 0.399712 0.137265 +v 0.672055 0.413907 -0.133928 +v 0.613258 0.341675 -0.154354 +v 0.786583 0.544847 -0.096783 +v 0.768856 0.565896 -0.060489 +v 0.672055 0.413907 0.133928 +v 0.730696 0.501576 0.073611 +v 0.686135 0.360830 -0.150669 +v 0.809626 0.517481 -0.108881 +v 0.766935 0.429850 -0.132501 +v 0.761767 0.574316 0.000000 +v 0.613258 0.341675 0.154354 +v 0.813417 0.626247 -0.075788 +v 0.839021 0.611098 -0.085261 +v 0.793721 0.637899 -0.047367 +v 0.686135 0.360830 0.150669 +v 0.768856 0.565896 0.060489 +v 0.746455 0.470391 0.117778 +v 0.619427 0.283145 -0.137236 +v 0.864627 0.595949 -0.075788 +v 0.832669 0.490118 -0.096783 +v 0.787419 0.389310 -0.117778 +v 0.785843 0.642561 0.000000 +v 0.619427 0.283145 0.137236 +v 0.700219 0.307756 -0.133928 +v 0.847933 0.703560 -0.059638 +v 0.879938 0.698065 -0.067092 +v 0.911944 0.692571 -0.059638 +v 0.823314 0.707784 -0.037273 +v 0.766935 0.429850 0.132501 +v 0.793721 0.637899 0.047367 +v 0.786583 0.544847 0.096783 +v 0.700219 0.307756 0.133928 +v 0.617684 0.235930 -0.085941 +v 0.936563 0.688344 -0.037273 +v 0.884319 0.584297 -0.047367 +v 0.850396 0.469070 -0.060489 +v 0.803175 0.358128 -0.073611 +v 0.813468 0.709475 0.000000 +v 0.617684 0.235930 0.085941 +v 0.625577 0.219883 0.000000 +v 0.711051 0.266929 -0.083705 +v 0.911107 0.765755 -0.053178 +v 0.957193 0.765755 -0.059825 +v 1.003279 0.765755 -0.053178 +v 1.038733 0.765755 -0.033236 +v 0.875654 0.765755 -0.033236 +v 0.809626 0.517481 0.108881 +v 0.787419 0.389310 0.117778 +v 0.823314 0.707784 0.037273 +v 0.813417 0.626247 0.075788 +v 0.711051 0.266929 0.083705 +v 0.715384 0.250599 0.000000 +v 1.052913 0.765755 0.000000 +v 0.946409 0.686653 0.000000 +v 0.892200 0.579635 0.000000 +v 0.857486 0.460650 0.000000 +v 0.809479 0.345652 0.000000 +v 0.861474 0.765755 0.000000 +v 0.929990 0.776479 -0.051602 +v 0.979075 0.777181 -0.058052 +v 1.028157 0.777879 -0.051602 +v 1.065915 0.778419 -0.032251 +v 1.081016 0.778632 0.000000 +v 0.892235 0.775943 -0.032251 +v 0.839021 0.611098 0.085261 +v 0.832669 0.490118 0.096783 +v 0.803175 0.358128 0.073611 +v 0.875654 0.765755 0.033236 +v 0.847933 0.703560 0.059638 +v 1.065915 0.778419 0.032174 +v 1.038733 0.765755 0.033236 +v 0.936563 0.688344 0.037273 +v 0.884319 0.584297 0.047367 +v 0.850396 0.469070 0.060489 +v 0.877131 0.775726 0.000000 +v 0.943713 0.783087 -0.047663 +v 0.992645 0.784366 -0.053621 +v 1.041577 0.785649 -0.047663 +v 1.079216 0.786631 -0.029789 +v 1.094273 0.787027 0.000000 +v 1.079216 0.786631 0.029174 +v 0.906073 0.782101 -0.029789 +v 0.879938 0.698065 0.067092 +v 0.864627 0.595949 0.075788 +v 0.892235 0.775943 0.032236 +v 0.911107 0.765755 0.053178 +v 1.041577 0.785649 0.046875 +v 1.028157 0.777879 0.051503 +v 1.003279 0.765755 0.053178 +v 0.911944 0.692571 0.059638 +v 0.891016 0.781708 0.000000 +v 0.951249 0.785448 -0.042542 +v 0.997575 0.787068 -0.047860 +v 1.043903 0.788686 -0.042542 +v 1.079539 0.789934 -0.026589 +v 1.093795 0.790431 0.000000 +v 1.079539 0.789934 0.024511 +v 1.043903 0.788686 0.039883 +v 0.915613 0.784200 -0.026589 +v 0.957193 0.765755 0.059825 +v 0.906073 0.782101 0.029666 +v 0.929990 0.776479 0.051553 +v 0.997575 0.787068 0.045616 +v 0.992645 0.784366 0.052956 +v 0.979075 0.777181 0.057969 +v 0.901357 0.783702 0.000000 +v 0.951569 0.783431 -0.037421 +v 0.993532 0.785033 -0.042099 +v 1.035492 0.786631 -0.037421 +v 1.067772 0.787863 -0.023388 +v 1.080684 0.788354 0.000000 +v 1.067772 0.787863 0.018464 +v 1.035492 0.786631 0.031119 +v 0.993532 0.785033 0.036781 +v 0.919292 0.782200 -0.023388 +v 0.915613 0.784200 0.026173 +v 0.943713 0.783087 0.047269 +v 0.951569 0.783431 0.034270 +v 0.951249 0.785448 0.041213 +v 0.906379 0.781708 0.000000 +v 0.943653 0.776909 -0.033482 +v 0.980182 0.778010 -0.037667 +v 1.016712 0.779111 -0.033482 +v 1.044812 0.779957 -0.020926 +v 1.056052 0.780295 0.000000 +v 1.044812 0.779957 0.011310 +v 1.016712 0.779111 0.021172 +v 0.980182 0.778010 0.027281 +v 0.943653 0.776909 0.027327 +v 0.915553 0.776064 -0.020926 +v 0.919292 0.782200 0.022403 +v 0.915553 0.776064 0.019003 +v 0.904312 0.775726 0.000000 +v 0.926468 0.765755 -0.031906 +v 0.957193 0.765755 -0.035895 +v 0.987920 0.765755 -0.031906 +v 1.011552 0.765755 -0.019942 +v 1.021006 0.765755 0.000000 +v 1.011552 0.765755 0.003324 +v 0.987920 0.765755 0.010635 +v 0.957193 0.765755 0.017947 +v 0.926468 0.765755 0.021271 +v 0.902834 0.765755 0.016618 +v 0.902834 0.765755 -0.019942 +v 0.893380 0.765755 0.000000 +v 0.886428 0.750924 -0.019014 +v 0.908324 0.750924 -0.030099 +v 0.936793 0.750924 -0.033795 +v 0.965261 0.750924 -0.030099 +v 0.987158 0.750924 -0.019014 +v 0.995918 0.750924 -0.000537 +v 0.987158 0.750924 0.002542 +v 0.965261 0.750924 0.009317 +v 0.936793 0.750924 0.016092 +v 0.908324 0.750924 0.019171 +v 0.886428 0.750924 0.014860 +v 0.877668 0.750924 -0.000537 +v 0.936793 0.750924 -0.007312 +v 0.440746 0.783205 0.000000 +v 0.446690 0.765755 0.000000 +v 0.430973 0.765755 0.119945 +v 0.425236 0.783205 0.118348 +v 0.425236 0.783205 -0.118348 +v 0.453011 0.750009 0.000000 +v 0.437073 0.750009 0.121642 +v 0.441668 0.793673 0.000000 +v 0.386470 0.765755 0.226985 +v 0.430973 0.765755 -0.119945 +v 0.426127 0.793673 -0.118596 +v 0.437073 0.750009 -0.121642 +v 0.426127 0.793673 0.118596 +v 0.381327 0.783205 0.223964 +v 0.381327 0.783205 -0.223964 +v 0.382124 0.793673 -0.224433 +v 0.317150 0.765755 0.317150 +v 0.391939 0.750009 0.230197 +v 0.321638 0.750009 0.321639 +v 0.386470 0.765755 -0.226985 +v 0.391939 0.750009 -0.230197 +v 0.447686 0.797164 0.000000 +v 0.431936 0.797164 -0.120212 +v 0.387332 0.797164 -0.227491 +v 0.230197 0.750009 0.391940 +v 0.226984 0.765755 0.386470 +v 0.317150 0.765755 -0.317150 +v 0.321638 0.750009 -0.321639 +v 0.431936 0.797164 0.120212 +v 0.382124 0.793673 0.224433 +v 0.312929 0.783205 0.312929 +v 0.313584 0.793673 -0.313584 +v 0.312929 0.783205 -0.312929 +v 0.317858 0.797164 -0.317858 +v 0.121642 0.750009 0.437072 +v 0.119944 0.765755 0.430973 +v 0.226984 0.765755 -0.386470 +v 0.230197 0.750009 -0.391940 +v 0.457031 0.793673 0.000000 +v 0.440950 0.793673 -0.122721 +v 0.395416 0.793673 -0.232239 +v 0.324491 0.793673 -0.324492 +v -0.000000 0.750009 0.453012 +v -0.000000 0.765755 0.446690 +v 0.223963 0.783205 0.381327 +v 0.223963 0.783205 -0.381327 +v 0.119944 0.765755 -0.430973 +v 0.121642 0.750009 -0.437072 +v 0.440950 0.793673 0.122721 +v 0.387332 0.797164 0.227491 +v 0.313584 0.793673 0.313584 +v 0.227491 0.797164 -0.387332 +v 0.224433 0.793673 -0.382125 +v 0.232239 0.793673 -0.395417 +v -0.119945 0.765755 0.430973 +v -0.121642 0.750009 0.437072 +v 0.118348 0.783205 0.425237 +v 0.118348 0.783205 -0.425237 +v -0.000000 0.750009 -0.453012 +v -0.000000 0.765755 -0.446690 +v 0.467924 0.783205 0.000000 +v 0.451460 0.783205 -0.125646 +v 0.404842 0.783205 -0.237775 +v 0.332226 0.783205 -0.332226 +v 0.237775 0.783205 -0.404842 +v -0.226985 0.765755 0.386470 +v -0.000000 0.783205 0.440746 +v 0.224433 0.793673 0.382125 +v 0.118596 0.793673 -0.426127 +v -0.000000 0.783205 -0.440746 +v -0.119945 0.765755 -0.430973 +v -0.121642 0.750009 -0.437072 +v 0.451460 0.783205 0.125646 +v 0.395416 0.793673 0.232239 +v 0.317858 0.797164 0.317858 +v 0.122721 0.793673 -0.440950 +v 0.120212 0.797164 -0.431937 +v 0.125646 0.783205 -0.451460 +v -0.317150 0.765755 0.317150 +v -0.230198 0.750009 0.391939 +v -0.321639 0.750009 0.321639 +v -0.118348 0.783205 0.425237 +v 0.118596 0.793673 0.426127 +v -0.000000 0.793673 -0.441668 +v -0.118348 0.783205 -0.425237 +v -0.226985 0.765755 -0.386470 +v 0.478596 0.765755 0.000000 +v 0.461756 0.765755 -0.128512 +v 0.414076 0.765755 -0.243198 +v 0.339803 0.765755 -0.339804 +v 0.243198 0.765755 -0.414076 +v 0.128512 0.765755 -0.461757 +v -0.391940 0.750009 0.230197 +v -0.386470 0.765755 0.226985 +v -0.223964 0.783205 0.381327 +v -0.000000 0.793673 0.441668 +v 0.227491 0.797164 0.387332 +v -0.000000 0.797164 -0.447686 +v -0.118596 0.793673 -0.426127 +v -0.223964 0.783205 -0.381327 +v -0.317150 0.765755 -0.317150 +v -0.230198 0.750009 -0.391939 +v -0.321639 0.750009 -0.321639 +v 0.461756 0.765755 0.128512 +v 0.404842 0.783205 0.237775 +v 0.324491 0.793673 0.324492 +v -0.000000 0.783205 -0.467924 +v -0.000000 0.793673 -0.457031 +v -0.000000 0.765755 -0.478597 +v -0.437073 0.750009 0.121642 +v -0.430974 0.765755 0.119945 +v -0.312929 0.783205 0.312929 +v -0.118596 0.793673 0.426127 +v 0.120212 0.797164 0.431937 +v -0.120212 0.797164 -0.431937 +v -0.224433 0.793673 -0.382125 +v -0.312929 0.783205 -0.312929 +v -0.386470 0.765755 -0.226985 +v -0.391940 0.750009 -0.230197 +v 0.518110 0.682112 0.000000 +v 0.499881 0.682112 -0.139122 +v 0.448260 0.682112 -0.263277 +v 0.367859 0.682112 -0.367859 +v 0.263277 0.682112 -0.448260 +v 0.139122 0.682112 -0.499882 +v -0.000000 0.682112 -0.518110 +v -0.453012 0.750009 0.000000 +v -0.446690 0.765755 0.000000 +v -0.381327 0.783205 0.223964 +v -0.224433 0.793673 0.382125 +v -0.000000 0.797164 0.447686 +v 0.232239 0.793673 0.395417 +v -0.122721 0.793673 -0.440950 +v -0.227491 0.797164 -0.387332 +v -0.313584 0.793673 -0.313584 +v -0.381327 0.783205 -0.223964 +v -0.430974 0.765755 -0.119945 +v 0.499881 0.682112 0.139122 +v 0.414076 0.765755 0.243198 +v 0.332226 0.783205 0.332226 +v -0.128513 0.765755 -0.461757 +v -0.125646 0.783205 -0.451460 +v -0.139123 0.682112 -0.499882 +v -0.437073 0.750009 -0.121642 +v -0.425237 0.783205 0.118348 +v -0.313584 0.793673 0.313584 +v -0.120212 0.797164 0.431937 +v 0.122721 0.793673 0.440950 +v -0.232240 0.793673 -0.395417 +v -0.317859 0.797164 -0.317858 +v -0.382125 0.793673 -0.224433 +v -0.425237 0.783205 -0.118348 +v 0.555408 0.599133 0.000000 +v 0.535865 0.599133 -0.149137 +v 0.480530 0.599133 -0.282230 +v 0.394341 0.599133 -0.394341 +v 0.282230 0.599133 -0.480530 +v 0.149137 0.599133 -0.535866 +v -0.000000 0.599133 -0.555408 +v -0.149138 0.599133 -0.535866 +v -0.440746 0.783205 0.000000 +v -0.382125 0.793673 0.224433 +v -0.227491 0.797164 0.387332 +v -0.000000 0.793673 0.457031 +v 0.237775 0.783205 0.404842 +v -0.237775 0.783205 -0.404842 +v -0.324492 0.793673 -0.324492 +v -0.387332 0.797164 -0.227491 +v -0.426127 0.793673 -0.118596 +v 0.535865 0.599133 0.149137 +v 0.448260 0.682112 0.263277 +v 0.339803 0.765755 0.339804 +v -0.263278 0.682112 -0.448260 +v -0.243198 0.765755 -0.414076 +v -0.282230 0.599133 -0.480530 +v -0.426127 0.793673 0.118596 +v -0.317859 0.797164 0.317858 +v -0.122721 0.793673 0.440950 +v 0.125646 0.783205 0.451460 +v -0.332226 0.783205 -0.332226 +v -0.395417 0.793673 -0.232239 +v -0.431937 0.797164 -0.120212 +v -0.441668 0.793673 0.000000 +v 0.588275 0.517481 0.000000 +v 0.567578 0.517481 -0.157963 +v 0.508969 0.517485 -0.298931 +v 0.417675 0.517481 -0.417675 +v 0.298931 0.517485 -0.508969 +v 0.157963 0.517485 -0.567578 +v -0.000000 0.517481 -0.588275 +v -0.157963 0.517481 -0.567578 +v -0.298931 0.517485 -0.508969 +v -0.387332 0.797164 0.227491 +v -0.232240 0.793673 0.395417 +v -0.000000 0.783205 0.467924 +v 0.243198 0.765755 0.414076 +v -0.339804 0.765755 -0.339804 +v -0.404842 0.783205 -0.237775 +v -0.440950 0.793673 -0.122721 +v -0.447686 0.797164 0.000000 +v 0.567578 0.517485 0.157963 +v 0.480530 0.599133 0.282230 +v 0.367859 0.682112 0.367859 +v -0.394341 0.599133 -0.394341 +v -0.367859 0.682112 -0.367859 +v -0.417675 0.517481 -0.417675 +v -0.431937 0.797164 0.120212 +v -0.324492 0.793673 0.324492 +v -0.125646 0.783205 0.451460 +v 0.128512 0.765755 0.461757 +v -0.414076 0.765755 -0.243198 +v -0.451461 0.783205 -0.125646 +v -0.457031 0.793673 0.000000 +v 0.592873 0.437827 -0.165003 +v 0.531651 0.437827 -0.312254 +v 0.436292 0.437827 -0.436292 +v 0.312254 0.437827 -0.531651 +v 0.165003 0.437827 -0.592873 +v -0.000000 0.437827 -0.614496 +v -0.165004 0.437827 -0.592873 +v -0.312255 0.437827 -0.531651 +v -0.436292 0.437827 -0.436292 +v -0.395417 0.793673 0.232239 +v -0.237775 0.783205 0.404842 +v -0.000000 0.765755 0.478597 +v 0.263277 0.682112 0.448260 +v -0.448260 0.682112 -0.263277 +v -0.461757 0.765755 -0.128512 +v -0.467924 0.783205 0.000000 +v -0.440950 0.793673 0.122721 +v 0.592873 0.437827 0.165003 +v 0.508969 0.517485 0.298931 +v 0.394341 0.599133 0.394341 +v -0.508969 0.517485 -0.298931 +v -0.480530 0.599133 -0.282230 +v -0.531651 0.437827 -0.312254 +v -0.332226 0.783205 0.332226 +v -0.128513 0.765755 0.461757 +v 0.139122 0.682112 0.499882 +v -0.499882 0.682112 -0.139122 +v -0.478597 0.765755 0.000000 +v -0.451461 0.783205 0.125646 +v 0.546669 0.360830 -0.321075 +v 0.448614 0.360830 -0.448614 +v 0.321074 0.360830 -0.546669 +v 0.169664 0.360830 -0.609621 +v -0.000000 0.360830 -0.631850 +v -0.169664 0.360830 -0.609621 +v -0.321075 0.360830 -0.546669 +v -0.448615 0.360830 -0.448614 +v -0.546669 0.360830 -0.321075 +v -0.404842 0.783205 0.237775 +v -0.243198 0.765755 0.414076 +v -0.000000 0.682112 0.518110 +v 0.282230 0.599133 0.480530 +v -0.535866 0.599133 -0.149137 +v -0.461757 0.765755 0.128512 +v 0.531651 0.437827 0.312254 +v 0.417675 0.517481 0.417675 +v 0.609621 0.360830 -0.169664 +v -0.592873 0.437827 -0.165003 +v -0.567578 0.517485 -0.157963 +v -0.609621 0.360830 -0.169664 +v -0.339804 0.765755 0.339804 +v -0.139123 0.682112 0.499882 +v 0.149137 0.599133 0.535866 +v -0.555408 0.599133 0.000000 +v -0.499882 0.682112 0.139122 +v -0.414076 0.765755 0.243198 +v 0.609621 0.360830 0.169664 +v 0.552100 0.287158 -0.324265 +v 0.453072 0.287158 -0.453072 +v 0.324265 0.287158 -0.552100 +v 0.171349 0.287158 -0.615677 +v -0.000000 0.287158 -0.638129 +v -0.171350 0.287158 -0.615677 +v -0.324265 0.287158 -0.552100 +v -0.453072 0.287158 -0.453072 +v -0.552100 0.287158 -0.324265 +v -0.615677 0.287158 -0.171349 +v -0.263278 0.682112 0.448260 +v -0.000000 0.599133 0.555408 +v 0.298931 0.517485 0.508969 +v -0.588275 0.517481 0.000000 +v -0.448260 0.682112 0.263277 +v 0.546669 0.360830 0.321075 +v 0.436292 0.437827 0.436292 +v 0.615677 0.287158 -0.171349 +v -0.631850 0.360830 0.000000 +v -0.614496 0.437827 0.000000 +v -0.367859 0.682112 0.367859 +v -0.149138 0.599133 0.535866 +v 0.157963 0.517481 0.567578 +v -0.567578 0.517481 0.157963 +v -0.480530 0.599133 0.282230 +v 0.615677 0.287158 0.171349 +v 0.541877 0.221240 -0.318259 +v 0.444680 0.221240 -0.444680 +v 0.318259 0.221240 -0.541877 +v 0.168176 0.221240 -0.604276 +v -0.000000 0.221240 -0.626311 +v -0.168177 0.221240 -0.604276 +v -0.318259 0.221240 -0.541877 +v -0.444680 0.221240 -0.444680 +v -0.541877 0.221240 -0.318259 +v -0.604277 0.221240 -0.168176 +v -0.282230 0.599133 0.480530 +v -0.000000 0.517481 0.588275 +v 0.312254 0.437827 0.531651 +v -0.592873 0.437827 0.165003 +v -0.535866 0.599133 0.149137 +v -0.394341 0.599133 0.394341 +v 0.552100 0.287158 0.324265 +v 0.448614 0.360830 0.448614 +v 0.604276 0.221240 -0.168176 +v -0.615677 0.287158 0.171349 +v -0.609621 0.360830 0.169664 +v -0.157963 0.517485 0.567578 +v 0.165003 0.437827 0.592873 +v -0.531651 0.437827 0.312254 +v -0.508969 0.517485 0.298931 +v -0.417675 0.517481 0.417675 +v 0.604276 0.221240 0.168176 +v 0.516317 0.166623 -0.303247 +v 0.423705 0.166623 -0.423705 +v 0.303247 0.166623 -0.516317 +v 0.160243 0.166623 -0.575771 +v -0.000000 0.166623 -0.596769 +v -0.160244 0.166623 -0.575771 +v -0.303247 0.166623 -0.516317 +v -0.423705 0.166623 -0.423705 +v -0.516317 0.166623 -0.303247 +v -0.575771 0.166623 -0.160243 +v -0.298931 0.517485 0.508969 +v -0.000000 0.437827 0.614496 +v 0.321074 0.360830 0.546669 +v -0.546669 0.360830 0.321075 +v 0.541877 0.221240 0.318259 +v 0.453072 0.287158 0.453072 +v 0.575771 0.166623 -0.160243 +v -0.596769 0.166623 0.000000 +v -0.604277 0.221240 0.168176 +v -0.552100 0.287158 0.324265 +v -0.165004 0.437827 0.592873 +v 0.169664 0.360830 0.609621 +v -0.448615 0.360830 0.448614 +v -0.436292 0.437827 0.436292 +v -0.312255 0.437827 0.531651 +v 0.575771 0.166623 0.160243 +v 0.483086 0.122640 -0.283731 +v 0.396438 0.122640 -0.396438 +v 0.283731 0.122640 -0.483086 +v 0.149931 0.122640 -0.538718 +v -0.000000 0.122640 -0.558363 +v -0.149931 0.122640 -0.538718 +v -0.283731 0.122640 -0.483086 +v -0.396438 0.122640 -0.396438 +v -0.483087 0.122640 -0.283731 +v -0.538718 0.122640 -0.149931 +v -0.558363 0.122640 0.000000 +v -0.541877 0.221240 0.318259 +v -0.000000 0.360830 0.631850 +v 0.324265 0.287158 0.552100 +v -0.453072 0.287158 0.453072 +v 0.516317 0.166623 0.303247 +v 0.596768 0.166623 0.000000 +v 0.444680 0.221240 0.444680 +v 0.538718 0.122640 -0.149931 +v -0.538718 0.122640 0.149931 +v -0.516317 0.166623 0.303247 +v -0.444680 0.221240 0.444680 +v -0.169664 0.360830 0.609621 +v 0.171349 0.287158 0.615677 +v -0.324265 0.287158 0.552100 +v -0.321075 0.360830 0.546669 +v 0.538718 0.122640 0.149931 +v 0.558363 0.122640 0.000000 +v 0.449858 0.088629 -0.264215 +v 0.369171 0.088629 -0.369171 +v 0.264215 0.088629 -0.449859 +v 0.139618 0.088629 -0.501662 +v -0.000000 0.088629 -0.519957 +v -0.139618 0.088629 -0.501662 +v -0.264215 0.088629 -0.449859 +v -0.369171 0.088629 -0.369171 +v -0.449859 0.088629 -0.264215 +v -0.501662 0.088629 -0.139618 +v -0.519957 0.088629 0.000000 +v -0.501662 0.088629 0.139618 +v -0.575771 0.166623 0.160243 +v -0.423705 0.166623 0.423705 +v -0.000000 0.287158 0.638129 +v 0.318259 0.221240 0.541877 +v -0.318259 0.221240 0.541877 +v 0.483086 0.122640 0.283731 +v 0.423705 0.166623 0.423705 +v 0.501662 0.088629 -0.139618 +v -0.449859 0.088629 0.264215 +v -0.483087 0.122640 0.283731 +v -0.396438 0.122640 0.396438 +v -0.303247 0.166623 0.516317 +v -0.171350 0.287158 0.615677 +v 0.168176 0.221240 0.604276 +v -0.168177 0.221240 0.604276 +v 0.501662 0.088629 0.139618 +v 0.519957 0.088629 0.000000 +v 0.424299 0.063924 -0.249203 +v 0.348195 0.063924 -0.348195 +v 0.249203 0.063924 -0.424298 +v 0.131685 0.063924 -0.473160 +v -0.000000 0.063924 -0.490415 +v -0.131686 0.063924 -0.473160 +v -0.249203 0.063924 -0.424298 +v -0.348196 0.063924 -0.348195 +v -0.424299 0.063924 -0.249203 +v -0.473160 0.063924 -0.131685 +v -0.490415 0.063924 0.000000 +v -0.473160 0.063924 0.131685 +v -0.424299 0.063924 0.249203 +v -0.283731 0.122640 0.483086 +v -0.000000 0.221240 0.626311 +v 0.303247 0.166623 0.516317 +v -0.160244 0.166623 0.575771 +v 0.449858 0.088629 0.264215 +v 0.396438 0.122640 0.396438 +v 0.473160 0.063924 -0.131685 +v -0.348196 0.063924 0.348195 +v -0.369171 0.088629 0.369171 +v -0.264215 0.088629 0.449859 +v -0.149931 0.122640 0.538718 +v 0.160243 0.166623 0.575771 +v -0.000000 0.166623 0.596769 +v 0.473160 0.063924 0.131685 +v 0.490415 0.063924 0.000000 +v 0.414076 0.047860 -0.243198 +v 0.339803 0.047860 -0.339804 +v 0.243198 0.047860 -0.414076 +v 0.128512 0.047860 -0.461757 +v -0.000000 0.047860 -0.478597 +v -0.128513 0.047860 -0.461757 +v -0.243198 0.047860 -0.414076 +v -0.339804 0.047860 -0.339804 +v -0.414076 0.047860 -0.243198 +v -0.461757 0.047860 -0.128512 +v -0.478597 0.047860 0.000000 +v -0.461757 0.047860 0.128512 +v -0.414076 0.047860 0.243198 +v -0.339804 0.047860 0.339804 +v -0.139618 0.088629 0.501662 +v 0.283731 0.122640 0.483086 +v -0.000000 0.122640 0.558363 +v 0.424299 0.063924 0.249203 +v 0.369171 0.088629 0.369171 +v 0.461756 0.047860 -0.128512 +v -0.243198 0.047860 0.414076 +v -0.249203 0.063924 0.424298 +v -0.131686 0.063924 0.473160 +v -0.000000 0.088629 0.519957 +v 0.149931 0.122640 0.538718 +v 0.461756 0.047860 0.128512 +v 0.478596 0.047860 0.000000 +v 0.410719 0.036005 -0.241228 +v 0.337050 0.036005 -0.337050 +v 0.241227 0.036005 -0.410719 +v 0.127471 0.036005 -0.458017 +v -0.000000 0.036005 -0.474720 +v -0.127471 0.036005 -0.458017 +v -0.241228 0.036005 -0.410719 +v -0.337051 0.036005 -0.337050 +v -0.410719 0.036005 -0.241228 +v -0.458017 0.036005 -0.127471 +v -0.474721 0.036005 0.000000 +v -0.458017 0.036005 0.127471 +v -0.410719 0.036005 0.241228 +v -0.337051 0.036005 0.337050 +v -0.241228 0.036005 0.410719 +v -0.000000 0.063924 0.490415 +v 0.264215 0.088629 0.449859 +v 0.139618 0.088629 0.501662 +v 0.414076 0.047860 0.243198 +v 0.348195 0.063924 0.348195 +v 0.458017 0.036005 -0.127471 +v -0.127471 0.036005 0.458017 +v -0.128513 0.047860 0.461757 +v -0.000000 0.047860 0.478597 +v 0.131685 0.063924 0.473160 +v 0.458017 0.036005 0.127471 +v 0.474720 0.036005 0.000000 +v 0.394137 0.024816 -0.231489 +v 0.323442 0.024816 -0.323442 +v 0.231489 0.024816 -0.394137 +v 0.122324 0.024816 -0.439524 +v -0.000000 0.024816 -0.455554 +v -0.122325 0.024816 -0.439524 +v -0.231489 0.024816 -0.394137 +v -0.323442 0.024816 -0.323442 +v -0.394137 0.024816 -0.231489 +v -0.439524 0.024816 -0.122325 +v -0.455554 0.024816 0.000000 +v -0.439524 0.024816 0.122325 +v -0.394137 0.024816 0.231489 +v -0.323442 0.024816 0.323442 +v -0.231489 0.024816 0.394137 +v -0.122325 0.024816 0.439524 +v 0.128512 0.047860 0.461757 +v 0.249203 0.063924 0.424298 +v 0.410719 0.036005 0.241228 +v 0.339803 0.047860 0.339804 +v 0.439524 0.024816 -0.122325 +v -0.000000 0.036005 0.474720 +v -0.000000 0.024816 0.455554 +v 0.127471 0.036005 0.458017 +v 0.243198 0.047860 0.414076 +v 0.439524 0.024816 0.122325 +v 0.455554 0.024816 0.000000 +v 0.354551 0.014956 -0.208238 +v 0.290957 0.014956 -0.290957 +v 0.208238 0.014956 -0.354551 +v 0.110038 0.014956 -0.395378 +v -0.000000 0.014956 -0.409797 +v -0.110038 0.014956 -0.395378 +v -0.208239 0.014956 -0.354551 +v -0.290957 0.014956 -0.290957 +v -0.354551 0.014956 -0.208238 +v -0.395378 0.014956 -0.110038 +v -0.409797 0.014956 0.000000 +v -0.395378 0.014956 0.110038 +v -0.354551 0.014956 0.208238 +v -0.290957 0.014956 0.290957 +v -0.208239 0.014956 0.354551 +v -0.110038 0.014956 0.395378 +v -0.000000 0.014956 0.409797 +v 0.241227 0.036005 0.410719 +v 0.337050 0.036005 0.337050 +v 0.394137 0.024816 0.231489 +v 0.395378 0.014956 -0.110038 +v 0.122324 0.024816 0.439524 +v 0.110038 0.014956 0.395378 +v 0.231489 0.024816 0.394137 +v 0.395378 0.014956 0.110038 +v 0.409797 0.014956 0.000000 +v 0.282184 0.007090 -0.165735 +v 0.231570 0.007090 -0.231570 +v 0.165735 0.007090 -0.282185 +v 0.087579 0.007090 -0.314679 +v -0.000000 0.007090 -0.326154 +v -0.087579 0.007090 -0.314679 +v -0.165735 0.007090 -0.282185 +v -0.231570 0.007090 -0.231570 +v -0.282184 0.007090 -0.165735 +v -0.314679 0.007090 -0.087579 +v -0.326155 0.007090 0.000000 +v -0.314679 0.007090 0.087579 +v -0.282184 0.007090 0.165735 +v -0.231570 0.007090 0.231570 +v -0.165735 0.007090 0.282185 +v -0.087579 0.007090 0.314679 +v -0.000000 0.007090 0.326154 +v 0.087579 0.007090 0.314679 +v 0.323442 0.024816 0.323442 +v 0.354551 0.014956 0.208238 +v 0.314679 0.007090 -0.087579 +v 0.208238 0.014956 0.354551 +v 0.165735 0.007090 0.282185 +v 0.290957 0.014956 0.290957 +v 0.314679 0.007090 0.087579 +v 0.326154 0.007090 0.000000 +v 0.167259 0.001883 -0.098236 +v 0.137258 0.001883 -0.137259 +v 0.098236 0.001883 -0.167259 +v 0.051910 0.001883 -0.186520 +v -0.000000 0.001883 -0.193322 +v -0.051911 0.001883 -0.186520 +v -0.098237 0.001883 -0.167259 +v -0.137259 0.001883 -0.137259 +v -0.167259 0.001883 -0.098236 +v -0.186520 0.001883 -0.051911 +v -0.193323 0.001883 0.000000 +v -0.186520 0.001883 0.051911 +v -0.167259 0.001883 0.098236 +v -0.137259 0.001883 0.137259 +v -0.098237 0.001883 0.167259 +v -0.051911 0.001883 0.186520 +v -0.000000 0.001883 0.193322 +v 0.051910 0.001883 0.186520 +v 0.098236 0.001883 0.167259 +v 0.282184 0.007090 0.165735 +v 0.186520 0.001883 -0.051911 +v 0.231570 0.007090 0.231570 +v 0.137258 0.001883 0.137259 +v 0.186520 0.001883 0.051911 +v 0.193322 0.001883 0.000000 +v -0.000000 0.000000 0.000000 +v 0.167259 0.001883 0.098236 +v 0.063813 0.861474 0.000000 +v 0.054654 0.888729 0.000000 +v 0.052734 0.888729 0.014691 +v 0.061568 0.861474 0.017135 +v 0.061568 0.861474 -0.017135 +v 0.072979 0.919969 0.020357 +v 0.111968 0.841089 0.000000 +v 0.047296 0.888729 0.027792 +v 0.052734 0.888729 -0.014691 +v 0.108028 0.841089 -0.030065 +v 0.075630 0.919969 0.000000 +v 0.065466 0.919969 0.038494 +v 0.108028 0.841089 0.030065 +v 0.055210 0.861474 0.032427 +v 0.055210 0.861474 -0.032427 +v 0.096873 0.841089 -0.056896 +v 0.100064 0.951211 0.027927 +v 0.089769 0.951211 0.052799 +v 0.183167 0.826023 0.000000 +v 0.176722 0.826023 -0.049184 +v 0.038821 0.888729 0.038821 +v 0.053751 0.919969 0.053751 +v 0.047296 0.888729 -0.027792 +v 0.072979 0.919969 -0.020357 +v 0.158473 0.826023 -0.093076 +v 0.103696 0.951211 0.000000 +v 0.073714 0.951211 0.073714 +v 0.176722 0.826023 0.049184 +v 0.096873 0.841089 0.056896 +v 0.045307 0.861474 0.045307 +v 0.079497 0.841089 -0.079497 +v 0.045307 0.861474 -0.045307 +v 0.130048 0.826023 -0.130048 +v 0.111754 0.978466 0.031195 +v 0.100259 0.978466 0.058974 +v 0.082330 0.978466 0.082330 +v 0.263228 0.813615 0.000000 +v 0.253966 0.813615 -0.070682 +v 0.227741 0.813615 -0.133759 +v 0.027792 0.888729 0.047296 +v 0.038494 0.919969 0.065466 +v 0.052799 0.951211 0.089769 +v 0.038821 0.888729 -0.038821 +v 0.065466 0.919969 -0.038494 +v 0.100064 0.951211 -0.027927 +v 0.186892 0.813615 -0.186892 +v 0.115809 0.978466 0.000000 +v 0.058974 0.978466 0.100259 +v 0.253966 0.813615 0.070682 +v 0.158473 0.826023 0.093076 +v 0.079497 0.841089 0.079497 +v 0.032426 0.861474 0.055210 +v 0.093076 0.826023 -0.158473 +v 0.056896 0.841089 -0.096873 +v 0.032426 0.861474 -0.055210 +v 0.133759 0.813615 -0.227741 +v 0.085811 0.997741 0.023955 +v 0.076985 0.997741 0.045285 +v 0.063219 0.997741 0.063219 +v 0.045285 0.997741 0.076986 +v 0.337972 0.801206 0.000000 +v 0.326081 0.801206 -0.090752 +v 0.292408 0.801206 -0.171740 +v 0.239960 0.801206 -0.239960 +v 0.014691 0.888729 0.052735 +v 0.020357 0.919969 0.072979 +v 0.027927 0.951211 0.100064 +v 0.031195 0.978466 0.111754 +v 0.027792 0.888729 -0.047296 +v 0.053751 0.919969 -0.053751 +v 0.089769 0.951211 -0.052799 +v 0.111754 0.978466 -0.031195 +v 0.171740 0.801206 -0.292408 +v 0.088924 0.997741 0.000000 +v 0.023955 0.997741 0.085811 +v 0.326081 0.801206 0.090752 +v 0.227741 0.813615 0.133759 +v 0.130048 0.826023 0.130048 +v 0.056896 0.841089 0.096873 +v 0.017135 0.861474 0.061568 +v 0.070682 0.813615 -0.253966 +v 0.049184 0.826023 -0.176722 +v 0.030065 0.841089 -0.108029 +v 0.017135 0.861474 -0.061568 +v 0.090752 0.801206 -0.326081 +v -0.000000 1.005054 0.000000 +v 0.393218 0.786140 0.000000 +v 0.379380 0.786140 -0.105586 +v 0.340206 0.786140 -0.199813 +v 0.279184 0.786140 -0.279184 +v 0.199813 0.786140 -0.340206 +v -0.000000 0.888729 0.054654 +v -0.000000 0.919969 0.075630 +v -0.000000 0.951211 0.103696 +v -0.000000 0.978466 0.115809 +v -0.000000 0.997741 0.088925 +v 0.014691 0.888729 -0.052735 +v 0.038494 0.919969 -0.065466 +v 0.073714 0.951211 -0.073714 +v 0.100259 0.978466 -0.058974 +v 0.085811 0.997741 -0.023955 +v 0.105586 0.786140 -0.379381 +v 0.379380 0.786140 0.105586 +v 0.292408 0.801206 0.171740 +v 0.186892 0.813615 0.186892 +v 0.093076 0.826023 0.158473 +v 0.030065 0.841089 0.108029 +v -0.000000 0.861474 0.063813 +v -0.000000 0.801206 -0.337972 +v -0.000000 0.813615 -0.263228 +v -0.000000 0.826023 -0.183167 +v -0.000000 0.841089 -0.111968 +v -0.000000 0.861474 -0.063813 +v -0.000000 0.786140 -0.393218 +v 0.076985 0.997741 -0.045285 +v -0.023955 0.997741 0.085811 +v 0.414784 0.765755 0.000000 +v 0.400190 0.765755 -0.111377 +v 0.358865 0.765755 -0.210772 +v 0.294497 0.765755 -0.294497 +v 0.210772 0.765755 -0.358865 +v 0.111377 0.765755 -0.400190 +v -0.014691 0.888729 0.052735 +v -0.020357 0.919969 0.072979 +v -0.027927 0.951211 0.100064 +v -0.031195 0.978466 0.111754 +v -0.000000 0.888729 -0.054654 +v 0.020357 0.919969 -0.072979 +v 0.052799 0.951211 -0.089769 +v 0.082330 0.978466 -0.082330 +v -0.000000 0.765755 -0.414784 +v 0.063219 0.997741 -0.063219 +v -0.045285 0.997741 0.076986 +v 0.400190 0.765755 0.111377 +v 0.340206 0.786140 0.199813 +v 0.239960 0.801206 0.239960 +v 0.133759 0.813615 0.227741 +v 0.049184 0.826023 0.176722 +v -0.000000 0.841089 0.111968 +v -0.017135 0.861474 0.061568 +v -0.105586 0.786140 -0.379381 +v -0.090752 0.801206 -0.326081 +v -0.070682 0.813615 -0.253966 +v -0.049184 0.826023 -0.176722 +v -0.030066 0.841089 -0.108029 +v -0.017135 0.861474 -0.061568 +v -0.111377 0.765755 -0.400190 +v 0.045285 0.997741 -0.076986 +v -0.063220 0.997741 0.063219 +v 0.414952 0.750806 0.115486 +v 0.430085 0.750806 0.000000 +v 0.414952 0.750806 -0.115486 +v 0.372103 0.750806 -0.218547 +v 0.305360 0.750806 -0.305360 +v 0.218547 0.750806 -0.372103 +v 0.115486 0.750806 -0.414952 +v -0.000000 0.750806 -0.430085 +v -0.027793 0.888729 0.047296 +v -0.038494 0.919969 0.065466 +v -0.052799 0.951211 0.089769 +v -0.058974 0.978466 0.100259 +v -0.014691 0.888729 -0.052735 +v -0.000000 0.919969 -0.075630 +v 0.027927 0.951211 -0.100064 +v 0.058974 0.978466 -0.100259 +v -0.115486 0.750806 -0.414952 +v 0.023955 0.997741 -0.085811 +v -0.076986 0.997741 0.045285 +v 0.372103 0.750806 0.218547 +v 0.358865 0.765755 0.210772 +v 0.279184 0.786140 0.279184 +v 0.171740 0.801206 0.292408 +v 0.070682 0.813615 0.253966 +v -0.000000 0.826023 0.183167 +v -0.030066 0.841089 0.108029 +v -0.032427 0.861474 0.055210 +v -0.210772 0.765755 -0.358865 +v -0.199813 0.786140 -0.340206 +v -0.171740 0.801206 -0.292408 +v -0.133759 0.813615 -0.227741 +v -0.093076 0.826023 -0.158473 +v -0.056896 0.841089 -0.096873 +v -0.032427 0.861474 -0.055210 +v -0.218547 0.750806 -0.372103 +v 0.031195 0.978466 -0.111754 +v -0.000000 0.997741 -0.088925 +v -0.082331 0.978466 0.082330 +v -0.085811 0.997741 0.023955 +v 0.305360 0.750806 0.305360 +v 0.294497 0.765755 0.294497 +v -0.038821 0.888729 0.038821 +v -0.053751 0.919969 0.053751 +v -0.073714 0.951211 0.073714 +v -0.027793 0.888729 -0.047296 +v -0.020357 0.919969 -0.072979 +v -0.000000 0.951211 -0.103696 +v -0.305360 0.750806 -0.305360 +v -0.294497 0.765755 -0.294497 +v -0.000000 0.978466 -0.115809 +v -0.023955 0.997741 -0.085811 +v -0.100259 0.978466 0.058974 +v -0.088925 0.997741 0.000000 +v 0.210772 0.765755 0.358865 +v 0.218547 0.750806 0.372103 +v 0.199813 0.786140 0.340206 +v 0.090752 0.801206 0.326081 +v -0.000000 0.813615 0.263228 +v -0.049184 0.826023 0.176722 +v -0.056896 0.841089 0.096873 +v -0.045307 0.861474 0.045307 +v -0.279185 0.786140 -0.279184 +v -0.239960 0.801206 -0.239960 +v -0.186892 0.813615 -0.186892 +v -0.130049 0.826023 -0.130048 +v -0.079497 0.841089 -0.079497 +v -0.045307 0.861474 -0.045307 +v -0.372103 0.750806 -0.218547 +v -0.358865 0.765755 -0.210772 +v -0.031195 0.978466 -0.111754 +v -0.045285 0.997741 -0.076986 +v -0.111754 0.978466 0.031195 +v -0.085811 0.997741 -0.023955 +v 0.111377 0.765755 0.400190 +v 0.115486 0.750806 0.414952 +v -0.047296 0.888729 0.027792 +v -0.065466 0.919969 0.038494 +v -0.089770 0.951211 0.052799 +v -0.038821 0.888729 -0.038821 +v -0.038494 0.919969 -0.065466 +v -0.027927 0.951211 -0.100064 +v -0.414952 0.750806 -0.115486 +v -0.400190 0.765755 -0.111377 +v -0.058974 0.978466 -0.100259 +v -0.063220 0.997741 -0.063219 +v -0.115809 0.978466 0.000000 +v -0.076986 0.997741 -0.045285 +v 0.105586 0.786140 0.379381 +v -0.000000 0.765755 0.414784 +v -0.000000 0.750806 0.430085 +v -0.000000 0.801206 0.337972 +v -0.070682 0.813615 0.253966 +v -0.093076 0.826023 0.158473 +v -0.079497 0.841089 0.079497 +v -0.055210 0.861474 0.032427 +v -0.340206 0.786140 -0.199813 +v -0.292408 0.801206 -0.171740 +v -0.227741 0.813615 -0.133759 +v -0.158473 0.826023 -0.093076 +v -0.096873 0.841089 -0.056896 +v -0.055210 0.861474 -0.032427 +v -0.430085 0.750806 0.000000 +v -0.414784 0.765755 0.000000 +v -0.052799 0.951211 -0.089769 +v -0.082331 0.978466 -0.082330 +v -0.100064 0.951211 0.027927 +v -0.111754 0.978466 -0.031195 +v -0.000000 0.786140 0.393218 +v -0.115486 0.750806 0.414952 +v -0.111377 0.765755 0.400190 +v -0.052735 0.888729 0.014691 +v -0.072979 0.919969 0.020357 +v -0.047296 0.888729 -0.027792 +v -0.053751 0.919969 -0.053751 +v -0.414952 0.750806 0.115486 +v -0.400190 0.765755 0.111377 +v -0.379381 0.786140 -0.105586 +v -0.073714 0.951211 -0.073714 +v -0.100259 0.978466 -0.058974 +v -0.103696 0.951211 0.000000 +v -0.105586 0.786140 0.379381 +v -0.218547 0.750806 0.372103 +v -0.210772 0.765755 0.358865 +v -0.090752 0.801206 0.326081 +v -0.133759 0.813615 0.227741 +v -0.130049 0.826023 0.130048 +v -0.096873 0.841089 0.056896 +v -0.061568 0.861474 0.017135 +v -0.326081 0.801206 -0.090752 +v -0.253966 0.813615 -0.070682 +v -0.176722 0.826023 -0.049184 +v -0.108029 0.841089 -0.030065 +v -0.061568 0.861474 -0.017135 +v -0.372103 0.750806 0.218547 +v -0.358865 0.765755 0.210772 +v -0.393219 0.786140 0.000000 +v -0.089770 0.951211 -0.052799 +v -0.100064 0.951211 -0.027927 +v -0.199813 0.786140 0.340206 +v -0.305360 0.750806 0.305360 +v -0.294497 0.765755 0.294497 +v -0.054655 0.888729 0.000000 +v -0.075630 0.919969 0.000000 +v -0.052735 0.888729 -0.014691 +v -0.065466 0.919969 -0.038494 +v -0.379381 0.786140 0.105586 +v -0.171740 0.801206 0.292408 +v -0.279185 0.786140 0.279184 +v -0.186892 0.813615 0.186892 +v -0.158473 0.826023 0.093076 +v -0.108029 0.841089 0.030065 +v -0.063813 0.861474 0.000000 +v -0.337972 0.801206 0.000000 +v -0.263228 0.813615 0.000000 +v -0.183167 0.826023 0.000000 +v -0.111968 0.841089 0.000000 +v -0.340206 0.786140 0.199813 +v -0.072979 0.919969 -0.020357 +v -0.239960 0.801206 0.239960 +v -0.326081 0.801206 0.090752 +v -0.292408 0.801206 0.171740 +v -0.227741 0.813615 0.133759 +v -0.176722 0.826023 0.049184 +v -0.253966 0.813615 0.070682 +v -0.526706 0.651362 -0.039883 +v -0.534329 0.646030 0.000000 +v -0.619922 0.238069 -0.071790 +v -0.624826 0.259599 -0.063813 +v -0.638129 0.287158 0.000000 +v -0.631184 0.277569 0.039883 +v -0.501666 0.699221 -0.063813 +v -0.508714 0.682112 -0.071712 +v -0.611709 0.194244 0.000000 +v -0.608883 0.198681 0.039883 +v -0.517593 0.664661 0.063813 +v -0.508714 0.682112 0.071712 +v -0.631184 0.277569 -0.039883 +v -0.624828 0.259599 0.063813 +v -0.615480 0.216617 0.063578 +v -0.615553 0.216807 -0.063813 +v -0.517593 0.664661 -0.063813 +v -0.498530 0.712498 -0.039883 +v -0.619922 0.238069 0.071790 +v -0.526706 0.651362 0.039883 +v -0.608884 0.198682 -0.039883 +v 0.605100 0.399712 0.137265 +v 0.613258 0.341675 0.154354 +v 0.605956 0.463769 0.000000 +v 0.600959 0.444810 -0.085753 +v 0.613258 0.341675 -0.154354 +v 0.605101 0.399712 -0.137265 +v 0.600960 0.444810 0.085753 +v 0.121642 0.750009 -0.437072 +v -0.000000 0.750009 -0.453012 +v 0.453011 0.750009 0.000000 +v 0.437073 0.750009 -0.121642 +v -0.453012 0.750009 0.000000 +v -0.437073 0.750009 -0.121642 +v -0.230198 0.750009 0.391939 +v -0.321639 0.750009 0.321639 +v -0.391940 0.750009 0.230197 +v -0.437073 0.750009 0.121642 +v 0.121642 0.750009 0.437072 +v -0.000000 0.750009 0.453012 +v -0.121642 0.750009 0.437072 +v 0.437073 0.750009 0.121642 +v 0.391939 0.750009 0.230197 +v 0.321638 0.750009 -0.321639 +v 0.230197 0.750009 -0.391940 +v -0.121642 0.750009 -0.437072 +v 0.391939 0.750009 -0.230197 +v 0.321638 0.750009 0.321639 +v 0.230197 0.750009 0.391940 +v -0.230198 0.750009 -0.391939 +v -0.501255 0.717792 0.000000 +v 0.617684 0.235930 0.085941 +v 0.625577 0.219883 0.000000 +v -0.321639 0.750009 -0.321639 +v -0.391940 0.750009 -0.230197 +v -0.498530 0.712498 0.039883 +v -0.501667 0.699221 0.063813 +v 0.617684 0.235930 -0.085941 +v 0.619427 0.283145 -0.137236 +v 0.619427 0.283145 0.137236 +vn -0.901883 0.415418 0.118168 +vn -0.905637 0.407056 0.118656 +vn -0.877041 0.418744 0.235298 +vn 0.058443 -0.998260 0.000732 +vn 0.015107 -0.999878 0.000183 +vn 0.014557 -0.949278 0.314035 +vn 0.056703 -0.947539 0.314524 +vn 0.162053 -0.986755 0.002014 +vn 0.157933 -0.933592 0.321604 +vn 0.392376 -0.919767 0.004334 +vn 0.378307 -0.856655 0.350688 +vn 0.783776 -0.620991 0.005249 +vn 0.726829 -0.553880 0.406079 +vn 0.994812 -0.101627 0.001984 +vn 0.908139 -0.082766 0.410321 +vn 0.003082 -0.939787 0.341685 +vn 0.002167 -0.619495 0.784967 +vn 0.011536 -0.679403 0.733634 +vn 0.044679 -0.675588 0.735923 +vn 0.123325 -0.652272 0.747856 +vn 0.275399 -0.556871 0.783593 +vn 0.460067 -0.316263 0.829615 +vn 0.563036 -0.041200 0.825373 +vn -0.000427 0.122166 0.992492 +vn 0.000397 0.003632 0.999969 +vn 0.002869 0.011841 0.999908 +vn 0.004852 0.029298 0.999542 +vn -0.008179 0.053499 0.998505 +vn -0.046510 0.041536 0.998047 +vn -0.039155 0.003113 0.999207 +vn -0.850551 0.473769 -0.228217 +vn -0.897885 0.424177 -0.117649 +vn -0.880886 0.473281 0.000000 +vn -0.013611 0.682394 0.730827 +vn -0.053896 0.680441 0.730796 +vn -0.147557 0.656789 0.739464 +vn -0.325968 0.560564 0.761223 +vn -0.537645 0.315806 0.781762 +vn -0.611530 0.029939 0.790613 +vn -0.904172 0.427137 0.000000 +vn -0.897885 0.424146 0.117618 +vn -0.020112 0.949461 0.313150 +vn -0.081820 0.945433 0.315287 +vn -0.227699 0.916379 0.329173 +vn -0.504196 0.785302 0.359203 +vn -0.810633 0.443220 0.382611 +vn -0.921232 0.039705 0.386944 +vn -0.020569 0.949400 -0.313334 +vn -0.021729 0.999756 -0.000092 +vn -0.004242 0.950468 -0.310770 +vn -0.088260 0.996094 -0.000488 +vn -0.246895 0.969024 -0.001343 +vn -0.549730 0.835322 -0.002350 +vn -0.880673 0.473647 -0.001984 +vn -0.999084 0.042146 -0.000610 +vn -0.877041 0.418744 -0.235298 +vn -0.920286 0.391156 0.000000 +vn -0.905637 0.407056 -0.118656 +vn -0.083132 0.945006 -0.316202 +vn -0.230201 0.914823 -0.331797 +vn -0.505570 0.782800 -0.362743 +vn -0.808710 0.444960 -0.384625 +vn -0.920835 0.042055 -0.387646 +vn -0.897885 0.424146 -0.117618 +vn -0.901883 0.415448 -0.118168 +vn -0.014161 0.682394 -0.730796 +vn -0.055361 0.680074 -0.731010 +vn -0.150029 0.655660 -0.739982 +vn -0.327616 0.560594 -0.760491 +vn -0.537431 0.320933 -0.779809 +vn -0.611988 0.033387 -0.790155 +vn 0.015168 -0.949339 -0.313852 +vn 0.011902 -0.679403 -0.733634 +vn 0.003265 -0.939817 -0.341594 +vn 0.000183 0.004212 -0.999969 +vn 0.003510 0.014008 -0.999878 +vn 0.005921 0.035951 -0.999329 +vn -0.010132 0.064333 -0.997864 +vn -0.051576 0.048463 -0.997467 +vn -0.041597 0.003998 -0.999115 +vn 0.003082 -0.620106 -0.784478 +vn -0.000031 0.122440 -0.992462 +vn -0.897885 0.424177 0.117649 +vn 0.046449 -0.674398 -0.736869 +vn 0.125980 -0.648946 -0.750298 +vn 0.275430 -0.552477 -0.786676 +vn 0.455519 -0.320536 -0.830500 +vn 0.561693 -0.046480 -0.826014 +vn -0.888668 0.391644 0.238441 +vn 0.058046 -0.947630 -0.314005 +vn 0.159948 -0.933836 -0.319865 +vn 0.380169 -0.857753 -0.345927 +vn 0.725547 -0.560930 -0.398602 +vn 0.908597 -0.089236 -0.407971 +vn 0.003235 -0.999969 0.000031 +vn 0.973144 0.230110 0.000824 +vn 0.890896 0.211737 0.401776 +vn 0.912900 0.408094 0.002533 +vn 0.836970 0.380932 0.392834 +vn 0.829035 0.559160 0.003784 +vn 0.764519 0.528550 0.368969 +vn 0.718650 0.695334 0.003937 +vn 0.668294 0.663717 0.335917 +vn 0.579577 0.814905 0.002838 +vn 0.542650 0.779687 0.312357 +vn 0.495163 0.868770 0.002258 +vn 0.458052 0.820643 0.341624 +vn 0.561205 0.137028 0.816218 +vn 0.532029 0.253456 0.807886 +vn 0.497543 0.363445 0.787591 +vn 0.449538 0.472060 0.758293 +vn 0.373669 0.563555 0.736686 +vn 0.289041 0.531114 0.796442 +vn -0.023225 -0.005249 0.999695 +vn -0.016785 -0.010254 0.999786 +vn -0.011444 -0.012940 0.999847 +vn -0.009796 -0.013276 0.999847 +vn -0.014801 -0.013916 0.999786 +vn -0.089755 -0.176122 0.980255 +vn -0.585772 -0.152379 0.795984 +vn -0.538896 -0.288766 0.791314 +vn -0.484146 -0.407910 0.774071 +vn -0.424635 -0.509781 0.748161 +vn -0.355907 -0.584765 0.728935 +vn -0.889828 -0.237159 0.389782 +vn -0.808740 -0.446852 0.382366 +vn -0.702475 -0.613269 0.361095 +vn -0.590625 -0.734855 0.333293 +vn -0.483291 -0.816767 0.315104 +vn -0.912076 0.409955 0.000000 +vn -0.965606 -0.259987 -0.000458 +vn -0.872433 -0.488693 -0.001465 +vn -0.748436 -0.663167 -0.002197 +vn -0.621601 -0.783288 -0.002136 +vn -0.507065 -0.861873 -0.001251 +vn -0.438215 -0.854366 0.279183 +vn -0.456130 -0.889889 -0.000732 +vn -0.889126 -0.238868 -0.390332 +vn -0.807001 -0.448531 -0.384075 +vn -0.700980 -0.613392 -0.363750 +vn -0.590442 -0.733757 -0.336039 +vn -0.484787 -0.815332 -0.316477 +vn -0.440962 -0.852931 -0.279305 +vn -0.359691 -0.584185 -0.727531 +vn -0.358074 -0.682241 -0.637410 +vn -0.585467 -0.154668 -0.795770 +vn -0.538499 -0.291696 -0.790490 +vn -0.484512 -0.409772 -0.772851 +vn -0.426496 -0.510056 -0.746910 +vn -0.909543 -0.399274 -0.115207 +vn -0.971191 -0.204688 -0.121891 +vn -0.912931 -0.326609 -0.244606 +vn -0.020478 -0.017853 -0.999603 +vn -0.024537 -0.005737 -0.999664 +vn -0.020844 -0.012207 -0.999695 +vn -0.017548 -0.016846 -0.999695 +vn -0.016724 -0.018097 -0.999695 +vn -0.909116 -0.400311 0.115055 +vn -0.873775 -0.472610 0.114475 +vn -0.795892 -0.566485 0.213538 +vn -0.353069 -0.684103 0.638203 +vn 0.559679 0.139714 -0.816828 +vn 0.528581 0.255501 -0.809473 +vn 0.494217 0.362987 -0.789911 +vn 0.449049 0.469283 -0.760308 +vn 0.378246 0.560869 -0.736412 +vn -0.091983 -0.174383 -0.980346 +vn 0.295267 0.530625 -0.794488 +vn 0.890500 0.214759 -0.401044 +vn 0.836634 0.384075 -0.390515 +vn 0.765191 0.530198 -0.365123 +vn 0.671041 0.663228 -0.331339 +vn 0.547929 0.777642 -0.308206 +vn 0.464522 0.818842 -0.337199 +vn 0.931486 0.265572 -0.248543 +vn 0.939543 0.342357 0.000000 +vn 0.947539 0.295114 -0.122684 +vn -0.351421 0.936186 0.001953 +vn -0.144444 0.989502 0.003174 +vn -0.126743 0.878811 0.459975 +vn -0.716758 0.697287 -0.000946 +vn -0.299997 0.838313 0.455214 +vn -0.621876 0.660207 0.421155 +vn -0.901822 0.432081 -0.004517 +vn -0.807031 0.443434 0.389904 +vn -0.930204 0.366863 -0.008484 +vn -0.824549 0.383312 0.416059 +vn -0.850673 0.525529 -0.011628 +vn -0.722465 0.508988 0.467910 +vn -0.668447 0.743645 -0.011139 +vn -0.531449 0.686514 0.496170 +vn -0.116459 0.505448 0.854946 +vn -0.258400 0.470656 0.843593 +vn -0.407605 0.396985 0.822321 +vn -0.450270 0.352367 0.820399 +vn -0.385876 0.395734 0.833338 +vn -0.270669 0.487838 0.829890 +vn 0.141606 -0.001190 0.989898 +vn -0.067690 0.525346 0.848170 +vn 0.989593 0.100253 0.103122 +vn 0.970244 0.213324 0.114475 +vn 0.960418 0.152654 0.232917 +vn 0.241829 0.092502 0.965880 +vn 0.209296 0.170660 0.962828 +vn 0.096194 0.178625 0.979186 +vn 0.009552 0.154332 0.987945 +vn -0.000122 0.151952 0.988372 +vn 0.361248 -0.477279 0.801019 +vn 0.607929 -0.282540 0.741997 +vn 0.679220 -0.106754 0.726096 +vn 0.583911 -0.078524 0.807978 +vn 0.402722 -0.205237 0.891995 +vn 0.279519 -0.338694 0.898404 +vn 0.488601 -0.768700 0.412671 +vn 0.784570 -0.501511 0.364544 +vn 0.893918 -0.279611 0.350291 +vn 0.861415 -0.285287 0.420179 +vn 0.679373 -0.540452 0.496323 +vn 0.458327 -0.754540 0.469588 +vn 0.524155 -0.851588 -0.000153 +vn 0.827143 -0.561968 0.001679 +vn 0.943205 -0.332133 0.003479 +vn 0.933256 -0.359081 0.005737 +vn 0.756859 -0.653493 0.006470 +vn 0.492843 -0.870083 0.004120 +vn 0.322489 -0.946562 -0.001129 +vn 0.912839 -0.326609 0.244942 +vn 0.824396 -0.565996 0.000000 +vn 0.894162 -0.447676 0.000000 +vn 0.486557 -0.770501 -0.411756 +vn 0.783990 -0.504074 -0.362285 +vn 0.895199 -0.281899 -0.345134 +vn 0.863735 -0.289010 -0.412824 +vn 0.682119 -0.544267 -0.488296 +vn 0.461928 -0.758202 -0.460128 +vn 0.357463 -0.479141 -0.801599 +vn 0.605884 -0.285867 -0.742393 +vn 0.679739 -0.108646 -0.725333 +vn 0.583636 -0.077883 -0.808222 +vn 0.401440 -0.199225 -0.893918 +vn 0.281961 -0.330638 -0.900632 +vn 0.135228 -0.002380 -0.990783 +vn 0.235755 0.091128 -0.967498 +vn 0.200720 0.170629 -0.964660 +vn 0.086123 0.184576 -0.979003 +vn 0.000671 0.174322 -0.984680 +vn -0.007141 0.169012 -0.985565 +vn 0.966613 -0.042848 -0.252602 +vn 0.960418 0.152654 -0.232917 +vn 0.989593 0.100223 -0.103092 +vn -0.119297 0.503342 -0.855770 +vn -0.261269 0.472793 -0.841517 +vn -0.414075 0.399792 -0.817713 +vn -0.459700 0.357036 -0.813105 +vn -0.394024 0.408490 -0.823298 +vn -0.277871 0.487381 -0.827754 +vn -0.072207 0.520127 -0.851009 +vn -0.298654 0.840297 -0.452376 +vn -0.617512 0.663961 -0.421613 +vn -0.801324 0.450209 -0.393872 +vn -0.819422 0.389691 -0.420270 +vn -0.721274 0.506912 -0.471969 +vn -0.538347 0.670644 -0.510239 +vn -0.482009 0.876125 -0.005127 +vn -0.394635 0.815363 0.423536 +vn -0.321909 0.946745 -0.002594 +vn -0.255287 0.921995 0.291086 +vn 0.004242 0.999969 0.000397 +vn -0.002960 0.999939 -0.010102 +vn 0.853450 0.521073 -0.007050 +vn 0.392041 0.688986 -0.609546 +vn 0.805170 -0.592517 -0.023621 +vn 0.588763 -0.206122 -0.781579 +vn 0.681478 -0.731040 -0.033296 +vn 0.485031 -0.441237 -0.754967 +vn -0.206824 0.638203 0.741539 +vn -0.129490 0.862056 0.489944 +vn -0.033418 0.999176 0.022340 +vn 0.047700 0.864040 -0.501114 +vn 0.099307 0.538743 -0.836573 +vn 0.053560 0.251839 -0.966277 +vn 0.020112 0.322611 0.946287 +vn 0.021943 0.748894 0.662282 +vn -0.025941 0.995605 0.089908 +vn -0.059175 0.930876 -0.360424 +vn -0.080172 0.784448 -0.614948 +vn -0.142582 0.557604 -0.817743 +vn 0.281747 -0.174993 0.943388 +vn 0.303903 0.444136 0.842830 +vn 0.034333 0.983764 0.175970 +vn -0.113865 0.956420 -0.268777 +vn -0.155339 0.858852 -0.488021 +vn -0.207404 0.641865 -0.738182 +vn 0.467238 -0.683187 0.561144 +vn 0.699515 0.004364 0.714560 +vn 0.355296 0.891934 0.279641 +vn -0.170354 0.971465 -0.164861 +vn -0.245552 0.901181 -0.357097 +vn -0.248726 0.651082 -0.717063 +vn 0.494430 -0.869167 0.006317 +vn 0.933134 -0.358898 0.019868 +vn 0.703146 0.710685 0.021790 +vn -0.203650 0.978942 -0.012574 +vn -0.326456 0.942869 -0.066073 +vn -0.397595 0.857082 -0.327525 +vn 0.460616 -0.712546 -0.529221 +vn 0.695486 -0.098544 -0.711722 +vn 0.397534 0.853816 -0.336070 +vn -0.198248 0.963439 0.180151 +vn -0.306833 0.888516 0.341075 +vn -0.393689 0.807672 0.438887 +vn 0.276559 -0.211951 -0.937315 +vn 0.294626 0.366161 -0.882656 +vn 0.046632 0.973235 -0.224982 +vn -0.146733 0.912168 0.382611 +vn -0.202643 0.700797 0.683950 +vn -0.232673 0.506485 0.830226 +vn 0.011689 0.309397 -0.950835 +vn 0.013245 0.708640 -0.705435 +vn -0.027589 0.995758 -0.087680 +vn -0.047395 0.829371 0.556658 +vn -0.015259 0.386608 0.922086 +vn 0.004639 0.119510 0.992798 +vn -0.211035 0.631001 -0.746513 +vn -0.138768 0.848781 -0.510147 +vn -0.024995 0.999664 -0.001190 +vn 0.120426 0.724570 0.678579 +vn 0.260750 0.006531 0.965361 +vn 0.272500 -0.255898 0.927488 +vn -0.395581 0.809961 -0.432905 +vn -0.258827 0.918851 -0.297800 +vn 0.004730 0.999878 0.013031 +vn 0.466628 0.599780 0.649983 +vn 0.621937 -0.400861 0.672628 +vn 0.551042 -0.592181 0.587878 +vn 0.649068 0.384991 -0.656087 +vn 0.055971 0.691214 0.720450 +vn -0.115940 0.804590 0.582354 +vn -0.262185 0.897946 0.353435 +vn -0.341655 0.885006 -0.316263 +vn -0.081423 0.793085 -0.603626 +vn -0.155675 0.857753 -0.489883 +vn 0.728690 0.365978 0.578784 +vn 0.318674 0.539384 0.779382 +vn 0.953551 0.300150 -0.024415 +vn -0.133976 0.836818 -0.530808 +vn 0.095401 0.667959 -0.738029 +vn 0.000000 0.999969 0.000000 +vn -0.992523 -0.122013 0.000000 +vn -0.937346 -0.348338 0.000000 +vn -0.905148 -0.348827 -0.242836 +vn -0.958617 -0.122227 -0.257057 +vn -0.832057 0.554674 0.000000 +vn -0.803217 0.555376 -0.215339 +vn -0.048616 0.998810 0.000000 +vn -0.046236 0.998840 -0.012726 +vn 0.544267 0.838893 0.000000 +vn 0.525376 0.839106 0.140843 +vn 0.783471 0.621387 0.000000 +vn 0.756371 0.621845 0.202918 +vn 0.880886 0.473281 0.000000 +vn 0.850551 0.473769 0.228217 +vn -0.810907 -0.349376 -0.469375 +vn -0.859004 -0.122410 -0.497085 +vn -0.719657 0.555559 -0.416425 +vn -0.041749 0.998810 -0.024415 +vn 0.470077 0.839625 0.272011 +vn 0.677236 0.622608 0.391980 +vn 0.761803 0.474471 0.440962 +vn -0.662465 -0.349620 -0.662465 +vn -0.701773 -0.122440 -0.701773 +vn -0.587878 0.555650 -0.587878 +vn -0.034272 0.998810 -0.034272 +vn 0.383831 0.839808 0.383831 +vn 0.553148 0.622913 0.553148 +vn 0.622303 0.474776 0.622303 +vn -0.469375 -0.349376 -0.810907 +vn -0.497085 -0.122379 -0.859004 +vn -0.416425 0.555559 -0.719657 +vn -0.024415 0.998810 -0.041749 +vn 0.272011 0.839625 0.470077 +vn 0.391980 0.622608 0.677236 +vn 0.440962 0.474471 0.761834 +vn -0.242836 -0.348827 -0.905148 +vn -0.257057 -0.122227 -0.958617 +vn -0.215339 0.555376 -0.803217 +vn -0.012726 0.998840 -0.046205 +vn 0.140843 0.839106 0.525376 +vn 0.202918 0.621845 0.756371 +vn 0.228217 0.473769 0.850551 +vn 0.000000 -0.348338 -0.937346 +vn 0.000000 -0.122013 -0.992523 +vn 0.000000 0.554674 -0.832057 +vn 0.000000 0.998810 -0.048616 +vn 0.000000 0.838893 0.544267 +vn 0.000000 0.621387 0.783471 +vn 0.000000 0.473281 0.880886 +vn 0.242836 -0.348827 -0.905148 +vn 0.257057 -0.122227 -0.958617 +vn 0.215308 0.555376 -0.803217 +vn 0.012726 0.998840 -0.046205 +vn -0.140843 0.839106 0.525376 +vn -0.202918 0.621845 0.756340 +vn -0.228217 0.473769 0.850551 +vn 0.469375 -0.349376 -0.810907 +vn 0.497085 -0.122379 -0.859004 +vn 0.416425 0.555559 -0.719657 +vn 0.024415 0.998810 -0.041749 +vn -0.272011 0.839625 0.470077 +vn -0.391980 0.622608 0.677236 +vn -0.440962 0.474502 0.761803 +vn 0.662465 -0.349620 -0.662465 +vn 0.701773 -0.122471 -0.701773 +vn 0.587878 0.555650 -0.587878 +vn 0.034272 0.998810 -0.034272 +vn -0.383831 0.839808 0.383831 +vn -0.553148 0.622913 0.553148 +vn -0.622303 0.474776 0.622303 +vn 0.810907 -0.349406 -0.469375 +vn 0.859004 -0.122379 -0.497085 +vn 0.719657 0.555559 -0.416425 +vn 0.041749 0.998810 -0.024415 +vn -0.470077 0.839625 0.272011 +vn -0.677236 0.622608 0.391980 +vn -0.761803 0.474471 0.440962 +vn 0.905148 -0.348827 -0.242836 +vn 0.958617 -0.122227 -0.257057 +vn 0.803217 0.555376 -0.215339 +vn 0.046205 0.998840 -0.012726 +vn -0.525376 0.839106 0.140843 +vn -0.756340 0.621876 0.202918 +vn -0.850551 0.473769 0.228217 +vn 0.937346 -0.348338 0.000000 +vn 0.992523 -0.122013 0.000000 +vn 0.832026 0.554674 0.000000 +vn 0.048616 0.998810 0.000000 +vn -0.544267 0.838893 0.000000 +vn -0.783471 0.621387 0.000000 +vn 0.905148 -0.348827 0.242836 +vn 0.958617 -0.122227 0.257057 +vn 0.803217 0.555376 0.215308 +vn 0.046205 0.998840 0.012726 +vn -0.525376 0.839106 -0.140843 +vn -0.756340 0.621876 -0.202918 +vn 0.810907 -0.349406 0.469375 +vn 0.859004 -0.122379 0.497085 +vn 0.719657 0.555559 0.416425 +vn 0.041749 0.998810 0.024415 +vn -0.470077 0.839625 -0.272011 +vn -0.677236 0.622608 -0.391980 +vn -0.761803 0.474471 -0.440962 +vn 0.662465 -0.349620 0.662465 +vn 0.701773 -0.122471 0.701773 +vn 0.587878 0.555650 0.587878 +vn 0.034272 0.998810 0.034272 +vn -0.383831 0.839808 -0.383831 +vn -0.553148 0.622913 -0.553148 +vn -0.622303 0.474776 -0.622303 +vn 0.469375 -0.349376 0.810907 +vn 0.497085 -0.122379 0.859004 +vn 0.416425 0.555559 0.719657 +vn 0.024415 0.998810 0.041749 +vn -0.272011 0.839625 -0.470077 +vn -0.391980 0.622608 -0.677236 +vn -0.440962 0.474471 -0.761803 +vn 0.242836 -0.348827 0.905148 +vn 0.257057 -0.122227 0.958617 +vn 0.215339 0.555376 0.803217 +vn 0.012726 0.998840 0.046205 +vn -0.140843 0.839106 -0.525376 +vn -0.202918 0.621845 -0.756371 +vn -0.228217 0.473769 -0.850551 +vn 0.000000 -0.348338 0.937346 +vn 0.000000 -0.122013 0.992523 +vn 0.000000 0.554674 0.832057 +vn 0.000000 0.998810 0.048616 +vn 0.000000 0.838893 -0.544267 +vn 0.000000 0.621387 -0.783471 +vn 0.000000 0.473281 -0.880886 +vn -0.242836 -0.348827 0.905148 +vn -0.257057 -0.122227 0.958617 +vn -0.215308 0.555376 0.803217 +vn -0.012726 0.998840 0.046205 +vn 0.140843 0.839106 -0.525376 +vn 0.202918 0.621845 -0.756371 +vn 0.228217 0.473769 -0.850551 +vn -0.469375 -0.349376 0.810907 +vn -0.497085 -0.122379 0.859004 +vn -0.416425 0.555559 0.719657 +vn -0.024415 0.998810 0.041749 +vn 0.272011 0.839625 -0.470077 +vn 0.391980 0.622608 -0.677236 +vn 0.440962 0.474471 -0.761803 +vn -0.662465 -0.349620 0.662465 +vn -0.701773 -0.122440 0.701773 +vn -0.587878 0.555650 0.587878 +vn -0.034272 0.998810 0.034272 +vn 0.383831 0.839808 -0.383831 +vn 0.553148 0.622913 -0.553148 +vn 0.622303 0.474776 -0.622303 +vn -0.810907 -0.349376 0.469375 +vn -0.859004 -0.122410 0.497085 +vn -0.719657 0.555528 0.416425 +vn -0.041749 0.998810 0.024415 +vn 0.470077 0.839625 -0.272011 +vn 0.677236 0.622639 -0.391980 +vn 0.761803 0.474471 -0.440962 +vn -0.905148 -0.348827 0.242836 +vn -0.958617 -0.122227 0.257057 +vn -0.803217 0.555376 0.215339 +vn -0.046236 0.998840 0.012726 +vn 0.525376 0.839106 -0.140843 +vn 0.756371 0.621845 -0.202918 +vn 0.850551 0.473769 -0.228217 +vn 0.908292 0.418256 0.000000 +vn 0.877041 0.418744 0.235298 +vn 0.920286 0.391156 0.000000 +vn 0.888668 0.391644 0.238441 +vn 0.907315 0.342753 0.243446 +vn 0.785638 0.419416 0.454756 +vn 0.796075 0.392285 0.460799 +vn 0.812830 0.343333 0.470504 +vn 0.931486 0.265542 0.248543 +vn 0.834162 0.266366 0.482864 +vn 0.855312 0.152379 0.495132 +vn 0.966613 -0.042848 0.252602 +vn 0.864498 -0.045808 0.500504 +vn 0.641804 0.419691 0.641804 +vn 0.650349 0.392499 0.650349 +vn 0.664052 0.343577 0.664052 +vn 0.681509 0.266579 0.681509 +vn 0.698813 0.152501 0.698813 +vn 0.706351 -0.045869 0.706351 +vn 0.454756 0.419416 0.785638 +vn 0.460799 0.392285 0.796075 +vn 0.470504 0.343333 0.812830 +vn 0.482864 0.266366 0.834162 +vn 0.495132 0.152409 0.855312 +vn 0.500504 -0.045808 0.864498 +vn 0.235298 0.418744 0.877041 +vn 0.238441 0.391644 0.888668 +vn 0.243446 0.342753 0.907315 +vn 0.249855 0.265908 0.931028 +vn 0.256172 0.152104 0.954558 +vn 0.258980 -0.045717 0.964782 +vn 0.000000 0.418256 0.908292 +vn 0.000000 0.391156 0.920286 +vn 0.000000 0.342357 0.939543 +vn 0.000000 0.265542 0.964080 +vn 0.000000 0.151891 0.988372 +vn 0.000000 -0.045656 0.998932 +vn -0.235298 0.418744 0.877041 +vn -0.238441 0.391644 0.888668 +vn -0.243446 0.342753 0.907315 +vn -0.249855 0.265877 0.931028 +vn -0.256172 0.152104 0.954558 +vn -0.258980 -0.045717 0.964782 +vn -0.454756 0.419416 0.785638 +vn -0.460799 0.392285 0.796075 +vn -0.470504 0.343333 0.812830 +vn -0.482864 0.266366 0.834162 +vn -0.495132 0.152379 0.855312 +vn -0.500504 -0.045808 0.864498 +vn -0.641804 0.419691 0.641804 +vn -0.650349 0.392499 0.650349 +vn -0.664052 0.343577 0.664052 +vn -0.681509 0.266579 0.681509 +vn -0.698813 0.152501 0.698813 +vn -0.706351 -0.045869 0.706351 +vn -0.785638 0.419416 0.454756 +vn -0.796075 0.392285 0.460799 +vn -0.812830 0.343364 0.470504 +vn -0.834162 0.266366 0.482864 +vn -0.855312 0.152379 0.495132 +vn -0.864498 -0.045808 0.500504 +vn -0.907315 0.342753 0.243446 +vn -0.931028 0.265908 0.249855 +vn -0.954558 0.152104 0.256172 +vn -0.964782 -0.045717 0.258980 +vn -0.939543 0.342357 0.000000 +vn -0.964080 0.265542 0.000000 +vn -0.988372 0.151891 0.000000 +vn -0.888668 0.391644 -0.238441 +vn -0.907315 0.342753 -0.243446 +vn -0.931028 0.265877 -0.249855 +vn -0.954558 0.152104 -0.256172 +vn -0.785638 0.419416 -0.454756 +vn -0.796075 0.392285 -0.460799 +vn -0.812830 0.343333 -0.470504 +vn -0.834162 0.266366 -0.482864 +vn -0.855312 0.152379 -0.495132 +vn -0.964782 -0.045717 -0.258980 +vn -0.864498 -0.045808 -0.500504 +vn -0.641804 0.419691 -0.641804 +vn -0.650349 0.392499 -0.650349 +vn -0.664052 0.343577 -0.664052 +vn -0.681509 0.266579 -0.681509 +vn -0.698813 0.152501 -0.698813 +vn -0.706351 -0.045869 -0.706351 +vn -0.454756 0.419416 -0.785638 +vn -0.460799 0.392285 -0.796075 +vn -0.470504 0.343333 -0.812830 +vn -0.482864 0.266366 -0.834162 +vn -0.495132 0.152379 -0.855312 +vn -0.500504 -0.045808 -0.864498 +vn -0.235298 0.418744 -0.877041 +vn -0.238441 0.391644 -0.888668 +vn -0.243446 0.342753 -0.907315 +vn -0.249855 0.265908 -0.931028 +vn -0.256172 0.152104 -0.954558 +vn -0.258980 -0.045717 -0.964782 +vn 0.000000 0.418256 -0.908292 +vn 0.000000 0.391156 -0.920286 +vn 0.000000 0.342357 -0.939543 +vn 0.000000 0.265542 -0.964080 +vn 0.000000 0.151891 -0.988372 +vn 0.000000 -0.045656 -0.998932 +vn 0.235298 0.418744 -0.877041 +vn 0.238441 0.391644 -0.888668 +vn 0.243446 0.342753 -0.907315 +vn 0.249855 0.265877 -0.931028 +vn 0.256172 0.152104 -0.954558 +vn 0.258980 -0.045717 -0.964782 +vn 0.454756 0.419416 -0.785638 +vn 0.460799 0.392285 -0.796075 +vn 0.470504 0.343333 -0.812830 +vn 0.482864 0.266366 -0.834162 +vn 0.495132 0.152379 -0.855312 +vn 0.500504 -0.045808 -0.864498 +vn 0.641804 0.419691 -0.641804 +vn 0.650349 0.392499 -0.650349 +vn 0.664052 0.343577 -0.664052 +vn 0.681509 0.266579 -0.681509 +vn 0.698813 0.152501 -0.698813 +vn 0.706351 -0.045869 -0.706351 +vn 0.785638 0.419416 -0.454756 +vn 0.796075 0.392285 -0.460799 +vn 0.812830 0.343364 -0.470504 +vn 0.834162 0.266366 -0.482864 +vn 0.855312 0.152379 -0.495132 +vn 0.864498 -0.045808 -0.500504 +vn 0.877041 0.418744 -0.235298 +vn 0.888668 0.391644 -0.238441 +vn 0.907315 0.342753 -0.243446 +vn 0.795892 -0.566485 0.213538 +vn 0.712180 -0.701987 0.000000 +vn 0.687399 -0.702445 0.184393 +vn 0.652974 -0.757347 0.000000 +vn 0.630146 -0.757805 0.169012 +vn 0.724021 -0.689749 0.000000 +vn 0.698752 -0.690329 0.187414 +vn 0.886410 -0.462874 0.000000 +vn 0.855861 -0.463454 0.229530 +vn 0.817774 -0.327158 0.473434 +vn 0.712729 -0.567248 0.412549 +vn 0.615345 -0.703146 0.356151 +vn 0.564043 -0.758446 0.326456 +vn 0.625660 -0.690939 0.362102 +vn 0.766625 -0.464125 0.443678 +vn 0.668111 -0.327403 0.668111 +vn 0.582171 -0.567522 0.582171 +vn 0.502579 -0.703421 0.502579 +vn 0.460646 -0.758660 0.460646 +vn 0.510971 -0.691183 0.510971 +vn 0.626209 -0.464370 0.626240 +vn 0.473434 -0.327158 0.817774 +vn 0.412549 -0.567248 0.712729 +vn 0.356151 -0.703146 0.615375 +vn 0.326456 -0.758446 0.564043 +vn 0.362102 -0.690939 0.625660 +vn 0.443678 -0.464125 0.766625 +vn 0.245003 -0.326609 0.912839 +vn 0.213538 -0.566485 0.795892 +vn 0.184393 -0.702445 0.687399 +vn 0.169012 -0.757805 0.630146 +vn 0.187414 -0.690329 0.698752 +vn 0.229530 -0.463454 0.855831 +vn 0.000000 -0.326243 0.945250 +vn 0.000000 -0.565996 0.824396 +vn 0.000000 -0.701987 0.712180 +vn 0.000000 -0.757347 0.652974 +vn 0.000000 -0.689749 0.724021 +vn 0.000000 -0.462905 0.886380 +vn -0.245003 -0.326609 0.912839 +vn -0.213538 -0.566485 0.795892 +vn -0.184393 -0.702445 0.687399 +vn -0.169012 -0.757805 0.630146 +vn -0.187414 -0.690329 0.698752 +vn -0.229530 -0.463454 0.855861 +vn -0.473434 -0.327158 0.817774 +vn -0.412549 -0.567248 0.712729 +vn -0.356151 -0.703146 0.615375 +vn -0.326456 -0.758446 0.564043 +vn -0.362102 -0.690939 0.625660 +vn -0.443678 -0.464125 0.766625 +vn -0.668111 -0.327403 0.668111 +vn -0.582171 -0.567522 0.582171 +vn -0.502579 -0.703421 0.502579 +vn -0.460646 -0.758660 0.460646 +vn -0.510971 -0.691183 0.510971 +vn -0.626209 -0.464370 0.626209 +vn -0.817774 -0.327158 0.473434 +vn -0.712729 -0.567248 0.412549 +vn -0.615375 -0.703146 0.356151 +vn -0.564043 -0.758446 0.326456 +vn -0.625660 -0.690939 0.362102 +vn -0.766625 -0.464125 0.443678 +vn -0.912931 -0.326609 0.244575 +vn -0.687399 -0.702445 0.184393 +vn -0.630146 -0.757805 0.169012 +vn -0.698752 -0.690329 0.187414 +vn -0.855831 -0.463485 0.229530 +vn -0.824396 -0.565996 0.000000 +vn -0.712180 -0.701987 0.000000 +vn -0.652974 -0.757347 0.000000 +vn -0.724021 -0.689749 0.000000 +vn -0.886410 -0.462874 0.000000 +vn -0.795892 -0.566485 -0.213538 +vn -0.687399 -0.702445 -0.184393 +vn -0.630146 -0.757805 -0.169012 +vn -0.698752 -0.690329 -0.187414 +vn -0.855831 -0.463454 -0.229530 +vn -0.817774 -0.327158 -0.473434 +vn -0.712729 -0.567217 -0.412549 +vn -0.615375 -0.703146 -0.356151 +vn -0.564043 -0.758446 -0.326456 +vn -0.625660 -0.690939 -0.362102 +vn -0.766625 -0.464125 -0.443678 +vn -0.668111 -0.327403 -0.668111 +vn -0.582171 -0.567522 -0.582171 +vn -0.502579 -0.703421 -0.502579 +vn -0.460646 -0.758660 -0.460646 +vn -0.510971 -0.691183 -0.510971 +vn -0.626209 -0.464370 -0.626209 +vn -0.473434 -0.327158 -0.817774 +vn -0.412549 -0.567248 -0.712729 +vn -0.356151 -0.703146 -0.615375 +vn -0.326456 -0.758446 -0.564043 +vn -0.362102 -0.690939 -0.625660 +vn -0.443678 -0.464125 -0.766625 +vn -0.245003 -0.326609 -0.912839 +vn -0.213538 -0.566485 -0.795892 +vn -0.184393 -0.702445 -0.687399 +vn -0.169012 -0.757805 -0.630146 +vn -0.187414 -0.690329 -0.698752 +vn -0.229530 -0.463454 -0.855831 +vn 0.000000 -0.326243 -0.945250 +vn 0.000000 -0.565996 -0.824396 +vn 0.000000 -0.701987 -0.712180 +vn 0.000000 -0.757347 -0.652974 +vn 0.000000 -0.689749 -0.724021 +vn 0.000000 -0.462905 -0.886380 +vn 0.245003 -0.326609 -0.912839 +vn 0.213538 -0.566485 -0.795892 +vn 0.184393 -0.702445 -0.687399 +vn 0.169012 -0.757805 -0.630146 +vn 0.187445 -0.690329 -0.698752 +vn 0.229530 -0.463454 -0.855861 +vn 0.473434 -0.327158 -0.817774 +vn 0.412549 -0.567248 -0.712729 +vn 0.356151 -0.703146 -0.615375 +vn 0.326456 -0.758446 -0.564043 +vn 0.362102 -0.690939 -0.625660 +vn 0.443678 -0.464125 -0.766625 +vn 0.668111 -0.327403 -0.668111 +vn 0.582171 -0.567522 -0.582171 +vn 0.502579 -0.703421 -0.502579 +vn 0.460646 -0.758660 -0.460646 +vn 0.510971 -0.691183 -0.510971 +vn 0.626209 -0.464370 -0.626209 +vn 0.817774 -0.327158 -0.473434 +vn 0.712729 -0.567248 -0.412549 +vn 0.615375 -0.703146 -0.356151 +vn 0.564043 -0.758446 -0.326456 +vn 0.625660 -0.690939 -0.362102 +vn 0.766625 -0.464125 -0.443678 +vn 0.912839 -0.326609 -0.244942 +vn 0.795892 -0.566485 -0.213538 +vn 0.687399 -0.702445 -0.184393 +vn 0.630146 -0.757805 -0.169012 +vn 0.698752 -0.690329 -0.187414 +vn 0.855861 -0.463454 -0.229530 +vn 0.025666 -0.999664 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.024781 -0.999664 -0.006623 +vn 0.068667 -0.997620 0.000000 +vn 0.066256 -0.997620 -0.017731 +vn 0.157170 -0.987548 0.000000 +vn 0.151677 -0.987579 -0.040620 +vn 0.373150 -0.927763 0.000000 +vn 0.360118 -0.927885 -0.096469 +vn 0.789148 -0.614154 0.000000 +vn 0.762017 -0.614399 -0.204505 +vn 0.022156 -0.999664 -0.012787 +vn 0.059236 -0.997650 -0.034272 +vn 0.135624 -0.987640 -0.078463 +vn 0.322153 -0.928129 -0.186377 +vn 0.682333 -0.615131 -0.394971 +vn 0.018067 -0.999664 -0.018067 +vn 0.048341 -0.997650 -0.048341 +vn 0.110691 -0.987640 -0.110691 +vn 0.262947 -0.928251 -0.262947 +vn 0.557329 -0.615375 -0.557329 +vn 0.012787 -0.999664 -0.022156 +vn 0.034272 -0.997650 -0.059236 +vn 0.078463 -0.987640 -0.135624 +vn 0.186377 -0.928129 -0.322153 +vn 0.394971 -0.615131 -0.682302 +vn 0.006623 -0.999664 -0.024781 +vn 0.017731 -0.997620 -0.066256 +vn 0.040620 -0.987579 -0.151677 +vn 0.096469 -0.927885 -0.360118 +vn 0.204474 -0.614399 -0.762017 +vn 0.000000 -0.999664 -0.025666 +vn 0.000000 -0.997620 -0.068667 +vn 0.000000 -0.987548 -0.157170 +vn 0.000000 -0.927763 -0.373150 +vn 0.000000 -0.614154 -0.789148 +vn -0.006623 -0.999664 -0.024781 +vn -0.017731 -0.997620 -0.066256 +vn -0.040620 -0.987579 -0.151677 +vn -0.096469 -0.927885 -0.360118 +vn -0.204474 -0.614399 -0.762017 +vn -0.012787 -0.999664 -0.022156 +vn -0.034272 -0.997650 -0.059236 +vn -0.078463 -0.987640 -0.135624 +vn -0.186377 -0.928129 -0.322153 +vn -0.394971 -0.615131 -0.682333 +vn -0.018067 -0.999664 -0.018067 +vn -0.048341 -0.997650 -0.048341 +vn -0.110691 -0.987640 -0.110691 +vn -0.262947 -0.928251 -0.262947 +vn -0.557329 -0.615375 -0.557329 +vn -0.022156 -0.999664 -0.012787 +vn -0.059236 -0.997650 -0.034272 +vn -0.135624 -0.987640 -0.078463 +vn -0.322153 -0.928129 -0.186377 +vn -0.682302 -0.615131 -0.394971 +vn -0.024781 -0.999664 -0.006623 +vn -0.066256 -0.997620 -0.017731 +vn -0.151677 -0.987579 -0.040620 +vn -0.360118 -0.927885 -0.096469 +vn -0.762017 -0.614399 -0.204474 +vn -0.025666 -0.999664 0.000000 +vn -0.068667 -0.997620 0.000000 +vn -0.157170 -0.987548 0.000000 +vn -0.373150 -0.927763 0.000000 +vn -0.789148 -0.614154 0.000000 +vn -0.024781 -0.999664 0.006623 +vn -0.066256 -0.997620 0.017731 +vn -0.151677 -0.987579 0.040620 +vn -0.360149 -0.927885 0.096469 +vn -0.762017 -0.614399 0.204474 +vn -0.022156 -0.999664 0.012787 +vn -0.059236 -0.997650 0.034272 +vn -0.135624 -0.987640 0.078463 +vn -0.322153 -0.928129 0.186377 +vn -0.682333 -0.615131 0.394971 +vn -0.018067 -0.999664 0.018067 +vn -0.048341 -0.997650 0.048341 +vn -0.110691 -0.987640 0.110691 +vn -0.262947 -0.928251 0.262947 +vn -0.557329 -0.615375 0.557329 +vn -0.012787 -0.999664 0.022156 +vn -0.034272 -0.997650 0.059236 +vn -0.078463 -0.987640 0.135624 +vn -0.186377 -0.928129 0.322153 +vn -0.394971 -0.615131 0.682302 +vn -0.006623 -0.999664 0.024781 +vn -0.017731 -0.997620 0.066256 +vn -0.040620 -0.987579 0.151677 +vn -0.096469 -0.927885 0.360118 +vn -0.204474 -0.614399 0.762017 +vn 0.000000 -0.999664 0.025666 +vn 0.000000 -0.997620 0.068667 +vn 0.000000 -0.987548 0.157170 +vn 0.000000 -0.927763 0.373150 +vn 0.000000 -0.614154 0.789148 +vn 0.006623 -0.999664 0.024781 +vn 0.017731 -0.997620 0.066256 +vn 0.040620 -0.987579 0.151677 +vn 0.096469 -0.927885 0.360149 +vn 0.204474 -0.614399 0.762017 +vn 0.012787 -0.999664 0.022156 +vn 0.034272 -0.997650 0.059236 +vn 0.078463 -0.987640 0.135624 +vn 0.186377 -0.928129 0.322153 +vn 0.394971 -0.615131 0.682333 +vn 0.018067 -0.999664 0.018067 +vn 0.048341 -0.997650 0.048341 +vn 0.110691 -0.987640 0.110691 +vn 0.262947 -0.928251 0.262947 +vn 0.557329 -0.615375 0.557329 +vn 0.022156 -0.999664 0.012787 +vn 0.059236 -0.997650 0.034272 +vn 0.135624 -0.987640 0.078463 +vn 0.322153 -0.928129 0.186346 +vn 0.682302 -0.615131 0.394971 +vn 0.024781 -0.999664 0.006623 +vn 0.066256 -0.997620 0.017731 +vn 0.151677 -0.987579 0.040620 +vn 0.360118 -0.927885 0.096469 +vn 0.762017 -0.614399 0.204474 +vn 0.464827 -0.373638 -0.802667 +vn 0.655812 -0.373882 -0.655812 +vn 0.000000 -0.372539 0.927976 +vn -0.240699 -0.373028 0.896023 +vn -0.802667 -0.373608 0.464827 +vn 0.896023 -0.372997 -0.240699 +vn -0.927976 -0.372539 0.000000 +vn 0.927976 -0.372539 0.000000 +vn 0.717063 0.696982 0.000000 +vn 0.990387 -0.138310 -0.000061 +vn 0.956694 -0.138737 0.255806 +vn 0.692129 0.697470 0.185583 +vn 0.857326 -0.139317 0.495529 +vn 0.620045 0.697653 0.358837 +vn 0.700125 -0.139531 0.700217 +vn 0.506516 0.697714 0.506546 +vn 0.495468 -0.139286 0.857356 +vn 0.358776 0.697714 0.620014 +vn 0.255867 -0.138737 0.956694 +vn 0.185583 0.697531 0.692068 +vn 0.000061 -0.138310 0.990387 +vn 0.000000 0.696982 0.717063 +vn -0.255806 -0.138737 0.956694 +vn -0.185583 0.697470 0.692129 +vn -0.495529 -0.139317 0.857326 +vn -0.358837 0.697653 0.620045 +vn -0.700217 -0.139531 0.700156 +vn -0.506546 0.697714 0.506516 +vn -0.857356 -0.139286 0.495468 +vn -0.620014 0.697714 0.358776 +vn -0.956694 -0.138737 0.255867 +vn -0.692068 0.697531 0.185583 +vn -0.990387 -0.138310 0.000061 +vn -0.717063 0.696982 0.000000 +vn -0.956694 -0.138737 -0.255806 +vn -0.692129 0.697470 -0.185583 +vn -0.857326 -0.139317 -0.495529 +vn -0.620045 0.697653 -0.358837 +vn -0.700125 -0.139531 -0.700217 +vn -0.506516 0.697714 -0.506546 +vn -0.495468 -0.139286 -0.857356 +vn -0.358776 0.697714 -0.620014 +vn -0.255867 -0.138737 -0.956694 +vn -0.185583 0.697531 -0.692068 +vn -0.000061 -0.138310 -0.990387 +vn 0.000000 0.696982 -0.717063 +vn 0.255806 -0.138737 -0.956694 +vn 0.185583 0.697470 -0.692129 +vn 0.495529 -0.139317 -0.857326 +vn 0.358837 0.697653 -0.620045 +vn 0.700217 -0.139531 -0.700156 +vn 0.506546 0.697714 -0.506516 +vn 0.857356 -0.139286 -0.495468 +vn 0.620014 0.697714 -0.358776 +vn 0.956694 -0.138737 -0.255867 +vn 0.692068 0.697531 -0.185583 +vn 0.292520 0.956236 0.000000 +vn 0.282083 0.956389 0.075686 +vn 0.177953 0.984008 0.000000 +vn 0.171606 0.984069 0.046022 +vn 0.158879 0.987274 0.000000 +vn 0.153264 0.987304 0.041078 +vn 0.217719 0.975982 0.000000 +vn 0.210059 0.976043 0.056276 +vn 0.504715 0.863277 0.000000 +vn 0.487197 0.863460 0.130558 +vn 0.693258 0.720664 0.000000 +vn 0.669057 0.721183 0.179449 +vn 0.252388 0.956511 0.146092 +vn 0.153508 0.984130 0.088839 +vn 0.137059 0.987365 0.079318 +vn 0.187872 0.976135 0.108676 +vn 0.435926 0.863887 0.252205 +vn 0.598956 0.721824 0.346660 +vn 0.206091 0.956572 0.206091 +vn 0.125340 0.984161 0.125340 +vn 0.111911 0.987396 0.111911 +vn 0.153356 0.976196 0.153356 +vn 0.355907 0.864071 0.355907 +vn 0.489151 0.722098 0.489151 +vn 0.146092 0.956511 0.252388 +vn 0.088839 0.984130 0.153508 +vn 0.079318 0.987365 0.137059 +vn 0.108676 0.976135 0.187872 +vn 0.252205 0.863887 0.435926 +vn 0.346660 0.721824 0.598956 +vn 0.075686 0.956389 0.282083 +vn 0.046022 0.984069 0.171606 +vn 0.041078 0.987304 0.153264 +vn 0.056276 0.976043 0.210059 +vn 0.130558 0.863460 0.487197 +vn 0.179449 0.721183 0.669057 +vn 0.000000 0.956236 0.292520 +vn 0.000000 0.984008 0.177953 +vn 0.000000 0.987274 0.158879 +vn 0.000000 0.975982 0.217719 +vn 0.000000 0.863277 0.504715 +vn 0.000000 0.720664 0.693258 +vn -0.075686 0.956389 0.282083 +vn -0.046022 0.984069 0.171606 +vn -0.041078 0.987304 0.153264 +vn -0.056276 0.976043 0.210059 +vn -0.130558 0.863460 0.487197 +vn -0.179449 0.721183 0.669057 +vn -0.146092 0.956511 0.252388 +vn -0.088839 0.984130 0.153508 +vn -0.079318 0.987365 0.137059 +vn -0.108676 0.976135 0.187872 +vn -0.252205 0.863887 0.435926 +vn -0.346660 0.721824 0.598956 +vn -0.206091 0.956572 0.206091 +vn -0.125340 0.984161 0.125340 +vn -0.111911 0.987396 0.111911 +vn -0.153356 0.976196 0.153356 +vn -0.355907 0.864071 0.355907 +vn -0.489151 0.722098 0.489151 +vn -0.252388 0.956511 0.146092 +vn -0.153508 0.984130 0.088839 +vn -0.137059 0.987365 0.079318 +vn -0.187872 0.976135 0.108676 +vn -0.435926 0.863887 0.252205 +vn -0.598956 0.721824 0.346660 +vn -0.282083 0.956389 0.075686 +vn -0.171606 0.984069 0.046022 +vn -0.153264 0.987304 0.041078 +vn -0.210059 0.976043 0.056276 +vn -0.487197 0.863460 0.130558 +vn -0.669057 0.721183 0.179449 +vn -0.292520 0.956236 0.000000 +vn -0.177953 0.984008 0.000000 +vn -0.158879 0.987274 0.000000 +vn -0.217719 0.975982 0.000000 +vn -0.504715 0.863277 0.000000 +vn -0.693258 0.720664 0.000000 +vn -0.282083 0.956389 -0.075686 +vn -0.171606 0.984069 -0.046022 +vn -0.153264 0.987304 -0.041078 +vn -0.210059 0.976043 -0.056276 +vn -0.487197 0.863460 -0.130558 +vn -0.669057 0.721183 -0.179449 +vn -0.252388 0.956511 -0.146092 +vn -0.153508 0.984130 -0.088839 +vn -0.137059 0.987365 -0.079318 +vn -0.187872 0.976135 -0.108676 +vn -0.435926 0.863887 -0.252205 +vn -0.598956 0.721824 -0.346660 +vn -0.206091 0.956572 -0.206091 +vn -0.125340 0.984161 -0.125340 +vn -0.111911 0.987396 -0.111911 +vn -0.153356 0.976196 -0.153356 +vn -0.355907 0.864071 -0.355907 +vn -0.489151 0.722098 -0.489151 +vn -0.146092 0.956511 -0.252388 +vn -0.088839 0.984130 -0.153508 +vn -0.079318 0.987365 -0.137059 +vn -0.108676 0.976135 -0.187872 +vn -0.252205 0.863887 -0.435926 +vn -0.346660 0.721824 -0.598956 +vn -0.075686 0.956389 -0.282083 +vn -0.046022 0.984069 -0.171606 +vn -0.041078 0.987304 -0.153264 +vn -0.056276 0.976043 -0.210059 +vn -0.130558 0.863460 -0.487197 +vn -0.179449 0.721183 -0.669057 +vn 0.000000 0.956236 -0.292520 +vn 0.000000 0.984008 -0.177953 +vn 0.000000 0.987274 -0.158879 +vn 0.000000 0.975982 -0.217719 +vn 0.000000 0.863277 -0.504715 +vn 0.000000 0.720664 -0.693258 +vn 0.075686 0.956389 -0.282083 +vn 0.046022 0.984069 -0.171606 +vn 0.041078 0.987304 -0.153264 +vn 0.056276 0.976043 -0.210059 +vn 0.130558 0.863460 -0.487197 +vn 0.179449 0.721183 -0.669057 +vn 0.146092 0.956511 -0.252388 +vn 0.088839 0.984130 -0.153508 +vn 0.079318 0.987365 -0.137059 +vn 0.108676 0.976135 -0.187872 +vn 0.252205 0.863887 -0.435926 +vn 0.346660 0.721824 -0.598956 +vn 0.206091 0.956572 -0.206091 +vn 0.125340 0.984161 -0.125340 +vn 0.111911 0.987396 -0.111911 +vn 0.153356 0.976196 -0.153356 +vn 0.355907 0.864071 -0.355907 +vn 0.489151 0.722098 -0.489151 +vn 0.252388 0.956511 -0.146092 +vn 0.153508 0.984130 -0.088839 +vn 0.137059 0.987365 -0.079318 +vn 0.187872 0.976135 -0.108676 +vn 0.435926 0.863887 -0.252205 +vn 0.598956 0.721824 -0.346660 +vn 0.282083 0.956389 -0.075686 +vn 0.171606 0.984069 -0.046022 +vn 0.153264 0.987304 -0.041078 +vn 0.210059 0.976043 -0.056276 +vn 0.487197 0.863460 -0.130558 +vn 0.669057 0.721183 -0.179449 +vn 0.363842 0.931455 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.351451 0.931516 0.093509 +vn 0.968261 0.249916 0.000000 +vn 0.935423 0.249763 0.250130 +vn 0.842860 -0.538102 0.000000 +vn 0.813959 -0.538713 0.217292 +vn 0.786767 -0.617206 -0.000031 +vn 0.759514 -0.618000 0.202857 +vn 0.314432 0.931791 0.181280 +vn 0.838404 0.249855 0.484359 +vn 0.729026 -0.539720 0.420911 +vn 0.680013 -0.619068 0.392743 +vn 0.256386 0.931913 0.256417 +vn 0.684652 0.249886 0.684652 +vn 0.595050 -0.540147 0.595050 +vn 0.555010 -0.619526 0.555040 +vn 0.181280 0.931791 0.314432 +vn 0.484359 0.249825 0.838404 +vn 0.420881 -0.539720 0.729026 +vn 0.392712 -0.619098 0.680013 +vn 0.093509 0.931516 0.351451 +vn 0.250160 0.249763 0.935423 +vn 0.217322 -0.538713 0.813959 +vn 0.202887 -0.618030 0.759484 +vn 0.000000 0.931455 0.363842 +vn 0.000000 0.249916 0.968261 +vn 0.000000 -0.538102 0.842860 +vn 0.000031 -0.617206 0.786767 +vn -0.093509 0.931516 0.351451 +vn -0.250130 0.249763 0.935423 +vn -0.217292 -0.538682 0.813959 +vn -0.202857 -0.618000 0.759514 +vn -0.181280 0.931791 0.314432 +vn -0.484359 0.249855 0.838404 +vn -0.420911 -0.539720 0.729026 +vn -0.392743 -0.619068 0.680013 +vn -0.256417 0.931913 0.256386 +vn -0.684652 0.249886 0.684652 +vn -0.595050 -0.540147 0.595050 +vn -0.555040 -0.619526 0.555010 +vn -0.314432 0.931791 0.181280 +vn -0.838404 0.249825 0.484359 +vn -0.729026 -0.539720 0.420881 +vn -0.680013 -0.619098 0.392712 +vn -0.351451 0.931516 0.093509 +vn -0.935423 0.249763 0.250160 +vn -0.813959 -0.538713 0.217292 +vn -0.759484 -0.618030 0.202887 +vn -0.363842 0.931455 0.000000 +vn -0.968261 0.249916 0.000000 +vn -0.842860 -0.538102 0.000000 +vn -0.786767 -0.617206 0.000031 +vn -0.351451 0.931516 -0.093509 +vn -0.935423 0.249763 -0.250130 +vn -0.813959 -0.538713 -0.217292 +vn -0.759514 -0.618000 -0.202857 +vn -0.314432 0.931791 -0.181280 +vn -0.838404 0.249855 -0.484359 +vn -0.729026 -0.539720 -0.420911 +vn -0.680013 -0.619068 -0.392743 +vn -0.256386 0.931913 -0.256417 +vn -0.684652 0.249886 -0.684652 +vn -0.595050 -0.540147 -0.595050 +vn -0.555010 -0.619526 -0.555040 +vn -0.181280 0.931791 -0.314432 +vn -0.484359 0.249825 -0.838404 +vn -0.420881 -0.539720 -0.729026 +vn -0.392712 -0.619098 -0.680013 +vn -0.093509 0.931516 -0.351451 +vn -0.250160 0.249763 -0.935423 +vn -0.217322 -0.538713 -0.813959 +vn -0.202887 -0.618030 -0.759484 +vn 0.000000 0.931455 -0.363842 +vn 0.000000 0.249916 -0.968261 +vn 0.000000 -0.538102 -0.842860 +vn -0.000031 -0.617206 -0.786767 +vn 0.093509 0.931516 -0.351451 +vn 0.250130 0.249763 -0.935423 +vn 0.217292 -0.538682 -0.813959 +vn 0.202857 -0.618000 -0.759514 +vn 0.181280 0.931791 -0.314432 +vn 0.484359 0.249855 -0.838404 +vn 0.420911 -0.539720 -0.729026 +vn 0.392743 -0.619068 -0.680013 +vn 0.256417 0.931913 -0.256386 +vn 0.684652 0.249886 -0.684652 +vn 0.595050 -0.540147 -0.595050 +vn 0.555040 -0.619526 -0.555010 +vn 0.314432 0.931791 -0.181280 +vn 0.838404 0.249825 -0.484359 +vn 0.729026 -0.539720 -0.420881 +vn 0.680013 -0.619098 -0.392712 +vn 0.351451 0.931516 -0.093509 +vn 0.935423 0.249763 -0.250160 +vn 0.813959 -0.538713 -0.217292 +vn 0.759484 -0.618030 -0.202887 +vn -0.354198 0.930296 -0.095187 +vn 0.095187 0.930296 0.354198 +vn 0.354198 0.930296 0.095187 +vn 0.183721 0.930387 0.317179 +vn -0.183721 0.930387 -0.317179 +vn -0.367443 0.930021 0.000000 +vn -0.183721 0.930387 0.317179 +vn 0.367412 0.930021 0.000000 +vn -0.317179 0.930387 0.183721 +vn -0.095187 0.930296 -0.354198 +vn 0.000000 0.930021 -0.367443 +vn -0.354198 0.930296 0.095187 +vn 0.095187 0.930296 -0.354198 +vn 0.000000 0.930021 0.367443 +vn -0.317179 0.930387 -0.183721 +vn 0.317179 0.930387 -0.183721 +vn -0.095187 0.930296 0.354198 +vn 0.317179 0.930387 0.183721 +vn 0.354198 0.930296 -0.095187 +vn 0.183721 0.930387 -0.317179 +vn -0.034730 0.999390 0.000000 +vn 0.033479 0.999390 -0.009003 +vn 0.034730 0.999390 0.000000 +vn 0.009003 0.999390 -0.033479 +vn 0.000000 0.999390 -0.034730 +vn -0.259163 0.930387 0.259163 +vn -0.017335 0.999390 0.029939 +vn 0.947539 0.295083 0.122654 +vn -0.004486 0.999969 0.000000 +vn -0.004151 0.950468 0.310739 +vn -0.003021 0.719291 0.694662 +vn -0.998688 0.050722 0.000000 +vn -0.003143 0.719321 -0.694632 +vn 0.970214 0.213324 -0.114505 +vn -0.136235 0.879482 -0.455947 +vn 0.949858 0.312662 0.000000 +vn 0.055757 -0.017579 -0.998260 +vn 0.201300 -0.540880 -0.816645 +vn 0.974456 -0.186071 -0.125645 +vn 0.988098 -0.096286 0.119938 +vn 0.974456 -0.186041 0.125614 +vn -0.879574 -0.475723 0.000000 +vn -0.873775 -0.472610 -0.114475 +vn 0.988067 -0.096286 -0.119938 +vn 0.295480 -0.855464 -0.425214 +vn -0.976196 -0.174993 -0.127903 +vn -0.971007 -0.205725 0.121677 +vn -0.976196 -0.174963 0.127903 +vn -0.976196 -0.174993 0.127903 +vn 0.896054 -0.372997 0.240699 +vn -0.802667 -0.373638 -0.464827 +vn -0.655812 -0.373852 -0.655812 +vn -0.240699 -0.373028 -0.896023 +vn -0.464827 -0.373638 -0.802667 +vn -0.896023 -0.373028 0.240699 +vn 0.000000 -0.372539 -0.927976 +vn -0.655812 -0.373852 0.655812 +vn 0.240699 -0.373028 0.896023 +vn -0.896023 -0.373028 -0.240699 +vn 0.802667 -0.373638 -0.464827 +vn 0.655812 -0.373882 0.655812 +vn 0.464827 -0.373638 0.802667 +vn -0.464827 -0.373638 0.802667 +vn 0.240699 -0.373028 -0.896023 +vn 0.802667 -0.373638 0.464827 +vn -0.033479 0.999390 0.009003 +vn -0.259163 0.930387 -0.259163 +vn -0.024445 0.999390 -0.024445 +vn -0.029939 0.999390 -0.017335 +vn 0.259163 0.930387 -0.259163 +vn 0.024445 0.999390 -0.024445 +vn 0.017335 0.999390 -0.029939 +vn 0.029939 0.999390 -0.017335 +vn 0.033479 0.999390 0.009003 +vn -0.009003 0.999390 0.033479 +vn 0.000000 0.999390 0.034730 +vn -0.017335 0.999390 -0.029939 +vn 0.259163 0.930387 0.259163 +vn 0.029939 0.999390 0.017335 +vn -0.009003 0.999390 -0.033479 +vn 0.024445 0.999390 0.024445 +vn 0.017335 0.999390 0.029939 +vn 0.009003 0.999390 0.033479 +vn -0.033479 0.999390 -0.009003 +vn -0.024445 0.999390 0.024445 +vn -0.029939 0.999390 0.017335 +vn 0.055757 -0.017579 0.998260 +vn 0.294198 -0.855403 0.426252 +vn 0.201300 -0.540880 0.816614 +s 1 +f 34//1 1243//2 593//3 +f 52//4 27//5 40//6 +f 52//4 40//6 65//7 +f 77//8 52//4 65//7 +f 77//8 65//7 84//9 +f 107//10 77//8 84//9 +f 107//10 84//9 85//11 +f 115//12 107//10 85//11 +f 115//12 85//11 99//13 +f 129//14 115//12 99//13 +f 129//14 99//13 128//15 +f 1252//16 36//17 40//6 +f 65//7 40//6 64//18 +f 65//7 64//18 58//19 +f 84//9 65//7 58//19 +f 84//9 58//19 59//20 +f 85//11 84//9 59//20 +f 85//11 59//20 70//21 +f 99//13 85//11 70//21 +f 99//13 70//21 98//22 +f 128//15 99//13 98//22 +f 128//15 98//22 114//23 +f 1244//24 33//25 64//18 +f 58//19 64//18 33//25 +f 58//19 33//25 35//26 +f 59//20 58//19 35//26 +f 59//20 35//26 45//27 +f 70//21 59//20 45//27 +f 70//21 45//27 69//28 +f 98//22 70//21 69//28 +f 98//22 69//28 83//29 +f 114//23 98//22 83//29 +f 114//23 83//29 113//30 +f 553//31 1//32 566//33 +f 35//26 33//25 20//34 +f 35//26 20//34 24//35 +f 45//27 35//26 24//35 +f 45//27 24//35 44//36 +f 69//28 45//27 44//36 +f 69//28 44//36 57//37 +f 83//29 69//28 57//37 +f 83//29 57//37 82//38 +f 113//30 83//29 82//38 +f 113//30 82//38 112//39 +f 566//33 1283//40 9//41 +f 24//35 20//34 18//42 +f 24//35 18//42 23//43 +f 44//36 24//35 23//43 +f 44//36 23//43 32//44 +f 57//37 44//36 32//44 +f 57//37 32//44 56//45 +f 82//38 57//37 56//45 +f 82//38 56//45 81//46 +f 112//39 82//38 81//46 +f 112//39 81//46 111//47 +f 4//48 8//49 1250//50 +f 23//43 18//42 8//49 +f 23//43 8//49 17//51 +f 32//44 23//43 17//51 +f 32//44 17//51 31//52 +f 56//45 32//44 31//52 +f 56//45 31//52 55//53 +f 81//46 56//45 55//53 +f 81//46 55//53 80//54 +f 111//47 81//46 80//54 +f 111//47 80//54 110//55 +f 565//56 592//57 1233//58 +f 17//51 8//49 4//48 +f 17//51 4//48 16//59 +f 31//52 17//51 16//59 +f 31//52 16//59 30//60 +f 55//53 31//52 30//60 +f 55//53 30//60 54//61 +f 80//54 55//53 54//61 +f 80//54 54//61 79//62 +f 110//55 80//54 79//62 +f 110//55 79//62 109//63 +f 1//32 565//56 2//64 +f 6//65 2//64 565//56 +f 16//59 4//48 7//66 +f 16//59 7//66 22//67 +f 30//60 16//59 22//67 +f 30//60 22//67 43//68 +f 54//61 30//60 43//68 +f 54//61 43//68 68//69 +f 79//62 54//61 68//69 +f 79//62 68//69 97//70 +f 109//63 79//62 97//70 +f 109//63 97//70 127//71 +f 565//56 1233//58 1249//58 +f 13//72 14//73 5//74 +f 22//67 7//66 15//75 +f 22//67 15//75 29//76 +f 43//68 22//67 29//76 +f 43//68 29//76 42//77 +f 68//69 43//68 42//77 +f 68//69 42//77 67//78 +f 97//70 68//69 67//78 +f 97//70 67//78 96//79 +f 127//71 97//70 96//79 +f 127//71 96//79 126//80 +f 11//81 15//75 1240//82 +f 1289//83 34//1 593//3 +f 29//76 15//75 14//73 +f 29//76 14//73 21//84 +f 42//77 29//76 21//84 +f 42//77 21//84 41//85 +f 67//78 42//77 41//85 +f 67//78 41//85 66//86 +f 96//79 67//78 66//86 +f 96//79 66//86 95//87 +f 126//80 96//79 95//87 +f 126//80 95//87 125//88 +f 636//89 1243//2 26//2 +f 636//89 26//2 592//57 +f 21//84 14//73 13//72 +f 21//84 13//72 28//90 +f 41//85 21//84 28//90 +f 41//85 28//90 53//91 +f 66//86 41//85 53//91 +f 66//86 53//91 78//92 +f 95//87 66//86 78//92 +f 95//87 78//92 108//93 +f 125//88 95//87 108//93 +f 125//88 108//93 136//94 +f 12//95 13//72 5//74 +f 28//90 13//72 27//5 +f 28//90 27//5 52//4 +f 53//91 28//90 52//4 +f 53//91 52//4 77//8 +f 78//92 53//91 77//8 +f 78//92 77//8 107//10 +f 108//93 78//92 107//10 +f 108//93 107//10 115//12 +f 136//94 108//93 115//12 +f 136//94 115//12 129//14 +f 148//96 129//14 128//15 +f 148//96 128//15 143//97 +f 121//98 148//96 143//97 +f 121//98 143//97 122//99 +f 92//100 121//98 122//99 +f 92//100 122//99 93//101 +f 62//102 92//100 93//101 +f 62//102 93//101 63//103 +f 39//104 62//102 63//103 +f 39//104 63//103 51//105 +f 10//106 39//104 51//105 +f 10//106 51//105 49//107 +f 143//97 128//15 114//23 +f 143//97 114//23 142//108 +f 122//99 143//97 142//108 +f 122//99 142//108 123//109 +f 93//101 122//99 123//109 +f 93//101 123//109 94//110 +f 63//103 93//101 94//110 +f 63//103 94//110 76//111 +f 51//105 63//103 76//111 +f 51//105 76//111 75//112 +f 49//107 51//105 75//112 +f 49//107 75//112 61//113 +f 142//108 114//23 113//30 +f 142//108 113//30 141//114 +f 123//109 142//108 141//114 +f 123//109 141//114 124//115 +f 94//110 123//109 124//115 +f 94//110 124//115 106//116 +f 76//111 94//110 106//116 +f 76//111 106//116 105//117 +f 75//112 76//111 105//117 +f 75//112 105//117 91//118 +f 61//113 75//112 91//118 +f 61//113 91//118 90//119 +f 141//114 113//30 112//39 +f 141//114 112//39 140//120 +f 124//115 141//114 140//120 +f 124//115 140//120 135//121 +f 106//116 124//115 135//121 +f 106//116 135//121 134//122 +f 105//117 106//116 134//122 +f 105//117 134//122 120//123 +f 91//118 105//117 120//123 +f 91//118 120//123 119//124 +f 90//119 91//118 119//124 +f 140//120 112//39 111//47 +f 140//120 111//47 139//125 +f 135//121 140//120 139//125 +f 135//121 139//125 155//126 +f 134//122 135//121 155//126 +f 134//122 155//126 147//127 +f 120//123 134//122 147//127 +f 120//123 147//127 144//128 +f 119//124 120//123 144//128 +f 119//124 144//128 116//129 +f 26//2 1234//130 592//57 +f 139//125 111//47 110//55 +f 139//125 110//55 138//131 +f 155//126 139//125 138//131 +f 155//126 138//131 156//132 +f 147//127 155//126 156//132 +f 147//127 156//132 145//133 +f 144//128 147//127 145//133 +f 144//128 145//133 117//134 +f 116//129 144//128 117//134 +f 116//129 117//134 88//135 +f 27//5 13//72 12//95 +f 1242//136 88//135 71//137 +f 138//131 110//55 109//63 +f 138//131 109//63 137//138 +f 156//132 138//131 137//138 +f 156//132 137//138 154//139 +f 145//133 156//132 154//139 +f 145//133 154//139 131//140 +f 117//134 145//133 131//140 +f 117//134 131//140 101//141 +f 88//135 117//134 101//141 +f 88//135 101//141 86//142 +f 60//143 74//144 1248//145 +f 137//138 109//63 127//71 +f 137//138 127//71 151//146 +f 154//139 137//138 151//146 +f 154//139 151//146 153//147 +f 131//140 154//139 153//147 +f 131//140 153//147 130//148 +f 101//141 131//140 130//148 +f 101//141 130//148 100//149 +f 86//142 101//141 100//149 +f 86//142 100//149 74//144 +f 47//150 1235//151 631//152 +f 74//144 48//153 1248//145 +f 151//146 127//71 126//80 +f 151//146 126//80 150//154 +f 153//147 151//146 150//154 +f 153//147 150//154 146//155 +f 130//148 153//147 146//155 +f 130//148 146//155 118//156 +f 100//149 130//148 118//156 +f 100//149 118//156 89//157 +f 74//144 100//149 89//157 +f 74//144 89//157 48//153 +f 1247//158 87//159 715//160 +f 104//161 116//129 1242//136 +f 150//154 126//80 125//88 +f 150//154 125//88 149//162 +f 146//155 150//154 149//162 +f 146//155 149//162 132//163 +f 118//156 146//155 132//163 +f 118//156 132//163 102//164 +f 89//157 118//156 102//164 +f 89//157 102//164 72//165 +f 48//153 89//157 72//165 +f 48//153 72//165 46//166 +f 37//167 48//153 46//166 +f 37//167 46//166 38//168 +f 149//162 125//88 136//94 +f 149//162 136//94 152//169 +f 132//163 149//162 152//169 +f 132//163 152//169 133//170 +f 102//164 132//163 133//170 +f 102//164 133//170 103//171 +f 72//165 102//164 103//171 +f 72//165 103//171 73//172 +f 46//166 72//165 73//172 +f 46//166 73//172 50//173 +f 38//168 46//166 50//173 +f 38//168 50//173 25//174 +f 152//169 136//94 129//14 +f 152//169 129//14 148//96 +f 133//170 152//169 148//96 +f 133//170 148//96 121//98 +f 103//171 133//170 121//98 +f 103//171 121//98 92//100 +f 73//172 103//171 92//100 +f 73//172 92//100 62//102 +f 50//173 73//172 62//102 +f 50//173 62//102 39//104 +f 25//174 50//173 39//104 +f 39//104 10//106 25//174 +f 539//175 509//176 159//177 +f 160//178 158//179 157//180 +f 166//181 160//178 163//182 +f 166//181 163//182 173//183 +f 177//184 166//181 173//183 +f 177//184 173//183 183//185 +f 189//186 177//184 183//185 +f 189//186 183//185 197//187 +f 205//188 189//186 197//187 +f 205//188 197//187 216//189 +f 225//190 205//188 216//189 +f 225//190 216//189 235//191 +f 173//183 163//182 172//192 +f 173//183 172//192 184//193 +f 183//185 173//183 184//193 +f 183//185 184//193 198//194 +f 197//187 183//185 198//194 +f 197//187 198//194 217//195 +f 216//189 197//187 217//195 +f 216//189 217//195 236//196 +f 235//191 216//189 236//196 +f 235//191 236//196 253//197 +f 182//198 172//192 1254//199 +f 1255//200 167//201 595//202 +f 184//193 172//192 182//198 +f 184//193 182//198 196//203 +f 198//194 184//193 196//203 +f 198//194 196//203 214//204 +f 217//195 198//194 214//204 +f 217//195 214//204 232//205 +f 236//196 217//195 232//205 +f 236//196 232//205 250//206 +f 253//197 236//196 250//206 +f 253//197 250//206 267//207 +f 196//203 182//198 199//208 +f 196//203 199//208 215//209 +f 214//204 196//203 215//209 +f 214//204 215//209 233//210 +f 232//205 214//204 233//210 +f 232//205 233//210 251//211 +f 250//206 232//205 251//211 +f 250//206 251//211 257//212 +f 267//207 250//206 257//212 +f 267//207 257//212 256//213 +f 215//209 199//208 218//214 +f 215//209 218//214 234//215 +f 233//210 215//209 234//215 +f 233//210 234//215 241//216 +f 251//211 233//210 241//216 +f 251//211 241//216 240//217 +f 257//212 251//211 240//217 +f 257//212 240//217 239//218 +f 256//213 257//212 239//218 +f 256//213 239//218 238//219 +f 234//215 218//214 219//220 +f 234//215 219//220 224//221 +f 241//216 234//215 224//221 +f 241//216 224//221 223//222 +f 240//217 241//216 223//222 +f 240//217 223//222 222//223 +f 239//218 240//217 222//223 +f 239//218 222//223 221//224 +f 238//219 239//218 221//224 +f 238//219 221//224 220//225 +f 219//220 218//214 1285//226 +f 648//227 691//228 207//229 +f 224//221 219//220 208//230 +f 224//221 208//230 204//231 +f 223//222 224//221 204//231 +f 223//222 204//231 203//232 +f 222//223 223//222 203//232 +f 222//223 203//232 202//233 +f 221//224 222//223 202//233 +f 221//224 202//233 201//234 +f 220//225 221//224 201//234 +f 220//225 201//234 212//235 +f 204//231 208//230 191//236 +f 204//231 191//236 188//237 +f 203//232 204//231 188//237 +f 203//232 188//237 187//238 +f 202//233 203//232 187//238 +f 202//233 187//238 186//239 +f 201//234 202//233 186//239 +f 201//234 186//239 194//240 +f 212//235 201//234 194//240 +f 212//235 194//240 211//241 +f 188//237 191//236 174//242 +f 188//237 174//242 176//243 +f 187//238 188//237 176//243 +f 187//238 176//243 175//244 +f 186//239 187//238 175//244 +f 186//239 175//244 180//245 +f 194//240 186//239 180//245 +f 194//240 180//245 193//246 +f 211//241 194//240 193//246 +f 211//241 193//246 210//247 +f 613//248 585//249 1258//250 +f 176//243 174//242 168//251 +f 176//243 168//251 165//252 +f 175//244 176//243 165//252 +f 175//244 165//252 170//253 +f 180//245 175//244 170//253 +f 180//245 170//253 179//254 +f 193//246 180//245 179//254 +f 193//246 179//254 192//255 +f 210//247 193//246 192//255 +f 210//247 192//255 209//256 +f 168//251 174//242 164//257 +f 165//252 168//251 161//258 +f 165//252 161//258 162//259 +f 170//253 165//252 162//259 +f 170//253 162//259 171//260 +f 179//254 170//253 171//260 +f 179//254 171//260 181//261 +f 192//255 179//254 181//261 +f 192//255 181//261 195//262 +f 209//256 192//255 195//262 +f 209//256 195//262 213//263 +f 160//178 161//258 158//179 +f 161//258 160//178 162//259 +f 162//259 160//178 166//181 +f 171//260 162//259 166//181 +f 171//260 166//181 177//184 +f 181//261 171//260 177//184 +f 181//261 177//184 189//186 +f 195//262 181//261 189//186 +f 195//262 189//186 205//188 +f 213//263 195//262 205//188 +f 213//263 205//188 225//190 +f 242//264 225//190 235//191 +f 242//264 235//191 252//265 +f 258//266 242//264 252//265 +f 258//266 252//265 268//267 +f 273//268 258//266 268//267 +f 273//268 268//267 283//269 +f 287//270 273//268 283//269 +f 287//270 283//269 298//271 +f 300//272 287//270 298//271 +f 300//272 298//271 299//273 +f 312//274 300//272 299//273 +f 312//274 299//273 310//275 +f 252//265 235//191 253//197 +f 252//265 253//197 269//276 +f 268//267 252//265 269//276 +f 268//267 269//276 284//277 +f 283//269 268//267 284//277 +f 283//269 284//277 286//278 +f 298//271 283//269 286//278 +f 298//271 286//278 285//279 +f 299//273 298//271 285//279 +f 299//273 285//279 296//280 +f 310//275 299//273 296//280 +f 310//275 296//280 309//281 +f 269//276 253//197 267//207 +f 269//276 267//207 272//282 +f 284//277 269//276 272//282 +f 284//277 272//282 271//283 +f 286//278 284//277 271//283 +f 286//278 271//283 270//284 +f 285//279 286//278 270//284 +f 285//279 270//284 281//285 +f 296//280 285//279 281//285 +f 296//280 281//285 295//286 +f 309//281 296//280 295//286 +f 309//281 295//286 308//287 +f 272//282 267//207 256//213 +f 272//282 256//213 255//288 +f 271//283 272//282 255//288 +f 271//283 255//288 254//289 +f 270//284 271//283 254//289 +f 270//284 254//289 265//290 +f 281//285 270//284 265//290 +f 281//285 265//290 280//291 +f 295//286 281//285 280//291 +f 295//286 280//291 294//292 +f 308//287 295//286 294//292 +f 308//287 294//292 307//293 +f 255//288 256//213 238//219 +f 255//288 238//219 237//294 +f 254//289 255//288 237//294 +f 254//289 237//294 248//295 +f 265//290 254//289 248//295 +f 265//290 248//295 264//296 +f 280//291 265//290 264//296 +f 280//291 264//296 279//297 +f 294//292 280//291 279//297 +f 294//292 279//297 293//298 +f 307//293 294//292 293//298 +f 307//293 293//298 306//299 +f 237//294 238//219 220//225 +f 237//294 220//225 230//300 +f 248//295 237//294 230//300 +f 248//295 230//300 247//301 +f 264//296 248//295 247//301 +f 264//296 247//301 263//302 +f 279//297 264//296 263//302 +f 279//297 263//302 278//303 +f 293//298 279//297 278//303 +f 293//298 278//303 292//304 +f 306//299 293//298 292//304 +f 306//299 292//304 305//305 +f 230//300 220//225 212//235 +f 230//300 212//235 229//306 +f 247//301 230//300 229//306 +f 247//301 229//306 246//307 +f 263//302 247//301 246//307 +f 263//302 246//307 262//308 +f 278//303 263//302 262//308 +f 278//303 262//308 277//309 +f 292//304 278//303 277//309 +f 292//304 277//309 291//310 +f 305//305 292//304 291//310 +f 305//305 291//310 304//311 +f 229//306 212//235 211//241 +f 229//306 211//241 228//312 +f 246//307 229//306 228//312 +f 246//307 228//312 245//313 +f 262//308 246//307 245//313 +f 262//308 245//313 261//314 +f 277//309 262//308 261//314 +f 277//309 261//314 276//315 +f 291//310 277//309 276//315 +f 291//310 276//315 290//316 +f 304//311 291//310 290//316 +f 304//311 290//316 303//317 +f 228//312 211//241 210//247 +f 228//312 210//247 227//318 +f 245//313 228//312 227//318 +f 245//313 227//318 244//319 +f 261//314 245//313 244//319 +f 261//314 244//319 260//320 +f 276//315 261//314 260//320 +f 276//315 260//320 275//321 +f 290//316 276//315 275//321 +f 290//316 275//321 289//322 +f 303//317 290//316 289//322 +f 303//317 289//322 302//323 +f 227//318 210//247 209//256 +f 227//318 209//256 226//324 +f 244//319 227//318 226//324 +f 244//319 226//324 243//325 +f 260//320 244//319 243//325 +f 260//320 243//325 259//326 +f 275//321 260//320 259//326 +f 275//321 259//326 274//327 +f 289//322 275//321 274//327 +f 289//322 274//327 288//328 +f 302//323 289//322 288//328 +f 302//323 288//328 301//329 +f 226//324 209//256 213//263 +f 226//324 213//263 231//330 +f 243//325 226//324 231//330 +f 243//325 231//330 249//331 +f 259//326 243//325 249//331 +f 259//326 249//331 266//332 +f 274//327 259//326 266//332 +f 274//327 266//332 282//333 +f 288//328 274//327 282//333 +f 288//328 282//333 297//334 +f 301//329 288//328 297//334 +f 301//329 297//334 311//335 +f 231//330 213//263 225//190 +f 231//330 225//190 242//264 +f 249//331 231//330 242//264 +f 249//331 242//264 258//266 +f 266//332 249//331 258//266 +f 266//332 258//266 273//268 +f 282//333 266//332 273//268 +f 282//333 273//268 287//270 +f 297//334 282//333 287//270 +f 297//334 287//270 300//272 +f 311//335 297//334 300//272 +f 311//335 300//272 312//274 +f 312//274 310//275 323//336 +f 302//323 315//337 316//338 +f 304//311 317//339 318//340 +f 303//317 316//338 317//339 +f 309//281 308//287 321//341 +f 307//293 306//299 319//342 +f 311//335 313//343 314//344 +f 301//329 314//344 315//337 +f 312//274 324//345 313//343 +f 306//299 305//305 318//340 +f 308//287 307//293 320//346 +f 310//275 309//281 322//347 +f 322//347 321//341 325//348 +f 314//344 313//343 325//348 +f 323//336 322//347 325//348 +f 319//342 318//340 325//348 +f 315//337 314//344 325//348 +f 321//341 320//346 325//348 +f 324//345 323//336 325//348 +f 320//346 319//342 325//348 +f 317//339 316//338 325//348 +f 316//338 315//337 325//348 +f 313//343 324//345 325//348 +f 318//340 317//339 325//348 +f 326//349 327//350 328//351 +f 326//349 328//351 329//352 +f 333//353 326//349 329//352 +f 333//353 329//352 338//354 +f 347//355 333//353 338//354 +f 347//355 338//354 354//356 +f 364//357 347//355 354//356 +f 364//357 354//356 374//358 +f 386//359 364//357 374//358 +f 386//359 374//358 398//360 +f 412//361 386//359 398//360 +f 412//361 398//360 429//362 +f 329//352 328//351 334//363 +f 329//352 334//363 339//364 +f 338//354 329//352 339//364 +f 338//354 339//364 355//365 +f 354//356 338//354 355//365 +f 354//356 355//365 375//366 +f 374//358 354//356 375//366 +f 374//358 375//366 399//367 +f 398//360 374//358 399//367 +f 398//360 399//367 430//368 +f 429//362 398//360 430//368 +f 429//362 430//368 464//369 +f 339//364 334//363 342//370 +f 339//364 342//370 356//371 +f 355//365 339//364 356//371 +f 355//365 356//371 376//372 +f 375//366 355//365 376//372 +f 375//366 376//372 400//373 +f 399//367 375//366 400//373 +f 399//367 400//373 431//374 +f 430//368 399//367 431//374 +f 430//368 431//374 465//375 +f 464//369 430//368 465//375 +f 464//369 465//375 497//376 +f 356//371 342//370 351//377 +f 356//371 351//377 370//378 +f 376//372 356//371 370//378 +f 376//372 370//378 393//379 +f 400//373 376//372 393//379 +f 400//373 393//379 422//380 +f 431//374 400//373 422//380 +f 431//374 422//380 457//381 +f 465//375 431//374 457//381 +f 465//375 457//381 490//382 +f 497//376 465//375 490//382 +f 497//376 490//382 521//383 +f 370//378 351//377 361//384 +f 370//378 361//384 382//385 +f 393//379 370//378 382//385 +f 393//379 382//385 408//386 +f 422//380 393//379 408//386 +f 422//380 408//386 439//387 +f 457//381 422//380 439//387 +f 457//381 439//387 473//388 +f 490//382 457//381 473//388 +f 490//382 473//388 504//389 +f 521//383 490//382 504//389 +f 521//383 504//389 535//390 +f 382//385 361//384 369//391 +f 382//385 369//391 392//392 +f 408//386 382//385 392//392 +f 408//386 392//392 421//393 +f 439//387 408//386 421//393 +f 439//387 421//393 456//394 +f 473//388 439//387 456//394 +f 473//388 456//394 489//395 +f 504//389 473//388 489//395 +f 504//389 489//395 520//396 +f 535//390 504//389 520//396 +f 535//390 520//396 550//397 +f 392//392 369//391 380//398 +f 392//392 380//398 407//399 +f 421//393 392//392 407//399 +f 421//393 407//399 438//400 +f 456//394 421//393 438//400 +f 456//394 438//400 472//401 +f 489//395 456//394 472//401 +f 489//395 472//401 503//402 +f 520//396 489//395 503//402 +f 520//396 503//402 534//403 +f 550//397 520//396 534//403 +f 550//397 534//403 563//404 +f 407//399 380//398 391//405 +f 407//399 391//405 420//406 +f 438//400 407//399 420//406 +f 438//400 420//406 455//407 +f 472//401 438//400 455//407 +f 472//401 455//407 488//408 +f 503//402 472//401 488//408 +f 503//402 488//408 519//409 +f 534//403 503//402 519//409 +f 534//403 519//409 549//410 +f 563//404 534//403 549//410 +f 563//404 549//410 578//411 +f 420//406 391//405 404//412 +f 420//406 404//412 437//413 +f 455//407 420//406 437//413 +f 455//407 437//413 471//414 +f 488//408 455//407 471//414 +f 488//408 471//414 502//415 +f 519//409 488//408 502//415 +f 519//409 502//415 533//416 +f 549//410 519//409 533//416 +f 549//410 533//416 562//417 +f 578//411 549//410 562//417 +f 578//411 562//417 589//418 +f 437//413 404//412 419//419 +f 437//413 419//419 454//420 +f 471//414 437//413 454//420 +f 471//414 454//420 487//421 +f 502//415 471//414 487//421 +f 502//415 487//421 518//422 +f 533//416 502//415 518//422 +f 533//416 518//422 548//423 +f 562//417 533//416 548//423 +f 562//417 548//423 577//424 +f 589//418 562//417 577//424 +f 589//418 577//424 594//425 +f 454//420 419//419 436//426 +f 454//420 436//426 470//427 +f 487//421 454//420 470//427 +f 487//421 470//427 501//428 +f 518//422 487//421 501//428 +f 518//422 501//428 532//429 +f 548//423 518//422 532//429 +f 548//423 532//429 555//430 +f 577//424 548//423 555//430 +f 577//424 555//430 567//431 +f 594//425 577//424 567//431 +f 594//425 567//431 582//432 +f 470//427 436//426 453//433 +f 470//427 453//433 486//434 +f 501//428 470//427 486//434 +f 501//428 486//434 508//435 +f 532//429 501//428 508//435 +f 532//429 508//435 525//436 +f 555//430 532//429 525//436 +f 555//430 525//436 538//437 +f 567//431 555//430 538//437 +f 567//431 538//437 554//438 +f 582//432 567//431 554//438 +f 582//432 554//438 566//33 +f 486//434 453//433 462//439 +f 486//434 462//439 477//440 +f 508//435 486//434 477//440 +f 508//435 477//440 494//441 +f 525//436 508//435 494//441 +f 525//436 494//441 507//442 +f 538//437 525//436 507//442 +f 538//437 507//442 524//443 +f 554//438 538//437 524//443 +f 554//438 524//443 537//444 +f 566//33 554//438 537//444 +f 566//33 537//444 553//31 +f 477//440 462//439 443//445 +f 477//440 443//445 461//446 +f 494//441 477//440 461//446 +f 494//441 461//446 476//447 +f 507//442 494//441 476//447 +f 507//442 476//447 493//448 +f 524//443 507//442 493//448 +f 524//443 493//448 506//449 +f 537//444 524//443 506//449 +f 537//444 506//449 523//450 +f 553//31 537//444 523//450 +f 553//31 523//450 536//451 +f 461//446 443//445 426//452 +f 461//446 426//452 442//453 +f 476//447 461//446 442//453 +f 476//447 442//453 460//454 +f 493//448 476//447 460//454 +f 493//448 460//454 475//455 +f 506//449 493//448 475//455 +f 506//449 475//455 492//456 +f 523//450 506//449 492//456 +f 523//450 492//456 505//457 +f 536//451 523//450 505//457 +f 536//451 505//457 522//458 +f 442//453 426//452 411//459 +f 442//453 411//459 425//460 +f 460//454 442//453 425//460 +f 460//454 425//460 441//461 +f 475//455 460//454 441//461 +f 475//455 441//461 459//462 +f 492//456 475//455 459//462 +f 492//456 459//462 474//463 +f 505//457 492//456 474//463 +f 505//457 474//463 491//464 +f 522//458 505//457 491//464 +f 522//458 491//464 499//465 +f 425//460 411//459 396//466 +f 425//460 396//466 410//467 +f 441//461 425//460 410//467 +f 441//461 410//467 424//468 +f 459//462 441//461 424//468 +f 459//462 424//468 440//469 +f 474//463 459//462 440//469 +f 474//463 440//469 458//470 +f 491//464 474//463 458//470 +f 491//464 458//470 467//471 +f 499//465 491//464 467//471 +f 499//465 467//471 466//472 +f 410//467 396//466 385//473 +f 410//467 385//473 395//474 +f 424//468 410//467 395//474 +f 424//468 395//474 409//475 +f 440//469 424//468 409//475 +f 440//469 409//475 423//476 +f 458//470 440//469 423//476 +f 458//470 423//476 433//477 +f 467//471 458//470 433//477 +f 467//471 433//477 432//478 +f 466//472 467//471 432//478 +f 466//472 432//478 434//479 +f 395//474 385//473 372//480 +f 395//474 372//480 383//481 +f 409//475 395//474 383//481 +f 409//475 383//481 394//482 +f 423//476 409//475 394//482 +f 423//476 394//482 402//483 +f 433//477 423//476 402//483 +f 433//477 402//483 401//484 +f 432//478 433//477 401//484 +f 432//478 401//484 403//485 +f 434//479 432//478 403//485 +f 434//479 403//485 417//486 +f 383//481 372//480 362//487 +f 383//481 362//487 371//488 +f 394//482 383//481 371//488 +f 394//482 371//488 378//489 +f 402//483 394//482 378//489 +f 402//483 378//489 377//490 +f 401//484 402//483 377//490 +f 401//484 377//490 379//491 +f 403//485 401//484 379//491 +f 403//485 379//491 390//492 +f 417//486 403//485 390//492 +f 417//486 390//492 416//493 +f 371//488 362//487 352//494 +f 371//488 352//494 358//495 +f 378//489 371//488 358//495 +f 378//489 358//495 357//496 +f 377//490 378//489 357//496 +f 377//490 357//496 359//497 +f 379//491 377//490 359//497 +f 379//491 359//497 367//498 +f 390//492 379//491 367//498 +f 390//492 367//498 389//499 +f 416//493 390//492 389//499 +f 416//493 389//499 415//500 +f 358//495 352//494 345//501 +f 358//495 345//501 340//502 +f 357//496 358//495 340//502 +f 357//496 340//502 341//503 +f 359//497 357//496 341//503 +f 359//497 341//503 349//504 +f 367//498 359//497 349//504 +f 367//498 349//504 366//505 +f 389//499 367//498 366//505 +f 389//499 366//505 388//506 +f 415//500 389//499 388//506 +f 415//500 388//506 414//507 +f 340//502 345//501 335//508 +f 340//502 335//508 330//509 +f 341//503 340//502 330//509 +f 341//503 330//509 336//510 +f 349//504 341//503 336//510 +f 349//504 336//510 348//511 +f 366//505 349//504 348//511 +f 366//505 348//511 365//512 +f 388//506 366//505 365//512 +f 388//506 365//512 387//513 +f 414//507 388//506 387//513 +f 414//507 387//513 413//514 +f 330//509 335//508 327//350 +f 327//350 326//349 330//509 +f 330//509 326//349 336//510 +f 336//510 326//349 333//353 +f 348//511 336//510 333//353 +f 348//511 333//353 347//355 +f 365//512 348//511 347//355 +f 365//512 347//355 364//357 +f 387//513 365//512 364//357 +f 387//513 364//357 386//359 +f 413//514 387//513 386//359 +f 413//514 386//359 412//361 +f 445//515 412//361 429//362 +f 445//515 429//362 463//516 +f 478//517 445//515 463//516 +f 478//517 463//516 495//518 +f 509//176 478//517 495//518 +f 509//176 495//518 526//519 +f 463//516 429//362 464//369 +f 463//516 464//369 496//520 +f 495//518 463//516 496//520 +f 495//518 496//520 527//521 +f 526//519 495//518 527//521 +f 526//519 527//521 557//522 +f 556//523 526//519 557//522 +f 556//523 557//522 583//524 +f 595//202 556//523 583//524 +f 595//202 583//524 611//525 +f 621//526 595//202 611//525 +f 621//526 611//525 638//527 +f 496//520 464//369 497//376 +f 496//520 497//376 528//528 +f 527//521 496//520 528//528 +f 527//521 528//528 558//529 +f 557//522 527//521 558//529 +f 557//522 558//529 584//530 +f 583//524 557//522 584//530 +f 583//524 584//530 612//531 +f 611//525 583//524 612//531 +f 611//525 612//531 639//532 +f 638//527 611//525 639//532 +f 638//527 639//532 664//533 +f 528//528 497//376 521//383 +f 528//528 521//383 551//534 +f 558//529 528//528 551//534 +f 558//529 551//534 580//535 +f 584//530 558//529 580//535 +f 584//530 580//535 608//536 +f 612//531 584//530 608//536 +f 612//531 608//536 634//537 +f 639//532 612//531 634//537 +f 639//532 634//537 661//538 +f 664//533 639//532 661//538 +f 664//533 661//538 688//539 +f 551//534 521//383 535//390 +f 551//534 535//390 564//540 +f 580//535 551//534 564//540 +f 580//535 564//540 591//541 +f 608//536 580//535 591//541 +f 608//536 591//541 618//542 +f 634//537 608//536 618//542 +f 634//537 618//542 644//543 +f 661//538 634//537 644//543 +f 661//538 644//543 670//544 +f 688//539 661//538 670//544 +f 688//539 670//544 698//545 +f 564//540 535//390 550//397 +f 564//540 550//397 579//546 +f 591//541 564//540 579//546 +f 591//541 579//546 607//547 +f 618//542 591//541 607//547 +f 618//542 607//547 633//548 +f 644//543 618//542 633//548 +f 644//543 633//548 660//549 +f 670//544 644//543 660//549 +f 670//544 660//549 687//550 +f 698//545 670//544 687//550 +f 698//545 687//550 717//551 +f 579//546 550//397 563//404 +f 579//546 563//404 590//552 +f 607//547 579//546 590//552 +f 607//547 590//552 617//553 +f 633//548 607//547 617//553 +f 633//548 617//553 643//554 +f 660//549 633//548 643//554 +f 660//549 643//554 669//555 +f 687//550 660//549 669//555 +f 687//550 669//555 697//556 +f 717//551 687//550 697//556 +f 717//551 697//556 727//557 +f 590//552 563//404 578//411 +f 590//552 578//411 606//558 +f 617//553 590//552 606//558 +f 617//553 606//558 632//559 +f 643//554 617//553 632//559 +f 643//554 632//559 659//560 +f 669//555 643//554 659//560 +f 669//555 659//560 673//561 +f 697//556 669//555 673//561 +f 697//556 673//561 700//562 +f 727//557 697//556 700//562 +f 727//557 700//562 699//563 +f 606//558 578//411 589//418 +f 606//558 589//418 616//564 +f 632//559 606//558 616//564 +f 632//559 616//564 637//565 +f 659//560 632//559 637//565 +f 659//560 637//565 647//566 +f 673//561 659//560 647//566 +f 673//561 647//566 672//567 +f 700//562 673//561 672//567 +f 700//562 672//567 671//568 +f 699//563 700//562 671//568 +f 699//563 671//568 689//569 +f 616//564 589//418 594//425 +f 616//564 594//425 610//570 +f 637//565 616//564 610//570 +f 637//565 610//570 620//571 +f 647//566 637//565 620//571 +f 647//566 620//571 646//572 +f 672//567 647//566 646//572 +f 672//567 646//572 645//573 +f 671//568 672//567 645//573 +f 671//568 645//573 662//574 +f 689//569 671//568 662//574 +f 689//569 662//574 668//575 +f 610//570 594//425 582//432 +f 610//570 582//432 593//3 +f 620//571 610//570 593//3 +f 620//571 593//3 636//89 +f 646//572 620//571 636//89 +f 646//572 636//89 619//576 +f 645//573 646//572 619//576 +f 645//573 619//576 635//577 +f 662//574 645//573 635//577 +f 662//574 635//577 642//578 +f 668//575 662//574 642//578 +f 668//575 642//578 641//579 +f 593//3 582//432 566//33 +f 619//576 636//89 592//57 +f 619//576 592//57 609//580 +f 635//577 619//576 609//580 +f 635//577 609//580 615//581 +f 642//578 635//577 615//581 +f 642//578 615//581 614//582 +f 641//579 642//578 614//582 +f 592//57 565//56 581//583 +f 609//580 592//57 581//583 +f 609//580 581//583 587//584 +f 615//581 609//580 587//584 +f 615//581 587//584 586//585 +f 614//582 615//581 586//585 +f 614//582 586//585 588//586 +f 565//56 553//31 536//451 +f 565//56 536//451 552//587 +f 581//583 565//56 552//587 +f 581//583 552//587 560//588 +f 587//584 581//583 560//588 +f 587//584 560//588 559//589 +f 586//585 587//584 559//589 +f 586//585 559//589 561//590 +f 588//586 586//585 561//590 +f 588//586 561//590 576//591 +f 605//592 588//586 576//591 +f 605//592 576//591 604//593 +f 552//587 536//451 522//458 +f 552//587 522//458 530//594 +f 560//588 552//587 530//594 +f 560//588 530//594 529//595 +f 559//589 560//588 529//595 +f 559//589 529//595 531//596 +f 561//590 559//589 531//596 +f 561//590 531//596 547//597 +f 576//591 561//590 547//597 +f 576//591 547//597 575//598 +f 604//593 576//591 575//598 +f 604//593 575//598 603//599 +f 530//594 522//458 499//465 +f 530//594 499//465 498//600 +f 529//595 530//594 498//600 +f 529//595 498//600 500//601 +f 531//596 529//595 500//601 +f 531//596 500//601 517//602 +f 547//597 531//596 517//602 +f 547//597 517//602 546//603 +f 575//598 547//597 546//603 +f 575//598 546//603 574//604 +f 603//599 575//598 574//604 +f 603//599 574//604 602//605 +f 498//600 499//465 466//472 +f 498//600 466//472 468//606 +f 500//601 498//600 468//606 +f 500//601 468//606 485//607 +f 517//602 500//601 485//607 +f 517//602 485//607 516//608 +f 546//603 517//602 516//608 +f 546//603 516//608 545//609 +f 574//604 546//603 545//609 +f 574//604 545//609 573//610 +f 602//605 574//604 573//610 +f 602//605 573//610 601//611 +f 468//606 466//472 434//479 +f 468//606 434//479 451//612 +f 485//607 468//606 451//612 +f 485//607 451//612 484//613 +f 516//608 485//607 484//613 +f 516//608 484//613 515//614 +f 545//609 516//608 515//614 +f 545//609 515//614 544//615 +f 573//610 545//609 544//615 +f 573//610 544//615 572//616 +f 601//611 573//610 572//616 +f 601//611 572//616 600//617 +f 451//612 434//479 417//486 +f 451//612 417//486 450//618 +f 484//613 451//612 450//618 +f 484//613 450//618 483//619 +f 515//614 484//613 483//619 +f 515//614 483//619 514//620 +f 544//615 515//614 514//620 +f 544//615 514//620 543//621 +f 572//616 544//615 543//621 +f 572//616 543//621 571//622 +f 600//617 572//616 571//622 +f 600//617 571//622 599//623 +f 450//618 417//486 416//493 +f 450//618 416//493 449//624 +f 483//619 450//618 449//624 +f 483//619 449//624 482//625 +f 514//620 483//619 482//625 +f 514//620 482//625 513//626 +f 543//621 514//620 513//626 +f 543//621 513//626 542//627 +f 571//622 543//621 542//627 +f 571//622 542//627 570//628 +f 599//623 571//622 570//628 +f 599//623 570//628 598//629 +f 449//624 416//493 415//500 +f 449//624 415//500 448//630 +f 482//625 449//624 448//630 +f 482//625 448//630 481//631 +f 513//626 482//625 481//631 +f 513//626 481//631 512//632 +f 542//627 513//626 512//632 +f 542//627 512//632 541//633 +f 570//628 542//627 541//633 +f 570//628 541//633 569//634 +f 598//629 570//628 569//634 +f 598//629 569//634 597//635 +f 448//630 415//500 414//507 +f 448//630 414//507 447//636 +f 481//631 448//630 447//636 +f 481//631 447//636 480//637 +f 512//632 481//631 480//637 +f 512//632 480//637 511//638 +f 541//633 512//632 511//638 +f 541//633 511//638 540//639 +f 569//634 541//633 540//639 +f 569//634 540//639 568//640 +f 597//635 569//634 568//640 +f 597//635 568//640 596//641 +f 447//636 414//507 413//514 +f 447//636 413//514 446//642 +f 480//637 447//636 446//642 +f 480//637 446//642 479//643 +f 511//638 480//637 479//643 +f 511//638 479//643 510//644 +f 540//639 511//638 510//644 +f 540//639 510//644 539//175 +f 568//640 540//639 539//175 +f 568//640 539//175 585//249 +f 596//641 568//640 585//249 +f 596//641 585//249 613//248 +f 446//642 413//514 412//361 +f 446//642 412//361 445//515 +f 479//643 446//642 445//515 +f 479//643 445//515 478//517 +f 510//644 479//643 478//517 +f 510//644 478//517 509//176 +f 539//175 510//644 509//176 +f 691//228 648//227 674//645 +f 702//646 691//228 674//645 +f 702//646 674//645 701//647 +f 731//648 702//646 701//647 +f 731//648 701//647 730//649 +f 759//650 731//648 730//649 +f 759//650 730//649 758//651 +f 786//652 759//650 758//651 +f 786//652 758//651 785//653 +f 648//227 621//526 638//527 +f 648//227 638//527 663//654 +f 674//645 648//227 663//654 +f 674//645 663//654 690//655 +f 701//647 674//645 690//655 +f 701//647 690//655 720//656 +f 730//649 701//647 720//656 +f 730//649 720//656 749//657 +f 758//651 730//649 749//657 +f 758//651 749//657 777//658 +f 785//653 758//651 777//658 +f 785//653 777//658 805//659 +f 663//654 638//527 664//533 +f 663//654 664//533 692//660 +f 690//655 663//654 692//660 +f 690//655 692//660 721//661 +f 720//656 690//655 721//661 +f 720//656 721//661 750//662 +f 749//657 720//656 750//662 +f 749//657 750//662 778//663 +f 777//658 749//657 778//663 +f 777//658 778//663 806//664 +f 805//659 777//658 806//664 +f 805//659 806//664 833//665 +f 692//660 664//533 688//539 +f 692//660 688//539 718//666 +f 721//661 692//660 718//666 +f 721//661 718//666 747//667 +f 750//662 721//661 747//667 +f 750//662 747//667 775//668 +f 778//663 750//662 775//668 +f 778//663 775//668 803//669 +f 806//664 778//663 803//669 +f 806//664 803//669 831//670 +f 833//665 806//664 831//670 +f 833//665 831//670 838//671 +f 718//666 688//539 698//545 +f 718//666 698//545 728//672 +f 747//667 718//666 728//672 +f 747//667 728//672 756//673 +f 775//668 747//667 756//673 +f 775//668 756//673 784//674 +f 803//669 775//668 784//674 +f 803//669 784//674 804//675 +f 831//670 803//669 804//675 +f 831//670 804//675 811//676 +f 838//671 831//670 811//676 +f 838//671 811//676 830//677 +f 728//672 698//545 717//551 +f 728//672 717//551 746//678 +f 756//673 728//672 746//678 +f 756//673 746//678 757//679 +f 784//674 756//673 757//679 +f 784//674 757//679 776//680 +f 804//675 784//674 776//680 +f 804//675 776//680 783//681 +f 811//676 804//675 783//681 +f 811//676 783//681 802//682 +f 830//677 811//676 802//682 +f 830//677 802//682 810//683 +f 746//678 717//551 727//557 +f 746//678 727//557 729//684 +f 757//679 746//678 729//684 +f 757//679 729//684 748//685 +f 776//680 757//679 748//685 +f 776//680 748//685 755//686 +f 783//681 776//680 755//686 +f 783//681 755//686 774//687 +f 802//682 783//681 774//687 +f 802//682 774//687 782//688 +f 810//683 802//682 782//688 +f 810//683 782//688 809//689 +f 729//684 727//557 699//563 +f 729//684 699//563 719//690 +f 748//685 729//684 719//690 +f 748//685 719//690 726//691 +f 755//686 748//685 726//691 +f 755//686 726//691 745//692 +f 774//687 755//686 745//692 +f 774//687 745//692 754//693 +f 782//688 774//687 754//693 +f 782//688 754//693 781//694 +f 809//689 782//688 781//694 +f 809//689 781//694 780//695 +f 719//690 699//563 689//569 +f 719//690 689//569 696//696 +f 726//691 719//690 696//696 +f 726//691 696//696 716//697 +f 745//692 726//691 716//697 +f 745//692 716//697 725//698 +f 754//693 745//692 725//698 +f 754//693 725//698 753//699 +f 781//694 754//693 753//699 +f 781//694 753//699 752//700 +f 780//695 781//694 752//700 +f 780//695 752//700 773//701 +f 696//696 689//569 668//575 +f 696//696 668//575 686//702 +f 716//697 696//696 686//702 +f 716//697 686//702 695//703 +f 725//698 716//697 695//703 +f 725//698 695//703 724//704 +f 753//699 725//698 724//704 +f 753//699 724//704 723//705 +f 752//700 753//699 723//705 +f 752//700 723//705 744//706 +f 773//701 752//700 744//706 +f 773//701 744//706 772//707 +f 686//702 668//575 641//579 +f 686//702 641//579 667//708 +f 695//703 686//702 667//708 +f 695//703 667//708 715//160 +f 724//704 695//703 715//160 +f 724//704 715//160 694//709 +f 723//705 724//704 694//709 +f 723//705 694//709 714//710 +f 744//706 723//705 714//710 +f 744//706 714//710 743//711 +f 772//707 744//706 743//711 +f 772//707 743//711 771//712 +f 694//709 715//160 666//713 +f 694//709 666//713 685//714 +f 714//710 694//709 685//714 +f 714//710 685//714 713//715 +f 743//711 714//710 713//715 +f 743//711 713//715 742//716 +f 771//712 743//711 742//716 +f 771//712 742//716 770//717 +f 666//713 631//152 658//718 +f 685//714 666//713 658//718 +f 685//714 658//718 684//719 +f 713//715 685//714 684//719 +f 713//715 684//719 712//720 +f 742//716 713//715 712//720 +f 742//716 712//720 741//721 +f 770//717 742//716 741//721 +f 770//717 741//721 769//722 +f 631//152 605//592 604//593 +f 631//152 604//593 630//723 +f 658//718 631//152 630//723 +f 658//718 630//723 657//724 +f 684//719 658//718 657//724 +f 684//719 657//724 683//725 +f 712//720 684//719 683//725 +f 712//720 683//725 711//726 +f 741//721 712//720 711//726 +f 741//721 711//726 740//727 +f 769//722 741//721 740//727 +f 769//722 740//727 768//728 +f 630//723 604//593 603//599 +f 630//723 603//599 629//729 +f 657//724 630//723 629//729 +f 657//724 629//729 656//730 +f 683//725 657//724 656//730 +f 683//725 656//730 682//731 +f 711//726 683//725 682//731 +f 711//726 682//731 710//732 +f 740//727 711//726 710//732 +f 740//727 710//732 739//733 +f 768//728 740//727 739//733 +f 768//728 739//733 767//734 +f 629//729 603//599 602//605 +f 629//729 602//605 628//735 +f 656//730 629//729 628//735 +f 656//730 628//735 655//736 +f 682//731 656//730 655//736 +f 682//731 655//736 681//737 +f 710//732 682//731 681//737 +f 710//732 681//737 709//738 +f 739//733 710//732 709//738 +f 739//733 709//738 738//739 +f 767//734 739//733 738//739 +f 767//734 738//739 766//740 +f 628//735 602//605 601//611 +f 628//735 601//611 627//741 +f 655//736 628//735 627//741 +f 655//736 627//741 654//742 +f 681//737 655//736 654//742 +f 681//737 654//742 680//743 +f 709//738 681//737 680//743 +f 709//738 680//743 708//744 +f 738//739 709//738 708//744 +f 738//739 708//744 737//745 +f 766//740 738//739 737//745 +f 766//740 737//745 765//746 +f 627//741 601//611 600//617 +f 627//741 600//617 626//747 +f 654//742 627//741 626//747 +f 654//742 626//747 653//748 +f 680//743 654//742 653//748 +f 680//743 653//748 679//749 +f 708//744 680//743 679//749 +f 708//744 679//749 707//750 +f 737//745 708//744 707//750 +f 737//745 707//750 736//751 +f 765//746 737//745 736//751 +f 765//746 736//751 764//752 +f 626//747 600//617 599//623 +f 626//747 599//623 625//753 +f 653//748 626//747 625//753 +f 653//748 625//753 652//754 +f 679//749 653//748 652//754 +f 679//749 652//754 678//755 +f 707//750 679//749 678//755 +f 707//750 678//755 706//756 +f 736//751 707//750 706//756 +f 736//751 706//756 735//757 +f 764//752 736//751 735//757 +f 764//752 735//757 763//758 +f 625//753 599//623 598//629 +f 625//753 598//629 624//759 +f 652//754 625//753 624//759 +f 652//754 624//759 651//760 +f 678//755 652//754 651//760 +f 678//755 651//760 677//761 +f 706//756 678//755 677//761 +f 706//756 677//761 705//762 +f 735//757 706//756 705//762 +f 735//757 705//762 734//763 +f 763//758 735//757 734//763 +f 763//758 734//763 762//764 +f 624//759 598//629 597//635 +f 624//759 597//635 623//765 +f 651//760 624//759 623//765 +f 651//760 623//765 650//766 +f 677//761 651//760 650//766 +f 677//761 650//766 676//767 +f 705//762 677//761 676//767 +f 705//762 676//767 704//768 +f 734//763 705//762 704//768 +f 734//763 704//768 733//769 +f 762//764 734//763 733//769 +f 762//764 733//769 761//770 +f 623//765 597//635 596//641 +f 623//765 596//641 622//771 +f 650//766 623//765 622//771 +f 650//766 622//771 649//772 +f 676//767 650//766 649//772 +f 676//767 649//772 675//773 +f 704//768 676//767 675//773 +f 704//768 675//773 703//774 +f 733//769 704//768 703//774 +f 733//769 703//774 732//775 +f 761//770 733//769 732//775 +f 761//770 732//775 760//776 +f 622//771 596//641 613//248 +f 622//771 613//248 640//777 +f 649//772 622//771 640//777 +f 649//772 640//777 665//778 +f 675//773 649//772 665//778 +f 675//773 665//778 693//779 +f 703//774 675//773 693//779 +f 703//774 693//779 722//780 +f 732//775 703//774 722//780 +f 732//775 722//780 751//781 +f 760//776 732//775 751//781 +f 760//776 751//781 779//782 +f 693//779 665//778 691//228 +f 693//779 691//228 702//646 +f 722//780 693//779 702//646 +f 722//780 702//646 731//648 +f 751//781 722//780 731//648 +f 751//781 731//648 759//650 +f 779//782 751//781 759//650 +f 779//782 759//650 786//652 +f 917//783 918//784 913//785 +f 892//786 917//783 913//785 +f 892//786 913//785 887//787 +f 866//788 892//786 887//787 +f 866//788 887//787 861//789 +f 840//790 866//788 861//789 +f 840//790 861//789 834//791 +f 813//792 840//790 834//791 +f 813//792 834//791 807//793 +f 786//652 813//792 807//793 +f 786//652 807//793 779//782 +f 913//785 918//784 893//794 +f 887//787 913//785 893//794 +f 887//787 893//794 867//795 +f 861//789 887//787 867//795 +f 861//789 867//795 841//796 +f 834//791 861//789 841//796 +f 834//791 841//796 814//797 +f 807//793 834//791 814//797 +f 807//793 814//797 787//798 +f 779//782 807//793 787//798 +f 779//782 787//798 760//776 +f 893//794 918//784 894//799 +f 867//795 893//794 894//799 +f 867//795 894//799 868//800 +f 841//796 867//795 868//800 +f 841//796 868//800 842//801 +f 814//797 841//796 842//801 +f 814//797 842//801 815//802 +f 787//798 814//797 815//802 +f 787//798 815//802 788//803 +f 760//776 787//798 788//803 +f 760//776 788//803 761//770 +f 894//799 918//784 895//804 +f 868//800 894//799 895//804 +f 868//800 895//804 869//805 +f 842//801 868//800 869//805 +f 842//801 869//805 843//806 +f 815//802 842//801 843//806 +f 815//802 843//806 816//807 +f 788//803 815//802 816//807 +f 788//803 816//807 789//808 +f 761//770 788//803 789//808 +f 761//770 789//808 762//764 +f 895//804 918//784 896//809 +f 869//805 895//804 896//809 +f 869//805 896//809 870//810 +f 843//806 869//805 870//810 +f 843//806 870//810 844//811 +f 816//807 843//806 844//811 +f 816//807 844//811 817//812 +f 789//808 816//807 817//812 +f 789//808 817//812 790//813 +f 762//764 789//808 790//813 +f 762//764 790//813 763//758 +f 896//809 918//784 897//814 +f 870//810 896//809 897//814 +f 870//810 897//814 871//815 +f 844//811 870//810 871//815 +f 844//811 871//815 845//816 +f 817//812 844//811 845//816 +f 817//812 845//816 818//817 +f 790//813 817//812 818//817 +f 790//813 818//817 791//818 +f 763//758 790//813 791//818 +f 763//758 791//818 764//752 +f 897//814 918//784 898//819 +f 871//815 897//814 898//819 +f 871//815 898//819 872//820 +f 845//816 871//815 872//820 +f 845//816 872//820 846//821 +f 818//817 845//816 846//821 +f 818//817 846//821 819//822 +f 791//818 818//817 819//822 +f 791//818 819//822 792//823 +f 764//752 791//818 792//823 +f 764//752 792//823 765//746 +f 898//819 918//784 899//824 +f 872//820 898//819 899//824 +f 872//820 899//824 873//825 +f 846//821 872//820 873//825 +f 846//821 873//825 847//826 +f 819//822 846//821 847//826 +f 819//822 847//826 820//827 +f 792//823 819//822 820//827 +f 792//823 820//827 793//828 +f 765//746 792//823 793//828 +f 765//746 793//828 766//740 +f 899//824 918//784 900//829 +f 873//825 899//824 900//829 +f 873//825 900//829 874//830 +f 847//826 873//825 874//830 +f 847//826 874//830 848//831 +f 820//827 847//826 848//831 +f 820//827 848//831 821//832 +f 793//828 820//827 821//832 +f 793//828 821//832 794//833 +f 766//740 793//828 794//833 +f 766//740 794//833 767//734 +f 900//829 918//784 901//834 +f 874//830 900//829 901//834 +f 874//830 901//834 875//835 +f 848//831 874//830 875//835 +f 848//831 875//835 849//836 +f 821//832 848//831 849//836 +f 821//832 849//836 822//837 +f 794//833 821//832 822//837 +f 794//833 822//837 795//838 +f 767//734 794//833 795//838 +f 767//734 795//838 768//728 +f 901//834 918//784 902//839 +f 875//835 901//834 902//839 +f 875//835 902//839 876//840 +f 849//836 875//835 876//840 +f 849//836 876//840 850//841 +f 822//837 849//836 850//841 +f 822//837 850//841 823//842 +f 795//838 822//837 823//842 +f 795//838 823//842 796//843 +f 768//728 795//838 796//843 +f 768//728 796//843 769//722 +f 902//839 918//784 903//844 +f 876//840 902//839 903//844 +f 876//840 903//844 877//845 +f 850//841 876//840 877//845 +f 850//841 877//845 851//846 +f 823//842 850//841 851//846 +f 823//842 851//846 824//847 +f 796//843 823//842 824//847 +f 796//843 824//847 797//848 +f 769//722 796//843 797//848 +f 769//722 797//848 770//717 +f 903//844 918//784 904//849 +f 877//845 903//844 904//849 +f 877//845 904//849 878//850 +f 851//846 877//845 878//850 +f 851//846 878//850 852//851 +f 824//847 851//846 852//851 +f 824//847 852//851 825//852 +f 797//848 824//847 825//852 +f 797//848 825//852 798//853 +f 770//717 797//848 798//853 +f 770//717 798//853 771//712 +f 904//849 918//784 905//854 +f 878//850 904//849 905//854 +f 878//850 905//854 879//855 +f 852//851 878//850 879//855 +f 852//851 879//855 853//856 +f 825//852 852//851 853//856 +f 825//852 853//856 826//857 +f 798//853 825//852 826//857 +f 798//853 826//857 799//858 +f 771//712 798//853 799//858 +f 771//712 799//858 772//707 +f 905//854 918//784 906//859 +f 879//855 905//854 906//859 +f 879//855 906//859 880//860 +f 853//856 879//855 880//860 +f 853//856 880//860 854//861 +f 826//857 853//856 854//861 +f 826//857 854//861 827//862 +f 799//858 826//857 827//862 +f 799//858 827//862 800//863 +f 772//707 799//858 800//863 +f 772//707 800//863 773//701 +f 906//859 918//784 907//864 +f 880//860 906//859 907//864 +f 880//860 907//864 881//865 +f 854//861 880//860 881//865 +f 854//861 881//865 855//866 +f 827//862 854//861 855//866 +f 827//862 855//866 828//867 +f 800//863 827//862 828//867 +f 800//863 828//867 801//868 +f 773//701 800//863 801//868 +f 773//701 801//868 780//695 +f 907//864 918//784 908//869 +f 881//865 907//864 908//869 +f 881//865 908//869 882//870 +f 855//866 881//865 882//870 +f 855//866 882//870 856//871 +f 828//867 855//866 856//871 +f 828//867 856//871 829//872 +f 801//868 828//867 829//872 +f 801//868 829//872 808//873 +f 780//695 801//868 808//873 +f 780//695 808//873 809//689 +f 908//869 918//784 909//874 +f 882//870 908//869 909//874 +f 882//870 909//874 883//875 +f 856//871 882//870 883//875 +f 856//871 883//875 857//876 +f 829//872 856//871 857//876 +f 829//872 857//876 836//877 +f 808//873 829//872 836//877 +f 808//873 836//877 835//878 +f 809//689 808//873 835//878 +f 809//689 835//878 810//683 +f 909//874 918//784 910//879 +f 883//875 909//874 910//879 +f 883//875 910//879 884//880 +f 857//876 883//875 884//880 +f 857//876 884//880 863//881 +f 836//877 857//876 863//881 +f 836//877 863//881 862//882 +f 835//878 836//877 862//882 +f 835//878 862//882 837//883 +f 810//683 835//878 837//883 +f 810//683 837//883 830//677 +f 910//879 918//784 911//884 +f 884//880 910//879 911//884 +f 884//880 911//884 889//885 +f 863//881 884//880 889//885 +f 863//881 889//885 888//886 +f 862//882 863//881 888//886 +f 862//882 888//886 864//887 +f 837//883 862//882 864//887 +f 837//883 864//887 858//888 +f 830//677 837//883 858//888 +f 830//677 858//888 838//671 +f 911//884 918//784 915//889 +f 889//885 911//884 915//889 +f 889//885 915//889 914//890 +f 888//886 889//885 914//890 +f 888//886 914//890 890//891 +f 864//887 888//886 890//891 +f 864//887 890//891 885//892 +f 858//888 864//887 885//892 +f 858//888 885//892 859//893 +f 838//671 858//888 859//893 +f 838//671 859//893 833//665 +f 915//889 918//784 919//894 +f 914//890 915//889 919//894 +f 914//890 919//894 912//895 +f 890//891 914//890 912//895 +f 890//891 912//895 886//896 +f 885//892 890//891 886//896 +f 885//892 886//896 860//897 +f 859//893 885//892 860//897 +f 859//893 860//897 832//898 +f 833//665 859//893 832//898 +f 833//665 832//898 805//659 +f 919//894 918//784 916//899 +f 912//895 919//894 916//899 +f 912//895 916//899 891//900 +f 886//896 912//895 891//900 +f 886//896 891//900 865//901 +f 860//897 886//896 865//901 +f 860//897 865//901 839//902 +f 832//898 860//897 839//902 +f 832//898 839//902 812//903 +f 805//659 832//898 812//903 +f 805//659 812//903 785//653 +f 916//899 918//784 917//783 +f 891//900 916//899 917//783 +f 891//900 917//783 892//786 +f 865//901 891//900 892//786 +f 865//901 892//786 866//788 +f 839//902 865//901 866//788 +f 839//902 866//788 840//790 +f 812//903 839//902 840//790 +f 812//903 840//790 813//792 +f 785//653 812//903 813//792 +f 785//653 813//792 786//652 +f 404//412 1267//904 1268//905 +f 384//906 373//907 372//480 +f 346//908 345//501 352//494 +f 435//909 436//426 419//419 +f 331//910 327//350 335//508 +f 462//439 453//433 1265//911 +f 920//912 921//913 922//914 +f 920//912 922//914 923//915 +f 923//915 922//914 927//916 +f 923//915 927//916 933//917 +f 933//917 927//916 940//918 +f 933//917 940//918 949//919 +f 949//919 940//918 959//920 +f 949//919 959//920 971//921 +f 971//921 959//920 984//922 +f 971//921 984//922 999//923 +f 999//923 984//922 1011//924 +f 999//923 1011//924 1027//925 +f 1027//925 1011//924 1042//926 +f 1027//925 1042//926 1059//927 +f 1059//927 1042//926 1077//928 +f 1059//927 1077//928 1095//929 +f 1095//929 1077//928 1110//930 +f 1095//929 1110//930 1129//931 +f 1129//931 1110//930 1144//932 +f 1129//931 1144//932 1163//933 +f 1163//933 1144//932 1179//934 +f 1163//933 1179//934 1196//935 +f 1196//935 1179//934 1210//936 +f 1196//935 1210//936 1220//937 +f 1220//937 1210//936 1212//938 +f 1220//937 1212//938 1201//939 +f 1201//939 1212//938 1181//940 +f 1201//939 1181//940 1169//941 +f 1169//941 1181//940 1147//942 +f 1169//941 1147//942 1135//943 +f 1135//943 1147//942 1113//944 +f 1135//943 1113//944 1102//945 +f 1102//945 1113//944 1081//946 +f 1102//945 1081//946 1065//947 +f 1065//947 1081//946 1046//948 +f 1065//947 1046//948 1032//949 +f 1032//949 1046//948 1016//950 +f 1032//949 1016//950 1003//951 +f 1003//951 1016//950 988//952 +f 1003//951 988//952 974//953 +f 974//953 988//952 962//954 +f 974//953 962//954 951//955 +f 951//955 962//954 942//956 +f 951//955 942//956 934//957 +f 934//957 942//956 928//958 +f 934//957 928//958 924//959 +f 924//959 928//958 921//913 +f 921//913 920//912 924//959 +f 926//960 920//912 923//915 +f 926//960 923//915 932//961 +f 938//962 926//960 932//961 +f 938//962 932//961 947//963 +f 956//964 938//962 947//963 +f 956//964 947//963 968//965 +f 980//966 956//964 968//965 +f 980//966 968//965 995//967 +f 1006//968 980//966 995//967 +f 1006//968 995//967 1022//969 +f 1036//970 1006//968 1022//969 +f 1036//970 1022//969 1053//971 +f 932//961 923//915 933//917 +f 932//961 933//917 948//972 +f 947//963 932//961 948//972 +f 947//963 948//972 969//973 +f 968//965 947//963 969//973 +f 968//965 969//973 996//974 +f 995//967 968//965 996//974 +f 995//967 996//974 1023//975 +f 1022//969 995//967 1023//975 +f 1022//969 1023//975 1054//976 +f 1053//971 1022//969 1054//976 +f 1053//971 1054//976 1089//977 +f 948//972 933//917 949//919 +f 948//972 949//919 970//978 +f 969//973 948//972 970//978 +f 969//973 970//978 997//979 +f 996//974 969//973 997//979 +f 996//974 997//979 1024//980 +f 1023//975 996//974 1024//980 +f 1023//975 1024//980 1055//981 +f 1054//976 1023//975 1055//981 +f 1054//976 1055//981 1090//982 +f 1089//977 1054//976 1090//982 +f 1089//977 1090//982 1109//983 +f 970//978 949//919 971//921 +f 970//978 971//921 998//984 +f 997//979 970//978 998//984 +f 997//979 998//984 1025//985 +f 1024//980 997//979 1025//985 +f 1024//980 1025//985 1056//986 +f 1055//981 1024//980 1056//986 +f 1055//981 1056//986 1091//987 +f 1090//982 1055//981 1091//987 +f 1090//982 1091//987 1124//988 +f 1109//983 1090//982 1124//988 +f 1109//983 1124//988 1122//989 +f 998//984 971//921 999//923 +f 998//984 999//923 1026//990 +f 1025//985 998//984 1026//990 +f 1025//985 1026//990 1057//991 +f 1056//986 1025//985 1057//991 +f 1056//986 1057//991 1092//992 +f 1091//987 1056//986 1092//992 +f 1091//987 1092//992 1125//993 +f 1124//988 1091//987 1125//993 +f 1124//988 1125//993 1156//994 +f 1122//989 1124//988 1156//994 +f 1122//989 1156//994 1142//995 +f 1026//990 999//923 1027//925 +f 1026//990 1027//925 1058//996 +f 1057//991 1026//990 1058//996 +f 1057//991 1058//996 1093//997 +f 1092//992 1057//991 1093//997 +f 1092//992 1093//997 1126//998 +f 1125//993 1092//992 1126//998 +f 1125//993 1126//998 1159//999 +f 1156//994 1125//993 1159//999 +f 1156//994 1159//999 1176//1000 +f 1142//995 1156//994 1176//1000 +f 1142//995 1176//1000 1157//1001 +f 1058//996 1027//925 1059//927 +f 1058//996 1059//927 1094//1002 +f 1093//997 1058//996 1094//1002 +f 1093//997 1094//1002 1127//1003 +f 1126//998 1093//997 1127//1003 +f 1126//998 1127//1003 1160//1004 +f 1159//999 1126//998 1160//1004 +f 1159//999 1160//1004 1192//1005 +f 1176//1000 1159//999 1192//1005 +f 1176//1000 1192//1005 1189//1006 +f 1157//1001 1176//1000 1189//1006 +f 1157//1001 1189//1006 1178//1007 +f 1094//1002 1059//927 1095//929 +f 1094//1002 1095//929 1128//1008 +f 1127//1003 1094//1002 1128//1008 +f 1127//1003 1128//1008 1161//1009 +f 1160//1004 1127//1003 1161//1009 +f 1160//1004 1161//1009 1193//1010 +f 1192//1005 1160//1004 1193//1010 +f 1192//1005 1193//1010 1215//1011 +f 1189//1006 1192//1005 1215//1011 +f 1189//1006 1215//1011 1207//1012 +f 1178//1007 1189//1006 1207//1012 +f 1178//1007 1207//1012 1191//1013 +f 1128//1008 1095//929 1129//931 +f 1128//1008 1129//931 1162//1014 +f 1161//1009 1128//1008 1162//1014 +f 1161//1009 1162//1014 1194//1015 +f 1193//1010 1161//1009 1194//1015 +f 1193//1010 1194//1015 1217//1016 +f 1215//1011 1193//1010 1217//1016 +f 1215//1011 1217//1016 1227//1017 +f 1207//1012 1215//1011 1227//1017 +f 1207//1012 1227//1017 1216//1018 +f 1191//1013 1207//1012 1216//1018 +f 1191//1013 1216//1018 1209//1019 +f 1162//1014 1129//931 1163//933 +f 1162//1014 1163//933 1195//1020 +f 1194//1015 1162//1014 1195//1020 +f 1194//1015 1195//1020 1218//1021 +f 1217//1016 1194//1015 1218//1021 +f 1217//1016 1218//1021 1230//1022 +f 1227//1017 1217//1016 1230//1022 +f 1227//1017 1230//1022 1229//1023 +f 1216//1018 1227//1017 1229//1023 +f 1216//1018 1229//1023 1225//1024 +f 1209//1019 1216//1018 1225//1024 +f 1209//1019 1225//1024 1203//1025 +f 1195//1020 1163//933 1196//935 +f 1195//1020 1196//935 1219//1026 +f 1218//1021 1195//1020 1219//1026 +f 1218//1021 1219//1026 1231//1027 +f 1230//1022 1218//1021 1231//1027 +f 1230//1022 1231//1027 1232//1028 +f 1229//1023 1230//1022 1232//1028 +f 1229//1023 1232//1028 1228//1029 +f 1225//1024 1229//1023 1228//1029 +f 1225//1024 1228//1029 1214//1030 +f 1203//1025 1225//1024 1214//1030 +f 1203//1025 1214//1030 1184//1031 +f 1219//1026 1196//935 1220//937 +f 1219//1026 1220//937 1224//1032 +f 1231//1027 1219//1026 1224//1032 +f 1231//1027 1224//1032 1223//1033 +f 1232//1028 1231//1027 1223//1033 +f 1232//1028 1223//1033 1222//1034 +f 1228//1029 1232//1028 1222//1034 +f 1228//1029 1222//1034 1221//1035 +f 1214//1030 1228//1029 1221//1035 +f 1214//1030 1221//1035 1204//1036 +f 1184//1031 1214//1030 1204//1036 +f 1184//1031 1204//1036 1171//1037 +f 1224//1032 1220//937 1201//939 +f 1224//1032 1201//939 1200//1038 +f 1223//1033 1224//1032 1200//1038 +f 1223//1033 1200//1038 1199//1039 +f 1222//1034 1223//1033 1199//1039 +f 1222//1034 1199//1039 1198//1040 +f 1221//1035 1222//1034 1198//1040 +f 1221//1035 1198//1040 1197//1041 +f 1204//1036 1221//1035 1197//1041 +f 1204//1036 1197//1041 1185//1042 +f 1171//1037 1204//1036 1185//1042 +f 1171//1037 1185//1042 1151//1043 +f 1200//1038 1201//939 1169//941 +f 1200//1038 1169//941 1168//1044 +f 1199//1039 1200//1038 1168//1044 +f 1199//1039 1168//1044 1167//1045 +f 1198//1040 1199//1039 1167//1045 +f 1198//1040 1167//1045 1166//1046 +f 1197//1041 1198//1040 1166//1046 +f 1197//1041 1166//1046 1165//1047 +f 1185//1042 1197//1041 1165//1047 +f 1185//1042 1165//1047 1164//1048 +f 1151//1043 1185//1042 1164//1048 +f 1151//1043 1164//1048 1137//1049 +f 1168//1044 1169//941 1135//943 +f 1168//1044 1135//943 1134//1050 +f 1167//1045 1168//1044 1134//1050 +f 1167//1045 1134//1050 1133//1051 +f 1166//1046 1167//1045 1133//1051 +f 1166//1046 1133//1051 1132//1052 +f 1165//1047 1166//1046 1132//1052 +f 1165//1047 1132//1052 1131//1053 +f 1164//1048 1165//1047 1131//1053 +f 1164//1048 1131//1053 1130//1054 +f 1137//1049 1164//1048 1130//1054 +f 1137//1049 1130//1054 1117//1055 +f 1134//1050 1135//943 1102//945 +f 1134//1050 1102//945 1101//1056 +f 1133//1051 1134//1050 1101//1056 +f 1133//1051 1101//1056 1100//1057 +f 1132//1052 1133//1051 1100//1057 +f 1132//1052 1100//1057 1099//1058 +f 1131//1053 1132//1052 1099//1058 +f 1131//1053 1099//1058 1098//1059 +f 1130//1054 1131//1053 1098//1059 +f 1130//1054 1098//1059 1097//1060 +f 1117//1055 1130//1054 1097//1060 +f 1117//1055 1097//1060 1096//1061 +f 1101//1056 1102//945 1065//947 +f 1101//1056 1065//947 1064//1062 +f 1100//1057 1101//1056 1064//1062 +f 1100//1057 1064//1062 1063//1063 +f 1099//1058 1100//1057 1063//1063 +f 1099//1058 1063//1063 1062//1064 +f 1098//1059 1099//1058 1062//1064 +f 1098//1059 1062//1064 1061//1065 +f 1097//1060 1098//1059 1061//1065 +f 1097//1060 1061//1065 1060//1066 +f 1096//1061 1097//1060 1060//1066 +f 1096//1061 1060//1066 1066//1067 +f 1064//1062 1065//947 1032//949 +f 1064//1062 1032//949 1031//1068 +f 1063//1063 1064//1062 1031//1068 +f 1063//1063 1031//1068 1030//1069 +f 1062//1064 1063//1063 1030//1069 +f 1062//1064 1030//1069 1029//1070 +f 1061//1065 1062//1064 1029//1070 +f 1061//1065 1029//1070 1028//1071 +f 1060//1066 1061//1065 1028//1071 +f 1060//1066 1028//1071 1033//1072 +f 1066//1067 1060//1066 1033//1072 +f 1066//1067 1033//1072 1050//1073 +f 1031//1068 1032//949 1003//951 +f 1031//1068 1003//951 1002//1074 +f 1030//1069 1031//1068 1002//1074 +f 1030//1069 1002//1074 1001//1075 +f 1029//1070 1030//1069 1001//1075 +f 1029//1070 1001//1075 1000//1076 +f 1028//1071 1029//1070 1000//1076 +f 1028//1071 1000//1076 1004//1077 +f 1033//1072 1028//1071 1004//1077 +f 1033//1072 1004//1077 1021//1078 +f 1050//1073 1033//1072 1021//1078 +f 1050//1073 1021//1078 1041//1079 +f 1002//1074 1003//951 974//953 +f 1002//1074 974//953 973//1080 +f 1001//1075 1002//1074 973//1080 +f 1001//1075 973//1080 972//1081 +f 1000//1076 1001//1075 972//1081 +f 1000//1076 972//1081 975//1082 +f 1004//1077 1000//1076 975//1082 +f 1004//1077 975//1082 992//1083 +f 1021//1078 1004//1077 992//1083 +f 1021//1078 992//1083 1010//1084 +f 1041//1079 1021//1078 1010//1084 +f 1041//1079 1010//1084 1040//1085 +f 973//1080 974//953 951//955 +f 973//1080 951//955 950//1086 +f 972//1081 973//1080 950//1086 +f 972//1081 950//1086 952//1087 +f 975//1082 972//1081 952//1087 +f 975//1082 952//1087 965//1088 +f 992//1083 975//1082 965//1088 +f 992//1083 965//1088 983//1089 +f 1010//1084 992//1083 983//1089 +f 1010//1084 983//1089 1009//1090 +f 1040//1085 1010//1084 1009//1090 +f 1040//1085 1009//1090 1039//1091 +f 950//1086 951//955 934//957 +f 950//1086 934//957 935//1092 +f 952//1087 950//1086 935//1092 +f 952//1087 935//1092 944//1093 +f 965//1088 952//1087 944//1093 +f 965//1088 944//1093 958//1094 +f 983//1089 965//1088 958//1094 +f 983//1089 958//1094 982//1095 +f 1009//1090 983//1089 982//1095 +f 1009//1090 982//1095 1008//1096 +f 1039//1091 1009//1090 1008//1096 +f 1039//1091 1008//1096 1038//1097 +f 935//1092 934//957 924//959 +f 935//1092 924//959 929//1098 +f 944//1093 935//1092 929//1098 +f 944//1093 929//1098 939//1099 +f 958//1094 944//1093 939//1099 +f 958//1094 939//1099 957//1100 +f 982//1095 958//1094 957//1100 +f 982//1095 957//1100 981//1101 +f 1008//1096 982//1095 981//1101 +f 1008//1096 981//1101 1007//1102 +f 1038//1097 1008//1096 1007//1102 +f 1038//1097 1007//1102 1037//1103 +f 924//959 920//912 929//1098 +f 929//1098 920//912 926//960 +f 939//1099 929//1098 926//960 +f 939//1099 926//960 938//962 +f 957//1100 939//1099 938//962 +f 957//1100 938//962 956//964 +f 981//1101 957//1100 956//964 +f 981//1101 956//964 980//966 +f 1007//1102 981//1101 980//966 +f 1007//1102 980//966 1006//968 +f 1037//1103 1007//1102 1006//968 +f 1037//1103 1006//968 1036//970 +f 993//1104 1005//1105 976//1106 +f 966//1107 993//1104 976//1106 +f 966//1107 976//1106 953//1108 +f 945//1109 966//1107 953//1108 +f 945//1109 953//1108 936//1110 +f 930//1111 945//1109 936//1110 +f 930//1111 936//1110 925//1112 +f 921//913 930//1111 925//1112 +f 921//913 925//1112 922//914 +f 976//1106 1005//1105 977//1113 +f 953//1108 976//1106 977//1113 +f 953//1108 977//1113 954//1114 +f 936//1110 953//1108 954//1114 +f 936//1110 954//1114 937//1115 +f 925//1112 936//1110 937//1115 +f 925//1112 937//1115 931//1116 +f 922//914 925//1112 931//1116 +f 922//914 931//1116 927//916 +f 977//1113 1005//1105 978//1117 +f 954//1114 977//1113 978//1117 +f 954//1114 978//1117 955//1118 +f 937//1115 954//1114 955//1118 +f 937//1115 955//1118 946//1119 +f 931//1116 937//1115 946//1119 +f 931//1116 946//1119 941//1120 +f 927//916 931//1116 941//1120 +f 927//916 941//1120 940//918 +f 978//1117 1005//1105 979//1121 +f 955//1118 978//1117 979//1121 +f 955//1118 979//1121 967//1122 +f 946//1119 955//1118 967//1122 +f 946//1119 967//1122 961//1123 +f 941//1120 946//1119 961//1123 +f 941//1120 961//1123 960//1124 +f 940//918 941//1120 960//1124 +f 940//918 960//1124 959//920 +f 979//1121 1005//1105 994//1125 +f 967//1122 979//1121 994//1125 +f 967//1122 994//1125 987//1126 +f 961//1123 967//1122 987//1126 +f 961//1123 987//1126 986//1127 +f 960//1124 961//1123 986//1127 +f 960//1124 986//1127 985//1128 +f 959//920 960//1124 985//1128 +f 959//920 985//1128 984//922 +f 994//1125 1005//1105 1015//1129 +f 987//1126 994//1125 1015//1129 +f 987//1126 1015//1129 1014//1130 +f 986//1127 987//1126 1014//1130 +f 986//1127 1014//1130 1013//1131 +f 985//1128 986//1127 1013//1131 +f 985//1128 1013//1131 1012//1132 +f 984//922 985//1128 1012//1132 +f 984//922 1012//1132 1011//924 +f 1015//1129 1005//1105 1035//1133 +f 1014//1130 1015//1129 1035//1133 +f 1014//1130 1035//1133 1045//1134 +f 1013//1131 1014//1130 1045//1134 +f 1013//1131 1045//1134 1044//1135 +f 1012//1132 1013//1131 1044//1135 +f 1012//1132 1044//1135 1043//1136 +f 1011//924 1012//1132 1043//1136 +f 1011//924 1043//1136 1042//926 +f 1035//1133 1005//1105 1052//1137 +f 1045//1134 1035//1133 1052//1137 +f 1045//1134 1052//1137 1080//1138 +f 1044//1135 1045//1134 1080//1138 +f 1044//1135 1080//1138 1079//1139 +f 1043//1136 1044//1135 1079//1139 +f 1043//1136 1079//1139 1078//1140 +f 1042//926 1043//1136 1078//1140 +f 1042//926 1078//1140 1077//928 +f 1052//1137 1005//1105 1068//1141 +f 1080//1138 1052//1137 1068//1141 +f 1080//1138 1068//1141 1106//1142 +f 1079//1139 1080//1138 1106//1142 +f 1079//1139 1106//1142 1112//1143 +f 1078//1140 1079//1139 1112//1143 +f 1078//1140 1112//1143 1111//1144 +f 1077//928 1078//1140 1111//1144 +f 1077//928 1111//1144 1110//930 +f 1068//1141 1005//1105 1087//1145 +f 1106//1142 1068//1141 1087//1145 +f 1106//1142 1087//1145 1120//1146 +f 1112//1143 1106//1142 1120//1146 +f 1112//1143 1120//1146 1146//1147 +f 1111//1144 1112//1143 1146//1147 +f 1111//1144 1146//1147 1145//1148 +f 1110//930 1111//1144 1145//1148 +f 1110//930 1145//1148 1144//932 +f 1087//1145 1005//1105 1107//1149 +f 1120//1146 1087//1145 1107//1149 +f 1120//1146 1107//1149 1140//1150 +f 1146//1147 1120//1146 1140//1150 +f 1146//1147 1140//1150 1174//1151 +f 1145//1148 1146//1147 1174//1151 +f 1145//1148 1174//1151 1180//1152 +f 1144//932 1145//1148 1180//1152 +f 1144//932 1180//1152 1179//934 +f 1107//1149 1005//1105 1121//1153 +f 1140//1150 1107//1149 1121//1153 +f 1140//1150 1121//1153 1154//1154 +f 1174//1151 1140//1150 1154//1154 +f 1174//1151 1154//1154 1188//1155 +f 1180//1152 1174//1151 1188//1155 +f 1180//1152 1188//1155 1211//1156 +f 1179//934 1180//1152 1211//1156 +f 1179//934 1211//1156 1210//936 +f 1121//1153 1005//1105 1141//1157 +f 1154//1154 1121//1153 1141//1157 +f 1154//1154 1141//1157 1175//1158 +f 1188//1155 1154//1154 1175//1158 +f 1188//1155 1175//1158 1206//1159 +f 1211//1156 1188//1155 1206//1159 +f 1211//1156 1206//1159 1226//1160 +f 1210//936 1211//1156 1226//1160 +f 1210//936 1226//1160 1212//938 +f 1141//1157 1005//1105 1155//1161 +f 1175//1158 1141//1157 1155//1161 +f 1175//1158 1155//1161 1187//1162 +f 1206//1159 1175//1158 1187//1162 +f 1206//1159 1187//1162 1205//1163 +f 1226//1160 1206//1159 1205//1163 +f 1226//1160 1205//1163 1213//1164 +f 1212//938 1226//1160 1213//1164 +f 1212//938 1213//1164 1181//940 +f 1155//1161 1005//1105 1153//1165 +f 1187//1162 1155//1161 1153//1165 +f 1187//1162 1153//1165 1173//1166 +f 1205//1163 1187//1162 1173//1166 +f 1205//1163 1173//1166 1186//1167 +f 1213//1164 1205//1163 1186//1167 +f 1213//1164 1186//1167 1182//1168 +f 1181//940 1213//1164 1182//1168 +f 1181//940 1182//1168 1147//942 +f 1153//1165 1005//1105 1139//1169 +f 1173//1166 1153//1165 1139//1169 +f 1173//1166 1139//1169 1152//1170 +f 1186//1167 1173//1166 1152//1170 +f 1186//1167 1152//1170 1172//1171 +f 1182//1168 1186//1167 1172//1171 +f 1182//1168 1172//1171 1148//1172 +f 1147//942 1182//1168 1148//1172 +f 1147//942 1148//1172 1113//944 +f 1139//1169 1005//1105 1119//1173 +f 1152//1170 1139//1169 1119//1173 +f 1152//1170 1119//1173 1138//1174 +f 1172//1171 1152//1170 1138//1174 +f 1172//1171 1138//1174 1149//1175 +f 1148//1172 1172//1171 1149//1175 +f 1148//1172 1149//1175 1114//1176 +f 1113//944 1148//1172 1114//1176 +f 1113//944 1114//1176 1081//946 +f 1119//1173 1005//1105 1105//1177 +f 1138//1174 1119//1173 1105//1177 +f 1138//1174 1105//1177 1118//1178 +f 1149//1175 1138//1174 1118//1178 +f 1149//1175 1118//1178 1115//1179 +f 1114//1176 1149//1175 1115//1179 +f 1114//1176 1115//1179 1082//1180 +f 1081//946 1114//1176 1082//1180 +f 1081//946 1082//1180 1046//948 +f 1105//1177 1005//1105 1086//1181 +f 1118//1178 1105//1177 1086//1181 +f 1118//1178 1086//1181 1104//1182 +f 1115//1179 1118//1178 1104//1182 +f 1115//1179 1104//1182 1083//1183 +f 1082//1180 1115//1179 1083//1183 +f 1082//1180 1083//1183 1047//1184 +f 1046//948 1082//1180 1047//1184 +f 1046//948 1047//1184 1016//950 +f 1086//1181 1005//1105 1067//1185 +f 1104//1182 1086//1181 1067//1185 +f 1104//1182 1067//1185 1084//1186 +f 1083//1183 1104//1182 1084//1186 +f 1083//1183 1084//1186 1048//1187 +f 1047//1184 1083//1183 1048//1187 +f 1047//1184 1048//1187 1017//1188 +f 1016//950 1047//1184 1017//1188 +f 1016//950 1017//1188 988//952 +f 1067//1185 1005//1105 1051//1189 +f 1084//1186 1067//1185 1051//1189 +f 1084//1186 1051//1189 1049//1190 +f 1048//1187 1084//1186 1049//1190 +f 1048//1187 1049//1190 1018//1191 +f 1017//1188 1048//1187 1018//1191 +f 1017//1188 1018//1191 989//1192 +f 988//952 1017//1188 989//1192 +f 988//952 989//1192 962//954 +f 1051//1189 1005//1105 1034//1193 +f 1049//1190 1051//1189 1034//1193 +f 1049//1190 1034//1193 1019//1194 +f 1018//1191 1049//1190 1019//1194 +f 1018//1191 1019//1194 990//1195 +f 989//1192 1018//1191 990//1195 +f 989//1192 990//1195 963//1196 +f 962//954 989//1192 963//1196 +f 962//954 963//1196 942//956 +f 1034//1193 1005//1105 1020//1197 +f 1019//1194 1034//1193 1020//1197 +f 1019//1194 1020//1197 991//1198 +f 990//1195 1019//1194 991//1198 +f 990//1195 991//1198 964//1199 +f 963//1196 990//1195 964//1199 +f 963//1196 964//1199 943//1200 +f 942//956 963//1196 943//1200 +f 942//956 943//1200 928//958 +f 1020//1197 1005//1105 993//1104 +f 991//1198 1020//1197 993//1104 +f 991//1198 993//1104 966//1107 +f 964//1199 991//1198 966//1107 +f 964//1199 966//1107 945//1109 +f 943//1200 964//1199 945//1109 +f 943//1200 945//1109 930//1111 +f 928//958 943//1200 930//1111 +f 928//958 930//1111 921//913 +f 1151//1043 1137//1049 1150//1201 +f 1142//995 1143//1202 1122//989 +f 1053//971 1089//977 1069//1203 +f 1122//989 1123//1204 1109//983 +f 1096//1061 1103//1205 1117//1055 +f 1171//1037 1170//1206 1184//1031 +f 1191//1013 1209//1019 1190//1207 +f 1036//970 1053//971 1070//1208 +f 1036//970 1070//1208 1037//1103 +f 1203//1025 1202//1209 1209//1019 +f 1066//1067 1085//1210 1096//1061 +f 1050//1073 1076//1211 1066//1067 +f 1184//1031 1183//1212 1203//1025 +f 1041//1079 1040//1085 1075//1213 +f 1171//1037 1151//1043 1170//1206 +f 1157//1001 1158//1214 1142//995 +f 1137//1049 1117//1055 1136//1215 +f 1038//1097 1072//1216 1039//1091 +f 1178//1007 1191//1013 1177//1217 +f 1089//977 1109//983 1088//1218 +f 1037//1103 1071//1219 1038//1097 +f 1050//1073 1041//1079 1076//1211 +f 1157//1001 1178//1007 1158//1214 +f 1040//1085 1039//1091 1074//1220 +f 1170//1206 1150//1201 452//1221 +f 1264//1222 1071//1219 1263//1223 +f 1261//1224 1262//1225 1076//1211 +f 1085//1210 1076//1211 1262//1225 +f 1190//1207 1208//1226 405//1227 +f 509//176 526//519 1260//1228 +f 1260//1228 526//519 556//523 +f 167//201 556//523 595//202 +f 595//202 621//526 1255//200 +f 172//192 163//182 1254//199 +f 8//49 18//42 3//1229 +f 3//1229 18//42 1288//1230 +f 15//75 7//66 1240//82 +f 1250//50 8//49 3//1229 +f 1//32 1283//40 566//33 +f 593//3 566//33 9//41 +f 19//1231 20//34 33//25 +f 1243//2 636//89 593//3 +f 64//18 40//6 36//17 +f 1244//24 64//18 36//17 +f 641//579 614//582 1237//1232 +f 1250//50 1239//1233 4//48 +f 7//66 4//48 1239//1233 +f 5//74 14//73 11//81 +f 1240//82 7//66 1239//1233 +f 1//32 553//31 565//56 +f 593//3 9//41 1289//83 +f 18//42 20//34 1288//1230 +f 40//6 27//5 1252//16 +f 1249//58 6//65 565//56 +f 14//73 15//75 11//81 +f 592//57 1234//130 1233//58 +f 1237//1232 614//582 588//586 +f 1237//1232 588//586 605//592 +f 539//175 159//177 1259//1234 +f 164//257 1257//1235 168//251 +f 509//176 1256//1236 159//177 +f 1258//250 585//249 1259//1234 +f 169//1237 164//257 174//242 +f 191//236 208//230 185//1238 +f 1290//1239 207//229 640//777 +f 621//526 1292//1240 1255//200 +f 163//182 160//178 157//180 +f 1284//1241 1292//1240 648//227 +f 1252//16 27//5 12//95 +f 119//124 116//129 104//161 +f 116//129 88//135 1242//136 +f 87//159 666//713 715//160 +f 87//159 1241//1242 666//713 +f 1253//1243 47//150 631//152 +f 631//152 666//713 1253//1243 +f 86//142 74//144 60//143 +f 640//777 1291//1244 1290//1239 +f 1291//1244 640//777 613//248 +f 208//230 219//220 200//1245 +f 665//778 640//777 207//229 +f 1285//226 200//1245 219//220 +f 648//227 207//229 1284//1241 +f 691//228 665//778 207//229 +f 605//592 1236//1246 1245//1246 +f 1235//151 605//592 631//152 +f 1248//145 48//153 37//167 +f 667//708 1251//1247 1247//158 +f 605//592 1235//151 1236//1246 +f 641//579 1238//1248 1246//1249 +f 641//579 1237//1232 1238//1248 +f 404//412 391//405 1267//904 +f 1265//911 453//433 436//426 +f 328//351 327//350 331//910 +f 443//445 462//439 469//1250 +f 342//370 1275//1251 344//1252 +f 342//370 334//363 1275//1251 +f 372//480 385//473 384//906 +f 351//377 1271//1253 361//384 +f 351//377 350//1254 1271//1253 +f 337//1255 335//508 345//501 +f 384//906 385//473 396//466 +f 361//384 368//1256 369//391 +f 361//384 1271//1253 368//1256 +f 352//494 1276//1257 346//908 +f 397//1258 396//466 411//459 +f 342//370 350//1254 351//377 +f 342//370 344//1252 350//1254 +f 380//398 369//391 368//1256 +f 334//363 328//351 332//1259 +f 404//412 418//1260 419//419 +f 404//412 1268//905 418//1260 +f 426//452 1286//1261 1282//1262 +f 1282//1262 411//459 426//452 +f 352//494 362//487 1277//1263 +f 1277//1263 1276//1257 352//494 +f 391//405 380//398 381//1264 +f 426//452 443//445 444//1265 +f 444//1265 1286//1261 426//452 +f 362//487 372//480 373//907 +f 373//907 1277//1263 362//487 +f 1202//1209 1183//1212 1270//1266 +f 1116//1267 428//1268 1136//1215 +f 428//1268 1287//1269 1136//1215 +f 1073//1270 353//1271 1074//1220 +f 353//1271 363//1272 1074//1220 +f 353//1271 1073//1270 1279//1273 +f 1070//1208 1069//1203 1263//1223 +f 1274//1274 1069//1203 1088//1218 +f 1177//1217 1273//1275 1272//1276 +f 1272//1276 1158//1214 1177//1217 +f 428//1268 1116//1267 427//1277 +f 1088//1218 1108//1278 343//1279 +f 1103//1205 1085//1210 1278//1280 +f 1108//1278 1123//1204 1280//1281 +f 1123//1204 1281//1282 1280//1281 +f 1143//1202 1158//1214 360//1283 +f 1158//1214 1272//1276 360//1283 +f 1075//1213 1261//1224 1076//1211 +f 1085//1210 1262//1225 1278//1280 +f 1123//1204 1143//1202 1281//1282 +f 1143//1202 360//1283 1281//1282 +f 1074//1220 363//1272 1075//1213 +f 363//1272 1261//1224 1075//1213 +f 1270//1266 1183//1212 452//1221 +f 1266//1284 1150//1201 1136//1215 +f 1273//1275 1177//1217 1190//1207 +f 1208//1226 1202//1209 406//1285 +f 1202//1209 1269//1286 406//1285 +f 1072//1216 1071//1219 1264//1222 +f 1241//1242 1253//1243 666//713 +f 71//137 86//142 60//143 +f 88//135 86//142 71//137 +f 1245//1246 1237//1232 605//592 +f 119//124 104//161 90//119 +f 667//708 1246//1249 1251//1247 +f 621//526 648//227 1292//1240 +f 208//230 200//1245 185//1238 +f 174//242 191//236 169//1237 +f 1258//250 1291//1244 613//248 +f 1244//24 19//1231 33//25 +f 1288//1230 20//34 19//1231 +f 199//208 182//198 178//1287 +f 206//1288 218//214 190//1289 +f 1260//1228 556//523 167//201 +f 157//180 1254//199 163//182 +f 178//1287 182//198 1254//199 +f 218//214 206//1288 1285//226 +f 161//258 1257//1235 158//179 +f 324//345 312//274 323//336 +f 303//317 302//323 316//338 +f 305//305 304//311 318//340 +f 304//311 303//317 317//339 +f 322//347 309//281 321//341 +f 320//346 307//293 319//342 +f 301//329 311//335 314//344 +f 302//323 301//329 315//337 +f 311//335 312//274 313//343 +f 319//342 306//299 318//340 +f 321//341 308//287 320//346 +f 323//336 310//275 322//347 +f 418//1260 435//909 419//419 +f 337//1255 331//910 335//508 +f 469//1250 462//439 1265//911 +f 1137//1049 1136//1215 1150//1201 +f 1143//1202 1123//1204 1122//989 +f 1089//977 1088//1218 1069//1203 +f 1123//1204 1108//1278 1109//983 +f 1103//1205 1116//1267 1117//1055 +f 1170//1206 1183//1212 1184//1031 +f 1209//1019 1208//1226 1190//1207 +f 1053//971 1069//1203 1070//1208 +f 1070//1208 1071//1219 1037//1103 +f 1202//1209 1208//1226 1209//1019 +f 1085//1210 1103//1205 1096//1061 +f 1076//1211 1085//1210 1066//1067 +f 1183//1212 1202//1209 1203//1025 +f 1040//1085 1074//1220 1075//1213 +f 1151//1043 1150//1201 1170//1206 +f 1158//1214 1143//1202 1142//995 +f 1117//1055 1116//1267 1136//1215 +f 1072//1216 1073//1270 1039//1091 +f 1191//1013 1190//1207 1177//1217 +f 1109//983 1108//1278 1088//1218 +f 1071//1219 1072//1216 1038//1097 +f 1041//1079 1075//1213 1076//1211 +f 1178//1007 1177//1217 1158//1214 +f 1039//1091 1073//1270 1074//1220 +f 1150//1201 1266//1284 452//1221 +f 1071//1219 1070//1208 1263//1223 +f 1208//1226 406//1285 405//1227 +f 1256//1236 509//176 1260//1228 +f 1257//1235 161//258 168//251 +f 585//249 539//175 1259//1234 +f 715//160 667//708 1247//158 +f 667//708 641//579 1246//1249 +f 435//909 1265//911 436//426 +f 332//1259 328//351 331//910 +f 444//1265 443//445 469//1250 +f 346//908 337//1255 345//501 +f 397//1258 384//906 396//466 +f 1282//1262 397//1258 411//459 +f 381//1264 380//398 368//1256 +f 1275//1251 334//363 332//1259 +f 1267//904 391//405 381//1264 +f 1269//1286 1202//1209 1270//1266 +f 1073//1270 1072//1216 1279//1273 +f 1069//1203 1274//1274 1263//1223 +f 343//1279 1274//1274 1088//1218 +f 1116//1267 1103//1205 427//1277 +f 1108//1278 1280//1281 343//1279 +f 427//1277 1103//1205 1278//1280 +f 1183//1212 1170//1206 452//1221 +f 1287//1269 1266//1284 1136//1215 +f 405//1227 1273//1275 1190//1207 +f 1279//1273 1072//1216 1264//1222 +f 191//236 185//1238 169//1237 +f 190//1289 199//208 178//1287 +f 218//214 199//208 190//1289 diff --git a/A4/shadow8t4/shadow8t4/resources/vert.glsl b/A4/shadow8t4/shadow8t4/resources/vert.glsl new file mode 100644 index 0000000..ab647c8 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/resources/vert.glsl @@ -0,0 +1,24 @@ +#version 120 + +uniform mat4 P; +uniform mat4 MV; +uniform mat4 MVL; +uniform vec3 lightPos1; +uniform vec3 lightPos2; +uniform float i1; +uniform float i2; + +attribute vec4 aPos; // in object space +attribute vec3 aNor; // in object space + +varying vec3 color; // Pass to fragment shader +varying vec4 p; +varying vec4 n; + +void main() +{ + gl_Position = P * MV * aPos; + p = MV * aPos; + n = MV * vec4(aNor, 0.0); + color = vec3(0.5, 0.5, 0.5); +} diff --git a/A4/shadow8t4/shadow8t4/src/Camera.cpp b/A4/shadow8t4/shadow8t4/src/Camera.cpp new file mode 100644 index 0000000..4263a23 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Camera.cpp @@ -0,0 +1,68 @@ +/* +#include "Camera.h" +#include "MatrixStack.h" +#include +#include + +Camera::Camera() : + aspect(1.0f), + fovy(45.0f), + znear(0.1f), + zfar(1000.0f), + rotations(0.0, 0.0), + translations(0.0f, 0.0f, -5.0f), + rfactor(0.01f), + tfactor(0.001f), + sfactor(0.005f) +{ +} + +Camera::~Camera() +{ +} + +void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt) +{ + mousePrev.x = x; + mousePrev.y = y; + if(shift) { + state = Camera::TRANSLATE; + } else if(ctrl) { + state = Camera::SCALE; + } else { + state = Camera::ROTATE; + } +} + +void Camera::mouseMoved(float x, float y) +{ + glm::vec2 mouseCurr(x, y); + glm::vec2 dv = mouseCurr - mousePrev; + switch(state) { + case Camera::ROTATE: + rotations += rfactor * dv; + break; + case Camera::TRANSLATE: + translations.x -= translations.z * tfactor * dv.x; + translations.y += translations.z * tfactor * dv.y; + break; + case Camera::SCALE: + translations.z *= (1.0f - sfactor * dv.y); + break; + } + mousePrev = mouseCurr; +} + +void Camera::applyProjectionMatrix(std::shared_ptr P) const +{ + // Modify provided MatrixStack + P->multMatrix(glm::perspective(fovy, aspect, znear, zfar)); +} + +void Camera::applyViewMatrix(std::shared_ptr MV) const +{ + MV->translate(translations); + MV->rotate(rotations.y, glm::vec3(1.0f, 0.0f, 0.0f)); + MV->rotate(rotations.x, glm::vec3(0.0f, 1.0f, 0.0f)); +} +*/ diff --git a/A4/shadow8t4/shadow8t4/src/Camera.h b/A4/shadow8t4/shadow8t4/src/Camera.h new file mode 100644 index 0000000..f54a2fb --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Camera.h @@ -0,0 +1,49 @@ +/* +#pragma once +#ifndef __Camera__ +#define __Camera__ + +#include + +#define GLM_FORCE_RADIANS +#include + +class MatrixStack; + +class Camera +{ +public: + enum { + ROTATE = 0, + TRANSLATE, + SCALE + }; + + Camera(); + virtual ~Camera(); + void setInitDistance(float z) { translations.z = -std::abs(z); } + void setAspect(float a) { aspect = a; }; + void setRotationFactor(float f) { rfactor = f; }; + void setTranslationFactor(float f) { tfactor = f; }; + void setScaleFactor(float f) { sfactor = f; }; + void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt); + void mouseMoved(float x, float y); + void applyProjectionMatrix(std::shared_ptr P) const; + void applyViewMatrix(std::shared_ptr MV) const; + +private: + float aspect; + float fovy; + float znear; + float zfar; + glm::vec2 rotations; + glm::vec3 translations; + glm::vec2 mousePrev; + int state; + float rfactor; + float tfactor; + float sfactor; +}; + +#endif +*/ diff --git a/A4/shadow8t4/shadow8t4/src/Component.cpp b/A4/shadow8t4/shadow8t4/src/Component.cpp new file mode 100644 index 0000000..0edd093 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Component.cpp @@ -0,0 +1,122 @@ +#include +#include "Component.h" + +using namespace std; + +Component::Component() +{ + parent = NULL; + selected = false; + t = vec3(0,0,0); + tp = vec3(0,0,0); + r = vec3(0,0,0); + s = vec3(1.0,1.0,1.0); + children.resize(0); + sid = 0; +} + +Component::Component(const Component& c) +{ + parent = c.parent; + children = c.children; + selected = c.selected; + t = vec3(c.t.x, c.t.y, c.t.z); + tp = vec3(c.tp.x, c.tp.y, c.tp.z); + r = vec3(c.r.x, c.r.y, c.r.z); + s = vec3(c.s.x, c.s.y, c.s.z); + sid = c.sid; +} + +void Component::draw(shared_ptr MV, shared_ptr P, shared_ptr S, shared_ptr Prog) +{ + MV->pushMatrix(); + MV->translate(tp.x, tp.y, tp.z); + MV->rotate(r.x, 1, 0, 0); + MV->rotate(r.y, 0, 1, 0); + MV->rotate(r.z, 0, 0, 1); + MV->translate(t.x, t.y, t.z); + for(unsigned int i = 0; i < children.size(); i++) + { + children[i].draw(MV, P, S, Prog); + } + if(selected) + { + MV->scale(1.1,1.1,1.1); + } + MV->scale(s.x,s.y,s.z); + glUniformMatrix4fv(Prog->getUniform("P"), 1, GL_FALSE, &P->topMatrix()[0][0]); + glUniformMatrix4fv(Prog->getUniform("MV"), 1, GL_FALSE, &MV->topMatrix()[0][0]); + S->draw(Prog); + MV->popMatrix(); +} + +Component& Component::getLastChild() +{ + if(this->children.empty()) + { + return *this; + } + return this->children[this->children.size() - 1].getLastChild(); +} + +Component& Component::getPrevious(Component *addr) +{ + if(children.empty()) + { + if(parent != NULL) + { + return parent->getPrevious(this); + } + } + + for(unsigned int i = 0; i < this->children.size(); i++) + { + //return *this; + if(&children[i] == addr) + { + if(i > 0) + { + return children[i-1].getLastChild(); + } + else + { + return *this; + } + } + } + + if (parent == NULL) { + return this->getLastChild(); + } + + return parent->getPrevious(this); +} + +Component& Component::getNext(Component *addr) +{ + if(addr == NULL) + { + if(!children.empty()) + { + return children[0]; + } + } + + for(unsigned int i = 0; i < this->children.size(); i++) + { + //return *this; + if(&children[i] == addr) + { + if(i+1 < children.size()) + { + return children[i+1]; + } + } + } + + if (parent == NULL) { + return *this; + } + + return parent->getNext(this); +} diff --git a/A4/shadow8t4/shadow8t4/src/Component.h b/A4/shadow8t4/shadow8t4/src/Component.h new file mode 100644 index 0000000..cebf40b --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Component.h @@ -0,0 +1,30 @@ +// Create Body Class +#include +#include "MatrixStack.h" +#include +#include +#include "Shape.h" +#include "Program.h" + +using namespace std; +using namespace glm; + +class Component +{ + public: + Component *parent; + vector children; + bool selected; + vec3 t; + vec3 tp; + vec3 r; + vec3 s; + int sid; // used for storing which shape to render + + Component(); + Component(const Component& c); + void draw(shared_ptr MV, shared_ptr P, shared_ptr S, shared_ptr Prog); + Component& getNext(Component *addr); + Component& getPrevious(Component *addr); + Component& getLastChild(); +}; diff --git a/A4/shadow8t4/shadow8t4/src/GLSL.cpp b/A4/shadow8t4/shadow8t4/src/GLSL.cpp new file mode 100644 index 0000000..2969872 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/GLSL.cpp @@ -0,0 +1,152 @@ +// +// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book +// Created by zwood on 2/21/10. +// Modified by sueda 10/15/15. +// + +#include "GLSL.h" +#include +#include +#include +#include + +using namespace std; + +namespace GLSL { + +const char * errorString(GLenum err) +{ + switch(err) { + case GL_NO_ERROR: + return "No error"; + case GL_INVALID_ENUM: + return "Invalid enum"; + case GL_INVALID_VALUE: + return "Invalid value"; + case GL_INVALID_OPERATION: + return "Invalid operation"; + case GL_STACK_OVERFLOW: + return "Stack overflow"; + case GL_STACK_UNDERFLOW: + return "Stack underflow"; + case GL_OUT_OF_MEMORY: + return "Out of memory"; + default: + return "No error"; + } +} + +void checkVersion() +{ + int major, minor; + major = minor = 0; + const char *verstr = (const char *)glGetString(GL_VERSION); + + if((verstr == NULL) || (sscanf(verstr, "%d.%d", &major, &minor) != 2)) { + printf("Invalid GL_VERSION format %d.%d\n", major, minor); + } + if(major < 2) { + printf("This shader example will not work due to the installed Opengl version, which is %d.%d.\n", major, minor); + exit(0); + } +} + +void checkError(const char *str) +{ + GLenum glErr = glGetError(); + if(glErr != GL_NO_ERROR) { + if(str) { + printf("%s: ", str); + } + printf("GL_ERROR = %s.\n", errorString(glErr)); + assert(false); + } +} + +void printShaderInfoLog(GLuint shader) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog = 0; + + checkError(GET_FILE_LINE); + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength); + checkError(GET_FILE_LINE); + + if(infologLength > 0) { + infoLog = (GLchar *)malloc(infologLength); + if(infoLog == NULL) { + puts("ERROR: Could not allocate InfoLog buffer"); + exit(1); + } + glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog); + checkError(GET_FILE_LINE); + printf("Shader InfoLog:\n%s\n\n", infoLog); + free(infoLog); + } +} + +void printProgramInfoLog(GLuint program) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog = 0; + + checkError(GET_FILE_LINE); + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infologLength); + checkError(GET_FILE_LINE); + + if(infologLength > 0) { + infoLog = (GLchar *)malloc(infologLength); + if(infoLog == NULL) { + puts("ERROR: Could not allocate InfoLog buffer"); + exit(1); + } + glGetProgramInfoLog(program, infologLength, &charsWritten, infoLog); + checkError(GET_FILE_LINE); + printf("Program InfoLog:\n%s\n\n", infoLog); + free(infoLog); + } +} + +char *textFileRead(const char *fn) +{ + FILE *fp; + char *content = NULL; + int count = 0; + if(fn != NULL) { + fp = fopen(fn,"rt"); + if(fp != NULL) { + fseek(fp, 0, SEEK_END); + count = (int)ftell(fp); + rewind(fp); + if(count > 0) { + content = (char *)malloc(sizeof(char) * (count+1)); + count = (int)fread(content,sizeof(char),count,fp); + content[count] = '\0'; + } + fclose(fp); + } else { + printf("error loading %s\n", fn); + } + } + return content; +} + +int textFileWrite(const char *fn, const char *s) +{ + FILE *fp; + int status = 0; + if(fn != NULL) { + fp = fopen(fn,"w"); + if(fp != NULL) { + if(fwrite(s,sizeof(char),strlen(s),fp) == strlen(s)) { + status = 1; + } + fclose(fp); + } + } + return(status); +} + +} diff --git a/A4/shadow8t4/shadow8t4/src/GLSL.h b/A4/shadow8t4/shadow8t4/src/GLSL.h new file mode 100644 index 0000000..f945fdd --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/GLSL.h @@ -0,0 +1,40 @@ +// +// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book +// Created by zwood on 2/21/10. +// Modified by sueda 10/15/15. +// + +#pragma once +#ifndef __GLSL__ +#define __GLSL__ + +#define GLEW_STATIC +#include + +/////////////////////////////////////////////////////////////////////////////// +// For printing out the current file and line number // +/////////////////////////////////////////////////////////////////////////////// +#include + +template +std::string NumberToString(T x) +{ + std::ostringstream ss; + ss << x; + return ss.str(); +} + +#define GET_FILE_LINE (std::string(__FILE__) + ":" + NumberToString(__LINE__)).c_str() +/////////////////////////////////////////////////////////////////////////////// + +namespace GLSL { + + void checkVersion(); + void checkError(const char *str = 0); + void printProgramInfoLog(GLuint program); + void printShaderInfoLog(GLuint shader); + int textFileWrite(const char *filename, const char *s); + char *textFileRead(const char *filename); +} + +#endif diff --git a/A4/shadow8t4/shadow8t4/src/Light.cpp b/A4/shadow8t4/shadow8t4/src/Light.cpp new file mode 100644 index 0000000..ebe7525 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Light.cpp @@ -0,0 +1,39 @@ +#include "Light.h" + +Light::Light() +{ + pos = glm::vec3(0.0f, 0.0f, 0.0f); + intensity = 0.0; +} + +Light::Light(const Light &l) +{ + pos = l.pos; + intensity = l.intensity; +} + +Light::Light(glm::vec3 p, float i) +{ + pos = p; + intensity = i; +} + +void Light::setPos(glm::vec3 p) +{ + this->pos = p; +} + +void Light::setIntensity(float i) +{ + this->intensity = i; +} + +glm::vec3 Light::getPos() +{ + return this->pos; +} + +float Light::getIntensity() +{ + return this->intensity; +} diff --git a/A4/shadow8t4/shadow8t4/src/Light.h b/A4/shadow8t4/shadow8t4/src/Light.h new file mode 100644 index 0000000..a1c3ed1 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Light.h @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include + +#include "GLSL.h" +#include "MyCamera.h" +#include "Shape.h" +#include "MatrixStack.h" + +class Light +{ + private: + glm::vec3 pos; + float intensity; + + public: + Light(); + Light(const Light &l); + Light(glm::vec3 p, float i); + void setPos(glm::vec3 p); + void setIntensity(float i); + glm::vec3 getPos(); + float getIntensity(); +}; diff --git a/A4/shadow8t4/shadow8t4/src/Material.cpp b/A4/shadow8t4/shadow8t4/src/Material.cpp new file mode 100644 index 0000000..279c0d0 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Material.cpp @@ -0,0 +1,39 @@ +#include "Material.h" + +using namespace std; + +Material::Material() +{ + this->ca = glm::vec3(0.3f,0.3f,0.3f); + this->cd = glm::vec3(0.3f,0.3f,0.3f); + this->cs = glm::vec3(1.0f,1.0f,1.0f); + this->shine = 0.0f; +} + +void Material::setMaterial(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh) +{ + this->ca = a; + this->cd = d; + this->cs = s; + this->shine = sh; +} + +glm::vec3 Material::getAmbient() +{ + return this->ca; +} + +glm::vec3 Material::getDiffuse() +{ + return this->cd; +} + +glm::vec3 Material::getSpecular() +{ + return this->cs; +} + +float Material::getShiny() +{ + return this->shine; +} diff --git a/A4/shadow8t4/shadow8t4/src/Material.h b/A4/shadow8t4/shadow8t4/src/Material.h new file mode 100644 index 0000000..3741f2d --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Material.h @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include + +#include "GLSL.h" +#include "MyCamera.h" +#include "Shape.h" +#include "MatrixStack.h" + +class Material +{ + private: + glm::vec3 ca; + glm::vec3 cd; + glm::vec3 cs; + float shine; + + public: + Material(); + Material(const Material &m) + { + ca = m.ca; + cd = m.cd; + cs = m.cs; + } + Material(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh) + { + ca = a; + cd = d; + cs = s; + shine = sh; + } + void setMaterial(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh); + glm::vec3 getAmbient(); + glm::vec3 getDiffuse(); + glm::vec3 getSpecular(); + float getShiny(); +}; diff --git a/A4/shadow8t4/shadow8t4/src/MatrixStack.cpp b/A4/shadow8t4/shadow8t4/src/MatrixStack.cpp new file mode 100644 index 0000000..eaa6e6c --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/MatrixStack.cpp @@ -0,0 +1,114 @@ +#include "MatrixStack.h" + +#include +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +using namespace std; + +MatrixStack::MatrixStack() +{ + mstack = make_shared< stack >(); + mstack->push(glm::mat4(1.0)); +} + +MatrixStack::~MatrixStack() +{ +} + +void MatrixStack::pushMatrix() +{ + const glm::mat4 &top = mstack->top(); + mstack->push(top); + assert(mstack->size() < 100); +} + +void MatrixStack::popMatrix() +{ + assert(!mstack->empty()); + mstack->pop(); + // There should always be one matrix left. + assert(!mstack->empty()); +} + +void MatrixStack::loadIdentity() +{ + glm::mat4 &top = mstack->top(); + top = glm::mat4(1.0); +} + +void MatrixStack::translate(const glm::vec3 &t) +{ + glm::mat4 &top = mstack->top(); + top *= glm::translate(t); +} + +void MatrixStack::translate(float x, float y, float z) +{ + translate(glm::vec3(x, y, z)); +} + +void MatrixStack::scale(const glm::vec3 &s) +{ + glm::mat4 &top = mstack->top(); + top *= glm::scale(s); +} + +void MatrixStack::scale(float x, float y, float z) +{ + scale(glm::vec3(x, y, z)); +} + +void MatrixStack::scale(float s) +{ + scale(glm::vec3(s, s, s)); +} + +void MatrixStack::rotate(float angle, const glm::vec3 &axis) +{ + glm::mat4 &top = mstack->top(); + top *= glm::rotate(angle, axis); +} + +void MatrixStack::rotate(float angle, float x, float y, float z) +{ + rotate(angle, glm::vec3(x, y, z)); +} + +void MatrixStack::multMatrix(const glm::mat4 &matrix) +{ + glm::mat4 &top = mstack->top(); + top *= matrix; +} + +const glm::mat4 &MatrixStack::topMatrix() const +{ + return mstack->top(); +} + +void MatrixStack::print(const glm::mat4 &mat, const char *name) +{ + if(name) { + printf("%s = [\n", name); + } + for(int i = 0; i < 4; ++i) { + for(int j = 0; j < 4; ++j) { + // mat[j] returns the jth column + printf("%- 5.2f ", mat[j][i]); + } + printf("\n"); + } + if(name) { + printf("];"); + } + printf("\n"); +} + +void MatrixStack::print(const char *name) const +{ + print(mstack->top(), name); +} diff --git a/A4/shadow8t4/shadow8t4/src/MatrixStack.h b/A4/shadow8t4/shadow8t4/src/MatrixStack.h new file mode 100644 index 0000000..66278ce --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/MatrixStack.h @@ -0,0 +1,50 @@ +#pragma once +#ifndef _MatrixStack_H_ +#define _MatrixStack_H_ + +#include +#include +#include + +class MatrixStack +{ +public: + MatrixStack(); + virtual ~MatrixStack(); + + // glPushMatrix(): Copies the current matrix and adds it to the top of the stack + void pushMatrix(); + // glPopMatrix(): Removes the top of the stack and sets the current matrix to be the matrix that is now on top + void popMatrix(); + + // glLoadIdentity(): Sets the top matrix to be the identity + void loadIdentity(); + // glMultMatrix(): Right multiplies the top matrix + void multMatrix(const glm::mat4 &matrix); + + // glTranslate(): Right multiplies the top matrix by a translation matrix + void translate(const glm::vec3 &trans); + void translate(float x, float y, float z); + // glScale(): Right multiplies the top matrix by a scaling matrix + void scale(const glm::vec3 &scale); + void scale(float x, float y, float z); + // glScale(): Right multiplies the top matrix by a scaling matrix + void scale(float size); + // glRotate(): Right multiplies the top matrix by a rotation matrix (angle in radians) + void rotate(float angle, const glm::vec3 &axis); + void rotate(float angle, float x, float y, float z); + + // glGet(GL_MODELVIEW_MATRIX): Gets the top matrix + const glm::mat4 &topMatrix() const; + + // Prints out the specified matrix + static void print(const glm::mat4 &mat, const char *name = 0); + // Prints out the top matrix + void print(const char *name = 0) const; + +private: + std::shared_ptr< std::stack > mstack; + +}; + +#endif diff --git a/A4/shadow8t4/shadow8t4/src/MyCamera.cpp b/A4/shadow8t4/shadow8t4/src/MyCamera.cpp new file mode 100644 index 0000000..affa6c0 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/MyCamera.cpp @@ -0,0 +1,88 @@ +#include "MyCamera.h" +#include "MatrixStack.h" +#include +#include + +Camera::Camera() : + aspect(1.0f), + fovy(45.0f), + znear(0.1f), + zfar(1000.0f), + rotations(0.0, 0.0), + translations(0.0f, 0.0f, -5.0f), + rfactor(0.01f), + tfactor(0.001f), + sfactor(0.005f), + pos(0.0f, 0.0f, 1.0f), + pitch(0.0f), + yaw(0.0f) +{ +} + +Camera::~Camera() +{ +} + +void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt) +{ + mousePrev.x = x; + mousePrev.y = y; + if(shift) { + state = Camera::TRANSLATE; + } else if(ctrl) { + state = Camera::SCALE; + } else { + state = Camera::ROTATE; + } +} + +void Camera::mouseMoved(float x, float y) +{ + glm::vec2 mouseCurr(x, y); + glm::vec2 dv = mouseCurr - mousePrev; + switch(state) { + case Camera::ROTATE: + rotations += rfactor * dv; + if(rotations.y > 0.6) + { + rotations.y = 0.6; + } + else if(rotations.y < -0.6) + { + rotations.y = -0.6; + } + break; + case Camera::TRANSLATE: + translations.x -= translations.z * tfactor * dv.x; + translations.y += translations.z * tfactor * dv.y; + break; + case Camera::SCALE: + translations.z *= (1.0f - sfactor * dv.y); + break; + } + mousePrev = mouseCurr; +} + +void Camera::applyProjectionMatrix(std::shared_ptr P) const +{ + // Modify provided MatrixStack + P->multMatrix(glm::perspective(fovy, aspect, znear, zfar)); +} + +glm::vec3 Camera::getPos() +{ + return pos; +} + +void Camera::transpose(glm::vec3 t) +{ + glm::vec3 target(sin(rotations.x), 0, cos(rotations.x)); + pos -= (cross(glm::vec3(0, 1, 0), target))*t.x; + pos -= target*t.z; +} + +void Camera::applyViewMatrix(std::shared_ptr MV) const +{ + glm::vec3 target(sin(rotations.x), sin(rotations.y), cos(rotations.x)); + MV->multMatrix(glm::lookAt(pos, pos + target, glm::vec3(0,1,0))); +} diff --git a/A4/shadow8t4/shadow8t4/src/MyCamera.h b/A4/shadow8t4/shadow8t4/src/MyCamera.h new file mode 100644 index 0000000..7f31dbe --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/MyCamera.h @@ -0,0 +1,54 @@ +#pragma once +#ifndef __MyCamera__ +#define __MyCamera__ + +#include + +#define GLM_FORCE_RADIANS +#include + +class MatrixStack; + +class Camera +{ +public: + enum { + ROTATE = 0, + TRANSLATE, + SCALE + }; + + Camera(); + virtual ~Camera(); + void setInitDistance(float z) { translations.z = -std::abs(z); } + void setAspect(float a) { aspect = a; }; + void setRotationFactor(float f) { rfactor = f; }; + void setTranslationFactor(float f) { tfactor = f; }; + void setScaleFactor(float f) { sfactor = f; }; + void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt); + void mouseMoved(float x, float y); + void applyProjectionMatrix(std::shared_ptr P) const; + void applyViewMatrix(std::shared_ptr MV) const; + glm::vec3 getPos(); + void transpose(glm::vec3 t); + +private: + float aspect; + float fovy; + float znear; + float zfar; + glm::vec2 rotations; + glm::vec3 translations; + glm::vec2 mousePrev; + int state; + float rfactor; + float tfactor; + float sfactor; + + // TODO: Implement these + glm::vec3 pos; + float pitch; // Preliminarily making these floats + float yaw; // to hold angles. +}; + +#endif diff --git a/A4/shadow8t4/shadow8t4/src/Program.cpp b/A4/shadow8t4/shadow8t4/src/Program.cpp new file mode 100644 index 0000000..1e85538 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Program.cpp @@ -0,0 +1,126 @@ +#include "Program.h" + +#include +#include + +#include "GLSL.h" + +using namespace std; + +Program::Program() : + vShaderName(""), + fShaderName(""), + pid(0), + verbose(true) +{ + +} + +Program::~Program() +{ + +} + +void Program::setShaderNames(const string &v, const string &f) +{ + vShaderName = v; + fShaderName = f; +} + +bool Program::init() +{ + GLint rc; + + // Create shader handles + GLuint VS = glCreateShader(GL_VERTEX_SHADER); + GLuint FS = glCreateShader(GL_FRAGMENT_SHADER); + + // Read shader sources + const char *vshader = GLSL::textFileRead(vShaderName.c_str()); + const char *fshader = GLSL::textFileRead(fShaderName.c_str()); + glShaderSource(VS, 1, &vshader, NULL); + glShaderSource(FS, 1, &fshader, NULL); + + // Compile vertex shader + glCompileShader(VS); + glGetShaderiv(VS, GL_COMPILE_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printShaderInfoLog(VS); + cout << "Error compiling vertex shader " << vShaderName << endl; + } + return false; + } + + // Compile fragment shader + glCompileShader(FS); + glGetShaderiv(FS, GL_COMPILE_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printShaderInfoLog(FS); + cout << "Error compiling fragment shader " << fShaderName << endl; + } + return false; + } + + // Create the program and link + pid = glCreateProgram(); + glAttachShader(pid, VS); + glAttachShader(pid, FS); + glLinkProgram(pid); + glGetProgramiv(pid, GL_LINK_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printProgramInfoLog(pid); + cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl; + } + return false; + } + + GLSL::checkError(GET_FILE_LINE); + return true; +} + +void Program::bind() +{ + glUseProgram(pid); +} + +void Program::unbind() +{ + glUseProgram(0); +} + +void Program::addAttribute(const string &name) +{ + attributes[name] = glGetAttribLocation(pid, name.c_str()); +} + +void Program::addUniform(const string &name) +{ + uniforms[name] = glGetUniformLocation(pid, name.c_str()); +} + +GLint Program::getAttribute(const string &name) const +{ + map::const_iterator attribute = attributes.find(name.c_str()); + if(attribute == attributes.end()) { + if(isVerbose()) { + cout << name << " is not an attribute variable" << endl; + } + return -1; + } + return attribute->second; +} + +GLint Program::getUniform(const string &name) const +{ + map::const_iterator uniform = uniforms.find(name.c_str()); + if(uniform == uniforms.end()) { + if(isVerbose()) { + cout << name << " is not a uniform variable" << endl; + } + return -1; + } + return uniform->second; +} diff --git a/A4/shadow8t4/shadow8t4/src/Program.h b/A4/shadow8t4/shadow8t4/src/Program.h new file mode 100644 index 0000000..51e58bb --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Program.h @@ -0,0 +1,44 @@ +#pragma once +#ifndef __Program__ +#define __Program__ + +#include +#include + +#define GLEW_STATIC +#include + +/** + * An OpenGL Program (vertex and fragment shaders) + */ +class Program +{ +public: + Program(); + virtual ~Program(); + + void setVerbose(bool v) { verbose = v; } + bool isVerbose() const { return verbose; } + + void setShaderNames(const std::string &v, const std::string &f); + virtual bool init(); + virtual void bind(); + virtual void unbind(); + + void addAttribute(const std::string &name); + void addUniform(const std::string &name); + GLint getAttribute(const std::string &name) const; + GLint getUniform(const std::string &name) const; + +protected: + std::string vShaderName; + std::string fShaderName; + +private: + GLuint pid; + std::map attributes; + std::map uniforms; + bool verbose; +}; + +#endif diff --git a/A4/shadow8t4/shadow8t4/src/Shape.cpp b/A4/shadow8t4/shadow8t4/src/Shape.cpp new file mode 100644 index 0000000..426ef9c --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Shape.cpp @@ -0,0 +1,165 @@ +#include "Shape.h" +#include + +#include "GLSL.h" +#include "Program.h" + +#define GLM_FORCE_RADIANS +#include + +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" + +using namespace std; + +Shape::Shape() : + posBufID(0), + norBufID(0), + texBufID(0) +{ +} + +Shape::~Shape() +{ +} + +void Shape::loadMesh(const string &meshName) +{ + // Load geometry + tinyobj::attrib_t attrib; + std::vector shapes; + std::vector materials; + string errStr; + bool rc = tinyobj::LoadObj(&attrib, &shapes, &materials, &errStr, meshName.c_str()); + if(!rc) { + cerr << errStr << endl; + } else { + // Some OBJ files have different indices for vertex positions, normals, + // and texture coordinates. For example, a cube corner vertex may have + // three different normals. Here, we are going to duplicate all such + // vertices. + // Loop over shapes + for(size_t s = 0; s < shapes.size(); s++) { + // Loop over faces (polygons) + size_t index_offset = 0; + for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { + size_t fv = shapes[s].mesh.num_face_vertices[f]; + // Loop over vertices in the face. + for(size_t v = 0; v < fv; v++) { + // access to vertex + tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v]; + posBuf.push_back(attrib.vertices[3*idx.vertex_index+0]); + posBuf.push_back(attrib.vertices[3*idx.vertex_index+1]); + posBuf.push_back(attrib.vertices[3*idx.vertex_index+2]); + if(!attrib.normals.empty()) { + norBuf.push_back(attrib.normals[3*idx.normal_index+0]); + norBuf.push_back(attrib.normals[3*idx.normal_index+1]); + norBuf.push_back(attrib.normals[3*idx.normal_index+2]); + } + if(!attrib.texcoords.empty()) { + texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+0]); + texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+1]); + } + } + index_offset += fv; + // per-face material (IGNORE) + shapes[s].mesh.material_ids[f]; + } + } + } +} + +void Shape::fitToUnitBox() +{ + // Scale the vertex positions so that they fit within [-1, +1] in all three dimensions. + glm::vec3 vmin(posBuf[0], posBuf[1], posBuf[2]); + glm::vec3 vmax(posBuf[0], posBuf[1], posBuf[2]); + for(int i = 0; i < (int)posBuf.size(); i += 3) { + glm::vec3 v(posBuf[i], posBuf[i+1], posBuf[i+2]); + vmin.x = min(vmin.x, v.x); + vmin.y = min(vmin.y, v.y); + vmin.z = min(vmin.z, v.z); + vmax.x = max(vmax.x, v.x); + vmax.y = max(vmax.y, v.y); + vmax.z = max(vmax.z, v.z); + } + glm::vec3 center = 0.5f*(vmin + vmax); + glm::vec3 diff = vmax - vmin; + float diffmax = diff.x; + diffmax = max(diffmax, diff.y); + diffmax = max(diffmax, diff.z); + float scale = 1.0f / diffmax; + for(int i = 0; i < (int)posBuf.size(); i += 3) { + posBuf[i ] = (posBuf[i ] - center.x) * scale; + posBuf[i+1] = (posBuf[i+1] - center.y) * scale; + posBuf[i+2] = (posBuf[i+2] - center.z) * scale; + } +} + +void Shape::init() +{ + // Send the position array to the GPU + glGenBuffers(1, &posBufID); + glBindBuffer(GL_ARRAY_BUFFER, posBufID); + glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_STATIC_DRAW); + + // Send the normal array to the GPU + if(!norBuf.empty()) { + glGenBuffers(1, &norBufID); + glBindBuffer(GL_ARRAY_BUFFER, norBufID); + glBufferData(GL_ARRAY_BUFFER, norBuf.size()*sizeof(float), &norBuf[0], GL_STATIC_DRAW); + } + + // Send the texture array to the GPU + if(!texBuf.empty()) { + glGenBuffers(1, &texBufID); + glBindBuffer(GL_ARRAY_BUFFER, texBufID); + glBufferData(GL_ARRAY_BUFFER, texBuf.size()*sizeof(float), &texBuf[0], GL_STATIC_DRAW); + } + + // Unbind the arrays + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLSL::checkError(GET_FILE_LINE); +} + +void Shape::draw(const shared_ptr prog) const +{ + // Bind position buffer + int h_pos = prog->getAttribute("aPos"); + glEnableVertexAttribArray(h_pos); + glBindBuffer(GL_ARRAY_BUFFER, posBufID); + glVertexAttribPointer(h_pos, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0); + + // Bind normal buffer + int h_nor = prog->getAttribute("aNor"); + if(h_nor != -1 && norBufID != 0) { + glEnableVertexAttribArray(h_nor); + glBindBuffer(GL_ARRAY_BUFFER, norBufID); + glVertexAttribPointer(h_nor, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0); + } + + // Bind texcoords buffer + int h_tex = prog->getAttribute("aTex"); + if(h_tex != -1 && texBufID != 0) { + glEnableVertexAttribArray(h_tex); + glBindBuffer(GL_ARRAY_BUFFER, texBufID); + glVertexAttribPointer(h_tex, 2, GL_FLOAT, GL_FALSE, 0, (const void *)0); + } + + // Draw + int count = posBuf.size()/3; // number of indices to be rendered + glDrawArrays(GL_TRIANGLES, 0, count); + + // Disable and unbind + if(h_tex != -1) { + glDisableVertexAttribArray(h_tex); + } + if(h_nor != -1) { + glDisableVertexAttribArray(h_nor); + } + glDisableVertexAttribArray(h_pos); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLSL::checkError(GET_FILE_LINE); +} diff --git a/A4/shadow8t4/shadow8t4/src/Shape.h b/A4/shadow8t4/shadow8t4/src/Shape.h new file mode 100644 index 0000000..297476c --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/Shape.h @@ -0,0 +1,37 @@ +#pragma once +#ifndef _SHAPE_H_ +#define _SHAPE_H_ + +#include +#include +#include + +class Program; + +/** + * A shape defined by a list of triangles + * - posBuf should be of length 3*ntris + * - norBuf should be of length 3*ntris (if normals are available) + * - texBuf should be of length 2*ntris (if texture coords are available) + * posBufID, norBufID, and texBufID are OpenGL buffer identifiers. + */ +class Shape +{ +public: + Shape(); + virtual ~Shape(); + void loadMesh(const std::string &meshName); + void fitToUnitBox(); + void init(); + void draw(const std::shared_ptr prog) const; + +private: + std::vector posBuf; + std::vector norBuf; + std::vector texBuf; + unsigned posBufID; + unsigned norBufID; + unsigned texBufID; +}; + +#endif diff --git a/A4/shadow8t4/shadow8t4/src/main.cpp b/A4/shadow8t4/shadow8t4/src/main.cpp new file mode 100644 index 0000000..8e4fd56 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/main.cpp @@ -0,0 +1,462 @@ +#include +#include +#define _USE_MATH_DEFINES +#include +#include + +#define GLEW_STATIC +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +#include "MyCamera.h" +#include "GLSL.h" +#include "MatrixStack.h" +#include "Program.h" +#include "Shape.h" +#include "Material.h" +#include "Light.h" +#include "Component.h" + +using namespace std; + +GLFWwindow *window; // Main application window +string RESOURCE_DIR = "./"; // Where the resources are loaded from + +shared_ptr camera; +shared_ptr prog; +shared_ptr sprog; +shared_ptr shape; +shared_ptr sphere; +shared_ptr cube; +shared_ptr teapot; + +bool keyToggles[256] = {false}; // only for English keyboards! + +vector materials; +Light l[2]; +int ind = 0; +int lind = 0; +int sind = 0; + +unsigned int pid0; +unsigned int pid1; + +//Variables affecting the assortment of shapes. +unsigned int n = 10; +float s = 1.0; +float tx = 1.0; +float ty = 1.0; +float tz = 1.0; +vector shapes; + +// This function is called when a GLFW error occurs +static void error_callback(int error, const char *description) +{ + cerr << description << endl; +} + +// This function is called when a key is pressed +static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) +{ + if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GL_TRUE); + } +} + +// This function is called when the mouse is clicked +static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) +{ + // Get the current mouse position. + double xmouse, ymouse; + glfwGetCursorPos(window, &xmouse, &ymouse); + // Get current window size. + int width, height; + glfwGetWindowSize(window, &width, &height); + if(action == GLFW_PRESS) { + bool shift = (mods & GLFW_MOD_SHIFT) != 0; + bool ctrl = (mods & GLFW_MOD_CONTROL) != 0; + bool alt = (mods & GLFW_MOD_ALT) != 0; + camera->mouseClicked((float)xmouse, (float)ymouse, shift, ctrl, alt); + } +} + +// This function is called when the mouse moves +static void cursor_position_callback(GLFWwindow* window, double xmouse, double ymouse) +{ + int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); + if(state == GLFW_PRESS) { + camera->mouseMoved((float)xmouse, (float)ymouse); + } +} + +static void char_callback(GLFWwindow *window, unsigned int key) +{ + keyToggles[key] = !keyToggles[key]; + char cp = (char)key; + + if(cp == 'W' || cp == 'w') + { + vec3 temp(0.0f, 0.0f, -0.1f); + camera->transpose(temp); + } + if(cp == 'A' || cp == 'a') + { + vec3 temp(-0.1f, 0.0f, 0.0f); + camera->transpose(temp); + } + if(cp == 'S' || cp == 's') + { + vec3 temp(0.0f, 0.0f, 0.1f); + camera->transpose(temp); + } + if(cp == 'D' || cp == 'd') + { + vec3 temp(0.1f, 0.0f, 0.0f); + camera->transpose(temp); + } + if(cp == 'X') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x + 0.1f, temp.y, temp.z)); + } + if(cp == 'x') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x - 0.1f, temp.y, temp.z)); + } + + if(cp == 'Y') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x, temp.y + 0.1f, temp.z)); + } + if(cp == 'y') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x, temp.y - 0.1f, temp.z)); + } + + if(cp == 'Z') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x, temp.y, temp.z + 0.1f)); + } + if(cp == 'z') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x, temp.y, temp.z - 0.1f)); + } +} + +// If the window is resized, capture the new size and reset the viewport +static void resize_callback(GLFWwindow *window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void createComponents() +{ + for(unsigned int i = 0; i < n; i++) + { + Component temp; + + temp.s.x = s; + temp.s.y = s; + temp.s.z = s; + + temp.tp.x = 0; + temp.tp.y = 0; + temp.tp.z = -tz*((float)i); + + temp.t.x = 1.0/2.0; + temp.t.y = 0; + temp.t.z = -1.0/2.0; + + temp.sid = rand()%3; + + shapes.push_back(temp); + } +} + +static void createMaterials() +{ + Material m1; + + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + + materials[0].setMaterial(glm::vec3(0.0f, 0.0f, 0.4f), glm::vec3(0.2f, 0.1f, 0.7f), glm::vec3(0.5f, 0.5f, 0.5f), 200.0f); + materials[1].setMaterial(glm::vec3(0.3f, 0.3f, 0.4f), glm::vec3(0.2f, 0.2f, 0.3f), glm::vec3(0.1f, 0.1f, 0.1f), 10.0f); + materials[2].setMaterial(glm::vec3(0.2f, 0.2f, 0.2f), glm::vec3(0.8f, 0.7f, 0.7f), glm::vec3(1.0f, 0.9f, 0.8f), 200.0f); + materials[3].setMaterial(glm::vec3(0.2f, 0.8f, 0.2f), glm::vec3(0.1f, 0.7f, 0.2f), glm::vec3(0.2f, 0.2f, 0.2f), 100.0f); + materials[4].setMaterial(glm::vec3(0.8f, 0.2f, 0.2f), glm::vec3(0.7f, 0.1f, 0.1f), glm::vec3(0.3f, 0.3f, 0.3f), 100.0f); + materials[5].setMaterial(glm::vec3(0.7f, 0.7f, 0.1f), glm::vec3(0.6f, 0.5f, 0.2f), glm::vec3(0.1f, 0.1f, 0.1f), 50.0f); + materials[6].setMaterial(glm::vec3(0.5f, 0.1f, 0.1f), glm::vec3(0.7f, 0.1f, 0.1f), glm::vec3(0.2f, 0.2f, 0.2f), 50.0f); + materials[7].setMaterial(glm::vec3(0.2f, 0.8f, 0.8f), glm::vec3(0.1f, 0.7f, 0.6f), glm::vec3(0.5f, 0.5f, 0.5f), 120.0f); + materials[8].setMaterial(glm::vec3(0.3f, 0.6f, 0.3f), glm::vec3(0.3f, 0.6f, 0.3f), glm::vec3(0.7f, 0.7f, 0.7f), 20.0f); + materials[9].setMaterial(glm::vec3(0.8f, 0.2f, 0.7f), glm::vec3(0.7f, 0.2f, 0.8f), glm::vec3(0.5f, 0.5f, 0.5f), 200.0f); + materials[10].setMaterial(glm::vec3(0.2f, 0.5f, 0.2f), glm::vec3(0.2f, 0.5f, 0.2f), glm::vec3(0.5f, 0.5f, 0.5f), 10.0f); +} + +static void makeGround() +{ + Component temp; + + temp.tp.x = 0.0f; + temp.tp.y = -1.0f; + temp.tp.z = 0.0f; + + temp.s.x = 100.0f; + temp.s.y = 0.0f; + temp.s.z = 100.0f; + + temp.t.x = 0.0f; + temp.t.y = 0.0f; + temp.t.z = 0.0f; + + temp.sid = 2; + + shapes.push_back(temp); +} + +// This function is called once to initialize the scene and OpenGL +static void init() +{ + // Initialize time. + glfwSetTime(0.0); + + // Set background color. + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + // Enable z-buffer test. + glEnable(GL_DEPTH_TEST); + + sprog = make_shared(); + sprog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "sil.glsl"); + sprog->setVerbose(false); + sprog->init(); + sprog->addAttribute("aPos"); + sprog->addAttribute("aNor"); + sprog->addUniform("MV"); + sprog->addUniform("P"); + + prog = make_shared(); + prog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "frag.glsl"); + prog->setVerbose(false); + prog->init(); + prog->addAttribute("aPos"); + prog->addAttribute("aNor"); + prog->addUniform("MV"); + prog->addUniform("P"); + prog->addUniform("MVL"); + prog->addUniform("lightPos1"); + prog->addUniform("lightPos2"); + prog->addUniform("ka"); + prog->addUniform("kd"); + prog->addUniform("ks"); + prog->addUniform("s"); + prog->addUniform("i1"); + prog->addUniform("i2"); + + camera = make_shared(); + camera->setInitDistance(2.0f); + + shape = make_shared(); + shape->loadMesh(RESOURCE_DIR + "bunny.obj"); + shape->fitToUnitBox(); + shape->init(); + + sphere = make_shared(); + sphere->loadMesh(RESOURCE_DIR + "sphere.obj"); + sphere->fitToUnitBox(); + sphere->init(); + + cube = make_shared(); + cube->loadMesh(RESOURCE_DIR + "cube.obj"); + cube->fitToUnitBox(); + cube->init(); + + teapot = make_shared(); + teapot->loadMesh(RESOURCE_DIR + "teapot.obj"); + teapot->fitToUnitBox(); + teapot->init(); + + createMaterials(); + + Light l1(glm::vec3(1.0f, 1.0f, 1.0f), 0.8f); + Light l2(glm::vec3(-1.0f, 1.0f, 1.0f), 0.2f); + l[0] = l1; + l[1] = l2; + + // separate function to create shapes. + createComponents(); + + makeGround(); + + GLSL::checkError(GET_FILE_LINE); +} + +// This function is called every frame to draw the scene. +static void render() +{ + // Clear framebuffer. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if(keyToggles[(unsigned)'c']) { + glEnable(GL_CULL_FACE); + } else { + glDisable(GL_CULL_FACE); + } + // Get current frame buffer size. + int width, height; + glfwGetFramebufferSize(window, &width, &height); + camera->setAspect((float)width/(float)height); + + // Matrix stacks + auto P = make_shared(); + auto MV = make_shared(); + + // Apply camera transforms + P->pushMatrix(); + camera->applyProjectionMatrix(P); + MV->pushMatrix(); + camera->applyViewMatrix(MV); + + prog->bind(); + + mat4 templ; + templ[0] = vec4(1.0, 0, 0, 0); + templ[1] = vec4(0, 1.0, 0, 0); + templ[2] = vec4(0, 0, 1.0, 0); + templ[3] = vec4(l[0].getPos().x, l[0].getPos().y, l[0].getPos().z, 1.0); + templ = MV->topMatrix()*templ; + glUniformMatrix4fv(prog->getUniform("MVL"), 1, GL_FALSE, glm::value_ptr(templ)); + + Component light; + + light.t.x = l[0].getPos().x; + light.t.y = l[0].getPos().y; + light.t.z = l[0].getPos().z; + + glUniform3f(prog->getUniform("lightPos1"), l[0].getPos().x, l[0].getPos().y, l[0].getPos().z); + glUniform3f(prog->getUniform("ka"), 0.95, 1.0, 0.35); + glUniform3f(prog->getUniform("kd"), 1.0, 1.0, 1.0); + glUniform3f(prog->getUniform("ks"), 1.0, 1.0, 1.0); + glUniform1f(prog->getUniform("s"), 1.0); + + light.draw(MV, P, sphere, prog); + prog->unbind(); + + glm::vec3 ambient = materials.at(0).getAmbient(); + glm::vec3 diffuse = materials.at(0).getDiffuse(); + glm::vec3 specular = materials.at(0).getSpecular(); + float shine = materials.at(0).getShiny(); + for(unsigned int i = 0; i < n + 1; i++) + { + prog->bind(); + ambient = materials.at(i).getAmbient(); + diffuse = materials.at(i).getDiffuse(); + specular = materials.at(i).getSpecular(); + shine = materials.at(i).getShiny(); + + glUniform3f(prog->getUniform("ka"), ambient.r, ambient.g, ambient.b); + glUniform3f(prog->getUniform("kd"), diffuse.r, diffuse.g, diffuse.b); + glUniform3f(prog->getUniform("ks"), specular.r, specular.g, specular.b); + glUniform1f(prog->getUniform("s"), shine); + glUniform1f(prog->getUniform("i1"), l[0].getIntensity()); + glUniform1f(prog->getUniform("i2"), l[1].getIntensity()); + + switch(shapes.at(i).sid) + { + case 0: + shapes.at(i).draw(MV, P, shape, prog); + break; + case 1: + shapes.at(i).draw(MV, P, teapot, prog); + break; + case 2: + shapes.at(i).draw(MV, P, cube, prog); + break; + default: + shapes.at(i).draw(MV, P, shape, prog); + break; + }; + prog->unbind(); + } + MV->popMatrix(); + P->popMatrix(); + + GLSL::checkError(GET_FILE_LINE); +} + +int main(int argc, char **argv) +{ + if(argc < 2) { + cout << "Please specify the resource directory." << endl; + return 0; + } + RESOURCE_DIR = argv[1] + string("/"); + + // Set error callback. + glfwSetErrorCallback(error_callback); + // Initialize the library. + if(!glfwInit()) { + return -1; + } + // Create a windowed mode window and its OpenGL context. + window = glfwCreateWindow(640, 480, "Alex Huddleston Assignment 4", NULL, NULL); + if(!window) { + glfwTerminate(); + return -1; + } + // Make the window's context current. + glfwMakeContextCurrent(window); + // Initialize GLEW. + glewExperimental = true; + if(glewInit() != GLEW_OK) { + cerr << "Failed to initialize GLEW" << endl; + return -1; + } + glGetError(); // A bug in glewInit() causes an error that we can safely ignore. + cout << "OpenGL version: " << glGetString(GL_VERSION) << endl; + cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl; + GLSL::checkVersion(); + // Set vsync. + glfwSwapInterval(1); + // Set keyboard callback. + glfwSetKeyCallback(window, key_callback); + // Set char callback. + glfwSetCharCallback(window, char_callback); + // Set cursor position callback. + glfwSetCursorPosCallback(window, cursor_position_callback); + // Set mouse button callback. + glfwSetMouseButtonCallback(window, mouse_button_callback); + // Set the window resize call back. + glfwSetFramebufferSizeCallback(window, resize_callback); + // Initialize scene. + init(); + // Loop until the user closes the window. + while(!glfwWindowShouldClose(window)) { + // Render scene. + render(); + // Swap front and back buffers. + glfwSwapBuffers(window); + // Poll for and process events. + glfwPollEvents(); + } + // Quit program. + glfwDestroyWindow(window); + glfwTerminate(); + return 0; +} diff --git a/A4/shadow8t4/shadow8t4/src/tiny_obj_loader.h b/A4/shadow8t4/shadow8t4/src/tiny_obj_loader.h new file mode 100644 index 0000000..b975601 --- /dev/null +++ b/A4/shadow8t4/shadow8t4/src/tiny_obj_loader.h @@ -0,0 +1,1922 @@ +/* +The MIT License (MIT) + +Copyright (c) 2012-2016 Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// +// version 1.0.3 : Support parsing texture options(#85) +// version 1.0.2 : Improve parsing speed by about a factor of 2 for large +// files(#105) +// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104) +// version 1.0.0 : Change data structure. Change license from BSD to MIT. +// + +// +// Use this in *one* .cc +// #define TINYOBJLOADER_IMPLEMENTATION +// #include "tiny_obj_loader.h" +// + +#ifndef TINY_OBJ_LOADER_H_ +#define TINY_OBJ_LOADER_H_ + +#include +#include +#include + +namespace tinyobj { + +// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ... +// +// -blendu on | off # set horizontal texture blending +// (default on) +// -blendv on | off # set vertical texture blending +// (default on) +// -boost float_value # boost mip-map sharpness +// -mm base_value gain_value # modify texture map values (default +// 0 1) +// # base_value = brightness, +// gain_value = contrast +// -o u [v [w]] # Origin offset (default +// 0 0 0) +// -s u [v [w]] # Scale (default +// 1 1 1) +// -t u [v [w]] # Turbulence (default +// 0 0 0) +// -texres resolution # texture resolution to create +// -clamp on | off # only render texels in the clamped +// 0-1 range (default off) +// # When unclamped, textures are +// repeated across a surface, +// # when clamped, only texels which +// fall within the 0-1 +// # range are rendered. +// -bm mult_value # bump multiplier (for bump maps +// only) +// +// -imfchan r | g | b | m | l | z # specifies which channel of the file +// is used to +// # create a scalar or bump texture. +// r:red, g:green, +// # b:blue, m:matte, l:luminance, +// z:z-depth.. +// # (the default for bump is 'l' and +// for decal is 'm') +// bump -imfchan r bumpmap.tga # says to use the red channel of +// bumpmap.tga as the bumpmap +// +// For reflection maps... +// +// -type sphere # specifies a sphere for a "refl" +// reflection map +// -type cube_top | cube_bottom | # when using a cube map, the texture +// file for each +// cube_front | cube_back | # side of the cube is specified +// separately +// cube_left | cube_right + +typedef enum { + TEXTURE_TYPE_NONE, // default + TEXTURE_TYPE_SPHERE, + TEXTURE_TYPE_CUBE_TOP, + TEXTURE_TYPE_CUBE_BOTTOM, + TEXTURE_TYPE_CUBE_FRONT, + TEXTURE_TYPE_CUBE_BACK, + TEXTURE_TYPE_CUBE_LEFT, + TEXTURE_TYPE_CUBE_RIGHT +} texture_type_t; + +typedef struct { + texture_type_t type; // -type (default TEXTURE_TYPE_NONE) + float sharpness; // -boost (default 1.0?) + float brightness; // base_value in -mm option (default 0) + float contrast; // gain_value in -mm option (default 1) + float origin_offset[3]; // -o u [v [w]] (default 0 0 0) + float scale[3]; // -s u [v [w]] (default 1 1 1) + float turbulence[3]; // -t u [v [w]] (default 0 0 0) + // int texture_resolution; // -texres resolution (default = ?) TODO + bool clamp; // -clamp (default false) + char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm') + bool blendu; // -blendu (default on) + bool blendv; // -blendv (default on) + float bump_multiplier; // -bm (for bump maps only, default 1.0) +} texture_option_t; + +typedef struct { + std::string name; + + float ambient[3]; + float diffuse[3]; + float specular[3]; + float transmittance[3]; + float emission[3]; + float shininess; + float ior; // index of refraction + float dissolve; // 1 == opaque; 0 == fully transparent + // illumination model (see http://www.fileformat.info/format/material/) + int illum; + + int dummy; // Suppress padding warning. + + std::string ambient_texname; // map_Ka + std::string diffuse_texname; // map_Kd + std::string specular_texname; // map_Ks + std::string specular_highlight_texname; // map_Ns + std::string bump_texname; // map_bump, bump + std::string displacement_texname; // disp + std::string alpha_texname; // map_d + + texture_option_t ambient_texopt; + texture_option_t diffuse_texopt; + texture_option_t specular_texopt; + texture_option_t specular_highlight_texopt; + texture_option_t bump_texopt; + texture_option_t displacement_texopt; + texture_option_t alpha_texopt; + + // PBR extension + // http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr + float roughness; // [0, 1] default 0 + float metallic; // [0, 1] default 0 + float sheen; // [0, 1] default 0 + float clearcoat_thickness; // [0, 1] default 0 + float clearcoat_roughness; // [0, 1] default 0 + float anisotropy; // aniso. [0, 1] default 0 + float anisotropy_rotation; // anisor. [0, 1] default 0 + float pad0; + float pad1; + std::string roughness_texname; // map_Pr + std::string metallic_texname; // map_Pm + std::string sheen_texname; // map_Ps + std::string emissive_texname; // map_Ke + std::string normal_texname; // norm. For normal mapping. + + texture_option_t roughness_texopt; + texture_option_t metallic_texopt; + texture_option_t sheen_texopt; + texture_option_t emissive_texopt; + texture_option_t normal_texopt; + + int pad2; + + std::map unknown_parameter; +} material_t; + +typedef struct { + std::string name; + + std::vector intValues; + std::vector floatValues; + std::vector stringValues; +} tag_t; + +// Index struct to support different indices for vtx/normal/texcoord. +// -1 means not used. +typedef struct { + int vertex_index; + int normal_index; + int texcoord_index; +} index_t; + +typedef struct { + std::vector indices; + std::vector num_face_vertices; // The number of vertices per + // face. 3 = polygon, 4 = quad, + // ... Up to 255. + std::vector material_ids; // per-face material ID + std::vector tags; // SubD tag +} mesh_t; + +typedef struct { + std::string name; + mesh_t mesh; +} shape_t; + +// Vertex attributes +typedef struct { + std::vector vertices; // 'v' + std::vector normals; // 'vn' + std::vector texcoords; // 'vt' +} attrib_t; + +typedef struct callback_t_ { + // W is optional and set to 1 if there is no `w` item in `v` line + void (*vertex_cb)(void *user_data, float x, float y, float z, float w); + void (*normal_cb)(void *user_data, float x, float y, float z); + + // y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in + // `vt` line. + void (*texcoord_cb)(void *user_data, float x, float y, float z); + + // called per 'f' line. num_indices is the number of face indices(e.g. 3 for + // triangle, 4 for quad) + // 0 will be passed for undefined index in index_t members. + void (*index_cb)(void *user_data, index_t *indices, int num_indices); + // `name` material name, `material_id` = the array index of material_t[]. -1 + // if + // a material not found in .mtl + void (*usemtl_cb)(void *user_data, const char *name, int material_id); + // `materials` = parsed material data. + void (*mtllib_cb)(void *user_data, const material_t *materials, + int num_materials); + // There may be multiple group names + void (*group_cb)(void *user_data, const char **names, int num_names); + void (*object_cb)(void *user_data, const char *name); + + callback_t_() + : vertex_cb(NULL), + normal_cb(NULL), + texcoord_cb(NULL), + index_cb(NULL), + usemtl_cb(NULL), + mtllib_cb(NULL), + group_cb(NULL), + object_cb(NULL) {} +} callback_t; + +class MaterialReader { + public: + MaterialReader() {} + virtual ~MaterialReader(); + + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) = 0; +}; + +class MaterialFileReader : public MaterialReader { + public: + explicit MaterialFileReader(const std::string &mtl_basedir) + : m_mtlBaseDir(mtl_basedir) {} + virtual ~MaterialFileReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *err); + + private: + std::string m_mtlBaseDir; +}; + +class MaterialStreamReader : public MaterialReader { + public: + explicit MaterialStreamReader(std::istream &inStream) + : m_inStream(inStream) {} + virtual ~MaterialStreamReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *err); + + private: + std::istream &m_inStream; +}; + +/// Loads .obj from a file. +/// 'attrib', 'shapes' and 'materials' will be filled with parsed shape data +/// 'shapes' will be filled with parsed shape data +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +/// 'mtl_basedir' is optional, and used for base directory for .mtl file. +/// In default(`NULL'), .mtl file is searched from an application's working directory. +/// 'triangulate' is optional, and used whether triangulate polygon face in .obj +/// or not. +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + const char *filename, const char *mtl_basedir = NULL, + bool triangulate = true); + +/// Loads .obj from a file with custom user callback. +/// .mtl is loaded as usual and parsed material_t data will be passed to +/// `callback.mtllib_cb`. +/// Returns true when loading .obj/.mtl become success. +/// Returns warning and error message into `err` +/// See `examples/callback_api/` for how to use this function. +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data = NULL, + MaterialReader *readMatFn = NULL, + std::string *err = NULL); + +/// Loads object from a std::istream, uses GetMtlIStreamFn to retrieve +/// std::istream for materials. +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + std::istream *inStream, MaterialReader *readMatFn = NULL, + bool triangulate = true); + +/// Loads materials into std::map +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream); + +} // namespace tinyobj + +#ifdef TINYOBJLOADER_IMPLEMENTATION +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace tinyobj { + +MaterialReader::~MaterialReader() {} + +#define TINYOBJ_SSCANF_BUFFER_SIZE (4096) + +struct vertex_index { + int v_idx, vt_idx, vn_idx; + vertex_index() : v_idx(-1), vt_idx(-1), vn_idx(-1) {} + explicit vertex_index(int idx) : v_idx(idx), vt_idx(idx), vn_idx(idx) {} + vertex_index(int vidx, int vtidx, int vnidx) + : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {} +}; + +struct tag_sizes { + tag_sizes() : num_ints(0), num_floats(0), num_strings(0) {} + int num_ints; + int num_floats; + int num_strings; +}; + +struct obj_shape { + std::vector v; + std::vector vn; + std::vector vt; +}; + +// See +// http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf +static std::istream &safeGetline(std::istream &is, std::string &t) { + t.clear(); + + // The characters in the stream are read one-by-one using a std::streambuf. + // That is faster than reading them one-by-one using the std::istream. + // Code that uses streambuf this way must be guarded by a sentry object. + // The sentry object performs various tasks, + // such as thread synchronization and updating the stream state. + + std::istream::sentry se(is, true); + std::streambuf *sb = is.rdbuf(); + + for (;;) { + int c = sb->sbumpc(); + switch (c) { + case '\n': + return is; + case '\r': + if (sb->sgetc() == '\n') sb->sbumpc(); + return is; + case EOF: + // Also handle the case when the last line has no line ending + if (t.empty()) is.setstate(std::ios::eofbit); + return is; + default: + t += static_cast(c); + } + } +} + +#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t')) +#define IS_DIGIT(x) \ + (static_cast((x) - '0') < static_cast(10)) +#define IS_NEW_LINE(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0')) + +// Make index zero-base, and also support relative index. +static inline int fixIndex(int idx, int n) { + if (idx > 0) return idx - 1; + if (idx == 0) return 0; + return n + idx; // negative value = relative +} + +static inline std::string parseString(const char **token) { + std::string s; + (*token) += strspn((*token), " \t"); + size_t e = strcspn((*token), " \t\r"); + s = std::string((*token), &(*token)[e]); + (*token) += e; + return s; +} + +static inline int parseInt(const char **token) { + (*token) += strspn((*token), " \t"); + int i = atoi((*token)); + (*token) += strcspn((*token), " \t\r"); + return i; +} + +// Tries to parse a floating point number located at s. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// Parses the following EBNF grammar: +// sign = "+" | "-" ; +// END = ? anything not in digit ? +// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +// integer = [sign] , digit , {digit} ; +// decimal = integer , ["." , integer] ; +// float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ; +// +// Valid strings are for example: +// -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2 +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +// The function is greedy and will parse until any of the following happens: +// - a non-conforming character is encountered. +// - s_end is reached. +// +// The following situations triggers a failure: +// - s >= s_end. +// - parse failure. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (s >= s_end) { + return false; + } + + double mantissa = 0.0; + // This exponent is base 2 rather than 10. + // However the exponent we parse is supposed to be one of ten, + // thus we must take care to convert the exponent/and or the + // mantissa to a * 2^E, where a is the mantissa and E is the + // exponent. + // To get the final double we will use ldexp, it requires the + // exponent to be in base 2. + int exponent = 0; + + // NOTE: THESE MUST BE DECLARED HERE SINCE WE ARE NOT ALLOWED + // TO JUMP OVER DEFINITIONS. + char sign = '+'; + char exp_sign = '+'; + char const *curr = s; + + // How many characters were read in a loop. + int read = 0; + // Tells whether a loop terminated due to reaching s_end. + bool end_not_reached = false; + + /* + BEGIN PARSING. + */ + + // Find out what sign we've got. + if (*curr == '+' || *curr == '-') { + sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + goto fail; + } + + // Read the integer part. + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + mantissa *= 10; + mantissa += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + + // We must make sure we actually got something. + if (read == 0) goto fail; + // We allow numbers of form "#", "###" etc. + if (!end_not_reached) goto assemble; + + // Read the decimal part. + if (*curr == '.') { + curr++; + read = 1; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + static const double pow_lut[] = { + 1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, + }; + const int lut_entries = sizeof pow_lut / sizeof pow_lut[0]; + + // NOTE: Don't use powf here, it will absolutely murder precision. + mantissa += static_cast(*curr - 0x30) * + (read < lut_entries ? pow_lut[read] : pow(10.0, -read)); + read++; + curr++; + end_not_reached = (curr != s_end); + } + } else if (*curr == 'e' || *curr == 'E') { + } else { + goto assemble; + } + + if (!end_not_reached) goto assemble; + + // Read the exponent part. + if (*curr == 'e' || *curr == 'E') { + curr++; + // Figure out if a sign is present and if it is. + end_not_reached = (curr != s_end); + if (end_not_reached && (*curr == '+' || *curr == '-')) { + exp_sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + // Empty E is not allowed. + goto fail; + } + + read = 0; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + exponent *= 10; + exponent += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + exponent *= (exp_sign == '+' ? 1 : -1); + if (read == 0) goto fail; + } + +assemble: + *result = + (sign == '+' ? 1 : -1) * + (exponent ? ldexp(mantissa * pow(5.0, exponent), exponent) : mantissa); + return true; +fail: + return false; +} + +static inline float parseFloat(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + float f = static_cast(val); + (*token) = end; + return f; +} + +static inline void parseFloat2(float *x, float *y, const char **token, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = parseFloat(token, default_x); + (*y) = parseFloat(token, default_y); +} + +static inline void parseFloat3(float *x, float *y, float *z, const char **token, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseFloat(token, default_x); + (*y) = parseFloat(token, default_y); + (*z) = parseFloat(token, default_z); +} + +static inline void parseV(float *x, float *y, float *z, float *w, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0, + const double default_w = 1.0) { + (*x) = parseFloat(token, default_x); + (*y) = parseFloat(token, default_y); + (*z) = parseFloat(token, default_z); + (*w) = parseFloat(token, default_w); +} + +static inline bool parseOnOff(const char **token, bool default_value = true) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + + bool ret = default_value; + if ((0 == strncmp((*token), "on", 2))) { + ret = true; + } else if ((0 == strncmp((*token), "off", 3))) { + ret = false; + } + + (*token) = end; + return ret; +} + +static inline texture_type_t parseTextureType( + const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + texture_type_t ty = default_value; + + if ((0 == strncmp((*token), "cube_top", strlen("cube_top")))) { + ty = TEXTURE_TYPE_CUBE_TOP; + } else if ((0 == strncmp((*token), "cube_bottom", strlen("cube_bottom")))) { + ty = TEXTURE_TYPE_CUBE_BOTTOM; + } else if ((0 == strncmp((*token), "cube_left", strlen("cube_left")))) { + ty = TEXTURE_TYPE_CUBE_LEFT; + } else if ((0 == strncmp((*token), "cube_right", strlen("cube_right")))) { + ty = TEXTURE_TYPE_CUBE_RIGHT; + } else if ((0 == strncmp((*token), "cube_front", strlen("cube_front")))) { + ty = TEXTURE_TYPE_CUBE_FRONT; + } else if ((0 == strncmp((*token), "cube_back", strlen("cube_back")))) { + ty = TEXTURE_TYPE_CUBE_BACK; + } else if ((0 == strncmp((*token), "sphere", strlen("sphere")))) { + ty = TEXTURE_TYPE_SPHERE; + } + + (*token) = end; + return ty; +} + +static tag_sizes parseTagTriple(const char **token) { + tag_sizes ts; + + ts.num_ints = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; + + ts.num_floats = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; + + ts.num_strings = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r") + 1; + + return ts; +} + +// Parse triples with index offsets: i, i/j/k, i//k, i/j +static vertex_index parseTriple(const char **token, int vsize, int vnsize, + int vtsize) { + vertex_index vi(-1); + + vi.v_idx = fixIndex(atoi((*token)), vsize); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = fixIndex(atoi((*token)), vnsize); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = fixIndex(atoi((*token)), vtsize); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = fixIndex(atoi((*token)), vnsize); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +// Parse raw triples: i, i/j/k, i//k, i/j +static vertex_index parseRawTriple(const char **token) { + vertex_index vi(static_cast(0)); // 0 is an invalid index in OBJ + + vi.v_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +static bool ParseTextureNameAndOption(std::string *texname, + texture_option_t *texopt, + const char *linebuf, const bool is_bump) { + // @todo { write more robust lexer and parser. } + bool found_texname = false; + std::string texture_name; + + // Fill with default value for texopt. + if (is_bump) { + texopt->imfchan = 'l'; + } else { + texopt->imfchan = 'm'; + } + texopt->bump_multiplier = 1.0f; + texopt->clamp = false; + texopt->blendu = true; + texopt->blendv = true; + texopt->sharpness = 1.0f; + texopt->brightness = 0.0f; + texopt->contrast = 1.0f; + texopt->origin_offset[0] = 0.0f; + texopt->origin_offset[1] = 0.0f; + texopt->origin_offset[2] = 0.0f; + texopt->scale[0] = 1.0f; + texopt->scale[1] = 1.0f; + texopt->scale[2] = 1.0f; + texopt->turbulence[0] = 0.0f; + texopt->turbulence[1] = 0.0f; + texopt->turbulence[2] = 0.0f; + texopt->type = TEXTURE_TYPE_NONE; + + const char *token = linebuf; // Assume line ends with NULL + + while (!IS_NEW_LINE((*token))) { + if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendu = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendv = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->clamp = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->sharpness = parseFloat(&token, 1.0); + } else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) { + token += 4; + texopt->bump_multiplier = parseFloat(&token, 1.0); + } else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseFloat3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]), + &(texopt->origin_offset[2]), &token); + } else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseFloat3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]), + &token, 1.0, 1.0, 1.0); + } else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseFloat3(&(texopt->turbulence[0]), &(texopt->turbulence[1]), + &(texopt->turbulence[2]), &token); + } else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) { + token += 5; + texopt->type = parseTextureType((&token), TEXTURE_TYPE_NONE); + } else if ((0 == strncmp(token, "-imfchan", 8)) && IS_SPACE((token[8]))) { + token += 9; + token += strspn(token, " \t"); + const char *end = token + strcspn(token, " \t\r"); + if ((end - token) == 1) { // Assume one char for -imfchan + texopt->imfchan = (*token); + } + token = end; + } else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) { + token += 4; + parseFloat2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0); + } else { + // Assume texture filename + token += strspn(token, " \t"); // skip space + size_t len = strcspn(token, " \t\r"); // untile next space + texture_name = std::string(token, token + len); + token += len; + + token += strspn(token, " \t"); // skip space + + found_texname = true; + } + } + + if (found_texname) { + (*texname) = texture_name; + return true; + } else { + return false; + } +} + +static void InitMaterial(material_t *material) { + material->name = ""; + material->ambient_texname = ""; + material->diffuse_texname = ""; + material->specular_texname = ""; + material->specular_highlight_texname = ""; + material->bump_texname = ""; + material->displacement_texname = ""; + material->alpha_texname = ""; + for (int i = 0; i < 3; i++) { + material->ambient[i] = 0.f; + material->diffuse[i] = 0.f; + material->specular[i] = 0.f; + material->transmittance[i] = 0.f; + material->emission[i] = 0.f; + } + material->illum = 0; + material->dissolve = 1.f; + material->shininess = 1.f; + material->ior = 1.f; + + material->roughness = 0.f; + material->metallic = 0.f; + material->sheen = 0.f; + material->clearcoat_thickness = 0.f; + material->clearcoat_roughness = 0.f; + material->anisotropy_rotation = 0.f; + material->anisotropy = 0.f; + material->roughness_texname = ""; + material->metallic_texname = ""; + material->sheen_texname = ""; + material->emissive_texname = ""; + material->normal_texname = ""; + + material->unknown_parameter.clear(); +} + +static bool exportFaceGroupToShape( + shape_t *shape, const std::vector > &faceGroup, + const std::vector &tags, const int material_id, + const std::string &name, bool triangulate) { + if (faceGroup.empty()) { + return false; + } + + // Flatten vertices and indices + for (size_t i = 0; i < faceGroup.size(); i++) { + const std::vector &face = faceGroup[i]; + + vertex_index i0 = face[0]; + vertex_index i1(-1); + vertex_index i2 = face[1]; + + size_t npolys = face.size(); + + if (triangulate) { + // Polygon -> triangle fan conversion + for (size_t k = 2; k < npolys; k++) { + i1 = i2; + i2 = face[k]; + + index_t idx0, idx1, idx2; + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + } + } else { + for (size_t k = 0; k < npolys; k++) { + index_t idx; + idx.vertex_index = face[k].v_idx; + idx.normal_index = face[k].vn_idx; + idx.texcoord_index = face[k].vt_idx; + shape->mesh.indices.push_back(idx); + } + + shape->mesh.num_face_vertices.push_back( + static_cast(npolys)); + shape->mesh.material_ids.push_back(material_id); // per face + } + } + + shape->name = name; + shape->mesh.tags = tags; + + return true; +} + +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream) { + // Create a default material anyway. + material_t material; + InitMaterial(&material); + + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + // Trim trailing whitespace. + if (linebuf.size() > 0) { + linebuf = linebuf.substr(0, linebuf.find_last_not_of(" \t") + 1); + } + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // new mtl + if ((0 == strncmp(token, "newmtl", 6)) && IS_SPACE((token[6]))) { + // flush previous material. + if (!material.name.empty()) { + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + } + + // initial temporary material + InitMaterial(&material); + + // set new mtl name + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + material.name = namebuf; + continue; + } + + // ambient + if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.ambient[0] = r; + material.ambient[1] = g; + material.ambient[2] = b; + continue; + } + + // diffuse + if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.diffuse[0] = r; + material.diffuse[1] = g; + material.diffuse[2] = b; + continue; + } + + // specular + if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.specular[0] = r; + material.specular[1] = g; + material.specular[2] = b; + continue; + } + + // transmittance + if ((token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) || + (token[0] == 'T' && token[1] == 'f' && IS_SPACE((token[2])))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.transmittance[0] = r; + material.transmittance[1] = g; + material.transmittance[2] = b; + continue; + } + + // ior(index of refraction) + if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) { + token += 2; + material.ior = parseFloat(&token); + continue; + } + + // emission + if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.emission[0] = r; + material.emission[1] = g; + material.emission[2] = b; + continue; + } + + // shininess + if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.shininess = parseFloat(&token); + continue; + } + + // illum model + if (0 == strncmp(token, "illum", 5) && IS_SPACE(token[5])) { + token += 6; + material.illum = parseInt(&token); + continue; + } + + // dissolve + if ((token[0] == 'd' && IS_SPACE(token[1]))) { + token += 1; + material.dissolve = parseFloat(&token); + continue; + } + if (token[0] == 'T' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + // Invert value of Tr(assume Tr is in range [0, 1]) + material.dissolve = 1.0f - parseFloat(&token); + continue; + } + + // PBR: roughness + if (token[0] == 'P' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + material.roughness = parseFloat(&token); + continue; + } + + // PBR: metallic + if (token[0] == 'P' && token[1] == 'm' && IS_SPACE(token[2])) { + token += 2; + material.metallic = parseFloat(&token); + continue; + } + + // PBR: sheen + if (token[0] == 'P' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.sheen = parseFloat(&token); + continue; + } + + // PBR: clearcoat thickness + if (token[0] == 'P' && token[1] == 'c' && IS_SPACE(token[2])) { + token += 2; + material.clearcoat_thickness = parseFloat(&token); + continue; + } + + // PBR: clearcoat roughness + if ((0 == strncmp(token, "Pcr", 3)) && IS_SPACE(token[3])) { + token += 4; + material.clearcoat_roughness = parseFloat(&token); + continue; + } + + // PBR: anisotropy + if ((0 == strncmp(token, "aniso", 5)) && IS_SPACE(token[5])) { + token += 6; + material.anisotropy = parseFloat(&token); + continue; + } + + // PBR: anisotropy rotation + if ((0 == strncmp(token, "anisor", 6)) && IS_SPACE(token[6])) { + token += 7; + material.anisotropy_rotation = parseFloat(&token); + continue; + } + + // ambient texture + if ((0 == strncmp(token, "map_Ka", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.ambient_texname), + &(material.ambient_texopt), token, + /* is_bump */ false); + continue; + } + + // diffuse texture + if ((0 == strncmp(token, "map_Kd", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.diffuse_texname), + &(material.diffuse_texopt), token, + /* is_bump */ false); + continue; + } + + // specular texture + if ((0 == strncmp(token, "map_Ks", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_texname), + &(material.specular_texopt), token, + /* is_bump */ false); + continue; + } + + // specular highlight texture + if ((0 == strncmp(token, "map_Ns", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_highlight_texname), + &(material.specular_highlight_texopt), token, + /* is_bump */ false); + continue; + } + + // bump texture + if ((0 == strncmp(token, "map_bump", 8)) && IS_SPACE(token[8])) { + token += 9; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // bump texture + if ((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // alpha texture + if ((0 == strncmp(token, "map_d", 5)) && IS_SPACE(token[5])) { + token += 6; + material.alpha_texname = token; + ParseTextureNameAndOption(&(material.alpha_texname), + &(material.alpha_texopt), token, + /* is_bump */ false); + continue; + } + + // displacement texture + if ((0 == strncmp(token, "disp", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: roughness texture + if ((0 == strncmp(token, "map_Pr", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.roughness_texname), + &(material.roughness_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: metallic texture + if ((0 == strncmp(token, "map_Pm", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.metallic_texname), + &(material.metallic_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: sheen texture + if ((0 == strncmp(token, "map_Ps", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.sheen_texname), + &(material.sheen_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: emissive texture + if ((0 == strncmp(token, "map_Ke", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.emissive_texname), + &(material.emissive_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: normal map texture + if ((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption( + &(material.normal_texname), &(material.normal_texopt), token, + /* is_bump */ false); // @fixme { is_bump will be true? } + continue; + } + + // unknown parameter + const char *_space = strchr(token, ' '); + if (!_space) { + _space = strchr(token, '\t'); + } + if (_space) { + std::ptrdiff_t len = _space - token; + std::string key(token, static_cast(len)); + std::string value = _space + 1; + material.unknown_parameter.insert( + std::pair(key, value)); + } + } + // flush last material. + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); +} + +bool MaterialFileReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) { + std::string filepath; + + if (!m_mtlBaseDir.empty()) { + filepath = std::string(m_mtlBaseDir) + matId; + } else { + filepath = matId; + } + + std::ifstream matIStream(filepath.c_str()); + LoadMtl(matMap, materials, &matIStream); + if (!matIStream) { + std::stringstream ss; + ss << "WARN: Material file [ " << filepath + << " ] not found. Created a default material."; + if (err) { + (*err) += ss.str(); + } + } + return true; +} + +bool MaterialStreamReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) { + (void)matId; + LoadMtl(matMap, materials, &m_inStream); + if (!m_inStream) { + std::stringstream ss; + ss << "WARN: Material stream in error state." + << " Created a default material."; + if (err) { + (*err) += ss.str(); + } + } + return true; +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + const char *filename, const char *mtl_basedir, + bool trianglulate) { + attrib->vertices.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + shapes->clear(); + + std::stringstream errss; + + std::ifstream ifs(filename); + if (!ifs) { + errss << "Cannot open file [" << filename << "]" << std::endl; + if (err) { + (*err) = errss.str(); + } + return false; + } + + std::string baseDir; + if (mtl_basedir) { + baseDir = mtl_basedir; + } + MaterialFileReader matFileReader(baseDir); + + return LoadObj(attrib, shapes, materials, err, &ifs, &matFileReader, + trianglulate); +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + std::istream *inStream, MaterialReader *readMatFn /*= NULL*/, + bool triangulate) { + std::stringstream errss; + + std::vector v; + std::vector vn; + std::vector vt; + std::vector tags; + std::vector > faceGroup; + std::string name; + + // material + std::map material_map; + int material = -1; + + shape_t shape; + + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + float x, y, z; + parseFloat3(&x, &y, &z, &token); + v.push_back(x); + v.push_back(y); + v.push_back(z); + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + float x, y, z; + parseFloat3(&x, &y, &z, &token); + vn.push_back(x); + vn.push_back(y); + vn.push_back(z); + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + float x, y; + parseFloat2(&x, &y, &token); + vt.push_back(x); + vt.push_back(y); + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + std::vector face; + face.reserve(3); + + while (!IS_NEW_LINE(token[0])) { + vertex_index vi = parseTriple(&token, static_cast(v.size() / 3), + static_cast(vn.size() / 3), + static_cast(vt.size() / 2)); + face.push_back(vi); + size_t n = strspn(token, " \t\r"); + token += n; + } + + // replace with emplace_back + std::move on C++11 + faceGroup.push_back(std::vector()); + faceGroup[faceGroup.size() - 1].swap(face); + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material) { + // Create per-face material. Thus we don't add `shape` to `shapes` at + // this time. + // just clear `faceGroup` after `exportFaceGroupToShape()` call. + exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + faceGroup.clear(); + material = newMaterialId; + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + + std::string err_mtl; + bool ok = (*readMatFn)(namebuf, materials, &material_map, &err_mtl); + if (err) { + (*err) += err_mtl; + } + + if (!ok) { + faceGroup.clear(); // for safety + return false; + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + if (ret) { + shapes->push_back(shape); + } + + shape = shape_t(); + + // material = -1; + faceGroup.clear(); + + std::vector names; + names.reserve(2); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + // names[0] must be 'g', so skip the 0th element. + if (names.size() > 1) { + name = names[1]; + } else { + name = ""; + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + if (ret) { + shapes->push_back(shape); + } + + // material = -1; + faceGroup.clear(); + shape = shape_t(); + + // @todo { multiple object name? } + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + name = std::string(namebuf); + + continue; + } + + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + char namebuf[4096]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + tag.name = std::string(namebuf); + + token += tag.name.size() + 1; + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = atoi(token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.floatValues.resize(static_cast(ts.num_floats)); + for (size_t i = 0; i < static_cast(ts.num_floats); ++i) { + tag.floatValues[i] = parseFloat(&token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + char stringValueBuffer[4096]; + +#ifdef _MSC_VER + sscanf_s(token, "%s", stringValueBuffer, + (unsigned)_countof(stringValueBuffer)); +#else + sscanf(token, "%s", stringValueBuffer); +#endif + tag.stringValues[i] = stringValueBuffer; + token += tag.stringValues[i].size() + 1; + } + + tags.push_back(tag); + } + + // Ignore unknown command. + } + + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + // exportFaceGroupToShape return false when `usemtl` is called in the last + // line. + // we also add `shape` to `shapes` when `shape.mesh` has already some + // faces(indices) + if (ret || shape.mesh.indices.size()) { + shapes->push_back(shape); + } + faceGroup.clear(); // for safety + + if (err) { + (*err) += errss.str(); + } + + attrib->vertices.swap(v); + attrib->normals.swap(vn); + attrib->texcoords.swap(vt); + + return true; +} + +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data /*= NULL*/, + MaterialReader *readMatFn /*= NULL*/, + std::string *err /*= NULL*/) { + std::stringstream errss; + + // material + std::map material_map; + int material_id = -1; // -1 = invalid + + std::vector indices; + std::vector materials; + std::vector names; + names.reserve(2); + std::string name; + std::vector names_out; + + std::string linebuf; + while (inStream.peek() != -1) { + safeGetline(inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + float x, y, z, w; // w is optional. default = 1.0 + parseV(&x, &y, &z, &w, &token); + if (callback.vertex_cb) { + callback.vertex_cb(user_data, x, y, z, w); + } + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + float x, y, z; + parseFloat3(&x, &y, &z, &token); + if (callback.normal_cb) { + callback.normal_cb(user_data, x, y, z); + } + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + float x, y, z; // y and z are optional. default = 0.0 + parseFloat3(&x, &y, &z, &token); + if (callback.texcoord_cb) { + callback.texcoord_cb(user_data, x, y, z); + } + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + indices.clear(); + while (!IS_NEW_LINE(token[0])) { + vertex_index vi = parseRawTriple(&token); + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + indices.push_back(idx); + size_t n = strspn(token, " \t\r"); + token += n; + } + + if (callback.index_cb && indices.size() > 0) { + callback.index_cb(user_data, &indices.at(0), + static_cast(indices.size())); + } + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, + static_cast(_countof(namebuf))); +#else + sscanf(token, "%s", namebuf); +#endif + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material_id) { + material_id = newMaterialId; + } + + if (callback.usemtl_cb) { + callback.usemtl_cb(user_data, namebuf, material_id); + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + + std::string err_mtl; + materials.clear(); + bool ok = (*readMatFn)(namebuf, &materials, &material_map, &err_mtl); + if (err) { + (*err) += err_mtl; + } + + if (!ok) { + return false; + } + + if (callback.mtllib_cb) { + callback.mtllib_cb(user_data, &materials.at(0), + static_cast(materials.size())); + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + names.clear(); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + // names[0] must be 'g', so skip the 0th element. + if (names.size() > 1) { + name = names[1]; + } else { + name.clear(); + } + + if (callback.group_cb) { + if (names.size() > 1) { + // create const char* array. + names_out.resize(names.size() - 1); + for (size_t j = 0; j < names_out.size(); j++) { + names_out[j] = names[j + 1].c_str(); + } + callback.group_cb(user_data, &names_out.at(0), + static_cast(names_out.size())); + + } else { + callback.group_cb(user_data, NULL, 0); + } + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // @todo { multiple object name? } + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + std::string object_name = std::string(namebuf); + + if (callback.object_cb) { + callback.object_cb(user_data, object_name.c_str()); + } + + continue; + } + +#if 0 // @todo + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + char namebuf[4096]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + tag.name = std::string(namebuf); + + token += tag.name.size() + 1; + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = atoi(token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.floatValues.resize(static_cast(ts.num_floats)); + for (size_t i = 0; i < static_cast(ts.num_floats); ++i) { + tag.floatValues[i] = parseFloat(&token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + char stringValueBuffer[4096]; + +#ifdef _MSC_VER + sscanf_s(token, "%s", stringValueBuffer, + (unsigned)_countof(stringValueBuffer)); +#else + sscanf(token, "%s", stringValueBuffer); +#endif + tag.stringValues[i] = stringValueBuffer; + token += tag.stringValues[i].size() + 1; + } + + tags.push_back(tag); + } +#endif + + // Ignore unknown command. + } + + if (err) { + (*err) += errss.str(); + } + + return true; +} +} // namespace tinyobj + +#endif + +#endif // TINY_OBJ_LOADER_H_ diff --git a/A4/src/Camera.cpp b/A4/src/Camera.cpp new file mode 100644 index 0000000..4263a23 --- /dev/null +++ b/A4/src/Camera.cpp @@ -0,0 +1,68 @@ +/* +#include "Camera.h" +#include "MatrixStack.h" +#include +#include + +Camera::Camera() : + aspect(1.0f), + fovy(45.0f), + znear(0.1f), + zfar(1000.0f), + rotations(0.0, 0.0), + translations(0.0f, 0.0f, -5.0f), + rfactor(0.01f), + tfactor(0.001f), + sfactor(0.005f) +{ +} + +Camera::~Camera() +{ +} + +void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt) +{ + mousePrev.x = x; + mousePrev.y = y; + if(shift) { + state = Camera::TRANSLATE; + } else if(ctrl) { + state = Camera::SCALE; + } else { + state = Camera::ROTATE; + } +} + +void Camera::mouseMoved(float x, float y) +{ + glm::vec2 mouseCurr(x, y); + glm::vec2 dv = mouseCurr - mousePrev; + switch(state) { + case Camera::ROTATE: + rotations += rfactor * dv; + break; + case Camera::TRANSLATE: + translations.x -= translations.z * tfactor * dv.x; + translations.y += translations.z * tfactor * dv.y; + break; + case Camera::SCALE: + translations.z *= (1.0f - sfactor * dv.y); + break; + } + mousePrev = mouseCurr; +} + +void Camera::applyProjectionMatrix(std::shared_ptr P) const +{ + // Modify provided MatrixStack + P->multMatrix(glm::perspective(fovy, aspect, znear, zfar)); +} + +void Camera::applyViewMatrix(std::shared_ptr MV) const +{ + MV->translate(translations); + MV->rotate(rotations.y, glm::vec3(1.0f, 0.0f, 0.0f)); + MV->rotate(rotations.x, glm::vec3(0.0f, 1.0f, 0.0f)); +} +*/ diff --git a/A4/src/Camera.h b/A4/src/Camera.h new file mode 100644 index 0000000..f54a2fb --- /dev/null +++ b/A4/src/Camera.h @@ -0,0 +1,49 @@ +/* +#pragma once +#ifndef __Camera__ +#define __Camera__ + +#include + +#define GLM_FORCE_RADIANS +#include + +class MatrixStack; + +class Camera +{ +public: + enum { + ROTATE = 0, + TRANSLATE, + SCALE + }; + + Camera(); + virtual ~Camera(); + void setInitDistance(float z) { translations.z = -std::abs(z); } + void setAspect(float a) { aspect = a; }; + void setRotationFactor(float f) { rfactor = f; }; + void setTranslationFactor(float f) { tfactor = f; }; + void setScaleFactor(float f) { sfactor = f; }; + void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt); + void mouseMoved(float x, float y); + void applyProjectionMatrix(std::shared_ptr P) const; + void applyViewMatrix(std::shared_ptr MV) const; + +private: + float aspect; + float fovy; + float znear; + float zfar; + glm::vec2 rotations; + glm::vec3 translations; + glm::vec2 mousePrev; + int state; + float rfactor; + float tfactor; + float sfactor; +}; + +#endif +*/ diff --git a/A4/src/Component.cpp b/A4/src/Component.cpp new file mode 100644 index 0000000..0edd093 --- /dev/null +++ b/A4/src/Component.cpp @@ -0,0 +1,122 @@ +#include +#include "Component.h" + +using namespace std; + +Component::Component() +{ + parent = NULL; + selected = false; + t = vec3(0,0,0); + tp = vec3(0,0,0); + r = vec3(0,0,0); + s = vec3(1.0,1.0,1.0); + children.resize(0); + sid = 0; +} + +Component::Component(const Component& c) +{ + parent = c.parent; + children = c.children; + selected = c.selected; + t = vec3(c.t.x, c.t.y, c.t.z); + tp = vec3(c.tp.x, c.tp.y, c.tp.z); + r = vec3(c.r.x, c.r.y, c.r.z); + s = vec3(c.s.x, c.s.y, c.s.z); + sid = c.sid; +} + +void Component::draw(shared_ptr MV, shared_ptr P, shared_ptr S, shared_ptr Prog) +{ + MV->pushMatrix(); + MV->translate(tp.x, tp.y, tp.z); + MV->rotate(r.x, 1, 0, 0); + MV->rotate(r.y, 0, 1, 0); + MV->rotate(r.z, 0, 0, 1); + MV->translate(t.x, t.y, t.z); + for(unsigned int i = 0; i < children.size(); i++) + { + children[i].draw(MV, P, S, Prog); + } + if(selected) + { + MV->scale(1.1,1.1,1.1); + } + MV->scale(s.x,s.y,s.z); + glUniformMatrix4fv(Prog->getUniform("P"), 1, GL_FALSE, &P->topMatrix()[0][0]); + glUniformMatrix4fv(Prog->getUniform("MV"), 1, GL_FALSE, &MV->topMatrix()[0][0]); + S->draw(Prog); + MV->popMatrix(); +} + +Component& Component::getLastChild() +{ + if(this->children.empty()) + { + return *this; + } + return this->children[this->children.size() - 1].getLastChild(); +} + +Component& Component::getPrevious(Component *addr) +{ + if(children.empty()) + { + if(parent != NULL) + { + return parent->getPrevious(this); + } + } + + for(unsigned int i = 0; i < this->children.size(); i++) + { + //return *this; + if(&children[i] == addr) + { + if(i > 0) + { + return children[i-1].getLastChild(); + } + else + { + return *this; + } + } + } + + if (parent == NULL) { + return this->getLastChild(); + } + + return parent->getPrevious(this); +} + +Component& Component::getNext(Component *addr) +{ + if(addr == NULL) + { + if(!children.empty()) + { + return children[0]; + } + } + + for(unsigned int i = 0; i < this->children.size(); i++) + { + //return *this; + if(&children[i] == addr) + { + if(i+1 < children.size()) + { + return children[i+1]; + } + } + } + + if (parent == NULL) { + return *this; + } + + return parent->getNext(this); +} diff --git a/A4/src/Component.h b/A4/src/Component.h new file mode 100644 index 0000000..cebf40b --- /dev/null +++ b/A4/src/Component.h @@ -0,0 +1,30 @@ +// Create Body Class +#include +#include "MatrixStack.h" +#include +#include +#include "Shape.h" +#include "Program.h" + +using namespace std; +using namespace glm; + +class Component +{ + public: + Component *parent; + vector children; + bool selected; + vec3 t; + vec3 tp; + vec3 r; + vec3 s; + int sid; // used for storing which shape to render + + Component(); + Component(const Component& c); + void draw(shared_ptr MV, shared_ptr P, shared_ptr S, shared_ptr Prog); + Component& getNext(Component *addr); + Component& getPrevious(Component *addr); + Component& getLastChild(); +}; diff --git a/A4/src/GLSL.cpp b/A4/src/GLSL.cpp new file mode 100644 index 0000000..2969872 --- /dev/null +++ b/A4/src/GLSL.cpp @@ -0,0 +1,152 @@ +// +// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book +// Created by zwood on 2/21/10. +// Modified by sueda 10/15/15. +// + +#include "GLSL.h" +#include +#include +#include +#include + +using namespace std; + +namespace GLSL { + +const char * errorString(GLenum err) +{ + switch(err) { + case GL_NO_ERROR: + return "No error"; + case GL_INVALID_ENUM: + return "Invalid enum"; + case GL_INVALID_VALUE: + return "Invalid value"; + case GL_INVALID_OPERATION: + return "Invalid operation"; + case GL_STACK_OVERFLOW: + return "Stack overflow"; + case GL_STACK_UNDERFLOW: + return "Stack underflow"; + case GL_OUT_OF_MEMORY: + return "Out of memory"; + default: + return "No error"; + } +} + +void checkVersion() +{ + int major, minor; + major = minor = 0; + const char *verstr = (const char *)glGetString(GL_VERSION); + + if((verstr == NULL) || (sscanf(verstr, "%d.%d", &major, &minor) != 2)) { + printf("Invalid GL_VERSION format %d.%d\n", major, minor); + } + if(major < 2) { + printf("This shader example will not work due to the installed Opengl version, which is %d.%d.\n", major, minor); + exit(0); + } +} + +void checkError(const char *str) +{ + GLenum glErr = glGetError(); + if(glErr != GL_NO_ERROR) { + if(str) { + printf("%s: ", str); + } + printf("GL_ERROR = %s.\n", errorString(glErr)); + assert(false); + } +} + +void printShaderInfoLog(GLuint shader) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog = 0; + + checkError(GET_FILE_LINE); + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength); + checkError(GET_FILE_LINE); + + if(infologLength > 0) { + infoLog = (GLchar *)malloc(infologLength); + if(infoLog == NULL) { + puts("ERROR: Could not allocate InfoLog buffer"); + exit(1); + } + glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog); + checkError(GET_FILE_LINE); + printf("Shader InfoLog:\n%s\n\n", infoLog); + free(infoLog); + } +} + +void printProgramInfoLog(GLuint program) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog = 0; + + checkError(GET_FILE_LINE); + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infologLength); + checkError(GET_FILE_LINE); + + if(infologLength > 0) { + infoLog = (GLchar *)malloc(infologLength); + if(infoLog == NULL) { + puts("ERROR: Could not allocate InfoLog buffer"); + exit(1); + } + glGetProgramInfoLog(program, infologLength, &charsWritten, infoLog); + checkError(GET_FILE_LINE); + printf("Program InfoLog:\n%s\n\n", infoLog); + free(infoLog); + } +} + +char *textFileRead(const char *fn) +{ + FILE *fp; + char *content = NULL; + int count = 0; + if(fn != NULL) { + fp = fopen(fn,"rt"); + if(fp != NULL) { + fseek(fp, 0, SEEK_END); + count = (int)ftell(fp); + rewind(fp); + if(count > 0) { + content = (char *)malloc(sizeof(char) * (count+1)); + count = (int)fread(content,sizeof(char),count,fp); + content[count] = '\0'; + } + fclose(fp); + } else { + printf("error loading %s\n", fn); + } + } + return content; +} + +int textFileWrite(const char *fn, const char *s) +{ + FILE *fp; + int status = 0; + if(fn != NULL) { + fp = fopen(fn,"w"); + if(fp != NULL) { + if(fwrite(s,sizeof(char),strlen(s),fp) == strlen(s)) { + status = 1; + } + fclose(fp); + } + } + return(status); +} + +} diff --git a/A4/src/GLSL.h b/A4/src/GLSL.h new file mode 100644 index 0000000..f945fdd --- /dev/null +++ b/A4/src/GLSL.h @@ -0,0 +1,40 @@ +// +// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book +// Created by zwood on 2/21/10. +// Modified by sueda 10/15/15. +// + +#pragma once +#ifndef __GLSL__ +#define __GLSL__ + +#define GLEW_STATIC +#include + +/////////////////////////////////////////////////////////////////////////////// +// For printing out the current file and line number // +/////////////////////////////////////////////////////////////////////////////// +#include + +template +std::string NumberToString(T x) +{ + std::ostringstream ss; + ss << x; + return ss.str(); +} + +#define GET_FILE_LINE (std::string(__FILE__) + ":" + NumberToString(__LINE__)).c_str() +/////////////////////////////////////////////////////////////////////////////// + +namespace GLSL { + + void checkVersion(); + void checkError(const char *str = 0); + void printProgramInfoLog(GLuint program); + void printShaderInfoLog(GLuint shader); + int textFileWrite(const char *filename, const char *s); + char *textFileRead(const char *filename); +} + +#endif diff --git a/A4/src/Light.cpp b/A4/src/Light.cpp new file mode 100644 index 0000000..ebe7525 --- /dev/null +++ b/A4/src/Light.cpp @@ -0,0 +1,39 @@ +#include "Light.h" + +Light::Light() +{ + pos = glm::vec3(0.0f, 0.0f, 0.0f); + intensity = 0.0; +} + +Light::Light(const Light &l) +{ + pos = l.pos; + intensity = l.intensity; +} + +Light::Light(glm::vec3 p, float i) +{ + pos = p; + intensity = i; +} + +void Light::setPos(glm::vec3 p) +{ + this->pos = p; +} + +void Light::setIntensity(float i) +{ + this->intensity = i; +} + +glm::vec3 Light::getPos() +{ + return this->pos; +} + +float Light::getIntensity() +{ + return this->intensity; +} diff --git a/A4/src/Light.h b/A4/src/Light.h new file mode 100644 index 0000000..a1c3ed1 --- /dev/null +++ b/A4/src/Light.h @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include + +#include "GLSL.h" +#include "MyCamera.h" +#include "Shape.h" +#include "MatrixStack.h" + +class Light +{ + private: + glm::vec3 pos; + float intensity; + + public: + Light(); + Light(const Light &l); + Light(glm::vec3 p, float i); + void setPos(glm::vec3 p); + void setIntensity(float i); + glm::vec3 getPos(); + float getIntensity(); +}; diff --git a/A4/src/Material.cpp b/A4/src/Material.cpp new file mode 100644 index 0000000..279c0d0 --- /dev/null +++ b/A4/src/Material.cpp @@ -0,0 +1,39 @@ +#include "Material.h" + +using namespace std; + +Material::Material() +{ + this->ca = glm::vec3(0.3f,0.3f,0.3f); + this->cd = glm::vec3(0.3f,0.3f,0.3f); + this->cs = glm::vec3(1.0f,1.0f,1.0f); + this->shine = 0.0f; +} + +void Material::setMaterial(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh) +{ + this->ca = a; + this->cd = d; + this->cs = s; + this->shine = sh; +} + +glm::vec3 Material::getAmbient() +{ + return this->ca; +} + +glm::vec3 Material::getDiffuse() +{ + return this->cd; +} + +glm::vec3 Material::getSpecular() +{ + return this->cs; +} + +float Material::getShiny() +{ + return this->shine; +} diff --git a/A4/src/Material.h b/A4/src/Material.h new file mode 100644 index 0000000..3741f2d --- /dev/null +++ b/A4/src/Material.h @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include + +#include "GLSL.h" +#include "MyCamera.h" +#include "Shape.h" +#include "MatrixStack.h" + +class Material +{ + private: + glm::vec3 ca; + glm::vec3 cd; + glm::vec3 cs; + float shine; + + public: + Material(); + Material(const Material &m) + { + ca = m.ca; + cd = m.cd; + cs = m.cs; + } + Material(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh) + { + ca = a; + cd = d; + cs = s; + shine = sh; + } + void setMaterial(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh); + glm::vec3 getAmbient(); + glm::vec3 getDiffuse(); + glm::vec3 getSpecular(); + float getShiny(); +}; diff --git a/A4/src/MatrixStack.cpp b/A4/src/MatrixStack.cpp new file mode 100644 index 0000000..eaa6e6c --- /dev/null +++ b/A4/src/MatrixStack.cpp @@ -0,0 +1,114 @@ +#include "MatrixStack.h" + +#include +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +using namespace std; + +MatrixStack::MatrixStack() +{ + mstack = make_shared< stack >(); + mstack->push(glm::mat4(1.0)); +} + +MatrixStack::~MatrixStack() +{ +} + +void MatrixStack::pushMatrix() +{ + const glm::mat4 &top = mstack->top(); + mstack->push(top); + assert(mstack->size() < 100); +} + +void MatrixStack::popMatrix() +{ + assert(!mstack->empty()); + mstack->pop(); + // There should always be one matrix left. + assert(!mstack->empty()); +} + +void MatrixStack::loadIdentity() +{ + glm::mat4 &top = mstack->top(); + top = glm::mat4(1.0); +} + +void MatrixStack::translate(const glm::vec3 &t) +{ + glm::mat4 &top = mstack->top(); + top *= glm::translate(t); +} + +void MatrixStack::translate(float x, float y, float z) +{ + translate(glm::vec3(x, y, z)); +} + +void MatrixStack::scale(const glm::vec3 &s) +{ + glm::mat4 &top = mstack->top(); + top *= glm::scale(s); +} + +void MatrixStack::scale(float x, float y, float z) +{ + scale(glm::vec3(x, y, z)); +} + +void MatrixStack::scale(float s) +{ + scale(glm::vec3(s, s, s)); +} + +void MatrixStack::rotate(float angle, const glm::vec3 &axis) +{ + glm::mat4 &top = mstack->top(); + top *= glm::rotate(angle, axis); +} + +void MatrixStack::rotate(float angle, float x, float y, float z) +{ + rotate(angle, glm::vec3(x, y, z)); +} + +void MatrixStack::multMatrix(const glm::mat4 &matrix) +{ + glm::mat4 &top = mstack->top(); + top *= matrix; +} + +const glm::mat4 &MatrixStack::topMatrix() const +{ + return mstack->top(); +} + +void MatrixStack::print(const glm::mat4 &mat, const char *name) +{ + if(name) { + printf("%s = [\n", name); + } + for(int i = 0; i < 4; ++i) { + for(int j = 0; j < 4; ++j) { + // mat[j] returns the jth column + printf("%- 5.2f ", mat[j][i]); + } + printf("\n"); + } + if(name) { + printf("];"); + } + printf("\n"); +} + +void MatrixStack::print(const char *name) const +{ + print(mstack->top(), name); +} diff --git a/A4/src/MatrixStack.h b/A4/src/MatrixStack.h new file mode 100644 index 0000000..66278ce --- /dev/null +++ b/A4/src/MatrixStack.h @@ -0,0 +1,50 @@ +#pragma once +#ifndef _MatrixStack_H_ +#define _MatrixStack_H_ + +#include +#include +#include + +class MatrixStack +{ +public: + MatrixStack(); + virtual ~MatrixStack(); + + // glPushMatrix(): Copies the current matrix and adds it to the top of the stack + void pushMatrix(); + // glPopMatrix(): Removes the top of the stack and sets the current matrix to be the matrix that is now on top + void popMatrix(); + + // glLoadIdentity(): Sets the top matrix to be the identity + void loadIdentity(); + // glMultMatrix(): Right multiplies the top matrix + void multMatrix(const glm::mat4 &matrix); + + // glTranslate(): Right multiplies the top matrix by a translation matrix + void translate(const glm::vec3 &trans); + void translate(float x, float y, float z); + // glScale(): Right multiplies the top matrix by a scaling matrix + void scale(const glm::vec3 &scale); + void scale(float x, float y, float z); + // glScale(): Right multiplies the top matrix by a scaling matrix + void scale(float size); + // glRotate(): Right multiplies the top matrix by a rotation matrix (angle in radians) + void rotate(float angle, const glm::vec3 &axis); + void rotate(float angle, float x, float y, float z); + + // glGet(GL_MODELVIEW_MATRIX): Gets the top matrix + const glm::mat4 &topMatrix() const; + + // Prints out the specified matrix + static void print(const glm::mat4 &mat, const char *name = 0); + // Prints out the top matrix + void print(const char *name = 0) const; + +private: + std::shared_ptr< std::stack > mstack; + +}; + +#endif diff --git a/A4/src/MyCamera.cpp b/A4/src/MyCamera.cpp new file mode 100644 index 0000000..affa6c0 --- /dev/null +++ b/A4/src/MyCamera.cpp @@ -0,0 +1,88 @@ +#include "MyCamera.h" +#include "MatrixStack.h" +#include +#include + +Camera::Camera() : + aspect(1.0f), + fovy(45.0f), + znear(0.1f), + zfar(1000.0f), + rotations(0.0, 0.0), + translations(0.0f, 0.0f, -5.0f), + rfactor(0.01f), + tfactor(0.001f), + sfactor(0.005f), + pos(0.0f, 0.0f, 1.0f), + pitch(0.0f), + yaw(0.0f) +{ +} + +Camera::~Camera() +{ +} + +void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt) +{ + mousePrev.x = x; + mousePrev.y = y; + if(shift) { + state = Camera::TRANSLATE; + } else if(ctrl) { + state = Camera::SCALE; + } else { + state = Camera::ROTATE; + } +} + +void Camera::mouseMoved(float x, float y) +{ + glm::vec2 mouseCurr(x, y); + glm::vec2 dv = mouseCurr - mousePrev; + switch(state) { + case Camera::ROTATE: + rotations += rfactor * dv; + if(rotations.y > 0.6) + { + rotations.y = 0.6; + } + else if(rotations.y < -0.6) + { + rotations.y = -0.6; + } + break; + case Camera::TRANSLATE: + translations.x -= translations.z * tfactor * dv.x; + translations.y += translations.z * tfactor * dv.y; + break; + case Camera::SCALE: + translations.z *= (1.0f - sfactor * dv.y); + break; + } + mousePrev = mouseCurr; +} + +void Camera::applyProjectionMatrix(std::shared_ptr P) const +{ + // Modify provided MatrixStack + P->multMatrix(glm::perspective(fovy, aspect, znear, zfar)); +} + +glm::vec3 Camera::getPos() +{ + return pos; +} + +void Camera::transpose(glm::vec3 t) +{ + glm::vec3 target(sin(rotations.x), 0, cos(rotations.x)); + pos -= (cross(glm::vec3(0, 1, 0), target))*t.x; + pos -= target*t.z; +} + +void Camera::applyViewMatrix(std::shared_ptr MV) const +{ + glm::vec3 target(sin(rotations.x), sin(rotations.y), cos(rotations.x)); + MV->multMatrix(glm::lookAt(pos, pos + target, glm::vec3(0,1,0))); +} diff --git a/A4/src/MyCamera.h b/A4/src/MyCamera.h new file mode 100644 index 0000000..7f31dbe --- /dev/null +++ b/A4/src/MyCamera.h @@ -0,0 +1,54 @@ +#pragma once +#ifndef __MyCamera__ +#define __MyCamera__ + +#include + +#define GLM_FORCE_RADIANS +#include + +class MatrixStack; + +class Camera +{ +public: + enum { + ROTATE = 0, + TRANSLATE, + SCALE + }; + + Camera(); + virtual ~Camera(); + void setInitDistance(float z) { translations.z = -std::abs(z); } + void setAspect(float a) { aspect = a; }; + void setRotationFactor(float f) { rfactor = f; }; + void setTranslationFactor(float f) { tfactor = f; }; + void setScaleFactor(float f) { sfactor = f; }; + void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt); + void mouseMoved(float x, float y); + void applyProjectionMatrix(std::shared_ptr P) const; + void applyViewMatrix(std::shared_ptr MV) const; + glm::vec3 getPos(); + void transpose(glm::vec3 t); + +private: + float aspect; + float fovy; + float znear; + float zfar; + glm::vec2 rotations; + glm::vec3 translations; + glm::vec2 mousePrev; + int state; + float rfactor; + float tfactor; + float sfactor; + + // TODO: Implement these + glm::vec3 pos; + float pitch; // Preliminarily making these floats + float yaw; // to hold angles. +}; + +#endif diff --git a/A4/src/Program.cpp b/A4/src/Program.cpp new file mode 100644 index 0000000..1e85538 --- /dev/null +++ b/A4/src/Program.cpp @@ -0,0 +1,126 @@ +#include "Program.h" + +#include +#include + +#include "GLSL.h" + +using namespace std; + +Program::Program() : + vShaderName(""), + fShaderName(""), + pid(0), + verbose(true) +{ + +} + +Program::~Program() +{ + +} + +void Program::setShaderNames(const string &v, const string &f) +{ + vShaderName = v; + fShaderName = f; +} + +bool Program::init() +{ + GLint rc; + + // Create shader handles + GLuint VS = glCreateShader(GL_VERTEX_SHADER); + GLuint FS = glCreateShader(GL_FRAGMENT_SHADER); + + // Read shader sources + const char *vshader = GLSL::textFileRead(vShaderName.c_str()); + const char *fshader = GLSL::textFileRead(fShaderName.c_str()); + glShaderSource(VS, 1, &vshader, NULL); + glShaderSource(FS, 1, &fshader, NULL); + + // Compile vertex shader + glCompileShader(VS); + glGetShaderiv(VS, GL_COMPILE_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printShaderInfoLog(VS); + cout << "Error compiling vertex shader " << vShaderName << endl; + } + return false; + } + + // Compile fragment shader + glCompileShader(FS); + glGetShaderiv(FS, GL_COMPILE_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printShaderInfoLog(FS); + cout << "Error compiling fragment shader " << fShaderName << endl; + } + return false; + } + + // Create the program and link + pid = glCreateProgram(); + glAttachShader(pid, VS); + glAttachShader(pid, FS); + glLinkProgram(pid); + glGetProgramiv(pid, GL_LINK_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printProgramInfoLog(pid); + cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl; + } + return false; + } + + GLSL::checkError(GET_FILE_LINE); + return true; +} + +void Program::bind() +{ + glUseProgram(pid); +} + +void Program::unbind() +{ + glUseProgram(0); +} + +void Program::addAttribute(const string &name) +{ + attributes[name] = glGetAttribLocation(pid, name.c_str()); +} + +void Program::addUniform(const string &name) +{ + uniforms[name] = glGetUniformLocation(pid, name.c_str()); +} + +GLint Program::getAttribute(const string &name) const +{ + map::const_iterator attribute = attributes.find(name.c_str()); + if(attribute == attributes.end()) { + if(isVerbose()) { + cout << name << " is not an attribute variable" << endl; + } + return -1; + } + return attribute->second; +} + +GLint Program::getUniform(const string &name) const +{ + map::const_iterator uniform = uniforms.find(name.c_str()); + if(uniform == uniforms.end()) { + if(isVerbose()) { + cout << name << " is not a uniform variable" << endl; + } + return -1; + } + return uniform->second; +} diff --git a/A4/src/Program.h b/A4/src/Program.h new file mode 100644 index 0000000..51e58bb --- /dev/null +++ b/A4/src/Program.h @@ -0,0 +1,44 @@ +#pragma once +#ifndef __Program__ +#define __Program__ + +#include +#include + +#define GLEW_STATIC +#include + +/** + * An OpenGL Program (vertex and fragment shaders) + */ +class Program +{ +public: + Program(); + virtual ~Program(); + + void setVerbose(bool v) { verbose = v; } + bool isVerbose() const { return verbose; } + + void setShaderNames(const std::string &v, const std::string &f); + virtual bool init(); + virtual void bind(); + virtual void unbind(); + + void addAttribute(const std::string &name); + void addUniform(const std::string &name); + GLint getAttribute(const std::string &name) const; + GLint getUniform(const std::string &name) const; + +protected: + std::string vShaderName; + std::string fShaderName; + +private: + GLuint pid; + std::map attributes; + std::map uniforms; + bool verbose; +}; + +#endif diff --git a/A4/src/Shape.cpp b/A4/src/Shape.cpp new file mode 100644 index 0000000..426ef9c --- /dev/null +++ b/A4/src/Shape.cpp @@ -0,0 +1,165 @@ +#include "Shape.h" +#include + +#include "GLSL.h" +#include "Program.h" + +#define GLM_FORCE_RADIANS +#include + +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" + +using namespace std; + +Shape::Shape() : + posBufID(0), + norBufID(0), + texBufID(0) +{ +} + +Shape::~Shape() +{ +} + +void Shape::loadMesh(const string &meshName) +{ + // Load geometry + tinyobj::attrib_t attrib; + std::vector shapes; + std::vector materials; + string errStr; + bool rc = tinyobj::LoadObj(&attrib, &shapes, &materials, &errStr, meshName.c_str()); + if(!rc) { + cerr << errStr << endl; + } else { + // Some OBJ files have different indices for vertex positions, normals, + // and texture coordinates. For example, a cube corner vertex may have + // three different normals. Here, we are going to duplicate all such + // vertices. + // Loop over shapes + for(size_t s = 0; s < shapes.size(); s++) { + // Loop over faces (polygons) + size_t index_offset = 0; + for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { + size_t fv = shapes[s].mesh.num_face_vertices[f]; + // Loop over vertices in the face. + for(size_t v = 0; v < fv; v++) { + // access to vertex + tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v]; + posBuf.push_back(attrib.vertices[3*idx.vertex_index+0]); + posBuf.push_back(attrib.vertices[3*idx.vertex_index+1]); + posBuf.push_back(attrib.vertices[3*idx.vertex_index+2]); + if(!attrib.normals.empty()) { + norBuf.push_back(attrib.normals[3*idx.normal_index+0]); + norBuf.push_back(attrib.normals[3*idx.normal_index+1]); + norBuf.push_back(attrib.normals[3*idx.normal_index+2]); + } + if(!attrib.texcoords.empty()) { + texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+0]); + texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+1]); + } + } + index_offset += fv; + // per-face material (IGNORE) + shapes[s].mesh.material_ids[f]; + } + } + } +} + +void Shape::fitToUnitBox() +{ + // Scale the vertex positions so that they fit within [-1, +1] in all three dimensions. + glm::vec3 vmin(posBuf[0], posBuf[1], posBuf[2]); + glm::vec3 vmax(posBuf[0], posBuf[1], posBuf[2]); + for(int i = 0; i < (int)posBuf.size(); i += 3) { + glm::vec3 v(posBuf[i], posBuf[i+1], posBuf[i+2]); + vmin.x = min(vmin.x, v.x); + vmin.y = min(vmin.y, v.y); + vmin.z = min(vmin.z, v.z); + vmax.x = max(vmax.x, v.x); + vmax.y = max(vmax.y, v.y); + vmax.z = max(vmax.z, v.z); + } + glm::vec3 center = 0.5f*(vmin + vmax); + glm::vec3 diff = vmax - vmin; + float diffmax = diff.x; + diffmax = max(diffmax, diff.y); + diffmax = max(diffmax, diff.z); + float scale = 1.0f / diffmax; + for(int i = 0; i < (int)posBuf.size(); i += 3) { + posBuf[i ] = (posBuf[i ] - center.x) * scale; + posBuf[i+1] = (posBuf[i+1] - center.y) * scale; + posBuf[i+2] = (posBuf[i+2] - center.z) * scale; + } +} + +void Shape::init() +{ + // Send the position array to the GPU + glGenBuffers(1, &posBufID); + glBindBuffer(GL_ARRAY_BUFFER, posBufID); + glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_STATIC_DRAW); + + // Send the normal array to the GPU + if(!norBuf.empty()) { + glGenBuffers(1, &norBufID); + glBindBuffer(GL_ARRAY_BUFFER, norBufID); + glBufferData(GL_ARRAY_BUFFER, norBuf.size()*sizeof(float), &norBuf[0], GL_STATIC_DRAW); + } + + // Send the texture array to the GPU + if(!texBuf.empty()) { + glGenBuffers(1, &texBufID); + glBindBuffer(GL_ARRAY_BUFFER, texBufID); + glBufferData(GL_ARRAY_BUFFER, texBuf.size()*sizeof(float), &texBuf[0], GL_STATIC_DRAW); + } + + // Unbind the arrays + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLSL::checkError(GET_FILE_LINE); +} + +void Shape::draw(const shared_ptr prog) const +{ + // Bind position buffer + int h_pos = prog->getAttribute("aPos"); + glEnableVertexAttribArray(h_pos); + glBindBuffer(GL_ARRAY_BUFFER, posBufID); + glVertexAttribPointer(h_pos, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0); + + // Bind normal buffer + int h_nor = prog->getAttribute("aNor"); + if(h_nor != -1 && norBufID != 0) { + glEnableVertexAttribArray(h_nor); + glBindBuffer(GL_ARRAY_BUFFER, norBufID); + glVertexAttribPointer(h_nor, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0); + } + + // Bind texcoords buffer + int h_tex = prog->getAttribute("aTex"); + if(h_tex != -1 && texBufID != 0) { + glEnableVertexAttribArray(h_tex); + glBindBuffer(GL_ARRAY_BUFFER, texBufID); + glVertexAttribPointer(h_tex, 2, GL_FLOAT, GL_FALSE, 0, (const void *)0); + } + + // Draw + int count = posBuf.size()/3; // number of indices to be rendered + glDrawArrays(GL_TRIANGLES, 0, count); + + // Disable and unbind + if(h_tex != -1) { + glDisableVertexAttribArray(h_tex); + } + if(h_nor != -1) { + glDisableVertexAttribArray(h_nor); + } + glDisableVertexAttribArray(h_pos); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLSL::checkError(GET_FILE_LINE); +} diff --git a/A4/src/Shape.h b/A4/src/Shape.h new file mode 100644 index 0000000..297476c --- /dev/null +++ b/A4/src/Shape.h @@ -0,0 +1,37 @@ +#pragma once +#ifndef _SHAPE_H_ +#define _SHAPE_H_ + +#include +#include +#include + +class Program; + +/** + * A shape defined by a list of triangles + * - posBuf should be of length 3*ntris + * - norBuf should be of length 3*ntris (if normals are available) + * - texBuf should be of length 2*ntris (if texture coords are available) + * posBufID, norBufID, and texBufID are OpenGL buffer identifiers. + */ +class Shape +{ +public: + Shape(); + virtual ~Shape(); + void loadMesh(const std::string &meshName); + void fitToUnitBox(); + void init(); + void draw(const std::shared_ptr prog) const; + +private: + std::vector posBuf; + std::vector norBuf; + std::vector texBuf; + unsigned posBufID; + unsigned norBufID; + unsigned texBufID; +}; + +#endif diff --git a/A4/src/main.cpp b/A4/src/main.cpp new file mode 100644 index 0000000..8e4fd56 --- /dev/null +++ b/A4/src/main.cpp @@ -0,0 +1,462 @@ +#include +#include +#define _USE_MATH_DEFINES +#include +#include + +#define GLEW_STATIC +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +#include "MyCamera.h" +#include "GLSL.h" +#include "MatrixStack.h" +#include "Program.h" +#include "Shape.h" +#include "Material.h" +#include "Light.h" +#include "Component.h" + +using namespace std; + +GLFWwindow *window; // Main application window +string RESOURCE_DIR = "./"; // Where the resources are loaded from + +shared_ptr camera; +shared_ptr prog; +shared_ptr sprog; +shared_ptr shape; +shared_ptr sphere; +shared_ptr cube; +shared_ptr teapot; + +bool keyToggles[256] = {false}; // only for English keyboards! + +vector materials; +Light l[2]; +int ind = 0; +int lind = 0; +int sind = 0; + +unsigned int pid0; +unsigned int pid1; + +//Variables affecting the assortment of shapes. +unsigned int n = 10; +float s = 1.0; +float tx = 1.0; +float ty = 1.0; +float tz = 1.0; +vector shapes; + +// This function is called when a GLFW error occurs +static void error_callback(int error, const char *description) +{ + cerr << description << endl; +} + +// This function is called when a key is pressed +static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) +{ + if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GL_TRUE); + } +} + +// This function is called when the mouse is clicked +static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) +{ + // Get the current mouse position. + double xmouse, ymouse; + glfwGetCursorPos(window, &xmouse, &ymouse); + // Get current window size. + int width, height; + glfwGetWindowSize(window, &width, &height); + if(action == GLFW_PRESS) { + bool shift = (mods & GLFW_MOD_SHIFT) != 0; + bool ctrl = (mods & GLFW_MOD_CONTROL) != 0; + bool alt = (mods & GLFW_MOD_ALT) != 0; + camera->mouseClicked((float)xmouse, (float)ymouse, shift, ctrl, alt); + } +} + +// This function is called when the mouse moves +static void cursor_position_callback(GLFWwindow* window, double xmouse, double ymouse) +{ + int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); + if(state == GLFW_PRESS) { + camera->mouseMoved((float)xmouse, (float)ymouse); + } +} + +static void char_callback(GLFWwindow *window, unsigned int key) +{ + keyToggles[key] = !keyToggles[key]; + char cp = (char)key; + + if(cp == 'W' || cp == 'w') + { + vec3 temp(0.0f, 0.0f, -0.1f); + camera->transpose(temp); + } + if(cp == 'A' || cp == 'a') + { + vec3 temp(-0.1f, 0.0f, 0.0f); + camera->transpose(temp); + } + if(cp == 'S' || cp == 's') + { + vec3 temp(0.0f, 0.0f, 0.1f); + camera->transpose(temp); + } + if(cp == 'D' || cp == 'd') + { + vec3 temp(0.1f, 0.0f, 0.0f); + camera->transpose(temp); + } + if(cp == 'X') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x + 0.1f, temp.y, temp.z)); + } + if(cp == 'x') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x - 0.1f, temp.y, temp.z)); + } + + if(cp == 'Y') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x, temp.y + 0.1f, temp.z)); + } + if(cp == 'y') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x, temp.y - 0.1f, temp.z)); + } + + if(cp == 'Z') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x, temp.y, temp.z + 0.1f)); + } + if(cp == 'z') + { + glm::vec3 temp = l[lind].getPos(); + l[lind].setPos(glm::vec3(temp.x, temp.y, temp.z - 0.1f)); + } +} + +// If the window is resized, capture the new size and reset the viewport +static void resize_callback(GLFWwindow *window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void createComponents() +{ + for(unsigned int i = 0; i < n; i++) + { + Component temp; + + temp.s.x = s; + temp.s.y = s; + temp.s.z = s; + + temp.tp.x = 0; + temp.tp.y = 0; + temp.tp.z = -tz*((float)i); + + temp.t.x = 1.0/2.0; + temp.t.y = 0; + temp.t.z = -1.0/2.0; + + temp.sid = rand()%3; + + shapes.push_back(temp); + } +} + +static void createMaterials() +{ + Material m1; + + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + materials.push_back(m1); + + materials[0].setMaterial(glm::vec3(0.0f, 0.0f, 0.4f), glm::vec3(0.2f, 0.1f, 0.7f), glm::vec3(0.5f, 0.5f, 0.5f), 200.0f); + materials[1].setMaterial(glm::vec3(0.3f, 0.3f, 0.4f), glm::vec3(0.2f, 0.2f, 0.3f), glm::vec3(0.1f, 0.1f, 0.1f), 10.0f); + materials[2].setMaterial(glm::vec3(0.2f, 0.2f, 0.2f), glm::vec3(0.8f, 0.7f, 0.7f), glm::vec3(1.0f, 0.9f, 0.8f), 200.0f); + materials[3].setMaterial(glm::vec3(0.2f, 0.8f, 0.2f), glm::vec3(0.1f, 0.7f, 0.2f), glm::vec3(0.2f, 0.2f, 0.2f), 100.0f); + materials[4].setMaterial(glm::vec3(0.8f, 0.2f, 0.2f), glm::vec3(0.7f, 0.1f, 0.1f), glm::vec3(0.3f, 0.3f, 0.3f), 100.0f); + materials[5].setMaterial(glm::vec3(0.7f, 0.7f, 0.1f), glm::vec3(0.6f, 0.5f, 0.2f), glm::vec3(0.1f, 0.1f, 0.1f), 50.0f); + materials[6].setMaterial(glm::vec3(0.5f, 0.1f, 0.1f), glm::vec3(0.7f, 0.1f, 0.1f), glm::vec3(0.2f, 0.2f, 0.2f), 50.0f); + materials[7].setMaterial(glm::vec3(0.2f, 0.8f, 0.8f), glm::vec3(0.1f, 0.7f, 0.6f), glm::vec3(0.5f, 0.5f, 0.5f), 120.0f); + materials[8].setMaterial(glm::vec3(0.3f, 0.6f, 0.3f), glm::vec3(0.3f, 0.6f, 0.3f), glm::vec3(0.7f, 0.7f, 0.7f), 20.0f); + materials[9].setMaterial(glm::vec3(0.8f, 0.2f, 0.7f), glm::vec3(0.7f, 0.2f, 0.8f), glm::vec3(0.5f, 0.5f, 0.5f), 200.0f); + materials[10].setMaterial(glm::vec3(0.2f, 0.5f, 0.2f), glm::vec3(0.2f, 0.5f, 0.2f), glm::vec3(0.5f, 0.5f, 0.5f), 10.0f); +} + +static void makeGround() +{ + Component temp; + + temp.tp.x = 0.0f; + temp.tp.y = -1.0f; + temp.tp.z = 0.0f; + + temp.s.x = 100.0f; + temp.s.y = 0.0f; + temp.s.z = 100.0f; + + temp.t.x = 0.0f; + temp.t.y = 0.0f; + temp.t.z = 0.0f; + + temp.sid = 2; + + shapes.push_back(temp); +} + +// This function is called once to initialize the scene and OpenGL +static void init() +{ + // Initialize time. + glfwSetTime(0.0); + + // Set background color. + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + // Enable z-buffer test. + glEnable(GL_DEPTH_TEST); + + sprog = make_shared(); + sprog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "sil.glsl"); + sprog->setVerbose(false); + sprog->init(); + sprog->addAttribute("aPos"); + sprog->addAttribute("aNor"); + sprog->addUniform("MV"); + sprog->addUniform("P"); + + prog = make_shared(); + prog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "frag.glsl"); + prog->setVerbose(false); + prog->init(); + prog->addAttribute("aPos"); + prog->addAttribute("aNor"); + prog->addUniform("MV"); + prog->addUniform("P"); + prog->addUniform("MVL"); + prog->addUniform("lightPos1"); + prog->addUniform("lightPos2"); + prog->addUniform("ka"); + prog->addUniform("kd"); + prog->addUniform("ks"); + prog->addUniform("s"); + prog->addUniform("i1"); + prog->addUniform("i2"); + + camera = make_shared(); + camera->setInitDistance(2.0f); + + shape = make_shared(); + shape->loadMesh(RESOURCE_DIR + "bunny.obj"); + shape->fitToUnitBox(); + shape->init(); + + sphere = make_shared(); + sphere->loadMesh(RESOURCE_DIR + "sphere.obj"); + sphere->fitToUnitBox(); + sphere->init(); + + cube = make_shared(); + cube->loadMesh(RESOURCE_DIR + "cube.obj"); + cube->fitToUnitBox(); + cube->init(); + + teapot = make_shared(); + teapot->loadMesh(RESOURCE_DIR + "teapot.obj"); + teapot->fitToUnitBox(); + teapot->init(); + + createMaterials(); + + Light l1(glm::vec3(1.0f, 1.0f, 1.0f), 0.8f); + Light l2(glm::vec3(-1.0f, 1.0f, 1.0f), 0.2f); + l[0] = l1; + l[1] = l2; + + // separate function to create shapes. + createComponents(); + + makeGround(); + + GLSL::checkError(GET_FILE_LINE); +} + +// This function is called every frame to draw the scene. +static void render() +{ + // Clear framebuffer. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if(keyToggles[(unsigned)'c']) { + glEnable(GL_CULL_FACE); + } else { + glDisable(GL_CULL_FACE); + } + // Get current frame buffer size. + int width, height; + glfwGetFramebufferSize(window, &width, &height); + camera->setAspect((float)width/(float)height); + + // Matrix stacks + auto P = make_shared(); + auto MV = make_shared(); + + // Apply camera transforms + P->pushMatrix(); + camera->applyProjectionMatrix(P); + MV->pushMatrix(); + camera->applyViewMatrix(MV); + + prog->bind(); + + mat4 templ; + templ[0] = vec4(1.0, 0, 0, 0); + templ[1] = vec4(0, 1.0, 0, 0); + templ[2] = vec4(0, 0, 1.0, 0); + templ[3] = vec4(l[0].getPos().x, l[0].getPos().y, l[0].getPos().z, 1.0); + templ = MV->topMatrix()*templ; + glUniformMatrix4fv(prog->getUniform("MVL"), 1, GL_FALSE, glm::value_ptr(templ)); + + Component light; + + light.t.x = l[0].getPos().x; + light.t.y = l[0].getPos().y; + light.t.z = l[0].getPos().z; + + glUniform3f(prog->getUniform("lightPos1"), l[0].getPos().x, l[0].getPos().y, l[0].getPos().z); + glUniform3f(prog->getUniform("ka"), 0.95, 1.0, 0.35); + glUniform3f(prog->getUniform("kd"), 1.0, 1.0, 1.0); + glUniform3f(prog->getUniform("ks"), 1.0, 1.0, 1.0); + glUniform1f(prog->getUniform("s"), 1.0); + + light.draw(MV, P, sphere, prog); + prog->unbind(); + + glm::vec3 ambient = materials.at(0).getAmbient(); + glm::vec3 diffuse = materials.at(0).getDiffuse(); + glm::vec3 specular = materials.at(0).getSpecular(); + float shine = materials.at(0).getShiny(); + for(unsigned int i = 0; i < n + 1; i++) + { + prog->bind(); + ambient = materials.at(i).getAmbient(); + diffuse = materials.at(i).getDiffuse(); + specular = materials.at(i).getSpecular(); + shine = materials.at(i).getShiny(); + + glUniform3f(prog->getUniform("ka"), ambient.r, ambient.g, ambient.b); + glUniform3f(prog->getUniform("kd"), diffuse.r, diffuse.g, diffuse.b); + glUniform3f(prog->getUniform("ks"), specular.r, specular.g, specular.b); + glUniform1f(prog->getUniform("s"), shine); + glUniform1f(prog->getUniform("i1"), l[0].getIntensity()); + glUniform1f(prog->getUniform("i2"), l[1].getIntensity()); + + switch(shapes.at(i).sid) + { + case 0: + shapes.at(i).draw(MV, P, shape, prog); + break; + case 1: + shapes.at(i).draw(MV, P, teapot, prog); + break; + case 2: + shapes.at(i).draw(MV, P, cube, prog); + break; + default: + shapes.at(i).draw(MV, P, shape, prog); + break; + }; + prog->unbind(); + } + MV->popMatrix(); + P->popMatrix(); + + GLSL::checkError(GET_FILE_LINE); +} + +int main(int argc, char **argv) +{ + if(argc < 2) { + cout << "Please specify the resource directory." << endl; + return 0; + } + RESOURCE_DIR = argv[1] + string("/"); + + // Set error callback. + glfwSetErrorCallback(error_callback); + // Initialize the library. + if(!glfwInit()) { + return -1; + } + // Create a windowed mode window and its OpenGL context. + window = glfwCreateWindow(640, 480, "Alex Huddleston Assignment 4", NULL, NULL); + if(!window) { + glfwTerminate(); + return -1; + } + // Make the window's context current. + glfwMakeContextCurrent(window); + // Initialize GLEW. + glewExperimental = true; + if(glewInit() != GLEW_OK) { + cerr << "Failed to initialize GLEW" << endl; + return -1; + } + glGetError(); // A bug in glewInit() causes an error that we can safely ignore. + cout << "OpenGL version: " << glGetString(GL_VERSION) << endl; + cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl; + GLSL::checkVersion(); + // Set vsync. + glfwSwapInterval(1); + // Set keyboard callback. + glfwSetKeyCallback(window, key_callback); + // Set char callback. + glfwSetCharCallback(window, char_callback); + // Set cursor position callback. + glfwSetCursorPosCallback(window, cursor_position_callback); + // Set mouse button callback. + glfwSetMouseButtonCallback(window, mouse_button_callback); + // Set the window resize call back. + glfwSetFramebufferSizeCallback(window, resize_callback); + // Initialize scene. + init(); + // Loop until the user closes the window. + while(!glfwWindowShouldClose(window)) { + // Render scene. + render(); + // Swap front and back buffers. + glfwSwapBuffers(window); + // Poll for and process events. + glfwPollEvents(); + } + // Quit program. + glfwDestroyWindow(window); + glfwTerminate(); + return 0; +} diff --git a/A4/src/tiny_obj_loader.h b/A4/src/tiny_obj_loader.h new file mode 100644 index 0000000..b975601 --- /dev/null +++ b/A4/src/tiny_obj_loader.h @@ -0,0 +1,1922 @@ +/* +The MIT License (MIT) + +Copyright (c) 2012-2016 Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// +// version 1.0.3 : Support parsing texture options(#85) +// version 1.0.2 : Improve parsing speed by about a factor of 2 for large +// files(#105) +// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104) +// version 1.0.0 : Change data structure. Change license from BSD to MIT. +// + +// +// Use this in *one* .cc +// #define TINYOBJLOADER_IMPLEMENTATION +// #include "tiny_obj_loader.h" +// + +#ifndef TINY_OBJ_LOADER_H_ +#define TINY_OBJ_LOADER_H_ + +#include +#include +#include + +namespace tinyobj { + +// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ... +// +// -blendu on | off # set horizontal texture blending +// (default on) +// -blendv on | off # set vertical texture blending +// (default on) +// -boost float_value # boost mip-map sharpness +// -mm base_value gain_value # modify texture map values (default +// 0 1) +// # base_value = brightness, +// gain_value = contrast +// -o u [v [w]] # Origin offset (default +// 0 0 0) +// -s u [v [w]] # Scale (default +// 1 1 1) +// -t u [v [w]] # Turbulence (default +// 0 0 0) +// -texres resolution # texture resolution to create +// -clamp on | off # only render texels in the clamped +// 0-1 range (default off) +// # When unclamped, textures are +// repeated across a surface, +// # when clamped, only texels which +// fall within the 0-1 +// # range are rendered. +// -bm mult_value # bump multiplier (for bump maps +// only) +// +// -imfchan r | g | b | m | l | z # specifies which channel of the file +// is used to +// # create a scalar or bump texture. +// r:red, g:green, +// # b:blue, m:matte, l:luminance, +// z:z-depth.. +// # (the default for bump is 'l' and +// for decal is 'm') +// bump -imfchan r bumpmap.tga # says to use the red channel of +// bumpmap.tga as the bumpmap +// +// For reflection maps... +// +// -type sphere # specifies a sphere for a "refl" +// reflection map +// -type cube_top | cube_bottom | # when using a cube map, the texture +// file for each +// cube_front | cube_back | # side of the cube is specified +// separately +// cube_left | cube_right + +typedef enum { + TEXTURE_TYPE_NONE, // default + TEXTURE_TYPE_SPHERE, + TEXTURE_TYPE_CUBE_TOP, + TEXTURE_TYPE_CUBE_BOTTOM, + TEXTURE_TYPE_CUBE_FRONT, + TEXTURE_TYPE_CUBE_BACK, + TEXTURE_TYPE_CUBE_LEFT, + TEXTURE_TYPE_CUBE_RIGHT +} texture_type_t; + +typedef struct { + texture_type_t type; // -type (default TEXTURE_TYPE_NONE) + float sharpness; // -boost (default 1.0?) + float brightness; // base_value in -mm option (default 0) + float contrast; // gain_value in -mm option (default 1) + float origin_offset[3]; // -o u [v [w]] (default 0 0 0) + float scale[3]; // -s u [v [w]] (default 1 1 1) + float turbulence[3]; // -t u [v [w]] (default 0 0 0) + // int texture_resolution; // -texres resolution (default = ?) TODO + bool clamp; // -clamp (default false) + char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm') + bool blendu; // -blendu (default on) + bool blendv; // -blendv (default on) + float bump_multiplier; // -bm (for bump maps only, default 1.0) +} texture_option_t; + +typedef struct { + std::string name; + + float ambient[3]; + float diffuse[3]; + float specular[3]; + float transmittance[3]; + float emission[3]; + float shininess; + float ior; // index of refraction + float dissolve; // 1 == opaque; 0 == fully transparent + // illumination model (see http://www.fileformat.info/format/material/) + int illum; + + int dummy; // Suppress padding warning. + + std::string ambient_texname; // map_Ka + std::string diffuse_texname; // map_Kd + std::string specular_texname; // map_Ks + std::string specular_highlight_texname; // map_Ns + std::string bump_texname; // map_bump, bump + std::string displacement_texname; // disp + std::string alpha_texname; // map_d + + texture_option_t ambient_texopt; + texture_option_t diffuse_texopt; + texture_option_t specular_texopt; + texture_option_t specular_highlight_texopt; + texture_option_t bump_texopt; + texture_option_t displacement_texopt; + texture_option_t alpha_texopt; + + // PBR extension + // http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr + float roughness; // [0, 1] default 0 + float metallic; // [0, 1] default 0 + float sheen; // [0, 1] default 0 + float clearcoat_thickness; // [0, 1] default 0 + float clearcoat_roughness; // [0, 1] default 0 + float anisotropy; // aniso. [0, 1] default 0 + float anisotropy_rotation; // anisor. [0, 1] default 0 + float pad0; + float pad1; + std::string roughness_texname; // map_Pr + std::string metallic_texname; // map_Pm + std::string sheen_texname; // map_Ps + std::string emissive_texname; // map_Ke + std::string normal_texname; // norm. For normal mapping. + + texture_option_t roughness_texopt; + texture_option_t metallic_texopt; + texture_option_t sheen_texopt; + texture_option_t emissive_texopt; + texture_option_t normal_texopt; + + int pad2; + + std::map unknown_parameter; +} material_t; + +typedef struct { + std::string name; + + std::vector intValues; + std::vector floatValues; + std::vector stringValues; +} tag_t; + +// Index struct to support different indices for vtx/normal/texcoord. +// -1 means not used. +typedef struct { + int vertex_index; + int normal_index; + int texcoord_index; +} index_t; + +typedef struct { + std::vector indices; + std::vector num_face_vertices; // The number of vertices per + // face. 3 = polygon, 4 = quad, + // ... Up to 255. + std::vector material_ids; // per-face material ID + std::vector tags; // SubD tag +} mesh_t; + +typedef struct { + std::string name; + mesh_t mesh; +} shape_t; + +// Vertex attributes +typedef struct { + std::vector vertices; // 'v' + std::vector normals; // 'vn' + std::vector texcoords; // 'vt' +} attrib_t; + +typedef struct callback_t_ { + // W is optional and set to 1 if there is no `w` item in `v` line + void (*vertex_cb)(void *user_data, float x, float y, float z, float w); + void (*normal_cb)(void *user_data, float x, float y, float z); + + // y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in + // `vt` line. + void (*texcoord_cb)(void *user_data, float x, float y, float z); + + // called per 'f' line. num_indices is the number of face indices(e.g. 3 for + // triangle, 4 for quad) + // 0 will be passed for undefined index in index_t members. + void (*index_cb)(void *user_data, index_t *indices, int num_indices); + // `name` material name, `material_id` = the array index of material_t[]. -1 + // if + // a material not found in .mtl + void (*usemtl_cb)(void *user_data, const char *name, int material_id); + // `materials` = parsed material data. + void (*mtllib_cb)(void *user_data, const material_t *materials, + int num_materials); + // There may be multiple group names + void (*group_cb)(void *user_data, const char **names, int num_names); + void (*object_cb)(void *user_data, const char *name); + + callback_t_() + : vertex_cb(NULL), + normal_cb(NULL), + texcoord_cb(NULL), + index_cb(NULL), + usemtl_cb(NULL), + mtllib_cb(NULL), + group_cb(NULL), + object_cb(NULL) {} +} callback_t; + +class MaterialReader { + public: + MaterialReader() {} + virtual ~MaterialReader(); + + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) = 0; +}; + +class MaterialFileReader : public MaterialReader { + public: + explicit MaterialFileReader(const std::string &mtl_basedir) + : m_mtlBaseDir(mtl_basedir) {} + virtual ~MaterialFileReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *err); + + private: + std::string m_mtlBaseDir; +}; + +class MaterialStreamReader : public MaterialReader { + public: + explicit MaterialStreamReader(std::istream &inStream) + : m_inStream(inStream) {} + virtual ~MaterialStreamReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *err); + + private: + std::istream &m_inStream; +}; + +/// Loads .obj from a file. +/// 'attrib', 'shapes' and 'materials' will be filled with parsed shape data +/// 'shapes' will be filled with parsed shape data +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +/// 'mtl_basedir' is optional, and used for base directory for .mtl file. +/// In default(`NULL'), .mtl file is searched from an application's working directory. +/// 'triangulate' is optional, and used whether triangulate polygon face in .obj +/// or not. +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + const char *filename, const char *mtl_basedir = NULL, + bool triangulate = true); + +/// Loads .obj from a file with custom user callback. +/// .mtl is loaded as usual and parsed material_t data will be passed to +/// `callback.mtllib_cb`. +/// Returns true when loading .obj/.mtl become success. +/// Returns warning and error message into `err` +/// See `examples/callback_api/` for how to use this function. +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data = NULL, + MaterialReader *readMatFn = NULL, + std::string *err = NULL); + +/// Loads object from a std::istream, uses GetMtlIStreamFn to retrieve +/// std::istream for materials. +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + std::istream *inStream, MaterialReader *readMatFn = NULL, + bool triangulate = true); + +/// Loads materials into std::map +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream); + +} // namespace tinyobj + +#ifdef TINYOBJLOADER_IMPLEMENTATION +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace tinyobj { + +MaterialReader::~MaterialReader() {} + +#define TINYOBJ_SSCANF_BUFFER_SIZE (4096) + +struct vertex_index { + int v_idx, vt_idx, vn_idx; + vertex_index() : v_idx(-1), vt_idx(-1), vn_idx(-1) {} + explicit vertex_index(int idx) : v_idx(idx), vt_idx(idx), vn_idx(idx) {} + vertex_index(int vidx, int vtidx, int vnidx) + : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {} +}; + +struct tag_sizes { + tag_sizes() : num_ints(0), num_floats(0), num_strings(0) {} + int num_ints; + int num_floats; + int num_strings; +}; + +struct obj_shape { + std::vector v; + std::vector vn; + std::vector vt; +}; + +// See +// http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf +static std::istream &safeGetline(std::istream &is, std::string &t) { + t.clear(); + + // The characters in the stream are read one-by-one using a std::streambuf. + // That is faster than reading them one-by-one using the std::istream. + // Code that uses streambuf this way must be guarded by a sentry object. + // The sentry object performs various tasks, + // such as thread synchronization and updating the stream state. + + std::istream::sentry se(is, true); + std::streambuf *sb = is.rdbuf(); + + for (;;) { + int c = sb->sbumpc(); + switch (c) { + case '\n': + return is; + case '\r': + if (sb->sgetc() == '\n') sb->sbumpc(); + return is; + case EOF: + // Also handle the case when the last line has no line ending + if (t.empty()) is.setstate(std::ios::eofbit); + return is; + default: + t += static_cast(c); + } + } +} + +#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t')) +#define IS_DIGIT(x) \ + (static_cast((x) - '0') < static_cast(10)) +#define IS_NEW_LINE(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0')) + +// Make index zero-base, and also support relative index. +static inline int fixIndex(int idx, int n) { + if (idx > 0) return idx - 1; + if (idx == 0) return 0; + return n + idx; // negative value = relative +} + +static inline std::string parseString(const char **token) { + std::string s; + (*token) += strspn((*token), " \t"); + size_t e = strcspn((*token), " \t\r"); + s = std::string((*token), &(*token)[e]); + (*token) += e; + return s; +} + +static inline int parseInt(const char **token) { + (*token) += strspn((*token), " \t"); + int i = atoi((*token)); + (*token) += strcspn((*token), " \t\r"); + return i; +} + +// Tries to parse a floating point number located at s. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// Parses the following EBNF grammar: +// sign = "+" | "-" ; +// END = ? anything not in digit ? +// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +// integer = [sign] , digit , {digit} ; +// decimal = integer , ["." , integer] ; +// float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ; +// +// Valid strings are for example: +// -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2 +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +// The function is greedy and will parse until any of the following happens: +// - a non-conforming character is encountered. +// - s_end is reached. +// +// The following situations triggers a failure: +// - s >= s_end. +// - parse failure. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (s >= s_end) { + return false; + } + + double mantissa = 0.0; + // This exponent is base 2 rather than 10. + // However the exponent we parse is supposed to be one of ten, + // thus we must take care to convert the exponent/and or the + // mantissa to a * 2^E, where a is the mantissa and E is the + // exponent. + // To get the final double we will use ldexp, it requires the + // exponent to be in base 2. + int exponent = 0; + + // NOTE: THESE MUST BE DECLARED HERE SINCE WE ARE NOT ALLOWED + // TO JUMP OVER DEFINITIONS. + char sign = '+'; + char exp_sign = '+'; + char const *curr = s; + + // How many characters were read in a loop. + int read = 0; + // Tells whether a loop terminated due to reaching s_end. + bool end_not_reached = false; + + /* + BEGIN PARSING. + */ + + // Find out what sign we've got. + if (*curr == '+' || *curr == '-') { + sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + goto fail; + } + + // Read the integer part. + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + mantissa *= 10; + mantissa += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + + // We must make sure we actually got something. + if (read == 0) goto fail; + // We allow numbers of form "#", "###" etc. + if (!end_not_reached) goto assemble; + + // Read the decimal part. + if (*curr == '.') { + curr++; + read = 1; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + static const double pow_lut[] = { + 1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, + }; + const int lut_entries = sizeof pow_lut / sizeof pow_lut[0]; + + // NOTE: Don't use powf here, it will absolutely murder precision. + mantissa += static_cast(*curr - 0x30) * + (read < lut_entries ? pow_lut[read] : pow(10.0, -read)); + read++; + curr++; + end_not_reached = (curr != s_end); + } + } else if (*curr == 'e' || *curr == 'E') { + } else { + goto assemble; + } + + if (!end_not_reached) goto assemble; + + // Read the exponent part. + if (*curr == 'e' || *curr == 'E') { + curr++; + // Figure out if a sign is present and if it is. + end_not_reached = (curr != s_end); + if (end_not_reached && (*curr == '+' || *curr == '-')) { + exp_sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + // Empty E is not allowed. + goto fail; + } + + read = 0; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + exponent *= 10; + exponent += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + exponent *= (exp_sign == '+' ? 1 : -1); + if (read == 0) goto fail; + } + +assemble: + *result = + (sign == '+' ? 1 : -1) * + (exponent ? ldexp(mantissa * pow(5.0, exponent), exponent) : mantissa); + return true; +fail: + return false; +} + +static inline float parseFloat(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + float f = static_cast(val); + (*token) = end; + return f; +} + +static inline void parseFloat2(float *x, float *y, const char **token, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = parseFloat(token, default_x); + (*y) = parseFloat(token, default_y); +} + +static inline void parseFloat3(float *x, float *y, float *z, const char **token, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseFloat(token, default_x); + (*y) = parseFloat(token, default_y); + (*z) = parseFloat(token, default_z); +} + +static inline void parseV(float *x, float *y, float *z, float *w, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0, + const double default_w = 1.0) { + (*x) = parseFloat(token, default_x); + (*y) = parseFloat(token, default_y); + (*z) = parseFloat(token, default_z); + (*w) = parseFloat(token, default_w); +} + +static inline bool parseOnOff(const char **token, bool default_value = true) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + + bool ret = default_value; + if ((0 == strncmp((*token), "on", 2))) { + ret = true; + } else if ((0 == strncmp((*token), "off", 3))) { + ret = false; + } + + (*token) = end; + return ret; +} + +static inline texture_type_t parseTextureType( + const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + texture_type_t ty = default_value; + + if ((0 == strncmp((*token), "cube_top", strlen("cube_top")))) { + ty = TEXTURE_TYPE_CUBE_TOP; + } else if ((0 == strncmp((*token), "cube_bottom", strlen("cube_bottom")))) { + ty = TEXTURE_TYPE_CUBE_BOTTOM; + } else if ((0 == strncmp((*token), "cube_left", strlen("cube_left")))) { + ty = TEXTURE_TYPE_CUBE_LEFT; + } else if ((0 == strncmp((*token), "cube_right", strlen("cube_right")))) { + ty = TEXTURE_TYPE_CUBE_RIGHT; + } else if ((0 == strncmp((*token), "cube_front", strlen("cube_front")))) { + ty = TEXTURE_TYPE_CUBE_FRONT; + } else if ((0 == strncmp((*token), "cube_back", strlen("cube_back")))) { + ty = TEXTURE_TYPE_CUBE_BACK; + } else if ((0 == strncmp((*token), "sphere", strlen("sphere")))) { + ty = TEXTURE_TYPE_SPHERE; + } + + (*token) = end; + return ty; +} + +static tag_sizes parseTagTriple(const char **token) { + tag_sizes ts; + + ts.num_ints = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; + + ts.num_floats = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; + + ts.num_strings = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r") + 1; + + return ts; +} + +// Parse triples with index offsets: i, i/j/k, i//k, i/j +static vertex_index parseTriple(const char **token, int vsize, int vnsize, + int vtsize) { + vertex_index vi(-1); + + vi.v_idx = fixIndex(atoi((*token)), vsize); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = fixIndex(atoi((*token)), vnsize); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = fixIndex(atoi((*token)), vtsize); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = fixIndex(atoi((*token)), vnsize); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +// Parse raw triples: i, i/j/k, i//k, i/j +static vertex_index parseRawTriple(const char **token) { + vertex_index vi(static_cast(0)); // 0 is an invalid index in OBJ + + vi.v_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +static bool ParseTextureNameAndOption(std::string *texname, + texture_option_t *texopt, + const char *linebuf, const bool is_bump) { + // @todo { write more robust lexer and parser. } + bool found_texname = false; + std::string texture_name; + + // Fill with default value for texopt. + if (is_bump) { + texopt->imfchan = 'l'; + } else { + texopt->imfchan = 'm'; + } + texopt->bump_multiplier = 1.0f; + texopt->clamp = false; + texopt->blendu = true; + texopt->blendv = true; + texopt->sharpness = 1.0f; + texopt->brightness = 0.0f; + texopt->contrast = 1.0f; + texopt->origin_offset[0] = 0.0f; + texopt->origin_offset[1] = 0.0f; + texopt->origin_offset[2] = 0.0f; + texopt->scale[0] = 1.0f; + texopt->scale[1] = 1.0f; + texopt->scale[2] = 1.0f; + texopt->turbulence[0] = 0.0f; + texopt->turbulence[1] = 0.0f; + texopt->turbulence[2] = 0.0f; + texopt->type = TEXTURE_TYPE_NONE; + + const char *token = linebuf; // Assume line ends with NULL + + while (!IS_NEW_LINE((*token))) { + if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendu = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendv = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->clamp = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->sharpness = parseFloat(&token, 1.0); + } else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) { + token += 4; + texopt->bump_multiplier = parseFloat(&token, 1.0); + } else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseFloat3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]), + &(texopt->origin_offset[2]), &token); + } else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseFloat3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]), + &token, 1.0, 1.0, 1.0); + } else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseFloat3(&(texopt->turbulence[0]), &(texopt->turbulence[1]), + &(texopt->turbulence[2]), &token); + } else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) { + token += 5; + texopt->type = parseTextureType((&token), TEXTURE_TYPE_NONE); + } else if ((0 == strncmp(token, "-imfchan", 8)) && IS_SPACE((token[8]))) { + token += 9; + token += strspn(token, " \t"); + const char *end = token + strcspn(token, " \t\r"); + if ((end - token) == 1) { // Assume one char for -imfchan + texopt->imfchan = (*token); + } + token = end; + } else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) { + token += 4; + parseFloat2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0); + } else { + // Assume texture filename + token += strspn(token, " \t"); // skip space + size_t len = strcspn(token, " \t\r"); // untile next space + texture_name = std::string(token, token + len); + token += len; + + token += strspn(token, " \t"); // skip space + + found_texname = true; + } + } + + if (found_texname) { + (*texname) = texture_name; + return true; + } else { + return false; + } +} + +static void InitMaterial(material_t *material) { + material->name = ""; + material->ambient_texname = ""; + material->diffuse_texname = ""; + material->specular_texname = ""; + material->specular_highlight_texname = ""; + material->bump_texname = ""; + material->displacement_texname = ""; + material->alpha_texname = ""; + for (int i = 0; i < 3; i++) { + material->ambient[i] = 0.f; + material->diffuse[i] = 0.f; + material->specular[i] = 0.f; + material->transmittance[i] = 0.f; + material->emission[i] = 0.f; + } + material->illum = 0; + material->dissolve = 1.f; + material->shininess = 1.f; + material->ior = 1.f; + + material->roughness = 0.f; + material->metallic = 0.f; + material->sheen = 0.f; + material->clearcoat_thickness = 0.f; + material->clearcoat_roughness = 0.f; + material->anisotropy_rotation = 0.f; + material->anisotropy = 0.f; + material->roughness_texname = ""; + material->metallic_texname = ""; + material->sheen_texname = ""; + material->emissive_texname = ""; + material->normal_texname = ""; + + material->unknown_parameter.clear(); +} + +static bool exportFaceGroupToShape( + shape_t *shape, const std::vector > &faceGroup, + const std::vector &tags, const int material_id, + const std::string &name, bool triangulate) { + if (faceGroup.empty()) { + return false; + } + + // Flatten vertices and indices + for (size_t i = 0; i < faceGroup.size(); i++) { + const std::vector &face = faceGroup[i]; + + vertex_index i0 = face[0]; + vertex_index i1(-1); + vertex_index i2 = face[1]; + + size_t npolys = face.size(); + + if (triangulate) { + // Polygon -> triangle fan conversion + for (size_t k = 2; k < npolys; k++) { + i1 = i2; + i2 = face[k]; + + index_t idx0, idx1, idx2; + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + } + } else { + for (size_t k = 0; k < npolys; k++) { + index_t idx; + idx.vertex_index = face[k].v_idx; + idx.normal_index = face[k].vn_idx; + idx.texcoord_index = face[k].vt_idx; + shape->mesh.indices.push_back(idx); + } + + shape->mesh.num_face_vertices.push_back( + static_cast(npolys)); + shape->mesh.material_ids.push_back(material_id); // per face + } + } + + shape->name = name; + shape->mesh.tags = tags; + + return true; +} + +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream) { + // Create a default material anyway. + material_t material; + InitMaterial(&material); + + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + // Trim trailing whitespace. + if (linebuf.size() > 0) { + linebuf = linebuf.substr(0, linebuf.find_last_not_of(" \t") + 1); + } + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // new mtl + if ((0 == strncmp(token, "newmtl", 6)) && IS_SPACE((token[6]))) { + // flush previous material. + if (!material.name.empty()) { + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + } + + // initial temporary material + InitMaterial(&material); + + // set new mtl name + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + material.name = namebuf; + continue; + } + + // ambient + if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.ambient[0] = r; + material.ambient[1] = g; + material.ambient[2] = b; + continue; + } + + // diffuse + if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.diffuse[0] = r; + material.diffuse[1] = g; + material.diffuse[2] = b; + continue; + } + + // specular + if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.specular[0] = r; + material.specular[1] = g; + material.specular[2] = b; + continue; + } + + // transmittance + if ((token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) || + (token[0] == 'T' && token[1] == 'f' && IS_SPACE((token[2])))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.transmittance[0] = r; + material.transmittance[1] = g; + material.transmittance[2] = b; + continue; + } + + // ior(index of refraction) + if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) { + token += 2; + material.ior = parseFloat(&token); + continue; + } + + // emission + if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.emission[0] = r; + material.emission[1] = g; + material.emission[2] = b; + continue; + } + + // shininess + if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.shininess = parseFloat(&token); + continue; + } + + // illum model + if (0 == strncmp(token, "illum", 5) && IS_SPACE(token[5])) { + token += 6; + material.illum = parseInt(&token); + continue; + } + + // dissolve + if ((token[0] == 'd' && IS_SPACE(token[1]))) { + token += 1; + material.dissolve = parseFloat(&token); + continue; + } + if (token[0] == 'T' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + // Invert value of Tr(assume Tr is in range [0, 1]) + material.dissolve = 1.0f - parseFloat(&token); + continue; + } + + // PBR: roughness + if (token[0] == 'P' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + material.roughness = parseFloat(&token); + continue; + } + + // PBR: metallic + if (token[0] == 'P' && token[1] == 'm' && IS_SPACE(token[2])) { + token += 2; + material.metallic = parseFloat(&token); + continue; + } + + // PBR: sheen + if (token[0] == 'P' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.sheen = parseFloat(&token); + continue; + } + + // PBR: clearcoat thickness + if (token[0] == 'P' && token[1] == 'c' && IS_SPACE(token[2])) { + token += 2; + material.clearcoat_thickness = parseFloat(&token); + continue; + } + + // PBR: clearcoat roughness + if ((0 == strncmp(token, "Pcr", 3)) && IS_SPACE(token[3])) { + token += 4; + material.clearcoat_roughness = parseFloat(&token); + continue; + } + + // PBR: anisotropy + if ((0 == strncmp(token, "aniso", 5)) && IS_SPACE(token[5])) { + token += 6; + material.anisotropy = parseFloat(&token); + continue; + } + + // PBR: anisotropy rotation + if ((0 == strncmp(token, "anisor", 6)) && IS_SPACE(token[6])) { + token += 7; + material.anisotropy_rotation = parseFloat(&token); + continue; + } + + // ambient texture + if ((0 == strncmp(token, "map_Ka", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.ambient_texname), + &(material.ambient_texopt), token, + /* is_bump */ false); + continue; + } + + // diffuse texture + if ((0 == strncmp(token, "map_Kd", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.diffuse_texname), + &(material.diffuse_texopt), token, + /* is_bump */ false); + continue; + } + + // specular texture + if ((0 == strncmp(token, "map_Ks", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_texname), + &(material.specular_texopt), token, + /* is_bump */ false); + continue; + } + + // specular highlight texture + if ((0 == strncmp(token, "map_Ns", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_highlight_texname), + &(material.specular_highlight_texopt), token, + /* is_bump */ false); + continue; + } + + // bump texture + if ((0 == strncmp(token, "map_bump", 8)) && IS_SPACE(token[8])) { + token += 9; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // bump texture + if ((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // alpha texture + if ((0 == strncmp(token, "map_d", 5)) && IS_SPACE(token[5])) { + token += 6; + material.alpha_texname = token; + ParseTextureNameAndOption(&(material.alpha_texname), + &(material.alpha_texopt), token, + /* is_bump */ false); + continue; + } + + // displacement texture + if ((0 == strncmp(token, "disp", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: roughness texture + if ((0 == strncmp(token, "map_Pr", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.roughness_texname), + &(material.roughness_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: metallic texture + if ((0 == strncmp(token, "map_Pm", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.metallic_texname), + &(material.metallic_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: sheen texture + if ((0 == strncmp(token, "map_Ps", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.sheen_texname), + &(material.sheen_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: emissive texture + if ((0 == strncmp(token, "map_Ke", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.emissive_texname), + &(material.emissive_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: normal map texture + if ((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption( + &(material.normal_texname), &(material.normal_texopt), token, + /* is_bump */ false); // @fixme { is_bump will be true? } + continue; + } + + // unknown parameter + const char *_space = strchr(token, ' '); + if (!_space) { + _space = strchr(token, '\t'); + } + if (_space) { + std::ptrdiff_t len = _space - token; + std::string key(token, static_cast(len)); + std::string value = _space + 1; + material.unknown_parameter.insert( + std::pair(key, value)); + } + } + // flush last material. + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); +} + +bool MaterialFileReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) { + std::string filepath; + + if (!m_mtlBaseDir.empty()) { + filepath = std::string(m_mtlBaseDir) + matId; + } else { + filepath = matId; + } + + std::ifstream matIStream(filepath.c_str()); + LoadMtl(matMap, materials, &matIStream); + if (!matIStream) { + std::stringstream ss; + ss << "WARN: Material file [ " << filepath + << " ] not found. Created a default material."; + if (err) { + (*err) += ss.str(); + } + } + return true; +} + +bool MaterialStreamReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) { + (void)matId; + LoadMtl(matMap, materials, &m_inStream); + if (!m_inStream) { + std::stringstream ss; + ss << "WARN: Material stream in error state." + << " Created a default material."; + if (err) { + (*err) += ss.str(); + } + } + return true; +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + const char *filename, const char *mtl_basedir, + bool trianglulate) { + attrib->vertices.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + shapes->clear(); + + std::stringstream errss; + + std::ifstream ifs(filename); + if (!ifs) { + errss << "Cannot open file [" << filename << "]" << std::endl; + if (err) { + (*err) = errss.str(); + } + return false; + } + + std::string baseDir; + if (mtl_basedir) { + baseDir = mtl_basedir; + } + MaterialFileReader matFileReader(baseDir); + + return LoadObj(attrib, shapes, materials, err, &ifs, &matFileReader, + trianglulate); +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + std::istream *inStream, MaterialReader *readMatFn /*= NULL*/, + bool triangulate) { + std::stringstream errss; + + std::vector v; + std::vector vn; + std::vector vt; + std::vector tags; + std::vector > faceGroup; + std::string name; + + // material + std::map material_map; + int material = -1; + + shape_t shape; + + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + float x, y, z; + parseFloat3(&x, &y, &z, &token); + v.push_back(x); + v.push_back(y); + v.push_back(z); + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + float x, y, z; + parseFloat3(&x, &y, &z, &token); + vn.push_back(x); + vn.push_back(y); + vn.push_back(z); + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + float x, y; + parseFloat2(&x, &y, &token); + vt.push_back(x); + vt.push_back(y); + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + std::vector face; + face.reserve(3); + + while (!IS_NEW_LINE(token[0])) { + vertex_index vi = parseTriple(&token, static_cast(v.size() / 3), + static_cast(vn.size() / 3), + static_cast(vt.size() / 2)); + face.push_back(vi); + size_t n = strspn(token, " \t\r"); + token += n; + } + + // replace with emplace_back + std::move on C++11 + faceGroup.push_back(std::vector()); + faceGroup[faceGroup.size() - 1].swap(face); + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material) { + // Create per-face material. Thus we don't add `shape` to `shapes` at + // this time. + // just clear `faceGroup` after `exportFaceGroupToShape()` call. + exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + faceGroup.clear(); + material = newMaterialId; + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + + std::string err_mtl; + bool ok = (*readMatFn)(namebuf, materials, &material_map, &err_mtl); + if (err) { + (*err) += err_mtl; + } + + if (!ok) { + faceGroup.clear(); // for safety + return false; + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + if (ret) { + shapes->push_back(shape); + } + + shape = shape_t(); + + // material = -1; + faceGroup.clear(); + + std::vector names; + names.reserve(2); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + // names[0] must be 'g', so skip the 0th element. + if (names.size() > 1) { + name = names[1]; + } else { + name = ""; + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + if (ret) { + shapes->push_back(shape); + } + + // material = -1; + faceGroup.clear(); + shape = shape_t(); + + // @todo { multiple object name? } + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + name = std::string(namebuf); + + continue; + } + + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + char namebuf[4096]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + tag.name = std::string(namebuf); + + token += tag.name.size() + 1; + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = atoi(token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.floatValues.resize(static_cast(ts.num_floats)); + for (size_t i = 0; i < static_cast(ts.num_floats); ++i) { + tag.floatValues[i] = parseFloat(&token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + char stringValueBuffer[4096]; + +#ifdef _MSC_VER + sscanf_s(token, "%s", stringValueBuffer, + (unsigned)_countof(stringValueBuffer)); +#else + sscanf(token, "%s", stringValueBuffer); +#endif + tag.stringValues[i] = stringValueBuffer; + token += tag.stringValues[i].size() + 1; + } + + tags.push_back(tag); + } + + // Ignore unknown command. + } + + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + // exportFaceGroupToShape return false when `usemtl` is called in the last + // line. + // we also add `shape` to `shapes` when `shape.mesh` has already some + // faces(indices) + if (ret || shape.mesh.indices.size()) { + shapes->push_back(shape); + } + faceGroup.clear(); // for safety + + if (err) { + (*err) += errss.str(); + } + + attrib->vertices.swap(v); + attrib->normals.swap(vn); + attrib->texcoords.swap(vt); + + return true; +} + +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data /*= NULL*/, + MaterialReader *readMatFn /*= NULL*/, + std::string *err /*= NULL*/) { + std::stringstream errss; + + // material + std::map material_map; + int material_id = -1; // -1 = invalid + + std::vector indices; + std::vector materials; + std::vector names; + names.reserve(2); + std::string name; + std::vector names_out; + + std::string linebuf; + while (inStream.peek() != -1) { + safeGetline(inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + float x, y, z, w; // w is optional. default = 1.0 + parseV(&x, &y, &z, &w, &token); + if (callback.vertex_cb) { + callback.vertex_cb(user_data, x, y, z, w); + } + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + float x, y, z; + parseFloat3(&x, &y, &z, &token); + if (callback.normal_cb) { + callback.normal_cb(user_data, x, y, z); + } + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + float x, y, z; // y and z are optional. default = 0.0 + parseFloat3(&x, &y, &z, &token); + if (callback.texcoord_cb) { + callback.texcoord_cb(user_data, x, y, z); + } + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + indices.clear(); + while (!IS_NEW_LINE(token[0])) { + vertex_index vi = parseRawTriple(&token); + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + indices.push_back(idx); + size_t n = strspn(token, " \t\r"); + token += n; + } + + if (callback.index_cb && indices.size() > 0) { + callback.index_cb(user_data, &indices.at(0), + static_cast(indices.size())); + } + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, + static_cast(_countof(namebuf))); +#else + sscanf(token, "%s", namebuf); +#endif + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material_id) { + material_id = newMaterialId; + } + + if (callback.usemtl_cb) { + callback.usemtl_cb(user_data, namebuf, material_id); + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + + std::string err_mtl; + materials.clear(); + bool ok = (*readMatFn)(namebuf, &materials, &material_map, &err_mtl); + if (err) { + (*err) += err_mtl; + } + + if (!ok) { + return false; + } + + if (callback.mtllib_cb) { + callback.mtllib_cb(user_data, &materials.at(0), + static_cast(materials.size())); + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + names.clear(); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + // names[0] must be 'g', so skip the 0th element. + if (names.size() > 1) { + name = names[1]; + } else { + name.clear(); + } + + if (callback.group_cb) { + if (names.size() > 1) { + // create const char* array. + names_out.resize(names.size() - 1); + for (size_t j = 0; j < names_out.size(); j++) { + names_out[j] = names[j + 1].c_str(); + } + callback.group_cb(user_data, &names_out.at(0), + static_cast(names_out.size())); + + } else { + callback.group_cb(user_data, NULL, 0); + } + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // @todo { multiple object name? } + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + std::string object_name = std::string(namebuf); + + if (callback.object_cb) { + callback.object_cb(user_data, object_name.c_str()); + } + + continue; + } + +#if 0 // @todo + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + char namebuf[4096]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + tag.name = std::string(namebuf); + + token += tag.name.size() + 1; + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = atoi(token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.floatValues.resize(static_cast(ts.num_floats)); + for (size_t i = 0; i < static_cast(ts.num_floats); ++i) { + tag.floatValues[i] = parseFloat(&token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + char stringValueBuffer[4096]; + +#ifdef _MSC_VER + sscanf_s(token, "%s", stringValueBuffer, + (unsigned)_countof(stringValueBuffer)); +#else + sscanf(token, "%s", stringValueBuffer); +#endif + tag.stringValues[i] = stringValueBuffer; + token += tag.stringValues[i].size() + 1; + } + + tags.push_back(tag); + } +#endif + + // Ignore unknown command. + } + + if (err) { + (*err) += errss.str(); + } + + return true; +} +} // namespace tinyobj + +#endif + +#endif // TINY_OBJ_LOADER_H_ diff --git a/L09.zip b/L09.zip new file mode 100644 index 0000000..2b99cf2 Binary files /dev/null and b/L09.zip differ diff --git a/L09/CMakeLists.txt b/L09/CMakeLists.txt new file mode 100644 index 0000000..62008b8 --- /dev/null +++ b/L09/CMakeLists.txt @@ -0,0 +1,127 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +# Name of the project +PROJECT(L09) + +# FOR LAB MACHINES ONLY! +# DO NOT EDIT +SET(DEF_DIR_GLM "C:\\c++\\glm") +SET(DEF_DIR_GLFW "C:\\c++\\glfw-3.2.1") +SET(DEF_DIR_GLEW "C:\\c++\\glew-2.0.0") + +# Is this the solution? +# Override with `cmake -DSOL=ON ..` +OPTION(SOL "Solution" OFF) + +# Use glob to get the list of all source files. +# We don't really need to include header and resource files to build, but it's +# nice to have them also show up in IDEs. +IF(${SOL}) + FILE(GLOB_RECURSE SOURCES "src0/*.cpp") + FILE(GLOB_RECURSE HEADERS "src0/*.h") + FILE(GLOB_RECURSE GLSL "resources0/*.glsl") +ELSE() + FILE(GLOB_RECURSE SOURCES "src/*.cpp") + FILE(GLOB_RECURSE HEADERS "src/*.h") + FILE(GLOB_RECURSE GLSL "resources/*.glsl") +ENDIF() + +# Set the executable. +ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCES} ${HEADERS} ${GLSL}) + +# Get the GLM environment variable. Since GLM is a header-only library, we +# just need to add it to the include directory. +SET(GLM_INCLUDE_DIR "$ENV{GLM_INCLUDE_DIR}") +IF(NOT GLM_INCLUDE_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLM_INCLUDE_DIR to the root directory of your GLM installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLM in ${DEF_DIR_GLM}") + IF(IS_DIRECTORY ${DEF_DIR_GLM}) + MESSAGE(STATUS "Found!") + SET(GLM_INCLUDE_DIR ${DEF_DIR_GLM}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +INCLUDE_DIRECTORIES(${GLM_INCLUDE_DIR}) + +# Get the GLFW environment variable. There should be a CMakeLists.txt in the +# specified directory. +SET(GLFW_DIR "$ENV{GLFW_DIR}") +IF(NOT GLFW_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLFW_DIR to the root directory of your GLFW installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLFW in ${DEF_DIR_GLFW}") + IF(IS_DIRECTORY ${DEF_DIR_GLFW}) + MESSAGE(STATUS "Found!") + SET(GLFW_DIR ${DEF_DIR_GLFW}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +OPTION(GLFW_BUILD_EXAMPLES "GLFW_BUILD_EXAMPLES" OFF) +OPTION(GLFW_BUILD_TESTS "GLFW_BUILD_TESTS" OFF) +OPTION(GLFW_BUILD_DOCS "GLFW_BUILD_DOCS" OFF) +IF(CMAKE_BUILD_TYPE MATCHES Release) + ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/release) +ELSE() + ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/debug) +ENDIF() +INCLUDE_DIRECTORIES(${GLFW_DIR}/include) +TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} glfw ${GLFW_LIBRARIES}) + +# Get the GLEW environment variable. +SET(GLEW_DIR "$ENV{GLEW_DIR}") +IF(NOT GLEW_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLEW_DIR to the root directory of your GLEW installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLEW in ${DEF_DIR_GLEW}") + IF(IS_DIRECTORY ${DEF_DIR_GLEW}) + MESSAGE(STATUS "Found!") + SET(GLEW_DIR ${DEF_DIR_GLEW}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +INCLUDE_DIRECTORIES(${GLEW_DIR}/include) +IF(WIN32) + # With prebuilt binaries + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/Release/Win32/glew32s.lib) +ELSE() + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/libGLEW.a) +ENDIF() + +# OS specific options and libraries +IF(WIN32) + # c++11 is enabled by default. + # -Wall produces way too many warnings. + # -pedantic is not supported. + # Disable warning 4996. + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996") + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} opengl32.lib) +ELSE() + # Enable all pedantic warnings. + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic") + IF(APPLE) + # Add required frameworks for GLFW. + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo") + ELSE() + #Link the Linux OpenGL library + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "GL") + ENDIF() +ENDIF() diff --git a/L09/resources/frag.glsl b/L09/resources/frag.glsl new file mode 100644 index 0000000..9b1dad9 --- /dev/null +++ b/L09/resources/frag.glsl @@ -0,0 +1,14 @@ +#version 120 + +uniform sampler2D texture0; +uniform sampler2D texture1; + +varying vec2 vTex0; +varying vec2 vTex1; + +void main() +{ + vec4 color0 = texture2D(texture0, vTex0); + //vec4 color1 = texture2D(texture1, vTex1); + gl_FragColor = color0; +} diff --git a/L09/resources/reveille.jpg b/L09/resources/reveille.jpg new file mode 100644 index 0000000..91113b5 Binary files /dev/null and b/L09/resources/reveille.jpg differ diff --git a/L09/resources/tamu.jpg b/L09/resources/tamu.jpg new file mode 100644 index 0000000..bff403e Binary files /dev/null and b/L09/resources/tamu.jpg differ diff --git a/L09/resources/vert.glsl b/L09/resources/vert.glsl new file mode 100644 index 0000000..4d7827f --- /dev/null +++ b/L09/resources/vert.glsl @@ -0,0 +1,18 @@ +#version 120 + +uniform mat4 P; +uniform mat4 MV; +uniform mat3 T1; + +attribute vec4 aPos; +attribute vec2 aTex; + +varying vec2 vTex0; +varying vec2 vTex1; + +void main() +{ + gl_Position = P * MV * aPos; + vTex0 = aTex; + vTex1 = aTex; +} diff --git a/L09/src/Camera.cpp b/L09/src/Camera.cpp new file mode 100644 index 0000000..55114ae --- /dev/null +++ b/L09/src/Camera.cpp @@ -0,0 +1,68 @@ +#include "Camera.h" +#include "MatrixStack.h" +#include +#define _USE_MATH_DEFINES +#include +#include + +Camera::Camera() : + aspect(1.0f), + fovy((float)(45.0*M_PI/180.0)), + znear(0.1f), + zfar(1000.0f), + rotations(0.0, 0.0), + translations(0.0f, 0.0f, -5.0f), + rfactor(0.01f), + tfactor(0.001f), + sfactor(0.005f) +{ +} + +Camera::~Camera() +{ +} + +void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt) +{ + mousePrev.x = x; + mousePrev.y = y; + if(shift) { + state = Camera::TRANSLATE; + } else if(ctrl) { + state = Camera::SCALE; + } else { + state = Camera::ROTATE; + } +} + +void Camera::mouseMoved(float x, float y) +{ + glm::vec2 mouseCurr(x, y); + glm::vec2 dv = mouseCurr - mousePrev; + switch(state) { + case Camera::ROTATE: + rotations += rfactor * dv; + break; + case Camera::TRANSLATE: + translations.x -= translations.z * tfactor * dv.x; + translations.y += translations.z * tfactor * dv.y; + break; + case Camera::SCALE: + translations.z *= (1.0f - sfactor * dv.y); + break; + } + mousePrev = mouseCurr; +} + +void Camera::applyProjectionMatrix(std::shared_ptr P) const +{ + // Modify provided MatrixStack + P->multMatrix(glm::perspective(fovy, aspect, znear, zfar)); +} + +void Camera::applyViewMatrix(std::shared_ptr MV) const +{ + MV->translate(translations); + MV->rotate(rotations.y, glm::vec3(1.0f, 0.0f, 0.0f)); + MV->rotate(rotations.x, glm::vec3(0.0f, 1.0f, 0.0f)); +} diff --git a/L09/src/Camera.h b/L09/src/Camera.h new file mode 100644 index 0000000..8501605 --- /dev/null +++ b/L09/src/Camera.h @@ -0,0 +1,47 @@ +#pragma once +#ifndef __Camera__ +#define __Camera__ + +#include + +#define GLM_FORCE_RADIANS +#include + +class MatrixStack; + +class Camera +{ +public: + enum { + ROTATE = 0, + TRANSLATE, + SCALE + }; + + Camera(); + virtual ~Camera(); + void setInitDistance(float z) { translations.z = -std::abs(z); } + void setAspect(float a) { aspect = a; }; + void setRotationFactor(float f) { rfactor = f; }; + void setTranslationFactor(float f) { tfactor = f; }; + void setScaleFactor(float f) { sfactor = f; }; + void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt); + void mouseMoved(float x, float y); + void applyProjectionMatrix(std::shared_ptr P) const; + void applyViewMatrix(std::shared_ptr MV) const; + +private: + float aspect; + float fovy; + float znear; + float zfar; + glm::vec2 rotations; + glm::vec3 translations; + glm::vec2 mousePrev; + int state; + float rfactor; + float tfactor; + float sfactor; +}; + +#endif diff --git a/L09/src/GLSL.cpp b/L09/src/GLSL.cpp new file mode 100644 index 0000000..2969872 --- /dev/null +++ b/L09/src/GLSL.cpp @@ -0,0 +1,152 @@ +// +// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book +// Created by zwood on 2/21/10. +// Modified by sueda 10/15/15. +// + +#include "GLSL.h" +#include +#include +#include +#include + +using namespace std; + +namespace GLSL { + +const char * errorString(GLenum err) +{ + switch(err) { + case GL_NO_ERROR: + return "No error"; + case GL_INVALID_ENUM: + return "Invalid enum"; + case GL_INVALID_VALUE: + return "Invalid value"; + case GL_INVALID_OPERATION: + return "Invalid operation"; + case GL_STACK_OVERFLOW: + return "Stack overflow"; + case GL_STACK_UNDERFLOW: + return "Stack underflow"; + case GL_OUT_OF_MEMORY: + return "Out of memory"; + default: + return "No error"; + } +} + +void checkVersion() +{ + int major, minor; + major = minor = 0; + const char *verstr = (const char *)glGetString(GL_VERSION); + + if((verstr == NULL) || (sscanf(verstr, "%d.%d", &major, &minor) != 2)) { + printf("Invalid GL_VERSION format %d.%d\n", major, minor); + } + if(major < 2) { + printf("This shader example will not work due to the installed Opengl version, which is %d.%d.\n", major, minor); + exit(0); + } +} + +void checkError(const char *str) +{ + GLenum glErr = glGetError(); + if(glErr != GL_NO_ERROR) { + if(str) { + printf("%s: ", str); + } + printf("GL_ERROR = %s.\n", errorString(glErr)); + assert(false); + } +} + +void printShaderInfoLog(GLuint shader) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog = 0; + + checkError(GET_FILE_LINE); + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength); + checkError(GET_FILE_LINE); + + if(infologLength > 0) { + infoLog = (GLchar *)malloc(infologLength); + if(infoLog == NULL) { + puts("ERROR: Could not allocate InfoLog buffer"); + exit(1); + } + glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog); + checkError(GET_FILE_LINE); + printf("Shader InfoLog:\n%s\n\n", infoLog); + free(infoLog); + } +} + +void printProgramInfoLog(GLuint program) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog = 0; + + checkError(GET_FILE_LINE); + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infologLength); + checkError(GET_FILE_LINE); + + if(infologLength > 0) { + infoLog = (GLchar *)malloc(infologLength); + if(infoLog == NULL) { + puts("ERROR: Could not allocate InfoLog buffer"); + exit(1); + } + glGetProgramInfoLog(program, infologLength, &charsWritten, infoLog); + checkError(GET_FILE_LINE); + printf("Program InfoLog:\n%s\n\n", infoLog); + free(infoLog); + } +} + +char *textFileRead(const char *fn) +{ + FILE *fp; + char *content = NULL; + int count = 0; + if(fn != NULL) { + fp = fopen(fn,"rt"); + if(fp != NULL) { + fseek(fp, 0, SEEK_END); + count = (int)ftell(fp); + rewind(fp); + if(count > 0) { + content = (char *)malloc(sizeof(char) * (count+1)); + count = (int)fread(content,sizeof(char),count,fp); + content[count] = '\0'; + } + fclose(fp); + } else { + printf("error loading %s\n", fn); + } + } + return content; +} + +int textFileWrite(const char *fn, const char *s) +{ + FILE *fp; + int status = 0; + if(fn != NULL) { + fp = fopen(fn,"w"); + if(fp != NULL) { + if(fwrite(s,sizeof(char),strlen(s),fp) == strlen(s)) { + status = 1; + } + fclose(fp); + } + } + return(status); +} + +} diff --git a/L09/src/GLSL.h b/L09/src/GLSL.h new file mode 100644 index 0000000..f945fdd --- /dev/null +++ b/L09/src/GLSL.h @@ -0,0 +1,40 @@ +// +// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book +// Created by zwood on 2/21/10. +// Modified by sueda 10/15/15. +// + +#pragma once +#ifndef __GLSL__ +#define __GLSL__ + +#define GLEW_STATIC +#include + +/////////////////////////////////////////////////////////////////////////////// +// For printing out the current file and line number // +/////////////////////////////////////////////////////////////////////////////// +#include + +template +std::string NumberToString(T x) +{ + std::ostringstream ss; + ss << x; + return ss.str(); +} + +#define GET_FILE_LINE (std::string(__FILE__) + ":" + NumberToString(__LINE__)).c_str() +/////////////////////////////////////////////////////////////////////////////// + +namespace GLSL { + + void checkVersion(); + void checkError(const char *str = 0); + void printProgramInfoLog(GLuint program); + void printShaderInfoLog(GLuint shader); + int textFileWrite(const char *filename, const char *s); + char *textFileRead(const char *filename); +} + +#endif diff --git a/L09/src/MatrixStack.cpp b/L09/src/MatrixStack.cpp new file mode 100644 index 0000000..eaa6e6c --- /dev/null +++ b/L09/src/MatrixStack.cpp @@ -0,0 +1,114 @@ +#include "MatrixStack.h" + +#include +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +using namespace std; + +MatrixStack::MatrixStack() +{ + mstack = make_shared< stack >(); + mstack->push(glm::mat4(1.0)); +} + +MatrixStack::~MatrixStack() +{ +} + +void MatrixStack::pushMatrix() +{ + const glm::mat4 &top = mstack->top(); + mstack->push(top); + assert(mstack->size() < 100); +} + +void MatrixStack::popMatrix() +{ + assert(!mstack->empty()); + mstack->pop(); + // There should always be one matrix left. + assert(!mstack->empty()); +} + +void MatrixStack::loadIdentity() +{ + glm::mat4 &top = mstack->top(); + top = glm::mat4(1.0); +} + +void MatrixStack::translate(const glm::vec3 &t) +{ + glm::mat4 &top = mstack->top(); + top *= glm::translate(t); +} + +void MatrixStack::translate(float x, float y, float z) +{ + translate(glm::vec3(x, y, z)); +} + +void MatrixStack::scale(const glm::vec3 &s) +{ + glm::mat4 &top = mstack->top(); + top *= glm::scale(s); +} + +void MatrixStack::scale(float x, float y, float z) +{ + scale(glm::vec3(x, y, z)); +} + +void MatrixStack::scale(float s) +{ + scale(glm::vec3(s, s, s)); +} + +void MatrixStack::rotate(float angle, const glm::vec3 &axis) +{ + glm::mat4 &top = mstack->top(); + top *= glm::rotate(angle, axis); +} + +void MatrixStack::rotate(float angle, float x, float y, float z) +{ + rotate(angle, glm::vec3(x, y, z)); +} + +void MatrixStack::multMatrix(const glm::mat4 &matrix) +{ + glm::mat4 &top = mstack->top(); + top *= matrix; +} + +const glm::mat4 &MatrixStack::topMatrix() const +{ + return mstack->top(); +} + +void MatrixStack::print(const glm::mat4 &mat, const char *name) +{ + if(name) { + printf("%s = [\n", name); + } + for(int i = 0; i < 4; ++i) { + for(int j = 0; j < 4; ++j) { + // mat[j] returns the jth column + printf("%- 5.2f ", mat[j][i]); + } + printf("\n"); + } + if(name) { + printf("];"); + } + printf("\n"); +} + +void MatrixStack::print(const char *name) const +{ + print(mstack->top(), name); +} diff --git a/L09/src/MatrixStack.h b/L09/src/MatrixStack.h new file mode 100644 index 0000000..66278ce --- /dev/null +++ b/L09/src/MatrixStack.h @@ -0,0 +1,50 @@ +#pragma once +#ifndef _MatrixStack_H_ +#define _MatrixStack_H_ + +#include +#include +#include + +class MatrixStack +{ +public: + MatrixStack(); + virtual ~MatrixStack(); + + // glPushMatrix(): Copies the current matrix and adds it to the top of the stack + void pushMatrix(); + // glPopMatrix(): Removes the top of the stack and sets the current matrix to be the matrix that is now on top + void popMatrix(); + + // glLoadIdentity(): Sets the top matrix to be the identity + void loadIdentity(); + // glMultMatrix(): Right multiplies the top matrix + void multMatrix(const glm::mat4 &matrix); + + // glTranslate(): Right multiplies the top matrix by a translation matrix + void translate(const glm::vec3 &trans); + void translate(float x, float y, float z); + // glScale(): Right multiplies the top matrix by a scaling matrix + void scale(const glm::vec3 &scale); + void scale(float x, float y, float z); + // glScale(): Right multiplies the top matrix by a scaling matrix + void scale(float size); + // glRotate(): Right multiplies the top matrix by a rotation matrix (angle in radians) + void rotate(float angle, const glm::vec3 &axis); + void rotate(float angle, float x, float y, float z); + + // glGet(GL_MODELVIEW_MATRIX): Gets the top matrix + const glm::mat4 &topMatrix() const; + + // Prints out the specified matrix + static void print(const glm::mat4 &mat, const char *name = 0); + // Prints out the top matrix + void print(const char *name = 0) const; + +private: + std::shared_ptr< std::stack > mstack; + +}; + +#endif diff --git a/L09/src/Program.cpp b/L09/src/Program.cpp new file mode 100644 index 0000000..1e85538 --- /dev/null +++ b/L09/src/Program.cpp @@ -0,0 +1,126 @@ +#include "Program.h" + +#include +#include + +#include "GLSL.h" + +using namespace std; + +Program::Program() : + vShaderName(""), + fShaderName(""), + pid(0), + verbose(true) +{ + +} + +Program::~Program() +{ + +} + +void Program::setShaderNames(const string &v, const string &f) +{ + vShaderName = v; + fShaderName = f; +} + +bool Program::init() +{ + GLint rc; + + // Create shader handles + GLuint VS = glCreateShader(GL_VERTEX_SHADER); + GLuint FS = glCreateShader(GL_FRAGMENT_SHADER); + + // Read shader sources + const char *vshader = GLSL::textFileRead(vShaderName.c_str()); + const char *fshader = GLSL::textFileRead(fShaderName.c_str()); + glShaderSource(VS, 1, &vshader, NULL); + glShaderSource(FS, 1, &fshader, NULL); + + // Compile vertex shader + glCompileShader(VS); + glGetShaderiv(VS, GL_COMPILE_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printShaderInfoLog(VS); + cout << "Error compiling vertex shader " << vShaderName << endl; + } + return false; + } + + // Compile fragment shader + glCompileShader(FS); + glGetShaderiv(FS, GL_COMPILE_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printShaderInfoLog(FS); + cout << "Error compiling fragment shader " << fShaderName << endl; + } + return false; + } + + // Create the program and link + pid = glCreateProgram(); + glAttachShader(pid, VS); + glAttachShader(pid, FS); + glLinkProgram(pid); + glGetProgramiv(pid, GL_LINK_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printProgramInfoLog(pid); + cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl; + } + return false; + } + + GLSL::checkError(GET_FILE_LINE); + return true; +} + +void Program::bind() +{ + glUseProgram(pid); +} + +void Program::unbind() +{ + glUseProgram(0); +} + +void Program::addAttribute(const string &name) +{ + attributes[name] = glGetAttribLocation(pid, name.c_str()); +} + +void Program::addUniform(const string &name) +{ + uniforms[name] = glGetUniformLocation(pid, name.c_str()); +} + +GLint Program::getAttribute(const string &name) const +{ + map::const_iterator attribute = attributes.find(name.c_str()); + if(attribute == attributes.end()) { + if(isVerbose()) { + cout << name << " is not an attribute variable" << endl; + } + return -1; + } + return attribute->second; +} + +GLint Program::getUniform(const string &name) const +{ + map::const_iterator uniform = uniforms.find(name.c_str()); + if(uniform == uniforms.end()) { + if(isVerbose()) { + cout << name << " is not a uniform variable" << endl; + } + return -1; + } + return uniform->second; +} diff --git a/L09/src/Program.h b/L09/src/Program.h new file mode 100644 index 0000000..51e58bb --- /dev/null +++ b/L09/src/Program.h @@ -0,0 +1,44 @@ +#pragma once +#ifndef __Program__ +#define __Program__ + +#include +#include + +#define GLEW_STATIC +#include + +/** + * An OpenGL Program (vertex and fragment shaders) + */ +class Program +{ +public: + Program(); + virtual ~Program(); + + void setVerbose(bool v) { verbose = v; } + bool isVerbose() const { return verbose; } + + void setShaderNames(const std::string &v, const std::string &f); + virtual bool init(); + virtual void bind(); + virtual void unbind(); + + void addAttribute(const std::string &name); + void addUniform(const std::string &name); + GLint getAttribute(const std::string &name) const; + GLint getUniform(const std::string &name) const; + +protected: + std::string vShaderName; + std::string fShaderName; + +private: + GLuint pid; + std::map attributes; + std::map uniforms; + bool verbose; +}; + +#endif diff --git a/L09/src/Texture.cpp b/L09/src/Texture.cpp new file mode 100644 index 0000000..1537763 --- /dev/null +++ b/L09/src/Texture.cpp @@ -0,0 +1,80 @@ +#include "Texture.h" +#include +#include +#include +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +using namespace std; + +Texture::Texture() : + filename(""), + tid(0) +{ + +} + +Texture::~Texture() +{ + +} + +void Texture::init() +{ + // Load texture + int w, h, ncomps; + stbi_set_flip_vertically_on_load(true); + unsigned char *data = stbi_load(filename.c_str(), &w, &h, &ncomps, 0); + if(!data) { + cerr << filename << " not found" << endl; + } + if(ncomps != 3) { + cerr << filename << " must have 3 components (RGB)" << endl; + } + if((w & (w - 1)) != 0 || (h & (h - 1)) != 0) { + cerr << filename << " must be a power of 2" << endl; + } + width = w; + height = h; + + // Generate a texture buffer object + glGenTextures(1, &tid); + // Bind the current texture to be the newly generated texture object + glBindTexture(GL_TEXTURE_2D, tid); + // Load the actual texture data + // Base level is 0, number of channels is 3, and border is 0. + glTexImage2D(GL_TEXTURE_2D, 0, ncomps, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + // Generate image pyramid + glGenerateMipmap(GL_TEXTURE_2D); + // Set texture wrap modes for the S and T directions + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // Set filtering mode for magnification and minimification + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + // Unbind + glBindTexture(GL_TEXTURE_2D, 0); + // Free image, since the data is now on the GPU + stbi_image_free(data); +} + +void Texture::setWrapModes(GLint wrapS, GLint wrapT) +{ + // Must be called after init() + glBindTexture(GL_TEXTURE_2D, tid); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); +} + +void Texture::bind(GLint handle) +{ + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(GL_TEXTURE_2D, tid); + glUniform1i(handle, unit); +} + +void Texture::unbind() +{ + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/L09/src/Texture.h b/L09/src/Texture.h new file mode 100644 index 0000000..9209149 --- /dev/null +++ b/L09/src/Texture.h @@ -0,0 +1,32 @@ +#pragma once +#ifndef __Texture__ +#define __Texture__ + +#define GLEW_STATIC +#include + +#include + +class Texture +{ +public: + Texture(); + virtual ~Texture(); + void setFilename(const std::string &f) { filename = f; } + void init(); + void setUnit(GLint u) { unit = u; } + GLint getUnit() const { return unit; } + void bind(GLint handle); + void unbind(); + void setWrapModes(GLint wrapS, GLint wrapT); // Must be called after init() + +private: + std::string filename; + int width; + int height; + GLuint tid; + GLint unit; + +}; + +#endif diff --git a/L09/src/main.cpp b/L09/src/main.cpp new file mode 100644 index 0000000..c57b422 --- /dev/null +++ b/L09/src/main.cpp @@ -0,0 +1,312 @@ +#include +#include +#define _USE_MATH_DEFINES +#include +#include +#include +#include + +#define GLEW_STATIC +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +#include "Camera.h" +#include "GLSL.h" +#include "MatrixStack.h" +#include "Program.h" +#include "Texture.h" + +using namespace std; + +GLFWwindow *window; // Main application window +string RESOURCE_DIR = "./"; // Where the resources are loaded from + +shared_ptr camera; +shared_ptr prog; +shared_ptr texture0; +shared_ptr texture1; + +vector posBuf; +vector texBuf; +vector indBuf; +map bufIDs; +int indCount; + +glm::mat3 T1; + +bool keyToggles[256] = {false}; // only for English keyboards! + +// This function is called when a GLFW error occurs +static void error_callback(int error, const char *description) +{ + cerr << description << endl; +} + +// This function is called when a key is pressed +static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) +{ + if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GL_TRUE); + } +} + +// This function is called when the mouse is clicked +static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) +{ + // Get the current mouse position. + double xmouse, ymouse; + glfwGetCursorPos(window, &xmouse, &ymouse); + // Get current window size. + int width, height; + glfwGetWindowSize(window, &width, &height); + if(action == GLFW_PRESS) { + bool shift = (mods & GLFW_MOD_SHIFT) != 0; + bool ctrl = (mods & GLFW_MOD_CONTROL) != 0; + bool alt = (mods & GLFW_MOD_ALT) != 0; + camera->mouseClicked((float)xmouse, (float)ymouse, shift, ctrl, alt); + } +} + +// This function is called when the mouse moves +static void cursor_position_callback(GLFWwindow* window, double xmouse, double ymouse) +{ + int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); + if(state == GLFW_PRESS) { + camera->mouseMoved((float)xmouse, (float)ymouse); + } +} + +static void char_callback(GLFWwindow *window, unsigned int key) +{ + keyToggles[key] = !keyToggles[key]; +} + +// If the window is resized, capture the new size and reset the viewport +static void resize_callback(GLFWwindow *window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +// This function is called once to initialize the scene and OpenGL +static void init() +{ + // Initialize time. + glfwSetTime(0.0); + + // Set background color. + glClearColor(0.1f, 0.2f, 0.4f, 1.0f); + // Enable z-buffer test. + glEnable(GL_DEPTH_TEST); + + prog = make_shared(); + prog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "frag.glsl"); + prog->setVerbose(true); + prog->init(); + prog->addAttribute("aPos"); + prog->addAttribute("aTex"); + prog->addUniform("MV"); + prog->addUniform("P"); + prog->addUniform("T1"); + prog->addUniform("texture0"); + prog->addUniform("texture1"); + prog->setVerbose(false); + + camera = make_shared(); + camera->setInitDistance(3.0f); + + texture0 = make_shared(); + texture0->setFilename(RESOURCE_DIR + "tamu.jpg"); + texture0->init(); + texture0->setUnit(0); + texture0->setWrapModes(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); + + texture1 = make_shared(); + texture1->setFilename(RESOURCE_DIR + "reveille.jpg"); + texture1->init(); + texture1->setUnit(1); + texture1->setWrapModes(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); + + // + // Texture matrix + // + T1[0][0] = 1.0f; + + // + // Initialize geometry + // + // We need to fill in the position buffer, normal buffer, the texcoord + // buffer, and the index buffer. + // 0 + posBuf.push_back(-1.0f); + posBuf.push_back(-1.0f); + posBuf.push_back(0.0f); + texBuf.push_back(0.0f); + texBuf.push_back(0.0f); + // 1 + posBuf.push_back(1.0f); + posBuf.push_back(-1.0f); + posBuf.push_back(0.0f); + texBuf.push_back(0.0f); + texBuf.push_back(0.0f); + // 2 + posBuf.push_back(-1.0f); + posBuf.push_back(1.0f); + posBuf.push_back(0.0f); + texBuf.push_back(0.0f); + texBuf.push_back(0.0f); + // 3 + posBuf.push_back(1.0f); + posBuf.push_back(1.0f); + posBuf.push_back(0.0f); + texBuf.push_back(0.0f); + texBuf.push_back(0.0f); + // Index + indBuf.push_back(0); + indBuf.push_back(1); + indBuf.push_back(2); + indBuf.push_back(3); + indBuf.push_back(2); + indBuf.push_back(1); + indCount = (int)indBuf.size(); + + // Generate 3 buffer IDs and put them in the bufIDs map. + GLuint tmp[3]; + glGenBuffers(3, tmp); + bufIDs["bPos"] = tmp[0]; + bufIDs["bTex"] = tmp[1]; + bufIDs["bInd"] = tmp[2]; + + glBindBuffer(GL_ARRAY_BUFFER, bufIDs["bPos"]); + glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, bufIDs["bTex"]); + glBufferData(GL_ARRAY_BUFFER, texBuf.size()*sizeof(float), &texBuf[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufIDs["bInd"]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indBuf.size()*sizeof(unsigned int), &indBuf[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + GLSL::checkError(GET_FILE_LINE); +} + +// This function is called every frame to draw the scene. +static void render() +{ + // Clear framebuffer. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if(keyToggles[(unsigned)'c']) { + glEnable(GL_CULL_FACE); + } else { + glDisable(GL_CULL_FACE); + } + if(keyToggles[(unsigned)'l']) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } else { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + + // Get current frame buffer size. + int width, height; + glfwGetFramebufferSize(window, &width, &height); + camera->setAspect((float)width/(float)height); + + // Matrix stacks + auto P = make_shared(); + auto MV = make_shared(); + + // Apply camera transforms + P->pushMatrix(); + camera->applyProjectionMatrix(P); + MV->pushMatrix(); + camera->applyViewMatrix(MV); + + prog->bind(); + texture0->bind(prog->getUniform("texture0")); + texture1->bind(prog->getUniform("texture1")); + glUniformMatrix4fv(prog->getUniform("P"), 1, GL_FALSE, glm::value_ptr(P->topMatrix())); + glUniformMatrix4fv(prog->getUniform("MV"), 1, GL_FALSE, glm::value_ptr(MV->topMatrix())); + glUniformMatrix3fv(prog->getUniform("T1"), 1, GL_FALSE, glm::value_ptr(T1)); + glEnableVertexAttribArray(prog->getAttribute("aPos")); + glBindBuffer(GL_ARRAY_BUFFER, bufIDs["bPos"]); + glVertexAttribPointer(prog->getAttribute("aPos"), 3, GL_FLOAT, GL_FALSE, 0, (void *)0); + glEnableVertexAttribArray(prog->getAttribute("aTex")); + glBindBuffer(GL_ARRAY_BUFFER, bufIDs["bTex"]); + glVertexAttribPointer(prog->getAttribute("aTex"), 2, GL_FLOAT, GL_FALSE, 0, (void *)0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufIDs["bInd"]); + glDrawElements(GL_TRIANGLES, indCount, GL_UNSIGNED_INT, (void *)0); + texture1->unbind(); + texture0->unbind(); + prog->unbind(); + + MV->popMatrix(); + P->popMatrix(); + + GLSL::checkError(GET_FILE_LINE); +} + +int main(int argc, char **argv) +{ + if(argc < 2) { + cout << "Please specify the resource directory." << endl; + return 0; + } + RESOURCE_DIR = argv[1] + string("/"); + + // Set error callback. + glfwSetErrorCallback(error_callback); + // Initialize the library. + if(!glfwInit()) { + return -1; + } + // Create a windowed mode window and its OpenGL context. + window = glfwCreateWindow(640, 480, "YOUR NAME", NULL, NULL); + if(!window) { + glfwTerminate(); + return -1; + } + // Make the window's context current. + glfwMakeContextCurrent(window); + // Initialize GLEW. + glewExperimental = true; + if(glewInit() != GLEW_OK) { + cerr << "Failed to initialize GLEW" << endl; + return -1; + } + glGetError(); // A bug in glewInit() causes an error that we can safely ignore. + cout << "OpenGL version: " << glGetString(GL_VERSION) << endl; + cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl; + GLSL::checkVersion(); + // Set vsync. + glfwSwapInterval(1); + // Set keyboard callback. + glfwSetKeyCallback(window, key_callback); + // Set char callback. + glfwSetCharCallback(window, char_callback); + // Set cursor position callback. + glfwSetCursorPosCallback(window, cursor_position_callback); + // Set mouse button callback. + glfwSetMouseButtonCallback(window, mouse_button_callback); + // Set the window resize call back. + glfwSetFramebufferSizeCallback(window, resize_callback); + // Initialize scene. + init(); + // Loop until the user closes the window. + while(!glfwWindowShouldClose(window)) { + // Render scene. + render(); + // Swap front and back buffers. + glfwSwapBuffers(window); + // Poll for and process events. + glfwPollEvents(); + } + // Quit program. + glfwDestroyWindow(window); + glfwTerminate(); + return 0; +} diff --git a/L09/src/stb_image.h b/L09/src/stb_image.h new file mode 100644 index 0000000..a3c1129 --- /dev/null +++ b/L09/src/stb_image.h @@ -0,0 +1,6755 @@ +/* stb_image - v2.12 - public domain image loader - http://nothings.org/stb_image.h + no warranty implied; use at your own risk + + Do this: + #define STB_IMAGE_IMPLEMENTATION + before you include this file in *one* C or C++ file to create the implementation. + + // i.e. it should look like this: + #include ... + #include ... + #include ... + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + + You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. + And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free + + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) + PNG 1/2/4/8-bit-per-channel (16 bpc not supported) + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels, 8/16 bit-per-channel) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + PNM (PPM and PGM binary only) + + Animated GIF still needs a proper API, but here's one way to do it: + http://gist.github.com/urraka/685d9a6340b26b830d49 + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) + + Full documentation under "DOCUMENTATION" below. + + + Revision 2.00 release notes: + + - Progressive JPEG is now supported. + + - PPM and PGM binary formats are now supported, thanks to Ken Miller. + + - x86 platforms now make use of SSE2 SIMD instructions for + JPEG decoding, and ARM platforms can use NEON SIMD if requested. + This work was done by Fabian "ryg" Giesen. SSE2 is used by + default, but NEON must be enabled explicitly; see docs. + + With other JPEG optimizations included in this version, we see + 2x speedup on a JPEG on an x86 machine, and a 1.5x speedup + on a JPEG on an ARM machine, relative to previous versions of this + library. The same results will not obtain for all JPGs and for all + x86/ARM machines. (Note that progressive JPEGs are significantly + slower to decode than regular JPEGs.) This doesn't mean that this + is the fastest JPEG decoder in the land; rather, it brings it + closer to parity with standard libraries. If you want the fastest + decode, look elsewhere. (See "Philosophy" section of docs below.) + + See final bullet items below for more info on SIMD. + + - Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing + the memory allocator. Unlike other STBI libraries, these macros don't + support a context parameter, so if you need to pass a context in to + the allocator, you'll have to store it in a global or a thread-local + variable. + + - Split existing STBI_NO_HDR flag into two flags, STBI_NO_HDR and + STBI_NO_LINEAR. + STBI_NO_HDR: suppress implementation of .hdr reader format + STBI_NO_LINEAR: suppress high-dynamic-range light-linear float API + + - You can suppress implementation of any of the decoders to reduce + your code footprint by #defining one or more of the following + symbols before creating the implementation. + + STBI_NO_JPEG + STBI_NO_PNG + STBI_NO_BMP + STBI_NO_PSD + STBI_NO_TGA + STBI_NO_GIF + STBI_NO_HDR + STBI_NO_PIC + STBI_NO_PNM (.ppm and .pgm) + + - You can request *only* certain decoders and suppress all other ones + (this will be more forward-compatible, as addition of new decoders + doesn't require you to disable them explicitly): + + STBI_ONLY_JPEG + STBI_ONLY_PNG + STBI_ONLY_BMP + STBI_ONLY_PSD + STBI_ONLY_TGA + STBI_ONLY_GIF + STBI_ONLY_HDR + STBI_ONLY_PIC + STBI_ONLY_PNM (.ppm and .pgm) + + Note that you can define multiples of these, and you will get all + of them ("only x" and "only y" is interpreted to mean "only x&y"). + + - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still + want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB + + - Compilation of all SIMD code can be suppressed with + #define STBI_NO_SIMD + It should not be necessary to disable SIMD unless you have issues + compiling (e.g. using an x86 compiler which doesn't support SSE + intrinsics or that doesn't support the method used to detect + SSE2 support at run-time), and even those can be reported as + bugs so I can refine the built-in compile-time checking to be + smarter. + + - The old STBI_SIMD system which allowed installing a user-defined + IDCT etc. has been removed. If you need this, don't upgrade. My + assumption is that almost nobody was doing this, and those who + were will find the built-in SIMD more satisfactory anyway. + + - RGB values computed for JPEG images are slightly different from + previous versions of stb_image. (This is due to using less + integer precision in SIMD.) The C code has been adjusted so + that the same RGB values will be computed regardless of whether + SIMD support is available, so your app should always produce + consistent results. But these results are slightly different from + previous versions. (Specifically, about 3% of available YCbCr values + will compute different RGB results from pre-1.49 versions by +-1; + most of the deviating values are one smaller in the G channel.) + + - If you must produce consistent results with previous versions of + stb_image, #define STBI_JPEG_OLD and you will get the same results + you used to; however, you will not get the SIMD speedups for + the YCbCr-to-RGB conversion step (although you should still see + significant JPEG speedup from the other changes). + + Please note that STBI_JPEG_OLD is a temporary feature; it will be + removed in future versions of the library. It is only intended for + near-term back-compatibility use. + + + Latest revision history: + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 + RGB-format JPEG; remove white matting in PSD; + allocate large structures on the stack; + correct channel count for PNG & BMP + 2.10 (2016-01-22) avoid warning introduced in 2.09 + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) partial animated GIF support + limited 16-bit PSD support + minor bugs, code cleanup, and compiler warnings + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) additional corruption checking + stbi_set_flip_vertically_on_load + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPEG, including x86 SSE2 & ARM NEON SIMD + progressive JPEG + PGM/PPM support + STBI_MALLOC,STBI_REALLOC,STBI_FREE + STBI_NO_*, STBI_ONLY_* + GIF bugfix + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + urraka@github (animated gif) Junggon Kim (PNM comments) + Daniel Gibson (16-bit TGA) + + Optimizations & bugfixes + Fabian "ryg" Giesen + Arseny Kapoulkine + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson + Dave Moore Roy Eltham Hayaki Saito Phil Jordan + Won Chun Luke Graham Johan Duparc Nathan Reed + the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis + Janez Zemva John Bartholomew Michal Cichon svdijk@github + Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson + Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github + Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan + Ryamond Barbiero Paul Du Bois Engin Manap snagar@github + Michaelangel007@github Oriol Ferrer Mesia socks-the-fox + Blazej Dariusz Roszkowski + + +LICENSE + +This software is dual-licensed to the public domain and under the following +license: you are granted a perpetual, irrevocable license to copy, modify, +publish, and distribute this file as you see fit. + +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// DOCUMENTATION +// +// Limitations: +// - no 16-bit-per-channel PNG +// - no 12-bit-per-channel JPEG +// - no JPEGs with arithmetic coding +// - no 1-bit BMP +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below for HDR usage): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *comp -- outputs # of image components in image file +// int req_comp -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data, or NULL on an allocation failure or if the image is +// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise. +// If req_comp is non-zero, *comp has the number of components that _would_ +// have been output otherwise. E.g. if you set req_comp to 4, you will always +// get RGBA output, but you can check *comp to see if it's trivially opaque +// because e.g. there were only 3 channels in the source image. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *comp will be unchanged. The function stbi_failure_reason() +// can be queried for an extremely brief, end-user unfriendly explanation +// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid +// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// =========================================================================== +// +// Philosophy +// +// stb libraries are designed with the following priorities: +// +// 1. easy to use +// 2. easy to maintain +// 3. good performance +// +// Sometimes I let "good performance" creep up in priority over "easy to maintain", +// and for best performance I may provide less-easy-to-use APIs that give higher +// performance, in addition to the easy to use ones. Nevertheless, it's important +// to keep in mind that from the standpoint of you, a client of this library, +// all you care about is #1 and #3, and stb libraries do not emphasize #3 above all. +// +// Some secondary priorities arise directly from the first two, some of which +// make more explicit reasons why performance can't be emphasized. +// +// - Portable ("ease of use") +// - Small footprint ("easy to maintain") +// - No dependencies ("ease of use") +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). +// +// =========================================================================== +// +// SIMD support +// +// The JPEG decoder will try to automatically use SIMD kernels on x86 when +// supported by the compiler. For ARM Neon support, you must explicitly +// request it. +// +// (The old do-it-yourself SIMD API is no longer supported in the current +// code.) +// +// On x86, SSE2 will automatically be used when available based on a run-time +// test; if not, the generic C versions are used as a fall-back. On ARM targets, +// the typical path is to have separate builds for NEON and non-NEON devices +// (at least this is true for iOS and Android). Therefore, the NEON support is +// toggled by a build flag: define STBI_NEON to get NEON loops. +// +// The output of the JPEG decoder is slightly different from versions where +// SIMD support was introduced (that is, for versions before 1.49). The +// difference is only +-1 in the 8-bit RGB channels, and only on a small +// fraction of pixels. You can force the pre-1.49 behavior by defining +// STBI_JPEG_OLD, but this will disable some of the SIMD decoding path +// and hence cost some performance. +// +// If for some reason you do not want to use any of SIMD code, or if +// you have issues compiling it, you can disable it entirely by +// defining STBI_NO_SIMD. +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image now supports loading HDR images in general, and currently +// the Radiance .HDR file format, although the support is provided +// generically. You can still load any file through the existing interface; +// if you attempt to load an HDR file, it will be automatically remapped to +// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// iPhone PNG support: +// +// By default we convert iphone-formatted PNGs back to RGB, even though +// they are internally encoded differently. You can disable this conversion +// by by calling stbi_convert_iphone_png_to_rgb(0), in which case +// you will always just get the native iphone "format" through (which +// is BGR stored in RGB). +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// + + +#ifndef STBI_NO_STDIO +#include +#endif // STBI_NO_STDIO + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for req_comp + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +typedef unsigned char stbi_uc; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef STB_IMAGE_STATIC +#define STBIDEF static +#else +#define STBIDEF extern +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); +STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *comp, int req_comp); +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *comp, int req_comp); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +#ifndef STBI_NO_LINEAR + STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); + STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + + #ifndef STBI_NO_STDIO + STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + #endif +#endif + +#ifndef STBI_NO_HDR + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); + STBIDEF void stbi_hdr_to_ldr_scale(float scale); +#endif // STBI_NO_HDR + +#ifndef STBI_NO_LINEAR + STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); + STBIDEF void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_LINEAR + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename); +STBIDEF int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// NOT THREADSAFE +STBIDEF const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +STBIDEF void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); + +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); +STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifdef STB_IMAGE_IMPLEMENTATION + +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ + || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ + || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ + || defined(STBI_ONLY_ZLIB) + #ifndef STBI_ONLY_JPEG + #define STBI_NO_JPEG + #endif + #ifndef STBI_ONLY_PNG + #define STBI_NO_PNG + #endif + #ifndef STBI_ONLY_BMP + #define STBI_NO_BMP + #endif + #ifndef STBI_ONLY_PSD + #define STBI_NO_PSD + #endif + #ifndef STBI_ONLY_TGA + #define STBI_NO_TGA + #endif + #ifndef STBI_ONLY_GIF + #define STBI_NO_GIF + #endif + #ifndef STBI_ONLY_HDR + #define STBI_NO_HDR + #endif + #ifndef STBI_ONLY_PIC + #define STBI_NO_PIC + #endif + #ifndef STBI_ONLY_PNM + #define STBI_NO_PNM + #endif +#endif + +#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) +#define STBI_NO_ZLIB +#endif + + +#include +#include // ptrdiff_t on osx +#include +#include + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +#include // ldexp +#endif + +#ifndef STBI_NO_STDIO +#include +#endif + +#ifndef STBI_ASSERT +#include +#define STBI_ASSERT(x) assert(x) +#endif + + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + + +#ifdef _MSC_VER +typedef unsigned short stbi__uint16; +typedef signed short stbi__int16; +typedef unsigned int stbi__uint32; +typedef signed int stbi__int32; +#else +#include +typedef uint16_t stbi__uint16; +typedef int16_t stbi__int16; +typedef uint32_t stbi__uint32; +typedef int32_t stbi__int32; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBI_NOTUSED(v) (void)(v) +#else +#define STBI_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#endif + +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) +// ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." +#endif + +#ifndef STBI_MALLOC +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED +#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#endif + +// x86/x64 detection +#if defined(__x86_64__) || defined(_M_X64) +#define STBI__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) +#define STBI__X86_TARGET +#endif + +#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) +// NOTE: not clear do we actually need this for the 64-bit path? +// gcc doesn't support sse2 intrinsics unless you compile with -msse2, +// (but compiling with -msse2 allows the compiler to use SSE2 everywhere; +// this is just broken and gcc are jerks for not fixing it properly +// http://www.virtualdub.org/blog/pivot/entry.php?id=363 ) +#define STBI_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) +// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET +// +// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the +// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. +// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not +// simultaneously enabling "-mstackrealign". +// +// See https://github.com/nothings/stb/issues/81 for more information. +// +// So default to no SSE2 on 32-bit MinGW. If you've read this far and added +// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. +#define STBI_NO_SIMD +#endif + +#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) +#define STBI_SSE2 +#include + +#ifdef _MSC_VER + +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid +static int stbi__cpuid3(void) +{ + int info[4]; + __cpuid(info,1); + return info[3]; +} +#else +static int stbi__cpuid3(void) +{ + int res; + __asm { + mov eax,1 + cpuid + mov res,edx + } + return res; +} +#endif + +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + +static int stbi__sse2_available() +{ + int info3 = stbi__cpuid3(); + return ((info3 >> 26) & 1) != 0; +} +#else // assume GCC-style if not VC++ +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + +static int stbi__sse2_available() +{ +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later + // GCC 4.8+ has a nice way to do this + return __builtin_cpu_supports("sse2"); +#else + // portable way to do this, preferably without using GCC inline ASM? + // just bail for now. + return 0; +#endif +} +#endif +#endif + +// ARM NEON +#if defined(STBI_NO_SIMD) && defined(STBI_NEON) +#undef STBI_NEON +#endif + +#ifdef STBI_NEON +#include +// assume GCC or Clang on ARM targets +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif + +#ifndef STBI_SIMD_ALIGN +#define STBI_SIMD_ALIGN(type, name) type name +#endif + +/////////////////////////////////////////////// +// +// stbi__context struct and start_xxx functions + +// stbi__context structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + stbi__uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + stbi_uc buffer_start[128]; + + stbi_uc *img_buffer, *img_buffer_end; + stbi_uc *img_buffer_original, *img_buffer_original_end; +} stbi__context; + + +static void stbi__refill_buffer(stbi__context *s); + +// initialize a memory-decode context +static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; +} + +// initialize a callback-based context +static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->img_buffer_original = s->buffer_start; + stbi__refill_buffer(s); + s->img_buffer_original_end = s->img_buffer_end; +} + +#ifndef STBI_NO_STDIO + +static int stbi__stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stbi__stdio_skip(void *user, int n) +{ + fseek((FILE*) user, n, SEEK_CUR); +} + +static int stbi__stdio_eof(void *user) +{ + return feof((FILE*) user); +} + +static stbi_io_callbacks stbi__stdio_callbacks = +{ + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, +}; + +static void stbi__start_file(stbi__context *s, FILE *f) +{ + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi__context *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi__rewind(stbi__context *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; + s->img_buffer_end = s->img_buffer_original_end; +} + +#ifndef STBI_NO_JPEG +static int stbi__jpeg_test(stbi__context *s); +static stbi_uc *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNG +static int stbi__png_test(stbi__context *s); +static stbi_uc *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_BMP +static int stbi__bmp_test(stbi__context *s); +static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_TGA +static int stbi__tga_test(stbi__context *s); +static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s); +static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_HDR +static int stbi__hdr_test(stbi__context *s); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_test(stbi__context *s); +static stbi_uc *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_GIF +static int stbi__gif_test(stbi__context *s); +static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNM +static int stbi__pnm_test(stbi__context *s); +static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +// this is not threadsafe +static const char *stbi__g_failure_reason; + +STBIDEF const char *stbi_failure_reason(void) +{ + return stbi__g_failure_reason; +} + +static int stbi__err(const char *str) +{ + stbi__g_failure_reason = str; + return 0; +} + +static void *stbi__malloc(size_t size) +{ + return STBI_MALLOC(size); +} + +// stbi__err - error +// stbi__errpf - error returning pointer to float +// stbi__errpuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define stbi__err(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define stbi__err(x,y) stbi__err(y) +#else + #define stbi__err(x,y) stbi__err(x) +#endif + +#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) + +STBIDEF void stbi_image_free(void *retval_from_stbi_load) +{ + STBI_FREE(retval_from_stbi_load); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_HDR +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static int stbi__vertically_flip_on_load = 0; + +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load = flag_true_if_should_flip; +} + +static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PNG + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_BMP + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_GIF + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PSD + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PIC + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PNM + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp); + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp); + return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + #ifndef STBI_NO_TGA + // test tga last because it's a crappy test! + if (stbi__tga_test(s)) + return stbi__tga_load(s,x,y,comp,req_comp); + #endif + + return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result = stbi__load_main(s, x, y, comp, req_comp); + + if (stbi__vertically_flip_on_load && result != NULL) { + int w = *x, h = *y; + int depth = req_comp ? req_comp : *comp; + int row,col,z; + stbi_uc temp; + + // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once + for (row = 0; row < (h>>1); row++) { + for (col = 0; col < w; col++) { + for (z = 0; z < depth; z++) { + temp = result[(row * w + col) * depth + z]; + result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; + result[((h - row - 1) * w + col) * depth + z] = temp; + } + } + } + } + + return result; +} + +#ifndef STBI_NO_HDR +static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) +{ + if (stbi__vertically_flip_on_load && result != NULL) { + int w = *x, h = *y; + int depth = req_comp ? req_comp : *comp; + int row,col,z; + float temp; + + // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once + for (row = 0; row < (h>>1); row++) { + for (col = 0; col < w; col++) { + for (z = 0; z < depth; z++) { + temp = result[(row * w + col) * depth + z]; + result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; + result[((h - row - 1) * w + col) * depth + z] = temp; + } + } + } + } +} +#endif + +#ifndef STBI_NO_STDIO + +static FILE *stbi__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + + +STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + unsigned char *result; + if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_flip(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} +#endif //!STBI_NO_STDIO + +STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_flip(&s,x,y,comp,req_comp); +} + +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__load_flip(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp); + if (hdr_data) + stbi__float_postprocess(hdr_data,x,y,comp,req_comp); + return hdr_data; + } + #endif + data = stbi__load_flip(s, x, y, comp, req_comp); + if (data) + return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); +} + +STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + float *result; + FILE *f = stbi__fopen(filename, "rb"); + if (!f) return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_file(&s,f); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_LINEAR + +// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is +// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always +// reports false! + +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +STBIDEF int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_file(&s,f); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(f); + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(clbk); + STBI_NOTUSED(user); + return 0; + #endif +} + +#ifndef STBI_NO_LINEAR +static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; + +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } +STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } +#endif + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } +STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + STBI__SCAN_load=0, + STBI__SCAN_type, + STBI__SCAN_header +}; + +static void stbi__refill_buffer(stbi__context *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + if (n == 0) { + // at end of file, treat same as if from memory, but need to handle case + // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start+1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static stbi_uc stbi__get8(stbi__context *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + stbi__refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +stbi_inline static int stbi__at_eof(stbi__context *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} + +static void stbi__skip(stbi__context *s, int n) +{ + if (n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} + +static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} + +static int stbi__get16be(stbi__context *s) +{ + int z = stbi__get8(s); + return (z << 8) + stbi__get8(s); +} + +static stbi__uint32 stbi__get32be(stbi__context *s) +{ + stbi__uint32 z = stbi__get16be(s); + return (z << 16) + stbi__get16be(s); +} + +#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) +// nothing +#else +static int stbi__get16le(stbi__context *s) +{ + int z = stbi__get8(s); + return z + (stbi__get8(s) << 8); +} +#endif + +#ifndef STBI_NO_BMP +static stbi__uint32 stbi__get32le(stbi__context *s) +{ + stbi__uint32 z = stbi__get16le(s); + return z + (stbi__get16le(s) << 16); +} +#endif + +#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings + + +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static stbi_uc stbi__compute_y(int r, int g, int b) +{ + return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); +} + +static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) stbi__malloc(req_comp * x * y); + if (good == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define COMBO(a,b) ((a)*8+(b)) + #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (COMBO(img_n, req_comp)) { + CASE(1,2) dest[0]=src[0], dest[1]=255; break; + CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; + CASE(2,1) dest[0]=src[0]; break; + CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; + CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; + CASE(3,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; + CASE(3,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; break; + CASE(4,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; + CASE(4,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; + CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; + default: STBI_ASSERT(0); + } + #undef CASE + } + + STBI_FREE(data); + return good; +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output = (float *) stbi__malloc(x * y * comp * sizeof(float)); + if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + } + if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; + } + STBI_FREE(data); + return output; +} +#endif + +#ifndef STBI_NO_HDR +#define stbi__float2int(x) ((int) (x)) +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output = (stbi_uc *) stbi__malloc(x * y * comp); + if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + } + STBI_FREE(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder +// +// simple implementation +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - some SIMD kernels for common paths on targets with SSE2/NEON +// - uses a lot of intermediate memory, could cache poorly + +#ifndef STBI_NO_JPEG + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + stbi_uc fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + stbi__uint16 code[256]; + stbi_uc values[256]; + stbi_uc size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} stbi__huffman; + +typedef struct +{ + stbi__context *s; + stbi__huffman huff_dc[4]; + stbi__huffman huff_ac[4]; + stbi_uc dequant[4][64]; + stbi__int16 fast_ac[4][1 << FAST_BITS]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + stbi_uc *data; + void *raw_data, *raw_coeff; + stbi_uc *linebuf; + short *coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks + } img_comp[4]; + + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int rgb; + + int scan_n, order[4]; + int restart_interval, todo; + +// kernels + void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); + stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); +} stbi__jpeg; + +static int stbi__build_huffman(stbi__huffman *h, int *count) +{ + int i,j,k=0,code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (stbi_uc) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (stbi__uint16) (code++); + if (code-1 >= (1 << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (stbi_uc) i; + } + } + } + return 1; +} + +// build a table that decodes both magnitude and value of small ACs in +// one go. +static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) +{ + int i; + for (i=0; i < (1 << FAST_BITS); ++i) { + stbi_uc fast = h->fast[i]; + fast_ac[i] = 0; + if (fast < 255) { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if (magbits && len + magbits <= FAST_BITS) { + // magnitude code followed by receive_extend code + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if (k < m) k += (-1 << magbits) + 1; + // if the result is small enough, we can fit it in fast_ac table + if (k >= -128 && k <= 127) + fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits)); + } + } + } +} + +static void stbi__grow_buffer_unsafe(stbi__jpeg *j) +{ + do { + int b = j->nomore ? 0 : stbi__get8(j->s); + if (b == 0xff) { + int c = stbi__get8(j->s); + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; + STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); + + sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB + k = stbi_lrot(j->code_buffer, n); + STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k + (stbi__jbias[n] & ~sgn); +} + +// get some unsigned bits +stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) +{ + unsigned int k; + if (j->code_bits < n) stbi__grow_buffer_unsafe(j); + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k; +} + +stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) +{ + unsigned int k; + if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static stbi_uc stbi__jpeg_dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi_uc *dequant) +{ + int diff,dc,k; + int t; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? stbi__extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * dequant[0]); + + // decode AC components, see JPEG spec + k = 1; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * dequant[zig]); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); + } + } + } while (k < 64); + return 1; +} + +static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) +{ + int diff,dc; + int t; + if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + if (j->succ_high == 0) { + // first scan for DC coefficient, must be first + memset(data,0,64*sizeof(data[0])); // 0 all the ac values now + t = stbi__jpeg_huff_decode(j, hdc); + diff = t ? stbi__extend_receive(j, t) : 0; + + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc << j->succ_low); + } else { + // refinement scan for DC coefficient + if (stbi__jpeg_get_bit(j)) + data[0] += (short) (1 << j->succ_low); + } + return 1; +} + +// @OPTIMIZE: store non-zigzagged during the decode passes, +// and only de-zigzag when dequantizing +static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) +{ + int k; + if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->succ_high == 0) { + int shift = j->succ_low; + + if (j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) << shift); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r); + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } else { + k += r; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) << shift); + } + } + } while (k <= j->spec_end); + } else { + // refinement scan for these AC coefficients + + short bit = (short) (1 << j->succ_low); + + if (j->eob_run) { + --j->eob_run; + for (k = j->spec_start; k <= j->spec_end; ++k) { + short *p = &data[stbi__jpeg_dezigzag[k]]; + if (*p != 0) + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } + } else { + k = j->spec_start; + do { + int r,s; + int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r) - 1; + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + r = 64; // force end of block + } else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } else { + if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if (stbi__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while (k <= j->spec_end) { + short *p = &data[stbi__jpeg_dezigzag[k++]]; + if (*p != 0) { + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } else { + if (r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while (k <= j->spec_end); + } + } + return 1; +} + +// take a -128..127 value and stbi__clamp it and convert to 0..255 +stbi_inline static stbi_uc stbi__clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (stbi_uc) x; +} + +#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) << 12) + +// derived from jidctint -- DCT_ISLOW +#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3*stbi__f2f(-1.847759065f); \ + t3 = p1 + p2*stbi__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2+p3); \ + t1 = stbi__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ + t0 = t0*stbi__f2f( 0.298631336f); \ + t1 = t1*stbi__f2f( 2.053119869f); \ + t2 = t2*stbi__f2f( 3.072711026f); \ + t3 = t3*stbi__f2f( 1.501321110f); \ + p1 = p5 + p1*stbi__f2f(-0.899976223f); \ + p2 = p5 + p2*stbi__f2f(-2.562915447f); \ + p3 = p3*stbi__f2f(-1.961570560f); \ + p4 = p4*stbi__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) +{ + int i,val[64],*v=val; + stbi_uc *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0] << 2; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = stbi__clamp((x0+t3) >> 17); + o[7] = stbi__clamp((x0-t3) >> 17); + o[1] = stbi__clamp((x1+t2) >> 17); + o[6] = stbi__clamp((x1-t2) >> 17); + o[2] = stbi__clamp((x2+t1) >> 17); + o[5] = stbi__clamp((x2-t1) >> 17); + o[3] = stbi__clamp((x3+t0) >> 17); + o[4] = stbi__clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SSE2 +// sse2 integer IDCT. not the fastest possible implementation but it +// produces bit-identical results to the generic C version so it's +// fully "transparent". +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + // This is constructed to match our regular (generic) integer IDCT exactly. + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + // dot product constant: even elems=x, odd elems=y + #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + // out(1) = c1[even]*x + c1[odd]*y + #define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + // out = in << 12 (in 16-bit, out 32-bit) + #define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + // wide add + #define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + // wide sub + #define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + // butterfly a/b, add bias, then shift by "s" and pack + #define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + // 8-bit interleave step (for transposes) + #define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + // 16-bit interleave step (for transposes) + #define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + + #define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); + + // rounding biases in column/row passes, see stbi__idct_block for explanation. + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + + // load + row0 = _mm_load_si128((const __m128i *) (data + 0*8)); + row1 = _mm_load_si128((const __m128i *) (data + 1*8)); + row2 = _mm_load_si128((const __m128i *) (data + 2*8)); + row3 = _mm_load_si128((const __m128i *) (data + 3*8)); + row4 = _mm_load_si128((const __m128i *) (data + 4*8)); + row5 = _mm_load_si128((const __m128i *) (data + 5*8)); + row6 = _mm_load_si128((const __m128i *) (data + 6*8)); + row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + + // column pass + dct_pass(bias_0, 10); + + { + // 16bit 8x8 transpose pass 1 + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + // transpose pass 2 + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + // transpose pass 3 + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + // row pass + dct_pass(bias_1, 17); + + { + // pack + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif // STBI_SSE2 + +#ifdef STBI_NEON + +// NEON integer IDCT. should produce bit-identical +// results to the generic C version. +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + +// wide add +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + +// wide sub +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + +// butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0*8); + row1 = vld1q_s16(data + 1*8); + row2 = vld1q_s16(data + 2*8); + row3 = vld1q_s16(data + 3*8); + row4 = vld1q_s16(data + 4*8); + row5 = vld1q_s16(data + 5*8); + row6 = vld1q_s16(data + 6*8); + row7 = vld1q_s16(data + 7*8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { +// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. +// whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + // row pass + // vrshrn_n_s32 only supports shifts up to 16, we need + // 17. so do a non-rounding shift of 16 first then follow + // up with a rounding shift by 1. + dct_pass(vshrn_n_s32, 16); + + { + // pack and round + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + // again, these can translate into one instruction, but often don't. +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + // sadly can't use interleaved stores here since we only write + // 8 bytes to each scan line! + + // 8x8 8-bit transpose pass 1 + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + // pass 2 + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + // pass 3 + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + // store + vst1_u8(out, p0); out += out_stride; + vst1_u8(out, p1); out += out_stride; + vst1_u8(out, p2); out += out_stride; + vst1_u8(out, p3); out += out_stride; + vst1_u8(out, p4); out += out_stride; + vst1_u8(out, p5); out += out_stride; + vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif // STBI_NEON + +#define STBI__MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static stbi_uc stbi__get_marker(stbi__jpeg *j) +{ + stbi_uc x; + if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } + x = stbi__get8(j->s); + if (x != 0xff) return STBI__MARKER_none; + while (x == 0xff) + x = stbi__get8(j->s); + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, stbi__jpeg_reset the entropy decoder and +// the dc prediction +static void stbi__jpeg_reset(stbi__jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->marker = STBI__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int stbi__parse_entropy_coded_data(stbi__jpeg *z) +{ + stbi__jpeg_reset(z); + if (!z->progressive) { + if (z->scan_n == 1) { + int i,j; + STBI_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + STBI_SIMD_ALIGN(short, data[64]); + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } else { + if (z->scan_n == 1) { + int i,j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) { + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } else { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x); + int y2 = (j*z->img_comp[n].v + y); + short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void stbi__jpeg_dequantize(short *data, stbi_uc *dequant) +{ + int i; + for (i=0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void stbi__jpeg_finish(stbi__jpeg *z) +{ + if (z->progressive) { + // dequantize and idct the data + int i,j,n; + for (n=0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int stbi__process_marker(stbi__jpeg *z, int m) +{ + int L; + switch (m) { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker","Corrupt JPEG"); + + case 0xDD: // DRI - specify restart interval + if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s)-2; + while (L > 0) { + int q = stbi__get8(z->s); + int p = q >> 4; + int t = q & 15,i; + if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG"); + if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + for (i=0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s); + L -= 65; + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s)-2; + while (L > 0) { + stbi_uc *v; + int sizes[16],i,n=0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < n; ++i) + v[i] = stbi__get8(z->s); + if (tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L==0; + } + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + stbi__skip(z->s, stbi__get16be(z->s)-2); + return 1; + } + return 0; +} + +// after we see SOS +static int stbi__process_scan_header(stbi__jpeg *z) +{ + int i; + int Ls = stbi__get16be(z->s); + z->scan_n = stbi__get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = stbi__get8(z->s), which; + int q = stbi__get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; // no match + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = stbi__get8(z->s); + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + aa = stbi__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if (z->progressive) { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } else { + if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int stbi__process_frame_header(stbi__jpeg *z, int scan) +{ + stbi__context *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG + p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires + c = stbi__get8(s); + if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG"); // JFIF requires + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); + + z->rgb = 0; + for (i=0; i < s->img_n; ++i) { + static unsigned char rgb[3] = { 'R', 'G', 'B' }; + z->img_comp[i].id = stbi__get8(s); + if (z->img_comp[i].id != i+1) // JFIF requires + if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files! + // somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format) + if (z->img_comp[i].id != rgb[i]) + return stbi__err("bad component ID","Corrupt JPEG"); + ++z->rgb; + } + q = stbi__get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); + } + + if (scan != STBI__SCAN_load) return 1; + + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].raw_data = stbi__malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); + + if (z->img_comp[i].raw_data == NULL) { + for(--i; i >= 0; --i) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + } + return stbi__err("outofmem", "Out of memory"); + } + // align blocks for idct using mmx/sse + z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + z->img_comp[i].linebuf = NULL; + if (z->progressive) { + z->img_comp[i].coeff_w = (z->img_comp[i].w2 + 7) >> 3; + z->img_comp[i].coeff_h = (z->img_comp[i].h2 + 7) >> 3; + z->img_comp[i].raw_coeff = STBI_MALLOC(z->img_comp[i].coeff_w * z->img_comp[i].coeff_h * 64 * sizeof(short) + 15); + z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } else { + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + } + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) + +#define stbi__SOF_progressive(x) ((x) == 0xc2) + +static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) +{ + int m; + z->marker = STBI__MARKER_none; // initialize cached marker to empty + m = stbi__get_marker(z); + if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); + if (scan == STBI__SCAN_type) return 1; + m = stbi__get_marker(z); + while (!stbi__SOF(m)) { + if (!stbi__process_marker(z,m)) return 0; + m = stbi__get_marker(z); + while (m == STBI__MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + m = stbi__get_marker(z); + } + } + z->progressive = stbi__SOF_progressive(m); + if (!stbi__process_frame_header(z, scan)) return 0; + return 1; +} + +// decode image to YCbCr format +static int stbi__decode_jpeg_image(stbi__jpeg *j) +{ + int m; + for (m = 0; m < 4; m++) { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + m = stbi__get_marker(j); + while (!stbi__EOI(m)) { + if (stbi__SOS(m)) { + if (!stbi__process_scan_header(j)) return 0; + if (!stbi__parse_entropy_coded_data(j)) return 0; + if (j->marker == STBI__MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!stbi__at_eof(j->s)) { + int x = stbi__get8(j->s); + if (x == 255) { + j->marker = stbi__get8(j->s); + break; + } else if (x != 0) { + return stbi__err("junk before marker", "Corrupt JPEG"); + } + } + // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 + } + } else { + if (!stbi__process_marker(j, m)) return 0; + } + m = stbi__get_marker(j); + } + if (j->progressive) + stbi__jpeg_finish(j); + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, + int w, int hs); + +#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) + +static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + stbi_uc *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = stbi__div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = stbi__div4(n+input[i-1]); + out[i*2+1] = stbi__div4(n+input[i+1]); + } + out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) + +static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = stbi__div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i=0,t0,t1; + + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + // process groups of 8 pixels for as long as we can. + // note we can't handle the last pixel in a row in this loop + // because we need to handle the filter boundary conditions. + for (; i < ((w-1) & ~7); i += 8) { +#if defined(STBI_SSE2) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + // interleave even and odd pixels, then undo scaling. + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + // pack and write output + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *) (out + i*2), outv); +#elif defined(STBI_NEON) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + // undo scaling and round, then store with even/odd phases interleaved + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i*2, o); +#endif + + // "previous" value for next iter + t1 = 3*in_near[i+7] + in_far[i+7]; + } + + t0 = t1; + t1 = 3*in_near[i] + in_far[i]; + out[i*2] = stbi__div16(3*t1 + t0 + 8); + + for (++i; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} +#endif + +static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + STBI_NOTUSED(in_far); + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +#ifdef STBI_JPEG_OLD +// this is the same YCbCr-to-RGB calculation that stb_image has used +// historically before the algorithm changes in 1.49 +#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 16) + 32768; // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr*float2fixed(1.40200f); + g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); + b = y_fixed + cb*float2fixed(1.77200f); + r >>= 16; + g >>= 16; + b >>= 16; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#else +// this is a reduced-precision calculation of YCbCr-to-RGB introduced +// to make sure the code produces the same results in both SIMD and scalar +#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* float2fixed(1.40200f); + g = y_fixed + (cr*-float2fixed(0.71414f)) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) +{ + int i = 0; + +#ifdef STBI_SSE2 + // step == 3 is pretty ugly on the final interleave, and i'm not convinced + // it's useful in practice (you wouldn't use it for textures, for example). + // so just accelerate step == 4 case. + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); + __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); + __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); + __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); + __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); // alpha channel + + for (; i+7 < count; i += 8) { + // load + __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 + + // unpack to short (and left-shift cr, cb by 8) + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + // color transform + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + // descale + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + // back to byte, set up for transpose + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + // transpose to interleave channels + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + // store + _mm_storeu_si128((__m128i *) (out + 0), o0); + _mm_storeu_si128((__m128i *) (out + 16), o1); + out += 32; + } + } +#endif + +#ifdef STBI_NEON + // in this version, step=3 support would be easy to add. but is there demand? + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); + int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); + int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); + int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + + for (; i+7 < count; i += 8) { + // load + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + // expand to s16 + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + // color transform + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + // undo scaling, round, convert to byte + uint8x8x4_t o; + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + // store, interleaving r/g/b/a + vst4_u8(out, o); + out += 8*4; + } + } +#endif + + for (; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* float2fixed(1.40200f); + g = y_fixed + cr*-float2fixed(0.71414f) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +// set up the kernels +static void stbi__setup_jpeg(stbi__jpeg *j) +{ + j->idct_block_kernel = stbi__idct_block; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; + +#ifdef STBI_SSE2 + if (stbi__sse2_available()) { + j->idct_block_kernel = stbi__idct_simd; + #ifndef STBI_JPEG_OLD + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + #endif + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; + } +#endif + +#ifdef STBI_NEON + j->idct_block_kernel = stbi__idct_simd; + #ifndef STBI_JPEG_OLD + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + #endif + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; +#endif +} + +// clean up the temporary component buffers +static void stbi__cleanup_jpeg(stbi__jpeg *j) +{ + int i; + for (i=0; i < j->s->img_n; ++i) { + if (j->img_comp[i].raw_data) { + STBI_FREE(j->img_comp[i].raw_data); + j->img_comp[i].raw_data = NULL; + j->img_comp[i].data = NULL; + } + if (j->img_comp[i].raw_coeff) { + STBI_FREE(j->img_comp[i].raw_coeff); + j->img_comp[i].raw_coeff = 0; + j->img_comp[i].coeff = 0; + } + if (j->img_comp[i].linebuf) { + STBI_FREE(j->img_comp[i].linebuf); + j->img_comp[i].linebuf = NULL; + } + } +} + +typedef struct +{ + resample_row_func resample; + stbi_uc *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi__resample; + +static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n; + z->s->img_n = 0; // make stbi__cleanup_jpeg safe + + // validate req_comp + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + + // load a jpeg image from whichever source, but leave in YCbCr format + if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n; + + if (z->s->img_n == 3 && n < 3) + decode_n = 1; + else + decode_n = z->s->img_n; + + // resample and color-convert + { + int k; + unsigned int i,j; + stbi_uc *output; + stbi_uc *coutput[4]; + + stbi__resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; + else r->resample = stbi__resample_row_generic; + } + + // can't error after this so, this is safe + output = (stbi_uc *) stbi__malloc(n * z->s->img_x * z->s->img_y + 1); + if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + stbi_uc *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + stbi_uc *y = coutput[0]; + if (z->s->img_n == 3) { + if (z->rgb == 3) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = y[i]; + out[1] = coutput[1][i]; + out[2] = coutput[2][i]; + out[3] = 255; + out += n; + } + } else { + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + } + } + stbi__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n; // report original components, not output + return output; + } +} + +static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char* result; + stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + j->s = s; + stbi__setup_jpeg(j); + result = load_jpeg_image(j, x,y,comp,req_comp); + STBI_FREE(j); + return result; +} + +static int stbi__jpeg_test(stbi__context *s) +{ + int r; + stbi__jpeg j; + j.s = s; + stbi__setup_jpeg(&j); + r = stbi__decode_jpeg_header(&j, STBI__SCAN_type); + stbi__rewind(s); + return r; +} + +static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) +{ + if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { + stbi__rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n; + return 1; +} + +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) +{ + int result; + stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); + j->s = s; + result = stbi__jpeg_info_raw(j, x, y, comp); + STBI_FREE(j); + return result; +} +#endif + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +#ifndef STBI_NO_ZLIB + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + stbi__uint16 fast[1 << STBI__ZFAST_BITS]; + stbi__uint16 firstcode[16]; + int maxcode[17]; + stbi__uint16 firstsymbol[16]; + stbi_uc size[288]; + stbi__uint16 value[288]; +} stbi__zhuffman; + +stbi_inline static int stbi__bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int stbi__bit_reverse(int v, int bits) +{ + STBI_ASSERT(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return stbi__bitreverse16(v) >> (16-bits); +} + +static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 0, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + if (sizes[i] > (1 << i)) + return stbi__err("bad sizes", "Corrupt PNG"); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (stbi__uint16) code; + z->firstsymbol[i] = (stbi__uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); + z->size [c] = (stbi_uc ) s; + z->value[c] = (stbi__uint16) i; + if (s <= STBI__ZFAST_BITS) { + int j = stbi__bit_reverse(next_code[s],s); + while (j < (1 << STBI__ZFAST_BITS)) { + z->fast[j] = fastv; + j += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + stbi_uc *zbuffer, *zbuffer_end; + int num_bits; + stbi__uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + stbi__zhuffman z_length, z_distance; +} stbi__zbuf; + +stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) +{ + if (z->zbuffer >= z->zbuffer_end) return 0; + return *z->zbuffer++; +} + +static void stbi__fill_bits(stbi__zbuf *z) +{ + do { + STBI_ASSERT(z->code_buffer < (1U << z->num_bits)); + z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) stbi__fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s,k; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = stbi__bit_reverse(a->code_buffer, 16); + for (s=STBI__ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s == 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + STBI_ASSERT(z->size[b] == s); + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s; + if (a->num_bits < 16) stbi__fill_bits(a); + b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; + if (b) { + s = b >> 9; + a->code_buffer >>= s; + a->num_bits -= s; + return b & 511; + } + return stbi__zhuffman_decode_slowpath(a, z); +} + +static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes +{ + char *q; + int cur, limit, old_limit; + z->zout = zout; + if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); + cur = (int) (z->zout - z->zout_start); + limit = old_limit = (int) (z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + STBI_NOTUSED(old_limit); + if (q == NULL) return stbi__err("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static int stbi__zlength_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static int stbi__zlength_extra[31]= +{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + +static int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static int stbi__zdist_extra[32] = +{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static int stbi__parse_huffman_block(stbi__zbuf *a) +{ + char *zout = a->zout; + for(;;) { + int z = stbi__zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes + if (zout >= a->zout_end) { + if (!stbi__zexpand(a, zout, 1)) return 0; + zout = a->zout; + } + *zout++ = (char) z; + } else { + stbi_uc *p; + int len,dist; + if (z == 256) { + a->zout = zout; + return 1; + } + z -= 257; + len = stbi__zlength_base[z]; + if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + z = stbi__zhuffman_decode(a, &a->z_distance); + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); + dist = stbi__zdist_base[z]; + if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); + if (zout + len > a->zout_end) { + if (!stbi__zexpand(a, zout, len)) return 0; + zout = a->zout; + } + p = (stbi_uc *) (zout - dist); + if (dist == 1) { // run of one byte; common in images. + stbi_uc v = *p; + if (len) { do *zout++ = v; while (--len); } + } else { + if (len) { do *zout++ = *p++; while (--len); } + } + } + } +} + +static int stbi__compute_huffman_codes(stbi__zbuf *a) +{ + static stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + stbi__zhuffman z_codelength; + stbi_uc lencodes[286+32+137];//padding for maximum single op + stbi_uc codelength_sizes[19]; + int i,n; + + int hlit = stbi__zreceive(a,5) + 257; + int hdist = stbi__zreceive(a,5) + 1; + int hclen = stbi__zreceive(a,4) + 4; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = stbi__zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + } + if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < hlit + hdist) { + int c = stbi__zhuffman_decode(a, &z_codelength); + if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if (c < 16) + lencodes[n++] = (stbi_uc) c; + else if (c == 16) { + c = stbi__zreceive(a,2)+3; + memset(lencodes+n, lencodes[n-1], c); + n += c; + } else if (c == 17) { + c = stbi__zreceive(a,3)+3; + memset(lencodes+n, 0, c); + n += c; + } else { + STBI_ASSERT(c == 18); + c = stbi__zreceive(a,7)+11; + memset(lencodes+n, 0, c); + n += c; + } + } + if (n != hlit+hdist) return stbi__err("bad codelengths","Corrupt PNG"); + if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int stbi__parse_uncompressed_block(stbi__zbuf *a) +{ + stbi_uc header[4]; + int len,nlen,k; + if (a->num_bits & 7) + stbi__zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check + a->code_buffer >>= 8; + a->num_bits -= 8; + } + STBI_ASSERT(a->num_bits == 0); + // now fill header the normal way + while (k < 4) + header[k++] = stbi__zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!stbi__zexpand(a, a->zout, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int stbi__parse_zlib_header(stbi__zbuf *a) +{ + int cmf = stbi__zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = stbi__zget8(a); + if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +// @TODO: should statically initialize these for optimal thread safety +static stbi_uc stbi__zdefault_length[288], stbi__zdefault_distance[32]; +static void stbi__init_zdefaults(void) +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; + for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; + for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; + for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; + + for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; +} + +static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!stbi__parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = stbi__zreceive(a,1); + type = stbi__zreceive(a,2); + if (type == 0) { + if (!stbi__parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!stbi__zdefault_distance[31]) stbi__init_zdefaults(); + if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; + } else { + if (!stbi__compute_huffman_codes(a)) return 0; + } + if (!stbi__parse_huffman_block(a)) return 0; + } + } while (!final); + return 1; +} + +static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return stbi__parse_zlib(a, parse_header); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer+len; + if (stbi__do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} +#endif + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + +#ifndef STBI_NO_PNG +typedef struct +{ + stbi__uint32 length; + stbi__uint32 type; +} stbi__pngchunk; + +static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) +{ + stbi__pngchunk c; + c.length = stbi__get32be(s); + c.type = stbi__get32be(s); + return c; +} + +static int stbi__check_png_header(stbi__context *s) +{ + static stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi__context *s; + stbi_uc *idata, *expanded, *out; + int depth; +} stbi__png; + + +enum { + STBI__F_none=0, + STBI__F_sub=1, + STBI__F_up=2, + STBI__F_avg=3, + STBI__F_paeth=4, + // synthetic filters used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static stbi_uc first_row_filter[5] = +{ + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static int stbi__paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +static stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; + +// create the png data from post-deflated data +static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) +{ + int bytes = (depth == 16? 2 : 1); + stbi__context *s = a->s; + stbi__uint32 i,j,stride = x*out_n*bytes; + stbi__uint32 img_len, img_width_bytes; + int k; + int img_n = s->img_n; // copy it into a local for later + + int output_bytes = out_n*bytes; + int filter_bytes = img_n*bytes; + int width = x; + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); + a->out = (stbi_uc *) stbi__malloc(x * y * output_bytes); // extra bytes to write off the end into + if (!a->out) return stbi__err("outofmem", "Out of memory"); + + img_width_bytes = (((img_n * x * depth) + 7) >> 3); + img_len = (img_width_bytes + 1) * y; + if (s->img_x == x && s->img_y == y) { + if (raw_len != img_len) return stbi__err("not enough pixels","Corrupt PNG"); + } else { // interlaced: + if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + } + + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *prior = cur - stride; + int filter = *raw++; + + if (filter > 4) + return stbi__err("invalid filter","Corrupt PNG"); + + if (depth < 8) { + STBI_ASSERT(img_width_bytes <= x); + cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place + filter_bytes = 1; + width = img_width_bytes; + } + + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + + // handle first byte explicitly + for (k=0; k < filter_bytes; ++k) { + switch (filter) { + case STBI__F_none : cur[k] = raw[k]; break; + case STBI__F_sub : cur[k] = raw[k]; break; + case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; + case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; + case STBI__F_avg_first : cur[k] = raw[k]; break; + case STBI__F_paeth_first: cur[k] = raw[k]; break; + } + } + + if (depth == 8) { + if (img_n != out_n) + cur[img_n] = 255; // first pixel + raw += img_n; + cur += out_n; + prior += out_n; + } else if (depth == 16) { + if (img_n != out_n) { + cur[filter_bytes] = 255; // first pixel top byte + cur[filter_bytes+1] = 255; // first pixel bottom byte + } + raw += filter_bytes; + cur += output_bytes; + prior += output_bytes; + } else { + raw += 1; + cur += 1; + prior += 1; + } + + // this is a little gross, so that we don't switch per-pixel or per-component + if (depth < 8 || img_n == out_n) { + int nk = (width - 1)*filter_bytes; + #define CASE(f) \ + case f: \ + for (k=0; k < nk; ++k) + switch (filter) { + // "none" filter turns into a memcpy here; make that explicit. + case STBI__F_none: memcpy(cur, raw, nk); break; + CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); break; + CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); break; + CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); break; + CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); break; + CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); break; + } + #undef CASE + raw += nk; + } else { + STBI_ASSERT(img_n+1 == out_n); + #define CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ + for (k=0; k < filter_bytes; ++k) + switch (filter) { + CASE(STBI__F_none) cur[k] = raw[k]; break; + CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); break; + CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); break; + CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); break; + CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); break; + CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break; + } + #undef CASE + + // the loop above sets the high byte of the pixels' alpha, but for + // 16 bit png files we also need the low byte set. we'll do that here. + if (depth == 16) { + cur = a->out + stride*j; // start at the beginning of the row again + for (i=0; i < x; ++i,cur+=output_bytes) { + cur[filter_bytes+1] = 255; + } + } + } + } + + // we make a separate pass to expand bits to pixels; for performance, + // this could run two scanlines behind the above code, so it won't + // intefere with filtering but will still be in the cache. + if (depth < 8) { + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; + // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit + // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop + stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + + // note that the final byte might overshoot and write more data than desired. + // we can allocate enough data that this never writes out of memory, but it + // could also overwrite the next scanline. can it overwrite non-empty data + // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. + // so we need to explicitly clamp the final ones + + if (depth == 4) { + for (k=x*img_n; k >= 2; k-=2, ++in) { + *cur++ = scale * ((*in >> 4) ); + *cur++ = scale * ((*in ) & 0x0f); + } + if (k > 0) *cur++ = scale * ((*in >> 4) ); + } else if (depth == 2) { + for (k=x*img_n; k >= 4; k-=4, ++in) { + *cur++ = scale * ((*in >> 6) ); + *cur++ = scale * ((*in >> 4) & 0x03); + *cur++ = scale * ((*in >> 2) & 0x03); + *cur++ = scale * ((*in ) & 0x03); + } + if (k > 0) *cur++ = scale * ((*in >> 6) ); + if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); + if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); + } else if (depth == 1) { + for (k=x*img_n; k >= 8; k-=8, ++in) { + *cur++ = scale * ((*in >> 7) ); + *cur++ = scale * ((*in >> 6) & 0x01); + *cur++ = scale * ((*in >> 5) & 0x01); + *cur++ = scale * ((*in >> 4) & 0x01); + *cur++ = scale * ((*in >> 3) & 0x01); + *cur++ = scale * ((*in >> 2) & 0x01); + *cur++ = scale * ((*in >> 1) & 0x01); + *cur++ = scale * ((*in ) & 0x01); + } + if (k > 0) *cur++ = scale * ((*in >> 7) ); + if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); + if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); + if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); + if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); + if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); + if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); + } + if (img_n != out_n) { + int q; + // insert alpha = 255 + cur = a->out + stride*j; + if (img_n == 1) { + for (q=x-1; q >= 0; --q) { + cur[q*2+1] = 255; + cur[q*2+0] = cur[q]; + } + } else { + STBI_ASSERT(img_n == 3); + for (q=x-1; q >= 0; --q) { + cur[q*4+3] = 255; + cur[q*4+2] = cur[q*3+2]; + cur[q*4+1] = cur[q*3+1]; + cur[q*4+0] = cur[q*3+0]; + } + } + } + } + } else if (depth == 16) { + // force the image data from big-endian to platform-native. + // this is done in a separate pass due to the decoding relying + // on the data being untouched, but could probably be done + // per-line during decode if care is taken. + stbi_uc *cur = a->out; + stbi__uint16 *cur16 = (stbi__uint16*)cur; + + for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { + *cur16 = (cur[0] << 8) | cur[1]; + } + } + + return 1; +} + +static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) +{ + stbi_uc *final; + int p; + if (!interlaced) + return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); + + // de-interlacing + final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; + if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + STBI_FREE(final); + return 0; + } + for (j=0; j < y; ++j) { + for (i=0; i < x; ++i) { + int out_y = j*yspc[p]+yorig[p]; + int out_x = i*xspc[p]+xorig[p]; + memcpy(final + out_y*a->s->img_x*out_n + out_x*out_n, + a->out + (j*x+i)*out_n, out_n); + } + } + STBI_FREE(a->out); + image_data += img_len; + image_data_len -= img_len; + } + } + a->out = final; + + return 1; +} + +static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi__uint16 *p = (stbi__uint16*) z->out; + + // compute color-based transparency, assuming we've + // already got 65535 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 65535); + p += 2; + } + } else { + for (i = 0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) +{ + stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; + stbi_uc *p, *temp_out, *orig = a->out; + + p = (stbi_uc *) stbi__malloc(pixel_count * pal_img_n); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + STBI_FREE(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi__reduce_png(stbi__png *p) +{ + int i; + int img_len = p->s->img_x * p->s->img_y * p->s->img_out_n; + stbi_uc *reduced; + stbi__uint16 *orig = (stbi__uint16*)p->out; + + if (p->depth != 16) return 1; // don't need to do anything if not 16-bit data + + reduced = (stbi_uc *)stbi__malloc(img_len); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is a decent approx of 16->8 bit scaling + + p->out = reduced; + STBI_FREE(orig); + + return 1; +} + +static int stbi__unpremultiply_on_load = 0; +static int stbi__de_iphone_flag = 0; + +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag = flag_true_if_should_convert; +} + +static void stbi__de_iphone(stbi__png *z) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + STBI_ASSERT(s->img_out_n == 4); + if (stbi__unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + stbi_uc a = p[3]; + stbi_uc t = p[0]; + if (a) { + p[0] = p[2] * 255 / a; + p[1] = p[1] * 255 / a; + p[2] = t * 255 / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +#define STBI__PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) + +static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) +{ + stbi_uc palette[1024], pal_img_n=0; + stbi_uc has_trans=0, tc[3]; + stbi__uint16 tc16[3]; + stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, color=0, is_iphone=0; + stbi__context *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!stbi__check_png_header(s)) return 0; + + if (scan == STBI__SCAN_type) return 1; + + for (;;) { + stbi__pngchunk c = stbi__get_chunk_header(s); + switch (c.type) { + case STBI__PNG_TYPE('C','g','B','I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I','H','D','R'): { + int comp,filter; + if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); + s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); + comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); + filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); + interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + if (scan == STBI__SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case STBI__PNG_TYPE('P','L','T','E'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = stbi__get8(s); + palette[i*4+1] = stbi__get8(s); + palette[i*4+2] = stbi__get8(s); + palette[i*4+3] = 255; + } + break; + } + + case STBI__PNG_TYPE('t','R','N','S'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = stbi__get8(s); + } else { + if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); + if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); + has_trans = 1; + if (z->depth == 16) { + for (k = 0; k < s->img_n; ++k) tc16[k] = stbi__get16be(s); // copy the values as-is + } else { + for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I','D','A','T'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); + if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } + if ((int)(ioff + c.length) < (int)ioff) return 0; + if (ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case STBI__PNG_TYPE('I','E','N','D'): { + stbi__uint32 raw_len, bpl; + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (scan != STBI__SCAN_load) return 1; + if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); + if (z->expanded == NULL) return 0; // zlib should set error + STBI_FREE(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; + if (has_trans) { + if (z->depth == 16) { + if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; + } else { + if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; + } + } + if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } + STBI_FREE(z->expanded); z->expanded = NULL; + return 1; + } + + default: + // if critical, fail + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); + #endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; + } + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + } +} + +static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp) +{ + unsigned char *result=NULL; + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + if (p->depth == 16) { + if (!stbi__reduce_png(p)) { + return result; + } + } + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + result = stbi__convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + STBI_FREE(p->out); p->out = NULL; + STBI_FREE(p->expanded); p->expanded = NULL; + STBI_FREE(p->idata); p->idata = NULL; + + return result; +} + +static unsigned char *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__png p; + p.s = s; + return stbi__do_png(&p, x,y,comp,req_comp); +} + +static int stbi__png_test(stbi__context *s) +{ + int r; + r = stbi__check_png_header(s); + stbi__rewind(s); + return r; +} + +static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) +{ + if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { + stbi__rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__png p; + p.s = s; + return stbi__png_info_raw(&p, x, y, comp); +} +#endif + +// Microsoft/Windows BMP image + +#ifndef STBI_NO_BMP +static int stbi__bmp_test_raw(stbi__context *s) +{ + int r; + int sz; + if (stbi__get8(s) != 'B') return 0; + if (stbi__get8(s) != 'M') return 0; + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + stbi__get32le(s); // discard data offset + sz = stbi__get32le(s); + r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); + return r; +} + +static int stbi__bmp_test(stbi__context *s) +{ + int r = stbi__bmp_test_raw(s); + stbi__rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int stbi__high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) n += 16, z >>= 16; + if (z >= 0x00100) n += 8, z >>= 8; + if (z >= 0x00010) n += 4, z >>= 4; + if (z >= 0x00004) n += 2, z >>= 2; + if (z >= 0x00002) n += 1, z >>= 1; + return n; +} + +static int stbi__bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +static int stbi__shiftsigned(int v, int shift, int bits) +{ + int result; + int z=0; + + if (shift < 0) v <<= -shift; + else v >>= shift; + result = v; + + z = bits; + while (z < 8) { + result += v >> z; + z += bits; + } + return result; +} + +typedef struct +{ + int bpp, offset, hsz; + unsigned int mr,mg,mb,ma, all_a; +} stbi__bmp_data; + +static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) +{ + int hsz; + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + info->mr = info->mg = info->mb = info->ma = 0; + + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = stbi__get16le(s); + s->img_y = stbi__get16le(s); + } else { + s->img_x = stbi__get32le(s); + s->img_y = stbi__get32le(s); + } + if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + info->bpp = stbi__get16le(s); + if (info->bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit"); + if (hsz != 12) { + int compress = stbi__get32le(s); + if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + } + if (info->bpp == 16 || info->bpp == 32) { + if (compress == 0) { + if (info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } else { + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; + } + } else if (compress == 3) { + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + // not documented, but generated by photoshop and handled by mspaint + if (info->mr == info->mg && info->mg == info->mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else { + int i; + if (hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); + stbi__get32le(s); // discard color space + for (i=0; i < 12; ++i) + stbi__get32le(s); // discard color space parameters + if (hsz == 124) { + stbi__get32le(s); // discard rendering intent + stbi__get32le(s); // discard offset of profile data + stbi__get32le(s); // discard size of profile data + stbi__get32le(s); // discard reserved + } + } + } + return (void *) 1; +} + + +static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *out; + unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + stbi_uc pal[256][4]; + int psize=0,i,j,width; + int flip_vertically, pad, target; + stbi__bmp_data info; + + info.all_a = 255; + if (stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if (info.hsz == 12) { + if (info.bpp < 24) + psize = (info.offset - 14 - 24) / 3; + } else { + if (info.bpp < 16) + psize = (info.offset - 14 - info.hsz) >> 2; + } + + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + + out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + if (info.bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + if (info.hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if (info.bpp == 4) width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) width = s->img_x; + else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=stbi__get8(s),v2=0; + if (info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + stbi__skip(s, pad); + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + stbi__skip(s, info.offset - 14 - info.hsz); + if (info.bpp == 24) width = 3 * s->img_x; + else if (info.bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (info.bpp == 24) { + easy = 1; + } else if (info.bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + unsigned char a; + out[z+2] = stbi__get8(s); + out[z+1] = stbi__get8(s); + out[z+0] = stbi__get8(s); + z += 3; + a = (easy == 2 ? stbi__get8(s) : 255); + all_a |= a; + if (target == 4) out[z++] = a; + } + } else { + int bpp = info.bpp; + for (i=0; i < (int) s->img_x; ++i) { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + int a; + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); + a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); + all_a |= a; + if (target == 4) out[z++] = STBI__BYTECAST(a); + } + } + stbi__skip(s, pad); + } + } + + // if alpha channel is all 0s, replace with all 255s + if (target == 4 && all_a == 0) + for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) + out[i] = 255; + + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i], p1[i] = p2[i], p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} +#endif + +// Targa Truevision - TGA +// by Jonathan Dummer +#ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if(is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: return STBI_grey; + case 16: if(is_grey) return STBI_grey_alpha; + // else: fall-through + case 15: if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; + case 24: // fall-through + case 32: return bits_per_pixel/8; + default: return 0; + } +} + +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if( tga_colormap_type > 1 ) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if ( tga_colormap_type == 1 ) { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip image x and y origin + tga_colormap_bpp = sz; + } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s,9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if( tga_w < 1 ) { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if( tga_h < 1 ) { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if (tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if(!tga_comp) { + stbi__rewind(s); + return 0; + } + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context *s) +{ + int res = 0; + int sz, tga_color_type; + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if ( tga_color_type == 1 ) { // colormapped (paletted) image + if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + stbi__skip(s,4); // skip image x and y origin + } else { // "normal" image w/o colormap + if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s,9); // skip colormap specification and image x/y origin + } + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: + stbi__rewind(s); + return res; +} + +// read 16bit value and convert to 24bit RGB +void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +{ + stbi__uint16 px = stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (r * 255)/31; + out[1] = (g * 255)/31; + out[2] = (b * 255)/31; + + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. +} + +static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + // read in the TGA header stuff + int tga_offset = stbi__get8(s); + int tga_indexed = stbi__get8(s); + int tga_image_type = stbi__get8(s); + int tga_is_RLE = 0; + int tga_palette_start = stbi__get16le(s); + int tga_palette_len = stbi__get16le(s); + int tga_palette_bits = stbi__get8(s); + int tga_x_origin = stbi__get16le(s); + int tga_y_origin = stbi__get16le(s); + int tga_width = stbi__get16le(s); + int tga_height = stbi__get16le(s); + int tga_bits_per_pixel = stbi__get8(s); + int tga_comp, tga_rgb16=0; + int tga_inverted = stbi__get8(s); + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4]; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); + + // tga info + *x = tga_width; + *y = tga_height; + if (comp) *comp = tga_comp; + + tga_data = (unsigned char*)stbi__malloc( (size_t)tga_width * tga_height * tga_comp ); + if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + stbi__skip(s, tga_offset ); + + if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { + for (i=0; i < tga_height; ++i) { + int row = tga_inverted ? tga_height -i - 1 : i; + stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; + stbi__getn(s, tga_row, tga_width * tga_comp); + } + } else { + // do I need to load a palette? + if ( tga_indexed) + { + // any data to skip? (offset usually = 0) + stbi__skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp ); + if (!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if (tga_rgb16) { + stbi_uc *pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb); + for (i=0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, pal_entry); + pal_entry += tga_comp; + } + } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + } + // load the data + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = stbi__get8(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if ( pal_idx >= tga_palette_len ) { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_comp; + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else if(tga_rgb16) { + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); + } else { + // read in the data raw + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = stbi__get8(s); + } + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + + // copy data + for (j = 0; j < tga_comp; ++j) + tga_data[i*tga_comp+j] = raw_data[j]; + + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * tga_comp; + int index2 = (tga_height - 1 - j) * tga_width * tga_comp; + for (i = tga_width * tga_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + STBI_FREE( tga_palette ); + } + } + + // swap RGB - if the source data was RGB16, it already is in the right order + if (tga_comp >= 3 && !tga_rgb16) + { + unsigned char* tga_pixel = tga_data; + for (i=0; i < tga_width * tga_height; ++i) + { + unsigned char temp = tga_pixel[0]; + tga_pixel[0] = tga_pixel[2]; + tga_pixel[2] = temp; + tga_pixel += tga_comp; + } + } + + // convert to target component count + if (req_comp && req_comp != tga_comp) + tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); + + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + // OK, done + return tga_data; +} +#endif + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s) +{ + int r = (stbi__get32be(s) == 0x38425053); + stbi__rewind(s); + return r; +} + +static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + int pixelCount; + int channelCount, compression; + int channel, i, count, len; + int bitdepth; + int w,h; + stbi_uc *out; + + // Check identifier + if (stbi__get32be(s) != 0x38425053) // "8BPS" + return stbi__errpuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (stbi__get16be(s) != 1) + return stbi__errpuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + stbi__skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) + return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = stbi__get32be(s); + w = stbi__get32be(s); + + // Make sure the depth is 8 bits. + bitdepth = stbi__get16be(s); + if (bitdepth != 8 && bitdepth != 16) + return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (stbi__get16be(s) != 3) + return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + stbi__skip(s,stbi__get32be(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + stbi__skip(s, stbi__get32be(s) ); + + // Skip the reserved data. + stbi__skip(s, stbi__get32be(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = stbi__get16be(s); + if (compression > 1) + return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + + // Create the destination image. + out = (stbi_uc *) stbi__malloc(4 * w*h); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, + // which we're going to just skip. + stbi__skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++, p += 4) + *p = (channel == 3 ? 255 : 0); + } else { + // Read the RLE data. + count = 0; + while (count < pixelCount) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len ^= 0x0FF; + len += 2; + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out + channel; + if (channel >= channelCount) { + // Fill this channel with default data. + stbi_uc val = channel == 3 ? 255 : 0; + for (i = 0; i < pixelCount; i++, p += 4) + *p = val; + } else { + // Read the data. + if (bitdepth == 16) { + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } + } + } + } + + if (channelCount >= 4) { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + // remove weird white matte from PSD + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } + } + } + + if (req_comp && req_comp != 4) { + out = stbi__convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + if (comp) *comp = 4; + *y = h; + *x = w; + + return out; +} +#endif + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +#ifndef STBI_NO_PIC +static int stbi__pic_is4(stbi__context *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (stbi__get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int stbi__pic_test_core(stbi__context *s) +{ + int i; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + stbi__get8(s); + + if (!stbi__pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} stbi__pic_packet; + +static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); + dest[i]=stbi__get8(s); + } + } + + return dest; +} + +static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + stbi__pic_packet packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return stbi__errpuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + + act_comp |= packet->channel; + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return stbi__errpuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=stbi__get8(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (stbi_uc) left; + + if (!stbi__readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = stbi__get8(s), i; + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + + if (count==128) + count = stbi__get16be(s); + else + count -= 127; + if (count > left) + return stbi__errpuc("bad file","scanline overrun"); + + if (!stbi__readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return stbi__errpuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp) +{ + stbi_uc *result; + int i, x,y; + + for (i=0; i<92; ++i) + stbi__get8(s); + + x = stbi__get16be(s); + y = stbi__get16be(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); + if ((1 << 28) / x < y) return stbi__errpuc("too large", "Image too large to decode"); + + stbi__get32be(s); //skip `ratio' + stbi__get16be(s); //skip `fields' + stbi__get16be(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) stbi__malloc(x*y*4); + memset(result, 0xff, x*y*4); + + if (!stbi__pic_load_core(s,x,y,comp, result)) { + STBI_FREE(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=stbi__convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi__pic_test(stbi__context *s) +{ + int r = stbi__pic_test_core(s); + stbi__rewind(s); + return r; +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb + +#ifndef STBI_NO_GIF +typedef struct +{ + stbi__int16 prefix; + stbi_uc first; + stbi_uc suffix; +} stbi__gif_lzw; + +typedef struct +{ + int w,h; + stbi_uc *out, *old_out; // output buffer (always 4 components) + int flags, bgindex, ratio, transparent, eflags, delay; + stbi_uc pal[256][4]; + stbi_uc lpal[256][4]; + stbi__gif_lzw codes[4096]; + stbi_uc *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; +} stbi__gif; + +static int stbi__gif_test_raw(stbi__context *s) +{ + int sz; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + sz = stbi__get8(s); + if (sz != '9' && sz != '7') return 0; + if (stbi__get8(s) != 'a') return 0; + return 1; +} + +static int stbi__gif_test(stbi__context *s) +{ + int r = stbi__gif_test_raw(s); + stbi__rewind(s); + return r; +} + +static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + pal[i][3] = transp == i ? 0 : 255; + } +} + +static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) +{ + stbi_uc version; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return stbi__err("not GIF", "Corrupt GIF"); + + version = stbi__get8(s); + if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); + if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + + stbi__g_failure_reason = ""; + g->w = stbi__get16le(s); + g->h = stbi__get16le(s); + g->flags = stbi__get8(s); + g->bgindex = stbi__get8(s); + g->ratio = stbi__get8(s); + g->transparent = -1; + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + if (!stbi__gif_header(s, g, comp, 1)) { + STBI_FREE(g); + stbi__rewind( s ); + return 0; + } + if (x) *x = g->w; + if (y) *y = g->h; + STBI_FREE(g); + return 1; +} + +static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) +{ + stbi_uc *p, *c; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi__out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + p = &g->out[g->cur_x + g->cur_y]; + c = &g->color_table[g->codes[code].suffix * 4]; + + if (c[3] >= 128) { + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) +{ + stbi_uc lzw_cs; + stbi__int32 len, init_code; + stbi__uint32 first; + stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi__gif_lzw *p; + + lzw_cs = stbi__get8(s); + if (lzw_cs > 12) return NULL; + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (init_code = 0; init_code < clear; init_code++) { + g->codes[init_code].prefix = -1; + g->codes[init_code].first = (stbi_uc) init_code; + g->codes[init_code].suffix = (stbi_uc) init_code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = stbi__get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (stbi__int32) stbi__get8(s) << valid_bits; + valid_bits += 8; + } else { + stbi__int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + stbi__skip(s, len); + while ((len = stbi__get8(s)) > 0) + stbi__skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) return stbi__errpuc("no clear code", "Corrupt GIF"); + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 4096) return stbi__errpuc("too many codes", "Corrupt GIF"); + p->prefix = (stbi__int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + + stbi__out_gif_code(g, (stbi__uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +static void stbi__fill_gif_background(stbi__gif *g, int x0, int y0, int x1, int y1) +{ + int x, y; + stbi_uc *c = g->pal[g->bgindex]; + for (y = y0; y < y1; y += 4 * g->w) { + for (x = x0; x < x1; x += 4) { + stbi_uc *p = &g->out[y + x]; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = 0; + } + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp) +{ + int i; + stbi_uc *prev_out = 0; + + if (g->out == 0 && !stbi__gif_header(s, g, comp,0)) + return 0; // stbi__g_failure_reason set by stbi__gif_header + + prev_out = g->out; + g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); + if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); + + switch ((g->eflags & 0x1C) >> 2) { + case 0: // unspecified (also always used on 1st frame) + stbi__fill_gif_background(g, 0, 0, 4 * g->w, 4 * g->w * g->h); + break; + case 1: // do not dispose + if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); + g->old_out = prev_out; + break; + case 2: // dispose to background + if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); + stbi__fill_gif_background(g, g->start_x, g->start_y, g->max_x, g->max_y); + break; + case 3: // dispose to previous + if (g->old_out) { + for (i = g->start_y; i < g->max_y; i += 4 * g->w) + memcpy(&g->out[i + g->start_x], &g->old_out[i + g->start_x], g->max_x - g->start_x); + } + break; + } + + for (;;) { + switch (stbi__get8(s)) { + case 0x2C: /* Image Descriptor */ + { + int prev_trans = -1; + stbi__int32 x, y, w, h; + stbi_uc *o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + g->lflags = stbi__get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *) g->lpal; + } else if (g->flags & 0x80) { + if (g->transparent >= 0 && (g->eflags & 0x01)) { + prev_trans = g->pal[g->transparent][3]; + g->pal[g->transparent][3] = 0; + } + g->color_table = (stbi_uc *) g->pal; + } else + return stbi__errpuc("missing color table", "Corrupt GIF"); + + o = stbi__process_gif_raster(s, g); + if (o == NULL) return NULL; + + if (prev_trans != -1) + g->pal[g->transparent][3] = (stbi_uc) prev_trans; + + return o; + } + + case 0x21: // Comment Extension. + { + int len; + if (stbi__get8(s) == 0xF9) { // Graphic Control Extension. + len = stbi__get8(s); + if (len == 4) { + g->eflags = stbi__get8(s); + g->delay = stbi__get16le(s); + g->transparent = stbi__get8(s); + } else { + stbi__skip(s, len); + break; + } + } + while ((len = stbi__get8(s)) != 0) + stbi__skip(s, len); + break; + } + + case 0x3B: // gif stream termination code + return (stbi_uc *) s; // using '1' causes warning on some compilers + + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); + } + } + + STBI_NOTUSED(req_comp); +} + +static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *u = 0; + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + memset(g, 0, sizeof(*g)); + + u = stbi__gif_load_next(s, g, comp, req_comp); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + if (u) { + *x = g->w; + *y = g->h; + if (req_comp && req_comp != 4) + u = stbi__convert_format(u, 4, req_comp, g->w, g->h); + } + else if (g->out) + STBI_FREE(g->out); + STBI_FREE(g); + return u; +} + +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) +{ + return stbi__gif_info_raw(s,x,y,comp); +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int stbi__hdr_test_core(stbi__context *s) +{ + const char *signature = "#?RADIANCE\n"; + int i; + for (i=0; signature[i]; ++i) + if (stbi__get8(s) != signature[i]) + return 0; + return 1; +} + +static int stbi__hdr_test(stbi__context* s) +{ + int r = stbi__hdr_test_core(s); + stbi__rewind(s); + return r; +} + +#define STBI__HDR_BUFLEN 1024 +static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) stbi__get8(z); + + while (!stbi__at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == STBI__HDR_BUFLEN-1) { + // flush to end of line + while (!stbi__at_eof(z) && stbi__get8(z) != '\n') + ; + break; + } + c = (char) stbi__get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + + + // Check identifier + if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) + return stbi__errpf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = (int) strtol(token, NULL, 10); + + *x = width; + *y = height; + + if (comp) *comp = 3; + if (req_comp == 0) req_comp = 3; + + // Read data + hdr_data = (float *) stbi__malloc(height * width * req_comp * sizeof(float)); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + stbi__getn(s, rgbe, 4); + stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = stbi__get8(s); + c2 = stbi__get8(s); + len = stbi__get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + stbi_uc rgbe[4]; + rgbe[0] = (stbi_uc) c1; + rgbe[1] = (stbi_uc) c2; + rgbe[2] = (stbi_uc) len; + rgbe[3] = (stbi_uc) stbi__get8(s); + stbi__hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + STBI_FREE(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= stbi__get8(s); + if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4); + + for (k = 0; k < 4; ++k) { + i = 0; + while (i < width) { + count = stbi__get8(s); + if (count > 128) { + // Run + value = stbi__get8(s); + count -= 128; + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = stbi__get8(s); + } + } + } + for (i=0; i < width; ++i) + stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + STBI_FREE(scanline); + } + + return hdr_data; +} + +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + + if (stbi__hdr_test(s) == 0) { + stbi__rewind( s ); + return 0; + } + + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi__rewind( s ); + return 0; + } + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *y = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *x = (int) strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +#ifndef STBI_NO_BMP +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) +{ + void *p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + stbi__rewind( s ); + if (p == NULL) + return 0; + *x = s->img_x; + *y = s->img_y; + *comp = info.ma ? 4 : 3; + return 1; +} +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) +{ + int channelCount; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + *y = stbi__get32be(s); + *x = stbi__get32be(s); + if (stbi__get16be(s) != 8) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 3) { + stbi__rewind( s ); + return 0; + } + *comp = 4; + return 1; +} +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained; + stbi__pic_packet packets[10]; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 88); + + *x = stbi__get16be(s); + *y = stbi__get16be(s); + if (stbi__at_eof(s)) { + stbi__rewind( s); + return 0; + } + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi__rewind( s ); + return 0; + } + + stbi__skip(s, 8); + + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + act_comp |= packet->channel; + + if (stbi__at_eof(s)) { + stbi__rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi__rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} +#endif + +// ************************************************************************************************* +// Portable Gray Map and Portable Pixel Map loader +// by Ken Miller +// +// PGM: http://netpbm.sourceforge.net/doc/pgm.html +// PPM: http://netpbm.sourceforge.net/doc/ppm.html +// +// Known limitations: +// Does not support comments in the header section +// Does not support ASCII image data (formats P2 and P3) +// Does not support 16-bit-per-channel + +#ifndef STBI_NO_PNM + +static int stbi__pnm_test(stbi__context *s) +{ + char p, t; + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + return 1; +} + +static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *out; + if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) + return 0; + *x = s->img_x; + *y = s->img_y; + *comp = s->img_n; + + out = (stbi_uc *) stbi__malloc(s->img_n * s->img_x * s->img_y); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + stbi__getn(s, out, s->img_n * s->img_x * s->img_y); + + if (req_comp && req_comp != s->img_n) { + out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + return out; +} + +static int stbi__pnm_isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) +{ + for (;;) { + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if (stbi__at_eof(s) || *c != '#') + break; + + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) + *c = (char) stbi__get8(s); + } +} + +static int stbi__pnm_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static int stbi__pnm_getinteger(stbi__context *s, char *c) +{ + int value = 0; + + while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { + value = value*10 + (*c - '0'); + *c = (char) stbi__get8(s); + } + + return value; +} + +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) +{ + int maxv; + char c, p, t; + + stbi__rewind( s ); + + // Get identifier + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + + c = (char) stbi__get8(s); + stbi__pnm_skip_whitespace(s, &c); + + *x = stbi__pnm_getinteger(s, &c); // read width + stbi__pnm_skip_whitespace(s, &c); + + *y = stbi__pnm_getinteger(s, &c); // read height + stbi__pnm_skip_whitespace(s, &c); + + maxv = stbi__pnm_getinteger(s, &c); // read max value + + if (maxv > 255) + return stbi__err("max value > 255", "PPM image not 8-bit"); + else + return 1; +} +#endif + +static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNG + if (stbi__png_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_GIF + if (stbi__gif_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_BMP + if (stbi__bmp_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PIC + if (stbi__pic_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_info(s, x, y, comp)) return 1; + #endif + + // test tga last because it's a crappy test! + #ifndef STBI_NO_TGA + if (stbi__tga_info(s, x, y, comp)) + return 1; + #endif + return stbi__err("unknown image type", "Image not of any known type, or corrupt"); +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__info_main(&s,x,y,comp); +} + +#endif // STB_IMAGE_IMPLEMENTATION + +/* + revision history: + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) allocate large structures on the stack + remove white matting for transparent PSD + fix reported channel count for PNG & BMP + re-enable SSE2 in non-gcc 64-bit + support RGB-formatted JPEG + read 16-bit PNGs (only as 8-bit) + 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED + 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling + info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) fix compiler warnings + partial animated GIF support + limited 16-bpc PSD support + #ifdef unused functions + bug with < 92 byte PIC,PNM,HDR,TGA + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) extra corruption checking (mmozeiko) + stbi_set_flip_vertically_on_load (nguillemot) + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) + progressive JPEG (stb) + PGM/PPM support (Ken Miller) + STBI_MALLOC,STBI_REALLOC,STBI_FREE + GIF bugfix -- seemingly never worked + STBI_NO_*, STBI_ONLY_* + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) + optimize PNG (ryg) + fix bug in interlaced PNG with user-specified channel count (stb) + 1.46 (2014-08-26) + fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG + 1.45 (2014-08-16) + fix MSVC-ARM internal compiler error by wrapping malloc + 1.44 (2014-08-07) + various warning fixes from Ronny Chevalier + 1.43 (2014-07-15) + fix MSVC-only compiler problem in code changed in 1.42 + 1.42 (2014-07-09) + don't define _CRT_SECURE_NO_WARNINGS (affects user code) + fixes to stbi__cleanup_jpeg path + added STBI_ASSERT to avoid requiring assert.h + 1.41 (2014-06-25) + fix search&replace from 1.36 that messed up comments/error messages + 1.40 (2014-06-22) + fix gcc struct-initialization warning + 1.39 (2014-06-15) + fix to TGA optimization when req_comp != number of components in TGA; + fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) + add support for BMP version 5 (more ignored fields) + 1.38 (2014-06-06) + suppress MSVC warnings on integer casts truncating values + fix accidental rename of 'skip' field of I/O + 1.37 (2014-06-04) + remove duplicate typedef + 1.36 (2014-06-03) + convert to header file single-file library + if de-iphone isn't set, load iphone images color-swapped instead of returning NULL + 1.35 (2014-05-27) + various warnings + fix broken STBI_SIMD path + fix bug where stbi_load_from_file no longer left file pointer in correct place + fix broken non-easy path for 32-bit BMP (possibly never used) + TGA optimization by Arseny Kapoulkine + 1.34 (unknown) + use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-stbi_uc to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) + 1.21 fix use of 'stbi_uc' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 (2008-08-02) + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - stbi__convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 (2006-11-19) + first released version +*/ diff --git a/L10.zip b/L10.zip new file mode 100644 index 0000000..0684d22 Binary files /dev/null and b/L10.zip differ diff --git a/L10/CMakeLists.txt b/L10/CMakeLists.txt new file mode 100644 index 0000000..383e48e --- /dev/null +++ b/L10/CMakeLists.txt @@ -0,0 +1,127 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +# Name of the project +PROJECT(L10) + +# FOR LAB MACHINES ONLY! +# DO NOT EDIT +SET(DEF_DIR_GLM "C:\\c++\\glm") +SET(DEF_DIR_GLFW "C:\\c++\\glfw-3.2.1") +SET(DEF_DIR_GLEW "C:\\c++\\glew-2.0.0") + +# Is this the solution? +# Override with `cmake -DSOL=ON ..` +OPTION(SOL "Solution" OFF) + +# Use glob to get the list of all source files. +# We don't really need to include header and resource files to build, but it's +# nice to have them also show up in IDEs. +IF(${SOL}) + FILE(GLOB_RECURSE SOURCES "src0/*.cpp") + FILE(GLOB_RECURSE HEADERS "src0/*.h") + FILE(GLOB_RECURSE GLSL "resources0/*.glsl") +ELSE() + FILE(GLOB_RECURSE SOURCES "src/*.cpp") + FILE(GLOB_RECURSE HEADERS "src/*.h") + FILE(GLOB_RECURSE GLSL "resources/*.glsl") +ENDIF() + +# Set the executable. +ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCES} ${HEADERS} ${GLSL}) + +# Get the GLM environment variable. Since GLM is a header-only library, we +# just need to add it to the include directory. +SET(GLM_INCLUDE_DIR "$ENV{GLM_INCLUDE_DIR}") +IF(NOT GLM_INCLUDE_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLM_INCLUDE_DIR to the root directory of your GLM installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLM in ${DEF_DIR_GLM}") + IF(IS_DIRECTORY ${DEF_DIR_GLM}) + MESSAGE(STATUS "Found!") + SET(GLM_INCLUDE_DIR ${DEF_DIR_GLM}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +INCLUDE_DIRECTORIES(${GLM_INCLUDE_DIR}) + +# Get the GLFW environment variable. There should be a CMakeLists.txt in the +# specified directory. +SET(GLFW_DIR "$ENV{GLFW_DIR}") +IF(NOT GLFW_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLFW_DIR to the root directory of your GLFW installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLFW in ${DEF_DIR_GLFW}") + IF(IS_DIRECTORY ${DEF_DIR_GLFW}) + MESSAGE(STATUS "Found!") + SET(GLFW_DIR ${DEF_DIR_GLFW}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +OPTION(GLFW_BUILD_EXAMPLES "GLFW_BUILD_EXAMPLES" OFF) +OPTION(GLFW_BUILD_TESTS "GLFW_BUILD_TESTS" OFF) +OPTION(GLFW_BUILD_DOCS "GLFW_BUILD_DOCS" OFF) +IF(CMAKE_BUILD_TYPE MATCHES Release) + ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/release) +ELSE() + ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/debug) +ENDIF() +INCLUDE_DIRECTORIES(${GLFW_DIR}/include) +TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} glfw ${GLFW_LIBRARIES}) + +# Get the GLEW environment variable. +SET(GLEW_DIR "$ENV{GLEW_DIR}") +IF(NOT GLEW_DIR) + # The environment variable was not set + SET(ERR_MSG "Please point the environment variable GLEW_DIR to the root directory of your GLEW installation.") + IF(WIN32) + # On Windows, try the default location + MESSAGE(STATUS "Looking for GLEW in ${DEF_DIR_GLEW}") + IF(IS_DIRECTORY ${DEF_DIR_GLEW}) + MESSAGE(STATUS "Found!") + SET(GLEW_DIR ${DEF_DIR_GLEW}) + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() + ELSE() + MESSAGE(FATAL_ERROR ${ERR_MSG}) + ENDIF() +ENDIF() +INCLUDE_DIRECTORIES(${GLEW_DIR}/include) +IF(WIN32) + # With prebuilt binaries + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/Release/Win32/glew32s.lib) +ELSE() + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/libGLEW.a) +ENDIF() + +# OS specific options and libraries +IF(WIN32) + # c++11 is enabled by default. + # -Wall produces way too many warnings. + # -pedantic is not supported. + # Disable warning 4996. + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996") + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} opengl32.lib) +ELSE() + # Enable all pedantic warnings. + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic") + IF(APPLE) + # Add required frameworks for GLFW. + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo") + ELSE() + #Link the Linux OpenGL library + TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "GL") + ENDIF() +ENDIF() diff --git a/L10/resources/earthClouds.jpg b/L10/resources/earthClouds.jpg new file mode 100644 index 0000000..4172dfc Binary files /dev/null and b/L10/resources/earthClouds.jpg differ diff --git a/L10/resources/earthKd.jpg b/L10/resources/earthKd.jpg new file mode 100644 index 0000000..b9fad89 Binary files /dev/null and b/L10/resources/earthKd.jpg differ diff --git a/L10/resources/earthKs.jpg b/L10/resources/earthKs.jpg new file mode 100644 index 0000000..3f3e48c Binary files /dev/null and b/L10/resources/earthKs.jpg differ diff --git a/L10/resources/frag.glsl b/L10/resources/frag.glsl new file mode 100644 index 0000000..ec07ff0 --- /dev/null +++ b/L10/resources/frag.glsl @@ -0,0 +1,14 @@ +#version 120 + +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform sampler2D texture2; +uniform vec3 lightPosCam; + +varying vec2 vTex0; + +void main() +{ + vec3 kd = texture2D(texture0, vTex0).rgb; + gl_FragColor = vec4(kd, 1.0); +} diff --git a/L10/resources/sphere.obj b/L10/resources/sphere.obj new file mode 100644 index 0000000..5dd7bde --- /dev/null +++ b/L10/resources/sphere.obj @@ -0,0 +1,1834 @@ +mtllib sphere.mtl +v -1 0 1.40385e-007 +v -0.983024 -0.156077 0.0964607 +v -0.983024 0.156077 -0.0964604 +v -0.978148 -0.185961 -0.0929805 +v -0.978148 0 0.207911 +v -0.978148 0 -0.207911 +v -0.978148 0.185961 0.0929807 +v -0.939205 -0.343331 0.00428931 +v -0.939205 -0.157379 0.305166 +v -0.939205 0.157379 -0.305166 +v -0.939205 0.343331 -0.00428905 +v -0.934172 -0.187593 -0.303531 +v -0.934172 0.187593 0.303531 +v -0.93267 -0.306855 0.189647 +v -0.93267 0.306855 -0.189647 +v -0.913545 -0.363797 -0.181898 +v -0.913545 0 0.406737 +v -0.913545 0 -0.406737 +v -0.913545 0.363797 0.181899 +v -0.866018 -0.490334 0.0979075 +v -0.866018 -0.306855 0.394783 +v -0.866018 0.306855 -0.394782 +v -0.866018 0.490334 -0.0979072 +v -0.851981 -0.516806 -0.0839041 +v -0.851981 -0.156077 0.499769 +v -0.851981 0.156077 -0.499768 +v -0.851981 0.516806 0.0839044 +v -0.850651 -0.447214 0.276393 +v -0.850651 0.447214 -0.276393 +v -0.845991 -0.363797 -0.389809 +v -0.845991 -0.185961 -0.499718 +v -0.845991 0.185961 0.499718 +v -0.845991 0.363797 0.38981 +v -0.809017 -0.525731 -0.262865 +v -0.809017 0 0.587785 +v -0.809017 0 -0.587785 +v -0.809017 0.525731 0.262866 +v -0.762354 -0.644208 0.0617517 +v -0.762354 -0.343331 0.548581 +v -0.762354 0.343331 -0.548581 +v -0.762354 0.644208 -0.0617515 +v -0.758172 -0.60373 0.246345 +v -0.758172 -0.490334 0.429824 +v -0.758172 0.490334 -0.429824 +v -0.758172 0.60373 -0.246345 +v -0.757312 -0.343331 -0.555521 +v -0.757311 0.343331 0.555521 +v -0.738585 -0.516806 -0.432902 +v -0.738585 -0.156077 -0.655845 +v -0.738585 0.156077 0.655845 +v -0.738585 0.516806 0.432902 +v -0.736686 -0.664689 -0.124433 +v -0.736686 0.185961 -0.650164 +v -0.736685 -0.185961 0.650164 +v -0.736685 0.664689 0.124433 +v -0.669131 -0.664689 -0.332344 +v -0.669131 0 0.743144 +v -0.669131 0 -0.743144 +v -0.669131 0.664689 0.332344 +v -0.653054 -0.644208 0.398142 +v -0.653054 0.644208 -0.398142 +v -0.643075 -0.490334 -0.588241 +v -0.643075 -0.306855 -0.701637 +v -0.643075 0.306855 0.701637 +v -0.643075 0.490334 0.588241 +v -0.639949 -0.739749 0.207932 +v -0.639949 -0.516806 0.568662 +v -0.639949 0.516806 -0.568662 +v -0.639949 0.739749 -0.207932 +v -0.632156 -0.774597 0.0194389 +v -0.632156 -0.363797 0.684127 +v -0.632156 0.363797 -0.684127 +v -0.632156 0.774597 -0.0194387 +v -0.580461 -0.644208 -0.498058 +v -0.580461 -0.157379 -0.798935 +v -0.58046 0.157379 0.798935 +v -0.58046 0.644208 0.498058 +v -0.57735 -0.794654 -0.187592 +v -0.57735 -0.187593 0.794655 +v -0.57735 0.187593 -0.794654 +v -0.57735 0.794654 0.187593 +v -0.525731 -0.447214 -0.723607 +v -0.525731 0.447214 0.723607 +v -0.522851 -0.774597 0.355846 +v -0.522851 -0.664689 0.533682 +v -0.522851 0.664689 -0.533681 +v -0.522851 0.774597 -0.355846 +v -0.5 -0.850651 0.16246 +v -0.5 -0.525731 0.688191 +v -0.5 0.525731 -0.688191 +v -0.5 0.850651 -0.16246 +v -0.499999 -0.774597 -0.387298 +v -0.499999 0 0.866026 +v -0.499999 0 -0.866026 +v -0.499999 0.774597 0.387299 +v -0.468576 -0.60373 -0.644939 +v -0.468576 -0.306855 -0.828418 +v -0.468576 0.306855 0.828418 +v -0.468576 0.60373 0.644939 +v -0.455297 -0.889527 -0.0380263 +v -0.455297 -0.363797 0.812623 +v -0.455297 0.363797 -0.812623 +v -0.455297 0.889527 0.0380264 +v -0.395511 -0.739749 -0.544373 +v -0.395511 -0.156077 -0.905103 +v -0.39551 0.156077 0.905103 +v -0.39551 0.739749 0.544373 +v -0.390694 -0.889527 -0.236853 +v -0.390694 -0.185961 0.901541 +v -0.390694 0.185961 -0.901541 +v -0.390694 0.889527 0.236853 +v -0.36073 -0.490334 -0.793377 +v -0.36073 0.490334 0.793377 +v -0.356822 -0.794654 0.491123 +v -0.356822 0.794655 -0.491123 +v -0.345991 -0.889527 0.298381 +v -0.345991 -0.664689 0.662178 +v -0.345991 0.664689 -0.662178 +v -0.345991 0.889527 -0.298381 +v -0.343074 -0.93267 0.111472 +v -0.343074 -0.516806 0.784354 +v -0.343074 0.516806 -0.784354 +v -0.343074 0.93267 -0.111472 +v -0.309017 -0.850651 -0.425325 +v -0.309017 0 0.951057 +v -0.309017 0 -0.951056 +v -0.309017 0.850651 0.425325 +v -0.29431 -0.644208 -0.705959 +v -0.29431 -0.343331 -0.891911 +v -0.294309 0.343331 0.891911 +v -0.294309 0.644208 0.705959 +v -0.286151 -0.953663 -0.092976 +v -0.286151 -0.343331 0.894562 +v -0.286151 0.343331 -0.894562 +v -0.286151 0.953663 0.0929761 +v -0.213835 -0.774597 -0.595209 +v -0.213835 -0.185961 -0.959006 +v -0.213834 0.185961 0.959006 +v -0.213834 0.774597 0.595209 +v -0.212032 -0.93267 -0.291836 +v -0.212032 0.156077 -0.964719 +v -0.212032 0.93267 0.291836 +v -0.212031 -0.156077 0.964719 +v -0.183479 -0.516806 -0.83621 +v -0.183479 0.516806 0.83621 +v -0.17686 -0.889527 0.421262 +v -0.17686 -0.774597 0.607223 +v -0.17686 0.774597 -0.607223 +v -0.17686 0.889527 -0.421262 +v -0.176851 -0.953663 0.243415 +v -0.176851 -0.644208 0.744124 +v -0.176851 0.644208 -0.744124 +v -0.176851 0.953663 -0.243415 +v -0.174499 -0.983024 0.0566981 +v -0.174499 -0.490334 0.853887 +v -0.174499 0.490334 -0.853887 +v -0.174499 0.983024 -0.0566981 +v -0.109305 -0.664689 -0.739082 +v -0.109305 -0.363797 -0.925043 +v -0.109305 0.363797 0.925043 +v -0.109305 0.664689 0.739082 +v -0.107846 -0.983024 -0.148438 +v -0.107846 -0.306855 0.945626 +v -0.107846 0.306855 -0.945626 +v -0.107846 0.983024 0.148438 +v -0.104529 -0.889527 -0.444764 +v -0.104529 0 0.994522 +v -0.104529 0 -0.994522 +v -0.104529 0.889527 0.444764 +v -7.96122e-008 -0.525731 -0.850651 +v -5.98336e-008 -0.187593 -0.982247 +v -5.68148e-008 -0.794655 -0.607062 +v -3.18213e-008 0.157379 -0.987538 +v -2.8159e-008 -0.953663 -0.300877 +v 0 -1 -0 +v 0 0.447214 -0.894427 +v 0 0.60373 -0.797189 +v 0 0.739749 -0.672883 +v 0 0.850651 -0.525731 +v 0 0.93267 -0.36073 +v 0 0.983024 -0.183479 +v 0 1 -0 +v 1.71718e-008 -0.983024 0.183479 +v 2.8159e-008 0.953663 0.300877 +v 3.37606e-008 -0.93267 0.36073 +v 4.92031e-008 -0.850651 0.525731 +v 5.68148e-008 0.794654 0.607062 +v 6.29749e-008 -0.739749 0.672883 +v 7.46087e-008 -0.60373 0.797189 +v 7.96122e-008 0.525731 0.850651 +v 8.37093e-008 -0.447214 0.894427 +v 9.19283e-008 0.187593 0.982247 +v 9.24235e-008 -0.157379 0.987538 +v 0.104529 -0.889527 -0.444764 +v 0.104529 0 0.994522 +v 0.104529 0 -0.994522 +v 0.104529 0.889527 0.444764 +v 0.107846 -0.983024 -0.148438 +v 0.107846 -0.306855 0.945626 +v 0.107846 0.306855 -0.945626 +v 0.107846 0.983024 0.148438 +v 0.109305 -0.664689 -0.739082 +v 0.109305 -0.363797 -0.925043 +v 0.109305 0.363797 0.925043 +v 0.109305 0.664689 0.739082 +v 0.174499 -0.983024 0.0566981 +v 0.174499 -0.490334 0.853887 +v 0.174499 0.490334 -0.853887 +v 0.174499 0.983024 -0.0566981 +v 0.176851 -0.953663 0.243415 +v 0.176851 -0.644208 0.744124 +v 0.176851 0.644208 -0.744124 +v 0.176851 0.953663 -0.243415 +v 0.17686 -0.889527 0.421262 +v 0.17686 -0.774597 0.607223 +v 0.17686 0.774597 -0.607223 +v 0.17686 0.889527 -0.421262 +v 0.183479 -0.516806 -0.83621 +v 0.183479 0.516806 0.83621 +v 0.212032 -0.93267 -0.291836 +v 0.212032 -0.156077 0.964719 +v 0.212032 0.156077 -0.964719 +v 0.212032 0.93267 0.291836 +v 0.213834 -0.774597 -0.595209 +v 0.213834 -0.185961 -0.959006 +v 0.213834 0.774597 0.595209 +v 0.213835 0.185961 0.959006 +v 0.286151 -0.953663 -0.0929761 +v 0.286151 -0.343331 0.894562 +v 0.286151 0.343331 -0.894562 +v 0.286151 0.953663 0.0929761 +v 0.294309 -0.644208 -0.705959 +v 0.294309 -0.343331 -0.891911 +v 0.29431 0.343331 0.891911 +v 0.29431 0.644208 0.705959 +v 0.309017 -0.850651 -0.425325 +v 0.309017 0 0.951056 +v 0.309017 0 -0.951057 +v 0.309017 0.850651 0.425325 +v 0.343074 -0.93267 0.111472 +v 0.343074 -0.516806 0.784354 +v 0.343074 0.516806 -0.784354 +v 0.343074 0.93267 -0.111472 +v 0.345991 -0.889527 0.298381 +v 0.345991 -0.664689 0.662178 +v 0.345991 0.664689 -0.662178 +v 0.345991 0.889527 -0.298381 +v 0.356822 -0.794654 0.491123 +v 0.356822 0.794654 -0.491123 +v 0.36073 -0.490334 -0.793377 +v 0.36073 0.490334 0.793377 +v 0.390694 -0.889527 -0.236853 +v 0.390694 -0.185961 0.901541 +v 0.390694 0.185961 -0.901541 +v 0.390694 0.889527 0.236853 +v 0.39551 -0.739749 -0.544373 +v 0.39551 -0.156077 -0.905103 +v 0.39551 0.739749 0.544373 +v 0.395511 0.156077 0.905103 +v 0.455297 -0.889527 -0.0380264 +v 0.455297 -0.363797 0.812623 +v 0.455297 0.363797 -0.812623 +v 0.455297 0.889527 0.0380263 +v 0.468576 -0.60373 -0.644939 +v 0.468576 -0.306855 -0.828418 +v 0.468576 0.306855 0.828418 +v 0.468576 0.60373 0.644939 +v 0.499999 -0.774597 -0.387298 +v 0.499999 0 0.866026 +v 0.499999 0 -0.866026 +v 0.499999 0.774597 0.387298 +v 0.5 -0.850651 0.16246 +v 0.5 -0.525731 0.688191 +v 0.5 0.525731 -0.688191 +v 0.5 0.850651 -0.16246 +v 0.522851 -0.774597 0.355846 +v 0.522851 -0.664689 0.533681 +v 0.522851 0.664689 -0.533682 +v 0.522851 0.774597 -0.355846 +v 0.525731 -0.447214 -0.723607 +v 0.525731 0.447214 0.723607 +v 0.57735 -0.794654 -0.187592 +v 0.57735 -0.187593 0.794654 +v 0.57735 0.187593 -0.794654 +v 0.57735 0.794654 0.187592 +v 0.58046 -0.644208 -0.498058 +v 0.58046 -0.157379 -0.798935 +v 0.58046 0.644208 0.498058 +v 0.580461 0.157379 0.798935 +v 0.632156 -0.774597 0.0194388 +v 0.632156 -0.363797 0.684127 +v 0.632156 0.363797 -0.684127 +v 0.632156 0.774597 -0.0194389 +v 0.639949 -0.739749 0.207932 +v 0.639949 -0.516806 0.568662 +v 0.639949 0.516806 -0.568662 +v 0.639949 0.739749 -0.207932 +v 0.643075 -0.490334 -0.588241 +v 0.643075 -0.306855 -0.701637 +v 0.643075 0.306855 0.701637 +v 0.643075 0.490334 0.588241 +v 0.653054 -0.644208 0.398142 +v 0.653054 0.644208 -0.398142 +v 0.669131 -0.664689 -0.332344 +v 0.669131 0 0.743144 +v 0.669131 0 -0.743144 +v 0.669131 0.664689 0.332344 +v 0.736685 -0.664689 -0.124433 +v 0.736686 -0.185961 0.650164 +v 0.736686 0.185961 -0.650164 +v 0.736686 0.664689 0.124433 +v 0.738585 -0.516806 -0.432902 +v 0.738585 -0.156077 -0.655845 +v 0.738585 0.156077 0.655845 +v 0.738585 0.516806 0.432902 +v 0.757311 -0.343331 -0.555521 +v 0.757312 0.343331 0.555521 +v 0.758172 -0.60373 0.246345 +v 0.758172 -0.490334 0.429824 +v 0.758172 0.490334 -0.429824 +v 0.758172 0.60373 -0.246345 +v 0.762354 -0.644208 0.0617515 +v 0.762354 -0.343331 0.548581 +v 0.762354 0.343331 -0.548581 +v 0.762354 0.644208 -0.0617516 +v 0.809017 -0.525731 -0.262866 +v 0.809017 0 0.587785 +v 0.809017 0 -0.587785 +v 0.809017 0.525731 0.262865 +v 0.845991 -0.363797 -0.389809 +v 0.845991 -0.185961 -0.499718 +v 0.845991 0.185961 0.499718 +v 0.845991 0.363797 0.389809 +v 0.850651 -0.447214 0.276393 +v 0.850651 0.447214 -0.276393 +v 0.851981 -0.516806 -0.0839043 +v 0.851981 -0.156077 0.499768 +v 0.851981 0.156077 -0.499769 +v 0.851981 0.516806 0.0839042 +v 0.866018 -0.490334 0.0979073 +v 0.866018 -0.306855 0.394782 +v 0.866018 0.306855 -0.394782 +v 0.866018 0.490334 -0.0979074 +v 0.913545 -0.363797 -0.181898 +v 0.913545 0 0.406737 +v 0.913545 0 -0.406737 +v 0.913545 0.363797 0.181898 +v 0.93267 -0.306855 0.189647 +v 0.93267 0.306855 -0.189647 +v 0.934172 -0.187593 -0.303531 +v 0.934172 0.187593 0.303531 +v 0.939205 -0.343331 0.00428914 +v 0.939205 -0.157379 0.305166 +v 0.939205 0.157379 -0.305166 +v 0.939205 0.343331 -0.00428922 +v 0.978148 -0.185961 -0.0929806 +v 0.978148 0 0.207911 +v 0.978148 0 -0.207911 +v 0.978148 0.185961 0.0929806 +v 0.983024 -0.156077 0.0964605 +v 0.983024 0.156077 -0.0964606 +v 1 0 -4.67949e-008 +vt -0.05 0.0972793 +vt -0.05 0.941264 +vt -0.0156234 0.327121 +vt -0.0150836 0.44046 +vt -0.0132618 0.151034 +vt -0.0128636 0.722813 +vt -0.00489247 0.782047 +vt -0.000726819 0.611555 +vt 2.2343e-008 0.5 +vt 0.000726849 0.388445 +vt 0.0048925 0.217953 +vt 0.0128637 0.277187 +vt 0.0132618 0.848966 +vt 0.0150836 0.55954 +vt 0.0155675 0.450115 +vt 0.0156234 0.672879 +vt 0.0179172 0.336875 +vt 0.0266314 0.731436 +vt 0.0312808 0.61852 +vt 0.0319269 0.400723 +vt 0.0333332 0.5 +vt 0.0499999 0.0587359 +vt 0.05 0.352416 +vt 0.05 0.449696 +vt 0.05 0.234944 +vt 0.05 0.293681 +vt 0.05 0.902721 +vt 0.05 0.560069 +vt 0.05 0.176208 +vt 0.0500001 0.676208 +vt 0.0500001 0.792348 +vt 0.0500002 1 +vt 0.0500002 0.117472 +vt 0.0666667 0.5 +vt 0.0680732 0.400723 +vt 0.0687194 0.61852 +vt 0.0733685 0.731436 +vt 0.0820829 0.336875 +vt 0.0843766 0.672879 +vt 0.0844326 0.450115 +vt 0.0849164 0.55954 +vt 0.0867383 0.848966 +vt 0.0871363 0.277187 +vt 0.0951076 0.217953 +vt 0.0992732 0.388445 +vt 0.1 0.5 +vt 0.100727 0.611555 +vt 0.104893 0.782047 +vt 0.112864 0.722813 +vt 0.113262 0.151034 +vt 0.115084 0.44046 +vt 0.115567 0.549885 +vt 0.115623 0.327121 +vt 0.117917 0.663125 +vt 0.126632 0.268564 +vt 0.131281 0.38148 +vt 0.131927 0.599277 +vt 0.133333 0.5 +vt 0.15 0.882528 +vt 0.15 0.70632 +vt 0.15 0.823792 +vt 0.15 0.207652 +vt 0.15 0 +vt 0.15 0.323792 +vt 0.15 0.765056 +vt 0.15 0.550304 +vt 0.15 0.647584 +vt 0.15 0.439931 +vt 0.15 0.0972794 +vt 0.15 0.941264 +vt 0.166667 0.5 +vt 0.168073 0.599277 +vt 0.168719 0.38148 +vt 0.173369 0.268564 +vt 0.182083 0.663125 +vt 0.184377 0.327121 +vt 0.184433 0.549885 +vt 0.184916 0.44046 +vt 0.186738 0.151034 +vt 0.187136 0.722813 +vt 0.195108 0.782047 +vt 0.199273 0.611555 +vt 0.2 0.5 +vt 0.200727 0.388445 +vt 0.204892 0.217953 +vt 0.212864 0.277187 +vt 0.213262 0.848966 +vt 0.215084 0.55954 +vt 0.215568 0.450115 +vt 0.215623 0.672879 +vt 0.217917 0.336875 +vt 0.226632 0.731436 +vt 0.231281 0.61852 +vt 0.231927 0.400723 +vt 0.233333 0.5 +vt 0.25 0.0587359 +vt 0.25 0.117472 +vt 0.25 0.176208 +vt 0.25 0.234944 +vt 0.25 0.293681 +vt 0.25 0.352416 +vt 0.25 0.449696 +vt 0.25 0.560069 +vt 0.25 0.676208 +vt 0.25 0.792348 +vt 0.25 0.902721 +vt 0.25 1 +vt 0.266667 0.5 +vt 0.268073 0.400723 +vt 0.268719 0.61852 +vt 0.273369 0.731436 +vt 0.282083 0.336875 +vt 0.284377 0.672879 +vt 0.284433 0.450115 +vt 0.284916 0.55954 +vt 0.286738 0.848966 +vt 0.287136 0.277187 +vt 0.295108 0.217953 +vt 0.299273 0.388445 +vt 0.3 0.5 +vt 0.300727 0.611555 +vt 0.304892 0.782047 +vt 0.312864 0.722813 +vt 0.313262 0.151034 +vt 0.315084 0.44046 +vt 0.315568 0.549885 +vt 0.315623 0.327121 +vt 0.317917 0.663125 +vt 0.326631 0.268564 +vt 0.331281 0.38148 +vt 0.331927 0.599277 +vt 0.333333 0.5 +vt 0.35 0.941264 +vt 0.35 0.0972794 +vt 0.35 0.647584 +vt 0.35 0.765056 +vt 0.35 0.323792 +vt 0.35 0 +vt 0.35 0.439931 +vt 0.35 0.207652 +vt 0.35 0.70632 +vt 0.35 0.823792 +vt 0.35 0.550304 +vt 0.35 0.882528 +vt 0.366667 0.5 +vt 0.368073 0.599277 +vt 0.368719 0.38148 +vt 0.373369 0.268564 +vt 0.382083 0.663125 +vt 0.384377 0.327121 +vt 0.384433 0.549885 +vt 0.384916 0.44046 +vt 0.386738 0.151034 +vt 0.387136 0.722813 +vt 0.395108 0.782047 +vt 0.399273 0.611555 +vt 0.4 0.5 +vt 0.400727 0.388445 +vt 0.404892 0.217953 +vt 0.412864 0.277187 +vt 0.413262 0.848966 +vt 0.415084 0.55954 +vt 0.415568 0.450115 +vt 0.415623 0.672879 +vt 0.417917 0.336875 +vt 0.426631 0.731436 +vt 0.431281 0.61852 +vt 0.431927 0.400723 +vt 0.433333 0.5 +vt 0.45 0.117472 +vt 0.45 1 +vt 0.45 0.176208 +vt 0.45 0.293681 +vt 0.45 0.560069 +vt 0.45 0.902721 +vt 0.45 0.234944 +vt 0.45 0.449696 +vt 0.45 0.0587359 +vt 0.45 0.352416 +vt 0.45 0.676208 +vt 0.45 0.792348 +vt 0.466667 0.5 +vt 0.468073 0.400723 +vt 0.468719 0.61852 +vt 0.473369 0.731436 +vt 0.482083 0.336875 +vt 0.484377 0.672879 +vt 0.484433 0.450115 +vt 0.484916 0.55954 +vt 0.486738 0.848966 +vt 0.487136 0.277187 +vt 0.495108 0.217953 +vt 0.499273 0.388445 +vt 0.5 0.5 +vt 0.500727 0.611555 +vt 0.504893 0.782047 +vt 0.512864 0.722813 +vt 0.513262 0.151034 +vt 0.515084 0.44046 +vt 0.515567 0.549885 +vt 0.515623 0.327121 +vt 0.517917 0.663125 +vt 0.526631 0.268564 +vt 0.531281 0.38148 +vt 0.531927 0.599277 +vt 0.533333 0.5 +vt 0.55 0.207652 +vt 0.55 0.550304 +vt 0.55 0.647584 +vt 0.55 0.941264 +vt 0.55 0.0972793 +vt 0.55 0.439931 +vt 0.55 0.706319 +vt 0.55 0.765056 +vt 0.55 0.323792 +vt 0.55 0.823792 +vt 0.55 0 +vt 0.55 0.882528 +vt 0.566667 0.5 +vt 0.568073 0.599277 +vt 0.568719 0.38148 +vt 0.573369 0.268564 +vt 0.582083 0.663125 +vt 0.584377 0.327121 +vt 0.584433 0.549885 +vt 0.584916 0.44046 +vt 0.586738 0.151034 +vt 0.587136 0.722813 +vt 0.595108 0.782047 +vt 0.599273 0.611555 +vt 0.6 0.5 +vt 0.600727 0.388445 +vt 0.604892 0.217953 +vt 0.612864 0.277187 +vt 0.613262 0.848966 +vt 0.615084 0.55954 +vt 0.615567 0.450115 +vt 0.615623 0.672879 +vt 0.617917 0.336875 +vt 0.626631 0.731436 +vt 0.631281 0.61852 +vt 0.631927 0.400723 +vt 0.633333 0.5 +vt 0.65 0.117472 +vt 0.65 0.176208 +vt 0.65 0.29368 +vt 0.65 0.792348 +vt 0.65 0.560069 +vt 0.65 0.676208 +vt 0.65 1 +vt 0.65 0.234944 +vt 0.65 0.352416 +vt 0.65 0.449696 +vt 0.65 0.902721 +vt 0.65 0.058736 +vt 0.666667 0.5 +vt 0.668073 0.400723 +vt 0.668719 0.61852 +vt 0.673369 0.731436 +vt 0.682083 0.336875 +vt 0.684377 0.672879 +vt 0.684433 0.450115 +vt 0.684916 0.55954 +vt 0.686738 0.848966 +vt 0.687136 0.277187 +vt 0.695108 0.217953 +vt 0.699273 0.388445 +vt 0.7 0.5 +vt 0.700727 0.611555 +vt 0.704892 0.782047 +vt 0.712864 0.722813 +vt 0.713262 0.151034 +vt 0.715084 0.44046 +vt 0.715567 0.549885 +vt 0.715623 0.327121 +vt 0.717917 0.663125 +vt 0.726632 0.268564 +vt 0.731281 0.38148 +vt 0.731927 0.599277 +vt 0.733333 0.5 +vt 0.75 0 +vt 0.75 0.0972794 +vt 0.75 0.207652 +vt 0.75 0.323792 +vt 0.75 0.439931 +vt 0.75 0.550304 +vt 0.75 0.647584 +vt 0.75 0.706319 +vt 0.75 0.765056 +vt 0.75 0.823792 +vt 0.75 0.882528 +vt 0.75 0.941264 +vt 0.766667 0.5 +vt 0.768073 0.599277 +vt 0.768719 0.38148 +vt 0.773368 0.268564 +vt 0.782083 0.663125 +vt 0.784377 0.327121 +vt 0.784433 0.549885 +vt 0.784917 0.44046 +vt 0.786738 0.151034 +vt 0.787136 0.722813 +vt 0.795108 0.782047 +vt 0.799273 0.611555 +vt 0.8 0.5 +vt 0.800727 0.388445 +vt 0.804893 0.217953 +vt 0.812864 0.277187 +vt 0.813262 0.848966 +vt 0.815084 0.55954 +vt 0.815568 0.450115 +vt 0.815623 0.672879 +vt 0.817917 0.336875 +vt 0.826631 0.731436 +vt 0.831281 0.61852 +vt 0.831927 0.400723 +vt 0.833333 0.5 +vt 0.85 0.058736 +vt 0.85 0.902721 +vt 0.85 0.352416 +vt 0.85 0.560069 +vt 0.85 0.676208 +vt 0.85 1 +vt 0.85 0.176208 +vt 0.85 0.29368 +vt 0.85 0.449696 +vt 0.85 0.792348 +vt 0.85 0.234944 +vt 0.85 0.117472 +vt 0.866667 0.5 +vt 0.868073 0.400723 +vt 0.868719 0.61852 +vt 0.873369 0.731436 +vt 0.882083 0.336875 +vt 0.884377 0.672879 +vt 0.884433 0.450115 +vt 0.884916 0.55954 +vt 0.886738 0.848966 +vt 0.887136 0.277187 +vt 0.895108 0.217953 +vt 0.899273 0.388445 +vt 0.9 0.5 +vt 0.900727 0.611555 +vt 0.904892 0.782047 +vt 0.912864 0.722813 +vt 0.913262 0.151034 +vt 0.915084 0.44046 +vt 0.915568 0.549885 +vt 0.915623 0.327121 +vt 0.917917 0.663125 +vt 0.926631 0.268564 +vt 0.931281 0.38148 +vt 0.931927 0.599277 +vt 0.933333 0.5 +vt 0.95 0 +vt 0.95 0.882528 +vt 0.95 0.823792 +vt 0.95 0.439931 +vt 0.95 0.706319 +vt 0.95 0.765056 +vt 0.95 0.0972793 +vt 0.95 0.550304 +vt 0.95 0.647584 +vt 0.95 0.941264 +vt 0.95 0.207652 +vt 0.95 0.323792 +vt 0.966667 0.5 +vt 0.968073 0.599277 +vt 0.968719 0.38148 +vt 0.973369 0.268564 +vt 0.982083 0.663125 +vt 0.984377 0.327121 +vt 0.984433 0.549885 +vt 0.984916 0.44046 +vt 0.986738 0.151034 +vt 0.987136 0.722813 +vt 0.995108 0.782047 +vt 0.999273 0.611555 +vt 1 0.5 +vt 1.00073 0.388445 +vt 1.00489 0.217953 +vt 1.01286 0.277187 +vt 1.01326 0.848966 +vt 1.01508 0.55954 +vt 1.01562 0.672879 +vt 1.05 0.0587359 +vt 1.05 0.902721 +vn -1 1.00021e-008 4.62596e-008 +vn -0.981591 -0.162468 0.100411 +vn -0.981591 0.162468 -0.100411 +vn -0.978376 -0.180943 -0.100195 +vn -0.978376 0.180943 0.100195 +vn -0.978376 -0.00869708 -0.206649 +vn -0.978376 0.0086971 0.20665 +vn -0.939218 -0.157292 0.30517 +vn -0.939218 -0.343297 0.00421013 +vn -0.939218 0.343297 -0.0042102 +vn -0.939218 0.157293 -0.305171 +vn -0.934172 0.187592 0.303531 +vn -0.934172 -0.187593 -0.303531 +vn -0.929022 -0.314761 0.194533 +vn -0.929022 0.314761 -0.194533 +vn -0.912988 0.360941 0.190194 +vn -0.912988 0.00869702 0.407893 +vn -0.912988 -0.360942 -0.190194 +vn -0.912988 -0.00869627 -0.407893 +vn -0.865939 0.31476 -0.388685 +vn -0.865939 -0.31476 0.388684 +vn -0.865939 -0.488415 0.107705 +vn -0.865939 0.488415 -0.107705 +vn -0.853145 0.162466 -0.49573 +vn -0.853145 -0.516052 -0.0763834 +vn -0.853144 -0.162466 0.495732 +vn -0.853144 0.516053 0.0763836 +vn -0.850652 0.447212 -0.276392 +vn -0.850652 -0.447213 0.276392 +vn -0.850417 -0.180942 -0.494015 +vn -0.850417 -0.360941 -0.382769 +vn -0.850416 0.180942 0.494016 +vn -0.850416 0.360941 0.382772 +vn -0.809018 -0.52573 -0.262865 +vn -0.809017 2.413e-007 -0.587785 +vn -0.809017 0.525732 0.262865 +vn -0.809017 -4.85101e-007 0.587786 +vn -0.763866 0.488416 -0.421851 +vn -0.763866 -0.488417 0.421851 +vn -0.763865 0.595742 -0.248195 +vn -0.763865 -0.595742 0.248195 +vn -0.762317 0.343296 -0.548653 +vn -0.762317 -0.644257 0.0616893 +vn -0.762317 0.644257 -0.0616879 +vn -0.762316 -0.343296 0.548655 +vn -0.757369 -0.343296 -0.555464 +vn -0.757368 0.343296 0.555465 +vn -0.735105 -0.516054 -0.439669 +vn -0.735104 -0.162466 -0.658199 +vn -0.735104 0.162467 0.6582 +vn -0.735104 0.516054 0.439671 +vn -0.73263 -0.667785 -0.131592 +vn -0.73263 0.180943 -0.656135 +vn -0.73263 -0.180942 0.656135 +vn -0.73263 0.667785 0.131592 +vn -0.670058 -0.00869553 0.742258 +vn -0.670058 0.00869665 -0.742258 +vn -0.670057 0.667785 0.324169 +vn -0.670057 -0.667786 -0.324169 +vn -0.652987 -0.644257 0.398171 +vn -0.652987 0.644257 -0.398172 +vn -0.645311 -0.734582 0.209674 +vn -0.645311 0.734582 -0.209674 +vn -0.645311 -0.516052 0.563262 +vn -0.64531 0.516053 -0.563262 +vn -0.637252 0.488417 0.59612 +vn -0.637252 0.31476 0.703446 +vn -0.637251 -0.488416 -0.596121 +vn -0.637251 -0.31476 -0.703447 +vn -0.62683 -0.360942 0.690511 +vn -0.62683 0.77903 -0.0140296 +vn -0.626829 -0.779031 0.0140304 +vn -0.626829 0.360942 -0.690512 +vn -0.580469 -0.157292 -0.798946 +vn -0.580468 0.157292 0.798947 +vn -0.580468 -0.644257 -0.497986 +vn -0.580467 0.644257 0.497987 +vn -0.57735 -0.187593 0.794654 +vn -0.57735 0.794655 0.187592 +vn -0.57735 0.187593 -0.794655 +vn -0.577349 -0.794656 -0.187593 +vn -0.525731 -0.447214 -0.723607 +vn -0.525731 0.447214 0.723607 +vn -0.515363 0.667784 -0.537089 +vn -0.515363 0.77903 -0.35709 +vn -0.515363 -0.667785 0.537089 +vn -0.515362 -0.77903 0.35709 +vn -0.500001 0.52573 -0.688191 +vn -0.5 -0.525729 0.688192 +vn -0.5 0.850651 -0.16246 +vn -0.5 -0.850651 0.16246 +vn -0.49887 -0.00869475 0.866633 +vn -0.49887 0.00869757 -0.866633 +vn -0.498869 -0.77903 -0.379791 +vn -0.498869 0.77903 0.379793 +vn -0.472095 -0.31476 -0.823439 +vn -0.472095 -0.595742 -0.649783 +vn -0.472095 0.314759 0.82344 +vn -0.472095 0.595743 0.649782 +vn -0.463014 0.360941 -0.80953 +vn -0.463014 -0.885484 -0.0391978 +vn -0.463014 0.885484 0.0391977 +vn -0.463013 -0.360942 0.80953 +vn -0.398825 -0.734582 -0.548934 +vn -0.398824 0.162469 0.90252 +vn -0.398824 0.734581 0.548935 +vn -0.398824 -0.162467 -0.902521 +vn -0.397626 -0.885484 -0.240441 +vn -0.397626 0.180943 -0.89953 +vn -0.397625 0.885484 0.240441 +vn -0.397625 -0.180944 0.89953 +vn -0.370023 -0.488416 -0.790274 +vn -0.370022 0.488416 0.790274 +vn -0.356821 0.794655 -0.491122 +vn -0.356821 -0.794656 0.491122 +vn -0.351546 0.667784 -0.656109 +vn -0.351546 -0.885484 0.303865 +vn -0.351546 0.885484 -0.303863 +vn -0.351546 -0.667785 0.656109 +vn -0.336281 -0.935402 0.109265 +vn -0.336281 -0.516052 0.787785 +vn -0.336281 0.516052 -0.787785 +vn -0.336281 0.935402 -0.109265 +vn -0.309017 -0.850651 -0.425325 +vn -0.309017 6.87643e-008 -0.951056 +vn -0.309017 4.8135e-007 0.951057 +vn -0.309017 0.850651 0.425326 +vn -0.29424 -0.644257 -0.705943 +vn -0.294239 0.644258 0.705943 +vn -0.294238 -0.343295 -0.891948 +vn -0.294238 0.343295 0.891949 +vn -0.286232 -0.953636 -0.0930024 +vn -0.286232 0.953636 0.0930024 +vn -0.286231 0.343296 -0.89455 +vn -0.286231 -0.343296 0.89455 +vn -0.207833 -0.935402 -0.286058 +vn -0.207833 0.935402 0.286058 +vn -0.207833 0.162468 -0.964577 +vn -0.207832 -0.162469 0.964577 +vn -0.207046 -0.77903 -0.591814 +vn -0.207046 -0.180943 -0.961453 +vn -0.207045 0.77903 0.591814 +vn -0.207045 0.180944 0.961453 +vn -0.190993 0.516052 0.834992 +vn -0.190992 -0.516052 -0.834992 +vn -0.180359 -0.885484 0.42824 +vn -0.180358 -0.779031 0.600485 +vn -0.180358 0.885484 -0.428239 +vn -0.180357 0.77903 -0.600486 +vn -0.176901 0.953636 -0.243484 +vn -0.176901 -0.953636 0.243484 +vn -0.1769 0.644256 -0.74407 +vn -0.1769 -0.644256 0.74407 +vn -0.165158 -0.984806 0.0536629 +vn -0.165158 0.984806 -0.0536629 +vn -0.165157 0.488415 -0.856839 +vn -0.165157 -0.488415 0.856839 +vn -0.105801 -0.00869593 -0.994349 +vn -0.105801 -0.885484 -0.452464 +vn -0.1058 0.885484 0.452465 +vn -0.1058 0.0086958 0.994349 +vn -0.102073 -0.984806 -0.140492 +vn -0.102073 0.984806 0.140492 +vn -0.102072 -0.31476 0.943667 +vn -0.102071 0.31476 -0.943667 +vn -0.101246 0.360941 0.927077 +vn -0.101246 -0.667784 -0.737437 +vn -0.101245 0.667785 0.737436 +vn -0.101245 -0.360941 -0.927077 +vn -1.38907e-007 0.187592 0.982247 +vn -1.37495e-007 -0.157294 0.987552 +vn -2.50052e-008 -0.52573 -0.850651 +vn -1.24996e-008 -0.953636 -0.300962 +vn -8.74969e-009 0.157294 -0.987552 +vn -1.25026e-009 0.850651 -0.52573 +vn -1.24987e-009 0.984806 -0.173657 +vn -1.24987e-009 0.595741 -0.803177 +vn -1.24987e-009 0.734582 -0.67852 +vn -1.24986e-009 0.935402 -0.353587 +vn 0 -1 1.49983e-008 +vn 0 0.447212 -0.894428 +vn 0 1 -1.34985e-008 +vn 3.74961e-009 -0.984806 0.173657 +vn 1.24987e-008 -0.935402 0.353587 +vn 1.24996e-008 0.953636 0.300962 +vn 2.00227e-008 0.794656 0.60706 +vn 2.12544e-008 -0.850651 0.52573 +vn 2.7497e-008 -0.734582 0.67852 +vn 2.8756e-008 0.52573 0.850651 +vn 3.37465e-008 -0.595741 0.803177 +vn 3.89956e-008 -0.447212 0.894428 +vn 1.45164e-007 -0.187592 -0.982247 +vn 1.45164e-007 -0.794656 -0.60706 +vn 0.101245 0.667785 0.737436 +vn 0.101245 0.360941 0.927077 +vn 0.101246 -0.360941 -0.927077 +vn 0.101246 -0.667784 -0.737437 +vn 0.102071 0.31476 -0.943667 +vn 0.102072 -0.31476 0.943667 +vn 0.102073 -0.984806 -0.140492 +vn 0.102073 0.984806 0.140492 +vn 0.1058 -0.00869608 -0.994349 +vn 0.1058 0.885484 0.452465 +vn 0.105801 -0.885484 -0.452464 +vn 0.105801 0.00869592 0.994349 +vn 0.165157 0.488415 -0.856839 +vn 0.165157 -0.488415 0.856839 +vn 0.165158 0.984806 -0.0536629 +vn 0.165158 -0.984806 0.0536629 +vn 0.1769 -0.644256 0.74407 +vn 0.1769 0.644256 -0.74407 +vn 0.176901 -0.953636 0.243484 +vn 0.176901 0.953636 -0.243484 +vn 0.180358 -0.779031 0.600485 +vn 0.180358 0.779031 -0.600485 +vn 0.180359 0.885484 -0.42824 +vn 0.180359 -0.885484 0.42824 +vn 0.190992 0.516052 0.834992 +vn 0.190993 -0.516052 -0.834992 +vn 0.207045 -0.180944 -0.961453 +vn 0.207045 0.77903 0.591814 +vn 0.207046 0.180943 0.961453 +vn 0.207047 -0.77903 -0.591814 +vn 0.207832 0.162469 -0.964577 +vn 0.207833 -0.162468 0.964577 +vn 0.207833 -0.935402 -0.286058 +vn 0.207833 0.935402 0.286058 +vn 0.286231 -0.343296 0.89455 +vn 0.286231 0.343296 -0.89455 +vn 0.286232 -0.953636 -0.0930024 +vn 0.286232 0.953636 0.0930024 +vn 0.294238 -0.343295 -0.891949 +vn 0.294238 0.343295 0.891948 +vn 0.294239 -0.644258 -0.705943 +vn 0.29424 0.644258 0.705943 +vn 0.309017 -8.52678e-007 -0.951057 +vn 0.309017 -6.87643e-008 0.951056 +vn 0.309017 -0.850651 -0.425326 +vn 0.309017 0.850651 0.425326 +vn 0.336281 -0.935402 0.109265 +vn 0.336281 -0.516052 0.787785 +vn 0.336281 0.516052 -0.787785 +vn 0.336281 0.935402 -0.109265 +vn 0.351546 0.667785 -0.656109 +vn 0.351546 -0.885484 0.303865 +vn 0.351546 0.885484 -0.303865 +vn 0.351546 -0.667785 0.656108 +vn 0.356821 0.794656 -0.491122 +vn 0.356822 -0.794655 0.491122 +vn 0.370022 -0.488416 -0.790274 +vn 0.370023 0.488416 0.790274 +vn 0.397626 -0.180943 0.89953 +vn 0.397626 -0.885484 -0.240442 +vn 0.397626 0.885484 0.240442 +vn 0.397626 0.180944 -0.899529 +vn 0.398824 0.162467 0.902521 +vn 0.398824 -0.162469 -0.90252 +vn 0.398824 -0.734582 -0.548934 +vn 0.398825 0.734582 0.548934 +vn 0.463014 -0.885484 -0.0391978 +vn 0.463014 0.885484 0.0391978 +vn 0.463014 -0.360941 0.80953 +vn 0.463014 0.360941 -0.80953 +vn 0.472095 -0.595743 -0.649782 +vn 0.472095 -0.314759 -0.82344 +vn 0.472095 0.595743 0.649782 +vn 0.472095 0.31476 0.823439 +vn 0.498869 -0.77903 -0.379792 +vn 0.498869 0.77903 0.379792 +vn 0.49887 -0.00869757 0.866633 +vn 0.498871 0.00869589 -0.866633 +vn 0.5 -0.850651 0.16246 +vn 0.5 0.850651 -0.16246 +vn 0.5 0.525729 -0.688192 +vn 0.500001 -0.52573 0.688191 +vn 0.515362 -0.77903 0.357091 +vn 0.515362 0.77903 -0.35709 +vn 0.515363 -0.667785 0.537089 +vn 0.515363 0.667785 -0.537089 +vn 0.525731 -0.447214 -0.723607 +vn 0.525731 0.447214 0.723607 +vn 0.577349 0.794656 0.187593 +vn 0.57735 -0.794655 -0.187592 +vn 0.57735 -0.187593 0.794655 +vn 0.57735 0.187593 -0.794655 +vn 0.580467 -0.644258 -0.497986 +vn 0.580467 0.644258 0.497986 +vn 0.580468 -0.157292 -0.798947 +vn 0.580469 0.157292 0.798946 +vn 0.626829 -0.360942 0.690512 +vn 0.626829 0.360942 -0.690512 +vn 0.626829 0.779031 -0.0140304 +vn 0.62683 -0.77903 0.0140295 +vn 0.637251 0.488417 0.596121 +vn 0.637251 0.31476 0.703447 +vn 0.637252 -0.488417 -0.59612 +vn 0.637252 -0.31476 -0.703446 +vn 0.64531 -0.516053 0.563262 +vn 0.645311 0.516052 -0.563262 +vn 0.645311 -0.734582 0.209674 +vn 0.645311 0.734582 -0.209674 +vn 0.652987 -0.644257 0.398172 +vn 0.652987 0.644257 -0.398171 +vn 0.670057 -0.667786 -0.324169 +vn 0.670057 0.667785 0.32417 +vn 0.670057 0.00869565 -0.742258 +vn 0.670058 -0.00869665 0.742258 +vn 0.732629 0.180942 -0.656136 +vn 0.732629 -0.667786 -0.131592 +vn 0.73263 0.667785 0.131592 +vn 0.73263 -0.180943 0.656135 +vn 0.735104 -0.162467 -0.6582 +vn 0.735104 -0.516053 -0.439671 +vn 0.735104 0.516054 0.43967 +vn 0.735104 0.162466 0.658199 +vn 0.757369 -0.343296 -0.555465 +vn 0.757369 0.343296 0.555464 +vn 0.762317 -0.644257 0.0616879 +vn 0.762317 0.343297 -0.548653 +vn 0.762317 0.644257 -0.0616893 +vn 0.762317 -0.343296 0.548653 +vn 0.763865 -0.595742 0.248195 +vn 0.763865 0.595742 -0.248195 +vn 0.763866 -0.488416 0.421851 +vn 0.763866 0.488416 -0.421851 +vn 0.809017 -5.86372e-007 -0.587785 +vn 0.809017 -0.525731 -0.262865 +vn 0.809017 -2.413e-007 0.587785 +vn 0.809018 0.52573 0.262865 +vn 0.850416 -0.180943 -0.494016 +vn 0.850416 -0.360941 -0.382771 +vn 0.850417 0.180942 0.494015 +vn 0.850417 0.360942 0.382769 +vn 0.850652 -0.447212 0.276392 +vn 0.850652 0.447212 -0.276393 +vn 0.853144 -0.516053 -0.0763836 +vn 0.853145 0.516052 0.0763834 +vn 0.853145 0.162466 -0.495731 +vn 0.853145 -0.162466 0.49573 +vn 0.865939 -0.488415 0.107705 +vn 0.865939 0.488415 -0.107705 +vn 0.865939 -0.31476 0.388685 +vn 0.865939 0.31476 -0.388684 +vn 0.912988 0.360942 0.190194 +vn 0.912988 0.00869627 0.407893 +vn 0.912988 -0.360941 -0.190194 +vn 0.912988 -0.00869702 -0.407893 +vn 0.929022 -0.314761 0.194533 +vn 0.929022 0.314761 -0.194533 +vn 0.934172 -0.187593 -0.303531 +vn 0.934172 0.187593 0.303531 +vn 0.939218 -0.157293 0.305171 +vn 0.939218 -0.343297 0.00421008 +vn 0.939218 0.343297 -0.0042101 +vn 0.939218 0.157293 -0.305171 +vn 0.978376 -0.0086971 -0.20665 +vn 0.978376 0.00869708 0.20665 +vn 0.978376 -0.180943 -0.100195 +vn 0.978376 0.180943 0.100195 +vn 0.981591 -0.162468 0.100411 +vn 0.981591 0.162468 -0.100411 +vn 1 -8.75182e-009 -1.62534e-008 +usemtl Default_Smoothing +s 1 +f 181/292/176 182/250/182 209/210/208 +f 213/254/213 209/210/208 243/218/243 +f 181/292/176 213/254/213 180/291/179 +f 181/292/176 209/210/208 213/254/213 +f 247/235/246 243/218/243 275/216/273 +f 217/264/216 213/254/213 247/235/246 +f 180/291/179 217/264/216 179/290/175 +f 213/254/213 243/218/243 247/235/246 +f 180/291/179 213/254/213 217/264/216 +f 279/229/277 275/216/273 297/214/301 +f 249/247/248 247/235/246 279/229/277 +f 217/264/216 249/247/248 216/270/215 +f 179/290/175 216/270/215 178/289/178 +f 247/235/246 275/216/273 279/229/277 +f 217/264/216 247/235/246 249/247/248 +f 179/290/175 217/264/216 216/270/215 +f 303/228/303 297/214/301 321/213/323 +f 278/240/279 279/229/277 303/228/303 +f 246/259/244 249/247/248 278/240/279 +f 216/270/215 246/259/244 212/271/211 +f 178/289/178 212/271/211 177/288/177 +f 279/229/277 297/214/301 303/228/303 +f 249/247/248 279/229/277 278/240/279 +f 216/270/215 249/247/248 246/259/244 +f 178/289/178 216/270/215 212/271/211 +f 320/223/325 321/213/323 335/209/335 +f 296/238/299 303/228/303 320/223/325 +f 274/249/274 278/240/279 296/238/299 +f 246/259/244 274/249/274 242/261/242 +f 212/271/211 242/261/242 208/276/206 +f 177/288/177 208/276/206 176/287/181 +f 303/228/303 321/213/323 320/223/325 +f 278/240/279 303/228/303 296/238/299 +f 246/259/244 278/240/279 274/249/274 +f 212/271/211 246/259/244 242/261/242 +f 177/288/177 212/271/211 208/276/206 +f 209/210/208 182/171/182 201/133/201 +f 231/175/231 201/133/201 223/144/227 +f 209/210/208 231/175/231 243/218/243 +f 209/210/208 201/133/201 231/175/231 +f 255/161/254 223/144/227 239/142/239 +f 263/190/261 231/175/231 255/161/254 +f 243/218/243 263/190/261 275/216/273 +f 231/175/231 223/144/227 255/161/254 +f 243/218/243 231/175/231 263/190/261 +f 271/155/269 239/142/239 258/136/259 +f 285/181/282 255/161/254 271/155/269 +f 263/190/261 285/181/282 293/196/292 +f 275/216/273 293/196/292 297/214/301 +f 255/161/254 239/142/239 271/155/269 +f 263/190/261 255/161/254 285/181/282 +f 275/216/273 263/190/261 293/196/292 +f 288/154/287 258/136/259 267/141/266 +f 307/166/305 271/155/269 288/154/287 +f 311/185/310 285/181/282 307/166/305 +f 293/196/292 311/185/310 325/197/320 +f 297/214/301 325/197/320 321/213/323 +f 271/155/269 258/136/259 288/154/287 +f 285/181/282 271/155/269 307/166/305 +f 293/196/292 285/181/282 311/185/310 +f 297/214/301 293/196/292 325/197/320 +f 301/149/294 267/141/266 281/135/281 +f 315/164/314 288/154/287 301/149/294 +f 329/180/329 307/166/305 315/164/314 +f 311/185/310 329/180/329 339/187/337 +f 325/197/320 339/187/337 343/202/341 +f 321/213/323 343/202/341 335/209/335 +f 288/154/287 267/141/266 301/149/294 +f 307/166/305 288/154/287 315/164/314 +f 311/185/310 307/166/305 329/180/329 +f 325/197/320 311/185/310 339/187/337 +f 321/213/323 325/197/320 343/202/341 +f 201/133/201 182/107/182 165/70/163 +f 184/106/185 165/70/163 142/59/137 +f 201/133/201 184/106/185 223/144/227 +f 201/133/201 165/70/163 184/106/185 +f 169/87/160 142/59/137 127/61/127 +f 197/116/203 184/106/185 169/87/160 +f 223/144/227 197/116/203 239/142/239 +f 184/106/185 142/59/137 169/87/160 +f 223/144/227 184/106/185 197/116/203 +f 139/81/142 127/61/127 107/65/106 +f 187/105/186 169/87/160 139/81/142 +f 197/116/203 187/105/186 226/122/221 +f 239/142/239 226/122/221 258/136/259 +f 169/87/160 127/61/127 139/81/142 +f 197/116/203 169/87/160 187/105/186 +f 239/142/239 197/116/203 226/122/221 +f 131/80/129 107/65/106 99/60/99 +f 161/92/168 139/81/142 131/80/129 +f 205/111/194 187/105/186 161/92/168 +f 226/122/221 205/111/194 235/123/235 +f 258/136/259 235/123/235 267/141/266 +f 139/81/142 107/65/106 131/80/129 +f 187/105/186 139/81/142 161/92/168 +f 226/122/221 187/105/186 205/111/194 +f 258/136/259 226/122/221 235/123/235 +f 113/75/113 99/60/99 83/67/83 +f 145/90/144 131/80/129 113/75/113 +f 190/104/189 161/92/168 145/90/144 +f 205/111/194 190/104/189 219/113/218 +f 235/123/235 219/113/218 251/128/251 +f 267/141/266 251/128/251 281/135/281 +f 131/80/129 99/60/99 113/75/113 +f 161/92/168 131/80/129 145/90/144 +f 205/111/194 161/92/168 190/104/189 +f 235/123/235 205/111/194 219/113/218 +f 267/141/266 235/123/235 251/128/251 +f 182/32/182 157/2/155 165/70/163 +f 135/387/133 157/364/155 123/356/123 +f 165/70/163 135/27/133 142/59/137 +f 165/70/163 157/2/155 135/27/133 +f 103/383/102 123/356/123 91/357/90 +f 135/27/133 103/13/102 111/42/110 +f 142/59/137 111/42/110 127/61/127 +f 135/387/133 123/356/123 103/383/102 +f 142/59/137 135/27/133 111/42/110 +f 73/377/71 91/357/90 69/360/63 +f 81/31/79 103/13/102 73/7/71 +f 111/42/110 81/31/79 95/48/95 +f 127/61/127 95/48/95 107/65/106 +f 103/383/102 91/357/90 73/377/71 +f 111/42/110 103/13/102 81/31/79 +f 127/61/127 111/42/110 95/48/95 +f 41/376/44 69/360/63 45/359/40 +f 55/18/55 73/7/71 41/6/44 +f 81/31/79 55/18/55 59/37/58 +f 95/48/95 59/37/58 77/49/77 +f 107/65/106 77/49/77 99/60/99 +f 73/377/71 69/360/63 41/376/44 +f 81/31/79 73/7/71 55/18/55 +f 95/48/95 81/31/79 59/37/58 +f 107/65/106 95/48/95 77/49/77 +f 23/371/23 45/359/40 29/363/28 +f 27/385/27 41/376/44 23/371/23 +f 37/30/36 55/18/55 27/16/27 +f 59/37/58 37/30/36 51/39/51 +f 77/49/77 51/39/51 65/54/66 +f 99/60/99 65/54/66 83/67/83 +f 41/376/44 45/359/40 23/371/23 +f 55/18/55 41/6/44 27/16/27 +f 59/37/58 55/18/55 37/30/36 +f 77/49/77 59/37/58 51/39/51 +f 99/60/99 77/49/77 65/54/66 +f 182/323/182 181/292/176 157/364/155 +f 153/319/150 181/292/176 180/291/179 +f 157/364/155 153/319/150 123/356/123 +f 157/364/155 181/292/176 153/319/150 +f 149/309/148 180/291/179 179/290/175 +f 153/319/150 149/309/148 119/338/118 +f 123/356/123 119/338/118 91/357/90 +f 153/319/150 180/291/179 149/309/148 +f 123/356/123 153/319/150 119/338/118 +f 148/303/149 179/290/175 178/289/178 +f 115/327/114 149/309/148 148/303/149 +f 119/338/118 115/327/114 87/344/85 +f 91/357/90 87/344/85 69/360/63 +f 149/309/148 179/290/175 148/303/149 +f 119/338/118 149/309/148 115/327/114 +f 91/357/90 119/338/118 87/344/85 +f 152/302/152 178/289/178 177/288/177 +f 118/314/116 148/303/149 152/302/152 +f 115/327/114 118/314/116 86/333/84 +f 87/344/85 86/333/84 61/345/61 +f 69/360/63 61/345/61 45/359/40 +f 148/303/149 178/289/178 152/302/152 +f 115/327/114 148/303/149 118/314/116 +f 87/344/85 115/327/114 86/333/84 +f 69/360/63 87/344/85 61/345/61 +f 156/297/156 177/288/177 176/287/181 +f 122/312/122 152/302/152 156/297/156 +f 90/322/88 118/314/116 122/312/122 +f 86/333/84 90/322/88 68/335/65 +f 61/345/61 68/335/65 44/350/38 +f 45/359/40 44/350/38 29/363/28 +f 152/302/152 177/288/177 156/297/156 +f 118/314/116 152/302/152 122/312/122 +f 86/333/84 118/314/116 90/322/88 +f 61/345/61 86/333/84 68/335/65 +f 45/359/40 61/345/61 44/350/38 +f 198/255/200 206/178/209 175/217/180 +f 220/244/226 228/211/230 198/255/200 +f 228/211/230 240/170/240 206/178/209 +f 198/255/200 228/211/230 206/178/209 +f 236/245/238 252/227/253 220/244/226 +f 252/227/253 260/198/260 228/211/230 +f 260/198/260 272/172/272 240/170/240 +f 220/244/226 252/227/253 228/211/230 +f 260/198/260 240/170/240 228/211/230 +f 256/251/258 268/233/268 236/245/238 +f 268/233/268 282/207/283 252/227/253 +f 282/207/283 290/192/293 260/198/260 +f 290/192/293 294/176/300 272/172/272 +f 236/245/238 268/233/268 252/227/253 +f 252/227/253 282/207/283 260/198/260 +f 290/192/293 272/172/272 260/198/260 +f 264/246/264 286/234/286 256/251/258 +f 286/234/286 304/222/304 268/233/268 +f 304/222/304 308/203/309 282/207/283 +f 308/203/309 322/191/318 290/192/293 +f 322/191/318 318/173/322 294/176/300 +f 256/251/258 286/234/286 268/233/268 +f 268/233/268 304/222/304 282/207/283 +f 308/203/309 290/192/293 282/207/283 +f 322/191/318 294/176/300 290/192/293 +f 280/252/280 298/239/296 264/246/264 +f 298/239/296 312/224/313 286/234/286 +f 312/224/313 326/215/327 304/222/304 +f 326/215/327 336/201/336 308/203/309 +f 336/201/336 340/186/340 322/191/318 +f 340/186/340 334/179/334 318/173/322 +f 264/246/264 298/239/296 286/234/286 +f 286/234/286 312/224/313 304/222/304 +f 304/222/304 326/215/327 308/203/309 +f 336/201/336 322/191/318 308/203/309 +f 340/186/340 318/173/322 322/191/318 +f 206/178/209 183/96/183 175/138/180 +f 240/170/240 210/134/212 206/178/209 +f 210/134/212 185/97/184 183/96/183 +f 206/178/209 210/134/212 183/96/183 +f 272/172/272 244/153/245 240/170/240 +f 244/153/245 214/124/217 210/134/212 +f 214/124/217 186/98/187 185/97/184 +f 240/170/240 244/153/245 210/134/212 +f 214/124/217 185/97/184 210/134/212 +f 294/176/300 276/159/276 272/172/272 +f 276/159/276 248/140/249 244/153/245 +f 248/140/249 215/118/214 214/124/217 +f 215/118/214 188/99/188 186/98/187 +f 272/172/272 276/159/276 244/153/245 +f 244/153/245 248/140/249 214/124/217 +f 215/118/214 186/98/187 214/124/217 +f 318/173/322 302/160/302 294/176/300 +f 302/160/302 277/148/278 276/159/276 +f 277/148/278 245/129/247 248/140/249 +f 245/129/247 211/117/210 215/118/214 +f 211/117/210 189/100/190 188/99/188 +f 294/176/300 302/160/302 276/159/276 +f 276/159/276 277/148/278 248/140/249 +f 245/129/247 215/118/214 248/140/249 +f 211/117/210 188/99/188 215/118/214 +f 334/179/334 319/165/324 318/173/322 +f 319/165/324 295/150/298 302/160/302 +f 295/150/298 273/137/275 277/148/278 +f 273/137/275 241/127/241 245/129/247 +f 241/127/241 207/112/207 211/117/210 +f 207/112/207 191/101/191 189/100/190 +f 318/173/322 319/165/324 302/160/302 +f 302/160/302 295/150/298 277/148/278 +f 277/148/278 273/137/275 245/129/247 +f 241/127/241 211/117/210 245/129/247 +f 207/112/207 189/100/190 211/117/210 +f 183/96/183 154/22/154 175/63/180 +f 185/97/184 150/69/151 183/96/183 +f 150/69/151 120/33/120 154/22/154 +f 150/69/151 154/22/154 183/96/183 +f 186/98/187 146/79/146 185/97/184 +f 146/79/146 116/50/117 150/69/151 +f 116/50/117 88/29/91 120/33/120 +f 185/97/184 146/79/146 150/69/151 +f 116/50/117 120/33/120 150/69/151 +f 188/99/188 147/85/147 186/98/187 +f 147/85/147 114/62/115 146/79/146 +f 114/62/115 84/44/87 116/50/117 +f 84/44/87 66/25/62 88/29/91 +f 186/98/187 147/85/147 146/79/146 +f 114/62/115 116/50/117 146/79/146 +f 84/44/87 88/29/91 116/50/117 +f 189/100/190 151/86/153 188/99/188 +f 151/86/153 117/74/119 147/85/147 +f 117/74/119 85/55/86 114/62/115 +f 85/55/86 60/43/60 84/44/87 +f 60/43/60 42/26/41 66/25/62 +f 188/99/188 151/86/153 147/85/147 +f 147/85/147 117/74/119 114/62/115 +f 85/55/86 84/44/87 114/62/115 +f 60/43/60 66/25/62 84/44/87 +f 191/101/191 155/91/157 189/100/190 +f 155/91/157 121/76/121 151/86/153 +f 121/76/121 89/64/89 117/74/119 +f 89/64/89 67/53/64 85/55/86 +f 67/53/64 43/38/39 60/43/60 +f 43/38/39 28/23/29 42/26/41 +f 189/100/190 155/91/157 151/86/153 +f 151/86/153 121/76/121 117/74/119 +f 89/64/89 85/55/86 117/74/119 +f 67/53/64 60/43/60 85/55/86 +f 43/38/39 42/26/41 60/43/60 +f 154/386/154 162/318/162 175/355/180 +f 120/33/120 132/1/132 154/22/154 +f 132/361/132 140/329/136 162/318/162 +f 132/361/132 162/318/162 154/386/154 +f 88/29/91 100/5/101 120/33/120 +f 100/375/101 108/346/108 132/361/132 +f 108/346/108 124/324/124 140/329/136 +f 120/33/120 100/5/101 132/1/132 +f 108/346/108 140/329/136 132/361/132 +f 66/25/62 70/11/72 88/29/91 +f 70/381/72 78/365/81 100/375/101 +f 78/365/81 92/340/94 108/346/108 +f 92/340/94 104/328/104 124/324/124 +f 88/29/91 70/11/72 100/5/101 +f 78/365/81 108/346/108 100/375/101 +f 92/340/94 124/324/124 108/346/108 +f 42/26/41 38/12/43 66/25/62 +f 38/382/43 52/370/52 70/381/72 +f 52/370/52 56/351/59 78/365/81 +f 56/351/59 74/339/76 92/340/94 +f 74/339/76 96/325/97 104/328/104 +f 66/25/62 38/12/43 70/11/72 +f 70/381/72 52/370/52 78/365/81 +f 56/351/59 92/340/94 78/365/81 +f 74/339/76 104/328/104 92/340/94 +f 28/23/29 20/17/22 42/26/41 +f 20/17/22 24/3/25 38/12/43 +f 24/372/25 34/366/34 52/370/52 +f 34/366/34 48/349/48 56/351/59 +f 48/349/48 62/334/68 74/339/76 +f 62/334/68 82/320/82 96/325/97 +f 42/26/41 20/17/22 38/12/43 +f 38/382/43 24/372/25 52/370/52 +f 34/366/34 56/351/59 52/370/52 +f 48/349/48 74/339/76 56/351/59 +f 62/334/68 96/325/97 74/339/76 +f 162/318/162 198/255/200 175/281/180 +f 140/329/136 174/282/173 162/318/162 +f 174/282/173 220/244/226 198/255/200 +f 174/282/173 198/255/200 162/318/162 +f 124/324/124 166/301/159 140/329/136 +f 166/301/159 194/272/204 174/282/173 +f 194/272/204 236/245/238 220/244/226 +f 140/329/136 166/301/159 174/282/173 +f 194/272/204 220/244/226 174/282/173 +f 104/328/104 136/307/140 124/324/124 +f 136/307/140 172/283/193 166/301/159 +f 172/283/193 224/266/223 194/272/204 +f 224/266/223 256/251/258 236/245/238 +f 124/324/124 136/307/140 166/301/159 +f 172/283/193 194/272/204 166/301/159 +f 224/266/223 236/245/238 194/272/204 +f 96/325/97 128/308/128 104/328/104 +f 128/308/128 158/296/167 136/307/140 +f 158/296/167 202/277/197 172/283/193 +f 202/277/197 232/265/234 224/266/223 +f 232/265/234 264/246/264 256/251/258 +f 104/328/104 128/308/128 136/307/140 +f 136/307/140 158/296/167 172/283/193 +f 202/277/197 224/266/223 172/283/193 +f 232/265/234 256/251/258 224/266/223 +f 82/320/82 112/313/112 96/325/97 +f 112/313/112 144/298/145 128/308/128 +f 144/298/145 170/284/172 158/296/167 +f 170/284/172 218/275/219 202/277/197 +f 218/275/219 250/260/250 232/265/234 +f 250/260/250 280/252/280 264/246/264 +f 96/325/97 112/313/112 128/308/128 +f 128/308/128 144/298/145 158/296/167 +f 158/296/167 170/284/172 202/277/197 +f 218/275/219 232/265/234 202/277/197 +f 250/260/250 264/246/264 232/265/234 +f 176/287/181 208/276/206 200/279/198 +f 208/276/206 242/261/242 230/269/229 +f 200/279/198 230/269/229 222/274/224 +f 208/276/206 230/269/229 200/279/198 +f 242/261/242 274/249/274 262/258/263 +f 230/269/229 262/258/263 254/263/255 +f 222/274/224 254/263/255 238/268/236 +f 242/261/242 262/258/263 230/269/229 +f 230/269/229 254/263/255 222/274/224 +f 274/249/274 296/238/299 292/241/291 +f 262/258/263 292/241/291 284/248/285 +f 254/263/255 284/248/285 270/256/271 +f 238/268/236 270/256/271 257/262/257 +f 262/258/263 274/249/274 292/241/291 +f 262/258/263 284/248/285 254/263/255 +f 238/268/236 254/263/255 270/256/271 +f 296/238/299 320/223/325 324/230/319 +f 292/241/291 324/230/319 310/236/308 +f 284/248/285 310/236/308 306/243/306 +f 270/256/271 306/243/306 287/253/288 +f 257/262/257 287/253/288 265/257/265 +f 292/241/291 296/238/299 324/230/319 +f 284/248/285 292/241/291 310/236/308 +f 270/256/271 284/248/285 306/243/306 +f 257/262/257 270/256/271 287/253/288 +f 320/223/325 335/209/335 342/220/343 +f 324/230/319 342/220/343 338/225/338 +f 310/236/308 338/225/338 328/231/326 +f 306/243/306 328/231/326 313/237/312 +f 287/253/288 313/237/312 299/242/297 +f 265/257/265 299/242/297 280/252/280 +f 324/230/319 320/223/325 342/220/343 +f 310/236/308 324/230/319 338/225/338 +f 306/243/306 310/236/308 328/231/326 +f 306/243/306 313/237/312 287/253/288 +f 265/257/265 287/253/288 299/242/297 +f 335/209/335 343/202/341 349/205/349 +f 343/202/341 339/187/337 355/195/354 +f 349/205/349 355/195/354 361/200/361 +f 343/202/341 355/195/354 349/205/349 +f 339/187/337 329/180/329 347/184/344 +f 355/195/354 347/184/344 359/189/359 +f 361/200/361 359/189/359 362/194/362 +f 339/187/337 347/184/344 355/195/354 +f 355/195/354 359/189/359 361/200/361 +f 329/180/329 315/164/314 333/167/333 +f 347/184/344 333/167/333 351/174/351 +f 359/189/359 351/174/351 357/182/357 +f 362/194/362 357/182/357 360/188/360 +f 347/184/344 329/180/329 333/167/333 +f 347/184/344 351/174/351 359/189/359 +f 362/194/362 359/189/359 357/182/357 +f 315/164/314 301/149/294 317/156/317 +f 333/167/333 317/156/317 332/162/332 +f 351/174/351 332/162/332 345/169/345 +f 357/182/357 345/169/345 353/177/352 +f 360/188/360 353/177/352 348/183/348 +f 333/167/333 315/164/314 317/156/317 +f 351/174/351 333/167/333 332/162/332 +f 357/182/357 351/174/351 345/169/345 +f 360/188/360 357/182/357 353/177/352 +f 301/149/294 281/135/281 300/146/295 +f 317/156/317 300/146/295 314/151/315 +f 332/162/332 314/151/315 327/157/328 +f 345/169/345 327/157/328 337/163/339 +f 353/177/352 337/163/339 341/168/342 +f 348/183/348 341/168/342 334/179/334 +f 317/156/317 301/149/294 300/146/295 +f 332/162/332 317/156/317 314/151/315 +f 345/169/345 332/162/332 327/157/328 +f 345/169/345 337/163/339 353/177/352 +f 348/183/348 353/177/352 341/168/342 +f 281/135/281 251/128/251 266/131/267 +f 251/128/251 219/113/218 234/121/233 +f 266/131/267 234/121/233 259/126/256 +f 251/128/251 234/121/233 266/131/267 +f 219/113/218 190/104/189 204/110/195 +f 234/121/233 204/110/195 227/115/222 +f 259/126/256 227/115/222 237/120/237 +f 219/113/218 204/110/195 234/121/233 +f 234/121/233 227/115/222 259/126/256 +f 190/104/189 145/90/144 160/93/166 +f 204/110/195 160/93/166 192/103/170 +f 227/115/222 192/103/170 195/108/205 +f 237/120/237 195/108/205 221/114/225 +f 204/110/195 190/104/189 160/93/166 +f 204/110/195 192/103/170 227/115/222 +f 237/120/237 227/115/222 195/108/205 +f 145/90/144 113/75/113 130/82/131 +f 160/93/166 130/82/131 138/88/143 +f 192/103/170 138/88/143 167/95/161 +f 195/108/205 167/95/161 193/102/171 +f 221/114/225 193/102/171 199/109/199 +f 160/93/166 145/90/144 130/82/131 +f 192/103/170 160/93/166 138/88/143 +f 195/108/205 192/103/170 167/95/161 +f 221/114/225 195/108/205 193/102/171 +f 113/75/113 83/67/83 98/72/98 +f 130/82/131 98/72/98 106/77/105 +f 138/88/143 106/77/105 125/83/126 +f 167/95/161 125/83/126 143/89/139 +f 193/102/171 143/89/139 163/94/164 +f 199/109/199 163/94/164 191/101/191 +f 130/82/131 113/75/113 98/72/98 +f 138/88/143 130/82/131 106/77/105 +f 138/88/143 125/83/126 167/95/161 +f 167/95/161 143/89/139 193/102/171 +f 199/109/199 193/102/171 163/94/164 +f 83/67/83 65/54/66 64/57/67 +f 65/54/66 51/39/51 47/47/47 +f 64/57/67 47/47/47 50/52/50 +f 65/54/66 47/47/47 64/57/67 +f 51/39/51 37/30/36 33/36/33 +f 47/47/47 33/36/33 32/41/32 +f 50/52/50 32/41/32 35/46/37 +f 51/39/51 33/36/33 47/47/47 +f 47/47/47 32/41/32 50/52/50 +f 37/30/36 27/16/27 19/19/16 +f 33/36/33 19/19/16 13/28/12 +f 32/41/32 13/28/12 17/34/17 +f 35/46/37 17/34/17 25/40/26 +f 37/30/36 19/19/16 33/36/33 +f 33/36/33 13/28/12 32/41/32 +f 32/41/32 17/34/17 35/46/37 +f 27/385/27 23/371/23 11/378/10 +f 19/19/16 11/8/10 7/14/5 +f 13/28/12 7/14/5 5/21/7 +f 17/34/17 5/21/7 9/24/8 +f 25/40/26 9/24/8 21/35/21 +f 19/19/16 27/16/27 11/8/10 +f 13/28/12 19/19/16 7/14/5 +f 13/28/12 5/21/7 17/34/17 +f 25/40/26 17/34/17 9/24/8 +f 23/371/23 29/363/28 15/368/15 +f 11/378/10 15/368/15 3/373/3 +f 7/384/5 3/373/3 1/379/1 +f 5/21/7 1/9/1 2/15/2 +f 9/24/8 2/15/2 14/20/14 +f 21/35/21 14/20/14 28/23/29 +f 11/378/10 23/371/23 15/368/15 +f 7/384/5 11/378/10 3/373/3 +f 7/14/5 1/9/1 5/21/7 +f 5/21/7 2/15/2 9/24/8 +f 9/24/8 14/20/14 21/35/21 +f 29/363/28 44/350/38 22/353/20 +f 44/350/38 68/335/65 40/343/42 +f 22/353/20 40/343/42 26/348/24 +f 44/350/38 40/343/42 22/353/20 +f 68/335/65 90/322/88 72/332/73 +f 40/343/42 72/332/73 53/337/53 +f 26/348/24 53/337/53 36/342/35 +f 68/335/65 72/332/73 40/343/42 +f 40/343/42 53/337/53 26/348/24 +f 90/322/88 122/312/122 102/315/100 +f 72/332/73 102/315/100 80/321/80 +f 53/337/53 80/321/80 58/330/57 +f 36/342/35 58/330/57 49/336/49 +f 90/322/88 102/315/100 72/332/73 +f 72/332/73 80/321/80 53/337/53 +f 53/337/53 58/330/57 36/342/35 +f 122/312/122 156/297/156 134/304/134 +f 102/315/100 134/304/134 110/310/109 +f 80/321/80 110/310/109 94/317/93 +f 58/330/57 94/317/93 75/326/74 +f 49/336/49 75/326/74 63/331/69 +f 102/315/100 122/312/122 134/304/134 +f 80/321/80 102/315/100 110/310/109 +f 80/321/80 94/317/93 58/330/57 +f 49/336/49 58/330/57 75/326/74 +f 156/297/156 176/287/181 164/294/165 +f 134/304/134 164/294/165 141/299/138 +f 110/310/109 141/299/138 126/305/125 +f 94/317/93 126/305/125 105/311/107 +f 75/326/74 105/311/107 97/316/96 +f 63/331/69 97/316/96 82/320/82 +f 134/304/134 156/297/156 164/294/165 +f 110/310/109 134/304/134 141/299/138 +f 110/310/109 126/305/125 94/317/93 +f 94/317/93 105/311/107 75/326/74 +f 75/326/74 97/316/96 63/331/69 +f 348/183/348 334/179/334 340/186/340 +f 352/193/353 340/186/340 336/201/336 +f 360/188/360 348/183/348 352/193/353 +f 352/193/353 348/183/348 340/186/340 +f 344/204/346 336/201/336 326/215/327 +f 356/199/358 352/193/353 344/204/346 +f 362/194/362 360/188/360 356/199/358 +f 344/204/346 352/193/353 336/201/336 +f 356/199/358 360/188/360 352/193/353 +f 312/224/313 330/221/331 326/215/327 +f 330/221/331 350/212/350 344/204/346 +f 358/206/356 356/199/358 350/212/350 +f 358/206/356 361/200/361 362/194/362 +f 330/221/331 344/204/346 326/215/327 +f 350/212/350 356/199/358 344/204/346 +f 358/206/356 362/194/362 356/199/358 +f 298/239/296 316/232/316 312/224/313 +f 316/232/316 331/226/330 330/221/331 +f 331/226/330 346/219/347 350/212/350 +f 346/219/347 354/208/355 358/206/356 +f 354/208/355 349/205/349 361/200/361 +f 316/232/316 330/221/331 312/224/313 +f 331/226/330 350/212/350 330/221/331 +f 346/219/347 358/206/356 350/212/350 +f 354/208/355 361/200/361 358/206/356 +f 280/252/280 299/242/297 298/239/296 +f 299/242/297 313/237/312 316/232/316 +f 313/237/312 328/231/326 331/226/330 +f 328/231/326 338/225/338 346/219/347 +f 342/220/343 354/208/355 338/225/338 +f 342/220/343 335/209/335 349/205/349 +f 299/242/297 316/232/316 298/239/296 +f 313/237/312 331/226/330 316/232/316 +f 328/231/326 346/219/347 331/226/330 +f 338/225/338 354/208/355 346/219/347 +f 342/220/343 349/205/349 354/208/355 +f 199/109/199 191/101/191 207/112/207 +f 229/119/228 207/112/207 241/127/241 +f 221/114/225 199/109/199 229/119/228 +f 229/119/228 199/109/199 207/112/207 +f 261/130/262 241/127/241 273/137/275 +f 253/125/252 229/119/228 261/130/262 +f 237/120/237 221/114/225 253/125/252 +f 261/130/262 229/119/228 241/127/241 +f 253/125/252 221/114/225 229/119/228 +f 295/150/298 291/147/290 273/137/275 +f 291/147/290 283/139/284 261/130/262 +f 269/132/270 253/125/252 283/139/284 +f 269/132/270 259/126/256 237/120/237 +f 291/147/290 261/130/262 273/137/275 +f 283/139/284 253/125/252 261/130/262 +f 269/132/270 237/120/237 253/125/252 +f 319/165/324 323/158/321 295/150/298 +f 323/158/321 309/152/311 291/147/290 +f 309/152/311 305/145/307 283/139/284 +f 305/145/307 289/143/289 269/132/270 +f 289/143/289 266/131/267 259/126/256 +f 323/158/321 291/147/290 295/150/298 +f 309/152/311 283/139/284 291/147/290 +f 305/145/307 269/132/270 283/139/284 +f 289/143/289 259/126/256 269/132/270 +f 334/179/334 341/168/342 319/165/324 +f 341/168/342 337/163/339 323/158/321 +f 337/163/339 327/157/328 309/152/311 +f 327/157/328 314/151/315 305/145/307 +f 300/146/295 289/143/289 314/151/315 +f 300/146/295 281/135/281 266/131/267 +f 341/168/342 323/158/321 319/165/324 +f 337/163/339 309/152/311 323/158/321 +f 327/157/328 305/145/307 309/152/311 +f 314/151/315 289/143/289 305/145/307 +f 300/146/295 266/131/267 289/143/289 +f 21/35/21 28/23/29 43/38/39 +f 39/45/45 43/38/39 67/53/64 +f 25/40/26 21/35/21 39/45/45 +f 39/45/45 21/35/21 43/38/39 +f 71/56/70 67/53/64 89/64/89 +f 54/51/54 39/45/45 71/56/70 +f 35/46/37 25/40/26 54/51/54 +f 71/56/70 39/45/45 67/53/64 +f 54/51/54 25/40/26 39/45/45 +f 121/76/121 101/73/103 89/64/89 +f 79/68/78 71/56/70 101/73/103 +f 57/58/56 54/51/54 79/68/78 +f 50/52/50 35/46/37 57/58/56 +f 101/73/103 71/56/70 89/64/89 +f 79/68/78 54/51/54 71/56/70 +f 57/58/56 35/46/37 54/51/54 +f 155/91/157 133/84/135 121/76/121 +f 133/84/135 109/78/111 101/73/103 +f 109/78/111 93/71/92 79/68/78 +f 76/66/75 57/58/56 93/71/92 +f 76/66/75 64/57/67 50/52/50 +f 133/84/135 101/73/103 121/76/121 +f 109/78/111 79/68/78 101/73/103 +f 93/71/92 57/58/56 79/68/78 +f 76/66/75 50/52/50 57/58/56 +f 191/101/191 163/94/164 155/91/157 +f 163/94/164 143/89/139 133/84/135 +f 143/89/139 125/83/126 109/78/111 +f 106/77/105 93/71/92 125/83/126 +f 98/72/98 76/66/75 106/77/105 +f 83/67/83 64/57/67 98/72/98 +f 163/94/164 133/84/135 155/91/157 +f 143/89/139 109/78/111 133/84/135 +f 125/83/126 93/71/92 109/78/111 +f 106/77/105 76/66/75 93/71/92 +f 98/72/98 64/57/67 76/66/75 +f 63/331/69 82/320/82 62/334/68 +f 46/341/46 62/334/68 48/349/48 +f 49/336/49 63/331/69 46/341/46 +f 46/341/46 63/331/69 62/334/68 +f 30/352/31 48/349/48 34/366/34 +f 31/347/30 46/341/46 30/352/31 +f 36/342/35 49/336/49 31/347/30 +f 30/352/31 46/341/46 48/349/48 +f 31/347/30 49/336/49 46/341/46 +f 24/372/25 16/369/18 34/366/34 +f 12/358/13 30/352/31 16/369/18 +f 18/354/19 31/347/30 12/358/13 +f 26/348/24 36/342/35 18/354/19 +f 16/369/18 30/352/31 34/366/34 +f 12/358/13 31/347/30 30/352/31 +f 18/354/19 36/342/35 31/347/30 +f 20/17/22 8/10/9 24/3/25 +f 8/380/9 4/374/4 16/369/18 +f 4/374/4 6/367/6 12/358/13 +f 10/362/11 18/354/19 6/367/6 +f 10/362/11 22/353/20 26/348/24 +f 8/380/9 16/369/18 24/372/25 +f 4/374/4 12/358/13 16/369/18 +f 6/367/6 18/354/19 12/358/13 +f 10/362/11 26/348/24 18/354/19 +f 28/23/29 14/20/14 20/17/22 +f 14/20/14 2/15/2 8/10/9 +f 2/15/2 1/9/1 4/4/4 +f 3/373/3 6/367/6 1/379/1 +f 15/368/15 10/362/11 3/373/3 +f 29/363/28 22/353/20 15/368/15 +f 14/20/14 8/10/9 20/17/22 +f 2/15/2 4/4/4 8/10/9 +f 1/379/1 6/367/6 4/374/4 +f 3/373/3 10/362/11 6/367/6 +f 15/368/15 22/353/20 10/362/11 +f 265/257/265 280/252/280 250/260/250 +f 233/267/232 250/260/250 218/275/219 +f 257/262/257 265/257/265 233/267/232 +f 233/267/232 265/257/265 250/260/250 +f 203/278/196 218/275/219 170/284/172 +f 225/273/220 233/267/232 203/278/196 +f 238/268/236 257/262/257 225/273/220 +f 203/278/196 233/267/232 218/275/219 +f 225/273/220 257/262/257 233/267/232 +f 144/298/145 159/295/169 170/284/172 +f 159/295/169 171/285/192 203/278/196 +f 196/280/202 225/273/220 171/285/192 +f 196/280/202 222/274/224 238/268/236 +f 159/295/169 203/278/196 170/284/172 +f 171/285/192 225/273/220 203/278/196 +f 196/280/202 238/268/236 225/273/220 +f 112/313/112 129/306/130 144/298/145 +f 129/306/130 137/300/141 159/295/169 +f 137/300/141 168/293/158 171/285/192 +f 168/293/158 173/286/174 196/280/202 +f 173/286/174 200/279/198 222/274/224 +f 129/306/130 159/295/169 144/298/145 +f 137/300/141 171/285/192 159/295/169 +f 168/293/158 196/280/202 171/285/192 +f 173/286/174 222/274/224 196/280/202 +f 82/320/82 97/316/96 112/313/112 +f 97/316/96 105/311/107 129/306/130 +f 105/311/107 126/305/125 137/300/141 +f 141/299/138 168/293/158 126/305/125 +f 164/294/165 173/286/174 141/299/138 +f 164/294/165 176/287/181 200/279/198 +f 97/316/96 129/306/130 112/313/112 +f 105/311/107 137/300/141 129/306/130 +f 126/305/125 168/293/158 137/300/141 +f 141/299/138 173/286/174 168/293/158 +f 164/294/165 200/279/198 173/286/174 diff --git a/L10/resources/square.obj b/L10/resources/square.obj new file mode 100644 index 0000000..7a7b508 --- /dev/null +++ b/L10/resources/square.obj @@ -0,0 +1,11 @@ +v -0.500000 -0.500000 0.000000 +v 0.500000 -0.500000 0.000000 +v -0.500000 0.500000 0.000000 +v 0.500000 0.500000 0.000000 +vn 0.000000 0.000000 1.000000 +vt 0 0 +vt 1 0 +vt 0 1 +vt 1 1 +f 2/2/1 4/4/1 3/3/1 +f 1/1/1 2/2/1 3/3/1 diff --git a/L10/resources/vert.glsl b/L10/resources/vert.glsl new file mode 100644 index 0000000..b81b9fb --- /dev/null +++ b/L10/resources/vert.glsl @@ -0,0 +1,17 @@ +#version 120 + +uniform mat4 P; +uniform mat4 MV; +uniform mat3 T; + +attribute vec4 aPos; +attribute vec3 aNor; +attribute vec2 aTex; + +varying vec2 vTex0; + +void main() +{ + gl_Position = P * MV * aPos; + vTex0 = aTex; +} diff --git a/L10/src/Camera.cpp b/L10/src/Camera.cpp new file mode 100644 index 0000000..55114ae --- /dev/null +++ b/L10/src/Camera.cpp @@ -0,0 +1,68 @@ +#include "Camera.h" +#include "MatrixStack.h" +#include +#define _USE_MATH_DEFINES +#include +#include + +Camera::Camera() : + aspect(1.0f), + fovy((float)(45.0*M_PI/180.0)), + znear(0.1f), + zfar(1000.0f), + rotations(0.0, 0.0), + translations(0.0f, 0.0f, -5.0f), + rfactor(0.01f), + tfactor(0.001f), + sfactor(0.005f) +{ +} + +Camera::~Camera() +{ +} + +void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt) +{ + mousePrev.x = x; + mousePrev.y = y; + if(shift) { + state = Camera::TRANSLATE; + } else if(ctrl) { + state = Camera::SCALE; + } else { + state = Camera::ROTATE; + } +} + +void Camera::mouseMoved(float x, float y) +{ + glm::vec2 mouseCurr(x, y); + glm::vec2 dv = mouseCurr - mousePrev; + switch(state) { + case Camera::ROTATE: + rotations += rfactor * dv; + break; + case Camera::TRANSLATE: + translations.x -= translations.z * tfactor * dv.x; + translations.y += translations.z * tfactor * dv.y; + break; + case Camera::SCALE: + translations.z *= (1.0f - sfactor * dv.y); + break; + } + mousePrev = mouseCurr; +} + +void Camera::applyProjectionMatrix(std::shared_ptr P) const +{ + // Modify provided MatrixStack + P->multMatrix(glm::perspective(fovy, aspect, znear, zfar)); +} + +void Camera::applyViewMatrix(std::shared_ptr MV) const +{ + MV->translate(translations); + MV->rotate(rotations.y, glm::vec3(1.0f, 0.0f, 0.0f)); + MV->rotate(rotations.x, glm::vec3(0.0f, 1.0f, 0.0f)); +} diff --git a/L10/src/Camera.h b/L10/src/Camera.h new file mode 100644 index 0000000..8501605 --- /dev/null +++ b/L10/src/Camera.h @@ -0,0 +1,47 @@ +#pragma once +#ifndef __Camera__ +#define __Camera__ + +#include + +#define GLM_FORCE_RADIANS +#include + +class MatrixStack; + +class Camera +{ +public: + enum { + ROTATE = 0, + TRANSLATE, + SCALE + }; + + Camera(); + virtual ~Camera(); + void setInitDistance(float z) { translations.z = -std::abs(z); } + void setAspect(float a) { aspect = a; }; + void setRotationFactor(float f) { rfactor = f; }; + void setTranslationFactor(float f) { tfactor = f; }; + void setScaleFactor(float f) { sfactor = f; }; + void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt); + void mouseMoved(float x, float y); + void applyProjectionMatrix(std::shared_ptr P) const; + void applyViewMatrix(std::shared_ptr MV) const; + +private: + float aspect; + float fovy; + float znear; + float zfar; + glm::vec2 rotations; + glm::vec3 translations; + glm::vec2 mousePrev; + int state; + float rfactor; + float tfactor; + float sfactor; +}; + +#endif diff --git a/L10/src/GLSL.cpp b/L10/src/GLSL.cpp new file mode 100644 index 0000000..2969872 --- /dev/null +++ b/L10/src/GLSL.cpp @@ -0,0 +1,152 @@ +// +// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book +// Created by zwood on 2/21/10. +// Modified by sueda 10/15/15. +// + +#include "GLSL.h" +#include +#include +#include +#include + +using namespace std; + +namespace GLSL { + +const char * errorString(GLenum err) +{ + switch(err) { + case GL_NO_ERROR: + return "No error"; + case GL_INVALID_ENUM: + return "Invalid enum"; + case GL_INVALID_VALUE: + return "Invalid value"; + case GL_INVALID_OPERATION: + return "Invalid operation"; + case GL_STACK_OVERFLOW: + return "Stack overflow"; + case GL_STACK_UNDERFLOW: + return "Stack underflow"; + case GL_OUT_OF_MEMORY: + return "Out of memory"; + default: + return "No error"; + } +} + +void checkVersion() +{ + int major, minor; + major = minor = 0; + const char *verstr = (const char *)glGetString(GL_VERSION); + + if((verstr == NULL) || (sscanf(verstr, "%d.%d", &major, &minor) != 2)) { + printf("Invalid GL_VERSION format %d.%d\n", major, minor); + } + if(major < 2) { + printf("This shader example will not work due to the installed Opengl version, which is %d.%d.\n", major, minor); + exit(0); + } +} + +void checkError(const char *str) +{ + GLenum glErr = glGetError(); + if(glErr != GL_NO_ERROR) { + if(str) { + printf("%s: ", str); + } + printf("GL_ERROR = %s.\n", errorString(glErr)); + assert(false); + } +} + +void printShaderInfoLog(GLuint shader) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog = 0; + + checkError(GET_FILE_LINE); + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength); + checkError(GET_FILE_LINE); + + if(infologLength > 0) { + infoLog = (GLchar *)malloc(infologLength); + if(infoLog == NULL) { + puts("ERROR: Could not allocate InfoLog buffer"); + exit(1); + } + glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog); + checkError(GET_FILE_LINE); + printf("Shader InfoLog:\n%s\n\n", infoLog); + free(infoLog); + } +} + +void printProgramInfoLog(GLuint program) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog = 0; + + checkError(GET_FILE_LINE); + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infologLength); + checkError(GET_FILE_LINE); + + if(infologLength > 0) { + infoLog = (GLchar *)malloc(infologLength); + if(infoLog == NULL) { + puts("ERROR: Could not allocate InfoLog buffer"); + exit(1); + } + glGetProgramInfoLog(program, infologLength, &charsWritten, infoLog); + checkError(GET_FILE_LINE); + printf("Program InfoLog:\n%s\n\n", infoLog); + free(infoLog); + } +} + +char *textFileRead(const char *fn) +{ + FILE *fp; + char *content = NULL; + int count = 0; + if(fn != NULL) { + fp = fopen(fn,"rt"); + if(fp != NULL) { + fseek(fp, 0, SEEK_END); + count = (int)ftell(fp); + rewind(fp); + if(count > 0) { + content = (char *)malloc(sizeof(char) * (count+1)); + count = (int)fread(content,sizeof(char),count,fp); + content[count] = '\0'; + } + fclose(fp); + } else { + printf("error loading %s\n", fn); + } + } + return content; +} + +int textFileWrite(const char *fn, const char *s) +{ + FILE *fp; + int status = 0; + if(fn != NULL) { + fp = fopen(fn,"w"); + if(fp != NULL) { + if(fwrite(s,sizeof(char),strlen(s),fp) == strlen(s)) { + status = 1; + } + fclose(fp); + } + } + return(status); +} + +} diff --git a/L10/src/GLSL.h b/L10/src/GLSL.h new file mode 100644 index 0000000..f945fdd --- /dev/null +++ b/L10/src/GLSL.h @@ -0,0 +1,40 @@ +// +// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book +// Created by zwood on 2/21/10. +// Modified by sueda 10/15/15. +// + +#pragma once +#ifndef __GLSL__ +#define __GLSL__ + +#define GLEW_STATIC +#include + +/////////////////////////////////////////////////////////////////////////////// +// For printing out the current file and line number // +/////////////////////////////////////////////////////////////////////////////// +#include + +template +std::string NumberToString(T x) +{ + std::ostringstream ss; + ss << x; + return ss.str(); +} + +#define GET_FILE_LINE (std::string(__FILE__) + ":" + NumberToString(__LINE__)).c_str() +/////////////////////////////////////////////////////////////////////////////// + +namespace GLSL { + + void checkVersion(); + void checkError(const char *str = 0); + void printProgramInfoLog(GLuint program); + void printShaderInfoLog(GLuint shader); + int textFileWrite(const char *filename, const char *s); + char *textFileRead(const char *filename); +} + +#endif diff --git a/L10/src/MatrixStack.cpp b/L10/src/MatrixStack.cpp new file mode 100644 index 0000000..eaa6e6c --- /dev/null +++ b/L10/src/MatrixStack.cpp @@ -0,0 +1,114 @@ +#include "MatrixStack.h" + +#include +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +using namespace std; + +MatrixStack::MatrixStack() +{ + mstack = make_shared< stack >(); + mstack->push(glm::mat4(1.0)); +} + +MatrixStack::~MatrixStack() +{ +} + +void MatrixStack::pushMatrix() +{ + const glm::mat4 &top = mstack->top(); + mstack->push(top); + assert(mstack->size() < 100); +} + +void MatrixStack::popMatrix() +{ + assert(!mstack->empty()); + mstack->pop(); + // There should always be one matrix left. + assert(!mstack->empty()); +} + +void MatrixStack::loadIdentity() +{ + glm::mat4 &top = mstack->top(); + top = glm::mat4(1.0); +} + +void MatrixStack::translate(const glm::vec3 &t) +{ + glm::mat4 &top = mstack->top(); + top *= glm::translate(t); +} + +void MatrixStack::translate(float x, float y, float z) +{ + translate(glm::vec3(x, y, z)); +} + +void MatrixStack::scale(const glm::vec3 &s) +{ + glm::mat4 &top = mstack->top(); + top *= glm::scale(s); +} + +void MatrixStack::scale(float x, float y, float z) +{ + scale(glm::vec3(x, y, z)); +} + +void MatrixStack::scale(float s) +{ + scale(glm::vec3(s, s, s)); +} + +void MatrixStack::rotate(float angle, const glm::vec3 &axis) +{ + glm::mat4 &top = mstack->top(); + top *= glm::rotate(angle, axis); +} + +void MatrixStack::rotate(float angle, float x, float y, float z) +{ + rotate(angle, glm::vec3(x, y, z)); +} + +void MatrixStack::multMatrix(const glm::mat4 &matrix) +{ + glm::mat4 &top = mstack->top(); + top *= matrix; +} + +const glm::mat4 &MatrixStack::topMatrix() const +{ + return mstack->top(); +} + +void MatrixStack::print(const glm::mat4 &mat, const char *name) +{ + if(name) { + printf("%s = [\n", name); + } + for(int i = 0; i < 4; ++i) { + for(int j = 0; j < 4; ++j) { + // mat[j] returns the jth column + printf("%- 5.2f ", mat[j][i]); + } + printf("\n"); + } + if(name) { + printf("];"); + } + printf("\n"); +} + +void MatrixStack::print(const char *name) const +{ + print(mstack->top(), name); +} diff --git a/L10/src/MatrixStack.h b/L10/src/MatrixStack.h new file mode 100644 index 0000000..66278ce --- /dev/null +++ b/L10/src/MatrixStack.h @@ -0,0 +1,50 @@ +#pragma once +#ifndef _MatrixStack_H_ +#define _MatrixStack_H_ + +#include +#include +#include + +class MatrixStack +{ +public: + MatrixStack(); + virtual ~MatrixStack(); + + // glPushMatrix(): Copies the current matrix and adds it to the top of the stack + void pushMatrix(); + // glPopMatrix(): Removes the top of the stack and sets the current matrix to be the matrix that is now on top + void popMatrix(); + + // glLoadIdentity(): Sets the top matrix to be the identity + void loadIdentity(); + // glMultMatrix(): Right multiplies the top matrix + void multMatrix(const glm::mat4 &matrix); + + // glTranslate(): Right multiplies the top matrix by a translation matrix + void translate(const glm::vec3 &trans); + void translate(float x, float y, float z); + // glScale(): Right multiplies the top matrix by a scaling matrix + void scale(const glm::vec3 &scale); + void scale(float x, float y, float z); + // glScale(): Right multiplies the top matrix by a scaling matrix + void scale(float size); + // glRotate(): Right multiplies the top matrix by a rotation matrix (angle in radians) + void rotate(float angle, const glm::vec3 &axis); + void rotate(float angle, float x, float y, float z); + + // glGet(GL_MODELVIEW_MATRIX): Gets the top matrix + const glm::mat4 &topMatrix() const; + + // Prints out the specified matrix + static void print(const glm::mat4 &mat, const char *name = 0); + // Prints out the top matrix + void print(const char *name = 0) const; + +private: + std::shared_ptr< std::stack > mstack; + +}; + +#endif diff --git a/L10/src/Program.cpp b/L10/src/Program.cpp new file mode 100644 index 0000000..1e85538 --- /dev/null +++ b/L10/src/Program.cpp @@ -0,0 +1,126 @@ +#include "Program.h" + +#include +#include + +#include "GLSL.h" + +using namespace std; + +Program::Program() : + vShaderName(""), + fShaderName(""), + pid(0), + verbose(true) +{ + +} + +Program::~Program() +{ + +} + +void Program::setShaderNames(const string &v, const string &f) +{ + vShaderName = v; + fShaderName = f; +} + +bool Program::init() +{ + GLint rc; + + // Create shader handles + GLuint VS = glCreateShader(GL_VERTEX_SHADER); + GLuint FS = glCreateShader(GL_FRAGMENT_SHADER); + + // Read shader sources + const char *vshader = GLSL::textFileRead(vShaderName.c_str()); + const char *fshader = GLSL::textFileRead(fShaderName.c_str()); + glShaderSource(VS, 1, &vshader, NULL); + glShaderSource(FS, 1, &fshader, NULL); + + // Compile vertex shader + glCompileShader(VS); + glGetShaderiv(VS, GL_COMPILE_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printShaderInfoLog(VS); + cout << "Error compiling vertex shader " << vShaderName << endl; + } + return false; + } + + // Compile fragment shader + glCompileShader(FS); + glGetShaderiv(FS, GL_COMPILE_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printShaderInfoLog(FS); + cout << "Error compiling fragment shader " << fShaderName << endl; + } + return false; + } + + // Create the program and link + pid = glCreateProgram(); + glAttachShader(pid, VS); + glAttachShader(pid, FS); + glLinkProgram(pid); + glGetProgramiv(pid, GL_LINK_STATUS, &rc); + if(!rc) { + if(isVerbose()) { + GLSL::printProgramInfoLog(pid); + cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl; + } + return false; + } + + GLSL::checkError(GET_FILE_LINE); + return true; +} + +void Program::bind() +{ + glUseProgram(pid); +} + +void Program::unbind() +{ + glUseProgram(0); +} + +void Program::addAttribute(const string &name) +{ + attributes[name] = glGetAttribLocation(pid, name.c_str()); +} + +void Program::addUniform(const string &name) +{ + uniforms[name] = glGetUniformLocation(pid, name.c_str()); +} + +GLint Program::getAttribute(const string &name) const +{ + map::const_iterator attribute = attributes.find(name.c_str()); + if(attribute == attributes.end()) { + if(isVerbose()) { + cout << name << " is not an attribute variable" << endl; + } + return -1; + } + return attribute->second; +} + +GLint Program::getUniform(const string &name) const +{ + map::const_iterator uniform = uniforms.find(name.c_str()); + if(uniform == uniforms.end()) { + if(isVerbose()) { + cout << name << " is not a uniform variable" << endl; + } + return -1; + } + return uniform->second; +} diff --git a/L10/src/Program.h b/L10/src/Program.h new file mode 100644 index 0000000..51e58bb --- /dev/null +++ b/L10/src/Program.h @@ -0,0 +1,44 @@ +#pragma once +#ifndef __Program__ +#define __Program__ + +#include +#include + +#define GLEW_STATIC +#include + +/** + * An OpenGL Program (vertex and fragment shaders) + */ +class Program +{ +public: + Program(); + virtual ~Program(); + + void setVerbose(bool v) { verbose = v; } + bool isVerbose() const { return verbose; } + + void setShaderNames(const std::string &v, const std::string &f); + virtual bool init(); + virtual void bind(); + virtual void unbind(); + + void addAttribute(const std::string &name); + void addUniform(const std::string &name); + GLint getAttribute(const std::string &name) const; + GLint getUniform(const std::string &name) const; + +protected: + std::string vShaderName; + std::string fShaderName; + +private: + GLuint pid; + std::map attributes; + std::map uniforms; + bool verbose; +}; + +#endif diff --git a/L10/src/Shape.cpp b/L10/src/Shape.cpp new file mode 100644 index 0000000..426ef9c --- /dev/null +++ b/L10/src/Shape.cpp @@ -0,0 +1,165 @@ +#include "Shape.h" +#include + +#include "GLSL.h" +#include "Program.h" + +#define GLM_FORCE_RADIANS +#include + +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" + +using namespace std; + +Shape::Shape() : + posBufID(0), + norBufID(0), + texBufID(0) +{ +} + +Shape::~Shape() +{ +} + +void Shape::loadMesh(const string &meshName) +{ + // Load geometry + tinyobj::attrib_t attrib; + std::vector shapes; + std::vector materials; + string errStr; + bool rc = tinyobj::LoadObj(&attrib, &shapes, &materials, &errStr, meshName.c_str()); + if(!rc) { + cerr << errStr << endl; + } else { + // Some OBJ files have different indices for vertex positions, normals, + // and texture coordinates. For example, a cube corner vertex may have + // three different normals. Here, we are going to duplicate all such + // vertices. + // Loop over shapes + for(size_t s = 0; s < shapes.size(); s++) { + // Loop over faces (polygons) + size_t index_offset = 0; + for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { + size_t fv = shapes[s].mesh.num_face_vertices[f]; + // Loop over vertices in the face. + for(size_t v = 0; v < fv; v++) { + // access to vertex + tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v]; + posBuf.push_back(attrib.vertices[3*idx.vertex_index+0]); + posBuf.push_back(attrib.vertices[3*idx.vertex_index+1]); + posBuf.push_back(attrib.vertices[3*idx.vertex_index+2]); + if(!attrib.normals.empty()) { + norBuf.push_back(attrib.normals[3*idx.normal_index+0]); + norBuf.push_back(attrib.normals[3*idx.normal_index+1]); + norBuf.push_back(attrib.normals[3*idx.normal_index+2]); + } + if(!attrib.texcoords.empty()) { + texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+0]); + texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+1]); + } + } + index_offset += fv; + // per-face material (IGNORE) + shapes[s].mesh.material_ids[f]; + } + } + } +} + +void Shape::fitToUnitBox() +{ + // Scale the vertex positions so that they fit within [-1, +1] in all three dimensions. + glm::vec3 vmin(posBuf[0], posBuf[1], posBuf[2]); + glm::vec3 vmax(posBuf[0], posBuf[1], posBuf[2]); + for(int i = 0; i < (int)posBuf.size(); i += 3) { + glm::vec3 v(posBuf[i], posBuf[i+1], posBuf[i+2]); + vmin.x = min(vmin.x, v.x); + vmin.y = min(vmin.y, v.y); + vmin.z = min(vmin.z, v.z); + vmax.x = max(vmax.x, v.x); + vmax.y = max(vmax.y, v.y); + vmax.z = max(vmax.z, v.z); + } + glm::vec3 center = 0.5f*(vmin + vmax); + glm::vec3 diff = vmax - vmin; + float diffmax = diff.x; + diffmax = max(diffmax, diff.y); + diffmax = max(diffmax, diff.z); + float scale = 1.0f / diffmax; + for(int i = 0; i < (int)posBuf.size(); i += 3) { + posBuf[i ] = (posBuf[i ] - center.x) * scale; + posBuf[i+1] = (posBuf[i+1] - center.y) * scale; + posBuf[i+2] = (posBuf[i+2] - center.z) * scale; + } +} + +void Shape::init() +{ + // Send the position array to the GPU + glGenBuffers(1, &posBufID); + glBindBuffer(GL_ARRAY_BUFFER, posBufID); + glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_STATIC_DRAW); + + // Send the normal array to the GPU + if(!norBuf.empty()) { + glGenBuffers(1, &norBufID); + glBindBuffer(GL_ARRAY_BUFFER, norBufID); + glBufferData(GL_ARRAY_BUFFER, norBuf.size()*sizeof(float), &norBuf[0], GL_STATIC_DRAW); + } + + // Send the texture array to the GPU + if(!texBuf.empty()) { + glGenBuffers(1, &texBufID); + glBindBuffer(GL_ARRAY_BUFFER, texBufID); + glBufferData(GL_ARRAY_BUFFER, texBuf.size()*sizeof(float), &texBuf[0], GL_STATIC_DRAW); + } + + // Unbind the arrays + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLSL::checkError(GET_FILE_LINE); +} + +void Shape::draw(const shared_ptr prog) const +{ + // Bind position buffer + int h_pos = prog->getAttribute("aPos"); + glEnableVertexAttribArray(h_pos); + glBindBuffer(GL_ARRAY_BUFFER, posBufID); + glVertexAttribPointer(h_pos, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0); + + // Bind normal buffer + int h_nor = prog->getAttribute("aNor"); + if(h_nor != -1 && norBufID != 0) { + glEnableVertexAttribArray(h_nor); + glBindBuffer(GL_ARRAY_BUFFER, norBufID); + glVertexAttribPointer(h_nor, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0); + } + + // Bind texcoords buffer + int h_tex = prog->getAttribute("aTex"); + if(h_tex != -1 && texBufID != 0) { + glEnableVertexAttribArray(h_tex); + glBindBuffer(GL_ARRAY_BUFFER, texBufID); + glVertexAttribPointer(h_tex, 2, GL_FLOAT, GL_FALSE, 0, (const void *)0); + } + + // Draw + int count = posBuf.size()/3; // number of indices to be rendered + glDrawArrays(GL_TRIANGLES, 0, count); + + // Disable and unbind + if(h_tex != -1) { + glDisableVertexAttribArray(h_tex); + } + if(h_nor != -1) { + glDisableVertexAttribArray(h_nor); + } + glDisableVertexAttribArray(h_pos); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + GLSL::checkError(GET_FILE_LINE); +} diff --git a/L10/src/Shape.h b/L10/src/Shape.h new file mode 100644 index 0000000..297476c --- /dev/null +++ b/L10/src/Shape.h @@ -0,0 +1,37 @@ +#pragma once +#ifndef _SHAPE_H_ +#define _SHAPE_H_ + +#include +#include +#include + +class Program; + +/** + * A shape defined by a list of triangles + * - posBuf should be of length 3*ntris + * - norBuf should be of length 3*ntris (if normals are available) + * - texBuf should be of length 2*ntris (if texture coords are available) + * posBufID, norBufID, and texBufID are OpenGL buffer identifiers. + */ +class Shape +{ +public: + Shape(); + virtual ~Shape(); + void loadMesh(const std::string &meshName); + void fitToUnitBox(); + void init(); + void draw(const std::shared_ptr prog) const; + +private: + std::vector posBuf; + std::vector norBuf; + std::vector texBuf; + unsigned posBufID; + unsigned norBufID; + unsigned texBufID; +}; + +#endif diff --git a/L10/src/Texture.cpp b/L10/src/Texture.cpp new file mode 100644 index 0000000..1537763 --- /dev/null +++ b/L10/src/Texture.cpp @@ -0,0 +1,80 @@ +#include "Texture.h" +#include +#include +#include +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +using namespace std; + +Texture::Texture() : + filename(""), + tid(0) +{ + +} + +Texture::~Texture() +{ + +} + +void Texture::init() +{ + // Load texture + int w, h, ncomps; + stbi_set_flip_vertically_on_load(true); + unsigned char *data = stbi_load(filename.c_str(), &w, &h, &ncomps, 0); + if(!data) { + cerr << filename << " not found" << endl; + } + if(ncomps != 3) { + cerr << filename << " must have 3 components (RGB)" << endl; + } + if((w & (w - 1)) != 0 || (h & (h - 1)) != 0) { + cerr << filename << " must be a power of 2" << endl; + } + width = w; + height = h; + + // Generate a texture buffer object + glGenTextures(1, &tid); + // Bind the current texture to be the newly generated texture object + glBindTexture(GL_TEXTURE_2D, tid); + // Load the actual texture data + // Base level is 0, number of channels is 3, and border is 0. + glTexImage2D(GL_TEXTURE_2D, 0, ncomps, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + // Generate image pyramid + glGenerateMipmap(GL_TEXTURE_2D); + // Set texture wrap modes for the S and T directions + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // Set filtering mode for magnification and minimification + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + // Unbind + glBindTexture(GL_TEXTURE_2D, 0); + // Free image, since the data is now on the GPU + stbi_image_free(data); +} + +void Texture::setWrapModes(GLint wrapS, GLint wrapT) +{ + // Must be called after init() + glBindTexture(GL_TEXTURE_2D, tid); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); +} + +void Texture::bind(GLint handle) +{ + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(GL_TEXTURE_2D, tid); + glUniform1i(handle, unit); +} + +void Texture::unbind() +{ + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/L10/src/Texture.h b/L10/src/Texture.h new file mode 100644 index 0000000..9209149 --- /dev/null +++ b/L10/src/Texture.h @@ -0,0 +1,32 @@ +#pragma once +#ifndef __Texture__ +#define __Texture__ + +#define GLEW_STATIC +#include + +#include + +class Texture +{ +public: + Texture(); + virtual ~Texture(); + void setFilename(const std::string &f) { filename = f; } + void init(); + void setUnit(GLint u) { unit = u; } + GLint getUnit() const { return unit; } + void bind(GLint handle); + void unbind(); + void setWrapModes(GLint wrapS, GLint wrapT); // Must be called after init() + +private: + std::string filename; + int width; + int height; + GLuint tid; + GLint unit; + +}; + +#endif diff --git a/L10/src/main.cpp b/L10/src/main.cpp new file mode 100644 index 0000000..0aa9bc5 --- /dev/null +++ b/L10/src/main.cpp @@ -0,0 +1,273 @@ +#include +#include +#define _USE_MATH_DEFINES +#include +#include +#include + +#define GLEW_STATIC +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +#include "Camera.h" +#include "GLSL.h" +#include "MatrixStack.h" +#include "Program.h" +#include "Shape.h" +#include "Texture.h" + +using namespace std; + +GLFWwindow *window; // Main application window +string RESOURCE_DIR = "./"; // Where the resources are loaded from + +shared_ptr camera; +shared_ptr prog; +shared_ptr texture0; +shared_ptr texture1; +shared_ptr texture2; +shared_ptr shape; + +glm::mat3 T; +glm::vec3 lightPosCam; + +bool keyToggles[256] = {false}; // only for English keyboards! + +// This function is called when a GLFW error occurs +static void error_callback(int error, const char *description) +{ + cerr << description << endl; +} + +// This function is called when a key is pressed +static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) +{ + if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GL_TRUE); + } +} + +// This function is called when the mouse is clicked +static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) +{ + // Get the current mouse position. + double xmouse, ymouse; + glfwGetCursorPos(window, &xmouse, &ymouse); + // Get current window size. + int width, height; + glfwGetWindowSize(window, &width, &height); + if(action == GLFW_PRESS) { + bool shift = (mods & GLFW_MOD_SHIFT) != 0; + bool ctrl = (mods & GLFW_MOD_CONTROL) != 0; + bool alt = (mods & GLFW_MOD_ALT) != 0; + camera->mouseClicked((float)xmouse, (float)ymouse, shift, ctrl, alt); + } +} + +// This function is called when the mouse moves +static void cursor_position_callback(GLFWwindow* window, double xmouse, double ymouse) +{ + int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); + if(state == GLFW_PRESS) { + camera->mouseMoved((float)xmouse, (float)ymouse); + } +} + +static void char_callback(GLFWwindow *window, unsigned int key) +{ + keyToggles[key] = !keyToggles[key]; + switch(key) { + case 'x': + lightPosCam.x += 0.1; + break; + case 'X': + lightPosCam.x -= 0.1; + break; + case 'y': + lightPosCam.y += 0.1; + break; + case 'Y': + lightPosCam.y -= 0.1; + break; + } +} + +// If the window is resized, capture the new size and reset the viewport +static void resize_callback(GLFWwindow *window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +// This function is called once to initialize the scene and OpenGL +static void init() +{ + // Initialize time. + glfwSetTime(0.0); + + // Set background color. + glClearColor(0.2f, 0.2f, 0.2f, 1.0f); + // Enable z-buffer test. + glEnable(GL_DEPTH_TEST); + + prog = make_shared(); + prog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "frag.glsl"); + prog->setVerbose(true); + prog->init(); + prog->addAttribute("aPos"); + prog->addAttribute("aNor"); + prog->addAttribute("aTex"); + prog->addUniform("P"); + prog->addUniform("MV"); + prog->addUniform("T"); + prog->addUniform("texture0"); + prog->addUniform("texture1"); + prog->addUniform("texture2"); + prog->addUniform("lightPosCam"); + prog->setVerbose(false); + + camera = make_shared(); + camera->setInitDistance(3.0f); + + texture0 = make_shared(); + texture0->setFilename(RESOURCE_DIR + "earthKd.jpg"); + texture0->init(); + texture0->setUnit(0); + texture0->setWrapModes(GL_REPEAT, GL_REPEAT); + + texture1 = make_shared(); + texture1->setFilename(RESOURCE_DIR + "earthKs.jpg"); + texture1->init(); + texture1->setUnit(1); + texture1->setWrapModes(GL_REPEAT, GL_REPEAT); + + texture2 = make_shared(); + texture2->setFilename(RESOURCE_DIR + "earthClouds.jpg"); + texture2->init(); + texture2->setUnit(2); + texture2->setWrapModes(GL_REPEAT, GL_REPEAT); + + lightPosCam.x = 1.0f; + lightPosCam.y = 1.0f; + lightPosCam.z = 1.0f; + + shape = make_shared(); + shape->loadMesh(RESOURCE_DIR + "sphere.obj"); + shape->init(); + + GLSL::checkError(GET_FILE_LINE); +} + +// This function is called every frame to draw the scene. +static void render() +{ + // Clear framebuffer. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if(keyToggles[(unsigned)'c']) { + glEnable(GL_CULL_FACE); + } else { + glDisable(GL_CULL_FACE); + } + if(keyToggles[(unsigned)'l']) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } else { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + + // Get current frame buffer size. + int width, height; + glfwGetFramebufferSize(window, &width, &height); + camera->setAspect((float)width/(float)height); + + // Matrix stacks + auto P = make_shared(); + auto MV = make_shared(); + + // Apply camera transforms + P->pushMatrix(); + camera->applyProjectionMatrix(P); + MV->pushMatrix(); + camera->applyViewMatrix(MV); + + prog->bind(); + texture0->bind(prog->getUniform("texture0")); + texture1->bind(prog->getUniform("texture1")); + texture2->bind(prog->getUniform("texture2")); + glUniformMatrix4fv(prog->getUniform("P"), 1, GL_FALSE, glm::value_ptr(P->topMatrix())); + glUniformMatrix4fv(prog->getUniform("MV"), 1, GL_FALSE, glm::value_ptr(MV->topMatrix())); + glUniformMatrix3fv(prog->getUniform("T"), 1, GL_FALSE, glm::value_ptr(T)); + glUniform3fv(prog->getUniform("lightPosCam"), 1, glm::value_ptr(lightPosCam)); + shape->draw(prog); + texture1->unbind(); + texture0->unbind(); + prog->unbind(); + + MV->popMatrix(); + P->popMatrix(); + + GLSL::checkError(GET_FILE_LINE); +} + +int main(int argc, char **argv) +{ + if(argc < 2) { + cout << "Please specify the resource directory." << endl; + return 0; + } + RESOURCE_DIR = argv[1] + string("/"); + + // Set error callback. + glfwSetErrorCallback(error_callback); + // Initialize the library. + if(!glfwInit()) { + return -1; + } + // Create a windowed mode window and its OpenGL context. + window = glfwCreateWindow(640, 480, "YOUR NAME", NULL, NULL); + if(!window) { + glfwTerminate(); + return -1; + } + // Make the window's context current. + glfwMakeContextCurrent(window); + // Initialize GLEW. + glewExperimental = true; + if(glewInit() != GLEW_OK) { + cerr << "Failed to initialize GLEW" << endl; + return -1; + } + glGetError(); // A bug in glewInit() causes an error that we can safely ignore. + cout << "OpenGL version: " << glGetString(GL_VERSION) << endl; + cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl; + GLSL::checkVersion(); + // Set vsync. + glfwSwapInterval(1); + // Set keyboard callback. + glfwSetKeyCallback(window, key_callback); + // Set char callback. + glfwSetCharCallback(window, char_callback); + // Set cursor position callback. + glfwSetCursorPosCallback(window, cursor_position_callback); + // Set mouse button callback. + glfwSetMouseButtonCallback(window, mouse_button_callback); + // Set the window resize call back. + glfwSetFramebufferSizeCallback(window, resize_callback); + // Initialize scene. + init(); + // Loop until the user closes the window. + while(!glfwWindowShouldClose(window)) { + // Render scene. + render(); + // Swap front and back buffers. + glfwSwapBuffers(window); + // Poll for and process events. + glfwPollEvents(); + } + // Quit program. + glfwDestroyWindow(window); + glfwTerminate(); + return 0; +} diff --git a/L10/src/stb_image.h b/L10/src/stb_image.h new file mode 100644 index 0000000..a3c1129 --- /dev/null +++ b/L10/src/stb_image.h @@ -0,0 +1,6755 @@ +/* stb_image - v2.12 - public domain image loader - http://nothings.org/stb_image.h + no warranty implied; use at your own risk + + Do this: + #define STB_IMAGE_IMPLEMENTATION + before you include this file in *one* C or C++ file to create the implementation. + + // i.e. it should look like this: + #include ... + #include ... + #include ... + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + + You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. + And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free + + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) + PNG 1/2/4/8-bit-per-channel (16 bpc not supported) + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels, 8/16 bit-per-channel) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + PNM (PPM and PGM binary only) + + Animated GIF still needs a proper API, but here's one way to do it: + http://gist.github.com/urraka/685d9a6340b26b830d49 + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) + + Full documentation under "DOCUMENTATION" below. + + + Revision 2.00 release notes: + + - Progressive JPEG is now supported. + + - PPM and PGM binary formats are now supported, thanks to Ken Miller. + + - x86 platforms now make use of SSE2 SIMD instructions for + JPEG decoding, and ARM platforms can use NEON SIMD if requested. + This work was done by Fabian "ryg" Giesen. SSE2 is used by + default, but NEON must be enabled explicitly; see docs. + + With other JPEG optimizations included in this version, we see + 2x speedup on a JPEG on an x86 machine, and a 1.5x speedup + on a JPEG on an ARM machine, relative to previous versions of this + library. The same results will not obtain for all JPGs and for all + x86/ARM machines. (Note that progressive JPEGs are significantly + slower to decode than regular JPEGs.) This doesn't mean that this + is the fastest JPEG decoder in the land; rather, it brings it + closer to parity with standard libraries. If you want the fastest + decode, look elsewhere. (See "Philosophy" section of docs below.) + + See final bullet items below for more info on SIMD. + + - Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing + the memory allocator. Unlike other STBI libraries, these macros don't + support a context parameter, so if you need to pass a context in to + the allocator, you'll have to store it in a global or a thread-local + variable. + + - Split existing STBI_NO_HDR flag into two flags, STBI_NO_HDR and + STBI_NO_LINEAR. + STBI_NO_HDR: suppress implementation of .hdr reader format + STBI_NO_LINEAR: suppress high-dynamic-range light-linear float API + + - You can suppress implementation of any of the decoders to reduce + your code footprint by #defining one or more of the following + symbols before creating the implementation. + + STBI_NO_JPEG + STBI_NO_PNG + STBI_NO_BMP + STBI_NO_PSD + STBI_NO_TGA + STBI_NO_GIF + STBI_NO_HDR + STBI_NO_PIC + STBI_NO_PNM (.ppm and .pgm) + + - You can request *only* certain decoders and suppress all other ones + (this will be more forward-compatible, as addition of new decoders + doesn't require you to disable them explicitly): + + STBI_ONLY_JPEG + STBI_ONLY_PNG + STBI_ONLY_BMP + STBI_ONLY_PSD + STBI_ONLY_TGA + STBI_ONLY_GIF + STBI_ONLY_HDR + STBI_ONLY_PIC + STBI_ONLY_PNM (.ppm and .pgm) + + Note that you can define multiples of these, and you will get all + of them ("only x" and "only y" is interpreted to mean "only x&y"). + + - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still + want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB + + - Compilation of all SIMD code can be suppressed with + #define STBI_NO_SIMD + It should not be necessary to disable SIMD unless you have issues + compiling (e.g. using an x86 compiler which doesn't support SSE + intrinsics or that doesn't support the method used to detect + SSE2 support at run-time), and even those can be reported as + bugs so I can refine the built-in compile-time checking to be + smarter. + + - The old STBI_SIMD system which allowed installing a user-defined + IDCT etc. has been removed. If you need this, don't upgrade. My + assumption is that almost nobody was doing this, and those who + were will find the built-in SIMD more satisfactory anyway. + + - RGB values computed for JPEG images are slightly different from + previous versions of stb_image. (This is due to using less + integer precision in SIMD.) The C code has been adjusted so + that the same RGB values will be computed regardless of whether + SIMD support is available, so your app should always produce + consistent results. But these results are slightly different from + previous versions. (Specifically, about 3% of available YCbCr values + will compute different RGB results from pre-1.49 versions by +-1; + most of the deviating values are one smaller in the G channel.) + + - If you must produce consistent results with previous versions of + stb_image, #define STBI_JPEG_OLD and you will get the same results + you used to; however, you will not get the SIMD speedups for + the YCbCr-to-RGB conversion step (although you should still see + significant JPEG speedup from the other changes). + + Please note that STBI_JPEG_OLD is a temporary feature; it will be + removed in future versions of the library. It is only intended for + near-term back-compatibility use. + + + Latest revision history: + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 + RGB-format JPEG; remove white matting in PSD; + allocate large structures on the stack; + correct channel count for PNG & BMP + 2.10 (2016-01-22) avoid warning introduced in 2.09 + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) partial animated GIF support + limited 16-bit PSD support + minor bugs, code cleanup, and compiler warnings + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) additional corruption checking + stbi_set_flip_vertically_on_load + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPEG, including x86 SSE2 & ARM NEON SIMD + progressive JPEG + PGM/PPM support + STBI_MALLOC,STBI_REALLOC,STBI_FREE + STBI_NO_*, STBI_ONLY_* + GIF bugfix + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + urraka@github (animated gif) Junggon Kim (PNM comments) + Daniel Gibson (16-bit TGA) + + Optimizations & bugfixes + Fabian "ryg" Giesen + Arseny Kapoulkine + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson + Dave Moore Roy Eltham Hayaki Saito Phil Jordan + Won Chun Luke Graham Johan Duparc Nathan Reed + the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis + Janez Zemva John Bartholomew Michal Cichon svdijk@github + Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson + Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github + Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan + Ryamond Barbiero Paul Du Bois Engin Manap snagar@github + Michaelangel007@github Oriol Ferrer Mesia socks-the-fox + Blazej Dariusz Roszkowski + + +LICENSE + +This software is dual-licensed to the public domain and under the following +license: you are granted a perpetual, irrevocable license to copy, modify, +publish, and distribute this file as you see fit. + +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// DOCUMENTATION +// +// Limitations: +// - no 16-bit-per-channel PNG +// - no 12-bit-per-channel JPEG +// - no JPEGs with arithmetic coding +// - no 1-bit BMP +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below for HDR usage): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *comp -- outputs # of image components in image file +// int req_comp -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data, or NULL on an allocation failure or if the image is +// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise. +// If req_comp is non-zero, *comp has the number of components that _would_ +// have been output otherwise. E.g. if you set req_comp to 4, you will always +// get RGBA output, but you can check *comp to see if it's trivially opaque +// because e.g. there were only 3 channels in the source image. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *comp will be unchanged. The function stbi_failure_reason() +// can be queried for an extremely brief, end-user unfriendly explanation +// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid +// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// =========================================================================== +// +// Philosophy +// +// stb libraries are designed with the following priorities: +// +// 1. easy to use +// 2. easy to maintain +// 3. good performance +// +// Sometimes I let "good performance" creep up in priority over "easy to maintain", +// and for best performance I may provide less-easy-to-use APIs that give higher +// performance, in addition to the easy to use ones. Nevertheless, it's important +// to keep in mind that from the standpoint of you, a client of this library, +// all you care about is #1 and #3, and stb libraries do not emphasize #3 above all. +// +// Some secondary priorities arise directly from the first two, some of which +// make more explicit reasons why performance can't be emphasized. +// +// - Portable ("ease of use") +// - Small footprint ("easy to maintain") +// - No dependencies ("ease of use") +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). +// +// =========================================================================== +// +// SIMD support +// +// The JPEG decoder will try to automatically use SIMD kernels on x86 when +// supported by the compiler. For ARM Neon support, you must explicitly +// request it. +// +// (The old do-it-yourself SIMD API is no longer supported in the current +// code.) +// +// On x86, SSE2 will automatically be used when available based on a run-time +// test; if not, the generic C versions are used as a fall-back. On ARM targets, +// the typical path is to have separate builds for NEON and non-NEON devices +// (at least this is true for iOS and Android). Therefore, the NEON support is +// toggled by a build flag: define STBI_NEON to get NEON loops. +// +// The output of the JPEG decoder is slightly different from versions where +// SIMD support was introduced (that is, for versions before 1.49). The +// difference is only +-1 in the 8-bit RGB channels, and only on a small +// fraction of pixels. You can force the pre-1.49 behavior by defining +// STBI_JPEG_OLD, but this will disable some of the SIMD decoding path +// and hence cost some performance. +// +// If for some reason you do not want to use any of SIMD code, or if +// you have issues compiling it, you can disable it entirely by +// defining STBI_NO_SIMD. +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image now supports loading HDR images in general, and currently +// the Radiance .HDR file format, although the support is provided +// generically. You can still load any file through the existing interface; +// if you attempt to load an HDR file, it will be automatically remapped to +// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// iPhone PNG support: +// +// By default we convert iphone-formatted PNGs back to RGB, even though +// they are internally encoded differently. You can disable this conversion +// by by calling stbi_convert_iphone_png_to_rgb(0), in which case +// you will always just get the native iphone "format" through (which +// is BGR stored in RGB). +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// + + +#ifndef STBI_NO_STDIO +#include +#endif // STBI_NO_STDIO + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for req_comp + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +typedef unsigned char stbi_uc; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef STB_IMAGE_STATIC +#define STBIDEF static +#else +#define STBIDEF extern +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); +STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *comp, int req_comp); +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *comp, int req_comp); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +#ifndef STBI_NO_LINEAR + STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); + STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + + #ifndef STBI_NO_STDIO + STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + #endif +#endif + +#ifndef STBI_NO_HDR + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); + STBIDEF void stbi_hdr_to_ldr_scale(float scale); +#endif // STBI_NO_HDR + +#ifndef STBI_NO_LINEAR + STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); + STBIDEF void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_LINEAR + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename); +STBIDEF int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// NOT THREADSAFE +STBIDEF const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +STBIDEF void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); + +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); +STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifdef STB_IMAGE_IMPLEMENTATION + +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ + || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ + || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ + || defined(STBI_ONLY_ZLIB) + #ifndef STBI_ONLY_JPEG + #define STBI_NO_JPEG + #endif + #ifndef STBI_ONLY_PNG + #define STBI_NO_PNG + #endif + #ifndef STBI_ONLY_BMP + #define STBI_NO_BMP + #endif + #ifndef STBI_ONLY_PSD + #define STBI_NO_PSD + #endif + #ifndef STBI_ONLY_TGA + #define STBI_NO_TGA + #endif + #ifndef STBI_ONLY_GIF + #define STBI_NO_GIF + #endif + #ifndef STBI_ONLY_HDR + #define STBI_NO_HDR + #endif + #ifndef STBI_ONLY_PIC + #define STBI_NO_PIC + #endif + #ifndef STBI_ONLY_PNM + #define STBI_NO_PNM + #endif +#endif + +#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) +#define STBI_NO_ZLIB +#endif + + +#include +#include // ptrdiff_t on osx +#include +#include + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +#include // ldexp +#endif + +#ifndef STBI_NO_STDIO +#include +#endif + +#ifndef STBI_ASSERT +#include +#define STBI_ASSERT(x) assert(x) +#endif + + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + + +#ifdef _MSC_VER +typedef unsigned short stbi__uint16; +typedef signed short stbi__int16; +typedef unsigned int stbi__uint32; +typedef signed int stbi__int32; +#else +#include +typedef uint16_t stbi__uint16; +typedef int16_t stbi__int16; +typedef uint32_t stbi__uint32; +typedef int32_t stbi__int32; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBI_NOTUSED(v) (void)(v) +#else +#define STBI_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#endif + +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) +// ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." +#endif + +#ifndef STBI_MALLOC +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED +#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#endif + +// x86/x64 detection +#if defined(__x86_64__) || defined(_M_X64) +#define STBI__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) +#define STBI__X86_TARGET +#endif + +#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) +// NOTE: not clear do we actually need this for the 64-bit path? +// gcc doesn't support sse2 intrinsics unless you compile with -msse2, +// (but compiling with -msse2 allows the compiler to use SSE2 everywhere; +// this is just broken and gcc are jerks for not fixing it properly +// http://www.virtualdub.org/blog/pivot/entry.php?id=363 ) +#define STBI_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) +// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET +// +// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the +// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. +// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not +// simultaneously enabling "-mstackrealign". +// +// See https://github.com/nothings/stb/issues/81 for more information. +// +// So default to no SSE2 on 32-bit MinGW. If you've read this far and added +// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. +#define STBI_NO_SIMD +#endif + +#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) +#define STBI_SSE2 +#include + +#ifdef _MSC_VER + +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid +static int stbi__cpuid3(void) +{ + int info[4]; + __cpuid(info,1); + return info[3]; +} +#else +static int stbi__cpuid3(void) +{ + int res; + __asm { + mov eax,1 + cpuid + mov res,edx + } + return res; +} +#endif + +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + +static int stbi__sse2_available() +{ + int info3 = stbi__cpuid3(); + return ((info3 >> 26) & 1) != 0; +} +#else // assume GCC-style if not VC++ +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + +static int stbi__sse2_available() +{ +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later + // GCC 4.8+ has a nice way to do this + return __builtin_cpu_supports("sse2"); +#else + // portable way to do this, preferably without using GCC inline ASM? + // just bail for now. + return 0; +#endif +} +#endif +#endif + +// ARM NEON +#if defined(STBI_NO_SIMD) && defined(STBI_NEON) +#undef STBI_NEON +#endif + +#ifdef STBI_NEON +#include +// assume GCC or Clang on ARM targets +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif + +#ifndef STBI_SIMD_ALIGN +#define STBI_SIMD_ALIGN(type, name) type name +#endif + +/////////////////////////////////////////////// +// +// stbi__context struct and start_xxx functions + +// stbi__context structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + stbi__uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + stbi_uc buffer_start[128]; + + stbi_uc *img_buffer, *img_buffer_end; + stbi_uc *img_buffer_original, *img_buffer_original_end; +} stbi__context; + + +static void stbi__refill_buffer(stbi__context *s); + +// initialize a memory-decode context +static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; +} + +// initialize a callback-based context +static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->img_buffer_original = s->buffer_start; + stbi__refill_buffer(s); + s->img_buffer_original_end = s->img_buffer_end; +} + +#ifndef STBI_NO_STDIO + +static int stbi__stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stbi__stdio_skip(void *user, int n) +{ + fseek((FILE*) user, n, SEEK_CUR); +} + +static int stbi__stdio_eof(void *user) +{ + return feof((FILE*) user); +} + +static stbi_io_callbacks stbi__stdio_callbacks = +{ + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, +}; + +static void stbi__start_file(stbi__context *s, FILE *f) +{ + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi__context *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi__rewind(stbi__context *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; + s->img_buffer_end = s->img_buffer_original_end; +} + +#ifndef STBI_NO_JPEG +static int stbi__jpeg_test(stbi__context *s); +static stbi_uc *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNG +static int stbi__png_test(stbi__context *s); +static stbi_uc *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_BMP +static int stbi__bmp_test(stbi__context *s); +static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_TGA +static int stbi__tga_test(stbi__context *s); +static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s); +static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_HDR +static int stbi__hdr_test(stbi__context *s); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_test(stbi__context *s); +static stbi_uc *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_GIF +static int stbi__gif_test(stbi__context *s); +static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNM +static int stbi__pnm_test(stbi__context *s); +static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +// this is not threadsafe +static const char *stbi__g_failure_reason; + +STBIDEF const char *stbi_failure_reason(void) +{ + return stbi__g_failure_reason; +} + +static int stbi__err(const char *str) +{ + stbi__g_failure_reason = str; + return 0; +} + +static void *stbi__malloc(size_t size) +{ + return STBI_MALLOC(size); +} + +// stbi__err - error +// stbi__errpf - error returning pointer to float +// stbi__errpuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define stbi__err(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define stbi__err(x,y) stbi__err(y) +#else + #define stbi__err(x,y) stbi__err(x) +#endif + +#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) + +STBIDEF void stbi_image_free(void *retval_from_stbi_load) +{ + STBI_FREE(retval_from_stbi_load); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_HDR +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static int stbi__vertically_flip_on_load = 0; + +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load = flag_true_if_should_flip; +} + +static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PNG + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_BMP + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_GIF + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PSD + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PIC + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PNM + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp); + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp); + return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + #ifndef STBI_NO_TGA + // test tga last because it's a crappy test! + if (stbi__tga_test(s)) + return stbi__tga_load(s,x,y,comp,req_comp); + #endif + + return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result = stbi__load_main(s, x, y, comp, req_comp); + + if (stbi__vertically_flip_on_load && result != NULL) { + int w = *x, h = *y; + int depth = req_comp ? req_comp : *comp; + int row,col,z; + stbi_uc temp; + + // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once + for (row = 0; row < (h>>1); row++) { + for (col = 0; col < w; col++) { + for (z = 0; z < depth; z++) { + temp = result[(row * w + col) * depth + z]; + result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; + result[((h - row - 1) * w + col) * depth + z] = temp; + } + } + } + } + + return result; +} + +#ifndef STBI_NO_HDR +static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) +{ + if (stbi__vertically_flip_on_load && result != NULL) { + int w = *x, h = *y; + int depth = req_comp ? req_comp : *comp; + int row,col,z; + float temp; + + // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once + for (row = 0; row < (h>>1); row++) { + for (col = 0; col < w; col++) { + for (z = 0; z < depth; z++) { + temp = result[(row * w + col) * depth + z]; + result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; + result[((h - row - 1) * w + col) * depth + z] = temp; + } + } + } + } +} +#endif + +#ifndef STBI_NO_STDIO + +static FILE *stbi__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + + +STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + unsigned char *result; + if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_flip(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} +#endif //!STBI_NO_STDIO + +STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_flip(&s,x,y,comp,req_comp); +} + +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__load_flip(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp); + if (hdr_data) + stbi__float_postprocess(hdr_data,x,y,comp,req_comp); + return hdr_data; + } + #endif + data = stbi__load_flip(s, x, y, comp, req_comp); + if (data) + return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); +} + +STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + float *result; + FILE *f = stbi__fopen(filename, "rb"); + if (!f) return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_file(&s,f); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_LINEAR + +// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is +// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always +// reports false! + +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +STBIDEF int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_file(&s,f); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(f); + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(clbk); + STBI_NOTUSED(user); + return 0; + #endif +} + +#ifndef STBI_NO_LINEAR +static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; + +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } +STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } +#endif + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } +STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + STBI__SCAN_load=0, + STBI__SCAN_type, + STBI__SCAN_header +}; + +static void stbi__refill_buffer(stbi__context *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + if (n == 0) { + // at end of file, treat same as if from memory, but need to handle case + // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start+1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static stbi_uc stbi__get8(stbi__context *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + stbi__refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +stbi_inline static int stbi__at_eof(stbi__context *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} + +static void stbi__skip(stbi__context *s, int n) +{ + if (n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} + +static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} + +static int stbi__get16be(stbi__context *s) +{ + int z = stbi__get8(s); + return (z << 8) + stbi__get8(s); +} + +static stbi__uint32 stbi__get32be(stbi__context *s) +{ + stbi__uint32 z = stbi__get16be(s); + return (z << 16) + stbi__get16be(s); +} + +#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) +// nothing +#else +static int stbi__get16le(stbi__context *s) +{ + int z = stbi__get8(s); + return z + (stbi__get8(s) << 8); +} +#endif + +#ifndef STBI_NO_BMP +static stbi__uint32 stbi__get32le(stbi__context *s) +{ + stbi__uint32 z = stbi__get16le(s); + return z + (stbi__get16le(s) << 16); +} +#endif + +#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings + + +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static stbi_uc stbi__compute_y(int r, int g, int b) +{ + return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); +} + +static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) stbi__malloc(req_comp * x * y); + if (good == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define COMBO(a,b) ((a)*8+(b)) + #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (COMBO(img_n, req_comp)) { + CASE(1,2) dest[0]=src[0], dest[1]=255; break; + CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; + CASE(2,1) dest[0]=src[0]; break; + CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; + CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; + CASE(3,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; + CASE(3,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; break; + CASE(4,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; + CASE(4,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; + CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; + default: STBI_ASSERT(0); + } + #undef CASE + } + + STBI_FREE(data); + return good; +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output = (float *) stbi__malloc(x * y * comp * sizeof(float)); + if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + } + if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; + } + STBI_FREE(data); + return output; +} +#endif + +#ifndef STBI_NO_HDR +#define stbi__float2int(x) ((int) (x)) +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output = (stbi_uc *) stbi__malloc(x * y * comp); + if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + } + STBI_FREE(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder +// +// simple implementation +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - some SIMD kernels for common paths on targets with SSE2/NEON +// - uses a lot of intermediate memory, could cache poorly + +#ifndef STBI_NO_JPEG + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + stbi_uc fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + stbi__uint16 code[256]; + stbi_uc values[256]; + stbi_uc size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} stbi__huffman; + +typedef struct +{ + stbi__context *s; + stbi__huffman huff_dc[4]; + stbi__huffman huff_ac[4]; + stbi_uc dequant[4][64]; + stbi__int16 fast_ac[4][1 << FAST_BITS]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + stbi_uc *data; + void *raw_data, *raw_coeff; + stbi_uc *linebuf; + short *coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks + } img_comp[4]; + + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int rgb; + + int scan_n, order[4]; + int restart_interval, todo; + +// kernels + void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); + stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); +} stbi__jpeg; + +static int stbi__build_huffman(stbi__huffman *h, int *count) +{ + int i,j,k=0,code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (stbi_uc) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (stbi__uint16) (code++); + if (code-1 >= (1 << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (stbi_uc) i; + } + } + } + return 1; +} + +// build a table that decodes both magnitude and value of small ACs in +// one go. +static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) +{ + int i; + for (i=0; i < (1 << FAST_BITS); ++i) { + stbi_uc fast = h->fast[i]; + fast_ac[i] = 0; + if (fast < 255) { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if (magbits && len + magbits <= FAST_BITS) { + // magnitude code followed by receive_extend code + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if (k < m) k += (-1 << magbits) + 1; + // if the result is small enough, we can fit it in fast_ac table + if (k >= -128 && k <= 127) + fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits)); + } + } + } +} + +static void stbi__grow_buffer_unsafe(stbi__jpeg *j) +{ + do { + int b = j->nomore ? 0 : stbi__get8(j->s); + if (b == 0xff) { + int c = stbi__get8(j->s); + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; + STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); + + sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB + k = stbi_lrot(j->code_buffer, n); + STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k + (stbi__jbias[n] & ~sgn); +} + +// get some unsigned bits +stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) +{ + unsigned int k; + if (j->code_bits < n) stbi__grow_buffer_unsafe(j); + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k; +} + +stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) +{ + unsigned int k; + if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static stbi_uc stbi__jpeg_dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi_uc *dequant) +{ + int diff,dc,k; + int t; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? stbi__extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * dequant[0]); + + // decode AC components, see JPEG spec + k = 1; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * dequant[zig]); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); + } + } + } while (k < 64); + return 1; +} + +static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) +{ + int diff,dc; + int t; + if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + if (j->succ_high == 0) { + // first scan for DC coefficient, must be first + memset(data,0,64*sizeof(data[0])); // 0 all the ac values now + t = stbi__jpeg_huff_decode(j, hdc); + diff = t ? stbi__extend_receive(j, t) : 0; + + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc << j->succ_low); + } else { + // refinement scan for DC coefficient + if (stbi__jpeg_get_bit(j)) + data[0] += (short) (1 << j->succ_low); + } + return 1; +} + +// @OPTIMIZE: store non-zigzagged during the decode passes, +// and only de-zigzag when dequantizing +static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) +{ + int k; + if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->succ_high == 0) { + int shift = j->succ_low; + + if (j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) << shift); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r); + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } else { + k += r; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) << shift); + } + } + } while (k <= j->spec_end); + } else { + // refinement scan for these AC coefficients + + short bit = (short) (1 << j->succ_low); + + if (j->eob_run) { + --j->eob_run; + for (k = j->spec_start; k <= j->spec_end; ++k) { + short *p = &data[stbi__jpeg_dezigzag[k]]; + if (*p != 0) + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } + } else { + k = j->spec_start; + do { + int r,s; + int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r) - 1; + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + r = 64; // force end of block + } else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } else { + if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if (stbi__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while (k <= j->spec_end) { + short *p = &data[stbi__jpeg_dezigzag[k++]]; + if (*p != 0) { + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } else { + if (r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while (k <= j->spec_end); + } + } + return 1; +} + +// take a -128..127 value and stbi__clamp it and convert to 0..255 +stbi_inline static stbi_uc stbi__clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (stbi_uc) x; +} + +#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) << 12) + +// derived from jidctint -- DCT_ISLOW +#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3*stbi__f2f(-1.847759065f); \ + t3 = p1 + p2*stbi__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2+p3); \ + t1 = stbi__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ + t0 = t0*stbi__f2f( 0.298631336f); \ + t1 = t1*stbi__f2f( 2.053119869f); \ + t2 = t2*stbi__f2f( 3.072711026f); \ + t3 = t3*stbi__f2f( 1.501321110f); \ + p1 = p5 + p1*stbi__f2f(-0.899976223f); \ + p2 = p5 + p2*stbi__f2f(-2.562915447f); \ + p3 = p3*stbi__f2f(-1.961570560f); \ + p4 = p4*stbi__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) +{ + int i,val[64],*v=val; + stbi_uc *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0] << 2; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = stbi__clamp((x0+t3) >> 17); + o[7] = stbi__clamp((x0-t3) >> 17); + o[1] = stbi__clamp((x1+t2) >> 17); + o[6] = stbi__clamp((x1-t2) >> 17); + o[2] = stbi__clamp((x2+t1) >> 17); + o[5] = stbi__clamp((x2-t1) >> 17); + o[3] = stbi__clamp((x3+t0) >> 17); + o[4] = stbi__clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SSE2 +// sse2 integer IDCT. not the fastest possible implementation but it +// produces bit-identical results to the generic C version so it's +// fully "transparent". +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + // This is constructed to match our regular (generic) integer IDCT exactly. + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + // dot product constant: even elems=x, odd elems=y + #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + // out(1) = c1[even]*x + c1[odd]*y + #define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + // out = in << 12 (in 16-bit, out 32-bit) + #define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + // wide add + #define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + // wide sub + #define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + // butterfly a/b, add bias, then shift by "s" and pack + #define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + // 8-bit interleave step (for transposes) + #define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + // 16-bit interleave step (for transposes) + #define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + + #define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); + + // rounding biases in column/row passes, see stbi__idct_block for explanation. + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + + // load + row0 = _mm_load_si128((const __m128i *) (data + 0*8)); + row1 = _mm_load_si128((const __m128i *) (data + 1*8)); + row2 = _mm_load_si128((const __m128i *) (data + 2*8)); + row3 = _mm_load_si128((const __m128i *) (data + 3*8)); + row4 = _mm_load_si128((const __m128i *) (data + 4*8)); + row5 = _mm_load_si128((const __m128i *) (data + 5*8)); + row6 = _mm_load_si128((const __m128i *) (data + 6*8)); + row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + + // column pass + dct_pass(bias_0, 10); + + { + // 16bit 8x8 transpose pass 1 + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + // transpose pass 2 + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + // transpose pass 3 + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + // row pass + dct_pass(bias_1, 17); + + { + // pack + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif // STBI_SSE2 + +#ifdef STBI_NEON + +// NEON integer IDCT. should produce bit-identical +// results to the generic C version. +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + +// wide add +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + +// wide sub +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + +// butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0*8); + row1 = vld1q_s16(data + 1*8); + row2 = vld1q_s16(data + 2*8); + row3 = vld1q_s16(data + 3*8); + row4 = vld1q_s16(data + 4*8); + row5 = vld1q_s16(data + 5*8); + row6 = vld1q_s16(data + 6*8); + row7 = vld1q_s16(data + 7*8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { +// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. +// whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + // row pass + // vrshrn_n_s32 only supports shifts up to 16, we need + // 17. so do a non-rounding shift of 16 first then follow + // up with a rounding shift by 1. + dct_pass(vshrn_n_s32, 16); + + { + // pack and round + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + // again, these can translate into one instruction, but often don't. +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + // sadly can't use interleaved stores here since we only write + // 8 bytes to each scan line! + + // 8x8 8-bit transpose pass 1 + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + // pass 2 + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + // pass 3 + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + // store + vst1_u8(out, p0); out += out_stride; + vst1_u8(out, p1); out += out_stride; + vst1_u8(out, p2); out += out_stride; + vst1_u8(out, p3); out += out_stride; + vst1_u8(out, p4); out += out_stride; + vst1_u8(out, p5); out += out_stride; + vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif // STBI_NEON + +#define STBI__MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static stbi_uc stbi__get_marker(stbi__jpeg *j) +{ + stbi_uc x; + if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } + x = stbi__get8(j->s); + if (x != 0xff) return STBI__MARKER_none; + while (x == 0xff) + x = stbi__get8(j->s); + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, stbi__jpeg_reset the entropy decoder and +// the dc prediction +static void stbi__jpeg_reset(stbi__jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->marker = STBI__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int stbi__parse_entropy_coded_data(stbi__jpeg *z) +{ + stbi__jpeg_reset(z); + if (!z->progressive) { + if (z->scan_n == 1) { + int i,j; + STBI_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + STBI_SIMD_ALIGN(short, data[64]); + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } else { + if (z->scan_n == 1) { + int i,j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) { + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } else { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x); + int y2 = (j*z->img_comp[n].v + y); + short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void stbi__jpeg_dequantize(short *data, stbi_uc *dequant) +{ + int i; + for (i=0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void stbi__jpeg_finish(stbi__jpeg *z) +{ + if (z->progressive) { + // dequantize and idct the data + int i,j,n; + for (n=0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int stbi__process_marker(stbi__jpeg *z, int m) +{ + int L; + switch (m) { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker","Corrupt JPEG"); + + case 0xDD: // DRI - specify restart interval + if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s)-2; + while (L > 0) { + int q = stbi__get8(z->s); + int p = q >> 4; + int t = q & 15,i; + if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG"); + if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + for (i=0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s); + L -= 65; + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s)-2; + while (L > 0) { + stbi_uc *v; + int sizes[16],i,n=0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < n; ++i) + v[i] = stbi__get8(z->s); + if (tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L==0; + } + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + stbi__skip(z->s, stbi__get16be(z->s)-2); + return 1; + } + return 0; +} + +// after we see SOS +static int stbi__process_scan_header(stbi__jpeg *z) +{ + int i; + int Ls = stbi__get16be(z->s); + z->scan_n = stbi__get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = stbi__get8(z->s), which; + int q = stbi__get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; // no match + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = stbi__get8(z->s); + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + aa = stbi__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if (z->progressive) { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } else { + if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int stbi__process_frame_header(stbi__jpeg *z, int scan) +{ + stbi__context *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG + p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires + c = stbi__get8(s); + if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG"); // JFIF requires + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); + + z->rgb = 0; + for (i=0; i < s->img_n; ++i) { + static unsigned char rgb[3] = { 'R', 'G', 'B' }; + z->img_comp[i].id = stbi__get8(s); + if (z->img_comp[i].id != i+1) // JFIF requires + if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files! + // somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format) + if (z->img_comp[i].id != rgb[i]) + return stbi__err("bad component ID","Corrupt JPEG"); + ++z->rgb; + } + q = stbi__get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); + } + + if (scan != STBI__SCAN_load) return 1; + + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].raw_data = stbi__malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); + + if (z->img_comp[i].raw_data == NULL) { + for(--i; i >= 0; --i) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + } + return stbi__err("outofmem", "Out of memory"); + } + // align blocks for idct using mmx/sse + z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + z->img_comp[i].linebuf = NULL; + if (z->progressive) { + z->img_comp[i].coeff_w = (z->img_comp[i].w2 + 7) >> 3; + z->img_comp[i].coeff_h = (z->img_comp[i].h2 + 7) >> 3; + z->img_comp[i].raw_coeff = STBI_MALLOC(z->img_comp[i].coeff_w * z->img_comp[i].coeff_h * 64 * sizeof(short) + 15); + z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } else { + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + } + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) + +#define stbi__SOF_progressive(x) ((x) == 0xc2) + +static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) +{ + int m; + z->marker = STBI__MARKER_none; // initialize cached marker to empty + m = stbi__get_marker(z); + if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); + if (scan == STBI__SCAN_type) return 1; + m = stbi__get_marker(z); + while (!stbi__SOF(m)) { + if (!stbi__process_marker(z,m)) return 0; + m = stbi__get_marker(z); + while (m == STBI__MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + m = stbi__get_marker(z); + } + } + z->progressive = stbi__SOF_progressive(m); + if (!stbi__process_frame_header(z, scan)) return 0; + return 1; +} + +// decode image to YCbCr format +static int stbi__decode_jpeg_image(stbi__jpeg *j) +{ + int m; + for (m = 0; m < 4; m++) { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + m = stbi__get_marker(j); + while (!stbi__EOI(m)) { + if (stbi__SOS(m)) { + if (!stbi__process_scan_header(j)) return 0; + if (!stbi__parse_entropy_coded_data(j)) return 0; + if (j->marker == STBI__MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!stbi__at_eof(j->s)) { + int x = stbi__get8(j->s); + if (x == 255) { + j->marker = stbi__get8(j->s); + break; + } else if (x != 0) { + return stbi__err("junk before marker", "Corrupt JPEG"); + } + } + // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 + } + } else { + if (!stbi__process_marker(j, m)) return 0; + } + m = stbi__get_marker(j); + } + if (j->progressive) + stbi__jpeg_finish(j); + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, + int w, int hs); + +#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) + +static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + stbi_uc *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = stbi__div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = stbi__div4(n+input[i-1]); + out[i*2+1] = stbi__div4(n+input[i+1]); + } + out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) + +static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = stbi__div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i=0,t0,t1; + + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + // process groups of 8 pixels for as long as we can. + // note we can't handle the last pixel in a row in this loop + // because we need to handle the filter boundary conditions. + for (; i < ((w-1) & ~7); i += 8) { +#if defined(STBI_SSE2) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + // interleave even and odd pixels, then undo scaling. + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + // pack and write output + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *) (out + i*2), outv); +#elif defined(STBI_NEON) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + // undo scaling and round, then store with even/odd phases interleaved + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i*2, o); +#endif + + // "previous" value for next iter + t1 = 3*in_near[i+7] + in_far[i+7]; + } + + t0 = t1; + t1 = 3*in_near[i] + in_far[i]; + out[i*2] = stbi__div16(3*t1 + t0 + 8); + + for (++i; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} +#endif + +static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + STBI_NOTUSED(in_far); + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +#ifdef STBI_JPEG_OLD +// this is the same YCbCr-to-RGB calculation that stb_image has used +// historically before the algorithm changes in 1.49 +#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 16) + 32768; // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr*float2fixed(1.40200f); + g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); + b = y_fixed + cb*float2fixed(1.77200f); + r >>= 16; + g >>= 16; + b >>= 16; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#else +// this is a reduced-precision calculation of YCbCr-to-RGB introduced +// to make sure the code produces the same results in both SIMD and scalar +#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* float2fixed(1.40200f); + g = y_fixed + (cr*-float2fixed(0.71414f)) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) +{ + int i = 0; + +#ifdef STBI_SSE2 + // step == 3 is pretty ugly on the final interleave, and i'm not convinced + // it's useful in practice (you wouldn't use it for textures, for example). + // so just accelerate step == 4 case. + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); + __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); + __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); + __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); + __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); // alpha channel + + for (; i+7 < count; i += 8) { + // load + __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 + + // unpack to short (and left-shift cr, cb by 8) + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + // color transform + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + // descale + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + // back to byte, set up for transpose + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + // transpose to interleave channels + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + // store + _mm_storeu_si128((__m128i *) (out + 0), o0); + _mm_storeu_si128((__m128i *) (out + 16), o1); + out += 32; + } + } +#endif + +#ifdef STBI_NEON + // in this version, step=3 support would be easy to add. but is there demand? + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); + int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); + int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); + int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + + for (; i+7 < count; i += 8) { + // load + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + // expand to s16 + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + // color transform + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + // undo scaling, round, convert to byte + uint8x8x4_t o; + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + // store, interleaving r/g/b/a + vst4_u8(out, o); + out += 8*4; + } + } +#endif + + for (; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* float2fixed(1.40200f); + g = y_fixed + cr*-float2fixed(0.71414f) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +// set up the kernels +static void stbi__setup_jpeg(stbi__jpeg *j) +{ + j->idct_block_kernel = stbi__idct_block; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; + +#ifdef STBI_SSE2 + if (stbi__sse2_available()) { + j->idct_block_kernel = stbi__idct_simd; + #ifndef STBI_JPEG_OLD + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + #endif + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; + } +#endif + +#ifdef STBI_NEON + j->idct_block_kernel = stbi__idct_simd; + #ifndef STBI_JPEG_OLD + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + #endif + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; +#endif +} + +// clean up the temporary component buffers +static void stbi__cleanup_jpeg(stbi__jpeg *j) +{ + int i; + for (i=0; i < j->s->img_n; ++i) { + if (j->img_comp[i].raw_data) { + STBI_FREE(j->img_comp[i].raw_data); + j->img_comp[i].raw_data = NULL; + j->img_comp[i].data = NULL; + } + if (j->img_comp[i].raw_coeff) { + STBI_FREE(j->img_comp[i].raw_coeff); + j->img_comp[i].raw_coeff = 0; + j->img_comp[i].coeff = 0; + } + if (j->img_comp[i].linebuf) { + STBI_FREE(j->img_comp[i].linebuf); + j->img_comp[i].linebuf = NULL; + } + } +} + +typedef struct +{ + resample_row_func resample; + stbi_uc *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi__resample; + +static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n; + z->s->img_n = 0; // make stbi__cleanup_jpeg safe + + // validate req_comp + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + + // load a jpeg image from whichever source, but leave in YCbCr format + if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n; + + if (z->s->img_n == 3 && n < 3) + decode_n = 1; + else + decode_n = z->s->img_n; + + // resample and color-convert + { + int k; + unsigned int i,j; + stbi_uc *output; + stbi_uc *coutput[4]; + + stbi__resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; + else r->resample = stbi__resample_row_generic; + } + + // can't error after this so, this is safe + output = (stbi_uc *) stbi__malloc(n * z->s->img_x * z->s->img_y + 1); + if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + stbi_uc *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + stbi_uc *y = coutput[0]; + if (z->s->img_n == 3) { + if (z->rgb == 3) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = y[i]; + out[1] = coutput[1][i]; + out[2] = coutput[2][i]; + out[3] = 255; + out += n; + } + } else { + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + } + } + stbi__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n; // report original components, not output + return output; + } +} + +static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char* result; + stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + j->s = s; + stbi__setup_jpeg(j); + result = load_jpeg_image(j, x,y,comp,req_comp); + STBI_FREE(j); + return result; +} + +static int stbi__jpeg_test(stbi__context *s) +{ + int r; + stbi__jpeg j; + j.s = s; + stbi__setup_jpeg(&j); + r = stbi__decode_jpeg_header(&j, STBI__SCAN_type); + stbi__rewind(s); + return r; +} + +static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) +{ + if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { + stbi__rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n; + return 1; +} + +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) +{ + int result; + stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); + j->s = s; + result = stbi__jpeg_info_raw(j, x, y, comp); + STBI_FREE(j); + return result; +} +#endif + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +#ifndef STBI_NO_ZLIB + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + stbi__uint16 fast[1 << STBI__ZFAST_BITS]; + stbi__uint16 firstcode[16]; + int maxcode[17]; + stbi__uint16 firstsymbol[16]; + stbi_uc size[288]; + stbi__uint16 value[288]; +} stbi__zhuffman; + +stbi_inline static int stbi__bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int stbi__bit_reverse(int v, int bits) +{ + STBI_ASSERT(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return stbi__bitreverse16(v) >> (16-bits); +} + +static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 0, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + if (sizes[i] > (1 << i)) + return stbi__err("bad sizes", "Corrupt PNG"); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (stbi__uint16) code; + z->firstsymbol[i] = (stbi__uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); + z->size [c] = (stbi_uc ) s; + z->value[c] = (stbi__uint16) i; + if (s <= STBI__ZFAST_BITS) { + int j = stbi__bit_reverse(next_code[s],s); + while (j < (1 << STBI__ZFAST_BITS)) { + z->fast[j] = fastv; + j += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + stbi_uc *zbuffer, *zbuffer_end; + int num_bits; + stbi__uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + stbi__zhuffman z_length, z_distance; +} stbi__zbuf; + +stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) +{ + if (z->zbuffer >= z->zbuffer_end) return 0; + return *z->zbuffer++; +} + +static void stbi__fill_bits(stbi__zbuf *z) +{ + do { + STBI_ASSERT(z->code_buffer < (1U << z->num_bits)); + z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) stbi__fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s,k; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = stbi__bit_reverse(a->code_buffer, 16); + for (s=STBI__ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s == 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + STBI_ASSERT(z->size[b] == s); + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s; + if (a->num_bits < 16) stbi__fill_bits(a); + b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; + if (b) { + s = b >> 9; + a->code_buffer >>= s; + a->num_bits -= s; + return b & 511; + } + return stbi__zhuffman_decode_slowpath(a, z); +} + +static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes +{ + char *q; + int cur, limit, old_limit; + z->zout = zout; + if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); + cur = (int) (z->zout - z->zout_start); + limit = old_limit = (int) (z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + STBI_NOTUSED(old_limit); + if (q == NULL) return stbi__err("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static int stbi__zlength_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static int stbi__zlength_extra[31]= +{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + +static int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static int stbi__zdist_extra[32] = +{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static int stbi__parse_huffman_block(stbi__zbuf *a) +{ + char *zout = a->zout; + for(;;) { + int z = stbi__zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes + if (zout >= a->zout_end) { + if (!stbi__zexpand(a, zout, 1)) return 0; + zout = a->zout; + } + *zout++ = (char) z; + } else { + stbi_uc *p; + int len,dist; + if (z == 256) { + a->zout = zout; + return 1; + } + z -= 257; + len = stbi__zlength_base[z]; + if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + z = stbi__zhuffman_decode(a, &a->z_distance); + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); + dist = stbi__zdist_base[z]; + if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); + if (zout + len > a->zout_end) { + if (!stbi__zexpand(a, zout, len)) return 0; + zout = a->zout; + } + p = (stbi_uc *) (zout - dist); + if (dist == 1) { // run of one byte; common in images. + stbi_uc v = *p; + if (len) { do *zout++ = v; while (--len); } + } else { + if (len) { do *zout++ = *p++; while (--len); } + } + } + } +} + +static int stbi__compute_huffman_codes(stbi__zbuf *a) +{ + static stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + stbi__zhuffman z_codelength; + stbi_uc lencodes[286+32+137];//padding for maximum single op + stbi_uc codelength_sizes[19]; + int i,n; + + int hlit = stbi__zreceive(a,5) + 257; + int hdist = stbi__zreceive(a,5) + 1; + int hclen = stbi__zreceive(a,4) + 4; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = stbi__zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + } + if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < hlit + hdist) { + int c = stbi__zhuffman_decode(a, &z_codelength); + if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if (c < 16) + lencodes[n++] = (stbi_uc) c; + else if (c == 16) { + c = stbi__zreceive(a,2)+3; + memset(lencodes+n, lencodes[n-1], c); + n += c; + } else if (c == 17) { + c = stbi__zreceive(a,3)+3; + memset(lencodes+n, 0, c); + n += c; + } else { + STBI_ASSERT(c == 18); + c = stbi__zreceive(a,7)+11; + memset(lencodes+n, 0, c); + n += c; + } + } + if (n != hlit+hdist) return stbi__err("bad codelengths","Corrupt PNG"); + if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int stbi__parse_uncompressed_block(stbi__zbuf *a) +{ + stbi_uc header[4]; + int len,nlen,k; + if (a->num_bits & 7) + stbi__zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check + a->code_buffer >>= 8; + a->num_bits -= 8; + } + STBI_ASSERT(a->num_bits == 0); + // now fill header the normal way + while (k < 4) + header[k++] = stbi__zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!stbi__zexpand(a, a->zout, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int stbi__parse_zlib_header(stbi__zbuf *a) +{ + int cmf = stbi__zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = stbi__zget8(a); + if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +// @TODO: should statically initialize these for optimal thread safety +static stbi_uc stbi__zdefault_length[288], stbi__zdefault_distance[32]; +static void stbi__init_zdefaults(void) +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; + for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; + for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; + for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; + + for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; +} + +static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!stbi__parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = stbi__zreceive(a,1); + type = stbi__zreceive(a,2); + if (type == 0) { + if (!stbi__parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!stbi__zdefault_distance[31]) stbi__init_zdefaults(); + if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; + } else { + if (!stbi__compute_huffman_codes(a)) return 0; + } + if (!stbi__parse_huffman_block(a)) return 0; + } + } while (!final); + return 1; +} + +static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return stbi__parse_zlib(a, parse_header); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer+len; + if (stbi__do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} +#endif + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + +#ifndef STBI_NO_PNG +typedef struct +{ + stbi__uint32 length; + stbi__uint32 type; +} stbi__pngchunk; + +static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) +{ + stbi__pngchunk c; + c.length = stbi__get32be(s); + c.type = stbi__get32be(s); + return c; +} + +static int stbi__check_png_header(stbi__context *s) +{ + static stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi__context *s; + stbi_uc *idata, *expanded, *out; + int depth; +} stbi__png; + + +enum { + STBI__F_none=0, + STBI__F_sub=1, + STBI__F_up=2, + STBI__F_avg=3, + STBI__F_paeth=4, + // synthetic filters used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static stbi_uc first_row_filter[5] = +{ + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static int stbi__paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +static stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; + +// create the png data from post-deflated data +static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) +{ + int bytes = (depth == 16? 2 : 1); + stbi__context *s = a->s; + stbi__uint32 i,j,stride = x*out_n*bytes; + stbi__uint32 img_len, img_width_bytes; + int k; + int img_n = s->img_n; // copy it into a local for later + + int output_bytes = out_n*bytes; + int filter_bytes = img_n*bytes; + int width = x; + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); + a->out = (stbi_uc *) stbi__malloc(x * y * output_bytes); // extra bytes to write off the end into + if (!a->out) return stbi__err("outofmem", "Out of memory"); + + img_width_bytes = (((img_n * x * depth) + 7) >> 3); + img_len = (img_width_bytes + 1) * y; + if (s->img_x == x && s->img_y == y) { + if (raw_len != img_len) return stbi__err("not enough pixels","Corrupt PNG"); + } else { // interlaced: + if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + } + + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *prior = cur - stride; + int filter = *raw++; + + if (filter > 4) + return stbi__err("invalid filter","Corrupt PNG"); + + if (depth < 8) { + STBI_ASSERT(img_width_bytes <= x); + cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place + filter_bytes = 1; + width = img_width_bytes; + } + + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + + // handle first byte explicitly + for (k=0; k < filter_bytes; ++k) { + switch (filter) { + case STBI__F_none : cur[k] = raw[k]; break; + case STBI__F_sub : cur[k] = raw[k]; break; + case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; + case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; + case STBI__F_avg_first : cur[k] = raw[k]; break; + case STBI__F_paeth_first: cur[k] = raw[k]; break; + } + } + + if (depth == 8) { + if (img_n != out_n) + cur[img_n] = 255; // first pixel + raw += img_n; + cur += out_n; + prior += out_n; + } else if (depth == 16) { + if (img_n != out_n) { + cur[filter_bytes] = 255; // first pixel top byte + cur[filter_bytes+1] = 255; // first pixel bottom byte + } + raw += filter_bytes; + cur += output_bytes; + prior += output_bytes; + } else { + raw += 1; + cur += 1; + prior += 1; + } + + // this is a little gross, so that we don't switch per-pixel or per-component + if (depth < 8 || img_n == out_n) { + int nk = (width - 1)*filter_bytes; + #define CASE(f) \ + case f: \ + for (k=0; k < nk; ++k) + switch (filter) { + // "none" filter turns into a memcpy here; make that explicit. + case STBI__F_none: memcpy(cur, raw, nk); break; + CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); break; + CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); break; + CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); break; + CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); break; + CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); break; + } + #undef CASE + raw += nk; + } else { + STBI_ASSERT(img_n+1 == out_n); + #define CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ + for (k=0; k < filter_bytes; ++k) + switch (filter) { + CASE(STBI__F_none) cur[k] = raw[k]; break; + CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); break; + CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); break; + CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); break; + CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); break; + CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break; + } + #undef CASE + + // the loop above sets the high byte of the pixels' alpha, but for + // 16 bit png files we also need the low byte set. we'll do that here. + if (depth == 16) { + cur = a->out + stride*j; // start at the beginning of the row again + for (i=0; i < x; ++i,cur+=output_bytes) { + cur[filter_bytes+1] = 255; + } + } + } + } + + // we make a separate pass to expand bits to pixels; for performance, + // this could run two scanlines behind the above code, so it won't + // intefere with filtering but will still be in the cache. + if (depth < 8) { + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; + // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit + // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop + stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + + // note that the final byte might overshoot and write more data than desired. + // we can allocate enough data that this never writes out of memory, but it + // could also overwrite the next scanline. can it overwrite non-empty data + // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. + // so we need to explicitly clamp the final ones + + if (depth == 4) { + for (k=x*img_n; k >= 2; k-=2, ++in) { + *cur++ = scale * ((*in >> 4) ); + *cur++ = scale * ((*in ) & 0x0f); + } + if (k > 0) *cur++ = scale * ((*in >> 4) ); + } else if (depth == 2) { + for (k=x*img_n; k >= 4; k-=4, ++in) { + *cur++ = scale * ((*in >> 6) ); + *cur++ = scale * ((*in >> 4) & 0x03); + *cur++ = scale * ((*in >> 2) & 0x03); + *cur++ = scale * ((*in ) & 0x03); + } + if (k > 0) *cur++ = scale * ((*in >> 6) ); + if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); + if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); + } else if (depth == 1) { + for (k=x*img_n; k >= 8; k-=8, ++in) { + *cur++ = scale * ((*in >> 7) ); + *cur++ = scale * ((*in >> 6) & 0x01); + *cur++ = scale * ((*in >> 5) & 0x01); + *cur++ = scale * ((*in >> 4) & 0x01); + *cur++ = scale * ((*in >> 3) & 0x01); + *cur++ = scale * ((*in >> 2) & 0x01); + *cur++ = scale * ((*in >> 1) & 0x01); + *cur++ = scale * ((*in ) & 0x01); + } + if (k > 0) *cur++ = scale * ((*in >> 7) ); + if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); + if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); + if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); + if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); + if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); + if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); + } + if (img_n != out_n) { + int q; + // insert alpha = 255 + cur = a->out + stride*j; + if (img_n == 1) { + for (q=x-1; q >= 0; --q) { + cur[q*2+1] = 255; + cur[q*2+0] = cur[q]; + } + } else { + STBI_ASSERT(img_n == 3); + for (q=x-1; q >= 0; --q) { + cur[q*4+3] = 255; + cur[q*4+2] = cur[q*3+2]; + cur[q*4+1] = cur[q*3+1]; + cur[q*4+0] = cur[q*3+0]; + } + } + } + } + } else if (depth == 16) { + // force the image data from big-endian to platform-native. + // this is done in a separate pass due to the decoding relying + // on the data being untouched, but could probably be done + // per-line during decode if care is taken. + stbi_uc *cur = a->out; + stbi__uint16 *cur16 = (stbi__uint16*)cur; + + for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { + *cur16 = (cur[0] << 8) | cur[1]; + } + } + + return 1; +} + +static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) +{ + stbi_uc *final; + int p; + if (!interlaced) + return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); + + // de-interlacing + final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; + if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + STBI_FREE(final); + return 0; + } + for (j=0; j < y; ++j) { + for (i=0; i < x; ++i) { + int out_y = j*yspc[p]+yorig[p]; + int out_x = i*xspc[p]+xorig[p]; + memcpy(final + out_y*a->s->img_x*out_n + out_x*out_n, + a->out + (j*x+i)*out_n, out_n); + } + } + STBI_FREE(a->out); + image_data += img_len; + image_data_len -= img_len; + } + } + a->out = final; + + return 1; +} + +static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi__uint16 *p = (stbi__uint16*) z->out; + + // compute color-based transparency, assuming we've + // already got 65535 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 65535); + p += 2; + } + } else { + for (i = 0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) +{ + stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; + stbi_uc *p, *temp_out, *orig = a->out; + + p = (stbi_uc *) stbi__malloc(pixel_count * pal_img_n); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + STBI_FREE(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi__reduce_png(stbi__png *p) +{ + int i; + int img_len = p->s->img_x * p->s->img_y * p->s->img_out_n; + stbi_uc *reduced; + stbi__uint16 *orig = (stbi__uint16*)p->out; + + if (p->depth != 16) return 1; // don't need to do anything if not 16-bit data + + reduced = (stbi_uc *)stbi__malloc(img_len); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is a decent approx of 16->8 bit scaling + + p->out = reduced; + STBI_FREE(orig); + + return 1; +} + +static int stbi__unpremultiply_on_load = 0; +static int stbi__de_iphone_flag = 0; + +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag = flag_true_if_should_convert; +} + +static void stbi__de_iphone(stbi__png *z) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + STBI_ASSERT(s->img_out_n == 4); + if (stbi__unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + stbi_uc a = p[3]; + stbi_uc t = p[0]; + if (a) { + p[0] = p[2] * 255 / a; + p[1] = p[1] * 255 / a; + p[2] = t * 255 / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +#define STBI__PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) + +static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) +{ + stbi_uc palette[1024], pal_img_n=0; + stbi_uc has_trans=0, tc[3]; + stbi__uint16 tc16[3]; + stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, color=0, is_iphone=0; + stbi__context *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!stbi__check_png_header(s)) return 0; + + if (scan == STBI__SCAN_type) return 1; + + for (;;) { + stbi__pngchunk c = stbi__get_chunk_header(s); + switch (c.type) { + case STBI__PNG_TYPE('C','g','B','I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I','H','D','R'): { + int comp,filter; + if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); + s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); + comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); + filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); + interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + if (scan == STBI__SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case STBI__PNG_TYPE('P','L','T','E'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = stbi__get8(s); + palette[i*4+1] = stbi__get8(s); + palette[i*4+2] = stbi__get8(s); + palette[i*4+3] = 255; + } + break; + } + + case STBI__PNG_TYPE('t','R','N','S'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = stbi__get8(s); + } else { + if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); + if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); + has_trans = 1; + if (z->depth == 16) { + for (k = 0; k < s->img_n; ++k) tc16[k] = stbi__get16be(s); // copy the values as-is + } else { + for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I','D','A','T'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); + if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } + if ((int)(ioff + c.length) < (int)ioff) return 0; + if (ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case STBI__PNG_TYPE('I','E','N','D'): { + stbi__uint32 raw_len, bpl; + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (scan != STBI__SCAN_load) return 1; + if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); + if (z->expanded == NULL) return 0; // zlib should set error + STBI_FREE(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; + if (has_trans) { + if (z->depth == 16) { + if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; + } else { + if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; + } + } + if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } + STBI_FREE(z->expanded); z->expanded = NULL; + return 1; + } + + default: + // if critical, fail + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); + #endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; + } + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + } +} + +static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp) +{ + unsigned char *result=NULL; + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + if (p->depth == 16) { + if (!stbi__reduce_png(p)) { + return result; + } + } + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + result = stbi__convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + STBI_FREE(p->out); p->out = NULL; + STBI_FREE(p->expanded); p->expanded = NULL; + STBI_FREE(p->idata); p->idata = NULL; + + return result; +} + +static unsigned char *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__png p; + p.s = s; + return stbi__do_png(&p, x,y,comp,req_comp); +} + +static int stbi__png_test(stbi__context *s) +{ + int r; + r = stbi__check_png_header(s); + stbi__rewind(s); + return r; +} + +static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) +{ + if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { + stbi__rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__png p; + p.s = s; + return stbi__png_info_raw(&p, x, y, comp); +} +#endif + +// Microsoft/Windows BMP image + +#ifndef STBI_NO_BMP +static int stbi__bmp_test_raw(stbi__context *s) +{ + int r; + int sz; + if (stbi__get8(s) != 'B') return 0; + if (stbi__get8(s) != 'M') return 0; + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + stbi__get32le(s); // discard data offset + sz = stbi__get32le(s); + r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); + return r; +} + +static int stbi__bmp_test(stbi__context *s) +{ + int r = stbi__bmp_test_raw(s); + stbi__rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int stbi__high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) n += 16, z >>= 16; + if (z >= 0x00100) n += 8, z >>= 8; + if (z >= 0x00010) n += 4, z >>= 4; + if (z >= 0x00004) n += 2, z >>= 2; + if (z >= 0x00002) n += 1, z >>= 1; + return n; +} + +static int stbi__bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +static int stbi__shiftsigned(int v, int shift, int bits) +{ + int result; + int z=0; + + if (shift < 0) v <<= -shift; + else v >>= shift; + result = v; + + z = bits; + while (z < 8) { + result += v >> z; + z += bits; + } + return result; +} + +typedef struct +{ + int bpp, offset, hsz; + unsigned int mr,mg,mb,ma, all_a; +} stbi__bmp_data; + +static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) +{ + int hsz; + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + info->mr = info->mg = info->mb = info->ma = 0; + + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = stbi__get16le(s); + s->img_y = stbi__get16le(s); + } else { + s->img_x = stbi__get32le(s); + s->img_y = stbi__get32le(s); + } + if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + info->bpp = stbi__get16le(s); + if (info->bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit"); + if (hsz != 12) { + int compress = stbi__get32le(s); + if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + } + if (info->bpp == 16 || info->bpp == 32) { + if (compress == 0) { + if (info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } else { + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; + } + } else if (compress == 3) { + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + // not documented, but generated by photoshop and handled by mspaint + if (info->mr == info->mg && info->mg == info->mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else { + int i; + if (hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); + stbi__get32le(s); // discard color space + for (i=0; i < 12; ++i) + stbi__get32le(s); // discard color space parameters + if (hsz == 124) { + stbi__get32le(s); // discard rendering intent + stbi__get32le(s); // discard offset of profile data + stbi__get32le(s); // discard size of profile data + stbi__get32le(s); // discard reserved + } + } + } + return (void *) 1; +} + + +static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *out; + unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + stbi_uc pal[256][4]; + int psize=0,i,j,width; + int flip_vertically, pad, target; + stbi__bmp_data info; + + info.all_a = 255; + if (stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if (info.hsz == 12) { + if (info.bpp < 24) + psize = (info.offset - 14 - 24) / 3; + } else { + if (info.bpp < 16) + psize = (info.offset - 14 - info.hsz) >> 2; + } + + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + + out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + if (info.bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + if (info.hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if (info.bpp == 4) width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) width = s->img_x; + else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=stbi__get8(s),v2=0; + if (info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + stbi__skip(s, pad); + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + stbi__skip(s, info.offset - 14 - info.hsz); + if (info.bpp == 24) width = 3 * s->img_x; + else if (info.bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (info.bpp == 24) { + easy = 1; + } else if (info.bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + unsigned char a; + out[z+2] = stbi__get8(s); + out[z+1] = stbi__get8(s); + out[z+0] = stbi__get8(s); + z += 3; + a = (easy == 2 ? stbi__get8(s) : 255); + all_a |= a; + if (target == 4) out[z++] = a; + } + } else { + int bpp = info.bpp; + for (i=0; i < (int) s->img_x; ++i) { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + int a; + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); + a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); + all_a |= a; + if (target == 4) out[z++] = STBI__BYTECAST(a); + } + } + stbi__skip(s, pad); + } + } + + // if alpha channel is all 0s, replace with all 255s + if (target == 4 && all_a == 0) + for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) + out[i] = 255; + + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i], p1[i] = p2[i], p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} +#endif + +// Targa Truevision - TGA +// by Jonathan Dummer +#ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if(is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: return STBI_grey; + case 16: if(is_grey) return STBI_grey_alpha; + // else: fall-through + case 15: if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; + case 24: // fall-through + case 32: return bits_per_pixel/8; + default: return 0; + } +} + +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if( tga_colormap_type > 1 ) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if ( tga_colormap_type == 1 ) { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip image x and y origin + tga_colormap_bpp = sz; + } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s,9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if( tga_w < 1 ) { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if( tga_h < 1 ) { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if (tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if(!tga_comp) { + stbi__rewind(s); + return 0; + } + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context *s) +{ + int res = 0; + int sz, tga_color_type; + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if ( tga_color_type == 1 ) { // colormapped (paletted) image + if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + stbi__skip(s,4); // skip image x and y origin + } else { // "normal" image w/o colormap + if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s,9); // skip colormap specification and image x/y origin + } + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: + stbi__rewind(s); + return res; +} + +// read 16bit value and convert to 24bit RGB +void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +{ + stbi__uint16 px = stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (r * 255)/31; + out[1] = (g * 255)/31; + out[2] = (b * 255)/31; + + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. +} + +static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + // read in the TGA header stuff + int tga_offset = stbi__get8(s); + int tga_indexed = stbi__get8(s); + int tga_image_type = stbi__get8(s); + int tga_is_RLE = 0; + int tga_palette_start = stbi__get16le(s); + int tga_palette_len = stbi__get16le(s); + int tga_palette_bits = stbi__get8(s); + int tga_x_origin = stbi__get16le(s); + int tga_y_origin = stbi__get16le(s); + int tga_width = stbi__get16le(s); + int tga_height = stbi__get16le(s); + int tga_bits_per_pixel = stbi__get8(s); + int tga_comp, tga_rgb16=0; + int tga_inverted = stbi__get8(s); + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4]; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); + + // tga info + *x = tga_width; + *y = tga_height; + if (comp) *comp = tga_comp; + + tga_data = (unsigned char*)stbi__malloc( (size_t)tga_width * tga_height * tga_comp ); + if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + stbi__skip(s, tga_offset ); + + if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { + for (i=0; i < tga_height; ++i) { + int row = tga_inverted ? tga_height -i - 1 : i; + stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; + stbi__getn(s, tga_row, tga_width * tga_comp); + } + } else { + // do I need to load a palette? + if ( tga_indexed) + { + // any data to skip? (offset usually = 0) + stbi__skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp ); + if (!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if (tga_rgb16) { + stbi_uc *pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb); + for (i=0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, pal_entry); + pal_entry += tga_comp; + } + } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + } + // load the data + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = stbi__get8(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if ( pal_idx >= tga_palette_len ) { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_comp; + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else if(tga_rgb16) { + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); + } else { + // read in the data raw + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = stbi__get8(s); + } + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + + // copy data + for (j = 0; j < tga_comp; ++j) + tga_data[i*tga_comp+j] = raw_data[j]; + + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * tga_comp; + int index2 = (tga_height - 1 - j) * tga_width * tga_comp; + for (i = tga_width * tga_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + STBI_FREE( tga_palette ); + } + } + + // swap RGB - if the source data was RGB16, it already is in the right order + if (tga_comp >= 3 && !tga_rgb16) + { + unsigned char* tga_pixel = tga_data; + for (i=0; i < tga_width * tga_height; ++i) + { + unsigned char temp = tga_pixel[0]; + tga_pixel[0] = tga_pixel[2]; + tga_pixel[2] = temp; + tga_pixel += tga_comp; + } + } + + // convert to target component count + if (req_comp && req_comp != tga_comp) + tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); + + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + // OK, done + return tga_data; +} +#endif + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s) +{ + int r = (stbi__get32be(s) == 0x38425053); + stbi__rewind(s); + return r; +} + +static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + int pixelCount; + int channelCount, compression; + int channel, i, count, len; + int bitdepth; + int w,h; + stbi_uc *out; + + // Check identifier + if (stbi__get32be(s) != 0x38425053) // "8BPS" + return stbi__errpuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (stbi__get16be(s) != 1) + return stbi__errpuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + stbi__skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) + return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = stbi__get32be(s); + w = stbi__get32be(s); + + // Make sure the depth is 8 bits. + bitdepth = stbi__get16be(s); + if (bitdepth != 8 && bitdepth != 16) + return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (stbi__get16be(s) != 3) + return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + stbi__skip(s,stbi__get32be(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + stbi__skip(s, stbi__get32be(s) ); + + // Skip the reserved data. + stbi__skip(s, stbi__get32be(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = stbi__get16be(s); + if (compression > 1) + return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + + // Create the destination image. + out = (stbi_uc *) stbi__malloc(4 * w*h); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, + // which we're going to just skip. + stbi__skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++, p += 4) + *p = (channel == 3 ? 255 : 0); + } else { + // Read the RLE data. + count = 0; + while (count < pixelCount) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len ^= 0x0FF; + len += 2; + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out + channel; + if (channel >= channelCount) { + // Fill this channel with default data. + stbi_uc val = channel == 3 ? 255 : 0; + for (i = 0; i < pixelCount; i++, p += 4) + *p = val; + } else { + // Read the data. + if (bitdepth == 16) { + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } + } + } + } + + if (channelCount >= 4) { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + // remove weird white matte from PSD + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } + } + } + + if (req_comp && req_comp != 4) { + out = stbi__convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + if (comp) *comp = 4; + *y = h; + *x = w; + + return out; +} +#endif + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +#ifndef STBI_NO_PIC +static int stbi__pic_is4(stbi__context *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (stbi__get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int stbi__pic_test_core(stbi__context *s) +{ + int i; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + stbi__get8(s); + + if (!stbi__pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} stbi__pic_packet; + +static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); + dest[i]=stbi__get8(s); + } + } + + return dest; +} + +static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + stbi__pic_packet packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return stbi__errpuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + + act_comp |= packet->channel; + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return stbi__errpuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=stbi__get8(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (stbi_uc) left; + + if (!stbi__readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = stbi__get8(s), i; + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + + if (count==128) + count = stbi__get16be(s); + else + count -= 127; + if (count > left) + return stbi__errpuc("bad file","scanline overrun"); + + if (!stbi__readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return stbi__errpuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp) +{ + stbi_uc *result; + int i, x,y; + + for (i=0; i<92; ++i) + stbi__get8(s); + + x = stbi__get16be(s); + y = stbi__get16be(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); + if ((1 << 28) / x < y) return stbi__errpuc("too large", "Image too large to decode"); + + stbi__get32be(s); //skip `ratio' + stbi__get16be(s); //skip `fields' + stbi__get16be(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) stbi__malloc(x*y*4); + memset(result, 0xff, x*y*4); + + if (!stbi__pic_load_core(s,x,y,comp, result)) { + STBI_FREE(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=stbi__convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi__pic_test(stbi__context *s) +{ + int r = stbi__pic_test_core(s); + stbi__rewind(s); + return r; +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb + +#ifndef STBI_NO_GIF +typedef struct +{ + stbi__int16 prefix; + stbi_uc first; + stbi_uc suffix; +} stbi__gif_lzw; + +typedef struct +{ + int w,h; + stbi_uc *out, *old_out; // output buffer (always 4 components) + int flags, bgindex, ratio, transparent, eflags, delay; + stbi_uc pal[256][4]; + stbi_uc lpal[256][4]; + stbi__gif_lzw codes[4096]; + stbi_uc *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; +} stbi__gif; + +static int stbi__gif_test_raw(stbi__context *s) +{ + int sz; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + sz = stbi__get8(s); + if (sz != '9' && sz != '7') return 0; + if (stbi__get8(s) != 'a') return 0; + return 1; +} + +static int stbi__gif_test(stbi__context *s) +{ + int r = stbi__gif_test_raw(s); + stbi__rewind(s); + return r; +} + +static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + pal[i][3] = transp == i ? 0 : 255; + } +} + +static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) +{ + stbi_uc version; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return stbi__err("not GIF", "Corrupt GIF"); + + version = stbi__get8(s); + if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); + if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + + stbi__g_failure_reason = ""; + g->w = stbi__get16le(s); + g->h = stbi__get16le(s); + g->flags = stbi__get8(s); + g->bgindex = stbi__get8(s); + g->ratio = stbi__get8(s); + g->transparent = -1; + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + if (!stbi__gif_header(s, g, comp, 1)) { + STBI_FREE(g); + stbi__rewind( s ); + return 0; + } + if (x) *x = g->w; + if (y) *y = g->h; + STBI_FREE(g); + return 1; +} + +static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) +{ + stbi_uc *p, *c; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi__out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + p = &g->out[g->cur_x + g->cur_y]; + c = &g->color_table[g->codes[code].suffix * 4]; + + if (c[3] >= 128) { + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) +{ + stbi_uc lzw_cs; + stbi__int32 len, init_code; + stbi__uint32 first; + stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi__gif_lzw *p; + + lzw_cs = stbi__get8(s); + if (lzw_cs > 12) return NULL; + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (init_code = 0; init_code < clear; init_code++) { + g->codes[init_code].prefix = -1; + g->codes[init_code].first = (stbi_uc) init_code; + g->codes[init_code].suffix = (stbi_uc) init_code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = stbi__get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (stbi__int32) stbi__get8(s) << valid_bits; + valid_bits += 8; + } else { + stbi__int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + stbi__skip(s, len); + while ((len = stbi__get8(s)) > 0) + stbi__skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) return stbi__errpuc("no clear code", "Corrupt GIF"); + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 4096) return stbi__errpuc("too many codes", "Corrupt GIF"); + p->prefix = (stbi__int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + + stbi__out_gif_code(g, (stbi__uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +static void stbi__fill_gif_background(stbi__gif *g, int x0, int y0, int x1, int y1) +{ + int x, y; + stbi_uc *c = g->pal[g->bgindex]; + for (y = y0; y < y1; y += 4 * g->w) { + for (x = x0; x < x1; x += 4) { + stbi_uc *p = &g->out[y + x]; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = 0; + } + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp) +{ + int i; + stbi_uc *prev_out = 0; + + if (g->out == 0 && !stbi__gif_header(s, g, comp,0)) + return 0; // stbi__g_failure_reason set by stbi__gif_header + + prev_out = g->out; + g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); + if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); + + switch ((g->eflags & 0x1C) >> 2) { + case 0: // unspecified (also always used on 1st frame) + stbi__fill_gif_background(g, 0, 0, 4 * g->w, 4 * g->w * g->h); + break; + case 1: // do not dispose + if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); + g->old_out = prev_out; + break; + case 2: // dispose to background + if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); + stbi__fill_gif_background(g, g->start_x, g->start_y, g->max_x, g->max_y); + break; + case 3: // dispose to previous + if (g->old_out) { + for (i = g->start_y; i < g->max_y; i += 4 * g->w) + memcpy(&g->out[i + g->start_x], &g->old_out[i + g->start_x], g->max_x - g->start_x); + } + break; + } + + for (;;) { + switch (stbi__get8(s)) { + case 0x2C: /* Image Descriptor */ + { + int prev_trans = -1; + stbi__int32 x, y, w, h; + stbi_uc *o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + g->lflags = stbi__get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *) g->lpal; + } else if (g->flags & 0x80) { + if (g->transparent >= 0 && (g->eflags & 0x01)) { + prev_trans = g->pal[g->transparent][3]; + g->pal[g->transparent][3] = 0; + } + g->color_table = (stbi_uc *) g->pal; + } else + return stbi__errpuc("missing color table", "Corrupt GIF"); + + o = stbi__process_gif_raster(s, g); + if (o == NULL) return NULL; + + if (prev_trans != -1) + g->pal[g->transparent][3] = (stbi_uc) prev_trans; + + return o; + } + + case 0x21: // Comment Extension. + { + int len; + if (stbi__get8(s) == 0xF9) { // Graphic Control Extension. + len = stbi__get8(s); + if (len == 4) { + g->eflags = stbi__get8(s); + g->delay = stbi__get16le(s); + g->transparent = stbi__get8(s); + } else { + stbi__skip(s, len); + break; + } + } + while ((len = stbi__get8(s)) != 0) + stbi__skip(s, len); + break; + } + + case 0x3B: // gif stream termination code + return (stbi_uc *) s; // using '1' causes warning on some compilers + + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); + } + } + + STBI_NOTUSED(req_comp); +} + +static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *u = 0; + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + memset(g, 0, sizeof(*g)); + + u = stbi__gif_load_next(s, g, comp, req_comp); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + if (u) { + *x = g->w; + *y = g->h; + if (req_comp && req_comp != 4) + u = stbi__convert_format(u, 4, req_comp, g->w, g->h); + } + else if (g->out) + STBI_FREE(g->out); + STBI_FREE(g); + return u; +} + +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) +{ + return stbi__gif_info_raw(s,x,y,comp); +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int stbi__hdr_test_core(stbi__context *s) +{ + const char *signature = "#?RADIANCE\n"; + int i; + for (i=0; signature[i]; ++i) + if (stbi__get8(s) != signature[i]) + return 0; + return 1; +} + +static int stbi__hdr_test(stbi__context* s) +{ + int r = stbi__hdr_test_core(s); + stbi__rewind(s); + return r; +} + +#define STBI__HDR_BUFLEN 1024 +static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) stbi__get8(z); + + while (!stbi__at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == STBI__HDR_BUFLEN-1) { + // flush to end of line + while (!stbi__at_eof(z) && stbi__get8(z) != '\n') + ; + break; + } + c = (char) stbi__get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + + + // Check identifier + if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) + return stbi__errpf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = (int) strtol(token, NULL, 10); + + *x = width; + *y = height; + + if (comp) *comp = 3; + if (req_comp == 0) req_comp = 3; + + // Read data + hdr_data = (float *) stbi__malloc(height * width * req_comp * sizeof(float)); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + stbi__getn(s, rgbe, 4); + stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = stbi__get8(s); + c2 = stbi__get8(s); + len = stbi__get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + stbi_uc rgbe[4]; + rgbe[0] = (stbi_uc) c1; + rgbe[1] = (stbi_uc) c2; + rgbe[2] = (stbi_uc) len; + rgbe[3] = (stbi_uc) stbi__get8(s); + stbi__hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + STBI_FREE(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= stbi__get8(s); + if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4); + + for (k = 0; k < 4; ++k) { + i = 0; + while (i < width) { + count = stbi__get8(s); + if (count > 128) { + // Run + value = stbi__get8(s); + count -= 128; + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = stbi__get8(s); + } + } + } + for (i=0; i < width; ++i) + stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + STBI_FREE(scanline); + } + + return hdr_data; +} + +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + + if (stbi__hdr_test(s) == 0) { + stbi__rewind( s ); + return 0; + } + + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi__rewind( s ); + return 0; + } + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *y = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *x = (int) strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +#ifndef STBI_NO_BMP +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) +{ + void *p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + stbi__rewind( s ); + if (p == NULL) + return 0; + *x = s->img_x; + *y = s->img_y; + *comp = info.ma ? 4 : 3; + return 1; +} +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) +{ + int channelCount; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + *y = stbi__get32be(s); + *x = stbi__get32be(s); + if (stbi__get16be(s) != 8) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 3) { + stbi__rewind( s ); + return 0; + } + *comp = 4; + return 1; +} +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained; + stbi__pic_packet packets[10]; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 88); + + *x = stbi__get16be(s); + *y = stbi__get16be(s); + if (stbi__at_eof(s)) { + stbi__rewind( s); + return 0; + } + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi__rewind( s ); + return 0; + } + + stbi__skip(s, 8); + + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + act_comp |= packet->channel; + + if (stbi__at_eof(s)) { + stbi__rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi__rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} +#endif + +// ************************************************************************************************* +// Portable Gray Map and Portable Pixel Map loader +// by Ken Miller +// +// PGM: http://netpbm.sourceforge.net/doc/pgm.html +// PPM: http://netpbm.sourceforge.net/doc/ppm.html +// +// Known limitations: +// Does not support comments in the header section +// Does not support ASCII image data (formats P2 and P3) +// Does not support 16-bit-per-channel + +#ifndef STBI_NO_PNM + +static int stbi__pnm_test(stbi__context *s) +{ + char p, t; + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + return 1; +} + +static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *out; + if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) + return 0; + *x = s->img_x; + *y = s->img_y; + *comp = s->img_n; + + out = (stbi_uc *) stbi__malloc(s->img_n * s->img_x * s->img_y); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + stbi__getn(s, out, s->img_n * s->img_x * s->img_y); + + if (req_comp && req_comp != s->img_n) { + out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + return out; +} + +static int stbi__pnm_isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) +{ + for (;;) { + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if (stbi__at_eof(s) || *c != '#') + break; + + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) + *c = (char) stbi__get8(s); + } +} + +static int stbi__pnm_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static int stbi__pnm_getinteger(stbi__context *s, char *c) +{ + int value = 0; + + while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { + value = value*10 + (*c - '0'); + *c = (char) stbi__get8(s); + } + + return value; +} + +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) +{ + int maxv; + char c, p, t; + + stbi__rewind( s ); + + // Get identifier + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + + c = (char) stbi__get8(s); + stbi__pnm_skip_whitespace(s, &c); + + *x = stbi__pnm_getinteger(s, &c); // read width + stbi__pnm_skip_whitespace(s, &c); + + *y = stbi__pnm_getinteger(s, &c); // read height + stbi__pnm_skip_whitespace(s, &c); + + maxv = stbi__pnm_getinteger(s, &c); // read max value + + if (maxv > 255) + return stbi__err("max value > 255", "PPM image not 8-bit"); + else + return 1; +} +#endif + +static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNG + if (stbi__png_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_GIF + if (stbi__gif_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_BMP + if (stbi__bmp_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PIC + if (stbi__pic_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_info(s, x, y, comp)) return 1; + #endif + + // test tga last because it's a crappy test! + #ifndef STBI_NO_TGA + if (stbi__tga_info(s, x, y, comp)) + return 1; + #endif + return stbi__err("unknown image type", "Image not of any known type, or corrupt"); +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__info_main(&s,x,y,comp); +} + +#endif // STB_IMAGE_IMPLEMENTATION + +/* + revision history: + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) allocate large structures on the stack + remove white matting for transparent PSD + fix reported channel count for PNG & BMP + re-enable SSE2 in non-gcc 64-bit + support RGB-formatted JPEG + read 16-bit PNGs (only as 8-bit) + 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED + 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling + info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) fix compiler warnings + partial animated GIF support + limited 16-bpc PSD support + #ifdef unused functions + bug with < 92 byte PIC,PNM,HDR,TGA + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) extra corruption checking (mmozeiko) + stbi_set_flip_vertically_on_load (nguillemot) + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) + progressive JPEG (stb) + PGM/PPM support (Ken Miller) + STBI_MALLOC,STBI_REALLOC,STBI_FREE + GIF bugfix -- seemingly never worked + STBI_NO_*, STBI_ONLY_* + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) + optimize PNG (ryg) + fix bug in interlaced PNG with user-specified channel count (stb) + 1.46 (2014-08-26) + fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG + 1.45 (2014-08-16) + fix MSVC-ARM internal compiler error by wrapping malloc + 1.44 (2014-08-07) + various warning fixes from Ronny Chevalier + 1.43 (2014-07-15) + fix MSVC-only compiler problem in code changed in 1.42 + 1.42 (2014-07-09) + don't define _CRT_SECURE_NO_WARNINGS (affects user code) + fixes to stbi__cleanup_jpeg path + added STBI_ASSERT to avoid requiring assert.h + 1.41 (2014-06-25) + fix search&replace from 1.36 that messed up comments/error messages + 1.40 (2014-06-22) + fix gcc struct-initialization warning + 1.39 (2014-06-15) + fix to TGA optimization when req_comp != number of components in TGA; + fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) + add support for BMP version 5 (more ignored fields) + 1.38 (2014-06-06) + suppress MSVC warnings on integer casts truncating values + fix accidental rename of 'skip' field of I/O + 1.37 (2014-06-04) + remove duplicate typedef + 1.36 (2014-06-03) + convert to header file single-file library + if de-iphone isn't set, load iphone images color-swapped instead of returning NULL + 1.35 (2014-05-27) + various warnings + fix broken STBI_SIMD path + fix bug where stbi_load_from_file no longer left file pointer in correct place + fix broken non-easy path for 32-bit BMP (possibly never used) + TGA optimization by Arseny Kapoulkine + 1.34 (unknown) + use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-stbi_uc to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) + 1.21 fix use of 'stbi_uc' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 (2008-08-02) + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - stbi__convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 (2006-11-19) + first released version +*/ diff --git a/L10/src/tiny_obj_loader.h b/L10/src/tiny_obj_loader.h new file mode 100644 index 0000000..b975601 --- /dev/null +++ b/L10/src/tiny_obj_loader.h @@ -0,0 +1,1922 @@ +/* +The MIT License (MIT) + +Copyright (c) 2012-2016 Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// +// version 1.0.3 : Support parsing texture options(#85) +// version 1.0.2 : Improve parsing speed by about a factor of 2 for large +// files(#105) +// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104) +// version 1.0.0 : Change data structure. Change license from BSD to MIT. +// + +// +// Use this in *one* .cc +// #define TINYOBJLOADER_IMPLEMENTATION +// #include "tiny_obj_loader.h" +// + +#ifndef TINY_OBJ_LOADER_H_ +#define TINY_OBJ_LOADER_H_ + +#include +#include +#include + +namespace tinyobj { + +// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ... +// +// -blendu on | off # set horizontal texture blending +// (default on) +// -blendv on | off # set vertical texture blending +// (default on) +// -boost float_value # boost mip-map sharpness +// -mm base_value gain_value # modify texture map values (default +// 0 1) +// # base_value = brightness, +// gain_value = contrast +// -o u [v [w]] # Origin offset (default +// 0 0 0) +// -s u [v [w]] # Scale (default +// 1 1 1) +// -t u [v [w]] # Turbulence (default +// 0 0 0) +// -texres resolution # texture resolution to create +// -clamp on | off # only render texels in the clamped +// 0-1 range (default off) +// # When unclamped, textures are +// repeated across a surface, +// # when clamped, only texels which +// fall within the 0-1 +// # range are rendered. +// -bm mult_value # bump multiplier (for bump maps +// only) +// +// -imfchan r | g | b | m | l | z # specifies which channel of the file +// is used to +// # create a scalar or bump texture. +// r:red, g:green, +// # b:blue, m:matte, l:luminance, +// z:z-depth.. +// # (the default for bump is 'l' and +// for decal is 'm') +// bump -imfchan r bumpmap.tga # says to use the red channel of +// bumpmap.tga as the bumpmap +// +// For reflection maps... +// +// -type sphere # specifies a sphere for a "refl" +// reflection map +// -type cube_top | cube_bottom | # when using a cube map, the texture +// file for each +// cube_front | cube_back | # side of the cube is specified +// separately +// cube_left | cube_right + +typedef enum { + TEXTURE_TYPE_NONE, // default + TEXTURE_TYPE_SPHERE, + TEXTURE_TYPE_CUBE_TOP, + TEXTURE_TYPE_CUBE_BOTTOM, + TEXTURE_TYPE_CUBE_FRONT, + TEXTURE_TYPE_CUBE_BACK, + TEXTURE_TYPE_CUBE_LEFT, + TEXTURE_TYPE_CUBE_RIGHT +} texture_type_t; + +typedef struct { + texture_type_t type; // -type (default TEXTURE_TYPE_NONE) + float sharpness; // -boost (default 1.0?) + float brightness; // base_value in -mm option (default 0) + float contrast; // gain_value in -mm option (default 1) + float origin_offset[3]; // -o u [v [w]] (default 0 0 0) + float scale[3]; // -s u [v [w]] (default 1 1 1) + float turbulence[3]; // -t u [v [w]] (default 0 0 0) + // int texture_resolution; // -texres resolution (default = ?) TODO + bool clamp; // -clamp (default false) + char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm') + bool blendu; // -blendu (default on) + bool blendv; // -blendv (default on) + float bump_multiplier; // -bm (for bump maps only, default 1.0) +} texture_option_t; + +typedef struct { + std::string name; + + float ambient[3]; + float diffuse[3]; + float specular[3]; + float transmittance[3]; + float emission[3]; + float shininess; + float ior; // index of refraction + float dissolve; // 1 == opaque; 0 == fully transparent + // illumination model (see http://www.fileformat.info/format/material/) + int illum; + + int dummy; // Suppress padding warning. + + std::string ambient_texname; // map_Ka + std::string diffuse_texname; // map_Kd + std::string specular_texname; // map_Ks + std::string specular_highlight_texname; // map_Ns + std::string bump_texname; // map_bump, bump + std::string displacement_texname; // disp + std::string alpha_texname; // map_d + + texture_option_t ambient_texopt; + texture_option_t diffuse_texopt; + texture_option_t specular_texopt; + texture_option_t specular_highlight_texopt; + texture_option_t bump_texopt; + texture_option_t displacement_texopt; + texture_option_t alpha_texopt; + + // PBR extension + // http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr + float roughness; // [0, 1] default 0 + float metallic; // [0, 1] default 0 + float sheen; // [0, 1] default 0 + float clearcoat_thickness; // [0, 1] default 0 + float clearcoat_roughness; // [0, 1] default 0 + float anisotropy; // aniso. [0, 1] default 0 + float anisotropy_rotation; // anisor. [0, 1] default 0 + float pad0; + float pad1; + std::string roughness_texname; // map_Pr + std::string metallic_texname; // map_Pm + std::string sheen_texname; // map_Ps + std::string emissive_texname; // map_Ke + std::string normal_texname; // norm. For normal mapping. + + texture_option_t roughness_texopt; + texture_option_t metallic_texopt; + texture_option_t sheen_texopt; + texture_option_t emissive_texopt; + texture_option_t normal_texopt; + + int pad2; + + std::map unknown_parameter; +} material_t; + +typedef struct { + std::string name; + + std::vector intValues; + std::vector floatValues; + std::vector stringValues; +} tag_t; + +// Index struct to support different indices for vtx/normal/texcoord. +// -1 means not used. +typedef struct { + int vertex_index; + int normal_index; + int texcoord_index; +} index_t; + +typedef struct { + std::vector indices; + std::vector num_face_vertices; // The number of vertices per + // face. 3 = polygon, 4 = quad, + // ... Up to 255. + std::vector material_ids; // per-face material ID + std::vector tags; // SubD tag +} mesh_t; + +typedef struct { + std::string name; + mesh_t mesh; +} shape_t; + +// Vertex attributes +typedef struct { + std::vector vertices; // 'v' + std::vector normals; // 'vn' + std::vector texcoords; // 'vt' +} attrib_t; + +typedef struct callback_t_ { + // W is optional and set to 1 if there is no `w` item in `v` line + void (*vertex_cb)(void *user_data, float x, float y, float z, float w); + void (*normal_cb)(void *user_data, float x, float y, float z); + + // y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in + // `vt` line. + void (*texcoord_cb)(void *user_data, float x, float y, float z); + + // called per 'f' line. num_indices is the number of face indices(e.g. 3 for + // triangle, 4 for quad) + // 0 will be passed for undefined index in index_t members. + void (*index_cb)(void *user_data, index_t *indices, int num_indices); + // `name` material name, `material_id` = the array index of material_t[]. -1 + // if + // a material not found in .mtl + void (*usemtl_cb)(void *user_data, const char *name, int material_id); + // `materials` = parsed material data. + void (*mtllib_cb)(void *user_data, const material_t *materials, + int num_materials); + // There may be multiple group names + void (*group_cb)(void *user_data, const char **names, int num_names); + void (*object_cb)(void *user_data, const char *name); + + callback_t_() + : vertex_cb(NULL), + normal_cb(NULL), + texcoord_cb(NULL), + index_cb(NULL), + usemtl_cb(NULL), + mtllib_cb(NULL), + group_cb(NULL), + object_cb(NULL) {} +} callback_t; + +class MaterialReader { + public: + MaterialReader() {} + virtual ~MaterialReader(); + + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) = 0; +}; + +class MaterialFileReader : public MaterialReader { + public: + explicit MaterialFileReader(const std::string &mtl_basedir) + : m_mtlBaseDir(mtl_basedir) {} + virtual ~MaterialFileReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *err); + + private: + std::string m_mtlBaseDir; +}; + +class MaterialStreamReader : public MaterialReader { + public: + explicit MaterialStreamReader(std::istream &inStream) + : m_inStream(inStream) {} + virtual ~MaterialStreamReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *err); + + private: + std::istream &m_inStream; +}; + +/// Loads .obj from a file. +/// 'attrib', 'shapes' and 'materials' will be filled with parsed shape data +/// 'shapes' will be filled with parsed shape data +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +/// 'mtl_basedir' is optional, and used for base directory for .mtl file. +/// In default(`NULL'), .mtl file is searched from an application's working directory. +/// 'triangulate' is optional, and used whether triangulate polygon face in .obj +/// or not. +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + const char *filename, const char *mtl_basedir = NULL, + bool triangulate = true); + +/// Loads .obj from a file with custom user callback. +/// .mtl is loaded as usual and parsed material_t data will be passed to +/// `callback.mtllib_cb`. +/// Returns true when loading .obj/.mtl become success. +/// Returns warning and error message into `err` +/// See `examples/callback_api/` for how to use this function. +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data = NULL, + MaterialReader *readMatFn = NULL, + std::string *err = NULL); + +/// Loads object from a std::istream, uses GetMtlIStreamFn to retrieve +/// std::istream for materials. +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + std::istream *inStream, MaterialReader *readMatFn = NULL, + bool triangulate = true); + +/// Loads materials into std::map +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream); + +} // namespace tinyobj + +#ifdef TINYOBJLOADER_IMPLEMENTATION +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace tinyobj { + +MaterialReader::~MaterialReader() {} + +#define TINYOBJ_SSCANF_BUFFER_SIZE (4096) + +struct vertex_index { + int v_idx, vt_idx, vn_idx; + vertex_index() : v_idx(-1), vt_idx(-1), vn_idx(-1) {} + explicit vertex_index(int idx) : v_idx(idx), vt_idx(idx), vn_idx(idx) {} + vertex_index(int vidx, int vtidx, int vnidx) + : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {} +}; + +struct tag_sizes { + tag_sizes() : num_ints(0), num_floats(0), num_strings(0) {} + int num_ints; + int num_floats; + int num_strings; +}; + +struct obj_shape { + std::vector v; + std::vector vn; + std::vector vt; +}; + +// See +// http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf +static std::istream &safeGetline(std::istream &is, std::string &t) { + t.clear(); + + // The characters in the stream are read one-by-one using a std::streambuf. + // That is faster than reading them one-by-one using the std::istream. + // Code that uses streambuf this way must be guarded by a sentry object. + // The sentry object performs various tasks, + // such as thread synchronization and updating the stream state. + + std::istream::sentry se(is, true); + std::streambuf *sb = is.rdbuf(); + + for (;;) { + int c = sb->sbumpc(); + switch (c) { + case '\n': + return is; + case '\r': + if (sb->sgetc() == '\n') sb->sbumpc(); + return is; + case EOF: + // Also handle the case when the last line has no line ending + if (t.empty()) is.setstate(std::ios::eofbit); + return is; + default: + t += static_cast(c); + } + } +} + +#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t')) +#define IS_DIGIT(x) \ + (static_cast((x) - '0') < static_cast(10)) +#define IS_NEW_LINE(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0')) + +// Make index zero-base, and also support relative index. +static inline int fixIndex(int idx, int n) { + if (idx > 0) return idx - 1; + if (idx == 0) return 0; + return n + idx; // negative value = relative +} + +static inline std::string parseString(const char **token) { + std::string s; + (*token) += strspn((*token), " \t"); + size_t e = strcspn((*token), " \t\r"); + s = std::string((*token), &(*token)[e]); + (*token) += e; + return s; +} + +static inline int parseInt(const char **token) { + (*token) += strspn((*token), " \t"); + int i = atoi((*token)); + (*token) += strcspn((*token), " \t\r"); + return i; +} + +// Tries to parse a floating point number located at s. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// Parses the following EBNF grammar: +// sign = "+" | "-" ; +// END = ? anything not in digit ? +// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +// integer = [sign] , digit , {digit} ; +// decimal = integer , ["." , integer] ; +// float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ; +// +// Valid strings are for example: +// -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2 +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +// The function is greedy and will parse until any of the following happens: +// - a non-conforming character is encountered. +// - s_end is reached. +// +// The following situations triggers a failure: +// - s >= s_end. +// - parse failure. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (s >= s_end) { + return false; + } + + double mantissa = 0.0; + // This exponent is base 2 rather than 10. + // However the exponent we parse is supposed to be one of ten, + // thus we must take care to convert the exponent/and or the + // mantissa to a * 2^E, where a is the mantissa and E is the + // exponent. + // To get the final double we will use ldexp, it requires the + // exponent to be in base 2. + int exponent = 0; + + // NOTE: THESE MUST BE DECLARED HERE SINCE WE ARE NOT ALLOWED + // TO JUMP OVER DEFINITIONS. + char sign = '+'; + char exp_sign = '+'; + char const *curr = s; + + // How many characters were read in a loop. + int read = 0; + // Tells whether a loop terminated due to reaching s_end. + bool end_not_reached = false; + + /* + BEGIN PARSING. + */ + + // Find out what sign we've got. + if (*curr == '+' || *curr == '-') { + sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + goto fail; + } + + // Read the integer part. + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + mantissa *= 10; + mantissa += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + + // We must make sure we actually got something. + if (read == 0) goto fail; + // We allow numbers of form "#", "###" etc. + if (!end_not_reached) goto assemble; + + // Read the decimal part. + if (*curr == '.') { + curr++; + read = 1; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + static const double pow_lut[] = { + 1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, + }; + const int lut_entries = sizeof pow_lut / sizeof pow_lut[0]; + + // NOTE: Don't use powf here, it will absolutely murder precision. + mantissa += static_cast(*curr - 0x30) * + (read < lut_entries ? pow_lut[read] : pow(10.0, -read)); + read++; + curr++; + end_not_reached = (curr != s_end); + } + } else if (*curr == 'e' || *curr == 'E') { + } else { + goto assemble; + } + + if (!end_not_reached) goto assemble; + + // Read the exponent part. + if (*curr == 'e' || *curr == 'E') { + curr++; + // Figure out if a sign is present and if it is. + end_not_reached = (curr != s_end); + if (end_not_reached && (*curr == '+' || *curr == '-')) { + exp_sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + // Empty E is not allowed. + goto fail; + } + + read = 0; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + exponent *= 10; + exponent += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + exponent *= (exp_sign == '+' ? 1 : -1); + if (read == 0) goto fail; + } + +assemble: + *result = + (sign == '+' ? 1 : -1) * + (exponent ? ldexp(mantissa * pow(5.0, exponent), exponent) : mantissa); + return true; +fail: + return false; +} + +static inline float parseFloat(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + float f = static_cast(val); + (*token) = end; + return f; +} + +static inline void parseFloat2(float *x, float *y, const char **token, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = parseFloat(token, default_x); + (*y) = parseFloat(token, default_y); +} + +static inline void parseFloat3(float *x, float *y, float *z, const char **token, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseFloat(token, default_x); + (*y) = parseFloat(token, default_y); + (*z) = parseFloat(token, default_z); +} + +static inline void parseV(float *x, float *y, float *z, float *w, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0, + const double default_w = 1.0) { + (*x) = parseFloat(token, default_x); + (*y) = parseFloat(token, default_y); + (*z) = parseFloat(token, default_z); + (*w) = parseFloat(token, default_w); +} + +static inline bool parseOnOff(const char **token, bool default_value = true) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + + bool ret = default_value; + if ((0 == strncmp((*token), "on", 2))) { + ret = true; + } else if ((0 == strncmp((*token), "off", 3))) { + ret = false; + } + + (*token) = end; + return ret; +} + +static inline texture_type_t parseTextureType( + const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + texture_type_t ty = default_value; + + if ((0 == strncmp((*token), "cube_top", strlen("cube_top")))) { + ty = TEXTURE_TYPE_CUBE_TOP; + } else if ((0 == strncmp((*token), "cube_bottom", strlen("cube_bottom")))) { + ty = TEXTURE_TYPE_CUBE_BOTTOM; + } else if ((0 == strncmp((*token), "cube_left", strlen("cube_left")))) { + ty = TEXTURE_TYPE_CUBE_LEFT; + } else if ((0 == strncmp((*token), "cube_right", strlen("cube_right")))) { + ty = TEXTURE_TYPE_CUBE_RIGHT; + } else if ((0 == strncmp((*token), "cube_front", strlen("cube_front")))) { + ty = TEXTURE_TYPE_CUBE_FRONT; + } else if ((0 == strncmp((*token), "cube_back", strlen("cube_back")))) { + ty = TEXTURE_TYPE_CUBE_BACK; + } else if ((0 == strncmp((*token), "sphere", strlen("sphere")))) { + ty = TEXTURE_TYPE_SPHERE; + } + + (*token) = end; + return ty; +} + +static tag_sizes parseTagTriple(const char **token) { + tag_sizes ts; + + ts.num_ints = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; + + ts.num_floats = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; + + ts.num_strings = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r") + 1; + + return ts; +} + +// Parse triples with index offsets: i, i/j/k, i//k, i/j +static vertex_index parseTriple(const char **token, int vsize, int vnsize, + int vtsize) { + vertex_index vi(-1); + + vi.v_idx = fixIndex(atoi((*token)), vsize); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = fixIndex(atoi((*token)), vnsize); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = fixIndex(atoi((*token)), vtsize); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = fixIndex(atoi((*token)), vnsize); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +// Parse raw triples: i, i/j/k, i//k, i/j +static vertex_index parseRawTriple(const char **token) { + vertex_index vi(static_cast(0)); // 0 is an invalid index in OBJ + + vi.v_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +static bool ParseTextureNameAndOption(std::string *texname, + texture_option_t *texopt, + const char *linebuf, const bool is_bump) { + // @todo { write more robust lexer and parser. } + bool found_texname = false; + std::string texture_name; + + // Fill with default value for texopt. + if (is_bump) { + texopt->imfchan = 'l'; + } else { + texopt->imfchan = 'm'; + } + texopt->bump_multiplier = 1.0f; + texopt->clamp = false; + texopt->blendu = true; + texopt->blendv = true; + texopt->sharpness = 1.0f; + texopt->brightness = 0.0f; + texopt->contrast = 1.0f; + texopt->origin_offset[0] = 0.0f; + texopt->origin_offset[1] = 0.0f; + texopt->origin_offset[2] = 0.0f; + texopt->scale[0] = 1.0f; + texopt->scale[1] = 1.0f; + texopt->scale[2] = 1.0f; + texopt->turbulence[0] = 0.0f; + texopt->turbulence[1] = 0.0f; + texopt->turbulence[2] = 0.0f; + texopt->type = TEXTURE_TYPE_NONE; + + const char *token = linebuf; // Assume line ends with NULL + + while (!IS_NEW_LINE((*token))) { + if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendu = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendv = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->clamp = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->sharpness = parseFloat(&token, 1.0); + } else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) { + token += 4; + texopt->bump_multiplier = parseFloat(&token, 1.0); + } else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseFloat3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]), + &(texopt->origin_offset[2]), &token); + } else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseFloat3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]), + &token, 1.0, 1.0, 1.0); + } else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseFloat3(&(texopt->turbulence[0]), &(texopt->turbulence[1]), + &(texopt->turbulence[2]), &token); + } else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) { + token += 5; + texopt->type = parseTextureType((&token), TEXTURE_TYPE_NONE); + } else if ((0 == strncmp(token, "-imfchan", 8)) && IS_SPACE((token[8]))) { + token += 9; + token += strspn(token, " \t"); + const char *end = token + strcspn(token, " \t\r"); + if ((end - token) == 1) { // Assume one char for -imfchan + texopt->imfchan = (*token); + } + token = end; + } else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) { + token += 4; + parseFloat2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0); + } else { + // Assume texture filename + token += strspn(token, " \t"); // skip space + size_t len = strcspn(token, " \t\r"); // untile next space + texture_name = std::string(token, token + len); + token += len; + + token += strspn(token, " \t"); // skip space + + found_texname = true; + } + } + + if (found_texname) { + (*texname) = texture_name; + return true; + } else { + return false; + } +} + +static void InitMaterial(material_t *material) { + material->name = ""; + material->ambient_texname = ""; + material->diffuse_texname = ""; + material->specular_texname = ""; + material->specular_highlight_texname = ""; + material->bump_texname = ""; + material->displacement_texname = ""; + material->alpha_texname = ""; + for (int i = 0; i < 3; i++) { + material->ambient[i] = 0.f; + material->diffuse[i] = 0.f; + material->specular[i] = 0.f; + material->transmittance[i] = 0.f; + material->emission[i] = 0.f; + } + material->illum = 0; + material->dissolve = 1.f; + material->shininess = 1.f; + material->ior = 1.f; + + material->roughness = 0.f; + material->metallic = 0.f; + material->sheen = 0.f; + material->clearcoat_thickness = 0.f; + material->clearcoat_roughness = 0.f; + material->anisotropy_rotation = 0.f; + material->anisotropy = 0.f; + material->roughness_texname = ""; + material->metallic_texname = ""; + material->sheen_texname = ""; + material->emissive_texname = ""; + material->normal_texname = ""; + + material->unknown_parameter.clear(); +} + +static bool exportFaceGroupToShape( + shape_t *shape, const std::vector > &faceGroup, + const std::vector &tags, const int material_id, + const std::string &name, bool triangulate) { + if (faceGroup.empty()) { + return false; + } + + // Flatten vertices and indices + for (size_t i = 0; i < faceGroup.size(); i++) { + const std::vector &face = faceGroup[i]; + + vertex_index i0 = face[0]; + vertex_index i1(-1); + vertex_index i2 = face[1]; + + size_t npolys = face.size(); + + if (triangulate) { + // Polygon -> triangle fan conversion + for (size_t k = 2; k < npolys; k++) { + i1 = i2; + i2 = face[k]; + + index_t idx0, idx1, idx2; + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + } + } else { + for (size_t k = 0; k < npolys; k++) { + index_t idx; + idx.vertex_index = face[k].v_idx; + idx.normal_index = face[k].vn_idx; + idx.texcoord_index = face[k].vt_idx; + shape->mesh.indices.push_back(idx); + } + + shape->mesh.num_face_vertices.push_back( + static_cast(npolys)); + shape->mesh.material_ids.push_back(material_id); // per face + } + } + + shape->name = name; + shape->mesh.tags = tags; + + return true; +} + +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream) { + // Create a default material anyway. + material_t material; + InitMaterial(&material); + + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + // Trim trailing whitespace. + if (linebuf.size() > 0) { + linebuf = linebuf.substr(0, linebuf.find_last_not_of(" \t") + 1); + } + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // new mtl + if ((0 == strncmp(token, "newmtl", 6)) && IS_SPACE((token[6]))) { + // flush previous material. + if (!material.name.empty()) { + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + } + + // initial temporary material + InitMaterial(&material); + + // set new mtl name + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + material.name = namebuf; + continue; + } + + // ambient + if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.ambient[0] = r; + material.ambient[1] = g; + material.ambient[2] = b; + continue; + } + + // diffuse + if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.diffuse[0] = r; + material.diffuse[1] = g; + material.diffuse[2] = b; + continue; + } + + // specular + if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.specular[0] = r; + material.specular[1] = g; + material.specular[2] = b; + continue; + } + + // transmittance + if ((token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) || + (token[0] == 'T' && token[1] == 'f' && IS_SPACE((token[2])))) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.transmittance[0] = r; + material.transmittance[1] = g; + material.transmittance[2] = b; + continue; + } + + // ior(index of refraction) + if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) { + token += 2; + material.ior = parseFloat(&token); + continue; + } + + // emission + if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) { + token += 2; + float r, g, b; + parseFloat3(&r, &g, &b, &token); + material.emission[0] = r; + material.emission[1] = g; + material.emission[2] = b; + continue; + } + + // shininess + if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.shininess = parseFloat(&token); + continue; + } + + // illum model + if (0 == strncmp(token, "illum", 5) && IS_SPACE(token[5])) { + token += 6; + material.illum = parseInt(&token); + continue; + } + + // dissolve + if ((token[0] == 'd' && IS_SPACE(token[1]))) { + token += 1; + material.dissolve = parseFloat(&token); + continue; + } + if (token[0] == 'T' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + // Invert value of Tr(assume Tr is in range [0, 1]) + material.dissolve = 1.0f - parseFloat(&token); + continue; + } + + // PBR: roughness + if (token[0] == 'P' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + material.roughness = parseFloat(&token); + continue; + } + + // PBR: metallic + if (token[0] == 'P' && token[1] == 'm' && IS_SPACE(token[2])) { + token += 2; + material.metallic = parseFloat(&token); + continue; + } + + // PBR: sheen + if (token[0] == 'P' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.sheen = parseFloat(&token); + continue; + } + + // PBR: clearcoat thickness + if (token[0] == 'P' && token[1] == 'c' && IS_SPACE(token[2])) { + token += 2; + material.clearcoat_thickness = parseFloat(&token); + continue; + } + + // PBR: clearcoat roughness + if ((0 == strncmp(token, "Pcr", 3)) && IS_SPACE(token[3])) { + token += 4; + material.clearcoat_roughness = parseFloat(&token); + continue; + } + + // PBR: anisotropy + if ((0 == strncmp(token, "aniso", 5)) && IS_SPACE(token[5])) { + token += 6; + material.anisotropy = parseFloat(&token); + continue; + } + + // PBR: anisotropy rotation + if ((0 == strncmp(token, "anisor", 6)) && IS_SPACE(token[6])) { + token += 7; + material.anisotropy_rotation = parseFloat(&token); + continue; + } + + // ambient texture + if ((0 == strncmp(token, "map_Ka", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.ambient_texname), + &(material.ambient_texopt), token, + /* is_bump */ false); + continue; + } + + // diffuse texture + if ((0 == strncmp(token, "map_Kd", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.diffuse_texname), + &(material.diffuse_texopt), token, + /* is_bump */ false); + continue; + } + + // specular texture + if ((0 == strncmp(token, "map_Ks", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_texname), + &(material.specular_texopt), token, + /* is_bump */ false); + continue; + } + + // specular highlight texture + if ((0 == strncmp(token, "map_Ns", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_highlight_texname), + &(material.specular_highlight_texopt), token, + /* is_bump */ false); + continue; + } + + // bump texture + if ((0 == strncmp(token, "map_bump", 8)) && IS_SPACE(token[8])) { + token += 9; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // bump texture + if ((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // alpha texture + if ((0 == strncmp(token, "map_d", 5)) && IS_SPACE(token[5])) { + token += 6; + material.alpha_texname = token; + ParseTextureNameAndOption(&(material.alpha_texname), + &(material.alpha_texopt), token, + /* is_bump */ false); + continue; + } + + // displacement texture + if ((0 == strncmp(token, "disp", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: roughness texture + if ((0 == strncmp(token, "map_Pr", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.roughness_texname), + &(material.roughness_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: metallic texture + if ((0 == strncmp(token, "map_Pm", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.metallic_texname), + &(material.metallic_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: sheen texture + if ((0 == strncmp(token, "map_Ps", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.sheen_texname), + &(material.sheen_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: emissive texture + if ((0 == strncmp(token, "map_Ke", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.emissive_texname), + &(material.emissive_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: normal map texture + if ((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption( + &(material.normal_texname), &(material.normal_texopt), token, + /* is_bump */ false); // @fixme { is_bump will be true? } + continue; + } + + // unknown parameter + const char *_space = strchr(token, ' '); + if (!_space) { + _space = strchr(token, '\t'); + } + if (_space) { + std::ptrdiff_t len = _space - token; + std::string key(token, static_cast(len)); + std::string value = _space + 1; + material.unknown_parameter.insert( + std::pair(key, value)); + } + } + // flush last material. + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); +} + +bool MaterialFileReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) { + std::string filepath; + + if (!m_mtlBaseDir.empty()) { + filepath = std::string(m_mtlBaseDir) + matId; + } else { + filepath = matId; + } + + std::ifstream matIStream(filepath.c_str()); + LoadMtl(matMap, materials, &matIStream); + if (!matIStream) { + std::stringstream ss; + ss << "WARN: Material file [ " << filepath + << " ] not found. Created a default material."; + if (err) { + (*err) += ss.str(); + } + } + return true; +} + +bool MaterialStreamReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) { + (void)matId; + LoadMtl(matMap, materials, &m_inStream); + if (!m_inStream) { + std::stringstream ss; + ss << "WARN: Material stream in error state." + << " Created a default material."; + if (err) { + (*err) += ss.str(); + } + } + return true; +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + const char *filename, const char *mtl_basedir, + bool trianglulate) { + attrib->vertices.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + shapes->clear(); + + std::stringstream errss; + + std::ifstream ifs(filename); + if (!ifs) { + errss << "Cannot open file [" << filename << "]" << std::endl; + if (err) { + (*err) = errss.str(); + } + return false; + } + + std::string baseDir; + if (mtl_basedir) { + baseDir = mtl_basedir; + } + MaterialFileReader matFileReader(baseDir); + + return LoadObj(attrib, shapes, materials, err, &ifs, &matFileReader, + trianglulate); +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + std::istream *inStream, MaterialReader *readMatFn /*= NULL*/, + bool triangulate) { + std::stringstream errss; + + std::vector v; + std::vector vn; + std::vector vt; + std::vector tags; + std::vector > faceGroup; + std::string name; + + // material + std::map material_map; + int material = -1; + + shape_t shape; + + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + float x, y, z; + parseFloat3(&x, &y, &z, &token); + v.push_back(x); + v.push_back(y); + v.push_back(z); + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + float x, y, z; + parseFloat3(&x, &y, &z, &token); + vn.push_back(x); + vn.push_back(y); + vn.push_back(z); + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + float x, y; + parseFloat2(&x, &y, &token); + vt.push_back(x); + vt.push_back(y); + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + std::vector face; + face.reserve(3); + + while (!IS_NEW_LINE(token[0])) { + vertex_index vi = parseTriple(&token, static_cast(v.size() / 3), + static_cast(vn.size() / 3), + static_cast(vt.size() / 2)); + face.push_back(vi); + size_t n = strspn(token, " \t\r"); + token += n; + } + + // replace with emplace_back + std::move on C++11 + faceGroup.push_back(std::vector()); + faceGroup[faceGroup.size() - 1].swap(face); + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material) { + // Create per-face material. Thus we don't add `shape` to `shapes` at + // this time. + // just clear `faceGroup` after `exportFaceGroupToShape()` call. + exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + faceGroup.clear(); + material = newMaterialId; + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + + std::string err_mtl; + bool ok = (*readMatFn)(namebuf, materials, &material_map, &err_mtl); + if (err) { + (*err) += err_mtl; + } + + if (!ok) { + faceGroup.clear(); // for safety + return false; + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + if (ret) { + shapes->push_back(shape); + } + + shape = shape_t(); + + // material = -1; + faceGroup.clear(); + + std::vector names; + names.reserve(2); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + // names[0] must be 'g', so skip the 0th element. + if (names.size() > 1) { + name = names[1]; + } else { + name = ""; + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + if (ret) { + shapes->push_back(shape); + } + + // material = -1; + faceGroup.clear(); + shape = shape_t(); + + // @todo { multiple object name? } + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + name = std::string(namebuf); + + continue; + } + + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + char namebuf[4096]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + tag.name = std::string(namebuf); + + token += tag.name.size() + 1; + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = atoi(token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.floatValues.resize(static_cast(ts.num_floats)); + for (size_t i = 0; i < static_cast(ts.num_floats); ++i) { + tag.floatValues[i] = parseFloat(&token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + char stringValueBuffer[4096]; + +#ifdef _MSC_VER + sscanf_s(token, "%s", stringValueBuffer, + (unsigned)_countof(stringValueBuffer)); +#else + sscanf(token, "%s", stringValueBuffer); +#endif + tag.stringValues[i] = stringValueBuffer; + token += tag.stringValues[i].size() + 1; + } + + tags.push_back(tag); + } + + // Ignore unknown command. + } + + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate); + // exportFaceGroupToShape return false when `usemtl` is called in the last + // line. + // we also add `shape` to `shapes` when `shape.mesh` has already some + // faces(indices) + if (ret || shape.mesh.indices.size()) { + shapes->push_back(shape); + } + faceGroup.clear(); // for safety + + if (err) { + (*err) += errss.str(); + } + + attrib->vertices.swap(v); + attrib->normals.swap(vn); + attrib->texcoords.swap(vt); + + return true; +} + +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data /*= NULL*/, + MaterialReader *readMatFn /*= NULL*/, + std::string *err /*= NULL*/) { + std::stringstream errss; + + // material + std::map material_map; + int material_id = -1; // -1 = invalid + + std::vector indices; + std::vector materials; + std::vector names; + names.reserve(2); + std::string name; + std::vector names_out; + + std::string linebuf; + while (inStream.peek() != -1) { + safeGetline(inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + float x, y, z, w; // w is optional. default = 1.0 + parseV(&x, &y, &z, &w, &token); + if (callback.vertex_cb) { + callback.vertex_cb(user_data, x, y, z, w); + } + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + float x, y, z; + parseFloat3(&x, &y, &z, &token); + if (callback.normal_cb) { + callback.normal_cb(user_data, x, y, z); + } + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + float x, y, z; // y and z are optional. default = 0.0 + parseFloat3(&x, &y, &z, &token); + if (callback.texcoord_cb) { + callback.texcoord_cb(user_data, x, y, z); + } + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + indices.clear(); + while (!IS_NEW_LINE(token[0])) { + vertex_index vi = parseRawTriple(&token); + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + indices.push_back(idx); + size_t n = strspn(token, " \t\r"); + token += n; + } + + if (callback.index_cb && indices.size() > 0) { + callback.index_cb(user_data, &indices.at(0), + static_cast(indices.size())); + } + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, + static_cast(_countof(namebuf))); +#else + sscanf(token, "%s", namebuf); +#endif + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material_id) { + material_id = newMaterialId; + } + + if (callback.usemtl_cb) { + callback.usemtl_cb(user_data, namebuf, material_id); + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 7; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + + std::string err_mtl; + materials.clear(); + bool ok = (*readMatFn)(namebuf, &materials, &material_map, &err_mtl); + if (err) { + (*err) += err_mtl; + } + + if (!ok) { + return false; + } + + if (callback.mtllib_cb) { + callback.mtllib_cb(user_data, &materials.at(0), + static_cast(materials.size())); + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + names.clear(); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + // names[0] must be 'g', so skip the 0th element. + if (names.size() > 1) { + name = names[1]; + } else { + name.clear(); + } + + if (callback.group_cb) { + if (names.size() > 1) { + // create const char* array. + names_out.resize(names.size() - 1); + for (size_t j = 0; j < names_out.size(); j++) { + names_out[j] = names[j + 1].c_str(); + } + callback.group_cb(user_data, &names_out.at(0), + static_cast(names_out.size())); + + } else { + callback.group_cb(user_data, NULL, 0); + } + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // @todo { multiple object name? } + char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + std::string object_name = std::string(namebuf); + + if (callback.object_cb) { + callback.object_cb(user_data, object_name.c_str()); + } + + continue; + } + +#if 0 // @todo + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + char namebuf[4096]; + token += 2; +#ifdef _MSC_VER + sscanf_s(token, "%s", namebuf, (unsigned)_countof(namebuf)); +#else + sscanf(token, "%s", namebuf); +#endif + tag.name = std::string(namebuf); + + token += tag.name.size() + 1; + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = atoi(token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.floatValues.resize(static_cast(ts.num_floats)); + for (size_t i = 0; i < static_cast(ts.num_floats); ++i) { + tag.floatValues[i] = parseFloat(&token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + char stringValueBuffer[4096]; + +#ifdef _MSC_VER + sscanf_s(token, "%s", stringValueBuffer, + (unsigned)_countof(stringValueBuffer)); +#else + sscanf(token, "%s", stringValueBuffer); +#endif + tag.stringValues[i] = stringValueBuffer; + token += tag.stringValues[i].size() + 1; + } + + tags.push_back(tag); + } +#endif + + // Ignore unknown command. + } + + if (err) { + (*err) += errss.str(); + } + + return true; +} +} // namespace tinyobj + +#endif + +#endif // TINY_OBJ_LOADER_H_